/* =============================================================================
   WICK — LEDGER DESIGN SYSTEM
   design-system-v2.css · v2.0 · dark theme only (MVP)
   =============================================================================

   WHO THIS FILE IS FOR
   This stylesheet is the single source of truth for Wick's UI. An agent
   building or updating a page should write HTML against the class contracts
   documented here and should NOT write new CSS. If a page needs something this
   file cannot express, the correct move is to add a component to this file —
   not to add a <style> block or inline styles to the page.

   RULES FOR THE AGENT
   1. Never hard-code a colour, font family, or radius. Use the custom
      properties in LAYER 1. If a value you need is missing, add a token.
   2. Never invent class names. Every class you may use is documented below
      with the markup it expects.
   3. Inline styles are permitted for exactly one thing: a dynamic width or
      value on a progress element (`.meter span`, `.bar span`), because those
      are data, not design.
   4. Every interactive control must be a <button> or <a>. Never a clickable
      <div>. Toggles use role="switch" + aria-checked. Filters use aria-pressed.
   5. The page must work with JavaScript disabled, apart from the modal and the
      ticker. Motion is decoration, never the only signal.
   6. Respect the markup contracts marked "REQUIRED" — the motion layer and the
      accessibility behaviour depend on them.

   LOAD ORDER
     <link rel="preconnect" href="https://fonts.googleapis.com">
     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
     <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter+Tight:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
     <link rel="stylesheet" href="/css/design-system-v2.css">
   Then GSAP + the motion script at the end of <body>.

   CONTENTS
     LAYER 1  Tokens
     LAYER 2  Base & reset
     LAYER 3  Layout primitives
     LAYER 4  Components
     LAYER 5  Utilities
     LAYER 6  Motion contract & accessibility
   ========================================================================== */


/* =============================================================================
   LAYER 1 — TOKENS
   ========================================================================== */

:root{
  /* --- Surface. Four steps, warm-shifted. Never introduce a fifth. --------- */
  --canvas:#12110F;        /* page background */
  --panel:#1A1815;         /* cards, rails, ticker, modal */
  --panel-2:#221F1B;       /* inset: tracks, active nav, hover fills */
  --rule:#2C2823;          /* hairline borders — the main structural device */
  --rule-2:#3B352E;        /* emphasised border: dashed empty states, hovers */

  /* --- Ink ---------------------------------------------------------------- */
  --text:#EAE4D9;          /* primary */
  --muted:#8A8377;         /* secondary copy, labels */
  --faint:#5C5750;         /* metadata, axis labels, disabled */

  /* --- Semantic. Domain colours: win/loss are meaning, not decoration. ----- */
  --win:#A9BC6C;
  --loss:#D4694F;
  --mark:#E3C77A;          /* brass. The one bright colour. Use sparingly:
                              focus rings, "today", the plan meter, the curve
                              endpoint. If brass appears more than ~3 times on
                              a screen, it has stopped meaning anything. */

  /* --- Type --------------------------------------------------------------- */
  --f-display:"Instrument Serif",Georgia,"Times New Roman",serif;
  --f-ui:"Inter Tight",system-ui,-apple-system,"Segoe UI",sans-serif;
  --f-num:"JetBrains Mono",ui-monospace,"SFMono-Regular",monospace;

  /* Display sizes are fluid; UI sizes are fixed. */
  --t-figure:clamp(56px,12vw,104px);   /* the one hero number per page */
  --t-h1:clamp(28px,5vw,40px);         /* page title */
  --t-h2:21px;                         /* section heading */
  --t-h3:19px;                         /* card heading */
  --t-body:15px;
  --t-sm:13.5px;
  --t-xs:12.5px;
  --t-2xs:11.5px;

  /* --- Space. 4px base. Use these, not arbitrary pixels. ------------------- */
  --s-1:4px;  --s-2:8px;  --s-3:12px; --s-4:16px;
  --s-5:20px; --s-6:24px; --s-8:32px; --s-10:40px; --s-12:48px;

  /* --- Shape. One radius for everything square-ish. ------------------------ */
  --r:3px;
  --r-pill:100px;
  --r-sheet:14px;          /* mobile bottom-sheet only */

  /* --- Layout ------------------------------------------------------------- */
  --shell:264px;           /* left rail width */
  --pad-x:20px;            /* page gutter, small screens */
  --pad-x-lg:40px;         /* page gutter, >=1024px */
  --bp-rail:1024px;        /* rail replaces bottom nav at this width */

  /* --- Depth -------------------------------------------------------------- */
  --z-sticky:20;
  --z-nav:40;
  --z-modal:50;

  /* --- Motion. Short, and only in response to an action or on first load. -- */
  --e-out:cubic-bezier(.22,1,.36,1);
  --d-fast:.15s;
  --d-base:.28s;
}


