/* =====================================================================
   visibility.aitravelstudio.com — production stylesheet (Visual Blueprint 3b)
   BLI-136 · Phase 1 · AI Travel Studio
   ---------------------------------------------------------------------
   Consumes design-tokens.css. NO RAW VALUES BELOW except where a token
   is composed (gradients, shadows). Every colour is a var().

   Breakpoint note for the build: this blueprint ships fixed-width review
   canvases, so desktop layout was scoped under `.v-page--d` rather than a
   media query in the REVIEW artifact.
   BUILD CONTRACT BC-2 APPLIED (BLI-136 T8.05): every `.v-page--d X` selector
   has been converted to `@media (min-width: 900px) { X }`, mobile-first,
   declarations and source order otherwise identical
   and were authored mobile-first.
   ===================================================================== */

*, *::before, *::after { box-sizing: border-box; }

.v-page {
  background: var(--vis-cream);
  color: var(--vis-ink);
  font-family: var(--vis-font-body);
  font-size: var(--vis-body);
  line-height: var(--vis-body-lh);
  -webkit-font-smoothing: antialiased;
}

/* ---------- Type ---------- */
/* ---------------------------------------------------------------------------
   Media constraint (BLI-136 T14.10 / AC-13).

   Without this, ANY image wider than the viewport pushes the page and produces
   horizontal scroll at 375px. It is not hypothetical here: the header and footer
   both render a logo at its intrinsic size, so a single re-export at a larger
   dimension would silently break every screen at once — and it would look like
   a layout bug rather than an asset bug.

   `height: auto` keeps the aspect ratio when the width is clamped.
   --------------------------------------------------------------------------- */
img, svg, video {
  max-width: 100%;
  height: auto;
}

.v-h1, .v-h2, .v-h3 { font-family: var(--vis-font-display); font-weight: var(--vis-w-semibold); margin: 0 0 var(--vis-s4); }
.v-h1 { font-size: var(--vis-h1); letter-spacing: var(--vis-h1-track); line-height: var(--vis-h1-lh); }
.v-h2 { font-size: var(--vis-h2); letter-spacing: var(--vis-h2-track); line-height: var(--vis-h2-lh); }
.v-h3 { font-size: var(--vis-h3); letter-spacing: var(--vis-h3-track); line-height: var(--vis-h3-lh); }
.v-h4 { font-family: var(--vis-font-body); font-weight: var(--vis-w-bold); font-size: var(--vis-body-lg); margin: 0 0 var(--vis-s2); line-height: var(--vis-tight-lh); }

.v-eyebrow {
  font-size: var(--vis-caption); font-weight: var(--vis-w-bold);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--vis-ink-muted); margin: 0 0 var(--vis-s3);
}
.v-eyebrow--teal { color: var(--vis-teal-deep); }
p { margin: 0 0 var(--vis-s4); }
.v-lead { font-size: var(--vis-body-lg); color: var(--vis-ink-light); }
.v-small { font-size: var(--vis-body-sm); color: var(--vis-ink-light); }
.v-meta { font-size: var(--vis-body-sm); color: var(--vis-ins-meta); }
.v-measure { max-width: var(--vis-text-col); }
strong, b { font-weight: var(--vis-w-bold); }
a { color: var(--vis-teal); }

/* ---------- Layout ---------- */
.v-container { max-width: var(--vis-container); margin: 0 auto; padding: 0 var(--vis-gutter); }
@media (min-width: 900px) {
  .v-container { padding: 0 var(--vis-gutter-lg); }
}
.v-section { padding: var(--vis-section-y) 0; }
@media (min-width: 900px) {
  .v-section { padding: var(--vis-section-y-lg) 0; }
}
.v-section--sand { background: var(--vis-sand); }
.v-section--tight { padding: var(--vis-s8) 0; }
@media (min-width: 900px) {
  .v-section--tight { padding: var(--vis-s9) 0; }
}
.v-center { text-align: center; }
.v-center .v-measure { margin-left: auto; margin-right: auto; }
.v-split { display: grid; gap: var(--vis-s7); }
@media (min-width: 900px) {
  .v-split { grid-template-columns: 1.05fr .95fr; gap: var(--vis-s8); align-items: start; }
  .v-split--center { align-items: center; }
  .v-2up { display: grid; grid-template-columns: 1fr 1fr; gap: var(--vis-s6); }
}

