/* --- Self-hosted webfonts -------------------------------------------------
 * Downloaded from Google Fonts once and committed; no third-party request is
 * made at runtime. Rationale (CLAUDE.md §16, phase 1 font amendment):
 *   - GDPR: LG München I, 3 O 17493/20 held that passing a visitor IP to
 *     Google Fonts without consent is unlawful. We target DE and IT.
 *   - One fewer connection able to block first paint. In the phase 0 build the
 *     render-blocking CDN link pushed observed FCP from 0.2s to 13.8s whenever
 *     fonts.googleapis.com was unreachable.
 *   - The build no longer depends on a CDN being up.
 *
 * All three families are variable fonts, so ONE file per family per subset
 * covers every weight we use — hence the font-weight ranges below.
 *
 * These URLs carry no ?v= cache-bust so they byte-match the <link rel=preload>
 * in the layout; a mismatch downloads each preloaded face twice. Font files are
 * immutable — a new cut gets a new filename.
 * ------------------------------------------------------------------------- */

@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 500 700;
    font-display: swap;
    src: url('../fonts/space-grotesk-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: 'Space Grotesk';
    font-style: normal;
    font-weight: 500 700;
    font-display: swap;
    src: url('../fonts/space-grotesk-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: 'Inter';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('../fonts/inter-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: 'Inter';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('../fonts/inter-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: 'JetBrains Mono';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('../fonts/jetbrains-mono-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: 'JetBrains Mono';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('../fonts/jetbrains-mono-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;
}

/* ==========================================================================
   NUVOBITS — structural CSS (theme-agnostic)

   This file must never contain a literal colour, font family or brand value.
   Everything visual comes from a token defined by the active theme.css.

   Token contract every theme must define:
     --bg --panel --panel-2 --panel-3 --line --line-soft
     --text --muted --faint
     --brand --brand-hover --brand-dim --gold
     --up --up-dim --down --down-dim --warn
     --row-hover --card-shadow --radius --radius-sm
     --ui --display --mono
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--ui);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--display); line-height: 1.15; margin: 0; font-weight: 600; }
p { margin: 0; }
img { max-width: 100%; height: auto; display: block; }

/* One rule: the transition used to live 1,000 lines below, as a second `a {}`. */
a { color: var(--brand); text-decoration: none; transition: color var(--dur) var(--ease); }
a:hover { color: var(--brand-hover); }

/* Links inside RUNNING TEXT are underlined, because against muted or faint body
   copy the brand colour alone does not reach the 3:1 that WCAG 1.4.1 requires
   to distinguish a link from its surroundings (axe: link-in-text-block).
   Navigation links are exempt: they are not embedded in a text block. */
.muted a,
.faint a,
.lead a,
.prose p a,
.card__body a,
.legal-list a,
.consent__text a,
.footer-base a,
.field__hint a,
.translation-notice a,
.callout p a {
    text-decoration: underline;
    text-underline-offset: 2px;
}

/*
 * THE GLOBAL FOCUS RING — the floor, not the ceiling.
 *
 * Every interactive element in the client realm inherits this, so a keyboard
 * user can always see where they are. Individual components may tighten the
 * offset (a row inside a scroller uses a negative one so the ring is not
 * clipped), never remove it.
 *
 * The colour is measured, not chosen: --focus-ring clears WCAG 2.4.11's 3:1
 * against every surface it meets in both themes — 4.51:1 on nuvo's hover tint,
 * 9.43:1 on carbon's. The values are in the theme layer so the ring cannot go
 * one theme's way and not the other's.
 */
:focus-visible {
    outline: var(--focus-ring-w) solid var(--focus-ring);
    outline-offset: var(--focus-offset);
    border-radius: 3px;
}

/* ── Layout primitives ─────────────────────────────────────────────────── */

.container {
    width: 100%;
    max-width: 1160px;
    margin-inline: auto;
    padding-inline: 24px;
}

.section { padding-block: 88px; }
.section--tight { padding-block: 56px; }
.section + .section { border-top: 1px solid var(--line-soft); }

.eyebrow {
    font-family: var(--mono);
    font-size: 12px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--brand);
    margin: 0 0 14px;
}

.section-head { max-width: 640px; margin-bottom: 44px; }
.section-head h2 { font-size: clamp(26px, 3.4vw, 36px); margin-bottom: 12px; }
.lead { color: var(--muted); font-size: 17px; }

/* Visually hidden but present for assistive tech — used where an accessible
   name must contain the visible text (WCAG 2.5.3).

   `.sr-only` IS THE SAME THING UNDER A THIRD NAME, and it is here because it
   was in use and defined nowhere (§17 item 23e). `terminal.latte` puts it on
   the two column headings that label the dock's close and cancel buttons — a
   heading a screen reader needs and a sighted client does not — and with no
   rule behind it the words simply RENDERED. Measured before this: "Close" at
   38.5x14 inside a 188.8px `<th>` on a 1366px desktop, "Cancel" at 46.2x14
   inside a 234.7px one.

   So this is a visible change and it is an intended one: two words leave the
   dock's header row. It is declared as a shared selector rather than as a
   fourth copy of the same six declarations — `.visually-hidden` below is a
   fifth spelling still, and collapsing all three is a rename across templates
   that is not this phase's to make.

   NOT `display: none`: that removes the element from the accessibility tree
   as well as the page, which would delete the very labels this exists to
   provide. The clip-rect pattern keeps them readable and unseen. */
.vh,
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ── Skip link ─────────────────────────────────────────────────────────── */

.skip-link {
    position: absolute;
    left: 12px;
    top: -60px;
    z-index: 100;
    background: var(--panel);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 10px 16px;
    transition: top .15s ease;
}
.skip-link:focus { top: 12px; }

/* ── Header ────────────────────────────────────────────────────────────── */

.site-header {
    position: sticky;
    top: 0;
    z-index: 40;
    background: color-mix(in srgb, var(--panel) 88%, transparent);
    backdrop-filter: saturate(1.4) blur(10px);
    border-bottom: 1px solid var(--line-soft);
}

.site-header__inner {
    display: flex;
    align-items: center;
    gap: 28px;
    min-height: 66px;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-family: var(--display);
    font-weight: 700;
    font-size: 19px;
    letter-spacing: -.01em;
    color: var(--text);
}
.brand:hover { color: var(--text); }
.brand__mark { width: 26px; height: 26px; }

.site-nav { display: flex; gap: 22px; margin-right: auto; }
.site-nav a { color: var(--muted); font-size: 14.5px; font-weight: 500; }
.site-nav a:hover { color: var(--text); }

.header-tools { display: flex; align-items: center; gap: 10px; }

/* ── The public header's auth block (ui-bugs-1) ──────────────────────────
   Structural only: every colour, radius and family here is a token, because
   §6 puts those in the skin and this rule is read by all three. */
.header-auth { display: flex; align-items: center; gap: 10px; }
.header-auth__avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 50%;
    background: var(--brand-dim); color: var(--brand);
    font-size: 10.5px; font-weight: 700; letter-spacing: .02em;
    flex: none;
}
.header-auth__name {
    font-size: 12.5px; color: var(--muted);
    max-width: 12ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The NAME is what gives way on a narrow header, never the way back into the
   cabinet: the avatar still says who is signed in and the button is the thing
   the client came to press. Same reasoning as the rail's descriptor giving way
   before the instrument code (§16 terminal fit). */
@media (max-width: 720px) { .header-auth__name { display: none; } }

/* ── Controls ──────────────────────────────────────────────────────────── */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    padding: 10px 18px;
    font: inherit;
    font-size: 14.5px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--dur) var(--ease),
                border-color var(--dur) var(--ease),
                color var(--dur) var(--ease),
                transform var(--dur) var(--ease);
}

