/* ============================================================================
   tokens.css — the only place a colour is allowed to be written as a hex value.
   Must load BEFORE every other stylesheet.

   Two layers, and the split is the whole point:

     Layer 1  raw palette.   Never referenced by a component.
     Layer 2  semantic roles. The only thing a component may use.

   Components say var(--danger), never var(--red-600). That indirection is
   what makes dark mode the ~40 lines at the bottom of this file instead of a
   second pass over all 151 KB of CSS.

   Consolidation note: the app had grown four neutral ramps (Tailwind slate,
   Tailwind gray, raw #333/#555/#ccc, Bootstrap #f8f9fa/#dee2e6), two greens
   (green + emerald) and three warns (amber + orange + Bootstrap yellow).
   Each family below lists the values it replaces so a find/replace can be
   verified rather than trusted.
   ========================================================================= */

:root {
  /* ── Layer 1: raw palette ───────────────────────────────────────────── */

  /* THE navy. One value. The app had grown five of them — #00093d, #001060,
     #0d1b6e, #001160, #001a78, #001a85 — none distinguishable from the next.
     Every shade below is mixed from this one, so changing this line restyles
     the whole app and the shades can never drift apart again. */
  --navy: #00093d;

  --navy-lift:  color-mix(in srgb, var(--navy), white 14%);  /* hover on navy */
  --navy-lift2: color-mix(in srgb, var(--navy), white 24%);  /* pressed/active */
  --navy-pale:  color-mix(in srgb, var(--navy), white 55%);  /* navy on a dark bg */
}

/* color-mix() needs Safari 16.2 / Chrome 111. Without this guard an older
   browser resolves those three to an invalid value, and anything painted with
   them falls back to transparent — buttons and the sidebar would lose their
   fill entirely. These are the mixes above, resolved by hand. */
@supports not (color: color-mix(in srgb, red, blue)) {
  :root {
    --navy-lift:  #1c2456;
    --navy-lift2: #2f3668;
    --navy-pale:  #8089ae;
  }
}

