/* ============================================================
   KitchenVis — the stock look.

   Tokens taken from the marketing site (Website/index.html) so a visitor
   crossing from kitchenvis.ai into the product does not feel the seam. Paper
   rather than white, ink rather than black, one deep green-black doing the work
   of a brand colour, and a green and a gold used sparingly.

   The rules this look is built on, all of which the previous glass theme broke:
     * NO shadows, NO blur, NO gradients. Depth comes from a hairline border
       and whitespace, nothing else.
     * ONE accent, used rarely. A page where everything is emphasised has no
       emphasis.
     * Generous type. 17px at 1.65, and headings that get properly large —
       restraint in colour buys room to be confident in scale.

   A deployment's own colours, logo and fonts still override these variables
   from the admin Branding page; the names below are unchanged for that reason.
   Light default; per-user dark toggle via data-theme on <html>.
   ============================================================ */

:root {
  /* --- The KitchenVis palette, named as the marketing site names it --------- */
  --ink:   #1b1b19;            /* body text */
  --ink-2: #54534e;            /* secondary text */
  --ink-3: #86857e;            /* captions, disabled */
  --paper: #fbfaf7;            /* page — warm, not #fff */
  --panel: #ffffff;            /* cards sit ON the paper */
  --line:  #e6e3db;            /* every border in the system */
  --deep:  #1f2a24;            /* headings, buttons: the brand colour */
  --green: #2f6d54;            /* focus rings, quiet highlights */
  --green-ink: #1a4535;        /* links — readable on paper */
  --gold:  #b3891f;            /* used once per page at most */

  /* --- The existing token names, mapped onto the palette -------------------
     Kept so every component rule, every template and the Branding page's
     CSS-var override keep working untouched. Restyling is a token swap, not a
     rewrite of 650 lines of component CSS. */
  --bg: var(--paper);
  --surface: var(--panel);
  --surface-solid: var(--panel);
  --border: var(--line);
  --text: var(--ink);
  --muted: var(--ink-2);
  --primary: var(--deep);
  --primary-contrast: #ffffff;
  --secondary: var(--green);
  --tertiary: var(--ink-3);
  --accent: var(--gold);
  --accent-contrast: #ffffff;
  /* Destructive stays red. It was riding on --accent, which is now gold — and
     a gold "delete" button is a gold "delete" button. */
  --danger: #b3261e;

  /* Typography — the system stack, so the page renders in the reader's own
     interface font and loads nothing. */
  --font-heading: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
                  Inter, Roboto, Helvetica, Arial, sans-serif;
  --font-body: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
               Inter, Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;

  /* Type scale. Base moves 15px -> 17px to match the marketing site; that is
     the single biggest contributor to the calmer feel, and it reflows every
     page by ~13% on purpose. */
  --fs-xs: .8125rem;           /* table headers, pills, captions */
  --fs-sm: .9375rem;           /* secondary text, table cells */
  --fs-base: 1.0625rem;        /* 17px — body copy, form inputs */
  --fs-lg: 1.1875rem;          /* card titles, section leads */
  --fs-md: 1.1875rem;          /* alias: admin templates use --fs-md */
  --fs-xl: 1.5rem;             /* page headings */
  --fs-2xl: 2rem;              /* screen titles */
  --fs-3xl: 3.25rem;           /* marketing / hero only */

  --blur: 0px;                 /* retained so any leftover blur() is a no-op */
  --radius: 14px;
  --radius-sm: 9px;
  --shadow: none;
  --shadow-sm: none;
  --ring: 0 0 0 2px rgba(47, 109, 84, .55);
  --maxw: 1080px;
}

/* Explicit dark (user toggled).
   The marketing site is light-only, so there is nothing to match — this is the
   same restraint inverted: near-black paper, one step of elevation, the green
   lifted enough to stay legible. */
:root[data-theme="dark"] {
  --ink:   #ececea;
  --ink-2: #a8a7a1;
  --ink-3: #7e7d77;
  --paper: #141513;
  --panel: #1c1e1b;
  --line:  #2e312c;
  --deep:  #e8e7e3;            /* on dark, the "deep" button is light on dark */
  --green: #6fbf9a;
  --green-ink: #8fd3b3;
  --gold:  #d8b45c;

  --primary-contrast: #141513;
  --accent-contrast: #141513;
  --danger: #ff8a80;
  --ring: 0 0 0 2px rgba(111, 191, 154, .55);
}

