-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Tailwind css files #6
Conversation
WalkthroughThe changes in this pull request primarily focus on integrating Tailwind CSS into the Aura.PHP application. This includes adding Tailwind CSS as a styling option in the Changes
Poem
Tip CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
🧹 Outside diff range and nitpick comments (7)
source/app/public/admin/css/tailwind.css (1)
1-2283
: Consider minifying the CSS for better performanceThe
tailwind.css
file is currently unminified, which can increase load times in production environments. Minifying the CSS can significantly improve page load speed.Modify your build script to generate a minified CSS file:
- "build:css": "tailwindcss -i ./tailwindcss/main.css -o ../admin/css/tailwind.css" + "build:css": "tailwindcss -i ./tailwindcss/main.css -o ../admin/css/tailwind.min.css --minify"This will output a minified CSS file named
tailwind.min.css
.source/app/public/admin-src/package.json (1)
18-18
: Consider adding a watch mode for developmentThe current script only handles one-time builds. For development, it would be helpful to have a watch mode.
"scripts": { "build": "rollup --config", - "tailwindcss": "tailwindcss -i ./tailwindcss/main.css -o ../admin/css/tailwind.css" + "tailwindcss": "tailwindcss -i ./tailwindcss/main.css -o ../admin/css/tailwind.css", + "tailwindcss:watch": "tailwindcss -i ./tailwindcss/main.css -o ../admin/css/tailwind.css --watch" }source/app/var/qiq/template/layout/Admin/base.php (1)
15-16
: Consider optimizing Google Fonts loadingThe current Google Fonts implementation loads multiple weights. Consider:
- Using
font-display: swap
for better performance- Preloading critical fonts
- Self-hosting the fonts for better performance
- <link href="https://fonts.googleapis.com/css?family=Noto+Sans+JP:100|Noto+Sans+JP:400|Noto+Sans+JP:700|Noto+Sans+JP:900|Roboto:100|Roboto:400|Roboto:700|Roboto:900&display=swap&subset=japanese" rel="stylesheet"> + <link rel="preconnect" href="https://fonts.googleapis.com"> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> + <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100;400;700;900&family=Roboto:wght@100;400;700;900&display=swap" rel="stylesheet">source/app/var/qiq/template/Admin/Login.php (2)
27-27
: Extract gradient text styles to a reusable classThe gradient text styling for the heading appears in multiple files. Consider extracting it to a reusable Tailwind component or utility class.
Create a new CSS class in your Tailwind configuration:
// tailwind.config.js module.exports = { theme: { extend: { + '.gradient-heading': { + '@apply text-xl text-center tracking-widest font-black bg-clip-text text-transparent bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500' + } } } }
59-59
: Consider using data attributes for button state managementThe current implementation uses direct ID manipulation for button states. Consider using data attributes for better maintainability:
- {{= $form->widget('continue', attr: ['id' => 'continue', 'disabled' => 'disabled', 'class' => '...']) }} + {{= $form->widget('continue', attr: [ + 'data-turnstile-button' => 'true', + 'disabled' => 'disabled', + 'class' => '...' + ]) }}Then update the JavaScript to use the data attribute:
function cfTurnstileChecked() { document.querySelector('[data-turnstile-button]').removeAttribute('disabled'); }source/app/public/admin-src/tailwindcss/index.html (2)
519-562
: Replace placeholder images with proper image handling.The image list section uses hardcoded placeholder images and lacks proper alt text.
Implement proper image handling:
-<img src="https://placehold.jp/500x300.png" alt="" class="rounded shadow max-h-80 mx-auto"> +<img src="<?= $this->escape($image->url) ?>" + alt="<?= $this->escape($image->description) ?>" + class="rounded shadow max-h-80 mx-auto" + loading="lazy">
713-715
: Consider enhancing the footer content.While the current footer is functional, consider adding useful links and information:
- Privacy policy
- Terms of service
- Contact information
- Version information
Example enhancement:
<footer> - <p class="font-sans font-thin text-sm">Copyrights © Suzuhiro Co.,Ltd. All rights reserved.</p> + <div class="grid grid-cols-1 md:grid-cols-3 gap-4"> + <div> + <p class="font-sans font-thin text-sm">Copyrights © Suzuhiro Co.,Ltd. All rights reserved.</p> + </div> + <div class="text-center"> + <nav class="space-x-4"> + <a href="/privacy" class="text-sm text-gray-600 hover:text-gray-900">Privacy Policy</a> + <a href="/terms" class="text-sm text-gray-600 hover:text-gray-900">Terms of Service</a> + </nav> + </div> + <div class="text-right"> + <p class="text-sm text-gray-600">Version <?= $this->escape($version) ?></p> + </div> + </div> </footer>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
source/app/public/admin-src/package-lock.json
is excluded by!**/package-lock.json
source/app/public/admin/images/heroicons/icon.svg
is excluded by!**/*.svg
📒 Files selected for processing (9)
README.md
(1 hunks)source/app/public/admin-src/package.json
(1 hunks)source/app/public/admin-src/tailwind.config.js
(1 hunks)source/app/public/admin-src/tailwindcss/index.html
(1 hunks)source/app/public/admin-src/tailwindcss/login.html
(1 hunks)source/app/public/admin-src/tailwindcss/main.css
(1 hunks)source/app/public/admin/css/tailwind.css
(1 hunks)source/app/var/qiq/template/Admin/Login.php
(2 hunks)source/app/var/qiq/template/layout/Admin/base.php
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- source/app/public/admin-src/tailwindcss/main.css
🔇 Additional comments (3)
source/app/public/admin-src/tailwind.config.js (1)
7-9
: Verify the forms plugin version compatibility
Ensure the forms plugin version matches the Tailwind CSS version for compatibility.
✅ Verification successful
Plugin and Tailwind CSS versions are compatible
The @tailwindcss/forms plugin (v0.5.9) is compatible with the installed Tailwind CSS version (v3.4.16). Both versions are up-to-date and follow the same major version (v3.x), ensuring proper functionality.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check package versions
cat package.json | jq '.devDependencies | .["@tailwindcss/forms"], .["tailwindcss"]'
Length of output: 131
Script:
#!/bin/bash
# Search for package.json files in the repository
fd package.json
# Once we find the package.json files, let's check their content for tailwind dependencies
fd package.json --exec cat {} \; | grep -A 2 -B 2 "tailwindcss\|@tailwindcss"
Length of output: 578
source/app/public/admin-src/package.json (1)
7-7
: Dependencies look up-to-date
The versions of Tailwind CSS (3.4.16) and its forms plugin (0.5.9) are current and compatible.
Also applies to: 11-11
README.md (1)
21-21
: LGTM: Documentation update matches implementation
The addition of Tailwind CSS to the Frontend section accurately reflects the changes in this PR.
border-color: rgb(15 23 42 / 0.1); | ||
} | ||
|
||
.lg\:px-8 { | ||
padding-left: 2rem; | ||
padding-right: 2rem; | ||
} | ||
|
||
.lg\:text-base { | ||
font-size: 1rem; | ||
line-height: 1.5rem; | ||
} | ||
|
||
.lg\:text-base\/loose { | ||
font-size: 1rem; | ||
line-height: 2; | ||
} | ||
|
||
.lg\:text-base\/normal { | ||
font-size: 1rem; | ||
line-height: 1.5; | ||
} | ||
|
||
.lg\:text-base\/relaxed { | ||
font-size: 1rem; | ||
line-height: 1.625; | ||
} | ||
|
||
.lg\:text-sm { | ||
font-size: 0.875rem; | ||
line-height: 1.25rem; | ||
} | ||
} | ||
|
||
@media (prefers-color-scheme: dark) { | ||
.dark\:border-gray-600 { | ||
--tw-border-opacity: 1; | ||
border-color: rgb(75 85 99 / var(--tw-border-opacity, 1)); | ||
} | ||
|
||
.dark\:border-slate-800 { | ||
--tw-border-opacity: 1; | ||
border-color: rgb(30 41 59 / var(--tw-border-opacity, 1)); | ||
} | ||
|
||
.dark\:bg-gray-700 { | ||
--tw-bg-opacity: 1; | ||
background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1)); | ||
} | ||
|
||
.dark\:bg-indigo-600 { | ||
--tw-bg-opacity: 1; | ||
background-color: rgb(79 70 229 / var(--tw-bg-opacity, 1)); | ||
} | ||
|
||
.dark\:bg-slate-800 { | ||
--tw-bg-opacity: 1; | ||
background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)); | ||
} | ||
|
||
.dark\:text-slate-400 { | ||
--tw-text-opacity: 1; | ||
color: rgb(148 163 184 / var(--tw-text-opacity, 1)); | ||
} | ||
|
||
.dark\:text-white { | ||
--tw-text-opacity: 1; | ||
color: rgb(255 255 255 / var(--tw-text-opacity, 1)); | ||
} | ||
|
||
.dark\:placeholder-gray-400::-moz-placeholder { | ||
--tw-placeholder-opacity: 1; | ||
color: rgb(156 163 175 / var(--tw-placeholder-opacity, 1)); | ||
} | ||
|
||
.dark\:placeholder-gray-400::placeholder { | ||
--tw-placeholder-opacity: 1; | ||
color: rgb(156 163 175 / var(--tw-placeholder-opacity, 1)); | ||
} | ||
|
||
.dark\:hover\:bg-indigo-700:hover { | ||
--tw-bg-opacity: 1; | ||
background-color: rgb(67 56 202 / var(--tw-bg-opacity, 1)); | ||
} | ||
|
||
.dark\:focus\:border-indigo-500:focus { | ||
--tw-border-opacity: 1; | ||
border-color: rgb(99 102 241 / var(--tw-border-opacity, 1)); | ||
} | ||
|
||
.dark\:focus\:ring-indigo-500:focus { | ||
--tw-ring-opacity: 1; | ||
--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity, 1)); | ||
} | ||
|
||
.dark\:focus\:ring-indigo-800:focus { | ||
--tw-ring-opacity: 1; | ||
--tw-ring-color: rgb(55 48 163 / var(--tw-ring-opacity, 1)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid committing generated CSS files to source control
Including generated files like tailwind.css
in the repository can lead to unnecessary bloat and potential merge conflicts. It's best practice to exclude generated files from version control and build them during deployment or development.
Add tailwind.css
to your .gitignore
file:
+ /source/app/public/admin/css/tailwind.css
Ensure your build process generates this CSS file as needed.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
*, ::before, ::after { | |
--tw-border-spacing-x: 0; | |
--tw-border-spacing-y: 0; | |
--tw-translate-x: 0; | |
--tw-translate-y: 0; | |
--tw-rotate: 0; | |
--tw-skew-x: 0; | |
--tw-skew-y: 0; | |
--tw-scale-x: 1; | |
--tw-scale-y: 1; | |
--tw-pan-x: ; | |
--tw-pan-y: ; | |
--tw-pinch-zoom: ; | |
--tw-scroll-snap-strictness: proximity; | |
--tw-gradient-from-position: ; | |
--tw-gradient-via-position: ; | |
--tw-gradient-to-position: ; | |
--tw-ordinal: ; | |
--tw-slashed-zero: ; | |
--tw-numeric-figure: ; | |
--tw-numeric-spacing: ; | |
--tw-numeric-fraction: ; | |
--tw-ring-inset: ; | |
--tw-ring-offset-width: 0px; | |
--tw-ring-offset-color: #fff; | |
--tw-ring-color: rgb(59 130 246 / 0.5); | |
--tw-ring-offset-shadow: 0 0 #0000; | |
--tw-ring-shadow: 0 0 #0000; | |
--tw-shadow: 0 0 #0000; | |
--tw-shadow-colored: 0 0 #0000; | |
--tw-blur: ; | |
--tw-brightness: ; | |
--tw-contrast: ; | |
--tw-grayscale: ; | |
--tw-hue-rotate: ; | |
--tw-invert: ; | |
--tw-saturate: ; | |
--tw-sepia: ; | |
--tw-drop-shadow: ; | |
--tw-backdrop-blur: ; | |
--tw-backdrop-brightness: ; | |
--tw-backdrop-contrast: ; | |
--tw-backdrop-grayscale: ; | |
--tw-backdrop-hue-rotate: ; | |
--tw-backdrop-invert: ; | |
--tw-backdrop-opacity: ; | |
--tw-backdrop-saturate: ; | |
--tw-backdrop-sepia: ; | |
--tw-contain-size: ; | |
--tw-contain-layout: ; | |
--tw-contain-paint: ; | |
--tw-contain-style: ; | |
} | |
::backdrop { | |
--tw-border-spacing-x: 0; | |
--tw-border-spacing-y: 0; | |
--tw-translate-x: 0; | |
--tw-translate-y: 0; | |
--tw-rotate: 0; | |
--tw-skew-x: 0; | |
--tw-skew-y: 0; | |
--tw-scale-x: 1; | |
--tw-scale-y: 1; | |
--tw-pan-x: ; | |
--tw-pan-y: ; | |
--tw-pinch-zoom: ; | |
--tw-scroll-snap-strictness: proximity; | |
--tw-gradient-from-position: ; | |
--tw-gradient-via-position: ; | |
--tw-gradient-to-position: ; | |
--tw-ordinal: ; | |
--tw-slashed-zero: ; | |
--tw-numeric-figure: ; | |
--tw-numeric-spacing: ; | |
--tw-numeric-fraction: ; | |
--tw-ring-inset: ; | |
--tw-ring-offset-width: 0px; | |
--tw-ring-offset-color: #fff; | |
--tw-ring-color: rgb(59 130 246 / 0.5); | |
--tw-ring-offset-shadow: 0 0 #0000; | |
--tw-ring-shadow: 0 0 #0000; | |
--tw-shadow: 0 0 #0000; | |
--tw-shadow-colored: 0 0 #0000; | |
--tw-blur: ; | |
--tw-brightness: ; | |
--tw-contrast: ; | |
--tw-grayscale: ; | |
--tw-hue-rotate: ; | |
--tw-invert: ; | |
--tw-saturate: ; | |
--tw-sepia: ; | |
--tw-drop-shadow: ; | |
--tw-backdrop-blur: ; | |
--tw-backdrop-brightness: ; | |
--tw-backdrop-contrast: ; | |
--tw-backdrop-grayscale: ; | |
--tw-backdrop-hue-rotate: ; | |
--tw-backdrop-invert: ; | |
--tw-backdrop-opacity: ; | |
--tw-backdrop-saturate: ; | |
--tw-backdrop-sepia: ; | |
--tw-contain-size: ; | |
--tw-contain-layout: ; | |
--tw-contain-paint: ; | |
--tw-contain-style: ; | |
} | |
/* | |
! tailwindcss v3.4.16 | MIT License | https://tailwindcss.com | |
*/ | |
/* | |
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) | |
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) | |
*/ | |
*, | |
::before, | |
::after { | |
box-sizing: border-box; | |
/* 1 */ | |
border-width: 0; | |
/* 2 */ | |
border-style: solid; | |
/* 2 */ | |
border-color: #e5e7eb; | |
/* 2 */ | |
} | |
::before, | |
::after { | |
--tw-content: ''; | |
} | |
/* | |
1. Use a consistent sensible line-height in all browsers. | |
2. Prevent adjustments of font size after orientation changes in iOS. | |
3. Use a more readable tab size. | |
4. Use the user's configured `sans` font-family by default. | |
5. Use the user's configured `sans` font-feature-settings by default. | |
6. Use the user's configured `sans` font-variation-settings by default. | |
7. Disable tap highlights on iOS | |
*/ | |
html, | |
:host { | |
line-height: 1.5; | |
/* 1 */ | |
-webkit-text-size-adjust: 100%; | |
/* 2 */ | |
-moz-tab-size: 4; | |
/* 3 */ | |
-o-tab-size: 4; | |
tab-size: 4; | |
/* 3 */ | |
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | |
/* 4 */ | |
font-feature-settings: normal; | |
/* 5 */ | |
font-variation-settings: normal; | |
/* 6 */ | |
-webkit-tap-highlight-color: transparent; | |
/* 7 */ | |
} | |
/* | |
1. Remove the margin in all browsers. | |
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. | |
*/ | |
body { | |
margin: 0; | |
/* 1 */ | |
line-height: inherit; | |
/* 2 */ | |
} | |
/* | |
1. Add the correct height in Firefox. | |
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) | |
3. Ensure horizontal rules are visible by default. | |
*/ | |
hr { | |
height: 0; | |
/* 1 */ | |
color: inherit; | |
/* 2 */ | |
border-top-width: 1px; | |
/* 3 */ | |
} | |
/* | |
Add the correct text decoration in Chrome, Edge, and Safari. | |
*/ | |
abbr:where([title]) { | |
-webkit-text-decoration: underline dotted; | |
text-decoration: underline dotted; | |
} | |
/* | |
Remove the default font size and weight for headings. | |
*/ | |
h1, | |
h2, | |
h3, | |
h4, | |
h5, | |
h6 { | |
font-size: inherit; | |
font-weight: inherit; | |
} | |
/* | |
Reset links to optimize for opt-in styling instead of opt-out. | |
*/ | |
a { | |
color: inherit; | |
text-decoration: inherit; | |
} | |
/* | |
Add the correct font weight in Edge and Safari. | |
*/ | |
b, | |
strong { | |
font-weight: bolder; | |
} | |
/* | |
1. Use the user's configured `mono` font-family by default. | |
2. Use the user's configured `mono` font-feature-settings by default. | |
3. Use the user's configured `mono` font-variation-settings by default. | |
4. Correct the odd `em` font sizing in all browsers. | |
*/ | |
code, | |
kbd, | |
samp, | |
pre { | |
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | |
/* 1 */ | |
font-feature-settings: normal; | |
/* 2 */ | |
font-variation-settings: normal; | |
/* 3 */ | |
font-size: 1em; | |
/* 4 */ | |
} | |
/* | |
Add the correct font size in all browsers. | |
*/ | |
small { | |
font-size: 80%; | |
} | |
/* | |
Prevent `sub` and `sup` elements from affecting the line height in all browsers. | |
*/ | |
sub, | |
sup { | |
font-size: 75%; | |
line-height: 0; | |
position: relative; | |
vertical-align: baseline; | |
} | |
sub { | |
bottom: -0.25em; | |
} | |
sup { | |
top: -0.5em; | |
} | |
/* | |
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) | |
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) | |
3. Remove gaps between table borders by default. | |
*/ | |
table { | |
text-indent: 0; | |
/* 1 */ | |
border-color: inherit; | |
/* 2 */ | |
border-collapse: collapse; | |
/* 3 */ | |
} | |
/* | |
1. Change the font styles in all browsers. | |
2. Remove the margin in Firefox and Safari. | |
3. Remove default padding in all browsers. | |
*/ | |
button, | |
input, | |
optgroup, | |
select, | |
textarea { | |
font-family: inherit; | |
/* 1 */ | |
font-feature-settings: inherit; | |
/* 1 */ | |
font-variation-settings: inherit; | |
/* 1 */ | |
font-size: 100%; | |
/* 1 */ | |
font-weight: inherit; | |
/* 1 */ | |
line-height: inherit; | |
/* 1 */ | |
letter-spacing: inherit; | |
/* 1 */ | |
color: inherit; | |
/* 1 */ | |
margin: 0; | |
/* 2 */ | |
padding: 0; | |
/* 3 */ | |
} | |
/* | |
Remove the inheritance of text transform in Edge and Firefox. | |
*/ | |
button, | |
select { | |
text-transform: none; | |
} | |
/* | |
1. Correct the inability to style clickable types in iOS and Safari. | |
2. Remove default button styles. | |
*/ | |
button, | |
input:where([type='button']), | |
input:where([type='reset']), | |
input:where([type='submit']) { | |
-webkit-appearance: button; | |
/* 1 */ | |
background-color: transparent; | |
/* 2 */ | |
background-image: none; | |
/* 2 */ | |
} | |
/* | |
Use the modern Firefox focus style for all focusable elements. | |
*/ | |
:-moz-focusring { | |
outline: auto; | |
} | |
/* | |
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) | |
*/ | |
:-moz-ui-invalid { | |
box-shadow: none; | |
} | |
/* | |
Add the correct vertical alignment in Chrome and Firefox. | |
*/ | |
progress { | |
vertical-align: baseline; | |
} | |
/* | |
Correct the cursor style of increment and decrement buttons in Safari. | |
*/ | |
::-webkit-inner-spin-button, | |
::-webkit-outer-spin-button { | |
height: auto; | |
} | |
/* | |
1. Correct the odd appearance in Chrome and Safari. | |
2. Correct the outline style in Safari. | |
*/ | |
[type='search'] { | |
-webkit-appearance: textfield; | |
/* 1 */ | |
outline-offset: -2px; | |
/* 2 */ | |
} | |
/* | |
Remove the inner padding in Chrome and Safari on macOS. | |
*/ | |
::-webkit-search-decoration { | |
-webkit-appearance: none; | |
} | |
/* | |
1. Correct the inability to style clickable types in iOS and Safari. | |
2. Change font properties to `inherit` in Safari. | |
*/ | |
::-webkit-file-upload-button { | |
-webkit-appearance: button; | |
/* 1 */ | |
font: inherit; | |
/* 2 */ | |
} | |
/* | |
Add the correct display in Chrome and Safari. | |
*/ | |
summary { | |
display: list-item; | |
} | |
/* | |
Removes the default spacing and border for appropriate elements. | |
*/ | |
blockquote, | |
dl, | |
dd, | |
h1, | |
h2, | |
h3, | |
h4, | |
h5, | |
h6, | |
hr, | |
figure, | |
p, | |
pre { | |
margin: 0; | |
} | |
fieldset { | |
margin: 0; | |
padding: 0; | |
} | |
legend { | |
padding: 0; | |
} | |
ol, | |
ul, | |
menu { | |
list-style: none; | |
margin: 0; | |
padding: 0; | |
} | |
/* | |
Reset default styling for dialogs. | |
*/ | |
dialog { | |
padding: 0; | |
} | |
/* | |
Prevent resizing textareas horizontally by default. | |
*/ | |
textarea { | |
resize: vertical; | |
} | |
/* | |
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) | |
2. Set the default placeholder color to the user's configured gray 400 color. | |
*/ | |
input::-moz-placeholder, textarea::-moz-placeholder { | |
opacity: 1; | |
/* 1 */ | |
color: #9ca3af; | |
/* 2 */ | |
} | |
input::placeholder, | |
textarea::placeholder { | |
opacity: 1; | |
/* 1 */ | |
color: #9ca3af; | |
/* 2 */ | |
} | |
/* | |
Set the default cursor for buttons. | |
*/ | |
button, | |
[role="button"] { | |
cursor: pointer; | |
} | |
/* | |
Make sure disabled buttons don't get the pointer cursor. | |
*/ | |
:disabled { | |
cursor: default; | |
} | |
/* | |
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) | |
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) | |
This can trigger a poorly considered lint error in some tools but is included by design. | |
*/ | |
img, | |
svg, | |
video, | |
canvas, | |
audio, | |
iframe, | |
embed, | |
object { | |
display: block; | |
/* 1 */ | |
vertical-align: middle; | |
/* 2 */ | |
} | |
/* | |
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) | |
*/ | |
img, | |
video { | |
max-width: 100%; | |
height: auto; | |
} | |
/* Make elements with the HTML hidden attribute stay hidden by default */ | |
[hidden]:where(:not([hidden="until-found"])) { | |
display: none; | |
} | |
[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select { | |
-webkit-appearance: none; | |
-moz-appearance: none; | |
appearance: none; | |
background-color: #fff; | |
border-color: #6b7280; | |
border-width: 1px; | |
border-radius: 0px; | |
padding-top: 0.5rem; | |
padding-right: 0.75rem; | |
padding-bottom: 0.5rem; | |
padding-left: 0.75rem; | |
font-size: 1rem; | |
line-height: 1.5rem; | |
--tw-shadow: 0 0 #0000; | |
} | |
[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus { | |
outline: 2px solid transparent; | |
outline-offset: 2px; | |
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); | |
--tw-ring-offset-width: 0px; | |
--tw-ring-offset-color: #fff; | |
--tw-ring-color: #2563eb; | |
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); | |
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); | |
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); | |
border-color: #2563eb; | |
} | |
input::-moz-placeholder, textarea::-moz-placeholder { | |
color: #6b7280; | |
opacity: 1; | |
} | |
input::placeholder,textarea::placeholder { | |
color: #6b7280; | |
opacity: 1; | |
} | |
::-webkit-datetime-edit-fields-wrapper { | |
padding: 0; | |
} | |
::-webkit-date-and-time-value { | |
min-height: 1.5em; | |
text-align: inherit; | |
} | |
::-webkit-datetime-edit { | |
display: inline-flex; | |
} | |
::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field { | |
padding-top: 0; | |
padding-bottom: 0; | |
} | |
select { | |
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); | |
background-position: right 0.5rem center; | |
background-repeat: no-repeat; | |
background-size: 1.5em 1.5em; | |
padding-right: 2.5rem; | |
-webkit-print-color-adjust: exact; | |
print-color-adjust: exact; | |
} | |
[multiple],[size]:where(select:not([size="1"])) { | |
background-image: initial; | |
background-position: initial; | |
background-repeat: unset; | |
background-size: initial; | |
padding-right: 0.75rem; | |
-webkit-print-color-adjust: unset; | |
print-color-adjust: unset; | |
} | |
[type='checkbox'],[type='radio'] { | |
-webkit-appearance: none; | |
-moz-appearance: none; | |
appearance: none; | |
padding: 0; | |
-webkit-print-color-adjust: exact; | |
print-color-adjust: exact; | |
display: inline-block; | |
vertical-align: middle; | |
background-origin: border-box; | |
-webkit-user-select: none; | |
-moz-user-select: none; | |
user-select: none; | |
flex-shrink: 0; | |
height: 1rem; | |
width: 1rem; | |
color: #2563eb; | |
background-color: #fff; | |
border-color: #6b7280; | |
border-width: 1px; | |
--tw-shadow: 0 0 #0000; | |
} | |
[type='checkbox'] { | |
border-radius: 0px; | |
} | |
[type='radio'] { | |
border-radius: 100%; | |
} | |
[type='checkbox']:focus,[type='radio']:focus { | |
outline: 2px solid transparent; | |
outline-offset: 2px; | |
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); | |
--tw-ring-offset-width: 2px; | |
--tw-ring-offset-color: #fff; | |
--tw-ring-color: #2563eb; | |
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); | |
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); | |
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); | |
} | |
[type='checkbox']:checked,[type='radio']:checked { | |
border-color: transparent; | |
background-color: currentColor; | |
background-size: 100% 100%; | |
background-position: center; | |
background-repeat: no-repeat; | |
} | |
[type='checkbox']:checked { | |
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); | |
} | |
@media (forced-colors: active) { | |
[type='checkbox']:checked { | |
-webkit-appearance: auto; | |
-moz-appearance: auto; | |
appearance: auto; | |
} | |
} | |
[type='radio']:checked { | |
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); | |
} | |
@media (forced-colors: active) { | |
[type='radio']:checked { | |
-webkit-appearance: auto; | |
-moz-appearance: auto; | |
appearance: auto; | |
} | |
} | |
[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus { | |
border-color: transparent; | |
background-color: currentColor; | |
} | |
[type='checkbox']:indeterminate { | |
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); | |
border-color: transparent; | |
background-color: currentColor; | |
background-size: 100% 100%; | |
background-position: center; | |
background-repeat: no-repeat; | |
} | |
@media (forced-colors: active) { | |
[type='checkbox']:indeterminate { | |
-webkit-appearance: auto; | |
-moz-appearance: auto; | |
appearance: auto; | |
} | |
} | |
[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus { | |
border-color: transparent; | |
background-color: currentColor; | |
} | |
[type='file'] { | |
background: unset; | |
border-color: inherit; | |
border-width: 0; | |
border-radius: 0; | |
padding: 0; | |
font-size: unset; | |
line-height: inherit; | |
} | |
[type='file']:focus { | |
outline: 1px solid ButtonText; | |
outline: 1px auto -webkit-focus-ring-color; | |
} | |
.sr-only { | |
position: absolute; | |
width: 1px; | |
height: 1px; | |
padding: 0; | |
margin: -1px; | |
overflow: hidden; | |
clip: rect(0, 0, 0, 0); | |
white-space: nowrap; | |
border-width: 0; | |
} | |
.pointer-events-none { | |
pointer-events: none; | |
} | |
.fixed { | |
position: fixed; | |
} | |
.absolute { | |
position: absolute; | |
} | |
.relative { | |
position: relative; | |
} | |
.sticky { | |
position: sticky; | |
} | |
.inset-0 { | |
inset: 0px; | |
} | |
.inset-y-0 { | |
top: 0px; | |
bottom: 0px; | |
} | |
.bottom-1\.5 { | |
bottom: 0.375rem; | |
} | |
.bottom-2\.5 { | |
bottom: 0.625rem; | |
} | |
.bottom-4 { | |
bottom: 1rem; | |
} | |
.end-1\.5 { | |
inset-inline-end: 0.375rem; | |
} | |
.end-2\.5 { | |
inset-inline-end: 0.625rem; | |
} | |
.left-0 { | |
left: 0px; | |
} | |
.left-1\/2 { | |
left: 50%; | |
} | |
.left-3 { | |
left: 0.75rem; | |
} | |
.right-0 { | |
right: 0px; | |
} | |
.right-4 { | |
right: 1rem; | |
} | |
.start-0 { | |
inset-inline-start: 0px; | |
} | |
.top-0 { | |
top: 0px; | |
} | |
.top-1\/2 { | |
top: 50%; | |
} | |
.top-2 { | |
top: 0.5rem; | |
} | |
.top-4 { | |
top: 1rem; | |
} | |
.top-full { | |
top: 100%; | |
} | |
.z-40 { | |
z-index: 40; | |
} | |
.z-50 { | |
z-index: 50; | |
} | |
.col-span-3 { | |
grid-column: span 3 / span 3; | |
} | |
.mx-5 { | |
margin-left: 1.25rem; | |
margin-right: 1.25rem; | |
} | |
.mx-auto { | |
margin-left: auto; | |
margin-right: auto; | |
} | |
.my-10 { | |
margin-top: 2.5rem; | |
margin-bottom: 2.5rem; | |
} | |
.-ml-px { | |
margin-left: -1px; | |
} | |
.mb-1 { | |
margin-bottom: 0.25rem; | |
} | |
.mb-2 { | |
margin-bottom: 0.5rem; | |
} | |
.mb-3 { | |
margin-bottom: 0.75rem; | |
} | |
.mb-4 { | |
margin-bottom: 1rem; | |
} | |
.ml-2 { | |
margin-left: 0.5rem; | |
} | |
.ml-6 { | |
margin-left: 1.5rem; | |
} | |
.ml-\[-11px\] { | |
margin-left: -11px; | |
} | |
.ml-auto { | |
margin-left: auto; | |
} | |
.mr-3 { | |
margin-right: 0.75rem; | |
} | |
.mt-1 { | |
margin-top: 0.25rem; | |
} | |
.mt-10 { | |
margin-top: 2.5rem; | |
} | |
.mt-3 { | |
margin-top: 0.75rem; | |
} | |
.mt-5 { | |
margin-top: 1.25rem; | |
} | |
.block { | |
display: block; | |
} | |
.inline-block { | |
display: inline-block; | |
} | |
.inline { | |
display: inline; | |
} | |
.flex { | |
display: flex; | |
} | |
.table { | |
display: table; | |
} | |
.grid { | |
display: grid; | |
} | |
.hidden { | |
display: none; | |
} | |
.h-1 { | |
height: 0.25rem; | |
} | |
.h-10 { | |
height: 2.5rem; | |
} | |
.h-4 { | |
height: 1rem; | |
} | |
.h-40 { | |
height: 10rem; | |
} | |
.h-5 { | |
height: 1.25rem; | |
} | |
.h-6 { | |
height: 1.5rem; | |
} | |
.h-\[100svh\] { | |
height: 100svh; | |
} | |
.h-fit { | |
height: -moz-fit-content; | |
height: fit-content; | |
} | |
.h-min { | |
height: -moz-min-content; | |
height: min-content; | |
} | |
.h-px { | |
height: 1px; | |
} | |
.max-h-20 { | |
max-height: 5rem; | |
} | |
.max-h-80 { | |
max-height: 20rem; | |
} | |
.max-h-\[40px\] { | |
max-height: 40px; | |
} | |
.w-10 { | |
width: 2.5rem; | |
} | |
.w-20 { | |
width: 5rem; | |
} | |
.w-4 { | |
width: 1rem; | |
} | |
.w-5 { | |
width: 1.25rem; | |
} | |
.w-6 { | |
width: 1.5rem; | |
} | |
.w-80 { | |
width: 20rem; | |
} | |
.w-full { | |
width: 100%; | |
} | |
.min-w-24 { | |
min-width: 6rem; | |
} | |
.max-w-20 { | |
max-width: 5rem; | |
} | |
.max-w-7xl { | |
max-width: 80rem; | |
} | |
.max-w-\[40px\] { | |
max-width: 40px; | |
} | |
.max-w-lg { | |
max-width: 32rem; | |
} | |
.max-w-sm { | |
max-width: 24rem; | |
} | |
.max-w-xs { | |
max-width: 20rem; | |
} | |
.flex-1 { | |
flex: 1 1 0%; | |
} | |
.flex-none { | |
flex: none; | |
} | |
.grow { | |
flex-grow: 1; | |
} | |
.table-auto { | |
table-layout: auto; | |
} | |
.caption-bottom { | |
caption-side: bottom; | |
} | |
.border-collapse { | |
border-collapse: collapse; | |
} | |
.origin-top-right { | |
transform-origin: top right; | |
} | |
.-translate-x-1\/2 { | |
--tw-translate-x: -50%; | |
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | |
} | |
.-translate-y-1\/2 { | |
--tw-translate-y: -50%; | |
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | |
} | |
.scale-0 { | |
--tw-scale-x: 0; | |
--tw-scale-y: 0; | |
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | |
} | |
.scale-100 { | |
--tw-scale-x: 1; | |
--tw-scale-y: 1; | |
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | |
} | |
.transform { | |
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | |
} | |
@keyframes pulse { | |
50% { | |
opacity: .5; | |
} | |
} | |
.animate-pulse { | |
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; | |
} | |
@keyframes spin { | |
to { | |
transform: rotate(360deg); | |
} | |
} | |
.animate-spin { | |
animation: spin 1s linear infinite; | |
} | |
.cursor-move { | |
cursor: move; | |
} | |
.select-none { | |
-webkit-user-select: none; | |
-moz-user-select: none; | |
user-select: none; | |
} | |
.grid-cols-1 { | |
grid-template-columns: repeat(1, minmax(0, 1fr)); | |
} | |
.grid-cols-2 { | |
grid-template-columns: repeat(2, minmax(0, 1fr)); | |
} | |
.flex-row { | |
flex-direction: row; | |
} | |
.flex-col { | |
flex-direction: column; | |
} | |
.flex-wrap { | |
flex-wrap: wrap; | |
} | |
.place-content-center { | |
place-content: center; | |
} | |
.items-center { | |
align-items: center; | |
} | |
.justify-end { | |
justify-content: flex-end; | |
} | |
.justify-center { | |
justify-content: center; | |
} | |
.justify-between { | |
justify-content: space-between; | |
} | |
.gap-2 { | |
gap: 0.5rem; | |
} | |
.gap-4 { | |
gap: 1rem; | |
} | |
.gap-5 { | |
gap: 1.25rem; | |
} | |
.space-x-1 > :not([hidden]) ~ :not([hidden]) { | |
--tw-space-x-reverse: 0; | |
margin-right: calc(0.25rem * var(--tw-space-x-reverse)); | |
margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse))); | |
} | |
.overflow-hidden { | |
overflow: hidden; | |
} | |
.overflow-scroll { | |
overflow: scroll; | |
} | |
.whitespace-normal { | |
white-space: normal; | |
} | |
.break-words { | |
overflow-wrap: break-word; | |
} | |
.rounded { | |
border-radius: 0.25rem; | |
} | |
.rounded-2xl { | |
border-radius: 1rem; | |
} | |
.rounded-3xl { | |
border-radius: 1.5rem; | |
} | |
.rounded-full { | |
border-radius: 9999px; | |
} | |
.rounded-lg { | |
border-radius: 0.5rem; | |
} | |
.rounded-md { | |
border-radius: 0.375rem; | |
} | |
.rounded-xl { | |
border-radius: 0.75rem; | |
} | |
.rounded-tl-md { | |
border-top-left-radius: 0.375rem; | |
} | |
.rounded-tr-md { | |
border-top-right-radius: 0.375rem; | |
} | |
.border { | |
border-width: 1px; | |
} | |
.border-2 { | |
border-width: 2px; | |
} | |
.border-y { | |
border-top-width: 1px; | |
border-bottom-width: 1px; | |
} | |
.border-b { | |
border-bottom-width: 1px; | |
} | |
.border-l { | |
border-left-width: 1px; | |
} | |
.border-t { | |
border-top-width: 1px; | |
} | |
.border-\[\#6b7280\] { | |
--tw-border-opacity: 1; | |
border-color: rgb(107 114 128 / var(--tw-border-opacity, 1)); | |
} | |
.border-gray-300 { | |
--tw-border-opacity: 1; | |
border-color: rgb(209 213 219 / var(--tw-border-opacity, 1)); | |
} | |
.border-indigo-500 { | |
--tw-border-opacity: 1; | |
border-color: rgb(99 102 241 / var(--tw-border-opacity, 1)); | |
} | |
.border-rose-500 { | |
--tw-border-opacity: 1; | |
border-color: rgb(244 63 94 / var(--tw-border-opacity, 1)); | |
} | |
.border-slate-200 { | |
--tw-border-opacity: 1; | |
border-color: rgb(226 232 240 / var(--tw-border-opacity, 1)); | |
} | |
.border-slate-300 { | |
--tw-border-opacity: 1; | |
border-color: rgb(203 213 225 / var(--tw-border-opacity, 1)); | |
} | |
.border-slate-900\/10 { | |
border-color: rgb(15 23 42 / 0.1); | |
} | |
.bg-gray-50 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-gray-900 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-indigo-100 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(224 231 255 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-indigo-500 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(99 102 241 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-rose-100 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(255 228 230 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-rose-50 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(255 241 242 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-rose-500 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(244 63 94 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-slate-100 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(241 245 249 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-slate-50 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-slate-900\/25 { | |
background-color: rgb(15 23 42 / 0.25); | |
} | |
.bg-white { | |
--tw-bg-opacity: 1; | |
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1)); | |
} | |
.bg-white\/70 { | |
background-color: rgb(255 255 255 / 0.7); | |
} | |
.bg-gradient-to-r { | |
background-image: linear-gradient(to right, var(--tw-gradient-stops)); | |
} | |
.from-indigo-500 { | |
--tw-gradient-from: #6366f1 var(--tw-gradient-from-position); | |
--tw-gradient-to: rgb(99 102 241 / 0) var(--tw-gradient-to-position); | |
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); | |
} | |
.from-transparent { | |
--tw-gradient-from: transparent var(--tw-gradient-from-position); | |
--tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position); | |
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); | |
} | |
.from-10\% { | |
--tw-gradient-from-position: 10%; | |
} | |
.via-purple-500 { | |
--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position); | |
--tw-gradient-stops: var(--tw-gradient-from), #a855f7 var(--tw-gradient-via-position), var(--tw-gradient-to); | |
} | |
.to-pink-500 { | |
--tw-gradient-to: #ec4899 var(--tw-gradient-to-position); | |
} | |
.to-transparent { | |
--tw-gradient-to: transparent var(--tw-gradient-to-position); | |
} | |
.bg-clip-text { | |
-webkit-background-clip: text; | |
background-clip: text; | |
} | |
.p-2 { | |
padding: 0.5rem; | |
} | |
.p-3 { | |
padding: 0.75rem; | |
} | |
.p-4 { | |
padding: 1rem; | |
} | |
.p-5 { | |
padding: 1.25rem; | |
} | |
.p-6 { | |
padding: 1.5rem; | |
} | |
.px-0 { | |
padding-left: 0px; | |
padding-right: 0px; | |
} | |
.px-2 { | |
padding-left: 0.5rem; | |
padding-right: 0.5rem; | |
} | |
.px-3 { | |
padding-left: 0.75rem; | |
padding-right: 0.75rem; | |
} | |
.px-4 { | |
padding-left: 1rem; | |
padding-right: 1rem; | |
} | |
.px-6 { | |
padding-left: 1.5rem; | |
padding-right: 1.5rem; | |
} | |
.py-1 { | |
padding-top: 0.25rem; | |
padding-bottom: 0.25rem; | |
} | |
.py-2 { | |
padding-top: 0.5rem; | |
padding-bottom: 0.5rem; | |
} | |
.py-3 { | |
padding-top: 0.75rem; | |
padding-bottom: 0.75rem; | |
} | |
.py-4 { | |
padding-top: 1rem; | |
padding-bottom: 1rem; | |
} | |
.pb-2 { | |
padding-bottom: 0.5rem; | |
} | |
.pl-6 { | |
padding-left: 1.5rem; | |
} | |
.ps-10 { | |
padding-inline-start: 2.5rem; | |
} | |
.ps-3 { | |
padding-inline-start: 0.75rem; | |
} | |
.pt-5 { | |
padding-top: 1.25rem; | |
} | |
.pt-7 { | |
padding-top: 1.75rem; | |
} | |
.text-center { | |
text-align: center; | |
} | |
.text-right { | |
text-align: right; | |
} | |
.align-middle { | |
vertical-align: middle; | |
} | |
.font-sans { | |
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | |
} | |
.text-base { | |
font-size: 1rem; | |
line-height: 1.5rem; | |
} | |
.text-lg { | |
font-size: 1.125rem; | |
line-height: 1.75rem; | |
} | |
.text-sm { | |
font-size: 0.875rem; | |
line-height: 1.25rem; | |
} | |
.text-xl { | |
font-size: 1.25rem; | |
line-height: 1.75rem; | |
} | |
.text-xs { | |
font-size: 0.75rem; | |
line-height: 1rem; | |
} | |
.font-black { | |
font-weight: 900; | |
} | |
.font-bold { | |
font-weight: 700; | |
} | |
.font-extrabold { | |
font-weight: 800; | |
} | |
.font-medium { | |
font-weight: 500; | |
} | |
.font-normal { | |
font-weight: 400; | |
} | |
.font-semibold { | |
font-weight: 600; | |
} | |
.font-thin { | |
font-weight: 100; | |
} | |
.uppercase { | |
text-transform: uppercase; | |
} | |
.italic { | |
font-style: italic; | |
} | |
.leading-6 { | |
line-height: 1.5rem; | |
} | |
.tracking-tight { | |
letter-spacing: -0.025em; | |
} | |
.tracking-wide { | |
letter-spacing: 0.025em; | |
} | |
.tracking-wider { | |
letter-spacing: 0.05em; | |
} | |
.tracking-widest { | |
letter-spacing: 0.1em; | |
} | |
.text-gray-400 { | |
--tw-text-opacity: 1; | |
color: rgb(156 163 175 / var(--tw-text-opacity, 1)); | |
} | |
.text-gray-500 { | |
--tw-text-opacity: 1; | |
color: rgb(107 114 128 / var(--tw-text-opacity, 1)); | |
} | |
.text-gray-900 { | |
--tw-text-opacity: 1; | |
color: rgb(17 24 39 / var(--tw-text-opacity, 1)); | |
} | |
.text-indigo-500 { | |
--tw-text-opacity: 1; | |
color: rgb(99 102 241 / var(--tw-text-opacity, 1)); | |
} | |
.text-indigo-600 { | |
--tw-text-opacity: 1; | |
color: rgb(79 70 229 / var(--tw-text-opacity, 1)); | |
} | |
.text-rose-500 { | |
--tw-text-opacity: 1; | |
color: rgb(244 63 94 / var(--tw-text-opacity, 1)); | |
} | |
.text-slate-300 { | |
--tw-text-opacity: 1; | |
color: rgb(203 213 225 / var(--tw-text-opacity, 1)); | |
} | |
.text-slate-500 { | |
--tw-text-opacity: 1; | |
color: rgb(100 116 139 / var(--tw-text-opacity, 1)); | |
} | |
.text-slate-600 { | |
--tw-text-opacity: 1; | |
color: rgb(71 85 105 / var(--tw-text-opacity, 1)); | |
} | |
.text-slate-700 { | |
--tw-text-opacity: 1; | |
color: rgb(51 65 85 / var(--tw-text-opacity, 1)); | |
} | |
.text-slate-800 { | |
--tw-text-opacity: 1; | |
color: rgb(30 41 59 / var(--tw-text-opacity, 1)); | |
} | |
.text-slate-900 { | |
--tw-text-opacity: 1; | |
color: rgb(15 23 42 / var(--tw-text-opacity, 1)); | |
} | |
.text-transparent { | |
color: transparent; | |
} | |
.text-white { | |
--tw-text-opacity: 1; | |
color: rgb(255 255 255 / var(--tw-text-opacity, 1)); | |
} | |
.underline { | |
text-decoration-line: underline; | |
} | |
.decoration-pink-500\/80 { | |
text-decoration-color: rgb(236 72 153 / 0.8); | |
} | |
.decoration-8 { | |
text-decoration-thickness: 8px; | |
} | |
.underline-offset-\[-5px\] { | |
text-underline-offset: -5px; | |
} | |
.opacity-0 { | |
opacity: 0; | |
} | |
.opacity-100 { | |
opacity: 1; | |
} | |
.shadow { | |
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); | |
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); | |
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |
} | |
.shadow-\[0_1px_3px_rgba\(15\2c 23\2c 42\2c 0\.03\)\2c 0_1px_2px_rgba\(15\2c 23\2c 42\2c 0\.06\)\] { | |
--tw-shadow: 0 1px 3px rgba(15,23,42,0.03),0 1px 2px rgba(15,23,42,0.06); | |
--tw-shadow-colored: 0 1px 3px var(--tw-shadow-color), 0 1px 2px var(--tw-shadow-color); | |
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |
} | |
.shadow-lg { | |
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); | |
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); | |
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |
} | |
.shadow-md { | |
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); | |
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); | |
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |
} | |
.shadow-gray-500\/20 { | |
--tw-shadow-color: rgb(107 114 128 / 0.2); | |
--tw-shadow: var(--tw-shadow-colored); | |
} | |
.shadow-gray-900\/10 { | |
--tw-shadow-color: rgb(17 24 39 / 0.1); | |
--tw-shadow: var(--tw-shadow-colored); | |
} | |
.shadow-indigo-500\/50 { | |
--tw-shadow-color: rgb(99 102 241 / 0.5); | |
--tw-shadow: var(--tw-shadow-colored); | |
} | |
.shadow-rose-500\/50 { | |
--tw-shadow-color: rgb(244 63 94 / 0.5); | |
--tw-shadow: var(--tw-shadow-colored); | |
} | |
.ring-1 { | |
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); | |
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); | |
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); | |
} | |
.ring-slate-600\/\[0\.04\] { | |
--tw-ring-color: rgb(71 85 105 / 0.04); | |
} | |
.drop-shadow-xl { | |
--tw-drop-shadow: drop-shadow(0 20px 13px rgb(0 0 0 / 0.03)) drop-shadow(0 8px 5px rgb(0 0 0 / 0.08)); | |
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); | |
} | |
.backdrop-blur { | |
--tw-backdrop-blur: blur(8px); | |
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); | |
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); | |
} | |
.transition { | |
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; | |
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; | |
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; | |
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | |
transition-duration: 150ms; | |
} | |
.transition-all { | |
transition-property: all; | |
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | |
transition-duration: 150ms; | |
} | |
.transition-colors { | |
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; | |
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | |
transition-duration: 150ms; | |
} | |
.transition-opacity { | |
transition-property: opacity; | |
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | |
transition-duration: 150ms; | |
} | |
.duration-300 { | |
transition-duration: 300ms; | |
} | |
.duration-500 { | |
transition-duration: 500ms; | |
} | |
.selection\:bg-fuchsia-300 *::-moz-selection { | |
--tw-bg-opacity: 1; | |
background-color: rgb(240 171 252 / var(--tw-bg-opacity, 1)); | |
} | |
.selection\:bg-fuchsia-300 *::selection { | |
--tw-bg-opacity: 1; | |
background-color: rgb(240 171 252 / var(--tw-bg-opacity, 1)); | |
} | |
.selection\:text-fuchsia-900 *::-moz-selection { | |
--tw-text-opacity: 1; | |
color: rgb(112 26 117 / var(--tw-text-opacity, 1)); | |
} | |
.selection\:text-fuchsia-900 *::selection { | |
--tw-text-opacity: 1; | |
color: rgb(112 26 117 / var(--tw-text-opacity, 1)); | |
} | |
.selection\:bg-fuchsia-300::-moz-selection { | |
--tw-bg-opacity: 1; | |
background-color: rgb(240 171 252 / var(--tw-bg-opacity, 1)); | |
} | |
.selection\:bg-fuchsia-300::selection { | |
--tw-bg-opacity: 1; | |
background-color: rgb(240 171 252 / var(--tw-bg-opacity, 1)); | |
} | |
.selection\:text-fuchsia-900::-moz-selection { | |
--tw-text-opacity: 1; | |
color: rgb(112 26 117 / var(--tw-text-opacity, 1)); | |
} | |
.selection\:text-fuchsia-900::selection { | |
--tw-text-opacity: 1; | |
color: rgb(112 26 117 / var(--tw-text-opacity, 1)); | |
} | |
.placeholder\:text-xs::-moz-placeholder { | |
font-size: 0.75rem; | |
line-height: 1rem; | |
} | |
.placeholder\:text-xs::placeholder { | |
font-size: 0.75rem; | |
line-height: 1rem; | |
} | |
.placeholder\:font-thin::-moz-placeholder { | |
font-weight: 100; | |
} | |
.placeholder\:font-thin::placeholder { | |
font-weight: 100; | |
} | |
.placeholder\:italic::-moz-placeholder { | |
font-style: italic; | |
} | |
.placeholder\:italic::placeholder { | |
font-style: italic; | |
} | |
.placeholder\:text-gray-400::-moz-placeholder { | |
--tw-text-opacity: 1; | |
color: rgb(156 163 175 / var(--tw-text-opacity, 1)); | |
} | |
.placeholder\:text-gray-400::placeholder { | |
--tw-text-opacity: 1; | |
color: rgb(156 163 175 / var(--tw-text-opacity, 1)); | |
} | |
.placeholder\:text-slate-500::-moz-placeholder { | |
--tw-text-opacity: 1; | |
color: rgb(100 116 139 / var(--tw-text-opacity, 1)); | |
} | |
.placeholder\:text-slate-500::placeholder { | |
--tw-text-opacity: 1; | |
color: rgb(100 116 139 / var(--tw-text-opacity, 1)); | |
} | |
.invalid\:border-pink-500:invalid { | |
--tw-border-opacity: 1; | |
border-color: rgb(236 72 153 / var(--tw-border-opacity, 1)); | |
} | |
.invalid\:text-pink-600:invalid { | |
--tw-text-opacity: 1; | |
color: rgb(219 39 119 / var(--tw-text-opacity, 1)); | |
} | |
.hover\:rounded-lg:hover { | |
border-radius: 0.5rem; | |
} | |
.hover\:bg-gray-50:hover { | |
--tw-bg-opacity: 1; | |
background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1)); | |
} | |
.hover\:bg-gray-900\/10:hover { | |
background-color: rgb(17 24 39 / 0.1); | |
} | |
.hover\:bg-indigo-100:hover { | |
--tw-bg-opacity: 1; | |
background-color: rgb(224 231 255 / var(--tw-bg-opacity, 1)); | |
} | |
.hover\:bg-indigo-600:hover { | |
--tw-bg-opacity: 1; | |
background-color: rgb(79 70 229 / var(--tw-bg-opacity, 1)); | |
} | |
.hover\:bg-rose-600:hover { | |
--tw-bg-opacity: 1; | |
background-color: rgb(225 29 72 / var(--tw-bg-opacity, 1)); | |
} | |
.hover\:underline:hover { | |
text-decoration-line: underline; | |
} | |
.hover\:shadow-lg:hover { | |
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); | |
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); | |
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |
} | |
.hover\:shadow-gray-900\/20:hover { | |
--tw-shadow-color: rgb(17 24 39 / 0.2); | |
--tw-shadow: var(--tw-shadow-colored); | |
} | |
.hover\:outline:hover { | |
outline-style: solid; | |
} | |
.hover\:outline-1:hover { | |
outline-width: 1px; | |
} | |
.hover\:outline-indigo-200:hover { | |
outline-color: #c7d2fe; | |
} | |
.focus\:border-indigo-500:focus { | |
--tw-border-opacity: 1; | |
border-color: rgb(99 102 241 / var(--tw-border-opacity, 1)); | |
} | |
.focus\:opacity-\[0\.85\]:focus { | |
opacity: 0.85; | |
} | |
.focus\:shadow-none:focus { | |
--tw-shadow: 0 0 #0000; | |
--tw-shadow-colored: 0 0 #0000; | |
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |
} | |
.focus\:outline-none:focus { | |
outline: 2px solid transparent; | |
outline-offset: 2px; | |
} | |
.focus\:ring-1:focus { | |
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); | |
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); | |
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); | |
} | |
.focus\:ring-4:focus { | |
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); | |
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color); | |
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); | |
} | |
.focus\:ring-indigo-300:focus { | |
--tw-ring-opacity: 1; | |
--tw-ring-color: rgb(165 180 252 / var(--tw-ring-opacity, 1)); | |
} | |
.focus\:ring-indigo-500:focus { | |
--tw-ring-opacity: 1; | |
--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity, 1)); | |
} | |
.focus\:invalid\:border-pink-500:invalid:focus { | |
--tw-border-opacity: 1; | |
border-color: rgb(236 72 153 / var(--tw-border-opacity, 1)); | |
} | |
.focus\:invalid\:ring-pink-500:invalid:focus { | |
--tw-ring-opacity: 1; | |
--tw-ring-color: rgb(236 72 153 / var(--tw-ring-opacity, 1)); | |
} | |
.active\:bg-gray-900\/20:active { | |
background-color: rgb(17 24 39 / 0.2); | |
} | |
.active\:opacity-\[0\.85\]:active { | |
opacity: 0.85; | |
} | |
.active\:shadow-none:active { | |
--tw-shadow: 0 0 #0000; | |
--tw-shadow-colored: 0 0 #0000; | |
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |
} | |
.disabled\:pointer-events-none:disabled { | |
pointer-events: none; | |
} | |
.disabled\:border-slate-200:disabled { | |
--tw-border-opacity: 1; | |
border-color: rgb(226 232 240 / var(--tw-border-opacity, 1)); | |
} | |
.disabled\:bg-slate-200:disabled { | |
--tw-bg-opacity: 1; | |
background-color: rgb(226 232 240 / var(--tw-bg-opacity, 1)); | |
} | |
.disabled\:bg-slate-50:disabled { | |
--tw-bg-opacity: 1; | |
background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1)); | |
} | |
.disabled\:text-slate-500:disabled { | |
--tw-text-opacity: 1; | |
color: rgb(100 116 139 / var(--tw-text-opacity, 1)); | |
} | |
.disabled\:text-white:disabled { | |
--tw-text-opacity: 1; | |
color: rgb(255 255 255 / var(--tw-text-opacity, 1)); | |
} | |
.disabled\:opacity-50:disabled { | |
opacity: 0.5; | |
} | |
.disabled\:shadow-none:disabled { | |
--tw-shadow: 0 0 #0000; | |
--tw-shadow-colored: 0 0 #0000; | |
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |
} | |
.group:hover .group-hover\:rounded-lg { | |
border-radius: 0.5rem; | |
} | |
.group:hover .group-hover\:bg-indigo-100 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(224 231 255 / var(--tw-bg-opacity, 1)); | |
} | |
.group:hover .group-hover\:outline { | |
outline-style: solid; | |
} | |
.group:hover .group-hover\:outline-1 { | |
outline-width: 1px; | |
} | |
.group:hover .group-hover\:outline-indigo-200 { | |
outline-color: #c7d2fe; | |
} | |
@media (min-width: 640px) { | |
.sm\:text-2xl { | |
font-size: 1.5rem; | |
line-height: 2rem; | |
} | |
} | |
@media (min-width: 768px) { | |
.md\:inline-block { | |
display: inline-block; | |
} | |
.md\:flex { | |
display: flex; | |
} | |
.md\:hidden { | |
display: none; | |
} | |
.md\:w-96 { | |
width: 24rem; | |
} | |
.md\:grid-cols-4 { | |
grid-template-columns: repeat(4, minmax(0, 1fr)); | |
} | |
.md\:space-x-3 > :not([hidden]) ~ :not([hidden]) { | |
--tw-space-x-reverse: 0; | |
margin-right: calc(0.75rem * var(--tw-space-x-reverse)); | |
margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); | |
} | |
.md\:p-8 { | |
padding: 2rem; | |
} | |
.md\:placeholder\:text-sm::-moz-placeholder { | |
font-size: 0.875rem; | |
line-height: 1.25rem; | |
} | |
.md\:placeholder\:text-sm::placeholder { | |
font-size: 0.875rem; | |
line-height: 1.25rem; | |
} | |
} | |
@media (min-width: 1024px) { | |
.lg\:z-50 { | |
z-index: 50; | |
} | |
.lg\:mx-0 { | |
margin-left: 0px; | |
margin-right: 0px; | |
} | |
.lg\:mb-2 { | |
margin-bottom: 0.5rem; | |
} | |
.lg\:ml-0 { | |
margin-left: 0px; | |
} | |
.lg\:flex { | |
display: flex; | |
} | |
.lg\:w-auto { | |
width: auto; | |
} | |
.lg\:grow { | |
flex-grow: 1; | |
} | |
.lg\:flex-col { | |
flex-direction: column; | |
} | |
.lg\:gap-4 { | |
gap: 1rem; | |
} | |
.lg\:space-x-5 > :not([hidden]) ~ :not([hidden]) { | |
--tw-space-x-reverse: 0; | |
margin-right: calc(1.25rem * var(--tw-space-x-reverse)); | |
margin-left: calc(1.25rem * calc(1 - var(--tw-space-x-reverse))); | |
} | |
.lg\:border-0 { | |
border-width: 0px; | |
} | |
.lg\:border-b { | |
border-bottom-width: 1px; | |
} | |
.lg\:border-slate-900\/10 { | |
border-color: rgb(15 23 42 / 0.1); | |
} | |
.lg\:px-8 { | |
padding-left: 2rem; | |
padding-right: 2rem; | |
} | |
.lg\:text-base { | |
font-size: 1rem; | |
line-height: 1.5rem; | |
} | |
.lg\:text-base\/loose { | |
font-size: 1rem; | |
line-height: 2; | |
} | |
.lg\:text-base\/normal { | |
font-size: 1rem; | |
line-height: 1.5; | |
} | |
.lg\:text-base\/relaxed { | |
font-size: 1rem; | |
line-height: 1.625; | |
} | |
.lg\:text-sm { | |
font-size: 0.875rem; | |
line-height: 1.25rem; | |
} | |
} | |
@media (prefers-color-scheme: dark) { | |
.dark\:border-gray-600 { | |
--tw-border-opacity: 1; | |
border-color: rgb(75 85 99 / var(--tw-border-opacity, 1)); | |
} | |
.dark\:border-slate-800 { | |
--tw-border-opacity: 1; | |
border-color: rgb(30 41 59 / var(--tw-border-opacity, 1)); | |
} | |
.dark\:bg-gray-700 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1)); | |
} | |
.dark\:bg-indigo-600 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(79 70 229 / var(--tw-bg-opacity, 1)); | |
} | |
.dark\:bg-slate-800 { | |
--tw-bg-opacity: 1; | |
background-color: rgb(30 41 59 / var(--tw-bg-opacity, 1)); | |
} | |
.dark\:text-slate-400 { | |
--tw-text-opacity: 1; | |
color: rgb(148 163 184 / var(--tw-text-opacity, 1)); | |
} | |
.dark\:text-white { | |
--tw-text-opacity: 1; | |
color: rgb(255 255 255 / var(--tw-text-opacity, 1)); | |
} | |
.dark\:placeholder-gray-400::-moz-placeholder { | |
--tw-placeholder-opacity: 1; | |
color: rgb(156 163 175 / var(--tw-placeholder-opacity, 1)); | |
} | |
.dark\:placeholder-gray-400::placeholder { | |
--tw-placeholder-opacity: 1; | |
color: rgb(156 163 175 / var(--tw-placeholder-opacity, 1)); | |
} | |
.dark\:hover\:bg-indigo-700:hover { | |
--tw-bg-opacity: 1; | |
background-color: rgb(67 56 202 / var(--tw-bg-opacity, 1)); | |
} | |
.dark\:focus\:border-indigo-500:focus { | |
--tw-border-opacity: 1; | |
border-color: rgb(99 102 241 / var(--tw-border-opacity, 1)); | |
} | |
.dark\:focus\:ring-indigo-500:focus { | |
--tw-ring-opacity: 1; | |
--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity, 1)); | |
} | |
.dark\:focus\:ring-indigo-800:focus { | |
--tw-ring-opacity: 1; | |
--tw-ring-color: rgb(55 48 163 / var(--tw-ring-opacity, 1)); | |
} | |
} | |
/source/app/public/admin/css/tailwind.css |
@@ -0,0 +1,11 @@ | |||
/** @type {import('tailwindcss').Config} */ | |||
module.exports = { | |||
content: ["./tailwindcss/**/*.{html,js}"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Based on the search results, I can see that Tailwind classes are indeed being used in PHP template files under source/app/var/qiq/template/
directory. The current content path in the Tailwind config only includes files under ./tailwindcss/**/*.{html,js}
, which would miss these PHP templates.
Content paths should include PHP templates
The current content path is missing PHP templates where Tailwind classes are actively used. Add the PHP template directory to ensure proper CSS generation.
source/app/var/qiq/template/**/*.php
contains Tailwind classes in template files- Current config would miss these classes, leading to missing styles
- content: ["./tailwindcss/**/*.{html,js}"],
+ content: [
+ "./tailwindcss/**/*.{html,js}",
+ "../../var/qiq/template/**/*.php"
+ ],
🔗 Analysis chain
Consider expanding the content paths
The current content path "./tailwindcss/**/*.{html,js}"
might be too restrictive. Consider including other directories where Tailwind classes might be used, such as template files.
- content: ["./tailwindcss/**/*.{html,js}"],
+ content: [
+ "./tailwindcss/**/*.{html,js}",
+ "../**/*.php",
+ "./**/*.{html,js}"
+ ],
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for potential Tailwind class usage outside the specified directory
rg -t html -t php -t js 'class="[^"]*[a-zA-Z0-9:-]+' --glob '!tailwindcss/**'
Length of output: 58328
@@ -11,10 +11,10 @@ | |||
{{ setBlock ('head_meta') }}{{= getBlock () ~}} | |||
{{ setBlock ('head_styles') }} | |||
<link href="{{= $siteUrl }}/admin/css/bundle.css" rel="stylesheet"> | |||
<link href="{{= $siteUrl }}/admin/css/tailwind.css" rel="stylesheet"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
CSS path needs to be updated to include 'public' directory
The Tailwind CSS file is actually located at /admin/css/tailwind.css
under the public
directory. The current template path {{= $siteUrl }}/admin/css/tailwind.css
should be updated to {{= $siteUrl }}/public/admin/css/tailwind.css
to match the actual file location.
🔗 Analysis chain
Verify the CSS file path and existence
The Tailwind CSS file path looks correct, but let's verify it's being generated in the right location.
Let me verify the correct path by searching for the CSS file and related build configurations.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if the CSS output directory exists and is writable
test -w "../admin/css" && echo "Directory exists and is writable" || echo "Directory issue"
Length of output: 63
Script:
#!/bin/bash
# Search for Tailwind CSS files and build configurations
fd -t f "tailwind.css"
# Search for any build scripts or config files related to Tailwind
fd -t f "(tailwind.config|postcss.config)"
# Check the actual web assets directory structure
fd -t d "(css|assets|public)" -d 3
Length of output: 211
<div class="p-4 mb-4 text-sm text-rose-500 rounded-lg bg-rose-50 mt-5" role="alert"> | ||
<svg class="inline w-6 h-6 "> | ||
<use xlink:href="/itae/admin/images/heroicons/icon.svg#shield-exclamation"></use> | ||
</svg> | ||
<span class="font-sans font-bold">TEXT</span> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace hardcoded "TEXT" placeholder
The alert message contains a hardcoded "TEXT" placeholder that needs to be replaced with actual error message content.
<input type="text" name="username" autofocus="" autocomplete="username" placeholder="username" required="required" minlength="5" maxlength="100" title="有効なユーザー名を入力してください" class="rounded w-full placeholder:text-slate-500 placeholder:font-thin transition duration-300 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500"> | ||
<p class="block text-sm text-rose-500 italic">TEXT</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent language usage in form validation
The form shows mixed language usage:
- Interface elements are in English
- Title attributes contain Japanese text
- Error messages use "TEXT" placeholder
Consider implementing proper localization support for consistent language handling.
Also applies to: 33-34
<form method="post" action="/admin/logout"> | ||
<button class="text-slate-600 text-base tracking-wide p-2 -ml-px font-medium"> | ||
<svg class="inline w-6 h-6 "> | ||
<use xlink:href="/admin/images/heroicons/icon.svg#arrow-left-on-rectangle"></use> | ||
</svg> | ||
</button> | ||
</form> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add CSRF protection to logout forms.
The logout forms are missing CSRF protection tokens, which could make them vulnerable to CSRF attacks.
Add CSRF token to both mobile and desktop logout forms:
<form method="post" action="/admin/logout">
+ <input type="hidden" name="_csrf" value="<?= $this->escape($csrf_token) ?>">
<button class="text-slate-600 text-base tracking-wide p-2 -ml-px font-medium">
<svg class="inline w-6 h-6 ">
<use xlink:href="/admin/images/heroicons/icon.svg#arrow-left-on-rectangle"></use>
</svg>
</button>
</form>
Also applies to: 219-225
<div id="menuBg" class="fixed z-50 inset-0 hidden md:hidden"> | ||
<div class="fixed inset-0 bg-slate-900/25 backdrop-blur transition-opacity opacity-100"></div> | ||
<div id="menu" class="fixed top-4 right-4 w-full max-w-xs bg-white rounded-3xl shadow-lg p-6 text-base font-semibold text-slate-900 dark:bg-slate-800 dark:text-slate-400 dark:highlight-white/5 transition-all origin-top-right opacity-0 scale-0"> | ||
<div class="flex justify-between"> | ||
<div> | ||
<ul class="grid grid-cols-1 gap-5"> | ||
<li class="group"> | ||
<a href="/admin/index" | ||
class="text-slate-600 text-base tracking-wide p-2 -ml-px font-extrabold"> | ||
<svg class="inline w-5 h-5 "> | ||
<use xlink:href="/admin/images/heroicons/icon.svg#home-modern"></use> | ||
</svg> | ||
HOME | ||
</a> | ||
<div class="mt-1 h-1 rounded-full bg-indigo-500"></div> | ||
</li> | ||
<li class="group"> | ||
<a href="/admin/menu-item1" | ||
class="text-slate-600 text-base tracking-wide p-2 -ml-px font-medium"> | ||
<svg class="inline w-5 h-5 "> | ||
<use xlink:href="/admin/images/heroicons/icon.svg#paint-brush"></use> | ||
</svg> | ||
MENU1 | ||
</a> | ||
<div class="mt-1 h-1 rounded-full "></div> | ||
</li> | ||
<li class="group"> | ||
<a href="/admin/menu-item2" | ||
class="text-slate-600 text-base tracking-wide p-2 -ml-px font-medium"> | ||
<svg class="inline w-5 h-5 "> | ||
<use xlink:href="/admin/images/heroicons/icon.svg#calendar"></use> | ||
</svg> | ||
MENU2 | ||
</a> | ||
<div class="mt-1 h-1 rounded-full "></div> | ||
</li> | ||
<li class="group"> | ||
<a href="/admin/menu-item3" | ||
class="text-slate-600 text-base tracking-wide p-2 -ml-px font-medium"> | ||
<svg class="inline w-5 h-5 "> | ||
<use xlink:href="/admin/images/heroicons/icon.svg#trophy"></use> | ||
</svg> | ||
MENU3 | ||
</a> | ||
<div class="mt-1 h-1 rounded-full "></div> | ||
</li> | ||
<li class="group"> | ||
<a href="/admin/menu-item4" | ||
class="text-slate-600 text-base tracking-wide p-2 -ml-px font-medium"> | ||
<svg class="inline w-5 h-5 "> | ||
<use xlink:href="/admin/images/heroicons/icon.svg#swatch"></use> | ||
</svg> | ||
MENU4 | ||
</a> | ||
<div class="mt-1 h-1 rounded-full "></div> | ||
</li> | ||
<li class="group"> | ||
<a href="/admin/menu-item5" | ||
class="text-slate-600 text-base tracking-wide p-2 -ml-px font-medium"> | ||
<svg class="inline w-5 h-5 "> | ||
<use xlink:href="/admin/images/heroicons/icon.svg#user-group"></use> | ||
</svg> | ||
MENU5 | ||
</a> | ||
<div class="mt-1 h-1 rounded-full "></div> | ||
</li> | ||
</ul> | ||
<div class="border-t border-slate-200 dark:border-slate-800 pt-5 mt-5"> | ||
<form method="post" action="/admin/logout"> | ||
<button class="text-slate-600 text-base tracking-wide p-2 -ml-px font-medium"> | ||
<svg class="inline w-6 h-6 "> | ||
<use xlink:href="/admin/images/heroicons/icon.svg#arrow-left-on-rectangle"></use> | ||
</svg> | ||
</button> | ||
</form> | ||
</div> | ||
</div> | ||
<div> | ||
<button type="button" id="menuCloser"> | ||
<svg class="inline w-6 h-6 "> | ||
<use xlink:href="/admin/images/heroicons/icon.svg#x-mark"></use> | ||
</svg> | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve navigation accessibility and maintainability.
The navigation menu has several areas for improvement:
- Duplicate menu items between mobile and desktop views
- Missing keyboard navigation support
- Inconsistent aria attributes
Consider extracting menu items to a template partial to avoid duplication and ensure consistency. Add proper keyboard navigation support:
<nav class="block leading-6 relative">
+ <ul class="flex flex-column space-x-1 md:space-x-3 lg:space-x-5" role="menubar">
- <ul class="flex flex-column space-x-1 md:space-x-3 lg:space-x-5">
<li class="group">
- <a href="/admin/index"
+ <a href="/admin/index" role="menuitem" tabindex="0"
class="text-slate-600 text-sm tracking-wide p-2 -ml-px font-extrabold">
Also applies to: 152-227
</div> | ||
</label> | ||
|
||
<label class="block mt-5"> | ||
<span class="block text-sm font-sans font-normal text-slate-700">テキストエリア</span> | ||
<textarea class="rounded w-full placeholder:text-slate-500 placeholder:font-thin transition duration-300 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500 leading-6 h-40" placeholder="プレースホルダー"></textarea> | ||
</label> | ||
|
||
<label class="block mt-5"> | ||
<span class="absolute block top-2 left-3 text-sm font-thin text-slate-500">テキストエリア</span> | ||
<textarea class="rounded w-full pt-7 placeholder:text-slate-500 placeholder:font-thin transition duration-300 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500 leading-6 h-40" placeholder=""></textarea> | ||
</label> | ||
|
||
<label class="block mt-5"> | ||
<span class="block text-sm font-sans font-normal text-slate-700">日付</span> | ||
<input type="text" class="flatpickr1 rounded w-full placeholder:text-slate-500 placeholder:font-thin transition duration-300 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500" placeholder="YYYY-MM-DD"> | ||
<script>flatpickr('.flatpickr1', { disableMobile: true });</script> | ||
</label> | ||
|
||
<label class="block mt-5"> | ||
<span class="absolute block top-2 left-3 text-sm font-thin text-slate-500">日付</span> | ||
<input type="text" class="flatpickr3 rounded w-full pt-7 placeholder:text-slate-500 placeholder:font-thin transition duration-300 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500" placeholder="YYYY-MM-DD"> | ||
<script>flatpickr('.flatpickr3', { disableMobile: true });</script> | ||
</label> | ||
|
||
<label class="block mt-5"> | ||
<span class="block text-sm font-sans font-normal text-slate-700">日時</span> | ||
<input type="text" class="flatpickr2 rounded w-full placeholder:text-slate-500 placeholder:font-thin transition duration-300 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500" placeholder="YYYY-MM-DD HH:MM"> | ||
<script>flatpickr('.flatpickr2', { disableMobile: true, enableTime: true, dateFormat: 'Y-m-d H:i' });</script> | ||
</label> | ||
|
||
<label class="block mt-5"> | ||
<span class="block top-2 left-3 text-sm font-thin text-slate-500">日時</span> | ||
<input type="text" class="flatpickr4 rounded w-full pt-7 placeholder:text-slate-500 placeholder:font-thin transition duration-300 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500" placeholder="YYYY-MM-DD HH:MM"> | ||
<script>flatpickr('.flatpickr4', { disableMobile: true, enableTime: true, dateFormat: 'Y-m-d H:i' });</script> | ||
</label> | ||
|
||
<label class="block mt-5"> | ||
<span class="block top-2 left-3 text-sm font-normal text-slate-700 tracking-wide select-none">ファイルタイプ</span> | ||
<input type="file" class="rounded w-full p-3 text-sm bg-white border border-[#6b7280] placeholder:text-slate-500 placeholder:font-thin transition duration-300 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500" placeholder=""> | ||
</label> | ||
|
||
<div class="mt-5"> | ||
<span class="block text-sm font-sans font-normal text-slate-700">チェックボックス</span> | ||
<label class="block"> | ||
<input type="checkbox" name="check1" value="1"> | ||
<span class="text-base font-sans font-normal text-slate-700">チェック1</span> | ||
</label> | ||
<label class="block"> | ||
<input type="checkbox" name="check2" value="2"> | ||
<span class="text-base font-sans font-normal text-slate-700">チェック2</span> | ||
</label> | ||
</div> | ||
|
||
<div class="mt-5"> | ||
<span class="block text-sm font-sans font-normal text-slate-700">ラジオボタン</span> | ||
<label class="inline"> | ||
<input type="radio" name="radio" value="1"> | ||
<span class="text-base font-sans font-normal text-slate-700">ラジオ1</span> | ||
</label> | ||
<label class="inline ml-2"> | ||
<input type="radio" name="radio" value="2"> | ||
<span class="text-base font-sans font-normal text-slate-700">ラジオ2</span> | ||
</label> | ||
</div> | ||
|
||
<label class="block mt-5"> | ||
<span class="block text-sm font-sans font-normal text-slate-700">選択(選択肢が6個以上)</span> | ||
<select class="rounded transition duration-300 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500"> | ||
<option>選択肢1</option> | ||
<option>選択肢2</option> | ||
<option>選択肢3</option> | ||
</select> | ||
</label> | ||
|
||
<label class="block mt-5"> | ||
<span class="absolute block top-2 left-3 text-sm font-thin text-slate-500">選択(選択肢が6個以上)</span> | ||
<select class="rounded transition duration-300 pt-7 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none invalid:border-pink-500 invalid:text-pink-600 focus:invalid:border-pink-500 focus:invalid:ring-pink-500"> | ||
<option>選択肢1</option> | ||
<option>選択肢2</option> | ||
<option>選択肢3</option> | ||
</select> | ||
</label> | ||
|
||
<div class="mt-5"> | ||
<span class="block text-sm font-sans font-normal text-slate-700">送信ボタン</span> | ||
<input type="submit" value="保存" class="py-2 px-4 bg-indigo-500 text-white text-sm font-sans font-bold tracking-wider rounded-full shadow-lg shadow-indigo-500/50 focus:outline-none hover:bg-indigo-600 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none"> | ||
</div> | ||
|
||
<div class="mt-5"> | ||
<span class="block text-sm font-sans font-normal text-slate-700">キャンセルボタン</span> | ||
<input type="button" value="キャンセル" class="py-2 px-4 bg-white text-gray-500 text-sm font-sans font-bold tracking-wider rounded-full shadow-lg shadow-gray-500/20 focus:outline-none border border-gray-300 hover:bg-gray-50 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none"> | ||
</div> | ||
|
||
<div class="mt-5"> | ||
<span class="block text-sm font-sans font-normal text-slate-700">無効ボタン</span> | ||
<input type="button" value="保存" class="py-2 px-4 bg-indigo-500 text-white text-sm font-sans font-bold tracking-wider rounded-full shadow-lg shadow-indigo-500/50 focus:outline-none disabled:text-white disabled:bg-slate-200 disabled:shadow-none" disabled="disabled"> | ||
</div> | ||
</form> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance form validation and initialization.
The form section needs improvements in validation and script handling:
- Add proper form validation attributes
- Move Flatpickr initialization to a separate script file
- Add proper error states and feedback
Apply these improvements:
-<form>
+<form novalidate onsubmit="return validateForm(this);">
<label class="block mt-5">
<span class="block text-sm font-sans font-normal text-slate-700">テキストタイプ</span>
- <input type="text" class="rounded w-full placeholder:text-slate-500">
+ <input type="text"
+ required
+ pattern="[A-Za-z0-9]+"
+ class="rounded w-full placeholder:text-slate-500"
+ aria-describedby="text-error">
+ <span id="text-error" class="hidden text-rose-500 text-sm"></span>
</label>
Move Flatpickr initialization to a separate file:
-<script>flatpickr('.flatpickr1', { disableMobile: true });</script>
Create a new file admin/js/form-init.js
:
document.addEventListener('DOMContentLoaded', () => {
initializeFlatpickr();
initializeFormValidation();
});
function initializeFlatpickr() {
const dateInputs = document.querySelectorAll('.flatpickr1');
dateInputs.forEach(input => {
flatpickr(input, {
disableMobile: true,
onChange: (selectedDates, dateStr) => {
validateDateInput(input, dateStr);
}
});
});
}
document.addEventListener('DOMContentLoaded', () => { | ||
setupMenu(); | ||
}); | ||
|
||
function setupMenu () { | ||
const menuOpener = document.querySelector('#menuOpener'); | ||
menuOpener.addEventListener('click', () => { | ||
const menuBg = document.querySelector('#menuBg'); | ||
menuBg.classList.remove('hidden'); | ||
|
||
const menu = menuBg.querySelector('#menu'); | ||
|
||
window.requestAnimationFrame(() => { | ||
menu.classList.add('scale-100'); | ||
menu.classList.add('opacity-100'); | ||
menu.classList.remove('scale-0'); | ||
menu.classList.remove('opacity-0'); | ||
}); | ||
}); | ||
|
||
const menuCloser = document.querySelector('#menuCloser'); | ||
menuCloser.addEventListener('click', () => { | ||
const menuBg = document.querySelector('#menuBg'); | ||
const menu = menuBg.querySelector('#menu'); | ||
|
||
window.requestAnimationFrame(() => { | ||
menu.classList.add('scale-0'); | ||
menu.classList.add('opacity-0'); | ||
menu.classList.remove('scale-100'); | ||
menu.classList.remove('opacity-100'); | ||
|
||
setTimeout(() => menuBg.classList.add('hidden'), 200); | ||
}); | ||
}); | ||
} | ||
</script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance JavaScript robustness and accessibility.
The menu functionality needs improvements in error handling and accessibility:
- Add error handling for DOM queries
- Implement proper ARIA attributes
- Consider cleanup for event listeners
Apply these changes:
document.addEventListener('DOMContentLoaded', () => {
- setupMenu();
+ try {
+ setupMenu();
+ } catch (error) {
+ console.error('Failed to setup menu:', error);
+ }
});
function setupMenu () {
const menuOpener = document.querySelector('#menuOpener');
+ if (!menuOpener) throw new Error('Menu opener button not found');
+ menuOpener.setAttribute('aria-expanded', 'false');
+ menuOpener.setAttribute('aria-controls', 'menu');
menuOpener.addEventListener('click', () => {
const menuBg = document.querySelector('#menuBg');
+ if (!menuBg) return;
menuBg.classList.remove('hidden');
const menu = menuBg.querySelector('#menu');
+ if (!menu) return;
+ menuOpener.setAttribute('aria-expanded', 'true');
window.requestAnimationFrame(() => {
menu.classList.add('scale-100');
menu.classList.add('opacity-100');
menu.classList.remove('scale-0');
menu.classList.remove('opacity-0');
});
});
const menuCloser = document.querySelector('#menuCloser');
+ if (!menuCloser) throw new Error('Menu closer button not found');
+ menuCloser.setAttribute('aria-label', 'Close menu');
menuCloser.addEventListener('click', () => {
const menuBg = document.querySelector('#menuBg');
+ if (!menuBg) return;
const menu = menuBg.querySelector('#menu');
+ if (!menu) return;
+ menuOpener.setAttribute('aria-expanded', 'false');
window.requestAnimationFrame(() => {
menu.classList.add('scale-0');
menu.classList.add('opacity-0');
menu.classList.remove('scale-100');
menu.classList.remove('opacity-100');
setTimeout(() => menuBg.classList.add('hidden'), 200);
});
});
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
document.addEventListener('DOMContentLoaded', () => { | |
setupMenu(); | |
}); | |
function setupMenu () { | |
const menuOpener = document.querySelector('#menuOpener'); | |
menuOpener.addEventListener('click', () => { | |
const menuBg = document.querySelector('#menuBg'); | |
menuBg.classList.remove('hidden'); | |
const menu = menuBg.querySelector('#menu'); | |
window.requestAnimationFrame(() => { | |
menu.classList.add('scale-100'); | |
menu.classList.add('opacity-100'); | |
menu.classList.remove('scale-0'); | |
menu.classList.remove('opacity-0'); | |
}); | |
}); | |
const menuCloser = document.querySelector('#menuCloser'); | |
menuCloser.addEventListener('click', () => { | |
const menuBg = document.querySelector('#menuBg'); | |
const menu = menuBg.querySelector('#menu'); | |
window.requestAnimationFrame(() => { | |
menu.classList.add('scale-0'); | |
menu.classList.add('opacity-0'); | |
menu.classList.remove('scale-100'); | |
menu.classList.remove('opacity-100'); | |
setTimeout(() => menuBg.classList.add('hidden'), 200); | |
}); | |
}); | |
} | |
</script> | |
document.addEventListener('DOMContentLoaded', () => { | |
try { | |
setupMenu(); | |
} catch (error) { | |
console.error('Failed to setup menu:', error); | |
} | |
}); | |
function setupMenu () { | |
const menuOpener = document.querySelector('#menuOpener'); | |
if (!menuOpener) throw new Error('Menu opener button not found'); | |
menuOpener.setAttribute('aria-expanded', 'false'); | |
menuOpener.setAttribute('aria-controls', 'menu'); | |
menuOpener.addEventListener('click', () => { | |
const menuBg = document.querySelector('#menuBg'); | |
if (!menuBg) return; | |
menuBg.classList.remove('hidden'); | |
const menu = menuBg.querySelector('#menu'); | |
if (!menu) return; | |
menuOpener.setAttribute('aria-expanded', 'true'); | |
window.requestAnimationFrame(() => { | |
menu.classList.add('scale-100'); | |
menu.classList.add('opacity-100'); | |
menu.classList.remove('scale-0'); | |
menu.classList.remove('opacity-0'); | |
}); | |
}); | |
const menuCloser = document.querySelector('#menuCloser'); | |
if (!menuCloser) throw new Error('Menu closer button not found'); | |
menuCloser.setAttribute('aria-label', 'Close menu'); | |
menuCloser.addEventListener('click', () => { | |
const menuBg = document.querySelector('#menuBg'); | |
if (!menuBg) return; | |
const menu = menuBg.querySelector('#menu'); | |
if (!menu) return; | |
menuOpener.setAttribute('aria-expanded', 'false'); | |
window.requestAnimationFrame(() => { | |
menu.classList.add('scale-0'); | |
menu.classList.add('opacity-0'); | |
menu.classList.remove('scale-100'); | |
menu.classList.remove('opacity-100'); | |
setTimeout(() => menuBg.classList.add('hidden'), 200); | |
}); | |
}); | |
} | |
</script> |
<!DOCTYPE html> | ||
<html lang="ja"> | ||
<head> | ||
<title>Title</title> | ||
<meta charset="UTF-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=Edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<meta name="robots" content="noindex"> | ||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+JP:100|Noto+Sans+JP:400|Noto+Sans+JP:500|Noto+Sans+JP:700|Noto+Sans+JP:800|Noto+Sans+JP:900|Roboto:100|Roboto:400|Roboto:700|Roboto:900&display=swap&subset=japanese" rel="stylesheet"> | ||
<script src="https://cdn.tailwindcss.com?plugins=forms"></script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add essential meta tags and optimize resource loading.
Several improvements can be made to enhance SEO and performance:
- Add essential meta tags for SEO
- Consider self-hosting Tailwind CSS for production
- Optimize font loading by only including required weights
Apply these changes:
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Title</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex">
+ <meta name="description" content="Admin interface description">
+ <meta name="theme-color" content="#ffffff">
- <link href="https://fonts.googleapis.com/css?family=Noto+Sans+JP:100|Noto+Sans+JP:400|Noto+Sans+JP:500|Noto+Sans+JP:700|Noto+Sans+JP:800|Noto+Sans+JP:900|Roboto:100|Roboto:400|Roboto:700|Roboto:900&display=swap&subset=japanese" rel="stylesheet">
+ <link href="https://fonts.googleapis.com/css?family=Noto+Sans+JP:400,700|Roboto:400,700&display=swap&subset=japanese" rel="stylesheet">
- <script src="https://cdn.tailwindcss.com?plugins=forms"></script>
+ <link href="/admin/css/tailwind.min.css" rel="stylesheet">
Committable suggestion skipped: line range outside the PR's diff.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
README.md
to include Tailwind CSS references.Chores