:root {

  /* Neutrals — Tailwind slate. Absorbs gray, the raw greys and Bootstrap's. */
  --slate-50:  #f8fafc;  /* also #f8f9fa #f7f8fa #f0f0f0 */
  --slate-100: #f1f5f9;  /* also #f3f4f6 #eee */
  --slate-200: #e2e8f0;  /* also #e5e7eb #dee2e6 #ddd */
  --slate-300: #cbd5e1;  /* also #ccc */
  --slate-400: #94a3b8;
  --slate-500: #64748b;  /* also #6b7280 #555 */
  --slate-600: #475569;
  --slate-700: #334155;  /* also #374151 #333 */
  --slate-800: #1e293b;  /* also #1f2937 */
  --slate-900: #0f172a;  /* also #111827 #000 */
  --slate-950: #020617;  /* near-black, and the dark theme's page bg */
  --white:     #ffffff;  /* absorbs #fff — 196 uses across both spellings */

  /* Success — green. Absorbs emerald (#10b981 #047857 #d1fae5 #a7f3d0 #ecfdf5). */
  --green-50:  #f0fdf4;
  --green-100: #dcfce7;
  --green-600: #16a34a;
  --green-700: #15803d;
  --green-800: #166534;
  --green-900: #14532d;

  /* Danger — red. */
  --red-50:  #fef2f2;
  --red-100: #fee2e2;
  --red-200: #fecaca;
  --red-500: #ef4444;
  --red-600: #dc2626;
  --red-700: #b91c1c;
  --red-800: #991b1b;
  --red-900: #7f1d1d;

  /* Warn — amber. Absorbs orange (#ea580c #9a3412 #7c2d12 #fed7aa #ffedd5
     #fff7ed), Bootstrap yellow (#ffc107) and #fef9c3. #ffba08 is the existing
     brand-ish accent at 73 uses, kept as the 400. */
  --amber-50:  #fffbeb;
  --amber-100: #fef3c7;
  --amber-200: #fde68a;
  --amber-400: #ffba08;
  --amber-500: #f59e0b;
  --amber-600: #d97706;
  --amber-700: #b45309;
  --amber-800: #92400e;

  /* Link blue. Deliberately its own ramp, not borrowed from indigo (info)
     or navy (brand): a link has to be distinguishable at a glance from a
     status badge and from a button, and navy reads as "heading" rather
     than "clickable" in a table cell. */
  --blue-600: #2563eb;
  --blue-400: #60a5fa;

  /* Info — indigo. Absorbs blue (#dbeafe #eff6ff #1d4ed8). */
  --indigo-50:  #eef2ff;
  --indigo-100: #dbeafe;
  --indigo-500: #6366f1;
  --indigo-700: #3730a3;

  /* ── Layer 2: semantic roles — components use ONLY these ────────────── */

  /* Surfaces & text */
  --surface:         var(--white);
  --surface-sunken:  var(--slate-50);    /* page background behind cards */
  --surface-hover:   var(--slate-100);
  /* Two jobs, two roles.

     --border divides things that are already distinct: a table row from
     the next, a card from the page. It can be quiet.

     --border-strong draws the EDGE OF A CONTROL — an input, a select, an
     outlined button. That edge is the only thing saying "you can type
     here", so it has to be seen. On white, slate-200 measured 1.23 against
     the background: present in the DOM, absent to the eye, which is why
     the filter strip looked like floating text.

     Both step darker here. The dark theme keeps its own values below, where
     a card is lighter than the page and the surface change carries the
     edge on its own. */
  --border:          var(--slate-300);
  --border-subtle:   var(--slate-200);
  --border-strong:   var(--slate-400);
  /* Text on white, each role one step darker than it was.
     Measured against #ffffff, the old values were:

        --text          #0f172a  17.85  AAA
        --text-muted    #64748b   4.76  AA, only just
        --text-subtle   #94a3b8   2.56  FAILS AA outright

     --text-subtle failing is why so much of the light theme read as washed
     out: it carries captions, table meta, timestamps and field labels — a
     large share of the words on any page. The dark theme never showed it
     because its equivalents sit at 14.5 / 6.96 / 3.75, where lightening a
     role moves it AWAY from the background. On white, lightening moves it
     toward the background, and the headroom runs out fast.

     Now 20.17 / 7.58 / 4.76 — AAA, AAA, AA. */
  --text:            var(--slate-950);
  --text-muted:      var(--slate-600);
  --text-subtle:     var(--slate-500);

  /* Brand */
  --brand:           var(--navy);
  --brand-hover:     var(--navy-lift);
  --on-solid:        var(--white);

  /* Links — the ONE text-clickability affordance in the app.

     Rule, and it is not a style preference: text carrying --link MUST
     navigate. Text that does not navigate must never borrow it, and must
     never take an underline or cursor:pointer to look important. The app
     grew a class (.rpt-board-branch) used on both <a> and <span> with
     identical styling and a hover underline, so half the "links" in the
     credits and dashboard tables led nowhere. One role, one meaning.

     Blue, and its own ramp rather than an alias of --brand or --info. Navy
     reads as "heading" in a table cell, not "clickable", and indigo is
     already spoken for by the info status family — a link has to be
     distinguishable at a glance from both. It lifts to #60a5fa on dark for
     the same reason the solid status colours do: #2563eb on #0f172a is
     legible but joyless, and links are meant to be found. */
  --link:            var(--blue-600);
  --link-hover:      var(--blue-400);

  /* The chevron on a <select>. Bootstrap ships one, but every select in the
     filter strip sets its own background and the shorthand wipes it, so the
     controls read as plain boxes with no hint that they open a list.
     Carried as a token because the colour is baked into the SVG as a hex —
     a data URI cannot reference a variable — and this file is where the
     hexes live. */

  /* The selected item in the sidebar. Amber, because this is the one place
     the brand's accent means "you are here".

     It has to flip. As a 14px label, --accent (#ffba08) measures 1.71 on
     white — unreadable — while amber-800 is 2.52 on the dark sidebar. No
     single value clears AA on both, so light takes amber-700 (5.02) and
     dark takes the bright accent (10.44). */
  --nav-active:      var(--amber-700);
  --select-caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");

  /* Permanently dark brand surfaces — the sidebar, the topbar, the landing
     hero. These are navy in BOTH themes, so unlike --surface they must not
     flip, and text on them stays white in both. Getting this wrong is how the
     landing hero ended up with near-black headlines on navy. */
  --brand-surface:   var(--navy);
  --brand-surface-2: var(--navy-lift);  /* hover on a navy surface */
  --on-dark:         var(--white);
  --on-dark-muted:   rgba(255, 255, 255, 0.68);

  /* Status families. Each has: solid (buttons/icons), bg (badge/alert tint),
     fg (text ON that tint), border. Keep the set complete — a family missing
     its fg is how unreadable badges get made. */
  --success:         var(--green-600);
  --success-bg:      var(--green-100);
  --success-fg:      var(--green-800);
  --success-border:  var(--green-600);

  --warn:            var(--amber-600);
  --warn-bg:         var(--amber-100);
  --warn-fg:         var(--amber-800);
  --warn-border:     var(--amber-400);

  --danger:          var(--red-600);
  --danger-bg:       var(--red-100);
  --danger-fg:       var(--red-800);
  --danger-border:   var(--red-600);

  --info:            var(--indigo-500);
  --info-bg:         var(--indigo-50);
  --info-fg:         var(--indigo-700);
  --info-border:     var(--indigo-500);

  /* Accent — the #ffba08 highlight, distinct from "warn" as a status. */
  --accent:          var(--amber-400);
  --on-accent:       var(--slate-900);
}

