/* M&S Depot Service - phone first. House colours from the monitor so the two look like one tool. */
:root{
  --nv:#1F3864; --nvink:#1F3864; --bl:#2A78D6; --brand:#055578;
  --ink:#12203a; --ink2:#41506B; --ink3:#76839B;
  --line:#D9E2F0; --line2:#EDF1F7; --light:#F2F5FA; --card:#fff; --pg:#EEF2F8; --grid:#E3EAF4;
  --red:#B1000E; --redbg:#FAE7E8; --amber:#B06A10; --amberbg:#FBEEDC; --grn:#1A7F37; --grnbg:#E8F4EC;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --sans:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0;background:var(--pg);color:var(--ink);font:15px/1.5 var(--sans);-webkit-text-size-adjust:100%}
#app{max-width:560px;margin:0 auto;min-height:100vh;background:var(--card)}
.top{background:var(--nv);color:#fff;padding:12px 15px;display:flex;align-items:center;gap:10px;position:sticky;top:0;z-index:5}
.mark{width:28px;height:28px;border-radius:50%;background:#fff;flex:none;object-fit:contain;padding:1px;box-sizing:border-box}
.top .who{flex:1;min-width:0}
.top b{font-size:14.5px;letter-spacing:.05em;text-transform:uppercase;display:block;line-height:1.15}
.top span{font-size:9px;letter-spacing:.15em;text-transform:uppercase;color:#B9C8E2;display:block;margin-top:1px}
.top button{background:none;border:1px solid #46567a;color:#B9C8E2;border-radius:6px;padding:6px 9px;font:700 9.5px/1 var(--sans);letter-spacing:.08em;text-transform:uppercase}
.live{background:var(--light);padding:8px 15px;font:11.5px/1 var(--mono);color:var(--ink2);border-bottom:1px solid var(--line);display:flex;gap:8px;align-items:center}
.dot{width:8px;height:8px;border-radius:50%;background:var(--grn);flex:none}
.dot.old{background:var(--amber)}
.strip{display:flex;border-bottom:1px solid var(--line)}
.strip div{flex:1;min-width:0;padding:12px 10px 12px 12px;border-right:1px solid var(--line2)}
.strip div:last-child{border-right:0}
.strip b{display:block;font:700 21px/1 var(--sans);color:var(--nvink);font-variant-numeric:tabular-nums}
.strip span{display:block;font:9.5px/1.3 var(--mono);letter-spacing:.07em;text-transform:uppercase;color:var(--ink3);margin-top:4px}
.today{padding:10px 15px;font:12px/1 var(--mono);border-bottom:1px solid var(--line);display:flex;justify-content:space-between;gap:10px}
.today.bad{background:var(--redbg);color:var(--red)} .today.good{background:var(--grnbg);color:var(--grn)}
h2{margin:0;padding:14px 15px 6px;font:700 10px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;color:var(--ink3);display:flex;justify-content:space-between;align-items:baseline}
h2 i{font-style:normal;color:var(--ink2);letter-spacing:0;font-size:11px}
/* E2, one handed. They read this standing next to a van holding a scanner, so a row is 44px of target
   rather than 28px and the numbers are big enough to take in without stopping. It costs about two rows of
   screen, which is the trade he accepted on 11-09-2026. */
.row{display:flex;align-items:center;gap:10px;padding:13px 15px;border-bottom:1px solid var(--line2);min-height:48px}
.rt{font-family:var(--mono);font-weight:700;color:var(--nvink);width:38px;flex:none;font-size:15.5px}
/* A commit time is five characters where a route number is three, so it gets its own width. Without this
   the time ran into the count beside it: "00:359 left". */
.rt.hm{width:54px}
.mid{flex:1;min-width:0;font-size:13.5px;color:var(--ink2)}
.mid u{text-decoration:none;color:var(--ink);font-weight:600}
.v{font-family:var(--mono);font-size:13.5px;flex:none;text-align:right;font-variant-numeric:tabular-nums}
.hot{color:var(--red);font-weight:700} .warm{color:var(--amber);font-weight:700} .cool{color:var(--ink3)}
.bar{flex:1;height:11px;border-radius:6px;background:var(--grid);overflow:hidden;min-width:40px}
.bar i{display:block;height:100%;background:var(--grn)}
/* A bar that is behind must not be green. These were written in a preview and never in the app, so the
   week bar rendered green while the figure beside it was under target and coloured amber. */
.bar i.amb{background:var(--amber)} .bar i.red{background:var(--red)}
.flag{width:7px;height:7px;border-radius:50%;background:var(--red);flex:none}
.flag.sp{background:transparent}
.calm{padding:16px 15px;text-align:center;color:var(--grn);font-size:13px;font-weight:600;border-bottom:1px solid var(--line2)}
.det{flex:1;min-width:0;font-size:12px;line-height:1.45;color:var(--ink2)}
.det u{text-decoration:none;color:var(--red);font-weight:700}
.det em{font-style:normal;color:var(--ink3)}
.qb{flex:none;width:92px;border:1px solid var(--nvink);background:var(--card);color:var(--nvink);border-radius:7px;
  padding:12px 4px;font:700 10.5px/1.25 var(--sans);letter-spacing:.03em;text-align:center;cursor:pointer;min-height:46px}
.qb[disabled]{cursor:default}
.qb.raised{border-color:var(--amber);color:var(--amber);background:var(--amberbg)}
.qb.confirmed{border-color:var(--grn);color:var(--grn);background:var(--grnbg)}
.qb.rejected{border-color:var(--line);color:var(--ink3);background:var(--light)}
.qb.station{border-color:var(--amber);color:var(--amber);background:var(--light)}   /* S54: a station miss, decided, standing against the depot */
/* Launch review item 56, 13-09-2026: the date a query was confirmed, on its own line under the pill's words. */
.qb em{display:block;font-style:normal;font-weight:600;font-size:10px;letter-spacing:0;margin-top:2px;font-variant-numeric:tabular-nums}
/* sheets */
.sheet{position:fixed;inset:0;background:rgba(18,32,58,.45);display:grid;place-items:end center;z-index:20}
.sheet>div{background:var(--card);width:100%;max-width:560px;border-radius:14px 14px 0 0;padding-bottom:10px;max-height:88vh;overflow:auto}
.sh{padding:15px 15px 8px;border-bottom:1px solid var(--line2)}
.sh b{display:block;color:var(--nvink);font-size:15px}
.sh span{display:block;color:var(--ink3);font-size:12px;font-family:var(--mono);margin-top:3px}
.opt{display:flex;align-items:center;gap:11px;padding:15px;border-bottom:1px solid var(--line2);font-size:14px;cursor:pointer;min-height:52px}
.opt i{width:16px;height:16px;border-radius:50%;border:2px solid var(--line);flex:none}
.opt.on i{border-color:var(--nv);background:var(--nv);box-shadow:inset 0 0 0 3px var(--card)}
.act{margin:12px 15px 4px;display:block;width:calc(100% - 30px);border:1px solid var(--nv);background:var(--nv);
  color:#fff;border-radius:9px;padding:15px;font:700 13.5px/1 var(--sans);letter-spacing:.04em;text-align:center;cursor:pointer;min-height:50px}
.act.ghost{background:var(--card);color:var(--ink2);border-color:var(--line)}
.act[disabled]{opacity:.55;cursor:default}
/* closed and sign in */
.mid-screen{padding:86% 24px 0;text-align:center}
.mid-screen.open{padding-top:86%}
.mid-screen .mk{display:block;width:auto;max-width:210px;height:auto;margin:0 auto 14px}
.mid-screen h1{margin:0 0 8px;font-size:21px;color:var(--nvink)}
.mid-screen h1.caps{margin-bottom:0}
.mid-screen p{margin:0;font-size:13.5px;color:var(--ink2)}
.mid-screen .hrs{font-family:var(--mono);font-size:13px;color:var(--ink);margin-top:20px;padding-top:16px;border-top:1px solid var(--line2);line-height:1.8}
.mid-screen .hrs b{font-size:16px;color:var(--nvink);display:block}
/* S51, 14-09-2026: the evening's ranking on the closed screen. Best first, the top depot crowned, a tap opens the day's
   figures under a card; the confetti canvas covers the screen for three seconds and takes no taps. */
.mid-screen.podium{text-align:left;padding:22px 16px 0}
.podium .pd-kicker{font:700 10.5px/1 var(--mono);letter-spacing:.18em;color:var(--ink3);text-transform:uppercase;margin-bottom:8px}
.podium .pd-kicker span{white-space:nowrap}   /* S75: a date never breaks inside itself */
.podium h1.caps{margin-bottom:4px;font-size:22px}
.podium .pd-cong{margin:0 0 14px;font-size:14.5px;line-height:1.35;color:var(--grn);font-weight:700;opacity:0;transition:opacity .45s ease}
.podium .pd-cong.on{opacity:1}
.podium .pd-cong.yours{color:var(--nvink)}
/* Audit 22-09-2026, L6: under reduced motion the congratulations line appears at once, without its fade, as the race's leader's
   tag did (the race is gone, S72). */
@media (prefers-reduced-motion:reduce){.podium .pd-cong{transition:none}}
.podium .hrs{text-align:center}
/* S65, THE WINNERS FILM (public/film.js). The rules below, to the end marker, are the edge page's FILM_CSS byte for byte (a test holds them identical). */
.wf{--wf-t:#12203a;--wf-mut:#5c6b86;--wf-line:#D9E2F0;--wf-chip:#F2F5FA;--wf-fig:#0b7593;--wf-up:#1A7F37;--wf-down:#B1000E;display:block;position:relative}
@media (prefers-color-scheme:dark){.wf{--wf-t:#F2F5FA;--wf-mut:#8A97B0;--wf-line:#233049;--wf-chip:#0f1623;--wf-fig:#17a2c9;--wf-up:#5BD98A;--wf-down:#FF7A72}}
.wf-stage{position:relative;width:100%;max-width:430px;margin:0 auto;aspect-ratio:9/16;min-height:300px;max-height:min(720px,calc(100vh - 190px));max-height:min(720px,calc(100svh - 190px));overflow:hidden;background:#E9EEF4;container-type:inline-size;cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}
.wf-video,.wf-end{position:absolute;left:0;top:0;width:100%;height:100%;object-fit:cover;display:block}
.wf-end{z-index:1}
.wf-load{position:absolute;left:0;right:0;bottom:46%;z-index:1;text-align:center;font:500 2.6cqw/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.08em;color:#6A778A}
.wf.wf-ready .wf-load{display:none}
.wf-head{position:absolute;left:0;right:0;top:0;z-index:2;padding:4.4cqw 6cqw 9cqw;pointer-events:none;text-align:left;background:linear-gradient(180deg,rgba(246,248,251,.92),rgba(246,248,251,.6) 58%,rgba(246,248,251,0))}
.wf .wf-head .wf-kick{margin:0;padding:0;font:600 2.45cqw/1.3 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.2em;text-transform:uppercase;text-indent:0;text-align:left;color:#4E5C70}
.wf .wf-head .wf-title{margin:1.2cqw 0 0;padding:0;font:800 6.2cqw/1.02 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;letter-spacing:.05em;text-transform:uppercase;text-indent:0;text-align:left;color:#1F3864}
.wf .wf-head .wf-cong{margin:1.6cqw 0 0;max-width:none;font-size:3.1cqw;line-height:1.3;text-align:left;text-wrap:balance}
.wf-win{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:14cqw 6cqw 5.6cqw;pointer-events:none;text-align:left;background:linear-gradient(0deg,rgba(248,250,252,.9),rgba(248,250,252,.72) 56%,rgba(248,250,252,0));opacity:0;visibility:hidden;transition:opacity .35s ease,visibility 0s linear .35s}
.wf.wf-won .wf-win{opacity:1;visibility:visible;transition:opacity .35s ease}
.wf-top,.wf-o{-webkit-appearance:none;appearance:none;margin:0;border:0;font:inherit;color:inherit;text-align:left;cursor:pointer;pointer-events:auto;-webkit-tap-highlight-color:transparent}
.wf-top{display:block;width:100%;padding:0;background:none}
.wf-top:focus-visible,.wf-o:focus-visible{outline:2px solid #17a2c9;outline-offset:2px}
.wf-top[aria-expanded="true"] .wf-nm{text-decoration:underline;text-decoration-thickness:.5cqw;text-underline-offset:1.4cqw}
.wf-eyb{display:flex;align-items:center;gap:2cqw;font:700 2.45cqw/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.24em;text-transform:uppercase;color:#8A6612}
.wf-eyb i,.wf-o i{flex:none;font-style:normal;border-radius:50%;display:grid;place-items:center;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-weight:800;letter-spacing:0;color:#1B2433}
.wf-eyb i{width:6.2cqw;height:6.2cqw;font-size:3.4cqw;background:radial-gradient(circle at 34% 28%,#FFFFFF 0,#E7C45E 46%,#B88A22 100%);box-shadow:inset 0 0 0 .4cqw rgba(255,255,255,.45)}
.wf-nm{display:block;margin-top:1.6cqw;font:900 15.5cqw/.86 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;letter-spacing:.005em;text-transform:uppercase;color:#1F3864;white-space:nowrap;text-shadow:0 .4cqw 3cqw rgba(255,255,255,.85);transform:scale(1.5);transform-origin:0 100%;opacity:0;filter:blur(2cqw);transition:transform .55s cubic-bezier(.18,1.35,.3,1),opacity .25s ease,filter .45s ease}
.wf.wf-won .wf-nm{transform:none;opacity:1;filter:none}
.wf-sc{display:flex;align-items:baseline;gap:3cqw;margin-top:1.2cqw;opacity:0;transform:translateY(3cqw);transition:opacity .35s ease .18s,transform .6s cubic-bezier(.16,.9,.2,1) .18s}
.wf.wf-won .wf-sc{opacity:1;transform:none}
.wf-pc{font:800 11.5cqw/1 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-variant-numeric:tabular-nums;letter-spacing:.005em;color:#A37A14;text-shadow:0 .4cqw 2.4cqw rgba(255,255,255,.8)}
.wf-ld{font:600 3.3cqw/1.25 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;color:#1F3864}
.wf-you{display:inline-block;margin-left:1.4cqw;vertical-align:.3cqw;font:700 1.95cqw/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.16em;color:#fff;background:#1F3864;border-radius:1.1cqw;padding:.9cqw 1.4cqw .8cqw}
.wf-oth{display:flex;gap:2.4cqw;margin-top:3.2cqw;opacity:0;visibility:hidden;transform:translateY(2.4cqw);transition:opacity .4s ease,transform .6s cubic-bezier(.16,.9,.2,1),visibility 0s linear .4s}
.wf.wf-rest .wf-oth{opacity:1;visibility:visible;transform:none;transition:opacity .4s ease,transform .6s cubic-bezier(.16,.9,.2,1)}
.wf-o{flex:1;min-width:0;display:flex;align-items:center;gap:1.4cqw;padding:1.8cqw;border-radius:2.6cqw;background:rgba(255,255,255,.95);box-shadow:0 1cqw 3.4cqw rgba(14,26,43,.14);color:#1F3864}
.wf-o[aria-expanded="true"]{box-shadow:0 0 0 .5cqw #1F3864,0 1cqw 3.4cqw rgba(14,26,43,.14)}
.wf-o i{width:5.6cqw;height:5.6cqw;font-size:3cqw}
.wf-o.r2 i{background:radial-gradient(circle at 34% 28%,#FFFFFF 0,#DCE2EA 46%,#9AA6B6 100%)}
.wf-o.r3 i{background:radial-gradient(circle at 34% 28%,#FFFFFF 0,#E0AA82 46%,#A5673D 100%)}
.wf-o span{display:block;min-width:0}
.wf-o b{display:block;font:800 3cqw/1.1 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;letter-spacing:.02em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-o small{display:block;font:500 2.5cqw/1.2 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;color:#5A6572;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-o .wf-you{display:inline-block;margin:.6cqw 0 0}
.wf-o em{margin-left:auto;font:800 3.3cqw/1 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-style:normal;font-variant-numeric:tabular-nums;white-space:nowrap}
.wf-o em.none{font-size:2.5cqw;font-weight:600;color:#5A6572}
.wf-chips{display:flex;gap:8px;margin:12px 0 0}
.wf-chips.one{justify-content:center}
.wf-chips.one .wf-chip{flex:0 1 220px}
.wf-chip{flex:1 1 0;min-width:0;display:flex;align-items:center;gap:8px;padding:9px 10px;border-radius:12px;border:1px solid var(--wf-line);background:var(--wf-chip);color:var(--wf-t);text-align:left}
.wf-chip.r1{border-color:var(--wf-fig)}
.wf-chip i{flex:none;width:22px;height:22px;border-radius:50%;display:grid;place-items:center;font:700 12px/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-style:normal;color:#0B1016;background:#C9A227}
.wf-chip.r2 i{background:#8A97B0}
.wf-chip.r3 i{background:#B08968}
.wf-chip span{display:block;min-width:0}
.wf-chip b{display:block;font-size:12.5px;font-weight:700;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-chip small{display:block;font-size:11px;line-height:1.3;color:var(--wf-mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-chip em{display:block;font-style:normal;font-weight:700;font-size:16px;line-height:1.2;color:var(--wf-fig);font-variant-numeric:tabular-nums;white-space:nowrap}
.wf-chip em.none{font-size:11px;font-weight:600;color:var(--wf-mut)}
.wf-chip.mine b{text-decoration:underline;text-underline-offset:3px}
@media (max-width:345px){.wf-chips{gap:6px}.wf-chip{gap:5px;padding:9px 5px}.wf-chip i{width:18px;height:18px;font-size:11px}.wf-chip em{font-size:14px}}
.wf-det{margin:10px 0 0;padding:10px 12px;border-radius:12px;border:1px solid var(--wf-line);background:var(--wf-chip);color:var(--wf-t);text-align:left}
.wf-det[hidden]{display:none}
.wf-dh b{display:block;font:700 10px/1.3 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.14em;text-transform:uppercase;color:var(--wf-mut)}
.wf-dh strong{display:block;font-size:22px;line-height:1.1;font-weight:700;color:var(--wf-fig);font-variant-numeric:tabular-nums;white-space:nowrap}
.wf-dh strong.none{font-size:14px;color:var(--wf-mut)}
.wf-dh span{display:block;margin-top:2px;font-size:12px;line-height:1.3;color:var(--wf-mut)}
.wf-tr{font-style:normal;font-size:13px;margin-left:6px;vertical-align:3px}
.wf-tr.up{color:var(--wf-up)}.wf-tr.down{color:var(--wf-down)}
.wf-det dl{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 12px;margin:8px 0 0;padding-top:6px;border-top:1px solid var(--wf-line);font-size:12px;line-height:1.3}
.wf-det dt{color:var(--wf-mut)}
.wf-det dd{margin:0;text-align:right;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
.wf-say{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}
.wf-hint{margin:10px 0 0;text-align:center;font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--wf-mut)}
.wf-hint span{white-space:nowrap}
.wf.wf-now,.wf.wf-now *{transition:none!important}
@media (prefers-reduced-motion:reduce){.wf,.wf *{transition:none!important}}
/* S70: the week so far under a weekday's result, in the page's own ground; it fades in when the chips land */
.wf-wk{margin:14px 16px 0;padding:10px 12px 8px;border:1px solid var(--wf-line);border-radius:12px;background:var(--wf-chip);color:var(--wf-t);text-align:left;opacity:0;transition:opacity .6s ease .2s}
.wf-rest .wf-wk{opacity:1}
.wf-reduced .wf-wk{transition:none}
.wf-wh{display:flex;justify-content:space-between;align-items:baseline;gap:8px;flex-wrap:wrap}
.wf-wh b{font:700 10.5px/1.3 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.16em;text-transform:uppercase}
.wf-wh span{font:10.5px/1.3 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--wf-mut);white-space:nowrap}
.wf-wr{display:grid;grid-template-columns:22px minmax(0,1fr) auto auto;align-items:center;gap:4px 9px;width:100%;margin:0;padding:8px 0;border:0;border-top:1px solid var(--wf-line);background:none;color:inherit;font:inherit;text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent}
.wf-wh + .wf-wr{margin-top:8px}
.wf-wr:focus-visible{outline:2px solid var(--wf-fig);outline-offset:2px;border-radius:6px}
.wf-wm{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;font-style:normal;font-weight:800;font-size:12px;color:#1B2433;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}
.wf-wm.r1{background:radial-gradient(circle at 34% 28%,#FFFFFF 0,#E7C45E 46%,#B88A22 100%)}
.wf-wm.r2{background:radial-gradient(circle at 34% 28%,#FFFFFF 0,#DCE2EA 46%,#9AA6B6 100%)}
.wf-wm.r3{background:radial-gradient(circle at 34% 28%,#FFFFFF 0,#E0AA82 46%,#A5673D 100%)}
.wf-wd{min-width:0}
.wf-wd b{display:block;font-size:13px;font-weight:800;letter-spacing:.02em;text-transform:uppercase;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-wd small{display:block;font-size:11px;line-height:1.3;color:var(--wf-mut);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-wd .wf-you{margin-left:4px;font-size:8.5px;padding:2px 4px;border-radius:3px;vertical-align:1px}
.wf-wt{font:600 10.5px/1.2 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--wf-mut);white-space:nowrap}
.wf-wt.up{color:var(--wf-up)} .wf-wt.down{color:var(--wf-down)}
.wf-wr em{font-style:normal;font-weight:800;font-size:17px;color:var(--wf-fig);font-variant-numeric:tabular-nums;white-space:nowrap;min-width:52px;text-align:right}
.wf-wr em.none{font-size:11px;font-weight:600;color:var(--wf-mut)}
.wf-wb{grid-column:2 / -1;height:3px;border-radius:2px;background:var(--wf-line);overflow:hidden}
.wf-wb i{display:block;height:100%;background:var(--wf-fig);border-radius:2px}
.wf-wl{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:4px;margin:2px 0 8px;padding:8px 6px;border-radius:10px;background:var(--wf-line)}
.wf-wl[hidden]{display:none}
.wf-wc{display:grid;justify-items:center;gap:4px;text-align:center}
.wf-wc small{font:600 9.5px/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;letter-spacing:.08em;text-transform:uppercase;color:var(--wf-mut)}
.wf-wc i{width:11px;height:11px;border-radius:50%;background:var(--wf-fig)}
.wf-wc.won i{box-shadow:0 0 0 2px var(--wf-chip),0 0 0 4px #B88A22}
.wf-wc.todo i,.wf-wc.void i{background:none;border:1.5px dashed var(--wf-mut)}
.wf-wc b{font:700 11px/1.2 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--wf-t);font-variant-numeric:tabular-nums;white-space:nowrap}
.wf-wc.todo b,.wf-wc.void b{font-weight:500;color:var(--wf-mut)}
.wf-wf{margin:6px 0 0;font-size:11px;line-height:1.4;color:var(--wf-mut)}
/* end of the film rules */
/* S65: THE WINNERS FILM on the closed screen. The film bleeds to the edges of the app as the race did; the chips alone, the hint
   and a depot's rows keep the page's side margin. Over the picture the congratulations keep the app's own colours (the light wash
   stays light in the dark theme, so the colours stay the light theme's). */
.podium .pd-film{margin:4px -16px 0}
.podium .pd-film .wf-chips,.podium .pd-film .wf-hint,.podium .pd-film .wf-det{margin-left:16px;margin-right:16px}
.wf .wf-head .pd-cong{color:#1A7F37;font-weight:700}
.wf .wf-head .pd-cong.yours{color:#1F3864}
form{padding:0 24px 24px;max-width:340px;margin:0 auto}
label{display:block;font:700 9.5px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;color:var(--ink3);margin:14px 0 6px;text-align:left}
/* S82, 07-10-2026: 16px, not 15px. An iPhone zooms in on a box whose text is under 16px when it is tapped, and stays zoomed: Pedro's
   profile opened cut at the left after Choose your password (his video of 10:46). .qline input was already 16px for the same reason. */
input{width:100%;border:1px solid var(--line);border-radius:8px;padding:12px;font:16px/1 var(--sans);background:var(--card);color:var(--ink)}
input:focus{outline:2px solid var(--bl);outline-offset:1px}
.err{color:var(--red);font-size:12.5px;margin-top:12px;min-height:18px}
/* The IRIS screens. The eye is painted on a canvas behind everything and the words sit below it: the padding
   is a share of the WIDTH, because a percentage padding always is, which is what put the words inside the eye
   the first time. 86% of the width clears the eye on every phone shape we care about. */
.drift{position:absolute;left:0;right:0;top:0;height:100%;width:100%;display:block;pointer-events:none;z-index:0}
#app{position:relative}
.mid-screen{position:relative;z-index:1}
.mid-screen .irismk{display:block;margin:0 auto 12px}
.mid-screen .word{font-size:25px;font-weight:600;letter-spacing:.44em;text-indent:.44em;color:var(--nvink)}
.mid-screen .slog{margin-top:9px;font:600 9px/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;color:#17a2c9}
.mid-screen h1.caps{margin-top:26px;font-size:15px;font-weight:700;letter-spacing:.24em;color:var(--ink)}
.mid-screen .step{margin-top:14px;font:9.5px/1 var(--mono);letter-spacing:.18em;text-transform:uppercase;color:var(--ink3)}
.mid-screen .track{width:132px;height:2px;background:var(--line2);border-radius:2px;margin:16px auto 0;overflow:hidden}
.mid-screen .track .bar{height:100%;width:0;background:#17a2c9;transition:width .42s ease}
.foot{position:relative;z-index:1}
form{position:relative;z-index:1}
.foot{padding:18px 15px 26px;text-align:center;font:10.5px/1.6 var(--mono);color:var(--ink3)}

/* The first sign in, where he replaces the password he was handed. Less top padding than the other mid
   screens because this one carries a form as well as the mark, and 86% of the WIDTH plus a form runs off
   the bottom of a small phone. */
.mid-screen.setpass{padding-top:58%}
/* Launch review item 4, 13-09-2026. The eye centres itself at 30% of its canvas height and sizes itself from
   it too, so on this screen the canvas is kept short and the eye sits higher, clear of the small mark above
   IRIS: at 390 wide the lower lid ends near 193px against the mark at 226px, and at 360 near 178px against
   209px. Scaled with the width, as the 58% above is. */
.drift.low{height:min(110vw,440px)}
.hint{margin-top:8px;font:11.5px/1.45 var(--sans);color:var(--ink3);text-align:left;min-height:17px}
.hint.ok{color:var(--grn)}
.row2{display:flex;gap:10px;margin-top:14px}
.row2 .act{margin:0;flex:1;width:auto;padding:10px 8px;font-size:13px}


/* ---------------------------------------------------------------------------------------------------
   E3, dark. Follows whatever the phone is already set to, because these are early starts in a dark yard
   and a white screen at five in the morning is unpleasant to look at.

   Only the tokens change. Every component above is painted through them, which is why this is short.
   The three colours that carry meaning, red amber green, are LIGHTENED rather than reused: the light
   theme's #B1000E on a dark ground is unreadable, and a failure has to be readable first. --------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --nv:#141D2B; --nvink:#8FD6EC; --bl:#4DA3FF; --brand:#17a2c9;
    --ink:#E6EDF3; --ink2:#A9B6C4; --ink3:#77869A;
    --line:#26313D; --line2:#202932; --light:#18212C; --card:#111922; --pg:#0B1016; --grid:#253040;
    --red:#FF7A72; --redbg:#2B1618; --amber:#E3A54B; --amberbg:#2B2112; --grn:#5BD98A; --grnbg:#11281B;
  }
  :root:not([data-theme="light"]) .top{border-bottom:1px solid #26313D}
  :root:not([data-theme="light"]) .top span{color:#8FA2B8}
  :root:not([data-theme="light"]) .top button{border-color:#33415A;color:#A9B6C4}
  :root:not([data-theme="light"]) .act{color:#0B1016;background:#8FD6EC;border-color:#8FD6EC}
  :root:not([data-theme="light"]) .act.ghost{background:var(--card);color:var(--ink2);border-color:var(--line)}
  :root:not([data-theme="light"]) .opt.on i{box-shadow:inset 0 0 0 3px var(--card);background:var(--nvink);border-color:var(--nvink)}
  :root:not([data-theme="light"]) .sheet{background:rgba(2,6,12,.62)}
  :root:not([data-theme="light"]) .bar i{background:var(--grn)}
  /* Launch review item 10, 13-09-2026: the rule above outranks .bar i.red and .bar i.amb, so a row marked
     late or past its commit carried a green bar in dark mode. The two fills that mean behind get the same
     weight back. */
  :root:not([data-theme="light"]) .bar i.amb{background:var(--amber)}
  :root:not([data-theme="light"]) .bar i.red{background:var(--red)}
}

/* ---------------------------------------------------------------------------------------------------
   Wave two, 12-09-2026. A4 a route opens its own screen, B2 one tap says the driver has been rung,
   C3 the week against his target, E1 the last board when there is no signal. --------------------- */
.row.tap{cursor:pointer}
.row.tap:active{background:var(--light)}
.row.tap:focus-visible{outline:2px solid var(--bl);outline-offset:-2px}
.top .back{background:none;border:1px solid #46567a;color:#fff;border-radius:8px;width:34px;height:34px;
  flex:none;font:400 22px/1 var(--sans);padding:0 0 3px}
.chip{flex:none;border-radius:999px;padding:9px 12px;font:700 9.5px/1 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;border:1px solid;min-height:36px;cursor:pointer}
/* NOT .act. That class already exists on this page and means the full width primary button, so a chip
   carrying it inherited width:calc(100% - 30px) and came out 330px wide inside a 390px row, squeezing the
   text beside it to nothing and pushing the board 28px past the edge of the phone. */
.chip.go{background:var(--nv);color:#fff;border-color:var(--nv)}
.chip.done{background:var(--grnbg);color:var(--grn);border-color:var(--grn);cursor:default}
.chip[disabled]{opacity:.55;cursor:default}
.rowpad{padding:14px 15px 4px;display:flex}
.rowpad .chip{flex:1;text-align:center;padding:15px 12px;min-height:50px;font-size:11px}
.cap{padding:14px 15px 4px;font:700 9.5px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;color:var(--ink3)}
.live.off{background:var(--redbg);color:var(--red)}
/* Item 15, 14-09-2026: the status words can run to a second line once the reader has stopped, so the words keep a
   line height of their own inside the one line bar. */
.live .said{line-height:1.45}
.live .said .part{white-space:nowrap}
.dot.off{background:var(--red)}
/* E1: a board that came out of the phone rather than off the wire says so by looking spent. */
.live.off ~ .strip b,.live.off ~ .strip span{opacity:.62}
.live.off ~ .row,.live.off ~ .today{opacity:.62}
/* Launch review item 7, 13-09-2026: the rest of a kept board looks spent too. The heading figures and their
   pills, the words under the strip's figures, the day tape and what sits open inside a box were still at
   full strength beside a red No signal line. Opacity, not colour, so the pill rules, light or dark, cannot
   undo it. */
.live.off ~ .strip em,.live.off ~ .tape,.live.off ~ h2 i,.live.off ~ .premopen,.live.off ~ .premlate,.live.off ~ .calm{opacity:.62}
/* Launch review item 34, 13-09-2026: a reading 5 to 15 minutes old turns the whole line amber, in the house
   amber ink on the amber ground (.live.prev), not only the dot. */
.live.old{background:var(--amberbg);color:#6B4108}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chip.go{background:var(--nvink);color:#0B1016;border-color:var(--nvink)}
  :root:not([data-theme="light"]) .top .back{border-color:#33415A}
  :root:not([data-theme="light"]) .live.old{background:var(--amberbg);color:var(--amber)}
}
.rt.good{color:var(--grn)} .rt.mid{color:var(--amber)} .rt.bad{color:var(--red)}
/* Launch review item 16, 13-09-2026. mid is the amber figure here and also the flexible column's class
   (.mid, flex:1), so an amber week figure took half the row and wrapped "Premium  ·  target 98.5". The
   figure keeps its own width; the amber stays. */
.row .rt{flex:none}

/* ---------------------------------------------------------------------------------------------------
   Wave three, 12-09-2026. His calls: the premiums as the extension shows them but ratioed to the phone,
   tapping one opens what is still out on it, and brought back comes off the strip.

   Every rule below paints a component that already exists on the dashboard. Nothing here is a new look.
   ------------------------------------------------------------------------------------------------ */

/* The day tape. The hour labels live on the scale underneath, not on the dots: four commits inside the
   first quarter of a 07:00 to 20:00 tape put four labels inside 65px of each other at phone width, and on
   the dashboard the same guard is 50px because the panel is three times wider. */
.tape{padding:12px 15px 10px;border-bottom:1px solid var(--line)}
.tcap{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:11px;gap:10px}
.tcap b{font:700 9.5px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;color:var(--ink3)}
.tcap em{font-style:normal;font:11px/1 var(--mono);color:var(--ink2);white-space:nowrap}
.track{position:relative;height:14px}
.trule{position:absolute;left:0;right:0;top:5px;height:3px;border-radius:3px;background:var(--grid)}
.tdone{position:absolute;left:0;top:5px;height:3px;border-radius:3px;background:var(--bl)}
.ttick{position:absolute;top:2px;width:1px;height:9px;background:var(--line)}
.tier{position:absolute;top:0;display:block;transform:translateX(-50%)}
.tier i{width:9px;height:9px;border-radius:50%;display:block;border:2px solid var(--card);box-sizing:content-box}
.tier.met i{background:var(--grn)}
.tier.miss i{background:var(--red)}
.tier.ahead i{background:var(--card);box-shadow:inset 0 0 0 2px var(--ink3)}
.tier.first{transform:none}
.tier.last{transform:translateX(-100%)}
.tnow{position:absolute;top:-3px;width:2px;height:19px;background:var(--nvink)}
.tscale{display:flex;justify-content:space-between;font:10px/1 var(--mono);color:var(--ink3);margin-top:6px}

/* A premium commit. The bar sits in a COLUMN here, not in the row, so it must be told to keep its height:
   .bar is written flex:1 for the route rows where it sits along the row, and flex:1 in a column makes it
   grow along the wrong axis and render as a hairline. That is not hypothetical, it happened in the
   preview for this screen and the check in test-app.js is there so it cannot happen again unseen. */
.barw{flex:1;min-width:0}
.blab{display:flex;justify-content:space-between;gap:8px;font-size:12px;color:var(--ink3);margin-bottom:6px}
.blab.bad{color:var(--red)}
.blab span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* display:block as well as the height. .bar is a span, and height does nothing to an inline box. In the
   route rows it never mattered because the row is a flex container and blockifies its children; here the
   parent is a plain div, so the span stayed inline and the bar rendered as nothing at all. */
.barw .bar{display:block;flex:none;width:100%;height:9px;min-width:0}
.row.prem{cursor:pointer}
.row.prem:active{background:var(--light)}
.row.prem:focus-visible{outline:2px solid var(--bl);outline-offset:-2px}
.row.prem.past{background:var(--redbg)}
.row.prem.past .bar{background:#F0C9CC}
.chev{flex:none;width:12px;text-align:right;color:var(--ink3);font:13px/1 var(--sans)}
.chev.bad{color:var(--red)}

/* What opens underneath a commit. A shaded well so it reads as belonging to the row above it rather than
   as three more rows of the board. */
/* premopen, not open. M4, audit of 12-09-2026: .open already belonged to the opening screen and this rule
   painted a grey box over the eye there. Same for .step below, now .hstep. */
.premopen{background:var(--light);border-bottom:1px solid var(--line)}
.premopen .row{border-bottom:1px solid var(--line)}
.premopen .row:last-of-type{border-bottom:0}
.premopen .calm{border-bottom:0}
/* Scoped to .open, because .cap is also the plain label above the route screen's chase row and that one
   has nothing on its right to push away from. Without the flex the label and the figure ran together and
   the caption read "STILL TO DELIVER5 stops on 3 routes". */
.premopen .cap{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
.cap em{font-style:normal;letter-spacing:0;text-transform:none;font-size:11px;color:var(--ink2);font-weight:400;white-space:nowrap}
.rowpad.send{gap:9px;padding-bottom:14px}
.rowpad.share{gap:9px;padding-bottom:14px}
/* Items 19 and 11, 14-09-2026 (S42): the IRIS eye painted with the page's inks, in the status line (his option A, the
   ring circling while readings arrive), beside the logo once the reader has stopped (option C, amber, the ring three
   quarters round and still) or with no signal (option B, grey, the rule under the header grey too), and below the boxes.
   The header is white in both themes, so its eye keeps the day inks. Every animation stops under reduced motion. */
.iris .hex,.iris .lid{fill:none;stroke:var(--nvink);stroke-width:3.6;stroke-linejoin:round}
.iris .ball{fill:var(--nvink)} .iris .pup{fill:var(--brand)}
.iris .ball,.iris .pup,.iris .spin,.iris .fill,.iris .pulse{transform-box:fill-box;transform-origin:center}
.lineeye{width:20px;height:20px;flex:none;display:block}
.lineeye .hex{stroke-width:8} .lineeye .lid{stroke-width:7}
.lineeye .spin{fill:none;stroke:var(--brand);stroke-width:5;stroke-linecap:round;stroke-dasharray:60 200;opacity:0}
.live.scan .lineeye .spin{opacity:1;animation:irisspin 1.6s linear infinite}
.live.scan .lineeye .ball{animation:irisbreathe 2.8s ease-in-out infinite}
.live.old .lineeye .hex,.live.old .lineeye .lid{stroke:var(--amber)} .live.old .lineeye .ball{fill:var(--amber)} .live.old .lineeye .pup{fill:var(--amberbg)}
.live.off .lineeye .hex,.live.off .lineeye .lid{stroke:var(--ink3)} .live.off .lineeye .ball{fill:var(--ink3)} .live.off .lineeye .pup{fill:var(--card)}
.top .hdreye{width:34px;height:34px;flex:none;display:block;overflow:visible}
/* S47: scanning, the header eye pulses and breathes as the one below the boxes; the ring of C is for the stopped state. */
.top .hdreye .pulse{fill:none;stroke:#17A2C9;stroke-width:1.6;opacity:0}
.top .hdreye.scan .pulse{animation:irisring 2.6s ease-out infinite}
.top .hdreye.scan .pulse.two{animation-delay:1.3s}
.top .hdreye.scan .ball{animation:irisbreathe 2.8s ease-in-out infinite}
.top .hdreye.scan .track,.top .hdreye.scan .fill{display:none}
.top .hdreye .hex,.top .hdreye .lid{stroke:#1F3864} .top .hdreye .ball{fill:#1F3864} .top .hdreye .pup{fill:#17A2C9}
.top .hdreye .track{fill:none;stroke:#E3EAF4;stroke-width:7}
.top .hdreye .fill{fill:none;stroke-width:7;stroke-linecap:round;stroke-dasharray:100 100;transform:rotate(-90deg)}
.top .hdreye .hex{stroke-width:7} .top .hdreye .lid{stroke-width:6}
.top .hdreye.stop .hex,.top .hdreye.stop .lid{stroke:#B06A10} .top .hdreye.stop .ball{fill:#B06A10} .top .hdreye.stop .pup{fill:#FBEEDC}
.top .hdreye.stop .fill{stroke:#B06A10;stroke-dashoffset:25}
.top .hdreye.nosig .hex,.top .hdreye.nosig .lid{stroke:#9AA6B8} .top .hdreye.nosig .ball{fill:#9AA6B8} .top .hdreye.nosig .pup{fill:#fff}
.top .hdreye.nosig .fill{stroke:#9AA6B8;stroke-dashoffset:100}
.top.nosig{border-bottom-color:#9AA6B8}
.top .who .title{color:#2A78D6;font-weight:700;letter-spacing:.14em;font-size:9.5px;margin-top:1px}
.watch{display:grid;justify-items:center;gap:6px;padding:26px 15px 30px;border-bottom:1px solid var(--line2)}
.watch svg{width:92px;height:92px}
.watch .pulse{fill:none;stroke:var(--brand);stroke-width:1.2;opacity:0}
.watch.scan .pulse{animation:irisring 2.6s ease-out infinite}
.watch.scan .pulse.two{animation-delay:1.3s}
.watch.scan .ball{animation:irisbreathe 2.8s ease-in-out infinite}
.watch b{font:700 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--nvink)}
.watch small{font:11px/1.4 var(--mono);color:var(--ink3);text-align:center}
.watch.stop .hex,.watch.stop .lid{stroke:var(--amber)} .watch.stop .ball{fill:var(--amber)} .watch.stop .pup{fill:var(--amberbg)} .watch.stop b{color:var(--amber)}
.watch.nosig .hex,.watch.nosig .lid{stroke:var(--ink3)} .watch.nosig .ball{fill:var(--ink3)} .watch.nosig .pup{fill:var(--card)} .watch.nosig b{color:var(--ink3)}
@keyframes irisspin{to{transform:rotate(360deg)}}
@keyframes irisbreathe{0%,100%{transform:scale(1)}50%{transform:scale(.8)}}
@keyframes irisring{0%{opacity:.55;transform:scale(.45)}100%{opacity:0;transform:scale(1.1)}}
/* S58, 19-09-2026 (his choice B, the hexagon trace, 18-09-2026): the eye that counts down to the next reading. The outline of the mark is
   the dim track (.count .hex) and the light that drains round it is .over, with a spark on its edge and one pulse when a reading lands;
   app.js (eyePaint) sets the dash and the spark once a second. Amber and a still spark once a reading is a minute late. */
.iris.count .hex{opacity:.28}
.iris .over{fill:none;stroke:var(--nvink);stroke-width:8.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:100 100;transition:stroke-dasharray 1s linear,stroke-dashoffset 1s linear}
.iris .spark{fill:var(--brand);transition:transform 1s linear}
.iris .pulsehex{fill:none;stroke:var(--brand);stroke-width:3;opacity:0;transform-box:fill-box;transform-origin:center}
.iris.count.land .over{transition:stroke-dasharray .45s ease-out,stroke-dashoffset .45s ease-out} .iris.count.land .spark{opacity:0} .iris.count.land .pulsehex{animation:irispulsehex 1.1s ease-out 1}
.iris.count.land .lid,.iris.count.land .ball,.iris.count.land .pup{transform-box:fill-box;transform-origin:center;animation:irisblink .34s ease-in-out .45s 1}
.iris.count.late .hex,.iris.count.late .lid{stroke:var(--amber)} .iris.count.late .ball{fill:var(--amber)} .iris.count.late .pup{fill:var(--amberbg)}
.iris.count.late .over{stroke:var(--amber)} .iris.count.late .spark{fill:var(--amber);animation:irislate 1.4s ease-in-out infinite}
.lineeye.count{overflow:visible} .lineeye .over{stroke-width:9}
.live.scan .lineeye.count .ball{animation:none}
.top .hdreye.count .ball{animation:none}
.top .hdreye .over{stroke:#1F3864} .top .hdreye .spark{fill:#17A2C9} .top .hdreye .pulsehex{stroke:#17A2C9}
.top .hdreye.count.late .hex,.top .hdreye.count.late .lid{stroke:#B06A10} .top .hdreye.count.late .ball{fill:#B06A10} .top .hdreye.count.late .pup{fill:#FBEEDC}
.top .hdreye.count.late .over{stroke:#B06A10} .top .hdreye.count.late .spark{fill:#B06A10}
.live .said .part.lt{color:var(--amber);font-weight:700}
/* S67, 24-09-2026, his pick of the countdown preview, C the scanner: under the header a dark strip of thirty cells goes out one by one
   towards the next reading, a small eye riding the last one lit and the seconds beside NEXT READING; a scan and a blink when a reading
   lands. The strip is an instrument and keeps its dark ground in both themes; amber when late or stopped, grey with no signal. */
.scanner{position:relative;background:#0B1628;padding:9px 15px 10px;border-bottom:1px solid #1B2C47;color:#BFE8FF}
.scanner .sc-row{display:flex;justify-content:space-between;align-items:baseline;font-family:var(--mono);font-size:10.5px;line-height:1.2;letter-spacing:.16em}
.scanner .sc-ct{font-size:14px;letter-spacing:.06em;color:#62C4FF;text-shadow:0 0 8px rgba(98,196,255,.8);font-variant-numeric:tabular-nums}
.scanner .sc-cells{position:relative;display:grid;grid-template-columns:repeat(30,1fr);gap:2px;margin-top:18px;height:9px}   /* room for the riding eye under the words, so it never touches NEXT READING */
.scanner .sc-cells i{position:relative;border-radius:1px;background:#15294A}
/* S69: each cell's light is its b, faded in and out over the second the tick sets it for, so the strip drains smoothly */
.scanner .sc-cells i b{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:1px;background:linear-gradient(#62C4FF,#2A78D6);box-shadow:0 0 6px rgba(98,196,255,.75);opacity:0;transition:opacity 1s linear}
.scanner .sc-rider{position:absolute;top:-17px;width:16px;height:16px;margin-left:-8px;transition:left 1s linear}
.scanner.land .sc-cells i b{transition:none} .scanner.land .sc-rider{transition:left .5s ease-out}
.scanner .sc-rider svg{display:block}
.scanner .sc-rider .hex,.scanner .sc-rider .lid{stroke:#BFE8FF} .scanner .sc-rider .ball{fill:#BFE8FF} .scanner .sc-rider .pup{fill:#0B1628}
.scanner .sc-scan{position:absolute;top:-3px;bottom:-3px;width:40px;left:0;opacity:0;background:linear-gradient(90deg,rgba(98,196,255,0),rgba(232,247,255,.9),rgba(98,196,255,0));pointer-events:none}
.scanner.land .sc-scan{animation:scanrun .7s ease-in .3s 1}
.scanner.land .sc-rider .lid,.scanner.land .sc-rider .ball,.scanner.land .sc-rider .pup{transform-box:fill-box;transform-origin:center;animation:irisblink .34s ease-in-out 1}   /* the blink closes on the eye's own centre, as the eyes' does */
.scanner.late,.scanner.stop{color:#F4D9A8}
.scanner.late .sc-ct,.scanner.stop .sc-ct{color:#E3A54B;text-shadow:0 0 8px rgba(227,165,75,.7)}
.scanner.late .sc-cells i,.scanner.stop .sc-cells i{background:#3A2A12}
.scanner.late .sc-rider .hex,.scanner.late .sc-rider .lid,.scanner.stop .sc-rider .hex,.scanner.stop .sc-rider .lid{stroke:#E3A54B} .scanner.late .sc-rider .ball,.scanner.stop .sc-rider .ball{fill:#E3A54B}
.scanner.off{color:#8A97AA}
.scanner.off .sc-ct{color:#8A97AA;text-shadow:none}
.scanner.off .sc-cells i{background:#1A2536}
.scanner.off .sc-rider .hex,.scanner.off .sc-rider .lid{stroke:#8A97AA} .scanner.off .sc-rider .ball{fill:#8A97AA}
@keyframes scanrun{0%{opacity:1;left:0}100%{opacity:1;left:calc(100% - 40px)}}
@media (prefers-reduced-motion:reduce){.scanner .sc-rider,.scanner .sc-cells i b{transition:none}.scanner.land .sc-scan,.scanner.land .sc-rider .lid,.scanner.land .sc-rider .ball,.scanner.land .sc-rider .pup{animation:none}}
@keyframes irispulsehex{from{opacity:.6;transform:scale(1)}to{opacity:0;transform:scale(1.2)}}
@keyframes irisblink{0%,100%{transform:scaleY(1)}50%{transform:scaleY(.08)}}
@keyframes irislate{0%,100%{opacity:.45}50%{opacity:.9}}
@media (prefers-reduced-motion: reduce){.iris *{animation:none!important}}
@media (prefers-reduced-motion: reduce){.iris .over,.iris .spark{transition:none!important}}
/* The directors' screen, item 7, 14-09-2026 (S44), his pick "screen for directors B". */
.dtiles{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:12px 15px;border-bottom:1px solid var(--line)}
.dtiles div{border:1px solid var(--line);border-radius:10px;padding:10px 9px;display:grid;gap:4px;min-width:0}
.dtiles div.warm{border-color:var(--amber);background:var(--amberbg)} .dtiles div.hot{border-color:var(--red);background:var(--redbg)}
.dtiles b{font-size:12.5px;color:var(--nvink)}
.dtiles strong{font:700 19px/1 var(--sans);color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.dtiles span{font:9.5px/1.3 var(--mono);color:var(--ink3)}
.dcap{padding:13px 15px 5px;font:700 9.5px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;color:var(--ink3);display:flex;justify-content:space-between}
.dcap em{font-style:normal;letter-spacing:0;text-transform:none;font-weight:400;font-size:10.5px;color:var(--ink2)}
.drow{display:grid;grid-template-columns:12px 1fr auto;gap:4px 10px;align-items:center;padding:11px 15px;border-bottom:1px solid var(--line2)}
.drow i{width:10px;height:10px;border-radius:50%;background:var(--grn)} .drow i.warm{background:var(--amber)} .drow i.hot{background:var(--red)}
.drow b{font-size:14px;color:var(--nvink)}
.drow .pcv{font:700 14px/1 var(--mono);color:var(--ink);font-variant-numeric:tabular-nums}
.drow small{grid-column:2 / 4;font:11px/1.45 var(--mono);color:var(--ink2)}
.need{padding:4px 15px 14px;display:grid;gap:7px}
.need p{margin:0;font-size:13px;line-height:1.4;color:var(--ink);padding-left:12px;position:relative}
.need p:before{content:'';position:absolute;left:0;top:.5em;width:5px;height:5px;border-radius:50%;background:var(--red)}
/* Items 4 and 17 of the launch day feedback, 14-09-2026: the stops that missed a commit whose time has gone, in the
   same shaded well as the routes still out above them, with the caption laid out the same way. */
.premlate{background:var(--light);border-bottom:1px solid var(--line)}
.premlate .row{border-bottom:1px solid var(--line)}
.premlate .row:last-of-type{border-bottom:0}
.premlate .cap{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
.premlate .mid{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.premlate .v.pc{color:var(--nvink);font-weight:700}
/* Item 12, 14-09-2026: a postcode is never broken across two lines, wherever it is drawn. */
.pc{white-space:nowrap;font-family:var(--mono);font-variant-numeric:tabular-nums}
.det .pc{color:var(--nvink);font-weight:700;font-size:11.5px}
/* Item 21, 14-09-2026 (S46): the tracking numbers under a failure's words, each a button that copies itself. */
.det .trkline{display:block;margin-top:3px}
.det button.trk{appearance:none;border:1px solid var(--line);background:var(--light);color:var(--nvink);border-radius:6px;padding:4px 7px;font:600 11.5px/1 var(--mono);letter-spacing:.03em;font-variant-numeric:tabular-nums;white-space:nowrap;cursor:pointer;min-height:24px}
/* S49 (phone finding 8): a 20 or 22 digit number breaks at its groups inside the column instead of running under the buttons. */
.det button.trk{white-space:normal;max-width:100%;text-align:left;line-height:1.35}
.det button.trk.did{background:var(--grnbg);color:var(--grn);border-color:var(--grn)}
/* S80: the open premiums' tracking numbers under a route in a premium time's box, the same buttons as under a failure (item 21). */
.mid .trkline{display:block;margin-top:3px}
.mid button.trk{appearance:none;border:1px solid var(--line);background:var(--light);color:var(--nvink);border-radius:6px;padding:4px 7px;font:600 11.5px/1 var(--mono);letter-spacing:.03em;font-variant-numeric:tabular-nums;cursor:pointer;min-height:24px;margin-top:3px}
.mid button.trk{white-space:normal;max-width:100%;text-align:left;line-height:1.35}
.mid button.trk.did{background:var(--grnbg);color:var(--grn);border-color:var(--grn)}
/* S79: Reopen this decision, on his board under a decided failure's words; the second tap is red. */
.det button.reo{appearance:none;border:0;background:none;margin:2px 0 0;padding:6px 0 2px;font:700 12px/1.2 var(--sans);color:var(--bl);text-decoration:underline;text-underline-offset:2px;cursor:pointer}
.det button.reo.sure{color:var(--red)}
.det button.reo[disabled]{color:var(--ink3);text-decoration:none;cursor:default}
.mid .pcs{display:block;margin-top:2px;font-size:11.5px;color:var(--nvink);font-weight:700;white-space:normal}
.mid .pcs .pc{font-size:11.5px}
.chip.gh{background:var(--card);color:var(--ink2);border-color:var(--line)}

/* The strip, three across. A number with a word under it rather than beside it, because "506 on 16 vans"
   on one line inside 130px wraps into the cell next to it. */
.strip.st3 div{padding:12px 6px 12px 13px}
.strip.st3 span{display:block;font:9.5px/1.3 var(--mono);letter-spacing:.07em;text-transform:uppercase;color:var(--ink3);margin-top:0}
.strip.st3 b{display:block;font:700 22px/1 var(--sans);color:var(--nvink);font-variant-numeric:tabular-nums;margin-top:5px}
.strip.st3 em{display:block;font:11px/1.2 var(--mono);color:var(--ink3);font-style:normal;margin-top:4px}

/* Against last week. */
.wk{display:flex;align-items:baseline;gap:10px;padding:13px 15px;border-bottom:1px solid var(--line2);min-height:46px}
.wk b{flex:1;min-width:0;font-size:13.5px;font-weight:600;color:var(--ink)}
.wk b span{font-weight:400;color:var(--ink2)}
.wk .v{font-size:13.5px}
.v.ok{color:var(--grn);font-weight:700}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .row.prem.past .bar{background:#3A1D20}
  :root:not([data-theme="light"]) .chip.gh{background:var(--card);color:var(--ink2);border-color:var(--line)}
  :root:not([data-theme="light"]) .tier i{border-color:var(--card)}
}

/* ---------------------------------------------------------------------------------------------------
   Wave four, 12-09-2026. Alerts. His picks: a commit about to go, a commit gone short and a collection
   window closing on by default, the pace one off unless a lead asks, the reader alarm to him alone.
   ------------------------------------------------------------------------------------------------ */

/* The way in, at the foot of the board. */
.row.alerts .bell{flex:none;width:22px;height:22px;border-radius:50%;background:var(--light);
  border:1px solid var(--line);position:relative}
.row.alerts .bell:after{content:'';position:absolute;left:50%;top:50%;width:7px;height:7px;margin:-3.5px 0 0 -3.5px;
  border-radius:50%;background:var(--ink3)}
.row.alerts .bell.on{background:var(--grnbg);border-color:var(--grn)}
.row.alerts .bell.on:after{background:var(--grn)}

/* A switch. Big enough to hit standing beside a van: 46 by 28 with a 56px row around it. */
.sw{display:flex;align-items:center;gap:12px;padding:13px 15px;border-bottom:1px solid var(--line2);min-height:56px}
.sw .t{flex:1;min-width:0}
.sw .t b{display:block;font-size:14px;font-weight:600;color:var(--ink)}
.sw .t span{display:block;font-size:12px;color:var(--ink3);margin-top:2px;line-height:1.4}
/* L3, audit of 12-09-2026: the pill is the indicator, the ROW is the switch, all 56px of it. */
.sw.tap{cursor:pointer}
.sw.tap:active{background:var(--light)}
.sw.tap:focus-visible{outline:2px solid var(--bl);outline-offset:-2px}
.tog{flex:none;width:46px;height:28px;border-radius:999px;background:var(--grn);border:0;padding:0;
  position:relative;transition:background .16s ease;display:block}
.tog.off{background:#C9D3E2}
.tog i{position:absolute;top:3px;left:21px;width:22px;height:22px;border-radius:50%;background:#fff;display:block;
  box-shadow:0 1px 3px rgba(0,0,0,.25);transition:left .16s ease}
.tog.off i{left:3px}
/* A rule he cannot change looks settled rather than broken: no pointer, no press state, and it does not
   fade out, because a faded switch reads as "not working" rather than as "not yours to move". */
.tog.fixed{background:#9FB4CF}
@media (prefers-reduced-motion: reduce){ .tog,.tog i{transition:none} }

.lead{padding:2px 15px 6px;font-size:13.5px;line-height:1.5;color:var(--ink2)}
.warn{padding:14px 15px;background:var(--amberbg);color:#6B4108;font-size:12.5px;line-height:1.5;
  border-bottom:1px solid var(--line)}
.warn b{display:block;font-size:13px;margin-bottom:4px;color:#5A3606}
.hstep{display:flex;gap:11px;padding:11px 15px;border-bottom:1px solid var(--line2);align-items:flex-start}
.hstep i{flex:none;width:21px;height:21px;border-radius:50%;background:var(--nv);color:#fff;
  font:700 11px/21px var(--mono);text-align:center;font-style:normal}
.hstep div{flex:1;font-size:13.5px;color:var(--ink2);line-height:1.45}
.hstep div b{color:var(--ink)}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tog.off{background:#33415A}
  :root:not([data-theme="light"]) .tog.fixed{background:#40536F}
  :root:not([data-theme="light"]) .tog i{background:#E6EDF3}
  :root:not([data-theme="light"]) .warn{background:#2B2112;color:#E3A54B;border-color:#3A2E18}
  :root:not([data-theme="light"]) .warn b{color:#F0C069}
  :root:not([data-theme="light"]) .hstep i{background:var(--nvink);color:#0B1016}
}

/* PREVIEW. His call 12-09-2026: an admin can open the app when nothing is running, to work on it. It
   takes the place of the live line rather than sitting near it, and it is amber rather than green,
   because "never a stale figure" is the rule this service was built on and a board from last Thursday
   sitting under the word "Updated" would quietly break it. */
.live.prev{background:var(--amberbg);color:#6B4108;font-weight:700;letter-spacing:.04em}
.dot.prev{background:var(--amber)}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .live.prev{background:#2B2112;color:#E3A54B}
}
/* An automatic preview session says so where Sign out would be. Not a button that does nothing: a label
   in the shape of one, so the state is visible without reading the amber line further down. */
.top .prevtag{border-color:var(--amber);color:var(--amber);opacity:1;cursor:default}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .top .prevtag{border-color:#E3A54B;color:#E3A54B}
}

/* ---------------------------------------------------------------------------------------------------
   Wave six, 12-09-2026. Chase from the phone: the depot photos one tap from Stops left, the route sheet
   with the photo about to go and the three ways to send it. His call: "same formats as my extension".
   ------------------------------------------------------------------------------------------------ */
.thumb{margin:12px 15px 4px;border:1px solid var(--line);border-radius:6px;overflow:hidden;background:#fff}
.thumb img{display:block;width:100%;height:auto}
.fine{margin:8px 15px 2px;font:11px/1.45 var(--sans);color:var(--ink3);text-align:center}
.act.small{margin-top:6px;min-height:40px;padding:11px;font-size:12px;border-color:transparent;color:var(--ink3)}
/* Launch review item 43, 13-09-2026: "Mark as chased" and "Cancel" were 40px tall, under the 44px every
   other target on this app is given. They carry no border, so the extra four pixels read as spacing. */
.act.small{min-height:44px}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .act.small{border-color:transparent;background:var(--card);color:var(--ink3)}
}

/* ---------------------------------------------------------------------------------------------------
   Wave seven, 12-09-2026, his calls the same afternoon: the dropdowns, Stops left at the top, at risk
   gone, "i dont think the font fits well to the phone screen too, can you use the smoothest format going,
   also blend the ms logo better improve the overal looks of this, keep my loading screen that i had in the
   extension on as well".

   THE TYPE. One face everywhere, the phone's own (San Francisco on an iPhone, Roboto on Android), with
   tabular figures so the numbers still line up in their columns. The monospace face is retired: it was
   chosen for alignment, and tabular figures give the alignment without the typewriter look he did not
   like. The token is redefined rather than every rule rewritten, so nothing below can miss a spot. */
:root{--mono:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}
body{font-variant-numeric:tabular-nums;-webkit-font-smoothing:antialiased}
/* Launch review item 57, 13-09-2026: tabular-nums restated after each font shorthand above, as the box
   headings do, because the shorthand resets it and the live line, the section figures, the strip's words,
   the TODAY line, the tape and the footer had lost their tabular figures. */
.live{font-size:12.5px;letter-spacing:.01em;font-variant-numeric:tabular-nums}
h2{font-size:11px;letter-spacing:.12em;font-variant-numeric:tabular-nums}
h2 i{font-size:12px;font-weight:700}
.rt{font-size:16px} .rt.hm{font-size:15px}
.v{font-size:14px} .mid{font-size:14px}
.strip span,.strip.st3 span{font-size:10px;letter-spacing:.06em}
.strip b,.strip.st3 b{font-size:23px}
.strip.st3 em{font-size:11.5px;font-variant-numeric:tabular-nums}
.today{font-size:12.5px;letter-spacing:.02em;font-weight:600;font-variant-numeric:tabular-nums}
.chip{font-size:10.5px;letter-spacing:.08em}
.cap{font-size:10.5px;letter-spacing:.12em}
.cap em{font-size:12px}
.blab{font-size:12px}
.tcap b{font-size:10.5px;letter-spacing:.12em;font-variant-numeric:tabular-nums} .tcap em{font-size:11.5px;font-variant-numeric:tabular-nums} .tscale{font-size:10.5px;font-variant-numeric:tabular-nums}
.foot{font-size:11px;font-variant-numeric:tabular-nums}
.sh span{font-size:12.5px}
.det{font-size:12.5px}
.wk b,.wk .v{font-size:14px}
.row.prem{cursor:default}
.row.prem:active{background:inherit}

/* THE HEADER. The M&S mark on white with the depot beside it and the blue rule under, the extension's own
   header, so the app and every picture it sends look like one thing. White in both themes: the mark is
   dark ink and belongs on white. */
.top{background:#fff;color:#12203a;padding:10px 15px;gap:12px;border-bottom:3px solid #2A78D6}
.top .brand{height:34px;width:auto;flex:none;display:block}
.top b{color:#1F3864;font-size:15px;letter-spacing:.04em}
.top span{color:#76839B;letter-spacing:.14em;font-size:9.5px}
.top button{border:1px solid #D9E2F0;color:#41506B;background:#fff;font-size:10px}
.top .back{border:1px solid #D9E2F0;color:#1F3864;background:#fff;font-size:22px}
.top .prevtag{border-color:#B06A10;color:#B06A10}
/* Launch review item 43, 13-09-2026. Sign out was 77 by 24 and Back 34 by 34, under the 44px target. The
   drawn buttons keep the approved header look; the area that takes the tap grows round them to 44px, which
   the 57px header already has room for. A tap on the pseudo element is a tap on the button. The offsets
   are from inside the 1px border: 22 + 22 is 44 for Sign out, 32 + 12 is 44 for Back. */
.top button{position:relative}
.top button:after{content:'';position:absolute;left:-5px;right:-5px;top:-11px;bottom:-11px}
.top .back:after{left:-6px;right:-6px;top:-6px;bottom:-6px}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .top{background:#fff;color:#12203a;border-bottom:3px solid #2A78D6}
  :root:not([data-theme="light"]) .top b{color:#1F3864}
  :root:not([data-theme="light"]) .top span{color:#76839B}
  :root:not([data-theme="light"]) .top button{border-color:#D9E2F0;color:#41506B;background:#fff}
  :root:not([data-theme="light"]) .top .back{border-color:#D9E2F0;color:#1F3864;background:#fff}
}

/* THE DROPDOWNS. A heading that is a switch: the figure on it so the number is seen without opening it,
   the chevron turning when it is open. 52px of target, like every row. */
h2.tab{cursor:pointer;justify-content:flex-start;align-items:center;gap:10px;padding:16px 15px;min-height:52px;
  background:var(--light);border-top:1px solid var(--line);border-bottom:1px solid var(--line);color:var(--ink2);margin-top:6px}
h2.tab i{margin-left:auto;color:var(--ink2)}
h2.tab i.bad{color:var(--red)}
h2.tab .chev{flex:none;width:14px;text-align:right;font:16px/1 var(--sans);color:var(--ink3);margin-left:0}
h2.tab i + .chev{margin-left:0}
h2.tab > .chev:first-of-type:last-child{margin-left:auto}
h2.tab.open{background:var(--card);border-bottom:1px solid var(--line2)}
h2.tab.open .chev{color:var(--nvink)}
h2.tab:active{background:var(--line2)}
h2.tab:focus-visible{outline:2px solid var(--bl);outline-offset:-2px}
/* 13-09-2026, the box heading as the extension's (S15). The title in the navy of the extension's box header,
   in sentence case rather than spaced capitals; the figure at the right edge beside the chevron, where it
   lines up with every other figure; and the extension's two pills round the figure only when the box asks
   for something now, red for past its time and orange for due inside 30 minutes. The title takes the free
   space, so the chevron no longer pushes the figure into the middle of the row. Grey capitals stay on the
   captions that do not open and shut: Failed today, THE DAY SO FAR, TODAY.
   tabular-nums comes after each font shorthand, because the shorthand resets it to normal and the column
   of figures would lose its tabular figures. Every figure sits in the same rounded box, clear when it is
   information, so a pill that appears on the minute update does not make its heading taller and push the
   rows below. The orange ink is the house amber ink on --amberbg (.warn, .live.prev): --amber on it is too
   faint for 14px text in daylight. */
h2.tab{text-transform:none;letter-spacing:0;font:600 15px/1.2 var(--sans);font-variant-numeric:tabular-nums;color:var(--nvink);padding-top:13px;padding-bottom:13px}
h2.tab .ttl{flex:1;min-width:0}
h2.tab i{margin-left:0;font:600 14px/18px var(--sans);font-variant-numeric:tabular-nums;color:var(--ink2);letter-spacing:0;text-transform:none;white-space:nowrap;padding:3px 10px;border-radius:999px;border:1px solid transparent}
h2.tab i.pill{font-weight:700}
h2.tab i.pill.now{color:var(--red);background:var(--redbg);border-color:rgba(177,0,14,.28)}
h2.tab i.pill.soon{color:#6B4108;background:var(--amberbg);border-color:rgba(176,106,16,.30)}
h2.tab .chev{width:18px;font:20px/1 var(--sans);text-align:center}
h2.tab > .chev:first-of-type:last-child{margin-left:0}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) h2.tab i.pill.soon{color:var(--amber)}
}
.tape{border-top:0}
/* Every caption with a figure keeps the figure at its own end of the row. The rule used to be scoped to
   the premium box, so a caption inside the Collections box read "SHUTTING IN 30 MIN2". */
.cap{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
/* Launch review item 44, 13-09-2026: the This week heading figure takes the week rows' own colours when it
   is under his target, amber within one point and red beyond it. Plain ink, not a pill: a pill asks for
   something now, and a week under target is information. */
h2.tab i.warm{color:var(--amber);font-weight:700}
h2.tab i.hot{color:var(--red);font-weight:700}
/* Launch review item 59, 13-09-2026: "Nothing finished this week yet" is a neutral note, not a success. */
.calm.plain{color:var(--ink2);font-weight:400}

/* THE LOADING SCREEN, wave eight: the extension's splash on a phone. The dark field and its grid, the IRIS
   mark and name forming, "in partnership with", the M&S mark resolving out of a blur and knocked out to
   white, the two settling together with the glow between them while the scan line crosses, then the bar. */
/* Two modes, his words 13-09-2026: "improve the loading screen can we try it 2 modes as well? one for day time
   one for dark", and on the previews, "Should follow the phones setting". app.js stamps .day or .dark on the
   screen from the phone's setting when the sequence starts. Dark keeps wave eight's field. Day is the house
   light field, the IRIS mark in its own inks, the M&S mark in its own colours with its white plate lifted off
   (app.js whiteLogo), and the scan line and the bar in the house blue. Only the tokens change between the two,
   the way the rest of this file does dark, so nothing below can be missed in one mode. The movement follows
   the previews: transform and opacity, on curves that start and end at rest, so the phone's compositor
   carries it and a busy moment (the board arriving, the mark being keyed) cannot make a step stutter. The
   stages, their timings and the length are wave eight's. */
.load{--ld-field:#12203a;--ld-grid:rgba(143,214,236,.08);--ld-ink:#EAF2FF;--ld-dot:#8FD6EC;--ld-word:#EAF2FF;
  --ld-accent:#8FD6EC;--ld-dim:rgba(234,242,255,.55);--ld-track:rgba(234,242,255,.16);--ld-bar:#8FD6EC;
  --ld-scan:#8FD6EC;--ld-scanhot:#fff;--ld-trail:rgba(143,214,236,.1);--ld-glow1:rgba(143,214,236,.32);--ld-glow2:rgba(143,214,236,.08)}
.load.day{--ld-field:#F2F5FA;--ld-grid:rgba(42,120,214,.075);--ld-ink:#0b3f5e;--ld-dot:#17a2c9;--ld-word:#0b3f5e;
  --ld-accent:#1F3864;--ld-dim:#41506B;--ld-track:#D9E2F0;--ld-bar:#2A78D6;
  --ld-scan:rgba(42,120,214,.55);--ld-scanhot:#2A78D6;--ld-trail:rgba(42,120,214,.09);--ld-glow1:rgba(255,255,255,.9);--ld-glow2:rgba(255,255,255,.45)}
.load{position:relative;z-index:1;min-height:100vh;padding:0 24px 40px;text-align:center;background:var(--ld-field);color:var(--ld-word);overflow:hidden}
.load .field{position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(var(--ld-grid) 1px,transparent 1px),linear-gradient(90deg,var(--ld-grid) 1px,transparent 1px);
  background-size:28px 28px}
/* The scan line travels on transform, not on top, so it is never laid out again mid crossing, with a faint trail
   above it so it reads as one sweep. It crosses in front of the marks: behind them the glow swallowed it, and on
   the day field the line vanished across the M&S mark altogether. */
.load:after{content:'';position:absolute;z-index:2;left:0;right:0;top:0;height:46px;opacity:0;transform:translateY(-60px);pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--ld-scan) 40%,var(--ld-scanhot) 50%,var(--ld-scan) 60%,transparent) 0 100%/100% 3px no-repeat,
    linear-gradient(180deg,transparent,var(--ld-trail)) 0 0/100% 43px no-repeat}
.load.s3:after{animation:scan 1.4s cubic-bezier(.45,0,.55,1) 1 forwards}
@keyframes scan{0%{transform:translateY(-60px);opacity:0}12%{opacity:1}88%{opacity:1}100%{transform:translateY(100vh);opacity:0}}
.load .stage{position:relative;padding-top:20vh;display:flex;flex-direction:column;align-items:center}
.load .mk{opacity:0}
.load .mk.iris{transform:translateY(16px) scale(.92);transition:opacity .9s cubic-bezier(.4,0,.2,1),transform 1.2s cubic-bezier(.16,.7,.2,1)}
.load.s1 .mk.iris{opacity:1;transform:none}
.load .mk.iris svg{display:block;margin:0 auto 12px}
.load .mk.iris svg path{stroke:var(--ld-ink)}
.load .mk.iris svg circle:nth-of-type(1){fill:var(--ld-ink)}
.load .mk.iris svg circle:nth-of-type(2){fill:var(--ld-dot)}
.load .mk.iris .word{font-size:28px;font-weight:600;letter-spacing:.44em;text-indent:.44em;color:var(--ld-word)}
.load .part{opacity:0;transform:translateY(5px);margin:24px 0 14px;font:600 10px/1 var(--sans);letter-spacing:.26em;text-transform:uppercase;color:var(--ld-accent);
  transition:opacity .9s cubic-bezier(.4,0,.2,1),transform .9s cubic-bezier(.16,.7,.2,1)}
.load.s2 .part{opacity:1;transform:none}
/* The M&S mark resolves on the extension's own curve, fast out of the blur and slow into focus. */
.load .mk.ms{position:relative;z-index:0;filter:blur(16px);transform:scale(1.1) translateY(10px);
  transition:opacity 1.1s cubic-bezier(.4,0,.2,1),filter 1.4s cubic-bezier(.16,.7,.2,1),transform 1.4s cubic-bezier(.16,.7,.2,1)}
.load .mk.ms canvas{display:block;width:min(60%,236px);height:auto;margin:0 auto;position:relative;z-index:1}
.load.s2 .mk.ms{opacity:1;filter:blur(0);transform:none}
.load .mk.ms .glow{position:absolute;left:50%;top:50%;width:260px;height:260px;margin:-130px 0 0 -130px;border-radius:50%;opacity:0;
  background:radial-gradient(circle closest-side,var(--ld-glow1) 0%,var(--ld-glow2) 55%,transparent 100%)}
/* The glow sits behind the words, never over them, so it cannot wash out the name or "in partnership with". */
.load .mk.iris,.load .part,.load .step,.load .track,.load .loadsub{position:relative;z-index:1}
/* Settling together: the IRIS mark comes down to the M&S mark and the M&S mark rises a touch to meet it, on one
   curve and one length, while the scan line crosses. */
.load.s3 .mk.iris{transform:translateY(10px) scale(.9);transition:opacity .9s cubic-bezier(.4,0,.2,1),transform 1.3s cubic-bezier(.65,0,.35,1)}
.load.s3 .mk.ms{transform:translateY(-3px);transition:opacity 1.1s cubic-bezier(.4,0,.2,1),filter 1.4s cubic-bezier(.16,.7,.2,1),transform 1.3s cubic-bezier(.65,0,.35,1)}
.load.s3 .mk.ms .glow{animation:glow 2.2s cubic-bezier(.45,0,.55,1) 1 forwards}
@keyframes glow{0%{opacity:0;transform:scale(.6)}45%{opacity:1;transform:scale(1.05)}100%{opacity:.55;transform:scale(1)}}
.load .step,.load .track,.load .loadsub{opacity:0;transform:translateY(6px);transition:opacity .6s cubic-bezier(.4,0,.2,1),transform .7s cubic-bezier(.16,.7,.2,1)}
.load .step{margin-top:30px;font:600 10.5px/1 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--ld-accent)}
/* The bar fills on transform, clipped by its track, each of its three steps easing in and out. */
.load .track{width:210px;height:5px;background:var(--ld-track);border-radius:4px;margin:14px auto 0;overflow:hidden;transition-delay:.08s}
.load .track .bar{height:100%;width:100%;transform:scaleX(0);transform-origin:0 50%;background:var(--ld-bar);transition:transform .8s cubic-bezier(.45,0,.2,1)}
.load .loadsub{margin-top:20px;font:600 10px/1.5 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--ld-dim);transition-delay:.16s}
/* Launch review item 49, 13-09-2026: the build keeps its lower case v inside a line set in capitals. */
.load .loadsub .build{text-transform:none}
.load.s4 .step,.load.s4 .track,.load.s4 .loadsub{opacity:1;transform:none}
/* Launch review item 49: the credit had a band of its own ground, and the grid stopped in a hard line along
   its top edge. It is see-through now, so the field and its grid run to the foot of the phone. */
.foot.loadcredit{position:absolute;left:0;right:0;bottom:0;z-index:1;background:transparent;color:rgba(234,242,255,.5);padding:14px 15px 24px}
.foot.loadcredit.day{color:#5C6A83}
@media (prefers-reduced-motion: reduce){
  .load .mk,.load .part,.load .step,.load .track,.load .loadsub,.load.s3 .mk.iris,.load.s3 .mk.ms{transition:none}
  .load.s3:after,.load.s3 .mk.ms .glow{animation:none}
  .load.s3 .mk.ms .glow{opacity:.55}
  .load .track .bar{transition:none}
}
/* THE PERCENTAGE INSIDE THE BAR, wave eight: as the extension's board has it, white inside the green when
   the green can hold it, green beside it when it cannot. The bar grows to 18px to carry the figure. */
.bar.pct{position:relative;height:18px;border-radius:9px;overflow:hidden}
.bar.pct i{position:relative;text-align:right;line-height:18px}
.bar.pct i b{font:700 10.5px/18px var(--sans);color:#fff;padding-right:7px;letter-spacing:.02em}
.bar.pct em{position:absolute;top:0;font:700 10.5px/18px var(--sans);color:var(--grn);font-style:normal;white-space:nowrap}
/* Launch review item 21, 13-09-2026: in dark mode the green is light, and white on it measured about 1.8 to 1.
   The figure inside the bar takes the dark ground's ink, about 10.7 to 1. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .bar.pct i b{color:#0B1016}
}
/* Launch review items 31 and 51, 13-09-2026: the Stops left figure is a column of one width, so every bar
   ends at the same point, and the route's total sits after what is left in quieter ink, "37 of 78". */
.v.rem{width:70px}
.v.rem em{font-style:normal;font-size:12px;font-weight:400;color:var(--ink3)}
/* S58, 19-09-2026: a route cleared of deliveries with collections still open reads "cleared" with "+3 coll" under it, inside the same 70px column so every bar still ends at one point. */
.v.rem em.coll{display:block;font-size:11px;line-height:1.2;white-space:nowrap}
/* Launch review item 55, 13-09-2026: the TODAY line wraps between its parts, never inside one, and a second
   line has room. The padding gives back what the line height takes, so a one line band keeps its height. */
.today{line-height:1.4;padding-top:7.5px;padding-bottom:7.5px}
.today .tparts{text-align:right}
.today .tp{white-space:nowrap}

/* ---------------------------------------------------------------------------------------------------
   Launch review item 5, 13-09-2026. Installed on an iPhone the app draws full screen under a translucent
   status bar (viewport-fit=cover and black-translucent in app.html), so the M&S mark, the depot and Sign
   out sat under the clock, and the credit line and a sheet's last button sat on the home indicator. That
   status bar writes its clock in white, so padding alone would put a white clock on the white header.
   The inset is painted instead, as a band in the theme colour the phone already uses for its bar: on the
   sticky header, so it stays when the board scrolls, and on the page itself for the screens without a
   header. The loading screen is dark already and runs under the bar as it is. Everywhere the phone
   reports no inset, env() is zero and nothing moves. ------------------------------------------------ */
#app{border-top:env(safe-area-inset-top,0px) solid var(--nv)}
#app:has(> .top),#app:has(> .load){border-top:0}
.top{border-top:env(safe-area-inset-top,0px) solid var(--nv)}
.foot{padding-bottom:calc(26px + env(safe-area-inset-bottom,0px))}
.foot.loadcredit{padding-bottom:calc(24px + env(safe-area-inset-bottom,0px))}
.sheet>div{padding-bottom:calc(10px + env(safe-area-inset-bottom,0px))}

/* ---------------------------------------------------------------------------------------------------
   Launch review, 13-09-2026, the collections and the route screen.
   ------------------------------------------------------------------------------------------------ */
/* Item 11: the route verdict in orange while a window shuts inside 30 minutes, the ink of the orange pill. */
.today.soon{background:var(--amberbg);color:#6B4108}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .today.soon{color:var(--amber)}
}
/* Item 52: an outward code is up to four characters, RM10 or EC3M, so it takes the commit time's width and
   the window beside it lines up with the commit rows above. */
.rt.pc{width:54px}
/* Item 12, 14-09-2026: the full postcode in the route screen's collection cell, its own width and a size that fits
   "IG11 8BL" beside the window at 360 wide. */
.rt.pc.full{width:78px;font-size:13px;letter-spacing:-.01em}
/* Item 37: a send that went but was not marked says so in red. */
.fine.bad{color:var(--red);font-weight:600}

/* ---------------------------------------------------------------------------------------------------
   Wave ten, 13-09-2026, sign in, loading, closed and the phone frame. His words the same day: "I want you
   to find fixes for what you flagged here ... do all the updates, do everything that you can".
   ------------------------------------------------------------------------------------------------ */
/* Launch review item 28: the holding mark in app.html, drawn before the script arrives, where the sign in and
   closed screens draw their small mark, on the phone's own light or dark ground. */
.hold{padding:86% 24px 0;text-align:center}
.hold svg{display:block;margin:0 auto 12px}
.hold .ln{fill:none;stroke:var(--nvink);stroke-width:3.6;stroke-linejoin:round}
.hold .pu{fill:var(--nvink)}
.hold .gl{fill:var(--brand)}

/* The loading screen in day mode on an installed iPhone. Its field is pale, and the status bar writes its clock in
   white, so the band item 5 paints under the clock on the sign in screen stays for the day field; the dark
   field carries the white clock as it always has. The screen gives the band's height back, so the credit still
   clears the home indicator. */
#app:has(> .load.day){border-top:env(safe-area-inset-top,0px) solid var(--nv)}
.load.day{min-height:calc(100vh - env(safe-area-inset-top,0px))}

/* Launch review items 5 and 23: the shortest screens tighten their spacing (app.js fitEntry adds .tight only
   where the screen would otherwise scroll). Every target keeps its height; only the air around them gives. */
.mid-screen.tight .irismk{width:40px;height:40px;margin-bottom:6px}
.mid-screen.tight .word{line-height:1.2}
.mid-screen.tight .slog{margin-top:6px}
.mid-screen.tight h1{margin-bottom:4px}
form.tight{padding-bottom:6px}
form.tight label{margin-top:9px}
form.tight .hint{margin-top:5px}
form.tight .row2{margin-top:9px}
form.tight .err{margin-top:6px}
form.tight .act{margin-top:8px}
form.tight .act.small{margin-top:2px}
form.tight .row2 .act{margin-top:0}
.foot.tight{padding-top:8px;padding-bottom:max(12px,calc(env(safe-area-inset-bottom,0px) + 6px))}

/* Launch review item 22: "No signal, trying again" after a first board fetch that failed. No figure, so nothing
   here is dimmed; the note sits where a board would start. */
/* S49 (phone finding 1): the screen's own class. .nosig alone is also the state class the header and its eye carry (S42, S47),
   and these rules used to reach them, so the header grew a blank band and the eye drew over the status line. */
.nosigscr{padding:18% 24px 0;text-align:center}
.nosigscr .irismk{display:block;margin:0 auto 14px}
.nosigscr p{margin:0 auto;max-width:300px;font-size:13.5px;line-height:1.5;color:var(--ink2)}
.mid-screen .again{margin-top:10px;font-size:12.5px;color:var(--ink3)}

/* Launch review item 24: the sentence under Sign out when the phone has no signal. Set on the button's own
   corner, over the line below the header, in the ink and ground of no signal. #app leads the selector so the
   header's own span rules, light and dark, cannot reach it. */
#app .top button span.say{position:absolute;right:-1px;top:calc(100% + 24px);display:block;margin:0;padding:7px 10px;
  border-radius:8px;border:1px solid var(--red);background:var(--redbg);color:var(--red);
  font:600 12.5px/1.2 var(--sans);letter-spacing:0;text-transform:none;white-space:nowrap;
  box-shadow:0 2px 8px rgba(18,32,58,.14);pointer-events:none;z-index:6}
/* And the header itself never wraps: a long name is cut with an ellipsis rather than taking a second line. */
.top .who b,.top .who span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.top button{white-space:nowrap}

/* ---------------------------------------------------------------------------------------------------
   Launch review, 13-09-2026, wave ten: rows, notes and weeks.
   ------------------------------------------------------------------------------------------------ */
/* Item 19, the remainder, staged for Claude Fable 5.1. The Collections row is one line with shorter words
   (public/app.js, the Collections box), so it keeps the spacing of every other box: the route column and the
   gaps are the rows' own again and the closing time lines up with the commit rows above it. collrow stays as
   the row's name and carries nothing but a guard that the words never wrap under the chip. */
.row.collrow .mid{white-space:nowrap}
/* Item 20: an office reference or a note with no space in it wraps inside the row rather than pushing the
   button off the edge. */
.det em{overflow-wrap:anywhere}
/* Item 20: the office reference moves to the next line whole rather than breaking at a hyphen, and breaks
   inside itself only when it is wider than the line. */
.det em .dref{display:inline-block;max-width:100%}

/* ---------------------------------------------------------------------------------------------------
   Launch review item 67, 13-09-2026, the tape's scale. The labels were spread by space-between, so their
   edges were spaced evenly and "11:00" sat under the 11:20 marker. Each label now stands at its own time:
   07:00 starts at the left end, 20:00 ends at the right end, the three between are centred on their ticks.
   The row keeps its height, so nothing under the tape moves.
   ------------------------------------------------------------------------------------------------ */
.tscale{position:relative;display:block;height:11px;line-height:11px}
.tscale span{position:absolute;top:0;transform:translateX(-50%);white-space:nowrap}
.tscale span.first{transform:none}
.tscale span.last{transform:translateX(-100%)}

/* ---------------------------------------------------------------------------------------------------
   The admin board, 13-09-2026, his calls: "lets not have stops left instead we have barking stops overview
   bristol and lcy, all 3 different tabs leave the day so far at the top looks good ... we need to have it
   separated by depots for all metrics", and "remove the idea of chasing drivers for admins". His account
   only; a lead's board never carries these classes.
   ------------------------------------------------------------------------------------------------ */
/* The day so far, three lanes on one scale. The names sit in a column of their own, so the tracks and the
   scale under them share one width and one set of percentages, and the now marker is drawn once over all
   three tracks. */
.tape.lanes .lanebody{display:flex;align-items:flex-start;gap:10px}
.tape.lanes .lanenames{flex:none;width:54px;display:flex;flex-direction:column}
.tape.lanes .lname{display:block;height:22px;font:600 12px/22px var(--sans);color:var(--ink2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tape.lanes .lname.off{color:var(--red)}
.tape.lanes .lanecol{flex:1;min-width:0}
.tape.lanes .lanestack{position:relative}
.tape.lanes .track.lane{height:22px}
.tape.lanes .track.lane .trule,.tape.lanes .track.lane .tdone{top:9.5px}
.tape.lanes .track.lane .ttick{top:6.5px}
.tape.lanes .track.lane .tier{top:4.5px}
.tape.lanes .lanestack .tnow{top:-2px;bottom:-2px;height:auto}
.tape.lanes .tscale{margin-top:6px}

/* A depot's box. The name as the heading, in the navy of every box title but a step larger, the dot at a
   glance, and the one line summary on its own line under the name so the stops left and what has gone wrong
   never squeeze beside it. The figure box and pills of the boxes inside are unchanged. */
h2.tab.depot{flex-wrap:wrap;row-gap:5px;column-gap:10px;margin-top:0;padding:14px 15px 13px;background:var(--card);
  border-top:0;border-bottom:1px solid var(--line)}
h2.tab.depot .ttl{font:700 16.5px/1.2 var(--sans);color:var(--nvink)}
h2.tab.depot .ddot{flex:none;width:10px;height:10px;border-radius:50%;background:var(--grn)}
h2.tab.depot .ddot.bad{background:var(--red)}
h2.tab.depot .dsum{flex-basis:100%;padding-left:20px;font:500 13.5px/1.4 var(--sans);font-variant-numeric:tabular-nums;color:var(--ink2)}
h2.tab.depot .dsum span,h2.tab.depot .dsum b{white-space:nowrap}
h2.tab.depot .dsum b{font-weight:600}
h2.tab.depot .dsum b.bad{color:var(--red)}
h2.tab.depot .dsum b.ok{color:var(--grn)}
h2.tab.depot.open{background:var(--light);border-bottom:1px solid var(--line)}
h2.tab.depot.noread{cursor:default}
.tape.lanes + h2.tab.depot{border-top:0}
.calm.noread{color:var(--red);font-weight:600}

/* What a depot box holds: that depot's own board, one level in. A rule down the left in the navy, so it stays
   plain whose boxes these are while he scrolls. */
.depotwell{border-left:3px solid var(--nvink);border-bottom:1px solid var(--line);padding-bottom:6px}
.depotwell > .strip{border-bottom:1px solid var(--line)}
/* The admin's raised row says who raised it and that it is decided on the panel, in the ink of the raised pill. */
.det em.raisedby{color:var(--amber);font-weight:600}

/* Item 7 on his board as well: a board kept with no signal looks spent inside the depot boxes too. The rows,
   the strip, the heading figures, the open wells and the depot summaries, as on a lead's board. */
.live.off ~ .depotwell > .row,.live.off ~ .depotwell > .strip b,.live.off ~ .depotwell > .strip span,.live.off ~ .depotwell > .strip em,
.live.off ~ .depotwell h2 i,.live.off ~ .depotwell > .premopen,.live.off ~ .depotwell > .premlate,.live.off ~ .depotwell > .calm,.live.off ~ h2.tab.depot .dsum{opacity:.62}
/* S49 (phone finding 4): the director's tiles, rows, caption and the line under them look spent too (S06, item 7). */
.live.off ~ .dtiles,.live.off ~ .drow,.live.off ~ .need,.live.off ~ .dcap{opacity:.62}
/* S49 (phone finding 11): a word in a tile (no reading, none due) is set smaller than a figure, so it stays inside the tile at 360. */
.dtiles strong.word{font-size:15px}

/* ---- Wave ten, board wording and layout from his answers of 13-09-2026 ---------------------------------------- */
/* Launch review item 33, his answer: "Cap at 99% on phone and extension (Recommended)". A route with a stop still on
   the van reads 99 at most, and its bar stops visibly short of the end: at 99 of a 150 pixel track the last pixel
   and a half hid under the track's rounded end and the bar still looked full. */
.bar.pct i.short{max-width:calc(100% - 6px)}

/* ---- wave ten, queries and alerts, 13-09-2026 ------------------------------------------------------------ */
/* Launch review item 75: the lead's optional short line under Something else. The field sits in the option
   list's own gutter, at 16px so an iPhone does not zoom the page when it takes the cursor, with the hint in the
   app's fine print under it. */
.qline{padding:4px 15px 12px;border-bottom:1px solid var(--line2)}
.qline input{font-size:16px;line-height:1.2;padding:11px 12px}
.qline .fine{margin:6px 0 0;text-align:left}
/* Item 75 on Thiago's raised row: the lead's words, quoted, in the row's plain ink under who raised it. */
.det em.words{color:var(--ink2);font-style:normal}
/* Item 76: the row a query alert named, tinted until a box or a row on the board is tapped. */
.row.linked{background:var(--amberbg);box-shadow:inset 3px 0 0 var(--amber)}

/* ---- The repair of 13-09-2026, finding screens-1, launch review item 18 ------------------------------------------
   His Failed today box on each depot: the title is held whole and the figure takes what is left, right aligned,
   breaking between its parts only (app.js holds each part whole), so "Failed today" never wraps and the figure is
   never drawn over it. Every other heading is untouched. */
h2.tab.fail .ttl{flex:none}
h2.tab.fail i{margin-left:auto;min-width:0;white-space:normal;text-align:right}
h2.tab.fail i .fp{white-space:nowrap}

/* ---- staged for Claude Fable 5.1, his answers of 13-09-2026 (the fable-pending branch) ------------------------- */
/* Launch review item 35, his answer: "Target 18:00, red once passed (Recommended)". Once 18:00 has gone, a route
   still carrying 18:00 stops has its count in red beside its red route number, as the panel paints the count. */
.mid u.bad{color:var(--red)}

/* ---- S71, PAST DAYS on his phone, the preview he approved as shown (24-09-2026): the ten working days, a day's two bands and the
   change sheet. Only what the app lacked, each colour a token, so the dark block above repaints it. The rows are .pdrow, as
   .row.prem.past is already taken by the premium rows past their commit. ---- */
h2.tab.depot .ddot.chg{background:var(--amber)}
h2.tab.depot .ddot.off{background:var(--line)}
h2.tab.depot .dsum .pdline{display:block;white-space:normal}
h2.tab.depot .dsum b.chg{color:var(--amber)}
h2.tab.depot.still{cursor:default}
h2.tab.depot.still:active{background:var(--card)}
h2.tab.depot.still .ttl{color:var(--ink3)}
h2 i.amb{color:var(--amber)}
.lead.pdlead{margin:0;padding:12px 15px;border-bottom:1px solid var(--line)}
.row.pdrow.chgd{background:var(--light)}
.row.pdrow .det u.out{color:var(--nvink)}
.row.pdrow .det em.by{color:var(--ink2)}
.row.pdrow .det em.chg{color:var(--red);font-weight:700}
.row.pdrow .det em.chg.g{color:var(--grn)}
.qb.fa{border-color:var(--red);color:var(--red)}
.qb.nf{border-color:var(--grn);color:var(--grn)}
.qb.un{border-color:var(--line);color:var(--ink3);background:var(--light)}
.flash{padding:11px 15px;font-size:13px;font-weight:600;line-height:1.45;border-bottom:1px solid var(--line)}
.flash.good{background:var(--grnbg);color:var(--grn)}
.flash.warn{background:var(--amberbg);color:var(--amber)}
.res{border-bottom:1px solid var(--line)}
.rrow{display:flex;align-items:baseline;gap:10px;padding:10px 15px;border-bottom:1px solid var(--line2);font-variant-numeric:tabular-nums}
.rrow:last-child{border-bottom:0}
.rrow .n{width:16px;flex:none;font-weight:800;color:var(--ink3)}
.rrow.first .n{color:var(--nvink)}
.rrow .nm{flex:1;min-width:0;font-weight:700;color:var(--nvink)}
.rrow .was{font-size:12px;font-weight:600;color:var(--amber);white-space:nowrap}
.rrow .pc{font-weight:800;color:var(--ink);white-space:nowrap}
.rrow .of{width:52px;flex:none;text-align:right;font-size:12px;color:var(--ink3)}
.ctx{margin:12px 15px 2px;padding:10px 12px;border-radius:8px;background:var(--amberbg);color:var(--ink2);font-size:13px;line-height:1.45}
.ctx b{color:var(--ink)}
.eff{margin:4px 15px 0;padding:11px 12px;border:1px solid var(--line);border-radius:8px;background:var(--light);font-size:13px;line-height:1.55;color:var(--ink2)}
.eff b{color:var(--ink)}
.ctx .dref{display:inline-block;max-width:100%}

/* S81, 07-10-2026: the driver profile pilot. His note once, then the level first (his choice 1A of the previews), today on his
   route, the record; the lead driver's and his row with Not him today. Gold, Silver and Watch are the level's own colours. */
:root{--dgold:#8A6100;--dgoldbg:#FBF1D4;--dgoldrim:#C9A227;--dsil:#4F5D73;--dsilbg:#EDF0F5;--dsilrim:#A3AEBF}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){--dgold:#E7C25A;--dgoldbg:#2A2312;--dgoldrim:#B8952A;--dsil:#C3CCD8;--dsilbg:#1D2531;--dsilrim:#6F7C8F}}
:root[data-theme="dark"]{--dgold:#E7C25A;--dgoldbg:#2A2312;--dgoldrim:#B8952A;--dsil:#C3CCD8;--dsilbg:#1D2531;--dsilrim:#6F7C8F}
.mid-screen.agree{padding-top:30px}
.dnote{padding:4px 20px 0;font-size:14px;line-height:1.5;color:var(--ink2)}
.dnote p{margin:10px 0}
.dnote ul{margin:6px 0 10px;padding-left:20px;color:var(--ink)}
.dnote li{margin:4px 0}
.dnote .box{padding:10px 12px;border-radius:9px;border:1px solid var(--dgoldrim);background:var(--dgoldbg);color:var(--ink)}
.dnote .box.warn{border-color:var(--amber);background:var(--amberbg)}
.dact{padding:0 0 24px}
.dlv{margin:12px 12px 6px;border:1px solid var(--line);border-radius:14px;padding:13px 14px 12px;background:var(--light)}
.dlv.gold{border-color:var(--dgoldrim);background:var(--dgoldbg)}
.dlv.silver{border-color:var(--dsilrim);background:var(--dsilbg)}
.dlv.watch{border-color:var(--amber);background:var(--amberbg)}
.dlv-h{display:flex;justify-content:space-between;align-items:baseline;gap:10px;font:700 10px/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--ink3)}
.dlv-h i{font-style:normal;letter-spacing:.02em;text-transform:none;font-size:11.5px;font-weight:600;color:var(--ink2)}
.dlv-main{display:flex;align-items:center;gap:12px;margin-top:10px}
.dlv .dmedal{flex:none}
.dlv-name{flex:1;min-width:0}
.dlv-name b{display:block;font-size:24px;font-weight:800;line-height:1.05;color:var(--ink2)}
.dlv.gold .dlv-name b{color:var(--dgold)} .dlv.silver .dlv-name b{color:var(--dsil)} .dlv.watch .dlv-name b{color:var(--amber)}
.dlv-name span{display:block;font-size:27px;font-weight:800;line-height:1.15;color:var(--ink);margin-top:2px;font-variant-numeric:tabular-nums}
.dlv-name span.sm{font-size:13px;font-weight:600;line-height:1.4;color:var(--ink2)}
.dscale{position:relative;margin:16px 0 0;height:10px;display:flex;border-radius:5px}
.dscale span{display:block;height:100%}
.dscale .w{flex:3;background:#C98A3A;border-radius:5px 0 0 5px} .dscale .s{flex:2;background:#8E9BB0} .dscale .g{flex:1;background:#C9A227;border-radius:0 5px 5px 0}
.dmark{position:absolute;top:-4px;width:18px;height:18px;border-radius:50%;background:var(--card);border:4px solid var(--ink);box-sizing:border-box}
.dscale-k{position:relative;height:16px;margin-top:5px;font:700 10px/1.4 var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--ink3)}
.dscale-k span{position:absolute;top:0;white-space:nowrap}
.dprog{margin-top:12px;height:10px;border-radius:5px;background:var(--grid);overflow:hidden}
.dprog i{display:block;height:100%;background:var(--ink3)}
.dlv-counts{display:flex;flex-wrap:wrap;gap:4px 16px;margin-top:8px;font-size:12.5px;color:var(--ink2);font-variant-numeric:tabular-nums}
.dlv .fine{margin:8px 0 0;text-align:left}
.dstrip b.amb{color:var(--amber)} .dstrip b.ok{color:var(--grn)}
.dstrip em{display:block;font-style:normal;font-size:11.5px;line-height:1.3;color:var(--ink2);margin-top:3px}
.dstrip em.amb{color:var(--amber);font-weight:600}
h2.tab.drec{margin-top:0;border-top:0}
h2.tab.drec.still{cursor:default}
.pcl{display:block;font-size:12px;font-weight:700;color:var(--nvink);letter-spacing:.02em;margin-top:2px}
.row.dfail{background:var(--amberbg);border-left:3px solid var(--amber)}
.row.dfail.confirmed,.row.dfail.station{background:var(--light);border-left-color:var(--line)}
.dstate{flex:none;max-width:104px;text-align:right;font:700 11px/1.3 var(--sans);color:var(--amber)}
.row.dfail.confirmed .dstate,.row.dfail.station .dstate{color:var(--ink2)}
.row.dfail.rejected .dstate,.row.dfail.open .dstate{color:var(--red)}
.drow2{display:flex;align-items:center;gap:10px;padding:12px 15px;border-bottom:1px solid var(--line2);flex-wrap:wrap}
.drow2 .nm{flex:1;min-width:0}
.drow2 .nm b{display:block;font-size:14.5px;font-weight:700;color:var(--nvink)}
.drow2 .nm span{display:block;font-size:12px;line-height:1.4;color:var(--ink3)}
.drow2 .lvr{flex:none;text-align:right}
.drow2 .lvr b{display:block;font-size:15px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;margin-top:3px}
.dchip{display:inline-block;border-radius:999px;padding:3px 9px;font:800 10px/1.3 var(--sans);letter-spacing:.1em;text-transform:uppercase;border:1px solid var(--line);color:var(--ink3);background:var(--light)}
.dchip.gold{color:var(--dgold);background:var(--dgoldbg);border-color:var(--dgoldrim)}
.dchip.silver{color:var(--dsil);background:var(--dsilbg);border-color:var(--dsilrim)}
.dchip.watch{color:var(--amber);background:var(--amberbg);border-color:var(--amber)}
.drow2 .nh{flex-basis:100%;margin-top:4px;border:1px solid var(--line);background:var(--card);color:var(--ink2);border-radius:8px;padding:10px;font:700 12px/1 var(--sans);letter-spacing:.03em;cursor:pointer}
.drow2 .nh.sure{border-color:var(--red);color:var(--red)}
.drow2 .nh[disabled]{opacity:.55;cursor:default}
.drow2 .nh:focus-visible{outline:2px solid var(--bl);outline-offset:2px}

/* S83, 07-10-2026: his reminders: the Alerts screen of a driver, its state, its three switches */
.dnote .dh{margin:16px 0 4px;font-size:20px;font-weight:700;line-height:1.25;color:var(--nvink)}
.donrow{display:flex;align-items:center;gap:10px;padding:13px 15px;border-bottom:1px solid var(--line);background:var(--light);color:var(--ink2);font-size:13.5px;font-weight:600}
.donrow i{width:10px;height:10px;border-radius:50%;background:var(--ink3);flex:none}
.donrow.on{background:var(--grnbg);color:var(--grn)} .donrow.on i{background:var(--grn)}
.dbox{margin:12px 15px 0;padding:11px 12px;border-radius:9px;background:var(--amberbg);border:1px solid var(--amber);font-size:13px;line-height:1.45;color:var(--ink2)}
.dsw{display:flex;align-items:center;gap:12px;padding:14px 15px;border-bottom:1px solid var(--line2)}
.dsw .t{flex:1;min-width:0}
.dsw .t b{display:block;font-size:14.5px;color:var(--ink)}
.dsw .t span{display:block;font-size:12px;line-height:1.4;color:var(--ink3);margin-top:2px}
.dtog{flex:none;min-width:58px;height:34px;border-radius:17px;border:1px solid var(--line);background:var(--light);color:var(--ink3);font:700 12px/1 var(--sans);letter-spacing:.04em;cursor:pointer}
.dtog.on{background:var(--grn);border-color:var(--grn);color:#fff}
.dtog[disabled]{opacity:.55}
.dtog:focus-visible{outline:2px solid var(--bl);outline-offset:2px}
.err.pad{padding:0 15px}

/* ---- S85 (R20), 26-10-2026: one login for two depots. The switch under the header (his option A) and the Decide sheet ---------------
   The switch is two buttons side by side, the depot on screen filled, each with the queries waiting for him in a small amber count. The
   Decide button and the raised row he decides are in the amber of a raised query; the sheet is the raise sheet's, with the lead's reason
   in a grey box above the three choices. */
.depsw{display:flex;gap:8px;padding:10px 15px;background:var(--card);border-bottom:1px solid var(--line)}
.depsw .swb{flex:1;min-width:0;display:flex;align-items:center;justify-content:center;gap:7px;border:1px solid var(--line);background:var(--card);color:var(--ink2);
  border-radius:9px;padding:10px 8px;font:700 13.5px/1.1 var(--sans);min-height:44px;box-sizing:border-box;cursor:pointer}
.depsw .swb.on{background:var(--nv);border-color:var(--nv);color:#fff}
.depsw .swb[disabled]{cursor:default;opacity:.6}
.depsw .swb b{display:inline-block;min-width:20px;padding:2px 6px;border-radius:999px;background:var(--amber);color:#fff;font-size:11px;font-weight:800;text-align:center}
.depsw .swb.on b{background:#fff;color:var(--amber)}
.depsw .swb:focus-visible{outline:2px solid var(--bl);outline-offset:2px}
.qb.decide{border-color:var(--nv);background:var(--nv);color:#fff}
.row.todecide{background:var(--amberbg);box-shadow:inset 3px 0 0 var(--amber)}
.dwhy{margin:10px 15px 0;padding:9px 11px;border-radius:9px;background:var(--light);font-size:13px;line-height:1.45;color:var(--ink2)}
.dwhy b{color:var(--ink)}
.opt small.dsub{display:block;font-size:12px;color:var(--ink3);margin-top:1px}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .depsw .swb.on{background:#8FD6EC;border-color:#8FD6EC;color:#0B1016}
  :root:not([data-theme="light"]) .depsw .swb.on b{background:#0B1016;color:var(--amber)}
  :root:not([data-theme="light"]) .qb.decide{background:#8FD6EC;border-color:#8FD6EC;color:#0B1016}
}