.btn--primary { background: var(--brand); color: var(--on-brand); }
.btn--primary:hover { background: var(--brand-hover); color: var(--on-brand); }

.btn--ghost { background: transparent; color: var(--text); border-color: var(--line); }
.btn--ghost:hover { background: var(--panel-3); color: var(--text); }

.btn--quiet { background: transparent; color: var(--muted); padding-inline: 10px; }
.btn--quiet:hover { color: var(--text); }

/*
 * PRESSED. One pixel of travel and nothing else — enough to feel, not enough
 * to notice. The redesign's discipline is that boldness is spent in one place
 * (the terminal) and everything around it stays quiet.
 */
.btn:active:not(:disabled) { transform: translateY(1px); }

/*
 * DISABLED, and never by opacity alone.
 *
 * Three signals: the control dims, the cursor says it cannot be used, and the
 * hover affordance is REMOVED — a disabled button that still lightens under
 * the pointer is a button that looks like it might work. The gated funds
 * screens (P6) are the case this matters most for: they are honest
 * placeholders, and they have to read as placeholders.
 *
 * --disabled-o is 0.7 rather than the conventional 0.5 so the label stays
 * legible; a client has to be able to read what is disabled to know what it
 * says.
 */
.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: var(--disabled-o);
    cursor: not-allowed;
    filter: saturate(.45);
}