/* ---------- Header / footer ---------- */
.v-header {
  display: flex; align-items: center; gap: var(--vis-s4);
  padding: var(--vis-s4) var(--vis-gutter);
  border-bottom: var(--vis-hairline); background: var(--vis-cream);
}
@media (min-width: 900px) {
  .v-header { padding: var(--vis-s5) var(--vis-gutter-lg); max-width: var(--vis-container); margin: 0 auto; }
}
.v-logo { height: 30px; width: auto; display: block; }
@media (min-width: 900px) {
  .v-logo { height: 34px; }
}
.v-header__tag { margin-left: auto; font-size: var(--vis-body-sm); color: var(--vis-ink-muted); }
.v-footer { border-top: var(--vis-hairline); padding: var(--vis-s7) var(--vis-gutter); }
@media (min-width: 900px) {
  .v-footer { padding: var(--vis-s7) var(--vis-gutter-lg); display: flex; align-items: center; gap: var(--vis-s5); max-width: var(--vis-container); margin: 0 auto; }
}
.v-footer img { height: 28px; margin-bottom: var(--vis-s3); }
@media (min-width: 900px) {
  .v-footer img { margin-bottom: 0; }
}
.v-footer p { margin: 0; font-size: var(--vis-body-sm); color: var(--vis-ink-muted); }
@media (min-width: 900px) {
  .v-footer p { margin-left: auto; }
}

/* ---------- Buttons ---------- */
.v-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--vis-s2);
  font-family: var(--vis-font-body); font-size: var(--vis-btn-size); font-weight: var(--vis-btn-weight);
  text-transform: var(--vis-btn-case); text-decoration: none;
  padding: var(--vis-btn-pad); border-radius: var(--vis-radius); border: 2px solid transparent;
  min-height: var(--vis-tap-min); cursor: pointer;
  transition: background var(--vis-motion) var(--vis-ease), border-color var(--vis-motion) var(--vis-ease);
}
.v-btn--primary { background: var(--vis-teal); color: var(--vis-white); }
.v-btn--primary:hover { background: var(--vis-teal-deep); }
.v-btn--ghost { background: var(--vis-white); color: var(--vis-teal-deep); border-color: var(--vis-teal); }
.v-btn--ghost:hover { background: var(--vis-teal-pale); border-color: var(--vis-teal-deep); }
.v-btn--sm { padding: 11px 20px; font-size: var(--vis-body-sm); min-height: 0; }
.v-btn--block { display: flex; width: 100%; }
.v-btn:focus-visible, a:focus-visible, summary:focus-visible, input:focus-visible, button:focus-visible {
  outline: var(--vis-focus-ring); outline-offset: var(--vis-focus-offset);
}

/* ---------- Cards ---------- */
.v-card {
  background: var(--vis-white); border: var(--vis-hairline);
  border-radius: var(--vis-radius); padding: var(--vis-s5);
  box-shadow: var(--vis-elevation);
}
@media (min-width: 900px) {
  .v-card { padding: var(--vis-s6); }
}
.v-card--flat { background: var(--vis-sand); box-shadow: none; border-color: var(--vis-border-strong); }
.v-card--quiet { box-shadow: none; }
.v-card + .v-card { margin-top: var(--vis-s3); }

/* ---------- Badges ---------- */
/*
 * The `hidden` attribute must actually hide things.
 *
 * The UA stylesheet applies [hidden] { display: none }, but ANY author rule
 * setting `display` outranks it. `.v-badge { display: inline-flex }` did exactly
 * that, so `badge.hidden = true` (results.js) silently did nothing and an empty
 * readiness pill rendered anyway — including on the null-score screen, where
 * readinessStatus is null and the badge is supposed to be absent entirely. The
 * markup even ships `hidden` on that span from the start, and it never took
 * effect.
 *
 * Found while checking whether `section.hidden` would work for the empty
 * dimensions block below. It would have — .v-section only sets padding — but the
 * same question asked of .v-badge turned up a live defect. Hence a global guard
 * rather than a per-class fix: the next element given a display rule must not
 * quietly stop being hideable.
 *
 * !important is correct here and not a shortcut: this must outrank every author
 * display declaration, which is precisely what the UA rule fails to do.
 */