/* =============================================================================
   LAYER 2 — BASE & RESET
   ========================================================================== */

*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
html{-webkit-text-size-adjust:100%}

body{
  background:var(--canvas);
  color:var(--text);
  font-family:var(--f-ui);
  font-size:var(--t-body);
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
img,svg,video{max-width:100%}
h1,h2,h3,h4,p,dl,dd,figure{margin:0}
ul,ol{margin:0;padding:0;list-style:none}

/* Focus is brass and always visible. Never remove this. */
:focus-visible{outline:2px solid var(--mark);outline-offset:2px;border-radius:2px}

::selection{background:var(--mark);color:var(--canvas)}


/* =============================================================================
   LAYER 3 — LAYOUT PRIMITIVES
   =============================================================================

   PAGE SKELETON — every page uses exactly this shape:

     <div class="app">
       <aside class="rail"> … </aside>          REQUIRED, desktop only
       <main class="main">
         <div class="top"> … </div>             REQUIRED, one per page
         <section class="ledger"> … </section>  optional hero
         <div class="ticker"> … </div>          optional
         <dl class="stats"> … </dl>             optional
         <div class="grid">
           <section class="panel"> … </section> repeat as needed
         </div>
       </main>
     </div>
     <nav class="bottom"> … </nav>              REQUIRED, mobile only
   ========================================================================== */

.app{display:grid;grid-template-columns:1fr;min-height:100vh}
@media(min-width:1024px){ .app{grid-template-columns:var(--shell) 1fr} }

/* `.main` reserves room for the fixed bottom nav on small screens. */
.main{min-width:0;padding-bottom:96px}
@media(min-width:1024px){ .main{padding-bottom:var(--s-10)} }

/* `.grid` is the page gutter. Anything full-bleed (hero, ticker, stats) sits
   OUTSIDE it and applies its own padding. */
.grid{padding:0 var(--pad-x)}
@media(min-width:1024px){ .grid{padding:0 var(--pad-x-lg)} }

/* A `.panel` is a horizontal band inside `.grid`, separated by a hairline.
   It is not a box — it has no border or background of its own.
     <section class="panel">
       <div class="panel-head"><h2>…</h2> …optional action… </div>
       …content…
     </section> */
.panel{border-bottom:1px solid var(--rule);padding:var(--s-8) 0}
.panel:last-child{border-bottom:0}
.panel-head{display:flex;align-items:center;justify-content:space-between;
            gap:var(--s-3);margin-bottom:var(--s-5)}
.panel-head h2{font-family:var(--f-display);font-size:var(--t-h2);font-weight:400;
               letter-spacing:-.01em}

/* `.cols` splits a panel into columns. Single column below 900px, always.
   Add `.wide` for an asymmetric 1.8fr / 1fr split (chart + companion). */
.cols{display:grid;gap:var(--s-4);grid-template-columns:1fr}
@media(min-width:900px){
  .cols{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cols.wide{grid-template-columns:minmax(0,1.8fr) minmax(0,1fr)}
  .cols.thirds{grid-template-columns:repeat(3,minmax(0,1fr))}
}


/* =============================================================================
   LAYER 4 — COMPONENTS
   ========================================================================== */

/* -----------------------------------------------------------------------------
   4.1 LEFT RAIL — desktop navigation
   -----------------------------------------------------------------------------
   <aside class="rail">
     <div>
       <div class="brand">Wick<em>.</em></div>
       <div class="brand-sub">Ledger — September 2026</div>
     </div>
     <nav class="nav" aria-label="Main">
       <a href="/" aria-current="page"><span class="dot"></span>Overview</a>
       <a href="/trades"><span class="dot"></span>Trades<span class="nav-count">248</span></a>
     </nav>
     <div class="rail-account"> … </div>
     <div class="rail-foot"> … </div>
   </aside>

   REQUIRED: the active link carries aria-current="page" — that attribute, not a
   class, is what styles it. Every link needs its <span class="dot">.
-------------------------------------------------------------------------- */
.rail{display:none}
@media(min-width:1024px){
  .rail{display:flex;flex-direction:column;border-right:1px solid var(--rule);
        padding:var(--s-8) 22px;position:sticky;top:0;height:100vh}
}
.brand{font-family:var(--f-display);font-size:30px;line-height:1;letter-spacing:-.02em}
.brand em{color:var(--mark);font-style:normal}
.brand-sub{color:var(--faint);font-size:12px;margin-top:var(--s-2)}

.nav{margin-top:38px;display:flex;flex-direction:column;gap:2px}
.nav a{display:flex;align-items:center;gap:11px;padding:9px 10px;margin-left:-10px;
       border-radius:var(--r);color:var(--muted);font-size:14.5px;
       transition:color var(--d-fast),background var(--d-fast)}
.nav a:hover{color:var(--text);background:var(--panel)}
.nav a[aria-current]{color:var(--text);background:var(--panel-2)}
.nav a[aria-current] .dot{background:var(--mark)}
.dot{width:5px;height:5px;border-radius:50%;background:var(--faint);flex:none}
.nav-count{margin-left:auto;font-size:12px;color:var(--faint);font-family:var(--f-num)}

/* Account line. Deliberately small — it is identification, not navigation.
   <div class="rail-account">
     <div class="avatar">RJ</div>
     <div>Rai J.<small>Futures — NQ, ES</small></div>
   </div>
   `margin-top:auto` pins this and everything after it to the bottom. */
.rail-account{margin-top:auto;display:flex;align-items:center;gap:10px;
              padding-top:var(--s-5);border-top:1px solid var(--rule)}
.rail-account > div{font-size:var(--t-sm);min-width:0}
.rail-account small{display:block;color:var(--faint);font-size:var(--t-2xs)}
.avatar{width:28px;height:28px;border-radius:50%;background:var(--panel-2);
        border:1px solid var(--rule);display:grid;place-items:center;
        font-size:var(--t-2xs);color:var(--muted);flex:none}

/* Promo slot. One per page, bottom of the rail. Plan limits, upgrades,
   onboarding nudges. Keep the label to one short sentence.
   <div class="rail-foot">
     <div class="lbl"><b>248</b> of <b>500</b> trades logged on the free plan</div>
     <div class="meter"><span style="width:49.6%"></span></div>
     <a href="/upgrade" class="cta">Go unlimited</a>
   </div> */
.rail-foot{margin-top:var(--s-3);background:var(--panel);border:1px solid var(--rule);
           border-radius:var(--r);padding:15px}
.rail-foot .lbl{color:var(--muted);font-size:var(--t-xs);line-height:1.35}
.rail-foot .lbl b{color:var(--text);font-weight:500;font-family:var(--f-num);font-size:var(--t-xs)}
.rail-foot .cta{display:inline-flex;align-items:center;gap:6px;color:var(--mark);
                font-size:13px;font-weight:500}
.rail-foot .cta:hover{text-decoration:underline;text-underline-offset:3px}


/* -----------------------------------------------------------------------------
   4.2 METER — a proportion of a known limit
   -----------------------------------------------------------------------------
   <div class="meter"><span style="width:49.6%"></span></div>
   Width is the only permitted inline style. Olive → brass, so it warms as it
   fills. For a value with no ceiling, use `.bar` instead.
-------------------------------------------------------------------------- */
.meter{height:5px;border-radius:var(--r-pill);background:var(--panel-2);
       margin:11px 0 10px;overflow:hidden}
.meter span{display:block;height:100%;border-radius:var(--r-pill);
            background:linear-gradient(90deg,var(--win),var(--mark))}


/* -----------------------------------------------------------------------------
   4.3 BOTTOM NAV — mobile navigation
   -----------------------------------------------------------------------------
   Exactly five items. They must mirror the first five rail items.
   Lives at the end of <body>, outside `.app`.
   <nav class="bottom" aria-label="Main">
     <a href="/" aria-current="page"><svg …/>Overview</a> …
   </nav>
-------------------------------------------------------------------------- */
.bottom{position:fixed;left:0;right:0;bottom:0;z-index:var(--z-nav);
        background:color-mix(in srgb,var(--canvas) 92%,transparent);
        backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
        border-top:1px solid var(--rule);
        display:grid;grid-template-columns:repeat(5,1fr);
        padding-bottom:env(safe-area-inset-bottom)}
@media(min-width:1024px){ .bottom{display:none} }
.bottom a{display:flex;flex-direction:column;align-items:center;gap:5px;
          padding:11px 0 10px;color:var(--faint);font-size:11px}
.bottom a[aria-current]{color:var(--text)}
.bottom a[aria-current] svg{color:var(--mark)}
.bottom svg{width:20px;height:20px}


/* -----------------------------------------------------------------------------
   4.4 TOP BAR
   -----------------------------------------------------------------------------
   <div class="top">
     <div><h1>Overview</h1><div class="top-meta">1 Sep – 18 Sep · 41 trades</div></div>
     <div class="top-actions"> …buttons… </div>
   </div>
   One <h1> per page. `.top-meta` is scope and count, not marketing.
-------------------------------------------------------------------------- */
.top{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--s-4);
     padding:var(--s-6) var(--pad-x) var(--s-5);border-bottom:1px solid var(--rule)}
@media(min-width:1024px){ .top{padding:34px var(--pad-x-lg) 22px} }
.top h1{font-family:var(--f-display);font-size:var(--t-h1);line-height:1;
        letter-spacing:-.015em;font-weight:400}
.top-meta{color:var(--faint);font-size:var(--t-xs);margin-top:7px}
.top-actions{display:flex;gap:var(--s-2);align-items:center}


/* -----------------------------------------------------------------------------
   4.5 BUTTONS
   -----------------------------------------------------------------------------
   <button class="btn btn-primary">Log a trade</button>
   One primary per screen region. Secondary for alternatives, ghost for
   low-stakes navigation, icon for toolbars. Labels name what happens
   ("Save trade"), never "Submit". Never append an arrow to the label.
-------------------------------------------------------------------------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
     height:36px;padding:0 15px;border-radius:var(--r);font-size:14px;
     font-weight:500;white-space:nowrap;transition:var(--d-fast)}
.btn svg{width:15px;height:15px;flex:none}
.btn-primary{background:var(--text);color:var(--canvas)}
.btn-primary:hover{background:#fff}
.btn-secondary{border:1px solid var(--rule);color:var(--text)}
.btn-secondary:hover{border-color:var(--muted)}
.btn-ghost{color:var(--muted)}
.btn-ghost:hover{color:var(--text)}
.btn-danger{border:1px solid color-mix(in srgb,var(--loss) 45%,transparent);color:var(--loss)}
.btn-danger:hover{background:color-mix(in srgb,var(--loss) 12%,transparent)}
.btn-icon{width:36px;padding:0;border:1px solid var(--rule)}
.btn-sm{height:30px;padding:0 11px;font-size:13px}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.42;pointer-events:none}


/* -----------------------------------------------------------------------------
   4.6 CHIPS — mutually exclusive filters
   -----------------------------------------------------------------------------
   <div class="chips">
     <button class="chip" aria-pressed="true">Everything</button>
     <button class="chip" aria-pressed="false">Wins</button>
   </div>
   REQUIRED: every chip carries aria-pressed. Exactly one is "true". The row
   scrolls horizontally on small screens — never wrap it.
-------------------------------------------------------------------------- */
.chips{display:flex;gap:7px;overflow-x:auto;scrollbar-width:none;padding-bottom:2px}
.chips::-webkit-scrollbar{display:none}
.chip{border:1px solid var(--rule);border-radius:var(--r-pill);padding:5px 13px;
      font-size:13px;color:var(--muted);white-space:nowrap;transition:var(--d-fast)}
.chip:hover{color:var(--text)}
.chip[aria-pressed="true"]{background:var(--text);color:var(--canvas);border-color:var(--text)}


/* -----------------------------------------------------------------------------
   4.7 TAGS — non-interactive labels
   -----------------------------------------------------------------------------
   <span class="tag tag-long">Long</span>
   <span class="tag">Opening range break</span>   ← neutral / setup name
   Direction only. Do not use a tag to show a result — the number carries that.
-------------------------------------------------------------------------- */
.tag{display:inline-block;border:1px solid var(--rule);border-radius:2px;
     padding:2px 7px;font-size:var(--t-2xs);color:var(--muted);line-height:1.5}
.tag-long{color:var(--win);border-color:color-mix(in srgb,var(--win) 35%,transparent)}
.tag-short{color:var(--loss);border-color:color-mix(in srgb,var(--loss) 35%,transparent)}
.tag-mark{color:var(--mark);border-color:color-mix(in srgb,var(--mark) 35%,transparent)}


/* -----------------------------------------------------------------------------
   4.8 HERO FIGURE — one per page, maximum
   -----------------------------------------------------------------------------
   The single most important number on the screen, set large in the serif.
   If a page has no number worth 104px, it has no hero — use `.top` alone.

   <section class="ledger">
     <div>
       <div class="figure-label">Net profit and loss</div>
       <div class="figure win"><span class="cur">$</span><span class="num" data-count="18420">0</span></div>
       <p class="figure-note">Up <b>12.4%</b> on the month. …</p>
     </div>
     <div class="donut"> … </div>        ← optional companion
   </section>
-------------------------------------------------------------------------- */
.ledger{padding:34px var(--pad-x) var(--s-8)}
@media(min-width:1024px){
  .ledger{padding:44px var(--pad-x-lg) var(--s-10);display:grid;
          grid-template-columns:minmax(0,1fr) 260px;gap:52px;align-items:center}
}
.figure-label{color:var(--muted);font-size:13px;margin-bottom:6px}
.figure{font-family:var(--f-display);font-size:var(--t-figure);line-height:.88;
        letter-spacing:-.035em;display:flex;align-items:baseline;gap:var(--s-1)}
.figure .cur{font-size:.42em;color:var(--muted);align-self:flex-start;margin-top:.25em}
.figure-note{color:var(--muted);font-size:var(--t-sm);margin-top:var(--s-4);max-width:46ch}
.figure-note b{color:var(--text);font-weight:500}


/* -----------------------------------------------------------------------------
   4.9 DONUT — one ratio out of a whole
   -----------------------------------------------------------------------------
   Win rate, plan adherence, setup share. Never for a trend.

   <div class="donut">
     <svg viewBox="0 0 120 120" role="img" aria-label="Win rate 61.4 percent, 25 wins and 16 losses">
       <circle cx="60" cy="60" r="51" fill="none" stroke="#221F1B" stroke-width="10"/>
       <circle class="js-ring" cx="60" cy="60" r="51" fill="none" stroke="#A9BC6C"
               stroke-width="10" stroke-linecap="butt" transform="rotate(-90 60 60)"
               stroke-dasharray="320.44" stroke-dashoffset="123.7"/>
     </svg>
     <div class="mid"><b>61.4%</b><small>25 wins / 16 losses</small></div>
   </div>

   Maths: circumference = 2πr = 320.44 for r=51.
          stroke-dashoffset = 320.44 × (1 − fraction).
   REQUIRED: aria-label states the value in words; the <svg> text is decorative.
   stroke-linecap MUST stay `butt` — a round cap reads as a progress pill.
-------------------------------------------------------------------------- */
.donut{display:grid;place-items:center;position:relative}
@media(max-width:1023px){ .donut{margin-top:var(--s-8)} }
.donut svg{width:min(220px,56vw);height:auto;display:block}
.donut .mid{position:absolute;text-align:center;line-height:1}
.donut .mid b{display:block;font-family:var(--f-display);font-size:38px;
              font-weight:400;letter-spacing:-.03em}
.donut .mid small{display:block;color:var(--muted);font-size:var(--t-xs);margin-top:7px}


/* -----------------------------------------------------------------------------
   4.10 TICKER — live, low-stakes, glanceable
   -----------------------------------------------------------------------------
   Open positions only. Never put anything here that needs to be read carefully
   or acted on — it moves, so it cannot be a primary surface.
   Duplicate the item list exactly twice; the motion layer translates -50%.

   <div class="ticker" aria-label="Open positions">
     <div class="ticker-track js-ticker">
       <span><b>NQ</b>long 2<span class="win">+$412</span></span>
       … repeat the full set a second time …
     </div>
   </div>
-------------------------------------------------------------------------- */
.ticker{overflow:hidden;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);
        background:var(--panel);padding:11px 0}
