/* Takings — stylesheet. LIGHT only, by choice (2026-10-05: "lets make it brighter"). Tokens first; the
   series palette lives in app.js and is validated against --surface below. There is no dark theme:
   the colours are literal in too many places (series, stages, crew, chart) for a second palette to
   be cheap, and every pair here is proved by verify.py against ONE set of grounds. */
/* ---------- tokens (light only, by choice) ---------- */
:root{
  --page:#f2f5fa;         /* soft blue-white, not grey */
  --surface:#ffffff;      /* cards — the series palette in app.js is validated against this */
  --surface-2:#eaeff7;    /* hover wash, chips, the agent portrait ground */
  --hair:#dfe5ee;
  --axis:#cfd7e3;
  --ink:#15213a;          /* navy, not black: the one thing that keeps a white page from looking clinical */
  --ink-2:#44506a;
  --muted:#5b687e;
  --on-ink:#ffffff;       /* text on an --ink or --accent ground (primary button, toast, the done tick) */
  --ring:rgba(21,33,58,.08);
  --accent:#2a6fdb;       /* the one blue: links, the current page, the chart line */
  --good:#1b8f3f;
  --bad:#c8323c;
  --warn:#9a5b00;         /* text: "past its date", "tight" — amber that still reads on white */
  --warn-dot:#b06a00;     /* non-text: the pending dot, the storm mark */
  --r:16px;
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --ease:cubic-bezier(.22,1,.36,1);
  --sab:env(safe-area-inset-bottom,0px);
}
*{box-sizing:border-box}
[hidden]{display:none !important}   /* must beat .btn{display:…} etc — the 2026-07-29 partfinder bug */
html{background:var(--page);-webkit-text-size-adjust:100%;color-scheme:light}
body{
  margin:0;background:var(--page);color:var(--ink);font:16px/1.45 var(--sans);
  min-height:100dvh;padding-bottom:calc(96px + var(--sab));
}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;background:none;border:0;padding:0;-webkit-tap-highlight-color:transparent}
button:focus-visible,input:focus-visible,a:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
h1,h2,h3{margin:0;font-weight:600;letter-spacing:-.01em}
.wrap{width:min(100% - 32px,640px);margin-inline:auto}
::selection{background:var(--accent);color:var(--on-ink)}
a{color:var(--accent)}

/* ---------- header ---------- */
.top{position:sticky;top:0;z-index:5;background:rgba(255,255,255,.84);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-bottom:1px solid var(--hair)}
.top .wrap{display:flex;align-items:center;justify-content:space-between;height:56px;gap:8px}
.brand{font-weight:700;font-size:17px;letter-spacing:.02em;display:flex;align-items:center;gap:9px;color:var(--ink);text-decoration:none;flex:none;min-height:44px}
.brand svg{width:22px;height:22px}
.sd{width:8px;height:8px;border-radius:50%;background:var(--muted);margin-left:4px;flex:none;transition:background .3s}
.sd.ok{background:var(--good)}
.sd.pending{background:var(--warn-dot)}
.sd.err{background:var(--bad)}
.sd.busy{animation:pulse 1.1s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}
.monthnav{display:flex;align-items:center;gap:0;margin-left:auto}
.monthnav button{min-width:44px;height:44px;display:grid;place-items:center;border-radius:10px;color:var(--ink-2)}
.monthnav button:hover{background:var(--surface-2);color:var(--ink)}
.monthnav button:disabled{opacity:.3;cursor:default;background:none}
.monthnav .mname{padding:0 6px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.monthnav svg{width:18px;height:18px}
/* On a phone the month arrows and the menu button together are wider than the bar when the brand
   word is there too, so on Money and Bets the word steps aside and the icon + dot stay. Measured by
   verify.py at 390px, not assumed. */
@media(max-width:479px){ .top.month .brand .word{display:none} }

/* ---------- the menu button: it carries the CURRENT page name, so the name is always in the header ----------
   It is a <button> in the header; the menu itself is a <dialog> that sits OUTSIDE the header in the DOM
   (see index.html) and opens in the top layer. The header carries backdrop-filter, which would make it
   the containing block for anything position:fixed inside it — that was the tab-bar trap, and a dialog
   in the top layer does not have it, but the dialog is kept outside the header anyway. */
.menu-btn{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:0 10px 0 12px;border-radius:12px;
  font-weight:600;font-size:15px;color:var(--ink);border:1px solid var(--hair);background:var(--surface);flex:none;max-width:52%}
.menu-btn:hover{background:var(--surface-2)}
.menu-btn[aria-expanded=true]{background:var(--ink);color:var(--on-ink);border-color:var(--ink)}
.menu-btn .pn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.menu-btn svg{width:20px;height:20px;flex:none}
dialog.menu{position:fixed;inset:auto;top:56px;left:0;right:0;margin:0;width:100%;max-width:100%;padding:0;
  border:0;border-top:1px solid var(--hair);border-radius:0 0 22px 22px;background:var(--surface);color:var(--ink);
  max-height:calc(100dvh - 56px);overflow:auto;box-shadow:0 18px 40px -12px rgba(21,33,58,.35)}
dialog.menu::backdrop{background:rgba(21,33,58,.28);backdrop-filter:none}
dialog.menu[open]{animation:menu .22s var(--ease)}
@keyframes menu{from{transform:translateY(-8px);opacity:0}to{transform:none;opacity:1}}
.menu-panel{padding:8px 8px calc(10px + var(--sab))}
.menu-list{list-style:none;margin:0;padding:0;display:grid;gap:2px}
.menu-list a{display:flex;align-items:center;gap:12px;min-height:48px;padding:0 12px;border-radius:12px;color:var(--ink);
  text-decoration:none;font-weight:600;font-size:16px}
.menu-list a:hover{background:var(--surface-2)}
/* "you are here" is a filled accent, hover is a wash — the two must never look alike */
.menu-list a[aria-current]{background:var(--accent);color:var(--on-ink)}
.menu-list a[aria-current]:hover{background:var(--accent)}
.menu-list a:focus-visible{outline-offset:-2px}
.menu-list svg{width:20px;height:20px;flex:none;color:var(--c,var(--muted))}
.menu-list a[aria-current] svg{color:var(--on-ink)}
.menu-foot{margin-top:6px;padding-top:8px;border-top:1px solid var(--hair);display:flex;gap:6px}
.menu-foot button{flex:1;min-height:44px;border-radius:12px;font-weight:600;color:var(--ink-2);padding:0 12px;display:flex;align-items:center;gap:12px}
.menu-foot button:hover{background:var(--surface-2);color:var(--ink)}
.menu-foot svg{width:20px;height:20px;flex:none}
@media(min-width:700px){
  dialog.menu{top:60px;left:auto;right:max(16px,calc((100vw - 640px) / 2));width:300px;border-radius:16px;border:1px solid var(--hair)}
  .menu-panel{padding:8px}
  .menu-list a{min-height:44px;font-size:15px}
}

/* ---------- cards & sections ---------- */
main{display:grid;gap:14px;padding-top:16px}
#tab-home,#tab-money,#tab-work,#tab-bets,#tab-next,#tab-kit,#tab-office,#tab-land{display:grid;gap:14px}
.card{background:var(--surface);border:1px solid var(--ring);border-radius:var(--r);padding:18px;box-shadow:0 1px 2px rgba(21,33,58,.04)}
.sec-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:8px 2px 2px}
.sec-head h2{font-size:13px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);font-weight:600}
.link{color:var(--accent);font-size:14px;font-weight:600;padding:6px 8px;border-radius:8px}
.link:hover{background:var(--surface-2)}

