/* ==========================================================================
   TRADEX — the Quant X design system.

   Retheming happens HERE, at the token layer, and nowhere else. Every component
   in this file and every inline style in the 25 tab modules already reads
   var(--...), so remapping these VALUES restyles the whole application without
   touching a single component. Names never change — a rename would silently
   break every tab. Add colours here or not at all.

   The values below are lifted verbatim from quant-x/dashboard.html and
   quant-x/index.html so the two products render as one platform:

     old TradeX            Quant X token          value
     --bg      #06080F  →  --bg                   #0b0f17
     --bg2     #090D18  →  --bg-deep              #080c12
     --panel   #0E1322  →  --bg-raise             #0f1521
     --panel-2 #141B2E  →  --bg-panel             #111928
     --panel-line α     →  --line (solid)         #1d2737
     --panel-line-hot α →  --line-bright (solid)  #2a3a52
     --cyan    #45E2EA  →  --accent               #22d3ee
     --txt     #E7EBF6  →  --ink                  #e8eef7
     --txt-dim #98A2BC  →  --ink-2                #9aa8bc
     --txt-faint #8089A5→  --ink-3                #7E8EA4
     --green   #36E0A0  →  --pos                  #34d399
     --red     #FF5C73  →  --neg                  #f87171
     --amber   #F4B740  →  --warn                 #fbbf24
     --violet  #8C7DF7  →  --violet               #a78bfa

   Display + body: Space Grotesk · Data: JetBrains Mono (loaded from Google
   Fonts in index.html exactly as the quant-x pages load them; there is no CSP
   on this origin, and both faces degrade to system stacks if the link fails).
   ========================================================================== */
:root{
  --bg:#0b0f17;
  --bg2:#080c12;             /* deepest surface: sidebar, tooltips, wells */
  --panel:#0f1521;           /* raised surface: panels, cards, tiles */
  --panel-2:#111928;         /* inset surface: inputs, gray pills */
  --panel-3:#1d2737;
  /* Borders are SOLID in Quant X, not translucent. A hairline that shifts with
     whatever sits behind it is what made the old sheet read muddy. */
  --panel-line:#1d2737;
  --panel-line-hot:#2a3a52;
  --grid:rgba(42,58,82,.30);

  --cyan:#22d3ee;
  --cyan-deep:#0ea5c4;
  --blue:#0ea5c4;
  --ice:#67e8f9;
  --teal:#22d3ee;
  --violet:#a78bfa;
  --gold:#fbbf24;

  --txt:#e8eef7;
  --txt-dim:#9aa8bc;
  --txt-faint:#7E8EA4;
  --white:#f4f8ff;

  /* Bull and bear. Named for what they mean, not what colour they are. */
  --green:#34d399;
  --mint:#34d399;
  --red:#f87171;
  --coral:#f87171;
  --amber:#fbbf24;

  /* Quant X does not glow. What is left of --neon is a single soft cast under
     an accent surface — and it is now a 3-length shadow, so it is finally legal
     inside the filter:drop-shadow() and text-shadow() that consume it (the old
     4-length value with a spread was silently dropped by both). */
  --neon:0 0 14px rgba(34,211,238,.45);
  --neon-soft:0 4px 18px -6px rgba(34,211,238,.45);

  --r-sm:9px;
  --r:14px;
  --r-lg:20px;
  --sbw:214px;               /* sidebar width */
  --hdr:60px;                /* topbar height — the sidebar sticks below it */

  /* --font stays the body face because every existing rule and inline style
     already points at it; it is now the display face, as on the Quant X deck.
     Data and code opt into the mono face explicitly. */
  --font:'Space Grotesk','Inter',system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-display:'Space Grotesk','Inter',system-ui,sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,"SF Mono",Menlo,Consolas,monospace;
}

*{box-sizing:border-box}
html,body{margin:0;height:100%}
html{overflow-x:clip}          /* as on the deck: nothing scrolls the page sideways */
/* Flat. The Quant X deck is a single deep surface with hairline-separated
   panels on top of it — the old radial glows and the 44px grid overlay were
   the loudest part of the difference between the two products. */
body{
  background:var(--bg);
  color:var(--txt);
  font-family:var(--font);
  font-size:14px;
  letter-spacing:0;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
/* Everything in this sheet is sized in px, so bumping a root font-size would
   move almost nothing. zoom scales the whole rendered tree — text, padding,
   borders — which is what "make it bigger" actually means here. */
#app{position:relative;z-index:1;min-height:100vh;display:flex;flex-direction:column;
  zoom:1.06}
@supports not (zoom:1.06){           /* older Firefox: at least lift the type */
  #app{font-size:106%}
}

/* The app shell: persistent left rail + content column, as on the deck. */
.shell{display:grid;grid-template-columns:var(--sbw) 1fr;flex:1;min-height:0}
.shell>*{min-width:0}

