/* admin.css — ❤️ HEART, the admin tab on design.fundamental.fans
   ==========================================================================
   His words, 5 Sept 2026 (~19:10 PT): "just make it a brain foam emoji … you can
   click on it and it'll take you to this admin … a log and dashboard … you're like
   the brain Buddy brand builder database." And 6 Sept 08:03: "we need something a
   little bit more clean and organized… more aligned with even more structure and
   cleanliness and order and organization."

   Everything here is the site's own paper language: the :root tokens in index.html,
   .tape / .stk / .section-title / .collapse-btn / .btn-px / .cc-note from the site
   and card-template.css, the Gold Classic post-it recipe, the Stepping Stones
   recipe and the badge recipe from cowork/brain-buddies/DESIGN-GROUND-TRUTH.md
   (§5.6 row 1, §8.6 #17, §5.4). No hex in this file was typed from memory; each one
   is in §3.2 or §4.1 there, or in card-template.css L84-86 (the badge text darks).

   COLOUR DISCIPLINE (6 Sept): inside HEART, gold means "waiting on you" and nothing
   else — the post-its, the ○ of a built row, the brief's waiting line. Everything that
   used to be gold for another reason is grey now (the 🧭 needs-prep chip, "+N" clips,
   the hidden-chars count). The single exception is the stepping stone's "you are here",
   which §8.4 defines as gold; a made-up you-are-here colour would break the ground truth.

   PHONE FIRST: 390 px, one column, no sideways scroll, every control at least 44 px
   tall, nothing that needs him ever expires. Sections fold; folds and drawers are
   <details> so an open one survives the 12-second re-render (only .adm-body is
   rewritten).

   Scoped to #pg-admin. It reuses the site's classes inside the admin; it never
   redefines them. One writer per file: index.html's <style> is not touched. */

/* ── the 390 px rule: the page must fit a phone with no sideways scroll ── */
#pg-admin,#pg-admin *{min-width:0;max-width:100%}
#pg-admin{overflow-wrap:anywhere}
/* a brief line's jump lands the tape under the sticky nav, not behind it */
#pg-admin>div{scroll-margin-top:100px}

/* ── type helpers ──
   Digits are Gaposiss (PixelGamer has no digits). The middot is missing from
   EmbossT1 AND Gaposiss, so it always gets its own span in the body font. The
   grey ladder (§4.1): titles #5A5855 fw600, qualifiers #7A7775 fw300, keys #929AA0. */
#pg-admin .adm-n{font-family:'Gaposiss','PixelGamer',monospace;font-variant-numeric:tabular-nums}
#pg-admin .adm-dot{font-family:'Avenir Next','Segoe UI',system-ui,sans-serif;color:#929AA0;padding:0 .2em}
#pg-admin .adm-hand{font-family:'Chalkduster',cursive}
#pg-admin .adm-title{color:#5A5855;font-weight:600}
#pg-admin .adm-qual{color:#7A7775;font-weight:300}
#pg-admin .adm-key{font-family:'Gaposiss','PixelGamer',monospace;font-size:.68rem;color:var(--ink-xlt);margin-left:6px;white-space:nowrap}
#pg-admin .adm-glyph{font-weight:700;margin-right:4px}
/* the needs-prep chip: grey, because gold is reserved for "waiting on you" in HEART */
#pg-admin .adm-prep{font-family:'Gaposiss','PixelGamer',monospace;font-size:.62rem;letter-spacing:.06em;color:#7A7775;background:rgba(58,58,58,.06);border:1px solid rgba(58,58,58,.12);border-radius:3px;padding:1px 6px;margin-left:6px;white-space:nowrap;vertical-align:middle}
#pg-admin .adm-more{color:#929AA0;font-family:'Gaposiss','PixelGamer',monospace;font-size:.68rem;margin-left:4px}
#pg-admin .adm-stk{font-size:1.1em;margin:0 4px}
/* the badge recipe from card-template.css .cc-badge (L74-86) and §5.4: an 8% wash of the
   family colour, a darkened text colour, no border. Static so it sits inline. PixelGamer,
   so never a comma, full stop, ampersand or digit inside. teal and grey are additions
   in the same recipe (text: --teal-dk and the ladder's #5A5855). */
#pg-admin .adm-badge{font-family:'PixelGamer',monospace;font-size:.68rem;font-weight:600;padding:2px 8px;border-radius:3px;letter-spacing:.02em;white-space:nowrap;vertical-align:middle}
#pg-admin .adm-badge.gold{background:rgba(196,149,56,.08);color:#8A7030}
#pg-admin .adm-badge.green{background:rgba(85,156,64,.08);color:#3A6A28}
#pg-admin .adm-badge.red{background:rgba(181,53,53,.08);color:#8A2020}
#pg-admin .adm-badge.teal{background:rgba(48,120,120,.08);color:#1F5A5F}
#pg-admin .adm-badge.grey{background:rgba(58,58,58,.06);color:#5A5855}
#pg-admin .adm-line .adm-badge{margin-left:6px}

/* the one-line "what this is", written for him, under every tape */
#pg-admin .adm-what{font-family:'Chalkduster',cursive;font-size:.85rem;color:var(--ink-md);text-align:center;margin:-.7rem auto .9rem;max-width:520px;line-height:1.6;text-wrap:balance}
#pg-admin .adm-sub{font-size:.8rem;color:#7A7775;text-align:center;margin:-.4rem 0 .8rem}

/* ── the status line above everything ── */
#adm-status{font-family:'Chalkduster',cursive;font-size:.85rem;color:var(--ink-md);text-align:center;margin:.2rem 0 1.4rem;line-height:2}
#adm-status .adm-alarm{display:block;color:var(--red);font-weight:700;font-size:.95rem}
#adm-status .adm-unknown{display:block}
#pg-admin .adm-badge.adm-chip{margin:0 4px;font-size:.62rem;letter-spacing:.09em}
#pg-admin .adm-tools{margin-top:.4rem}
#pg-admin .adm-tools .btn-px{font-size:.8rem;padding:5px 12px}
/* every control at least 44 px tall — his thumb, not a cursor */
#pg-admin .btn-px{min-height:44px}
#pg-admin .collapse-btn{min-height:44px}

/* ── honest empties ── */
#pg-admin .adm-unknown{color:var(--red);font-family:'Chalkduster',cursive;font-size:.9rem;text-align:center;line-height:1.6;padding:.4rem 0}
#pg-admin .adm-warn{color:var(--red);font-family:'Chalkduster',cursive;font-size:.8rem;text-align:center;margin:.2rem 0 .6rem}
#pg-admin .adm-head{font-family:'Chalkduster',cursive;font-size:.95rem;color:var(--ink-md);text-align:center;margin:.2rem 0 .6rem}
#pg-admin .adm-foot{font-family:'Chalkduster',cursive;font-size:.75rem;color:var(--ink-lt);text-align:center;margin:.8rem 0 0}
#pg-admin .cc-note .stk{margin-right:6px}

/* ── folds and drawers ──
   A section that is long folds under its tape: a <details> whose summary is one line in his
   handwriting with the counts, 44 px tall, in the site's .collapse-btn look. A drawer is the
   same control inside a section (a Formula stage, a shipped day, a page of his words). */
#pg-admin details>summary{list-style:none}
#pg-admin details>summary::-webkit-details-marker{display:none}
#pg-admin details.adm-fold>summary,#pg-admin details.adm-d>summary{cursor:pointer;min-height:44px;display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:8px 14px;font-family:'Chalkduster',cursive;font-size:.85rem;line-height:1.5;color:var(--ink-md);border:1.5px solid rgba(58,58,58,.08);border-radius:5px;background:rgba(58,58,58,.02);box-shadow:0 2px 4px rgba(0,0,0,.04);transition:border-color .15s,color .15s}
#pg-admin details.adm-fold>summary::before,#pg-admin details.adm-d>summary::before{content:'▸';color:var(--ink-xlt);font-size:.8em;flex:0 0 auto}
#pg-admin details[open].adm-fold>summary::before,#pg-admin details[open].adm-d>summary::before{content:'▾'}
#pg-admin details.adm-fold>summary:hover,#pg-admin details.adm-d>summary:hover{border-color:var(--teal);color:var(--teal)}
#pg-admin details>summary:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
#pg-admin .adm-fold-line{flex:1 1 0}   /* shrinks and wraps inside, so the ▸ never sits alone on a line */
#pg-admin .adm-fold-line .adm-unknown{display:inline;padding:0;text-align:left}
#pg-admin .adm-fold-hint{font-size:.7rem;color:var(--ink-xlt);margin-left:auto}
#pg-admin details.adm-fold>.adm-body{padding:.7rem 0 0}
#pg-admin details.adm-d{margin:.35rem 0}
#pg-admin details.adm-d>summary{font-size:.9rem}
#pg-admin details.adm-d>summary .stk{font-size:1.2em}
#pg-admin details.adm-d.dim>summary{opacity:.45}
#pg-admin details[open].adm-d>summary{border-radius:5px 5px 0 0}
#pg-admin details.adm-d>.adm-d-body{background:rgba(58,58,58,.015);border:1px dashed rgba(58,58,58,.08);border-top:none;border-radius:0 0 6px 6px;padding:.5rem .8rem .6rem}
#pg-admin .adm-count{font-family:'Gaposiss','PixelGamer',monospace;font-size:1em;color:#3A3A3A;margin-left:auto;padding-left:8px}

/* ── THE BRIEF · three lines, each a tap to its section ── */
#adm-brief .adm-brief-line{display:flex;align-items:flex-start;gap:8px;min-height:44px;padding:8px 10px;border-radius:6px;cursor:pointer;font-size:.95rem;line-height:1.6;color:#5A5855}
#adm-brief .adm-brief-line:hover{background:rgba(48,120,120,.04)}
#adm-brief .adm-brief-line:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
#adm-brief .adm-brief-line .adm-glyph{padding-top:2px}
#adm-brief .adm-brief-lbl{font-family:'Chalkduster',cursive;font-size:.8rem;color:var(--ink-md);flex:0 0 auto;width:96px;padding-top:3px}
#adm-brief .adm-brief-txt{flex:1 1 auto}
#adm-brief .adm-brief-txt b{color:#2D2F32;font-weight:700}
#adm-brief .adm-brief-line.unknown .adm-brief-txt{color:var(--red);font-family:'Chalkduster',cursive}
#adm-brief .adm-brief-subs{margin:-.2rem 0 .5rem 2.2rem}
#adm-brief .adm-brief-sub{font-size:.85rem;color:#5A5855;line-height:1.6;margin:0 0 .15rem}
#adm-brief .adm-brief-sub b{color:var(--red);font-weight:600}
#adm-brief .adm-read-row{text-align:center;margin:.7rem 0 .2rem}
#adm-brief .adm-read{font-size:.92rem}

/* ── WAITING ON YOU · the post-it pile ──
   Gold Classic, verbatim (DESIGN-GROUND-TRUTH §5.6 row 1). Two 170px notes fit a
   358px phone column: 170 + 14 + 170 = 354. This gold is reserved: in HEART it means
   "waiting on you" and nothing else. */
#adm-needs .adm-pile{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:14px;justify-items:center;padding:6px 0 10px}
#pg-admin .adm-note{position:relative;width:170px;padding:16px 18px 22px;border-radius:1px 1px 3px 3px;box-shadow:3px 4px 10px rgba(0,0,0,.22),0 1px 3px rgba(0,0,0,.12);background:linear-gradient(90deg,#E8DDA0 0%,#F2EABC 30%,#F8F0CA 100%);color:#6D5042;font-family:'Chalkduster',cursive;font-size:.88rem;line-height:1.7;text-align:center;text-wrap:balance;cursor:pointer}
#pg-admin .adm-note .adm-strip{position:absolute;top:0;left:0;width:6px;bottom:0;background:linear-gradient(90deg,rgba(0,0,0,.06),transparent)}
/* ⛔ NO PEEL. His 5 Sept 22:41 words on the pile: "a weird little corner thing where it has like a digital square with
   like a fake fold… that needs to look a little bit more like a real Post-it note." The §5.6 triangle is retired here;
   a real post-it lifts off the paper at the bottom, so the bottom shadow is deeper and the glue strip at the top is
   flat. Four real-looking versions go to him on a card before anything fancier ships. */
#pg-admin .adm-note .adm-peel{display:none}
#pg-admin .adm-note{box-shadow:1px 2px 4px rgba(0,0,0,.14),0 12px 16px -9px rgba(0,0,0,.42)}
#pg-admin .adm-note::before{content:'';position:absolute;top:0;left:0;right:0;height:14px;background:linear-gradient(180deg,rgba(0,0,0,.07),transparent);pointer-events:none}
/* the five 170px notes' own rotations, cycling — never all the same */
#pg-admin .adm-note:nth-child(5n+1){transform:rotate(-2deg)}
#pg-admin .adm-note:nth-child(5n+2){transform:rotate(1.5deg)}
#pg-admin .adm-note:nth-child(5n+3){transform:rotate(-1deg)}
#pg-admin .adm-note:nth-child(5n+4){transform:rotate(2deg)}
#pg-admin .adm-note:nth-child(5n+5){transform:rotate(-.5deg)}
#pg-admin .adm-note .stk{font-size:1.6em;display:block;margin:0 auto 4px;width:fit-content}
#pg-admin .adm-note .adm-nt{font-size:.85rem;color:#6D5042;display:block}
#pg-admin .adm-note .adm-open{display:block;margin-top:6px;font-size:.8rem;color:#8A6A28}
#pg-admin .adm-note .adm-age{display:block;font-size:.7rem;color:#9B6943}
/* from 72 h: the sheet may forget the card; the note stays, and says so in red */
#pg-admin .adm-note .adm-old{display:block;font-size:.66rem;line-height:1.5;color:#B53535;margin-top:4px}
#pg-admin .adm-note:focus-visible{outline:2px solid var(--teal);outline-offset:3px}
/* more than six waiting: a stack (§10.5) with the count on the front note */
#pg-admin .adm-stack{position:relative;width:170px;height:120px;cursor:pointer;justify-self:center}
#pg-admin .adm-stack .adm-note{position:absolute;inset:0;width:170px;height:120px;padding:14px 16px 18px}
#pg-admin .adm-stack .adm-note.back{transform:rotate(2.2deg);box-shadow:0 2px 4px rgba(58,58,58,.18)}
#pg-admin .adm-stack .adm-note.front{transform:rotate(.2deg);box-shadow:0 1px 3px rgba(58,58,58,.15),0 4px 12px rgba(58,58,58,.12)}

/* ── YOU ANSWERED · rows ── */
#pg-admin .adm-row{padding:.35rem 0;border-bottom:1px solid rgba(58,58,58,.05)}
#pg-admin .adm-row:last-child{border-bottom:none}
#pg-admin .adm-line{margin:0;font-size:.95rem;line-height:1.7;color:#5A5855;cursor:pointer}
#pg-admin .adm-line.plain{cursor:default}
#adm-answers .adm-line{min-height:44px;display:flex;flex-wrap:wrap;align-items:center;gap:2px}
#pg-admin .adm-reply{white-space:pre-wrap;color:#5A5855;font-size:.9rem;line-height:1.6;margin:.3rem 0 .3rem 1.6rem;padding:.5rem .8rem;background:rgba(58,58,58,.015);border:1px dashed rgba(58,58,58,.08);border-radius:6px}
#pg-admin .adm-sec{font-family:'Gaposiss','PixelGamer',monospace;font-size:.72rem;color:var(--ink-xlt);display:block;margin-bottom:.2rem}

/* ── Stepping Stones (§8.6 #17), shared by THE TIMELINE's road and THE PLAN's S.P.A.R.K. strip:
   teal done · gold pulsing "you are here" (§8.4) · dashed upcoming. The wobble is
   #sketch-accuracy — the only filter reachable from a stylesheet; #wobble lives inside
   #pg-storytelling. */
#pg-admin .adm-stone{width:28px;height:28px;border-radius:50%;flex:0 0 auto;filter:url(#sketch-accuracy);transition:transform .15s}
#pg-admin .adm-stone.done{background:var(--teal);border:2px solid rgba(48,120,120,.3);box-shadow:0 2px 4px rgba(0,0,0,.12)}
#pg-admin .adm-stone.now{background:var(--gold);border:2px solid rgba(196,149,56,.4);box-shadow:0 2px 4px rgba(0,0,0,.12),0 0 8px rgba(196,149,56,.3);animation:pulse-stone 1.5s ease-in-out infinite alternate}
#pg-admin .adm-stone.next{background:rgba(58,58,58,.08);border:1.5px dashed rgba(58,58,58,.15)}
#pg-admin .adm-stone.pop{transform:scale(1.3)}

/* ── THE TIMELINE · the goal, the road, the drawers ── */
#adm-timeline .adm-goal{font-size:1rem;font-weight:700;color:#2D2F32;text-align:center;line-height:1.55;margin:0 auto .9rem;max-width:560px;text-wrap:balance}
#adm-timeline .adm-road{display:flex;justify-content:center;align-items:flex-start;gap:6px;padding:12px 8px 10px;background:linear-gradient(180deg,rgba(90,160,200,.06),rgba(90,160,200,.12));border-radius:20px;margin:0 auto .8rem;max-width:560px}
#adm-timeline .adm-road-col{flex:1 1 0;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;min-width:0}
#adm-timeline .adm-road-col .stk{font-size:1.1em}
#adm-timeline .adm-road-n{font-family:'Chalkduster',cursive;font-size:.7rem;color:var(--ink-lt);white-space:nowrap}
#adm-timeline .adm-road-t{font-size:.72rem;color:#5A5855;font-weight:600;line-height:1.3}
#adm-timeline .adm-road-col.next .adm-road-t{color:var(--ink-xlt);font-weight:400}
#adm-timeline .adm-road-when{font-family:'Chalkduster',cursive;font-size:.64rem;color:var(--ink-xlt)}
#adm-timeline .adm-here{font-family:'Chalkduster',cursive;font-size:.68rem;color:var(--gold-deep);white-space:nowrap}
/* a source key wraps here (it can be a file name and a line); the full path is the title */
#adm-timeline .adm-key{white-space:normal;overflow-wrap:anywhere}
#adm-timeline .adm-meta{font-size:.78rem;color:#7A7775;margin:-.1rem 0 .3rem 1.7rem;font-weight:300}
#adm-timeline .adm-meta .adm-n{color:#5A5855}

/* ── THE PLAN · stones, stages, rows ── */
#adm-board .adm-strip{text-align:center;margin:.2rem 0 .6rem}
#adm-board .adm-stones{display:inline-flex;gap:6px;flex-wrap:nowrap;overflow-x:auto;max-width:100%;padding:8px 10px 6px;position:relative;vertical-align:top;align-items:flex-start;background:linear-gradient(180deg,rgba(90,160,200,.06),rgba(90,160,200,.12));border-radius:20px}
#adm-board .adm-stone-col{display:flex;flex-direction:column;align-items:center;gap:4px;flex:0 0 auto;width:34px}
#adm-board .adm-stone-col .stk{font-size:1em}
#adm-board .adm-loop{display:block;margin:-2px auto 0;overflow:visible}
#adm-board .adm-loop path{fill:none;stroke:var(--ink-xlt);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;filter:url(#sketch-accuracy)}
#adm-board .adm-loop.now path{stroke:var(--gold);stroke-width:2}
#adm-board .adm-loop-label{font-family:'Chalkduster',cursive;font-size:.75rem;color:var(--ink-lt);text-align:center;margin:0 0 .3rem}
#adm-board .adm-loop.now + .adm-loop-label{color:var(--gold-deep)}
#adm-board .adm-caveat{font-size:.78rem;color:#7A7775;text-align:center;margin:0 auto .9rem;max-width:520px;line-height:1.5}
#adm-board .adm-group{font-family:'Chalkduster',cursive;font-size:.88rem;color:var(--ink-md);margin:.6rem 0 .2rem .2rem}
#adm-board .adm-row{padding:.3rem 0 .3rem .2rem}
#adm-board .adm-meta{font-size:.78rem;color:#7A7775;margin:0 0 .2rem 1.7rem;font-weight:300}
#adm-board .adm-meta .adm-n{color:#5A5855}
#adm-board .collapse-btn{margin-left:1.4rem!important}
#adm-board .adm-spec{font-size:.85rem;color:#5A5855;line-height:1.6;white-space:pre-wrap}
#adm-board .adm-spec .adm-lbl{font-family:'Chalkduster',cursive;font-size:.72rem;color:var(--ink-lt);display:block;margin-top:.4rem}
#adm-board .adm-spec a{color:var(--teal);text-decoration:none;border-bottom:1px dashed rgba(48,120,120,.4)}