/* System dark, when the user hasn't explicitly chosen light (JS-off fallback) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink:   #ececea;
    --ink-2: #a8a7a1;
    --ink-3: #7e7d77;
    --paper: #141513;
    --panel: #1c1e1b;
    --line:  #2e312c;
    --deep:  #e8e7e3;
    --green: #6fbf9a;
    --green-ink: #8fd3b3;
    --gold:  #d8b45c;
    --primary-contrast: #141513;
    --accent-contrast: #141513;
    --danger: #ff8a80;
    --ring: 0 0 0 2px rgba(111, 191, 154, .55);
  }
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }
html, body { height: 100%; }

body {
  margin: 0;
  /* Flat. The glass theme layered two radial gradients here; depth in this
     system comes from whitespace and one hairline, never from paint. */
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.65;
  min-height: 100%;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--green-ink); text-decoration: none; }
a:hover { text-decoration: underline; }

/* --- Accessibility helpers --- */
.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--primary);
  color: var(--primary-contrast);
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  z-index: 100;
}
.skip-link:focus { left: 12px; top: 12px; }

:focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: 8px;
}

/* --- Top bar ---
   Not sticky, and not frosted. The marketing site's header scrolls away with
   the page; a sticky bar over a calm layout is a permanent piece of furniture
   competing with the content. */
.topbar {
  background: transparent;
  border-bottom: 1px solid var(--border);
}
.topbar-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 22px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.wordmark {
  font-weight: 600;
  letter-spacing: -.01em;
  font-size: 1.1875rem;
  color: var(--deep);
  display: inline-flex;
  align-items: center;
  gap: 11px;
}
.wordmark:hover { text-decoration: none; }
/* The mark is a filled tile, as on the marketing site — not a coloured glyph. */
.wordmark-mark {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--deep);
  color: var(--panel);
  display: grid;
  place-items: center;
  font-size: .9375rem;
  font-weight: 700;
  flex: none;
}

/* wrap, not nowrap: at 390px the ribbon is wider than the viewport, and a
   marketing page that scrolls sideways on a phone is one people leave. The
   header is the only place this bites — everything else is already fluid. */
.nav { display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
       justify-content: flex-end; row-gap: 6px; }
.nav-link {
  color: var(--ink-2);
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-weight: 500;
  font-size: var(--fs-sm);
}
.nav-link:hover { color: var(--deep); background: transparent; text-decoration: none; }
.nav-cta { color: var(--deep); font-weight: 600; }
.nav-logout { color: var(--ink-3); }

.icon-btn {
  cursor: pointer;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink-2);
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
}
.icon-btn:hover { border-color: var(--ink-3); color: var(--deep); }

/* --- Layout --- */
.container {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 44px 24px 80px;
}

/* --- Cards / panels — a hairline and nothing else --- */
.card, .panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
}
.card + .card, .panel + .panel { margin-top: 18px; }

h1, h2, h3 {
  font-family: var(--font-heading);
  color: var(--deep);
  margin: 0 0 .5em;
  text-wrap: balance;
}
/* Fluid, and properly large. Restraint in colour is what buys the room. */
h1 {
  font-size: clamp(2rem, 5.4vw, var(--fs-3xl));
  line-height: 1.08;
  letter-spacing: -.025em;
  font-weight: 650;
}
h2 {
  font-size: clamp(1.375rem, 3.2vw, var(--fs-2xl));
  line-height: 1.2;
  letter-spacing: -.02em;
  font-weight: 640;
}
h3 { font-size: var(--fs-lg); line-height: 1.3; font-weight: 600; }
.muted { color: var(--muted); }
/* A lead paragraph under an h1 — the marketing site's `.lede`. */
.lede { font-size: clamp(1.0625rem, 2.1vw, 1.3125rem); color: var(--ink-2); max-width: 56ch; }