[hidden] { display: none !important; }

.v-badge {
  display: inline-flex; align-items: center; border-radius: var(--vis-radius-pill);
  padding: 4px 14px; font-size: var(--vis-body-sm); font-weight: var(--vis-w-bold);
  letter-spacing: .02em;
  /* Readiness labels are multi-word; ~30px headroom at 375px is tighter than
     before, so a known label must not break across lines. */
  white-space: nowrap;
}
/* The raw-value fallback can receive an arbitrary wire string, which nowrap
   would make unbreakable and push off-screen (measured: 20ch +10px, 24ch +48px).
   Wrapping is restored here ONLY, so the safety net survives the nowrap above. */
.v-badge--raw { white-space: normal; }
.v-badge--good    { background: var(--vis-ins-good-bg); color: var(--vis-ins-good-ink); }
.v-badge--partial { background: var(--vis-ins-warn-bg); color: var(--vis-ins-warn-ink); }
.v-badge--bad     { background: var(--vis-ins-bad-bg);  color: var(--vis-ins-bad-ink); }
.v-badge--quiet   { background: var(--vis-sand); color: var(--vis-ink-light); }
.v-tag {
  display: inline-block; background: var(--vis-sand); color: var(--vis-ink-light);
  border-radius: var(--vis-radius-pill); padding: 3px 11px;
  font-size: var(--vis-caption); font-weight: var(--vis-w-semibold); margin-right: var(--vis-s2);
}
.v-tag--now  { background: var(--vis-ins-good-bg); color: var(--vis-ins-good-ink); }
.v-tag--soon { background: var(--vis-orange-pale); color: var(--vis-orange-deep); }

/* ---------- HERO ---------- */
.v-hero { background: linear-gradient(180deg, var(--vis-sand) 0%, var(--vis-cream) 62%); }
.v-hero .v-h1 { margin-bottom: var(--vis-s5); }
.v-hero__trust { font-size: var(--vis-body-sm); color: var(--vis-ink-muted); margin: var(--vis-s4) 0 0; }

/* =====================================================================
   THE SCORE RAIL — the §3.3 answer.
   ---------------------------------------------------------------------
   ⚠ ACCEPTANCE CRITERION (T8): measured filled width / track width must
   equal totalScore/100 within 0.5%.

   That is why NOTHING in this component uses `border`. A 1px border on
   the track reduces the content box; a 1px border on each segment eats
   fill area five times over. Both make the rail under-report the score —
   measured at 61.8–62.4% for a 63.0 score in the Phase 3a wireframes.
   The rail's entire claim is "the filled length IS the score," so that
   is a correctness bug, not a styling nit.

   Every rule below draws with inset box-shadow, which paints OVER the
   box without consuming a single pixel of layout width.
   ===================================================================== */
.v-rail { margin: 0; }
.v-rail__track {
  display: flex; width: 100%; height: var(--vis-rail-h);
  border-radius: var(--vis-rail-radius); overflow: hidden;
  background: var(--vis-rail-track);
  box-shadow: inset 0 0 0 1px var(--vis-rail-divider);   /* NOT border */
}
@media (min-width: 900px) {
  .v-rail__track { height: var(--vis-rail-h-lg); }
}
.v-rail__track--lg { height: 28px; }
@media (min-width: 900px) {
  .v-rail__track--lg { height: 34px; }
}
.v-rail__seg {
  position: relative; height: 100%;
  box-shadow: inset -1px 0 0 var(--vis-rail-divider);     /* NOT border-right */
}
.v-rail__seg:last-child { box-shadow: none; }
.v-rail__fill { display: block; height: 100%; background: var(--vis-rail-fill); }
.v-rail__seg--focus .v-rail__fill { background: var(--vis-rail-focus); }  /* fill only — no text ever sits on this */
.v-rail__key {
  display: flex; width: 100%; margin-top: var(--vis-s2);
  font-size: var(--vis-caption); font-weight: var(--vis-w-semibold);
  color: var(--vis-ins-meta); font-variant-numeric: tabular-nums;
}
.v-rail__key span { text-align: center; }
.v-rail__note { font-size: var(--vis-body-sm); color: var(--vis-ink-light); margin: var(--vis-s3) 0 0; }
.v-rail__sum { font-variant-numeric: tabular-nums; }

