/* ══════════════════════════════════════════════════════════════════════════
   AURORA — the third client skin (§6). Dark-first, dense, exchange-shaped.

   A skin is a COMPLETE FACE, not a stylesheet (§6): tokens here, art beside
   this file, template overrides under app/views/themes/aurora/, and a copy
   overlay under lang/themes/aurora/ if the voice differs.

   ── THE YELLOW IS NOT BINANCE'S, AND THAT IS A MEASUREMENT ────────────────

   The reference mockup uses #F0B90B — Binance's own mark. This skin does not,
   because #F0B90B + IBM Plex + an exchange layout is trade dress, and §17
   items 1 and 2 (no entity, no licence, no reviewed legal set) are still open.
   Confusion is the risk, and the mitigation is cheap.

   The brief proposed #EAB308. Measured, that is **ΔE76 = 2.6** from Binance's
   yellow and 0.2° of hue away — at the just-noticeable-difference threshold,
   which is to say not a separation at all. It would have been the same yellow
   with a different name.

   `--brand: #E5B62E` is **ΔE76 = 9.8** from #F0B90B, roughly four times the
   JND and perceptible side by side, and it gets there by DESATURATING (78%
   against Binance's 91%) rather than by shifting hue — so the skin still reads
   as a warm-yellow exchange and does not read as theirs. It is also the better
   value on contrast: 9.19:1 on a panel against #EAB308's 9.10, and 10.18:1 for
   a dark label sitting on it.

   The NUVOBITS lockup beside it is our own; nothing here imitates a mark.

   ── CONTRAST IS A PROPERTY OF A PAIR (§6) ─────────────────────────────────

   Every figure below was computed against the surface the token actually
   MEETS, and the binding surface is named. `--line` is deliberately absent
   from those pairs: it is a border, and text never sits on it — measuring
   against it once nearly over-corrected `--faint` for a surface that does not
   exist.

   The bound is 4.5:1 for text, 3:1 for non-text and for text at 24px+.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
    color-scheme: dark;

    /* ── surfaces — near-black, four steps ────────────────────────────── */
    --bg: #0B0E13;          /* page */
    --panel: #161A21;       /* card, rail */
    --panel-2: #0F131A;     /* inset: inputs, table stripes, quiet wells */
    --panel-3: #1E242D;     /* raised / hover — the LIGHTEST surface, so the
                               binding one for every text pair below */
    --line: #2A313B;        /* a border that must be seen */
    --line-soft: #1E242D;   /* the ordinary hairline */

    /* ── text — worst case is always --panel-3 ───────────────────────── */
    --text: #EAECEF;        /* 13.19:1 on panel-3, 14.74 on a panel */
    --muted: #9AA4B2;       /*  6.19:1 on panel-3 */
    --faint: #8A94A4;       /*  5.09:1 on panel-3 — #7A8494 measured 4.13
                               there and was rejected, the admin realm's
                               lesson taken before shipping rather than after */

    /* ── accent: buttons, links, active nav, focus ────────────────────── */
    --brand: #E5B62E;       /*  8.22:1 on panel-3 · dark label on it 10.18:1 */
    --brand-hover: #F2C64A; /* brighter, because a dark skin brightens on hover */
    --brand-dim: rgba(229, 182, 46, .12);

    /* ── trading semantics — NEVER the accent ─────────────────────────── */
    --up: #16C784;          /*  7.09:1 on panel-3 as text */
    --up-strong: #0ECB81;   /*  the fuller hue: fills, borders, badges */
    --up-dim: rgba(14, 203, 129, .12);
    --down: #F25C73;        /*  4.87:1 on panel-3 — #F0526A measured 4.55,
                               a pass mark rather than headroom */
    --down-strong: #F6465D; /*  the fuller hue, for fills where 3:1 applies */
    --down-dim: rgba(246, 70, 93, .12);
    --warn: #E8A33D;        /*  7.24:1 on panel-3 */

    /* ── money accent — and here it CANNOT be the brand ──────────────────
       §1 reserves gold for a balance figure. On nuvo the brand is indigo, so
       gold is the only warm note and the rule costs nothing. On aurora the
       brand is ALREADY warm — reusing it would make a balance look like a
       link, which is the exact confusion §1's rule exists to prevent.

       So the money accent is a deeper amber, ΔE76 = 13.4 from the brand:
       plainly a different colour at a glance, still unmistakably money. */
    --gold: #F0A93A;        /*  7.76:1 on panel-3 */
    --gold-figure: #F0A93A; /*  same value: on a dark skin it already clears
                               the text bound, so the large-figure split nuvo
                               needs (its approved gold is 3.40:1 on white)
                               has nothing to buy here */

    /* ── destructive action ──────────────────────────────────────────────
       NOT --down. --down is a DATA colour tuned for a P/L figure; this is a
       FILL under a white label, and it carries 5.29:1 for that label. */
    --danger: #CC2653;

    --row-hover: #1E242D;
    --chart-grid: rgba(154, 164, 178, .18);
    --chart-ink: #E5B62E;
    --card-shadow: 0 1px 2px rgba(0, 0, 0, .40);

    /* ── geometry — tighter than nuvo, an exchange is not a brochure ──── */
    --radius: 8px;          /* cards   */
    --radius-sm: 4px;       /* controls */
    --radius-pill: 20px;    /* pills   */

    /* ── density ─────────────────────────────────────────────────────── */
    --row-h: 30px;
    --fs-fig: 12px;
    --fs-fig-sm: 11px;
    --wl-fig: 66px;

    /* THE BOTTOM TAB BAR'S HEIGHT (mobile-A). Below 860px the seven nav
       entries leave the header and become a fixed bar at the bottom of the
       screen, within a thumb's reach. It is a token because §6 puts a density
       value in the theme, and because the BAR's own height and the padding
       that stops the page hiding underneath it are two rules that must resolve
       to one number — the shape §9 records every time this project has had two
       declarations of one fact. */
    --tabbar-h: 56px;

    /* ── type — IBM Plex, SELF-HOSTED (§8) ───────────────────────────────
       OFL-1.1, vendored by bin/vendor_fonts.php into this skin's own fonts/
       directory with its licence and provenance beside it (§6 sanctions a
       theme package carrying fonts/). Binance's own "BinancePlex" is a
       proprietary customisation of Plex and is NOT used; upstream IBM Plex
       carries the same character and is free to redistribute.

       The @font-face declarations are at the FOOT of this file rather than in
       app.css, so a visitor on another skin never parses them and never
       preloads them. Cost measured on the wire by bin/prove_fonts.mjs, not
       estimated: an English page on aurora downloads 3 files and 76,040 bytes
       of type against nuvo's 3 and 101,976 — aurora is 25,936 bytes LIGHTER,
       because it needs two families where nuvo needs three. */
    --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    --ui: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --display: 'IBM Plex Sans', var(--ui);

    /* ── interaction states (UI polish) ──────────────────────────────────
       Same NAMES as every other skin — a token only some skins declare is a
       dropped declaration the moment THEME changes, not a fallback, and the
       parity check now enforces that across all three.

       --focus-ring is the brand: 8.22:1 at its worst against a surface and
       6.91:1 against --line, well past WCAG 2.4.11's 3:1, because a ring most
       often sits directly beside a border. */
    --dur: 140ms;
    --ease: cubic-bezier(.2, 0, 0, 1);
    --focus-ring: var(--brand);
    --focus-ring-w: 2px;
    --focus-offset: 2px;
    --press: #232A34;
    --disabled-o: .7;
    --lift: none;           /* deliberately flat: an exchange surface does not
                               float, and a hover shadow would be the one
                               place this skin grew depth */

    /* ── THE LABEL THAT BELONGS ON A FILL (aurora-2) ─────────────────────
       A coloured fill needs a label chosen FOR IT, and structural CSS wrote
       `color: #fff` on seven of them. White is right on some fills and wrong
       on most: measured, `.cab-pill--live` — the LIVE badge §11 makes
       load-bearing — was white on `--up-strong` at **1.92:1 on nuvo dark**
       and failed AA in four of six skin/mode combinations, from the redesign
       until now.
       aurora-1 fixed exactly one of the seven (`.btn--primary`) with a
       per-skin literal. That works and does not generalise: every new brand
       fill needs its own override in every skin, and whoever adds one will
       not know. So it is a TOKEN — chosen per skin per mode by measurement,
       read by structural CSS, and covered for free by the existing
       every-skin-defines-every-var check. Ratios are against this skin's own
       fill values and are stated so the next reader can re-check them. */
    --on-brand: #12161D;        /* 9.55:1 */
    --on-up: #12161D;           /* 8.53:1 */
    --on-down: #12161D;         /* 5.14:1 */
    --on-danger: #FFFFFF;       /* 5.29:1 */
}

