mirror of
https://github.com/luxfi/design.git
synced 2026-10-30 16:58:57 +00:00
The catalog names @hanzo/design 0.5.24 and typescript 7.0.2, but the lock
still resolved ^0.5.18 and ^5.9.3, so a frozen install of this head refuses
("specifiers in the lockfile don't match specifiers in package.json"), and
styles.css, tailwind.css and tokens.gen.ts were last generated from 0.5.18.
This is `pnpm install` under the pinned pnpm 11.24.0 followed by
`pnpm build`, nothing hand-edited: the lock states the catalog's versions,
and the sheets inherit 0.5.24 — --font-feature-settings is now `normal` and
the scrollbar button is hidden, both substrate changes. All 26 token checks
pass and tsc emits dist/ cleanly.
Co-authored-by: Hanzo Dev <[email protected]>
947 lines
40 KiB
CSS
947 lines
40 KiB
CSS
/* Lux Design System — Tailwind v4 bridge. The ONE import a Tailwind app adds.
|
||
*
|
||
* AUTO-GENERATED by scripts/gen-tokens.mjs — DO NOT EDIT.
|
||
*
|
||
* @import "tailwindcss";
|
||
* @import "@luxfi/design/tailwind.css";
|
||
*
|
||
* Import it AFTER tailwindcss — @theme has to follow the framework it extends.
|
||
* The tokens are inlined rather than @imported because an @import must precede
|
||
* every other rule; placed after tailwindcss it would be invalid and the browser
|
||
* would drop the whole token layer without a word.
|
||
*/
|
||
/* Lux Design System — the entry point. Import THIS one file.
|
||
*
|
||
* AUTO-GENERATED by scripts/gen-tokens.mjs — DO NOT EDIT.
|
||
* Edit tokens/brand.css and re-run "pnpm gen".
|
||
*
|
||
* The neutral system below is inherited from @hanzo/[email protected] at build
|
||
* time and is not maintained here; the Lux brand layer is the last block in the
|
||
* file. Typeface: Zen — this sheet declares no @font-face and no url(), so
|
||
* install @hanzo/font and import "@hanzo/font/css" ahead of this one if you want
|
||
* the faces rather than the system stack. See scripts/gen-tokens.mjs for why.
|
||
*/
|
||
|
||
/* ── inherited: colors ───────────────────────────────────── */
|
||
:root{
|
||
color-scheme:dark;
|
||
|
||
|
||
--neutral-50:#FAFAFA;
|
||
--neutral-100:#F5F5F5;
|
||
--neutral-200:#E5E5E5;
|
||
--neutral-300:#D4D4D4;
|
||
--neutral-400:#A3A3A3;
|
||
--neutral-500:#737373;
|
||
--neutral-600:#525252;
|
||
--neutral-700:#404040;
|
||
--neutral-800:#262626;
|
||
--neutral-900:#171717;
|
||
--neutral-950:#0A0A0A;
|
||
--pure-black:#000000;
|
||
--pure-white:#FFFFFF;
|
||
|
||
--lux-black:#0A0A0B;
|
||
--lux-white:#FFFFFF;
|
||
|
||
|
||
|
||
|
||
--white-03:rgb(255 255 255 / .03);
|
||
--white-05:rgb(255 255 255 / .05);
|
||
--white-06:rgb(255 255 255 / .06);
|
||
--white-08:rgb(255 255 255 / .08);
|
||
--white-10:rgb(255 255 255 / .10);
|
||
--white-14:rgb(255 255 255 / .14);
|
||
--white-15:rgb(255 255 255 / .15);
|
||
--white-16:rgb(255 255 255 / .16);
|
||
--white-18:rgb(255 255 255 / .18);
|
||
--white-20:rgb(255 255 255 / .20);
|
||
--white-22:rgb(255 255 255 / .22);
|
||
--white-30:rgb(255 255 255 / .30);
|
||
--white-40:rgb(255 255 255 / .40);
|
||
--white-45:rgb(255 255 255 / .45);
|
||
--white-55:rgb(255 255 255 / .55);
|
||
--white-60:rgb(255 255 255 / .60);
|
||
--white-78:rgb(255 255 255 / .78);
|
||
--white-80:rgb(255 255 255 / .80);
|
||
--white-92:rgb(255 255 255 / .92);
|
||
|
||
|
||
--background:#0a0a0a;
|
||
|
||
--foreground:#e5e5e5;
|
||
--card:#0f0f0f;
|
||
--card-foreground:#e5e5e5;
|
||
--popover:#0f0f0f;
|
||
--popover-foreground:#e5e5e5;
|
||
--primary:#fafafa;
|
||
|
||
--primary-hover:#e5e5e5;
|
||
--primary-foreground:#0a0a0a;
|
||
--secondary:#262626;
|
||
|
||
--secondary-hover:#333333;
|
||
--secondary-foreground:#fafafa;
|
||
--muted:#171717;
|
||
--muted-foreground:#a3a3a3;
|
||
--accent:#262626;
|
||
--accent-foreground:#fafafa;
|
||
|
||
--destructive:var(--state-error);
|
||
--destructive-hover:#dc2626;
|
||
--destructive-foreground:#fafafa;
|
||
|
||
|
||
--border:var(--white-10);
|
||
--border-strong:var(--white-16);
|
||
--border-control:var(--white-15);
|
||
--border-focus:var(--white-22);
|
||
--border-selected:var(--white-30);
|
||
--input:var(--border-control);
|
||
|
||
--ring:var(--white-40);
|
||
|
||
--ring-halo:var(--white-10);
|
||
--brand:#e4e4e7;
|
||
--brand-foreground:#09090b;
|
||
--brand-muted:#a3a3a3;
|
||
--black:#000000;
|
||
--white:#fafafa;
|
||
--selection:var(--white-20);
|
||
|
||
|
||
--glass:var(--white-05);
|
||
--glass-strong:var(--white-08);
|
||
|
||
|
||
--surface-page:var(--background);
|
||
--surface-card:rgb(38 38 38 / .5);
|
||
--surface-card-emphasis:rgb(38 38 38 / .75);
|
||
--surface-card-quiet:rgb(38 38 38 / .35);
|
||
|
||
--surface-overlay:rgb(23 23 23 / .92);
|
||
--surface-header:rgb(0 0 0 / .7);
|
||
--surface-scrim:rgb(0 0 0 / .8);
|
||
|
||
|
||
|
||
--surface-0:var(--background);
|
||
--surface-1:var(--card);
|
||
--surface-2:var(--muted);
|
||
--surface-3:var(--secondary);
|
||
|
||
|
||
--text-primary:#fafafa;
|
||
--text-secondary:var(--white-78);
|
||
--text-tertiary:var(--white-55);
|
||
--text-helper:var(--muted-foreground);
|
||
--text-disabled:var(--white-30);
|
||
|
||
|
||
--state-error:#ef4444;
|
||
--state-error-text:#fca5a5;
|
||
--state-error-bg:rgb(239 68 68 / .1);
|
||
--state-online:#4ade80;
|
||
--state-success:#22c55e;
|
||
--chrome-dot-red:rgb(239 68 68 / .6);
|
||
--chrome-dot-yellow:rgb(234 179 8 / .6);
|
||
--chrome-dot-green:rgb(34 197 94 / .6);
|
||
}
|
||
|
||
.light{
|
||
color-scheme:light;
|
||
--background:#f7f7f7;
|
||
--foreground:#0a0a0a;
|
||
|
||
--card:#f2f2f2;
|
||
--card-foreground:#0a0a0a;
|
||
--popover:#fbfbfb;
|
||
--popover-foreground:#0a0a0a;
|
||
--primary:#0a0a0a;
|
||
--primary-hover:#262626;
|
||
--primary-foreground:#fafafa;
|
||
--secondary:#e4e4e4;
|
||
--secondary-hover:#e0e0e0;
|
||
--secondary-foreground:#0a0a0a;
|
||
--muted:#ededed;
|
||
--muted-foreground:#525252;
|
||
--accent:#e4e4e4;
|
||
--accent-foreground:#0a0a0a;
|
||
--destructive:var(--state-error);
|
||
--destructive-hover:#dc2626;
|
||
--destructive-foreground:#ffffff;
|
||
--border:rgb(0 0 0 / .10);
|
||
--border-strong:rgb(0 0 0 / .16);
|
||
--border-control:rgb(0 0 0 / .15);
|
||
|
||
--border-focus:rgb(0 0 0 / .32);
|
||
--border-selected:rgb(0 0 0 / .42);
|
||
--input:var(--border-control);
|
||
|
||
--ring:rgb(0 0 0 / .5);
|
||
--ring-halo:rgb(0 0 0 / .07);
|
||
--black:#0a0a0a;
|
||
--white:#ffffff;
|
||
--selection:rgb(0 0 0 / .16);
|
||
--glass:rgb(0 0 0 / .04);
|
||
--glass-strong:rgb(0 0 0 / .07);
|
||
--surface-card:#f2f2f2;
|
||
--surface-card-emphasis:#fdfdfd;
|
||
--surface-card-quiet:#f5f5f5;
|
||
--surface-overlay:rgb(255 255 255 / .95);
|
||
--surface-header:rgb(255 255 255 / .8);
|
||
--surface-scrim:rgb(0 0 0 / .5);
|
||
--text-primary:var(--neutral-950);
|
||
--text-secondary:rgb(10 10 10 / .78);
|
||
--text-tertiary:rgb(10 10 10 / .55);
|
||
--text-disabled:rgb(10 10 10 / .3);
|
||
}
|
||
|
||
/* ── inherited: typography ───────────────────────────────────── */
|
||
:root{
|
||
|
||
--type-scale:1;
|
||
|
||
|
||
--type-ratio:1;
|
||
|
||
|
||
--text-floor:0.625rem;
|
||
--text-ceiling:30vw;
|
||
--text-xs:clamp(var(--text-floor), calc((0.875rem - 0.1875rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-xs:calc((1.35rem - 0.35rem * var(--type-ratio, 1)) * var(--type-scale, 1));
|
||
--text-sm:clamp(var(--text-floor), calc((0.875rem - 0.0625rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-sm:calc((1.35rem - 0.2rem * var(--type-ratio, 1)) * var(--type-scale, 1));
|
||
--text-base:clamp(var(--text-floor), calc(0.875rem * var(--type-scale, 1)), var(--text-ceiling)); --leading-base:calc(1.35rem * var(--type-scale, 1));
|
||
--text-lg:clamp(var(--text-floor), calc((0.875rem + 0.0625rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-lg:calc((1.35rem + 0.05rem * var(--type-ratio, 1)) * var(--type-scale, 1));
|
||
--text-xl:clamp(var(--text-floor), calc((0.875rem + 0.1875rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-xl:calc((1.35rem + 0.2rem * var(--type-ratio, 1)) * var(--type-scale, 1));
|
||
--text-2xl:clamp(var(--text-floor), calc((0.875rem + 0.4375rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-2xl:calc((1.35rem + 0.35rem * var(--type-ratio, 1)) * var(--type-scale, 1));
|
||
--text-3xl:clamp(var(--text-floor), calc((0.875rem + 0.75rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-3xl:calc((1.35rem + 0.6rem * var(--type-ratio, 1)) * var(--type-scale, 1));
|
||
--text-4xl:clamp(var(--text-floor), calc((0.875rem + 1.125rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-4xl:calc((1.35rem + 0.9rem * var(--type-ratio, 1)) * var(--type-scale, 1));
|
||
--text-5xl:clamp(var(--text-floor), calc((0.875rem + 1.625rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-5xl:1.05;
|
||
--text-6xl:clamp(var(--text-floor), calc((0.875rem + 2.375rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-6xl:1;
|
||
--text-7xl:clamp(var(--text-floor), calc((0.875rem + 3.125rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-7xl:1;
|
||
--text-8xl:clamp(var(--text-floor), calc((0.875rem + 4.375rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-8xl:1;
|
||
--text-9xl:clamp(var(--text-floor), calc((0.875rem + 6.125rem * var(--type-ratio, 1)) * var(--type-scale, 1)), var(--text-ceiling)); --leading-9xl:1;
|
||
|
||
|
||
--font-size-xs:var(--text-xs);
|
||
--font-size-sm:var(--text-sm);
|
||
--font-size-base:var(--text-base);
|
||
--font-size-lg:var(--text-lg);
|
||
--font-size-xl:var(--text-xl);
|
||
--font-size-2xl:var(--text-2xl);
|
||
--font-size-3xl:var(--text-3xl);
|
||
--font-size-4xl:var(--text-4xl);
|
||
--font-size-5xl:var(--text-5xl);
|
||
--font-size-6xl:var(--text-6xl);
|
||
--font-size-7xl:var(--text-7xl);
|
||
--font-size-8xl:var(--text-8xl);
|
||
--font-size-9xl:var(--text-9xl);
|
||
|
||
|
||
--text-control:var(--text-sm);
|
||
|
||
--weight-normal:400;
|
||
--weight-medium:500;
|
||
--weight-semibold:600;
|
||
--weight-bold:700;
|
||
|
||
--tracking-tight:-0.025em;
|
||
--tracking-normal:0em;
|
||
--tracking-wide:0.025em;
|
||
--tracking-widest:0.1em;
|
||
|
||
--leading-none:1;
|
||
--leading-tight:1.25;
|
||
--leading-snug:1.375;
|
||
--leading-normal:1.5;
|
||
--leading-relaxed:1.625;
|
||
--leading-golden:1.618;
|
||
|
||
|
||
--type-hero:600 var(--text-5xl)/1.05 var(--font-display);
|
||
--type-h2:700 var(--text-4xl)/var(--leading-4xl) var(--font-display);
|
||
--type-h3:600 var(--text-xl)/var(--leading-xl) var(--font-display);
|
||
--type-lead:400 var(--text-lg)/var(--leading-relaxed) var(--font-sans);
|
||
--type-body:400 var(--text-sm)/var(--leading-sm) var(--font-sans);
|
||
--type-caption:400 var(--text-xs)/var(--leading-xs) var(--font-sans);
|
||
--type-code:400 var(--text-sm)/var(--leading-relaxed) var(--font-mono);
|
||
--type-eyebrow:600 0.625rem/1 var(--font-sans);
|
||
}
|
||
|
||
@media (pointer:coarse){
|
||
:root{--text-control:calc(1rem * var(--type-scale, 1))}
|
||
}
|
||
|
||
/* ── inherited: spacing ───────────────────────────────────── */
|
||
:root{
|
||
|
||
--density:1;
|
||
|
||
--space-0:0;
|
||
--space-1:calc(0.25rem * var(--density, 1));
|
||
--space-2:calc(0.5rem * var(--density, 1));
|
||
--space-3:calc(0.75rem * var(--density, 1));
|
||
--space-4:calc(1rem * var(--density, 1));
|
||
--space-5:calc(1.25rem * var(--density, 1));
|
||
--space-6:calc(1.5rem * var(--density, 1));
|
||
--space-8:calc(2rem * var(--density, 1));
|
||
--space-10:calc(2.5rem * var(--density, 1));
|
||
--space-12:calc(3rem * var(--density, 1));
|
||
--space-14:calc(3.5rem * var(--density, 1));
|
||
--space-16:calc(4rem * var(--density, 1));
|
||
--space-20:calc(5rem * var(--density, 1));
|
||
--space-24:calc(6rem * var(--density, 1));
|
||
--space-32:calc(8rem * var(--density, 1));
|
||
|
||
|
||
--golden-1:0.25rem;
|
||
--golden-2:0.405rem;
|
||
--golden-3:0.654rem;
|
||
--golden-4:1.059rem;
|
||
--golden-5:1.713rem;
|
||
--golden-6:2.772rem;
|
||
--golden-7:4.487rem;
|
||
--golden-8:7.26rem;
|
||
--golden-9:11.749rem;
|
||
--golden-split:38.2% 61.8%;
|
||
|
||
|
||
--container-max:80rem;
|
||
--container-prose:48rem;
|
||
--container-wide:72rem;
|
||
|
||
--gutter:max(1rem,var(--safe-left),var(--safe-right));
|
||
--gutter-sm:1.5rem;
|
||
--gutter-lg:2rem;
|
||
--section-y:2.5rem;
|
||
--section-y-lg:3.5rem;
|
||
--hero-y:3rem;
|
||
--hero-y-lg:4.5rem;
|
||
--header-height:3.5rem;
|
||
|
||
|
||
|
||
--tap-target:44px;
|
||
|
||
|
||
|
||
--control-height-sm:32px;
|
||
--control-height:36px;
|
||
--control-height-lg:40px;
|
||
--control-height-xl:52px;
|
||
|
||
|
||
|
||
--safe-top:env(safe-area-inset-top,0px);
|
||
--safe-right:env(safe-area-inset-right,0px);
|
||
--safe-bottom:env(safe-area-inset-bottom,0px);
|
||
--safe-left:env(safe-area-inset-left,0px);
|
||
}
|
||
|
||
@media (min-width:48rem){
|
||
:root{
|
||
--section-y:4rem;
|
||
--section-y-lg:6rem;
|
||
--hero-y:5rem;
|
||
--hero-y-lg:8rem;
|
||
--header-height:4rem;
|
||
}
|
||
}
|
||
|
||
/* ── inherited: grid ───────────────────────────────────── */
|
||
:root{
|
||
|
||
--grid-columns:12;
|
||
|
||
|
||
--grid-gap:var(--space-6);
|
||
--grid-gap-tight:var(--space-4);
|
||
--grid-gap-loose:var(--space-8);
|
||
|
||
|
||
--breakpoint-sm:40rem;
|
||
--breakpoint-md:48rem;
|
||
--breakpoint-lg:64rem;
|
||
--breakpoint-xl:80rem;
|
||
--breakpoint-2xl:96rem;
|
||
|
||
|
||
--grid-card-min:18rem;
|
||
--grid-card-min-wide:24rem;
|
||
}
|
||
|
||
/* ── inherited: radius ───────────────────────────────────── */
|
||
:root{
|
||
--radius:0.5rem;
|
||
--radius-sm:0.375rem;
|
||
--radius-md:0.5rem;
|
||
--radius-lg:0.75rem;
|
||
--radius-xl:1rem;
|
||
--radius-2xl:1.5rem;
|
||
--radius-composer:28px;
|
||
--radius-full:9999px;
|
||
}
|
||
|
||
/* ── inherited: elevation ───────────────────────────────────── */
|
||
:root{
|
||
--shadow-none:none;
|
||
|
||
--shadow-floating:0 24px 60px -16px rgb(0 0 0 / .75);
|
||
--shadow-inset-hairline:inset 0 0 0 1px var(--white-10);
|
||
|
||
|
||
|
||
--edge-highlight:inset 0 1px 0 0 rgb(255 255 255 / .10);
|
||
|
||
--bloom:0 0 24px -2px rgb(255 255 255 / .28);
|
||
|
||
--ring-focus:0 0 0 3px var(--ring-halo);
|
||
|
||
|
||
--shadow-sm:0 1px 2px 0 rgb(0 0 0 / .40);
|
||
--shadow:0 1px 3px 0 rgb(0 0 0 / .45), 0 1px 2px -1px rgb(0 0 0 / .45);
|
||
--shadow-md:0 4px 6px -1px rgb(0 0 0 / .50), 0 2px 4px -2px rgb(0 0 0 / .50);
|
||
--shadow-lg:0 10px 15px -3px rgb(0 0 0 / .55), 0 4px 6px -4px rgb(0 0 0 / .55);
|
||
--shadow-xl:0 20px 25px -5px rgb(0 0 0 / .60), 0 8px 10px -6px rgb(0 0 0 / .60);
|
||
--shadow-2xl:var(--shadow-floating);
|
||
|
||
|
||
|
||
--sheet-0:var(--surface-page);
|
||
--sheet-1:var(--surface-card);
|
||
--sheet-2:var(--surface-card-emphasis);
|
||
|
||
--shadow-sheet-1:var(--edge-highlight),0 1px 2px 0 rgb(0 0 0 / .40);
|
||
--shadow-sheet-2:var(--edge-highlight),0 10px 15px -3px rgb(0 0 0 / .55),0 4px 6px -4px rgb(0 0 0 / .55);
|
||
|
||
|
||
--fold:12px;
|
||
--fold-face:linear-gradient(315deg,var(--glass-strong) 0,var(--glass-strong) calc(var(--fold) - 1px),var(--border-strong) calc(var(--fold) - 1px),var(--border-strong) var(--fold),transparent var(--fold));
|
||
|
||
|
||
--glow-hero:radial-gradient(circle,rgb(255 255 255 / .12) 0%,transparent 68%);
|
||
--glow-hero-blur:120px;
|
||
|
||
--sheen-card:radial-gradient(120% 120% at 80% 0%,rgb(255 255 255 / .08) 0%,transparent 55%);
|
||
|
||
--sheen-edge:linear-gradient(90deg,transparent,rgb(255 255 255 / .14) 50%,transparent);
|
||
|
||
--gradient-chrome:linear-gradient(to right,#ffffff,var(--white-80),var(--white-60));
|
||
--gradient-chrome-2:linear-gradient(to right,#ffffff,var(--neutral-500));
|
||
|
||
--gradient-protect:linear-gradient(to bottom,var(--white-10),transparent);
|
||
}
|
||
|
||
.light{
|
||
--shadow-floating:0 24px 60px -16px rgb(0 0 0 / .18);
|
||
|
||
--shadow-sheet-1:var(--edge-highlight),0 1px 2px 0 rgb(0 0 0 / .06);
|
||
--shadow-sheet-2:var(--edge-highlight),0 10px 15px -3px rgb(0 0 0 / .09),0 4px 6px -4px rgb(0 0 0 / .07);
|
||
--shadow-inset-hairline:inset 0 0 0 1px rgb(0 0 0 / .10);
|
||
--edge-highlight:inset 0 0 0 0 transparent;
|
||
--bloom:0 6px 20px -4px rgb(0 0 0 / .18);
|
||
--shadow-sm:0 1px 2px 0 rgb(0 0 0 / .06);
|
||
--shadow:0 1px 3px 0 rgb(0 0 0 / .08), 0 1px 2px -1px rgb(0 0 0 / .06);
|
||
--shadow-md:0 4px 6px -1px rgb(0 0 0 / .08), 0 2px 4px -2px rgb(0 0 0 / .06);
|
||
--shadow-lg:0 10px 15px -3px rgb(0 0 0 / .09), 0 4px 6px -4px rgb(0 0 0 / .07);
|
||
--shadow-xl:0 20px 25px -5px rgb(0 0 0 / .10), 0 8px 10px -6px rgb(0 0 0 / .08);
|
||
--glow-hero:radial-gradient(circle,rgb(0 0 0 / .06) 0%,transparent 68%);
|
||
--sheen-card:radial-gradient(120% 120% at 80% 0%,rgb(0 0 0 / .04) 0%,transparent 55%);
|
||
--sheen-edge:linear-gradient(90deg,transparent,rgb(0 0 0 / .08) 50%,transparent);
|
||
--gradient-chrome:linear-gradient(to right,#0a0a0a,rgb(10 10 10 / .8),rgb(10 10 10 / .6));
|
||
--gradient-chrome-2:linear-gradient(to right,#0a0a0a,var(--neutral-500));
|
||
--gradient-protect:linear-gradient(to bottom,rgb(0 0 0 / .10),transparent);
|
||
}
|
||
|
||
/* ── inherited: motion ───────────────────────────────────── */
|
||
:root{
|
||
--duration-fast:150ms;
|
||
--duration-base:300ms;
|
||
--duration-slow:400ms;
|
||
--duration-slower:500ms;
|
||
--duration-glow:9s;
|
||
--duration-press:90ms;
|
||
--ease-out:cubic-bezier(0,0,0.2,1);
|
||
--ease-in-out:cubic-bezier(0.4,0,0.2,1);
|
||
|
||
--ease-emphasis:cubic-bezier(0.16,1,0.3,1);
|
||
--stagger:60ms;
|
||
--entry-rise:16px;
|
||
--entry-rise-lg:24px;
|
||
}
|
||
|
||
@keyframes lux-fade-up{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
|
||
@keyframes lux-fade-down{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}
|
||
@keyframes lux-slide-up-fade{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}
|
||
|
||
@keyframes lux-zoom-in{from{opacity:0;transform:scale(.97) translateY(8px)}to{opacity:1;transform:none}}
|
||
@keyframes lux-glow{0%,100%{transform:scale(1);opacity:.45}50%{transform:scale(1.08);opacity:.65}}
|
||
@keyframes lux-pulse-dot{0%,100%{opacity:1}50%{opacity:.35}}
|
||
|
||
@media (prefers-reduced-motion:reduce){
|
||
*,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
|
||
}
|
||
|
||
/* ── inherited: z ───────────────────────────────────── */
|
||
:root{
|
||
--z-base:0;
|
||
--z-raised:10;
|
||
--z-sticky:200;
|
||
--z-header:300;
|
||
--z-dropdown:400;
|
||
--z-overlay:500;
|
||
--z-modal:600;
|
||
--z-popover:700;
|
||
--z-toast:800;
|
||
|
||
|
||
--z-tooltip:var(--z-popover);
|
||
--z-notification:var(--z-toast);
|
||
}
|
||
|
||
/* ── inherited: fonts ───────────────────────────────────── */
|
||
:root{
|
||
--font-sans:"Zen",ui-sans-serif,system-ui,sans-serif;
|
||
--font-display:var(--font-sans);
|
||
--font-mono:"Zen Mono",ui-monospace,SFMono-Regular,monospace;
|
||
--font-serif:Georgia,serif;
|
||
|
||
--font-feature-settings:normal;
|
||
}
|
||
|
||
/* ── inherited: base ───────────────────────────────────── */
|
||
@layer base {
|
||
*{box-sizing:border-box;border-color:var(--border)}
|
||
html{
|
||
-webkit-font-smoothing:antialiased;
|
||
text-rendering:optimizeLegibility;
|
||
scroll-behavior:smooth;
|
||
|
||
-webkit-text-size-adjust:100%;
|
||
}
|
||
|
||
body{margin:0;background:var(--background);color:var(--foreground);font-family:var(--font-sans,ui-sans-serif,system-ui,sans-serif);font-size:var(--text-base);line-height:var(--leading-base);font-feature-settings:var(--font-feature-settings);overflow-wrap:break-word}
|
||
h1,h2,h3,h4{margin:0;font-family:var(--font-display,var(--font-sans,ui-sans-serif,system-ui,sans-serif));letter-spacing:var(--tracking-tight);color:var(--text-primary)}
|
||
p{margin:0;text-wrap:pretty}
|
||
code,pre,kbd{font-family:var(--font-mono,ui-monospace,SFMono-Regular,monospace)}
|
||
|
||
a{color:var(--text-primary);text-decoration:none;text-underline-offset:4px}
|
||
|
||
:is(p,li,blockquote,dd,dt,td,th,figcaption) a:hover{text-decoration:underline}
|
||
|
||
|
||
:where(a,button,[role=button],input,select,textarea,summary,[tabindex]){
|
||
transition:color var(--duration-fast) var(--ease-out),
|
||
background-color var(--duration-fast) var(--ease-out),
|
||
border-color var(--duration-fast) var(--ease-out),
|
||
box-shadow var(--duration-fast) var(--ease-out),
|
||
opacity var(--duration-fast) var(--ease-out),
|
||
transform var(--duration-press) var(--ease-out);
|
||
}
|
||
|
||
|
||
:where(button,[role=button],a[role=button],summary):active:not(:disabled){
|
||
transform:scale(.98);
|
||
}
|
||
|
||
|
||
:where(input,select,textarea,button){font:inherit;color:inherit}
|
||
:where(input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]),select,textarea){
|
||
background:var(--surface-2);
|
||
border:1px solid var(--border-control);
|
||
|
||
border-radius:var(--radius-md);
|
||
padding:0 var(--space-3);
|
||
|
||
--ring-offset:-2px;
|
||
}
|
||
:where(textarea){padding:var(--space-2) var(--space-3);resize:vertical}
|
||
|
||
:where(input,select,textarea):hover:not(:focus-visible):not(:disabled){background:var(--surface-3)}
|
||
:where(input,textarea)::placeholder{color:var(--text-disabled)}
|
||
:where(input,select,textarea,button):disabled{opacity:.5;cursor:not-allowed}
|
||
:where(button,[role=button],summary,label,select){cursor:pointer}
|
||
|
||
|
||
:where(img,svg,video,canvas,iframe,picture,object){max-width:100%}
|
||
:where(img,video){height:auto}
|
||
|
||
:where(pre){overflow-x:auto}
|
||
|
||
|
||
@media (pointer:coarse){
|
||
:where(button,[role=button],a[role=button],summary,select,textarea,
|
||
input:not([type=checkbox]):not([type=radio]):not([type=hidden])){
|
||
min-height:var(--tap-target);
|
||
}
|
||
:where(input,select,textarea){font-size:var(--text-control)}
|
||
|
||
:where([role=checkbox],[role=radio],[role=switch],input[type=checkbox],input[type=radio]){position:relative}
|
||
:where([role=checkbox],[role=radio],[role=switch],input[type=checkbox],input[type=radio])::after{
|
||
content:'';position:absolute;top:50%;left:50%;
|
||
width:var(--tap-target);height:var(--tap-target);
|
||
transform:translate(-50%,-50%);
|
||
}
|
||
}
|
||
|
||
|
||
:focus-visible{outline:2px solid var(--ring);outline-offset:var(--ring-offset,2px)}
|
||
|
||
::selection{background:var(--selection);color:var(--text-primary)}
|
||
|
||
|
||
:where(html){scrollbar-color:var(--white-15) transparent;scrollbar-width:thin}
|
||
.light{scrollbar-color:rgb(0 0 0 / .18) transparent}
|
||
:where(*)::-webkit-scrollbar{width:6px;height:6px}
|
||
:where(*)::-webkit-scrollbar-track{background:transparent}
|
||
:where(*)::-webkit-scrollbar-thumb{background:var(--white-15);border-radius:var(--radius-full)}
|
||
:where(*)::-webkit-scrollbar-thumb:hover{background:var(--white-30)}
|
||
:where(*)::-webkit-scrollbar-corner{background:transparent}
|
||
|
||
:where(*)::-webkit-scrollbar-button{display:none;width:0;height:0}
|
||
.light :where(*)::-webkit-scrollbar-thumb{background:rgb(0 0 0 / .18)}
|
||
.light :where(*)::-webkit-scrollbar-thumb:hover{background:rgb(0 0 0 / .32)}
|
||
}
|
||
|
||
/* ── Lux: tokens/brand.css ────────────────────────────── */
|
||
/* Lux — the brand layer, and the only hand-authored token file in this package.
|
||
*
|
||
* Everything else you get from @luxfi/design comes from the shared substrate:
|
||
* the neutral ladder, the opacity rungs, the surface recipes, the type scale,
|
||
* elevation, motion. That is deliberate, and it is the shape of the whole
|
||
* estate — the substrate carries the design-system facts, a brand package
|
||
* carries the brand facts, and there is exactly one copy of each.
|
||
*
|
||
* Lux is the MINIMAL end of that family. Hanzo is monochrome; Lux is monochrome
|
||
* taken further, and "further" here is four specific things, each measured
|
||
* rather than felt:
|
||
*
|
||
* the ground pure #000000, where Hanzo's token sits at #0a0a0a
|
||
* the accent pure #ffffff, where Hanzo sits at #e4e4e7
|
||
* the lift ONE raised surface, where Hanzo has two
|
||
* the hairline .08, where Hanzo draws .10 — and paints #262626 OPAQUE
|
||
*
|
||
* Nothing below invents a value. Every one is either a rung of the inherited
|
||
* ladder or a literal @luxfi/brand declares.
|
||
*
|
||
* The numbers come from a headless render of the live surfaces at 1440px, not
|
||
* from source: every painted border, fill and ink value on lux.financial and
|
||
* hanzo.ai, counted by element. Where a comment below cites a count, that is
|
||
* where it is from.
|
||
*
|
||
* Before adding a token here, ask whether it is a LUX fact or a DESIGN-SYSTEM
|
||
* fact. Design-system facts go upstream, where every brand gets them.
|
||
*
|
||
* ─── THE GOLD IS REVERSED. DO NOT RESTORE IT. ────────────────────────────
|
||
*
|
||
* 0.1.0 of this package shipped a gold accent, #D4AF37, in --brand. 0.1.1
|
||
* removed it on the CTO's instruction, quoted in full so nobody has to guess
|
||
* at the intent later:
|
||
*
|
||
* "no gold in lux, only monochrome white and black, more severe and
|
||
* minimal than hanzo.ai"
|
||
*
|
||
* The archaeology that produced the gold was real and it is not worth
|
||
* repeating: lux.network's globals.css once declared it under a comment
|
||
* reading "Gold accent: #D4AF37", the founder's commit message named it, and
|
||
* the Lux Exchange carried `gold: '#D4AF37'` as a Tailwind literal. All true,
|
||
* all HISTORICAL. Every live Lux surface has since flattened that slot to
|
||
* white, and the rebrand that did it also added an end-to-end test on
|
||
* lux.network asserting the page paints zero pixels in hue band 20–60. THAT
|
||
* TEST IS CORRECT AND MUST STAY. Read it as the fence it is: the estate
|
||
* already decided this once, and 0.1.0 climbed the fence.
|
||
*
|
||
* There is no --lux-gold token here to "just re-enable". That is deliberate.
|
||
* An unused brand-colour token is exactly what a future agent re-wires by
|
||
* accident, so the hue is gone from the package rather than parked in it.
|
||
*
|
||
* THE TRAP, NAMED, because it is still live and it is what produced 0.1.0:
|
||
* lux.network AS DEPLOYED TODAY STILL PAINTS THE GOLD. A render of it at
|
||
* 1440px puts 18,198 saturated pixels on the page, 100% of them in hue bucket
|
||
* 40–49 — 0.66% of the first screen — from `--accent: oklch(0.75 0.14 85)`,
|
||
* which resolves to #d6a62e. So the deployed site and the test in its own repo
|
||
* contradict each other, and anyone who probes the site for "what Lux looks
|
||
* like" will find gold and conclude it belongs. It does not. The two surfaces
|
||
* that carry the CURRENT brand are lux.financial (0 saturated pixels above the
|
||
* fold; its only colour anywhere is one photograph at y=2737) and
|
||
* @luxfi/[email protected]. Measure those. The lux.network deployment is stale, and
|
||
* bringing it in line is that repo's job, not this package's.
|
||
*
|
||
* This package's own shipped doctrine never agreed with the gold either —
|
||
* prompts/system.md has said "Monochrome. True black. White type. Color only
|
||
* as state, never as decoration." since before 0.1.0, and the specimen cards
|
||
* in guidelines/ have always painted their ground #000. 0.1.1 is the tokens
|
||
* catching up to the words.
|
||
*/
|
||
|
||
/* The Lux layer wins on SPECIFICITY, not on load order.
|
||
Both sheets declare --brand. At equal specificity the later one wins, so
|
||
importing the substrate after this sheet silently reverts the brand to its
|
||
default — and only partly: --brand-hover, --brand-bg and --brand-border
|
||
survive, so the swatch row shows one brand value beside a different
|
||
brand-hover. Nothing errors. Doubling the selector takes this block to
|
||
(0,2,0) and the question of order stops existing.
|
||
|
||
`.light` is doubled rather than qualified with :root for the same reason the
|
||
substrate leaves it bare: a surface may scope the light theme to a SUBTREE,
|
||
and `:root.light` would only ever match the document element. `.light.light`
|
||
matches any element and still outranks the substrate.
|
||
|
||
A consumer deliberately retuning these must match (0,2,0) — doubling their
|
||
own selector is the whole of it. */
|
||
:root:root{
|
||
/* ——— the accent ———
|
||
#FFFFFF, and it is not a choice made here. @luxfi/[email protected] ships two
|
||
product configs — brand.json (Lux Exchange) and financial.json (Lux Pay) —
|
||
and they declare the SAME theme, to the digit:
|
||
|
||
dark { accent1:#FFFFFF, surface1:#000000, surface2:#1A1A1A }
|
||
light { accent1:#000000, surface1:#FFFFFF, surface2:#F9F9F9 }
|
||
|
||
accent1 is the brand accent. In dark it is pure white; in light it is pure
|
||
black. Two independent product surfaces agreeing on all five values is as
|
||
close to an authoritative brand file as this estate has.
|
||
|
||
WHY A PURE WHITE ACCENT IS AN ACCENT AT ALL, on a surface whose text is
|
||
also white-ish: because nothing else on it is PURE. The ink ramp tops out
|
||
at #fafafa and the substrate explains why — #ffffff on #000000 is 21:1,
|
||
the maximum contrast pair that exists, and at paragraph size it halates.
|
||
So the ink stays a shade under, and the one thing painted at the actual
|
||
extreme reads as the accent. The polarity IS the brand.
|
||
|
||
That is also precisely where Lux parts from Hanzo. Hanzo's --brand is
|
||
#e4e4e7 — a near-white sitting BELOW its own ink, and carrying a faint
|
||
blue cast (~6% HSL saturation; B is three levels above R and G). Lux's
|
||
accent sits ABOVE the ink and has no cast at all. Brighter than everything
|
||
and perfectly neutral, spent rarely and small. */
|
||
--brand:var(--pure-white);
|
||
/* A hover on a fill that is already the brightest value available can only
|
||
step DOWN, so the only question is how far. The substrate answered it for
|
||
--primary, which has the same problem: a large drop reads as the control
|
||
going DISABLED under the cursor, which is the one thing a hover must never
|
||
look like, so the step is small and --bloom (elevation.css, a white glow at
|
||
.28) does the actual lighting. --neutral-200 is one rung, and it is a rung
|
||
rather than a number picked to feel right. */
|
||
--brand-hover:var(--neutral-200);
|
||
|
||
/* Ink on the accent. The substrate's inherited value is #09090b, which is
|
||
correct on contrast (20.5:1) and wrong on principle here: 9,9,11 is not
|
||
achromatic — blue runs two levels above red and green, about 10% HSL
|
||
saturation. On a brand whose whole claim is zero chroma, the one colour
|
||
sitting inside the brand's own button should not be the exception nobody
|
||
looks at. --pure-black is 21:1 and has no cast. */
|
||
--brand-foreground:var(--pure-black);
|
||
|
||
/* How the accent is actually spent: the eyebrow pill, and the hairline on a
|
||
featured tile. Both surfaces that carry this component draw it as a fill
|
||
inside a border of the same colour — lux.financial as `${BRAND_COLOR}20`
|
||
on `1px solid ${BRAND_COLOR}40`, the Exchange as `bg-gold/20
|
||
border-gold/40`.
|
||
|
||
Those two are NOT the same numbers, and 0.1.0's note that they were is
|
||
worth correcting because it is the kind of error that propagates. The
|
||
first pair is eight-digit hex: 0x20/255 = 12.5% and 0x40/255 = 25.1%. The
|
||
second is Tailwind opacity syntax: a literal 20% and 40%. lux.financial —
|
||
the live monochrome surface, and the one this package follows — is
|
||
therefore 12.5% on 25%.
|
||
|
||
Which lands between rungs, and this package ships a rule about that:
|
||
"Never invent an in-between step like 12% or 37%" (prompts/rules.md).
|
||
0.1.0 broke it, writing bespoke .12 and .25 alphas. So the pill snaps to
|
||
the ladder it was always meant to sit on — .10 and .22 — a hair quieter
|
||
than measured, which is the direction Lux is going anyway. */
|
||
--brand-bg:var(--white-10);
|
||
--brand-border:var(--white-22);
|
||
|
||
/* ——— the mark ———
|
||
The press-kit constants the logo is drawn from. --lux-white was already
|
||
#FFFFFF; --lux-black arrived as #0A0A0B, and that is not a Lux value at
|
||
all — it is Hanzo's press-kit black, carried in by the inherit's textual
|
||
hanzo- -> lux- rename, which turns a Hanzo fact into something that LOOKS
|
||
like a Lux fact. It is also not grey: blue sits one level above red and
|
||
green, hue 240deg, and the achromatic check below is what noticed.
|
||
components/core/LuxLogo.jsx paints the black variant of the mark with it.
|
||
|
||
@luxfi/[email protected] gives the answer in three places at once — primaryColor
|
||
#000000, dark surface1 #000000, light accent1 #000000. Lux's black is
|
||
black.
|
||
|
||
Restated identically in .light: this is a brand constant, invariant by
|
||
nature, and saying so in both blocks is cheaper than an exemption in the
|
||
gate that some later token would slip through. */
|
||
--lux-black:var(--pure-black);
|
||
|
||
/* ——— severity 1 of 4: the ground goes to true black ———
|
||
@luxfi/brand's surface1, in both product configs. It is also what this
|
||
package's own specimen cards have hardcoded as `background:#000` since the
|
||
first release, while the token underneath them said #0a0a0a — one fact in
|
||
two places, disagreeing. This settles it in favour of the brand file.
|
||
|
||
It is the highest-leverage single token in the layer. The ink gains
|
||
contrast without moving (#fafafa goes 18.97:1 → 20.12:1), the accent
|
||
reaches the full 21:1, and every card lifts further off the page for free:
|
||
--card was five levels above the old ground and is ten above this one.
|
||
|
||
Worth knowing before someone "corrects" this back: hanzo.ai's own screen is
|
||
also pure black — 77% of its pixels are #000000, because a `bg-black`
|
||
wrapper paints over the #0a0a0a its token declares. Hanzo's design system
|
||
and Hanzo's site disagree about the ground. Lux's does not. */
|
||
--background:var(--pure-black);
|
||
|
||
/* ——— severity 2 of 4: ONE lift, not two ———
|
||
Hanzo's ladder has four rungs: page #0a0a0a, card #0f0f0f, muted #171717,
|
||
control #262626. Lux has three. --card and --muted are the same surface
|
||
here, and that is the point: at this severity "a panel" and "a quieter
|
||
panel" are not two objects, they are one object, and the second rung was a
|
||
distinction the system was paying for without using. Text rank still
|
||
separates them — --muted-foreground is untouched and reads 7.85:1 here.
|
||
|
||
#0a0a0a is --neutral-950, and it is what lux.financial paints its raised
|
||
cards — 73 elements of it, the second-most-common pixel value on the page
|
||
after the black ground itself.
|
||
@luxfi/brand calls surface2 #1A1A1A; the ladder's nearest rung is #171717,
|
||
three levels off and visually identical, and staying ON the ladder is
|
||
worth more than three levels — so the control rung is left inherited
|
||
(--secondary / --accent, #262626) rather than nudged to a bespoke value.
|
||
|
||
Consequence, stated plainly so it is not later "fixed": --surface-1 and
|
||
--surface-2 resolve to the same value in Lux. The numeric ladder has three
|
||
distinct rungs, not four. If a surface needs a second lift, it is building
|
||
something Lux does not have. */
|
||
--card:var(--neutral-950);
|
||
--popover:var(--card);
|
||
--muted:var(--card);
|
||
|
||
/* ——— severity 3 of 4: a quieter hairline ———
|
||
.08, measured off lux.financial, against the substrate's .10 — and it is
|
||
the single highest-traffic token in the package: 44 of the var() references
|
||
in the shipped components are this one. Every card, table row, divider and
|
||
dialog edge steps back one rung.
|
||
|
||
The measurement is not marginal. Of 331 painted edges on lux.financial,
|
||
286 are exactly rgba(255,255,255,0.08) at 1px — one value doing nearly all
|
||
the work. hanzo.ai draws the same job with 48 edges of OPAQUE #262626
|
||
(about 15% white, and opaque, so it vanishes the moment it lands on a
|
||
lifted surface) plus 28 at .10. That is the difference in one number: Lux's
|
||
edges are softer, and they are all the same edge.
|
||
|
||
Only the DECORATIVE boundary moves. --border-control, --border-focus,
|
||
--border-selected and --ring are untouched, because they are not decoration
|
||
— they are how a keyboard user knows where they are, and --ring still owes
|
||
WCAG 2.4.11's 3:1 against every canvas. Lux quiets what merely separates.
|
||
It does not quiet what tells you where you are. */
|
||
--border:var(--white-08);
|
||
|
||
/* ——— severity 4 of 4: the fourth permitted hue is withdrawn ———
|
||
The substrate permits exactly four hue exceptions (DESIGN.md §2.4): error
|
||
red, online green, success green, and the macOS window-chrome dot trio.
|
||
Lux permits three.
|
||
|
||
This is not taste. --chrome-dot-yellow is rgb(234 179 8 / .6) — hue 45.6°,
|
||
which sits squarely inside the 20–60 band lux.network's end-to-end test
|
||
asserts is empty. A Lux surface rendering a window mock (guidelines/
|
||
color-semantic.card.html ships one) would paint gold-band pixels and fail
|
||
that test, having never gone near the gold. The other three exceptions are
|
||
SIGNALS and stay: "delete everything" and "you cannot click this" must not
|
||
be the same colour, and red at 0° and green at 142° are nowhere near the
|
||
fence. Window chrome is decoration, and decoration does not get a hue.
|
||
|
||
One value for all three, aliased onto --border-selected so it inverts with
|
||
the theme on its own. Three identical dots is what a monochrome window mock
|
||
looks like; the names are the substrate's and are kept so the vocabulary
|
||
matches. */
|
||
--chrome-dot-red:var(--border-selected);
|
||
--chrome-dot-yellow:var(--border-selected);
|
||
--chrome-dot-green:var(--border-selected);
|
||
}
|
||
|
||
/* Light theme.
|
||
Every token above whose value is a fixed literal is restated here, because
|
||
`:root` and `.light` have identical specificity and this layer is written
|
||
LAST — so a token declared only above would outrank the substrate's own
|
||
light value and silently keep its dark one. Tokens whose value is a bare
|
||
var() onto something that already inverts (--popover, --muted, the chrome
|
||
dots) need no restatement, and check-tokens.mjs knows the difference.
|
||
|
||
The accent inverts cleanly and completely, which is the reward for it being
|
||
monochrome: #000000 on #ffffff is the same 21:1 pair seen from the other
|
||
side. This is where 0.1.0's real trouble was — a gold tuned on black
|
||
measured 1.96:1 on white, far under the 3:1 floor for any non-text mark, and
|
||
could not simply be darkened because sRGB yellow below about L*45 turns
|
||
olive. 0.1.0 shipped a bronze, #7E5A16, as the honest ceiling and documented
|
||
it as such. Monochrome has no hue to darken, so that whole compromise
|
||
dissolves: there is nothing to tune, and nothing to explain. */
|
||
.light.light{
|
||
--brand:var(--pure-black);
|
||
/* The mirror of --neutral-200 in dark, one rung further out. The substrate's
|
||
rule: black-on-white at a given step reads FAINTER than white-on-black at
|
||
the same step, so light is pushed harder — .22/.30 becomes .32/.42 for its
|
||
focus and selection rungs. #262626 is the value the substrate itself uses
|
||
for --primary-hover in light, for this exact reason. */
|
||
--brand-hover:var(--neutral-800);
|
||
--brand-foreground:var(--pure-white);
|
||
--brand-bg:rgb(0 0 0 / .10);
|
||
--brand-border:rgb(0 0 0 / .22);
|
||
|
||
/* Invariant — the mark is the mark. Restated so the gate can see it is
|
||
deliberate rather than forgotten. */
|
||
--lux-black:var(--pure-black);
|
||
|
||
--background:var(--pure-white);
|
||
/* The complement of dark's lift, rounded to the ladder: #0a0a0a is ten levels
|
||
off black, #f5f5f5 is ten off white, and it is --neutral-100.
|
||
@luxfi/brand's surface2 here is #F9F9F9 — four levels apart, same call as
|
||
#1A1A1A vs #171717 above, same answer: stay on the ladder. */
|
||
--card:var(--neutral-100);
|
||
|
||
/* NOT quieted to .08. The dark hairline is a measured Lux value, taken off
|
||
lux.financial, which is a dark surface — there is no measured Lux light
|
||
hairline, and inventing one would be taste rather than evidence. So light
|
||
keeps the substrate's .10. This restatement exists only because declaring
|
||
--border above would otherwise strand the light theme on the dark value;
|
||
the number is upstream's, unchanged, and should be left alone until
|
||
somebody has a light Lux surface to measure. */
|
||
--border:rgb(0 0 0 / .10);
|
||
}
|
||
|
||
|
||
@theme inline {
|
||
--color-background: var(--background);
|
||
--color-foreground: var(--foreground);
|
||
--color-card: var(--card);
|
||
--color-card-foreground: var(--card-foreground);
|
||
--color-popover: var(--popover);
|
||
--color-popover-foreground: var(--popover-foreground);
|
||
--color-primary: var(--primary);
|
||
--color-primary-foreground: var(--primary-foreground);
|
||
--color-secondary: var(--secondary);
|
||
--color-secondary-foreground: var(--secondary-foreground);
|
||
--color-muted: var(--muted);
|
||
--color-muted-foreground: var(--muted-foreground);
|
||
--color-accent: var(--accent);
|
||
--color-accent-foreground: var(--accent-foreground);
|
||
--color-destructive: var(--destructive);
|
||
--color-destructive-foreground: var(--destructive-foreground);
|
||
--color-border: var(--border);
|
||
--color-input: var(--input);
|
||
--color-ring: var(--ring);
|
||
--color-brand: var(--brand);
|
||
--color-brand-foreground: var(--brand-foreground);
|
||
--color-brand-hover: var(--brand-hover);
|
||
--color-brand-bg: var(--brand-bg);
|
||
--color-brand-border: var(--brand-border);
|
||
|
||
--color-error: var(--state-error);
|
||
--color-success: var(--state-success);
|
||
--color-online: var(--state-online);
|
||
|
||
--radius-sm: var(--radius-sm);
|
||
--radius-md: var(--radius-md);
|
||
--radius-lg: var(--radius-lg);
|
||
--radius-xl: var(--radius-xl);
|
||
|
||
--font-sans: var(--font-sans);
|
||
--font-mono: var(--font-mono);
|
||
}
|