/* ---- scrollbars ---- */
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--panel-line-hot);border-radius:6px}
::-webkit-scrollbar-thumb:hover{background:var(--txt-faint)}
::selection{background:var(--cyan);color:#04141a}

/* ================= TOPBAR =================
   The deck's topbar: one 60px strip, hairline under it, brand at the left and
   the account control at the right. Navigation is no longer here — it lives in
   the left rail below. */
header.hud{
  display:flex;align-items:center;gap:18px;
  height:var(--hdr);padding:0 22px;position:sticky;top:0;z-index:30;
  border-bottom:1px solid var(--panel-line);
  background:rgba(11,15,23,.88);backdrop-filter:blur(12px);
}
.brand{display:flex;align-items:center;gap:12px;min-width:0}
.brand .logo{
  width:32px;height:28px;display:grid;place-items:center;color:var(--cyan);flex:none;
}
/* The mark ships as an opaque PNG with a baked-in near-black background; lighten
   resolves it to the header behind it. Full reasoning in site/css/site.css. */
.brand .logo img{height:28px;width:auto;display:block;mix-blend-mode:lighten}
.brand h1{
  font-family:var(--font-display);
  font-size:17px;margin:0;letter-spacing:.14em;font-weight:700;color:var(--txt);
  white-space:nowrap;
}
/* The per-tab subtitle is the deck's breadcrumb: mono, tracked, tertiary. */
.brand .sub{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.2em;
  color:var(--txt-faint);margin-top:2px;text-transform:uppercase;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}

/* burger — only ever visible in the mobile drawer breakpoint */
.sb-burger{display:none;background:none;border:1px solid var(--panel-line-hot);
  border-radius:8px;color:var(--txt);padding:5px 9px;cursor:pointer;
  font-family:var(--font-mono);font-size:14px;line-height:1;flex:none}
.sb-burger:hover{border-color:var(--cyan);color:var(--cyan)}

.runbar{display:flex;flex-direction:column;align-items:center;gap:6px}
.runbtns{display:flex;gap:8px}
.runbtns button{
  background:none;border:1px solid var(--panel-line-hot);color:var(--txt-dim);
  padding:7px 15px;border-radius:var(--r-sm);font-family:var(--font);font-size:11.5px;
  font-weight:600;letter-spacing:.08em;
  cursor:pointer;transition:.15s;display:flex;align-items:center;gap:6px;
}
.runbtns button:hover{border-color:var(--txt-faint);color:var(--txt)}
.runbtns button.on{color:var(--cyan);border-color:rgba(34,211,238,.35);background:rgba(34,211,238,.12)}
.runbtns button.stop{color:var(--red);border-color:rgba(248,113,113,.35)}
.runbtns button.stop:hover{background:rgba(248,113,113,.1);border-color:var(--red)}
.running-tag{font-size:10.5px;font-family:var(--font-mono);color:var(--txt-faint)}
.running-tag b{color:var(--cyan)}

.status-pills{display:flex;justify-content:flex-end;align-items:center;gap:10px;margin-left:auto}
.pill{
  display:flex;align-items:center;gap:8px;border:1px solid var(--panel-line);
  border-radius:20px;padding:5px 12px;font-family:var(--font-mono);font-size:10.5px;
  letter-spacing:.1em;color:var(--txt-dim);background:var(--panel-2);
}
.pill .dot{width:7px;height:7px;border-radius:50%;background:var(--green);flex:none}
.pill.engine .dot{background:var(--cyan)}
.pill b{color:var(--txt)}

/* account widget (topbar) + LOG IN nav entry */
.acct{display:flex;align-items:center}
.acct-in{display:flex;align-items:center;gap:10px;border:1px solid var(--panel-line);
  border-radius:20px;padding:4px 6px 4px 13px;background:var(--panel-2);
  font-family:var(--font-mono);font-size:10.5px}
.acct-bal{color:var(--txt-dim);letter-spacing:.1em;white-space:nowrap}
.acct-bal b{color:var(--cyan);font-size:12px}
.acct-cr{color:var(--txt-faint)}
.acct-email{color:var(--txt);max-width:150px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;letter-spacing:.02em}
.acct-btn{background:none;border:1px solid var(--panel-line-hot);color:var(--txt-dim);
  padding:5px 12px;border-radius:16px;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.12em;
  cursor:pointer;transition:.15s}
.acct-btn:hover{border-color:var(--txt-faint);color:var(--txt)}

/* ================= LEFT RAIL =================
   The deck's sidebar: sticky, its own scroll, mono section headings, one
   active item carrying the accent. Section headings are written by app.js as
   .sb-sec rows inside the same #tabs element the old pill row used. */
.sidebar{
  display:flex;flex-direction:column;
  background:var(--bg2);border-right:1px solid var(--panel-line);
  position:sticky;top:var(--hdr);align-self:start;
  height:calc(100vh - var(--hdr));overflow-y:auto;z-index:20;
}
nav.tabs{display:flex;flex-direction:column;gap:2px;padding:14px 12px 18px}
.sb-sec{
  font-family:var(--font-mono);font-size:9px;letter-spacing:.22em;color:var(--txt-faint);
  text-transform:uppercase;padding:15px 10px 6px;user-select:none;
}
.sb-sec:first-child{padding-top:2px}
nav.tabs button,nav.tabs a{
  display:flex;align-items:center;gap:10px;
  background:transparent;border:1px solid transparent;color:var(--txt-dim);
  padding:8px 11px;border-radius:var(--r-sm);font-family:var(--font);font-size:12.5px;
  font-weight:500;letter-spacing:.04em;text-transform:none;
  cursor:pointer;transition:.15s;text-decoration:none;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;
}
nav.tabs button:hover,nav.tabs a:hover{background:var(--panel-2);color:var(--txt)}
nav.tabs button.active,nav.tabs a.active{
  color:var(--cyan);border-color:rgba(34,211,238,.35);background:rgba(34,211,238,.12);
}
nav.tabs button.loginlink,nav.tabs a.loginlink{color:var(--cyan);
  border-color:rgba(34,211,238,.35);background:rgba(34,211,238,.12)}
.sb-foot{margin-top:auto;padding:14px 12px;border-top:1px solid var(--panel-line);
  display:flex;justify-content:center}

/* ================= PANELS ================= */
/* The deck caps a view at 1460px and centres it: past that, a table row is
   wider than the eye tracks in one pass. */
main{flex:1;padding:20px 22px 40px;min-width:0;max-width:1460px;width:100%;margin:0 auto}
.panel{
  position:relative;background:var(--panel);
  border:1px solid var(--panel-line);border-radius:var(--r);padding:16px 18px;
}
/* Panel headings are the deck's small mono caps — tertiary ink, not a glowing
   cyan label on every box. The accent is reserved for what is actually live. */
.panel-title{
  font-family:var(--font-mono);font-size:10.5px;font-weight:500;letter-spacing:.16em;
  color:var(--txt-faint);margin-bottom:13px;
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;text-transform:uppercase;
}
.panel-title .accent{color:var(--txt)}
/* When the strapline will not fit beside the heading it drops to its own line
   rather than squeezing the heading into two words per row. */
.panel-title small{color:var(--txt-faint);font-size:9.5px;letter-spacing:.12em;opacity:.85;
  flex:1 1 240px}

.grid{display:grid;gap:16px}
.grid>*{min-width:0}          /* prevent nowrap tables from blowing out grid tracks */
.panel{overflow:hidden}
.deck-grid{grid-template-columns:370px 1fr 360px}
table.mini th,table.mini td{padding:5px 5px;font-size:10px}
table.mini .tiny{font-size:8.5px}
.two{grid-template-columns:1fr 1fr}
.three{grid-template-columns:1fr 1fr 1fr}

/* ================= TABLES =================
   All tabular data is mono and tabular-figures: columns of numbers have to
   line up when you scan them for an hour. */
table{width:100%;border-collapse:collapse;font-family:var(--font-mono);font-size:11.5px}
th{color:var(--txt-faint);font-weight:500;text-align:left;letter-spacing:.14em;
   padding:8px 9px;font-size:9.5px;text-transform:uppercase;border-bottom:1px solid var(--panel-line)}
td{padding:8px 9px;border-bottom:1px solid var(--panel-line);color:var(--txt-dim);white-space:nowrap}
tbody tr:last-child td{border-bottom:none}
tr:hover td{background:rgba(34,211,238,.05)}
td.num,th.num{text-align:right}
.pos{color:var(--green)}
.neg{color:var(--red)}
.muted{color:var(--txt-dim)}
.hl{color:var(--cyan)}
.chipid{color:var(--txt);font-weight:600}

/* score badge */
.badge{display:inline-block;padding:1px 7px;border-radius:6px;font-size:10px;
  border:1px solid var(--panel-line);color:var(--cyan)}
.badge.s{background:rgba(34,211,238,.12)}

/* ================= STAT TILES ================= */
.stat-row{display:grid;gap:14px}
.stat{border:1px solid var(--panel-line);border-radius:var(--r);padding:14px 16px;background:var(--panel)}
.stat .k{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.16em;color:var(--txt-faint);text-transform:uppercase}
.stat .v{font-family:var(--font-mono);font-size:26px;font-weight:700;color:var(--txt);margin-top:6px;line-height:1.1}
.stat .v.g{color:var(--green)}
.stat .s{font-family:var(--font-mono);font-size:10.5px;color:var(--txt-faint);margin-top:5px}

/* ================= BARS / METERS =================
   Flat accent fills on a --line track, as on the deck's gauntlet bars. */
.meter{height:5px;border-radius:3px;background:var(--panel-line);overflow:hidden;margin-top:6px}
.meter>span{display:block;height:100%;background:var(--cyan);border-radius:3px}
.barrow{display:flex;align-items:center;gap:10px;margin:7px 0;font-family:var(--font-mono);font-size:11px}
.barrow .lab{width:120px;color:var(--txt-dim);flex:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.barrow .track{flex:1;height:6px;background:var(--panel-line);border-radius:3px;overflow:hidden}
.barrow .track>span{display:block;height:100%;background:var(--cyan);border-radius:3px}
.barrow .val{width:74px;text-align:right;color:var(--txt-faint)}

/* progress ring */
.ring{--p:34;--c:var(--cyan);width:120px;height:120px;border-radius:50%;
  background:conic-gradient(var(--c) calc(var(--p)*1%), var(--panel-line) 0);
  display:grid;place-items:center;position:relative}
.ring::after{content:"";position:absolute;inset:12px;border-radius:50%;background:var(--panel)}
.ring b{position:relative;z-index:1;color:var(--txt);font-family:var(--font-mono);font-size:20px}

/* toggles */
.toggle{display:inline-flex;align-items:center;gap:8px}
.sw{width:34px;height:17px;border-radius:12px;background:var(--panel-2);position:relative;
  cursor:pointer;border:1px solid var(--panel-line-hot);transition:.15s}
.sw::after{content:"";position:absolute;top:1px;left:1px;width:13px;height:13px;border-radius:50%;
  background:var(--txt-faint);transition:.15s}
.sw.on{background:var(--cyan);border-color:var(--cyan)}
.sw.on::after{left:18px;background:#04141a}

/* segmented control */
.seg{display:inline-flex;border:1px solid var(--panel-line-hot);border-radius:20px;overflow:hidden}
.seg button{background:transparent;border:0;color:var(--txt-dim);padding:5px 13px;
  font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;cursor:pointer}
.seg button:hover{color:var(--txt)}
.seg button.on{background:rgba(34,211,238,.12);color:var(--cyan)}

/* chips */
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{border:1px solid var(--panel-line-hot);border-radius:20px;padding:6px 12px;
  font-family:var(--font-mono);font-size:11px;background:none;
  color:var(--txt-dim);letter-spacing:.06em;cursor:pointer;transition:.15s}
.chip:hover{color:var(--txt);border-color:var(--txt-faint)}
.chip.on{color:var(--cyan);border-color:rgba(34,211,238,.35);background:rgba(34,211,238,.12)}
.chip.warn{color:var(--amber);border-color:rgba(251,191,36,.35);background:rgba(251,191,36,.1)}
.chip.blue{color:var(--ice);border-color:rgba(103,232,249,.35)}

/* inputs */
input.f,select.f,textarea.f{
  width:100%;background:var(--panel-2);border:1px solid var(--panel-line-hot);border-radius:var(--r-sm);
  color:var(--txt);font-family:var(--font-mono);font-size:12px;padding:9px 12px;letter-spacing:.02em;
}
input.f::placeholder,textarea.f::placeholder{color:var(--txt-faint)}
input.f:focus,select.f:focus,textarea.f:focus{outline:none;border-color:rgba(34,211,238,.35)}
label.fl{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.16em;color:var(--txt-faint);text-transform:uppercase;display:block;margin-bottom:5px}
.field{margin-bottom:14px}
.formgrid{display:grid;grid-template-columns:130px 1fr;gap:12px 16px;align-items:center}
.formgrid label.fl{margin:0}

/* code / log */
.log{font-family:var(--font-mono);font-size:10.5px;line-height:1.7;color:var(--txt-dim);max-height:340px;overflow:auto}
.log .h{color:var(--cyan)}
.log .g{color:var(--green)}
.log .hr{color:var(--txt-faint)}
.echo{font-family:var(--font-mono);font-size:10.5px;color:var(--ice);line-height:1.6;max-height:150px;overflow:auto;
  background:var(--bg2);border:1px solid var(--panel-line);border-radius:var(--r-sm);padding:10px}

/* DNA helix */
.helix{width:90px;height:290px;position:relative;flex:none}

/* neural core canvas */
.core-wrap{position:relative;min-height:520px;display:grid;place-items:center}
#coreCanvas{width:100%;height:520px}
.core-center{position:absolute;top:44%;left:50%;transform:translate(-50%,-50%);text-align:center;pointer-events:none}
.core-center .big{font-family:var(--font-mono);font-size:74px;font-weight:700;color:var(--txt);line-height:.9}
.core-center .big small{font-size:26px;color:var(--txt-faint)}
.core-center .lab{font-family:var(--font-mono);font-size:10px;letter-spacing:.26em;color:var(--txt-faint);margin-top:6px}
.core-center .tribe{color:var(--cyan);font-family:var(--font-mono);font-size:13px;letter-spacing:.14em;margin-top:14px}
.core-center .task{color:var(--txt-dim);font-size:11px;margin-top:4px}
.core-stats{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-top:8px;text-align:center}
.core-stats .k{font-family:var(--font-mono);font-size:8.5px;letter-spacing:.14em;color:var(--txt-faint)}
.core-stats .v{font-family:var(--font-mono);font-size:16px;font-weight:700;color:var(--txt);margin-top:3px}
.core-stats .v.c{color:var(--cyan)}
.core-stats .v.g{color:var(--green)}

/* chart */
.chart{width:100%;height:100%;display:block}
.legend{display:flex;flex-wrap:wrap;gap:6px 14px;font-family:var(--font-mono);font-size:10px;color:var(--txt-dim);margin-top:10px}
.legend i{display:inline-block;width:10px;height:3px;border-radius:2px;margin-right:5px;vertical-align:middle}

/* footer strip */
footer.strip{display:grid;grid-template-columns:repeat(6,1fr);gap:14px;
  padding:14px 26px;border-top:1px solid var(--panel-line);margin-top:8px}
footer.strip .cell .k{font-family:var(--font-mono);font-size:9px;letter-spacing:.18em;color:var(--txt-faint);text-transform:uppercase}
footer.strip .cell .v{font-family:var(--font-mono);font-size:20px;font-weight:700;color:var(--txt);margin-top:5px}
footer.strip .cell .v.c{color:var(--cyan)}
footer.strip .cell .v.g{color:var(--green)}

.section-gap{height:16px}
.flex{display:flex}.between{justify-content:space-between}.center{align-items:center}.gap{gap:10px}
.wrap{flex-wrap:wrap}
.scrolly{max-height:430px;overflow:auto}
/* .tiny is the sheet's caption/label class — mono caps, the deck signature. */
.tiny{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;color:var(--txt-faint)}
.hidden{display:none!important}

/* guide */
.guide-step{border:1px solid var(--panel-line);border-radius:var(--r);background:var(--panel);
  padding:20px 24px;margin-bottom:16px;
  display:grid;grid-template-columns:64px 1fr;gap:18px;align-items:start;position:relative}
.guide-step .n{font-family:var(--font-mono);font-size:34px;font-weight:700;color:var(--cyan)}
.guide-step h3{margin:0 0 8px;font-size:15px;letter-spacing:.02em;color:var(--txt)}
.guide-step p{margin:0 0 8px;color:var(--txt-dim);line-height:1.7;font-size:12.5px}
.guide-step .tag{position:absolute;top:16px;right:18px;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.12em;
  border:1px solid var(--panel-line-hot);border-radius:14px;padding:3px 10px;color:var(--txt-dim)}
.guide-step b{color:var(--cyan)}
.guide-hero h2{font-size:30px;letter-spacing:-.01em;color:var(--txt);margin:0 0 12px}
.guide-hero h2 span{color:var(--cyan)}

/* map */
#mapCanvas{width:100%;height:74vh;display:block;border-radius:var(--r)}
.map-legend{position:absolute;left:22px;bottom:30px;background:var(--bg2);
  border:1px solid var(--panel-line-hot);border-radius:var(--r-sm);padding:12px 16px;
  font-family:var(--font-mono);font-size:11px}
.map-legend .row{display:flex;align-items:center;gap:10px;margin:5px 0}
.map-legend .row i{width:9px;height:9px;border-radius:50%}
.map-legend .row b{margin-left:auto;color:var(--txt)}

/* insights heat cell */
.heat{padding:5px 8px;border-radius:6px;text-align:center;color:var(--green);font-family:var(--font-mono)}
.heat.best{border:1px solid rgba(52,211,153,.45);background:rgba(52,211,153,.12)}
.heat.dim{color:var(--txt-faint)}

/* portfolio list item */
.pf-item{border:1px solid var(--panel-line);border-radius:var(--r-sm);padding:12px 14px;margin-bottom:10px;cursor:pointer;transition:.15s}
.pf-item:hover{border-color:var(--panel-line-hot);background:var(--panel-2)}
.pf-item.on{border-color:rgba(34,211,238,.35);background:rgba(34,211,238,.12)}
.pf-item .top{display:flex;justify-content:space-between;align-items:center}
.pf-item .name{color:var(--txt);font-size:14px;font-weight:600;letter-spacing:0}
.pf-item .g{width:22px;height:22px;border-radius:6px;display:grid;place-items:center;
  font-family:var(--font-mono);font-size:11px;
  border:1px solid var(--panel-line-hot);color:var(--cyan)}
.pf-item .meta{font-family:var(--font-mono);font-size:10.5px;color:var(--txt-faint);margin-top:6px}

.grade-badge{width:70px;height:70px;border-radius:var(--r);display:grid;place-items:center;
  border:1px solid rgba(251,191,36,.35);background:rgba(251,191,36,.1);
  font-family:var(--font-mono);font-size:38px;font-weight:700;color:var(--amber)}
.grade-sub{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:14px 0}
.grade-sub .cell{border:1px solid var(--panel-line);border-radius:var(--r-sm);padding:8px;text-align:center}
.grade-sub .cell .k{font-family:var(--font-mono);font-size:8.5px;letter-spacing:.14em;color:var(--txt-faint)}
.grade-sub .cell .v{font-family:var(--font-mono);font-size:20px;font-weight:700;margin-top:4px}
.gA{color:var(--green)}.gB{color:var(--ice)}.gC{color:var(--amber)}.gD{color:var(--red)}

.deploy-btns{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-top:14px}
.deploy-btns button{background:rgba(34,211,238,.12);border:1px solid rgba(34,211,238,.35);color:var(--cyan);
  padding:12px;border-radius:var(--r-sm);font-family:var(--font);font-weight:600;
  letter-spacing:.06em;font-size:12px;cursor:pointer;transition:.15s}
.deploy-btns button:hover{background:rgba(34,211,238,.2)}
.deploy-btns button.ghost{color:var(--txt-dim);background:none;border-color:var(--panel-line-hot)}
.deploy-btns button.ghost:hover{color:var(--txt);background:var(--panel-2)}

/* toolbar */
.toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:14px}
.toolbar .seg,.toolbar input.f,.toolbar select.f{margin:0}
.toolbar input.f{width:240px}
.toolbar select.f{width:auto}

@media (max-width:1500px){
  .deck-grid{grid-template-columns:1fr}
  footer.strip{grid-template-columns:repeat(3,1fr)}
}

/* ---- responsive: the rail collapses to a scrolling strip ----------------
   Under 820px there is no room for a 214px rail beside a data table, so the
   rail becomes a horizontal strip pinned under the topbar. It is a strip and
   not a hidden drawer on purpose: navigation you can see beats navigation you
   have to remember is there, and it needs no JS to open. */
@media (max-width:820px){
  .shell{grid-template-columns:1fr}
  .sidebar{
    position:sticky;top:var(--hdr);height:auto;align-self:stretch;
    border-right:0;border-bottom:1px solid var(--panel-line);
    flex-direction:row;overflow-x:auto;overflow-y:hidden;
  }
  nav.tabs{flex-direction:row;padding:9px 12px;gap:6px}
  nav.tabs button,nav.tabs a{border-radius:20px;padding:6px 13px;font-size:12px}
  .sb-sec,.sb-foot{display:none}
  header.hud{padding:0 14px;gap:12px}
  main{padding:16px 14px 34px}
}
@media (max-width:560px){
  .brand h1{font-size:15px}
  .acct-email{max-width:96px}
}

/* ---- product switcher (Trade X AI <-> Quant X) -----------------------
   Both products share this origin and this session cookie, so switching is
   a plain link — no re-auth, no token hand-off. It lives in the foot of the
   rail, where the deck keeps its tier chip. */
.prodswitch{
  display:inline-flex;align-items:center;gap:2px;
  border:1px solid var(--panel-line);border-radius:999px;padding:3px;
  background:var(--panel-2);font-family:var(--font-mono);font-size:10px;letter-spacing:.08em;
  text-transform:uppercase;line-height:1;white-space:nowrap;
}
.prodswitch a{
  padding:6px 11px;border-radius:999px;color:var(--txt-faint);
  text-decoration:none;transition:color .15s,background .15s;
}
.prodswitch a:hover{color:var(--txt)}
.prodswitch a.on{background:var(--cyan);color:#04141a;font-weight:700}

/* Product switch at the TOP of the rail, above the section list. It used to
   live in .sb-foot, which supplied the separator and the bottom placement;
   both are restated here rather than inherited. display:flex (not the base
   inline-flex) so it spans the rail instead of hugging its text at the top
   of a column. */
.prodswitch-top{
  /* Vertical in the rail. Three platform names — Trade X Charts, Trade X AI,
     Trade X Quant X — do not fit side by side in a 200px column; laid out in a
     row they either overflow or shrink to unreadable. Stacked, each gets the
     rail's full width and reads at its intended size. The horizontal pill is
     kept for the mobile strip below, and the marketing site header keeps its
     own horizontal strip, where there is room for it. */
  display:flex;flex-direction:column;align-items:stretch;gap:3px;
  margin:12px 12px 6px;padding:3px;border-radius:var(--r-sm);
}
.prodswitch-top a{
  border-radius:var(--r-sm);text-align:center;padding:8px 10px;
}
@media (max-width:900px){
  /* The rail turns into a horizontal strip here and .sb-foot was hidden
     outright. Keep the switch visible — it is the one control that changes
     which product you are looking at — but let it sit inline in the strip. */
  /* Back to a row here: the rail is a horizontal strip at this width, so a
     stacked switch would push the whole page down. */
  .prodswitch-top{flex-direction:row;margin:0;align-self:center;flex:none;padding:2px;border-radius:999px}
  .prodswitch-top a{padding:6px 11px;border-radius:999px}
}

/* ==========================================================================
   QUANT X COMPONENT LAYER
   Typography and the small component set the Quant X site uses. Appended
   rather than woven in, so the port is one reviewable block and reverting it
   means deleting from here down.
   ========================================================================== */

/* The deck's type scale: display face, tight tracking, no glow. */
h1,h2,h3,h4{font-family:var(--font-display);letter-spacing:-.01em;font-weight:700;color:var(--txt)}
h1{font-size:22px}
h2{font-size:19px}
h3{font-size:16px;font-weight:600}
h4{font-size:14px;font-weight:600}

/* Data stays monospaced — columns of numbers must align, and a licence key or
   a ticket is read character by character. */
code,pre,.mono,.num,td.num,th.num,.hub-code,.m5-raw,.tv{font-family:var(--font-mono)}
.num,td.num{font-variant-numeric:tabular-nums}

/* Small uppercase labels: the Quant X signature. */
.fl,.cs-tl,.tl{font-family:var(--font-mono);font-weight:500;font-size:10.5px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--txt-faint)}
th{font-family:var(--font-mono);font-weight:500;font-size:9.5px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--txt-faint)}

/* ---------- stat tiles ---------- */
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:14px;margin-bottom:20px}
.tile{background:var(--panel);border:1px solid var(--panel-line);border-radius:var(--r);
  padding:17px 18px;position:relative;overflow:hidden}