/* ---------- Score ring ---------- */
.v-ring {
  position: relative; flex: none; border-radius: 50%;
  width: 104px; height: 104px;
  display: grid; place-items: center;
}
@media (min-width: 900px) {
  .v-ring { width: 150px; height: 150px; }
}
.v-ring::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(var(--vis-teal) 0 calc(var(--v-score, 0) * 1%), var(--vis-sand) calc(var(--v-score, 0) * 1%) 100%);
}
.v-ring::after {
  content: ''; position: absolute; inset: 11px; border-radius: 50%; background: var(--vis-white);
  box-shadow: inset 0 0 0 1px var(--vis-border);
}
@media (min-width: 900px) {
  .v-ring::after { inset: 15px; }
}
.v-ring__num {
  position: relative; z-index: 1; text-align: center; line-height: 1;
  font-family: var(--vis-font-display); font-weight: var(--vis-w-medium);
  font-size: 34px; letter-spacing: -.02em; color: var(--vis-ink);
}
@media (min-width: 900px) {
  .v-ring__num { font-size: 48px; }
}
.v-ring__den { display: block; font-family: var(--vis-font-body); font-size: var(--vis-caption); font-weight: var(--vis-w-semibold); color: var(--vis-ins-meta); letter-spacing: .04em; margin-top: 4px; }
.v-ring--null::before { background: var(--vis-sand); }
.v-ring--null .v-ring__num { color: var(--vis-ink-muted); }

.v-scorehead { display: flex; align-items: center; gap: var(--vis-s5); }
@media (min-width: 900px) {
  .v-scorehead { gap: var(--vis-s6); }
}

/* ---------- Dimension rows ---------- */
.v-dim { border-top: var(--vis-hairline); padding: var(--vis-s4) 0; }
.v-dim:first-child { border-top: 0; padding-top: 0; }
.v-dim__head { display: flex; align-items: center; gap: var(--vis-s3); }
.v-dim__letter {
  flex: none; width: 30px; height: 30px; border-radius: var(--vis-radius-sm);
  background: var(--vis-teal-pale); color: var(--vis-teal-deep);
  display: grid; place-items: center; font-weight: var(--vis-w-bold); font-size: var(--vis-body-sm);
}
.v-dim__name { font-weight: var(--vis-w-bold); font-size: var(--vis-body); }
.v-dim__figs { margin-left: auto; text-align: right; font-variant-numeric: tabular-nums; }
.v-dim__pct { display: block; font-size: var(--vis-num-dim); font-weight: var(--vis-w-bold); line-height: 1.1; }
.v-dim__pts { display: block; font-size: var(--vis-caption); color: var(--vis-ins-meta); font-weight: var(--vis-w-semibold); }
.v-dim__bar {
  height: 8px; border-radius: var(--vis-rail-radius); overflow: hidden;
  background: var(--vis-sand); box-shadow: inset 0 0 0 1px var(--vis-rail-divider);
  margin: var(--vis-s3) 0 var(--vis-s2);
}
.v-dim__bar i { display: block; height: 100%; background: var(--vis-teal); }
.v-dim__bar--focus i { background: var(--vis-orange); }
.v-dim__desc { margin: 0 0 var(--vis-s1); font-size: var(--vis-body-sm); color: var(--vis-ink-light); }
.v-dim__meta { margin: 0; font-size: var(--vis-caption); color: var(--vis-ins-meta); }
.v-dim--muted .v-dim__name { color: var(--vis-ink-muted); }
.v-dim--muted .v-dim__letter { background: var(--vis-sand); color: var(--vis-ink-muted); }

