/* Gold Quant Lab - goldpip.us. [M30/M31]
 *
 * The approved visual direction (docs/design/README.md): compact, premium, data-dense, minimal
 * chrome, colour used only for meaning - green profit, red loss and drawdown, amber caution.
 * Gold is the single accent and is used for identity, never for a value. English throughout;
 * Roman Urdu appears only inside a trade explanation card.
 *
 * Contrast: every text colour here is checked against its own surface at 4.5:1 or better.
 */

:root {
  /* The FXVM-inspired direction: bright white, cool blue surfaces, deep navy type, one electric
     blue accent, and green/red reserved for money. The palette is the whole of this change -
     no rule below moves a box or touches behaviour, because every component already reads its
     colour from a name here rather than writing one into itself. [M79]

     The names are the old ones. `--gold` now holds a blue, which reads oddly until you see why:
     renaming it would have meant editing 450 call sites in one commit, and a redesign that
     large should not also be a rename that large. The aliases below say what each one now means
     and the names migrate afterwards, separately, where a mistake is visible. */

  /* -------- the brand, as specified in the brief */
  --brand: #0B57E3;
  --brand-dark: #063FAF;
  --brand-soft: #EAF2FF;
  --navy: #12324A;

  --bg: #F5F9FF;
  --surface: #FFFFFF;
  --surface-2: #FBFCFF;
  --surface-3: #FCFDFF;
  --line: #DDE8F5;
  --line-strong: #C9DDF8;
  /* Softer than --line, for row separators that should be felt rather than seen. */
  --line-soft: #EDF3FB;
  --text: #17324D;
  --text-dim: #5B6E83;
  /* The brief's muted grey is #8A9AAA, which measures 2.88:1 on white and fails for text of any
     size. It stays available as --muted-line for rules and icons; type gets this instead, which
     is the same colour taken down only until it passes at 4.76:1. */
  --text-faint: #5C6E7F;

  /* -------- legacy accent names, now carrying the blue */
  --gold: var(--brand);
  --gold-hover: var(--brand-dark);
  --gold-tint: var(--brand-soft);
  --gold-dim: #A9C8F7;
  /* The gold could never carry white type - white on #C8942D measured 2.72:1, so every primary
     button in the old palette wore dark text against its own brand colour. White on #0B57E3
     measures 6.02:1, so the button finally reads the way a primary button should. */
  --on-gold: #FFFFFF;
  --up: #16B878;
  --down: #EF5D68;
  --down-tint: #FDEDEE;
  /* The counterpart to --down-tint, which existed alone: the palette could tint a loss
     and a caution but had no ground for a confirmation. --up-text on it measures
     4.69:1, so the success note carries body type rather than only a colour. [M79] */
  --up-tint: #E8F8F0;
  --amber: #E8A33D;
  --amber-tint: #FFF4E5;
  --blue: var(--brand);
  /* The palette above is the identity: fills, borders, tints and badges use it exactly as the
     brief specifies. These exist because a colour that is right for a 2px border or a chip fill
     is usually too light to carry 12px type - measured on the new palette, not assumed:
       #16B878 on white  2.57:1     #EF5D68 on white  3.26:1
       #8A9AAA on white  2.88:1     #E8A33D on white  2.20:1
     All below WCAG's 4.5:1 for body text, and on a trading page those numbers *are* the body
     text: profit and loss figures are the single most-read thing on the site. Each is the same
     hue taken down only until it passes on every ground it can land on - white, the soft blue
     section, and its own tint, which a closing row and a caution panel both use.
     The brand blue needs no darkening: #0B57E3 already measures 6.02:1 on white. [M79] */
  --gold-text: var(--brand);
  --up-text: #0F7D52;
  --down-text: #DA1524;
  --amber-text: #986213;
  /* The edge a card is actually drawn with. --line-soft reads as almost nothing on white, which
     left every panel floating without a boundary; this is the same warm grey taken far enough
     to be seen. Kept as its own token rather than reusing --line-strong, because separators
     inside a card and the card's own outline should be able to move apart. */
  --line-card: #D3E2F4;
  /* Subtle, never a glow. Two very shallow layers read as lift; one deep one reads as a modal.
     Tinted toward the navy rather than neutral black, so a card's shadow belongs to the same
     palette as its border instead of greying the blue underneath it. */
  --shadow-card:
    0 1px 2px rgba(16, 50, 90, .04),
    0 2px 6px -1px rgba(16, 50, 90, .06),
    0 8px 20px -14px rgba(16, 50, 90, .16);
  --shadow-pop: 0 10px 24px -12px rgba(16, 50, 90, .22), 0 2px 6px rgba(16, 50, 90, .06);
  --scrim: rgba(18, 50, 74, .38);
  --radius: 10px;
  /* Cards sit slightly softer than controls - 14px against 10px - which is the difference
     between a surface and a thing you press. */
  --radius-card: 14px;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", "Cascadia Mono", Consolas, monospace;
  --sans: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --wrap: 1240px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Links inside running text are underlined, not merely coloured: colour alone fails WCAG 1.4.1
   for readers who cannot distinguish it. Navigation, buttons and card links are unambiguous
   from their surroundings, so those opt out. */
a { color: var(--blue); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .17em; }
a:hover { text-decoration-thickness: 2px; }
.site-nav a, .app-nav a, .crumbs a, .brand, .btn, .link-grid a, .foot-links a, .skip { text-decoration: none; }
.site-nav a:hover, .app-nav a:hover, .crumbs a:hover, .foot-links a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 3px; }
[hidden] { display: none !important; }
img, svg { max-width: 100%; height: auto; }

h1, h2, h3 { line-height: 1.25; letter-spacing: -0.015em; margin: 0 0 .5em; }
h1 { font-size: clamp(1.6rem, 1.15rem + 1.7vw, 2.3rem); font-weight: 650; }
h2 { font-size: 1.22rem; font-weight: 620; }
h3 { font-size: 1.02rem; font-weight: 620; margin-top: 1.6em; }
p { margin: 0 0 1em; }
code { font-family: var(--mono); font-size: .92em; background: var(--surface-2); padding: 1px 5px; border-radius: 4px; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }

.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;
}
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--gold); color: var(--on-gold); padding: 10px 16px; font-weight: 600;
}
.skip:focus { left: 8px; top: 8px; }

/* ------------------------------------------------------------------ header */

.site-head {
  border-bottom: 1px solid var(--line-card);
  background: rgba(255, 255, 255, .88);
  backdrop-filter: blur(10px);
  position: sticky; top: 0; z-index: 30;
}
.head-inner { display: flex; align-items: center; gap: 16px; min-height: 74px; }
.brand { display: flex; align-items: center; gap: 17px; color: var(--text); text-decoration: none; }
.brand:hover { text-decoration: none; }
/* The announcement strip. Full-bleed accent above everything, including the header, so the
   page opens on the brand rather than on a navigation bar. Kept to one line: the moment it
   wraps on a phone it stops being a strip and becomes a paragraph nobody reads. */
.promo-bar {
  background: var(--gold); color: var(--on-gold); text-align: center;
  font-size: .82rem; font-weight: 600; padding: 9px 16px; letter-spacing: .01em;
}
.promo-bar .promo-sep { opacity: .6; margin: 0 8px; }
/* The rule above says one line, and at 390px the full sentence was two. The second clause is
   the one that can go: "Systematic gold trading" is the claim, "Transparent investor reporting"
   is the elaboration, and an elaboration that wraps costs more than it adds. */
@media (max-width: 560px) {
  .promo-bar .promo-sep, .promo-bar .promo-b { display: none; }
  .promo-bar { font-size: .78rem; padding: 8px 14px; }
}

/* The wordmark: a deep-blue-to-cyan sweep across real text.
   Text, not an image. It stays selectable, searchable, translatable and legible to a screen
   reader without an alt attribute standing in for it, and it is sharp at any pixel density -
   which a 107x48 PNG is not. The gradient is painted through the glyphs with background-clip. */
