/*
 * Hercules Client Portal — the surface.
 *
 * `packages/ui/src/tokens.css` positions this front end as "the terminal, softened", and the
 * softening is the whole design brief. The back office is an INSTRUMENT: 13px, dense, a nav rail
 * of thirty-five routes, built for somebody who lives in it. This is a DOCUMENT, read once by
 * somebody who has never seen it, on a phone, deciding whether to trust a broker with their
 * money. So:
 *
 *   type      15px base and a 1.55 line height, against the console's 13/1.45, set in Graphik —
 *             the corporate face. Body text a stranger reads carefully is not the same as a
 *             column a professional scans.
 *   width     a 560px measure on forms and 900px on the hub. A field that spans a 27-inch monitor
 *             is a field nobody can see the label and the input of at the same time.
 *   radius    12px, against the console's 6 and the dealing terminal's 0. Rounding costs density
 *             and buys approachability, and only one of those matters here.
 *   motion    present but short. A form that animates is a form that feels slow on the fourth
 *             screen; a step that slides in once tells you where you are.
 *
 * THIS IS WHERE THE BRAND IS EXPRESSED MOST FULLY, because it is the page a visitor reaches one
 * click after hercules.forex, and a seam between the two is a seam a stranger reads as "this is
 * not the same company". The palette is `packages/ui/src/brand/brand.css`: the corporate purple
 * ramp, the corporate ink greys, the corporate face. It is COPIED into the `:root` blocks below
 * rather than `@import`ed, for the reason `sync-brand.mjs` records — this server serves exactly
 * one directory, an `@import` is a second round trip in front of a render-blocking stylesheet,
 * and the containment is worth more than the duplication. The rule that follows from copying:
 * THE COMPONENT RULES BELOW NEVER NAME A COLOUR. Rebranding this surface means changing the
 * three `:root` blocks and nothing under them.
 *
 * WHAT THE BRAND DOES NOT TAKE IS DIRECTION. `--pos` and `--neg` are the two colours on this
 * page whose meaning must never be misread, and they keep the values the product shipped with,
 * in both themes. The accent is purple; up is still green and down is still red.
 *
 * FIVE THINGS THIS STYLESHEET DOES THAT ARE NOT DECORATION:
 *
 *   1. NO INLINE STYLE, ANYWHERE. The CSP ships `style-src 'self'` with no `unsafe-inline`, which
 *      blocks the style ATTRIBUTE as well as the tag. A width written with `setAttribute('style',…)`
 *      renders at zero and says nothing. `el()` writes `node.style.cssText`, which is a CSSOM
 *      write governed by `script-src`, so it applies — but everything that can be a class is one.
 *   2. THE FOCUS RING IS NEVER REMOVED. `:focus-visible` is styled up, not away. This is a form
 *      somebody may be completing with a keyboard, a screen reader, or a phone's switch control,
 *      and the single most common accessibility defect in a sign-up flow is an invisible focus.
 *   3. TOUCH TARGETS ARE 44px MINIMUM. Every control, on every breakpoint. The console can put a
 *      24px icon button in a table row because it is used with a mouse; a client tapping "resend
 *      code" on a train cannot.
 *   4. ERRORS ARE NOT COLOUR ALONE. Every invalid field gets a border, an icon and a sentence.
 *      Roughly one man in twelve cannot reliably see the red. The purple accent is deliberately
 *      no help to him and no hindrance either: simulated for protanopia and deuteranopia, an
 *      error border (#FF5C6C) collapses towards olive and an accent border (#A768FF) towards
 *      blue, which is the one axis a dichromat still has. They are never the same edge.
 *   5. GRAPHIK HAS NO 700 CUT. Three weights ship — 400, 600 and 900, the display face. CSS font
 *      matching resolves any requested weight above 500 UPWARDS first, so `bold` (700) and the
 *      fractional weights this file used to carry (620, 640) all land on 900 and set a form label
 *      in the headline face. Every weight below is 400, 600 or 900, written out, and `strong`
 *      and `b` are pinned to 600 for the same reason.
 *
 * `prefers-reduced-motion` is honoured for real: the transitions are removed, not shortened.
 */

