/* ---------- game ---------- */
#game{position:absolute;inset:0;display:none}
#game.on{display:block}
/* ---------- the opening's shot ----------
   The game runs behind the opening's letterbox with all chrome hidden: every
   child of #game but the stage, and inside the stage everything but the
   picture. The vignette stays. Chained :not() for older browsers. */
body.cinema #game > :not(#stage){display:none!important}
body.cinema #stage > :not(#view):not(#vignette){display:none!important}
/* Fixed, and as tall as the whole screen (R.fitViewport() works out
   --full-h), not just the part #app is pinned to: the world runs on under a
   see-through toolbar or a home-screen app's short report of its own height. */
#stage{position:fixed;left:0;top:0;width:100%;height:var(--full-h,100%);overflow:hidden;background:#05070b}
@supports (height:100lvh){ #stage{height:max(var(--full-h,100%),100lvh)} }
/* In a home-screen app, run it on past the home bar as well: a few pixels
   drawn off the glass cost nothing (the camera sits half of them low), and a
   short report no longer leaves a bar. */
@media (display-mode: standalone){
  #stage{height:calc(max(var(--full-h,100%),100lvh) + env(safe-area-inset-bottom))}
}
/* No CSS blur: a filter over a canvas re-rasterises every frame. The blur is
   baked once (R.freeze()). */
/* touch-action:none: double-tap zoom, pinch and pull-to-refresh would leave
   you playing a magnified corner. */
canvas#view{position:absolute;inset:0;width:100%;height:100%;display:block;image-rendering:auto;
  touch-action:none}
#vignette{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 45%,transparent 45%,rgba(0,0,0,.62) 100%)}
#flash{position:absolute;inset:0;pointer-events:none;background:#fff;opacity:0;transition:opacity .3s}
/* The curtain across a level change, above the world and below every panel.
   Its 190ms is what Levels.transition() waits; they must agree. */
#fade{position:absolute;inset:0;pointer-events:none;background:#05070c;opacity:0;
  transition:opacity .19s ease;z-index:4}
#fade.on{opacity:1}

/* HUD */
.hud{position:absolute;pointer-events:none;z-index:5}
/* Softer than panels, since it sits over the office all shift. */
.hud .card{pointer-events:auto;position:relative;background:linear-gradient(180deg,rgba(24,31,43,.82),rgba(17,22,31,.86));
  border:1px solid var(--line-soft);border-radius:var(--radius);backdrop-filter:blur(9px);
  box-shadow:0 10px 26px -18px #000,inset 0 1px 0 rgba(255,255,255,.04)}
/* The phone bar's wrapper: zero height and click-through on desktop;
   responsive.css makes it the bar. */
#hudTop{position:absolute;top:0;left:0;right:0;z-index:5;pointer-events:none}
#shiftBar{display:none}
#hudTL{top:12px;left:12px;width:236px}
#hudTL .card{padding:10px 12px;transition:box-shadow .3s,border-color .3s}
#hudTL.low .card{border-color:rgba(255,95,86,.65);box-shadow:0 0 30px -8px rgba(255,95,86,.6)}
#hudTL.low .who-name{color:var(--bad)}
/* min-width:0 so name and rank clip rather than widen the card. */
.who-row{display:flex;align-items:center;gap:9px}
.who-row>div{min-width:0}
/* A lanyard photo in a ring, which turns alert-coloured with the card when
   patience is low. */
.who-face{font-size:26px;line-height:1;flex:0 0 auto;
  padding:5px 7px;border-radius:11px;border:1px solid var(--line-soft);
  background:radial-gradient(circle at 50% 35%,rgba(255,111,145,.16),rgba(255,111,145,.02));
  transition:border-color .3s,background .3s}
#hudTL.low .who-face{border-color:rgba(255,95,86,.5);
  background:radial-gradient(circle at 50% 35%,rgba(255,95,86,.24),rgba(255,95,86,.03))}
.who-name{font-weight:700;font-size:15px;line-height:1.1}
.who-rank{font-family:var(--mono);font-size:10px;letter-spacing:.12em;color:var(--hold);text-transform:uppercase}
.bar{height:9px;background:#0b0f16;border:1px solid var(--line-soft);border-radius:6px;overflow:hidden;position:relative;
  box-shadow:inset 0 1px 3px rgba(0,0,0,.5)}