/* ── Dark theme ────────────────────────────────────────────────────────────
   Follows the OS. Only LAYER 2 is redefined — no component changes.

   Two things that are not simply "lighten everything":

   1. Solids must get LIGHTER on dark or they vanish. --success at #16a34a is
      near-invisible on #0f172a; on dark it becomes #4ade80.
   2. Tints must INVERT, not lighten. --success-bg #dcfce7 is a pale mint that
      would read as a glaring white block on a dark card; on dark it becomes a
      deep green with light text over it.

   The :not([data-theme="light"]) guard leaves room for an explicit toggle
   later without rewriting this block.
   ------------------------------------------------------------------------ */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --surface:        #0f172a;
    --surface-sunken: #020617;
    --surface-hover:  #1e293b;
    --border:         #1e293b;
    --border-strong:  #475569;
    --border-subtle:  #172033;
    --text:           #e2e8f0;
    --text-muted:     #94a3b8;
    --text-subtle:    #64748b;

    --brand:          var(--navy-pale);
    --brand-hover:    color-mix(in srgb, var(--navy), white 70%);
    --on-solid:       #0b1020;

    --success:        #4ade80;
    --success-bg:     #12301f;
    --success-fg:     #bbf7d0;
    --success-border: #16a34a;

    --warn:           #fbbf24;
    --warn-bg:        #382812;
    --warn-fg:        #fde68a;
    --warn-border:    #d97706;

    --danger:         #f87171;
    --danger-bg:      #3a1a1c;
    --danger-fg:      #fecaca;
    --danger-border:  #dc2626;

    --info:           #818cf8;
    --info-bg:        #1e2148;
    --info-fg:        #c7d2fe;
    --info-border:    #6366f1;

    --nav-active:     #ffba08;
    --select-caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    --link:           #60a5fa;   /* lifts on dark, like the solids above */
    --link-hover:     #93c5fd;
    --accent:         #ffba08;
    --on-accent:      #0b1020;
  }
}

/* Explicit opt-in, for a manual toggle. Mirrors the block above. */
:root[data-theme="dark"] {
  --surface:        #0f172a;
  --surface-sunken: #020617;
  --surface-hover:  #1e293b;
  --border:         #1e293b;
  --border-strong:  #475569;
  --border-subtle:  #172033;
  --text:           #e2e8f0;
  --text-muted:     #94a3b8;
  --text-subtle:    #64748b;
  --brand:          var(--navy-pale);
  --brand-hover:    color-mix(in srgb, var(--navy), white 70%);
  --on-solid:       #0b1020;
  --success:        #4ade80;
  --success-bg:     #12301f;
  --success-fg:     #bbf7d0;
  --success-border: #16a34a;
  --warn:           #fbbf24;
  --warn-bg:        #382812;
  --warn-fg:        #fde68a;
  --warn-border:    #d97706;
  --danger:         #f87171;
  --danger-bg:      #3a1a1c;
  --danger-fg:      #fecaca;
  --danger-border:  #dc2626;
  --info:           #818cf8;
  --info-bg:        #1e2148;
  --info-fg:        #c7d2fe;
  --info-border:    #6366f1;

  --nav-active:     #ffba08;
  --select-caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  --link:           #60a5fa;   /* lifts on dark, like the solids above */
  --link-hover:     #93c5fd;
  --accent:         #ffba08;
  --on-accent:      #0b1020;
}