.ticker-track{display:flex;gap:34px;width:max-content;font-family:var(--f-num);
              font-size:var(--t-xs);color:var(--faint);white-space:nowrap}
.ticker-track > span{display:inline-flex;align-items:center;gap:var(--s-2)}
.ticker-track b{color:var(--text);font-weight:500;font-family:var(--f-display);
                font-size:15px;letter-spacing:-.01em}


/* -----------------------------------------------------------------------------
   4.11 STATS — the supporting four
   -----------------------------------------------------------------------------
   Full-bleed band of 2 (mobile) / 4 (desktop). Four items, always — the
   dividing rules assume it. Sits outside `.grid`.

   <dl class="stats">
     <div class="stat"><dt>Win rate</dt><dd class="num">61.4%</dd>
       <div class="delta">25 wins · 16 losses</div></div>
     … ×4 …
   </dl>
-------------------------------------------------------------------------- */
.stats{display:grid;grid-template-columns:repeat(2,1fr)}
@media(min-width:900px){ .stats{grid-template-columns:repeat(4,1fr)} }
.stat{padding:var(--s-5);border-bottom:1px solid var(--rule);border-right:1px solid var(--rule)}
@media(min-width:1024px){ .stat{padding:22px var(--pad-x-lg)} }
.stat:nth-child(2n){border-right:0}
@media(min-width:900px){
  .stat{border-right:1px solid var(--rule)}
  .stat:last-child{border-right:0}
}
.stat dt{color:var(--muted);font-size:13px;margin-bottom:9px}
.stat dd{font-size:27px;line-height:1}
.stat .delta{font-size:var(--t-xs);margin-top:9px;color:var(--faint)}


