/* BluBox v0 — styles.
   Measurements come from the signed-off mockup v1
   Ruled colors: #378ADD flat = home lens (#17), #2E7FB8 metallic = off-default (#32),
   rank border = homepage HERO fade at 14px doubled width (#21),
   cluster fade = suggestion-button transition (#36). */

:root{
  --card-blue:#378ADD;
  --card-steel:#2E7FB8;
  --gold:#ffdb01;
  --hero-fade:linear-gradient(to right,#ffdb01,#ff0f6f,#fe01fa);
  --rounded:"Arial Rounded MT Bold","Arial Rounded MT",ui-rounded,"SF Pro Rounded","Helvetica Neue",Arial,sans-serif;   /* the LOGO voice — the BluBox card, its pills, and the wordmark only (John 2026-08-02: "that font is the logo") */
  --ui:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;   /* Path A 2026-08-02: the app's one UI voice — system sans, weight carries the hierarchy Arial Rounded used to */
  --times:"Times New Roman",Times,serif;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --sys:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  /* dark — the ruled default (#19) */
  --page:#0d1117; --surface:#151c28; --line:#243044; --ink:#e6edf5;
  --muted:#8ba2bd; --faint:#64788f; --btn:#161e2b; --btnline:#26324a;
  --chipbg:#1c2634; --chipline:#2b3850; --workbg:#0e1520; --rowline:#1f2a3c;
  --dot:#3a4a60; --doton:#cfdcea; --err:#ff5d5d; --good:#4cc26a; --shadow:rgba(0,0,0,.22);   /* Path A: .30→.22 — softer lift */
  --title:#d9a441;   /* #101: box titles wear bronze-amber — warm, and far enough from status-gold #ffdb01 */
  --daywait:#ffdb01; --dayok:#378ADD;   /* #68: Day gold until chain-confirmed, then Blu */
}
html.light{
  /* #154/#155: face SETTLED at #e1e9f3.  Shared light tokens; the ledger-paper
     choice (#155: Green or Buff) sets the card/menu/button surfaces below. */
  --page:#e1e9f3; --ink:#17222f;
  --muted:#544f30; --faint:#655e34;   /* #155: darkened so "Show Work" + sub-text read on ledger paper */
  --dot:#b9c6d6; --doton:#31435a; --err:#c02929; --good:#2e8b47; --shadow:rgba(23,34,47,.12);   /* Path A: .18→.12 */
  --title:#6f4d16;   /* #101 light: DEEPER bronze (John: darker for light mode only) */
  --daywait:#9a7b00; --dayok:#2E7FB8;   /* #68 light: readable gold-wait; steel Blu */
}
html.light.paper-buff{   /* #155: Ledger Buff (workbg/rowline deepened so Show Work + token rows read clearly) */
  --surface:#f1e6ac; --line:#b0a052; --btn:#f7f0c6; --btnline:#b0a052;
  --chipbg:#ecdf9e; --chipline:#b0a052; --workbg:#e6d894; --rowline:#cdbd72;
}
html.light.paper-green{   /* #155: Ledger Green (rowline deepened for clearer token rows) */
  --surface:#d3e6bf; --line:#7ba05e; --btn:#e0efd0; --btnline:#7ba05e;
  --chipbg:#c9dfad; --chipline:#7ba05e; --workbg:#c2dba8; --rowline:#a8c688;
}
html.dark-screen{   /* #158b (John): the WOW dark — a phosphor accounting terminal.
     Near-black green page, pale-green ink, bright phosphor title + lit dots. */
  --page:#060d08; --surface:#0c1710; --line:#244a2e; --ink:#d6ebd8;
  --muted:#78ad82; --faint:#5a8a64; --btn:#0e1c13; --btnline:#26472f;
  --chipbg:#122419; --chipline:#26472f; --workbg:#08130c; --rowline:#183020;
  --dot:#2c5236; --doton:#74e08c; --err:#ff6b6b; --good:#5bd47f; --shadow:rgba(0,0,0,.5);
  --title:#5bd47f;   /* phosphor-green box titles — the terminal glow */
}
html.dark-slate{   /* Path B (John, 2026-08-03): the modern-minimal sixth theme — neutral
     near-black, hairline lines, ink titles, ONE accent (the Blu).  No terminal
     tint, no ledger paper: the quiet room the numbers speak in. */
  --page:#09090b; --surface:#131316; --line:#26262b; --ink:#e9e9ec;
  --muted:#9a9aa3; --faint:#6e6e78; --btn:#151519; --btnline:#2a2a30;
  --chipbg:#1b1b20; --chipline:#303038; --workbg:#0e0e11; --rowline:#202025;
  --dot:#3a3a42; --doton:#d6d6dc; --err:#ff6b6b; --good:#4cc26a; --shadow:rgba(0,0,0,.45);
  --title:#e9e9ec;   /* ink titles — the accent stays in the interactive chrome */
  --daywait:#d9a441; --dayok:#5ea2e8;
}
html.dark-blue{   /* #158d (John): the blue twin of the green-screen — the white ink
     goes soft LIGHT-BLUE the same way green-screen turns it light-green. Navy terminal. */
  --page:#070d18; --surface:#0f1a2e; --line:#26426e; --ink:#d0e4fb;
  --muted:#84a4cc; --faint:#6484ac; --btn:#101d33; --btnline:#294870;
  --chipbg:#152740; --chipline:#294870; --workbg:#0a1424; --rowline:#182c48;
  --dot:#2e4a72; --doton:#78b6ef; --err:#ff6b6b; --good:#4cc26a; --shadow:rgba(0,0,0,.5);
  --title:#68b0f2;   /* sky-blue box titles — the blue glow */
}
/* #155: theme swatches in the Settings row — each wears its theme's title color */
.thopt{display:inline-block;padding:2px 5px;border-radius:8px;font-size:12.5px;font-weight:600;
  margin:0 1px;cursor:pointer;border:1.5px solid transparent;vertical-align:middle}   /* John 2026-08-03: sides 9→5, margin 2→1 — five swatches (Slate joined) ran 37px past the phone row; this buys 50 so the ✓ fits on any label */
.thopt.th-slate,.thopt.th-screen,.thopt.th-blue{padding:2px 7px;border-color:var(--line)}   /* John 2026-08-03: the DARK swatches run wider AND wear a visible edge — their near-black fills vanished into Slate's panel, so Green and Blue read as bare words, "cards removed" (the .thon ink ring still outranks this on the active pick) */
.thopt.th-green,.thopt.th-buff{padding:2px 4px}   /* …and the light papers, short words in bright pills, run a little thinner */
.thopt.th-dark{background:#151c28;color:#d9a441}
.thopt.th-screen{background:#0c1710;color:#5bd47f}   /* #158b: phosphor-green terminal swatch */
.thopt.th-blue{background:#0f1a2e;color:#68b0f2}   /* #158d: blue-screen swatch */
.thopt.th-slate{background:#131316;color:#e9e9ec}   /* Path B: the Slate swatch — neutral ink on neutral dark */
.thopt.th-green{background:#d3e6bf;color:#6f4d16}
.thopt.th-buff{background:#f1e6ac;color:#6f4d16}
.thopt.thon{border-color:var(--ink);font-weight:800}
html.light #setVault{color:#9a6b00}   /* #155: Vault line — readable dark gold on light paper (bright gold vanishes) */
html.light .menu-about{color:#3f3a20}   /* #155: darker bottom explanatory text on light paper */
/* #161 (John, 2026-07-24): active/pressed button states need DARK, saturated accents on
   the light papers — the dark-theme brights (gold #ffdb01, light-blue #cfe4fa, card-blue
   as text) wash out on cream/paper (measured 1.0–2.9:1). These restore ≥4.5:1. */
html.light .timerlock.on{background:rgba(150,105,0,.16);border-color:rgba(150,105,0,.6);color:#6e4f00}
html.light .charttoggle.active{background:rgba(55,138,221,.16);border-color:#4d7cbb;color:#164a88}
html.light .pxseg button.on{background:rgba(55,138,221,.18);color:#164a88}
html.light .row.sel .row-name{color:#164a88}
html.light .hd-token.srt,html.light .hd-token.srt .sortcaret{color:#164a88}

*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--page);color:var(--ink);font-family:var(--sys);
  -webkit-font-smoothing:antialiased;transition:background .25s ease,color .25s ease}
button{font:inherit;color:inherit}

#app{max-width:430px;margin:0 auto;padding:12px 16px 30px}
/* #154: on desktop/localhost the 430px column floats as loose cards on a wide
   page — frame it like a phone screen. Real phones (narrow) get NO frame: the
   app fills the actual screen. */
@media (min-width:481px){
  body{background:#000}   /* #154: black desk behind the phone so the frame pops */
  #app{position:relative;background:var(--page);
    width:min(430px, calc(100vw - 56px));   /* the whole frame always fits — no clipped borders */
    border:12px solid #0a0a0a;              /* the phone body / bezel */
    border-radius:54px;
    box-shadow:0 0 0 1px rgba(255,255,255,.07), inset 0 0 0 1px rgba(255,255,255,.04), 0 26px 70px rgba(0,0,0,.65);  /* rim + glass edge + lift */
    margin:24px auto;
    padding-top:42px;padding-bottom:28px}   /* status-bar strip for the island + home-bar room */
  #app::before{                             /* Dynamic Island + camera cutout on the right */
    content:"";position:absolute;top:9px;left:50%;transform:translateX(-50%);
    width:112px;height:29px;border-radius:16px;z-index:60;
    background:radial-gradient(circle at 82% 50%, #16283a 0 2.4px, #060a12 2.8px 4.8px, #000 5.2px), #000;
    box-shadow:0 0 0 1px rgba(255,255,255,.05)}
  #app::after{                              /* iOS-style home indicator */
    content:"";position:absolute;left:50%;bottom:9px;transform:translateX(-50%);
    width:120px;height:5px;border-radius:3px;background:var(--muted);opacity:.5}
}
/* #159 (John, 2026-07-23): the DESKTOP display. At true desktop widths the
   phone frame gives way to a wider 900px panel that uses the empty desk. The
   iPhone chrome (Dynamic Island, home indicator) retires; the canvas widens
   for the columns / large-chart work to come. Content is still single-column
   here — this is the room, not yet the layout. */
@media (min-width:960px){
  #app{width:900px;max-width:900px;border-radius:32px;padding-top:28px}
  #app::before,#app::after{display:none}
  /* #159 (John, 2026-07-23): the desktop ledger gains a DETAILS column —
     TOKEN | DETAILS | QTY. | PRICE. Line 1 of a row's detail shows in it; a click
     stacks the rest (rows 2,3,4…) directly beneath, left-justified, same column. */
  #app .row-head,#app .row-line.bal{grid-template-columns:172px minmax(0,1fr) 56px 88px;grid-template-rows:auto;align-items:start}   /* #166: minmax(0,…) so a long detail line can't shove Qty/Price off-screen */
  #app .hd-details{display:block;text-align:left}
  /* every cell places explicitly so the mobile stake double-row doesn't leak in */
  #app .row-line.bal .row-name{grid-column:1;grid-row:1}
  #app .row-line.bal .row-detail{grid-column:2;grid-row:1;display:block;justify-self:start;min-width:0;
    font-family:var(--sys);font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;
    white-space:normal;overflow-wrap:anywhere;line-height:1.5}   /* #166: wrap long lines inside the column instead of pushing the grid wider */
  #app .row-line.bal .row-amt{grid-column:3;grid-row:1;justify-self:end;align-self:start}
  #app .row-line.bal .row-right{grid-column:4;grid-row:1;justify-self:end;align-self:start}
  #app .row-detail .rd-one{display:block}
  #app .row-detail .rd-rest{display:none}
  /* #192: the desk's Token Prices grid.  It MUST carry #app — the Balances rule
     above is id-qualified, so a plain .pxhead class loses to it and the card
     would silently wear a four-column track list with two columns empty.
     (That exact specificity trap collapsed the LPX card's grid in #189.) */
  #app .row-head.pxhead,#app .row-line.px{grid-template-columns:minmax(172px,1fr) 110px 130px;grid-template-rows:auto;align-items:baseline}
  /* #188c (John): "make the T-Share font match the token font."  On a stake row
     the Details cell is row DATA now — part of the line the eye reads across —
     not the 12px system footnote every other row keeps there.  It wears the
     token face, size and ink, so name and T-Shares read as one line. */
  #app .row.stake .row-detail, #app .row.stake .row-detail .rd-one{
    font-family:var(--ui);font-size:15.5px;color:var(--ink)}
  #app .row.open .row-detail .rd-rest{display:block;margin-top:2px}   /* the click stacks the list beneath line 1 */
  #app .rd-rest .dl{padding-left:20px;text-indent:-20px}   /* #166 (John): hanging indent — a wrapped line tucks under, the field indents (.wl-sub) stay put */
  /* desktop: where the column ALREADY carries the breakdown (sample mode's
     .hasdetail rows), the box is redundant and folds away.  #184 (John): a REAL
     row's Details cell holds only the wallet name — its derivation still needs
     the box, so an unqualified rule here was swallowing every real-mode Show
     Work on the desk (the "HSI dropdown does not open" report). */
  /* #188c (John): …and a STAKE row no longer carries it either — its cell now
     states the T-Shares and the derivation went back to the fold, so the box
     must show.  Same failure mode as the #184 bug above, one class narrower. */
  #app .row.hasdetail.open:not(.stake) .work{display:none}
  .entry.wide{max-width:600px}   /* #184 (John): "that line might have to be wider" — Watched Addresses gets the desk's room so Preset · Hide · Delete fit beside the address */
}

/* ---------- corner buttons: page-header furniture, not card elements (#31) ---------- */
.apphead{position:sticky;top:0;z-index:25;background:var(--page);display:flex;justify-content:space-between;align-items:center;padding:6px 2px 14px}   /* #138 (John): with the BluBox unsticky (#137), the menu row keeps the post */
.cornerbtn{width:40px;height:40px;border-radius:12px;background:var(--btn);border:1px solid var(--btnline);
  display:flex;align-items:center;justify-content:center;cursor:pointer}
.cornerbtn svg{display:block}
.dropdown{position:absolute;top:50px;z-index:30;min-width:252px;background:var(--surface);
  border:1px solid var(--line);border-radius:16px;padding:8px;box-shadow:0 2px 6px var(--shadow),0 10px 28px var(--shadow);display:none;
  max-height:calc(100vh - 70px);overflow-y:auto;overscroll-behavior:contain}   /* #76 audit: the menu scrolls inside itself — before, its bottom was reachable only when the page behind happened to be taller */
.dropdown.openmenu{display:block}
#menuPanel{left:0}
#settingsPanel{right:0}
.menu-cap{font-size:11px;color:var(--faint);padding:4px 11px 7px}
.menu-item{font-family:var(--ui);font-size:13.5px;color:var(--ink);padding:10px 11px;border-radius:8px;
  border-top:1px solid var(--rowline);cursor:pointer;width:100%;text-align:left;background:none;border-left:none;border-right:none;border-bottom:none;display:block}
.menu-item:first-of-type{border-top:none}
.menu-item:hover{background:var(--chipbg)}
.menu-item.current{outline:1.5px solid var(--card-blue);outline-offset:-1.5px}
.menu-item .def{color:var(--muted);font-size:11.5px;font-family:var(--sys)}
.menu-item.danger{color:var(--err)}
/* John 07-25: the Vault row wears its state — name blue, On green, Off red, action muted */
.bv-name{color:var(--card-blue);font-weight:700}
.bv-on{color:var(--good);font-weight:700}
.bv-off{color:var(--err);font-weight:700}
.bv-act{color:var(--muted)}
.menu-item.danger.armed{color:#fff;background:var(--err)}
.menu-row{display:flex;gap:8px;margin:4px 0}
.menu-item.half{flex:1;border:1px solid var(--line);border-radius:12px;text-align:left;background:none}   /* John 07-29: every card wears the Theme fence's border — one line color across the panel */
.menu-item.half:hover{background:var(--chipbg)}
.menu-ico{display:inline-block;vertical-align:-3px;margin-left:4px;color:var(--muted)}   /* John 07-29: the printer says "Print" better than three dots did */
/* John 07-29: on ledger paper (Sage and Buff) the PulseChain card goes black —
   the same black the Ranking card wears, and the fade reads its best on it.
   Ethereum keeps the paper.  Light-only: the dark themes are already near-black. */
html.light .menu-item.half.chain-pls{background:#000;border-color:#000;color:#e6edf5}
html.light .menu-item.half.chain-pls:hover{background:#141414}
html.light .menu-item.half.chain-pls .def{color:#9fb2c7}   /* the muted olive would vanish on black */
.menu-about{font-size:11px;color:var(--faint);line-height:1.55;padding:9px 11px 5px;border-top:1px solid var(--rowline);margin-top:4px}

/* ---------- The Card (#17, #32, #39) ---------- */
.card{position:relative;z-index:20;border-radius:24px;padding:17px 22px 10px;color:#fff;font-family:var(--rounded);   /* John 2026-08-02: 5px shorter top to bottom — 20/12 → 17/10 */
  box-shadow:0 1px 2px var(--shadow),0 8px 24px var(--shadow);margin-bottom:14px;outline:none;touch-action:none}   /* Path A: layered soft lift — a tight contact shadow + a wide low one, not one heavy throw */   /* #137 (John, re-rules #49): the BluBox scrolls up WITH the Hex Fade — transaction readers want the space; the middle box (Restore, range, chart) keeps the sticky post */
.card.flat{background:var(--card-blue)}          /* home lens — FLAT, no sheen */
.card.metal{background:
    linear-gradient(155deg, rgba(255,255,255,.17) 0%, rgba(255,255,255,0) 30%,
                    rgba(7,20,34,.20) 58%, rgba(255,255,255,.10) 84%, rgba(4,12,22,.14) 100%),
    var(--card-steel);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.30), inset 0 -1px 0 rgba(0,0,0,.18), 0 1px 2px var(--shadow), 0 8px 24px var(--shadow)}
.card-title{font-size:15px;opacity:.95;letter-spacing:.01em;text-align:center}
/* #182: the Included Addresses lens — the card grows a row per address */
#cardAddrs{display:flex;flex-direction:column;gap:8px;margin:46px auto 6px;width:100%;max-width:400px;padding:0 4px}   /* #182-3: rows clear the pill; John 07-25: on the wide desktop card the list stays a centered column so names and numbers sit TOGETHER, never across the page */
#cardAddrs .ca-row{display:flex;justify-content:space-between;align-items:baseline;gap:14px;font-size:17px;color:#fff}   /* John 07-25: bigger text and numbers */
#cardAddrs .ca-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
#cardAddrs .ca-usd{flex:0 0 auto}
#cardAddrs .ca-usd sup{font-size:11px}
/* #188m (John): "make $ superscript in all fields."  One class, sized in em so it
   rides whatever text it lands in — fold bullets, row values, the Price line.
   #188o (John): "the Superscript is above the number line… it looks really
   strange."  It was, and there is a reason the eye rejects it: a RAISED small
   figure means CENTS ($12⁹⁹), so a raised $ reads as a typesetting error.
   Financial setting CAP-ALIGNS the mark instead — same vertical band as the
   digits, just smaller, so it stops looking like a numeral without floating.
   The offset is MEASURED, not guessed: canvas actualBoundingBoxAscent for "1" at
   1em minus "$" at .62em gives 0.21–0.22em, and it holds across both faces and
   every size in the app (rounded 15.5/34px, system 12.5px).  The old .38em was
   nearly double that — hence the float.
   TWO traps, both measured rather than reasoned about:
   1. <sup> carries a browser default of `vertical-align:super`, which was being
      ADDED to the offset — the mark rode the super lift PLUS .38em.  Reset to
      baseline first, then apply the raise.
   2. `top` in em resolves against the element's OWN font-size, not the parent's,
      so the number here is not the parent-em figure.
   And a third, caught by John's eye rather than by a metric: aligning the INK
   TOPS is the wrong target.  The $ glyph runs above cap height AND below the
   baseline, so top-of-ink alignment reads as vertically CENTRED on the digits —
   John, seeing it: "the $ is top aligned in the BluBox card, all other locations
   it is center aligned."  The Card had been right since #77.  So the law is now
   the CARD's own numbers, applied everywhere: .55em, raised .45em of its own em.
   One appearance, already signed off, in every field. */
sup.cur{font-size:.55em;line-height:0;vertical-align:baseline;position:relative;top:-.45em;
  margin-right:1px;font-weight:inherit}
#cardAddrs .ca-un{opacity:.7;font-size:14px}
#cardAddrs .ca-tot{border-top:1px solid rgba(255,255,255,.28);padding-top:7px;margin-top:1px;font-weight:600}   /* #184 (John): the rows are checkable — the Total closes the list */
.card-value{font-size:38px;line-height:1.08;margin-top:6px;text-align:center}   /* #77, then 2px smaller (John, 07-19) */
.card-value .cur{font-size:.55em;position:relative;top:-.45em;margin-right:1px}   /* the $ rides superscript */
/* #90: the lens rail — one pill on the RIGHT holding arrow, dots, arrow */
.lensrail{position:absolute;right:10px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;
  align-items:center;gap:2px;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.20);
  border-radius:12px;padding:2px}   /* #132: the pill shrinks — the arrows keep their length */
.card .lensrail .cbtn{width:18px;height:26px;background:none;border:0;color:#fff}   /* #133 (John): the pill runs SHORTER — still a fatter press than the original 22px */
  /* #94 (John): match the legend card — the pill is the card, the arrows are bare glyphs like the dots */
.lensdots{display:flex;flex-direction:column;gap:4px;background:none;border:0;padding:0 4px;cursor:pointer}   /* #133: tighter legend; #209 (John): dots spread a little — the pill runs longer */
.lensdots b{width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.30)}
.lensdots b.on{background:#fff}
/* #110 (John, re-rules #92): mobile navigates by swipe, so every rail arrow goes on
   touch — the pill legends (lens dots + the window pill) stay as the position marker.
   The flip cluster + pane arrows already hide via .cluster{display:none} below. */
@media (hover:none) and (pointer:coarse){.lensrail .cbtn,.pricerail .cbtn{display:none}}
@media (hover:none) and (pointer:coarse){.card .lensrail{padding:9px 2px}}   /* #210c (John): "make the pill legend a little taller" — the phone pill holds only the dots, so it ran short; 2→9px caps stretch it */
.card-foot{margin-top:8px;text-align:center}

.fitline{display:block;white-space:nowrap;overflow:hidden}   /* auto-shrink law (#37) */
.workaff{font-size:11px;letter-spacing:.02em;opacity:.6;background:none;border:none;cursor:pointer;font-family:inherit;text-decoration:underline;text-underline-offset:3px}   /* #155: underlined text-link — no leading triangle (it never indicated state) */
.box .workaff{color:var(--faint);opacity:1}
.workaff-row{text-align:center}
/* #210h (John): the Ranking face's Show Work link retired — the work lives on
   the 4th face (#183's door and its #195d wrap rules went with it) */
#rankSources{background:rgba(255,255,255,.05)}   /* #209: the 4th face's pane — the #183 fold's colors carry over */
#rankSources, #rankSources li{color:#d9cfa3}
.rank-src-h{font-family:var(--ui);font-weight:700;color:var(--gold);font-size:13px;letter-spacing:.05em;margin:10px 0 4px}   /* #209: each face's header over its own bullets */
#rankSources .rank-src-h:first-child{margin-top:2px}

/* ---------- Rank box (#21): black + gold by ruling, in BOTH themes ---------- */
/* #127 (John, re-ruled): the Fade Card wears its own dot legend IN the right
   border — bare dots, no pill chrome, the full 14px band on all four sides;
   the lit dot is the face showing, a tap returns Home (the Ranking). */
.rankwrap{position:relative;z-index:1;border-radius:24px;padding:10px 14px 10px 10px;background:var(--hero-fade);margin-bottom:14px}   /* Path A (John, 2026-08-02): the Hex Fade BAND returns at 10px — 14px on the right, the dots' lane */
.rankdots{position:absolute;right:0;top:0;bottom:0;display:flex;flex-direction:column;gap:8px;   /* #209 (John): dots spread a little — the legend runs longer */
  align-items:center;justify-content:center;appearance:none;-webkit-appearance:none;
  background:none;border:0;margin:0;padding:0 2.5px;cursor:pointer}   /* 2.5px centers the 9px dots in the 14px right lane (John 2026-08-02) */
.rankdots b{width:9px;height:9px;border-radius:50%;background:rgba(0,0,0,.35)}   /* back on the fade band (John 2026-08-02) — the #159 dot colors return with it */
.rankdots b.on{background:#000}
.rank{background:#000;border-radius:12px;display:flex;align-items:center;gap:12px;padding:14px;cursor:pointer;outline:none}   /* Path A: gap 15→12, sides 16→14 — the captions buy back the room the system font spends; radius 12 nests inside the 24px wrap minus its 13.5px band */
.rank .phex{width:46px;height:auto;flex:none}
/* #97: the logo waves at newcomers — never tapped, or 30 days quiet */
.phex.beckon{animation:beckon 2.8s ease-in-out infinite;transform-origin:50% 55%}
@keyframes beckon{0%,100%{transform:scale(1) rotate(0deg)}12%{transform:scale(1.08) rotate(-4deg)}24%{transform:scale(1.08) rotate(3deg)}36%{transform:scale(1) rotate(0deg)}}
@media (prefers-reduced-motion:reduce){.phex.beckon{animation:none}}
.rank-text{min-width:0;flex:1}
.rank-title{font-family:var(--ui);font-weight:700;color:var(--gold);font-size:14.5px;letter-spacing:.05em;text-align:center}   /* first-level tracking (#51); John 07-25: centered logo-edge to fade-edge, matching the alternate faces */
/* two columns (#51): rank over "of N Stakers" left, delta over its window right;
   each column right-aligns so number and caption share a flush right edge */
.rank-cols{display:flex;justify-content:space-between;align-items:flex-end;gap:14px;margin-top:9px}   /* air above the numbers */
.rank-col{display:flex;flex-direction:column;align-items:flex-end;min-width:0}
.rank-col-l{flex:1.4}
.rank-col-r{flex:1}
@media (min-width:410px){.rank-col-r{margin-right:16px}}   /* inset mirrors the logo's border gap where width allows (#51) */
@media (min-width:410px){.rank.egg .rank-col-r{margin-right:8px}}   /* #195d (John: the Liquid face's "30-day change could move right"): the alternate faces sat 8px further left than the Ranking face — measured 58px vs 50px from the fade edge.  Halving the #51 inset on .egg (the class both alternate faces wear) squares all three faces on one right edge. */
.rank-value{display:block;font-family:var(--ui);font-weight:800;letter-spacing:-.01em;font-variant-numeric:tabular-nums;color:var(--gold);font-size:36px;line-height:1.12;text-align:right;width:100%}
.rank-delta{display:block;font-family:var(--ui);font-weight:900;letter-spacing:-.01em;font-variant-numeric:tabular-nums;color:var(--gold);font-size:36px;line-height:1.12;text-align:right;width:100%}   /* emphatically bold (Path A: the Times text-stroke retired — weight 900 carries it alone) */
.rank-sub{font-family:var(--ui);font-weight:600;color:var(--gold);opacity:.82;font-size:12px;margin-top:8px;text-align:right;white-space:nowrap;letter-spacing:.02em;width:100%;min-width:0}   /* Path A: width:100% makes the caption's box the COLUMN's box — before this, the box grew with the text, fitAll saw no overflow, and the two captions could collide mid-card (Times was narrow enough to hide it) */   /* air below the numbers */
.rank-value sup,.rank-delta sup{font-size:.55em}   /* superscript # and +/- */
.rank-sub .sep-dot{font-size:.95em;line-height:0}   /* the enlarged separator dot (true bullet; 'dot' belongs to the pane pips) */
.rank .phex#rankLogo{cursor:pointer}
.rank.egg{cursor:pointer}
.rank-title.eggt{cursor:pointer;text-align:center;text-decoration:underline;text-decoration-thickness:.5px;text-underline-offset:3px;text-decoration-color:rgba(255,219,1,.35)}   /* centered logo-edge to fade-edge (ruled 07-15) */
.rank.egg .rank-col-l{padding-right:14px}   /* the supply column slides left a little (ruled 07-15) */
.rank.egg .rank-text{transform:translateX(-8px)}   /* whole text block bumps left so the side gaps read even (ruled 07-15) */
.rank-chartwrap{margin-top:9px}
.rank-chartwrap svg{width:100%;height:auto;display:block}
/* Timer Lock (#83; #98: two lines, riding the pane rail below the arrows) */
.timerlock{display:flex;flex-direction:column;align-items:center;gap:3px;font-size:9.5px;font-weight:700;
  line-height:1.15;color:var(--muted);background:var(--chipbg);border:1px solid var(--chipline);
  border-radius:8px;padding:5px 8px;cursor:pointer}
.timerlock .tl2{display:flex;align-items:center;gap:4px}
.timerlock.on{background:rgba(255,219,1,.13);border-color:rgba(255,219,1,.45);color:#ffdb01}
.pane-stick .timerlock{position:absolute;top:0;right:160px}   /* #100/#104: LEFT of the pill, same top line; #209: 104→160 — the enlarged letter cards need the room */
@media (hover:none) and (pointer:coarse){.pane-stick .timerlock{right:0}}   /* phone: the arrows hide, the lock holds the corner */

/* ---------- generic box ---------- */
.box{position:relative;background:var(--surface);border:1px solid var(--line);border-radius:20px;
  padding:15px 18px;margin-bottom:14px;outline:none}
.box-head{display:flex;justify-content:space-between;align-items:center;gap:10px}
.box-title{font-family:var(--ui);font-size:15px;color:var(--ink);color:var(--title);min-width:0;flex:1}   /* #132: long face names shrink, never shove the chips */
.head-right{display:flex;align-items:center;gap:8px;flex:none}
.chip{white-space:nowrap;font-size:11px;font-weight:700;color:var(--muted);background:var(--chipbg);border:1px solid var(--chipline);
  border-radius:999px;padding:3px 10px;font-variant-numeric:tabular-nums}   /* bold time field (#48) */
#yieldChip{width:70px;height:28px;border-radius:8px;padding:0;box-sizing:border-box;display:flex;align-items:center;justify-content:center}   /* #209 (John): the date-range button and the chart button share ONE size and shape */
.charttoggle{width:70px;height:28px;border-radius:8px;background:var(--chipbg);border:1px solid var(--chipline);
  color:var(--muted);display:flex;align-items:center;justify-content:center;cursor:pointer;box-sizing:border-box}   /* #209: 56→70 — the chart button matches the date-range button */
.charttoggle.active{background:rgba(55,138,221,.20);border-color:#37588a;color:#cfe4fa}

#yield{touch-action:none;position:sticky;z-index:19}   /* docks below the Card; top set by layoutSticky() (#49) */
/* #158e (John): seals the sticky seam — a page-colored band under the stuck Value
   card so token rows can't flash in the gap above the Token Balances header.
   #188v (John, 2026-07-26) RE-RULES ITS SIZE: at 13px the band filled almost the
   whole 14px gap, and John, watching the ledger scroll: "the black strip blocked
   transactions from showing as they scroll up in the blank space."  Same band,
   opposite verdict — it was hiding rows that should still be readable, not just
   the flash it was built for.  4px is enough to cover the seam itself and gives
   the other 10px back to the rows. */
#yield::after{content:"";position:absolute;left:0;right:0;top:100%;height:4px;background:var(--page)}
.yield-line{font-family:var(--ui);font-size:27px;color:var(--ink);margin:9px 0 3px;text-align:center}
.scope{font-size:12px;color:var(--muted);margin-bottom:7px;text-align:center;white-space:pre-line}   /* #133: two-line scope texts */
.chartwrap{margin:10px 0 4px}
.chartwrap svg{width:100%;height:auto;display:block}
.chart-total{font-family:var(--ui);font-size:16px;color:var(--ink);margin-top:6px;text-align:center}

/* ---------- pane rows ---------- */
#pane{touch-action:pan-y}
.row{border-top:1px solid var(--rowline)}
.row:first-of-type{border-top:none}
.row-line{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:10px 0;cursor:pointer}
.row-name{font-family:var(--ui);font-size:15.5px;color:var(--ink);min-width:0}   /* #155: +1px */
.row-amt{font-size:13px;color:var(--muted);margin-left:7px;font-family:var(--sys);font-variant-numeric:tabular-nums}   /* #155: +1px */
.row-right{flex:none;display:flex;align-items:baseline}
.row-usd{font-family:var(--ui);font-size:13px;color:var(--ink);font-variant-numeric:tabular-nums}   /* #155: +1px; #195d (John): "Price will be small for all tokens" — 17px steps down to the Qty column's own 13px, so the row reads as one quiet line */
.chev{font-size:11px;color:var(--faint);margin-left:9px}
.tx-date{font-family:var(--mono);font-size:15.5px;color:var(--faint);margin-right:8px;display:inline-block;width:50px;box-sizing:content-box}   /* #169l (John): row date matches the Transaction name size; #169m fixed-width column so the Transaction label lines up over the names in BOTH header and rows regardless of the date's font size */
.tx-head .tx-date{font-size:11px}   /* the column heading keeps its small uppercase label size — the fixed width holds the alignment */
.tx-date.tx-date-full{font-size:11.5px;width:78px}   /* #199b (dormant since #199c): a >5-char date gets the wider cell */
.txleg-step{font-weight:700}   /* #199c: the ‹ Newer / Older › pagers — chips like the months, no tint */
.row.sel .row-line{background:linear-gradient(to right,transparent,rgba(55,138,221,.10) 12%,rgba(55,138,221,.10) 88%,transparent);
  border-radius:8px}
.row.sel .row-name{color:var(--card-blue)}     /* tap-to-select highlight (#35) */
/* #156: columnar Token Balances — Token left, Qty + Price right, one shared 14px
   left gutter so every column stays straight; LP rows flag with a ledger tab in
   that gutter (color flips with the theme). Qty column locked to the 0.09/999M max. */
.row-line.bal{display:grid;grid-template-columns:minmax(0,1fr) max-content max-content;column-gap:14px;padding:10px 6px 10px 14px}   /* #195d (John: "Qty needs to move right closer to the Price") — the name takes the slack; Qty sits against the Price column instead of stranded mid-row */
.row-line.bal .row-name{text-align:left}
.row-line.bal .row-amt{margin-left:0;text-align:right;justify-self:end}
.row-line.bal .row-right{justify-self:end}
.row-head{display:grid;grid-template-columns:minmax(0,1fr) max-content max-content;column-gap:14px;padding:2px 6px 6px 14px;margin-top:-5px;
  font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--faint);border-bottom:1.5px solid var(--line)}   /* #164 (John): bold column labels + the sort caret (inherits) */
.row-head span{text-align:right}
.row-head span:first-child{text-align:left}
/* #159 (John): the Token header is a sort toggle — click to sort A→Z, click again to return */
.row-head .hd-token{cursor:pointer;display:inline-flex;align-items:center;gap:5px;user-select:none}
.row-head .hd-token .sortcaret{font-size:9px;letter-spacing:0;color:var(--faint)}
.row-head .hd-token.srt,.row-head .hd-token.srt .sortcaret{color:var(--card-blue)}
/* #192 (John): the Token Prices card — Token left, the 24-hour change and the
   price right.  Its own track list, not the Balances one: this card has no
   Details and no Qty, so borrowing that grid would leave two empty columns and
   strand the price short of the right edge every other card shares. */
.row-head.pxhead,.row-line.px{display:grid;grid-template-columns:minmax(96px,1fr) 100px 92px;column-gap:12px}   /* #210u: 78→100 — the middle column holds the range steppers */
/* #210u (John): the range steppers — LONG chips, easy hotspots, flanking the label */
.hd-chg.chgwin{display:flex;align-items:center;justify-content:flex-end;gap:4px;text-transform:none}
.chgstep{background:var(--chipbg);border:1px solid var(--chipline);border-radius:8px;color:var(--muted);
  font-size:17px;font-weight:700;line-height:1;padding:3px 10px;cursor:pointer;font-family:var(--ui)}   /* #212 (John): the range arrows read LARGER — 13→17px glyph, the horizontal padding 9→10px.  Then "a little shorter, keep the width": the VERTICAL padding alone came back 5→3px, so the chip stands 25px instead of 29 and its 29px width is untouched. */
.chg-lab{min-width:28px;text-align:center;cursor:default;font-size:11px;font-weight:700;color:var(--faint)}
.row-line.px{padding:10px 6px 10px 14px;align-items:baseline}
.row-line.px .row-name{text-align:left}
.row-line.px .px-chg,.row-line.px .px-px{justify-self:end;text-align:right;font-variant-numeric:tabular-nums}
.row-line.px .px-px{font-family:var(--ui);font-size:15.5px;color:var(--ink)}   /* the price reads like a row value, because it is one */
/* the INK is the sign — a gain and a loss are equal citizens (#189f), same
   weight and size, only the colour differs.  Both wear the theme's own good/err,
   so all four themes stay legible instead of one hard-coded green. */
.row-line.px .px-chg{font-family:var(--sys);font-size:13px;font-weight:700}
/* .row-head gives the Token label a pointer because it SORTS on the Balances
   card.  This card has no sort, and a pointer promising a control that isn't
   there is the same lie as a control you can't see. */
.row-head.pxhead .hd-token{cursor:default}
/* #192c: an HTT's ratio to HEX, shown as a percent of a HEX.  It sits in the
   PRICE column but is not a price, and the row already carries a percentage in
   the 24H column — so it stays PLAIN ink at the row's own weight while the
   change beside it is bold and coloured.  Weight and colour are what keep a
   LEVEL from being read as a CHANGE. */
.row-line.px .px-ratio{font-weight:400}
.px-up{color:var(--good)}
.px-down{color:var(--err)}
.px-none{color:var(--faint);font-weight:400}
/* #159 (John): the ledger-tab bar now marks every row that OPENS to a breakdown —
   LPs AND stakes (never a single-line token). It's the "there's more here" cue. */
.row.expandable{position:relative}
.row.expandable::before{content:"";position:absolute;left:2px;top:3px;bottom:3px;width:5px;border-radius:3px;background:var(--card-blue);z-index:1}
html.light.paper-buff .row.expandable::before{background:#6a9a4e}   /* buff theme → green tab */
html.light.paper-green .row.expandable::before{background:#b0902f}   /* green theme → gold tab */
html.dark-screen .row.expandable::before{background:#e0a83a}   /* #158b: phosphor terminal → amber tab, the contrast note */
html.dark-blue .row.expandable::before{background:#e0a83a}   /* #158d: blue terminal → amber tab too, the warm contrast */
/* #156: stakes are the reason BluBox exists — their long names ("HSI Portable
   Stakes", "Native HEX Stakes") don't fit a token column, so they get a DOUBLE
   ROW: full-width name on top, T-shares left + value right aligned below. */
.row.stake .row-line.bal{grid-template-columns:minmax(0,1fr) max-content max-content;grid-template-rows:auto auto;row-gap:2px}
.row.stake .row-name{grid-column:1 / -1;grid-row:1}
.row.stake .row-amt{grid-column:2;grid-row:2;justify-self:end;text-align:right;margin-left:0}   /* #159: stake QTY = count, in the QTY column */
.row.stake .row-right{grid-column:3;grid-row:2;justify-self:end;align-self:end}
/* #159 (John): the DETAILS column header hides on the phone (the ledger stays 3-col there) */
.hd-details{display:none}
/* #151 LAW (John, 2026-07-22): Show Work is prose a human reads to trust a number —
   bullets, system sans 12.5px, FULL INK. Never mono, never muted, never 11px. */
.work{font-family:var(--sys);font-size:12.5px;line-height:1.65;color:var(--ink);background:var(--workbg);
  border-left:3px solid var(--card-blue);border-radius:6px;padding:8px 11px;margin:2px 0 10px;display:none}
.row.open .work{display:block}
.row-detail{display:none}   /* #159: the inline second-tap line — desktop only (see the 960px block) */
.dots{display:flex;justify-content:center;gap:6px;padding-top:11px}
.dot{width:7px;height:7px;border-radius:50%;background:var(--dot)}
.dot.on{background:var(--doton)}
#yieldChip{cursor:pointer}
#yieldTitle{flex:1;text-align:center}   /* #108 (John): Price centered between the card's left border and the date chip */
/* #86: the HEX value toggle — the Ledger Tabs (design 3 ruled 07-19: "it shows truth").
   Both modes always readable; the lit tab is the mode showing. FUTURE turns the number Blu. */
.valtoggle{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:52px;border-radius:12px;
  background:var(--card-blue);border:1px solid rgba(255,255,255,.35);cursor:pointer;padding:4px;z-index:6}
.valtoggle .seg{display:flex;align-items:center;justify-content:center;min-height:20px;border-radius:9px;padding:6px 2px;font-size:9px;letter-spacing:.03em;
  font-weight:700;color:rgba(255,255,255,.9);transition:all .2s;line-height:1;font-family:var(--rounded)}   /* #159 (John): flex-centered so the label doesn't drift in the pill at Cmd+/- zoom */
.valtoggle .seg.on{background:#fff;color:#1a5296;box-shadow:0 1px 4px rgba(0,0,0,.3)}   /* #161: darker blue on the white pill — the small 9px label needs ≥4.5:1 (card-blue read 3.59) */
.valtoggle .seg + .seg{margin-top:3px}
.yield-line.sky,.chart-total.sky{color:var(--card-blue)}
#yield{padding-left:72px;padding-right:56px}   /* #138 (John, re-rules #86/#39 symmetry): the Value stack slides right — the right band only needs the chevrons */
#yield .box-head{margin-left:-58px;margin-right:-16px}   /* #138b: 2px back left (John) */   /* #132/#133: the header escapes the toggle band — the rail lives BELOW it; the chip and chart button slide right for the title */
@media (hover:none) and (pointer:coarse){#yield{padding-right:20px}#yield .box-head{margin-right:-12px}}   /* #133/#138: no chevrons on touch — the header and the Value stack take the full width */   /* #133: on the phone the flip cluster is gone — the header takes the whole width and the title looks left */

/* ---------- arrow clusters (#36): desktop only; idle 50% -> hover 100%,
     transition lifted from the suggestion button ---------- */
.cluster{position:absolute;right:10px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:4px;
  opacity:.5;transition:all 150ms cubic-bezier(0.4, 0, 0.2, 1);z-index:5}
.cluster:hover,.cluster:focus-within{opacity:1}
.cluster--h{flex-direction:row}
.cbtn{width:22px;height:22px;border-radius:8px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.13);
  display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;color:var(--ink)}
html.light .cbtn{background:rgba(23,34,47,.06);border-color:rgba(23,34,47,.16)}
.card .cbtn{background:rgba(8,18,30,.34);border-color:rgba(255,255,255,.22);color:#fff}
/* arrow buttons run 2:1 along the axis they point (John, 07-19) — pane arrows keep it.
   #90: cardUp/cardDown moved inside the lens rail; #96 (John): the Price/Yield card's
   arrows go SMALL again — the rails are the targets now */
#dpUp,#dpDown{width:22px;height:44px}   /* #104: arrow-ONLY cards run 2:1 again (the #82 law); rail glyphs stay small */
/* #197e: the arrows' 44px hit-targets retired with them — the pill legend took the rail */
/* the Yield window pair rides the bottom-right corner, balances-card style (John, 07-19);
   the window dot legend mirrors it in the bottom-LEFT corner, and the box reserves the
   corner strip so flowing content never collides */
/* #95: the price rail — arrows and legend combined in one pill, bottom-right */
.pricerail{position:absolute;right:10px;bottom:8px;display:flex;align-items:center;gap:1px;padding:0 2px;height:22px;   /* #132: the pill shrinks */
  background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.20);border-radius:12px}
.pricerail .cbtn{background:none;border:0;width:15px;height:18px;color:var(--ink);position:relative}   /* #157 (John): the pill runs SHORTER — the arrow's long hotspot no longer widens it */
.pricerail .cbtn::after{content:"";position:absolute;top:-6px;bottom:-6px;width:30px;z-index:3}   /* #157: the fat tap target lives HERE, reaching inward over the dots — the pill stays short, the press stays long */
.pricerail #dpLeft::after{left:0}     /* left arrow's hotspot reaches RIGHT into the dots */
.pricerail #dpRight::after{right:0}   /* right arrow's hotspot reaches LEFT into the dots */
/* #85/#90: the window dot legend — ONE pill, now bottom-RIGHT, the arrows riding just above it */
#yieldDots{display:flex;align-items:center;height:22px;padding:0 3px;gap:5px;background:none;border:0;cursor:pointer;position:relative;z-index:1}   /* #209 (John): dots spread a little — the pill runs longer */   /* #157: sits below the arrow hotspots so the outer edges step the window, the centre returns Home */
#yieldDots .dot{width:6px;height:6px}   /* #102: tight like the BluBox's lens dots */
html.light .pricerail{background:rgba(23,34,47,.06);border-color:rgba(23,34,47,.16)}
#yield{padding-bottom:14px;min-height:150px}   /* #100/#104: rail beside Show Work; floor keeps the long flip pair clear */
.yield-flip{top:8px;transform:none}   /* #92/#104: anchored high — the 2:1 pair clears the rail on any face */
.dpad .blank{visibility:hidden}
@media (hover:none) and (pointer:coarse){.cluster{display:none}}   /* gestures rule on touch (#36) */

/* #198 (John): the by-wallet ledger — one bordered card per address, its
   identity at the top; the fence bleeds its padding (the px-sect trick) so
   rows keep the full width */
.wcard{border:1px solid var(--line);border-radius:10px;margin:6px -9px 12px;padding:0 8px 3px}
/* #208 (John 07-30): TXNs dealt by wallet — the brick grid.  The 900px desk
   lays cards two across (each column ≈ the phone pane, so rows read the
   same); below the desk the phone column holds one.  Missing cards slide
   forward, keeping the brick look. */
.txw-grid{display:grid;grid-template-columns:1fr;gap:0 10px;align-items:start;margin:0 -9px}
@media (min-width:960px){.txw-grid{grid-template-columns:1fr 1fr}}
.txw-grid .wcard{margin:6px 0 12px}
.wcard-head{display:flex;justify-content:space-between;align-items:baseline;gap:10px;
  font-family:var(--ui);font-size:12px;font-weight:700;color:var(--title);padding:6px 2px 3px}
.wcard-head .wc-tot{font-variant-numeric:tabular-nums;color:var(--ink);white-space:nowrap}
/* #198: the grouping toggle beside the Timer Lock — same card voice */
.grouplock{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;line-height:1.15;
  font-size:10.5px;font-weight:700;font-family:var(--ui);color:var(--muted);   /* #209g (John): 9.5→10.5 — the Sort by card's text runs 1px larger; gap 3→2 + sides 5→4 so the box HOLDS the 66×37 Timer-Lock match */
  background:var(--chipbg);border:1px solid var(--chipline);border-radius:8px;padding:4px 8px;cursor:pointer}   /* #210b (John): the ONE chip voice across the rail and the Value card */   /* John 07-30: two lines — Sort / By Token, the Timer Lock's stance; #209f (John): the Timer Lock's exact chrome too — radius 10, 8px sides */
.timerlock,.grouplock,.searchlock{width:66px;min-height:37px;box-sizing:border-box;justify-content:center;white-space:nowrap}   /* #209f (John): "make the sort button the same size as the All timers lock" — one fixed box guarantees it in every browser; #210: the spyglass wears it too */
/* #210b: ONE hover for the whole family — the resting colors are now identical,
   so the old background-swap hovers said nothing; a light lift says "pressable".
   Rides BEFORE the :active rules so the press-darken beats it while held. */
@media (hover:hover) and (pointer:fine){
  .pane-pill .pp:hover,.grouplock:hover,.timerlock:hover,.searchlock:hover,.chgstep:hover,#yieldChip:hover,.charttoggle:hover{filter:brightness(1.12)}}
/* #209h (John): the buttons feel the press — a 120ms fade on every state change
   and a dip while held.  scale() paints without laying out, so no box ever
   shifts; reduced-motion keeps the shade change and drops the movement. */
.pane-pill .pp,.grouplock,.timerlock,.searchlock,.chgstep,#yieldChip,.charttoggle{
  transition:background-color .12s ease,border-color .12s ease,color .12s ease,transform .12s ease,filter .12s ease,outline-color .12s ease,box-shadow .12s ease}
.pane-pill .pp:active,.grouplock:active,.timerlock:active,.searchlock:active,.chgstep:active,#yieldChip:active,.charttoggle:active{
  transform:scale(.97);filter:brightness(.9);
  box-shadow:inset 0 2px 3px rgba(0,0,0,.35)}   /* #209i (John: "try it") — the pushed-in face: an inset lip of shade along the top edge reads as real depth, only while held */
@media (prefers-reduced-motion:reduce){
  .pane-pill .pp,.grouplock,.timerlock,.searchlock,.chgstep,#yieldChip,.charttoggle{transition:none}
  .pane-pill .pp:active,.grouplock:active,.timerlock:active,.searchlock:active,.chgstep:active,#yieldChip:active,.charttoggle:active{transform:none}}
.grouplock[hidden]{display:none}   /* the two-line display:flex would otherwise beat the hidden attribute's UA display:none */
.pane-stick .grouplock{position:absolute;top:0;right:376px}   /* left of the spyglass's seat; #209/#210: 176→232→304 — Sort sits outboard because it comes and goes with the data, the always-present spyglass holds the inner seat so its absence never leaves a hole.  #223: 304→376 on the desk — the Value Card replica is present whenever Balances is, so IT takes the inner seat by that same rule and Sort stays outboard of it.  The phone/coarse seats below are untouched (the replica never renders there). */
@media (max-width:959px){.pane-stick .grouplock{top:42px;right:232px}}   /* John 07-30: below the 960 desk the app column is ~430px at EVERY window width (#195d's lesson — key on the desk, not the viewport), so the line is too tight and Sort drops below the Timer Lock — #210: outboard of the spyglass there too */
@media (hover:none) and (pointer:coarse){.pane-stick .grouplock{top:42px;right:0}}   /* phone: the lock holds the corner, the spyglass beside it (#210c), Sort back on the row beneath */
/* #223 (John): the Value Card replica sits BESIDE Sort, and takes the INNER of
   the two seats (304; Sort moved out to 376).  That is the rail's own rule, not
   a preference: a control that comes and goes sits outboard so its absence
   never opens a hole between the ones that remain — and Sort comes and goes
   with the data (one wallet, or no real read, and it is gone) while this
   replica is there whenever Balances is.  MEASURED with Sort hidden: at 376 the
   replica left a 72px gap in the middle of the rail; at 304 the rail closes up.
   It wears .grouplock for the family chrome (#210b's one chip voice).
   DESKTOP ONLY, twice over: under 960 the app column is ~430px at every window
   width (#195d's lesson) and the rail's second row is already spoken for, and a
   coarse pointer is a phone whatever its width. */
.pane-stick .valcard{right:304px;top:0}
@media (max-width:959px){.pane-stick .valcard{display:none}}
@media (hover:none) and (pointer:coarse){.pane-stick .valcard{display:none}}

/* #210 (John): the spyglass — the Sort/Timer card voice, always present */
.searchlock{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;line-height:1.15;
  font-size:10.5px;font-weight:700;font-family:var(--ui);color:var(--muted);
  background:var(--chipbg);border:1px solid var(--chipline);border-radius:8px;padding:4px 8px;cursor:pointer}   /* #210b: the ONE chip voice */
.searchlock .tl2{display:flex;align-items:center}   /* kills the inline-svg baseline slack — the box holds 66×37 like its rail-mates */
.searchlock .tl2 svg{width:12px;height:12px}
.pane-stick .searchlock{position:absolute;top:0;right:232px}
@media (max-width:959px){.pane-stick .searchlock{top:42px;right:160px}}   /* under the Timer Lock's seat */
@media (hover:none) and (pointer:coarse){.pane-stick .searchlock{top:0;right:74px}}   /* #210c (John): beside the Timer Lock, not under it — the phone has no letter pill, so the top row has the room; the 42-row goes back to Sort alone and the body legend breathes */
/* the search modal: input + grouped live results, everything esc'd (#76) */
.s-out{max-height:52vh;overflow-y:auto;margin-top:10px;text-align:left}
.s-note{font-family:var(--sys);font-size:12.5px;line-height:1.65;color:var(--muted)}
.s-head{font-family:var(--ui);font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--faint);margin:12px 0 4px;border-bottom:1.5px solid var(--line);padding-bottom:3px}
.s-head:first-child{margin-top:2px}
.s-hit{display:block;width:100%;text-align:left;font-family:var(--sys);font-size:12.5px;color:var(--ink);
  background:none;border:none;border-radius:8px;padding:5px 6px;cursor:pointer}
.s-hit:hover{background:var(--chipbg)}
.s-more{font-family:var(--sys);font-size:11.5px;color:var(--faint);padding:4px 6px 2px}
/* the landing flash — the found row announces itself, then quiets */
.s-flash{outline:2px solid var(--card-blue);outline-offset:-2px;border-radius:8px;transition:outline-color 1.6s ease .6s}
@media (prefers-reduced-motion:reduce){.s-flash{transition:none}}

/* #197e (John): the pill legend that replaced the pane arrows — three tiny
   letter cards, arranged by the settings Order, the showing card lit */
.pane-pill{display:inline-flex;gap:6px;align-items:center}   /* #209 (John): the letter cards run 50% larger — desktop-only by construction (the cluster hides on touch) */
.pane-pill .pp{border:1px solid var(--chipline);border-radius:8px;background:var(--chipbg);color:var(--muted);
  font-family:var(--ui);font-size:16.5px;font-weight:700;line-height:1;padding:0 9px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;height:37px;box-sizing:border-box}   /* #209g (John): the letter cards stand as tall as the Timer Lock card; #210b: the ONE chip voice */
.pane-pill .pp.on{outline:1.5px solid var(--card-blue);outline-offset:-1.5px;color:var(--ink)}   /* the showing card lit — outline + ink */

/* #211 (John, after a friend "landed on the price page on his first visit" and
   never found the other cards): the letters teach themselves.  Each card holds
   a CONSECUTIVE SLICE of one PulseChain fade — the same five stops the chain
   row wears (#79/#202) — sized N×100% and stepped across by position, so the
   colors line up across the gaps and the leftmost card really does wear the
   left end of the fade.  The cards then light in turn (--ppd) and the row
   reads as one wave.  It runs until the visitor taps a card, once, ever. */
.pane-pill .pp{position:relative;overflow:hidden}
.pane-pill .ppl{position:relative;z-index:1}   /* the letter rides ABOVE the fade — an overlay that swallowed its own letter would teach nothing */
body.bb-teach .pane-pill .pp::after{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background-image:linear-gradient(to right,#00EAFF,#0080FF,#8000FF,#E619E6,#FF0000);
  background-size:calc(var(--ppn) * 100%) 100%;background-position:var(--ppp) 0;
  opacity:0;animation:ppwave 3.2s ease-in-out var(--ppd) infinite}
@keyframes ppwave{0%{opacity:0}8%{opacity:.9}22%{opacity:0}100%{opacity:0}}   /* the sweep takes ~1.3s of the 3.2, so the row rests between passes instead of strobing */
body.bb-dormant .pane-pill .pp::after{animation:none}   /* the Welcome veil hides this rail (visibility:hidden) — a wave nobody can see would spend its first passes on an empty screen */
@media (prefers-reduced-motion:reduce){
  body.bb-teach .pane-pill .pp::after{animation:none;opacity:.3}}   /* no motion, but the invitation stays — the fade sits steady across the row */

/* #211c (John's ruling on the phone half of #211): the letter cards are
   desktop-only by construction — .cluster is display:none on coarse pointers,
   MEASURED 0×0 at 390×844 — so the phone gets its own pair of signals, and
   they teach the two different things a lost visitor needs.

   The NUDGE performs the gesture instead of naming it: the card slides left
   and springs back, twice, then rests.  Deliberately NOT an arrow — an arrow
   reads as a button, and #36 took the arrows off touch precisely because
   gestures rule there; a flashing control that cannot be pressed is a broken
   promise.  The DOTS then answer the question the nudge raises — how many
   cards are there — wearing the same fade slices as their desktop cousins.

   Both stop with the same tap that stops the letters (bb-teach, store.ppSeen).
   The nudge's transform is always retired before swapAnim's own: ppTaught()
   runs ahead of setPane on every path that changes a card. */
@media (hover:none) and (pointer:coarse){
  body.bb-teach:not(.bb-dormant) #paneBody{animation:ppnudge 4s ease-in-out infinite}
  body.bb-teach #pane > .dots .dot{position:relative;overflow:hidden}
  body.bb-teach:not(.bb-dormant) #pane > .dots .dot::after{
    content:'';position:absolute;inset:0;border-radius:50%;pointer-events:none;
    background-image:linear-gradient(to right,#00EAFF,#0080FF,#8000FF,#E619E6,#FF0000);
    background-size:calc(var(--ppn) * 100%) 100%;background-position:var(--ppp) 0;
    opacity:0;animation:ppwave 3.2s ease-in-out var(--ppd) infinite}
  @media (prefers-reduced-motion:reduce){
    body.bb-teach:not(.bb-dormant) #paneBody{animation:none}   /* the nudge IS motion — with motion refused there is nothing left of it to keep */
    body.bb-teach:not(.bb-dormant) #pane > .dots .dot::after{animation:none;opacity:.45}}
}
@keyframes ppnudge{0%,6%{transform:none}14%{transform:translateX(-14px)}22%{transform:none}30%{transform:translateX(-14px)}38%,100%{transform:none}}   /* two passes inside the first 1.5s, then 2.5s of stillness — a hint, not a twitch */

/* #55: the pane arrows ride a zero-height sticky rail pinned under the Yield box */
.pane-stick{position:sticky;height:0;z-index:18}   /* top set by layoutSticky() */
.pane-stick .cluster{top:0;transform:none}
/* #84: the pane's title + Timer Lock pin at the same stop line as the arrows,
   so all three stay in reach however deep the list scrolls */
#pane .box-head{position:sticky;z-index:17;background:var(--surface);padding-bottom:6px;min-height:46px}   /* #100: the strip covers the rail line */

/* #56: the provenance note toggle — the title itself and the ⓘ beside it */
/* #159 (John): quick-print glyph on the Token Balances header */
.pane-print{background:none;border:0;padding:0 2px;margin-left:5px;cursor:pointer;color:var(--muted);vertical-align:middle;line-height:0}
.pane-print:hover{color:var(--ink)}
.pane-print svg{display:block}
/* #106: the address chip — how many addresses feed the totals; tap to glance, tap again to manage */
.addr-chip{font-size:11px;font-weight:700;color:var(--muted);background:var(--chipbg);border:1px solid var(--chipline);
  border-radius:999px;padding:2px 9px;cursor:pointer;font-variant-numeric:tabular-nums;
  display:table;margin:7px 0 0}   /* #107: always its own line, clear air below the title — no accidental title taps */
.addr-chip[aria-expanded="true"]{background:rgba(55,138,221,.20);border-color:#37588a;color:#cfe4fa}
#paneTitle{font-size:17px;padding-right:192px;align-self:flex-start;line-height:1.05;margin-top:2px}   /* John 07-29: Token Balances / Transactions / Token Prices are page titles — 2px above a box title */   /* #106/#107: the Timer Lock + arrows claim 190px of the header's right; the title's cap-top rides level with their card tops (line box tightened, measured) */
@media (hover:hover){
  #card{padding-left:46px;padding-right:46px}
  .pane-stick .cluster{right:0;top:0}   /* #100: the rail lives INSIDE the head strip now — rows own the full width */
}

/* focus visibility for keyboard control (#36) */
.card:focus-visible,.rank:focus-visible,.box:focus-visible{box-shadow:0 0 0 2.5px rgba(55,138,221,.55)}

/* ---------- overlays / modals ---------- */
.overlay{position:fixed;inset:0;background:rgba(4,8,14,.72);display:flex;align-items:center;justify-content:center;
  padding:20px;z-index:50}
.overlay.hidden{display:none}
.entry{width:100%;max-width:400px;background:var(--surface);border:1px solid var(--line);border-radius:20px;padding:22px;
  max-height:calc(100vh - 40px);overflow-y:auto}   /* #76: many addresses scroll inside the modal instead of clipping off-screen */
.entry .sampletop{text-align:center;font-family:var(--ui);font-size:13px;color:var(--gold);
  letter-spacing:.03em;margin-bottom:10px}   /* ruling #66 — first thing a first-arrival reads */
/* #184b (John: "these 2 lines need contrast against their background").  MEASURED:
   bright gold #ffdb01 on the ledger papers read 1.08:1 (buff) and 1.03:1 (green)
   — the two gold lines in the entry popup were all but invisible on paper.  The
   #161 failure class again; the dark themes are fine (12.5–13.4:1).  Dark gold
   restores 5.2:1 on buff and 4.9:1 on green. */
html.light .entry .sampletop{color:#7d5600}
.entry .entrylead{text-align:center;font-family:var(--ui);font-size:13px;color:var(--ink);
  line-height:1.5;margin-bottom:10px}   /* the Desktop-first / QR line, framed by the two gold tildes */
.entry h2{font-family:var(--ui);font-weight:normal;font-size:18px;margin-bottom:8px}
.entry h2.mtitle{font-weight:600}   /* #152: bold modal title by ruling */
.entry p{font-size:12.5px;color:var(--muted);line-height:1.6;margin-bottom:12px}
.entry .modal-lead{font-weight:600;color:var(--ink);margin-bottom:8px}
.entry .modal-bullets{list-style:disc;padding-left:20px;margin:0 0 12px}
.entry .modal-bullets li{font-size:12.5px;color:var(--muted);line-height:1.5;margin-bottom:6px}
.entry .modal-bullets ul{list-style:circle;padding-left:18px;margin:5px 0 0}   /* #152: nested sub-bullets */
.entry .modal-bullets ul li{margin-bottom:4px}
.entry .modal-bullets ul ul{list-style:square}   /* #152: third level */
.entry .modal-steps{list-style:decimal;padding-left:22px;margin:0 0 10px}   /* #152: numbered steps */
.entry .modal-steps li{font-size:12.5px;color:var(--muted);line-height:1.5;margin-bottom:7px}
.entry .modal-steps strong{color:var(--ink)}
.entry .modal-steps ul{list-style:disc;padding-left:18px;margin:5px 0 0}
.entry .modal-steps ul li{margin-bottom:4px}
.entry .modal-bullets strong{color:var(--ink)}
.entry .modal-note{font-size:12px;color:var(--muted);line-height:1.55;margin:10px 2px 4px}
.entry .modal-note strong{color:var(--ink)}
/* #121: modal bullet lists — same muted note voice, tight bullets */
.entry .modal-list{font-size:12px;color:var(--muted);line-height:1.5;margin:8px 0 4px;padding-left:18px}
.entry .modal-list li{margin:3px 0}
.entry .modal-list strong{color:var(--ink)}
.entry .mono{font-family:var(--mono);font-size:12px;line-height:1.7;color:var(--muted);background:var(--workbg);
  border-radius:12px;padding:10px 12px;margin-bottom:12px;word-break:break-all}
.entry input,.entry textarea{width:100%;background:var(--workbg);border:1px solid var(--line);border-radius:12px;
  color:var(--ink);font-family:var(--mono);font-size:13px;padding:11px 12px}
.entry textarea{min-height:86px;resize:vertical}
.entry .err{color:var(--err);font-size:12px;min-height:30px;line-height:1.5;padding-top:6px}
.entry .go{width:100%;margin-top:6px;background:var(--card-blue);border:none;color:#fff;font-family:var(--ui);
  font-size:15px;padding:12px;border-radius:12px;cursor:pointer}
/* #121: secondary modal actions (Save as File, Show QR) stack full-width under the primary */
.entry .go2{display:block;width:100%;margin-top:8px;background:none;border:1px solid var(--line);color:var(--ink);
  font-family:var(--ui);font-size:14px;padding:10px;border-radius:12px;cursor:pointer}
.entry .go2:hover{border-color:var(--card-blue);background:var(--card-blue);color:#fff}   /* #195c (John's screenshot): white text with NO fill — invisible on the light papers, and a phone's tap leaves hover stuck, so "Preset when clicked" vanished on Buff.  The blue fill under the white is the same pair the primary button already wears on every theme. */
/* #121: the QR courier is computer-only — a phone has nothing to beam to */
@media (hover:none) and (pointer:coarse){.qr-courier{display:none}}
.entry .quiet{display:block;width:100%;margin-top:10px;text-align:center;background:none;border:none;cursor:pointer;
  color:var(--faint);font-size:12px}

/* suspected tokens (#42): below the list, red border, counted nowhere */
.row.suspect{border:1.5px solid #e5484d;border-radius:8px;padding:0 9px;margin:8px 0 2px}
.row-excl{font-size:11.5px;color:#e5484d;font-family:var(--sys)}

/* watched-address rows (#41): hidden = red border + the exclusion flag */
.addr-row{border:1.5px solid transparent;border-radius:8px;padding:7px 9px;margin-bottom:6px;background:var(--workbg)}
.addr-row.off{border-color:#e5484d}
.addr-line{display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap}   /* #184: the Preset chip wraps to its own row where the width isn't there */
.addr{font-family:var(--mono);font-size:12.5px;color:var(--ink);min-width:0;overflow-wrap:anywhere;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.addr-nick{font-family:var(--sys);color:var(--muted);margin-left:8px;font-size:12px}
.nick-btn{font-family:var(--sys);font-size:12px;color:var(--muted);background:none;border:none;border-bottom:1px dashed var(--chipline);cursor:pointer;padding:0 0 1px}
.nick-btn.unnamed{color:var(--faint);font-style:italic}
.addr-sub{font-family:var(--mono);font-size:11.5px;color:var(--muted);margin-bottom:6px}
.addr-row.editing{border-color:var(--card-blue)}
.nick-edit{flex:1;min-width:0;background:var(--card);border:1px solid var(--line);border-radius:8px;color:var(--ink);font-family:var(--sys);font-size:12.5px;padding:7px 9px}
.addr-left{display:flex;align-items:center;gap:8px;min-width:0}
.reorder{display:flex;flex-direction:column;gap:3px;flex-shrink:0}
.reord-btn{font-size:9px;line-height:1;color:var(--muted);background:var(--chipbg);border:1px solid var(--chipline);border-radius:5px;padding:3px 6px;cursor:pointer}
.reord-btn:disabled{opacity:.28;cursor:default}
.addr-actions{display:flex;gap:5px;flex:0 0 auto}   /* John 07-25 (#184): tighter gap — Preset · Hide · Delete share one line */
.addr-line > .addr-actions:only-child{margin-left:auto}   /* John 07-25: Save/Cancel keep the same right edge as every control pair */
.addr-btn{font-size:11px;font-family:var(--sys);color:var(--muted);background:var(--chipbg);border:1px solid var(--chipline);border-radius:8px;padding:3px 6px;cursor:pointer;white-space:nowrap}   /* #184: 8px→6px, "slightly tighter" — and a chip never wraps its own label */
.addr-flag{display:block;width:100%;text-align:left;margin-top:7px;color:#e5484d;background:rgba(229,72,77,.08);border:1px solid #e5484d;border-radius:8px;font-size:11.5px;line-height:1.45;padding:6px 9px;cursor:pointer;font-family:var(--sys)}
/* ---- #181: Presets — the ⅔/⅓ Settings row, the popup rows, the pickers ---- */
.menu-item.half.w23{flex:2}
.menu-item.half.w13{flex:1}
/* John 07-29: the two chain cards size to their own text and split what's left.
   min-width:max-content is what holds the line — the ✓ moves between the cards,
   so a fixed ratio can't fit both states at 375px; letting each card claim its
   content first does.  Tighter side padding buys the room. */
.menu-item.half.chain-pls, .menu-item.half.chain-eth{flex:1 1 auto;min-width:max-content;padding-left:8px;padding-right:8px}
.menu-item.half.wkeep{flex:1.8}   /* John 07-29: the keep-BluBox card takes the wider share — its longest label, "Place on the Home Screen", must sit on one line */
.pre-name{font-family:var(--sys);font-size:13px;color:var(--ink);background:none;border:none;cursor:pointer;text-align:left;padding:2px 0}
.pre-name .def{font-weight:400;color:var(--muted);font-size:11.5px}
.addr-row.pre-active{outline:1px solid var(--chipline);border-radius:8px}
/* John 07-25: paired buttons share one width; the affirmative (Edit, Save)
   reads slightly stronger than its neighbor (Delete, Cancel) */
.pm-edit,.pm-del,.pm-save,.pm-cancel{min-width:62px;text-align:center}
.pm-edit,.pm-save{color:var(--ink);border-color:var(--muted);font-weight:700}
/* John 07-25 (#184): the Preset chip joins Hide/Delete on the desk.  On a phone
   the line has no room for a fourth thing, so it keeps its old row beneath —
   and its old dashed-link look, undoing the .addr-btn chip it now shares. */
.addr-pre{order:3;flex:0 0 100%;margin-top:5px;text-align:left;overflow:hidden;text-overflow:ellipsis;
  color:var(--muted);background:none;border:none;border-radius:0;border-bottom:1px dashed var(--chipline);
  font-size:11.5px;line-height:1.45;padding:0 0 2px}
.addr-actions{order:2}
/* the desk has the room: the chip leaves its own row and joins Hide + Delete,
   margin-left:auto holding the trio together at the right edge.  This block
   sits AFTER the base rule on purpose — same specificity, so source order is
   what decides which one wins. */
@media (min-width:960px){
  .addr-pre{order:0;flex:0 0 auto;max-width:200px;margin:0 0 0 auto;   /* #184b: measured — the 600px row has ~244px spare here, so an 18-character preset name shows in full */
    background:var(--chipbg);border:1px solid var(--chipline);border-radius:8px;
    font-size:11px;line-height:normal;padding:3px 6px}
}
.addr-flag.soft{color:var(--muted);background:var(--chipbg);border-color:var(--chipline);cursor:default}
.pre-list{display:flex;flex-direction:column;gap:4px;margin:7px 0}
.pre-members{font-family:var(--sys);font-size:11.5px;color:var(--muted);line-height:1.55;margin:2px 0 5px 4px}
.pre-row{display:flex;align-items:center;gap:8px}
.pre-row .reorder{flex:0 0 auto}
.pm-ghost{display:inline-block;width:21px}   /* matches the measured ▲▼ column so every checkbox shares one left edge */
.pre-check{display:flex;align-items:center;justify-content:flex-start;gap:8px;font-family:var(--sys);font-size:12.5px;color:var(--ink);cursor:pointer;text-align:left}
.pre-check input{flex:0 0 auto;width:15px;height:15px;margin:0}
.pre-check .def{color:var(--muted);font-size:11px}
.pre-summary{display:block;width:100%;text-align:left;font-family:var(--sys);font-size:12.5px;color:var(--muted);background:var(--card);border:1px solid var(--line);border-radius:8px;padding:7px 9px;margin-top:6px;cursor:pointer}
#prePick{border:1px solid var(--line);border-radius:8px;padding:8px 9px;margin-top:5px}

.sampletag{text-align:center;font-size:11px;color:var(--faint);padding:8px 0 0;font-family:var(--mono)}

/* selection check marks are bold (#47); the alarm-area annotation stays plain */
.defck{font-weight:700}

/* #184 (John): back to top — desktop only.  Hidden until the page has actually
   scrolled, so it never sits on a screen with nothing above it. */
.totop{display:none}
@media (min-width:960px){
  .totop{display:flex;position:fixed;right:26px;bottom:26px;z-index:60;align-items:center;justify-content:center;
    width:44px;height:44px;border-radius:50%;cursor:pointer;
    background:var(--chipbg);border:1px solid var(--chipline);color:var(--muted);
    box-shadow:0 3px 14px rgba(0,0,0,.28)}
  .totop[hidden]{display:none}
  .totop:hover{color:var(--ink);border-color:var(--muted)}
}
/* address-change notice (#45) */
.notice{position:fixed;left:50%;transform:translateX(-50%);bottom:16px;z-index:70;width:calc(100% - 32px);max-width:420px;
  background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--card-blue);border-radius:16px;
  padding:12px 14px;box-shadow:0 2px 6px var(--shadow),0 10px 28px var(--shadow);font-size:12.5px;line-height:1.55;color:var(--muted)}
.notice.hidden{display:none}
.notice strong{display:block;color:var(--ink);font-size:13px;margin-bottom:3px}
.notice .notice-quote{display:block;margin-top:6px;font-style:italic;color:var(--ink)}
.notice-actions{display:flex;gap:10px;align-items:center;margin-top:9px}
.notice-actions .go2{background:var(--card-blue);border:none;color:#fff;font-family:var(--ui);font-size:12.5px;padding:7px 12px;border-radius:8px;cursor:pointer}
.notice-actions .quiet2{background:none;border:none;color:var(--faint);font-size:12px;cursor:pointer}


/* HEX-day complication, header center (#67): the watch face wears its own
   calendar — contract count, same number on both chains */
.hexday{position:absolute;left:50%;top:26px;transform:translate(-50%,-50%);
  font-family:var(--ui);font-size:13px;color:var(--ink);opacity:.95;
  border:1px solid var(--line);background:var(--surface);border-radius:8px;
  padding:3px 10px;font-variant-numeric:tabular-nums;cursor:pointer;white-space:nowrap}
.hexday b{font-weight:700;color:var(--daywait)}
.hexday.ok,.hexday.ok b{color:var(--dayok)}

/* Validators box (#69): rows on existing tokens; slashed wears --err */
.vals{display:flex;flex-direction:column;gap:8px;margin-top:8px}
.val-row{border:1px solid var(--rowline);border-radius:12px;padding:9px 11px;
  font-family:var(--ui);font-size:13.5px;color:var(--ink)}
.val-id{font-family:var(--mono);font-size:12px;color:var(--muted)}
.val-status{font-weight:700}
.val-status.slashed{color:var(--err)}
.val-bal{font-variant-numeric:tabular-nums}
.val-sub{font-size:12px;color:var(--muted);margin-top:2px}
.val-stale{color:var(--daywait)}
.val-fresh{color:var(--dayok)}   /* the chain vouched just now — same Blu as the Day */

/* John 07-29: the Token Prices board fence — Core PulseChain reads as one object.
   The side margins BLEED (−9px) exactly what the padding + border cost (8+1),
   so the rows inside keep the same width and x as the WALLET rows below —
   the fence line rides in the pane's gutter, and nothing pinches. */
.px-sect{border:1px solid var(--line);border-radius:12px;margin:2px -9px 10px;padding:0 8px 2px}
.px-sect-cap{font-family:var(--ui);font-size:14px;color:var(--title);text-align:center;padding:5px 0 3px;letter-spacing:.4px}   /* John 07-30: "Enlarge" — 11px → 14px, the plsfade voice */
/* #210q (John): the stamps live back in the seam's own hd-note — the original
   #196 seat, opaque and sticky.  PLS directly left of ETH, a tab of air
   between (#210o); the pair wraps right-aligned where the phone runs tight. */
.pxhead-note .hd-note{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:2px 32px;white-space:normal}
.pxhead-note .hd-note>span{white-space:nowrap}
/* #196: a board row's chart unfolds INLINE, full pane width (John: "in the
   dropdown, rather than a popup") — window rail, the line, its caption */
.bc-rail{display:flex;align-items:center;justify-content:center;gap:10px;margin:2px 0 8px}
.bc-svg{width:100%;height:auto;display:block}
.bc-line{font-size:10.5px;color:var(--muted);text-align:center;margin:8px 0 2px;font-family:var(--mono);line-height:1.4}
.bc-fold{cursor:default}

/* #196: the WALLET head's provenance note — small, right-justified, never uppercase */
.row-head.pxhead.pxhead-note, #app .row-head.pxhead.pxhead-note{grid-template-columns:max-content 1fr}
.row-head .hd-note{justify-self:end;align-self:end;text-align:right;text-transform:none;letter-spacing:0;font-weight:600;font-size:10px;color:var(--muted);white-space:nowrap;cursor:default}

/* #73: settings fence for the operator wing */
.menu-sect{border:1px solid var(--line);border-radius:12px;margin:6px 4px;padding:2px 2px 4px}
.menu-sect.sect-tight{margin:6px 2px;padding:2px 0 4px}   /* John 07-29: the Theme/Order fence gives its side room back — the full 12px cost wrapped "Buff" onto a second line at 375px */
.menu-sect-cap{font-family:var(--ui);font-size:11px;color:var(--title);text-align:center;padding:4px 0 2px;letter-spacing:.4px}   /* #102: amber */

/* #73: RPC weather complication — three gateway dots by the gear */
.wxdots{position:absolute;right:54px;top:26px;transform:translateY(-50%);
  display:flex;gap:5px;align-items:center;padding:6px;cursor:pointer;border-radius:8px}
.wxdots[hidden]{display:none}   /* #78: author display:flex beats the UA [hidden] rule — without this, Weather Off left gray dots painted */
/* #79: the chain row wears PulseChain's own fade — same stops as the #pls-grad logo gradient */
.plsfade{font-size:14.5px;   /* John 07-29: PulseChain RPC speaks 1px above the row */
  background:linear-gradient(to right,#00EAFF,#0080FF,#8000FF,#E619E6,#FF0000);
  -webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent}
.wxdots b{width:9px;height:9px;border-radius:50%;background:var(--dot)}
.wxdots b.blu{background:var(--dayok)}
.wxdots b.gold{background:var(--daywait)}
.wxdots b.red{background:var(--err)}

/* #73: the full-screen weather report (header chrome stays above) */
.wxscreen{position:fixed;left:0;right:0;bottom:0;top:56px;background:var(--page);z-index:40;
  overflow-y:auto;padding:10px 14px 20px}
.wxscreen.hidden{display:none}
.wxhead{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.wxtitle{font-family:var(--ui);font-size:17px;font-weight:700;color:var(--ink)}
.wxsub{font-size:12px;color:var(--muted);flex:1}
.wxsect{font-family:var(--ui);font-size:12px;color:var(--faint);letter-spacing:.4px;margin:12px 0 6px;text-transform:uppercase}
.wxrow{display:flex;align-items:center;gap:10px;border:1px solid var(--rowline);border-radius:12px;
  padding:9px 12px;margin-bottom:8px;font-family:var(--ui);font-size:13.5px;color:var(--ink)}
.wxrow b{width:10px;height:10px;border-radius:50%;background:var(--dot);flex-shrink:0}
.wxrow b.blu{background:var(--dayok)} .wxrow b.gold{background:var(--daywait)} .wxrow b.red{background:var(--err)}
.wxname{flex:1;font-family:var(--mono);font-size:12.5px}
.wxstat{font-variant-numeric:tabular-nums;color:var(--muted);font-size:12.5px}
.wxfoot{font-size:11.5px;color:var(--faint);margin-top:14px;line-height:1.5}
.wxref{font-size:11px;color:var(--faint);margin:-6px 2px 10px 32px;line-height:1.45}

/* #123 (John): the phone has no chart button — rotating the phone IS the
   chart toggle there. Desktop (hover + fine pointer) keeps the button. */
@media (hover: none) and (pointer: coarse){
  .charttoggle{display:none}
}
/* #123: the sideways face — the middle box's chart fills the screen; the
   overlay sits above everything and vanishes the moment the phone tilts back */
.landchart{position:fixed;inset:0;z-index:80;background:var(--page);display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:8px;
  padding:10px calc(16px + env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left))}
.landchart svg{width:100%;max-width:calc(72vh * 2.47);height:auto;display:block}
.lc-head{display:flex;align-items:center;gap:10px}
.lc-title{font-family:var(--ui);font-size:16px;color:var(--title)}
.lc-line{font-family:var(--ui);font-size:17px;color:var(--ink);text-align:center}
.lc-line.sky{color:var(--card-blue)}

/* #124 (John): the chart-scale segment on the Token Balances header —
   Price × Qty (the portfolio default) | Price (the unit price alone) */
.pxseg{display:inline-flex;gap:2px;vertical-align:middle;margin-left:8px;padding:2px;
  background:var(--chipbg);border:1px solid var(--chipline);border-radius:8px}
.pxseg button{border:0;background:transparent;color:var(--muted);font-size:10px;font-weight:700;
  font-family:var(--ui);letter-spacing:.02em;padding:3px 8px;border-radius:8px;cursor:pointer;white-space:nowrap}
.pxseg button.on{background:rgba(55,138,221,.22);color:#cfe4fa}

/* #128/#130 (John): the privacy curtain — Close BluBox folds the BluBox and
   the Hex Fade away. The button is the TRUE/FUTURE toggle's twin: same size,
   same Blu, same left rail of the middle box (which survives the curtain, so
   Restore always has a home). When TRUE/FUTURE is showing (#yield.vt-on),
   the two stack on the shared rail. */
.bbclose{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:52px;border-radius:12px;
  background:var(--card-blue);border:1px solid rgba(255,255,255,.35);cursor:pointer;padding:4px;z-index:6}
.bbclose .seg{display:flex;align-items:center;justify-content:center;min-height:20px;border-radius:9px;padding:6px 2px;font-size:9px;letter-spacing:.03em;
  font-weight:700;color:rgba(255,255,255,.9);line-height:1;font-family:var(--rounded)}   /* #159 (John): flex-centered so the label doesn't drift in the pill at Cmd+/- zoom */
.bbclose .seg + .seg{margin-top:3px}
/* #131 (John): Close lives ON the BluBox card (left rail, every lens — the
   lensrail's mirror); while the curtain is drawn the card is gone and
   #bbRestore takes the TRUE/FUTURE slot on the middle box. */
.card .bbclose{left:10px}
.card.ca-on .bbclose{top:20px;transform:none}   /* #182: on the extended Included Addresses face the centered pill would sit ON the rows */
.card.ca-on .card-value{display:none}   /* #182-3 (John): no big Total here — that is the front page's detail; this face is the split */
#cardAddrs .ca-addr{font-family:var(--mono);font-size:13.5px;opacity:.75;margin-left:8px}   /* #182-2: the address rides beside the nick on desktop */
@media (hover:none) and (pointer:coarse){#cardAddrs .ca-addr{display:none}}   /* touch keeps the tight row */
/* #188 (John, 2026-07-26): "show the whole address — this will require adjusting
   the distance between existing columns."  All 42 characters print at 351px in
   this mono face (measured), so the desktop list widens from 400 to 660 and the
   row becomes three columns: nick | whole address | value.  The address column
   right-aligns inside the name cell and the value cell takes a fixed width, so
   the three columns line up DOWN the list however long the nicks are.  Touch is
   untouched — .ca-addr is display:none there and the row keeps its tight pair. */
@media (min-width:960px){
  #cardAddrs{max-width:660px}
  #cardAddrs .ca-row{gap:18px}
  #cardAddrs .ca-name{display:flex;align-items:baseline;gap:12px;flex:1;overflow:visible}
  #cardAddrs .ca-nick{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
  #cardAddrs .ca-nick.ca-fb{display:none}   /* unnicked: the abbreviation is the TOUCH name only — the whole address speaks here */
  #cardAddrs .ca-addr{margin:0 0 0 auto;white-space:nowrap;flex:0 0 auto}
  #cardAddrs .ca-usd{min-width:116px;text-align:right}
}
body.bb-closed .card, body.bb-closed .rankwrap{display:none}
/* ---- #218 (John, 2026-08-01): "There needs to be a way to hide the Value card.
   It's nice to see at a glance, but when looking at Balances with dropdowns, it
   takes too much space."  This is NOT the Hide BluBox curtain above — that one
   is a privacy gesture, it takes the Rank with it, and it can carry an unlock
   code.  This is room: one Settings toggle, remembered, and the Rank stays.
   SCREEN ONLY — on paper the print presets already decide what the sheet
   carries (#209's four), and a screen preference must not rewrite a preset.

   ⚠️ #222 (John, 2026-08-02): "The BluBox card is gone, not the Value card.  The
   BluBox card scrolls away, so that is fine the way it was."  #218 aimed at
   `.card` — the blue Total Wallet card — which is the BLUBOX card, not this
   one.  The Value Card is #yield: the box whose title becomes "<the row you
   tapped> Value" and whose figure is that row's worth ("LP HEX⇆HTT-5000 =
   $750").  Re-aimed, and the Total Wallet card is untouched again.

   `:not(.bb-closed)` is LOAD-BEARING, not tidiness: Restore BluBox lives INSIDE
   #yield (#131 put it there deliberately — the card it restores is hidden, so
   its own control cannot ride on it).  Hiding this box while the curtain is
   drawn would take the only way back with it, and a control the user cannot see
   is one this app does not ship.  So while BluBox is hidden, the Value Card
   stays regardless of this setting.
   Safe on the Prices view: that board is #pane, a different element. ---- */
@media screen { body.novalcard:not(.bb-closed) #yield{display:none} }
.modal-code{display:block;width:100%;margin:10px 0;background:var(--btn);border:1px solid var(--btnline);
  border-radius:8px;color:var(--ink);font-size:15px;padding:10px 11px;font-family:var(--mono)}

/* #141 (John): the curtain's prompt line — smaller, plain Arial Bold (the
   value lines wear Arial ROUNDED Bold; the straight face marks instruction) */
.yield-line.prompt{font-family:Arial,Helvetica,sans-serif;font-weight:700;font-size:14px;color:var(--muted)}

/* #142: the landscape day-range pill — the portrait pill's twin */
.landchart .lc-rail{display:inline-flex;align-items:center;gap:2px;background:var(--chipbg);
  border:1px solid var(--chipline);border-radius:12px;padding:0 3px;height:24px}
.landchart .lc-rail .cbtn{background:none;border:0;width:36px;height:20px;color:var(--ink)}
.landchart .lc-dots{display:flex;gap:3px;padding:0 3px}
.landchart .lc-dots b{width:6px;height:6px;border-radius:50%;background:var(--dot)}
.landchart .lc-dots b.on{background:var(--doton)}

/* BluBox-Vault (2026-07-22): the phone's front door. Opaque — the empty-booted
   app behind it never reads. .entry supplies the card; the container centers it. */
#vaultGate{position:fixed;inset:0;z-index:120;background:var(--page);display:flex;
  align-items:flex-start;justify-content:center;overflow:auto;padding:46px 20px 20px}
.entry ul.sub{margin-left:16px}   /* the "which method locks it" sub-bullets */
#setVault{color:var(--gold)}   /* John's ruling: the Vault label wears amber — the row must catch the eye */
.chain-ico{width:15px;height:15px;display:inline-block;vertical-align:-3px;margin-right:4px}   /* chain-row logos (2026-07-22): real marks at row size */   /* John 07-29: both marks up 1px */
.chain-ico-eth{width:9.6px}   /* the diamond is tall — narrow box keeps it visually level with the pulse hex (width tracks the 1px height bump) */
.menu-item[hidden]{display:none}   /* .menu-item's display:block was beating the hidden attribute — the Vault row leaked onto desktop */

/* Rung-1 Welcome face (2026-07-22): the Price card's once-per-session greeting.
   Straight Arial Bold marks instruction (the #141 convention); the mono path
   wears card-blue so the checkable thing is the visually distinct thing. */
.greet{padding:14px 6px 10px;text-align:center;margin:0 calc(15px - 56px) 0 calc(15px - 72px)}   /* same rail-padding compensation as the head — the message centers on the CARD */
.greet-main{font-family:Arial,Helvetica,sans-serif;font-weight:700;font-size:17px;color:var(--ink);line-height:1.55}
.greet-main .greet-addr{display:block;font-family:var(--mono);font-size:15px;color:var(--card-blue);margin-bottom:2px}   /* its own line, no underline — a signpost, not a door (John): nothing detours the balance-seeker */
.greet-tap{font-family:Arial,Helvetica,sans-serif;font-weight:700;font-size:15px;color:var(--gold);margin-top:12px}   /* John: the main action wears amber, 1px up from the ink pass */

/* Dormant open (John's rulings 2026-07-22): until the wallet awakens, every value
   is BLANK — visibility keeps the layout steady while nothing personal reads.
   A veil, not $0: zero is a false number and the load-failure symptom. Visual
   only — the chain reads continue underneath, so awakening is instant. */
body.bb-dormant #yield .head-right{display:none}   /* the empty control cluster kept Welcome off-center */
body.bb-dormant #yield .box-head{margin:0 calc(15px - 56px) 0 calc(15px - 72px)}   /* the box pads 72/56 for its rails; symmetric 15px gaps truly center Welcome */
/* John's blessing ("awesome as the opening look"): the veiled cards COLLAPSE —
   a slim true-blue bar, the fade frame holding only the logo — while the token
   pane keeps its tall frame, an empty space promising nothing. */
body.bb-dormant .card-title,body.bb-dormant .rank-title,body.bb-dormant #paneTitle,
body.bb-dormant .card-value,body.bb-dormant .card-foot,
body.bb-dormant .lensrail,body.bb-dormant .lensdots,body.bb-dormant .bbclose,
body.bb-dormant .rank-cols,body.bb-dormant .rankdots,body.bb-dormant .rank-chartwrap,
body.bb-dormant #cardAddrs{display:none}   /* #182: the address list sleeps under the dormant veil like the rest of the card */
body.bb-dormant #paneBody,body.bb-dormant #pane .cluster,
body.bb-dormant #pane .timerlock,body.bb-dormant #pane .searchlock,body.bb-dormant #pane .cbtn{visibility:hidden}   /* #210: the spyglass sleeps with the rail */
.work ul{margin:0;padding-left:16px;list-style:disc}   /* #151 (John): Show Work reads as bullets */
.work li{margin:3px 0}
/* #186 (John): the "= total" line is the CONCLUSION of the line above it, not
   another item — "needs an indent and no bullet".  So: no marker, indented past
   the bullet text, and a hanging indent so a long total wraps under its own "="
   instead of running back to the margin. */
.work li.wl-total{list-style:none;margin-left:12px;padding-left:14px;text-indent:-14px}
/* ---------- #189 (John): the LPX pool CARD.  DESKTOP ONLY ("This can be desktop
   only") — the card and the bullets both render, and width picks one, the same
   two-homes pattern #169n uses for the month legend.  Under 960px nothing here
   applies and the phone fold is byte-for-byte what it was.

   ⚠️ #234 (John, 2026-08-02): "Printing the Balance page in detail does not show
   the PlusX dropdown."  It could not: LETTER IS 816px, under this 960px bar, so
   on paper the whole block below never applied — the card stayed display:none
   and the PHONE bullets printed in its place.  The #188 note further down had
   already written that sentence about #cardAddrs and nobody carried the lesson
   here.  `, print` is the whole fix: paper gets the card and loses the bullets,
   exactly like the desk.  The width suits it — the fold is ~806px on screen and
   the card lays out at ~775px, which is what a Letter page gives it too. ---------- */
.lpxcard{display:none}
@media (min-width:960px), print{
  #app .work.haslpx > ul{display:none}          /* on the desk the card IS the fold */
  #app .work.haslpx .lpxcard{display:block}
  .lpxcard{font-family:var(--sys);font-size:12.5px;line-height:1.5;color:var(--ink)}
  /* ONE grid for the card's DATA — sections and rows are display:contents, so
     every line's label / quantity / value land in the same three columns and
     all three size themselves to their own widest entry.  Fixed tracks would
     have been a guess: a 253,629,903.3808 PRVX side is real, and a bigger one
     overflowed into the column beside it.
     #189b (John): `width:max-content` is the whole ruling — the block stops at
     its own content instead of stretching to the fold, so a label sits a gap
     away from its number rather than a column away. */
  /* #218: the LABEL column is `auto`, not max-content — under the two-track grid
     below this block gives way before the history does, and a squeezed label
     must WRAP (auto's floor is min-content) rather than push its own figures out
     of the box.  The two number columns stay max-content: a wrapped figure is
     unreadable.
     ⚠️ TWO measured dead ends on the way here, both worth not repeating:
     `minmax(0,max-content)` resolved the label column to 0px and blew the two
     number columns to 371px each — a 0 min never grows back under negative free
     space.  And `width:max-content` on the box fought the same battle from the
     other side.  #189b's ruling survives both: the width now comes from the
     TRACK, which is itself max-content whenever the card has room, so the block
     still stops at its own content — it only yields when the history needs its
     floor. */
  .lpxcard .lx-body{display:grid;grid-template-columns:auto max-content max-content;
    column-gap:22px;width:100%;max-width:100%}
  .lpxcard .lx-sec,.lpxcard .lx-row{display:contents}
  /* ⚠️ #218: PROSE MUST NOT SIZE THE COLUMNS.  MEASURED on a live-shaped card —
     the two notes and the gauge's caption carry 470–800px of max-content each,
     and as full-row grid items they grew this block's three tracks to 787px
     inside a 377px box: the Value column landed 65px INSIDE the Position History
     pane beside it.  #197's flex-wrap hid the defect rather than fixing it —
     the history simply wrapped away and handed the left block the whole card,
     which is exactly the inconsistency John is asking us to remove.
     width:0 + min-width:100% is the standard escape: the item contributes
     nothing to intrinsic track sizing and still renders across the full row. */
  .lpxcard .lx-body .lx-note,.lpxcard .lx-body .lx-gauge,
  .lpxcard .lx-body .lx-h{width:0;min-width:100%}
  /* the head carries the three facts the collapsed row also shows — kept here
     because the fold has to stand on its own when it is what you are reading */
  .lpxcard .lx-head{grid-column:1/-1;display:flex;align-items:baseline;gap:12px;
    padding-bottom:6px;margin-bottom:2px;border-bottom:1px solid var(--line)}
  .lpxcard .lx-pool{font-family:var(--ui);font-size:15px}
  .lpxcard .lx-pair{font-family:var(--ui);font-size:15px;color:var(--muted)}
  .lpxcard .lx-share{margin-left:auto;font-variant-numeric:tabular-nums}
  .lpxcard .lx-h{grid-column:1/-1;display:flex;align-items:baseline;gap:10px;font-weight:700;margin:8px 0 3px}
  .lpxcard .lx-sub{font-weight:400;color:var(--muted);font-size:11.5px}   /* the NTZ caption rides its header */
  .lpxcard .lx-k,.lpxcard .lx-q,.lpxcard .lx-v{padding:1px 0;font-variant-numeric:tabular-nums}
  .lpxcard .lx-q,.lpxcard .lx-v{text-align:right;white-space:nowrap}
  /* display:contents leaves a row with no box of its own, so a total's rule is
     its own full-width element rather than a border that would break at the gaps */
  .lpxcard .lx-rule{grid-column:1/-1;border-top:1px solid var(--rowline);margin:3px 0 2px}
  .lpxcard .lx-rule-foot{margin-top:9px}
  .lpxcard .lx-tot .lx-k,.lpxcard .lx-tot .lx-v{font-weight:700}
  .lpxcard .lx-spot .lx-k,.lpxcard .lx-spot .lx-v{font-weight:700}   /* Price is the one the eye hunts for; the four zone bounds frame it */
  .lpxcard .lx-wall .lx-k,.lpxcard .lx-wall .lx-v{font-weight:700}   /* #197f (John): the WALLS bold too — he read Sell as Max Sell; the stale boundaries must not dress like the NTZ band */
  /* #215: "Run by you" is the one word on this card that changes what every
     number below it means — your own pool has no manager taking a joiner's fee.
     It reads bold; someone else's manager reads as a plain address, because an
     address is all we can honestly say about them. */
  .lpxcard .lx-mine .lx-v,.lpxcard .lx-you{font-weight:700}
  /* the market comparison sits a half-step back from the five prices — it
     ANNOTATES the Price line rather than joining the zone it describes */
  .lpxcard .lx-mkt .lx-k{color:var(--muted)}
  .lpxcard .lx-far .lx-k,.lpxcard .lx-far .lx-v{color:var(--err);font-weight:700}   /* 2x or more from our own price — the zone has been left behind */
  /* #189d (John): two zones — the position as it stands on the left, how it got
     there on the right.  The left keeps its max-content width so labels stay
     beside their figures; the right takes whatever is left and has room to grow
     into, which is what John asked the width to be spent on. */
  /* #218 (John: "make the row show the Position History beside the Held in
     Wallet column.  It is in some pools and not in others"): #197's flex-wrap
     dropped the history BELOW the position whenever less than ~300px remained
     beside it — and that width is set by the left block's own content, so the
     same card read one way on one pool and another way on the next.  Two grid
     tracks settle it: the history track keeps a 300px floor and the position
     track gives way first (its labels wrap).  #197's actual guarantee still
     holds below — the hrow's shrinkable columns and this pane's overflow:hidden
     are what keep the Value column inside the card.
     The second track is declared only on .lx-2col, which the card adds when a
     history exists — a card without one must not reserve 300px of empty air. */
  .lpxcard .lx-cols{display:grid;grid-template-columns:minmax(0,max-content);align-items:start;gap:18px}
  /* the floor is 404px, not #197's 300: with each side now carrying its dollars
     under its count, 300px left the two number columns ~54px and every
     303,928,631 in them ellipsised away.  #219 raised it again — bolding the
     Now row (John) widened a 12-character count past the 83px that 380px
     bought, and it ellipsised to "301,500,0…".  MEASURED: 404px puts ~95px in
     each number column, which clears a BOLD 12-character count, and still
     leaves the position block ~353px — above the gauge's ~280px of labels.
     The pair needs ~700px of card to sit side by side without the position
     block spilling.  MEASURED: the fold's parent is a FIXED 806px at every
     desktop width (960 and 1280 both), so the card is ~775px always — there is
     no reachable width where this floor bites. */
  .lpxcard .lx-cols.lx-2col{grid-template-columns:minmax(0,auto) minmax(404px,1fr)}
  .lpxcard .lx-hist{min-width:0;border-left:1px solid var(--rowline);padding-left:16px}
  /* #190: the wallet label takes the label AND quantity columns.  Sized into
     column 1 it would set that column's max-content width — a label carrying an
     address, a nickname AND a preset is ~210px, which came straight out of the
     history zone's number columns. */
  .lpxcard .lx-held .lx-k{grid-column:1/3;font-weight:700}   /* #197d (John): the wallet identity speaks bold */
  .lpxcard .lx-held .lx-q{display:none}
  .det-ceil{font-weight:700;font-size:1.15em}   /* #197c (John): the visible row's "XX% of Max Sell" speaks bold, a step larger */
  .det-ceil.det-hot{color:var(--err)}   /* #197h (John): red within 20% of either wall — the same band the gauge marker wears */
  .lpxcard .lx-hist .lx-h{margin-top:0}
  .lpxcard .lx-hnote{color:var(--muted);padding-left:14px;text-indent:-14px}
  /* #197 (John's screenshot): FIXED columns cannot shrink, and on a narrower
     desk the left zone left this grid less than its 196px of fixed mins — the
     Value column fell off the card's right edge.  Every column now has a
     shrinkable floor; the two quantity columns give way first (ellipsis),
     the Value column never leaves the card. */
  .lpxcard .lx-hrow{display:grid;grid-template-columns:minmax(62px,72px) minmax(40px,52px) minmax(0,1fr) minmax(0,1fr) minmax(50px,max-content);
    gap:6px;font-variant-numeric:tabular-nums;padding:1px 0}
  .lpxcard .lx-hist{overflow:hidden}
  /* an ISO date breaks at its own hyphens if left to wrap — width alone is not the fix */
  .lpxcard .lx-hd,.lpxcard .lx-hm{white-space:nowrap}
  .lpxcard .lx-hsum .lx-hd,.lpxcard .lx-hil .lx-hd{white-space:normal}
  .lpxcard .lx-hf,.lpxcard .lx-ha,.lpxcard .lx-hv{text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* #218: the second line inside a summary cell — the side's DOLLARS under its
     count, and the growth percent under its quantity.  A step back in ink and
     size so the count still leads; the cell keeps one text-align and one
     column, so the two lines stay stacked on the same right edge. */
  /* #219 (John): "Make the dollar amounts below the token Qty … the same font
     size as the token Qty."  The 11.5px step-down is gone — the second line is
     a figure the reader compares across columns, not a caption.  Only the ink
     steps back now, and it inherits weight so a bolded row bolds both lines. */
  .lpxcard .lx-hu{display:block;color:var(--muted)}
  /* two lines need room to be two lines — the clip guard (#197) stays on, and it
     is no longer what cuts the growth percent off: the percent has its own line. */
  .lpxcard .lx-hsum .lx-hf,.lpxcard .lx-hsum .lx-ha,
  .lpxcard .lx-hgrow .lx-hf,.lpxcard .lx-hgrow .lx-ha{line-height:1.35;padding-bottom:2px}
  .lpxcard .lx-hhead{color:var(--muted);font-weight:700}
  .lpxcard .lx-hhead .lx-hf,.lpxcard .lx-hhead .lx-ha,.lpxcard .lx-hhead .lx-hv{color:var(--ink)}
  /* #189e: the verdict — did the pool beat holding?  It is the line the eye
     should land on, so it reads bold and takes the good/bad ink the app already
     uses for a gain and a loss. */
  .lpxcard .lx-hil span{font-weight:700}
  /* #197c (John): the WHOLE verdict row wears its color — BluBox blue for a
     gain (his call, over the app's green), red for a loss */
  .lpxcard .lx-hil.lx-up span,.lpxcard .lx-h12.lx-up span{color:var(--card-blue)}
  .lpxcard .lx-hil.lx-down span,.lpxcard .lx-h12.lx-down span{color:var(--err)}
  /* #218: the 12-month PACE takes the verdict's shape and its ink.  #219 (John)
     re-ruled the weight — it reads BOLD, the same as the verdict it paces: he
     asked for the line, so it is not a footnote to the line above it. */
  .lpxcard .lx-h12 .lx-hd{grid-column:1/4;white-space:normal}
  .lpxcard .lx-h12 .lx-hm,.lpxcard .lx-h12 .lx-hf{display:none}
  .lpxcard .lx-h12 span{font-weight:700}
  /* #219 (John): "Make the row 'Now…' Bold" — label, both counts, both dollar
     lines and the total.  It is the row the whole ledger settles into. */
  .lpxcard .lx-hnow span{font-weight:700}
  .lpxcard .lx-hnow .lx-hu{color:var(--ink)}
  /* #219 (John): "Make the titles and numbers in Your Position Bold." */
  .lpxcard .lx-pos .lx-k,.lpxcard .lx-pos .lx-q,.lpxcard .lx-pos .lx-v{font-weight:700}
  /* ---- #219 (John): "Add the math you used to calculate the loss/gain and 12 mo
     pace.  Show Work."  The #50 law rules the shape — bullets, system sans,
     12.5px, full ink, never mono and never muted.  The arithmetic line under
     each bullet is the one indent, so the claim and its working read apart. ---- */
  .lpxcard .lx-hwork{margin-top:8px;border-top:1px solid var(--rowline);padding-top:6px}
  .lpxcard .lx-wh{font-weight:700;margin-bottom:3px}
  .lpxcard .lx-hwork ul{margin:0;padding-left:15px}
  .lpxcard .lx-hwork li{margin:0 0 4px}
  .lpxcard .lx-wm{display:block;font-variant-numeric:tabular-nums}
  /* the verdict's label takes the three left columns; its percent lands in the
     anchor column and its dollars in the Value column, so it lines up with the
     two figures it is the difference of */
  .lpxcard .lx-hil .lx-hd{grid-column:1/4}
  .lpxcard .lx-hil .lx-hm,.lpxcard .lx-hil .lx-hf{display:none}
  .lpxcard .lx-hist .lx-hnote{margin-top:4px;font-size:11.5px}
  /* a 59-move position is the longest measured — it scrolls in place rather than
     growing the card and re-entering the #188p/#188u sticky problems */
  .lpxcard .lx-hscroll{max-height:132px;overflow-y:auto}
  .lpxcard .lx-wdr .lx-hm{color:var(--err)}
  .lpxcard .lx-hist .lx-rule{margin:4px 0 3px}
  /* a summary line has no Move, so its label takes both label columns — otherwise
     "Qty Growth from LPX" wraps inside an 80px Date column */
  .lpxcard .lx-hsum .lx-hd,.lpxcard .lx-hgrow .lx-hd{grid-column:1/3;font-weight:700}
  .lpxcard .lx-hsum .lx-hm,.lpxcard .lx-hgrow .lx-hm{display:none}
  .lpxcard .lx-hgrow{margin-top:3px}
  .lpxcard .lx-hgrow .lx-hf,.lpxcard .lx-hgrow .lx-ha{font-weight:700}
  /* #197: the ceiling gauge — Price between the floor and Max Sell, log-scaled.
     grid-column 1/-1 is LOAD-BEARING: as a plain child of the display:contents
     section it landed in COLUMN 1 of the left grid, and its ~280px of labels
     blew the label column to ~500px — John: "I like the left pane closer to
     the labels, like the previous load."  Spanning the row keeps column 1
     label-sized; the width cap keeps the gauge from stretching the card. */
  /* #197e (John): the bar runs the full section, to the divider — width:0 +
     min-width:100% makes it FILL the zone without CONTRIBUTING to the
     max-content width (the 250px cap solved the stretch by shrinking the bar,
     which put the marker's third-of-the-way on a bar that wasn't the space). */
  .lpxcard .lx-gauge{grid-column:1/-1;margin-top:7px;width:0;min-width:100%}
  .lpxcard .lx-gtrack{position:relative;height:6px;border-radius:3px;background:var(--chipbg);border:1px solid var(--chipline)}
  .lpxcard .lx-gtrack i{position:absolute;top:-3px;width:2.5px;height:12px;border-radius:2px;background:var(--card-blue);transform:translateX(-50%)}
  .lpxcard .lx-stale .lx-gtrack i,.lpxcard .lx-near .lx-gtrack i{background:var(--err)}   /* #197c: red within 20% of either wall */
  .lpxcard .lx-glbl{display:flex;justify-content:space-between;font-size:10px;color:var(--muted);margin-top:3px;gap:6px}
  .lpxcard .lx-glbl span{font-weight:700}   /* #197d (John): all three labels bold */
  .lpxcard .lx-glbl span:nth-child(2){color:var(--ink)}
  .lpxcard .lx-stale .lx-glbl span:nth-child(2){color:var(--err)}
  .lpxcard .lx-gnote{font-size:10.5px;color:var(--muted);margin-top:3px}
  .lpxcard .lx-stale .lx-gnote{color:var(--err);font-weight:600}
  .lpxcard .lx-note,.lpxcard .lx-foot{grid-column:1/-1}
  .lpxcard .lx-note{color:var(--muted);margin-top:3px}
  .lpxcard .lx-foot{color:var(--muted);margin-top:5px;padding-left:14px;text-indent:-14px}   /* hanging, like every other wrapped line in the app */
  .lpxcard .lx-warn{color:var(--ink)}   /* the trust caveat is never a footnote grey */
}
/* #160d (John): each HSI's field lines indent one level under their 'HSI #x' head */
.wl-sub{margin-left:22px}
/* #188h (John): "insert a tab space after Extracted" — a real tab collapses in
   HTML, so the gap is an inline-block of fixed width.  Wide enough to read as a
   deliberate column break, not an accidental double space. */
.wl-tab{display:inline-block;width:26px}
/* #167 (John): the HSI sort control — two toggles above HSI #1 */
.hsisort{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 16px;margin:5px 0 7px}
.hsisort-lbl{font-size:11px;color:var(--faint);text-transform:uppercase;letter-spacing:.03em}
.hsisort-btn{cursor:pointer;color:var(--muted);white-space:nowrap;user-select:none;font-weight:700}
.hsisort-btn:hover{color:var(--ink)}
.hsisort-btn.on{color:var(--card-blue)}
html.light .hsisort-btn.on{color:#164a88}   /* #161: readable on light paper */
/* #169d (John): Transactions age legend — 6-over-6 BRICK WALL of tinted cards.
   13 columns; each card spans 2, the bottom row starts at col 2 → offset half a card. */
/* #199c: the legend holds a VARIABLE set now — Last 31-Days + only the months
   that exist + the pagers — so #169g's rigid 15-column brick (built for
   exactly fourteen fixed cards) gives way to content-sized chips that wrap
   into their own brick.  Same cap, same centering, same tint grammar. */
.tx-legend{display:flex;flex-wrap:wrap;gap:4px;justify-content:center;padding:2px 5px 9px;margin:0 auto 4px;max-width:377px;border-bottom:1.5px solid var(--line)}
/* John 2026-08-03: the month legend STICKS — it is the page's navigation, and on a
   352-move card switching months meant scrolling all the way back up.  It pins on
   the --legstick line layoutSticky computes (under the box-head, clearing the
   hanging Sort/Search chips below 960), and the column heads re-anchor beneath it.
   Opaque surface so the rows pass under, z below the rail's chips (18) and the
   box-head, above the rows. */
.tx-legend--body{position:sticky;top:var(--legstick,0);z-index:15;background:var(--surface);
  max-width:none;padding-top:var(--legpad,2px);margin-bottom:0;padding-bottom:13px}   /* the at-rest 4px margin-bottom was a TRANSPARENT band — row text ghosted through it while pinned; it folds into opaque padding (9+4) */   /* full pane width — a 377px box let rows slide visibly past its flanks when pinned;
  the top padding is measured by layoutSticky to absorb the chip band below 960, so no see-through seam opens above the pinned legend */
/* #210c (John: "the month buttons on the TXNs page overlap"): the #169h/#169n
   header home is RETIRED — its premise was free middle space in the band, and
   the #209/#210 rail (letter cards + Search + Sort + Timer Lock) owns that
   band now.  ONE home at every width: the body copy, above the column heading.
   Below 960 the Search/Sort seats hang at top:42 into the body's first inches,
   so the legend steps clear of them there. */
@media (max-width:959px){ .tx-legend--body{margin-top:34px} }
.txleg{border-radius:5px;padding:3px 7px;text-align:center;font-size:9px;font-weight:600;cursor:pointer;
  color:var(--ink);white-space:nowrap;
  background:hsla(210,72%,52%,calc(0.30 - var(--n) * 0.020));border:1px solid hsla(210,55%,50%,.22)}   /* single-hue tint, newest month darkest (theme-safe: tint over surface, ink text) */
/* #180 (John): the All card resets the ledger to every date. It leads the brick so the
   way OUT of a filter reads before the filters, and wears no --n tint — it is not a month. */
.txleg-all{background:transparent;border-style:dashed;font-weight:700}
.txleg-all.on{background:hsla(210,72%,52%,.30);border-style:solid}
.txleg.on{border-color:var(--ink);box-shadow:0 0 0 1px var(--ink);font-weight:700}   /* #169j (John): the month being filtered — an ink ring on the lit card */
/* #169k (John): the ledger column heading — mirrors .row-head (bold, uppercase, faint, ruled) */
.tx-head{display:flex;justify-content:space-between;align-items:baseline;padding:2px 0 6px;margin-top:-2px;
  font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--faint);border-bottom:1.5px solid var(--line)}
/* #210e (John): "All cards, make Column headers sticky" — every column head
   stops at the line layoutSticky publishes (one under the box-head) and rides
   there while its own list scrolls; a head inside a by-wallet card sticks
   within that card's bounds, so the next card's head takes over naturally.
   Opaque surface so rows never show through; under the box-head (17) and
   rail (18), over the rows. */
#pane .row-head, #pane .tx-head{position:sticky;top:var(--colstick,52px);z-index:16;background:var(--surface)}
.tx-none{padding:18px 12px;text-align:center;color:var(--muted);font-size:13px}   /* #169j: empty state when a month has no transactions */
.entry a{color:var(--card-blue);text-underline-offset:2px}   /* modal links wear the house blue — never the browser's visited-purple */

/* #159 (John, 2026-07-23): PRINT — white paper, dark ink, no line split across a
   page. Three presets scope what prints via a body class (printChooser/doPrint). */
#printPresets{display:none}   /* the presets print sheet exists only for the printer */

@media print {
  @page { margin: 12mm; }
  html, body { background: #fff !important; }
  /* preset: PRESET GLOBAL VIEW — the roll call alone, ink on white (John 07-25) */
  body.print-presets #app, body.print-presets .sampletag { display: none !important; }
  body.print-presets::before, body.print-presets::after { display: none !important; }   /* the phone-frame dressing never prints */
  body.print-presets #printPresets { display: block !important; font-family: var(--sys); }
  body.print-presets #printPresets, body.print-presets #printPresets * { color: #111 !important; text-shadow: none !important; }   /* ink, not theme green */
  #printPresets h1 { font-size: 18px; margin: 0 0 12px; }
  #printPresets .pp-group { break-inside: avoid; page-break-inside: avoid; margin: 0 0 12px; }
  #printPresets .pp-name { font-weight: 700; font-size: 14px; margin: 0 0 3px; }
  #printPresets .pp-addr { font-size: 12px; line-height: 1.6; margin-left: 14px; }
  #printPresets .modal-bullets { font-size: 12px; line-height: 1.55; margin: 0 0 14px; break-inside: avoid; }
  /* strip the phone frame; dark ink everywhere */
  #app { width: auto !important; max-width: 100% !important; margin: 0 !important; padding: 0 !important;
    background: #fff !important; border: 0 !important; border-radius: 0 !important; box-shadow: none !important; }
  #app::before, #app::after { display: none !important; }
  #app, #app * { color: #111 !important; text-shadow: none !important; -webkit-print-color-adjust: exact; }
  /* #159 (John): sticky headers print in normal flow — otherwise the "Token Balances"
     title renders where it was stuck (mid-page) instead of atop the ledger */
  .apphead, #yield, #pane, #pane .box-head, .box-head, .pane-stick { position: static !important; top: auto !important; }
  #pane .box-head, .box-head { background: transparent !important; }   /* no grey band on paper */
  /* cards → white with a hairline rule, no gradients/shadows */
  .card, .rankwrap, #yield, #pane, .box, .rank {
    background: #fff !important; border: 1px solid #bbb !important; box-shadow: none !important;
    border-radius: 8px !important; margin: 0 0 10px !important; }
  .rankwrap { padding: 10px !important; }
  /* interface chrome drops away */
  .apphead, .dropdown, .lensrail, .pricerail, .lensdots, .rankdots, .dots,
  .bbclose, .valtoggle, .charttoggle, #chartToggle, .workaff, .workaff-row,
  .pane-print, .pane-stick, .timerlock, .grouplock, .searchlock, .head-right, #wxScreen, .wxdots, .chev, .totop { display: none !important; }   /* .chev: the ▸/▾ expander is a screen cue — never ink (#169o) */
  /* never split a card / row / line across a page break */
  .card, .rankwrap, #yield, .box, .row, .row-head { break-inside: avoid; page-break-inside: avoid; }
  /* #208 (John 07-30): a wallet card MAY break between rows — but its header
     never sits orphaned at a page's foot with the first row overleaf */
  .txw-grid { display: block; }
  .wcard { break-inside: auto; page-break-inside: auto; }
  .wcard-head { break-inside: avoid; break-after: avoid; page-break-after: avoid; }
  /* the ledger prints every row EXPANDED — the full detail box, on white */
  .row .work { display: block !important; background: #fff !important; border-left: 2px solid #999 !important;
    border-radius: 0 !important; padding: 4px 0 6px 10px !important; margin: 2px 0 4px !important; }
  /* #159 (John): the expandable-tab bar is a screen cue — on paper it's just wasted ink */
  .row.expandable::before { display: none !important; }
  /* #169n: the month legend + row tints are screen cues — on paper the date column already says the month, so the blue would be wasted ink (tints ride inline styles; !important outranks them) */
  .tx-legend { display: none !important; }
  .row-line { background: none !important; }

  /* preset: THIS PAGE — the cards, no ledger */
  body.print-page #pane, body.print-page .sampletag { display: none !important; }
  /* preset: ADDRESS LIST WITH VALUE TOTALS (#182, John) — the Included
     Addresses card alone, its Show Work breakdown expanded on paper */
  body.print-addrs .rankwrap, body.print-addrs #yield, body.print-addrs #pane,
  body.print-addrs .sampletag { display: none !important; }
  body.print-addrs #cardWork { display: block !important; }
  body.print-addrs #cardAddrs { margin-top: 12px; }   /* no pill on paper — the clearance gap closes */
  /* the dormant veil never prints — a fresh session can print before its wake tap */
  body.print-addrs .card-title { display: block !important; }
  body.print-addrs #cardAddrs { display: flex !important; }
  /* #188 (John): the whole address prints too — this preset IS the address list,
     and paper is where you check one against a wallet.  Letter is 816px, under
     the 960px desktop breakpoint, so that block never applies here; the same
     three columns are restated for the page's own width. */
  #cardAddrs { max-width: none !important; width: 100% !important; padding: 0 !important; }
  #cardAddrs .ca-name { display: flex !important; align-items: baseline; gap: 12px; flex: 1; overflow: visible !important; }
  #cardAddrs .ca-nick { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  #cardAddrs .ca-nick.ca-fb { display: none; }
  #cardAddrs .ca-addr { margin: 0 0 0 auto !important; white-space: nowrap; flex: 0 0 auto; opacity: 1 !important; }
  #cardAddrs .ca-usd { min-width: 116px; text-align: right; }
  /* the card's work fold prints like the ledger's: ink on white, ruled left (#183: the rank fold too; #209: the fold became the 4th face's pane) */
  #cardWork, #rankSources { background: #fff !important; border: 0 !important; border-left: 2px solid #999 !important;
    border-radius: 0 !important; padding: 4px 0 6px 10px !important; margin: 8px 0 4px !important; }
  #rankSources, #rankSources li, #rankSources .rank-src-h { color: #111 !important; }
  /* preset: SELECTED GRAPH — only the showing card, its chart blown up */
  body.print-graph #card, body.print-graph .rankwrap, body.print-graph #pane,
  body.print-graph .sampletag { display: none !important; }
  body.print-graph .chartwrap svg { width: 100% !important; height: auto !important; }
  /* preset: TOKEN BALANCES — only the ledger */
  body.print-ledger #card, body.print-ledger .rankwrap, body.print-ledger #yield { display: none !important; }
  /* preset: TRANSACTION BALANCE — only the Transactions ledger, in the selected month range (#169o, John) */
  body.print-tx #card, body.print-tx .rankwrap, body.print-tx #yield,
  body.print-txbrief #card, body.print-txbrief .rankwrap, body.print-txbrief #yield { display: none !important; }
  /* #199d (John): the STATEMENT — one line per move, folds closed on paper.
     This must outrank the print law that expands every fold. */
  body.print-txbrief .row .work { display: none !important; }
  body.print-txbrief .row, body.print-txbrief .row-line { break-inside: avoid !important; page-break-inside: avoid !important; }
  /* each transaction (its line + expanded detail) stays whole, so page breaks fall BETWEEN transactions, never mid-transaction */
  body.print-tx .row, body.print-tx .row-line, body.print-tx .row .work { break-inside: avoid !important; page-break-inside: avoid !important; }
}

/* ================= #170: the Start page — the desktop first view =================
   A marketing surface with ONE deliberate look: the dark brand shell (the app's
   ruled dark palette, hardcoded so a visitor's stored theme cannot restyle the
   front door), Blu for every interactive accent.  The two device frames wear
   Buff and Sage on purpose — the landing quietly teaches that themes exist. */
body.landing #app, body.landing .overlay, body.landing .wxscreen, body.landing .notice { display: none !important; }
body.landing { background: #0d1117; }
#start { display: none; }
body.landing #start {
  display: block; min-height: 100vh; background: #0d1117; color: #e6edf5;
  font-family: var(--sys); -webkit-font-smoothing: antialiased;
}
#start .st-head { display: flex; align-items: center; gap: 10px; max-width: 1140px; margin: 0 auto; padding: 18px 24px 6px; }
#start .st-mark { display: inline-flex; align-items: center; gap: 3px; }   /* the wordmark IS the logo: "Blu" in a blu box, "Box" beside it */
#start .st-logo { font-family: var(--rounded); font-size: 18px; color: #fff; background: #378ADD; border-radius: 10px; padding: 4px 10px 5px; }
#start .st-brand { font-family: var(--rounded); font-size: 21px; color: #e6edf5; }
#start .st-domain { font-family: var(--mono); font-size: 12.5px; color: #8ba2bd; margin-top: 3px; }
#start .st-head .st-mini { margin-left: auto; }
#start h1 { font-family: var(--ui); font-size: 44px; line-height: 1.12; color: #e6edf5; margin: 0 0 16px; }
#start h2 { font-family: var(--ui); font-size: 24px; color: #e6edf5; text-align: center; margin: 0 0 22px; }
#start h3 { font-family: var(--ui); font-size: 16.5px; color: #e6edf5; margin: 0 0 8px; }
#start p { margin: 0 0 12px; font-size: 14.5px; line-height: 1.62; color: #b6c5d8; }
#start strong { color: #e6edf5; }
#start .st-mono { font-family: var(--mono); font-size: 13px; color: #cfdcea; }
.st-open {
  display: inline-block; background: #378ADD; color: #fff; border: 0; border-radius: 12px;
  font-family: var(--ui); font-size: 17px; padding: 12px 30px; cursor: pointer;
}
.st-open:hover { background: #2E7FB8; }
.st-open.st-mini { font-size: 13.5px; padding: 8px 16px; border-radius: 12px; }
.st-hero {
  display: flex; align-items: center; gap: 44px; max-width: 1140px;
  margin: 0 auto; padding: 44px 24px 30px;
}
.st-copy { flex: 1 1 46%; min-width: 0; }
.st-sub { font-size: 16px; }
/* #175 (John): the three claims lead — enlarged and bold, Free + No Account on
   one line, the community line beneath.  They outrank the sample-data note. */
#start .st-claims { display: flex; flex-direction: column; gap: 5px; margin: 18px 0 6px 63px;
  font-family: var(--ui); font-size: 18.5px; color: #e6edf5; }   /* John 07-25: stacked; the 63px centers "Free" under the Open BluBox button (measured) */
#start .st-claims .st-in1 { margin-left: 3ch; }    /* John 07-25: his slant, tuned by eye — lines 2 and 3 sit one space left of the even grid */
#start .st-claims .st-in2 { margin-left: 7ch; }
#start .st-claims .st-in3 { margin-left: 11ch; }
.st-frames { flex: 1 1 54%; min-width: 0; margin: 0; position: relative; text-align: center; }
.st-shot { border-radius: 16px; box-shadow: 0 18px 48px rgba(0,0,0,.55); height: auto; }
.st-shot-d { width: 74%; max-width: 460px; }
.st-shot-p { width: 24%; max-width: 150px; position: absolute; right: 2%; top: 9%; }
.st-cap { font-size: 12.5px; color: #8ba2bd; margin-top: 14px; }
/* John 2026-08-03: the Features Card — the page's established card chrome (.st-pillar's),
   two columns of bullets inside, matching the two groups he wrote. */
.st-features { grid-column: 1 / span 2; grid-row: 2; background: #151c28; border: 1px solid #243044;
  border-radius: 16px; padding: 18px 22px 6px; }
.st-feat-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; align-items: start; }
.st-features .st-bullets { margin-bottom: 8px; }
.st-features .st-sub { margin: 4px 0 0; }

/* John 2026-08-03: a link with no inline colour fell back to the UA's #0000EE on the
   #151c28 pillar — measured 1.3:1, unreadable.  Every other link on this page happened
   to carry an inline colour, so the gap only showed on a NEW link.  This makes
   legibility the default; the inline-styled links (incl. the muted footer) still win. */
#start a, #start a:visited { color: #378ADD; }
.st-never { font-size: 14.5px; color: #e6edf5; margin-top: 12px; line-height: 1.45; }   /* John 2026-08-03: the connect-a-wallet warning rides under the hero photo, centered by .st-frames */
.st-steps { max-width: 1140px; margin: 0 auto; padding: 34px 24px 10px; border-top: 1px solid #243044; }
.st-step-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; align-items: start; }   /* John 2026-08-03: flex -> grid so the Features Card can occupy the room Steps 1 and 2 gave back */
.st-step-row > .st-step:nth-child(3) { grid-column: 3; grid-row: 1 / span 2; }   /* the COLUMN must be explicit too: an item with a definite row is placed before the auto-flow items, so row-only sent Step 3 to column 1 and shoved Steps 1-2 sideways */   /* Step 3 is the tallest — it spans both rows, and the card fills the space beside it rather than pushing the section taller */
.st-step { flex: 1 1 0; min-width: 0; }
.st-n {
  display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  border-radius: 50%; background: #378ADD; color: #fff; font-family: var(--ui);
  font-size: 15px; margin-bottom: 10px;
}
.st-bullets { margin: 0 0 12px; padding-left: 20px; }   /* hanging indent — bullets' law */
.st-bullets li { font-size: 14.5px; line-height: 1.62; color: #b6c5d8; margin-bottom: 6px; }
/* .st-qr / .st-qr-cap removed with the landing's demo QR (John 2026-08-03) */
.st-band {
  display: flex; gap: 28px; max-width: 1140px; margin: 0 auto; padding: 30px 24px;
  border-top: 1px solid #243044;
}
.st-pillar { flex: 1 1 0; min-width: 0; background: #151c28; border: 1px solid #243044; border-radius: 16px; padding: 20px 22px; }
.st-pillar h3 { color: #378ADD; }
.st-foot { text-align: center; padding: 26px 24px 44px; border-top: 1px solid #243044; max-width: 1140px; margin: 0 auto; }
.st-fine { font-family: var(--mono); font-size: 11.5px; color: #64788f; margin-top: 16px; }
@media (max-width: 959px) {
  .st-hero { flex-direction: column; padding-top: 26px; }
  #start h1 { font-size: 34px; }
  .st-step-row, .st-band { flex-direction: column; }
  .st-step-row { grid-template-columns: 1fr; }   /* the grid stacks with everything else below 960 */
  .st-step-row > .st-step:nth-child(3) { grid-column: 1; grid-row: auto; }
  .st-features { grid-column: 1; grid-row: auto; }
  .st-feat-cols { grid-template-columns: 1fr; }   /* one column on a phone — two would halve an already narrow line */
  .st-shot-d { width: 92%; max-width: 430px; }
  .st-shot-p { width: 30%; max-width: 132px; right: -2%; }
}

/* #195 (John): the Start Pane row — four equal buttons under the Theme row.
   "Transactions" must fit a 390px phone quarter, so the type steps down and
   centers.  Selection marks like the chain row: a ✓ and an ink border. */
/* #195b (John): ONE line — "Order:" then three view-cards, each [Blu ✓ | name | n].
   Tight per his earlier rulings (swatch height, ridden up into the Theme row's
   own bottom padding).  The Blu zone is its own target; tapping a card
   anywhere else cycles its number — the badge is small, the intent is not. */
.menu-row.r4{margin:-4px 0 4px}
.menu-row.r4 .vlabel{align-self:center;font-family:var(--ui);font-size:13.5px;color:var(--ink);padding:0 1px 0 11px}   /* #195b (John: "Order needs better visibility") — the label speaks at Theme's own size and ink, not a whisper */
.menu-row.r4 .menu-item{flex:1 1 auto;display:flex;align-items:center;justify-content:flex-start;gap:5px;border:1px solid var(--line);border-radius:8px;background:none;font-size:11px;padding:3px 5px}   /* John 07-29: same border as the fence.  2026-08-03: flex 1→1 1 auto (the Bal card carries four pieces), and flex-start — number + label cluster LEFT, the zones ride right on the auto margin below */
.menu-row.r4 .vblu,.menu-row.r4 .vval{white-space:nowrap}
.menu-row.r4 .vname + .vblu{margin-left:auto}   /* John 2026-08-03 card grammar: [n] Label ……… Blu Val */
.menu-row.r4 .vcard-txn{flex:0.72}
.menu-row.r4 .menu-item:hover{background:var(--chipbg)}
.menu-row.r4 .vblu,.menu-row.r4 .vval{font-size:10.5px;color:var(--faint)}
.menu-row.r4 .vblu.von,.menu-row.r4 .vval.von{color:var(--ink);font-weight:700}
.menu-row.r4 .vname{font-weight:600;color:var(--ink)}
.menu-row.r4 .vord{border:1px solid var(--rowline);border-radius:5px;padding:0 4px;font-variant-numeric:tabular-nums;color:var(--ink)}
/* #195: BluBox deselected — the upper cards (the Card with its HexFade, and the
   Price/Value box) leave; only the lower pane shows, full window */
body.noblu #card,body.noblu .rankwrap,body.noblu #yield{display:none}   /* #195b fix (John: "Hex Fade rides with the BluBox Order selection") — the fade card is a SIBLING of #card, not a child, so the first cut left it standing when Blu was off.  "BluBox includes the HexFade" was the ruling from the start. */

/* #195c (John: add-address, nickname, preset entries "not visible in Buff"):
   no ::placeholder rule existed, so every empty field showed the browser's
   default grey — ~3.3:1 on buff paper, washy to invisible on a real screen.
   An empty form shows ONLY placeholders, so the placeholders ARE the form.
   The theme's own faint ink replaces the UA grey on every field, every theme. */
input::placeholder,textarea::placeholder{color:var(--faint);opacity:1}
/* #201: the A card's section caps — the settings fence lettering, resized for the pane */
.actu-cap{margin:14px 4px 6px;text-align:center}
.actu-sel{margin:8px 4px 2px;font-family:var(--sys);font-size:12.5px;color:var(--ink);display:flex;align-items:center;flex-wrap:wrap}   /* #201c: the notify-threshold row — #50 ink, the pill dress reused */
.actu-det{margin-left:10px;color:var(--muted);font-size:12.5px}   /* #201h (John's screenshot): the detail ran into the symbol — my invented class had no dress; now it wears the muted detail voice with its own gap */
/* #201j: the A card's three-zone row — name | value centered | new-data slot right */
.actu-line{display:grid;grid-template-columns:1fr auto 1fr;align-items:center}
.actu-line .actu-mid{justify-self:center}
.actu-line .row-right{justify-self:end;display:flex;align-items:center;gap:6px}
.actu-new{color:var(--muted);font-size:12px;white-space:nowrap}
/* #202 (John's TODO, built 2026-07-30): the PulseChain fade — the Core
   PulseChain board wears the same frame grammar as the HEX Fade Card
   (.rankwrap), in PulseChain's own gradient (the #pls-grad stops, as the
   chain row's .plsfade text already does).  The fence inside goes solid so
   the rows read on the surface, not on the gradient. */
.plswrap{border-radius:16px;padding:2px;margin:2px -6px 10px;
  border:2.5px solid transparent;
  background:linear-gradient(var(--surface),var(--surface)) padding-box,linear-gradient(to right,#00EAFF,#0080FF,#8000FF,#E619E6,#FF0000) border-box}   /* Path A trial 2026-08-02: the PulseChain fade thins to a 2.5px frame, same grammar as the Hex Fade */
.plswrap .px-sect{background:var(--surface);border:none;border-radius:12px;margin:0}
.lx-side{font-size:9.5px;opacity:.78;letter-spacing:.4px}   /* #197i: LPX's own words — Fund / Anchor — ride small above/before the symbol */
/* #229: the marker on a move recovered from custody transfers rather than from
   an event of its own — a quiet star, the note under the table explains it. */
@media (min-width:960px), print{ .lpxcard .lx-rec{color:var(--muted);font-weight:700;cursor:help} }
/* #231: the ENDING BALANCE line under each move — the position the chain held
   after it.  A step back in ink so the moves stay the story and the balance
   reads as the running consequence of them. */
@media (min-width:960px), print{
  .lpxcard .lx-hend .lx-hm{color:var(--muted);font-style:italic}
  .lpxcard .lx-hend .lx-hf,.lpxcard .lx-hend .lx-ha{color:var(--muted)}
}
/* #237: the Min Buy TICK — the floor drawn where it actually falls on the
   0..Max Sell track, instead of being asserted at the left cap where the pool
   can never reach.  A quiet mark, not a second marker: the price indicator
   stays the thing the eye finds. */
@media (min-width:960px), print{
  .lpxcard .lx-gtrack{position:relative}
  .lpxcard .lx-gfloor{position:absolute;top:-2px;bottom:-2px;width:2px;margin-left:-1px;
    background:var(--muted);opacity:.55;border-radius:1px;cursor:help}
}

/* ================= Path A (John, 2026-08-02): the modern pass ================= */
/* 1. WEIGHT CARRIES THE HIERARCHY.  Arial Rounded MT Bold was a bold-only face —
   every element set in it was bold for free.  The system font is not, so the
   elements that traded --rounded for --ui get their weight stated here, in one
   block, instead of forty scattered edits.  600 = the working semibold voice;
   the selectors that already declared 700 keep it (this block omits them). */
#app .row.stake .row-detail, #app .row.stake .row-detail .rd-one,
.menu-item,.box-title,.yield-line,.chart-total,.row-name,.row-usd,
.row-line.px .px-px,.entry .sampletop,.entry .entrylead,.entry h2,
.hexday,.val-row,.wxsect,.wxrow,.lc-title,.lc-line,
.px-sect-cap,.menu-sect-cap,.lpxcard .lx-pool,.lpxcard .lx-pair,
.menu-row.r4 .vlabel{font-weight:600}
.entry .go{font-weight:700}   /* the primary action speaks up */
.entry .go2,.notice-actions .go2{font-weight:600}
#start h1{font-weight:800;letter-spacing:-.015em}   /* modern display type: heavy and slightly tight */
#start h2,#start h3{font-weight:700}
#start .st-claims{font-weight:600}
#start .st-open{font-weight:700}
#start .st-n{font-weight:700}
/* 2. NUMBERS SIT IN COLUMNS.  Tabular figures wherever a value is the message. */
.yield-line,.chart-total{font-variant-numeric:tabular-nums}
/* 3. MICRO-TRANSITIONS.  Interactive chrome eases instead of snapping; the
   pressed-state cluster at #209i already carries its own richer transition and
   is not repeated here.  Reduced-motion users get instant switches. */
.menu-item,.menu-item.half,.cornerbtn,.thopt,.addr-btn,.entry .go,.entry .go2,
.notice-actions .go2,.pxseg button,.st-open{transition:background-color .15s ease,border-color .15s ease,color .15s ease}
@media (prefers-reduced-motion:reduce){
  .menu-item,.menu-item.half,.cornerbtn,.thopt,.addr-btn,.entry .go,.entry .go2,
  .notice-actions .go2,.pxseg button,.st-open{transition:none}}
/* 4. SKELETON LOADERS.  While a value is genuinely unknown (first real-wallet
   read, the price board's first fetch) the slot shows a quiet shimmer bar the
   size of the number it awaits — never a blank, never a false zero.  app.js
   paints .skel spans into the waiting slots and removes them when data lands. */
.skel{display:inline-block;height:1em;min-width:64px;border-radius:6px;vertical-align:-.15em;
  background:linear-gradient(90deg,var(--chipbg) 25%,var(--line) 50%,var(--chipbg) 75%);
  background-size:200% 100%;animation:skelshine 1.4s ease-in-out infinite}
.skel.w-lg{min-width:150px}
.skel.w-sm{min-width:40px}
@keyframes skelshine{from{background-position:150% 0}to{background-position:-150% 0}}
@media (prefers-reduced-motion:reduce){.skel{animation:none;background:var(--chipbg)}}
.skelrows{padding:4px 2px 8px}
.skelrow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 2px;border-bottom:1px solid var(--rowline)}
.skelrow:last-child{border-bottom:none}

/* ================= Path B (John, 2026-08-03): the Slate face ================= */
/* Slate is the ONE theme where the brand fences go quiet: hairline borders in
   place of the gradients, the rank card on the theme surface instead of black,
   ink numbers with the Blu carrying the delta.  Every other theme keeps its
   fades exactly as ruled (#241 / John's 10px band).  The HEX logo mark stays
   full-color — the one point of brand saturation in the quiet room. */
html.dark-slate .rankwrap{border:.5px solid transparent;
  background:linear-gradient(var(--surface),var(--surface)) padding-box,var(--hero-fade) border-box}   /* John 2026-08-03: a HALF-point Hex Fade frames the T-Shares card — one physical pixel on retina, the way iOS draws its own hairlines (3px→2px→1px trialed down to here) */
html.dark-slate .rank{background:none}
html.dark-slate .rankdots b{background:var(--dot)}
html.dark-slate .rankdots b.on{background:var(--doton)}
html.dark-slate .rank-title,html.dark-slate .rank-src-h{color:var(--muted)}
html.dark-slate .rank-value{color:var(--ink)}
html.dark-slate .rank-delta{color:var(--dayok)}   /* the one accent speaks the change */
html.dark-slate .rank-sub{color:var(--faint);opacity:1}
html.dark-slate .plswrap{border:.5px solid transparent;padding:2px;
  background:linear-gradient(var(--surface),var(--surface)) padding-box,linear-gradient(to right,#00EAFF,#0080FF,#8000FF,#E619E6,#FF0000) border-box}   /* John 2026-08-03: the PulseChain Core board wears its own chain's fade at a HALF point — the T-Shares ring's twin, one physical pixel on retina */

/* John 2026-08-03: on phone the Search and Sort chips speak in SYMBOLS alone —
   the spyglass and the stacked-cards glyph, centered in the same #209f chip box
   (one-size law untouched, tap targets unchanged).  Desktop keeps the words. */
#viewGroup .gl-ico{display:none}
@media (hover:none) and (pointer:coarse){
  #viewGroup .gl-ico{display:block}
  #viewGroup .gl1,#viewGroup .gl2{display:none}
  .searchlock .tl1{display:none}
  .searchlock .tl2 svg{width:17px;height:17px}
}

/* John 2026-08-03 ("do A first"): the collapsed caution runs.  The summary is the
   quiet voice — muted ink, same row grammar; the dealt-out run nests beneath it.
   PRINT always deals the runs out: a statement omits nothing. */
.cau-run{display:none}
.cau-run.open{display:block}
.cau-sum .row-name,.cau-sum .row-usd{color:var(--muted)}
@media print{
  .cau-sum{display:none !important}
  .cau-run{display:block !important}
}

/* John 2026-08-03 (B): the Combined-view toggle's seats — the #209f chip box,
   one seat outboard of Sort on the desk, beside the spyglass on the phone
   (his ruling: "The toggle can go in the sticky row.  My phone shows room"). */
.pane-stick .viewstory{position:absolute;top:0;right:448px}
@media (max-width:959px){.pane-stick .viewstory{top:42px;right:304px}}
@media (hover:none) and (pointer:coarse){.pane-stick .viewstory{top:0;right:148px}}

/* ---- #255: the Scene lens — the ▶ door, the scrubbing arrows, the exit that
   lands where you traveled.  Theme-aware through the same variables every
   chip wears; the backdrop dims either paper. */
/* #255a (John): 'Play Button needs to be larger' — 11→16px, with padding so
   the thumb target outgrows the glyph */
.scenebtn{color:var(--dayok);font-size:16px;margin-right:6px;padding:2px 6px;cursor:pointer;opacity:.85;align-self:center;line-height:1}
@media (hover:hover) and (pointer:fine){ .scenebtn:hover{opacity:1;filter:brightness(1.15)} }
#sceneLens{position:fixed;inset:0;background:var(--shadow);backdrop-filter:blur(2px) brightness(.55);-webkit-backdrop-filter:blur(2px) brightness(.55);z-index:400;display:flex;align-items:center;justify-content:center}
/* #255a (John): 'Arrow buttons cannot move up and down with additional text'
   — the box holds ONE height, the stage scrolls inside it, so the arrows
   never move and a rapid forward-tap stays smooth.  Bottom, not top: the
   jump was the fault, and bottom is where the phone thumb lives. */
.scene-box{background:var(--surface);color:var(--ink);border:1px solid var(--chipline);border-radius:14px;max-width:560px;width:94%;height:min(430px,84vh);display:flex;flex-direction:column;padding:18px 16px;font-family:var(--ui);box-shadow:0 12px 40px var(--shadow);box-sizing:border-box}
.scene-head{font-size:12px;font-weight:700;color:var(--muted);text-align:center;margin-bottom:12px}
.scene-stage{flex:1;overflow:auto;display:flex;flex-direction:column;justify-content:center;text-align:center;padding:10px 4px 14px}
.scene-step{font-size:10.5px;font-weight:700;color:var(--muted);margin-bottom:8px}
.scene-title{font-size:17px;font-weight:800;margin-bottom:6px}
.scene-amt{font-size:15px;font-weight:700;margin-bottom:10px}
.scene-line,.scene-when{font-size:11.5px;color:var(--muted);margin-top:6px;line-height:1.4}
.scene-foot{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-top:auto;padding-top:8px}
.scene-nav{font-size:20px;line-height:1;padding:6px 18px;border-radius:10px;border:1px solid var(--chipline);background:var(--chipbg);color:var(--ink);cursor:pointer}
.scene-nav:disabled{opacity:.35;cursor:default}
.scene-exitbtn{font-size:11px;font-weight:700;padding:8px 14px;border-radius:10px;border:1px solid var(--chipline);background:var(--chipbg);color:var(--ink);cursor:pointer;font-family:var(--ui)}
.row.scene-exit .row-line{outline:2px solid var(--dayok);outline-offset:-2px;transition:outline-color 1.2s}