/* ── The typeface ────────────────────────────────────────────────────────────
  The same three faces `brand.css` declares, against this app's own copy of the files under
  `public/brand/fonts/`. Declared here rather than by linking `/brand/brand.css` because that
  would be a second render-blocking stylesheet in front of the first paint on a phone, to carry
  three rules; `sync-brand.mjs` already guarantees the bytes are identical, and `--check` fails
  CI if they drift. Never a font CDN: the CSP is `default-src 'none'` with `font-src 'self'`, so
  a Google Fonts URL is refused silently and the page renders in Times.
*/
@font-face {
  font-family: "Graphik";
  src: url("/brand/fonts/graphik-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Graphik";
  src: url("/brand/fonts/graphik-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
/* Graphik Super, the display cut. Used on one thing: the page title. */
@font-face {
  font-family: "Graphik";
  src: url("/brand/fonts/graphik-900.woff2") format("woff2");
  font-weight: 900; font-style: normal; font-display: swap;
}

:root {
  /* ── Ground ────────────────────────────────────────────────────────────────
    The corporate ink ramp. The old ground here was a blue-black (#0B0F14) that read as a
    different company sitting next to the marketing page; these are the site's own neutral steps.
    `--sunken` is true black — the site's `--color_1` — which is a single step below the page and
    is why an input reads as recessed inside a card without needing a shadow to say so.
  */
  --bg: #08080A;
  --surface: #101216;
  --raised: #16191F;
  --sunken: #000000;
  --overlay: rgba(0, 0, 0, .74);

  /* Rules and boundaries. `--line-strong` is the corporate #676767, which brand.css reserves for
     exactly this: rules, never text. It is what every INTERACTIVE edge is drawn in — 3.7:1 on the
     input ground — because WCAG 1.4.11 asks 3:1 of a control boundary and the old #35455A was
     1.9:1, an input a sighted user could not find the edge of. `--line` stays a hairline: a card
     border carries no information and does not need to shout. */
  --line: #2E3238;
  --line-strong: #676767;
  --line-subtle: #1F2429;

  /* Text. The corporate greys, walked down from white: 20.01 / 11.59 / 7.20 on the page ground.
     #676767 is NOT in this group — at 3.54:1 it is a rule, not a sentence. */
  --text: #FFFFFF;
  --dim: #C5C5C5;
  --muted: #9B9B9B;
  --inverse: #08080A;

  /* ── Accent ────────────────────────────────────────────────────────────────
    Three steps of one hue, and they are not interchangeable:

      --accent        #A768FF  TEXT and edges. 5.78:1 on the page, 5.09:1 on a raised panel. The
                               corporate #8127FF is 3.49:1 here and fails as a link colour — this
                               is that hue walked towards white until it passes.
      --accent-hover  #BA88FF  7.67:1. More contrast on hover, never less.
      --accent-solid  #8127FF  the corporate purple itself, for FILLS: white on it is 5.73:1, and
                               it is what a progress bar and a checked control are painted in.
      --brand-grad             the corporate call-to-action gradient, and — rule 4 of brand.css —
                               nothing but a call to action. A gradient behind a row reads as a
                               highlight that means something, and it would mean nothing.
  */
  --accent: #A768FF;
  --accent-hover: #BA88FF;
  --accent-solid: #8127FF;
  --accent-wash: #190C2C;
  --on-accent: #FFFFFF;
  --brand-grad: linear-gradient(90deg, #8127FF 0%, #9209B5 100%);
  --brand-grad-hover: linear-gradient(90deg, #631FC2 0%, #9209B5 100%);

  /* DIRECTION AND STATE ARE NOT BRAND COLOURS. Untouched by the rebrand, in both themes: green
     means up, red means down, and amber means the client must read something before continuing.
     The informational blue stays blue and does NOT become the corporate teal — #0CCEAD sits a
     few degrees from --pos, and "information" and "success" reading alike is precisely the
     confusion rule 4 exists to prevent. */
  --pos: #2FC08A;  --pos-wash: #0E2A22;
  --neg: #FF5C6C;  --neg-wash: #33161C;
  --warn: #F5A524; --warn-wash: #2E2210;
  --info: #4FB6E8; --info-wash: #0F2733;
  --neutral: #9B9B9B; --neutral-wash: #1F2429;

  --focus: #BA88FF;

  --s1: 2px; --s2: 4px; --s3: 6px; --s4: 8px; --s5: 12px;
  --s6: 16px; --s7: 20px; --s8: 24px; --s9: 32px; --s10: 40px;
  --s11: 48px; --s12: 64px;

  --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-full: 9999px;

  /* Graphik carries `tnum`, so a figure column can be set in the UI face; it has no `zero`, so
     anything that needs a slashed zero — an address, a hash, a reference — stays monospace. */
  --ui: "Graphik", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --measure: 560px;
  --page: 940px;
  --tap: 44px;

  --elev-1: 0 0 0 1px var(--line);
  --elev-2: 0 0 0 1px var(--line), 0 10px 30px rgba(0, 0, 0, .40);

  --fast: 140ms cubic-bezier(.2, 0, .38, .9);
  --base: 220ms cubic-bezier(.16, 1, .3, 1);

  /* CandleChart/Spark read getComputedStyle(document.documentElement) for --t-*, so these
     aliases live on :root rather than under .desk. var() only: a hex here would freeze the
     chart against the dark theme when the client has asked for light. */
  --t-bg: var(--bg);
  --t-panel: var(--surface);
  --t-panel-2: var(--raised);
  --t-raised: var(--raised);
  --t-line: var(--line-subtle);
  --t-line-2: var(--line);
  --t-line-soft: var(--line-subtle);
  --t-text: var(--text);
  --t-dim: var(--dim);
  --t-faint: var(--muted);
  --t-accent: var(--accent);
  --t-accent-dim: var(--accent-solid);
  --t-accent-wash: var(--accent-wash);
  --t-accent-wash-soft: color-mix(in srgb, var(--accent) 8%, transparent);
  --t-up: var(--pos);
  --t-up-wash: var(--pos-wash);
  --t-down: var(--neg);
  --t-down-wash: var(--neg-wash);
  --t-warn: var(--warn);
  --t-info: var(--info);
  --t-mono: var(--mono);
  --t-ui: var(--ui);
  --t-focus: var(--focus);
  --t-1: var(--s1); --t-2: var(--s2); --t-3: var(--s3); --t-4: var(--s4); --t-5: var(--s5);
}

/* ── Light ───────────────────────────────────────────────────────────────────
  A form a client may open on a bright phone outdoors, so this block is not an afterthought and
  is not a tint of the dark one. The accent INVERTS: #A768FF is 1.9:1 on white and would be an
  invisible link, so the ramp darkens to #611DBF (8.62:1) with #4E1697 (11.14:1) on hover.

  The grounds are the palest step of the brand wash (#F5EEFF, 1.13:1 under a white card — the
  same separation the blue-grey ground it replaces had) with white cards on top. The measured
  pairs this block relies on, all against the ground each colour actually sits on:

    text     #08080A on #FFFFFF 20.01, on #F5EEFF 17.68        body copy
    dim      #4B4B4B on #FFFFFF  8.72, on #F5EEFF  7.71        secondary copy
    muted    #5F5F5F on #FFFFFF  6.39, on #F0E5FF  5.28        hints, labels, meta
    accent   #611DBF on #FFFFFF  8.62, on #F0E5FF  7.12        links, checked edges
    focus    #6E21D9 on #FFFFFF  7.29, on #F5EEFF  6.44        the ring, against both grounds
    control  #676767 on #FFFFFF  5.66, on #F5EEFF  5.00        every input, button and choice edge
    on fill  #FFFFFF on #6E21D9  7.29, on the gradient 5.73–7.17

  #A8A8A8 is a RULE only (2.38:1): card borders and table lines carry no information. It never
  draws the edge of something you can click.

  BOTH GUARDS, BOTH DIRECTIONS, and no colour is defined only here — the media query so the OS
  preference works, the attribute so an explicit choice beats it. The two blocks are duplicates
  on purpose and have to be changed together.
*/
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #F5EEFF; --surface: #FFFFFF; --raised: #FFFFFF; --sunken: #F5EEFF;
    --overlay: rgba(8, 8, 10, .45);
    --line: #A8A8A8; --line-strong: #676767;
    --line-subtle: color-mix(in srgb, #A8A8A8 45%, #FFFFFF);
    --text: #08080A; --dim: #4B4B4B; --muted: #5F5F5F; --inverse: #FFFFFF;
    --accent: #611DBF; --accent-hover: #4E1697; --accent-solid: #6E21D9; --accent-wash: #F0E5FF;
    --pos: #0F7A54; --pos-wash: #E3F6EE;
    --neg: #C42A3A; --neg-wash: #FDE9EB;
    --warn: #A96B04; --warn-wash: #FDF3E0;
    --info: #1B6E92; --info-wash: #E4F3FA;
    --neutral: #5F5F5F; --neutral-wash: color-mix(in srgb, #A8A8A8 22%, #FFFFFF);
    --focus: #6E21D9;
    --elev-2: 0 0 0 1px var(--line), 0 8px 24px rgba(8, 8, 10, .10);
    --t-bg: var(--bg);
    --t-panel: var(--surface);
    --t-panel-2: var(--raised);
    --t-raised: var(--raised);
    --t-line: var(--line-subtle);
    --t-line-2: var(--line);
    --t-line-soft: var(--line-subtle);
    --t-text: var(--text);
    --t-dim: var(--dim);
    --t-faint: var(--muted);
    --t-accent: var(--accent);
    --t-accent-dim: var(--accent-solid);
    --t-accent-wash: var(--accent-wash);
    --t-accent-wash-soft: color-mix(in srgb, var(--accent) 8%, transparent);
    --t-up: var(--pos);
    --t-up-wash: var(--pos-wash);
    --t-down: var(--neg);
    --t-down-wash: var(--neg-wash);
    --t-warn: var(--warn);
    --t-info: var(--info);
    --t-mono: var(--mono);
    --t-ui: var(--ui);
    --t-focus: var(--focus);
    --t-1: var(--s1); --t-2: var(--s2); --t-3: var(--s3); --t-4: var(--s4); --t-5: var(--s5);
  }
}
:root[data-theme="light"] {
  --bg: #F5EEFF; --surface: #FFFFFF; --raised: #FFFFFF; --sunken: #F5EEFF;
  --overlay: rgba(8, 8, 10, .45);
  --line: #A8A8A8; --line-strong: #676767;
  --line-subtle: color-mix(in srgb, #A8A8A8 45%, #FFFFFF);
  --text: #08080A; --dim: #4B4B4B; --muted: #5F5F5F; --inverse: #FFFFFF;
  --accent: #611DBF; --accent-hover: #4E1697; --accent-solid: #6E21D9; --accent-wash: #F0E5FF;
  --pos: #0F7A54; --pos-wash: #E3F6EE;
  --neg: #C42A3A; --neg-wash: #FDE9EB;
  --warn: #A96B04; --warn-wash: #FDF3E0;
  --info: #1B6E92; --info-wash: #E4F3FA;
  --neutral: #5F5F5F; --neutral-wash: color-mix(in srgb, #A8A8A8 22%, #FFFFFF);
  --focus: #6E21D9;
  --elev-2: 0 0 0 1px var(--line), 0 8px 24px rgba(8, 8, 10, .10);
  --t-bg: var(--bg);
  --t-panel: var(--surface);
  --t-panel-2: var(--raised);
  --t-raised: var(--raised);
  --t-line: var(--line-subtle);
  --t-line-2: var(--line);
  --t-line-soft: var(--line-subtle);
  --t-text: var(--text);
  --t-dim: var(--dim);
  --t-faint: var(--muted);
  --t-accent: var(--accent);
  --t-accent-dim: var(--accent-solid);
  --t-accent-wash: var(--accent-wash);
  --t-accent-wash-soft: color-mix(in srgb, var(--accent) 8%, transparent);
  --t-up: var(--pos);
  --t-up-wash: var(--pos-wash);
  --t-down: var(--neg);
  --t-down-wash: var(--neg-wash);
  --t-warn: var(--warn);
  --t-info: var(--info);
  --t-mono: var(--mono);
  --t-ui: var(--ui);
  --t-focus: var(--focus);
  --t-1: var(--s1); --t-2: var(--s2); --t-3: var(--s3); --t-4: var(--s4); --t-5: var(--s5);
}

* { box-sizing: border-box; }

/*
 * `[hidden]` has to win.
 *
 * The attribute's default rule is `display: none`, and ANY later `display` declaration on a
 * matching selector beats it on specificity — `.acct { display: flex }` renders a hidden element.
 * That is not a theoretical concern: it is why the sign-out button appeared on the sign-in page
 * and why an empty error marker sat under every field on first paint. One rule, at the top,
 * rather than remembering `display: none` on each of them.
 */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--ui);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

body { min-height: 100vh; display: flex; flex-direction: column; }

/* Every figure is tabular so a decimal point does not wander between rows. */
.mono, .num, .amount, code { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* `bold` is 700 and Graphik has no 700: the match resolves upwards and sets every `<strong>` in
   the family's headline cut. 600 is the semibold that was meant. */
strong, b { font-weight: 600; }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ── The shell ───────────────────────────────────────────────────────────── */

.top {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: var(--s6);
  padding: 0 var(--s6);
  height: 60px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line-subtle);
}

.brand {
  display: flex; align-items: center; gap: var(--s5);
  min-width: 0;
  font-size: 14px;
}
/*
 * The wordmark, inlined in `index.html` so `currentColor` inherits — see the comment there.
 *
 * Sized in `em` off `.brand`, so the lockup and the subtitle beside it stay in proportion at any
 * text size. It carries NO transition: a logo that fades in on every route change reads as the
 * page reloading.
 */
.hx-wordmark {
  display: block; height: 1.25em; width: auto; color: inherit; flex: none;
  /* The ratio is stated as well as implied by the viewBox: an inline SVG with only a height in a
     flex row is one of the shapes Safari has historically resolved to a zero or a stretched width,
     and a header logo is not a place to find that out from a bug report. */
  aspect-ratio: 1904.65 / 231.59;
}

.brand .sub { color: var(--muted); font-weight: 400; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }

/* Below this the header is the wordmark, an account number and a sign-out button, and something
   has to go. The subtitle does: `app.js` writes the section name into it, and the page's own `h1`
   says the same thing forty pixels lower. */
@media (max-width: 560px) {
  .brand { gap: var(--s4); }
  .brand .sub { display: none; }
}

.top .spacer { margin-left: auto; }

.acct {
  display: flex; align-items: center; gap: var(--s4);
  font-size: 13px; color: var(--dim);
}

main { flex: 1; width: 100%; }

.page {
  width: 100%; max-width: var(--page); margin: 0 auto;
  padding: var(--s9) var(--s6) var(--s12);
}
.page.narrow { max-width: var(--measure); }
.page.desk { max-width: none; width: 100%; padding: 0 0 var(--s6); }

/*
 * The page title, and the one place the display cut appears. Graphik Super is what the corporate
 * site sets its headlines in, so a client arriving from hercules.forex meets the same voice on the
 * first line of the form; tracked in a little, because a heavy cut at 26px sets loose.
 *
 * The weight is pinned on the ELEMENT, not on `.page > h1`, because `h1` is the one heading the
 * browser weights for us and its default is `bold` — 700, which Graphik does not have and which
 * font matching resolves up to 900 anyway. The six pre-authentication screens build their `h1`
 * inside a card (`ui.js`, `card(…, { heading: 1 })`) and so never match the selector below; left
 * to the browser they would arrive at the same face by accident rather than by decision.
 */
h1 { font-weight: 900; letter-spacing: -.02em; }
.page > h1 {
  font-size: 26px; line-height: 1.25;
  margin: 0 0 var(--s4);
}
.page > .lede {
  margin: 0 0 var(--s8);
  color: var(--dim); font-size: 15px; max-width: 62ch;
}

h2 { font-size: 18px; margin: 0 0 var(--s4); font-weight: 600; letter-spacing: -.01em; }
h3 { font-size: 14px; margin: 0 0 var(--s3); font-weight: 600; letter-spacing: .01em; }

.stack { display: flex; flex-direction: column; gap: var(--s6); }
.stack.tight { gap: var(--s4); }
.row { display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap; }
.grid { display: grid; gap: var(--s5); }
.grid.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid.c2 > :only-child,
.grid.c3 > :only-child { grid-column: 1 / -1; }
@media (max-width: 720px) { .grid.c2, .grid.c3 { grid-template-columns: 1fr; } }

/* ── Cards ───────────────────────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--s7);
}
.card.flush { padding: 0; overflow: hidden; }
.card h2, .card h3 { margin-top: 0; }
.card .sub { color: var(--muted); font-size: 13px; margin: 0 0 var(--s5); }

.tile {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--s6);
}
.tile .k { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .06em; }
.tile .v { font-size: 22px; font-weight: 600; margin-top: var(--s2); font-variant-numeric: tabular-nums; }
.tile .m { color: var(--dim); font-size: 12.5px; margin-top: var(--s2); }

/* ── Progress ────────────────────────────────────────────────────────────── */

.progress {
  display: flex; align-items: center; gap: var(--s5);
  padding: var(--s6) var(--s7);
  background: var(--raised); border: 1px solid var(--line); border-radius: var(--r-md);
}
.bar { flex: 1; height: 8px; border-radius: var(--r-full); background: var(--sunken); overflow: hidden; }
/* Flat, not the gradient. The gradient is the call to action and nothing else; a progress bar
   painted in it would read as a second button lying on its side. */
.bar > span {
  display: block; height: 100%; border-radius: var(--r-full);
  background: var(--accent-solid);
  transition: width var(--base);
}
.progress .pct { font-variant-numeric: tabular-nums; font-weight: 600; min-width: 3.5ch; text-align: right; }

/* The step list. A checklist, not a wizard: every step says what it is and what it costs. */
.steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.steps li { border-bottom: 1px solid var(--line-subtle); }
.steps li:last-child { border-bottom: 0; }

.step {
  display: grid; grid-template-columns: 30px 1fr auto; align-items: start;
  gap: var(--s5); width: 100%; text-align: left;
  padding: var(--s6) var(--s7);
  background: none; border: 0; color: inherit; font: inherit;
  min-height: var(--tap); cursor: pointer;
  transition: background var(--fast);
}
.step:hover:not([disabled]) { background: var(--raised); }
.step[disabled] { cursor: default; opacity: .55; }
.step .dot {
  width: 26px; height: 26px; border-radius: var(--r-full);
  display: grid; place-items: center; font-size: 13px; font-weight: 600;
  border: 1.5px solid var(--line-strong); color: var(--muted);
  margin-top: 1px;
}
.step.done .dot { background: var(--pos-wash); border-color: var(--pos); color: var(--pos); }
.step.waived .dot { background: var(--warn-wash); border-color: var(--warn); color: var(--warn); }
.step.current .dot { background: var(--accent-wash); border-color: var(--accent); color: var(--accent); }
/* Both are spans inside a span, so they need an explicit block or the title and the description
 * run together into one sentence — "Create your accountEmail address, a password and…". */
.step .t { display: block; font-weight: 600; }
.step .d { display: block; color: var(--muted); font-size: 13px; margin-top: var(--s1); line-height: 1.45; }
.step .meta { color: var(--muted); font-size: 12.5px; white-space: nowrap; text-align: right; }
.step.current { background: color-mix(in srgb, var(--accent-wash) 55%, transparent); }

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

form { display: flex; flex-direction: column; gap: var(--s6); }

.field { display: flex; flex-direction: column; gap: var(--s3); }
.field > label { font-size: 13.5px; font-weight: 600; }
.field .hint { color: var(--muted); font-size: 12.5px; }

/* The edge of an input is a control boundary, so it is drawn in `--line-strong` and measured on
   the input's own ground: 3.71:1 in the dark theme and 5.00:1 in the light one, against the 3:1
   WCAG 1.4.11 asks of a control. The old --line drew that edge at 1.48:1, which is not an edge.
   Hover goes to the accent rather than to a heavier grey — on a touch screen there is no hover,
   and on a pointer it should be obvious the field is live. Focus is the ring, and the ring is
   never removed. */
.input, select.input, textarea.input {
  width: 100%;
  min-height: var(--tap);
  padding: var(--s4) var(--s5);
  background: var(--sunken);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  color: var(--text);
  font: inherit;
  transition: border-color var(--fast), background var(--fast);
}
.input:hover, select.input:hover { border-color: var(--accent); }
.input:focus, select.input:focus, textarea.input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
textarea.input { min-height: 96px; resize: vertical; }
.input::placeholder { color: var(--muted); }

/* An invalid field is a border, an icon and a sentence — never colour alone. */
.field.bad .input { border-color: var(--neg); background: color-mix(in srgb, var(--neg-wash) 40%, var(--sunken)); }
.field .err {
  display: flex; align-items: flex-start; gap: var(--s3);
  color: var(--neg); font-size: 13px;
}
.field .err::before { content: "▲"; font-size: 11px; line-height: 1.5; }

fieldset { border: 0; margin: 0; padding: 0; }
legend { font-size: 13.5px; font-weight: 600; padding: 0 0 var(--s3); }

.choice {
  display: flex; align-items: flex-start; gap: var(--s5);
  min-height: var(--tap);
  padding: var(--s5) var(--s6);
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--sunken);
  cursor: pointer;
  transition: border-color var(--fast), background var(--fast);
}
.choice:hover { border-color: var(--accent); }
.choice input { margin-top: 4px; accent-color: var(--accent-solid); width: 18px; height: 18px; flex: none; }
.choice .t { font-weight: 600; }
.choice .d { color: var(--muted); font-size: 12.5px; }
.choice:has(input:checked) { border-color: var(--accent); background: var(--accent-wash); }

.choices { display: flex; flex-direction: column; gap: var(--s4); }

/* The password meter. Four segments, and a label — a bar alone says nothing. */
.meter { display: flex; gap: var(--s2); margin-top: var(--s2); }
.meter i { flex: 1; height: 4px; border-radius: var(--r-full); background: var(--line); }
.meter.s1 i:nth-child(-n+1) { background: var(--neg); }
.meter.s2 i:nth-child(-n+2) { background: var(--warn); }
.meter.s3 i:nth-child(-n+3) { background: var(--info); }
.meter.s4 i { background: var(--pos); }

/* ── Buttons ─────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s3);
  min-height: var(--tap); padding: 0 var(--s7);
  border-radius: var(--r-sm); border: 1px solid var(--line-strong);
  background: var(--raised); color: var(--text);
  font: inherit; font-weight: 600; cursor: pointer;
  transition: background var(--fast), border-color var(--fast), transform var(--fast);
}
.btn:hover:not(:disabled) { border-color: var(--accent); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
/* The gradient lives here and on nothing else on this surface: it is the corporate call to
   action, and the primary button is the only call to action a screen of this flow has. The
   border is transparent rather than absent so the button keeps the same box as its siblings. */
.btn.primary {
  background: var(--brand-grad); border-color: transparent; color: var(--on-accent);
}
.btn.primary:hover:not(:disabled) { background: var(--brand-grad-hover); border-color: transparent; }
/* The submit spinner sits ON the gradient, where a grey ring disappears. */
.btn.primary .spinner {
  border-color: color-mix(in srgb, var(--on-accent) 45%, transparent);
  border-top-color: var(--on-accent);
}
.btn.ghost { background: none; border-color: transparent; color: var(--dim); }
.btn.ghost:hover:not(:disabled) { background: var(--raised); color: var(--text); }
.btn.block { width: 100%; }
.btn.sm { min-height: 36px; padding: 0 var(--s5); font-size: 13.5px; }
.btn.danger { border-color: var(--neg); color: var(--neg); }
.btn.danger:hover:not(:disabled) { background: var(--neg-wash); }

.btn-row { display: flex; gap: var(--s4); flex-wrap: wrap; }

/* ── Notices ─────────────────────────────────────────────────────────────── */

.notice {
  display: flex; gap: var(--s5); align-items: flex-start;
  padding: var(--s6); border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--raised);
  font-size: 14px;
}
.notice .ico { font-size: 13px; line-height: 1.5; flex: none; }
.notice strong { display: block; margin-bottom: var(--s2); }
.notice.info { border-color: var(--info); background: var(--info-wash); }
.notice.info .ico { color: var(--info); }
.notice.pos { border-color: var(--pos); background: var(--pos-wash); }
.notice.pos .ico { color: var(--pos); }
.notice.warn { border-color: var(--warn); background: var(--warn-wash); }
.notice.warn .ico { color: var(--warn); }
.notice.neg { border-color: var(--neg); background: var(--neg-wash); }
.notice.neg .ico { color: var(--neg); }

/* The statutory risk warning. Deliberately not dismissible and deliberately not styled down. */
.risk-warning {
  border: 1px solid var(--warn); background: var(--warn-wash);
  border-radius: var(--r-sm); padding: var(--s6);
  font-size: 13.5px; line-height: 1.5;
}
.risk-warning b { display: block; margin-bottom: var(--s2); }

.badge {
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: 2px var(--s4); border-radius: var(--r-full);
  font-size: 11.5px; font-weight: 600; letter-spacing: .02em;
  background: var(--neutral-wash); color: var(--neutral);
  border: 1px solid color-mix(in srgb, var(--neutral) 40%, transparent);
}
.badge.pos { background: var(--pos-wash); color: var(--pos); border-color: color-mix(in srgb, var(--pos) 40%, transparent); }
.badge.warn { background: var(--warn-wash); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.badge.neg { background: var(--neg-wash); color: var(--neg); border-color: color-mix(in srgb, var(--neg) 40%, transparent); }
.badge.info { background: var(--info-wash); color: var(--info); border-color: color-mix(in srgb, var(--info) 40%, transparent); }

/* ── The code input ──────────────────────────────────────────────────────── */

.code-input {
  display: flex; gap: var(--s4); justify-content: flex-start;
}
.code-input input {
  width: 52px; height: 60px;
  text-align: center; font-family: var(--mono); font-size: 22px;
  background: var(--sunken); border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  color: var(--text);
}
.code-input input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
@media (max-width: 420px) {
  .code-input { gap: var(--s3); }
  .code-input input { width: 44px; height: 52px; font-size: 19px; }
}

/* ── Documents and uploads ───────────────────────────────────────────────── */

.drop {
  border: 1.5px dashed var(--line-strong); border-radius: var(--r-md);
  padding: var(--s10) var(--s6); text-align: center;
  background: var(--sunken);
  transition: border-color var(--fast), background var(--fast);
}
.drop.over { border-color: var(--accent); background: var(--accent-wash); }
.drop .t { font-weight: 600; }
.drop .d { color: var(--muted); font-size: 13px; margin-top: var(--s2); }

.doc-list { display: flex; flex-direction: column; gap: var(--s4); }
.doc {
  display: flex; align-items: center; gap: var(--s5);
  padding: var(--s5) var(--s6);
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--sunken);
}
.doc .t { font-weight: 600; flex: 1; }

/* ── Tables (the few there are) ──────────────────────────────────────────── */

table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th {
  text-align: left; font-weight: 600; color: var(--muted);
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .06em;
  padding: var(--s4) var(--s6); border-bottom: 1px solid var(--line);
}
td { padding: var(--s5) var(--s6); border-bottom: 1px solid var(--line-subtle); vertical-align: top; }
tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

dl.kv { display: grid; grid-template-columns: minmax(140px, auto) 1fr; gap: var(--s3) var(--s6); margin: 0; }
dl.kv dt { color: var(--muted); font-size: 13px; }
dl.kv dd { margin: 0; font-size: 13.5px; }

/* ── Toast ───────────────────────────────────────────────────────────────── */

.toast-wrap {
  position: fixed; left: 50%; bottom: var(--s7); transform: translateX(-50%);
  display: flex; flex-direction: column; gap: var(--s4); z-index: 60;
  width: min(520px, calc(100vw - 2 * var(--s6)));
}
.toast {
  display: flex; gap: var(--s5); align-items: flex-start;
  padding: var(--s5) var(--s6);
  border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--raised); box-shadow: var(--elev-2);
  font-size: 13.5px;
  animation: rise var(--base);
}
.toast.pos { border-color: var(--pos); }
.toast.neg { border-color: var(--neg); }
.toast strong { display: block; }
.toast .body { color: var(--dim); }

@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

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

.auth {
  min-height: calc(100vh - 60px);
  display: grid; place-items: center; padding: var(--s8) var(--s6) var(--s12);
}
.auth .card { width: 100%; max-width: 440px; }
.auth .switch { text-align: center; color: var(--muted); font-size: 13.5px; margin-top: var(--s6); }

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

.foot {
  border-top: 1px solid var(--line-subtle);
  padding: var(--s7) var(--s6);
  color: var(--muted); font-size: 12.5px;
}
.foot .inner { max-width: var(--page); margin: 0 auto; display: flex; flex-wrap: wrap; gap: var(--s6); }

/* ── Utilities ───────────────────────────────────────────────────────────── */

.muted { color: var(--muted); }
.dim { color: var(--dim); }
.small { font-size: 13px; }
.tiny { font-size: 12px; }
.center { text-align: center; }
.spacer { margin-left: auto; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.spinner {
  width: 16px; height: 16px; border-radius: var(--r-full);
  border: 2px solid var(--line-strong); border-top-color: var(--accent);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  /* Removed, not shortened. A 1ms animation still triggers vestibular symptoms in some people. */
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

/* ── Client desk ───────────────────────────────────────────────────────────
 * Layout copied from the dealing terminal, scoped under .desk so it cannot restyle a form
 * route. html/body stay scrollable: overflow:hidden is the terminal's, not this shell's.
 * Dealer chrome (firm P&L, LP list, kill, flatten, equity curve, status FEEDS/SRC/DIV,
 * treasury .addr) is not drawn here; the hide list below is the backstop if markup leaks.
 */

.desk #hb-firm, .desk .hstat:has(#hb-firm),
.desk #lp-list, .desk .sub:has(#lp-list),
.desk #btn-kill, .desk .sub:has(#btn-kill),
.desk #btn-flat, .desk #equity, .desk #stat,
.desk .addr, .desk .sub:has(.addr) { display: none !important; }

.desk #desk, .page.desk#desk {
  display: grid;
  width: 100%;
  height: calc(100dvh - 60px);
  gap: 1px;
  background: var(--t-line);
  color: var(--t-text);
  font: 400 11px/1.35 var(--t-mono);
  font-variant-numeric: tabular-nums;
  grid-template-columns: 268px minmax(280px, 1fr) 264px 252px;
  grid-template-rows: 34px minmax(200px, 1fr) 236px;
  grid-template-areas:
    "head  head    head  head"
    "watch chart   book  rail"
    "watch blotter book  rail";
}
.desk #desk button, .page.desk#desk button,
.desk #desk input, .page.desk#desk input,
.desk #desk select, .page.desk#desk select { font: inherit; color: inherit; }
.desk #desk button, .page.desk#desk button { cursor: pointer; }

.desk .panel {
  background: var(--t-panel);
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}
.desk .panel > header {
  display: flex;
  align-items: center;
  gap: var(--t-4);
  height: 20px;
  flex: 0 0 20px;
  padding: 0 var(--t-3);
  background: var(--t-panel-2);
  border-bottom: 1px solid var(--t-line);
  font: 600 9px/1 var(--t-ui);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--t-faint);
  user-select: none;
}
.desk .panel > header .t { color: var(--t-dim); }
.desk .panel > header .sp { margin-left: auto; }
.desk .panel-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
.desk .panel-body::-webkit-scrollbar { width: 7px; height: 7px; }
.desk .panel-body::-webkit-scrollbar-thumb { background: var(--t-line-2); }
.desk .panel-body::-webkit-scrollbar-track { background: transparent; }
.desk .panel-body--column { display: flex; flex-direction: column; overflow: visible; }

.desk #head {
  grid-area: head;
  background: var(--t-panel-2);
  display: flex;
  align-items: center;
  gap: var(--t-5);
  padding: 0 var(--t-4) 0 0;
  border-bottom: 1px solid var(--t-line-2);
}
.desk #head .sep { width: 1px; height: 20px; background: var(--t-line); }
.desk #head .grow { margin-left: auto; }
.desk .hstat { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.desk .hstat .k {
  font: 600 8px/1 var(--t-ui); letter-spacing: .10em; text-transform: uppercase; color: var(--t-faint);
}
.desk .hstat .v { font-size: 12px; line-height: 1; white-space: nowrap; }
.desk .hstat .v.big { font-size: 14px; font-weight: 600; }
.desk #sym-badge {
  display: flex; align-items: center; gap: var(--t-3);
  padding: 2px var(--t-4);
  border: 1px solid var(--t-accent-dim);
  background: var(--t-accent-wash);
  color: var(--t-accent);
  font-size: 12px; font-weight: 600; letter-spacing: .04em;
}