/* ---------- Accordion (native details/summary) ---------- */
.v-act { background: var(--vis-white); border: var(--vis-hairline); border-radius: var(--vis-radius); margin-bottom: var(--vis-s3); box-shadow: var(--vis-elevation); }
.v-act > summary {
  list-style: none; cursor: pointer; padding: var(--vis-s4) var(--vis-s5);
  display: flex; align-items: center; gap: var(--vis-s3); flex-wrap: wrap;
  font-weight: var(--vis-w-bold); font-size: var(--vis-body-lg); min-height: var(--vis-tap-min);
}
.v-act > summary::-webkit-details-marker { display: none; }
.v-act__chev { margin-left: auto; flex: none; color: var(--vis-teal-deep); transition: transform var(--vis-motion) var(--vis-ease); }
.v-act[open] .v-act__chev { transform: rotate(180deg); }
.v-act[open] > summary { border-bottom: var(--vis-hairline); }
.v-act__w { font-weight: var(--vis-w-regular); font-size: var(--vis-body-sm); color: var(--vis-ins-meta); }
.v-act__body { padding: var(--vis-s4) var(--vis-s5) var(--vis-s5); }
.v-act__lead { font-size: var(--vis-body); color: var(--vis-ink-light); margin: 0 0 var(--vis-s5); }
.v-dimblock { border-left: 3px solid var(--vis-teal-pale); padding-left: var(--vis-s4); margin-bottom: var(--vis-s5); }
.v-dimblock:last-child { margin-bottom: 0; }
.v-dimblock h3, .v-dimblock h4 { margin: 0 0 var(--vis-s1); font-size: var(--vis-body); font-weight: var(--vis-w-bold); }
.v-dimblock p { margin: 0; font-size: var(--vis-body-sm); color: var(--vis-ink-light); }
.v-fam { background: var(--vis-orange-pale); border-radius: var(--vis-radius-sm); padding: var(--vis-s3) var(--vis-s4); margin-top: var(--vis-s3); font-size: var(--vis-body-sm); color: var(--vis-ink-light); }
.v-fam > b { display: block; font-size: var(--vis-caption); text-transform: uppercase; letter-spacing: .1em; color: var(--vis-orange-deep); margin-bottom: var(--vis-s1); }
.v-act__foot { margin: var(--vis-s5) 0 0; padding-top: var(--vis-s4); border-top: var(--vis-hairline); font-size: var(--vis-body-sm); color: var(--vis-ink-light); }

/* ---------- Zone labels (the Phase-1 copy safeguard) ---------- */
.v-zone {
  border-radius: var(--vis-radius); padding: var(--vis-s4) var(--vis-s5);
  font-size: var(--vis-body-sm); margin-bottom: var(--vis-s5);
  background: var(--vis-white); border: var(--vis-hairline);
  box-shadow: inset 4px 0 0 var(--vis-teal);
}
.v-zone--soon { background: var(--vis-orange-pale); border-color: var(--vis-border-strong); box-shadow: inset 4px 0 0 var(--vis-orange); }
.v-zone > b { display: block; margin-bottom: var(--vis-s1); font-size: var(--vis-body); }
.v-zone p { margin: 0; color: var(--vis-ink-light); }

/* ---------- Preview / roadmap ---------- */
.v-step { display: flex; gap: var(--vis-s4); align-items: flex-start; margin-bottom: var(--vis-s5); }
.v-step:last-child { margin-bottom: 0; }
.v-step__n {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  background: var(--vis-ink); color: var(--vis-white);
  display: grid; place-items: center; font-weight: var(--vis-w-bold); font-size: var(--vis-body-sm);
}
.v-step__thumb { background: var(--vis-sand); border-radius: var(--vis-radius-sm); box-shadow: inset 0 0 0 1px var(--vis-border-strong); margin-bottom: var(--vis-s3); display: grid; place-items: center; color: var(--vis-ink-muted); font-size: var(--vis-caption); }
.v-fan { position: relative; }
.v-fan__item { position: absolute; background: var(--vis-sand); border-radius: var(--vis-radius); box-shadow: inset 0 0 0 1px var(--vis-border-strong), var(--vis-elevation); display: grid; place-items: center; color: var(--vis-ink-muted); font-size: var(--vis-body-sm); text-align: center; padding: var(--vis-s3); }
.v-disclaimer { margin: var(--vis-s5) 0 0; padding-top: var(--vis-s4); border-top: var(--vis-hairline); font-size: var(--vis-body-sm); font-weight: var(--vis-w-semibold); color: var(--vis-ink-light); }