/* -----------------------------------------------------------------------------
   4.12 CARD — a box inside a column
   -----------------------------------------------------------------------------
   Use a card ONLY inside `.cols`. A card that is alone in a panel is a box for
   no reason — drop it and let the panel hold the content directly.

   <div class="card">
     <h3>Where the money came from</h3>
     <p class="sub">Total R by setup, this month</p>
     …content…
   </div>
-------------------------------------------------------------------------- */
.card{background:var(--panel);border:1px solid var(--rule);border-radius:var(--r);
      padding:var(--s-5)}
.card > h3{font-family:var(--f-display);font-size:var(--t-h3);font-weight:400;
           margin-bottom:var(--s-1);letter-spacing:-.01em}
.card > .sub{color:var(--faint);font-size:var(--t-xs);margin-bottom:var(--s-4)}


/* -----------------------------------------------------------------------------
   4.13 CHART — equity curve and friends
   -----------------------------------------------------------------------------
   Always inline SVG with preserveAspectRatio="none" and a role/aria-label
   describing the shape in words. Give the drawn line `class="js-line"` so the
   motion layer can stroke it on.
   Grid lines: var(--rule). Line: var(--win) or var(--loss). Endpoint dot:
   var(--mark).
-------------------------------------------------------------------------- */
.chart{width:100%;height:auto;display:block}
.chart-axis{display:flex;justify-content:space-between;color:var(--faint);
            font-size:var(--t-2xs);margin-top:9px}