/* ── aurora's LIGHT mode — the ☾/☀ toggle, orthogonal to THEME (§6) ─────
   Same token NAMES, surfaces flipped.

   THE ACCENT CANNOT SURVIVE THE FLIP. #E5B62E measures 1.59:1 on the light
   raised surface — yellow on white is the classic contrast failure, and it is
   not close. As TEXT (a link, an active nav item) it darkens to a deep amber
   that clears the bound with headroom; the bright yellow stays only where it
   is a FILL carrying a dark label, which is where it was always legible.

   This is the mirror of nuvo lifting its indigo in dark mode: the split
   exists because of the surface, not because anybody changed their mind
   about the hue. */
html[data-theme="light"] {
    color-scheme: light;

    --bg: #F6F7F9;
    --panel: #FFFFFF;
    --panel-2: #F1F3F6;
    --panel-3: #E8EBF0;
    --line: #D3D8E0;
    --line-soft: #E4E8EE;

    --text: #12161D;        /* 15.17:1 on panel-3 */
    --muted: #59616E;       /*  5.23:1 on panel-3 */
    --faint: #626A77;       /*  4.57:1 on panel-3 — #69717E measured 4.12 */

    --brand: #7A5A10;       /*  5.33:1 on panel-3 as TEXT (the yellow is 1.59) */
    --brand-hover: #5E4509;
    --brand-dim: rgba(229, 182, 46, .16);

    --up: #0A7049;          /*  5.13:1 on panel-3 */
    --up-strong: #0D8656;
    --up-dim: rgba(13, 134, 86, .10);
    --down: #C02A38;        /*  4.84:1 on panel-3 */
    --down-strong: #D0353C;
    --down-dim: rgba(208, 53, 60, .10);
    --warn: #856010;        /*  4.78:1 on panel-3 — nuvo's #8A6410 measures 4.49
                               here, because aurora's sunk panel is darker */

    /* On a warm skin the brand is itself a yellow, so gold leans ORANGE to stay
       a different thing (§1): a balance figure must not read as a link. Both
       modes are measured — dark ΔE76 13.4, light 14.8. */
    --gold: #8F5216;        /*  5.19:1 on panel-3 */
    --gold-figure: #A96520; /*  3.85:1 on panel-3 — the large-text bound, and it
                               is used ONLY at 24px+, exactly as nuvo does */

    --row-hover: #EEF1F5;
    --chart-grid: rgba(90, 100, 118, .22);
    --chart-ink: #7A5A10;
    --card-shadow: 0 1px 2px rgba(18, 22, 29, .05);
    --press: #E4E8EE;
    --lift: none;

    /* the label that belongs on a fill — see :root (aurora-2) */
    --on-brand: #FFFFFF;        /* 6.37:1 */
    --on-up: #FFFFFF;           /* 4.60:1 */
    --on-down: #FFFFFF;         /* 4.93:1 */
    --on-danger: #FFFFFF;       /* 5.29:1 */
}