:root {
  --brand-sweep: linear-gradient(96deg, #063FAF 0%, #0B57E3 46%, #12A5F0 100%);
  /* The market strip's band. Not white: in the approved reference it sits a shade below the page
     as a cool, almost-grey light tone, which is what separates it from the header above without
     a heavy rule. Named so the exact shade is one line to change. */
  --ticker-bg: #EEF1F6;
  --ticker-line: #D5DDE8;
  /* The travelling lights on the strip's border. Named because they are the one place red
     appears without meaning loss, and somebody will want to change them. [M80] */
  --ticker-light: #FF2D45;
  --ticker-light-soft: #FF8792;
}
/* A candle standing in for a letter. [M84]
   Sized in em so it tracks the wordmark at any size, and nested inside .brand-text so that em
   resolves against 2.75rem rather than against the link's inherited 16px - which is how the
   first attempt produced a 12px candle beside a 32px letter. */
.brand-text .cdl {
  display: inline-block; width: .34em; height: .78em; vertical-align: -.045em;
  margin: 0 .012em; overflow: visible;
}
.brand-text .cdl svg { display: block; width: 100%; height: 100%; overflow: visible; }

/* The letter each candle replaces, present for text but not for the eye. Clipped rather than
   `display: none`, which would take it out of the accessibility tree and out of a copy-paste
   along with it - the whole point is that the markup still spells GoldPip. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* The candles turn, on two different periods so they never move together. [M83]
   The swing stops at 52 degrees: past that a candle goes edge-on and becomes a one-pixel line,
   and a wordmark that loses a letter every few seconds reads as broken rather than as alive. */
.brand-text .cdl g {
  transform-box: fill-box; transform-origin: 50% 50%;
  animation: candle-swing 7s ease-in-out infinite;
}
.brand-text .cdl.down g { animation-duration: 9.5s; animation-delay: -2.6s; }
@keyframes candle-swing {
  0%, 100% { transform: rotateY(-52deg); }
  50%      { transform: rotateY(52deg); }
}
/* A logo that moves forever is a logo somebody has to look away from. */
@media (prefers-reduced-motion: reduce) {
  .brand-text .cdl g { animation: none; transform: none; }
}

/* A heavier, more geometric face than the body text, which is deliberately humanist. Loaded as
   a five-glyph subset, so the second family costs a few hundred bytes. The fallback is the body
   family at the same weight - the mark stays bold and legible if the subset never arrives. */
.brand-text {
  /* The body family at its heaviest, not a second family. [M80]
     Poppins was loaded as a five-glyph subset for this one word - and nine other rules asked for
     it too, so every button declaring Poppins rendered its P, e, i, l and r from Poppins and
     every other letter from the fallback. Mixed letterforms inside single words, on the most
     prominent controls on the site. Jakarta 800 is already loaded for the body, so the wordmark
     now costs nothing, the mismatch is gone, and the identity is one family distinguished by
     weight and tracking rather than by importing a second personality.

     Tracking is opened to .026em: the negative letter-spacing that suits body headings pulls a
     five-letter wordmark into a lump, and a logo wants its letters to sit apart enough to be
     read as shapes. */
  /* Archivo Black. [M81]
     Jakarta 800 is that family's heaviest weight, so "bolder" could only be answered by a face
     that has a 900 - enlarging 800 makes the word bigger, not heavier, which is a different
     thing and the wrong one. Archivo is a grotesque: tighter apertures and flatter terminals
     than a geometric face, so at 900 it reads as confident rather than as round and soft.
     Subsetted to the letters of the name, so the second family costs about a kilobyte. */
  font-family: "Archivo", var(--sans);
  font-weight: 900; font-size: 2.75rem; white-space: nowrap; letter-spacing: .05em;
  line-height: 1; color: var(--brand-dark);
}
@supports (background-clip: text) or (-webkit-background-clip: text) {
  /* Guarded, because the fallback of this failing is transparent text on a white header - a
     logo that is not there at all. Without the guard, one unsupported browser loses the brand. */
  .brand-text {
    background: var(--brand-sweep);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}
/* On the navy footer the word reverts to solid white, because the sweep would disappear into
   the ground. The candles keep their colours: red and green mean something, and a white candle
   means nothing. [M84] */
.site-foot .brand-text { background: none; color: #fff; }

.site-nav { margin-left: auto; }
.site-nav ul { display: flex; gap: 2px; list-style: none; margin: 0; padding: 0; flex-wrap: wrap; }
.site-nav a {
  display: block; padding: 7px 11px; border-radius: 7px;
  color: var(--text-dim); font-size: .875rem; text-decoration: none;
}
.site-nav a:hover { background: var(--surface-3); color: var(--text); text-decoration: none; }
.site-nav a[aria-current="page"] {
  background: var(--gold-tint); color: var(--text);
  box-shadow: inset 0 -2px 0 var(--gold);
}

/* -------------------------------------------------------------- breadcrumbs */

.crumbs { padding-top: 14px; }
.crumbs ol { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0; padding: 0; font-size: .82rem; }
.crumbs li + li::before { content: "/"; color: var(--text-faint); margin-right: 6px; }
.crumbs a { color: var(--text-faint); }
.crumbs [aria-current] { color: var(--text-dim); }

/* -------------------------------------------------------------------- main */

main { padding: 26px 20px 70px; }
.lede { font-size: 1.06rem; color: var(--text-dim); max-width: 72ch; }

.hero { padding: 14px 0 26px; }
.hero h1 { max-width: 20ch; }
.hero-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 20px; }

/* inline-flex, not inline-block: a block button centres horizontally through `text-align` and
   vertically through whatever the line box happens to be, so a label sits off-centre the moment
   the button has a min-height, an icon, or a second line. Flex centres it on both axes by
   construction, at every size, which is what makes a row of buttons look set rather than
   assembled. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 20px; min-height: 44px; border-radius: 8px; text-align: center;
  background: var(--gold); color: var(--on-gold); font-weight: 700; font-size: .9rem;
  line-height: 1.2; border: 1px solid var(--gold); cursor: pointer; text-decoration: none;
}
.btn:hover { background: var(--gold-hover); text-decoration: none; }
.btn.ghost { background: transparent; color: var(--text); border-color: var(--line); }
.btn.ghost:hover { background: var(--surface-2); }

/* ------------------------------------------------------------------- cards */

.cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 10px; margin: 0 0 20px;
}
.card {
  background: var(--surface); border: 1px solid var(--line-card);
  border-radius: var(--radius-card); padding: 13px 15px 14px; min-width: 0;
  box-shadow: var(--shadow-card);
}
.card .label {
  font: 600 10.5px/1 var(--mono); letter-spacing: .09em; color: var(--text-faint);
  text-transform: uppercase; margin: 0 0 9px;
}
.card .value { font: 640 1.42rem/1.15 var(--mono); letter-spacing: -.02em; margin: 0; }
.card .sub { font-size: .78rem; color: var(--text-faint); margin: 5px 0 0; }

/* ------------------------------------------------------------------ panels */

.panel {
  background: var(--surface); border: 1px solid var(--line-card);
  border-radius: var(--radius-card); margin: 0 0 16px; overflow: hidden; min-width: 0;
  box-shadow: var(--shadow-card);
}
/* Lift on hover, but only where there is something to click. A card that rises under the cursor
   is telling the reader it is a button; a figure that is only a figure should stay still.
   `:has` is the whole condition, so a browser without it simply gets no lift. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .card:has(a):hover, .panel:has(a):hover {
    transform: translateY(-2px); border-color: var(--line-strong);
    box-shadow: var(--shadow-pop);
  }
  .card, .panel { transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
}
.panel-head {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 13px 17px; border-bottom: 1px solid var(--line-card); background: var(--surface-2);
}
.panel-head h2, .panel-head h3 { margin: 0; font-size: 1rem; }
.panel-head .hint { margin-left: auto; color: var(--text-faint); font-size: .78rem; }
.panel-body { padding: 16px 17px; }
.panel-body > :last-child { margin-bottom: 0; }

.grid-halves { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 16px; align-items: start; }

.link-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 10px; }
.link-grid a {
  display: block; padding: 14px 16px; background: var(--surface-2);
  border: 1px solid var(--line-card); border-radius: 9px; color: var(--text); text-decoration: none;
}
.link-grid a:hover { border-color: var(--gold-dim); text-decoration: none; }
.link-grid h3 { margin: 0 0 4px; font-size: .95rem; }
.link-grid p { margin: 0; font-size: .84rem; color: var(--text-faint); }

/* ------------------------------------------------------------------ colour */

.up { color: var(--up-text); }
.down { color: var(--down-text); }
.dim { color: var(--text-faint); }
.mono { font-family: var(--mono); }
.nowrap { white-space: nowrap; }

.tag {
  display: inline-block; padding: 2px 8px; border-radius: 4px;
  font: 600 10.5px/1.7 var(--mono); letter-spacing: .05em;
  border: 1px solid var(--line); color: var(--text-dim); white-space: nowrap;
}
.tag.sell { color: var(--down-text); border-color: color-mix(in srgb, var(--down) 38%, transparent); }
.tag.buy { color: var(--up-text); border-color: color-mix(in srgb, var(--up) 38%, transparent); }
.tag.open { color: var(--blue); border-color: color-mix(in srgb, var(--blue) 38%, transparent); }
.tag.valid { color: var(--up-text); border-color: color-mix(in srgb, var(--up) 38%, transparent); }
.tag.rejected { color: var(--amber-text); border-color: color-mix(in srgb, var(--amber) 38%, transparent); }
.tag.gold { color: var(--gold-text); border-color: var(--gold-dim); }

.notice {
  background: var(--surface-2); border: 1px solid var(--line-card);
  border-left: 4px solid var(--line-strong); border-radius: 8px;
  padding: 12px 15px; color: var(--text-dim); font-size: .88rem; margin: 0 0 14px;
}
.notice.warn { border-left-color: var(--amber); }
.notice.info { border-left-color: var(--blue); }
/* Reserved for the one thing that stops the whole system being a trading system: the engine
   not running. Loud on purpose, and not used for anything a reader can safely scroll past. */
.notice.bad {
  border-left-color: var(--down);
  border-color: color-mix(in srgb, var(--down) 38%, transparent);
  background: var(--down-tint);
  color: var(--text);
}

.ticks { padding-left: 1.1em; margin: 0 0 1em; }
.ticks li { margin-bottom: .5em; color: var(--text-dim); }
.stages { padding-left: 1.2em; }
.stages li { margin-bottom: .55em; color: var(--text-dim); }

/* ------------------------------------------------------------------ tables */

.table-wrap { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; font-size: .84rem; }
caption { text-align: left; }
th {
  text-align: left; padding: 9px 13px; font: 600 10.5px/1.3 var(--mono);
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-dim);
  border-bottom: 2px solid var(--line-card); white-space: nowrap; background: var(--surface-2);
}
tbody th { text-transform: none; font-size: .82rem; letter-spacing: 0; color: var(--text-dim); background: none; font-family: var(--sans); }
td { padding: 10px 13px; border-bottom: 1px solid var(--line); vertical-align: top; }
tbody tr:last-child td, tbody tr:last-child th { border-bottom: 0; }
tbody tr:hover { background: var(--surface-2); }
td.num, th.num { text-align: right; font-family: var(--mono); white-space: nowrap; }
.reason { color: var(--text-dim); max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------------------------------------------------------- key/value */

.kv { display: grid; grid-template-columns: minmax(140px, max-content) 1fr; gap: 8px 20px; margin: 0 0 1em; font-size: .88rem; }
.kv dt { color: var(--text-faint); }
.kv dd { margin: 0; font-family: var(--mono); word-break: break-word; }
/* The mono is right for what this list was built for - tickets, prices, timestamps - and wrong
   for a sentence. `.prose` is the opt-out rather than the default, so every figure list on the
   site keeps its alignment. */
.kv.prose dd { font-family: var(--sans); }

/* ------------------------------------------------------------- trade detail */

.explain {
  background: var(--gold-tint);
  border: 1px solid var(--gold-dim); border-radius: 9px; padding: 15px 17px; margin-bottom: 16px;
}
.explain .why { font-size: 1.02rem; margin: 0 0 8px; }
.gates { list-style: none; margin: 0; padding: 0; }
.gate-row {
  display: grid; grid-template-columns: 18px minmax(120px, 190px) 1fr; gap: 10px;
  align-items: baseline; font-size: .82rem; padding: 7px 0; border-bottom: 1px solid var(--line-soft);
}
.gate-row:last-child { border-bottom: 0; }
.gate-row .mark.pass { color: var(--up); }
.gate-row .mark.fail { color: var(--down); }
.gate-row .gname { font-family: var(--mono); color: var(--text-dim); }
.gate-row .gdet { color: var(--text-faint); font-family: var(--mono); }

.timeline { list-style: none; position: relative; padding: 0 0 0 22px; margin: 0; }
.timeline::before { content: ""; position: absolute; left: 4px; top: 8px; bottom: 8px; width: 1px; background: var(--line); }
.tl-item { position: relative; padding-bottom: 18px; }
.tl-item:last-child { padding-bottom: 0; }
.tl-item::before {
  content: ""; position: absolute; left: -22px; top: 7px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--surface); border: 2px solid var(--line);
}
.tl-item.locked::before { border-color: var(--up); }
.tl-item.exit::before { border-color: var(--gold); }
.tl-head { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin: 0 0 3px; font-size: .9rem; }
.tl-meta { color: var(--text-faint); font: 400 .8rem var(--mono); }
.tl-body { color: var(--text-dim); font-size: .85rem; margin: 0 0 2px; }
.retention-bar { height: 6px; border-radius: 3px; background: var(--surface-3); overflow: hidden; margin-top: 8px; max-width: 320px; }
.retention-bar span { display: block; height: 100%; background: var(--up); }

/* ---------------------------------------------------------------- baskets */

.basket { background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius); margin-bottom: 10px; }
.basket summary { padding: 13px 16px; cursor: pointer; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.basket summary::-webkit-details-marker { display: none; }
.basket summary::before { content: "▶"; color: var(--text-faint); font-size: .65rem; }
.basket[open] summary::before { content: "▼"; }
.sum-stats { margin-left: auto; display: flex; gap: 16px; font: 500 .82rem var(--mono); color: var(--text-dim); flex-wrap: wrap; }
.basket-body { padding: 0 16px 16px; }

/* ------------------------------------------------------------------- prose */

.prose { max-width: 74ch; }
.prose h2 { margin-top: 1.9em; }
.prose p, .prose li { color: var(--text-dim); }
.prose strong { color: var(--text); }

/* -------------------------------------------------------------------- auth */

.auth-wrap { display: grid; place-items: center; min-height: 60vh; padding: 20px 0; }
.auth-card {
  width: 100%; max-width: 400px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 14px; padding: 30px 28px;
}
.auth-card h1 { font-size: 1.35rem; margin-bottom: .25em; }
.auth-sub { color: var(--text-faint); font-size: .88rem; margin-bottom: 22px; }
.auth-card label { display: block; font-size: .82rem; color: var(--text-dim); margin-bottom: 6px; font-weight: 550; }
/* Every visible field in the card, not a list of types. [M80]
   It was `input[type="tel"], input[type="password"]`, so the moment the identity field became
   `type="text"` - one box for an address or a number - it fell out of the selector and rendered
   as a raw browser input: narrower than the field under it, white against the other's tint, no
   radius. Styling by role rather than by type is what stops that happening to the next field
   somebody adds. */
.auth-card input:not([type="hidden"]) {
  width: 100%; box-sizing: border-box;
  padding: 11px 13px; background: var(--bg); border: 1px solid var(--line);
  border-radius: 8px; color: var(--text); font-size: 1rem; margin-bottom: 4px;
}
.auth-card input:focus { outline: none; border-color: var(--gold-dim); box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 22%, transparent); }
.auth-card button[type="submit"] {
  width: 100%; padding: 12px; margin-top: 14px; background: var(--gold); color: var(--on-gold);
  border: 0; border-radius: 8px; font: 640 .95rem var(--sans); cursor: pointer;
}
.auth-card button[type="submit"]:hover { background: var(--gold-hover); }
.field-help { font-size: .76rem; color: var(--text-faint); margin: 0 0 16px; }
.auth-error {
  background: var(--down-tint); border: 1px solid color-mix(in srgb, var(--down) 34%, transparent);
  color: var(--down); border-radius: 8px; padding: 10px 13px; font-size: .85rem; margin-bottom: 16px;
}
.auth-alt { font-size: .85rem; color: var(--text-faint); margin: 16px 0 0; text-align: center; }
.auth-note { font-size: .76rem; color: var(--text-faint); margin: 18px 0 0; padding-top: 16px; border-top: 1px solid var(--line-soft); }

.toggle { display: flex; gap: 12px; align-items: flex-start; padding: 12px 0; border-bottom: 1px solid var(--line-soft); }
.toggle input { width: 18px; height: 18px; margin-top: 2px; accent-color: var(--gold); flex: none; }
.toggle label { font-size: .92rem; color: var(--text); font-weight: 550; display: block; margin-bottom: 2px; }
.toggle .field-help { margin: 0; }
.toggle.danger label { color: var(--down); }
form.panel button[type="submit"] {
  margin-top: 18px; padding: 10px 20px; background: var(--gold); color: var(--on-gold);
  border: 0; border-radius: 8px; font: 640 .9rem var(--sans); cursor: pointer;
}

/* ------------------------------------------------------------------ footer */

/* Navy, because the footer is where the page ends and a pale one just runs out. It also gives
   the whole document a base to sit on, which is the job the old --surface-2 strip never did. */
.site-foot {
  border-top: 0; background: var(--navy); color: #C3D3E2;
  padding: 52px 0 20px; margin-top: 64px;
}
/* Three equal link columns. The wide 2fr lead column held an about-and-disclaimer block that
   was removed; leaving the track behind would have stretched the first list to twice the width
   of the other two for no reason. */
