/* Chapter 8: every app on a plinth, phone and a larger device, same scale, same angle. */
.hall { --h: min(34svh, 17vw); --pool: rgb(0 0 0 / 0.05); --hush: rgb(255 255 255 / 0.7); --hoodc: rgb(236 236 236 / 0.85); --plate: #1b1b1b; --plate-cut: rgb(255 255 255 / 0.8); --plate-lit: rgb(0 0 0 / 0.22); --rim: rgb(255 255 255 / 0.95); --sheen: rgb(255 255 255 / 0.5); --spill: rgb(255 255 255 / 0.7); --floor: rgb(0 0 0 / 0.14); padding: 0; background: var(--ground); }
:root[data-theme='dark'] .hall { --pool: rgb(255 255 255 / 0.17); --hush: rgb(0 0 0 / 0.72); --hoodc: #000; --plate: #f2f2f2; --plate-cut: rgb(0 0 0 / 0.7); --plate-lit: rgb(255 255 255 / 0.5); --rim: rgb(255 255 255 / 0.42); --sheen: rgb(255 255 255 / 0.07); --spill: rgb(255 255 255 / 0.22); --floor: rgb(255 255 255 / 0.12); }
.hall-pin { position: relative; padding: calc(var(--bar-h) + 32px) var(--margin) clamp(48px, 8vh, 96px); overflow: clip; }
.hall-still { position: absolute; inset: 0; }
.hall-still img { opacity: var(--still-fade); }
.hall h2 { position: relative; font-size: var(--type-giant); }
.exhibits { position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(36px, 6vh, 72px) clamp(16px, 2.4vw, 32px); margin-top: clamp(32px, 6vh, 64px); }
.exhibits li:nth-child(3n + 2) { transform: translateY(8svh); }
.ex { display: grid; justify-items: center; gap: 10px; color: var(--ink); text-decoration: none; text-align: center; }
/* The name and tagline stay in the page for screen readers and search. On screen, the plinth face says it. */
.ex-said { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.ex-label { display: contents; }
.hall-hood, .hall-exit { display: none; }

.spec {
  --w: calc(var(--h) * 0.46);
  --pw: calc(var(--h) * 1.56);
  --pd: calc(var(--h) * 0.8);
  --ph: calc(var(--h) * 0.74);
  --edge: calc(var(--h) * 0.016);
  position: relative;
  display: block;
  width: calc(var(--h) * 1.74);
  height: calc(var(--h) * 2.2);
  perspective: calc(var(--h) * 3.6);
  perspective-origin: 50% calc(var(--h) * 0.6);
  transition: filter 0.5s ease;
}
.rig { position: absolute; left: 50%; top: calc(var(--h) * 1.1); width: 0; height: 0; transform-style: preserve-3d; transform: rotateX(-8deg) rotateY(-24deg); }

/* The phone stands forward and to the right, over the corner of the larger device. */
.slab { position: absolute; display: block; left: calc(var(--h) * 0.27); top: calc(var(--h) * -1); width: var(--w); height: var(--h); transform-style: preserve-3d; transform: translateZ(calc(var(--h) * 0.22)); }
.slab > img, .slab > i { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: calc(var(--h) * 0.058); }
.slab > i { background: #333; }
.slab > i:nth-child(1) { transform: translateZ(calc(var(--h) * -0.024)); }
.slab > i:nth-child(2) { transform: translateZ(calc(var(--h) * -0.016)); }
.slab > i:nth-child(3) { transform: translateZ(calc(var(--h) * -0.008)); background: #1a1a1a; }

/* The larger device. Its screen is the app's real admin panel. */
.dev { --sw: calc(var(--h) * 1.06); --sh: calc(var(--h) * 0.682); --lift: 0px; position: absolute; left: 0; top: 0; width: 0; height: 0; transform-style: preserve-3d; transform: translate3d(calc(var(--h) * -0.2), 0, calc(var(--h) * -0.08)); }
.dev b { position: absolute; display: block; }
.lid { position: absolute; left: calc(var(--sw) / -2); top: calc(var(--sh) * -1 - var(--lift)); width: var(--sw); height: var(--sh); transform-style: preserve-3d; transform-origin: 50% 100%; }
.lid > i { position: absolute; inset: 0; border-radius: calc(var(--h) * 0.02); background: #333; transform: translateZ(calc(var(--h) * -0.012)); }
.pane { position: absolute; inset: 0; display: block; padding: calc(var(--h) * 0.018); border-radius: calc(var(--h) * 0.02); background: #0b0b0b; overflow: hidden; }
.pane img { width: 100%; height: 100%; object-fit: cover; object-position: 0 0; border-radius: calc(var(--h) * 0.006); background: #1a1a1a; }

.dev-laptop { --sw: calc(var(--h) * 1); --sh: calc(var(--h) * 0.646); --lift: var(--edge); --dd: calc(var(--h) * 0.54); transform: translate3d(calc(var(--h) * -0.27), 0, calc(var(--h) * -0.08)); }
.dev-laptop .lid { transform: translateZ(calc(var(--dd) / -2)) rotateX(11deg); }
.deck { left: calc(var(--sw) / -2); top: calc(var(--dd) / -2 - var(--edge)); width: var(--sw); height: var(--dd); border-radius: calc(var(--h) * 0.012); background: linear-gradient(#4b4b4b, #2e2e2e); transform: rotateX(90deg); }
.deck::before { content: ''; position: absolute; left: 7%; right: 7%; top: 7%; height: 50%; border-radius: calc(var(--h) * 0.008); background: #161616; }
.deck::after { content: ''; position: absolute; left: 36%; right: 36%; top: 63%; bottom: 7%; border-radius: calc(var(--h) * 0.008); background: #3c3c3c; }
.lip { left: calc(var(--sw) / -2); top: calc(var(--edge) * -1); width: var(--sw); height: var(--edge); background: #1a1a1a; transform: translateZ(calc(var(--dd) / 2)); }
.hinge { left: calc(var(--sw) * -0.17); top: calc(var(--edge) * -2.2); width: calc(var(--sw) * 0.34); height: calc(var(--edge) * 1.3); border-radius: calc(var(--edge) * 0.65); background: #0d0d0d; transform: translateZ(calc(var(--dd) / -2 + var(--h) * 0.006)); }

.dev-tablet { --sw: calc(var(--h) * 0.98); --sh: calc(var(--h) * 0.735); }

.dev-monitor { --sw: calc(var(--h) * 1.14); --sh: calc(var(--h) * 0.73); --lift: calc(var(--h) * 0.27); }
.neck { left: calc(var(--h) * -0.06); top: calc(var(--h) * -0.3); width: calc(var(--h) * 0.12); height: calc(var(--h) * 0.3); background: linear-gradient(#3a3a3a, #1a1a1a); transform: translateZ(calc(var(--h) * -0.03)); }
.foot { left: calc(var(--h) * -0.22); top: calc(var(--h) * -0.15 - var(--edge)); width: calc(var(--h) * 0.44); height: calc(var(--h) * 0.3); border-radius: calc(var(--h) * 0.02); background: linear-gradient(#4b4b4b, #2e2e2e); transform: rotateX(90deg); }

.block { position: absolute; left: 0; top: 0; transform-style: preserve-3d; }
.block b { position: absolute; display: block; }
.block .p { left: calc(var(--pw) / -2); top: calc(var(--pd) / -2); width: var(--pw); height: var(--pd); background: radial-gradient(ellipse 58% 62% at 34% 26%, var(--spill), transparent), var(--plinth-top); transform: rotateX(90deg); }
.block .p::before { content: ''; position: absolute; left: 3%; right: 27%; top: 8%; bottom: 20%; background: radial-gradient(closest-side, rgb(0 0 0 / 0.5), transparent); }
.block .p::after { content: ''; position: absolute; left: 62%; right: 6%; top: 60%; bottom: 12%; background: radial-gradient(closest-side, rgb(0 0 0 / 0.5), transparent); }
.block .f { left: calc(var(--pw) / -2); top: 0; display: grid; justify-items: center; align-content: start; gap: calc(var(--h) * 0.035); width: var(--pw); height: var(--ph); padding-top: calc(var(--h) * 0.07); overflow: hidden; background: linear-gradient(105deg, transparent 22%, var(--sheen) 44%, transparent 64%), linear-gradient(var(--plinth-front-1), var(--plinth-front-2)); box-shadow: inset 0 1px 0 var(--rim); transform: translateZ(calc(var(--pd) / 2)); }
.block .s { left: calc(var(--pd) / -2); top: 0; width: var(--pd); height: var(--ph); background: linear-gradient(var(--plinth-side-1), var(--plinth-side-2)); box-shadow: inset 0 1px 0 var(--rim); transform: translateX(calc(var(--pw) / 2)) rotateY(90deg); }
/* A pool on the floor, so the plinth stands on something. */
.block .g { left: calc(var(--pw) * -0.8); top: calc(var(--ph) - var(--pd) * 1.1); width: calc(var(--pw) * 1.6); height: calc(var(--pd) * 2.2); background: radial-gradient(closest-side, var(--floor), transparent); transform: rotateX(90deg); }
.plate { font-size: calc(var(--h) * 0.098); font-weight: 600; letter-spacing: -0.02em; line-height: 1.1; white-space: nowrap; color: var(--plate); text-shadow: 0 1px 0 var(--plate-cut); transition: text-shadow 0.4s var(--ease); }
.ex:hover .plate, .ex:focus-visible .plate { text-shadow: 0 1px 0 var(--plate-cut), 0 0 calc(var(--h) * 0.07) var(--plate-lit); }

/* The architecture on each plinth face, under the name. Drawn in the name's colour; hall-maps.mjs sets when each step fires. */
.ex-map { --run: paused; display: block; width: calc(var(--h) * 1.36); height: auto; overflow: visible; color: var(--plate); fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }
.ex-map.on { --run: running; }
.ex-map text { fill: currentColor; stroke: none; font-size: 11px; font-weight: 500; }
.m-wire { opacity: 0.32; }
.m-fine { opacity: 0.4; stroke-width: 0.8; }
.m-core, .m-row, .m-parcel, .m-card { fill: currentColor; stroke: none; }
.m-lit { opacity: 0; fill: currentColor; }
.m-away .m-lit { display: none; }
.m-away { opacity: 0.45; }
.m-sig { opacity: 0; stroke-width: 2.2; stroke-dasharray: 0.16 2; stroke-dashoffset: 0.16; }
.m-faint { stroke-width: 1.4; }
.m-fence { opacity: 0.55; stroke-dasharray: 2 4; }
.m-radar, .m-near, .m-scan, .m-car { opacity: 0; }
.m-near { stroke-dasharray: 2 3; }
.m-car { stroke-width: 4.5; stroke-dasharray: 0.03 2; stroke-dashoffset: 0.03; }
.m-road { opacity: 0.4; stroke-dasharray: 5 4; }
.m-post { stroke-width: 2; }
.m-gate { stroke-width: 2.4; transform-origin: 34px 78px; }
.m-ticket, .m-board { opacity: 0.6; }
.m-roll { opacity: 0.4; }
.m-parcel .m-fine { stroke: var(--ground); opacity: 1; }
.m-still { fill: currentColor; stroke: none; opacity: 0.26; }
.m-orbit { opacity: 0.5; stroke-dasharray: 2 6; transform-origin: 160px 52px; }
@media (prefers-reduced-motion: no-preference) {
  .m-sig, .m-lit, .m-row, .m-gate, .m-near, .m-scan, .m-car, .m-radar, .m-parcel, .m-card, .m-orbit { animation: 6s linear infinite; animation-delay: calc(var(--s, 0) * 1s); animation-play-state: var(--run); }
  .m-sig { animation-name: m-hop; }
  .m-lit { animation-name: m-land; }
  .m-row { animation-name: m-row; }
  .m-gate { animation-name: m-gate; animation-timing-function: var(--ease); }
  .m-near { animation-name: m-near; }
  .m-scan { animation-name: m-scan; }
  .m-car { animation-name: m-drive; }
  .m-radar { animation-name: m-radar; animation-timing-function: ease-out; transform-origin: 62px 44px; }
  .m-parcel { animation-name: m-parcel; animation-timing-function: var(--ease); }
  .m-card { animation-name: m-card; animation-timing-function: var(--ease); }
  .m-orbit { animation-name: m-orbit; animation-duration: 18s; }
  @keyframes m-hop { 0% { stroke-dashoffset: 0.16; opacity: 0; } 2%, 15% { opacity: 1; } 17%, 100% { stroke-dashoffset: -1; opacity: 0; } }
  @keyframes m-land { 0% { opacity: 0; } 3% { opacity: 0.85; } 40% { opacity: 0.18; } 70%, 100% { opacity: 0; } }
  @keyframes m-row { 0% { opacity: 0; transform: translateX(-6px); } 5%, 52% { opacity: 1; transform: none; } 62%, 100% { opacity: 0; transform: none; } }
  @keyframes m-gate { 0% { transform: none; } 9%, 46% { transform: rotate(-58deg); } 56%, 100% { transform: none; } }
  @keyframes m-near { 0% { opacity: 0; } 5% { opacity: 0.9; } 42% { opacity: 0.5; } 58%, 100% { opacity: 0; } }
  @keyframes m-scan { 0% { opacity: 0; transform: none; } 3% { opacity: 1; } 21% { opacity: 1; transform: translateX(60px); } 25%, 100% { opacity: 0; transform: translateX(60px); } }
  @keyframes m-drive { 0% { stroke-dashoffset: 0.03; opacity: 0; } 2%, 33% { opacity: 1; } 36%, 100% { stroke-dashoffset: -1; opacity: 0; } }
  @keyframes m-radar { 0% { opacity: 0.7; transform: scale(0.45); } 34%, 100% { opacity: 0; transform: scale(1.14); } }
  @keyframes m-parcel { 0% { opacity: 0; transform: none; } 4%, 10% { opacity: 1; transform: none; } 18%, 32% { transform: translateX(88px); } 40%, 54% { transform: translateX(176px); } 62%, 76% { opacity: 1; transform: translateX(252px); } 84%, 100% { opacity: 0; transform: translateX(252px); } }
  @keyframes m-card { 0%, 12% { opacity: 1; transform: none; } 20%, 34% { transform: translateX(34px); } 42%, 56% { transform: translateX(68px); } 64%, 82% { opacity: 1; transform: translateX(102px); } 90% { opacity: 0; transform: translateX(102px); } 92% { opacity: 0; transform: none; } 100% { opacity: 1; transform: none; } }
  @keyframes m-orbit { to { transform: rotate(360deg); } }
}


/* ---------- Computers: the hall, back to front. Smoke 0, plinths 1, veil 2, words 3, hood 4, the arch 5.
   Nothing between the pin and those layers may form a stacking context, so the row moves piece by piece. ---------- */
.tier-full .hall { --h: min(38svh, 20.4vw); --step: 37vw; height: 340vh; }
.tier-full .hall-pin { position: sticky; top: 0; height: 100svh; padding: 0; overflow: clip; background: var(--ground); }
.tier-full .hall.scene-on .hall-still { display: none; }

.hall-smoke { filter: blur(3px); inset: -8px; width: calc(100% + 16px); height: calc(100% + 16px); }
.hall-veil { z-index: 2; pointer-events: none; }

.tier-full .hall h2 { position: absolute; z-index: 3; left: var(--margin); top: calc(var(--bar-h) + 9svh); max-width: 4.6em; text-shadow: 0 0 22px var(--hush), 0 0 5px var(--hush); pointer-events: none; }

.tier-full .exhibits { position: absolute; left: 0; top: 0; bottom: 0; display: block; width: var(--step); margin: 0; }
.tier-full .exhibits li:nth-child(n) { transform: none; }
.tier-full .ex { position: absolute; inset: 0; display: block; text-align: left; pointer-events: none; }
.tier-full .ex:focus-visible { outline: none; }
.tier-full .ex .spec { position: absolute; pointer-events: auto; transform: translate3d(calc(64vw + var(--i) * var(--step)), 0, 0); }
.tier-full .spec { z-index: 1; left: calc(var(--h) * -0.87); top: calc(50% - var(--h) * 1.08); }
.tier-full .ex:focus-visible .f { outline: 2px solid var(--plate); outline-offset: calc(var(--h) * -0.02); }
.tier-full .exhibits li:nth-child(n + 4) .rig { display: none; }

/* Lit by the page itself until the smoke is running. */
.tier-full .hall:not(.scene-on) .spec::before { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse 50% 46% at 50% 44%, var(--pool), transparent); }
.tier-full .hall.scene-on .spec {
  --lit: 0; --tl: 0; --tx: 50%; --ty: 50%; --rx: 64%;
  -webkit-mask-image:
    radial-gradient(ellipse calc(var(--rx) * 1.2) 90% at 50% 44%, rgb(0 0 0 / var(--lit)) 76%, transparent 100%),
    radial-gradient(circle var(--tr, 40vmin) at var(--tx) var(--ty), rgb(0 0 0 / var(--tl)) 25%, transparent 100%);
  mask-image:
    radial-gradient(ellipse calc(var(--rx) * 1.2) 90% at 50% 44%, rgb(0 0 0 / var(--lit)) 76%, transparent 100%),
    radial-gradient(circle var(--tr, 40vmin) at var(--tx) var(--ty), rgb(0 0 0 / var(--tl)) 25%, transparent 100%);
}

/* The mask stops at the box and a floor pool would not, so here the smoke's own light does that job. */
.tier-full .hall.scene-on .block .g { display: none; }

.tier-full .hall-hood { position: absolute; z-index: 4; inset: 0 0 auto 0; display: block; height: 92px; pointer-events: none; background: linear-gradient(var(--hoodc) 40%, transparent); }

/* The way out. scenes/smoke.js shapes both arches; the inner one opens onto the page itself. */
.tier-full .hall-exit { position: absolute; z-index: 5; inset: 0; display: block; visibility: hidden; pointer-events: none; }
.hall-door, .hall-through { position: absolute; inset: 0; display: block; }
.hall-door { background: linear-gradient(var(--invert-ground) 62%, color-mix(in srgb, var(--invert-ground) 90%, var(--ground))); }
.hall-through { background: var(--ground); pointer-events: auto; }
.hall-spill { position: absolute; left: 0; top: 0; display: block; width: 200px; height: 26vh; margin-left: -100px; background: linear-gradient(color-mix(in srgb, var(--ink) 16%, transparent), transparent 90%); -webkit-mask-image: linear-gradient(90deg, transparent, #000 22%, #000 78%, transparent); mask-image: linear-gradient(90deg, transparent, #000 22%, #000 78%, transparent); transform-origin: 50% 0; opacity: 0; }

@media (max-width: 760px) {
  .hall { --h: min(28svh, 46vw); }
  .ex-map { width: calc(var(--h) * 1.46); }
  .ex-map text { font-size: 13px; }
  .hall-pin { padding-inline: 0; }
  .hall h2 { padding-inline: var(--margin); }
  /* One exhibit at a time, swiped along the hall. */
  .exhibits { display: flex; gap: 8px; padding-inline: 8vw; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
  .exhibits::-webkit-scrollbar { display: none; }
  .exhibits li { flex: 0 0 84vw; scroll-snap-align: center; }
  .exhibits li:nth-child(3n + 2) { transform: none; }
}
