/* Recon prototype — dark forest / emerald / restrained gold.
   Palette and spacing rhythm come from .claude/skills/recon-design-system/SKILL.md.
   Alliance colours are DOMAIN colours and are never themed. */

:root{
  --bg:#07110D; --surface:#0E1B16; --raised:#14251D; --border:#22382D;
  --emerald:#19B86B; --green-hot:#2AD67D;
  --gold:#D4AF37; --gold-soft:#E7C96A;
  --text:#F3F5F2; --text-2:#94A59C; --text-3:#65766D;
  --red:#D9503F;

  /* Alliance = domain, never theme. */
  --alliance-red:#E2413A; --alliance-blue:#3B82F6;

  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s6:24px; --s8:32px; --s12:48px;
  --r-sm:9px; --r-md:14px;

  /* Motion. Four durations and three curves, from references/motion.md. There is no fifth
     duration — anything that needs longer than --t-move outside a reward is doing too much. */
  --t-instant:90ms; --t-quick:160ms; --t-move:240ms; --t-reward:900ms;
  --e-out:cubic-bezier(.22,.61,.36,1);
  --e-in:cubic-bezier(.55,.06,.68,.19);
  --e-snap:cubic-bezier(.34,1.2,.64,1);   /* slide-to-submit completion ONLY */
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}

/* Any element given a display in CSS outranks the user agent's [hidden] rule, so setting
   .hidden = true silently stops working and the element renders anyway. That has now cost
   two bugs in this codebase — the whole console rendering under the sign-in form, and the
   update bar showing when no update existed — so it is settled here once. !important is
   right for exactly this: `hidden` means "not present", and no layout rule should outrank it. */
[hidden]{display:none !important}
html,body{overflow-x:hidden}
body{
  margin:0;background:var(--bg);color:var(--text);
  font:400 16px/1.45 Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  -webkit-font-smoothing:antialiased;
}
.num{font-variant-numeric:tabular-nums}
button{font-family:inherit}

/* ---------------------------------------------------------------- icons */
/* One family, one weight, inherited colour — see icons.js and references/iconography.md.
   `vertical-align:-.16em` aligns the 24-grid glyph to the CAP HEIGHT of adjacent text rather
   than its baseline, which is what makes an icon sit level with a word instead of low. */
.ic{display:inline-block;vertical-align:-.16em;flex:none;color:inherit}
[data-icon]{display:inline-flex;align-items:center;color:inherit}

/* An icon-only control: the ICON is 20px, the TARGET is 44px. Padding does that, never a
   bigger glyph (iconography §8). */
.iconbtn{
  width:44px;height:44px;flex:none;display:flex;align-items:center;justify-content:center;
  border:0;background:transparent;color:var(--text-2);cursor:pointer;border-radius:var(--r-sm);
  padding:0;position:relative;transition:color var(--t-instant) var(--e-out);
}
.iconbtn:active{color:var(--text)}
/* Unread marker is a dot ON the bell, not a different bell: swapping the glyph changes the
   silhouette people are scanning for. */
.iconbtn .dot{position:absolute;top:9px;right:9px;width:8px;height:8px;border-radius:50%;
  background:var(--gold);border:2px solid var(--surface)}

/* A single `.empty` dropped into a grid lands in ONE COLUMN and wraps to one word per line.
   Cost a genuinely unreadable prematch panel; fixed here rather than at each call site. */
.statgrid>.empty,.zones>.empty{grid-column:1/-1}

/* ---------------------------------------------------------------- chrome */
.topbar{
  display:flex;align-items:center;gap:var(--s3);
  padding:var(--s3) var(--s4);border-bottom:1px solid var(--border);
  background:var(--surface);position:sticky;top:0;z-index:20;
}
/* THE SUPPLIED MARK, USED VERBATIM.
 *
 * It arrived as a rounded blue square with no alpha channel, so its corners carry white. They
 * are clipped here with border-radius rather than edited out of the file: keying white to
 * transparent is a guess about which pixels were background, it fringes every antialiased
 * edge, and it would punch holes straight through the white R inside the mark. 18.4% is the
 * measured radius of the shape itself, rounded up so no white survives.
 *
 * Nothing recolours it. The blue is not in Recon's palette and that is not this file's
 * problem to solve — a logo is identity, not a theme token. */
.brandmark{
  display:block;flex:none;border-radius:19%;
  /* The mark carries its own background, so it needs no plate behind it on any surface. */
  image-rendering:auto;
}
.brandmark.big{margin:0 auto var(--s3);width:84px;height:84px}
.wordmark{font:700 15px/1 Inter,sans-serif;letter-spacing:2.5px;color:var(--text)}

/* The mark as a control. It must not look like a button — the brand is the brand — so this
   strips the chrome and leaves only the press feedback and a focus ring for the keyboard. */
.brandbtn{
  display:flex;align-items:center;gap:var(--s3);flex:none;
  background:none;border:0;padding:0;margin:0;cursor:pointer;color:inherit;
  border-radius:var(--r-sm);
}
.brandbtn:active{opacity:.7}
.brandbtn:focus-visible{outline:2px solid var(--emerald);outline-offset:3px}

.navbtn{margin-left:calc(-1 * var(--s2));color:var(--text-2)}
.navbtn[aria-expanded="true"]{color:var(--green-hot)}
.navbtn[aria-expanded="true"] .ic{transform:rotate(180deg)}
.navbtn .ic{transition:transform 120ms ease}

/* A panel under the bar rather than a floating card: it is 44px-tall rows the width of the
   screen, which is what a thumb wants, and it cannot end up half off-screen on a phone. */