.foot-inner { display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px; }
.foot-links h2 {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .11em; color: #FFFFFF;
  font-family: var(--sans); font-weight: 700; margin: 0 0 14px;
}
.foot-links ul { list-style: none; margin: 0; padding: 0; }
.foot-links li { margin-bottom: 3px; }
.foot-links a { font-size: .875rem; color: #C3D3E2; display: block; padding: 4px 0; }
.foot-links a:hover { color: #FFFFFF; }
.foot-bottom {
  border-top: 1px solid rgba(255, 255, 255, .11); margin-top: 34px; padding-top: 18px;
}
.foot-bottom p { font-size: .78rem; color: #8CA3B8; margin: 0; }

/* --------------------------------------------------------------- app nav */

.app-nav { margin: 0 0 22px; border-bottom: 1px solid var(--line-soft); }
.app-nav ul { display: flex; gap: 4px; list-style: none; margin: 0; padding: 0; overflow-x: auto; }
.app-nav a { display: block; padding: 9px 14px; color: var(--text-faint); font-size: .88rem; border-bottom: 2px solid transparent; white-space: nowrap; }
.app-nav a:hover { color: var(--text); text-decoration: none; }
.app-nav a[aria-current="page"] { color: var(--gold); border-bottom-color: var(--gold); }

/* -------------------------------------------------------------- freshness */

.freshness {
  display: inline-flex; align-items: center; gap: 7px; font-size: .76rem;
  color: var(--text-faint); font-family: var(--mono);
}
/* A bigger light. [M83] At 7px it read as a bullet point beside the word; the dot is the part
   that carries the state at a glance, so it is the part worth seeing. The soft ring around it
   is what stops a 10px circle looking like a stray character. */
.freshness .dot {
  width: 10px; height: 10px; border-radius: 50%; background: var(--up); flex: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--up) 22%, transparent);
}
.freshness.delayed { color: var(--amber); }
.freshness.delayed .dot { background: var(--amber); box-shadow: 0 0 0 3px color-mix(in srgb, var(--amber) 22%, transparent); }
.freshness.stale { color: var(--down); }
.freshness.stale .dot { background: var(--down); box-shadow: 0 0 0 3px color-mix(in srgb, var(--down) 22%, transparent); }
.flash { animation: flash .9s ease-out; }
@keyframes flash { from { background: var(--gold-tint); } to { background: transparent; } }

/* ------------------------------------------------------------ responsive */

@media (max-width: 980px) {
  .foot-inner { grid-template-columns: 1fr 1fr; }
  .grid-halves { grid-template-columns: 1fr; }
}

@media (max-width: 780px) {
  /* No header nav on a phone, and nothing to open it with. [M80]
     The floating button is gone; the footer carries every one of these links in four labelled
     groups on every page, so nothing became unreachable - the navigation simply moved to the
     end of the page, which is where somebody who has finished reading looks for it anyway. */
  .site-nav { display: none; }
  .head-inner { flex-wrap: wrap; }
  main { padding: 18px 16px 60px; }
  .wrap { padding: 0 16px; }
  .cards { grid-template-columns: repeat(auto-fit, minmax(142px, 1fr)); gap: 8px; }
  .card .value { font-size: 1.2rem; }
  .kv { grid-template-columns: 1fr; gap: 2px; }
  .kv dt { margin-top: 10px; font-size: .78rem; }
  .gate-row { grid-template-columns: 18px 1fr; }
  .gate-row .gdet { grid-column: 2; }
  .reason { max-width: 200px; }
  .foot-inner { grid-template-columns: 1fr; gap: 20px; }
  .sum-stats { margin-left: 0; width: 100%; gap: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ------------------------------------------------------------- dashboard */

.dash-head { display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap; margin-bottom: 18px; }
.cards.tight { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); margin-bottom: 16px; }
.panel-body.flush { padding: 0; }

.period-bar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 4px 0 16px; }
.period-bar button {
  padding: 8px 15px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 8px; color: var(--text-dim); font: 550 .85rem var(--sans); cursor: pointer;
}
.period-bar button:hover { background: var(--surface-2); color: var(--text); }
.period-bar button.on { background: var(--gold); border-color: var(--gold); color: var(--on-gold); }
.period-note { margin-left: auto; font-size: .76rem; color: var(--text-faint); font-family: var(--mono); }

.grid-2-1 { display: grid; grid-template-columns: minmax(0, 1.85fr) minmax(0, 1fr); gap: 16px; align-items: start; }

/* the chart */
.chart { margin: 0; position: relative; }
.eqchart { width: 100%; height: 280px; display: block; }
.eqchart .ax { fill: var(--text-faint); font: 10px var(--mono); }
.chart .tip {
  position: absolute; top: 8px; pointer-events: none;
  background: var(--surface-3); border: 1px solid var(--line); border-radius: 8px;
  padding: 9px 12px; font: 11.5px/1.6 var(--mono); color: var(--text-dim);
  min-width: 180px; box-shadow: var(--shadow-pop);
}
.chart .tip strong { display: block; color: var(--text); margin-bottom: 4px; font-size: 11px; }
.chart .tip span { display: flex; justify-content: space-between; gap: 14px; }
.chart .tip b { color: var(--text); font-weight: 600; }
.chart-toggle { margin-left: auto; display: flex; gap: 4px; flex-wrap: wrap; }
.chart-toggle button {
  padding: 5px 10px; background: transparent; border: 1px solid var(--line);
  border-radius: 6px; color: var(--text-faint); font: 500 .74rem var(--sans); cursor: pointer;
}
.chart-toggle button.on { background: var(--surface-3); color: var(--text); border-color: var(--line); }

/* comparisons */
.cmp-title { font-size: .82rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-faint); font-family: var(--mono); margin: 0 0 8px; }
.cmp-title + .cmp { margin-bottom: 22px; }
table.cmp th[scope="row"] { color: var(--text-dim); }
table.cmp td { padding: 7px 10px; }

/* daily table: the day's tone is carried by a leading bar, not by a wash of colour over the
   numbers, so the figures stay readable and colour is not the only signal. */
table.daily tbody th[scope="row"] { border-left: 3px solid var(--line); padding-left: 12px; }
table.daily tr.win th[scope="row"] { border-left-color: var(--up); }
table.daily tr.loss th[scope="row"] { border-left-color: var(--down); }
table.daily tr.flat th[scope="row"] { border-left-color: var(--text-faint); }

@media (max-width: 980px) {
  .grid-2-1 { grid-template-columns: 1fr; }
  .period-note { margin-left: 0; width: 100%; }
}

/* A row the broker has already closed but the journal has not yet recorded. It is dimmed and
   labelled rather than removed: the position was real and its record is arriving. */
/* Dimming a whole row with opacity drops every colour inside it below the contrast floor -
   the header, the direction tag and the rule code all failed together. The row is marked with
   a tint and its amber edge instead, which an assistive reader can also perceive. */
tr.closing { background: var(--gold-tint); }
tr.closing td, tr.closing th { color: var(--text-faint); }
tr.closing th[scope="row"], tr.closing td:first-child { border-left: 3px solid var(--amber); }

/* ------------------------------------------------- public performance section */

.perf .period-bar { margin: 0 0 16px; }
.period-bar a {
  display: inline-block; padding: 8px 15px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 8px; color: var(--text-dim);
  font: 550 .85rem var(--sans); text-decoration: none;
}
.period-bar a:hover { background: var(--surface-3); color: var(--text); text-decoration: none; }
.period-bar a.on { background: var(--gold); border-color: var(--gold); color: var(--on-gold); }

.perf-cards { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); margin-bottom: 18px; }
.perf-sub { font-size: 1rem; margin: 26px 0 10px; }

.chart { margin: 0 0 6px; position: relative; }
/* The viewBox sets the aspect; height:auto keeps it from being squashed on a phone, and the
   stroke is vector-effect'd so the line stays one pixel at any scale. */
.eqchart { width: 100%; height: auto; display: block; }
.eqchart .ax { fill: var(--text-faint); font: 10px var(--mono); }
.chart-empty { padding: 30px 0; text-align: center; font-size: .88rem; }
.chart-legend {
  display: flex; gap: 16px; flex-wrap: wrap; align-items: baseline;
  font-size: .8rem; color: var(--text-faint); margin: 8px 0 0;
}
.chart-legend b { color: var(--text); }

@media (max-width: 780px) {
  .eqchart { min-height: 200px; }
  .perf-cards { grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); }
  .period-bar a { padding: 7px 12px; font-size: .8rem; }
}

/* ------------------------------------------------------------ feed health */

.health.degraded { border-color: color-mix(in srgb, var(--amber) 50%, transparent); }
.health.engine-down { border-color: color-mix(in srgb, var(--down) 50%, transparent); }
/* A down engine is not one amber card among three. The panel itself changes colour, so the
   state is legible from across the room and before any text is read. */
.health.engine-down .panel-head h2,
.health.engine-down .panel-head h3 { color: var(--down); }
.health.engine-down .panel-head .hint { color: var(--down); }

/* Broker open vs engine managed. Two numbers that must agree, shown side by side so the
   disagreement is the thing a reader sees rather than something they have to work out. */
.coverage {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 18px; align-items: baseline;
  background: var(--surface-2); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--line); border-radius: 9px;
  padding: 13px 15px; margin-bottom: 12px;
}
.coverage.ok { border-left-color: var(--up); }
.coverage.warn { border-left-color: var(--amber); }
.coverage.bad { border-left-color: var(--down); background: var(--down-tint); }
.coverage-pair { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.coverage-label { font: 600 10.5px/1 var(--mono); letter-spacing: .09em; text-transform: uppercase; color: var(--text-faint); }
.coverage-value { font: 640 1.5rem/1 var(--mono); }
.coverage.bad .coverage-value { color: var(--down); }
.coverage-verdict { grid-column: 1 / -1; margin: 4px 0 0; font: 600 .8rem/1.35 var(--mono); letter-spacing: .04em; }
.coverage.ok .coverage-verdict { color: var(--text-faint); font-weight: 400; letter-spacing: 0; font-family: inherit; }
.coverage.warn .coverage-verdict { color: var(--amber); }
.coverage.bad .coverage-verdict { color: var(--down); }
.coverage .feed-sub { grid-column: 1 / -1; margin: 2px 0 0; }
.calendar-health { margin-bottom: 12px; }
.coverage-restore { grid-column: 1 / -1; margin: 6px 0 0; font-size: .78rem; color: var(--text-faint); }
.coverage-restore.bad { color: var(--down); font-weight: 600; }
.feeds { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; margin-bottom: 16px; }
.feed {
  background: var(--surface-2); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--line); border-radius: 9px; padding: 13px 15px;
}
.feed.ok { border-left-color: var(--up); }
.feed.warn { border-left-color: var(--amber); }
.feed.bad { border-left-color: var(--down); }
.feed-title { font: 600 10.5px/1 var(--mono); letter-spacing: .09em; text-transform: uppercase; color: var(--text-faint); margin: 0 0 8px; }
.feed-state { font: 640 1.3rem/1.1 var(--mono); margin: 0; }
.feed.ok .feed-state { color: var(--up); }
.feed.warn .feed-state { color: var(--amber); }
.feed.bad .feed-state { color: var(--down); }
.feed-sub { font-size: .76rem; color: var(--text-faint); margin: 5px 0 10px; }
.feed-kv { grid-template-columns: minmax(96px, auto) 1fr; gap: 4px 12px; font-size: .78rem; margin: 0; }
.feed-kv dd { font-size: .78rem; }
tr.down th[scope="row"] { color: var(--down); }

/* --------------------------------------- closed at broker, awaiting the journal */

.pending { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line-soft); }
.pending-head {
  font: 600 10.5px/1 var(--mono); letter-spacing: .09em; text-transform: uppercase;
  color: var(--amber); margin: 0 0 6px;
}
.pending .dim { font-size: .82rem; margin: 0 0 10px; }
.pending table { background: var(--gold-tint); }

/* -------------------------------------------------- readable rule names */

.rule { display: inline-flex; flex-direction: column; gap: 1px; line-height: 1.3; }
.rule-name { font-weight: 550; white-space: nowrap; }
.rule-code { font-size: .68rem; color: var(--text-faint); white-space: nowrap; }

.idea-sub { font-size: .95rem; margin: 22px 0 8px; }
.reasons { margin: 0 0 1em; padding-left: 1.15em; }
.reasons li { color: var(--text-dim); margin-bottom: .35em; }
.small { font-size: .78rem; }

/* ------------------------------------------------- masked trade reasoning */