/* Let the browser theme form controls, scrollbars and autofill to match. */
:root { color-scheme: light; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { color-scheme: dark; }
}
:root[data-theme="dark"] { color-scheme: dark; }

/* ── Bootstrap bridge ──────────────────────────────────────────────────────
   Bootstrap ships utilities whose colour is baked in: .text-dark is always
   #212529, .bg-white always #fff. On a dark surface those render as dark text
   on a dark card — this is why the "Filter Sales" heading was invisible. The
   markup uses them widely enough that rewriting every template is the wrong
   trade; pointing them at tokens fixes all of it at once.

   Bootstrap's own components (tables, dropdowns, modals, form controls) are
   handled separately by data-bs-theme, which layout.html sets from the OS.
   ------------------------------------------------------------------------ */
.text-dark, .text-body, .text-black          { color: var(--text) !important; }
.text-muted, .text-secondary                 { color: var(--text-muted) !important; }
.text-white                                  { color: var(--on-solid) !important; }
.bg-white, .bg-body, .bg-light               { background-color: var(--surface) !important; }
.bg-dark                                     { background-color: var(--brand) !important; }
.text-primary                                { color: var(--brand) !important; }
.bg-primary                                  { background-color: var(--brand) !important; }
.text-success                                { color: var(--success) !important; }
.bg-success                                  { background-color: var(--success) !important; }
.text-danger                                 { color: var(--danger) !important; }
.bg-danger                                   { background-color: var(--danger) !important; }
.text-warning                                { color: var(--warn) !important; }
.bg-warning                                  { background-color: var(--warn) !important; }
.text-info                                   { color: var(--info) !important; }
.bg-info                                     { background-color: var(--info) !important; }
.border                                      { border-color: var(--border) !important; }

/* The page itself, so dark mode is not a white frame around dark cards. */
body { background-color: var(--surface-sunken); color: var(--text); }

/* -- Typography -------------------------------------------------------------
   Edutele Access v2.1, adopted whole. Canonical spec:
   EDUTELE/edutele-pay-frontend/docs/typography.md -- that file decides, this
   one implements. A component may not introduce a size, weight, tracking or
   line height that is not below; if it needs one, the spec changes first.

   Four rules worth restating, because breaking them is invisible in review:
     * Four weights only -- 400/500/600/700. Never 300, 800 or 900.
     * Nothing below 12px except the numeric unread badge.
     * Nothing is uppercase at all. (Deviation from v2.1, which allows
       uppercase on a table column header; this product wants none.)
     * Positive tracking means "transcribe this", never emphasis.
   ------------------------------------------------------------------------ */