.tile::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--cyan);opacity:.85}
.tile.g::before{background:var(--mint)}
.tile.go::before{background:var(--gold)}
.tile.v::before{background:var(--violet)}
.tile.c::before{background:var(--coral)}
.tile .tl{display:block}
.tile .tv{font-family:var(--font-mono);font-size:26px;font-weight:700;margin-top:8px;
  letter-spacing:0;color:var(--txt);display:block;line-height:1.1}
.tile .td{font-family:var(--font-mono);font-size:11px;margin-top:6px;color:var(--txt-faint)}
.tile .td.up{color:var(--mint)}
.tile .td.down{color:var(--coral)}

/* ---------- badges ---------- */
.badge{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-mono);
  font-weight:600;font-size:11px;letter-spacing:.03em;padding:4px 9px;border-radius:7px;
  border:1px solid var(--panel-line-hot);color:var(--txt-dim);white-space:nowrap}
.badge.ok{color:var(--mint);border-color:rgba(52,211,153,.35);background:rgba(52,211,153,.12)}
.badge.info{color:var(--cyan);border-color:rgba(34,211,238,.35);background:rgba(34,211,238,.12)}
.badge.warn{color:var(--gold);border-color:rgba(251,191,36,.35);background:rgba(251,191,36,.12)}
.badge.bad{color:var(--coral);border-color:rgba(248,113,113,.35);background:rgba(248,113,113,.12)}
.badge.mute{color:var(--txt-faint);border-color:var(--panel-line);background:var(--panel-2)}