.desk #watch  { grid-area: watch; }
.desk #booktape {
  grid-area: book;
  display: flex; flex-direction: column; gap: 1px;
  background: var(--t-line); min-height: 0;
}
.desk #booktape > #book { flex: 0 0 auto; }
.desk #booktape > #tape { flex: 1 1 auto; min-height: 0; }
.desk #chart  { grid-area: chart; }
.desk #rail   { grid-area: rail; }
.desk #blotter{ grid-area: blotter; }

.desk table.grid { display: table; width: 100%; border-collapse: collapse; gap: 0; }
.desk table.grid th {
  position: sticky; top: 0; z-index: 2;
  background: var(--t-panel-2);
  border-bottom: 1px solid var(--t-line);
  font: 600 8px/1 var(--t-ui); letter-spacing: .09em; text-transform: uppercase;
  color: var(--t-faint);
  padding: 3px var(--t-3);
  text-align: right;
  white-space: nowrap;
  user-select: none;
}
.desk table.grid th:first-child, .desk table.grid td:first-child { text-align: left; }
.desk table.grid td {
  padding: 2px var(--t-3);
  border-bottom: 1px solid var(--t-line-soft);
  text-align: right;
  white-space: nowrap;
  font-size: 11px;
}
.desk table.grid tbody tr:hover { background: var(--t-accent-wash-soft); }
.desk table.grid tbody tr.sel { background: var(--t-accent-wash); box-shadow: inset 2px 0 0 var(--t-accent); }
.desk .up { color: var(--t-up); }
.desk .down { color: var(--t-down); }
.desk .flat { color: var(--t-dim); }
.desk .faint { color: var(--t-faint); }

