/* ============================================================
 * Universal Colour Relationship Contract · v4
 * ============================================================
 *
 * Spec: docs/reference/UNIVERSAL_COLOUR_RELATIONSHIP_PROPOSAL.md
 * Source: ~/Desktop/ophtho-scribe-claude-ai-design/
 *         Dashboard - Palette Variations (source for bundle).html
 *
 * Architecture
 * ------------
 * Every visible colour slot in the app is a *stable formula* over a
 * fixed set of 13 palette-authored input tokens plus 3 platform
 * constants. Switching the brand swatch swaps the 16 tokens; every
 * --app-*, --ds-*, and (future) --widget-* output recomputes in one
 * paint — no per-palette component overrides exist anywhere.
 *
 * This file defines tokens only. Components consume them via their
 * own selectors in component-appearance.css and app-shell-tone.css.
 *
 * Activate a brand swatch by setting data-palette on <html>:
 *
 *   <html data-palette="terracotta">  (default — no attribute needed)
 *   <html data-palette="sage-clinic">
 *   <html data-palette="ink-copper">
 *   <html data-palette="mulberry">
 *
 * Adding a new brand swatch
 * -------------------------
 * Author all 13 palette-input tokens. Do NOT derive any of them via
 * color-mix() — the design system intentionally exposes per-palette
 * control over warmth, contrast, and state harmonisation. Do NOT add
 * per-palette overrides for any component selector — every slot is a
 * formula over these tokens.
 *
 *   Neutrals (5):  --paper, --surface, --ink, --muted, --faint
 *   Rules    (2):  --line, --line-soft
 *   Accent   (3):  --accent, --accent-soft, --accent-ink
 *   State    (3):  --success, --warning, --info
 *
 * Lightness ladder for the neutrals: surface ≈ L* 95, paper ≈ L* 91,
 * line ≈ L* 86, line-soft ≈ L* 90, faint ≈ L* 66, muted ≈ L* 49,
 * ink ≈ L* 10–14. Paper must be visibly darker than surface; line
 * darker than line-soft; muted darker than faint.
 *
 * Mix space: srgb (matches the design source). All component formulas
 * use color-mix(in srgb, …).
 * ============================================================ */


/* ──────────────────────────────────────────────────────────────
 * BRAND PALETTES — 4 authored swatches
 * Source: ~/Desktop/ophtho-scribe-claude-ai-design/Dashboard - Palette Variations (source for bundle).html
 * Lines 32–58 in source; copied byte-for-byte below.
 * ────────────────────────────────────────────────────────────── */

:root,
:root[data-palette="terracotta"] {
  /* Source: claude.ai/design bundle JMXAOcBVGbdZsS6rz0xI8w
   * (project/dist/ophthoscribe-tokens.css — archived design preview, comp 39). */
  --paper:        #FAF6EC;
  --paper-2:      #FDFAF2;
  --surface:      #FFFFFF;
  --ink:          #1F1B16;
  --muted:        #7A6D5C;
  --faint:        #A89782;
  --line:         #E6DCC7;
  --line-soft:    #EFE6D2;
  --line-strong:  #CDBFA7;
  --accent:       #C2553A;
  --accent-soft:  #F1DED4;
  --accent-ink:   #8E3A26;
  --success:      #4B7A5B;
  --success-soft: #E5EFE6;
  --warning:      #A57225;
  --warning-soft: #F3E8D3;
  --danger:       #A4443D;
  --danger-soft:  #F1DDDD;
  --info:         #3D5F87;
}

:root[data-palette="sage"],
:root[data-palette="sage-clinic"] {
  --paper:        #F1EFE6;
  --surface:      #F7F5EC;
  --ink:          #1C1F1B;
  --muted:        #6D7569;
  --faint:        #A6AC9F;
  --line:         #DEDDD0;
  --line-soft:    #E8E6D8;
  --accent:       #5C7A5B;
  --accent-soft:  #E0E7DA;
  --accent-ink:   #3F5A40;
  --success:      #5C7A5B;
  --warning:      #A26B2A;
  --info:         #3B6491;
}

