diff --git a/DESIGN.md b/DESIGN.md
new file mode 100644
index 0000000..11b0400
--- /dev/null
+++ b/DESIGN.md
@@ -0,0 +1,284 @@
+# Monochrome Design System
+
+A comprehensive design language for consistent UI/UX across the Monochrome music streaming application.
+
+## Design Tokens
+
+### Typography Scale
+
+| Token | Value | Usage |
+| ------------- | --------------- | ---------------------------- |
+| `--text-xs` | 0.75rem (12px) | Captions, badges, timestamps |
+| `--text-sm` | 0.875rem (14px) | Secondary text, labels |
+| `--text-base` | 1rem (16px) | Body text (default) |
+| `--text-md` | 1.125rem (18px) | Lead paragraphs |
+| `--text-lg` | 1.25rem (20px) | Small headings |
+| `--text-xl` | 1.5rem (24px) | H4, card titles |
+| `--text-2xl` | 1.875rem (30px) | H3 |
+| `--text-3xl` | 2.25rem (36px) | H2 |
+| `--text-4xl` | 3rem (48px) | H1 |
+| `--text-5xl` | 3.75rem (60px) | Display text |
+
+### Font Weights
+
+| Token | Value |
+| ----------------- | ----- |
+| `--font-normal` | 400 |
+| `--font-medium` | 500 |
+| `--font-semibold` | 600 |
+| `--font-bold` | 700 |
+
+### Spacing Scale
+
+| Token | Value | Pixels |
+| ------------ | ------- | ------ |
+| `--space-1` | 0.25rem | 4px |
+| `--space-2` | 0.5rem | 8px |
+| `--space-3` | 0.75rem | 12px |
+| `--space-4` | 1rem | 16px |
+| `--space-5` | 1.25rem | 20px |
+| `--space-6` | 1.5rem | 24px |
+| `--space-8` | 2rem | 32px |
+| `--space-10` | 2.5rem | 40px |
+| `--space-12` | 3rem | 48px |
+| `--space-16` | 4rem | 64px |
+
+### Border Radius Scale
+
+| Token | Value | Usage |
+| --------------- | ------ | ----------------------- |
+| `--radius-none` | 0 | Sharp corners |
+| `--radius-xs` | 2px | Small badges, tags |
+| `--radius-sm` | 4px | Inputs, small buttons |
+| `--radius-md` | 8px | Cards, panels (default) |
+| `--radius-lg` | 12px | Large cards, modals |
+| `--radius-xl` | 16px | Hero elements |
+| `--radius-2xl` | 24px | Extra large elements |
+| `--radius-full` | 9999px | Circles, pills |
+
+### Transition Timing
+
+| Token | Value |
+| -------------------- | ----- |
+| `--duration-instant` | 0ms |
+| `--duration-fast` | 150ms |
+| `--duration-normal` | 300ms |
+| `--duration-slow` | 500ms |
+
+### Easing Functions
+
+| Token | Value | Usage |
+| ----------------- | --------------------------------------- | --------------------- |
+| `--ease-linear` | linear | Continuous animations |
+| `--ease-in` | cubic-bezier(0.4, 0, 1, 1) | Entering elements |
+| `--ease-out` | cubic-bezier(0, 0, 0.2, 1) | Exiting elements |
+| `--ease-in-out` | cubic-bezier(0.4, 0, 0.2, 1) | Standard transitions |
+| `--ease-out-back` | cubic-bezier(0.34, 1.56, 0.64, 1) | Bouncy effects |
+| `--ease-elastic` | cubic-bezier(0.68, -0.55, 0.265, 1.55) | Playful animations |
+| `--ease-spring` | cubic-bezier(0.175, 0.885, 0.32, 1.275) | Snappy interactions |
+
+### Shadows
+
+| Token | Value |
+| ---------------- | ------------------------------------------------------------------- |
+| `--shadow-none` | none |
+| `--shadow-xs` | 0 1px 2px 0 rgb(0 0 0 / 0.05) |
+| `--shadow-sm` | 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1) |
+| `--shadow-md` | 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1) |
+| `--shadow-lg` | 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1) |
+| `--shadow-xl` | 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1) |
+| `--shadow-2xl` | 0 25px 50px -12px rgb(0 0 0 / 0.25) |
+| `--shadow-inner` | inset 0 2px 4px 0 rgb(0 0 0 / 0.05) |
+| `--shadow-glow` | 0 0 20px rgb(var(--highlight-rgb) / 0.5) |
+
+### Z-Index Scale
+
+| Token | Value | Usage |
+| -------------- | ----- | --------------- |
+| `--z-hide` | -1 | Hidden elements |
+| `--z-base` | 0 | Default |
+| `--z-docked` | 10 | Docked elements |
+| `--z-dropdown` | 1000 | Dropdowns |
+| `--z-sticky` | 1100 | Sticky headers |
+| `--z-banner` | 1200 | Banners |
+| `--z-overlay` | 1300 | Overlays |
+| `--z-modal` | 1400 | Modals |
+| `--z-popover` | 1500 | Popovers |
+| `--z-tooltip` | 1600 | Tooltips |
+| `--z-toast` | 1700 | Toasts |
+
+## Component Tokens
+
+### Buttons
+
+| Token | Value |
+| ------------------ | ----------------------------- |
+| `--btn-height-sm` | 32px |
+| `--btn-height-md` | 40px |
+| `--btn-height-lg` | 48px |
+| `--btn-padding-sm` | var(--space-2) var(--space-3) |
+| `--btn-padding-md` | var(--space-3) var(--space-4) |
+| `--btn-padding-lg` | var(--space-4) var(--space-6) |
+
+### Inputs
+
+| Token | Value |
+| ----------------- | ----------------------------- |
+| `--input-height` | 40px |
+| `--input-padding` | var(--space-3) var(--space-4) |
+
+### Cards
+
+| Token | Value |
+| ---------------- | ---------------- |
+| `--card-padding` | var(--space-4) |
+| `--card-gap` | var(--space-4) |
+| `--card-radius` | var(--radius-lg) |
+
+### Modals
+
+| Token | Value |
+| ---------------------- | ---------------- |
+| `--modal-padding` | var(--space-6) |
+| `--modal-radius` | var(--radius-xl) |
+| `--modal-max-width-sm` | 400px |
+| `--modal-max-width-md` | 500px |
+| `--modal-max-width-lg` | 600px |
+| `--modal-max-width-xl` | 800px |
+
+## Utility Classes
+
+### Typography
+
+```css
+.text-xs, .text-sm, .text-base, .text-md, .text-lg, .text-xl, .text-2xl, .text-3xl, .text-4xl
+.font-normal, .font-medium, .font-semibold, .font-bold
+.leading-none, .leading-tight, .leading-snug, .leading-normal, .leading-relaxed
+```
+
+### Spacing
+
+```css
+.m-0, .m-1, .m-2, .m-3, .m-4, .m-6, .m-8
+.mt-0, .mt-1, .mt-2, .mt-3, .mt-4, .mt-6
+.mb-0, .mb-1, .mb-2, .mb-3, .mb-4, .mb-6
+.ml-0, .ml-2, .ml-4
+.mr-0, .mr-2, .mr-4
+.mx-0, .mx-2, .mx-4
+.my-0, .my-2, .my-4
+.p-0, .p-1, .p-2, .p-3, .p-4, .p-6
+.px-0, .px-2, .px-3, .px-4
+.py-0, .py-1, .py-2, .py-3
+.gap-0, .gap-1, .gap-2, .gap-3, .gap-4, .gap-6
+```
+
+### Border Radius
+
+```css
+.rounded-none, .rounded-xs, .rounded-sm, .rounded-md, .rounded-lg, .rounded-xl, .rounded-full
+```
+
+### Shadows
+
+```css
+.shadow-none, .shadow-xs, .shadow-sm, .shadow-md, .shadow-lg, .shadow-xl
+```
+
+### Display & Flex
+
+```css
+.block, .inline-block, .inline, .flex, .inline-flex, .grid, .hidden
+.flex-row, .flex-col, .flex-wrap, .flex-nowrap
+.items-start, .items-center, .items-end
+.justify-start, .justify-center, .justify-end, .justify-between
+.flex-1, .flex-auto, .flex-none
+```
+
+### Text
+
+```css
+.text-left, .text-center, .text-right
+.truncate
+.line-clamp-2, .line-clamp-3
+.text-muted, .text-highlight
+```
+
+### Other
+
+```css
+.cursor-pointer, .cursor-default
+.transition-fast, .transition-normal, .transition-slow
+```
+
+## Best Practices
+
+### DO:
+
+- Use design tokens for all values
+- Use utility classes for common patterns
+- Keep component styles in CSS, not inline JS
+- Use semantic HTML elements
+- Maintain consistent spacing using the spacing scale
+
+### DON'T:
+
+- Use hardcoded pixel values
+- Use inline styles in JavaScript
+- Mix different border-radius values arbitrarily
+- Skip the spacing scale with custom values
+- Use arbitrary font sizes outside the type scale
+
+## Migration Guide
+
+### From hardcoded values:
+
+```css
+/* Before */
+.element {
+ padding: 16px;
+ font-size: 14px;
+ border-radius: 4px;
+ margin-bottom: 24px;
+}
+
+/* After */
+.element {
+ padding: var(--space-4);
+ font-size: var(--text-sm);
+ border-radius: var(--radius-sm);
+ margin-bottom: var(--space-6);
+}
+```
+
+### From inline styles:
+
+```javascript
+// Before
+element.style.cssText = 'display: flex; gap: 8px; padding: 16px;';
+
+// After
+element.classList.add('flex', 'gap-2', 'p-4');
+```
+
+## Themes
+
+The design system supports multiple themes. Each theme defines color variables while maintaining consistent spacing, typography, and other design tokens.
+
+Available themes:
+
+- `monochrome` (default)
+- `dark`
+- `ocean`
+- `purple`
+- `forest`
+- `mocha`
+- `machiatto`
+- `frappe`
+- `latte`
+- `white`
+
+## Notes
+
+- The `--highlight-rgb` variable must be in comma-separated RGB format (e.g., `245, 245, 245`) for use with `rgb()` function
+- All spacing values are in rem units for accessibility
+- The design system is mobile-first and responsive
diff --git a/js/lyrics.js b/js/lyrics.js
index c3b0125..922b2eb 100644
--- a/js/lyrics.js
+++ b/js/lyrics.js
@@ -926,6 +926,29 @@ export function openLyricsPanel(track, audioPlayer, lyricsManager, forceOpen = f
sidePanelManager.open('lyrics', 'Lyrics', renderControls, renderContent, forceOpen);
}
+function getLyricsHighlightColor() {
+ // Check if the current theme is light
+ const isLight = getComputedStyle(document.documentElement).colorScheme === 'light';
+ return isLight ? '#000' : '#fff';
+}
+
+function updateLyricsTheme() {
+ const highlightColor = getLyricsHighlightColor();
+ document.querySelectorAll('am-lyrics').forEach((el) => {
+ el.setAttribute('highlight-color', highlightColor);
+ });
+}
+
+// watch for theme changes
+const themeObserver = new MutationObserver(() => {
+ updateLyricsTheme();
+});
+
+themeObserver.observe(document.documentElement, {
+ attributes: true,
+ attributeFilter: ['data-theme', 'style'],
+});
+
async function renderLyricsComponent(container, track, audioPlayer, lyricsManager) {
container.innerHTML = '
Loading lyrics...
';
@@ -951,7 +974,7 @@ async function renderLyricsComponent(container, track, audioPlayer, lyricsManage
amLyrics.setAttribute('query', `${title} ${artist}`.trim());
if (isrc) amLyrics.setAttribute('isrc', isrc);
- amLyrics.setAttribute('highlight-color', '#93c5fd');
+ amLyrics.setAttribute('highlight-color', getLyricsHighlightColor());
amLyrics.setAttribute('hover-background-color', 'rgba(59, 130, 246, 0.14)');
amLyrics.setAttribute('autoscroll', '');
amLyrics.setAttribute('interpolate', '');
@@ -960,8 +983,6 @@ async function renderLyricsComponent(container, track, audioPlayer, lyricsManage
container.appendChild(amLyrics);
- // Setup observer IMMEDIATELY to catch lyrics as they load (not after waiting)
- // This is critical - observer must be running before lyrics arrive from LRCLIB
lyricsManager.setupLyricsObserver(amLyrics);
// If Romaji mode is enabled and track has Asian text, ensure Kuroshiro is ready
diff --git a/package-lock.json b/package-lock.json
index 2152da2..088afe7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -81,6 +81,7 @@
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -1609,6 +1610,7 @@
"integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@keyv/serialize": "^1.1.1"
}
@@ -1650,6 +1652,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
},
@@ -1693,6 +1696,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
}
@@ -3270,6 +3274,7 @@
"resolved": "https://registry.npmjs.org/@svta/cml-xml/-/cml-xml-1.0.1.tgz",
"integrity": "sha512-11LkJa5kDEcsRMWkVI1ABH3KLCxGoiSVe4kQ293ItVj8ncTTQ7htmCGiJDjS+Cmy35UgF3e/vc0ysJIiWRTx2g==",
"license": "Apache-2.0",
+ "peer": true,
"engines": {
"node": ">=20"
},
@@ -3318,6 +3323,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -3341,6 +3347,7 @@
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -3638,6 +3645,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -4675,6 +4683,7 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -7296,6 +7305,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -7379,6 +7389,7 @@
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -8484,6 +8495,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"@csstools/css-parser-algorithms": "^3.0.5",
"@csstools/css-syntax-patches-for-csstree": "^1.0.19",
@@ -8934,6 +8946,7 @@
"integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==",
"dev": true,
"license": "BSD-2-Clause",
+ "peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.15.0",
@@ -9308,6 +9321,7 @@
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@@ -9744,6 +9758,7 @@
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"rollup": "dist/bin/rollup"
},
diff --git a/styles.css b/styles.css
index 64b677e..86d160e 100644
--- a/styles.css
+++ b/styles.css
@@ -1,47 +1,189 @@
/* stylelint-disable no-descending-specificity */
+
+/* ==========================================================================
+ DESIGN SYSTEM - Monochrome
+ A comprehensive design language for consistent UI/UX
+ ========================================================================== */
+
:root {
color-scheme: light dark;
- /* Font - default to Inter for instant render, JS will override if needed */
- --font-family: 'Inter', sans-serif;
- --font-size-scale: 100%; /* Dynamic font size scale (50% - 200%) */
+ /* -------------------------------------------------------------------------
+ TYPOGRAPHY SCALE
+ Use these variables for ALL font sizes
+ ------------------------------------------------------------------------- */
+ --font-family: 'Inter', -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, sans-serif;
+ --font-size-scale: 100%;
- /* Spacing */
- --spacing-xs: 0.25rem;
- --spacing-sm: 0.5rem;
- --spacing-md: 1rem;
- --spacing-lg: 1.5rem;
- --spacing-xl: 2rem;
- --spacing-2xl: 3rem;
- --spacing-3xl: 4rem;
+ /* Typography Scale - Base 16px (1rem) */
+ --text-xs: 0.75rem; /* 12px - Captions, badges, timestamps */
+ --text-sm: 0.875rem; /* 14px - Secondary text, labels */
+ --text-base: 1rem; /* 16px - Body text (default) */
+ --text-md: 1.125rem; /* 18px - Lead paragraphs */
+ --text-lg: 1.25rem; /* 20px - Small headings */
+ --text-xl: 1.5rem; /* 24px - H4, card titles */
+ --text-2xl: 1.875rem; /* 30px - H3 */
+ --text-3xl: 2.25rem; /* 36px - H2 */
+ --text-4xl: 3rem; /* 48px - H1 */
+ --text-5xl: 3.75rem; /* 60px - Display text */
- /* Layout */
- --radius: 0.75rem;
+ /* Font Weights */
+ --font-normal: 400;
+ --font-medium: 500;
+ --font-semibold: 600;
+ --font-bold: 700;
- /* Slightly more rounded for modern feel */
- --radius-sm: 0.5rem;
- --radius-full: 9999px;
+ /* Line Heights */
+ --leading-none: 1;
+ --leading-tight: 1.25;
+ --leading-snug: 1.375;
+ --leading-normal: 1.5;
+ --leading-relaxed: 1.625;
+
+ /* -------------------------------------------------------------------------
+ SPACING SCALE
+ Use these variables for ALL spacing (margin, padding, gap)
+ ------------------------------------------------------------------------- */
+ --space-0: 0;
+ --space-1: 0.25rem; /* 4px */
+ --space-2: 0.5rem; /* 8px */
+ --space-3: 0.75rem; /* 12px */
+ --space-4: 1rem; /* 16px */
+ --space-5: 1.25rem; /* 20px */
+ --space-6: 1.5rem; /* 24px */
+ --space-8: 2rem; /* 32px */
+ --space-10: 2.5rem; /* 40px */
+ --space-12: 3rem; /* 48px */
+ --space-16: 4rem; /* 64px */
+ --space-20: 5rem; /* 80px */
+ --space-24: 6rem; /* 96px */
+
+ /* Legacy spacing aliases (deprecated, use --space-* instead) */
+ --spacing-xs: var(--space-1);
+ --spacing-sm: var(--space-2);
+ --spacing-md: var(--space-4);
+ --spacing-lg: var(--space-6);
+ --spacing-xl: var(--space-8);
+ --spacing-2xl: var(--space-12);
+ --spacing-3xl: var(--space-16);
+
+ /* -------------------------------------------------------------------------
+ BORDER RADIUS SCALE
+ Use these variables for ALL border-radius values
+ ------------------------------------------------------------------------- */
+ --radius-none: 0;
+ --radius-xs: 2px; /* Small badges, tags */
+ --radius-sm: 4px; /* Inputs, small buttons */
+ --radius-md: 8px; /* Cards, panels */
+ --radius-lg: 12px; /* Large cards, modals */
+ --radius-xl: 16px; /* Hero elements */
+ --radius-2xl: 24px; /* Extra large elements */
+ --radius-full: 9999px; /* Circles, pills, avatars */
+
+ /* Legacy radius aliases (deprecated, use --radius-md for default) */
+ --radius: var(--radius-md);
+
+ /* -------------------------------------------------------------------------
+ LAYOUT DIMENSIONS
+ ------------------------------------------------------------------------- */
--player-bar-height-desktop: 90px;
--player-bar-height-mobile: 130px;
+ --sidebar-width: 240px;
+ --sidebar-collapsed-width: 70px;
- /* Animations & Transitions */
- --transition-fast: 0.15s cubic-bezier(0.4, 0, 0.2, 1);
- --transition-normal: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- --transition-slow: 0.5s cubic-bezier(0.4, 0, 0.2, 1);
+ /* -------------------------------------------------------------------------
+ TRANSITIONS & ANIMATIONS
+ ------------------------------------------------------------------------- */
+ --duration-instant: 0ms;
+ --duration-fast: 150ms;
+ --duration-normal: 300ms;
+ --duration-slow: 500ms;
+ --ease-linear: linear;
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
--ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-elastic: cubic-bezier(0.68, -0.55, 0.265, 1.55);
+ --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
+
+ /* Legacy transition aliases */
+ --transition-fast: var(--duration-fast) var(--ease-in-out);
+ --transition-normal: var(--duration-normal) var(--ease-in-out);
+ --transition-slow: var(--duration-slow) var(--ease-in-out);
--transition: var(--transition-normal);
- /* Fallback */
-
- /* Shadows (layered for depth) */
- --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ /* -------------------------------------------------------------------------
+ SHADOWS
+ ------------------------------------------------------------------------- */
+ --shadow-none: none;
+ --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
- --shadow-glow: 0 0 15px var(--highlight-rgb);
+ --shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
+ --shadow-glow: 0 0 20px rgb(var(--highlight-rgb) / 0.5);
+
+ /* -------------------------------------------------------------------------
+ Z-INDEX SCALE
+ ------------------------------------------------------------------------- */
+ --z-hide: -1;
+ --z-base: 0;
+ --z-docked: 10;
+ --z-dropdown: 1000;
+ --z-sticky: 1100;
+ --z-banner: 1200;
+ --z-overlay: 1300;
+ --z-modal: 1400;
+ --z-popover: 1500;
+ --z-tooltip: 1600;
+ --z-toast: 1700;
+
+ /* -------------------------------------------------------------------------
+ COMPONENT TOKENS
+ ------------------------------------------------------------------------- */
+
+ /* Buttons */
+ --btn-height-sm: 32px;
+ --btn-height-md: 40px;
+ --btn-height-lg: 48px;
+ --btn-padding-sm: var(--space-2) var(--space-3);
+ --btn-padding-md: var(--space-3) var(--space-4);
+ --btn-padding-lg: var(--space-4) var(--space-6);
+
+ /* Inputs */
+ --input-height: 40px;
+ --input-padding: var(--space-3) var(--space-4);
+
+ /* Cards */
+ --card-padding: var(--space-4);
+ --card-gap: var(--space-4);
+ --card-radius: var(--radius-lg);
+
+ /* Modals */
+ --modal-padding: var(--space-6);
+ --modal-radius: var(--radius-xl);
+ --modal-max-width-sm: 400px;
+ --modal-max-width-md: 500px;
+ --modal-max-width-lg: 600px;
+ --modal-max-width-xl: 800px;
+
+ /* Covers */
--cover-filter: blur(50px) brightness(0.4);
+ --cover-radius: var(--radius-md);
+
+ /* -------------------------------------------------------------------------
+ SEMANTIC COLORS (will be overridden by themes)
+ ------------------------------------------------------------------------- */
+ --color-danger: #ef4444;
+ --color-danger-hover: #dc2626;
+ --color-success: #10b981;
+ --color-success-hover: #059669;
+ --color-warning: #f59e0b;
+ --color-warning-hover: #d97706;
+ --color-info: #3b82f6;
+ --color-info-hover: #2563eb;
}
:root[data-theme='monochrome'] {
@@ -171,7 +313,7 @@
--input: #45475a;
--ring: #89b4fa;
--highlight: #89b4fa;
- --highlight-rgb: #b4befe;
+ --highlight-rgb: 180, 190, 254;
--active-highlight: #b4befe;
--explicit-badge: #f9e2af;
}
@@ -193,7 +335,7 @@
--input: #494d64;
--ring: #8aadf4;
--highlight: #8aadf4;
- --highlight-rgb: #b7bdf8;
+ --highlight-rgb: 183, 189, 248;
--active-highlight: #b7bdf8;
--explicit-badge: #eed49f;
}
@@ -215,7 +357,7 @@
--input: #45475a;
--ring: #8caaee;
--highlight: #8caaee;
- --highlight-rgb: #babbf1;
+ --highlight-rgb: 186, 187, 241;
--active-highlight: #babbf1;
--explicit-badge: #e5c890;
}
@@ -237,7 +379,7 @@
--input: #bcc0cc;
--ring: #fdfdfd;
--highlight: #1e66f5;
- --highlight-rgb: #7287fd;
+ --highlight-rgb: 114, 135, 253;
--active-highlight: #7287fd;
--explicit-badge: #df8e1d;
}
@@ -321,13 +463,518 @@ a {
kbd {
background-color: var(--secondary);
border: 1px solid var(--border);
- border-radius: 4px;
- padding: 0.25rem 0.5rem;
- font-size: 0.85rem;
+ border-radius: var(--radius-sm);
+ padding: var(--space-1) var(--space-2);
+ font-size: var(--text-sm);
font-family: inherit;
- box-shadow: 0 2px 4px rgb(0, 0, 0, 0.1);
+ box-shadow: var(--shadow-sm);
}
+/* ==========================================================================
+ UTILITY CLASSES
+ Consistent utility classes for common patterns
+ ========================================================================== */
+
+/* Typography utilities */
+.text-xs {
+ font-size: var(--text-xs);
+}
+
+.text-sm {
+ font-size: var(--text-sm);
+}
+
+.text-base {
+ font-size: var(--text-base);
+}
+
+.text-md {
+ font-size: var(--text-md);
+}
+
+.text-lg {
+ font-size: var(--text-lg);
+}
+
+.text-xl {
+ font-size: var(--text-xl);
+}
+
+.text-2xl {
+ font-size: var(--text-2xl);
+}
+
+.text-3xl {
+ font-size: var(--text-3xl);
+}
+
+.text-4xl {
+ font-size: var(--text-4xl);
+}
+
+.font-normal {
+ font-weight: var(--font-normal);
+}
+
+.font-medium {
+ font-weight: var(--font-medium);
+}
+
+.font-semibold {
+ font-weight: var(--font-semibold);
+}
+
+.font-bold {
+ font-weight: var(--font-bold);
+}
+
+.leading-none {
+ line-height: var(--leading-none);
+}
+
+.leading-tight {
+ line-height: var(--leading-tight);
+}
+
+.leading-snug {
+ line-height: var(--leading-snug);
+}
+
+.leading-normal {
+ line-height: var(--leading-normal);
+}
+
+.leading-relaxed {
+ line-height: var(--leading-relaxed);
+}
+
+/* Spacing utilities */
+.m-0 {
+ margin: var(--space-0);
+}
+
+.m-1 {
+ margin: var(--space-1);
+}
+
+.m-2 {
+ margin: var(--space-2);
+}
+
+.m-3 {
+ margin: var(--space-3);
+}
+
+.m-4 {
+ margin: var(--space-4);
+}
+
+.m-6 {
+ margin: var(--space-6);
+}
+
+.m-8 {
+ margin: var(--space-8);
+}
+
+.mt-0 {
+ margin-top: var(--space-0);
+}
+
+.mt-1 {
+ margin-top: var(--space-1);
+}
+
+.mt-2 {
+ margin-top: var(--space-2);
+}
+
+.mt-3 {
+ margin-top: var(--space-3);
+}
+
+.mt-4 {
+ margin-top: var(--space-4);
+}
+
+.mt-6 {
+ margin-top: var(--space-6);
+}
+
+.mb-0 {
+ margin-bottom: var(--space-0);
+}
+
+.mb-1 {
+ margin-bottom: var(--space-1);
+}
+
+.mb-2 {
+ margin-bottom: var(--space-2);
+}
+
+.mb-3 {
+ margin-bottom: var(--space-3);
+}
+
+.mb-4 {
+ margin-bottom: var(--space-4);
+}
+
+.mb-6 {
+ margin-bottom: var(--space-6);
+}
+
+.ml-0 {
+ margin-left: var(--space-0);
+}
+
+.ml-2 {
+ margin-left: var(--space-2);
+}
+
+.ml-4 {
+ margin-left: var(--space-4);
+}
+
+.mr-0 {
+ margin-right: var(--space-0);
+}
+
+.mr-2 {
+ margin-right: var(--space-2);
+}
+
+.mr-4 {
+ margin-right: var(--space-4);
+}
+
+.mx-0 {
+ margin-left: var(--space-0);
+ margin-right: var(--space-0);
+}
+
+.mx-2 {
+ margin-left: var(--space-2);
+ margin-right: var(--space-2);
+}
+
+.mx-4 {
+ margin-left: var(--space-4);
+ margin-right: var(--space-4);
+}
+
+.my-0 {
+ margin-top: var(--space-0);
+ margin-bottom: var(--space-0);
+}
+
+.my-2 {
+ margin-top: var(--space-2);
+ margin-bottom: var(--space-2);
+}
+
+.my-4 {
+ margin-top: var(--space-4);
+ margin-bottom: var(--space-4);
+}
+
+.p-0 {
+ padding: var(--space-0);
+}
+
+.p-1 {
+ padding: var(--space-1);
+}
+
+.p-2 {
+ padding: var(--space-2);
+}
+
+.p-3 {
+ padding: var(--space-3);
+}
+
+.p-4 {
+ padding: var(--space-4);
+}
+
+.p-6 {
+ padding: var(--space-6);
+}
+
+.px-0 {
+ padding-left: var(--space-0);
+ padding-right: var(--space-0);
+}
+
+.px-2 {
+ padding-left: var(--space-2);
+ padding-right: var(--space-2);
+}
+
+.px-3 {
+ padding-left: var(--space-3);
+ padding-right: var(--space-3);
+}
+
+.px-4 {
+ padding-left: var(--space-4);
+ padding-right: var(--space-4);
+}
+
+.py-0 {
+ padding-top: var(--space-0);
+ padding-bottom: var(--space-0);
+}
+
+.py-1 {
+ padding-top: var(--space-1);
+ padding-bottom: var(--space-1);
+}
+
+.py-2 {
+ padding-top: var(--space-2);
+ padding-bottom: var(--space-2);
+}
+
+.py-3 {
+ padding-top: var(--space-3);
+ padding-bottom: var(--space-3);
+}
+
+.gap-0 {
+ gap: var(--space-0);
+}
+
+.gap-1 {
+ gap: var(--space-1);
+}
+
+.gap-2 {
+ gap: var(--space-2);
+}
+
+.gap-3 {
+ gap: var(--space-3);
+}
+
+.gap-4 {
+ gap: var(--space-4);
+}
+
+.gap-6 {
+ gap: var(--space-6);
+}
+
+/* Radius utilities */
+.rounded-none {
+ border-radius: var(--radius-none);
+}
+
+.rounded-xs {
+ border-radius: var(--radius-xs);
+}
+
+.rounded-sm {
+ border-radius: var(--radius-sm);
+}
+
+.rounded-md {
+ border-radius: var(--radius-md);
+}
+
+.rounded-lg {
+ border-radius: var(--radius-lg);
+}
+
+.rounded-xl {
+ border-radius: var(--radius-xl);
+}
+
+.rounded-full {
+ border-radius: var(--radius-full);
+}
+
+/* Shadow utilities */
+.shadow-none {
+ box-shadow: var(--shadow-none);
+}
+
+.shadow-xs {
+ box-shadow: var(--shadow-xs);
+}
+
+.shadow-sm {
+ box-shadow: var(--shadow-sm);
+}
+
+.shadow-md {
+ box-shadow: var(--shadow-md);
+}
+
+.shadow-lg {
+ box-shadow: var(--shadow-lg);
+}
+
+.shadow-xl {
+ box-shadow: var(--shadow-xl);
+}
+
+/* Display utilities */
+.block {
+ display: block;
+}
+
+.inline-block {
+ display: inline-block;
+}
+
+.inline {
+ display: inline;
+}
+
+.flex {
+ display: flex;
+}
+
+.inline-flex {
+ display: inline-flex;
+}
+
+.grid {
+ display: grid;
+}
+
+.hidden {
+ display: none;
+}
+
+/* Flex utilities */
+.flex-row {
+ flex-direction: row;
+}
+
+.flex-col {
+ flex-direction: column;
+}
+
+.flex-wrap {
+ flex-wrap: wrap;
+}
+
+.flex-nowrap {
+ flex-wrap: nowrap;
+}
+
+.items-start {
+ align-items: flex-start;
+}
+
+.items-center {
+ align-items: center;
+}
+
+.items-end {
+ align-items: flex-end;
+}
+
+.justify-start {
+ justify-content: flex-start;
+}
+
+.justify-center {
+ justify-content: center;
+}
+
+.justify-end {
+ justify-content: flex-end;
+}
+
+.justify-between {
+ justify-content: space-between;
+}
+
+.flex-1 {
+ flex: 1 1 0%;
+}
+
+.flex-auto {
+ flex: 1 1 auto;
+}
+
+.flex-none {
+ flex: none;
+}
+
+/* Text utilities */
+.text-left {
+ text-align: left;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.truncate {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.line-clamp-2 {
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.line-clamp-3 {
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+/* Color utilities */
+.text-muted {
+ color: var(--muted-foreground);
+}
+
+.text-highlight {
+ color: var(--highlight);
+}
+
+/* Cursor utilities */
+.cursor-pointer {
+ cursor: pointer;
+}
+
+.cursor-default {
+ cursor: default;
+}
+
+/* Transition utilities */
+.transition-fast {
+ transition: all var(--duration-fast) var(--ease-in-out);
+}
+
+.transition-normal {
+ transition: all var(--duration-normal) var(--ease-in-out);
+}
+
+.transition-slow {
+ transition: all var(--duration-slow) var(--ease-in-out);
+}
+
+/* ==========================================================================
+ APP LAYOUT
+ ========================================================================== */
+
.app-container {
display: grid;
height: 100vh;
@@ -581,13 +1228,13 @@ kbd {
#pinned-items-list .nav-item a .pinned-item-cover {
width: 24px;
height: 24px;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
flex-shrink: 0;
object-fit: cover;
}
#pinned-items-list .nav-item a .pinned-item-cover.artist {
- border-radius: 50%;
+ border-radius: var(--radius-full);
}
#pinned-items-list .nav-item a .pinned-item-name {
@@ -600,7 +1247,7 @@ kbd {
.pinned-item-collage {
width: 24px;
height: 24px;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
flex-shrink: 0;
display: grid;
grid-template-columns: 1fr 1fr;
@@ -643,7 +1290,7 @@ kbd {
.nav-btn {
width: 32px;
height: 32px;
- border-radius: 50%;
+ border-radius: var(--radius-full);
background-color: var(--card);
border: 1px solid var(--border);
@@ -1250,7 +1897,7 @@ input[type='search']::-webkit-search-cancel-button {
}
.card.artist .card-image {
- border-radius: 50%;
+ border-radius: var(--radius-full);
}
.card-image-wrapper .explicit-badge {
@@ -1307,7 +1954,7 @@ input[type='search']::-webkit-search-cancel-button {
font-size: 0.6rem;
font-weight: 700;
padding: 0.15rem 0.3rem;
- border-radius: 3px;
+ border-radius: var(--radius-xs);
margin-left: 0.5rem;
vertical-align: middle;
line-height: 1;
@@ -1319,7 +1966,7 @@ input[type='search']::-webkit-search-cancel-button {
font-size: 0.6rem;
font-weight: 700;
padding: 0.15rem 0.3rem;
- border-radius: 3px;
+ border-radius: var(--radius-xs);
margin-left: 0.5rem;
vertical-align: middle;
line-height: 1;
@@ -1502,7 +2149,7 @@ input[type='search']::-webkit-search-cancel-button {
width: 40px;
height: 40px;
background-color: var(--muted);
- border-radius: 4px;
+ border-radius: var(--radius-sm);
object-fit: cover;
flex-shrink: 0;
}
@@ -1650,7 +2297,7 @@ input[type='search']::-webkit-search-cancel-button {
}
.detail-header-image.artist {
- border-radius: 50%;
+ border-radius: var(--radius-full);
}
.detail-header-info .type {
@@ -1688,7 +2335,7 @@ input[type='search']::-webkit-search-cancel-button {
background-color: var(--secondary);
color: var(--muted-foreground);
padding: 0.15rem 0.6rem;
- border-radius: 1rem;
+ border-radius: var(--radius-full);
font-size: 0.75rem;
font-weight: 500;
text-transform: capitalize;
@@ -1726,7 +2373,7 @@ input[type='search']::-webkit-search-cancel-button {
width: 40px;
height: 40px;
padding: 0;
- border-radius: 50%;
+ border-radius: var(--radius-full);
display: flex;
align-items: center;
justify-content: center;
@@ -1827,7 +2474,7 @@ input[type='search']::-webkit-search-cancel-button {
.modal-actions .btn-secondary {
padding: 0.875rem 1.75rem;
- border-radius: 2rem;
+ border-radius: var(--radius-full);
font-weight: 600;
font-size: 0.95rem;
}
@@ -1890,7 +2537,7 @@ input[type='search']::-webkit-search-cancel-button {
content: '';
width: 14px;
height: 16px;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
flex-shrink: 0;
display: inline-block;
background-image: radial-gradient(currentcolor 1.2px, transparent 1.3px);
@@ -2091,7 +2738,7 @@ input[type='search']::-webkit-search-cancel-button {
width: 18px;
height: 18px;
background: var(--primary);
- border-radius: 50%;
+ border-radius: var(--radius-full);
cursor: pointer;
transition: background-color var(--transition-fast);
}
@@ -2104,7 +2751,7 @@ input[type='search']::-webkit-search-cancel-button {
width: 18px;
height: 18px;
background: var(--primary);
- border-radius: 50%;
+ border-radius: var(--radius-full);
cursor: pointer;
border: none;
transition: background-color var(--transition-fast);
@@ -2201,7 +2848,7 @@ input[type='search']::-webkit-search-cancel-button {
inset: 0;
background-color: var(--secondary);
transition: background-color var(--transition-normal);
- border-radius: 24px;
+ border-radius: var(--radius-2xl);
box-shadow: inset 0 2px 4px rgb(0, 0, 0, 0.1);
/* Inner shadow for depth */
@@ -2218,7 +2865,7 @@ input[type='search']::-webkit-search-cancel-button {
transition: transform var(--transition-spring, 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275));
/* Spring animation */
- border-radius: 50%;
+ border-radius: var(--radius-full);
box-shadow: 0 2px 4px rgb(0, 0, 0, 0.2);
}
@@ -2274,7 +2921,7 @@ input:checked + .slider::before {
.track-info .cover {
width: 56px;
height: 56px;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
background-color: var(--muted);
object-fit: cover;
flex-shrink: 0;
@@ -2362,7 +3009,7 @@ input:checked + .slider::before {
justify-content: center;
width: 32px;
height: 32px;
- border-radius: 50%;
+ border-radius: var(--radius-full);
position: relative;
-webkit-tap-highlight-color: transparent;
}
@@ -2451,7 +3098,7 @@ input:checked + .slider::before {
flex-grow: 1;
height: 6px;
background-color: var(--secondary);
- border-radius: 3px;
+ border-radius: var(--radius-xs);
}
.progress-bar:hover {
@@ -2462,7 +3109,7 @@ input:checked + .slider::before {
width: 0;
height: 100%;
background-color: var(--muted-foreground);
- border-radius: 3px;
+ border-radius: var(--radius-xs);
transition: background-color 0.2s ease;
position: relative;
pointer-events: none;
@@ -2482,7 +3129,7 @@ input:checked + .slider::before {
width: 12px;
height: 12px;
background-color: var(--highlight);
- border-radius: 50%;
+ border-radius: var(--radius-full);
box-shadow: 0 2px 4px rgb(0, 0, 0, 0.3);
}
@@ -2542,7 +3189,7 @@ input:checked + .slider::before {
width: 100px;
height: 4px;
background-color: var(--secondary);
- border-radius: 2px;
+ border-radius: var(--radius-xs);
}
.volume-controls .volume-bar:hover {
@@ -2553,7 +3200,7 @@ input:checked + .slider::before {
width: var(--volume-level, 70%);
height: 100%;
background-color: var(--muted-foreground);
- border-radius: 2px;
+ border-radius: var(--radius-xs);
transition: background-color 0.2s ease;
position: relative;
pointer-events: none;
@@ -2573,7 +3220,7 @@ input:checked + .slider::before {
width: 12px;
height: 12px;
background-color: var(--highlight);
- border-radius: 50%;
+ border-radius: var(--radius-full);
box-shadow: 0 2px 4px rgb(0, 0, 0, 0.3);
}
@@ -2632,7 +3279,7 @@ input:checked + .slider::before {
padding: 0.5rem 0.75rem;
margin-right: 8px;
cursor: pointer;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
transition:
background-color var(--transition-fast),
transform var(--transition-fast);
@@ -2684,7 +3331,7 @@ input:checked + .slider::before {
align-items: center;
padding: 0.5rem 0.75rem;
background: var(--accent);
- border-radius: 4px;
+ border-radius: var(--radius-sm);
margin-bottom: 0.25rem;
}
@@ -2717,7 +3364,7 @@ input:checked + .slider::before {
cursor: pointer;
padding: 0.25rem 0.5rem;
font-size: 0.8rem;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
}
.blocked-items-list .unblock-btn:hover {
@@ -2838,7 +3485,7 @@ input:checked + .slider::before {
font-size: 2rem;
width: 48px;
height: 48px;
- border-radius: 50%;
+ border-radius: var(--radius-full);
cursor: pointer;
display: flex;
align-items: center;
@@ -2953,7 +3600,7 @@ input:checked + .slider::before {
flex: 1;
height: 6px;
background: rgb(255, 255, 255, 0.2);
- border-radius: 3px;
+ border-radius: var(--radius-xs);
cursor: pointer;
position: relative;
transition: height 0.2s ease;
@@ -2966,7 +3613,7 @@ input:checked + .slider::before {
.fullscreen-progress-container .progress-fill {
height: 100%;
background: var(--foreground);
- border-radius: 3px;
+ border-radius: var(--radius-xs);
width: 0%;
transition: width 0.1s ease;
position: relative;
@@ -2987,7 +3634,7 @@ input:checked + .slider::before {
width: 12px;
height: 12px;
background-color: var(--highlight);
- border-radius: 50%;
+ border-radius: var(--radius-full);
box-shadow: 0 2px 4px rgb(0, 0, 0, 0.3);
}
@@ -3004,7 +3651,7 @@ input:checked + .slider::before {
color: var(--foreground);
cursor: pointer;
padding: 0.5rem;
- border-radius: 50%;
+ border-radius: var(--radius-full);
display: flex;
align-items: center;
justify-content: center;
@@ -3029,7 +3676,7 @@ input:checked + .slider::before {
height: 64px;
background: var(--foreground);
color: var(--background);
- border-radius: 50%;
+ border-radius: var(--radius-full);
}
.fullscreen-buttons #fs-play-pause-btn:hover {
@@ -3055,7 +3702,7 @@ input:checked + .slider::before {
color: var(--foreground);
cursor: pointer;
padding: 0.5rem;
- border-radius: 50%;
+ border-radius: var(--radius-full);
display: flex;
align-items: center;
justify-content: center;
@@ -3077,7 +3724,7 @@ input:checked + .slider::before {
width: 150px;
height: 6px;
background-color: rgb(255, 255, 255, 0.2);
- border-radius: 3px;
+ border-radius: var(--radius-xs);
cursor: pointer;
position: relative;
transition: height 0.2s ease;
@@ -3090,7 +3737,7 @@ input:checked + .slider::before {
.fs-volume-fill {
height: 100%;
background-color: var(--foreground);
- border-radius: 3px;
+ border-radius: var(--radius-xs);
width: var(--fs-volume-level, 70%);
transition: width 0.1s ease;
position: relative;
@@ -3111,7 +3758,7 @@ input:checked + .slider::before {
width: 12px;
height: 12px;
background-color: var(--highlight);
- border-radius: 50%;
+ border-radius: var(--radius-full);
box-shadow: 0 2px 4px rgb(0, 0, 0, 0.3);
}
@@ -3324,7 +3971,7 @@ input:checked + .slider::before {
width: 40px;
height: 40px;
flex-shrink: 0;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
}
.skeleton-track-details {
@@ -3372,7 +4019,7 @@ input:checked + .slider::before {
}
.skeleton-card.artist .skeleton-card-image {
- border-radius: 50%;
+ border-radius: var(--radius-full);
}
.skeleton-card-title {
@@ -3447,7 +4094,7 @@ input:checked + .slider::before {
display: flex;
align-items: center;
justify-content: center;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
transition:
transform var(--transition-fast),
color var(--transition-fast),
@@ -3711,7 +4358,7 @@ input:checked + .slider::before {
width: 6px;
height: 6px;
background-color: var(--highlight);
- border-radius: 50%;
+ border-radius: var(--radius-full);
animation: pulse 2s infinite;
}
@@ -3727,7 +4374,7 @@ input:checked + .slider::before {
width: 8px;
height: 8px;
background-color: #10b981;
- border-radius: 50%;
+ border-radius: var(--radius-full);
}
#download-current-btn:disabled {
@@ -3757,7 +4404,7 @@ input:checked + .slider::before {
.template-guide code {
background-color: var(--secondary);
padding: 0.2rem 0.4rem;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
font-size: 0.85em;
}
@@ -4290,7 +4937,7 @@ img[src=''] {
border: none;
color: white;
padding: 0.75rem;
- border-radius: 50%;
+ border-radius: var(--radius-full);
cursor: pointer;
z-index: 1001;
display: flex;
@@ -4465,7 +5112,7 @@ img[src=''] {
width: 100%;
height: 8px;
background: var(--secondary);
- border-radius: 4px;
+ border-radius: var(--radius-sm);
overflow: hidden;
position: relative;
}
@@ -4473,7 +5120,7 @@ img[src=''] {
.csv-import-progress .progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary), var(--highlight));
- border-radius: 4px;
+ border-radius: var(--radius-sm);
width: 0%;
transition: width 0.3s ease;
position: relative;
@@ -5428,7 +6075,7 @@ img[src=''] {
width: 16px;
height: 16px;
background-color: var(--highlight);
- border-radius: 50%;
+ border-radius: var(--radius-full);
box-shadow: 0 2px 6px rgb(0, 0, 0, 0.3);
}
@@ -5574,7 +6221,7 @@ body:has(#fullscreen-cover-overlay:not([style*='display: none'])) .now-playing-b
.genius-annotated {
background-color: rgb(255, 255, 100, 0.1);
cursor: pointer;
- border-radius: 4px;
+ border-radius: var(--radius-sm);
transition: background-color 0.2s;
}
@@ -6290,7 +6937,7 @@ textarea:focus {
width: 18px;
height: 18px;
background: linear-gradient(145deg, var(--primary), var(--highlight));
- border-radius: 50%;
+ border-radius: var(--radius-full);
cursor: grab;
margin-left: -6px;
box-shadow:
@@ -6306,7 +6953,7 @@ textarea:focus {
width: 18px;
height: 18px;
background: linear-gradient(145deg, var(--primary), var(--highlight));
- border-radius: 50%;
+ border-radius: var(--radius-full);
cursor: grab;
box-shadow:
0 2px 8px rgb(0, 0, 0, 0.3),