/* ============================================================
   rostra.css — v0.1.0
   Core of the Rostra design system: tokens, themes, density, components.
   Framework-independent: link the file and use the rs-* classes.
   Theme: data-theme="light|dark|warm|contrast" on any container.
   Density: data-density="compact|medium|roomy|mobile".

   No font is loaded from here: rostra.css makes no network requests.
   Link fonts.css or your own local copy of Golos Text — see the README.
   ============================================================ */

/* --- 1. Tokens ------------------------------------------------
   GENERATED from rostra.tokens.json — do not edit by hand.
   Rebuild with: npm run build:css

   Colours are declared twice: sRGB first, then oklch inside @supports.
   Duplicating the declaration within one block does not work: a browser does
   not validate a custom property's value, so an old one accepts oklch as a
   valid token and the property consuming it becomes invalid instead —
   leaving nothing at all instead of a fallback.
   -------------------------------------------------------------- */

:root,
[data-theme='light'] {
  --rs-accent-50: #eff6ff;
  --rs-accent-100: #dfecff;
  --rs-accent-200: #bcd2f9;
  --rs-accent-400: #7fa4ea;
  --rs-accent-500: #3f6bbf;
  --rs-accent-600: #2c56a8;
  --rs-accent-700: #214487;
  --rs-ok: #249057;
  --rs-ok-bg: #d9fae3;
  --rs-ok-fg: #005e31;
  --rs-warn: #d49838;
  --rs-warn-bg: #fff1ce;
  --rs-warn-fg: #754700;
  --rs-bad: #c04442;
  --rs-bad-bg: #ffe9e6;
  --rs-bad-fg: #972e2d;
  --rs-info: var(--rs-accent-500);
  --rs-info-bg: #e4f1ff;
  --rs-info-fg: #284e99;
  --rs-bg: #f9fafd;
  --rs-surface: #ffffff;
  --rs-surface-2: #f8f9fc;
  --rs-surface-3: #eef0f4;
  --rs-border: #dfe1e7;
  --rs-border-strong: #ced1d8;
  --rs-control-border: #83868e;
  --rs-hairline: #edeef2;
  --rs-text: #1c1f25;
  --rs-text-muted: #656971;
  --rs-text-faint: #686c74;
  --rs-text-placeholder: #71747c;
  --rs-text-invert: #ffffff;
  --rs-shadow-1: 0 1px 2px rgba(20, 22, 35, 0.05);
  --rs-shadow-2: 0 8px 24px -10px rgba(20, 22, 35, 0.22);
  --rs-shadow-3: 0 20px 50px -22px rgba(20, 22, 35, 0.45);
  --rs-ring: 0 0 0 3px #dae9ff;
  --rs-ring-bad: 0 0 0 3px #ffdedb;
  --rs-font: 'Golos Text', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --rs-fs-display: 26px;
  --rs-fs-title: 20px;
  --rs-fs-section: 15.5px;
  --rs-fs-body: 13.5px;
  --rs-fs-ui: 12.5px;
  --rs-fs-label: 11.5px;
  --rs-lh-body: 1.6;
  --rs-lh-ui: 1.4;
  --rs-radius-xs: 2px;
  --rs-radius-sm: 4px;
  --rs-radius: 6px;
  --rs-radius-lg: 10px;
  --rs-radius-pill: 999px;
  --rs-space-1: 4px;
  --rs-space-2: 8px;
  --rs-space-3: 12px;
  --rs-space-4: 16px;
  --rs-space-5: 20px;
  --rs-space-6: 24px;
  --rs-space-7: 32px;
  --rs-space-8: 40px;
  --rs-dur-instant: 120ms;
  --rs-dur-fast: 180ms;
  --rs-dur: 260ms;
  --rs-dur-slow: 380ms;
  --rs-dur-panel: 440ms;
  --rs-dur-out: 160ms;
  --rs-dur-out-panel: 240ms;
  --rs-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --rs-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --rs-ease-panel: cubic-bezier(0.16, 1, 0.3, 1);
  --rs-ease-in: cubic-bezier(0.55, 0, 1, 0.45);
  --rs-lift: 10px;
  --rs-control-h: 32px;
  --rs-control-h-sm: 28px;
  --rs-row-pad: 12px;
  --rs-pad-card: 18px;
}

[data-theme='dark'] {
  --rs-accent-50: #1b2942;
  --rs-accent-100: #23375c;
  --rs-accent-200: #2e4b83;
  --rs-accent-400: #5a84d4;
  --rs-accent-500: #6796ee;
  --rs-accent-600: #7daafd;
  --rs-accent-700: #97beff;
  --rs-ok-bg: #153c25;
  --rs-ok-fg: #8ee0ab;
  --rs-warn-bg: #4a330f;
  --rs-warn-fg: #f5cf7d;
  --rs-bad-bg: #542523;
  --rs-bad-fg: #ffb8b0;
  --rs-info-bg: #223251;
  --rs-info-fg: #aeceff;
  --rs-bg: #13161c;
  --rs-surface: #1c1f26;
  --rs-surface-2: #23262d;
  --rs-surface-3: #2c3039;
  --rs-border: #34383f;
  --rs-border-strong: #494d56;
  --rs-control-border: #7b808a;
  --rs-hairline: #282b33;
  --rs-text: #eceef3;
  --rs-text-muted: #a7abb3;
  --rs-text-faint: #9b9ea6;
  --rs-text-placeholder: #888c94;
  --rs-text-invert: #0f1217;
  --rs-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --rs-shadow-2: 0 8px 24px -10px rgba(0, 0, 0, 0.6);
  --rs-shadow-3: 0 20px 50px -22px rgba(0, 0, 0, 0.75);
  --rs-ring: 0 0 0 3px #314c7e;
}

[data-theme='warm'] {
  --rs-bg: #faf7f1;
  --rs-surface: #ffffff;
  --rs-surface-2: #faf7f2;
  --rs-surface-3: #f4f0e7;
  --rs-border: #e8e4dd;
  --rs-border-strong: #d8d4ca;
  --rs-control-border: #8a867d;
  --rs-hairline: #f3f0ea;
  --rs-text: #29231d;
  --rs-text-muted: #6f685f;
  --rs-text-faint: #726a62;
  --rs-text-placeholder: #7a736c;
  --rs-radius: 10px;
  --rs-radius-lg: 14px;
  --rs-shadow-1: 0 1px 2px rgba(30, 26, 20, 0.05);
  --rs-shadow-2: 0 10px 30px -14px rgba(30, 26, 20, 0.24);
}

[data-theme='contrast'] {
  --rs-accent-500: #0a41ad;
  --rs-accent-600: #002c88;
  --rs-ok-fg: #004d21;
  --rs-warn-fg: #5a3200;
  --rs-bad-fg: #861118;
  --rs-info-fg: #133c8b;
  --rs-bg: #ffffff;
  --rs-surface: #ffffff;
  --rs-surface-2: #ffffff;
  --rs-surface-3: #ebebeb;
  --rs-border: #52555b;
  --rs-border-strong: #26292e;
  --rs-control-border: #26292e;
  --rs-hairline: #9b9ea5;
  --rs-text: #0b0d12;
  --rs-text-muted: #303338;
  --rs-text-faint: #3a3d43;
  --rs-text-placeholder: #505358;
  --rs-ring: 0 0 0 3px #3a6cce;
  --rs-shadow-1: none;
  --rs-shadow-2: 0 0 0 1px #52555b;
}

/* Density */

[data-density='compact'] { --rs-control-h: 28px; --rs-control-h-sm: 24px; --rs-row-pad: 7px; --rs-pad-card: 14px; --rs-fs-ui: 12px; }

[data-density='medium'] { --rs-control-h: 32px; --rs-control-h-sm: 28px; --rs-row-pad: 12px; --rs-pad-card: 18px; }

[data-density='roomy'] { --rs-control-h: 38px; --rs-control-h-sm: 32px; --rs-row-pad: 16px; --rs-pad-card: 24px; --rs-fs-ui: 13px; }

[data-density='mobile'] { --rs-control-h: 44px; --rs-control-h-sm: 38px; --rs-row-pad: 14px; --rs-pad-card: 16px; --rs-fs-ui: 13.5px; --rs-fs-label: 12px; --rs-fs-body: 15px; --rs-radius: 16px; --rs-radius-sm: 12px; --rs-radius-lg: 20px; }