@keyframes flashUp   { from { background: var(--t-up-wash); }   to { background: transparent; } }
@keyframes flashDown { from { background: var(--t-down-wash); } to { background: transparent; } }
.desk .fu { animation: flashUp 380ms ease-out; }
.desk .fd { animation: flashDown 380ms ease-out; }

.desk #watch table.grid { table-layout: fixed; width: 100%; }
.desk #watch col.c-sym { width: auto; }
.desk #watch col.c-last { width: 90px; }
.desk #watch col.c-chg { width: 38px; }
.desk #watch col.c-spk { width: 42px; }
.desk #watch td.sym { font-weight: 600; letter-spacing: .01em; overflow: hidden; text-overflow: ellipsis; }
.desk #watch td, .desk #watch th { padding-left: 4px; padding-right: 4px; }
.desk #watch canvas.spark { display: block; width: 38px; height: 14px; }
.desk #watch td.sparkcell { padding: 1px 4px 1px 0; }
.desk #watch .cls {
  display: inline-block; width: 5px; height: 5px; margin-right: 4px;
  vertical-align: middle;
}
.desk .cls-STABLE { background: var(--t-info); }
.desk .cls-ECOSYSTEM { background: var(--t-dim); }
.desk .cls-MEME { background: var(--t-warn); }
.desk .cls-WRAPPED_MAJOR { background: var(--t-text); }