/* -----------------------------------------------------------------------------
   4.14 STREAK — one cell per session
   -----------------------------------------------------------------------------
   <div class="streak" aria-hidden="true">
     <i class="up"></i><i class="dn"></i> … <i class="up today"></i>
   </div>
   <div class="streak-key"><span>25 Aug</span><span>18 Sep</span></div>
   aria-hidden because the same information must exist as text nearby.
-------------------------------------------------------------------------- */
.streak{display:flex;gap:3px}
.streak i{width:100%;height:34px;border-radius:1px;background:var(--panel-2);display:block}
.streak i.up{background:var(--win);opacity:.72}
.streak i.dn{background:var(--loss);opacity:.72}
.streak i.today{outline:1px solid var(--mark);outline-offset:1px}
.streak-key{display:flex;justify-content:space-between;color:var(--faint);
            font-size:var(--t-2xs);margin-top:10px}


/* -----------------------------------------------------------------------------
   4.15 DISTRIBUTION BARS — ranked comparison
   -----------------------------------------------------------------------------
   <div class="dist">
     <div class="dist-row"><span>Opening range</span>
       <div class="bar"><span style="width:78%"></span></div>
       <span class="num">+8.2R</span></div>
   </div>
   Negative values: add style="background:var(--loss)" to the inner span and
   `.loss` to the number. Sort descending.
-------------------------------------------------------------------------- */
.dist{display:flex;flex-direction:column;gap:11px}
.dist-row{display:grid;grid-template-columns:96px 1fr 50px;align-items:center;
          gap:11px;font-size:13px}
