/*
 * Layout + touch UI for the A100 noise exhibit.
 * Full-bleed isometric blueprint scene (design: isomap-1 + blueprint-2,
 * customer-approved look) — no side panels, direct manipulation only.
 * Fixed 16:9 signage stage, scaled via container-query units so touch and
 * type sizes stay proportional regardless of viewport.
 */
/* Shared inner-padding rhythm for every floating HTML box on the stage (dB
   badges, context panel, chart container) — one pair of values so all boxes
   "breathe" the same amount, instead of each picking its own (customer
   report: inconsistent padding across the pills/panels). The SVG pills
   (hotspot chips, distance handle) use their own px-based rhythm — see
   PILL_PAD_X in js/scene.js — since they're laid out in SVG user units, not
   cqw/cqh. */
:root {
  --pad-box-y: 1.2cqh;
  --pad-box-x: 1.3cqw;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  font-family: var(--font-family);
  color: var(--text-standard);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

/* Kiosk touch screen: no text-selection highlight anywhere (customer report:
   tapping labels shows a blue selection flash). */
* {
  -webkit-user-select: none;
  user-select: none;
}
::selection { background: transparent; color: inherit; }
::-moz-selection { background: transparent; color: inherit; }

/* Kiosk: no focus outlines anywhere (touch-only exhibit, no keyboard users) —
   catch-all in addition to the per-component :focus-visible:none rules below,
   so newly added interactive elements (SVG hotspots, dB badges, chart) never
   show a browser-default ring either. */
* { outline: none; }
:focus, :focus-visible { outline: none; }

/* --- Kiosk backdrop + fixed 16:9 stage --- */
.kiosk {
  display: flex; align-items: center; justify-content: center;
  height: 100vh; min-height: 100vh;
  background: #04121F;
}
.stage {
  position: relative;
  width: 100vw;
  height: 100vh;
  background: #0A2A50;
  color: var(--color-white);
  container-type: size;
  overflow: hidden;
}
.ic { width: 1em; height: 1em; display: inline-block; vertical-align: -0.12em; flex: none; }

/* --- Scene: fills the whole stage --- */
.scene { position: absolute; inset: 0; overflow: hidden; background: #0A2A50; }
.scene__mount { position: absolute; inset: 0; }
.scene__mount svg.pic { position: absolute; inset: 0; width: 100%; height: 100%; }
/* Decorative scene layers (vignette, grid, road, terrain) must NOT swallow
   taps — only the gear hotspots and the draggable house/wall are interactive. */
.scene__mount svg.pic { pointer-events: none; }
.scene__mount svg.pic .hot,
.scene__mount svg.pic .built-env,
.scene__mount svg.pic .wall-group { pointer-events: auto; }

/* --- Top dock: brand, presets, tools (GLOBAL to this page only — no other pages exist in this exhibit) --- */
.topdock {
  position: absolute; bottom: 0; left: 0; right: 0; z-index: 9;
  display: flex; align-items: center; justify-content: space-between; gap: 1.6cqw;
  padding: 1.4cqh 1.8cqw;
  background: linear-gradient(0deg, rgba(4,18,35,.86) 0%, rgba(4,18,35,0) 100%);
}
/* Brand moved to the top of the stage (customer report) — the topdock at
   the bottom now holds the day/night toggle instead (see .daynight below). */
.brand-top {
  position: absolute; top: 2.4cqh; left: 1.8cqw; z-index: 9;
  display: flex; align-items: baseline; gap: .7cqw; color: var(--color-white); text-shadow: 0 1px 3px rgba(0,0,0,.5);
}
.brand-top .logo { font-weight: var(--fw-bold); font-size: 2cqh; line-height: 1; }
.brand-top .logo b { color: var(--color-primary-25); }
.brand-top .sub { font-size: 1.15cqh; color: var(--color-primary-25); }

.seg {
  display: flex; align-items: center; background: var(--color-white);
  border: 1px solid var(--color-grey-50); border-radius: var(--radius-pill);
  padding: .5cqh; box-shadow: var(--shadow-main); gap: .3cqw;
}
.seg button {
  border: 0; background: transparent; cursor: pointer; border-radius: var(--radius-pill);
  font-family: inherit; font-weight: var(--fw-bold); color: var(--color-grey-125);
  min-height: max(64px, 6.6cqh); padding: 0 1.4cqw;
  display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1.1;
}
.seg button .pt { font-size: 1.6cqh; display: flex; align-items: center; gap: .4cqw; }
.seg button .ps { font-size: 1.02cqh; color: var(--color-grey-100); font-weight: var(--fw-regular); }
.seg button.is-active { background: var(--color-primary-100); color: var(--color-white); }
.seg button.is-active .ps { color: var(--color-white); }
.seg button:focus-visible { outline: none; }
.seg .lead {
  display: flex; align-items: center; font-size: 1.05cqh; font-weight: var(--fw-bold); color: var(--color-grey-100);
  text-transform: uppercase; letter-spacing: .04em; padding: 0 .8cqw 0 1cqw;
}
.seg .sep { width: 1px; height: 4.6cqh; background: var(--color-grey-40); margin: 0 .3cqw; flex: none; }
.seg button.indiv { position: relative; cursor: pointer; }
.seg button.indiv:disabled { cursor: default; }
.seg button.indiv[aria-pressed="true"] {
  background: rgba(0,158,227,.12); color: var(--color-primary-125);
  box-shadow: inset 0 0 0 1.6px var(--color-primary-50);
}
.seg button.indiv[aria-pressed="true"] .pt .ic { color: var(--color-primary-100); }
.seg button.indiv[aria-pressed="true"] .ps { color: var(--color-primary-100); }
.seg button.indiv .dot {
  position: absolute; top: .9cqh; right: .9cqw; width: 1.1cqh; height: 1.1cqh;
  min-width: 9px; min-height: 9px; border-radius: var(--radius-pill); background: var(--color-primary-50);
  box-shadow: 0 0 0 .5cqh rgba(0,158,227,.22); animation: dotPing 2.6s ease-out infinite;
}
@keyframes dotPing { 0% { box-shadow: 0 0 0 0 rgba(0,158,227,.4); } 70% { box-shadow: 0 0 0 1cqh rgba(0,158,227,0); } 100% { box-shadow: 0 0 0 0 rgba(0,158,227,0); } }

.tools { display: flex; align-items: center; gap: .7cqw; flex: none; }
.icbtn {
  border: 1px solid rgba(196,229,244,.7); background: rgba(10,50,95,.6); cursor: pointer;
  border-radius: var(--radius-pill); color: var(--color-white); font-family: inherit; font-weight: var(--fw-bold);
  font-size: 1.35cqh; min-height: max(64px, 6cqh); padding: 0 1.3cqw;
  display: inline-flex; align-items: center; gap: .5cqw;
}
.icbtn .ic { font-size: 1.9cqh; }
.icbtn.is-on { background: var(--color-primary-50); border-color: var(--color-primary-50); color: var(--color-primary-150); }
.icbtn:disabled { opacity: .6; cursor: default; }
.icbtn:focus-visible { outline: none; }

/* --- Day/night toggle: lives in the bottom topdock now (customer report:
   brand should be up top, day/night down with the other tools). --- */
.daynight {
  display: flex; align-items: center; gap: .7cqw; flex: none;
  background: rgba(255,255,255,.95); border: 1px solid var(--color-grey-50); border-radius: var(--radius-pill);
  padding: .7cqh .9cqw; cursor: pointer; min-height: max(64px, 6.6cqh);
}
.daynight:focus-visible { outline: none; }
.daynight .orb {
  width: 3cqh; height: 3cqh; min-width: 30px; min-height: 30px; border-radius: var(--radius-pill);
  background: radial-gradient(circle at 38% 34%, #FFE9A8, #F2C200); transition: background .25s ease;
}
[data-period="night"] .daynight .orb { background: radial-gradient(circle at 38% 34%, #E7EEF5, #A5ABAD); }
.daynight .lab { font-size: 1.35cqh; font-weight: var(--fw-bold); color: var(--color-primary-150); }

/* --- Dual dB badges (always visible, clickable to pick the audible location) --- */
.db {
  position: absolute; z-index: 7; background: rgba(255,255,255,.97); border-radius: var(--radius-box);
  box-shadow: var(--shadow-main); padding: var(--pad-box-y) var(--pad-box-x); display: flex; align-items: center; gap: .8cqw;
  border-left: .6cqw solid var(--noise-critical); cursor: pointer; border-top: 2px solid transparent;
  border-right: 2px solid transparent; border-bottom: 2px solid transparent;
}
.db:focus-visible { outline: none; }
.db.is-active {
  border-top-color: var(--color-primary-50); border-right-color: var(--color-primary-50); border-bottom-color: var(--color-primary-50);
  box-shadow: 0 0 0 2px var(--color-primary-50), var(--shadow-main);
}
.db .num { font-size: 3.2cqh; font-weight: var(--fw-bold); line-height: 1; transition: color .3s ease; }
.db .meta { display: flex; flex-direction: column; gap: .1cqh; }
.db .meta .k { font-size: 1.15cqh; color: var(--color-grey-100); text-transform: uppercase; letter-spacing: .04em; font-weight: var(--fw-bold); }
.db .meta .v { font-size: 1.3cqh; font-weight: var(--fw-bold); color: var(--text-standard); }
.db .unit { font-size: 1.2cqh; color: var(--color-grey-100); font-weight: var(--fw-regular); }
/* "Im Garten davor" sits next to the tree, in the garden strip between the
   house and the wall/road — clear of the chart (which ends at ~22.4cqw) and
   of the "Lärmschutzwand" hotspot further down the wall. */
.db--garden { left: 39cqw; top: 31cqh; }
/* Sits above and left of the "Haus & Fenster" hotspot pill (customer report:
   the two used to overlap) — still at #houseGroup's own screen position
   (flat-iso rebuild — house sits in the plot's upper-right corner at the
   default distance), just offset clear of the pill and of the chart. */
.db--house { left: 18cqw; top: 8cqh; }
.db[data-key="healthy"] { border-left-color: var(--noise-healthy); }
.db[data-key="healthy"] .num { color: var(--noise-healthy); }
.db[data-key="slight"] { border-left-color: var(--noise-slight); }
.db[data-key="slight"] .num { color: var(--noise-slight-text); } /* deepened: raw yellow fails AA as text on white */
.db[data-key="sleep"] { border-left-color: var(--noise-sleep); }
.db[data-key="sleep"] .num { color: var(--noise-sleep); }
.db[data-key="critical"] { border-left-color: var(--noise-critical); }
.db[data-key="critical"] .num { color: var(--noise-critical); }

/* --- Scene: vehicles, wall, wave, hotspots --- */
:root {
  --v-top: #164A80; --v-right: #103F72; --v-front: #0B2C52; --v-edge: #DCEFF9;
  --v-glass: #0A2848; --v-glasshair: #8FD0F0; --v-tire: #0A2440; --v-rim: #5E93BC; --v-hub: #8FD0F0;
  --v-ew: 2.2px;
}
.veh .vt { fill: var(--v-top); }
.veh .vr { fill: var(--v-right); }
.veh .vf { fill: var(--v-front); }
.veh .vt, .veh .vr, .veh .vf { stroke: var(--v-edge); stroke-width: var(--v-ew); stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.veh .glass { fill: var(--v-glass); stroke: var(--v-glasshair); stroke-width: 1.4px; vector-effect: non-scaling-stroke; }
.veh .lamp { fill: #EAF6FC; }
.veh .tire { fill: var(--v-tire); stroke: var(--v-edge); stroke-width: 1.5px; vector-effect: non-scaling-stroke; }
.veh .rim { fill: none; stroke: var(--v-rim); stroke-width: 1.4px; vector-effect: non-scaling-stroke; }
.veh .hub { fill: var(--v-hub); }
.veh .seam { fill: none; stroke: var(--v-edge); stroke-width: 1.3px; stroke-opacity: .55; vector-effect: non-scaling-stroke; }

/* Per-lane @keyframes (fixed start/end translate) are injected by
   scene.js#_injectLaneKeyframes — the lane offsets are static, only the
   animation-name/duration/delay are set from here on. */
.veh-lane { animation-timing-function: linear; animation-iteration-count: infinite; }
/* Vehicle art (design/isomap-1.html) is drawn with its length already along
   the road's RUN axis, so the "in" carriageway needs no reorientation at
   all. "out" needs no CSS transform either any more — a CSS reflection
   (scaleX(-1), a 180deg rotation, or any other single 2D transform) can't
   correctly reverse travel direction here: RUN, WID and the vertical axis
   aren't three independent 2D directions, so fixing where any two of them
   land always breaks the third (see scene.js buildMirroredVehicleSymbol for
   the full reasoning). scene.js instead builds a `-out` sibling symbol with
   every part's own RUN-component reversed and points the outbound lanes'
   <use> at that sibling — the classes below stay as styling hooks only. */
.veh-orient--in, .veh-orient--out { transform-box: fill-box; transform-origin: center; }

.wall-group { transition: opacity .3s ease; transform-box: fill-box; transform-origin: 50% 100%; }
.wall-group.wall-building { animation: wallBuild .55s ease-out; }
@keyframes wallBuild {
  0%   { transform: scaleY(.15) translateY(6%); opacity: .25; }
  55%  { transform: scaleY(1.08); opacity: 1; }
  100% { transform: scaleY(1); opacity: 1; }
}

/* Rings ripple outward from the road and fade — like the hotspot pulse, but
   #waveGroup itself carries the RUN/WID ground-plane matrix (scene.js
   waveMarkup), so the plain local circles it contains render as iso ellipses
   flat on the road, not screen-plane circles. The outer .wave-scale
   wrapper's size follows loudness (scene.js renderWave sets --wave-max-r) so
   louder sources reach further; vector-effect="non-scaling-stroke" on each
   ring (set in scene.js) keeps the stroke a constant screen width despite
   the ground-plane skew and the scale animation below. */
#waveGroup { transition: opacity .4s ease; }
.wave-scale { transform-box: fill-box; transform-origin: center; transform: scale(var(--wave-max-r, 2)); transition: transform .4s ease; }
.wave-ring { transform-box: fill-box; transform-origin: center; opacity: 0; transition: stroke .35s ease; }
#waveGroup:not(.is-silent) .wave-ring { animation: waveRipple var(--pulse-speed, 2.4s) ease-out infinite; }
.wave-ring[data-i="1"] { animation-delay: -0.8s; }
.wave-ring[data-i="2"] { animation-delay: -1.6s; }
@keyframes waveRipple { 0% { transform: scale(.05); opacity: .9; } 100% { transform: scale(1); opacity: 0; } }

.excavator { transition: opacity .3s ease; }
/* Pivot = the boom's own shoulder joint (51,-0.5 in #excArm's local geometry,
   confirmed via getBBox() — it sits exactly at the bbox's top-left corner).
   transform-box:view-box + absolute view-box coordinates was tried first (per
   spec that should pivot correctly regardless of ancestor transforms) but
   produced a wildly flung-out arm in testing; fill-box with the box's own
   corner is the robust, verified-correct equivalent. */
.excavator.is-digging #excArm { animation: dig 2s ease-in-out infinite; transform-box: fill-box; transform-origin: 0% 0%; }
@keyframes dig { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(15deg); } }

.built-env.draggable-env, .wall-group.draggable-env { cursor: grab; touch-action: none; }
/* #treeGroup shares .built-env (moves with the house) but isn't itself a
   drag handle, so the eased-follow transition is keyed off .built-env alone. */
.built-env { transition: transform .12s ease-out; }

.hot { cursor: pointer; }
.hot-pulse {
  opacity: .3; transform-box: fill-box; transform-origin: center;
  animation: hotPulse 2.6s ease-out infinite;
}
.hot-ring { transition: stroke .2s ease, filter .2s ease; }
.hot.is-active .hot-ring { stroke: var(--color-primary-50); stroke-width: 3.2; filter: drop-shadow(0 0 4px rgba(0,158,227,.7)); }
.hot:focus-visible .hot-ring { outline: none; }
@keyframes hotPulse { 0% { transform: scale(.55); opacity: .45; } 70% { opacity: 0; } 100% { transform: scale(1.7); opacity: 0; } }

.leader { transition: opacity .2s ease; }
.leader #leaderLine, .leader #leaderEnd { transition: x1 .18s ease, y1 .18s ease, x2 .18s ease, y2 .18s ease, cx .18s ease, cy .18s ease; }

/* --- Context panel: bottom-right, white, card-style options --- */
.ctxpanel {
  position: absolute; right: 1.8cqw; bottom: 12cqh; width: 30cqw; min-width: 360px; max-height: 64cqh;
  background: var(--color-white); border-radius: var(--radius-card); box-shadow: var(--shadow-main);
  border: 1px solid var(--color-grey-40); z-index: 8; overflow: hidden; display: flex; flex-direction: column;
}
.ctxpanel[hidden] { display: none; }
.ctxpanel .ph {
  display: flex; align-items: center; justify-content: space-between; gap: 1cqw;
  padding: var(--pad-box-y) var(--pad-box-x); border-bottom: 1px solid var(--color-grey-40); flex: none;
}
.ctxpanel .ph .t { display: flex; align-items: center; gap: .7cqw; font-size: 1.9cqh; font-weight: var(--fw-bold); color: var(--color-primary-150); }
.ctxpanel .ph .t .ic { font-size: 2.2cqh; color: var(--color-primary-100); }
.ctxpanel .x {
  border: 1px solid var(--color-grey-50); background: var(--color-white); cursor: pointer;
  width: max(44px, 5.2cqh); height: max(44px, 5.2cqh); display: grid; place-items: center; color: var(--color-grey-125);
  border-radius: var(--radius-button);
}
.ctxpanel .x:focus-visible { outline: none; }
.ctxpanel .x .ic { font-size: 2cqh; }
.ctxpanel .pb { padding: var(--pad-box-y) var(--pad-box-x); display: flex; flex-direction: column; gap: 1cqh; overflow-y: auto; }

.ctxpanel .group-title {
  margin: .4cqh 0 0; font-size: 1.15cqh; font-weight: var(--fw-bold); letter-spacing: .05em;
  text-transform: uppercase; color: var(--color-primary-125);
}
.opt {
  display: flex; align-items: center; gap: 1cqw; min-height: max(72px, 8cqh); width: 100%;
  border: 1px solid var(--color-grey-50); border-radius: var(--radius-card); padding: .9cqh 1cqw;
  cursor: pointer; background: var(--color-white); text-align: left; font-family: inherit;
}
.opt[aria-pressed="true"] { border-color: var(--color-primary-50); border-width: 2px; background: #F2FAFE; }
.opt .th { width: max(48px, 5.4cqh); height: max(48px, 5.4cqh); flex: none; display: grid; place-items: center; color: var(--color-primary-100); }
.opt .ot { display: flex; flex-direction: column; gap: .2cqh; flex: 1; }
.opt .ot .ol { font-size: 1.5cqh; font-weight: var(--fw-bold); color: var(--color-primary-150); }
.opt .ot .oc { font-size: 1.15cqh; color: var(--color-grey-100); }
.opt .rd {
  width: max(22px, 2.6cqh); height: max(22px, 2.6cqh); border-radius: var(--radius-pill);
  border: 2px solid var(--color-grey-50); flex: none; display: grid; place-items: center;
}
.opt[aria-pressed="true"] .rd { border-color: var(--color-primary-50); }
.opt[aria-pressed="true"] .rd::after {
  content: ""; width: max(11px, 1.3cqh); height: max(11px, 1.3cqh); border-radius: var(--radius-pill); background: var(--color-primary-50);
}
.opt:focus-visible { outline: none; }

.trow {
  display: flex; align-items: center; justify-content: space-between; gap: 1cqw; width: 100%;
  min-height: max(64px, 5.6cqh); border: 1px solid var(--color-grey-50); border-radius: var(--radius-card);
  padding: 0 1.1cqw; cursor: pointer; background: var(--color-grey-25); font-family: inherit;
  font-size: 1.35cqh; font-weight: var(--fw-bold); color: var(--text-standard);
}
.trow.is-on { background: var(--color-primary-25); border-color: var(--color-primary-50); color: var(--color-primary-150); }
.trow:focus-visible { outline: none; }
.trow__track {
  width: 5cqw; min-width: 46px; height: 2.6cqh; min-height: 26px; border-radius: var(--radius-pill);
  background: var(--color-grey-50); position: relative; flex: none; transition: background .2s;
}
.trow__track::after {
  content: ""; position: absolute; top: 12%; left: 5%; width: 42%; height: 76%; border-radius: var(--radius-pill);
  background: var(--color-white); box-shadow: 0 1px 3px rgba(0,0,0,.3); transition: left .2s;
}
.trow.is-on .trow__track { background: var(--color-primary-50); }
.trow.is-on .trow__track::after { left: 53%; }

.steps { display: flex; gap: 0; flex-wrap: wrap; }
.steps__btn {
  flex: 1 1 0; min-width: 60px; min-height: max(56px, 5.6cqh); font-family: inherit; font-size: 1.25cqh;
  font-weight: var(--fw-bold); background: var(--color-white); color: var(--color-grey-125);
  border: 1px solid var(--color-grey-50); cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.steps__btn + .steps__btn { border-left: 0; }
.steps__btn:first-child { border-top-left-radius: var(--radius-card); border-bottom-left-radius: var(--radius-card); }
.steps__btn:last-child { border-top-right-radius: var(--radius-card); border-bottom-right-radius: var(--radius-card); }
.steps__btn.is-active { background: var(--color-primary-100); color: var(--color-white); border-color: var(--color-primary-100); }
.steps__btn:focus-visible { outline: none; position: relative; z-index: 2; }

.prow { display: flex; align-items: center; justify-content: space-between; gap: 1cqw; padding-top: 1cqh; border-top: 1px solid var(--color-grey-40); }
.prow .l { font-size: 1.35cqh; font-weight: var(--fw-bold); color: var(--text-standard); white-space: nowrap; }
.prow .v { font-size: 1.35cqh; font-weight: var(--fw-bold); color: var(--color-primary-125); white-space: nowrap; }
.prow input[type="range"] {
  flex: 1; margin: 0 1cqw; accent-color: var(--color-primary-50);
  height: max(28px, 2.8cqh);
}

/* --- "Schall über Entfernung" chart: compact overlay, left-middle --- */
.noise-chart {
  position: absolute; z-index: 6; left: 1.4cqw; top: 38cqh;
  width: 21cqw; min-width: 250px; max-width: 320px;
  background: rgba(6,26,50,.72); border: 1px solid rgba(143,208,240,.35); border-radius: var(--radius-card);
  padding: var(--pad-box-y) var(--pad-box-x); pointer-events: none; backdrop-filter: blur(2px);
}
.noise-chart .nc-title { margin: 0 0 .4cqh; font-size: 1.15cqh; font-weight: var(--fw-bold); color: #DCEFF9; }
.noise-chart .nc-svg { display: block; width: 100%; height: auto; }
.nc-legend { display: flex; gap: 1cqw; margin-top: .4cqh; }
.nc-legend__item { display: flex; align-items: center; gap: .3cqw; font-size: 1.05cqh; font-weight: var(--fw-bold); color: #DCEFF9; }
.nc-legend__item i { width: 1cqh; height: 1cqh; min-width: 8px; min-height: 8px; border-radius: var(--radius-pill); flex: none; }

/* --- Reduced motion: everything static --- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