/* Colour in oklch, where the browser understands it. */
@supports (color: oklch(0 0 0)) {
  :root,
  [data-theme='light'] {
    --rs-accent-50: oklch(0.972 0.018 262);
    --rs-accent-100: oklch(0.94 0.035 262);
    --rs-accent-200: oklch(0.86 0.06 262);
    --rs-accent-400: oklch(0.72 0.11 262);
    --rs-accent-500: oklch(0.54 0.14 262);
    --rs-accent-600: oklch(0.47 0.14 262);
    --rs-accent-700: oklch(0.4 0.12 262);
    --rs-ok: oklch(0.58 0.13 155);
    --rs-ok-bg: oklch(0.955 0.045 155);
    --rs-ok-fg: oklch(0.42 0.11 155);
    --rs-warn: oklch(0.72 0.13 75);
    --rs-warn-bg: oklch(0.965 0.05 80);
    --rs-warn-fg: oklch(0.44 0.1 70);
    --rs-bad: oklch(0.56 0.16 25);
    --rs-bad-bg: oklch(0.96 0.035 25);
    --rs-bad-fg: oklch(0.46 0.14 25);
    --rs-info-bg: oklch(0.955 0.035 262);
    --rs-info-fg: oklch(0.44 0.13 262);
    --rs-bg: oklch(0.985 0.004 265);
    --rs-surface-2: oklch(0.982 0.004 265);
    --rs-surface-3: oklch(0.955 0.005 265);
    --rs-border: oklch(0.91 0.008 265);
    --rs-border-strong: oklch(0.86 0.01 265);
    --rs-control-border: oklch(0.62 0.012 265);
    --rs-hairline: oklch(0.95 0.005 265);
    --rs-text: oklch(0.24 0.012 265);
    --rs-text-muted: oklch(0.52 0.014 265);
    --rs-text-faint: oklch(0.53 0.014 265);
    --rs-text-placeholder: oklch(0.56 0.012 265);
    --rs-ring: 0 0 0 3px oklch(0.93 0.04 262);
    --rs-ring-bad: 0 0 0 3px oklch(0.93 0.04 25);
  }
  
  [data-theme='dark'] {
    --rs-accent-50: oklch(0.28 0.05 262);
    --rs-accent-100: oklch(0.34 0.07 262);
    --rs-accent-200: oklch(0.42 0.1 262);
    --rs-accent-400: oklch(0.62 0.13 262);
    --rs-accent-500: oklch(0.68 0.14 262);
    --rs-accent-600: oklch(0.74 0.13 262);
    --rs-accent-700: oklch(0.8 0.11 262);
    --rs-ok-bg: oklch(0.32 0.06 155);
    --rs-ok-fg: oklch(0.84 0.11 155);
    --rs-warn-bg: oklch(0.34 0.06 75);
    --rs-warn-fg: oklch(0.87 0.11 85);
    --rs-bad-bg: oklch(0.33 0.07 25);
    --rs-bad-fg: oklch(0.86 0.1 25);
    --rs-info-bg: oklch(0.32 0.06 262);
    --rs-info-fg: oklch(0.85 0.09 262);
    --rs-bg: oklch(0.2 0.012 265);
    --rs-surface: oklch(0.24 0.014 265);
    --rs-surface-2: oklch(0.27 0.014 265);
    --rs-surface-3: oklch(0.31 0.016 265);
    --rs-border: oklch(0.34 0.014 265);
    --rs-border-strong: oklch(0.42 0.016 265);
    --rs-control-border: oklch(0.6 0.016 265);
    --rs-hairline: oklch(0.29 0.014 265);
    --rs-text: oklch(0.95 0.006 265);
    --rs-text-muted: oklch(0.74 0.012 265);
    --rs-text-faint: oklch(0.7 0.012 265);
    --rs-text-placeholder: oklch(0.64 0.012 265);
    --rs-text-invert: oklch(0.18 0.012 265);
    --rs-ring: 0 0 0 3px oklch(0.42 0.09 262);
  }
  
  [data-theme='warm'] {
    --rs-bg: oklch(0.976 0.008 85);
    --rs-surface-2: oklch(0.978 0.008 85);
    --rs-surface-3: oklch(0.955 0.012 85);
    --rs-border: oklch(0.92 0.01 85);
    --rs-border-strong: oklch(0.87 0.014 85);
    --rs-control-border: oklch(0.62 0.014 85);
    --rs-hairline: oklch(0.955 0.008 85);
    --rs-text: oklch(0.26 0.014 70);
    --rs-text-muted: oklch(0.52 0.016 70);
    --rs-text-faint: oklch(0.53 0.016 70);
    --rs-text-placeholder: oklch(0.56 0.014 70);
  }
  
  [data-theme='contrast'] {
    --rs-accent-500: oklch(0.42 0.18 262);
    --rs-accent-600: oklch(0.34 0.16 262);
    --rs-ok-fg: oklch(0.36 0.11 155);
    --rs-warn-fg: oklch(0.36 0.09 70);
    --rs-bad-fg: oklch(0.4 0.15 25);
    --rs-info-fg: oklch(0.38 0.14 262);
    --rs-surface-3: oklch(0.94 0 0);
    --rs-border: oklch(0.45 0.01 265);
    --rs-border-strong: oklch(0.28 0.01 265);
    --rs-control-border: oklch(0.28 0.01 265);
    --rs-hairline: oklch(0.7 0.01 265);
    --rs-text: oklch(0.16 0.01 265);
    --rs-text-muted: oklch(0.32 0.01 265);
    --rs-text-faint: oklch(0.36 0.01 265);
    --rs-text-placeholder: oklch(0.44 0.01 265);
    --rs-ring: 0 0 0 3px oklch(0.55 0.16 262);
    --rs-shadow-2: 0 0 0 1px oklch(0.45 0.01 265);
  }
}

/* --- 2. Base ------------------------------------------------- */
.rs { font-family: var(--rs-font); color: var(--rs-text); background: var(--rs-bg); font-variant-numeric: tabular-nums; -webkit-font-smoothing: antialiased; }
.rs *, .rs *::before, .rs *::after { box-sizing: border-box; }
.rs a { color: var(--rs-accent-500); text-decoration: none; }
.rs a:hover { color: var(--rs-accent-600); text-decoration: underline; text-underline-offset: 2px; }
/* Section eyebrow: uppercase plus a hairline running to the end of the block.
   The line gives the page its rhythm; a leading dash would be pure decoration. */
.rs-eyebrow { display: flex; align-items: center; gap: 10px; font: 500 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-muted); text-transform: uppercase; letter-spacing: 0.07em; }
.rs-eyebrow::after { content: ''; flex: 1; height: 1px; background: var(--rs-hairline); }
.rs-eyebrow--sentence { text-transform: none; letter-spacing: 0; }
.rs-eyebrow--bare::after { display: none; }
/* Three official variants, each with its place:
   .rs-eyebrow        — page and library sections: the line sets the page rhythm;
   .rs-eyebrow--tick  — inside cards and panels, where a line fights the border;
   .rs-eyebrow--tag   — above a group of cards: the label reads as a section.
   There is no fourth: more variants mean less system. */
.rs-eyebrow--tick { gap: 7px; }
.rs-eyebrow--tick::before { content: ''; width: 10px; height: 2px; border-radius: 1px; background: var(--rs-accent-500); flex: none; }
.rs-eyebrow--tick::after { display: none; }
.rs-eyebrow--tag > span:first-child { background: var(--rs-surface-3); border-radius: var(--rs-radius-sm); padding: 5px 8px; flex: none; white-space: nowrap; }
/* Uppercase is allowed in exactly two places: the section eyebrow and a code
   or abbreviation. Never in buttons, headings, sentences, or statuses longer
   than a single word. */
.rs-caps { text-transform: uppercase; letter-spacing: 0.07em; font-weight: 500; font-size: var(--rs-fs-label); }
.rs-code { text-transform: uppercase; letter-spacing: 0.02em; color: var(--rs-text-faint); }
/* A block of code — a config, a payload, a snippet. Monospace here rather than
   the interface face: alignment is the point, and it is the one place in the
   system where the text is not prose. */
.rs-pre { margin: 0; padding: 12px 14px; background: var(--rs-surface-2); border: 1px solid var(--rs-hairline); border-radius: var(--rs-radius); font: 400 var(--rs-fs-label) / 1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--rs-text); overflow-x: auto; white-space: pre; }
/* A class or property name reads as code, so no uppercase */
.rs-api { text-transform: none; letter-spacing: 0; color: var(--rs-text-muted); background: var(--rs-surface-2); border: 1px solid var(--rs-hairline); border-radius: 3px; padding: 1px 5px; font-size: var(--rs-fs-label); }
.rs-title { font: 600 var(--rs-fs-title) / 1.25 var(--rs-font); color: var(--rs-text); margin: 0; }
.rs-section-title { font: 600 var(--rs-fs-section) / 1.4 var(--rs-font); margin: 0; }
.rs-text { font: 400 var(--rs-fs-body) / var(--rs-lh-body) var(--rs-font); color: var(--rs-text); }
.rs-muted { color: var(--rs-text-muted); }
.rs-faint { color: var(--rs-text-faint); }