.desk #chart .toolbar { display: flex; align-items: center; gap: var(--t-2); margin-left: var(--t-4); }
.desk .tbtn {
  background: transparent; border: 1px solid var(--t-line-2); color: var(--t-dim);
  padding: 1px 6px; font: 600 9px/1.4 var(--t-ui); letter-spacing: .06em;
  border-radius: 0;
}
.desk .tbtn:hover { border-color: var(--t-accent-dim); color: var(--t-text); }
.desk .tbtn[aria-pressed="true"] { background: var(--t-accent-wash); border-color: var(--t-accent-dim); color: var(--t-accent); }
.desk #chart .panel-body { position: relative; overflow: hidden; }
.desk #chart canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.desk #ohlc {
  position: absolute; top: var(--t-3); left: var(--t-4); z-index: 3;
  display: flex; gap: var(--t-5); pointer-events: none;
  font-size: 10px; color: var(--t-dim);
  text-shadow: 0 0 6px var(--t-bg), 0 0 6px var(--t-bg);
}
.desk #ohlc b { font-weight: 600; color: var(--t-text); }
.desk #ohlc .k { color: var(--t-faint); }

.desk .bookside { display: flex; flex-direction: column; }
.desk .bookrow {
  position: relative; display: grid;
  grid-template-columns: 1fr 74px 40px;
  align-items: center;
  height: 15px; padding: 0 var(--t-3);
  font-size: 11px;
}
.desk .bookrow .bar { position: absolute; top: 1px; bottom: 1px; right: 0; z-index: 0; }
.desk .bookrow.ask .bar { background: var(--t-down-wash); }
.desk .bookrow.bid .bar { background: var(--t-up-wash); }
.desk .bookrow > span { position: relative; z-index: 1; }
.desk .bookrow .px { text-align: left; }
.desk .bookrow.ask .px { color: var(--t-down); }
.desk .bookrow.bid .px { color: var(--t-up); }
.desk .bookrow .sz { text-align: right; color: var(--t-text); }
.desk .bookrow .vn { text-align: right; color: var(--t-faint); font-size: 9px; letter-spacing: .04em; }
.desk .bookrow .vn.hx { color: var(--t-accent); }

