// Generated by scripts/sync-tokens.ts from tokens.css. Do not edit. export const ROXY_UI_TOKENS_CSS = `/** * Roxy UI design tokens. ~30 CSS custom properties that every component reads. Light + dark defaults. Host page overrides at :root or per element. No Tailwind, no class-name overrides, no JS theme switcher. * * Delivery model: this file ships as a global light-DOM stylesheet (linked, or auto-injected by the CDN bundle). Custom properties inherit through the shadow boundary, so tokens set on a light-DOM ancestor reach every component shadow. The explicit theme blocks therefore target light-DOM selectors (:root, .dark, [data-theme="dark"], a wrapper element), NOT :host (a :host rule in a global sheet matches nothing). The :host([data-theme]) selectors are kept only for the case where this CSS is ever adopted directly into a shadow root; they are inert in global delivery. * * Light is the default. Dark applies under any of: * - prefers-color-scheme: dark * - [data-theme="dark"] on the element itself or any ancestor (typically :root) * - .dark class on the element itself or any ancestor (typically :root) * * Explicit choice wins over the OS: the [data-theme] / .dark blocks come after the @media (prefers-color-scheme: dark) block in source order, and a closer ancestor overrides a farther one through normal custom-property inheritance. * * Motion gating: * - --roxy-motion-duration defaults to 200ms. Set to 0ms to disable. * - prefers-reduced-motion: reduce forces 0ms regardless of host overrides. */ :root, :host { /* Color: brand */ --roxy-primary: #0f172a; --roxy-secondary: #475569; --roxy-accent: #f59e0b; /* Text-safe accent variant. amber-500 hits 2.14:1 on white which fails * WCAG AA for body text. amber-700 hits 4.5:1, used wherever the accent * tone is applied to text. Fills (planet glyphs, chart accents, badges * with non-text use) keep --roxy-accent. */ --roxy-accent-ink: #b45309; /* Color: status. The base value (success, warning, danger, info) is for * fills and tints. The -fg variant is darker so text on a light tint passes * WCAG AA (>= 4.5:1 on white). Use -fg whenever status color hits text. */ --roxy-success: #16a34a; --roxy-success-fg: #166534; --roxy-warning: #ea580c; --roxy-warning-fg: #9a3412; --roxy-danger: #dc2626; --roxy-danger-fg: #991b1b; --roxy-info: #0284c7; --roxy-info-fg: #075985; /* Color: surface */ --roxy-bg: #ffffff; --roxy-surface: #ffffff; --roxy-fg: #0a0a0a; --roxy-muted: #71717a; --roxy-border: #e4e4e7; --roxy-ring: rgba(245, 158, 11, 0.4); /* Typography */ --roxy-font-sans: "Geist", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --roxy-font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; --roxy-text-xs: 0.75rem; --roxy-text-sm: 0.875rem; --roxy-text-base: 1rem; --roxy-text-lg: 1.125rem; --roxy-text-xl: 1.5rem; --roxy-weight-normal: 400; --roxy-weight-bold: 600; --roxy-leading-tight: 1.2; --roxy-leading-normal: 1.5; --roxy-tracking-tight: -0.02em; --roxy-tracking-normal: 0em; /* Spacing */ --roxy-space-xs: 0.25rem; --roxy-space-sm: 0.5rem; --roxy-space-md: 1rem; --roxy-space-lg: 1.5rem; --roxy-space-xl: 2.5rem; /* Radius */ --roxy-radius-sm: 4px; --roxy-radius-md: 8px; --roxy-radius-lg: 12px; --roxy-radius-full: 9999px; /* Shadow */ --roxy-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06); --roxy-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.06); --roxy-shadow-lg: 0 12px 24px -8px rgba(0, 0, 0, 0.14); /* Motion */ --roxy-motion-duration: 200ms; --roxy-motion-easing: cubic-bezier(0.4, 0, 0.2, 1); /* Heat scale: a single base hue. Consumers mix it with \`transparent\` at * increasing percentages to paint cooler-to-hotter tiers. The mix-with- * transparent approach lets the page bg show through and keeps text * colour stable (always --roxy-fg), so the cells read in both themes * without per-tier text colours. */ --roxy-heat: var(--roxy-danger, #ef4444); } /* Dark theme via system preference */ @media (prefers-color-scheme: dark) { :root, :host { --roxy-primary: #f8fafc; --roxy-secondary: #94a3b8; --roxy-accent: #fbbf24; --roxy-accent-ink: #fbbf24; /* Status -fg overrides must mirror the explicit [data-theme="dark"] block * below. Without these, a user on system dark with no data-theme attribute * inherits the light-mode -fg values (e.g. #166534 success) which renders * as near-invisible dark green on a near-black surface and fails WCAG AA. */ --roxy-success: #22c55e; --roxy-success-fg: #86efac; --roxy-warning: #fb923c; --roxy-warning-fg: #fdba74; --roxy-danger: #ef4444; --roxy-danger-fg: #fca5a5; --roxy-info: #38bdf8; --roxy-info-fg: #7dd3fc; --roxy-bg: #0a0a0a; --roxy-surface: #18181b; --roxy-fg: #fafafa; --roxy-muted: #a1a1aa; --roxy-border: #27272a; --roxy-ring: rgba(251, 191, 36, 0.45); --roxy-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5); --roxy-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6), 0 2px 4px -2px rgba(0, 0, 0, 0.5); --roxy-shadow-lg: 0 12px 24px -8px rgba(0, 0, 0, 0.7); --roxy-heat: var(--roxy-danger, #ef4444); } } /* Light theme override. Beats the @media (prefers-color-scheme: dark) block * when the host explicitly opts back into light. Without this, a dark-mode OS * pins the tokens to dark even after data-theme="light" is set. The light-DOM * selectors (:root.light, .light, [data-theme="light"]) set the vars on the * ancestor or the element itself so they inherit into every component shadow; * :host([data-theme="light"]) is inert in global delivery and kept only for * shadow-adopted use. */ :root[data-theme="light"], [data-theme="light"], :root.light, .light, :host([data-theme="light"]) { --roxy-primary: #0f172a; --roxy-secondary: #475569; --roxy-accent: #f59e0b; --roxy-accent-ink: #b45309; --roxy-success: #16a34a; --roxy-success-fg: #166534; --roxy-warning: #ea580c; --roxy-warning-fg: #9a3412; --roxy-danger: #dc2626; --roxy-danger-fg: #991b1b; --roxy-info: #0284c7; --roxy-info-fg: #075985; --roxy-bg: #ffffff; --roxy-surface: #ffffff; --roxy-fg: #0a0a0a; --roxy-muted: #71717a; --roxy-border: #e4e4e7; --roxy-ring: rgba(245, 158, 11, 0.4); --roxy-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06); --roxy-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.06); --roxy-shadow-lg: 0 12px 24px -8px rgba(0, 0, 0, 0.14); } /* Dark theme via explicit opt-in. The light-DOM selectors (:root.dark, .dark, * [data-theme="dark"]) set the vars on the ancestor or the element itself so * they inherit into every component shadow; this is what makes a .dark class on * any ancestor (Tailwind, shadcn) actually theme the components in global * delivery. :host([data-theme="dark"]) is inert in global delivery and kept * only for shadow-adopted use. */ :root[data-theme="dark"], [data-theme="dark"], :root.dark, .dark, :host([data-theme="dark"]) { --roxy-primary: #f8fafc; --roxy-secondary: #94a3b8; --roxy-accent: #fbbf24; --roxy-accent-ink: #fbbf24; --roxy-success: #22c55e; --roxy-success-fg: #86efac; --roxy-warning: #fb923c; --roxy-warning-fg: #fdba74; --roxy-danger: #ef4444; --roxy-danger-fg: #fca5a5; --roxy-info: #38bdf8; --roxy-info-fg: #7dd3fc; --roxy-bg: #0a0a0a; --roxy-surface: #18181b; --roxy-fg: #fafafa; --roxy-muted: #a1a1aa; --roxy-border: #27272a; --roxy-ring: rgba(251, 191, 36, 0.45); --roxy-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5); --roxy-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6), 0 2px 4px -2px rgba(0, 0, 0, 0.5); --roxy-shadow-lg: 0 12px 24px -8px rgba(0, 0, 0, 0.7); --roxy-heat: var(--roxy-danger, #ef4444); } /* Reduced motion override */ @media (prefers-reduced-motion: reduce) { :root, :host { --roxy-motion-duration: 0ms; } } `;