/* ══════════════════════════════════════════════════════════════════════════
   THE SKIN ITSELF

   Structural CSS (app.css) reads the tokens above and is not touched. What
   follows is aurora's own component layer — the classes its own templates
   introduce, plus the handful of shared components whose SHAPE differs here.

   Every class below is one an aurora template actually uses. An earlier cut of
   this file styled a `.a-board__flag` and a `.a-feature__mark` that no template
   ever rendered, which is a declaration nobody can see being wrong.
   ══════════════════════════════════════════════════════════════════════════ */

body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Plex has a taller x-height than Inter; headings tighten rather than grow. */
h1, h2, h3 { letter-spacing: -.02em; }

/* ── shared components whose SHAPE differs on this skin ───────────────── */

/*
 * THE PRIMARY BUTTON'S LABEL IS PER MODE, AND THAT IS A MEASUREMENT.
 *
 * app.css puts a white label on --brand, which is right for an indigo or a
 * cyan brand and wrong for a yellow one. carbon already overrides it with a
 * dark literal for the same reason. One literal is not enough here, because
 * aurora's brand INVERTS across the ☾/☀ toggle: it is a bright yellow in dark
 * mode and a dark brown in light mode, so a single label colour fails one of
 * them. Measured — dark label: 10.18:1 on the dark brand, 3.04:1 on the light
 * one. The light mode keeps white, at 6.37:1.
 */