.reveal {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--surface-2); border: 1px dashed var(--line);
  border-radius: 6px; padding: 4px 10px; cursor: pointer;
  color: var(--text-faint); font: 500 .78rem var(--sans);
}
.reveal:hover { border-color: var(--gold-dim); color: var(--text-dim); }
.reveal-eye { font-size: .9rem; line-height: 1; filter: grayscale(1); opacity: .8; }
.explain .reveal, .reveal.block { padding: 8px 14px; font-size: .88rem; }
.revealed-text { color: var(--text-dim); }

.reveal-dialog {
  position: fixed; inset: 0; z-index: 80; display: grid; place-items: center;
  background: var(--scrim); padding: 20px;
}
.reveal-dialog form {
  width: 100%; max-width: 340px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 13px; padding: 24px;
}
.reveal-title { font-weight: 620; font-size: 1rem; margin: 0 0 6px; }
.reveal-note { font-size: .8rem; color: var(--text-faint); margin: 0 0 16px; }
.reveal-dialog input {
  width: 100%; padding: 10px 12px; background: var(--bg); border: 1px solid var(--line);
  border-radius: 8px; color: var(--text); font-size: 1rem;
}
.reveal-dialog input:focus { outline: none; border-color: var(--gold-dim); }
.reveal-actions { display: flex; gap: 8px; margin-top: 14px; }
.reveal-actions button {
  flex: 1; padding: 10px; border: 0; border-radius: 8px; cursor: pointer;
  background: var(--gold); color: var(--on-gold); font: 620 .88rem var(--sans);
}
.reveal-actions button.ghost { background: transparent; color: var(--text-dim); border: 1px solid var(--line); }
.reveal-error { color: var(--down); font-size: .82rem; margin: 12px 0 0; }

/* The by-day index on the signal history. [M39] */
.archive-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 2px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.archive-list li { padding: 7px 10px; border-radius: 7px; display: flex; gap: 10px;
  align-items: baseline; justify-content: space-between; }
.archive-list li:hover { background: var(--surface-2); }
.archive-list a { font-weight: 550; }
.archive-list .dim { font-family: var(--mono); font-size: .74rem; white-space: nowrap; }

/* ===================================================== live floating P/L [M41] */

.floatcard {
  position: relative; margin: 18px 0 22px; padding: 20px 22px 18px;
  border: 2px solid var(--line-card); border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
/* A hairline of the P/L's own colour along the top edge - enough to read the sign from
   across the room without tinting the numbers themselves. */
.floatcard::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 3px;
  background: linear-gradient(90deg, transparent, currentColor, transparent); opacity: .8;
}
/* The sign is carried by the whole edge, not only the hairline. Taken to .55 because at .30 on
   a 2px border the tint was there in the stylesheet and not on the screen. */
.floatcard.up { color: var(--up); border-color: color-mix(in srgb, var(--up) 55%, transparent); }
.floatcard.down { color: var(--down); border-color: color-mix(in srgb, var(--down) 55%, transparent); }
.floatcard.flat { color: var(--text-faint); }

.floatcard-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.floatcard-head h2 {
  margin: 0; font: 600 11px/1.3 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-faint);
}
.floatcard-age { margin: 0; font: 500 11px/1.3 var(--mono); color: var(--text-faint); }

.floatcard-main { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin: 10px 0 4px; }
.floatcard-money {
  margin: 0; font: 650 clamp(2.1rem, 7vw, 3.1rem)/1 var(--mono); letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.floatcard-r {
  margin: 0; font: 600 clamp(1rem, 3.4vw, 1.35rem)/1 var(--mono); opacity: .82;
  font-variant-numeric: tabular-nums;
}
.floatcard-money.up, .floatcard-r.up { color: var(--up-text); }
.floatcard-money.down, .floatcard-r.down { color: var(--down-text); }
.floatcard-money.flat, .floatcard-r.flat { color: var(--text); }

.floatcard-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(136px, 1fr));
  gap: 0; margin: 16px 0 0; padding: 0;
  background: var(--surface); border: 1px solid var(--line-card); border-radius: 10px;
  overflow: hidden;
}
/* The separators are drawn by the tiles, not by a gap over a dark grid background. Seven tiles
   in a two-column layout leave an empty cell, and with the background carrying the lines that
   cell became a grey block on mobile - the grid's filler showing through where no tile was.
   An inset shadow on each tile puts the line inside the tile that owns it, so an absent tile
   draws nothing. The container's own border and overflow:hidden clip the outer edges. */
.fc-item {
  margin: 0; padding: 10px 12px; background: var(--surface);
  box-shadow: inset -1px -1px 0 var(--line-strong);
}
.fc-item dt {
  margin: 0 0 3px; font: 500 10px/1.3 var(--mono); letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-faint);
}
.fc-item dd {
  margin: 0; font: 600 1.02rem/1.2 var(--mono); color: var(--text);
  font-variant-numeric: tabular-nums;
}
.fc-item dd.up { color: var(--up-text); }
.fc-item dd.down { color: var(--down-text); }

.floatcard-split {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 12px 0 0; font-size: .86rem; color: var(--text-dim);
}
.floatcard-split strong { font-family: var(--mono); font-size: .98rem; }
.floatcard-split .sep { color: var(--text-faint); }
.floatcard-foot { margin: 10px 0 0; font-size: .76rem; color: var(--text-faint); }

.floattable td.num, .floattable th.num { font-variant-numeric: tabular-nums; }

/* Fourteen columns of numbers. The default table padding is comfortable for four and pushes
   this one off the side of the screen, so it is tightened here rather than everywhere: the
   figures are short and monospaced, and the row separators carry the structure that the extra
   whitespace was carrying before. [M52] */
.floattable { font-size: .78rem; }
.floattable th {
  padding: 7px 8px; font-size: 9.5px; letter-spacing: .05em;
}
.floattable td { padding: 7px 8px; }
.floattable .reason { max-width: 200px; }

/* The "of" in "4 of 6" is a qualifier on the label, not part of it. */
.fc-of { letter-spacing: 0; text-transform: none; color: var(--text-faint); font-weight: 400; }
.floattable .strategy-target { color: var(--text-dim); }

/* --------------------------------------------------------------- baskets */

.basket {
  margin: 14px 0; padding: 14px 16px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--surface-2);
}
.basket-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.basket-head h3 { margin: 0; font-size: .95rem; }
.basket-head p { margin: 0; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.basket-legs { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 2px; }
.basket-legs li {
  display: grid; grid-template-columns: 78px 84px 92px 1fr 1fr; gap: 10px;
  align-items: baseline; padding: 7px 9px; border-radius: 7px; background: var(--surface);
  font-family: var(--mono); font-size: .78rem; font-variant-numeric: tabular-nums;
}
.basket-legs .leg-label { color: var(--text-faint); }
.basket-legs .leg-peak, .basket-legs .leg-worst { color: var(--text-faint); }
.basket-foot { margin: 10px 0 0; font-size: .74rem; color: var(--text-faint); }

@media (max-width: 620px) {
  .floatcard { padding: 16px 15px 14px; border-radius: 14px; }
  .floatcard-grid { grid-template-columns: repeat(2, 1fr); }
  .fc-item dd { font-size: .96rem; }
  .basket-legs li { grid-template-columns: 1fr 1fr; gap: 4px 10px; }
}

@media (max-width: 780px) {
  /* Kept from the thumb-control block that was removed with the floating menu: a
     backdrop-filter makes an element a containing block for fixed descendants, which caused a
     positioning bug once, and the flat header reads better on a small screen regardless. */
  .site-head {
    -webkit-backdrop-filter: none; backdrop-filter: none;
    background: rgba(255, 255, 255, .97);
  }
}

/* ---------------------------------------------------------------- learn FAQ [M69] */

.faq { margin: 14px 0 0; }
.faq dt {
  margin: 18px 0 0; font-weight: 620; font-size: 1.02rem; color: var(--text);
}
.faq dt:first-child { margin-top: 0; }
.faq dd {
  margin: 6px 0 0; padding: 0 0 0 14px; color: var(--text-dim);
  border-left: 2px solid var(--line-card);
}

/* ---------------------------------------------------------------- investor portal [M78]
   Monochromatic. One hue — the brand blue — as tints (toward white), tones (toward a cool
   grey) and shades (toward the ink). It was the brand gold until M79 moved the whole site to the
   blue direction; the structure below did not change, only which hue fills it.

   The ramp is not decoration: depth encodes **how settled a figure is**, which is the thing this
   page most needs to communicate.

     Withdrawable   deepest   money you can actually take out
     Active capital deep      money that is yours and working
     Realised       mid       money that is final but still invested
     Floating       palest    not money yet, and a dashed edge to say so

   A first version put the ramp only on states that do not exist yet — the up/down shades, the
   ACTIVE chip, the copied button — so on a dashboard where every figure is zero none of it
   showed, and the cards were washed out because their border tint was lighter than the site's
   own. Depth now does the work whether or not there is any data.

   Direction, when there is any, is carried by depth and an arrow rather than a second hue. */
:root {
  /* tints - the brand blue toward white */
  --m-50:  #F4F7FE;
  --m-100: #EBF2FE;
  --m-200: #DAE6FD;
  --m-300: #BED4FC;
  --m-400: #9ABCFA;
  --m-500: #75A3F8;
  /* the hue itself */
  --m-600: #0B5AEA;
  /* tones - the blue toward a cool grey, for borders and quiet text. Darker than a direct
     conversion of the gold tones would give: at that lightness the label colour measured 4.42:1
     on --m-100, and these labels are 11px uppercase, which is small text and needs 4.5. */
  --m-tone-1: #4A6390;
  --m-tone-2: #4A6391;
  --m-tone-3: #4B6392;
  /* shades - the blue toward the ink, for emphasis and text */
  --m-700: #0A4FCF;
  --m-800: #0945B4;
  --m-900: #0F3D92;
  --m-950: #16346B;
  --m-990: #1E2A41;
}

.invhead { display: flex; align-items: flex-start; gap: 18px; margin: 0 0 18px; flex-wrap: wrap; }
.invhead h1 { margin: 2px 0 6px; font-size: 1.7rem; letter-spacing: -.02em; color: var(--m-990); }
.invhead .kicker { margin: 0; font-family: var(--mono); font-size: .68rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--m-tone-2); }
.invhead .lede { margin: 0; color: var(--text-dim); font-size: .95rem; }

.statuschip { margin-left: auto; display: inline-flex; align-items: center; gap: 7px;
  border-radius: 20px; padding: 7px 14px; font-family: var(--mono); font-size: .72rem;
  font-weight: 620; letter-spacing: .05em; white-space: nowrap;
  border: 1px solid var(--m-500); background: var(--m-200); color: var(--m-950); }
