/* ══════════════════════════════════════════════════════════════════════════
   Hệ thiết kế — design system for the committee's work-management system,
   built for calm, high-density public-sector work.

   What that language actually is, as a set of decisions:
     · one strong accent (#3370FF) and nothing else loud — every other hue is
       reserved for a state, never for decoration
     · calm navy chrome around a bright work canvas
     · royal blue for navigation and action, with teal/amber/red reserved for
       semantic status
     · restrained elevation and fewer framing borders
     · 8–12px surfaces and an optional compact density on large screens
     · near-black text at #1F2329 rather than pure black, with a three-step
       quiet scale below it

   Provenance, stated plainly: the token values below are Lark/Feishu's
   published design-language values. They were cross-checked against the one
   ByteDance token table that could be read from a primary source in this
   session — Semi Design's palette (Blue 5 rgb(0,100,250), Grey 9
   rgb(28,31,35), Grey 5 rgb(107,112,117)) — which sits in the same family and
   agrees on the shape of the scales, not on the exact steps. Verify against
   Lark's own design documentation before this ships to the committee.

   Everything downstream reads the SEMANTIC names in the second block. The
   ramps in the first block exist to be pointed at, not used directly: that
   is what makes a theme swap a change to one file.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── ramps ──────────────────────────────────────────────────────────────
     Lark's neutrals carry a faint blue cast, which is what keeps them from
     going muddy beside the accent. The 600 step of any signal hue carries
     white text; the 50/800 pair makes a readable quiet badge. */

  --n-0:   #ffffff;
  --n-50:  #f4f7fb;
  --n-100: #eaf0f6;
  --n-200: #d8e1eb;
  --n-300: #c4cfdb;
  --n-400: #a4b0bf;
  --n-500: #7c8999;
  --n-600: #5c6877;
  --n-700: #435064;
  --n-800: #29374a;
  --n-900: #172437;
  --n-950: #0b1b31;

  --blue-50:  #f0f4ff;
  --blue-100: #e1eaff;
  --blue-200: #c2d3ff;
  --blue-300: #a0bcff;
  --blue-400: #7ba1ff;
  --blue-500: #4e83fd;
  --blue-600: #3370ff;   /* the Lark blue — 4.55:1 with white */
  --blue-700: #245bdb;   /* hover */
  --blue-800: #1c4cbf;   /* active */
  --blue-900: #133c9a;

  --navy-700: #173a67;
  --navy-800: #102f56;
  --navy-900: #0d2849;
  --navy-950: #091f39;

  --red-50:  #fef0ef;
  --red-100: #fde2e2;
  --red-200: #fbc4c4;
  --red-500: #f76965;
  --red-600: #f54a45;
  --red-700: #d83931;
  --red-800: #a92721;

  --amber-50:  #fff8e6;
  --amber-100: #ffefc7;
  --amber-200: #ffdd8a;
  --amber-500: #ffa53d;
  --amber-600: #ff8800;
  --amber-700: #d97400;
  --amber-800: #8f4700;

  --teal-50:  #edfafa;
  --teal-100: #d2f2f0;
  --teal-200: #9fe2dd;
  --teal-500: #20a89f;
  --teal-600: #0f8f87;
  --teal-700: #0b746e;
  --teal-800: #075a56;
  /* Legacy aliases; existing routes migrate to semantic on-track in Phase 03/04. */
  --green-50: var(--teal-50);
  --green-100: var(--teal-100);
  --green-200: var(--teal-200);
  --green-500: var(--teal-500);
  --green-600: var(--teal-600);
  --green-700: var(--teal-700);
  --green-800: var(--teal-800);

  /* ── semantic surfaces ─────────────────────────────────────────────────
     A canvas the panels sit on, and the panels themselves. The old system
     had one ground and hairlines; this one separates by elevation. */

  --canvas: var(--n-50);
  --surface: var(--n-0);
  --surface-sunken: #f8fafc;
  --surface-raised: var(--n-0);
  --surface-hover: var(--n-50);
  --surface-active: var(--n-100);
  --surface-selected: var(--blue-50);

  --border: var(--n-200);
  --border-strong: var(--n-300);
  --border-selected: var(--blue-600);

  /* ── semantic ink ──────────────────────────────────────────────────────
     Measured on --surface (white): n-900 → 15.9:1, n-600 → 5.6:1,
     n-500 → 3.2:1. n-500 is Lark's placeholder grey and is therefore used
     ONLY for placeholder text, which WCAG does not hold to 4.5:1; anything
     that carries meaning uses --ink-subtle (n-600) or darker. */

  --ink: var(--n-900);
  --ink-muted: var(--n-600);        /* 5.6:1 */
  --ink-subtle: var(--n-600);       /* the floor for meaningful text */
  --ink-placeholder: var(--n-500);  /* placeholder only */
  --ink-disabled: var(--n-400);
  --ink-on-fill: var(--n-0);

  --ink-primary: var(--blue-800);
  /* red-700 measures 4.62:1 on white but only 4.29:1 on the grey canvas, and
     alert text is read on both grounds. One step darker clears each. */
  --ink-danger: var(--red-800);     /* 7.0:1 on white, 6.5:1 on the canvas */
  --ink-warning: var(--amber-800);  /* 6.8:1 */
  --ink-success: var(--teal-800);

  /* Lark's own #3370FF measures 4.25:1 against white — a shade under the
     4.5:1 bar for the 13px labels these fills carry. The fill is therefore
     one step darker (#245BDB, 5.8:1) while #3370FF stays the brand hue
     everywhere it does not sit behind small text: tints, borders, icons,
     the selected pill. One deviation, made deliberately, recorded here. */
  --fill-primary: #1f5fbf;
  --fill-primary-hover: #184f9f;
  --fill-primary-active: #123f80;
  --brand: var(--blue-600);
  --fill-danger: var(--red-700);
  --fill-danger-hover: var(--red-800);

  /* ── the rail ──────────────────────────────────────────────────────────
     Navy chrome keeps global navigation distinct from the white work canvas.
     Current position uses a lighter navy surface plus the blue brand mark. */

  --rail-bg: var(--navy-950);
  --rail-bg-hover: var(--navy-800);
  --rail-bg-active: #173f70;
  --rail-ink: #e5edf7;
  --rail-ink-quiet: #aebed2;
  --rail-ink-active: #ffffff;
  --rail-border: #254361;

  /* ── type ──────────────────────────────────────────────────────────────
     Be Vietnam Pro is drawn for Vietnamese: the stacked diacritics on ế, ộ,
     ữ are designed rather than auto-composed, which is what keeps a dense
     13px table legible. A generic sans stack stands behind it. */

  --font: 'Be Vietnam Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
          Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;

  /* ── density ───────────────────────────────────────────────────────────
     Comfortable is the default. Lark's own scale (14px body, 32px controls)
     is a compact mode: correct for a clerk on a big monitor working a queue
     all day, tiring for everyone else reading long Vietnamese sentences at
     12–13px. So the comfortable scale ships, and `data-density="compact"`
     on <html> restores the tight one for the people who want it. Every size
     and control height below is a token, which is what makes that a
     seven-line override rather than a second stylesheet. */

  --text-2xs: 13px;
  --text-xs:  13px;   /* metadata floor */
  --text-sm:  14px;
  --text-md:  15px;   /* body */
  --text-lg:  17px;
  --text-xl:  19px;
  --text-2xl: 22px;
  --text-3xl: 26px;
  --text-4xl: 32px;

  --control-h: 36px;
  --control-h-sm: 30px;
  --input-h: 38px;
  --row-py: 14px;     /* list rows land at 56px with a two-line cell */

  --leading-tight: 1.3;
  --leading-snug: 1.45;
  --leading: 1.6;

  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* ── space — a 4px grid, named by step ─────────────────────────────── */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 20px;
  --s-6: 24px;
  --s-8: 32px;
  --s-10: 40px;
  --s-12: 48px;
  --s-16: 64px;

  /* ── shape — restrained 8–12px work surfaces ───────────────────────── */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-xl: 12px;
  --radius-full: 9999px;

  /* ── elevation ─────────────────────────────────────────────────────────
     Surfaces use a soft edge shadow; stronger shadows remain for floating
     controls, sheets, and toasts. */
  --shadow-xs: 0 1px 2px rgb(9 31 57 / 0.06);
  --shadow-sm: 0 1px 3px rgb(31 35 41 / 0.06);
  --shadow-md: 0 4px 12px rgb(31 35 41 / 0.09);
  --shadow-lg: 0 6px 24px rgb(31 35 41 / 0.14);
  --ring: 0 0 0 3px rgb(51 112 255 / 0.2);

  /* ── motion — one pair of durations, one curve ─────────────────────── */
  --dur-fast: 120ms;
  --dur: 180ms;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  --z-rail: 20;
  --z-header: 30;
  --z-sheet: 50;
  --z-toast: 60;
}

