lib-theme-lucent: initial import (access-first set, 2026-07)
One of three candidates for the access-first / maximum-legibility theme family (WCAG AAA as identity): 7:1+ contrast on every pair (passes validate-theme.mjs --aaa), 1.125rem body floor with nothing under 14px, 44px controls for everyone, 3px focus rings, links underlined at rest, reduced-motion built in. Built for IGH/NDIS-facing surfaces first. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
473
theme.css
Normal file
473
theme.css
Normal file
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Lucent — cool daylight clarity. Access-first: WCAG AAA as identity.
|
||||
*
|
||||
* One of three candidates in the access-first family (NDIS participants,
|
||||
* their families, older support coordinators — IGH portals). The thesis:
|
||||
* maximum legibility is not compliance overhead, it IS the personality.
|
||||
* Dignity, clarity, zero squinting. GOV.UK / NHS design heritage,
|
||||
* modernized: a near-white cool field, pure white cards, TRUE near-black
|
||||
* ink, and one deep accessible blue doing all the pointing. Links are the
|
||||
* same blue and underlined BY DEFAULT — an affordance, not a decoration.
|
||||
* Boundaries are drawn with strong ink-alpha borders (0.25–0.3), not
|
||||
* shadows: low-vision users need edges, not atmosphere. Radius is a modest
|
||||
* 0.5rem; elevation is low; motion is minimal and quick with all springs
|
||||
* aliased to standard eases.
|
||||
*
|
||||
* Contrast is verified, not hoped for (Y ≈ L³; C = (Y1+.05)/(Y2+.05)):
|
||||
* LIGHT body ink 0.15 on bg 0.99 → ~19.1:1 (on white card ~19.7:1)
|
||||
* muted-fg 0.35 on white → ~11.3:1 (muted is still reading text)
|
||||
* white label on primary 0.42 → ~8.5:1 (blue's real WCAG Y sits
|
||||
* below L³, so the true ratio is higher still)
|
||||
* DARK body ink 0.96 on bg 0.16 → ~17.3:1 (on card 0.22 ~15.4:1)
|
||||
* muted-fg 0.78 on card 0.22 → ~8.7:1 (on bg ~9.7:1)
|
||||
* ink 0.15 on primary 0.74 → ~8.5:1
|
||||
* Every status pair targets ≥7:1 and never dips below 4.5:1.
|
||||
*
|
||||
* Type is Atkinson Hyperlegible (designed by the Braille Institute for
|
||||
* low-vision readers) for BOTH body and headings — hierarchy comes from
|
||||
* weight 700 and the ramp, not a second family. JetBrains Mono for code.
|
||||
* The ramp starts larger than the house norm (body 1.125rem/1.65) and the
|
||||
* caption never drops below 14px. Touch targets are 44px for EVERYONE,
|
||||
* not just coarse pointers.
|
||||
*
|
||||
* Token contract matches lib-theme-caffe-florian/theme.css (Crema v1).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fonts: consuming apps load Atkinson Hyperlegible + JetBrains Mono at the
|
||||
* top of their entry CSS (where @import statements are allowed), via the
|
||||
* Google Fonts URL documented in this theme's README. Embedding the
|
||||
* @import here — or smuggling the URL in a comment for a build script to
|
||||
* lift — breaks PostCSS's ordering rules, so neither is done in this file.
|
||||
*/
|
||||
|
||||
:root {
|
||||
--font-sans: "Atkinson Hyperlegible", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
--font-heading: "Atkinson Hyperlegible", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||
|
||||
/* Tailwind utility families. Distinct names so a consuming app's
|
||||
* `@theme inline` can indirect to these (--font-heading/--font-sans
|
||||
* collide with Tailwind's own font-* namespace). */
|
||||
--heading-family: "Atkinson Hyperlegible", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
--body-family: "Atkinson Hyperlegible", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
|
||||
/* ── Colors ── near-white cool daylight field, pure white cards, true
|
||||
* near-black cool ink. Body ink on bg ≈ 19.1:1; on card ≈ 19.7:1. */
|
||||
--background: oklch(0.99 0.002 240);
|
||||
--foreground: oklch(0.15 0.005 250);
|
||||
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.15 0.005 250);
|
||||
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.15 0.005 250);
|
||||
|
||||
/* Primary — one deep accessible blue (GOV.UK lineage) with a pure
|
||||
* white label. Approx (1+.05)/(0.42³+.05) ≈ 8.5:1; saturated blue's
|
||||
* true WCAG luminance is lower than L³, so the real ratio is higher. */
|
||||
--primary: oklch(0.42 0.15 255);
|
||||
--primary-foreground: oklch(1 0 0);
|
||||
|
||||
--secondary: oklch(0.93 0.008 245);
|
||||
--secondary-foreground: oklch(0.22 0.01 250);
|
||||
|
||||
/* muted-foreground is still reading text in an access theme — it must
|
||||
* clear 7:1 on white too. 0.35³=0.0429 → 1.05/0.0929 ≈ 11.3:1. */
|
||||
--muted: oklch(0.945 0.004 245);
|
||||
--muted-foreground: oklch(0.35 0.01 250);
|
||||
|
||||
/* Accent — a pale blue wash for hover/selection, deep blue ink on top
|
||||
* (0.854/0.083 ≈ 10.3:1). Never a second competing fill. */
|
||||
--accent: oklch(0.93 0.03 250);
|
||||
--accent-foreground: oklch(0.32 0.11 255);
|
||||
|
||||
/* ── Status ── deep solid fills with white labels (destructive /
|
||||
* success / info), dark ink on amber for warning — every pair targets
|
||||
* ≥7:1. destructive 1.05/(0.45³+.05) ≈ 7.4:1 (red's true Y is lower →
|
||||
* real ratio higher); success deepened to 0.40 because green's true Y
|
||||
* runs ABOVE L³ (1.05/0.114 ≈ 9.2:1 approx, ≈7.5:1 real); info
|
||||
* 1.05/0.124 ≈ 8.5:1; warning ink-on-amber 0.562/0.058 ≈ 9.7:1. */
|
||||
--destructive: oklch(0.45 0.17 27);
|
||||
--destructive-foreground: oklch(1 0 0);
|
||||
--success: oklch(0.40 0.11 155);
|
||||
--success-foreground: oklch(1 0 0);
|
||||
--warning: oklch(0.80 0.14 80);
|
||||
--warning-foreground: oklch(0.20 0.03 80);
|
||||
--info: oklch(0.42 0.11 230);
|
||||
--info-foreground: oklch(1 0 0);
|
||||
|
||||
/* Borders STRONG — ink at 0.25–0.3 alpha. Visible boundaries for low
|
||||
* vision, not decorative hairlines. */
|
||||
--border: oklch(0.15 0.005 250 / 0.28);
|
||||
--input: oklch(0.15 0.005 250 / 0.32);
|
||||
--ring: oklch(0.42 0.15 255);
|
||||
|
||||
/* Chart palette — blue lead, adjacent hues ≥60° apart, adjacent-index
|
||||
* lightness varied so series separate for color-blind readers too. */
|
||||
--chart-1: oklch(0.45 0.14 255);
|
||||
--chart-2: oklch(0.58 0.12 150);
|
||||
--chart-3: oklch(0.70 0.13 80);
|
||||
--chart-4: oklch(0.55 0.16 20);
|
||||
--chart-5: oklch(0.48 0.14 310);
|
||||
|
||||
--sidebar: oklch(0.965 0.004 245);
|
||||
--sidebar-foreground: oklch(0.15 0.005 250);
|
||||
--sidebar-primary: oklch(0.42 0.15 255);
|
||||
--sidebar-primary-foreground: oklch(1 0 0);
|
||||
--sidebar-accent: oklch(0.93 0.03 250);
|
||||
--sidebar-accent-foreground: oklch(0.32 0.11 255);
|
||||
--sidebar-border: oklch(0.15 0.005 250 / 0.25);
|
||||
--sidebar-ring: oklch(0.42 0.15 255);
|
||||
|
||||
/* Syntax — every token deep enough to read as body text on white;
|
||||
* comments are NOT faded into illegibility (0.40 ≈ 9:1). */
|
||||
--syntax-keyword: oklch(0.42 0.14 310);
|
||||
--syntax-string: oklch(0.42 0.10 155);
|
||||
--syntax-number: oklch(0.45 0.12 55);
|
||||
--syntax-comment: oklch(0.40 0.01 250);
|
||||
--syntax-function: oklch(0.42 0.13 255);
|
||||
--syntax-type: oklch(0.42 0.09 210);
|
||||
|
||||
/* ── Chat surfaces ──
|
||||
* User bubble is the deep blue with white text (≈8.5:1); assistant is
|
||||
* a white card with a strong visible border. */
|
||||
--chat-user-bg: oklch(0.42 0.15 255);
|
||||
--chat-user-fg: oklch(1 0 0);
|
||||
--chat-assistant-bg: oklch(1 0 0);
|
||||
--chat-assistant-fg: oklch(0.15 0.005 250);
|
||||
--chat-assistant-border: oklch(0.15 0.005 250 / 0.28);
|
||||
|
||||
/* Modest radius — calm, institutional, never pill-happy. */
|
||||
--radius: 0.5rem;
|
||||
|
||||
/* ── Motion ── minimal and quick; nothing decorative. All springs
|
||||
* alias to the standard eases — personality lives in restraint. */
|
||||
--duration-fast: 120ms;
|
||||
--duration-base: 200ms;
|
||||
--duration-slow: 300ms;
|
||||
--duration-slower: 400ms;
|
||||
--duration-spring: 200ms;
|
||||
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--ease-decelerate: cubic-bezier(0, 0, 0, 1);
|
||||
--ease-accelerate: cubic-bezier(0.3, 0, 1, 1);
|
||||
--ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
|
||||
|
||||
--ease-spring-gentle: var(--ease-standard);
|
||||
--ease-spring-snappy: var(--ease-decelerate);
|
||||
--ease-spring-bouncy: var(--ease-standard);
|
||||
|
||||
/* ── Typography ── access ramp: starts larger, generous line-heights,
|
||||
* caption never below 14px. Fixed rem, product register. */
|
||||
--text-hero-size: 3rem;
|
||||
--text-hero-lh: 1.15;
|
||||
--text-display-size: 2.5rem;
|
||||
--text-display-lh: 1.2;
|
||||
--text-headline-size: 1.875rem;
|
||||
--text-headline-lh: 1.25;
|
||||
--text-title-size: 1.5rem;
|
||||
--text-title-lh: 1.3;
|
||||
--text-subtitle-size: 1.25rem;
|
||||
--text-subtitle-lh: 1.45;
|
||||
--text-body-size: 1.125rem;
|
||||
--text-body-lh: 1.65;
|
||||
--text-label-size: 1rem;
|
||||
--text-label-lh: 1.5;
|
||||
--text-caption-size: 0.875rem;
|
||||
--text-caption-lh: 1.4;
|
||||
|
||||
/* ── Elevation ── low. Separation is the job of borders here; shadows
|
||||
* only whisper altitude for popovers and dialogs. */
|
||||
--elevation-0: none;
|
||||
--elevation-1: 0 1px 2px oklch(0.15 0.005 250 / 0.05);
|
||||
--elevation-2: 0 1px 3px oklch(0.15 0.005 250 / 0.07), 0 1px 2px oklch(0.15 0.005 250 / 0.04);
|
||||
--elevation-3: 0 4px 8px -2px oklch(0.15 0.005 250 / 0.08), 0 2px 4px -2px oklch(0.15 0.005 250 / 0.04);
|
||||
--elevation-4: 0 12px 24px -6px oklch(0.15 0.005 250 / 0.1), 0 4px 8px -4px oklch(0.15 0.005 250 / 0.05);
|
||||
--elevation-5: 0 20px 40px -8px oklch(0.15 0.005 250 / 0.14);
|
||||
|
||||
--spacing: 0.25rem;
|
||||
|
||||
/* No sub-pixel hairlines in an access theme — thin is a real 1px. */
|
||||
--border-width-thin: 1px;
|
||||
--border-width-base: 1px;
|
||||
--border-width-thick: 2px;
|
||||
--border-width-heavy: 4px;
|
||||
|
||||
/* No glass — inert values so consuming apps referencing these get no-ops. */
|
||||
--glass-blur: 0px;
|
||||
--glass-saturate: 100%;
|
||||
--glass-brightness: 1;
|
||||
--glass-contrast: 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dark mode — very dark cool charcoal with very light ink (≈17.3:1), cards
|
||||
* stepping clearly lighter (bg 0.16 → card 0.22 → popover 0.24 → muted
|
||||
* 0.26: popover above card, below muted). Primary flips to a lighter blue
|
||||
* carrying near-black ink (≈8.5:1) — dark-ink-on-bright beats
|
||||
* white-on-mid-tone.
|
||||
*/
|
||||
.dark {
|
||||
--background: oklch(0.16 0.005 250);
|
||||
--foreground: oklch(0.96 0.005 250);
|
||||
|
||||
--card: oklch(0.22 0.005 250);
|
||||
--card-foreground: oklch(0.96 0.005 250);
|
||||
|
||||
--popover: oklch(0.24 0.005 250);
|
||||
--popover-foreground: oklch(0.96 0.005 250);
|
||||
|
||||
/* Lighter blue, near-black ink: (0.74³+.05)/(0.15³+.05) ≈ 8.5:1. */
|
||||
--primary: oklch(0.74 0.11 255);
|
||||
--primary-foreground: oklch(0.15 0.01 255);
|
||||
|
||||
--secondary: oklch(0.26 0.006 250);
|
||||
--secondary-foreground: oklch(0.93 0.005 250);
|
||||
|
||||
/* muted-fg 0.78: on card 0.22 ≈ 8.7:1, on bg ≈ 9.7:1, on muted 0.26
|
||||
* ≈ 7.8:1 — muted text stays AAA reading text in dark mode too. */
|
||||
--muted: oklch(0.26 0.006 250);
|
||||
--muted-foreground: oklch(0.78 0.01 250);
|
||||
|
||||
--accent: oklch(0.30 0.05 255);
|
||||
--accent-foreground: oklch(0.85 0.08 255);
|
||||
|
||||
/* Status flips to bright swatches with near-black ink so every pair
|
||||
* clears ≥7:1: destructive 0.423/0.054 ≈ 7.8:1 approx (kept at 0.72
|
||||
* because red's true Y runs below L³); success ≈ 9.7:1; warning
|
||||
* ≈ 11.1:1; info ≈ 9.0:1. */
|
||||
--destructive: oklch(0.72 0.16 25);
|
||||
--destructive-foreground: oklch(0.16 0.02 25);
|
||||
--success: oklch(0.78 0.14 155);
|
||||
--success-foreground: oklch(0.16 0.03 155);
|
||||
--warning: oklch(0.82 0.14 80);
|
||||
--warning-foreground: oklch(0.16 0.03 80);
|
||||
--info: oklch(0.76 0.10 230);
|
||||
--info-foreground: oklch(0.15 0.03 230);
|
||||
|
||||
/* Strong light-ink borders — boundaries stay visible at night too. */
|
||||
--border: oklch(0.96 0.005 250 / 0.28);
|
||||
--input: oklch(0.96 0.005 250 / 0.32);
|
||||
--ring: oklch(0.74 0.11 255);
|
||||
|
||||
--chart-1: oklch(0.70 0.12 255);
|
||||
--chart-2: oklch(0.78 0.13 150);
|
||||
--chart-3: oklch(0.82 0.13 80);
|
||||
--chart-4: oklch(0.70 0.15 20);
|
||||
--chart-5: oklch(0.68 0.13 310);
|
||||
|
||||
--sidebar: oklch(0.18 0.005 250);
|
||||
--sidebar-foreground: oklch(0.96 0.005 250);
|
||||
--sidebar-primary: oklch(0.74 0.11 255);
|
||||
--sidebar-primary-foreground: oklch(0.15 0.01 255);
|
||||
--sidebar-accent: oklch(0.30 0.05 255);
|
||||
--sidebar-accent-foreground: oklch(0.85 0.08 255);
|
||||
--sidebar-border: oklch(0.96 0.005 250 / 0.25);
|
||||
--sidebar-ring: oklch(0.74 0.11 255);
|
||||
|
||||
--syntax-keyword: oklch(0.78 0.11 310);
|
||||
--syntax-string: oklch(0.80 0.11 155);
|
||||
--syntax-number: oklch(0.82 0.11 55);
|
||||
--syntax-comment: oklch(0.74 0.01 250);
|
||||
--syntax-function: oklch(0.78 0.10 255);
|
||||
--syntax-type: oklch(0.80 0.08 210);
|
||||
|
||||
/* ── Chat surfaces (dark) ── user bubble is a deep blue panel with
|
||||
* very light ink (≈12:1); assistant matches the card. */
|
||||
--chat-user-bg: oklch(0.30 0.06 255);
|
||||
--chat-user-fg: oklch(0.96 0.005 250);
|
||||
--chat-assistant-bg: oklch(0.22 0.005 250);
|
||||
--chat-assistant-fg: oklch(0.96 0.005 250);
|
||||
--chat-assistant-border: oklch(0.96 0.005 250 / 0.28);
|
||||
|
||||
--elevation-1: 0 1px 2px oklch(0 0 0 / 0.3);
|
||||
--elevation-2: 0 1px 3px oklch(0 0 0 / 0.4), 0 1px 2px oklch(0 0 0 / 0.25);
|
||||
--elevation-3: 0 4px 8px -2px oklch(0 0 0 / 0.4), 0 2px 4px -2px oklch(0 0 0 / 0.25);
|
||||
--elevation-4: 0 12px 24px -6px oklch(0 0 0 / 0.45), 0 4px 8px -4px oklch(0 0 0 / 0.25);
|
||||
--elevation-5: 0 20px 40px -8px oklch(0 0 0 / 0.55);
|
||||
}
|
||||
|
||||
/*
|
||||
* @layer base — Lucent's access-first philosophy.
|
||||
*
|
||||
* Atkinson Hyperlegible everywhere; no negative tracking (the font was
|
||||
* drawn for character disambiguation — don't squeeze it). Links carry a
|
||||
* real underline at rest. Boundaries are borders, not shadows.
|
||||
*/
|
||||
@layer base {
|
||||
body {
|
||||
min-height: 100vh;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
letter-spacing: 0;
|
||||
font-family: var(--font-sans);
|
||||
font-size: var(--text-body-size);
|
||||
line-height: var(--text-body-lh);
|
||||
}
|
||||
|
||||
/* Headings — same family, weight 700 does the hierarchy work.
|
||||
* `color: inherit` (NOT var(--foreground)) so headings sitting on
|
||||
* colored slabs keep the slab's foreground pairing. */
|
||||
h1, h2, h3, h4,
|
||||
[data-slot="card-title"],
|
||||
[data-slot="dialog-title"],
|
||||
[data-slot="sheet-title"],
|
||||
[data-slot="alert-dialog-title"] {
|
||||
font-family: var(--font-heading);
|
||||
font-weight: 700;
|
||||
letter-spacing: 0;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
code, kbd, samp, pre,
|
||||
[data-slot="code"],
|
||||
[data-slot="code-block"] {
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
/* Inline code — foreground-tint chip with foreground ink (house
|
||||
* pattern); slightly stronger tint so the chip boundary is visible. */
|
||||
:not(pre) > code {
|
||||
padding: 0.1em 0.35em;
|
||||
border-radius: calc(var(--radius) * 0.5);
|
||||
background: color-mix(in oklch, var(--foreground) 8%, transparent);
|
||||
color: var(--foreground);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/* Selection — a solid blue tint, ink stays put. */
|
||||
::selection {
|
||||
background: color-mix(in oklch, var(--primary) 25%, transparent);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
/* Links — the blue, UNDERLINED AT REST (an affordance you can see,
|
||||
* not one you must discover); the underline thickens on hover. */
|
||||
a {
|
||||
color: var(--primary);
|
||||
text-decoration-line: underline;
|
||||
text-decoration-thickness: 1px;
|
||||
text-decoration-color: currentColor;
|
||||
text-underline-offset: 0.2em;
|
||||
transition: text-decoration-thickness var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
a:hover {
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
|
||||
[data-slot="sidebar"] {
|
||||
background: var(--sidebar);
|
||||
border-right: var(--border-width-base) solid var(--sidebar-border);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Focus-visible — thicker than the house norm: a 3px solid ring, offset
|
||||
* 2px, on every actionable control. Keyboard users are first-class here.
|
||||
* Placed outside @layer base so it beats Tailwind's default ring utilities.
|
||||
*/
|
||||
[data-slot="button"]:focus-visible,
|
||||
[data-slot="select-trigger"]:focus-visible,
|
||||
[data-slot="checkbox"]:focus-visible,
|
||||
[data-slot="radio-group-item"]:focus-visible,
|
||||
[data-slot="switch"]:focus-visible,
|
||||
[data-slot="tabs-trigger"]:focus-visible,
|
||||
a:focus-visible {
|
||||
outline: 3px solid var(--ring);
|
||||
outline-offset: 2px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Buttons — bold labels (Atkinson ships 400/700; the 700 IS the button
|
||||
* voice, GOV.UK style). */
|
||||
[data-slot="button"] {
|
||||
font-weight: 700;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
[data-slot="button"]:hover:not(:disabled) {
|
||||
opacity: 0.9;
|
||||
}
|
||||
[data-slot="button"]:active:not(:disabled) {
|
||||
opacity: 0.82;
|
||||
}
|
||||
|
||||
/* Card titles — pinned to the subtitle role so the scale is the theme's
|
||||
* decision, not the card primitive's default. */
|
||||
[data-slot="card-title"] {
|
||||
font-size: var(--text-subtitle-size);
|
||||
line-height: var(--text-subtitle-lh);
|
||||
}
|
||||
|
||||
/* Touch targets — 44px minimum for EVERYONE, not gated behind a coarse-
|
||||
* pointer query. Tremor, low vision, and arthritis don't check your
|
||||
* pointer type. */
|
||||
[data-slot="button"] {
|
||||
min-height: 2.75rem;
|
||||
min-width: 2.75rem;
|
||||
}
|
||||
[data-slot="input"],
|
||||
[data-slot="select-trigger"] {
|
||||
min-height: 2.75rem;
|
||||
}
|
||||
|
||||
/* Coarse pointers keep the same floor (harmless, kept for parity with the
|
||||
* house pattern). */
|
||||
@media (pointer: coarse) {
|
||||
[data-slot="button"] {
|
||||
min-height: 2.75rem;
|
||||
min-width: 2.75rem;
|
||||
}
|
||||
[data-slot="input"],
|
||||
[data-slot="select-trigger"] {
|
||||
min-height: 2.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Inputs — white field, strong visible border; focus is a border-color
|
||||
* change PLUS a 2px ring so the state change never hides. */
|
||||
[data-slot="input"],
|
||||
[data-slot="textarea"],
|
||||
[data-slot="select-trigger"] {
|
||||
background: var(--card);
|
||||
border: var(--border-width-base) solid var(--input);
|
||||
border-radius: var(--radius);
|
||||
color: var(--foreground);
|
||||
transition:
|
||||
border-color var(--duration-fast) var(--ease-standard),
|
||||
box-shadow var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
[data-slot="input"]::placeholder,
|
||||
[data-slot="textarea"]::placeholder {
|
||||
color: var(--muted-foreground);
|
||||
opacity: 1;
|
||||
}
|
||||
[data-slot="input"]:hover:not(:disabled),
|
||||
[data-slot="textarea"]:hover:not(:disabled),
|
||||
[data-slot="select-trigger"]:hover:not(:disabled) {
|
||||
border-color: color-mix(in oklch, var(--foreground) 45%, transparent);
|
||||
}
|
||||
[data-slot="input"]:focus,
|
||||
[data-slot="input"]:focus-visible,
|
||||
[data-slot="textarea"]:focus,
|
||||
[data-slot="textarea"]:focus-visible,
|
||||
[data-slot="select-trigger"]:focus {
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 2px var(--ring);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Reduced motion — transitions on interactive slots drop to zero; nothing
|
||||
* in this theme is motion-dependent. */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
[data-slot="button"],
|
||||
[data-slot="input"],
|
||||
[data-slot="textarea"],
|
||||
[data-slot="select-trigger"],
|
||||
[data-slot="tabs-trigger"],
|
||||
[data-slot="switch"],
|
||||
[data-slot="checkbox"],
|
||||
a {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user