:root {
  --font-body: 'Plus Jakarta Sans', system-ui, sans-serif;

  /* Sizes. rem on web, root left at the browser default so these track the
     reader's own font-size setting. px in the comments is reference only. */
  --text-badge:    0.6875rem;  /* 11 - unread count ONLY, the one sub-12 size */
  --text-meta:     0.8125rem;  /* 13 - dates, status, counts, tab labels, and
                                       the uppercase table header */
  --text-body:     0.875rem;   /* 14 - body, field labels, links, chips */
  --text-support:  0.9375rem;  /* 15 - secondary buttons, toasts, empty states,
                                       card numbers, stepper values */
  --text-row:      1rem;       /* 16 - row titles/values/figures, inputs,
                                       primary buttons. The workhorse. */
  --text-section:  1rem;       /* 16 - section heads, card titles */
  --text-title:    1.125rem;   /* 18 - page title, price */
  --text-card-fig: 1.25rem;    /* 20 - card figure */
  --text-peep:     1.375rem;   /* 22 - peep figure */
  --text-emph:     1.5rem;     /* 24 - emphasis figure */
  --text-stat:     1.625rem;   /* 26 - stat figure */
  --text-sec-fig:  1.875rem;   /* 30 - section figure */
  --text-code:     2rem;       /* 32 - code read aloud or transcribed */
  --text-hero:     2.125rem;   /* 34 - hero figure */
  --text-display:  2.375rem;   /* 38 - balance figure, pre-auth display */

  /* Weights. body leaves font-weight unset, so 400 is the inherited default
     and roles at 400 declare nothing. */
  --weight-regular: 400;   /* muted body, explanations, empty states, meta */
  --weight-medium:  500;   /* inactive tab labels */
  --weight-semi:    600;   /* row titles, buttons, field labels, chips, links */
  --weight-bold:    700;   /* titles, figures, badges */

  /* Tracking. Six values, each doing a job. Nothing decorative. */
  --track-figure-lg: -0.03em;  /* 38, 34, 30 */
  --track-figure-md: -0.02em;  /* 26, 24, 22, 20 figures; 18 price */
  --track-title:     -0.01em;  /* 18 titles, 16 heads */
  --track-none:       0;       /* everything 15 and below */
  --track-grouped:    0.06em;  /* card numbers, the uppercase table header */
  --track-spoken:     0.08em;  /* codes read aloud or transcribed */

  /* Line height, unitless. Anything that can wrap to a paragraph gets 1.6;
     anything that must not wrap gets 1. */
  --leading-display: 1.05;
  --leading-hero:    1.1;
  --leading-figure:  1;
  --leading-title:   1.25;
  --leading-single:  1;
  --leading-body:    1.6;
  --leading-meta:    1.65;
}

body {
  font-family: var(--font-body);
  font-size: var(--text-row);
  line-height: var(--leading-title);
  /* font-weight deliberately unset: 400 inherits */
}

/* -- Type roles -------------------------------------------------------------
   Named exactly as the spec names them, so a call site reads the same in
   either product. Every figure carries tabular numerals so money aligns.
   ------------------------------------------------------------------------ */
.t-display     { font-size: var(--text-display);  font-weight: var(--weight-bold); letter-spacing: var(--track-figure-lg); line-height: var(--leading-display); }
.t-balance     { font-size: var(--text-display);  font-weight: var(--weight-bold); letter-spacing: var(--track-figure-lg); line-height: var(--leading-display); font-variant-numeric: tabular-nums; }
.t-hero-fig    { font-size: var(--text-hero);     font-weight: var(--weight-bold); letter-spacing: var(--track-figure-lg); line-height: var(--leading-hero);    font-variant-numeric: tabular-nums; }
.t-code        { font-size: var(--text-code);     font-weight: var(--weight-bold); letter-spacing: var(--track-spoken);    line-height: var(--leading-figure);  font-variant-numeric: tabular-nums; }
.t-section-fig { font-size: var(--text-sec-fig);  font-weight: var(--weight-bold); letter-spacing: var(--track-figure-lg); line-height: var(--leading-figure);  font-variant-numeric: tabular-nums; }
.t-stat-fig    { font-size: var(--text-stat);     font-weight: var(--weight-bold); letter-spacing: var(--track-figure-md); line-height: var(--leading-figure);  font-variant-numeric: tabular-nums; }
.t-emph-fig    { font-size: var(--text-emph);     font-weight: var(--weight-bold); letter-spacing: var(--track-figure-md); line-height: var(--leading-figure);  font-variant-numeric: tabular-nums; }
.t-peep-fig    { font-size: var(--text-peep);     font-weight: var(--weight-bold); letter-spacing: var(--track-figure-md); line-height: var(--leading-figure);  font-variant-numeric: tabular-nums; }
.t-card-fig    { font-size: var(--text-card-fig); font-weight: var(--weight-bold); letter-spacing: var(--track-figure-md); line-height: var(--leading-figure);  font-variant-numeric: tabular-nums; }