.desk #spreadbar {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--t-4);
  padding: 3px var(--t-3);
  background: var(--t-panel-2);
  border-top: 1px solid var(--t-line); border-bottom: 1px solid var(--t-line);
  font-size: 11px;
}
.desk #spreadbar .mid { font-size: 12px; color: var(--t-text); text-align: center; }
.desk #spreadbar .lab { font: 600 8px/1 var(--t-ui); letter-spacing: .09em; text-transform: uppercase; color: var(--t-faint); }
.desk #spreadbar .r { text-align: right; }

.desk #tape .row {
  display: grid; grid-template-columns: 52px 1fr 62px 34px;
  gap: var(--t-3); padding: 1px var(--t-3);
  font-size: 10px;
  align-items: center;
}
.desk #tape .row .tm { color: var(--t-faint); }
.desk #tape .row.buy .px { color: var(--t-up); }
.desk #tape .row.sell .px { color: var(--t-down); }
.desk #tape .row .sz { text-align: right; color: var(--t-dim); }
.desk #tape .row .vn { text-align: right; color: var(--t-faint); font-size: 9px; }
.desk #tape .row.own { background: var(--t-accent-wash-soft); box-shadow: inset 2px 0 0 var(--t-accent); }
.desk #tape .row.own .vn { color: var(--t-accent); }