.btn { font-weight: 600; }
/* `.btn--primary`'s label was a per-skin literal here, and a second one under
   `[data-theme=light]` because this skin's brand INVERTS across the toggle.
   Both are gone: `--on-brand` carries the same measured values for every fill
   on this skin, so the one button that was fixed and the six that were not are
   now one rule (aurora-2). Only the BORDER stays skin-specific. */
.btn--primary { border-color: var(--brand); }
.btn--primary:hover { border-color: var(--brand-hover); }

.risk-warning {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: var(--muted);
}

/* ── layout scaffolding this skin's own templates use ─────────────────── */
.a-wrap { width: min(1240px, 100% - 40px); margin-inline: auto; }

.a-eyebrow {
    color: var(--brand);
    letter-spacing: .12em;
    text-transform: uppercase;
    font-size: 11px;
    font-weight: 700;
    margin: 0;
}

.a-lead { color: var(--muted); font-size: 15px; line-height: 1.6; margin: 8px 0 0; max-width: 62ch; }

.a-section { padding: 54px 0; border-top: 1px solid var(--line-soft); }
.a-section__head { margin-bottom: 26px; }
.a-section__head h2 { margin: 8px 0 0; font-size: clamp(21px, 2.4vw, 27px); }

/* ── chrome bar ───────────────────────────────────────────────────────── */
.a-top {
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    position: sticky;
    top: 0;
    z-index: 40;
}

.a-top__inner {
    width: min(1240px, 100% - 40px);
    margin-inline: auto;
    height: 58px;
    display: flex;
    align-items: center;
    gap: 26px;
}

.a-top__tools { display: flex; align-items: center; gap: 8px; margin-left: auto; }

.a-brand { display: inline-flex; align-items: center; gap: 9px; text-decoration: none; color: var(--text); }
.a-brand__mark { flex: none; }
.a-brand__word { font-weight: 400; letter-spacing: .06em; font-size: 16px; }
.a-brand__word b { font-weight: 700; color: var(--brand); }

.a-nav { display: flex; align-items: center; gap: 20px; font-size: 14px; min-width: 0; }

.a-nav a {
    color: var(--muted);
    text-decoration: none;
    font-weight: 500;
    padding: 18px 0;
    border-bottom: 2px solid transparent;
    white-space: nowrap;
    transition: color var(--dur) var(--ease);
}

.a-nav a:hover { color: var(--text); }
.a-nav a[aria-current] { color: var(--brand); border-bottom-color: var(--brand); }
.a-nav .is-unrouted { color: var(--faint); white-space: nowrap; }