/* --- 3. Buttons -------------------------------------------- */
.rs-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: var(--rs-control-h); padding: 0 12px; border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius); background: var(--rs-surface); color: var(--rs-text);
  font: 500 var(--rs-fs-ui) / 1 var(--rs-font); cursor: pointer; white-space: nowrap;
  transition: background var(--rs-dur-fast) var(--rs-ease), border-color var(--rs-dur-fast) var(--rs-ease), color var(--rs-dur-fast) var(--rs-ease);
}
.rs-btn:hover { background: var(--rs-surface-2); border-color: var(--rs-border-strong); }
.rs-btn:active { background: var(--rs-surface-3); }
/* The focus ring takes three rules for the sake of browsers without
   :focus-visible. The first is the fallback: a ring on any focus, mouse
   included. The second removes it where :focus-visible is understood — in
   older browsers that selector is invalid, so the whole rule is skipped and
   the fallback survives. The third gives the ring back to the keyboard.
   The order must not change. */
.rs-btn:focus { outline: none; box-shadow: var(--rs-ring); }
.rs-btn:focus:not(:focus-visible) { box-shadow: none; }
.rs-btn:focus-visible { outline: none; box-shadow: var(--rs-ring); border-color: var(--rs-accent-400); }
.rs-btn[disabled], .rs-btn.is-disabled { opacity: 0.5; cursor: not-allowed; background: var(--rs-surface-2); }
.rs-btn--primary { background: var(--rs-accent-500); border-color: transparent; color: var(--rs-text-invert); }
.rs-btn--primary:hover { background: var(--rs-accent-600); border-color: transparent; }
.rs-btn--primary:active { background: var(--rs-accent-700); }
.rs-btn--ghost { background: transparent; border-color: transparent; color: var(--rs-text-muted); }
.rs-btn--ghost:hover { background: var(--rs-surface-3); color: var(--rs-text); border-color: transparent; }
.rs-btn--danger { color: var(--rs-bad-fg); border-color: var(--rs-border); border-color: color-mix(in oklab, var(--rs-bad) 40%, var(--rs-border)); }
.rs-btn--danger:hover { background: var(--rs-bad-bg); }
.rs-btn--sm { height: var(--rs-control-h-sm); padding: 0 10px; font-size: var(--rs-fs-label); }
.rs-btn--icon { width: var(--rs-control-h); padding: 0; }
.rs-btn.is-loading { color: transparent; position: relative; }
/* The spinner colour follows the button surface, not its text: text is
   transparent while loading. A white spinner on a light button would be
   invisible. */
.rs-btn.is-loading::after {
  content: ''; position: absolute; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent; color: var(--rs-text);
  animation: rs-spin 700ms linear infinite;
}
.rs-btn--primary.is-loading::after { color: var(--rs-text-invert); }
@keyframes rs-spin { to { transform: rotate(360deg); } }

/* --- 4. Fields --------------------------------------------- */
.rs-field { display: flex; flex-direction: column; gap: 6px; }
.rs-label { font: 400 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-muted); }
.rs-hint { font: 400 var(--rs-fs-label) / 1.45 var(--rs-font); color: var(--rs-text-faint); }
.rs-error { font: 400 var(--rs-fs-label) / 1.45 var(--rs-font); color: var(--rs-bad-fg); }
/* A control border is not decoration — it is the only sign that there is a
   field here at all. WCAG 1.4.11 asks for 3:1, which --rs-border (the card
   hairline) does not provide. The quieter original look is one line away:
   --rs-control-border: var(--rs-border). */
.rs-input, .rs-select, .rs-textarea {
  height: var(--rs-control-h); padding: 0 11px; border: 1px solid var(--rs-control-border);
  border-radius: var(--rs-radius); background: var(--rs-surface); color: var(--rs-text);
  font: 400 var(--rs-fs-ui) / 1 var(--rs-font); width: 100%;
  transition: border-color var(--rs-dur-fast) var(--rs-ease), box-shadow var(--rs-dur-fast) var(--rs-ease);
}
.rs-textarea { height: auto; padding: 9px 11px; line-height: var(--rs-lh-ui); resize: vertical; }
.rs-input::placeholder, .rs-textarea::placeholder { color: var(--rs-text-placeholder); }
.rs-input:hover, .rs-select:hover { border-color: var(--rs-border-strong); }
.rs-input:focus, .rs-select:focus, .rs-textarea:focus { outline: none; border-color: var(--rs-accent-400); box-shadow: var(--rs-ring); }
.rs-input[aria-invalid='true'], .rs-input.is-error { border-color: var(--rs-bad); }
.rs-input[aria-invalid='true']:focus, .rs-input.is-error:focus { box-shadow: var(--rs-ring-bad); }
.rs-input[disabled], .rs-input[readonly] { background: var(--rs-surface-2); color: var(--rs-text-muted); cursor: not-allowed; }
.rs-select { -webkit-appearance: none; -moz-appearance: none; appearance: none; padding-right: 30px; }

.rs-check, .rs-radio { width: 16px; height: 16px; border: 1px solid var(--rs-control-border); background: var(--rs-surface); display: inline-flex; align-items: center; justify-content: center; flex: none; }
.rs-check { border-radius: var(--rs-radius-sm); }
.rs-radio { border-radius: var(--rs-radius-pill); }
.rs-check.is-on, .rs-radio.is-on { background: var(--rs-accent-500); border-color: var(--rs-accent-500); color: var(--rs-text-invert); }
.rs-radio.is-on { background: var(--rs-surface); border-color: var(--rs-accent-500); }
.rs-radio.is-on::after { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--rs-accent-500); }
/* An unchecked switch on a white card differed from the background only by
   its surface-3 fill — about 1.1:1. The border makes it visible. */
.rs-switch { width: 32px; height: 18px; border-radius: var(--rs-radius-pill); background: var(--rs-surface-3); border: 1px solid var(--rs-control-border); display: inline-flex; align-items: center; padding: 1px; flex: none; transition: background var(--rs-dur) var(--rs-ease), border-color var(--rs-dur) var(--rs-ease); }
.rs-switch::after { content: ''; width: 14px; height: 14px; border-radius: 50%; background: var(--rs-surface); box-shadow: var(--rs-shadow-1); transition: transform var(--rs-dur) var(--rs-ease); }
.rs-switch.is-on { background: var(--rs-accent-500); border-color: var(--rs-accent-500); }
.rs-switch.is-on::after { transform: translateX(14px); }

/* Native controls wearing the system's visuals.
   Markup: <label class="rs-choice"><input type="checkbox" class="rs-choice__input">
   <span class="rs-check"></span><span>label</span></label>
   The input owns the state, so accessibility, forms and keyboard work without
   a line of JavaScript — .is-on is only needed where the visual is drawn
   without an input, a table cell for example.
   The checkmark is drawn with borders so a basic checkbox pulls in no icon font. */
.rs-choice { display: inline-flex; align-items: center; gap: 9px; position: relative; font: 400 var(--rs-fs-ui) / 1.4 var(--rs-font); color: var(--rs-text); cursor: pointer; }
.rs-choice__input { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; pointer-events: none; }
.rs-choice__input:disabled ~ * { opacity: 0.5; cursor: not-allowed; }
.rs-choice:has(.rs-choice__input:disabled) { cursor: not-allowed; }
.rs-choice__input:checked + .rs-check { background: var(--rs-accent-500); border-color: var(--rs-accent-500); color: var(--rs-text-invert); }
.rs-choice__input:checked + .rs-check::after,
.rs-choice__input:indeterminate + .rs-check::after { content: ''; display: block; }
.rs-choice__input:checked + .rs-check::after { width: 4px; height: 8px; border: 2px solid currentColor; border-top: 0; border-left: 0; transform: translateY(-1px) rotate(45deg); }
.rs-choice__input:indeterminate + .rs-check { background: var(--rs-accent-500); border-color: var(--rs-accent-500); color: var(--rs-text-invert); }
.rs-choice__input:indeterminate + .rs-check::after { width: 8px; height: 2px; border-radius: 1px; background: currentColor; }
.rs-choice__input:checked + .rs-radio { background: var(--rs-surface); border-color: var(--rs-accent-500); }
.rs-choice__input:checked + .rs-radio::after { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--rs-accent-500); animation: rs-pop var(--rs-dur-instant) var(--rs-ease-out) both; }
.rs-choice__input:checked + .rs-switch { background: var(--rs-accent-500); border-color: var(--rs-accent-500); }
.rs-choice__input:checked + .rs-switch::after { transform: translateX(14px); }
.rs-choice__input:focus + .rs-check,
.rs-choice__input:focus + .rs-radio,
.rs-choice__input:focus + .rs-switch { box-shadow: var(--rs-ring); }
.rs-choice__input:focus:not(:focus-visible) + .rs-check,
.rs-choice__input:focus:not(:focus-visible) + .rs-radio,
.rs-choice__input:focus:not(:focus-visible) + .rs-switch { box-shadow: none; }
.rs-choice__input:focus-visible + .rs-check,
.rs-choice__input:focus-visible + .rs-radio,
.rs-choice__input:focus-visible + .rs-switch { box-shadow: var(--rs-ring); border-color: var(--rs-accent-400); }

/* --- 5. Surfaces ------------------------------------------- */
.rs-card { background: var(--rs-surface); border: 1px solid var(--rs-border); border-radius: var(--rs-radius); }
.rs-card__body { padding: var(--rs-pad-card); }
.rs-divider { height: 1px; background: var(--rs-hairline); border: 0; margin: var(--rs-space-4) 0; }