/* Focus is designed, not inherited. Keyboard users get the same signal colour
   the rest of the interface uses for "this is live". */
a:focus-visible,button:focus-visible,input:focus-visible,
select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--cyan);outline-offset:2px;border-radius:4px}

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

/* ==========================================================================
   MOTION LAYER — a trading desk reads as live, not decorated.

   Rule for everything here: motion carries information or it does not ship.
   Panels reveal so the eye follows the order of the page; live indicators
   pulse because "connected" is a state worth seeing across the room; numbers
   flash on change because a figure that moved is the one you care about.
   Nothing bounces, nothing spins for decoration, nothing delays a click.

   All of it is disabled under prefers-reduced-motion by the block above.
   ========================================================================== */

/* Panels arrive as the eye reaches them. 260ms is under the ~300ms where
   motion starts feeling like waiting. */
.panel, .tile, .cs-daycard{
  animation: tx-rise .26s cubic-bezier(.22,.61,.36,1) both;
}
@keyframes tx-rise{
  from{ opacity:0; transform:translateY(8px) }
  to  { opacity:1; transform:none }
}
/* Staggered so a grid of tiles reads left to right rather than all at once. */
.tiles .tile:nth-child(1){ animation-delay:.02s }
.tiles .tile:nth-child(2){ animation-delay:.06s }
.tiles .tile:nth-child(3){ animation-delay:.10s }
.tiles .tile:nth-child(4){ animation-delay:.14s }
.tiles .tile:nth-child(5){ animation-delay:.18s }