/*
 * The feed pill reads $priceState, the server's own verdict. Three states, so
 * there are three rules — a pill with one appearance would be decoration.
 */
.a-feed {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    font-size: 11px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--faint);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    padding: 3px 10px;
    white-space: nowrap;
}

.a-feed b { font-weight: 700; }
.a-feed--live b { color: var(--up); }
.a-feed--stale b { color: var(--warn); }
.a-feed--awaiting b { color: var(--faint); }

/* ── the ticker rail — real poller data, never a marquee of invented rows ─ */
.a-rail {
    border-block: 1px solid var(--line);
    background: var(--panel-2);
    overflow-x: auto;
    scrollbar-width: none;
}

.a-rail::-webkit-scrollbar { display: none; }

.a-rail__inner {
    width: min(1240px, 100% - 40px);
    margin-inline: auto;
    display: flex;
    align-items: center;
    gap: 26px;
    padding: 10px 0;
    white-space: nowrap;
}

.a-rail__state {
    font-size: 10px;
    letter-spacing: .08em;
    text-transform: uppercase;
    font-weight: 700;
    border: 1px solid var(--line);
    border-radius: 3px;
    padding: 2px 7px;
    flex: none;
}

.a-rail__state--live { color: var(--up); border-color: var(--up); }
.a-rail__state--stale { color: var(--warn); border-color: var(--warn); }
.a-rail__state--awaiting { color: var(--faint); }

.a-rail__item { display: inline-flex; align-items: baseline; gap: 8px; font-size: 13px; flex: none; }
.a-rail__sym { color: var(--muted); font-weight: 600; }

/* A fixed width so a symbol moving between quoted and not reflows nothing. */
.a-rail__px {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    color: var(--text);
    min-width: 72px;
    text-align: right;
}

/* ── hero ─────────────────────────────────────────────────────────────── */
.a-hero { border-bottom: 1px solid var(--line-soft); }

.a-hero__inner {
    width: min(1240px, 100% - 40px);
    margin-inline: auto;
    display: grid;
    grid-template-columns: 1.05fr .95fr;
    gap: 44px;
    align-items: center;
    padding: 60px 0 48px;
}

.a-hero h1 { font-size: clamp(30px, 4.2vw, 44px); line-height: 1.1; font-weight: 700; margin: 12px 0; }
.a-hero__lead { color: var(--muted); font-size: 16px; line-height: 1.6; max-width: 52ch; margin: 0; }
.a-hero__cta { display: flex; gap: 12px; margin-top: 26px; flex-wrap: wrap; }
.a-hero__note { color: var(--faint); font-size: 13px; margin: 16px 0 0; }

.a-trust {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 30px;
    margin-top: 28px;
    padding-top: 22px;
    border-top: 1px solid var(--line-soft);
    font-size: 12px;
    color: var(--muted);
}

.a-trust > div { display: flex; flex-direction: column; gap: 3px; }
.a-trust b { font-size: 18px; color: var(--text); font-weight: 600; }
.a-trust .balance { font-size: 18px; }

/* ── the quote board — OUR prices, with OUR staleness vocabulary ───────── */
.a-board {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 6px 6px 2px;
}

/*
 * The head and the rows share ONE track definition, so the columns line up by
 * construction rather than by two authors keeping in step — the terminal-fit
 * lesson, where a heading grid and a row grid could never agree.
 */
.a-board__head,
.a-board__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 92px 92px;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
}

.a-board__head {
    font-size: 10px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--faint);
    padding-bottom: 6px;
}

.a-board__row { border-top: 1px solid var(--line-soft); border-radius: var(--radius-sm); }
.a-board__sym { min-width: 0; }
.a-board__sym b { display: block; font-weight: 600; font-size: 13px; }
.a-board__sym small { display: block; font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.a-board__px {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-size: 13px;
}

/* An unquotable row keeps the row's height, so the board does not jump when a
   feed goes quiet. It spans both figure columns because there is no figure. */
.a-board__await {
    grid-column: 2 / -1;
    font-size: 11px;
    color: var(--faint);
}

.a-board__note { margin: 10px 4px 8px; font-size: 11px; color: var(--faint); }

/* ── feature cards ────────────────────────────────────────────────────── */
.a-features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }

.a-feature {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 24px;
}

.a-feature .card__title { margin: 0 0 8px; font-size: 17px; }
.a-feature .card__body { margin: 0; color: var(--muted); font-size: 14px; line-height: 1.6; }

/* ── footer ───────────────────────────────────────────────────────────── */
.a-foot { background: var(--panel-2); border-top: 1px solid var(--line); margin-top: 40px; }
.a-foot__inner { width: min(1240px, 100% - 40px); margin-inline: auto; padding: 44px 0 22px; }

.a-foot__grid {
    display: grid;
    grid-template-columns: 1.6fr repeat(3, minmax(0, 1fr));
    gap: 30px;
    margin-bottom: 32px;
}

.a-foot__col h3 {
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--faint);
    margin: 0 0 12px;
}

.a-foot__col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.a-foot__col a { color: var(--muted); text-decoration: none; font-size: 14px; }
.a-foot__col a:hover { color: var(--brand); }
.a-foot__about { font-size: 13px; line-height: 1.6; margin: 12px 0 0; max-width: 40ch; }

.a-foot__base {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 26px;
    padding-top: 18px;
    border-top: 1px solid var(--line-soft);
    font-size: 12px;
    color: var(--faint);
}

@media (max-width: 940px) {
    .a-hero__inner { grid-template-columns: 1fr; gap: 28px; padding-top: 40px; }
    .a-features { grid-template-columns: 1fr; }
    .a-foot__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .a-nav { display: none; }
}

/*
 * At phone width the chrome bar WRAPS rather than losing a control.
 *
 * Measured at 390px: brand, language, appearance, Log in and the register CTA
 * need 544px in one row, so the register button was drawn 154px past the right
 * edge and the document scrolled sideways. Every alternative hides something a
 * visitor came for — the sign-in link, or the language switcher on a site whose
 * whole premise is six locales — so the row becomes two rows instead, and the
 * bar stops being sticky there, because a two-row sticky header on a 844px-tall
 * screen is a tenth of the viewport permanently spent on chrome.
 *
 * The nav links are the one thing hidden, and the footer carries every one of
 * them; app.css hides .site-nav at its own breakpoint for the same reason.
 */
@media (max-width: 560px) {
    .a-foot__grid { grid-template-columns: 1fr; }
    .a-feed { display: none; }

    .a-top { position: static; }

    .a-top__inner {
        flex-wrap: wrap;
        height: auto;
        row-gap: 10px;
        padding-block: 10px;
    }

    .a-top__tools { width: 100%; margin-left: 0; justify-content: flex-end; }
}

/* ══════════════════════════════════════════════════════════════════════════
   THE CABINET AND THE TERMINAL (aurora-2)

   APPEARANCE ONLY. There is no aurora override of `app/layout.latte` and
   there should not be: that template is base-only for all three skins, which
   is why the DEMO/LIVE pill, the risk-warning partial and the notification
   bell exist ONCE and cannot drift per skin. §11's honesty is a property of
   there being a single copy, and a 209-line duplicate would put that at the
   mercy of somebody keeping two files in step. A skin changes how the product
   looks; it does not restate what the product says.

   Everything below is a value this skin already owns — its tokens, and the
   chrome language its own public front established (`.a-top`, `.a-nav`,
   `.a-feed`). No colour, radius or family is written down.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── the cabinet's top chrome, in the public front's own vocabulary ───────
   ITS COLOURS APPLY EVERYWHERE; ITS GEOMETRY IS SCOPED TO THE DESKTOP BAR,
   and that split is a live defect this skin was shipping (mobile-A).

   theme.css loads AFTER cabinet.css, so a skin's `.cab-header` beats the
   structural sheet's at equal specificity — INCLUDING the one inside a media
   query, because a media query adds no specificity. `height: 58px` was
   therefore in force at every width, while cabinet.css's mobile rule wrapped
   the header into three rows: measured at 390px, aurora's header BOX computed
   58px while its children ran to y=187, so the nav and the DEMO pill were
   painted 129px outside their own header, over "Welcome back" and the
   verification banner beneath. That is the reported "the header overlaps
   itself", and it was aurora-only — nuvo and carbon wrap to an honest 143px,
   which is why measuring one skin missed it (§16 rule 139).

   58px, 26px of gap and the 19px-padded underline tabs below are all values
   for a bar with seven entries in it. On a phone the entries are a fixed
   bottom bar and the header is one 56px row, so these describe a layout that
   is not there — hence `min-width`, not a scoping of convenience.

   The BACKGROUND and the RULE are not scoped: they are what makes this
   aurora, at every width. */