/* Compact — the density this system started at. For a văn thư working a queue
   on a large monitor, where seeing twelve rows at once beats reading comfort. */
:root[data-density='compact'] {
  --text-2xs: 13px;
  --text-xs:  13px;
  --text-sm:  14px;
  --text-md:  14px;
  --text-lg:  16px;
  --text-xl:  18px;
  --text-2xl: 20px;
  --text-3xl: 24px;
  --text-4xl: 30px;

  --control-h: 32px;
  --control-h-sm: 26px;
  --input-h: 32px;
  --row-py: 10px;

  --leading: 1.5715;
}

/* Touch is never compact: a thumb needs its 44px whatever the setting says. */
@media (pointer: coarse) {
  :root, :root[data-density='compact'] {
    --text-2xs: 13px;
    --text-xs: 13px;
    --control-h: 44px;
    --control-h-sm: 44px;
    --input-h: 44px;
    --row-py: 14px;
  }
}

@media (max-width: 900px) {
  :root, :root[data-density='compact'] {
    --text-2xs: 13px;
    --text-xs: 13px;
    --text-sm: 14px;
    --text-md: 15px;
    --control-h: 44px;
    --control-h-sm: 44px;
    --input-h: 44px;
    --row-py: 14px;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   Base
   ══════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--text-md);
  line-height: var(--leading);
  font-weight: var(--weight-normal);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: -0.011em;
}
h1 { font-size: var(--text-3xl); letter-spacing: -0.02em; }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
h4 { font-size: var(--text-md); }