.bar>i{display:block;height:100%;width:50%;border-radius:5px;transition:width .3s ease}
.bar-row{display:flex;align-items:center;gap:7px;margin-top:7px;font-family:var(--mono);font-size:10px;color:var(--dim)}
.bar-row .lbl{width:16px;text-align:center;font-size:12px;opacity:.85}
.bar-row .bar{flex:1}
.bar-row .val{width:52px;text-align:right;color:var(--text)}
.bar-row .val i{font-style:normal;color:var(--dim)}
#hudTR{top:12px;right:12px;width:250px;text-align:right}
#hudTR .card{padding:10px 12px}
.money-row{display:flex;justify-content:flex-end;gap:14px;font-family:var(--mono);font-size:13px}
.money-row b{color:var(--hold);font-weight:700}
/* Wanted (engine/law.js): five stars, the lit ones gold, flashing red and blue
   while an officer has eyes on you. Never faded with the quiet HUD. */
.wanted{margin-top:3px;font-size:17px;letter-spacing:2px;line-height:1;color:#ffd34d;text-shadow:0 1px 2px rgba(0,0,0,.6)}
.wanted.seen{animation:wantedSeen .5s steps(1) infinite}
@keyframes wantedSeen{0%{color:#ff4d4d}50%{color:#4da3ff}}
body.hud-quiet #hudTR:has(.wanted:not([hidden])) .card{opacity:1}
.clock{font-family:var(--mono);font-size:22px;letter-spacing:.06em;color:var(--text)}
.clock small{font-size:10px;color:var(--dim);letter-spacing:.2em;display:block}
/* The weather line, quieter than the queue. */
.sky{margin-top:5px;display:flex;align-items:center;justify-content:flex-end;gap:6px;
  font-family:var(--mono);font-size:10px;color:var(--dim);letter-spacing:.12em;
  text-transform:uppercase;white-space:nowrap;overflow:hidden}
.queue{margin-top:7px;display:flex;align-items:center;justify-content:flex-end;gap:7px;
  font-family:var(--mono);font-size:11px;color:var(--hold);letter-spacing:.06em}
.queue[hidden]{display:none}
.qdot{width:7px;height:7px;border-radius:50%;background:var(--hold);
  box-shadow:0 0 8px var(--hold);animation:qpulse 1.1s ease-in-out infinite}
@keyframes qpulse{50%{opacity:.25;transform:scale(.7)}}
@media(prefers-reduced-motion:reduce){.qdot{animation:none}}
/* The written queue: same row, blue and still (an email waits), unlike the
   amber pulse of a ringing bell. */
.queue.written{color:var(--brand);margin-top:3px}
.queue.written .qdot{background:var(--brand);box-shadow:0 0 8px var(--brand);animation:none}

/* ---------- the job tracker ----------
   The objective and open jobs under the right-hand card. Jobs fold to titles
   and the box to its header, which names the tracked job. The list scrolls;
   objective and header never do. */
#tracker{top:calc(12px + var(--hudr-h,104px) + 8px);right:12px;width:250px;
  display:flex;flex-direction:column;
  max-height:calc(100% - var(--hudr-h,104px) - 250px)}
#tracker .card{min-height:0;display:flex;flex-direction:column;overflow:hidden;padding:0}
.tk-head{display:flex;align-items:center;gap:6px;padding:8px 10px;
  font-family:var(--mono);font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim)}
.tk-lbl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Folded, the header shows the tracked job's name in readable type. */
#tracker.folded .tk-lbl{color:var(--good);font-family:var(--ui);font-size:12px;
  letter-spacing:.01em;text-transform:none}
#tracker.folded .tk-body,#tracker.folded #tkTitles{display:none}
#tracker.folded #tkFold{transform:rotate(-90deg)}
/* No count beside a job name. */
#tracker.folded .tk-n{display:none}
.tk-n{flex:0 0 auto;color:var(--hold);letter-spacing:.06em}
.tk-n:empty{display:none}
.tk-b{flex:0 0 auto;width:22px;height:22px;line-height:1;border-radius:6px;cursor:pointer;
  background:rgba(255,255,255,.04);border:1px solid var(--line-soft);color:var(--dim);font-size:11px;
  display:flex;align-items:center;justify-content:center;pointer-events:auto;transition:.14s}