.cab-header {
    background: var(--bg);
    border-bottom: 1px solid var(--line);
}

@media (min-width: 861px) {
    .cab-header {
        height: 58px;
        padding-inline: 20px;
        gap: 26px;
    }
}

.cab-brand img { height: 22px; }

/* UNDERLINE TABS, not pill backgrounds. `.a-nav` marks the current page with
   a brand-coloured label over a brand-coloured bottom rule, and the cabinet
   is the same navigation on a darker bar — so it reads as one site rather
   than two products that happen to share a logo.

   DESKTOP ONLY, for the reason the bar's height is: 19px of vertical padding
   and a 14px label describe an entry in a horizontal strip inside a 58px bar.
   Below 860px the seven entries are a fixed bottom bar of 9.5px labels under
   their icons, and these values would break it exactly as `height: 58px`
   broke the header. */
@media (min-width: 861px) {
    .cab-nav { gap: 20px; }

    .cab-nav__item {
        padding: 19px 0;
        border: 0;
        border-bottom: 2px solid transparent;
        border-radius: 0;
        font-size: 14px;
        color: var(--muted);
        transition: color var(--dur) var(--ease);
    }

    a.cab-nav__item:hover { color: var(--text); background: none; }

    .cab-nav__item.is-active {
        color: var(--brand);
        background: none;
        border-bottom-color: var(--brand);
        font-weight: 600;
    }
}

/* Not a link, at any width. */
.cab-nav__item--soon { color: var(--faint); }

/* The DEMO/LIVE pill takes `.a-feed`'s shape — the public front's own state
   pill. Its COLOUR still comes from `accounts.type` through cabinet.css; this
   changes what it looks like and never what it says. */
.cab-pill {
    border-radius: var(--radius-pill);
    font-size: var(--fs-fig-sm);
    letter-spacing: .06em;
    padding: 3px 10px;
}

/* Desktop only, same reason: the mobile header is one 56px row with a tighter
   cluster, and 16px here would clobber it from a later stylesheet. */
@media (min-width: 861px) {
    .cab-acct { gap: 16px; }
}

.cab-avatar { border-radius: var(--radius-pill); }

.cab-menu > summary {
    border-radius: var(--radius-sm);
    border-color: transparent;
}

.cab-menu > summary:hover,
.cab-menu[open] > summary { background: var(--panel-3); }

.cab-menu__panel {
    border-radius: var(--radius);
    border-color: var(--line);
}

/* ── surfaces: flat, bordered, exchange-shaped ──────────────────────────── */
.card, .cab-head, .panel {
    border-radius: var(--radius);
    border-color: var(--line-soft);
}

/* `--lift` is `none` on this skin by decision (aurora-1): an exchange surface
   does not float. The border does the separating. */
a.card:hover, .card--link:hover { box-shadow: none; border-color: var(--line); }

/* ── THE TERMINAL, ALL FOUR REGIONS ─────────────────────────────────────
   browse (left) · chart · ticket · watchlist (right). The fourth is not a
   detail: term-tabs added the browse panel, and a skin that treated three of
   them would leave exactly one bare — which is the defect the bare-base pass
   exists about, reintroduced by the skin meant to fix it. */