:root[data-palette="ink-copper"] {
  --paper:        #F0EBE1;
  --surface:      #F7F2E8;
  --ink:          #1A2230;
  --muted:        #6E695A;
  --faint:        #A89C83;
  --line:         #DDD5C5;
  --line-soft:    #E7DFCF;
  --accent:       #9C5A2D;
  --accent-soft:  #EFDDC8;
  --accent-ink:   #6F3D17;
  --success:      #3D6A55;
  --warning:      #9C5E1D;
  --info:         #2A4A7A;
}

:root[data-palette="mulberry"] {
  --paper:        #F1EBE1;
  --surface:      #F7F2E9;
  --ink:          #211A1E;
  --muted:        #6E5F62;
  --faint:        #A89AA0;
  --line:         #E2D6CB;
  --line-soft:    #ECDFD4;
  --accent:       #7D3A4A;
  --accent-soft:  #EDD9DC;
  --accent-ink:   #5A2434;
  --success:      #5C7A5B;
  --warning:      #A06A2A;
  --info:         #46517F;
}


/* ──────────────────────────────────────────────────────────────
 * PLATFORM CONSTANTS — palette-invariant
 * Used for slots whose semantic colour should NOT change with brand
 * (no-show neutrality, destructive actions, fixed status/action colours).
 * ────────────────────────────────────────────────────────────── */

:root {
  --state-neutral:  #7A7567;   /* No-show / disabled */
  --state-danger:   #B33A2E;   /* Destructive (× delete hover only) */
  --state-followup: #3D5F87;   /* Book / follow-up action, fixed from dashboard reference */
  --state-testing:  #A8872D;   /* Testing status, fixed calm yellow */
  --state-inroom:   #2F7C8A;   /* Being Seen status, fixed clinical teal */
}


/* ──────────────────────────────────────────────────────────────
 * APP-SHELL OUTPUT TOKENS — global chrome above every workspace
 * Prefix: --app-*
 * ────────────────────────────────────────────────────────────── */

:root {

  /* Page (outermost background) */
  --app-page-bg:                 var(--paper);
  --app-page-text:               var(--ink);
  --app-page-muted-text:         var(--muted);
  --app-page-faint-text:         var(--faint);

  /* Top workspace navigation band
   * (Workspace · Customize · Migrate · Encounter View) */
  --app-top-nav-bg:              color-mix(in srgb, var(--ink) 5%, var(--paper));
  --app-top-nav-rule:            color-mix(in srgb, var(--ink) 10%, transparent);
  --app-top-nav-text:            color-mix(in srgb, var(--ink) 60%, transparent);
  --app-top-nav-active-text:     var(--ink);
  --app-top-nav-active-bg:       color-mix(in srgb, var(--ink) 6%, transparent);

  /* Logo lockup */
  --app-logo-mark:               var(--ink);
  --app-logo-pupil:              var(--accent);
  --app-logo-word-primary:       var(--accent);   /* "Ophtho" */
  --app-logo-word-secondary:     var(--ink);      /* "Scribe" */
  --app-logo-separator:          color-mix(in srgb, var(--ink) 18%, transparent);

  /* Fixed dark top-right action
   * (Logout · Save & Return · Exit · also aliased by + Add Patient) */
  --app-top-action-bg:           var(--ink);
  --app-top-action-text:         var(--paper);
  --app-top-action-border:       var(--ink);
  --app-top-action-hover-bg:     color-mix(in srgb, var(--ink) 90%, var(--surface));

  /* Workspace sub-nav band
   * (Dashboard · Inbox · Wait Lists · Billing). Sub-nav sits on paper,
   * not surface — verified in source line 127. */
  --app-subnav-bg:               var(--paper);
  --app-subnav-rule:             color-mix(in srgb, var(--ink) 8%, transparent);
  --app-subnav-text:             color-mix(in srgb, var(--ink) 55%, transparent);
  --app-subnav-active-text:      var(--accent);
  --app-subnav-active-rule:      var(--accent);
  --app-subnav-active-bg:        transparent;
}