/* ── WHAT SHIPPED · a drawer per day, the sentence not the hash ── */
#adm-shipped details.adm-day>summary .adm-n{font-size:1rem;color:#3A3A3A}
#adm-shipped .adm-day-sub{color:var(--ink-lt);font-size:.78rem;margin-left:8px}
#adm-shipped .adm-item{font-size:.88rem;color:#5A5855;line-height:1.6;padding:.15rem 0 .15rem .2rem;display:flex;gap:8px;align-items:baseline}
#adm-shipped .adm-item .adm-n{font-size:.72rem;color:var(--ink-xlt);flex:0 0 auto}
#adm-shipped .adm-total{font-family:'Chalkduster',cursive;font-size:.9rem;color:var(--ink-md);text-align:center;margin-top:.6rem}
#adm-shipped .adm-total .adm-n{font-size:1.15rem;color:#3A3A3A}

/* ── EACH HEARTBEAT ── */
#adm-beats .adm-rung{font-family:'Chalkduster',cursive;font-size:.78rem;color:#7A7775;text-align:center;margin:0 0 .8rem;line-height:1.8}
#adm-beats .adm-rung .on{color:var(--teal);font-weight:600}
#adm-beats details.adm-beat{border-bottom:1px solid rgba(58,58,58,.05);padding:.3rem 0}
#adm-beats details.adm-beat summary{cursor:pointer;list-style:none;font-size:.92rem;line-height:1.7;color:#5A5855;min-height:44px;display:flex;flex-wrap:wrap;align-items:center;gap:2px}
#adm-beats details.adm-beat summary::before{content:'▸';color:var(--ink-xlt);margin-right:6px;font-size:.8em}
#adm-beats details[open].adm-beat summary::before{content:'▾'}
#adm-beats .adm-when{font-family:'Chalkduster',cursive;font-size:.8rem;color:var(--ink-lt);margin-right:6px}
#adm-beats .adm-tok{font-size:.8rem;margin-left:6px}
#adm-beats .adm-tok.unknown{font-family:'Chalkduster',cursive;color:var(--ink-xlt)}
#adm-beats .adm-next{font-size:.8rem;color:#7A7775;font-weight:300;margin-left:6px}
#adm-beats .adm-report{margin:.3rem 0 .4rem 1.4rem;font-size:.86rem;color:#5A5855;line-height:1.6}
#adm-beats .adm-report .adm-lbl{font-family:'Chalkduster',cursive;font-size:.72rem;color:var(--ink-lt);display:block;margin-top:.35rem}
#adm-beats .adm-report .adm-n{color:var(--ink-xlt);font-size:.75rem}

/* ── YOUR WORDS · a drawer per page, entries inside ── */
#adm-log .adm-pressure{font-family:'Chalkduster',cursive;font-size:.85rem;color:var(--ink-md);text-align:center;margin:0 0 .9rem}
#adm-log .adm-pressure.red{color:var(--red)}
#adm-log details.adm-words>summary .adm-grp{color:#5A5855;font-weight:600;font-family:'Avenir Next','Segoe UI',system-ui,sans-serif;font-size:.9rem}
#adm-log details.adm-words>summary .adm-qual{font-size:.78rem;font-family:'Chalkduster',cursive}
#adm-log .adm-entry{padding:.5rem 0;border-bottom:1px solid rgba(58,58,58,.05)}
#adm-log .adm-entry:last-child{border-bottom:none}
#adm-log .adm-entry-head{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:.25rem}
#adm-log .adm-ts{font-family:'Chalkduster',cursive;font-size:.72rem;color:var(--ink-lt)}
#adm-log .adm-text{white-space:pre-wrap;color:#5A5855;font-size:.92rem;line-height:1.65}
#adm-log .adm-hidden{color:#929AA0;font-family:'Gaposiss','PixelGamer',monospace;font-size:.72rem;margin-left:4px}
#adm-log .adm-whole{font-family:'Chalkduster',cursive;font-size:.72rem;color:var(--teal);background:none;border:none;cursor:pointer;padding:0 6px;min-height:44px;vertical-align:middle}

/* ── motion: the first stylesheet in this system to honour reduced motion
   (DESIGN-GROUND-TRUTH §12 item 13 says the system has none) ── */
@media (prefers-reduced-motion:reduce){#pg-admin *{animation:none!important;transition:none!important}}

/* ── 🚀 LAUNCH — readiness list + the prompt box (6 Sept 2026, his words: the prompt lives in HEART, folded) ── */
#pg-admin .adm-launch-list{margin:4px 0 10px}
#pg-admin .adm-launch-prompt{background:#FAFAF5;border:1.5px solid rgba(58,58,58,.16);border-radius:6px;padding:10px 10px 12px;box-shadow:0 2px 6px rgba(58,58,58,.08)}
#pg-admin .adm-launch-t{font-family:'Chalkduster',cursive;font-size:.9rem;color:#2D2F32;margin-bottom:6px}
#pg-admin .adm-prompt{width:100%;min-height:220px;max-height:420px;font-family:ui-monospace,Menlo,monospace;font-size:.72rem;line-height:1.5;color:#5A5855;background:#fff;border:1.5px solid rgba(58,58,58,.12);border-radius:5px;padding:8px;resize:vertical;white-space:pre;overflow:auto}
#pg-admin .adm-launch-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:8px}
#pg-admin .adm-launch-row .adm-qual{font-family:'Gaposiss',monospace;font-size:.68rem;word-break:break-all}

/* ── 🎠 THE FOCUS BANNER · what Brain Buddy is on RIGHT NOW ──────────────────────────────
   His 09:25 words (board row 1iqekmq.1o, "4c"): "some type of fun like head like banner that like
   shows quotes or like phrases from brain body … what they're focusing on in that moment."
   Decision #46. Class family .adm-focus / .adm-focus-* is mine; admin.js owns the markup and
   renders it into #adm-focus, between the status line and THE BRIEF.

   WHY THIS BLOCK IS AT THE END: the banner draws near the TOP, and this file's blocks otherwise
   run in DOM order. 🚀 LAUNCH was appended the same way, and admin.js is being written in the same
   beat with comments that cite admin.css line numbers — inserting 100 lines mid-file would
   silently invalidate every one of them. Move both blocks into DOM order when the file is quiet.

   A STRIP, NOT A HERO (his #41 rule for the top of HEART). It is a slip of card paper laid on the
   notebook: paper ground, a hairline, the §5.6 stuck-TOP-edge wash, one contact+ambient shadow
   pair, .3deg off square, capped at 640px, type topping out at .95rem.

   📏 THE HEIGHT, MEASURED — AND THE NUMBER THAT USED TO SIT HERE WAS A BEST CASE PASSED OFF AS A
   RULE. This block said "its height is bounded by the data … Measured at a true 390px: 188px tall,
   about a fifth of the screen", and both halves were false. Rendered through the real path
   (puppeteer, /index.html#admin, a true 390x844, deviceScaleFactor 2, the site's own fonts, the
   three rules below toggled off and on in the same page so the two columns are the same build):

       payload at 390x844                    was     now    📬 THE BRIEF starts at
       a clean fresh beat, no warnings      244px   244px   y849 → y829
       the heartbeat.json IN THIS REPO      331px   322px   y936 → y907
         (one seed row, long since late: the LATE warning runs 5 lines, git-has-moved-on 2)
       a 400-char `did` + those warnings    491px   369px   y1097 → y954

   "beat.mjs slices `did` at 400 chars" is a cap on CHARACTERS, not on height: 400 characters set
   at .95rem/600 in this column is NINE lines, 205px, measured. That was the whole bound, and it
   was not one — the strip grew past half a phone screen and pushed 📬 THE BRIEF, the one panel on
   this page that wants something from him, to y1097. `did` is now clamped at L384 and the doubled
   bottom gap is gone at L345; worst case is 369px and cannot be grown any further by a longer `did`.
   ⚠️ IT IS STILL A THIRD OF AN 844px SCREEN ON TODAY'S DATA, and CSS cannot honestly take it lower
   — see the warnings note below. The remaining lever is the panel ORDER in admin.js's ensureHosts
   (its `else if (id === 'adm-focus')` branch — no line number: that file is being edited in the
   same beat as this one): this strip asks him for nothing and sits above the panel that does.
   That is a decision about his page, not a stylesheet's to make, so it is named, not taken.
   ⚠️ RE-MEASURE, DO NOT RE-ASSERT. Change a size, a leading or a margin in this block and run the
   render again and rewrite this table. A number copied forward from a friendlier payload is the
   same failure as a board row still written in the present tense a week after the fix.

   ⛔ AND THE WARNINGS ARE NOT WHERE YOU TAKE THE HEIGHT BACK. They are the largest block on the
   strip in the real case — 136px of the 322 — and they are also the ONLY copy of what they say:
   .adm-focus-warn text appears nowhere else on the page, unlike `did`, which 💓 EACH HEARTBEAT
   prints in full. This file's own rule, at .adm-cat-sub below: "a clipped name must never be the
   only copy." So no line-clamp, no max-height, no display:none and no opacity on a warning. A
   strip that got short by hiding why it cannot be trusted is the exact lie the whole panel exists
   to prevent.
   ⛔ NO SIDE-TAB ACCENT BAR. The Garden's pin strip carries its states on
   `border-left:3px solid #D4614E/#C49538/#559C40`; that exact pattern was flagged on this codebase
   today and removed. Here the state rides on the FOAM STICKER (admin.js picks the emoji), the
   LABEL INK and the AGE INK, through one custom property — --focus-ink. The only edge treatment is
   the full-width top glue wash of BLACK at 5%, which is the post-it's own stuck edge (§5.6, and
   .adm-note::before at L136), not a coloured slab on one side.
   ⛔ NO GOLD ON THIS STRIP, twice over: in HEART gold means "waiting on you" and the banner asks
   him for nothing, and --gold-deep #A87A28 on this paper is 3.66:1 — under the floor anyway.
   MOTION: none. §9.4 — "the paper never wobbles", no entrance animations, and a banner that
   pulses is a banner asserting life the data has not proved. Personality is the sticker, the
   handwriting and the tilt. The two .15s hovers are the documented scale (§3.8) and the
   reduced-motion guard at L248 already kills them. */
#pg-admin .adm-focus{
  --focus-ink:#5A5855;                    /* the default claims no state at all */
  display:flow-root;                      /* contains the float below whatever markup follows it */
  position:relative;
  width:calc(100% - 4px);                 /* 4px of slack absorbs the tilt's overhang at a true 390px */
  max-width:640px;margin:.1rem auto .7rem;
  padding:10px 13px 11px;
  background:#FAFAF5;                     /* var(--card) — §3.1 card paper. Never pure white (§11) */
  border:1px solid rgba(58,58,58,.10);
  border-radius:2px 2px 4px 4px;          /* stuck top edge square, free bottom edge softer (§5.6) */
  box-shadow:1px 2px 4px rgba(0,0,0,.10),0 10px 14px -9px rgba(0,0,0,.30);
  transform:rotate(-.3deg);               /* a fraction of a degree off square — hand-placed, and static.
                                             ⚠️ a transform makes this a containing block: nothing inside
                                             the strip may be position:fixed. */
  font-size:.92rem;line-height:1.6;color:#5A5855;      /* 6.77:1 on #FAFAF5 */
  transition:border-color .15s,background-color .15s
}
/* the stuck edge — the §5.6 TOP-stuck recipe, the same 14px of rgba(0,0,0,.07) the post-it pile
   already uses at L136. Full width, black, no hue, inside the paper: it reads as the edge the slip
   is stuck down along, and it is the opposite of a coloured bar down one side. Taken verbatim
   rather than softened, because an invisible design is not a subtle one. */
/* 📏 ONE BOTTOM GAP, NOT TWO. ensureHosts gives every host but #adm-status the site's `section`
   class, and .section is margin-bottom:2rem (index.html L74) — so the host contributed 32px UNDER
   a slip that already carries its own .7rem, and margin collapsing made the bigger one win. 32px
   of his phone for a gap that was designed at 11. The tape-headed sections keep the 2rem rhythm
   they were drawn for; this one is a slip of paper sitting above 📬 THE BRIEF, and it reads closer
   to the brief it heads. Measured: 32px → 11px, on every state including the empty one. */
#pg-admin #adm-focus{margin-bottom:0}
#pg-admin .adm-focus::before{content:'';position:absolute;top:0;left:0;right:0;height:14px;border-radius:2px 2px 0 0;background:linear-gradient(180deg,rgba(0,0,0,.07),transparent);pointer-events:none}
/* tappable only when admin.js makes it so — it drops the tap when 💓 EACH HEARTBEAT is not on the
   page, and a strip that looks like a control and is not is worse than no control */
#pg-admin .adm-focus[role="button"],#pg-admin .adm-focus[tabindex]{min-height:44px;cursor:pointer}
#pg-admin .adm-focus[role="button"]:hover,#pg-admin .adm-focus[tabindex]:hover{border-color:rgba(48,120,120,.45)}
#pg-admin .adm-focus:focus-visible{outline:2px solid var(--teal);outline-offset:3px}

/* the sticker. The white foam halo comes from the site's own .stk, which the markup carries — the
   same contract as .adm-stk (L50); this file never redefines a site class. admin.js writes an
   inline rotate() from tilt(), which beats the fallback tilt here, and that is the point. */
#pg-admin .adm-focus-stk{display:inline-block;font-size:1.5em;line-height:1;vertical-align:middle;transform:rotate(-5deg)}
#pg-admin .adm-focus>.adm-focus-stk{float:left;margin:1px 10px 2px 0}   /* fallback: loose in the strip, text wraps round it */
#pg-admin .adm-focus-head .adm-focus-stk{float:none;margin:0 8px 0 0}   /* today: inside the head, so the head lays it out */

/* the glance line — sticker, phrase, state word, age. Safe as flex because admin.js builds it from
   spans only; it wraps rather than overflowing at 390. */
#pg-admin .adm-focus-head{display:flex;align-items:center;flex-wrap:wrap;gap:2px 8px;margin:0 0 .1rem}
/* Brain Buddy's phrase — his handwriting, and the only place personality lives. It wears the state
   ink, so a warm phrase can never read live while the age beside it says otherwise. */
#pg-admin .adm-focus-lead{font-family:'Chalkduster',cursive;font-size:.82rem;line-height:1.5;color:var(--focus-ink)}
/* one plain word: LIVE · LATE · QUIET · UNKNOWN. PixelGamer, so no comma, full stop, ampersand or digit. */
#pg-admin .adm-focus-state{font-family:'PixelGamer',monospace;font-size:.62rem;letter-spacing:.09em;padding:2px 8px;border-radius:3px;background:rgba(58,58,58,.05);color:var(--focus-ink);white-space:nowrap}
/* the age reads in the SHUT state, so it is #5A5855-or-darker (6.77:1), never the #7A7775 used
   elsewhere in this file — #7A7775 on #FAFAF5 is 4.25:1, under the floor, and the age is the whole
   honesty mechanism. A banner whose staleness is one tap deep lies to a glance. */
#pg-admin .adm-focus-age{font-family:'Chalkduster',cursive;font-size:.8rem;color:var(--focus-ink);white-space:nowrap}
/* the one sentence that lands — beat.mjs's own `did`, never a phrase. 10.86:1 on #FAFAF5.
   📏 CLAMPED AT FOUR LINES, which is the only real bound on this strip's height. beat.mjs slices
   `did` to 400 chars, and 400 chars set at .95rem/600 in this column is NINE lines — 205px measured,
   nearly a quarter of an 844px screen for one sentence. Measured capacity of the four lines: ~173
   characters in the 326px column at 390px, ~339 in the 612px column at 1280px. So a normal BEAT:
   line is never touched and a 400-char one clips at both widths, which is the case this is for.
   ⚠️ THIS IS ONLY HONEST BECAUSE THE WHOLE SENTENCE IS ONE TAP AWAY. -webkit-line-clamp draws its
   own ellipsis, so the clip is VISIBLE, and 💓 EACH HEARTBEAT prints the same `did` unclipped —
   admin.js's renderBeats writes it straight into each beat's <summary> as .adm-title, and the only
   rule this file gives that summary is L222, which wraps rather than clips. ⛔ No clamp may be
   added there. That section is exactly where .adm-focus-go taps to. Clip the sentence here and
   clip it there too and this becomes the thing .adm-cat-sub forbids: the only copy, clipped. */
#pg-admin .adm-focus-what{margin:.1rem 0 .15rem;font-size:.95rem;font-weight:600;line-height:1.5;color:#3A3A3A;text-wrap:pretty;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}
/* ⛔ TWO LINES, AND THE REST IS ONE TAP DEEPER — WHERE IT ALREADY LIVES.
   Measured at a true 390 with a real current beat, the strip stood at 290px of
   an 844px screen: 34%, over a third of his phone, for the thing the spec calls
   "a strip, not a hero". The length comes entirely from `did`, which is one
   sentence written by whoever ran the beat and has no ceiling on it.
   ⭐ THE ANSWER WAS ALREADY WRITTEN DOWN and did not need a new control:
   research 016's phone rule is a one-breath headline first, the full text behind
   a tap (play-packet/HEART.md, panel 0 and the phone rules). This strip ALREADY
   taps through to 💓 EACH HEARTBEAT, which holds every beat in full. So the
   headline clamps and the tap that exists carries the rest — nothing new to
   learn, nothing hidden that has no way back.
   ⚠️ THE AGE, THE STATE WORD AND THE WARNINGS ARE DELIBERATELY NOT CLAMPED.
   Those are the parts that say the data is dead, and admin.js's own comment
   above the head is blunt about why: "a banner whose staleness is one tap deep
   lies to a glance, and a glance is all it gets on a phone." Only the
   description of the work is folded; never the reason to distrust it. */
/* what it is reaching for, and the warnings. Both are prose in his language, so they read as
   sentences and step back by size and weight — not by dropping under 4.5:1. */
/* ⛔ CLAMPED, like .adm-focus-what above it, and for the reason the ceiling exists. The banner
   must stay a STRIP — dsproof fails it past 33% of the screen — and this line is written fresh
   by every beat, so its length is not under anyone's control. Unclamped it ran to three lines
   at 390px and pushed the banner to 34%, consuming the dashboard it is supposed to introduce.
   Two lines here, two in .adm-focus-what: the strip cannot grow no matter what a beat writes. */
#pg-admin .adm-focus-next{margin:.15rem 0 0;font-size:.78rem;font-weight:300;line-height:1.5;color:#5A5855;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}
#pg-admin .adm-focus-warn{margin:.3rem 0 0;padding-top:.3rem;border-top:1px dashed rgba(58,58,58,.10);font-family:'Chalkduster',cursive;font-size:.78rem;line-height:1.45;color:#8A2020}
/* the dashed rule marks where the warnings START. Repeating it between them cost a border, .3rem
   of padding and .3rem of margin per extra warning — ~10px each — and read as a list of unrelated
   notices rather than one stack of reasons not to trust the line above. The words are untouched. */
#pg-admin .adm-focus-warn+.adm-focus-warn{margin-top:.15rem;padding-top:0;border-top:none}
/* ⚠️ NOT display:flex. admin.js builds this line as spans interleaved with bare text ("who" ·
   "on your ladder" · "tokens"), and a flex container turns every text run into its own item — the
   phrase would wrap at the wrong words. Normal inline flow keeps his sentence a sentence. */
#pg-admin .adm-focus-meta{margin:.3rem 0 0;font-size:.75rem;font-weight:300;line-height:1.55;color:#5A5855}
/* a failed read is louder than an empty one, and it sits in the strip's rhythm, not centred */
#pg-admin .adm-focus .adm-unknown{text-align:left;padding:0;font-size:.85rem}
/* the tap-through, which says what it does and nothing more. :not(.btn-px) so that if admin.js ever
   hands it the site's pixel button, THAT keeps its own white-on-teal and my ink never lands on it. */
