Chunte's picture
Chunte HF Staff
Minimal UI: nav icons + motion pass (transitions-dev + apple-design), UX unchanged
e63a744 verified
Raw History Blame Contribute Delete
24 kB
@import "tailwindcss";
/* ── Minimal design system ────────────────────────────────────────
Quiet, monochrome chrome in the spirit of Apple / OpenAI interfaces:
white (or near-black) canvases, hairline separators instead of boxes,
large radii, pill controls, frosted floating bars and one functional
accent (system blue) reserved for selection, focus and links. The
primary action is a solid black (white in dark) pill. Flagged episodes
use system orange (as Mail flags do), which also echoes the LeRobot logo.
<html class="dark"> selects the dark set; see utils/theme.ts. Never
hard-code colours in components: every value has a token below. */
@custom-variant dark (&:where(.dark, .dark *));
:root {
color-scheme: light;
/* Canvas & surfaces */
--bg: #ffffff;
--bg-subtle: #f9f9fb; /* sidebar, page wells */
--surface: #ffffff; /* cards */
--surface-muted: #f4f4f6; /* inputs, segmented tracks, code */
--surface-raised: rgba(255, 255, 255, 0.82); /* glass: menus, floating bars */
--media: #0b0b0c; /* behind video and 3D */
/* Text */
--fg: #111113;
--fg-secondary: #5f5f66; /* 6.4:1 β€” any text the user must read */
--fg-tertiary: #8e8e93; /* 3.3:1 β€” decoration, placeholders */
/* Lines & fills */
--separator: rgba(0, 0, 0, 0.08);
--separator-strong: rgba(0, 0, 0, 0.14);
--fill: rgba(0, 0, 0, 0.04);
--fill-hover: rgba(0, 0, 0, 0.065);
--fill-press: rgba(0, 0, 0, 0.1);
/* Primary action: solid monochrome pill */
--primary: #111113;
--on-primary: #ffffff;
/* Functional accent: selection, focus, links */
--accent: #0071e3;
--accent-fg: #0066cc;
--accent-soft: rgba(0, 113, 227, 0.1);
--focus-ring: rgba(0, 113, 227, 0.35);
/* Flagged episodes only */
--flag: #ff9500;
--flag-fg: #b25f00;
--flag-soft: rgba(255, 149, 0, 0.12);
/* Status */
--success: #248a3d;
--success-soft: rgba(52, 199, 89, 0.12);
--warning: #8a6100; /* amber, distinct from the flag orange */
--warning-soft: rgba(255, 204, 0, 0.16);
--danger: #d70015;
--danger-soft: rgba(255, 59, 48, 0.1);
/* Playback position: neutral, like a QuickTime scrubber */
--playhead: #111113;
/* Charts */
--chart-grid: rgba(0, 0, 0, 0.06);
--chart-axis: rgba(0, 0, 0, 0.12);
--chart-1: #0071e3;
--chart-2: #28a745;
--chart-3: #af52de;
--chart-4: #00a3bf;
--chart-5: #ff2d55;
--chart-6: #5856d6;
--chart-7: #a2845e;
--chart-8: #30b0c7;
--chart-9: #c7a400;
--chart-10: #6e8b3d; /* olive: distinct from the tertiary grey */
/* Shape */
--radius-sm: 8px;
--radius: 10px; /* controls, inputs */
--radius-lg: 16px; /* cards */
--radius-xl: 20px; /* media frames, sheets */
/* Elevation: almost flat; soft shadow only on floating surfaces */
--shadow-float:
0 0 0 0.5px rgba(0, 0, 0, 0.08), 0 8px 28px -6px rgba(0, 0, 0, 0.16),
0 2px 6px -2px rgba(0, 0, 0, 0.06);
--shadow-card: 0 1px 2px rgba(0, 0, 0, 0.03);
/* Motion */
/* House curves. --ease-out is transitions.dev's --ease-smooth-out (same curve): every surface
that appears or leaves. --ease-spring (the non-overshooting iOS sheet curve) is only for
things that physically slide: tab pill, segmented thumb, switch knob, phone sheet. */
--ease-out: cubic-bezier(0.22, 1, 0.36, 1);
--ease-smooth-out: var(--ease-out);
--ease-spring: cubic-bezier(0.32, 0.72, 0, 1);
/* House durations. Careful: --dur-fast (120ms, hover/press) is NOT --duration-fast (250ms). */
--dur-fast: 120ms;
--dur: 200ms;
--dur-slow: 320ms;
/* transitions.dev motion scale, matched by usage (see the transitions-dev skill). */
--duration-stagger: 40ms;
--duration-micro: 80ms;
--duration-quick: 150ms; /* any close: menu, popover, modal; text/tooltip appear */
--duration-fast: 250ms; /* menu / modal open, icon swap, accordion, sliding tabs */
--duration-medium: 350ms; /* panel close */
--duration-slow: 400ms; /* panel open, skeleton -> content reveal */
--duration-very-slow: 500ms;
--scale-large: 0.96; /* modal open / close */
--scale-medium: 0.97; /* menu open */
--scale-small: 0.98; /* tooltip open */
--scale-tiny: 0.99; /* menu close */
--blur-small: 2px; /* icon swap, skeleton reveal (small layers only) */
--blur-medium: 3px;
--distance-micro: 4px;
--distance-medium: 12px;
--scrollbar: rgba(0, 0, 0, 0.16);
}
:root.dark {
color-scheme: dark;
--bg: #0f0f10;
--bg-subtle: #141416;
--surface: #18181a;
--surface-muted: #222225;
--surface-raised: rgba(32, 32, 35, 0.78);
--media: #000000;
--fg: #f5f5f7;
--fg-secondary: #a1a1a6;
--fg-tertiary: #6e6e73;
--separator: rgba(255, 255, 255, 0.08);
--separator-strong: rgba(255, 255, 255, 0.14);
--fill: rgba(255, 255, 255, 0.05);
--fill-hover: rgba(255, 255, 255, 0.08);
--fill-press: rgba(255, 255, 255, 0.12);
--primary: #f5f5f7;
--on-primary: #111113;
--accent: #0a84ff;
--accent-fg: #4da3ff;
--accent-soft: rgba(10, 132, 255, 0.16);
--focus-ring: rgba(10, 132, 255, 0.45);
--flag: #ff9f0a;
--flag-fg: #ffb340;
--flag-soft: rgba(255, 159, 10, 0.16);
--success: #30d158;
--success-soft: rgba(48, 209, 88, 0.14);
--warning: #ffd60a;
--warning-soft: rgba(255, 214, 10, 0.14);
--danger: #ff6961;
--danger-soft: rgba(255, 69, 58, 0.16);
--playhead: #f5f5f7;
--chart-grid: rgba(255, 255, 255, 0.06);
--chart-axis: rgba(255, 255, 255, 0.14);
--chart-1: #0a84ff;
--chart-2: #30d158;
--chart-3: #bf5af2;
--chart-4: #64d2ff;
--chart-5: #ff375f;
--chart-6: #7d7aff;
--chart-7: #ac8e68;
--chart-8: #40c8e0;
--chart-9: #ffd60a;
--chart-10: #a3c76b;
--shadow-float:
0 0 0 0.5px rgba(255, 255, 255, 0.1), 0 10px 32px -6px rgba(0, 0, 0, 0.6),
0 2px 8px -2px rgba(0, 0, 0, 0.4);
--shadow-card: none;
--scrollbar: rgba(255, 255, 255, 0.18);
}
@theme inline {
--color-bg: var(--bg);
--color-bg-subtle: var(--bg-subtle);
--color-surface: var(--surface);
--color-surface-muted: var(--surface-muted);
--color-surface-raised: var(--surface-raised);
--color-media: var(--media);
--color-fg: var(--fg);
--color-fg-secondary: var(--fg-secondary);
--color-fg-tertiary: var(--fg-tertiary);
--color-separator: var(--separator);
--color-separator-strong: var(--separator-strong);
--color-fill: var(--fill);
--color-fill-hover: var(--fill-hover);
--color-fill-press: var(--fill-press);
--color-primary: var(--primary);
--color-on-primary: var(--on-primary);
--color-accent: var(--accent);
--color-accent-fg: var(--accent-fg);
--color-accent-soft: var(--accent-soft);
--color-flag: var(--flag);
--color-flag-fg: var(--flag-fg);
--color-flag-soft: var(--flag-soft);
--color-success: var(--success);
--color-success-soft: var(--success-soft);
--color-warning: var(--warning);
--color-warning-soft: var(--warning-soft);
--color-danger: var(--danger);
--color-danger-soft: var(--danger-soft);
--font-sans:
var(--font-inter), -apple-system, BlinkMacSystemFont, "SF Pro Text",
"Segoe UI", system-ui, sans-serif;
--font-mono:
var(--font-geist-mono), "SF Mono", ui-monospace, Menlo, monospace;
/* 11px caption; 13px is the workhorse secondary size */
--text-2xs: 0.6875rem;
--text-2xs--line-height: 1rem;
--text-13: 0.8125rem;
--text-13--line-height: 1.125rem;
/* Tracking is size-specific (SF-style): small text opens up slightly, large text tightens.
Body (14px) keeps the -0.006em set on <body>. */
--text-2xs--letter-spacing: 0.01em;
--text-xs--letter-spacing: 0.005em;
--text-13--letter-spacing: -0.002em;
--text-lg--letter-spacing: -0.012em;
--text-xl--letter-spacing: -0.016em;
--text-2xl--letter-spacing: -0.02em;
--text-3xl--letter-spacing: -0.024em;
--text-4xl--letter-spacing: -0.026em;
--text-5xl--letter-spacing: -0.03em;
--text-6xl--letter-spacing: -0.032em;
/* Every bare transition-colors / transition-opacity runs on the hover token and house curve. */
--default-transition-duration: var(--dur-fast);
--default-transition-timing-function: var(--ease-out);
--radius-sm: var(--radius-sm);
--radius-md: var(--radius);
--radius-lg: var(--radius-lg);
--radius-xl: var(--radius-xl);
--shadow-float: var(--shadow-float);
--shadow-card: var(--shadow-card);
--ease-out: var(--ease-out);
--ease-spring: var(--ease-spring);
}
/* Compatibility: the previous token names, mapped onto the new system so
untouched components keep working. New code uses the names above. */
:root,
:root.dark {
--surface-0: var(--bg);
--surface-1: var(--surface);
--surface-2: var(--surface-muted);
--fg-soft: var(--fg);
--fg-muted: var(--fg-secondary);
--fg-faint: var(--fg-tertiary);
--line: var(--separator);
--line-subtle: var(--separator);
--line-strong: var(--separator-strong);
--fill-strong: var(--fill-hover);
--accent-ring: var(--focus-ring);
--playhead-glow: transparent;
}
@theme inline {
--color-surface-0: var(--bg);
--color-surface-1: var(--surface);
--color-surface-2: var(--surface-muted);
--color-fg-soft: var(--fg);
--color-fg-muted: var(--fg-secondary);
--color-fg-faint: var(--fg-tertiary);
--color-line: var(--separator);
--color-line-subtle: var(--separator);
--color-line-strong: var(--separator-strong);
--color-fill-strong: var(--fill-hover);
}
html {
font-size: 16px;
/* Phones would flash a grey rectangle over pill buttons; feedback is the press state. */
-webkit-tap-highlight-color: transparent;
}
body {
background: var(--bg);
color: var(--fg);
font-size: 0.875rem; /* 14px UI text */
letter-spacing: -0.006em;
font-feature-settings:
"cv11" 1,
"ss01" 1,
"ss03" 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
::selection {
background: var(--accent-soft);
}
/* Lucide icons at a lighter 1.75 stroke: closer to SF Symbols. */
svg[stroke-width="2"] {
stroke-width: 1.75;
}
/* Focus: a soft accent halo, keyboard only. Base layer, so components can
restyle it, never remove it without a replacement. */
@layer base {
:where(
a,
button,
input,
select,
textarea,
summary,
[tabindex],
[role="button"]
):focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--focus-ring);
}
input[type="range"]:focus-visible {
box-shadow: none;
}
input[type="range"]:focus-visible::-webkit-slider-thumb {
box-shadow: 0 0 0 4px var(--focus-ring);
}
input[type="range"]:focus-visible::-moz-range-thumb {
box-shadow: 0 0 0 4px var(--focus-ring);
}
}
/* Numeric readouts always use tabular figures so rows don't jitter. */
.tabular,
[data-tabular] {
font-variant-numeric: tabular-nums;
}
/* Titles: tight tracking, like SF Display. */
.title {
letter-spacing: -0.022em;
font-weight: 600;
}
/* Quiet section label (sentence case, never uppercase). */
.label {
font-size: var(--text-13);
line-height: var(--text-13--line-height);
font-weight: 500;
color: var(--fg-secondary);
}
/* Frosted floating material: menus, popovers, the playback bar. */
@utility glass {
background: var(--surface-raised);
-webkit-backdrop-filter: saturate(180%) blur(20px);
backdrop-filter: saturate(180%) blur(20px);
box-shadow: var(--shadow-float);
}
/* Translucent chrome bar (top bar). */
@utility chrome {
background: color-mix(in srgb, var(--bg) 80%, transparent);
-webkit-backdrop-filter: saturate(180%) blur(20px);
backdrop-filter: saturate(180%) blur(20px);
}
@layer components {
/* Content card: hairline, large radius, flat. */
.card {
@apply rounded-lg border border-separator bg-surface shadow-card;
}
/* Kept for components that still use the old helper names. */
.panel {
@apply rounded-lg border border-separator bg-surface;
}
.panel-raised {
@apply glass rounded-xl;
}
/* Buttons β€” pills, no borders, a gentle press. Variants:
.btn (tinted secondary), .btn-primary (solid monochrome: the one main
action), .btn-ghost (toolbar), .btn-active (selected toggle),
.btn-flagged (flag filters/actions), .btn-danger, .btn-icon (circle).
Heights: .btn 32px; .btn-sm 28px; .btn-lg 40px. */
.btn {
@apply inline-flex h-8 cursor-pointer items-center justify-center gap-1.5 rounded-full bg-fill px-3.5 text-13 font-medium whitespace-nowrap text-fg select-none;
transition:
background-color var(--dur-fast) var(--ease-out),
color var(--dur-fast) var(--ease-out),
transform var(--dur-fast) var(--ease-out),
box-shadow var(--dur-fast) var(--ease-out),
opacity var(--dur-fast) var(--ease-out);
}
.btn:hover {
@apply bg-fill-hover;
}
.btn:active {
@apply bg-fill-press;
transform: scale(0.97);
}
.btn:disabled {
@apply pointer-events-none cursor-not-allowed opacity-40;
}
.btn-sm {
@apply h-7 gap-1 px-3 text-2xs;
}
.btn-lg {
@apply h-10 px-5 text-sm;
}
.btn-primary,
.btn-primary:hover {
@apply bg-primary text-on-primary;
}
.btn-primary:hover {
opacity: 0.86;
}
.btn-primary:active {
@apply bg-primary;
opacity: 0.8;
}
.btn-ghost {
@apply bg-transparent text-fg-secondary;
}
.btn-ghost:hover {
@apply bg-fill text-fg;
}
.btn-active,
.btn-active:hover {
@apply bg-accent-soft text-accent-fg;
}
.btn-flagged,
.btn-flagged:hover {
@apply bg-flag-soft text-flag-fg;
}
.btn-danger,
.btn-danger:hover {
@apply bg-danger-soft text-danger;
}
.btn-icon {
@apply aspect-square px-0;
}
/* Text inputs and selects. */
.field {
@apply h-8 rounded-md border border-transparent bg-surface-muted px-3 text-sm text-fg placeholder:text-fg-tertiary;
transition:
background-color var(--dur-fast) var(--ease-out),
border-color var(--dur-fast) var(--ease-out),
box-shadow var(--dur-fast) var(--ease-out);
}
.field:hover {
@apply bg-fill-hover;
}
.field:focus,
.field:focus-visible {
@apply border-accent bg-surface;
outline: none;
box-shadow: 0 0 0 3px var(--focus-ring);
}
/* Loading placeholder. */
.skeleton {
position: relative;
overflow: hidden;
background: var(--fill);
border-radius: var(--radius);
}
.skeleton::after {
content: "";
position: absolute;
inset: 0;
transform: translateX(-100%);
background: linear-gradient(
90deg,
transparent,
var(--fill-hover),
transparent
);
animation: shimmer 1.6s linear infinite;
}
}
@keyframes shimmer {
to {
transform: translateX(100%);
}
}
/* Range sliders: thin monochrome track, white knob with a soft shadow
(QuickTime / iOS). The filled part is drawn by the component with a
background gradient on --range-fill when it wants one. */
input[type="range"].range {
-webkit-appearance: none;
appearance: none;
height: 20px;
background: transparent;
cursor: pointer;
}
input[type="range"].range::-webkit-slider-runnable-track {
height: 4px;
border-radius: 999px;
background: linear-gradient(
to right,
var(--playhead) 0 var(--range-fill, 0%),
var(--fill-press) var(--range-fill, 0%) 100%
);
}
input[type="range"].range::-moz-range-track {
height: 4px;
border-radius: 999px;
background: var(--fill-press);
}
input[type="range"].range::-moz-range-progress {
height: 4px;
border-radius: 999px;
background: var(--playhead);
}
input[type="range"].range::-webkit-slider-thumb {
-webkit-appearance: none;
margin-top: -6px;
width: 16px;
height: 16px;
border-radius: 999px;
background: #ffffff;
box-shadow:
0 0 0 0.5px rgba(0, 0, 0, 0.12),
0 2px 6px rgba(0, 0, 0, 0.22);
transition: transform var(--dur-fast) var(--ease-out);
}
input[type="range"].range::-moz-range-thumb {
width: 16px;
height: 16px;
border: none;
border-radius: 999px;
background: #ffffff;
box-shadow:
0 0 0 0.5px rgba(0, 0, 0, 0.12),
0 2px 6px rgba(0, 0, 0, 0.22);
}
input[type="range"].range:active::-moz-range-thumb {
transform: scale(1.12);
}
input[type="range"].range:active::-webkit-slider-thumb {
transform: scale(1.12);
}
/* Scrollbars: thin, overlay-like. */
* {
scrollbar-width: thin;
scrollbar-color: var(--scrollbar) transparent;
}
*::-webkit-scrollbar {
width: 8px;
height: 8px;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 8px;
border: 2px solid transparent;
background-clip: padding-box;
}
*:hover::-webkit-scrollbar-thumb {
background-color: var(--scrollbar);
}
/* ── Motion ─────────────────────────────────────────────────────── */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fade-in-up {
animation: fadeInUp var(--dur-slow) var(--ease-out) both;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.animate-fade-in {
animation: fadeIn var(--dur) var(--ease-out) both;
}
.animate-fade-in-late {
animation: fadeInUp var(--dur-slow) var(--ease-out) 0.25s both;
}
/* Menus and popovers: a small spring from just above. */
@keyframes menuPop {
from {
opacity: 0;
transform: translateY(-4px) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.animate-menu-pop {
animation: menuPop var(--dur) var(--ease-spring) both;
transform-origin: top center;
}
/* ── Shared transitions (transitions.dev patterns on the house tokens) ──
All use the `scale` / `opacity` properties and CSS transitions, never keyframes, for anything
that can be reopened mid-exit: a transition retargets from the live value, so it reverses
smoothly (apple-design: interruptible). Drive them with `data-state` from usePresence(). */
/* Surface that grows from its trigger (menus, popovers). Set transform-origin to the trigger. */
.t-pop {
transition:
opacity var(--duration-fast) var(--ease-out),
scale var(--duration-fast) var(--ease-out);
}
.t-pop[data-state="open"] {
opacity: 1;
scale: 1;
@starting-style {
opacity: 0;
scale: var(--scale-medium);
}
}
.t-pop[data-state="closing"] {
opacity: 0;
scale: var(--scale-tiny);
transition-duration: var(--duration-quick);
pointer-events: none;
}
/* Centred overlay content (enlarged camera, fullscreen insight). */
.t-modal {
transition:
opacity var(--duration-fast) var(--ease-out),
scale var(--duration-fast) var(--ease-out);
}
.t-modal[data-state="open"] {
opacity: 1;
scale: 1;
@starting-style {
opacity: 0;
scale: var(--scale-large);
}
}
.t-modal[data-state="closing"] {
opacity: 0;
scale: var(--scale-large);
transition-duration: var(--duration-quick);
pointer-events: none;
}
/* For an element that is re-classed rather than mounted (no @starting-style to hook). */
@keyframes t-modal-in {
from {
opacity: 0;
scale: var(--scale-large);
}
}
.t-modal-in {
animation: t-modal-in var(--duration-fast) var(--ease-out) both;
}
/* Opacity-only enter/exit: scrims, veils, backdrops (never animate the blur radius). */
.t-fade {
transition: opacity var(--duration-fast) var(--ease-out);
}
.t-fade[data-state="open"] {
opacity: 1;
@starting-style {
opacity: 0;
}
}
.t-fade[data-state="closing"] {
opacity: 0;
transition-duration: var(--duration-quick);
pointer-events: none;
}
/* Skeleton -> content: play only on the loading -> loaded change, not on every mount. */
@keyframes t-reveal {
from {
opacity: 0;
}
}
.t-reveal {
animation: t-reveal var(--duration-slow) ease-in-out both;
}
/* Two icons in one slot cross-fade with blur + scale (IconSwap in ui.tsx). */
.icon-swap {
display: inline-grid;
place-items: center;
}
.icon-swap > [data-slot] {
grid-area: 1 / 1;
display: inline-flex;
transition:
opacity var(--duration-fast) ease-in-out,
scale var(--duration-fast) ease-in-out,
filter var(--duration-fast) ease-in-out;
}
.icon-swap[data-state="on"] > [data-slot="off"],
.icon-swap[data-state="off"] > [data-slot="on"] {
opacity: 0;
scale: 0.25;
filter: blur(var(--blur-small));
}
.icon-swap[data-instant] > [data-slot] {
transition: none;
}
/* In-flow disclosure that grows / shrinks (Collapse in ui.tsx). Padding goes on the inner
element, never the track, or a strip stays visible when closed. */
.collapse-track {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows var(--duration-fast) var(--ease-out);
}
.collapse-track[data-state="open"] {
grid-template-rows: 1fr;
}
.collapse-inner {
min-height: 0;
overflow: hidden;
opacity: 0;
transition: opacity var(--duration-fast) var(--ease-out);
}
.collapse-track[data-state="open"] > .collapse-inner {
opacity: 1;
}
/* One frame without transitions while the theme flips, so 120ms control fades can't lag the
instantly re-themed canvas (utils/theme.ts adds and removes it). */
.theme-switching,
.theme-switching *,
.theme-switching *::before,
.theme-switching *::after {
transition: none !important;
}
/* ── Accessibility preferences ──────────────────────────────────── */
/* Reduced motion is not "no feedback": state changes are instant and moving keyframes become a
short fade, but spinners keep turning so a load never looks hung. */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
.animate-spin {
animation-duration: 900ms !important;
animation-iteration-count: infinite !important;
}
.animate-menu-pop,
.animate-fade-in-up,
.animate-fade-in-late,
.t-modal-in,
.t-reveal {
animation-name: fadeIn !important;
animation-duration: var(--dur) !important;
}
.skeleton::after {
animation: none !important;
}
}
/* Reduced transparency: frosted surfaces become solid. */
@media (prefers-reduced-transparency: reduce) {
:root,
:root.dark {
--surface-raised: var(--surface);
}
.glass,
.chrome {
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
}
.chrome {
background: var(--bg) !important;
}
}
/* More contrast: firmer separators and secondary text, and an edge on glass. */
@media (prefers-contrast: more) {
:root {
--separator: rgba(0, 0, 0, 0.2);
--separator-strong: rgba(0, 0, 0, 0.32);
--fg-secondary: #45454b;
--surface-raised: var(--surface);
}
:root.dark {
--separator: rgba(255, 255, 255, 0.22);
--separator-strong: rgba(255, 255, 255, 0.34);
--fg-secondary: #c7c7cc;
--surface-raised: var(--surface);
}
.glass {
outline: 1px solid var(--separator-strong);
}
}
@media (forced-colors: active) {
.glass,
.card {
border: 1px solid CanvasText;
}
}