.bar{height:6px;border-radius:var(--r-pill);background:var(--panel-2);overflow:hidden}
.bar span{display:block;height:100%;border-radius:var(--r-pill);background:var(--win);opacity:.8}
.dist-row .num{color:var(--muted);text-align:right;font-size:12px}


/* -----------------------------------------------------------------------------
   4.16 TRADE TABLE — and its mobile counterpart
   -----------------------------------------------------------------------------
   The table and the stacked rows are the SAME data rendered twice. The CSS
   swaps them at 860px. Render both; never render one and hide it with JS.

   <table> … </table>
   <div class="rows">
     <div class="row">
       <div><span class="sym">NQ</span> <span class="tag tag-long">Long</span></div>
       <div class="num win">+$1,860</div>
       <div class="r2"><span>Opening range break</span>·<span>18m</span>·<span>+2.4R</span></div>
     </div>
   </div>
   Money and time go in `.num` (tabular figures) and align right via `.r`.
-------------------------------------------------------------------------- */
table{width:100%;border-collapse:collapse;display:none}
@media(min-width:860px){ table{display:table} }
thead th{text-align:left;font-weight:500;font-size:var(--t-xs);color:var(--faint);
         padding:0 var(--s-3) 11px;border-bottom:1px solid var(--rule)}
