/* survey.css: the Survey tab, the plan editor and the plan photo import.
 *
 * Three screens that share one idea: a full bleed map with glass floating
 * on it. The survey's HUD sits above the tab bar (walking continues while
 * other tabs are open, so the tab bar stays); the editor puts the tab bar
 * away and docks its tools at the bottom; the plan import takes the whole
 * screen for the minute it needs, top bar included.
 *
 * Built only from the tokens and classes in base.css (ARCHITECTURE.md
 * section 7). Positions come from the safe-area tokens, never fixed pixel
 * guesses about a notch; full-height surfaces state 100vh, then 100dvh.
 *
 * Text people read (sheet and card copy, the editor's flow panel, labels
 * and hints) is sized in var(--fs), so Larger Text reaches it, as in
 * base.css. What floats over the map (the survey HUD, the editor's bars,
 * dock and selection card, chips and legends) stays in px, as map.css does:
 * it has to hold its place over a canvas. A field never goes under 16px.
 * White text sits on the --fill-blue stops (4.7:1 and better), never on the
 * brand blue (3.6:1).
 *
 * What it refuses to do: put anything under a finger that scrolls the page
 * while it should move the map or a handle. The stages and canvases are
 * touch-action: none, and long-press callouts are off where a long press
 * means something.
 */

