├── .gitignore
├── src
└── tailwind.css
├── tailwind.config.js
├── package.json
├── index.html
└── dist
├── main.js
└── tailwind.css
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/src/tailwind.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | purge: [
3 | "*.html"
4 | ],
5 | mode: "jit",
6 | darkMode: false, // or 'media' or 'class'
7 | theme: {
8 | extend: {},
9 | fontFamily: {
10 | sans: ["Fira sans", "sans-serif"]
11 | }
12 | },
13 | variants: {
14 | extend: {},
15 | },
16 | plugins: [],
17 | }
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "demo",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tailwindcss -i src/tailwind.css -o dist/tailwind.css --watch",
8 | "server": "live-server . --no-css-inject"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "tailwindcss": "^2.2.15"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Screen Recorder
8 |
9 |
10 |
11 |
12 |
13 |
20 |
21 |
22 |
23 |
24 | Video recorder
25 |
26 |
27 |
28 |
29 |
30 |
33 |
36 |
37 |
38 |
39 |
40 | Recorded video
41 |
42 |
43 |
44 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/dist/main.js:
--------------------------------------------------------------------------------
1 | let stream = null,
2 | audio = null,
3 | mixedStream = null,
4 | chunks = [],
5 | recorder = null
6 | startButton = null,
7 | stopButton = null,
8 | downloadButton = null,
9 | recordedVideo = null;
10 |
11 | async function setupStream () {
12 | try {
13 | stream = await navigator.mediaDevices.getDisplayMedia({
14 | video: true
15 | });
16 |
17 | audio = await navigator.mediaDevices.getUserMedia({
18 | audio: {
19 | echoCancellation: true,
20 | noiseSuppression: true,
21 | sampleRate: 44100,
22 | },
23 | });
24 |
25 | setupVideoFeedback();
26 | } catch (err) {
27 | console.error(err)
28 | }
29 | }
30 |
31 | function setupVideoFeedback() {
32 | if (stream) {
33 | const video = document.querySelector('.video-feedback');
34 | video.srcObject = stream;
35 | video.play();
36 | } else {
37 | console.warn('No stream available');
38 | }
39 | }
40 |
41 | async function startRecording () {
42 | await setupStream();
43 |
44 | if (stream && audio) {
45 | mixedStream = new MediaStream([...stream.getTracks(), ...audio.getTracks()]);
46 | recorder = new MediaRecorder(mixedStream);
47 | recorder.ondataavailable = handleDataAvailable;
48 | recorder.onstop = handleStop;
49 | recorder.start(1000);
50 |
51 | startButton.disabled = true;
52 | stopButton.disabled = false;
53 |
54 | console.log('Recording started');
55 | } else {
56 | console.warn('No stream available.');
57 | }
58 | }
59 |
60 | function stopRecording () {
61 | recorder.stop();
62 |
63 | startButton.disabled = false;
64 | stopButton.disabled = true;
65 | }
66 |
67 | function handleDataAvailable (e) {
68 | chunks.push(e.data);
69 | }
70 |
71 | function handleStop (e) {
72 | const blob = new Blob(chunks, { 'type' : 'video/mp4' });
73 | chunks = [];
74 |
75 | downloadButton.href = URL.createObjectURL(blob);
76 | downloadButton.download = 'video.mp4';
77 | downloadButton.disabled = false;
78 |
79 | recordedVideo.src = URL.createObjectURL(blob);
80 | recordedVideo.load();
81 | recordedVideo.onloadeddata = function() {
82 | const rc = document.querySelector(".recorded-video-wrap");
83 | rc.classList.remove("hidden");
84 | rc.scrollIntoView({ behavior: "smooth", block: "start" });
85 |
86 | recordedVideo.play();
87 | }
88 |
89 | stream.getTracks().forEach((track) => track.stop());
90 | audio.getTracks().forEach((track) => track.stop());
91 |
92 | console.log('Recording stopped');
93 | }
94 |
95 | window.addEventListener('load', () => {
96 | startButton = document.querySelector('.start-recording');
97 | stopButton = document.querySelector('.stop-recording');
98 | downloadButton = document.querySelector('.download-video');
99 | recordedVideo = document.querySelector('.recorded-video');
100 |
101 | startButton.addEventListener('click', startRecording);
102 | stopButton.addEventListener('click', stopRecording);
103 | })
--------------------------------------------------------------------------------
/dist/tailwind.css:
--------------------------------------------------------------------------------
1 | /*! tailwindcss v2.2.15 | MIT License | https://tailwindcss.com */
2 |
3 | /*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */
4 |
5 | /*
6 | Document
7 | ========
8 | */
9 |
10 | /**
11 | Use a better box model (opinionated).
12 | */
13 |
14 | *,
15 | ::before,
16 | ::after {
17 | box-sizing: border-box;
18 | }
19 |
20 | /**
21 | Use a more readable tab size (opinionated).
22 | */
23 |
24 | html {
25 | -moz-tab-size: 4;
26 | -o-tab-size: 4;
27 | tab-size: 4;
28 | }
29 |
30 | /**
31 | 1. Correct the line height in all browsers.
32 | 2. Prevent adjustments of font size after orientation changes in iOS.
33 | */
34 |
35 | html {
36 | line-height: 1.15;
37 | /* 1 */
38 | -webkit-text-size-adjust: 100%;
39 | /* 2 */
40 | }
41 |
42 | /*
43 | Sections
44 | ========
45 | */
46 |
47 | /**
48 | Remove the margin in all browsers.
49 | */
50 |
51 | body {
52 | margin: 0;
53 | }
54 |
55 | /**
56 | Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
57 | */
58 |
59 | body {
60 | font-family:
61 | system-ui,
62 | -apple-system, /* Firefox supports this but not yet `system-ui` */
63 | 'Segoe UI',
64 | Roboto,
65 | Helvetica,
66 | Arial,
67 | sans-serif,
68 | 'Apple Color Emoji',
69 | 'Segoe UI Emoji';
70 | }
71 |
72 | /*
73 | Grouping content
74 | ================
75 | */
76 |
77 | /**
78 | 1. Add the correct height in Firefox.
79 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
80 | */
81 |
82 | hr {
83 | height: 0;
84 | /* 1 */
85 | color: inherit;
86 | /* 2 */
87 | }
88 |
89 | /*
90 | Text-level semantics
91 | ====================
92 | */
93 |
94 | /**
95 | Add the correct text decoration in Chrome, Edge, and Safari.
96 | */
97 |
98 | abbr[title] {
99 | -webkit-text-decoration: underline dotted;
100 | text-decoration: underline dotted;
101 | }
102 |
103 | /**
104 | Add the correct font weight in Edge and Safari.
105 | */
106 |
107 | b,
108 | strong {
109 | font-weight: bolder;
110 | }
111 |
112 | /**
113 | 1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
114 | 2. Correct the odd 'em' font sizing in all browsers.
115 | */
116 |
117 | code,
118 | kbd,
119 | samp,
120 | pre {
121 | font-family:
122 | ui-monospace,
123 | SFMono-Regular,
124 | Consolas,
125 | 'Liberation Mono',
126 | Menlo,
127 | monospace;
128 | /* 1 */
129 | font-size: 1em;
130 | /* 2 */
131 | }
132 |
133 | /**
134 | Add the correct font size in all browsers.
135 | */
136 |
137 | small {
138 | font-size: 80%;
139 | }
140 |
141 | /**
142 | Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
143 | */
144 |
145 | sub,
146 | sup {
147 | font-size: 75%;
148 | line-height: 0;
149 | position: relative;
150 | vertical-align: baseline;
151 | }
152 |
153 | sub {
154 | bottom: -0.25em;
155 | }
156 |
157 | sup {
158 | top: -0.5em;
159 | }
160 |
161 | /*
162 | Tabular data
163 | ============
164 | */
165 |
166 | /**
167 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
168 | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
169 | */
170 |
171 | table {
172 | text-indent: 0;
173 | /* 1 */
174 | border-color: inherit;
175 | /* 2 */
176 | }
177 |
178 | /*
179 | Forms
180 | =====
181 | */
182 |
183 | /**
184 | 1. Change the font styles in all browsers.
185 | 2. Remove the margin in Firefox and Safari.
186 | */
187 |
188 | button,
189 | input,
190 | optgroup,
191 | select,
192 | textarea {
193 | font-family: inherit;
194 | /* 1 */
195 | font-size: 100%;
196 | /* 1 */
197 | line-height: 1.15;
198 | /* 1 */
199 | margin: 0;
200 | /* 2 */
201 | }
202 |
203 | /**
204 | Remove the inheritance of text transform in Edge and Firefox.
205 | 1. Remove the inheritance of text transform in Firefox.
206 | */
207 |
208 | button,
209 | select {
210 | /* 1 */
211 | text-transform: none;
212 | }
213 |
214 | /**
215 | Correct the inability to style clickable types in iOS and Safari.
216 | */
217 |
218 | button,
219 | [type='button'],
220 | [type='reset'],
221 | [type='submit'] {
222 | -webkit-appearance: button;
223 | }
224 |
225 | /**
226 | Remove the inner border and padding in Firefox.
227 | */
228 |
229 | ::-moz-focus-inner {
230 | border-style: none;
231 | padding: 0;
232 | }
233 |
234 | /**
235 | Restore the focus styles unset by the previous rule.
236 | */
237 |
238 | :-moz-focusring {
239 | outline: 1px dotted ButtonText;
240 | }
241 |
242 | /**
243 | Remove the additional ':invalid' styles in Firefox.
244 | See: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737
245 | */
246 |
247 | :-moz-ui-invalid {
248 | box-shadow: none;
249 | }
250 |
251 | /**
252 | Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
253 | */
254 |
255 | legend {
256 | padding: 0;
257 | }
258 |
259 | /**
260 | Add the correct vertical alignment in Chrome and Firefox.
261 | */
262 |
263 | progress {
264 | vertical-align: baseline;
265 | }
266 |
267 | /**
268 | Correct the cursor style of increment and decrement buttons in Safari.
269 | */
270 |
271 | ::-webkit-inner-spin-button,
272 | ::-webkit-outer-spin-button {
273 | height: auto;
274 | }
275 |
276 | /**
277 | 1. Correct the odd appearance in Chrome and Safari.
278 | 2. Correct the outline style in Safari.
279 | */
280 |
281 | [type='search'] {
282 | -webkit-appearance: textfield;
283 | /* 1 */
284 | outline-offset: -2px;
285 | /* 2 */
286 | }
287 |
288 | /**
289 | Remove the inner padding in Chrome and Safari on macOS.
290 | */
291 |
292 | ::-webkit-search-decoration {
293 | -webkit-appearance: none;
294 | }
295 |
296 | /**
297 | 1. Correct the inability to style clickable types in iOS and Safari.
298 | 2. Change font properties to 'inherit' in Safari.
299 | */
300 |
301 | ::-webkit-file-upload-button {
302 | -webkit-appearance: button;
303 | /* 1 */
304 | font: inherit;
305 | /* 2 */
306 | }
307 |
308 | /*
309 | Interactive
310 | ===========
311 | */
312 |
313 | /*
314 | Add the correct display in Chrome and Safari.
315 | */
316 |
317 | summary {
318 | display: list-item;
319 | }
320 |
321 | /**
322 | * Manually forked from SUIT CSS Base: https://github.com/suitcss/base
323 | * A thin layer on top of normalize.css that provides a starting point more
324 | * suitable for web applications.
325 | */
326 |
327 | /**
328 | * Removes the default spacing and border for appropriate elements.
329 | */
330 |
331 | blockquote,
332 | dl,
333 | dd,
334 | h1,
335 | h2,
336 | h3,
337 | h4,
338 | h5,
339 | h6,
340 | hr,
341 | figure,
342 | p,
343 | pre {
344 | margin: 0;
345 | }
346 |
347 | button {
348 | background-color: transparent;
349 | background-image: none;
350 | }
351 |
352 | fieldset {
353 | margin: 0;
354 | padding: 0;
355 | }
356 |
357 | ol,
358 | ul {
359 | list-style: none;
360 | margin: 0;
361 | padding: 0;
362 | }
363 |
364 | /**
365 | * Tailwind custom reset styles
366 | */
367 |
368 | /**
369 | * 1. Use the user's configured `sans` font-family (with Tailwind's default
370 | * sans-serif font stack as a fallback) as a sane default.
371 | * 2. Use Tailwind's default "normal" line-height so the user isn't forced
372 | * to override it to ensure consistency even when using the default theme.
373 | */
374 |
375 | html {
376 | font-family: Fira sans, sans-serif;
377 | /* 1 */
378 | line-height: 1.5;
379 | /* 2 */
380 | }
381 |
382 | /**
383 | * Inherit font-family and line-height from `html` so users can set them as
384 | * a class directly on the `html` element.
385 | */
386 |
387 | body {
388 | font-family: inherit;
389 | line-height: inherit;
390 | }
391 |
392 | /**
393 | * 1. Prevent padding and border from affecting element width.
394 | *
395 | * We used to set this in the html element and inherit from
396 | * the parent element for everything else. This caused issues
397 | * in shadow-dom-enhanced elements like where the content
398 | * is wrapped by a div with box-sizing set to `content-box`.
399 | *
400 | * https://github.com/mozdevs/cssremedy/issues/4
401 | *
402 | *
403 | * 2. Allow adding a border to an element by just adding a border-width.
404 | *
405 | * By default, the way the browser specifies that an element should have no
406 | * border is by setting it's border-style to `none` in the user-agent
407 | * stylesheet.
408 | *
409 | * In order to easily add borders to elements by just setting the `border-width`
410 | * property, we change the default border-style for all elements to `solid`, and
411 | * use border-width to hide them instead. This way our `border` utilities only
412 | * need to set the `border-width` property instead of the entire `border`
413 | * shorthand, making our border utilities much more straightforward to compose.
414 | *
415 | * https://github.com/tailwindcss/tailwindcss/pull/116
416 | */
417 |
418 | *,
419 | ::before,
420 | ::after {
421 | box-sizing: border-box;
422 | /* 1 */
423 | border-width: 0;
424 | /* 2 */
425 | border-style: solid;
426 | /* 2 */
427 | border-color: currentColor;
428 | /* 2 */
429 | }
430 |
431 | /*
432 | * Ensure horizontal rules are visible by default
433 | */
434 |
435 | hr {
436 | border-top-width: 1px;
437 | }
438 |
439 | /**
440 | * Undo the `border-style: none` reset that Normalize applies to images so that
441 | * our `border-{width}` utilities have the expected effect.
442 | *
443 | * The Normalize reset is unnecessary for us since we default the border-width
444 | * to 0 on all elements.
445 | *
446 | * https://github.com/tailwindcss/tailwindcss/issues/362
447 | */
448 |
449 | img {
450 | border-style: solid;
451 | }
452 |
453 | textarea {
454 | resize: vertical;
455 | }
456 |
457 | input::-moz-placeholder, textarea::-moz-placeholder {
458 | opacity: 1;
459 | color: #9ca3af;
460 | }
461 |
462 | input:-ms-input-placeholder, textarea:-ms-input-placeholder {
463 | opacity: 1;
464 | color: #9ca3af;
465 | }
466 |
467 | input::placeholder,
468 | textarea::placeholder {
469 | opacity: 1;
470 | color: #9ca3af;
471 | }
472 |
473 | button,
474 | [role="button"] {
475 | cursor: pointer;
476 | }
477 |
478 | /**
479 | * Override legacy focus reset from Normalize with modern Firefox focus styles.
480 | *
481 | * This is actually an improvement over the new defaults in Firefox in our testing,
482 | * as it triggers the better focus styles even for links, which still use a dotted
483 | * outline in Firefox by default.
484 | */
485 |
486 | :-moz-focusring {
487 | outline: auto;
488 | }
489 |
490 | table {
491 | border-collapse: collapse;
492 | }
493 |
494 | h1,
495 | h2,
496 | h3,
497 | h4,
498 | h5,
499 | h6 {
500 | font-size: inherit;
501 | font-weight: inherit;
502 | }
503 |
504 | /**
505 | * Reset links to optimize for opt-in styling instead of
506 | * opt-out.
507 | */
508 |
509 | a {
510 | color: inherit;
511 | text-decoration: inherit;
512 | }
513 |
514 | /**
515 | * Reset form element properties that are easy to forget to
516 | * style explicitly so you don't inadvertently introduce
517 | * styles that deviate from your design system. These styles
518 | * supplement a partial reset that is already applied by
519 | * normalize.css.
520 | */
521 |
522 | button,
523 | input,
524 | optgroup,
525 | select,
526 | textarea {
527 | padding: 0;
528 | line-height: inherit;
529 | color: inherit;
530 | }
531 |
532 | /**
533 | * Use the configured 'mono' font family for elements that
534 | * are expected to be rendered with a monospace font, falling
535 | * back to the system monospace stack if there is no configured
536 | * 'mono' font family.
537 | */
538 |
539 | pre,
540 | code,
541 | kbd,
542 | samp {
543 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
544 | }
545 |
546 | /**
547 | * 1. Make replaced elements `display: block` by default as that's
548 | * the behavior you want almost all of the time. Inspired by
549 | * CSS Remedy, with `svg` added as well.
550 | *
551 | * https://github.com/mozdevs/cssremedy/issues/14
552 | *
553 | * 2. Add `vertical-align: middle` to align replaced elements more
554 | * sensibly by default when overriding `display` by adding a
555 | * utility like `inline`.
556 | *
557 | * This can trigger a poorly considered linting error in some
558 | * tools but is included by design.
559 | *
560 | * https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210
561 | */
562 |
563 | img,
564 | svg,
565 | video,
566 | canvas,
567 | audio,
568 | iframe,
569 | embed,
570 | object {
571 | display: block;
572 | /* 1 */
573 | vertical-align: middle;
574 | /* 2 */
575 | }
576 |
577 | /**
578 | * Constrain images and videos to the parent width and preserve
579 | * their intrinsic aspect ratio.
580 | *
581 | * https://github.com/mozdevs/cssremedy/issues/14
582 | */
583 |
584 | img,
585 | video {
586 | max-width: 100%;
587 | height: auto;
588 | }
589 |
590 | /**
591 | * Ensure the default browser behavior of the `hidden` attribute.
592 | */
593 |
594 | [hidden] {
595 | display: none;
596 | }
597 |
598 | .container {
599 | width: 100%;
600 | }
601 |
602 | @media (min-width: 640px) {
603 | .container {
604 | max-width: 640px;
605 | }
606 | }
607 |
608 | @media (min-width: 768px) {
609 | .container {
610 | max-width: 768px;
611 | }
612 | }
613 |
614 | @media (min-width: 1024px) {
615 | .container {
616 | max-width: 1024px;
617 | }
618 | }
619 |
620 | @media (min-width: 1280px) {
621 | .container {
622 | max-width: 1280px;
623 | }
624 | }
625 |
626 | @media (min-width: 1536px) {
627 | .container {
628 | max-width: 1536px;
629 | }
630 | }
631 |
632 | .mx-auto {
633 | margin-left: auto;
634 | margin-right: auto;
635 | }
636 |
637 | .-mx-4 {
638 | margin-left: -1rem;
639 | margin-right: -1rem;
640 | }
641 |
642 | .mx-4 {
643 | margin-left: 1rem;
644 | margin-right: 1rem;
645 | }
646 |
647 | .my-8 {
648 | margin-top: 2rem;
649 | margin-bottom: 2rem;
650 | }
651 |
652 | .mb-8 {
653 | margin-bottom: 2rem;
654 | }
655 |
656 | .mb-4 {
657 | margin-bottom: 1rem;
658 | }
659 |
660 | .mt-8 {
661 | margin-top: 2rem;
662 | }
663 |
664 | .flex {
665 | display: flex;
666 | }
667 |
668 | .hidden {
669 | display: none;
670 | }
671 |
672 | .h-80 {
673 | height: 20rem;
674 | }
675 |
676 | .h-auto {
677 | height: auto;
678 | }
679 |
680 | .w-full {
681 | width: 100%;
682 | }
683 |
684 | .flex-1 {
685 | flex: 1 1 0%;
686 | }
687 |
688 | .flex-wrap {
689 | flex-wrap: wrap;
690 | }
691 |
692 | .items-center {
693 | align-items: center;
694 | }
695 |
696 | .justify-center {
697 | justify-content: center;
698 | }
699 |
700 | .overflow-hidden {
701 | overflow: hidden;
702 | }
703 |
704 | .bg-gray-800 {
705 | --tw-bg-opacity: 1;
706 | background-color: rgba(31, 41, 55, var(--tw-bg-opacity));
707 | }
708 |
709 | .bg-gray-900 {
710 | --tw-bg-opacity: 1;
711 | background-color: rgba(17, 24, 39, var(--tw-bg-opacity));
712 | }
713 |
714 | .bg-black {
715 | --tw-bg-opacity: 1;
716 | background-color: rgba(0, 0, 0, var(--tw-bg-opacity));
717 | }
718 |
719 | .bg-gradient-to-br {
720 | background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
721 | }
722 |
723 | .from-purple-500 {
724 | --tw-gradient-from: #8b5cf6;
725 | --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(139, 92, 246, 0));
726 | }
727 |
728 | .to-pink-500 {
729 | --tw-gradient-to: #ec4899;
730 | }
731 |
732 | .p-4 {
733 | padding: 1rem;
734 | }
735 |
736 | .py-4 {
737 | padding-top: 1rem;
738 | padding-bottom: 1rem;
739 | }
740 |
741 | .py-8 {
742 | padding-top: 2rem;
743 | padding-bottom: 2rem;
744 | }
745 |
746 | .px-4 {
747 | padding-left: 1rem;
748 | padding-right: 1rem;
749 | }
750 |
751 | .text-center {
752 | text-align: center;
753 | }
754 |
755 | .text-2xl {
756 | font-size: 1.5rem;
757 | line-height: 2rem;
758 | }
759 |
760 | .text-xl {
761 | font-size: 1.25rem;
762 | line-height: 1.75rem;
763 | }
764 |
765 | .text-lg {
766 | font-size: 1.125rem;
767 | line-height: 1.75rem;
768 | }
769 |
770 | .font-bold {
771 | font-weight: 700;
772 | }
773 |
774 | .font-light {
775 | font-weight: 300;
776 | }
777 |
778 | .uppercase {
779 | text-transform: uppercase;
780 | }
781 |
782 | .text-white {
783 | --tw-text-opacity: 1;
784 | color: rgba(255, 255, 255, var(--tw-text-opacity));
785 | }
786 |
787 | .text-gray-500 {
788 | --tw-text-opacity: 1;
789 | color: rgba(107, 114, 128, var(--tw-text-opacity));
790 | }
791 |
792 | .transition-all {
793 | transition-property: all;
794 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
795 | transition-duration: 150ms;
796 | }
797 |
798 | .duration-300 {
799 | transition-duration: 300ms;
800 | }
801 |
802 | .hover\:from-purple-600:hover {
803 | --tw-gradient-from: #7c3aed;
804 | --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(124, 58, 237, 0));
805 | }
806 |
807 | .hover\:to-pink-600:hover {
808 | --tw-gradient-to: #db2777;
809 | }
810 |
811 | .hover\:opacity-90:hover {
812 | opacity: 0.9;
813 | }
814 |
815 | .disabled\:opacity-50:disabled {
816 | opacity: 0.5;
817 | }
--------------------------------------------------------------------------------