.term-body { background: var(--bg); }

.term-cat, .term-watch, .term-chart, .term-ticket {
    background: var(--panel);
    border-right-color: var(--line-soft);
}

/* The account strip reads as one continuous bar, as the public chrome does. */
.term-strip {
    background: var(--bg);
    border-bottom-color: var(--line);
}

.term-strip .term-acct__cell {
    background: none;
    border-right-color: var(--line-soft);
}

/* Section heads: the eyebrow treatment this skin uses everywhere else. */
.term-watch__head h2,
.term-cat__head h2 {
    font-size: var(--fs-fig-sm);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--faint);
    font-weight: 700;
}

.term-watch__cols {
    background: var(--panel-2);
    border-bottom-color: var(--line-soft);
}

/* Rows sit on the panel and separate by hairline, not by radius. */
.wl-row, .cat-row { border-bottom-color: var(--line-soft); }
.wl-row--sel, .cat-row--sel { background: var(--brand-dim); border-left-color: var(--brand); }

/* The browse panel's tabs are the same underline idiom as the cabinet nav,
   at the panel's scale — one navigation language on one screen. */
.term-cat__tabs { border-bottom-color: var(--line-soft); }

.term-cat__tab {
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    padding: 6px 2px;
    margin-right: 14px;
}

.term-cat__tab:hover { background: none; color: var(--text); }

.term-cat__tab--on {
    background: none;
    color: var(--brand);
    border-bottom-color: var(--brand);
}

/* ── the ticket ─────────────────────────────────────────────────────────
   BUY and SELL keep the platform's own semantics (§11 green/red); what this
   changes is the surface they sit on. The place button's LABEL is
   `var(--on-brand)` from Block A — on this skin's yellow that is a dark ink
   at 9.55:1, where the literal white it replaced measured 1.90:1. */
.term-ticket { background: var(--panel); }

.ba-btn { border-radius: var(--radius-sm); }

.place-btn {
    border-radius: var(--radius-sm);
    font-weight: 700;
    letter-spacing: .02em;
}

.vol-stepper input, .term-ticket .plain {
    background: var(--panel-2);
    border-color: var(--line);
    border-radius: var(--radius-sm);
}

/* ── the dock ───────────────────────────────────────────────────────────── */
.term-dock { background: var(--panel); border-top-color: var(--line); }
.term-dock__tab--on { color: var(--brand); }

/* ── the status bar ─────────────────────────────────────────────────────── */
.term-foot { background: var(--bg); border-top-color: var(--line); }

/* ── @font-face — IBM Plex, taken by bin/vendor_fonts.php ──────────────────
 * NO CDN, EVER (§8): a CDN request discloses the visitor's IP address to a
 * third party (LG München I, 3 O 17493/20). These files are committed, and
 * `php bin/vendor_fonts.php --check` verifies them against PROVENANCE.md.
 *
 * They live HERE rather than in app.css because a family is a theme value
 * (§6) and because a visitor on nuvo or carbon should not even parse them.
 *
 * IBM Plex Sans is variable, so one file per subset covers 400-600. IBM Plex
 * Mono is not, so it costs a file per weight per subset. Only latin and
 * latin-ext are vendored — between them they cover every locale in LANGS —
 * and the unicode-range is what makes latin-ext free for a page without one.
 *
 * No ?v= on these URLs, so they byte-match the <link rel=preload> in this
 * skin's layout; a mismatch downloads each preloaded face twice. A font file
 * is immutable — a new cut gets a new filename.
 * ------------------------------------------------------------------------- */

@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('fonts/ibm-plex-sans-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF
}

@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('fonts/ibm-plex-sans-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-600-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('fonts/ibm-plex-mono-600-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD
}

/* The way from the featured board to the whole catalogue (browse-reorg). */
.a-board__more { margin-top: 18px; }