.navmenu{
  position:sticky;top:53px;z-index:19;
  background:var(--raised);border-bottom:1px solid var(--border);
  box-shadow:0 8px 24px rgba(0,0,0,.35);
}
.navmenu a,.navmenu button{
  display:flex;align-items:center;gap:var(--s3);width:100%;
  background:none;border:0;border-bottom:1px solid var(--border);
  padding:var(--s4);text-align:left;text-decoration:none;cursor:pointer;
  font:600 14px/1.2 Inter,sans-serif;color:var(--text);
}
.navmenu a:last-child,.navmenu button:last-child{border-bottom:0}
.navmenu .ic{color:var(--text-2);flex:none}
.navmenu [aria-current="page"]{color:var(--green-hot)}
.navmenu [aria-current="page"] .ic{color:var(--green-hot)}
.navmenu .what{display:block;font:400 12px/1.35 Inter,sans-serif;color:var(--text-3);margin-top:3px}
.navmenu a:active,.navmenu button:active{background:var(--surface)}
.spacer{flex:1}
.pill{
  font:600 11px/1 Inter,sans-serif;letter-spacing:.8px;text-transform:uppercase;
  padding:6px 10px;border-radius:999px;background:var(--raised);
  color:var(--text-2);border:1px solid var(--border);white-space:nowrap;
}
.pill.live{color:var(--green-hot);border-color:#1d4536}
.pill.off{color:var(--gold-soft);border-color:#3c3520}
.pill.gold{color:var(--gold);border-color:#3c3520}
.pill.pending{color:var(--text-3)}

.banner{padding:10px var(--s4);font-size:13px;border-bottom:1px solid var(--border);
  background:var(--raised);color:var(--text-2)}
.banner.warn{color:var(--gold-soft)}
.banner.bad{color:var(--red)}

main{padding:var(--s4);max-width:520px;margin:0 auto;padding-bottom:96px}

/* ---------------------------------------------------------------- tab bar */
.tabbar{
  position:fixed;left:0;right:0;bottom:0;z-index:20;
  /* minmax(0,1fr), not 1fr. A bare 1fr is minmax(AUTO,1fr) and will not shrink below its
     content, so at 320px the INCENTIVES column took 76px while the others took 61 and the
     bar visibly lost its rhythm. */
  display:grid;grid-template-columns:repeat(6,minmax(0,1fr));
  background:var(--surface);border-top:1px solid var(--border);
  padding-bottom:env(safe-area-inset-bottom);
}
.tabbar button{
  background:none;border:0;padding:10px 4px 12px;cursor:pointer;color:var(--text-3);
  font:600 10px/1.3 Inter,sans-serif;letter-spacing:.7px;text-transform:uppercase;
  display:flex;flex-direction:column;align-items:center;gap:5px;
}
.tabbar button [data-icon]{line-height:0}
.tabbar button[aria-selected=true]{color:var(--green-hot)}
body.focus-mode .tabbar{display:none}
body.focus-mode main{padding-bottom:var(--s6)}

/* ---------------------------------------------------------------- blocks */
h2{font:700 11px/1 Inter,sans-serif;letter-spacing:1.4px;text-transform:uppercase;
  color:var(--text-3);margin:var(--s6) 0 var(--s3) 2px}
h2:first-child{margin-top:0}

.card{background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-md);padding:var(--s4);margin-bottom:var(--s3)}
.card.raised{background:var(--raised)}
.card.accent{border-color:#1d4536}

.row{display:flex;align-items:center;gap:var(--s3);padding:var(--s3) 0;
  border-bottom:1px solid var(--border)}
.row:last-child{border-bottom:0}
.row .grow{flex:1;min-width:0}
.label{font:600 10px/1 Inter,sans-serif;letter-spacing:1.2px;text-transform:uppercase;
  color:var(--text-3)}
.sub{font-size:13px;color:var(--text-2)}

/* Numbers dominate labels. */
.stat{display:flex;flex-direction:column;gap:3px}
.stat .v{font:700 26px/1 Inter,sans-serif;font-variant-numeric:tabular-nums;color:var(--text)}
.stat .v.dash{color:var(--text-3);font-weight:400}
.stat .v.gold{color:var(--gold)}
.statgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s4)}
.statgrid.two{grid-template-columns:repeat(2,1fr)}

.alliance{font:700 11px/1 Inter,sans-serif;letter-spacing:1.2px;padding:5px 9px;
  border-radius:var(--r-sm);text-transform:uppercase}
.alliance.blue{background:rgba(59,130,246,.16);color:#8FBBFF;border:1px solid rgba(59,130,246,.4)}
.alliance.red{background:rgba(226,65,58,.16);color:#FF9A94;border:1px solid rgba(226,65,58,.4)}

/* Watch item — restrained gold, noticeable not alarming. */
.watch{background:rgba(212,175,55,.07);border:1px solid rgba(212,175,55,.32);
  border-radius:var(--r-md);padding:var(--s3) var(--s4);margin-bottom:var(--s3)}
.watch .label{color:var(--gold)}
.watch p{margin:6px 0 0;font-size:14px;color:var(--text)}
.watch .why{margin-top:6px;font-size:13px;color:var(--text-2)}

/* ---------------------------------------------------------------- buttons */
.btn{width:100%;min-height:50px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--raised);color:var(--text);font:600 15px/1 Inter,sans-serif;
  cursor:pointer;transition:background 120ms,border-color 120ms}
.btn:active{background:#193024}
.btn.primary{background:var(--emerald);border-color:var(--emerald);color:#04150C;font-weight:700}
.btn.primary:active{background:var(--green-hot)}
.btn.ghost{background:transparent}
.btn[disabled]{opacity:.45;cursor:not-allowed}
.btn.sm{min-height:40px;font-size:13px}

/* ---------------------------------------------------------------- HOLD */
.stagerail{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:3px;
  margin-bottom:var(--s4)}                 /* grid, not scroll — no horizontal scrollbar */
.stagerail div{font:600 9px/1 Inter,sans-serif;letter-spacing:.4px;text-transform:uppercase;
  text-align:center;padding:7px 2px;border-radius:6px;color:var(--text-3);
  background:var(--surface);border:1px solid transparent;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.stagerail div.done{color:var(--text-3);opacity:.45}
.stagerail div.now{color:var(--green-hot);background:var(--raised);border-color:#1d4536;
  transition:color var(--t-quick) var(--e-out),background var(--t-quick) var(--e-out)}

/* Can this robot score RIGHT NOW? That is the question the scout is actually asking, and it
   deserves its own line rather than a word buried in a stage cell. Never guessed: when the
   game configuration does not say, this says it does not know. */
.hubbar{display:flex;align-items:center;justify-content:center;gap:8px;
  margin:0 0 var(--s3);padding:9px;border-radius:var(--r-sm);
  font:700 11px/1 Inter,sans-serif;letter-spacing:1.4px;text-transform:uppercase}
.hubbar.on{background:rgba(25,184,107,.12);border:1px solid #1d4536;color:var(--green-hot)}
.hubbar.off{background:var(--surface);border:1px solid var(--border);color:var(--text-3)}
.hubbar.unknown{background:var(--surface);border:1px dashed var(--border);color:var(--text-3);
  letter-spacing:.6px;text-transform:none;font-weight:500;font-size:12px;
  flex-wrap:wrap;padding:var(--s2) var(--s3)}
.hubbar .hubset{background:var(--raised);border:1px solid var(--border);border-radius:999px;
  color:var(--text-2);font:600 11px/1 Inter,sans-serif;letter-spacing:.8px;
  text-transform:uppercase;padding:8px 12px;cursor:pointer;min-height:34px}
.hubbar .hubset:active{color:var(--text);border-color:var(--emerald)}
/* The late answer at shift 2+. Quieter than the S1 pair on purpose: it is a way back in for
   a scout who joined mid-match, not the question everybody is asked. */
.hubbar .hubset.late{font-size:10px;padding:6px 10px;min-height:30px;opacity:.85}
.hubbar .grow{flex:1;text-align:left}

/* ---------------------------------------------------------------- match clock */
/* One line. The stage rail directly above already says WHERE the match is, so this only
   carries how long is left and whether the clock is still driving. */
.clockbar{display:flex;align-items:center;gap:var(--s3);margin:0 0 var(--s3);
  padding:var(--s2) var(--s3);border-radius:var(--r-sm);min-height:40px;
  background:var(--surface);border:1px solid var(--border)}
.clockbar .sub{font-size:11px;flex:1}
.clockbar.on{border-color:#1d4536;background:rgba(25,184,107,.08)}
/* Gold, not red: running on manual stages is a deliberate choice a scout made, not a fault. */
.clockbar.manual{border-color:rgba(212,175,55,.34);background:rgba(212,175,55,.07)}
.clockbar .ctime{font:700 17px/1 Inter,sans-serif;color:var(--text);
  font-variant-numeric:tabular-nums;flex:none}
.clockbar.manual .ctime{color:var(--gold-soft)}

/* ---------------------------------------------------------------- climb */
/* Beneath HOLD and the secondary actions, because a climb happens once and FUEL happens all
   match — §6.1 is explicit that not every button gets equal weight. */
.climbbox{margin-top:var(--s4);padding:var(--s3);border-radius:var(--r-sm);
  background:var(--surface);border:1px solid var(--border)}
.climbrow{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap}
.climbrow button{flex:1;min-width:72px;min-height:44px;border-radius:var(--r-sm);
  background:var(--raised);border:1px solid var(--border);color:var(--text);
  font:600 13px/1 Inter,sans-serif;cursor:pointer}
.climbrow button:active{border-color:var(--emerald);color:var(--green-hot)}
/* A failed attempt is still an attempt and still worth recording — restrained, never alarming. */
.climbrow button.fail{color:var(--text-2)}
.climbrow button.fail:active{border-color:#7a4a44;color:#F1736A}

.holdwrap{display:flex;justify-content:center;padding:var(--s2) 0 var(--s3);position:relative}
/* HOLD has to DOMINATE (§6). It was the largest element on the screen and simultaneously the
   faintest — a hairline on the page background reads as an outline of a control rather than a
   control. Presence comes from a raised surface and a brighter rim, not from filling it with
   emerald: a solid green disc would make the resting state look active, and the whole point of
   the ring is that active looks different. */
#hold{
  width:min(70vw,280px);aspect-ratio:1;border-radius:50%;
  border:2px solid #2c4a3c;
  background:radial-gradient(circle at 50% 42%,#16281f 0%,var(--surface) 72%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04),0 10px 34px rgba(0,0,0,.4);
  color:var(--text);
  cursor:pointer;user-select:none;touch-action:none;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  transition:transform 90ms ease-out,border-color 120ms,background 120ms;
}
#hold.held{transform:scale(.975);border-color:var(--emerald);background:#0d2019;
  box-shadow:0 0 0 1px rgba(25,184,107,.25),0 0 44px rgba(25,184,107,.14)}
#hold .big{font:700 30px/1 Inter,sans-serif;letter-spacing:2px}
#hold .cap{font-size:13px;color:var(--text-2)}
#hold .count{font:700 68px/1 Inter,sans-serif;font-variant-numeric:tabular-nums;
  color:var(--green-hot)}
#hold .est{font:600 10px/1 Inter,sans-serif;letter-spacing:1.6px;color:var(--text-2);
  text-transform:uppercase}
#hold .dur{font:500 15px/1 Inter,sans-serif;font-variant-numeric:tabular-nums;
  color:var(--text-2);margin-top:5px}
/* expanding emerald ring while held */
.ring{position:absolute;top:50%;left:50%;width:min(70vw,280px);aspect-ratio:1;
  transform:translate(-50%,-50%);border-radius:50%;border:2px solid var(--emerald);
  opacity:0;pointer-events:none}
#hold.held ~ .ring{animation:pulse 1.6s ease-out infinite}
@keyframes pulse{0%{transform:translate(-50%,-50%) scale(1);opacity:.5}
                 100%{transform:translate(-50%,-50%) scale(1.16);opacity:0}}

/* confirm strip — compact, in place, never a new page */
.confirm{background:var(--raised);border:1px solid #1d4536;border-radius:var(--r-md);
  padding:var(--s3) var(--s4);margin-bottom:var(--s3);text-align:center}
.confirm .label{color:var(--green-hot)}
.confirm .big{font:700 40px/1 Inter,sans-serif;font-variant-numeric:tabular-nums;
  margin:var(--s2) 0}
.confirm .meta{font-size:13px;color:var(--text-2);margin-bottom:var(--s3)}
.stepper{display:flex;align-items:center;justify-content:center;gap:var(--s4);
  margin-bottom:var(--s3)}
.stepper button{width:52px;height:52px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--surface);color:var(--text);font-size:26px;cursor:pointer}
.stepper .n{font:700 30px/1 Inter,sans-serif;font-variant-numeric:tabular-nums;min-width:52px}

/* Secondary actions. Semantically distinguishable (§27) but deliberately SUBORDINATE to
   HOLD: the tint lives on the icon and the border, never on the fill. Three filled colour
   blocks under HOLD would compete with it, and HOLD is the one control that must win. */
.acts{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s2)}
.acts button{min-height:62px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--surface);color:var(--text-2);font:600 11px/1 Inter,sans-serif;
  letter-spacing:.9px;text-transform:uppercase;cursor:pointer;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  transition:background var(--t-instant) var(--e-out),border-color var(--t-instant) var(--e-out)}
.acts button:active{background:var(--raised);color:var(--text)}
.acts button [data-icon]{line-height:0}
.acts button[data-act=pass]{border-color:#1e4038}
.acts button[data-act=pass] .ic{color:#3FC7B4}          /* cool, directional */
.acts button[data-act=miss]{border-color:#3f2622}
.acts button[data-act=miss] .ic{color:#E0705F}          /* restrained red */
.acts button[data-act=defense]{border-color:#3c3520}
.acts button[data-act=defense] .ic{color:var(--gold)}   /* shield / amber */

/* One short green flash on the control the finger is already on — the eye is there, so the
   confirmation goes there too (motion §4). */
@keyframes actflash{0%{background:rgba(42,214,125,.30);border-color:var(--green-hot)}
                    100%{background:var(--surface);border-color:inherit}}
.acts button.flash{animation:actflash var(--t-quick) var(--e-out)}

.breakdown{width:100%;min-height:44px;margin-top:var(--s2);border-radius:var(--r-sm);
  border:1px solid #3a2a22;background:transparent;color:#C98C6B;
  font:600 11px/1 Inter,sans-serif;letter-spacing:1px;text-transform:uppercase;cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:8px}

.stagectl{display:flex;gap:var(--s2);justify-content:center;margin-top:var(--s4)}
.stagectl button{height:42px;min-width:52px;border-radius:var(--r-sm);
  border:1px solid var(--border);background:var(--surface);color:var(--text-2);cursor:pointer}
.stagectl button[disabled]{opacity:.35}
.stagectl .lk.open{color:var(--gold);border-color:#3c3520}

/* ---------------------------------------------------------------- misc */
.chips{display:flex;flex-wrap:wrap;gap:var(--s2)}
.chip{padding:9px 13px;border-radius:999px;border:1px solid var(--border);
  background:var(--surface);color:var(--text-2);font-size:13px;cursor:pointer}
.chip[aria-pressed=true]{background:rgba(25,184,107,.14);border-color:#1d4536;
  color:var(--green-hot)}
.rate{display:grid;grid-template-columns:repeat(6,1fr);gap:var(--s2)}
.rate button{min-height:48px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--surface);color:var(--text-2);font:600 15px/1 Inter,sans-serif;cursor:pointer}
.rate button[aria-pressed=true]{background:rgba(25,184,107,.14);border-color:#1d4536;
  color:var(--green-hot)}
.rate button.ns{font-size:10px;letter-spacing:.6px}

/* Star rating. Gold, because a rating is an assessment of quality — the same reason gold
   carries XP and achievements — and never green, which in Recon means "active/current". */
.rating{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);
  padding:var(--s3) var(--s4) var(--s4)}
.stars{display:flex;gap:var(--s1);justify-content:center}
.stars button{
  width:52px;height:52px;display:flex;align-items:center;justify-content:center;
  background:none;border:0;padding:0;cursor:pointer;color:var(--text-3);
  transition:color var(--t-instant) var(--e-out),transform var(--t-instant) var(--e-out);
}
.stars button:active{transform:scale(.9)}
.stars button.on{color:var(--gold)}
.stars button.on .ic{fill:var(--gold)}   /* filled = chosen; outline = not */
.ratemeta{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  margin-top:var(--s2)}
.ratemeta .ro{font:600 13px/1 Inter,sans-serif;color:var(--text-2);
  font-variant-numeric:tabular-nums}
.ratemeta .ro.set{color:var(--gold-soft)}
.ratemeta .ns{background:transparent;border:1px solid var(--border);border-radius:999px;
  color:var(--text-3);font:600 11px/1 Inter,sans-serif;letter-spacing:.8px;
  text-transform:uppercase;padding:9px 14px;cursor:pointer}
.ratemeta .ns[aria-pressed=true]{border-color:#1d4536;color:var(--green-hot);
  background:rgba(25,184,107,.12)}
/* `font: ... inherit` is not valid — `inherit` is not a font-family, so the whole shorthand
   was dropped and every textarea in the app fell back to the UA's monospace. Scout notes
   and the console's intel form were both rendering in Courier. */
textarea{width:100%;min-height:84px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--surface);color:var(--text);padding:var(--s3);
  font:400 15px/1.45 Inter,sans-serif;resize:vertical}

/* Starting position — a simplified DIAGRAM of the robot's own starting area, not a scale
   field. Discrete regions with an obvious selected state; pixel-perfect placement is never
   asked for (§8), because the scout has thirty seconds and one hand. */
.field{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);
  padding:var(--s3);margin-bottom:var(--s3)}
.fieldsvg{width:100%;height:auto;display:block;touch-action:manipulation}
.fieldsvg .zone{cursor:pointer}
.fieldsvg .zone rect{fill:#0a1712;stroke:var(--border);stroke-width:1;stroke-dasharray:3 3;
  transition:fill var(--t-instant) var(--e-out),stroke var(--t-instant) var(--e-out)}
.fieldsvg .zone text{fill:var(--text-3);font:600 9px/1 Inter,sans-serif;letter-spacing:.4px;
  pointer-events:none;text-transform:uppercase}
.fieldsvg .zone:focus-visible rect{stroke:var(--green-hot);stroke-width:2}
.fieldsvg .zone.on rect{fill:rgba(25,184,107,.16);stroke:var(--emerald);
  stroke-dasharray:none;stroke-width:1.6}
.fieldsvg .zone.on text{fill:var(--green-hot)}
/* The alliance wall is the only cue that makes "left" mean anything, so it is drawn in the
   ALLIANCE's colour — domain colour, never themed. */
.fieldsvg .wall.red{fill:var(--alliance-red)}
.fieldsvg .wall.blue{fill:var(--alliance-blue)}
.fieldsvg .walltx{font:700 7px/1 Inter,sans-serif;letter-spacing:1.2px}
.fieldsvg .walltx.red{fill:var(--alliance-red)}
.fieldsvg .walltx.blue{fill:var(--alliance-blue)}
.zonepick{margin:var(--s3) 0 0;text-align:center}

/* slide to submit */
.slide{position:relative;height:58px;border-radius:var(--r-sm);background:var(--raised);
  border:1px solid var(--border);overflow:hidden;user-select:none;touch-action:none}
.slide .fill{position:absolute;inset:0;width:0;background:rgba(25,184,107,.22)}
.slide .txt{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font:700 12px/1 Inter,sans-serif;letter-spacing:1.6px;text-transform:uppercase;
  color:var(--text-2);pointer-events:none}
.slide .knob{position:absolute;top:4px;left:4px;width:50px;height:48px;border-radius:7px;
  background:var(--emerald);color:#04150C;display:flex;align-items:center;
  justify-content:center;font-size:19px;font-weight:700}
.slide.done .fill{width:100%!important}
.slide.done .knob{background:var(--green-hot)}

.reward{text-align:center;padding:var(--s8) var(--s4)}
.reward .h{font:700 13px/1 Inter,sans-serif;letter-spacing:2px;text-transform:uppercase;
  color:var(--green-hot);margin-bottom:var(--s6)}
.reward .amt{font:700 34px/1 Inter,sans-serif;font-variant-numeric:tabular-nums;
  color:var(--gold);animation:goldpulse 1.1s ease-out}
@keyframes goldpulse{0%{opacity:.25;transform:scale(.94)}100%{opacity:1;transform:scale(1)}}

.toast{position:fixed;left:50%;bottom:84px;transform:translateX(-50%);z-index:40;
  background:var(--raised);border:1px solid var(--border);padding:10px 16px;
  border-radius:var(--r-sm);font-size:14px;opacity:0;transition:opacity 140ms;
  pointer-events:none;white-space:nowrap}
.toast.show{opacity:1}

.sheet{position:fixed;inset:0;z-index:50;background:rgba(3,8,6,.72);
  display:flex;align-items:flex-end;justify-content:center}
.sheet[hidden]{display:none}
.sheet .inner{background:var(--surface);border-top:1px solid var(--border);
  border-radius:var(--r-md) var(--r-md) 0 0;width:100%;max-width:520px;padding:var(--s4);
  padding-bottom:calc(var(--s4) + env(safe-area-inset-bottom))}
.sheet .opt{width:100%;min-height:50px;margin-bottom:var(--s2);border-radius:var(--r-sm);
  border:1px solid var(--border);background:var(--raised);color:var(--text);
  font:600 14px/1 Inter,sans-serif;cursor:pointer;text-align:left;padding:0 var(--s4)}

.empty{color:var(--text-3);padding:var(--s6) var(--s4);text-align:center;font-size:14px}
.empty.left{text-align:left;padding:var(--s4);line-height:1.6}

/* A back control is a button with an icon in it, not a "←" glyph pretending to be one. */
.btn.back{width:auto;padding:0 14px;display:inline-flex;align-items:center;gap:7px}

/* ---------------------------------------------------------------- notifications */
.note{display:flex;gap:var(--s3);align-items:flex-start;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s3) var(--s4);
  margin-bottom:var(--s2);width:100%;text-align:left;color:inherit;font:inherit;cursor:default}
button.note{cursor:pointer}
button.note:active{background:var(--raised)}
.note .nic{flex:none;margin-top:1px;color:var(--text-3)}
.note .t{font:600 14px/1.35 Inter,sans-serif;color:var(--text)}
.note .b{font-size:13px;line-height:1.5;color:var(--text-2);margin-top:3px}
.note .when{font:500 11px/1 Inter,sans-serif;color:var(--text-3);margin-left:auto;
  flex:none;padding-left:var(--s2)}
/* Gold = priority intel. Green = ready/normal. Red = a real failure, and nothing else. */
.note.gold{background:rgba(212,175,55,.07);border-color:rgba(212,175,55,.32)}
.note.gold .nic{color:var(--gold)}
.note.green .nic{color:var(--green-hot)}
.note.bad{background:rgba(217,80,63,.09);border-color:rgba(217,80,63,.4)}
.note.bad .nic{color:var(--red)}
.note.unread{border-left:3px solid var(--gold)}
.demo{display:inline-block;font:600 9px/1 Inter,sans-serif;letter-spacing:1px;
  text-transform:uppercase;padding:4px 7px;border-radius:4px;margin-left:6px;
  background:rgba(212,175,55,.13);color:var(--gold);border:1px solid rgba(212,175,55,.3)}
.demo.pend{background:rgba(101,118,109,.13);color:var(--text-3);border-color:var(--border)}

/* ---------------------------------------------------------------- auth */
/* Sign-in and the no-workspace state are the only screens shown without a session, so both
   drop the chrome: no tab bar to a workspace you cannot reach, no status pills about a
   stack you are not yet talking to. */
body.auth-mode .topbar, body.auth-mode .tabbar{display:none}
body.auth-mode main{padding-top:var(--s8)}

.auth{max-width:380px;margin:0 auto;display:flex;flex-direction:column;justify-content:center;
  min-height:calc(100dvh - 120px)}
.auth .mark{font:700 32px/1 Inter,sans-serif;letter-spacing:6px;text-align:center;
  color:var(--text)}
.auth .mark span{color:var(--emerald)}
.auth .tag{text-align:center;color:var(--text-2);font-size:14px;margin:var(--s3) 0 0}
.auth form{margin-top:var(--s8);display:grid;gap:var(--s2)}
.auth .label{margin-top:var(--s3)}
.auth .btn{margin-top:var(--s4)}
.auth .foot{color:var(--text-3);font-size:12px;line-height:1.5;margin:var(--s6) 0 0;
  text-align:center}

/* 16px minimum: any smaller and iOS Safari zooms the viewport on focus, which on a phone
   throws away the layout mid-sign-in (§14). */
input[type=email],input[type=password],input[type=text]{
  width:100%;min-height:50px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--surface);color:var(--text);padding:0 var(--s3);
  font:400 16px/1 Inter,sans-serif}
input:focus{outline:none;border-color:var(--emerald)}
input[disabled]{opacity:.5}

.err{background:rgba(217,80,63,.12);border:1px solid var(--red);border-radius:var(--r-sm);
  color:#FFB4A8;font-size:13px;line-height:1.5;padding:var(--s3);margin:var(--s4) 0 0}

/* ---------------------------------------------------------------- station claim */
/* Six rows in two alliance groups (ux-flows §6). The alliance bar is a colour cue that
   never carries meaning alone — every row also states its alliance and its state in text
   (design.md §2.2 rule 1), so the screen survives being read in sunlight, on a bad screen,
   or by someone who cannot separate red from green. */
.stgroup{display:flex;gap:var(--s3);margin-bottom:var(--s3)}
.stgroup .tag{width:52px;flex:0 0 52px;display:flex;align-items:flex-start;justify-content:center;
  padding-top:14px;font:700 11px/1 Inter,sans-serif;letter-spacing:1px}
.stgroup.red .tag{color:var(--alliance-red)}
.stgroup.blue .tag{color:var(--alliance-blue)}
.stgroup .rows{flex:1;display:grid;gap:var(--s2)}

.stationrow{display:flex;align-items:center;gap:var(--s3);width:100%;min-height:56px;
  padding:0 var(--s3);border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--surface);color:var(--text);text-align:left;cursor:pointer;
  font:inherit;transition:background 120ms,border-color 120ms}
.stationrow:active{background:var(--raised)}
.stationrow .bar{width:3px;align-self:stretch;margin:10px 0;border-radius:2px}
.stationrow.red .bar{background:var(--alliance-red)}
.stationrow.blue .bar{background:var(--alliance-blue)}
.stationrow .nm{font:700 15px/1 Inter,sans-serif;letter-spacing:.5px}
.stationrow .st{margin-left:auto;font-size:13px;color:var(--text-2);text-align:right}

/* Mine: emerald, because it is the active/selected state — not because it is a colour the
   alliance owns. The alliance bar on the left is untouched. */
.stationrow.mine{border-color:var(--emerald);background:#10221a}
.stationrow.mine .st{color:var(--green-hot);font-weight:600}
.stationrow.taken{cursor:default}
.stationrow.taken .nm{color:var(--text-2)}
/* Somebody is here and you may sit down anyway. It must not read as "taken" (you can tap it)
   and must not read as "available" (you would be surprised by company), so it is neither of
   those two — a gold hairline, the palette's word for "worth noticing". */
.stationrow.shared{border-color:rgba(212,175,55,.34)}
.stationrow.shared .st{color:var(--gold-soft)}
.stationrow.off{cursor:not-allowed;opacity:.5}

/* ---------------------------------------------------------------- update bar */
/* Gold, because it is priority information about the app itself, and DISMISSIBLE by being
   ignorable: it never blocks the screen. A scout mid-match must be able to keep scouting and
   deal with it afterwards — see sw.js on why an update is offered rather than applied. */
.updatebar{display:flex;align-items:center;gap:var(--s3);
  background:rgba(212,175,55,.10);border-bottom:1px solid rgba(212,175,55,.32);
  padding:var(--s3) var(--s4);font-size:13px;color:var(--gold-soft)}
.updatebar button{margin-left:auto;background:transparent;border:1px solid var(--gold);
  color:var(--gold);border-radius:var(--r-sm);padding:6px 12px;
  font:600 12px/1 Inter,sans-serif;cursor:pointer}
.updatebar button:active{background:#201b0c}

/* ---------------------------------------------------------------- reduced motion */
/* Not a blanket `animation:none`. The test is: after motion is disabled, is any INFORMATION
   missing? The live HOLD count and the duration readout are information, so they are
   untouched; the ring, the flash and the reward pulse are decoration, so they go. Feedback
   that was carried by an animation becomes an instant state change — it does not disappear. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:1ms !important;animation-iteration-count:1 !important;
    transition-duration:1ms !important;scroll-behavior:auto !important;
  }
  #hold.held ~ .ring{display:none}
}

/* A label that now carries an icon has to lay its icon out; `.label` is a block by default
   and the SVG sat on the text baseline. */
.watch .label,.note .t{display:flex;align-items:center;gap:6px}
.watch .label{flex-wrap:wrap}
.note .t{display:block}
.note .grow{flex:1;min-width:0}
/* Buttons that carry an icon beside their label need to lay it out. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px}

/* Home's footer strip: where I am, and how much of this seat is behind me. */
.eventstrip{display:flex;align-items:center;gap:var(--s4);margin-top:var(--s6);
  padding-top:var(--s4);border-top:1px solid var(--border)}
.eventstrip .nm{font:600 15px/1.3 Inter,sans-serif;color:var(--text-2);margin-top:5px}
.eventstrip .stat{align-items:flex-end}
.eventstrip .v{font-size:22px}
.eventstrip .of{color:var(--text-3);font-weight:400;font-size:15px}

/* Live scouting is a FOCUSED MODE (§9), not a tab with chrome around it. The tab bar already
   goes; so do the wordmark, the game-config pill and the bell. What stays is the network
   pill, because a scout who has gone offline mid-match needs to know that and cannot be asked
   to leave the screen to find out. */
body.focus-mode .wordmark,
body.focus-mode #cfgpill,
body.focus-mode #navBtn,
body.focus-mode #navMenu,
body.focus-mode #bellBtn{display:none}
/* The mark stays — it is the only thing left identifying the screen — but it stops being the
   way home. Live scouting is a focused mode (§5), and a stray thumb on the logo during a
   match must not navigate out of it. Inert, not hidden: the bar looks exactly as it did. */
body.focus-mode .brandbtn{pointer-events:none}
body.focus-mode .topbar{padding-top:var(--s2);padding-bottom:var(--s2);justify-content:flex-end}

/* One brief gold glow behind the reward figures. Once, on arrival, ~240ms — the whole
   celebration budget (motion.md §8). The scout must be able to leave immediately. */
@keyframes rwglow{
  0%  {box-shadow:0 0 0 0 rgba(212,175,55,.28)}
  60% {box-shadow:0 0 34px 6px rgba(212,175,55,.16)}
  100%{box-shadow:0 0 0 0 rgba(212,175,55,0)}
}
.rewardnums{border-radius:var(--r-md);animation:rwglow 1s var(--e-out) 1}

/* ---------------------------------------------------------------- robot photo slot */
/* One component, used wherever a robot is identified. It is the seam MediaProvider plugs
   into: when an approved canonical photo exists it fills this; until then it says so, small.
   Never a generated or substituted robot image (media-policy §1). */
.idrow{display:flex;gap:var(--s4);align-items:flex-start}
.robotshot{
  width:104px;height:104px;flex:none;border-radius:var(--r-sm);overflow:hidden;
  background:#0a1712;border:1px dashed var(--border);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  color:var(--text-3);text-align:center;padding:6px;
}
.robotshot img{width:100%;height:100%;object-fit:cover;display:block}
.robotshot .cap{font:600 8px/1.25 Inter,sans-serif;letter-spacing:.4px;text-transform:uppercase}
/* Anything below "admin-approved canonical current-season" is LABELLED (media-policy §10).
   A scout must never have to wonder whether what they are looking at was checked. */
.robotshot.provisional{border-style:solid;border-color:rgba(212,175,55,.4)}
.shotnote{font:600 8px/1 Inter,sans-serif;letter-spacing:.8px;text-transform:uppercase;
  color:var(--gold);margin-top:5px;text-align:center}

/* An empty state that is one sentence does not need 200px of padding around it. The tall
   version is right for a whole EMPTY SCREEN; inside a card or a grid it is just a hole. */
.card > .empty,.statgrid > .empty,.field > .empty{padding:var(--s3) 0}

/* ---------------------------------------------------------------- view-as */
/* A distinct ADMIN accent — violet. Deliberately not green (which means active/current), not
   gold (priority intel and rewards), and above all not red or blue, which belong to the
   alliances and must never be borrowed for app chrome. */
.viewasbar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  display:flex;align-items:center;gap:var(--s3);
  padding:10px var(--s4);padding-bottom:calc(10px + env(safe-area-inset-bottom));
  background:#241a3a;border-top:1px solid #4b3a73;color:#CDBBF5;
  font:600 13px/1 Inter,sans-serif;
}
.viewasbar strong{color:#EADCFF;text-transform:uppercase;letter-spacing:.8px;font-size:12px}
.viewasbar button{margin-left:auto;background:transparent;border:1px solid #6A55A0;
  color:#CDBBF5;border-radius:var(--r-sm);padding:8px 12px;
  font:600 12px/1 Inter,sans-serif;cursor:pointer;min-height:36px}
.viewasbar button:active{background:#2f2350}
/* The bar sits where the tab bar does, so the tab bar moves up rather than under it. */
body.viewas .tabbar{bottom:57px}
body.viewas main{padding-bottom:150px}
body.viewas.focus-mode main{padding-bottom:80px}

.roleopt{display:flex;align-items:center;gap:var(--s3);width:100%;min-height:52px;
  padding:0 var(--s3);margin-bottom:var(--s2);border-radius:var(--r-sm);
  border:1px solid var(--border);background:var(--surface);color:var(--text);
  font:600 14px/1 Inter,sans-serif;cursor:pointer;text-align:left}
.roleopt:active{background:var(--raised)}
.roleopt[aria-pressed=true]{border-color:#6A55A0;background:#1b1630;color:#CDBBF5}
.roleopt .who{flex:1;min-width:0}
.roleopt .cnt{font:500 11px/1 Inter,sans-serif;color:var(--text-3)}
/* A dashed border says "nothing here yet". Once there IS a photograph it is a frame, not a
   placeholder outline. */
.robotshot.has-img{border-style:solid;border-color:var(--border);padding:0}
.robotshot.has-img.provisional{border-color:rgba(212,175,55,.5)}

/* ---------------------------------------------------------------- settings */
.prefrow{display:flex;align-items:center;gap:var(--s4);padding:var(--s3) 0;
  border-bottom:1px solid var(--border)}
.prefrow:last-child{border-bottom:0}
.prefrow .pl{font:600 14px/1.3 Inter,sans-serif;color:var(--text)}
.prefrow .pw{font-size:12px;line-height:1.5;color:var(--text-3);margin-top:3px}

/* A switch, not a checkbox: this is a setting that takes effect, not a form field waiting
   to be submitted. 52x30 with a 44px-tall tap area around it. */
.tog{width:52px;height:30px;flex:none;border-radius:999px;border:1px solid var(--border);
  background:var(--surface);cursor:pointer;padding:0;position:relative;
  transition:background var(--t-quick) var(--e-out),border-color var(--t-quick) var(--e-out)}
.tog .knob{position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;
  background:var(--text-3);transition:transform var(--t-quick) var(--e-out),
  background var(--t-quick) var(--e-out)}
.tog.on{background:rgba(25,184,107,.22);border-color:var(--emerald)}
.tog.on .knob{transform:translateX(22px);background:var(--green-hot)}

.namerow{display:flex;gap:var(--s2);align-items:center;margin-top:var(--s3)}
.namerow input{flex:1;min-width:0}

.chipedit{display:flex;flex-direction:column;gap:var(--s2);margin-top:var(--s2)}
.chiprow{display:flex;align-items:center;gap:var(--s2)}
.chiprow .cl{flex:1;min-width:0;min-height:44px}
.chiprow .grip{width:32px;height:44px;display:flex;align-items:center;justify-content:center;
  color:var(--text-3);cursor:pointer;transform:rotate(90deg)}
.chiprow .grip[hidden]{display:none !important}
.mini{min-height:44px;padding:0 12px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--surface);color:var(--text-2);font:600 12px/1 Inter,sans-serif;cursor:pointer;
  display:inline-flex;align-items:center;gap:5px}
.mini.bad{color:#E0705F;border-color:#3f2622;padding:0 10px}
.chip[aria-disabled=true]{opacity:.65;cursor:default}

/* A scout's own override on top of the OS setting. Same rule as the media query: information
   stays, decoration goes. */
html.reduce-motion *,html.reduce-motion *::before,html.reduce-motion *::after{
  animation-duration:1ms !important;animation-iteration-count:1 !important;
  transition-duration:1ms !important;
}
html.reduce-motion #hold.held ~ .ring{display:none}
/* A chip of your own, in the review list. Gold-ish outline, not a different shape: it is the
   same control doing the same thing, just with a different author. */
.chip.mine{border-color:rgba(212,175,55,.42)}
.chip.mine[aria-pressed=true]{background:rgba(25,184,107,.14);border-color:#1d4536}

/* ---------------------------------------------------------------- oauth */
.gbtn{display:flex;align-items:center;justify-content:center;gap:10px}
.gbtn .gmark{
  width:22px;height:22px;border-radius:50%;background:#04150C;color:var(--green-hot);
  display:inline-flex;align-items:center;justify-content:center;
  font:700 13px/1 Inter,sans-serif;
}
/* The provider's own mark is deliberately not reproduced. Google's logo has brand rules, and
   a hand-drawn approximation of somebody else's mark is the same mistake as an approximated
   Recon logo — just committed against a company with lawyers. */
.gpending{
  background:var(--surface);border:1px dashed var(--border);border-radius:var(--r-md);
  padding:var(--s3) var(--s4);
}
.gpending .label{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.orline{display:flex;align-items:center;gap:var(--s3);margin:var(--s6) 0 0;
  color:var(--text-3);font-size:12px}
.orline::before,.orline::after{content:'';flex:1;height:1px;background:var(--border)}

/* ---------------------------------------------------------------- predictions */
/* Two alliances, in the alliances' own colours, and a percentage. Deliberately NOT the shape
   of a betting slip: no odds, no stake field, no balance at risk. There is nothing to wager
   here and the component must not imply otherwise. */
.pred .predbar{display:flex;height:10px;border-radius:999px;overflow:hidden;
  background:var(--raised)}
.pred .predbar .r{background:var(--alliance-red)}
.pred .predbar .b{background:var(--alliance-blue)}
.pred .predrow{display:flex;justify-content:space-between;margin-top:var(--s3);
  font:600 13px/1 Inter,sans-serif;letter-spacing:.6px}
.pred .predrow strong{font-variant-numeric:tabular-nums;font-size:17px}
.pred .predrow .red{color:var(--alliance-red)}
.pred .predrow .blue{color:var(--alliance-blue)}

/* ---------------------------------------------------------------- demo data */
/* GOLD, not the view-as violet. They answer different questions — view-as is "who am I
   rendering as", this is "which numbers am I looking at" — and a scout who conflates them
   would draw a real conclusion from invented robots. */
.demobar{
  position:fixed;left:0;right:0;bottom:0;z-index:59;
  display:flex;align-items:center;gap:var(--s3);
  padding:10px var(--s4);padding-bottom:calc(10px + env(safe-area-inset-bottom));
  background:#241f0d;border-top:1px solid #4b3f16;color:var(--gold-soft);
  font:600 13px/1 Inter,sans-serif;
}
.demobar strong{color:#F2E2A8}
.demobar button{margin-left:auto;background:transparent;border:1px solid #6a5a20;
  color:var(--gold-soft);border-radius:var(--r-sm);padding:8px 12px;
  font:600 12px/1 Inter,sans-serif;cursor:pointer;min-height:36px}
.demobar button:active{background:#2f2810}
body.demodata .tabbar{bottom:57px}
body.demodata main{padding-bottom:150px}
body.demodata.focus-mode main{padding-bottom:80px}
/* Both bars at once: view-as sits above demo, and the tab bar above both. */
body.demodata.viewas .viewasbar{bottom:57px}
body.demodata.viewas .tabbar{bottom:114px}
body.demodata.viewas main{padding-bottom:206px}

/* Below ~360px the longest tab label no longer fits its fifth of the bar. Tightening the
   label is the right trade: the ICON carries recognition and the word confirms it, so a
   slightly smaller word is better than an uneven bar or a truncated one. */
@media (max-width: 359px){
  .tabbar button{font-size:9px;letter-spacing:.2px;padding-left:2px;padding-right:2px}
}

/* Bulk FUEL correction, beneath the ±1 stepper rather than replacing it. Four even cells so
   every target clears 44px at 375px; ±1 keeps the larger, more-used control above. */
.confirm .bulk{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s2);
  margin-bottom:var(--s3)}
.confirm .bulk button{min-height:46px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--surface);color:var(--text-2);cursor:pointer;
  font:600 14px/1 Inter,sans-serif;font-variant-numeric:tabular-nums}
.confirm .bulk button:active{background:var(--raised);color:var(--text);
  border-color:var(--emerald)}

/* ---------------------------------------------------------------- pits */
.pitq{margin-bottom:var(--s4)}

.pwrow{display:flex;flex-direction:column;gap:6px;width:100%;text-align:left;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);
  padding:var(--s3) var(--s4);margin-bottom:var(--s2);color:inherit;font:inherit;cursor:pointer}
.pwrow:active{background:var(--raised)}
.pwrow.resolved{opacity:.6}
.pwtop{display:flex;align-items:center;gap:var(--s3)}
.pwteam{font:700 18px/1 Inter,sans-serif;font-variant-numeric:tabular-nums}
.pwcat{font:600 11px/1 Inter,sans-serif;letter-spacing:1px;text-transform:uppercase;
  color:var(--text-2)}
.pwstat{margin-left:auto;font:600 10px/1 Inter,sans-serif;letter-spacing:1px;
  text-transform:uppercase;padding:5px 9px;border-radius:999px;border:1px solid var(--border);
  color:var(--text-3)}
/* Gold for an open problem — priority intel, not an alarm. Green only once it is fixed. */
.pwstat.open{color:var(--gold);border-color:rgba(212,175,55,.4);background:rgba(212,175,55,.09)}
.pwstat.investigating,.pwstat.monitoring{color:var(--gold-soft);border-color:#3c3520}
.pwstat.resolved{color:var(--green-hot);border-color:#1d4536}
.pwdesc{font-size:14px;color:var(--text)}
.pwmeta{font-size:12px;color:var(--text-3)}
.pwmeta strong{color:var(--gold-soft);font-weight:600}

.pwdetail{text-align:left}
.pwthread{max-height:38vh;overflow-y:auto;border:1px solid var(--border);
  border-radius:var(--r-sm);padding:var(--s3);background:var(--bg)}
.pwu{padding:var(--s2) 0;border-bottom:1px solid var(--border)}
.pwu:last-child{border-bottom:0}
.pwuw{display:block;font:600 11px/1.3 Inter,sans-serif;color:var(--text-3)}
.pwun{display:block;font-size:14px;line-height:1.5;color:var(--text);margin-top:3px}
.pwun em{color:var(--gold-soft);font-style:normal;font-weight:600}

/* Segmented control. Two named halves of one tab — the design system forbids a single
   ambiguous "PITS" label unless the page itself separates them, and this is that separation. */
.seg{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:4px;margin-bottom:var(--s4);
  background:var(--surface);border:1px solid var(--border);border-radius:999px}
.seg button{min-height:38px;border:0;border-radius:999px;background:transparent;
  color:var(--text-2);font:600 13px/1 Inter,sans-serif;cursor:pointer;
  transition:background var(--t-instant) var(--e-out),color var(--t-instant) var(--e-out)}
.seg button[aria-pressed=true]{background:var(--raised);color:var(--green-hot)}

/* SIX tabs need more width per label than five did. Measured, not guessed: the longest label
   ("Rewards") is 54.5px at 10px type, and a sixth of the viewport minus padding only clears
   that above roughly 410px. Below it the whole bar drops to 9px — uniformly, because one tab
   in a different size reads as a mistake rather than as a fit.
   Covers 320, 375 and 390; 430 and up keep the full size. */
@media (max-width:410px){
  .tabbar button{font-size:9px;letter-spacing:.3px;padding-left:2px;padding-right:2px}
}

/* ---------------------------------------------------------------- pit photo */
.psbtns{display:grid;grid-template-columns:1fr 1fr;gap:var(--s2);margin-top:var(--s3)}
/* A <label> wrapping a hidden file input is the only way to style the control; it needs the
   button's own layout back because .btn assumes it is a <button>. */
.psbtns .btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  cursor:pointer;min-height:44px}

.psgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:var(--s2)}
.psitem{margin:0;border:1px solid var(--border);border-radius:var(--r-sm);overflow:hidden;
  background:#0a1712}
.psitem img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover}
.psnoimg{display:flex;align-items:center;justify-content:center;aspect-ratio:4/3;
  font-size:11px;color:var(--text-3)}
/* The review state is the point of showing these at all — an upload with no visible state is
   indistinguishable from one that failed, and the scout's next move is to take another. */
.psstate{font:600 9px/1 Inter,sans-serif;letter-spacing:.8px;text-transform:uppercase;
  padding:6px 4px;text-align:center;color:var(--text-3);border-top:1px solid var(--border)}
.psstate.pending_review{color:var(--gold)}
.psstate.approved{color:var(--green-hot)}
.psstate.rejected{color:var(--red)}
/* `h2:first-child{margin-top:0}` is right almost everywhere and wrong here: the photo heading
   IS the first child of #psForm, so it lost its top margin and collided with the team name
   sitting just above the form. */
#psWho{margin-bottom:var(--s4)}

/* ---------------------------------------------------------------- your reports */
.repcard{margin-bottom:var(--s3)}
.repcard.gone{opacity:.55}
.repacts{display:flex;gap:8px;margin-top:var(--s3)}
.repacts .btn.tiny{width:auto;padding:0 12px}
.btn.tiny.danger{color:#F1736A;border-color:rgba(241,115,106,.42)}
.pill.gold{color:var(--gold-soft);border-color:rgba(212,175,55,.34)}

/* "No preference" is not one of the places — it is the answer that there is no place. The
   dashed edge keeps it in the same row without reading as a seventh position. */
.chip.nopref{border-style:dashed}
.chip.nopref[aria-pressed="true"]{border-style:solid}

/* ---------------------------------------------------------------- partner */
#partnerCard select{width:100%}

/* ---------------------------------------------------------------- strategy on home */
/* Three buttons, not one: "open the desk, then find Compare" is two decisions and Compare is
   one. Primary on the desk itself, because that is the one somebody wants most mornings. */
.strategyhome .strategybtns{display:flex;gap:8px;flex-wrap:wrap}
.strategyhome .btn{width:auto;flex:1;min-width:104px;text-decoration:none;
  display:flex;align-items:center;justify-content:center}