.statuschip .pip { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.statuschip.ok { background: var(--m-900); border-color: var(--m-950); color: var(--m-50); }
.statuschip.wait { background: var(--m-300); border-color: var(--m-500); color: var(--m-950); }
.statuschip.bad { background: var(--m-990); border-color: var(--m-990); color: var(--m-100); }

/* The five metrics, stepped by how settled each one is. */
.invcards { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; }
.invcards .card { border-radius: 13px; box-shadow: 0 1px 2px rgba(16, 50, 90, .06);
  background: var(--m-50); border: 1px solid var(--m-400); }
.invcards .card .label { color: var(--m-tone-2); }
.invcards .card .value { color: var(--m-990); }
.invcards .card .sub { color: var(--m-tone-3); }

/* 1 active capital — the anchor */
.invcards .card:nth-child(1) { background: linear-gradient(180deg, var(--m-300), var(--m-100));
  border-color: var(--m-500); }
/* 2 floating — provisional, so the palest fill and a dashed edge */
.invcards .card:nth-child(2) { background: var(--surface); border-style: dashed;
  border-color: var(--m-400); }
.invcards .card:nth-child(2) .value { color: var(--m-tone-1); }
/* 3 and 4 realised — final money, plain tint */
.invcards .card:nth-child(3),
.invcards .card:nth-child(4) { background: var(--m-100); border-color: var(--m-400); }
/* 5 withdrawable — the one that can actually leave, so the deepest */
.invcards .card:nth-child(5) { background: linear-gradient(180deg, var(--m-400), var(--m-200));
  border-color: var(--m-tone-3); }
.invcards .card:nth-child(5) .label { color: var(--m-950); }

.invcards .v.up { color: var(--m-990); font-weight: 660; }
.invcards .v.down { color: var(--m-tone-2); font-weight: 660; }
.invcards .v.up::before { content: "\25B2 "; font-size: .72em; }
.invcards .v.down::before { content: "\25BC "; font-size: .72em; }

.invactions { display: flex; gap: 12px; margin: 18px 0; }
/* Width and style here, colour left to the variant. The shorthand `border: 1px solid
   transparent` used to sit on this rule, and because `.invactions .btn` outranks `.btn-ghost`
   it overrode the variant's border-color - so the secondary button had an invisible edge and
   read as a link rather than a control. */
.invactions .btn { flex: 1; text-align: center; padding: 14px 20px; border-radius: 11px;
  font-weight: 640; font-size: .95rem; text-decoration: none;
  border-width: 1px; border-style: solid; }
.btn-gold { background: var(--m-600); color: #fff; border-color: var(--m-800);
  box-shadow: 0 1px 2px rgba(16, 50, 90, .28); }
.btn-gold:hover { background: var(--m-700); }
.btn-ghost { background: var(--surface); color: var(--m-800); border-color: var(--m-400); }
.btn-ghost:hover { background: var(--m-50); border-color: var(--m-600); color: var(--m-900); }

.invnav a { color: var(--m-tone-2); }
.invnav a[aria-current="page"] { color: var(--m-990); }

/* Panels and headings join the ramp, so the page reads as one hue even with no data. */
.invbody .panel { border-color: var(--m-400); }
.invbody .panel-head { background: var(--m-100); border-bottom-color: var(--m-400); }
.invbody .panel-head h2, .invbody .panel-head h3 { color: var(--m-950); }
.invbody .notice { background: var(--m-100); border: 1px solid var(--m-400);
  border-left: 3px solid var(--m-600); border-radius: 8px; padding: 11px 15px;
  color: var(--m-950); }
/* The one caution on this site that must not look like every other note. Inside the portal
   everything is a shade of the one blue, including `.notice.bad` - which is right for a
   monochromatic scheme and wrong for the sentence that says sending on the wrong network loses
   the money permanently. Amber is the exception, and it is the only one. */
.invbody .notice.warn {
  background: var(--amber-tint); border: 1px solid #F0DCB4;
  border-left: 3px solid var(--amber); color: var(--amber-text);
}
.invbody .notice.warn strong { color: var(--amber-text); }

/* The address, scannable. White plate so a wallet camera has a clean quiet zone whatever the
   panel behind it is doing. */
/* Centred in its card. It sat hard left in a full-width panel with a field of empty space
   beside it, which reads as something that failed to load rather than as a thing to scan. */
.qrbox {
  margin: 16px auto 4px; padding: 16px; background: #fff; border: 1px solid var(--m-300);
  border-radius: 14px; display: flex; flex-direction: column; align-items: center;
  gap: 9px; width: max-content;
}
.qrbox .qr { display: block; width: 100%; max-width: 168px; height: auto; }
.qrhint {
  margin: 0; font: 600 10.5px/1 var(--mono); letter-spacing: .09em; text-transform: uppercase;
  color: var(--m-tone-2);
}

.invbody .notice.bad { background: var(--m-200); border-left-color: var(--m-990);
  color: var(--m-990); }
.invbody thead th { background: var(--m-100); color: var(--m-tone-2);
  border-bottom-color: var(--m-400); }

.refrow { display: flex; align-items: center; gap: 14px; margin: 0 0 18px;
  background: var(--m-100); border: 1px solid var(--m-400); border-radius: 12px;
  padding: 13px 16px; }
.refrow .label { margin: 0 0 3px; font-family: var(--mono); font-size: .66rem;
  letter-spacing: .11em; text-transform: uppercase; color: var(--m-tone-2); }
.refurl { margin: 0; font-family: var(--mono); font-size: .84rem; word-break: break-all;
  color: var(--m-990); }

.copybtn { display: inline-flex; align-items: center; gap: 6px; margin-left: auto;
  flex-shrink: 0; border: 1px solid var(--m-tone-3); background: var(--m-200);
  border-radius: 8px; padding: 8px 12px; font-size: .78rem; font-weight: 600;
  color: var(--m-950); cursor: pointer; font-family: inherit;
  min-height: 40px; /* a real touch target on a phone */ }
.copybtn:hover { background: var(--m-300); border-color: var(--m-tone-1); }
.copybtn:focus-visible { outline: 2px solid var(--m-600); outline-offset: 2px; }
.copybtn .copyglyph { font-size: .95rem; line-height: 1; }
/* Confirmation is a depth change, not a colour change. */
.copybtn.copied { background: var(--m-900); border-color: var(--m-950); color: var(--m-50); }
.copybtn.copyfailed { background: var(--surface); border-color: var(--m-990); color: var(--m-990); }

.emptystate { margin: 0; padding: 22px 4px; color: var(--m-tone-2); text-align: center;
  font-size: .9rem; }
.emptystate p { margin: 0; max-width: 46ch; margin-inline: auto; }
/* The Guardian, only where a screen has one empty panel that matters more than the others.
   Fixed width and height attributes on the tag as well as here, so the panel does not jump when
   the image arrives - it is lazy-loaded, and an empty box that grows is worse than a wait. */
.emptystate .masc {
  width: 100%; max-width: 150px; height: auto; display: block; margin: 2px auto 12px;
}
@media (prefers-reduced-motion: no-preference) {
  .emptystate .emptyart { animation: emptyart-in .45s ease both; }
}
@keyframes emptyart-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; } }

.perfwrap { padding: 4px 0 0; }
.perfvalue { margin: 0 0 8px; font-size: 1.5rem; font-weight: 650; letter-spacing: -.02em;
  font-family: var(--mono); color: var(--m-990); }

.infoblock { background: var(--m-100); border: 1px solid var(--m-400); border-radius: 12px;
  padding: 14px 18px; margin: 18px 0 0; }
.infoblock summary { cursor: pointer; font-weight: 620; font-size: .92rem; color: var(--m-950); }
.infoblock ul { margin: 12px 0 0; padding-left: 20px; color: var(--text-dim); font-size: .9rem; }
.infoblock li { margin-bottom: 6px; }

/* deposit */
.depgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 0 0 16px; }
.depfield { background: var(--m-50); border: 1px solid var(--m-400); border-radius: 11px;
  padding: 13px 15px; }
.depfield.wide { grid-column: 1 / -1; }
.depfield .label { margin: 0 0 5px; font-family: var(--mono); font-size: .66rem;
  letter-spacing: .11em; text-transform: uppercase; color: var(--m-tone-2); }
.depvalue {
  margin: 0; font-size: 1.12rem; font-weight: 750; color: var(--m-990);
  /* Every field on this row is one short value, so they should sit on the same line whether the
     value is a word, a badge or a figure. */
  min-height: 28px; display: flex; align-items: center;
}
/* The network is the field that loses money when it is misread, so it is the loudest thing here.
   Centred on both axes rather than sitting on the text baseline: it is a chip, and a chip with
   its label pushed to one side reads as an accident. */
.netbadge {
  display: inline-flex; align-items: center; justify-content: center; text-align: center;
  min-height: 28px; padding: 4px 14px;
  background: var(--m-900); border: 1px solid var(--m-950); color: var(--m-50);
  border-radius: 7px; font-family: var(--mono); font-size: .84rem; font-weight: 700;
  letter-spacing: .08em; line-height: 1;
}
.addrrow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* break-all, never truncate: an address with an ellipsis in it is an address that loses money */
.addr { font-family: var(--mono); font-size: .84rem; word-break: break-all; flex: 1 1 260px;
  background: var(--m-200); border: 1px solid var(--m-500); border-radius: 7px;
  padding: 9px 11px; color: var(--m-990); }
.addrcell { max-width: 260px; word-break: break-all; font-size: .76rem; }
.depsteps { color: var(--text-dim); font-size: .92rem; padding-left: 20px; }
.depsteps li { margin-bottom: 6px; }
.backlink { margin-top: 26px; }

.cfgform { display: grid; gap: 13px; max-width: 520px; }
.cfgform label { display: grid; gap: 5px; font-size: .85rem; font-weight: 600;
  color: var(--m-950); }
.cfgform input { padding: 9px 11px; border: 1px solid var(--m-500); border-radius: 8px;
  font-family: var(--mono); font-size: .88rem; background: var(--surface); color: var(--text); }
.cfgform input:focus-visible { outline: 2px solid var(--m-600); outline-offset: 1px; }
.cfgform .checkline { display: flex; align-items: center; gap: 9px; font-weight: 500; }
.cfgform .btn { justify-self: start; padding: 11px 20px; border-radius: 9px; cursor: pointer;
  font-weight: 640; }

@media (max-width: 900px) {
  .invcards { grid-template-columns: 1fr 1fr; }
  /* Active capital leads on a phone; the other four pair up beneath it. */
  .invcards .card:nth-child(1) { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .invhead { gap: 10px; }
  .statuschip { margin-left: 0; }
  .invactions { flex-direction: column; }
  .depgrid { grid-template-columns: 1fr; }
  /* Centred, like the deposit card. `stretch` pushed the label and the link to the left wall and
     spread the button across the full width, so one card on the page was aligned differently
     from every other. */
  .refrow { flex-direction: column; align-items: center; text-align: center; gap: 10px; }
  .refrow .label, .refrow .refurl { text-align: center; }
  .refrow .refurl { word-break: break-all; }
  .copybtn { margin-left: 0; justify-content: center; min-height: 44px; padding: 10px 22px; }
}

/* Bottom tab bar — phones only. [M78]
   Hidden above 900px, where the top navigation is already reachable without a thumb.
   It was 700px, which left a phone in landscape and every small tablet without it. */
.tabbar { display: none; }

@media (max-width: 900px) {
  .tabbar {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 40;
    /* White, as drawn. The filled tint the live version used made the whole bar read as a panel
       sitting on the page rather than as the edge of the app. */
    background: var(--surface);
    border-top: 1px solid var(--line);
    /* Clears the home indicator on a notched phone; 0 elsewhere. */
    padding-bottom: env(safe-area-inset-bottom, 0);
    box-shadow: 0 -1px 3px rgba(16, 50, 90, .06);
  }
  .tabbar a {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 4px;
    /* 56px is a thumb, not a cursor. */
    min-height: 56px;
    padding: 8px 2px 7px;
    text-decoration: none;
    color: var(--text-faint);
    /* Sentence case in the body face. Mono uppercase read as a system readout, and this is
       navigation - the one part of the interface that should not look technical. */
    font-family: var(--sans);
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
  }
  /* The current tab is marked by colour alone: icon and label together, no fill and no rule.
     A filled tab plus a coloured label plus a top border is three markers for one state. */
  .tabbar a[aria-current="page"] { color: var(--gold); }
  .tabbar .tabglyph { display: flex; align-items: center; justify-content: center;
    height: 22px; line-height: 1; }
  .tabbar .tabglyph svg { display: block; }
  .tabbar a:active { background: var(--m-100); }

  /* The bar is fixed, so the page has to end above it or the last row hides behind it. */
  .invbody { padding-bottom: 78px; }
  /* The top nav duplicates the bar on a phone; one of them is enough. */
  .invnav { display: none; }
}

/* Account actions in the header. [M78]
   Two distinct choices when signed out, never one button that guesses. */
.head-account { display: flex; align-items: center; gap: 8px; margin-left: 12px; }

/* The header's sign-in control wears the same sweep as the wordmark, so the two ends of the
   header belong to each other. It is a filled pill rather than a text link because it is the
   only thing a returning reader comes to the header to do. */
.head-account .ha-link {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 40px;
  padding: 8px 20px;
  border-radius: 999px;
  font-family: var(--sans);
  font-size: .88rem;
  font-weight: 800;
  letter-spacing: .01em;
  color: #fff;
  background-color: var(--brand-dark);
  background-image: var(--brand-sweep);
  border: 0;
  box-shadow: 0 4px 12px -5px rgba(11, 87, 227, .65);
  transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
  text-decoration: none;
  white-space: nowrap;
}
.head-account .ha-link:hover {
  color: #fff; text-decoration: none;
  transform: translateY(-1px); filter: saturate(1.1);
  box-shadow: 0 8px 18px -6px rgba(11, 87, 227, .7);
}
.head-account .ha-link:active { transform: translateY(0); }

.head-account .ha-cta {
  padding: 7px 14px;
  border-radius: 8px;
  font-size: .82rem;
  font-weight: 640;
  text-decoration: none;
  white-space: nowrap;
  background: var(--gold);
  color: #fff;
  border: 1px solid var(--gold-hover);
}
.head-account .ha-cta:hover { background: var(--gold-hover); }

.head-account .ha-who {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 11px 5px 5px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--surface-2);
  text-decoration: none;
  color: var(--text);
  white-space: nowrap;
}
.head-account .ha-who:hover { border-color: var(--line-strong); }
.head-account .ha-avatar {
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--text); color: var(--bg);
  font: 640 11px/1 var(--mono);
}
.head-account .ha-name { font-size: .82rem; font-weight: 570; }

@media (max-width: 760px) {
  /* The header is tight on a phone. The name goes; the avatar still identifies the account,
     and the two signed-out choices stay because they are the whole point of the header there. */
  .head-account { margin-left: auto; gap: 6px; }
  .head-account .ha-name { display: none; }
  .head-account .ha-who { padding: 4px; border-radius: 50%; }
  .head-account .ha-link, .head-account .ha-cta { padding: 6px 10px; font-size: .78rem; }
}