/* --- 6. Status --------------------------------------------- */
.rs-badge { display: inline-flex; align-items: center; gap: 6px; height: 22px; white-space: nowrap; padding: 0 8px; border-radius: var(--rs-radius-sm); font: 500 var(--rs-fs-label) / 1 var(--rs-font); background: var(--rs-surface-3); color: var(--rs-text-muted); }
.rs-badge::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: none; }
.rs-badge--plain::before { display: none; }
.rs-badge--ok { background: var(--rs-ok-bg); color: var(--rs-ok-fg); }
.rs-badge--warn { background: var(--rs-warn-bg); color: var(--rs-warn-fg); }
.rs-badge--bad { background: var(--rs-bad-bg); color: var(--rs-bad-fg); }
.rs-badge--info { background: var(--rs-info-bg); color: var(--rs-info-fg); }
.rs-chip { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; height: var(--rs-control-h-sm); padding: 0 10px; border: 1px solid var(--rs-border); border-radius: var(--rs-radius); background: var(--rs-surface); font: 400 var(--rs-fs-ui) / 1 var(--rs-font); color: var(--rs-text); }
.rs-chip.is-on { border-color: var(--rs-accent-200); background: var(--rs-accent-50); color: var(--rs-info-fg); font-weight: 500; }
.rs-chip--add { border-style: dashed; color: var(--rs-text-muted); }

/* --- 7. Table ---------------------------------------------- */
.rs-table { width: 100%; border-collapse: collapse; font-family: var(--rs-font); }
.rs-table th { text-align: left; font: 500 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-muted); text-transform: uppercase; letter-spacing: 0.06em; padding: 10px 14px; background: var(--rs-surface-2); border-bottom: 1px solid var(--rs-border); white-space: nowrap; }
.rs-table td { font: 400 var(--rs-fs-ui) / var(--rs-lh-ui) var(--rs-font); color: var(--rs-text); padding: var(--rs-row-pad) 14px; border-bottom: 1px solid var(--rs-hairline); }
.rs-table tbody tr:hover td { background: var(--rs-surface-2); }
.rs-table .rs-num { text-align: right; font-variant-numeric: tabular-nums; }
.rs-table--zebra tbody tr:nth-child(even) td { background: var(--rs-surface-2); }
.rs-table--sentence-head th { text-transform: none; letter-spacing: 0; }
.rs-table__group td { background: var(--rs-surface-2); font-weight: 500; color: var(--rs-text); }
.rs-table-wrap { border: 1px solid var(--rs-border); border-radius: var(--rs-radius); overflow: hidden; background: var(--rs-surface); }

/* --- 8. Navigation ----------------------------------------- */
.rs-tabs { display: flex; gap: 20px; border-bottom: 1px solid var(--rs-border); }
/* A tab may be a div or a button. For a button the browser paints its own
   background, border and font, so the reset is mandatory — otherwise tabs
   look like buttons. */
.rs-tab { appearance: none; -webkit-appearance: none; background: none; border: 0; padding: 0 0 10px; font: 400 var(--rs-fs-ui) / 1 var(--rs-font); color: var(--rs-text-muted); cursor: pointer; }
/* State arrives from two directions: .is-on is set by hand-written markup,
   data-state by the behaviour library in the React layer. Both are equal
   citizens — otherwise the core would be tied to one way of using it. */
.rs-tab.is-on,
.rs-tab[data-state='active'] { color: var(--rs-text); font-weight: 500; box-shadow: inset 0 -2px 0 var(--rs-accent-500); }
/* The class is doubled on purpose: a nav item is usually an <a>, and `.rs a`
   above is one point more specific than a single class would be. Without this
   every inactive item comes out accent-blue and underlines on hover. */
.rs-nav-item { display: flex; align-items: center; gap: 10px; height: var(--rs-control-h); padding: 0 10px; border-radius: var(--rs-radius); font: 400 var(--rs-fs-ui) / 1 var(--rs-font); cursor: pointer; }
.rs-nav-item.rs-nav-item { color: var(--rs-text-muted); text-decoration: none; }
.rs-nav-item.rs-nav-item:hover { background: var(--rs-surface-2); color: var(--rs-text); text-decoration: none; }
.rs-nav-item.rs-nav-item.is-on { background: var(--rs-surface-3); color: var(--rs-text); font-weight: 500; }
.rs-crumbs { display: flex; align-items: center; gap: 8px; font: 400 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-muted); }
.rs-seg { display: inline-flex; padding: 2px; gap: 2px; background: var(--rs-surface-3); border-radius: var(--rs-radius); }
.rs-seg__btn { height: var(--rs-control-h-sm); padding: 0 11px; border: 0; border-radius: calc(var(--rs-radius) - 2px); background: transparent; color: var(--rs-text-muted); font: 400 var(--rs-fs-ui) / 1 var(--rs-font); cursor: pointer; }
.rs-seg__btn.is-on { background: var(--rs-surface); color: var(--rs-text); font-weight: 500; box-shadow: var(--rs-shadow-1); }

/* --- 9. Feedback ------------------------------------------- */
/* Geometry of floating layers. Their appearance is defined below; this is
   only where they hang — without it every consumer would position dialogs
   with inline styles. */
.rs-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; inset: 0; z-index: 40; background: rgba(20, 22, 35, 0.4); background: color-mix(in oklab, var(--rs-text) 40%, transparent); }
.rs-layer { position: fixed; z-index: 41; }
.rs-layer--center { top: 50%; left: 50%; transform: translate(-50%, -50%); max-width: calc(100vw - 2 * var(--rs-space-5)); max-height: calc(100vh - 2 * var(--rs-space-5)); max-height: calc(100dvh - 2 * var(--rs-space-5)); display: flex; }
.rs-layer--right { top: 0; right: 0; bottom: 0; display: flex; }
.rs-drawer { width: min(460px, 100vw); height: 100%; display: flex; flex-direction: column; background: var(--rs-surface); border-left: 1px solid var(--rs-border); box-shadow: var(--rs-shadow-3); }
.rs-drawer__head, .rs-dialog__head { flex: none; display: flex; align-items: center; gap: 12px; padding: 14px var(--rs-pad-card); border-bottom: 1px solid var(--rs-hairline); }
.rs-drawer__body, .rs-dialog__body { flex: 1; min-height: 0; overflow: auto; padding: var(--rs-pad-card); }
.rs-drawer__foot, .rs-dialog__foot { flex: none; display: flex; justify-content: flex-end; gap: 8px; padding: 12px var(--rs-pad-card); border-top: 1px solid var(--rs-hairline); background: var(--rs-surface-2); }
.rs-toast-viewport { position: fixed; z-index: 42; top: var(--rs-space-4); right: var(--rs-space-4); display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
.rs-toast-viewport > * { pointer-events: auto; }
.rs-toast { display: flex; gap: 10px; padding: 11px 12px; background: var(--rs-surface); border: 1px solid var(--rs-border); border-radius: var(--rs-radius); box-shadow: var(--rs-shadow-2); width: 340px; }
.rs-toast__title { font: 500 var(--rs-fs-ui) / 1.35 var(--rs-font); color: var(--rs-text); }
.rs-toast__text { font: 400 var(--rs-fs-label) / 1.45 var(--rs-font); color: var(--rs-text-muted); margin-top: 2px; }
.rs-dialog { width: 440px; max-width: 100%; display: flex; flex-direction: column; background: var(--rs-surface); border: 1px solid var(--rs-border); border-radius: var(--rs-radius-lg); box-shadow: var(--rs-shadow-3); overflow: hidden; }
.rs-popover { background: var(--rs-surface); border: 1px solid var(--rs-border); border-radius: var(--rs-radius); box-shadow: var(--rs-shadow-2); padding: 12px 14px; }
.rs-tooltip { display: inline-block; background: var(--rs-text); color: var(--rs-surface); font: 400 var(--rs-fs-label) / 1.4 var(--rs-font); padding: 5px 8px; border-radius: var(--rs-radius-sm); }
.rs-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px; text-align: center; padding: var(--rs-space-7) var(--rs-space-5); }
.rs-empty__art { width: 56px; height: 40px; border-radius: var(--rs-radius-sm); border: 1px solid var(--rs-border); background: repeating-linear-gradient(45deg, var(--rs-surface-3) 0 5px, var(--rs-surface) 5px 10px); }
.rs-skeleton { height: 11px; border-radius: 3px; background: var(--rs-surface-3); position: relative; overflow: hidden; }
.rs-skeleton::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent); background: linear-gradient(90deg, transparent, color-mix(in oklab, var(--rs-surface) 70%, transparent), transparent); animation: rs-shimmer 1.3s infinite; }
@keyframes rs-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