/* The accent bar on a tile sweeps once on arrival — the desk "powering on". */
.tile::before{ animation: tx-bar .5s ease-out both }
@keyframes tx-bar{ from{ transform:scaleY(0); transform-origin:top } to{ transform:scaleY(1) } }

/* A live connection is a state, so it breathes. Used by the MT5 bridge dot. */
.m5-dot.m5-on{ animation: tx-pulse 4.5s ease-in-out infinite }
@keyframes tx-pulse{
  0%,100%{ box-shadow:0 0 0 0 rgba(52,211,153,.55) }
  50%    { box-shadow:0 0 0 6px rgba(52,211,153,0) }
}

/* A figure that just changed is the one worth looking at. Applied by app.js. */
.tx-changed{ animation: tx-flash .9s ease-out }
@keyframes tx-flash{
  0%  { background:rgba(34,211,238,.22); border-radius:4px }
  100%{ background:transparent }
}

/* Rows in a data table settle in sequence, like a feed filling. Capped at 10
   so a 200-row table does not become a slideshow. */
table tr{ animation: tx-row .22s ease-out both }
table tr:nth-child(1){ animation-delay:.00s } table tr:nth-child(2){ animation-delay:.02s }
table tr:nth-child(3){ animation-delay:.04s } table tr:nth-child(4){ animation-delay:.06s }
table tr:nth-child(5){ animation-delay:.08s } table tr:nth-child(6){ animation-delay:.10s }
table tr:nth-child(7){ animation-delay:.12s } table tr:nth-child(8){ animation-delay:.14s }
table tr:nth-child(9){ animation-delay:.16s } table tr:nth-child(n+10){ animation-delay:.18s }
@keyframes tx-row{ from{ opacity:0; transform:translateX(-4px) } to{ opacity:1; transform:none } }