#pg-admin .adm-focus-go:not(.btn-px){display:inline-flex;align-items:center;gap:6px;margin-top:.15rem;padding:0 2px;background:none;border:none;border-bottom:1px dashed transparent;cursor:pointer;font-family:'Chalkduster',cursive;font-size:.78rem;text-align:left;color:#1F5A5F}
/* ⚠️ NO 44px THUMB ON THE HINT LINE. admin.js makes the WHOLE STRIP the control (tappable(wrap)),
   and that is 200-390px tall — far past the floor. Reserving another 44px here for a <p> that is
   not the control cost 25px of his phone. It takes the thumb back only if it becomes the control. */
#pg-admin button.adm-focus-go,#pg-admin .adm-focus-go[role="button"],#pg-admin .adm-focus-go[tabindex]{min-height:44px}
#pg-admin .adm-focus[role="button"]:hover .adm-focus-go:not(.btn-px){border-bottom-color:rgba(48,120,120,.4)}

/* THE STATES — ink only, and every one of them ≥ 4.5:1 on #FAFAF5. Two hooks, both of which
   admin.js writes on .adm-focus itself: the coarse tone CLASS and the precise data-state. Either
   one alone lands the ink, so a refactor that drops one cannot silently grey the strip out.
   ⚠️ Nothing here fires on an ancestor or a child — the state belongs on .adm-focus. */
/* LIVE — teal-dk #1F5A5F on #FAFAF5 = 7.47:1 */
#pg-admin .adm-focus.live,#pg-admin .adm-focus[data-state="live"]{--focus-ink:#1F5A5F}
/* LATE — #8A2020 (the badge red text, L58) on #FAFAF5 = 8.69:1, and the paper's own edge reddens */
#pg-admin .adm-focus.late,#pg-admin .adm-focus[data-state="late"]{--focus-ink:#8A2020;border-color:rgba(181,53,53,.30)}
/* QUIET — a quiet beat claims nothing, so it takes no colour; the 🧘 sticker carries it. 6.77:1 */
#pg-admin .adm-focus.quiet,#pg-admin .adm-focus[data-state="quiet"]{--focus-ink:#5A5855}
/* STOPPED — settled, nothing in flight. #3A6A28 = 6.13:1. admin.js mints no `stopped` tone today;
   the rule is here because its FOCUS_TONE comment names this file's five ink states. */
#pg-admin .adm-focus.stopped{--focus-ink:#3A6A28}
/* UNKNOWN — a wrong clock, a failed transcript, an unreadable file. var(--red) #B53535 = 5.69:1,
   matching .adm-unknown (L79), and the paper goes dashed so it looks wrong rather than ordinary. */
#pg-admin .adm-focus.unknown,#pg-admin .adm-focus[data-state="unreadable"]{--focus-ink:#B53535;border-color:rgba(181,53,53,.30);border-style:dashed}

/* ── 🗂️ THE CATEGORISED PLAN · everything being worked on, in his categories ─────────────
   His 09:25 words: "a really clean and organized list of all the different things that are being
   worked on and organized into clear categories." THE PLAN used to drawer by Formula STAGE, which
   is process; renderPlanByCategory now drawers by the board's own `group` — the BACKLOG's real
   sections — which is what the time is going ON. The rows inside are still the board's own
   .adm-row / .adm-line / .adm-title, styled at L202-208, and they render inside #adm-board, so
   nothing here restyles a row. ⚠️ If this list ever moves out of #adm-board it loses that styling.

   ⚠️ A CATEGORY NAME IS NOT A TAPE. Twelve of the eighteen group names carry a glyph EmbossT1
   cannot draw ( · ( ) : / ), so a tape would render them with holes in. The name is set in the
   body face at fw600 #3A3A3A, and a midpoint dot inside one still needs its own .adm-dot span.
   Names run 5 to 192 characters, so nothing here is nowrap: they wrap on the #pg-admin
   overflow-wrap:anywhere + min-width:0 rules (L31-32).
   ⛔ NO SIDE-TAB ACCENT BARS, and no coloured slab standing in for a category. A category is a
   drawer with a name and a count; status colour stays where it already lives in HEART — on the
   row's glyph, which admin.js colours inline from GLYPH, and on the badge wash. */
#pg-admin details.adm-cat{margin:.5rem 0}   /* categories are the top level here, so a little more air than a plain drawer (L100) */
/* the name and the count in the summary. The summary itself is drawer()'s .adm-d (L91) — this only
   dresses what is inside it. #3A3A3A on the summary's ground = 9.63:1. */
#pg-admin .adm-cat-name{flex:1 1 auto;min-width:0;font-family:'Avenir Next','Segoe UI',system-ui,sans-serif;font-size:.9rem;font-weight:600;line-height:1.4;color:#3A3A3A}
#pg-admin .adm-cat-count{flex:0 0 auto;margin-left:auto;padding-left:8px;font-family:'Gaposiss','PixelGamer',monospace;font-size:.9rem;font-variant-numeric:tabular-nums;color:#3A3A3A}
/* the tally — "3 blocked · 5 on your yes" — in his handwriting, inherited from the summary. It is
   flex:0 0 auto so a long name pushes it onto its own line instead of squeezing the name. 6.00:1 */
#pg-admin .adm-cat-tally{flex:0 0 auto;font-size:.72rem;line-height:1.5;color:#5A5855}
/* the full heading and where it came from — printed because a clipped name must never be the only
   copy. Its .adm-key is a file and a line, so it wraps rather than pushing the column sideways. */
#pg-admin .adm-cat-sub{flex:1 1 100%;margin:.15rem 0 .35rem;font-family:'Chalkduster',cursive;font-size:.75rem;line-height:1.5;color:#5A5855}
#pg-admin .adm-cat-sub .adm-key{white-space:normal;overflow-wrap:anywhere}
/* the eight Formula-step counts, kept from the drawers this replaced so nothing left the page */
#pg-admin .adm-cat-note{margin:0 auto .8rem;max-width:520px;font-size:.8rem;line-height:1.9;color:#5A5855;text-align:center}
#pg-admin .adm-cat-step{display:inline-block;margin:0 5px;white-space:nowrap}
#pg-admin .adm-cat-step .adm-n{font-size:.82rem;color:#3A3A3A;margin-left:1px}
/* an empty category is DRAWN, never hidden — "Open questions for Deesil" has a good name and zero
   rows. ⚠️ But it must not be dimmed into illegibility: drawer()'s .dim is opacity .45, which puts
   #3A3A3A on this ground at 2.33:1 — a category he is meant to read, at a third of the floor. So
   the category keeps full strength here and steps back by WEIGHT and by saying so in words.
   (Measured: .45 → 2.33:1 · .7 → 4.24:1 · 1 → 9.66:1. There is no dim that both reads and fades.) */
#pg-admin details.adm-d.adm-cat.dim>summary{opacity:1}
#pg-admin .adm-cat.empty .adm-cat-name{font-weight:400}
#pg-admin .adm-cat-empty{margin:.1rem 0;padding:.35rem 0 .35rem .2rem;font-family:'Chalkduster',cursive;font-size:.8rem;color:#5A5855}
/* a group id with no heading in the file: flagged all the way round, never renamed, never dropped
   (his #43 rule). A dashed frame is a margin flag — it is not an accent bar and it is not on one side. */
#pg-admin .adm-cat.unknown{padding:6px 8px;border:1.5px dashed rgba(181,53,53,.35);border-radius:6px;background:rgba(181,53,53,.04)}
#pg-admin .adm-cat.unknown .adm-cat-name{font-family:'Chalkduster',cursive;font-weight:600;color:#8A2020}   /* 7.56:1 */
/* the sum, asserted in his handwriting — and when it does not add up, that sentence goes red
   instead of a total nobody checked. .warn arrives as a second class on the same <p>. */
#pg-admin .adm-cat-total{margin:.7rem 0 .2rem;font-family:'Chalkduster',cursive;font-size:.85rem;line-height:1.6;color:#5A5855;text-align:center}
#pg-admin .adm-cat-total .adm-n{font-size:1.1rem;color:#3A3A3A}
#pg-admin .adm-cat-total.warn{color:#8A2020;font-weight:600}

/* ── 💓 THE HEARTBEAT SWITCH AND THE PIN · adm-hb-* and adm-pin-* ────────────────────────
   His words, 6 Sept 2026 ~16:20, and they are the whole spec: "we should have like a cool
   visual like display of like kind of like an on-off switch of his heartbeat you know in the
   heart tab something kind of fun and visually that represents like it running and being on
   and like if I switch it off like something visual as well that shows that and then if it's
   not functioning something that shows that as well… A MENU AND A VISUAL ELEMENT THAT'S LIKE
   ACTUALLY CONNECTED PROPERLY AND FUNCTIONING WITH THE ACTUAL SYSTEM."
   And on the pin: "a pin that has essentially A LOCATION THAT TRACKS IT ON THE ACTUAL TO-DO
   LIST but then there's like A SHORTCUT TO THE PIN ON THE TOP OF THE PAGE."

   ⛔ THREE STATES, NEVER TWO — and this file draws a FOURTH on purpose:
     🟢 BEATING          it is running and working
     🌙 IDLE             HE switched it off; nothing is wrong
     🔴 NOT RESPONDING   nobody switched anything and it stopped anyway
     ❔ UNKNOWN          nothing has told this stylesheet which of the three is true
   The fourth is the reason the rest can be trusted. ⭐ EVERY DEFAULT BELOW IS THE UNKNOWN
   ONE: an unlit lamp with a dashed rim, a knob parked between the two positions, no glow and
   no pulse. So a markup change, a dropped class, a renamed token or a render that never ran
   CANNOT leave a green light on his screen. The failure direction of this whole block is
   "it says it does not know", never "it says it is fine".

   ⚠️ WHY IT IS APPENDED AND NOT FILED IN DOM ORDER: the same reason 🚀 LAUNCH and 🎠 THE FOCUS
   BANNER were. admin.js is being written in this same beat by another builder, with comments
   that cite admin.css line numbers; inserting 200 lines mid-file would silently invalidate
   every one of them. Move it into DOM order when the file is quiet.

   📐 WRITTEN AGAINST MARKUP THAT DID NOT EXIST YET. When these rules were written there was
   not one `adm-hb` or `adm-pin` string anywhere in the site (grepped admin.js, channel.js and
   index.html). So:
     · STATE TRAVELS AS CUSTOM PROPERTIES, NOT AS DESCENDANT CHAINS. The state rules set
       --hb-ink / --hb-lamp-* / --hb-knob-top on whatever element carries the state, and the
       parts read them through var() with an honest fallback. Custom properties inherit, so
       the state can land on the panel, on a wrapper, on the section, or on any single part of
       the family, and the light still changes. Nothing here says `.adm-hb .adm-hb-lamp`, and
       nothing re-declares a property between the state and the part — see .adm-hb below.
     · THE STATE SELECTOR IS `[class*="adm-hb"]`, so it matches every part of the family, the
       ones that exist today and the ones admin.js has not named yet, without this file having
       to know them. Plain attribute matching — nothing there for an old browser to drop.
     · EVERY PART STYLES ITSELF. .adm-hb-lamp is styled whether or not .adm-hb wraps it.
     · NO TAG SELECTORS where a class will do; the two exceptions (button.adm-hb-sw,
       details.adm-pin) only ADD behaviour that a tag genuinely implies.
     · BOTH HOOKS ACCEPTED for every state — a class and a data attribute — and the canonical
       longhand rule is written out before the :is() alias rule, so a browser without :is()
       loses the aliases and still lands the canonical state rather than the whole block.
     · NOTHING IS HIDDEN BY DEFAULT. There is no display:none in this block that could swallow
       markup this file has never seen. The one collapse is opt-in (.adm-pin-body.fold).

   ⛔ NO SIDE-TAB ACCENT BARS. The Garden's own pin strip carries its states on
   `border-left:3px solid #D4614E/#C49538/#559C40` (grant-garden/index.html L10589-10590) and
   that exact pattern was flagged on this codebase today and removed. Here the state rides on
   the LAMP (shape, fill, rim), the KNOB POSITION, the STAMPED WORD and, for the loud one, a
   frame that goes all the way round. The only edge treatment is the §5.6 stuck-TOP-edge wash
   that .adm-note::before (L136) and .adm-focus::before (L346) already use.

   ⛔ AND IT MUST NOT LOOK READY IF IT IS NOT WIRED. He has been shown fake controls twice
   today. .adm-hb-sw[disabled] / [aria-disabled="true"] / .unavailable strips the switch of
   every affordance — the knob loses its lift, the track goes hatched, the cursor says
   not-allowed — and .adm-hb-why prints the reason at full contrast. A switch that cannot
   reach the sheet must read as OUT OF ORDER, not as OFF.

   🎨 CONTRAST, measured, not remembered. The plate is #FAFAF5 (--card, §3.1 card paper, never
   pure white §11). Every text colour in this block, computed against the ground it actually
   sits on, is noted at its rule. ⛔ #7A7775 on #FAFAF5 is 4.25:1 and appears NOWHERE here:
   the ages, the notes and the reasons are the honesty mechanism and none of them may sit
   under the floor. */

/* ── the plate: a slip of card paper laid on the notebook, the .adm-focus recipe (L320) ── */
/* ⛔ NOT ONE CUSTOM PROPERTY IS DECLARED HERE, AND THAT IS THE WHOLE MECHANISM.
   The first cut set the UNKNOWN defaults on this rule, and the harness caught what that costs:
   a state set on an ANCESTOR (the section, or a wrapper admin.js invents) inherits down — and
   then this rule re-declares it at a level closer to the lamp and WINS. State on a wrapper
   landed on nothing; a beating heart rendered as UNKNOWN. Every default now lives in the var()
   fallback at the point of use instead, so nothing between the state and the part can overwrite
   it. Measured before and after in a puppeteer harness at a true 390.
   ⭐ THE FALLBACKS ARE THE UNKNOWN STATE: an unlit dashed lens, a knob parked between the two
   positions, no glow, no pulse. So "no state anywhere" and "a state we do not recognise" both
   land on "I do not know", and neither can land on green. */
#pg-admin .adm-hb{
  display:flow-root;position:relative;
  width:calc(100% - 4px);                             /* 4px of slack absorbs the tilt at a true 390px */
  max-width:640px;margin:.1rem auto .9rem;
  padding:12px 13px 13px;
  background:var(--hb-plate,#FAFAF5);
  border:var(--hb-edge-w,1px) var(--hb-edge-style,solid) var(--hb-edge,rgba(58,58,58,.12));
  border-radius:2px 2px 4px 4px;                      /* stuck top edge square, free bottom softer (§5.6) */
  box-shadow:1px 2px 4px rgba(0,0,0,.10),0 10px 14px -9px rgba(0,0,0,.30);
  transform:rotate(-.35deg);                          /* hand-placed and STATIC. ⚠️ a transform makes this a
                                                         containing block: nothing inside may be position:fixed */
  font-size:.92rem;line-height:1.6;color:#5A5855      /* 6.77:1 on #FAFAF5 */
}
/* the stuck edge, verbatim from .adm-note::before (L136) — full width, black, no hue. It is the
   opposite of a coloured bar down one side, which is the thing that was removed today. */
#pg-admin .adm-hb::before{content:'';position:absolute;top:0;left:0;right:0;height:14px;border-radius:2px 2px 0 0;background:linear-gradient(180deg,rgba(0,0,0,.07),transparent);pointer-events:none}
/* if the builder nests a named plate inside the panel, only ONE of them is paper — otherwise the
   slip renders twice, one inside the other, with two shadows and two tilts */
#pg-admin .adm-hb .adm-hb-plate{background:none;border:none;box-shadow:none;padding:0;transform:none;margin:0}
#pg-admin .adm-hb .adm-hb-plate::before{display:none}
/* and if the plate is used ALONE, it is the paper */
#pg-admin .adm-hb-plate{position:relative;background:var(--hb-plate,#FAFAF5);border:var(--hb-edge-w,1px) var(--hb-edge-style,solid) var(--hb-edge,rgba(58,58,58,.12));border-radius:2px 2px 4px 4px;padding:12px 13px 13px}

/* ── the head: lamp · words · switch. Wraps rather than overflowing at 390. ── */
/* ⚠️ flex-START, not center. The lamp is a picture of the stamped word, so the two line up at the
   top of the column; centred, the lamp drifted to the middle of a tall column and read as loose
   furniture rather than as the plate's own light. Measured in the harness at a true 390. */
#pg-admin .adm-hb-head{display:flex;align-items:flex-start;flex-wrap:wrap;gap:10px 14px;min-width:0}
#pg-admin .adm-hb-col{flex:1 1 150px;min-width:0}    /* the words column shrinks before anything overflows */

/* ── 🔦 THE LAMP BEHIND GLASS · the visual element he asked for ──────────────────────────
   ⛔ IT MUST NOT SPEAK IN COLOUR ALONE (he reads this in sunlight, and colour-blind users
   exist). Three things change with the state and only one of them is hue:
     SHAPE   a round lens (beating, idle) vs a hard-cornered square (not responding)
     FILL    a filled, lit lens (beating) vs a hollow ring with a hole in it (idle, stopped)
     RIM     a 2px solid hairline (beating) · a 3px solid ring (idle) · 3px DASHED (stopped)
   Rendered in greyscale, beating is a solid disc, idle is a donut and not-responding is a
   broken-edged square. The colour is the fourth signal, not the first.
   ⚠️ NO ::before/::after GLYPH IS DRAWN INSIDE THE LAMP. admin.js may put a foam sticker in
   there (🟢 🌙 🔴) and a pseudo-element cross would land on top of it. The state is carried by
   the box the sticker sits in, which can never collide with the box's contents. */