.desk #rail .panel-body { display: flex; flex-direction: column; }
.desk #rail .sub { border-bottom: 1px solid var(--t-line); }
.desk #rail .sub > h4 {
  margin: 0; padding: 3px var(--t-3);
  background: var(--t-panel-2);
  font: 600 8px/1.3 var(--t-ui); letter-spacing: .09em; text-transform: uppercase; color: var(--t-faint);
  display: flex; align-items: center; gap: var(--t-3);
}
.desk #rail .sub > h4 .sp { margin-left: auto; }
.desk #rail .sub .body { padding: var(--t-3); display: flex; flex-direction: column; gap: var(--t-3); }

.desk .qtyrow { display: grid; grid-template-columns: auto 1fr auto; gap: var(--t-2); align-items: center; }
.desk .qtyrow label { font: 600 8px/1 var(--t-ui); letter-spacing: .09em; text-transform: uppercase; color: var(--t-faint); }
.desk #qty, .desk #volume {
  background: var(--t-bg); border: 1px solid var(--t-line-2); color: var(--t-text);
  padding: 3px var(--t-3); width: 100%; text-align: right; font-size: 12px;
  min-height: 0; border-radius: 0;
}
.desk #qty:focus, .desk #volume:focus { border-color: var(--t-accent); }
.desk .qstep { background: var(--t-raised); border: 1px solid var(--t-line-2); color: var(--t-dim); width: 20px; padding: 2px 0; }
.desk .qstep:hover { color: var(--t-accent); border-color: var(--t-accent-dim); }