/* ---------- Form ---------- */
.v-field { margin-bottom: var(--vis-s5); }
.v-field label { display: block; font-weight: var(--vis-w-bold); font-size: var(--vis-body-sm); margin-bottom: var(--vis-s2); }
.v-input {
  width: 100%; height: var(--vis-input-h); padding: var(--vis-input-pad);
  font-family: var(--vis-font-body); font-size: var(--vis-body);
  color: var(--vis-ink); background: var(--vis-white);
  border: 1px solid var(--vis-border-strong); border-radius: var(--vis-radius);
}
.v-input::placeholder { color: var(--vis-ink-muted); }
.v-hint { margin: var(--vis-s2) 0 0; font-size: var(--vis-body-sm); color: var(--vis-ink-light); }
.v-field--err .v-input { border-color: var(--vis-ins-bad-ink); border-width: 2px; }
.v-err { margin: var(--vis-s2) 0 0; font-size: var(--vis-body-sm); font-weight: var(--vis-w-semibold); color: var(--vis-ins-bad-ink); }
.v-formnote { margin: var(--vis-s4) 0 0; font-size: var(--vis-body-sm); color: var(--vis-ink-light); text-align: center; }

/* ---------- Processing ---------- */
.v-prog { height: 12px; border-radius: var(--vis-rail-radius); overflow: hidden; background: var(--vis-sand); box-shadow: inset 0 0 0 1px var(--vis-rail-divider); }
@media (min-width: 900px) {
  .v-prog { height: 16px; }
}
.v-prog i { display: block; height: 100%; background: var(--vis-teal); }
.v-proghead { display: flex; justify-content: space-between; margin-top: var(--vis-s2); font-size: var(--vis-body-sm); color: var(--vis-ink-light); font-variant-numeric: tabular-nums; }
.v-dim--active { background: var(--vis-teal-pale); border-radius: var(--vis-radius-sm); padding-left: var(--vis-s4); padding-right: var(--vis-s4); margin: 0 calc(var(--vis-s4) * -1); }

/* ---------- Fixes ---------- */
.v-fix__head { display: flex; gap: var(--vis-s3); align-items: baseline; margin-bottom: var(--vis-s2); }
.v-fix__n { flex: none; width: 26px; height: 26px; border-radius: 50%; background: var(--vis-orange); color: var(--vis-ink); display: grid; place-items: center; font-weight: var(--vis-w-bold); font-size: var(--vis-body-sm); }
.v-fix p { margin: 0 0 var(--vis-s3); font-size: var(--vis-body-sm); color: var(--vis-ink-light); }

/* ---------- Copy-link control (F-D2 — must actually work) ---------- */
/*
 * flex-wrap:wrap is LOAD-BEARING and is the second half of the AC-13 fix.
 *
 * The two declarations solve OPPOSITE HALVES of one defect, and either alone is
 * broken:
 *   - Without `overflow-wrap:anywhere` on [data-copy-url], the URL is one
 *     unbreakable token setting a 220px min-content floor -> 144px of
 *     HORIZONTAL OVERFLOW.
 *   - With overflow-wrap but WITHOUT flex-wrap, that floor is removed and
 *     flex-shrink crushes the URL instead: measured at 48px wide x 357px tall,
 *     14 lines of ~2 characters, rendering as a vertical ribbon
 *     (https: / //visib / ility.ai / …) with the button stretched 373px tall.
 *     The share control becomes unusable.
 *
 * ⚠️ AND scrollWidth IS GREEN IN BOTH BROKEN STATES. The metric structurally
 * cannot tell them apart: removing the overflow is exactly what causes the
 * collapse. An overflow fix therefore needs a RENDERED check, not just a
 * re-measure of the number that prompted it.
 *
 * Measured remedy, one declaration: block 373->239px, URL 48->319px wide,
 * 14->3 lines, button 373->55px, scroll stays 375/0. align-items:flex-start and
 * flex:1 1 100% were measured as adding NOTHING and are deliberately absent.
 */