/* Header layout, corrected. [M78]

   The header carried a brand, ten navigation items, a mode badge, an account block and a live
   indicator, on one row with `flex-wrap: wrap` on the list — so it folded onto a second line and
   the freshness text broke mid-phrase. The badge is gone, "Account" left the nav because the
   account block does that job, and the row no longer wraps: the nav scrolls sideways inside
   itself if it must, which keeps everything else on one line and at the right height. */

.head-inner { flex-wrap: nowrap; gap: 12px; }

.site-nav {
  margin-left: auto;
  min-width: 0;              /* lets the nav shrink instead of pushing the account block out */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;     /* a scrollbar in a 60px header is worse than the overflow */
  -webkit-overflow-scrolling: touch;
}
.site-nav::-webkit-scrollbar { display: none; }
.site-nav ul { flex-wrap: nowrap; }
.site-nav a { white-space: nowrap; }

/* The live indicator is appended by live.js and was wrapping to two lines. */
.freshness { white-space: nowrap; flex: none; }

.head-account { flex: none; }

@media (max-width: 1100px) {
  /* Tighter links so nine items and the account block still share one row. Nothing here may
     touch `position`: below 780px the nav becomes a fixed popover anchored to the menu button,
     and forcing it back to `static` put an invisible 324px panel into the header's flow and
     made the bar 346px tall on every phone. It was invisible, so it looked like a layout bug
     rather than a rule fighting another rule. */
  .site-nav a { font-size: .84rem; padding: 7px 9px; }
}

@media (max-width: 860px) {
  .freshness { display: none; }   /* the same figure is on the page itself */
}

@media (max-width: 760px) {
  .head-inner { gap: 8px; }
  /* The wordmark stays. It used to be hidden here to save room when it was small, quiet text
     beside the bars - now it *is* the brand, and hiding it left a gap where the logo should be.
     The room comes from the header dropping its Create account button instead, which was a
     second copy of the one in the hero. */
  /* The mark shrinks with the word so the lockup keeps its proportions rather than becoming
     a large icon beside small type. [M80] */
  /* The candles are sized in em, so they follow this on their own. [M84] */
  .brand-text { font-size: 2.1rem; }
  .head-account { margin-left: auto; }
}

/* Minimal chrome, on the investor's own pages. [M78]

   The public header exists to sell and to be crawled: nine marketing links, a live freshness
   readout, a menu button. On an investor's dashboard none of that is theirs — they signed in to
   see their own money, and the account nav directly beneath already offers everywhere they can
   go. Leaving both meant two navigations stacked on top of each other, the top one advertising
   pages they did not come for.

   The marketing nav is not removed from the site, only from these five pages. It stays exactly
   as it is for visitors, which is who it is for. */

[data-chrome="minimal"] .site-nav,
[data-chrome="minimal"] .freshness {
  display: none !important;
}

/* With the nav gone the account block would be pinned to the logo; this pushes it right. */
[data-chrome="minimal"] .head-account { margin-left: auto; }

/* ---------------------------------------------------------------- FAQ accordion [M79 §24]
   Built on <details>, so it opens with no JavaScript, is keyboard-operable for free, and
   find-in-page can reach a closed answer in Chrome and Edge. */
.faq-acc { padding: 2px 0; }
.faq-item { border-bottom: 1px solid var(--m-300); }
.faq-item:last-child { border-bottom: 0; }
.faq-item summary {
  cursor: pointer; list-style: none; padding: 14px 40px 14px 2px; font-weight: 640;
  color: var(--m-990); position: relative; font-size: .94rem;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:focus-visible { outline: 2px solid var(--m-600); outline-offset: 2px; }
/* A chevron drawn from a rotated corner: two borders instead of an icon file. */
.faq-item summary::after {
  content: ""; position: absolute; right: 10px; top: 19px; width: 8px; height: 8px;
  border-right: 2px solid var(--m-600); border-bottom: 2px solid var(--m-600);
  transform: rotate(45deg); transition: transform .2s ease;
}
.faq-item[open] summary::after { transform: rotate(-135deg); }
@media (prefers-reduced-motion: reduce) { .faq-item summary::after { transition: none; } }
.faq-item p { margin: 0 0 16px; padding-right: 36px; color: var(--m-tone-2); font-size: .9rem; }

/* The one figure that decides whether a profit is charged. Set apart from the bullets so it
   reads as the account's own number rather than another line of policy. */
.hwm {
  background: var(--m-100); border: 1px solid var(--m-300); border-radius: 10px;
  padding: 12px 14px; margin: 0 0 14px;
}
.hwmvalue {
  margin: 4px 0 6px; font: 640 1.3rem/1.1 var(--mono); letter-spacing: -.02em;
  color: var(--m-990); font-variant-numeric: tabular-nums;
}
.hwmhint { margin: 0; font-size: .82rem; color: var(--m-tone-2); }

/* ---------------------------------------------------------------- tables become cards [M79]
   Below 560px a six-column trade table is six columns squeezed into a thumb's width, and its
   header - the only thing that says what each number means - is off the top of the screen. Each
   row becomes its own card instead, with every cell carrying the label the header used to give
   it. The markup stays a real <table>: the same DOM serves both, so nothing about the document
   outline or the reading order changes with the viewport. */
@media (max-width: 560px) {
  .invbody .tablewrap { overflow: visible; }
  .invbody table, .invbody tbody, .invbody tr, .invbody td { display: block; width: 100%; }
  .invbody thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .invbody tr {
    border: 1px solid var(--m-300); border-radius: 11px; padding: 10px 13px; margin: 0 0 9px;
    background: var(--surface);
  }
  .invbody td {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
    padding: 5px 0; border: 0; text-align: right;
  }
  .invbody td::before {
    content: attr(data-label); text-align: left; flex: none;
    font: 600 10.5px/1.5 var(--mono); letter-spacing: .08em; text-transform: uppercase;
    color: var(--m-tone-2);
  }
  /* The figure the reader came for. One per row, and it is not the one the header put first. */
  .invbody td.lead { font-size: 1.12rem; font-weight: 640; padding-top: 2px; }
  .invbody td.lead::before { align-self: center; }
}

/* ---------------------------------------------------------------- touch targets [M79]
   Measured on an iPhone profile: the auth inputs were 42px tall against a 44px minimum, which
   is the size of the smallest thing a thumb reliably hits. The submit button was already 44. */
.auth-card input, .auth-card button, .auth-card select {
  min-height: 44px;
}
/* A form that has been submitted says so. Without this the reader taps, nothing changes for
   three seconds, and they tap again. */
button.is-busy {
  opacity: .72; cursor: progress;
}
button.is-busy::after {
  content: ""; width: 13px; height: 13px; margin-left: 9px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent; display: inline-block;
  vertical-align: -2px; animation: busy-spin .7s linear infinite;
}
@keyframes busy-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { button.is-busy::after { animation: none; } }

/* ================================================================ homepage [M79]
   The approved direction: white then soft blue then white, one idea per band, generous vertical
   space. Scoped with `hp-` so none of it can reach the data pages, which are dense on purpose
   and would be ruined by this much air. */

/* ---- the market strip.
   Light, not navy. The approved reference is a pale band of pairs with the move in green or red
   beside each one, and it reads better here for a plain reason: the announcement bar above it is
   already a solid blue, and two saturated bands stacked make a header that shouts before the
   page has said anything.

   One instrument, because one instrument is what the feed carries. The reference shows eight
   currency pairs; this system is single-symbol end to end, so a row of borrowed tickers would be
   decoration with invented numbers behind it. There is no daily percentage either - the feed
   publishes a day *range*, not an open - so the coloured, arrowed figure is the floating P/L,
   which is genuinely signed and genuinely moves. */
/* A light that travels round the edge.
   The frame is a rounded box filled with a conic gradient; the band sits inside it, inset by the
   border's own thickness, so what shows through the 2px gap *is* the border. Rotating the
   gradient's start angle walks a bright arc round the whole perimeter, corners included, which a
   border-image or a moving pseudo-element cannot do without seams.
   `@property` is what makes an angle animatable at all - a plain custom property would jump from
   0 to 360 rather than sweep - and everything is guarded so a browser without it gets a plain
   rule instead of a still gradient pretending to be one. */
@property --ticker-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
.ticker-frame {
  /* Flush against the header and full width, as it was. The inset pill read as a separate
     component floating below the chrome; this is one band of the header. */
  margin: 0; padding: 2px 0; border-radius: 0; background: var(--ticker-line);
}
@supports (background: conic-gradient(from 0deg, red, blue)) {
  .ticker-frame {
    /* Two lights, opposite each other, so one is always in view whichever edge you are
       watching. Each is a tight bright core with a short falloff either side - a wide soft arc
       reads as a glow on the whole border rather than as something travelling along it.

       Red, as asked. Worth knowing: red means loss everywhere else on this site, and this sits
       on the frame of the market strip. It is on the frame and never on a number, which is what
       keeps the two from being confused. */
    background:
      conic-gradient(from var(--ticker-angle),
        var(--ticker-line) 0deg,
        var(--ticker-line) 72deg,
        var(--ticker-light-soft) 82deg,
        var(--ticker-light) 90deg,
        var(--ticker-light-soft) 98deg,
        var(--ticker-line) 108deg,
        var(--ticker-line) 252deg,
        var(--ticker-light-soft) 262deg,
        var(--ticker-light) 270deg,
        var(--ticker-light-soft) 278deg,
        var(--ticker-line) 288deg,
        var(--ticker-line) 360deg);
    animation: ticker-sweep 5s linear infinite;
  }
}
@keyframes ticker-sweep { to { --ticker-angle: 360deg; } }
/* A light that circles forever is a light somebody has to look away from. */
@media (prefers-reduced-motion: reduce) {
  .ticker-frame { animation: none; background: var(--ticker-line); }
}

.ticker {
  background: var(--ticker-bg); color: var(--text); overflow: hidden; height: 42px;
  display: flex; align-items: center; position: relative;
  border: 0; border-radius: 0;
}
.ticker-run { display: flex; white-space: nowrap; animation: ticker-roll 26s linear infinite; }
@keyframes ticker-roll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* Pausing on hover is the difference between a strip you can read and one you chase. */
.ticker:hover .ticker-run, .ticker:focus-within .ticker-run { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  /* Still readable, just not moving: the strip scrolls by hand instead. */
  .ticker { overflow-x: auto; }
  .ticker-run { animation: none; }
}
.ti {
  display: inline-flex; align-items: center; gap: 7px; padding: 0 20px; font-size: .8rem;
  border-right: 1px solid var(--ticker-line); color: var(--text-dim);
}
.ti b { font-weight: 700; color: var(--navy); letter-spacing: .01em; }
.ti .v { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--text); }
.ti .k { color: var(--text-faint); }
.ti .up { color: var(--up-text); font-weight: 700; font-variant-numeric: tabular-nums; }
.ti .dn { color: var(--down-text); font-weight: 700; font-variant-numeric: tabular-nums; }
.ti .flat { color: var(--text-faint); font-weight: 600; font-variant-numeric: tabular-nums; }
/* The instrument's own mark, where the reference puts a flag. Gold is not a currency pair, so
   it gets a bullion disc rather than a country. */
.ti-mark { display: inline-flex; flex: none; }
.ti-mark svg { width: 17px; height: 17px; display: block; }

/* ---- bands */
.hp { --band: 104px; }
.hp section { padding: var(--band) 0; }
.hp .soft { background: var(--bg); }
.hp .in { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }
.hp h2 {
  font-size: 2.4rem; font-weight: 800; line-height: 1.15; letter-spacing: -.025em;
  color: var(--navy); margin: 0 0 14px; text-wrap: balance;
}
.hp h3 { font-size: 1.16rem; font-weight: 700; color: var(--navy); margin: 0 0 8px; }
.hp .eye {
  font-size: .74rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 8px;
}
.hp .lede { color: var(--text-dim); font-size: 1.08rem; max-width: 60ch; margin: 0; }
.hp .center { text-align: center; }
.hp .center .lede { margin-left: auto; margin-right: auto; }
.hp .head { margin-bottom: 52px; }