.desk .tradebtns { display: grid; grid-template-columns: 1fr 1fr; gap: var(--t-3); }
.desk .trade {
  border: 1px solid; padding: var(--t-3) 0; border-radius: 0;
  font: 600 11px/1.2 var(--t-ui); letter-spacing: .10em;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
}
.desk .trade small { font: 400 11px/1 var(--t-mono); letter-spacing: 0; opacity: .9; }
.desk .trade.buy {
  background: color-mix(in srgb, var(--t-up) 13%, transparent);
  border-color: color-mix(in srgb, var(--t-up) 45%, transparent);
  color: var(--t-up);
}
.desk .trade.buy:hover { background: color-mix(in srgb, var(--t-up) 24%, transparent); }
.desk .trade.sell {
  background: color-mix(in srgb, var(--t-down) 13%, transparent);
  border-color: color-mix(in srgb, var(--t-down) 45%, transparent);
  color: var(--t-down);
}
.desk .trade.sell:hover { background: color-mix(in srgb, var(--t-down) 24%, transparent); }
.desk .trade kbd {
  font: 600 8px/1 var(--t-ui); letter-spacing: .08em; color: var(--t-faint);
  border: 1px solid var(--t-line-2); padding: 1px 3px; margin-top: 1px;
}

.desk #rail .kv, .desk #desk .kv {
  display: grid; grid-template-columns: auto 1fr; gap: 1px var(--t-3); font-size: 10px;
}
.desk #rail .kv .k, .desk #desk .kv .k { color: var(--t-faint); white-space: nowrap; }
.desk #rail .kv .v, .desk #desk .kv .v {
  text-align: right; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.desk .chip {
  display: inline-flex; align-items: center; gap: 3px;
  border: 1px solid var(--t-line-2); padding: 0 4px; height: 14px;
  font: 600 8px/1 var(--t-ui); letter-spacing: .08em; text-transform: uppercase; color: var(--t-dim);
}
.desk .chip.on { border-color: color-mix(in srgb, var(--t-up) 45%, transparent); color: var(--t-up); background: color-mix(in srgb, var(--t-up) 10%, transparent); }
.desk .chip.off { border-color: var(--t-line-2); color: var(--t-faint); }
.desk .chip.warn { border-color: color-mix(in srgb, var(--t-warn) 50%, transparent); color: var(--t-warn); background: color-mix(in srgb, var(--t-warn) 10%, transparent); }
.desk .chip.bad { border-color: color-mix(in srgb, var(--t-down) 45%, transparent); color: var(--t-down); background: color-mix(in srgb, var(--t-down) 10%, transparent); }

.desk #blotter .tabs { display: flex; gap: 0; margin-left: var(--t-4); }
.desk #blotter .tab {
  background: transparent; border: 0; border-bottom: 2px solid transparent;
  color: var(--t-faint); padding: 1px 7px;
  font: 600 9px/1.4 var(--t-ui); letter-spacing: .08em; text-transform: uppercase;
}
.desk #blotter .tab[aria-selected="true"] { color: var(--t-accent); border-bottom-color: var(--t-accent); }
.desk #blotter .tab:hover { color: var(--t-text); }

@media (max-width: 1100px) {
  .desk #desk, .page.desk#desk { display: flex; flex-direction: column; height: auto; }
  .desk #chart { min-height: 280px; }
  .desk .trade { min-height: var(--tap); }
}