/* --- Buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  padding: 13px 24px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--deep);
  transition: background .15s ease, border-color .15s ease;
}
.btn:hover { text-decoration: none; background: #f2f0ea; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn-primary {
  background: var(--deep);
  border-color: var(--deep);
  color: var(--primary-contrast);
}
.btn-primary:hover { background: #16201b; border-color: #16201b; }
.btn-accent {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}
.btn-ghost { background: transparent; color: var(--deep); border-color: var(--border); }
.btn-ghost:hover { background: #f2f0ea; }
:root[data-theme="dark"] .btn:hover,
:root[data-theme="dark"] .btn-ghost:hover { background: #242722; }
:root[data-theme="dark"] .btn-primary:hover { background: #ffffff; border-color: #ffffff; }

/* --- Forms --- */
label { display: block; font-weight: 400; font-size: var(--fs-sm); color: var(--ink-2); margin: 0 0 6px; }
.field { margin-bottom: 16px; }

input, select, textarea {
  width: 100%;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 11px 13px;
}
/* A checkbox is not a text field. The blanket `width:100%` above stretched every
   tick box to the full form width and pushed its label onto the next line —
   which on the consent boxes made "I agree" look like a heading over an empty
   row. Every page that has ever needed a checkbox has re-fixed this locally;
   fix it once, here. */
input[type="checkbox"], input[type="radio"] {
  width: auto;
  margin: 0;
  accent-color: var(--green);
}
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
}
input::placeholder, textarea::placeholder { color: var(--ink-3); }
/* An outline rather than a glow, offset so it reads as a ring and not a border
   thickening — the same treatment the marketing site's form uses. */
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--green);
  outline-offset: 1px;
  border-color: transparent;
}

/* --- A full-width bordered strip of facts (marketing site's `.strip`) --- */
.strip {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--panel);
  margin: 56px 0 0;
}
.strip-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.strip-inner > div { padding: 26px 24px; border-right: 1px solid var(--border); }
.strip-inner > div:last-child { border-right: 0; }

/* --- The one dark panel, for a single emphasis per page --- */
.split {
  background: var(--deep);
  color: #f3f1ec;
  border-radius: 18px;
  padding: 44px;
}
.split h1, .split h2, .split h3 { color: #ffffff; }
.split p { color: #c9c8c0; max-width: 60ch; }
.split .gold { color: #e2c46a; }
@media (max-width: 640px) {
  .split { padding: 28px; }
  .strip-inner > div { border-right: 0; border-bottom: 1px solid var(--border); }
}

/* --- Progress bar ---
   4px, not 12. At full width a 12px bar of near-black was the loudest thing on
   the results page — louder than the render it was describing. A fidelity score
   is a footnote to the picture; the number beneath it does the telling. */
.progress {
  position: relative;
  height: 4px;
  width: 100%;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}
.progress-bar {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--green);
  transition: width .4s ease;
}
.progress.working .progress-bar {
  background-image: linear-gradient(
    -45deg,
    rgba(255, 255, 255, .30) 25%, transparent 25%,
    transparent 50%, rgba(255, 255, 255, .30) 50%,
    rgba(255, 255, 255, .30) 75%, transparent 75%, transparent
  );
  background-size: 28px 28px;
  animation: progress-stripe 900ms linear infinite;
}
@keyframes progress-stripe {
  from { background-position: 0 0; }
  to   { background-position: 28px 0; }
}
@media (prefers-reduced-motion: reduce) {
  .progress.working .progress-bar { animation: none; }
}

/* --- Thumbnail grid --- */
.thumb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
}
.thumb {
  background: var(--surface);
  -webkit-backdrop-filter: blur(var(--blur));
  backdrop-filter: blur(var(--blur));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.thumb img {
  display: block;
  width: 100%;
  height: 150px;
  object-fit: cover;
  background: var(--border);
}
.thumb .thumb-body { padding: 10px 12px; }
.thumb .thumb-title { font-weight: 700; font-size: .92rem; }
.thumb .thumb-meta { color: var(--muted); font-size: .82rem; }
/* A transition video keeps its own aspect ratio — unlike .thumb img it is never
   cropped to a 150px strip, because a clip is the content, not a preview.
   Here rather than in a page <style> block: _video_card.html is re-served on its
   own by GET /jobs/{id}/status on every poll tick, with no page around it. */
.thumb video {
  display: block;
  width: 100%;
  height: auto;
  background: var(--border);
}
.video-slot { max-width: 560px; margin-top: 16px; }

/* Hand-off call to action beneath a finished result (strip -> refine,
   refine -> transition video). Shared, so the two pages cannot drift apart. */
.strip-cta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
.strip-cta .btn { width: auto; }
.strip-cta .muted { font-size: .85rem; }

/* --- Badges / scores --- */
.badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: .78rem;
  font-weight: 700;
  border: 1px solid var(--border);
  background: var(--surface);
}
.badge-ok { color: var(--primary); border-color: var(--primary); }
.badge-bad { color: var(--accent); border-color: var(--accent); }

/* --- Tables --- */
.table-wrap { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; }
table.data th, table.data td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
table.data th { color: var(--muted); font-weight: 700; font-size: .85rem; }

/* --- Before/after compare viewer (app.js Viz.openCompare) --- */
.cmp-overlay[hidden] { display: none; }  /* display:flex below would defeat [hidden] */
.cmp-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(6, 12, 24, .72);
  backdrop-filter: blur(6px);
}
.cmp-dialog {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(1100px, 100%);
  max-height: 100%;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface-solid);
}
.cmp-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.cmp-title { font-weight: 800; }
.cmp-stage {
  position: relative;
  overflow: hidden;
  min-height: 0;
  width: 100%;
  margin: 0 auto;              /* centred when the width cap (app.js) bites */
  aspect-ratio: 4 / 3;         /* placeholder until the render's real ratio loads */
  max-height: 72vh;
  border-radius: 10px;
  background: #0b1220;
  cursor: ew-resize;
  touch-action: none;          /* pointer-drag owns horizontal gestures */
  user-select: none;
}
.cmp-stage img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;        /* drags hit the stage, not the images */
}
.cmp-before { position: absolute; }
.cmp-after-clip { position: absolute; inset: 0; }
.cmp-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  margin-left: -1px;
  background: var(--primary-contrast);
  box-shadow: 0 0 6px rgba(0, 0, 0, .55);
}
.cmp-knob {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 5px 9px;
  border-radius: 999px;
  background: var(--surface-solid);
  border: 1px solid var(--border);
  font-size: .8rem;
  font-weight: 800;
  color: var(--text);
  white-space: nowrap;
}
.cmp-tag {
  position: absolute;
  bottom: 10px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 700;
  color: #fff;
  background: rgba(6, 12, 24, .62);
}
.cmp-tag-before { left: 10px; }
.cmp-tag-after { right: 10px; }
.cmp-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.cmp-hint { color: var(--muted); font-size: .82rem; }
.cmp-download { width: auto; }
/* Before photo unavailable: render-only view, no divider/labels. */
.cmp-no-before .cmp-handle,
.cmp-no-before .cmp-tag,
.cmp-no-before .cmp-hint { display: none; }

