:root{font-family:'SFMono-Regular',Consolas,'Liberation Mono',monospace;color:#24364a;background:#f8fafc;font-size:14px;--blue:#2658d9;--teal:#158975;--line:#b8c5cf}*{box-sizing:border-box}body{margin:0}header{display:flex;justify-content:space-between;align-items:center;padding:24px 28px;background:white;border-bottom:1px solid var(--line)}.brand{display:flex;gap:15px;align-items:center}.mark{background:var(--blue);color:white;font-size:44px;width:58px;height:58px;text-align:center}h1{font-size:29px;font-weight:500;margin:0;letter-spacing:1px}h1 small{font-size:14px;color:#8291a0}p{line-height:1.6}.brand p{font-size:12px;letter-spacing:2px;margin:8px 0 0}.session{display:grid;grid-template-columns:auto auto;gap:8px 20px;align-items:center}.session b{font-size:24px}.session>span:last-child{grid-column:1/3;text-align:right;font-size:12px}.badge{background:#eaf0ff;color:var(--blue);padding:7px;font-size:12px}.tape{display:flex;justify-content:space-between;gap:25px;padding:14px 28px;background:#edf3fb;border-bottom:1px solid #d4dfe8;font-size:12px;overflow:auto;white-space:nowrap}.tape b{color:var(--blue)}main{padding:24px}.metrics{display:grid;grid-template-columns:1.25fr 1.25fr 1fr 1.2fr .8fr;margin:4px 0 25px}.metrics>div{padding:0 22px;border-right:1px solid #d1d9df}.metrics>div:first-child{padding-left:2px}.metrics>div:last-child{border:0}label{display:block;font-size:12px;letter-spacing:1.2px;color:#647786}strong{font-weight:400}.metrics strong{display:block;font-size:clamp(20px,2.5vw,36px);margin:10px 0;color:#307d87}.metrics>div:first-child strong{color:#263649}small{font-size:12px;color:#718493}.metrics button{margin-top:0}.primary{display:grid;grid-template-columns:1.05fr 1fr;gap:16px}.panel{border:1px solid #9baebb;box-shadow:inset 0 0 0 2px white;background:#fff;min-width:0}.panel-head{height:48px;padding:0 16px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #cdd7df;background:#f2f7fa;gap:10px}.panel-head h2,h2{font-size:14px;letter-spacing:.5px;margin:0}.panel-head>span{font-size:12px;color:#5a8795}.panel-head em{font-style:normal;color:#71a2ba;margin-right:12px}.vortex-wrap{height:330px;position:relative;overflow:hidden}.overlay{position:absolute;top:20px;left:20px;font-size:12px;color:#607b8c;line-height:1.8;pointer-events:none}.overlay small{font-size:12px;color:#94a3ad}#vortex{width:100%;height:100%}.vortex-bottom{position:absolute;bottom:16px;left:20px;right:20px;display:flex;justify-content:space-between;font-size:12px;color:#6396a0}.network{border-top:1px solid #d2dce4;padding:12px 18px;height:118px}.network>span{font-size:12px}.network svg{width:100%;height:75px}.quote{padding:20px 20px 4px;display:flex;justify-content:space-between;align-items:center;gap:15px}.quote strong{font-size:36px;color:#245d86}.quote span{font-size:12px;color:#69808e;max-width:160px;text-align:right}#candles{width:100%;height:338px;display:block}.chart-foot{display:flex;justify-content:space-between;padding:14px 18px;font-size:12px;border-top:1px solid #e6ebf0;color:#67808e}.secondary{display:grid;grid-template-columns:1fr 1fr 1.15fr;gap:16px;margin:16px 0 26px}.secondary .panel{min-height:230px}.chart-value{display:block;margin:17px 18px 0;font-size:24px;color:#48719d}#curve{width:100%;height:125px;display:block}.order{padding:18px}.order-row{display:flex;gap:8px;margin:12px 0}.order input{width:100%;min-width:60px}.order p{font-size:12px;min-height:32px;margin:8px 0}.events{height:180px;overflow:auto;padding:8px 16px}.events p{font-size:12px;color:#718390}.event{font-size:12px;display:grid;grid-template-columns:60px 1fr auto;gap:10px;padding:9px 0;border-bottom:1px solid #edf1f5}.event small{color:#688396}.section-title{display:flex;justify-content:space-between;margin:0 0 12px;gap:12px}.section-title>span{font-size:12px;color:#7b8c99}.agents{display:grid;grid-template-columns:repeat(6,1fr);gap:12px}.agent{border:1px solid var(--line);border-top:3px solid var(--agent);padding:15px 12px;background:linear-gradient(160deg,white,color-mix(in srgb,var(--agent) 8%,white));color:#31465b;text-align:center;cursor:pointer;min-height:180px}.agent .orb{width:46px;height:46px;display:grid;place-items:center;margin:8px auto 12px;border-radius:50%;background:#172731;color:var(--agent);box-shadow:0 0 0 4px color-mix(in srgb,var(--agent) 20%,transparent);font-size:22px}.agent b{color:var(--agent);display:block;margin-bottom:8px}.agent small{display:block;font-size:12px;line-height:1.5}.agent strong{display:block;font-size:18px;margin-top:15px}.positions{margin-top:24px}.table-scroll{overflow:auto}table{border-collapse:collapse;width:100%;text-align:left;font-size:13px}th{font-size:12px;font-weight:400;color:#758895}td,th{padding:14px 18px;border-bottom:1px solid #edf1f5;white-space:nowrap}footer{padding:22px 0 0;color:#768794;font-size:12px}footer p{max-width:1100px}button,input,select{font:inherit;border:1px solid #b9cbd9;border-radius:0;background:#f5f9fc;color:#315575;padding:9px 12px}button{cursor:pointer}button:hover{background:#e5eef8}button:focus-visible,input:focus-visible,select:focus-visible{outline:2px solid #2658d9;outline-offset:3px}button:disabled{opacity:.5;cursor:not-allowed}#buy,#toggle{background:#2658d9;color:white;border-color:#2658d9;white-space:nowrap}#symbol{border:0;background:transparent;font-weight:bold;padding-left:0}#export{font-size:12px;padding:6px}.positive{color:#14836e!important}.negative{color:#b55068!important}dialog{border:1px solid #93a9bb;padding:32px;max-width:540px;width:90%;color:#2c4256;line-height:1.7}dialog::backdrop{background:#17365155}#dismiss{float:right}dialog h2{font-size:22px}dialog p{font-size:14px}@media(min-width:1600px){main{max-width:1700px;margin:auto}.vortex-wrap{height:400px}#candles{height:408px}}@media(max-width:1050px){.metrics{grid-template-columns:repeat(3,1fr);gap:24px}.metrics>div{padding:0 12px}.agents{grid-template-columns:repeat(3,1fr)}.secondary{grid-template-columns:1fr 1fr}.secondary>.panel:last-child{grid-column:1/3}.primary{grid-template-columns:1fr 1fr}.panel-head>span{font-size:10px}.quote{align-items:start;flex-direction:column}.quote strong{font-size:27px}.quote span{text-align:left}#candles{height:318px}}@media(max-width:700px){header{padding:16px;align-items:start}.brand{gap:8px}.mark{width:42px;height:42px;font-size:34px}h1{font-size:23px}h1 small{display:none}.brand p{font-size:10px;letter-spacing:0}.session{display:flex;flex-direction:column;align-items:end;gap:5px}.session b{font-size:18px}.session>span:last-child{font-size:10px;max-width:125px}.badge{font-size:10px}.tape{padding:12px 16px}main{padding:16px}.metrics{grid-template-columns:1fr 1fr;gap:22px}.metrics>div{padding-left:0}.metrics strong{font-size:25px}.metrics label{font-size:11px}.primary,.secondary{grid-template-columns:1fr}.secondary>.panel:last-child{grid-column:auto}.quote{flex-direction:row}.agents{grid-template-columns:repeat(2,1fr)}.section-title{flex-direction:column}.panel-head>span{font-size:11px}#candles{height:300px}.vortex-wrap{height:300px}.metrics>div:last-child{grid-column:1/3;display:flex;align-items:center;gap:20px}.metrics>div:last-child strong{font-size:20px}.metrics>div:last-child label{display:none}}
/* Reference terminal composition */
:root{font-family:'IBM Plex Mono',monospace;background:#fbfcff;color:#35404b;--line:#aeb7c2}body{background:linear-gradient(115deg,#fcfcff,#faffff 52%,#fffaff)}header{padding:22px 28px;background:#ffffffbd}h1{font-family:'Chakra Petch',sans-serif;font-size:34px;letter-spacing:1px}h1 small{font-family:'IBM Plex Mono',monospace;font-size:14px}.mark{position:relative;font-family:monospace;font-size:53px;background:#2470e9;border:2px solid #80b3e5;box-shadow:inset 0 0 0 4px #3983f3;width:62px;height:62px;line-height:57px}.brand p{font-weight:500;letter-spacing:1.7px;color:#7f8891}.session b{font-family:'Chakra Petch',monospace;letter-spacing:2px}.badge{background:transparent;letter-spacing:1px}.badge:before{content:'● ';color:#398bd1}.tape{background:#f0f4ff88;border-left:4px solid #80c2ce;padding:15px 23px;letter-spacing:.2px}main{padding:28px 22px;max-width:1800px;margin:auto}.metrics{grid-template-columns:1.3fr 1.12fr .94fr .97fr .84fr;gap:0;margin:0 0 27px}.metrics>div{padding:0 24px}.metrics label{font-weight:600;letter-spacing:1.4px}.metrics strong{font-family:'Chakra Petch',monospace;font-size:clamp(27px,2.8vw,43px);letter-spacing:1px;margin:6px 0}.metrics>div:nth-child(2) strong{color:#66a399!important}.metrics>div:nth-child(3) strong{color:#b5a273}.metrics>div:nth-child(4) strong{color:#65a2ac}.metrics>div:nth-child(5) strong{color:#648bb2}.metrics strong i{font-size:.7em;color:#bac1c8;font-style:normal}.metrics button{padding:5px 8px;font-size:12px;float:right}.metrics #engine{font-size:12px;display:inline-block;padding-top:5px}.primary{grid-template-columns:1.08fr .92fr;gap:18px}.panel{border:2px solid #aeb6c0;box-shadow:0 0 0 1px #e2e5e9;background:linear-gradient(130deg,#fff,#fbfcff)}.panel-head{height:52px;background:#f1f5fc88;border-bottom:2px solid #dce0e6;padding:0 17px}.panel-head h2{font-size:15px;font-weight:600;letter-spacing:.35px}.panel-tag{padding:4px 7px;background:#e8f1f544;border:1px solid #e0e8ed;letter-spacing:.4px}.vortex-wrap{height:clamp(365px,31vw,540px)}.overlay{top:24px;left:20px;font-weight:500;color:#8b929a;letter-spacing:.4px}.overlay small{color:#7d8a93}.legend{display:flex;gap:16px;margin-top:12px;font-size:12px}.legend span:first-child{color:#4b88b7}.legend span:nth-child(2){color:#4aa4ad}.legend span:nth-child(3){color:#696b86}.callout{position:absolute;background:#ffffffd9;border:2px solid #c8cdd2;padding:10px 13px;min-width:122px;box-shadow:3px 3px 0 #eff1f5}.callout small{display:block;font-size:12px;letter-spacing:.5px}.callout b{font-family:'Chakra Petch',monospace;display:block;margin-top:3px;font-size:19px;font-weight:500;color:#63818e}.callout-left{left:18px;top:55%;border-left-color:#58b2ba}.callout-right{right:18px;bottom:55px;border-left-color:#c7b77b}.vortex-bottom{font-size:12px;color:#8f98a0;letter-spacing:.5px}.network{height:155px;padding:12px 16px;background:#fbfaff}.network-title{display:flex;justify-content:space-between;font-size:12px;font-weight:500}.network-title small{font-size:12px;color:#8b939c}.network canvas{width:100%;height:110px;display:block}.field-stats{display:grid;grid-template-columns:repeat(4,1fr);border-top:2px solid #dce1e6;background:#f7fafc}.field-stats>div{padding:10px 15px;border-right:1px solid #e3e7ec}.field-stats small{display:block;font-size:12px;letter-spacing:.4px}.field-stats b{display:block;font-family:'Chakra Petch',monospace;font-size:16px;margin-top:4px;color:#68a2a6}.field-stats>div:last-child b{color:#b5a875}.market-panel{display:flex;flex-direction:column}.chart-toolbar{display:flex;justify-content:space-between;align-items:center;padding:10px 16px;border-bottom:1px solid #eff1f5;gap:8px}.chart-switch{display:flex}.chart-switch button{font-size:12px;padding:6px 9px;background:transparent;border-color:#d2dae2}.chart-switch button[aria-pressed=true]{background:#eaf1fa;color:#2c638e;border-color:#9eb9d1}.chart-toolbar a{color:#6689a3;text-decoration:none;font-size:12px}.chart-toolbar a:hover{text-decoration:underline}#native-chart{flex:1;display:flex;flex-direction:column;min-height:0}#native-chart[hidden],#tv-chart[hidden]{display:none!important}.quote{padding:22px 18px 12px;align-items:center;flex-direction:row}.quote strong{font-family:'Chakra Petch',monospace;font-size:clamp(34px,3.2vw,50px);color:#b77e8c;letter-spacing:1px}.quote span{font-size:12px;color:#799ca8}.ohlc{padding:0 19px 14px;color:#8b949c;font-size:12px;word-spacing:6px}#candles{height:clamp(360px,34vw,580px);flex:1;min-height:200px}.chart-foot{font-size:12px;color:#8b9ca8;margin-top:auto;padding:13px 16px}.secondary{grid-template-columns:.9fr 1.5fr 1fr;gap:17px;margin:18px 0 29px}.secondary .panel{height:234px;min-height:0}.chart-value{font-family:'Chakra Petch',monospace;font-size:29px;margin:12px 17px 0;color:#6b8bb4}#curve{height:130px}.trace-description{font-size:12px;color:#91a1ae;padding:0 16px;margin:10px 0}.trace-panel canvas{width:100%;height:132px;display:block}.trace-footer{display:flex;justify-content:space-between;gap:10px;padding:0 15px;font-size:12px;color:#98a4af}.events{height:178px}.section-title h2{letter-spacing:1.3px}.section-title>span{letter-spacing:1px}.agents{gap:12px}.agent{min-height:242px;padding:12px 10px 0;overflow:hidden;position:relative;background:linear-gradient(125deg,#fff,color-mix(in srgb,var(--agent) 10%,white));border-top-width:3px}.agent>small:first-child{text-align:left;font-size:12px;color:#8b969f}.agent .orb{width:57px;height:57px;margin:16px auto 13px;font-size:0;border:5px solid #172527;box-shadow:0 0 0 1px #8b999b,inset 0 0 8px var(--agent);background:repeating-conic-gradient(from 20deg,var(--agent) 0deg 9deg,#1f3b42 12deg 24deg);position:relative}.agent .orb:after{content:attr(data-number);position:absolute;inset:9px;background:#142930;border:2px dotted var(--agent);border-radius:50%;font-size:13px;color:#e8eef1;display:grid;place-items:center}.agent b{font-family:'Chakra Petch',monospace;font-size:19px;font-weight:500;margin-bottom:5px}.agent small{color:#8695a0}.agent strong{font-family:'Chakra Petch',monospace;font-size:25px;margin-top:13px;color:var(--agent)}.agent canvas{height:43px;width:100%;display:block;margin-top:10px}.trading-workspace{display:grid;grid-template-columns:350px 1fr;gap:18px;margin-top:25px}.positions{margin:0}.trading-workspace .panel-head{height:47px}.order p{margin:6px 0}#buy,#toggle{background:#477ba7;border-color:#477ba7}.positive{color:#60a697!important}.negative{color:#b7778e!important}footer{color:#8a98a4}#tv-chart{flex:1;position:relative;min-height:570px}#tv-widget{height:100%;min-height:570px;position:absolute;inset:0}#tv-loading{position:absolute;top:80px;left:20px;right:20px;text-align:center;color:#8294a5;font-size:14px;pointer-events:none}.tradingview-widget-copyright{font-size:12px;text-align:center;padding:5px}.tradingview-widget-copyright a{color:#6283a4}.tv-note{font-size:12px;color:#8a97a3}
@media(min-width:1600px){.vortex-wrap{height:490px}#candles{height:515px}}
@media(max-width:1100px){.metrics>div{padding:0 12px}.metrics label{font-size:11px}.metrics strong{font-size:29px}.metrics small{font-size:11px}.metrics button{float:none;margin-top:5px}.primary{gap:12px}.panel-head{padding:0 12px}.panel-head h2{font-size:14px}.panel-tag{font-size:10px!important}.callout{padding:7px;min-width:100px}.callout small{font-size:10px}.vortex-wrap{height:390px}.network{height:145px}.network canvas{height:100px}.field-stats>div{padding:9px}.field-stats small{font-size:10px}.secondary{grid-template-columns:.9fr 1.4fr 1fr;gap:12px}.secondary>.panel:last-child{grid-column:auto}.secondary .panel-head{padding:0 10px}.secondary h2{font-size:12px}.trace-footer{font-size:10px}.agents{grid-template-columns:repeat(6,1fr);gap:8px}.agent>small:first-child{font-size:10px}.agent small{font-size:10px}.agent strong{font-size:21px}.agent{padding-left:5px;padding-right:5px}.chart-toolbar{align-items:start;flex-direction:column}.events{padding:8px}.event{grid-template-columns:40px 1fr;gap:5px}.event>span:last-child{grid-column:2}.quote strong{font-size:34px}.trading-workspace{grid-template-columns:300px 1fr}}
@media(max-width:760px){main{padding:18px 12px}.metrics{grid-template-columns:repeat(2,1fr);gap:20px}.metrics>div{padding-left:0}.metrics>div:last-child{grid-column:1/3;display:flex;gap:15px;align-items:center}.metrics>div:last-child label{display:block}.metrics>div:last-child strong{font-size:27px}.metrics>div:last-child button{margin:0 0 0 auto}.metrics small{font-size:12px}.primary{grid-template-columns:1fr}.secondary{grid-template-columns:1fr}.secondary>.panel:last-child{grid-column:auto}.secondary h2{font-size:14px}.secondary .panel{height:230px}.agents{grid-template-columns:repeat(3,1fr)}.agent>small:first-child,.agent small{font-size:12px}.agent strong{font-size:23px}.trading-workspace{grid-template-columns:1fr}.chart-toolbar{flex-direction:row;align-items:center}.chart-toolbar a{font-size:11px}.vortex-wrap{height:375px}#candles{height:380px;flex:auto}.panel-tag{font-size:12px!important}.network-title small{font-size:10px}.field-stats small{font-size:12px}.trace-footer{font-size:12px}.event{grid-template-columns:55px 1fr auto}.event>span:last-child{grid-column:auto}.section-title>span{font-size:11px}#tv-chart,#tv-widget{min-height:520px}.ohlc{font-size:11px;word-spacing:2px}.callout-left{left:10px}.callout-right{right:10px}.quote strong{font-size:38px}}
@media(max-width:430px){.agents{grid-template-columns:repeat(2,1fr)}.metrics>div:last-child label{font-size:10px;max-width:55px}.field-stats small{font-size:10px}.trace-footer{font-size:10px}.quote strong{font-size:32px}}

/* ---------------------------------------------------------------------
   ORB additions.
   Appended rather than merged so the original terminal composition above
   stays diffable against the crypto build it came from.
   --------------------------------------------------------------------- */

/* Two banners sit between the tape and the metrics. Both mean "do not read
   the numbers below at face value", so both are full-bleed and unmissable —
   a subtle warning on a real-money dashboard is a warning nobody acts on. */
.banner{padding:14px 28px;font-size:13px;line-height:1.6;border-bottom:1px solid;letter-spacing:.2px}
.banner code{background:#00000010;padding:2px 6px;font-size:12px}
.banner-alert{background:#fdeef1;border-color:#e4b9c4;color:#8c2f46}
.banner-warn{background:#fff6e8;border-color:#e8d2ab;color:#8a5a1c}
.banner-note{background:#eef4fd;border-color:#c3d4ec;color:#31527f}

/* REAL money must not look like the paper badge. */
.badge-live{color:#a8243f;font-weight:600}
.badge-live:before{color:#d33b58}

/* Panel 02: the bot's own view of the selected symbol, in place of the
   candle chart the crypto build drew from Coinbase. There is no equivalent
   free live feed for US equities, and inventing one would be worse than
   showing what the bot actually knows. */
.symbol-detail{padding:4px 20px 20px}
.sd-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:14px 0 18px}
.sd-grid small{display:block;letter-spacing:1px;margin-bottom:6px}
.sd-grid b{font-family:'Chakra Petch',monospace;font-size:22px;font-weight:500;color:#48719d}
.sd-reason{font-size:12px;line-height:1.7;color:#5d6e7d;border-left:3px solid #d8e2ea;padding-left:12px;margin:0 0 14px}
.sd-reason small{letter-spacing:.8px;color:#8494a1}
.sd-trades div{display:grid;grid-template-columns:70px 1fr auto;gap:10px;font-size:12px;padding:7px 0;border-bottom:1px solid #eef2f6}
.sd-trades span:first-child{color:#8494a1}

/* Position states. ORPHAN is the one that costs money, so it colours the
   whole row rather than sitting quietly in a status column. */
.state-ok{color:#14836e;letter-spacing:.5px}
.state-bad{color:#b0344f;font-weight:600;letter-spacing:.5px}
.row-bad{background:#fdf3f5}
.row-bad td{border-bottom-color:#f0dbe1}
.nostop{color:#9aa6b1;font-style:italic}

/* Panel 07: state and the commands that change it. Read-only on purpose —
   see the note in app.js. */
.control{padding:18px;display:grid;gap:20px}
.control label{font-weight:600;letter-spacing:1.3px;margin-bottom:8px}
.control strong{font-family:'Chakra Petch',monospace;font-size:26px;letter-spacing:1px;display:block}
.control small{display:block;margin-top:7px;line-height:1.6}
.control a{display:inline-block;margin-top:10px;font-size:12px;color:#2470e9}
.control-cmds code{display:block;background:#f3f6fa;border:1px solid #e1e8ef;padding:8px 10px;
  font-size:12px;margin-bottom:6px;overflow-x:auto;white-space:nowrap;color:#3d5468}

/* The six are placeholders until the ORB strategy is split into agents.
   Greyed so nobody reads them as live. */
.agent-idle{opacity:.55;filter:saturate(.45)}
.agent-idle:hover{opacity:.8;filter:saturate(.7)}
#agents-note{color:#9aa6b1}

#network{width:100%;height:78px;display:block}
.ohlc.negative{font-weight:600}

@media(max-width:1050px){
  .control{grid-template-columns:1fr 1fr}
  .control-cmds{grid-column:1/3}
  .sd-grid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:700px){
  .banner{padding:12px 16px;font-size:12px}
  .control{grid-template-columns:1fr}
  .control-cmds{grid-column:auto}
}

/* The conversion canvas had no height of its own, so it took the crypto
   build's and pushed its own footer out of the panel. */
#trace{width:100%;height:118px;display:block}
.trace-panel{display:flex;flex-direction:column}
.trace-panel .trace-footer{margin-top:auto;padding-bottom:14px}
.trace-description{margin:14px 15px 4px;font-size:12px;letter-spacing:.6px;color:#7c8b98}
.events{height:196px}

/* A grid item's default min-width is auto, which is the content's intrinsic
   width — so the eight-column positions table widened its track and pushed
   the whole page into a horizontal scroll on a phone, instead of scrolling
   inside its own .table-scroll box. */
.trading-workspace>*,.primary>*,.secondary>*{min-width:0}
.table-scroll{max-width:100%}
/* NOT min-width:0 on the tape's spans. With white-space:nowrap they then
   shrink below their own text and the right-hand label prints straight
   through the ticker — "SHOP MOOMOO US FUTU" on top of each other. The tape
   scrolls instead; the header's status line was the actual mobile overflow
   and is fixed separately. */
.tape>span:last-child{flex:0 0 auto}
.tape>#ticker{flex:1 1 auto}

/* Metric tiles are grid items too, and a long value like $2,100.04 at 25px
   set their automatic minimum wider than the 1fr track, pushing the page a
   few pixels past the viewport on a phone. */
.metrics>div{min-width:0}
/* Only the sub-labels may break anywhere. Letting a currency figure wrap
   turns $2,090.60 into "$2,090.6" over "0", which reads as a different
   number. */
.metrics small{overflow-wrap:anywhere}
.metrics strong{overflow-wrap:normal}
@media(max-width:700px){
  .metrics>div{padding-right:14px}
  .metrics>div:nth-child(2n){padding-right:0}
}

/* The header's status line is capped at 125px on a phone; anything longer
   than that used to spill past the viewport rather than wrap. */
.session>span:last-child{overflow-wrap:anywhere}

@media(max-width:430px){
  .metrics strong{font-size:21px}
  .metrics>div:last-child strong{font-size:19px}
}

/* Inside a Telegram Mini App. Set by initTelegram(); absent everywhere else,
   so none of this affects the page in a normal browser. */
html[data-tg="1"] body{background:var(--tg-bg,#fbfcff)}
html[data-tg="1"] header{padding-top:34px}
html[data-tg="1"] .brand p{display:none}
html[data-tg="1"] footer{padding-bottom:40px}

/* Action buttons. Only drawn when /api/status says the viewer is authorised
   for them, so their presence is already proof of authentication. */
.control-actions #actions{display:grid;gap:8px}
.control-actions button{width:100%;text-align:center}
.btn-stop{background:#8a5a1c;color:#fff;border-color:#8a5a1c}
.btn-go{background:#14836e;color:#fff;border-color:#14836e}
.btn-danger{background:#b0344f;color:#fff;border-color:#b0344f}
.btn-stop:hover{background:#a06a26}
.btn-go:hover{background:#199a82}
.btn-danger:hover{background:#c73f5c}
.btn-small{padding:4px 9px;font-size:12px;width:auto!important}
.control-note{font-size:12px;line-height:1.6;color:#7c8b98;margin:4px 0 0}
.control-note.pending{color:#8a5a1c}
.action-note{font-size:12px;line-height:1.6;margin:10px 0 0;min-height:18px}
td .btn-small{white-space:nowrap}

/* The quick action bar. Sticks to the bottom of the viewport on a phone,
   because the full Control panel is a long scroll away and a kill switch you
   have to hunt for is not one. */
.quickbar{position:sticky;bottom:0;z-index:20;display:flex;gap:10px;flex-wrap:wrap;
  padding:12px 28px;background:#ffffffee;border-top:1px solid #cdd7df;
  backdrop-filter:blur(6px)}
.quickbar button{flex:1 1 200px}
@media(max-width:700px){
  .quickbar{padding:10px 14px;gap:8px}
  .quickbar button{flex:1 1 100%;padding:12px}
}

/* Positions as cards on a phone.
   As a table it scrolls sideways, and the Close button is the last of nine
   columns — 500px past the right edge on a 390px screen. Present, and
   unreachable on the one device the Mini App actually runs on. */
@media(max-width:760px){
  .positions .table-scroll{overflow:visible}
  .positions table{min-width:0;display:block}
  .positions thead{display:none}
  .positions tbody{display:block}
  .positions tr{
    display:block;border:1px solid var(--line);border-left:3px solid #c3ccd4;
    padding:12px 14px;margin-bottom:10px;background:#fff;
  }
  .positions tr.row-bad{border-left-color:#b0344f;background:#fdf3f5}
  .positions td{
    display:flex;justify-content:space-between;align-items:baseline;gap:14px;
    border:0;padding:5px 0;white-space:normal;text-align:right;
  }
  .positions td:before{
    content:attr(data-label);
    font-size:10.5px;letter-spacing:1.1px;color:#8494a1;
    text-align:left;flex:0 0 auto;
  }
  .positions td:empty{display:none}
  /* The symbol is the card's heading, not another label/value pair. */
  .positions .cell-symbol{
    justify-content:flex-start;padding:0 0 8px;margin-bottom:6px;
    border-bottom:1px solid #edf1f5;text-align:left;
  }
  .positions .cell-symbol:before{display:none}
  .positions .cell-symbol b{font-family:'Chakra Petch',monospace;font-size:19px}
  .positions .cell-action{display:block;padding:12px 0 2px}
  .positions .cell-action:before{display:none}
  .positions .cell-action button{width:100%!important;padding:11px}
  .positions td[data-label="STATE"]{flex-wrap:wrap}
  .positions td[data-label="STATE"] small{flex-basis:100%;text-align:right}
}

/* Panel 08 — research memos. Reading material, styled as such: a document,
   not another readout. */
.research-panel{margin-top:18px}
.research{padding:8px 18px 18px;max-height:420px;overflow-y:auto}
.research-empty{font-size:13px;color:#7c8b98;margin:12px 0}
.memo{border-bottom:1px solid #edf1f5;padding:10px 0}
.memo:last-child{border-bottom:0}
.memo summary{cursor:pointer;display:flex;justify-content:space-between;gap:14px;
  align-items:baseline;list-style:none;padding:4px 0}
.memo summary::-webkit-details-marker{display:none}
.memo summary:before{content:'▸';color:#9aa6b1;margin-right:8px;font-size:11px}
.memo[open] summary:before{content:'▾'}
.memo summary b{font-family:'Chakra Petch',monospace;font-size:16px;color:#2470e9}
.memo summary span{font-size:12px;color:#8494a1}
.memo-body{margin:8px 0 6px;padding:12px 14px;background:#f7f9fc;
  border-left:3px solid #d8e2ea;font-family:'IBM Plex Mono',monospace;font-size:12px;
  line-height:1.75;white-space:pre-wrap;word-break:break-word;color:#41505d;
  max-height:260px;overflow-y:auto}
.memo-file{display:block;font-size:11px;color:#9aa6b1;letter-spacing:.4px}

/* The tape, with live prices. Each entry is one unbreakable unit so a symbol
   never wraps away from its own price. */
#ticker{display:inline-flex;gap:26px;align-items:baseline}
.tick{white-space:nowrap}
.tick b{color:#41505d;font-weight:600;margin-right:5px}
.tick i{font-style:normal;font-size:11px}
.tick i.up{color:#14836e}
.tick i.down{color:#b0344f}

/* The tick flash. A brief wash of colour behind a price that just moved, so a
 * glance at the tape tells you the page is live without having to watch a
 * digit and wait. Short and low-contrast on purpose: this fires every thirty
 * seconds on up to thirteen symbols, and anything louder would be a page you
 * stop looking at. */
@keyframes tick-flash-up{from{background:#14836e33}to{background:transparent}}
@keyframes tick-flash-down{from{background:#b0344f33}to{background:transparent}}
.tick.flash-up{animation:tick-flash-up 1.4s ease-out;border-radius:3px}
.tick.flash-down{animation:tick-flash-down 1.4s ease-out;border-radius:3px}

/* Motion is decoration here — the price and its sign carry the same
 * information without it, so a reader who has asked for less of it loses
 * nothing. */
@media (prefers-reduced-motion: reduce){
  .tick.flash-up,.tick.flash-down{animation:none}
}
#priceinfo b{font-size:13px;letter-spacing:.4px}

/* When dashboard/logo.png exists it replaces the glyph. Cropped to fill the
   same square the ✳ occupied, so the header geometry does not move. */
.mark img{width:100%;height:100%;object-fit:cover;display:block}
.mark:has(img){background:transparent;border:2px solid #80b3e5;box-shadow:none;
  line-height:0;overflow:hidden}

/* The kill switch's own button. Sits under the state in the Control panel,
   so the thing you reach for in a hurry is where the state you reacted to
   is — not two panels further down. Empty and invisible when the session is
   not authorised to use it. */
#kill-action:empty{display:none}
#kill-action{margin-top:8px}
#kill-action button{width:100%}

/* --- Backtest panel ---------------------------------------------------- */
.backtest{display:flex;flex-direction:column;gap:10px;padding:14px 16px}
.bt-row{
  display:grid;
  grid-template-columns:96px 1fr 1fr 110px;
  grid-template-areas:"h live best delta" "mix mix mix mix" "cav cav cav cav";
  gap:10px 14px;align-items:center;
  padding:12px 14px;border:1px solid #e6ebf0;border-radius:6px;background:#fbfcfd;
}
/* A row the data cannot support is drawn as such, not just labelled: someone
   skimming reads the shape before they read the words. */
.bt-row.bt-weak{border-style:dashed;opacity:0.72}
.bt-horizon{grid-area:h}
.bt-horizon strong{display:block;font-size:19px;color:#11181f}
.bt-horizon small,.bt-compare small{display:block;font-size:11px;color:#5b6b7a;margin-top:2px}
.bt-live{grid-area:live}
.bt-best{grid-area:best}
.bt-compare label{display:block;font-size:10px;letter-spacing:.08em;color:#5b6b7a}
.bt-compare strong{font-size:16px;color:#11181f}
.bt-delta{grid-area:delta;text-align:right;font-size:17px;font-weight:600}
.bt-delta small{display:block;font-size:10px;font-weight:400;color:#5b6b7a}
.bt-exits{grid-area:mix;font-size:11px;color:#5b6b7a;border-top:1px solid #eef2f5;padding-top:8px}
/* Its own row, not `grid-row:3` on the exits area — that collided with the
   delta the moment the phone layout added a row above it. */
.bt-caveat{grid-area:cav;font-size:11px;font-weight:600;color:#b0344f;letter-spacing:.04em}
.bt-note{font-size:11px;line-height:1.55;color:#5b6b7a;margin:4px 2px 0}

/* Phone: the four-column comparison stops being a comparison below ~620px,
   so it stacks rather than compressing into unreadable columns. */
@media (max-width:620px){
  .bt-row{
    grid-template-columns:1fr 1fr;
    grid-template-areas:"h h" "live best" "delta delta" "mix mix" "cav cav";
  }
  .bt-delta{text-align:left}
}