p { margin: 0; }
img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }
button, a, select, input, textarea { touch-action: manipulation; }

a {
  color: var(--ink-primary);
  text-decoration: none;
  text-underline-offset: 2px;
  border-radius: var(--radius-sm);
}
a:hover { text-decoration: underline; }

/* Focus is never removed — only replaced with a ring that reads on any
   surface, including the dark rail. */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--fill-primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.rail :focus-visible { outline-color: #9fc3ff; }

::selection { background: var(--blue-100); }

/* Figures line up. Be Vietnam Pro carries tabular figures; where it does
   not the fallback stack does, and either way the request is harmless. */
.tnum, table, .metric, [class*='-count'], [class*='-num'], [class*='-pct'],
[class*='-date'], [class*='-due'], [class*='-time'] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ══════════════════════════════════════════════════════════════════════════
   Accessibility utilities
   ══════════════════════════════════════════════════════════════════════ */

/* Visible only to assistive technology. Used for live-region announcements
   and for labels a sighted user reads from position instead of words. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* First tab stop on the page. Ten tab stops of navigation used to stand
   between a keyboard user and the work; this is the way past them. */
.skip-link {
  position: fixed; top: var(--s-3); left: var(--s-3); z-index: 100;
  padding: var(--s-3) var(--s-5);
  background: var(--fill-primary); color: var(--ink-on-fill);
  font-weight: var(--weight-semibold); border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  transform: translateY(calc(-100% - var(--s-4)));
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus-visible { transform: translateY(0); text-decoration: none; }

/* ══════════════════════════════════════════════════════════════════════════
   Buttons
   ══════════════════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-2);
  min-height: var(--control-h); padding: 6px var(--s-4);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  line-height: 1.2; white-space: nowrap;
  background: transparent; color: var(--ink);
  border: 1px solid transparent; border-radius: var(--radius-md);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
.btn svg { width: 16px; height: 16px; flex: none; }

.btn-primary {
  background: var(--fill-primary); color: var(--ink-on-fill);
  box-shadow: var(--shadow-xs);
}
.btn-primary:hover { background: var(--fill-primary-hover); }
.btn-primary:active { background: var(--fill-primary-active); }

.btn-secondary {
  background: var(--surface); color: var(--ink);
  border-color: var(--border-strong); box-shadow: var(--shadow-xs);
}
.btn-secondary:hover { background: var(--surface-hover); border-color: var(--n-400); }
.btn-secondary:active { background: var(--surface-active); }

.btn-ghost { color: var(--ink-muted); }
.btn-ghost:hover { background: var(--surface-active); color: var(--ink); }

/* The link variant carries sentence-length labels, so unlike every other
   button it wraps rather than running off the side of a phone. */
.btn-link {
  padding: 0; min-height: 0; color: var(--ink-primary);
  font-weight: var(--weight-medium);
  white-space: normal; text-align: left; align-items: flex-start;
}
.btn-link svg { margin-top: 3px; }
.btn-link:hover { text-decoration: underline; }

.btn-danger { background: var(--fill-danger); color: var(--ink-on-fill); }
.btn-danger:hover { background: var(--fill-danger-hover); }

.btn-sm { min-height: var(--control-h-sm); padding: var(--s-1) var(--s-3); font-size: var(--text-xs); }
.btn-icon { width: var(--control-h); min-height: var(--control-h); padding: 0; }

/* Disabled says so to the pointer, the eye and the accessibility tree. */
.btn:disabled, .btn[aria-disabled='true'] {
  opacity: 0.45; cursor: not-allowed; box-shadow: none;
}

/* ══════════════════════════════════════════════════════════════════════════
   Fields
   ══════════════════════════════════════════════════════════════════════ */

.field { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
.field-label {
  font-size: var(--text-xs); font-weight: var(--weight-medium);
  color: var(--ink-muted);
}
/* Required is marked in the label, and the input carries `required` so the
   platform states it too — the asterisk alone is decoration. */
.field-label .req { color: var(--ink-danger); margin-left: 2px; }

.input {
  width: 100%; min-height: var(--input-h); padding: 6px var(--s-3);
  font: inherit; font-size: var(--text-md); color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
.input::placeholder { color: var(--ink-placeholder); opacity: 1; }
.input:hover { border-color: var(--n-400); }
.input:focus-visible {
  outline: none; border-color: var(--fill-primary); box-shadow: var(--ring);
}
textarea.input { min-height: 80px; resize: vertical; line-height: var(--leading); }

/* A field the platform should treat as suspect: flagged, not merely tinted. */
.input[aria-invalid='true'] { border-color: var(--fill-danger); }
.input[aria-invalid='true']:focus-visible { box-shadow: 0 0 0 3px rgb(220 38 38 / 0.22); }

/* Helper and error text. Both are wired to the input with aria-describedby by
   the caller, so a screen reader hears them as part of the field. */
.field-help { font-size: var(--text-xs); color: var(--ink-subtle); }
.field-warn {
  display: flex; align-items: center; gap: var(--s-1);
  font-size: var(--text-xs); color: var(--ink-warning);
  font-weight: var(--weight-medium);
}
.field-warn svg { width: 13px; height: 13px; flex: none; }

/* A select with appearance:none and nothing in its place is a text field as far
   as the eye is concerned. The chevron is drawn in the background so a select
   needs no wrapper element to be recognisable. */
select.input {
  appearance: none; padding-right: var(--s-8); cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23646a73' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-3) center;
  background-size: 15px 15px;
}
select.input:disabled { cursor: not-allowed; }

/* ══════════════════════════════════════════════════════════════════════════
   Segmented control — native radios underneath
   ══════════════════════════════════════════════════════════════════════ */

.seg {
  display: inline-flex; padding: 3px; gap: 2px;
  background: var(--n-100); border-radius: var(--radius-md);
}
.seg-opt {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: var(--control-h-sm); padding: 0 var(--s-3);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--ink-muted); border-radius: var(--radius-sm); cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.seg-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.seg-opt:hover { color: var(--ink); }
.seg-opt:has(input:checked) {
  background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-xs); font-weight: var(--weight-semibold);
}
.seg-opt:has(input:focus-visible) { outline: 2px solid var(--fill-primary); outline-offset: 1px; }

/* ══════════════════════════════════════════════════════════════════════════
   Filter chips
   ══════════════════════════════════════════════════════════════════════ */

.chip {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: var(--control-h); padding: 0 var(--s-4);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--ink-muted); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-full);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.chip:hover { background: var(--surface-hover); color: var(--ink); border-color: var(--border-strong); }
.chip[aria-pressed='true'] {
  background: var(--fill-primary); border-color: var(--fill-primary); color: var(--ink-on-fill);
}
.chip[aria-pressed='true']:hover { background: var(--fill-primary-hover); border-color: var(--fill-primary-hover); }

/* ══════════════════════════════════════════════════════════════════════════
   Badges — status carries a dot as well as a hue, so the state survives
   greyscale, print and colour-blind vision.
   ══════════════════════════════════════════════════════════════════════ */

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px var(--s-2);
  font-size: var(--text-xs); font-weight: var(--weight-medium);
  line-height: 1.35; white-space: nowrap;
  border-radius: var(--radius-full);
  background: var(--n-100); color: var(--n-700);
}
.badge::before {
  content: ''; width: 6px; height: 6px; flex: none;
  border-radius: var(--radius-full); background: currentColor; opacity: 0.75;
}
.badge--plain::before { display: none; }

.badge--info    { background: var(--blue-50);  color: var(--blue-800); }
.badge--danger  { background: var(--red-50);   color: var(--red-800); }
.badge--warning { background: var(--amber-50); color: var(--amber-800); }
.badge--success { background: var(--teal-50); color: var(--teal-800); }
.badge--neutral { background: var(--n-100);    color: var(--n-700); }

/* The badge's own shape changes for the two states that must never be missed. */
.badge--danger::before { border-radius: 1px; transform: rotate(45deg); }
.badge--success::before { border-radius: var(--radius-full); }

/* ══════════════════════════════════════════════════════════════════════════
   Cards and panels
   ══════════════════════════════════════════════════════════════════════ */

.card {
  background: var(--surface-raised);
  border: 1px solid transparent;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.card-head {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--n-100);
}
.card-title { font-size: var(--text-lg); font-weight: var(--weight-semibold); }
.card-body { padding: var(--s-5); }
.card-body--flush { padding: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   Meters
   ══════════════════════════════════════════════════════════════════════ */

.meter {
  position: relative; display: block; flex: 1;
  height: 8px; min-width: 60px;
  background: var(--n-200); border-radius: var(--radius-full); overflow: hidden;
}
.meter-fill {
  display: block; height: 100%; border-radius: var(--radius-full);
  background: var(--blue-500);
  transition: width var(--dur) var(--ease);
}
.meter-fill--over { background: var(--red-500); }
.meter-fill--warn { background: var(--amber-500); }
.meter-fill--done { background: var(--teal-500); }
/* The 100% mark, so a bar clamped at the brim still shows where the line is. */
.meter--capped::after {
  content: ''; position: absolute; inset-block: -2px; right: 0; width: 2px;
  background: var(--n-500); border-radius: 1px;
}

/* ══════════════════════════════════════════════════════════════════════════
   Skeletons
   ══════════════════════════════════════════════════════════════════════ */

.sk {
  display: block; border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--n-200) 25%, var(--n-100) 50%, var(--n-200) 75%);
  background-size: 200% 100%;
  animation: sk-sweep 1.4s ease-in-out infinite;
}
@keyframes sk-sweep { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) {
  .sk { animation: none; background: var(--n-200); }
  *, *::before, *::after {
    animation-duration: 1ms !important; animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   Toast — the live region's visible half
   ══════════════════════════════════════════════════════════════════════ */

.toast-region {
  position: fixed; right: var(--s-5); bottom: var(--s-5); z-index: var(--z-toast);
  display: flex; flex-direction: column; gap: var(--s-2);
  pointer-events: none;
}
.toast {
  display: flex; align-items: flex-start; gap: var(--s-3);
  max-width: 380px; padding: var(--s-3) var(--s-4);
  background: var(--n-900); color: var(--n-0);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  font-size: var(--text-sm); line-height: var(--leading-snug);
  animation: toast-in var(--dur) var(--ease) both;
}
.toast svg { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.toast--success svg { color: var(--teal-500); }
.toast--danger svg { color: var(--red-500); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
