/* GuyWay Fleet Operations, design system v4 (2026-09-12): 15 px base, 14 px
   tables, 28 px KPI values, 236 px rail, nothing under 12.5 px; measured
   against the vendor panel (16 px base, 14 px body, 20 px titles).
   Skin modelled on the Yelowsoft admin panel the
   dispatch team already uses: light grey page, white rounded cards with a soft
   edge, an icon rail on the left, a white top bar with the page title, KPI
   cards across the top, card titles underlined with a short yellow rule,
   status as a coloured dot and a word. Brand tokens from the GuyWay design
   system v1.3; GT Walsheim throughout. No gradients, no dark blocks. */
/* WOFF2, subset to the characters this product actually sets: Latin, the
   punctuation, the currency marks and the few symbols the interface uses.
   The three OpenType files were 150 KB compressed and are 76 KB as subset
   WOFF2, which is 74 KB off every first launch of both phone apps, on a
   connection a driver pays for by the megabyte. Regenerate with pyftsubset if
   the glyph set ever needs to grow; the OTFs stay in the repo as the source.
   Three weights ship and only three exist: asking for 600 gets Bold. */
@font-face{font-family:"GT Walsheim";src:url(brand/GT-Walsheim-Regular.woff2) format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"GT Walsheim";src:url(brand/GT-Walsheim-Medium.woff2) format("woff2");font-weight:500;font-display:swap}
@font-face{font-family:"GT Walsheim";src:url(brand/GT-Walsheim-Bold.woff2) format("woff2");font-weight:700;font-display:swap}
:root{--gw-yellow:#EAFF68;--gw-charcoal:#011E13;--gw-white:#FFFFFF;--gw-lavender:#DADDEF;--gw-mint:#61DDAA;--gw-lime:#D5EE37;--gw-sun:#FFE700;--gw-coral:#FF6742;
--c800:#0A2C1F;--c700:#16402F;--c600:#27594A;--c500:#45796A;--c400:#739A8D;--c300:#A9C1B8;--c200:#D2DFDA;--c100:#E8EFEC;--c050:#F3F7F5;--y400:#F1FF8E;--y600:#C7DC56;
--bg:#F5F7FB;--card:#FFFFFF;--panel:#F8FAF9;--tint:#EEF2F0;--fg0:#14201B;--fg:#2E3833;--fg2:#4F5A55;--fg3:#5F6964;--border:#E3E8E6;--border2:#CFD8D4;--edge:#7A847F;--hover:#F3F7F5;--sel:#E8EFEC;--row-line:#EBEFED;
--crit:#B8461F;--okfg:#1E6B4E;--chg:#4A5591;--accent:var(--gw-sun);
/* severity marks: a small bar or dot, never a fill (Michel, 12 Oct 2026, the morning check) */
--sev-crit:var(--gw-coral);--sev-warn:var(--gw-sun);--sev-ok:var(--gw-mint);
/* each status dot keeps its brand fill inside a darker ring of the same colour, so it reads on white (3:1) */
--sev-crit-ring:#D9502E;--sev-warn-ring:#B07D00;--sev-ok-ring:#1E9E6E;--sev-info-ring:#6E76B8;--sev-none-ring:var(--c400);--ring-mix:72%;
/* the rail: neutral grey, not the brand green. The console is a tool somebody
   looks at all day beside the vendor panel, and a saturated block down the left
   edge reads as decoration; grey lets the yellow marker on the current page and
   the status dots be the only colour on the screen that means anything. */
--rail:#2E3440;--rail2:#3B4252;--rail3:#4A5262;--rail-fg:#D5DAE3;--rail-fg2:#98A0AE;
--r:10px;--rs:6px;--in:24px;--ctl:36px;--ctl-sm:32px;--tab-pad:10px 0;--tab-pad-sub:7px 0;--tab-pad-sm:10px 0;--tab-gap:24px;--gap:12px;--side:236px;--top:64px;--shadow:0 1px 2px rgba(1,30,19,.05),0 4px 14px -6px rgba(1,30,19,.10);--fs:15px;--fs-sm:13.5px;--fs-xs:12.5px;--fs-lbl:11.5px;--fs-title:17px;--fs-h1:22px;--fs-kpi:28px;
--font:"GT Walsheim",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
/* The layers, bottom to top (Michel, 14 Oct 2026: the Fleet map's zoom, range
   button and legend drew over the top bar once the page was scrolled). Page
   content sits at --z-content; a map card is its own stacking context
   (isolation), so Leaflet's 400 to 1000 and the map's own legend and
   capsules stay inside the map and never meet the top bar. Sticky table
   heads, then floating buttons, then the top bar, which covers everything
   that scrolls; the rail, toasts, the command bar and account menu, sheets
   and modals sit above it; a map opened full screen covers it all. */
--z-content:0;--z-sticky:2;--z-float:1035;--z-topbar:1060;--z-rail:1100;--z-toast:1140;--z-popover:1150;--z-sheet:1180;--z-modal:1190;--z-fullscreen:1500}
*{box-sizing:border-box}html{font-size:15px}
body{margin:0;font-family:var(--font);font-size:var(--fs);background:var(--bg);color:var(--fg);line-height:1.5;-webkit-font-smoothing:antialiased;display:grid;grid-template-columns:var(--side) minmax(0,1fr);grid-template-rows:var(--top) minmax(0,1fr);min-height:100vh}
button,input,select,textarea{font:inherit;color:inherit}a{color:var(--link)}
/* ---- sidebar: dark grey, grouped by area, like the dispatch panel -------- */
.side{grid-row:1/-1;grid-column:1;background:var(--rail);color:var(--rail-fg);display:flex;flex-direction:column;position:sticky;top:0;height:100vh;overflow:hidden;z-index:var(--z-rail)}
.side .brand{flex:none;display:flex;align-items:center;height:var(--top);padding:0 24px;border-bottom:1px solid var(--rail2)}.side .brand img{height:24px;display:block}
.side .label{display:none}
.nav{display:flex;flex-direction:column;padding:8px 0 16px;flex:1 1 auto;min-height:0;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--rail3) transparent}
.nav .sec{font-size:var(--fs-lbl);letter-spacing:.1em;text-transform:uppercase;color:var(--rail-fg2);padding:14px 24px 4px;font-weight:500}
.nav a{display:flex;align-items:center;gap:12px;color:var(--rail-fg);text-decoration:none;padding:8px 24px;flex:none;font-size:14.5px;font-weight:500;border-left:3px solid transparent;transition:background .12s,color .12s}
.nav a svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;flex:none;opacity:.85}
.nav a:hover{background:var(--rail2);color:var(--gw-white)}.nav a.on{background:var(--rail2);color:var(--gw-white);border-left-color:var(--gw-yellow)}.nav a.on svg{opacity:1;color:var(--gw-yellow)}.nav a.cur{color:var(--gw-white)}.nav a.cur svg{opacity:1}
/* flyout sub-menus: a dark panel to the right of the rail, opened by hover or keyboard focus (chrome.js positions it) */
.nav .item{flex:none;position:relative}.nav .item>a .chev{margin-left:auto;width:7px;height:7px;border-right:1.5px solid currentColor;border-top:1.5px solid currentColor;transform:rotate(45deg);opacity:.5;flex:none}
.nav .item.open>a{background:var(--rail2);color:var(--gw-white)}.nav .item.open>a .chev{opacity:.9}
.nav .sub{display:none;position:fixed;left:var(--side);z-index:var(--z-rail);min-width:216px;background:var(--rail2);color:var(--rail-fg);border-radius:0 10px 10px 0;box-shadow:0 10px 30px rgba(20,24,33,.4);padding:6px 0 8px}.nav .item.open .sub{display:block}
.nav .sub b{display:block;font-weight:500;color:var(--gw-white);padding:10px 20px 6px;font-size:14.5px}.nav .sub .links a{display:block;padding:7px 20px;font-size:14px;font-weight:400;border-left:0;color:var(--rail-fg);white-space:nowrap}
.nav .sub .links a:hover{background:var(--rail3);color:var(--gw-white)}.nav .sub .links a.on{color:var(--gw-yellow)}.nav .sub.two .links{columns:2;column-gap:0;min-width:400px}.nav .sub.two .links a{break-inside:avoid}
.side .foot{flex:none;margin-top:auto;display:flex;align-items:center;gap:10px;padding:14px 24px;border-top:1px solid var(--rail2);font-size:var(--fs-xs);color:var(--rail-fg2)}.side .foot img{width:24px;height:24px;border-radius:6px}
/* ---- top bar ------------------------------------------------------------- */
.top{grid-column:2;grid-row:1;display:flex;align-items:center;gap:18px;padding:0 28px;background:var(--card);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:var(--z-topbar);min-width:0}
.top h1{margin:0;font-size:var(--fs-h1);font-weight:500;white-space:nowrap;color:var(--fg0);letter-spacing:-.01em}
.top .right{margin-left:auto;padding-left:16px;display:flex;align-items:center;gap:16px;color:var(--fg3);font-size:var(--fs-sm);white-space:nowrap;flex:none}
.env{font-size:var(--fs-xs);color:var(--fg2);padding:4px 12px;border:1px solid var(--border2);border-radius:999px;background:var(--panel)}.env.live{color:var(--okfg);border-color:var(--gw-mint)}
/* A small laptop (1024): the bar's right side gives way inside the bar, rather than pushing the account menu
   off the screen. The long fleet badge shortens with "..." (its full words on hover), the shortcut hint goes
   and the gaps close a little; Updated, the menu, Search and Help keep their size (25 Oct 2026). */
@media (min-width:801px) and (max-width:1280px){
.top .right{flex:0 1 auto;min-width:0;gap:10px}
.top .right>#env{flex:0 1 auto;min-width:4.5em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.top .jumpbtn kbd{display:none}
}
/* At 1024 a longer name (an operator's, a viewer's) still pushed the bar out: up to 1100 px the role word
   moves into the account menu only (it is already there) and a very long name ends in "...". */
@media (min-width:801px) and (max-width:1100px){
.top .who .whobtn>.role{display:none}
.top .who .whobtn>.name{max-width:8em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
}
.who{display:flex;align-items:center;gap:10px;padding-left:14px;border-left:1px solid var(--border);position:relative}.who .whobtn{display:flex;align-items:center;gap:10px;background:none;border:0;padding:4px 6px;border-radius:var(--rs);cursor:pointer;color:inherit}.who .whobtn:hover{background:var(--hover)}.who .whobtn .chev{width:7px;height:7px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);opacity:.5;margin:0 2px 3px 2px}.who #logout{display:none}.who .acct{position:absolute;right:0;top:calc(100% + 8px);min-width:240px;background:var(--card);border:1px solid var(--border);border-radius:var(--r);box-shadow:0 12px 40px rgba(35,42,59,.18);padding:6px 0;z-index:var(--z-popover)}.who .acct .head{padding:10px 16px 10px;border-bottom:1px solid var(--border);margin-bottom:6px;display:flex;flex-direction:column;gap:2px}.who .acct .head b{font-weight:500;color:var(--fg0)}.who .acct .head span{font-size:var(--fs-lbl);letter-spacing:.06em;text-transform:uppercase;color:var(--fg3)}.who .acct a,.who .acct button{display:block;width:100%;text-align:left;padding:9px 16px;font-size:var(--fs-sm);color:var(--fg);text-decoration:none;background:none;border:0;cursor:pointer;font-weight:500}.who .acct a:hover,.who .acct button:hover,.who .acct a:focus-visible,.who .acct button:focus-visible{background:var(--sel);outline:0}.who .acct .out{border-top:1px solid var(--border);margin-top:6px;padding-top:12px}
.who .avatar{width:34px;height:34px;border-radius:50%;background:var(--ink);color:var(--ink-hi);display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:14px}
.who .avatar.photo{overflow:hidden}.who .avatar img{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}
.who .name{color:var(--fg);font-weight:500}.who .role{font-size:var(--fs-lbl);letter-spacing:.06em;text-transform:uppercase;color:var(--fg3)}
/* ---- KPI cards (every page renders its counters into #stats) ------------- */
.stats{grid-column:1/-1;display:grid;grid-template-columns:repeat(auto-fit,minmax(172px,1fr));gap:16px}.stats[data-cols="4"]{grid-template-columns:repeat(4,minmax(0,1fr))}.stats[data-cols="3"]{grid-template-columns:repeat(3,minmax(0,1fr))}
.stats span{background:var(--card);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow);padding:16px 20px 14px;min-width:0;display:flex;flex-direction:column-reverse;gap:4px;font-size:var(--fs-sm);color:var(--fg2);white-space:nowrap}
.stats b{font-size:var(--fs-kpi);font-weight:500;color:var(--fg0);line-height:1.1;font-variant-numeric:tabular-nums;letter-spacing:-.01em}.stats .hl b{color:var(--crit)}
.stats i.dot{order:1;margin:0 0 4px;width:9px;height:9px}
/* ---- SOS strip (chrome.js) ---------------------------------------------- */
.sosstrip{grid-column:1/-1;background:var(--gw-coral);color:var(--gw-charcoal);border-radius:var(--rs);padding:12px 16px;font-size:var(--fs);font-weight:500;display:flex;gap:10px;align-items:center;flex-wrap:wrap}.sosstrip b{background:var(--gw-white);color:var(--gw-crit);padding:1px 8px;border-radius:999px;font-size:12px;letter-spacing:.06em}.sosstrip a{color:var(--gw-charcoal);margin-left:auto;font-weight:600}
/* ---- content ------------------------------------------------------------- */
main{grid-column:2;grid-row:2;padding:24px 28px 36px;display:grid;gap:20px;align-content:start;min-width:0}
/* Fleet map on a computer: the map full width on top, the car list under it, a car's
   details beside both (Michel, 12 Oct 2026: side by side the map was too small). */
main.fleet{grid-template-columns:minmax(0,1fr);grid-auto-flow:row dense}main.fleet.has-detail{grid-template-columns:minmax(0,1fr) 380px}
main.fleet>.sosstrip{order:-9}main.fleet>.stats{order:-8}main.fleet>.card.map{order:-7;grid-column:1}main.fleet>.card.list{grid-column:1}
main.fleet>.detail{grid-column:2;grid-row:span 2}
/* Fleet map on a computer (Michel, 12 Oct 2026): closer to square, and the legend,
   zone counts and reporting line in a column beside the map instead of over it. */
@media(min-width:1101px) and (pointer:fine),(min-width:1367px){
main.fleet>.card.map{height:clamp(560px,calc(100vh - 84px),1200px);display:grid;grid-template-columns:minmax(0,1fr) 252px;grid-template-rows:auto auto minmax(0,1fr)}
main.fleet>.card.map>h3,main.fleet>.card.map>.zheat{grid-column:1/-1}
main.fleet>.card.map>#map{grid-column:1;grid-row:3;min-height:0;border-radius:0 0 0 var(--r)}
main.fleet>.card.map>.legend{grid-column:2;grid-row:3;position:static;display:flex;flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:2px;margin:0;padding:12px 14px;background:none;border:0;border-left:1px solid var(--border);border-radius:0;box-shadow:none;overflow-y:auto;font-size:var(--fs-sm)}
main.fleet>.card.map>.legend>span,main.fleet>.card.map>.legend>a{display:flex;align-items:center;min-height:32px;padding:0 6px;border-radius:var(--rs)}
main.fleet>.card.map>.legend>span[role=button]:hover{background:var(--hover)}
main.fleet>.card.map>.legend>:not(span):not(a){flex:none;padding:8px 6px 0;margin-top:6px;border-top:1px solid var(--border);line-height:1.45}
main.fleet>.card.map>.legend [data-tip]:hover::after,main.fleet>.card.map>.legend [data-tip]:focus-visible::after{top:50%;bottom:auto;left:auto;right:calc(100% + 10px);transform:translateY(-50%)}
}
/* Hover definitions (data-tip): the counters and the map legend. */
[data-tip]{position:relative}[data-tip]:hover::after,[data-tip]:focus-visible::after{content:attr(data-tip);position:absolute;left:0;top:calc(100% + 6px);z-index:1200;width:max-content;max-width:280px;white-space:normal;padding:8px 10px;background:var(--fg0);color:var(--card);border-radius:var(--rs);font-size:var(--fs-sm);font-weight:400;line-height:1.35;box-shadow:var(--shadow);pointer-events:none;text-transform:none;letter-spacing:0}
.map .legend [data-tip]:hover::after,.map .legend [data-tip]:focus-visible::after{top:auto;bottom:calc(100% + 8px)}
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow);min-width:0}
.card h3{margin:0;padding:18px var(--in,24px) 10px;font-size:var(--fs-title);font-weight:500;color:var(--fg0);position:relative;letter-spacing:-.005em}
/* The section title mark (Gokul, 22 Oct 2026): a short dash under every section title in the
   accent colour staff pick in Appearance (GuyWay yellow unless they change it). Not on side panels, panels inside a section, tiles or pop-ups. */
.card h3::after{content:"";display:block;width:48px;height:4px;background:var(--accent);border-radius:2px;margin-top:8px}
.card .body{padding:16px var(--in,24px) 20px}
.toolbar{display:flex;gap:12px;align-items:center;flex-wrap:wrap;padding:14px var(--in,24px);border-bottom:1px solid var(--border)}
.toolbar input[type=search],.toolbar input[type=text],.toolbar input[type=date],.toolbar input[type=month],.toolbar select{height:var(--ctl);padding:0 14px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);font-size:var(--fs-sm)}
.toolbar input[type=search]{flex:1;min-width:220px;max-width:380px;border-radius:999px;padding:0 18px}.toolbar label{font-size:var(--fs-sm);color:var(--fg2);display:flex;gap:6px;align-items:center}
/* ---- tables -------------------------------------------------------------- */
.tablewrap,.card.list{overflow:auto}.card.list{max-height:calc(100vh - var(--top) - 36px)}
table{width:100%;border-collapse:separate;border-spacing:0;font-size:14px}
th{position:sticky;top:0;z-index:var(--z-sticky);background:var(--panel);text-align:left;padding:0 18px;height:44px;border-bottom:1px solid var(--border2);font-size:13px;font-weight:500;color:var(--fg2);cursor:pointer;user-select:none;white-space:nowrap}
th:first-child{border-radius:0}th:hover{color:var(--fg)}th[aria-sort]{color:var(--fg)}th .dir{display:inline-block;width:1em;color:var(--fg3)}th[aria-sort=ascending] .dir::after{content:"\25B4"}th[aria-sort=descending] .dir::after{content:"\25BE"}
tr.filters td{position:sticky;top:44px;z-index:var(--z-sticky);background:var(--card);padding:8px 10px;height:auto;border-bottom:1px solid var(--border)}
tr.filters input,tr.filters select{width:100%;height:var(--ctl-sm);padding:0 10px;border:1px solid var(--edge);border-radius:var(--rs);font-size:var(--fs-sm);background:var(--card)}
td{padding:0 18px;height:46px;border-bottom:1px solid var(--row-line);white-space:nowrap;vertical-align:middle}
tbody tr:last-child td{border-bottom:0}tbody tr{cursor:pointer}tbody tr:hover{background:var(--hover)}tbody tr.sel{background:var(--sel)}tbody tr.sel td:first-child{box-shadow:inset 3px 0 0 var(--accent)}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}.sub{color:var(--fg3);font-size:var(--fs-sm);margin-left:6px}
/* ---- status: a dot and a word ------------------------------------------- */
.pill{display:inline-flex;align-items:center;gap:8px;font-size:14px;font-weight:500;color:var(--fg);--dot:var(--c300)}
.pill::before{content:"";width:9px;height:9px;border-radius:50%;background:var(--dot);flex:none;box-shadow:inset 0 0 0 1.5px var(--ring,color-mix(in srgb,var(--dot) var(--ring-mix),#000))}
.pill.critical{--dot:var(--gw-coral);--ring:var(--sev-crit-ring);color:var(--crit)}.pill.recall{--dot:var(--gw-coral);--ring:var(--sev-crit-ring);color:var(--crit)}.pill.warn{--dot:var(--gw-sun);--ring:var(--sev-warn-ring)}.pill.ok{--dot:var(--gw-mint);--ring:var(--sev-ok-ring)}.pill.charging{--dot:var(--chg);--ring:var(--chg)}.pill.unknown{--dot:var(--c300);--ring:var(--sev-none-ring);color:var(--fg3)}
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;background:var(--c300);margin-right:6px;vertical-align:0;box-shadow:inset 0 0 0 1.5px var(--sev-none-ring)}.dot.critical,.dot.recall{background:var(--gw-coral);box-shadow:inset 0 0 0 1.5px var(--sev-crit-ring)}.dot.warn{background:var(--gw-sun);box-shadow:inset 0 0 0 1.5px var(--sev-warn-ring)}.dot.ok{background:var(--gw-mint);box-shadow:inset 0 0 0 1.5px var(--sev-ok-ring)}.dot.charging{background:var(--chg);box-shadow:none}
#legend .dot{box-shadow:none}
/* the map legend draws each status the way the map does: a ring around the car (chrome.js gwCarSvg) */
#legend .dot{--ring:var(--c300);width:12px;height:12px;box-sizing:border-box;background:color-mix(in srgb,var(--ring) 30%,transparent);border:2.4px solid var(--ring)}#legend .dot.critical,#legend .dot.recall{--ring:var(--gw-coral)}#legend .dot.warn{--ring:var(--gw-sun)}#legend .dot.ok{--ring:var(--gw-mint)}#legend .dot.charging{--ring:var(--chg)}
/* ---- map ----------------------------------------------------------------- */
.card.map{position:relative;z-index:var(--z-content);isolation:isolate;display:flex;flex-direction:column;min-height:460px}#map{flex:1;min-height:400px;background:var(--wash2);border-radius:0 0 var(--r) var(--r)}
.map .legend{position:absolute;left:12px;bottom:12px;z-index:1001;background:rgba(255,255,255,.95);border:1px solid var(--border);border-radius:var(--rs);padding:8px 14px;font-size:var(--fs-sm);display:flex;gap:14px;flex-wrap:wrap;box-shadow:var(--shadow)}.map .legend span{display:inline-flex;align-items:center}
/* Every map, on every page, keeps its own layers to itself: Leaflet's panes
   and controls (400 to 1000) and Google's are stacked inside the map, never
   against the top bar. */
.leaflet-container,.gm-style{isolation:isolate}
.leaflet-container{font:inherit}.carpin{background:none;border:0}.carpin .car{width:34px;height:34px}.carpin .car svg{width:34px;height:34px;display:block}.carpin .car.still svg{opacity:.88}.leaflet-control-layers{border:1px solid var(--border)!important;border-radius:var(--rs)!important;box-shadow:var(--shadow)!important;font-size:12px}.leaflet-control-layers label{display:inline-block;margin-right:8px}.yardpin{display:flex!important;justify-content:center;align-items:flex-end;box-sizing:border-box;padding-bottom:7px;background:none;border:0;pointer-events:none}.yardpin .hubtag{pointer-events:auto;cursor:pointer;position:relative;display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 9px 0 6px;background:var(--gw-yellow);color:var(--gw-charcoal);border:2px solid var(--gw-charcoal);border-radius:7px;font-size:12px;line-height:1;white-space:nowrap;box-shadow:0 2px 6px rgba(1,30,19,.35)}.yardpin .hubtag::after{content:"";position:absolute;left:50%;bottom:-8px;margin-left:-6px;border:6px solid transparent;border-bottom:0;border-top:8px solid var(--gw-charcoal)}.yardpin .hubtag svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.yardpin .hubtag b{font-weight:700}.yardpin .hubtag i{font-style:normal;font-weight:500;padding-left:6px;border-left:1px solid rgba(1,30,19,.35)}
/* ---- detail pane --------------------------------------------------------- */
.detail{padding:0;overflow:auto;max-height:calc(100vh - var(--top) - 36px);position:sticky;top:calc(var(--top) + 18px)}
.detail .head{padding:18px var(--in,24px);border-bottom:1px solid var(--border);display:flex;align-items:flex-start;gap:10px}.detail .head .btn{margin-left:auto}
.detail h2{margin:0;font-size:20px;font-weight:500;line-height:1.2;color:var(--fg0)}.detail .vin{font-family:ui-monospace,Menlo,monospace;font-size:var(--fs-xs);color:var(--fg3)}
.detail>:not(.head):not(.sec){margin-left:var(--in,24px);margin-right:var(--in,24px)}.detail>h2{margin-top:14px}.detail>.vin{margin-bottom:10px}
.detail .sec{padding:16px var(--in,24px);border-bottom:1px solid var(--border)}.detail .sec:last-child{border:0}.detail .sec h3{padding:0 0 8px;font-size:15px}.detail .sec h3::after{display:none}
.facts{display:grid;grid-template-columns:128px 1fr;gap:6px 12px;font-size:14px;margin:0}.facts dt{color:var(--fg3)}.facts dd{margin:0;font-weight:500}
.controls{display:flex;flex-wrap:wrap;gap:8px}canvas#d-chart{width:100%;height:80px;display:block}
/* ---- buttons ------------------------------------------------------------- */
.btn{height:var(--ctl);padding:0 16px;justify-content:center;text-align:center;border-radius:var(--rs);border:1px solid var(--edge);background:var(--card);color:var(--fg);font-weight:500;cursor:pointer;font-size:14px;line-height:34px;transition:background .12s,border-color .12s;display:inline-flex;align-items:center;gap:6px;text-decoration:none;white-space:nowrap}
.btn:hover{background:var(--hover);border-color:var(--fg3)}/* Main button: brand yellow words on charcoal by day, charcoal on yellow at night (--ink-hi), as the avatar (Gokul, 22 Oct 2026). */
.btn.primary{background:var(--ink);border-color:var(--ink);color:var(--ink-hi)}.btn.primary:hover{background:var(--ink-hover)}
.btn.danger{background:var(--gw-crit);border-color:var(--gw-crit);color:var(--gw-white)}.btn.danger:hover{filter:brightness(.92)}
.btn:disabled{opacity:.4;cursor:not-allowed}.btn.small{height:var(--ctl-sm);line-height:30px;padding:0 12px;font-size:13px}
.btn:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--focus);outline-offset:1px}
/* ---- inline action form -------------------------------------------------- */
.actform{border:1px solid var(--border);border-radius:var(--rs);padding:14px 16px;margin:12px 0 0;background:var(--panel)}.actform h4{margin:0 0 8px;font-size:15px;font-weight:500;color:var(--fg0)}
.actform label{display:block;font-size:var(--fs-sm);margin:10px 0;color:var(--fg2)}.actform input:not([type=checkbox]),.actform select,.actform textarea{width:100%;padding:8px 12px;margin-top:5px;font-size:14px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg)}
.actform .note{font-size:var(--fs-sm);color:var(--fg3);margin:8px 0}
.result{min-height:1.4em;font-size:14px;font-weight:500;padding:8px 0 0}.result.bad{color:var(--crit)}.result.good{color:var(--okfg)}
.audit{list-style:none;padding:0;margin:0;font-size:var(--fs-sm);max-height:260px;overflow:auto}.audit li{padding:7px 0;border-bottom:1px solid var(--border)}.audit li:last-child{border:0}.audit b{font-weight:500}.audit time{color:var(--fg3);margin-right:6px;font-variant-numeric:tabular-nums}
.auditwide{grid-column:1/-1}.auditwide ul{list-style:none;padding:12px var(--in,24px) 18px;margin:0;font-size:var(--fs-sm);columns:2;column-gap:28px}.auditwide li{padding:4px 0;break-inside:avoid}
.muted{color:var(--fg3);font-size:var(--fs-sm)}.hidden,.actform label.hidden,.card.hidden{display:none!important}
/* ---- moving around: page entry, smooth scroll, search and jump ------------ */
html{scroll-behavior:smooth}
/* backwards, not both: a finished animation that keeps holding transform
   makes main the containing block for anything position:fixed inside it, and
   the car sheet on a phone then lands at the foot of the page, not the screen. */
@media(prefers-reduced-motion:no-preference){main{animation:gw-in .16s ease-out backwards}@keyframes gw-in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}tbody tr{transition:background .1s}}
.jumpbtn kbd{font:inherit;font-size:var(--fs-xs);color:var(--fg3);border:1px solid var(--border2);border-radius:4px;padding:0 5px;margin-left:6px;line-height:18px}
.jump{position:fixed;top:calc(var(--top) + 8px);left:50%;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));z-index:var(--z-popover);background:var(--card);border:1px solid var(--border);border-radius:var(--r);box-shadow:0 12px 40px rgba(35,42,59,.18);padding:10px}
.jump input{width:100%;height:40px;padding:0 14px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg);font-size:var(--fs)}
.jump ul{list-style:none;margin:8px 0 0;padding:0;max-height:min(420px,60vh);overflow:auto}
.jump li{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--rs);cursor:pointer;font-size:var(--fs-sm)}.jump li[aria-selected=true],.jump li:hover{background:var(--sel)}
.jump li .k{flex:none;width:52px;font-size:var(--fs-lbl);letter-spacing:.06em;text-transform:uppercase;color:var(--fg3)}.jump li.none{color:var(--fg3);cursor:default}
/* The command bar says what it understood and what will happen before it
   happens: one status line under the box, one note per row. */