/* ──────────────────────────────────────────────────────────────
 * DAY-SHEET OUTPUT TOKENS — Dashboard tab content only
 * Prefix: --ds-*
 * All formulas verified against the palette-variations source.
 * ────────────────────────────────────────────────────────────── */

:root {

  /* Page header band — Dashboard h1 + date + Add Patient.
   * Sits on the paper background, not a separate band. */
  --ds-page-header-bg:           var(--paper);
  --ds-page-header-rule:         transparent;
  --ds-title-text:               var(--ink);
  --ds-date-text:                var(--muted);

  /* + Add Patient pill — aliased to --app-top-action-* (solid ink). */
  --ds-add-action-bg:            var(--app-top-action-bg);
  --ds-add-action-text:          var(--app-top-action-text);
  --ds-add-action-border:        var(--app-top-action-border);
  --ds-add-action-hover-bg:      var(--app-top-action-hover-bg);

  /* Day-sheet card frame */
  --ds-card-bg:                  var(--surface);
  --ds-card-border:              color-mix(in srgb, var(--ink) 8%, transparent);

  /* Table column-header band
   * (TIME · PATIENT · STATUS · APPOINTMENT & REASON · …) */
  --ds-table-header-bg:          color-mix(in srgb, var(--ink) 3%, var(--surface));
  --ds-table-header-text:        var(--muted);
  --ds-table-header-rule:        color-mix(in srgb, var(--ink) 10%, transparent);

  /* Table rows */
  --ds-row-bg:                   var(--surface);
  --ds-row-text:                 var(--ink);
  --ds-row-muted-text:           var(--muted);
  --ds-row-faint-text:           var(--faint);
  --ds-row-rule:                 var(--line-soft);
  --ds-row-hover-bg:             color-mix(in srgb, var(--accent-soft) 50%, var(--surface));
  --ds-row-selected-bg:          var(--accent-soft);

  /* PIN / VISIT metadata beneath patient name */
  --ds-meta-label-text:          var(--muted);
  --ds-meta-value-text:          var(--ink);

  /* Time cell — "8:30" + "am" */
  --ds-time-hour-text:           var(--ink);
  --ds-time-period-text:         var(--muted);

  /* Appointment-type pill — GENERAL CONSULT · FOLLOW-UP · POST-OP.
   * Accent-soft bg + accent-INK text (darker variant) for contrast. */
  --ds-type-pill-bg:             var(--accent-soft);
  --ds-type-pill-text:           var(--accent-ink);

  /* Testing chips — HVF 24-2, OCT Mac, Optos, … */
  --ds-test-chip-bg:             color-mix(in srgb, var(--ink) 5%, var(--surface));
  --ds-test-chip-text:           var(--ink);
  --ds-test-chip-border:         transparent;

  /* "None" / "—" placeholder in the testing column */
  --ds-test-empty-text:          var(--faint);


  /* ── Status pills ─────────────────────────────────────────────
   * Anatomy: state-tinted bg + state text + state dot.
   * Checked-in uses the fixed follow-up navy; Testing uses a fixed
   * calm yellow; Being Seen uses a fixed clinical teal; the
   * remaining active states use the palette-authored state hues;
   * no-show uses the neutral
   * ink-mute family.
   * ───────────────────────────────────────────────────────── */

  --ds-status-checkedin-bg:      color-mix(in srgb, var(--state-followup) 14%, var(--surface));
  --ds-status-checkedin-text:    var(--state-followup);
  --ds-status-checkedin-dot:     var(--state-followup);

  --ds-status-testing-bg:        color-mix(in srgb, var(--state-testing) 16%, var(--surface));
  --ds-status-testing-text:      var(--state-testing);
  --ds-status-testing-dot:       var(--state-testing);

  --ds-status-inroom-bg:         color-mix(in srgb, var(--state-inroom) 14%, var(--surface));
  --ds-status-inroom-text:       var(--state-inroom);
  --ds-status-inroom-dot:        var(--state-inroom);

  --ds-status-complete-bg:       color-mix(in srgb, var(--success) 14%, var(--surface));
  --ds-status-complete-text:     var(--success);
  --ds-status-complete-dot:      var(--success);

  --ds-status-noshow-bg:         color-mix(in srgb, var(--ink) 6%, var(--surface));
  --ds-status-noshow-text:       var(--muted);
  --ds-status-noshow-dot:        var(--faint);

  /* Status "empty" (no status assigned yet) — same family as no-show. */
  --ds-status-empty-bg:          color-mix(in srgb, var(--ink) 6%, var(--surface));
  --ds-status-empty-text:        var(--faint);
  --ds-status-empty-dot:         var(--faint);


  /* ── Task chips (SURV · FILES · BILL · F/U) ──────────────────
   * STATE-DRIVEN: each appointment-status state has one fixed
   * colour role regardless of which column the chip lives in.
   *
   *   done    ✓  → --success family   (Surv done, Bill submitted, F/U booked)
   *   pending ·  → --warning family   (Bill pending)
   *   sent    ↗  → --accent family    (Surv sent / in-person)
   *   needed  !  → --info family      (F/U needed/pending)
   *   book        → fixed follow-up navy, palette-invariant
   *   add     +  → ink + muted        (Files +, Survey add)
   *   empty   ·  → faint              (any "none" / "—")
   * ───────────────────────────────────────────────────────── */

  --ds-task-done-bg:             color-mix(in srgb, var(--success) 18%, transparent);
  --ds-task-done-text:           var(--success);

  --ds-task-pending-bg:          color-mix(in srgb, var(--warning) 16%, transparent);
  --ds-task-pending-text:        var(--warning);

  --ds-task-sent-bg:             var(--accent-soft);
  --ds-task-sent-text:           var(--accent-ink);

  --ds-task-needed-bg:           color-mix(in srgb, var(--info) 14%, transparent);
  --ds-task-needed-text:         var(--info);

  --ds-followup-book-bg:         color-mix(in srgb, var(--state-followup) 14%, transparent);
  --ds-followup-book-text:       var(--state-followup);

  --ds-task-add-bg:              color-mix(in srgb, var(--ink) 8%, transparent);
  --ds-task-add-text:            var(--muted);
  --ds-task-add-hover-bg:        color-mix(in srgb, var(--accent) 18%, transparent);
  --ds-task-add-hover-text:      var(--accent-ink);

  --ds-task-empty-bg:            color-mix(in srgb, var(--ink) 6%, transparent);
  --ds-task-empty-text:          var(--faint);
  --ds-task-empty-opacity:       0.45;

  --ds-task-caption-text:        var(--faint);


  /* ── Encounter actions ──────────────────────────────────────
   * v4.3: Start moved to the "soft chip + dark text" pattern that
   * the status pills, appt-chip, and task chips already use, so
   * the encounter button joins the chip family visually instead of
   * competing as a solid-colour primary. Hover deepens the tint.
   *
   *   start       — accent-soft bg + accent-ink text (chip family)
   *   resume      — accent solid    ("Resume →" for testing / in-room)
   *   view-note   — accent outlined ("View note" for complete)
   *   reschedule  — aliased to start (for no-show)
   * ───────────────────────────────────────────────────────── */

  --ds-encounter-start-bg:        var(--accent-soft);
  --ds-encounter-start-text:      var(--accent-ink);
  --ds-encounter-start-border:    transparent;
  --ds-encounter-start-hover-bg:  color-mix(in srgb, var(--accent) 22%, var(--surface));

  --ds-encounter-resume-bg:       var(--accent);
  --ds-encounter-resume-text:     var(--surface);
  --ds-encounter-resume-border:   var(--accent);
  --ds-encounter-resume-hover-bg: color-mix(in srgb, var(--accent) 88%, var(--ink));

  --ds-encounter-view-bg:         transparent;
  --ds-encounter-view-text:       var(--accent);
  --ds-encounter-view-border:     color-mix(in srgb, var(--accent) 50%, transparent);
  --ds-encounter-view-hover-bg:   color-mix(in srgb, var(--accent) 8%, transparent);

  --ds-encounter-reschedule-bg:        var(--ds-encounter-start-bg);
  --ds-encounter-reschedule-text:      var(--ds-encounter-start-text);
  --ds-encounter-reschedule-border:    var(--ds-encounter-start-border);
  --ds-encounter-reschedule-hover-bg:  var(--ds-encounter-start-hover-bg);


  /* ── Row icon buttons — shared neutral pair ─────────────────
   * Used by widget cards across the app (inbox, wait-list, etc.)
   * where the edit/delete buttons share a neutral treatment at rest
   * and only the delete adopts --state-danger on hover.
   * ───────────────────────────────────────────────────────── */

  --ds-row-icon-bg:                  transparent;
  --ds-row-icon-text:                var(--muted);
  --ds-row-icon-border:              color-mix(in srgb, var(--ink) 12%, transparent);
  --ds-row-icon-hover-bg:            color-mix(in srgb, var(--ink) 5%, transparent);
  --ds-row-icon-hover-text:          var(--ink);
  --ds-row-icon-danger-hover-bg:     color-mix(in srgb, var(--state-danger) 10%, transparent);
  --ds-row-icon-danger-hover-text:   var(--state-danger);


  /* ── Day-sheet row edit pencil (✎) — neutral soft chip ───────
   * v4.5: gray bg (ink 8% over transparent) + ink-solid glyph.
   * Edit is a utility action, not a brand-primary, so it stays in
   * the neutral chip family — visually deferring to the Start /
   * Resume encounter buttons which carry the accent.
   *
   * The runtime button uses `background` on a ::before pseudo-
   * element to fill the masked glyph, so `--ds-row-edit-glyph`
   * colours the pencil itself, not the button's text colour.
   * ───────────────────────────────────────────────────────── */

  --ds-row-edit-bg:              color-mix(in srgb, var(--ink) 8%, transparent);
  --ds-row-edit-glyph:           var(--ink);
  --ds-row-edit-border:          transparent;
  --ds-row-edit-hover-bg:        color-mix(in srgb, var(--ink) 14%, transparent);
  --ds-row-edit-hover-glyph:     var(--ink);
  --ds-row-edit-hover-border:    transparent;


  /* ── Day-sheet row delete × — Option B: solid ink + danger hover ─
   * At rest: solid ink chip (mirrors the Logout / Add Patient pill
   * dark treatment but at 30px square). On hover: --state-danger.
   * ───────────────────────────────────────────────────────── */

  --ds-row-delete-bg:            var(--ink);
  --ds-row-delete-glyph:         var(--paper);
  --ds-row-delete-border:        var(--ink);
  --ds-row-delete-hover-bg:      var(--state-danger);
  --ds-row-delete-hover-glyph:   var(--paper);
  --ds-row-delete-hover-border:  var(--state-danger);


  /* ── Footer state-summary band ──────────────────────────────
   * "5 TODAY · 1 CHECKED IN · 1 IN ROOM · 1 COMPLETE · 1 NO SHOW"
   * Mirrors the table-header band tint. Total ("5") uses --accent.
   * ───────────────────────────────────────────────────────── */

  --ds-footer-bg:                color-mix(in srgb, var(--ink) 3%, var(--surface));
  --ds-footer-rule:              color-mix(in srgb, var(--ink) 10%, transparent);
  --ds-footer-count-text:        var(--ink);
  --ds-footer-total-text:        var(--accent);
  --ds-footer-label-text:        var(--muted);
  --ds-footer-divider:           color-mix(in srgb, var(--ink) 12%, transparent);
  --ds-footer-add-text:          var(--ink);
  --ds-footer-add-border:        color-mix(in srgb, var(--ink) 22%, transparent);
  --ds-footer-add-hover-bg:      color-mix(in srgb, var(--ink) 5%, transparent);


  /* ── Workspace-card chrome — Inbox / Wait Lists / Billing ────
   * Cards in workspace tabs reuse most of the day-sheet contract
   * (card frame, header band, count badge, row anatomy, meta text)
   * via the tokens already defined above. The slots below add
   * inbox-specific affordances that don't appear on the day sheet:
   * outlined-light action buttons (View / Book / Reject / Include /
   * Exclude), solid state-changing actions (Finalize), and text inputs
   * (Booking Notes textarea).
   * ───────────────────────────────────────────────────────── */

  /* Card-level action button (outlined-light neutral pill).
   * All inbox row-action buttons share this treatment at rest;
   * destructive intent can be revealed on hover by adopting
   * --state-danger via the danger-hover variant below. */
  --ds-card-action-bg:               transparent;
  --ds-card-action-text:             var(--ink);
  --ds-card-action-border:           color-mix(in srgb, var(--ink) 22%, transparent);
  --ds-card-action-hover-bg:         color-mix(in srgb, var(--ink) 5%, transparent);
  --ds-card-action-hover-text:       var(--ink);
  --ds-card-action-hover-border:     color-mix(in srgb, var(--ink) 35%, transparent);

  /* Card-level destructive action button (Reject / Exclude / remove
   * ×). Inherits the neutral resting treatment but flips to danger
   * on hover. Not used by default; rules opt in by adding the
   * `-danger` variant tokens. */
  --ds-card-action-danger-hover-bg:      color-mix(in srgb, var(--state-danger) 10%, transparent);
  --ds-card-action-danger-hover-text:    var(--state-danger);
  --ds-card-action-danger-hover-border:  color-mix(in srgb, var(--state-danger) 40%, transparent);

  /* Card count badge ("10", "4" at top-right of each card header).
   * Aliased to --app-top-action-* so it stays visually identical to
   * Logout / + Add Patient — a tiny solid-ink pill with paper text. */
  --ds-card-count-bg:                var(--app-top-action-bg);
  --ds-card-count-text:              var(--app-top-action-text);
  --ds-card-count-border:            var(--app-top-action-border);

  /* Text inputs (textarea, input[type=text/number/etc.]).
   * Sit on the surface with a faint ink outline; focus pulls the
   * outline to --accent and adds a soft accent halo ring. */
  --ds-input-bg:                     transparent;
  --ds-input-text:                   var(--ink);
  --ds-input-placeholder-text:       var(--faint);
  --ds-input-border:                 color-mix(in srgb, var(--ink) 20%, transparent);
  --ds-input-hover-border:           color-mix(in srgb, var(--ink) 32%, transparent);
  --ds-input-focus-border:           var(--accent);
  --ds-input-focus-ring:             color-mix(in srgb, var(--accent) 18%, transparent);


  /* ── Palette switcher (floating bottom-right card) ──────────
   * Card itself is paper-coloured; swatch dots use direct --accent
   * from each palette (no formula — the dots ARE the palettes).
   * ───────────────────────────────────────────────────────── */

  --ds-palette-card-bg:          var(--paper);
  --ds-palette-card-border:      color-mix(in srgb, var(--ink) 10%, transparent);
  --ds-palette-card-shadow:      0 10px 30px -16px rgba(0,0,0,0.18);
  --ds-palette-label-text:       var(--faint);
  --ds-palette-name-text:        var(--ink);
  --ds-palette-hex-text:         var(--muted);
  --ds-palette-swatch-ring:      color-mix(in srgb, var(--ink) 20%, transparent);
  --ds-palette-swatch-active:    var(--ink);


  /* ── Exam / widget surfaces ──────────────────────────────────
   * Encounter widgets should follow the same palette relationships
   * as the Day Sheet: paper canvas, surface cards, subtle ink-mix
   * header/footer bands, semantic state chips, and shared input
   * focus behavior. These slots intentionally derive from the same
   * 13 palette inputs so swatch changes propagate across Dashboard
   * and exam features together.
   * ───────────────────────────────────────────────────────── */

  --exam-page-bg:                var(--paper);
  --exam-page-text:              var(--ink);
  --exam-page-muted-text:        var(--muted);
  --exam-page-faint-text:        var(--faint);

  --exam-card-bg:                var(--surface);
  --exam-card-border:            color-mix(in srgb, var(--ink) 8%, transparent);
  --exam-card-shadow:            0 1px 0 rgba(255,255,255,0.55) inset,
                                 0 1px 2px rgba(31,27,22,0.05),
                                 0 28px 56px -36px rgba(31,27,22,0.22);
  --exam-card-header-bg:         color-mix(in srgb, var(--ink) 3%, var(--surface));
  --exam-card-header-text:       var(--ink);
  --exam-card-header-rule:       color-mix(in srgb, var(--ink) 10%, transparent);
  --exam-card-footer-bg:         var(--exam-card-header-bg);
  --exam-card-footer-rule:       var(--exam-card-header-rule);

  --exam-section-title-text:     var(--muted);
  --exam-section-rule:           color-mix(in srgb, var(--ink) 10%, transparent);
  --exam-row-rule:               var(--line-soft);
  --exam-row-hover-bg:           color-mix(in srgb, var(--accent-soft) 42%, var(--surface));

  --exam-input-bg:               transparent;
  --exam-input-filled-bg:        var(--surface);
  --exam-input-border:           color-mix(in srgb, var(--ink) 20%, transparent);
  --exam-input-hover-border:     color-mix(in srgb, var(--ink) 32%, transparent);
  --exam-input-focus-border:     var(--accent);
  --exam-input-focus-ring:       color-mix(in srgb, var(--accent) 18%, transparent);
  --exam-input-text:             var(--ink);
  --exam-input-placeholder:      var(--faint);

  --exam-chip-bg:                color-mix(in srgb, var(--ink) 6%, transparent);
  --exam-chip-text:              var(--muted);
  --exam-chip-border:            transparent;
  --exam-chip-hover-bg:          color-mix(in srgb, var(--ink) 10%, transparent);
  --exam-chip-active-bg:         var(--accent-soft);
  --exam-chip-active-text:       var(--accent-ink);
  --exam-chip-stored-text:       var(--warning);
  --exam-chip-abnormal-bg:       color-mix(in srgb, var(--warning) 16%, transparent);
  --exam-chip-abnormal-text:     var(--warning);
  --exam-chip-na-bg:             color-mix(in srgb, var(--ink) 6%, transparent);
  --exam-chip-na-text:           var(--faint);
  --exam-chip-editing-bg:        var(--surface);
  --exam-chip-editing-border:    var(--accent);

  --exam-eye-od-bg:              var(--accent-soft);
  --exam-eye-od-text:            var(--accent-ink);
  --exam-eye-os-bg:              color-mix(in srgb, var(--success) 16%, var(--surface));
  --exam-eye-os-text:            var(--success);

  --exam-action-bg:              var(--ds-card-action-bg);
  --exam-action-text:            var(--ds-card-action-text);
  --exam-action-border:          var(--ds-card-action-border);
  --exam-action-hover-bg:        var(--ds-card-action-hover-bg);
  --exam-action-hover-text:      var(--ds-card-action-hover-text);
  --exam-action-hover-border:    var(--ds-card-action-hover-border);

  /* ── Modal surfaces ───────────────────────────────────────── */

  --modal-overlay-bg:            color-mix(in srgb, var(--ink) 42%, transparent);
  --modal-bg:                    var(--surface);
  --modal-border:                color-mix(in srgb, var(--ink) 10%, transparent);
  --modal-shadow:                0 24px 70px -34px rgba(31,27,22,0.34);
  --modal-title-text:            var(--ink);
  --modal-body-text:             var(--muted);
  --modal-rule:                  color-mix(in srgb, var(--ink) 10%, transparent);
}