/* ---- hero */
.hp-hero { padding: 76px 0 80px; position: relative; overflow: hidden; }
.hp-hero::before {
  content: ""; position: absolute; right: -180px; top: -150px; width: 740px; height: 740px;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 40% 40%, var(--gold-tint) 0%, var(--bg) 52%,
    rgba(245, 249, 255, 0) 72%);
}
.hp-hero .in {
  display: grid; grid-template-columns: 1.05fr .95fr; gap: 52px; align-items: center;
  position: relative;
}
.hp-hero h1 {
  font-size: 3.4rem; font-weight: 800; line-height: 1.06; letter-spacing: -.035em;
  color: var(--navy); margin: 14px 0 20px; text-wrap: balance;
}
.hp-hero h1 em { font-style: normal; color: var(--gold); }
.hp-cta { display: flex; gap: 12px; margin: 26px 0 14px; flex-wrap: wrap; }
.hp-risk { font-size: .84rem; color: var(--text-faint); margin: 0; }
.hp-trust {
  display: flex; gap: 20px; margin-top: 24px; padding-top: 20px;
  border-top: 1px solid var(--line); flex-wrap: wrap;
}
.hp-trust span {
  display: inline-flex; align-items: center; gap: 7px; font-size: .84rem;
  color: var(--text-dim); font-weight: 600;
}
.hp-art {
  position: relative; display: flex; justify-content: center; align-items: flex-end;
  min-height: 340px;
}
.hp-art .masc { width: 78%; max-width: 300px; height: auto; position: relative; z-index: 2; }
.hp-plate {
  position: absolute; inset: auto 0 0 0; height: 72%; border-radius: 24px;
  background: linear-gradient(160deg, var(--gold-tint), var(--bg));
  border: 1px solid var(--line);
}
.hp-float {
  position: absolute; z-index: 3; background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; padding: 10px 13px; box-shadow: var(--shadow-card);
}
.hp-float .k {
  font-size: .64rem; color: var(--text-faint); font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase;
}
.hp-float .n {
  font-family: var(--mono); font-size: 1rem; font-weight: 600; color: var(--navy);
  font-variant-numeric: tabular-nums;
}
.hp-float.one { top: 8%; left: 0; }
.hp-float.two { bottom: 16%; right: 0; }

/* ---- trust band */
.hp-stats {
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.hp-stats .in {
  display: grid; grid-template-columns: repeat(4, 1fr); padding-top: 34px; padding-bottom: 34px;
}
.hp-stat { padding: 0 28px; border-right: 1px solid var(--line); }
.hp-stat:first-child { padding-left: 0; }
.hp-stat:last-child { border-right: 0; padding-right: 0; }
.hp-stat b {
  display: block; font-size: 1.5rem; font-weight: 800; color: var(--navy); letter-spacing: -.02em;
}
.hp-stat i {
  display: block; font-style: normal; font-size: .88rem; font-weight: 700; color: var(--text);
  margin: 3px 0 4px;
}
.hp-stat span { font-size: .82rem; color: var(--text-dim); }

/* ---- grids and cards */
.hp-grid { display: grid; gap: 20px; }
.hp-g4 { grid-template-columns: repeat(4, 1fr); }
.hp-g3 { grid-template-columns: repeat(3, 1fr); }
.hp-g2 { grid-template-columns: repeat(2, 1fr); }
.hp-card {
  background: var(--surface); border: 1px solid var(--line-card); border-radius: var(--radius-card);
  padding: 26px; box-shadow: var(--shadow-card);
}
.hp-card p { color: var(--text-dim); font-size: .94rem; margin: 0; }
.hp-ico {
  width: 40px; height: 40px; border-radius: 11px; background: var(--gold-tint); color: var(--gold);
  display: flex; align-items: center; justify-content: center; margin-bottom: 15px;
}
.hp-ico svg {
  width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ---- steps */
.hp-step .num {
  width: 44px; height: 44px; border-radius: 12px; background: var(--navy); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 1.05rem;
  font-weight: 800; margin-bottom: 16px;
}
.hp-step p { color: var(--text-dim); font-size: .94rem; margin: 0; }

/* ---- split */
.hp-split { display: grid; grid-template-columns: 1fr 1fr; gap: 54px; align-items: center; }
.hp-split .masc { width: 100%; max-width: 260px; height: auto; display: block; margin: 0 auto; }

/* ---- profit share */
.hp-share { display: flex; gap: 12px; margin-top: 22px; }
.hp-share .bar { background: var(--gold); color: #fff; border-radius: 11px; padding: 18px 20px; }
.hp-share .bar.you { flex: 7; }
.hp-share .bar.fee { flex: 3; background: var(--navy); }
.hp-share .bar b { display: block; font-size: 1.7rem; font-weight: 800; letter-spacing: -.02em; }
.hp-share .bar span { font-size: .8rem; opacity: .88; }

/* ---- comparison */
.hp-cmp { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.hp-cmp .col {
  border-radius: var(--radius-card); padding: 26px; border: 1px solid var(--line-card);
  background: var(--surface);
}
.hp-cmp .col.good { border-color: var(--gold-dim); box-shadow: var(--shadow-pop); }
.hp-cmp h4 { font-size: .95rem; margin: 0 0 14px; color: var(--navy); }
.hp-cmp ul { list-style: none; padding: 0; margin: 0; }
.hp-cmp li {
  padding: 8px 0 8px 26px; position: relative; font-size: .92rem; color: var(--text-dim);
  border-bottom: 1px solid var(--line-soft);
}
.hp-cmp li:last-child { border-bottom: 0; }
.hp-cmp li::before {
  position: absolute; left: 0; top: 8px; width: 17px; height: 17px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: .62rem; font-weight: 800;
}
/* Grey, not red: red on this site means a negative number, and a caution that looks like a loss
   teaches the reader to ignore both. */
.hp-cmp .bad li::before {
  content: "\2013"; background: var(--surface-3); color: var(--text-faint);
  border: 1px solid var(--line);
}
.hp-cmp .good li::before { content: "\2713"; background: var(--gold-tint); color: var(--gold); }

/* ---- CTA band */
.hp-band { background: var(--gold-tint); border-top: 1px solid var(--line); }
.hp-band .in {
  display: grid; grid-template-columns: 1fr auto; gap: 36px; align-items: center;
  padding-top: 52px; padding-bottom: 52px;
}
.hp-band .masc { width: 160px; height: auto; display: block; }

@media (max-width: 900px) {
  .hp { --band: 60px; }
  .hp-hero { padding: 30px 0 42px; }
  .hp-hero .in, .hp-split, .hp-cmp, .hp-g4, .hp-g3, .hp-g2 { grid-template-columns: 1fr; }
  .hp-hero .in { gap: 26px; }
  .hp-hero h1 { font-size: 2.1rem; margin: 10px 0 14px; }
  .hp h2 { font-size: 1.65rem; }
  .hp .head { margin-bottom: 30px; }
  .hp-split { gap: 26px; }
  .hp-art { min-height: 0; }
  .hp-float { display: none; }
  .hp-stats .in { grid-template-columns: 1fr 1fr; gap: 20px 0; }
  .hp-stat { padding: 0 14px 0 0; border-right: 0; }
  .hp-stat:nth-child(odd) { border-right: 1px solid var(--line); }
  .hp-stat:nth-child(even) { padding-left: 14px; }
  .hp-band .in { grid-template-columns: 1fr; text-align: center; }
  .hp-band .masc { margin: 0 auto; }
  .hp-cta .btn { flex: 1; text-align: center; }
}

/* The Guardian on the auth pages. Small and above the heading, so the form starts where the eye
   already is rather than being pushed below a picture. */
.auth-art { margin: 0 0 6px; text-align: center; }
.auth-art .masc { width: 108px; height: auto; display: inline-block; }
.invhead .masc { width: 96px; height: auto; flex: none; }

/* ---------------------------------------------------------------- deposit form [M79]
   The form shipped with no styles at all - raw browser inputs on a page where everything else
   had been designed - so it read as a different site. These are the same surfaces, radii and
   type the rest of the portal uses. */

.depform { display: grid; gap: 0; margin: 0 0 6px; max-width: 520px; }
.depform label {
  display: block; margin: 0 0 7px;
  font-family: var(--mono); font-size: .66rem; letter-spacing: .11em; text-transform: uppercase;
  color: var(--m-tone-2);
}
.depform input[type="text"] {
  width: 100%; box-sizing: border-box;
  /* 48px, comfortably over the 44px a thumb needs, and 16px type because anything smaller makes
     iOS zoom the page the moment the field is focused. */
  min-height: 48px; padding: 12px 14px; font-size: 16px;
  font-family: var(--mono);
  color: var(--m-990); background: var(--surface);
  border: 1px solid var(--m-400); border-radius: 10px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.depform input[type="text"]::placeholder { color: var(--m-400); }
.depform input[type="text"]:focus {
  outline: none; border-color: var(--m-600);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 18%, transparent);
}
.depform .field-help {
  margin: 7px 0 18px; font-size: .8rem; color: var(--m-tone-2); line-height: 1.5;
}
.depform button[type="submit"] {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 12px 26px; margin-top: 4px;
  font-family: var(--sans); font-size: .95rem; font-weight: 800; letter-spacing: .01em;
  color: #fff; background-color: var(--brand-dark); background-image: var(--brand-sweep);
  border: 0; border-radius: 999px; cursor: pointer;
  box-shadow: 0 5px 14px -6px rgba(11, 87, 227, .7);
  transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
}
.depform button[type="submit"]:hover {
  transform: translateY(-1px); filter: saturate(1.08);
  box-shadow: 0 9px 20px -7px rgba(11, 87, 227, .75);
}
.depform button[type="submit"]:active { transform: translateY(0); }

/* The two summary cards at the top. Label above, value centred under it, so ASSET/USDT and
   NETWORK/TRC20 read as one object each rather than as a caption with something loose beside it. */
.depfield { text-align: center; }
.depfield.wide { text-align: left; }
.depfield .label { text-align: center; }
.depfield.wide .label { text-align: left; }
.depvalue {
  justify-content: center;
  font-family: var(--sans); font-weight: 800; letter-spacing: .01em;
  font-size: 1.2rem;
}
.depfield.wide .depvalue { justify-content: flex-start; }

/* The network chip, in the brand's own face and sweep. It is the field that loses money when it
   is misread, so it is the loudest thing on the page - and now it looks deliberate rather than
   like a leftover tag. */
.netbadge {
  font-family: var(--sans);
  font-size: .92rem; font-weight: 800; letter-spacing: .06em;
  min-height: 34px; padding: 6px 18px; border-radius: 999px;
  color: #fff; border: 0;
  background-color: var(--brand-dark); background-image: var(--brand-sweep);
  box-shadow: 0 4px 12px -6px rgba(11, 87, 227, .6);
}

/* The submitted-deposits table and the steps, given the same air as everything else. */
.depsteps { margin: 0 0 4px; padding-left: 20px; color: var(--m-tone-2); font-size: .92rem; }
.depsteps li { margin-bottom: 7px; }

@media (max-width: 560px) {
  .depform { max-width: none; }
  .depform button[type="submit"] { width: 100%; }
}

/* ---------------------------------------------------------------- deposit summary rows [M79]
   Label and value on one line - ASSET : USDT - rather than a caption stacked above a figure.
   Two words that belong together read faster side by side, and the card stops being mostly air. */
.depfield.row {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  text-align: left; padding: 15px 18px;
}
.depfield.row .label {
  margin: 0; flex: none;
  font-family: var(--mono); font-size: .68rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--m-tone-2);
}
/* The colon is drawn rather than typed, so it never ends up in a copied value or read aloud by
   a screen reader as part of the label. */
.depfield.row .label::after {
  content: ":"; margin-left: 7px; opacity: .5;
}
.depfield.row .depvalue {
  margin: 0; min-height: 0; display: inline-flex; align-items: center;
  font-family: var(--sans); font-weight: 800; font-size: 1.18rem;
  letter-spacing: .01em; color: var(--m-990);
}
@media (max-width: 560px) {
  /* Centred here too. `space-between` pushed the label to one wall and the value to the other,
     which turns two words that belong together into two separate things on a narrow card. */
  .depfield.row { justify-content: center; gap: 10px; }
}

/* ---------------------------------------------------------------- the address card [M79]
   Address and code side by side. The QR sat alone under a full-width address row with a field
   of empty card either side of it, which reads as a layout that gave up rather than as a thing
   to point a phone at. */
.depfield.wide {
  display: grid; grid-template-columns: 1fr auto; grid-template-areas: "label qr" "addr qr";
  gap: 6px 24px; align-items: start; padding: 18px 20px;
}
.depfield.wide > .label { grid-area: label; }
.depfield.wide > .addrrow { grid-area: addr; align-self: center; }
.depfield.wide > .qrbox { grid-area: qr; margin: 0; align-self: center; }
@media (max-width: 700px) {
  /* One column on a phone, code first: on a small screen the camera is the quicker route and
     the address is the fallback, which is the opposite of the order on a desktop. */
  .depfield.wide {
    grid-template-columns: 1fr; grid-template-areas: "label" "qr" "addr"; gap: 10px;
    justify-items: center;
  }
  .depfield.wide > .label { justify-self: start; }
  .depfield.wide > .addrrow { width: 100%; }
}

/* The copy button, centred on a phone. The address takes the full width there so the button
   wraps onto its own line, and a lone control hard against the left wall of a centred card
   reads as something that fell out of the layout. */
@media (max-width: 700px) {
  .depfield.wide > .addrrow { justify-content: center; }
  .depfield.wide > .addrrow .copybtn { min-height: 44px; padding: 10px 22px; }
}

/* ------------------------------------------------------------ profile and reset [M79]
   The identity pages reuse .depform, so only what they add is here. */

/* The counterpart to .auth-error. It existed for failure and not for success, so "your password
   has been changed" arrived as unstyled body text under the heading. */
.auth-ok {
  background: var(--up-tint); border: 1px solid color-mix(in srgb, var(--up) 34%, transparent);
  color: var(--up); border-radius: 8px; padding: 10px 13px; font-size: .85rem; margin-bottom: 16px;
}

/* File inputs. A browser's default is a grey button and a filename, at whatever size the OS
   likes, next to fields that have been given a shape - so the one control asking for a
   photograph of somebody's ID looked the least trustworthy thing on the page. */
.depform input[type="file"] {
  width: 100%; box-sizing: border-box;
  min-height: 48px; padding: 10px 12px; margin: 0 0 14px;
  font-family: var(--sans); font-size: .9rem; color: var(--m-tone-2);
  background: var(--surface); border: 1px dashed var(--m-400); border-radius: 10px;
  cursor: pointer;
}
.depform input[type="file"]:focus-visible {
  outline: none; border-color: var(--m-600); border-style: solid;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 18%, transparent);
}
.depform input[type="file"]::file-selector-button {
  margin-right: 12px; padding: 8px 16px;
  font-family: var(--sans); font-size: .8rem; font-weight: 700;
  color: #fff; background-color: var(--brand-dark); background-image: var(--brand-sweep);
  border: 0; border-radius: 999px; cursor: pointer;
}
.depform input[type="email"] { /* same shape as the text fields beside it */ }
.depform input[type="email"], .depform input[type="password"] {
  width: 100%; box-sizing: border-box;
  min-height: 48px; padding: 12px 14px; font-size: 16px; font-family: var(--mono);
  color: var(--m-990); background: var(--surface);
  border: 1px solid var(--m-400); border-radius: 10px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.depform input[type="email"]:focus, .depform input[type="password"]:focus {
  outline: none; border-color: var(--m-600);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 18%, transparent);
}

/* The verification state, given its own line above the explanation rather than buried in it. */
.kycstate { margin: 0 0 10px; }

/* ================================================================ operator panel [M80]
   The admin area is a set of queues, and a queue is read at a glance and acted on in one tap.
   Everything below serves that: the thing needing attention is the loudest, the decision is
   beside the row it decides, and the whole thing stacks on a phone because an operator is not
   always at a desk when a deposit arrives. */

.adminbody { max-width: 1180px; margin: 0 auto; padding: 26px 20px 70px; }
.adminbody h1 { margin: 0 0 6px; font-size: 1.55rem; }
.adminbody .panel { margin-bottom: 20px; }
.adminnav a[aria-current="page"] { color: var(--brand); border-bottom-color: var(--brand); }

.tiny { font-size: .74rem; }
.adminbody td, .adminbody th { vertical-align: top; font-size: .86rem; }
.adminbody .mono.tiny { word-break: break-all; }
.rowlink { white-space: nowrap; font-weight: 600; }

/* The queue cards. A count of zero is quiet; anything above zero on an urgent queue is not -
   the whole reason to open this page is to find out which of these is not zero. */
.qgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.qcard {
  display: flex; flex-direction: column; gap: 4px; padding: 16px 18px;
  border: 1px solid var(--m-300); border-radius: 12px; background: var(--surface);
  color: inherit; text-decoration: none;
  transition: border-color .15s ease, transform .15s ease;
}
.qcard:hover { border-color: var(--m-600); transform: translateY(-1px); text-decoration: none; }
.qn { font: 800 1.9rem/1 var(--sans); color: var(--m-tone-2); }
.ql { font-size: .8rem; color: var(--text-faint); }
.qcard.urgent .qn { color: var(--brand); }
.qcard.urgent:has(.qn:not(:empty)) { border-color: var(--m-300); }

/* Filters keep their own state, so they need to look like a bar rather than a form. */
.filterbar {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px;
  margin: 0 0 18px; padding: 14px 16px;
  border: 1px solid var(--m-300); border-radius: 12px; background: var(--brand-soft);
}
.filterbar label {
  display: flex; flex-direction: column; gap: 5px;
  font: 600 10.5px/1.5 var(--mono); letter-spacing: .09em; text-transform: uppercase;
  color: var(--m-tone-2);
}
.filterbar input, .filterbar select {
  min-height: 40px; padding: 8px 11px; font-size: 15px; font-family: var(--sans);
  color: var(--m-990); background: var(--surface);
  border: 1px solid var(--m-400); border-radius: 9px; min-width: 170px;
}
.filterbar input:focus, .filterbar select:focus {
  outline: none; border-color: var(--m-600);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 16%, transparent);
}
.filterbar button {
  min-height: 40px; padding: 8px 20px;
  font-family: var(--sans); font-size: .82rem; font-weight: 700;
  color: #fff; background-color: var(--brand-dark); background-image: var(--brand-sweep);
  border: 0; border-radius: 999px; cursor: pointer;
}

/* The decision, beside the row it decides. */
.decide { display: flex; flex-direction: column; gap: 7px; min-width: 210px; }
.decide input[type="text"] {
  min-height: 38px; padding: 7px 10px; font-size: 14px; font-family: var(--sans);
  color: var(--m-990); background: var(--surface);
  border: 1px solid var(--m-400); border-radius: 9px; width: 100%; box-sizing: border-box;
}
.decide .moves { display: flex; flex-wrap: wrap; gap: 7px; }
.decide button {
  min-height: 38px; padding: 8px 14px;
  font-family: var(--sans); font-size: .78rem; font-weight: 700;
  border-radius: 999px; border: 1px solid var(--m-400); cursor: pointer;
  color: var(--m-990); background: var(--surface);
}
.decide button:hover { border-color: var(--m-600); }
/* Only the consequential move is coloured. Three loud buttons is no emphasis at all. */
.decide button.ok {
  color: #fff; border-color: transparent;
  background-color: var(--brand-dark); background-image: var(--brand-sweep);
}
.decide button.down { color: var(--down-text); border-color: color-mix(in srgb, var(--down) 40%, transparent); }

.pager { display: flex; align-items: center; justify-content: center; gap: 18px; margin: 18px 0 0; font-size: .85rem; }
.pager span { color: var(--text-faint); }
.pagenum { font-family: var(--mono); font-size: .78rem; }

/* Identity documents, at a size somebody can actually read a card number from. */
.kyccard { display: flex; flex-direction: column; gap: 14px; }
.kycdocs { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; }
.kycdocs figure { margin: 0; }
.kycdocs figcaption {
  margin: 0 0 6px; font: 600 10.5px/1.5 var(--mono);
  letter-spacing: .09em; text-transform: uppercase; color: var(--m-tone-2);
}
.kycdocs img {
  display: block; width: 100%; height: auto; border-radius: 10px;
  border: 1px solid var(--m-300); background: var(--brand-soft);
}
.prooflink { display: inline-flex; align-items: center; gap: 8px; font-size: .8rem; }
.prooflink img {
  width: 44px; height: 44px; object-fit: cover; border-radius: 7px; border: 1px solid var(--m-300);
}

/* The same stacked-card treatment the investor tables get, on a wider breakpoint: an operator
   table has more columns, so it runs out of width sooner. */
@media (max-width: 860px) {
  .adminbody .tablewrap { overflow: visible; }
  .adminbody table, .adminbody tbody, .adminbody tr, .adminbody td { display: block; width: 100%; }
  .adminbody thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .adminbody tr {
    border: 1px solid var(--m-300); border-radius: 11px; padding: 12px 14px; margin: 0 0 10px;
    background: var(--surface);
  }
  .adminbody td {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
    padding: 6px 0; border: 0; text-align: right;
  }
  .adminbody td::before {
    content: attr(data-label); text-align: left; flex: none;
    font: 600 10.5px/1.5 var(--mono); letter-spacing: .08em; text-transform: uppercase;
    color: var(--m-tone-2);
  }
  /* The decision form is the exception: it is a control, not a value, so it takes the full
     width of the card instead of being squeezed against a label. */
  .adminbody td:has(.decide) { display: block; text-align: left; }
  .adminbody td:has(.decide)::before { display: block; margin-bottom: 7px; }
  .filterbar label, .filterbar input, .filterbar select { width: 100%; min-width: 0; }
  .filterbar button { width: 100%; }
}

/* A required field says so where the eye already is - on its label. [M80]
   Red, because that is the one colour a form marker is read as, and it carries no meaning on
   its own: `required` is on the input, the browser enforces it, and the server checks again. */
.req { color: var(--down-text); font-weight: 700; margin-left: 3px; }
.reqnote { margin-top: 2px; }
.reqnote .req { margin: 0 5px 0 0; }

/* ================================================================= support chat [M80]
   The corner the floating menu vacated. One button, one panel, one message - and a line in the
   panel saying a person reads it, because the thing that makes a chat bubble dishonest is
   letting somebody believe an agent is waiting when the answer comes tomorrow. */

.chat-fab {
  position: fixed; z-index: 60;
  right: max(18px, env(safe-area-inset-right));
  bottom: max(18px, env(safe-area-inset-bottom));
  width: 56px; height: 56px; padding: 0; border: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--on-gold); background-color: var(--brand-dark); background-image: var(--brand-sweep);
  box-shadow: 0 10px 26px -10px rgba(11, 87, 227, .8); cursor: pointer;
  transition: transform .2s cubic-bezier(.2,.8,.3,1), box-shadow .2s ease;
}
.chat-fab:hover { transform: translateY(-2px); box-shadow: 0 14px 30px -10px rgba(11, 87, 227, .85); }
.chat-fab:active { transform: scale(.95); }
.chat-fab[aria-expanded="true"] { transform: scale(.92); }