.jump .say{margin:8px 2px 0;font-size:var(--fs-sm);color:var(--fg2);min-height:1.2em}.jump .say[hidden]{display:none}
.jump li .t{flex:none;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jump li .h{flex:1;min-width:0;text-align:right;color:var(--fg3);font-size:var(--fs-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jump li.grp{padding:10px 10px 4px;cursor:default;font-size:var(--fs-lbl);letter-spacing:.06em;text-transform:uppercase;color:var(--fg3)}.jump li.grp:hover{background:none}
.jump li.confirmrow{background:var(--tint);border:1px solid var(--border2)}.jump li.confirmrow .t{font-weight:600}
.jump li.rec .k{width:66px}.jump li.rec .t{display:flex;flex-direction:column;gap:1px;flex:1 1 auto;min-width:0;max-width:70%}.jump li.rec .t b{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.jump li.rec .t small{color:var(--fg3);font-size:var(--fs-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Ask GuyWay (fleet/consoleask.py): the answer sits inline under the box, no
   modal. A small AI label says who wrote it; the sources and the Open button
   follow. Scrolls inside the box so a phone keeps the keyboard and the box. */
.jump .askans{margin:8px 0 0;padding:10px 12px;border:1px solid var(--border2);border-radius:var(--rs);background:var(--panel);max-height:min(320px,42vh);overflow:auto;font-size:var(--fs-sm)}.jump .askans[hidden]{display:none}
.jump .askhead{display:flex;align-items:center;gap:8px;margin:0 0 6px;font-size:var(--fs-xs);color:var(--fg2)}
.jump .ailbl{flex:none;font-size:var(--fs-lbl);letter-spacing:.06em;font-weight:600;padding:1px 6px;border-radius:4px;background:var(--tint);color:var(--fg);border:1px solid var(--border2)}
.jump .asktext{margin:0 0 8px;color:var(--fg);line-height:1.45;white-space:pre-line}
.jump .asksrc{margin:0 0 2px;font-size:var(--fs-lbl);letter-spacing:.06em;text-transform:uppercase;color:var(--fg3)}
.jump .askcite{list-style:none;margin:0 0 8px;padding:0;max-height:none;overflow:visible}.jump .askcite li{display:block;padding:2px 0;min-height:0;cursor:default}.jump .askcite li:hover{background:none}
.jump .askcite a{color:var(--fg);text-decoration:underline;text-underline-offset:2px}
.jump .askopen{display:inline-flex;align-items:center;margin:2px 0 6px}
.jump .asknote{margin:0;font-size:var(--fs-xs);color:var(--fg3)}
.jump .asgcar{margin:0 0 8px}.jump .asgcar .q{margin:0 0 4px}.jump .asgcar .muted{margin:0 0 4px;font-size:var(--fs-xs)}.jump .asgcar .cbtns{display:flex;gap:8px;margin-top:6px}
/* A data answer (fleet/askdata.py): the figure large, the sentence, last week, a top five. */
.jump .datalbl{flex:none;font-size:var(--fs-lbl);letter-spacing:.06em;font-weight:600;padding:1px 6px;border-radius:4px;color:var(--fg);border:1px solid var(--border2)}
.jump .askfig{margin:2px 0 4px;font-size:var(--fs-kpi);font-weight:600;line-height:1.1;color:var(--fg);font-variant-numeric:tabular-nums}
.jump .askcmp{margin:0 0 8px;font-size:var(--fs-xs);color:var(--fg2)}.jump .askcmp .up{color:var(--okfg)}.jump .askcmp .down{color:var(--crit)}
.jump .asktbl{width:100%;border-collapse:collapse;margin:0 0 8px;font-size:var(--fs-sm)}.jump .asktbl td{padding:4px 2px;border-top:1px solid var(--border2)}
.jump .askspark{display:block;width:100%;height:40px;margin:0 0 8px}.jump .askspark path{fill:none;stroke:var(--fg2);stroke-width:1.5;vector-effect:non-scaling-stroke}
.jump .asktbl td.r{width:20px;color:var(--fg3)}.jump .asktbl td.n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.jump .asksugg{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 4px}
/* On a small screen the box sits under the top bar rather than at the foot of
   the screen: the iOS keyboard rises from the bottom and would cover it. */
@media(max-width:800px){.jump{top:calc(var(--safe-t) + var(--top) + 6px);left:8px;right:8px;transform:none;width:auto;padding:10px}
.jump input{height:46px;font-size:16px}.jump ul{max-height:min(420px,48vh)}.jump li{padding:12px 10px;min-height:44px}.jump li .h{display:none}.jump li .t,.jump li.rec .t{max-width:none}.jump li.rec .t small{white-space:normal}}
/* The bar's microphone (fleet/consolevoice.py, Michel, 14 Oct 2026): a square the input's height, same edge,
   radius and fill, so the row reads as one control (#1457). Recording shows a row under it: dot, level, time, Cancel. */
.jumprow{display:flex;align-items:stretch;gap:8px}.jumprow input{flex:1 1 auto;min-width:0}
.jumpmic{flex:none;display:grid;place-items:center;width:40px;height:40px;padding:0;margin:0;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg2);cursor:pointer}
.jumpmic[hidden]{display:none}.jumpmic:hover{background:var(--hover);color:var(--fg)}.jumpmic:focus-visible{outline:2px solid var(--chg);outline-offset:2px}
.jumpmic svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.jumpmic.on{background:var(--crit);border-color:var(--crit);color:var(--gw-white)}.jumpmic.on svg rect{fill:currentColor}.jumpmic.busy{opacity:.6;cursor:progress}
.jumprec{display:flex;align-items:center;gap:10px;margin:8px 0 0;padding:6px 6px 6px 12px;border:1px solid var(--border2);border-radius:var(--rs);background:var(--panel);font-size:var(--fs-sm);color:var(--fg2)}.jumprec[hidden]{display:none}
.jumprec .dot{flex:none;width:10px;height:10px;border-radius:50%;background:var(--crit)}
.jumprec .lvl{flex:1 1 auto;min-width:40px;display:flex;align-items:center;gap:3px;height:22px}.jumprec .lvl i{flex:1 1 0;max-width:4px;height:100%;border-radius:2px;background:var(--fg2);transform:scaleY(.15);transition:transform .08s linear}
.jumprec .tm{flex:none;font-variant-numeric:tabular-nums;color:var(--fg)}.jumprec .wd{flex:none}
.jumprec .btn{flex:none;min-width:64px;justify-content:center}
@media(prefers-reduced-motion:no-preference){.jumprec .dot{animation:gw-recdot 1.2s ease-in-out infinite}@keyframes gw-recdot{50%{opacity:.35}}}
@media(max-width:800px){.jumpmic{width:46px;height:46px}.jumpmic svg{width:22px;height:22px}.jumprec .wd{display:none}.jumprec .btn{min-height:44px}}
/* ---- login --------------------------------------------------------------- */
body.login{display:grid;grid-template-columns:1fr;grid-template-rows:1fr;place-items:center;background:var(--bg)}
/* The console places every main in row 2 under its top bar (and column 2 beside the rail on a laptop). A sign-in or lock page has neither, so its card would sit in an empty second row: on a phone, the bottom half of the screen (Michel, 12 Oct 2026). */
body.login>main{grid-row:1;grid-column:1}.login .card{width:400px;padding:36px}.login .card img{height:28px;display:block;margin-bottom:24px}
.login label{display:block;margin:14px 0 5px;font-size:var(--fs-sm);color:var(--fg2)}.login input{width:100%;height:40px;padding:0 14px;border:1px solid var(--edge);border-radius:var(--rs)}.login button{width:100%;margin-top:20px;justify-content:center}
.err{color:var(--crit);min-height:1.2em;font-size:var(--fs-sm);margin:0}
/* The Microsoft door, under the password form. The button is Microsoft's own
   "Sign in with Microsoft" artwork, served unaltered from /static/brand/
   (ms-signin-light.svg on the password page, ms-signin-dark.svg on the
   Microsoft-only page: one theme per page, as their branding page asks). It
   is 215 by 41, drawn by the file, so the link only supplies the hit area
   and a focus ring. The link is styled as a button and not made one: a form
   posting to start a redirect would need a CSRF token that a person with no
   session has not got. */
.login .ssosplit{display:flex;align-items:center;gap:12px;margin:20px 0 0;color:var(--fg3);font-size:var(--fs-sm)}
.login .ssosplit::before,.login .ssosplit::after{content:"";flex:1 1 0;height:1px;background:var(--border)}
.login a.btn.sso{display:block;width:215px;max-width:100%;height:41px;line-height:0;margin:12px auto 0;padding:0;border:0;border-radius:0;background:none}
.login a.btn.sso:hover{background:none}
.login a.btn.sso img{display:block;width:215px;height:41px;max-width:100%;margin:0}
.login p.signup{margin:12px 0 0}
.login .card{max-width:calc(100vw - 32px)}
/* console-signin.js, only in the app installed on an iPhone or iPad */
.login .ssohelp{margin:16px 0 0;padding:14px;border:1px solid var(--border2);border-radius:var(--rs);background:var(--panel);font-size:var(--fs-sm);color:var(--fg2)}
.login .ssohelp p{margin:0 0 10px}.login .ssohelp b{color:var(--fg0);font-weight:500}.login .ssohelp .btn{margin-top:0}.login .ssohelp p.muted{margin:10px 0 0}
.login .ssohelp [hidden]{display:none}
/* The second factor. The key, the otpauth link and the recovery codes are read
   off this screen and copied by hand onto a phone or onto paper, so they are
   set monospaced, spaced out, and wrapped inside the card rather than scrolled
   out of it. The policy is style-src 'self' with no unsafe-inline, so these
   rules have to live here: a style attribute on the page is dropped silently. */
.login h2{margin:0 0 10px;font-size:var(--fs-title);font-weight:500;color:var(--fg0)}
.login .qr{display:flex;justify-content:center;margin:12px 0}
.login .qr svg{width:200px;height:200px;border:1px solid var(--border);border-radius:var(--rs)}
.login .key,.login .uri{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;word-break:break-all;background:var(--panel);border:1px solid var(--border);border-radius:var(--rs)}
.login .key{font-size:var(--fs-title);letter-spacing:.12em;padding:12px 14px;margin:12px 0;color:var(--fg0)}
.login .uri{font-size:var(--fs-xs);padding:10px 12px;margin:10px 0;color:var(--fg2)}
.login .codes{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:var(--fs);letter-spacing:.08em;columns:2;margin:14px 0;padding-left:var(--in,24px);color:var(--fg0)}
.login .codes li{margin:4px 0;break-inside:avoid}
/* A link drawn as a button stays a flex box, so its label sits in the middle of
   the button at any height (the offline page's 48 px Try again was top-aligned
   as a block, 15 Oct 2026). */
.login a.btn{display:flex;align-items:center;justify-content:center;text-align:center;text-decoration:none;margin-top:16px}
/* ---- narrow and phone ---------------------------------------------------- */
@media(max-width:1100px){main.fleet,main.fleet.has-detail{grid-template-columns:1fr}.detail{position:static;max-height:none}.auditwide ul{columns:1}.card.list{max-height:60vh}}
@media(max-width:800px){.stats,.stats[data-cols]{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px}.stats span{padding:12px 14px 10px}.stats b{font-size:22px}.card.map{min-height:320px}#map{min-height:300px}.toolbar input[type=search]{max-width:none}}
/* ---- colour modes and accent themes (Settings, Appearance) --------------
   Additive. /static/admin.theme.js stamps <html data-mode="light|dark|system"
   data-theme="sun|yellow|mint|lime|coral|lavender|custom"> and, for a custom
   accent, sets --accent-custom on <html>. Every existing token keeps its light
   value; dark mode only re-points the surface and text tokens. */
/* Dark mode is the rider app's night palette (gw-rider-app src/ui/theme.ts,
   `dark`; Michel, 13 Oct 2026): a black page, #1C1C1C cards, a grey text
   ladder and the lime for links, the primary button, focus and the active
   state, never for a card or a tile. Ratios on the #1C1C1C card, checked by
   tests/test_console_contrast.py: fg 15.0, fg2 7.0, fg3 5.8 (4.6 on --sel),
   lime 15.4, crit text 5.8, the field edge 3.6. The fg3 is a step lighter
   than the app's #8C8C8C so it still reads on a selected row. */
:root{--accent-custom:var(--gw-sun);--dk-bg:#000000;--dk-card:#1C1C1C;--dk-panel:#212121;--dk-tint:#262626;--dk-fg0:#FFFFFF;--dk-fg:#F0F0F0;--dk-fg2:#A6A6A6;--dk-fg3:#969696;--dk-border:#2A2A2A;--dk-border2:#3A3A3A;--dk-edge:#737373;--dk-hover:#242424;--dk-sel:#2E2E2E;--dk-okfg:#EAFF68;--dk-crit:#E07A55;--dk-chg:#A9AEDC;--dk-shadow:0 1px 2px rgba(0,0,0,.30),0 10px 28px rgba(0,0,0,.30);
--dk-rail:#121212;--dk-rail2:#262626;--dk-rail3:#333333;--dk-rail-fg:#D9D9D9;--dk-rail-fg2:#A6A6A6;--dk-mark:rgba(234,255,104,.30);--dk-nozone-fg:#FF6B78;
/* Roles that take a brand colour by day and another at night. Each light
   value is the colour the rule used before it was named, so the day look is
   unchanged; only the dark blocks below re-point them. */
--gw-crit:#B8461F;--link:var(--c600);--ink:var(--gw-charcoal);--on-ink:var(--gw-white);--ink-hi:var(--gw-yellow);--ink-hover:var(--c700);--chip:var(--gw-charcoal);--chip-fg:var(--gw-yellow);--focus:var(--c500);
--wash:var(--c050);--wash2:var(--c100);--wash3:var(--c200);--wash-ink:var(--c700);--wash-mute:var(--c500);--solid:var(--c700);--on-solid:var(--gw-white);--line-strong:var(--c600);--strong-fg:var(--c800);
--notice:var(--y400);--notice-fg:var(--gw-charcoal);--notice-fg2:var(--c700);--mark-bg:var(--y400);--on-chg:var(--gw-white);--nozone-fg:var(--nozone);--row-sel:var(--sel);--oldpos-dim:.6;--well-edge:transparent;--off-dim:.55;--sep:var(--border2);--seg-on:var(--fg0);--seg-on-fg:var(--card);--seg-track:var(--panel);--seg-pill:var(--card)}
:root[data-theme=sun]{--accent:var(--gw-sun)}:root[data-theme=yellow]{--accent:var(--gw-yellow)}:root[data-theme=mint]{--accent:var(--gw-mint)}:root[data-theme=lime]{--accent:var(--gw-lime)}:root[data-theme=coral]{--accent:var(--gw-coral)}:root[data-theme=lavender]{--accent:var(--gw-lavender)}:root[data-theme=custom]{--accent:var(--accent-custom)}
:root[data-mode=dark]{color-scheme:dark;--row-line:var(--dk-border);--sev-crit-ring:var(--gw-coral);--sev-warn-ring:var(--gw-sun);--sev-ok-ring:var(--gw-mint);--sev-info-ring:var(--gw-lavender);--sev-none-ring:var(--c300);--ring-mix:100%;--bg:var(--dk-bg);--card:var(--dk-card);--panel:var(--dk-panel);--tint:var(--dk-tint);--fg0:var(--dk-fg0);--fg:var(--dk-fg);--fg2:var(--dk-fg2);--fg3:var(--dk-fg3);--border:var(--dk-border);--border2:var(--dk-border2);--edge:var(--dk-edge);--hover:var(--dk-hover);--sel:var(--dk-sel);--okfg:var(--dk-okfg);--crit:var(--dk-crit);--chg:var(--dk-chg);--shadow:var(--dk-shadow);--rail:var(--dk-rail);--rail2:var(--dk-rail2);--rail3:var(--dk-rail3);--rail-fg:var(--dk-rail-fg);--rail-fg2:var(--dk-rail-fg2);--link:var(--gw-yellow);--ink:var(--gw-yellow);--on-ink:var(--gw-charcoal);--ink-hi:var(--gw-charcoal);--ink-hover:var(--y400);--chip:var(--dk-tint);--chip-fg:var(--gw-yellow);--focus:var(--gw-yellow);--wash:var(--dk-panel);--wash2:var(--dk-tint);--wash3:var(--dk-sel);--wash-ink:var(--dk-fg0);--wash-mute:var(--dk-fg2);--solid:var(--dk-fg);--on-solid:var(--dk-bg);--line-strong:var(--dk-fg2);--strong-fg:var(--dk-fg0);--notice:var(--dk-tint);--notice-fg:var(--dk-fg0);--notice-fg2:var(--dk-fg2);--mark-bg:var(--dk-mark);--on-chg:var(--gw-charcoal);--nozone-fg:var(--dk-nozone-fg);--row-sel:var(--dk-sel);--oldpos-dim:1;--well-edge:var(--dk-edge);--off-dim:.8;--sep:var(--dk-fg3);--seg-on:var(--gw-yellow);--seg-on-fg:var(--gw-charcoal);--seg-track:var(--dk-bg);--seg-pill:var(--dk-sel)}
:root[data-mode=dark] .map .legend,:root[data-mode=dark] .map .rangekey{background:var(--card)}:root[data-mode=dark] .leaflet-bar a,:root[data-mode=dark] .leaflet-control-layers,:root[data-mode=dark] .leaflet-popup-content-wrapper,:root[data-mode=dark] .leaflet-popup-tip,:root[data-mode=dark] .leaflet-tooltip{background:var(--card);color:var(--fg0);border-color:var(--border2)}:root[data-mode=dark] .leaflet-bar a:hover{background:var(--hover)}:root[data-mode=dark] .leaflet-bar a.leaflet-disabled{background:var(--panel);color:var(--fg3)}:root[data-mode=dark] .leaflet-bar,:root[data-mode=dark] .leaflet-control-layers{border-color:var(--border2)}:root[data-mode=dark] .leaflet-control-attribution{background:rgba(0,0,0,.65);color:var(--fg2)}:root[data-mode=dark] .leaflet-control-attribution a{color:var(--fg0)}:root[data-mode=dark] .leaflet-tooltip-top::before{border-top-color:var(--card)}:root[data-mode=dark] .leaflet-tooltip-bottom::before{border-bottom-color:var(--card)}:root[data-mode=dark] .leaflet-tooltip-left::before{border-left-color:var(--card)}:root[data-mode=dark] .leaflet-tooltip-right::before{border-right-color:var(--card)}:root[data-mode=dark] .leaflet-container{background:var(--wash2)}:root[data-mode=dark] .login img[src*="/brand/wordmark.svg"]{filter:brightness(0) invert(1)}
@media (prefers-color-scheme:dark){
:root[data-mode=system]{color-scheme:dark;--row-line:var(--dk-border);--sev-crit-ring:var(--gw-coral);--sev-warn-ring:var(--gw-sun);--sev-ok-ring:var(--gw-mint);--sev-info-ring:var(--gw-lavender);--sev-none-ring:var(--c300);--ring-mix:100%;--bg:var(--dk-bg);--card:var(--dk-card);--panel:var(--dk-panel);--tint:var(--dk-tint);--fg0:var(--dk-fg0);--fg:var(--dk-fg);--fg2:var(--dk-fg2);--fg3:var(--dk-fg3);--border:var(--dk-border);--border2:var(--dk-border2);--edge:var(--dk-edge);--hover:var(--dk-hover);--sel:var(--dk-sel);--okfg:var(--dk-okfg);--crit:var(--dk-crit);--chg:var(--dk-chg);--shadow:var(--dk-shadow);--rail:var(--dk-rail);--rail2:var(--dk-rail2);--rail3:var(--dk-rail3);--rail-fg:var(--dk-rail-fg);--rail-fg2:var(--dk-rail-fg2);--link:var(--gw-yellow);--ink:var(--gw-yellow);--on-ink:var(--gw-charcoal);--ink-hi:var(--gw-charcoal);--ink-hover:var(--y400);--chip:var(--dk-tint);--chip-fg:var(--gw-yellow);--focus:var(--gw-yellow);--wash:var(--dk-panel);--wash2:var(--dk-tint);--wash3:var(--dk-sel);--wash-ink:var(--dk-fg0);--wash-mute:var(--dk-fg2);--solid:var(--dk-fg);--on-solid:var(--dk-bg);--line-strong:var(--dk-fg2);--strong-fg:var(--dk-fg0);--notice:var(--dk-tint);--notice-fg:var(--dk-fg0);--notice-fg2:var(--dk-fg2);--mark-bg:var(--dk-mark);--on-chg:var(--gw-charcoal);--nozone-fg:var(--dk-nozone-fg);--row-sel:var(--dk-sel);--oldpos-dim:1;--well-edge:var(--dk-edge);--off-dim:.8;--sep:var(--dk-fg3);--seg-on:var(--gw-yellow);--seg-on-fg:var(--gw-charcoal);--seg-track:var(--dk-bg);--seg-pill:var(--dk-sel)}
:root[data-mode=system] .map .legend,:root[data-mode=system] .map .rangekey{background:var(--card)}:root[data-mode=system] .leaflet-bar a,:root[data-mode=system] .leaflet-control-layers,:root[data-mode=system] .leaflet-popup-content-wrapper,:root[data-mode=system] .leaflet-popup-tip,:root[data-mode=system] .leaflet-tooltip{background:var(--card);color:var(--fg0);border-color:var(--border2)}:root[data-mode=system] .leaflet-bar a:hover{background:var(--hover)}:root[data-mode=system] .leaflet-bar a.leaflet-disabled{background:var(--panel);color:var(--fg3)}:root[data-mode=system] .leaflet-bar,:root[data-mode=system] .leaflet-control-layers{border-color:var(--border2)}:root[data-mode=system] .leaflet-control-attribution{background:rgba(0,0,0,.65);color:var(--fg2)}:root[data-mode=system] .leaflet-control-attribution a{color:var(--fg0)}:root[data-mode=system] .leaflet-tooltip-top::before{border-top-color:var(--card)}:root[data-mode=system] .leaflet-tooltip-bottom::before{border-bottom-color:var(--card)}:root[data-mode=system] .leaflet-tooltip-left::before{border-left-color:var(--card)}:root[data-mode=system] .leaflet-tooltip-right::before{border-right-color:var(--card)}:root[data-mode=system] .leaflet-container{background:var(--wash2)}:root[data-mode=system] .login img[src*="/brand/wordmark.svg"]{filter:brightness(0) invert(1)}
}

/* ---- range zones around the hub (fleet/rangezone.py) ------------------- */
.map .rangekey{position:absolute;left:56px;top:78px;z-index:1001;width:272px;background:rgba(255,255,255,.96);border:1px solid var(--border);border-radius:var(--rs);padding:12px 14px;box-shadow:var(--shadow);font-size:var(--fs-sm);display:flex;flex-direction:column;gap:9px}
.map .rangekey[hidden]{display:none}
.rangekey .rk-h{font-weight:600;color:var(--fg0)}.rangekey .rk-h span{display:block;font-weight:400;color:var(--fg3);font-size:var(--fs-xs)}
.rangekey .rk-row{display:flex;gap:10px;align-items:flex-start}.rangekey .rk-row b{display:block;font-weight:600;color:var(--fg0)}.rangekey .rk-row span{color:var(--fg2);font-size:var(--fs-xs);line-height:1.4}
.rk-sw{flex:0 0 auto;width:22px;height:14px;border-radius:4px;margin-top:3px}
.rk-sw.warn{background:color-mix(in srgb,var(--gw-sun) 30%,transparent);border:2.5px dashed var(--gw-sun)}
.rk-sw.nogo{background:color-mix(in srgb,var(--gw-coral) 26%,transparent);border:2.5px solid var(--gw-coral)}
.rk-sw.ok{background:transparent;border:1.5px solid var(--fg3)}
.rangekey .rk-row div:only-child span{color:var(--fg3)}
.rangekey .btn{align-self:flex-start;display:inline-flex;align-items:center;gap:6px}.rangekey .btn .rk-sw{width:14px;height:10px;margin:0;border-width:2px}.rangekey .btn[aria-pressed=true] .rk-sw{display:none}
.map .rangekey:not(.open){width:auto;padding:0;background:none;border:0;box-shadow:none}.rangekey:not(.open) .rk-h,.rangekey:not(.open) .rk-row{display:none}.rangekey:not(.open) .btn{box-shadow:var(--shadow);background:var(--card)}.rangekey .btn[aria-pressed=true]{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
.ringpin{background:none;border:0}
.ringtag{display:flex;flex-direction:column;align-items:center;justify-content:center;height:40px;border-radius:999px;background:var(--gw-charcoal);color:var(--gw-white);box-shadow:var(--shadow);font-size:12px;line-height:1.2;border:2px solid var(--gw-sun)}
.ringtag.nogo{border-color:var(--gw-coral)}.ringtag b{font-weight:600;font-size:13px}.ringtag span{font-size:12.5px;opacity:.85}
/* The trip marks on every map (fleet/static/tripmarks.js, the same as the apps' src/ui/marks.tsx;
   Michel, 13 Oct 2026): ink black by day and white by night, the halo the map ground's side. */
:root{--trip-ink:#000000;--trip-halo:#FFFFFF}
:root[data-mode=dark]{--trip-ink:#FFFFFF;--trip-halo:#000000}
@media (prefers-color-scheme:dark){:root[data-mode=system]{--trip-ink:#FFFFFF;--trip-halo:#000000}}
.tripmark{background:none;border:0}.tripmark svg{display:block}
.tripmark .tm-ink{fill:var(--trip-ink)}.tripmark .tm-halo{fill:var(--trip-halo)}.tripmark .tm-lime{fill:var(--gw-yellow)}.tripmark .tm-edge{stroke:var(--trip-ink)}
/* The trip's route (tripmarks.js leafletRoute, googleRoute; Michel, 13 Oct 2026): the apps' lime
   on a thin casing, charcoal by day and black by night. Not the car's trail. */
:root{--route-line:var(--gw-yellow);--route-edge:var(--gw-charcoal)}
:root[data-mode=dark]{--route-edge:#000000}
@media (prefers-color-scheme:dark){:root[data-mode=system]{--route-edge:#000000}}
.leaflet-container path.tm-route{stroke:var(--route-line)}.leaflet-container path.tm-route-edge{stroke:var(--route-edge)}
@media (max-width:760px){.map .rangekey{left:52px;right:12px;width:auto}}

/* ---- Chart tokens (fleet/static/chartkit.js, styled in dashboard.css) ------
   Michel, 13 Oct 2026: option B, "Summary and bars", in the GuyWay Mint set.
   req: the pale bar (requests, the days before today). done: what went right
   (completed rides, a single measure); the light mint is a shade darker than
   the swatch's #2FB884 so a bar keeps 3:1 against a white card (3.1:1; the
   swatch gave 2.5:1), the dark mint is 9.8:1 on the dark card. acc: the small
   selection dot. accink: the selection rule. lost: the outcomes that lost a
   ride (cancelled, no driver, no show), a coral one step darker than the brand's
   so it keeps 3:1 on the card (4.1). alt: a second category beside mint
   (corporate trips), the deep brand green. s3: a third series, lavender.
   Series always come in that order: done, alt, s3; lost only for what went
   wrong (palette review G, 22 Oct 2026). Figures use the main text colour.
   One block, light then the console's two dark selectors, nothing else. */
:root{--ch-req:#D9F4E8;--ch-done:#26A574;--ch-acc:var(--gw-charcoal);--ch-accink:var(--gw-charcoal);--ch-lost:#D9502E;--ch-alt:var(--c700);--ch-s3:#6E76B8}
:root[data-mode=dark]{--ch-req:#1D4235;--ch-done:var(--gw-mint);--ch-acc:var(--gw-yellow);--ch-accink:var(--gw-mint);--ch-lost:#FF8A6A;--ch-alt:#A9AEDC;--ch-s3:#BDBDBD}
@media (prefers-color-scheme:dark){:root[data-mode=system]{--ch-req:#1D4235;--ch-done:var(--gw-mint);--ch-acc:var(--gw-yellow);--ch-accink:var(--gw-mint);--ch-lost:#FF8A6A;--ch-alt:#A9AEDC;--ch-s3:#BDBDBD}}
/* ---- end of chart tokens ---- */

/* ---- no-entry security zones (fleet/securityzones.py) ------------------
   A red of its own rather than the brand coral: coral already means the
   range no-go line and a critical car, and a wharf alarm must not read as
   either at a glance. */
:root{--nozone:#D7263D;--nozone-ink:#FFFFFF}
.szsign{background:none;border:0}
.szsign .szs{display:flex;align-items:center;gap:6px;white-space:nowrap;pointer-events:none}
.szsign .szs i{flex:none;width:18px;height:18px;border-radius:50%;background:var(--nozone);border:2px solid var(--nozone-ink);box-shadow:0 1px 3px rgba(1,30,19,.35);position:relative}
.szsign .szs i::after{content:"";position:absolute;left:3px;right:3px;top:6px;height:2px;border-radius:1px;background:var(--nozone-ink)}
.szsign .szs b{font-size:var(--fs-xs);font-weight:600;color:var(--nozone-ink);background:var(--nozone);padding:2px 7px;border-radius:999px;box-shadow:0 1px 3px rgba(1,30,19,.35)}
.legend .szleg{display:inline-flex;align-items:center;gap:6px;color:inherit;text-decoration:none}
.legend .szleg i{width:14px;height:10px;border-radius:3px;background:color-mix(in srgb,var(--nozone) 40%,transparent);border:2px solid var(--nozone)}
.szring{background:none;border:0}
.szring span{display:block;width:40px;height:40px;border-radius:50%;border:3px solid var(--nozone);box-shadow:0 0 0 2px var(--nozone-ink);animation:szpulse 1.6s ease-out infinite}
@keyframes szpulse{0%{transform:scale(.85);opacity:1}100%{transform:scale(1.25);opacity:.35}}
@media (prefers-reduced-motion:reduce){.szring span{animation:none}}
/* the zones page */
main.szpage{display:grid;grid-template-columns:minmax(0,1.45fr) minmax(0,1fr);gap:18px;align-items:start}
main.szpage .lead{margin:0 0 12px}
.szpage #szmap{height:560px;border-radius:var(--rs);border:1px solid var(--border)}
.szpage .szstate{font-size:var(--fs-xs);font-weight:600;border-radius:999px;padding:2px 8px;background:var(--tint);color:var(--fg2)}
.szpage .szstate.on{background:color-mix(in srgb,var(--nozone) 14%,transparent);color:var(--nozone-fg)}
.szpage .szunv{font-size:var(--fs-xs);font-weight:600;color:var(--crit)}
.szpage td.note{min-width:280px;max-width:420px;white-space:normal}.szpage td.note b{color:var(--fg0)}.szpage td.note span:last-child{display:block;margin-top:4px;color:var(--fg2);font-size:var(--fs-xs);line-height:1.45}
.szpage > section.card:first-of-type > p,.szpage > section.card:first-of-type > .row,.szpage > section.card:first-of-type > form,.szpage .szwatch > b{margin-left:var(--in,24px);margin-right:var(--in,24px)}.szpage > section.card:first-of-type > p.lead{margin-top:18px}.szpage .szwatch > b{display:block;margin-bottom:8px}.szpage #szadd-row{margin-top:12px;margin-bottom:4px}
.szpage > section.card:last-of-type{padding:0;overflow:hidden}.szpage > section.card:last-of-type #szmap{border:0;border-radius:0}
.szpage td.num,.szpage td:nth-child(2),.szpage td:nth-child(4){white-space:nowrap}
.szpage tr.sel td{background:var(--sel)}
.szpage form.szform{display:grid;gap:10px;padding:14px;border:1px solid var(--border);border-radius:var(--rs);background:var(--panel);margin-top:12px}
.szpage form.szform textarea{min-height:120px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:var(--fs-sm)}
.szpage form.szform .row{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.szpage .szwatch{margin-top:14px}
@media(max-width:1439px){main.szpage{grid-template-columns:1fr}.szpage #szmap{height:380px}}
/* The map on the right, every zone drawn, in view while the list scrolls (Gokul, 21 Oct 2026),
   where the whole list still fits beside it: the note column narrower and Edit over Switch off.
   Narrower screens keep the map under the list, so no column or button is cut. */
@media(min-width:1440px){main.szpage{grid-template-columns:minmax(0,1.7fr) minmax(0,1fr)}.szpage > section.card:last-of-type{position:sticky;top:calc(var(--top) + 16px)}.szpage #szmap{height:calc(100vh - var(--top) - 150px);min-height:420px}
  .szpage td.note{min-width:200px}.szpage #sztable td:last-child{white-space:normal}
  .szpage #sztable td:last-child .btn{display:flex;width:100%;position:relative;min-height:40px;margin:0}
  .szpage #sztable td:last-child .btn + .btn{margin-top:16px}
  .szpage #sztable td:last-child .btn::after{content:"";position:absolute;left:-1px;right:-1px;top:-5px;bottom:-5px}}
.szpage form.szform[hidden]{display:none}
/* Safety in three tabs (safetytabs.js, Gokul on Sai Teja's layout, 21 Oct 2026):
   the red SOS bar, the title with the page's buttons, the SOS tiles, the tabs,
   then the table. The title and the tabs are appended to main and put first
   here, so each page's :first-child rules keep meaning its first card. */
main.gwsafety > .sfhead,main.gwsafety > .sftabs{grid-column:1/-1;min-width:0}
main.gwsafety > .sfhead{order:-3;display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:12px 16px}
main.gwsafety > .sftabs{order:-1;border-bottom:1px solid var(--border)}
main.gwsafety.issues > #sos,main.gwsafety > .sosstrip{order:-4}
main.gwsafety.issues > #stats{order:-2}
/* Safety keeps four tiles, Open, Ongoing, Resolved today, Overdue: is every SOS being attended to
   (Gokul, 21 Oct 2026). issues.js draws Open, Ongoing, Overdue, SOS active today, Resolved today,
   Median first response; SOS active today and the median stay on the Support inbox. */
main.gwsafety.issues > #stats > span:is(:nth-child(4),:nth-child(6)){display:none}
main.gwsafety.issues > #stats > span:nth-child(5){order:3}
main.gwsafety.issues > #stats > span:nth-child(3){order:4}
main.gwsafety.issues > section.card.list > .toolbar.tabbar{display:none}
.sfhead h2{margin:0;font-size:var(--fs-h1);font-weight:500;letter-spacing:-.01em;color:var(--fg0);line-height:1.25}
.sfhead p{margin:4px 0 0;color:var(--fg2);font-size:var(--fs-sm);max-width:70ch}
.sfhead .sfacts{display:flex;flex-wrap:wrap;gap:16px 8px}
.sfhead .sfacts:empty{display:none}
.sftabs .tabs{display:flex;gap:8px}
.sftabs .tab{display:inline-flex;align-items:center;min-height:48px;box-sizing:border-box;border-bottom:2px solid transparent;padding:8px 14px 10px;margin-bottom:-1px;font-weight:500;font-size:var(--fs);color:var(--fg2);text-decoration:none}
.sftabs .tab:hover{color:var(--fg)}
.sftabs .tab.on{color:var(--fg0);border-bottom-color:var(--ink)}
.sftabs .tab .n{color:var(--fg2);font-size:var(--fs-sm);margin-left:6px;font-variant-numeric:tabular-nums;font-weight:400}
.sftabs .tab .n.hot{color:var(--crit);font-weight:600}
/* The SOS ticket in a panel from the right. */
main.gwsafety.issues.has-detail{grid-template-columns:minmax(0,1fr)}
main.gwsafety.issues #detail{position:fixed;top:var(--top);right:0;bottom:0;width:min(560px,100%);margin:0;border-radius:0;border-width:0 0 0 1px;
  overflow-y:auto;overscroll-behavior:contain;z-index:var(--z-sheet);box-shadow:var(--peek-shadow);animation:sfslide .16s ease-out}
main.gwsafety.issues #detail.hidden{display:none}
@keyframes sfslide{from{transform:translateX(24px);opacity:.6}to{transform:none;opacity:1}}
@media(prefers-reduced-motion:reduce){main.gwsafety.issues #detail{animation:none}}
.sfscrim{position:fixed;inset:var(--top) 0 0 0;background:color-mix(in srgb,var(--fg0) 28%,transparent);z-index:calc(var(--z-sheet) - 1);display:none}
body:has(main.gwsafety.issues #detail:not(.hidden)) .sfscrim{display:block}
/* SOS tab controls (Gokul, 21 Oct 2026): square corners for all of them, 40 px to look at and
   48 px to tap (workspace rule 15): buttons and chips catch the extra 4 px above and below with an
   invisible ::after (5 px from inside their 1 px border); the search box and the filters are 48 px boxes showing their middle 40 px,
   with the focus ring drawn inside it. All / Mine / Unassigned first in the filter row, 8 px apart.
   Safety only: the Support inbox keeps its look. */
main.gwsafety.issues > section.card.list .toolbar.filters{align-items:center;gap:16px 12px}
main.gwsafety.issues > section.card.list .toolbar.filters > .toolbar.inbox{padding:0;gap:16px 8px;flex-wrap:wrap}
main.gwsafety.issues > section.card.list .toolbar.filters input[type=search]{flex:1 1 220px;min-width:180px}
main.gwsafety.issues > section.card.list :is(.chip,.btn),main.gwsafety > .sfhead .btn,main.gwsafety.issues > #sos .btn{position:relative;min-height:40px;border-radius:var(--rs);font-size:var(--fs-sm)}
main.gwsafety.issues > section.card.list :is(.chip,.btn)::after,main.gwsafety > .sfhead .btn::after,main.gwsafety.issues > #sos .btn::after{content:"";position:absolute;left:-1px;right:-1px;top:-5px;bottom:-5px}
main.gwsafety.issues > section.card.list .btn.small,main.gwsafety.issues > #sos .btn.small{padding:0 16px}
main.gwsafety.issues > #sos .btn{height:40px;min-height:40px;padding-block:0}
main.gwsafety.issues > section.card.list :is(input[type=search],select){height:48px;min-height:48px;border:solid transparent;border-width:4px 0;background-clip:padding-box;
  box-shadow:inset 0 0 0 1px var(--edge);border-radius:var(--rs)/calc(var(--rs) + 4px);font-size:var(--fs-sm)}
main.gwsafety.issues > section.card.list :is(input[type=search],select):focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--focus)}
main.gwsafety > .sfhead > div:first-child{flex:1 1 320px;min-width:0}
main.gwsafety > .sfhead p{max-width:none}
/* The Add a zone form: the console's field look, each label above its box. */
.szpage form.szform label:not(.check){display:grid;gap:6px;font-size:var(--fs-sm);color:var(--fg2)}
.szpage form.szform :where(input[type=text],textarea){width:100%;box-sizing:border-box;min-height:48px;padding:10px 12px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg);font:inherit;font-size:var(--fs-sm)}
.szpage form.szform label.check{display:flex;align-items:center;gap:8px;min-height:48px;font-size:var(--fs-sm)}
@media(max-width:800px){.sftabs .tab{padding:8px 10px}main.gwsafety.issues #detail{top:0;z-index:var(--z-modal)}.sfscrim{display:none!important}
  main.gwsafety.issues .gwmorebtn{min-width:48px}
  main.gwsafety.issues > section.card.list .toolbar.inbox{overflow-y:hidden;padding-block:4px}}
@media(max-width:400px){.sftabs .tab{padding:8px 8px}.sftabs .tabs{padding-right:0;-webkit-mask-image:none;mask-image:none}}
/* Search everything written stays on the Support inbox only (Gokul, 21 Oct 2026). */
main.gwsafety.issues > #fts{display:none}
/* Zone heat on the fleet map (zoneheat.js; Michel, 25 Sept and 14 Oct 2026).
   Two parts. The switch and the metric (.zheat): between the card title and
   the map on a laptop, in Map controls on a phone, with one line saying what
   the colour means. The time bar (.zh-bar): docked on the map's bottom edge
   while the layer is on, a frosted glass capsule (design A, below) with the
   hour, chevrons, play, a hairline ruler and the legend; the zone card
   (.zh-card) opens above it. zoneheat.js sets
   --zh-l, --zh-w, --zh-b (where the map is) and --zh-bh, --zh-h (the bar's
   height, and the room it takes) on the card. Colours are the brand tokens only. */
.zheat{padding:0 var(--in,24px) 10px;display:flex;flex-direction:column;gap:6px;font-size:var(--fs-sm)}
.zheat .zh-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.zheat:not(.on) .zh-seg,.zheat:not(.on) .zh-explain{display:none}
.zheat .zh-toggle .zh-sw{width:14px;height:10px;border-radius:2px;background:linear-gradient(90deg,var(--y400),var(--gw-sun),var(--gw-coral));flex:none}
.zheat .zh-toggle[aria-pressed=true]{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
/* the metric picker is the shared segmented control (.gwseg) */
.zheat .zh-explain{margin:0;color:var(--fg2);line-height:1.4}
/* The time bar (Michel, 14 Oct 2026, design A of three: Apple Weather and Maps):
   one frosted glass capsule floating over the map, compact type, a hairline
   ruler, no boxed buttons. Glass where the browser blurs what is behind it,
   a solid card where it cannot. The zone card above it is the same glass. */
:root{--glass:rgba(255,255,255,.72);--glass-solid:var(--card);--glass-rim:rgba(255,255,255,.6);--glass-wash:rgba(120,120,128,.16);--glass-shadow:0 8px 28px rgba(0,0,0,.18)}
:root[data-mode=dark]{--glass:rgba(30,30,32,.62);--glass-rim:rgba(255,255,255,.12);--glass-wash:rgba(255,255,255,.12);--glass-shadow:0 8px 28px rgba(0,0,0,.4)}
@media (prefers-color-scheme:dark){:root[data-mode=system]{--glass:rgba(30,30,32,.62);--glass-rim:rgba(255,255,255,.12);--glass-wash:rgba(255,255,255,.12);--glass-shadow:0 8px 28px rgba(0,0,0,.4)}}
.zh-bar,.zh-card{background:var(--glass);-webkit-backdrop-filter:blur(24px) saturate(180%);backdrop-filter:blur(24px) saturate(180%);box-shadow:var(--glass-shadow),inset 0 0 0 .5px var(--glass-rim);color:var(--fg0);border:0}
@supports not ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){.zh-bar,.zh-card{background:var(--glass-solid)}}
.zh-bar{position:absolute;left:var(--zh-l,12px);width:var(--zh-w,auto);bottom:calc(var(--zh-b,12px) + var(--zh-safe,0px));z-index:1005;box-sizing:border-box;display:flex;flex-direction:column;gap:2px;padding:4px 4px 8px;border-radius:22px;font-size:var(--fs-sm);-webkit-user-select:none;user-select:none}
.zh-bar[hidden],.zh-card[hidden]{display:none}
body.mapmode .card.map{--zh-safe:var(--safe-b)}
.zh-top{display:flex;align-items:center;height:40px}
.zh-bar button{font:inherit;color:inherit;margin:0;padding:0;border:0;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent}
.zh-step{flex:none;width:40px;height:40px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;opacity:.55;touch-action:manipulation}
.zh-step svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.zh-step:hover:not(:disabled){opacity:.9}.zh-step:disabled{opacity:.18;cursor:default}
.zh-when{flex:1 1 auto;min-width:0;height:40px;display:flex;align-items:baseline;justify-content:center;gap:8px;padding-top:11px;box-sizing:border-box}
.zh-when:disabled{cursor:default}
.zh-kind{flex:none;font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fg2)}
.zh-kind[data-k=forecast]{color:var(--fg0);opacity:.75}
.zh-when b{min-width:0;font-size:16px;line-height:1.2;font-weight:600;letter-spacing:-.01em;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* the play glyph: a small disc inside a 40 px target */
.zh-play{flex:none;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;position:relative}
.zh-play::before{content:"";position:absolute;width:30px;height:30px;border-radius:50%;background:var(--glass-wash)}
.zh-play.on::before{background:var(--fg0)}.zh-play.on{color:var(--bg)}
.zh-play svg{position:relative;width:12px;height:12px;fill:currentColor}
.zh-bar button:focus-visible,.zh-scroll:focus-visible,.zh-card .zh-x:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;border-radius:999px}
/* the ruler: hairline ticks, the forecast a faint dashed baseline, one dot */
.zh-strip{position:relative;height:26px;margin:0 10px;-webkit-mask-image:linear-gradient(90deg,transparent,#000 16%,#000 84%,transparent);mask-image:linear-gradient(90deg,transparent,#000 16%,#000 84%,transparent)}
.zh-scroll{height:100%;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scrollbar-width:none;overscroll-behavior-x:contain;touch-action:pan-x;cursor:grab}
.zh-scroll::-webkit-scrollbar{display:none}
.zh-scroll.drag{cursor:grabbing;scroll-snap-type:none}
.zh-cells{display:flex;height:100%;width:max-content}
.zh-pad{flex:none;position:relative;height:100%}
.zh-pad em{position:absolute;bottom:0;font-style:normal;font-size:10px;line-height:1;color:var(--fg3);white-space:nowrap}
.zh-pad.l em{right:8px}.zh-pad.r em{left:8px}
.zh-c{flex:none;position:relative;width:14px;height:100%;scroll-snap-align:center;font-style:normal;cursor:pointer}
.zh-c::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:currentColor;opacity:.25}
.zh-c.forecast::after{background:repeating-linear-gradient(90deg,currentColor 0 2px,transparent 2px 5px)}
.zh-c.none::after{opacity:.08}
.zh-c b{position:absolute;left:6.5px;bottom:0;width:1px;height:5px;background:currentColor;opacity:.35}
.zh-c.big b{height:9px;opacity:.6}
.zh-c.forecast b{opacity:.18}.zh-c.forecast.big b{opacity:.35}
.zh-c.none b{opacity:.1}
.zh-c.nowc b{left:6px;width:2px;height:9px;opacity:1;background:var(--gw-lime)}
.zh-c em{position:absolute;left:7px;bottom:12px;transform:translateX(-50%);font-style:normal;font-size:10px;line-height:1;color:var(--fg2);white-space:nowrap;pointer-events:none;font-variant-numeric:tabular-nums}
.zh-c em.d{font-weight:600}
.zh-dot{position:absolute;left:50%;bottom:-4px;width:9px;height:9px;margin-left:-4.5px;border-radius:50%;background:var(--fg0);box-shadow:0 0 0 2px var(--glass-solid);pointer-events:none}
/* the legend: a thin colour bar with its whole numbers under it, then the unit */
.zh-legend{display:flex;align-items:flex-end;justify-content:center;flex-wrap:wrap;gap:2px 8px;padding:6px 12px 0;color:var(--fg2);font-size:11px;line-height:1}
.zh-scale{display:flex;flex-direction:column;gap:3px}
.zh-sw{display:flex;height:4px;border-radius:2px;overflow:hidden}
.zh-key{display:block;width:20px;height:4px}
.zh-scale.fut .zh-sw{opacity:.55}
.zh-nums{display:flex}.zh-nums em{width:20px;font-style:normal;font-variant-numeric:tabular-nums}
.zh-legend .zh-note{flex:1 1 100%;text-align:center;padding-top:3px;line-height:1.3}
/* the zone card, the same glass */
.zh-card{position:absolute;left:var(--zh-l,12px);bottom:calc(var(--zh-b,12px) + var(--zh-safe,0px) + var(--zh-bh,0px) + 8px);z-index:1006;width:min(300px,var(--zh-w,300px));box-sizing:border-box;padding:6px 6px 12px 16px;border-radius:20px;font-size:13px}
.zh-card-h{display:flex;align-items:center;justify-content:space-between;gap:8px}
.zh-card-h b{font-size:15px;font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.zh-card .zh-x{flex:none;width:40px;height:40px;border:0;border-radius:50%;background:none;color:var(--fg2);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0}
.zh-card .zh-x svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.zh-card-when{margin:0 0 4px;display:flex;align-items:baseline;gap:8px;color:var(--fg2)}
.zh-big{margin:0 0 8px;color:var(--fg2)}.zh-big b{font-size:24px;line-height:1.1;font-weight:600;color:var(--fg0);font-variant-numeric:tabular-nums}
.zh-card dl{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 12px;margin:0;padding-right:10px}
.zh-card dt{color:var(--fg2)}.zh-card dd{margin:0;text-align:right;font-variant-numeric:tabular-nums}
/* the map's own controls and the floating legend step up over the bar */
.card.map.zh-on .leaflet-bottom,body.mapmode .card.map.zh-on .leaflet-top.leaflet-right,body.mapmode .card.map.zh-on .leaflet-top.leaflet-left,.card.map.zh-lift>.legend{margin-bottom:var(--zh-h,0px)}
/* the position and driver reporting lines, folded behind "Data status" */
.legend .datastat{flex:1 1 100%;font-size:var(--fs-xs);color:var(--fg2)}
.datastat summary{display:flex;align-items:center;gap:8px;min-height:32px;list-style:none;cursor:pointer;font-weight:500;color:var(--fg2)}
.datastat summary::-webkit-details-marker{display:none}
.datastat summary::before{content:"";width:6px;height:6px;margin-left:2px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg);transition:transform .15s}
.datastat[open] summary::before{transform:rotate(45deg)}
.datastat>span{display:block;padding:2px 0 4px;line-height:1.45}.datastat>span:empty{display:none}
@media(pointer:coarse){.datastat summary{min-height:44px}}
/* Service recovery (care.html) */
main.carepage{display:grid;gap:18px}
.carepage [hidden]{display:none!important}
.carepage .row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
.carepage .lead{margin:0 0 12px}
.carepage .crstats{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;margin:6px 0 10px}
.carepage .crstat{display:flex;flex-direction:column;gap:2px;padding:10px 12px;border:1px solid var(--border);border-radius:var(--rs)}
.carepage .crstat b{font-size:var(--fs-title)}
.carepage .crform{display:grid;gap:10px;margin-top:14px;padding-top:14px;border-top:1px solid var(--border);max-width:640px}
.carepage .crfields{display:grid;gap:10px}
.carepage .crset{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px 16px;margin:8px 0 12px}
.carepage .crform label,.carepage .crset label{display:flex;flex-direction:column;gap:4px;font-size:var(--fs-sm)}
.carepage .crset label:has(input[type=checkbox]),.carepage label.check{flex-direction:row;align-items:center;gap:8px}
.carepage .cracts{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}
.carepage .crwhy{max-width:260px;white-space:normal}
.carepage .crhist{list-style:none;margin:6px 0 0;padding:0;text-align:left;font-size:var(--fs-sm);min-width:200px}.carepage .crhist li+li{margin-top:4px}

/* Incident reports (incidents.html) */
main.incpage{display:grid;gap:18px}
.incpage [hidden]{display:none!important}
.incpage .row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
.incpage .lead{margin:0 0 12px}
.incpage label.check{display:flex;align-items:center;gap:6px;font-size:var(--fs-sm)}
.incpage #in-table tbody tr{cursor:pointer}
.incpage #in-table tr.serious td:first-child{box-shadow:inset 3px 0 0 var(--crit)}
.incpage .insec{border-top:1px solid var(--border);padding:12px 0}
.incpage .insec h4{margin:0 0 8px;font-size:var(--fs);font-weight:600;color:var(--fg0)}
.incpage .infield{display:grid;grid-template-columns:180px minmax(0,1fr);gap:10px;padding:2px 0;font-size:var(--fs-sm)}
.incpage .inaccount{white-space:pre-wrap;margin:0}
.incpage .inphotos{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px}
.incpage .inphotos figure{margin:0}
.incpage .inphotos img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:var(--rs);border:1px solid var(--border);background:var(--panel)}
.incpage .inshut{display:grid;place-items:center;aspect-ratio:4/3;border-radius:var(--rs);border:1px dashed var(--border2);background:var(--panel);color:var(--fg3);font-size:var(--fs-xs);text-align:center;padding:8px}
.incpage .inphotos figcaption{font-size:var(--fs-xs);color:var(--fg3);margin-top:4px}
.incpage .insig{width:300px;max-width:100%;height:auto;border-bottom:1px solid var(--border2);margin:4px 0 10px}
.incpage .insig polyline{fill:none;stroke:var(--fg0);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.incpage .inlog{margin:0;padding-left:20px;font-size:var(--fs-sm);line-height:1.5}
.incpage .inform{display:grid;gap:10px;margin-top:14px;padding-top:14px;border-top:1px solid var(--border)}
.incpage .infields{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px 16px}
.incpage .infields label{display:flex;flex-direction:column;gap:4px;font-size:var(--fs-sm)}
.incpage .infields label.wide{grid-column:1/-1}
.incpage .infields label.check{flex-direction:row;align-items:center;align-self:end;gap:8px;min-height:36px}
.incpage .infields label.check input{margin:0}
.incpage #in-table td{vertical-align:top}
.incpage #in-table{width:100%}
.incpage #in-table td:nth-child(2){white-space:normal;min-width:220px;max-width:340px}
.incpage #in-table td:nth-child(2) .pill{display:inline-block;margin:2px 4px 0 0}
@media(max-width:700px){.incpage .infield{grid-template-columns:minmax(0,1fr)}}

/* The joint statement on the other driver's phone (statement.html). The
   sign-in card, so it reads as the same house. */
body.statement{align-items:start;padding:24px 16px}
.statement .card{width:min(560px,100%);padding:28px}
.statement .facts{display:grid;grid-template-columns:130px minmax(0,1fr);gap:6px 12px;margin:14px 0;font-size:var(--fs-sm)}
.statement .facts dt{color:var(--fg3)}.statement .facts dd{margin:0;color:var(--fg0)}
.statement .small{font-size:var(--fs-xs);word-break:break-all}
.statement textarea{width:100%;padding:10px 14px;border:1px solid var(--edge);border-radius:var(--rs);font:inherit}
.statement .pad{display:block;width:100%;height:180px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);touch-action:none}
.statement .padrow{display:flex;justify-content:flex-end;margin-top:6px}
.statement .padrow .btn{width:auto;margin-top:0}
.statement .err{color:var(--crit);font-size:var(--fs-sm);min-height:1em}
.statement .ok{color:var(--okfg);font-size:var(--fs);margin:12px 0 4px}
.statement [hidden]{display:none!important}
/* ---- public chargers on the fleet map (publiccharge.js) ---------------------
   The pin is the Lucide zap on the charging colour, so it reads as a place to
   charge and never as a car. A dashed edge is an approximate pin; faded is a
   site the GEA has announced but not opened. */
.chgpin{background:none;border:0}
.chgpin .chg{width:30px;height:30px;border-radius:9px;background:var(--chg);border:2px solid var(--gw-white);box-shadow:0 1px 4px rgba(1,30,19,.35);display:flex;align-items:center;justify-content:center;cursor:pointer}
.chgpin .chg svg{width:17px;height:17px;fill:var(--on-chg);stroke:none}
.chgpin .chg.approx{border-style:dashed}
.chgpin .chg.soon{opacity:.55}
.chgpin .chg.sel{border-color:var(--gw-yellow);border-width:3px;transform:scale(1.12)}
.legend .pcleg{display:inline-flex;align-items:center;gap:6px;cursor:pointer}
.legend .pcleg[aria-pressed=false]{opacity:.45;text-decoration:line-through}
/* Drivers on duty that no car pin shows (Michel, 12 Oct 2026): ink, never a lime fill. */
.drvpin{background:none;border:0;cursor:pointer}
.drvmini{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;background:var(--gw-charcoal);box-shadow:0 0 0 1.5px var(--gw-mint)}
.drvmini svg{width:10px;height:10px;fill:none;stroke:var(--gw-white);stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.chgmini{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:5px;background:var(--chg)}
.chgmini svg{width:11px;height:11px;fill:var(--on-chg)}
.pcd .pc-status{margin:0 0 8px;font-weight:500;color:var(--fg0)}
.pcd .pc-status.unknown{color:var(--fg2);font-weight:400}
.pcd .pc-status.out_of_service{color:var(--crit)}
.pcd .pc-rec{display:flex;flex-wrap:wrap;gap:6px;align-items:center;font-size:var(--fs-sm)}
.pcd .pc-rec select,.pcd .pc-rec input{height:32px;border:1px solid var(--edge);border-radius:var(--rs);padding:0 8px;background:var(--card);min-width:0}
.pcd .pc-rec input[name=free]{width:92px}.pcd .pc-rec input[name=note]{flex:1 1 140px}
.pcd .pc-rec .muted{flex:1 0 100%}
.pc-note{display:flex;flex-direction:column;gap:4px;font-size:var(--fs-sm);color:var(--fg2);margin-bottom:8px}
.pc-note input,#d-charge input,#d-charge select{height:var(--ctl);border:1px solid var(--edge);border-radius:var(--rs);padding:0 10px;background:var(--card);width:100%;min-width:0}
.pc-cars{list-style:none;margin:0;padding:0}
.pc-cars li{padding:9px 0;border-bottom:1px solid var(--border);display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:12px;row-gap:2px;align-items:center}
.pc-cars li.muted{display:block}
.pc-cars .pc-act{grid-column:2;grid-row:1/3}
.pc-cars .pc-act .result{grid-column:1/-1;flex-basis:100%}
.pc-cars .pc-act:has(.result:not(:empty)){grid-column:1/-1;grid-row:auto}
.pc-cars li:last-child{border-bottom:0}
.pc-car{display:flex;align-items:baseline;gap:8px;font-size:14px}
.pc-car a{text-decoration:none;color:var(--fg0)}
.pc-car span:nth-of-type(1){color:var(--fg2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.pc-soc{margin-left:auto;font-weight:500;font-variant-numeric:tabular-nums}.pc-soc.low{color:var(--crit)}
.pc-meta{font-size:var(--fs-sm);color:var(--fg2);display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.pc-meta .pill{font-size:var(--fs-xs);padding:1px 8px;border-radius:999px;background:var(--tint)}
.pc-act{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.pc-act .result{padding:0}
#d-charge{display:flex;flex-direction:column;gap:8px}
#d-charge .btn{white-space:normal;height:auto;min-height:36px;line-height:1.3;padding:6px 14px;text-align:left}
#d-charge .dc-pick{display:flex;gap:8px}#d-charge .dc-pick select{flex:1}
#d-charge p{margin:0}
.pcreg{grid-column:1/-1}
.pcreg .pc-intro{padding:0 var(--in,24px);margin:0 0 8px;max-width:980px}
.pcreg .pc-tablewrap{overflow-x:auto;padding:0 8px 8px}
.pc-table{width:100%;border-collapse:collapse;font-size:14px}
.pc-table th{text-align:left;font-size:var(--fs-lbl);text-transform:uppercase;letter-spacing:.06em;color:var(--fg3);font-weight:500;padding:8px 14px;border-bottom:1px solid var(--border)}
.pc-table td{padding:10px 14px;border-bottom:1px solid var(--border);vertical-align:top;height:auto;white-space:normal}
.pc-table td a{text-decoration:none}
.pc-table td:first-child{min-width:220px;max-width:340px}.pc-table td:last-child{width:1%}
.pc-table .mono{font-family:ui-monospace,Menlo,monospace;font-size:var(--fs-xs);white-space:nowrap}
.pc-form{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px 14px;padding:4px 0}
.pc-form .pc-f{display:flex;flex-direction:column;gap:3px;font-size:var(--fs-sm);color:var(--fg2)}
.pc-form .pc-f.wide{grid-column:span 2}
.pc-form input:not([type=checkbox]),.pc-form select{height:var(--ctl);border:1px solid var(--edge);border-radius:var(--rs);padding:0 10px;background:var(--card);min-width:0}
.pc-form input[type=checkbox]{width:18px;height:18px;margin:6px 0}
.pc-form .pc-formact{grid-column:1/-1;display:flex;gap:8px;align-items:center}.pc-form .pc-formact .result{padding:0}
.pc-adddet{padding:4px var(--in,24px) 18px}.pc-adddet summary{cursor:pointer;font-weight:500;color:var(--link);padding:6px 0}
@media(max-width:640px){.pc-form{grid-template-columns:1fr 1fr}.pc-form .pc-f.wide{grid-column:1/-1}.pcreg .pc-intro{padding:0 16px}}
.pc-car a b{white-space:nowrap}
@media(max-width:480px){.pc-cars li{grid-template-columns:1fr}.pc-cars .pc-act{grid-column:1;grid-row:auto;margin-top:4px}}
/* Start charge (GuyWay pays; the desk starts it in the Flash Charge portal) */
.pc-start{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px}.pc-start .result{padding:0}
#pc-start select{height:var(--ctl);border:1px solid var(--edge);border-radius:var(--rs);padding:0 10px;background:var(--card);width:100%;min-width:0}
.pc-portal{display:flex;flex-wrap:wrap;align-items:flex-end;gap:8px;padding:0 var(--in,24px) 12px}.pc-portal .pc-f{display:flex;flex-direction:column;gap:3px;flex:1 1 320px;font-size:var(--fs-sm);color:var(--fg2)}
.pc-portal input{height:var(--ctl);border:1px solid var(--edge);border-radius:var(--rs);padding:0 10px;background:var(--card)}
.pc-sh{margin:8px var(--in,24px) 4px;font-size:15px;font-weight:500;color:var(--fg0)}
.pc-table input{height:32px;border:1px solid var(--edge);border-radius:var(--rs);padding:0 8px;background:var(--card);min-width:0;width:100%}.pc-table input.pc-num{width:90px}
.pc-table th{position:static}

/* ---- phone and tablet (docs/console-mobile.md) ----------------------------
   Three layers, each additive to what is above:
   1. everywhere: the safe area. Installed on an iPhone or iPad the console
      draws under the status bar (viewport-fit=cover, black-translucent), so
      the page is pushed down by the status bar's height and a strip in the
      rail colour sits behind the clock. In a browser tab the inset is zero
      and nothing moves.
   2. a touch screen of any size: 44 px targets (Apple's minimum), taps that
      do not wait for a double tap, no hover-only menus.
   3. a narrow screen (900 px and under, or a phone on its side): the rail is
      put away for a tab bar at the foot and a More menu (chrome.js), the top
      bar turns rail-coloured, and tables pin their first column. */
:root{--safe-t:env(safe-area-inset-top,0px);--safe-b:env(safe-area-inset-bottom,0px);--safe-l:env(safe-area-inset-left,0px);--safe-r:env(safe-area-inset-right,0px);--tabbar:0px}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{padding-top:var(--safe-t)}
body::before{content:"";position:fixed;left:0;right:0;top:0;height:var(--safe-t);background:var(--rail);z-index:1200;pointer-events:none}
.side{top:var(--safe-t);height:calc(100vh - var(--safe-t));height:calc(100dvh - var(--safe-t))}
.top{top:var(--safe-t)}
.helppanel{top:var(--safe-t);height:calc(100vh - var(--safe-t));height:calc(100dvh - var(--safe-t))}
.env:empty{display:none}
.jumpbtn svg,.helpbtn svg,.gwburger{display:none}

/* 2. touch */
@media(pointer:coarse){
body{touch-action:manipulation;-webkit-tap-highlight-color:rgba(1,30,19,.12)}
.btn,.btn.small{height:auto;min-height:44px;line-height:1.2;padding-top:6px;padding-bottom:6px;justify-content:center}
.btn.small{padding-left:14px;padding-right:14px}
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]),select{min-height:44px}
.toolbar input[type=search],.toolbar input[type=text],.toolbar input[type=date],.toolbar input[type=month],.toolbar select,tr.filters input,tr.filters select{height:44px}
input[type=checkbox],input[type=radio]{width:22px;height:22px;flex:none}
label:has(>input[type=checkbox]),label:has(>input[type=radio]){min-height:44px;display:inline-flex;align-items:center;gap:8px}
.nav a{padding-top:12px;padding-bottom:12px}.nav .sub .links a{padding:12px 20px}.nav .sub b a{color:inherit;text-decoration:none;display:block;min-height:44px;line-height:44px;margin:-10px -20px -6px;padding:0 20px}
button.tab,a.tab,[role=tab],.tabs button,.tabs a{min-height:44px}
.who .whobtn{min-height:44px}.who .acct a,.who .acct button{min-height:44px;padding-top:12px;padding-bottom:12px}
th{height:48px}td{height:50px}
details>summary{min-height:44px;display:flex;align-items:center;cursor:pointer}
.leaflet-touch .leaflet-bar a{font-size:20px}
.map .legend span[role=button]{padding:0 4px}
.jump li{min-height:44px}
main button:not(.leaflet-control *),.helpbtn,.jumpbtn{min-height:44px}
.helpbtn{min-width:44px;justify-content:center}
td>a,td>b>a{display:inline-flex;align-items:center;min-height:44px}
.sosstrip a{display:inline-flex;align-items:center;min-height:44px;padding:0 4px}
.leaflet-touch .leaflet-bar a{width:44px;height:44px;line-height:44px}
.map .legend span[role=button],.legend .szleg{min-height:44px}
td input[type=checkbox],th input[type=checkbox]{width:24px!important;height:24px!important}
/* a cell that forwards taps to its checkbox (issues.js) is the target */
td[data-tap=cell],th[data-tap=cell]{min-width:48px;width:48px;cursor:pointer}
.pills button,.seg button,.gwseg>button{min-height:44px}
main .toolbar label.chk{min-height:44px}
main select{min-width:64px}
button.tab,a.tab,[role=tab]{min-width:44px;flex-shrink:0;justify-content:center}
.map .legend span[role=button]{min-width:44px}
.leaflet-control-layers label{display:inline-flex;align-items:center;gap:4px;min-height:44px}
.help a.more{display:inline-flex;align-items:center;min-height:44px}
}

/* 3. narrow: tab bar, More menu, rail-coloured top bar */
@media(max-width:900px),(pointer:coarse) and (max-width:1366px){
:root{--top:56px;--tabbar:0px}
body{grid-template-columns:minmax(0,1fr);grid-template-rows:var(--top) minmax(0,1fr);padding-left:var(--safe-l);padding-right:var(--safe-r);padding-bottom:calc(var(--tabbar) + var(--safe-b))}
.side{display:none}
.top{grid-column:1;grid-row:1;padding:0 6px 0 16px;gap:6px;background:var(--rail);border-bottom:0;color:var(--rail-fg);overflow:visible;z-index:var(--z-topbar)}
.top h1{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:18px;color:var(--gw-white)}
.top .right{gap:2px;padding-left:0;color:var(--rail-fg)}
.top #updated{display:none}
.top .env{background:transparent;color:var(--rail-fg);border-color:var(--rail3);max-width:180px;overflow:hidden;text-overflow:ellipsis}
.top .btn{background:transparent;border-color:transparent;color:var(--gw-white);min-width:44px;min-height:44px;height:44px;padding:0 10px;justify-content:center}
.top .btn:hover{background:var(--rail2);border-color:transparent}
.jumpbtn svg,.helpbtn svg{display:block;width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.helpbtn .q{display:none}
.top .jumpbtn,.top .helpbtn{width:44px;padding:0;border-radius:50%}
.jumpbtn .lbl,.jumpbtn kbd{display:none}
.helpbtn{font-size:17px}
.who{border-left:0;padding-left:0;gap:0}.who .name,.who .role,.who .whobtn .chev{display:none}
.who .whobtn{min-width:44px;min-height:44px;justify-content:center;padding:0 5px}.who .whobtn:hover{background:var(--rail2)}
.who .avatar{background:var(--gw-yellow);color:var(--gw-charcoal)}
.who .acct{position:fixed;right:calc(var(--safe-r) + 8px);top:calc(var(--safe-t) + var(--top) + 4px);width:min(320px,calc(100vw - 16px))}
.jump{top:calc(var(--safe-t) + var(--top) + 6px);left:calc(var(--safe-l) + 8px);right:calc(var(--safe-r) + 8px);transform:none;width:auto}
.jump input{font-size:16px}
main{grid-column:1;grid-row:2;padding:14px 14px 24px;gap:14px}
.sosstrip{position:sticky;top:calc(var(--safe-t) + var(--top) + 8px);z-index:900;order:-9;flex-wrap:nowrap;padding:4px 6px 4px 12px;font-size:14px;box-shadow:0 6px 18px rgba(184,70,31,.3)}
.sosstrip .what{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sosstrip a{flex:none;display:inline-flex;align-items:center;min-height:44px;padding:0 10px;margin-left:0}
.helppanel{width:100%;border-left:0;height:auto;bottom:calc(var(--tabbar) + var(--safe-b));z-index:1090}
.bulkbar{left:calc(var(--safe-l) + 8px)!important;right:calc(var(--safe-r) + 8px)!important;bottom:calc(var(--tabbar) + var(--safe-b) + 8px)!important}
/* tables: the first column (the car, the ride, the ticket) stays put while
   the rest scrolls sideways inside the card */
.tablewrap th:first-child,.tablewrap td:first-child,.card.list th:first-child,.card.list td:first-child{position:sticky;left:0;z-index:1;background:var(--card);box-shadow:inset -1px 0 0 var(--border)}
.tablewrap th:first-child,.card.list th:first-child{z-index:3;background:var(--panel)}
.tablewrap tr.filters td:first-child,.card.list tr.filters td:first-child{z-index:3}
tbody tr:hover td:first-child{background:var(--hover)}tbody tr.sel td:first-child{background:var(--sel)}
.card.list{max-height:none}
.auditwide ul{columns:1}
/* a detail panel's title and its buttons: the buttons drop under the title
   rather than squeezing it to one letter a line */
button.tab,a.tab{white-space:nowrap}
/* a select sizes itself to its longest option, which on a phone can be wider
   than the screen */
main select{max-width:100%;min-width:64px}main input:not([type=checkbox]):not([type=radio]){max-width:100%}
main div:has(>table):not(.tablewrap){overflow-x:auto;min-width:0}
.toolbar label{max-width:100%;min-width:0}.toolbar label>select{flex:1 1 auto;min-width:64px;width:100%}
.detail{scroll-margin-top:calc(var(--safe-t) + var(--top) + 64px)}
.detail .head{flex-wrap:wrap}.detail .head>div:first-child{flex:1 1 200px;min-width:0}

/* the hamburger, where the rail is put away (the menu itself is below) */
.gwburger{display:inline-flex;position:relative;align-items:center;justify-content:center;width:44px;height:44px;flex:none;border-radius:50%;border:0;background:transparent;color:var(--gw-white);cursor:pointer}
.gwburger:hover,.gwburger[aria-expanded=true]{background:var(--rail2)}
.gwburger svg{width:22px;height:22px;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;fill:none}
.gwburger .badge{position:absolute;top:3px;right:1px;min-width:19px;height:19px;padding:0 5px;border-radius:10px;background:var(--gw-coral);color:var(--gw-white);font-size:11px;font-weight:700;line-height:19px;text-align:center;box-shadow:0 0 0 2px var(--rail)}
.gwburger .badge[hidden]{display:none}
.gwburger:focus-visible{outline:2px solid var(--gw-yellow);outline-offset:1px}
/* the account lives in the menu here, so the avatar gives its room back */
.top .who{display:none}
}
/* iOS zooms the whole page into any field set under 16 px the moment it is
   tapped, and does not zoom back out. Important because page stylesheets set
   their fields' size with more specific selectors than any rule here. */
@media(max-width:900px) and (pointer:coarse),(pointer:coarse) and (max-width:1366px){
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]),select,textarea{font-size:16px!important}}
/* The narrow top bar has no room for the environment pill on a phone. */
@media(max-width:600px){
/* A destructive button (cancel a ride, offboard a driver, immobilise a car)
   never sits under the thumb beside the one that was meant: on a phone it
   moves to a line of its own under the others, the way iOS sets a
   destructive action apart, and is outlined rather than filled so it no
   longer looks like the primary action. */
.btn.danger{order:99;flex:1 1 100%;margin-left:0;margin-top:6px;justify-content:center;background:var(--card);color:var(--crit);border-color:var(--crit);border-width:1.5px}
.btn.danger:hover{background:var(--hover)}.top .env{display:none}.sosstrip .long{display:none}
/* the alert may run to two lines on a phone: the age and the car are at its end */
.sosstrip .what{white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.3}
/* tabs: one row that scrolls sideways, never a second ragged row */
.tabs{flex-wrap:nowrap!important;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}.tabs::-webkit-scrollbar{display:none}
.tabs>*{flex:none}
.leaflet-control-attribution{font-size:10px!important;line-height:1.3;max-width:70vw}}
/* a table that scrolls sideways says so: a soft shadow on the edge that has
   more behind it (the background moves with the content, the shadow stays) */
@media(max-width:900px){.tablewrap,.card.list{background:linear-gradient(to left,var(--card) 30%,transparent) right center/40px 100% no-repeat local,linear-gradient(to left,rgba(35,42,59,.14),transparent) right center/14px 100% no-repeat scroll,var(--card)}}
/* a touch screen with the rail (an iPad in landscape): the top bar holds the
   44 px controls, so the name and the timestamp give way to them */
@media(pointer:coarse) and (min-width:901px) and (max-width:1366px){.top #updated,.who .name,.who .role{display:none}}

/* ---- the fleet map on a small screen ----------------------------------------
   The map first and edge to edge, since it is what the page is for; the car
   list under it. On a phone a car's details rise from the bottom as a sheet
   over the list, leaving the top of the map (and the car on it) in view. */
@media(max-width:1100px),(pointer:coarse) and (max-width:1366px){
main.fleet>#detail{position:static;max-height:none}
main.fleet>.card.map{order:-3}
main.fleet>#detail{order:-2}
main.fleet>.stats{order:-1}
main.fleet>.card.list{order:1}
main.fleet>.auditwide{order:2}
main.fleet{display:flex;flex-direction:column}
main.fleet>.sosstrip{order:-9}
main.fleet #map{flex:none;height:56vh;height:56svh}
}
@media(max-width:700px){
main.fleet>.stats{order:1}
main.fleet>.card.map{margin:-14px -14px 0;border-radius:0;border-left:0;border-right:0;border-top:0;min-height:0}
main.fleet>.card.map>h3{display:none}
main.fleet>.card.map>.zheat{padding:8px 12px}
main.fleet #map{height:calc(100svh - var(--safe-t) - var(--top) - var(--tabbar) - var(--safe-b) - 150px);min-height:300px;border-radius:0}
.map .legend{left:8px;right:8px;bottom:8px;flex-wrap:nowrap;overflow-x:auto;gap:4px 12px;padding:0 10px;scrollbar-width:none}
.map .legend span[role=button]{min-height:36px}
.map .rangekey{left:8px;right:auto;top:auto!important;bottom:64px;max-width:calc(100% - 16px)}
.map .legend::-webkit-scrollbar{display:none}
.map .legend span,.map .legend a{white-space:nowrap;flex:none}
.map .legend #zonecounts,.map .legend #poscounts,.map .legend #drvcounts{display:none}
main.fleet.has-detail>#detail{position:fixed;left:var(--safe-l);right:var(--safe-r);bottom:calc(var(--tabbar) + var(--safe-b));top:auto;max-height:46vh;max-height:46svh;margin:0;z-index:1050;border-radius:16px 16px 0 0;border-bottom:0;box-shadow:0 -10px 34px rgba(20,24,33,.28);overscroll-behavior:contain}
main.fleet.has-detail>#detail .head{position:sticky;top:0;z-index:2;background:var(--card);padding-top:20px;flex-wrap:nowrap}
main.fleet.has-detail>.card.map>.zheat{display:none}
main.fleet.has-detail>#detail .head>div:first-child{flex:1 1 auto}main.fleet.has-detail>#detail .head .btn{margin-left:0;flex:none}
main.fleet.has-detail>#detail .head::before{content:"";position:absolute;top:7px;left:50%;width:38px;height:5px;margin-left:-19px;border-radius:3px;background:var(--border2)}
.facts{grid-template-columns:minmax(96px,40%) minmax(0,1fr)}
}

/* ---- the menu behind the hamburger (chrome.js) --------------------------------
   Modelled on the website's nav drawer (guyway-website site2.css: .nav-drawer):
   a charcoal scrim that fades in, a panel from the right that slides in 20 px
   and fades up, a round 44 px close button, groups divided by a rule, 18 px
   rows. Console tokens throughout. Shown only where the rail is put away. */
.gwmenu{display:none}
.gwmenu:not([hidden]){display:block;position:fixed;inset:0;z-index:var(--z-sheet)}
html.gwmenu-open,html.gwmenu-open body{overflow:hidden}
.gwmenu-scrim{position:absolute;inset:0;background:rgba(1,30,19,.5)}
.gwmenu-panel{position:absolute;top:0;right:0;height:100%;width:min(360px,92vw);background:var(--card);color:var(--fg);display:flex;flex-direction:column;box-shadow:-20px 0 60px rgba(1,30,19,.25);padding-top:var(--safe-t);padding-right:var(--safe-r)}
@media(prefers-reduced-motion:no-preference){.gwmenu-scrim{animation:gw-fade .25s ease-out both}.gwmenu-panel{animation:gw-slide .3s cubic-bezier(.2,.8,.2,1) both}
@keyframes gw-fade{from{opacity:0}to{opacity:1}}@keyframes gw-slide{from{transform:translateX(20px);opacity:0}to{transform:none;opacity:1}}}
.gwmenu-top{flex:none;display:flex;align-items:center;justify-content:space-between;padding:12px 16px 8px 24px}
.gwmenu-top b{font-size:var(--fs-lbl);font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--fg3)}
.gwmenu-close{width:44px;height:44px;flex:0 0 44px;border-radius:50%;border:0;background:var(--tint);color:var(--fg0);display:inline-flex;align-items:center;justify-content:center;cursor:pointer}
.gwmenu-close svg{width:16px;height:16px;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;fill:none}
.gwmenu-sos{flex:none;display:flex;align-items:center;gap:10px;margin:4px 16px 8px;padding:0 14px;min-height:48px;border-radius:var(--r);background:var(--gw-coral);color:var(--gw-white)!important;text-decoration:none;font-weight:500}
.gwmenu-sos[hidden]{display:none}.gwmenu-sos b{background:var(--gw-white);color:var(--gw-crit);padding:1px 8px;border-radius:999px;font-size:12px;letter-spacing:.06em}.gwmenu-sos i{margin-left:auto;font-style:normal;font-weight:600;text-decoration:underline}
.gwmenu-body{flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:0 16px 12px 24px}
.gwmenu-group{padding-top:12px;margin-top:8px;border-top:1px solid var(--border)}
.gwmenu-group:first-child{border-top:0;margin-top:0}
.gwmenu-group h5{margin:0 0 4px;font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--fg3)}
.gwmenu ul{list-style:none;margin:0;padding:0}
.gwmenu .row{display:flex;align-items:stretch}
.gwmenu .row a{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:14px;min-height:48px;padding:0 4px;color:var(--fg0);text-decoration:none;font-size:18px;font-weight:500}
.gwmenu .row a svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;flex:none;color:var(--fg2)}
.gwmenu a[aria-current=page]{color:var(--okfg)}.gwmenu a[aria-current=page] svg{color:var(--okfg)}
.gwmenu li.cur>.row a{box-shadow:inset 3px 0 0 var(--accent);padding-left:12px;margin-left:-12px}
.gwmenu .exp{flex:none;width:48px;min-height:48px;border:0;background:none;color:var(--fg3);cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:var(--rs)}
.gwmenu .exp i{width:9px;height:9px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg);margin-top:-4px;transition:transform .15s}
.gwmenu .exp[aria-expanded=true] i{transform:rotate(-135deg);margin-top:4px}
.gwmenu .subs{padding:0 0 8px 38px;display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}
.gwmenu .subs[hidden]{display:none}
.gwmenu .subs a{display:flex;align-items:center;min-height:44px;color:var(--fg);text-decoration:none;font-size:15px}
.gwmenu-foot{flex:none;border-top:1px solid var(--border);padding:12px 16px calc(12px + var(--safe-b)) 24px;background:var(--card)}
.gwmenu-who{display:flex;align-items:center;gap:12px;margin:0 0 10px}
.gwmenu-who .av{width:36px;height:36px;flex:none;border-radius:50%;background:var(--ink);color:var(--ink-hi);display:inline-flex;align-items:center;justify-content:center;font-weight:700}
.gwmenu-who .av.photo{overflow:hidden}.gwmenu-who .av img{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}
.gwmenu-who a{display:flex;flex-direction:column;min-height:44px;justify-content:center;text-decoration:none;min-width:0}
.gwmenu-who a b{color:var(--fg0);font-weight:500}.gwmenu-who a span{color:var(--fg3);font-size:var(--fs-sm)}
.gwmenu-acts{display:flex;gap:8px}.gwmenu-acts .btn{min-height:44px;height:auto;flex:1 1 0;justify-content:center;padding-left:8px;padding-right:8px}.gwmenu-acts [hidden]{display:none}
.gwmenu-acts .gwout{color:var(--crit);border-color:var(--crit)}
/* the list fades at its foot while there is more of it below */
.gwmenu-body{-webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 28px),transparent);mask-image:linear-gradient(to bottom,#000 calc(100% - 28px),transparent);padding-bottom:28px}
.gwmenu-env{font-size:var(--fs-xs);color:var(--fg2);border:1px solid var(--border2);border-radius:999px;padding:2px 10px;margin-right:auto;margin-left:10px;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gwmenu-env[hidden]{display:none}.gwmenu-env.live{color:var(--okfg);border-color:var(--gw-mint)}
/* Install app on iOS: the steps, as a card */
.gwinstall-help:not([hidden]){position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:flex-end;justify-content:center;background:rgba(1,30,19,.5);padding:16px 16px calc(16px + var(--safe-b))}
.gwinstall-help[hidden]{display:none}
/* Inside the GuyWay Ops app (console-native.js) there is nothing to install. */
html.gwnative .gwinstall{display:none!important}
.gwinstall-card{width:min(440px,100%);background:var(--card);color:var(--fg);border-radius:16px;padding:var(--in,24px) var(--in,24px) 18px;box-shadow:0 -10px 40px rgba(1,30,19,.3)}
.gwinstall-card h2{margin:0 0 10px;font-size:var(--fs-title);font-weight:500;color:var(--fg0)}
.gwinstall-card ol{margin:0 0 12px;padding-left:20px;line-height:1.55}.gwinstall-card li{margin:4px 0}
.gwinstall-card .btn{width:100%;justify-content:center;min-height:44px}
.who .acct .gwinstall[hidden]{display:none}

/* ---- the fleet map as the page, on a phone or a tablet (mapmode.js) ----------- */
.mm-ui,.mm-back,.mm-sheet,.mm-grab{display:none}
.mm-sheet:not([hidden]){display:block;position:fixed;inset:0;z-index:1170}
.mm-scrim{position:absolute;inset:0;background:rgba(1,30,19,.35)}
.mm-panel{position:absolute;left:0;right:0;bottom:0;max-height:min(78%,640px);margin:0 auto;width:min(560px,100%);background:var(--card);color:var(--fg);border-radius:16px 16px 0 0;display:flex;flex-direction:column;box-shadow:0 -10px 40px rgba(1,30,19,.3);padding-bottom:var(--safe-b)}
@media(prefers-reduced-motion:no-preference){.mm-panel{animation:gw-rise .22s ease-out both}@keyframes gw-rise{from{transform:translateY(24px);opacity:.6}to{transform:none;opacity:1}}}
.mm-head{flex:none;display:flex;align-items:center;justify-content:space-between;padding:10px 12px 6px 20px}
.mm-head b{font-size:var(--fs-title);font-weight:500;color:var(--fg0)}
.mm-close{width:44px;height:44px;border-radius:50%;border:0;background:var(--tint);color:var(--fg0);display:inline-flex;align-items:center;justify-content:center;cursor:pointer}
.mm-close svg{width:16px;height:16px;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;fill:none}
.mm-body{overflow-y:auto;overscroll-behavior:contain;padding:0 20px 16px}
.mm-sec{padding:12px 0;border-top:1px solid var(--border)}.mm-sec:first-child{border-top:0}.mm-sec[hidden]{display:none}
.mm-sec h5{margin:0 0 8px;font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--fg3)}
.mm-sec>p{margin:0 0 8px;font-size:var(--fs-sm)}
/* .mm-seg: the shared segmented control (.gwseg) */
.mm-lists{display:flex;flex-wrap:wrap;gap:8px}
/* the moved controls, set as rows in the sheet rather than over a map */
.mm-sheet .legend{position:static;display:flex;flex-wrap:wrap;gap:6px;background:none;border:0;box-shadow:none;padding:0}
.mm-sheet .legend span[role=button],.mm-sheet .legend .pcleg,.mm-sheet .legend .szleg{min-height:44px;padding:0 14px;border:1px solid var(--edge);border-radius:var(--rs);display:inline-flex;align-items:center;gap:6px}
.mm-sheet .legend [aria-pressed=true]{background:var(--sel);border-color:var(--focus);color:var(--fg0)}
.mm-sheet .legend [aria-pressed=false]{opacity:.5;text-decoration:line-through;background:none}
.mm-sheet .legend .muted{flex:1 1 100%}
.mm-sheet .zheat{padding:0}
.mm-sheet .rangekey{position:static;width:auto;background:none;border:0;box-shadow:none;padding:0}
.mm-sheet .rangekey[hidden]{display:none}
.mm-sheet .rangekey.open{background:var(--panel);border:1px solid var(--border);border-radius:var(--rs);padding:12px}

@media(max-width:900px),(pointer:coarse) and (max-width:1366px){
body.mapmode main.fleet:not(.listview){position:fixed;left:0;right:0;top:calc(var(--safe-t) + var(--top));bottom:0;padding:0;display:block;overflow:hidden;animation:none}
body.mapmode main.fleet:not(.listview)>:not(.map):not(#detail):not(#pc-detail):not(#ccnow.open){display:none!important}
body.mapmode main.fleet:not(.listview)>.card.map{position:absolute;inset:0;margin:0;border:0;border-radius:0;min-height:0;box-shadow:none}
body.mapmode main.fleet:not(.listview)>.card.map>h3{display:none}
body.mapmode main.fleet:not(.listview) #map{position:absolute!important;inset:0;height:auto!important;min-height:0;border-radius:0}
body.mapmode main.fleet:not(.listview) .leaflet-control-layers,body.mapmode main.fleet:not(.listview) .leaflet-control-zoom{display:none}
body.mapmode main.fleet:not(.listview) .leaflet-control-attribution{font-size:10px!important;opacity:.8}
body.mapmode main.fleet:not(.listview) .leaflet-top.leaflet-right{top:auto;bottom:calc(var(--safe-b) + 4px)}
/* the floating controls */
body.mapmode main.fleet:not(.listview) .mm-ui{display:flex;flex-direction:column;gap:8px;position:absolute;left:calc(var(--safe-l) + 10px);right:calc(var(--safe-r) + 10px);top:10px;z-index:1010;pointer-events:none}
.mm-ui>*{pointer-events:auto}
.mm-filter{align-self:flex-start;min-height:44px;padding:0 18px;border:0;border-radius:var(--rs);background:var(--chip);color:var(--chip-fg);font-weight:500;font-size:var(--fs-sm);box-shadow:0 2px 10px rgba(1,30,19,.22);cursor:pointer}.mm-filter[hidden]{display:none}
.mm-sos:empty{display:none}
.mm-sos .sosstrip{position:static;margin:0;box-shadow:0 6px 18px rgba(184,70,31,.3)}
.mm-row{display:flex;gap:8px;align-items:flex-start}
.mm-find{position:relative;flex:1 1 auto;min-width:0;max-width:420px}
.mm-find input{width:100%;height:46px;border:1px solid var(--well-edge);border-radius:999px;padding:0 16px 0 42px;background:var(--card);color:var(--fg0);font-size:16px!important;box-shadow:0 2px 10px rgba(1,30,19,.22)}
.mm-find-ico{position:absolute;left:14px;top:13px;color:var(--fg3);pointer-events:none}
.mm-find-ico svg,.mm-btn svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;display:block}
.mm-results{position:absolute;left:0;right:0;top:52px;margin:0;padding:6px;list-style:none;background:var(--card);border-radius:var(--r);box-shadow:0 10px 30px rgba(1,30,19,.25);max-height:50vh;overflow:auto}
.mm-results[hidden]{display:none}
.mm-results li{display:flex;align-items:center;gap:10px;min-height:48px;padding:0 10px;border-radius:var(--rs);cursor:pointer}
.mm-results li[aria-selected=true],.mm-results li:hover{background:var(--sel)}
.mm-results li b{font-weight:600;color:var(--fg0)}.mm-results li span{flex:1;min-width:0;color:var(--fg2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mm-results li i{font-style:normal;color:var(--fg2);font-variant-numeric:tabular-nums}
.mm-results li.none{color:var(--fg3);cursor:default}
.mm-btn{flex:none;width:46px;height:46px;border-radius:50%;border:0;background:var(--card);color:var(--fg0);display:inline-flex;align-items:center;justify-content:center;box-shadow:0 2px 10px rgba(1,30,19,.22);cursor:pointer}
.mm-btn[aria-expanded=true]{background:var(--ink);color:var(--ink-hi)}
/* the list view: the page as on a laptop, stacked, with a way back */
body.mapmode main.fleet.listview .mm-ui{display:none}
body.mapmode main.fleet.listview .mm-back{display:inline-flex;position:fixed;right:calc(var(--safe-r) + 16px);bottom:calc(var(--safe-b) + 16px);z-index:1020;min-height:48px;padding:0 20px;border-radius:var(--rs);box-shadow:0 6px 20px rgba(1,30,19,.3)}
body.mapmode main.fleet.listview{padding-bottom:88px}
/* the car and charger sheets: a peek, then everything */
body.mapmode main.fleet:not(.listview)>#detail,body.mapmode main.fleet:not(.listview)>#pc-detail{position:absolute;left:0;right:0;bottom:0;top:auto;width:auto;margin:0 auto;max-width:560px;z-index:1050;border-radius:16px 16px 0 0;border-bottom:0;box-shadow:0 -10px 34px rgba(1,30,19,.28);overflow-y:auto;overscroll-behavior:contain;padding-bottom:var(--safe-b);transition:max-height .22s ease-out}
body.mapmode main.fleet:not(.listview)>:is(#detail,#pc-detail).mm-peek{max-height:min(44%,300px);overflow:hidden}
body.mapmode main.fleet:not(.listview)>:is(#detail,#pc-detail).mm-full{max-height:calc(100% - 64px)}
body.mapmode main.fleet:not(.listview)>:is(#detail,#pc-detail) .mm-grab{display:block;position:sticky;top:0;z-index:3;width:100%;height:22px;border:0;padding:0;margin:0;background:var(--card);cursor:pointer;touch-action:none}
body.mapmode main.fleet:not(.listview)>:is(#detail,#pc-detail) .mm-grab::before{content:"";display:block;width:40px;height:5px;margin:8px auto 0;border-radius:3px;background:var(--border2)}
body.mapmode main.fleet:not(.listview)>:is(#detail,#pc-detail) .head{position:sticky;top:22px;z-index:2;background:var(--card);padding-top:4px;flex-wrap:nowrap;touch-action:none}
body.mapmode main.fleet:not(.listview)>:is(#detail,#pc-detail) .head::before{display:none}
body.mapmode main.fleet:not(.listview)>:is(#detail,#pc-detail) .head>div:first-child{flex:1 1 auto;min-width:0}
body.mapmode main.fleet:not(.listview)>:is(#detail,#pc-detail) .head .btn{margin-left:0;flex:none}
/* on a tablet the sheet is a card at the bottom left, the map beside it */
@media(min-width:760px){body.mapmode main.fleet:not(.listview)>#detail,body.mapmode main.fleet:not(.listview)>#pc-detail{left:calc(var(--safe-l) + 12px);right:auto;width:420px;bottom:12px;border-radius:16px;border:1px solid var(--border)}
body.mapmode main.fleet:not(.listview)>:is(#detail,#pc-detail).mm-full{max-height:calc(100% - 84px)}}
}
/* pins keep their drawn size inside a 44 px target on a touch screen (app.js) */
.carpin,.chgpin,.drvpin{display:flex!important;align-items:center;justify-content:center}
.chgpin .chg.chgn{width:34px;height:34px;border-radius:50%;background:var(--gw-charcoal);border:3px solid var(--chg);box-shadow:0 0 0 1.5px var(--gw-white),0 1px 4px rgba(1,30,19,.35)}
.chgpin .chg.chgn b{color:var(--gw-yellow);font-size:14px;font-weight:700}
/* touch: cars drawn a little larger inside their 44 px target (app.js) */
@media(pointer:coarse){.carpin .car,.carpin .car svg{width:38px;height:38px}}
/* the help button is a drawn icon (help.js), styled with the magnifier above */
@media(max-width:900px),(pointer:coarse) and (max-width:1366px){
/* on a tablet the map controls open as a card under their button, not a
   sheet across the map, and the zoom buttons come back, bottom right */
@media(min-width:760px){.mm-sheet .mm-scrim{background:rgba(1,30,19,.12)}
.mm-panel{top:calc(var(--safe-t) + var(--top) + 70px);bottom:auto;left:auto;right:calc(var(--safe-r) + 12px);margin:0;width:380px;max-height:calc(100% - var(--safe-t) - var(--top) - 90px);border-radius:16px;padding-bottom:0}
body.mapmode main.fleet:not(.listview) .leaflet-control-zoom{display:block}
body.mapmode main.fleet:not(.listview) .leaflet-top.leaflet-left{top:auto;left:auto;right:calc(var(--safe-r) + 12px);bottom:calc(var(--safe-b) + 28px)}}
}

/* 5. iPhone and iPad polish (30 Sept 2026) */
@media(max-width:900px),(pointer:coarse) and (max-width:1366px){
/* a strip that scrolls says so: its last item fades into the edge */
.tabs{-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(to right,#000 calc(100% - 32px),transparent);padding-right:24px}
}
@media(max-width:600px){
/* list tables read as cards (chrome.js labels the cells) */
table.gwcards,table.gwcards>tbody,table.gwcards>tbody>tr,table.gwcards>tbody>tr>td,table.gwcards>tfoot,table.gwcards>tfoot>tr,table.gwcards>tfoot>tr>td{display:block;width:auto}
table.gwcards>tfoot>tr{margin:0 0 10px;padding:10px 14px;border-radius:14px;background:var(--panel)}
table.gwcards>tfoot>tr>td{border:0;height:auto;padding:4px 0;text-align:right;white-space:normal;overflow-wrap:anywhere;position:static!important}
table.gwcards>tfoot>tr>td::before{content:attr(data-label);float:left;margin-right:12px;color:var(--fg3);font-size:var(--fs-sm)}
table.gwcards>tfoot>tr>td[data-label=""]::before,table.gwcards>tfoot>tr>td:first-child::before{content:none}
table.gwcards>tfoot>tr>td:first-child{text-align:left;font-weight:600}
table.gwcards>tfoot>tr>td:empty{display:none}
table.gwcards>thead{display:none}
table.gwcards>tbody>tr{position:relative;margin:0 0 10px;padding:10px 14px;border:1px solid var(--border);border-radius:14px;background:var(--card);box-shadow:var(--shadow)}
table.gwcards>tbody>tr>td{position:static!important;box-shadow:none!important;background:transparent!important;border:0;height:auto;min-height:0;padding:5px 0;display:block;text-align:right;white-space:normal;overflow-wrap:anywhere}
table.gwcards>tbody>tr>td::after{content:"";display:table;clear:both}
table.gwcards>tbody>tr>td::before{content:attr(data-label);float:left;max-width:42%;margin-right:12px;text-align:left;color:var(--fg3);font-size:var(--fs-sm);font-weight:500}
table.gwcards>tbody>tr>td[data-label=""]::before{content:none}
table.gwcards>tbody>tr>td:first-child{display:block;text-align:left;font-size:16px;padding:0 0 6px;margin:0 0 4px;border-bottom:1px solid var(--border)}
table.gwcards>tbody>tr>td:first-child::before{content:none}
table.gwcards>tbody>tr>td:empty{display:none}
/* a row's selection checkbox sits in the card's corner; the next cell is its title */
table.gwcards>tbody>tr>td:first-child:has(>input[type=checkbox]){position:absolute!important;top:6px;right:8px;width:auto;min-width:44px;padding:0;margin:0;border:0;display:flex;justify-content:center;align-items:center;min-height:44px}
table.gwcards>tbody>tr>td:first-child:has(>input[type=checkbox])+td{text-align:left;font-size:16px;padding:0 52px 6px 0;margin:0 0 4px;border-bottom:1px solid var(--border)}
table.gwcards>tbody>tr>td:first-child:has(>input[type=checkbox])+td::before{content:none}
table.gwcards>tbody>tr.filters{display:none}
main .tablewrap:has(>table.gwcards),main .card.list:has(table.gwcards){background:none!important;max-height:none}
}
/* the car panel's Contact group for the driver on shift (app.js, chrome.js gwContact) */
.detail .d-quick{padding-top:12px;padding-bottom:12px}
.dpanel .d-contact{margin:8px 0 14px}
/* the charger panel opens on a summary; the report form waits behind its button (publiccharge.js) */
.pcd .pc-sumfacts{list-style:none;margin:10px 0;padding:0;display:flex;flex-direction:column;gap:2px;font-size:var(--fs-sm);color:var(--fg2)}
.pcd .pc-sumact{display:flex;flex-wrap:wrap;gap:8px}
.pcd .pc-sumact .btn{min-height:44px;flex:1 1 auto;justify-content:center}
.pcd .sec{scroll-margin-top:84px}
.pcd .pc-go-report{min-height:44px}
.pcd .pc-sum .pc-status{margin-bottom:10px}
body.mapmode main.fleet:not(.listview)>#pc-detail .head .vin{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* 6. any map opens full screen (chrome.js, 30 Sept 2026) */
.gwmapfull{position:absolute;top:10px;right:10px;z-index:1001;width:40px;height:40px;border-radius:50%;border:0;background:var(--card);color:var(--fg0);box-shadow:0 1px 4px rgba(1,30,19,.3);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0}
.gwmapfull:hover{background:var(--panel)}
.gwmapfull:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.gwmapfull svg{width:20px;height:20px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
@media(pointer:coarse){.gwmapfull{width:44px;height:44px}}
.gwmapfull-on{position:fixed!important;inset:0!important;top:var(--safe-t,0px)!important;width:auto!important;height:auto!important;max-height:none!important;min-height:0!important;margin:0!important;border-radius:0!important;z-index:var(--z-fullscreen)!important}
/* A map is a stacking context of its own, so a map opened full screen would
   stay under the top bar; the card holding it rises with it. */
.card.map:has(.gwmapfull-on){z-index:var(--z-fullscreen)}
.gwmapfull-on>.gwmapfull{top:calc(12px + env(safe-area-inset-top,0px));right:calc(12px + env(safe-area-inset-right,0px))}
body.gwmapfull-open{overflow:hidden}
/* the Leaflet zoom and layer controls sit clear of the button */
.leaflet-container:has(>.gwmapfull) .leaflet-top.leaflet-right{margin-top:52px}

/* Low connectivity (chrome.js gwNet, Michel, 4 Oct 2026): the connection dot
   and words in the header (green live, amber slow, grey offline, Michel,
   13 Oct 2026; a tap checks again), the banner once the page's data is over 30 s old,
   the "Map paused to save data" chip, and the grey on a car or driver not
   heard from for two minutes. */
.netstate{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-sm);color:var(--fg3)}
.netstate i{width:8px;height:8px;border-radius:50%;background:var(--gw-mint);flex:none}
.netstate[data-state=slow] i{background:var(--gw-sun);box-shadow:0 0 0 1px var(--c500)}
.netstate[data-state=slow]{color:var(--fg)}
.netstate[data-state=offline] i{background:var(--rail-fg2)}
.netstate[data-state=offline]{color:var(--fg);font-weight:500}
.top .netstate{cursor:pointer}
.gw-stale{grid-column:1/-1;background:var(--gw-sun);color:var(--gw-charcoal);border-radius:var(--rs);padding:10px 16px;font-size:var(--fs-sm);font-weight:500}
.netchip{position:absolute;top:14px;right:16px;z-index:1001;display:inline-flex;align-items:center;gap:10px;min-height:36px;padding:0 6px 0 14px;border-radius:999px;border:1px solid var(--gw-charcoal);background:var(--gw-sun);color:var(--gw-charcoal);font:500 var(--fs-sm)/1 var(--font);cursor:pointer}
.netchip[hidden]{display:none}
.netchip b{background:var(--gw-charcoal);color:var(--gw-white);border-radius:999px;padding:6px 10px;font-weight:600}
#fleet tr.oldpos td{color:var(--fg3)}
#fleet tr.oldpos td .pill{opacity:var(--oldpos-dim)}
.seen.old,#fleet tr.oldpos td.seen{color:var(--crit)}
html.gw-weak .szring span{animation:none}
html.gw-weak .leaflet-zoom-anim .leaflet-zoom-animated,html.gw-weak .leaflet-fade-anim .leaflet-tile{transition:none!important}
@media(max-width:900px),(pointer:coarse) and (max-width:1366px){
.netstate{color:var(--rail-fg);padding:0 6px}
.netstate[data-state=live] span{display:none}
.netstate[data-state=offline]{color:var(--rail-fg)}
.gw-stale{position:sticky;top:calc(var(--safe-t) + var(--top) + 8px);z-index:899;order:-8}
.netchip{position:fixed;left:50%;right:auto;top:auto;transform:translateX(-50%);min-height:44px;bottom:calc(var(--tabbar) + var(--safe-b) + 84px);box-shadow:0 2px 8px rgba(1,30,19,.25)}
}
/* ---- phone: team views and the island (#1177) ---------------------------------
   chrome.js sets html.gwviews on a phone (600 px and under) for every login but
   a confined one. Nothing here applies anywhere else: the laptop and the iPad
   keep the rail and the hamburger menu exactly as they were.
   The look is the rider and driver apps' (gw-rider-app src/ui/theme.ts,
   src/ui/tabs/bar.tsx, src/lib/homegap.ts). Every colour of it is a token in
   this first block, so a different brand choice is a change here alone. */
.gwtitle{display:contents}.gwview,.gwisland,.gwmenu-pages,.gwburger .ic-pages{display:none}
.gwvsheet{display:none}
html.gwviews,body.gwoff{
  --isl-bar:#FBFBFB;--isl-pill:#E9E9E9;--isl-bubble:rgba(255,255,255,.96);--isl-bubble-edge:rgba(0,0,0,.12);
  --isl-lit-fill:var(--gw-yellow);--isl-lit-edge:#D2E80F;--isl-icon:#8E8E93;--isl-label:#000000;--isl-shadow:0 8px 24px rgba(0,0,0,.10);
  --isl-ink:#000000;--isl-on-ink:var(--gw-yellow);
  /* the island is 62 tall and 21 above the foot; the page, the help panel,
     the bulk bar, the toast and the map's sheets keep clear of it (--tabbar) */
  --tabbar:92px}
html.gwviews[data-mode=dark],html[data-mode=dark] body.gwoff{--isl-bar:#262626;--isl-pill:#444444;--isl-bubble:rgba(255,255,255,.26);--isl-bubble-edge:rgba(255,255,255,.35);--isl-lit-fill:none;--isl-lit-edge:var(--gw-yellow);--isl-icon:#FFFFFF;--isl-label:#FFFFFF;--isl-shadow:0 8px 24px rgba(0,0,0,.35);--isl-ink:var(--gw-yellow);--isl-on-ink:#000000}
@media (prefers-color-scheme:dark){html.gwviews[data-mode=system],html[data-mode=system] body.gwoff{--isl-bar:#262626;--isl-pill:#444444;--isl-bubble:rgba(255,255,255,.26);--isl-bubble-edge:rgba(255,255,255,.35);--isl-lit-fill:none;--isl-lit-edge:var(--gw-yellow);--isl-icon:#FFFFFF;--isl-label:#FFFFFF;--isl-shadow:0 8px 24px rgba(0,0,0,.35);--isl-ink:var(--gw-yellow);--isl-on-ink:#000000}}

/* the view's name over the page title. The whole title is the button's
   target (taller than 44 px), the name drawn at its top and the page title
   under it; the title lets a tap through to the button. */
html.gwviews .gwtitle{display:flex;position:relative;flex:1 1 auto;align-self:stretch;min-width:0;flex-direction:column;justify-content:center;padding-top:15px}
html.gwviews .gwtitle h1{flex:none;line-height:1.15;pointer-events:none;position:relative}
html.gwviews .gwview{display:flex;position:absolute;inset:0;align-items:flex-start;gap:4px;margin:0;padding:9px 0 0;border:0;border-radius:0;background:transparent;color:var(--rail-fg);font:500 13px/1 var(--font);text-align:left;cursor:pointer}
html.gwviews .gwview i{width:7px;height:7px;border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:rotate(45deg);margin:0 0 0 4px}
/* One line, cut with an ellipsis: a long name ("Choose your view", "Operations Manager") beside "Slow connection" folded onto
   two lines over the page name (Lisbon, WP2 B1). The full name stays in the text and the button's aria-label. */
html.gwviews .gwview{max-width:100%;min-width:0}
html.gwviews .gwview span{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
html.gwviews .gwview i{flex:none}
/* "Slow connection" and "Offline, last update ..." on a phone (Gokul, WP2, 19 Oct): a thin strip under the top bar, the full width, in
   place of the words in the bar, so the bar keeps room for the view's name in full. The same element (role=status),
   only drawn elsewhere, so a screen reader hears it once. The page moves down by the strip while it shows; the Live
   dot stays in the bar. Laptops and tablets are unchanged. */
html.gwviews{--gwslow:26px}
html.gwviews .top .netstate:is([data-state=slow],[data-state=offline]){position:absolute;left:0;right:0;top:100%;height:var(--gwslow);justify-content:center;padding:0 16px;background:var(--gw-sun);color:var(--gw-charcoal);font-weight:500;white-space:nowrap;z-index:1}
/* Offline (Gokul, 19 Oct): the same strip in a neutral grey that follows light and dark. */
html.gwviews .top .netstate[data-state=offline]{background:var(--border2);color:var(--fg0)}
html.gwviews .top .netstate:is([data-state=slow],[data-state=offline]) i{display:none}
html.gwviews:has(.top .netstate:is([data-state=slow],[data-state=offline])) main{margin-top:var(--gwslow)}
html.gwviews:has(.top .netstate:is([data-state=slow],[data-state=offline])) .gw-stale{top:calc(var(--safe-t) + var(--top) + var(--gwslow) + 8px)}
html.gwviews .gwview:focus-visible{outline:2px solid var(--gw-yellow);outline-offset:-2px;border-radius:var(--rs)}

/* the sheet of views */
html.gwviews .gwvsheet:not([hidden]){display:block;position:fixed;inset:0;z-index:1185}
.gwvsheet-scrim{position:absolute;inset:0;background:rgba(0,0,0,.38)}
.gwvsheet-panel{position:absolute;left:0;right:0;bottom:0;max-height:88%;overflow-y:auto;overscroll-behavior:contain;background:var(--card);color:var(--fg);border-radius:20px 20px 0 0;padding:8px 16px calc(16px + var(--safe-b));box-shadow:0 -10px 34px rgba(0,0,0,.2)}
@media(prefers-reduced-motion:no-preference){.gwvsheet-scrim{animation:gw-fade .2s ease-out both}.gwvsheet-panel{animation:gw-rise .22s ease-out both}}
.gwvsheet-grab{width:36px;height:5px;border-radius:3px;background:var(--border2);margin:4px auto 10px}
.gwvsheet-head{display:flex;align-items:center;justify-content:space-between}
.gwvsheet-head b{font-size:18px;font-weight:700;letter-spacing:-.02em;color:var(--fg0)}
.gwvsheet-close{width:44px;height:44px;border-radius:50%;border:0;background:var(--tint);color:var(--fg0);display:inline-flex;align-items:center;justify-content:center;cursor:pointer}
.gwvsheet-close svg{width:16px;height:16px;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;fill:none}
.gwvsheet-panel>p{margin:2px 0 10px;color:var(--fg2);font-size:13px}
.gwvsheet-opt{display:grid;grid-template-columns:36px minmax(0,1fr);gap:12px;align-items:center;min-height:56px;padding:8px;border-radius:12px;color:var(--fg0)!important;text-decoration:none}
.gwvsheet-opt:hover{background:var(--hover)}
.gwvsheet-opt[aria-current=true]{background:var(--sel)}
.gwvsheet-opt .ic{width:36px;height:36px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:var(--tint);color:var(--fg0)}
.gwvsheet-opt[aria-current=true] .ic{background:var(--isl-ink);color:var(--isl-on-ink)}
.gwvsheet-opt .ic svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.gwvsheet-opt .tx b{display:block;font-weight:500;font-size:15px}
.gwvsheet-opt .tx span{display:block;font-size:13px;color:var(--fg2)}

/* All pages: the hamburger becomes a grid and its panel lists the rail by category, then page, then tab */
html.gwviews .gwburger .ic-menu{display:none}
html.gwviews .gwburger .ic-pages{display:block;width:22px;height:22px;stroke:currentColor;stroke-width:1.8;fill:none}
html.gwviews .gwmenu-body{display:none}
html.gwviews .gwmenu-pages{display:block;flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:4px 16px 12px}
.gwpages-q{width:100%;height:44px;border:1px solid var(--edge);border-radius:12px;padding:0 12px;background:var(--card);color:var(--fg0);font:400 16px var(--font)}
/* level 1: the categories, one 48 px row each, the current one marked by a small accent bar */
.gwpages-list ul{list-style:none;margin:0;padding:0}
.gwcat-l1{margin-top:6px}
.gwcat{position:relative;width:100%;display:grid;grid-template-columns:22px minmax(0,1fr) auto 10px;align-items:center;gap:12px;min-height:48px;padding:0 6px 0 10px;border:0;border-bottom:1px solid var(--border);background:none;color:var(--fg0);font:500 15px var(--font);text-align:left;cursor:pointer}
.gwcat:hover{background:var(--hover)}
.gwcat .ic svg{display:block;width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;color:var(--fg2)}
.gwcat .ct{font-size:13px;font-weight:400;color:var(--fg3);font-variant-numeric:tabular-nums}
.gwcat .go,.gwcat-back i{width:7px;height:7px;border-right:1.8px solid var(--fg3);border-bottom:1.8px solid var(--fg3);transform:rotate(-45deg)}
.gwcat.cur::before{content:"";position:absolute;left:0;top:12px;bottom:12px;width:3px;border-radius:2px;background:var(--accent)}
.gwcat.cur .ic svg{color:var(--fg0)}
/* level 2: back, the category name, its pages with their tabs folded under them */
.gwcat-head{display:flex;align-items:center;gap:4px;min-height:44px;margin:6px 0 2px;border-bottom:1px solid var(--border)}
.gwcat-back{display:inline-flex;align-items:center;gap:8px;min-height:44px;min-width:44px;padding:0 10px 0 4px;margin-left:-4px;border:0;border-radius:var(--rs);background:none;color:var(--fg2);font:400 14px var(--font);cursor:pointer}
.gwcat-back i{transform:rotate(135deg);margin-left:4px}
.gwcat-back:hover{background:var(--hover);color:var(--fg0)}
.gwcat-head h5{margin:0;font-size:15px;font-weight:600;color:var(--fg0);outline:0}
.gwmenu .gwcat-l2 .row a{position:relative;font-size:15px;min-height:44px;gap:12px;padding-left:10px}
.gwmenu .gwcat-l2 .row a svg{width:18px;height:18px}
.gwmenu .gwcat-l2 .exp{width:44px;min-height:44px}
.gwmenu .gwcat-l2 li{border-bottom:1px solid var(--border)}
.gwmenu .gwcat-l2 li.cur>.row a{box-shadow:none;padding-left:10px;margin-left:0}
.gwmenu .gwcat-l2 li.cur>.row a::before{content:"";position:absolute;left:0;top:12px;bottom:12px;width:3px;border-radius:2px;background:var(--accent)}
.gwmenu .tabs{display:grid;grid-template-columns:1fr 1fr;column-gap:8px;padding:0 0 6px 40px}
.gwmenu .tabs[hidden]{display:none}
.gwmenu .tabs a{display:flex;align-items:center;min-height:44px;color:var(--fg);text-decoration:none;font-size:14px;line-height:1.2;position:relative}
.gwmenu .tabs a[aria-current=page]{color:var(--fg0);font-weight:600}
.gwmenu .tabs a[aria-current=page]::before{content:"";position:absolute;left:-10px;top:50%;width:5px;height:5px;margin-top:-2.5px;border-radius:50%;background:var(--accent)}
/* everything out, on every page (Michel, 14 Oct 2026), and all of it on one phone screen:
   "Can you make a full menu that fits in one screen? Your example misses settings." A small heading per
   category, then its pages as compact tiles, three to a row with the icon over the name, in the shared
   even grid (.btn-grid.g3: equal columns, one height per row, the last row stretches). The top, the search
   and the foot tighten only in this state (.gwmenu.gwall-on): the account moves beside Close and the
   foot's buttons become one even row, icon over label. */
.gwcat-all{padding-top:0}
.gwall-sec{margin-top:5px}
.gwall-sec:first-child{margin-top:4px}
.gwall-sec h5{display:flex;align-items:center;gap:6px;margin:0 0 3px;padding:0 2px;font-size:11px;line-height:14px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--fg3)}
.gwall-sec h5 .ic svg{display:block;width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.gwall-sec .btn-grid{gap:6px}
.gwmenu .gwall-sec.solo{padding-top:10px}
.nav .sec.solo+a{margin-top:10px}
/* A heading that only repeats its one page (Overview over Overview, chrome.js soloGroup): kept for a screen reader only. */
.gwmenu .gwall-sec.solo h5,.gwmenu-group.solo h5,.nav .sec.solo{position:absolute;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.gwmenu .gwall-sec .row{display:block;min-width:0}
.gwmenu .gwall-sec .row a{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;height:100%;min-height:40px;padding:4px;border-radius:10px;background:var(--tint);color:var(--fg0);font-size:12px;font-weight:500;line-height:14px;text-align:center;text-decoration:none;overflow:hidden}
.gwmenu .gwall-sec .row a span{max-width:100%;overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.gwmenu .gwall-sec .row a svg{flex:none;width:16px;height:16px;color:var(--fg2)}
.gwmenu .gwall-sec .row a:active{background:var(--sel)}
.gwmenu .gwall-sec .row a[aria-current=page]{font-weight:600;background:var(--sel);box-shadow:inset 0 0 0 1.5px var(--accent)}
.gwmenu .gwall-sec .row a[aria-current=page] svg{color:var(--fg0)}
.gwmenu .gwall-sec .row a:focus-visible{outline:2px solid var(--edge);outline-offset:-2px}
/* the top: the account beside Close, both 40 px */
.gwmenu-me{display:none}
html.gwviews .gwmenu.gwall-on .gwmenu-top{gap:8px;padding:4px 12px 2px 16px}
html.gwviews .gwmenu.gwall-on .gwmenu-top b{white-space:nowrap}
html.gwviews .gwmenu.gwall-on .gwmenu-env{min-width:0}
html.gwviews .gwmenu.gwall-on .gwmenu-me{display:inline-flex;flex:none;margin-left:auto;width:40px;height:40px;align-items:center;justify-content:center;border-radius:50%;text-decoration:none}
.gwmenu-me .av{width:32px;height:32px;border-radius:50%;background:var(--ink);color:var(--ink-hi);display:inline-flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;overflow:hidden}
.gwmenu-me .av img{width:100%;height:100%;object-fit:cover;display:block}
.gwmenu-me:focus-visible{outline:2px solid var(--edge);outline-offset:0}
html.gwviews .gwmenu.gwall-on .gwmenu-close{width:40px;height:40px;flex-basis:40px}
/* the search, a little shorter (16 px text still, so iOS does not zoom) */
html.gwviews .gwmenu.gwall-on .gwmenu-pages{padding:2px 12px 6px 16px}
html.gwviews .gwmenu.gwall-on .gwpages-q{height:40px;border-radius:10px}
/* the foot: one even row, icon over label, the account line folded into the top */
html.gwviews .gwmenu.gwall-on .gwmenu-foot{padding:6px 12px calc(6px + var(--safe-b)) 16px}
html.gwviews .gwmenu.gwall-on .gwmenu-who{display:none}
html.gwviews .gwmenu.gwall-on .gwmenu-acts{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:6px}
html.gwviews .gwmenu.gwall-on .gwmenu-acts .btn{flex-direction:column;gap:2px;min-height:42px;padding:3px 2px;font-size:11px;line-height:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
html.gwviews .gwmenu.gwall-on .gwmenu-acts .btn::before{content:"";flex:none;width:18px;height:18px;background:currentColor;-webkit-mask:var(--ic) center/contain no-repeat;mask:var(--ic) center/contain no-repeat}
.gwmenu-acts .gwpushbtn{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9'/%3E%3Cpath d='M10.3 21a1.94 1.94 0 0 0 3.4 0'/%3E%3C/svg%3E")}
.gwmenu-acts .gwinstall{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v12'/%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3Cpath d='M5 21h14'/%3E%3C/svg%3E")}
.gwmenu-acts .gwreload{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 12a9 9 0 1 1-3-6.7L21 8'/%3E%3Cpath d='M21 3v5h-5'/%3E%3C/svg%3E")}
.gwmenu-acts .gwout{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/%3E%3Cpath d='m16 17 5-5-5-5'/%3E%3Cpath d='M21 12H9'/%3E%3C/svg%3E")}
/* the tiles fill the phone, whatever its height (Michel, 14 Oct 2026, on a tall iPhone with a band of
   empty space above the foot: "Make it always adapt to the phone size, but take the full place").
   The list between the search and the foot is a size container; one tile height (--t) is worked out
   from its height and the rows and headings it holds (--rows and --secs, set by chrome.js), and the
   row gaps, the headings, the icons and the names all follow --t. A tile is 40 px at the least (a
   360x640 phone) and 76 px at the most; the space a capped tile leaves goes between the sections.
   A long name ("Scheduled & recurring") takes two lines and its row grows to hold them (#1600), so no
   name is cut; chrome.js measures what those rows add and takes it off the tiles' share (--wrapped). Below the least, the list scrolls as before. Only the phone (html.gwviews) has this menu. */
@supports (container-type:size){
html.gwviews .gwmenu.gwall-on .gwmenu-pages:not(.searching){display:flex;flex-direction:column}
html.gwviews .gwmenu.gwall-on .gwmenu-pages:not(.searching)>.gwpages-q{flex:none}
html.gwviews .gwmenu.gwall-on .gwmenu-pages:not(.searching)>.gwpages-list{flex:1 1 0;min-height:0;container-type:size}
.gwmenu.gwall-on .gwcat-all:not([hidden]){display:flex;flex-direction:column;justify-content:space-between;min-height:100cqh;
  --d:calc(var(--rows) * 1.1 + var(--secs) * .35 - .1);
  --t:clamp(40px, calc((100cqh - var(--wrapped, 0px) - 1px * var(--secs)) / var(--d)), 76px)}
.gwmenu.gwall-on .gwall-sec,.gwmenu.gwall-on .gwall-sec:first-child{margin-top:0}
.gwmenu.gwall-on .gwall-sec h5{font-size:clamp(11px, calc(var(--t) * .06 + 8.6px), 13px);line-height:calc(var(--t) * .25 + 3px);margin-bottom:calc(var(--t) * .1 - 2px);gap:clamp(6px, calc(var(--t) * .12), 8px)}
.gwmenu.gwall-on .gwall-sec h5 .ic svg{width:clamp(12px, calc(var(--t) * .2), 15px);height:clamp(12px, calc(var(--t) * .2), 15px)}
.gwmenu.gwall-on .gwall-sec .btn-grid{grid-auto-rows:minmax(var(--t), auto);gap:calc(var(--t) * .1)}
.gwmenu.gwall-on .gwall-sec .row a{gap:clamp(2px, calc(var(--t) * .07 - 1px), 4px);border-radius:clamp(10px, calc(var(--t) * .18), 14px);font-size:min(clamp(12px, calc(var(--t) * .1 + 8px), 15px), var(--name, 15px));line-height:1.18}
.gwmenu.gwall-on .gwall-sec .row a svg{width:clamp(16px, calc(var(--t) * .38), 28px);height:clamp(16px, calc(var(--t) * .38), 28px)}
}
/* A short phone (a 360x640 Android, an iPhone SE) with the console's seven groups: ten rows of tiles and
   seven headings do not fit at the usual heading size, so below 700 px of height the headings shrink to
   one 11 px line with no gap under it, the tile rows sit 2 px apart, and the top, the list and the foot give
   back a few pixels of padding. Tiles stay at their 40 px floor (the same floor a 640 px phone had with six
   groups); from about 700 px up nothing here applies and the tiles are 44 px and more. */
@supports (container-type:size){
@media (max-height:700px){
html.gwviews .gwmenu.gwall-on .gwmenu-top{padding-top:2px;padding-bottom:0}
html.gwviews .gwmenu.gwall-on .gwmenu-pages{padding-bottom:2px}
html.gwviews .gwmenu.gwall-on .gwmenu-foot{padding-top:4px;padding-bottom:calc(4px + var(--safe-b))}
.gwmenu.gwall-on .gwcat-all:not([hidden]){--t:clamp(40px, calc((100cqh - var(--wrapped, 0px) - 12px * var(--secs)) / (var(--rows) * 1.05)), 76px)}
.gwmenu.gwall-on .gwall-sec h5{font-size:11px;line-height:11px;margin-bottom:1px}
.gwmenu.gwall-on .gwall-sec .btn-grid{gap:calc(var(--t) * .05)}
}
}
/* search: one flat list, each row "Category › Page › Tab" */
.gwpages-n{margin:10px 0 2px;font-size:12px;color:var(--fg3)}
.gwmenu .gwpages-hits .row{display:block;border-bottom:1px solid var(--border)}
.gwmenu .gwpages-hits .row a{display:block;min-height:44px;padding:12px 4px 0;font-size:15px;font-weight:400;line-height:20px;color:var(--fg0);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gwpages-hits .crumb{color:var(--fg3);font-size:13px}
.gwpages-hits b{font-weight:500}
.gwmenu .gwpages-hits a[aria-current=page]{color:var(--fg0)!important}.gwpages-hits a[aria-current=page] b{font-weight:600}
.gwpages-hits a[aria-current=page]::after{content:"";display:inline-block;width:5px;height:5px;margin:0 0 2px 8px;border-radius:50%;background:var(--accent);vertical-align:middle}
.gwpages-none{color:var(--fg2);padding:24px 4px}
:is(.gwcat,.gwcat-back,.gwmenu .gwcat-l2 a,.gwmenu .gwcat-l2 .exp,.gwpages-hits a):focus-visible{outline:2px solid var(--edge);outline-offset:-2px;border-radius:var(--rs)}
@media(prefers-reduced-motion:no-preference){.gwcat-l1.in-l{animation:gw-in-l .2s cubic-bezier(.2,.8,.2,1) both}.gwcat-l2.in-r{animation:gw-in-r .2s cubic-bezier(.2,.8,.2,1) both}
@keyframes gw-in-r{from{transform:translateX(24px);opacity:0}to{transform:none;opacity:1}}@keyframes gw-in-l{from{transform:translateX(-24px);opacity:0}to{transform:none;opacity:1}}}
/* the foot, tighter on a phone: one account line, then Reload and Sign out */
html.gwviews .gwmenu-foot{padding:8px 16px calc(8px + var(--safe-b))}
html.gwviews .gwmenu-who{margin:0 0 6px;gap:10px}
html.gwviews .gwmenu-who .av{width:30px;height:30px;font-size:13px}
html.gwviews .gwmenu-who a{flex-direction:row;align-items:center;gap:8px;min-width:0;overflow:hidden;white-space:nowrap}
html.gwviews .gwmenu-who a b{overflow:hidden;text-overflow:ellipsis;font-size:14px}
html.gwviews .gwmenu-who a span{font-size:12px;flex:none}
html.gwviews .gwmenu-acts .btn{font-size:14px}

/* the island */
html.gwviews .gwisland{display:block;position:fixed;left:calc(var(--safe-l) + 21px);right:calc(var(--safe-r) + 21px);bottom:calc(var(--safe-b) + 21px);height:62px;border-radius:31px;background:var(--isl-bar);box-shadow:var(--isl-shadow);z-index:1040;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;transform-origin:50% 100%;transition:transform .32s cubic-bezier(.3,1.3,.5,1),opacity .2s}
html.gwviews .gwisland.compact{transform:translateY(6px) scale(.86)}
.gwisland .lit{position:absolute;top:4px;bottom:4px;left:0;width:var(--pill,90px);border-radius:26px;background:var(--isl-pill);border:.5px solid transparent;transform:translateX(var(--x,0px)) scale(var(--sx,1),var(--sy,1)) skewX(var(--lean,0deg));transition:transform .42s cubic-bezier(.34,1.45,.55,1),background-color .15s,border-color .15s;will-change:transform;pointer-events:none}
.gwisland .lit[hidden]{display:none}
.gwisland.down .lit{background:var(--isl-bubble);border-color:var(--isl-bubble-edge);transition:transform .12s ease-out,background-color .12s,border-color .12s}
.gwisland.down.drag .lit{transition:transform .05s linear,background-color .12s}
.gwisland .gwtab{position:absolute;top:0;bottom:0;left:var(--cx,0px);width:var(--pill,90px);margin-left:calc(var(--pill,90px) / -2);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;color:var(--isl-label)!important;text-decoration:none;font:400 10px/1.1 var(--font);-webkit-tap-highlight-color:transparent}
.gwisland .gwtab .gwlbl{max-width:100%;padding:0 4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gwisland .gwtab.on{font-weight:500}
.gwisland .ico svg{display:block;width:24px;height:24px;stroke:var(--isl-icon);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.gwisland .gwtab.on .ico svg{stroke:var(--isl-lit-edge);fill:var(--isl-lit-fill)}
.gwisland .gwtab:focus-visible{outline:2px solid var(--isl-label);outline-offset:-4px;border-radius:26px}
@media(prefers-reduced-motion:reduce){html.gwviews .gwisland,.gwisland .lit{transition-duration:.16s!important;transition-timing-function:ease-out!important}}
/* out of the way under a sheet or a menu that needs the foot */
html.gwviews body:has(main.fleet.has-detail) .gwisland,html.gwviews.gwmenu-open .gwisland{opacity:0;pointer-events:none;transform:translateY(24px)}
/* behind the island the page fades into its own ground, so no line of text
   or edge of a card shows beside or under the island while the page scrolls
   (Sai Teja, 10 Oct 2026, on an iPhone: the island read as overlapping the
   Offers card). Nothing is hidden at rest: the page still ends --tabbar above
   the foot. The fleet map keeps showing under the island, as a map app does. */
html.gwviews body::after{content:"";position:fixed;left:0;right:0;bottom:0;height:calc(var(--safe-b) + 21px + 62px + 28px);background:linear-gradient(to bottom,transparent,var(--bg) 58%);pointer-events:none;z-index:1039}
html.gwviews body.mapmode::after,html.gwviews body:has(main.fleet.has-detail)::after,html.gwviews.gwmenu-open body::after{display:none}
/* the bulk bar sits above the island and stays clear of the fade */
html.gwviews .bulkbar{z-index:1041}
/* the phone map: its corner controls and its way back to the map sit over the island */
html.gwviews body.mapmode main.fleet:not(.listview) .leaflet-top.leaflet-right{bottom:calc(var(--safe-b) + var(--tabbar))}
html.gwviews body.mapmode main.fleet.listview .mm-back{bottom:calc(var(--safe-b) + var(--tabbar))}
html.gwviews body.mapmode main.fleet.listview{padding-bottom:calc(88px + var(--tabbar))}

/* ---- saved toast (chrome.js gwToast, Michel 8 Oct 2026) ----------------------
   One status line in the bottom right corner after a console write: "Saved"
   with a check for 2 s, or "Not saved" and the reason for 5 s with a close
   button. Above the help panel and the bulk bar, below the jump search. On a
   phone it sits centred above the tab bar and the home indicator. */
.gw-toast{position:fixed;right:calc(var(--safe-r,0px) + 24px);bottom:calc(var(--safe-b,0px) + 24px);z-index:var(--z-toast);display:flex;align-items:center;gap:10px;max-width:min(420px,calc(100vw - 32px));padding:10px 12px 10px 14px;background:var(--card);color:var(--fg0);border:1px solid var(--border2);border-radius:var(--r);box-shadow:var(--shadow),0 6px 20px rgba(1,30,19,.14);font-family:var(--font);font-size:var(--fs-sm);line-height:1.35;pointer-events:auto}
.gw-toast[hidden]{display:none}
.gw-toast-ic{flex:none;display:inline-flex;color:var(--okfg)}
.gw-toast-ic svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.gw-toast-msg{min-width:0;overflow-wrap:anywhere}.gw-toast-msg b{font-weight:500}
.gw-toast[data-kind=err]{border-color:var(--crit)}
.gw-toast[data-kind=err] .gw-toast-ic,.gw-toast[data-kind=err] .gw-toast-msg b{color:var(--crit)}
.gw-toast-x{flex:none;display:inline-grid;place-items:center;width:32px;height:32px;margin:-4px -4px -4px 2px;padding:0;border:0;border-radius:var(--rs);background:transparent;color:var(--fg2);cursor:pointer}
.gw-toast-x[hidden]{display:none}
.gw-toast-x:hover{background:var(--hover);color:var(--fg0)}
.gw-toast-x:focus-visible{outline:2px solid var(--edge);outline-offset:1px}
.gw-toast-x svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
@media(prefers-reduced-motion:no-preference){.gw-toast{opacity:0;transform:translateY(6px);transition:opacity .16s ease-out,transform .16s ease-out}.gw-toast.on{opacity:1;transform:none}}
@media(max-width:900px),(pointer:coarse) and (max-width:1366px){
.gw-toast{right:auto;left:50%;bottom:calc(var(--tabbar,0px) + var(--safe-b,0px) + 16px);transform:translateX(-50%)}
.gw-toast-x{width:44px;height:44px;margin:-10px -8px -10px 0}
}
@media(max-width:900px) and (prefers-reduced-motion:no-preference),(pointer:coarse) and (max-width:1366px) and (prefers-reduced-motion:no-preference){
.gw-toast{transform:translate(-50%,6px)}.gw-toast.on{transform:translateX(-50%)}
}
/* the issues page's bulk bar holds the bottom edge while rows are ticked:
   the toast goes above it rather than over its buttons */
body:has(.bulkbar:not(.hidden)) .gw-toast{bottom:calc(var(--tabbar,0px) + var(--safe-b,0px) + 96px)}

#hublist{position:absolute;top:44px;right:12px;z-index:var(--z-popover);width:min(280px,calc(100% - 24px));max-height:60%;overflow:auto;background:var(--card);color:var(--fg);border:1px solid var(--border2);border-radius:var(--rs);box-shadow:var(--shadow)}#hublist[hidden]{display:none}#hublist .hl-head{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--border);position:sticky;top:0;background:var(--card)}#hublist .hl-head span{color:var(--fg2);font-size:12px;flex:1}#hublist .hl-x{border:0;background:none;font-size:20px;line-height:1;color:var(--fg2);cursor:pointer;padding:0 4px}#hublist ul{list-style:none;margin:0;padding:4px 0}#hublist li button{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}#hublist li button:hover,#hublist li button.sel{background:var(--sel)}#hublist .hl-soc{margin-left:auto;font-variant-numeric:tabular-nums}#hublist .hl-st{color:var(--fg2);font-size:12px;min-width:64px;text-align:right}#hublist .hl-empty{margin:0;padding:12px;color:var(--fg2)}
/* Record links (chrome.js gwLink): every id and name that names a record is a
   real link. Quiet at rest so a table of them still reads as data, a solid
   underline on hover and a ring on keyboard focus so it is plainly clickable. */
a.gwl{color:inherit;text-decoration:underline;text-decoration-color:var(--edge);text-decoration-thickness:1px;text-underline-offset:3px;border-radius:2px;cursor:pointer}
a.gwl:hover{color:var(--fg0);text-decoration-color:currentColor}
a.gwl:focus-visible{outline:2px solid var(--chg);outline-offset:2px;text-decoration-color:currentColor}
/* ---- even button groups (Michel, 13 Oct 2026) --------------------------------
   "Buttons and design on the web are always symmetric, proportional." Every
   group of record actions in a side panel or detail header is a .btn-grid:
   equal columns, one height per row, outer edges on the panel's edges, and
   never an orphan. Three to a row on a laptop; the last row stretches to fill
   (one button takes the whole row, two take half each). Two to a row on a
   phone, the last odd one full width. .g2 keeps two to a row everywhere, for
   long labels; .g3 keeps three to a row everywhere, for compact tiles. Counting skips hidden children (:nth-child(of S)), so a button
   hidden by a state change never leaves a hole.
   .btn-grid.risk is the separated row for what cannot be undone in one click
   (suspend, offboard, immobilise): after the everyday actions, under a rule.
   A long label wraps inside its cell rather than widening it. */
.btn-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:8px;align-items:stretch}
.btn-grid:empty{display:none}
.btn-grid>*{grid-column:span 2;min-width:0;margin:0}
.btn-grid>.hidden,.btn-grid>[hidden]{display:none}
@media (min-width:641px){
.btn-grid:not(.g2)>:nth-last-child(1 of :not(.hidden,[hidden])):nth-child(3n+1 of :not(.hidden,[hidden])){grid-column:1/-1}
.btn-grid:not(.g2)>:nth-last-child(2 of :not(.hidden,[hidden])):nth-child(3n+1 of :not(.hidden,[hidden])),
.btn-grid:not(.g2)>:nth-last-child(1 of :not(.hidden,[hidden])):nth-child(3n+2 of :not(.hidden,[hidden])){grid-column:span 3}
}
/* .g3: three to a row at every width, a phone included (compact tiles, such as the phone's All pages) */
.btn-grid.g3>:nth-last-child(1 of :not(.hidden,[hidden])):nth-child(3n+1 of :not(.hidden,[hidden])){grid-column:1/-1}
.btn-grid.g3>:nth-last-child(2 of :not(.hidden,[hidden])):nth-child(3n+1 of :not(.hidden,[hidden])),
.btn-grid.g3>:nth-last-child(1 of :not(.hidden,[hidden])):nth-child(3n+2 of :not(.hidden,[hidden])){grid-column:span 3}
/* four left over (3n+1 in all, n above 0): two rows of two rather than three and one across */
.btn-grid.g3>:nth-child(3n+1 of :not(.hidden,[hidden])):nth-last-child(4 of :not(.hidden,[hidden])),
.btn-grid.g3>:nth-child(3n+1 of :not(.hidden,[hidden])):nth-last-child(4 of :not(.hidden,[hidden]))~*{grid-column:span 3}
.btn-grid .btn,.btn-grid>details>summary.btn{width:100%;height:auto;min-height:36px;padding:6px 10px;justify-content:center;text-align:center;white-space:normal;line-height:1.25;overflow-wrap:anywhere}
.btn-grid .btn.small,.btn-grid>details>summary.btn.small{min-height:34px;padding:5px 10px}
.btn-grid>span,.btn-grid>p,.btn-grid>.muted{grid-column:1/-1;align-self:center}
.btn-grid>input{grid-column:1/-1;min-height:36px;padding:0 12px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg)}
.btn-grid.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.btn-grid.g2>*{grid-column:auto}
.btn-grid.g2>:nth-last-child(1 of :not(.hidden,[hidden])):nth-child(odd of :not(.hidden,[hidden])){grid-column:1/-1}
.btn-grid.risk{margin-top:10px;padding-top:10px;border-top:1px solid var(--border)}
@media (max-width:640px){
.btn-grid:not(.g3){grid-template-columns:repeat(2,minmax(0,1fr))}
.btn-grid:not(.g3)>*{grid-column:auto}
.btn-grid:not(.g3)>:nth-last-child(1 of :not(.hidden,[hidden])):nth-child(odd of :not(.hidden,[hidden])),.btn-grid>span,.btn-grid>p,.btn-grid>.muted,.btn-grid>input{grid-column:1/-1}
.btn-grid .btn,.btn-grid>details>summary.btn,.btn-grid .btn.small{min-height:44px}
/* The grid already sets a destructive button apart (the .risk row): it keeps
   its cell rather than the phone's own-line rule above. */
.btn-grid>.btn.danger{order:0;margin-top:0}
}
/* ---- section picker: a record with more sections than fit on one line ------
   A 460 px side panel cannot show eleven tabs of uneven length without
   wrapping into ragged rows, and a scrolling strip would hide most of them.
   Such a record shows one full-width "Section" picker instead, the control
   the phone layout already used: one aligned control at every width. The
   tab list stays in the page, hidden, so the picker is built from it and the
   two never disagree. A record with few sections that fit on one line keeps
   its tabs. */
.secpick{display:flex;align-items:center;gap:10px;margin-top:14px;margin-bottom:12px;padding-bottom:12px;border-bottom:1px solid var(--border)}
.secpick span{font-size:var(--fs-sm);color:var(--fg2);flex:none}
.secpick select{flex:1;min-width:0;height:40px;padding:0 12px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg0);font:500 var(--fs-sm) var(--font);cursor:pointer}
.secpick-tabs{display:none!important}
@media (max-width:640px){.secpick{position:sticky;top:calc(var(--safe-t,0px) + var(--top));z-index:3;background:var(--card);padding:10px 0;margin-top:8px}.secpick select{height:44px;font-size:16px}}
/* A row of list tabs that may not fit (status filters beside an open side
   panel): one line that scrolls sideways, with the far edge fading out, never
   a second ragged row holding one orphan tab. */
.tabs.tabstrip{display:flex;flex-wrap:nowrap;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;max-width:100%;min-width:0;animation:gw-tabfade linear both;animation-timeline:scroll(self inline)}
/* The fade shows only while there is more to scroll to: a strip that fits has
   no scroll timeline, so the animation, and the fade, never apply. */
@keyframes gw-tabfade{0%,96%{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent)}100%{-webkit-mask-image:none;mask-image:none}}
.tabs.tabstrip::-webkit-scrollbar{display:none}
.tabs.tabstrip>.tab{flex:none}
/* Phone: a few tabs that nearly fit get a tighter gap, so the strip does not wobble sideways by a few px; a long strip still scrolls */
@media (max-width:800px){.tabs.tabstrip{--tab-gap:16px;column-gap:16px}}
/* ---- the segmented control (Michel, 14 Oct 2026) ------------------------------
   One look for every row of mutually exclusive choices in the console (a
   status filter, a period, a base map): a rounded track holding equal
   segments, the chosen one a raised pill. On Customers, IDs, a 390 px phone
   showed "Waiting for the de" under "Decided by the machineAll" with the
   chosen pill covering its neighbour, and on Riders four segments sat to the
   left of a wider track. The rules:
   - every segment has the same width and together they span the track: an
     equal grid, never content-sized flex items;
   - the chosen pill is the segment itself, so it covers exactly its cell;
   - a label never overlaps a neighbour or is cut: it wraps between words
     inside its own cell, and a control whose labels are too long for a phone
     carries a short form (.seg-long / .seg-short, the full text kept as the
     button's title and aria-label);
   - .rows2 is the even two-row grid for a group of six (three to a row).
   On a laptop the track is as wide as its widest label times the count (an
   inline grid of equal tracks); on a phone it takes the full width.
   The chosen state is whichever the page already sets: .on, aria-pressed,
   aria-checked, aria-selected, or a checked radio inside a label. */
.gwseg{display:inline-grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:2px;padding:3px;margin:0;max-width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--edge);border-radius:calc(var(--rs) + 3px);background:var(--seg-track);vertical-align:middle}
.gwseg:empty{display:none}
.gwseg>:is(button,.btn,label,a){display:flex;align-items:center;justify-content:center;gap:6px;min-width:0;width:auto;height:auto;min-height:32px;margin:0;padding:4px 14px;box-sizing:border-box;border:0;border-radius:var(--rs);background:none;box-shadow:none;color:var(--fg2);font:500 var(--fs-sm)/1.2 var(--font);text-align:center;text-decoration:none;white-space:normal;overflow-wrap:normal;word-break:normal;hyphens:none;cursor:pointer;flex:none}
.gwseg>:is(button,.btn,label,a):hover{color:var(--fg0);background:none}
.gwseg>:is(.on,[aria-pressed=true],[aria-checked=true],[aria-selected=true],label:has(input:checked)),.gwseg>:is(.on,[aria-pressed=true],[aria-checked=true],[aria-selected=true]):hover{background:var(--seg-pill);color:var(--fg0);box-shadow:var(--shadow)}
.gwseg>:is(button,.btn,label,a):focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.gwseg>:is(button,.btn):disabled{opacity:.45;cursor:not-allowed}
.gwseg>label>input[type=radio]{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}
.gwseg>label:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:-2px}
.gwseg>.hidden,.gwseg>[hidden]{display:none}
.gwseg .seg-short{display:none;white-space:nowrap}
.gwseg.rows2{grid-auto-flow:row;grid-template-columns:repeat(3,minmax(0,1fr));border-radius:18px}
.gwseg.rows2>*{border-radius:var(--rs)}
@media (max-width:640px){
.gwseg{display:grid;width:100%}
.gwseg>:is(button,.btn,label,a){min-height:44px;padding:4px 8px}
.gwseg:has(>:nth-child(5))>:is(button,.btn,label,a){padding:4px 4px}
.gwseg .seg-long{display:none}.gwseg .seg-short{display:inline}
}
@media (min-width:641px){.gwseg.rows2{grid-auto-flow:column;grid-template-columns:none;border-radius:999px}.gwseg.rows2>*{border-radius:calc(var(--rs) + 3px)}}
/* ---- contact: the Contact group on a driver (chrome.js gwContact) ---- */
.gwc{display:flex;flex-direction:column;gap:8px}
.gwc-btn{justify-content:center}
/* A label breaks between words, never inside one; and in a panel too narrow for three to a row (the car
   panel on the Command Centre, about 346 px) the group is two to a row, so "WhatsApp call" fits (25 Oct 2026). */
div.gwc{container-type:inline-size}
.gwc-btn>span{overflow-wrap:break-word}
@container (max-width:380px){
.gwc-row.btn-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
.gwc-row.btn-grid>*{grid-column:auto!important}
}
.gwc-btn svg{width:16px;height:16px;flex:none;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.gwc-call{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:8px 10px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--panel)}
.gwc-call.hidden{display:none}
.gwc-line{flex:1 1 160px;font-size:var(--fs-sm);font-weight:500;color:var(--fg0)}
.gwc-msg{display:flex;flex-direction:column;gap:8px}
.gwc-msg.hidden{display:none}
.gwc-msg label{display:flex;flex-direction:column;gap:6px;font-size:var(--fs-sm);color:var(--fg2)}
.gwc-msg textarea{width:100%;min-height:64px;border:1px solid var(--edge);border-radius:var(--rs);padding:8px 10px;background:var(--card);color:var(--fg0);font:inherit;resize:vertical}
.gwc-msg .controls{display:flex;gap:8px}
.gwc .result{padding:0}.gwc .result:empty{display:none}
.gwc-notes{margin:0;font-size:var(--fs-xs);color:var(--fg3);line-height:1.4}
.gwc-audio{display:none}

/* The hover peek (chrome.js, section "peek"): a small read-only card for a
   record link. The console's card, lifted a little off the page. */
:root{--peek-shadow:0 8px 24px rgba(35,42,59,.14),0 1px 3px rgba(35,42,59,.08)}
:root[data-mode=dark]{--peek-shadow:0 8px 24px rgba(0,0,0,.5),0 1px 3px rgba(0,0,0,.4)}
@media (prefers-color-scheme:dark){:root[data-mode=system]{--peek-shadow:0 8px 24px rgba(0,0,0,.5),0 1px 3px rgba(0,0,0,.4)}}
.gw-peek{position:fixed;z-index:var(--z-popover);left:0;top:0;width:min(340px,calc(100vw - 16px));max-height:calc(100vh - 16px);overflow:auto;background:var(--card);color:var(--fg);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--peek-shadow);padding:12px 14px;font-size:var(--fs-sm);line-height:1.4}
.gw-peek[hidden]{display:none}
.gw-peek:focus{outline:none}.gw-peek:focus-visible{outline:2px solid var(--chg);outline-offset:2px}
.gw-peek-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.gw-peek-title{font-weight:500;font-size:var(--fs);color:var(--fg0);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gw-peek-chip{flex:none;display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-xs);font-weight:500;color:var(--fg);--dot:var(--c300)}
.gw-peek-chip::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--dot)}
.gw-peek-chip[data-tone=ok]{--dot:var(--gw-mint)}.gw-peek-chip[data-tone=warn]{--dot:var(--gw-sun)}.gw-peek-chip[data-tone=live]{--dot:var(--chg)}
.gw-peek-chip[data-tone=bad]{--dot:var(--gw-coral);color:var(--crit)}.gw-peek-chip[data-tone=muted]{color:var(--fg3)}
.gw-peek-sub{color:var(--fg2);font-size:var(--fs-xs);margin-top:2px;overflow-wrap:anywhere}
.gw-peek-note{color:var(--fg2);margin-top:8px}
.gw-peek-fields{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:4px 12px;margin:10px 0 0}
.gw-peek-fields dt{color:var(--fg3);font-size:var(--fs-xs)}
.gw-peek-fields dd{margin:0;color:var(--fg0);overflow-wrap:anywhere}
.gw-peek-links{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:10px;padding-top:8px;border-top:1px solid var(--border)}
.gw-peek-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:10px;padding-top:8px;border-top:1px solid var(--border);font-size:var(--fs-xs)}
.gw-peek-switch{background:none;border:0;padding:0;color:var(--fg3);font:inherit;cursor:pointer;text-decoration:underline;text-underline-offset:3px}
.gw-peek-switch:hover{color:var(--fg0)}.gw-peek-switch:focus-visible{outline:2px solid var(--chg);outline-offset:2px;border-radius:2px}
/* Back to the list and copy chips (chrome.js "back and copy"). The back link
   sits before the page title, quiet like the stamp beside it; on the phone bar
   it is the chevron alone at full touch size, its words kept for the screen
   reader. An id chip is the id in monospace, never wrapped, with a copy
   button beside it: 24 px, 44 px of hit area under a finger. */
.gwback{display:inline-flex;align-items:center;gap:4px;flex:none;padding:4px 8px 4px 4px;margin-right:-8px;border-radius:var(--rs);color:var(--fg3);font-size:var(--fs-sm);text-decoration:none;white-space:nowrap;max-width:240px;overflow:hidden;text-overflow:ellipsis}
.gwback span{overflow:hidden;text-overflow:ellipsis}
.gwback svg{flex:none;width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.gwback:hover{color:var(--fg0);background:var(--hover)}
.gwback:focus-visible{outline:2px solid var(--chg);outline-offset:1px}
@media(max-width:900px),(pointer:coarse) and (max-width:1366px){
.gwback{justify-content:center;width:44px;height:44px;padding:0;margin:0 0 0 -12px;color:var(--rail-fg)}
.gwback:hover{color:var(--gw-white);background:var(--rail2)}
.gwback svg{width:20px;height:20px}
.gwback span{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
}
.gwid{display:inline-flex;align-items:center;gap:2px;white-space:nowrap;vertical-align:baseline;max-width:100%}
.gwid .gwid-id{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.92em;font-variant-numeric:tabular-nums;white-space:nowrap}
main .gwid .gwid-copy,.gwid .gwid-copy{position:relative;display:inline-grid;place-items:center;flex:none;width:24px;height:24px;min-height:24px;min-width:24px;padding:0;margin:0;border:0;border-radius:var(--rs);background:transparent;color:var(--fg3);cursor:pointer;opacity:.7}
.gwid .gwid-copy svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.gwid .gwid-copy:hover{opacity:1;color:var(--fg0);background:var(--hover)}
.gwid .gwid-copy:focus-visible{opacity:1;outline:2px solid var(--chg);outline-offset:1px}
.gwid .gwid-copy.done{opacity:1;color:var(--okfg)}
@media(pointer:coarse){.gwid .gwid-copy::after{content:"";position:absolute;inset:-10px}}
/* The installed console's lock screen and its enrol offer (fleet/consolelock.py,
   console-lock.js). The lock is the sign-in card, so it reads as the same door. */
.gwlock .lockcard{display:flex;flex-direction:column;gap:12px;text-align:left}
.gwlock .lockcard h2{margin:0;font-size:var(--fs-title)}
.gwlock .lockcard p{margin:0}
.gwlock .lockcard .btn{width:100%;height:48px;justify-content:center;margin-top:4px}
.gwlock .lockcard .btn.ghost{border-color:transparent;background:none;color:var(--fg2)}
/* In the middle of the screen over a dimmed page, not at the bottom where it
   read as part of the page (Michel, 27 Oct 2026, iPhone). */
.gwlock-offer{position:fixed;left:16px;right:16px;top:50%;transform:translateY(-50%);z-index:60;max-width:480px;margin:0 auto;padding:20px;border:1px solid var(--border2);border-radius:var(--r);background:var(--card);box-shadow:var(--shadow),0 0 0 100vmax rgba(0,0,0,.45);display:flex;flex-direction:column;gap:10px;font-size:var(--fs-sm);color:var(--fg)}
.gwlock-offer b{font-size:var(--fs);color:var(--fg0)}
.gwlock-offer .row{display:flex;gap:8px;flex-wrap:wrap}
.gwlock-offer .err{min-height:0}
.lk-list{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.lk-list li{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:8px 10px;border:1px solid var(--border);border-radius:var(--rs)}
.lk-list li span{flex:1 1 200px;font-size:var(--fs-sm);color:var(--fg2)}
.lk-list li b{color:var(--fg0)}

/* ---- page summary tiles (issues 1312 and 1474; every page since 14 Oct 2026) --
   Michel, 14 Oct 2026, iPhone, Business > Pricing: "2 active Vehicle types .
   2 rows Rates . 3 active Zones / 0 active Zone prices . 0 rules Surge, off /
   4 of 12 Cars with a type set" wrapped raggedly over three lines. Every
   counter strip outside the dashboard (.stats; the offline copy of the
   dashboard keeps its own grid) is the even tiles Rides (1474) and Customers
   already had: one small card per counter, the tiles of a row the same width
   and the same height, each tile still opening what its text link opened.
   The strip measures itself (a size container), so a strip inside a card
   follows the card and not the screen:
   - narrower than 600 px (a phone): three to a row, number over label;
   - 600 to 899 px (a tablet, or a narrow card): four to a row, number over label;
   - 900 px and wider (a laptop): one row, label over the big number, while
     there are eight or fewer; nine or ten sit five to a row, eleven or more six.
   The last row never leaves an orphan: its tiles grow to share the row (one
   tile takes the row, two take half each).
   Zeros keep the rule of issue 1312: on a phone, and only there, a counter
   that is a bare zero ("0", "GYD 0", "0%") is left out (is-zero, marked by
   chrome.js) and a strip of nothing but zeros is left out whole (all-zero). A
   zero said in words is a fact and stays: "0 rules Surge, off", "0 active
   Zone prices" and "0 of 12 Cars with a type set" on Pricing.
   A tile that opens a tab or a filter (is-tap: data-go, data-tab, data-jump,
   data-filter, data-status, role=button) gets a pointer and a hover edge; a
   red counter (hl, crit) keeps its red number and gets a red edge. This comes
   after every other strip rule in this file and outranks the page sheets. */
body main:not(.dashboard) .stats:not(.gwoff-stats){container:gwstats/inline-size;display:flex;flex-wrap:wrap;align-items:stretch;gap:8px;grid-template-columns:none;min-width:0;overflow:visible;clip-path:none;scroll-snap-type:none}
body main:not(.dashboard) .stats:not(.gwoff-stats)[hidden]{display:none}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span{position:relative;box-sizing:border-box;flex:1 1 calc(100% / 3 - 12px);display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:1px;min-width:0;min-height:44px;margin:0;padding:6px 10px;background:var(--card);border:1px solid var(--border);border-radius:var(--rs);box-shadow:none;font-size:var(--fs-xs);line-height:1.2;color:var(--fg2);text-transform:none;letter-spacing:0;white-space:normal;overflow-wrap:anywhere;text-decoration:none;scroll-snap-align:none}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span::before{content:none}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span>b{order:-1;max-width:100%;font-size:var(--fs-title);font-weight:600;line-height:1.2;letter-spacing:0;color:var(--fg0);white-space:normal;overflow:visible;text-overflow:clip}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span>.usd{order:2}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span>b small{margin-left:3px;font-size:var(--fs-xs);font-weight:500;letter-spacing:0;color:var(--fg2);white-space:nowrap}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span>i.dot{position:absolute;top:8px;right:8px;margin:0;width:8px;height:8px}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span.is-tap{cursor:pointer}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span.is-tap:hover{border-color:var(--border2)}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span:focus-visible{outline:2px solid var(--focus);outline-offset:1px}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span:is(.hl,.crit){border-color:var(--crit)}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span:is(.hl,.crit)>b,body main:not(.dashboard) .stats:not(.gwoff-stats)>span>b.hl{color:var(--crit)}
@container gwstats (min-width:600px){
body main:not(.dashboard) .stats:not(.gwoff-stats)>span{flex-basis:calc(25% - 12px)}
}
@container gwstats (min-width:900px){
body main:not(.dashboard) .stats:not(.gwoff-stats)>span{flex-basis:calc(12.5% - 12px);justify-content:flex-start;gap:4px;padding:14px 16px 12px;border-radius:var(--r);box-shadow:var(--shadow);font-size:var(--fs-sm)}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span>b{order:1;font-size:var(--fs-kpi);font-weight:500;line-height:1.1;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span>i.dot{top:12px;right:12px}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span>b small{margin-left:5px;font-size:var(--fs-sm)}
body main:not(.dashboard) .stats:not(.gwoff-stats):has(>span:nth-child(9))>span{flex-basis:calc(20% - 12px)}
body main:not(.dashboard) .stats:not(.gwoff-stats):has(>span:nth-child(11))>span{flex-basis:calc(100% / 6 - 12px)}
}
@media(min-width:1001px){body main:not(.dashboard) .stats:not(.gwoff-stats){gap:12px}}
@media(max-width:600px){
body main:not(.dashboard) .stats:not(.gwoff-stats).all-zero{display:none}
body main:not(.dashboard) .stats:not(.gwoff-stats)>span.is-zero{display:none}
}
/* KPI tiles (fleet/static/kpi.js), shared by any page that adopts them; first
   on Marketing > Metrics (Michel, 12 Oct 2026: "aesthetically pleasing,
   proportioned ... maybe by also having icons"). Separate from .stats so the
   dashboard and fleet counters are untouched; every tile rule sits under
   .kpis because the dashboard already has its own span.kpi inside .stats. Neutral icon chip, no fills in
   the accent: colour on a tile is only the green or red of a change. Columns
   follow the width of the card, not the window, so a narrow card beside the
   rail gets two or three and every section lines up on the same grid. */
.kpiwrap{container-type:inline-size}
.kpigrp{margin:18px 0 0}.kpigrp:first-child{margin-top:4px}
.kpigrp-h{display:flex;align-items:baseline;gap:12px;margin:0 0 8px}
.kpigrp-h h4{margin:0;font-size:var(--fs-lbl);font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--fg3)}
.kpigrp-n{margin-left:auto;font-size:var(--fs-xs);color:var(--fg3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.kpigrp-n .bad{color:var(--crit)}
.kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
/* a narrow card: two columns everywhere; a section of three leads with its
   first tile (the total) across the row rather than leaving a hole */
@container (max-width:760px){.kpis{grid-template-columns:repeat(2,minmax(0,1fr))}.kpis[data-n="3"]>.kpi:first-child{grid-column:1/-1}}
.kpis>.kpi{display:grid;grid-template-rows:auto auto 1fr;align-content:start;gap:9px;min-width:0;padding:14px 16px 13px;background:var(--card);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow)}
.kpi-h{display:flex;align-items:center;gap:10px;min-width:0}
.kpi-ic{flex:none;display:grid;place-items:center;width:28px;height:28px;border-radius:var(--rs);background:var(--wash);color:var(--wash-mute);box-shadow:inset 0 0 0 1px var(--border)}
.kpi-svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.kpi-l{font-size:var(--fs-sm);color:var(--fg2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.kpi-v{display:block;font-size:var(--fs-kpi);font-weight:500;line-height:1.05;color:var(--fg0);font-variant-numeric:tabular-nums;letter-spacing:-.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.kpi-u{font-size:var(--fs-sm);font-weight:500;color:var(--fg3);letter-spacing:.02em;margin-right:6px}
.kpi-f{align-self:end;display:flex;align-items:center;gap:6px;min-height:18px;font-size:var(--fs-xs);color:var(--fg3);white-space:nowrap;overflow:hidden}
.kpi-d{display:inline-flex;align-items:center;gap:2px;font-weight:500;color:var(--fg2);font-variant-numeric:tabular-nums}
.kpi-d.good{color:var(--okfg)}.kpi-d.bad{color:var(--crit)}
.kpi-arr{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.kpi-s{color:var(--fg3)}
.kpi-split{display:flex;gap:14px}.kpi-split b{font-weight:500;color:var(--fg);font-variant-numeric:tabular-nums}
.kpis>.kpi.is-off{background:var(--panel);box-shadow:none}
.kpis>.kpi.is-off .kpi-ic{background:transparent;color:var(--fg3)}
.kpis>.kpi.is-off .kpi-v{font-size:var(--fs-sm);font-weight:400;line-height:1.05;color:var(--fg3);letter-spacing:0;padding:9px 0 0}
/* phone: each section one row that scrolls sideways, like the counters, so the
   tables start on the first screens instead of after twenty stacked tiles */
@media(max-width:600px){
.kpis,.kpis[data-n]{display:flex;overflow-x:auto;gap:8px;margin:0 -16px;padding:0 16px 2px;scrollbar-width:none;scroll-snap-type:x proximity;scroll-padding:0 16px}
.kpis::-webkit-scrollbar{display:none}
.kpis>.kpi{flex:0 0 auto;width:min(156px,41vw);padding:12px 12px 11px;gap:8px;scroll-snap-align:start}
.kpi-v{font-size:var(--fs-h1)}
/* the change keeps its arrow and figure; "vs week before" is in the tooltip.
   Labels may take two lines here; reserving both keeps every figure in the row on one baseline */
.kpi-l{white-space:normal;line-height:1.25;min-height:2.5em;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.kpi-h{align-items:flex-start}
.kpi-ic{width:24px;height:24px}.kpi-svg{width:14px;height:14px}
.kpi-f{flex-wrap:wrap;white-space:normal;row-gap:2px}
.kpi-split{flex-direction:column;gap:0}.kpi-split>span{white-space:nowrap}
.kpi-f>.kpi-s{display:none}
.kpigrp-h{flex-wrap:wrap;row-gap:2px}.kpigrp-n{margin-left:0;flex-basis:100%;white-space:normal}
}
/* ---- phone: one standard on every page (Michel, 12 Oct 2026) -------------------
   The name over the title is the rail section, plain text, and a button only on
   the dashboard (its view). The island holds the page's sub-sections, each an
   icon over one word as in the rider and driver apps; More holds the rest past five. A page
   with no sub-sections has no island. The page's own tab row, when the island
   says the same thing, is not shown. */
html.gwviews .gwview.plain{cursor:default;pointer-events:none;opacity:.78}
html.gwviews .gwview[hidden]{display:none}
html.gwviews.gwnoisland{--tabbar:0px}
html.gwviews [role=tablist].gwtabs-island,html.gwviews .toolbar.gwtabs-island{display:none!important}
html.gwviews .gwisland .gwbadge{position:absolute;top:5px;left:calc(50% + 5px);min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--gw-crit);color:var(--gw-white);font:600 11px/18px var(--font);text-align:center}
html.gwviews .gwisland .gwbadge[hidden]{display:none}
/* ---- phone: the bottom bar (Chats, Command Centre, Rides, Support; 28 Oct 2026) ----
   chrome.js builds it from the rail, so a role sees only what it can open. It
   sits flush at the foot, as iPhone's own tab bar does, with the home
   indicator's inset under it; a page's island floats 10 above it. --bnav is
   its height and --tabbar, which the page, the sheets, the toast and the round
   + already keep clear of, grows by it. As on the island, the words are black (white
   in dark mode) for contrast and the icons grey, the current one lit. The laptop
   and the iPad keep the rail. */
.gwbnav{display:none}
html.gwviews.gwbnav-on{--bnav:56px;--tabbar:calc(var(--bnav) + 84px)}
html.gwviews.gwbnav-on.gwnoisland{--tabbar:var(--bnav)}
html.gwviews.gwbnav-on .gwbnav{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:1045;height:calc(var(--bnav) + var(--safe-b));padding:0 var(--safe-r) var(--safe-b) var(--safe-l);background:var(--isl-bar);border-top:1px solid var(--border);box-sizing:border-box;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
html.gwviews.gwbnav-on .gwisland{bottom:calc(var(--safe-b) + var(--bnav) + 10px)}
html.gwviews.gwbnav-on body::after{height:calc(var(--safe-b) + var(--bnav) + 10px + 62px + 20px)}
html.gwviews.gwbnav-on.gwnoisland body::after{display:none}
html.gwviews.gwbnav-on.gwnoisland .btn.gwfab{bottom:calc(var(--bnav) + var(--safe-b) + 16px)}
.gwbtab{flex:1 1 0;min-width:44px;min-height:44px;position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;color:var(--isl-label)!important;text-decoration:none;font:500 11px/1.1 var(--font);-webkit-tap-highlight-color:transparent}
.gwbtab .lbl{max-width:100%;padding:0 2px;white-space:nowrap}
.gwbtab .ico svg{display:block;width:24px;height:24px;stroke:var(--isl-icon);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.gwbtab[aria-current=page]{font-weight:600}
.gwbtab[aria-current=page] .ico svg{stroke:var(--isl-lit-edge);fill:var(--isl-lit-fill)}
.gwbtab:focus-visible{outline:2px solid var(--isl-label);outline-offset:-4px;border-radius:12px}
.gwbtab:active .ico{transform:scale(.92)}
.gwcbadge{min-width:18px;height:18px;padding:0 5px;border-radius:9px;box-sizing:border-box;background:var(--gw-crit);color:var(--gw-white);font:600 11px/18px var(--font);text-align:center;font-variant-numeric:tabular-nums}
.gwcbadge[hidden]{display:none}
.gwbtab .gwcbadge{position:absolute;top:4px;left:calc(50% + 6px)}
.nav a .gwcbadge{margin-left:auto;flex:none}
.gwvsheet-opt:not(:has(.ic)){grid-template-columns:minmax(0,1fr);padding:8px 12px}
button.gwvsheet-opt{width:100%;border:0;background:none;text-align:left;font:inherit;cursor:pointer}
button.gwvsheet-opt[aria-current=true]{background:var(--sel)}
/* the toolbar on a phone (chrome.js): search, Filters, ⋯ on one row; the
   main New button as the round + at the foot, right, above the island */
html.gwviews .gwtoolhost{flex-wrap:wrap}
html.gwviews .gwtoolrow{display:flex;align-items:center;gap:8px;flex:1 1 100%;min-width:0;position:relative}
/* :not(#fts-q) matches the weight of the desktop rule further down, so on a phone the search box
   gives way and the "more" button stays inside the card (it stuck out 9 px and the card slid sideways) */
html.gwviews .gwtoolrow input[type=search],html.gwviews main .gwtoolrow input[type=search]:not(#fts-q){flex:1 1 auto;min-width:0;width:auto;height:44px}
html.gwviews .gwtoolrow .btn{flex:none;min-height:44px}
html.gwviews .gwfbtn{display:inline-flex;align-items:center;gap:6px}
html.gwviews .gwfcount{min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:var(--chip);color:var(--chip-fg);font-size:12px;font-weight:600;line-height:20px;text-align:center}
html.gwviews .gwfcount[hidden]{display:none}
html.gwviews .gwmorebtn{width:44px;padding:0;justify-content:center}
html.gwviews .gwmorebtn svg{width:20px;height:20px;fill:currentColor}
html.gwviews .gwmoved{display:none!important}
html.gwviews .gwactmenu{position:absolute;right:0;top:calc(100% + 6px);z-index:1100;min-width:200px;padding:6px;border:1px solid var(--border2);border-radius:12px;background:var(--card);box-shadow:0 10px 30px rgba(1,30,19,.18)}
html.gwviews .gwactmenu[hidden]{display:none}
html.gwviews .gwactmenu button{display:block;width:100%;min-height:44px;padding:0 12px;border:0;border-radius:8px;background:none;color:var(--fg0);font:inherit;font-size:var(--fs);text-align:left}
html.gwviews .gwactmenu button:active{background:var(--hover)}
html.gwviews .gwactmenu .none{display:block;padding:10px 12px;color:var(--fg3)}
.gwfsheet{display:none}
html.gwviews .gwfsheet:not([hidden]){display:block;position:fixed;inset:0;z-index:var(--z-modal)}
.gwfsheet-scrim{position:absolute;inset:0;background:rgba(1,30,19,.45)}
.gwfsheet-box{position:absolute;left:0;right:0;bottom:0;max-height:85svh;display:flex;flex-direction:column;background:var(--card);border-radius:16px 16px 0 0;padding-bottom:var(--safe-b)}
.gwfsheet-head{display:flex;align-items:center;gap:8px;padding:14px 16px 10px;border-bottom:1px solid var(--border)}
.gwfsheet-head b{flex:1 1 auto;font-size:var(--fs-title);font-weight:500;color:var(--fg0)}
.gwfsheet-head .btn{min-height:40px}
.gwfsheet-body{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;padding:8px 16px 16px;display:flex;flex-direction:column;gap:12px}
.gwfsheet-body label{display:flex;flex-direction:column;gap:6px;font-size:var(--fs-sm);color:var(--fg2)}
.gwfsheet-body select,.gwfsheet-body input{width:100%;max-width:none;height:44px;font-size:16px}
html.gwviews .btn.gwfab{position:fixed;right:calc(var(--safe-r) + 21px);bottom:calc(var(--tabbar) + var(--safe-b) + 21px + 12px);z-index:var(--z-float);width:56px;height:56px;min-height:56px;padding:0;border-radius:50%;justify-content:center;font-size:0;box-shadow:0 8px 24px rgba(1,30,19,.25)}
html.gwviews.gwnoisland .btn.gwfab{bottom:calc(var(--safe-b) + 21px)}
html.gwviews .btn.gwfab>*:not(.gwfab-ic){display:none}
/* main .btn.small sets 14 px words with !important; the + keeps its label for
   screen readers only, so the words never spill out of the circle. */
html.gwviews main .btn.gwfab{font-size:0!important}
html.gwviews .btn.gwfab{gap:0;align-items:center;line-height:0}
html.gwviews .gwfab-ic{display:block;width:26px;height:26px}
/* the first segmented group keeps its own row; its look is the shared .gwseg */
html.gwviews .gwtoolhost>.seg.gwsegrow{order:1;flex:1 1 100%;min-width:0}
html.gwviews .gwtoolhost>.gwtoolrow{order:0}
html.gwviews .toolbar.gwtoolempty{display:none}
.gwfgroup{display:flex;flex-direction:column;gap:6px;font-size:var(--fs-sm);color:var(--fg2)}
.gwfgroup .seg.gwseg{display:grid;width:100%}
html.gwviews .gwfab-ic svg{display:block;width:26px;height:26px;stroke:currentColor;stroke-width:2.2;fill:none;stroke-linecap:round}
html.gwviews.gwmenu-open .btn.gwfab{display:none}
/* second-level tabs and chip rows: one standard, a row that slides sideways
   inside itself, never a page that does */
html.gwviews .subtabs,html.gwviews .toolbar.inbox{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
html.gwviews .subtabs::-webkit-scrollbar,html.gwviews .toolbar.inbox::-webkit-scrollbar{display:none}
html.gwviews .toolbar.inbox .chip{flex:none}
/* no page and no panel moves sideways on a phone (Michel, 12 Oct 2026: "don't
   allow to wiggle it right and left"); wide content scrolls inside its own box */
html.gwviews,html.gwviews body{overflow-x:clip;overscroll-behavior-x:none;max-width:100%}
html.gwviews main,html.gwviews .detail,html.gwviews .sheet,html.gwviews .gwvsheet-panel,html.gwviews .gwmenu-pages{overflow-x:clip;overscroll-behavior-x:none;max-width:100vw}
/* ---- the banner for a notification while the console is open (chrome.js gwNotice) ----
   WhatsApp's in-app banner: under the status bar, above everything, two lines
   until it is held down, then the whole text. */
.gwnotice{position:fixed;left:8px;right:8px;top:calc(var(--safe-t) + 8px);z-index:1300;max-width:560px;margin:0 auto;display:flex;align-items:flex-start;gap:12px;padding:12px 8px 12px 12px;border:1px solid var(--border2);border-radius:16px;background:var(--card);box-shadow:0 10px 30px rgba(1,30,19,.18),0 2px 6px rgba(1,30,19,.08);transform:translateY(calc(-100% - var(--safe-t) - 16px));transition:transform .25s ease;cursor:pointer;touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.gwnotice.in{transform:none}
.gwnotice.crit{border-color:var(--crit)}
.gwnotice img{flex:none;width:36px;height:36px;border-radius:8px}
.gwnotice .tx{flex:1 1 auto;min-width:0}
.gwnotice b{display:block;font-size:var(--fs);font-weight:600;color:var(--fg0);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gwnotice.crit b{color:var(--crit)}
.gwnotice p{margin:2px 0 0;font-size:var(--fs-sm);line-height:1.4;color:var(--fg2);white-space:pre-line;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.gwnotice.open p{display:block;-webkit-line-clamp:unset;max-height:60vh;overflow-y:auto}
.gwnotice .x{flex:none;width:32px;height:32px;margin:-4px 0 0;padding:0;border:0;border-radius:50%;background:none;color:var(--fg3);display:flex;align-items:center;justify-content:center}
.gwnotice .x svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
@media(prefers-reduced-motion:reduce){.gwnotice{transition:none}}
/* ---- a new driver applicant (console-applicant.js, Michel 14 Oct 2026) -------
   Over the page, never blocking it: a card in the bottom right corner of a
   computer, a sheet along the bottom of a phone above the tab bar. Under the
   photo viewer (the sheet View opens) and the notice banner. One card at a
   time; Accept, Decline and View as one even row (.btn-grid.g3). */
.gwapplicant{position:fixed;right:calc(var(--safe-r) + 16px);bottom:calc(var(--tabbar) + var(--safe-b) + 16px);z-index:1250;width:360px;max-width:calc(100vw - 32px);box-sizing:border-box;display:flex;flex-direction:column;gap:10px;padding:14px 14px 16px;border:1px solid var(--border2);border-radius:16px;background:var(--card);color:var(--fg);box-shadow:0 14px 40px rgba(1,30,19,.22),0 2px 6px rgba(1,30,19,.08);transform:translateY(12px);opacity:0;transition:transform .2s ease,opacity .2s ease}
.gwapplicant.in{transform:none;opacity:1}
.gwapplicant[hidden]{display:none}
.gwapplicant header{display:flex;align-items:center;gap:8px;min-height:32px}
.gwapplicant header b{flex:1 1 auto;min-width:0;font-size:var(--fs);font-weight:600;color:var(--fg0)}
.gwapplicant-n{flex:none;font-size:var(--fs-xs);color:var(--fg2);font-variant-numeric:tabular-nums}
.gwapplicant .x{flex:none;width:36px;height:36px;margin:-4px -6px -4px 0;padding:0;border:0;border-radius:50%;background:none;color:var(--fg3);display:flex;align-items:center;justify-content:center;cursor:pointer}
.gwapplicant .x svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.gwapplicant-who{margin:0;font-size:var(--fs);color:var(--fg0)}.gwapplicant-who .muted{font-size:var(--fs-sm)}
.gwapplicant-says{margin:0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:6px}
.gwapplicant-says li{font-size:var(--fs-xs);line-height:1.3;padding:4px 8px;border:1px solid var(--edge);border-radius:999px;color:var(--fg2)}
.gwapplicant-says li.lic.checked{color:var(--okfg);border-color:var(--okfg)}
.gwapplicant-says li.lic.none{color:var(--crit);border-color:var(--crit)}
.gwapplicant-q{margin:0;font-size:var(--fs-sm);line-height:1.4;color:var(--fg)}
.gwapplicant-reason{display:flex;flex-direction:column;gap:4px;font-size:var(--fs-sm);color:var(--fg2)}
.gwapplicant-reason input{width:100%;box-sizing:border-box;min-height:44px;padding:0 12px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg);font-size:var(--fs-sm)}
.gwapplicant .btn-grid .btn{min-height:44px}
.gwapplicant .result{margin:0;padding:0}.gwapplicant .result:empty{display:none}
@media (max-width:640px){
.gwapplicant{left:0;right:0;bottom:calc(var(--tabbar) + var(--safe-b));width:auto;max-width:none;border-radius:16px 16px 0 0;border-bottom:0;padding:14px calc(var(--safe-r) + 16px) 16px calc(var(--safe-l) + 16px);box-shadow:0 -10px 34px rgba(1,30,19,.22)}
}
@media(prefers-reduced-motion:reduce){.gwapplicant{transition:none}}
/* ---- the notification sheet after sign-in (console-push.js) ----
   A bottom sheet on a phone or tablet, a card in the corner on a computer. */
:root{--gwpush-on:var(--gw-charcoal);--gwpush-knob:var(--gw-white)}
:root[data-mode=dark]{--gwpush-on:var(--gw-yellow);--gwpush-knob:var(--gw-charcoal)}
@media (prefers-color-scheme:dark){:root[data-mode=system]{--gwpush-on:var(--gw-yellow);--gwpush-knob:var(--gw-charcoal)}}
html.gwpush-open,html.gwpush-open body{overflow:hidden}
.gwpush.is-modal{position:fixed;inset:0;z-index:1195;display:flex;align-items:flex-end;justify-content:center;background:rgba(1,30,19,.5);padding:calc(var(--safe-t) + 16px) var(--safe-r) 0 var(--safe-l)}
.gwpush.is-modal .gwpush-panel{width:min(560px,100%);max-height:100%;overflow-y:auto;overscroll-behavior:contain;border-radius:20px 20px 0 0;padding:20px 16px calc(16px + var(--safe-b));box-shadow:0 -10px 40px rgba(1,30,19,.3)}
.gwpush.is-card{position:fixed;right:calc(var(--safe-r) + 24px);bottom:calc(var(--safe-b) + 24px);z-index:1135;width:min(400px,calc(100vw - 32px))}
.gwpush.is-card .gwpush-panel{max-height:min(640px,calc(100vh - 48px));overflow-y:auto;border:1px solid var(--border2);border-radius:16px;padding:18px 18px 14px;box-shadow:0 12px 40px rgba(1,30,19,.18)}
.gwpush-panel{background:var(--card);color:var(--fg);font-family:var(--font);outline:0}
.gwpush-panel h2{margin:0 0 6px;font-size:var(--fs-title);font-weight:500;color:var(--fg0)}
.gwpush-lead{margin:0 0 8px;font-size:var(--fs-sm);line-height:1.45;color:var(--fg2)}
.gwpush-group{border-top:1px solid var(--border);padding-top:8px;margin-top:8px}
.gwpush-group h3{margin:0;font-size:var(--fs-lbl);font-weight:500;letter-spacing:.06em;text-transform:uppercase;color:var(--fg3)}
.gwpush-row{display:flex;align-items:center;gap:14px;min-height:44px;padding:6px 0;cursor:pointer}
.gwpush-row .tx{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.gwpush-row .tx b{font-weight:500;font-size:var(--fs);color:var(--fg0)}
.gwpush-row .tx span{font-size:var(--fs-sm);line-height:1.4;color:var(--fg2)}
.gwpush-row input[role=switch]{flex:none;appearance:none;-webkit-appearance:none;margin:0;width:51px;height:31px;border-radius:999px;background:var(--border2);position:relative;cursor:pointer;transition:background .15s}
.gwpush-row input[role=switch]::after{content:"";position:absolute;top:2px;left:2px;width:27px;height:27px;border-radius:50%;background:var(--gw-white);box-shadow:0 1px 3px rgba(1,30,19,.3);transition:transform .15s}
.gwpush-row input[role=switch]:checked{background:var(--gwpush-on)}
.gwpush-row input[role=switch]:checked::after{transform:translateX(20px);background:var(--gwpush-knob)}
.gwpush-row input[role=switch]:focus-visible{outline:2px solid var(--fg0);outline-offset:2px}
.gwpush-help{margin:4px 0 12px;padding:12px 14px;border:1px solid var(--border2);border-radius:var(--r);background:var(--tint);font-size:var(--fs-sm);line-height:1.45;color:var(--fg)}
.gwpush-msg{margin:12px 0 0;font-size:var(--fs-sm);line-height:1.4;color:var(--crit)}
.gwpush-help[hidden],.gwpush-msg[hidden]{display:none}
.gwpush-steps{margin:8px 0 0;padding-left:20px}.gwpush-steps li{margin:4px 0}
.gwpush-acts{display:flex;flex-direction:column;gap:8px;margin-top:14px}
.gwpush-acts .btn{min-height:44px;height:auto;justify-content:center;font-size:15px}
.gwpush.is-card .gwpush-acts{flex-direction:row-reverse}.gwpush.is-card .gwpush-acts .btn{flex:1 1 0}
.gwpush-lost{position:fixed;left:calc(var(--safe-l) + 8px);right:calc(var(--safe-r) + 8px);top:calc(var(--safe-t) + 8px);z-index:1290;max-width:560px;margin:0 auto;display:flex;align-items:center;gap:10px;padding:8px 6px 8px 14px;border:1px solid var(--border2);border-radius:14px;background:var(--card);color:var(--fg0);font-size:var(--fs-sm);box-shadow:0 10px 30px rgba(1,30,19,.18)}
.gwpush-lost span{flex:1 1 auto;min-width:0}
.gwpush-lost .btn{min-height:44px;height:auto}
.gwpush-lost .x{flex:none;width:44px;height:44px;padding:0;border:0;border-radius:50%;background:none;color:var(--fg3);display:flex;align-items:center;justify-content:center;cursor:pointer}
.gwpush-lost .x svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
@media(prefers-reduced-motion:reduce){.gwpush-row input[role=switch],.gwpush-row input[role=switch]::after{transition:none}}
/* ---- phone polish pass (Michel, 13 Oct 2026: "clean and proportionate on a phone") ----
   A list card read one value per line, label far left and value far right, so
   a driver or a car took a whole screen. At phone width a card is now a two
   column grid, each value under its small label; the title, an action cell
   (no label) and a cell marked .gwwide take the full width. */
@media(max-width:600px){
table.gwcards>tbody>tr{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:14px;row-gap:2px;align-items:start}
table.gwcards>tbody>tr>td{text-align:left;padding:4px 0;min-width:0}
table.gwcards>tbody>tr>td::before{float:none;display:block;max-width:none;margin:0 0 1px;font-size:12px;line-height:1.3}
table.gwcards>tbody>tr>td:first-child,table.gwcards>tbody>tr>td:first-child:has(>input[type=checkbox])+td,table.gwcards>tbody>tr>td[data-label=""],table.gwcards>tbody>tr>td[colspan],table.gwcards>tbody>tr>td.gwwide{grid-column:1/-1}
table.gwcards>tbody>tr>td[data-label=""]:not(:first-child){text-align:right}
table.gwcards>tbody>tr>td[colspan]{text-align:center}
/* A long-text cell (td.wrap: a message, a note) across the card (Michel,
   22 Oct 2026: on Rider messaging the Message ran over Recipients). Page
   rules give these cells a desktop min-width by id (#bc-table td.wrap
   260px), which beats the grid's min-width:0 and pushed the text into the
   next column. */
table.gwcards>tbody>tr>td.wrap{grid-column:1/-1;min-width:0!important}
/* a page rule that keeps a cell on one line would run it into its neighbour */
table.gwcards.gwcards>tbody>tr>td{white-space:normal}
/* A row's actions in a card (Michel, 13 Oct 2026: on an applicant card the
   Accept button ran off the left edge and "Being read" was not visible). The
   page rule keeps .rowacts on one right-aligned line for the desktop table;
   on a card that line is wider than the card and spills out to the left. Here
   it is the even grid instead: two equal columns, the last odd button across
   the row, a field across the row, and the destructive button last, across,
   outlined (the phone .btn.danger rule). Dense flow lets a button after a
   field fill the hole beside the one before it, so no button is left alone. */
table.gwcards>tbody>tr>td .rowacts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-flow:row dense;gap:8px;width:100%;justify-content:stretch;align-items:stretch}
table.gwcards>tbody>tr>td .rowacts>*{grid-column:auto;min-width:0;width:100%;max-width:none;margin:0;box-sizing:border-box}
table.gwcards>tbody>tr>td .rowacts>.hidden,table.gwcards>tbody>tr>td .rowacts>[hidden]{display:none}
table.gwcards>tbody>tr>td .rowacts>.btn{height:auto;min-height:44px;padding:6px 10px;justify-content:center;text-align:center;white-space:normal;line-height:1.25;overflow-wrap:anywhere}
table.gwcards>tbody>tr>td .rowacts>input,table.gwcards>tbody>tr>td .rowacts>span,table.gwcards>tbody>tr>td .rowacts>.btn.danger{grid-column:1/-1}
table.gwcards>tbody>tr>td .rowacts>input{height:44px;min-height:44px;padding:0 12px}
table.gwcards>tbody>tr>td .rowacts>span{align-self:center;text-align:left}
table.gwcards>tbody>tr>td .rowacts>:nth-last-child(1 of :not(input,span,.danger,.hidden,[hidden])):nth-child(odd of :not(input,span,.danger,.hidden,[hidden])){grid-column:1/-1}
/* .g1: one per row, for actions whose labels do not fit half a card */
table.gwcards>tbody>tr>td .rowacts.g1{grid-template-columns:minmax(0,1fr)}
}
/* Incident reports: the two selects and the search share one width, the
   check boxes sit two to a row as full 44 px targets */
@media(max-width:600px){
.incpage #in-filters{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px 12px}
.incpage #in-filters>select,.incpage #in-filters>input[type=search]{grid-column:1/-1;width:100%;max-width:none;min-width:0;box-sizing:border-box}
.incpage #in-filters>label.check{min-height:44px;min-width:0}
}
/* A list toolbar with no search box left its ellipsis menu alone on the first
   row and the main button alone on another. Without a search the ellipsis
   sits at the end of the main button's row, the button filling the rest. */
html.gwviews .gwtoolhost>.gwtoolrow:not(:has(input)){flex:none;order:3}
html.gwviews .gwtoolhost>.gwtoolrow:not(:has(input))~.btn.primary{order:2;flex:1 1 0;justify-content:center;min-height:44px}
html.gwviews .gwtoolhost>.gwtoolrow:not(:has(input))~.grow{display:none}
html.gwviews .gwtoolhost>.gwtoolrow:not(:has(input))~.lead,html.gwviews .gwtoolhost>.gwtoolrow:not(:has(input))~label.check{flex:1 1 100%}
/* Call screen (chrome.js, "call screen"): a call in app takes over the screen
   like a phone call on a phone, and is a dialog on a desktop. Dark in both
   themes, as a call screen is. Minimise leaves a bar at the bottom. */
html.gwcall-lock,html.gwcall-lock body{overflow:hidden;overscroll-behavior:none}
.gwcall{position:fixed;inset:0;z-index:1300;display:flex;align-items:center;justify-content:center;padding:24px;background:rgba(1,30,19,.55);overscroll-behavior:contain;touch-action:none}
.gwcall[hidden],.gwcall-bar[hidden],.gwcall-bar-end[hidden],.gwcall-min[hidden]{display:none}
.gwcall-card{box-sizing:border-box;width:min(380px,100%);min-height:560px;max-height:100%;display:flex;flex-direction:column;align-items:center;gap:20px;padding:16px 24px 32px;border-radius:24px;background:var(--gw-charcoal);color:var(--gw-white);box-shadow:0 24px 60px rgba(1,30,19,.45);touch-action:manipulation;overflow:auto}
.gwcall-top{align-self:stretch;display:flex}
.gwcall-min{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 14px 0 8px;border:0;border-radius:22px;background:transparent;color:var(--c200);font-size:var(--fs-sm);font-weight:500;cursor:pointer}
.gwcall-min:hover{background:rgba(255,255,255,.08)}.gwcall-min svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.gwcall-who{flex:1 1 auto;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;min-height:0}
.gwcall-av{width:112px;height:112px;border-radius:50%;background:var(--c700);color:var(--gw-yellow);display:flex;align-items:center;justify-content:center;font-size:40px;font-weight:500;letter-spacing:.02em;margin-bottom:20px;position:relative}
.gwcall[data-phase=calling] .gwcall-av::after,.gwcall[data-phase=ringing] .gwcall-av::after{content:"";position:absolute;inset:-8px;border-radius:50%;border:2px solid var(--c500);animation:gwcall-ring 1.6s ease-out infinite}
@keyframes gwcall-ring{from{transform:scale(.92);opacity:1}to{transform:scale(1.18);opacity:0}}
@media (prefers-reduced-motion:reduce){.gwcall .gwcall-av::after{animation:none}}
.gwcall-name{margin:0;font-size:28px;line-height:1.2;font-weight:500;color:var(--gw-white);overflow-wrap:anywhere}
.gwcall-role{margin:6px 0 0;font-size:var(--fs-sm);color:var(--c300)}
.gwcall-status{margin:18px 0 0;font-size:var(--fs-title);font-weight:500;color:var(--c200)}
.gwcall[data-phase=connected] .gwcall-status{color:var(--gw-mint)}
.gwcall-clock{margin:4px 0 0;min-height:1.4em;font-size:var(--fs-title);font-variant-numeric:tabular-nums;color:var(--gw-white)}
.gwcall-out{margin:4px 0 0;min-height:1.4em;font-size:var(--fs-xs);color:var(--c300)}
.gwcall-keys{display:flex;justify-content:center;gap:28px;flex-wrap:wrap}
.gwcall-key{display:flex;flex-direction:column;align-items:center;gap:8px;min-width:72px;padding:0;border:0;background:none;color:var(--c200);font-size:var(--fs-sm);cursor:pointer}
.gwcall-key:disabled{opacity:.45;cursor:default}
.gwcall-orb{width:72px;height:72px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.14);color:var(--gw-white);transition:background .15s}
.gwcall-key:not(:disabled):hover .gwcall-orb{background:rgba(255,255,255,.22)}
.gwcall-key[aria-pressed=true] .gwcall-orb{background:var(--gw-white);color:var(--gw-charcoal)}
.gwcall-key.end .gwcall-orb{background:var(--gw-crit);color:var(--gw-white)}.gwcall-key.end:hover .gwcall-orb{background:var(--crit);filter:brightness(.92)}
.gwcall-orb svg{width:28px;height:28px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.gwcall-key:focus-visible{outline:0}.gwcall-key:focus-visible .gwcall-orb,.gwcall-min:focus-visible,.gwcall-bar button:focus-visible{outline:2px solid var(--gw-yellow);outline-offset:3px}
.gwcall-bar{position:fixed;z-index:1160;right:24px;bottom:24px;width:340px;display:flex;align-items:center;gap:6px;padding:6px;border-radius:28px;background:var(--gw-charcoal);color:var(--gw-white);box-shadow:0 10px 30px rgba(1,30,19,.35)}
.gwcall-bar-open{flex:1 1 auto;min-width:0;min-height:44px;display:flex;align-items:center;gap:10px;padding:0 12px;border:0;border-radius:22px;background:transparent;color:inherit;font-size:var(--fs-sm);font-weight:500;text-align:left;cursor:pointer}
.gwcall-bar-open:hover{background:rgba(255,255,255,.08)}
.gwcall-bar-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}
.gwcall-dot{flex:none;width:10px;height:10px;border-radius:50%;background:var(--c400)}
.gwcall-bar[data-phase=connected] .gwcall-dot{background:var(--gw-mint)}
.gwcall-bar-end{flex:none;width:44px;height:44px;border-radius:50%;border:0;display:flex;align-items:center;justify-content:center;background:var(--gw-crit);color:var(--gw-white);cursor:pointer}
.gwcall-bar-end svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
@media(max-width:600px){
.gwcall{padding:0;background:var(--gw-charcoal)}
.gwcall-card{width:100%;height:100%;min-height:0;max-height:none;border-radius:0;box-shadow:none;padding:calc(var(--safe-t) + 8px) calc(var(--safe-r) + 16px) calc(var(--safe-b) + 40px) calc(var(--safe-l) + 16px)}
.gwcall-bar{left:calc(var(--safe-l) + 16px);right:calc(var(--safe-r) + 16px);width:auto;bottom:calc(var(--tabbar) + var(--safe-b) + 12px)}
}
/* ---- period picker (rangepick.js), shared by the dashboard and Marketing metrics -----
   Today, 7 days, 30 days, This month, Custom as a row of buttons, and the custom
   dates as an inline form under it. The row is the shared segmented control
   (.gwseg, added by rangepick.js): five equal segments, the width of the page
   on a phone, every button 44 px tall. The page places the group. */
.gwrange{min-width:0}
.customrange{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:var(--fs-sm);color:var(--fg2)}
.customrange label{display:flex;align-items:center;gap:6px}.customrange input[type=date]{height:31px;padding:0 10px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg);font-size:13px}
.customrange .err{min-height:0}
@media(max-width:640px){
.gwrange{flex:1 1 100%;margin:2px 0 0}}
/* The installed console offline (console-offline.html, console-offline.js,
   Michel, 13 Oct 2026): the lock card the copy opens behind, then the copy
   itself, read only. Since 14 Oct 2026 ("making it look more like the normal
   mode") the copy wears the phone console's own look: the dark top bar with
   the section over the page title and the connection dot, one calm line that
   says how old the screen is, the dashboard's KPI cards and figure strips,
   cards with the yellow rule, and the tab bar at the foot (the island's
   tokens). The wordmark and the icons are inline, never an image. */
.gwoff [hidden]{display:none!important}
.gwoff-sprite{position:absolute;width:0;height:0;overflow:hidden}
.gwoff .lockcard{display:flex;flex-direction:column;gap:12px;text-align:left}
.gwoff .lockcard .gwoff-mark{display:block;width:114px;height:28px;margin-bottom:12px;align-self:flex-start;color:var(--fg0)}
.gwoff .lockcard h2{margin:0;font-size:var(--fs-title)}
.gwoff .lockcard p{margin:0}
.gwoff .lockcard .btn{width:100%;height:48px;justify-content:center;margin-top:4px}
body.gwoff:not(.login){display:block;min-height:100vh;background:var(--bg)}
.gwoff-top{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:6px;min-height:calc(56px + env(safe-area-inset-top,0px));padding:env(safe-area-inset-top,0px) calc(6px + env(safe-area-inset-right,0px)) 0 calc(16px + env(safe-area-inset-left,0px));background:var(--rail);color:var(--rail-fg)}
.gwoff-logo{flex:none;display:block;width:61px;height:15px;color:var(--gw-white)}
.gwoff-title{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:3px;margin-left:6px;padding-left:12px;border-left:1px solid var(--rail3)}
.gwoff-sec{font:500 13px/1 var(--font);color:var(--rail-fg)}
.gwoff-title h1{margin:0;font-size:18px;font-weight:500;line-height:1.15;color:var(--gw-white);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gwoff-top .netstate{flex:none;cursor:default;padding:0 6px;color:var(--rail-fg)}
.gwoff-top .netstate[data-state=live] span{display:none}
.gwoff-iconbtn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--gw-white);cursor:pointer}
.gwoff-iconbtn:hover{background:var(--rail2)}
.gwoff-iconbtn:focus-visible{outline:2px solid var(--gw-yellow);outline-offset:1px}
.gwoff-iconbtn svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.gwoff-main{display:flex;flex-direction:column;gap:14px;max-width:760px;margin:0 auto;padding:14px calc(14px + env(safe-area-inset-right,0px)) calc(24px + env(safe-area-inset-bottom,0px)) calc(14px + env(safe-area-inset-left,0px))}
body.gwoff-has-island .gwoff-main{padding-bottom:calc(env(safe-area-inset-bottom,0px) + 104px)}
/* one line, the console's card ground, yellow only as the small mark */
.gwoff-note{display:flex;align-items:center;gap:10px;min-height:40px;padding:8px 14px 8px 12px;border:1px solid var(--border);border-radius:var(--rs);background:var(--card);box-shadow:var(--shadow);color:var(--fg2);font-size:var(--fs-sm)}
.gwoff-note i{flex:none;width:3px;height:18px;border-radius:2px;background:var(--sev-warn)}
.gwoff-note.old i{background:var(--sev-crit)}
.gwoff-note span{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gwoff-note b{font-weight:500;color:var(--fg0)}
.gwoff-live{width:100%;min-height:44px;justify-content:center}
.gwoff-page{display:flex;flex-direction:column;gap:14px}
.gwoff-who{margin:4px 0 0;text-align:center;font-size:var(--fs-xs)}
.gwoff-who b{font-weight:500}
.gwoff-card .body{padding:12px var(--in,24px) 18px}
.gwoff-card.list .body{padding:4px var(--in,24px) 8px}
.gwoff-empty{margin:8px 0}
.gwoff-foot{margin:12px 0 0}
.gwoff-lbl{margin:18px 0 6px;font-size:var(--fs-xs);font-weight:500;color:var(--fg2)}
/* figures: the morning check's strip, label over value, a hairline between */
.gwoff-figs{margin:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));row-gap:14px}
.gwoff-figs.c2{grid-template-columns:repeat(2,minmax(0,1fr))}
.gwoff-fig{display:flex;flex-direction:column;justify-content:space-between;gap:4px;min-width:0;padding:0 12px;border-left:1px solid var(--border)}
.gwoff-figs:not(.c2)>.gwoff-fig:nth-child(3n+1),.gwoff-figs.c2>.gwoff-fig:nth-child(2n+1){padding-left:0;border-left:0}
.gwoff-fig dt{font-size:var(--fs-xs);line-height:1.3;color:var(--fg3)}
.gwoff-fig dd{margin:0;font-size:24px;font-weight:500;line-height:1.1;color:var(--fg0);font-variant-numeric:tabular-nums;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gwoff-fig.hot dd{color:var(--crit)}
/* the dashboard's KPI cards (dashboard.css .stats span.kpi), two to a row on a
   phone, an odd last card across the row */
.gwoff-stats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.gwoff-stats span.kpi{min-width:0;padding:12px 14px 10px;justify-content:flex-end;white-space:normal}
.gwoff-stats span.kpi b{display:flex;align-items:baseline;flex-wrap:wrap;gap:0 5px;font-size:22px}
.gwoff-stats span.kpi i.unit{font-style:normal;font-weight:400;font-size:var(--fs-xs);color:var(--fg3)}
.gwoff-stats span.kpi em.lbl{font-style:normal}
.gwoff-stats span.kpi:last-child:nth-child(odd){grid-column:1/-1}
@media(min-width:700px){
.gwoff-stats{grid-template-columns:repeat(6,minmax(0,1fr));gap:14px}
.gwoff-stats span.kpi,.gwoff-stats span.kpi:last-child:nth-child(odd){grid-column:span 2}
.gwoff-stats span.kpi:nth-child(3n+1):last-child{grid-column:1/-1}
.gwoff-stats span.kpi:nth-child(3n+1):nth-last-child(2),.gwoff-stats span.kpi:nth-child(3n+1):nth-last-child(2)+span.kpi{grid-column:span 3}}
/* lists: the record and its state on one line, the detail under it */
.gwoff-list{list-style:none;margin:0;padding:0}
.gwoff-list li{min-width:0;padding:12px 0;border-bottom:1px solid var(--border)}
.gwoff-list li:last-child{border-bottom:0}
.gwoff-row{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0}
.gwoff-row>b{min-width:0;font-weight:500;color:var(--fg0);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gwoff-row>.pill{flex:none;font-size:var(--fs-sm)}
.gwoff-sub{display:block;margin-top:2px;font-size:var(--fs-sm);color:var(--fg);overflow-wrap:anywhere}
.gwoff-alert{padding:8px 0}
.gwoff-alert .pill{align-items:baseline;white-space:normal}
/* the tab bar at the foot: the phone console's island, without the drag */
.gwoff-island{position:fixed;z-index:30;left:calc(env(safe-area-inset-left,0px) + 21px);right:calc(env(safe-area-inset-right,0px) + 21px);bottom:calc(env(safe-area-inset-bottom,0px) + 21px);max-width:560px;margin:0 auto;display:flex;height:62px;padding:4px;border-radius:31px;background:var(--isl-bar);box-shadow:var(--isl-shadow)}
.gwoff-tab{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;padding:0 2px;border:0;border-radius:26px;background:transparent;color:var(--isl-label);font:400 10px/1.1 var(--font);cursor:pointer;-webkit-tap-highlight-color:transparent}
.gwoff-tab.on{background:var(--isl-pill);font-weight:500}
.gwoff-tab .ico svg{display:block;width:24px;height:24px;stroke:var(--isl-icon);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.gwoff-tab.on .ico svg{stroke:var(--isl-lit-edge);fill:var(--isl-lit-fill)}
.gwoff-tab .gwlbl{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gwoff-tab:focus-visible{outline:2px solid var(--isl-label);outline-offset:-4px}
body.gwoff .gwoff-sheet:not([hidden]){display:block;position:fixed;inset:0;z-index:1185}
.gwoff-sheet .gwvsheet-opt{width:100%;border:0;background:none;font:inherit;text-align:left;cursor:pointer}
/* Service recovery: the settings pair up two to a row instead of one long
   column, and the wallet lookup gives its field the row with the button */
@media(max-width:600px){
.carepage .crset{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px 12px}
.carepage .crset label{min-width:0;justify-content:flex-end}
.carepage .crset label:has(input[type=checkbox]){min-height:44px;justify-content:flex-start}
.carepage .crset input:not([type=checkbox]){width:100%;min-width:0;box-sizing:border-box}
.carepage #cr-wallet-find{flex-wrap:nowrap}
.carepage #cr-wallet-find input{flex:1 1 auto;min-width:0}
.carepage #cr-wallet-find .btn{flex:none;min-height:44px}
}
/* iPhone date and time fields (Michel, 13 Oct 2026, Vehicles, Record a
   document: "all the text boxes need to be the same width, currently two are
   wider"). Safari gives these a built-in minimum width and centres the value,
   so in a form they stuck out past every other box. On a touch screen they
   take the width of their box like any other field and read from the left. */
@media (pointer:coarse){
  input[type=date],input[type=time],input[type=datetime-local],input[type=month],input[type=week]{-webkit-appearance:none;appearance:none;min-width:0;max-width:100%;box-sizing:border-box;text-align:left;background-color:var(--card)}
  .actform label>input[type=date],.actform label>input[type=time],.actform label>input[type=datetime-local],.actform label>input[type=month],.actform label>input[type=week],.gwfsheet-body input[type=date],.gwfsheet-body input[type=time]{width:100%}
  input[type=date]::-webkit-date-and-time-value,input[type=time]::-webkit-date-and-time-value,input[type=datetime-local]::-webkit-date-and-time-value{text-align:left}
}
/* Sign-in and lock pages on a phone: one screen that does not move (Michel,
   13 Oct 2026: "Don't allow to scroll down or up the login page on mobile").
   The page is exactly the screen's height, the card centred in it, and the
   rubber-band drag is off. A screen too short for the card (a small phone in
   landscape, or with the keyboard up) still scrolls, so nothing is cut off. */
@media (max-width:900px) and (min-height:560px){
  html:has(body.login){height:100%;overflow:hidden;overscroll-behavior:none}
  body.login{box-sizing:border-box;height:100vh;height:100dvh;min-height:0;overflow:hidden;overscroll-behavior:none;touch-action:manipulation}
}
/* ---- photo viewer (chrome.js gwViewer, Michel 13 Oct 2026) ----------------
   A document photo opens in the console: a bar with Close and Rotate, the
   picture on a dark stage (never a white page while it loads), and the page's
   actions under it. Full screen on a phone, between the safe areas; a centred
   box on a laptop, the actions beside the picture. */
.gwphoto[hidden]{display:none!important}
html.gwphoto-open,html.gwphoto-open body{overflow:hidden}
.gwphoto{position:fixed;inset:0;z-index:1300;display:flex;align-items:center;justify-content:center}
.gwphoto-scrim{position:absolute;inset:0;background:rgba(0,0,0,.6)}
.gwphoto-box{position:relative;display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto;width:100%;height:100%;background:var(--card);color:var(--fg);overflow:hidden}
.gwphoto-bar{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px;padding:calc(var(--safe-t) + 8px) calc(var(--safe-r) + 10px) 8px calc(var(--safe-l) + 10px);border-bottom:1px solid var(--border)}
.gwphoto-bar b{font-size:16px;font-weight:600;color:var(--fg0);text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gwphoto-bar .btn{min-height:44px;height:auto;padding:0 12px;gap:6px;justify-content:center}
.gwphoto-bar .btn[hidden]{display:none}
.gwphoto-bar svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.gwphoto-stage{position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden;background:var(--gw-charcoal);color:var(--gw-white);touch-action:none;user-select:none;-webkit-user-select:none}
.gwphoto-img{max-width:100%;max-height:100%;object-fit:contain;transform-origin:center;transition:transform .12s ease-out;cursor:zoom-in}
.gwphoto-img[hidden]{display:none}
.gwphoto-state,.gwphoto-err,.gwphoto-pdf{margin:0;padding:24px;text-align:center;font-size:15px;line-height:1.4;max-width:420px}
.gwphoto-err,.gwphoto-pdf{display:flex;flex-direction:column;align-items:center;gap:14px}
.gwphoto-err[hidden],.gwphoto-pdf[hidden],.gwphoto-state[hidden],.gwphoto-none[hidden]{display:none}
.gwphoto-none{margin:0;padding:24px;text-align:center;font-size:15px;line-height:1.4;max-width:420px}
.gwphoto-err p,.gwphoto-pdf p{margin:0}
.gwphoto-err .btn,.gwphoto-pdf .btn{min-height:44px;min-width:160px;justify-content:center}
.gwphoto-acts{padding:12px calc(var(--safe-r) + 16px) calc(var(--safe-b) + 12px) calc(var(--safe-l) + 16px);border-top:1px solid var(--border);max-height:55vh;overflow-y:auto;overscroll-behavior:contain;background:var(--card)}
.gwphoto-acts[hidden]{display:none}
@media(prefers-reduced-motion:reduce){.gwphoto-img{transition:none}}
.gwphoto-close svg+svg{display:none}
/* The dark look (gwViewer look:'dark', the chat's photos, Michel 28 Oct 2026):
   the picture on black edge to edge, the name and a round X over its top. */
.gwphoto.dark .gwphoto-box{background:var(--gw-charcoal);color:var(--gw-white);grid-template-rows:minmax(0,1fr)}
.gwphoto.dark .gwphoto-bar{position:absolute;inset:0 0 auto 0;z-index:1;border-bottom:0;background:linear-gradient(color-mix(in srgb,var(--gw-charcoal) 70%,transparent),transparent)}
.gwphoto.dark .gwphoto-bar b{color:var(--gw-white)}
.gwphoto.dark .gwphoto-rotate{display:none}
.gwphoto.dark .gwphoto-close{grid-column:3;grid-row:1;width:44px;min-width:44px;padding:0;border:0;border-radius:50%;background:color-mix(in srgb,var(--gw-white) 18%,transparent);color:var(--gw-white)}
.gwphoto.dark .gwphoto-close svg:first-child,.gwphoto.dark .gwphoto-close span{display:none}
.gwphoto.dark .gwphoto-close svg+svg{display:block;width:22px;height:22px}
.gwphoto.dark .gwphoto-bar b{grid-column:1/3;grid-row:1;text-align:left;padding-left:6px}
.gwphoto.dark .gwphoto-stage{padding:calc(var(--safe-t) + 60px) 0 var(--safe-b)}
.gwphoto.dark .gwphoto-img{cursor:default}
@media(min-width:901px){
.gwphoto-box{width:min(1180px,calc(100vw - 64px));height:min(860px,calc(100vh - 64px));border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,.35)}
.gwphoto-bar{padding:10px 12px}
.gwphoto.has-acts .gwphoto-box{grid-template-columns:minmax(0,1fr) 380px;grid-template-rows:auto minmax(0,1fr)}
.gwphoto.has-acts .gwphoto-bar{grid-column:1/-1}
.gwphoto.has-acts .gwphoto-acts{max-height:none;border-top:0;border-left:1px solid var(--border);padding:16px}
}
/* The dark look stays edge to edge on a laptop too, over the phone chat's own layer (1300). */
.gwphoto.dark{z-index:1600}
.gwphoto.dark .gwphoto-box{width:100%;height:100%;border-radius:0;box-shadow:none}
.gwphoto.dark .gwphoto-bar{padding:calc(var(--safe-t) + 8px) calc(var(--safe-r) + 10px) 8px calc(var(--safe-l) + 10px)}
/* ---- address fields (Michel, 15 Oct 2026; fleet/static/addrfield.js) ----------------------
   Every console form that takes a pickup, a drop-off or a stop: type, then
   pick a row; the rows sit under the field, in the flow, so a scrolling
   form or sheet never clips them. */
.addr{min-width:0}.addr>label{margin-bottom:0}
.addr-list{list-style:none;margin:4px 0 0;padding:4px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);box-shadow:var(--shadow);max-height:280px;overflow-y:auto}
.addr-list[hidden]{display:none}
.addr-list li{display:flex;flex-direction:column;justify-content:center;gap:1px;min-height:44px;padding:6px 10px;border-radius:var(--rs);cursor:pointer;font-size:var(--fs-sm);color:var(--fg)}
.addr-list li b{font-weight:500;color:var(--fg0);overflow-wrap:anywhere}.addr-list li span{color:var(--fg3);font-size:var(--fs-xs);overflow-wrap:anywhere}
.addr-list li[aria-selected=true],.addr-list li:hover{background:var(--sel)}
.addr-list li.grp{min-height:0;padding:8px 10px 2px;cursor:default;font-size:var(--fs-lbl);letter-spacing:.06em;text-transform:uppercase;color:var(--fg3)}.addr-list li.grp:hover{background:none}
.addr-list li.none{cursor:default;color:var(--fg3)}.addr-list li.none:hover{background:none}

/* ---- Needs you now on the Command Centre (ccnow.js; Sai Teja, 19 Oct 2026) ----
   The same card as on Rides (rides.css .nownow), above the counters: one plain
   sentence per thing that needs a person and the button that deals with it.
   On a phone the map is the page, so a red chip over it opens the card. */
main.fleet>.nownow{order:-8;grid-column:1/-1;border-color:var(--crit);padding:14px 16px}
main.fleet>.nownow[hidden]{display:none}
main.fleet>.nownow.calm{border-color:var(--border);padding:8px 16px}
main.fleet>.nownow.calm h3{display:none}
.nownow h3{margin:0 0 4px;padding:0;display:flex;align-items:center;gap:8px;line-height:24px}
.nownow h3::after{display:none}
.nownow h3 .n{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0 7px;box-sizing:border-box;background:var(--gw-crit);color:var(--gw-white);border-radius:999px;font-size:var(--fs-xs);font-weight:600;line-height:1}
.nownow h3 .n:empty{display:none}
.nownow .ccclose{display:none;margin-left:auto}
.nownow ul{list-style:none;margin:0;padding:0}
#ccnow-list>li{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,320px);align-items:center;gap:10px 16px;padding:12px 0;border-top:1px solid var(--border)}
#ccnow-list>li:first-child{border-top:0}
#ccnow-list>li.quiet{display:block;color:var(--fg2);padding:2px 0}
#ccnow-list li .what{min-width:0;line-height:1.35}
#ccnow-list li .sub{display:block;margin:2px 0 0;color:var(--fg2);font-size:var(--fs-sm);overflow-wrap:anywhere}
#ccnow-list>li.sos .what b{color:var(--crit)}
.ccpick{grid-column:1/-1;padding:10px 12px;background:var(--panel);border:1px solid var(--border);border-radius:var(--rs)}
.ccpick p{margin:4px 0}.ccpick .ok{color:var(--okfg);font-weight:600}.ccpick .err{color:var(--crit);font-weight:600}
.cccars>li{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 0;border-top:1px solid var(--border)}
.cccars>li:first-child{border-top:0}
.cccars>li.ccask{background:var(--sel);margin:0 -12px;padding:8px 12px;flex-wrap:wrap}
.cccars .btn{min-height:40px}
@media(max-width:640px){#ccnow-list>li{grid-template-columns:minmax(0,1fr)}}
@media(max-width:1100px),(pointer:coarse) and (max-width:1366px){main.fleet>.nownow{order:-4}}
.mm-now{align-self:flex-start;min-height:44px;padding:0 18px;border:0;border-radius:var(--rs);background:var(--gw-crit);color:var(--gw-white);font-weight:600;font-size:var(--fs-sm);box-shadow:0 2px 10px rgba(184,70,31,.3);cursor:pointer}
.mm-now[hidden]{display:none}
@media(max-width:900px),(pointer:coarse) and (max-width:1366px){
body.mapmode main.fleet:not(.listview)>#ccnow.open{display:block;position:absolute;left:calc(var(--safe-l) + 10px);right:calc(var(--safe-r) + 10px);top:118px;max-height:calc(100% - 140px);overflow-y:auto;z-index:1020;margin:0;box-shadow:0 10px 34px rgba(20,24,33,.28)}
body.mapmode main.fleet:not(.listview)>#ccnow.open .ccclose{display:inline-flex}
}

/* ---- the view dropdown (#1600): a filter on the menu, never access ------------------------------
   fleet/consoleview.py writes the person's view on <html> as data-gw-view when it serves the page, so
   these rules hide the groups that view does not show before any script runs (no flash). The rail and
   both menus built from it (the iPad drawer, phone All pages) carry data-views on each group and page
   (tools/nav.py, chrome.js). The group of the page on screen is never hidden (data-here), and Show all
   (.gwshowall, this device) lists everything. With no view chosen nothing is hidden. */
html[data-gw-view="owner"]:not(.gwshowall) :is(.nav, .gwmenu) [data-views]:not([data-views~="owner"]):not([data-here]),
html[data-gw-view="ops"]:not(.gwshowall) :is(.nav, .gwmenu) [data-views]:not([data-views~="ops"]):not([data-here]),
html[data-gw-view="dispatcher"]:not(.gwshowall) :is(.nav, .gwmenu) [data-views]:not([data-views~="dispatcher"]):not([data-here]),
html[data-gw-view="fleet"]:not(.gwshowall) :is(.nav, .gwmenu) [data-views]:not([data-views~="fleet"]):not([data-here]),
html[data-gw-view="support"]:not(.gwshowall) :is(.nav, .gwmenu) [data-views]:not([data-views~="support"]):not([data-here]),
html[data-gw-view="finance"]:not(.gwshowall) :is(.nav, .gwmenu) [data-views]:not([data-views~="finance"]):not([data-here]),
html[data-gw-view="marketing"]:not(.gwshowall) :is(.nav, .gwmenu) [data-views]:not([data-views~="marketing"]):not([data-here]){display:none}
/* the page on screen sits outside the view: said under its group's heading */
.nav .gwoutside{flex:none;padding:0 24px 4px;font-size:var(--fs-xs);color:var(--rail-fg2);font-style:italic}
.gwmenu .gwoutside{margin:-2px 0 4px;font-size:11px;line-height:14px;color:var(--fg3);font-style:italic}
.gwmenu.gwall-on .gwall-sec .gwoutside{margin:0 0 2px}
/* the rail's foot (laptop): View and Show all, above the brand line */
.gwviewbox{flex:none;display:flex;flex-direction:column;gap:6px;padding:10px 24px 12px;border-top:1px solid var(--rail2)}
.gwviewbox .gwviewlbl{display:flex;align-items:center;gap:10px;font-size:var(--fs-xs);color:var(--rail-fg2)}
.gwviewbox select{flex:1 1 auto;min-width:0;min-height:32px;padding:4px 8px;border-radius:8px;border:1px solid var(--rail3);background:var(--rail2);color:var(--rail-fg);font-size:var(--fs-sm)}
.gwviewbox select:focus-visible{outline:2px solid var(--gw-yellow);outline-offset:1px}
.gwshowall-sw{display:flex;align-items:center;gap:8px;font-size:var(--fs-xs);color:var(--rail-fg2);cursor:pointer;min-height:24px}
.gwshowall-sw input{accent-color:var(--gw-yellow);width:16px;height:16px;margin:0}
/* the drawer (iPad): the list at the top; a phone has the one-row button that opens the sheet instead */
.gwmenu-view{flex:none;padding:0 16px 8px 24px}
.gwmenu-view .gwviewlbl{display:flex;align-items:center;gap:10px;font-size:var(--fs-sm);color:var(--fg2)}
.gwmenu-view select{flex:1 1 auto;min-width:0;min-height:44px;padding:6px 10px;border-radius:10px;border:1px solid var(--border2);background:var(--card);color:var(--fg0)}
.gwmenu-view .gwviewbtn{display:none}
html.gwviews .gwmenu-view{padding:0 12px 2px 16px}
html.gwviews .gwmenu-view .gwviewlbl{display:none}
html.gwviews .gwmenu-view .gwviewbtn{display:flex;align-items:center;gap:8px;width:100%;min-height:40px;padding:0 12px;border:1px solid var(--border2);border-radius:10px;background:var(--card);color:var(--fg0);font:inherit;font-size:14px;font-weight:500;text-align:left;cursor:pointer}
html.gwviews .gwmenu-view .gwviewbtn .tx{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
html.gwviews .gwmenu-view .gwviewbtn i{flex:none;width:7px;height:7px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg) translate(-2px,-2px);opacity:.6}
.gwmenu-acts .gwshowallbtn[aria-pressed=true]{border-color:var(--ink);color:var(--fg0)}
.gwmenu-acts .gwshowallbtn{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='7' height='7' rx='1.5'/%3E%3Crect x='14' y='3' width='7' height='7' rx='1.5'/%3E%3Crect x='3' y='14' width='7' height='7' rx='1.5'/%3E%3Crect x='14' y='14' width='7' height='7' rx='1.5'/%3E%3C/svg%3E")}
/* A placeholder tab (WIP, #1600 plan 5.4): its name, one sentence, "Not built yet" and links to the pages that cover part of it today. Tokens only, so dark follows; under main so a page's own .pane or .panel padding does not win. */
main .wip-panel{max-width:640px;margin:16px var(--in,24px) var(--in,24px);padding:20px;border:1px dashed var(--border2);border-radius:var(--r);background:var(--card);color:var(--fg)}
.wip-panel h2{margin:0 0 8px;font-size:var(--fs-title);font-weight:600;color:var(--fg0)}
.wip-panel p{margin:0 0 12px;line-height:1.5}
.wip-panel .wip-tag{display:inline-block;padding:2px 10px;border-radius:999px;background:var(--chip);color:var(--chip-fg);font-size:var(--fs-xs);font-weight:600}
.wip-panel .wip-links{margin:0;font-size:var(--fs-sm);color:var(--fg2)}
.wip-panel .wip-links a{color:var(--link);margin-right:12px;white-space:nowrap}
/* One look across the console (OPS-UNIFORM). Every text box, dropdown, tab and filter chip
   starts from these, so a page that adds no style of its own still looks like the rest.
   :where() keeps them at zero weight: a page rule always wins, and pages point at the same
   sizes (--ctl, --ctl-sm, --tab-pad, --tab-pad-sub) instead of their own numbers. */
:where(input:not([type]),input[type=text],input[type=search],input[type=email],input[type=tel],input[type=number],input[type=date],input[type=month],input[type=time],input[type=week],input[type=datetime-local],input[type=password],input[type=url],select:not([multiple]),textarea){box-sizing:border-box;height:var(--ctl);padding:0 12px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg);font-size:var(--fs-sm);font-family:var(--font)}
:where(textarea,select[multiple]){box-sizing:border-box;height:auto;min-height:var(--ctl);padding:8px 12px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg);font-size:var(--fs-sm);font-family:var(--font)}
:where(.tab){background:none;border:0;border-bottom:2px solid transparent;border-radius:0;padding:var(--tab-pad);font-family:var(--font);font-weight:500;font-size:var(--fs);line-height:1.3;color:var(--fg2);cursor:pointer}
:where(.tab):hover{color:var(--fg0)}:where(.tab.on,.tab[aria-selected=true]){color:var(--fg0);border-bottom-color:var(--ink)}
:where(.chip,.rchip,.cachip):is(button,a){display:inline-flex;align-items:center;gap:6px;height:var(--ctl);padding:0 14px;border:1px solid var(--edge);border-radius:var(--rs);background:var(--card);color:var(--fg);font:500 var(--fs-sm)/1 var(--font);cursor:pointer;white-space:nowrap}
:where(.chip,.rchip,.cachip):is(button,a):hover{background:var(--hover);border-color:var(--fg3)}
:where(.chip,.rchip):is(button,a):is(.on,[aria-pressed=true]){background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
input:where(:not([type]),[type=text],[type=search],[type=email],[type=tel],[type=number],[type=date],[type=month],[type=time],[type=week],[type=datetime-local],[type=password],[type=url]),select,textarea{font-size:var(--fs-sm)}
/* Search boxes are the one round control; everything you press is a rounded rectangle. */
:where(input[type=search]){border-radius:999px;padding:0 16px}
/* Tables that sit straight in a card or panel start on the card's 24px line, like its title,
   toolbar and tabs. Tables inside a padded card body keep their own inset. */
:is(.card,.panel,.pane,#listwrap)>table>*>tr>:is(th,td):first-child,:is(.card,.panel,.pane,#listwrap)>.tablewrap>table>*>tr>:is(th,td):first-child{padding-left:var(--in,24px)}:is(.card,.panel,.pane,#listwrap)>table>*>tr>:is(th,td):last-child,:is(.card,.panel,.pane,#listwrap)>.tablewrap>table>*>tr>:is(th,td):last-child{padding-right:var(--in,24px)}
/* One dropdown arrow, drawn from the colour tokens so it follows dark mode, a fixed 14px from
   the right edge. !important on these few longhands only: many pages set the background
   shorthand on their selects, which would otherwise wipe the arrow. */
select:not([multiple]){-webkit-appearance:none!important;appearance:none!important;padding-right:34px!important;background-image:linear-gradient(45deg,transparent 50%,var(--fg2) 50%),linear-gradient(135deg,var(--fg2) 50%,transparent 50%)!important;background-position:calc(100% - 19px) 52%,calc(100% - 14px) 52%!important;background-size:5px 5px,5px 5px!important;background-repeat:no-repeat!important;text-overflow:ellipsis}
select:not([multiple]):disabled{opacity:.55}
/* Status filters inside a toolbar (Vehicles, Drivers, Documents) become their own grey tab
   row across the card, like the second tab row on School runs, so the search and buttons
   below get one clean line. */
@media (min-width:801px){.toolbar>.subtabs{order:-1;flex:1 1 100%;margin:-14px calc(-1 * var(--in,24px)) 2px;padding:2px var(--in,24px) 0;background:var(--panel);border-bottom:1px solid var(--border)}}
/* .sub is a small grey subtitle; a toolbar that is also .sub (Vehicles, Drivers, Partners) keeps the toolbar's own line and type. */
.toolbar.sub{margin-left:0;color:inherit;font-size:inherit}
/* Incidents: the search box opens the filter row instead of wrapping alone at its end. */
#in-q{order:-1}
/* No-entry zones: Edit and Switch off stack in their cell so the list fits its card. */
@media (min-width:801px){.szpage tbody td:last-child{white-space:normal;width:1%}.szpage tbody td:last-child .btn{display:flex;width:100%;justify-content:center}.szpage tbody td:last-child .btn+.btn{margin-top:6px}}
/* Phone filter chips (Michel, 28 Oct 2026): "the UI needs to be proportional". Status filters
   (Vehicles, Drivers, Rides, School runs, Marketing, Payments) used to wrap into three tall rows
   on a phone, about 350 px before the list. On a phone they are now one line of chips that
   scrolls sideways, as on Uber, Bolt and Gmail: a 32 px chip inside a 44 px tap target (the
   6 px above and below is a transparent border the fill is clipped from), snap stops, a soft
   fade on the side that has more (chrome.js sets .gwchip-l and .gwchip-r), and the picked chip
   scrolled into view (chrome.js). The two :not(#...) give these rules an ID's weight so they
   win over the dark-mode pick colours, which carry one. Laptops are unchanged. */
@media (max-width:800px){
html:not(#gwchip):not(#gwchip2) :is(.toolbar>.subtabs,.tabbar.inner>.tabs,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs,.toolbar>.rchips){flex-wrap:nowrap!important;align-items:center;gap:6px!important;min-width:0;max-width:100%;height:auto;overflow-x:auto!important;overflow-y:hidden!important;overscroll-behavior-x:contain;scroll-snap-type:x proximity;scroll-padding-inline:16px;scrollbar-width:none;-webkit-overflow-scrolling:touch;animation:none!important;-webkit-mask-image:none;mask-image:none}
/* A row inside a toolbar takes the toolbar's full line and its inset; a row straight in a card or
   panel (Marketing, Payments) keeps its own padding and its own rule for when it shows. */
html:not(#gwchip):not(#gwchip2) :is(.toolbar>.subtabs,.tabbar.inner>.tabs,.toolbar>.rchips){flex:1 1 100%!important;margin:0!important;padding:0!important}
:is(.toolbar>.subtabs,.tabbar.inner>.tabs,.card>.subtabs,.panel>.subtabs,.toolbar>.rchips)::-webkit-scrollbar{display:none}
html:not(#gwchip):not(#gwchip2) :is(.toolbar>.subtabs,.tabbar.inner>.tabs,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs,.toolbar>.rchips)>:is(.tab,.stab,.rchip){flex:none!important;scroll-snap-align:start;display:inline-flex;align-items:center;gap:6px;box-sizing:border-box!important;height:44px!important;min-height:44px!important;min-width:44px!important;margin:0!important;padding:0 12px!important;border-style:solid!important;border-width:6px 0!important;border-color:transparent!important;border-radius:var(--rs)/calc(var(--rs) + 6px)!important;background-clip:padding-box!important;font-size:14px!important;line-height:1.2!important;white-space:nowrap}
html:not(#gwchip):not(#gwchip2) :is(.toolbar>.subtabs,.tabbar.inner>.tabs,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs,.toolbar>.rchips)>:is(.tab,.stab,.rchip):not(.on,[aria-selected=true],[aria-pressed=true]){background-color:var(--panel)!important;color:var(--fg2)}
html:not(#gwchip):not(#gwchip2) :is(.toolbar>.subtabs,.tabbar.inner>.tabs,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs,.toolbar>.rchips)>:is(.tab,.stab,.rchip):focus-visible{outline-offset:-4px}
html:not(#gwchip):not(#gwchip2) :is(.toolbar>.subtabs,.tabbar.inner>.tabs,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs,.toolbar>.rchips)>:is(.tab,.stab,.rchip).hidden{display:none!important}
.gwchip-r{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent)!important;mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent)!important}
.gwchip-l{-webkit-mask-image:linear-gradient(90deg,transparent,#000 28px)!important;mask-image:linear-gradient(90deg,transparent,#000 28px)!important}
.gwchip-l.gwchip-r{-webkit-mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent)!important;mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent)!important}
/* The count under the chips ("10 vehicles") starts at the left edge like the chips above it,
   instead of floating right-aligned in the middle of the card. */
html:not(#gwchip) .toolbar:has(>.subtabs,>.rchips)>.count{text-align:left!important;line-height:20px;font-size:var(--fs-sm)}
/* The search box gives way to Filters and the more button in the phone tool row, instead of
   holding 220 px and pushing the more button past the card's edge. */
html.gwviews main .gwtoolrow input[type=search]:not(#fts-q){min-width:0}
}
/* Touch screens: every tab, second-row tab and status chip is at least 44 px to tap. */
@media (pointer:coarse){.tabs .tab,.tabs>a,.toolbar>.subtabs .tab,.tabbar.inner .tab,.tabbar.sub .tab,#mtabs .tab,.toolbar>.rchips>.rchip,.subtabs>.stab,main.slots .tabs a{min-height:44px!important;min-width:44px!important;box-sizing:border-box}}
/* One button size in toolbars and pagers: a small button there is the regular 36 px. */
.toolbar .btn.small,.pager .btn.small{height:var(--ctl);line-height:calc(var(--ctl) - 2px);padding:0 16px;font-size:14px}
/* Switches the same height as the boxes and buttons beside them (36 px) on a laptop. */
@media (pointer:fine){.gwseg>:is(button,.btn,label,a){min-height:28px;padding-top:2px;padding-bottom:2px}}
/* Room for the words in a box: dropdown text stops before the arrow, dates fit their icon. */
select:not([multiple]){padding-right:30px!important;background-position:calc(100% - 17px) 52%,calc(100% - 12px) 52%!important}
input[type=date]{min-width:150px}input[type=datetime-local]{min-width:200px}
@media (min-width:801px){#v-q{flex:1 1 260px;min-width:240px}#in-q{flex:1 1 280px;min-width:240px}#in-status,#in-kind{max-width:220px}#fts-q{flex:1 1 380px;max-width:none}}
/* The dropdown arrow is a thin chevron like the ones on menus and Bookings tools; light and dark
   versions in the console's secondary text colour (fg2). */
select:not([multiple]){background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%235F677A' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")!important;background-position:calc(100% - 12px) 50%!important;background-size:10px 6px!important}
:root[data-mode=dark] select:not([multiple]){background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23A6A6A6' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")!important}
@media (prefers-color-scheme:dark){:root[data-mode=system] select:not([multiple]){background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23A6A6A6' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")!important}}
/* An empty message line under a toolbar takes no room until it has something to say. */
:is(.panel,.pane)>.result:empty{min-height:0;padding:0}
/* Second tabs (Gokul, 22 Oct 2026): a narrower view inside a tab (Drivers and Vehicles status,
   School runs routes, Marketing managers). On the card's white, no underline, 32 px with 6 px
   corners; the picked one is filled light green. The picked box's edge sits on the card's 24 px
   line (Gokul, 23 Oct 2026). */
:is(.toolbar>.subtabs,.tabbar.inner,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs){background:none!important;border-bottom:0!important;gap:4px!important}
@media (min-width:801px){.toolbar>.subtabs{margin:-14px 0 0!important;padding:12px 0 0!important}.tabbar.inner,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs{padding:12px var(--in,24px) 0!important}}
:is(.toolbar>.subtabs,.tabbar.inner,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs) :is(.tab,.stab){border:0!important;border-radius:var(--rs)!important;padding:0 12px!important;min-height:var(--ctl-sm);display:inline-flex;align-items:center;gap:6px;font-size:14px;line-height:1.2;color:var(--fg2);background:none}
:is(.toolbar>.subtabs,.tabbar.inner,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs) :is(.tab,.stab):hover{background:var(--panel);color:var(--fg0)}
:is(.toolbar>.subtabs,.tabbar.inner,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs) :is(.tab.on,.tab[aria-selected=true],.stab.on){background:var(--wash2)!important;color:var(--strong-fg)!important}
/* Counts in second tabs are small grey numbers, not bubbles (the look guide). */
:is(.toolbar>.subtabs,.tabbar.inner,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs) .tab .n{background:none!important;color:var(--fg3)!important;padding:0!important;min-width:0!important;margin-left:2px;font-size:var(--fs-xs);font-weight:500}
@media (pointer:fine){:is(.toolbar>.subtabs,.tabbar.inner,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs) :is(.tab,.stab){min-height:var(--ctl-sm)!important;font-size:14px!important}}
@media (min-width:801px){.toolbar>.rchips>.rchip{font-size:14px}}
@media (pointer:coarse){:is(.toolbar>.subtabs,.tabbar.inner,.card>.subtabs:not(.cc-tabbar),.panel>.subtabs) :is(.tab,.stab){min-height:44px!important}}
/* The sliding tab line (chrome.js, the look guide): on a laptop the picked main tab's line is one bar
   that moves; the tab's own underline steps aside. Phones keep the tab's own underline. */
.tabs.gwslid{position:relative}
.gwslide{position:absolute;left:0;top:0;height:2px;background:var(--ink);border-radius:2px;pointer-events:none;opacity:0}
.gwslide.gwslide-go{transition:transform .18s ease,width .18s ease}
@media (min-width:801px){.tabs.gwslid>:is(.on,[aria-selected=true]){border-bottom-color:transparent!important}}
@media (max-width:800px){.gwslide{display:none}}
@media (prefers-reduced-motion:reduce){.gwslide.gwslide-go{transition:none}}
/* Long pages in tabs (chrome.js, the look guide): the tab row is a slim card at the top; sections
   of the other tabs are put away. A section title is never an empty phone toolbar. */
.card.gwsplitbar{padding:0 var(--in,24px)!important;display:block}.card.gwsplitbar>.tabs{display:flex;gap:var(--tab-gap,24px);border:0;margin:0;padding:0;overflow-x:auto;scrollbar-width:none}.card.gwsplitbar>.tabs>.tab{padding:var(--tab-pad);min-height:48px;white-space:nowrap}
main .gwsplit-out{display:none!important}
html.gwviews main [data-split] .toolbar.gwtoolempty:has(h2,h3,h4){display:flex}
/* ---- Gokul's review, 23 Oct 2026: one rule per kind of problem -------------------------------- */
/* 1. Second tab rows that sit inside a tab (Drivers Applications, Documents, Incidents; Events
   Managers) take the same light green look as every other second row. */
:is(.panel,.viewpanel,[role=tabpanel])>.toolbar.tabbar{border-bottom:0;padding-top:12px;padding-bottom:4px}
:is(.panel,.viewpanel,[role=tabpanel])>.toolbar.tabbar>.tabs{gap:4px!important;margin-left:0;background:none!important;border:0!important}
:is(.panel,.viewpanel,[role=tabpanel])>.toolbar.tabbar>.tabs>.tab{border:0!important;border-radius:var(--rs)!important;padding:0 12px!important;display:inline-flex;align-items:center;gap:6px;color:var(--fg2);background:none}
:is(.panel,.viewpanel,[role=tabpanel])>.toolbar.tabbar>.tabs>.tab:hover{background:var(--panel);color:var(--fg0)}
:is(.panel,.viewpanel,[role=tabpanel])>.toolbar.tabbar>.tabs>:is(.tab.on,.tab[aria-selected=true]){background:var(--wash2)!important;color:var(--strong-fg)!important}
:is(.panel,.viewpanel,[role=tabpanel])>.toolbar.tabbar>.tabs .n{background:none!important;color:var(--fg3)!important;padding:0!important;min-width:0!important;margin-left:2px;font-size:var(--fs-xs);font-weight:500}
@media (pointer:fine){:is(.panel,.viewpanel,[role=tabpanel])>.toolbar.tabbar>.tabs>.tab{min-height:var(--ctl-sm)!important;font-size:14px!important}}
@media (pointer:coarse){:is(.panel,.viewpanel,[role=tabpanel])>.toolbar.tabbar>.tabs>.tab{min-height:44px!important}}
/* 2. Everything in a card starts 24 px in: a table never adds its own inset inside a padded box. */
.szwatch>b{display:block;padding:16px var(--in,24px) 8px}.szwatch>.tablewrap{margin:0 var(--in,24px)}.szwatch>.empty{padding:12px var(--in,24px)}
.pcreg .pc-tablewrap{padding:0;margin:0}
.card.board>.intro{padding:0 var(--in,24px)}#grid>*>tr>:first-child{padding-left:var(--in,24px)}
#p-types .cols>.col:first-child table>*>tr>:first-child{padding-left:var(--in,24px)}
main.slots .cols>.card>.rows{padding:0 0 8px}
/* Tables inside a form column line up with their heading. */
.actform .tablewrap table>*>tr>:first-child{padding-left:0}
/* Column headers are sentence case everywhere, never capitals. */
main th{text-transform:none!important;letter-spacing:0!important}
/* 3. No yellow dash on a title inside a tab or a section box: a section there is its own box. */
:is([role=tabpanel],.panel,.viewpanel,.pane,.sec,.td-sec,[data-split]) :is(h2,h3,h4)::after{display:none!important}
/* 5. One switch: the buttons sit inside their frame. */
.gwseg>.btn,.seg>.btn{height:auto!important;line-height:1.2!important}
/* 6. Search boxes keep to the guide's width. */
main .toolbar input[type=search]:not(#fts-q){flex:0 1 340px!important;max-width:380px!important;min-width:220px}
/* 7. Tiles inside a tab look like the tiles at the top of a page. */
main.corporate .cards span{background:var(--card);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow)}
/* 10. Vehicle profile: one rhythm for the three columns. */
#v-docs h4:not(:first-child),#v-drivers .tablewrap{margin-top:20px}#v-docs .controls{margin-top:8px}
/* Safety: the page name is in the top bar; the head keeps its one line. */
main.gwsafety>.sfhead h2{display:none}
.tl-titles{display:flex;flex-direction:column;gap:2px}.tl-titles .muted{font-size:var(--fs-sm)}
main.slots section.tab .tl-rule,main.slots section.tab :is(h2,h3)::after{display:none!important}
/* Reports: a word value on a tile (the period) is set at title size. */
#stats>span.words>b{font-size:var(--fs-title);line-height:1.35}
/* Admin: the left list is the page's tab row, as on every other page; the one-tab bar repeating the
   page name goes (Gokul, 23 Oct 2026). Panels keep their own second rows. */
main.admin{grid-template-columns:minmax(0,1fr)!important}
main.admin>nav.groups:not(:has(#groups>.tab:not([hidden]) ~ .tab:not([hidden]))){display:none}
main.admin>.menu{grid-column:1/-1;position:static!important;flex-direction:row!important;flex-wrap:nowrap;overflow-x:auto;gap:0 var(--tab-gap,24px);padding:0 var(--in,24px)!important;-webkit-mask-image:none!important;mask-image:none!important}
main.admin>.menu .sec{display:none}
main.admin>.menu .item{min-height:48px;padding:0!important;border-radius:0!important;border-bottom:2px solid transparent!important;background:none!important;box-shadow:none!important;font-size:var(--fs);font-weight:500;color:var(--fg2);white-space:nowrap}
main.admin>.menu .item:hover{color:var(--fg0)}
main.admin>.menu .item.on{color:var(--fg0);border-bottom-color:var(--ink)!important}
main.admin>.panels{grid-column:1/-1}
/* Review follow-ups: Public chargers' note, Transactions rows and Slots timeline title on the 24 px line. */
.pcreg .pc-intro{padding:0!important}
#p-transactions>.toolbar,#p-transactions .st-wrap>.toolbar{padding-left:var(--in,24px)!important;padding-right:var(--in,24px)!important}
.st-more{text-transform:none!important;letter-spacing:0!important;font-size:var(--fs-sm)!important;font-weight:500}
.tl-head>.tl-titles{padding-left:var(--in,24px)}.tl-head>.tl-titles>.tl-h{padding-left:0!important;background:none!important}
#adv-subs[hidden]{display:none!important}
#adv-subs{margin-bottom:16px!important}#adv-subs+.tools{padding-top:0}
/* A title that repeats its tab is hidden (chrome.js); a title bar left with only a note keeps it. */
.gwdup{display:none!important}
/* The tab row and the content under it read as one card, as on every page built in one card (Gokul,
   23 Oct 2026): Admin's tab row and its panel; a long page's tab row and the first box of the tab. */
main.admin>.menu{border-bottom-left-radius:0!important;border-bottom-right-radius:0!important;margin-bottom:-20px;box-shadow:none}
main.admin>.panels>.card.panel{border-top-left-radius:0;border-top-right-radius:0;border-top:0}
.card.gwsplitbar{border-bottom-left-radius:0;border-bottom-right-radius:0;margin-bottom:-20px;box-shadow:none}
main [data-split].gwsplit-first{border-top-left-radius:0;border-top-right-radius:0;border-top:0}
@media (max-width:800px){main.admin>.menu,.card.gwsplitbar{margin-bottom:-14px}}
/* Demand calendar: its cards are padded, so a table bleeds to the card edges and long text wraps. */
main.demandpage .card td{white-space:normal}
/* Rides: Bookings tools also opens the three planning pages that live under Rides in the menu
   (Gokul, 23 Oct 2026), after a thin line. */
.rmenu>a.rlink{color:var(--fg);text-decoration:none}
.rmenu>button+a.rlink{border-top:1px solid var(--border);margin-top:4px;padding-top:4px}
/* Slots & charging, every tab (Gokul, 23 Oct 2026; the first sweep missed Slots' link tabs): forms,
   facts and lists in a card start on the 24 px line like its title; labels in sentence case;
   card titles at the console's title size. */
main.slots .card>:is(form,dl,ul,ol,table,.inline,.facts,.groups,.rows){margin-left:var(--in,24px);margin-right:var(--in,24px)}
main.slots .card>:last-child:not(.tablewrap){margin-bottom:var(--in,24px)}
main.slots .card>h2{font-size:var(--fs-title)!important;font-weight:500!important}
main.slots :is(form.inline label,dl.facts dt){text-transform:none!important;letter-spacing:0!important;font-size:var(--fs-sm)!important}
/* Sweep 2 (every tab of every page): a title inside a card's toolbar row takes no second inset;
   an empty line inside a bled table area keeps the 24 px line; Experiments tables reach the card
   edges like every other table; sub-headings in sentence case. */
.card .toolbar>:is(h2,h3){padding:0!important;margin:0}
main h4.sh-h{text-transform:none!important;letter-spacing:0!important}
/* Tables sit inside their card with a 24 px gutter on both sides; the header band and the row lines
   stop at the gutter (Gokul, 23 Oct 2026: the Business templates look, everywhere). Inside a section
   box (.sec, .td-sec) a table still fills the box, which is its frame. Containers that already pad
   24 px (a .body, Business panels, Desks panes, padded cards) add no second gutter. */
main :where(.card,.panel,.pane,.viewpanel,#listwrap)>.tablewrap:not(.sec>.tablewrap),
main #p-types .cols>.col>.tablewrap{margin-left:var(--in,24px)!important;margin-right:var(--in,24px)!important}
main .card>.body>.tablewrap,main.corporate #panel>.tablewrap,main.demandpage .card>.tablewrap,main.exppage .card>.tablewrap,main.manage .pane>.tablewrap{margin-left:0!important;margin-right:0!important}
main :is(.tablewrap,.pc-tablewrap):not(.sec .tablewrap,.td-sec .tablewrap) table>*>tr>:first-child{padding-left:16px!important}
main :is(.tablewrap,.pc-tablewrap):not(.sec .tablewrap,.td-sec .tablewrap) table>*>tr>:last-child{padding-right:16px!important}
/* Safety: the tab row is the top row of the list card, as on Vehicles and every other page (Gokul,
   23 Oct 2026; Sai Teja's design, flagged for her review). Styles only: the markup stays hers. The
   tabs sit on the card's 24 px line, 24 px apart, with the main tabs' underline. */
main.gwsafety>.sftabs{background:var(--card);border:1px solid var(--border);border-radius:var(--r) var(--r) 0 0;padding:0 var(--in,24px);box-shadow:var(--shadow)}
main.gwsafety>.sftabs .tabs{gap:var(--tab-gap,24px)}
main.gwsafety>.sftabs .tab{padding:0!important}
main.gwsafety.issues>.sftabs{margin-bottom:-20px;box-shadow:none}
main.gwsafety.issues>section.card.list{border-top-left-radius:0;border-top-right-radius:0;border-top:1px solid var(--border)}
main.gwsafety:not(.issues)>.sftabs{border-radius:var(--r)}
/* Off route now: one card under the tabs, so the two join too; No-entry zones keeps its gap (list and map side by side). */
main.gwsafety.safety:not(:has(#szmap))>.sftabs{border-radius:var(--r) var(--r) 0 0;margin-bottom:-20px;box-shadow:none}
main.gwsafety.safety:not(:has(#szmap))>section.card{border-top-left-radius:0;border-top-right-radius:0;border-top:1px solid var(--border)}
@media (max-width:800px){main.gwsafety.issues>.sftabs{margin-bottom:-14px}}
/* The picked option of every switch (All / Mine / Unassigned, date ranges, Today / This week, Live or
   Done chips) is the light green of a picked second tab, so it stands out from the grey track
   (Gokul, 23 Oct 2026). The colour tokens stay as Michel set them; this is the picked look only. */
:is(.gwseg,.gwrange,.seg)>:is(.on,[aria-pressed=true],[aria-checked=true],[aria-selected=true],label:has(input:checked)),
:is(.gwseg,.gwrange,.seg)>:is(.on,[aria-pressed=true],[aria-checked=true],[aria-selected=true]):hover{background:var(--wash2)!important;color:var(--strong-fg)!important;box-shadow:none!important;font-weight:500}
:is(.gwseg,.gwrange,.seg){background:var(--card)!important}
/* The main tab line sits on the tab row's bottom edge on every page, as on Command Centre (Gokul,
   23 Oct 2026): it never floats above the row's padding, and it is drawn on whole pixels. */
.gwslide{top:auto!important;bottom:0}
.toolbar:has(>.tabs.gwslid){padding-top:0!important;padding-bottom:0!important}
.toolbar>.tabs.gwslid{align-self:stretch;align-items:stretch}
.tabs.gwslid>:is(.tab,a){min-height:52px;display:inline-flex;align-items:center;box-sizing:border-box}
/* Templates look for tables that sit straight in a card or pane, with no wrapper (Command Centre's
   Fleet and Ride queue, others): 24 px gutter both sides, cells 16 px in (Gokul, 23 Oct 2026). */
main :where(.card,.panel,.pane,.cc-pane,.viewpanel,#listwrap)>table:not(.sec>table){margin-left:var(--in,24px);margin-right:var(--in,24px);width:calc(100% - 2 * var(--in,24px))}
main :where(.card,.panel,.pane,.cc-pane,.viewpanel,#listwrap)>table:not(.sec>table)>*>tr>:first-child{padding-left:16px!important}
main :where(.card,.panel,.pane,.cc-pane,.viewpanel,#listwrap)>table:not(.sec>table)>*>tr>:last-child{padding-right:16px!important}
.card.board>.gridwrap{margin-left:var(--in,24px);margin-right:var(--in,24px)}#grid>*>tr>:first-child{padding-left:16px!important}
.tabs.cc-tabbar{gap:var(--tab-gap,24px)!important;padding-left:var(--in,24px)!important}.tabs.cc-tabbar>.tab{padding-left:0!important;padding-right:0!important}
/* ---- Palermo's review, 23 Oct 2026: the Must findings ------------------------------------------ */
/* P01: one header band, 40 px, 12.5 px words; the filter row under it follows. */
main th{height:40px!important;font-size:var(--fs-xs)!important}
main tr.filters td{top:40px}
/* P23 P25 P38 P43 P44 P46 P49 P51 P54 P56 P65 P66: no column hidden on a wide laptop. Words in cells
   wrap from 1280 px; ids, numbers, money, dates and row buttons stay on one line. Below 1280 cells stay on
   one line, as on main, and a table wider than its card scrolls inside it (Hima's re-check of PR 1840). */
@media (min-width:1280px){
main table :is(td,th){white-space:normal}
main table :is(td.num,th.num,td.acts,td:has(>.btn),td:has(>a:only-child)){white-space:nowrap}
main table th{overflow-wrap:normal;word-break:normal}
main table td{overflow-wrap:break-word}  /* N07: a word breaks only when it is longer than its column */
}
/* Hima's review of PR 1840: ids, links, statuses and times never split ("R-" / "000015", "GW-" / "047");
   when a table is wider than its card at a small laptop it scrolls sideways inside the card, as on main. */
@media (min-width:801px){
main table td :is(a,b,.pill,time,.id,.vin){white-space:nowrap}
main table td.st,main table td:has(>.pill:only-child){white-space:nowrap}
main :is(#listwrap,.tablewrap){overflow-x:auto}
}
/* P13: an open Bookings tool is shown as picked (light green), never as a second dark button. */
#rtools-sum.on{background:var(--wash2)!important;border-color:var(--wash2)!important;color:var(--strong-fg)!important}
/* P50: destructive buttons are a red outline, never filled. */
main .btn.danger{background:var(--card)!important;color:var(--crit)!important;border-color:var(--crit)!important}
main .btn.danger:hover{background:var(--hover)!important;filter:none}
/* ---- opsu-fix-a: shared look fixes from Palermo's review (P02 P03 P04 P05 P06 P07 P10) ---- */
/* P02: one main tab row, 48 px, on every page: the tabs fill the row, no padding above them. */
main .tabs.gwslid{padding-top:0!important;padding-bottom:0!important}
main .tabs.gwslid>:is(.tab,a){min-height:48px!important;height:48px;padding-top:0!important;padding-bottom:0!important}
@media (min-width:801px){main .tabs.gwslid>:is(.tab,a){margin-top:0!important;margin-bottom:0!important}
main.rides #listcard>.rhead{min-height:48px!important}main.rides:not(.has-detail) #listcard>.rhead>.rtools{top:6px!important}}
/* P03: switches have the one 6 px corner of every control; the options inside sit 4 px round. */
:is(.gwseg,.gwrange,.seg){border-radius:var(--rs)!important}
:is(.gwseg,.gwrange,.seg)>:is(button,.btn,label,a){border-radius:4px!important}
/* P04: a button outside a table row or a pager is the regular 36 px with 14 px words; 13 px is not one
   of the six sizes, so small buttons in tables keep 32 px but take 14 px words too. */
main .btn.small:not(:is(.gwseg,.gwrange,.seg)>*){font-size:14px!important}
@media (min-width:801px){
main .btn.small:not(table *,.pager *,:is(.gwseg,.gwrange,.seg)>*){height:var(--ctl)!important;min-height:var(--ctl)!important;line-height:calc(var(--ctl) - 2px)!important;padding-left:16px;padding-right:16px}
/* ...but a button in an even group keeps the group's rule: a long label wraps inside its cell and the row
   grows, rather than spilling over the edge at 36 px ("WhatsApp call" in the driver panel, 25 Oct 2026).
   It ties the rule above on weight and wins by coming after it: keep it below. */
main .btn-grid>.btn.small{height:auto!important;line-height:1.25!important;padding-left:10px;padding-right:10px}
/* P05: the pager reads count on the left, Previous and Next on the right, on the card's 24 px line. */
main .pager{gap:8px;padding-left:var(--in,24px)!important;padding-right:var(--in,24px)!important}
main .pager:has(>:is(button,.btn):first-child)>:not(button,.btn){order:-1;margin:0!important;flex:0 1 auto!important;text-align:left;min-width:0}
main .pager:has(>:is(button,.btn):first-child)>:is(button,.btn):first-child{margin-left:auto!important}
/* the page count stays on one line; a long note beside it wraps instead (Payments at 1024, 25 Oct 2026) */
main .pager:has(>:is(button,.btn):first-child)>[id$=pageinfo]{flex:none!important;white-space:nowrap}
main .pager:has(>:is(button,.btn):first-child)>.grow{display:none}
}
/* P01 sweep: cells are 12 px in at the sides, as the guide's table spec says (first and last 16, set
   above); the old 18 px pushed wide numbers tables past their card at 1440. */
main :is(th,td){padding-left:12px;padding-right:12px}
/* P06: menu section names and the role in the top bar read in sentence case at 12.5 px, never capitals. */
.nav .sec,.who .role,.gwmenu-group h5,.gwall-sec h5>span:last-child,.gwmenu-top b{font-size:var(--fs-xs)!important;text-transform:lowercase!important;letter-spacing:.01em!important}
.gwall-sec h5{font-size:var(--fs-xs)!important;text-transform:none!important;letter-spacing:.01em!important}
.nav .sec::first-letter,.who .role::first-letter,.gwmenu-group h5::first-letter,.gwall-sec h5>span:last-child::first-letter,.gwmenu-top b::first-letter{text-transform:uppercase}
.gwmenu-top b{display:inline-block}
/* P07: checkboxes and radios tick in the brand green, not the browser's blue (a page's own colour still wins). */
:where(input[type=checkbox],input[type=radio]){accent-color:var(--c500)}
/* P10: at night the picked switch option and the picked second tab are a clear green with white words
   (about 3.4 : 1 against the card), not a grey that hardly differs from the card. Light mode unchanged. */
:root{--pick-dk:var(--c500);--pick-dk-fg:var(--gw-white)}
:root[data-mode=dark] :is(:is(.gwseg,.gwrange,.seg)>:is(.on,[aria-pressed=true],[aria-checked=true],[aria-selected=true],label:has(input:checked)),:is(.subtabs,.rchips,.tabbar.inner .tabs,.toolbar.tabbar>.tabs,.tabs.tabstrip,#adv-subs):not(.gwslid)>:is(.on,[aria-pressed=true],[aria-selected=true]),#rtools-sum.on),
:root[data-mode=dark] :is(:is(.gwseg,.gwrange,.seg)>:is(.on,[aria-pressed=true],[aria-checked=true],[aria-selected=true]),:is(.subtabs,.rchips,.tabbar.inner .tabs,.toolbar.tabbar>.tabs,.tabs.tabstrip,#adv-subs):not(.gwslid)>:is(.on,[aria-pressed=true],[aria-selected=true])):hover{background:var(--pick-dk)!important;border-color:var(--pick-dk)!important;color:var(--pick-dk-fg)!important}
@media (prefers-color-scheme:dark){
:root[data-mode=system] :is(:is(.gwseg,.gwrange,.seg)>:is(.on,[aria-pressed=true],[aria-checked=true],[aria-selected=true],label:has(input:checked)),:is(.subtabs,.rchips,.tabbar.inner .tabs,.toolbar.tabbar>.tabs,.tabs.tabstrip,#adv-subs):not(.gwslid)>:is(.on,[aria-pressed=true],[aria-selected=true]),#rtools-sum.on),
:root[data-mode=system] :is(:is(.gwseg,.gwrange,.seg)>:is(.on,[aria-pressed=true],[aria-checked=true],[aria-selected=true]),:is(.subtabs,.rchips,.tabbar.inner .tabs,.toolbar.tabbar>.tabs,.tabs.tabstrip,#adv-subs):not(.gwslid)>:is(.on,[aria-pressed=true],[aria-selected=true])):hover{background:var(--pick-dk)!important;border-color:var(--pick-dk)!important;color:var(--pick-dk-fg)!important}
}
/* ---- end opsu-fix-a ---- */
/* ---- opsu-fix-b: Rides, Support inbox, Safety (Palermo's review, 23 Oct 2026) ---- */
/* P20: Safety keeps one page name (safetytabs.js); the page buttons sit at the right end of the tab
   row, main last. Sai Teja's design: styles and the minimum markup only (the .sfacts box moved from the
   head into the tab row). On a phone the buttons take their own line above the tabs. */
main.gwsafety>.sftabs{display:flex;align-items:center;gap:8px 16px}
main.gwsafety>.sftabs>.tabs{flex:1 1 auto;min-width:0}
main.gwsafety>.sftabs>.sfacts{display:flex;flex:none;gap:8px;margin-left:auto;align-items:center}
main.gwsafety>.sftabs>.sfacts:empty{display:none}
@media(max-width:800px){main.gwsafety>.sftabs{flex-wrap:wrap}main.gwsafety>.sftabs>.tabs{flex:1 1 100%}
  main.gwsafety>.sftabs>.sfacts{order:-1;flex:1 1 100%;flex-wrap:wrap;margin:0;padding:12px 0 4px}}
/* P19: the SOS tab uses the console's shared sizes (36 px controls on a laptop, the switch options 28 px
   inside their 36 px frame), as the Support inbox shows the same controls. The rules above stay (tests). */
@media(min-width:801px){
main.gwsafety.issues > section.card.list .btn,main.gwsafety.issues > #sos .btn,main.gwsafety>.sftabs .sfacts .btn{height:36px;min-height:36px;padding:0 16px;font-size:14px}
main.gwsafety.issues > section.card.list .gwseg>.chip{height:28px;min-height:28px;padding:2px 14px}
main.gwsafety.issues > section.card.list .toolbar.filters > .toolbar.inbox{gap:0}
main.gwsafety.issues > section.card.list :is(input[type=search],select){height:36px;min-height:36px;border:1px solid var(--edge);background-clip:border-box;box-shadow:none;border-radius:var(--rs)}
main.gwsafety.issues > section.card.list input[type=search]{border-radius:999px}
main.gwsafety.issues > section.card.list :is(input[type=search],select):focus-visible{box-shadow:0 0 0 2px var(--focus)}
}
/* P61: on a phone every SOS control is 44 px and the search row wraps, so nothing runs off the screen. */
@media(max-width:800px){
main.gwsafety.issues > section.card.list :is(.btn,.chip,input[type=search],select),main.gwsafety>.sftabs .sfacts .btn{height:44px;min-height:44px}
main.gwsafety.issues > section.card.list :is(input[type=search],select){border:1px solid var(--edge);background-clip:border-box;box-shadow:none}
main.gwsafety.issues > section.card.list .toolbar{flex-wrap:wrap;max-width:100%}
main.gwsafety.issues > section.card.list .gwtoolrow{min-width:0;max-width:100%}
main.gwsafety.issues > section.card.list .gwtoolrow input[type=search]{flex:1 1 auto!important;min-width:0!important;width:auto}
main.gwsafety>.sftabs>.sfacts .btn{flex:1 1 auto;justify-content:center}
}
/* P21: No-entry zones. Status is a dot with a ring (shared .pill), not a filled pill; the row buttons are
   the 32 px table-row size; Switch off is a red outline (.btn.danger). */
.szpage .szstate.pill{background:none;padding:0;border-radius:0;font-size:var(--fs-sm);font-weight:500;color:var(--fg);--dot:var(--c300)}
.szpage .szstate.pill.on{background:none;color:var(--fg);--dot:var(--nozone);--ring:var(--sev-crit-ring)}
@media(min-width:801px){.szpage #sztable td:last-child .btn{height:32px;min-height:32px;font-size:14px}.szpage #sztable td:last-child .btn+.btn{margin-top:8px}}
/* P22: Cars in or near a zone now starts on the card's 24 px line like everything else; its empty line
   is the grey "none". */
main.szpage .szwatch>b{padding-left:0!important;padding-right:0!important}
.szpage .szwatch #szwatch-empty{color:var(--fg3);text-align:left;padding:12px var(--in,24px);font-size:var(--fs-sm)}
/* ---- end opsu-fix-b ---- */
/* ---- Second review, 23 Oct 2026: regressions ---- */
/* N02: an icon-only button keeps its square shape; the 36 px button padding never squeezes its icon. */
main .btn:has(>svg:only-child),main .btn.mmw-step{padding-left:0!important;padding-right:0!important;width:var(--ctl);min-width:var(--ctl);justify-content:center}
main .btn:has(>svg:only-child)>svg,main .btn.mmw-step>svg{flex:none;width:16px;height:16px}
/* N03: the Overview charge filters and the Slots Charging second tabs are picked in the same night green. */
:root[data-mode=dark] :is(.cachip[aria-pressed=true],.chgsplit>button[aria-selected=true]){background:var(--pick-dk)!important;border-color:var(--pick-dk)!important;color:var(--pick-dk-fg)!important}
@media (prefers-color-scheme:dark){:root[data-mode=system] :is(.cachip[aria-pressed=true],.chgsplit>button[aria-selected=true]){background:var(--pick-dk)!important;border-color:var(--pick-dk)!important;color:var(--pick-dk-fg)!important}}
/* ---- Second review, 23 Oct 2026: the Should items ---- */
/* N10: five or more choices show as one dropdown on a laptop (chrome.js); the buttons stay for phones. */
.gwsegpick{display:none}
@media (min-width:801px){main .gwsegpicked{display:none!important}main .gwsegpick{display:inline-block;width:auto;min-width:150px;height:var(--ctl)}}
/* N10: Marketing metrics' period and Export CSV sit in the card, above its tab row. */
main.mmpage>.mmbar{background:var(--card);border:1px solid var(--border);border-bottom:0;border-radius:var(--r) var(--r) 0 0;padding:12px var(--in,24px);margin-bottom:-20px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
main.mmpage>.mmbar+.card.gwsplitbar{border-top-left-radius:0;border-top-right-radius:0}
/* N04: on a phone a switch is 44 px tall like every other control. */
@media (max-width:800px){main :is(.gwseg,.gwrange,.seg){padding:0!important;min-height:44px;box-sizing:content-box}main :is(.gwseg,.gwrange,.seg)>*{min-height:44px!important}}
/* N08: the second line under a column name is 12.5 px, not 11.5. */
#tx .st-th-sub{font-size:var(--fs-xs)!important}
/* N11: custom date boxes are 36 px like the rest of the row. */
.customrange input[type=date]{height:var(--ctl);font-size:var(--fs-sm)}
/* P08: Marketing overview tiles put the label on top and the number under it. */
.ov-money .cell{display:flex;flex-direction:column}.ov-money .cell>span{order:-1;font-size:var(--fs-sm);color:var(--fg2)}.ov-money .cell>b{font-size:var(--fs-kpi)!important;font-weight:500;color:var(--fg0);line-height:1.2}
/* P62: on a phone the + button never covers the help text at the end of Transactions. */
@media (max-width:800px){#p-transactions{padding-bottom:88px}}
/* N14: the Admin group row (My account) uses the shared tab row: 24 px line, 24 px apart. */
main.admin>nav.groups{padding:0 var(--in,24px)!important}main.admin>nav.groups .tabs{gap:var(--tab-gap,24px)!important}main.admin>nav.groups .tab{padding:0!important;min-height:48px}
main.admin>nav.groups:not([style*="none"])+.menu{border-top-left-radius:0;border-top-right-radius:0}
/* Bookings tools lines up with Refresh, Export CSV, Import and New booking (Gokul, 23 Oct 2026). */
@media(min-width:801px){.rhead .rtools,.rtools{margin-bottom:0!important;margin-top:0!important;align-self:center}}
main.rides:not(.has-detail) #listcard>.rhead>.rtools{top:10px!important}
/* Hima's review of PR 1840: a picked option, second tab or chip has a 1 px green edge, so it shows
   against the white card (3:1), not only its light green fill. A main tab row (sliding line) never gets the edge,
   even when it also carries the subtabs class (Command Centre: Fleet, Ride queue). */
:is(.gwseg,.gwrange,.seg)>:is(.on,[aria-pressed=true],[aria-checked=true],[aria-selected=true],label:has(input:checked)),
:is(.subtabs:not(.gwslid):not(.cc-tabbar),.tabbar.inner,#set-tabs,#adv-subs,.chgsplit,.rchips) :is(.tab.on,.stab.on,.tab[aria-selected=true],[aria-pressed=true],button[aria-selected=true]),
#rtools-sum.on,.rchip[aria-pressed=true]{box-shadow:inset 0 0 0 1px var(--c500)!important}
/* Hima's review of PR 1840, small fixes: the sort arrow keeps a gap from its heading; a pager's count
   keeps a gap from its button; Dispatch settings' group tabs fade at the right edge when more slide in. */
th .dir{margin-left:4px}
.pager>span+.btn{margin-left:12px}
#set-tabs.more{-webkit-mask-image:linear-gradient(to right,black calc(100% - 40px),transparent);mask-image:linear-gradient(to right,black calc(100% - 40px),transparent)}
/* Hima's re-check of PR 1840: a tab the page hides for a role (hidden) stays hidden, whatever the tab row's
   own display rule says (Payments > Advanced for an operator or a viewer). */
main :is(.tab,.stab,[role=tab])[hidden]{display:none!important}
/* Hima's re-check of PR 1840: below 1280 px a table that cannot fit its card keeps its natural width and
   scrolls inside it, instead of squeezing its rows taller (Admin audit, the Command Centre ride queue). */
@media (min-width:801px) and (max-width:1279px){
main :where(.card,.panel,.pane,.cc-pane,.viewpanel,#listwrap)>table:not(.sec>table){width:auto;min-width:calc(100% - 2 * var(--in,24px))}
main #a-table,main #cc-rides{min-width:max-content}
main .cc-pane:has(>#cc-rides){overflow-x:auto}
}