/* --- 10. Data ---------------------------------------------- */
.rs-metric { background: var(--rs-surface); border: 1px solid var(--rs-border); border-radius: var(--rs-radius); padding: 13px 15px; }
.rs-metric__label { font: 400 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-muted); }
.rs-metric__value { font: 600 21px / 1 var(--rs-font); color: var(--rs-text); }
.rs-meter { height: 6px; border-radius: 3px; background: var(--rs-surface-3); overflow: hidden; }
.rs-meter__fill { height: 6px; border-radius: 3px; background: var(--rs-accent-500); }
.rs-steps { display: flex; align-items: center; }
.rs-step { display: flex; align-items: center; gap: 9px; font: 400 var(--rs-fs-ui) / 1 var(--rs-font); color: var(--rs-text-muted); }
.rs-step__dot { width: 24px; height: 24px; border-radius: 50%; border: 1px solid var(--rs-border); display: flex; align-items: center; justify-content: center; font: 500 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-faint); background: var(--rs-surface); }
.rs-step.is-now { color: var(--rs-text); font-weight: 500; }
.rs-step.is-now .rs-step__dot { border-color: var(--rs-accent-500); color: var(--rs-accent-500); }
.rs-step.is-done .rs-step__dot { background: var(--rs-accent-500); border-color: var(--rs-accent-500); color: var(--rs-text-invert); }
.rs-step__line { flex: 1; height: 1px; background: var(--rs-border); margin: 0 12px; }
.rs-step__line.is-done { background: var(--rs-accent-500); }

/* --- 11. Shell --------------------------------------------- */
.rs-shell { display: flex; min-height: 100%; background: var(--rs-bg); }
.rs-shell__side { flex: none; width: 236px; background: var(--rs-surface); border-right: 1px solid var(--rs-hairline); display: flex; flex-direction: column; }
.rs-shell__side[data-collapsed='true'] { width: 64px; }
.rs-shell__main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rs-shell__topbar { height: 52px; background: var(--rs-surface); border-bottom: 1px solid var(--rs-hairline); display: flex; align-items: center; gap: 14px; padding: 0 var(--rs-space-5); }
.rs-shell__content { padding: var(--rs-space-5); }

/* --- 12. Markdown ------------------------------------------ */
.rs-md { font: 400 var(--rs-fs-body) / var(--rs-lh-body) var(--rs-font); color: var(--rs-text); }
.rs-md h1 { font: 600 21px / 1.3 var(--rs-font); margin: 0 0 8px; }
.rs-md h2 { font: 600 var(--rs-fs-section) / 1.4 var(--rs-font); margin: 22px 0 10px; }
.rs-md p { margin: 0 0 12px; }
.rs-md ul, .rs-md ol { margin: 0 0 12px; padding-left: 20px; }
.rs-md li { margin: 0 0 6px; }
.rs-md ul { list-style: none; padding-left: 15px; }
.rs-md ul li { position: relative; }
.rs-md ul li::before { content: ''; position: absolute; left: -15px; top: 9px; width: 5px; height: 5px; border-radius: 1px; background: var(--rs-accent-500); }
.rs-md blockquote { margin: 16px 0; padding-left: 15px; border-left: 2px solid var(--rs-border); color: var(--rs-text-muted); }
.rs-md code { background: var(--rs-surface-2); border: 1px solid var(--rs-hairline); border-radius: 3px; padding: 1px 5px; font: inherit; font-size: var(--rs-fs-ui); }
.rs-md pre { background: var(--rs-surface-2); border: 1px solid var(--rs-border); border-radius: var(--rs-radius); padding: 13px 15px; font: 400 var(--rs-fs-ui) / 1.7 var(--rs-font); overflow-x: auto; }
.rs-md hr { border: 0; height: 1px; background: var(--rs-hairline); margin: 22px 0; }

/* --- 13. Utilities and accessibility ----------------------- */
.rs-focusable:focus { outline: none; box-shadow: var(--rs-ring); }
.rs-focusable:focus:not(:focus-visible) { box-shadow: none; }
.rs-focusable:focus-visible { outline: none; box-shadow: var(--rs-ring); }
.rs-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  .rs *, .rs *::before, .rs *::after {
    animation-duration: 1ms !important; animation-iteration-count: 1 !important;
    transition-duration: 1ms !important; scroll-behavior: auto !important;
  }
}

/* --- 14. Calendar and date range --------------------------- */
.rs-cal { width: 246px; }
.rs-cal__head { display: flex; align-items: center; gap: 8px; padding: 0 2px 10px; }
.rs-cal__month { font: 500 var(--rs-fs-ui) / 1 var(--rs-font); color: var(--rs-text); }
.rs-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.rs-cal__dow { font: 400 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-faint); text-align: center; padding: 0 0 6px; text-transform: uppercase; letter-spacing: 0.06em; }
.rs-cal__day { height: 30px; display: flex; align-items: center; justify-content: center; border-radius: var(--rs-radius-sm); font: 400 var(--rs-fs-ui) / 1 var(--rs-font); color: var(--rs-text); cursor: pointer; }
.rs-cal__day:hover { background: var(--rs-surface-3); }
.rs-cal__day.is-out { color: var(--rs-text-faint); }
.rs-cal__day.is-today { box-shadow: inset 0 0 0 1px var(--rs-border-strong); }
.rs-cal__day.is-range { background: var(--rs-accent-50); border-radius: 0; color: var(--rs-info-fg); }
.rs-cal__day.is-sel { background: var(--rs-accent-500); color: var(--rs-text-invert); font-weight: 500; }
.rs-cal__day.is-sel:first-of-type { border-radius: var(--rs-radius-sm); }
/* No opacity here: faint text at 0.45 alpha lands at 1.9:1 against the surface,
   and a non-working day is still readable content, not an inactive control. */
.rs-cal__day.is-off { color: var(--rs-text-faint); cursor: not-allowed; }

/* --- 15. Multiselect and combobox -------------------------- */
.rs-combo { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; min-height: var(--rs-control-h); padding: 4px 8px; border: 1px solid var(--rs-control-border); border-radius: var(--rs-radius); background: var(--rs-surface); }
.rs-combo:focus-within { border-color: var(--rs-accent-400); box-shadow: var(--rs-ring); }
/* The wrapper owns the positioning context; the list hangs off the field
   rather than off the page, so a combobox inside a dialog travels with it. */
.rs-combo-wrap { position: relative; }
.rs-combo__input { flex: 1 1 60px; min-width: 60px; height: 22px; border: 0; padding: 0; background: transparent; color: var(--rs-text); font: 400 var(--rs-fs-ui) / 1 var(--rs-font); }
.rs-combo__input:focus { outline: none; }
.rs-combo__list { z-index: 41; max-height: 260px; overflow-y: auto; }
.rs-token { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 4px 0 8px; border-radius: var(--rs-radius-sm); background: var(--rs-surface-3); font: 400 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text); white-space: nowrap; }
.rs-token__x { color: var(--rs-text-faint); cursor: pointer; padding: 0 3px; border: 0; background: none; font: inherit; line-height: 1; }
.rs-token__x:hover { color: var(--rs-text); }
.rs-token__x:focus-visible { outline: none; box-shadow: var(--rs-ring); border-radius: var(--rs-radius-sm); color: var(--rs-text); }
.rs-menu { background: var(--rs-surface); border: 1px solid var(--rs-border); border-radius: var(--rs-radius); box-shadow: var(--rs-shadow-2); padding: 4px; min-width: 200px; }
.rs-menu__item.rs-menu__item { color: var(--rs-text); text-decoration: none; }
.rs-menu__item { display: flex; align-items: center; gap: 9px; height: var(--rs-control-h); padding: 0 9px; border-radius: var(--rs-radius-sm); font: 400 var(--rs-fs-ui) / 1 var(--rs-font); color: var(--rs-text); cursor: pointer; }
/* is-focus for hand-written markup, data-highlighted for the item the
   keyboard moved to — without it arrow navigation is invisible on screen. */
.rs-menu__item:hover, .rs-menu__item.is-focus, .rs-menu__item[data-highlighted] { background: var(--rs-surface-2); outline: none; }
.rs-menu__item.is-on, .rs-menu__item[data-state='checked'] { color: var(--rs-info-fg); font-weight: 500; }
.rs-menu__item.is-disabled, .rs-menu__item[data-disabled] { opacity: 0.5; cursor: not-allowed; }
.rs-menu__sep { height: 1px; background: var(--rs-hairline); margin: 4px 0; }
.rs-push { margin-left: auto; }
.rs-menu__hint { margin-left: auto; color: var(--rs-text-faint); font-size: var(--rs-fs-label); }

/* --- 16. Inline editing ------------------------------------ */
.rs-cell-edit { display: inline-flex; align-items: center; gap: 6px; min-height: 24px; margin: -3px -7px; padding: 3px 7px; border: 1px solid transparent; border-radius: var(--rs-radius-sm); cursor: text; }
.rs-cell-edit:hover { border-color: var(--rs-border); background: var(--rs-surface); }
.rs-cell-edit.is-editing { border-color: var(--rs-accent-400); box-shadow: var(--rs-ring); background: var(--rs-surface); }
.rs-cell-edit.is-dirty { border-color: var(--rs-warn); background: var(--rs-warn-bg); }
.rs-cell-edit__pen { opacity: 0; color: var(--rs-text-faint); font-size: 13px; }
.rs-cell-edit:hover .rs-cell-edit__pen { opacity: 1; }