#pg-admin .adm-hb-lamp,#pg-admin .adm-hb-light{
  position:relative;flex:0 0 auto;
  width:58px;height:58px;                             /* ≥44px in both axes even if it is made tappable */
  display:inline-flex;align-items:center;justify-content:center;
  font-size:1.5rem;line-height:1;
  border-radius:var(--hb-lamp-radius,50%);
  background:var(--hb-lamp-fill,radial-gradient(circle at 50% 42%,#E9E7E0 0%,#F3F1EB 78%));
  border:var(--hb-lamp-rim,2px dashed rgba(58,58,58,.34));
  box-shadow:var(--hb-lamp-glow,inset 0 3px 7px rgba(0,0,0,.16));
  animation:var(--hb-lamp-beat,none)
}
/* ❤️ THE RAINBOW HEART, IN 3-D, WITH THE RAINBOW GLIDING THROUGH IT — his 6 Sept design note.
   ⭐ IT IS THE SAME HEART AS THE NAV BUTTON. .heart-rb (index.html L48) already clips the five
   Power-Up colours into a ♥ glyph; admin.js puts that exact class here so there is ONE rainbow on
   this site, not two that drift. Everything below only adds depth and motion to it.
   · THE GLIDE — the gradient is stretched to 300% and its position animated, so the colours slide
     THROUGH the heart shape instead of the shape moving. That is the ombré he asked for, and it is
     the reason the size is 300%: at 100% there is nothing off-screen to slide in.
   · THE 3-D — a real emoji heart is glossy and sits above the paper. Two things do that here: a
     drop-shadow beneath it so it lifts off the disc, and a white sheen laid over the top-left of
     the glyph. ⚠️ The sheen has to be a SECOND BACKGROUND LAYER, not a pseudo-element: the glyph is
     painted by background-clip:text, and a ::after would sit over the letterform as a rectangle.
   · THE DISC stays grey in every state — his ask — so the state is carried by motion, the rim, the
     badge word and the switch position instead of by the lamp's colour. */
#pg-admin .adm-hb-heart{
  font-family:'Avenir Next','Segoe UI',system-ui,sans-serif;font-weight:900;line-height:1;
  font-size:1.9rem;display:inline-block;
  background-image:
    linear-gradient(158deg,rgba(255,255,255,.55) 0%,rgba(255,255,255,.16) 26%,rgba(255,255,255,0) 46%),
    linear-gradient(90deg,#C13B2A 0.0000%,#C23C2A 0.1302%,#C33D29 0.2604%,#C33E29 0.3906%,#C44028 0.5208%,#C54128 0.6510%,#C64228 0.7812%,#C74327 0.9115%,#C84427 1.0417%,#C84627 1.1719%,#C94726 1.3021%,#CA4826 1.4323%,#CB4A25 1.5625%,#CC4B25 1.6927%,#CD4C25 1.8229%,#CD4E24 1.9531%,#CE4F24 2.0833%,#CF5123 2.2135%,#D05223 2.3438%,#D15423 2.4740%,#D25522 2.6042%,#D25722 2.7344%,#D35821 2.8646%,#D45A21 2.9948%,#D55B21 3.1250%,#D65D20 3.2552%,#D75E20 3.3854%,#D7601F 3.5156%,#D8621F 3.6458%,#D9641E 3.7760%,#DA651E 3.9062%,#DB671E 4.0365%,#DC691D 4.1667%,#DD6B1D 4.2969%,#DE6C1C 4.4271%,#DE6E1C 4.5573%,#DF701B 4.6875%,#E0721B 4.8177%,#E1741B 4.9479%,#E2761A 5.0781%,#E3781A 5.2083%,#E47A19 5.3385%,#E57C19 5.4688%,#E57E18 5.5990%,#E68018 5.7292%,#E78218 5.8594%,#E88417 5.9896%,#E88617 6.1198%,#E98817 6.2500%,#E98917 6.3802%,#E98B16 6.5104%,#E98C16 6.6406%,#E98D16 6.7708%,#E98F15 6.9010%,#E99015 7.0312%,#E99215 7.1615%,#E99315 7.2917%,#E89415 7.4219%,#E89615 7.5521%,#E89714 7.6823%,#E89814 7.8125%,#E89A14 7.9427%,#E89B14 8.0729%,#E79C14 8.2031%,#E79E14 8.3333%,#E79F14 8.4635%,#E7A013 8.5938%,#E7A213 8.7240%,#E7A313 8.8542%,#E6A513 8.9844%,#E6A613 9.1146%,#E6A713 9.2448%,#E6A912 9.3750%,#E6AA12 9.5052%,#E6AB12 9.6354%,#E6AD12 9.7656%,#E5AE12 9.8958%,#E5AF12 10.0260%,#E5B112 10.1562%,#E5B211 10.2865%,#E5B311 10.4167%,#E5B511 10.5469%,#E4B611 10.6771%,#E4B711 10.8073%,#E4B911 10.9375%,#E4BA11 11.0677%,#E4BC10 11.1979%,#E4BD10 11.3281%,#E3BE10 11.4583%,#E3C010 11.5885%,#E3C110 11.7188%,#E3C210 11.8490%,#E3C410 11.9792%,#E3C50F 12.1094%,#E2C60F 12.2396%,#E2C80F 12.3698%,#E2C90F 12.5000%,#E1CB10 12.6302%,#E1CD11 12.7604%,#E0CF12 12.8906%,#E0D112 13.0208%,#DFD213 13.1510%,#DED414 13.2812%,#DED615 13.4115%,#DDD816 13.5417%,#DCD917 13.6719%,#DCDB17 13.8021%,#DADB18 13.9323%,#D7DB19 14.0625%,#D4DA1A 14.1927%,#D2D91B 14.3229%,#CFD91C 14.4531%,#CCD81D 14.5833%,#CAD71D 14.7135%,#C7D71E 14.8438%,#C4D61F 14.9740%,#C2D620 15.1042%,#BFD521 15.2344%,#BDD422 15.3646%,#BAD423 15.4948%,#B8D324 15.6250%,#B5D224 15.7552%,#B3D225 15.8854%,#B1D126 16.0156%,#AED027 16.1458%,#ACD028 16.2760%,#AACF29 16.4062%,#A8CE2A 16.5365%,#A6CE2B 16.6667%,#A4CD2B 16.7969%,#A1CC2C 16.9271%,#9FCC2D 17.0573%,#9DCB2E 17.1875%,#9BCA2F 17.3177%,#99CA30 17.4479%,#98C931 17.5781%,#96C832 17.7083%,#94C833 17.8385%,#92C734 17.9688%,#90C634 18.0990%,#8FC635 18.2292%,#8DC536 18.3594%,#8BC437 18.4896%,#8AC438 18.6198%,#88C339 18.7500%,#83C239 18.8802%,#7EC23A 19.0104%,#79C13A 19.1406%,#75C13B 19.2708%,#70C03B 19.4010%,#6BBF3C 19.5312%,#67BF3C 19.6615%,#63BE3D 19.7917%,#5EBE3D 19.9219%,#5ABD3E 20.0521%,#56BC3E 20.1823%,#52BC3F 20.3125%,#4EBB3F 20.4427%,#4ABB40 20.5729%,#46BA40 20.7031%,#42BA41 20.8333%,#41B944 20.9635%,#42B849 21.0938%,#42B84D 21.2240%,#43B752 21.3542%,#43B756 21.4844%,#44B65B 21.6146%,#44B55F 21.7448%,#45B563 21.8750%,#45B467 22.0052%,#46B46B 22.1354%,#46B36F 22.2656%,#47B373 22.3958%,#47B277 22.5260%,#47B17B 22.6562%,#48B17E 22.7865%,#48B082 22.9167%,#49B085 23.0469%,#49AF89 23.1771%,#4AAE8C 23.3073%,#4AAE8F 23.4375%,#4BAD93 23.5677%,#4BAD96 23.6979%,#4CAC99 23.8281%,#4CAC9C 23.9583%,#4DAB9F 24.0885%,#4DAAA1 24.2188%,#4EAAA4 24.3490%,#4EA9A7 24.4792%,#4FA8A9 24.6094%,#4FA4A8 24.7396%,#50A1A8 24.8698%,#509DA7 25.0000%,#4F9DA9 25.1302%,#4F9EAA 25.2604%,#4E9EAC 25.3906%,#4E9EAD 25.5208%,#4D9FAF 25.6510%,#4D9FB0 25.7812%,#4C9FB2 25.9115%,#4B9FB3 26.0417%,#4B9FB5 26.1719%,#4B9FB6 26.3021%,#4A9FB7 26.4323%,#4A9FB8 26.5625%,#4A9FB9 26.6927%,#4A9FBA 26.8229%,#4A9EBB 26.9531%,#499EBD 27.0833%,#499EBE 27.2135%,#499DBF 27.3438%,#499DC0 27.4740%,#499DC1 27.6042%,#499CC2 27.7344%,#489CC3 27.8646%,#489BC4 27.9948%,#489BC5 28.1250%,#489AC6 28.2552%,#489AC7 28.3854%,#4899C8 28.5156%,#4898CA 28.6458%,#4898CB 28.7760%,#4897CC 28.9062%,#4796CD 29.0365%,#4796CE 29.1667%,#4795CF 29.2969%,#4794D0 29.4271%,#4794D1 29.5573%,#4793D2 29.6875%,#4792D3 29.8177%,#4791D4 29.9479%,#4790D5 30.0781%,#478FD6 30.2083%,#478FD6 30.3385%,#478ED7 30.4688%,#478DD8 30.5990%,#478CD9 30.7292%,#478BDA 30.8594%,#478ADB 30.9896%,#4789DC 31.1198%,#4788DD 31.2500%,#4683DC 31.3802%,#457EDB 31.5104%,#4579D9 31.6406%,#4474D8 31.7708%,#436ED7 31.9010%,#4269D6 32.0312%,#4165D4 32.1615%,#4160D3 32.2917%,#405BD2 32.4219%,#3F56D1 32.5521%,#3F51CF 32.6823%,#3E4CCE 32.8125%,#3D48CC 32.9427%,#3D43CB 33.0729%,#3C3ECA 33.2031%,#3D3BC8 33.3333%,#403BC7 33.4635%,#443AC5 33.5938%,#473AC3 33.7240%,#4B3BC1 33.8542%,#4F3BBE 33.9844%,#533CBC 34.1146%,#563CB9 34.2448%,#593DB7 34.3750%,#5C3DB4 34.5052%,#5F3EB2 34.6354%,#623EAF 34.7656%,#653EAD 34.8958%,#673FAB 35.0260%,#693FA8 35.1562%,#6B40A6 35.2865%,#6D40A3 35.4167%,#6F40A1 35.5469%,#71419F 35.6771%,#72419C 35.8073%,#74419A 35.9375%,#754198 36.0677%,#764296 36.1979%,#774293 36.3281%,#784291 36.4583%,#78428F 36.5885%,#79428D 36.7188%,#7A428B 36.8490%,#7A4388 36.9792%,#7A4386 37.1094%,#7A4384 37.2396%,#7A4382 37.3698%,#7A4380 37.5000%,#7C4381 37.6302%,#7D4382 37.7604%,#7F4382 37.8906%,#804383 38.0208%,#824384 38.1510%,#844385 38.2812%,#864386 38.4115%,#864385 38.5417%,#874285 38.6719%,#884285 38.8021%,#894285 38.9323%,#8A4285 39.0625%,#8A4284 39.1927%,#8B4284 39.3229%,#8C4284 39.4531%,#8D4283 39.5833%,#8E4283 39.7135%,#8E4283 39.8438%,#8F4282 39.9740%,#904282 40.1042%,#914181 40.2344%,#924181 40.3646%,#934180 40.4948%,#934180 40.6250%,#94417F 40.7552%,#95417F 40.8854%,#96417E 41.0156%,#97417D 41.1458%,#98417D 41.2760%,#98407C 41.4062%,#99407B 41.5365%,#9A407B 41.6667%,#9B407A 41.7969%,#9C4079 41.9271%,#9D4078 42.0573%,#9E4077 42.1875%,#9E4076 42.3177%,#9F3F76 42.4479%,#A03F75 42.5781%,#A13F74 42.7083%,#A23F73 42.8385%,#A33F72 42.9688%,#A43F71 43.0990%,#A43F70 43.2292%,#A53E6E 43.3594%,#A63E6D 43.4896%,#A73E6C 43.6198%,#A83E6B 43.7500%,#A93E6A 43.8802%,#A93D69 44.0104%,#AA3D67 44.1406%,#AA3C66 44.2708%,#AB3C65 44.4010%,#AB3C63 44.5312%,#AC3B62 44.6615%,#AC3B61 44.7917%,#AD3A5F 44.9219%,#AD3A5E 45.0521%,#AE395D 45.1823%,#AE395B 45.3125%,#AF395A 45.4427%,#AF3858 45.5729%,#B03857 45.7031%,#B03755 45.8333%,#B13754 45.9635%,#B13752 46.0938%,#B23650 46.2240%,#B2364F 46.3542%,#B3354D 46.4844%,#B3354B 46.6146%,#B4354A 46.7448%,#B43448 46.8750%,#B53446 47.0052%,#B53345 47.1354%,#B63343 47.2656%,#B63241 47.3958%,#B7323F 47.5260%,#B8323E 47.6562%,#B8313C 47.7865%,#B9313A 47.9167%,#B93038 48.0469%,#BA3036 48.1771%,#BA3034 48.3073%,#BB2F32 48.4375%,#BB2F30 48.5677%,#BC2E2E 48.6979%,#BC302E 48.8281%,#BD312D 48.9583%,#BD322D 49.0885%,#BE332D 49.2188%,#BE342C 49.3490%,#BF362C 49.4792%,#BF372B 49.6094%,#C0382B 49.7396%,#C03A2A 49.8698%,#C13B2A 50.0000%,#C23C2A 50.1302%,#C33D29 50.2604%,#C33E29 50.3906%,#C44028 50.5208%,#C54128 50.6510%,#C64228 50.7812%,#C74327 50.9115%,#C84427 51.0417%,#C84627 51.1719%,#C94726 51.3021%,#CA4826 51.4323%,#CB4A25 51.5625%,#CC4B25 51.6927%,#CD4C25 51.8229%,#CD4E24 51.9531%,#CE4F24 52.0833%,#CF5123 52.2135%,#D05223 52.3438%,#D15423 52.4740%,#D25522 52.6042%,#D25722 52.7344%,#D35821 52.8646%,#D45A21 52.9948%,#D55B21 53.1250%,#D65D20 53.2552%,#D75E20 53.3854%,#D7601F 53.5156%,#D8621F 53.6458%,#D9641E 53.7760%,#DA651E 53.9062%,#DB671E 54.0365%,#DC691D 54.1667%,#DD6B1D 54.2969%,#DE6C1C 54.4271%,#DE6E1C 54.5573%,#DF701B 54.6875%,#E0721B 54.8177%,#E1741B 54.9479%,#E2761A 55.0781%,#E3781A 55.2083%,#E47A19 55.3385%,#E57C19 55.4688%,#E57E18 55.5990%,#E68018 55.7292%,#E78218 55.8594%,#E88417 55.9896%,#E88617 56.1198%,#E98817 56.2500%,#E98917 56.3802%,#E98B16 56.5104%,#E98C16 56.6406%,#E98D16 56.7708%,#E98F15 56.9010%,#E99015 57.0312%,#E99215 57.1615%,#E99315 57.2917%,#E89415 57.4219%,#E89615 57.5521%,#E89714 57.6823%,#E89814 57.8125%,#E89A14 57.9427%,#E89B14 58.0729%,#E79C14 58.2031%,#E79E14 58.3333%,#E79F14 58.4635%,#E7A013 58.5938%,#E7A213 58.7240%,#E7A313 58.8542%,#E6A513 58.9844%,#E6A613 59.1146%,#E6A713 59.2448%,#E6A912 59.3750%,#E6AA12 59.5052%,#E6AB12 59.6354%,#E6AD12 59.7656%,#E5AE12 59.8958%,#E5AF12 60.0260%,#E5B112 60.1562%,#E5B211 60.2865%,#E5B311 60.4167%,#E5B511 60.5469%,#E4B611 60.6771%,#E4B711 60.8073%,#E4B911 60.9375%,#E4BA11 61.0677%,#E4BC10 61.1979%,#E4BD10 61.3281%,#E3BE10 61.4583%,#E3C010 61.5885%,#E3C110 61.7188%,#E3C210 61.8490%,#E3C410 61.9792%,#E3C50F 62.1094%,#E2C60F 62.2396%,#E2C80F 62.3698%,#E2C90F 62.5000%,#E1CB10 62.6302%,#E1CD11 62.7604%,#E0CF12 62.8906%,#E0D112 63.0208%,#DFD213 63.1510%,#DED414 63.2812%,#DED615 63.4115%,#DDD816 63.5417%,#DCD917 63.6719%,#DCDB17 63.8021%,#DADB18 63.9323%,#D7DB19 64.0625%,#D4DA1A 64.1927%,#D2D91B 64.3229%,#CFD91C 64.4531%,#CCD81D 64.5833%,#CAD71D 64.7135%,#C7D71E 64.8438%,#C4D61F 64.9740%,#C2D620 65.1042%,#BFD521 65.2344%,#BDD422 65.3646%,#BAD423 65.4948%,#B8D324 65.6250%,#B5D224 65.7552%,#B3D225 65.8854%,#B1D126 66.0156%,#AED027 66.1458%,#ACD028 66.2760%,#AACF29 66.4062%,#A8CE2A 66.5365%,#A6CE2B 66.6667%,#A4CD2B 66.7969%,#A1CC2C 66.9271%,#9FCC2D 67.0573%,#9DCB2E 67.1875%,#9BCA2F 67.3177%,#99CA30 67.4479%,#98C931 67.5781%,#96C832 67.7083%,#94C833 67.8385%,#92C734 67.9688%,#90C634 68.0990%,#8FC635 68.2292%,#8DC536 68.3594%,#8BC437 68.4896%,#8AC438 68.6198%,#88C339 68.7500%,#83C239 68.8802%,#7EC23A 69.0104%,#79C13A 69.1406%,#75C13B 69.2708%,#70C03B 69.4010%,#6BBF3C 69.5312%,#67BF3C 69.6615%,#63BE3D 69.7917%,#5EBE3D 69.9219%,#5ABD3E 70.0521%,#56BC3E 70.1823%,#52BC3F 70.3125%,#4EBB3F 70.4427%,#4ABB40 70.5729%,#46BA40 70.7031%,#42BA41 70.8333%,#41B944 70.9635%,#42B849 71.0938%,#42B84D 71.2240%,#43B752 71.3542%,#43B756 71.4844%,#44B65B 71.6146%,#44B55F 71.7448%,#45B563 71.8750%,#45B467 72.0052%,#46B46B 72.1354%,#46B36F 72.2656%,#47B373 72.3958%,#47B277 72.5260%,#47B17B 72.6562%,#48B17E 72.7865%,#48B082 72.9167%,#49B085 73.0469%,#49AF89 73.1771%,#4AAE8C 73.3073%,#4AAE8F 73.4375%,#4BAD93 73.5677%,#4BAD96 73.6979%,#4CAC99 73.8281%,#4CAC9C 73.9583%,#4DAB9F 74.0885%,#4DAAA1 74.2188%,#4EAAA4 74.3490%,#4EA9A7 74.4792%,#4FA8A9 74.6094%,#4FA4A8 74.7396%,#50A1A8 74.8698%,#509DA7 75.0000%,#4F9DA9 75.1302%,#4F9EAA 75.2604%,#4E9EAC 75.3906%,#4E9EAD 75.5208%,#4D9FAF 75.6510%,#4D9FB0 75.7812%,#4C9FB2 75.9115%,#4B9FB3 76.0417%,#4B9FB5 76.1719%,#4B9FB6 76.3021%,#4A9FB7 76.4323%,#4A9FB8 76.5625%,#4A9FB9 76.6927%,#4A9FBA 76.8229%,#4A9EBB 76.9531%,#499EBD 77.0833%,#499EBE 77.2135%,#499DBF 77.3438%,#499DC0 77.4740%,#499DC1 77.6042%,#499CC2 77.7344%,#489CC3 77.8646%,#489BC4 77.9948%,#489BC5 78.1250%,#489AC6 78.2552%,#489AC7 78.3854%,#4899C8 78.5156%,#4898CA 78.6458%,#4898CB 78.7760%,#4897CC 78.9062%,#4796CD 79.0365%,#4796CE 79.1667%,#4795CF 79.2969%,#4794D0 79.4271%,#4794D1 79.5573%,#4793D2 79.6875%,#4792D3 79.8177%,#4791D4 79.9479%,#4790D5 80.0781%,#478FD6 80.2083%,#478FD6 80.3385%,#478ED7 80.4688%,#478DD8 80.5990%,#478CD9 80.7292%,#478BDA 80.8594%,#478ADB 80.9896%,#4789DC 81.1198%,#4788DD 81.2500%,#4683DC 81.3802%,#457EDB 81.5104%,#4579D9 81.6406%,#4474D8 81.7708%,#436ED7 81.9010%,#4269D6 82.0312%,#4165D4 82.1615%,#4160D3 82.2917%,#405BD2 82.4219%,#3F56D1 82.5521%,#3F51CF 82.6823%,#3E4CCE 82.8125%,#3D48CC 82.9427%,#3D43CB 83.0729%,#3C3ECA 83.2031%,#3D3BC8 83.3333%,#403BC7 83.4635%,#443AC5 83.5938%,#473AC3 83.7240%,#4B3BC1 83.8542%,#4F3BBE 83.9844%,#533CBC 84.1146%,#563CB9 84.2448%,#593DB7 84.3750%,#5C3DB4 84.5052%,#5F3EB2 84.6354%,#623EAF 84.7656%,#653EAD 84.8958%,#673FAB 85.0260%,#693FA8 85.1562%,#6B40A6 85.2865%,#6D40A3 85.4167%,#6F40A1 85.5469%,#71419F 85.6771%,#72419C 85.8073%,#74419A 85.9375%,#754198 86.0677%,#764296 86.1979%,#774293 86.3281%,#784291 86.4583%,#78428F 86.5885%,#79428D 86.7188%,#7A428B 86.8490%,#7A4388 86.9792%,#7A4386 87.1094%,#7A4384 87.2396%,#7A4382 87.3698%,#7A4380 87.5000%,#7C4381 87.6302%,#7D4382 87.7604%,#7F4382 87.8906%,#804383 88.0208%,#824384 88.1510%,#844385 88.2812%,#864386 88.4115%,#864385 88.5417%,#874285 88.6719%,#884285 88.8021%,#894285 88.9323%,#8A4285 89.0625%,#8A4284 89.1927%,#8B4284 89.3229%,#8C4284 89.4531%,#8D4283 89.5833%,#8E4283 89.7135%,#8E4283 89.8438%,#8F4282 89.9740%,#904282 90.1042%,#914181 90.2344%,#924181 90.3646%,#934180 90.4948%,#934180 90.6250%,#94417F 90.7552%,#95417F 90.8854%,#96417E 91.0156%,#97417D 91.1458%,#98417D 91.2760%,#98407C 91.4062%,#99407B 91.5365%,#9A407B 91.6667%,#9B407A 91.7969%,#9C4079 91.9271%,#9D4078 92.0573%,#9E4077 92.1875%,#9E4076 92.3177%,#9F3F76 92.4479%,#A03F75 92.5781%,#A13F74 92.7083%,#A23F73 92.8385%,#A33F72 92.9688%,#A43F71 93.0990%,#A43F70 93.2292%,#A53E6E 93.3594%,#A63E6D 93.4896%,#A73E6C 93.6198%,#A83E6B 93.7500%,#A93E6A 93.8802%,#A93D69 94.0104%,#AA3D67 94.1406%,#AA3C66 94.2708%,#AB3C65 94.4010%,#AB3C63 94.5312%,#AC3B62 94.6615%,#AC3B61 94.7917%,#AD3A5F 94.9219%,#AD3A5E 95.0521%,#AE395D 95.1823%,#AE395B 95.3125%,#AF395A 95.4427%,#AF3858 95.5729%,#B03857 95.7031%,#B03755 95.8333%,#B13754 95.9635%,#B13752 96.0938%,#B23650 96.2240%,#B2364F 96.3542%,#B3354D 96.4844%,#B3354B 96.6146%,#B4354A 96.7448%,#B43448 96.8750%,#B53446 97.0052%,#B53345 97.1354%,#B63343 97.2656%,#B63241 97.3958%,#B7323F 97.5260%,#B8323E 97.6562%,#B8313C 97.7865%,#B9313A 97.9167%,#B93038 98.0469%,#BA3036 98.1771%,#BA3034 98.3073%,#BB2F32 98.4375%,#BB2F30 98.5677%,#BC2E2E 98.6979%,#BC302E 98.8281%,#BD312D 98.9583%,#BD322D 99.0885%,#BE332D 99.2188%,#BE342C 99.3490%,#BF362C 99.4792%,#BF372B 99.6094%,#C0382B 99.7396%,#C03A2A 99.8698%,#C13B2A 100.0000%);
  background-size:100% 100%, 200% 100%;
  background-position:0 0, 0% 50%;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 1px 0 rgba(255,255,255,.75)) drop-shadow(0 2px 2px rgba(58,58,58,.34)) drop-shadow(0 4px 6px rgba(0,0,0,.18))
}
/* ⛔ THE DISC IS GREY IN EVERY STATE, overriding the per-state fills below — his words. The rim,
   the motion and the words carry the state; the lamp is the heart's resting place, not a signal. */