/* ── Shared: glass on a map ───────────────────────────────────────────── */
.sv-view, .ed-view {
  --sv-glass: rgba(5, 11, 31, .72);
  --sv-glass-hi: rgba(10, 22, 58, .86);
  background: var(--bg);
  isolation: isolate;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
.sv-stage, .ed-stage { position: absolute; inset: 0; overflow: hidden; touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.sv-round, .ed-round, .sv-notice, .sv-hud, .ed-top, .ed-context, .ed-dock, .ed-card, .ed-panel {
  background: var(--sv-glass);
  -webkit-backdrop-filter: saturate(160%) blur(18px); backdrop-filter: saturate(160%) blur(18px);
  border: 1px solid var(--line-2);
  box-shadow: 0 14px 36px -18px rgba(0, 0, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .06);
}
.sv-round, .ed-round {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center; color: var(--ink);
  transition: transform 120ms var(--ease), background 200ms, color 200ms;
}
.sv-round:active, .ed-round:active { transform: scale(.9); background: var(--sv-glass-hi); }
.sv-round .ico, .ed-round .ico { width: 20px; height: 20px; }
.sv-round.on { color: var(--blue-hi); box-shadow: inset 0 0 0 1.5px rgba(41, 169, 242, .7), 0 0 18px -4px rgba(41, 169, 242, .8); }
.ed-round:disabled { opacity: .38; pointer-events: none; }

/* ═══════════════════════════════════════════════════════════════════════
   SURVEY
   ═══════════════════════════════════════════════════════════════════════ */

.sv-top {
  position: absolute; z-index: 5; top: 10px;
  left: calc(var(--safe-l) + 12px); right: calc(var(--safe-r) + 12px);
  display: flex; align-items: flex-start; gap: 10px; pointer-events: none;
}
.sv-top > * { pointer-events: auto; }
.sv-notice {
  flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 9px;
  min-height: 44px; padding: 9px 14px 9px 11px; border-radius: 16px;
  font-size: 13.5px; line-height: 1.35; color: var(--ink);
  animation: drop 240ms var(--ease) both;
}
.sv-notice-said { flex: 1 1 180px; min-width: 0; display: flex; align-items: center; gap: 9px; }
.sv-notice-icon { flex: none; width: 26px; height: 26px; border-radius: 9px; display: grid; place-items: center; color: var(--blue-hi); background: rgba(41, 169, 242, .14); }
.sv-notice-text { min-width: 0; }
/* A notice that asks for something (Keep testing, Finish now, Why): real buttons, 44 px tall to tap. */
.sv-notice-acts { flex: none; display: flex; gap: 6px; margin: -4px -6px -4px auto; }
.sv-notice-acts:not(:has(.sv-notice-btn:not([hidden]))) { display: none; }
.sv-notice-btn { flex: none; min-height: 44px; font-size: 13.5px; }
.sv-top-btns { margin-left: auto; display: flex; flex-direction: column; gap: 8px; }
.sv-paused .sv-notice-icon { color: var(--warn); background: rgba(251, 191, 36, .14); }

/* The HUD: everything a walker needs, in reach of a thumb. */
.sv-hud {
  position: absolute; z-index: 6;
  left: calc(var(--safe-l) + 10px); right: calc(var(--safe-r) + 10px); bottom: 10px;
  max-width: 560px; margin: 0 auto;
  border-radius: 26px; padding: 12px;
  display: flex; flex-direction: column; gap: 10px;
  animation: rise 280ms var(--ease) both;
}
.sv-confirm {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 8px 8px 12px; border-radius: 16px;
  background: rgba(1, 142, 220, .16); border: 1px solid rgba(41, 169, 242, .45);
  animation: rise 200ms var(--ease) both;
}
.sv-confirm-icon { color: var(--blue-hi); display: grid; place-items: center; }
.sv-confirm-text { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; }
.sv-confirm-x { width: 40px; height: 40px; flex: none; border-radius: 12px; display: grid; place-items: center; color: var(--ink-2); }
.sv-confirm-x:active { background: var(--glass-2); }

/* Idle: one big way in. */
.sv-idle { display: flex; align-items: center; gap: 14px; }
.sv-idle-text { flex: 1; min-width: 0; }
.sv-idle-title { margin: 0; font: 700 16px/1.25 var(--head); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sv-idle-sub { margin: 3px 0 0; font-size: 13px; line-height: 1.4; color: var(--ink-2); }
.sv-start {
  position: relative; flex: none; display: inline-flex; align-items: center; gap: 8px;
  min-height: 56px; padding: 0 22px 0 18px; border-radius: 999px;
  font: 700 15.5px/1 var(--head); color: #fff;
  background: radial-gradient(circle at 30% 20%, #0a78bd, #0565a0 58%, #04578a);
  box-shadow: 0 16px 34px -12px rgba(1, 142, 220, .95), inset 0 1px 0 rgba(255, 255, 255, .35);
  transition: transform 160ms var(--spring);
}
.sv-start:active { transform: scale(.94); }
.sv-start-ring { position: absolute; inset: -5px; border-radius: inherit; border: 2px solid rgba(41, 169, 242, .7); animation: svRing 2.2s var(--ease) infinite; pointer-events: none; }
@keyframes svRing { 0% { transform: scale(.96); opacity: .9; } 100% { transform: scale(1.18); opacity: 0; } }

/* Live. */
.sv-live { display: flex; flex-direction: column; gap: 10px; }
.sv-live-top { display: grid; grid-template-columns: 132px minmax(0, 1fr); gap: 12px; align-items: center; }
.sv-gauge-wrap { display: flex; flex-direction: column; align-items: center; min-width: 0; }
.sv-gauge { position: relative; width: 132px; height: 132px; }
.sv-g-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.sv-g-track { stroke: rgba(255, 255, 255, .09); stroke-width: 10; stroke-linecap: round; }
.sv-g-value, .sv-g-glow {
  stroke: var(--ink-3); stroke-width: 10; stroke-linecap: round;
  transition: stroke-dashoffset 650ms var(--ease), stroke 400ms var(--ease);
}
.sv-g-glow { stroke-width: 16; opacity: .28; filter: blur(5px); }
.sv-g-ticks line { stroke: rgba(255, 255, 255, .22); stroke-width: 1.5; stroke-linecap: round; }
.sv-g-thr { stroke: #ffffff; stroke-width: 2.5; stroke-linecap: round; opacity: .85; }
.sv-g-markwrap { transform-box: view-box; transform-origin: 64px 64px; transition: transform 650ms var(--ease); }
.sv-g-mark { fill: var(--ink-3); stroke: #fff; stroke-width: 2.5; transition: fill 400ms; }
.sv-gauge[data-kind="none"] .sv-g-markwrap { opacity: 0; }
.sv-gauge[data-kind="none"] .sv-g-track { animation: svBreath 1.8s ease-in-out infinite; }
@keyframes svBreath { 50% { stroke: rgba(41, 169, 242, .32); } }
.sv-g-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; padding-top: 6px; pointer-events: none; }
.sv-g-num { font: 800 32px/1 var(--head); letter-spacing: -.03em; color: var(--ink); min-height: 32px; }
.sv-g-unit { margin-top: 2px; font: 700 11px/1 var(--body); color: var(--ink-3); letter-spacing: .04em; min-height: 11px; }
.sv-g-grade { margin-top: 6px; font: 700 12px/1 var(--head); color: var(--ink-2); max-width: 96px; text-align: center; }
.sv-gauge[data-tone="ok"] .sv-g-grade { color: #6ee7b7; }
.sv-gauge[data-tone="warn"] .sv-g-grade { color: #fcd34d; }
.sv-gauge[data-tone="bad"] .sv-g-grade { color: #fca5a5; }
.sv-g-sub { margin: -6px 0 0; max-width: 132px; font-size: 11.5px; line-height: 1.3; color: var(--ink-3); text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sv-live-side { min-width: 0; display: flex; flex-direction: column; gap: 9px; }
/* "Auto scanning, 42 samples": the walk's main news, a live dot that keeps pulsing while it samples by itself. */
.sv-auto {
  display: flex; align-items: center; gap: 10px; min-width: 0;
  padding: 6px 12px 6px 11px; border-radius: 15px;
  background: rgba(52, 211, 153, .1); border: 1px solid rgba(52, 211, 153, .36);
}
.sv-auto-dot { position: relative; flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 10px rgba(52, 211, 153, .9); }
.sv-auto-dot::after { content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 2px solid var(--ok); opacity: 0; animation: livePulse 1.6s var(--ease) infinite; }
.sv-auto-words { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; min-width: 0; }
.sv-auto-text { font: 700 14px/1.2 var(--head); color: #d1fae5; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sv-auto-sub { font-size: 12px; line-height: 1.25; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Paused, or no sensor measuring now (idle, "Waiting for a sensor"): amber and still, never the green pulse of a scan. */
.sv-auto.paused, .sv-auto.idle { background: rgba(251, 191, 36, .1); border-color: rgba(251, 191, 36, .4); }
.sv-auto.paused .sv-auto-dot, .sv-auto.idle .sv-auto-dot { background: var(--warn); box-shadow: none; }
.sv-auto.paused .sv-auto-dot::after, .sv-auto.idle .sv-auto-dot::after { animation: none; }
.sv-auto.paused .sv-auto-text, .sv-auto.idle .sv-auto-text { color: #fde68a; }
.sv-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.sv-stat { display: flex; flex-direction: column; gap: 3px; min-width: 0; padding: 8px 9px; border-radius: 13px; background: var(--glass); border: 1px solid var(--line); }
.sv-stat-v { font: 700 17px/1 var(--head); letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sv-stat-l { font-size: 10.5px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .08em; font-weight: 700; }
.sv-stat.warn { border-color: rgba(251, 191, 36, .35); }
.sv-stat.warn .sv-stat-v { color: #fde68a; }

/* The row's padding holds the chips' 44 px reach (::after) inside the scroller that would clip it. */
.sv-pills { gap: 6px; padding: 8px 0; margin: -8px 0; scroll-snap-type: none; }
/* It settles on a whole chip once a scroll ends (survey.js settlePills): the tail lets the last chip reach the
   left edge, and the start fades only over a chip's own padding, never its dot or its first letters. */
.sv-pills::after { content: ''; flex: none; width: var(--sv-tail, 0px); margin-left: -6px; }
@supports (animation-timeline: scroll(self inline)) {
  .sv-pills {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 calc(var(--sx-start) * .35), #000 calc(100% - var(--sx-end)), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 calc(var(--sx-start) * .35), #000 calc(100% - var(--sx-end)), transparent);
  }
}
.sv-pill {
  display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: 999px;
  font: 600 12px/1 var(--body); color: var(--ink-2); background: var(--glass); border: 1px solid var(--line); white-space: nowrap;
}
.sv-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-3); flex: none; position: relative; }
.sv-pill.is-ok { color: #c7f9e4; border-color: rgba(52, 211, 153, .35); }
.sv-pill.is-ok .sv-dot { background: var(--ok); box-shadow: 0 0 8px rgba(52, 211, 153, .9); }
.sv-pill.is-busy .sv-dot { background: var(--blue-hi); }
.sv-pill.is-busy .sv-dot::after { content: ''; position: absolute; inset: -3px; border-radius: 50%; border: 1.5px solid var(--blue-hi); animation: livePulse 1.1s var(--ease) infinite; }
.sv-pill.is-warn { color: #fde68a; border-color: rgba(251, 191, 36, .35); }
.sv-pill.is-warn .sv-dot { background: var(--warn); }
.sv-pill.is-bad { color: #fecaca; border-color: rgba(248, 113, 113, .4); }
.sv-pill.is-bad .sv-dot { background: var(--bad); }
.sv-pill.is-idle .sv-dot { background: var(--info); }
.sv-pill.is-off { opacity: .6; }
/* A sensor's health chip: the one place its state is said (colour and a word). A tap opens its reason below the chips. */
.sv-chip { position: relative; height: 30px; transition: transform 120ms var(--ease), background 200ms; }
.sv-chip::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 44px; margin-top: -22px; }
.sv-chip:active { transform: scale(.95); }
.sv-chip[aria-expanded="true"] { background: var(--glass-2); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2); }
.sv-chip-label { max-width: 130px; overflow: hidden; text-overflow: ellipsis; }
.sv-chip-meta { font-weight: 500; opacity: .82; }
/* Silent is a hollow red ring, not only a colour. */
.sv-chip.is-bad .sv-dot { background: transparent; box-shadow: inset 0 0 0 2px var(--bad); }
.sv-why {
  margin: 0; padding: 9px 12px; border-radius: 14px;
  font-size: 13px; line-height: 1.45; color: var(--ink);
  background: var(--glass-2); border: 1px solid var(--line-2);
  animation: rise 200ms var(--ease) both;
}

/* Stop and go: only slow sensors are live, so the walker stands at each spot and waits for the green dot.
   No clock (the ring counts down) and no sensor's state (the chips say it): a title, Android's quota, one line or the dot.
   ⚠ Compact, and the gauge steps aside while it shows (.sv-live.sag): the HUD must not cover the plan. */
.sv-sag {
  display: flex; flex-direction: column; gap: 6px; padding: 9px 11px 10px; border-radius: 17px;
  background: rgba(251, 191, 36, .08); border: 1px solid rgba(251, 191, 36, .32);
  animation: rise 220ms var(--ease) both;
}
.sv-sag p { margin: 0; }
.sv-sag-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.sv-sag-title { display: flex; align-items: center; gap: 7px; min-width: 0; font: 700 14px/1.2 var(--head); color: #fde68a; }
.sv-sag-title .ico { color: var(--warn); flex: none; }
.sv-sag-quota { flex: none; padding-top: 2px; font-size: 11px; color: var(--ink-2); white-space: nowrap; }
.sv-sag-line { font-size: 12.5px; line-height: 1.4; color: var(--ink-2); }
.sv-sag-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; }
.sv-sag-state { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1 1 170px; font-size: 12.5px; line-height: 1.3; font-weight: 600; color: var(--ink); }
.sv-sag-dot { width: 13px; height: 13px; border-radius: 50%; flex: none; border: 2px solid var(--ink-3); }
.sv-sag-dot[data-state="wait"] { border-color: var(--warn); background: rgba(251, 191, 36, .35); animation: blink 1.4s ease-in-out infinite; }
.sv-sag-dot[data-state="done"] { border-color: var(--ok); background: var(--ok); box-shadow: 0 0 10px rgba(52, 211, 153, .9); }
.sv-sag-btns { display: flex; gap: 6px; flex: none; margin-left: auto; }
.sv-live.sag .sv-gauge-wrap { display: none; }
.sv-live.sag .sv-live-top { grid-template-columns: minmax(0, 1fr); }
/* The one pill that is a button (Start walk readings): blue, and 36 px to tap. */
.sv-pill-item { display: inline-flex; flex: none; }
.sv-pill-act { height: 36px; padding: 0 12px 0 10px; font-weight: 700; color: #e0f2fe; background: rgba(1, 142, 220, .2); border-color: rgba(41, 169, 242, .6); transition: transform 120ms var(--ease); }
.sv-pill-act:active { transform: scale(.95); }
.sv-pill-act .ico { width: 14px; height: 14px; color: var(--blue-hi); }

.sv-controls { display: grid; grid-template-columns: 46px 46px minmax(0, 1fr) 50px 50px; gap: 7px; align-items: center; }
.sv-ctl {
  height: 52px; border-radius: 17px; display: grid; place-items: center; color: var(--ink);
  background: var(--glass-2); border: 1px solid var(--line-2);
  transition: transform 120ms var(--ease), background 200ms;
}
.sv-ctl:active { transform: scale(.92); background: rgba(255, 255, 255, .14); }
.sv-ctl .ico { width: 22px; height: 22px; }
.sv-ctl-stop { color: #fecaca; background: rgba(248, 113, 113, .14); border-color: rgba(248, 113, 113, .38); }
.sv-ctl-stop .ico { fill: currentColor; }
/* ⚠ Sample here is a small extra, never the main control: auto scan samples by itself. A quiet navy fill (white on it is 12:1 and better). */
.sv-sample {
  justify-self: center; height: 44px; max-width: 100%; padding: 0 13px; border-radius: 15px; min-width: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font: 600 13px/1 var(--head); color: #fff; letter-spacing: -.005em;
  background: linear-gradient(180deg, #0f2f55, #0c2646);
  border: 1px solid rgba(41, 169, 242, .4);
  transition: transform 140ms var(--spring), filter 200ms, opacity 200ms;
  overflow: hidden; white-space: nowrap;
}
.sv-sample .ico { width: 17px; height: 17px; }
.sv-sample:active { transform: scale(.95); }
.sv-sample:disabled { opacity: .5; }
.sv-sample.busy { filter: saturate(.7); }
.sv-sample.busy .ico { animation: spin 1s linear infinite; }
.sv-paused .sv-sample { filter: grayscale(.6); }

/* No floor yet. */
.sv-empty, .ed-empty { position: absolute; inset: 0; z-index: 8; display: grid; place-items: center; padding: 16px calc(var(--safe-r) + 16px) 16px calc(var(--safe-l) + 16px); overflow-y: auto; }
.sv-empty-card, .ed-empty-card { width: 100%; max-width: 420px; padding: 6px 18px 18px; animation: rise 280ms var(--ease) both; }
.sv-empty-card .empty, .ed-empty-card .empty { padding: 26px 8px 18px; }

/* The start sheet. */
.sv-mode-card {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 72px; padding: 12px 14px;
  border-radius: 18px; text-align: left; background: var(--glass); border: 1px solid var(--line);
  transition: background 200ms var(--ease), border-color 200ms, transform 120ms var(--ease);
}
.sv-mode-card:active { transform: scale(.98); }
.sv-mode-card.on { background: rgba(1, 142, 220, .14); border-color: rgba(41, 169, 242, .65); box-shadow: 0 0 0 1px rgba(41, 169, 242, .35), 0 12px 28px -16px rgba(1, 142, 220, .9); }
.sv-mode-card:disabled { opacity: .5; }
.sv-mode-icon { width: 44px; height: 44px; flex: none; display: grid; place-items: center; border-radius: 14px; background: var(--glass-2); color: var(--blue-hi); }
.sv-mode-card.on .sv-mode-icon { background: linear-gradient(140deg, var(--blue), var(--navy)); color: #fff; }
.sv-mode-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sv-mode-title { font: 700 calc(15 * var(--fs))/1.2 var(--head); }
.sv-mode-body { font-size: calc(12.5 * var(--fs)); line-height: 1.4; color: var(--ink-2); }
.sv-mode-check { width: 26px; height: 26px; flex: none; display: grid; place-items: center; border-radius: 50%; border: 1.5px solid var(--line-2); color: transparent; transition: background 200ms, color 200ms, border-color 200ms; }
.sv-mode-check .ico { width: 15px; height: 15px; stroke-width: 2.6; }
.sv-mode-card.on .sv-mode-check { background: var(--blue); border-color: var(--blue); color: #fff; }
.sv-sources { padding: 12px 14px 4px; }
.sv-sources .divider { margin: 2px 0; }
.sv-sources .toggle-hint .dot-live { width: 7px; height: 7px; margin-right: 2px; vertical-align: 1px; }
.sv-tip { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: 15px; background: rgba(1, 142, 220, .1); border: 1px solid rgba(41, 169, 242, .28); }
.sv-tip .ico { color: var(--blue-hi); margin-top: 2px; }
.sv-tip p { margin: 0; font-size: calc(13 * var(--fs)); line-height: 1.45; color: #cfe9fb; }
.sv-tip.sv-tip-warn { background: rgba(251, 191, 36, .1); border-color: rgba(251, 191, 36, .32); }
.sv-tip-warn .ico { color: var(--warn); }
.sv-tip-warn p { color: #fde68a; }

/* The summary sheet. The thumbnail is every walk on the floor, beside numbers for this one: it says so on itself. */
.sv-sum-thumb { position: relative; }
.sv-sum-thumb-label {
  position: absolute; left: 10px; top: 10px; margin: 0; padding: 5px 10px; border-radius: 999px;
  font: 600 calc(12 * var(--fs))/1.2 var(--head); color: var(--ink);
  background: rgba(5, 11, 31, .8); border: 1px solid var(--line-2);
}
.sv-sum-cov { display: flex; align-items: center; gap: 14px; padding: 12px 14px; border-radius: 18px; background: var(--glass); border: 1px solid var(--line); }
.sv-sum-cov .ring { flex: none; }
.sv-sum-cov-title { margin: 0 0 3px; font: 700 calc(15 * var(--fs))/1.2 var(--head); }
.sv-sum-cov p { margin: 0; }
.sv-sum-signal { margin-top: 8px !important; font-size: calc(13 * var(--fs)); line-height: 1.5; color: var(--ink-2); }
.sv-sum-signal .spinner { --s: 14px; vertical-align: -2px; margin-right: 6px; }
.sv-sum-signal .badge { margin-right: 2px; }
.sv-sum-list { margin: 0; padding-left: 18px; color: var(--ink-2); font-size: calc(13.5 * var(--fs)); line-height: 1.6; }

@media (max-height: 720px) {
  .sv-live-top { grid-template-columns: 108px minmax(0, 1fr); }
  .sv-gauge { width: 108px; height: 108px; }
  .sv-g-num { font-size: 27px; min-height: 27px; }
  .sv-g-sub { max-width: 108px; }
  .sv-stat { padding: 6px 7px; }
  .sv-stat-v { font-size: 15px; }
  .sv-hud { padding: 10px; gap: 8px; }
  .sv-ctl { height: 48px; }
  .sv-sag { gap: 4px; }
}
/* A phone is narrow: the words matter more than the icon on the big button. */
@media (max-width: 430px) {
  .sv-sample .ico { display: none; }
}
@media (max-width: 360px) {
  .sv-controls { grid-template-columns: 42px 42px minmax(0, 1fr) 46px 46px; gap: 6px; }
  .sv-sample { font-size: 12.5px; padding: 0 10px; }
}

/* ═══════════════════════════════════════════════════════════════════════
   PLAN EDITOR
   ═══════════════════════════════════════════════════════════════════════ */

.ed-top {
  position: absolute; z-index: 6; top: 10px;
  left: calc(var(--safe-l) + 10px); right: calc(var(--safe-r) + 10px);
  display: flex; align-items: center; gap: 8px; padding: 6px; border-radius: 22px;
  animation: drop 240ms var(--ease) both;
}
.ed-top .ed-round { width: 40px; height: 40px; background: transparent; border: 0; box-shadow: none; }
.ed-top .ed-round:active { background: var(--glass-2); }
.ed-title { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; padding-left: 2px; }
.ed-eyebrow { font: 700 10px/1 var(--head); letter-spacing: .14em; text-transform: uppercase; color: var(--blue-hi); }
.ed-floor { font: 700 15px/1.2 var(--head); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ed-top-actions { display: flex; align-items: center; gap: 2px; flex: none; }
.ed-add {
  display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 14px 0 11px; margin-left: 4px; border-radius: 14px;
  font: 700 14px/1 var(--head); color: #fff;
  background: var(--fill-blue);
  box-shadow: 0 10px 22px -10px rgba(1, 142, 220, .95), inset 0 1px 0 rgba(255, 255, 255, .28);
  transition: transform 140ms var(--spring);
}
.ed-add:active { transform: scale(.94); }
.ed-add .ico { width: 18px; height: 18px; stroke-width: 2.2; }

.ed-bottom, .ed-panel {
  position: absolute; z-index: 6;
  left: calc(var(--safe-l) + 10px); right: calc(var(--safe-r) + 10px);
  /* The view already ends at the safe area once the tab bar is put away. */
  bottom: 10px;
  max-width: 640px; margin: 0 auto;
}
.ed-bottom { display: flex; flex-direction: column; gap: 8px; background: none; border: 0; box-shadow: none; }
.ed-context { border-radius: 18px; padding: 10px 12px; display: flex; flex-direction: column; gap: 9px; }
.ed-hint { margin: 0; font-size: 13px; line-height: 1.4; color: var(--ink-2); }
.ed-options { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.ed-options .seg { min-width: 220px; }
.ed-note { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; line-height: 1.4; color: var(--ink-2); }
.ed-measure { font: 800 22px/1 var(--head); color: #fde68a; letter-spacing: -.01em; }

/* ⚠ EVERY TOOL IN SIGHT. Eight tools share the dock evenly, each at least
   44 px, so a 393 px phone shows Measure and Scale beside the rest with
   nothing to scroll to and nothing dimmed at rest. Only a screen narrower
   than eight such tools (about 375 px and under) scrolls, and then its
   edges fade from where it is (.scroll-x, base.css). */
.ed-dock { border-radius: 22px; padding: 4px; gap: 0; }
.ed-dock > .ed-tool { flex: 1 0 44px; min-width: 44px; padding: 0 1px; }
.ed-tool {
  min-width: 58px; height: 58px; padding: 0 6px; border-radius: 16px;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  font: 600 10px/1 var(--head); color: var(--ink-3);
  transition: background 200ms var(--ease), color 200ms, transform 120ms var(--ease);
}
.ed-tool:active { transform: scale(.92); }
.ed-tool .ico { width: 22px; height: 22px; }
.ed-tool.on { color: #fff; background: linear-gradient(180deg, rgba(41, 169, 242, .42), rgba(1, 142, 220, .24)); box-shadow: inset 0 0 0 1px rgba(125, 211, 252, .5), 0 8px 18px -10px rgba(1, 142, 220, .9); }
.ed-tool.on .ico { color: #e0f2fe; }

.ed-mats { gap: 6px; margin: 0 -2px; padding: 2px; max-width: 100%; }
.ed-mat {
  display: inline-flex; align-items: center; gap: 7px; height: 38px; padding: 0 11px 0 9px; border-radius: 999px;
  border: 1px solid var(--line-2); background: rgba(2, 6, 20, .45); color: var(--ink-2);
  font-size: 13px; font-weight: 600; white-space: nowrap;
  transition: background 180ms, border-color 180ms, color 180ms, transform 120ms var(--ease);
}
.ed-mat:active { transform: scale(.95); }
.ed-mat.on { color: #fff; border-color: rgba(41, 169, 242, .7); background: rgba(1, 142, 220, .2); }
.ed-swatch { width: 16px; height: 16px; flex: none; border-radius: 5px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .3), 0 0 10px -3px currentColor; }
.ed-mat-db { font: 700 11px/1 var(--mono); color: var(--ink-3); padding: 3px 6px; border-radius: 6px; background: rgba(255, 255, 255, .06); }
.ed-mat.on .ed-mat-db { color: #cfe9fb; background: rgba(41, 169, 242, .2); }

.ed-card { border-radius: 20px; padding: 12px; display: flex; flex-direction: column; gap: 10px; animation: rise 200ms var(--ease) both; }
.ed-card-head, .ed-review-head { display: flex; align-items: center; gap: 11px; min-width: 0; }
.ed-card-icon { width: 38px; height: 38px; flex: none; display: grid; place-items: center; border-radius: 12px; background: var(--glass-2); color: var(--blue-hi); }
.ed-card-icon .ed-swatch { width: 20px; height: 20px; }
.ed-card-icon.ai { background: linear-gradient(140deg, #6d5dfc, var(--blue)); color: #fff; }
.ed-card-icon.ok { background: rgba(52, 211, 153, .16); color: #6ee7b7; }
.ed-card-text { flex: 1; min-width: 0; }
.ed-card-title { margin: 0; font: 700 15px/1.25 var(--head); overflow-wrap: anywhere; }
.ed-card-sub { margin: 2px 0 0; font-size: 12.5px; line-height: 1.4; color: var(--ink-2); }
.ed-card-close { width: 40px; height: 40px; flex: none; border-radius: 12px; display: grid; place-items: center; color: var(--ink-3); }
.ed-card-close:active { background: var(--glass-2); }
.ed-card-row .seg { max-width: 320px; }
.ed-card-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* An empty plan's four ways to start, two by two above the dock. */
.ed-card.ed-start { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; padding: 8px; border-radius: 18px; }
.ed-start .btn { min-height: 44px; padding: 6px 10px; justify-content: flex-start; text-align: left; white-space: normal; line-height: 1.2; font-size: 13px; }
.ed-start .btn .ico { flex: none; }
.ed-panel .ed-card-title { font-size: calc(15 * var(--fs)); }
.ed-panel .ed-card-sub { font-size: calc(12.5 * var(--fs)); }

.ed-panel { border-radius: 24px; padding: 14px; max-height: 58%; overflow-y: auto; overscroll-behavior: contain; animation: rise 240ms var(--ease) both; }
.ed-review, .ed-walk { display: flex; flex-direction: column; gap: 12px; }
/* A group heading in a flow panel, as in a sheet: the panel's gap spaces it. */
.ed-panel .section-label { margin: 6px 2px 0; }
.ed-review-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.ed-review-actions .btn { flex: 1 1 auto; }
.ed-review-actions .btn-ghost { flex: 0 1 auto; }
.ed-steps { margin: 0; padding-left: 20px; font-size: calc(13.5 * var(--fs)); line-height: 1.55; color: var(--ink-2); }
.ed-steps li + li { margin-top: 3px; }
.ed-warn { display: flex; gap: 8px; align-items: flex-start; margin: 0; padding: 10px 12px; border-radius: 13px; font-size: calc(13 * var(--fs)); line-height: 1.45; color: #fde68a; background: rgba(251, 191, 36, .1); border: 1px solid rgba(251, 191, 36, .3); }
.ed-warn .ico { flex: none; margin-top: 1px; }
.ed-walk-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.ed-walk-stats > div { display: flex; flex-direction: column; gap: 4px; padding: 12px 10px; border-radius: 15px; background: var(--glass); border: 1px solid var(--line); }
.ed-walk-num { font: 800 22px/1 var(--head); letter-spacing: -.02em; }
.ed-walk-label { font-size: 10.5px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .08em; font-weight: 700; }
.ed-walk.live .ed-walk-stats > div:first-child { border-color: rgba(41, 169, 242, .45); box-shadow: 0 0 22px -10px rgba(41, 169, 242, .9); }

.ed-north { align-items: center; }
.ed-north-arrow { width: 40px; height: 40px; flex: none; display: grid; place-items: center; border-radius: 50%; background: var(--glass-2); color: var(--hot); transition: transform 160ms var(--ease); }
.ed-north-val { min-width: 46px; text-align: right; font: 700 calc(14 * var(--fs))/1 var(--mono); }
.ed-empty-actions { margin-top: 4px; }

/* AI: progress, photo tray, the draft's notes. */
.ed-progress { position: absolute; inset: 0; z-index: 9; display: grid; place-items: center; padding: 20px; background: rgba(2, 6, 18, .45); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); animation: fadeIn 220ms var(--ease) both; }
.ai-card { width: 100%; max-width: 360px; padding: 26px 22px 20px; border-radius: 26px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 10px; animation: rise 280ms var(--ease) both; }
.ai-scan { position: relative; width: 96px; height: 96px; display: grid; place-items: center; margin-bottom: 6px; color: #fff; }
.ai-scan .ico { position: relative; z-index: 1; filter: drop-shadow(0 0 16px rgba(109, 93, 252, .9)); }
.ai-scan i { position: absolute; inset: 0; border-radius: 50%; border: 2px solid rgba(125, 211, 252, .55); animation: ripple 2.4s var(--ease) infinite; }
.ai-scan i:nth-child(2) { animation-delay: .8s; border-color: rgba(167, 139, 250, .55); }
.ai-scan i:nth-child(3) { animation-delay: 1.6s; }
.ai-scan::before { content: ''; position: absolute; inset: 18px; border-radius: 50%; background: radial-gradient(circle, rgba(109, 93, 252, .5), rgba(1, 142, 220, .25) 60%, transparent 72%); animation: breathe 2.4s ease-in-out infinite; }
.ai-title { margin: 0; font: 800 calc(18 * var(--fs))/1.25 var(--head); letter-spacing: -.01em; }
.ai-hint { margin: 0; min-height: 20px; font-size: calc(14 * var(--fs)); color: var(--ink-2); animation: fadeIn 400ms var(--ease) both; }
.ai-bar { display: block; width: 100%; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, .08); overflow: hidden; margin: 6px 0 2px; }
.ai-bar-fill { display: block; height: 100%; border-radius: 3px; background: linear-gradient(90deg, #6d5dfc, var(--blue-hi), #a5f3fc); transform: scaleX(0); transform-origin: 0 50%; transition: transform 500ms linear; }
.ai-card .tiny { margin: 0; }
.ai-tray { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.ai-tray-empty { grid-column: 1 / -1; margin: 0; padding: 18px 14px; border-radius: 15px; border: 1.5px dashed var(--line-2); font-size: calc(13 * var(--fs)); line-height: 1.45; color: var(--ink-3); text-align: center; }
.ai-thumb { position: relative; aspect-ratio: 1; border-radius: 14px; overflow: hidden; background: var(--glass-2); border: 1px solid var(--line); display: grid; place-items: center; animation: rise 200ms var(--ease) both; }
.ai-thumb img { width: 100%; height: 100%; object-fit: cover; max-width: none; }
.ai-thumb-x { position: absolute; top: 4px; right: 4px; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; color: #fff; background: rgba(5, 11, 31, .78); border: 1px solid var(--line-2); }
.ai-thumb-x .ico { width: 16px; height: 16px; }
.ai-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; max-height: 26vh; max-height: 26dvh; overflow-y: auto; overscroll-behavior: contain; }
.ai-list li { display: flex; gap: 8px; align-items: flex-start; font-size: calc(13 * var(--fs)); line-height: 1.45; color: var(--ink-2); }
.ai-list .badge { flex: none; margin-top: 1px; }
/* The model's own words: quoted, in the plain text colour, never the app's warning styling. */
.ai-list li.ai-said { padding-left: 10px; border-left: 2px solid var(--line-2); }
.ai-details .ai-said-note { margin: 0; padding: 0 12px 12px; }
.ai-details { border-radius: 14px; background: var(--glass); border: 1px solid var(--line); }
.ai-details > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 12px;
  font: 600 calc(13.5 * var(--fs))/1.3 var(--head); color: var(--ink-2);
}
.ai-details > summary::-webkit-details-marker { display: none; }
.ai-details > summary::after { content: ''; margin-left: auto; width: 8px; height: 8px; border-right: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3); transform: rotate(45deg) translateY(-2px); transition: transform 200ms var(--ease); }
.ai-details[open] > summary::after { transform: rotate(-135deg) translateY(-2px); }
.ai-details .ai-list { padding: 0 12px 12px; }

/* ═══════════════════════════════════════════════════════════════════════
   PLAN PHOTO IMPORT
   ═══════════════════════════════════════════════════════════════════════ */

.pi-screen {
  position: fixed; inset: 0; z-index: 50;
  height: 100vh; height: 100dvh;
  display: flex; flex-direction: column;
  background: radial-gradient(120% 60% at 50% 0%, rgba(1, 142, 220, .14), transparent 60%), var(--bg);
  padding: var(--safe-t) var(--safe-r) 0 var(--safe-l);
  animation: fadeIn 200ms var(--ease) both;
  outline: none;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
.pi-head { display: flex; align-items: center; gap: 10px; padding: 10px 12px 8px; }
.pi-icon-btn { width: 44px; height: 44px; flex: none; border-radius: 14px; display: grid; place-items: center; color: var(--ink-2); background: var(--glass); border: 1px solid var(--line); }
.pi-icon-btn:active { background: var(--glass-2); transform: scale(.94); }
.pi-titles { flex: 1; min-width: 0; }
.pi-eyebrow { margin: 0 0 3px; font: 700 10.5px/1 var(--head); letter-spacing: .14em; text-transform: uppercase; color: var(--blue-hi); }
.pi-title { margin: 0; font: 800 19px/1.2 var(--head); letter-spacing: -.01em; }
.pi-dots { display: flex; gap: 6px; flex: none; padding-right: 4px; }
.pi-dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--line-2); transition: background 240ms, transform 240ms var(--spring); }
.pi-dots i.on { background: var(--blue-hi); box-shadow: 0 0 10px rgba(41, 169, 242, .8); }
.pi-stage { position: relative; flex: 1; min-height: 0; overflow: hidden; touch-action: none; }
.pi-canvas { position: absolute; left: 0; top: 0; display: block; touch-action: none; outline: none; cursor: crosshair; }
.pi-canvas:focus-visible { box-shadow: inset 0 0 0 2px var(--blue-hi); }
.pi-loupe {
  position: absolute; left: 0; top: 0; z-index: 2; pointer-events: none; border-radius: 50%;
  box-shadow: 0 18px 40px -10px rgba(0, 0, 0, .9), 0 0 0 1px rgba(255, 255, 255, .25);
  will-change: transform;
}
.pi-busy { position: absolute; inset: 0; z-index: 3; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; background: rgba(5, 11, 31, .55); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.pi-busy .spinner { --s: 34px; border-width: 3px; }
.pi-busy-text { margin: 0; font: 700 calc(15 * var(--fs))/1.3 var(--head); }
.pi-bar { display: block; width: min(260px, 70%); height: 6px; border-radius: 3px; background: rgba(255, 255, 255, .1); overflow: hidden; }
.pi-bar-fill { display: block; height: 100%; background: linear-gradient(90deg, var(--blue), var(--blue-hi), #a5f3fc); transform: scaleX(0); transform-origin: 0 50%; transition: transform 160ms linear; }
.pi-foot {
  flex: none; display: flex; flex-direction: column; gap: 10px;
  padding: 12px calc(var(--safe-r) + 14px) calc(var(--safe-b) + 14px) calc(var(--safe-l) + 14px);
  background: linear-gradient(0deg, rgba(5, 11, 31, .98), rgba(5, 11, 31, .86));
  border-top: 1px solid var(--line);
}
.pi-hint { margin: 0; font-size: calc(13.5 * var(--fs)); line-height: 1.45; color: var(--ink-2); }
.pi-controls { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.pi-controls > .btn { flex: 0 0 auto; }
.pi-controls > .pi-main { flex: 1 1 auto; }
.pi-row { display: flex; gap: 8px; width: 100%; }
.pi-row .btn { flex: 0 0 auto; }
.pi-row .pi-main { flex: 1 1 auto; }
.pi-len { display: flex; align-items: center; gap: 10px; width: 100%; }
.pi-len-label { flex: none; font: 600 calc(12 * var(--fs))/1.2 var(--head); letter-spacing: .04em; color: var(--ink-3); }
.pi-len input { flex: 1; min-width: 0; font-size: max(16px, calc(16 * var(--fs))); font-variant-numeric: tabular-nums; }
.pi-len-unit { flex: none; min-width: 24px; color: var(--ink-3); font-size: calc(14 * var(--fs)); }

@media (min-width: 900px) {
  .sv-hud { left: auto; right: calc(var(--safe-r) + 16px); width: 440px; margin: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════
   LIDAR SCAN IMPORT (map/scanimport.js)
   The guide sheet, then a full screen built on the plan photo import's
   frame (.pi-screen, .pi-head, .pi-stage, .pi-foot): a progress card while
   the worker reads the file, then the scan seen from above with what was
   measured floating on it, and the tuning controls below.
   ═══════════════════════════════════════════════════════════════════════ */

/* The guide sheet. */
.si-intro { display: flex; gap: 12px; align-items: flex-start; }
.si-intro-icon {
  width: 44px; height: 44px; flex: none; display: grid; place-items: center; border-radius: 14px; color: #fff;
  background: linear-gradient(140deg, var(--blue-hi), var(--navy));
  box-shadow: 0 10px 24px -12px rgba(1, 142, 220, .9), inset 0 1px 0 rgba(255, 255, 255, .22);
}
.si-intro-icon .ico { width: 24px; height: 24px; }
.si-intro-text { margin: 0; font-size: calc(14 * var(--fs)); line-height: 1.5; color: var(--ink-2); display: flex; flex-direction: column; gap: 6px; }
.si-intro-text p { margin: 0; }
.si-tips { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; }
.si-tips li { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 6px 12px 6px 8px; border-radius: 13px; background: var(--glass); border: 1px solid var(--line); font-size: calc(14 * var(--fs)); color: var(--ink); }
.si-tip-icon { width: 28px; height: 28px; flex: none; display: grid; place-items: center; border-radius: 9px; color: var(--blue-hi); background: rgba(41, 169, 242, .14); }
.si-tip-icon .ico { width: 17px; height: 17px; }
.si-how-steps { padding: 0 14px 12px 32px; }

/* The screen. */
.si-screen.closing { animation: fadeOut 180ms var(--ease) both; }
.si-sub { margin: 4px 0 0; font-size: 12.5px; line-height: 1.3; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.si-stage { background: var(--bg); }
.si-map { position: absolute; inset: 0; }

/* What was measured: glass chips floating over the top of the map. */
.si-chips { position: absolute; z-index: 2; top: 10px; left: 12px; right: 12px; gap: 6px; padding: 0 0 2px; pointer-events: auto; }
/* ⚠ No edge fade (.scroll-x, base.css): a mask on the row would stop its glass chips blurring the scan. */
.si-chips { -webkit-mask-image: none; mask-image: none; animation: none; }
.si-stat {
  display: flex; flex-direction: column; gap: 3px; min-width: 64px; padding: 7px 11px 8px; border-radius: 14px;
  background: rgba(5, 11, 31, .76); -webkit-backdrop-filter: saturate(160%) blur(14px); backdrop-filter: saturate(160%) blur(14px);
  border: 1px solid var(--line-2); box-shadow: 0 10px 24px -16px rgba(0, 0, 0, .9);
  animation: drop 220ms var(--ease) both;
}
.si-stat-v { font: 700 15px/1.1 var(--head); letter-spacing: -.01em; color: var(--ink); white-space: nowrap; }
.si-stat-l { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }

/* The key, bottom right (the scale bar has the bottom left). */
.si-legend {
  position: absolute; z-index: 2; right: 12px; bottom: 10px; max-width: calc(100% - 150px);
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px 12px; padding: 7px 11px; border-radius: 13px;
  background: rgba(5, 11, 31, .72); border: 1px solid var(--line); font-size: 11.5px; color: var(--ink-2); pointer-events: none;
}
.si-key { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.si-sw { --sw: #9fb3d1; width: 16px; height: 4px; flex: none; border-radius: 2px; background: var(--sw); }
.si-sw.dash { background: repeating-linear-gradient(90deg, var(--sw) 0 5px, transparent 5px 8px); }
.si-sw.door { height: 12px; width: 14px; background: none; border-left: 2px solid var(--sw); border-top: 2px dashed var(--sw); border-radius: 0 12px 0 0; }
.si-sw.gap { height: 10px; width: 16px; background: none; border-left: 2px solid var(--ink-2); border-right: 2px solid var(--ink-2); border-radius: 0; }
.si-sw.hatch { width: 14px; height: 12px; border-radius: 3px; border: 1.5px solid var(--sw); background: repeating-linear-gradient(135deg, rgba(229, 231, 235, .6) 0 1.5px, transparent 1.5px 4px); }

/* Re-running the analysis after a control changes. */
.si-working {
  position: absolute; z-index: 3; left: 50%; bottom: 58px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 14px; border-radius: 999px;
  font: 700 12.5px/1 var(--head); color: var(--ink); background: rgba(10, 22, 58, .9); border: 1px solid rgba(41, 169, 242, .45);
  box-shadow: 0 12px 28px -14px rgba(1, 142, 220, .9); animation: rise 200ms var(--ease) both;
}
.si-working .spinner { --s: 14px; border-width: 2px; }

/* Reading, and what went wrong: one card in the middle. */
.si-card-wrap { position: absolute; inset: 0; z-index: 4; display: grid; place-items: center; padding: 16px; overflow-y: auto; }
.si-card { width: 100%; max-width: 380px; padding: 24px 20px 18px; border-radius: 26px; display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; animation: rise 260ms var(--ease) both; }
.si-orbit { margin-bottom: 4px; }
.si-card-sub, .si-card-body { margin: 0; font-size: calc(13.5 * var(--fs)); line-height: 1.5; color: var(--ink-2); }
.si-card-body { font-size: calc(14.5 * var(--fs)); color: var(--ink); }
.si-card-note { margin: 0; color: var(--ink-3); }
.si-card-icon { width: 56px; height: 56px; display: grid; place-items: center; border-radius: 18px; margin-bottom: 2px; }
.si-card-icon.warn { color: #fde68a; background: rgba(251, 191, 36, .14); border: 1px solid rgba(251, 191, 36, .32); }
.si-card-icon .ico { width: 28px; height: 28px; }
.si-card-actions { display: flex; flex-direction: column; gap: 8px; width: 100%; margin-top: 6px; }
.si-card .btn-ghost { align-self: center; min-width: 140px; }
.si-card-actions .btn { width: 100%; }

.si-steps { list-style: none; margin: 6px 0 2px; padding: 0; width: 100%; display: flex; flex-direction: column; gap: 4px; text-align: left; }
.si-step { display: flex; align-items: center; gap: 11px; min-height: 34px; padding: 0 12px; border-radius: 12px; font-size: calc(14 * var(--fs)); color: var(--ink-3); transition: background 200ms var(--ease), color 200ms; }
.si-step-mark { position: relative; width: 18px; height: 18px; flex: none; border-radius: 50%; border: 1.5px solid var(--line-2); }
.si-step[data-state="active"] { color: var(--ink); background: rgba(41, 169, 242, .1); }
.si-step[data-state="active"] .si-step-mark { border-color: rgba(41, 169, 242, .35); border-top-color: var(--blue-hi); animation: spin .9s linear infinite; }
.si-step[data-state="done"] { color: var(--ink-2); }
.si-step[data-state="done"] .si-step-mark { border-color: var(--ok); background: var(--ok); }
.si-step[data-state="done"] .si-step-mark::after {
  content: ''; position: absolute; left: 5px; top: 2px; width: 4px; height: 8px;
  border: solid #04261a; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.si-bar { display: block; width: 100%; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, .08); overflow: hidden; margin: 6px 0 4px; }
.si-bar-fill { display: block; height: 100%; border-radius: 3px; background: linear-gradient(90deg, var(--blue), var(--blue-hi), #a5f3fc); transform: scaleX(0); transform-origin: 0 50%; transition: transform 240ms var(--ease); }

/* Below the map: warnings, the tuning, and the way out. */
.si-foot { max-height: 56%; overflow-y: auto; overscroll-behavior: contain; gap: 12px; }
.si-warns { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; }
.si-tune { display: flex; flex-direction: column; gap: 8px; }
.si-tune-row { display: flex; align-items: center; gap: 10px; }
.si-tune-row .seg { flex: 1; min-width: 0; }
.si-tune-row .seg-opt { min-height: 44px; }
.si-tune-label { flex: none; width: calc(46 * var(--fs)); font: 600 calc(12 * var(--fs))/1.2 var(--head); letter-spacing: .04em; color: var(--ink-3); }
.si-toggles { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 16px; }
.si-toggles.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.si-toggles .toggle { min-height: 48px; padding: 2px 0; }
.si-toggles .toggle-label { font-size: calc(14.5 * var(--fs)); }
.si-tools { display: flex; gap: 8px; }
.si-tools .btn { flex: 1 1 0; min-width: 0; min-height: 44px; padding: 0 12px; font-size: calc(14 * var(--fs)); }
.si-actions { display: flex; gap: 8px; }
.si-actions .btn { flex: 1 1 0; min-width: 0; padding: 0 14px; }
.si-actions .btn-primary { flex-grow: 1.2; }
.si-note { margin: -4px 0 0; color: var(--ink-3); line-height: 1.45; }

@media (max-width: 360px) {
  .si-toggles.two { grid-template-columns: minmax(0, 1fr); }
  .si-legend { max-width: calc(100% - 110px); }
}
@media (min-width: 720px) {
  .si-foot { padding-left: max(calc(var(--safe-l) + 14px), calc(50% - 300px)); padding-right: max(calc(var(--safe-r) + 14px), calc(50% - 300px)); }
}