/* ---------- home: the life dashboard ----------
   One card per section, each a LINK to that section (the whole card is the tap target). Everything on
   it is read from the five documents, the status feed and the island — nothing is entered here and
   nothing is stored here. No target, no streak, nothing to chase: his standing rule. */
.home{display:grid;gap:12px}
.home-hero{padding:20px 20px 18px}
.home-hero h1{font-size:24px;font-weight:700;letter-spacing:-.02em}
.home-hero .date{color:var(--muted);font-size:14px;margin-top:2px}
.flags{list-style:none;margin:12px 0 0;padding:0;display:grid;gap:6px}
.flags li{display:flex;align-items:center;gap:10px;font-size:15px;color:var(--ink)}
.flags li::before{content:"";width:9px;height:9px;border-radius:50%;background:var(--c,var(--muted));flex:none}
.flags li.bad{color:var(--bad);font-weight:600}
.flags li.quiet{color:var(--muted)}
.flags li a{color:inherit;text-decoration:underline;text-underline-offset:3px;min-height:44px;display:flex;align-items:center}
.flags li.quiet::before{background:var(--good)}
.hcard{display:block;position:relative;text-decoration:none;color:var(--ink);padding:16px 18px 16px;border-top:4px solid var(--c,var(--hair));
  transition:transform .25s var(--ease),box-shadow .25s var(--ease)}
.hcard:hover{box-shadow:0 10px 24px -14px rgba(21,33,58,.35);transform:translateY(-1px)}
.hcard .lbl{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--c,var(--muted))}
.hcard .lbl .go{font-size:12px;letter-spacing:0;text-transform:none;font-weight:600;color:var(--muted);display:inline-flex;align-items:center;gap:3px}
.hcard .lbl .go svg{width:14px;height:14px}
.hcard .big{font-size:30px;font-weight:700;letter-spacing:-.02em;line-height:1.1;margin-top:8px;font-variant-numeric:tabular-nums;color:var(--ink)}
.hcard .big small{font-size:15px;font-weight:600;color:var(--ink-2);letter-spacing:0;margin-left:6px}
.hcard .big .up{color:var(--good)}
.hcard .big .down{color:var(--bad)}
.hcard .sub{color:var(--muted);font-size:14px;margin-top:4px}
.hcard .strip{margin-top:12px;height:10px}
.hlist{list-style:none;margin:10px 0 0;padding:0;display:grid;gap:5px}
.hlist li{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:baseline;column-gap:8px;font-size:14px;color:var(--ink)}
.hlist li .dot{align-self:center}
.hlist li .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hlist li .v{color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:13px}
.hlist li .v.late{color:var(--warn);font-weight:600}
.hlist li.more{color:var(--muted);font-size:13px;grid-template-columns:1fr}
.hlist li.one{grid-template-columns:1fr}
.hlist li.two{grid-template-columns:minmax(0,1fr) auto}
.hlist li.two .nm{white-space:normal;overflow-wrap:anywhere}   /* a hostname cut to "dealscoutcirc…" says nothing; let it wrap */
/* one colour per section: the menu icon, the card's top edge and its label. The same hexes sit in
   SECTION_COLOUR in app.js for the "what needs you" dots; verify.py checks every one on --surface. */