#pg-admin .adm-hb-lamp,#pg-admin .adm-hb-light{
  --hb-lamp-fill:radial-gradient(circle at 50% 40%,#F2F0EA 0%,#E4E1D9 62%,#D6D2C8 100%)
}
@media (prefers-reduced-motion:no-preference){
  /* 🟢 BEATING — the rainbow slides through the heart, and the heart throbs. Two different speeds
     on purpose: the glide is slow and continuous (it is alive), the throb is the pulse itself. */
  #pg-admin .adm-hb.beating .adm-hb-heart,#pg-admin [data-hb="beating"] .adm-hb-heart{
    animation:hbGlide 7s linear infinite, hbThrob 2.4s ease-in-out infinite
  }
  /* 🌙 IDLE — resting. The rainbow still drifts, very slowly, because it is ALIVE and choosing not
     to work, and a completely frozen heart is what NOT RESPONDING has to look like. */
  #pg-admin .adm-hb.idle .adm-hb-heart,#pg-admin [data-hb="idle"] .adm-hb-heart{
    animation:hbGlide 26s linear infinite
  }
}
/* 🔴 NOT RESPONDING — STILL. No glide, no throb, and the colour drains out of it. Stillness is the
   signal, and it is the one state that must never look busy. */
#pg-admin .adm-hb.dead .adm-hb-heart,#pg-admin [data-hb="dead"] .adm-hb-heart{
  animation:none!important;filter:grayscale(.82) drop-shadow(0 2px 2px rgba(58,58,58,.30))
}
#pg-admin .adm-hb.idle .adm-hb-heart,#pg-admin [data-hb="idle"] .adm-hb-heart{opacity:.72}
/* ⛔ THE SEAM. He caught it: "when it meets up with the pattern again there's a sharp line… if you
   were to freeze-frame this you'd see a sharp [edge] in the design." He was right, and the cause was
   arithmetic, not taste. The gradient held ONE rainbow and the travel was 0% → 300% of a 300%-wide
   image, so the animation ran off the end of the colours and snapped back to the start — a hard cut,
   once per loop, every time.
   ⭐ THE FIX IS TO MAKE THE END OF THE TRAVEL IDENTICAL TO ITS START: two whole rainbows in the
   gradient, closing on the colour it opened with, an image 200% of the box, and a travel of exactly
   0% → 100% — which under CSS percentage positioning slides through exactly one full cycle, landing
   on a frame pixel-identical to the one it left.
   ⛔ AND THE SHARP LINE WAS NOT THE WRAP AT ALL — it was VIOLET JUMPING STRAIGHT BACK TO RED.
   The five Power-Up colours run red → violet, so a loop that returns violet → red crosses the whole
   colour wheel in ONE stop while every other step crosses a seventh of it. That reads as a cut, and
   it is exactly what he described: "when it meets up with the pattern again there's a sharp line…
   if you were to freeze-frame this you'd see it." Two bridging hues now carry violet home the long
   way round — a magenta and a rose — so the loop closes on the gentlest step in the whole ramp.
   ⭐ AND IT IS INTERPOLATED THROUGH HUE, NOT THROUGH RGB, which is what finally made it smooth.
   Spacing the eight brand colours by RGB distance made every step change at the same MEASURED rate
   and he still saw it jump — because a straight line between two colours in sRGB cuts across the
   colour wheel through mud, and the eye sees that, whatever the arithmetic says. The ramp now walks
   the HUE forward between each pair and emits 18 stops per pair, so the browser is only ever
   interpolating a sliver and the sweep is a real rainbow. His words: "it needs to run between all
   the colors smoothly, it's kind of jumping in the middle of it."
   ⚠️ THE OLD NOTE BELOW IS KEPT because its lesson still holds and its conclusion did not.
   · superseded: the stops were spaced by colour distance, not evenly,
   Evenly spaced, green→teal still changed 1.68× faster than the average and read as an edge of its
   own, because the Power-Up colours are not evenly spaced in colour to begin with. Each stop now
   gets width in proportion to how far it has to travel, so the RATE of change is constant across
   the whole ramp and there is no step anywhere for the eye to catch. Measured, not judged.
   ⛔ AND IT HAD TO GO HORIZONTAL TOO, which is the part I got wrong twice. At 135° a HORIZONTAL
   shift does not advance a diagonal gradient by a whole cycle — it advances it by the projection
   onto the gradient axis — so the loop landed mid-colour and cut. I tried the diagonal three ways
   (shift = P/√2, P and P·√2 on both axes, with a repeating gradient) and freeze-framed each: all
   three still seamed. He offered the diagonal as an idea, not a requirement, and what he actually
   asked for was no sharp line. 90° gives that exactly, and it is PROVED rather than reasoned:
   the frames at 0% and 100% are compared pixel-for-pixel by dsproof's own freeze-frame test. */
@keyframes hbGlide{0%{background-position:0 0,0% 50%}100%{background-position:0 0,100% 50%}}
@keyframes hbThrob{0%,100%{transform:scale(1)}12%{transform:scale(1.13)}24%{transform:scale(1)}36%{transform:scale(1.07)}48%{transform:scale(1)}}

/* the glass. A gloss over the top-left quarter only, so a sticker underneath stays readable. */
#pg-admin .adm-hb-lamp::after,#pg-admin .adm-hb-light::after{content:'';position:absolute;inset:0;border-radius:inherit;background:linear-gradient(158deg,rgba(255,255,255,.42) 0 24%,rgba(255,255,255,0) 46%);pointer-events:none}

/* ── 🎚️ THE SWITCH · a wall plate with a knob, not a Material toggle ─────────────────────
   A vertical two-position switch: knob UP is BEAT, knob DOWN is IDLE. The position is a
   POSITION, which reads at a glance with no colour at all and reads in a photograph.
   The track is the postcard's own cardboard rhythm narrowed to a stripe — the itemEdge /
   .ck-board treatment in channel.js (L453, L2400) — in paper greys, so it is board and not a
   coloured slab. 62 × 100 px: past the 44px floor on both axes with room to spare. */
#pg-admin .adm-hb-sw,#pg-admin .adm-hb-switch{
  position:relative;flex:0 0 auto;
  width:62px;height:100px;min-width:48px;min-height:48px;
  padding:0;border-radius:11px;
  border:1.5px solid rgba(58,58,58,.20);
  background:
    repeating-linear-gradient(180deg,#E8E5DC 0 18px,#DEDAD0 18px 20px,#EFECE3 20px 44px,#DEDAD0 44px 46px,#E8E5DC 46px 68px,#DEDAD0 68px 70px,#EFECE3 70px 100px);
  box-shadow:inset 0 2px 6px rgba(0,0,0,.14),0 1px 0 rgba(255,255,255,.7);
  cursor:pointer;-webkit-appearance:none;appearance:none
}
#pg-admin .adm-hb-sw:focus-visible,#pg-admin .adm-hb-switch:focus-visible{outline:2px solid var(--teal);outline-offset:3px}
/* the knob — paper, with a real contact shadow, so it reads as an object sitting in a groove */
#pg-admin .adm-hb-knob{
  position:absolute;left:5px;right:5px;height:42px;
  top:var(--hb-knob-top,calc(50% - 21px));
  border-radius:7px;
  background:linear-gradient(180deg,#FFFDF7 0%,#F4F1E8 62%,#E9E5DA 100%);
  border:1px solid rgba(58,58,58,.22);
  box-shadow:0 2px 3px rgba(0,0,0,.22),0 7px 10px -7px rgba(0,0,0,.35),inset 0 1px 0 rgba(255,255,255,.9);
  transition:top .2s ease
}
/* the two grip lines on the knob — an object with a texture, the way a real switch has one */
#pg-admin .adm-hb-knob::after{content:'';position:absolute;left:50%;top:50%;width:20px;height:7px;transform:translate(-50%,-50%);background:repeating-linear-gradient(180deg,rgba(58,58,58,.20) 0 1px,transparent 1px 3px)}
/* the BEAT / IDLE words printed on the plate beside the track. PixelGamer, so never a comma,
   a full stop, an ampersand or a digit inside. #5A5855 on #FAFAF5 = 6.77:1 */
#pg-admin .adm-hb-lbl{font-family:'PixelGamer',monospace;font-size:.6rem;letter-spacing:.09em;color:#5A5855;line-height:1.9;text-align:center}
#pg-admin .adm-hb-lbl.on{color:#3A3A3A;font-weight:600}   /* 10.86:1 on #FAFAF5 */

/* ── 📋 THE MENU · the other half of what he asked for ───────────────────────────────────
   "a MENU and a visual element". The menu is two stamped cards, BEAT and IDLE. The chosen one
   is PRESSED IN — an inset shadow and no lift — so the choice reads by depth, not only by ink.
   Every hook a toggle can plausibly carry is accepted, because the markup was unseen. */
#pg-admin .adm-hb-menu{display:flex;flex-wrap:wrap;gap:8px;margin:.6rem 0 .2rem;align-items:center}
#pg-admin .adm-hb-opt{
  min-height:44px;display:inline-flex;align-items:center;gap:6px;
  padding:6px 14px;cursor:pointer;
  font-family:'PixelGamer',monospace;font-size:.72rem;letter-spacing:.06em;
  color:#5A5855;                                       /* 6.77:1 on #FAFAF5 */
  background:linear-gradient(180deg,#FFFDF7,#F2EFE6);
  border:1.5px solid rgba(58,58,58,.18);border-radius:4px;
  box-shadow:0 2px 0 rgba(58,58,58,.16),0 3px 6px -3px rgba(0,0,0,.25);
  transition:transform .1s,box-shadow .1s,border-color .15s
}
#pg-admin .adm-hb-opt:hover{border-color:var(--teal);color:var(--teal-dk)}   /* #1F5A5F on #FAFAF5 = 7.47:1 */
#pg-admin .adm-hb-opt:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
#pg-admin .adm-hb-opt:active{transform:translateY(2px);box-shadow:0 0 0 rgba(58,58,58,.16)}
/* the one that is currently chosen: pressed into the paper */
#pg-admin .adm-hb-opt.on,#pg-admin .adm-hb-opt.sel,#pg-admin .adm-hb-opt[aria-pressed="true"],#pg-admin .adm-hb-opt[aria-checked="true"]{
  color:#3A3A3A;font-weight:600;                        /* 10.86:1 on #FAFAF5 */
  background:linear-gradient(180deg,#EFECE3,#F7F4EC);
  border-color:rgba(58,58,58,.32);
  box-shadow:inset 0 2px 4px rgba(0,0,0,.18);transform:translateY(1px)
}

/* ── the words on the plate ── */
/* the state word, stamped. PixelGamer: letters and spaces only — BEATING · IDLE · NOT
   RESPONDING all draw clean. Its ground is rgba(58,58,58,.05) over #FAFAF5 = #F0F0EC. */
#pg-admin .adm-hb-stamp,#pg-admin .adm-hb-state{
  display:inline-block;font-family:'PixelGamer',monospace;font-size:.68rem;letter-spacing:.1em;
  padding:4px 10px;border-radius:3px;background:rgba(58,58,58,.05);
  color:var(--hb-ink,#5A5855);white-space:nowrap;
  border:1px solid rgba(58,58,58,.10)
}
/* Brain Buddy's line about it, his handwriting, wearing the state ink so a warm phrase can
   never read live while the age beside it says otherwise */
#pg-admin .adm-hb-lead{margin:.15rem 0 .15rem;font-family:'Chalkduster',cursive;font-size:.82rem;line-height:1.5;color:var(--hb-ink,#5A5855)}
/* the one sentence that lands. #3A3A3A on #FAFAF5 = 10.86:1 */
#pg-admin .adm-hb-what{margin:.2rem 0 .1rem;font-size:.95rem;font-weight:600;line-height:1.5;color:#3A3A3A;text-wrap:pretty}
/* ⭐ THE DEAD-MAN'S CHECK, IN WORDS — "last beat 6 min ago", "idle and alive", "last heard from
   at 15:52". This is the whole point of the mechanism and it is never dimmed: #5A5855 = 6.77:1,
   never the #7A7775 used elsewhere in this file, which is 4.25:1 and under the floor. A liveness
   stamp he has to squint at is not a liveness stamp. */
#pg-admin .adm-hb-age,#pg-admin .adm-hb-check{font-family:'Chalkduster',cursive;font-size:.8rem;line-height:1.55;color:#5A5855}
#pg-admin .adm-hb-note,#pg-admin .adm-hb-sub{margin:.25rem 0 0;font-size:.78rem;font-weight:300;line-height:1.5;color:#5A5855}   /* 6.77:1 */
/* the honest small print under a control — what it can and cannot do */
#pg-admin .adm-hb-small{margin:.3rem 0 0;font-family:'Chalkduster',cursive;font-size:.75rem;line-height:1.5;color:#5A5855}      /* 6.77:1 */

/* ⏳ HIS WISH IS WRITTEN AND THE RUNNER HAS NOT ANSWERED YET. The sheet is written instantly;
   the runner only reads it at the top of its next cycle, which can be a quarter of an hour away.
   ⛔ SO THE LAMP MUST NOT MOVE ON A TAP. The lamp is the RUNNER'S state; pending rides on the
   SWITCH and on this note. A light that turns green because he tapped, rather than because the
   runner answered, is exactly the fake control this whole panel exists to replace.
   #8A2020 on #FAFAF5 = 8.69:1 */
#pg-admin .adm-hb-pending{display:block;margin:.35rem 0 0;font-family:'Chalkduster',cursive;font-size:.78rem;line-height:1.5;color:#8A2020}
#pg-admin .adm-hb.pending .adm-hb-knob,#pg-admin .adm-hb-sw.pending .adm-hb-knob,#pg-admin .adm-hb-knob.pending{outline:2px dashed rgba(138,32,32,.55);outline-offset:2px}

/* ── ⛔ OUT OF ORDER · a part that cannot actually be wired must LOOK unavailable and SAY why ──
   Not greyed-out-and-still-clickable, and not merely recoloured. The affordances themselves are
   removed: the knob loses its lift and its groove shadow, the track is hatched over, the cursor
   refuses. ⚠️ NO OPACITY ON TEXT — the reason has to stay readable, and opacity is what put
   #3A3A3A at 2.33:1 in the .adm-cat note above. */
#pg-admin .adm-hb-sw[disabled],#pg-admin .adm-hb-sw[aria-disabled="true"],#pg-admin .adm-hb-sw.unavailable,
#pg-admin .adm-hb-switch[disabled],#pg-admin .adm-hb-switch[aria-disabled="true"],#pg-admin .adm-hb-switch.unavailable{
  cursor:not-allowed;
  background:repeating-linear-gradient(135deg,#E4E1D8 0 6px,#D9D5CB 6px 12px);
  border-style:dashed;border-color:rgba(58,58,58,.30);
  box-shadow:none
}
#pg-admin .adm-hb-sw[disabled] .adm-hb-knob,#pg-admin .adm-hb-sw[aria-disabled="true"] .adm-hb-knob,#pg-admin .adm-hb-sw.unavailable .adm-hb-knob,
#pg-admin .adm-hb-switch[disabled] .adm-hb-knob,#pg-admin .adm-hb-switch[aria-disabled="true"] .adm-hb-knob,#pg-admin .adm-hb-switch.unavailable .adm-hb-knob{
  background:#E4E1D8;box-shadow:none;border-style:dashed;border-color:rgba(58,58,58,.30)
}
#pg-admin .adm-hb-opt[disabled],#pg-admin .adm-hb-opt[aria-disabled="true"],#pg-admin .adm-hb-opt.unavailable{
  cursor:not-allowed;background:repeating-linear-gradient(135deg,#EFECE3 0 6px,#E6E2D9 6px 12px);
  border-style:dashed;box-shadow:none;transform:none;color:#5A5855            /* 6.77:1 — still readable */
}
/* the reason, which must always be present when anything above is. #8A2020 on #FAFAF5 = 8.69:1 */
#pg-admin .adm-hb-why{margin:.35rem 0 0;font-family:'Chalkduster',cursive;font-size:.8rem;line-height:1.5;color:#8A2020}

/* ── THE THREE STATES (and the fourth). ────────────────────────────────────────────────────
   Every rule sets custom properties only, on whatever element carries the state — the panel, a
   wrapper, the lamp. Nothing here reaches DOWN into a child, so no markup shape can break it.
   ⚠️ THE ALIAS SETS ARE A SEPARATE RULE ON PURPOSE. The canonical selectors are written longhand
   first; the :is() aliases follow. A browser that does not understand :is() drops only the second
   rule, and the canonical state still lands — instead of the whole block failing to UNKNOWN. */

/* 🟢 BEATING — a filled, lit, round lens with a halo, and the one place motion is the subject.
   Ink #3A6A28 on #FAFAF5 = 6.13:1 (and 5.62:1 on the stamp's #F0F0EC ground). */
#pg-admin [class*="adm-hb"].beating,#pg-admin [class*="adm-hb"].beat,#pg-admin [data-hb="beating"],#pg-admin [data-hb="beat"]{
  --hb-ink:#3A6A28;
  --hb-lamp-fill:radial-gradient(circle at 34% 30%,#A8DC72 0%,#88C339 24%,#559C40 58%,#3C5E25 100%);
  --hb-lamp-rim:2px solid rgba(60,94,37,.55);
  --hb-lamp-radius:50%;
  --hb-lamp-glow:inset 0 -3px 6px rgba(0,0,0,.20),inset 0 3px 5px rgba(255,255,255,.35),0 0 0 5px rgba(85,156,64,.13),0 0 14px rgba(85,156,64,.30);
  --hb-lamp-beat:adm-hb-breath 2.4s ease-in-out infinite;
  --hb-knob-top:5px
}
#pg-admin [class*="adm-hb"]:is(.on,.live,.running,.alive),#pg-admin [data-hb]:is([data-hb="on"],[data-hb="live"],[data-hb="running"],[data-hb="alive"]){
  --hb-ink:#3A6A28;
  --hb-lamp-fill:radial-gradient(circle at 34% 30%,#A8DC72 0%,#88C339 24%,#559C40 58%,#3C5E25 100%);
  --hb-lamp-rim:2px solid rgba(60,94,37,.55);
  --hb-lamp-radius:50%;
  --hb-lamp-glow:inset 0 -3px 6px rgba(0,0,0,.20),inset 0 3px 5px rgba(255,255,255,.35),0 0 0 5px rgba(85,156,64,.13),0 0 14px rgba(85,156,64,.30);
  --hb-lamp-beat:adm-hb-breath 2.4s ease-in-out infinite;
  --hb-knob-top:5px
}