/* --- 17. Tree ---------------------------------------------- */
.rs-tree__row { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: var(--rs-radius-sm); font: 400 var(--rs-fs-ui) / 1.4 var(--rs-font); cursor: pointer; }
.rs-tree__row:hover { background: var(--rs-surface-2); }
.rs-tree__row.is-on { background: var(--rs-accent-50); color: var(--rs-info-fg); }
.rs-tree__toggle { width: 16px; color: var(--rs-text-faint); flex: none; text-align: center; }
.rs-tree__kids { margin-left: 17px; padding-left: 13px; border-left: 1px solid var(--rs-hairline); }

/* --- 18. Files --------------------------------------------- */
.rs-drop { border: 1px dashed var(--rs-control-border); border-radius: var(--rs-radius); background: var(--rs-surface-2); padding: var(--rs-space-6); display: flex; flex-direction: column; align-items: center; gap: 7px; text-align: center; }
.rs-drop.is-over { border-color: var(--rs-accent-500); background: var(--rs-accent-50); }
.rs-file { display: flex; align-items: center; gap: 11px; padding: 10px 12px; border: 1px solid var(--rs-border); border-radius: var(--rs-radius); background: var(--rs-surface); }
.rs-file__icon { width: 30px; height: 34px; border-radius: 3px; border: 1px solid var(--rs-border); background: var(--rs-surface-2); display: flex; align-items: flex-end; justify-content: center; padding-bottom: 4px; font: 500 9px / 1 var(--rs-font); color: var(--rs-text-muted); text-transform: uppercase; letter-spacing: 0.04em; flex: none; }
.rs-file__name { font: 400 var(--rs-fs-ui) / 1.35 var(--rs-font); color: var(--rs-text); }
.rs-file__meta { font: 400 var(--rs-fs-label) / 1.35 var(--rs-font); color: var(--rs-text-muted); }

/* --- 19. Board --------------------------------------------- */
.rs-board { display: flex; gap: 12px; align-items: flex-start; }
.rs-board__col { flex: 1; min-width: 0; background: var(--rs-surface-2); border: 1px solid var(--rs-hairline); border-radius: var(--rs-radius); padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.rs-board__head { display: flex; align-items: center; gap: 8px; padding: 2px 2px 4px; font: 500 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-muted); text-transform: uppercase; letter-spacing: 0.07em; }
.rs-board__count { margin-left: auto; color: var(--rs-text-faint); letter-spacing: 0; }
.rs-board__card { background: var(--rs-surface); border: 1px solid var(--rs-border); border-radius: var(--rs-radius); padding: 11px 12px; box-shadow: var(--rs-shadow-1); cursor: grab; }
.rs-board__card:hover { border-color: var(--rs-border-strong); }
.rs-board__ghost { border: 1px dashed var(--rs-accent-400); background: var(--rs-accent-50); border-radius: var(--rs-radius); height: 62px; }

/* --- 20. Timeline ------------------------------------------ */
.rs-timeline { display: flex; flex-direction: column; }
.rs-timeline__item { display: grid; grid-template-columns: 132px 16px 1fr; column-gap: 12px; padding: 0 0 16px; }
.rs-timeline__when { font: 400 var(--rs-fs-label) / 1.5 var(--rs-font); color: var(--rs-text-muted); text-align: right; padding-top: 2px; }
.rs-timeline__rail { display: flex; flex-direction: column; align-items: center; }
.rs-timeline__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--rs-surface); border: 2px solid var(--rs-accent-500); margin-top: 4px; flex: none; }
.rs-timeline__dot--muted { border-color: var(--rs-border-strong); }
.rs-timeline__line { flex: 1; width: 1px; background: var(--rs-hairline); margin: 4px 0 -14px; }
.rs-timeline__body { font: 400 var(--rs-fs-ui) / 1.5 var(--rs-font); color: var(--rs-text); padding-bottom: 2px; }

/* --- 21. Keyboard hint ------------------------------------- */
.rs-kbd { display: inline-flex; align-items: center; height: 19px; padding: 0 5px; border: 1px solid var(--rs-border); border-bottom-width: 2px; border-radius: 4px; background: var(--rs-surface-2); font: 500 10.5px / 1 var(--rs-font); color: var(--rs-text-muted); }

/* --- 22. Alerts -------------------------------------------- */
.rs-alert { display: flex; gap: 11px; padding: 12px 14px; border: 1px solid var(--rs-border); border-radius: var(--rs-radius); background: var(--rs-surface-2); }
.rs-alert__mark { width: 3px; border-radius: 2px; background: var(--rs-text-faint); flex: none; }
.rs-alert__title { font: 500 var(--rs-fs-ui) / 1.4 var(--rs-font); color: var(--rs-text); }
.rs-alert__text { font: 400 var(--rs-fs-label) / 1.5 var(--rs-font); color: var(--rs-text-muted); margin-top: 3px; }
.rs-alert--ok { background: var(--rs-ok-bg); border-color: var(--rs-border); border-color: color-mix(in oklab, var(--rs-ok) 30%, transparent); }
.rs-alert--ok .rs-alert__mark { background: var(--rs-ok); }
.rs-alert--warn { background: var(--rs-warn-bg); border-color: var(--rs-border); border-color: color-mix(in oklab, var(--rs-warn) 30%, transparent); }
.rs-alert--warn .rs-alert__mark { background: var(--rs-warn); }
.rs-alert--bad { background: var(--rs-bad-bg); border-color: var(--rs-border); border-color: color-mix(in oklab, var(--rs-bad) 30%, transparent); }
.rs-alert--bad .rs-alert__mark { background: var(--rs-bad); }
.rs-alert--info { background: var(--rs-info-bg); border-color: var(--rs-border); border-color: color-mix(in oklab, var(--rs-info) 25%, transparent); }
.rs-alert--info .rs-alert__mark { background: var(--rs-info); }

/* --- 23. Misc ---------------------------------------------- */
.rs-avatar { width: 28px; height: 28px; border-radius: var(--rs-radius); background: var(--rs-surface-3); display: inline-flex; align-items: center; justify-content: center; font: 600 10.5px / 1 var(--rs-font); color: var(--rs-text-muted); flex: none; }
.rs-avatar--round { border-radius: 50%; }
.rs-stack { display: flex; }
.rs-stack .rs-avatar { margin-left: -5px; box-shadow: 0 0 0 2px var(--rs-surface); padding-right: 2px; }
.rs-stack .rs-avatar:first-child { margin-left: 0; }
.rs-kv { display: grid; grid-template-columns: 150px 1fr; gap: 10px 16px; font: 400 var(--rs-fs-ui) / 1.5 var(--rs-font); }
.rs-kv dt { color: var(--rs-text-muted); margin: 0; }
.rs-kv dd { color: var(--rs-text); margin: 0; }

/* --- 24. Mobile shell -------------------------------------- */
/* Enabled on the container: data-density="mobile". Same tokens, different
   values: larger text, 16px radii, 44px touch targets. */
[data-density='mobile'] { --rs-control-h: 44px; --rs-control-h-sm: 38px; --rs-row-pad: 14px; --rs-pad-card: 16px; --rs-fs-ui: 13.5px; --rs-fs-label: 12px; --rs-fs-body: 15px; --rs-radius: 16px; --rs-radius-sm: 12px; --rs-radius-lg: 20px; }
.rs-m-card { background: var(--rs-surface); border: 1px solid var(--rs-border); border-radius: 16px; padding: 15px 16px; }
.rs-m-card__foot { display: flex; align-items: center; gap: 16px; margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--rs-hairline); }
.rs-m-nav { display: grid; grid-template-columns: repeat(4, 1fr); background: var(--rs-surface); border-top: 1px solid var(--rs-hairline); padding: 9px 12px 22px; }
.rs-m-nav__item { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; min-height: 44px; font: 400 12px / 1 var(--rs-font); color: var(--rs-text-muted); }
.rs-m-nav__item.is-on { color: var(--rs-accent-500); font-weight: 500; }
.rs-sheet { background: var(--rs-surface); border-radius: 24px 24px 0 0; padding: 10px 18px 26px; box-shadow: var(--rs-shadow-3); }
.rs-sheet__grip { width: 38px; height: 4px; border-radius: 2px; background: var(--rs-border); margin: 0 auto 16px; }
.rs-m-scroller { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; }
.rs-m-scroller::-webkit-scrollbar { display: none; }
.rs-m-chip { display: inline-flex; align-items: center; height: 38px; padding: 0 15px; border-radius: 12px; border: 1px solid var(--rs-border); background: var(--rs-surface); font: 400 13.5px / 1 var(--rs-font); color: var(--rs-text); flex: none; }
.rs-m-chip.is-on { background: var(--rs-accent-500); border-color: transparent; color: var(--rs-text-invert); font-weight: 500; }
.rs-m-action { height: 52px; border-radius: 15px; display: flex; align-items: center; justify-content: center; gap: 8px; background: var(--rs-accent-500); color: var(--rs-text-invert); font: 500 15px / 1 var(--rs-font); border: 0; width: 100%; }