/* Controls answer instantly. Transition, never animation — an animation on
   hover queues up and makes the interface feel laggy under a fast pointer. */
.chip, button, .tile, .panel{ transition: transform .12s ease, box-shadow .18s ease,
  border-color .18s ease, background .18s ease }
.chip:hover, button:hover{ transform:translateY(-1px) }
.chip:active, button:active{ transform:translateY(0) }
.tile:hover{ border-color:var(--panel-line-hot); box-shadow:var(--neon-soft) }

/* The signal colour sweeps the top of a panel on hover — the one purely
   atmospheric touch, and it costs nothing because it is a gradient, not a node. */
.panel{ position:relative; overflow:hidden }
.panel::after{
  content:""; position:absolute; left:0; right:0; top:0; height:1px;
  background:linear-gradient(90deg, transparent, var(--cyan), transparent);
  opacity:0; transition:opacity .3s ease;
}
.panel:hover::after{ opacity:.55 }

/* ---------------------------------------------------------------- downloads
   The filenames under YOUR LICENCE are the one thing on that panel a customer
   came to click, and they were rendering as ordinary monospace body text —
   indistinguishable from the seat table above them. These glow so the eye
   lands on them first.

   The glow is on the text, not a background: a filled chip would read as a
   button and invite a click on the whole row, when only the name is the link.
   The pulse is slow and shallow on purpose — this marks the target, it does
   not demand attention every second — and it is dropped entirely for anyone
   who has asked the OS to reduce motion, for whom a breathing page is a
   symptom trigger rather than a flourish. */