thead th:first-child,tbody td:first-child{padding-left:0}
thead th.r,tbody td.r{text-align:right;padding-right:0}
tbody td{padding:15px var(--s-3);border-bottom:1px solid var(--rule);
         font-size:14.5px;vertical-align:middle}
tbody tr:hover td{background:var(--panel)}
.sym{font-family:var(--f-display);font-size:var(--t-h3);letter-spacing:-.01em}
.setup{color:var(--muted);font-size:13px}

.rows{display:flex;flex-direction:column}
@media(min-width:860px){ .rows{display:none} }
.row{display:grid;grid-template-columns:1fr auto;gap:var(--s-1) var(--s-3);
     padding:15px 0;border-bottom:1px solid var(--rule)}
.row .r2{grid-column:1/-1;display:flex;gap:var(--s-2);align-items:center;
         color:var(--faint);font-size:var(--t-xs)}


/* -----------------------------------------------------------------------------
   4.17 EMPTY STATE
   -----------------------------------------------------------------------------
   An empty screen is an invitation, not an apology. The heading says what is
   missing, the copy says what to do, the button does it. Never "Oops" or
   "No data found".

   <div class="empty">
     <h3>No trades tagged “Inventory fade”</h3>
     <p>Tag a trade with this setup and it will show up here.</p>
     <button class="btn btn-secondary">Clear the filter</button>
   </div>
-------------------------------------------------------------------------- */
.empty{border:1px dashed var(--rule-2);border-radius:var(--r);
       padding:var(--s-8) var(--s-6);text-align:center}
.empty h3{font-family:var(--f-display);font-weight:400;font-size:22px;margin-bottom:6px}
.empty p{color:var(--muted);font-size:14px;margin:0 auto var(--s-5);max-width:40ch}


/* -----------------------------------------------------------------------------
   4.18 SKELETON
   -----------------------------------------------------------------------------
   <div class="sk-stack" aria-hidden="true">
     <div class="sk" style="width:38%"></div><div class="sk"></div>
   </div>
   Match the shape of the content that is coming. Wrap in aria-hidden and put
   aria-busy="true" on the region that is loading.
-------------------------------------------------------------------------- */
.sk{height:13px;border-radius:2px;
    background:linear-gradient(90deg,var(--panel) 0%,var(--panel-2) 50%,var(--panel) 100%);
    background-size:200% 100%;animation:sk-shimmer 1.4s linear infinite}
@keyframes sk-shimmer{ to{background-position:-200% 0} }
.sk-stack{display:flex;flex-direction:column;gap:11px}


/* -----------------------------------------------------------------------------
   4.19 FORM CONTROLS
   -----------------------------------------------------------------------------
   <div class="field">
     <label for="entry">Entry</label>
     <input id="entry" placeholder="20145.25">
   </div>
   REQUIRED: every control has a <label for>. Placeholders are examples, never
   labels. Wrap two short fields in `.two`.
   Error: add `.field-error` to the wrapper and a `.field-msg` after the input.
-------------------------------------------------------------------------- */
.field{margin-bottom:15px}
.field label{display:block;font-size:13px;color:var(--muted);margin-bottom:6px}
.field input,.field select,.field textarea{
  width:100%;background:var(--canvas);border:1px solid var(--rule);border-radius:var(--r);
  color:var(--text);padding:9px 11px;font:inherit;font-size:14.5px}
.field input{font-family:var(--f-num)}   /* prices and sizes are numbers */
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--muted);outline:none}
.field textarea{resize:vertical;min-height:76px}
.field input::placeholder,.field textarea::placeholder{color:var(--faint)}
.field-error input,.field-error select,.field-error textarea{border-color:var(--loss)}
.field-msg{color:var(--loss);font-size:var(--t-xs);margin-top:6px}
.two{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-3)}

/* Switch. A labelled row, not a bare toggle.
   <button type="button" class="switch" role="switch" aria-checked="true">
     <span>Followed my plan<span>Flags the trade for review when off</span></span>
     <span class="track"></span>
   </button>
   REQUIRED: role="switch" + aria-checked, toggled in JS. */