/* 🌙 IDLE — HE turned it off, so nothing on this plate may look like a fault. The lamp is a
   HOLE: a thick solid ring round unlit paper, sunk with an inner shadow. Round, like beating —
   the difference is filled versus hollow — and the knob is DOWN, which is the signal that says
   a hand did this. No red, no dashes, no alarm. Ink #5A5855 on #FAFAF5 = 6.77:1. */
#pg-admin [class*="adm-hb"].idle,#pg-admin [data-hb="idle"]{
  --hb-ink:#5A5855;
  --hb-lamp-fill:radial-gradient(circle at 50% 46%,#DCD9D1 0%,#EDEAE2 74%,#F4F1E9 100%);
  --hb-lamp-rim:3px solid rgba(58,58,58,.30);
  --hb-lamp-radius:50%;
  --hb-lamp-glow:inset 0 4px 8px rgba(0,0,0,.20),inset 0 -2px 4px rgba(255,255,255,.55);
  --hb-lamp-beat:none;
  --hb-knob-top:calc(100% - 47px)
}
#pg-admin [class*="adm-hb"]:is(.off,.paused,.sleeping),#pg-admin [data-hb]:is([data-hb="off"],[data-hb="paused"],[data-hb="sleeping"]){
  --hb-ink:#5A5855;
  --hb-lamp-fill:radial-gradient(circle at 50% 46%,#DCD9D1 0%,#EDEAE2 74%,#F4F1E9 100%);
  --hb-lamp-rim:3px solid rgba(58,58,58,.30);
  --hb-lamp-radius:50%;
  --hb-lamp-glow:inset 0 4px 8px rgba(0,0,0,.20),inset 0 -2px 4px rgba(255,255,255,.55);
  --hb-lamp-beat:none;
  --hb-knob-top:calc(100% - 47px)
}

/* ❔ UNKNOWN — this stylesheet was told nothing, or was told something it does not recognise.
   It reads WRONG rather than ordinary: red dashed all the way round, the way .adm-cat.unknown
   (above) and .adm-focus.unknown already do it. var(--red) #B53535 on #FAFAF5 = 5.69:1. */
#pg-admin [class*="adm-hb"].unknown,#pg-admin [data-hb="unknown"]{
  --hb-ink:#B53535;
  --hb-lamp-rim:2px dashed rgba(181,53,53,.55);
  --hb-lamp-beat:none;
  --hb-edge:rgba(181,53,53,.30);--hb-edge-style:dashed;--hb-edge-w:1.5px
}

/* 🔴 NOT RESPONDING — LAST, so that if a stale class ever rides along with a live one, STOPPED
   wins the cascade. This is the state that protects him and it may never lose a tie.
   ⛔ AND IT MUST READ AS STOPPED, NOT AS BUSY: --hb-lamp-beat is forced back to none here, so
   no combination of classes can leave a red light pulsing as though something were happening.
   ⛔ THE KNOB STAYS UP. Nobody switched anything — that is the entire distinction from IDLE, and
   a knob that slid down would tell him he did this. Beating and stopped share the knob position
   and differ by the lamp; idle and stopped share the dark lamp and differ by the knob. No two of
   the three agree on both.
   THE SHAPE: --hb-lamp-radius drops from 50% to 6px. In a photograph, in sunlight, or in
   greyscale, the light is SQUARE — a blown fuse, not a lamp — with a broken dashed rim.
   Ink #8A2020 on the washed plate #F6EEE9 = 7.94:1 (and 8.69:1 on plain #FAFAF5). */
#pg-admin [class*="adm-hb"].down,#pg-admin [class*="adm-hb"].dead,#pg-admin [class*="adm-hb"].stopped,
#pg-admin [data-hb="down"],#pg-admin [data-hb="dead"],#pg-admin [data-hb="stopped"],#pg-admin [data-hb="not-responding"]{
  --hb-ink:#8A2020;
  --hb-lamp-fill:linear-gradient(180deg,#F0E6E2 0%,#E4D6D2 100%);
  --hb-lamp-rim:3px dashed #B53535;
  --hb-lamp-radius:6px;
  --hb-lamp-glow:inset 0 0 0 2px rgba(181,53,53,.10),inset 0 3px 7px rgba(0,0,0,.18);
  --hb-lamp-beat:none;
  --hb-knob-top:5px;
  --hb-plate:#F6EEE9;                                  /* rgba(181,53,53,.06) over #FAFAF5 */
  --hb-edge:#B53535;--hb-edge-style:dashed;--hb-edge-w:2px
}
#pg-admin [class*="adm-hb"]:is(.broken,.stalled,.missing,.gone,.silent,.notresponding),#pg-admin [data-hb]:is([data-hb="broken"],[data-hb="stalled"],[data-hb="missing"],[data-hb="gone"],[data-hb="silent"],[data-hb="notresponding"]){
  --hb-ink:#8A2020;
  --hb-lamp-fill:linear-gradient(180deg,#F0E6E2 0%,#E4D6D2 100%);
  --hb-lamp-rim:3px dashed #B53535;
  --hb-lamp-radius:6px;
  --hb-lamp-glow:inset 0 0 0 2px rgba(181,53,53,.10),inset 0 3px 7px rgba(0,0,0,.18);
  --hb-lamp-beat:none;
  --hb-knob-top:5px;
  --hb-plate:#F6EEE9;
  --hb-edge:#B53535;--hb-edge-style:dashed;--hb-edge-w:2px
}

/* ── 🚨 THE ALARM · the loudest thing on the screen when it happens, and absent otherwise ────
   ⛔ THERE IS NO display:none HERE AND THERE MUST NEVER BE ONE. This file's own rule at the
   focus strip: "no line-clamp, no max-height, no display:none and no opacity on a warning."
   Its invisibility comes from admin.js NOT RENDERING IT when nothing is wrong — a warning that
   is in the DOM and hidden by a stylesheet is one dropped class away from being invisible while
   being true, which is the exact failure this whole panel exists to prevent.
   ⚠️ THE RATIO IS TAKEN AT THE GRADIENT'S LIGHTEST STOP, not its darkest — quoting the easy end
   of a gradient is the same dishonesty as quoting a height from a friendly payload.
   #FFFFFF on #C54545 (the top of the band) = 4.87:1 · on #B53535 (the bottom) = 5.96:1. */
#pg-admin .adm-hb-alarm{
  display:block;margin:.6rem 0 .2rem;padding:10px 12px;
  font-family:'Chalkduster',cursive;font-size:.95rem;font-weight:700;line-height:1.5;
  color:#fff;background:linear-gradient(180deg,#C54545,#B53535);
  border-radius:4px;
  box-shadow:0 3px 0 rgba(120,30,30,.35),0 6px 12px -5px rgba(0,0,0,.35);
  text-wrap:balance
}
/* what to do about it, on the plate rather than on the band. #8A2020 on #F6EEE9 = 7.94:1 */
#pg-admin .adm-hb-alarm-sub{margin:.3rem 0 0;font-size:.82rem;line-height:1.55;color:#8A2020}

/* ── the beat · a slow double thump, the rhythm of index.html's own .heart-rb (L49-50) ───────
   ⛔ THE NAME IS adm-hb-breath AND NOT `heartbeat`. index.html L50 already defines @keyframes
   heartbeat for the rainbow ❤️ in the nav; a second definition with that name would silently
   redefine his nav's animation from a stylesheet loaded after it.
   It animates transform and box-shadow only — nothing that reflows — and it is attached to the
   BEATING state alone. */
@keyframes adm-hb-breath{
  0%,100%{transform:scale(1);   box-shadow:inset 0 -3px 6px rgba(0,0,0,.20),inset 0 3px 5px rgba(255,255,255,.35),0 0 0 5px rgba(85,156,64,.13),0 0 14px rgba(85,156,64,.30)}
  12%    {transform:scale(1.07);box-shadow:inset 0 -3px 6px rgba(0,0,0,.20),inset 0 3px 5px rgba(255,255,255,.35),0 0 0 9px rgba(85,156,64,.18),0 0 22px rgba(85,156,64,.45)}
  24%    {transform:scale(1);   box-shadow:inset 0 -3px 6px rgba(0,0,0,.20),inset 0 3px 5px rgba(255,255,255,.35),0 0 0 5px rgba(85,156,64,.13),0 0 14px rgba(85,156,64,.30)}
  36%    {transform:scale(1.04);box-shadow:inset 0 -3px 6px rgba(0,0,0,.20),inset 0 3px 5px rgba(255,255,255,.35),0 0 0 7px rgba(85,156,64,.16),0 0 18px rgba(85,156,64,.38)}
}
/* the guard at L248 already kills this with `animation:none!important` on #pg-admin *, and an
   !important declaration beats a later normal one, so the cascade is on our side. This is here
   anyway: it is the only motion on the page that carries meaning, so it gets its own guard
   rather than relying on a rule 200 lines up staying scoped the way it is today. */
@media (prefers-reduced-motion:reduce){
  #pg-admin .adm-hb-lamp,#pg-admin .adm-hb-light{animation:none!important}
  #pg-admin .adm-hb-knob{transition:none!important}
}

/* ── 📌 THE PIN · one pin, two places ──────────────────────────────────────────────────────
   His words: "a pin that has essentially A LOCATION THAT TRACKS IT ON THE ACTUAL TO-DO LIST
   but then there's like A SHORTCUT TO THE PIN ON THE TOP OF THE PAGE so you can see where the
   last work was done and where it was left off."
   So .adm-pin is the SHORTCUT at the top and .adm-pin-here is the LOCATION on the list. The pin
   belongs to the row; the strip is a jump-to, not a second pin.
   ⛔ NOT THE GARDEN'S border-left. grant-garden/index.html L10580-10590 carries this strip's
   states on a 3px coloured left border, and that pattern was removed from this codebase today.
   The strip here is the same slip of paper as .adm-focus and the plate above: stuck top edge,
   no side bar, state on the ink and on a frame that goes all the way round. */
#pg-admin .adm-pin{
  position:relative;display:flow-root;
  width:calc(100% - 4px);max-width:640px;margin:.1rem auto .7rem;
  padding:0 0 2px;
  background:#FAFAF5;
  border:1px solid rgba(58,58,58,.10);
  border-radius:2px 2px 4px 4px;
  box-shadow:1px 2px 4px rgba(0,0,0,.10),0 10px 14px -9px rgba(0,0,0,.30);
  transform:rotate(.25deg);                            /* tilted the other way from the plate, so the two
                                                          slips read as separately hand-placed, not as a grid.
                                                          ⚠️ containing block: nothing inside may be fixed. */
  color:#5A5855                                        /* 6.77:1 on #FAFAF5 */
}
#pg-admin .adm-pin::before{content:'';position:absolute;top:0;left:0;right:0;height:14px;border-radius:2px 2px 0 0;background:linear-gradient(180deg,rgba(0,0,0,.07),transparent);pointer-events:none}
/* the head — a real 44px control, and it WRAPS: the "what" can be a whole sentence */
#pg-admin .adm-pin-head{
  display:flex;align-items:center;flex-wrap:wrap;gap:4px 8px;
  width:100%;min-height:44px;padding:9px 12px;
  background:none;border:none;text-align:left;cursor:pointer;
  font-family:inherit;font-size:.92rem;color:#5A5855
}
#pg-admin .adm-pin-head:focus-visible{outline:2px solid var(--teal);outline-offset:-2px}
#pg-admin .adm-pin-stk,#pg-admin .adm-pin-emoji{flex:0 0 auto;font-size:1.15em;line-height:1}
/* "Brain Buddy was last working on" — chalk, and #5A5855 not #7A7775: nothing on this strip is
   allowed under 4.5:1, because the whole strip is a claim about where he is. 6.77:1 */
#pg-admin .adm-pin-lead{flex:0 0 auto;font-family:'Chalkduster',cursive;font-size:.76rem;color:#5A5855}
/* the work itself. #3A3A3A on #FAFAF5 = 10.86:1 */
#pg-admin .adm-pin-what{flex:1 1 160px;min-width:0;font-size:.88rem;font-weight:600;line-height:1.5;color:#3A3A3A}
/* ⭐ THE AGE IS THE HONESTY AND IT IS NEVER GREYED OUT. 6.77:1, never #929AA0 (2.73:1) which is
   what the Garden's .pin-age uses at L10599. A pin whose staleness is faint is a pin that lies. */
#pg-admin .adm-pin-age{flex:0 0 auto;font-family:'Chalkduster',cursive;font-size:.76rem;color:#5A5855;white-space:nowrap}
#pg-admin .adm-pin-tap{flex:0 0 auto;font-family:'Chalkduster',cursive;font-size:.72rem;color:#5A5855}   /* 6.77:1 */
#pg-admin .adm-pin.open .adm-pin-tap{display:none}
#pg-admin .adm-pin-arrow{flex:0 0 auto;margin-left:auto;color:#5A5855;font-size:.8em}
#pg-admin .adm-pin.open .adm-pin-arrow,#pg-admin details.adm-pin[open] .adm-pin-arrow{transform:rotate(180deg)}
/* the body. ⛔ NOT HIDDEN BY DEFAULT — this file has never seen the markup, and a stylesheet that
   guesses wrong about a collapse hook makes his last-known position vanish. The collapse is
   OPT-IN: admin.js adds `fold` to the body if it wants CSS to do the hiding, and a <details>
   needs nothing at all because the browser already hides a closed one. */
#pg-admin .adm-pin-body{padding:0 12px 11px 34px}
#pg-admin .adm-pin:not(.open)>.adm-pin-body.fold{display:none}
#pg-admin .adm-pin-body p{margin:0 0 6px;font-size:.82rem;line-height:1.6;color:#5A5855}   /* 6.77:1 */
#pg-admin .adm-pin-body b,#pg-admin .adm-pin-body strong{color:#3A3A3A}                    /* 10.86:1 */
#pg-admin .adm-pin-next,#pg-admin .adm-pin-why,#pg-admin .adm-pin-where{margin:0 0 6px;font-size:.82rem;line-height:1.6;color:#5A5855}
/* ⚠️ a `where` is a board and a card and an anchor — it wraps rather than pushing the column sideways */
#pg-admin .adm-pin-where{overflow-wrap:anywhere}
/* TAKE ME TO THE PIN. :not(.btn-px) so that if admin.js hands it the site's pixel button, that
   keeps its own white-on-teal and none of my ink lands on it. #1F5A5F on #FAFAF5 = 7.47:1 */
#pg-admin .adm-pin-go:not(.btn-px){
  display:inline-flex;align-items:center;gap:6px;min-height:44px;
  padding:6px 14px;margin:.2rem 0;
  font-family:'Chalkduster',cursive;font-size:.82rem;color:#1F5A5F;
  background:linear-gradient(180deg,#FFFDF7,#F2EFE6);
  border:1.5px solid rgba(48,120,120,.38);border-radius:5px;
  box-shadow:0 2px 0 rgba(48,120,120,.22),0 3px 6px -3px rgba(0,0,0,.22);
  cursor:pointer;transition:transform .1s,box-shadow .1s
}
#pg-admin .adm-pin-go:not(.btn-px):active{transform:translateY(2px);box-shadow:0 0 0 rgba(48,120,120,.22)}
#pg-admin .adm-pin-go:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
/* a stale pin says so, in red, and is never dimmed or folded away. #8A2020 on #FAFAF5 = 8.69:1 */
#pg-admin .adm-pin-warn{margin:.3rem 0 .2rem;font-family:'Chalkduster',cursive;font-size:.8rem;line-height:1.5;color:#8A2020;font-weight:600}
#pg-admin .adm-pin-small{margin:.3rem 0 0;font-family:'Chalkduster',cursive;font-size:.74rem;line-height:1.5;color:#5A5855}   /* 6.77:1 */
/* a stale strip goes dashed all the way round — a margin flag, not a bar on one side */
#pg-admin .adm-pin.stale,#pg-admin .adm-pin[data-pin="stale"]{border:1.5px dashed rgba(181,53,53,.35);background:#F7F2ED}   /* #8A2020 on it = 8.18:1 */
/* a finished pin is settled, not urgent: it steps back by WEIGHT, never by dropping under 4.5:1 */
#pg-admin .adm-pin.done .adm-pin-what,#pg-admin .adm-pin[data-pin="done"] .adm-pin-what{font-weight:400;color:#5A5855}       /* 6.77:1 */
/* the strip has nothing to say. Honest, and it still occupies its own line rather than collapsing
   to nothing, so its absence is never mistaken for a pin that failed to load. */
#pg-admin .adm-pin .adm-unknown{text-align:left;padding:8px 12px;font-size:.85rem}

/* ── 📌 THE LOCATION · the row on the to-do list that the pin is stuck in ──────────────────
   ⭐ OUTLINE, NOT BORDER OR PADDING. An outline takes NO space in the layout, so this cannot
   shift, reflow or overflow a row whose markup this file has never seen — the single most
   dangerous thing a stylesheet can do to another builder's list. It also means the rule is safe
   on a <details>, a <li>, a <p> or a bare <div> alike.
   ⛔ AND IT IS NOT GOLD. Inside HEART gold means "waiting on you" and nothing else; the pin is
   where Brain Buddy was working, which asks him for nothing. */
#pg-admin .adm-pin-here{
  outline:2px dashed rgba(48,120,120,.55);outline-offset:3px;border-radius:4px;
  background:rgba(48,120,120,.05);
  scroll-margin-top:110px                              /* the jump lands under the sticky nav, not behind it */
}
#pg-admin .adm-pin-here.done{outline-color:rgba(58,58,58,.35)}
/* the pin drawn ON the row. Inline by default, because inline is the one placement that cannot
   break an unknown layout; `.corner` opts into the pushed-in look and needs the row to be
   position:relative, which is why it is not the default. */
#pg-admin .adm-pin-mark{display:inline-block;font-size:1.1em;line-height:1;margin-right:5px;transform:rotate(-12deg)}
#pg-admin .adm-pin-mark.corner{position:absolute;top:-8px;left:-6px;margin:0;font-size:1.2em;pointer-events:none}
#pg-admin .adm-pin-here.rel,#pg-admin .adm-pin-here.corner{position:relative}

/* ── the phone. #pg-admin's L31-32 rules already stop anything overflowing 390px; these two are
   about what is worth the room rather than what fits. ── */
@media (max-width:400px){
  #pg-admin .adm-pin-tap{display:none}                 /* the arrow already says it opens */
  #pg-admin .adm-hb-head{gap:8px 10px}
}

/* ▸ MORE — a torn paper tab, not a browser button. His note, 6 Sept: "the more button underneath
   the heartbeat is like out of brand". It was a default-looking pill on a page made of paper.
   Now it is the corner of the card lifting: cream, one hairline of ink, the top edge open so it
   reads as attached to the plate above it rather than floating beside it, and a fraction off
   square like everything else on this desk. 44px tall, because it is his tap.
   #5A5855 on #FDFAF3 = 7.4:1. */