.dl-file{
  color:var(--cyan);
  text-shadow:var(--neon);
  text-decoration:none;
  letter-spacing:.01em;
  transition:color .18s ease, text-shadow .18s ease;
  animation:dl-breathe 4.5s ease-in-out infinite;
}
.dl-file:hover,
.dl-file:focus-visible{
  color:#7ef0ff;
  text-shadow:0 0 18px rgba(34,211,238,.85), 0 0 34px rgba(34,211,238,.35);
  text-decoration:underline;
  animation:none;            /* a hovered target has been found; stop marking it */
}
.dl-file:focus-visible{ outline:1px solid var(--cyan); outline-offset:3px }

@keyframes dl-breathe{
  0%,100%{ text-shadow:0 0 10px rgba(34,211,238,.34) }
  50%    { text-shadow:0 0 17px rgba(34,211,238,.62) }
}

@media (prefers-reduced-motion: reduce){
  .dl-file{ animation:none; text-shadow:var(--neon) }
}

/* ------------------------------------------------------- deck-style surface
   The Quant X deck reads as the more modern of the two consoles, and this
   brings its language to the dashboard: uppercase monospace headings that sit
   back, numbers that come forward, and hairline cards with no decoration
   competing with the figures.

   Scoped under .deckish rather than applied to .panel and .tile globally.
   Those two classes are used by every tab in the app, and restyling them from
   here would silently redesign fifteen screens nobody asked about — including
   the builder, where the panel chrome is load-bearing for a form. One screen
   changes; the rest are a deliberate decision for later. */