.btn:disabled:hover,
.btn[aria-disabled="true"]:hover {
    background: inherit;
    border-color: inherit;
    color: inherit;
}

.btn:disabled:active,
.btn[aria-disabled="true"]:active { transform: none; }

.btn--lg { padding: 14px 24px; font-size: 15.5px; }

.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    padding: 0;
}
.icon-btn:hover { color: var(--text); background: var(--panel-3); }
.icon-btn svg { width: 17px; height: 17px; }

/* Locale switcher: <details>, so it needs no JavaScript and every locale root
   stays a crawlable link. */
.lang-switch { position: relative; }

.lang-switch > summary {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    list-style: none;
    cursor: pointer;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 8px 12px;
}
.lang-switch > summary::-webkit-details-marker { display: none; }
.lang-switch > summary:hover { color: var(--text); }
.lang-switch > summary::after {
    content: "";
    width: 6px;
    height: 6px;
    border-right: 1.5px solid var(--faint);
    border-bottom: 1.5px solid var(--faint);
    transform: translateY(-2px) rotate(45deg);
}

.lang-switch ul {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    z-index: 50;
    min-width: 150px;
    margin: 0;
    padding: 6px;
    list-style: none;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    box-shadow: var(--card-shadow);
}
.lang-switch ul a {
    display: block;
    padding: 7px 10px;
    border-radius: 4px;
    color: var(--muted);
    font-size: 14px;
}
.lang-switch ul a:hover { background: var(--panel-3); color: var(--text); }
.lang-switch ul a[aria-current] { color: var(--brand); font-weight: 600; }

/* A CTA whose page is not routed yet: same weight, no fake link. */
.is-pending { cursor: default; opacity: .55; }

/* ── Cards & tables ────────────────────────────────────────────────────── */

.card {
    background: var(--panel);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    box-shadow: var(--card-shadow);
    padding: 26px;
}

.card__title { font-size: 18px; margin-bottom: 10px; }
.card__body { color: var(--muted); font-size: 15px; }

.grid-3 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 20px;
}

.table-wrap {
    background: var(--panel);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    box-shadow: var(--card-shadow);
    overflow-x: auto;
}

table.data {
    width: 100%;
    border-collapse: collapse;
    font-size: 14.5px;
}

table.data th,
table.data td {
    text-align: left;
    padding: 13px 20px;
    border-bottom: 1px solid var(--line-soft);
    white-space: nowrap;
}

table.data thead th {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--faint);
    font-weight: 500;
}

table.data tbody tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--row-hover); }

.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.sym { font-family: var(--mono); font-weight: 600; letter-spacing: .01em; }
.muted { color: var(--muted); }
.faint { color: var(--faint); }
.balance { font-family: var(--mono); color: var(--gold); font-weight: 600; }

.tag {
    display: inline-block;
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--muted);
    background: var(--panel-3);
    border-radius: 4px;
    padding: 3px 8px;
}

/* ── Footer ────────────────────────────────────────────────────────────── */

.site-footer {
    background: var(--panel-2);
    border-top: 1px solid var(--line-soft);
    padding-block: 56px 28px;
}

.footer-grid {
    display: grid;
    grid-template-columns: 2fr repeat(3, 1fr);
    gap: 40px;
    margin-bottom: 44px;
}