.switch{display:flex;width:100%;align-items:center;justify-content:space-between;
        gap:var(--s-3);text-align:left;border-top:1px solid var(--rule);
        padding-top:var(--s-3);margin-top:var(--s-1)}
.switch > span > span{display:block;color:var(--muted);font-size:var(--t-xs)}
.track{width:40px;height:22px;border-radius:var(--r-pill);background:var(--panel-2);
       border:1px solid var(--rule);position:relative;flex:none;transition:.18s}
.track::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;
              border-radius:50%;background:var(--muted);transition:.18s}
[aria-checked="true"] .track{background:var(--win);border-color:var(--win)}
[aria-checked="true"] .track::after{left:20px;background:var(--canvas)}


/* -----------------------------------------------------------------------------
   4.20 MODAL / BOTTOM SHEET
   -----------------------------------------------------------------------------
   Native <dialog>. Centred on desktop, a bottom sheet under 640px — one
   component, two presentations. Opened with .showModal(), closed by the form's
   method="dialog". Do not build a custom overlay.

   <dialog class="modal">
     <form method="dialog" class="sheet">
       <h2>Log a trade</h2>
       <p class="hint">Fill in what you know now.</p>
       …fields…
       <div class="sheet-foot">
         <button value="cancel" class="btn btn-ghost">Cancel</button>
         <button value="save" class="btn btn-primary">Save trade</button>
       </div>
     </form>
   </dialog>
-------------------------------------------------------------------------- */
dialog{border:0;padding:0;background:transparent;max-width:none;max-height:none;width:100%}
dialog::backdrop{background:rgba(10,9,8,.72)}
.sheet{background:var(--panel);border:1px solid var(--rule);color:var(--text);
       width:min(520px,100%);margin:auto;border-radius:var(--r);padding:var(--s-6)}
@media(max-width:640px){
  dialog{position:fixed;inset:auto 0 0 0;margin:0}
  .sheet{border-radius:var(--r-sheet) var(--r-sheet) 0 0;border-bottom:0;padding-bottom:30px}
}
.sheet h2{font-family:var(--f-display);font-weight:400;font-size:25px;margin-bottom:3px}
.sheet .hint{color:var(--muted);font-size:var(--t-sm);margin-bottom:22px}
.sheet-foot{display:flex;gap:9px;justify-content:flex-end;margin-top:22px}


/* =============================================================================
   LAYER 5 — UTILITIES
   These are the only utilities. Do not add one-off helpers to a page.
   ========================================================================== */

/* Any figure a person might compare to another figure. Money, R, durations,
   percentages, counts. Tabular figures keep columns aligned. */
.num{font-family:var(--f-num);font-variant-numeric:tabular-nums;letter-spacing:-.02em}

/* Semantic colour. Apply to the number, not its container. */
.win{color:var(--win)}
.loss{color:var(--loss)}
.mark{color:var(--mark)}

.muted{color:var(--muted)}
.faint{color:var(--faint)}
.serif{font-family:var(--f-display);font-weight:400;letter-spacing:-.01em}

.flow > * + *{margin-top:var(--s-3)}          /* vertical rhythm in prose */
.stack{display:flex;flex-direction:column;gap:var(--s-3)}
.cluster{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-2)}
.push{margin-left:auto}                        /* shove an item to the right */

.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
                 overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}


/* =============================================================================
   LAYER 6 — MOTION CONTRACT & ACCESSIBILITY
   =============================================================================

   Motion is GSAP only, in one script, at the end of <body>. The CSS side
   provides no entrance animations — do not add any.

   HOOKS the motion layer looks for. Emit these classes/attributes and the
   shared script handles the rest; emit nothing and the page is simply static.

     [data-count="18420"]   count-up on a figure. Text content must be the
                            final value as a fallback for no-JS.
     .js-line               an SVG <path> stroked on over ~1.1s.
     .js-ring               the donut's value arc. The script animates from a
                            full offset to the inline stroke-dashoffset.
     .js-ticker             the `.ticker-track`, translated to xPercent:-50.
     .js-modal-open         a button that opens the nearest <dialog>.

   PRINCIPLES
   · One orchestrated sequence on first load. Never a second one on scroll.
   · Everything else is a response to something the person did.
   · Hover transitions belong on interactive elements only, never on cards.
   · Every animation must be skippable: the page is correct before it runs.
   ========================================================================== */

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

/* Larger touch targets on coarse pointers. */
@media(pointer:coarse){
  .btn{height:42px;padding:0 18px}
  .btn-icon{width:42px}
  .chip{padding:8px 15px}
  .nav a{padding:12px 10px}
}