/* --- 25. System state pages -------------------------------- */
/* 403/404/500, maintenance, first run. One markup, different tone. */
.rs-state { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 9px; max-width: 420px; margin: 0 auto; padding: var(--rs-space-8) var(--rs-space-5); }
/* The mark has no frame: the icon lives inside the code line rather than in a
   block of its own — an empty page already draws attention, and a backdrop
   would only weigh it down. */
.rs-state__code { display: flex; align-items: center; gap: 7px; font: 500 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-faint); text-transform: uppercase; letter-spacing: 0.07em; }
.rs-state__mark { font-size: 15px; color: var(--rs-text-faint); }
.rs-state__mark--warn { color: var(--rs-warn); }
.rs-state__mark--bad { color: var(--rs-bad); }
.rs-state__mark--info { color: var(--rs-info); }
.rs-state__title { font: 600 var(--rs-fs-section) / 1.35 var(--rs-font); color: var(--rs-text); }
.rs-state__text { font: 400 var(--rs-fs-ui) / 1.55 var(--rs-font); color: var(--rs-text-muted); }
.rs-state__actions { display: flex; gap: 8px; margin-top: 6px; }
.rs-state__tech { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rs-hairline); width: 100%; display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 14px; font: 400 var(--rs-fs-label) / 1.5 var(--rs-font); color: var(--rs-text-faint); }

/* --- 26. Tablet 768–1024 ----------------------------------- */
/* The sidebar becomes a rail, the table scrolls with a pinned first column,
   filters collapse behind one button. The application sets the attribute
   rather than a media query, so the same layout works inside a narrow panel
   on a large screen. */
.rs-shell[data-viewport='tablet'] .rs-shell__side { width: 60px; }
.rs-shell[data-viewport='tablet'] .rs-shell__content { padding: var(--rs-space-4); }
.rs-rail { width: 60px; flex: none; background: var(--rs-surface); border-right: 1px solid var(--rs-hairline); display: flex; flex-direction: column; align-items: center; padding: 12px 0; gap: 4px; }
.rs-rail__item.rs-rail__item { text-decoration: none; }
.rs-rail__item { width: 40px; height: 40px; border-radius: var(--rs-radius); display: flex; align-items: center; justify-content: center; color: var(--rs-text-muted); font-size: 20px; cursor: pointer; }
.rs-rail__item:hover { background: var(--rs-surface-2); color: var(--rs-text); }
.rs-rail__item.is-on { background: var(--rs-accent-50); color: var(--rs-accent-500); }
[data-theme='dark'] .rs-rail__item.is-on { background: var(--rs-accent-50); color: var(--rs-accent-600); }

.rs-table-scroll { overflow-x: auto; }
.rs-table--sticky th:first-child, .rs-table--sticky td:first-child { position: sticky; left: 0; z-index: 1; background: var(--rs-surface); }
.rs-table--sticky th:first-child { background: var(--rs-surface-2); z-index: 2; }
.rs-table--sticky th:first-child::after, .rs-table--sticky td:first-child::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; width: 1px; background: var(--rs-border); }
.rs-table--sticky tbody tr:hover td:first-child { background: var(--rs-surface-2); }

@media (max-width: 1024px) {
  .rs-hide-tablet { display: none !important; }
}
@media (max-width: 768px) {
  .rs-hide-mobile { display: none !important; }
}

/* --- 27. One-screen rule ----------------------------------- */
/* An admin panel is an application, not a page: its height equals the window,
   only the working area scrolls, header and footer are pinned. The page as a
   whole never scrolls. */
.rs-app { height: 100vh; height: 100dvh; display: flex; overflow: hidden; }
.rs-app__main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.rs-app__bar { flex: none; }
.rs-pane { flex: 1; min-height: 0; overflow: auto; }
.rs-pane--fixed { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }

/* --- 28. Custom table scrollbars --------------------------- */
/* A wide table gets two scrollbars: above the header and below the last row.
   The top one exists so that scrolling right does not require travelling to
   the end of the list first. */
.rs-xscroll { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -ms-overflow-style: none; }
.rs-xscroll::-webkit-scrollbar { display: none; }
.rs-xbar { display: flex; align-items: center; gap: 10px; padding: 7px 14px; background: var(--rs-surface); }
.rs-xbar--top { border-bottom: 1px solid var(--rs-hairline); }
.rs-xbar--bottom { border-top: 1px solid var(--rs-hairline); }
.rs-xbar__track { position: relative; flex: 1; height: 6px; border-radius: 3px; background: var(--rs-surface-3); cursor: pointer; }
.rs-xbar__thumb { position: absolute; top: 0; height: 6px; border-radius: 3px; background: var(--rs-control-border); transition: background var(--rs-dur-fast) var(--rs-ease); }
.rs-xbar__track:hover .rs-xbar__thumb { background: var(--rs-text-faint); }
.rs-xbar__thumb:active { background: var(--rs-accent-500); }
.rs-xbar__label { flex: none; font: 400 var(--rs-fs-label) / 1 var(--rs-font); color: var(--rs-text-faint); white-space: nowrap; }


/* ============================================================
   24. Motion
   One idea: everything entering decelerates for a long time at the end
   (easeOutQuint), everything leaving accelerates briefly. That is why an
   entrance reads as "placed on the table" rather than "yanked into view".
   ============================================================ */

@keyframes rs-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes rs-rise {
  from { opacity: 0; transform: translate3d(0, var(--rs-lift), 0) scale(0.985); }
  to { opacity: 1; transform: none; }
}
@keyframes rs-drop {
  from { opacity: 0; transform: translate3d(0, -6px, 0) scale(0.97); }
  to { opacity: 1; transform: none; }
}
@keyframes rs-pop {
  from { opacity: 0; transform: translate3d(0, 8px, 0) scale(0.96); }
  to { opacity: 1; transform: none; }
}
@keyframes rs-slide-right {
  from { opacity: 0; transform: translate3d(36px, 0, 0) scale(0.97); }
  to { opacity: 1; transform: none; }
}
@keyframes rs-panel-in { from { transform: translate3d(101%, 0, 0); } to { transform: none; } }

/* Exit: the same geometry at half the length, on an accelerating curve.
   An element must leave faster than it arrived, otherwise closing feels
   like interface lag. */
@keyframes rs-fade-out { to { opacity: 0; } }
@keyframes rs-rise-out { to { opacity: 0; transform: translate3d(0, 6px, 0) scale(0.99); } }
@keyframes rs-drop-out { to { opacity: 0; transform: translate3d(0, -5px, 0) scale(0.98); } }
@keyframes rs-pop-out { to { opacity: 0; transform: translate3d(0, 5px, 0) scale(0.97); } }
@keyframes rs-slide-right-out { to { opacity: 0; transform: translate3d(28px, 0, 0) scale(0.98); } }
@keyframes rs-panel-out { to { transform: translate3d(101%, 0, 0); } }
@keyframes rs-bar { from { transform: scaleY(0.02); } to { transform: scaleY(1); } }
@keyframes rs-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.28; } }
@keyframes rs-track { 0% { transform: translateX(-70%); } 100% { transform: translateX(280%); } }
@keyframes rs-nudge {
  0% { transform: none; } 18% { transform: translateX(-4px); } 42% { transform: translateX(3px); }
  68% { transform: translateX(-2px); } 100% { transform: none; }
}

/* Entrance utilities */
.rs-in { animation: rs-rise var(--rs-dur) var(--rs-ease-out) both; }
.rs-in--fade { animation-name: rs-fade; }
.rs-in--drop { animation-name: rs-drop; transform-origin: top center; }
.rs-in--pop { animation-name: rs-pop; }
.rs-in--right { animation-name: rs-slide-right; }
.rs-in--slow { animation-duration: var(--rs-dur-slow); }

/* Exit utilities. Applied --rs-dur-out before unmounting. */
.rs-out { animation: rs-rise-out var(--rs-dur-out) var(--rs-ease-in) both; }
.rs-out--fade { animation-name: rs-fade-out; }
.rs-out--drop { animation-name: rs-drop-out; }
.rs-out--pop { animation-name: rs-pop-out; }
.rs-out--right { animation-name: rs-slide-right-out; }
.rs-out--panel { animation-name: rs-panel-out; animation-duration: var(--rs-dur-out-panel); }

/* Stagger: 45ms step, capped at the ninth child */
.rs-stagger > * { animation: rs-rise var(--rs-dur) var(--rs-ease-out) both; }
.rs-stagger > *:nth-child(2) { animation-delay: 45ms; }
.rs-stagger > *:nth-child(3) { animation-delay: 90ms; }
.rs-stagger > *:nth-child(4) { animation-delay: 135ms; }
.rs-stagger > *:nth-child(5) { animation-delay: 180ms; }
.rs-stagger > *:nth-child(6) { animation-delay: 225ms; }
.rs-stagger > *:nth-child(7) { animation-delay: 270ms; }
.rs-stagger > *:nth-child(8) { animation-delay: 315ms; }
.rs-stagger > *:nth-child(n + 9) { animation-delay: 360ms; }