.footer-col h3 {
    font-family: var(--ui);
    font-size: 12px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--faint);
    margin-bottom: 14px;
}
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.footer-col a { color: var(--muted); font-size: 14.5px; }
.footer-col a:hover { color: var(--text); }

.risk-warning {
    border: 1px solid var(--line);
    border-left: 3px solid var(--warn);
    border-radius: var(--radius-sm);
    background: var(--panel);
    padding: 18px 20px;
    margin-bottom: 24px;
}
.risk-warning h3 {
    font-family: var(--ui);
    font-size: 12px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--warn);
    margin-bottom: 8px;
}
.risk-warning p { color: var(--muted); font-size: 13px; line-height: 1.65; }

.footer-base {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 24px;
    justify-content: space-between;
    align-items: center;
    padding-top: 22px;
    border-top: 1px solid var(--line-soft);
    color: var(--faint);
    font-size: 13px;
}

/* ── Inner-page header & breadcrumbs ───────────────────────────────────── */

.page-head {
    padding-block: 48px 44px;
    background: var(--panel-2);
    border-bottom: 1px solid var(--line-soft);
}
.page-head h1 {
    font-size: clamp(30px, 4vw, 44px);
    letter-spacing: -.02em;
    margin-bottom: 14px;
    max-width: 22ch;
}
.page-head__lead { color: var(--muted); font-size: 17px; max-width: 62ch; }

.breadcrumbs { margin-bottom: 18px; }
.breadcrumbs ol {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 13px;
    color: var(--faint);
}
.breadcrumbs li + li::before { content: "/"; margin-right: 8px; color: var(--faint); }
.breadcrumbs a { color: var(--muted); }
.breadcrumbs a:hover { color: var(--text); }
.breadcrumbs [aria-current] { color: var(--faint); }

/* ── Anchor nav ────────────────────────────────────────────────────────── */

.anchor-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 44px;
}
.anchor-nav a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 8px 14px;
    font-size: 14px;
    font-weight: 500;
    color: var(--muted);
}
.anchor-nav a:hover { background: var(--panel-3); color: var(--text); }
.anchor-nav__count { font-family: var(--mono); font-size: 11px; color: var(--faint); }

.market-group { scroll-margin-top: 90px; }
.market-group + .market-group { margin-top: 56px; }

/* ── Screenshot frame ──────────────────────────────────────────────────── */

.shot {
    margin: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--card-shadow);
    background: var(--panel);
}
.shot img { width: 100%; height: auto; display: block; }

/* ── Lists ─────────────────────────────────────────────────────────────── */

.tick-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 12px 28px;
    list-style: none;
    margin: 28px 0 0;
    padding: 0;
}
.tick-list li {
    position: relative;
    padding-left: 26px;
    color: var(--muted);
    font-size: 15px;
}
.tick-list li::before {
    content: "";
    position: absolute;
    left: 4px;
    top: .55em;
    width: 8px;
    height: 8px;
    border-radius: 2px;
    background: var(--brand);
}

.spec-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    list-style: none;
    margin: 24px 0 0;
    padding: 0;
}
.spec-strip li {
    font-family: var(--mono);
    font-size: 12px;
    letter-spacing: .02em;
    color: var(--muted);
    background: var(--panel-3);
    border-radius: var(--radius-sm);
    padding: 8px 13px;
}

.note-list { margin: 0; }
.note-list__row {
    display: grid;
    grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
    gap: 12px 32px;
    padding: 18px 0;
    border-bottom: 1px solid var(--line-soft);
}
.note-list__row:first-child { border-top: 1px solid var(--line-soft); }
.note-list dt { font-weight: 600; font-size: 15px; margin: 0; }
.note-list dd { margin: 0; color: var(--muted); font-size: 15px; }

/* ── Feature rows (platform tour) ──────────────────────────────────────── */

.feature-rows { border-top: 1px solid var(--line-soft); }
.feature-row {
    display: grid;
    grid-template-columns: 56px minmax(0, 260px) minmax(0, 1fr);
    gap: 24px 32px;
    align-items: start;
    padding: 28px 0;
    border-bottom: 1px solid var(--line-soft);
}
.feature-row__index { font-size: 12px; color: var(--brand); padding-top: 4px; }
.feature-row__title { font-size: 19px; }
.feature-row__body { color: var(--muted); font-size: 15px; }