.c-money{--c:#2a6fdb}
.c-work{--c:#d9541f}
.c-bets{--c:#c93d78}
.c-next{--c:#168a5d}
.c-kit{--c:#b06a00}
.c-office{--c:#6a5ee0}
.c-land{--c:#168a93}
.hlist:empty{display:none}
.hlist li.none{color:var(--muted);grid-template-columns:1fr}
.hline{margin-top:8px;font-size:14px;color:var(--ink-2)}
.hline b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.hline.warn{color:var(--warn)}
.counts{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:10px}
.counts div{background:var(--surface-2);border-radius:12px;padding:10px 10px 8px;text-align:center}
.counts b{display:block;font-size:24px;font-weight:700;line-height:1.1;font-variant-numeric:tabular-nums;color:var(--ink)}
.counts span{font-size:12px;color:var(--muted);font-weight:600}
.counts div.bad b{color:var(--bad)}
.counts div.bad{background:#fbe9ea}
.counts div.busy b{color:var(--accent)}
.shortcuts{padding:16px 18px}
.shortcuts .lbl{font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.shortcuts ul{list-style:none;margin:10px 0 0;padding:0;display:grid;gap:8px}
.shortcuts a{display:flex;align-items:center;gap:12px;min-height:48px;padding:0 12px;border-radius:12px;background:var(--surface-2);color:var(--ink);text-decoration:none;font-weight:600}
.shortcuts a:hover{background:#dfe6f2}
.shortcuts a svg{width:20px;height:20px;flex:none;color:var(--c,var(--accent))}
.shortcuts a .ext{margin-left:auto;color:var(--muted);font-size:12px;font-weight:500;display:inline-flex;align-items:center;gap:4px;white-space:nowrap}
.shortcuts a .ext svg{width:13px;height:13px;color:var(--muted)}
.shortcuts .note{margin-top:8px}
@media(min-width:700px){
  .home{grid-template-columns:1fr 1fr}
  .home .home-hero,.home .shortcuts{grid-column:1/-1}
}

/* ---------- hero ---------- */
.hero{padding:22px 20px 20px}
/* .room borrows the hero's label row. It is NOT a .hero, so it has to be named here — without it
   the title and the pill run together as one word ("The office3 agents"). */
.hero .lbl,.room .lbl{color:var(--ink-2);font-size:14px;display:flex;justify-content:space-between;align-items:center;gap:8px}
.hero .lbl .pill,.room .lbl .pill{font-size:12px;color:var(--muted);border:1px solid var(--hair);padding:2px 8px;border-radius:99px;white-space:nowrap}
.hero .total{font-size:clamp(44px,12vw,58px);font-weight:700;line-height:1.05;letter-spacing:-.03em;margin:6px 0 2px;color:var(--ink)}
.hero .total.pop{animation:pop .5s var(--ease)}
@keyframes pop{0%{transform:scale(.985)}45%{transform:scale(1.015)}100%{transform:none}}
.hero .sub{color:var(--muted);font-size:14px;min-height:20px}
.strip{display:flex;gap:2px;height:12px;border-radius:4px;overflow:hidden;background:var(--axis);margin-top:16px}
.strip .seg{height:100%;min-width:0;transition:flex-basis .7s var(--ease),min-width .7s var(--ease)}
.strip.empty{background:var(--axis)}
.legend{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:12px;font-size:13px;color:var(--ink-2)}
.legend span{display:inline-flex;align-items:center;gap:6px}
.dot{width:9px;height:9px;border-radius:50%;flex:none;background:var(--c,#6b7788)}

/* ---------- plans list ---------- */
.plans{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.plan{position:relative;background:var(--surface);border:1px solid var(--ring);border-radius:var(--r);display:grid;grid-template-columns:1fr auto;align-items:stretch;transition:box-shadow .9s var(--ease),transform .45s var(--ease)}
.plan.bump{box-shadow:0 0 0 1px var(--c),0 0 26px -6px var(--c);transition:none}
.plan.enter{animation:enter .45s var(--ease)}
@keyframes enter{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.plan-main{text-align:left;padding:14px 4px 14px 16px;display:grid;grid-template-columns:auto 1fr auto;grid-template-areas:"dot name amt" "dot share amt" "dot track track";column-gap:10px;row-gap:2px;align-items:center;border-radius:var(--r) 0 0 var(--r);min-width:0}
.plan-main:hover{background:var(--surface-2)}
.plan-main .dot{grid-area:dot;align-self:start;margin-top:7px;width:10px;height:10px}
.plan-main .name{grid-area:name;font-weight:600;font-size:17px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.plan-main .share{grid-area:share;color:var(--muted);font-size:13px;font-variant-numeric:tabular-nums}
.plan-main .amt{grid-area:amt;align-self:start;font-weight:600;font-size:17px;font-variant-numeric:tabular-nums;white-space:nowrap;padding-left:8px;transition:transform .35s var(--ease)}
.plan.bump .amt{transform:scale(1.08);transform-origin:right center}
.track{grid-area:track;height:10px;background:var(--axis);border-radius:0 4px 4px 0;margin-top:8px;overflow:hidden}
.fill{height:100%;width:0;background:var(--c,#6b7788);border-radius:0 4px 4px 0;transition:width .7s var(--ease)}
.plan-add{width:56px;display:grid;place-items:center;color:var(--ink-2);border-left:1px solid var(--hair);border-radius:0 var(--r) var(--r) 0}
.plan-add:hover{background:var(--surface-2);color:var(--ink)}
.plan-add svg{width:20px;height:20px}
.empty{color:var(--muted);font-size:15px;text-align:center;padding:26px 12px}
.empty b{color:var(--ink-2);font-weight:600;display:block;margin-bottom:4px}

/* ---------- work in flight ---------- */
.jobs{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.jobs:empty{display:none}
.job{background:var(--surface);border:1px solid var(--ring);border-radius:var(--r)}
.job-main{width:100%;text-align:left;padding:14px 16px;display:grid;grid-template-columns:minmax(0,1fr) auto;
  column-gap:12px;row-gap:2px;align-items:baseline;border-radius:var(--r)}
.job-main:hover{background:var(--surface-2)}
.j-client{font-weight:600;font-size:17px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.j-amt{font-weight:600;font-size:17px;font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
.j-noamt{color:var(--muted);font-weight:500;font-size:13px}
.j-title{grid-column:1/-1;color:var(--ink-2);font-size:14px}
.j-stage{grid-column:1/-1;display:flex;align-items:center;flex-wrap:wrap;gap:6px;color:var(--muted);font-size:13px;margin-top:5px}
.j-late{color:var(--warn)}
.j-moves{grid-column:1/-1;display:grid;gap:4px;margin-top:10px;padding-top:9px;border-top:1px solid var(--hair)}
.j-move{color:var(--ink-2);font-size:13px;display:flex;gap:8px}
.j-move b{flex:none;min-width:40px;color:var(--muted);font-weight:600;font-size:11px;letter-spacing:.06em;
  text-transform:uppercase;line-height:1.55}
.job.done .j-client{color:var(--ink-2);font-weight:500}
.job.done .j-amt{color:var(--ink-2)}

/* ---------- bets ----------
   Its own ledger, deliberately nothing to do with Money. The direction is a WORD as well as a
   colour ("£40 down"), so it does not depend on being able to tell green from red. */
.bets{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.bets:empty{display:none}
.bet{background:var(--surface);border:1px solid var(--ring);border-radius:var(--r)}
.bet-main{width:100%;text-align:left;padding:14px 16px;display:grid;grid-template-columns:minmax(0,1fr) auto;
  column-gap:12px;row-gap:2px;align-items:baseline;border-radius:var(--r)}
.bet-main:hover{background:var(--surface-2)}
.b-what{font-weight:600;font-size:17px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.b-net{font-weight:600;font-size:16px;font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
.b-net.up{color:var(--good)}
.b-net.down{color:var(--bad)}
.b-net.level{color:var(--ink-2)}
.b-wait{color:var(--muted);font-size:13px;font-weight:500;text-align:right;white-space:nowrap}
.b-meta{grid-column:1/-1;color:var(--muted);font-size:13px;margin-top:4px}
.b-note{grid-column:1/-1;color:var(--ink-2);font-size:13px;margin-top:4px}
.bdir{font-size:.42em;font-weight:600;letter-spacing:0;color:var(--ink-2);vertical-align:baseline}
.bdir.up{color:var(--good)}
.bdir.down{color:var(--bad)}
.note-card{padding:14px 16px}
.note-card p{margin:0}

/* ---------- next: one flat list ---------- */
.todos{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.todos:empty{display:none}
.todo{background:var(--surface);border:1px solid var(--ring);border-radius:14px;
  display:grid;grid-template-columns:auto minmax(0,1fr);align-items:stretch}
.tick{position:relative;width:52px;display:grid;place-items:center;border-radius:14px 0 0 14px;color:transparent}
.tick:hover{background:var(--surface-2)}
.tick svg{width:16px;height:16px;pointer-events:none;position:relative}
.tick::before{content:"";position:absolute;width:22px;height:22px;border:2px solid var(--axis);border-radius:7px}
.tick:hover::before{border-color:var(--muted)}
.todo.done .tick{color:var(--on-ink)}
.todo.done .tick::before{background:var(--good);border-color:var(--good)}
.todo-main{text-align:left;padding:14px 16px 14px 4px;min-height:52px;font-size:16px;
  border-radius:0 14px 14px 0;overflow-wrap:anywhere;display:flex;align-items:center}
.todo-main:hover{background:var(--surface-2)}
.todo.done .todo-main{color:var(--muted);text-decoration:line-through;text-decoration-color:var(--axis)}

/* ---------- kit: dated reminders, nothing checked live ---------- */
.kits{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.kits:empty{display:none}
.kit{background:var(--surface);border:1px solid var(--ring);border-radius:var(--r)}
.kit-main{width:100%;text-align:left;padding:14px 16px;display:grid;grid-template-columns:minmax(0,1fr) auto;
  column-gap:12px;row-gap:2px;align-items:baseline;border-radius:var(--r)}
.kit-main:hover{background:var(--surface-2)}
.k-what{font-weight:600;font-size:16px;line-height:1.3;overflow-wrap:anywhere}
.k-when{font-weight:600;font-size:14px;color:var(--ink-2);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.k-in{grid-column:1/-1;color:var(--muted);font-size:13px;margin-top:3px}
.k-in.late{color:var(--warn)}
.k-note{grid-column:1/-1;color:var(--ink-2);font-size:13px;margin-top:5px}

/* ---------- the office ----------
   A pixel-art room on a <canvas>, with the WORDS laid over it as HTML: one button per desk (the tap
   target, the name label and the screen reader's sentence), a speech bubble per desk for working /
   failed, and a card. A "pip" is only green when the feed SAID the thing worked; grey is "ran, we do
   not know"; a hollow ring is "we have no idea", and it is hollow precisely so it cannot be
   mistaken at a glance for a quiet, healthy grey. The room itself keeps its own colours — it is a
   picture, and its labels and bubbles sit on the picture, not on the page. */
.room{padding:18px 14px 16px}
.scene{position:relative;margin:14px 0 0;line-height:0;border-radius:12px;overflow:hidden;background:#2f3546;user-select:none;-webkit-user-select:none}
.scene canvas{display:block;width:100%;height:auto;image-rendering:pixelated;image-rendering:crisp-edges}
/* the desk button: covers chair, desk and label; the name sits on the label band at its foot */
.spot{position:absolute;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;
  padding:0 4px 3px;border-radius:8px;line-height:1.2;color:#ffffff;min-width:0}
.spot:hover{background:rgba(255,255,255,.07)}
.spot:focus-visible{outline:2px solid #ffffff;outline-offset:-2px;border-radius:8px}
/* 10px on a phone: three desks in 390px leaves ~100px a label, and "softwaredev2" must fit whole —
   a name cut to "softwar…" is two different people. verify.py measures it rather than trusting this. */
.s-name{display:inline-flex;align-items:center;gap:3px;max-width:100%;font-size:10px;font-weight:600;letter-spacing:-.01em;
  background:rgba(13,13,13,.78);padding:2px 5px;border-radius:99px;border-bottom:2px solid var(--c,#898781);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.s-name .pip{width:7px;height:7px}
.s-name.s1{font-size:9px}
.s-name.s2{font-size:8px;letter-spacing:-.02em}
.s-txt{overflow:hidden;text-overflow:ellipsis;min-width:0}
/* the bubble hangs off the head, points down at it, and leans inwards at the room's edges */
/* The clamp sits on the inner span, not the bubble: -webkit-line-clamp clips the CONTENT box, so on
   a padded element the third line shows through the bottom padding. Seen, not theorised. */
.bubble{position:absolute;transform:translateX(-50%);z-index:2;font-size:10px;line-height:1.25;font-weight:500;color:#0d0d0d;
  background:#f4f2ea;padding:4px 7px;border-radius:9px;text-align:center;pointer-events:none;box-shadow:0 2px 0 rgba(0,0,0,.35)}
.bubble>span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}
.bubble::after{content:"";position:absolute;left:50%;bottom:-5px;margin-left:-4px;border:4px solid transparent;border-top:5px solid #f4f2ea;border-bottom:0}
.bubble.bad{background:#ffd9d9;color:#5a1414}
.bubble.bad::after{border-top-color:#ffd9d9}
.pip{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--muted);flex:none;vertical-align:.06em}
.pip.good{background:var(--good)}
.pip.bad{background:var(--bad)}
.pip.busy{background:var(--warn-dot);animation:pulse 1.1s ease-in-out infinite}
.pip.plain{background:var(--muted)}
.pip.unknown{background:none;box-shadow:inset 0 0 0 2px var(--muted)}
/* on the dark label band over the room the dots need their brighter forms */
.s-name .pip.good{background:#3ab54a}
.s-name .pip.busy{background:#fab219}
.s-name .pip.bad{background:#e66767}
.s-name .pip.plain{background:#a9a7a0}
.s-name .pip.unknown{box-shadow:inset 0 0 0 2px #a9a7a0}
@media(min-width:560px){
  .room{padding:18px 20px 18px}
  .s-name{font-size:12px}
  .bubble{font-size:11px}
}
/* the card */
.agent .ag-top{display:flex;align-items:center;gap:14px;margin-bottom:12px}
.agent .face{width:72px;height:90px;flex:none;image-rendering:pixelated;border-radius:12px;background:var(--surface-2);border-bottom:3px solid var(--c,#6b7788)}
.agent .ag-who{min-width:0}
.agent .ag-role{margin:0 0 6px;color:var(--ink-2);font-size:14px}
.agent .ag-state{margin:0;display:flex;align-items:center;gap:7px;font-size:14px;color:var(--ink)}
.agent .ag-head{margin:0 0 6px;font-size:17px;font-weight:600;line-height:1.3;overflow-wrap:anywhere}
.agent .ag-when{margin:0 0 10px;font-variant-numeric:tabular-nums}
.agent .ag-lines{list-style:none;margin:0 0 12px;padding:10px 0 0;border-top:1px solid var(--hair);display:grid;gap:4px;color:var(--ink-2);font-size:14px}
.agent .ag-note{margin:0}
/* Now / Today: the sheet's second half. Job rows are a small grid — time, then the words, then the
   outcome on its own line under them — so a 120-character description wraps under its own time
   rather than pushing the outcome off the right edge of a 390px sheet. */
.agent .ag-h{margin:14px 0 6px;padding-top:12px;border-top:1px solid var(--hair);font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.agent .ag-now{margin:0;font-size:15px;line-height:1.4;overflow-wrap:anywhere}
.agent .ag-now.busy{font-weight:600;color:var(--ink)}
.agent .ag-now-when{margin:4px 0 0;font-variant-numeric:tabular-nums}
.agent .ag-jobs{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.agent .ag-job{display:grid;grid-template-columns:auto 1fr;column-gap:10px;row-gap:2px;align-items:baseline;font-size:14px;line-height:1.35}
.agent .j-time{color:var(--ink-2);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:13px}
.agent .j-desc{color:var(--ink);overflow-wrap:anywhere}
.agent .j-meta{grid-column:2;display:flex;align-items:center;gap:6px;color:var(--muted);font-size:13px}
.agent .j-meta .pip{width:7px;height:7px}
.agent .ag-src{margin:8px 0 0}

/* ---------- Gavs Land ----------
   Watch-only. Everything here is words and drawings of counts the server sent; the one control on
   the whole tab is "Start a new island", and it goes through the confirm sheet. Plain English, no
   numbers without a word beside them saying what they are. */
.land-hero .total{font-size:clamp(38px,10vw,50px)}
.land-hero .total small{font-size:.42em;font-weight:600;color:var(--ink-2);letter-spacing:0;margin-left:6px}
.land-hero .total .up{color:var(--good)}
.land-hero .total .down{color:var(--bad)}
.land-facts{display:grid;grid-template-columns:1fr 1fr;gap:10px 14px;margin-top:14px;padding-top:12px;border-top:1px solid var(--hair)}
.land-facts div{min-width:0}
.land-facts b{display:block;font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:2px}
.land-facts span{font-size:15px;font-weight:600;color:var(--ink);line-height:1.3;overflow-wrap:anywhere}
.land-facts span.famine{color:var(--bad)}
.land-facts span.tight{color:var(--warn)}
.land-clock{color:var(--muted);font-size:13px;margin-top:12px}
.land-dead{color:var(--bad);font-weight:600}
/* since you last looked */
.since{padding:16px 18px}
.since h2{font-size:13px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);font-weight:600;margin-bottom:8px}
.since p{margin:0 0 6px;color:var(--ink);font-size:15px;line-height:1.4}
.since ul{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:5px}
.since li{color:var(--ink-2);font-size:14px;line-height:1.35;display:grid;grid-template-columns:auto 1fr;column-gap:8px}
.since li b{color:var(--muted);font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:1.7}
/* the population chart */
.land-chart{padding:16px 16px 12px}
.land-chart svg{display:block;width:100%;height:auto}
.land-chart .axis{stroke:var(--axis);stroke-width:1}
.land-chart .line{fill:none;stroke:var(--accent);stroke-width:2;stroke-linejoin:round}
.land-chart .area{fill:var(--accent);opacity:.14}
.land-chart .lbl{fill:#5b687e;font-size:11px;font-family:system-ui,sans-serif}
.land-chart .lbl.r{text-anchor:end}
.land-chart .peak{fill:#44506a;font-size:11px;font-family:system-ui,sans-serif}
.land-chart .peak.r{text-anchor:end}
.land-chart .thin{stroke:var(--bad);stroke-width:1;opacity:.55}
.land-chart .foot{color:var(--muted);font-size:13px;margin-top:8px}
/* discoveries */
.techs{list-style:none;margin:0;padding:0;display:grid;gap:0}
.tech{display:grid;grid-template-columns:auto minmax(0,1fr) auto;column-gap:12px;row-gap:2px;align-items:baseline;padding:11px 0;border-top:1px solid var(--hair)}
.tech:first-child{border-top:0}
.tech .yr{color:var(--muted);font-size:12px;font-variant-numeric:tabular-nums;white-space:nowrap;min-width:52px;line-height:1.6}
.tech .nm{font-weight:600;font-size:15px;color:var(--ink)}
.tech .fx{grid-column:2;color:var(--ink-2);font-size:13px;line-height:1.35}
.tech .who{color:var(--muted);font-size:12px;white-space:nowrap;text-align:right;line-height:1.6}
.tech.lost .nm{color:var(--bad);text-decoration:line-through;text-decoration-color:var(--bad)}
.tech.possible .nm,.tech.later .nm{color:var(--ink-2);font-weight:500}
.tech.possible .yr,.tech.later .yr{color:var(--axis)}
.tech.later{opacity:.6}
/* the log */
.landlog{list-style:none;margin:0;padding:0}
.landlog li{display:grid;grid-template-columns:auto 12px minmax(0,1fr);column-gap:8px;align-items:baseline;padding:8px 0;border-top:1px solid var(--hair);font-size:14px;line-height:1.4}
.landlog li:first-child{border-top:0}
.landlog .yr{color:var(--muted);font-size:12px;font-variant-numeric:tabular-nums;white-space:nowrap;min-width:52px}
.landlog .k{width:8px;height:8px;border-radius:50%;background:var(--axis);align-self:center;justify-self:center}
.landlog .k.found{background:var(--accent)}
.landlog .k.lost,.landlog .k.famine,.landlog .k.sick,.landlog .k.fight,.landlog .k.end{background:var(--bad)}
.landlog .k.storm{background:var(--warn-dot)}
.landlog .k.birth{background:var(--good)}
.landlog .k.left{background:#6a5ee0}
.landlog .k.arrive,.landlog .k.note{background:var(--ink-2)}
.landlog .tx{color:var(--ink);overflow-wrap:anywhere}
.landlog li.dim .tx{color:var(--ink-2)}
.landlog .more{margin-top:10px}
/* the island picture: counts drawn, not a map — its own colours, it is a picture */
.isle{padding:14px 14px 12px}
.isle svg{display:block;width:100%;height:auto;border-radius:12px;background:#1b3a5c}
.isle .sea{fill:#1b3a5c}
.isle .sand{fill:#d9c48a}
.isle .grass{fill:#3c7a3a}
.isle .grass2{fill:#4b8f45}
.isle .tree{fill:#245a2a}
.isle .trunk{fill:#5a3b22}
.isle .hut{fill:#a86a3c}
.isle .roof{fill:#e0c890}
.isle .stone{fill:#9a9a94}
.isle .field{fill:#c9a541}
.isle .fieldrow{stroke:#8f7220;stroke-width:1}
.isle .boat{fill:#7a4a24}
.isle .wave{stroke:#4a7fb0;stroke-width:1.2;fill:none;opacity:.7}
.isle .person{fill:#f0c7a4}
.isle .cap{color:var(--muted);font-size:13px;margin-top:8px;display:flex;flex-wrap:wrap;gap:4px 14px}
.isle .cap span{white-space:nowrap}
/* the people */
.folk{list-style:none;margin:0;padding:0;display:grid;gap:0}
.folk li{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:10px;row-gap:1px;padding:8px 0;border-top:1px solid var(--hair);font-size:14px;line-height:1.35}
.folk li:first-child{border-top:0}
.folk .nm{font-weight:600;color:var(--ink)}
.folk .nm i{font-style:normal;font-weight:500;color:var(--muted);font-size:12px;margin-left:6px}
.folk .ag{color:var(--ink-2);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.folk .kin{grid-column:1/-1;color:var(--muted);font-size:12px}
.pyr{display:grid;grid-template-columns:auto 1fr auto 1fr auto;gap:4px 8px;align-items:center;font-size:13px;color:var(--ink-2);font-variant-numeric:tabular-nums}
.pyr .band{color:var(--muted);text-align:right;white-space:nowrap;font-size:12px}
.pyr .bar{height:12px;border-radius:3px;background:var(--axis);position:relative;min-width:0}
.pyr .bar i{position:absolute;top:0;bottom:0;border-radius:3px;background:#c93d78;width:var(--w,0%)}
.pyr .bar.m i{background:var(--accent)}
.pyr .bar.f i{right:0}
.pyr .bar.m i{left:0}
.pyr .n{min-width:22px;text-align:center}
.pyr .hd{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.06em}
/* past islands */
.past{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.past li{background:var(--surface);border:1px solid var(--ring);border-radius:var(--r);padding:12px 16px;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:12px;row-gap:2px}
.past .nm{font-weight:600;font-size:16px}
.past .yrs{color:var(--ink-2);font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.past .how{grid-column:1/-1;color:var(--muted);font-size:13px}
.land-new{display:flex;justify-content:center;padding:6px 0 4px}
.land-new .btn{min-width:min(100%,280px)}

/* ---------- history ---------- */
.hist{padding:16px 16px 12px}
.hist .bars{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:6px;align-items:end;height:118px;border-bottom:1px solid var(--axis);padding:22px 2px 0}   /* padding-top = headroom for the value label */
.hist .col{position:relative;display:grid;align-items:end;justify-items:center;height:100%;border-radius:6px 6px 0 0}
.hist .col:hover{background:var(--surface-2)}
.hist .bar{height:var(--h,0%);width:min(100%,22px);background:#9fb0c8;border-radius:4px 4px 0 0;transition:height .7s var(--ease);min-height:2px}
.hist .col.cur .bar{background:var(--accent)}
.hist .col.none .bar{background:var(--axis);min-height:2px}
.hist .val{position:absolute;bottom:calc(var(--h,0%) + 4px);left:50%;transform:translateX(-50%);font-size:11px;color:var(--ink-2);white-space:nowrap;font-variant-numeric:tabular-nums}
.hist .col:last-child .val{left:auto;right:0;transform:none}
.hist .labels{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:6px;text-align:center;font-size:11px;color:var(--muted);margin-top:6px;font-variant-numeric:tabular-nums}
.hist .labels span.cur{color:var(--ink);font-weight:600}
.hist .foot{color:var(--muted);font-size:13px;margin-top:10px;text-align:center}

/* ---------- data ---------- */
.data{display:grid;gap:10px}
.data p{margin:0;color:var(--ink-2);font-size:14px}
.data .row{display:flex;flex-wrap:wrap;gap:8px}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:0 16px;border-radius:12px;font-weight:600;font-size:15px;border:1px solid var(--hair);background:var(--surface);color:var(--ink)}
.btn:hover{background:var(--surface-2);border-color:var(--axis)}
.btn.primary{background:var(--accent);color:var(--on-ink);border-color:var(--accent)}
.btn.primary:hover{background:#235fc0}
.btn.danger{color:var(--bad)}
.btn.ghost{background:none;border-color:transparent;color:var(--ink-2)}
.btn.ghost:hover{background:var(--surface-2)}
.btn svg{width:18px;height:18px}
.note{color:var(--muted);font-size:13px}
.warn{color:var(--warn);font-size:13px}
.err-note{color:var(--bad);font-size:13px}

/* ---------- floating add button ---------- */
.fab{position:fixed;left:0;right:0;bottom:var(--sab);padding:12px 16px 12px;display:flex;justify-content:center;pointer-events:none;background:linear-gradient(to top,rgba(242,245,250,.96),rgba(242,245,250,0));z-index:4}
.fab .btn{pointer-events:auto;min-height:52px;padding:0 24px;font-size:16px;border-radius:99px;box-shadow:0 10px 30px -8px rgba(42,111,219,.55);width:min(100%,360px)}

/* ---------- dialogs (bottom sheet on phones) ---------- */
dialog{border:0;padding:0;background:var(--surface);color:var(--ink);border-radius:20px 20px 0 0;width:100%;max-width:100%;margin:auto 0 0;box-shadow:0 -10px 40px rgba(21,33,58,.25);max-height:92dvh;overflow:auto}
dialog::backdrop{background:rgba(21,33,58,.45);backdrop-filter:blur(2px)}
dialog[open]{animation:sheet .32s var(--ease)}
@keyframes sheet{from{transform:translateY(24px);opacity:0}to{transform:none;opacity:1}}
@media(min-width:640px){
  dialog{margin:auto;width:440px;border-radius:20px;border:1px solid var(--hair)}
  @keyframes sheet{from{transform:translateY(10px) scale(.98);opacity:0}to{transform:none;opacity:1}}
}
.sheet{padding:20px 20px calc(20px + var(--sab))}
.sheet header{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.sheet h2{font-size:19px}
.sheet .x{width:40px;height:40px;display:grid;place-items:center;border-radius:10px;color:var(--ink-2);margin-right:-8px}
.sheet .x:hover{background:var(--surface-2);color:var(--ink)}
.sheet .x svg{width:18px;height:18px}
.field{display:grid;gap:6px;margin-bottom:14px}
.field label{font-size:13px;color:var(--ink-2);font-weight:500}
.field input[type=text],.field input[type=password],.field input[type=number],.field input[type=date]{width:100%;min-height:48px;background:var(--page);border:1px solid var(--hair);border-radius:12px;padding:0 14px;color:var(--ink);color-scheme:light}
.field input:focus{border-color:var(--accent);outline:none}
.money{position:relative}
.money input{padding-left:36px !important;font-size:22px;font-weight:600;font-variant-numeric:tabular-nums}
.money::before{content:"£";position:absolute;left:14px;top:50%;transform:translateY(-50%);font-size:20px;color:var(--muted)}
/* two short fields side by side, so the sheet's actions stay reachable on a phone */
.duo{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.duo .money input{font-size:19px;padding-left:30px !important}
.duo .money::before{left:11px;font-size:17px}
.nudge{margin:-6px 0 14px}
/* the actions of a long sheet stay on screen while the fields above it scroll */
.actions.stick .btn.danger{flex:0 0 auto;padding:0 12px}
.actions.stick{position:sticky;bottom:calc(-1 * var(--sab));background:var(--surface);
  padding:10px 0 calc(6px + var(--sab));margin-top:0;box-shadow:0 -10px 14px -10px var(--surface)}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:0 12px;border-radius:99px;border:1px solid var(--hair);color:var(--ink-2);font-weight:500;background:var(--page)}
.chip[aria-checked=true]{border-color:var(--ink);color:var(--ink);background:var(--surface-2)}
.check{display:flex;align-items:center;gap:12px;min-height:44px;color:var(--ink-2);font-size:15px;line-height:1.3;margin-bottom:8px}
.check input{width:20px;height:20px;accent-color:var(--accent)}
.actions{display:flex;gap:8px;margin-top:6px;flex-wrap:wrap}
.actions .btn{flex:1}
.entries{list-style:none;margin:0 0 16px;padding:0;border-top:1px solid var(--hair)}
.entries li button{width:100%;display:grid;grid-template-columns:1fr auto;gap:2px 12px;text-align:left;padding:10px 4px;border-bottom:1px solid var(--hair);min-height:52px;align-items:center;border-radius:6px}
.entries li button:hover{background:var(--surface-2)}
.entries .e-amt{font-weight:600;font-variant-numeric:tabular-nums;text-align:right}
.entries .e-note{color:var(--ink-2);font-size:14px}
.entries .e-meta{color:var(--muted);font-size:12px;grid-column:1/-1}
.entries .rep{display:inline-flex;align-items:center;gap:4px}
.entries .rep svg{width:12px;height:12px}
.vstat{display:flex;justify-content:space-between;color:var(--ink-2);font-size:14px;margin:4px 0 12px}
.vstat b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.divider{border:0;border-top:1px solid var(--hair);margin:16px 0}

/* ---------- toast ---------- */
.toast{position:fixed;left:50%;bottom:calc(84px + var(--sab));transform:translate(-50%,16px);opacity:0;background:var(--ink);color:var(--on-ink);padding:10px 12px 10px 16px;border-radius:99px;display:flex;align-items:center;gap:12px;font-weight:600;font-size:15px;box-shadow:0 10px 30px -6px rgba(21,33,58,.5);z-index:6;transition:transform .35s var(--ease),opacity .35s var(--ease);pointer-events:none;max-width:calc(100% - 32px);white-space:nowrap}
.toast.on{transform:translate(-50%,0);opacity:1;pointer-events:auto}
.toast button{color:var(--on-ink);text-decoration:underline;text-underline-offset:3px;padding:6px 8px;border-radius:8px;font-weight:700}
.toast button:hover{background:rgba(255,255,255,.14)}
.toast .t-msg{overflow:hidden;text-overflow:ellipsis}

/* ---------- no-JS / failed-JS fallback (visible by default, script replaces it) ---------- */
.nojs{padding:26px 22px}
.nojs h1{font-size:26px;margin-bottom:8px}
.nojs p{margin:0 0 8px;color:var(--ink-2)}
.nojs .err{color:var(--bad);font-family:ui-monospace,monospace;font-size:13px;white-space:pre-wrap}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{transition:none !important;animation:none !important}
}
.c-msg{margin:0 0 16px;color:var(--ink-2)}
.entries li.pad{padding:12px 4px}

/* ---------- signing in ----------
   The sign-in page (login.html) and the two sign-in things inside the app: the "Signing in" card at
   the foot of every tab, and the card shown instead of any figures when this device is offline and
   cannot prove it is still signed in. */
body.signin{padding-bottom:var(--sab);min-height:100dvh;display:grid;align-content:center}
.login{width:min(100% - 32px,420px);padding-block:28px 24px}
.login-card{padding:24px 22px 22px}
.login-brand{display:flex;align-items:center;gap:9px;font-weight:700;font-size:17px;letter-spacing:.02em;color:var(--ink);margin-bottom:20px}
.login-brand svg{width:26px;height:26px;flex:none}
.login h1{font-size:26px;margin-bottom:4px}
.login-why,.login-kept{margin:6px 0 0;color:var(--ink-2);font-size:14px}
.login-kept{color:var(--warn)}
.login form{margin-top:18px}
.login .check{margin-bottom:4px}
.login-err{margin:6px 0 4px}
.login .actions{margin-top:12px}
.login-nopass,.login-nojs{margin-top:16px}
.login-nopass p,.login-nojs p{margin:0 0 8px;color:var(--ink-2)}
.login-nopass b{color:var(--ink)}
.login-cmd{font-family:ui-monospace,monospace;font-size:13px;line-height:1.5;background:var(--page);border:1px solid var(--hair);border-radius:10px;padding:10px 12px;overflow-wrap:anywhere;color:var(--ink) !important}
.login-foot{text-align:center;margin:0}
.signedout{padding:26px 22px}
.signedout h1{font-size:24px;margin-bottom:8px}
.signedout p{margin:0 0 10px;color:var(--ink-2)}
.signedout .row{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}