#pg-admin .adm-hb-toggle{
  display:inline-flex;align-items:center;gap:5px;
  min-height:44px;margin:-2px 0 0 14px;padding:0 15px;
  font-family:'PixelGamer',monospace;font-size:.64rem;letter-spacing:.06em;color:#5A5855;
  background:linear-gradient(180deg,#FDFAF3 0%,#F4F1E8 100%);
  border:1.5px solid rgba(42,37,32,.16);border-top:none;
  border-radius:0 0 7px 7px;
  box-shadow:0 2px 3px rgba(42,37,32,.10);
  transform:rotate(-.4deg);cursor:pointer;
  transition:transform .14s ease,box-shadow .14s ease
}
#pg-admin .adm-hb-toggle:hover{transform:rotate(-.7deg) translateY(1px);box-shadow:0 3px 6px rgba(42,37,32,.14)}
#pg-admin .adm-hb-toggle:active{transform:translateY(2px) rotate(0deg);box-shadow:0 1px 2px rgba(42,37,32,.12)}
#pg-admin .adm-hb-toggle:focus-visible{outline:3px solid var(--teal,#307878);outline-offset:2px}
@media (prefers-reduced-motion:reduce){#pg-admin .adm-hb-toggle{transition:none}}

/* ⛔ THE DISC IS GREY IN EVERY STATE, AND THIS RULE HAS TO COME LAST TO SAY SO. His words, 6 Sept:
   "the circle that it's resting on should be like a gray tone or something with like the rainbow
   heart". The per-state blocks above set --hb-lamp-fill on the STATE element (.adm-hb.beating and
   friends), and an earlier attempt to set it on the lamp lost to them — measured: the disc still
   came back rgb(168,220,114), the green. Same custom property, higher specificity, later in the
   file, so it wins without an !important.
   ⭐ AND LOSING THE COLOUR HERE COSTS NOTHING, because the state never lived in the disc alone: it
   is in the heart's MOTION (gliding and throbbing · drifting · dead still), in the badge word, in
   the switch's knob position and in the rim. Four carriers, three of which survive a photograph. */
#pg-admin .adm-hb.beating .adm-hb-lamp,#pg-admin .adm-hb.idle .adm-hb-lamp,
#pg-admin .adm-hb.dead .adm-hb-lamp,#pg-admin .adm-hb.unknown .adm-hb-lamp,
#pg-admin [data-hb] .adm-hb-lamp,#pg-admin [data-state] .adm-hb-lamp,
#pg-admin .adm-hb.beating .adm-hb-light,#pg-admin .adm-hb.idle .adm-hb-light,
#pg-admin .adm-hb.dead .adm-hb-light,#pg-admin [data-hb] .adm-hb-light{
  --hb-lamp-fill:radial-gradient(circle at 50% 40%,#F4F2EC 0%,#E4E1D9 62%,#D4D0C6 100%)
}

/* ── 📊 THE BAR GRAPH · his 6 Sept ask, under the plan ────────────────────────────────────
   "I would love to see a bar graph of its growth and what it's focusing on… I just want to see a
   full understanding of the task it's working on and what it's trying to accomplish."
   ⭐ IT IS DRAWN AS PAPER, NOT AS A CHART. The track is the composition book's own rule — a hairline
   trough on cream — and the segments are strips of tape laid into it, tilted a whisker like every
   other object on this desk. No gridlines, no axis, no chart furniture: he asked to understand at a
   glance, and furniture is what you add when the shape alone will not carry it.
   🎨 THE THREE INKS ARE THE SITE'S OWN, not new ones: green #559C40 for what he has approved, gold
   #C49538 for what is built and waiting on his yes, red #B53535 for blocked. Contrast on the labels
   is what matters and the segments carry a dark hairline so they read on any ground.
   ⚠️ WIDTHS ARE PERCENTAGES OF EACH CATEGORY, so a category of three and one of forty are both
   readable — an absolute scale would make everything but the biggest bar invisible. */
#pg-admin .adm-bars{margin:.2rem 0 1rem;padding:11px 12px 9px;background:#FDFAF3;
  border:1.5px solid rgba(42,37,32,.14);border-radius:4px;box-shadow:0 1.5px 0 rgba(42,37,32,.08)}
#pg-admin .adm-bars-head{margin:0 0 9px;font-size:.82rem;line-height:1.5;color:#3A3A3A}  /* 10.9:1 on #FDFAF3 */
#pg-admin .adm-bar-all{height:16px;margin-bottom:11px}
#pg-admin .adm-bar-row{display:flex;align-items:center;gap:8px;margin:0 0 6px}
#pg-admin .adm-bar-name{flex:0 0 38%;min-width:0;display:flex;align-items:center;gap:4px;
  font-size:.74rem;line-height:1.35;color:#5A5855;overflow-wrap:anywhere}                 /* 7.4:1 */
#pg-admin .adm-bar-name>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#pg-admin .adm-bar{position:relative;flex:1 1 auto;display:flex;height:13px;border-radius:2px;overflow:hidden;
  background:repeating-linear-gradient(90deg,#EFEDE6 0 5px,#E9E7E0 5px 6px);
  border:1px solid rgba(42,37,32,.13);box-shadow:inset 0 1px 2px rgba(42,37,32,.10);
  transform:rotate(-.18deg)}
#pg-admin .adm-bar-seg{display:block;height:100%;border-right:1px solid rgba(42,37,32,.18)}
#pg-admin .adm-seg-x{background:linear-gradient(180deg,#6FBF56,#559C40)}
#pg-admin .adm-seg-b{background:linear-gradient(180deg,#D9B057,#C49538)}
#pg-admin .adm-seg-k{background:linear-gradient(180deg,#CC4A4A,#B53535)}
#pg-admin .adm-bar-n{flex:0 0 auto;font-family:'Gaposiss','PixelGamer',monospace;font-size:.7rem;color:#3A3A3A}
#pg-admin .adm-bar-of{color:#5A5855}
#pg-admin .adm-bars-key{display:flex;align-items:center;gap:5px;flex-wrap:wrap;margin:9px 0 0;
  font-size:.72rem;line-height:1.5;color:#5A5855}
#pg-admin .adm-bars-key span[class^="adm-key-"]{display:inline-block;width:11px;height:11px;border-radius:2px;
  border:1px solid rgba(42,37,32,.18);margin-left:6px}
#pg-admin .adm-key-x{background:#559C40}
#pg-admin .adm-key-b{background:#C49538}
#pg-admin .adm-key-k{background:#B53535}
@media (max-width:430px){#pg-admin .adm-bar-name{flex-basis:44%;font-size:.7rem}}

/* ── 🧭 THE SHAPE OF THE PAGE · the crease, the two piles, the tape on a post-it ───────────
   HIS COMPLAINT, 6 Sept 2026, and this block is one answer to it: "I do not understand what it
   means by waiting on me — what is it that you are waiting on me for? I am looking at it and most
   of the stuff is that you are waiting on me. What is that?" And the standing note: "we need to
   spend a little bit more time getting the entire dashboard solid and organized and clean and
   simple to understand."

   ⛔ THAT IS NOT A COLOUR BRIEF AND IT IS NOT MOSTLY A CSS BUG. Measured before this was written:
   formula-board.json holds 122 tasks, 25 render as "waiting on your yes", and only 6 of those
   carry a card id — 19 were never put to him at all. A stylesheet cannot make that sentence true.
   What a stylesheet CAN do is stop the page from making the two piles look identical, so that when
   the other builder splits them, the split is visible from a glance and from across the room.

   ⭐ HIS OWN METHOD IS THE DESIGN, in his words the same day: build it, put it in its library spot,
   announce it on a Convo card with a button that goes straight to it, feedback box and accuracy
   meter on that card. So the second pile is not a queue and it is not a request. It is a RECEIPT:
   here is what was done, filed where you can find it, nothing needed from you. It is drawn as till
   paper — flat, dotted, printed — because a receipt is the one paper object on a desk that nobody
   has ever had to act on.

   THE THREE LEVERS ARE SPACE, WEIGHT AND PAPER. No new colour and no new box:
     · SPACE — a crease between panels, and the panel that wants something gets the widest berth.
     · WEIGHT — the pile that wants something is announced at .95rem/600 #3A3A3A; the one that
       reports is .8rem/400 #5A5855. Same ink family, two different voices.
     · PAPER — a post-it lifts off the desk (shadow, tilt, tape). A receipt lies flat on it
       (hairline highlight, dotted perforation, no ambient shadow, .12deg). Photograph the two in
       greyscale and they are still not the same object.

   📏 ALL OF IT WAS RENDERED THROUGH THE REAL PATH before this comment was written: the real
   /index.html#admin, served locally, puppeteer at a true 390x844 deviceScaleFactor 2, the site's
   own fonts, admin.js running. The crease, the two piles, the receipt roll and every family's tape
   were measured and photographed there, and three rules were WRONG on the first pass and are fixed
   below with the measurement that caught each. ⚠️ ONE HONEST GAP REMAINS: the pile and receipt
   MARKUP was injected by the harness in the shape this file expects, because the builder who owns
   admin.js is writing the real markup in this same beat. So the RULES are proven; the CONTRACT is
   not. When admin.js lands, render it again and re-measure. ⚠️ RE-MEASURE, DO NOT RE-ASSERT.

   ⛔ AND THE DISC RULE ABOVE THIS BLOCK MUST STAY THE LAST WORD ON --hb-lamp-fill. Nothing below
   declares that property and no selector below matches .adm-hb-lamp, .adm-hb-light or any other
   adm-hb-* part — grepped, not assumed. The approved heartbeat plate is untouched by this block.
   MOTION: none. Not one animation and not one transition is added here, so the L248 reduced-motion
   guard has nothing new to switch off. */

/* ── §A · THE CREASE · one boundary between panels, drawn once ─────────────────────────────
   The panels ran together because `.section{margin-bottom:2rem}` (index.html L74) was the ONLY
   thing between them, and 32px of nothing does not read as a boundary when the thing above it is
   also a list of rows on cream. The crease is a fold in the page: one hairline of ink with one
   line of white underneath it, faded out at both ends so it is a crease and not a border. It is
   the notebook's own language — the same trick the 📊 bar graph's trough uses two blocks up.
   📏 RENDERED at a true 390x844 through /index.html#admin with the site's own fonts: the gap
   between the last row of one panel and the next tape goes 32px → 59px, with the fold sitting at
   the 32px mark. A section boundary is now findable at arm's length, which is the whole ask.
   🎨 THE FOLD IS rgba(58,58,58,.17), NOT .13. The page's own ground is ruled in blue every 28px
   (body, index.html L29) and at .13 the fold photographed as one more ruled line. .17 plus the
   white line under it reads as a crease and nothing else. Both were rendered and compared.
   ⛔ THE EXCLUSIONS LIVE INSIDE :where() AND THAT IS NOT TIDINESS — IT IS THE BUG THIS BLOCK HAD.
   Written the obvious way, `:not(#adm-focus):not(#adm-brief)`, the two ids inside :not() COUNT,
   and the base rule outweighed `#pg-admin>#adm-needs` below it. Measured: the panel that wants
   something rendered at 27.2px of top padding instead of 36.8px, and the .adm-wants alias was dead
   in the file — a rule that looked like a feature and did nothing. :where() contributes zero, so
   the id rule and the aliases both land. Re-measured after the fix, in the same page: #adm-needs
   36.8/43.2 · a panel marked .adm-wants 36.8/43.2 · one marked .adm-fyi 27.2/32 · #adm-brief and
   #adm-focus 0, with no crease drawn on either.
   ⚠️ IF A BROWSER DOES NOT KNOW :where() the whole selector is dropped and there is simply no
   crease — the page falls back to today's 32px rhythm. It cannot fall back to a broken layout,
   which is why the risk is taken here and nowhere that carries meaning.
   ⛔ TWO PANELS ARE EXEMPT AND BOTH EXEMPTIONS ARE MEASURED, NOT PREFERRED.
     · #adm-focus is a slip of paper, not a tape-headed panel (BARE_HOSTS-adjacent: ensureHosts
       gives it .section for the margin, and the L344 note already takes that margin back to 0).
     · #adm-brief gets NO crease above it, because the focus block above spent a whole beat buying
       back the pixels that push 📬 THE BRIEF — the one panel that wants something — down his
       phone (y1097 → y954, measured in that block's own table). Adding 27px here would spend
       them again. The boundary above the brief is the focus strip's own free bottom edge. */
#pg-admin>.section+.section:where(:not([id="adm-focus"]):not([id="adm-brief"])){position:relative;padding-top:1.7rem}
#pg-admin>.section+.section:where(:not([id="adm-focus"]):not([id="adm-brief"]))::before{
  content:'';position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:min(100%,560px);height:1px;
  background:linear-gradient(90deg,rgba(58,58,58,0),rgba(58,58,58,.17) 14%,rgba(58,58,58,.17) 86%,rgba(58,58,58,0));
  box-shadow:0 1px 0 rgba(255,255,255,.6);
  pointer-events:none}
/* ⭐ THE PANEL THAT WANTS SOMETHING GETS THE WIDEST BERTH, and that is the whole "it should look
   like it wants something" at the page level: it is the one thing on the tab with room around it.
   .adm-wants is an alias so the builder can move the treatment if the pile moves out of #adm-needs;
   .adm-fyi is its opposite and takes the ordinary rhythm, so a panel can be marked either way
   without this file having to know the id. */
#pg-admin>#adm-needs,#pg-admin>.adm-wants.section,#pg-admin>.adm-wants{padding-top:2.3rem;margin-bottom:2.7rem}
#pg-admin>#adm-needs::before,#pg-admin>.adm-wants.section::before,#pg-admin>.adm-wants::before{width:100%}
#pg-admin>.adm-fyi.section,#pg-admin>.adm-fyi{padding-top:1.7rem;margin-bottom:2rem}

/* ── §B · WHOSE PILE IT IS · two heads that do not sound alike ─────────────────────────────
   Two piles can share one panel, so each needs a name in his language, and the two names must not
   be set the same way — a matched pair of headings is exactly what made 25 things look like 25
   requests. YOURS announces; MINE reports. Both hooks accepted (class and data attribute) for the
   same reason the state rules above accept both: a rename in admin.js cannot silently flatten them.
   📏 RENDERED with injected markup at a true 390: 15.2px/600/#3A3A3A against 12.8px/400/#5A5855 —
   the two heads do not read as a matched pair even in a greyscale screenshot. ⚠️ The markup was the
   harness's, not admin.js's. Ground for the contrast below: the page (body's gradient, darkest
   broad band #EEF0F6; a blue rule line is darker still and both inks clear the floor on it too —
   #3A3A3A 8.39:1, #5A5855 5.23:1). */
#pg-admin .adm-pile-head{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 8px;margin:.2rem 0 .45rem;font-family:'Chalkduster',cursive;line-height:1.5}
#pg-admin .adm-pile-head .adm-n{margin-left:auto;padding-left:8px;font-size:.95em;color:#3A3A3A}
/* YOURS — it is asking, so it is said out loud. #3A3A3A on #EEF0F6 = 9.98:1 */
#pg-admin .adm-pile-head.yours,#pg-admin .adm-pile-head[data-pile="yours"]{font-size:.95rem;font-weight:600;color:#3A3A3A}
/* MINE — it is reporting, so it steps back by SIZE and WEIGHT and never by dropping under the
   floor. #5A5855 on #EEF0F6 = 6.22:1. ⛔ #7A7775 was the obvious quieter grey and it is 4.35:1 on
   this ground and 3.90:1 on the receipt paper below — under the floor, so it is not used here. */
#pg-admin .adm-pile-head.mine,#pg-admin .adm-pile-head[data-pile="mine"]{font-size:.8rem;font-weight:400;color:#5A5855}
/* the honest one-liner under a head — "these are finished and filed; nothing is needed from you".
   Body face, not chalk: it is a plain sentence, not a label. 6.22:1 */
#pg-admin .adm-pile-sub{margin:-.3rem 0 .55rem;font-size:.78rem;line-height:1.55;color:#5A5855}
#pg-admin .adm-pile-sub b{font-weight:600;color:#3A3A3A}

/* ── §C · THE RECEIPT · what was built, filed, and needs nothing from him ───────────────────
   A roll of till paper: cream (⛔ never white, §11), a dotted perforation top and bottom, a printed
   list inside, one line of white highlight and NO ambient shadow — the receipt is printed ON the
   desk, where the post-it sits on top of it. The tilt is .12deg against the post-it's 2deg, so even
   the hand that placed them reads as a different gesture.
   ⚠️ A transform makes this a containing block: nothing inside a receipt roll may be position:fixed.
   📏 RENDERED with injected markup at a true 390: the roll comes out 358px wide — the same column
   the post-its stand in, so the two piles are the same size and only the PAPER is different. A
   tappable row measures 56px, past the 44px floor.
   ⛔ AND `align-items:center` ON A TAPPABLE ROW WAS WRONG AND THE PHOTOGRAPH CAUGHT IT. A row whose
   text runs to two lines centred its ✓ against the whole block, so the tick sat 8px below the title
   it belongs to and the slip stopped looking printed. Baseline is kept in every state and the extra
   height a thumb needs is spent under the line instead. Re-measured: the tick's top is now 1px off
   the title's. ⚠️ The markup was the harness's, not admin.js's.
   Ground for every ink below is the paper's own darkest stop, #F3F0E6. */
#pg-admin .adm-receipts{
  position:relative;max-width:560px;margin:.1rem auto .5rem;padding:9px 13px 4px;
  background:linear-gradient(180deg,#F8F5EE,#F3F0E6);
  border:1px solid rgba(42,37,32,.09);
  border-top:2px dotted rgba(42,37,32,.26);
  border-bottom:2px dotted rgba(42,37,32,.26);
  box-shadow:0 1px 0 rgba(255,255,255,.55);
  transform:rotate(-.12deg)}
/* if a roll is dropped inside the post-it grid it takes the whole width rather than becoming a
   150px column — cheap insurance, because this file has never seen the markup */
#pg-admin .adm-pile>.adm-receipts{grid-column:1/-1;justify-self:stretch;width:100%}
/* a printed line. #3A3A3A on #F3F0E6 = 9.98:1 */
#pg-admin .adm-receipt{display:flex;align-items:baseline;gap:9px;padding:.45rem 0;border-bottom:1px dotted rgba(42,37,32,.15);font-size:.86rem;line-height:1.55;color:#3A3A3A}
#pg-admin .adm-receipt:last-child{border-bottom:none}
/* done. #3A6A28 on #F3F0E6 = 5.63:1 — and it is a ✓ beside words, never the only carrier */
#pg-admin .adm-receipt-tick{flex:0 0 auto;color:#3A6A28}
#pg-admin .adm-receipt-what{flex:1 1 auto;min-width:0}
/* where it was filed — his step 2, "it is already there and ready to go". 6.22:1 */
#pg-admin .adm-receipt-where{display:block;font-size:.76rem;font-weight:300;line-height:1.5;color:#5A5855}
#pg-admin .adm-receipt-when{flex:0 0 auto;font-family:'Gaposiss','PixelGamer',monospace;font-size:.72rem;font-variant-numeric:tabular-nums;color:#5A5855}
/* the way through to the thing itself — his step 4. Same dashed-underline text control as
   .adm-focus-go (L415), :not(.btn-px) for the same reason: if admin.js hands it the site's pixel
   button, that keeps its own white-on-teal and my ink never lands on it. 6.86:1 */
#pg-admin .adm-receipt-go:not(.btn-px){display:inline-flex;align-items:center;gap:5px;margin-top:.1rem;padding:0 2px;background:none;border:none;border-bottom:1px dashed rgba(48,120,120,.4);cursor:pointer;font-family:'Chalkduster',cursive;font-size:.78rem;line-height:1.5;text-align:left;color:#1F5A5F}
/* 44px only where the thing IS the control — the L418 rule, kept: a <p> that is not tappable does
   not get to spend 44px of his phone. */
#pg-admin button.adm-receipt-go,#pg-admin a.adm-receipt-go,#pg-admin .adm-receipt-go[role="button"],#pg-admin .adm-receipt-go[tabindex]{min-height:44px}
#pg-admin .adm-receipt[role="button"],#pg-admin .adm-receipt[tabindex],#pg-admin a.adm-receipt{min-height:44px;cursor:pointer;text-decoration:none}
#pg-admin .adm-receipt:focus-visible,#pg-admin .adm-receipt-go:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
/* the total line at the bottom of a slip — the count, and the sentence that says nothing is owed */
#pg-admin .adm-receipts-foot{margin:.35rem 0 .4rem;padding-top:.35rem;border-top:1px dotted rgba(42,37,32,.15);font-family:'Chalkduster',cursive;font-size:.76rem;line-height:1.5;color:#5A5855;text-align:center}
#pg-admin .adm-receipts-foot .adm-n{color:#3A3A3A}
/* an empty roll still prints — an honest empty is this file's rule everywhere else (L78) */
#pg-admin .adm-receipts .adm-unknown{text-align:left;padding:.2rem 0;font-size:.82rem}

