/* The account hub: a first-person 3D world (js/world/) with a thin DOM layer on top.
   The canvas is decoration plus input. Everything readable lives in DOM "documents" that
   slide in beside the object being inspected (a bottom sheet on phones), and in a keyboard
   strip of the things in the car. No floating icons, markers or tooltips over the world. */
/* Hub mode: while the car is shown (js/world/hub.js sets it), the storefront header and footer
   step aside and the car fills the screen. This file is only loaded by account.html. */
.hub-mode .site-header, .hub-mode .site-footer, .hub-mode .skip-link { display: none; }
.hub {
  /* --hub-line: the world's ink (js/world/style.js INK): every sticker, slip and card on top of
     the car gets the same outline and hard shadow as the things drawn in it */
  --hub-paper: #ece4cf; --hub-ink: #1d1a14; --hub-accent: #b0281c; --hub-dim: #4f4739; --hub-line: #17110f; --hub-bone: #f0e2bf;
  background: #07070b; color: var(--ink); height: 100svh; min-height: 30rem; overflow: hidden; position: relative;
}
.hub:has([data-cockpit-content][hidden]) { height: auto; min-height: 0; padding: 6rem var(--gutter) 3rem; }
.hub__content { inset: 0; position: absolute; }
.hub__content[hidden] { display: none; }