.tk-b:hover{color:var(--text);border-color:var(--brand);background:rgba(255,111,145,.12)}
.tk-b:focus-visible{outline:2px solid var(--hold);outline-offset:2px}
#tracker.titles #tkTitles{color:var(--brand);border-color:var(--brand)}
.tk-body{min-height:0;display:flex;flex-direction:column;overflow:hidden}
.tk-obj{padding:0 10px 9px;font-size:12px;line-height:1.35;color:var(--text)}
/* Feathered at the bottom; padding lets the last job clear it. */
.tk-list{min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none;
  border-top:1px dashed var(--line);padding:4px 4px 14px;
  -webkit-mask-image:linear-gradient(180deg,#000 calc(100% - 14px),transparent 100%);
  mask-image:linear-gradient(180deg,#000 calc(100% - 14px),transparent 100%)}
.tk-list::-webkit-scrollbar{width:0}
.tk-list:empty{display:none}
/* A job is a title row you can fold and a pin you can track it with. Two
   buttons side by side rather than one inside the other, which is not a thing
   a button may contain. */
.tk-q{display:flex;align-items:flex-start;gap:4px;border-radius:9px;padding:1px;
  border:1px solid transparent}
.tk-q+.tk-q{margin-top:2px}
.tk-q.on{border-color:rgba(90,212,138,.45);background:rgba(90,212,138,.08)}
.tk-title{flex:1;min-width:0;text-align:left;cursor:pointer;pointer-events:auto;
  background:none;border:0;padding:5px 6px;border-radius:8px;font-family:inherit}
.tk-title:hover{background:rgba(255,255,255,.05)}
.tk-title:focus-visible{outline:2px solid var(--hold);outline-offset:-2px}
.tk-nm{display:flex;gap:6px;align-items:baseline;font-size:12px;color:var(--text)}
.tk-nm b{flex:1;min-width:0;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tk-nm i{flex:0 0 auto;font-style:normal;font-family:var(--mono);font-size:9px;color:var(--dim);letter-spacing:.06em}
.tk-q.on .tk-nm b{color:var(--good)}
/* The current step, capped at two lines (full text in the Jobs panel). */
.tk-step{margin-top:3px;font-size:11px;line-height:1.35;color:var(--dim);
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
#tracker.titles .tk-step,.tk-q.shut .tk-step{display:none}
/* The pin is a solid chip when tracked, so which job owns the compass is
   obvious. */
.tk-pin{flex:0 0 auto;width:26px;align-self:stretch;min-height:26px;cursor:pointer;pointer-events:auto;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.04);border:1px solid transparent;border-radius:9px;
  font-size:12px;opacity:.62;filter:grayscale(.4);
  transition:opacity .15s,background .15s,border-color .15s,transform .09s,filter .15s}
.tk-pin:hover{opacity:1;filter:none;background:rgba(255,255,255,.09)}
.tk-pin:active{transform:scale(.88)}
.tk-pin:focus-visible{outline:2px solid var(--hold);outline-offset:-2px}
.tk-q.on .tk-pin{opacity:1;filter:none;background:var(--good);border-color:var(--good);
  box-shadow:0 0 0 3px rgba(90,212,138,.2)}
.tk-title:active{background:rgba(255,255,255,.08)}
.tk-b:active{transform:scale(.9)}
@media(prefers-reduced-motion:reduce){.tk-pin:active,.tk-b:active{transform:none}}
.tk-empty{padding:8px 10px;font-size:11px;color:var(--dim)}
#minimapWrap{position:absolute;right:12px;bottom:96px;z-index:5}
/* The minimap is a button that opens the map, borderless. */
#minimapBtn{display:block;padding:0;border:0;background:none;cursor:pointer;line-height:0;
  border-radius:8px;pointer-events:auto}
#minimapBtn:hover #minimap,#minimapBtn:focus-visible #minimap{border-color:var(--brand)}
#minimapBtn:focus-visible{outline:2px solid var(--brand);outline-offset:3px}
#minimapBtn:active{transform:scale(.98)}
@media(prefers-reduced-motion:reduce){#minimapBtn:active{transform:none}}
#minimap{display:block;border-radius:8px;border:1px solid var(--line);background:rgba(11,15,22,.85);
  transition:border-color .14s}
#hudBottom{left:0;right:0;bottom:12px;display:flex;flex-direction:column;align-items:center;gap:8px}
/* ---- the gun readout ----
   One line above the prompt; `hidden` most of the shift, taking no space. */
/* `display:flex` beats the `hidden` attribute's own `display:none`, which is
   how an empty pill ends up sitting over the office for the whole shift. */
#gunHud[hidden]{display:none}
#gunHud{display:flex;align-items:center;gap:8px;pointer-events:none;
  background:rgba(21,27,37,.9);border:1px solid var(--line-soft);border-radius:999px;
  padding:5px 12px;font-family:var(--mono);font-size:11px;color:var(--dim)}
.gh-e{font-size:13px;line-height:1}
.gh-n{color:var(--text)}
.gh-a{letter-spacing:.12em;color:var(--good)}
.gh-a.rl{color:var(--hold);letter-spacing:.04em}
#keyhints{display:flex;gap:6px;flex-wrap:wrap;justify-content:center;pointer-events:auto}
#keyhints button{display:inline-flex;align-items:center;gap:5px;
  background:rgba(21,27,37,.72);border:1px solid var(--line-soft);border-radius:7px;
  padding:5px 9px;font-size:11px;color:var(--dim);cursor:pointer;font-family:var(--mono);transition:.14s}
#keyhints button:hover{color:var(--text);border-color:var(--brand);background:rgba(255,111,145,.1)}
.kh-i{font-size:12px;line-height:1;opacity:.8}
/* A new place's name, once, high and quiet: clear of the player, and under
   the alerts, which have the top. */
#zoneName{position:absolute;top:22%;left:50%;transform:translate(-50%,-50%);font-family:var(--mono);
  font-size:clamp(14px,2.2vw,20px);letter-spacing:.35em;text-transform:uppercase;color:#fff;opacity:0;pointer-events:none;
  text-shadow:0 2px 14px rgba(0,0,0,.85);z-index:4;white-space:nowrap}