.t-page-title  { font-size: var(--text-title);    font-weight: var(--weight-bold); letter-spacing: var(--track-title);     line-height: var(--leading-title); }
.t-price       { font-size: var(--text-title);    font-weight: var(--weight-bold); letter-spacing: var(--track-figure-md); line-height: var(--leading-title); font-variant-numeric: tabular-nums; }
.t-section-head,
.t-card-title  { font-size: var(--text-section);  font-weight: var(--weight-bold); letter-spacing: var(--track-title);     line-height: var(--leading-title); }

.t-row-title   { font-size: var(--text-row); font-weight: var(--weight-semi);    line-height: var(--leading-single); }
.t-row-value   { font-size: var(--text-row); font-weight: var(--weight-regular); line-height: var(--leading-single); }
.t-row-fig     { font-size: var(--text-row); font-weight: var(--weight-bold);    line-height: var(--leading-single); font-variant-numeric: tabular-nums; }

.t-btn         { font-size: var(--text-row);     font-weight: var(--weight-semi); line-height: var(--leading-single); }
.t-input       { font-size: var(--text-row);     font-weight: var(--weight-semi); line-height: var(--leading-single); }
.t-btn-2       { font-size: var(--text-support); font-weight: var(--weight-semi); line-height: var(--leading-single); }
.t-stepper     { font-size: var(--text-support); font-weight: var(--weight-bold); line-height: var(--leading-single); font-variant-numeric: tabular-nums; }
.t-chip        { font-size: var(--text-body);    font-weight: var(--weight-semi); line-height: var(--leading-single); }

.t-toast       { font-size: var(--text-support); font-weight: var(--weight-semi);    line-height: var(--leading-title); }
.t-empty       { font-size: var(--text-support); font-weight: var(--weight-regular); line-height: var(--leading-body); }
.t-card-number { font-size: var(--text-support); font-weight: var(--weight-regular); letter-spacing: var(--track-grouped); font-variant-numeric: tabular-nums; }
.t-body        { font-size: var(--text-body);    font-weight: var(--weight-regular); line-height: var(--leading-body); }
.t-field-label { font-size: var(--text-body);    font-weight: var(--weight-semi);    line-height: var(--leading-single); }
.t-link        { font-size: var(--text-body);    font-weight: var(--weight-semi);    line-height: var(--leading-single); }
.t-meta        { font-size: var(--text-meta);    font-weight: var(--weight-regular); line-height: var(--leading-meta); font-variant-numeric: tabular-nums; }
.t-meta-strong { font-size: var(--text-meta);    font-weight: var(--weight-semi);    line-height: var(--leading-meta); font-variant-numeric: tabular-nums; }
.t-tab         { font-size: var(--text-meta);    font-weight: var(--weight-medium);  line-height: var(--leading-single); }
.t-tab.is-current { font-weight: var(--weight-bold); }

/* The one exception to the 12px floor: a numeric unread count, never prose. */
.t-badge       { font-size: var(--text-badge); font-weight: var(--weight-bold); line-height: var(--leading-single); font-variant-numeric: tabular-nums; }

/* Web-only. Sentence case, not uppercase - see the header note. */
.t-table-head  { font-size: var(--text-meta); font-weight: var(--weight-bold); }

/* ── Row status marking ────────────────────────────────────────────────────
   A status tint is calibrated for a badge a few words wide. Stretched across
   a full table row it drowns the numbers it is meant to qualify, and on
   screens where most rows carry a status the whole table turns one colour.
   Rows get an edge accent and a whisper of tint instead of a fill.
   ------------------------------------------------------------------------ */
.row-success > td { background: color-mix(in srgb, var(--success) 7%, var(--surface)); }
.row-warn    > td { background: color-mix(in srgb, var(--warn)    7%, var(--surface)); }
.row-danger  > td { background: color-mix(in srgb, var(--danger)  7%, var(--surface)); }
.row-info    > td { background: color-mix(in srgb, var(--info)    7%, var(--surface)); }
.row-success > td:first-child { box-shadow: inset 3px 0 0 var(--success); }
.row-warn    > td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
.row-danger  > td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
.row-info    > td:first-child { box-shadow: inset 3px 0 0 var(--info); }