/* --- Pre-judge preview: banner + detection ticks (refine quality / render) --- */
.pj-stage {
  position: relative;
  border-radius: 12px;
  overflow: hidden;
  background: #0b1220;
}
.pj-stage img {
  display: block;
  width: 100%;
  max-height: 70vh;
  object-fit: contain;
}
.pj-banner {
  position: absolute;
  top: 12px;
  right: 12px;
  padding: 6px 14px;
  border-radius: 999px;
  font-size: .8rem;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #fff;
  display: none;
}
.pj-banner.show { display: inline-block; }
.pj-banner.pass { background: #1f8a4c; }
.pj-banner.recommend { background: #b8860b; }
.pj-banner.block { background: var(--accent); }
.pj-reason {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 10px 14px;
  font-size: .84rem;
  color: #fff;
  background: linear-gradient(transparent, rgba(6, 12, 24, .85));
  display: none;
}
.pj-reason.show { display: block; }
.pj-ticks {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}
.pj-ticks li { font-size: .82rem; font-weight: 600; }
.pj-ticks li.on { color: #1f8a4c; }
.pj-ticks li.off { color: var(--accent); }

/* --- Wall dimensions (strip journey: quality gate + results) ----------------
   Sits DIRECTLY BELOW the image it describes, and always OUTSIDE any polling
   slot — app.js replaces a polled card's innerHTML wholesale (static/app.js).
   A row list rather than a <table>: three columns of prose would need a
   horizontal scrollbar on a phone, and the number is the thing to read. */
.wd {
  margin: 14px 0 22px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  -webkit-backdrop-filter: blur(var(--blur));
  backdrop-filter: blur(var(--blur));
  box-shadow: var(--shadow-sm);
}
/* Match .hero-slot's cap so the block is exactly as wide as the image above it. */
.hero-wrap .wd { max-width: 560px; }

.wd-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.wd-title { font-size: var(--fs-lg); margin: 0; }
.wd-src {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
}

.wd-list { list-style: none; margin: 0; padding: 0; }
.wd-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 0;
  border-top: 1px solid var(--border);
}
.wd-row:first-child { border-top: 0; }

.wd-pos {
  flex: 0 0 auto;
  min-width: 76px;
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--primary);
}
.wd-main { flex: 1 1 200px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.wd-name { font-weight: 600; }
.wd-deriv { font-size: var(--fs-sm); color: var(--muted); }

.wd-len { flex: 0 0 auto; margin-left: auto; display: flex; align-items: baseline; gap: 8px; }
.wd-num {
  font-family: var(--font-mono);
  font-size: var(--fs-lg);
  font-weight: 800;
  font-variant-numeric: tabular-nums;   /* the column aligns down the list */
  white-space: nowrap;
}
.wd-range, .wd-qual { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted); }

/* Honesty states. A withheld measurement is NEUTRAL, never --accent: that reads
   across this app as error/destructive (.badge-bad, .pj-ticks li.off), and an
   unmeasurable wall is the system declining to guess, not the user's mistake. */
.wd-rough .wd-num { color: var(--muted); font-weight: 700; }
.wd-none .wd-name { color: var(--muted); }
.wd-nolen { font-size: var(--fs-sm); font-style: italic; color: var(--muted); }

.wd-foot { margin: 10px 0 0; font-size: var(--fs-xs); color: var(--muted); }

/* --- Zones: the runs within a wall -----------------------------------------
   Nested inside .wd-row, indented under the wall they belong to. Deliberately
   quieter than the wall line: the wall is the headline, the zones are how it
   breaks down. */
.wd-zones {
  list-style: none;
  margin: 8px 0 2px;
  padding: 0 0 0 12px;
  flex-basis: 100%;
  border-left: 2px solid var(--border);
}
.wd-zone {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  padding: 4px 0;
  font-size: var(--fs-sm);
}
.wd-zone-type {
  flex: 0 0 auto;
  min-width: 92px;
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
}
.wd-zone-main { flex: 1 1 160px; min-width: 0; display: flex; flex-direction: column; }
.wd-zone-name { font-weight: 600; }
.wd-zone-deriv { font-size: var(--fs-xs); color: var(--muted); }
.wd-zone-len { flex: 0 0 auto; margin-left: auto; display: flex; align-items: baseline; gap: 6px; }
.wd-zone-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;   /* aligns under the wall's own figure */
  white-space: nowrap;
}