.v-copy { display: flex; flex-wrap: wrap; gap: var(--vis-s3); align-items: stretch; }
.v-copy__url {
  flex: 1; min-width: 0; height: var(--vis-input-h); padding: var(--vis-input-pad);
  background: var(--vis-sand); border: 1px solid var(--vis-border-strong); border-radius: var(--vis-radius);
  font-size: var(--vis-body-sm); color: var(--vis-ink-light);
  display: flex; align-items: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.v-copy__btn { flex: none; }
.v-copy__ok { margin: var(--vis-s3) 0 0; font-size: var(--vis-body-sm); font-weight: var(--vis-w-semibold); color: var(--vis-ins-good-ink); }

/*
 * ---------- Unbreakable-token overflow (T14.10 / AC-13) ----------
 *
 * MEASURED FAIL, not a theoretical hardening. tester-custom drove playwright at
 * 375x812 (isMobile, hasTouch, dpr 2) and the results screen came back
 * scrollWidth 519 / clientWidth 375 — 144px of horizontal scroll. Nine other
 * states were clean. Two INDEPENDENT causes, one defect class: a long URL is a
 * single unbreakable token, and under the default `overflow-wrap: normal` it
 * sets a min-content floor that no amount of flex-shrink can cross.
 *
 *   A) [data-copy-url] — the share URL, ~100px of the overflow. Worse in
 *      production, not better: the localhost URL is 69 chars, the real
 *      https://visibility.aitravelstudio.com/results?id=<uuid> is 85. Swapping
 *      it in took the overflow from +144 to +245.
 *
 *   B) .v-fix prose — the residual 44px. Engine-generated evidence embeds bare
 *      URLs ("...No destination sub-pages crawled under https://…/destinations/").
 *      DATA-DRIVEN AND SYSTEMIC: 9 bare URLs across the 22 recommendation
 *      bodies on a single real run. Any audited domain with a long path
 *      reproduces it.
 *
 * Fixing only (A) leaves +44. This is the exact fix tester-custom verified as a
 * runtime stylesheet — 375/375/0, and still passing with the production-length
 * share URL. flex-wrap and min-width:0 were measured and proved UNNECESSARY, so
 * they are deliberately not added here.
 *
 * .v-cov__item is included as a same-class extension and is NOT part of the
 * measured set — it renders API-supplied prompt text and is structurally
 * identical, it simply did not happen to overflow on the sampled payload.
 * Leaving a known-identical hole open because one payload missed it is how a
 * sweep reports clean while the defect ships.
 *
 * NOTE: `.v-copy__url` above carries min-width:0 + nowrap + ellipsis and is
 * NEVER APPLIED to any element — [data-copy-url] is a bare <p class="v-small">.
 * Dead CSS that looks like the solution is a trap; recorded rather than
 * silently deleted or silently applied (ellipsis would truncate the very URL
 * the control exists to show).
 */
[data-copy-url],
.v-fix p,
.v-fix b,
.v-cov__item,
.v-badge--raw,
.v-field__err {
  overflow-wrap: anywhere;
}

/* ---------- Error / limit states ---------- */
.v-state { text-align: center; max-width: 560px; margin: 0 auto; }
.v-state__icon {
  width: 60px; height: 60px; margin: 0 auto var(--vis-s5); border-radius: var(--vis-radius);
  display: grid; place-items: center; background: var(--vis-orange-pale); color: var(--vis-orange-deep);
}
.v-state__icon--bad { background: var(--vis-ins-bad-bg); color: var(--vis-ins-bad-ink); }
.v-state p { color: var(--vis-ink-light); }

/* ---------- Desktop-only composition ---------- */
@media (min-width: 900px) {
  .v-acts { max-width: 900px; margin: 0 auto; }
  .v-act__2up { display: grid; grid-template-columns: 1fr 1fr; gap: var(--vis-s5); }
  .v-narrow { max-width: 900px; margin-left: auto; margin-right: auto; }
  .v-wide { max-width: 1060px; margin-left: auto; margin-right: auto; }
  .v-fan { width: 700px; height: 330px; flex: none; }
  .v-fanrow { display: flex; gap: var(--vis-s7); align-items: flex-start; }
  .v-step { margin-bottom: var(--vis-s5); }
}

/* ---------- A11y ---------- */
.v-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.v-skip {
  position: absolute; left: var(--vis-s4); top: calc(var(--vis-s4) * -4);
  background: var(--vis-teal-deep); color: var(--vis-white);
  padding: var(--vis-s3) var(--vis-s4); border-radius: var(--vis-radius); z-index: 20;
  transition: top var(--vis-motion) var(--vis-ease);
}
.v-skip:focus { top: var(--vis-s4); }

@media (prefers-reduced-motion: reduce) {
  .v-act__chev, .v-btn, .v-skip { transition: none; }
}