/* Layers animate themselves. The backdrop goes first, the content 40ms later:
   the eye has time to register that the background stepped back. */
.rs-backdrop { animation: rs-fade var(--rs-dur-fast) linear both; }
.rs-toast { animation: rs-slide-right var(--rs-dur) var(--rs-ease-out) both; }
.rs-dialog { animation: rs-pop var(--rs-dur) var(--rs-ease-out) 40ms both; }
.rs-drawer { animation: rs-panel-in var(--rs-dur-panel) var(--rs-ease-panel) both; }
.rs-popover, .rs-menu { animation: rs-drop var(--rs-dur-fast) var(--rs-ease-out) both; transform-origin: top center; }
.rs-tooltip { animation: rs-drop var(--rs-dur-instant) var(--rs-ease-out) both; }

/* Closing: the is-out class overrides the entrance animation */
.rs-backdrop.is-out { animation: rs-fade-out var(--rs-dur-out) linear both; }
.rs-toast.is-out { animation: rs-slide-right-out var(--rs-dur-out) var(--rs-ease-in) both; }
.rs-dialog.is-out { animation: rs-pop-out var(--rs-dur-out) var(--rs-ease-in) both; }
.rs-drawer.is-out { animation: rs-panel-out var(--rs-dur-out-panel) var(--rs-ease-in) both; }
.rs-popover.is-out, .rs-menu.is-out { animation: rs-drop-out var(--rs-dur-instant) var(--rs-ease-in) both; }

/* States. Entering a state is faster than leaving it, which makes the cursor feel sticky. */
.rs-nav-item, .rs-menu__item, .rs-tab, .rs-chip, .rs-cal__day, .rs-tree__row,
.rs-cell-edit, .rs-seg__btn, .rs-file, .rs-board__card, .rs-table tbody tr td {
  transition: background-color var(--rs-dur-fast) var(--rs-ease),
              color var(--rs-dur-fast) var(--rs-ease),
              border-color var(--rs-dur-fast) var(--rs-ease),
              box-shadow var(--rs-dur-fast) var(--rs-ease);
}
.rs-nav-item:hover, .rs-menu__item:hover, .rs-chip:hover, .rs-cal__day:hover,
.rs-tree__row:hover, .rs-board__card:hover, .rs-table tbody tr:hover td {
  transition-duration: var(--rs-dur-instant);
}
.rs-btn { transition: background-color var(--rs-dur-instant) var(--rs-ease), border-color var(--rs-dur-instant) var(--rs-ease), color var(--rs-dur-instant) var(--rs-ease), box-shadow var(--rs-dur-fast) var(--rs-ease), transform var(--rs-dur-instant) var(--rs-ease); }
.rs-btn:active, .rs-chip:active, .rs-seg__btn:active { transform: scale(0.985); }
.rs-meter__fill { transition: width var(--rs-dur-slow) var(--rs-ease-out); }
.rs-step__dot, .rs-step__line { transition: background-color var(--rs-dur) var(--rs-ease-out), border-color var(--rs-dur) var(--rs-ease-out), color var(--rs-dur) var(--rs-ease-out); }
.rs-check, .rs-radio { transition: background-color var(--rs-dur-instant) var(--rs-ease), border-color var(--rs-dur-instant) var(--rs-ease); }
.rs-radio.is-on::after { animation: rs-pop var(--rs-dur-instant) var(--rs-ease-out) both; }
.rs-switch { transition: background-color var(--rs-dur-fast) var(--rs-ease); }
.rs-switch::after { transition: transform var(--rs-dur-fast) var(--rs-ease-out); }
.rs-badge { transition: background-color var(--rs-dur) var(--rs-ease), color var(--rs-dur) var(--rs-ease); }

/* Infinite animation is only for live data */
.rs-live { animation: rs-pulse 2.4s var(--rs-ease) infinite; }
.rs-progress { height: 2px; background: var(--rs-surface-3); overflow: hidden; border-radius: 1px; }
.rs-progress__bar { height: 2px; width: 32%; border-radius: 1px; background: var(--rs-accent-500); animation: rs-track 1.4s var(--rs-ease) infinite; }
.rs-skeleton::after { animation-duration: 1.6s; }

/* Form error: a decaying nudge, once per submit */
.rs-shake { animation: rs-nudge var(--rs-dur-slow) var(--rs-ease) both; }

/* Chart bars grow from the bottom */
.rs-grow { transform-origin: bottom; animation: rs-bar var(--rs-dur-slow) var(--rs-ease-out) both; }

/* Demo: plays when the whole card is hovered */
.rs-demo__stage { position: relative; overflow: hidden; }
.rs-demo:hover .rs-demo__obj { animation: var(--rs-demo-anim, rs-rise) var(--rs-demo-dur, var(--rs-dur)) var(--rs-ease-out) both; }
.rs-demo-stagger-card:hover .rs-demo-stagger > * { animation: rs-rise var(--rs-dur) var(--rs-ease-out) both; }
.rs-demo-stagger-card:hover .rs-demo-stagger > *:nth-child(2) { animation-delay: 45ms; }
.rs-demo-stagger-card:hover .rs-demo-stagger > *:nth-child(3) { animation-delay: 90ms; }
.rs-demo-stagger-card:hover .rs-demo-stagger > *:nth-child(4) { animation-delay: 135ms; }
.rs-demo-shake:hover .rs-input { animation: rs-nudge var(--rs-dur-slow) var(--rs-ease) both; }

/* --- Right to left -------------------------------------------
   Mirrored by overriding the handful of rules that carry a direction, not by
   moving the whole file to logical properties: those start at Chrome 89 and
   Safari 15, and would push the support floor past what the README promises —
   and past what rostra.legacy.css can express at all. Everything else is
   flexbox, which flips on its own.

   Worth revisiting the day the floor rises past Safari 15 for another
   reason: then logical properties cost nothing and this block goes away. */
[dir='rtl'] .rs-select { padding-right: 11px; padding-left: 30px; }
[dir='rtl'] .rs-table th { text-align: right; }
[dir='rtl'] .rs-table .rs-num { text-align: left; }
[dir='rtl'] .rs-table--sticky th:first-child, [dir='rtl'] .rs-table--sticky td:first-child { left: auto; right: 0; }
[dir='rtl'] .rs-table--sticky th:first-child::after, [dir='rtl'] .rs-table--sticky td:first-child::after { right: auto; left: 0; }
[dir='rtl'] .rs-layer--right { right: auto; left: 0; }
[dir='rtl'] .rs-drawer { border-left: 0; border-right: 1px solid var(--rs-border); }
[dir='rtl'] .rs-toast-viewport { right: auto; left: var(--rs-space-4); }
[dir='rtl'] .rs-shell__side { border-right: 0; border-left: 1px solid var(--rs-hairline); }
[dir='rtl'] .rs-rail { border-right: 0; border-left: 1px solid var(--rs-hairline); }
[dir='rtl'] .rs-push, [dir='rtl'] .rs-menu__hint { margin-left: 0; margin-right: auto; }
[dir='rtl'] .rs-board__count { margin-left: 0; margin-right: auto; }
[dir='rtl'] .rs-tree__kids { margin-left: 0; margin-right: 17px; padding-left: 0; padding-right: 13px; border-left: 0; border-right: 1px solid var(--rs-hairline); }
[dir='rtl'] .rs-timeline__when { text-align: left; }
[dir='rtl'] .rs-stack .rs-avatar { margin-left: 0; margin-right: -5px; padding-right: 0; padding-left: 2px; }
[dir='rtl'] .rs-stack .rs-avatar:first-child { margin-right: 0; }
[dir='rtl'] .rs-md ul, [dir='rtl'] .rs-md ol { padding-left: 0; padding-right: 20px; }
[dir='rtl'] .rs-md ul { padding-right: 15px; }
[dir='rtl'] .rs-md ul li::before { left: auto; right: -15px; }
[dir='rtl'] .rs-md blockquote { padding-left: 0; padding-right: 15px; border-left: 0; border-right: 2px solid var(--rs-border); }
/* Our own glyphs: the month chevrons and the tree's collapsed arrow point
   along the reading direction. The expanded arrow and the checkmark are
   symmetric, so flipping them changes nothing. */
[dir='rtl'] .rs-cal__head .rs-btn--icon, [dir='rtl'] .rs-tree__toggle { transform: scaleX(-1); }
/* The switch knob travels the other way, and the checkmark is not mirrored:
   a tick reads the same in both directions. */
[dir='rtl'] .rs-switch.is-on::after, [dir='rtl'] .rs-choice__input:checked + .rs-switch::after { transform: translateX(-14px); }