/* ── Prose & callouts ──────────────────────────────────────────────────── */

.prose { max-width: 68ch; }
.prose__block + .prose__block { margin-top: 38px; }
.prose h2 { font-size: 23px; margin-bottom: 12px; }
.prose p { color: var(--muted); font-size: 16.5px; }

.callout {
    margin-top: 42px;
    border: 1px solid var(--line);
    border-left: 3px solid var(--brand);
    border-radius: var(--radius-sm);
    background: var(--panel);
    padding: 22px 24px;
}
.callout--warn { border-left-color: var(--warn); }
.callout__title { font-size: 17px; margin-bottom: 8px; }
.callout p { color: var(--muted); font-size: 15px; }

/* ── FAQ ───────────────────────────────────────────────────────────────── */

.faq-list {
    border-top: 1px solid var(--line-soft);
    max-width: 78ch;
}
.faq-item { border-bottom: 1px solid var(--line-soft); }
.faq-item > summary {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    list-style: none;
    cursor: pointer;
    padding: 20px 0;
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after {
    content: "";
    flex: none;
    margin-left: auto;
    margin-top: 7px;
    width: 8px;
    height: 8px;
    border-right: 1.6px solid var(--faint);
    border-bottom: 1.6px solid var(--faint);
    transform: rotate(45deg);
    transition: transform .15s ease;
}
.faq-item[open] > summary::after { transform: rotate(-135deg); }
.faq-item__q { font-family: var(--ui); font-size: 16.5px; font-weight: 600; margin: 0; }
.faq-item__a { padding-bottom: 22px; max-width: 70ch; }
.faq-item__a p { color: var(--muted); font-size: 15.5px; }

/* ── Legal documents ───────────────────────────────────────────────────── */

.translation-notice {
    border: 1px solid var(--line);
    border-left: 3px solid var(--brand);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
    padding: 16px 18px;
    margin-bottom: 30px;
}
.translation-notice p { color: var(--muted); font-size: 14.5px; }
.translation-notice__en {
    margin-top: 6px;
    color: var(--faint);
    font-style: italic;
}

.legal-summary { margin-top: 0; margin-bottom: 30px; }
.legal-summary p + p { margin-top: 10px; }

.legal-updated {
    font-family: var(--mono);
    font-size: 12.5px;
    margin-bottom: 34px;
}

.prose__block p + p { margin-top: 14px; }
.prose__block[id] { scroll-margin-top: 90px; }

.legal-list {
    margin: 14px 0 0;
    padding-left: 20px;
    color: var(--muted);
    font-size: 16px;
}
.legal-list li { margin-bottom: 8px; }
.legal-list li::marker { color: var(--faint); }

/* ── Closing CTA ───────────────────────────────────────────────────────── */

.cta-band {
    background: var(--panel-2);
    border-top: 1px solid var(--line-soft);
    padding-block: 56px;
}
.cta-band__inner {
    display: flex;
    flex-wrap: wrap;
    gap: 26px 40px;
    align-items: center;
    justify-content: space-between;
}
.cta-band h2 { font-size: clamp(22px, 3vw, 30px); margin-bottom: 10px; }
.cta-band p { color: var(--muted); max-width: 52ch; }
.cta-band__actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* ── Forms ─────────────────────────────────────────────────────────────── */

.form { display: grid; gap: 18px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

.field { display: grid; gap: 6px; }
.field__label { font-size: 13.5px; font-weight: 600; color: var(--text); }
.field__hint { font-size: 12.5px; color: var(--faint); }
.field__input,
.field__textarea {
    width: 100%;
    font: inherit;
    font-size: 15px;
    color: var(--text);
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 11px 13px;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.field__textarea { min-height: 150px; resize: vertical; }
.field__input:focus,
.field__textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-dim);
}
.field--invalid .field__input,
.field--invalid .field__textarea { border-color: var(--down); }
.field__error {
    font-size: 13px;
    color: var(--down);
    font-weight: 500;
}

.check { display: flex; gap: 10px; align-items: flex-start; font-size: 14.5px; color: var(--muted); }
.check input { margin-top: 3px; flex: none; width: 16px; height: 16px; accent-color: var(--brand); }

.btn--block { width: 100%; }

/* The honeypot. Never shown, never announced, never reachable by keyboard —
   a person cannot fill it in, so anything that does is not a person. */
.hp {
    position: absolute !important;
    left: -9999px !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ── Flash messages ────────────────────────────────────────────────────── */

.flash-stack { display: grid; gap: 10px; margin-bottom: 22px; }
.flash {
    border: 1px solid var(--line);
    border-left: 3px solid var(--brand);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
    padding: 13px 16px;
    font-size: 14.5px;
    color: var(--text);
}
.flash--success { border-left-color: var(--up); }
.flash--error { border-left-color: var(--down); }
.flash--notice { border-left-color: var(--warn); }

/* ── Auth pages ────────────────────────────────────────────────────────── */

.auth-shell {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
    gap: 48px;
    align-items: start;
}
.auth-shell--narrow { grid-template-columns: minmax(0, 520px); justify-content: center; }

.auth-card {
    background: var(--panel);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    box-shadow: var(--card-shadow);
    padding: 34px;
}
.auth-card--centred { text-align: center; }
.auth-card__title { font-size: clamp(24px, 3vw, 32px); margin-bottom: 10px; }
.auth-card__lead { color: var(--muted); font-size: 15.5px; margin-bottom: 26px; }
.auth-card__alt { font-size: 14.5px; color: var(--muted); text-align: center; }
.auth-card__mark {
    width: 54px;
    height: 54px;
    margin: 0 auto 20px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    color: var(--up);
    background: var(--up-dim);
}
.auth-card__mark svg { width: 26px; height: 26px; }

.auth-aside { padding-top: 8px; }
.auth-aside__title { font-size: 17px; margin-bottom: 16px; }
.tick-list--stack { grid-template-columns: 1fr; margin-top: 0; margin-bottom: 28px; }

@media (max-width: 900px) {
    .auth-shell { grid-template-columns: 1fr; gap: 32px; }
    /* RESTATED, because the base rule above it wins otherwise: both carry
       one class of specificity and a media query adds none, so below 900px
       `--narrow` silently stopped being narrow. The `.cab-main--flush`
       shape (mobile-A), found by the gate check written for it. */
    .auth-shell--narrow { grid-template-columns: minmax(0, 520px); }
    .form-row { grid-template-columns: 1fr; }
}

/* ── Error page ────────────────────────────────────────────────────────── */

.error-page { padding-block: 120px; text-align: center; }
.error-page h1 { font-size: clamp(28px, 5vw, 44px); margin-bottom: 14px; }
.error-page p { color: var(--muted); margin-bottom: 26px; }
.error-page .code {
    font-family: var(--mono);
    font-size: 13px;
    letter-spacing: .18em;
    color: var(--faint);
    margin-bottom: 18px;
}

/* ── Responsive ────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
    .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px; }
    .section { padding-block: 60px; }
    /* Same shape: without this a `--tight` section was 60px below 900px —
       LOOSER than the 56px it asks for, and identical to every section
       beside it. Kept proportionally tighter than the default. */
    .section--tight { padding-block: 40px; }
}

@media (max-width: 700px) {
    .site-nav { display: none; }
    .footer-grid { grid-template-columns: 1fr; }
    .container { padding-inline: 18px; }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { transition-duration: .001ms !important; }
}

/* ── Consent banner ────────────────────────────────────────────────────── */

.consent {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 60;
    background: var(--panel);
    border-top: 1px solid var(--line);
    box-shadow: 0 -6px 24px rgba(0, 0, 0, .08);
    padding: 18px 0;
}
.consent__inner {
    width: 100%;
    max-width: 1160px;
    margin-inline: auto;
    padding-inline: 24px;
    display: flex;
    flex-wrap: wrap;
    gap: 18px 40px;
    align-items: center;
    justify-content: space-between;
}
.consent__text { max-width: 64ch; }
.consent__title { font-size: 15px; margin-bottom: 4px; }
.consent__text p { color: var(--muted); font-size: 14px; }
.consent__actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* Underlined, not just coloured: this link sits inside faint footer text, and
   colour alone does not carry 3:1 against its surroundings (WCAG 1.4.1 —
   caught by axe's link-in-text-block). */
.footer-consent-link {
    margin-left: 14px;
    font-size: 13px;
    text-decoration: underline;
    text-underline-offset: 2px;
}

@media (max-width: 700px) {
    .consent__inner { flex-direction: column; align-items: stretch; }
    .consent__actions { justify-content: stretch; }
    .consent__actions .btn { flex: 1; }
}

/* The cabinet's CSS moved to assets/css/cabinet.css in P6 — it is loaded only
   by app/layout.latte. It was costing every public page a measured Lighthouse
   point for rules a landing visitor never uses. */


/* Available to assistive technology, invisible on screen. The ledger table's
   <caption> uses it: a table needs a caption, the page already has a heading. */
.visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ============================================================================
   PRICE STRIP — phase 3
   The quote cell keeps ONE height whether it holds a number or the awaiting
   marker, so a symbol going stale (or coming back) shifts nothing below it.
   That is a CLS guarantee, not a nicety: the strip sits above the fold on the
   home page and changes state without a reload.
   ========================================================================= */

.data td.quote {
    /* Locks the row height across both states. Matches the line-height of a
       formatted number at this font size; the awaiting marker is smaller and
       would otherwise render a shorter row. */
    height: 40px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.quote__awaiting {
    font-size: 11.5px;
    color: var(--faint);
    font-family: var(--ui);
    letter-spacing: .02em;
}
.quote-note {
    margin-top: 10px;
    font-size: 12px;
    color: var(--muted);
}

/* carbon's rail: fixed-width value cells so the row cannot reflow when a
   symbol switches between a quote and an em-dash. */
.c-rail__val { min-width: 9ch; display: inline-block; text-align: right; }
.c-rail__state { font-weight: 700; letter-spacing: .06em; }
.c-rail__state--live { color: var(--up); }
.c-rail__state--stale { color: var(--warn); }

/* ── Layout utilities (P7) ────────────────────────────────────────────────
   These replace 48 `style="…"` attributes that were spread across 14
   templates. Not a style preference: a CSP nonce authorises a <script> or a
   <style> ELEMENT, and cannot authorise a style ATTRIBUTE. Keeping them would
   have meant `style-src 'unsafe-inline'`, which is most of what the directive
   exists to prevent — an injected `style=` can hide, move or overlay anything
   on the page. Named for the job, not the value. */
.align-right   { text-align: right; }
.m-0           { margin: 0; }
.ml-6          { margin-left: 6px; }
.mt-16         { margin-top: 16px; }
.mt-20         { margin-top: 20px; }
.mt-22         { margin-top: 22px; }
.mt-24         { margin-top: 24px; }
.mt-26         { margin-top: 26px; }
.fs-13         { font-size: 13px; }
.note-sm       { margin-top: 16px; font-size: 13px; }
.note-md       { margin-top: 14px; font-size: 13.5px; }
.aside-lead    { font-size: 15px; margin-bottom: 20px; }
.footer-about  { margin-top: 14px; max-width: 40ch; font-size: 14.5px; }
.footer-fine   { font-size: 12px; margin-top: 18px; }
.inline-links  { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.no-rule       { border-top: 0; padding-top: 0; }

/* ══ Icons (UI polish) ════════════════════════════════════════════════════
 *
 * Inlined by App\Core\Icon — no request, no CDN, no CLS. Every <svg> carries
 * explicit width and height, so the box is reserved before paint; CLS has been
 * 0 since phase 2 and an unsized inline image is the classic way to lose it.
 */

/*
 * A UI icon sits on the text baseline beside its label and inherits the text
 * colour, which is what lets one asset serve both themes.
 */
.ico {
    display: inline-block;
    flex: none;
    vertical-align: -0.135em;
}

/*
 * Instrument artwork. NOT recoloured: a coin logo or a national flag is a mark
 * that is recognisable from elsewhere, and tinting it makes it a different one.
 */
.pairico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 18px;
    height: 18px;
    vertical-align: -0.25em;
}

/* Flags are 4:3 and coins are square. Rounding the flag keeps the row tidy
 * without cropping anything that carries meaning. */
.pairico--flag {
    border-radius: 2px;
    overflow: hidden;
    object-fit: cover;
}

.pairico--glyph { color: var(--gold-figure); }

/*
 * THE FALLBACK, for an instrument with no artwork.
 *
 * A currency code in a circle — never a broken image, never an empty space,
 * and never a generic globe that would read as "some country". The catalogue
 * grows through the admin (A3 adds instruments), so this is a normal state.
 */
.pairico--fallback {
    width: 18px;
    height: 18px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--panel-2);
    color: var(--muted);
    font-family: var(--mono);
    font-size: 8px;
    font-weight: 600;
    letter-spacing: .02em;
    line-height: 1;
}

.pairico--lg,
.pairico--lg.pairico--fallback {
    width: 24px;
    height: 24px;
    font-size: 10px;
}

/* An icon and its label, spaced once rather than in twenty places. */
.withico {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* ══ Interaction states (UI polish) ═══════════════════════════════════════
 *
 * Token-driven, ~140ms, consistent. A polished interaction state is FELT, not
 * noticed — the redesign's discipline holds, and nothing here adds a gradient,
 * a shadow that was not there, or motion for its own sake.
 *
 * Everything below is presentation. No control gains or loses a capability.
 */

/*
 * ── A CARD HOVERS ONLY IF IT IS CLICKABLE ──────────────────────────────────
 *
 * The affordance has to be true. A hover lift on a card that does nothing when
 * clicked teaches the reader that lifting means nothing, and then the lift that
 * DOES mean something reads as decoration.
 *
 * So the selector is the anchor, never the class: `a.card` and `.card--link`
 * are clickable by construction, and a plain `.card` is left alone.
 */
a.card,
.card--link {
    transition: border-color var(--dur) var(--ease),
                box-shadow var(--dur) var(--ease);
}

a.card:hover,
.card--link:hover {
    border-color: var(--line);
    box-shadow: var(--lift);
}

/*
 * ── FORM FIELDS ────────────────────────────────────────────────────────────
 *
 * The focus ring is the global one. What is added here is the BORDER moving
 * with it, so the field reads as active even at a glance, and an invalid state
 * that is a border and a colour rather than a colour alone.
 */
input:not([type="checkbox"]):not([type="radio"]),
select,
textarea {
    transition: border-color var(--dur) var(--ease),
                background var(--dur) var(--ease);
}

input:not([type="checkbox"]):not([type="radio"]):hover:not(:disabled),
select:hover:not(:disabled),
textarea:hover:not(:disabled) { border-color: var(--line); }

input:focus-visible,
select:focus-visible,
textarea:focus-visible { border-color: var(--focus-ring); }

/*
 * INVALID is never colour alone: the border thickens as well as reddening, so
 * the state survives a monochrome screenshot and a colour vision deficiency.
 * `:user-invalid` rather than `:invalid` — `:invalid` paints a field red before
 * the client has typed anything, which is a scolding rather than a signal.
 */
input:user-invalid,
select:user-invalid,
textarea:user-invalid {
    border-color: var(--down);
    border-width: 2px;
}

input:disabled,
select:disabled,
textarea:disabled {
    opacity: var(--disabled-o);
    cursor: not-allowed;
}

/*
 * ── TABLE ROWS ─────────────────────────────────────────────────────────────
 *
 * Only where a row is a target. A static data table does not hover, for the
 * same reason a static card does not.
 */
tbody tr:hover > td { background: var(--row-hover); }

tbody tr > td { transition: background var(--dur) var(--ease); }

/*
 * ── LINKS AND NAV ──────────────────────────────────────────────────────────
 */

/*
 * ── PRESSED SURFACES ───────────────────────────────────────────────────────
 *
 * --press is a touch beyond --row-hover in each theme: distinguishable when
 * you are looking for it and invisible when you are not.
 */
.btn--ghost:active:not(:disabled),
.icon-btn:active:not(:disabled) { background: var(--press); }
