/* ── Fourteen days, as a strip ──
   Not a bar chart: bars scale to the busiest day, so one completion drew
   thirteen hairlines and a single full-height block — which read as a stray
   yellow rectangle rather than as information. A strip has no scale to
   distort, so an empty fortnight looks empty instead of broken. */
.pl-strip{display:flex;align-items:center;gap:12px;margin-top:16px;
  padding-top:14px;border-top:1px solid var(--line-2);}
.pl-strip-l{font-size:10.5px;color:var(--fg-3);white-space:nowrap;}
.pl-strip-days{display:flex;gap:4px;direction:ltr;}
.pl-d{width:11px;height:11px;border-radius:2.5px;background:var(--bg-3);display:block;}
.pl-d.lv1{background:var(--gold-dk);}
.pl-d.lv2{background:var(--gold-dp);}
.pl-d.lv3{background:var(--gold);}
.pl-d.now{box-shadow:0 0 0 1.5px var(--gold-line);}

/* ── The year, in the Done view ──
   A quiet month is listed as quiet: a month left out reads as missing data. */
.pl-hist{margin-bottom:12px;}
.pl-hist-top{display:flex;gap:26px;flex-wrap:wrap;padding-bottom:14px;margin-bottom:14px;
  border-bottom:1px solid var(--line-2);}
.pl-hist-fig{display:flex;flex-direction:column;gap:2px;}
.pl-hist-fig b{font-family:var(--f-mono);font-size:22px;font-weight:600;color:var(--gold-lt);
  direction:ltr;unicode-bidi:isolate;letter-spacing:-.02em;}
.pl-hist-fig span{font-size:10.5px;color:var(--fg-3);}
/* Held to a readable width rather than stretched across the screen: twelve
   full-width tracks is a lot of furniture for a figure that is mostly zero. */
.pl-hist-rows{display:flex;flex-direction:column;gap:5px;max-width:520px;}
.pl-hist-row{display:grid;grid-template-columns:44px minmax(0,1fr) 30px;align-items:center;gap:10px;}
.pl-hist-m{font-size:11px;color:var(--fg-2);}
.pl-hist-track{height:6px;background:var(--bg-2);border-radius:var(--r1);overflow:hidden;}
.pl-hist-bar{display:block;height:100%;border-radius:var(--r1);
  background:linear-gradient(90deg,var(--gold-dk),var(--gold-dp));transition:width .5s var(--ease);}
.pl-hist-n{font-size:11.5px;color:var(--fg-2);text-align:end;}
.pl-hist-row.quiet{opacity:.42;}
.pl-hist-row.quiet .pl-hist-track{background:var(--bg-2);}

/* ══════════════════════════════════════════════════════
   Zexca — dashboard stylesheet
   Same design language as the activation terminal: dark luxury gold,
   exchange typography, trilingual (EN / AR / FA) with full RTL.
   Written mobile-first: base rules target the phone, min-width queries
   widen it. The 5-button bottom bar is the primary navigation.
   ══════════════════════════════════════════════════════ */

/* ══ TOKENS ══ */
:root{
  --bg-0:#0A0C10; --bg-1:#11151C; --bg-2:#171C25; --bg-3:#1F2632; --bg-4:#28313F;
  --line:#242C38; --line-2:#1A212B; --hair:rgba(255,255,255,0.06);

  --gold:#E8B647; --gold-lt:#F7D488; --gold-dp:#B8862A; --gold-dk:#7A5A1C;
  --gold-pale:rgba(232,182,71,0.09); --gold-line:rgba(232,182,71,0.30);
  --gold-glow:rgba(232,182,71,0.18); --on-gold:#150F02;

  --mlc:#7FB4D4; --mlc-lt:#A9D0E8; --mlc-dp:#4E88AC;
  --mlc-pale:rgba(127,180,212,0.10); --mlc-line:rgba(127,180,212,0.30);

  /* Text — every level clears 4.5:1 against the card backgrounds */
  --fg:#EDF1F6; --fg-2:#A9B4C2; --fg-3:#8A96A6;

  --up:#0ECB81; --up-pale:rgba(14,203,129,0.10); --up-line:rgba(14,203,129,0.30);
  --down:#F6465D; --down-pale:rgba(246,70,93,0.09); --down-line:rgba(246,70,93,0.28);
  --warn:#F0B90B; --warn-pale:rgba(240,185,11,0.10); --warn-line:rgba(240,185,11,0.26);
  --info:#7FB4D4; --info-pale:rgba(127,180,212,0.10); --info-line:rgba(127,180,212,0.28);

  /* Tier accents, shared with the activation page's package cards */
  --tier-bronze:#C08457;
  --tier-silver:#B4BCC8; --tier-gold:#E8B647; --tier-platinum:#D9DFE8; --tier-black:#F7D488;
  /* Package distribution: four swatches that stay apart from each other when
     they sit side by side in one bar. */
  --pkg-silver:#7E8AA0; --pkg-gold:#E8B647; --pkg-platinum:#D9DFE8; --pkg-black:#9A6B18;
  /* The four markets the engine trades, for the distribution donut. Gold keeps
     the product's gold; the other three stay far enough apart to be told apart
     in a 15px arc and in a 10px legend dot. */
  --sig-forex:#7FB4D4; --sig-gold:#E8B647; --sig-crypto:#8E7CC3; --sig-stock:#5EC5A6;
  /* The two legs and the reader, for the genealogy canvas. Alpha and beta keep
     the colours the team module already gave them — the same leg cannot be gold
     in one tab and copper in the next — so the reader's own node takes the third,
     neutral one rather than sitting on either side. */
  --leg-alpha:#E8B647; --leg-alpha-rgb:232,182,71;
  --leg-beta:#7FB4D4;  --leg-beta-rgb:127,180,212;
  --leg-root:#D9DFE8;  --leg-root-rgb:217,223,232;

  /* ══ SPACING ══
     A 4px scale, because `--r1` is already 4px and a rhythm that disagrees with
     the radius reads as two systems. Before this there was no scale at all —
     every margin and gap in this file is a literal, and literals drift: the same
     "section gap" appears as 14, 16 and 18px within a hundred lines of each
     other. New work takes these; existing literals are replaced only where a
     component is being touched for another reason, so this lands as a
     convergence rather than as one enormous diff nobody can review. */
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px;
  --space-5:24px; --space-6:32px; --space-7:48px; --space-8:64px;

  /* ══ MOTION ══
     `--ease` above is the house out-curve and is NOT replaced — every existing
     transition in this file already speaks it. What was missing is duration:
     .18s, .22s, .25s, .3s and .34s all appear in this stylesheet meaning "a
     normal transition", which is four accidental dialects of one idea.

     FOUR DURATIONS, BY WHAT THEY ARE FOR:
       1  a press — felt under the finger rather than watched
       2  the standard change of state
       3  a surface travelling a real distance: sheet, drawer
       4  an entrance permitted to be noticed, once

     AND EXITS ARE FASTER THAN ENTRANCES. A thing arriving deserves to be
     watched; a thing leaving is in the way, and `--ease-exit` accelerates it
     out rather than easing it out. `--ease-spring` overshoots exactly once and
     is for arrivals only — never for anything a reader is waiting on. */
  --dur-1:120ms; --dur-2:220ms; --dur-3:340ms; --dur-4:480ms;
  --ease-exit:cubic-bezier(0.4,0,1,1);
  --ease-spring:cubic-bezier(0.34,1.4,0.64,1);

  /* ══ ELEVATION ══
     DECLARED HERE AND ENRICHED THERE. `zexca-depth.css` owns the product's
     material vocabulary — `--sh-1/2/3`, bevels, wells — but declares it under
     `body.depth`, so nothing in this file could ever reference it. These four
     are the base set: modest, correct on their own, and overridden by the
     material layer when it is on, exactly the way `--lift` already works.

     THE NUMBERS ARE DELIBERATELY SMALL. A drop shadow barely exists on a
     #0A0C10 ground — the material layer says so at length and spends its budget
     on edge lighting instead. These carry separation, not drama. */
  --elev-0:none;
  --elev-1:0 1px 2px rgba(0,0,0,.45);
  --elev-2:0 2px 6px rgba(0,0,0,.50), 0 8px 20px rgba(0,0,0,.28);
  --elev-3:0 4px 12px rgba(0,0,0,.58), 0 16px 38px rgba(0,0,0,.38);

  --r1:4px; --r2:8px; --r3:12px;
  /* THE STATUS BAR IS PART OF THE BAR'S HEIGHT, and folding it in here is what
     makes that true in the nine places that read this token rather than in one.
     `.topbar` sets its height from it, the notification panel hangs below it,
     four sticky offsets measure from it and `.gx-stage` subtracts it from the
     viewport — every one of them wants the space the bar ACTUALLY occupies.

     IT WAS WRONG ON A PHONE UNTIL NOW, and the web-app work is what exposed it:
     `apple-mobile-web-app-status-bar-style: black-translucent` puts the web view
     under the status bar, which is the integrated look that is wanted — but
     nothing in this stylesheet reserved a top inset for the header. Only
     `.drawer-bar` did, which is why the menu looked right and the bar behind it
     did not. On a Dynamic Island phone the wordmark sat under the island.

     `env()` is 0 wherever there is no inset, so this is still exactly 56px on a
     laptop, on Android with no cutout, and in any browser that has never heard
     of safe areas. */
  --topbar-h:calc(56px + env(safe-area-inset-top, 0px)); --tabbar-h:62px; --drawer-w:290px;

  --f-display:'Plus Jakarta Sans',system-ui,-apple-system,sans-serif;
  --f-body:'Inter',system-ui,-apple-system,sans-serif;
  --f-mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --ease:cubic-bezier(0.16,1,0.3,1);
}
/* RTL typefaces: Vazirmatn for Persian, IBM Plex Sans Arabic for Arabic */
html[lang="fa"]{--f-display:'Vazirmatn',system-ui,sans-serif;--f-body:'Vazirmatn',system-ui,sans-serif;}
html[lang="ar"]{--f-display:'IBM Plex Sans Arabic',system-ui,sans-serif;--f-body:'IBM Plex Sans Arabic',system-ui,sans-serif;}

/* ══ BASE ══ */
*{margin:0;padding:0;box-sizing:border-box;}
/* clip rather than hidden — hidden on html breaks position:sticky */
html{-webkit-text-size-adjust:100%;overflow-x:clip;}
body{
  background:var(--bg-0);color:var(--fg);font-family:var(--f-body);font-size:14px;line-height:1.65;
  min-height:100vh;min-height:100dvh;
  /* `clip`, NOT `hidden` — AND THE HEADER DEPENDS ON THE DIFFERENCE.
     `overflow-x:hidden` forces the other axis to compute as `auto`, which makes
     the body a scroll container. `.topbar` is `position:sticky`, so it then
     stuck to the BODY while the page actually scrolled on the viewport — and a
     sticky element whose scroll container is not the thing being scrolled
     simply travels with the content. The bar left the screen on the way down
     and took the notification and support buttons with it.

     `clip` cuts off horizontal overflow exactly as `hidden` did and creates no
     scroll container at all, so `overflow-y` stays `visible` and sticky resolves
     against the viewport again. `html` above has used `clip` since it was
     written, so nothing new is being relied on here. */
  overflow-x:clip;-webkit-font-smoothing:antialiased;
  -webkit-tap-highlight-color:transparent;
  padding-bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom,0px) + 12px);
}
button,input,select,textarea{font-family:inherit;color:inherit;font-size:inherit;}
button{background:none;border:none;cursor:pointer;touch-action:manipulation;}
a{color:var(--gold-lt);text-decoration:none;}
/* Figures stay tabular and LTR, even in RTL */
.num{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1;
     direction:ltr;unicode-bidi:isolate;display:inline-block;}

/* Every element that carries a figure must open its own bidi isolate.
   `direction:ltr` on its own does nothing: without unicode-bidi the element
   stays in the parent's paragraph level, so in RTL a leading "-", "+" or "$"
   and a trailing "%" get pushed to the wrong end (-1.25% became %1.25-). */
.acct-no,.drawer-acct,.drawer-version,.badge,.menu-item-badge,
.stat-val,.chip.mono,.dt .cell-num,.pr-pct,.snap-val,.milo-ticker b,
.hero-amount,.coin-val,.cc-val.mono,
.range-tab,.sig-sym,.sig-prices,.sig-res,.kv-v,
.mkt-sym,.mkt-price,.mkt-chg,.rp-row-val,.chart-axis,
.fs-count,.ms-target,.fact-val,.ms-row-amt,.bal-pct,.pkg-count,.pkg-pct,
.st-val,.dl-acct,.dl-amt,.tk-no,
.gx-stat-val,.gx-node-lbl,.gx-tick,.gx-depth-lbl,.gx-res-id,.gx-tag,.gx-count,
.pkg-range,.pkg-return-val,.ladder-ret,.ct-no,.ct-val,.sig-figv,
.dnt-pct,.dnt-count,.dir-count,.stk-val,.month-lbl,.mkx-wr,.mkx-n,
.sigc-sym,.sigc-pval,.sigc-qval,.sigc-ladv,.sigc-time,.sigc-tlbl,.mwx-c-day{
  unicode-bidi:isolate;}
::-webkit-scrollbar{width:5px;height:5px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{background:var(--bg-4);border-radius:3px;}
:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:var(--r1);}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}
[hidden]{display:none !important;}

.ic{width:16px;height:16px;flex-shrink:0;stroke:currentColor;fill:none;stroke-width:1.6;
    stroke-linecap:round;stroke-linejoin:round;}
.ic-lg{width:20px;height:20px;}
.ic-xl{width:28px;height:28px;stroke-width:1.35;}
[dir="rtl"] .ic-dir{transform:scaleX(-1);}

/* Uppercase micro-labels do not survive Persian/Arabic script */
html[lang="fa"] .lbl,html[lang="ar"] .lbl,
html[lang="fa"] .card-eyebrow,html[lang="ar"] .card-eyebrow,
html[lang="fa"] .stat-lbl,html[lang="ar"] .stat-lbl,
html[lang="fa"] .dt th,html[lang="ar"] .dt th,
html[lang="fa"] .menu-group-title,html[lang="ar"] .menu-group-title,
html[lang="fa"] .pr-lbl,html[lang="ar"] .pr-lbl,
html[lang="fa"] .cc-lbl,html[lang="ar"] .cc-lbl,
html[lang="fa"] .rp-title,html[lang="ar"] .rp-title,
html[lang="fa"] .rp-row-label,html[lang="ar"] .rp-row-label,
html[lang="fa"] .wr-title,html[lang="ar"] .wr-title,
html[lang="fa"] .field-label,html[lang="ar"] .field-label
{letter-spacing:0;text-transform:none;}
html[lang="fa"] .qb,html[lang="ar"] .qb{font-family:var(--f-body);}

/* Money masking (privacy mode) — keeps layout, hides figures */
body.mask-money .money{color:transparent !important;text-shadow:0 0 9px var(--fg-2);user-select:none;}
/* -webkit-text-fill-color BEATS color, and two headings on this product are cut
   from a clipped gradient — so masking `color` alone would leave them legible
   while every figure beside them blurred. */
body.mask-money .money{-webkit-text-fill-color:transparent;}

/* ── A figure that is also a door ──
   `.stat` is a div; `.stat-go` is the same tile rendered as a button because it
   leads somewhere. It must not look like a control at rest — it is a number
   first — so the only resting difference is the chevron, at a third opacity. */
.stat-go{appearance:none;-webkit-appearance:none;background:none;border:0;padding:0;
  margin:0;font:inherit;color:inherit;cursor:pointer;position:relative;
  text-align:inherit;display:block;width:100%;}
.stat-go-ic{position:absolute;top:0;inset-inline-end:0;display:inline-flex;
  color:var(--fg-3);opacity:.32;transition:opacity .18s var(--ease), transform .18s var(--ease);}
.stat-go-ic .ic{width:13px;height:13px;}
.stat-go:hover .stat-go-ic{opacity:1;color:var(--gold-lt);transform:translateX(2px);}
[dir="rtl"] .stat-go:hover .stat-go-ic{transform:scaleX(-1) translateX(2px);}
.stat-go:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:var(--r1);}
/* The sheet while its own contents are being fetched — see `contractsSheet`. */
.sheet-load{padding:6px 0 2px;}

/* Motion preference set in Settings, independent of the OS setting */
body.no-motion *,body.no-motion *::before,body.no-motion *::after{
  animation-duration:.001ms !important;animation-iteration-count:1 !important;
  transition-duration:.001ms !important;}
body.no-motion #bgCanvas{display:none;}

#bgCanvas{position:fixed;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;}
.shell{position:relative;z-index:1;}

/* ══════════════════════════════════════════════════════
   TOP BAR
   ══════════════════════════════════════════════════════ */
.topbar{
  height:var(--topbar-h);background:rgba(10,12,16,0.94);
  -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);
  border-bottom:1px solid var(--line-2);display:flex;align-items:center;
  padding-inline:12px;position:sticky;top:0;z-index:60;gap:10px;
  /* At rest the bar is barely a surface — it sits on the page rather than over
     it. Once the content starts passing underneath it earns a defined edge and
     a shadow, because now there IS something underneath to separate from.
     `data-scrolled` is written once per state change, not per scroll event. */
  /* THE SHADOW IS NOT THIS FILE'S TO TAKE. `zexca-depth.css` lights the top bar
     and the tab bar permanently and says why: the chrome is on screen the whole
     time a reader is here, so it joins the elevation system and is lit by the
     same lamp as the content. A rest state that removed that shadow would be
     this file arguing with that one.

     So the scroll state is expressed in what this file DOES own — the hairline
     and the opacity of the ground. At rest the bar sits on the page with no
     edge; once content is passing underneath it takes an edge, because now
     there is something to be separated from. */
  transition:background var(--dur-2) var(--ease),
             border-color var(--dur-2) var(--ease);
  border-bottom-color:transparent;
  /* The bar now COVERS the status bar area — that is the point, so the dark
     surface runs to the top of the screen instead of the content merely being
     pushed down below a gap. This keeps its CONTENTS out of the inset, so the
     row a reader sees is 56px on every device. */
  padding-top:env(safe-area-inset-top, 0px);
  /* The horizontal insets matter in landscape on a notched phone, where the
     cutout eats into one side. */
  padding-inline-start:calc(12px + env(safe-area-inset-left, 0px));
  padding-inline-end:calc(12px + env(safe-area-inset-right, 0px));
}
.topbar[data-scrolled="1"]{
  background:rgba(10,12,16,0.97);
  border-bottom-color:var(--line-2);
}

/* The wordmark is the way home, so it is a button rather than a decoration. */
.tb-logo{display:flex;align-items:center;gap:9px;flex-shrink:0;min-width:0;text-align:start;}
.tb-words,.tb-name{display:block;}
.tb-mark{
  width:30px;height:30px;border-radius:var(--r2);flex-shrink:0;
  background:linear-gradient(145deg,var(--gold-lt),var(--gold-dp));
  display:flex;align-items:center;justify-content:center;
  font-family:var(--f-display);font-weight:800;font-size:14px;color:var(--on-gold);
  box-shadow:0 3px 14px var(--gold-glow);
  transform-style:preserve-3d;animation:markFloat 7s ease-in-out infinite;
}
@keyframes markFloat{0%,100%{transform:perspective(300px) rotateY(0) rotateX(0)}
  50%{transform:perspective(300px) rotateY(16deg) rotateX(-7deg)}}
.tb-name{font-family:var(--f-display);font-weight:800;font-size:16px;letter-spacing:0.03em;
  background:linear-gradient(120deg,var(--gold-lt),var(--gold));-webkit-background-clip:text;
  background-clip:text;-webkit-text-fill-color:transparent;line-height:1.2;}
.tb-tag{font-size:10px;color:var(--fg-3);display:none;}
.tb-spacer{flex:1;}
.tb-right{display:flex;align-items:center;gap:4px;flex-shrink:0;}

/* ── Primary destinations, fixed in the bar (desktop only) ──
   The phone reaches these through the bottom bar, so the row is not rendered
   there at all: below 1024px this bar is exactly what it was. */
.tb-nav{display:none;}
@media(min-width:1024px){
  .tb-nav{display:flex;align-items:center;gap:2px;margin-inline-start:12px;}
}
.tb-nav-item{position:relative;padding:9px 14px;border-radius:var(--r2);font-size:15px;
  font-weight:700;color:var(--fg-2);white-space:nowrap;transition:color .2s,background .2s;}
.tb-nav-item:hover{color:var(--fg);background:var(--bg-1);}
.tb-nav-item.active{color:var(--gold-lt);}
/* The underline sits on the bar's own border line, so the active destination
   reads as the tab of the page under it. */
.tb-nav-item.active::after{content:'';position:absolute;bottom:-9px;inset-inline:13px;height:2px;
  background:linear-gradient(90deg,transparent,var(--gold),transparent);}

/* Account chip */
/* Identity, not a control: it states who is signed in and reacts to nothing. */
.acct-chip{display:flex;align-items:center;gap:9px;padding:5px 9px;border-radius:var(--r2);
  border:1px solid transparent;min-height:40px;}
/* The menu's own door. Wider than a plain icon button because it carries the
   caret that says a panel is behind it. */
.acct-icon{width:auto;gap:3px;padding-inline:9px;}
.acct-icon .ic{width:19px;height:19px;}
.acct-caret{display:flex;align-items:center;color:var(--fg-3);transition:transform .24s var(--ease);}
.acct-caret .ic{width:13px;height:13px;}

/* ── The account rollup ──
   One menu on the right, opened by pointing at it rather than by clicking:
   the trigger is not a link and navigates nowhere. Below 1024px it does not
   exist — the phone keeps its drawer — so every rule lives in the query. */
.acct-pop{display:none;}
/* ── The rollup is desktop-only, and now actually is ──
   THIS RULE USED TO LIE. It read `.acct-icon{display:none;}` here and claimed
   the trigger was not drawn below 1024px — but `.icon-btn` further down this
   file sets `display:flex`, the two selectors carry the same specificity, and
   the later one wins. The person glyph has been on every phone since the line
   was written, doing nothing, because a rule that matches and loses is not a
   rule that fails loudly.

   The whole `.acct-menu` goes instead of its parts: the identity chip and the
   trigger both live inside it, and below 1024px the drawer is the menu. Once
   the drawer's trigger became the reader's own avatar, leaving this up meant
   TWO avatars in one bar — and this one at `y=-13`, half cut off by the top of
   the bar it did not fit in.

   In a max-width query so it wins on order and cannot reach the desktop. */
@media(max-width:1023px){.acct-menu{display:none;}}
/* AND THE LANGUAGE PICKER GOES WITH IT. The rule above has shed the account
   rollup on phones since it was written; the picker never got the same
   treatment, so below 1024px it stayed wedged into the bar beside the bell, the
   support button and the source chip. It now lives in the drawer — see
   `menuLangHtml()` — which is where the account's other switches already are.
   The element is only hidden, not removed: `setLang()` still writes
   `#langCode` and closes `#langMenu`, and both must remain in the document for
   the desktop picker that shares them. */
@media(max-width:1023px){.lang{display:none;}}
@media(min-width:1024px){
  /* Stretched to the bar's full height on purpose: `top:100%` on the panel then
     means the bar's own bottom edge, so the menu rolls down from the edge rather
     than from the middle of the chip — and the whole height of the chip's column
     is hoverable, not just the 40px the chip itself occupies. */
  .tb-right{align-self:stretch;}
  .acct-menu{position:relative;align-self:stretch;display:flex;align-items:center;}
  .acct-menu.open .acct-icon{color:var(--gold-lt);border-color:var(--gold-line);
    background:var(--gold-pale);}
  .acct-menu.open .acct-caret{transform:rotate(180deg);}
  /* Two columns, because one made the reader scroll to reach Settings — the row
     that moved in here in the first place. The groups are balanced by the column
     layout and told not to break, so a group is never split down the middle. */
  .acct-pop-nav{column-count:2;column-gap:10px;}
  .menu-group{break-inside:avoid;margin-bottom:10px;}
  .acct-pop{position:absolute;top:calc(100% + 5px);inset-inline-end:0;width:432px;z-index:90;
    background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r3);
    box-shadow:0 20px 54px rgba(0,0,0,.62);flex-direction:column;
    max-height:min(78vh,660px);transform-origin:top center;}
  .acct-menu.open .acct-pop{display:flex;animation:rollDown .26s var(--ease);}
  /* The gap above the panel would drop the hover on the way down, so the panel
     reaches back over it with a strip of its own. */
  .acct-pop::before{content:'';position:absolute;top:-7px;inset-inline:0;height:7px;}
}
/* Rolling down from the bar's edge, the same motion the language menu uses. */
@keyframes rollDown{
  from{opacity:0;transform:perspective(760px) rotateX(-14deg) translateY(-8px);}
  to{opacity:1;transform:none;}
}
.acct-pop-head{display:flex;align-items:center;gap:11px;padding:14px;
  border-bottom:1px solid var(--line-2);}
.acct-pop-id{min-width:0;flex:1;}
.acct-mail{font-size:12.5px;font-weight:600;color:var(--fg);direction:ltr;unicode-bidi:isolate;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;}
.acct-pop-uid{display:flex;align-items:center;gap:5px;margin-top:2px;}
.acct-pop-uid .acct-no{font-size:11px;}
.acct-pop-copy{width:22px;height:22px;border-radius:var(--r1);display:flex;align-items:center;
  justify-content:center;color:var(--fg-3);transition:color .18s,background .18s;}
.acct-pop-copy:hover{color:var(--gold-lt);background:var(--gold-pale);}
.acct-pop-copy .ic{width:13px;height:13px;}
.acct-pop-chips{display:flex;gap:6px;flex-wrap:wrap;padding:11px 14px 0;}
.acct-pop-chips:empty{display:none;}
.acct-pop-nav{flex:1;overflow-y:auto;padding:9px 8px;overscroll-behavior:contain;}
.acct-pop-foot{border-top:1px solid var(--line-2);padding:8px;}
.avatar{width:30px;height:30px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;
  justify-content:center;font-family:var(--f-display);font-weight:700;font-size:12px;
  background:linear-gradient(145deg,var(--bg-4),var(--bg-2));border:1px solid var(--gold-line);
  color:var(--gold-lt);letter-spacing:0.04em;}
.avatar-lg{width:46px;height:46px;font-size:16px;}
/* Wrapper spans that stack two lines of text. Without an explicit column
   flex they would run together on one line. */
.acct-text,.coin-text,.sig-mid,.chk-text,.notif-body,.sw-row-text{
  display:flex;flex-direction:column;min-width:0;}
.acct-text{display:none;text-align:start;align-items:flex-start;min-width:0;}
@media(min-width:420px){.acct-text{display:flex;}}
.acct-name{font-size:12.5px;font-weight:600;line-height:1.25;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;max-width:150px;}
.acct-no{font-family:var(--f-mono);font-size:10.5px;color:var(--fg-3);direction:ltr;}

/* Icon buttons (menu, bell, gear) */
.icon-btn{position:relative;width:40px;height:40px;border-radius:var(--r2);display:flex;
  align-items:center;justify-content:center;color:var(--fg-2);
  border:1px solid transparent;transition:all .2s;}
.icon-btn:hover{color:var(--gold-lt);border-color:var(--gold-line);background:var(--gold-pale);}
.icon-btn.on{color:var(--gold-lt);border-color:var(--gold-line);background:var(--gold-pale);}
.icon-btn .ic{width:19px;height:19px;}
.badge{position:absolute;top:5px;inset-inline-end:5px;min-width:16px;height:16px;padding:0 4px;
  border-radius:8px;background:var(--down);color:#fff;font-family:var(--f-mono);font-size:9.5px;
  font-weight:600;display:flex;align-items:center;justify-content:center;direction:ltr;
  border:1.5px solid var(--bg-0);}
.badge:empty,.badge[data-count="0"]{display:none;}
.bell-ring{animation:bellPulse 2.6s ease-in-out infinite;}
@keyframes bellPulse{0%,92%,100%{transform:none}94%{transform:rotate(-11deg)}97%{transform:rotate(9deg)}}

/* Language picker — same behaviour as the activation page */
.lang{position:relative;}
.lang-btn{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--fg-2);
  border:1px solid var(--line);border-radius:var(--r1);padding:6px 9px;transition:all .2s;min-height:38px;}
.lang-btn:hover{border-color:var(--gold-line);color:var(--gold-lt);}
.lang-code{font-family:var(--f-mono);font-size:11px;text-transform:uppercase;}
.lang-menu{
  position:absolute;top:calc(100% + 7px);inset-inline-end:0;min-width:186px;z-index:90;
  background:var(--bg-2);border:1px solid var(--line);border-radius:var(--r2);padding:5px;
  box-shadow:0 16px 44px rgba(0,0,0,.6);display:none;
  transform-origin:top right;animation:menuIn .22s var(--ease);
}
[dir="rtl"] .lang-menu{transform-origin:top left;}
.lang-menu.open{display:block;}
@keyframes menuIn{from{opacity:0;transform:perspective(600px) rotateX(-12deg) translateY(-6px)}
  to{opacity:1;transform:none}}
.lang-opt{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;
  padding:11px 12px;border-radius:var(--r1);font-size:13.5px;color:var(--fg-2);
  transition:background .18s,color .18s;text-align:start;min-height:44px;}
.lang-opt:hover{background:var(--bg-3);color:var(--fg);}
.lang-opt.on{color:var(--gold-lt);background:var(--gold-pale);}
.lang-opt .ic{width:15px;height:15px;opacity:0;}
.lang-opt.on .ic{opacity:1;}
.lang-native{font-size:11.5px;color:var(--fg-3);}
.lang-opt.on .lang-native{color:var(--gold);}

/* Status pill */
.pill{display:inline-flex;align-items:center;gap:7px;font-size:11.5px;padding:5px 11px;
  border-radius:var(--r1);background:var(--warn-pale);border:1px solid var(--warn-line);
  color:var(--warn);white-space:nowrap;}
.pill.live{background:var(--up-pale);border-color:var(--up-line);color:var(--up);}
.pill-dot{width:5px;height:5px;border-radius:50%;background:currentColor;animation:pulse 2.4s infinite;}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}

/* Floating toast */
.toast{
  display:none;position:fixed;z-index:95;
  bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom,0px) + 16px);
  left:50%;max-width:min(92vw,540px);
  background:rgba(14,203,129,0.13);border:1px solid var(--up-line);border-radius:var(--r2);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  padding:12px 18px;text-align:center;font-size:12.5px;color:var(--up);
  box-shadow:0 10px 34px rgba(0,0,0,.55);transform:translateX(-50%);
}
.toast.show{display:flex;align-items:center;gap:var(--space-2);text-align:start;
  animation:toastIn var(--dur-3) var(--ease);}
/* The exit: faster than the entrance, and accelerating away rather than easing
   out — a thing that is finished should not linger over it. */
.toast.leaving{animation:toastOut var(--dur-1) var(--ease-exit) forwards;}
.toast-ic{flex:0 0 auto;display:flex;}
.toast-ic .ic{width:16px;height:16px;}
.toast-msg{min-width:0;}
/* A FAILURE IS NOT GREEN. This box carried "Card added" and "that did not work"
   in the same `--up` green for its whole life, which tells a reader glancing at
   the corner the opposite of what happened. The red is the one `.err-box`
   already uses further down this file, so the two ways this product reports a
   failure look like one thing. */
.toast.bad{background:var(--down-pale);border-color:var(--down-line);color:var(--down);}
@keyframes toastIn{from{opacity:0;transform:translateX(-50%) translateY(16px) scale(.96)}
  to{opacity:1;transform:translateX(-50%) scale(1)}}
@keyframes toastOut{from{opacity:1;transform:translateX(-50%) scale(1)}
  to{opacity:0;transform:translateX(-50%) translateY(8px) scale(.98)}}
@media(prefers-reduced-motion:reduce){
  /* It still appears and still goes; it simply does not travel to do either. */
  .toast.show{animation:none;}
  .toast.leaving{animation:none;opacity:0;}
}

/* ══════════════════════════════════════════════════════
   MENU: the phone's drawer, and the desktop's rollup
   ONE ROUTE LIST, TWO SHAPES. `.menu-*` is the labelled row, and the desktop
   rollup is the only thing that draws it now. The phone's drawer draws `.mx-*`
   instead — a grid of tiles, because a drawer is 290px wide and a column of
   16px rows spent most of that on nothing.

   `.menu-*` still lives in this section rather than moving next to the rollup:
   the drawer's foot (Legal, Log out) is two `.menu-item`s, and those two do
   belong to the drawer. The rows are shared; only the route list stopped being.
   ══════════════════════════════════════════════════════ */
.scrim{position:fixed;inset:0;z-index:80;background:rgba(4,6,9,.66);
  -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
  opacity:0;pointer-events:none;transition:opacity .3s var(--ease);}
.scrim.on{opacity:1;pointer-events:auto;}

.drawer{
  position:fixed;inset-block:0;inset-inline-start:0;width:var(--drawer-w);max-width:86vw;z-index:85;
  background:var(--bg-1);border-inline-end:1px solid var(--line);
  display:flex;flex-direction:column;
  transform:translateX(-100%);transition:transform var(--dur-3) var(--ease);
  box-shadow:0 0 50px rgba(0,0,0,.6);
  /* Landscape on a notched phone puts the cutout down the leading edge, which
     is exactly where this panel lives. */
  padding-inline-start:env(safe-area-inset-left,0px);
}
[dir="rtl"] .drawer{transform:translateX(100%);}
.drawer.open,[dir="rtl"] .drawer.open{transform:translateX(0);}

/* ── Full screen on a phone ──
   The panel becomes the page. z-index 85 is already above the top bar (60) and
   the tab bar (71), so nothing about the layering moves — only the box. The
   slide stays: it is what says where this came from.

   Desktop is not in this query and keeps the 290px panel it has always had. */
@media(max-width:1023px){
  .drawer{width:100%;max-width:none;inset:0;border-inline-end:0;box-shadow:none;}
}

/* The way back, on its own row above the identity — the shape the reference
   app uses, and the reason the head sits lower than a strip's would. */
.drawer-bar{display:flex;align-items:center;padding:8px 8px 0;
  padding-top:calc(8px + env(safe-area-inset-top,0px));}
.drawer-head{padding:6px 18px 16px;border-bottom:1px solid var(--line-2);
  display:flex;align-items:flex-start;gap:13px;}
.drawer-kyc{margin-top:9px;}
.drawer-head-text{min-width:0;flex:1;}
.drawer-name{font-family:var(--f-display);font-weight:700;font-size:15px;line-height:1.3;}
.drawer-acct{font-family:var(--f-mono);font-size:11px;color:var(--fg-3);direction:ltr;}
/* The number and its copy button read as one object, so the row is LTR as a
   whole even in Persian and Arabic — an account number is not a sentence, and
   a button that jumps to the far side of it in one language and back in the
   next is a button nobody learns where to find. */
.drawer-acct-row{display:flex;align-items:center;gap:4px;margin-top:3px;direction:ltr;}
.drawer-copy{width:24px;height:24px;border-radius:var(--r1);display:flex;align-items:center;
  justify-content:center;color:var(--fg-3);flex-shrink:0;transition:color .18s,background .18s;}
.drawer-copy:hover{color:var(--gold);background:var(--gold-pale);}
.drawer-copy .ic{width:13px;height:13px;}
/* ── The package card ──────────────────────────────────
   The one piece of the menu that is a statement rather than a destination:
   what this account holds, and how far the next band is.

   IT TAKES ITS COLOUR FROM THE TIER, NOT FROM GOLD. `--tier-*` already exists
   for the contract cards and the activation page, so a Platinum account gets
   platinum here and the menu agrees with every other screen that mentions the
   package. `--tier` is set once by the tier class and everything else in the
   card reads it. */
/* SMALLER, BECAUSE IT SAYS LESS NOW. The card lost its four figures (see
   `menuPackageHtml`), so the padding that framed a block of numbers is framing
   a badge, a line of type and a bar. The drawer's job is to get a reader
   somewhere, and every pixel this takes is a menu row pushed under the fold. */
.dpkg{margin:12px 16px 0;padding:12px 14px 13px;border-radius:var(--r3);
  --tier:var(--gold);
  border:1px solid color-mix(in srgb, var(--tier) 34%, transparent);
  background:
    radial-gradient(120% 140% at 100% 0%, color-mix(in srgb, var(--tier) 13%, transparent), transparent 60%),
    linear-gradient(155deg,var(--bg-2),var(--bg-1));
  position:relative;overflow:hidden;}
.dpkg.silver{--tier:var(--tier-silver);}
.dpkg.gold{--tier:var(--tier-gold);}
.dpkg.platinum{--tier:var(--tier-platinum);}
.dpkg.black{--tier:var(--tier-black);}
.dpkg.bronze{--tier:var(--tier-bronze);}

.dpkg-top{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:9px;}
.dpkg-badge{display:inline-flex;align-items:center;gap:6px;font-family:var(--f-display);
  font-weight:700;font-size:13px;padding:4px 11px;border-radius:var(--r1);
  color:var(--tier);border:1px solid var(--tier);background:rgba(255,255,255,.03);}
.dpkg-badge .ic{width:13px;height:13px;}
/* The return band, from the catalogue. Pushed to the end so the two read as
   "this package" then "what it pays" rather than as one run-on line. */

.dpkg-goal{font-size:10.5px;letter-spacing:0.08em;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:7px;}
html[lang="fa"] .dpkg-goal,html[lang="ar"] .dpkg-goal{letter-spacing:0;text-transform:none;font-size:12px;}
.dpkg-bar{height:6px;border-radius:99px;background:var(--bg-3);overflow:hidden;direction:ltr;}
.dpkg-bar > span{display:block;height:100%;border-radius:99px;
  background:linear-gradient(90deg,color-mix(in srgb,var(--tier) 55%,transparent),var(--tier));
  transition:width .5s var(--ease);}

/* At the top of the ladder there is no bar, because a bar at 100% reads as
   "nearly" and this is "arrived". */
.dpkg-max{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--tier);font-weight:600;}
.dpkg-max .ic{width:15px;height:15px;}
.dpkg-none{font-size:12.5px;color:var(--fg-2);line-height:1.65;}
.dpkg-cta{width:100%;margin-top:11px;min-height:42px;}

/* No longer pushed to the far end: it leads the bar it now has to itself. */
.drawer-close{margin-inline-end:auto;}

.drawer-scroll{flex:1;overflow-y:auto;padding:10px 8px 8px;overscroll-behavior:contain;}
/* ── THERE IS MORE BELOW ──
   The list ended at a hard edge against the footer's border, which is exactly
   what the BOTTOM of a list looks like — so a reader with three more groups
   under the fold had no way to know, and simply did not scroll.

   A mask rather than an overlay, because a mask applies to the element's
   painted BOX and not to the content inside it: the fade stays welded to the
   bottom edge of the panel while the rows travel underneath it. An absolutely
   positioned gradient would need a stacking context and would have to be kept
   clear of the scrollbar.

   AND IT IS ONLY THERE WHEN IT IS TRUE. `data-more` is written by the shell
   and removed the moment the list is scrolled to the end, so the fade never
   lies about content that does not exist — a permanent one would dim the last
   row of a short menu for no reason. */
.drawer-scroll[data-more="1"]{
  -webkit-mask-image:linear-gradient(to bottom, #000 calc(100% - 30px), transparent 100%);
  mask-image:linear-gradient(to bottom, #000 calc(100% - 30px), transparent 100%);
}
.menu-group{margin-bottom:14px;}
.menu-group-title{font-size:10px;letter-spacing:0.14em;text-transform:uppercase;color:var(--fg-3);
  padding:0 12px;margin-bottom:6px;}
.menu-item{display:flex;align-items:center;gap:11px;width:100%;padding:11px 12px;
  border-radius:var(--r2);font-size:13.5px;color:var(--fg-2);text-align:start;min-height:44px;
  border:1px solid transparent;transition:background .18s,color .18s,border-color .18s;}
.menu-item:hover{background:var(--bg-2);color:var(--fg);}
.menu-item.active{background:var(--gold-pale);border-color:var(--gold-line);color:var(--gold-lt);font-weight:600;}
.menu-item .ic{color:var(--fg-3);}
.menu-item.active .ic{color:var(--gold);}
.menu-item-badge{margin-inline-start:auto;font-family:var(--f-mono);font-size:10px;
  background:var(--down);color:#fff;border-radius:8px;min-width:16px;height:16px;padding:0 4px;
  display:flex;align-items:center;justify-content:center;direction:ltr;}
.drawer-foot{border-top:1px solid var(--line-2);padding:10px 8px;
  padding-bottom:calc(10px + env(safe-area-inset-bottom,0px));}
.drawer-version{font-family:var(--f-mono);font-size:10px;color:var(--fg-3);
  text-align:center;padding-top:6px;direction:ltr;}
.menu-item.danger{color:var(--down);}
.menu-item.danger .ic{color:var(--down);}

/* ── The phone's menu grid ────────────────────────────
   Four to a row at the drawer's full width, three when a language's words are
   long enough to need the room. The tile is the target, not the glyph: 44px of
   icon inside a button that is never shorter than 64px, so the reach does not
   depend on hitting a 22px drawing.

   THE GOLD IS THE ONE THE PRODUCT ALREADY HAS. `--gold` and its ramp were
   defined for the activation terminal and are what the tier chips, the leg
   colours and the active row have used since; a menu that introduced a second
   gold would have made every one of those look wrong by a few degrees. */
/* ── The menu arrives in order ──
   THE PANEL SLIDES AND ITS CONTENTS FOLLOW, half a beat behind and one group
   at a time. That half beat is the whole effect: a panel whose contents are
   already finished when it lands reads as a picture of a menu sliding in, and
   one whose contents settle after it lands reads as a menu arriving.

   Four groups, 40ms apart — 120ms of stagger in total, which is under the
   threshold where a reader starts waiting for the last one. The delays are
   `nth-child` rather than inline styles so nothing in `buildMenus()` has to
   know this exists.

   ONE-SHOT, NEVER A LOOP: `animation` with `both`, no iteration count. When the
   drawer closes the elements are still there, already at rest. */
@media(prefers-reduced-motion:no-preference){
  .drawer.open .mx-group{animation:mxIn var(--dur-3) var(--ease) both;}
  .drawer.open .mx-group:nth-child(1){animation-delay:60ms;}
  .drawer.open .mx-group:nth-child(2){animation-delay:100ms;}
  .drawer.open .mx-group:nth-child(3){animation-delay:140ms;}
  .drawer.open .mx-group:nth-child(4){animation-delay:180ms;}
  .drawer.open .mx-group:nth-child(n+5){animation-delay:200ms;}
}
@keyframes mxIn{from{opacity:0;transform:translateY(10px)}
  to{opacity:1;transform:translateY(0)}}

.mx-group{margin-bottom:18px;}
.mx-group-title{font-size:10px;letter-spacing:0.14em;text-transform:uppercase;color:var(--fg-3);
  padding:0 6px 7px;margin-bottom:8px;border-bottom:1px solid var(--gold-line);}
/* THREE, NOT FOUR, AND THE FIRST VERSION WAS FOUR. The drawer is 290px, so a
   fourth column puts each tile at 64px — and "Transactions" is 66px of one
   unbreakable word at this size, in a language with some of the shortest
   labels here. It was being split as "Transactio / ns". Three columns give the
   tile 87px, which fits every label in all three dictionaries with room left.
   The grid is not the point; being able to read the destination is. */
.mx-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;}

.mx-tile{display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:9px 2px 8px;border-radius:var(--r2);min-height:64px;
  color:var(--fg-2);border:1px solid transparent;
  transition:background .18s,color .18s,border-color .18s;}
.mx-tile:hover{background:var(--bg-2);color:var(--fg);}

/* The tile inside the tile: a dark square with a gold hairline, and the glyph
   in gold on top of it. */
.mx-ic{position:relative;width:44px;height:44px;border-radius:var(--r2);
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(150deg,var(--bg-3),var(--bg-2));
  border:1px solid var(--gold-line);color:var(--gold);
  transition:border-color .18s,box-shadow .18s,background .18s;}
.mx-ic .ic{width:22px;height:22px;stroke-width:1.4;}
/* The second tone is set inside the sprite, not here — see the MENU SET note
   in icons.js. A rule written at this level cannot reach a `<use>` shadow
   tree, and silently matches nothing. */
.mx-tile:hover .mx-ic{border-color:var(--gold);box-shadow:0 0 0 3px var(--gold-glow);}
.mx-tile.active .mx-ic{background:var(--gold-pale);border-color:var(--gold);
  box-shadow:0 0 0 3px var(--gold-glow);color:var(--gold-lt);}

/* NOT CLAMPED, AND THE FIRST VERSION WAS. `-webkit-line-clamp:2` looked right
   in English and cut off all sixteen labels in Persian, where the same
   destinations run to two and three words. A tile is allowed to be as tall as
   its name: the grid stretches the row to match, the tiles in that row stay
   aligned, and no reader is shown a destination they cannot read. */
/* `align-self:stretch` is doing real work. `.mx-tile` centres its children, so
   without it the label sized to its own text and then wrapped inside THAT —
   a 64px tile handing its label a 30px box and breaking "Wallet" across two
   lines with 34px of tile sitting empty either side. */
.mx-label{align-self:stretch;font-size:10.5px;line-height:1.3;text-align:center;
  /* `overflow-wrap`, not `word-break`: this breaks a word only when it cannot
     fit on a line by itself, where `word-break:break-word` broke words that
     would have fitted perfectly well on the next one. */
  overflow-wrap:break-word;}
/* Vazirmatn and IBM Plex Sans Arabic draw well past the Latin line box — at
   1.3 the ink of a two-line label stood 2px outside it. The leading is the
   fix rather than a taller tile: the two scripts need it everywhere they set
   small text, and a label that merely fits is not the same as one that sits. */
html[lang="fa"] .mx-label,html[lang="ar"] .mx-label{line-height:1.55;}
.mx-tile.active .mx-label{color:var(--gold-lt);font-weight:600;}
/* The count rides the corner of the tile rather than the end of a row — there
   is no end of a row here to ride. */
/* ── Language, at the foot of the drawer ──
   THREE SEGMENTS ON THE SAME THREE-COLUMN RHYTHM as `.mx-grid` above it, so the
   row lines up with the tiles and reads as the last entry in one list rather
   than as a control bolted on underneath. Same radius, same border treatment,
   same 180ms as every tile — the only thing that differs is that these are
   values rather than destinations, which is what the filled selected state
   says.

   `.on` IS THE CLASS AND NOT `.active` because `setLang()` already maintains
   `.on` across every `.lang-opt` in the document. Matching the state the shell
   already tracks is what keeps this control and the desktop bar's picker from
   ever disagreeing. */
.mx-lang{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-1);}
.mx-lang-opt{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:3px;min-height:52px;padding:var(--space-2) var(--space-1);border-radius:var(--r2);
  background:var(--bg-2);border:1px solid var(--line-2);color:var(--fg-2);
  transition:background var(--dur-2) var(--ease),color var(--dur-2) var(--ease),
             border-color var(--dur-2) var(--ease),transform var(--dur-1) var(--ease);}
.mx-lang-native{font-size:12.5px;font-weight:600;line-height:1.2;}
.mx-lang-code{font-size:9.5px;letter-spacing:0.12em;color:var(--fg-3);}
.mx-lang-opt.on{background:var(--gold-pale);border-color:var(--gold);color:var(--gold-lt);}
.mx-lang-opt.on .mx-lang-code{color:var(--gold);}
.mx-lang-opt:hover{border-color:var(--gold-line);color:var(--fg);}
/* The press, at --dur-1: felt under the finger rather than watched. Both
   reduced-motion switches already zero every `:active` transform, so this
   needs no guard of its own. */
.mx-lang-opt:active{transform:scale(.96);}

.mx-ic .menu-item-badge{position:absolute;top:-4px;inset-inline-end:-4px;margin:0;
  border:2px solid var(--bg-1);height:18px;min-width:18px;}

/* ── The trigger ──────────────────────────────────────
   Was three lines; is the reader's own initials. Sized to the icon buttons it
   sits beside so the bar's rhythm is unchanged, with the ring picking up the
   gold the menu behind it is drawn in. */
.menu-btn{width:38px;height:38px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;flex-shrink:0;transition:background .18s;}
.menu-btn:hover{background:var(--bg-2);}
.menu-btn-face{width:30px;height:30px;transition:border-color .18s,box-shadow .18s;}
.menu-btn[aria-expanded="true"] .menu-btn-face{border-color:var(--gold);
  box-shadow:0 0 0 3px var(--gold-glow);}


/* ══════════════════════════════════════════════════════
   BOTTOM TAB BAR
   Physical order is identical in every language: Home stays on the far
   left, so the bar itself is forced to LTR while each label keeps the
   document direction for correct shaping.
   ══════════════════════════════════════════════════════ */
.tabbar{position:fixed;inset-inline:0;bottom:0;z-index:71;
  background:rgba(10,12,16,0.96);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);
  border-top:1px solid var(--line-2);padding-bottom:env(safe-area-inset-bottom,0px);
  /* Landscape on a notched phone puts the cutout down one side. */
  padding-inline:env(safe-area-inset-left,0px) env(safe-area-inset-right,0px);}
.tabbar-inner{display:flex;height:var(--tabbar-h);direction:ltr;position:relative;}
.tab-item{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  color:var(--fg-3);position:relative;
  transition:color var(--dur-2) var(--ease),transform var(--dur-1) var(--ease);
  padding:0 2px;}
[dir="rtl"] .tab-lbl{direction:rtl;}

/* ── ONE INDICATOR THAT TRAVELS, NOT FIVE THAT FADE ──
   Each tab used to own a 2px line and light its own. Nothing moved between
   them, so the bar read as five separate lamps rather than as one selection
   moving along a row — which is the thing that makes a tab bar feel like a
   place you are IN rather than a set of links.

   It rides on `--tab-i`, the active index, written by `syncNav()`. The row is
   already `direction:ltr` whatever the shell's language, so an index maps to a
   position identically in English, Arabic and Persian without a second case.

   `translate3d` and `opacity` only: this is a composited move, so it costs a
   GPU quad and never a layout. And it is the ONE place `--ease-spring` is used
   in the shell — an arrival is allowed a single overshoot; nothing a reader is
   waiting on gets one. */
.tab-ind{position:absolute;top:-1px;left:0;height:2px;pointer-events:none;
  width:calc(100% / var(--tab-n, 5));
  transform:translate3d(calc(var(--tab-i, 0) * 100%), 0, 0);
  opacity:0;
  transition:transform var(--dur-3) var(--ease-spring),opacity var(--dur-2) var(--ease);}
.tabbar-inner[data-on="1"] .tab-ind{opacity:1;}
.tab-ind::after{content:'';position:absolute;inset:0 20%;
  background:linear-gradient(90deg,transparent,var(--gold),transparent);}

.tab-item.active{color:var(--gold);}
.tab-item.active .ic{transform:translateY(-1px);}
/* The lit destination sits in its own pool of light. A 1px line says "this
   one"; the glow says it from the corner of the eye, which is how a thumb
   finds a tab without the eye leaving the content. */
.tab-item.active::after{content:'';position:absolute;top:6px;left:50%;
  width:30px;height:30px;margin-left:-15px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,var(--gold-glow) 0%,transparent 70%);}

@media(prefers-reduced-motion:reduce){
  /* The selection still MOVES — it just arrives rather than travels. Removing
     the indicator instead would take information away, which is the one thing
     reduced motion must never do. */
  .tab-ind{transition:opacity var(--dur-1) linear;}
}
.tab-lbl{font-size:9.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;
  line-height:1.3;}
.tab-item .ic{width:21px;height:21px;transition:transform .22s var(--ease);}

/* ══════════════════════════════════════════════════════
   MOVING BETWEEN SCREENS
   ══════════════════════════════════════════════════════
   `navigate()` runs the screen swap inside `document.startViewTransition()`
   where the browser has it. These rules are what that transition looks like;
   without them the browser's default cross-fade applies, which is already
   better than the instant cut but says nothing about direction.

   THE OUTGOING SCREEN LEAVES FASTER THAN THE INCOMING ONE ARRIVES, and it
   leaves by receding rather than by sliding: a tab bar is a set of siblings,
   not a stack, so a horizontal slide would imply an order the five tabs do not
   have. Down-and-back for the old, up-and-forward for the new — the reader
   stays in one place and the content is what changes.

   The shell is excluded by name. A header and a tab bar that cross-faded with
   the content would be the one thing that makes this read as a page load. */
@media(prefers-reduced-motion:no-preference){
  ::view-transition-old(root){
    animation:screenOut var(--dur-2) var(--ease-exit) both;
  }
  ::view-transition-new(root){
    animation:screenIn var(--dur-3) var(--ease) both;
  }
}
@keyframes screenOut{from{opacity:1;transform:scale(1)}
  to{opacity:0;transform:scale(.985)}}
@keyframes screenIn{from{opacity:0;transform:scale(1.008) translateY(6px)}
  to{opacity:1;transform:scale(1) translateY(0)}}

/* The chrome does not travel with the content. Naming these takes them out of
   the root snapshot and leaves them painted, untouched, across the whole
   transition — which is what makes the app feel like one surface with changing
   contents rather than a series of documents. */
.topbar{view-transition-name:zx-topbar;}
.tabbar{view-transition-name:zx-tabbar;}

/* ══════════════════════════════════════════════════════
   LAYOUT
   ══════════════════════════════════════════════════════ */
.body{display:flex;align-items:flex-start;}
.center{flex:1;min-width:0;padding:16px 14px 28px;max-width:100%;}

.screen{display:none;}
/* The router moves focus here on navigation so screen readers land on the new
   screen; that is a programmatic move, so it must not paint a focus ring. */
.screen:focus,.screen:focus-visible{outline:none;}
.screen.active{display:block;animation:screenIn .42s var(--ease) both;}
@keyframes screenIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

.screen-head{margin-bottom:16px;}
.card-eyebrow,.screen-eyebrow{font-size:10.5px;letter-spacing:0.16em;text-transform:uppercase;
  color:var(--gold);display:flex;align-items:center;gap:8px;margin-bottom:7px;font-weight:600;}
.screen-eyebrow::before{content:'';width:18px;height:1px;background:var(--gold-line);}
.screen-title{font-family:var(--f-display);font-weight:700;font-size:24px;letter-spacing:-0.02em;
  line-height:1.25;}
/* ── A TITLE CUT FROM THE HOUSE GOLD ──
   The same gradient the brand wordmark is cut from (`.tb-name`), applied as an
   opt-in modifier rather than to `.screen-title` itself — that class is shared
   by every screen in the product, and gilding all of them would make the gold
   mean nothing.

   `color` is set BEFORE the clip, and that is not belt-and-braces: with
   `-webkit-text-fill-color:transparent` a browser that does not paint the
   gradient renders the heading INVISIBLE. The flat gold underneath is what it
   falls back to. */
.screen-title.gold{
  color:var(--gold-lt);
  background:linear-gradient(120deg,var(--gold-lt),var(--gold));
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
  /* The descender on a "g" or "y" is clipped by the text box on some engines
     when a gradient is painted through it; a hair of padding gives it room. */
  padding-bottom:2px;
}
html[lang="fa"] .screen-title,html[lang="ar"] .screen-title{letter-spacing:0;}
.screen-sub{font-size:13.5px;color:var(--fg-2);margin-top:7px;line-height:1.75;max-width:640px;}

.section-head{display:flex;align-items:center;gap:10px;margin:22px 0 11px;flex-wrap:wrap;}
.section-head h2{font-family:var(--f-display);font-weight:700;font-size:16px;letter-spacing:-0.01em;}
.section-head .link{margin-inline-start:auto;font-size:12px;color:var(--fg-3);display:inline-flex;
  align-items:center;gap:5px;}
.section-head .link:hover{color:var(--gold-lt);}
.section-head .link .ic{width:13px;height:13px;}

/* ── A SECTION HEADING THAT IS ALSO A DOOR ──
   Used once, on AI Market.

   THE FIRST VERSION WAS THE WRONG KIND OF GOLD. It set the word in the display
   face at 800, filled it with a clipped gradient and embossed it — which is a
   perfectly good description of word art. Gold as a FILL on a heading reads as
   cheap however carefully the ramp is mixed, because the expensive thing on a
   dark page is restraint: every other heading in this product is Plus Jakarta
   Sans at 700 in plain `--fg`, and the moment this one stopped matching them it
   stopped looking like part of the same product.

   So the type is now IDENTICAL to `.section-head h2` — same face, same weight,
   same size, same tracking, same colour — and the gold is spent in one place
   only: a hairline rule that starts as a short mark under the first letters and
   runs the width of the word when the pointer arrives. One accent, one
   movement, nothing filled. */
.sec-go-h{line-height:1;}
.sec-go{appearance:none;-webkit-appearance:none;background:none;border:0;padding:0 0 5px;
  margin:0;cursor:pointer;font:inherit;
  display:inline-flex;align-items:center;gap:8px;position:relative;
  font-family:var(--f-display);font-weight:700;font-size:16px;letter-spacing:-0.01em;
  color:var(--fg);transition:color .18s var(--ease);}
/* The rule. `transform:scaleX` rather than `width` so it animates on the
   compositor and cannot reflow the heading beside it. */
.sec-go::after{content:'';position:absolute;inset-inline-start:0;bottom:0;
  height:1px;width:100%;background:var(--gold);
  transform:scaleX(.26);transform-origin:left center;
  transition:transform .34s var(--ease), opacity .2s;opacity:.55;}
[dir="rtl"] .sec-go::after{transform-origin:right center;}
.sec-go:hover{color:var(--gold-lt);}
.sec-go:hover::after{transform:scaleX(1);opacity:1;}
.sec-go .ic{width:14px;height:14px;flex:none;color:var(--fg-3);
  transition:transform .2s var(--ease), color .18s;}
.sec-go:hover .ic{color:var(--gold-lt);transform:translateX(3px);}
[dir="rtl"] .sec-go:hover .ic{transform:scaleX(-1) translateX(3px);}
.sec-go:focus-visible{outline:2px solid var(--gold);outline-offset:4px;border-radius:var(--r1);}

/* ══════════════════════════════════════════════════════
   PRIMITIVES
   ══════════════════════════════════════════════════════ */

/* Card */
.card{background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r3);
  padding:16px;position:relative;margin-bottom:12px;}
.card.gold-top{border-color:var(--gold-line);}
.card.gold-top::before{content:'';position:absolute;top:0;inset-inline:18px;height:1px;
  background:linear-gradient(90deg,transparent,var(--gold),transparent);}
.card-head{display:flex;align-items:center;gap:10px;margin-bottom:14px;}
.card-head h3{font-family:var(--f-display);font-weight:700;font-size:14.5px;letter-spacing:-0.01em;}
.card-head .card-head-right{margin-inline-start:auto;display:flex;align-items:center;gap:8px;}
.lbl{font-size:10.5px;letter-spacing:0.12em;text-transform:uppercase;color:var(--fg-3);}

/* Stat */
.stat-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
.stat{background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r2);padding:12px;}
.stat-lbl{font-size:10px;letter-spacing:0.1em;text-transform:uppercase;color:var(--fg-3);
  margin-bottom:5px;line-height:1.5;}
.stat-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:17px;font-weight:600;
  direction:ltr;line-height:1.3;}
.stat-val.up{color:var(--up);} .stat-val.down{color:var(--down);}
.stat-val.gold{color:var(--gold-lt);} .stat-val.mlc{color:var(--mlc-lt);}
.stat-sub{font-size:11px;color:var(--fg-3);margin-top:3px;}

/* Chip */
.chip{display:inline-flex;align-items:center;gap:5px;font-size:11px;padding:3px 9px;
  border-radius:var(--r1);background:var(--bg-3);border:1px solid var(--line);color:var(--fg-2);
  white-space:nowrap;line-height:1.6;}
.chip .ic{width:12px;height:12px;}
.chip.up{background:var(--up-pale);border-color:var(--up-line);color:var(--up);}
.chip.down{background:var(--down-pale);border-color:var(--down-line);color:var(--down);}
.chip.warn{background:var(--warn-pale);border-color:var(--warn-line);color:var(--warn);}
.chip.info{background:var(--info-pale);border-color:var(--info-line);color:var(--info);}
.chip.gold{background:var(--gold-pale);border-color:var(--gold-line);color:var(--gold-lt);}
.chip.mono{font-family:var(--f-mono);direction:ltr;}

/* Data table */
.dt-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:var(--r2);}
.dt{width:100%;border-collapse:collapse;font-size:12.5px;min-width:540px;}
.dt.dt-sm{min-width:360px;}
.dt th{font-size:10px;letter-spacing:0.1em;text-transform:uppercase;color:var(--fg-3);
  text-align:start;font-weight:500;padding:9px 12px;border-bottom:1px solid var(--line);
  white-space:nowrap;background:var(--bg-1);position:sticky;top:0;}
.dt td{padding:11px 12px;border-bottom:1px solid var(--hair);vertical-align:middle;}
.dt tbody tr:last-child td{border-bottom:none;}
.dt tbody tr:hover{background:var(--bg-2);}
.dt .cell-end{text-align:end;}
.dt .cell-num{font-family:var(--f-mono);font-variant-numeric:tabular-nums;direction:ltr;}
.dt .cell-date{white-space:nowrap;}

/* Sheet — bottom sheet on phones, centred dialog on wide screens */
/* `pointer-events:none` while closed is not a nicety. From 600px the sheet is hidden
   with `opacity:0` and stays centred in the viewport — and an invisible element still
   takes clicks, so a closed sheet was swallowing every press inside a ~540×740 box in
   the middle of the page, whether or not it had ever been opened. */
.sheet{position:fixed;inset-inline:0;bottom:0;z-index:88;
  /* `dvh` so the sheet is measured against the viewport the reader actually
     has, not the tallest one Safari might report with its bars hidden. */
  max-height:86vh;max-height:86dvh;
  background:var(--bg-1);border-top:1px solid var(--line);
  border-radius:var(--r3) var(--r3) 0 0;pointer-events:none;
  transform:translateY(102%);
  transition:transform var(--dur-3) var(--ease);
  display:flex;flex-direction:column;box-shadow:0 -14px 50px rgba(0,0,0,.6);
  /* The home indicator sits inside this surface once it is up. */
  padding-bottom:env(safe-area-inset-bottom,0px);}
/* `--sheet-drag` is written by the pointer handler while a finger is on the
   grip and removed the moment it lifts, so the open position is the resting
   state and the drag is an offset from it rather than a second source of
   truth about where the sheet is. */
.sheet.open{transform:translateY(var(--sheet-drag, 0px));pointer-events:auto;}
/* Under the finger there is no transition — the sheet tracks the finger exactly,
   which is the whole difference between dragging a thing and asking it to move.
   Letting go puts the transition back, so it springs home or leaves. */
.sheet.dragging{transition:none;}
.sheet-grip{touch-action:none;cursor:grab;}
.sheet.dragging .sheet-grip{cursor:grabbing;}
.sheet-head{touch-action:none;}
.sheet-head{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--line-2);}
.sheet-head h3{font-family:var(--f-display);font-weight:700;font-size:15px;}
.sheet-head .icon-btn{margin-inline-start:auto;}
.sheet-body{padding:14px 16px;overflow-y:auto;overscroll-behavior:contain;
  padding-bottom:calc(16px + env(safe-area-inset-bottom,0px));}
.sheet-grip{width:36px;height:4px;border-radius:2px;background:var(--bg-4);margin:8px auto 0;}

/* Empty state */
/* ── Nothing here ──
   THE BORDER IS SOLID NOW, NOT DASHED. A dashed outline is the web's sign for
   a drop target or an unfinished placeholder — it says "something is missing
   from this page", when what is actually true is "this list is empty, which is
   a normal state of a working screen". Solid and quiet says the second thing.

   The component itself is unchanged: `emptyState()` already takes a glyph, a
   title, a sentence, optional chips and an action, which is exactly the three
   things an empty state owes a reader — what is not here, why, and what to do.
   Twenty-five call sites pass those today and none of them needs editing. */
.empty-state{text-align:center;padding:var(--space-6) var(--space-5);
  border:1px solid var(--line-2);
  border-radius:var(--r3);background:var(--bg-1);}
.empty-icon{width:52px;height:52px;border-radius:var(--r3);margin:0 auto 14px;
  background:var(--gold-pale);border:1px solid var(--gold-line);color:var(--gold);
  display:flex;align-items:center;justify-content:center;}
.empty-icon .ic{width:24px;height:24px;}
.empty-title{font-family:var(--f-display);font-weight:700;font-size:15px;margin-bottom:7px;}
.empty-text{font-size:13px;color:var(--fg-3);line-height:1.8;max-width:420px;margin:0 auto;}
.empty-list{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin-top:14px;}
/* The action is the only thing on this screen a reader can act on, so it is the
   only thing given a press of its own. */
.empty-state .btn-ghost{transition:transform var(--dur-1) var(--ease),
  background var(--dur-2) var(--ease);}
.empty-state .btn-ghost:active{transform:scale(.96);}

/* Skeleton */
.skel{background:linear-gradient(90deg,var(--bg-2) 25%,var(--bg-3) 50%,var(--bg-2) 75%);
  background-size:220% 100%;border-radius:var(--r1);animation:skelSlide 1.3s ease-in-out infinite;
  color:transparent !important;}
@keyframes skelSlide{from{background-position:130% 0}to{background-position:-30% 0}}
.skel-line{height:12px;margin-bottom:9px;}
.skel-line.w40{width:40%;} .skel-line.w60{width:60%;} .skel-line.w80{width:80%;}
.skel-block{height:64px;border-radius:var(--r2);}

/* Inline error with retry */
.err-box{display:flex;align-items:center;gap:11px;padding:13px;border-radius:var(--r2);
  background:var(--down-pale);border:1px solid var(--down-line);font-size:12.5px;color:var(--fg-2);}
.err-box .ic{color:var(--down);}
.err-retry{margin-inline-start:auto;font-size:12px;color:var(--down);border:1px solid var(--down-line);
  border-radius:var(--r1);padding:6px 12px;min-height:34px;white-space:nowrap;}
.err-retry:hover{background:var(--down-pale);}

/* Progress ring */
.ring-wrap{position:relative;width:74px;height:74px;flex-shrink:0;}
.ring-wrap svg{transform:rotate(-90deg);display:block;}
.pr-bg{fill:none;stroke:var(--line-2);stroke-width:3;}
/* The gradient stroke is set inline per instance, so each ring carries its
   own <defs> and no cross-SVG id reference is needed. */
.pr-fill{fill:none;stroke:var(--gold);stroke-width:3;stroke-linecap:round;
  stroke-dasharray:207;stroke-dashoffset:207;transition:stroke-dashoffset .8s var(--ease);}
.pr-text{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center;
  width:100%;}
.pr-pct{font-family:var(--f-mono);font-weight:600;font-size:15px;color:var(--gold-lt);direction:ltr;}
.pr-lbl{font-size:9px;color:var(--fg-3);letter-spacing:0.1em;text-transform:uppercase;}

/* Buttons */
.btn-gold{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  background:linear-gradient(145deg,var(--gold-lt),var(--gold) 45%,var(--gold-dp));
  color:var(--on-gold);font-weight:700;font-size:13.5px;padding:13px 22px;border-radius:var(--r1);
  box-shadow:0 6px 22px var(--gold-glow);transition:transform .2s var(--ease),box-shadow .2s;
  position:relative;overflow:hidden;min-height:46px;
}
.btn-gold:hover{transform:translateY(-2px);box-shadow:0 12px 30px var(--gold-glow);}
.btn-gold:active{transform:translateY(0) scale(.985);}
.btn-gold.is-disabled{opacity:.36;pointer-events:none;box-shadow:none;}
.btn-gold.sm{padding:9px 15px;font-size:12.5px;min-height:38px;}
.btn-ghost{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:12px 18px;
  border:1px solid var(--line);border-radius:var(--r1);font-size:13px;color:var(--fg-2);
  transition:all .2s;min-height:44px;background:var(--bg-1);}
.btn-ghost:hover{border-color:var(--gold-line);color:var(--fg);}
.btn-ghost.sm{padding:8px 13px;font-size:12px;min-height:36px;}
/* Same rule as `.btn-gold.is-disabled` — greyed and inert rather than removed,
   so a locked action stays visible where it will sit once it unlocks. */
.btn-ghost.is-disabled{opacity:.4;pointer-events:none;}
.btn-row{display:flex;gap:9px;flex-wrap:wrap;}

/* Toggle switch */
.sw{position:relative;width:42px;height:24px;border-radius:12px;background:var(--bg-4);
  border:1px solid var(--line);flex-shrink:0;transition:background .22s,border-color .22s;}
.sw::after{content:'';position:absolute;top:2px;inset-inline-start:2px;width:18px;height:18px;
  border-radius:50%;background:var(--fg-3);transition:transform .22s var(--ease),background .22s;}
.sw.on{background:var(--gold-pale);border-color:var(--gold-line);}
.sw.on::after{background:var(--gold);transform:translateX(18px);}
[dir="rtl"] .sw.on::after{transform:translateX(-18px);}
.sw-row{display:flex;align-items:center;gap:12px;padding:13px 0;border-bottom:1px solid var(--hair);}
.sw-row:last-child{border-bottom:none;}
.sw-row-text{min-width:0;flex:1;}
.sw-row-title{font-size:13.5px;font-weight:500;}
.sw-row-sub{font-size:11.5px;color:var(--fg-3);margin-top:2px;line-height:1.6;}

/* Risk notices, reused from the activation page */
.risk-notice{background:var(--warn-pale);border:1px solid var(--warn-line);border-radius:var(--r2);
  padding:13px 15px;font-size:12px;color:var(--fg-2);line-height:1.75;}
.risk-notice strong{color:var(--warn);display:flex;align-items:center;gap:7px;margin-bottom:5px;font-weight:600;}
.risk-notice .ic{width:13px;height:13px;}
.risk-disclaimer{background:var(--down-pale);border:1px solid var(--down-line);border-radius:var(--r2);
  padding:12px 14px;font-size:11.5px;color:var(--fg-2);line-height:1.75;}
.risk-disclaimer strong{color:var(--down);display:flex;align-items:center;gap:6px;margin-bottom:5px;font-weight:600;}
.risk-disclaimer .ic{width:13px;height:13px;}

/* ══════════════════════════════════════════════════════
   HOME — greeting and snapshot
   ══════════════════════════════════════════════════════ */
.greet{display:flex;align-items:flex-start;gap:12px;margin-bottom:14px;flex-wrap:wrap;}
.greet-text{min-width:0;flex:1;}
.greet-hi{font-family:var(--f-display);font-weight:700;font-size:20px;letter-spacing:-0.02em;
  line-height:1.3;}
html[lang="fa"] .greet-hi,html[lang="ar"] .greet-hi{letter-spacing:0;}
.greet-date{font-size:12px;color:var(--fg-3);margin-top:3px;}

/* ── Fast start, minimal ──
   Five stars in the greeting row, and deliberately nothing else: no count, no
   label, no chip. The affiliate card carries all of that for the reader who
   went looking for it. This is for the one who did not.

   NO BOX. The affiliate card gives each star a 34px disc with a border and a
   background, which is right inside a panel and wrong at the top of a page —
   five bordered discs beside a greeting read as a control, and this is not one
   to operate, it is a state to notice. Here the glyph is the whole thing. */
/* The slot is a plain flex item on a wide screen and a full-width one on a
   phone, which is the whole of the responsive behaviour. */
.fs-slot{display:inline-flex;}

.fs-mini{display:inline-flex;align-items:center;gap:5px;
  padding:5px 8px;border-radius:999px;
  text-decoration:none;line-height:0;
  border:1px solid transparent;background:transparent;
  transition:background .18s,border-color .18s;}
.fs-mini:hover,.fs-mini:focus-visible{background:var(--bg-2);border-color:var(--hair);}
.fs-mini:focus-visible{outline:2px solid var(--gold);outline-offset:2px;}

.fs-mini-star .ic{width:15px;height:15px;display:block;}

/* OFF is the resting state and most of what is on screen, so it is quiet:
   the outline of a star, not a grey star. A filled grey glyph beside a filled
   gold one reads as two kinds of earned. */
.fs-mini-star .ic{fill:none;stroke:var(--fg-4,var(--fg-3));stroke-width:1.6;
  stroke-linejoin:round;opacity:.45;}

/* ON is filled and gold, with a glow small enough to be felt rather than seen.
   `drop-shadow` rather than `box-shadow` so the halo follows the star's points
   instead of boxing them. */
.fs-mini-star.on .ic{fill:var(--gold);stroke:var(--gold);opacity:1;
  filter:drop-shadow(0 0 5px rgba(232,182,71,.45));}

/* Lit left to right on first paint — the order they were earned in. */
.fs-mini-star.on{animation:fsMiniLight .42s cubic-bezier(.2,.9,.3,1.4) both;}
@keyframes fsMiniLight{
  from{opacity:0;transform:scale(.55) rotate(-18deg);}
  to  {opacity:1;transform:none;}
}

/* All five. One slow breath, not a celebration that repeats forever in the
   corner of a page somebody is trying to read. */
.fs-mini.done .fs-mini-star.on .ic{
  filter:drop-shadow(0 0 7px rgba(232,182,71,.6));}

@media(prefers-reduced-motion:reduce){
  .fs-mini-star.on{animation:none;}
}

/* On a phone the greeting takes the row and this wraps under it with the
   engine pill. Slightly smaller, and the tap target comes from the padding
   rather than from making the glyphs bigger. */
/* ON A PHONE IT TAKES ITS OWN LINE, and that is not a preference.
   The greeting is the page's first sentence and there is not room for it
   beside five stars AND the engine pill at 390px — measured, not assumed:
   adding this row broke "Good evening, Sam" onto two lines. The slot drops
   below, the pill stays exactly where it was, and the greeting is one line
   again. */
@media(max-width:600px){
  .fs-slot{order:3;flex:0 0 100%;margin-top:-2px;}
  .fs-mini{padding:5px 7px;gap:4px;margin-inline-start:-7px;}
  .fs-mini-star .ic{width:14px;height:14px;}
}


.snapshot{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r2);
  padding:11px 14px;margin-bottom:12px;}
.snap-item{display:flex;flex-direction:column;gap:1px;min-width:0;}
.snap-lbl{font-size:10px;color:var(--fg-3);}
.snap-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:13.5px;
  font-weight:600;direction:ltr;}
.snap-val.up{color:var(--up);} .snap-val.down{color:var(--down);}
.snap-sep{width:1px;height:26px;background:var(--line-2);}
.milo-ticker{margin-inline-start:auto;display:flex;align-items:center;gap:9px;font-size:11.5px;
  color:var(--fg-3);min-width:0;}
.milo-ticker .ic{width:14px;height:14px;color:var(--gold);flex-shrink:0;}
.milo-ticker b{font-family:var(--f-mono);color:var(--gold-lt);font-weight:600;direction:ltr;}
.milo-wave{display:inline-flex;align-items:flex-end;gap:2px;height:12px;}
.milo-wave i{width:2px;background:var(--gold);border-radius:1px;animation:wave 1.1s ease-in-out infinite;}
.milo-wave i:nth-child(1){height:5px;animation-delay:0s}
.milo-wave i:nth-child(2){height:10px;animation-delay:.13s}
.milo-wave i:nth-child(3){height:7px;animation-delay:.26s}
.milo-wave i:nth-child(4){height:12px;animation-delay:.39s}
@keyframes wave{0%,100%{transform:scaleY(.45)}50%{transform:scaleY(1)}}

/* ══ HOME — portfolio hero ══ */
.hero-total{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;margin-bottom:4px;}
.hero-amount{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:34px;
  font-weight:600;letter-spacing:-0.02em;direction:ltr;line-height:1.1;}
.hero-sub{font-size:11.5px;color:var(--fg-3);margin-bottom:16px;}
.hero-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-bottom:12px;}
.coin-chips{display:grid;grid-template-columns:1fr 1fr;gap:9px;}
.coin-chip{display:flex;align-items:center;gap:10px;padding:11px 12px;border-radius:var(--r2);
  border:1px solid var(--line-2);background:var(--bg-2);}
.coin-chip.zc{border-color:var(--gold-line);background:var(--gold-pale);}
.coin-chip.mlc{border-color:var(--mlc-line);background:var(--mlc-pale);}
.coin-badge{width:30px;height:30px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;
  justify-content:center;font-family:var(--f-display);font-weight:700;font-size:10.5px;
  color:var(--on-gold);}
.coin-chip.zc .coin-badge{background:linear-gradient(145deg,var(--gold-lt),var(--gold-dp));}
.coin-chip.mlc .coin-badge{background:linear-gradient(145deg,var(--mlc-lt),var(--mlc-dp));}
/* MILO is four characters where ZED is three, and the badge is a circle: at the
   shared size the M and the O sit on the rim. The type scales to the label
   rather than the circle growing, so the two coins stay the same token. */
.coin-chip.mlc .coin-badge{font-size:9px;letter-spacing:-0.01em;}
.coin-text{min-width:0;}
.coin-name{font-size:11px;color:var(--fg-3);}
/* What the coin is for, said on the chip: one withdraws, the other transfers. */
.coin-role{font-size:10.5px;color:var(--fg-3);line-height:1.5;}
.coin-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:14.5px;
  font-weight:600;direction:ltr;}
.coin-chip.zc .coin-val{color:var(--gold-lt);}
.coin-chip.mlc .coin-val{color:var(--mlc-lt);}

/* ══ HOME — contract clock ══ */
.cc-top{display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
.cc-ring-side{display:flex;flex-direction:column;align-items:center;gap:7px;}
.cc-countdown{font-size:11px;color:var(--fg-3);white-space:nowrap;}
.cc-facts{flex:1;min-width:180px;display:grid;grid-template-columns:1fr 1fr;gap:10px 14px;}
.cc-fact{min-width:0;}
.cc-lbl{font-size:9.5px;letter-spacing:0.1em;text-transform:uppercase;color:var(--fg-3);
  line-height:1.5;}
.cc-val{font-size:13px;font-weight:600;margin-top:1px;}
.cc-val.mono{font-family:var(--f-mono);font-variant-numeric:tabular-nums;direction:ltr;}
.cc-val.gold{color:var(--gold-lt);}
.tier-badge{display:inline-flex;align-items:center;gap:6px;font-family:var(--f-display);
  font-weight:700;font-size:13px;padding:4px 11px;border-radius:var(--r1);
  color:var(--tier);border:1px solid var(--tier);background:rgba(255,255,255,.03);}
.tier-badge.silver{--tier:var(--tier-silver);}
.tier-badge.gold{--tier:var(--tier-gold);}
.tier-badge.platinum{--tier:var(--tier-platinum);}
.tier-badge.black{--tier:var(--tier-black);}

/* What a contract is doing, when it is not simply running. Sits beside the tier
   badge and borrows its shape, so the card gains a fact rather than a new
   language. A running contract shows nothing here — the absence is the normal
   case, and a chip that always says something is a chip nobody reads. */
.ct-state{display:inline-flex;align-items:center;font-family:var(--f-display);
  font-weight:700;font-size:11px;letter-spacing:.06em;text-transform:uppercase;
  padding:4px 9px;border-radius:var(--r1);margin-inline-end:8px;
  color:var(--warn);border:1px solid var(--warn-line);background:var(--warn-pale);}
.ct-state.matured{color:var(--up);border-color:var(--up-line);background:var(--up-pale);}
.ct-state.suspended{color:var(--down);border-color:var(--down-line);background:var(--down-pale);}
.cc-frozen-note{margin-top:10px;font-size:12px;line-height:1.65;color:var(--fg-3);
  border-inline-start:2px solid var(--warn-line);padding-inline-start:10px;}

/* 24-month strip */
.month-strip{display:grid;grid-template-columns:repeat(12,1fr);gap:3px;margin-top:16px;direction:ltr;}
.ms-cell{height:16px;border-radius:2px;background:var(--bg-3);border:1px solid var(--line-2);
  position:relative;}
.ms-cell.past{background:linear-gradient(180deg,var(--gold),var(--gold-dp));border-color:var(--gold-dp);}
.ms-cell.now{background:var(--gold-pale);border-color:var(--gold);animation:pulse 2s infinite;}
.ms-legend{display:flex;gap:14px;flex-wrap:wrap;margin-top:9px;font-size:10.5px;color:var(--fg-3);}
.ms-key{display:inline-flex;align-items:center;gap:6px;}
.ms-swatch{width:10px;height:10px;border-radius:2px;border:1px solid var(--line-2);background:var(--bg-3);}
.ms-swatch.past{background:var(--gold);border-color:var(--gold-dp);}
.ms-swatch.now{background:var(--gold-pale);border-color:var(--gold);}

/* Renewal state */
.cc-renew{margin-top:15px;padding:13px;border-radius:var(--r2);background:var(--gold-pale);
  border:1px solid var(--gold-line);}
.cc-renew-title{font-family:var(--f-display);font-weight:700;font-size:13.5px;color:var(--gold-lt);
  margin-bottom:5px;}
.cc-renew-text{font-size:12px;color:var(--fg-2);line-height:1.7;margin-bottom:11px;}

/* The clock on one side, what to do next on the other. Below 900px the column
   drops under the clock rather than squeezing both. */
.cc-cols{display:flex;gap:16px;align-items:stretch;flex-wrap:wrap;}
.cc-main{flex:1 1 340px;min-width:0;}
.cc-side{flex:0 0 100%;display:flex;flex-direction:column;gap:9px;justify-content:center;
  padding-top:4px;}
@media(min-width:900px){
  .cc-side{flex:0 0 210px;border-inline-start:1px solid var(--line-2);padding-inline-start:16px;}
}
.cc-side-figs{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:6px;}
@media(min-width:900px){.cc-side-figs{grid-template-columns:1fr;}}
.cc-side .btn-gold,.cc-side .btn-ghost{width:100%;justify-content:center;}

/* ── Your contract, read at arm's length ──
   The card carries the one number a client checks daily — which month of 24
   they are in — so it is set larger than the rest of the page rather than at
   the same size as a market row. Scoped to the card so the ring, the facts and
   the month strip keep their compact sizes everywhere else they appear. */
#cardContract .card-head h3{font-size:18.5px;}
#cardContract .tier-badge{font-size:15px;padding:5px 13px;}
#cardContract .ring-wrap{width:96px;height:96px;}
#cardContract .ring-wrap svg{width:100%;height:100%;}
#cardContract .pr-pct{font-size:20px;}
#cardContract .pr-lbl{font-size:10.5px;}
#cardContract .cc-countdown{font-size:13px;}
#cardContract .cc-lbl{font-size:11px;}
#cardContract .cc-val{font-size:17px;margin-top:3px;}
#cardContract .cc-facts{gap:14px 18px;}
#cardContract .ms-cell{height:20px;}
#cardContract .ms-legend{font-size:12px;gap:16px;}
#cardContract .ms-swatch{width:12px;height:12px;}
#cardContract .cc-renew-title{font-size:15px;}
#cardContract .cc-renew-text{font-size:13px;}
@media(max-width:479px){
  /* A phone has no room for the full step up, but the ratio is kept. */
  #cardContract .card-head h3{font-size:16px;}
  #cardContract .cc-val{font-size:15px;}
  #cardContract .ring-wrap{width:84px;height:84px;}
}

/* ══ NEW CONTRACT — the signing step ══
   The agreement, the confirmations and the signature, worn by the second step
   of #/newcontract. The class names are deliberately the same ones the
   activation terminal uses for the first contract, so the two places a contract
   is signed look alike — and so the material layer, which already lights
   `.agreement-box`, `.sig-box` and the signature canvas, reaches both without
   a second set of rules. */
.agr-meta{font-size:11px;color:var(--fg-3);margin-bottom:10px;}
.agr-defs{margin:6px 0;}
.agr-defs dt{font-weight:600;color:var(--fg);margin-top:7px;}
.agr-defs dd{margin:0 0 0 14px;}
[dir="rtl"] .agr-defs dd{margin:0 14px 0 0;}
.agr-cl{margin:5px 0;}
.agr-cl b{color:var(--fg-3);font-weight:600;font-family:var(--f-mono);font-size:11.5px;}
.agr-list{margin:6px 0 6px 20px;padding:0;}
[dir="rtl"] .agr-list{margin:6px 20px 6px 0;}
.agr-list li{margin:3px 0;}
/* The executed block: name and date are filled in, never a blank rule. */
.agr-sign{display:grid;gap:10px;margin-top:18px;padding-top:14px;
  border-top:1px solid var(--line);}
.agr-sign div{display:flex;justify-content:space-between;gap:14px;align-items:baseline;}
.agr-sign span{font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--fg-3);}
html[lang="fa"] .agr-sign span,html[lang="ar"] .agr-sign span{letter-spacing:0;text-transform:none;}
.agr-sign b{font-family:var(--f-display);font-size:14px;color:var(--fg);}
.agr-sign .agr-sig-name{color:var(--gold-lt);font-size:17px;}

/* How far through the document the reader actually is. */
.agr-count{font-size:11px;color:var(--fg-3);font-variant-numeric:tabular-nums;}
.agr-progress{display:flex;align-items:center;gap:10px;margin-top:10px;}
.agr-progress-track{flex:1;height:4px;border-radius:2px;background:var(--bg-0);overflow:hidden;}
.agr-progress-track span{display:block;height:100%;width:0;border-radius:2px;
  background:linear-gradient(90deg,var(--gold-dp),var(--gold));transition:width .15s linear;}
.agr-progress-lbl{font-size:11px;color:var(--fg-3);white-space:nowrap;}
.agr-jump{font-size:11px;color:var(--gold);padding:3px 8px;border-radius:var(--r1);
  white-space:nowrap;transition:background .15s,color .15s;}
.agr-jump:hover{background:var(--gold-pale);color:var(--gold-lt);}
.agr-progress.done .agr-progress-track span{background:var(--up);}
.agr-progress.done .agr-progress-lbl{color:var(--up);}

/* Which clause a tick is actually accepting. */
.check-ref{display:block;font-size:10.5px;color:var(--fg-3);margin-top:3px;}
.check-row.on .check-text{color:var(--fg);}

.agreement-box{max-height:320px;overflow-y:auto;background:var(--bg-0);
  border:1px solid var(--line-2);border-radius:var(--r2);padding:14px 15px;
  font-size:12.5px;line-height:1.75;color:var(--fg-2);}
.agreement-box .doc-title{display:block;font-family:var(--f-display);font-weight:700;
  font-size:14px;color:var(--fg);margin-bottom:8px;}
.agreement-box h4{font-family:var(--f-display);font-size:12.5px;font-weight:700;
  color:var(--fg);margin:13px 0 4px;}
.agreement-box p{margin:0;}

.check-row{display:flex;align-items:flex-start;gap:11px;padding:9px 0;}
.custom-check{width:21px;height:21px;flex-shrink:0;margin-top:1px;border-radius:6px;
  border:1px solid var(--line);background:var(--bg-0);display:flex;align-items:center;
  justify-content:center;color:transparent;
  transition:background .18s,border-color .18s,color .18s,transform .15s var(--ease);}
.custom-check .ic{width:13px;height:13px;stroke-width:2.8;}
.custom-check:hover{border-color:var(--gold-line);}
.custom-check.checked{background:var(--gold-pale);border-color:var(--gold);color:var(--gold);}
.custom-check:focus-visible{outline:2px solid var(--gold);outline-offset:2px;}
.check-text{font-size:12.5px;line-height:1.65;color:var(--fg-2);}

.sig-area{display:grid;grid-template-columns:1fr;gap:11px;}
@media(min-width:600px){ .sig-area{grid-template-columns:1fr 1fr;} }
.sig-box{background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r2);
  padding:12px 13px;position:relative;min-width:0;}
.sig-box-title{display:block;font-size:10.5px;letter-spacing:0.1em;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:8px;}
html[lang="fa"] .sig-box-title,html[lang="ar"] .sig-box-title{letter-spacing:0;text-transform:none;font-size:11.5px;}
/* A signature is written, so the field is a ruled line rather than a box. */
.sig-input{width:100%;background:none;border:none;border-bottom:1px solid var(--line);
  padding:6px 2px;color:var(--gold-lt);font-family:var(--f-display);font-size:19px;
  font-weight:600;outline:none;min-height:40px;transition:border-color .18s;}
.sig-input:focus{border-bottom-color:var(--gold);}
.sig-stamp{font-size:10.5px;color:var(--fg-3);margin-top:7px;min-height:15px;
  direction:ltr;unicode-bidi:isolate;word-break:break-word;}
#ncSigCanvas{width:100%;height:108px;display:block;border-radius:var(--r2);
  background:var(--bg-0);border:1px solid var(--line-2);touch-action:none;cursor:crosshair;}
.sig-clear{position:absolute;top:10px;inset-inline-end:11px;display:inline-flex;
  align-items:center;gap:5px;font-size:11px;color:var(--fg-3);padding:4px 8px;
  border-radius:var(--r1);transition:color .18s,background .18s;}
.sig-clear:hover{color:var(--gold-lt);background:var(--gold-pale);}
.sig-clear .ic{width:12px;height:12px;}

/* ══ HOME — completion checklist ══ */
.chk-top{display:flex;align-items:center;gap:14px;margin-bottom:12px;}
.chk-top-text{min-width:0;flex:1;}
.chk-title{font-family:var(--f-display);font-weight:700;font-size:14.5px;}
.chk-sub{font-size:12px;color:var(--fg-3);margin-top:3px;line-height:1.6;}
.chk-list{display:flex;flex-direction:column;}
.chk-item{display:flex;align-items:center;gap:11px;width:100%;padding:11px 2px;text-align:start;
  border-bottom:1px solid var(--hair);min-height:46px;transition:opacity .2s;}
.chk-item:last-child{border-bottom:none;}
.chk-box{width:21px;height:21px;border-radius:50%;flex-shrink:0;border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;color:transparent;}
.chk-item.done .chk-box{background:var(--up-pale);border-color:var(--up-line);color:var(--up);}
.chk-box .ic{width:12px;height:12px;stroke-width:2.6;}
.chk-text{flex:1;min-width:0;}
.chk-name{font-size:13px;font-weight:500;}
.chk-item.done .chk-name{color:var(--fg-3);font-weight:400;}
.chk-hint{font-size:11px;color:var(--fg-3);margin-top:1px;line-height:1.5;}
.chk-item.done .chk-hint{display:none;}
.chk-go{color:var(--fg-3);flex-shrink:0;}
.chk-item:hover .chk-go{color:var(--gold-lt);}
.chk-item.done .chk-go{display:none;}

/* ══ HOME — equity chart ══ */
.chart-box{position:relative;}
.chart{display:block;width:100%;height:auto;overflow:visible;}
.chart-grid{stroke:var(--hair);stroke-width:1;}
.chart-fill{fill:url(#eqFill);}
.chart-line{fill:none;stroke:var(--gold);stroke-width:2;stroke-linejoin:round;stroke-linecap:round;}
.chart-proj{fill:none;stroke:var(--gold-dp);stroke-width:1.6;stroke-dasharray:4 4;opacity:.75;}
.chart-dot{fill:var(--bg-0);stroke:var(--gold);stroke-width:2;}
.chart-axis{font-family:var(--f-mono);font-size:10px;fill:var(--fg-3);direction:ltr;}
.chart-legend{display:flex;gap:14px;flex-wrap:wrap;margin-top:10px;font-size:10.5px;color:var(--fg-3);}
.chart-key{display:inline-flex;align-items:center;gap:6px;}
.chart-key i{width:14px;height:2px;background:var(--gold);border-radius:1px;}
.chart-key.proj i{background:repeating-linear-gradient(90deg,var(--gold-dp) 0 4px,transparent 4px 7px);}
.range-tabs{display:flex;gap:4px;background:var(--bg-2);border:1px solid var(--line-2);
  border-radius:var(--r1);padding:2px;}
.range-tab{padding:5px 10px;border-radius:2px;font-family:var(--f-mono);font-size:10.5px;
  color:var(--fg-3);min-height:28px;direction:ltr;}
.range-tab.active{background:var(--gold-pale);color:var(--gold-lt);}

/* ══ HOME — signals ══ */
.sig-list{display:flex;flex-direction:column;gap:8px;}
/* ── ONE GEOMETRY FOR EVERY ROW ──
   The third column was `auto`, so it sized itself to whatever the result
   happened to be: `+1.33%` is narrower than `-2.11%`, which left the middle
   column a different width on every row — and on the wide ones the price pair
   ran out of room and wrapped onto a second line. Three rows were one height
   and two were another, in a list whose whole job is to be scanned.

   A fixed track fixes all of it at once. 78px holds `-12.34%` and the status
   chip under it at every supported size, and `minmax` lets it grow rather than
   clip if a language ever needs more.

   (`flex-shrink` on `.sig-end` had never done anything: this is a grid.) */
.sig{display:grid;grid-template-columns:auto 1fr minmax(78px, max-content);gap:10px;align-items:center;
  width:100%;padding:12px;border-radius:var(--r2);background:var(--bg-1);
  border:1px solid var(--line-2);text-align:start;transition:all .2s;}
.sig:hover{border-color:var(--line);background:var(--bg-2);}
.sig-side{width:44px;height:44px;border-radius:var(--r2);display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:1px;flex-shrink:0;font-size:8.5px;
  letter-spacing:0.06em;text-transform:uppercase;font-weight:600;}
.sig-side.long{background:var(--up-pale);border:1px solid var(--up-line);color:var(--up);}
.sig-side.short{background:var(--down-pale);border:1px solid var(--down-line);color:var(--down);}
.sig-side .ic{width:15px;height:15px;}
.sig-mid{min-width:0;}
.sig-sym{font-family:var(--f-mono);font-size:13.5px;font-weight:600;direction:ltr;
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
/* ── THE MARK ON A SIGNAL ──
   `.sig-sym` and `.sigc-id` were already flex rows with a gap, so the mark
   goes in as a first child and nothing else moves. Three sizes because three
   surfaces: a list row, the card somebody forwards, and a history table where
   the cell also carries the market's name.

   SMALLER THAN A WATCHLIST MARK ON PURPOSE. A signal row already leads with a
   44px LONG/SHORT block, which is the thing to read first; a mark at the
   watchlist's 22px would compete with it. */
.sig-sym .cix{width:18px;height:18px;}
/* NEVER TWO LINES. A pair of eight-digit prices is wider than the column on a
   small phone, and wrapping it is what made the BTC rows taller than the rest.
   Tabular figures so the arrows line up down the list, and an ellipsis so the
   overflow case is a clipped price rather than a taller card. */
.sig-prices{font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  font-size:11px;color:var(--fg-3);direction:ltr;margin-top:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.sig-meta{font-size:10.5px;color:var(--fg-3);margin-top:3px;display:flex;gap:9px;flex-wrap:wrap;}
.sig-end{display:flex;flex-direction:column;align-items:flex-end;gap:4px;
  text-align:end;direction:ltr;}
.sig-res{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:15px;font-weight:600;
  direction:ltr;}
.sig-res.up{color:var(--up);} .sig-res.down{color:var(--down);}
.sig-stat{margin-top:0;}
/* The strip over the signal list: six figures where three chips used to sit with
   air between them. Same anatomy as Home's snapshot, so the two read alike. */
.sig-strip{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:11px;
  padding:11px 14px;border-radius:var(--r2);background:var(--bg-1);
  border:1px solid var(--line-2);}
.sig-fig{display:flex;flex-direction:column;gap:1px;min-width:0;}
.sig-figl{font-size:10px;color:var(--fg-3);}
.sig-figv{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:13.5px;
  font-weight:600;direction:ltr;}
.sig-figv.up{color:var(--up);} .sig-figv.down{color:var(--down);}
@media(max-width:479px){
  .sig-strip{gap:12px;}
  .sig-strip .snap-sep{display:none;}
}

/* Signal detail sheet rows */
.kv{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;
  border-bottom:1px solid var(--hair);font-size:12.5px;}
.kv:last-child{border-bottom:none;}
.kv-k{color:var(--fg-3);}
.kv-v{font-family:var(--f-mono);font-variant-numeric:tabular-nums;direction:ltr;text-align:end;}
.kv-v.up{color:var(--up);} .kv-v.down{color:var(--down);} .kv-v.gold{color:var(--gold-lt);}

/* ══ HOME — market ══ */
.mkt-scroll{display:flex;gap:9px;overflow-x:auto;-webkit-overflow-scrolling:touch;
  padding-bottom:4px;scroll-snap-type:x proximity;}
/* ── THE CARD IS A COLUMN, AND IT HAD NEVER BEEN TOLD SO ──
   `.mkt-name`, `.mkt-price` and `.mkt-chg` are `<span>`s with no display of
   their own, so they were INLINE — and `margin-top` does nothing to an inline
   box. All three ran together on one line: "Metals4,373.20+0.08%", with the
   class name welded to the price and the price welded to the change. Only
   `.mkt-sym` broke the line, and only because it happens to be `display:flex`.

   Laying the card out as a flex column is the fix and is also the chance to
   give it a hierarchy it never had: the price is the thing a reader came for,
   so it is the largest thing on the card, and the change sits on its baseline
   rather than under it — the way a price and its delta are read everywhere
   else in this product. */
.mkt-card{flex:0 0 152px;scroll-snap-align:start;padding:12px;border-radius:var(--r2);
  background:var(--bg-1);border:1px solid var(--line-2);text-align:start;
  display:flex;flex-direction:column;
  transition:border-color var(--dur-2) var(--ease),background var(--dur-2) var(--ease),
             transform var(--dur-1) var(--ease);}
.mkt-card:hover{border-color:var(--gold-line);}
.mkt-card:active{transform:scale(.985);}
.mkt-sym{font-family:var(--f-mono);font-size:12.5px;font-weight:600;direction:ltr;
  display:flex;align-items:center;gap:6px;}
.mkt-name{display:block;font-size:10px;letter-spacing:0.07em;text-transform:uppercase;
  color:var(--fg-3);margin-top:2px;}

/* The price and its change share a baseline. `align-items:baseline` is what
   keeps a 17px figure and an 11px percentage sitting on the same line rather
   than centred against each other, which is the detail that makes a row of
   these read as one price each. */
.mkt-price{display:block;font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  font-size:17px;font-weight:600;line-height:1.15;direction:ltr;
  margin-top:var(--space-2);transition:color .5s;}
.mkt-price.tick-up{color:var(--up);} .mkt-price.tick-down{color:var(--down);}
.mkt-chg{display:block;font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  font-size:11px;direction:ltr;margin-top:3px;}
.mkt-chg.up{color:var(--up);} .mkt-chg.down{color:var(--down);}
.spark{display:block;margin-top:8px;width:100%;height:26px;overflow:visible;}
.spark path{fill:none;stroke-width:1.6;stroke-linejoin:round;stroke-linecap:round;}
.spark.up path{stroke:var(--up);} .spark.down path{stroke:var(--down);}
.mkt-signal-dot{width:6px;height:6px;border-radius:50%;background:var(--gold);
  box-shadow:0 0 8px var(--gold-glow);flex-shrink:0;}
.mkt-table-wrap{display:none;}

/* The card carries what the table's extra columns carry, so a phone is not shown
   less than a laptop. */
.mkt-figs{display:grid;grid-template-columns:1fr 1fr;gap:5px 8px;margin-top:9px;
  padding-top:8px;border-top:1px solid var(--line-2);}
.mkt-fig{display:flex;flex-direction:column;gap:1px;min-width:0;}
.mkt-fig i{font-style:normal;font-size:9.5px;color:var(--fg-3);}
.mkt-fig b{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:11px;
  font-weight:600;direction:ltr;unicode-bidi:isolate;}
/* A FIGURE THAT DOES NOT EXIST SHOULD LOOK LIKE ONE. Gold has no market cap and
   the feed carries no 7d or 30d for it yet, so three of this card's four slots
   are an em dash — and at full strength three dashes read as a card that failed
   to load rather than as three figures that do not apply. The slot stays, so
   every card has the same anatomy and the columns line up down the row; it just
   stops shouting. */
.mkt-fig b[data-none="1"]{color:var(--fg-3);opacity:.55;font-weight:500;}
.mkt-fig b.up{color:var(--up);} .mkt-fig b.down{color:var(--down);}
.mkt-card{flex:0 0 176px;}

/* ── The market table ──
   Eight columns fit because the figures are narrow and the header does the
   explaining. A sortable header is a button so the keyboard can reach it, and the
   caret says which way the column is pointing. */
.th-sort{display:inline-flex;align-items:center;gap:5px;font:inherit;color:inherit;
  padding:2px 0;border-radius:var(--r1);transition:color .18s;}
.th-sort:hover{color:var(--gold-lt);}
.th-sort.on{color:var(--gold-lt);}
/* Faintly visible at rest: a column nobody knows is sortable might as well not
   be. It brightens on hover and stays lit on the column in force. */
.th-caret{font-style:normal;font-size:8px;opacity:.3;transition:opacity .18s;}
.th-sort:hover .th-caret{opacity:.7;}
.th-sort.on .th-caret{opacity:1;}
.dt-mkt{min-width:840px;}
.dt-mkt th:first-child,.dt-mkt td:first-child{min-width:104px;}
.dt-mkt .cell-num{white-space:nowrap;}
/* A figure that does not exist for this instrument: present, quiet, not a zero. */
.cell-none{color:var(--fg-3);opacity:.7;}
.mkt-trend-cell{width:120px;}
.dt-mkt .spark{margin-top:0;height:22px;}

/* ══ Rail panels (shared with the activation page's right rail) ══ */
.rp-title{font-size:10.5px;letter-spacing:0.14em;text-transform:uppercase;color:var(--fg-3);margin-bottom:8px;}
.rp-row{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:7px 0;
  border-bottom:1px solid var(--hair);}
.rp-row:last-child{border-bottom:none;}
.rp-row-label{font-size:11.5px;color:var(--fg-3);display:flex;align-items:center;gap:7px;}
.rp-row-label .ic{width:13px;height:13px;}
.rp-row-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:11.5px;
  font-weight:500;direction:ltr;}
.rp-row-val.gold{color:var(--gold-lt);} .rp-row-val.green{color:var(--up);}
.rp-row-val.red{color:var(--down);}


/* ══════════════════════════════════════════════════════
   NOTIFICATIONS
   ══════════════════════════════════════════════════════ */
/* A SHADE THAT COMES DOWN FROM THE TOP BAR.
   It was a small floating card: it hung under the top bar, stopped somewhere
   in the middle of the screen, and left three hundred pixels of fully lit page
   underneath it competing for the eye. It read as unfinished — and it was the
   missing backdrop and the loose edge that did that, NOT the direction.

   THE DIRECTION IS RIGHT AND IT IS DELIBERATE. Notifications come down from
   the top on both phone platforms — the iOS Notification Center and the
   Android shade are both a downward pull from the top edge — and the bell that
   opens this sits up there too, so the surface appears where the finger was.
   A bottom sheet is the idiom for an ACTION: a confirmation, a picker, a form.
   `.sheet` in this file is exactly that and stays where it is. Reading a list
   of things that happened is not an action, and moving it to the opposite edge
   would put it a screen away from the control that opens it.

   What was actually wrong is fixed instead: it now spans the full width, its
   bottom edge is rounded so it reads as a surface rather than a cut, it is
   backed by a scrim so the page behind it is behind it, and it can be pushed
   back up with the same gesture that pulled it down. */
.notif-panel{position:fixed;inset-inline:0;top:var(--topbar-h);bottom:auto;z-index:88;
  background:var(--bg-1);border-bottom:1px solid var(--line);
  border-radius:0 0 var(--r3) var(--r3);
  box-shadow:0 18px 50px rgba(0,0,0,.6);
  display:flex;flex-direction:column;
  max-height:min(78vh,640px);overflow:hidden;
  /* OUT OF SIGHT ABOVE THE BAR — its own height AND the offset it starts at.
     `translateY(-102%)` alone clears only the height, and this panel begins
     56px down the page, so 46px of it stayed on screen: the grip and the last
     line of the oldest notification sat over the top bar in every state but
     open. The bottom-sheet version did not have this because `bottom:0` put
     the offset at zero in the direction it travelled.

     The clearance is 80px and not 12: `box-shadow: 0 18px 50px` paints up to
     68px BELOW the panel's own edge, and a shadow from an off-screen element
     is still drawn. Twelve pixels hid the panel and left its shadow lying
     across the top bar. */
  transform:translateY(calc(-100% - var(--topbar-h) - 80px));pointer-events:none;
  transition:transform .32s var(--ease);}
.notif-panel.open{transform:translateY(0);pointer-events:auto;}

/* The grip sits at the BOTTOM here, because that is the edge the finger
   reaches for and the direction the surface travels. A grip at the top of a
   shade that came from the top would point back at the bar it emerged from. */
.notif-grip{width:36px;height:4px;border-radius:2px;background:var(--bg-4);
  margin:2px auto 8px;flex:none;order:99;}
.notif-head{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line-2);}
.notif-head h3{font-family:var(--f-display);font-weight:700;font-size:14px;}
.notif-mark{margin-inline-start:auto;font-size:11.5px;color:var(--fg-3);padding:6px 8px;}
.notif-mark:hover{color:var(--gold-lt);}
.notif-list{overflow-y:auto;overscroll-behavior:contain;padding:6px;}
.notif-item{display:flex;gap:11px;align-items:flex-start;width:100%;padding:11px;text-align:start;
  border-radius:var(--r2);transition:background .18s;position:relative;}
.notif-item:hover{background:var(--bg-2);}
.notif-item.unread{background:var(--bg-2);}
.notif-icon{width:32px;height:32px;border-radius:var(--r2);flex-shrink:0;display:flex;
  align-items:center;justify-content:center;background:var(--bg-3);border:1px solid var(--line);
  color:var(--fg-2);}
.notif-icon.signal{background:var(--gold-pale);border-color:var(--gold-line);color:var(--gold);}
.notif-icon.deposit,.notif-icon.contract{background:var(--up-pale);border-color:var(--up-line);color:var(--up);}
.notif-icon.withdrawal{background:var(--info-pale);border-color:var(--info-line);color:var(--info);}
.notif-icon.kyc{background:var(--warn-pale);border-color:var(--warn-line);color:var(--warn);}
.notif-body{min-width:0;flex:1;}
.notif-title{font-size:12.5px;line-height:1.6;}
.notif-time{font-size:10px;color:var(--fg-3);margin-top:3px;}
.notif-dot{width:7px;height:7px;border-radius:50%;background:var(--gold);flex-shrink:0;margin-top:11px;}
.notif-filters{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px;}
.filter-chip{font-size:11.5px;padding:6px 12px;border-radius:var(--r1);border:1px solid var(--line);
  color:var(--fg-3);background:var(--bg-1);min-height:34px;}
.filter-chip.active{border-color:var(--gold-line);background:var(--gold-pale);color:var(--gold-lt);}

/* ══════════════════════════════════════════════════════
   SETTINGS
   ══════════════════════════════════════════════════════ */
.set-group{margin-bottom:12px;}
.seg{display:flex;gap:5px;background:var(--bg-2);border:1px solid var(--line-2);
  border-radius:var(--r2);padding:3px;}
.seg-btn{flex:1;padding:9px 8px;border-radius:var(--r1);font-size:12.5px;color:var(--fg-3);
  min-height:38px;transition:all .2s;}
.seg-btn.active{background:var(--gold-pale);color:var(--gold-lt);font-weight:600;}
/* A period switch inside a module head: the same control, sized for a title row
   rather than for a form. */
.seg.seg-sm{width:auto;flex:0 0 auto;padding:2px;gap:2px;}
.seg.seg-sm .seg-btn{flex:0 0 auto;padding:5px 11px;font-size:11.5px;min-height:0;}
.soon{opacity:.55;pointer-events:none;}

/* ══════════════════════════════════════════════════════
   CONTRACT PRINT VIEW
   ══════════════════════════════════════════════════════ */
.doc{background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r2);padding:18px;
  font-size:12.5px;color:var(--fg-2);line-height:1.85;max-height:52vh;overflow-y:auto;}
.doc h4{font-size:12.5px;color:var(--fg);margin:15px 0 4px;font-weight:600;}
.doc h4:first-of-type{margin-top:10px;}
.doc .doc-title{font-family:var(--f-display);font-weight:700;font-size:15px;color:var(--gold-lt);
  margin-bottom:8px;}
.doc-sig{margin-top:16px;padding-top:12px;border-top:1px solid var(--line-2);font-size:11.5px;}

/* ══════════════════════════════════════════════════════
   THE FILED CONTRACT DOCUMENT — #/contracts/<number>
   ══════════════════════════════════════════════════════
   A sixty-four section agreement is a DOCUMENT, and the one rule that follows
   from that is the one the old sheet broke: it does not live in a scrolling
   box. `.doc` caps itself at 52vh because it was five short clauses inside a
   bottom sheet; `.cdoc-body` lifts that cap, because a reader who came here to
   read the thing they signed should be able to read it the way the page reads.

   AND IT IS LEFT-TO-RIGHT WHATEVER THE INTERFACE IS. The agreement is English
   by its own section 62. An English legal document laid out right-to-left keeps
   its words and loses its structure — clause numbers detach from their clauses,
   the definition list inverts. The article carries `dir="ltr"` in the markup
   and this is what makes it stick inside an RTL page. */
.cdoc{direction:ltr;text-align:left;}
.cdoc-tools{margin-bottom:14px;justify-content:space-between;}

/* ── The letterhead ──
   The mark and the wordmark, and the contract number on the other side. What it
   deliberately does NOT carry is a registered name, an address or a licence
   number: `zexca-legal.html` §73 lists those as not yet stated, and a letterhead
   is the last place to invent one. */
.cdoc-head{
  display:flex;align-items:center;gap:14px;
  padding:18px 20px;border:1px solid var(--line);border-bottom:none;
  border-radius:var(--r2) var(--r2) 0 0;
  background:linear-gradient(135deg,rgba(232,182,71,.09),transparent 60%),var(--bg-1);
}
.cdoc-mark{
  width:42px;height:42px;border-radius:var(--r2);flex-shrink:0;
  background:linear-gradient(145deg,var(--gold-lt),var(--gold-dp));
  display:flex;align-items:center;justify-content:center;
  font-family:var(--f-display);font-weight:800;font-size:20px;color:var(--on-gold);
}
.cdoc-id{flex:1;min-width:0;}
.cdoc-brand{font-family:var(--f-display);font-weight:800;font-size:19px;letter-spacing:.08em;
  color:var(--gold-lt);line-height:1.15;}
.cdoc-kind{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--fg-3);
  margin-top:3px;}
.cdoc-ref{text-align:right;flex-shrink:0;}
.cdoc-ref span{display:block;font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--fg-3);}
.cdoc-ref b{font-family:var(--f-mono);font-size:13px;color:var(--fg);}

/* Repeated at the top of every printed page after the first. Off-screen until
   then — a running head is a paper device and has no job on a scrolling page. */
.cdoc-runhead{display:none;}

.cdoc-part{border:1px solid var(--line);border-bottom:none;padding:16px 20px;
  background:var(--bg-1);}
.cdoc-h2{font-family:var(--f-display);font-size:12px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--fg-3);margin:0 0 10px;}
.cdoc-h3{font-family:var(--f-display);font-size:12px;font-weight:700;color:var(--fg);
  margin:0 0 8px;}

/* The four blocks stack into ONE sheet: the letterhead, the particulars, the
   agreement and the execution block. Each drops the edge it shares with the
   next, and all four take the same line colour — `.doc`'s own `--line-2` is a
   shade darker than `--line` and read as a seam through the middle of a
   document that is supposed to be continuous. */
.cdoc-body{max-height:none;overflow:visible;border-radius:0;margin:0;
  border-color:var(--line);border-top:none;border-bottom:none;}

.cdoc-exec{border:1px solid var(--line);border-top:none;
  border-radius:0 0 var(--r2) var(--r2);padding:18px 20px;background:var(--bg-1);}
.cdoc-exec-none{padding:16px;}
.cdoc-superseded{margin:0 0 12px;}
.cdoc-note{font-size:11px;color:var(--fg-3);margin:10px 0 0;line-height:1.7;}

.cdoc-confirms{margin-top:18px;padding-top:14px;border-top:1px solid var(--line-2);}
.cdoc-cf{display:flex;gap:9px;align-items:flex-start;padding:6px 0;font-size:11.5px;
  color:var(--fg-2);line-height:1.65;}
.cdoc-cf .ic{flex-shrink:0;margin-top:2px;color:var(--up);}
/* A confirmation the record does NOT carry is drawn as missing rather than
   quietly left out — an absent tick on a document is information. */
.cdoc-cf.missing{color:var(--fg-3);}
.cdoc-cf.missing .ic{color:var(--warn);}
.cdoc-cf i{display:block;font-style:normal;font-size:10px;letter-spacing:.06em;
  color:var(--fg-3);margin-top:2px;}

.cdoc-fp{margin-top:18px;padding-top:14px;border-top:1px solid var(--line-2);}
.cdoc-fp div{display:flex;flex-wrap:wrap;gap:4px 10px;align-items:baseline;
  font-size:10.5px;color:var(--fg-3);margin-bottom:5px;}
.cdoc-fp span{letter-spacing:.06em;text-transform:uppercase;}
/* The hash wraps rather than scrolls: on paper there is nowhere to scroll to,
   and a fingerprint cut off at the page edge proves nothing. */
.cdoc-fp code{font-family:var(--f-mono);font-size:10.5px;color:var(--fg-2);
  word-break:break-all;direction:ltr;}
.cdoc-gov{font-size:10px;color:var(--fg-3);text-transform:none !important;letter-spacing:0;}

/* The list of documents. `.ct-row` already draws a contract row; this adds the
   one thing that row has never had to say — whether an acceptance was recorded
   against it. */
.cdoc-state{display:block;font-size:10px;letter-spacing:.06em;margin-top:3px;}
.cdoc-state.on{color:var(--up);}
.cdoc-state.off{color:var(--warn);}

/* ══════════════════════════════════════════════════════
   WALLET
   ══════════════════════════════════════════════════════ */

/* ── Tab strip ──
   Shared by every screen that has sub-routes: wallet keeps its .wtabs markup,
   newer screens use .tabstrip. Both are the same component. */
.wtabs,.tabstrip{display:flex;gap:6px;overflow-x:auto;-webkit-overflow-scrolling:touch;
  border-bottom:1px solid var(--line-2);margin-bottom:16px;padding-bottom:2px;}
.wtabs::-webkit-scrollbar,.tabstrip::-webkit-scrollbar{height:0;}
.wtab,.tab-btn{display:inline-flex;align-items:center;gap:7px;padding:11px 14px;white-space:nowrap;
  font-size:13px;color:var(--fg-3);border-bottom:2px solid transparent;min-height:46px;
  transition:color .2s,border-color .2s;}
.wtab:hover,.tab-btn:hover{color:var(--fg-2);}
/* `.active` alongside `[aria-selected]` because two screens mark the current
   tab with a class rather than the attribute — the Binary Option positions
   tabs and the wallet's history switch. Neither was ever lit, because the only
   rule here keyed off the attribute. */
.wtab[aria-selected="true"],.tab-btn[aria-selected="true"],
.wtab.active,.tab-btn.active{color:var(--gold-lt);
  border-bottom-color:var(--gold);font-weight:600;}
.wtab .ic,.tab-btn .ic{width:16px;height:16px;}
.wtab-count{font-family:var(--f-mono);font-size:10px;background:var(--bg-3);border-radius:8px;
  padding:1px 6px;color:var(--fg-3);direction:ltr;}

/* ── Two-column panel: form + the history of that same operation ──
   The running summary lives in the confirmation popup, not on the page, so
   the second column carries recent activity instead. */
.wcols{display:block;}
.wform{min-width:0;}
.wside{min-width:0;margin-top:16px;}
.wreceipt{background:var(--bg-2);border:1px solid var(--gold-line);
  border-radius:var(--r3);padding:14px;}
.wr-title{font-size:10.5px;letter-spacing:0.12em;text-transform:uppercase;color:var(--fg-3);
  margin-bottom:10px;}
html[lang="fa"] .wr-title,html[lang="ar"] .wr-title{letter-spacing:0;text-transform:none;}
.wr-total{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  padding-top:10px;margin-top:6px;border-top:1px solid var(--line);}
.wr-total-lbl{font-size:12px;color:var(--fg-2);}
.wr-total-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:20px;
  font-weight:600;color:var(--gold-lt);direction:ltr;unicode-bidi:isolate;}
.wr-note{font-size:11px;color:var(--fg-3);line-height:1.65;margin-top:10px;}

/* ── Form fields ── */
.field{margin-bottom:16px;}
.field-2{display:grid;grid-template-columns:1fr;gap:12px;}

/* Native select, styled to match the text inputs. Native is deliberate: on a
   phone it opens the platform picker, which beats any custom list. */
.sel{width:100%;background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r2);
  padding:13px 38px 13px 14px;font-size:13.5px;color:var(--fg);appearance:none;-webkit-appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--fg-3) 50%),
    linear-gradient(135deg,var(--fg-3) 50%,transparent 50%);
  background-position:calc(100% - 18px) 55%,calc(100% - 13px) 55%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;
  transition:border-color .25s,box-shadow .25s;}
[dir="rtl"] .sel{padding:13px 14px 13px 38px;
  background-position:18px 55%,13px 55%;
  background-image:linear-gradient(135deg,transparent 50%,var(--fg-3) 50%),
    linear-gradient(45deg,var(--fg-3) 50%,transparent 50%);}
.sel:focus{border-color:var(--gold);box-shadow:0 0 0 3px var(--gold-pale);outline:none;}
.sel option{background:var(--bg-1);color:var(--fg);}

/* ── The Z / MILO split, chosen by the reader ──
   A range for the fine control, three buttons for the usual answers, and a bar
   that shows the division at a glance. The range's own max is set from the
   balance, so it cannot be dragged to a share the wallet cannot pay. */
.split-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
.split-range{flex:1 1 180px;min-width:140px;height:26px;background:none;appearance:none;
  -webkit-appearance:none;direction:ltr;}
.split-range::-webkit-slider-runnable-track{height:6px;border-radius:3px;
  background:linear-gradient(90deg,var(--gold-dp),var(--mlc-dp));}
.split-range::-moz-range-track{height:6px;border-radius:3px;
  background:linear-gradient(90deg,var(--gold-dp),var(--mlc-dp));}
.split-range::-webkit-slider-thumb{appearance:none;-webkit-appearance:none;width:18px;height:18px;
  margin-top:-6px;border-radius:50%;background:linear-gradient(145deg,var(--gold-lt),var(--gold-dp));
  border:1px solid var(--gold);box-shadow:0 2px 8px rgba(0,0,0,.5);cursor:pointer;}
.split-range::-moz-range-thumb{width:18px;height:18px;border-radius:50%;
  background:linear-gradient(145deg,var(--gold-lt),var(--gold-dp));border:1px solid var(--gold);
  cursor:pointer;}
.split-range:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:var(--r1);}
.split-bar{display:flex;height:8px;border-radius:4px;overflow:hidden;margin-top:11px;
  background:var(--bg-3);direction:ltr;}
.split-z{background:linear-gradient(90deg,var(--gold),var(--gold-dp));transition:width .2s var(--ease);}
.split-ml{background:linear-gradient(90deg,var(--mlc-dp),var(--mlc));transition:width .2s var(--ease);}
.qb.on{border-color:var(--gold-line);background:var(--gold-pale);color:var(--gold-lt);}

/* Live figures under the amount, replacing the old summary column */
.inline-figs{display:flex;gap:14px;flex-wrap:wrap;align-items:baseline;
  padding:12px 14px;border-radius:var(--r2);background:var(--bg-2);
  border:1px solid var(--line-2);margin-bottom:16px;}
.if-main{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:17px;
  font-weight:600;color:var(--gold-lt);direction:ltr;unicode-bidi:isolate;}
.if-main.mlc{color:var(--mlc-lt);}
.if-lbl{font-size:11px;color:var(--fg-3);}
.if-side{font-size:11.5px;color:var(--fg-3);margin-inline-start:auto;}
.field-label{font-size:11px;letter-spacing:0.12em;text-transform:uppercase;color:var(--fg-3);
  margin-bottom:9px;display:block;}
html[lang="fa"] .field-label,html[lang="ar"] .field-label{letter-spacing:0;text-transform:none;}
.amount-wrap{position:relative;direction:ltr;}
.amount-prefix{position:absolute;left:16px;top:50%;transform:translateY(-50%);
  font-family:var(--f-mono);font-size:20px;color:var(--fg-3);pointer-events:none;}
.amount-input{
  width:100%;background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r2);
  padding:15px 88px 15px 40px;font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  font-size:24px;font-weight:600;transition:border-color .25s,box-shadow .25s;direction:ltr;
  -moz-appearance:textfield;
}
.amount-input::-webkit-outer-spin-button,.amount-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}
.amount-input:focus{border-color:var(--gold);box-shadow:0 0 0 3px var(--gold-pale);outline:none;}
.amount-input::placeholder{color:var(--fg-3);font-size:18px;font-weight:400;}
.amount-input.invalid{border-color:var(--down);}
.amount-unit{position:absolute;right:14px;top:50%;transform:translateY(-50%);
  font-family:var(--f-mono);font-size:11px;color:var(--fg-3);}
.amount-max{position:absolute;right:12px;top:50%;transform:translateY(-50%);
  font-size:11px;color:var(--gold-lt);border:1px solid var(--gold-line);border-radius:var(--r1);
  padding:5px 9px;background:var(--gold-pale);min-height:30px;}
.field-error{display:none;align-items:center;gap:7px;font-size:12px;color:var(--down);margin-top:9px;}
.field-error.show{display:flex;}
.field-error .ic{width:13px;height:13px;flex-shrink:0;}
.field-hint{font-size:11.5px;color:var(--fg-3);margin-top:9px;line-height:1.6;}
.field-ok{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--up);margin-top:9px;}
.field-ok .ic{width:13px;height:13px;}

.quick-btns{display:flex;gap:7px;margin-top:10px;flex-wrap:wrap;}
.qb{flex:1;min-width:60px;min-height:38px;padding:9px 7px;border-radius:var(--r1);
  border:1px solid var(--line);font-family:var(--f-mono);font-size:12px;color:var(--fg-2);
  background:var(--bg-1);transition:all .2s var(--ease);direction:ltr;}
.qb:hover{border-color:var(--gold-line);color:var(--gold-lt);background:var(--gold-pale);}

.slider-wrap{margin-top:14px;}
.slider-label{display:flex;justify-content:space-between;font-size:11px;color:var(--fg-3);margin-bottom:9px;}
input[type=range]{width:100%;-webkit-appearance:none;appearance:none;height:5px;border-radius:3px;
  outline:none;cursor:pointer;background:var(--bg-3);}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:20px;height:20px;border-radius:50%;
  background:linear-gradient(145deg,var(--gold-lt),var(--gold-dp));border:2px solid var(--bg-0);
  cursor:pointer;box-shadow:0 2px 10px var(--gold-glow);}
input[type=range]::-moz-range-thumb{width:16px;height:16px;border-radius:50%;
  background:var(--gold);border:2px solid var(--bg-0);cursor:pointer;}
input[type=range]:focus-visible{outline:2px solid var(--gold);outline-offset:4px;}

/* Text input: addresses, account numbers, 2FA, notes */
.tin{width:100%;background:var(--bg-0);border:1px solid var(--line);border-radius:var(--r2);
  padding:13px 14px;font-size:13.5px;transition:border-color .25s,box-shadow .25s;}
.tin:focus{border-color:var(--gold);box-shadow:0 0 0 3px var(--gold-pale);outline:none;}
.tin::placeholder{color:var(--fg-3);}
.tin.invalid{border-color:var(--down);}
.tin.mono{font-family:var(--f-mono);font-size:12.5px;direction:ltr;unicode-bidi:isolate;}
.tin.code{font-family:var(--f-mono);font-size:19px;letter-spacing:0.42em;text-align:center;
  direction:ltr;max-width:220px;}
.tin-row{display:flex;gap:8px;align-items:stretch;}
.tin-row .tin{flex:1;min-width:0;}

/* ── Option tiles: payout coin and network ── */
.payment-methods{display:grid;grid-template-columns:1fr;gap:9px;}
.pm-item{background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r2);padding:14px;
  display:flex;align-items:center;gap:12px;transition:all .22s var(--ease);min-height:62px;
  text-align:start;width:100%;}
.pm-item:hover{border-color:var(--line);background:var(--bg-2);}
.pm-item.selected{border-color:var(--gold-line);background:var(--gold-pale);}
.pm-item.is-soon{opacity:.6;}
.pm-icon{color:var(--gold);display:flex;flex-shrink:0;}
.pm-text{display:flex;flex-direction:column;min-width:0;flex:1;}
.pm-name{font-size:13px;font-weight:500;}
.pm-sub{font-family:var(--f-mono);font-size:11px;color:var(--fg-3);direction:ltr;unicode-bidi:isolate;}
.pm-item .chip{margin-inline-start:auto;}

.opt-row{display:flex;gap:8px;flex-wrap:wrap;}
.opt{display:flex;flex-direction:column;gap:2px;padding:10px 13px;border-radius:var(--r2);
  border:1px solid var(--line);background:var(--bg-1);color:var(--fg-2);text-align:start;
  min-height:52px;transition:all .2s;min-width:104px;}
.opt:hover{border-color:var(--gold-line);color:var(--fg);}
.opt.selected{border-color:var(--gold-line);background:var(--gold-pale);color:var(--gold-lt);}
.opt-name{font-family:var(--f-mono);font-size:12.5px;font-weight:600;direction:ltr;unicode-bidi:isolate;}
/* An option whose name is words, not a code: Arabic and Persian letters do not
   join in a monospace face, and they must read in the page direction. */
.opt-name.text{font-family:var(--f-body);direction:inherit;unicode-bidi:normal;letter-spacing:0;}
.opt-sub{font-size:10.5px;color:var(--fg-3);}
.opt.selected .opt-sub{color:var(--gold);}

/* ── Deposit gateway ── */
.addr-box{background:var(--bg-0);border:1px solid var(--gold-line);border-radius:var(--r2);
  padding:13px;display:flex;align-items:center;gap:10px;}
.addr-val{font-family:var(--f-mono);font-size:12px;color:var(--gold-lt);word-break:break-all;
  direction:ltr;unicode-bidi:isolate;flex:1;min-width:0;line-height:1.6;}
.copy-btn{flex-shrink:0;border:1px solid var(--line);border-radius:var(--r1);padding:8px 10px;
  color:var(--fg-2);min-height:36px;display:inline-flex;align-items:center;gap:6px;font-size:11.5px;}
.copy-btn:hover{border-color:var(--gold-line);color:var(--gold-lt);}
.qr-box{display:flex;flex-direction:column;align-items:center;gap:8px;padding:14px;
  background:var(--bg-0);border:1px solid var(--line-2);border-radius:var(--r2);}
.qr-box svg{width:148px;height:148px;background:#fff;border-radius:var(--r1);padding:7px;}
.qr-note{font-size:10.5px;color:var(--fg-3);}
.dep-grid{display:grid;grid-template-columns:1fr;gap:12px;}
.expiry{font-family:var(--f-mono);font-size:12px;color:var(--warn);direction:ltr;unicode-bidi:isolate;}

/* Horizontal status stepper (deposit) */
.dsteps{display:flex;gap:6px;margin-top:14px;}
.dstep{flex:1;padding:10px;border-radius:var(--r2);border:1px solid var(--line-2);
  background:var(--bg-1);text-align:center;}
.dstep.on{border-color:var(--gold-line);background:var(--gold-pale);}
.dstep.done{border-color:var(--up-line);background:var(--up-pale);}
.dstep-lbl{font-size:11px;color:var(--fg-3);}
.dstep.on .dstep-lbl{color:var(--gold-lt);font-weight:600;}
.dstep.done .dstep-lbl{color:var(--up);}
.dstep-sub{font-family:var(--f-mono);font-size:10px;color:var(--fg-3);margin-top:3px;
  direction:ltr;unicode-bidi:isolate;}

/* ── Convert ── */
.conv{display:grid;grid-template-columns:1fr auto 1fr;gap:10px;align-items:center;}
.conv-side{padding:13px;border-radius:var(--r2);border:1px solid var(--line-2);background:var(--bg-1);}
.conv-side.zc{border-color:var(--gold-line);background:var(--gold-pale);}
.conv-side.mlc{border-color:var(--mlc-line);background:var(--mlc-pale);}
.conv-lbl{font-size:10.5px;color:var(--fg-3);}
.conv-coin{font-family:var(--f-display);font-weight:700;font-size:15px;margin-top:2px;}
.conv-side.zc .conv-coin{color:var(--gold-lt);}
.conv-side.mlc .conv-coin{color:var(--mlc-lt);}
.conv-bal{font-family:var(--f-mono);font-size:11px;color:var(--fg-3);margin-top:3px;
  direction:ltr;unicode-bidi:isolate;}
.conv-arrow{color:var(--fg-3);display:flex;align-items:center;justify-content:center;}
.conv-arrow .ic{width:22px;height:22px;}

/* ── Withdrawal requests and lifecycle ── */
.req-list{display:flex;flex-direction:column;gap:8px;}
.req{display:grid;grid-template-columns:auto 1fr auto;gap:11px;align-items:center;width:100%;
  padding:12px;border-radius:var(--r2);background:var(--bg-1);border:1px solid var(--line-2);
  text-align:start;transition:all .2s;}
.req:hover{border-color:var(--line);background:var(--bg-2);}
.req-icon{width:36px;height:36px;border-radius:var(--r2);flex-shrink:0;display:flex;
  align-items:center;justify-content:center;background:var(--bg-3);border:1px solid var(--line);
  color:var(--fg-2);}
.req-icon.pending{background:var(--warn-pale);border-color:var(--warn-line);color:var(--warn);}
.req-icon.approved{background:var(--info-pale);border-color:var(--info-line);color:var(--info);}
.req-icon.successful{background:var(--up-pale);border-color:var(--up-line);color:var(--up);}
.req-icon.rejected,.req-icon.cancelled{background:var(--down-pale);border-color:var(--down-line);color:var(--down);}
.req-mid{display:flex;flex-direction:column;min-width:0;}
.req-amount{font-family:var(--f-mono);font-size:13.5px;font-weight:600;direction:ltr;unicode-bidi:isolate;}
.req-meta{font-size:11px;color:var(--fg-3);margin-top:2px;}
.req-end{display:flex;flex-direction:column;align-items:flex-end;gap:4px;flex-shrink:0;}
.req-id{font-family:var(--f-mono);font-size:10px;color:var(--fg-3);direction:ltr;unicode-bidi:isolate;}

/* Vertical timeline */
.tl{display:flex;flex-direction:column;margin:4px 0;}
.tl-item{display:grid;grid-template-columns:auto 1fr;gap:12px;}
.tl-rail{display:flex;flex-direction:column;align-items:center;}
.tl-dot{width:13px;height:13px;border-radius:50%;border:2px solid var(--line);background:var(--bg-1);
  flex-shrink:0;margin-top:3px;}
.tl-item.done .tl-dot{background:var(--up);border-color:var(--up);}
.tl-item.current .tl-dot{background:var(--gold);border-color:var(--gold);
  box-shadow:0 0 0 4px var(--gold-pale);animation:pulse 2.2s infinite;}
.tl-item.bad .tl-dot{background:var(--down);border-color:var(--down);}
.tl-line{width:2px;flex:1;background:var(--line-2);min-height:20px;margin:3px 0;}
.tl-item:last-child .tl-line{display:none;}
.tl-body{display:flex;flex-direction:column;align-items:flex-start;padding-bottom:14px;min-width:0;}
.tl-item:last-child .tl-body{padding-bottom:0;}
.tl-state{font-size:13px;font-weight:600;display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  width:100%;}
.tl-item.todo .tl-state{color:var(--fg-3);font-weight:500;}
.tl-item.bad .tl-state{color:var(--down);}
.tl-when{font-size:11px;color:var(--fg-3);margin-inline-start:auto;}
.tl-note{font-size:11.5px;color:var(--fg-3);line-height:1.7;margin-top:2px;}
.tl-actions{margin-top:8px;}

/* ── Ledger and pagination ── */
/* ══════════════════════════════════════════════════════
   CONTRACT PAYOUTS — the wallet history, grouped by contract
   ══════════════════════════════════════════════════════
   The ledger list below is the same money in time order. This view exists
   because a contract pays month by month and two contracts paying at once
   interleave into a chronological list nobody can separate again. */
.hv-tabs{margin-bottom:14px;}
.cp-h{font-family:var(--f-display);font-weight:700;font-size:19px;letter-spacing:-.015em;
  color:var(--fg);margin:0;}

/* The one figure the product never stated: what this account has been paid in
   total, across every contract it holds. */
.cp-grand{
  padding:15px 18px;border-radius:var(--r3);margin-bottom:14px;
  background:linear-gradient(135deg,var(--gold-pale),transparent 62%),var(--bg-1);
  border:1px solid var(--line);border-inline-start:3px solid var(--gold);
}
.cp-grand-k{display:block;font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:7px;}
.cp-grand-v{display:block;font-family:var(--f-mono);font-size:28px;font-weight:600;
  line-height:1.05;letter-spacing:-.02em;color:var(--gold-lt);
  font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate;}
.cp-grand-v i{font-style:normal;font-size:13px;color:var(--fg-3);margin-inline-start:6px;}
.cp-grand-s{display:block;margin-top:6px;font-size:12px;color:var(--fg-3);}

.cp-card{padding:0;overflow:hidden;}
.cp-head{display:flex;align-items:center;gap:11px;padding:14px 16px 12px;flex-wrap:wrap;}
.cp-id{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;}
.cp-no{font-family:var(--f-mono);font-size:13px;color:var(--fg);letter-spacing:.02em;
  direction:ltr;unicode-bidi:isolate;}
.cp-cyc{font-size:11px;color:var(--fg-3);}
.cp-sum{text-align:end;flex:none;display:flex;flex-direction:column;gap:2px;}
.cp-sum b{font-family:var(--f-mono);font-size:15px;font-weight:600;color:var(--up);
  font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate;}
.cp-sum i{font-style:normal;font-size:10.5px;color:var(--fg-3);
  direction:ltr;unicode-bidi:isolate;}

/* How far the contract has run against what it is owed. The track is the whole
   obligation, so a short bar is a young contract and not a failing one. */
.cp-bar{height:3px;background:var(--bg-3);overflow:hidden;}
.cp-bar span{display:block;height:100%;background:linear-gradient(90deg,var(--gold-dp),var(--gold-lt));}

.cp-rows{padding:4px 16px 14px;}
/* A month, and the three facts about it: which cycle, which calendar month, and
   what landed. The cycle number leads because it is the ordering and the thing
   a reader is checking for a gap in. */
.cp-row{display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:center;
  padding:9px 0;border-bottom:1px solid var(--line-2);}
.cp-row:last-child{border-bottom:0;}
.cp-m{
  flex:none;min-width:24px;height:24px;padding:0 6px;border-radius:7px;
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--f-mono);font-size:11px;font-weight:600;
  background:var(--bg-3);color:var(--fg-2);border:1px solid var(--hair);
  font-variant-numeric:tabular-nums;
}
.cp-mid{display:flex;flex-direction:column;gap:1px;min-width:0;}
.cp-per{font-size:13px;color:var(--fg);}
/* When the money actually landed, which is NOT the month it was for: a catch-up
   run can publish two cycles on one day. */
.cp-when{font-size:10.5px;color:var(--fg-3);}
.cp-amt{font-family:var(--f-mono);font-size:14px;font-weight:600;color:var(--up);
  font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate;white-space:nowrap;}
.cp-amt i{font-style:normal;font-size:10px;color:var(--fg-3);margin-inline-start:4px;}

@media(max-width:479px){
  .cp-grand-v{font-size:24px;}
  .cp-head{padding-inline:13px;}
  .cp-rows{padding-inline:13px;}
}

.led-list{display:flex;flex-direction:column;gap:8px;}
.led{display:grid;grid-template-columns:auto 1fr auto;gap:11px;align-items:center;width:100%;
  padding:12px;border-radius:var(--r2);background:var(--bg-1);border:1px solid var(--line-2);
  text-align:start;}
.led:hover{border-color:var(--line);background:var(--bg-2);}
.led-icon{width:34px;height:34px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;
  justify-content:center;background:var(--bg-3);border:1px solid var(--line);}
.led-icon.in{background:var(--up-pale);border-color:var(--up-line);color:var(--up);}
.led-icon.out{background:var(--down-pale);border-color:var(--down-line);color:var(--down);}
.led-mid{display:flex;flex-direction:column;min-width:0;}
.led-type{font-size:13px;font-weight:500;}
.led-meta{font-size:11px;color:var(--fg-3);margin-top:2px;}
.led-end{display:flex;flex-direction:column;align-items:flex-end;gap:4px;}
.led-amount{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:13.5px;
  font-weight:600;direction:ltr;unicode-bidi:isolate;}
.led-amount.in{color:var(--up);} .led-amount.out{color:var(--fg);}
.txid{font-family:var(--f-mono);font-size:11px;color:var(--fg-3);direction:ltr;unicode-bidi:isolate;
  word-break:break-all;}

/* The ledger is a table on wide screens and a card list on phones — same rows,
   same order, rendered from the same data. The signal history uses the same pair,
   and both base rules live here: a media query carries no extra specificity, so a
   flat rule further down the file would beat the block that reveals the table. */
.led-table-wrap{display:none;}
.sig-table-wrap{display:none;}

.pager{display:flex;align-items:center;gap:6px;justify-content:center;flex-wrap:wrap;margin-top:16px;
  direction:ltr;}
.pager-btn{min-width:36px;min-height:36px;padding:7px 10px;border-radius:var(--r1);
  border:1px solid var(--line);background:var(--bg-1);color:var(--fg-2);
  font-family:var(--f-mono);font-size:12px;transition:all .18s;}
.pager-btn:hover:not(.is-disabled){border-color:var(--gold-line);color:var(--gold-lt);}
.pager-btn.active{background:var(--gold-pale);border-color:var(--gold-line);color:var(--gold-lt);font-weight:600;}
.pager-btn.is-disabled{opacity:.34;pointer-events:none;}
.pager-gap{color:var(--fg-3);padding:0 2px;}
.pager-info{font-size:11.5px;color:var(--fg-3);text-align:center;margin-top:9px;}

/* ── Wallet balance header ── */
.wb-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin-top:12px;}
.wb-flags{display:flex;gap:6px;flex-wrap:wrap;margin-top:12px;}

/* ══════════════════════════════════════════════════════
   PROFILE, KYC, TELEGRAM, PASSWORD
   ══════════════════════════════════════════════════════ */

/* ── Identity header ── */
.id-row{display:flex;align-items:center;gap:13px;}
.id-text{display:flex;flex-direction:column;min-width:0;flex:1;}
.id-name{font-family:var(--f-display);font-size:17px;font-weight:700;}
.id-name.unset{color:var(--fg-3);font-weight:500;}
.id-acct{display:flex;align-items:center;gap:7px;margin-top:3px;}
.id-acct-val{font-family:var(--f-mono);font-size:12px;color:var(--fg-3);
  direction:ltr;unicode-bidi:isolate;}
.id-chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:12px;}

/* ── State banner: what the account has to do next ── */
.state-banner{display:flex;align-items:flex-start;gap:11px;padding:13px 14px;border-radius:var(--r2);
  border:1px solid var(--line-2);background:var(--bg-1);margin-bottom:16px;}
.state-banner .ic{flex-shrink:0;margin-top:1px;}
.sb-text{display:flex;flex-direction:column;min-width:0;flex:1;}
.sb-title{font-size:13px;font-weight:600;}
.sb-sub{font-size:11.5px;color:var(--fg-3);line-height:1.7;margin-top:3px;}
.state-banner.warn{border-color:var(--warn-line);background:var(--warn-pale);}
.state-banner.warn .ic,.state-banner.warn .sb-title{color:var(--warn);}
.state-banner.info{border-color:var(--info-line);background:var(--info-pale);}
.state-banner.info .ic,.state-banner.info .sb-title{color:var(--info);}
.state-banner.ok{border-color:var(--up-line);background:var(--up-pale);}
.state-banner.ok .ic,.state-banner.ok .sb-title{color:var(--up);}
.state-banner.bad{border-color:var(--down-line);background:var(--down-pale);}
.state-banner.bad .ic,.state-banner.bad .sb-title{color:var(--down);}

/* ── Locked field: read-only after the identity was verified ── */
.tin[readonly]{background:var(--bg-2);color:var(--fg-2);cursor:default;}
.tin[readonly]:focus{border-color:var(--line);box-shadow:none;}
.lock-note{display:flex;align-items:center;gap:7px;font-size:11px;color:var(--fg-3);margin-top:8px;}
.lock-note .ic{width:12px;height:12px;flex-shrink:0;}
.lock-note button{color:var(--gold-lt);text-decoration:underline;text-underline-offset:2px;}

/* ── Dirty-state save bar ── */
.sec-foot{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding-top:14px;margin-top:2px;
  border-top:1px solid var(--hair);}
.sec-foot .btn-ghost{margin-inline-start:auto;}

/* ── KYC document cards ── */
.kdoc-list{display:flex;flex-direction:column;gap:10px;}
.kdoc{background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r2);padding:14px;}
.kdoc.approved{border-color:var(--up-line);}
.kdoc.rejected{border-color:var(--down-line);}
.kdoc-head{display:flex;align-items:center;gap:11px;}
.kdoc-icon{width:38px;height:38px;border-radius:var(--r2);flex-shrink:0;display:flex;
  align-items:center;justify-content:center;background:var(--bg-3);border:1px solid var(--line);
  color:var(--gold);}
.kdoc-text{display:flex;flex-direction:column;min-width:0;flex:1;}
.kdoc-title{font-size:13.5px;font-weight:600;}
.kdoc-req{font-size:11.5px;color:var(--fg-3);line-height:1.65;margin-top:3px;}
.kdoc-body{display:flex;align-items:center;gap:12px;margin-top:12px;}
.kdoc-thumb{width:66px;height:66px;border-radius:var(--r2);flex-shrink:0;overflow:hidden;
  background:var(--bg-0);border:1px solid var(--line);display:flex;align-items:center;
  justify-content:center;color:var(--fg-3);}
.kdoc-thumb img{width:100%;height:100%;object-fit:cover;display:block;}
.kdoc-meta{display:flex;flex-direction:column;min-width:0;flex:1;gap:3px;}
.kdoc-file{font-family:var(--f-mono);font-size:11.5px;color:var(--fg-2);direction:ltr;
  unicode-bidi:isolate;word-break:break-all;}
.kdoc-size{font-size:11px;color:var(--fg-3);}
/* The byte figure is a number with a Latin unit: isolate it, or "1.8 MB"
   comes out as "MB 1.8" in RTL. The timestamp beside it is localized prose
   and must stay in reader direction. */
.kdoc-bytes{font-size:11px;color:var(--fg-3);direction:ltr;unicode-bidi:isolate;
  align-self:flex-start;}
.kdoc-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px;}
.kdoc-drop{display:flex;flex-direction:column;align-items:center;gap:7px;width:100%;
  padding:20px 14px;margin-top:12px;border-radius:var(--r2);border:1px dashed var(--line);
  background:var(--bg-0);color:var(--fg-3);transition:all .22s;}
.kdoc-drop:hover{border-color:var(--gold-line);color:var(--gold-lt);background:var(--gold-pale);}
.kdoc-drop .ic{width:22px;height:22px;}
.kdoc-drop-lbl{font-size:12.5px;}
.kdoc-drop-sub{font-size:10.5px;}

/* ── Telegram link card ── */
.tg-state{display:flex;align-items:center;gap:11px;padding:13px;border-radius:var(--r2);
  background:var(--bg-0);border:1px solid var(--line-2);}
.tg-state.on{border-color:var(--up-line);background:var(--up-pale);}
.tg-handle{font-family:var(--f-mono);font-size:13px;direction:ltr;unicode-bidi:isolate;}
.tg-steps{counter-reset:tgs;margin:12px 0 0;padding:0;list-style:none;}
.tg-steps li{position:relative;padding-inline-start:26px;font-size:12px;color:var(--fg-2);
  line-height:1.75;margin-bottom:5px;}
.tg-steps li::before{counter-increment:tgs;content:counter(tgs);position:absolute;
  inset-inline-start:0;top:2px;width:17px;height:17px;border-radius:50%;font-size:10px;
  font-family:var(--f-mono);display:flex;align-items:center;justify-content:center;
  background:var(--gold-pale);border:1px solid var(--gold-line);color:var(--gold-lt);}
.tg-code{font-family:var(--f-mono);font-size:18px;letter-spacing:0.22em;color:var(--gold-lt);
  direction:ltr;unicode-bidi:isolate;}

/* ── Password rules ── */
.pw-bar{height:5px;border-radius:3px;background:var(--bg-3);overflow:hidden;margin-top:10px;}
.pw-bar-fill{height:100%;width:0;border-radius:3px;background:var(--down);
  transition:width .3s var(--ease),background .3s;}
.pw-bar-fill.mid{background:var(--warn);} .pw-bar-fill.good{background:var(--up);}
.pw-rules{display:flex;flex-direction:column;gap:5px;margin-top:11px;}
.pw-rule{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--fg-3);}
.pw-rule .ic{width:13px;height:13px;flex-shrink:0;}
.pw-rule.ok{color:var(--up);}
.pw-strength{font-size:11px;color:var(--fg-3);margin-top:7px;}

/* Latin inside a localized sentence: a bot handle, a function name. Without
   the isolate its brackets and @ jump to the wrong end of the phrase. */
.iso{direction:ltr;unicode-bidi:isolate;}
code.iso{font-family:var(--f-mono);font-size:11px;color:var(--gold-lt);
  display:block;margin-top:6px;word-break:break-all;white-space:pre-line;}

/* The password form stays narrow — a wide password field reads as a search box */
.pw-col{max-width:440px;}

/* ── Missing-items list on the overview banner ── */
.miss-list{display:flex;flex-direction:column;gap:7px;margin-top:11px;}
.miss-row{display:flex;align-items:center;gap:10px;width:100%;padding:11px 12px;text-align:start;
  border-radius:var(--r2);border:1px solid var(--line-2);background:var(--bg-1);font-size:12.5px;}
.miss-row:hover{border-color:var(--gold-line);color:var(--gold-lt);background:var(--gold-pale);}
.miss-row .ic{flex-shrink:0;}
.miss-row .ic-end{margin-inline-start:auto;}
[dir="rtl"] .miss-row .ic-end{transform:scaleX(-1);}

/* ══════════════════════════════════════════════════════
   SUPPORT: tickets, thread, chat, knowledge base
   ══════════════════════════════════════════════════════ */

/* Inbox: the list narrow, the conversation wide. One column until there is
   room for both, and then the list is what stays put while the thread scrolls. */
.tkcols{display:block;}
.tklist{min-width:0;}
.tkthread{min-width:0;}

/* Its own list class: .led-list is swapped for a table from 768px up, which
   would make a ticket list disappear on desktop. */
.tk-list{display:flex;flex-direction:column;gap:8px;}

.tk-row{display:grid;grid-template-columns:auto 1fr auto;gap:11px;align-items:start;width:100%;
  padding:13px 12px;border-radius:var(--r2);background:var(--bg-1);border:1px solid var(--line-2);
  text-align:start;transition:all .2s;}
.tk-row:hover{border-color:var(--line);background:var(--bg-2);}
.tk-row.on{border-color:var(--gold-line);background:var(--gold-pale);}
.tk-icon{width:34px;height:34px;border-radius:var(--r2);flex-shrink:0;display:flex;
  align-items:center;justify-content:center;background:var(--bg-3);border:1px solid var(--line);
  color:var(--fg-2);}
.tk-icon.answered{background:var(--gold-pale);border-color:var(--gold-line);color:var(--gold-lt);}
.tk-icon.resolved{background:var(--up-pale);border-color:var(--up-line);color:var(--up);}
.tk-mid{display:flex;flex-direction:column;min-width:0;gap:3px;}
.tk-subj{font-size:13px;font-weight:500;line-height:1.45;}
.tk-meta{font-size:11px;color:var(--fg-3);}
.tk-no{font-family:var(--f-mono);font-size:10.5px;color:var(--fg-3);
  direction:ltr;unicode-bidi:isolate;}
.tk-end{display:flex;flex-direction:column;align-items:flex-end;gap:5px;flex-shrink:0;}
.tk-dot{width:7px;height:7px;border-radius:50%;background:var(--gold);flex-shrink:0;}

/* Thread head: what support needs to see before reading a word */
.tk-head{background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r3);
  padding:14px;margin-bottom:14px;}
.tk-head-top{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:9px;}
.tk-head h3{font-size:14.5px;font-weight:600;line-height:1.5;flex:1;min-width:180px;}
.tk-ids{display:flex;gap:7px;flex-wrap:wrap;margin-top:10px;padding-top:10px;
  border-top:1px solid var(--hair);}

/* Messages */
.msgs{display:flex;flex-direction:column;gap:12px;}
.msg{display:grid;grid-template-columns:auto 1fr;gap:10px;align-items:start;}
.msg.you{grid-template-columns:1fr auto;}
.msg-av{width:30px;height:30px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;
  justify-content:center;font-family:var(--f-display);font-size:11px;font-weight:700;
  background:var(--bg-3);border:1px solid var(--line);color:var(--fg-2);}
.msg.agent .msg-av{background:var(--gold-pale);border-color:var(--gold-line);color:var(--gold-lt);}
.msg-bubble{background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r2);
  padding:11px 13px;min-width:0;}
.msg.you .msg-bubble{background:var(--gold-pale);border-color:var(--gold-line);}
.msg-body{font-size:13px;line-height:1.8;color:var(--fg);white-space:pre-line;word-break:break-word;}
.msg-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:5px;}
.msg-who{font-size:11.5px;font-weight:600;color:var(--fg-2);}
.msg-when{font-size:10.5px;color:var(--fg-3);}
.msg-files{display:flex;flex-direction:column;gap:5px;margin-top:8px;}
.msg-file{display:inline-flex;align-items:center;gap:7px;font-size:11px;color:var(--fg-3);
  padding:6px 9px;border-radius:var(--r1);background:var(--bg-0);border:1px solid var(--line-2);}
.msg-file .ic{width:13px;height:13px;flex-shrink:0;}
.msg-file b{font-family:var(--f-mono);font-weight:400;direction:ltr;unicode-bidi:isolate;
  word-break:break-all;}
/* A system line is the record of an event, not a person speaking */
.msg.system{grid-template-columns:1fr;}
.msg.system .msg-bubble{background:transparent;border:none;border-top:1px dashed var(--line-2);
  border-radius:0;padding:9px 0 0;text-align:center;}
.msg.system .msg-body{font-size:11px;color:var(--fg-3);}

.reply-box{margin-top:16px;padding-top:14px;border-top:1px solid var(--hair);}
.reply-box textarea,.tin-area{width:100%;background:var(--bg-0);border:1px solid var(--line);
  border-radius:var(--r2);padding:12px 14px;font-size:13.5px;font-family:var(--f-body);
  color:var(--fg);line-height:1.8;resize:vertical;min-height:96px;
  transition:border-color .25s,box-shadow .25s;}
.tin-area:focus{border-color:var(--gold);box-shadow:0 0 0 3px var(--gold-pale);outline:none;}
.tin-area::placeholder{color:var(--fg-3);}

/* Five stars, asked once, after the thread is done */
.stars{display:flex;gap:5px;}
.star-btn{padding:5px;color:var(--fg-3);transition:color .18s,transform .18s;}
.star-btn:hover,.star-btn.on{color:var(--gold);}
.star-btn .ic{width:22px;height:22px;}
.star-btn.on .ic{fill:var(--gold);}

/* Chat: the same bubbles, in a scrolling box with a composer under it */
.chat-box{background:var(--bg-0);border:1px solid var(--line-2);border-radius:var(--r2);
  padding:14px;max-height:400px;overflow-y:auto;display:flex;flex-direction:column;gap:11px;}
.chat-typing{display:flex;align-items:center;gap:7px;font-size:11.5px;color:var(--fg-3);}
.chat-typing i{width:6px;height:6px;border-radius:50%;background:var(--fg-3);
  animation:blink 1.2s infinite;}
.chat-typing i:nth-child(2){animation-delay:.2s;}
.chat-typing i:nth-child(3){animation-delay:.4s;}
@keyframes blink{0%,80%,100%{opacity:.25}40%{opacity:1}}
.chat-foot{display:flex;gap:8px;align-items:flex-end;margin-top:12px;}
.chat-foot .tin{flex:1;min-width:0;}

/* Channel tiles: WhatsApp, Telegram, email — real links, always available */
.ch-row{display:grid;grid-template-columns:1fr;gap:9px;margin-top:12px;}
.ch{display:flex;align-items:center;gap:11px;padding:12px 13px;border-radius:var(--r2);min-width:0;
  background:var(--bg-1);border:1px solid var(--line-2);transition:all .2s;text-align:start;}
.ch .ic{flex-shrink:0;}
.ch:hover{border-color:var(--gold-line);background:var(--gold-pale);}
.ch-text{display:flex;flex-direction:column;min-width:0;flex:1;}
.ch-name{font-size:12.5px;font-weight:500;}
.ch-sub{font-size:11px;color:var(--fg-3);direction:ltr;unicode-bidi:isolate;}

/* Knowledge base */
.kb-row{display:flex;align-items:center;gap:11px;width:100%;padding:13px 12px;text-align:start;
  border-radius:var(--r2);background:var(--bg-1);border:1px solid var(--line-2);transition:all .2s;}
.kb-row:hover{border-color:var(--gold-line);background:var(--gold-pale);}
.kb-text{display:flex;flex-direction:column;min-width:0;flex:1;gap:3px;}
.kb-title{font-size:13px;font-weight:500;line-height:1.45;}
.kb-group{font-size:10.5px;color:var(--fg-3);}
.kb-body{font-size:13px;line-height:1.9;color:var(--fg-2);white-space:pre-line;}

/* ══════════════════════════════════════════════════════
   DASHBOARD GRID
   A screen whose job is to be read in one look, not worked through step by
   step. Modules sit on a 12-column grid and carry lighter chrome than .card:
   one hairline, one small title, no padding contest between neighbours.
   ══════════════════════════════════════════════════════ */
/* `minmax(0,1fr)`, NOT `1fr`, AND THE DIFFERENCE WAS THE WHOLE PHONE LAYOUT.
   A bare `1fr` track takes its automatic minimum from its items' min-content.
   `.mkt-scroll` — the market table, which carries `overflow-x:auto` and is
   built to scroll inside itself — has a min-content of about 1841px. That
   number climbed into the track, so on a 390px phone the grid box measured
   362px while its single column measured 1841px, and `body{overflow-x:hidden}`
   cut the difference off. Every card on Home was rendered and then clipped:
   not squashed, not scrollable, gone.

   `minmax(0,1fr)` lets the track floor at zero and hands the overflow back to
   the element that asked for it. Desktop never sees this rule — both the
   768px and the 1024px queries below set `grid-template-columns` themselves —
   so the same fix reaches the signals screen and the terminal, which share
   this grid, and reaches nothing above 768px. */
.dash{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;align-items:start;}
/* Two modules sharing one grid cell, stacked. */
.dash-stack{display:flex;flex-direction:column;gap:12px;min-width:0;}
/* Home puts `.card`s in the grid rather than `.mod`s, and a card carries its own
   bottom margin for the single-column layouts it was built for. Inside a grid the
   gap owns the spacing. */
.dash .card{margin-bottom:0;}
.dash .card:last-child{margin-bottom:0;}
.mod{background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r3);
  padding:15px 16px;min-width:0;display:flex;flex-direction:column;}
.mod.flush{padding:0;overflow:hidden;}
.mod-head{display:flex;align-items:center;gap:8px 10px;margin-bottom:13px;min-height:20px;
  flex-wrap:wrap;}
.mod-title{font-size:10.5px;letter-spacing:0.13em;text-transform:uppercase;color:var(--fg-3);
  font-weight:600;min-width:0;}
html[lang="fa"] .mod-title,html[lang="ar"] .mod-title{letter-spacing:0;text-transform:none;
  font-size:12px;font-family:var(--f-body);}
.mod-end{margin-inline-start:auto;display:flex;align-items:center;gap:8px;min-width:0;}
.mod-note{font-size:11px;color:var(--fg-3);line-height:1.6;}
.mod-foot{margin-top:auto;padding-top:12px;}
/* A rule that separates without drawing attention to itself. */
.mod-sep{height:1px;background:var(--hair);margin:13px 0;}

/* KPI strip: the four figures the screen exists to state. */
.kpis{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
.kpi{background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r3);
  padding:14px 15px;min-width:0;position:relative;overflow:hidden;}
.kpi.lead{background:linear-gradient(160deg,rgba(232,182,71,0.09),var(--bg-1) 62%);
  border-color:var(--gold-line);}
.kpi-lbl{font-size:10.5px;letter-spacing:0.12em;text-transform:uppercase;color:var(--fg-3);
  display:block;margin-bottom:7px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
html[lang="fa"] .kpi-lbl,html[lang="ar"] .kpi-lbl{letter-spacing:0;text-transform:none;
  font-size:11.5px;}
.kpi-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:23px;
  font-weight:600;line-height:1.1;color:var(--fg);display:block;
  direction:ltr;unicode-bidi:isolate;}
.kpi.lead .kpi-val{font-size:27px;color:var(--gold-lt);}
.kpi-val.mlc{color:var(--mlc-lt);}
.kpi-sub{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:11px;color:var(--fg-3);
  min-width:0;}
.kpi-delta{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-weight:600;
  direction:ltr;unicode-bidi:isolate;}
.kpi-delta.up{color:var(--up);} .kpi-delta.down{color:var(--down);}
.kpi-spark{position:absolute;inset-inline-end:13px;bottom:11px;opacity:.42;pointer-events:none;}
.kpi-spark svg{display:block;}
.kpi{padding-bottom:16px;}
/* The sub line sits beside the spark, not under it. */
.kpi-sub{padding-inline-end:96px;}
@media(max-width:599px){.kpi-sub{padding-inline-end:0;} .kpi-spark{display:none;}}

@media(min-width:600px){
  .kpis{grid-template-columns:repeat(4,1fr);}
  /* Three tiles inside a module, not four across the page. A new class rather
     than an override on `.kpis`, so the affiliate strip at the top of the board
     keeps the layout it has always had. */
  .kpis-inline{grid-template-columns:repeat(3,1fr);}
}
/* The Current month panel's tiles sit inside a module that already has its own
   padding and heading, so they read as part of it rather than as a second strip:
   a little smaller, and spaced to the module's rhythm. */
.kpis-inline{margin:12px 0 13px;}
.kpis-inline .kpi{padding:12px 13px;}
.kpis-inline .kpi-val{font-size:20px;}
.kpis-inline .kpi.lead .kpi-val{font-size:23px;}
.kpis-inline .kpi-sub{padding-inline-end:0;}
/* Twelve columns from 1024px, which is where the left column disappears. The
   grid used to wait for 1280px because the permanent drawer took ~300px of a
   1024px screen and left a span-4 module about 216px wide — narrower than any
   sidebar in the product. With the menu in the top bar the same screen gives a
   span-4 about 310px, so the boards fill a laptop instead of running on halves. */
/* Every span from 3 to 12 is written out, including the ones nothing uses today.
   A missing class does not fall back to a narrower span — it falls back to
   `grid-column:auto`, which is one column, and the cell renders about a hundred
   pixels wide with its contents cut in half. That cost an afternoon once. */
@media(min-width:1024px){
  .dash{grid-template-columns:repeat(12,1fr);}
  .sp-12{grid-column:span 12;} .sp-9{grid-column:span 9;} .sp-8{grid-column:span 8;}
  .sp-7{grid-column:span 7;} .sp-6{grid-column:span 6;} .sp-5{grid-column:span 5;}
  .sp-4{grid-column:span 4;} .sp-3{grid-column:span 3;}
}
@media(min-width:768px) and (max-width:1023px){
  .dash{grid-template-columns:1fr 1fr;}
  /* In the terminal a nine- or eight-column cell becomes a HALF, not a full row.
     Spanning both columns after a span-1 neighbour would push it onto its own
     row and leave the other half of the previous one empty. */
  .zx .sp-9,.zx .sp-8{grid-column:span 1;}
  .sp-12{grid-column:span 2;} .sp-9,.sp-8,.sp-7{grid-column:span 2;}
  .sp-6,.sp-5,.sp-4,.sp-3{grid-column:span 1;}
}

/* ══════════════════════════════════════════════════════
   AFFILIATE: fast start, legs, balance, packages, sales
   ══════════════════════════════════════════════════════ */

/* Fast start: five stars that fill as directs arrive inside the window. */
.fs-stars{display:flex;gap:7px;align-items:center;margin:2px 0 12px;flex-wrap:wrap;}
.fs-star{width:34px;height:34px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line-2);background:var(--bg-2);color:var(--fg-3);transition:all .35s;}
.fs-star .ic{width:18px;height:18px;}
.fs-star.on{border-color:var(--gold-line);background:var(--gold-pale);color:var(--gold);
  box-shadow:0 0 0 3px var(--gold-pale),0 2px 14px rgba(232,182,71,0.18);}
.fs-star.on .ic{fill:var(--gold);}
.fs-count{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:13px;
  color:var(--fg-2);margin-inline-start:6px;direction:ltr;unicode-bidi:isolate;}

/* Milestone ladder: one live target with a bar, the rest as a compact list. */
.ms-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap;
  margin-bottom:9px;}
.ms-target{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:20px;
  font-weight:600;color:var(--gold-lt);direction:ltr;unicode-bidi:isolate;}
.ms-of{font-size:11.5px;color:var(--fg-3);}
.ms-bar{height:12px;border-radius:6px;background:var(--bg-3);overflow:hidden;
  border:1px solid var(--line-2);}
.ms-fill{height:100%;border-radius:6px;
  background:linear-gradient(90deg,var(--gold-dp),var(--gold),var(--gold-lt));
  transition:width .8s cubic-bezier(.2,.7,.2,1);}
/* Auto-fit rather than a fixed column count: the same row of facts appears in a
   340px module and in a full-width card, and neither should decide the other. */
.factrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(94px,1fr));
  gap:11px 14px;margin-top:11px;}
.factitem{display:flex;flex-direction:column;gap:2px;min-width:0;}
.fact-lbl{font-size:10px;letter-spacing:0.1em;text-transform:uppercase;color:var(--fg-3);}
html[lang="fa"] .fact-lbl,html[lang="ar"] .fact-lbl{letter-spacing:0;text-transform:none;}
.fact-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:13.5px;
  font-weight:600;direction:ltr;unicode-bidi:isolate;}
/* A localized date is words, not a figure: forcing it LTR moves the day to the
   end of the line — so the `.text` variant hands direction back to the page. */
.fact-val.text{font-family:var(--f-body);font-size:12.5px;direction:inherit;
  unicode-bidi:normal;font-weight:500;}
/* Two figures side by side. .wb-grid is a four-up grid and squeezes a pair. */
.fig-2,.fig-3{display:grid;grid-template-columns:1fr;gap:10px;margin-top:12px;}
@media(min-width:520px){.fig-3{grid-template-columns:1fr 1fr;}}
.ms-list{display:flex;flex-direction:column;gap:7px;margin-top:14px;padding-top:12px;
  border-top:1px solid var(--hair);}
.ms-row{display:flex;align-items:center;gap:9px;font-size:12px;}
.ms-row .ic{flex-shrink:0;}
.ms-row .ms-row-amt{font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  direction:ltr;unicode-bidi:isolate;min-width:74px;}
.ms-row-rw{color:var(--fg-3);font-size:11.5px;flex:1;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.ms-reward{display:flex;align-items:flex-start;gap:8px;margin-top:12px;padding:9px 11px;
  border-radius:var(--r2);background:var(--gold-pale);border:1px solid var(--gold-line);
  font-size:11.5px;line-height:1.6;color:var(--gold-lt);}
.ms-reward .ic{width:14px;height:14px;flex-shrink:0;margin-top:2px;}
.ms-row.achieved .ms-row-amt{color:var(--up);}
.ms-row.locked{opacity:.55;}

/* Two legs, side by side, then the balance between them. */
.legs{display:flex;flex-direction:column;gap:2px;}
.leg{display:grid;grid-template-columns:auto 1fr auto auto;gap:11px;align-items:center;
  padding:10px 2px;border-bottom:1px solid var(--hair);}
.leg:last-child{border-bottom:none;}
.leg-name{font-size:12.5px;font-weight:500;}
.leg-heads{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:11.5px;
  color:var(--fg-3);direction:ltr;unicode-bidi:isolate;}
.leg-vol{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:13px;
  font-weight:600;min-width:78px;text-align:end;direction:ltr;unicode-bidi:isolate;}
.leg.alpha .leg-vol{color:var(--gold-lt);}
.leg.beta .leg-vol{color:var(--mlc-lt);}
/* Month mode states growth, so the figures read as additions. */
.leg.month .leg-heads,.leg.month .leg-vol{color:var(--up);}
.leg.month .leg-vol{font-weight:700;}

/* A module wide enough for two columns of package rows should use them. The
   query is on the module, not the viewport, because the same module appears at
   several widths. Without container-query support it stays one column, which is
   what it was before. */
.mod{container-type:inline-size;}
.pkg-list{display:grid;grid-template-columns:1fr;gap:0 22px;}
@container (min-width:520px){
  .pkg-list{grid-template-columns:1fr 1fr;}
}

.bal{display:flex;height:26px;border-radius:var(--r1);overflow:hidden;border:1px solid var(--line-2);
  margin-top:2px;}
.bal-seg{display:flex;align-items:center;justify-content:center;gap:6px;font-size:11.5px;
  font-weight:600;min-width:0;overflow:hidden;white-space:nowrap;transition:flex-basis .8s ease;}
.bal-seg.a{background:linear-gradient(180deg,var(--gold-dp),var(--gold-dk));color:#1A1204;}
.bal-seg.b{background:linear-gradient(180deg,var(--mlc-dp),#2E5A74);color:#F2FAFF;}
.bal-pct{font-family:var(--f-mono);font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate;}
.bal-legend{display:flex;gap:14px;flex-wrap:wrap;margin-top:9px;}
.bal-key{display:flex;align-items:center;gap:7px;font-size:11.5px;color:var(--fg-3);}
.bal-dot{width:9px;height:9px;border-radius:3px;flex-shrink:0;}
.bal-dot.a{background:var(--gold);} .bal-dot.b{background:var(--mlc);}
/* A qualifier hanging off a legend figure — the date a locked balance releases.
   Dimmer than the key it sits in, so the eye reads amount first and condition
   second, and it keeps its own line when the legend wraps on a narrow card. */
.bal-note{color:var(--fg-3);opacity:0.72;font-size:11px;}

/* ══ THE ONCHAIN LEADERBOARD ════════════════════════
   Ordinary house furniture: a card, a data table, chips. Deliberately none of
   the `.zx` terminal's vocabulary — no gold wordmark, no mono wide-tracked
   caps, no live dot — because this page contains no model and must not read as
   though it does.

   It is also the one surface where fa and ar are the point rather than a
   translation, so everything here is logical-property only and every figure
   carries its own bidi isolate. */
.hl-notice{
  display:flex;align-items:flex-start;gap:9px;flex-wrap:wrap;
  background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r2);
  padding:11px 13px;margin:12px 0;font-size:12px;color:var(--fg-2);line-height:1.65;
}
.hl-notice .ic{width:15px;height:15px;flex:none;color:var(--fg-3);margin-top:2px;}
.hl-notice span{flex:1 1 260px;min-width:0;}
.hl-method{flex:none;font-size:12px;}

.hl-meta{
  display:flex;gap:14px;flex-wrap:wrap;margin-bottom:11px;
  font-size:11px;color:var(--fg-3);
}
.hl-stale{margin-bottom:12px;}

/* An address is never allowed to reverse inside an RTL sentence. `dir="ltr"`
   alone does not do it — without the isolate the surrounding paragraph level
   still owns the run, and 0x… comes out scrambled. */
.hl-addr{display:inline-flex;align-items:center;gap:6px;min-width:0;}
.hl-addr-t{
  font-family:var(--f-mono);font-size:12px;color:var(--fg);
  direction:ltr;unicode-bidi:isolate;white-space:nowrap;
}
.hl-copy{
  appearance:none;background:none;border:0;padding:2px;cursor:pointer;
  color:var(--fg-3);display:inline-flex;flex:none;border-radius:var(--r1);
}
.hl-copy:hover{color:var(--gold);}
.hl-copy .ic{width:13px;height:13px;}

/* Drawdown is a figure the reader is meant to weigh, not skim past — so it is
   set at full foreground, the same weight the profit beside it carries. It was
   `--fg-2`, which is the colour this sheet uses for a figure you are allowed to
   skim, and that is the opposite of what this column is for: a row whose risk
   reads as secondary to its profit is the exact misreading the module exists to
   prevent. The colour stays neutral rather than scaling with severity, because
   a red-for-bad ramp would be the sheet passing judgement on the number. */
.hl-dd{color:var(--fg);}

.hl-flags{display:flex;gap:5px;flex-wrap:wrap;}
.hl-flag{
  font-size:10px;letter-spacing:0.04em;padding:2px 7px;border-radius:999px;
  background:var(--bg-3);border:1px solid var(--line-2);color:var(--fg-3);
  white-space:nowrap;cursor:help;
}
.hl-flag:focus-visible{outline:2px solid var(--gold);outline-offset:1px;}
html[lang="fa"] .hl-flag,html[lang="ar"] .hl-flag{letter-spacing:0;}

/* ── THE PHONE CARD ──
   Profit, drawdown and the badges all survive here. That is the requirement,
   and it is why this is a purpose-built card rather than the table with
   columns hidden — a hidden column is exactly how drawdown would have been the
   thing that disappeared on a small screen. */
.hl-cards{display:flex;flex-direction:column;gap:9px;}
.hl-card{
  background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r2);padding:11px 12px;
}
.hl-card-top{display:flex;align-items:center;gap:9px;margin-bottom:9px;min-width:0;}
.hl-rank{
  font-size:12px;color:var(--fg-3);min-width:22px;
  direction:ltr;unicode-bidi:isolate;
}
.hl-card-figs{display:grid;grid-template-columns:1fr 1fr;gap:9px;}
.hl-card-figs > div{display:flex;flex-direction:column;gap:2px;min-width:0;}
.hl-k{font-size:10px;letter-spacing:0.09em;text-transform:uppercase;color:var(--fg-3);}
html[lang="fa"] .hl-k,html[lang="ar"] .hl-k{letter-spacing:0;text-transform:none;font-size:11px;}
.hl-v{
  font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:13px;font-weight:600;
  direction:ltr;unicode-bidi:isolate;
}
.hl-card-flags{margin-top:9px;}

.hl-method-body{font-size:13px;line-height:1.75;color:var(--fg-2);}
.hl-method-body p{margin:0 0 11px;}

/* The table is the desktop view and the cards are the phone one. Both rules
   sit together, before the media query, because a media query carries no extra
   specificity and a later flat rule would beat it. */
.hl-table-wrap{display:none;}
.hl-cards{display:flex;}
@media(min-width:768px){
  .hl-table-wrap{display:block;}
  .hl-cards{display:none;}
}

/* Package mix across the team */
.pkg-bar{display:flex;height:14px;border-radius:7px;overflow:hidden;border:1px solid var(--line-2);
  margin-bottom:14px;}
.pkg-seg{min-width:2px;transition:flex-basis .8s ease;}
.pkg-seg.silver{background:var(--pkg-silver);}
.pkg-seg.gold{background:var(--pkg-gold);}
.pkg-seg.platinum{background:var(--pkg-platinum);}
.pkg-seg.black{background:var(--pkg-black);}
.pkg-row{display:grid;grid-template-columns:auto 1fr auto auto;gap:10px;align-items:center;
  padding:8px 2px;border-bottom:1px solid var(--hair);font-size:12.5px;}
.pkg-row:last-child{border-bottom:none;}
.pkg-key{width:11px;height:11px;border-radius:3px;flex-shrink:0;}
.pkg-count{font-family:var(--f-mono);font-variant-numeric:tabular-nums;color:var(--fg-2);
  direction:ltr;unicode-bidi:isolate;}
.pkg-pct{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-weight:600;
  min-width:52px;text-align:end;direction:ltr;unicode-bidi:isolate;}

/* Small screens: give the content the padding back, and let the four-column
   sales table fit instead of scrolling inside its box. */
@media(max-width:479px){
  .mod{padding:13px 13px;}
  .kpi{padding:12px 13px;}
  .kpi-val{font-size:21px;} .kpi.lead .kpi-val{font-size:24px;}
  .dt.dt-sm{min-width:0;font-size:11.5px;}
  .dt.dt-sm th,.dt.dt-sm td{padding:9px 6px;}
  .fs-star{width:31px;height:31px;}
  .fs-star .ic{width:16px;height:16px;}
}
/* Wide desktops get air, not bigger boxes. */
@media(min-width:1600px){
  .dash{gap:16px;}
  .kpi{padding:16px 18px;}
  .kpi-val{font-size:25px;} .kpi.lead .kpi-val{font-size:30px;}
  .mod{padding:17px 18px;}
}

/* Sales history: stacked bars per month, five to a page */
.sales-total{display:flex;gap:16px;flex-wrap:wrap;align-items:baseline;}
.deskbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:11px 14px;
  border:1px dashed var(--line-2);border-radius:var(--r2);background:transparent;}
.deskbar-lbl{font-size:11px;color:var(--fg-3);margin-inline-end:auto;}
.st-item{display:flex;align-items:baseline;gap:7px;font-size:11.5px;color:var(--fg-3);}
.st-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:14px;font-weight:600;
  color:var(--fg);direction:ltr;unicode-bidi:isolate;}
.st-val.gold{color:var(--gold-lt);} .st-val.mlc{color:var(--mlc-lt);}
/* Bonus paid is MILO Coin, and every other MLC figure on this board is tinted.
   Scoped to the cell rather than added as a bare `.mlc`, which does not exist —
   every use of the class in this sheet is qualified by the element it colours. */
.dt .cell-num b.mlc{color:var(--mlc-lt);font-weight:600;}
.bar-a{fill:url(#barGold);} .bar-b{fill:url(#barBlue);}
.bar-lbl{font-family:var(--f-mono);font-size:9.5px;fill:var(--fg-3);}
.bar-val{font-family:var(--f-mono);font-size:10px;fill:var(--fg-2);font-weight:600;}

/* Downline signups */
.dl-row{display:grid;grid-template-columns:auto 1fr auto;gap:10px;align-items:center;
  padding:9px 2px;border-bottom:1px solid var(--hair);}
.dl-row:last-child{border-bottom:none;}
.dl-text{display:flex;flex-direction:column;min-width:0;gap:2px;}
.dl-name{font-size:12.5px;font-weight:500;}
.dl-meta{font-size:10.5px;color:var(--fg-3);}
.dl-acct{font-family:var(--f-mono);font-size:10px;color:var(--fg-3);direction:ltr;unicode-bidi:isolate;}
.dl-end{display:flex;flex-direction:column;align-items:flex-end;gap:4px;}
.dl-amt{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:12.5px;
  font-weight:600;color:var(--gold-lt);direction:ltr;unicode-bidi:isolate;}

/* ══════════════════════════════════════════════════════
   CONTRACT PACKAGES
   The activation page's package cards, brought into the dashboard for the New
   contract flow. Same anatomy — head, range, historical return, features, CTA —
   with the accent colour set per package through one custom property, so a fifth
   package needs a colour and nothing else.
   ══════════════════════════════════════════════════════ */
.pkg-grid{display:grid;gap:12px;grid-template-columns:1fr;margin-bottom:18px;}
@media(min-width:640px){.pkg-grid{grid-template-columns:1fr 1fr;}}
@media(min-width:1200px){.pkg-grid{grid-template-columns:repeat(3,1fr);}}
.pkg{background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r3);padding:18px;
  position:relative;text-align:start;width:100%;display:block;
  transition:border-color .3s,background .3s,transform .3s var(--ease),box-shadow .3s;}
.pkg:hover:not(.locked){border-color:var(--line);background:var(--bg-2);transform:translateY(-2px);}
.pkg.selected{border-color:var(--gold-line);background:var(--gold-pale);
  box-shadow:0 12px 40px rgba(232,182,71,.10);}
.pkg.locked{opacity:.5;}
.pkg::before{content:'';position:absolute;top:-1px;inset-inline:18px;height:2px;background:var(--tier);
  opacity:0;transition:opacity .3s;}
.pkg.selected::before{opacity:1;}
.pkg.bronze{--tier:var(--tier-bronze);}
.pkg.silver{--tier:var(--tier-silver);}
.pkg.gold{--tier:var(--tier-gold);}
.pkg.platinum{--tier:var(--tier-platinum);}
.pkg.black{--tier:var(--tier-black);}
.pkg-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;}
.pkg-tier{font-family:var(--f-display);font-weight:700;font-size:19px;color:var(--tier);
  display:block;margin-bottom:3px;}
.pkg-range{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:11.5px;
  color:var(--fg-3);display:block;margin-bottom:13px;direction:ltr;unicode-bidi:isolate;}
.pkg-badge{font-size:9.5px;letter-spacing:0.1em;padding:4px 9px;border-radius:var(--r1);
  background:var(--gold);color:var(--on-gold);font-weight:700;flex-shrink:0;}
.pkg-entry{font-size:9.5px;letter-spacing:0.1em;padding:4px 9px;border-radius:var(--r1);
  background:rgba(192,132,87,.16);color:var(--tier-bronze);font-weight:700;flex-shrink:0;
  border:1px solid rgba(192,132,87,.4);}
html[lang="fa"] .pkg-badge,html[lang="ar"] .pkg-badge,
html[lang="fa"] .pkg-entry,html[lang="ar"] .pkg-entry{letter-spacing:0;}
.pkg-lock{display:none;align-items:center;gap:7px;font-size:11.5px;color:var(--warn);
  background:var(--warn-pale);border:1px solid var(--warn-line);border-radius:var(--r1);
  padding:6px 10px;margin-bottom:11px;}
.pkg.locked .pkg-lock{display:flex;}
.pkg-lock .ic{width:12px;height:12px;}
/* A span by necessity — the card is a button, so it may hold no block elements —
   which means every part of it has to be told to behave like one. */
.pkg-return{display:block;margin:12px 0;padding:12px;background:var(--bg-0);border-radius:var(--r2);
  border:1px solid var(--hair);}
.pkg-return-label{font-size:10px;letter-spacing:0.1em;text-transform:uppercase;color:var(--fg-3);
  display:block;margin-bottom:5px;}
html[lang="fa"] .pkg-return-label,html[lang="ar"] .pkg-return-label{letter-spacing:0;text-transform:none;}
.pkg-return-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:21px;
  font-weight:600;color:var(--fg);display:block;direction:ltr;unicode-bidi:isolate;}
.pkg-return-period{font-size:10.5px;color:var(--fg-3);margin-top:3px;display:block;}
.pkg-features{list-style:none;display:flex;flex-direction:column;gap:6px;margin-top:12px;}
.pkg-features li{font-size:11.5px;color:var(--fg-3);display:flex;align-items:center;gap:8px;
  line-height:1.5;}
.pkg-features li::before{content:'';width:4px;height:4px;border-radius:50%;background:var(--tier);
  flex-shrink:0;}
.pkg-cta{display:block;width:100%;margin-top:15px;padding:11px;border-radius:var(--r1);
  font-size:12.5px;text-align:center;border:1px solid var(--line-2);color:var(--fg-2);
  min-height:42px;transition:all .3s;}
.pkg.selected .pkg-cta{background:linear-gradient(145deg,var(--gold-lt),var(--gold-dp));
  border-color:var(--gold);color:var(--on-gold);font-weight:700;}

/* The ladder: the same five packages as one row, with the reader's own step
   marked. It is a summary, not a control — the CTA under it is the control. */
.ladder{display:flex;gap:6px;align-items:stretch;margin:14px 0 12px;}
.ladder-step{flex:1;min-width:0;padding:10px 8px;border-radius:var(--r2);background:var(--bg-1);
  border:1px solid var(--line-2);text-align:center;position:relative;}
.ladder-step.on{border-color:var(--tier);background:rgba(255,255,255,.03);}
/* A step the wallet can reach is a button into that package; one it cannot is
   left plain, because there is nothing behind it to open. */
button.ladder-step{cursor:pointer;transition:border-color .2s,background .2s,transform .2s;}
button.ladder-step:hover{border-color:var(--tier);background:var(--bg-2);transform:translateY(-2px);}
.ladder-step.off{opacity:.55;}
.ladder-step.next{border-color:var(--gold-line);background:var(--gold-pale);}
/* Two lines rather than an ellipsis: the longest package name needs the second
   one in every language, and a truncated package name is worse than a taller
   step. */
.ladder-name{display:block;font-size:11px;font-weight:600;color:var(--tier);line-height:1.3;}
.ladder-ret{display:block;font-family:var(--f-mono);font-size:10px;color:var(--fg-3);
  margin-top:3px;direction:ltr;unicode-bidi:isolate;}
.ladder-tag{display:block;font-size:9.5px;color:var(--gold-lt);margin-top:4px;}
.ladder-step.bronze{--tier:var(--tier-bronze);}
.ladder-step.silver{--tier:var(--tier-silver);}
.ladder-step.gold{--tier:var(--tier-gold);}
.ladder-step.platinum{--tier:var(--tier-platinum);}
.ladder-step.black{--tier:var(--tier-black);}
/* Five steps need about 60px each. On a phone, and in the narrow column the
   ladder sits in between 1024 and 1279, they wrap three and two instead. */
@media(max-width:479px),(min-width:1024px) and (max-width:1279px){
  .ladder{flex-wrap:wrap;}
  .ladder-step{flex:1 1 30%;}
}

/* A contract row, in the list of everything the account holds. */
.ct-row{display:flex;align-items:center;gap:12px;width:100%;padding:12px;border-radius:var(--r2);
  background:var(--bg-1);border:1px solid var(--line-2);text-align:start;margin-bottom:8px;
  transition:border-color .2s,background .2s;}
.ct-row:hover{border-color:var(--line);background:var(--bg-2);}
.ct-row.on{border-color:var(--gold-line);background:var(--gold-pale);}
.ct-mid{flex:1;min-width:0;}
.ct-no{font-family:var(--f-mono);font-size:11px;color:var(--fg-3);direction:ltr;unicode-bidi:isolate;
  display:block;}
.ct-meta{font-size:11px;color:var(--fg-3);margin-top:3px;}
.ct-end{display:flex;flex-direction:column;align-items:flex-end;gap:3px;flex-shrink:0;}
.ct-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:13.5px;
  font-weight:600;color:var(--gold-lt);direction:ltr;unicode-bidi:isolate;}
.ct-sub{font-size:10.5px;color:var(--fg-3);}

/* ══════════════════════════════════════════════════════
   GALAXY — the binary genealogy as a canvas
   Two views of one tree: nodes floating free, or three structured levels you
   drill through. Node position comes from three custom properties set per node
   (--x, --y, --sz) instead of a style string per node, so the paint rules and
   every animation live here.

   Which animated property does what, because they must not collide:
     translate  → the endless drift of a free-floating node
     scale      → the entrance, once, when a view is built
     ::before   → the breathing glow (its own opacity and scale)
     box-shadow → hover, so it never touches a transform
   ══════════════════════════════════════════════════════ */
.gx{position:relative;}

/* Toolbar. From 768px it floats over the canvas on glass, which is the whole
   point of the view; on a phone it sits above instead, because overlaid it would
   cover most of a 430px-tall stage. */
.gx-bar{display:flex;flex-direction:column;gap:9px;margin-bottom:10px;}
.gx-bar-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.gx-bar-row .seg{margin-inline-end:auto;}
.gx-stats{display:flex;align-items:center;gap:14px;flex-wrap:wrap;min-width:0;}
.gx-stat{display:flex;align-items:baseline;gap:6px;font-size:10.5px;color:var(--fg-3);}
.gx-stat-val{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:14px;
  font-weight:600;color:var(--fg);direction:ltr;}
.gx-stat.up .gx-stat-val{color:var(--up);}
.gx-stat.gold .gx-stat-val{color:var(--gold-lt);}
.gx-keys{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-inline-start:auto;}
.gx-key{display:flex;align-items:center;gap:6px;font-size:10.5px;color:var(--fg-3);}
.gx-key-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;}
.gx-key.alpha .gx-key-dot{background:var(--leg-alpha);box-shadow:0 0 8px rgba(var(--leg-alpha-rgb),.7);}
.gx-key.beta .gx-key-dot{background:var(--leg-beta);box-shadow:0 0 8px rgba(var(--leg-beta-rgb),.7);}
.gx-key.root .gx-key-dot{background:var(--leg-root);box-shadow:0 0 8px rgba(var(--leg-root-rgb),.6);}
.gx-tool{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;
  border-radius:var(--r2);border:1px solid var(--line);background:var(--bg-2);color:var(--fg-2);
  transition:color .2s,border-color .2s,background .2s;}
.gx-tool:hover{color:var(--fg);border-color:var(--gold-line);}
.gx-tool[aria-pressed="true"]{color:var(--gold-lt);border-color:var(--gold-line);background:var(--gold-pale);}
.gx-search{display:flex;align-items:center;gap:8px;width:100%;}
.gx-search .tin{flex:1;min-width:0;}
.gx-res{display:flex;flex-direction:column;gap:5px;margin-top:2px;}
.gx-res-row{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:8px 11px;border-radius:var(--r2);border:1px solid var(--line-2);background:var(--bg-2);
  font-size:12.5px;text-align:start;}
.gx-res-row:hover{border-color:var(--gold-line);}
.gx-res-id{font-family:var(--f-mono);font-size:10.5px;color:var(--fg-3);direction:ltr;}
.gx-count{font-family:var(--f-mono);font-variant-numeric:tabular-nums;direction:ltr;}

/* Breadcrumb, and the two controls the design had pinned to the bottom-left of
   the viewport — which here is exactly where the bottom tab bar lives. They
   belong beside the path they act on. */
.gx-path{display:flex;align-items:center;gap:7px;flex-wrap:wrap;}
.gx-crumb{font-size:11px;color:var(--fg-3);padding:3px 2px;transition:color .2s;}
.gx-crumb:hover{color:var(--fg-2);}
.gx-crumb.on{color:var(--gold-lt);font-weight:600;}
.gx-crumb-sep{color:var(--bg-4);font-size:11px;}
.gx-nav{display:flex;gap:7px;margin-inline-start:auto;}
.gx-navbtn{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:var(--r2);
  border:1px solid var(--gold-line);background:var(--gold-pale);color:var(--gold-lt);
  font-size:11.5px;font-weight:600;min-height:34px;}
.gx-navbtn:hover{background:rgba(232,182,71,0.16);}
.gx-navbtn[disabled]{opacity:.4;pointer-events:none;}

/* ── Stage ── */
.gx-stage{position:relative;overflow:hidden;isolation:isolate;
  height:min(72vh,560px);min-height:430px;
  border-block:1px solid var(--line-2);background:var(--bg-1);
  /* Full width on a phone: the canvas reaches the screen edge by cancelling the
     content padding, and gets its border and corners back at 600px. */
  margin-inline:-14px;}
.gx-stage:focus-visible{outline:2px solid var(--gold);outline-offset:-2px;}

/* Layers, back to front: grid, scanlines, star field, leg glows, links, nodes. */
.gx-grid,.gx-scan{position:absolute;inset:0;pointer-events:none;}
.gx-grid{background-image:linear-gradient(rgba(232,182,71,.022) 1px,transparent 1px),
  linear-gradient(90deg,rgba(232,182,71,.022) 1px,transparent 1px);background-size:34px 34px;}
.gx-scan{z-index:5;background-image:repeating-linear-gradient(0deg,rgba(255,255,255,.016) 0px,
  rgba(255,255,255,.016) 1px,transparent 1px,transparent 3px);}
.gx-star{position:absolute;border-radius:50%;background:#fff;opacity:.3;pointer-events:none;
  animation:gx-twinkle var(--dur) ease-in-out infinite;animation-delay:var(--delay);}
.gx-meteor{position:absolute;height:1.5px;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.85),transparent);
  animation:gx-meteor var(--dur) linear infinite;animation-delay:var(--delay);}
.gx-meteor.gold{background:linear-gradient(90deg,transparent,rgba(232,182,71,.8),transparent);height:1px;}
[dir="rtl"] .gx-meteor{transform:scaleX(-1);}
.gx-core{position:absolute;left:50%;top:var(--y);width:min(520px,86%);aspect-ratio:1;
  transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(var(--leg-root-rgb),.10),rgba(var(--leg-root-rgb),.03) 45%,transparent 70%);
  transition:top .8s var(--ease);}
.gx-glow{position:absolute;bottom:-8%;width:min(300px,58%);aspect-ratio:1;border-radius:50%;
  pointer-events:none;transition:opacity .6s;}
/* Physical sides, not logical ones: a node's x is a plain `left` percentage, so
   alpha is drawn on the left of the canvas in every language. Logical properties
   put the gold glow on the right in Arabic and Persian — under beta's nodes,
   telling the reader the opposite of the truth about which side is which. */
.gx-glow.alpha{left:-8%;
  background:radial-gradient(circle,rgba(var(--leg-alpha-rgb),.13),transparent 68%);}
.gx-glow.beta{right:-8%;
  background:radial-gradient(circle,rgba(var(--leg-beta-rgb),.13),transparent 68%);}

.gx-links{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;
  transition:opacity .5s;}
.gx-link{stroke-width:1;stroke-dasharray:4 4;animation:gx-flow 1.6s linear infinite;}
.gx-link.draw{animation:gx-flow 1.6s linear infinite,gx-draw .6s ease-out both;}

/* ── A node ── */
.gx-node{position:absolute;left:var(--x);top:var(--y);width:var(--sz);height:var(--sz);
  margin-inline-start:calc(var(--sz) / -2);margin-top:calc(var(--sz) / -2);
  border-radius:50%;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:1px;line-height:1.1;color:var(--n-color);
  border:1.5px solid var(--n-color);
  background:radial-gradient(circle at 34% 28%,rgba(var(--n-rgb),.28),rgba(0,0,0,.93) 68%);
  box-shadow:0 0 14px rgba(var(--n-rgb),.45),0 0 40px rgba(var(--n-rgb),.16),
    inset 0 0 16px rgba(var(--n-rgb),.16);
  animation:gx-enter .5s var(--ease) both,gx-drift var(--drift-dur,16s) ease-in-out infinite;
  animation-delay:var(--delay,0s),var(--delay,0s);
  transition:box-shadow .25s,border-color .25s,filter .25s,opacity .4s;
  z-index:var(--z,20);}
/* The breathing glow lives on a pseudo element so the node's own transform
   properties stay free for the drift and the entrance. */
.gx-node::before{content:'';position:absolute;inset:-3px;border-radius:50%;pointer-events:none;
  box-shadow:0 0 18px rgba(var(--n-rgb),.35);
  animation:gx-breathe var(--breathe-dur,5s) ease-in-out infinite;animation-delay:var(--delay,0s);}
.gx-node:hover{filter:brightness(1.18);
  box-shadow:0 0 20px rgba(var(--n-rgb),.7),0 0 56px rgba(var(--n-rgb),.28),
    inset 0 0 18px rgba(var(--n-rgb),.2);}
.gx-node.dim{opacity:.2;filter:saturate(.4) blur(1px);}
.gx-node.self{--n-color:var(--leg-root);--n-rgb:var(--leg-root-rgb);}
.gx-node.alpha{--n-color:var(--leg-alpha);--n-rgb:var(--leg-alpha-rgb);}
.gx-node.beta{--n-color:var(--leg-beta);--n-rgb:var(--leg-beta-rgb);}
/* Tree mode is a diagram, not a nebula: the nodes hold still. */
.gx-stage.tree .gx-node{animation:gx-enter .5s var(--ease) both;animation-delay:var(--delay,0s);}
.gx-stage.tree .gx-node::before{animation:none;}

.gx-node-lbl{font-family:var(--f-mono);font-size:var(--fs,11px);font-weight:600;letter-spacing:.5px;
  direction:ltr;text-shadow:0 0 8px rgba(0,0,0,.9);}
.gx-tick{font-family:var(--f-mono);font-size:7px;letter-spacing:1.4px;opacity:.9;direction:ltr;}
/* Arabic and Persian letters do not join in a monospace face, and a four-letter
   Latin abbreviation is not what these languages abbreviate to — so the tick
   drops the mono, the tracking and the forced direction, and gains a little
   size to stay legible at this scale. */
html[lang="fa"] .gx-tick,html[lang="ar"] .gx-tick{font-family:var(--f-body);font-size:8.5px;
  letter-spacing:0;direction:inherit;}
.gx-tick.silver{color:var(--tier-silver);} .gx-tick.gold{color:var(--tier-gold);}
.gx-tick.platinum{color:var(--tier-platinum);} .gx-tick.black{color:var(--gold-lt);}
.gx-dot{position:absolute;inset-inline-end:-2px;bottom:-2px;width:11px;height:11px;border-radius:50%;
  border:2px solid var(--bg-0);}
.gx-dot.on{background:var(--up);box-shadow:0 0 9px var(--up);}
.gx-dot.off{background:var(--down);box-shadow:0 0 9px var(--down);}
.gx-tag{position:absolute;inset-inline-start:-7px;top:-7px;width:16px;height:16px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;background:var(--bg-0);
  border:1px solid var(--n-color);font-family:var(--f-mono);font-size:9px;font-weight:600;
  direction:ltr;}
.gx-crown{position:absolute;top:-13px;left:50%;transform:translateX(-50%);width:13px;height:13px;
  color:var(--gold-lt);filter:drop-shadow(0 0 5px rgba(232,182,71,.8));}
.gx-crown .ic{width:13px;height:13px;stroke-width:1.9;}
/* The reader's own node keeps its orbit, so the eye finds itself first. */
.gx-orbit{position:absolute;inset:-13px;border-radius:50%;pointer-events:none;
  border:1px solid rgba(var(--leg-root-rgb),.34);
  border-top-color:rgba(var(--leg-root-rgb),.95);border-inline-end-color:transparent;
  animation:gx-orbit 7s linear infinite;}
/* A node the search jumped to pulses until the eye lands on it. */
.gx-ping{position:absolute;inset:0;border-radius:50%;pointer-events:none;
  border:1.5px solid var(--n-color);animation:gx-ring 1.5s ease-out infinite;}

/* An open placement slot */
.gx-node.ghost{border-style:dashed;background:rgba(var(--n-rgb),.05);
  box-shadow:0 0 14px rgba(var(--n-rgb),.14);animation:gx-enter .5s var(--ease) both;}
.gx-node.ghost::before{animation:none;box-shadow:none;}
.gx-node.ghost .ic{width:15px;height:15px;}
.gx-open{position:absolute;top:calc(100% + 5px);left:50%;transform:translateX(-50%);
  font-size:9px;letter-spacing:1.2px;color:rgba(14,203,129,.9);white-space:nowrap;}

/* Depth meter, and the one-line hint the design carried */
.gx-depth{position:absolute;inset-inline-end:12px;top:50%;transform:translateY(-50%);z-index:6;
  display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none;}
.gx-depth-cap{font-size:9px;letter-spacing:.6px;color:var(--fg-3);text-transform:uppercase;}
html[lang="fa"] .gx-depth-cap,html[lang="ar"] .gx-depth-cap{text-transform:none;letter-spacing:0;
  font-size:9.5px;}
.gx-depth-lbl{font-family:var(--f-mono);font-size:10px;letter-spacing:.5px;color:var(--fg-2);
  direction:ltr;}
.gx-depth-track{width:3px;height:104px;border-radius:2px;background:var(--bg-4);position:relative;}
.gx-depth-fill{position:absolute;top:0;inset-inline-start:0;width:3px;border-radius:2px;
  background:linear-gradient(180deg,var(--gold-lt),var(--gold-dp));
  box-shadow:0 0 10px var(--gold-glow);transition:height .6s var(--ease);}
.gx-hint{position:absolute;inset-inline:0;bottom:12px;z-index:6;text-align:center;
  font-size:10.5px;letter-spacing:.4px;color:var(--fg-3);pointer-events:none;padding:0 12px;}

@keyframes gx-twinkle{0%,100%{opacity:.15}50%{opacity:.75}}
@keyframes gx-meteor{0%{translate:0 0;opacity:0}8%{opacity:.9}60%{opacity:.5}
  100%{translate:128vw 46vh;opacity:0}}
@keyframes gx-breathe{0%,100%{scale:1;opacity:.85}50%{scale:1.07;opacity:1}}
@keyframes gx-drift{0%,100%{translate:0 0}33%{translate:9px -12px}66%{translate:-11px 7px}}
@keyframes gx-orbit{from{rotate:0deg}to{rotate:360deg}}
@keyframes gx-ring{0%{scale:1;opacity:.85}70%{scale:2.1;opacity:0}100%{scale:2.1;opacity:0}}
@keyframes gx-flow{to{stroke-dashoffset:-40}}
@keyframes gx-draw{from{opacity:0}to{opacity:1}}
@keyframes gx-enter{from{opacity:0;scale:.55}to{opacity:1;scale:1}}

/* The member sheet: identity rows, the two placement slots, and the invite */
.gx-who{display:flex;align-items:center;gap:12px;margin-bottom:14px;}
.gx-who .avatar{width:44px;height:44px;font-size:13px;flex-shrink:0;}
.gx-who-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;}
.gx-live{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--fg-3);}
.gx-live-dot{width:7px;height:7px;border-radius:50%;background:var(--up);box-shadow:0 0 8px var(--up);}
.gx-live.off .gx-live-dot{background:var(--down);box-shadow:0 0 8px var(--down);}
/* A value that is a localized word or date, not a figure: body font, and it
   keeps the page direction so the day does not slide to the end of the line. */
.kv-v.text{font-family:var(--f-body);direction:inherit;unicode-bidi:normal;}
.kv-v.row{display:inline-flex;align-items:center;gap:8px;}
.gx-copy{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;
  border-radius:var(--r1);border:1px solid var(--line);color:var(--fg-3);flex-shrink:0;}
.gx-copy:hover{color:var(--gold-lt);border-color:var(--gold-line);background:var(--gold-pale);}
.gx-copy .ic{width:14px;height:14px;}
.gx-slots{display:grid;gap:8px;}
/* An empty or pending position is a button into its own invitation, a filled one
   is a plain row. Both wear the same shape, so the list still reads as one thing. */
.gx-slot{display:flex;align-items:center;gap:10px;padding:11px 13px;border-radius:var(--r2);
  border:1px solid var(--line-2);background:var(--bg-2);width:100%;text-align:start;
  transition:border-color .2s,background .2s;}
button.gx-slot:hover{border-color:var(--gold-line);}
.gx-slot-go{width:15px;height:15px;opacity:.65;flex-shrink:0;}
.avatar.gx-empty{border:1.5px dashed var(--up-line);background:var(--up-pale);color:var(--up);}
.gx-slot-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;}
.gx-slot-name{font-weight:600;font-size:12.5px;}
.gx-slot-state{margin-inline-start:auto;font-size:11px;text-align:end;}
.gx-slot.filled{border-color:var(--line);}
.gx-slot.filled .gx-slot-dot{background:var(--fg-3);}
.gx-slot.filled .gx-slot-state{color:var(--fg-2);}
.gx-slot.open{border-color:var(--up-line);background:var(--up-pale);}
.gx-slot.open .gx-slot-dot{background:var(--up);box-shadow:0 0 9px var(--up);}
.gx-slot.open .gx-slot-state{color:var(--up);}
.gx-slot.pending{border-color:var(--warn-line);background:var(--warn-pale);}
.gx-slot.pending .gx-slot-dot{background:var(--warn);box-shadow:0 0 9px var(--warn);}
.gx-slot.pending .gx-slot-state{color:var(--warn);}
.gx-inv{display:grid;gap:8px;}
@media(min-width:420px){.gx-inv.two{grid-template-columns:1fr 1fr;}}
.gx-sheet-note{font-size:11px;color:var(--fg-3);line-height:1.7;margin-top:10px;}
/* Register: one door per leg, side by side so the two legs read as the pair they
   are, each carrying the position it would fill under its own label. */
.gx-ends{display:grid;gap:8px;}
@media(min-width:420px){.gx-ends{grid-template-columns:1fr 1fr;}}
.gx-end{display:flex;flex-direction:column;align-items:flex-start;gap:4px;width:100%;
  padding:11px 13px;border-radius:var(--r2);text-align:start;
  border:1px solid rgba(var(--leg-alpha-rgb),.3);background:rgba(var(--leg-alpha-rgb),.07);
  transition:border-color .2s,background .2s,transform .2s;}
.gx-end.beta{border-color:rgba(var(--leg-beta-rgb),.3);background:rgba(var(--leg-beta-rgb),.07);}
.gx-end:hover{transform:translateY(-1px);border-color:rgba(var(--leg-alpha-rgb),.6);}
.gx-end.beta:hover{border-color:rgba(var(--leg-beta-rgb),.6);}
.gx-end-top{display:flex;align-items:center;gap:7px;font-weight:700;font-size:12.5px;
  color:var(--leg-alpha);}
.gx-end.beta .gx-end-top{color:var(--leg-beta);}
.gx-end-top .ic{width:14px;height:14px;}
/* Where the person lands. A localized line with a Latin name in it: body font,
   page direction, and the name isolated by `.iso`. */
.gx-end-sub{font-family:var(--f-body);font-size:11px;color:var(--fg-3);line-height:1.6;}

@media(min-width:600px){
  .gx-stage{margin-inline:0;border:1px solid var(--line-2);border-radius:var(--r3);}
}
@media(min-width:768px){
  /* Room enough to float the controls over the canvas, which is the point of
     this view: the network fills the frame and the chrome sits on glass. */
  .gx-stage{height:min(76vh,660px);}
  .gx-bar{position:absolute;inset-inline:0;top:0;z-index:7;margin:0;padding:12px 16px 16px;
    background:linear-gradient(180deg,rgba(10,12,16,.94) 58%,rgba(10,12,16,.55) 82%,transparent);
    pointer-events:none;}
  .gx-bar > *{pointer-events:auto;}
  .gx-bar-row{pointer-events:none;}
  .gx-bar-row > *{pointer-events:auto;}
}
@media(min-width:1024px){
  /* Fill the laptop: everything above the stage is the screen head and the tab
     strip, and the stage takes what is left. */
  .gx-stage{height:calc(100dvh - var(--topbar-h) - 196px);min-height:520px;}
}
@media(min-width:1600px){
  .gx-stage{min-height:640px;}
}
/* Motion is decoration here, never information: with it off, every node keeps
   its position, its colour and its label. */
@media(prefers-reduced-motion:reduce){
  .gx-star,.gx-meteor,.gx-orbit,.gx-ping,.gx-link{animation:none !important;}
  .gx-star{opacity:.35;} .gx-meteor{display:none;}
}

/* ══════════════════════════════════════════════════════
   RESPONSIVE
   ══════════════════════════════════════════════════════ */
@media(min-width:600px){
  .tb-tag{display:block;}
  .center{padding:20px 20px 30px;}
  .hero-grid{grid-template-columns:repeat(4,1fr);}
  .stat-grid{grid-template-columns:repeat(4,1fr);}
  .hero-amount{font-size:40px;}
  /* A NARROW DROPDOWN WHERE THERE IS A POINTER. Same edge, same direction —
     what changes is that it stops being the width of the screen and becomes a
     panel under its own button. No grip, because there is nothing to drag with
     a mouse, and no scrim: dimming a whole workspace to show six lines is
     theatre on a screen this size. */
  .notif-panel{inset-inline:auto;inset-inline-end:12px;width:400px;
    top:calc(var(--topbar-h) + 6px);
    border:1px solid var(--line);border-radius:var(--r3);
    box-shadow:0 20px 60px rgba(0,0,0,.7);
    transform:none;max-height:min(70vh,520px);
    display:none;transition:none;}
  .notif-panel.open{display:flex;animation:menuIn .22s var(--ease);}
  .notif-grip{display:none;}
  .screen-title{font-size:28px;}
  .month-strip{grid-template-columns:repeat(24,1fr);}
  .sheet{inset-inline:auto;left:50%;bottom:auto;top:50%;width:min(560px,92vw);
    transform:translate(-50%,-46%) scale(.96);opacity:0;border-radius:var(--r3);
    border:1px solid var(--line);transition:opacity .26s var(--ease),transform .26s var(--ease);}
  .sheet.open{transform:translate(-50%,-50%) scale(1);opacity:1;}
  .sheet-grip{display:none;}
  .payment-methods{grid-template-columns:repeat(2,1fr);}
  .wb-grid{grid-template-columns:repeat(4,1fr);}
  .dep-grid{grid-template-columns:1fr auto;align-items:start;}
}
@media(min-width:768px){
  .legs{grid-template-columns:1fr 1fr;}
  .fig-2{grid-template-columns:1fr 1fr;}
  .fig-3{grid-template-columns:repeat(3,1fr);}
  .cc-facts{grid-template-columns:repeat(3,1fr);}
  .mkt-scroll{display:none;}
  .mkt-table-wrap{display:block;}
  .sig{grid-template-columns:auto 1fr auto auto;}
  .led-list{display:none;}
  .led-table-wrap{display:block;}
  #gPanel .sig-list{display:none;}
  .sig-table-wrap{display:block;}

}
/* Two documents side by side only while the form column owns the full width —
   from 1024px the panel splits into form + side column and they would squeeze. */
@media(min-width:768px) and (max-width:1023px){
  .kdoc-list{display:grid;grid-template-columns:1fr 1fr;align-items:start;}
  /* Three channels across only while the column owns the full width: from
     1024px the card sits in a 340px sidebar and they would overflow it. */
  .ch-row{grid-template-columns:repeat(3,1fr);}
}
@media(min-width:1024px){
  /* The desktop shell: the bottom bar retires, and the menu leaves the left
     column entirely for the rollup in the top bar — so the page is full width
     and nothing but content stands between the two edges. */
  body{padding-bottom:26px;}
  .tabbar{display:none;}
  .toast{bottom:26px;}
  .drawer,.scrim,.menu-btn{display:none;}
  .center{padding:24px 26px 40px;}
  .notif-panel{max-height:min(76vh,620px);}
  /* Form on one side, that operation's own history on the other. */
  .wcols{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:18px;align-items:start;}
  .wside{margin-top:0;position:sticky;top:calc(var(--topbar-h) + 18px);}
  .field-2{grid-template-columns:1fr 1fr;}
  /* The support inbox: list on one side, conversation on the other */
  .tkcols{display:grid;grid-template-columns:340px minmax(0,1fr);gap:18px;align-items:start;}
  .tklist{position:sticky;top:calc(var(--topbar-h) + 18px);max-height:calc(100dvh - var(--topbar-h) - 40px);
    overflow-y:auto;}
}
@media(min-width:1280px){
  .hero-amount{font-size:44px;}
}

/* ══════════════════════════════════════════════════════
   SIGNALS: period control, win-rate chart, distribution donut,
   direction, streaks, history table
   ══════════════════════════════════════════════════════ */

/* All time, or one month walked with the arrows. */
.sig-period{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
.sig-period-note{font-size:11.5px;color:var(--fg-3);}
.month-nav{display:flex;align-items:center;gap:4px;background:var(--bg-2);
  border:1px solid var(--line-2);border-radius:var(--r2);padding:2px;}
.month-btn{width:28px;height:28px;display:flex;align-items:center;justify-content:center;
  border-radius:var(--r1);color:var(--fg-2);transition:background .18s,color .18s;}
.month-btn:hover{background:var(--bg-3);color:var(--fg);}
.month-btn.is-disabled{opacity:.32;pointer-events:none;}
.month-lbl{min-width:104px;text-align:center;font-size:12.5px;color:var(--fg);font-weight:600;}

/* Three modules across one row, all the same height. `.dash` aligns its cells to the
   start so a short card never gets padded out to a neighbour's height — right almost
   everywhere, but here it left the row with a ragged bottom edge. These three are one
   band, so they stretch, and each one's own foot note settles at the bottom because
   `.mod-foot` already claims the leftover space. */
.dash .sg-eq{align-self:stretch;}
.dash .sg-eq > .mod{height:100%;}
/* The donut is the only one of the three with no foot line, so its body takes the
   slack instead and stays centred in whatever height the row ends up with. */
.sg-eq .dnt-wrap{flex:1;align-content:center;}
/* Streaks is the shortest of the three. Its rule and closing line drop to the foot the
   way the other two modules' notes do, so the row has content at the top and the bottom
   of all three cards rather than one card trailing off into space. */
.sg-eq .mod-sep{margin-top:auto;}
/* Between 1024 and 1279 a third of the row is ~310px, which is narrower than the donut
   and its legend side by side — the legend wraps underneath, the card doubles in height
   and drags two half-empty neighbours up with it. So on that band the distribution takes
   the whole row and the other two split the next one. */
@media(min-width:1024px) and (max-width:1279px){
  .dash .sg-dist{grid-column:span 12;}
  .dash .sg-dir,.dash .sg-stk{grid-column:span 6;}
}

/* The band that separates the period's own figures from the trend charts under it.
   Without it, four charts standing still while the picker moves read as broken. */
.sg-band{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;padding-top:6px;
  border-top:1px solid var(--line-2);}
.sg-band-t{font-size:11px;letter-spacing:0.12em;text-transform:uppercase;color:var(--gold-lt);
  font-weight:600;}
html[lang="fa"] .sg-band-t,html[lang="ar"] .sg-band-t{letter-spacing:0;text-transform:none;
  font-size:12.5px;font-family:var(--f-body);}
.sg-band-n{font-size:11.5px;color:var(--fg-3);}

/* The trend charts. Three lines and one pair of columns, drawn at the width of
   their own box so a label keeps the size the stylesheet gives it. */
.sig-chart{width:100%;}
.sig-chart svg{width:100%;height:auto;display:block;overflow:visible;}
.sig-chart-box{min-height:176px;}
.chart-line.up{stroke:var(--up);}
.chart-line.down{stroke:var(--down);}
.chart-line.gold{stroke:var(--gold);}
.chart-dot.up{stroke:var(--up);} .chart-dot.down{stroke:var(--down);}
.chart-dot.gold{stroke:var(--gold);}
/* A month whose figure cannot be stated: hollow, mid-axis, and it breaks the line. */
.chart-dot.gap{fill:var(--bg-0);stroke:var(--fg-3);stroke-dasharray:2 2;}
.chart-avg{stroke:var(--mlc);stroke-width:1.3;stroke-dasharray:5 4;}
.chart-mlbl{fill:var(--fg-3);font-size:10px;}
/* Flat tone shading rather than a gradient: three charts, three tones, and no
   per-instance gradient id to keep unique. */
.sig-chart .chart-fill.up{fill:rgba(14,203,129,0.13);}
.sig-chart .chart-fill.down{fill:rgba(246,70,93,0.13);}
.sig-chart .chart-fill.gold{fill:rgba(232,182,71,0.13);}

/* Long against short, by month: two columns, wins under losses. */
.bar-keys{display:flex;gap:10px;}
.bar-key{display:flex;align-items:center;gap:5px;font-size:10.5px;color:var(--fg-3);}
.bar-key i{width:9px;height:9px;border-radius:2px;}
.bar-key i.win{background:var(--up);} .bar-key i.loss{background:var(--down);}
.bar-seg{transition:opacity .18s;}
.bar-seg.win{fill:var(--up);fill-opacity:.85;}
.bar-seg.loss{fill:var(--down);fill-opacity:.8;}
.bar-col:hover .bar-seg{fill-opacity:1;}
/* The side marker is a letter, not a figure — and a Persian or Arabic letter in a
   monospace face does not join. It takes the body font, as every localized label
   in this file does. */
.bar-side{fill:var(--fg-3);font-size:9px;font-family:var(--f-body);}

/* Win rate by market against the months. */
.dt-mkx{min-width:640px;}
.dt-mkx th,.dt-mkx td{padding:9px 10px;}
.mkx-mk{display:flex;align-items:center;gap:8px;white-space:nowrap;}
.mkx-wr{display:block;font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  font-size:13px;font-weight:600;direction:ltr;unicode-bidi:isolate;}
.mkx-wr.up{color:var(--up);} .mkx-wr.down{color:var(--down);}
.mkx-n{display:block;font-style:normal;font-size:10px;color:var(--fg-3);
  font-family:var(--f-mono);direction:ltr;unicode-bidi:isolate;}

/* The distribution donut. Four classes, and they close the circle by
   construction: the engine issues no signal outside them. */
.dnt-wrap{display:flex;align-items:center;gap:18px;flex-wrap:wrap;}
.dnt{position:relative;width:190px;height:190px;flex-shrink:0;}
.dnt svg{width:190px;height:190px;transform:rotate(-90deg);}
.dnt circle{fill:none;stroke-width:18;}
.dnt-track{stroke:var(--bg-3);}
.dnt-arc{transition:stroke-width .18s;}
.dnt-arc:hover{stroke-width:21;}
.dnt-arc.forex{stroke:var(--sig-forex);}
.dnt-arc.gold{stroke:var(--sig-gold);}
.dnt-arc.crypto{stroke:var(--sig-crypto);}
.dnt-arc.stock{stroke:var(--sig-stock);}
.dnt-mid{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:1px;pointer-events:none;}
.dnt-mid b{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:27px;
  font-weight:600;color:var(--fg);direction:ltr;unicode-bidi:isolate;}
.dnt-mid i{font-style:normal;font-size:11px;color:var(--fg-3);}
.dnt-legend{display:flex;flex-direction:column;gap:11px;flex:1 1 200px;min-width:180px;}
.dnt-key{display:grid;grid-template-columns:10px auto auto auto 1fr;align-items:baseline;
  gap:8px;font-size:13px;color:var(--fg-2);}
.dnt-dot{width:10px;height:10px;border-radius:3px;}
.dnt-dot.forex{background:var(--sig-forex);}
.dnt-dot.gold{background:var(--sig-gold);}
.dnt-dot.crypto{background:var(--sig-crypto);}
.dnt-dot.stock{background:var(--sig-stock);}
.dnt-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.dnt-pct{font-size:14px;font-weight:600;color:var(--fg);}
.dnt-count{font-size:11.5px;color:var(--fg-3);}
.dnt-count::before{content:'· ';}
/* When the module is wide enough to hold them, the four legend rows go two-up and the
   whole group centres — otherwise a full-width distribution card is a donut and four
   short lines huddled at one end with half the card empty. The query is on the module,
   as the package rows' one is, because this module appears at several widths. */
@container (min-width:620px){
  .dnt-wrap{justify-content:center;gap:34px;}
  .dnt-legend{display:grid;grid-template-columns:1fr 1fr;gap:12px 26px;flex:0 1 auto;}
}

/* Long against short. */
.dir-row{display:grid;grid-template-columns:auto auto 1fr auto;align-items:center;gap:10px 12px;
  padding:10px 0;border-bottom:1px solid var(--hair);}
.dir-row:last-of-type{border-bottom:0;}
.dir-side{display:flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;}
.dir-row.long .dir-side{color:var(--up);}
.dir-row.short .dir-side{color:var(--down);}
.dir-count{font-size:15px;font-weight:600;color:var(--fg);}
.dir-res{display:flex;align-items:baseline;gap:5px;font-size:11px;color:var(--fg-3);}
.dir-res b{font-size:13px;}
.dir-res b.up{color:var(--up);} .dir-res b.down{color:var(--down);}

/* Streaks: two figures and the run the engine is on right now. */
.stk-row{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
.stk{background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r2);padding:11px 12px;
  min-width:0;}
.stk-lbl{display:block;font-size:10.5px;color:var(--fg-3);margin-bottom:5px;line-height:1.45;}
.stk-val{font-size:22px;font-weight:600;line-height:1;}
.stk-val.up{color:var(--up);} .stk-val.down{color:var(--down);}
.stk-now{font-size:12px;color:var(--fg-3);}
.stk-now b{color:var(--fg);}
.stk-now b.up{color:var(--up);} .stk-now b.down{color:var(--down);}

/* ══ LIVE SIGNAL CARDS ═════════════════════════════════
   One card per signal a reader can act on. The grid has no breakpoint of its own:
   one up on a phone, two on a laptop, three on a wide screen, decided by how much
   room a card needs rather than by a guess about the device. */
/* ── `min(380px, 100%)`, NOT `380px`, AND THE PHONE DEPENDS ON THE DIFFERENCE ──
   A bare `minmax(380px, 1fr)` reads as "at least 380, share what is left". It
   is not: 380px is a FLOOR the track cannot go under, so on a container
   narrower than 380 the column is still 380 and the card hangs over the end of
   its own screen.

   That is what it did. `.center` pads 14px a side, so a 384px Android phone
   offers 356px of content — the card was laid out at 380 and its trailing
   border sat hard against the edge of the glass while its leading one kept the
   full 14px. A 430px iPhone offers 402px, the floor is met, and the same card
   is correct. One rule, two devices, and the split looked like a platform bug.

   `min(380px, 100%)` says what the bare number meant to: 380 where there is
   room for it, the container's own width where there is not. Nothing changes
   above 408px — the floor is still 380 and two columns still form at 774. */
.sigcards{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(380px,100%),1fr));gap:14px;}
.sigc{position:relative;background:var(--bg-1);border:1px solid var(--line);
  border-radius:var(--r3);padding:15px 16px 13px;display:flex;flex-direction:column;gap:12px;
  transition:border-color .5s,box-shadow .5s;}
/* Two halos, because the two states are two different things.
   A closed signal is a finished fact: its colour sits INSIDE the card and does not
   move. A live one still has money in the market: its colour is OUTSIDE the card and
   breathes, so the only thing moving in a grid is the only thing that can change. */
.sigc.done.profit{border-color:var(--up-line);
  box-shadow:inset 0 0 34px rgba(14,203,129,0.16),inset 0 0 0 1px rgba(14,203,129,0.05);}
.sigc.done.loss{border-color:var(--down-line);
  box-shadow:inset 0 0 34px rgba(246,70,93,0.16),inset 0 0 0 1px rgba(246,70,93,0.05);}
/* The wash. An inset shadow glows from the edges and leaves the middle of the card
   dark, which reads as a coloured rim rather than a finished trade — so a closed card
   also takes a bloom across the whole of itself. It sits above the content, which is
   why the alpha is low and why it must not take a pointer: the chart link and the copy
   buttons are underneath it. */
.sigc.done::after{content:'';position:absolute;inset:0;border-radius:inherit;
  pointer-events:none;}
.sigc.done.profit::after{
  background:radial-gradient(120% 90% at 50% 0%,rgba(14,203,129,0.16),rgba(14,203,129,0.06) 55%,rgba(14,203,129,0.03) 100%);}
.sigc.done.loss::after{
  background:radial-gradient(120% 90% at 50% 0%,rgba(246,70,93,0.16),rgba(246,70,93,0.06) 55%,rgba(246,70,93,0.03) 100%);}
.sigc.live.profit{border-color:rgba(14,203,129,0.55);animation:sigcGlowUp 2.8s ease-in-out infinite;}
.sigc.live.loss{border-color:rgba(246,70,93,0.55);animation:sigcGlowDown 2.8s ease-in-out infinite;}
@keyframes sigcGlowUp{
  0%,100%{box-shadow:0 0 22px rgba(14,203,129,0.16);}
  50%{box-shadow:0 0 40px rgba(14,203,129,0.40);}
}
@keyframes sigcGlowDown{
  0%,100%{box-shadow:0 0 22px rgba(246,70,93,0.16);}
  50%{box-shadow:0 0 40px rgba(246,70,93,0.40);}
}
/* With motion off the halo keeps its colour and loses only the movement: the state is
   information, the breathing is decoration. The global no-motion rule cuts every
   animation to its last frame, which here is the dim one — so these two say plainly
   where the halo should rest. */
body.no-motion .sigc.live.profit{animation:none;box-shadow:0 0 34px rgba(14,203,129,0.34);}
body.no-motion .sigc.live.loss{animation:none;box-shadow:0 0 34px rgba(246,70,93,0.34);}
@media(prefers-reduced-motion:reduce){
  .sigc.live.profit{animation:none;box-shadow:0 0 34px rgba(14,203,129,0.34);}
  .sigc.live.loss{animation:none;box-shadow:0 0 34px rgba(246,70,93,0.34);}
}

.sigc-head{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;}
.sigc-id{display:flex;align-items:center;gap:7px;flex-wrap:wrap;min-width:0;}
.sigc-sym{font-size:16px;font-weight:700;letter-spacing:0.02em;color:var(--gold-lt);}
/* The card's own mark. 24px against a 16px symbol: the card has the room, and
   this is the surface where the instrument should register before the text. */
.sigc-id .cix{width:24px;height:24px;}
.sigc-side{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:700;
  padding:3px 8px;border-radius:var(--r1);letter-spacing:0.06em;text-transform:uppercase;}
.sigc-side .ic{width:13px;height:13px;}
.sigc-side.long{color:var(--up);background:var(--up-pale);border:1px solid var(--up-line);}
.sigc-side.short{color:var(--down);background:var(--down-pale);border:1px solid var(--down-line);}
html[lang="fa"] .sigc-side,html[lang="ar"] .sigc-side{text-transform:none;letter-spacing:0;}
.sigc-when{display:flex;flex-direction:column;align-items:flex-end;gap:3px;text-align:end;}
.sigc-stat{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:600;
  padding:2px 8px;border-radius:20px;border:1px solid var(--line);color:var(--fg-3);}
.sigc-stat.live{color:var(--gold-lt);background:var(--gold-pale);border-color:var(--gold-line);}
.sigc-stat.up{color:var(--up);background:var(--up-pale);border-color:var(--up-line);}
.sigc-stat.down{color:var(--down);background:var(--down-pale);border-color:var(--down-line);}
.sigc-time,.sigc-ago{font-size:10px;color:var(--fg-3);}
.sigc-time{font-family:var(--f-mono);}

.sigc-pnl{display:flex;justify-content:space-between;align-items:flex-end;gap:10px;
  background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r2);padding:10px 13px;}
.sigc-plbl{display:block;font-size:9.5px;letter-spacing:0.1em;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:2px;}
html[lang="fa"] .sigc-plbl,html[lang="ar"] .sigc-plbl{letter-spacing:0;text-transform:none;font-size:10.5px;}
.sigc-pval{font-size:23px;font-weight:700;line-height:1.1;}
.sigc-pval.up{color:var(--up);} .sigc-pval.down{color:var(--down);}
.sigc-quote{text-align:end;}
.sigc-qval{font-size:13px;color:var(--fg-2);}

/* The track runs from the stop to the last target with a tenth held back at each
   end, so the marker's position is the trade's whole story in one glance — and a
   trade that has run past either end still has room to keep moving. */
.sigc-track{position:relative;height:6px;background:var(--bg-3);border-radius:3px;margin-top:2px;}
.sigc-zone{position:absolute;top:0;bottom:0;background:var(--gold-pale);
  border-inline:1px solid var(--gold-line);border-radius:2px;}
/* The fill runs from the entry to the price: gold while the trade is ahead, a grey
   heavier than the track itself while it is behind. */
.sigc-fill{position:absolute;top:0;bottom:0;border-radius:3px;background:var(--bg-4);
  transition:inset-inline-start .6s,inline-size .6s,background .4s;}
.sigc-fill.profit{background:linear-gradient(90deg,var(--gold-dp),var(--gold));}
.sigc-fill.loss{background:var(--fg-3);}
.sigc-tick{position:absolute;top:-3px;width:2px;height:12px;background:var(--line);border-radius:1px;
  transform:translateX(-1px);transition:background .3s;z-index:2;}
.sigc-tick.hit{background:var(--gold-lt);box-shadow:0 0 6px rgba(232,182,71,0.6);}
/* The stop is a landmark, not a target: it is never reached and never lights. */
.sigc-tick.stop{background:var(--fg-3);}
.sigc-mark{position:absolute;top:-4px;width:10px;height:14px;border-radius:3px;z-index:3;
  background:var(--fg-2);transform:translateX(-5px);transition:inset-inline-start .6s,background .4s;}
.sigc-mark.profit{background:var(--gold-lt);box-shadow:0 0 8px rgba(232,182,71,0.55);}
.sigc-mark.loss{background:var(--fg-3);}
/* Positioned labels rather than a spread row: each one belongs to a tick. Every one
   of them centres on its tick — the reserved ends keep the first and last inside the
   track, so none has to hug an edge any more. */
.sigc-trackl{position:relative;height:13px;}
.sigc-tlbl{position:absolute;top:0;font-size:9px;font-family:var(--f-mono);color:var(--fg-3);
  transform:translateX(-50%);white-space:nowrap;transition:color .3s;}
html[dir="rtl"] .sigc-tlbl{transform:translateX(50%);}
.sigc-tlbl.hit{color:var(--gold-lt);}

.sigc-ladder{display:flex;flex-direction:column;}
.sigc-lad{display:grid;grid-template-columns:1fr auto 26px;align-items:center;gap:10px;
  padding:6px 0;border-bottom:1px solid var(--hair);}
.sigc-lad:last-child{border-bottom:0;}
.sigc-ladk{display:flex;align-items:center;gap:5px;font-size:11.5px;color:var(--fg-3);}
.sigc-ladk .ic{width:12px;height:12px;color:var(--gold-lt);}
/* The tick ships with every target row and the `hit` class is its only switch,
   so the live layer can take it back as readily as it grants it. */
.sigc-ladk .sigc-ladtick{display:none;}
.sigc-lad.hit .sigc-ladk .sigc-ladtick{display:block;}
.sigc-lad.hit .sigc-ladk{color:var(--gold-lt);}
.sigc-ladv{font-size:13px;font-weight:600;color:var(--fg);}
.sigc-lad.lev .sigc-ladv{color:var(--gold-lt);}
/* The copy column is kept on every row, with or without a button in it, so the prices
   line up down the card instead of straggling. */
.sigc-ladc{display:block;width:26px;}
.sigc-copy{width:26px;height:26px;display:flex;align-items:center;justify-content:center;
  border-radius:var(--r1);border:1px solid var(--line-2);background:var(--bg-2);color:var(--fg-3);
  transition:color .18s,border-color .18s,background .18s;}
.sigc-copy .ic{width:13px;height:13px;}
.sigc-copy:hover{color:var(--gold-lt);border-color:var(--gold-line);background:var(--gold-pale);}

/* Two doors out of the card: the chart, and the trade. */
.sigc-acts{display:flex;gap:9px;margin-top:auto;padding-top:11px;border-top:1px solid var(--line-2);}
.sigc-act{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;min-height:38px;
  border-radius:var(--r2);font-size:12px;font-weight:600;border:1px solid var(--line);
  background:var(--bg-2);color:var(--fg-2);transition:border-color .18s,color .18s,background .18s;}
.sigc-act .ic{width:14px;height:14px;}
.sigc-act:hover{border-color:var(--gold-line);color:var(--gold-lt);background:var(--gold-pale);}
.sigc-act.gold{border-color:var(--gold-line);color:var(--gold-lt);
  background:linear-gradient(180deg,rgba(232,182,71,0.16),rgba(232,182,71,0.06));}
.sigc-act.is-disabled{opacity:.5;}
.sigc-act.is-disabled:hover{border-color:var(--gold-line);background:none;}



/* The history's filters: what happened at the start of the row, which market at the
   inline end of it. Logical properties, so Arabic and Persian mirror for free. */
.sig-filters{display:flex;align-items:center;gap:8px 14px;flex-wrap:wrap;margin-bottom:14px;}
.sig-filter-group{display:flex;gap:6px;flex-wrap:wrap;}
/* The scope group chooses which signals; the markets group filters inside that choice.
   They are two questions, so they are set apart rather than reading as one long row of
   six chips. */
.sig-filter-group.scope{margin-inline-end:18px;}
.sig-filter-group.end{margin-inline-start:auto;}

/* The history table, cards on a phone the way the wallet ledger does it. Its
   display pair lives with the ledger's, above the 768px block. */
.dt-sig{min-width:720px;}
/* Result is a column of its own between R:R and Status. Both were right-aligned
   before, which read as one crowded column instead of two. */
.dt-sig th:nth-child(5),.dt-sig td:nth-child(5){width:74px;}
.dt-sig th:nth-child(6),.dt-sig td:nth-child(6){width:104px;}
.dt-sig .th-status,.dt-sig .td-status{padding-inline-start:22px;}
/* In a card the direction is a 44px square with the word under the arrow. In a
   table row that square sets the row height for nothing, so the same markup lies
   down: arrow, then word, on one line. */
.dt-sig .sig-side{display:inline-flex;width:auto;height:auto;flex-direction:row;gap:5px;
  padding:3px 8px;font-size:11px;letter-spacing:0;text-transform:none;}
.dt-sig .sig-side .ic{width:13px;height:13px;}
.dt-sig td{vertical-align:middle;}

/* ══════════════════════════════════════════════════════
   ZEXCA AI MARKET INTELLIGENCE — the terminal at #/ai
   ══════════════════════════════════════════════════════
   THIS SCREEN IS ENGLISH ONLY and forces `dir="ltr"` on itself. It is a trading
   terminal, and every real one is English. The shell around it still mirrors,
   and `nav.ai` / `tab.ai` keep all three translations because those are shell,
   not screen.

   The one thing that buys: with no Arabic or Persian letter anywhere inside
   `.zx`, `--f-mono` can be used freely for every label and figure. That rule —
   no RTL script in a monospace face — still binds every other screen in this
   product, where it has cost six separate fixes.

   Everything here is repainted rather than re-rendered, so the rules that move
   are transitions on properties the script writes. The few real keyframes carry
   a `no-motion` resting state, because turning motion off must never turn
   information off. */

/* Full bleed. `.center`'s padding is 14px, then 20 at 768, then 26 at 1024;
   the terminal escapes each of them so the grid reaches the screen edges the
   way a dealing-room display does. */
.zx{margin-inline:-14px;direction:ltr;text-align:left;
  font-family:var(--f-body);color:var(--fg);}
.zx *{direction:ltr;}

/* ── The header bar ── */
.zx-bar{display:flex;align-items:center;justify-content:space-between;gap:14px;
  flex-wrap:wrap;padding:10px 14px;border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,rgba(255,255,255,0.035),rgba(255,255,255,0));}
.zx-brand{display:flex;align-items:baseline;gap:10px;min-width:0;}
.zx-word{font-size:18px;font-weight:600;letter-spacing:0.22em;
  background:linear-gradient(180deg,var(--gold-lt),var(--gold-dp));
  -webkit-background-clip:text;background-clip:text;color:transparent;}
.zx-sub{font-family:var(--f-mono);font-size:9.5px;letter-spacing:0.26em;color:var(--fg-3);
  white-space:nowrap;}
.zx-bar-sep{width:1px;height:22px;background:var(--line);flex:none;}
.zx-bar-grp{display:flex;align-items:center;gap:8px;font-family:var(--f-mono);
  font-size:10px;letter-spacing:0.12em;color:var(--fg-3);flex-wrap:wrap;}
.zx-bar-end{display:flex;align-items:center;gap:18px;font-family:var(--f-mono);
  font-size:10px;letter-spacing:0.12em;color:var(--fg-3);flex-wrap:wrap;}
.zx-bar-end b{color:var(--fg);font-weight:500;}
.zx-dot{width:6px;height:6px;border-radius:50%;background:var(--up);
  box-shadow:0 0 8px var(--up);animation:zxBlink 1.6s infinite;flex:none;}
.zx-dot.warn{background:var(--warn);box-shadow:0 0 8px var(--warn);}
.zx-dot.off{background:var(--fg-3);box-shadow:none;animation:none;}
.zx-clock{color:var(--gold);font-size:12px;letter-spacing:0.14em;}
/* The rotating focus, stated once. The three analysis panels follow it, so the
   bar has to say which instrument is up and how long it has left — a page that
   changes its subject without saying so reads as a fault. */
.zx-focus{display:inline-flex;align-items:center;gap:7px;}
.zx-focus b{color:var(--gold-lt);font-weight:500;min-width:56px;display:inline-block;}
.zx-focus-n{color:var(--fg-3);opacity:.8;}
.zx-focus-t{display:block;width:42px;height:3px;border-radius:2px;
  background:rgba(255,255,255,0.09);overflow:hidden;flex:none;}
.zx-focus-f{display:block;height:100%;background:var(--gold);transition:width 1s linear;}
@keyframes zxBlink{0%,100%{opacity:1}50%{opacity:.25}}

/* ── The three tabs ──
   Physically left-to-right in every language, like everything else inside `.zx`.
   A reserved tab says so on its own button: a tab that looks identical to a
   working one and then turns out to be empty is a worse discovery than a label. */
/* THE STRIP SCROLLS; THE DOOR AT THE END OF IT MUST NOT.
   `overflow-x:auto` used to sit here, on the whole strip, with AI MARKET
   pushed to the far end by `margin-inline-start:auto`. On a desktop that is
   exactly right. On a phone it was a bug and a bad one: at 430px the three tabs
   alone are 683px wide, so the door sat 188px past the visible edge and the one
   way to reach the AI Market screen from here was to know it was there and
   swipe for it.

   The scrolling moved down one level, onto the tabs themselves. The door is now
   a sibling of the scroller rather than a passenger in it, so it holds the end
   of the strip at every width and the tabs slide underneath it. */
.zx-tabs{display:flex;align-items:stretch;
  border-bottom:1px solid var(--line);background:rgba(255,255,255,0.012);}
/* `flex:0 1 auto` — MAY SHRINK, MUST NOT GROW, and the difference is the whole
   bug. With `flex:1` the scroller stretched to fill the strip and pushed the
   door to the far right edge: on a 1920px screen that put AI MARKET twelve
   hundred pixels from the tabs, alone in a corner the eye never travels to. It
   was on the page and invisible, which is worse than absent — absent at least
   gets reported.

   Shrink-only keeps the door immediately after PERFORMANCE at every desktop
   width, where a reader scanning the tab group finds it without looking for
   it. On a phone the list shrinks to what is left, scrolls inside itself, and
   the door — a sibling of the scroller, never a passenger in it — stays put. */
.zx-tabs-list{display:flex;align-items:stretch;flex:0 1 auto;min-width:0;
  overflow-x:auto;scrollbar-width:none;}
.zx-tabs-list::-webkit-scrollbar{display:none;}
.zx-tab{appearance:none;-webkit-appearance:none;background:none;border:0;
  border-bottom:2px solid transparent;padding:11px 16px;cursor:pointer;flex:none;
  display:inline-flex;align-items:center;gap:9px;white-space:nowrap;
  font-family:var(--f-mono);font-size:10px;letter-spacing:0.18em;color:var(--fg-3);}
.zx-tab:hover{color:var(--fg-2);}
.zx-tab[aria-selected="true"]{color:var(--gold);border-bottom-color:var(--gold);
  background:linear-gradient(180deg,rgba(255,255,255,0),var(--gold-pale));}
.zx-tab-soon{font-style:normal;font-size:8px;letter-spacing:0.13em;color:var(--fg-3);
  border:1px solid var(--line);border-radius:var(--r1);padding:2px 5px;opacity:.75;}
/* The door out, held at the far end — the position that already means "leaving
   this" everywhere else in the product. `flex:none` and a background of its own,
   because the tabs now scroll UNDER it and a transparent button would have
   PERFORMANCE sliding through it. */
/* `--gold`, not `--gold-dp`. The dark tone was chosen when this sat alone at
   the edge of the strip; beside three lit tabs it just read as switched off.
   It cannot be confused with the SELECTED tab, which is marked by a gold
   underline and a gold-pale wash that this deliberately has neither of. */
.zx-tab-go{flex:none;color:var(--gold);background:var(--bg-0);
  border-inline-start:1px solid var(--line);}
.zx-tab-go:hover{color:var(--gold-lt);}
.zx-tab-go .ic{width:12px;height:12px;transition:transform .18s var(--ease);}

/* ── A reserved tab's rows. The label column is fixed so the four or five
      statements read as one list rather than as four indents. ── */
.zx-res{display:flex;flex-direction:column;gap:11px;}
.zx-res-r{display:grid;grid-template-columns:150px 1fr;gap:12px;align-items:baseline;}
.zx-res-r b{font-family:var(--f-mono);font-size:9px;letter-spacing:0.15em;
  color:var(--gold);font-weight:400;}
.zx-res-r span{font-size:12px;color:var(--fg-2);line-height:1.7;}
@media (max-width:640px){.zx-res-r{grid-template-columns:1fr;gap:3px}}

/* ── The demo banner. §37: mock data is labelled, always, and never mixed. ── */
.zx-banner{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:9px 14px;background:var(--gold-pale);border-bottom:1px solid var(--gold-line);
  font-size:12px;color:var(--gold-lt);}
.zx-banner b{font-family:var(--f-mono);font-size:10px;letter-spacing:0.18em;
  padding:3px 8px;border:1px solid var(--gold-line);border-radius:var(--r1);
  background:rgba(0,0,0,0.25);color:var(--gold);flex:none;}
.zx-banner span{color:var(--fg-2);min-width:0;}

/* ── The ticker strip ── */
.zx-tape{display:flex;align-items:stretch;overflow-x:auto;-webkit-overflow-scrolling:touch;
  border-bottom:1px solid var(--line);background:rgba(255,255,255,0.015);
  scrollbar-width:none;}
.zx-tape::-webkit-scrollbar{display:none;}
.zx-tk{display:flex;align-items:baseline;gap:8px;padding:9px 16px;white-space:nowrap;
  border-right:1px solid var(--line-2);font-family:var(--f-mono);flex:none;}
.zx-tk-sym{font-size:10px;letter-spacing:0.14em;color:var(--fg-3);}
/* The strip is `align-items:baseline`, which would hang a mark off the text
   baseline and make the whole row jitter as it scrolls. */
.zx-tk .cix{width:15px;height:15px;align-self:center;}
.zx-tk-px{font-size:12px;color:var(--fg);}
.zx-tk-ch{font-size:10.5px;}
.zx-tk-ch.up{color:var(--up);} .zx-tk-ch.down{color:var(--down);}
.zx-tk-st{font-size:8.5px;letter-spacing:0.12em;color:var(--fg-3);opacity:.75;}

/* ── The grid ── */
.zx-grid{padding:12px 14px 8px;}

/* ── Panel chrome. Built on `.mod` so the terminal is this product's design
      system rather than a second one bolted beside it. ── */
.zx .mod{background:linear-gradient(180deg,rgba(255,255,255,0.030),rgba(255,255,255,0.010));
  border-color:var(--line);border-radius:var(--r2);padding:12px 13px 11px;}
.zx .mod-title{font-family:var(--f-mono);font-size:9.5px;letter-spacing:0.19em;
  color:var(--fg-3);font-weight:400;}
.zx .mod-title i{color:var(--gold);font-style:normal;}
.zx .mod-head{margin-bottom:10px;}

/* ── The state chip. The mechanism that makes §33 and §39 one thing: a panel
      states how fresh it is, so the layout is already right for the truth. ── */
.zx-st{font-family:var(--f-mono);font-size:8.5px;letter-spacing:0.14em;
  padding:2px 6px;border-radius:var(--r1);border:1px solid;white-space:nowrap;flex:none;}
.zx-st.live{color:var(--up);border-color:var(--up-line);background:var(--up-pale);}
.zx-st.delayed{color:var(--warn);border-color:var(--warn-line);background:var(--warn-pale);}
.zx-st.stale{color:var(--down);border-color:var(--down-line);background:var(--down-pale);}
.zx-st.demo{color:var(--gold);border-color:var(--gold-line);background:var(--gold-pale);}
.zx-st.unavailable,.zx-st.not_supported{color:var(--fg-3);border-color:var(--line);
  background:rgba(255,255,255,0.02);}
/* Head meta. It needs its own size: dropped into `.mod-end` with nothing else to
   inherit from it took the body face at 14px and shouted over its own title. */
.zx-meta{font-family:var(--f-mono);font-size:9px;letter-spacing:0.13em;color:var(--fg-3);
  white-space:nowrap;}

/* A panel with no data says so in place of its figures, never beside them. */
.zx-none{display:flex;flex-direction:column;gap:5px;align-items:flex-start;
  padding:16px 2px;font-family:var(--f-mono);}
.zx-none b{font-size:11px;letter-spacing:0.14em;color:var(--fg-3);font-weight:400;}
.zx-none span{font-size:10px;color:var(--fg-3);opacity:.72;letter-spacing:0.06em;}

/* ── Canvases. Sized by measurement in script; these are only the boxes. ── */
.zx-cv{display:block;width:100%;min-width:0;}
.zx-stage{position:relative;border-radius:var(--r2);overflow:hidden;
  background:radial-gradient(600px 380px at 50% 45%,rgba(127,180,212,0.07),transparent 70%);}

/* ── 03 monitor ── */
/* The history cell reads `<mark> XAUUSD · Gold`, and ALL THREE are inside the
   flex row. An earlier version wrapped only the mark and the ticker and used
   `vertical-align` to seat them: that works while every row has an SVG mark,
   and breaks the moment one falls back to the typographic badge, which is a
   taller box — the ` · Gold` after it lifted off the baseline. Laying the
   whole cell out removes the failure rather than tuning it. */
/* ══ THE FAST-START LADDER ═════════════════════════
   Four rungs, and the unreached ones are drawn at full size rather than
   dimmed away — a ladder that hid what is ahead would remove the only reason
   to look at it. Reached is stated by the tick and the gold, not by presence. */
.bn-ladder{display:grid;gap:8px;margin:10px 0 14px;}
@media(min-width:560px){ .bn-ladder{grid-template-columns:repeat(4,1fr);} }
.bn-rung{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:11px 13px;border-radius:var(--r2);
  background:var(--bg-1);border:1px solid var(--line-2);color:var(--fg-3);
}
.bn-rung .ic{width:15px;height:15px;flex:none;}
.bn-rung.on{
  background:var(--gold-pale);border-color:var(--gold-line);color:var(--gold-lt);
}
.bn-rung-d{font-size:12.5px;font-weight:600;}
.bn-rung-c{
  font-family:var(--f-mono);font-size:11px;margin-inline-start:auto;
  white-space:nowrap;
}

/* What has actually been handed over. A list of events, so it reads as a
   record rather than as a total somebody could disagree with. */
.bn-paid-r{
  display:flex;align-items:center;gap:9px;
  padding:9px 0;border-bottom:1px solid var(--hair);font-size:13px;
}
.bn-paid-r:last-child{border-bottom:0;}
.bn-paid-r .ic{width:15px;height:15px;flex:none;color:var(--gold);}
.bn-paid-at{
  margin-inline-start:auto;font-family:var(--f-mono);font-size:11px;
  color:var(--fg-3);white-space:nowrap;
}

/* ── THE PRIZE, WITH THE THING ITSELF IN IT ──
   A product shot on its own light plate rather than a cut-out. The photograph is
   lit for a pale ground; knocking the background out would leave a grey fringe
   on every aluminium edge and a hard line where the shadow used to be. So the
   plate IS the frame — the hairline and the card's own padding are what stop it
   reading as a hole punched in the page.

   The plate carries the photograph's own vertical gradient (#D7EBF6 sampled at
   its top edge, #F6F8F9 at its bottom), so there is no flash of a wrong colour
   while the image decodes and no seam at any edge if it never arrives. */
.bn-prize{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;align-items:center;}
.bn-prize-shot{
  --shot-a:#D7EBF6; --shot-b:#F6F8F9;            /* the MacBook's own ground */
  border-radius:var(--r2);overflow:hidden;border:1px solid var(--line);
  background:linear-gradient(180deg,var(--shot-a),var(--shot-b));line-height:0;
}
/* Each shot brings its own plate, sampled from its own top and bottom edge. The
   Rolex is photographed on cold water and runs a good deal darker than the
   MacBook's near-white; borrowing the other card's gradient put a pale band
   behind a dark photograph for the moment before it decoded. */
.bn-prize-shot.watch{--shot-a:#C2DEED; --shot-b:#64869C;}
.bn-prize-shot img{width:100%;height:auto;display:block;}
.bn-prize-body{min-width:0;}
.bn-prize-rows{display:flex;flex-direction:column;gap:11px;margin-top:13px;}
.bn-prize-row{min-width:0;}
.bn-prize-top{display:flex;align-items:baseline;gap:8px;margin-bottom:6px;}
.bn-prize-lbl{
  font-size:10px;letter-spacing:0.1em;text-transform:uppercase;color:var(--fg-3);
}
/* Its own isolate rather than a line added to the global list: the value is a
   pair of figures around a slash, and in RTL an un-isolated "3 / 5" reverses. */
.bn-prize-val{
  margin-inline-start:auto;font-family:var(--f-mono);font-variant-numeric:tabular-nums;
  font-size:12.5px;font-weight:600;direction:ltr;unicode-bidi:isolate;white-space:nowrap;
}
.bn-prize-val.done{color:var(--up);}
html[lang="fa"] .bn-prize-lbl,html[lang="ar"] .bn-prize-lbl{
  letter-spacing:0;text-transform:none;font-size:11px;
}
/* The split only from 768px. Below it the shot goes full width above the copy,
   which is the one arrangement that does not squeeze a 2.4:1 photograph into a
   column too narrow to see it in. */
@media(min-width:768px){
  .bn-prize{grid-template-columns:minmax(0,38%) minmax(0,1fr);gap:20px;}
}

.sigh-sym{display:flex;align-items:center;gap:7px;}
.sigh-sym .cix{width:18px;height:18px;}
.sigh-mkt{color:var(--fg-3);}

/* ── A LEADING COLUMN FOR THE MARK ──
   16px and not 22px: this table is 10px mono at a 5px row rhythm, and a
   watchlist-sized disc would be taller than the row it sits in. The head row
   carries an empty cell to match. */
.zx-mon{display:grid;grid-template-columns:16px 58px 1fr 54px 40px 34px;gap:0 8px;
  align-items:center;font-family:var(--f-mono);font-size:10px;
  padding:5px 0;border-bottom:1px solid var(--hair);}
.zx-mon.head{color:var(--fg-3);font-size:8.5px;letter-spacing:0.13em;padding-bottom:6px;
  border-bottom-color:var(--line);}
.zx-mon-sym{color:var(--fg-2);letter-spacing:0.03em;overflow:hidden;text-overflow:ellipsis;
  display:flex;flex-direction:column;align-items:flex-start;gap:1px;line-height:1.15;}
/* The instrument's own footnote, where its symbol is shorter than the truth —
   `GOLD` is PAX Gold, not the London fix. A tag, not a sentence: the column is
   58px wide and the sentence is the title attribute. */
.zx-mon-note{font-style:normal;font-size:7.5px;letter-spacing:0.1em;color:var(--fg-3);
  border:1px solid var(--line);border-radius:2px;padding:0 3px;opacity:.85;cursor:help;}

/* ── THE MARKET IS SHUT, WHICH IS NOT THE SAME AS THE FEED BEING DOWN ──
   Every non-crypto row is a 24/7 contract on a market that closes, so the price
   stays live and current while the thing it tracks is not trading. The tag says
   so and the row is dimmed — dimmed rather than greyed out, because the figure
   is still the last real one and still worth reading. Absent entirely while the
   market is open: a badge that is always there is a badge nobody sees. */
.zx-mon-shut{font-style:normal;font-size:7.5px;letter-spacing:0.1em;
  color:var(--fg-3);border:1px solid var(--line);border-radius:2px;
  padding:0 3px;margin-inline-start:4px;cursor:help;white-space:nowrap;}
.zx-mon-off{opacity:.62;}
.zx-mon-off .zx-mon-shut{color:var(--gold);border-color:color-mix(in oklab,var(--gold) 45%,transparent);}
.zx-mon-off:hover{opacity:1;}
.zx-mon .cix{width:16px;height:16px;}
.zx-mon-mid{display:flex;align-items:center;gap:7px;min-width:0;}
.zx-mon-px{color:var(--fg);}
.zx-mon-spk{margin-left:auto;width:58px;height:16px;flex:none;}
.zx-mon-spk svg{display:block;width:100%;height:100%;}
.zx-mon-ch{text-align:right;} .zx-mon-ch.up{color:var(--up);} .zx-mon-ch.down{color:var(--down);}
.zx-mon-vol{text-align:right;color:var(--fg-3);}
.zx-mon-ai{text-align:right;}

/* ── 04 order flow ── */
.zx-flow-top{display:flex;justify-content:space-between;font-family:var(--f-mono);
  font-size:10px;margin-bottom:6px;}
.zx-flow-b{color:var(--up);} .zx-flow-s{color:var(--down);}
.zx-kind{font-family:var(--f-mono);font-size:8.5px;letter-spacing:0.13em;color:var(--fg-3);
  margin-top:8px;padding-top:8px;border-top:1px solid var(--hair);}
.zx-kind b{color:var(--warn);font-weight:400;}
.zx-stats{display:grid;grid-template-columns:1fr 1fr;gap:7px 12px;margin-top:10px;}
.zx-stat-l{font-family:var(--f-mono);font-size:8.5px;letter-spacing:0.15em;color:var(--fg-3);}
.zx-stat-v{font-family:var(--f-mono);font-size:11.5px;margin-top:2px;color:var(--fg);}
.zx-stat-v.up{color:var(--up);} .zx-stat-v.down{color:var(--down);}
.zx-stat-v.warn{color:var(--warn);} .zx-stat-v.info{color:var(--mlc);}
.zx-interp{margin-top:10px;padding-top:9px;border-top:1px solid var(--hair);
  font-size:12px;color:var(--fg);line-height:1.5;}

/* ── 05 news ── */
.zx-nw{padding:8px 0;border-bottom:1px solid var(--hair);}
.zx-nw:last-child{border-bottom:0;}
.zx-nw-top{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-family:var(--f-mono);font-size:8.5px;letter-spacing:0.13em;color:var(--fg-3);}
.zx-nw-h{display:block;font-size:12.5px;color:var(--fg);margin-top:4px;line-height:1.4;
  text-decoration:none;}
/* The headline is a link now that the feeds carry one. It does not advertise
   itself as one until it is pointed at — a list of twelve underlined headlines
   is a wall, and the cursor says the same thing more quietly. */
a.zx-nw-h:hover,a.zx-nw-h:focus-visible{color:var(--gold);text-decoration:underline;}
.zx-nw-foot{display:flex;align-items:center;gap:8px;margin-top:6px;flex-wrap:wrap;
  font-family:var(--f-mono);font-size:9px;}
.zx-sent{padding:2px 6px;border-radius:var(--r1);border:1px solid;letter-spacing:0.11em;}
.zx-sent.bull{color:var(--up);border-color:var(--up-line);background:var(--up-pale);}
.zx-sent.bear{color:var(--down);border-color:var(--down-line);background:var(--down-pale);}
.zx-sent.flat{color:var(--gold);border-color:var(--gold-line);background:var(--gold-pale);}
.zx-nw-conf{margin-left:auto;color:var(--mlc);}

/* ── 06 funnel ── */
.zx-fn{display:grid;grid-template-columns:minmax(96px,150px) 1fr 78px;align-items:center;
  gap:10px;padding:4px 0;}
.zx-fn-l{font-family:var(--f-mono);font-size:9px;letter-spacing:0.11em;color:var(--fg-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.zx-fn.gold .zx-fn-l{color:var(--gold);}
.zx-fn-track{height:19px;display:flex;justify-content:center;min-width:0;}
.zx-fn-bar{height:100%;border-radius:3px;overflow:hidden;transition:width .5s var(--ease);
  background:linear-gradient(90deg,var(--mlc-dp),var(--mlc));min-width:2px;}
.zx-fn.gold .zx-fn-bar{background:linear-gradient(90deg,var(--gold-dp),var(--gold-lt));}
.zx-fn-v{font-family:var(--f-mono);font-size:12px;text-align:right;color:var(--fg);}
.zx-fn.gold .zx-fn-v{color:var(--gold-lt);}
.zx-fn-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;
  flex-wrap:wrap;margin-top:10px;padding-top:9px;border-top:1px solid var(--hair);
  font-family:var(--f-mono);font-size:9.5px;letter-spacing:0.12em;color:var(--fg-3);}
.zx-fn-foot b{font-weight:400;color:var(--fg);}
.zx-fn-foot b.down{color:var(--down);} .zx-fn-foot b.gold{color:var(--gold);}

/* ── 07 opportunity ── */
.zx-op{border-color:var(--gold-line);
  background:linear-gradient(180deg,rgba(232,182,71,0.06),rgba(255,255,255,0.010));}
.zx-op-top{display:flex;align-items:flex-end;justify-content:space-between;gap:10px;
  padding-bottom:9px;border-bottom:1px solid var(--hair);}
.zx-op-lbl{font-family:var(--f-mono);font-size:9px;letter-spacing:0.17em;color:var(--fg-3);}
/* The mark beside the candidate, sized to the 21px symbol it introduces. */
.zx-op-id{display:flex;align-items:center;gap:10px;}
.zx-op-id .cix{width:26px;height:26px;}
.zx-op-sym{font-size:21px;font-weight:500;letter-spacing:0.03em;color:var(--gold-lt);
  margin-top:2px;}
.zx-op-score{font-family:var(--f-mono);font-size:25px;color:var(--mlc);line-height:1.05;}
.zx-op-m{display:grid;grid-template-columns:1fr 1fr;gap:6px 12px;margin-top:10px;}
.zx-op-row{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-family:var(--f-mono);font-size:9.5px;border-bottom:1px solid var(--hair);
  padding-bottom:4px;}
.zx-op-row span:first-child{letter-spacing:0.11em;color:var(--fg-3);}
.zx-q{display:grid;grid-template-columns:24px 1fr 44px 48px;align-items:center;gap:8px;
  padding:5px 0;border-bottom:1px solid var(--hair);font-family:var(--f-mono);font-size:10px;}
.zx-q-r{color:var(--fg-3);} .zx-q-s{color:var(--fg-2);}
.zx-q-side.up{color:var(--up);} .zx-q-side.down{color:var(--down);}
.zx-q-sc{text-align:right;color:var(--mlc);}

/* ── 08 regime ── */
.zx-rg-name{font-size:23px;font-weight:500;letter-spacing:0.05em;color:var(--mlc);}
.zx-rg-str{font-family:var(--f-mono);font-size:10px;letter-spacing:0.15em;color:var(--gold);
  margin-top:2px;}
.zx-rg-bar{display:flex;align-items:center;gap:8px;margin-top:10px;}
.zx-rg-track{display:block;flex:1;height:4px;border-radius:2px;
  background:rgba(255,255,255,0.07);overflow:hidden;}
.zx-rg-fill{display:block;height:100%;background:var(--mlc);transition:width .5s var(--ease);}
.zx-rg-conf{font-family:var(--f-mono);font-size:10px;color:var(--fg-2);}
.zx-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:10px;}
.zx-tag{font-family:var(--f-mono);font-size:8px;letter-spacing:0.11em;padding:2px 6px;
  border-radius:var(--r1);border:1px solid var(--line);color:var(--fg-3);}
.zx-tag.on{border-color:var(--mlc-line);color:var(--mlc);background:var(--mlc-pale);}

/* ── 09 volatility ── */
.zx-vol-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;
  flex-wrap:wrap;margin-top:8px;font-family:var(--f-mono);font-size:9.5px;}
.zx-vol-foot span{color:var(--fg-3);letter-spacing:0.11em;}
.zx-vol-foot b{color:var(--down);font-weight:400;}
.zx-vol-st{font-family:var(--f-mono);font-size:9px;color:var(--fg-3);margin-top:4px;
  letter-spacing:0.07em;}

/* ── 10 correlation ── */
/* Ten instruments means ten columns. The minimum keeps a cell readable and lets
   `.dt-wrap` scroll on a narrow rail rather than crushing the figures — the same
   answer the market table already uses. */
.zx-cor{display:grid;gap:3px;min-width:430px;}
.zx-cor-h{font-family:var(--f-mono);font-size:8px;letter-spacing:0.07em;color:var(--fg-3);
  text-align:center;}
.zx-cor-r{font-family:var(--f-mono);font-size:8px;letter-spacing:0.07em;color:var(--fg-3);
  display:flex;align-items:center;}
.zx-cor-c{height:21px;border-radius:2px;display:flex;align-items:center;justify-content:center;
  font-family:var(--f-mono);font-size:8.5px;border:1px solid var(--line-2);color:var(--fg-2);}
.zx-cor-c.self{background:rgba(255,255,255,0.05);color:var(--fg-3);}
.zx-cor-c.strong{border-color:var(--gold-line);color:var(--fg);}
.zx-break{margin-top:11px;border:1px solid var(--down-line);background:var(--down-pale);
  border-radius:var(--r2);padding:8px 10px;}
.zx-break-t{font-family:var(--f-mono);font-size:9px;letter-spacing:0.15em;color:var(--down);
  margin-bottom:4px;}
.zx-break-r{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  font-family:var(--f-mono);font-size:10px;color:var(--fg-2);}
.zx-break-n{font-family:var(--f-mono);font-size:9.5px;color:var(--fg-3);margin-top:4px;}

/* ── 11 sentiment ── */
.zx-se-top{display:flex;align-items:flex-end;gap:10px;margin-bottom:10px;flex-wrap:wrap;}
.zx-se-lbl{font-size:25px;font-weight:500;letter-spacing:0.03em;}
.zx-se-lbl.up{color:var(--up);} .zx-se-lbl.down{color:var(--down);} .zx-se-lbl.flat{color:var(--gold);}
.zx-se-sc{font-family:var(--f-mono);font-size:19px;color:var(--fg);}
.zx-se-r{display:grid;grid-template-columns:54px 1fr 36px;align-items:center;gap:9px;
  padding:3px 0;}
.zx-se-n{font-family:var(--f-mono);font-size:9.5px;color:var(--fg-3);letter-spacing:0.09em;}
.zx-se-t{display:block;height:4px;border-radius:2px;background:rgba(255,255,255,0.07);
  overflow:hidden;}
.zx-se-f{display:block;height:100%;border-radius:2px;transition:width .5s var(--ease);}
.zx-se-v{font-family:var(--f-mono);font-size:10px;text-align:right;}
.zx-parts{margin-top:9px;padding-top:8px;border-top:1px solid var(--hair);
  font-family:var(--f-mono);font-size:8.5px;letter-spacing:0.11em;color:var(--fg-3);}

/* ── 12 structure ── */
.zx-str-s{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:10px;
  padding-top:9px;border-top:1px solid var(--hair);}
.zx-str-l{font-family:var(--f-mono);font-size:8.5px;letter-spacing:0.13em;color:var(--fg-3);}
.zx-str-v{font-family:var(--f-mono);font-size:12px;margin-top:2px;color:var(--fg);}
.zx-str-v.up{color:var(--up);} .zx-str-v.down{color:var(--down);}
.zx-str-v.gold{color:var(--gold);} .zx-str-v.none{color:var(--fg-3);}
.zx-why{font-family:var(--f-mono);font-size:8.5px;color:var(--fg-3);margin-top:7px;
  letter-spacing:0.05em;opacity:.8;}

/* ── 13 stream ── */
.zx-stream{max-height:272px;overflow:hidden;}
.zx-ln{display:grid;grid-template-columns:58px 8px 1fr;align-items:baseline;gap:8px;
  padding:4px 0;border-bottom:1px solid rgba(255,255,255,0.035);
  font-family:var(--f-mono);font-size:10px;}
.zx-ln-t{color:var(--fg-3);}
.zx-ln-d{color:var(--mlc);}
.zx-ln-d.up{color:var(--up);} .zx-ln-d.down{color:var(--down);} .zx-ln-d.warn{color:var(--gold);}
.zx-ln-x{color:var(--fg-2);min-width:0;overflow:hidden;text-overflow:ellipsis;}

/* ── 15 risk ── */
.zx-rk-r{display:grid;grid-template-columns:minmax(84px,104px) 1fr 32px;align-items:center;
  gap:9px;padding:4px 0;}
.zx-rk-n{font-family:var(--f-mono);font-size:9.5px;color:var(--fg-3);letter-spacing:0.09em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.zx-rk-t{display:block;height:4px;border-radius:2px;background:rgba(255,255,255,0.07);
  overflow:hidden;}
.zx-rk-f{display:block;height:100%;border-radius:2px;transition:width .5s var(--ease);}
.zx-rk-v{font-family:var(--f-mono);font-size:10px;text-align:right;color:var(--fg-2);}

/* ── 16 telemetry · 17 infrastructure ── */
.zx-tm{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:4.5px 0;border-bottom:1px solid rgba(255,255,255,0.04);
  font-family:var(--f-mono);font-size:9.5px;}
.zx-tm-l{letter-spacing:0.09em;color:var(--fg-3);min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.zx-tm-v{font-size:10.5px;color:var(--fg);white-space:nowrap;}
.zx-tm-v.none{color:var(--fg-3);}
.zx-if{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:6px 0;border-bottom:1px solid var(--hair);font-family:var(--f-mono);font-size:10px;}
.zx-if-n{color:var(--fg-2);letter-spacing:0.09em;}
.zx-if-s{display:flex;align-items:center;gap:7px;letter-spacing:0.11em;color:var(--fg-3);}
.zx-if-note{font-family:var(--f-mono);font-size:8.5px;color:var(--fg-3);opacity:.75;
  margin-top:9px;letter-spacing:0.05em;line-height:1.5;}

/* ── Round two: what a panel says instead of a figure ──
   `.zx-await` is the whole round in one class. A cell with no data does not go
   blank and does not print a zero — it names the environment variable that
   would fill it, so an empty row is something a reader can act on. It is gold
   rather than grey deliberately: it is not an error, it is an instruction. */
.zx-await{display:inline-block;font-style:normal;font-family:var(--f-mono);
  font-size:7.5px;letter-spacing:0.12em;color:var(--gold);background:var(--gold-pale);
  border:1px solid var(--gold-line);border-radius:var(--r1);
  padding:1px 5px;margin-inline-start:7px;white-space:nowrap;vertical-align:middle;}
.zx-if.waiting .zx-if-s{opacity:.62;}
.zx-mon-none{font-family:var(--f-mono);font-size:8.5px;letter-spacing:.11em;
  color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* A track with nothing in it must not read as a measured zero, so the row that
   has no value drops its track entirely rather than drawing an empty one. */
.zx-se-r.none .zx-se-t,.zx-rk-r.none .zx-rk-t{border:1px dashed var(--hair);
  background:none;height:3px;border-radius:2px;}
.zx-se-r.none .zx-se-v,.zx-rk-r.none .zx-rk-v,.zx-rl-v.none{color:var(--fg-3);opacity:.6;}
/* A tag whose input is missing is neither on nor off. Three states, three
   looks — dark for tested-and-false, dashed for never-tested. */
.zx-tag.none{border-style:dashed;opacity:.45;}
.zx-fn.blocked .zx-fn-track{opacity:.4;}

/* The banner is always rendered and hidden by this class, because the source
   can change after the screen is mounted. */
.zx-banner.off{display:none;}

/* The connection panel that replaces the demo desk on a live feed. */
.zx-conn{display:inline-flex;align-items:baseline;gap:6px;font-family:var(--f-mono);
  font-size:9px;letter-spacing:0.1em;white-space:nowrap;}
.zx-conn i{font-style:normal;color:var(--fg-3);opacity:.75;}
.zx-conn b{color:var(--fg);font-weight:500;max-width:32ch;overflow:hidden;
  text-overflow:ellipsis;}
.zx-conn b.down{color:var(--down);}

/* An AI reading, when a model has actually produced one. It is set apart from
   the figures around it because it is an interpretation of them, not another
   one of them — and it always carries the model's name. */
.zx-ai-note{margin-top:10px;padding:9px 10px;border:1px solid var(--mlc-line);
  border-radius:var(--r1);background:var(--mlc-pale);}
.zx-ai-h{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-family:var(--f-mono);font-size:8px;letter-spacing:0.14em;color:var(--mlc);}
.zx-ai-h b{font-weight:600;}
.zx-ai-h span{color:var(--fg-3);}
.zx-ai-t{margin-top:6px;font-size:11px;line-height:1.55;color:var(--fg-2);}

/* The drop-off under an empty opportunity panel: this cycle's own counts, gate
   by gate, with the one that took the last candidate marked. */
.zx-lost{display:grid;gap:2px;margin-top:6px;}
.zx-lost-r{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:4px 0;border-bottom:1px solid var(--hair);
  font-family:var(--f-mono);font-size:9px;letter-spacing:0.09em;color:var(--fg-3);}
.zx-lost-r b{color:var(--fg-2);font-weight:500;}
.zx-lost-r.out{color:var(--down);}
.zx-lost-r.out b{color:var(--down);}

/* Regime states both of its inputs and how each voted, because the label can
   only follow one of them and they disagree often. */
.zx-rg-in{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:9px;padding-top:8px;
  border-top:1px solid var(--hair);}
.zx-rg-in span{display:inline-flex;align-items:baseline;gap:6px;
  font-family:var(--f-mono);font-size:8.5px;letter-spacing:0.1em;color:var(--fg-3);}
.zx-rg-in b{color:var(--fg);font-weight:500;}
.zx-rg-in b.up{color:var(--up);} .zx-rg-in b.down{color:var(--down);}

/* ── 01 brain HUD ── */
.zx-brain-st{display:flex;gap:5px;flex-wrap:wrap;}
.zx-bs{font-family:var(--f-mono);font-size:8.5px;letter-spacing:0.14em;padding:3px 7px;
  border-radius:var(--r1);border:1px solid var(--line);color:var(--fg-3);}
.zx-bs.on{border-color:var(--mlc-line);color:var(--on-gold);background:var(--mlc);}
.zx-pipe{display:flex;align-items:stretch;margin-top:8px;padding-top:10px;
  border-top:1px solid var(--hair);}
.zx-pp{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:0 3px;border-right:1px solid var(--hair);}
.zx-pp:last-child{border-right:0;}
.zx-pp-n{font-family:var(--f-mono);font-size:7.5px;letter-spacing:0.07em;color:var(--fg-3);
  text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;}
.zx-pp.active .zx-pp-n{color:var(--mlc);}
.zx-pp.done .zx-pp-n{color:var(--fg-2);}
.zx-pp.blocked .zx-pp-n{color:var(--fg-3);opacity:.5;text-decoration:line-through;}
.zx-pp-t{display:block;width:100%;height:3px;border-radius:2px;
  background:rgba(255,255,255,0.07);overflow:hidden;}
.zx-pp-f{display:block;height:100%;background:var(--mlc);transition:width .35s linear;}
.zx-pp.done .zx-pp-f{background:var(--fg-3);}
.zx-pp.blocked .zx-pp-f{background:repeating-linear-gradient(90deg,
  var(--line) 0 3px,transparent 3px 6px);}

/* ── 02 radar layers · anomaly ── */
.zx-rl{display:grid;grid-template-columns:1fr 1fr;gap:3px 10px;margin-top:10px;}
.zx-rl-r{display:flex;align-items:center;justify-content:space-between;gap:6px;
  font-family:var(--f-mono);font-size:9.5px;letter-spacing:0.09em;padding:3px 0;
  border-bottom:1px solid rgba(255,255,255,0.045);}
.zx-rl-n{color:var(--fg-3);} .zx-rl-v{color:var(--mlc);}
.zx-rl-v.hot{color:var(--gold);}
.zx-anom{margin-top:10px;border:1px solid var(--gold-line);background:var(--gold-pale);
  border-radius:var(--r2);padding:8px 10px;}
.zx-anom-t{font-family:var(--f-mono);font-size:9px;letter-spacing:0.16em;color:var(--gold);
  margin-bottom:4px;}
.zx-anom-h{font-family:var(--f-mono);font-size:11px;color:var(--fg);}
.zx-anom-d{font-family:var(--f-mono);font-size:9.5px;color:var(--fg-3);margin-top:3px;}

/* ── The demo desk ── */
.zx-desk{padding:0 14px 14px;}

/* ── Widths. Every panel survives every width; the wide ones degrade the way
      this product already degrades wide things. ── */
@media(min-width:768px){
  .zx{margin-inline:-20px;}
  .zx-bar,.zx-banner,.zx-grid,.zx-desk{padding-left:20px;padding-right:20px;}
}
@media(min-width:1024px){
  .zx{margin-inline:-26px;}
  .zx-bar,.zx-banner,.zx-grid,.zx-desk{padding-left:26px;padding-right:26px;}
}
@media(max-width:1279px){
  /* Five dense columns do not fit a quarter-width rail; the monitor drops its
     volatility column before it drops a price. */
  .zx-mon{grid-template-columns:16px 56px 1fr 52px 32px;}
  .zx-mon-vol{display:none;}
  .zx-mon-spk{width:46px;}
}
@media(max-width:767px){
  .zx-word{font-size:16px;letter-spacing:0.16em;}
  .zx-bar,.zx-banner{gap:8px;}
  .zx-bar-sep{display:none;}
  .zx-op-m,.zx-stats,.zx-rl{grid-template-columns:1fr;}
  .zx-str-s{grid-template-columns:1fr 1fr;}
  .zx-fn{grid-template-columns:minmax(78px,1fr) 1.2fr 62px;gap:8px;}
  .zx-pipe{overflow-x:auto;}
  .zx-pp{min-width:62px;flex:none;}
}

/* Motion off keeps every figure and every colour; only the movement goes. */
body.no-motion .zx-dot{animation:none;}

/* ══════════════════════════════════════════════════════
   REDUCED MOTION
   ══════════════════════════════════════════════════════ */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;}
  .screen.active{animation:none;}
  #bgCanvas{display:none;}
}

/* ══════════════════════════════════════════════════════
   WHERE THE FIGURES COME FROM
   ══════════════════════════════════════════════════════
   The sign-in used to live here — a card painted over the whole page, because
   a dashboard drawn behind a prompt is somebody's balances shown to somebody
   who has not proved they are them. It is now a page of its own,
   `zexca-login.html`, which honours that rule more completely than an overlay
   could: `showSignIn()` leaves this document rather than covering it. */

/* The chip in the top bar. Gold and pulsing when live, quiet when demo — the
   difference has to be visible without reading it. */
.src-pill{cursor:pointer;border:1px solid var(--line);background:var(--bg-2);color:var(--fg-3);}
.src-pill:hover{border-color:var(--bg-4);color:var(--fg-2);}
.src-pill.live{background:var(--up-pale);border-color:var(--up-line);color:var(--up);}
.src-row{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:8px 0;border-bottom:1px solid var(--line-2);font-size:13px;
}
.src-note{margin:0 0 12px;color:var(--fg-2);font-size:13px;line-height:1.7;}
.src-out{width:100%;margin-top:16px;justify-content:center;}

@media(max-width:520px){ .src-pill{display:none;} }

/* ══════════════════════════════════════════════════════
   THE AFFILIATE AGREEMENT GATE
   ══════════════════════════════════════════════════════
   Two steps in front of the program, drawn as a card over a blurred page. The
   blur is the reason the page is still visible behind it: the reader is not
   somewhere else, they are in front of something. The sign-in page is the product's
   other blocking surface and this borrows its shape — one card, one gold glow
   above it, nothing else on screen to click.
   ══════════════════════════════════════════════════════ */
.affgate{
  position:relative;display:grid;place-items:center;padding:8px 0 28px;
  min-height:min(74vh,720px);
}
/* The glass. `backdrop-filter` over a radial gold wash, which is the same
   treatment the sign-in screen and the top bar already use — a new blur recipe
   here would read as a different product. */
.affgate::before{
  content:'';position:absolute;inset:-8px;border-radius:var(--r3);
  background:radial-gradient(760px 380px at 50% -6%,var(--gold-glow),transparent 64%);
  -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
  pointer-events:none;
}
.affgate-card{
  position:relative;width:100%;max-width:620px;
  background:linear-gradient(165deg,rgba(22,26,33,.94),rgba(13,16,21,.96));
  border:1px solid var(--gold-line);border-radius:var(--r3);
  box-shadow:0 28px 70px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.02) inset;
  display:flex;flex-direction:column;overflow:hidden;
}
.affgate-head{display:flex;align-items:center;gap:12px;padding:16px 20px;
  border-bottom:1px solid var(--line-2);}
.affgate-mark{display:flex;align-items:center;gap:9px;color:var(--gold);min-width:0;}
.affgate-mark b{font-family:var(--f-display);font-size:12px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--fg-2);font-weight:700;}
html[lang="fa"] .affgate-mark b,html[lang="ar"] .affgate-mark b{letter-spacing:0;
  text-transform:none;font-size:13px;}
/* Two dots rather than "Step 1 of 2": at this length the words are longer than
   the thing they describe. */
.affgate-steps{display:flex;gap:6px;margin-inline-start:auto;}
.affgate-steps span{width:22px;height:3px;border-radius:99px;background:var(--bg-4);}
.affgate-steps span.on{background:var(--gold);}
.affgate-steps span.done{background:var(--gold-dp);}

.affgate-body{padding:20px;}
.affgate-title{font-family:var(--f-display);font-size:19px;font-weight:700;
  letter-spacing:-.01em;margin-bottom:6px;}
.affgate-sub{font-size:13px;color:var(--fg-2);line-height:1.75;margin-bottom:18px;}

/* ── The three ── */
.affacks{display:flex;flex-direction:column;gap:9px;}
.affack{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:start;
  padding:14px 15px;border-radius:var(--r2);border:1px solid var(--line-2);
  background:var(--bg-2);transition:border-color .18s,background .18s;}
.affack:hover{border-color:var(--gold-line);}
.affack.on{border-color:var(--gold);background:var(--gold-pale);}
.affack-box{width:20px;height:20px;border-radius:5px;flex-shrink:0;margin-top:1px;
  border:1.5px solid var(--line);display:flex;align-items:center;justify-content:center;
  color:transparent;transition:all .18s;}
.affack-box .ic{width:13px;height:13px;stroke-width:2.4;}
.affack.on .affack-box{background:var(--gold);border-color:var(--gold);color:var(--on-gold);}
.affack-text{min-width:0;display:flex;flex-direction:column;gap:4px;}
.affack-t{font-size:13.5px;font-weight:600;color:var(--fg);line-height:1.4;}
.affack.on .affack-t{color:var(--gold-lt);}
.affack-d{font-size:12px;color:var(--fg-3);line-height:1.7;}

/* ── The document ──
   Scrolls inside itself and is the only thing on this card that does. The
   height is capped in `vh` so the card never grows past the window and takes
   the Sign button off the bottom of it with no way to reach it. */
.affgate-body-doc{display:flex;flex-direction:column;min-height:0;}
.affdoc{
  max-height:min(46vh,420px);overflow-y:auto;overscroll-behavior:contain;
  border:1px solid var(--line-2);border-radius:var(--r2);background:var(--bg-0);
  padding:16px 17px;font-size:12.5px;line-height:1.8;color:var(--fg-2);
}
.affdoc:focus-visible{outline:2px solid var(--gold-line);outline-offset:2px;}
.affdoc-title{font-family:var(--f-display);font-size:13px;letter-spacing:.06em;
  color:var(--gold-lt);margin-bottom:8px;}
.affdoc-pre{margin-bottom:14px;color:var(--fg-2);}
.affdoc-c{margin-bottom:13px;}
.affdoc-c h4{font-size:12.5px;font-weight:700;color:var(--fg);margin-bottom:3px;}
.affdoc-c p{margin:0;}
.affdoc-end{margin-top:16px;padding-top:10px;border-top:1px solid var(--line-2);
  font-family:var(--f-mono);font-size:10.5px;color:var(--fg-3);text-align:center;}

/* Says whether the condition for signing has been met, and changes when it is
   rather than only unlocking a button somewhere else. */
.affdoc-flag{display:flex;align-items:center;gap:8px;margin-top:10px;
  font-size:11.5px;color:var(--fg-3);transition:color .2s;}
.affdoc-flag .ic{width:14px;height:14px;}
.affdoc-flag.on{color:var(--up);}

/* ── The signature ── */
.affsign{display:grid;grid-template-columns:minmax(0,1fr) 92px 130px;gap:10px;margin-top:16px;}
@media(max-width:560px){.affsign{grid-template-columns:minmax(0,1fr) 92px;}
  .affsign-f:last-child{grid-column:1 / -1;}}
.affsign-f{display:flex;flex-direction:column;gap:5px;min-width:0;}
.affsign-f > span{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--fg-3);}
html[lang="fa"] .affsign-f > span,html[lang="ar"] .affsign-f > span{letter-spacing:0;
  text-transform:none;font-size:12px;}
.affsign-f input{
  width:100%;padding:11px 12px;min-height:44px;border-radius:var(--r1);
  background:var(--bg-2);border:1px solid var(--line-2);color:var(--fg);font-size:13.5px;
  transition:border-color .18s;
}
.affsign-f input:focus{outline:none;border-color:var(--gold);}
.affsign-f input[readonly]{color:var(--fg-3);background:var(--bg-1);}
/* The name is a signature: it is set in the display face and left-to-right in
   every language, because a name is not a sentence. */
#affName{font-family:var(--f-display);font-size:15px;direction:ltr;text-align:start;}
#affCountry{text-transform:uppercase;direction:ltr;}
.affsign-note{margin-top:12px;}

.affgate-foot{display:flex;align-items:center;gap:12px;padding:15px 20px;
  border-top:1px solid var(--line-2);background:rgba(0,0,0,.18);}
.affgate-note{font-size:11.5px;color:var(--fg-3);line-height:1.6;min-width:0;}
.affgate-go{margin-inline-start:auto;flex-shrink:0;}
.affgate-go[disabled]{opacity:.38;pointer-events:none;box-shadow:none;}
@media(max-width:520px){
  .affgate-foot{flex-wrap:wrap;}
  .affgate-go{width:100%;margin-inline-start:0;}
}

/* ══════════════════════════════════════════════════════
   THE PHONE — what measurement said was wrong, and only that
   ══════════════════════════════════════════════════════
   One query, at the same 1023px boundary the rest of the shell uses, so the
   desktop is untouched by everything in it. Nothing here is a restyle for its
   own sake: each rule answers a figure taken off a 390px viewport with the
   page signed in and live.

   THE LAYOUT ITSELF IS NOT FIXED HERE. That was one token — `minmax(0,1fr)`
   on `.dash`, near the top of this file — and it is what made Home visible at
   all. What follows is the part that is a matter of degree: reach, and the two
   places where two columns is one too many.
   ══════════════════════════════════════════════════════ */
@media(max-width:1023px){

  /* ── Reach ──
     Every one of these measured under 44px, which is the smallest thing a
     finger hits reliably. They are listed rather than swept up by a blanket
     `button{min-height:44px}` because several of these elements are laid out
     by their height — a bar 56px tall does not take a blanket. */
  .menu-btn{width:44px;height:44px;}
  .icon-btn{width:44px;height:44px;}
  .lang-btn{min-height:44px;}
  .tb-logo{min-height:44px;}
  /* `.sm` is named on both. The small variants carry their own `min-height`
     under a two-class selector, so a one-class rule here loses to them however
     late it appears — 36px stayed 36px until these matched their specificity. */
  .btn-gold.sm,.btn-ghost.sm,.btn-ghost{min-height:44px;}
  /* The chart's range tabs measured 28x33 — the smallest target on the page,
     and one a reader taps repeatedly. The type stays where it is; the box
     grows around it. Padding alone reached 38px because the base rule sets a
     `min-height` of its own. */
  .range-tab{padding:12px 14px;min-height:44px;}
  /* "See all" measured 15px tall. It is text, so it gets a box. */
  .section-head .link{display:inline-flex;align-items:center;min-height:44px;padding:0 4px;}

  /* ── One column where two were too narrow ──
     The coin chips measured 160px wide and 113px tall: a badge, a name, a
     figure and a note folded into four lines each. Full width they are two
     lines, and the badge sits beside the number instead of above it. */
  .coin-chips{grid-template-columns:1fr;}

  /* The hero number is the largest thing on the page and the first thing read;
     at 390px it was crowding its own percentage chip. */
  .hero-total{gap:9px;}
  .center{padding-inline:14px;}
}

/* Under 380px — the small phones that are still in use — the two stat columns
   stop being worth it for the same reason the coin chips did. */
@media(max-width:379px){
  .hero-grid{grid-template-columns:1fr;}
}

/* ══════════════════════════════════════════════════════
   PRINT — the contract document must survive paper
   ══════════════════════════════════════════════════════ */
/* This block used to be purely SUBTRACTIVE — it hid the chrome, unclipped
   `.doc`, and stopped. No `@page`, so the printed sheet took whatever margin
   the browser felt like; no break rules, so a clause could split across two
   pages and the signature block could land alone on the last one; and nothing
   said which contract a loose middle page belonged to.

   It is a real page layout now. What it still does NOT do is number the pages:
   Chrome does not implement the `@page` margin boxes that would put a counter
   there, and the browser's own print dialog already offers headers and footers
   that do it properly. Faking it with a fixed element would number every page
   "1".

   ONE MORE THING WORTH KNOWING: the typefaces come from Google Fonts over the
   network. A printed page from an offline browser falls back to the system
   serif stack named below, which is why one is named rather than left to
   chance. */
@page{size:A4;margin:18mm 16mm 20mm;}

@media print{
  .topbar,.tabbar,.drawer,.scrim,.notif-panel,.acct-pop,#bgCanvas,.toast,
  .src-pill,.imp-bar,.screen-head,.cdoc-tools,.btn-row,
  .deskbar{display:none !important;}

  html,body{background:#fff !important;color:#000;padding:0;margin:0;}
  .center,.stage,.screen{padding:0 !important;margin:0 !important;max-width:none !important;}

  /* Paper is not a dark interface. Every colour below is restated for white
     rather than inherited, because a token tuned for #0A0C10 prints as a smear
     of grey on cream. */
  .doc,.cdoc-head,.cdoc-part,.cdoc-exec{
    background:#fff !important;color:#000 !important;
    border-color:#bbb !important;border-radius:0 !important;
  }
  .doc{max-height:none;overflow:visible;font-size:10pt;line-height:1.65;}
  .cdoc-body{border-left:none !important;border-right:none !important;}
  .doc .doc-title,.cdoc-brand{color:#000 !important;}
  .cdoc-kind,.cdoc-h2,.cdoc-h3,.cdoc-note,.cdoc-fp div,.cdoc-gov,
  .agr-sign span,.cdoc-cf i{color:#444 !important;}
  .doc h4,.agr-sign b,.cdoc-ref b,.cdoc-fp code,.cdoc-cf{color:#000 !important;}
  .agr-sign .agr-sig-name{color:#000 !important;}
  .cdoc-mark{
    background:none !important;color:#000 !important;
    border:1.5pt solid #000;box-shadow:none;
  }

  /* ── Where the page is allowed to break ──
     A heading at the foot of a page with its clause overleaf is the classic
     way a printed agreement reads as careless. */
  .doc h4{break-after:avoid;break-inside:avoid;}
  .doc p,.doc li,.agr-defs>*{break-inside:avoid;orphans:3;widows:3;}
  .cdoc-head,.cdoc-part{break-inside:avoid;break-after:avoid;}
  /* THE EXECUTION BLOCK IS NEVER SPLIT. A name on one sheet and the date it was
     accepted on the next is the one break on this document that actually
     matters. */
  .cdoc-exec,.agr-sign,.cdoc-fp,.cdoc-confirms{break-inside:avoid;}

  /* The running head. `position:fixed` is what repeats an element on every
     printed page in every engine that supports printing at all; the letterhead
     proper sits at the top of page one and this carries the same two facts
     onto the rest. */
  .cdoc-runhead{
    display:flex !important;justify-content:space-between;gap:12px;
    position:fixed;top:0;left:0;right:0;
    font-size:8pt;letter-spacing:.06em;text-transform:uppercase;color:#555;
    border-bottom:.5pt solid #ccc;padding-bottom:3pt;
  }
  .cdoc{padding-top:6mm;}

  /* A sheet is a screen device; if one is somehow open at print time it prints
     in flow rather than as a floating panel. */
  .sheet{position:static;transform:none;opacity:1;max-height:none;box-shadow:none;}
}

/* ══════════════════════════════════════════════════════
   §10 — the impersonation banner
   ══════════════════════════════════════════════════════
   An administrator inside somebody's account, and the one thing that keeps the
   feature honest: a session that looks exactly like the reader's own, except
   that it says it is not.

   FIXED, FULL WIDTH, AND WITH NO CLOSE CONTROL. Every other notice on this
   dashboard can be dismissed because every other notice is about the reader's
   own business. This one is about who is holding the account, it is true for
   as long as the session lives, and an operator who could hide it would
   eventually forget which account they were in.

   Red rather than gold. The palette's gold is the brand and it reads as
   ordinary here; this is the one bar on the page that should not look like it
   belongs. */
.imp-bar{
  position:fixed;inset-inline:0;top:0;z-index:400;
  display:flex;align-items:center;gap:12px;padding:9px 16px;
  background:linear-gradient(180deg,#5a1220,#3d0c16);
  border-bottom:1px solid rgba(255,120,140,.45);
  box-shadow:0 6px 24px rgba(0,0,0,.45);
  font-size:12.5px;color:#ffe6ea;
}
.imp-bar .imp-ic{display:inline-flex;flex:0 0 auto;color:#ff8fa3}
.imp-bar .imp-ic svg{width:18px;height:18px}
.imp-text{display:flex;flex-direction:column;gap:1px;min-width:0;line-height:1.5}
.imp-text b{font-weight:600}
.imp-text span{color:rgba(255,230,234,.72);font-size:11.5px}
.imp-leave{
  margin-inline-start:auto;flex:0 0 auto;cursor:pointer;
  padding:6px 13px;border-radius:999px;font-size:12px;font-weight:600;
  background:rgba(255,255,255,.12);color:#fff;
  border:1px solid rgba(255,255,255,.28);
}
.imp-leave:hover{background:rgba(255,255,255,.2)}

/* The page moves down by the bar's height rather than sliding under it — a
   banner that covers the top navigation is a banner that breaks the screen it
   is warning about. */
body.impersonating{padding-top:46px}
body.impersonating .topbar{top:46px}
@media (max-width:640px){
  .imp-bar{padding:8px 12px;gap:9px}
  .imp-text span{display:none}
  body.impersonating{padding-top:40px}
  body.impersonating .topbar{top:40px}
}

/* ══ A NOTICE FROM THE DESK ══════════════════════════
   An interrupting message, and it is deliberately NOT dressed as an alarm.

   Stopping somebody's screen is already the loudest act this interface has; a
   red border and the word URGENT on top of it is the design shouting over
   itself, and it makes a message from the desk look like something that broke.
   The weight here comes from PROVENANCE instead — the platform's own seal, its
   name, and the hour the notice was sent, set in the same mono face every other
   fact on this product is set in.

   One accent, used twice: the seal and the action. Everything else is the
   neutral scale. That restraint is the design. */
.nt-scrim{position:fixed;inset:0;z-index:200;display:flex;align-items:center;
  justify-content:center;padding:20px;
  background:rgba(6,8,12,0.74);
  backdrop-filter:blur(6px) saturate(120%);-webkit-backdrop-filter:blur(6px) saturate(120%);
  animation:ntFade 0.24s var(--ease) both;}
body.nt-open{overflow:hidden;}

.nt-card{width:min(560px,100%);max-height:min(84vh,720px);display:flex;flex-direction:column;
  background:var(--bg-1);border:1px solid var(--line);border-radius:var(--r3);
  box-shadow:0 1px 0 rgba(255,255,255,0.04) inset, 0 30px 70px -20px rgba(0,0,0,0.75);
  animation:ntRise 0.34s var(--ease) both;outline:none;overflow:hidden;}

/* ── The letterhead ── */
.nt-head{display:flex;align-items:center;gap:12px;padding:18px 20px 16px;
  border-bottom:1px solid var(--hair);flex:none;}
/* The product's own mark, as a seal. Same treatment as the top bar, without the
   idle float — a notice does not bob. */
.nt-seal{width:34px;height:34px;border-radius:var(--r2);flex:none;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(145deg,var(--gold-lt),var(--gold-dp));
  font-family:var(--f-display);font-weight:800;font-size:16px;color:var(--on-gold);
  box-shadow:0 3px 14px var(--gold-glow);}
.nt-from{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1;}
.nt-from b{font-family:var(--f-display);font-weight:800;font-size:15px;letter-spacing:0.03em;
  color:var(--fg);line-height:1.2;}
.nt-from i{font-style:normal;font-size:11.5px;color:var(--fg-3);line-height:1.3;}
.nt-when{font-family:var(--f-mono);font-size:11px;color:var(--fg-3);flex:none;
  align-self:flex-start;padding-top:2px;white-space:nowrap;}
/* A Jalali or Hijri date is words, not digits, and IBM Plex Mono has no glyphs
   for either — the fallback stretched "شهریور" across the header. The body face
   carries these calendars; mono stays for the figures that are actually mono. */
html[lang="fa"] .nt-when,html[lang="ar"] .nt-when,
html[lang="fa"] .notif-full-time,html[lang="ar"] .notif-full-time{
  font-family:var(--f-body);font-size:11.5px;}

/* ── The message ──
   It scrolls, and the header and the action do not: on a long notice the way
   out must never be below the fold. */
.nt-scroll{overflow-y:auto;padding:18px 20px 20px;flex:1 1 auto;min-height:0;
  overscroll-behavior:contain;}
.nt-msg{margin:0;font-size:15px;line-height:1.85;color:var(--fg);
  white-space:pre-wrap;overflow-wrap:anywhere;}

/* ── The footer ── */
.nt-foot{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:14px 20px 16px;border-top:1px solid var(--hair);background:var(--bg-0);flex:none;}
.nt-seq{font-family:var(--f-mono);font-size:11.5px;color:var(--fg-3);letter-spacing:0.06em;
  direction:ltr;unicode-bidi:isolate;}
.nt-seq i{font-style:normal;opacity:0.45;margin:0 3px;}
.nt-go{min-width:168px;}

@keyframes ntFade{from{opacity:0}to{opacity:1}}
@keyframes ntRise{from{opacity:0;transform:translateY(14px) scale(0.985)}
                  to{opacity:1;transform:none}}
@media(max-width:479px){
  .nt-scrim{padding:0;align-items:flex-end;}
  .nt-card{max-height:88vh;border-radius:var(--r3) var(--r3) 0 0;border-bottom:none;}
  .nt-go{min-width:0;flex:1;}
  .nt-foot{padding-bottom:calc(16px + env(safe-area-inset-bottom));}
}
/* A reader who has asked for less motion gets the dialog, not the entrance. */
@media(prefers-reduced-motion:reduce){
  .nt-scrim,.nt-card{animation:none;}
}
body.no-motion .nt-scrim,body.no-motion .nt-card{animation:none;}

/* ══ ONE NOTIFICATION, IN FULL ═══════════════════════
   The bell shows two lines; this is the whole thing. */
.notif-full-head{display:flex;align-items:center;gap:11px;margin-bottom:13px;}
.notif-full-time{font-family:var(--f-mono);font-size:11.5px;color:var(--fg-3);margin-bottom:5px;}
.notif-full-body{margin:0;font-size:15px;line-height:1.85;color:var(--fg);
  white-space:pre-wrap;overflow-wrap:anywhere;}

/* ══ THE BELL ROW STAYS A ROW ════════════════════════
   Two lines of the opening, then the tap. A five-paragraph notice rendered in
   full here took over the panel and pushed every other alert off the bottom. */
.notif-title{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;text-align:start;}
.nt-msg,.notif-full-body{text-align:start;}
.notif-time{display:flex;align-items:center;gap:7px;}
.notif-more{font-weight:600;color:var(--gold);font-size:10px;letter-spacing:0.08em;
  text-transform:uppercase;}
html[lang="fa"] .notif-more,html[lang="ar"] .notif-more{letter-spacing:0;text-transform:none;
  font-size:11px;}

/* ══════════════════════════════════════════════════════
   MARKET WATCH — the screen at #/market
   ══════════════════════════════════════════════════════
   A data-dense page built from the same parts as the rest of the product:
   `.dash` grid, `.mod` cards, `.dt` tables, `.filter-chip`. What is new here is
   only what a market page needs and nothing else had — a sticky asset header, a
   timeframe rail, indicator toggles, and the chart's own container.

   THE PHONE IS NOT THIS LAYOUT COMPRESSED. Below 1024px the two side panels
   stop being a column beside the chart and become one segmented control under
   it, because a phone reader is looking at one instrument at a time and
   scrolling past a table to reach the chart is the wrong order. `data-pane` on
   the root decides which of the two is showing.
   ══════════════════════════════════════════════════════ */

/* ── The development-fixture banner ──
   A bar, not a chip. A fixture that announces itself quietly is a fixture
   somebody eventually reads as a price. */
.mw-fixture{display:flex;flex-direction:column;gap:4px;margin:0 0 16px;padding:12px 14px;
  border-radius:var(--r2);background:var(--warn-pale);border:1px solid var(--warn-line);}
.mw-fixture b{display:flex;align-items:center;gap:8px;font-size:12px;letter-spacing:0.08em;
  text-transform:uppercase;color:var(--warn);}
.mw-fixture b svg{width:15px;height:15px;flex:none;}
.mw-fixture span{font-size:12px;line-height:1.65;color:var(--fg-2);}
html[lang="fa"] .mw-fixture b,html[lang="ar"] .mw-fixture b{letter-spacing:0;text-transform:none;
  font-size:13px;}

.mw-head{margin-bottom:14px;}

/* ══ THE ANALYSIS CONTROL, IN THE FOOT OF THE CHART CARD ══
   Under the chart rather than up in the page header, because what it reads is
   the instrument and timeframe currently drawn — a control sitting inches away
   from its own subject is one a reader has to guess the scope of.

   The hairline is what makes it read as the card's action rather than as more
   chart furniture; `margin-top:auto` pins it to the bottom on the desktop
   layout, where the card is a flex column taller than its contents. */
.mw-chart-foot{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin-top:auto;padding-top:12px;border-top:1px solid var(--line-2);}

/* ── The language of the reading ──
   A SEPARATE CHOICE FROM THE LANGUAGE OF THE PAGE, so it is a separate
   control. Same shape as the watchlist's span menu — a button naming the
   current choice, a popup listing the rest — because it is the same gesture,
   and a second dropdown idiom on one screen is one to learn twice.

   IT OPENS UPWARD. This sits at the very bottom of the chart card; a menu
   dropping below it would open past the end of the card and, on a phone, in
   behind the tab bar. */
.mwa-lang{position:relative;flex:none;}
.mwa-lang-btn{display:inline-flex;align-items:center;gap:6px;appearance:none;
  border:1px solid var(--line);background:var(--bg-2);cursor:pointer;
  border-radius:var(--r2);padding:7px 10px;min-height:36px;
  font-family:inherit;font-size:12px;color:var(--fg-2);}
.mwa-lang-btn:hover{border-color:var(--gold-line);color:var(--fg);}
.mwa-lang-btn svg{width:13px;height:13px;flex:none;opacity:.75;}
/* The chosen name is content in its own script, so it is isolated from the
   page's direction the way every other native string here is. */
.mwa-lang-cur{unicode-bidi:isolate;}
.mwa-lang-caret{transition:transform .18s var(--ease);}
.mwa-lang.open .mwa-lang-caret{transform:rotate(180deg);}

/* ── Both menus in the row share one geometry ──
   `mwaPlaceMenu` measures the room and sets `max-height` in pixels, so the cap
   here is only the ceiling it clamps against. Upward is the default; `.drop`
   is set when there is not enough room above. */
.mwa-pop{display:none;position:absolute;bottom:calc(100% + 6px);top:auto;
  inset-inline-start:0;
  z-index:20;padding:5px;border-radius:var(--r2);
  background:var(--bg-2);border:1px solid var(--line);
  box-shadow:0 16px 34px rgba(0,0,0,.5);
  max-height:min(320px,52vh);overflow-y:auto;overscroll-behavior:contain;}
.open > .mwa-pop{display:flex;flex-direction:column;gap:2px;}
.drop > .mwa-pop{bottom:auto;top:calc(100% + 6px);}

.mwa-lang-pop{min-width:150px;}
.mwa-lang.drop .mwa-lang-caret{transform:none;}
.mwa-lang.open.drop .mwa-lang-caret{transform:rotate(180deg);}

/* ── The readings this account still has ──
   ONE CONTROL WITH A COUNT, NOT A ROW OF CHIPS. Forty-eight hours is enough to
   accumulate a couple of dozen readings, and a row of chips at that point is a
   horizontal scroll bar under a chart — the kind of thing that works the day
   it is built and not a week later. This is the same size at two entries and
   at twenty. */
.mwa-recent{position:relative;flex:none;}
.mwa-recent-btn{display:inline-flex;align-items:center;gap:6px;appearance:none;
  border:1px solid var(--line);background:var(--bg-2);cursor:pointer;
  border-radius:var(--r2);padding:7px 10px;min-height:36px;
  font-family:inherit;font-size:12px;color:var(--fg-2);}
.mwa-recent-btn:hover{border-color:var(--gold-line);color:var(--fg);}
.mwa-recent-btn svg{width:13px;height:13px;flex:none;opacity:.75;}
.mwa-recent-n{padding:1px 6px;border-radius:999px;background:var(--bg-4);
  font-size:10.5px;color:var(--fg-2);}
.mwa-recent-caret{transition:transform .18s var(--ease);}
.mwa-recent.open .mwa-recent-caret{transform:rotate(180deg);}
.mwa-recent.drop .mwa-recent-caret{transform:none;}
.mwa-recent.open.drop .mwa-recent-caret{transform:rotate(180deg);}

.mwa-recent-pop{min-width:min(340px,86vw);}
.mwa-recent-opt{appearance:none;border:0;background:transparent;cursor:pointer;
  display:flex;flex-direction:column;gap:3px;align-items:stretch;
  font-family:inherit;border-radius:var(--r1);padding:9px 10px;text-align:start;}
.mwa-recent-opt:hover{background:var(--bg-3);}
.mwa-recent-opt.active{background:var(--gold-pale);}
.mwa-recent-top{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;}
.mwa-recent-sym{font-size:12.5px;color:var(--fg);font-weight:700;}
.mwa-recent-tf{font-size:11px;color:var(--fg-2);}
.mwa-recent-lg{font-size:11px;color:var(--fg-3);unicode-bidi:isolate;}
/* Pushed to the end of the row, whichever direction the page runs. */
.mwa-recent-at{font-size:10.5px;color:var(--fg-3);margin-inline-start:auto;}
/* The headline is the reading's own words in the reading's own language, which
   is not necessarily the page's — so it is isolated and clipped rather than
   allowed to wrap a menu open to three lines. */
.mwa-recent-h{font-size:11.5px;line-height:1.5;color:var(--fg-3);
  unicode-bidi:isolate;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mwa-recent-opt.active .mwa-recent-h{color:var(--fg-2);}
.mwa-recent-note{padding:8px 10px 3px;font-size:10.5px;line-height:1.5;
  color:var(--fg-3);border-top:1px solid var(--line-2);margin-top:4px;}
.mwa-lang-opt{appearance:none;border:0;background:transparent;cursor:pointer;
  font-family:inherit;font-size:13px;color:var(--fg-3);border-radius:var(--r1);
  padding:8px 10px;text-align:start;unicode-bidi:isolate;}
.mwa-lang-opt:hover{background:var(--bg-3);color:var(--fg-2);}
.mwa-lang-opt.active{background:var(--gold-pale);color:var(--gold-lt);font-weight:600;}

/* It carries its own remaining count, so pressing it is never a surprise. */
.mwa-btn{gap:8px;}
.mwa-btn svg{width:15px;height:15px;color:var(--gold);}
.mwa-btn-t{font-weight:700;}
.mwa-btn-n{font-size:11px;color:var(--fg-3);letter-spacing:0.02em;
  padding-inline-start:8px;margin-inline-start:2px;border-inline-start:1px solid var(--line);}
/* Nothing left is not an error — it is an offer. Warm rather than red. */
.mwa-btn.spent svg{color:var(--fg-3);}
.mwa-btn.spent .mwa-btn-n{color:var(--gold);}

/* ══ THE ANALYSIS DRAWER ═══════════════════════════════
   A DRAWER IN THE CARD, NOT A WINDOW OVER THE PAGE.

   The first version was a floating overlay: fixed to the viewport, a scrim
   behind it, the page scroll locked. It worked and it was the wrong shape. A
   reading is ABOUT the chart a few centimetres above it, and an overlay is a
   thing you put in front of what you were looking at — the reader could not
   check a sentence against the candles it describes without dismissing the
   sentence first.

   So it expands in place, under the row it was launched from. Nothing is
   covered, nothing is trapped, and the page scrolls normally around it. */
.mwa-panel{display:none;}
.mwa-panel.open{display:block;margin-top:12px;padding-top:14px;
  border-top:1px solid var(--line);
  animation:mwaSlide .26s var(--ease);}
@keyframes mwaSlide{from{opacity:0;transform:translateY(-6px);}
  to{opacity:1;transform:none;}}

.mwa-head{display:flex;align-items:flex-start;gap:12px;
  padding-bottom:12px;margin-bottom:14px;border-bottom:1px solid var(--line-2);}
.mwa-head-t{min-width:0;}
.mwa-eyebrow{display:block;font-size:10px;letter-spacing:0.16em;text-transform:uppercase;
  color:var(--gold);font-weight:700;}
html[lang="fa"] .mwa-eyebrow,html[lang="ar"] .mwa-eyebrow{letter-spacing:0;text-transform:none;font-size:11px;}
.mwa-title{font-family:var(--f-display);font-weight:800;font-size:16px;margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Which language the reading is in. Quieter than the instrument — it labels
   the text below rather than naming the subject. */
.mwa-title-lang{font-weight:600;font-size:12.5px;color:var(--fg-3);
  unicode-bidi:isolate;}
.mwa-title-lang::before{content:'·';margin:0 7px;color:var(--fg-3);opacity:.6;}
.mwa-head-e{margin-inline-start:auto;display:flex;align-items:center;gap:10px;flex:none;}
.mwa-left{font-size:11px;color:var(--fg-3);white-space:nowrap;}

/* No scroll of its own: the drawer is part of the page now, and the page is
   what scrolls. A nested scroll region inside a card is a second thing to
   drag and a place a reader's wheel gesture gets swallowed. */
.mwa-body{}

.mwa-working{display:flex;flex-direction:column;gap:10px;padding:22px 0;text-align:center;}
.mwa-working b{font-family:var(--f-display);font-size:14px;}
.mwa-working span{font-size:12px;color:var(--fg-3);line-height:1.6;}
.mwa-working .mwx-skel{margin-bottom:6px;}

.mwa-err{display:flex;flex-direction:column;align-items:center;gap:9px;
  padding:26px 8px;text-align:center;}
.mwa-err-ic{width:22px;height:22px;color:var(--warn);}
.mwa-err b{font-family:var(--f-display);font-size:14px;}
.mwa-err span{font-size:12px;color:var(--fg-3);line-height:1.65;max-width:44ch;}
.mwa-err-acts{display:flex;gap:9px;margin-top:6px;}

.mwa-note{display:flex;align-items:center;gap:8px;margin-bottom:14px;
  padding:9px 12px;border-radius:var(--r2);font-size:11.5px;color:var(--fg-2);
  background:var(--bg-2);border:1px solid var(--line-2);}
.mwa-note svg{width:13px;height:13px;flex:none;color:var(--fg-3);}

.mwa-lead{font-family:var(--f-display);font-weight:700;font-size:15.5px;
  line-height:1.55;margin-bottom:16px;}

.mwa-sec{margin-bottom:16px;}
.mwa-sec-h{font-size:10.5px;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--fg-3);font-weight:700;margin-bottom:6px;}
html[lang="fa"] .mwa-sec-h,html[lang="ar"] .mwa-sec-h{letter-spacing:0;text-transform:none;font-size:12px;}
.mwa-sec-b{font-size:13px;line-height:1.85;color:var(--fg-2);}

/* ── THE LINE BETWEEN WHAT WAS MEASURED AND WHAT WAS NOT ──
   Everything above this block is a reading of figures the platform computed.
   This one is the model's general knowledge and carries no figure at all. That
   distinction is the honesty of this whole feature, so it is DRAWN rather than
   left to the reader to infer: its own rule, its own ground, and a sentence
   under it saying exactly what it is. */
.mwa-fund{margin-top:20px;padding-top:16px;border-top:1px solid var(--line);}
.mwa-fund .mwa-sec-h{color:var(--gold-dp);}
.mwa-fund-note{font-size:11px;line-height:1.7;color:var(--fg-3);
  padding:10px 12px;border-radius:var(--r2);background:var(--bg-2);
  border:1px solid var(--line-2);margin-bottom:16px;}

/* ── The fact sheet ──
   Folded away by default. A reader who wants the reading gets the reading; a
   reader who wants to check it gets every number the model was handed. */
.mwa-figs{margin-top:4px;}
.mwa-figs-b{display:inline-flex;align-items:center;gap:6px;
  font-size:11.5px;color:var(--fg-3);background:none;border:0;cursor:pointer;padding:4px 0;}
.mwa-figs-b:hover{color:var(--fg-2);}
.mwa-figs-caret{width:13px;height:13px;transition:transform .18s var(--ease);}
.mwa-figs-caret.up{transform:rotate(180deg);}
.mwa-figs-w{margin-top:8px;padding:12px;border-radius:var(--r2);
  background:var(--bg-0);border:1px solid var(--line-2);
  max-height:280px;overflow:auto;overscroll-behavior:contain;}
.mwa-figs-t{font-size:10.5px;letter-spacing:0.12em;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:8px;}
html[lang="fa"] .mwa-figs-t,html[lang="ar"] .mwa-figs-t{letter-spacing:0;text-transform:none;font-size:11.5px;}
.mwa-figs-tbl{width:100%;border-collapse:collapse;}
.mwa-figs-tbl th{text-align:start;font-weight:500;font-size:11.5px;color:var(--fg-3);
  padding:4px 8px 4px 0;white-space:nowrap;
  /* A key is a source identifier — `priceVsEma200Pct` — and it reads
     left-to-right whatever the page's direction is. */
  direction:ltr;unicode-bidi:isolate;}
.mwa-figs-tbl td{text-align:end;font-size:12px;padding:4px 0;
  font-variant-numeric:tabular-nums;}

.mwa-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin-top:18px;padding-top:12px;border-top:1px solid var(--line-2);
  font-size:11px;color:var(--fg-3);}
.mwa-model{direction:ltr;unicode-bidi:isolate;}
.mwa-disc{margin-top:8px;font-size:10.5px;line-height:1.7;color:var(--fg-3);opacity:.85;}

.mwa-buy-lead{font-size:13px;line-height:1.8;color:var(--fg-2);margin-bottom:14px;}

@media(max-width:767px){
  .mwa-title{font-size:15px;}
  /* The count leaves the drawer's own header on a narrow screen — the subject
     and the collapse control are what a thumb needs there, and the count is on
     the button a few pixels above anyway. */
  .mwa-left{display:none;}
  .mwa-sec-b{font-size:12.5px;}
  /* 44px targets, as everywhere else on this screen. */
  .mwa-figs-b{min-height:44px;}
  .mw-chart-foot{padding-top:10px;gap:8px;}
  /* All three full width and stacked. Side by side at 390px the button loses
     its count and the language name truncates to nothing useful. */
  .mwa-btn{width:100%;justify-content:center;min-height:44px;}
  .mwa-lang,.mwa-recent{width:100%;}
  .mwa-lang-btn,.mwa-recent-btn{width:100%;justify-content:center;min-height:44px;}
  .mwa-pop{inset-inline:0;min-width:0;}
  .mwa-lang-opt{min-height:44px;display:flex;align-items:center;}
  .mwa-recent-opt{min-height:44px;}
  .mwa-panel.open{margin-top:10px;padding-top:12px;}
}

@media(prefers-reduced-motion:reduce){
  .mwa-figs-caret,.mwa-lang-caret,.mwa-recent-caret{transition:none;}
  .mwa-panel.open{animation:none;}
}


/* ── Asset classes ── */
.mw-classes{display:flex;gap:8px;overflow-x:auto;padding-bottom:4px;margin-bottom:14px;
  scrollbar-width:none;-ms-overflow-style:none;}
.mw-classes::-webkit-scrollbar{display:none;}
.mw-classes .filter-chip{flex:none;display:inline-flex;align-items:center;gap:6px;}
.mw-lock{display:inline-flex;opacity:.5;}
.mw-lock svg{width:12px;height:12px;}

/* ── The sticky asset header ──
   `top` clears the fixed top bar. It is the answer to "what am I looking at"
   and the chart scrolls under it. */
.mw-asset{position:sticky;top:calc(var(--topbar-h) + 6px);z-index:12;
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  padding:13px 16px;margin-bottom:14px;border-radius:var(--r2);
  background:var(--bg-1);border:1px solid var(--line-2);
  box-shadow:0 6px 22px -14px rgba(0,0,0,0.8);}
.mw-asset-id{display:flex;flex-direction:column;gap:2px;min-width:0;}
.mw-sym{font-family:var(--f-display);font-weight:800;font-size:17px;letter-spacing:0.02em;
  color:var(--fg);}
.mw-name{font-size:11.5px;color:var(--fg-3);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;}

/* ── THE INSTRUMENT'S OWN FOOTNOTE ──
   Thirteen catalogue rows are perpetual contracts on the thing their label
   names, not the thing itself. Six characters beside the symbol and the whole
   sentence in the `title`, which is the same bargain `.zx-mon-note` strikes on
   the monitor — deliberately the same treatment, so a reader who has learned
   what the tag means on one screen has learned it on both. `cursor:help` is
   what says there is more to read. */
.mw-r-note,.mw-asset .mw-note{font-style:normal;font-family:var(--f-mono);font-size:8px;
  letter-spacing:0.1em;color:var(--fg-3);border:1px solid var(--line);border-radius:2px;
  padding:0 3px;margin-inline-start:6px;opacity:.85;cursor:help;vertical-align:1px;
  white-space:nowrap;flex:none;}
.mw-sym-row{display:flex;align-items:center;min-width:0;}
.mw-sym-row .mw-r-note{font-size:8.5px;vertical-align:0;}
.dt tr:hover .mw-r-note{color:var(--fg-2);border-color:var(--rim-hi);}
.mw-asset-px{display:flex;align-items:baseline;gap:10px;margin-inline-start:auto;}
.mw-last{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:24px;
  font-weight:600;color:var(--fg);direction:ltr;unicode-bidi:isolate;}
.mw-chg{font-family:var(--f-mono);font-variant-numeric:tabular-nums;font-size:13.5px;
  font-weight:600;direction:ltr;unicode-bidi:isolate;color:var(--fg-3);}
.mw-chg.up{color:var(--up);} .mw-chg.down{color:var(--down);}
.mw-asset-end{display:flex;align-items:center;gap:9px;flex-wrap:wrap;}
.mw-at{font-size:11px;color:var(--fg-3);}

/* ── Timeframes ──
   A rail rather than a `.seg`: nine of them do not fit a segmented control on a
   phone, and horizontal scroll is the honest answer to nine of anything. */
.mw-tfs{display:flex;gap:4px;overflow-x:auto;max-width:100%;scrollbar-width:none;}
.mw-tfs::-webkit-scrollbar{display:none;}
.mw-tf{flex:none;min-width:38px;padding:6px 9px;border-radius:var(--r1);
  border:1px solid transparent;background:transparent;color:var(--fg-3);
  font-family:var(--f-mono);font-size:11.5px;font-weight:600;cursor:pointer;
  transition:background .15s var(--ease),color .15s var(--ease);}
.mw-tf:hover{background:var(--bg-2);color:var(--fg-2);}
.mw-tf.active{background:var(--gold-pale);border-color:var(--gold-line);color:var(--gold-lt);}

/* ── Indicator toggles ── */
.mw-inds{display:flex;gap:6px;flex-wrap:wrap;margin:12px 0 10px;}
.mw-ind{display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border-radius:99px;
  border:1px solid var(--line);background:var(--bg-2);color:var(--fg-3);
  font-size:11.5px;cursor:pointer;transition:all .15s var(--ease);}
.mw-ind i{width:8px;height:8px;border-radius:2px;flex:none;opacity:.35;}
.mw-ind:hover{border-color:var(--line);color:var(--fg-2);}
.mw-ind.on{background:var(--bg-3);border-color:var(--gold-line);color:var(--fg);}
.mw-ind.on i{opacity:1;}

/* ── The chart ──
   The library owns everything inside `.mw-chart`; nothing re-renders it while
   it lives, because a re-render drops the canvas and the reader's zoom with it. */
.mw-chart{width:100%;height:440px;}
.mw-chart-none{padding:8px 0;}
.mw-busy{opacity:.55;transition:opacity .2s var(--ease);pointer-events:none;}
.mw-legend{display:flex;gap:14px;flex-wrap:wrap;min-height:18px;margin-top:8px;
  font-family:var(--f-mono);font-size:11px;color:var(--fg-2);
  direction:ltr;unicode-bidi:isolate;}
.mw-legend span{display:inline-flex;gap:5px;}
.mw-legend i{font-style:normal;color:var(--fg-3);}

/* ── The watchlist ── */
.mw-search{width:100%;margin:10px 0 4px;padding:9px 11px;border-radius:var(--r2);
  background:var(--bg-0);border:1px solid var(--line-2);color:var(--fg);font-size:13px;}
.mw-search:focus{outline:none;border-color:var(--gold-line);}
.mw-count{font-family:var(--f-mono);font-size:11.5px;color:var(--fg-3);}
/* The list scrolls inside its card so the chart beside it stays put. */
.mw-list{max-height:min(46vh,420px);overflow-y:auto;}
.mw-r-sym{font-family:var(--f-mono);font-size:12.5px;color:var(--fg);}
.mw-r-name{font-size:10.5px;color:var(--fg-3);margin-top:2px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:150px;}
.mw-r-await{font-size:9.5px;color:var(--fg-3);margin-top:2px;}
.dt tr.mw-on > td{background:var(--gold-pale);}
.dt tr.mw-on > td:first-child{box-shadow:inset 3px 0 0 var(--gold);}

/* ── Market details ── */

/* ── The phone's panes ──
   One control over the two side panels. Hidden from 1024px up, where both are
   on screen at once and a switch would be a control that hides information for
   no reason. */

@media(max-width:1023px){
  /* One column, in DOM order: chart, the panel switch, the four side cards,
     then the two wide ones. `display:block` rather than a one-column grid so
     the stacks below flow at their own height with no row alignment at all. */
  .mw-grid{display:block;}
  .mw-side,.mw-ctx{margin-top:12px;}
  .mw-main{margin-top:0;}
  .mw-chart{height:300px;}
  .mw-asset{gap:10px;padding:11px 13px;}
  .mw-last{font-size:20px;}
  .mw-asset-px{margin-inline-start:auto;}
  /* Comfortable targets. §10. */
  .mw-tf{min-height:36px;min-width:44px;}
  .mw-ind{min-height:34px;}
  .mw-classes .filter-chip{min-height:36px;}
  .mw-list{max-height:none;}
  /* EIGHT INDICATOR CHIPS WRAP TO THREE ROWS ON A PHONE, and those three rows
     sit between the reader and the chart — which is the one thing the mobile
     order exists to put first. One scrolling rail instead, the same shape the
     timeframes already use, so the chart comes up by about a hundred pixels. */
  .mw-inds{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;
    margin:10px 0 8px;padding-bottom:2px;}
  .mw-inds::-webkit-scrollbar{display:none;}
  .mw-ind{flex:none;}
  /* The page's own heading is the largest block between a phone reader and the
     chart, and on a screen they return to daily it is the least useful. Scoped
     to this screen — every other one keeps the heading it has. */
  .mw-head{margin-bottom:10px;}
  .mw-head .screen-title{font-size:22px;}
  .mw-head .screen-sub{font-size:11.5px;line-height:1.55;margin-top:4px;}
}
@media(min-width:1024px){

  /* ── THE SIDE SPANS BOTH ROWS, AND THAT IS THE WHOLE FIX ──
     A grid row is as tall as its tallest cell, so a two-row layout with a short
     cell in each row leaves that difference as white space — here it was 376px
     under the chart and 305px under the scanner. Making the side column span
     rows 1 and 2 means the chart's row is the chart's height and the column
     beside it simply keeps going, which is what a reader expects to see and
     what no amount of tuning the individual modules could produce.

     Written as explicit lines rather than as `.sp-8`/`.sp-4` spans because the
     span classes place a cell in the NEXT free slot, and there is no free slot
     that is "column nine, both rows". */
  /* `start`, NOT `stretch`, AND THAT IS THE OTHER HALF OF THE FIX. Stretching
     made every cell as tall as its row, which is right when the two columns are
     about the same height and wrong the moment they are not: the side column
     carries three cards and the main column one, so the row was sized by the
     side and the chart card was inflated to match it — 1176px on a 900px
     screen, with the time axis below the fold.

     With `start` a column that runs out of content simply ends, and the taller
     one keeps going beside it. The leftover is at the BOTTOM of a column, next
     to a column still in use, which is what unequal columns look like
     everywhere. The void this file's earlier note fought was a different
     animal: it sat BETWEEN two cards, in the middle of the page. */
  /* THE FIRST ROW IS A DEFINITE LENGTH, AND THAT IS WHY THE VOID STAYS AWAY.
     Left as `auto` it was still a track a spanning item could grow: the side
     column is taller than both rows together, and the grid handed row one its
     share of the difference — 295px of nothing between the chart and the card
     under it, in the middle of the page. A track with a definite size takes no
     share. The leftover goes to row two, which is the bottom of the left
     column, beside a right column still in use.

     ── THE 1.6 IS A DECISION, NOT A DERIVATION ──
     The three numbers below are the fit-the-viewport ones multiplied by 1.6,
     asked for by name: 380→608, 100vh−380→160vh−608, 660→1056. Fitting the
     first screen exactly produced a 372px chart at 900px tall, which is a
     price ladder rather than a chart to read structure on.

     SO THE CARD NOW RUNS PAST THE FOLD ON A SHORT SCREEN — about 300px at
     900px tall, none at 1424px and above. That is the trade this multiplier
     buys, and it is written here so the next person to measure a card hanging
     off the bottom knows it was chosen. */
  .mw-grid{grid-template-rows:clamp(608px, calc(160vh - 608px), 1056px) auto;}
  /* `.dash` sets `align-items:start` for every grid on the product, and the
     chart column is the one place that has to opt out: a card told to start is
     a card sized by its contents, and `height:100%` inside it then resolves
     against nothing. The main column fills its row; the context column fills
     what is left under it; only the side keeps `start`. */
  .mw-grid .mw-main,
  .mw-grid .mw-ctx{align-self:stretch;}
  .mw-grid .mw-main{grid-column:1 / 9;  grid-row:1;}
  /* `start` ON THE SIDE ONLY. Stretch is what the other two want — the chart
     card fills its row, the context stack fills what is left — but a side
     column that stretches is a column asked to be as tall as two rows it is
     taller than already. It ends where its last card ends. */
  .mw-grid .mw-side{grid-column:9 / 13; grid-row:1 / 3; align-self:start;}
  .mw-grid .mw-ctx {grid-column:1 / 9;  grid-row:2;}

  /* ── THE CHART IS SIZED BY THE SCREEN, NOT BY THE COLUMN BESIDE IT ──
     It used to take the remainder of a row the side column defined, which is
     how a watchlist gaining rows made a chart taller. Two unrelated things,
     one number.

     So the card is measured against the viewport instead — see the row track
     above for the arithmetic. `160vh - 608px` is the space under the header
     stack (nav, page heading, class tabs and the asset strip come to about
     368px) taken 1.6 times, and clamped at both ends: never so short that
     candles become a smear, never so tall that a big monitor gets a chart
     nobody asked for.

     `chart.resize()` still reads the height off this container rather than
     being told one, exactly as before — what changed is only what decides it. */
  .mw-grid .mw-main > .mod{display:flex;flex-direction:column;height:100%;}
  /* `flex-basis:0` AND `overflow:hidden` ARE BOTH LOAD-BEARING, and leaving
     either out produces a loop rather than an error. The chart reads its height
     off this box; if this box is also sized by what the chart drew, each one is
     waiting on the other and the card settles a few hundred pixels too tall —
     which is exactly what the first attempt did, turning a 173px void under the
     chart into a 229px void beside it.

     A basis of zero means the box contributes nothing to the card's height and
     simply takes what is left, so the measurement runs one way only. The clip
     covers the frame between the grid resizing this box and `resize()` telling
     the library about it. */
  .mw-grid .mw-main .mw-chart{flex:1 1 0;height:0;min-height:280px;overflow:hidden;}

  /* ── ROOM FOR THE DRAWER ──
     The row above is a FIXED height and the chart card fills it, which is what
     makes the chart size itself to the screen rather than to the column beside
     it. It also means a drawer opening inside that card has nowhere to go: the
     row cannot get taller, so the chart is squeezed to its 280px floor and the
     reading spills out of the card.

     So while the drawer is open the row is released to `auto` and the chart is
     pinned to a real height instead of a flexible one. The card grows
     downward, the page scrolls, and the chart stays exactly the size it was —
     which is the whole point of reading an analysis beside it. `mwaGrow` sets
     the class and tells the charting library its box moved. */
  .mw-grid.mwa-grown{grid-template-rows:auto auto;}
  .mw-grid.mwa-grown .mw-main > .mod{height:auto;}
  /* `flex:none` only — the height is written inline by `mwaGrow`, which
     measures what the chart already is. A number here would be a guess, and
     the first version of this rule guessed 440 against a real 791. */
  .mw-grid.mwa-grown .mw-main .mw-chart{flex:none;}

  /* The side used to stick. With four cards in it the column is about twice a
     viewport tall, so there is nothing to stick — a sticky element taller than
     the screen just scrolls, minus the top it can never show. The asset header
     above still sticks, which is the one that was doing the work. */
}

/* ══════════════════════════════════════════════════════
   MARKET WATCH — the context row
   ══════════════════════════════════════════════════════
   Scanner, venue status and the correlation matrix. They sit BELOW the chart on
   every breakpoint and none of them is behind the phone's pane switch: the
   watchlist and the details panel are two views of one instrument, so a control
   that swaps them is right, but these are separate questions and a reader
   should not have to know they exist to find them.
   ══════════════════════════════════════════════════════ */
.mwx-note{display:flex;align-items:flex-start;gap:8px;margin-top:11px;line-height:1.6;}
.mwx-note svg{flex:none;margin-top:2px;}
.mwx-sub{margin:9px 0 2px;font-size:11px;color:var(--fg-3);line-height:1.6;}
.mwx-seg{margin-top:10px;}
.mod-end .mwx-seg{margin-top:0;}

/* A card that has not answered yet. Three bars rather than a spinner, because
   the shape it is about to become is a list. */
.mwx-skel{display:flex;flex-direction:column;gap:8px;margin-top:14px;}
.mwx-skel i{height:13px;border-radius:var(--r1);background:var(--bg-2);
  animation:mwxPulse 1.4s var(--ease) infinite;}
.mwx-skel i:nth-child(2){width:78%;animation-delay:.12s;}
.mwx-skel i:nth-child(3){width:54%;animation-delay:.24s;}
@keyframes mwxPulse{0%,100%{opacity:.45}50%{opacity:.9}}
@media(prefers-reduced-motion:reduce){.mwx-skel i{animation:none;}}

/* ── The scanner ── */
.mwx-scan{margin-top:10px;}
/* THE RANK LIVES INSIDE THE IDENTITY BLOCK, NOT IN A COLUMN OF ITS OWN. As a
   cell it carried its own borders and its own padding, which drew a seam down
   the left of the table and left the digit reading as a number standing beside
   the row rather than one belonging to it. Here it is the first item in the
   same flex row as the coin mark and the ticker: one block, one highlight, and
   a click anywhere on it is a click on the row. */
.mwx-rank{flex:none;width:16px;text-align:end;color:var(--fg-4,var(--fg-3));
  font-family:var(--f-mono);font-size:10.5px;opacity:.75;}
.mwx-scan td{vertical-align:middle;}

/* A five- or six-letter ticker in a 22px disc. `MORPHO` and `RENDER` are real
   tickers and cutting them to five reads as a rendering bug, so the type drops
   instead of the text. */
/* ── A CRYPTO STAND-IN IS A DISC, NOT A TILE ──
   The widening tile is right where every mark is a tile: a forex list is
   `EUR GBP JPY` in a column and `US100` widening rather than being cut to
   `US10` is the whole point. It is wrong in a crypto list, where it sits beside
   round brand marks — a 31px rounded rectangle next to a 22px circle reads as
   a broken image rather than as a stand-in.

   So in this class it takes the disc's shape and size exactly, and the TYPE
   gives way instead of the text. Nothing is truncated: `MORPHO` and `RENDER`
   are real tickers, and `MORPH` reads as a rendering fault. */
.cix-txt.cix-crypto{border-radius:50%;width:22px;min-width:22px;padding:0;
  font-size:6.5px;letter-spacing:-0.01em;}
.cix-txt.cix-crypto.cix-txt-sm{font-size:5.5px;letter-spacing:-0.04em;}

/* ── A RASTER MARK ──
   Eleven coins have no free vector that was found, so they are 128px PNGs on
   disc. `cover` on a round 22px box because the sources are not consistently
   square — Jupiter's is a wide banner and Pepe's is a picture with a caption —
   and a circle crop is what makes a row of them read as a row of coins rather
   than as a strip of thumbnails. The ring `.cix` already draws does the rest.

   The plate underneath matters: several are transparent PNGs whose artwork is
   dark, and on this background they would otherwise be a shape cut out of
   nothing. */
.cix-img{object-fit:cover;background:var(--bg-3);}
/* Everywhere else the tile still widens rather than clipping. */
.cix-txt-sm{font-size:6.5px;letter-spacing:-0.02em;}


/* ── The span picker in the change column's heading ──
   A `.dt` header is sticky and the popover has to escape it, so the wrapper is
   the positioning context and the panel is absolutely placed against it. The
   same shape as the account menu: hidden by `display`, shown on `.open`, and
   dismissed by an outside click or Escape.

   `text-transform` is reset because `.dt th` uppercases, and "24H CHANGE" is a
   heading while "24h" is a value the reader chose. */
.mw-span{position:relative;display:inline-block;text-transform:none;
  letter-spacing:normal;}
.mw-span-btn{display:inline-flex;align-items:center;gap:5px;appearance:none;
  border:0;background:transparent;padding:0;cursor:pointer;color:inherit;
  font:inherit;letter-spacing:0.1em;text-transform:uppercase;}
.mw-span-btn:hover{color:var(--fg-2);}
.mw-span-caret{width:11px;height:11px;flex:none;opacity:.7;
  transition:transform .16s var(--ease);}
.mw-span.open .mw-span-caret{transform:rotate(180deg);}
.mw-span-pop{display:none;position:absolute;top:calc(100% + 6px);inset-inline-end:0;
  z-index:60;min-width:96px;padding:5px;border-radius:var(--r2);
  background:var(--bg-1);border:1px solid var(--line);
  box-shadow:0 14px 34px rgba(0,0,0,.5);}
.mw-span.open .mw-span-pop{display:flex;flex-direction:column;gap:2px;}
.mw-span-opt{appearance:none;border:0;background:transparent;cursor:pointer;
  text-align:start;padding:9px 11px;border-radius:var(--r1);color:var(--fg-3);
  font-family:var(--f-mono);font-size:12px;letter-spacing:normal;
  text-transform:none;}
.mw-span-opt:hover{background:var(--bg-2);color:var(--fg-2);}
.mw-span-opt.active{background:var(--gold-pale);color:var(--gold-lt);font-weight:600;}
/* The second between choosing a span and its figures arriving. Dimmed rather
   than blanked: a dash at full strength says "there is no such number", and
   the true statement for that second is "it is coming". */
.mw-chg-wait{opacity:.42;transition:opacity .18s var(--ease);}

/* ── The watchlist's columns ──
   A TABLE'S SLACK HAS TO GO SOMEWHERE, AND THE ONLY CHOICE IS WHERE. The
   symbol is start-aligned and both figures are end-aligned, so the space left
   over inside the first two columns lands between the ticker and its price —
   144px of it, most of a card, with a reader travelling to pair a symbol with
   a number. Widening the LAST column is the only thing that moves the price
   left; nothing done to the first two changes the distance, because it is
   their sum that sets it.

   So the slack is moved rather than removed: about fifty pixels out of the
   symbol and price columns and into the change column, which can carry it —
   its heading is a control with a caret, and it is the last thing on the row
   rather than a pair a reader reads together. */
.mw-list th:first-child,.mw-list td:first-child{width:32%;}
.mw-list th:nth-child(2),.mw-list td:nth-child(2){width:26%;}
.mw-list th:nth-child(3),.mw-list td:nth-child(3){width:42%;}

/* ── Market Session ──
   THE FIVE FX CENTRES AS A TABLE, WHICH IS WHAT REPLACED THE VENUE LIST. Nine
   venues at a dot and two lines each was 530px of card for eighteen lines of
   text, and it answered a per-instrument question. Five rows of five columns
   answer the one a currency reader has, in half the height.

   The table is `.dt` like the scanner above it, so the two narrow cards in this
   column are one vocabulary rather than a list and a grid. */
/* FIXED COLUMNS, BECAUSE THE STATUS IS THE COLUMN A READER CAME FOR. Left to
   size themselves, `America/New_York` and two dates pushed the table past the
   card and `.dt-wrap` did what it is there for — it scrolled, and the answer
   scrolled out of sight. Five stated widths make the whole row fit the column
   this card lives in. */
.mwx-sess{table-layout:fixed;}
.mwx-sess th,.mwx-sess td{padding-inline:6px;}
/* These headings wrap where the rest of the product's do not: five of them in
   this width cannot each hold one line, and the tracking comes down so they
   take two rather than three. */
.mwx-sess th{white-space:normal;line-height:1.3;letter-spacing:0.04em;}
.mwx-sess th:nth-child(1),.mwx-sess td:nth-child(1){width:22%;}
.mwx-sess th:nth-child(2),.mwx-sess td:nth-child(2){width:27%;}
.mwx-sess th:nth-child(3),.mwx-sess td:nth-child(3){width:18.5%;}
.mwx-sess th:nth-child(4),.mwx-sess td:nth-child(4){width:18.5%;}
.mwx-sess th:nth-child(5),.mwx-sess td:nth-child(5){width:14%;}
.mwx-sess td{vertical-align:top;padding-top:7px;padding-bottom:7px;}
.mwx-sess .chip{padding:2px 6px;font-size:10px;}
.mwx-sess th .mwx-c-gmt{display:block;font-size:8.5px;font-weight:400;
  letter-spacing:0.06em;color:var(--fg-4,var(--fg-3));text-transform:uppercase;}
.mwx-c-city{font-size:12px;line-height:1.35;color:var(--fg);}
/* The country under the city, and the centre's own clock under its zone: the
   second line of each identity column, at the same weight in both. */
/* `display:block` beats `.num`, which these carry for their digits and which is
   inline-block — without it the clock sat beside the zone instead of under it,
   on exactly the rows whose zone name was short enough to leave room. */
.mwx-c-sub{display:block;font-size:10px;line-height:1.35;color:var(--fg-3);margin-top:1px;}
/* A ZONE NAME BREAKS AT ITS SLASH OR NOT AT ALL. `overflow-wrap:anywhere` split
   it wherever it ran out of room — `Australia/Sydn` above `ey` — so the wrap
   opportunity is placed by the renderer instead, with a `<wbr>` after the
   separator, and the word itself is left unbreakable. */
.mwx-c-tz{display:block;font-size:10px;line-height:1.35;color:var(--fg-2);
  overflow-wrap:normal;word-break:normal;}
.mwx-c-when b{font-size:12.5px;line-height:1.35;color:var(--fg);}
/* The date never wraps. Split across two lines it doubled every row's height
   for a figure that reads as one thing. */
.mwx-c-day{display:block;font-size:10px;line-height:1.35;color:var(--fg-3);
  margin-top:1px;white-space:nowrap;}
/* An open centre tints its whole row rather than one cell. The row IS the
   statement — city, zone, hours and status are one fact — and colouring the
   status cell alone made the other four look like they belonged to a different
   answer. */
.mwx-sess tr.on td{background:color-mix(in srgb,var(--up) 7%,transparent);}
.mwx-sess tr.on .mwx-c-city{color:var(--up);}
/* Not a footnote. It is the sentence that stops "Closed" being read as "the
   currency market is shut", which is the one misreading this table invites. */
.mwx-sess-note{line-height:1.5;}

/* ── The window picker ──
   THE SAME CONTROL AS THE TIMEFRAME STRIP, BECAUSE IT IS THE SAME KIND OF
   CHOICE. `.mw-tf` above already styles "one of several spans of time" — a
   second look for the same idea would be two vocabularies on one screen. All
   that is added here is the layout: these WRAP rather than scroll, since six
   short labels fit a phone in one row and a picker that scrolls hides the
   options at its end.

   Not a `.seg` either: that control is for two or three mutually exclusive
   halves, and six of them at 390px hands each button 55px with its label
   sitting on the border. */
.mwx-ranges{display:flex;flex-wrap:wrap;gap:4px;margin:11px 0 2px;}
/* The class this card is measuring, stated in the head rather than chosen
   there. A label, not a control — the tab strip at the top of the screen is
   where that choice is made, and two places to change one thing is one too
   many. */
.mwx-scope{font-family:var(--f-mono);font-size:10.5px;letter-spacing:0.06em;
  text-transform:uppercase;color:var(--fg-3);}
/* A 44px touch target without a 44px-tall row: grown with padding the eye does
   not read as size. */
@media(max-width:767px){
  .mwx-ranges .mw-tf{min-height:36px;min-width:44px;}
}

.mwx-perf{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px;}
.mwx-perf li{display:grid;grid-template-columns:56px 1fr 64px;align-items:center;gap:9px;}

/* ── The expander ──
   Full width, because it acts on the whole list above it rather than on any
   one row, and at the bottom because that is where a reader arrives wanting
   more. It says what it will do and how many — "Show all" over a list that is
   already all of them is a button that lies about its set, so it is not
   rendered at all when there is nothing to expand. */
.mwx-more{display:flex;align-items:center;justify-content:center;gap:6px;
  width:100%;margin-top:11px;padding:9px 12px;appearance:none;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--r2);background:transparent;
  color:var(--fg-3);font-size:11.5px;font-weight:600;letter-spacing:0.02em;
  transition:background .14s var(--ease),color .14s var(--ease),border-color .14s var(--ease);}
.mwx-more:hover{background:var(--bg-2);color:var(--fg-2);border-color:var(--line-2);}
.mwx-more-caret{width:12px;height:12px;flex:none;opacity:.75;
  transition:transform .18s var(--ease);}
.mwx-more-caret.up{transform:rotate(180deg);}
.mwx-p-sym{font-family:var(--f-mono);font-size:11px;color:var(--fg-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.mwx-p-bar{height:6px;border-radius:99px;background:var(--bg-2);overflow:hidden;}
.mwx-p-bar i{display:block;height:100%;border-radius:99px;}
.mwx-p-bar i.up{background:var(--up);} .mwx-p-bar i.down{background:var(--down);}
.mwx-p-val{font-family:var(--f-mono);font-size:11px;text-align:end;
  font-variant-numeric:tabular-nums;}


/* ── Headlines ──
   TWO COLUMNS WITHOUT A BREAKPOINT. This card sits in the wide column under the
   chart, where a single-file list of twelve headlines would be a very long
   ribbon of mostly white space. `auto-fill` with a floor does the whole job:
   two columns where there is room for two, one where there is not, and nothing
   to keep in sync with a media query when the grid around it changes.

   The floor is 320px and not less. At 248 this column fitted THREE, and a
   headline is a sentence: three-up clipped most of them mid-clause, which turns
   a list you can scan into a list you have to open. 320 gives two here, one on
   a phone, and a line long enough to end. */
.mwx-nw-grid{display:grid;gap:2px;margin-top:8px;
  grid-template-columns:repeat(auto-fill,minmax(min(320px,100%),1fr));}

/* The whole row is the link, not the headline inside it — a 12px target in a
   dense list is a target that gets missed. */
.mwx-nw{display:flex;flex-direction:column;gap:3px;padding:9px 10px;
  border-radius:var(--r2);text-decoration:none;color:inherit;
  border:1px solid transparent;transition:background .12s,border-color .12s;}
.mwx-nw:hover,.mwx-nw:focus-visible{background:var(--bg-2);border-color:var(--hair);}
.mwx-nw:focus-visible{outline:2px solid var(--gold);outline-offset:1px;}

.mwx-nw-top{display:flex;align-items:baseline;gap:8px;font-size:10px;
  color:var(--fg-3);}
/* The publisher gets the emphasis and the clock does not: who said it is the
   part a reader weighs, and the time is only ever a tiebreak. */
.mwx-nw-src{font-weight:600;letter-spacing:.04em;color:var(--fg-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.mwx-nw-at{margin-inline-start:auto;white-space:nowrap;font-family:var(--f-mono);}

/* Three lines, then an ellipsis. A headline is one sentence and a card of them
   should scan as a column of equal weights; one four-line outlier pushes every
   card beside it out of alignment for no gain in meaning. */
.mwx-nw-h{font-size:12px;line-height:1.45;color:var(--fg);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden;}
.mwx-nw:hover .mwx-nw-h{color:var(--gold);}

.mwx-nw-note{margin-top:10px;}

@media(max-width:767px){
  /* FIVE COLUMNS ON A PHONE, ALL FIVE OF THEM ON SCREEN. `.dt-sm` carries a
     360px floor that a 358px card cannot meet, so the table scrolled and took
     Status with it. The floor is lifted here and the width goes to the two
     columns that cannot give any up — the city and the status — while the zone
     wraps at its slash and the hours are four characters wide. */
  .mwx-sess{min-width:0;}
  .mwx-sess td,.mwx-sess th{padding-inline:4px;}
  .mwx-sess th:nth-child(1),.mwx-sess td:nth-child(1){width:21%;}
  .mwx-sess th:nth-child(2),.mwx-sess td:nth-child(2){width:22%;}
  .mwx-sess th:nth-child(3),.mwx-sess td:nth-child(3){width:17%;}
  .mwx-sess th:nth-child(4),.mwx-sess td:nth-child(4){width:17%;}
  .mwx-sess th:nth-child(5),.mwx-sess td:nth-child(5){width:23%;}
  .mwx-c-tz{font-size:9.5px;}
  .mwx-c-day{font-size:9.5px;}
  .mwx-perf li{grid-template-columns:48px 1fr 58px;}
}

/* ── The tick ──
   A price that moved, flashed for as long as it takes to notice. Bitcoin moves
   about 0.01% in three seconds: the digits that change are the last two of
   seven, and without this the page looks frozen while it is working perfectly.
   The oldest convention on a trading screen, and the cheapest.

   Applied as an animation rather than a class that has to be taken off again —
   the row is re-rendered on the next tick anyway, so nothing has to clean up,
   and a cell that ticks twice in a row restarts rather than sticking. */
@keyframes mwTickUp{
  0%{background:color-mix(in srgb,var(--up) 26%,transparent);color:var(--up);}
  100%{background:transparent;}
}
@keyframes mwTickDown{
  0%{background:color-mix(in srgb,var(--down) 26%,transparent);color:var(--down);}
  100%{background:transparent;}
}
.tick-up{animation:mwTickUp .9s var(--ease);border-radius:var(--r1);}
.tick-down{animation:mwTickDown .9s var(--ease);border-radius:var(--r1);}
.mw-last.tick-up,.mw-last.tick-down{padding-inline:6px;margin-inline:-6px;}
/* A reader who has asked for less motion gets the colour without the flash. */
@media(prefers-reduced-motion:reduce){
  .tick-up,.tick-down{animation:none;}
  .tick-up{color:var(--up);} .tick-down{color:var(--down);}
}
/* The bar's own date, first in the legend and set apart from the four prices
   after it. Forced LTR: a date with a 24-hour time in it reads left to right in
   every language this product speaks. */
.mw-lg-t{color:var(--fg-2);font-weight:600;padding-inline-end:4px;
  border-inline-end:1px solid var(--hair);margin-inline-end:4px;}

/* ══════════════════════════════════════════════════════
   MARKET WATCH — typography and the direction of a figure
   ══════════════════════════════════════════════════════
   Scoped to `.mw` throughout. This screen is read differently from the rest of
   the product: it is scanned rather than filled in, and the two things a reader
   looks for on it are WHICH INSTRUMENT and WHICH WAY. Everything below serves
   one of those two.
   ══════════════════════════════════════════════════════ */

/* A module heading here names a workspace, not a form section, so it carries
   more weight than the product's default label. */
.mw .mod-title{font-size:12px;letter-spacing:0.1em;font-weight:800;color:var(--fg-2);}
html[lang="fa"] .mw .mod-title,html[lang="ar"] .mw .mod-title{font-size:14px;font-weight:800;}

/* The symbol is the thing the eye lands on in a list of twelve. */
.mw-r-sym{font-family:var(--f-mono);font-size:14.5px;font-weight:700;
  letter-spacing:0.01em;color:var(--fg);}
.mw-list tbody tr td:first-child{padding-top:9px;padding-bottom:9px;}
.mw-r-name{font-size:10.5px;}

/* ── A SIGNED FIGURE CARRIES ITS DIRECTION, EVERYWHERE ON THIS SCREEN ──
   The colour is the reading. `up` and `down` were already on the watchlist and
   the asset header; this makes it true of the scanner and the performance list
   as well, so a reader never has to work out from a minus sign what a colour
   would have told them.

   NOT the widest-range column, and that is the one deliberate exception: its
   figure is a distance between a high and a low, it has no sign, and painting a
   magnitude green would say "rose" about a number that says no such thing. */
.mw .up,.mw .mwx-p-val.up,.mw .mwx-scan .up{color:var(--up);font-weight:600;}
.mw .down,.mw .mwx-p-val.down,.mw .mwx-scan .down{color:var(--down);font-weight:600;}

/* ── The watchlist took the details panel's column, and then the class grew ──
   The cap came off when nothing sat beneath it any more: twelve rows were
   twelve rows and the column was as tall as its content. Forty-two rows are a
   different object — about 2,650px of side column with the rest of the page
   beside it as whitespace — so on a desktop it scrolls INSIDE ITS OWN BOX.
   `.dt th` is already `position:sticky`, so the column headings, and the span
   picker living in one of them, stay put while the rows move under them.

   PHONES KEEP THE WHOLE LIST. There the card is one thing in a vertical stack
   rather than a column next to a chart, and a nested scroll inside a page
   scroll is the worse of the two problems — a thumb ends up moving whichever
   one it happens to land on.

   This rule sits at the end of the file on purpose: it is the last word on a
   property three earlier blocks also set, and it was the block above at
   `max-height:none` that quietly beat the media query when it was written
   further up. */
.mw-list{max-height:none;overflow-y:visible;}
@media(min-width:1024px){
  .mw-list{max-height:clamp(320px, calc(100vh - 430px), 640px);
    max-height:clamp(320px, calc(100dvh - 430px), 640px);overflow-y:auto;}
}

/* ══════════════════════════════════════════════════════
   INSTRUMENT MARKS
   ══════════════════════════════════════════════════════
   Two shapes behind one class. `.cix` on an `<svg>` is a brand mark from the
   CC0 set in `coins.js`; `.cix.cix-txt` on a `<span>` is the ticker in a tinted
   square, for the thirty-three instruments that have no logo because they are
   not companies — gold, the euro, the Nasdaq, crude.

   `.ic` MUST NOT APPLY HERE. The product's own icons are strokes on
   `currentColor` with `fill:none`; these carry their own fills, and inheriting
   that rule would erase them. That is why they have a class of their own rather
   than a modifier on the existing one.
   ══════════════════════════════════════════════════════ */
.cix{width:22px;height:22px;flex:none;border-radius:50%;
  /* Explicitly cleared: a stray `fill:none` from anywhere would blank the art. */
  fill:initial;stroke:none;
  /* ── A HAIRLINE RING, ON EVERY MARK ──
     Two of the twelve ship a near-black brand disc — XRP at luminance 40 and
     Cardano at 28, measured — and on a page this dark the disc simply is not
     there: XRP read as a white X floating in the row. The fix is NOT to
     lighten somebody's brand colour, which would be altering the artwork. It
     is to give every mark an edge, so a dark coin reads as a dark coin.
     Uniform on purpose: invisible on the bright ones, and nothing is singled
     out. */
  box-shadow:0 0 0 1px rgba(255,255,255,0.16);}
.cix-txt{display:inline-flex;align-items:center;justify-content:center;
  border-radius:6px;box-shadow:none;font-family:var(--f-mono);font-size:8.5px;font-weight:700;
  letter-spacing:0.02em;line-height:1;
  background:var(--bg-3);color:var(--fg-2);border:1px solid var(--hair);
  /* Square for a three-letter ticker, and widening rather than clipping for the
     handful that are longer — `US100` is a name, `US10` is not. */
  min-width:22px;width:auto;padding:0 4px;}

/* Tinted per asset class, so a page of forex rows is not a wall of identical
   grey squares. Muted on purpose — these sit beside a brand mark and must not
   outshout it. */
.cix-forex{background:color-mix(in srgb,var(--info,#7FB4D4) 16%,var(--bg-3));color:var(--info,#7FB4D4);}
.cix-metal{background:color-mix(in srgb,var(--gold) 16%,var(--bg-3));color:var(--gold-lt,var(--gold));}
.cix-metals{background:color-mix(in srgb,var(--gold) 16%,var(--bg-3));color:var(--gold-lt,var(--gold));}
.cix-index{background:color-mix(in srgb,var(--up) 13%,var(--bg-3));color:var(--up);}
.cix-indices{background:color-mix(in srgb,var(--up) 13%,var(--bg-3));color:var(--up);}
.cix-stock{background:color-mix(in srgb,var(--fg-2) 12%,var(--bg-3));color:var(--fg);}
.cix-commodity,.cix-commodities,.cix-energy{
  background:color-mix(in srgb,var(--warn) 14%,var(--bg-3));color:var(--warn);}

/* The mark and the two lines of text beside it. */
.mw-r-id{display:flex;align-items:center;gap:10px;min-width:0;}
.mw-r-id > span{min-width:0;}

/* The asset header's mark is the largest one on the screen. */
.mw-asset .cix{width:30px;height:30px;}
.mw-asset .cix-txt{font-size:10px;border-radius:8px;}
.mw-asset-id{display:flex;align-items:center;gap:11px;}
.mw-asset-txt{display:flex;flex-direction:column;gap:2px;min-width:0;}

/* Home's cards put it inline with the ticker. */
.mkt-sym .cix{width:18px;height:18px;margin-inline-end:7px;vertical-align:-4px;}
.mkt-sym .cix-txt{font-size:7.5px;border-radius:5px;}

@media(max-width:767px){
  .cix{width:20px;height:20px;}
  .mw-r-id{gap:8px;}
  .mw-asset .cix{width:26px;height:26px;}
}

/* ══════════════════════════════════════════════════════
   THE PROSPECT DESK
   ══════════════════════════════════════════════════════
   A working list, not a dashboard. Rows are dense and tappable, the funnel is
   a strip rather than a chart, and the one thing that must be visible without
   reading anything is which cards are overdue.
   ══════════════════════════════════════════════════════ */
.pd-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px;}
.pd-quota{font-size:11.5px;color:var(--fg-3);margin-inline-start:auto;}
.pd-quota.out{color:var(--warn);}

/* ── The temperature mark ──
   A dot the reader set, never a word: the stage chip beside it is the system's
   claim and these two must not read as the same kind of statement. */
.pd-temp{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block;}
.pd-temp-cold{background:var(--mlc);box-shadow:0 0 0 3px var(--mlc-pale);}
.pd-temp-warm{background:var(--warn);box-shadow:0 0 0 3px var(--warn-pale);}
.pd-temp-hot{background:var(--down);box-shadow:0 0 0 3px var(--down-pale);}
/* A filter chip on this bar may carry an icon, and the shared class does not
   lay one out — without this the clock sits hard against "Due". */
.pd-filters .filter-chip,.pd-tchip{display:inline-flex;align-items:center;gap:6px;}
.pd-filters .filter-chip .ic{width:13px;height:13px;}

/* ── The funnel ── */
.pd-fun{display:flex;flex-direction:column;gap:7px;}
.pd-fun-row{display:grid;grid-template-columns:96px minmax(0,1fr) 38px;align-items:center;gap:10px;}
.pd-fun-lbl{font-size:11.5px;color:var(--fg-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pd-fun-track{height:18px;background:var(--bg-3);border-radius:var(--r1);overflow:hidden;}
.pd-fun-bar{display:block;height:100%;border-radius:var(--r1);
  background:linear-gradient(90deg,var(--gold-dk),var(--gold-dp));transition:width .5s var(--ease);}
.pd-fun-bar.won{background:linear-gradient(90deg,var(--gold-dp),var(--gold-lt));}
.pd-fun-val{font-size:12.5px;color:var(--fg);text-align:end;}
.pd-fun-lost{font-size:11px;color:var(--fg-3);padding-top:4px;}

/* ── The filter bar ── */
.pd-bar{display:flex;flex-wrap:wrap;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line-2);
  align-items:center;}
.pd-filters{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
.pd-bar-gap{width:1px;height:18px;background:var(--line);margin:0 3px;}
.pd-search{position:relative;flex:1 1 180px;min-width:150px;}
.pd-search-ic{position:absolute;inset-inline-start:11px;top:50%;transform:translateY(-50%);
  color:var(--fg-3);pointer-events:none;display:flex;}
.pd-search .tin{padding-inline-start:34px;}

/* ══════════════════════════════════════════════════════
   THE FOLLOW-UP BOARD
   ══════════════════════════════════════════════════════
   The one thing on this screen with a deadline, drawn as the one thing on this
   screen with a deadline. Everything else here is a list; this is a clock.

   The colour is the band and nothing else — green while there is time, amber
   once a day of it is gone, red for the last hours, grey once the window has
   closed. It is spent on four cards at most, which is what lets it mean
   something: a screen where everything is coloured has no colours left. */
.pd-fu-grid{display:grid;gap:12px;
  grid-template-columns:repeat(auto-fill,minmax(272px,1fr));}

.pd-fu{display:flex;flex-direction:column;gap:11px;
  padding:14px;border-radius:var(--r2);
  border:1px solid var(--line);background:var(--bg-2);
  /* The band lives on one edge, not on the whole panel. A fully tinted card
     in --warn would out-shout `Send demo` two panels down, and the rule
     carries the same meaning at a fraction of the weight — the same argument
     `.pd-getmail` makes. */
  border-inline-start:3px solid var(--line);}

.pd-fu-top{display:flex;align-items:center;gap:8px;min-width:0;}
.pd-fu-name{flex:1 1 auto;min-width:0;background:none;border:none;padding:0;cursor:pointer;
  font-size:13.5px;font-weight:600;color:var(--fg);text-align:start;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pd-fu-name:hover{color:var(--gold);}
.pd-fu-name:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:var(--r1);}

/* ── The clock ──
   The arc answers "how much of it have I burned", which is read at a glance
   and cannot be read off digits; the digits answer "how long have I actually
   got", which cannot be read off an arc. They are two questions, so they are
   two marks. */
.pd-fu-clock{display:flex;align-items:center;gap:13px;}
.pd-fu-ring{width:56px;height:56px;flex-shrink:0;
  /* Draining from twelve o'clock. `stroke-dashoffset` is the only thing the
     tick writes here: one attribute, no layout, no reflow of the page. */
  transform:rotate(-90deg);}
.pd-fu-tr{fill:none;stroke:var(--bg-4);stroke-width:5;}
.pd-fu-arc{fill:none;stroke:var(--fg-3);stroke-width:5;stroke-linecap:round;
  transition:stroke-dashoffset .9s linear,stroke .3s;}

.pd-fu-fig{display:flex;flex-direction:column;gap:2px;min-width:0;}
.pd-fu-time{font-family:var(--f-mono);font-size:23px;font-weight:600;line-height:1.05;
  color:var(--fg);letter-spacing:-0.5px;
  /* A countdown reads left to right in every language — the hours are the
     hours. Isolated so an RTL paragraph cannot reorder the colons. */
  direction:ltr;unicode-bidi:isolate;}
.pd-fu-word{font-size:11px;color:var(--fg-3);}

.pd-fu-why{font-size:11px;color:var(--fg-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pd-fu-cap{margin:0;font-size:11px;line-height:1.5;color:var(--warn);}

.pd-fu-acts{display:flex;align-items:center;gap:6px;}
.pd-fu-gap{flex:1 1 auto;}
.pd-fu-acts .btn-ghost,.pd-fu-acts .btn-gold{white-space:nowrap;}

/* ── The four bands ── */
.pd-fu.ok{border-inline-start-color:var(--up);}
.pd-fu.ok .pd-fu-arc{stroke:var(--up);}
.pd-fu.warn{border-inline-start-color:var(--warn);}
.pd-fu.warn .pd-fu-arc{stroke:var(--warn);}
.pd-fu.warn .pd-fu-word{color:var(--warn);}
.pd-fu.late{border-inline-start-color:var(--down);background:var(--down-pale);}
.pd-fu.late .pd-fu-arc{stroke:var(--down);}
.pd-fu.late .pd-fu-time,.pd-fu.late .pd-fu-word{color:var(--down);}
/* THE ONLY THING ON THIS SCREEN THAT MOVES BY ITSELF, and it is spent on the
   last hours of a promise. Same pulse the Planner's overdue group uses. */
.pd-fu.late .pd-fu-time{animation:pdPulse 1.6s ease-in-out infinite;}
/* ── Past the window ──
   THIS USED TO FADE THE CARD OUT. A promise that has been broken is the one
   thing on this desk still getting worse every hour, and dimming it said the
   opposite: finished, nothing to do. So it is now the loudest card on the
   board and stays that way until somebody presses one of the verbs.
   The ring is empty because there is no window left to draw a proportion of;
   the digits carry the fact, counting the other way with a `+` in front. */
.pd-fu.over{border-inline-start-color:var(--down);background:var(--down-pale);}
.pd-fu.over .pd-fu-arc{stroke:var(--down);opacity:.45;}
.pd-fu.over .pd-fu-time,.pd-fu.over .pd-fu-word{color:var(--down);}
.pd-fu.over .pd-fu-word{font-weight:600;}
/* Two seconds, on the edge rather than the whole card. Twenty overdue cards
   strobing out of phase is a board nobody can read, and this has to survive
   sitting behind real work all afternoon. */
.pd-fu.over{animation:pdOverdue 2s ease-in-out infinite;}
@keyframes pdOverdue{
  0%,100%{box-shadow:0 0 0 0 rgba(0,0,0,0);}
  50%{box-shadow:inset 3px 0 0 0 var(--down);}
}
/* An overdue card never shows the held dot — see `pdClock`. Its digits do
   stand still overnight, and the red is what says why that is not the same as
   being switched off. */
.pd-fu.over .pd-fu-time{opacity:1;animation:none;}

/* ── Held ──
   Outside the calling hours the digits stand still, and a card that stands
   still without saying why reads as broken. The dot is the only difference:
   the band it is in has not changed, only whether it is being spent. */
.pd-fu.held .pd-fu-time{opacity:.72;}
.pd-fu.held .pd-fu-word::before{content:'';display:inline-block;
  width:5px;height:5px;border-radius:50%;background:currentColor;
  margin-inline-end:6px;vertical-align:middle;opacity:.7;}
.pd-fu.held .pd-fu-time{animation:none;}

.pd-fu-foot{margin:12px 0 0;font-size:11px;line-height:1.55;color:var(--fg-3);}

@keyframes pdPulse{0%,100%{opacity:1;}50%{opacity:.55;}}
@media(prefers-reduced-motion:reduce){
  .pd-fu.late .pd-fu-time{animation:none;}
  .pd-fu-arc{transition:none;}
  /* The alarm becomes a standing edge rather than a pulsing one. The card is
     still the loudest on the board; it simply stops moving. */
  .pd-fu.over{animation:none;box-shadow:inset 3px 0 0 0 var(--down);}
}

@media (max-width:480px){
  .pd-fu-grid{grid-template-columns:1fr;}
  .pd-fu-ring{width:48px;height:48px;}
  .pd-fu-time{font-size:20px;}
}

/* ── A row ──
   `due` is the only state that changes the row itself rather than adding a
   badge to it, because "what did I let slip" has to be answerable by looking
   rather than by reading. */
.pd-list{display:flex;flex-direction:column;}
.pd-row{display:flex;align-items:center;gap:11px;width:100%;text-align:start;
  padding:13px 14px;border-bottom:1px solid var(--line-2);transition:background .2s;}
.pd-row:last-child{border-bottom:none;}
.pd-row:hover{background:var(--bg-2);}
.pd-row.filed{opacity:.5;}
/* The row is a container of controls now, so its main area is the button and
   it has to carry the focus ring the whole row used to. */
.pd-row-main{background:none;border:none;padding:0;cursor:pointer;text-align:start;align-items:stretch;}
.pd-row-main:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:var(--r1);}
.pd-tbtn{flex-shrink:0;padding:4px;border-radius:50%;line-height:0;}
.pd-tbtn:hover{background:var(--bg-3);}
.pd-row-next{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--gold-dp);margin-top:2px;}
.pd-row-next .ic{width:11px;height:11px;}

/* ── The row's own verbs ──
   The whole point of the redesign: ringing somebody, writing down what was
   said and pushing a step to tomorrow are what this screen is FOR, and each
   used to cost opening the sheet. */
/* FOUR FIXED SLOTS, NOT A PACKED ROW. Ring, note, later, confirm — each one
   owns a column, and a card the verb does not apply to leaves the slot empty
   (`.pd-act-gap`). Packed, the row put the headset in the third column on one
   card and the fourth on the next, so a list of icons read as scattered and
   "the second one" named a different action on every line. Fixed width also
   means the chip column beside it starts at the same place on every row. */
.pd-acts-row{display:grid;grid-template-columns:repeat(4,30px);gap:2px;
  flex-shrink:0;opacity:0;transition:opacity .2s;}
.pd-act-gap{display:block;width:30px;height:30px;}
.pd-row:hover .pd-acts-row,.pd-row:focus-within .pd-acts-row{opacity:1;}
.pd-act{display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;border-radius:var(--r2);color:var(--fg-3);transition:all .15s;}
.pd-act:hover{color:var(--gold);background:var(--bg-3);}
.pd-act.ok:hover{color:var(--up);}
.pd-act .ic{width:15px;height:15px;}
/* Touch has no hover, so on a phone the verbs are simply there — and so is a
   narrow window on a laptop, where the row is tight enough that a hidden
   control is a control nobody finds. */
@media (hover:none),(max-width:720px){.pd-acts-row{opacity:1;}}
.pd-row.due{box-shadow:inset 3px 0 0 var(--warn);}
[dir="rtl"] .pd-row.due{box-shadow:inset -3px 0 0 var(--warn);}
.pd-row-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:3px;}
.pd-row-top{display:flex;align-items:center;gap:7px;flex-wrap:wrap;}
.pd-name{font-size:13.5px;font-weight:600;color:var(--fg);}
.pd-row-sub{font-size:11.5px;color:var(--fg-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pd-sep{padding:0 6px;color:var(--line);}
/* Aligned to the INLINE start of its own column, so the chips read as a
   column of words rather than as a ragged right edge. `start` is the logical
   keyword and needs no RTL twin — the pair of physical ones it replaced had
   the two directions disagreeing about which edge a due date hung from. */
.pd-row-end{display:flex;flex-direction:column;align-items:start;gap:4px;flex-shrink:0;}
.pd-due{font-size:10.5px;color:var(--fg-3);}
.pd-due.on{color:var(--warn);}
.pd-notes{display:inline-flex;align-items:center;gap:3px;font-size:10.5px;color:var(--fg-3);}
.pd-notes .ic{width:12px;height:12px;}

/* ══ ONE GRID FOR THE WHOLE LIST ══════════════════════
   Flex sizes every row on its own, so the chip column was as wide as whatever
   that row happened to hold — `Added` on one line, `Following up` on the next
   — and the two started at different places down the page. Widening it by hand
   is not a fix either: the Persian for `Called` runs half again as long, and a
   pixel width picked against English is a clipped word in another script.

   So the LIST owns the tracks and each row subgrids onto them. The chip column
   is sized once, to the widest chip actually in the list, in whatever language
   the reader is in — and every row lines up with it for free. Every row shares
   the same padding, so the tracks are offset identically and stay aligned.

   The flex rules above remain the fallback, unchanged, for an engine without
   subgrid: ragged, which is what it was, and never broken. */
@supports (grid-template-columns: subgrid) {
  .pd-list{display:grid;column-gap:11px;
    grid-template-columns:auto auto minmax(0,1fr) auto 126px;}
  /* A shared desk shows no action column — see `mnLeadRowHtml`, which draws
     four cells and not five. The track count has to match the markup or the
     chip lands under the name. */
  .pd-list.mn-rolist{grid-template-columns:auto auto minmax(0,1fr) auto;}
  .pd-row{display:grid;grid-column:1 / -1;grid-template-columns:subgrid;
    align-items:center;}
}

/* ══ THE SAME ROW, ON A PHONE ═════════════════════════
   Five columns do not fit in three hundred and ninety pixels, and the one that
   gives way first is the name — which is the only thing on the row somebody
   is actually looking for. So the row folds: the name takes the whole first
   line, and the stage, the date and the four verbs share the second.

   The columns still line up, because they are still columns — the fold moves
   them onto a line of their own rather than abandoning the grid for a flex
   scramble, which is what made the icons ragged in the first place. */
@media (max-width:560px){
  .pd-list,.pd-list.mn-rolist{display:flex;flex-direction:column;}
  .pd-row{display:grid;align-items:center;column-gap:9px;row-gap:9px;
    grid-template-columns:auto auto minmax(0,1fr) auto;}
  .pd-seq{grid-area:1 / 1;}
  .pd-tbtn{grid-area:1 / 2;}
  .pd-row-main{grid-area:1 / 3 / 2 / 5;}
  /* Side by side now rather than stacked: on one line of its own the stage and
     the date have the width to read as a sentence. */
  .pd-row-end{grid-area:2 / 3 / 3 / 4;flex-direction:row;align-items:center;gap:9px;}
  .pd-acts-row{grid-area:2 / 4 / 3 / 5;}
}

.pd-pager{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px;
  border-top:1px solid var(--line-2);}
.pd-pager-lbl{font-size:11.5px;color:var(--fg-3);}

/* ── One card, in the sheet ── */
.pd-card{display:flex;flex-direction:column;gap:16px;}
.pd-card-top{display:flex;align-items:center;gap:10px;}
.pd-card-id{flex:1 1 auto;min-width:0;}
.pd-card-name{font-size:17px;font-weight:700;color:var(--fg);}
.pd-card-meta{font-size:12px;color:var(--fg-3);display:flex;align-items:center;flex-wrap:wrap;}
.pd-alert{display:flex;align-items:flex-start;gap:9px;padding:11px 13px;border-radius:var(--r2);
  font-size:12.5px;line-height:1.6;background:var(--bg-2);border:1px solid var(--line-2);color:var(--fg-2);}
.pd-alert .ic{flex-shrink:0;margin-top:2px;}
.pd-alert.bad{background:var(--down-pale);border-color:var(--down-line);color:var(--down);}
.pd-alert.ok{background:var(--gold-pale);border-color:var(--gold-line);color:var(--gold-lt);}
.pd-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;}
.pd-fact{background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r2);padding:10px 12px;}
.pd-fact-k{display:block;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--fg-3);
  margin-bottom:5px;}
html[lang="fa"] .pd-fact-k,html[lang="ar"] .pd-fact-k{letter-spacing:0;text-transform:none;}
.pd-fact-v{display:block;font-size:13px;color:var(--fg);line-height:1.5;}
.pd-fact-s{display:block;font-size:11px;color:var(--fg-3);margin-top:3px;}
.pd-acts{flex-wrap:wrap;gap:8px;}

.pd-live{display:flex;align-items:center;gap:9px;padding:11px 13px;border-radius:var(--r2);
  background:var(--info-pale);border:1px solid var(--info-line);font-size:12.5px;color:var(--fg-2);}
.pd-live .ic{flex-shrink:0;color:var(--info);}
.pd-revoke{margin-inline-start:auto;font-size:11.5px;color:var(--fg-3);text-decoration:underline;
  flex-shrink:0;}
.pd-revoke:hover{color:var(--down);}

.pd-sec{border-top:1px solid var(--line-2);padding-top:14px;}
.pd-sec-h{font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--fg-3);margin-bottom:10px;}
html[lang="fa"] .pd-sec-h,html[lang="ar"] .pd-sec-h{letter-spacing:0;text-transform:none;}
.pd-send{display:flex;align-items:center;gap:10px;padding:7px 0;font-size:12px;
  border-bottom:1px solid var(--line-2);}
.pd-send:last-child{border-bottom:none;}
.pd-send-d{color:var(--fg-3);}
.pd-send-s{margin-inline-start:auto;color:var(--fg-2);}
.pd-send-s.ok{color:var(--up);}
.pd-send-s.bad{color:var(--down);}

.pd-notes-list{display:flex;flex-direction:column;gap:9px;margin-bottom:12px;}
.pd-note{background:var(--bg-2);border:1px solid var(--line-2);border-radius:var(--r2);padding:10px 12px;}
/* A note somebody else wrote — a leader coaching this desk — must never read
   as the reader's own memory of a call. */
.pd-note.other{border-inline-start:2px solid var(--mlc);background:var(--mlc-pale);}
.pd-note-b{font-size:12.5px;line-height:1.6;color:var(--fg);white-space:pre-wrap;}
.pd-note-m{font-size:10.5px;color:var(--fg-3);margin-top:5px;}
.pd-note-add{display:flex;gap:8px;}
.pd-note-add .tin{flex:1 1 auto;}

/* ══ THE CARD'S ONE STORY ═════════════════════════════ */
.pd-tl{display:flex;flex-direction:column;}
.pd-tl-row{display:flex;align-items:flex-start;gap:11px;padding:7px 0;position:relative;}
/* The spine: a hairline behind the dots, stopping at the last one. */
.pd-tl-row::before{content:'';position:absolute;inset-inline-start:4px;top:16px;bottom:-7px;
  width:1px;background:var(--line-2);}
.pd-tl-row:last-child::before{display:none;}
.pd-tl-dot{width:9px;height:9px;border-radius:50%;background:var(--bg-4);flex-shrink:0;
  margin-top:5px;position:relative;z-index:1;box-shadow:0 0 0 3px var(--bg-1);}
.pd-tl-dot.registered{background:var(--gold);}
.pd-tl-dot.lost{background:var(--down);}
.pd-tl-dot.demo_opened,.pd-tl-dot.demo_used{background:var(--info);}
.pd-tl-dot.called{background:var(--up);}
.pd-tl-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px;}
.pd-tl-t{font-size:12.5px;color:var(--fg-2);}
.pd-tl-t i{font-style:normal;color:var(--fg-3);}
.pd-tl-note{font-size:12px;color:var(--fg);background:var(--bg-2);border-radius:var(--r2);
  padding:7px 10px;margin-top:3px;white-space:pre-wrap;}
.pd-tl-when{font-size:10.5px;color:var(--fg-3);flex-shrink:0;padding-top:1px;}

/* ══ THE OVERVIEW ═════════════════════════════════════ */
.pd-over{margin-bottom:12px;}
.pd-lv-top{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap;}
.pd-lv-name{font-size:14px;font-weight:600;color:var(--gold-lt);}
.pd-lv-pts{font-family:var(--f-mono);font-size:17px;font-weight:600;color:var(--fg);
  direction:ltr;unicode-bidi:isolate;}
.pd-lv-pts i{font-style:normal;font-size:11px;color:var(--fg-3);}
.pd-lv-track{height:6px;border-radius:3px;background:var(--bg-3);overflow:hidden;margin:9px 0 7px;}
.pd-lv-track span{display:block;height:100%;border-radius:3px;
  background:linear-gradient(90deg,var(--gold-dp),var(--gold-lt));transition:width .6s var(--ease);}
.pd-lv-sub{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;font-size:11px;color:var(--fg-3);}
/* Said in the interface, not only in the code: the platform has a real
   affiliate standing and this ladder is not it. */
.pd-lv-note{font-size:10.5px;color:var(--fg-3);opacity:.75;}

.pd-chart{margin-top:16px;padding-top:14px;border-top:1px solid var(--line-2);}
.pd-chart-h{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  font-size:10.5px;color:var(--fg-3);margin-bottom:10px;flex-wrap:wrap;}
.pd-chart-keys{display:flex;align-items:center;gap:6px;}
.pd-chart-keys .k{width:8px;height:8px;border-radius:2px;display:inline-block;margin-inline-start:6px;}
.pd-chart-keys .k.added{background:var(--bg-4);}
.pd-chart-keys .k.won{background:var(--gold);}
.pd-chart-bars{display:flex;align-items:flex-end;gap:5px;height:40px;direction:ltr;}
/* EVERY MONTH IS A TRACK, FILLED OR NOT. Bars alone scale to the busiest
   month, so eleven quiet months and one busy one drew eleven hairlines and a
   single block — which reads as a stray rectangle rather than as a chart. That
   is the same failure the Planner's trend had, and the same fix: give the
   empty state a shape of its own so an empty year looks empty instead of
   broken.

   Two fills per track, the registered one in front of the added one — the gap
   between them is the story of a pipeline. */
.pd-cm{flex:1 1 0;height:100%;display:flex;align-items:flex-end;justify-content:center;
  position:relative;background:var(--bg-2);border-radius:2px;overflow:hidden;opacity:.55;}
.pd-cm:has(.pd-cm-a),.pd-cm:has(.pd-cm-w){opacity:1;}
.pd-cm-a{width:100%;border-radius:2px 2px 0 0;background:var(--bg-4);}
.pd-cm-w{position:absolute;bottom:0;width:100%;border-radius:2px 2px 0 0;
  background:linear-gradient(180deg,var(--gold),var(--gold-dp));}
.pd-chart-x{display:flex;gap:5px;direction:ltr;margin-top:5px;}
.pd-chart-x span{flex:1 1 0;font-size:9px;color:var(--fg-3);text-align:center;white-space:nowrap;}
.pd-chart-f{display:flex;align-items:center;flex-wrap:wrap;gap:2px;
  font-size:11px;color:var(--fg-3);margin-top:10px;}

/* On a phone the overview and the funnel sit between the reader and the list
   they came for, so both give ground — the panels stay, they just stop being
   the whole first screen. */
@media (max-width:720px){
  .pd-chart-bars{height:28px;}
  .pd-chart{margin-top:12px;padding-top:11px;}
  .pd-fun{gap:5px;}
  .pd-fun-track{height:14px;}
  .pd-over,.pd-fun-row{font-size:11px;}
}

.pd-sort{flex-shrink:0;}
.pd-sort .sel{padding:8px 30px 8px 11px;font-size:12px;min-width:150px;}
[dir="rtl"] .pd-sort .sel{padding:8px 11px 8px 30px;}

.pd-form{display:flex;flex-direction:column;}
.pd-form .field:last-of-type{margin-bottom:16px;}
.pd-tpick{display:flex;gap:7px;flex-wrap:wrap;}
.pd-locked{display:flex;align-items:center;gap:8px;padding:13px 14px;border-radius:var(--r2);
  background:var(--bg-2);border:1px solid var(--line-2);color:var(--fg-3);font-size:13px;}
.pd-locked .ic{margin-inline-start:auto;width:14px;height:14px;}
.pd-why{display:flex;flex-direction:column;gap:8px;}
.pd-why .btn-ghost{justify-content:flex-start;}

/* ══════════════════════════════════════════════════════
   THE LEARNING HUB
   ══════════════════════════════════════════════════════
   A library of things to read. It reuses the vocabulary the rest of this
   sheet already owns — `.mod` for panels, `.pd-lv-track` for the progress
   bars, `.filter-chip` for the tabs, `.tier-badge` for the lock, `.chip` for
   the flags — and adds only what a grid of material genuinely needs that
   nothing else here has: a card with a picture on it.

   THE LOCK IS DRAWN AS AN INVITATION AND NOT AS A REFUSAL. A locked card keeps
   its title, its description and its shape and loses its colour; it does not
   get a red edge or a warning. What it is saying is "there is more here", and
   a card that looked like an error would say the opposite. */

.lh-top{margin-bottom:14px;}
.lh-top-head{display:flex;align-items:flex-start;gap:12px;}
.lh-top-title{font-size:13.5px;font-weight:600;color:var(--fg);}
.lh-top-sub{margin-top:3px;font-size:11.5px;color:var(--fg-3);line-height:1.55;}
.lh-top-pct{margin-inline-start:auto;font-size:22px;font-weight:600;color:var(--gold-lt);
  line-height:1;flex-shrink:0;}

/* One bar per category under the headline one. Three narrow columns on a
   desktop, stacked on a phone — a 60-pixel progress bar reads as a dash. */
/* CAPPED, NOT STRETCHED. `1fr` across a wide panel puts six hundred pixels
   between a category's name and its count, and a 4px bar drawn that wide reads
   as a rule rather than as a measure. Three columns of a readable width,
   packed to the start. */
.lh-cats{display:grid;gap:12px 26px;margin-top:14px;
  grid-template-columns:repeat(auto-fit,minmax(170px,240px));
  justify-content:start;}
.lh-cat-top{display:flex;align-items:baseline;gap:8px;}
.lh-cat-name{font-size:11.5px;color:var(--fg-2);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.lh-cat-n{margin-inline-start:auto;font-size:11px;color:var(--fg-3);flex-shrink:0;}
.pd-lv-track.sm{height:4px;margin:6px 0 0;}
.lh-cat-lock{display:flex;align-items:center;gap:5px;margin-top:5px;
  font-size:10.5px;color:var(--fg-3);}
.lh-cat-lock .ic{width:11px;height:11px;}

.lh-bar{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:14px;}
.lh-chip-n{margin-inline-start:6px;font-size:10px;color:var(--fg-3);}
.filter-chip.active .lh-chip-n{color:var(--on-gold);opacity:.75;}

/* ── The grid ──
   `auto-fill` and not `auto-fit`: with two items in a category, `auto-fit`
   stretches them across the whole width and a training deck ends up drawn
   like a hero banner. `auto-fill` keeps a card a card. */
.lh-grid{display:grid;gap:14px;
  grid-template-columns:repeat(auto-fill,minmax(232px,1fr));}

.lh-card{display:flex;flex-direction:column;background:var(--bg-1);
  border:1px solid var(--line-2);border-radius:var(--r3);overflow:hidden;
  transition:border-color .2s,transform .2s;}
.lh-card:hover{border-color:var(--line);transform:translateY(-2px);}
.lh-card.locked{opacity:.62;}
.lh-card.locked:hover{transform:none;}
/* Read, and quietly so. A finished item is not an achievement to celebrate on
   every card in the grid — it is one the reader can stop looking at. */
.lh-card.done{border-color:var(--up-line);}

.lh-thumb{position:relative;display:block;width:100%;aspect-ratio:16/10;
  background:var(--bg-2);border:none;padding:0;cursor:pointer;overflow:hidden;}
.lh-thumb img{width:100%;height:100%;object-fit:cover;display:block;}
/* ── WHEN THERE IS NO PICTURE ──
   A PDF gets a real thumbnail — the publisher's browser renders its first page
   at upload. A Word file and a PowerPoint never will: nothing on this server
   can rasterise one. So the placeholder has to look like a decision rather
   than like a picture that failed to load, which is what a lone grey glyph in
   a large empty box looks like. The type is named under the mark, on a ground
   tinted a step off the card, and it reads as a cover.

   A VIDEO GETS NO POSTER EITHER, deliberately. YouTube will serve one, and
   fetching it would put every reader's address in front of Google on a page
   they only opened to see a list. The embed itself is `youtube-nocookie` for
   the same reason; loading the poster anyway would give that away for a
   thumbnail. */
.lh-thumb-ic{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:9px;color:var(--fg-3);
  background:linear-gradient(160deg,var(--bg-2),var(--bg-3));}
.lh-thumb-ic .ic-xl{width:34px;height:34px;opacity:.55;}
.lh-thumb-word{font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--fg-3);opacity:.8;}
html[lang="fa"] .lh-thumb-word,html[lang="ar"] .lh-thumb-word{
  letter-spacing:0;text-transform:none;font-size:11px;font-family:var(--f-body);}
.lh-thumb:focus-visible{outline:2px solid var(--gold);outline-offset:-2px;}
.lh-card.locked .lh-thumb{cursor:default;}
/* A blur is not a lock, and this is not one — the picture behind a locked card
   is never fetched at all (`hasThumb && !locked` in learn.js), so there is
   nothing here to see through. */

.lh-tick,.lh-lock{position:absolute;top:8px;inset-inline-end:8px;
  width:24px;height:24px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;backdrop-filter:blur(6px);}
.lh-tick{background:var(--up-pale);border:1px solid var(--up-line);color:var(--up);}
.lh-lock{background:var(--bg-0);border:1px solid var(--line);color:var(--fg-3);}
.lh-tick .ic,.lh-lock .ic{width:13px;height:13px;}

.lh-body{flex:1 1 auto;display:flex;flex-direction:column;gap:6px;padding:12px 13px 0;}
.lh-flags{display:flex;flex-wrap:wrap;gap:6px;}
.lh-flags:empty{display:none;}
.lh-title{background:none;border:none;padding:0;cursor:pointer;text-align:start;
  font-size:13.5px;font-weight:600;color:var(--fg);line-height:1.4;}
.lh-title:hover{color:var(--gold);}
.lh-title:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:var(--r1);}
/* Two lines and then an ellipsis. A blurb somebody wrote at length must not
   make one card in the row twice the height of its neighbours. */
.lh-desc{margin:0;font-size:11.5px;line-height:1.55;color:var(--fg-3);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.lh-meta{font-size:10.5px;color:var(--fg-3);}

.lh-foot{padding:10px 13px 12px;margin-top:10px;}
.lh-check{display:inline-flex;align-items:center;gap:8px;background:none;border:none;
  padding:0;cursor:pointer;font-size:11.5px;color:var(--fg-3);transition:color .2s;}
.lh-check:hover{color:var(--fg-2);}
.lh-check.on{color:var(--up);}
.lh-box{width:17px;height:17px;border-radius:var(--r1);border:1.5px solid var(--line);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
  transition:all .2s;}
.lh-box .ic{width:11px;height:11px;opacity:0;transform:scale(.6);transition:all .2s;}
.lh-check:hover .lh-box{border-color:var(--gold);}
.lh-check.on .lh-box{background:var(--up);border-color:var(--up);color:var(--bg-0);}
.lh-check.on .lh-box .ic{opacity:1;transform:scale(1);}
.lh-check.big{font-size:12.5px;}
.lh-check:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:var(--r1);}

.lh-need{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--fg-3);}
.lh-need .ic{width:12px;height:12px;}

.lh-note{margin:18px 2px 0;font-size:11px;line-height:1.65;color:var(--fg-3);}

/* ── The sheet ── */
.lh-view{margin:-14px -16px 14px;background:var(--bg-0);
  border-bottom:1px solid var(--line-2);min-height:120px;}
.lh-loading{padding:40px 16px;text-align:center;font-size:12px;color:var(--fg-3);}
.lh-hint{margin:0;padding:10px 16px;font-size:11px;color:var(--fg-3);text-align:center;}

.lh-sheet-desc{margin:0 0 10px;font-size:12.5px;line-height:1.65;color:var(--fg-2);}
.lh-sheet-meta{font-size:11px;color:var(--fg-3);margin-bottom:14px;}
.lh-sheet-acts{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
.lh-sheet-acts .btn-gold{margin-inline-start:auto;}

/* ══ THE READER ═══════════════════════════════════════
   The whole viewport. Not a panel with a document in it — the document, with
   the few controls needed to get through it around the edges.

   It replaced a bottom sheet with the page squeezed into the top half of it,
   which on a phone was a column of text four centimetres tall and made
   downloading the file the only sensible way to read anything. Nothing in a
   Learning Hub should have to ask that.

   `z-index` is above the sheet (88), because a locked or undrawable item still
   opens there and the reader must sit over it when both have been used. */
.lh-reader{position:fixed;inset:0;z-index:96;display:flex;flex-direction:column;
  background:var(--bg-0);animation:lhFade .18s var(--ease);}

.lh-rd-top,.lh-rd-foot{display:flex;align-items:center;gap:10px;flex-shrink:0;
  padding:9px 12px;background:var(--bg-1);}
.lh-rd-top{border-bottom:1px solid var(--line-2);}
.lh-rd-foot{border-top:1px solid var(--line-2);justify-content:space-between;
  /* Clear of the home indicator on a phone, where this bar is the last thing
     above the bottom edge of the screen. */
  padding-bottom:calc(9px + env(safe-area-inset-bottom,0px));}

.lh-rd-title{flex:1 1 auto;min-width:0;font-size:13px;font-weight:600;color:var(--fg);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* 40px, because this is a control somebody presses with a thumb sixty times
   while reading a deck on a train. */
.lh-rd-btn{display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;flex-shrink:0;border-radius:var(--r2);
  color:var(--fg-2);background:none;border:none;cursor:pointer;transition:all .15s;}
.lh-rd-btn:hover{background:var(--bg-3);color:var(--fg);}
.lh-rd-btn:disabled{opacity:.3;cursor:default;}
.lh-rd-btn:disabled:hover{background:none;color:var(--fg-2);}
.lh-rd-btn .ic{width:17px;height:17px;}
.lh-rd-btn:focus-visible{outline:2px solid var(--gold);outline-offset:-2px;}

/* The lesson's languages, shown only when there is a choice. Each is named in
   its own script, so the choice does not have to be translated before it can
   be made. Forced LTR as a group so the order is the same in every interface
   language — a picker that reorders itself is a picker people misclick. */
.lh-rd-langs{display:flex;align-items:center;gap:2px;flex-shrink:0;
  direction:ltr;unicode-bidi:isolate;
  border:1px solid var(--line);border-radius:var(--r2);padding:2px;}
.lh-rd-lang{padding:5px 9px;border:none;background:none;cursor:pointer;
  border-radius:var(--r1);font-size:11.5px;color:var(--fg-3);
  transition:all .15s;white-space:nowrap;}
.lh-rd-lang:hover{color:var(--fg);}
.lh-rd-lang.on{background:var(--bg-3);color:var(--gold);font-weight:600;}
.lh-rd-lang:focus-visible{outline:2px solid var(--gold);outline-offset:-2px;}
@media (max-width:560px){.lh-rd-lang{padding:5px 7px;font-size:11px;}}

.lh-rd-zoom{display:flex;align-items:center;gap:2px;flex-shrink:0;}
/* The level, and the way back to it: pressing it puts the page at fit. */
.lh-rd-lvl{min-width:52px;padding:6px 4px;border:none;background:none;cursor:pointer;
  font-size:11.5px;color:var(--fg-3);border-radius:var(--r1);transition:color .15s;}
.lh-rd-lvl:hover{color:var(--gold);}

/* ── The stage ──
   Centred at fit, scrollable once zoomed past it. `place-content` rather than
   flex centring, because a grid keeps a child larger than its container
   scrollable from the top-left instead of clipping its overflow, which is the
   classic bug in a zoomable viewer. */
/* `safe center` IS THE WHOLE TRICK. Plain `center` on a grid whose child is
   larger than the container pushes the overflow off BOTH edges, so the top of
   a page fitted to the width of a phone becomes unreachable — the scrollbar
   cannot go above the start of the track. `safe` keeps it centred while it
   fits and falls back to start alignment the moment it does not. */
.lh-rd-stage{flex:1 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain;
  display:grid;place-content:safe center;padding:12px;
  -webkit-overflow-scrolling:touch;}
.lh-rd-stage.zoomed{cursor:grab;}

.lh-rd-canvas{display:block;background:var(--bg-2);border-radius:var(--r1);
  box-shadow:0 4px 30px rgba(0,0,0,.5);opacity:0;transition:opacity .18s;}
.lh-rd-canvas.on{background:#fff;opacity:1;}

.lh-rd-img{display:block;border-radius:var(--r1);}

/* Sized to the stage rather than to the page: a video has one shape and
   letterboxing it inside a document reader would waste the screen. */
.lh-rd-video{width:min(94vw,1400px);aspect-ratio:16/9;background:#000;
  border-radius:var(--r2);overflow:hidden;}
.lh-rd-video iframe{width:100%;height:100%;border:0;display:block;}

.lh-rd-pages{display:flex;align-items:center;gap:4px;}
.lh-rd-at{min-width:64px;text-align:center;font-size:12px;color:var(--fg-2);
  /* A page count reads left to right in every language. */
  direction:ltr;unicode-bidi:isolate;}

.lh-rd-dl{display:inline-flex;align-items:center;gap:7px;padding:8px 12px;
  border-radius:var(--r2);font-size:12px;color:var(--fg-3);
  border:1px solid var(--line);transition:all .15s;}
.lh-rd-dl:hover{color:var(--gold);border-color:var(--gold-line);}
.lh-rd-dl .ic{width:14px;height:14px;}
/* Two editions sit as a pair, and on a phone they keep their labels — "for a
   phone" and "for a screen" is the whole reason there are two of them, and an
   unlabelled pair of identical download icons is a puzzle. */
.lh-rd-dls{display:flex;align-items:center;gap:6px;}
@media (max-width:560px){
  .lh-rd-dls .lh-rd-dl span{display:inline;}
  .lh-rd-dls .lh-rd-dl{padding:7px 9px;font-size:11px;}
  .lh-rd-dls .lh-rd-dl .ic{display:none;}
}

/* The page behind must not scroll under a full-screen reader — on a phone that
   is how a document turns into a rubber-banding mess. */
body.lh-locked{overflow:hidden;}

@keyframes lhFade{from{opacity:0;}to{opacity:1;}}
@media(prefers-reduced-motion:reduce){
  .lh-reader{animation:none;}
  .lh-rd-canvas{transition:none;}
  .lh-card:hover{transform:none;}
}

/* On a phone the download label is the first thing to go — the icon says it,
   and the page controls are what the thumb is reaching for. */
/* ── THE PHONE'S TOP BAR ──
   Close, title, language, zoom and full-screen do not fit across 390 pixels,
   and what gave way first was the title — squeezed to nothing by a flex rule
   that let it. So the bar WRAPS: the title takes the first line with the close
   button, and the controls take the second. Two rows cost about forty pixels
   of document and keep every control at a size a thumb can hit, which is the
   trade this whole reader exists to make.

   The full-screen button goes entirely. On a phone the reader already fills
   the viewport, and Safari on iOS refuses `requestFullscreen` on anything but
   a video — so it was a button that either did nothing visible or nothing at
   all. */
@media (max-width:560px){
  .lh-rd-dl span{display:none;}
  .lh-rd-dl{padding:8px;}
  .lh-rd-foot .lh-check{font-size:0;gap:0;}
  .lh-rd-foot .lh-check .lh-box{width:22px;height:22px;}
  .lh-rd-foot .lh-check .lh-box .ic{width:13px;height:13px;}
  .lh-rd-stage{padding:6px;}

  /* TWO ROWS, NOT THREE. The title and the close button take the first; the
     language picker and the zoom share the second. A third row would cost
     another forty pixels of the document, which is the thing the reader is
     here for. */
  .lh-rd-top{flex-wrap:wrap;row-gap:5px;padding:8px 12px;}
  .lh-rd-top > [data-lhclose]{order:0;}
  .lh-rd-title{order:1;flex:1 1 auto;font-size:12.5px;}
  .lh-rd-langs{order:2;}
  .lh-rd-zoom{order:3;margin-inline-start:auto;}
  [data-lhfull]{display:none;}
  .lh-rd-lang{padding:6px 11px;font-size:11.5px;}
  .lh-rd-lvl{min-width:44px;}
}

@media (max-width:480px){
  .lh-grid{grid-template-columns:1fr;}
  .lh-top-pct{font-size:19px;}
  .lh-sheet-acts .btn-gold{margin-inline-start:0;}
}

/* ══ THE PLANNER ══════════════════════════════════════ */
.pl-views{display:flex;gap:6px;}
.pl-group{border-bottom:1px solid var(--line-2);}
.pl-group:last-child{border-bottom:none;}
.pl-group-h{display:flex;align-items:center;gap:7px;padding:11px 14px 7px;
  font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--fg-3);}
html[lang="fa"] .pl-group-h,html[lang="ar"] .pl-group-h{letter-spacing:0;text-transform:none;}
.pl-group.late .pl-group-h{color:var(--down);}
.pl-group.late{background:linear-gradient(90deg,var(--down-pale),transparent);}
.pl-group.late .pl-item{box-shadow:inset 3px 0 0 var(--down);}
[dir="rtl"] .pl-group.late .pl-item{box-shadow:inset -3px 0 0 var(--down);}
.pl-pulse{width:7px;height:7px;border-radius:50%;background:var(--down);flex-shrink:0;
  animation:plPulse 1.8s ease-out infinite;}
@keyframes plPulse{
  0%{box-shadow:0 0 0 0 rgba(246,70,93,.55);}
  70%{box-shadow:0 0 0 7px rgba(246,70,93,0);}
  100%{box-shadow:0 0 0 0 rgba(246,70,93,0);}
}
/* A reader who asked the system to stop moving things gets a solid dot.
   `body.no-motion` is this app's own switch (see `applyPrefs`); the media
   query covers the reader who set it in the operating system instead. */
@media (prefers-reduced-motion:reduce){.pl-pulse{animation:none;}}
body.no-motion .pl-pulse{animation:none;}
.pl-today{margin-inline-start:auto;font-size:10px;color:var(--gold);}
.pl-count{margin-inline-start:auto;font-size:10px;color:var(--fg-3);}
.pl-group.now .pl-group-h{color:var(--gold);}
.pl-item{display:flex;align-items:center;gap:11px;width:100%;text-align:start;
  padding:11px 14px;border-top:1px solid var(--line-2);}
.pl-group-h + .pl-item{border-top:none;}
.pl-item.follow:hover{background:var(--bg-2);}
.pl-item-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px;}
.pl-item-t{font-size:13px;color:var(--fg);}
.pl-item-s{font-size:11px;color:var(--fg-3);}
.pl-item-go{color:var(--fg-3);flex-shrink:0;}
/* A follow-up has no tick: it is finished by moving the card it belongs to,
   which is the destination this row already is. */
.pl-tick{width:19px;height:19px;border-radius:50%;border:1.5px solid var(--line);flex-shrink:0;
  transition:border-color .2s,background .2s;}
.pl-tick:hover{border-color:var(--gold);background:var(--gold-pale);}
.pl-del{color:var(--fg-3);flex-shrink:0;opacity:0;transition:opacity .2s;}
.pl-item:hover .pl-del{opacity:1;}
.pl-del:hover{color:var(--down);}
.pl-del .ic{width:14px;height:14px;}
.pl-done{margin-top:10px;}
.pl-form{margin-bottom:12px;}

/* ── The encouragement panel ──
   A mirror of the reader's own week, never anybody else's — see the note on
   `Crm::POINTS_TASK`. It leads the screen because finishing things is what the
   screen is for. */
.pl-stats{padding-bottom:14px;}
.pl-stats-row{display:flex;align-items:center;gap:18px;flex-wrap:wrap;}
.pl-figs{display:flex;gap:26px;flex-wrap:wrap;}
.pl-fig{display:flex;flex-direction:column;gap:2px;min-width:76px;}
.pl-fig-top{display:flex;align-items:baseline;gap:6px;color:var(--fg-3);}
.pl-fig-top .ic{width:12px;height:12px;align-self:center;}
.pl-fig-top b{font-family:var(--f-mono);font-size:20px;font-weight:600;color:var(--fg);
  direction:ltr;unicode-bidi:isolate;letter-spacing:-.02em;}
.pl-fig-l{font-size:10.5px;color:var(--fg-3);}
.pl-fig-s{font-size:10px;color:var(--fg-3);}

/* Fourteen days of completions. Bars and not a line: a day with nothing done
   should read as an absence, and a line drawn through zero implies a value. */
.pl-trend{display:flex;align-items:flex-end;gap:4px;height:52px;margin-top:16px;
  padding-top:18px;border-top:1px solid var(--line-2);position:relative;direction:ltr;}
.pl-tb{flex:1 1 0;border-radius:2px 2px 0 0;min-height:3px;
  background:linear-gradient(180deg,var(--gold-dp),var(--gold-dk));transition:height .4s var(--ease);}
.pl-tb.zero{background:var(--bg-3);}
.pl-tb.now{background:linear-gradient(180deg,var(--gold-lt),var(--gold));}
.pl-trend-l{position:absolute;top:0;inset-inline-start:0;font-size:9.5px;color:var(--fg-3);}
.pl-trend-none{font-size:11.5px;color:var(--fg-3);margin-top:14px;padding-top:12px;
  border-top:1px solid var(--line-2);}

.pl-views{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px;}
.pl-cal{flex-shrink:0;margin-inline-start:auto;}
.pl-pick{display:flex;gap:7px;flex-wrap:wrap;}
.pl-pick .filter-chip{display:inline-flex;align-items:center;gap:5px;}
.pl-pick .filter-chip .ic{width:12px;height:12px;}

/* ── A row ── */
.pl-item.hot{box-shadow:inset 3px 0 0 var(--gold);}
[dir="rtl"] .pl-item.hot{box-shadow:inset -3px 0 0 var(--gold);}
.pl-item.is-done .pl-item-t{color:var(--fg-3);text-decoration:line-through;}
.pl-item-main{background:none;border:none;padding:0;text-align:start;cursor:pointer;}
.pl-item-t{display:flex;align-items:center;gap:7px;}
.pl-item-s .ic{width:11px;height:11px;vertical-align:-1px;margin-inline-end:3px;}
.pl-tick.on{border-color:var(--gold);background:var(--gold);color:var(--on-gold);
  display:flex;align-items:center;justify-content:center;}
.pl-tick.on .ic{width:12px;height:12px;stroke-width:3;}
.pl-tick.fu{border-style:dashed;}
.pl-acts{display:flex;gap:2px;flex-shrink:0;opacity:0;transition:opacity .2s;}
.pl-item:hover .pl-acts,.pl-item:focus-within .pl-acts{opacity:1;}
.pl-act{color:var(--fg-3);padding:4px;border-radius:var(--r1);}
.pl-act:hover{color:var(--gold);background:var(--bg-3);}
.pl-act .ic{width:14px;height:14px;}
.pl-rm{margin-inline-start:auto;color:var(--down);}
/* Touch has no hover, so the row controls have to be there all along. */
@media (hover:none){.pl-acts{opacity:1;}}

/* ══ THE DATE AND TIME PICKERS ════════════════════════
   Hand-built because the native controls follow the BROWSER's locale, not this
   application's — see the block comment above `weekStart()` in dashboard.js.
   Both are Gregorian and 24-hour in every language. */
.dp-field{position:relative;}
.dp-open{display:flex;align-items:center;gap:9px;width:100%;text-align:start;cursor:pointer;}
.dp-open .ic{width:15px;height:15px;color:var(--fg-3);flex-shrink:0;}
.dp-txt{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.dp-caret{margin-inline-start:auto;width:12px !important;height:12px !important;}
.dp-clear{margin-inline-start:auto;display:flex;padding:2px;border-radius:var(--r1);}
.dp-clear:hover{background:var(--bg-3);}
.dp-clear .ic{width:12px;height:12px;}

.dp-pop{
  position:absolute;z-index:60;inset-inline-start:0;top:calc(100% + 6px);
  min-width:300px;max-width:min(340px,calc(100vw - 32px));
  background:var(--bg-1);border:1px solid var(--line);border-radius:var(--r3);
  padding:12px;box-shadow:0 18px 44px rgba(0,0,0,.55);
}
.dp-quick{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:11px;}
.dp-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:9px;}
.dp-mon{font-size:12.5px;font-weight:600;color:var(--fg);}
.dp-nav{color:var(--fg-3);padding:5px;border-radius:var(--r1);display:flex;}
.dp-nav:hover{color:var(--gold);background:var(--bg-3);}
.dp-nav .ic{width:15px;height:15px;}
.dp-day{position:relative;}
.dp-day.on{border-color:var(--gold);background:var(--gold-pale);color:var(--gold-lt);}
.dp-dot{position:absolute;bottom:4px;left:50%;transform:translateX(-50%);
  width:3px;height:3px;border-radius:50%;background:var(--gold);}

/* 24-hour, and the columns say so by never showing anything but 00–23. */
.tp-pop{min-width:236px;}
.tp-cols{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
.tp-col{display:flex;flex-direction:column;gap:5px;min-width:0;}
.tp-lbl{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--fg-3);}
html[lang="fa"] .tp-lbl,html[lang="ar"] .tp-lbl{letter-spacing:0;text-transform:none;}
.tp-scroll{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;
  max-height:150px;overflow-y:auto;padding-inline-end:2px;}
.tp-col:last-child .tp-scroll{grid-template-columns:repeat(3,1fr);}
.tp-cell{padding:7px 0;border-radius:var(--r1);border:1px solid var(--line-2);
  background:var(--bg-2);color:var(--fg-2);font-size:12px;transition:border-color .15s;}
.tp-cell:hover{border-color:var(--gold-line);color:var(--fg);}
.tp-cell.on{border-color:var(--gold);background:var(--gold-pale);color:var(--gold-lt);}

.pl-week{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-bottom:6px;}
.pl-week span{text-align:center;font-size:10px;color:var(--fg-3);}
.pl-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;}
.pl-cell{aspect-ratio:1;border-radius:var(--r1);border:1px solid var(--line-2);background:var(--bg-2);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  font-size:11.5px;color:var(--fg-2);transition:border-color .2s;}
.pl-cell.empty{border:none;background:none;}
.pl-cell.today{border-color:var(--gold-line);color:var(--gold-lt);}
.pl-cell.has{background:var(--bg-3);color:var(--fg);}
.pl-cell:hover:not(.empty){border-color:var(--gold-line);}
.pl-cell-n{font-size:9px;color:var(--gold);}

@media (min-width:720px){
  .pd-fun-row{grid-template-columns:130px minmax(0,1fr) 46px;}
  .pd-form .field-2{grid-template-columns:110px 1fr;}
}

/* ══════════════════════════════════════════════════════
   MENTORING — showing somebody your desk
   ══════════════════════════════════════════════════════
   THE MENTOR-BLUE IS ALREADY IN THE PALETTE and is used here on purpose. It is
   `--mlc`, the same accent `.pd-note.other` uses to mark a note the reader did
   not write, so a coaching remark on a card and the screen that granted the
   coaching read as one colour rather than as two features.

   GOLD IS THE READER'S OWN ACTION and stays that: giving access is gold, the
   people who hold it are blue. Nothing on the read-only side is gold, which is
   the quietest way to say a mentor is not working this desk.
   ══════════════════════════════════════════════════════ */

/* ── What is shared, and what is not ──
   TWO LINES ABOVE THE FIELD THAT GIVES IT AWAY, not below it and not in a help
   page. A reader about to hand over their contact list reads the promise before
   they press the button or the promise is decorative. */
.mn-terms{display:flex;flex-direction:column;gap:7px;margin-bottom:14px;
  padding:11px 12px;border:1px solid var(--line-2);border-radius:var(--r2);background:var(--bg-2);}
.mn-term{display:flex;align-items:flex-start;gap:8px;font-size:11.5px;line-height:1.55;color:var(--fg-2);}
.mn-term .ic{width:13px;height:13px;flex-shrink:0;margin-top:2px;}
.mn-term.ok .ic{color:var(--mlc);}
.mn-term.no .ic{color:var(--fg-3);}
.mn-term.no{color:var(--fg-3);}

/* SIZED TO WHAT GOES IN IT. An account number is eight characters; a field
   running the width of a 1440px card invites a sentence and reads as a search
   box rather than as the one short thing it takes. */
.mn-give{display:flex;gap:8px;margin-bottom:10px;}
.mn-give .tin{flex:0 1 260px;font-family:var(--f-mono);letter-spacing:.04em;}
/* THE MONO IS FOR THE NUMBER, NOT FOR THE PROMPT. The placeholder is a Persian
   or Arabic sentence in the other two languages, and mono with letter-spacing
   pulls a connected script apart. */
.mn-give .tin::placeholder{font-family:var(--f-body);letter-spacing:normal;}
.mn-full{margin:0 0 10px;}

/* ── A row on either side of the screen ── */
.mn-list{display:flex;flex-direction:column;border-top:1px solid var(--line-2);}
.mn-row{display:flex;align-items:center;gap:11px;width:100%;text-align:start;
  padding:12px 2px;border-bottom:1px solid var(--line-2);}
.mn-row:last-child{border-bottom:none;}
.mn-row.off{opacity:.55;}
.mn-row-id{display:flex;flex-direction:column;gap:3px;flex:1 1 auto;min-width:0;}
.mn-row-name{font-size:13px;font-weight:500;color:var(--fg);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mn-row-sub{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--fg-3);flex-wrap:wrap;}

/* Live or stopped, as a mark rather than as a word — the word is on the row
   already and this is what the eye finds first down a column. */
.mn-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;
  background:var(--mlc);box-shadow:0 0 0 3px var(--mlc-pale);}
.mn-row.off .mn-dot{background:var(--fg-3);box-shadow:none;}

/* THE COUNTER IS FOR THE OWNER. "Never opened" is the most useful thing it
   ever says, so it is not styled as an afterthought. */
.mn-reads{display:flex;align-items:center;gap:5px;flex-shrink:0;
  font-size:11px;color:var(--fg-3);}
.mn-reads .ic{width:12px;height:12px;}
.mn-reads i{font-style:normal;color:var(--fg-3);opacity:.75;}
.mn-off-lbl{font-size:11px;color:var(--fg-3);flex-shrink:0;}
.mn-stop{flex-shrink:0;}

/* ── Lists the reader looks after ── */
.mn-go{cursor:pointer;background:none;border:none;transition:background .2s;
  border-radius:var(--r1);padding-inline:6px;}
.mn-go:hover{background:var(--bg-2);}
.mn-go:focus-visible{outline:2px solid var(--gold);outline-offset:2px;}
.mn-av{width:30px;height:30px;border-radius:50%;flex-shrink:0;display:grid;place-items:center;
  background:var(--mlc-pale);border:1px solid var(--mlc-line);color:var(--mlc-lt);}
.mn-av .ic{width:14px;height:14px;}
.mn-chev{flex-shrink:0;color:var(--fg-3);line-height:0;}

/* ══ THE READ-ONLY DESK ══════════════════════════════ */
.mn-deskhead{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:14px;}
.mn-who{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0;}
.mn-who-n{font-size:15px;font-weight:600;color:var(--fg);}
.mn-who-a{font-family:var(--f-mono);font-size:11px;color:var(--fg-3);letter-spacing:.04em;}
/* SAID ON EVERY PAGE OF THE DESK, not once on the way in — a reader hunting for
   a phone number should find out why on the screen they are hunting on. */
.mn-ro{display:inline-flex;align-items:center;gap:5px;flex-shrink:0;
  padding:4px 9px;border-radius:999px;font-size:10.5px;letter-spacing:.04em;
  border:1px solid var(--mlc-line);background:var(--mlc-pale);color:var(--mlc-lt);}
.mn-ro .ic{width:11px;height:11px;}

/* The row with the verbs taken off. No hover-to-act cluster, no gold, and the
   whole row is one button again — which is the truth about what it does. */
.mn-rorow{cursor:pointer;background:none;border:none;border-bottom:1px solid var(--line-2);}
.mn-rorow:focus-visible{outline:2px solid var(--gold);outline-offset:-2px;}
.mn-has{display:inline-flex;align-items:center;gap:4px;color:var(--fg-3);}
.mn-has .ic{width:11px;height:11px;}
.mn-has.on{color:var(--fg-2);}
.mn-has.on .ic{color:var(--mlc);}

/* Where the address and the number sit on the owner's own card. */
.mn-hidden{display:inline-flex;align-items:center;gap:5px;color:var(--fg-3);font-style:italic;}
.mn-hidden .ic{width:11px;height:11px;}

/* ── What they plan to do ── */
.mn-tasks{display:flex;flex-direction:column;gap:6px;}
.mn-task{display:flex;align-items:center;gap:9px;padding:8px 10px;
  border:1px solid var(--line-2);border-radius:var(--r2);background:var(--bg-2);}
.mn-task.done{opacity:.55;}
.mn-task.done .mn-task-t{text-decoration:line-through;}
.mn-task-b{line-height:0;color:var(--gold-dp);}
.mn-task.done .mn-task-b{color:var(--up);}
.mn-task-b .ic{width:13px;height:13px;}
.mn-task-t{flex:1 1 auto;min-width:0;font-size:12.5px;color:var(--fg);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.mn-task-d{flex-shrink:0;font-size:10.5px;color:var(--fg-3);}

/* Whose name goes on the note, said next to the box rather than discovered
   after pressing send. */
.mn-note-sig{margin:7px 0 0;font-size:10.5px;color:var(--fg-3);line-height:1.5;}

/* A note somebody else wrote, on the owner's own card: who it was, above the
   words, because the accent bar alone says "not mine" and not "from whom". */
.pd-note-from{display:flex;align-items:center;gap:5px;margin-bottom:6px;
  font-size:10.5px;letter-spacing:.02em;color:var(--mlc-lt);}
.pd-note-from .ic{width:11px;height:11px;}

@media (max-width:720px){
  /* The read counter drops below the name rather than squeezing it — on a
     phone the name is what the reader is looking for. */
  .mn-row{flex-wrap:wrap;row-gap:7px;}
  .mn-reads{order:3;width:100%;padding-inline-start:18px;}
  .mn-go{flex-wrap:nowrap;}
  .mn-deskhead{gap:9px;}
  .mn-ro{order:4;}
}

/* ══════════════════════════════════════════════════════
   THE ADDRESS THAT HAS NOT ARRIVED YET
   ══════════════════════════════════════════════════════ */

/* WHERE THE ADDRESS WOULD BE, in the row's own detail line and in the card's
   header — not a badge beside the name and not a tint on the whole row. A card
   still waiting for an address is unfinished, not urgent, and `.pd-row.due`
   already spends the row's left edge on the thing that IS urgent. Amber says
   "incomplete" without competing for that. */
.pd-noemail{display:inline-flex;align-items:center;gap:4px;color:var(--warn);}
.pd-noemail .ic{width:11px;height:11px;}

/* ══ ASKING FOR IT, ON THE CARD ══
   Sits directly above the action row, because `Send demo` is the one thing it
   unblocks and the moment somebody needs this is the moment they have just been
   given an address on the phone. */
/* A NEUTRAL PANEL WITH AN AMBER RULE, NOT AN AMBER PANEL. `--warn` (#F0B90B)
   and `--gold` (#E8B647) are all but the same hue, so a fully tinted box reads
   as the card's primary call to action and out-shouts `Send demo` sitting
   directly under it — which is the button this panel exists to get you to. The
   rule carries the same meaning at a fraction of the weight. */
.pd-getmail{margin:14px 0;padding:12px 14px;border-radius:var(--r2);
  border:1px solid var(--line);background:var(--bg-2);
  border-inline-start:2px solid var(--warn);}
.pd-getmail-h{display:flex;align-items:center;gap:7px;
  font-size:12px;font-weight:600;color:var(--fg);}
.pd-getmail-h .ic{width:13px;height:13px;color:var(--warn);}
.pd-getmail-s{margin:5px 0 10px;font-size:11.5px;line-height:1.55;color:var(--fg-2);}
.pd-getmail-row{display:flex;gap:8px;}
.pd-getmail-row .tin{flex:1 1 auto;min-width:0;}
.pd-getmail-row .btn-gold{flex-shrink:0;}

@media (max-width:480px){
  /* The field takes the width and the button drops under it, rather than the
     two of them squeezing an email address into forty pixels. */
  .pd-getmail-row{flex-direction:column;}
  .pd-getmail-row .btn-gold{width:100%;}
}

/* ── THE NUMBER ON A PROSPECT ──
   A prospect list is written down the page and quoted by number. It leads the
   row because that is where the eye counts, and it is deliberately quiet: the
   name is what the reader is looking for, the number is what they say out loud
   once they have found it. Tabular figures so a column of them lines up. */
.pd-seq{
  flex-shrink:0;min-width:2.1em;
  font-size:11px;color:var(--fg-3);text-align:end;
  font-variant-numeric:tabular-nums;
}
.pd-card-name .pd-seq{margin-inline-end:8px;font-size:12px;}

/* A board still filling. Stated, not warned about: it is a fact about how much
   has been measured, not a fault in what is shown. */
.hl-partial{color:var(--fg-2);}

/* ══════════════════════════════════════════════════════
   UP / DOWN — the trading screen
   ══════════════════════════════════════════════════════
   Logical properties throughout, so the whole screen mirrors in Arabic and
   Persian without a single [dir="rtl"] rule. The two exceptions are the ones
   that must NOT mirror: a price and a countdown are figures, and figures read
   left to right in every language this product speaks. They carry dir="ltr"
   in the markup and `unicode-bidi:isolate` here, which is the same treatment
   the onchain board gives an address.
   ══════════════════════════════════════════════════════ */
.ud-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;}
.ud-bal{font-size:12px;color:var(--fg-3);}
.ud-bal b{color:var(--fg);margin-inline-start:6px;}

/* The warning that stands where the ticket would be. It is not a banner above
   the form — until it is accepted there IS no form, which is the difference
   between a disclosure and a checkbox. */
.ud-warn{border-color:var(--warn-line);}
.ud-warn-t{font-family:var(--f-display);font-size:15px;font-weight:700;margin-bottom:10px;}
.ud-warn p{font-size:12.5px;line-height:1.75;color:var(--fg-2);margin-bottom:10px;}
.ud-warn .btn-gold{margin-top:4px;}


.ud-lbl{font-size:11px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--fg-3);margin-top:12px;margin-bottom:7px;}


.ud-chips{display:flex;gap:7px;flex-wrap:wrap;}
.ud-chip{
  padding:8px 14px;border-radius:999px;cursor:pointer;min-height:38px;
  background:var(--bg-2);border:1px solid var(--line-2);color:var(--fg-2);
  font-family:var(--f-mono);font-size:12px;
}
.ud-chip.on{background:var(--gold-dp);border-color:var(--gold);color:var(--gold-lt);}

.ud-amt{display:flex;align-items:center;gap:8px;background:var(--bg-2);
  border:1px solid var(--line-2);border-radius:var(--r2);padding:0 13px;}
.ud-amt:focus-within{border-color:var(--gold);}
.ud-amt-in{
  flex:1;min-width:0;background:none;border:0;outline:none;padding:14px 0;
  font-family:var(--f-mono);font-size:19px;color:var(--fg);
  direction:ltr;unicode-bidi:isolate;
}
.ud-amt-sfx{font-size:12px;color:var(--fg-3);flex:none;}

.ud-hint{font-size:11px;color:var(--fg-3);margin-top:6px;}
.ud-facts{margin-top:14px;border-top:1px solid var(--line-2);}
.ud-why{font-size:11.5px;line-height:1.7;color:var(--fg-3);margin-top:8px;}
.ud-place{width:100%;margin-top:14px;}
.ud-place:disabled{opacity:.36;pointer-events:none;box-shadow:none;}

/* A market with no usable price. Named on the tab rather than hidden, because
   a market that quietly disappears is a market the reader thinks they imagined. */
.ud-dot{display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--warn);margin-inline-start:6px;}

.ud-list{padding:0;}
.ud-row{
  display:flex;align-items:center;gap:11px;padding:13px 15px;cursor:pointer;
  border-bottom:1px solid var(--line-2);min-height:56px;
}
.ud-row:last-child{border-bottom:0;}
.ud-row:hover{background:var(--bg-2);}
.ud-row-dir{display:flex;flex:none;width:30px;height:30px;border-radius:50%;
  align-items:center;justify-content:center;}
.ud-row-dir .ic{width:14px;height:14px;}
.ud-row-dir.up{background:var(--up-pale);color:var(--up);}
.ud-row-dir.down{background:var(--down-pale);color:var(--down);}
.ud-row-main{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1;}
.ud-row-sym{font-size:13px;font-weight:600;}
.ud-row-sub{font-size:11px;color:var(--fg-3);font-family:var(--f-mono);}
.ud-row-end{display:flex;flex-direction:column;align-items:flex-end;gap:3px;flex:none;}
.ud-row-stake{font-size:13px;font-family:var(--f-mono);}
.ud-row-res{font-size:10.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--fg-3);}
.ud-row-res.up{color:var(--up);}
.ud-row-res.down{color:var(--down);}
/* The countdown. LTR because it is a figure, and tabular so it does not jitter
   as the seconds tick down. */
.ud-row-left{font-family:var(--f-mono);font-size:12px;color:var(--gold-lt);
  font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate;}

.ud-confirm .kv:first-child{border-top:0;}
.ud-result-line{font-size:14px;line-height:1.7;margin-bottom:12px;}
.ud-result.up .ud-result-line{color:var(--up);}
.ud-result.down .ud-result-line{color:var(--down);}
.ud-proof-h{font-family:var(--f-display);font-size:13px;font-weight:700;margin:16px 0 4px;}

@media(min-width:768px){
}

/* ── AN AMOUNT IS A FIGURE, AND FIGURES DO NOT MIRROR ──
   "+70.00 ZC" is mixed content: a sign, Latin digits and a Latin unit. Laid out
   in an RTL line it comes out "ZC 70.00+" — every part correct and the whole
   thing wrong. Isolating the value fixes all of them at once, and it belongs
   here rather than in the markup because every value in these blocks is a
   figure; there is no case that wants the other behaviour. */
.ud-facts .kv-v,
.ud-confirm .kv-v,
.ud-row-stake,
.ud-bal b{direction:ltr;unicode-bidi:isolate;}


/* The risk sheet. Its actions sit at the bottom as a pair so "accept" is never
   the only thing a reader can press — a disclosure with one button is a door
   with one direction, and this one has to be dismissible. */
.ud-warn-sheet p{font-size:13px;line-height:1.8;color:var(--fg-2);margin-bottom:12px;}
.ud-warn-sheet p:first-child{color:var(--fg);font-weight:500;}
.ud-warn-acts{display:flex;gap:10px;margin-top:18px;flex-wrap:wrap;}
.ud-warn-acts .btn-gold{flex:1;min-width:160px;}
.ud-warn-acts .btn-ghost{flex:none;}

/* ── The chart card ──
   Fixed height so the ticket below it does not jump as candles load, and the
   host is a plain div because the library owns everything inside it. */
.ud-chart-card{padding-bottom:12px;}
.ud-chart-head{display:flex;align-items:center;justify-content:space-between;
  gap:10px;margin-bottom:10px;flex-wrap:wrap;}
.ud-chart-sym{font-size:13px;font-weight:600;}
.ud-chart-ivs{display:flex;gap:6px;}
.ud-chip.sm{padding:5px 10px;font-size:11px;min-height:30px;}
.ud-chart{width:100%;height:260px;}
.ud-chart-note{font-size:11px;line-height:1.7;color:var(--fg-3);margin-top:9px;}

/* ══════════════════════════════════════════════════════
   BINARY OPTION — the trading terminal
   ══════════════════════════════════════════════════════
   The shape every exchange converges on, and it converges for a reason: the
   chart is what you look at, the panel is what you touch, and the positions are
   what you check. One grid, source order = phone order, so the layout is a
   rearrangement of the same markup rather than two of them.

   Green is up and red is down, everywhere, without exception. A screen that
   uses the accent gold for one side and a semantic colour for the other makes
   the two sides look like different KINDS of action, and they are not.
   ══════════════════════════════════════════════════════ */

/* ── The market strip ── */
/* ── The market strip ──
   Was a row of flat grey boxes with the name in plain white — a market picker
   that read as a list of words. Now each market is a card carrying its own
   mark, its ticker code, its price and a tinted move pill, in the house's own
   gold-on-dark language. Tiles grow to fill a wide column and scroll on a
   phone: `flex:1 0 <basis>` fills when there is room, overflow scrolls when
   there is not, so one rule serves both without a media query. */
.ud-strip{
  display:flex;gap:10px;overflow-x:auto;padding-bottom:4px;margin-bottom:16px;
  scrollbar-width:none;-ms-overflow-style:none;
  /* A swipe lands on a card rather than between two. */
  scroll-snap-type:x proximity;scroll-padding-inline:0;
}
.ud-strip-i{scroll-snap-align:start;}
/* On a wide screen every card fits, so the shoulder is wasted space and the
   row goes back to filling the width it has. */
@media(min-width:768px){ .ud-strip-i{flex:1 0 154px;} }
.ud-strip::-webkit-scrollbar{display:none;}

/* ══════════════════════════════════════════════════════
   A STRIP THAT CONTINUES, SAYING SO
   ══════════════════════════════════════════════════════
   Six rows in this stylesheet scroll sideways with their scrollbar deliberately
   hidden — which is right on a phone, where the bar is invisible until you are
   already dragging, and wrong the moment it is the only thing that would have
   told a reader there was more.

   `data-edge` is written by `bindEdgeFades()` and says which sides have content
   beyond them. The fade is a MASK, so it stays welded to the box while the
   content travels under it, and it is only ever on the side that is actually
   hiding something: a row scrolled to its end shows no fade at its end.

   Written against the attribute rather than against each class, so a strip opts
   in by being named once in the binder rather than by growing its own rules. */
[data-edge="end"]{
  -webkit-mask-image:linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
  mask-image:linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
}
[data-edge="start"]{
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 34px);
  mask-image:linear-gradient(to right, transparent 0, #000 34px);
}
[data-edge="both"]{
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 34px,
                                     #000 calc(100% - 34px), transparent 100%);
  mask-image:linear-gradient(to right, transparent 0, #000 34px,
                             #000 calc(100% - 34px), transparent 100%);
}
.ud-strip-i{
  /* ── THE NEXT CARD HAS TO PEEK ──
     This was `flex:1 0 154px`, and the `1` was the whole problem: the cards
     that fit GREW to fill the row, so the last visible one ended flush with the
     right edge and the strip looked like a list of exactly two things. Gold and
     Ethereum were one swipe away and nothing on screen said so.

     A basis that leaves a sliver of the next card showing is the standard way
     a horizontal row says it continues — it needs no arrow, no dots and no
     instruction, and it is the same signal a reader already knows from every
     other app on the phone. Two cards plus a 34px shoulder at any width. */
  flex:0 0 calc(50% - 22px);display:flex;flex-direction:column;gap:10px;
  padding:12px 13px;border-radius:var(--r3);cursor:pointer;text-align:start;
  background:
    linear-gradient(158deg,rgba(255,255,255,0.022),transparent 62%),
    var(--bg-1);
  border:1px solid var(--line-2);color:var(--fg-2);
  transition:border-color .18s var(--ease),background .18s var(--ease),
    box-shadow .18s var(--ease),transform .18s var(--ease);
}
.ud-strip-i:hover{border-color:var(--gold-line);transform:translateY(-1px);}
/* Selected is the one that gets the gold: a lit ring, a warm ground and a soft
   glow, so the active market is unmistakable across the width of the strip. */
.ud-strip-i.on{
  border-color:var(--gold);
  background:
    linear-gradient(158deg,var(--gold-pale),transparent 60%),
    var(--bg-2);
  box-shadow:0 0 0 1px var(--gold-line),0 6px 20px -10px var(--gold-glow);
}
.ud-strip-top{display:flex;align-items:center;gap:9px;}
.ud-strip-mark{display:flex;flex:none;}
.ud-strip-mark .cix{width:26px;height:26px;}
.ud-strip-id{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1;}
.ud-strip-n{
  font-size:12.5px;font-weight:650;color:var(--fg);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:-0.01em;
}
.ud-strip-i.on .ud-strip-n{color:var(--gold-lt);}
.ud-strip-code{
  display:flex;align-items:center;
  font-family:var(--f-mono);font-size:9.5px;letter-spacing:0.06em;
  color:var(--fg-3);direction:ltr;unicode-bidi:isolate;
}
/* The move, as a tinted pill with a direction wedge — the exchange convention,
   and a far cleaner read than bare coloured digits. */
.ud-strip-c{
  flex:none;display:inline-flex;align-items:center;gap:3px;
  padding:2px 6px;border-radius:999px;
  font-family:var(--f-mono);font-size:10px;font-weight:600;line-height:1;
  direction:ltr;unicode-bidi:isolate;
}
.ud-strip-c.up{color:var(--up);background:var(--up-pale);}
.ud-strip-c.down{color:var(--down);background:var(--down-pale);}
.ud-strip-c.none{color:var(--fg-3);background:var(--bg-3);}
.ud-arw{width:0;height:0;border-inline:3px solid transparent;}
.ud-strip-c.up .ud-arw{border-bottom:4px solid var(--up);}
.ud-strip-c.down .ud-arw{border-top:4px solid var(--down);}
.ud-strip-p{
  font-family:var(--f-mono);font-size:16px;font-weight:600;color:var(--fg);
  font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate;
  letter-spacing:-0.01em;
}
.ud-strip-i.on .ud-strip-p{color:var(--fg);}
.ud-strip-code .ud-dot{margin-inline-start:6px;}

/* ── The symbol header ── */
.ud-hd{
  display:flex;align-items:flex-end;justify-content:space-between;gap:16px;
  flex-wrap:wrap;padding:14px 16px;margin-bottom:12px;
  background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r3);
}
.ud-hd-sym{font-size:13px;font-weight:700;display:flex;align-items:baseline;gap:8px;}
.ud-hd-code{font-family:var(--f-mono);font-size:10.5px;color:var(--fg-3);
  letter-spacing:.04em;direction:ltr;unicode-bidi:isolate;}
.ud-hd-row{display:flex;align-items:baseline;gap:10px;margin-top:4px;}
.ud-hd-price{
  font-family:var(--f-mono);font-size:30px;font-weight:600;color:var(--fg);
  font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate;
  line-height:1.1;
}
.ud-hd-price.up{color:var(--up);}
.ud-hd-price.down{color:var(--down);}
.ud-hd-chg{font-family:var(--f-mono);font-size:13px;color:var(--fg-3);
  direction:ltr;unicode-bidi:isolate;}
.ud-hd-chg.up{color:var(--up);}
.ud-hd-chg.down{color:var(--down);}
.ud-hd-stats{display:flex;gap:22px;}
.ud-hd-stat{display:flex;flex-direction:column;gap:3px;}
.ud-hd-stat span{font-size:10px;letter-spacing:.05em;text-transform:uppercase;color:var(--fg-3);}
.ud-hd-stat b{font-family:var(--f-mono);font-size:12.5px;font-weight:500;
  font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate;}

/* ── The working grid ── */
.ud-work{display:flex;flex-direction:column;gap:14px;}
.ud-main{min-width:0;display:flex;flex-direction:column;gap:14px;}
.ud-side{min-width:0;display:flex;flex-direction:column;gap:10px;}
/* ── The balance, at the head of the panel ──
   Same card, same border, same tokens as `.ud-panel` below it — this is the
   house surface at a larger size, not a new one. The figure is monospace and
   tabular so it does not shuffle as it changes, and isolated LTR because an
   amount is a figure. */
.ud-bal{
  display:flex;flex-direction:column;gap:5px;
  background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r3);
  padding:13px 16px;
}
.ud-bal-k{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--fg-3);}
.ud-bal-v{
  /* Gold, because that is what a Z Coin figure is in this product — the wallet
     stat, the coin chip and the portfolio card all render it this way. Picking
     anything else here would make the same balance a different colour on a
     different screen, which is how a reader stops trusting either. */
  font-family:var(--f-mono);font-size:24px;font-weight:700;color:var(--gold-lt);
  line-height:1.15;font-variant-numeric:tabular-nums;
  direction:ltr;unicode-bidi:isolate;
  display:flex;align-items:baseline;gap:6px;
  /* `direction:ltr` fixes the order INSIDE the figure — "3,705.00 ZC" and never
     "ZC 3,705.00". It does not place the box, and a full-width box packs its
     contents left, which under RTL left the label on the right and the number
     on the left. Shrinking the box to its content and aligning it to the
     writing direction's start puts both on the same edge in both languages. */
  align-self:start;width:max-content;
}
.ud-bal-u{font-size:12px;font-weight:500;font-style:normal;color:var(--fg-3);}

/* ── The order panel ── */
.ud-panel{
  background:var(--bg-1);border:1px solid var(--line-2);border-radius:var(--r3);
  padding:15px 16px 17px;
}
.ud-panel .ud-lbl:first-child{margin-top:0;}
.ud-quicks{display:flex;gap:6px;margin-top:8px;flex-wrap:wrap;}
.ud-quick{
  flex:1;min-width:46px;padding:7px 0;border-radius:var(--r1);cursor:pointer;
  background:var(--bg-2);border:1px solid var(--line-2);color:var(--fg-2);
  font-family:var(--f-mono);font-size:11.5px;min-height:34px;
}
.ud-quick:hover{border-color:var(--gold-line);color:var(--fg);}

/* ── The two actions ──
   Equal in every dimension. Same width, same height, same type, same weight —
   only the colour and the word differ, because only the colour and the word
   differ about what they do. */
.ud-acts{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:18px;}
.ud-act{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  padding:13px 8px;border-radius:var(--r2);cursor:pointer;min-height:66px;
  border:1px solid transparent;font-weight:700;
  transition:transform .12s var(--ease), filter .16s var(--ease);
}
.ud-act .ic{width:16px;height:16px;}
.ud-act-t{font-size:13.5px;letter-spacing:.01em;}
.ud-act-s{font-family:var(--f-mono);font-size:11px;opacity:.85;
  direction:ltr;unicode-bidi:isolate;}
.ud-act.up{background:var(--up);color:#062012;}
.ud-act.down{background:var(--down);color:#2A0308;}
.ud-act:hover:not(:disabled){filter:brightness(1.08);}
.ud-act:active:not(:disabled){transform:scale(.985);}
.ud-act:disabled{opacity:.34;cursor:not-allowed;}
.ud-loss{
  margin-top:9px;text-align:center;font-size:11.5px;color:var(--fg-3);
}
.ud-loss b{font-family:var(--f-mono);margin-inline-start:5px;
  direction:ltr;unicode-bidi:isolate;}

.ud-pos{background:var(--bg-1);border:1px solid var(--line-2);
  border-radius:var(--r3);overflow:hidden;}
.ud-pos .wtabs{margin:0;border-bottom:1px solid var(--line-2);}
.ud-pos .card{border:0;border-radius:0;background:none;}

/* ── The chart fills the space it is given ── */
.ud-chart-card{padding:13px 14px 12px;}
.ud-chart{height:300px;}

@media(min-width:1024px){
  /* Panel to its own column, chart into what is left, positions under the
     chart. 320px is the width the amount field, the expiry row and two
     side-by-side actions need — narrower and the actions wrap their own labels.

     Named areas rather than order numbers, because the three children read in
     phone order in the source and this is the only place that says otherwise. */
  .ud-work{
    display:grid;grid-template-columns:minmax(0,1fr) 320px;
    grid-template-areas:"main side" "pos side";align-items:start;
  }
  .ud-main{grid-area:main;}
  .ud-side{grid-area:side;position:sticky;top:78px;}
  .ud-pos{grid-area:pos;}
  .ud-chart{height:380px;}
  .ud-hd-price{font-size:34px;}
}
@media(max-width:479px){
  .ud-hd{padding:12px 13px;}
  .ud-hd-price{font-size:26px;}
  .ud-hd-stats{gap:16px;}
  .ud-chart{height:240px;}
}

/* ── The amount, with its stepper ──
   The figure is the widest thing in the row and the two buttons sit at its
   edges, so the eye lands on the number rather than on the controls. */
.ud-amt{padding:0;}
.ud-step{
  flex:none;width:42px;align-self:stretch;cursor:pointer;
  background:none;border:0;color:var(--fg-3);font-size:18px;line-height:1;
  min-height:48px;
}
.ud-step:hover{color:var(--gold-lt);background:var(--bg-3);}
.ud-amt-in{text-align:center;padding:13px 0;}
.ud-amt-sfx{padding-inline-end:2px;}

/* ── The payout headline ──
   The one number that decides whether the proposition is worth taking. Its two
   readings stay below at ordinary size — a headline that travels alone is how
   a payout gets mistaken for a return. */
.ud-payout{
  display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  margin-top:18px;padding:11px 13px;border-radius:var(--r2);
  background:var(--bg-2);border:1px solid var(--line-2);
}
.ud-payout-k{font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--fg-3);}
.ud-payout-v{
  font-family:var(--f-mono);font-size:26px;font-weight:700;color:var(--up);
  line-height:1;direction:ltr;unicode-bidi:isolate;
}
.ud-acts{margin-top:10px;}

/* A countdown that has run out and not been settled. Amber rather than red:
   the trade is not lost, it is late, and those read differently. */
.ud-row-left.warn{color:var(--warn);}

/* ══ BINARY OPTION — the card on Home ══════════════════
   It sits directly under the wallet balance, in the wide column, and it is the
   only card on this page a member can act on in the next thirty seconds. That
   earns it the gold rule at the top and a real call to action — and nothing
   more than that. The accent is the one this product already uses for Z Coin;
   a second highlight colour invented for one card is how a design stops being
   a design. */
.ud-w-note{font-size:11.5px;line-height:1.7;color:var(--fg-3);margin:-6px 0 13px;}

.ud-w-tiles{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px;}
.ud-w-tile{
  display:flex;flex-direction:column;gap:3px;min-width:0;cursor:pointer;
  padding:11px 12px;border-radius:var(--r2);text-align:start;
  background:var(--bg-2);border:1px solid var(--line-2);color:inherit;
  transition:border-color .16s var(--ease);
}
.ud-w-tile:hover{border-color:var(--gold-line);}
.ud-w-t-top{display:flex;align-items:center;gap:8px;}
.ud-w-t-name{font-size:12px;font-weight:600;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* The payout rides on the market it belongs to rather than in a column of its
   own, so a reader comparing two markets compares two complete offers. */
.ud-w-t-pay{
  margin-inline-start:auto;flex:none;
  font-family:var(--f-mono);font-size:10.5px;font-weight:600;
  color:var(--gold-lt);background:var(--gold-dp);border-radius:999px;padding:2px 7px;
  direction:ltr;unicode-bidi:isolate;
}
.ud-w-t-price{font-family:var(--f-mono);font-size:14px;color:var(--fg);
  font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate;}
.ud-w-t-chg{font-family:var(--f-mono);font-size:11px;color:var(--fg-3);
  direction:ltr;unicode-bidi:isolate;}
.ud-w-t-chg.up{color:var(--up);}
.ud-w-t-chg.down{color:var(--down);}

.ud-w-foot{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin-top:14px;padding-top:13px;border-top:1px solid var(--line-2);flex-wrap:wrap;
}
.ud-w-offer{display:flex;flex-direction:column;align-items:flex-end;gap:2px;text-align:end;}
/* "Payout up to 70%" is a sentence with a figure at the end, and in an RTL line
   the sign detaches and lands in front — "%70". Isolating the figure keeps the
   two together whichever way the line runs. */
.ud-w-offer b{font-family:var(--f-mono);font-size:13.5px;color:var(--gold-lt);font-weight:700;}
.ud-w-offer b,.ud-w-offer i{unicode-bidi:isolate;}
.ud-w-offer b bdi,.ud-w-offer i bdi{direction:ltr;unicode-bidi:isolate;}
/* The break-even rate, at ordinary size, on the same line as the payout. This
   module has never shown one without the other and the front page is the last
   place to start. */
.ud-w-offer i{font-style:normal;font-size:10.5px;color:var(--fg-3);}

@media(max-width:479px){
  .ud-w-tiles{grid-template-columns:minmax(0,1fr);}
  .ud-w-foot{flex-direction:column;align-items:stretch;}
  .ud-w-offer{align-items:flex-start;text-align:start;}
}