.deckish .vhead{
  display:flex; align-items:flex-end; gap:16px; flex-wrap:wrap; margin-bottom:20px;
}
.deckish .vhead h1{ font-size:22px; font-weight:700; letter-spacing:-.01em; margin:0 }
.deckish .vhead p{
  color:var(--txt-faint); font-family:var(--font-mono); font-size:11.5px;
  letter-spacing:.06em; margin:4px 0 0; text-transform:uppercase;
}
.deckish .vhead .spacer{ margin-left:auto }

/* KPI tiles. The left accent bar goes: on the deck the number IS the emphasis,
   and a coloured rule beside every tile competes with the one figure that
   actually moved. Colour is kept for the value when it carries meaning. */
.deckish .tiles{ gap:12px }
.deckish .tile{ padding:15px 16px; border-radius:var(--r-sm) }
.deckish .tile::before{ display:none }
.deckish .tile .tl{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--txt-faint);
}
.deckish .tile .tv{ font-size:27px; margin-top:9px }
.deckish .tile.g .tv{ color:var(--mint) }
.deckish .tile.go .tv{ color:var(--gold) }
.deckish .tile.v .tv{ color:var(--violet) }
.deckish .tile.c .tv{ color:var(--coral) }

/* Cards. The deck's heading is a label, not a title: small, spaced, receding,
   with anything status-like pushed to the right rail of the same line. */
.deckish .panel{ border-radius:var(--r-sm); padding:0 }
.deckish .panel-title{
  display:flex; align-items:center; gap:8px; padding:14px 16px 0;
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--txt-faint); border:0;
}
.deckish .panel-title small{
  margin-left:auto; text-transform:none; letter-spacing:.02em;
  font-size:10.5px; color:var(--txt-faint); opacity:.8;
}
.deckish .panel > *:not(.panel-title){ padding:12px 16px 16px }
.deckish .panel + .panel{ margin-top:12px }