@supports not (color: color-mix(in srgb, red, blue)) {
  .row-success > td { background: var(--success-bg); }
  .row-warn    > td { background: var(--warn-bg); }
  .row-danger  > td { background: var(--danger-bg); }
  .row-info    > td { background: var(--info-bg); }
}

/* -- Spacing & density ------------------------------------------------------
   layout.md: "Two numbers do almost all the work." Gutter and Rhythm are both
   20px; there is no third value. If a screen feels tight the fix is fewer
   sections, not a smaller gap.

   Table rows take the Profile-row metrics (12px 16px, 56px) rather than the
   List-row ones (14px 15-16px, 56-64px): these are data tables read in bulk,
   not touch targets. Before this the app carried 31 distinct cell paddings,
   so no two tables shared a rhythm.
   ------------------------------------------------------------------------ */
:root {
  --gutter:      20px;  /* left and right of everything */
  --rhythm:      20px;  /* between one section and the next */
  --head-gap:    12px;  /* section head to the card below it */
  --stack-gap:   12px;  /* between sibling cards in one section */
  --pane-top:     8px;  /* above the first section only */
  --pane-bottom: 24px;  /* below the last section */

  /* Row height is padding + content, nothing else. An explicit height on a
     <tr> is added to the cell padding rather than absorbing it, so the row
     ends up taller than the number says and the value stops meaning
     anything. 12px top and bottom around 15px text lands a data row on the
     44px tap floor exactly. */
  /* Spacing steps. layout.md fixes the structural numbers -- 8 pane-top,
     12 head/stack gap, 20 gutter/rhythm, 24 pane-bottom -- but says nothing
     about the small gaps inside a row (icon to label, chip to chip). 4 and 6
     exist so that separating two words never reaches for 12. */
  --space-1:  4px;
  --space-2:  6px;
  --space-3:  8px;
  --space-4: 12px;
  --space-5: 16px;
  --space-6: 20px;
  --space-7: 24px;

  --row-pad-y:   8px;
  --row-pad-x:   16px;

  --radius-card: 16px;
  --radius-tile: 12px;
  --radius-btn:  14px;
  --radius-pill: 999px;

  --tap-min:     44px;  /* never below this in the smallest dimension */
}

/* One rhythm for every data table in the app. */
.app-table > thead > tr > th,
.app-table > tbody > tr > td,
table:not(.table-plain) > thead > tr > th,
table:not(.table-plain) > tbody > tr > td {
  padding: var(--row-pad-y) var(--row-pad-x);
}
table:not(.table-plain) > tbody > tr > td {
  border-bottom: 1px solid var(--border-subtle);
}
table:not(.table-plain) > tbody > tr:last-child > td {
  border-bottom: 0;
}

/* ── No pills in data tables ───────────────────────────────────────────────
   A capsule is for a value floating in open space, where it needs an edge to
   read as one thing. A table cell already has edges — the column and the row
   give it both. Filling every cell of a column with a capsule turns the
   column into a block of colour and competes with the figures beside it.

   Inside a <td> these render as plain text and keep only their colour, which
   is the part that carries meaning. The classes still work everywhere else;
   this is scoped to table cells and nothing more.
   ------------------------------------------------------------------------ */
td .rpt-hero-verdict,
td .badge,
td .al-tag, td .al-tag-credit, td .al-tag-debit, td .al-tag-info,
td .al-tag-neutral, td .al-tag-warn, td .al-reversed-badge,
td .bs-return-tag, td .dc-branch-tag,
td .exp-tag, td .exp-tag-admin, td .exp-tag-restock, td .exp-tag-staff,
td .flag-pill, td .flag-pill-group, td .hof-you-pill,
td .inv-exp-pill, td .pr-cat-pill, td .prod-cat-pill,
td .tgt-pill, td .tgt-pill-on {
  background: none !important;
  background-color: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  box-shadow: none !important;
  min-width: 0 !important;
  font-weight: var(--weight-semi);
  font-size: inherit;
  letter-spacing: normal;
}

/* The status dot inside a verdict was a counterweight to the capsule; with
   the capsule gone it is just a speck ahead of the word. */
td .rpt-hero-verdict .dot { display: none !important; }