/* ---------- the world ---------- */
.hub__viewport { cursor: default; inset: 0; position: absolute; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.hub__canvas { display: block; height: 100%; width: 100%; }
/* A night-blue vignette: a dark car. Static, never animated. No film grain: the world is flat
   colour and drawn marks (js/world/style.js), not camera noise. */
.hub__viewport::after {
  background: radial-gradient(ellipse 80% 75% at 50% 46%, transparent 62%, rgba(10, 10, 32, .2) 86%, rgba(6, 6, 20, .45) 100%);
  content: ''; inset: 0; pointer-events: none; position: absolute;
}
.hub__loading { color: var(--muted); font-size: .7rem; font-weight: 900; inset: auto 0 45% 0; letter-spacing: .2em; position: absolute; text-align: center; }
.hub:not([data-hub-state="loading"]) .hub__loading { display: none; }
.hub[data-hub-state="loading"] .hub__loading { animation: hub-flicker 1.1s steps(2, end) infinite; }
@keyframes hub-flicker { 50% { opacity: .35; } }

/* ---------- HUD: who you are, and the way out ---------- */
.hub__hud { align-items: flex-start; display: flex; gap: 1rem; justify-content: space-between; left: 0; padding: clamp(.75rem, 2vw, 1.25rem) var(--gutter); pointer-events: none; position: absolute; right: 0; top: 0; z-index: 3; background: linear-gradient(rgba(5, 4, 3, .72), rgba(5, 4, 3, 0)); }
.hub__hud > * { pointer-events: auto; }
.hub__id h1 { color: var(--ink); font-size: clamp(1rem, 2vw, 1.35rem); font-weight: 900; letter-spacing: -.02em; line-height: 1; margin-top: .2rem; }
.hub__id h1 em { color: var(--orange); font-style: normal; }
/* The title takes programmatic focus on sign-in (account.js) so screen readers start here;
   it is not a control, so it never draws a focus box over the world. */
.hub__id h1:focus, .hub__id h1:focus-visible { outline: none; }
.hub__email { color: var(--muted); font-size: .7rem; margin-top: .25rem; overflow-wrap: anywhere; }
.hub__controls { align-items: center; display: flex; gap: .35rem; }
/* everything behind one MENU: a dark glass button; it opens a small panel under it (account.js) */
.hub__exit { align-items: center; backdrop-filter: blur(4px); background: rgba(14, 11, 9, .78); border: 1px solid rgba(240, 226, 191, .34); color: var(--hub-bone); display: inline-flex; font-size: .64rem; font-weight: 800; gap: .45rem; justify-content: center; letter-spacing: .12em; line-height: 1; min-height: 2.5rem; padding: .5rem .8rem; text-decoration: none; text-transform: uppercase; transition: background 160ms ease, border-color 160ms ease, color 160ms ease; white-space: nowrap; }
.hub__exit:hover, .hub__exit:focus-visible, .hub__menu-toggle[aria-expanded="true"] { background: var(--hub-bone); border-color: var(--hub-bone); color: var(--hub-line); }
.hub__exit:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.hub__ctl-icon, .hub__sound-icon { flex: none; height: 1rem; width: 1rem; }
.hub__clear { border-color: rgba(232, 160, 96, .7); color: #f0c49a; } /* only there while the car looks altered (outside the menu: it must be one tap) */
.hub__clear[hidden] { display: none; }
@media (pointer: coarse) { .hub__exit { min-height: 2.75rem; } }
.hub__menu { position: relative; }
.hub__hud:has(.hub__menu-panel:not([hidden])) { z-index: 20; } /* the open panel sits over the driving layers */
.hub__menu-panel { animation: hub-menu-in 140ms ease-out; backdrop-filter: blur(6px); background: rgba(14, 11, 9, .95); border: 1px solid rgba(240, 226, 191, .3); box-shadow: 0 14px 30px rgba(0, 0, 0, .5); display: flex; flex-direction: column; min-width: 13.5rem; padding: .35rem; position: absolute; right: 0; top: calc(100% + .4rem); }
.hub__menu-panel[hidden] { display: none; }
.hub__menu-item { align-items: center; background: none; border: 0; color: var(--hub-bone); cursor: pointer; display: flex; font: inherit; font-size: .66rem; font-weight: 800; gap: .75rem; letter-spacing: .12em; line-height: 1; min-height: 2.75rem; padding: .5rem .75rem; text-align: left; text-decoration: none; text-transform: uppercase; width: 100%; }
.hub__menu-item[hidden] { display: none; }
.hub__menu-item:hover, .hub__menu-item:focus-visible { background: rgba(240, 226, 191, .12); outline: none; }
.hub__menu-item:focus-visible { box-shadow: inset 0 0 0 2px var(--orange); }
.hub__menu-item [data-hub-sound-state] { color: var(--orange); margin-left: auto; }
.hub__signout { border-top: 1px solid rgba(240, 226, 191, .18); color: var(--orange); margin-top: .3rem; }
/* sound: a small toggle, never a gate; the icon and the word both say which way it is */
.hub__sound[aria-pressed="true"] .hub__sound-mute, .hub__sound[aria-pressed="false"] .hub__sound-waves { display: none; }
.hub__sound[aria-pressed="false"] [data-hub-sound-state] { color: rgba(240, 226, 191, .55); }
@keyframes hub-menu-in { from { opacity: 0; transform: translateY(-.3rem); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .hub__menu-panel { animation: none; } }

/* ---------- Sign out asks first: a small card in the cockpit's paper and ink ---------- */
.hub__confirm { background: var(--hub-paper); border: 2px solid var(--hub-line); box-shadow: 6px 6px 0 var(--hub-line); color: var(--hub-ink); margin: auto; max-width: calc(100vw - 2rem); padding: 1.25rem 1.25rem 1.1rem; width: 24rem; }
.hub__confirm[hidden] { display: none; }
.hub__confirm::backdrop { backdrop-filter: blur(2px); background: rgba(5, 4, 3, .62); }
.hub__confirm-kicker { color: var(--hub-accent); font-size: .6rem; font-weight: 800; letter-spacing: .16em; margin: 0 0 .45rem; text-transform: uppercase; }
.hub__confirm-title { font-size: 1.35rem; font-weight: 900; letter-spacing: -.02em; line-height: 1.05; margin: 0 0 .5rem; text-transform: uppercase; }
.hub__confirm-text { color: var(--hub-dim); font-size: .8rem; line-height: 1.4; margin: 0 0 1.1rem; }
.hub__confirm-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.hub__confirm-actions button { border: 2px solid var(--hub-line); cursor: pointer; flex: 1 1 8rem; font: inherit; font-size: .66rem; font-weight: 800; letter-spacing: .12em; min-height: 2.75rem; padding: .6rem .8rem; text-transform: uppercase; white-space: nowrap; }
.hub__confirm-stay { background: var(--hub-line); color: var(--hub-bone); }
.hub__confirm-leave { background: var(--orange); color: var(--hub-line); }
.hub__confirm-actions button:hover { box-shadow: 3px 3px 0 var(--hub-line); transform: translate(-1px, -1px); }
.hub__confirm-actions button:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; }
.hub__confirm-leave:focus-visible { outline-color: var(--hub-line); }
.hub .cockpit__data-error { position: relative; z-index: 3; }

/* ---------- keyboard: the things in the car ---------- */
.hub__sr-only, .hub__things:not(:focus-within) { border: 0; clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; white-space: nowrap; width: 1px; }
.hub__things:focus-within { bottom: clamp(.75rem, 2vw, 1.25rem); display: grid; gap: .4rem; justify-items: start; left: var(--gutter); max-width: min(30rem, 70%); position: absolute; z-index: 4; }
/* Only the focused thing shows, like a game's interact prompt; the rest stay in the tab order. */
.hub__things:focus-within .hub__thing:not(:focus) { clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; }
.hub__things-help { color: var(--bone); flex-basis: 100%; font-size: .6rem; font-weight: 900; letter-spacing: .16em; text-shadow: 0 1px 2px #000; }
.hub__thing { background: rgba(10, 9, 8, .72); border: 1px solid rgba(215, 208, 193, .3); color: var(--muted); font-size: .7rem; font-weight: 800; letter-spacing: .08em; min-height: 2.5rem; padding: .45rem .75rem; text-align: left; }
.hub__thing:focus-visible { background: var(--hub-paper); border-color: var(--hub-paper); color: var(--hub-ink); outline: 3px solid var(--orange); outline-offset: 2px; }

/* ---------- captions (radio, intercom, horn) ---------- */
/* a comic caption box */
.hub__subtitle { background: var(--hub-bone); border: 2px solid var(--hub-line); bottom: clamp(4.5rem, 12vh, 7rem); box-shadow: 4px 4px 0 var(--hub-line); color: var(--hub-line); font-family: 'Courier New', monospace; font-size: clamp(.8rem, 1.4vw, .95rem); font-weight: 700; left: 50%; max-width: min(36rem, 86vw); opacity: 0; padding: .45rem .8rem; pointer-events: none; position: absolute; text-align: center; transform: translate(-50%, .4rem); transition: opacity .2s, transform .2s; z-index: 3; }
.hub__subtitle.is-on { opacity: 1; transform: translate(-50%, 0); }

/* ---------- supplements: small, physical, pinned beside the inspected object ----------
   The object carries the numbers. world.js places each supplement next to it on screen
   (--doc-x / --doc-y; below it on tall screens). Each one is made of its own stuff. */
.hub__docs { pointer-events: none; position: absolute; inset: 0; z-index: 2; }
.hub-doc[hidden] { display: none; }
.hub-doc {
  --doc-x: 60%; --doc-y: 30%;
  background: var(--hub-paper); box-shadow: 0 0 0 2.5px var(--hub-line), .5rem .6rem 0 rgba(10, 8, 22, .82); color: var(--hub-ink);
  display: grid; gap: .45rem; left: var(--doc-x); max-height: min(70vh, 34rem); opacity: 0; overflow: auto; overscroll-behavior: contain;
  padding: .9rem 1rem 1rem; pointer-events: auto; position: absolute; top: var(--doc-y); width: min(19rem, 34vw);
  transform: scale(.86) rotate(var(--doc-tilt, 1deg)); transform-origin: var(--doc-origin, 0 50%);
  transition: opacity .2s ease .3s, transform .5s cubic-bezier(.3, 1.45, .5, 1) .25s; /* it pops, a little too far */
}
.hub-doc.is-open { opacity: 1; transform: scale(1) rotate(var(--doc-tilt, 1deg)); }
.hub-doc__back { border-bottom: 2px solid currentColor; color: var(--hub-ink); font-size: .6rem; font-weight: 900; justify-self: start; letter-spacing: .14em; min-height: 2.25rem; padding: .3rem 0; }
.hub-doc__back:focus-visible, .hub-doc__action:focus-visible, .hub-doc :is(button, [tabindex="0"]):focus-visible { outline: 3px solid var(--hub-ink); outline-offset: 3px; }
.hub-doc__title { color: var(--hub-ink); font-size: clamp(1.05rem, 1.7vw, 1.35rem); font-weight: 900; letter-spacing: -.02em; line-height: 1; }
.hub-doc__title:focus { outline: none; }
.hub-doc__code { font-family: 'Courier New', monospace; font-size: clamp(1.6rem, 3vw, 2.2rem); font-weight: 900; letter-spacing: .04em; line-height: 1; overflow-wrap: anywhere; user-select: all; }
.hub-doc__status, .hub-doc__note, .hub-doc small { color: var(--hub-dim); font-size: .72rem; font-weight: 700; line-height: 1.4; }
.hub-doc__line { border-top: 1px dashed rgba(0, 0, 0, .35); display: grid; gap: .1rem .75rem; grid-template-columns: 1fr auto; padding-top: .4rem; }
.hub-doc__line h3, .hub-doc__slots h3, .hub-doc__activity h3 { font-size: .64rem; font-weight: 900; letter-spacing: .1em; }
.hub-doc__line strong { font-family: 'Courier New', monospace; font-size: 1.2rem; font-weight: 900; grid-row: span 2; text-align: right; }
.hub-doc__notes { display: grid; gap: .3rem; }
.hub-doc__notes small { font-size: .66rem; }
.hub-doc__stamp { border: 3px solid var(--hub-accent); border-radius: .25rem; color: var(--hub-accent); font-size: .8rem; font-weight: 900; justify-self: end; letter-spacing: .08em; padding: .2rem .45rem; transform: rotate(-6deg); }
.hub-doc__action { background: var(--hub-ink); box-shadow: 3px 3px 0 rgba(0, 0, 0, .35); color: var(--hub-paper); font-size: .7rem; font-weight: 900; letter-spacing: .16em; min-height: 2.75rem; padding: .6rem 1rem; }
.hub-doc__activity { display: grid; gap: .25rem; }
.hub-doc__activity ul { display: grid; gap: .15rem; list-style: none; margin: 0; padding: 0; font-family: 'Courier New', monospace; font-size: .78rem; }
.hub-doc__activity li { display: flex; gap: .75rem; justify-content: space-between; }
.hub-doc__slots { display: grid; gap: .3rem; }
.cockpit__slot-buckets { list-style: none; margin: 0 0 .5rem; max-height: 14rem; overflow: auto; padding: 0; }
.cockpit__slot-buckets li { border-top: 1px solid rgba(0, 0, 0, .25); font-family: 'Courier New', monospace; font-size: .74rem; font-weight: 700; line-height: 1.45; overflow-wrap: anywhere; padding: .3rem 0; }
.cockpit__warning { font-family: 'Courier New', monospace; font-size: .7rem; font-weight: 700; }
.cockpit__warning::before { background: #6d3a20; border: 1px solid rgba(0, 0, 0, .5); border-radius: 50%; content: ''; display: inline-block; height: .5rem; margin-right: .4rem; width: .5rem; }
.cockpit__warning--on::before { background: #3fe85a; box-shadow: 0 0 6px #3fe85a; }
.cockpit__warning--dim { opacity: .7; }

/* the key fob's tag: an orange motel tag, punched, stamped */
.hub-doc--fob {
  --hub-paper: #e7782b; --hub-ink: #1c0c02; --hub-dim: #5a2808; --doc-tilt: -2deg;
  border-radius: 1.4rem 1.4rem .6rem .6rem; padding-top: 1.6rem; width: min(15rem, 30vw);
  background: radial-gradient(circle at 50% .75rem, #1a0d05 0 .32rem, #c9a24a .33rem .52rem, transparent .53rem), linear-gradient(160deg, #ea7f30, #b4490f);
}
.hub-doc--fob .hub-doc__code { color: #fff3df; text-shadow: 0 1px 0 rgba(60, 20, 0, .6); }
/* the taxi meter's printout: dot-matrix on tractor-feed paper */
.hub-doc--meter {
  --hub-paper: #f1efd8; --doc-tilt: .8deg; font-family: 'Courier New', monospace; padding-inline: 1.7rem;
  background:
    radial-gradient(circle, #1a1814 0 .22rem, transparent .23rem) 0 .4rem / 1rem 1.2rem repeat-y,
    radial-gradient(circle, #1a1814 0 .22rem, transparent .23rem) 100% .4rem / 1rem 1.2rem repeat-y,
    repeating-linear-gradient(#f1efd8 0 2.4rem, #e2ead0 2.4rem 4.8rem);
}
.hub-doc--meter .hub-doc__title { font-family: 'Courier New', monospace; letter-spacing: 0; }
/* the receipt spike's slip: torn thermal paper */
.hub-doc--receipt {
  --hub-paper: #efe9d8; --doc-tilt: -1.4deg; font-family: 'Courier New', monospace; width: min(16rem, 30vw);
  -webkit-mask: linear-gradient(#000, #000) 0 .45rem / 100% calc(100% - .9rem) no-repeat, conic-gradient(from 135deg at 50% 0, #000 90deg, transparent 0) 0 0 / .8rem .45rem repeat-x, conic-gradient(from -45deg at 50% 100%, #000 90deg, transparent 0) 0 100% / .8rem .45rem repeat-x;
  mask: linear-gradient(#000, #000) 0 .45rem / 100% calc(100% - .9rem) no-repeat, conic-gradient(from 135deg at 50% 0, #000 90deg, transparent 0) 0 0 / .8rem .45rem repeat-x, conic-gradient(from -45deg at 50% 100%, #000 90deg, transparent 0) 0 100% / .8rem .45rem repeat-x;
  padding-block: 1.2rem;
}
/* the licence's back: laminated card, magnetic stripe, a barcode nobody can scan */
.hub-doc--license {
  --hub-paper: #d6dbe0; --doc-tilt: 1.2deg; border-radius: .8rem; padding-top: 2.6rem; width: min(20rem, 34vw);
  background: linear-gradient(#22262b, #22262b) 0 .9rem / 100% 1.1rem no-repeat, linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .45) 42%, rgba(160, 220, 255, .25) 48%, transparent 58%), #d6dbe0;
}
.hub-doc--license::after { background: repeating-linear-gradient(90deg, #1b1b1b 0 2px, transparent 2px 4px, #1b1b1b 4px 7px, transparent 7px 9px); content: ''; display: block; height: 1.6rem; opacity: .75; }
/* the litter tray's card: a laminated sign off a staff toilet door, a list of what is in, one big SCOOP */
.hub-doc--litter { --hub-paper: #e6dcc0; --hub-ink: #1d1611; --hub-dim: #5b4c3a; --doc-tilt: -1deg; width: min(16rem, 30vw); border-top: .5rem solid #567f7b; }
.hub-doc__litter { display: grid; gap: .35rem; }
.hub-doc__pick { border: 2px solid var(--hub-ink); color: var(--hub-ink); font-size: .72rem; font-weight: 900; letter-spacing: .06em; min-height: 3rem; padding: .4rem .7rem; text-align: left; }
.hub-doc__pick[aria-pressed="true"] { background: #ffd23f; box-shadow: 3px 3px 0 var(--hub-ink); }
.hub-doc__pick[hidden] { display: none; }
.hub-doc__action:disabled { cursor: default; opacity: .5; }
.hub-doc__pick:focus-visible { outline: 3px solid var(--hub-ink); outline-offset: 3px; }
/* (coffee phase-4 review repair, L36) SCOOP stays in view while the picks scroll under it: on a short landscape phone the doc
   (at most 70vh) is shorter than its three picks, and SCOOP sat in its hidden overflow (374-422 in a doc ending at 376) */
.hub-doc--litter [data-litter-scoop] { bottom: 0; position: sticky; z-index: 1; }
/* the machine needs no card: its lever is the control and its plate says the rest. A small
   chip in the corner (sit back, "?" for the details); a PULL fallback appears only for
   keyboard focus. */
.hub-doc--machine {
  --hub-paper: rgba(16, 15, 13, .72); --hub-ink: #e6dfcb; --hub-dim: #bdb5a2; --doc-tilt: 0deg;
  align-items: center; border-radius: .2rem; box-shadow: 0 0 0 2px var(--hub-line), 3px 3px 0 var(--hub-line); display: flex; flex-wrap: wrap; gap: .2rem .9rem; overflow: visible; padding: .15rem .75rem; width: auto; max-width: min(21rem, calc(100vw - 2rem));
}
/* the machine's corner chip just appears: a popping layer would cost frames mid-flip */
.hub-doc--machine, .hub-doc--machine.is-open { transform: none; transition: none; }
.hub-doc__info summary { cursor: pointer; display: grid; font-size: .7rem; font-weight: 900; height: 2.25rem; list-style: none; place-items: center; width: 2.25rem; }
.hub-doc__info summary::-webkit-details-marker { display: none; }
.hub-doc__info summary span { border: 1px solid currentColor; border-radius: 50%; display: grid; height: 1.3rem; place-items: center; width: 1.3rem; }
.hub-doc__info summary:focus-visible { outline: 3px solid var(--hub-ink); outline-offset: 2px; }
.hub-doc__info[open] { flex-basis: 100%; }
.hub-doc__info p { margin: 0 0 .5rem; }
.hub__sr-focusable:not(:focus) { border: 0; clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; white-space: nowrap; width: 1px; }

/* ---------- phones and portrait tablets: the supplement sits under the object ---------- */
@media (max-width: 760px), (max-width: 1050px) and (orientation: portrait) {
  .hub { min-height: 26rem; }
  .hub__id h1 { font-size: 1rem; }
  .hub__clear { justify-content: center; min-width: 2.75rem; }
  .hub__clear .hub__sound-word { clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; } /* CLEAR VISUALS: the icon says it; the words stay for screen readers */
  .hub__controls { gap: .3rem; }
  .hub__clear { position: absolute; right: var(--gutter); top: 3.85rem; } /* below MENU: the row never overflows */
  .hub__id .account-kicker { letter-spacing: .08em; white-space: nowrap; }
  .hub__exit { gap: .35rem; letter-spacing: .1em; padding-inline: .6rem; }
  .hub__email { display: none; }
  .hub-doc, .hub-doc--fob, .hub-doc--receipt, .hub-doc--license, .hub-doc--litter { max-height: 44%; width: min(92vw, 24rem); --doc-origin: 50% 0; }
  .hub-doc--machine { --doc-origin: 0 0; max-height: none; width: auto; }
  .hub__things:focus-within { max-width: none; right: var(--gutter); }
  .hub__subtitle { bottom: 1.25rem; }
}

/* ---------- no WebGL / the world failed: the documents become the page ---------- */
.hub[data-hub-state="fallback"] { height: auto; min-height: 0; overflow: visible; padding: 6rem var(--gutter) 3rem; }
.hub[data-hub-state="fallback"] .hub__content { position: static; }
.hub[data-hub-state="fallback"] :is(.hub__viewport, .hub__things, .hub__subtitle, .hub-doc__back, .hub-doc__action) { display: none; }
.hub[data-hub-state="fallback"] .hub__docs { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); pointer-events: auto; position: static; }
.hub[data-hub-state="fallback"] .hub-doc { -webkit-mask: none; mask: none; max-height: none; opacity: 1; position: static; transform: none; transition: none; width: auto; }
.hub[data-hub-state="fallback"] .hub-doc .hub__sr-only { clip-path: none; height: auto; margin: 0; overflow: visible; position: static; white-space: normal; width: auto; }

@media (prefers-reduced-motion: reduce) {
  .hub-doc, .hub__subtitle { transition: opacity .12s linear; }
  .hub-doc, .hub-doc.is-open { transform: rotate(var(--doc-tilt, 0deg)); }
  .hub[data-hub-state="loading"] .hub__loading { animation: none; }
}