.chat-panel {
  position: fixed; z-index: 61;
  right: max(18px, env(safe-area-inset-right));
  bottom: calc(max(18px, env(safe-area-inset-bottom)) + 68px);
  width: min(340px, calc(100vw - 32px));
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 16px; box-shadow: 0 22px 50px -20px rgba(18, 50, 74, .45);
  overflow: hidden;
}
.chat-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px 16px; color: var(--on-gold);
  background-color: var(--brand-dark); background-image: var(--brand-sweep);
}
.chat-title { font-family: var(--sans); font-weight: 700; font-size: .95rem; letter-spacing: .01em; }
.chat-close {
  background: none; border: 0; color: var(--on-gold); font-size: 1.5rem; line-height: 1;
  padding: 0 2px; cursor: pointer; opacity: .85;
}
.chat-close:hover { opacity: 1; }

.chat-log { padding: 16px 16px 6px; }
.chat-msg {
  margin: 0 0 10px; padding: 11px 14px; font-size: .9rem; line-height: 1.5;
  border-radius: 14px; max-width: 92%;
}
/* Theirs on the left in the soft blue, yours on the right in the brand. The two sides have to
   be told apart at a glance or a log is a wall of paragraphs. */
.chat-msg.them { background: var(--brand-soft); color: var(--text); border-bottom-left-radius: 5px; }
.chat-msg.me {
  margin-left: auto; color: var(--on-gold); border-bottom-right-radius: 5px;
  background-color: var(--brand-dark); background-image: var(--brand-sweep);
}
.chat-meta { margin: 0 0 4px; font-size: .74rem; color: var(--text-faint); }

.chat-form { padding: 4px 16px 16px; display: grid; gap: 0; }
.chat-label {
  display: block; margin: 8px 0 5px;
  font: 600 10.5px/1.5 var(--mono); letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-faint);
}
.chat-form input[type="text"], .chat-form textarea {
  width: 100%; box-sizing: border-box; padding: 10px 12px;
  font: inherit; font-size: 15px; color: var(--text);
  background: var(--bg); border: 1px solid var(--line); border-radius: 9px; resize: vertical;
}
.chat-form input:focus, .chat-form textarea:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 16%, transparent);
}
.chat-form button[type="submit"] {
  margin-top: 11px; min-height: 44px; padding: 11px 20px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--sans); font-size: .92rem; font-weight: 700;
  color: var(--on-gold); background-color: var(--brand-dark); background-image: var(--brand-sweep);
  border: 0; border-radius: 999px; cursor: pointer;
}

/* The investor pages already have a tab bar in that corner, so the bubble lifts above it. */
[data-chrome="minimal"] .chat-fab { bottom: calc(max(18px, env(safe-area-inset-bottom)) + 74px); }
[data-chrome="minimal"] .chat-panel { bottom: calc(max(18px, env(safe-area-inset-bottom)) + 142px); }
@media (min-width: 901px) {
  [data-chrome="minimal"] .chat-fab { bottom: max(18px, env(safe-area-inset-bottom)); }
  [data-chrome="minimal"] .chat-panel { bottom: calc(max(18px, env(safe-area-inset-bottom)) + 68px); }
}

@media (prefers-reduced-motion: reduce) {
  .chat-fab { transition: none; }
}