#zoneName.show{animation:zoneFade 2.4s ease forwards}
@keyframes zoneFade{0%{opacity:0;letter-spacing:.5em}20%{opacity:.8;letter-spacing:.35em}
  70%{opacity:.8}100%{opacity:0;letter-spacing:.3em}}

/* Notifications live in css/comms.css: an alert that points into a record, and
   the record. The band is the bottom of the stack: HUD (5), controls (6),
   dialogue (20), the call (25), panels and console (26) and the exit
   interview (28) all cover it. */
/* The cab's meter and the driver's talk (engine/cabs.js): over the bottom of the screen while you ride. */
.cab-bar{position:fixed;left:50%;bottom:calc(86px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);z-index:40;
  display:flex;flex-direction:column;gap:6px;width:min(640px,calc(100vw - 32px));
  padding:10px 12px;border-radius:14px;background:rgba(18,22,32,.88);border:1px solid rgba(255,214,90,.45);
  box-shadow:0 6px 20px rgba(0,0,0,.35);font-family:var(--ui);color:#fff3c4}
.cab-bar[hidden]{display:none}
.cab-talk{font-size:15px;line-height:1.4;color:#f6efd8;min-height:2.8em}
.cab-talk b{color:#ffd65a;margin-right:6px}
.cab-face{float:left;width:56px;height:56px;margin:0 10px 0 0;border-radius:50%;overflow:hidden;
  background:rgba(255,214,90,.14);border:1px solid rgba(255,214,90,.45)}
.cab-face:empty{display:none}
.cab-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}
.cab-meter{flex:1;font-weight:700;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.cab-bar .btn{padding:6px 10px;font-size:13px}
body.cinema .cab-bar{display:none}
/* Your crew (engine/fight.js): how many are with you and their orders. */
.crew-chip{display:block;margin:4px 0 0 auto;padding:2px 8px;border-radius:999px;border:1px solid rgba(159,224,255,.35);background:rgba(14,22,36,.55);color:#9fe0ff;font:600 11px var(--mono);cursor:pointer;pointer-events:auto}
.crew-chip[hidden]{display:none}
body.hud-quiet #hudTR:has(.crew-chip:not([hidden])) .card{opacity:1}