/* ── §D · THE TAPE · a post-it carrying the colour of the Convo card it points at ───────────
   His step 3 is that a finished thing gets ANNOUNCED on a card. So a note in the waiting pile is a
   pointer to a card, and it should wear that card's colour — but the note's paper is Gold Classic
   and gold means "waiting on you" in HEART, so the colour cannot go into the paper.
   ⭐ IT GOES ON THE TAPE, which is the site's own object and the one place on a desk where a second
   colour is ordinary. It is 56x15px, centred, at the TOP — ⛔ it is not a bar down one side, and
   there is no coloured slab anywhere in this block.
   🎨 THE TONES ARE THE CARD'S OWN, lifted from channel.js's TAPES map (L390-404): the family's
   `top` tone as the light stop and its `edge` tone as the dark stop, which is exactly the site's
   .tape.<family> recipe (index.html L95). Nothing new is mixed. The dark stop is what makes the
   tape READ: measured against the palest ground it can land on (#F8F0CA, the note's light end),
   every family's dark stop is at least 3.19:1, so the object's shape is never invisible — teal
   6.82 · gold 4.13 · red 7.72 · green 5.60 · blue 6.26 · dark 11.70 · grey and metallic 6.18 ·
   brown 8.83 · white 3.19 · no-colour 4.05.
   ⚠️ WHITE IS THE ONE DEVIATION AND IT IS DELIBERATE: TAPES.white is #FFFFFF, and pure white tape
   on cream is both invisible and against §11. It takes the white card's own text grey #8A8580 as
   its light stop instead, which is what card-template.css already uses to make that family legible.
   ⭐ A NOTE WITH NO KNOWN COLOUR STILL LOOKS DELIBERATE: the fallback is MASKING TAPE, #C9C4B4 over
   #7A7468 — a real object, deliberately chosen, that says nothing about a card rather than guessing
   at one. The default lives in the var() fallback and NOT on .adm-note, which is the lesson the
   heartbeat plate learned the hard way (L558): a default declared on the element beats a value
   inherited from an ancestor, and then a colour set on a wrapper lands on nothing.
   📏 RENDERED at a true 390x844, all eleven cases in one pile — every family plus a note with no
   colour at all. Two notes per row still fit (170+14+170=354 in a 358px column), each tape came out
   56x15 at top:-7px with the right two tones in it, and the tape's overhang clears the row above on
   the pile's own 14px grid gap. .adm-pile's top padding goes 6px → 14px so the first row's tape is
   not clipped by the panel edge; measured clearance after that change, 4px.
   ⛔ NOT ON A STACK. The stack (L150) is a count of what is underneath, not one card, so it has no
   one colour to wear and its ::after is switched off rather than left to draw a grey smudge. */
#pg-admin #adm-needs .adm-pile{padding-top:14px}
#pg-admin .adm-note::after{
  content:'';position:absolute;top:-7px;left:50%;margin-left:-28px;width:56px;height:15px;
  background:linear-gradient(160deg,var(--card-colour,var(--card-color,#C9C4B4)) 0%,var(--card-edge,#7A7468) 100%);
  clip-path:polygon(2% 0%,100% 6%,98% 100%,0% 94%);
  filter:drop-shadow(0 1px 2px rgba(58,58,58,.28));
  transform:rotate(-1.4deg);
  pointer-events:none}
#pg-admin .adm-stack .adm-note::after{display:none}
/* THE FAMILIES. Three hooks each — the class the site already uses everywhere, a data attribute,
   and a data attribute on ANY ancestor (custom properties inherit, so a family set on the pile or
   on a wrapper still reaches the tape). Written longhand rather than through :is(), so a browser
   that drops one selector still lands the other two. */
#pg-admin .adm-note.teal,#pg-admin .adm-note[data-family="teal"],#pg-admin [data-card-family="teal"]{--card-colour:#3A8888;--card-edge:#1F5A5F}
#pg-admin .adm-note.gold,#pg-admin .adm-note[data-family="gold"],#pg-admin [data-card-family="gold"]{--card-colour:#D4A548;--card-edge:#8A7028}
#pg-admin .adm-note.red,#pg-admin .adm-note[data-family="red"],#pg-admin [data-card-family="red"]{--card-colour:#C54545;--card-edge:#8A2525}
#pg-admin .adm-note.green,#pg-admin .adm-note[data-family="green"],#pg-admin [data-card-family="green"]{--card-colour:#65AC50;--card-edge:#3A6A28}
#pg-admin .adm-note.blue,#pg-admin .adm-note[data-family="blue"],#pg-admin [data-card-family="blue"]{--card-colour:#5A8AB0;--card-edge:#3A5A7A}
#pg-admin .adm-note.dark,#pg-admin .adm-note[data-family="dark"],#pg-admin [data-card-family="dark"]{--card-colour:#5A5A5A;--card-edge:#2D2F32}
#pg-admin .adm-note.grey,#pg-admin .adm-note[data-family="grey"],#pg-admin [data-card-family="grey"]{--card-colour:#8A8885;--card-edge:#5A5855}
#pg-admin .adm-note.gray,#pg-admin .adm-note[data-family="gray"],#pg-admin [data-card-family="gray"]{--card-colour:#8A8885;--card-edge:#5A5855}
#pg-admin .adm-note.brown,#pg-admin .adm-note[data-family="brown"],#pg-admin [data-card-family="brown"]{--card-colour:#7D6052;--card-edge:#5A3A2A}
#pg-admin .adm-note.metallic,#pg-admin .adm-note[data-family="metallic"],#pg-admin [data-card-family="metallic"]{--card-colour:#A8A49E;--card-edge:#5A5855}
#pg-admin .adm-note.white,#pg-admin .adm-note[data-family="white"],#pg-admin [data-card-family="white"]{--card-colour:#8A8580;--card-edge:#B0ACA5}

/* ── §E · THE STEP FROM A HEADING TO ITS ROWS ──────────────────────────────────────────────
   Inside 📋 THE PLAN a group heading was .88rem and the rows under it are .95rem — the heading was
   SMALLER than the thing it headed, which is why the list read as one undifferentiated run. The fix
   is proximity, not decoration and not indentation: air ABOVE the heading, almost none below it, so
   the heading belongs to the rows that follow rather than floating between two groups.
   ⛔ NO LEFT INDENT ON THE ROWS. It was the other obvious fix and it costs 14px of a 326px column
   on his phone, twice over inside a category drawer, for a step that space already provides free.
   Higher specificity than L200's rule rather than a later-in-file bet, so the order of this block
   can never decide it. #5A5855 on the panel ground = 6.22:1. */
#pg-admin #adm-board .adm-group{margin:1.2rem 0 .15rem .2rem;font-size:.86rem;font-weight:600;color:#5A5855}
#pg-admin #adm-board .adm-group:first-child{margin-top:.2rem}

/* ── 🖼️ THE INSPIRATION WALL · his 6 Sept 08:20 tick 6 ──────────────────────
   Curation, not waiting-on-you, so the ink is grey (SIGNAL law, admin.js L92-94; gold is
   reserved for what needs him). The dial is device-local this beat and the panel prints
   that limit at .adm-ins-limit; a next beat wires it to the sheet. Tap targets are ≥44px
   for the phone rule; the strength radios read as pill buttons rather than form radios
   because the strength is a preference, not a form field.
   Colour tokens are the same greys/teals already vouched for elsewhere in this file. */
#adm-inspiration .adm-ins-limit{font-family:'Chalkduster',cursive;font-size:.78rem;color:var(--ink-lt);text-align:center;margin:.2rem 0 .8rem;line-height:1.55}
#adm-inspiration .adm-ins-empty{font-family:'Chalkduster',cursive;color:var(--ink-md);text-align:center;padding:.6rem 0}
#adm-inspiration details.adm-ins-drawer>summary .adm-grp{color:#5A5855;font-weight:600;font-family:'Avenir Next','Segoe UI',system-ui,sans-serif;font-size:.9rem}
#adm-inspiration details.adm-ins-drawer>summary .adm-qual{font-size:.78rem;font-family:'Chalkduster',cursive}
#adm-inspiration .adm-ins-entry{padding:.7rem 0;border-bottom:1px solid rgba(58,58,58,.05)}
#adm-inspiration .adm-ins-entry:last-child{border-bottom:none}
#adm-inspiration .adm-ts{font-family:'Chalkduster',cursive;font-size:.72rem;color:var(--ink-lt)}
#adm-inspiration .adm-ins-url{margin:.25rem 0 .3rem;word-break:break-all;overflow-wrap:anywhere}
#adm-inspiration .adm-ins-url a{color:var(--teal);font-family:'Gaposiss','PixelGamer',monospace;font-size:.82rem;text-decoration:none;border-bottom:1px dotted var(--teal);min-height:44px;display:inline-block;padding:6px 0;line-height:1.4}
#adm-inspiration .adm-ins-url a:hover,#adm-inspiration .adm-ins-url a:focus{border-bottom-style:solid}
#adm-inspiration .adm-ins-what{margin:.15rem 0 .5rem;color:#5A5855;font-size:.92rem;line-height:1.6;white-space:pre-wrap}
#adm-inspiration .adm-ins-what.adm-ins-empty{color:var(--ink-xlt);font-style:italic}
#adm-inspiration .adm-ins-dial{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:.3rem}
#adm-inspiration .adm-ins-dial-lbl{font-family:'Chalkduster',cursive;font-size:.72rem;color:var(--ink-lt);margin-right:4px;flex-basis:100%}
#adm-inspiration .adm-ins-str{min-height:44px;padding:8px 12px;font-family:'Chalkduster',cursive;font-size:.78rem;color:#5A5855;background:#FAFAF5;border:1.5px solid rgba(58,58,58,.16);border-radius:14px;cursor:pointer;line-height:1.2}
#adm-inspiration .adm-ins-str:hover,#adm-inspiration .adm-ins-str:focus{border-color:var(--teal);color:var(--teal)}
#adm-inspiration .adm-ins-str.on{background:var(--teal);color:#fff;border-color:var(--teal);box-shadow:0 1px 3px rgba(48,120,120,.25)}

/* ── 🎚️ THE SLIDER · his ask, 6 Sept: "making it a slider where I can slide it back and forth and
   then it locks on one side like an actual switch" ──────────────────────────────────────────────
   ⛔ AND THE REASON HE ASKED IS THE PART TO REMEMBER: every tap he made had already WORKED. His
   sheet carries five writes in ninety seconds. He pressed it five times because nothing moved and
   nothing spoke, so a control that had obeyed him looked identical to one that had not. The drag is
   half the fix; the other half is that the knob now travels under his finger and the plate says what
   it did. A control that works silently is indistinguishable from a broken one.
   · WHILE DRAGGING the knob follows the pointer with NO transition — a knob that eases toward the
     finger feels broken, because a real switch has no opinion about where your thumb is.
   · ON RELEASE the transition comes back and it LOCKS to the nearer end. A physical switch never
     rests in the middle, so neither does this.
   · grab / grabbing cursors and touch-action:none, so a vertical drag moves the knob instead of
     scrolling the page out from under him — on a phone that is the whole difference. */
#pg-admin .adm-hb-sw{touch-action:none;cursor:grab}
#pg-admin .adm-hb-sw.dragging{cursor:grabbing}
#pg-admin .adm-hb-sw.dragging .adm-hb-knob{transition:none;box-shadow:0 3px 5px rgba(0,0,0,.28),0 10px 14px -8px rgba(0,0,0,.4),inset 0 1px 0 rgba(255,255,255,.9)}
/* the knob obeys an inline --hb-knob-top while a drag is in flight, and falls back to its resting
   end the moment the drag ends and the property is removed */
#pg-admin .adm-hb-sw .adm-hb-knob{top:var(--hb-knob-top,calc(50% - 21px))}
#pg-admin .adm-hb.beating .adm-hb-knob,#pg-admin [data-hb="beating"] .adm-hb-knob{--hb-knob-rest:5px}
#pg-admin .adm-hb-sw:not(.dragging) .adm-hb-knob{transition:top .18s cubic-bezier(.3,1.4,.5,1)}
/* a hint that it is draggable at all — two grip lines and a shallow groove, the way a real switch
   tells your thumb what to do before you read anything */
#pg-admin .adm-hb-sw::after{content:'';position:absolute;left:50%;top:50%;width:22px;height:0;
  transform:translate(-50%,-50%);border-top:1.5px solid rgba(58,58,58,.16);border-bottom:1.5px solid rgba(58,58,58,.16);
  height:7px;pointer-events:none;opacity:.55}
@media (prefers-reduced-motion:reduce){#pg-admin .adm-hb-sw:not(.dragging) .adm-hb-knob{transition:none}}

/* ⛔ THE KNOB MUST REFUSE THE GESTURE TOO, not just the plate. On a phone his finger lands on the
   KNOB, and touch-action on the parent does not cover a child that has its own. He reported it
   exactly: "instead of like the screen dragging, can I click on the button and drag it up". */
#pg-admin .adm-hb-knob{touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
#pg-admin .adm-hb-sw{-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
/* a bigger thumb target on a phone without making the plate taller: the knob keeps its look and
   grows an invisible margin of grab area around itself */
@media (max-width:600px){
  #pg-admin .adm-hb-sw{width:70px}
  #pg-admin .adm-hb-knob::after{content:'';position:absolute;inset:-10px;border-radius:12px}
}

/* 🎯 #adm-accuracy — the first accuracy meter (row 1cajdr.1o). A strip between the focus and the
   brief. The NUMBER is the loud thing, so its own font-size beats the label's; two widths sit
   side-by-side because agreement is the honest signal. Colours reuse the site's existing tokens:
   the number wears the acted/verified green because a passing tally IS acted work — a threshold
   below which it turns red is his call, and this beat leaves that off. */
#pg-admin #adm-accuracy{
  display:flex;align-items:center;flex-wrap:wrap;gap:6px 12px;
  margin:.4rem 0 1.1rem;padding:.55rem .85rem;
  background:rgba(255,255,255,.5);border:1px dashed rgba(48,120,120,.28);border-radius:6px;
  font-family:'Chalkduster',cursive;color:var(--ink-md);line-height:1.4}
#pg-admin .adm-acc-stk{display:inline-block;font-size:1.35em;line-height:1;vertical-align:middle;margin-right:2px}
#pg-admin .adm-acc-lead{font-family:'PixelGamer',monospace;font-size:.7rem;letter-spacing:.09em;color:#3A3A3A;white-space:nowrap}
#pg-admin .adm-acc-figs{display:inline-flex;align-items:baseline;flex-wrap:wrap;gap:2px 8px;font-size:.85rem}
#pg-admin .adm-acc-num{font-family:'PixelGamer',monospace;font-size:1.05rem;color:#559C40;font-weight:600;letter-spacing:.02em}
#pg-admin .adm-acc-w{font-family:'PixelGamer',monospace;font-size:.72rem;color:#5A5855;letter-spacing:.06em}
#pg-admin .adm-acc-when{margin-left:auto;font-family:'Chalkduster',cursive;font-size:.75rem;color:#5A5855;white-space:nowrap}
#pg-admin #adm-accuracy .adm-unknown{text-align:left;padding:0;font-size:.85rem;flex:1 1 100%}
/* 🎯 the drift line — beat 34. Own line under the number so the score reads first and the drift
   reads second; the ALL-CAPS lead phrase is the name the accuracy row already writes into
   accuracy.json's drift[], never a re-wording. Coral, not red, because a drift is not a failure —
   it is a decision he still owes ("a number I can disagree with" needs a THING to disagree with). */
#pg-admin .adm-acc-drift{flex:1 1 100%;display:inline-flex;align-items:baseline;flex-wrap:wrap;gap:2px 6px;margin-top:.15rem;font-family:'Chalkduster',cursive;color:#5A5855;font-size:.82rem;line-height:1.35}
#pg-admin .adm-acc-drift-stk{font-size:1em;line-height:1;margin-right:2px}
#pg-admin .adm-acc-drift-count{font-family:'PixelGamer',monospace;font-size:.7rem;letter-spacing:.09em;color:#B53535}
#pg-admin .adm-acc-drift-lead{font-family:'PixelGamer',monospace;font-size:.75rem;letter-spacing:.04em;color:#3A3A3A}
@media (max-width:600px){
  #pg-admin #adm-accuracy{gap:4px 10px;padding:.5rem .7rem}
  #pg-admin .adm-acc-when{margin-left:0;flex:1 1 100%;text-align:left}
  #pg-admin .adm-acc-drift{font-size:.78rem}
  #pg-admin .adm-acc-drift-lead{font-size:.7rem}
}

/* 📚 #adm-sources — one drawer per card that names its sources, one row per citation.
   Reuses details.adm-d for the drawer shell; the row-level styles below only handle
   the citation line's three parts (location, date, why). */
#pg-admin .adm-sources-drawer .adm-cite{margin:.25rem 0;font-size:.85rem;line-height:1.55;color:#4A4744}
#pg-admin .adm-sources-drawer .adm-cite-loc{font-family:'JetBrains Mono','SF Mono',Menlo,monospace;color:#2D2F32;word-break:break-all}
#pg-admin .adm-sources-drawer .adm-cite-date{margin-left:.5rem;font-size:.72rem;color:#7A7775}
#pg-admin .adm-sources-drawer .adm-cite-why{margin-left:.35rem;color:#5A5855}
@media (max-width:600px){
  #pg-admin .adm-sources-drawer .adm-cite{font-size:.8rem}
  #pg-admin .adm-sources-drawer .adm-cite-date{display:block;margin:.1rem 0 0 0}
  #pg-admin .adm-sources-drawer .adm-cite-why{display:block;margin:.05rem 0 0 0}
}

/* 📏 #adm-standards — deterministic checks with drawers per check kind.
   Each check drawer opens to a stack of hit rows; a hit row carries the pattern
   label, the file:line, the snippet, the why, the fix. The palette drawer opens
   to a swatch grid. The NOT BUILT drawer opens to a list of named unknowns. */
#pg-admin #adm-standards .adm-std-scope{margin:.15rem 0 .6rem;font-size:.8rem}
#pg-admin .adm-std-drawer{margin:.4rem 0}
#pg-admin .adm-std-sub{margin:.25rem 0 .5rem;font-size:.78rem;line-height:1.5}
#pg-admin .adm-std-hit{padding:.4rem .5rem;margin:.35rem 0;border-left:3px solid #C49538;background:rgba(196,149,56,.06);border-radius:2px}
#pg-admin .adm-std-hit-head{display:flex;flex-wrap:wrap;gap:.4rem;align-items:baseline}
#pg-admin .adm-std-label{font-weight:600;color:#2D2F32}
#pg-admin .adm-std-hit .adm-cite-loc{font-family:'JetBrains Mono','SF Mono',Menlo,monospace;color:#4A4744;font-size:.72rem;word-break:break-all}
#pg-admin .adm-std-snippet{margin:.35rem 0;padding:.3rem .5rem;background:rgba(45,47,50,.05);border-radius:2px;font-family:'JetBrains Mono','SF Mono',Menlo,monospace;font-size:.72rem;color:#2D2F32;overflow-x:auto;white-space:pre;line-height:1.4}
#pg-admin .adm-std-why{margin:.2rem 0 0;font-size:.76rem;line-height:1.5}
#pg-admin .adm-std-fix{margin:.15rem 0 0;font-size:.76rem;line-height:1.5;color:#3A6A28}
#pg-admin .adm-std-swatches{display:flex;flex-wrap:wrap;gap:.35rem;margin:.4rem 0}
#pg-admin .adm-std-swatch{display:flex;align-items:center;gap:.35rem;padding:.25rem .4rem;background:rgba(0,0,0,.03);border-radius:3px;font-size:.72rem}
#pg-admin .adm-std-chip{display:inline-block;width:14px;height:14px;border-radius:2px;border:1px solid rgba(0,0,0,.15);flex-shrink:0}
#pg-admin .adm-std-hex{font-family:'JetBrains Mono','SF Mono',Menlo,monospace;color:#2D2F32;font-size:.72rem}
#pg-admin .adm-std-count{color:#5A5855;font-size:.72rem}
#pg-admin .adm-std-nb{padding:.35rem .5rem;margin:.3rem 0;border-left:3px solid #7A7775;background:rgba(122,119,117,.05);border-radius:2px}
@media (max-width:600px){
  #pg-admin .adm-std-hit,#pg-admin .adm-std-nb{padding:.35rem .4rem}
  #pg-admin .adm-std-snippet{font-size:.68rem}
  #pg-admin .adm-std-hit-head{flex-direction:column;gap:.15rem}
}