/* An open stretch is real information — it is the space a new run can go into —
   so it is styled as present-but-secondary, not as a defect. */
.wd-z-open .wd-zone-name,
.wd-z-open .wd-zone-num { color: var(--muted); font-style: italic; }
.wd-z-rough .wd-zone-num { color: var(--muted); }
.wd-z-none .wd-zone-name { color: var(--muted); }

@media (max-width: 520px) {
  .wd-zones { padding-left: 8px; }
  .wd-zone-type { flex-basis: 100%; min-width: 0; }
  .wd-zone-len { flex-basis: 100%; margin-left: 0; justify-content: flex-start; }
}

/* Mobile: 520px matches the existing results-grid breakpoint. The position chip
   and the number each take a full line — no horizontal scroll. */
@media (max-width: 520px) {
  .wd { padding: 12px 14px; }
  .wd-row { gap: 6px; }
  .wd-pos { flex-basis: 100%; min-width: 0; }
  .wd-len { flex-basis: 100%; margin-left: 0; justify-content: flex-start; }
}

/* --- Published legal pages (privacy, terms) ---------------------------------
   The prose is lifted verbatim from the static site, which styled it inline.
   Those three rules are reproduced here against THIS theme's tokens rather than
   the static site's hexes, so the documents inherit whatever branding is live
   instead of pinning one palette into a legal page. Measure is capped because a
   policy nobody can read is a policy nobody has read. */
.legal { max-width: 68ch; }
.legal h2 { margin: 30px 0 8px; font-size: 1.15rem; }
.legal p, .legal li { color: var(--text); }
.legal .upd { color: var(--muted); font-size: var(--fs-sm); margin: 0 0 34px; }
.legal .box {
  background: var(--surface-solid, var(--surface));
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 18px 20px;
  margin: 22px 0;
}
