/* Supervisor (Ops) sub-app styles — extracted from the old supervisor.html inline block and
 * SCOPED under #g-sup so they can never bleed into the guard app markup that shares the page.
 * Design tokens live on #g-sup (not :root) so guard.css's globals stay authoritative; the
 * generic utilities (.hidden, base *, body) are intentionally NOT redefined — guard.css owns them. */
#g-sup{
  --navy:#032b49;--navy-2:#005080;--red:#e11d2a;--green:#0f9d58;--amber:#e08600;--line:#e4eaf1;--muted:#5f7288;--bg:#eaf0f6;--ink:#16222f;
  --blue:#0a6bb0;--blue-bright:#1a86d0;--blue-light:#4aa3dd;
  --grad-primary:linear-gradient(90deg,#005080,#0a6bb0);
  --grad-header-mobile:linear-gradient(165deg,#032b49,#005080);
  background:var(--bg);color:var(--ink);min-height:100vh;padding-bottom:calc(64px + env(safe-area-inset-bottom));
}
#g-sup .shead{position:sticky;top:0;z-index:50;background:var(--grad-header-mobile);color:#fff;padding:12px 16px calc(10px);display:flex;align-items:center;gap:10px}
#g-sup .shead .ttl{font-family:var(--font-display);font-weight:800;font-size:16px;flex:1}
#g-sup .shead .ttl small{display:block;font-weight:500;font-size:11px;opacity:.75}
/* position:relative anchors the 44px hit-area overlay at the foot of this file — see THE 44px FLOOR
   IN FIELD MODE'S CHROME. Nothing about the pill's paint changes. */
#g-sup .sclock{border:none;border-radius:99px;padding:8px 14px;font-size:12.5px;font-weight:800;cursor:pointer;background:rgba(255,255,255,.14);color:#fff;position:relative}
#g-sup .sclock.on{background:var(--green)}
/* Break pill. Amber when ON break — the same amber .tag.brk already uses for an officer on break,
   so one colour means one thing across the whole Field-mode surface. Tighter padding than the clock
   pill because it shares a ~360px header with the title, the clock and the exit button. The
   [hidden] line is belt-and-braces: nothing currently gives .sclock a display, so the UA rule works
   on its own — but the day someone adds `#g-sup .shead button{display:flex}` for alignment, the
   attribute silently loses and an off-duty person grows a Break button. Cheap to pre-empt. */
#g-sup .sbreak{padding:8px 11px;white-space:nowrap}
#g-sup .sbreak[hidden]{display:none}
#g-sup .sbreak.on{background:var(--amber);color:#fff}
/* Glance strip — two facts a supervisor should not have to tap for: officers posted, staff on the
   clock. Dispatchers get this from the console topbar chip; this is the phone's version of it. */
#g-sup .sglance{display:flex;gap:8px;margin:2px 0 12px}
/* font:inherit + appearance:none are load-bearing, not decoration: the staff tile is a <button>
   (it toggles the list open) and the officer tile is a <div>. Without these the two sit side by
   side in DIFFERENT typefaces — the UA button font vs the app's — which is exactly the kind of
   half-a-millimetre wrongness that makes a screen look unfinished. */
#g-sup .sglance .gl{flex:1;min-width:0;background:#fff;border:1px solid var(--line);border-radius:13px;padding:9px 11px;text-align:left;font:inherit;color:var(--ink);-webkit-appearance:none;appearance:none}
#g-sup .sglance .gl b{display:block;font-family:var(--font-display);font-size:20px;line-height:1.15;font-variant-numeric:tabular-nums}
#g-sup .sglance .gl small{display:block;font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;margin-top:2px}
#g-sup .sglance .gl .sub{display:block;font-size:11px;font-weight:800;color:var(--amber);margin-top:3px}
#g-sup .sglance .gl.tap{cursor:pointer}
[data-theme="dark"] #g-sup .sglance .gl{background:#12202c;border-color:#22364a}
#g-sup .sview{display:none;padding:14px 14px 20px}
#g-sup .sview.on{display:block}
#g-sup .scard{background:#fff;border:1px solid var(--line);border-left-width:4px;border-radius:13px;padding:11px 13px;margin-bottom:9px;font-size:14px}
#g-sup .scard .meta{font-size:12.5px;color:var(--muted);margin-top:3px;overflow-wrap:anywhere}
#g-sup .scard.ok{border-left-color:var(--green)}
#g-sup .scard.bad{border-left-color:var(--red);background:#fdf3f3}
#g-sup .scard.warn{border-left-color:var(--amber);background:#fffaf0}
#g-sup .scard.grey{border-left-color:#b9c1cf}
#g-sup .sec{font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:16px 0 8px}
#g-sup .sec:first-child{margin-top:2px}
#g-sup .tag{font-size:10.5px;font-weight:800;padding:2px 8px;border-radius:99px;margin-left:5px;white-space:nowrap}
#g-sup .tag.brk{background:#fdf0dc;color:#a8660a}#g-sup .tag.geo{background:#fdeaea;color:#c0182a}#g-sup .tag.late{background:var(--red);color:#fff}
#g-sup .sbtn{display:inline-block;border:none;border-radius:10px;padding:9px 14px;font-size:13.5px;font-weight:800;cursor:pointer;background:var(--grad-primary,var(--navy));color:#fff}
#g-sup .sbtn.ghost{background:#eef1f6;color:#1b2230}
#g-sup .sbtn.red{background:var(--red)}
#g-sup .sbtn.green{background:var(--green)}
#g-sup .sbtn.wfull{display:block;width:100%;text-align:center;margin-top:8px}
#g-sup .sbtn:disabled{opacity:.5}
#g-sup .sbtn.grad{background:var(--grad-primary,linear-gradient(90deg,#005080,#0a6bb0));color:#fff;border:none}
#g-sup .srow-acts{display:flex;gap:8px;margin-top:9px;flex-wrap:wrap}
#g-sup .sos-card{border:3px solid var(--red);border-radius:14px;background:#fff;padding:13px;margin-bottom:10px;animation:spulse 1.3s ease-in-out infinite}
@keyframes spulse{0%,100%{box-shadow:0 0 0 0 rgba(225,29,42,.35)}50%{box-shadow:0 0 0 8px rgba(225,29,42,0)}}
#g-sup .sos-card .t{font-weight:800;color:#c0182a;font-size:15px}
#g-sup .sos-card .sbtn.green.wfull{padding:12px}
#g-sup .responding{color:var(--green);font-weight:800;font-size:13px}
#g-sup a{color:#0a6bb0;text-decoration:none;font-weight:600}
#g-sup .snav{position:fixed;left:0;right:0;bottom:0;z-index:60;display:flex;background:#fff;border-top:1px solid var(--line);padding-bottom:env(safe-area-inset-bottom)}
#g-sup .snav button{flex:1;border:none;background:none;padding:9px 0 7px;font-size:10.5px;font-weight:700;color:#8ea0b3;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:2px}
#g-sup .snav button.on{color:#0a6bb0;font-weight:800}
#g-sup .snav .ic{font-size:20px;line-height:1}
#g-sup .snav button .bdg{position:absolute;transform:translate(14px,-2px);background:var(--red);color:#fff;font-size:9px;font-weight:800;border-radius:99px;min-width:15px;height:15px;display:flex;align-items:center;justify-content:center;padding:0 3px}
#g-sup #smap{height:44vh;min-height:280px;border-radius:14px;border:1px solid var(--line)}
#g-sup .me-dot{width:100%;height:100%;border-radius:50%;background:#0a6bb0;border:3px solid #fff;box-shadow:0 0 0 4px rgba(10,107,176,.35);animation:mepulse 1.8s ease-in-out infinite}
@keyframes mepulse{0%,100%{box-shadow:0 0 0 4px rgba(10,107,176,.35)}50%{box-shadow:0 0 0 10px rgba(10,107,176,0)}}
#g-sup .nb-row{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--line);border-left-width:4px;border-radius:12px;padding:10px 12px;margin-bottom:8px;font-size:13.5px}
#g-sup .nb-row.uncovered{border-left-color:var(--red);background:#fff7f7}
#g-sup .nb-row.covered{border-left-color:var(--green)}
#g-sup .nb-row.idle{border-left-color:#b9c1cf}
#g-sup .nb-row input[type=checkbox]{width:19px;height:19px;flex:0 0 auto;accent-color:#0a6bb0}
#g-sup .nb-main{flex:1;min-width:0}
#g-sup .nb-name{font-weight:800}
#g-sup .nb-meta{font-size:12px;color:var(--muted);margin-top:2px}
#g-sup .nb-dist{font-weight:800;color:var(--navy);white-space:nowrap;font-size:13px}
#g-sup .nb-nav{flex:0 0 auto;background:var(--green);color:#fff;border:none;border-radius:10px;padding:9px 12px;font-size:12.5px;font-weight:800;text-decoration:none;white-space:nowrap}
#g-sup .nb-due{color:#c0182a;font-weight:700}
/* Add-to-route button. 34px because this is tapped one-handed, often in a car park in the dark —
   below ~32 the miss rate climbs. When the site is on the route it shows its stop NUMBER, so the
   list itself tells you the order without cross-referencing the panel above. */
#g-sup .nb-add{flex:0 0 auto;width:34px;height:34px;border-radius:10px;border:1.5px solid var(--line);background:#fff;color:#0a6bb0;font-size:17px;font-weight:800;line-height:1;cursor:pointer;padding:0}
#g-sup .nb-add.on{background:#0a6bb0;border-color:#0a6bb0;color:#fff;font-size:14px}
#g-sup .nb-row.on-route{box-shadow:inset 0 0 0 1.5px rgba(10,107,176,.35)}
/* The route panel: the supervisor's own list, above the site list they build it from. */
#g-sup .rt-wrap{background:var(--navy);color:#fff;border-radius:14px;padding:12px 13px;box-shadow:0 8px 24px rgba(10,18,38,.28)}
#g-sup .rt-head{display:flex;flex-wrap:wrap;gap:6px;align-items:baseline;font-size:13px;margin-bottom:9px}
#g-sup .rt-head b{flex:1;min-width:0}
#g-sup .rt-warn{font-size:11.5px;color:#ffd07a;font-weight:700}
#g-sup .rt-empty{font-size:12.5px;line-height:1.5;color:#cdd9e8;background:rgba(255,255,255,.07);border-radius:10px;padding:10px 11px}
#g-sup .rt-list{display:flex;flex-direction:column;gap:6px}
#g-sup .rt-stop{display:flex;align-items:center;gap:8px;background:rgba(255,255,255,.09);border-radius:10px;padding:7px 8px;font-size:13px}
#g-sup .rt-num{flex:0 0 auto;width:22px;height:22px;border-radius:7px;background:#fff;color:var(--navy);font-weight:800;font-size:12px;display:flex;align-items:center;justify-content:center}
#g-sup .rt-main{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:700}
#g-sup .rt-mi{font-weight:600;color:#b9cadd;font-size:12px}
#g-sup .rt-stop .nb-due{color:#ff9aa5}
#g-sup .rt-b{flex:0 0 auto;width:32px;height:32px;border-radius:9px;border:0;background:rgba(255,255,255,.16);color:#fff;font-size:15px;line-height:1;cursor:pointer;padding:0}
#g-sup .rt-b[disabled]{opacity:.32;cursor:default}
#g-sup .rt-b.rt-x{background:rgba(255,255,255,.1);color:#ff9aa5}
#g-sup .rt-acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
#g-sup .rt-acts .sbtn{background:#fff;color:var(--navy);padding:8px 13px}
#g-sup .rt-acts .sbtn.ghost{background:transparent;color:#fff;border:1.5px solid rgba(255,255,255,.42)}
#g-sup .rt-acts .sbtn[disabled]{opacity:.45}
/* Search over the site list. 16px font is deliberate: anything smaller makes iOS/Android zoom the
   page on focus, which throws the map off screen mid-typing. */
#g-sup .nb-search{width:100%;padding:11px 12px;margin:0 0 9px;border:1px solid var(--line);border-radius:11px;font-size:16px;font-family:inherit;background:#fff}
/* Searchable picker for long <select>s (269 sites, 312 officers).
   ⚠ EVERY RULE HERE IS DOUBLED ONTO .gcf-ov, AND MUST STAY THAT WAY. These were scoped to #g-sup
   alone, which is true of every sheet that renders INSIDE the Field-mode shell — but the task
   composer (supTaskFromMsg) builds a .gcf-ov overlay and appends it to document.body, so a picker
   attached in there matched not one of these selectors and painted as a bare readonly input over an
   invisible, backgroundless, unlayered popup. That is the house's known body-appended-overlay trap,
   and it fails SILENTLY: the markup is perfect and the screen is broken. Any NEW .sp-pick rule needs
   both scopes, and any new body-appended sheet that calls supPicker() needs its own scope added. */
#g-sup .sp-pick,.gcf-ov .sp-pick{position:relative}
#g-sup .sp-pick-in,.gcf-ov .sp-pick-in{width:100%;padding:11px 12px;border:1px solid var(--line);border-radius:11px;font-size:15px;background:#fff;font-family:inherit;cursor:pointer}
#g-sup .sp-pick-pop,.gcf-ov .sp-pick-pop{position:absolute;left:0;right:0;top:0;z-index:60;background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:0 14px 34px rgba(10,18,38,.22);padding:8px}
#g-sup .sp-pick-q,.gcf-ov .sp-pick-q{width:100%;padding:10px 11px;border:1px solid var(--line);border-radius:9px;font-size:16px;font-family:inherit}
#g-sup .sp-pick-list,.gcf-ov .sp-pick-list{max-height:46vh;overflow:auto;margin-top:7px;-webkit-overflow-scrolling:touch}
#g-sup .sp-pick-row,.gcf-ov .sp-pick-row{display:block;width:100%;text-align:left;background:none;border:0;border-radius:9px;padding:11px 10px;font:600 14px/1.3 inherit;color:var(--navy);cursor:pointer}
#g-sup .sp-pick-row:active,#g-sup .sp-pick-row:hover,.gcf-ov .sp-pick-row:active,.gcf-ov .sp-pick-row:hover{background:#eef4fb}
#g-sup .sp-pick-none,.gcf-ov .sp-pick-none{padding:12px 10px;font-size:13px;color:var(--muted)}
/* The <optgroup> heading, kept alive across the upgrade (supPicker). Sticky so "Fellow officers"
   is still on screen a hundred rows into the roster — the heading is the whole navigation aid. */
#g-sup .sp-pick-grp,.gcf-ov .sp-pick-grp{position:sticky;top:0;background:#fff;padding:9px 10px 5px;font:700 11px/1.2 inherit;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
/* Officers who work this post — call/text buttons big enough to hit one-handed. */
#g-sup .reg-row{display:flex;align-items:center;gap:8px}
#g-sup .reg-main{flex:1;min-width:0}
#g-sup .reg-b{flex:0 0 auto;background:#eef4fb;color:#0a6bb0;border-radius:9px;padding:9px 12px;font-size:12.5px;font-weight:800;text-decoration:none;white-space:nowrap}
#g-sup .reg-b.call{background:var(--green);color:#fff}
#g-sup .ch-row{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--line);border-radius:12px;padding:11px 13px;margin-bottom:7px;font-size:14px;cursor:pointer}
#g-sup .ch-row .ic2{font-size:18px;flex:0 0 auto}
#g-sup .ch-main{flex:1;min-width:0}
#g-sup .ch-name{font-weight:800;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .ch-prev{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
#g-sup .ch-cat{font-size:10px;font-weight:700;color:var(--muted);background:#eef2f8;border-radius:6px;padding:1px 6px;vertical-align:1px}
#g-sup .ch-dot{width:10px;height:10px;border-radius:50%;background:var(--red);flex:0 0 auto}
#g-sup .ch-search{width:100%;padding:11px 13px;border:1px solid var(--line);border-radius:12px;font-size:15px;background:#fff}
/* Gear-list filter box (My gear · Currently out). LAYOUT ONLY — it rides on .ch-search for its skin
   so it inherits the dark rule below and the measured 44px tap height, and .ch-search itself is left
   alone because Directory, Posts and the mention picker all share it. .gear-row has margin-bottom
   but no margin-top, so without this the box sits flush on the first row. */
#g-sup .asr-q{margin-bottom:8px}
#g-sup .ch-top{display:flex;gap:8px;align-items:center;margin-bottom:10px}
#g-sup .ch-top .ch-search{flex:1;margin-bottom:0}
#g-sup .ch-top .sbtn{flex:none}
/* filter tabs: horizontally-scrollable chip row */
#g-sup .ch-tabs{display:flex;gap:7px;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:9px;margin-bottom:2px;scrollbar-width:none}
#g-sup .ch-tabs::-webkit-scrollbar{display:none}
#g-sup .ch-tab{flex:0 0 auto;background:#eef2f8;border:1px solid var(--line);color:var(--muted);font-weight:700;font-size:12.5px;padding:6px 13px;border-radius:999px;white-space:nowrap;cursor:pointer;display:inline-flex;align-items:center;gap:5px}
#g-sup .ch-tab.on{background:linear-gradient(135deg,#005080,#0a6bb0);color:#fff;border-color:transparent}
#g-sup .ch-tab .tb{background:#e11d2a;color:#fff;font-size:9px;font-weight:800;border-radius:99px;min-width:15px;height:15px;display:inline-flex;align-items:center;justify-content:center;padding:0 4px}
#g-sup .ch-tab.on .tb{background:rgba(255,255,255,.28)}
/* pin star + right-side cluster on each row */
#g-sup .ch-rt{display:flex;align-items:center;gap:8px;flex:0 0 auto}
#g-sup .ch-pin{background:none;border:none;font-size:17px;line-height:1;color:#ccd5e0;cursor:pointer;padding:2px}
#g-sup .ch-pin.on{color:#f5a623}
#g-sup .th-head{display:flex;align-items:center;gap:10px;position:sticky;top:52px;background:var(--bg);padding:8px 0;z-index:5}
/* position:relative anchors the 44px hit-area overlay at the foot of this file — see THE 44px FLOOR
   IN FIELD MODE'S CHROME. The chip's own box is untouched. */
#g-sup .th-back{border:none;background:#fff;border:1px solid var(--line);border-radius:10px;padding:8px 12px;font-size:13px;font-weight:800;cursor:pointer;position:relative}
#g-sup .th-title{font-weight:800;font-size:15px;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .th-msgs{padding:4px 0 10px;display:flex;flex-direction:column;gap:7px}
#g-sup .bub{max-width:82%;padding:8px 12px;border-radius:13px;font-size:14px;line-height:1.35;white-space:pre-wrap;word-break:break-word}
#g-sup .bub.me{align-self:flex-end;background:var(--navy);color:#fff}
#g-sup .bub.them{align-self:flex-start;background:#fff;border:1px solid var(--line)}
#g-sup .bub .bm{font-size:10.5px;opacity:.65;margin-bottom:2px}
#g-sup .bub.prio{border:2px solid var(--red)}
#g-sup .th-compose{position:sticky;bottom:calc(64px + env(safe-area-inset-bottom));display:flex;gap:8px;background:var(--bg);padding:8px 0 4px}
#g-sup .th-compose input{flex:1;padding:12px 14px;border:1px solid var(--line);border-radius:99px;font-size:15px;background:#fff}
#g-sup .th-compose button{border:none;background:var(--navy);color:#fff;border-radius:99px;padding:0 18px;font-weight:800;font-size:14px;cursor:pointer}
#g-sup .more-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
#g-sup .more-tile{background:#fff;border:1px solid var(--line);border-radius:14px;padding:16px 12px;text-align:center;font-weight:800;font-size:13px;cursor:pointer}
#g-sup .more-tile .ic3{display:block;font-size:26px;margin-bottom:6px}
#g-sup .gear-row{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--line);border-radius:12px;padding:10px 13px;margin-bottom:8px;font-size:13.5px}
#g-sup .gear-row .gk{font-size:19px}
#g-sup .gear-main{flex:1;min-width:0}
#g-sup .gear-tag{font-size:11px;color:var(--muted)}
/* ── ISSUE GEAR / UNIFORM: the multi-item line editor ─────────────────────────────────────────────
   Each line is a CARD, not a table row. A table needs four columns of horizontal room and this sheet
   is 360px wide with a 12px gutter each side: the item name is the long thing and it gets the full
   width, with Qty / $ each / Remove on a second line under it. Everything typed or tapped clears the
   house --tap:44px floor (guard.css:2059) — the number inputs inherit it from #g-sup .field input's
   11px padding + 15px text, and Remove states it outright because a bare text button would not.  */
#g-sup .ui-row{background:#fff;border:1px solid var(--line);border-radius:13px;padding:11px 12px 12px;margin-bottom:9px}
#g-sup .ui-nums{display:flex;align-items:flex-end;gap:9px;margin-top:9px}
#g-sup .ui-n{flex:1 1 0;min-width:0;display:block}
#g-sup .ui-n>span{display:block;font-size:11px;font-weight:700;color:var(--muted);margin-bottom:4px;text-transform:uppercase;letter-spacing:.04em}
#g-sup .ui-n>input{width:100%;min-height:var(--tap,44px);padding:10px 11px;border:1px solid var(--line);
  border-radius:11px;font-size:15px;font-family:inherit;background:#fff;color:inherit}
/* flex:none + its own floor: it must not shrink under the two inputs, and "Remove" on a 44px target
   is the difference between deleting the line you meant and the one below it. */
#g-sup .ui-del{flex:none;min-height:var(--tap,44px);padding:0 13px;border:1px solid var(--line);
  border-radius:11px;background:#eef1f6;color:#1b2230;font-family:inherit;font-size:12.5px;font-weight:800;cursor:pointer}
#g-sup .ui-line-note{display:none;margin-top:7px;font-size:12px;font-weight:700;color:var(--red)}
#g-sup .ui-line-note.on{display:block}
/* WHY this line costs what it costs — "1st shirt — company provided", "shirt #2 — $15.00". Green,
   not grey: it is the good news on the line, and it is the sentence a supervisor repeats out loud to
   the officer standing in front of them. */
#g-sup .ui-why{display:none;margin-top:7px;font-size:12px;font-weight:700;color:var(--green)}
#g-sup .ui-why.on{display:block}
/* A price the supervisor cannot change has to LOOK like one, or the first thing they do is tap it
   and wonder why the keyboard did nothing. */
#g-sup .ui-n>input.locked{background:var(--sunk,#f4f7fb);color:var(--muted);font-weight:800}
/* .sbtn's own 9px/13.5px padding measures 36px — under the 44px floor, and this is the control the
   supervisor taps once per extra item. Measured at 375x812 before this rule. */
#g-sup .ui-add{min-height:var(--tap,44px);display:flex;align-items:center;justify-content:center;margin-top:2px}
/* Same story, and worse: Clear signature shipped at 6px/12px = 28px tall. It is the undo for the one
   control on this screen that cannot be undone any other way — a bad scrawl has to be clearable on
   the first tap, with an officer watching. */
#g-sup .ui-sigclear{min-height:var(--tap,44px);display:inline-flex;align-items:center;margin-top:6px;padding:0 14px;font-size:12.5px}
/* The running total, said BEFORE anyone signs. A signature over a number the supervisor never saw
   is the same problem as a signature over an unlisted set of items. */
#g-sup .ui-total{display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin:11px 0 4px;padding:11px 13px;border:1px solid var(--line);border-radius:12px;
  background:var(--sunk,#f4f7fb);font-size:13px;font-weight:700;color:var(--muted)}
#g-sup .ui-total b{font-size:18px;font-weight:800;color:var(--heading,#0b2036);font-variant-numeric:tabular-nums}
#g-sup .ui-total .ui-total-none{font-weight:600}
/* The acknowledgment is the legal core of the record — it is quoted, not paraphrased, and it stays
   readable rather than being squeezed into a hint. */
#g-sup .ui-ack{background:var(--sunk,#f4f7fb);border:1px solid var(--line);border-radius:12px;
  padding:11px 13px;font-size:12.5px;line-height:1.55;font-style:italic;color:var(--ink,#1b2230)}
#g-sup .ui-ack+.ck{margin-top:8px}
#g-sup .sev-seg{display:flex;gap:6px}
#g-sup .sev-seg button{flex:1;border:1px solid var(--line);background:#fff;border-radius:10px;padding:10px 4px;font-size:12.5px;font-weight:800;cursor:pointer;color:#3a5064}
#g-sup .sev-seg button.on{color:#fff}
#g-sup .sev-seg button[data-sev="1"].on{background:var(--green);border-color:var(--green)}
#g-sup .sev-seg button[data-sev="2"].on{background:var(--amber);border-color:var(--amber)}
#g-sup .sev-seg button[data-sev="3"].on{background:var(--red);border-color:var(--red)}
.clockcam{position:fixed;inset:0;background:rgba(10,16,30,.92);z-index:200;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;padding:20px}
.clockcam img{max-width:88vw;max-height:55vh;border-radius:14px;border:3px solid #fff}
.clockcam .hint{color:#c3cede}
#g-sup .rad-bar,body > .rad-bar{position:fixed;right:10px;bottom:calc(72px + env(safe-area-inset-bottom));width:172px;max-width:calc(100vw - 20px);background:#01192b;color:#fff;border-radius:12px;box-shadow:0 6px 22px rgba(0,0,0,.4);padding:8px 9px;z-index:100000;font-family:inherit}
#g-sup .field{margin-bottom:11px}
#g-sup .field label{display:block;font-size:12px;font-weight:700;color:var(--muted);margin-bottom:5px}
#g-sup .field select,#g-sup .field input,#g-sup .field textarea{width:100%;padding:11px 12px;border:1px solid var(--line);border-radius:11px;font-size:15px;background:#fff;font-family:inherit}
#g-sup .rub{background:#fff;border:1px solid var(--line);border-radius:13px;padding:4px 13px;margin-bottom:12px}
#g-sup .rub-item{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:11px 0;border-bottom:1px solid #f0f2f7;font-size:13.5px;flex-wrap:wrap}
#g-sup .rub-item:last-child{border-bottom:none}
#g-sup .rub-seg{display:inline-flex;gap:4px}
#g-sup .rub-seg button{border:1px solid var(--line);background:#fff;border-radius:8px;padding:6px 11px;font-size:12px;font-weight:700;cursor:pointer;color:#3a5064}
#g-sup .rub-seg button.on{background:var(--navy);color:#fff;border-color:var(--navy)}
#g-sup .rub-seg button.p.on{background:var(--green);border-color:var(--green)}
#g-sup .rub-seg button.f.on{background:var(--red);border-color:var(--red)}
#g-sup .hint{font-size:12.5px;color:var(--muted)}
/* Motion: house tokens (guard.css :root / DESIGN-SYSTEM.md §7) — the supervisor overlay shares the
   officer app's document, so it gets the tokens for free. Same contract as guard.css's .toast:
   slide + fade in over --t-med, fade out over --t-fast with the translate reset held until after
   the fade. translateX(-50%) is the centring and is carried through BOTH states. */
.stoast{position:fixed;left:50%;transform:translateX(-50%) translateY(10px);bottom:calc(76px + env(safe-area-inset-bottom));background:#032b49;color:#fff;padding:11px 18px;border-radius:99px;font-size:13.5px;font-weight:600;z-index:100;box-shadow:0 8px 24px rgba(3,18,34,.35);opacity:0;transition:opacity var(--t-fast) var(--ease),transform 0s linear var(--t-fast);pointer-events:none;max-width:92vw;text-align:center}
.stoast.on{opacity:1;transform:translateX(-50%) translateY(0);transition:opacity var(--t-med) var(--ease),transform var(--t-med) var(--ease)}
@media (prefers-reduced-motion:reduce){
  .stoast,.stoast.on{transform:translateX(-50%);transition:opacity var(--t-fast) linear}
}
#g-sup .empty{color:var(--muted);font-size:13.5px;padding:14px 4px;text-align:center}
.map-pin-txt{display:inline-block;transform:translate(-50%,-130%);background:#032b49;color:#fff;border-radius:6px;padding:3px 8px;font-size:11px;font-weight:700;white-space:nowrap;box-shadow:0 1px 5px rgba(0,0,0,.35)}
.map-pin-txt.covered{background:#0f9d58}.map-pin-txt.uncovered{background:#e11d2a}
/* covered, but nobody's position is known: still green — dimmed with a dashed inner rule, matching the dashed geofence ring */
.map-pin-txt.covered.nogps{background:#3f8f66;outline:1px dashed rgba(255,255,255,.75);outline-offset:-3px}
.sdot{color:#fff;border-radius:50%;width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:13px;border:2px solid #fff;box-sizing:border-box;box-shadow:0 0 0 4px rgba(15,157,88,.3),0 1px 4px rgba(0,0,0,.35);background:#0f9d58}
.sdot.brk{background:#e08600;box-shadow:0 0 0 4px rgba(224,134,0,.3),0 1px 4px rgba(0,0,0,.35)}.sdot.off{background:#e11d2a;box-shadow:0 0 0 4px rgba(225,29,42,.3),0 1px 4px rgba(0,0,0,.35)}
.ssos{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:18px;border-radius:50%;background:#fff;box-shadow:0 0 0 4px rgba(225,29,42,.45)}
#g-sup .ann-img{display:block;width:100%;max-height:260px;object-fit:cover;border-radius:11px;margin:8px 0 2px;cursor:zoom-in;border:1px solid var(--line)}
#g-sup .tour-stops{margin-top:8px;display:flex;flex-direction:column;gap:7px}
#g-sup .tour-stop{display:flex;align-items:center;gap:9px;background:#fff;border:1px solid var(--line);border-radius:11px;padding:9px 11px}
#g-sup .tour-stop.done{background:#f0faf4;border-color:#b7e6ca}
#g-sup .tour-stop .ts-n{flex:0 0 auto;width:22px;height:22px;border-radius:50%;background:var(--navy);color:#fff;font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center}
#g-sup .tour-stop.done .ts-n{background:var(--green)}
#g-sup .tour-stop .ts-main{flex:1;min-width:0;font-size:13.5px}
#g-sup .tour-stop .ts-sla{font-size:10.5px;font-weight:800;color:#a8660a;background:#fdf0dc;border-radius:99px;padding:1px 7px;margin-left:6px}
.post-sheet{position:fixed;inset:0;z-index:150;background:#eaf0f6;overflow-y:auto;padding:0 14px calc(30px + env(safe-area-inset-bottom))}
.post-sheet .ps-head{position:sticky;top:0;background:#eaf0f6;display:flex;align-items:center;gap:10px;padding:12px 0 8px;z-index:5;border-bottom:1px solid #e4eaf1}
.post-sheet .ps-body{padding:12px 0}
/* Mounted inside #g-sup (see openPost). 90 covers .snav(60)/.shead(50) but stays under .stoast(100) so toasts remain visible over the open sheet. */
#g-sup .post-sheet{z-index:90}
#g-sup svg.ic{width:15px;height:15px;vertical-align:-2px;flex:none}
#g-sup .sec svg.ic{width:13px;height:13px}
#g-sup .sbtn svg.ic,#g-sup .nb-nav svg.ic{width:14px;height:14px}
#g-sup .more-tile .ic3 svg.ic{width:26px;height:26px;vertical-align:0}
#g-sup .snav svg.ic{width:20px;height:20px}
#g-sup .ch-cat-h{display:flex;align-items:center;gap:8px;padding:10px 4px 6px;font-size:11px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);cursor:pointer;user-select:none}
#g-sup .ch-cat-h .n{font-family:var(--font-mono);font-weight:700;color:#8ea0b3;text-transform:none}
#g-sup .ch-cat-h .chev{margin-left:auto;transition:transform var(--t-fast) var(--ease);font-size:13px;color:#8ea0b3}
#g-sup .ch-cat-h.closed .chev{transform:rotate(-90deg)}
#g-sup .ch-cat-h .ub{background:#e11d2a;color:#fff;font-size:9px;font-weight:800;border-radius:99px;min-width:15px;height:15px;display:inline-flex;align-items:center;justify-content:center;padding:0 4px}
#g-sup .s-ts{font-family:var(--font-mono);font-size:11px;font-weight:400;color:#8593a5;white-space:nowrap}
#g-sup .s-pct{font-family:var(--font-mono);font-size:12px;font-weight:700;flex:none}
#g-sup .s-pct.ok{color:#0d7a45}#g-sup .s-pct.warn{color:#a8660a}
#g-sup .ch-ava{width:36px;height:36px;border-radius:10px;background:#e7eff7;color:#0a6bb0;font-family:var(--font-display);font-weight:700;font-size:12px;display:flex;align-items:center;justify-content:center;flex:none}
#g-sup .ch-ava .ic{width:17px;height:17px}
#g-sup .s-num{font-family:var(--font-display);font-weight:800;font-size:22px;color:var(--ink)}
#g-sup .s-lbl{font-size:10px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-top:2px}
/* Proof-of-visit photos on the Inspect form. Thumbnails are deliberately large enough to read the
   burned-in stamp on a phone — a supervisor has to be able to see the shot actually captured the
   post before they submit, not after someone queries the visit weeks later. */
#g-sup .in-shots{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}
#g-sup .in-shots:empty{display:none}
#g-sup .in-shot{position:relative;display:inline-block}
#g-sup .in-shot img{width:96px;height:96px;object-fit:cover;border-radius:10px;border:1px solid var(--line);display:block}
#g-sup .in-shot button{position:absolute;top:-6px;right:-6px;width:24px;height:24px;border-radius:50%;border:0;background:#c0182a;color:#fff;font-size:15px;line-height:1;cursor:pointer;box-shadow:0 2px 6px rgba(0,0,0,.3)}
#g-sup .in-foot{position:sticky;bottom:calc(64px + env(safe-area-inset-bottom));z-index:5;background:var(--bg);display:flex;gap:9px;padding:10px 0 4px;margin-top:12px}
#g-sup .in-foot .sbtn{padding:13px}
#g-sup .in-foot .sbtn.ghost{flex:1}

/* ---- Field report composer ------------------------------------------------------------------
   A native bottom-sheet, not a form dumped on a page. Mounted INSIDE #g-sup (never on <body>) so
   every scoped class above actually applies to it, and deliberately below .stoast's z-index of
   100: the sheet has to cover .snav (60), but the toast must still be able to land on top of it.
   Every measurement here is checked at 360x800 — the narrowest phone in the fleet. */
#g-sup .fr-sheet{z-index:90}
#g-sup .fr-sheet .ps-body{padding:14px 0 4px}
#g-sup .fr-sheet .field{margin-bottom:12px}            /* one rhythm down the whole sheet */
#g-sup .fr-sheet .field label{font-size:12px;font-weight:700;color:var(--muted);margin-bottom:6px}
#g-sup .fr-sheet textarea{line-height:1.45;resize:vertical;min-height:104px}
/* The entry point on the Inspect tab: a peer action, not a footnote. */
#g-sup .fr-alt{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
#g-sup .fr-alt .fr-alt-t{flex:1;min-width:148px;font-size:13px;color:var(--muted);line-height:1.35}
#g-sup .fr-alt .sbtn{flex:none;white-space:nowrap;display:inline-flex;align-items:center;gap:6px}
/* Same three-level segmented control the Inspect form uses, so severity looks and behaves
   identically on both screens — and only the SELECTED segment takes colour. Red is danger-only in
   this design system, and an officer asleep on post is exactly what it is reserved for. */
#g-sup .sev-seg button[data-sev="info"].on{background:var(--blue);border-color:var(--blue)}
#g-sup .sev-seg button[data-sev="concern"].on{background:var(--amber);border-color:var(--amber)}
#g-sup .sev-seg button[data-sev="serious"].on{background:var(--red);border-color:var(--red)}
/* Where-were-you switch: the same segmented control, but a plain choice rather than a severity, so
   the selected half takes the navy the app uses for "this is the current state" and never a status
   colour. Its GEOMETRY is overridden down in the house layer (see .loc-seg there) — the shared
   .sev-seg rule hard-codes three columns for the severity control.
   [data-loc] is carried, not decorative: it lifts this rule to the same specificity the severity
   rules use, so the dark skin's blanket `#g-sup .sev-seg button{background:var(--surface)}` further
   down cannot repaint the SELECTED half back to the unselected surface and leave the switch reading
   as though nothing were chosen. */
#g-sup .loc-seg button[data-loc].on{background:var(--navy);border-color:var(--navy);color:#fff}
#g-sup .loc-seg button:disabled{opacity:.45;cursor:not-allowed}
/* Photo grid: three square tiles per row with 8px gutters, so six photos read as two tidy rows
   on a 360px screen instead of a ragged wrap. */
#g-sup .fr-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:10px}
#g-sup .fr-tile{position:relative;aspect-ratio:1/1;border-radius:12px;overflow:hidden;background:#dbe3ec;display:block;padding:0;border:0}
#g-sup .fr-tile img{width:100%;height:100%;object-fit:cover;display:block}
#g-sup .fr-tile .fr-rm{position:absolute;top:5px;right:5px;width:24px;height:24px;border-radius:50%;border:0;background:rgba(8,18,30,.62);color:#fff;font-size:15px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}
#g-sup .fr-tile.fr-add{border:1.5px dashed #b3c2d2;background:#fff;color:var(--blue);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;cursor:pointer;font:800 12px/1 inherit}
#g-sup .fr-tile.fr-add:active{background:#f2f7fc}
#g-sup .fr-tile.fr-add svg.ic{width:24px;height:24px}
/* In-flight tile: the photo being stamped holds its own place in the grid with its own progress
   bar, so a six-photo batch fills the grid in front of you instead of hiding behind a spinner. */
#g-sup .fr-tile.pend{background:#e3eaf2}
#g-sup .fr-tile.pend i{position:absolute;left:0;bottom:0;height:3px;width:40%;background:var(--blue);border-radius:0 3px 3px 0;animation:frslide 1.1s ease-in-out infinite}
@keyframes frslide{0%{transform:translateX(-100%)}100%{transform:translateX(250%)}}
/* Tagged people: chips above, type-ahead below — the console composer's @-autocomplete idiom. */
#g-sup .fr-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}
#g-sup .fr-chips:empty{display:none}
#g-sup .fr-chip{display:inline-flex;align-items:center;gap:5px;background:#e2eefa;color:#0a5a94;border-radius:99px;padding:5px 5px 5px 11px;font-size:12px;font-weight:700;max-width:100%}
#g-sup .fr-chip button{border:0;background:rgba(3,43,73,.13);color:var(--navy);width:19px;height:19px;border-radius:50%;font-size:13px;line-height:1;cursor:pointer;flex:none;display:flex;align-items:center;justify-content:center;padding:0}
#g-sup .fr-pick{position:relative}
#g-sup .fr-pop{position:absolute;left:0;right:0;top:calc(100% + 5px);z-index:20;background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:0 14px 34px rgba(10,18,38,.22);max-height:44vh;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:5px}
#g-sup .fr-prow{display:flex;align-items:center;gap:9px;width:100%;text-align:left;background:none;border:0;border-radius:9px;padding:10px;font:600 14px/1.3 inherit;color:var(--ink);cursor:pointer}
#g-sup .fr-prow.on,#g-sup .fr-prow:hover,#g-sup .fr-prow:active{background:#eef4fb}
#g-sup .fr-prow .fr-pn{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#g-sup .fr-prow .fr-ps{font-size:10px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);flex:none}
#g-sup .fr-pnone{padding:13px 10px;font-size:13px;color:var(--muted)}
/* ⚠ align-items and the input's margin-top are BOTH overridden at the foot of this file — see
   THE 44px FLOOR IN FIELD MODE'S FORMS. flex-start + the 1px nudge lined the box up with the first
   line of text; the floor block centres the checkbox column instead, so the 44px square around it
   is inside the card no matter how long the copy is. Editing them here changes nothing on its own. */
#g-sup .fr-toggle{display:flex;align-items:flex-start;gap:10px;cursor:pointer;background:#fff;border:1px solid var(--line);border-radius:12px;padding:12px 13px;margin-bottom:12px}
#g-sup .fr-toggle input{width:19px;height:19px;accent-color:var(--navy);flex:none;margin-top:1px}
#g-sup .fr-toggle b{display:block;font-size:13.5px;font-weight:700}
#g-sup .fr-toggle small{display:block;font-size:11.5px;color:var(--muted);margin-top:2px}
/* Hints and errors are cards with an icon and a sentence — never a bare grey line of text. */
#g-sup .fr-note{display:flex;align-items:flex-start;gap:8px;border-radius:11px;padding:10px 12px;font-size:12.5px;line-height:1.4;margin-top:8px}
#g-sup .fr-note svg.ic{width:15px;height:15px;flex:none;margin-top:1px}
#g-sup .fr-note.info{background:#eef4fb;color:#3a5064}
#g-sup .fr-note.info svg.ic{color:var(--blue)}
#g-sup .fr-note.warn{background:#fdf0dc;color:#8a5405}
#g-sup .fr-note.warn svg.ic{color:#a8660a}
/* Primary action: full width, pinned to the bottom of the sheet, above the safe area. */
#g-sup .fr-foot{position:sticky;bottom:0;z-index:6;background:linear-gradient(180deg,rgba(234,240,246,0),var(--bg) 22%);padding:14px 0 calc(10px + env(safe-area-inset-bottom));margin-top:14px}
#g-sup .fr-foot .sbtn{padding:15px;font-size:15px;border-radius:13px;display:flex;align-items:center;justify-content:center;gap:9px}
#g-sup .fr-spin{width:15px;height:15px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:frspin .7s linear infinite;flex:none}
/* The label on the supervisor's own thread view, where their post lands seconds after they send. */
/* display:flex + fit-content, not inline-flex: .bub is white-space:pre-wrap, so the chip has to be
   a block-level box or the report text runs on straight after it. */
#g-sup .fr-tag{display:flex;width:fit-content;align-items:center;gap:5px;background:#e2eefa;color:#0a5a94;border-radius:99px;padding:3px 9px 3px 8px;font-size:10px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;margin:0 0 5px}
#g-sup .fr-tag svg.ic{width:12px;height:12px}
#g-sup .bub.me .fr-tag{background:rgba(255,255,255,.22);color:#fff}
@keyframes frspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){#g-sup .fr-spin,#g-sup .fr-tile.pend i{animation:none}}

/* ================================================================================================
   MAP TAB + POST DETAILS — task #240 (owner, 2026-07-30)
   Three complaints: the map still chose the order and stamped distances; there was no way to search
   for a post ON the map; the details view was "still legacy". Every measurement below is checked at
   360x800, the narrowest phone in the fleet, in both themes.
   ------------------------------------------------------------------------------------------------
   Surface tokens, declared here rather than edited into the block at the top of this file so the
   dark override at the bottom has one place to flip. Later rule, same specificity → this wins, and
   custom properties merge rather than replace.
   ============================================================================================== */
#g-sup{--surface:#fff;--surface-2:#eef2f8;--surface-3:#eef4fb;--sunk:#f5f8fc}

/* ---- Search, floating over the map ------------------------------------------------------------
   .ms-wrap deliberately creates a stacking context (position + z-index:0). Without it, .ms-bar's
   z-index of 900 — which it needs to clear Leaflet's own controls at 800 — would also paint over
   the sticky .shead (50) and the fixed .snav (60) as the page scrolls. Contained here, it beats
   Leaflet and still passes under the app's own chrome. */
#g-sup .ms-wrap{position:relative;z-index:0}
#g-sup .ms-bar{position:absolute;left:10px;right:10px;top:10px;z-index:900}
#g-sup .ms-field{display:flex;align-items:center;gap:8px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:0 6px 20px rgba(10,18,38,.20);padding:0 10px}
#g-sup .ms-field > svg.ic{width:17px;height:17px;color:var(--muted);flex:none}
/* 16px is not a taste call: anything smaller and iOS/Android zoom the page on focus, which throws
   the map off screen the moment a supervisor starts typing. */
/* border-radius with no border: guard.css:484 gives every focused input a 3px box-shadow ring, and
   on a square-cornered field inside a rounded pill that ring reads as a stray blue rectangle. */
#g-sup .ms-in{flex:1;min-width:0;border:0;border-radius:9px;background:none;padding:12px 4px;font:600 16px/1.1 inherit;color:var(--ink)}
#g-sup .ms-in:focus{outline:none}
#g-sup .ms-in::placeholder{color:var(--muted);font-weight:500}
#g-sup .ms-x{flex:none;width:30px;height:30px;border:0;border-radius:50%;background:var(--surface-2);color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}
#g-sup .ms-x svg.ic{width:14px;height:14px}
#g-sup .ms-res{margin-top:7px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:0 14px 34px rgba(10,18,38,.26);max-height:min(44vh,280px);overflow-y:auto;-webkit-overflow-scrolling:touch;padding:5px}
#g-sup .ms-item{display:flex;align-items:stretch;gap:3px}
#g-sup .ms-item + .ms-item{border-top:1px solid var(--line)}
#g-sup .ms-row{flex:1;min-width:0;display:flex;align-items:center;gap:9px;background:none;border:0;border-radius:9px;padding:10px 8px;text-align:left;cursor:pointer;font:inherit;color:var(--ink)}
#g-sup .ms-row:active{background:var(--surface-3)}
#g-sup .ms-dot{flex:none;width:9px;height:9px;border-radius:50%;background:#b9c1cf}
#g-sup .ms-dot.covered{background:var(--green)}
#g-sup .ms-dot.uncovered{background:var(--red);box-shadow:0 0 0 3px rgba(225,29,42,.18)}
#g-sup .ms-main{flex:1;min-width:0;display:block}
#g-sup .ms-main b{display:block;font-size:14px;font-weight:800;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .ms-main small{display:block;font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
#g-sup .ms-go{flex:none;color:var(--blue)}
#g-sup .ms-det{flex:none;width:42px;border:0;border-left:1px solid var(--line);background:none;color:var(--blue);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}
#g-sup .ms-det:active{background:var(--surface-3)}
#g-sup .ms-none,#g-sup .ms-more{padding:12px 10px;font-size:12.5px;color:var(--muted);line-height:1.45}
#g-sup .ms-none b{display:block;color:var(--ink);font-size:13.5px;margin-bottom:2px}
#g-sup .ms-more{border-top:1px solid var(--line);text-align:center}
/* Losing the tile CDN is not the same as losing the tab — the list, distances, route and search all
   still work, so say that instead of showing one grey line and taking the round with it. */
#g-sup .ms-nomap{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;text-align:center;padding:22px 26px;background:var(--sunk);border-radius:14px;color:var(--muted)}
#g-sup .ms-nomap svg.ic{width:24px;height:24px;opacity:.5}
#g-sup .ms-nomap b{color:var(--ink);font-size:14px}
#g-sup .ms-nomap span{font-size:12px;line-height:1.45;max-width:250px}

/* ---- The list order is the supervisor's ------------------------------------------------------ */
/* Wraps rather than scrolls, unlike the chat filter row this borrows its look from: there are only
   ever four of these and at 360px the fourth one hangs off the edge — an order they cannot see is an
   order they do not have. */
#g-sup .nb-ord{flex-wrap:wrap;overflow:visible;padding-bottom:8px;margin-bottom:0}
#g-sup .nb-ordl{text-transform:none;letter-spacing:0;font-weight:700;color:var(--blue)}
#g-sup .nb-hint{font-size:11.5px;color:var(--muted);margin:0 2px 9px}
#g-sup .nb-filter{display:flex;align-items:center;gap:7px;background:var(--surface-3);border-radius:10px;padding:8px 11px;margin-bottom:9px;font-size:12.5px;color:#3a5064}
#g-sup .nb-filter svg.ic{width:14px;height:14px;color:var(--blue);flex:none}
#g-sup .nb-filter b{font-weight:800}
#g-sup .nb-clear{margin-left:auto;flex:none;border:0;background:none;color:var(--blue);font:800 12.5px inherit;cursor:pointer;padding:2px 4px}
#g-sup .nb-det{color:var(--blue);font-weight:700}
/* At 360px the row was: 34px + button + 52px distance + a 74px "◎ Go" button + padding, which left
   the site NAME about 118px and wrapped "Bayfront Distribution" onto two lines. The glyph alone is
   the same navigate icon used everywhere else in this app, and the label comes back on a wider phone.
   The distance keeps its own prominent column — the owner asked twice for that number to be visible. */
@media (max-width:400px){
  #g-sup .nb-nav .nb-go{display:none}
  #g-sup .nb-nav{padding:10px 12px}
}

/* ---- The pin's own mini card ----------------------------------------------------------------- */
#g-sup .mpop{min-width:172px;font-size:12.5px}
#g-sup .mpop .mp-t{font-weight:800;font-size:14px;margin-bottom:3px;color:var(--ink)}
#g-sup .mpop .mp-m{color:var(--muted);line-height:1.4}
#g-sup .mpop .mp-ok{color:#0d7a45}#g-sup .mpop .mp-bad{color:#c0182a}#g-sup .mpop .mp-idle{color:var(--muted);font-weight:700}
#g-sup .mpop .mp-a{display:flex;flex-direction:column;gap:5px;margin-top:8px;padding-top:7px;border-top:1px solid var(--line)}
#g-sup .mpop .mp-a a{display:flex;align-items:center;gap:6px;font-weight:800;font-size:12.5px}

/* ---- Post details sheet ----------------------------------------------------------------------
   Mounted inside #g-sup (see supervisor.js), so it needs a z-index under .stoast's 100 — the sheet
   must cover .snav (60), and a toast fired from inside the sheet must still land on top of it. The
   unscoped .post-sheet rule above sets 150 as a <body> fallback; id+class beats it. */
#g-sup .ps-sheet{z-index:90}
#g-sup .ps-sheet .ps-body{padding:12px 0 4px}
#g-sup .ps-skel{display:flex;flex-direction:column;gap:9px;padding:4px 0}
#g-sup .ps-skel i{display:block;border-radius:12px;background:linear-gradient(90deg,var(--surface-2),var(--sunk),var(--surface-2));background-size:220% 100%;animation:psshim 1.2s ease-in-out infinite}
#g-sup .ps-skel i:nth-child(1){height:84px}
#g-sup .ps-skel i:nth-child(2){height:70px}
#g-sup .ps-skel i:nth-child(3){height:132px}
@keyframes psshim{0%{background-position:120% 0}100%{background-position:-120% 0}}
#g-sup .ps-hero{background:var(--surface);border:1px solid var(--line);border-radius:15px;padding:13px 14px}
#g-sup .ps-htop{display:flex;align-items:flex-start;gap:9px}
#g-sup .ps-name{flex:1;min-width:0;font-family:var(--font-display);font-weight:800;font-size:19px;line-height:1.2;color:var(--ink)}
#g-sup .ps-pill{flex:none;font-size:10.5px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;border-radius:99px;padding:4px 9px;white-space:nowrap;margin-top:2px}
#g-sup .ps-pill.ok{background:#e4f6ec;color:#0d7a45}
#g-sup .ps-pill.bad{background:var(--red);color:#fff}
#g-sup .ps-pill.idle{background:var(--surface-2);color:var(--muted)}
#g-sup .ps-addr{display:flex;align-items:flex-start;gap:6px;margin-top:7px;font-size:13px;color:#3a5064;line-height:1.4}
#g-sup .ps-addr svg.ic{width:14px;height:14px;color:var(--muted);flex:none;margin-top:2px}
#g-sup .ps-facts{display:flex;flex-wrap:wrap;gap:5px 6px;margin-top:9px}
#g-sup .ps-facts > span{font-size:11.5px;font-weight:700;color:var(--muted);background:var(--surface-2);border-radius:99px;padding:3px 9px}
#g-sup .ps-facts i.w{font-style:normal;color:#a8660a}
#g-sup .ps-facts > span:has(i.w){background:#fdf0dc}
/* A live BOLO is the one thing on this sheet that must never be a section you scroll to. */
#g-sup .ps-bolo{display:flex;align-items:flex-start;gap:9px;background:#fdeaea;border:1.5px solid #f3c3c3;border-radius:13px;padding:11px 12px;margin-top:9px}
#g-sup .ps-bolo svg.ic{width:17px;height:17px;color:#c0182a;flex:none;margin-top:1px}
#g-sup .ps-bolo b{display:block;font-size:12.5px;font-weight:800;color:#c0182a;letter-spacing:.03em}
#g-sup .ps-bolo span{display:block;font-size:12.5px;color:#7e2b31;line-height:1.4;margin-top:2px}
/* Three per row, wrapping — never a horizontal scroller. An action a supervisor cannot see is an
   action they do not have, and at 360px six of these will not fit on one line. */
#g-sup .ps-acts{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:11px 0 3px}
#g-sup .ps-act{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;min-height:62px;background:var(--surface);border:1px solid var(--line);border-radius:13px;padding:9px 6px;font:800 11px/1.2 inherit;color:var(--blue);text-align:center;text-decoration:none;cursor:pointer}
#g-sup .ps-act svg.ic{width:19px;height:19px}
#g-sup .ps-act span{display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#g-sup .ps-act.pri{background:var(--green);border-color:var(--green);color:#fff}
#g-sup .ps-act.on{background:var(--blue);border-color:var(--blue);color:#fff}
/* :active was scale(.97) here; it is now the shared house rule at the foot of this file, which is
   the same scale plus the token-driven dim. Measured before removing: .ps-act was the one control
   matching TWO :active rules. */
#g-sup .ps-stats{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin:11px 0 3px}
#g-sup .ps-stat{background:var(--surface);border:1px solid var(--line);border-left-width:4px;border-left-color:#b9c1cf;border-radius:12px;padding:9px 12px}
#g-sup .ps-stat.ok{border-left-color:var(--green)}
#g-sup .ps-stat.bad{border-left-color:var(--red)}
#g-sup .ps-stat .s-num{font-size:20px}
/* People and shifts as sub-rows: one line of identity, one of context, and the two taps that matter
   pinned right. 40px targets — this gets used one-handed, at night, in a car park. */
#g-sup .ps-row{display:flex;align-items:center;gap:9px;background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:9px 11px;margin-bottom:7px}
#g-sup .ps-row.open{background:var(--sunk);border-style:dashed}
#g-sup .ps-ava{flex:none;width:38px;height:38px;border-radius:11px;background:var(--surface-3);color:var(--blue);font-family:var(--font-display);font-weight:700;font-size:12.5px;display:flex;align-items:center;justify-content:center}
#g-sup .ps-ava.on{background:#e4f6ec;color:#0d7a45;box-shadow:inset 0 0 0 1.5px rgba(15,157,88,.45)}
/* 64px, not 52: the roster clock went 12-hour, so the widest line is "10:00 AM" (8 mono glyphs)
   rather than "10:00" (5). At 52px it overflowed a flex:none box onto the name beside it. */
#g-sup .ps-time{flex:none;width:64px;font-family:var(--font-mono);font-size:11.5px;font-weight:700;color:var(--ink);line-height:1.35;text-align:center}
#g-sup .ps-time i{display:block;font-style:normal;font-weight:400;color:var(--muted)}
#g-sup .ps-rm{flex:1;min-width:0}
#g-sup .ps-rm b{display:block;font-size:13.5px;font-weight:800;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .ps-rm .meta{font-size:11.5px;color:var(--muted);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .ps-on{color:#0d7a45}
#g-sup .ps-b{flex:none;width:40px;height:40px;border-radius:11px;background:var(--surface-3);color:var(--blue);border:0;display:flex;align-items:center;justify-content:center;text-decoration:none}
#g-sup .ps-b.call{background:var(--green);color:#fff}
#g-sup .ps-b svg.ic{width:16px;height:16px}
#g-sup .ps-nop{flex:none;font-size:10.5px;font-weight:700;color:var(--muted);text-align:right;max-width:64px;line-height:1.25}
/* Empty states are cards with a sentence, never a bare grey line. */
#g-sup .ps-empty{background:var(--sunk);border:1px dashed var(--line);border-radius:12px;padding:14px 15px;text-align:center;margin-bottom:7px}
#g-sup .ps-empty b{display:block;font-size:13.5px;font-weight:800;color:var(--ink)}
#g-sup .ps-empty span{display:block;font-size:12px;color:var(--muted);line-height:1.45;margin-top:3px}
/* The record, folded. 48 history rows plus 4,000 characters of post orders unfolded on a phone is
   not a detail view, it is a scroll — so each section states its count and opens on request. */
#g-sup .ps-fold{background:var(--surface);border:1px solid var(--line);border-radius:12px;margin-bottom:7px;overflow:hidden}
#g-sup .ps-fh{display:flex;align-items:center;gap:9px;width:100%;background:none;border:0;padding:12px 12px;font:800 13.5px inherit;color:var(--ink);text-align:left;cursor:pointer}
#g-sup .ps-fh b{flex:1;min-width:0;font-weight:800;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .ps-fi{flex:none;color:var(--muted);display:flex}
#g-sup .ps-fn{flex:none;font-family:var(--font-mono);font-size:11px;font-weight:700;color:var(--muted);background:var(--surface-2);border-radius:99px;padding:2px 8px}
#g-sup .ps-fv{flex:none;font-size:10px;font-weight:800;color:var(--blue);background:var(--surface-3);border-radius:99px;padding:2px 7px}
#g-sup .ps-fb2{flex:none;font-size:10px;font-weight:800;color:#fff;background:var(--red);border-radius:99px;padding:2px 7px;letter-spacing:.03em}
#g-sup .ps-chev{flex:none;color:#8ea0b3;font-size:13px;transition:transform var(--t-fast) var(--ease)}
#g-sup .ps-fh.open .ps-chev{transform:rotate(180deg)}
#g-sup .ps-fb{padding:2px 11px 9px;border-top:1px solid var(--line)}
#g-sup .ps-fb .scard{margin-bottom:7px}
#g-sup .ps-fb .scard:last-child{margin-bottom:2px}
/* overflow-wrap:anywhere — post orders, site notes and visit notes have no length ceiling (owner
   order, 2026-08-13), and one unbroken run of characters would otherwise widen the sheet. */
#g-sup .ps-long{white-space:pre-wrap;overflow-wrap:anywhere;font-size:13px;line-height:1.5;color:#3a5064;padding:9px 0 2px}
@media (prefers-reduced-motion:reduce){#g-sup .ps-skel i{animation:none}#g-sup .ps-act:active{transform:none}}

/* ================================================================================================
   DARK THEME
   guard.js sets [data-theme="dark"] on <html> and guard.css carries a full dark skin — but #g-sup
   declared its tokens light-only, so the Ops app stayed a bright island inside a dark officer app.
   Flip the tokens, then repaint the places that hardcode a light value. Purely additive: not one
   light-theme rule above is modified.
   Deliberately NOT inverted: the map tiles, .map-pin-txt, .sdot and .ssos — those sit on OSM
   imagery, which is light in both themes, and a filtered tile layer reads worse than an honest one.
   ============================================================================================== */
[data-theme="dark"] #g-sup{--line:#26303f;--muted:#93a3b7;--bg:#0f1520;--ink:#e6edf7;--surface:#161d2b;--surface-2:#1d2635;--surface-3:#1a2740;--sunk:#131a26}
/* ⚠ THE .gcf-ov TWIN NEEDS THE TOKENS, NOT JUST THE SELECTORS. Every .sp-pick rule in this file is
   doubled onto .gcf-ov (see the note at the top) because the task composer's sheet is appended to
   document.body, where #g-sup-scoped rules reach nothing. Doubling the SELECTOR is only half of it:
   the dark rules below paint with var(--surface), and #g-sup above is the only scope in the house
   that declares --surface at all — so on a body-appended .gcf-ov it resolved to nothing, the whole
   `background:var(--surface)` declaration dropped out, and the type-ahead popup rendered TRANSPARENT
   over the dark sheet behind it. Declared here in the same shape #g-sup declares them, so the var()s
   below reach both doors. Only the --surface family: --line, --muted and --ink are on guard.css's
   own :root in BOTH themes, which is why the light twins at the top of this file have always worked
   and why redeclaring them here would change the rest of the sheet's skin for nothing. */
[data-theme="dark"] .gcf-ov{--surface:#161d2b;--surface-2:#1d2635;--surface-3:#1a2740;--sunk:#131a26}
[data-theme="dark"] #g-sup a,[data-theme="dark"] #g-sup .nb-det,[data-theme="dark"] #g-sup .nb-ordl{color:#6fb2e8}
[data-theme="dark"] #g-sup .scard,[data-theme="dark"] #g-sup .sos-card,[data-theme="dark"] #g-sup .nb-row,
[data-theme="dark"] #g-sup .ch-row,[data-theme="dark"] #g-sup .gear-row,[data-theme="dark"] #g-sup .more-tile,
[data-theme="dark"] #g-sup .tour-stop,[data-theme="dark"] #g-sup .rub,[data-theme="dark"] #g-sup .bub.them,
[data-theme="dark"] #g-sup .th-back,[data-theme="dark"] #g-sup .fr-toggle,[data-theme="dark"] #g-sup .fr-pop,
[data-theme="dark"] #g-sup .sp-pick-pop,[data-theme="dark"] #g-sup .sp-pick-in,[data-theme="dark"] #g-sup .nb-add,
[data-theme="dark"] .gcf-ov .sp-pick-pop,[data-theme="dark"] .gcf-ov .sp-pick-in,
[data-theme="dark"] .gcf-ov .sp-pick-grp,[data-theme="dark"] #g-sup .sp-pick-grp,
[data-theme="dark"] #g-sup .ch-search,[data-theme="dark"] #g-sup .nb-search,[data-theme="dark"] #g-sup .th-compose input,
[data-theme="dark"] #g-sup .field select,[data-theme="dark"] #g-sup .field input,[data-theme="dark"] #g-sup .field textarea,
[data-theme="dark"] #g-sup .ui-row,[data-theme="dark"] #g-sup .ui-n>input,
[data-theme="dark"] #g-sup .rub-seg button,[data-theme="dark"] #g-sup .sev-seg button{background:var(--surface);color:var(--ink)}
/* .ui-total and .ui-ack are painted on --sunk, which the dark token block above already redefines —
   but --sunk is DARKER than --surface, so the row cards sitting next to them stay the raised thing
   and the two summary panels stay the recessed one, the same way round as in light. */
[data-theme="dark"] #g-sup .ui-del{background:#243044;color:#dbe6f5;border-color:var(--line)}
/* The locked price box has to stay READ-ONLY-looking in dark too — it inherits .ui-n>input's dark
   surface from the rule above, which would make it identical to an editable one. */
[data-theme="dark"] #g-sup .ui-n>input.locked{background:var(--sunk);color:var(--muted)}
[data-theme="dark"] #g-sup .ui-why{color:#5fd398}
/* --navy is #032b49: on the dark #161d2b surface the selected half would read as an unselected one
   with a slightly different black. navy-2 is the same colour family, legible against it. */
[data-theme="dark"] #g-sup .loc-seg button[data-loc].on{background:var(--navy-2);border-color:var(--navy-2);color:#fff}
[data-theme="dark"] #g-sup .snav{background:#111826}
[data-theme="dark"] #g-sup .scard.bad,[data-theme="dark"] #g-sup .nb-row.uncovered{background:#2a1719}
[data-theme="dark"] #g-sup .scard.warn{background:#2a2214}
[data-theme="dark"] #g-sup .sbtn.ghost{background:#243044;color:#dbe6f5}
[data-theme="dark"] #g-sup .ch-tab,[data-theme="dark"] #g-sup .ch-cat,[data-theme="dark"] #g-sup .ps-fn{background:var(--surface-2)}
/* The light-theme active chip gradient (#005080→#0a6bb0) is DARKER than the dark-theme inactive
   chips, so the selected order read as the dimmest one. Brighten it so "chosen" still looks chosen. */
[data-theme="dark"] #g-sup .ch-tab.on{background:linear-gradient(135deg,#0a6bb0,#1a86d0);color:#fff;border-color:transparent}
[data-theme="dark"] #g-sup .reg-b,[data-theme="dark"] #g-sup .fr-note.info,[data-theme="dark"] #g-sup .nb-filter,
[data-theme="dark"] #g-sup .ps-b,[data-theme="dark"] #g-sup .ps-ava,[data-theme="dark"] #g-sup .ps-fv{background:var(--surface-3);color:#8fc3f0}
/* Must come after the .ps-b rule above, which is specific enough to have eaten the green Call
   button in dark mode (measured — it rendered as a second, identical-looking Text button). */
[data-theme="dark"] #g-sup .ps-b.call,[data-theme="dark"] #g-sup .reg-b.call{background:var(--green);color:#fff}
/* .nb-dist is var(--navy) — invisible on a dark card. */
[data-theme="dark"] #g-sup .nb-dist,[data-theme="dark"] #g-sup .ps-time{color:var(--ink)}
[data-theme="dark"] #g-sup .nb-filter{color:#b7c6d8}
[data-theme="dark"] #g-sup .sp-pick-row,[data-theme="dark"] .gcf-ov .sp-pick-row{color:#9dc6ea}
/* AFTER the surface/ink rule above, which lists .sp-pick-grp for its BACKGROUND — a sticky heading
   with no background lets the rows scroll through it. Only the colour is taken back here. */
[data-theme="dark"] .gcf-ov .sp-pick-grp,[data-theme="dark"] #g-sup .sp-pick-grp{color:var(--muted)}
[data-theme="dark"] .gcf-ov .sp-pick-row:active,[data-theme="dark"] .gcf-ov .sp-pick-row:hover{background:#1f2c40}
[data-theme="dark"] #g-sup .sp-pick-row:active,[data-theme="dark"] #g-sup .sp-pick-row:hover,
[data-theme="dark"] #g-sup .fr-prow.on,[data-theme="dark"] #g-sup .fr-prow:hover,[data-theme="dark"] #g-sup .ms-row:active{background:#1f2c40}
[data-theme="dark"] #g-sup .ch-ava{background:#1d2b3e;color:#7fb6e8}
[data-theme="dark"] #g-sup .rt-wrap{border:1px solid #24405c}
[data-theme="dark"] #g-sup .tour-stop.done{background:#152a1f;border-color:#2c5f42}
[data-theme="dark"] #g-sup .fr-tile{background:#222c3b}
[data-theme="dark"] #g-sup .fr-tile.fr-add{background:var(--surface);border-color:#38465c}
[data-theme="dark"] #g-sup .ps-addr,[data-theme="dark"] #g-sup .ps-long,[data-theme="dark"] #g-sup .fr-note.info{color:#b7c6d8}
[data-theme="dark"] #g-sup .ps-pill.ok{background:#14351f;color:#5fd398}
[data-theme="dark"] #g-sup .ps-pill.idle{background:var(--surface-2);color:var(--muted)}
[data-theme="dark"] #g-sup .ps-ava.on{background:#14351f;color:#5fd398}
[data-theme="dark"] #g-sup .ps-on{color:#5fd398}
[data-theme="dark"] #g-sup .ps-facts i.w{color:#e8b45c}
[data-theme="dark"] #g-sup .ps-facts > span:has(i.w){background:#2a2214}
[data-theme="dark"] #g-sup .ps-bolo{background:#2a1719;border-color:#5e2a2f}
[data-theme="dark"] #g-sup .ps-bolo svg.ic,[data-theme="dark"] #g-sup .ps-bolo b{color:#ff8e97}
[data-theme="dark"] #g-sup .ps-bolo span{color:#e5b8bc}
[data-theme="dark"] #g-sup .nb-due,[data-theme="dark"] #g-sup .mpop .mp-bad{color:#ff8e97}
[data-theme="dark"] #g-sup .mpop .mp-ok{color:#5fd398}
[data-theme="dark"] #g-sup .s-pct.ok{color:#5fd398}[data-theme="dark"] #g-sup .s-pct.warn{color:#e8b45c}
[data-theme="dark"] #g-sup .tag.brk{background:#2a2214;color:#e8b45c}
[data-theme="dark"] #g-sup .tag.geo{background:#2a1719;color:#ff8e97}
[data-theme="dark"] #g-sup .rub-item{border-bottom-color:#222b39}
/* .post-sheet's own frame is unscoped (it predates the #g-sup move) — theme it the same way. */
[data-theme="dark"] .post-sheet{background:#0f1520}
[data-theme="dark"] .post-sheet .ps-head{background:#0f1520;border-bottom-color:#26303f}

/* ================================================================================================
   INSPECT — the site-visit form, rebuilt 2026-07-30
   Everything below is TOKEN-driven (--surface / --sunk / --line / --ink / --muted, declared for
   light at line 295 and for dark at line 458) so neither theme needs a rule of its own. That is the
   whole point: the defect this block replaces was an INLINE `background:#fff` on the officers list,
   and an inline style outranks every [data-theme="dark"] selector in this file — the list rendered
   as a stark white box with --ink (#e6edf7) text on it, measured live at 360x800.
   Two status inks are the only new tokens; both themes need a red and an amber that read on their
   own background, and the dark values are the ones already proven elsewhere in this file.
   ============================================================================================== */
#g-sup{--danger-ink:#c0182a;--amber-ink:#a8660a}
[data-theme="dark"] #g-sup{--danger-ink:#ff8e97;--amber-ink:#e8b45c}

/* --- section cards ---------------------------------------------------------------------------- */
#g-sup .in-sec{margin:0 0 16px}
#g-sup .in-sec-h{display:flex;align-items:center;gap:7px;margin:0 0 8px;font-size:12px;font-weight:800;
  text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
#g-sup .in-sec-h svg.ic{width:13px;height:13px}
#g-sup .in-sec-sub{margin:0 0 9px;font-size:12.5px;line-height:1.45;color:var(--muted)}
#g-sup .in-sub-tail{margin:8px 0 0}
/* the count chip on a section header — "3 selected", "2 failed", "1 photo" */
#g-sup .in-count{margin-left:auto;text-transform:none;letter-spacing:0;font-family:var(--font-mono);
  font-size:11px;font-weight:700;color:var(--muted);background:var(--surface-2);border-radius:99px;padding:2px 9px}
#g-sup .in-count.on{background:var(--surface-3);color:var(--blue)}
#g-sup .in-count.bad{background:var(--surface-2);color:var(--danger-ink)}

/* --- officers checked --------------------------------------------------------------------------
   326 active officers in the seeded fleet. The list renders a capped slice and everything already
   ticked, and the search drives the rest — see paintGuards() in supervisor.js. */
#g-sup .in-chk{background:var(--surface);border:1px solid var(--line);border-radius:14px;overflow:hidden}
#g-sup .in-chk-top{display:flex;align-items:center;gap:8px;padding:9px 10px;background:var(--sunk);border-bottom:1px solid var(--line)}
#g-sup .in-chk-search{flex:1;min-width:0;display:flex;align-items:center;gap:8px;color:var(--muted);
  background:var(--surface);border:1px solid var(--line);border-radius:11px;padding:0 11px}
#g-sup .in-chk-search svg.ic{flex:none}
/* 16px, like every other field in the app: below it iOS/Android zoom the page on focus. */
#g-sup .in-chk-search input{flex:1;min-width:0;width:100%;border:0;outline:none;background:none;color:var(--ink);
  font-family:inherit;font-size:16px;min-height:var(--tap,44px);padding:0}
#g-sup .in-chk-search input::placeholder{color:var(--muted);opacity:.9}
#g-sup .in-chk-search input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
#g-sup .in-chk-clear{flex:none;min-height:var(--tap,44px);padding:0 13px;border:1px solid var(--line);
  border-radius:11px;background:var(--surface);color:var(--blue);font-family:inherit;font-size:12.5px;font-weight:800;cursor:pointer}
#g-sup .in-chk-list{max-height:min(46vh,300px);overflow-y:auto;-webkit-overflow-scrolling:touch}
#g-sup .in-chk-row{display:flex;align-items:center;gap:11px;min-height:var(--tap,44px);padding:5px 12px;
  font-size:14.5px;color:var(--ink);cursor:pointer;border-bottom:1px solid var(--line)}
#g-sup .in-chk-row:last-child{border-bottom:0}
#g-sup .in-chk-row.on{background:var(--surface-3)}
#g-sup .in-chk-nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* appearance:none, or Android paints the OS checkbox — which on a dark surface is the dark square
   the owner's screenshot shows. The whole 44px row is the hit target because it is a <label>. */
#g-sup .in-chk-row input[type=checkbox]{appearance:none;-webkit-appearance:none;flex:none;position:relative;
  width:22px;height:22px;margin:0;border:2px solid var(--line);border-radius:7px;background:var(--sunk);cursor:pointer;
  transition:border-color var(--t-fast) var(--ease)}
#g-sup .in-chk-row input[type=checkbox]:checked{background:var(--blue);border-color:var(--blue)}
#g-sup .in-chk-row input[type=checkbox]:checked::after{content:"";position:absolute;left:6px;top:2px;
  width:5px;height:10px;border:solid #fff;border-width:0 2.6px 2.6px 0;transform:rotate(45deg)}
#g-sup .in-chk-row input[type=checkbox]:focus-visible{outline:2px solid var(--blue-bright);outline-offset:2px}
#g-sup .in-chk-more,#g-sup .in-chk-none{padding:11px 13px;font-size:12.5px;color:var(--muted);
  background:var(--sunk);border-top:1px solid var(--line)}
#g-sup .in-chk-more:empty{display:none}
#g-sup .in-chk-none{border-top:0}

/* --- the rubric ---------------------------------------------------------------------------------
   ONE row component. The old row was `flex + justify-content:space-between + flex-wrap`, so a short
   label kept its pills on the right and a long one ("Site secure (doors, gates, lights)") wrapped
   them onto their own LEFT-aligned line — measured: rows 1-3 seg at x=185, rows 4-5 at x=28. Here
   the label and the control are each their own full-width band below 480px, so label length cannot
   change the layout; above 480px they sit side by side, still on one shared rule. */
#g-sup .rub{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:2px 13px;margin:0}
#g-sup .rub-item{display:flex;flex-wrap:wrap;align-items:center;gap:9px 10px;padding:12px 0;
  border-bottom:1px solid var(--line);font-size:14px}
#g-sup .rub-item:last-child{border-bottom:0}
#g-sup .rub-lbl{flex:1 1 100%;min-width:0;font-weight:600;line-height:1.35;color:var(--ink)}
#g-sup .rub-seg{flex:1 1 100%;display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
@media (min-width:480px){
  #g-sup .rub-lbl{flex:1 1 auto}
  #g-sup .rub-seg{flex:0 0 252px;margin-left:auto}
}
#g-sup .rub-b{min-height:var(--tap,44px);display:inline-flex;align-items:center;justify-content:center;gap:5px;
  padding:0 6px;border:1px solid var(--line);border-radius:11px;background:var(--sunk);color:var(--muted);
  font-family:inherit;font-size:12.5px;font-weight:800;cursor:pointer;
  /* border + colour only. `background` in a transition made a theme flip animate every control, and
     in a throttled WebView the animation never runs and the control sits on the wrong colour. */
  transition:border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
#g-sup .rub-b svg.ic{width:14px;height:14px}
#g-sup .rub-b.n svg.ic{display:none}
#g-sup .rub-b:focus-visible{outline:2px solid var(--blue-bright);outline-offset:2px}
#g-sup .rub-b.on{color:#fff;border-color:transparent;box-shadow:0 2px 8px rgba(8,16,28,.18)}
#g-sup .rub-b.p.on{background:var(--green)}
#g-sup .rub-b.f.on{background:var(--red)}
#g-sup .rub-b.n.on{background:var(--muted)}
/* A failed item is the reason the visit spawns a follow-up task — it has to be findable at a glance
   rather than sitting in an identical row. */
#g-sup .rub-item[data-state="fail"] .rub-lbl{color:var(--danger-ink)}
#g-sup .rub-item[data-state="fail"]{box-shadow:inset 3px 0 0 -1px var(--red)}

/* --- severity: same 3-up geometry as the rubric, so the two read as one control family ---------- */
#g-sup .sev-seg{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
#g-sup .sev-seg button{min-height:var(--tap,44px);border-radius:11px;padding:0 4px;
  display:inline-flex;align-items:center;justify-content:center;font-family:inherit}
/* The where-were-you switch borrows that geometry but has TWO halves, not three — without this it
   sits in a 3-up grid with a phantom empty column and each half renders a third of the width. Its
   labels are sentences rather than one word, so they are allowed to wrap instead of being clipped;
   min-height above still keeps the tap target at 44px when they do not. */
#g-sup .loc-seg{grid-template-columns:repeat(2,1fr)}
#g-sup .loc-seg button{padding:6px 8px;line-height:1.2;white-space:normal}

/* --- notes / failure block ---------------------------------------------------------------------- */
#g-sup .in-fail{background:var(--sunk);border:1px solid var(--line);border-left:3px solid var(--amber);
  border-radius:12px;padding:11px 12px}
#g-sup .in-warn-lbl{display:flex;align-items:flex-start;gap:6px;color:var(--amber-ink)}
#g-sup .in-warn-lbl svg.ic{flex:none;margin-top:1px}
#g-sup .in-ck{display:flex;align-items:center;gap:10px;min-height:var(--tap,44px);margin:2px 0 0;
  font-size:13.5px;font-weight:600;color:var(--ink);cursor:pointer}
#g-sup .in-ck input[type=checkbox]{appearance:none;-webkit-appearance:none;flex:none;position:relative;
  width:22px;height:22px;margin:0;border:2px solid var(--line);border-radius:7px;background:var(--surface);cursor:pointer}
#g-sup .in-ck input[type=checkbox]:checked{background:var(--blue);border-color:var(--blue)}
#g-sup .in-ck input[type=checkbox]:checked::after{content:"";position:absolute;left:6px;top:2px;
  width:5px;height:10px;border:solid #fff;border-width:0 2.6px 2.6px 0;transform:rotate(45deg)}

/* --- GPS proof line ------------------------------------------------------------------------------ */
#g-sup .in-gps{display:flex;align-items:center;gap:8px;margin:0 0 4px;padding:10px 12px;border-radius:12px;
  background:var(--sunk);border:1px solid var(--line);font-size:12.5px;line-height:1.35;color:var(--muted)}
#g-sup .in-gps svg.ic{flex:none}
#g-sup .in-gps.ok{color:var(--green)}
#g-sup .in-gps.warn{color:var(--amber-ink)}
#g-sup .in-sec .sbtn.wfull{min-height:var(--tap,44px);display:flex;align-items:center;justify-content:center;gap:7px;margin-top:0}
/* the "Field report" escape hatch at the top of the tab — measured at 36px, the bar is 44 */
#g-sup .fr-alt .sbtn{min-height:var(--tap,44px)}

/* --- the action bar ------------------------------------------------------------------------------
   ★ THE GREEN BAR. This was sticky at `bottom:calc(64px + safe)` while .snav is only ~51px tall, so
   a 13px band sat between the bar and the nav with nothing painted in it — and whatever was
   scrolling behind showed through. Reproduced at scrollTop 140-185: the green `1 · Routine`
   severity pill, framed by the bar above and the nav below, reading as a stray green bar under
   "Save draft". Anchoring at bottom:0 and padding down PAST the nav means the bar's own background
   owns the whole band; the overlap is invisible because .snav (z-index 60) is painted over it. */
#g-sup .in-foot{position:sticky;bottom:0;z-index:5;display:flex;align-items:center;gap:9px;
  background:var(--bg);padding:10px 0 calc(58px + env(safe-area-inset-bottom));margin-top:14px}
#g-sup .in-foot .sbtn{min-height:var(--tap,44px);padding:12px 14px;display:inline-flex;align-items:center;
  justify-content:center;gap:7px;line-height:1}
#g-sup .in-foot .sbtn.ghost{flex:1}
#g-sup .in-foot .in-submit{flex:2}
#g-sup .in-foot .sbtn.is-done{background:var(--green)}
#g-sup .in-foot .sbtn svg.ic{width:15px;height:15px}
#g-sup .in-spin{width:14px;height:14px;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;
  border-radius:50%;display:inline-block;animation:inspin .7s linear infinite}
@keyframes inspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){#g-sup .in-spin{animation:none}}

/* --- floating radio chrome must not sit on a control ----------------------------------------------
   radio.js appends .rad-fab / .rad-bar to <body>, so neither can be reached by a #g-sup-scoped
   selector — these two rules are deliberately unscoped, like .post-sheet and .stoast above, and are
   gated on the Inspect view being the active one. The FAB is fixed at right:22px / bottom:128px,
   which put it (measured, 360x800) at x 290-338 y 624-672 — directly on the "Site secure" N/A
   button, and over #in-notes, "3 · SERIOUS" and the Submit button at other scroll offsets.
   Docking it beside the action bar and reserving a 60px gutter for it means it has a permanent home
   and covers nothing. Same idiom as guard.css:872, which moves .rad-bar out of the chat composer. */
body:has(#sv-inspect.on) .rad-fab{right:14px;bottom:calc(60px + env(safe-area-inset-bottom));width:46px;height:46px}
body:has(#sv-inspect.on) #g-sup .in-foot{padding-right:60px}
/* expanded radio bar: lift it clear of the action bar rather than letting it land on Submit */
body:has(#sv-inspect.on) #g-sup .rad-bar{bottom:calc(132px + env(safe-area-inset-bottom))}

/* ================================================================================================
   CHAT IN FIELD MODE — the officer messenger, running inside the Ops shell
   ------------------------------------------------------------------------------------------------
   supervisor.js no longer renders chat at all; guard.js does, into #sv-chat (see the chat-adapter
   block in guard.js). That works with NO restyling because guard.css's messenger is entirely
   UNSCOPED (.gchat / .g-thread / .gwrap / .gbubble / .ginbox / .gib-* / .g-compose ...) and its own
   skin tokens (--gb-chat, --gb-them, --gb-mine, --gb-field, --gb-surf, --gb-chip, --gb-rule ...)
   are declared on :root and [data-theme="dark"], which #g-sup does not redefine.
   Checked token by token before relying on it: #g-sup's --navy #032b49 - --ink #16222f -
   --muted #5f7288 - --line #e4eaf1 - --bg #eaf0f6 are the SAME values guard.css :root declares, and
   in dark the pairs differ only in the last step of the ramp (--ink #e6edf7 vs #e6eaf2, --line
   #26303f in both). So nothing below repaints the thread — it only supplies the shell GEOMETRY the
   officer app gets from .gapp / .gmain and #g-sup does not have.
   ============================================================================================== */
/* The Chat tab pins the app to the screen height so ONLY the list scrolls — the header, the action
   row and the compose bar stay put. Same rule, same reason, as guard.css's `.gapp:has(#gv-messages.on)`.
   ⚠ THE PIN COVERS THE CONVERSATION LIST TOO, AND IT HAS TO. It used to say
   `:has(#sv-chat.on .gchat)` — a THREAD only — under the comment "the INBOX is deliberately left
   alone: it scrolls the page like every other Field-mode tab". That sentence was wrong, and it is
   the owner's "still it's frozen scrolling up and down" on the staff chat inbox.
   The inbox is NOT like every other Field-mode tab: guard.css paints it as `.ginbox`, which carries
   `overflow-y:auto` + `overscroll-behavior:contain`. With no pin, `#sv-chat.on` is `.sview`'s plain
   display:block, so .ginbox's `flex:1` is inert and its height comes out exactly as tall as its own
   content. An overflow:auto box with nothing to scroll is STILL a scroll container, and contain on
   it means a drag that starts anywhere over the list is swallowed instead of chaining to #g-sup —
   so the list did not move at all, on any finger, in either direction.
   This is the identical mechanism guard.css's own note (section "Chat", `.gapp:has(#gv-messages.on)`)
   records for the officer app, measured there at 390x844. That fix widened the officer selector off
   `.gchat` and never reached this staff twin, which is why the same bug survived the 1.3.121 wave on
   the one surface an admin/supervisor account actually opens.
   Two ways to break it again: narrowing either selector back to a thread, or giving #g-sup a height
   that is not bounded — either one un-bounds .ginbox and the swallow comes straight back. */
#g-sup:has(#sv-chat.on){height:100vh;height:100dvh;overflow:hidden;display:flex;flex-direction:column}
/* The THREAD releases the bottom reserve: its compose bar pads its own background down past .snav
   (see the band note below). The LIST keeps #g-sup's `64px + safe`, which is what holds the last
   conversation row clear of the fixed nav now that the page itself no longer scrolls. */
#g-sup:has(#sv-chat.on .gchat){padding-bottom:0}
#g-sup #sv-chat.on{display:flex;flex-direction:column;flex:1;min-height:0}
#g-sup #sv-chat.on:has(.gchat){padding:0 18px}
/* .gth2 carries `margin:-18px -18px 0` so the thread header bleeds to the screen edge; an 18px
   gutter on the container is what makes that land flush instead of 18px short. */
#g-sup #sv-chat.on .gchat{flex:1;min-height:0}
/* THE BAND UNDER THE COMPOSER. #g-sup reserves `64px + safe` at the bottom for .snav, but .snav is
   only ~52px tall — the same dead band that showed the green severity pill through the Inspect
   action bar (see the .in-foot note above). Here the reserve is dropped entirely and the compose
   bar's OWN background pads down past the nav, so it owns the whole strip; .snav (z-index 60) is
   simply painted on top of it. env() is applied once, here, rather than twice. */
#g-sup #sv-chat.on .g-compose{padding-bottom:calc(56px + env(safe-area-inset-bottom))}
/* The "new messages" pill sits above the composer, which is now taller by the nav's height. */
#g-sup #sv-chat.on .gnewmsg{bottom:calc(126px + env(safe-area-inset-bottom))}
/* …and so does the "Notifications are off" bar. guard.js appends it to <body>, so like .rad-fab and
   .post-sheet above these two rules are deliberately UNSCOPED and gated on #g-sup instead. Field
   mode KEEPS the bar — a supervisor who cannot be reached is the same outage as an officer who
   cannot be — it just has different chrome to clear: .snav is ~52px + safe and gShowOps() takes the
   SOS button off screen, so the tall default guard.css uses (which reserves the SOS column) can come
   down here. These sit at the same specificity as guard.css's `body:has(#gv-messages.on)` rule and
   win on order, which is the whole reason supervisor.css is loaded second.
   The dock is set on <body>, matching guard.css: #g-toast reads the same variable to stack above
   the bar, and it is the bar's SIBLING, so a property set on #g-notifbar would be invisible to it. */
body:has(#g-sup:not(.hidden)){--g-nb-dock:calc(68px + env(safe-area-inset-bottom))}
body:has(#g-sup #sv-chat.on .gchat){--g-nb-dock:calc(150px + env(safe-area-inset-bottom))}
/* The inbox keeps the page gutters it shares with Today and Alerts. */
#g-sup #sv-chat.on .ginbox{padding:2px 0}
/* Two staff-only inbox avatars guard.css has no rule for (an officer list can never contain them). */
#g-sup .gib-av.glyph.inc{background:linear-gradient(160deg,#e11d2a,#8a0f1c)}
#g-sup .gib-av.glyph.grp{opacity:.95}

/* ---- 44px in the thread ------------------------------------------------------------------------
   Two controls come in from guard.css below the bar and are MEASURED here at 360x800:
     · .gth2-back  24x11  (`padding:0 4px 2px 0` on a bare chevron)
     · .grx / .grx.act  34px and 30px (the chat surface was explicitly out of scope for the officer
       modernization sweep, which is why they were never raised)
   Both are fixed with the house ::after overlay from that sweep — the chip keeps its painted size
   and grows an invisible 44px hit area — rather than by resizing them, which would change the
   thread's visual rhythm. Scoped to #g-sup because guard.css belongs to the officer app and is
   being edited elsewhere; the OFFICER app still has both defects and they are named in the report. */
#g-sup #sv-chat .gth2-back{position:relative;min-width:22px}
#g-sup #sv-chat .gth2-back::after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:var(--tap,44px);height:var(--tap,44px)}
#g-sup #sv-chat .grx{position:relative}
#g-sup #sv-chat .grx::after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:100%;min-width:var(--tap,44px);height:var(--tap,44px)}

/* ================================================================================================
   SITE-INSPECTION CARD  (guard.js gInspectCard)
   ------------------------------------------------------------------------------------------------
   DELIBERATELY UNSCOPED, like .post-sheet / .stoast / .clockcam above: the markup is produced by
   guard.js, which has no idea which shell it is rendering into. In practice these cards only ever
   appear in staff channels (grp:dispatch / grp:supervisors), which only Field mode can open — but
   scoping them to #g-sup would make that an assumption instead of a fact, and the class names
   (.insp-*) exist nowhere else in the platform, so an unscoped block collides with nothing.

   Every value is a --gb-* chat token or a status colour that already has a proven dark counterpart
   in this file, so dark mode needs only the status pills rather than a parallel skin. Emoji-to-icon
   is doctrine: the rubric row draws the house 24px stroked glyphs, never the tick/cross/clipboard
   characters the server put in the text.
   ============================================================================================== */
.gwrap.insp-wrap{max-width:100%;width:100%;align-self:stretch;align-items:stretch}
.gwrap.them>.gbubble.insp-card{padding:0;overflow:hidden;white-space:normal;border-radius:14px;
  border-left:3px solid var(--blue,#0a6bb0);box-shadow:0 1px 2px rgba(18,28,48,.06),0 8px 22px rgba(18,28,48,.07);
  /* .gbubble.them sets align-self:flex-start on the bubble ITSELF, which beats the wrapper's
     align-items — so a card whose content is narrow (a single captioned photo) shrink-to-fits to
     about half the row. MEASURED at 360x800: 153px inside a 304px wrapper. A record on the wall
     runs the full width whatever is in it. */
  align-self:stretch;width:100%}
.gwrap.them>.gbubble.insp-card.sev-ok{border-left-color:var(--green,#0f9d58)}
.gwrap.them>.gbubble.insp-card.sev-concern{border-left-color:var(--amber,#e08600)}
.gwrap.them>.gbubble.insp-card.sev-serious{border-left-color:var(--red,#e11d2a)}
.insp-card .insp-head{display:flex;align-items:flex-start;gap:9px;padding:11px 13px 0}
.insp-card .insp-ic{flex:none;width:17px;color:var(--muted,#5f7288)}
.insp-card .insp-ic svg{width:17px;height:17px;display:block}
.insp-card .insp-h{flex:1;min-width:0}
.insp-card .insp-h b{display:block;font-family:var(--font-display,inherit);font-weight:700;font-size:14.5px;
  line-height:1.25;word-break:break-word}
.insp-card .insp-h small{display:block;font-size:11px;color:var(--muted,#5f7288);margin-top:2px}
/* The score is the headline number — a supervisor scrolling a busy channel reads this and nothing
   else. Big, monospaced so 4/5 and 12/12 line up down the channel, and coloured by outcome. */
.insp-card .insp-score{flex:none;font-family:var(--font-mono,ui-monospace,monospace);font-weight:700;
  font-size:16px;line-height:1;padding:7px 11px;border-radius:11px;letter-spacing:-.02em;white-space:nowrap}
.insp-card .insp-score.pass{background:#e4f6ec;color:#0d7a45}
.insp-card .insp-score.part{background:#fdf0dc;color:#a8660a}
.insp-card .insp-score.fail{background:#fbe3e5;color:#c0182a}
.insp-card .insp-sev{margin:8px 13px 0;font-size:9.5px;font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;border-radius:99px;padding:3px 9px;display:inline-block;background:#fdf0dc;color:#a8660a}
.insp-card.sev-serious .insp-sev{background:#fbe3e5;color:#c0182a}
.insp-card .insp-by{display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;padding:7px 13px 0;
  font-size:12px;font-weight:600;color:var(--muted,#5f7288)}
.insp-card .insp-geo{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:700;
  border-radius:99px;padding:2px 8px;background:var(--gb-press,rgba(10,30,60,.07))}
.insp-card .insp-geo svg{width:11px;height:11px}
.insp-card .insp-geo.ok{color:#0d7a45}
.insp-card .insp-geo.warn{color:#a8660a}
/* The rubric: an icon row, not a sentence of ticks and crosses. A FAILED item is the reason the
   visit spawns follow-up work, so it is the loud one — the same rule as .rub-item[data-state="fail"]
   on the Inspect form, so the two screens agree about what a failure looks like. */
.insp-card .insp-rub{display:flex;flex-wrap:wrap;gap:6px;padding:10px 13px 0}
.insp-card .insp-r{display:inline-flex;align-items:center;gap:5px;border-radius:9px;padding:5px 9px 5px 7px;
  font-size:11px;font-weight:700;background:var(--gb-press,rgba(10,30,60,.07));color:var(--muted,#5f7288)}
.insp-card .insp-ri{display:flex;flex:none}
.insp-card .insp-ri svg{width:13px;height:13px;display:block}
.insp-card .insp-r.pass{color:#0d7a45}
.insp-card .insp-r.na{opacity:.55}
.insp-card .insp-r.fail{background:#fbe3e5;color:#c0182a;box-shadow:inset 0 0 0 1px rgba(192,24,42,.28)}
.insp-card .insp-ofc{display:flex;flex-wrap:wrap;gap:5px;padding:9px 13px 0}
.insp-card .insp-chip{display:inline-flex;align-items:center;gap:6px;border-radius:99px;padding:3px 10px 3px 3px;
  font-size:11.5px;font-weight:700;background:var(--gb-press,rgba(10,30,60,.07))}
.insp-card .insp-chip i{flex:none;width:19px;height:19px;border-radius:50%;color:#fff;font-style:normal;
  font-family:var(--font-display,inherit);font-weight:800;font-size:10px;display:flex;align-items:center;justify-content:center}
.insp-card .insp-chip.plain{padding:3px 10px;color:var(--muted,#5f7288)}
.insp-card .insp-notes{padding:9px 13px 0;font-size:13px;line-height:1.45;white-space:pre-wrap;word-break:break-word}
/* Proof shots. There is NO mosaic geometry here any more, and that is the point: this block used to
   be a verbatim copy of guard.css's .fr-mos rules with `insp-shots`/`insp-t` swapped in for
   `fr-mos`/`fr-t` — a third photo grid in an app that only ever needed one. The visit cards build
   their album with frMosaicHtml() now, exactly like the field-report card and a multi-photo channel
   message, so the geometry, the "+N" overflow tile, the tap target and the lightbox all live once
   in guard.css. Two things that were quietly wrong are fixed by the deletion: a visit with five
   photos no longer loses the fifth (the copy had no .fr-x tile, so the extra was dropped from the
   grid AND from the viewer's set), and an officer who is not a supervisor now sees a styled grid —
   this file does not load for them, so the copy rendered as an unstyled stack of full-width images.
   Only the things a visit card has that a report card does not are still stated here. */
/* A follow-up visit photo: the picture is the message, with a one-line caption under it. */
.insp-card.insp-shot-only{border-left-color:var(--muted,#5f7288)}
.insp-card .insp-cap{padding:8px 13px 10px;font-size:12px;font-weight:700;line-height:1.3}
.insp-card .insp-cap span{display:block;font-weight:600;font-size:11px;color:var(--muted,#5f7288);margin-top:2px}
/* Photo provenance — whether the pictures are proof the supervisor was on the post or only
   supporting evidence. Under the album, because it is a claim ABOUT those pictures. `.up` is amber,
   never red: an uploaded photo is legitimate evidence, just not proof of presence, and red is
   danger-only here. A sentence the parser does not recognise gets neither colour. */
.insp-card .insp-prov{display:flex;flex-direction:column;gap:3px;padding:7px 13px 0}
.insp-card .insp-p{position:relative;padding-left:11px;font-size:11px;line-height:1.35;color:var(--muted,#5f7288)}
.insp-card .insp-p::before{content:"";position:absolute;left:0;top:.42em;width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.55}
.insp-card .insp-p.live{color:#0d7a45}
.insp-card .insp-p.up{color:#a8660a}
[data-theme="dark"] .insp-card .insp-p.live{color:#5fd398}
[data-theme="dark"] .insp-card .insp-p.up{color:#e0ab5a}
.insp-card .fr-foot{padding:0 13px 10px}
.insp-card .fr-foot .grxbar{margin-top:9px}
/* Dark: only the status pills need real values — everything else is already a --gb-* token. */
[data-theme="dark"] .insp-card .insp-score.pass{background:#14351f;color:#5fd398}
[data-theme="dark"] .insp-card .insp-score.part,[data-theme="dark"] .insp-card .insp-sev{background:#2a2214;color:#e8b45c}
[data-theme="dark"] .insp-card .insp-score.fail{background:#2a1719;color:#ff8e97}
[data-theme="dark"] .insp-card.sev-serious .insp-sev{background:#2a1719;color:#ff8e97}
[data-theme="dark"] .insp-card .insp-r.pass{color:#5fd398}
[data-theme="dark"] .insp-card .insp-r.fail{background:#2a1719;color:#ff8e97;box-shadow:inset 0 0 0 1px rgba(255,142,151,.3)}
[data-theme="dark"] .insp-card .insp-geo.ok{color:#5fd398}
[data-theme="dark"] .insp-card .insp-geo.warn{color:#e8b45c}

/* --- REACTIVE CONTROLS: the #g-sup half of the house layer --------------------------------------
   The rule ("if it's done an action it should visually show") and its tokens live in guard.css
   section 14, which is in scope here — supervisor.html only redirects to guard.html, so both
   stylesheets are always on the same document. This file re-states just the rules that an existing
   #g-sup-scoped selector would out-specify: an unscoped `.is-done{background:...}` (0,0,1,0) loses
   to `#g-sup .sbtn.grad` (0,1,2,0), so the supervisor's Save buttons would go busy and then settle
   back to navy instead of green. Everything else (the spinner, the tokens, prefers-reduced-motion)
   is inherited and deliberately NOT duplicated.

   #g-sup .ps-act already shipped with transform:scale(.97) and is the precedent the house treatment
   was chosen to match; it is folded into the shared selector below rather than left as a one-off. */
#g-sup .sbtn,#g-sup .ps-act,#g-sup .fr-chip,#g-sup .insp-chip{
  transition:transform var(--press-ms,.09s) ease-out,filter var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
#g-sup .sbtn:active,#g-sup .ps-act:active,#g-sup .fr-chip:active,#g-sup .insp-chip:active{
  transform:scale(var(--press-scale,.97));filter:var(--press-dim,brightness(.93))}
@media (hover:hover){
  #g-sup .sbtn:hover,#g-sup .ps-act:hover{filter:var(--hover-dim,brightness(1.05))}
}
#g-sup .sbtn.is-busy,#g-sup .sbtn.is-done,#g-sup .sbtn.is-err,
#g-sup .ps-act.is-busy,#g-sup .ps-act.is-done,#g-sup .ps-act.is-err{
  transform:none!important;filter:none!important}
/* The settled states have to beat .sbtn.grad / .red / .green, hence the id in the selector. */
#g-sup .sbtn.is-done,#g-sup .ps-act.is-done{background:var(--green);color:#fff;border-color:transparent}
#g-sup .sbtn.is-err,#g-sup .ps-act.is-err{background:var(--red);color:#fff;border-color:transparent}
/* .sbtn is display:inline-block (and .wfull is block), so the icon+label pairing gBusy() swaps in
   needs a flex box or the spinner sits on its own baseline and the label jumps. */
#g-sup .sbtn.is-busy,#g-sup .sbtn.is-done,#g-sup .sbtn.is-err{
  display:inline-flex;align-items:center;justify-content:center;gap:7px}
#g-sup .sbtn.wfull.is-busy,#g-sup .sbtn.wfull.is-done,#g-sup .sbtn.wfull.is-err{display:flex}
/* gBusy() is defined in guard.js and emits .gspin; the inspection Submit predates it and emits
   .in-spin. Give the shared spinner the same ink-on-light correction .in-spin never needed. */
#g-sup .sbtn.ghost .gspin{border-color:rgba(20,40,70,.20);border-top-color:var(--navy-ink,#032b49)}
[data-theme="dark"] #g-sup .sbtn.ghost .gspin{
  border-color:rgba(200,220,245,.24);border-top-color:var(--navy-ink)}
/* .sbtn:disabled{opacity:.5} at the top of this file is what gBusy() would otherwise fade a working
   button to; the three transient states carry their own colour and must stay fully opaque. */
#g-sup .sbtn.is-busy:disabled,#g-sup .sbtn.is-done:disabled,#g-sup .sbtn.is-err:disabled{opacity:1}

/* ── THE BULKHEAD CARD (supRun / supFail in supervisor.js, gOpsBoom in guard.js) ────────────────
   What a Field-mode tab shows when its render threw. It is deliberately NOT styled like a toast or
   an .empty: this is a section that failed to draw, and the person holding the phone has to be able
   to read the exception out loud to the office. Hence the monospace block — .sfail-e wraps and
   preserves the newline between the message and the stack frame, and `user-select:text` because
   copying it is the entire point (the rest of this shell disables selection on tap targets).
   .bad's red band is reused rather than a new colour: it is already the "something is wrong here"
   signal on every other card in this file. Motion tokens per DESIGN-SYSTEM.md §7. */
#g-sup .sfail{background:#fdf3f3;border:1px solid var(--line);border-left:4px solid var(--red);
  border-radius:13px;padding:12px 13px;margin-bottom:10px;font-size:14px;
  animation:sfail-in var(--t-med,200ms) var(--ease,cubic-bezier(.2,.7,.3,1)) both}
#g-sup .sfail b{display:block;font-weight:800;color:var(--ink)}
#g-sup .sfail .meta{font-size:12.5px;color:var(--muted);margin-top:4px}
#g-sup .sfail-e{display:block;white-space:pre-wrap;word-break:break-word;user-select:text;-webkit-user-select:text;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11.5px;line-height:1.45;
  background:#fff;border:1px solid var(--line);border-radius:9px;padding:8px 9px;margin-top:8px;color:#8a1420}
@keyframes sfail-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){#g-sup .sfail{animation:none}}
[data-theme="dark"] #g-sup .sfail{background:#2a1719;border-color:#22364a;border-left-color:var(--red)}
[data-theme="dark"] #g-sup .sfail-e{background:#12202c;border-color:#22364a;color:#ff9ba4}

/* An advance on the PAYER's phone: the row he opens to get the $cashtag into Cash App. The card
   itself is guard.css's .td-adv (one implementation, both apps); this only marks the row. */
.gear-row.adv{border-left:3px solid #2f9e5c}

/* ── CLEARING NOTIFICATIONS (renderMore in supervisor.js) ───────────────────────────────────────
   The ✕ on a bell row and the "Clear all" beside the section heading. Owner ask, 2026-08-14:
   "ability to clear notifications one by one or all at once".

   ⚠ NO SWIPE-TO-DISMISS, and this is a hard constraint rather than a preference. The officer shell
   owns a UNIVERSAL SWIPE-BACK navigation gesture, so a horizontal drag on a list row already means
   "go back" everywhere in this app. A swipe-away here would either swallow that gesture on this one
   screen or fire it by accident mid-clear — and "I meant to clear one notification and the screen
   left" is a worse outcome than one extra tap. Explicit ✕, at the house --tap:44px floor.

   Motion per DESIGN-SYSTEM.md §7: tokens only, compositable properties only (opacity + transform —
   NOT height/max-height, which would relayout the list every frame on the mid-range Androids this
   ships to), and the whole thing inside prefers-reduced-motion:no-preference. Under reduced motion
   there is no transition, so supervisor.js's transitionend listener never fires and its 260ms timer
   is what removes the row — which is exactly why that exit has two ways out. */
/* margin-BOTTOM only, deliberately longhand. The base `#g-sup .sec{margin:16px 0 8px}` and the
   `#g-sup .sec:first-child{margin-top:2px}` above it carry the same specificity as `.sec.snf-sec`,
   so a shorthand here would silently win the top margin off :first-child (Notifications IS the
   first section on a phone whose account has no command post) and push the whole screen down. */
#g-sup .sec.snf-sec{display:flex;align-items:center;gap:8px;margin-bottom:4px}
#g-sup .sec.snf-sec>span{flex:1;min-width:0}
#g-sup .snf-all{flex:none;min-height:var(--tap,44px);display:inline-flex;align-items:center;padding:0 10px;
  background:transparent;border:0;border-radius:10px;cursor:pointer;
  font-family:inherit;font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:#0a6bb0}
#g-sup .snf-all:disabled{opacity:.5}
#g-sup .snf-x{flex:none;width:var(--tap,44px);height:var(--tap,44px);margin:-6px -8px -6px 0;
  display:flex;align-items:center;justify-content:center;
  background:transparent;border:0;border-radius:11px;cursor:pointer;
  font-family:inherit;font-size:15px;line-height:1;color:var(--muted)}
#g-sup .snf-x:disabled{opacity:.45}
[data-theme="dark"] #g-sup .snf-all{color:#6cb6ea}
@media (prefers-reduced-motion:no-preference){
  /* --press-ms, not --t-fast, on the transform: DESIGN-SYSTEM.md §7.1's first documented exception
     — a tap has to feel landed before the finger lifts, and --t-fast there reads as a laggy button.
     Same transition/scale/dim triple guard.css gives every other pressable in this app. */
  #g-sup .snf-all,#g-sup .snf-x{transition:transform var(--press-ms,.09s) ease-out,background var(--t-fast) var(--ease),filter var(--t-fast) var(--ease)}
  #g-sup .snf-all:active,#g-sup .snf-x:active{transform:scale(var(--press-scale,.97));filter:var(--press-dim)}
  #g-sup .snf-all.is-busy,#g-sup .snf-x:disabled{transform:none;filter:none}
  /* The row's exit. Set on .snf-row (not on .gear-row) so the gear-custody rows further down the
     same screen, which share every other style with it, are untouched. */
  #g-sup .snf-row{transition:opacity var(--t-med,200ms) var(--ease),transform var(--t-med,200ms) var(--ease)}
  #g-sup .snf-row.snf-go{opacity:0;transform:translateX(26px)}
}
#g-sup .snf-x:active{background:#eef1f6}
[data-theme="dark"] #g-sup .snf-x:active{background:#243044}

/* ── MY TASKS: the task card's outer chassis ─────────────────────────────────────────────────────
   Field supervisor Sam: "the font size of 'My Tasks' is relatively small … Or, better still, the
   content of 'My Tasks' should be reorganized and spaced out."

   THE CARD ITSELF IS NOT HERE. Its type, chips, meta grid, prose and fold are guard.css section 25
   (.gtk-*), unscoped, because the officer lane and the body-appended detail sheet render the same
   anatomy and nothing under #g-sup can reach either. This file owns only what is specific to being
   a row in THIS list.

   ⚠ WHY A MODIFIER AND NOT AN EDIT TO .gear-row. `#g-sup .gear-row` (13.5px, centred, 10px/13px
   padding) is shared — Directory, Posts, the assign sheet's held-gear rows and the mention picker
   all draw it, and the comment beside its definition says so. Widening it to Sam's 16px would
   re-type five other screens on his say-so about one. `.gtk-row` is added by renderTasks alone.

   ⚠ AND WHY IT IS SCOPED. `#g-sup .gear-row` is (1,1,0); a plain `.gear-row.gtk-row` in guard.css
   is (0,2,0) and would lose to it on padding and alignment — silently, and only in this lane. The
   id has to be matched to be beaten, which is exactly why this rule lives in this file. */
/* ⚠ display:block, NOT the shared row's flex. Measured on a 375px handset: the trailing ✓ Done
   button took 67px out of the row, leaving the description 236px wide — about 29 characters a line,
   where the whole report was that lines are too short and too small to read. Dropping the flex gives
   .gear-main the full width (~330px, ~41 characters) and the action moves to .gtk-foot below. */
#g-sup .gear-row.gtk-row{
  display:block;padding:15px 15px;margin-bottom:11px;font-size:16px}
/* The action line. Right-aligned so the thumb finds it in the same place on every card, and given
   real separation from the text it acts on rather than being tucked against it. */
#g-sup .gear-row.gtk-row .gtk-foot{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:12px}
#g-sup .gear-row.gtk-row .gtk-foot>.sbtn{min-height:var(--tap,44px);flex:none}
/* The "Created by … · history" link and the To pay / Sent back notes keep the muted voice they had,
   but at a size that belongs next to 16px body copy rather than the 11px the dense row used. */
#g-sup .gtk-sub{font-size:13px;line-height:1.45;margin-top:8px;color:var(--muted)}
/* The word "history" paints 43px wide, one pixel under the house floor — measured, not assumed. The
   negative margin buys the hit area back on both axes without moving the text a pixel, which is the
   same trick section 5 of guard.css uses on every small chip. */
#g-sup .gtk-sub .gtk-hist-lnk{min-height:var(--tap,44px);min-width:var(--tap,44px);
  display:inline-flex;align-items:center;justify-content:center;
  background:none;border:0;padding:0 5px;margin:0 -5px;font:inherit;color:#0a6bb0;text-align:left;
  cursor:pointer;font-weight:700}
[data-theme="dark"] #g-sup .gtk-sub .gtk-hist-lnk{color:#8fc4f0}

/* ══ MY TASKS — THE KIND CHIPS (supervisor.js renderTasks) ════════════════════════════════════════
   The phone half of the console's filter row. Shaped on .gib-filters / .gib-f / .gib-fn in guard.css
   — the officer inbox's own filter row, which is this app's established answer to "narrow a list on
   a handset": a horizontally scrollable strip of pills, count on each, one tap.
   ★ WRITTEN HERE AND SCOPED TO #g-sup RATHER THAN REUSING .gib-f DIRECTLY, for two reasons and both
   are load-bearing. The inbox chip is 31px tall; every control in the Field-mode tasks lane carries
   the house --tap:44px floor (see .tka-filters and .gtk-hist-lnk above), and borrowing a shorter
   target for a new one would be the parity standard going backwards. And a rule the inbox owns would
   then be answerable for two screens that are free to diverge.
   The scroll strip hides its scrollbar (a thumb drags it) and never wraps: a filter row that reflows
   to two lines pushes the first task off the fold on a 375px screen. */
#g-sup .tkf-chips{display:flex;gap:7px;margin:0 0 10px;overflow-x:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch}
#g-sup .tkf-chips::-webkit-scrollbar{display:none}
#g-sup .tkf-chip{flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;min-height:var(--tap,44px);
  padding:0 14px;border:1px solid var(--line,#d3dae6);border-radius:22px;background:var(--surface,#fff);
  color:var(--ink,#33405a);font:inherit;font-size:13.5px;font-weight:700;cursor:pointer;white-space:nowrap}
/* ON = a filled navy pill, the same "selected chip" language .gib-f.on and .gchan-chip.on already
   speak everywhere else in this app, so a supervisor does not have to learn a second one. */
#g-sup .tkf-chip.on{background:var(--navy,#22345f);border-color:var(--navy,#22345f);color:#fff}
#g-sup .tkf-cn{min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:var(--sunk,#eef2f8);
  color:var(--muted,#5f7288);font-size:11.5px;font-weight:800;display:inline-flex;align-items:center;
  justify-content:center;font-variant-numeric:tabular-nums}
#g-sup .tkf-chip.on .tkf-cn{background:rgba(255,255,255,.26);color:#fff}
#g-sup .tkf-chip:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(26,134,208,.35)}
[data-theme="dark"] #g-sup .tkf-chip{background:#141b28;border-color:#2a3648;color:#cbd6e6}
[data-theme="dark"] #g-sup .tkf-chip.on{background:#1d4a80;border-color:#1d4a80;color:#fff}
[data-theme="dark"] #g-sup .tkf-cn{background:#1e2739;color:#9aa9bd}
@media (prefers-reduced-motion: no-preference){
  #g-sup .tkf-chip{transition:background var(--t-fast,150ms) var(--ease,cubic-bezier(.2,.7,.3,1)),
    border-color var(--t-fast,150ms) var(--ease,cubic-bezier(.2,.7,.3,1)),
    color var(--t-fast,150ms) var(--ease,cubic-bezier(.2,.7,.3,1))}
  #g-sup .tkf-chip:active{transform:scale(var(--press-scale,.97))}
}

/* ══ TASK ACTIVITY (supervisor.js taskActivitySheet AND taskHistorySheet) ═════════════════════════
   Everything that has happened to a task, on the board and on one task. The CARD still needs no
   rules of its own — it is .scard in the four tones this shell already has (grey for the quiet
   kinds, ok for the two that close work out, warn for anything that undoes or overrides somebody,
   bad for a deletion and a refusal), so a tone change lands here and on every other card at once.
   What IS new: the filter row, the two title states, and the three things a timeline needs that a
   list did not — the day heading, the sentence under the tone, and the old→new.
   Every control carries the --tap floor: this is a thumb, and the house rule is 44px. */
#g-sup .tka-filters{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}
#g-sup .tka-filters select{width:100%;min-height:var(--tap,44px);font:inherit;font-size:14px;
  border:1px solid var(--line);border-radius:10px;padding:0 10px;background:#fff;color:inherit}
#g-sup .tka-dates{display:flex;gap:8px}
#g-sup .tka-dates input{flex:1;min-width:0;min-height:var(--tap,44px);font:inherit;font-size:14px;
  border:1px solid var(--line);border-radius:10px;padding:0 10px;background:#fff;color:inherit}
/* The title of a task that still exists — a real control, so it takes the tap floor, bought back
   with a negative margin so the text does not move (the trick .gtk-hist-lnk uses just above). */
#g-sup .tka-open{min-height:var(--tap,44px);display:inline-flex;align-items:center;text-align:left;
  background:none;border:0;padding:0 5px;margin:0 -5px;font:inherit;font-weight:800;color:#0a6bb0;cursor:pointer}
/* …and the title of one that is GONE. Struck through, and deliberately NOT a button: there is
   nothing left to open, and a control whose only outcome is a dead end is worse than plain text. */
#g-sup .tka-gone{text-decoration:line-through;text-decoration-thickness:1px;color:var(--muted);font-weight:700}
/* ---- THE TIMELINE'S DAY HEADING ----------------------------------------------------------------
   The handset twin of the console's .daychip and of the message thread's day separator: one heading
   per COMPANY day, in normal flow above the cards it introduces. Deliberately NOT sticky — an opaque
   lozenge pinned to a scrollport paints over the card beneath it, which is the bug the console's own
   separator was fixed for. Not a control, so no tap floor: it is a label. */
#g-sup .tka-day{font-size:11px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
  color:var(--muted);margin:14px 0 7px;padding-left:2px}
#g-sup .tka-day:first-child{margin-top:2px}
/* What an edit moved, or what a refusal was refusing — the sentence the pill cannot carry. */
#g-sup .tka-what{font-size:12.5px;font-weight:700;margin-top:4px;overflow-wrap:anywhere}
/* The old → new. `anywhere` because a due date, a name and a Cash App tag all land in here and a
   long one must wrap rather than push the card off a 375px screen. */
#g-sup .tka-chg{font-size:12px;margin-top:4px;line-height:1.55;color:var(--muted);overflow-wrap:anywhere}
/* The NEW value is the one the reader is looking for, so it takes the card's own ink while the
   sentence around it stays muted — the same weighting the console's .chg-b gives it. No dark twin:
   --ink is a THEMED token in guard.css (#16222f light, #e6eaf2 dark), so one rule covers both and a
   hardcoded override here would be a second opinion that stops following the palette. */
#g-sup .tka-chg b{color:var(--ink,#1d2939);font-weight:800}
[data-theme="dark"] #g-sup .tka-open{color:#8fc4f0}
[data-theme="dark"] #g-sup .tka-filters select,[data-theme="dark"] #g-sup .tka-dates input{background:#141c28;border-color:var(--line)}

/* ══ FIELD MAIL (supervisor.js supMailScreen and below) ═══════════════════════════════════════════
   GMAIL ON ANDROID is the reference (owner: "make the field mail like gmail", "not basic"), painted
   on the USG navy tokens — the same relationship the messenger has to Discord.
   Everything paints from var(--surface,#fff) / var(--sunk,…) rather than a literal #fff so the DARK
   block earlier in this file (which redefines exactly those tokens on #g-sup) reaches this section
   without a single [data-theme="dark"] rule of its own. That is the officer house-control-layer
   lesson: an allow-list of dark rules rots, tokens do not.
   Every interactive control carries the --tap:44px floor. Rows are 16px because they are the
   My-tasks mobile bar: a trailing control in a flex row takes ~67px off a 360px screen and leaves
   about 29 characters of subject, which is the shape the owner rejected there. */
#g-sup .hide{display:none!important}

/* ⚠ ONE ACCENT TOKEN, because --blue is NOT redefined by the dark block above and a foreground
   painted straight from it fails in dark. MEASURED: .sm-ccbtn was #0a6bb0 on --bg #0f1520 = 3.26:1,
   under the 4.5 floor for 13.5px text. The house already solved this once for links
   ([data-theme="dark"] #g-sup a{color:#6fb2e8}); this is the same value, made available to every
   accent FOREGROUND and border here so the next rule added cannot miss it. --blue itself is kept for
   accent BACKGROUNDS (the unread badge, the active pill), where the text on top is white and the
   pair already passes in both themes. */
#g-sup{--sm-accent:var(--blue,#0a6bb0)}
[data-theme="dark"] #g-sup{--sm-accent:#6fb2e8}

/* ---- the top bar: Gmail's search pill, doing three jobs ---- */
#g-sup .sm-bar{display:flex;align-items:center;gap:6px;margin:2px 0 10px}
#g-sup .sm-chip{flex:1;min-width:0;display:flex;align-items:center;gap:9px;min-height:var(--tap,44px);
  padding:8px 14px;border:1px solid var(--line);border-radius:99px;background:var(--surface,#fff);
  color:var(--muted);font:inherit;font-size:14.5px;text-align:left;cursor:pointer;-webkit-appearance:none;appearance:none;
  box-shadow:0 1px 3px rgba(10,20,40,.06)}
#g-sup .sm-chip .ic{flex:none;width:19px;height:19px;color:var(--muted)}
#g-sup .sm-chip-tx{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-bar-menu,#g-sup .sm-bar-av{flex:none}
#g-sup .sm-bar-av{width:var(--tap,44px);height:var(--tap,44px);display:inline-flex;align-items:center;justify-content:center;
  border:0;background:transparent;padding:0;cursor:pointer}
#g-sup .sm-ic{flex:none;width:var(--tap,44px);height:var(--tap,44px);display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:12px;background:var(--surface,#fff);color:var(--ink);cursor:pointer;padding:0}
#g-sup .sm-ic.danger{color:var(--red)}
#g-sup .sm-ic .ic{width:20px;height:20px}
#g-sup .sm-bar-menu{border:0;background:transparent}
/* CONNECTIVITY ONLY. A 403 is not an outage and must never reach this banner — the calendar-mobile
   rule. It says what is true (this is the last mail that arrived) instead of blaming the server. */
#g-sup .sm-off{background:#fdf0dc;color:#7a4a06;border:1px solid #f0d9b0;border-radius:11px;
  padding:9px 12px;font-size:13.5px;font-weight:700;margin-bottom:10px}
[data-theme="dark"] #g-sup .sm-off{background:#33240d;color:#f0cf9a;border-color:#4d380f}

/* ---- the search screen ---- */
#g-sup .sm-bar-search .sm-qin,#g-sup .sm-bar-cmp .sm-cmp-title{flex:1;min-width:0}
#g-sup .sm-qin{min-height:var(--tap,44px);padding:9px 14px;border:1px solid var(--line);border-radius:99px;
  background:var(--surface,#fff);color:var(--ink);font:inherit;font-size:16px;-webkit-appearance:none;appearance:none}
#g-sup .sm-recent{display:flex;align-items:center;gap:11px;width:100%;box-sizing:border-box;min-height:var(--tap,44px);
  padding:8px 10px;border:0;border-bottom:1px solid var(--line);background:transparent;color:var(--ink);
  font:inherit;font-size:15px;text-align:left;cursor:pointer}
#g-sup .sm-recent .ic{flex:none;width:18px;height:18px;color:var(--muted)}
#g-sup .sm-hi{background:rgba(224,161,6,.28);color:inherit;border-radius:3px;padding:0 1px}

/* ---- multi-select (Gmail's long-press mode): the TOP BAR MORPHS into this — #sm-topbar hides,
   this strip takes its place with ✕ · count · archive/delete/read/⋮, and the Select all /
   Deselect all chips ride underneath. ---- */
#g-sup .sm-selbar{display:block;margin:2px 0 10px;padding:4px 6px;
  background:rgba(10,107,176,.10);border:1px solid var(--line);border-radius:13px}
#g-sup .sm-selrow{display:flex;align-items:center;gap:6px}
#g-sup .sm-selcount{flex:1;min-width:0;font-size:17px;font-weight:800;padding-left:4px}
#g-sup .sm-selacts{display:flex;gap:2px;flex:none}
#g-sup .sm-selbar .sm-ic{border-color:transparent;background:transparent;font-size:20px;line-height:1}
#g-sup .sm-selsub{display:flex;gap:8px;flex-wrap:wrap;padding:3px 6px 7px 8px}
/* The chips stay visually small; the ::after overlay buys the 44px hit box back — the house trick.
   The overlay belongs to the button itself, so hit-testing cannot be stolen by the row. */
#g-sup .sm-selchip{position:relative;min-height:34px;padding:0 14px;border:1px solid var(--line);border-radius:99px;
  background:var(--surface,#fff);color:var(--sm-accent);font:inherit;font-size:13px;font-weight:800;cursor:pointer;
  -webkit-appearance:none;appearance:none}
#g-sup .sm-selchip::after{content:"";position:absolute;left:0;right:0;top:-5px;bottom:-5px;border-radius:99px}

/* ---- filter chips ---- */
#g-sup .sm-pills{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:8px}
#g-sup .sm-pill{flex:0 1 auto;min-height:var(--tap,44px);display:inline-flex;align-items:center;gap:6px;
  padding:0 14px;border:1px solid var(--line);border-radius:99px;background:var(--surface,#fff);
  color:var(--ink);font:inherit;font-size:13.5px;font-weight:800;cursor:pointer;-webkit-appearance:none;appearance:none}
#g-sup .sm-pill.on{background:var(--navy);border-color:var(--navy);color:#fff}
#g-sup .sm-pill .n{font-size:11.5px;font-weight:800;background:rgba(10,107,176,.14);color:var(--sm-accent);border-radius:99px;padding:1px 7px}
#g-sup .sm-pill.on .n{background:rgba(255,255,255,.22);color:#fff}

/* ---- pull to refresh: the house ring ---- */
#g-sup .sm-ptr{height:0;overflow:hidden;display:flex;align-items:center;justify-content:center}
#g-sup .sm-spin{width:22px;height:22px;border-radius:50%;border:2.5px solid var(--line);border-top-color:var(--sm-accent);display:block}
#g-sup .sm-ptr.armed .sm-spin{border-top-color:var(--sm-accent);border-right-color:var(--sm-accent)}
@media (prefers-reduced-motion: no-preference){
  #g-sup .sm-ptr.armed .sm-spin{animation:smspin .7s linear infinite}
  @keyframes smspin{to{transform:rotate(360deg)}}
}

/* ---- the list ------------------------------------------------------------------------------------
   ⚠ .sm-rowwrap IS overflow:hidden AND THAT IS LOAD-BEARING, not tidiness: the swipe backdrops are
   absolutely positioned inside it, so a revealed action is CLIPPED rather than widening the document.
   Without it a half-swiped row gives the whole page a horizontal scrollbar. Measured at 390 and 360. */
#g-sup .sm-rows{display:block}
#g-sup .sm-rowwrap{position:relative;overflow:hidden;border-radius:14px;margin-bottom:8px;background:var(--sunk,#eef2f7)}
#g-sup .sm-swipe{position:absolute;top:0;bottom:0;width:100%;display:flex;align-items:center;gap:9px;
  padding:0 20px;color:#fff;font-size:13.5px;font-weight:800;opacity:0;pointer-events:none}
#g-sup .sm-swipe .ic{width:22px;height:22px}
#g-sup .sm-swipe.left{right:0;justify-content:flex-end;background:#2a7d52}
#g-sup .sm-swipe.right{left:0;justify-content:flex-start;background:var(--navy-2,#005080)}
#g-sup .sm-rowwrap.sw-l .sm-swipe.left,#g-sup .sm-rowwrap.sw-r .sm-swipe.right{opacity:1}
#g-sup .sm-row{position:relative;display:flex;align-items:flex-start;gap:12px;width:100%;box-sizing:border-box;
  min-height:var(--tap,44px);background:var(--surface,#fff);border:1px solid var(--line);border-radius:14px;
  padding:12px 12px 12px 12px;cursor:pointer;font-size:16px;text-align:left}
#g-sup .sm-row.on{border-color:var(--sm-accent)}
#g-sup .sm-row.picked{background:rgba(10,107,176,.12);border-color:var(--sm-accent)}
#g-sup .sm-row:focus-visible{outline:2px solid var(--sm-accent);outline-offset:2px}
/* THE DISC IS A FIXED COLUMN and the text column takes the remainder — the today-strip lesson: a
   flexible avatar plus a flexible text box is how a long address shreds a subject into one word per
   line. min-width:0 on the text column is what actually lets the ellipsis happen. */
#g-sup .sm-avwrap{flex:none;position:relative;width:40px;height:40px;display:block;border-radius:50%}
/* The disc IS the selection control (Gmail), and it is 40px because that is the size the row was
   designed around — so the hit area is bought back with a ::after overlay rather than by growing the
   art, which is the house trick for every chip that must stay visually small. MEASURED at 390: 40 →
   44 on both axes, and the -2px inset stays inside .sm-row's 12px padding, so the row cannot clip it
   out of hit-testing the way an oversized <input> gets clipped. */
#g-sup .sm-avwrap::after{content:"";position:absolute;inset:-2px;border-radius:50%}
#g-sup .sm-av{width:40px;height:40px;font-size:15px;border-radius:50%}
#g-sup .sm-av-sm{width:30px;height:30px;font-size:12px}
#g-sup .sm-av-xs{width:24px;height:24px;font-size:10px}
#g-sup .sm-av-lg{width:44px;height:44px;font-size:17px}
#g-sup .sm-av-fb{display:inline-flex;align-items:center;justify-content:center;background:var(--navy-2,#005080);color:#fff;font-weight:800}
#g-sup .sm-tick{position:absolute;inset:0;border-radius:50%;background:var(--sm-accent);color:#fff;
  display:none;align-items:center;justify-content:center}
#g-sup .sm-tick .ic{width:22px;height:22px}
#g-sup .sm-row.picked .sm-tick{display:flex}
#g-sup .sm-rowtx{flex:1;min-width:0;display:block}
#g-sup .sm-row-1{display:flex;align-items:baseline;gap:8px}
#g-sup .sm-who{flex:1;min-width:0;font-size:16px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-when{flex:none;font-size:13px;color:var(--muted);font-variant-numeric:tabular-nums}
#g-sup .sm-row-2{display:flex;align-items:center;gap:6px;margin-top:1px}
#g-sup .sm-sub{flex:1;min-width:0;font-size:16px;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-clip{flex:none;color:var(--muted);display:inline-flex}
#g-sup .sm-clip .ic{width:15px;height:15px}
/* "Seen by N" on a company-mailbox row — the console's .m-seen chip, sized for a thumb-width list.
   Both themes come free: --sunk, --line and --muted are declared on #g-sup and re-declared under
   [data-theme="dark"] #g-sup in the token blocks ABOVE, so this needs no dark override of its own.
   Tabular numerals so a column of chips does not jitter as the counts change. */
#g-sup .sm-seenc{flex:none;display:inline-flex;align-items:center;gap:3px;padding:1px 7px;border-radius:99px;
  background:var(--sunk);border:1px solid var(--line);color:var(--muted);font-size:12px;font-weight:700;
  font-variant-numeric:tabular-nums;line-height:1.5}
#g-sup .sm-seenc .ic{width:13px;height:13px;opacity:.75}
#g-sup .sm-seenc b{font-weight:800}
/* One line, clamped: in Gmail the snippet is a hint, and letting it run turns the list into a wall. */
#g-sup .sm-snip{display:block;font-size:15px;line-height:1.35;color:var(--muted);margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* THE READ/UNREAD CONTRAST IS THE GMAIL LOOK: unread is bold with an accent rail, read recedes. */
#g-sup .sm-row.unread{border-left:4px solid var(--sm-accent);padding-left:9px}
#g-sup .sm-row.unread .sm-who,#g-sup .sm-row.unread .sm-sub{font-weight:800}
#g-sup .sm-row.unread .sm-when{color:var(--sm-accent);font-weight:800}
#g-sup .sm-star{flex:none;width:var(--tap,44px);height:var(--tap,44px);margin:-8px -8px -8px 0;
  border:0;background:transparent;color:var(--line);font-size:21px;line-height:1;cursor:pointer;padding:0}
#g-sup .sm-star.on{color:#e0a106}
#g-sup .sm-star-big{width:var(--tap,44px);height:var(--tap,44px);font-size:24px}
/* The FAB floats over the end of the list, so the list has to stop short of it. */
#g-sup .sm-more{margin-top:4px;padding-bottom:86px}
#g-sup .sm-more .sbtn{min-height:var(--tap,44px)}
#g-sup .sm-end{text-align:center;font-size:12.5px;color:var(--muted);padding:10px 4px 2px}

/* ---- the composer FAB: Gmail's LABELLED pill, not a bare circle. Bottom-right is free in Field
   mode: gShowOps() hides #g-sos. ---- */
#g-sup .sm-fab{position:fixed;right:14px;bottom:calc(78px + env(safe-area-inset-bottom,0px));z-index:55;
  min-width:56px;height:56px;padding:0 20px 0 16px;gap:9px;border-radius:16px;border:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--grad-primary,linear-gradient(90deg,#005080,#0a6bb0));color:#fff;
  box-shadow:0 8px 22px rgba(3,40,73,.34);cursor:pointer}
#g-sup .sm-fab .ic{width:22px;height:22px;flex:none}
#g-sup .sm-fab-tx{font:inherit;font-size:14.5px;font-weight:800;letter-spacing:.01em}
#g-sup .sm-fab-off{background:var(--surface,#fff);color:var(--muted);border:1px solid var(--line);box-shadow:0 4px 14px rgba(3,40,73,.16)}
#g-sup .sm-act:disabled,#g-sup .sm-fab:disabled{opacity:.55;cursor:default}

/* ---- skeletons: the shape of the real row, so the pane never flashes empty ---- */
#g-sup .sm-sk{display:flex;gap:12px;align-items:center;background:var(--surface,#fff);border:1px solid var(--line);
  border-radius:14px;padding:14px 12px;margin-bottom:8px}
#g-sup .sm-sk-av{flex:none;width:40px;height:40px;border-radius:50%;background:var(--sunk,#eef2f7)}
#g-sup .sm-sk-c{flex:1;min-width:0}
#g-sup .sm-sk-l{height:11px;border-radius:6px;background:var(--sunk,#eef2f7);margin-bottom:8px}
#g-sup .sm-sk-l:last-child{margin-bottom:0}
@media (prefers-reduced-motion: no-preference){
  #g-sup .sm-sk-av,#g-sup .sm-sk-l{background:linear-gradient(90deg,var(--sunk,#eef2f7) 25%,var(--line) 37%,var(--sunk,#eef2f7) 63%);
    background-size:400% 100%;animation:smsh 1.3s ease-in-out infinite}
  @keyframes smsh{0%{background-position:100% 0}100%{background-position:0 0}}
}

/* ---- empty + error states: centered, house iconography, no emoji ---- */
#g-sup .sm-empty{text-align:center;padding:34px 18px;color:var(--muted)}
#g-sup .sm-empty .ic{width:44px;height:44px;opacity:.42;margin-bottom:10px;stroke-width:1.6}
#g-sup .sm-empty h3{margin:0 0 6px;font-size:17px;font-weight:800;color:var(--ink)}
#g-sup .sm-empty p{margin:0 auto 12px;font-size:14.5px;line-height:1.5;max-width:32em}

/* ---- the undo snackbar ---- */
#g-sup .sm-undo{position:fixed;left:12px;right:12px;bottom:calc(74px + env(safe-area-inset-bottom,0px));z-index:96;
  display:flex;align-items:center;gap:12px;background:#1c2430;color:#eef2f8;border-radius:12px;
  padding:12px 14px;font-size:14px;box-shadow:0 10px 28px rgba(3,18,34,.4)}
#g-sup .sm-undo span{flex:1;min-width:0}
#g-sup .sm-undo button{flex:none;min-height:var(--tap,44px);padding:0 12px;border:0;border-radius:9px;background:transparent;
  color:#7cc0f5;font:inherit;font-weight:800;text-transform:uppercase;letter-spacing:.04em;cursor:pointer}

/* ---- the drawer: mailbox switcher + folders ------------------------------------------------------
   Mounted INSIDE #g-sup, never on <body> — a body-appended overlay is outside every `#g-sup …`
   selector in this file and renders unstyled. z-index sits above .snav (60) and below .stoast (100)
   so a toast raised from inside the drawer is still readable. */
#g-sup .sm-drawer{position:fixed;inset:0;z-index:95;background:rgba(3,20,36,.5);display:flex;align-items:flex-end;justify-content:center}
#g-sup .sm-drawer-card{width:100%;max-width:560px;max-height:82vh;display:flex;flex-direction:column;
  background:var(--bg);border-radius:18px 18px 0 0;box-shadow:0 -10px 34px rgba(3,18,34,.34);outline:none}
/* The NAVIGATION drawer is Gmail's: a full-height sheet from the LEFT edge. The text-viewer sheet
   (.sm-txtsheet) keeps the bottom-sheet layout above — only the nav opts into this shape. */
#g-sup .sm-drawer.sm-nav{align-items:stretch;justify-content:flex-start}
#g-sup .sm-nav .sm-drawer-card{width:86%;max-width:340px;height:100%;max-height:none;
  border-radius:0 18px 18px 0;box-shadow:10px 0 34px rgba(3,18,34,.34)}
#g-sup .sm-drawer-head{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line)}
#g-sup .sm-drawer-head b{flex:1;font-size:16px;font-weight:800}
#g-sup .sm-drawer-body{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 14px calc(16px + env(safe-area-inset-bottom,0px))}
#g-sup .sm-box,#g-sup .sm-fold{display:flex;align-items:center;gap:11px;width:100%;box-sizing:border-box;
  min-height:52px;padding:9px 12px;margin-bottom:6px;border:1px solid var(--line);border-radius:12px;
  background:var(--surface,#fff);color:var(--ink);font:inherit;text-align:left;cursor:pointer;-webkit-appearance:none;appearance:none}
#g-sup .sm-fold .ic{flex:none;width:20px;height:20px;color:var(--sm-accent)}
#g-sup .sm-box.on,#g-sup .sm-fold.on{border-color:var(--sm-accent);background:rgba(10,107,176,.08)}
#g-sup .sm-box-tx{flex:1;min-width:0}
#g-sup .sm-box-tx b{display:block;font-size:15px;font-weight:800;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-box-tx small{display:block;font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-fold-tx{flex:1;min-width:0;font-size:15px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-n{flex:none;font-size:11.5px;font-weight:800;background:var(--blue);color:#fff;border-radius:99px;padding:2px 8px}
/* Drafts shows a TOTAL, not an unread — quieter chrome for a number that is not a demand. */
#g-sup .sm-n.dim{background:transparent;color:var(--muted);border:1px solid var(--line)}

/* ---- one message ---- */
#g-sup .sm-msg-sub{margin:2px 0 12px;font-size:21px;line-height:1.28;font-weight:700;overflow-wrap:anywhere}
#g-sup .sm-from{display:flex;align-items:center;gap:11px;margin-bottom:8px}
#g-sup .sm-from-tx{flex:1;min-width:0;border:0;background:transparent;padding:0;font:inherit;color:var(--ink);
  text-align:left;cursor:pointer;min-height:var(--tap,44px)}
#g-sup .sm-from-1{display:flex;align-items:baseline;gap:8px}
#g-sup .sm-from-1 b{flex:1;min-width:0;font-size:16px;font-weight:800;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-from-when{flex:none;font-size:13px;color:var(--muted)}
#g-sup .sm-from-2{display:flex;align-items:center;gap:4px;font-size:13.5px;color:var(--muted)}
#g-sup .sm-from-2 .ic{width:15px;height:15px}
#g-sup .sm-from-tx.open .sm-from-2 .ic{transform:rotate(180deg)}
#g-sup .sm-fromdet{background:var(--sunk,#f3f6fa);border:1px solid var(--line);border-radius:12px;padding:10px 12px;margin-bottom:10px}
#g-sup .sm-kv{display:flex;gap:10px;font-size:13.5px;padding:3px 0;overflow-wrap:anywhere}
#g-sup .sm-kv span{flex:none;width:44px;color:var(--muted);text-transform:uppercase;font-size:11px;font-weight:800;letter-spacing:.05em;padding-top:2px}
#g-sup .sm-kv b{flex:1;min-width:0;font-weight:600}
#g-sup .sm-acts{display:flex;flex-wrap:wrap;gap:7px;margin:12px 0 4px}
#g-sup .sm-act{flex:0 1 auto;min-height:var(--tap,44px);display:inline-flex;align-items:center;gap:6px;padding:0 13px;
  border:1px solid var(--line);border-radius:99px;background:var(--surface,#fff);color:var(--ink);
  font:inherit;font-size:13.5px;font-weight:800;cursor:pointer;-webkit-appearance:none;appearance:none}
#g-sup .sm-act .ic{width:18px;height:18px}
#g-sup .sm-act.danger{color:var(--red)}
#g-sup .sm-atts{margin:12px 0}
#g-sup .sm-att{display:flex;align-items:center;gap:10px;width:100%;box-sizing:border-box;min-height:var(--tap,44px);
  padding:10px 12px;margin-bottom:7px;border:1px solid var(--line);border-radius:12px;
  background:var(--surface,#fff);color:var(--ink);font:inherit;text-align:left;cursor:pointer;-webkit-appearance:none;appearance:none}
#g-sup .sm-att .ic{flex:none;width:20px;height:20px;color:var(--sm-accent)}
#g-sup .sm-att-tx{flex:1;min-width:0}
#g-sup .sm-att-tx b{display:block;font-size:14.5px;font-weight:700;overflow-wrap:anywhere}
#g-sup .sm-att-tx small{display:block;font-size:12px;color:var(--muted)}
#g-sup .sm-att-dl{flex:none;color:var(--muted);display:inline-flex}
#g-sup .sm-att-row{cursor:default}
/* THE MESSAGE BODY KEEPS ITS OWN COLOURS, in both themes. An email is a document somebody else
   authored: forcing a dark background under markup that assumes white makes half of real-world mail
   (dark text on transparent, white logos, table borders) unreadable. So the frame sits on a white
   card in dark mode too — which is what every mail client on a phone does — and only the CHROME
   around it follows the theme. */
#g-sup .sm-bodywrap{background:#fff;border:1px solid var(--line);border-radius:13px;overflow:hidden}
#g-sup .sm-frame{display:block;width:100%;border:0;min-height:140px;background:#fff}
#g-sup .sm-pre{white-space:pre-wrap;word-break:break-word;font-size:13.5px;line-height:1.5;
  background:var(--sunk,#f4f7fa);border:1px solid var(--line);border-radius:10px;padding:10px;margin:0}

/* ---- "Seen by" (company mailboxes only; renders nothing when the payload has no read_by) ---- */
#g-sup .sm-seen{margin:0 0 10px}
#g-sup .sm-seen-b{display:flex;align-items:center;gap:7px;width:100%;box-sizing:border-box;min-height:var(--tap,44px);
  padding:6px 12px;border:1px dashed var(--line);border-radius:12px;background:transparent;color:var(--muted);
  font:inherit;font-size:13px;font-weight:700;text-align:left;cursor:pointer;-webkit-appearance:none;appearance:none}
#g-sup .sm-seen-b .ic{width:16px;height:16px;flex:none}
#g-sup .sm-seen-b>span:nth-child(2){flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#g-sup .sm-seen-c{flex:none;display:inline-flex}
#g-sup .sm-seen-b.open .sm-seen-c{transform:rotate(180deg)}
#g-sup .sm-seen-l{padding:8px 4px 2px}
#g-sup .sm-seen-r{display:flex;align-items:center;gap:9px;padding:6px 0;border-bottom:1px solid var(--line)}
#g-sup .sm-seen-r:last-child{border-bottom:0}
#g-sup .sm-seen-r b{flex:1;min-width:0;font-size:14px;font-weight:700;color:var(--ink);overflow-wrap:anywhere}
#g-sup .sm-seen-r small{flex:none;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}

/* ---- composer ---- */
#g-sup .sm-bar-cmp .sm-cmp-title{font-size:16px;font-weight:800;padding-left:2px}
#g-sup .sm-send{flex:none;min-height:var(--tap,44px);display:inline-flex;align-items:center;gap:7px;padding:0 15px;
  border:0;border-radius:99px;background:var(--grad-primary,linear-gradient(90deg,#005080,#0a6bb0));color:#fff;
  font:inherit;font-size:14px;font-weight:800;cursor:pointer}
#g-sup .sm-send .ic{width:18px;height:18px}
#g-sup .sm-send.retry{background:var(--red)}
#g-sup .sm-cmp{padding-bottom:20px}
#g-sup .sm-from-line{font-size:13px;color:var(--muted);padding:2px 2px 10px}
#g-sup .sm-from-line b{color:var(--ink);font-weight:700}
#g-sup .sm-draft{background:rgba(15,157,88,.1);color:#0b6b3d;border:1px solid rgba(15,157,88,.28);
  border-radius:11px;padding:9px 12px;font-size:13.5px;font-weight:700;margin-bottom:10px;display:flex;align-items:center;gap:7px}
#g-sup .sm-draft .ic{width:17px;height:17px}
[data-theme="dark"] #g-sup .sm-draft{background:#10301f;color:#7fd6a4;border-color:#1d5638}
#g-sup .sm-f{display:block;margin-bottom:9px}
#g-sup .sm-f>span{display:block;font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-bottom:4px}
#g-sup .sm-f>input{width:100%;box-sizing:border-box;min-height:var(--tap,44px);padding:10px 12px;font:inherit;font-size:16px;
  border:1px solid var(--line);border-radius:12px;background:var(--surface,#fff);color:var(--ink);-webkit-appearance:none;appearance:none}
/* Recipient chips. */
#g-sup .sm-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px}
#g-sup .sm-chips:empty{display:none}
/* ⚠ ONE LINE, ELLIPSISED — MEASURED at 390: a 58-character address with overflow-wrap:anywhere broke
   mid-word into three ragged lines inside the pill, which is the today-strip failure wearing a
   different shape. Gmail truncates the chip and keeps the whole address on the tooltip/title; the ✕
   is flex:none so it can never be the thing that gets squeezed out. */
#g-sup .sm-chipx{display:inline-flex;align-items:center;gap:6px;max-width:100%;padding:4px 5px 4px 4px;
  border-radius:99px;background:rgba(10,107,176,.12);color:var(--ink);font-size:13.5px;font-weight:700}
/* Gmail's chip leads with the identity disc — same generator as every other avatar here. */
#g-sup .sm-av-chip{width:24px;height:24px;font-size:10px;flex:none}
#g-sup .sm-chipx-t{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-chipx button{flex:none;width:26px;height:26px;border:0;border-radius:50%;background:rgba(3,43,73,.12);
  color:var(--ink);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0}
#g-sup .sm-chipx button .ic{width:13px;height:13px}
/* 16px on every field is not a style choice: iOS Safari and several Android WebViews ZOOM the page
   when a focused input is under 16px, and a zoomed composer on a 360px screen scrolls sideways. */
#g-sup .sm-body{width:100%;box-sizing:border-box;min-height:200px;padding:12px;font:inherit;font-size:16px;line-height:1.5;
  border:1px solid var(--line);border-radius:12px;background:var(--surface,#fff);color:var(--ink);
  resize:vertical;-webkit-appearance:none;appearance:none}
#g-sup .sm-ccbtn{min-height:var(--tap,44px);padding:0 12px;margin-bottom:9px;border:1px solid var(--line);border-radius:99px;
  background:transparent;color:var(--sm-accent);font:inherit;font-size:13.5px;font-weight:800;cursor:pointer}
#g-sup .sm-attbar{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0}
#g-sup .sm-attbar .sbtn{min-height:var(--tap,44px)}
#g-sup .sm-sugg{background:var(--surface,#fff);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 12px 28px rgba(10,18,38,.18);padding:5px;margin:-4px 0 9px;max-height:44vh;overflow-y:auto}
#g-sup .sm-sugg-row{display:flex;align-items:center;gap:10px;width:100%;box-sizing:border-box;min-height:var(--tap,44px);
  text-align:left;padding:6px 8px;border:0;border-radius:9px;background:transparent;color:var(--ink);font:inherit;cursor:pointer}
#g-sup .sm-sugg-row>span{flex:1;min-width:0}
#g-sup .sm-sugg-row b{display:block;font-size:14.5px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-sugg-row small{display:block;font-size:12.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#g-sup .sm-saved{text-align:center;font-size:12.5px;font-weight:700;color:var(--muted);margin-top:10px;min-height:16px}

/* ---- Gmail parity, round 2 (claude/field-mail-gmail) — the list dressing, the morphing bars, the
   popover menus and the reader pills. Everything paints from the same tokens as the block above, so
   the dark redefinitions on #g-sup reach all of it with no per-class dark rules. ---- */
/* Gmail's small section label over the rows ("Primary" → the folder name here). */
#g-sup .sm-seclabel{font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);padding:2px 4px 8px}
/* The blue unread dot beside the time — the second unread signal Gmail's right column carries. */
#g-sup .sm-dot{flex:none;width:9px;height:9px;border-radius:50%;background:var(--sm-accent)}
/* The red Draft marker on a row that owns a half-written reply. --red is dark-safe (tokens block). */
#g-sup .sm-draftmark{flex:none;color:var(--red,#c62828);font-weight:800;font-size:13.5px}
/* Mailbox bundles — Gmail's category rows, one per OTHER readable mailbox. */
#g-sup .sm-bundle{display:flex;align-items:center;gap:12px;width:100%;box-sizing:border-box;min-height:var(--tap,44px);
  background:var(--sunk,#eef2f7);border:1px dashed var(--line);border-radius:14px;margin-bottom:8px;
  padding:10px 12px;cursor:pointer;font:inherit;font-size:16px;text-align:left;color:var(--ink);
  -webkit-appearance:none;appearance:none}
#g-sup .sm-bundle .sm-who{font-weight:800}
#g-sup .sm-bn{flex:none;font-size:12px;font-weight:800;border-radius:99px;padding:3px 10px;font-variant-numeric:tabular-nums}
#g-sup .sm-bn.c0{background:rgba(42,125,82,.14);color:#1e6b44}
#g-sup .sm-bn.c1{background:rgba(224,161,6,.16);color:#8a5c00}
#g-sup .sm-bn.c2{background:rgba(10,107,176,.14);color:var(--sm-accent)}
[data-theme="dark"] #g-sup .sm-bn.c0{background:rgba(72,187,120,.16);color:#7fd6a4}
[data-theme="dark"] #g-sup .sm-bn.c1{background:rgba(224,161,6,.18);color:#f0cf9a}
/* Borderless icon buttons for the morphing bars (top-bar icons never carry card chrome in Gmail). */
#g-sup .sm-ic-bare{border-color:transparent;background:transparent}
/* The reader's head actions, appended beside moreShell's ‹ Back inside .th-head. */
#g-sup .sm-headacts{margin-left:auto;display:flex;gap:0;flex:none}
/* The ⋮ popover and the emoji strip. Above the drawer (95), below the toast (100). */
#g-sup .sm-pop-ov{position:fixed;inset:0;z-index:97;background:rgba(3,20,36,.18)}
#g-sup .sm-pop{position:absolute;top:104px;right:12px;min-width:200px;background:var(--surface,#fff);
  border:1px solid var(--line);border-radius:14px;box-shadow:0 14px 34px rgba(3,18,34,.28);
  padding:6px;display:flex;flex-direction:column}
#g-sup .sm-pop-b{display:flex;align-items:center;gap:10px;min-height:var(--tap,44px);padding:6px 12px;
  border:0;border-radius:10px;background:transparent;color:var(--ink);font:inherit;font-size:14.5px;font-weight:700;
  text-align:left;cursor:pointer;-webkit-appearance:none;appearance:none}
#g-sup .sm-pop-b .ic{width:18px;height:18px;color:var(--sm-accent);flex:none}
#g-sup .sm-pop-b.danger,#g-sup .sm-pop-b.danger .ic{color:var(--red)}
#g-sup .sm-emostrip{flex-direction:row;gap:2px;min-width:0;padding:5px}
#g-sup .sm-emo{width:var(--tap,44px);height:var(--tap,44px);border:0;border-radius:12px;background:transparent;
  font-size:24px;line-height:1;cursor:pointer;padding:0}
/* The reader footer: Reply / Reply all / Forward as BIG pills sharing the row, the emoji react
   round beside them — Gmail's bottom anatomy. */
#g-sup .sm-acts-gm{flex-wrap:nowrap;gap:8px;margin:14px 0 4px}
/* nowrap, MEASURED: "Reply all" at flex-basis 0 wrapped to two lines inside its own pill at 390 —
   the pills share the row by flexing on auto instead, and under 375px the pill icons yield so the
   three labels + the react button still fit a 360 screen without the row scrolling. */
#g-sup .sm-acts-gm .sm-act-pill{flex:1 1 auto;justify-content:center;min-height:48px;font-size:14.5px;
  padding:0 10px;white-space:nowrap}
#g-sup .sm-react{flex:0 0 auto;width:48px;min-height:48px;justify-content:center;padding:0;border-radius:99px}
@media (max-width:374px){#g-sup .sm-acts-gm .sm-act-pill .ic{display:none}}
/* Compose: the icon-only send plane (Gmail's), and the reply-type switcher chip on the To row. */
#g-sup .sm-send-ic{width:var(--tap,44px);padding:0;justify-content:center;border-radius:12px}
#g-sup .sm-rtype{display:inline-flex;align-items:center;gap:6px;min-height:var(--tap,44px);padding:0 12px;
  margin:0 0 9px;border:1px solid var(--line);border-radius:99px;background:var(--surface,#fff);color:var(--ink);
  font:inherit;font-size:13.5px;font-weight:800;cursor:pointer;-webkit-appearance:none;appearance:none}
#g-sup .sm-rtype .ic{width:16px;height:16px;color:var(--sm-accent)}
#g-sup .sm-rtype .ic:last-child{color:var(--muted)}

/* Motion, house rule (DESIGN-SYSTEM §7): press feedback on every control, sheets that rise, a FAB
   that answers the finger — CSS only, and nothing that moves for its own sake. */
@media (prefers-reduced-motion: no-preference){
  #g-sup .sm-chip,#g-sup .sm-ic,#g-sup .sm-pill,#g-sup .sm-row,#g-sup .sm-act,#g-sup .sm-att,
  #g-sup .sm-box,#g-sup .sm-fold,#g-sup .sm-fab,#g-sup .sm-sugg-row,#g-sup .sm-star,#g-sup .sm-send,
  #g-sup .sm-recent,#g-sup .sm-from-tx{
    transition:transform var(--press-ms,.09s) ease-out,border-color var(--t-fast,.16s) var(--ease,ease),
      background var(--t-fast,.16s) var(--ease,ease),color var(--t-fast,.16s) var(--ease,ease),
      filter var(--t-fast,.16s) var(--ease,ease)}
  #g-sup .sm-chip:active,#g-sup .sm-ic:active,#g-sup .sm-pill:active,#g-sup .sm-row:active,
  #g-sup .sm-act:active,#g-sup .sm-att:active,#g-sup .sm-box:active,#g-sup .sm-fold:active,
  #g-sup .sm-sugg-row:active,#g-sup .sm-star:active,#g-sup .sm-send:active,#g-sup .sm-recent:active,
  #g-sup .sm-from-tx:active{transform:scale(var(--press-scale,.97));filter:var(--press-dim,brightness(.97))}
  #g-sup .sm-fab:active{transform:scale(.92)}
  #g-sup .sm-row.swiping{transition:none}
  #g-sup .sm-row:not(.swiping){transition:transform .2s cubic-bezier(.2,.8,.2,1)}
  #g-sup .sm-swipe{transition:opacity .12s linear}
  #g-sup .sm-seen-c,#g-sup .sm-from-2 .ic{transition:transform var(--t-fast,.16s) var(--ease,ease)}
  #g-sup .sm-drawer{animation:smfade var(--t-fast,.16s) var(--ease,ease)}
  #g-sup .sm-drawer-card{animation:smrise .22s cubic-bezier(.2,.8,.2,1)}
  /* The nav drawer slides in from its own edge; the bottom-sheet rise stays for the text viewer. */
  #g-sup .sm-nav .sm-drawer-card{animation:smslide .22s cubic-bezier(.2,.8,.2,1)}
  #g-sup .sm-undo{animation:smrise .2s cubic-bezier(.2,.8,.2,1)}
  #g-sup .sm-selbar{animation:smfade .14s linear}
  #g-sup .sm-pop-ov{animation:smfade var(--t-fast,.16s) var(--ease,ease)}
  #g-sup .sm-pop{animation:smpop .16s cubic-bezier(.2,.8,.2,1)}
  #g-sup .sm-bundle,#g-sup .sm-selchip,#g-sup .sm-rtype,#g-sup .sm-pop-b,#g-sup .sm-emo{
    transition:transform var(--press-ms,.09s) ease-out,border-color var(--t-fast,.16s) var(--ease,ease),
      background var(--t-fast,.16s) var(--ease,ease),color var(--t-fast,.16s) var(--ease,ease),
      filter var(--t-fast,.16s) var(--ease,ease)}
  #g-sup .sm-bundle:active,#g-sup .sm-selchip:active,#g-sup .sm-rtype:active,#g-sup .sm-pop-b:active,
  #g-sup .sm-emo:active{transform:scale(var(--press-scale,.97));filter:var(--press-dim,brightness(.97))}
  @keyframes smfade{from{opacity:0}to{opacity:1}}
  @keyframes smrise{from{transform:translateY(14px)}to{transform:translateY(0)}}
  @keyframes smslide{from{transform:translateX(-26px)}to{transform:translateX(0)}}
  @keyframes smpop{from{transform:translateY(-6px) scale(.98);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}
}
/* ── THE 44px FLOOR IN FIELD MODE'S CHROME ───────────────────────────────────────────────────────
   Three controls MEASURED live at 390x844 and 360x800 — every More sub-screen, Today, the post
   sheet and the field-report sheet — all under the house --tap:44px floor (guard.css :root, ~2059):

     · .th-back   35px tall.  The "‹ Back" / "‹ Close" chip. moreShell() puts it on EVERY More
       sub-screen, and openPost / openFieldReport put the same class on both full-screen sheets, so
       this is the most-tapped control on the entire Field-mode surface and the only way out of a
       screen for anyone whose handset has no back gesture.
     · #s-clock   32px  ·  #s-exit   39px.  One rule, .sclock, styles both. #s-break (.sbreak,
       [hidden] off duty) shares it and is fixed with them — which is the outcome we want, because
       Break is the pill that appears mid-shift, taken one-handed, often in a moving vehicle.

   THE OVERLAY, NOT A RESIZE. The controls keep the painted size the header rhythm and the sub-screen
   title row were designed around, and grow an invisible, centred hit area instead. Growing the
   paint would re-space a 360px header that already carries a title, a clock pill, a break pill and
   an exit button. This is the same trick guard.css section 5 uses on every small chip and
   .gtk-hist-lnk uses above.

   width:100% UNDER min-width, never a flat width:var(--tap). Both controls are WIDER than they are
   tall: a 44px-wide overlay would clamp the band of bought-back height to the middle 44px and still
   miss at the ends of a ~90px pill — "fixed" at the centre probe, missing at the corner probes.

   var(--tap,44px) WITH the fallback, like everything else in this file: --tap is declared in
   guard.css, not here, so the bare form is one stylesheet-load accident away from a 0px hit area.

   ⚠ MEASURED, so nobody re-derives it: width:100% on an absolutely positioned child resolves
   against its containing block's PADDING box, so on .th-back — the one of the two that has a
   border — the overlay is the chip's 64.8px minus its 1px border either side = 62.8px, not 64.8px.
   The hit box measured live is 65x44 (the chip itself carries the painted band, the overlay carries
   the height), which clears the floor with 18px of width to spare, so this is a note and not a bug.
   Do not "fix" it with a calc() that hardcodes the border width of a rule 960 lines up.

   No [data-theme="dark"] twin, on purpose — the overlay paints nothing, so there is nothing to
   re-colour. It is a hit target, not a chip. */
#g-sup .th-back::after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:100%;min-width:var(--tap,44px);height:var(--tap,44px)}
#g-sup .sclock::after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:100%;min-width:var(--tap,44px);height:var(--tap,44px)}
/* ── THE 44px FLOOR IN FIELD MODE'S FORMS ────────────────────────────────────────────────────────
   ⚠ THERE ARE TWO OF THESE BLOCKS AT THE TRAIN. claude/sup-tap-floor (c4e07e6, unmerged) adds its
   own foot block titled "THE 44px FLOOR IN FIELD MODE'S CHROME", covering .th-back and the .sclock
   header pills. It is DISJOINT from this one — chrome there, forms here — and the merge must keep
   BOTH blocks and BOTH halves of test/sup-tap-floor.test.js. Taking one side of that file silently
   deletes the other branch's proof.

   MEASURED live, headless Chromium against this worktree, 390x844 and 360x800, elementFromPoint
   walked out from each control's centre until it stops answering (the "hit box" numbers below are
   that reach, not a guess at what the CSS ought to produce):

     · #an-send   painted 362x36 (332x36 at 360), hit box 120x36.9 — 2 of the 8 probes on the 44px
       square landed on the button; the other 6 fell through to #sv-more. "Post announcement" on
       More › Announce, straight off the bare `#g-sup .sbtn` baseline (padding:9px 14px, 13.5px).
     · #tkh-back  the same 362x36 / 120x36.9 / 2-of-8. "‹ Back to my tasks" on
       More › My tasks › History — and moreShell() REPLACES the screen, so this button is the only
       way out of that panel. A missed tap here is a supervisor stuck.
     · #an-pin    a 17x17 checkbox in a 17px-tall inline-styled label: hit box 73.5x23.9, 1 of 8,
       and TWO of the seven misses landed on #an-send below it. The failure mode there is not
       "nothing happens", it is POSTING THE ANNOUNCEMENT while reaching for the priority tick.
       After: 71.9x44.9 and 5 of 8 — the three that still miss are the LEFT column of the square,
       which hangs 11px off the left edge of a label whose checkbox starts at x=0, and they land on
       inert page background. That is the geometry of every .in-ck row in this file, not something
       specific to this one; the announcement button is out of reach either way, which was the
       actual defect.
     · #fr-all    ⚠ NOT actually under the floor, and the record should say so: measured 8-of-8
       with an 88.5x61.4 hit box at both widths, because the .fr-toggle card happens to be 61px
       tall — two lines of copy plus 12px padding. The floor there is a coincidence of the wording,
       not a property of the row: with one line of copy the card is 45px, the top-aligned checkbox
       centres at y=23.5, and the bottom of its 44px square falls outside the card. min-height plus
       a centred checkbox column turns that coincidence into a guarantee. The only pixel that moves
       is the checkbox itself, 5.5px down into the middle of the card; the card and the other 20
       controls on that sheet measure byte-identical to the stock run.

   AFTER, same probes, same two widths: #an-send and #tkh-back are 362x44 painted / 120x44.9 hit /
   8 of 8 (332 wide at 360). #fr-all stays 8 of 8. Nothing on any of the three screens scrolls
   sideways and no neighbouring control is swallowed at either width.

   THE PAINTED RAISE, NOT AN OVERLAY, for the two buttons. They sit last-ish in a vertical form
   flow with nothing beside them, so 8px of extra height costs nothing and reads as a more
   confident primary action; an invisible overlay would be the wrong tool where the paint is free
   to grow. This is the house form for a form-flow button and there are ~14 of them already in this
   file — .in-sec .sbtn.wfull (the rule this one mirrors), .fr-alt .sbtn, .in-foot .sbtn,
   .gtk-foot>.sbtn. The overlay belongs to CHROME, where the rhythm is fixed; that is the other
   block's job.

   PER-INSTANCE, NOT A BASELINE RAISE. `#g-sup .sbtn` is worn by row actions, card footers, ghost
   buttons and toolbar chips all over this shell; raising the baseline to 44px would re-space every
   one of them, and none of those was measured. Two ID selectors have a blast radius of two.

   display:flex WITH the min-height, never min-height alone — a taller box with a static label
   leaves the text glued to the top edge, which looks like a rendering bug rather than a big button.

   #an-pin IS A MARKUP FIX, in supervisor.js, not a rule here: the label now wears .in-ck, the house
   checkbox row 340 lines up, which already carries the floor, the flex centring and the 22px
   appearance:none box. ⚠ THE HIT SURFACE IS THE LABEL — a click anywhere on a label toggles its
   input. Never grow the INPUT instead: an input sized past its row gets clipped straight back out
   of hit-testing by that row, which is the trap officer-ui-house-layer documents.

   var(--tap,44px) WITH the fallback, like everything else in this file: --tap is declared on :root
   in guard.css, never here, so a bare var(--tap) is one stylesheet-load-order accident away from a
   0px floor. */
#g-sup #an-send,#g-sup #tkh-back{min-height:var(--tap,44px);display:flex;align-items:center;justify-content:center}
/* Overrides align-items:flex-start and the input's margin-top:1px on the base rules ~760 lines up.
   Those two lined the box up with the first line of text; centred, the 44px square around the
   checkbox is inside the card whatever the copy does. The card grows by nothing at today's copy
   (it already measures 61px) — this is a floor, not a resize. */
#g-sup .fr-toggle{min-height:var(--tap,44px);align-items:center}
#g-sup .fr-toggle input{margin-top:0}
