/* Landing v4 -- app/templates/landing/index_v4.html and sections/v4/.
   The kage z-stack: poster z0, canvas z1, page z10, rail z45, header z50,
   vignette z55, grain z60. Phone first, system fonts, no framework, no
   web font. Budget: this file under 20 KB. Steel theme per CLAUDE.md.
   NO scroll-behavior:smooth anywhere (probes photograph mid-glide). */

:root {
  --bg: #04060a;
  --panel: rgba(7, 10, 16, .82);
  --panel-line: rgba(212, 175, 55, .28);
  --line: #2a2a2a;
  --gold: #d4af37;
  --gold-2: #e2c252;
  --ink: #f2f2f2;
  --ink-2: #d9d9d9;
  --ink-3: #bdbdbd;
  --ink-4: #8f8f8f;
  --mono: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Menlo, Consolas, monospace;
  --header-h: 56px;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--bg); }
body.v4 {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; }
a { color: inherit; }
a:focus-visible, button:focus-visible, input:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
p { margin: 0; }
.v4-wrap { width: 100%; max-width: 1160px; margin: 0 auto; padding: 0 20px; }
.v4-icon { width: 1em; height: 1em; fill: currentColor; flex: none; }
.v4-nb { white-space: nowrap; }
.v4-dim { color: var(--ink-4); }
.v4-price { color: var(--gold); font-weight: 600; }

/* ---- the stack ------------------------------------------------------- */
.v4-poster { position: fixed; inset: 0; z-index: 0; background: var(--bg); }
.v4-poster img { width: 100%; height: 100%; object-fit: cover; display: block; }
#landing3d-root { position: fixed; inset: 0; z-index: 1; }
html.no-webgl #landing3d-root { display: none; }
.v4-page { position: relative; z-index: 10; }
.v4-rail { position: fixed; z-index: 45; }
.v4-header { position: fixed; z-index: 50; }
.v4-vignette {
  position: fixed; inset: 0; z-index: 55; pointer-events: none;
  background: radial-gradient(ellipse 120% 90% at 50% 42%, transparent 58%, rgba(0, 0, 0, .38) 100%);
}
.v4-grain {
  position: fixed; inset: 0; z-index: 60; pointer-events: none;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='128' height='128' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E");
}

/* ---- buttons ---------------------------------------------------------- */
.v4-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 22px;
  border: 2px solid transparent; border-radius: 6px;
  font-weight: 700; font-size: 16px; line-height: 1.2;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  font-family: inherit;
}
.v4-btn-gold { background: var(--gold); border-color: var(--gold); color: #000; }
.v4-btn-gold:hover { background: var(--gold-2); border-color: var(--gold-2); }
.v4-btn-ghost { border-color: rgba(255, 255, 255, .8); color: #fff; background: rgba(0, 0, 0, .35); }
.v4-btn-ghost:hover { background: rgba(255, 255, 255, .12); }
.v4-btn-sm { min-height: 36px; padding: 0 14px; font-size: 14px; }
.v4-door { color: var(--gold); text-decoration: none; font-weight: 600; }
.v4-door:hover { color: var(--gold-2); text-decoration: underline; }

/* ---- header ----------------------------------------------------------- */
.v4-header {
  top: 0; left: 0; right: 0; height: var(--header-h);
  background: linear-gradient(rgba(2, 3, 6, .88), rgba(2, 3, 6, 0));
  transition: transform .28s ease;
}
.v4-header--hidden { transform: translateY(calc(-1 * var(--header-h) - 8px)); }
.v4-header-row { display: flex; align-items: center; gap: 12px; height: var(--header-h); }
.v4-brand { display: inline-flex; align-items: center; gap: 10px; flex: none; }
.v4-brand img { width: auto; height: 30px; }
/* The round knight badge beside the wordmark — wide screens only: under
   700px the header row is already tight against the phone number. */
img.v4-brand-badge { display: none; width: 32px; height: 32px; }
.v4-header-nav { display: flex; align-items: center; gap: 14px; margin-left: auto; }
.v4-phone {
  display: inline-flex; align-items: center; gap: 7px;
  color: #fff; text-decoration: none; font-weight: 600; font-size: 15px;
}
.v4-phone:hover { color: var(--gold-2); }
.v4-header-login { color: var(--ink-3); text-decoration: none; font-size: 14px; }
.v4-header-login:hover { color: #fff; }
/* The 3D switch (LANDING_2D). ON here: gold track, knob right. The 2D
   page draws the same control OFF in its own sheet. */
.v4-toggle {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  color: var(--ink-2); text-decoration: none; font-size: 13px; font-weight: 700;
}
.v4-toggle:hover { color: #fff; }
.v4-toggle-track {
  position: relative; width: 30px; height: 16px; border-radius: 8px;
  background: var(--gold); border: 1px solid var(--gold);
}
.v4-toggle-knob {
  position: absolute; top: 1px; left: 15px; width: 12px; height: 12px;
  border-radius: 50%; background: #000;
}

/* ---- chapter rail ------------------------------------------------------ */
.v4-rail {
  right: 10px; top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 14px;
}
.v4-rail a {
  display: flex; align-items: center; gap: 8px; flex-direction: row-reverse;
  text-decoration: none; color: var(--ink-3);
}
.v4-rail-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: rgba(255, 255, 255, .28); border: 1px solid rgba(255, 255, 255, .35);
}
.v4-rail a.is-on .v4-rail-dot { background: var(--gold); border-color: var(--gold); }
.v4-rail-label {
  font-size: 12px; letter-spacing: .04em; opacity: 0;
  transition: opacity .2s ease;
}
.v4-rail a:hover .v4-rail-label, .v4-rail a:focus-visible .v4-rail-label,
.v4-rail a.is-on .v4-rail-label { opacity: 1; }

/* ---- chapters ---------------------------------------------------------- */
.v4-chapter {
  position: relative;
  min-height: 128vh;
  display: flex; align-items: center;
  padding: 18vh 0;
}
/* Rack explorer: a click on the open yard must reach the canvas (z1), and
   hit-testing stops at ANY box in the way -- so the page box and the stock
   chapter both release the point, every other chapter and the stock panel
   catch their own. The bundle arms picking only while parked on the stock
   chapter; released clicks elsewhere just fall on inert scenery. pan-y keeps
   the canvas from eating touch scroll where it is now the hit target (r3f
   sets touch-action:none for its pointer events). */
.v4-page { pointer-events: none; }
.v4-page > .v4-chapter { pointer-events: auto; }
.v4-page > .v4-stock { pointer-events: none; }
.v4-stock .v4-panel { pointer-events: auto; }
/* Products chapter releases like stock: the staged units behind the panel
   answer clicks (product cards -- PRODUCTS_CATALOG Phase 4). */
.v4-page > .v4-built { pointer-events: none; }
.v4-built .v4-panel { pointer-events: auto; }
#landing3d-root canvas { touch-action: pan-y !important; }
/* The fork walk (LANDING_V4_AISLE_WALK Phase 2): while html.v4-walking is
   set the wheel walks the eye, not the page -- scroll locks, the chapter
   chrome fades and releases its hit-testing so clicks fall through to the
   racks and yard units, and the canvas takes the whole touch (drag walks).
   The header stays live; the walk's own HUD portals to <body>, outside
   these rules. */
html.v4-walking { overflow: hidden; }
.v4-rail, .v4-panel { transition: opacity .45s ease; }
html.v4-walking .v4-rail,
html.v4-walking .v4-page .v4-panel { opacity: 0; }
html.v4-walking .v4-rail,
html.v4-walking .v4-page .v4-chapter,
html.v4-walking .v4-page .v4-chapter * { pointer-events: none !important; }
html.v4-walking #landing3d-root canvas { touch-action: none !important; }
.v4-panel {
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 10px;
  padding: 26px 22px 30px;
  max-width: 760px;
}
.v4-mark {
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  color: var(--gold); opacity: .75; margin: 0 0 10px;
}
.v4-mark::before { content: "▸ "; }
.v4-h2 { font-size: clamp(26px, 4.5vw, 38px); line-height: 1.15; margin: 0 0 10px; }
.v4-h3 { font-size: 19px; margin: 26px 0 12px; color: var(--ink); }
.v4-sub { color: var(--ink-2); margin: 0 0 18px; max-width: 52em; }

/* Gate (hero) */
.v4-gate { min-height: 178vh; align-items: flex-start; padding-top: 0; }
.v4-gate-copy {
  min-height: 100vh; min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding-top: calc(var(--header-h) + 10px); padding-bottom: 10vh;
  max-width: 700px; margin: 0;
}
.v4-kicker {
  font-family: var(--mono); font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gold); margin: 0 0 14px;
  text-shadow: 0 1px 8px rgba(0, 0, 0, .8);
}
.v4-gate h1 {
  font-size: clamp(32px, 6.4vw, 58px); line-height: 1.08;
  margin: 0 0 14px; text-shadow: 0 2px 18px rgba(0, 0, 0, .75);
}
.v4-lead {
  font-size: clamp(16px, 2.2vw, 19px); color: var(--ink-2);
  max-width: 34em; margin: 0 0 16px; text-shadow: 0 1px 10px rgba(0, 0, 0, .8);
}
.v4-cred-line {
  font-size: 14px; color: var(--ink-2); margin: 0 0 18px;
  text-shadow: 0 1px 8px rgba(0, 0, 0, .8);
}
.v4-actions { display: flex; flex-wrap: wrap; gap: 12px; margin: 0 0 18px; }
.v4-since { font-size: 13px; color: var(--ink-3); text-shadow: 0 1px 8px rgba(0, 0, 0, .8); }
.v4-scroll-cue {
  position: absolute; left: 50%; transform: translateX(-50%);
  top: calc(100vh - 64px);
  font-family: var(--mono); font-size: 11px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-3);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.v4-scroll-cue-line { width: 1px; height: 34px; background: linear-gradient(var(--gold), transparent); }

/* Shop: dense capability grid */
.v4-shop-voice { font-style: italic; color: var(--ink-2); max-width: 60em; margin: -6px 0 20px; }
.v4-shop-voice .v4-dim { font-style: normal; white-space: nowrap; }
.v4-cap-artifact { margin: 0; }
.v4-cap-artifact img {
  /* A thin band, not a hero image: the plot is proof furniture in a dense
     card, and the full 8:5 frame would double the panel's height. */
  display: block; width: 100%; height: auto; max-height: 110px;
  object-fit: cover; border-radius: 6px;
  border: 1px solid var(--line); opacity: .92;
}
/* CWB certification mark. A BADGE, not a band: `.v4-cap-artifact img` is a
   110px `object-fit: cover` strip built for wide photos and would crop a
   square seal down to a slice of gold. Direct child of `.v4-cap`, so the
   `>` rules above are untouched -- it is an <img>, not a <p> or an <h3>. */
.v4-cert-mark {
  display: block; width: 64px; height: 64px; object-fit: contain;
  align-self: flex-start;
  /* The card's 10px flex gap is tuned for text blocks; a seal wants less air
     around it than a paragraph does. */
  margin: -2px 0;
}
.v4-caps, .v4-training-cards { display: grid; grid-template-columns: 1fr; gap: 14px; }
.v4-cap {
  border: 1px solid var(--line); border-radius: 8px;
  padding: 16px 16px 18px; background: rgba(10, 13, 20, .55);
  /* One gap for every block pair, and the door on the card floor: CTAs
     share a baseline across a row however tall the copy above them ran. */
  display: flex; flex-direction: column; gap: 10px;
}
/* DIRECT CHILDREN, and the `>` is load-bearing. One of these cards now
   mounts the live Forgelet panel inside itself, and a descendant rule reaches
   every node in it: `.v4-cap p` is (0,1,1) and outranks every single-class
   rule in forgelet-theme.css, so it was silently repainting the panel's own
   paragraphs -- the 11px muted price disclaimer came out 15px in --ink-2, and
   `.forgelet-pricecard-error` would have rendered a checkout failure in calm
   grey instead of red. `.v4-cap h3` reached the checkout modal's headings the
   same way.

   Phase 2 stopped the panel's CSS leaking OUT into this page; nothing stopped
   this page leaking IN. Scoping to `>` closes the whole class rather than
   patching the properties that happened to be noticed: every card's own copy
   is a direct child (no v4 template nests a <p> or <h3> inside a card), and
   nothing the panel renders is. scripts/landing_dxf_card_smoke.mjs measures
   the computed size of two panel paragraphs to keep it that way. */
.v4-cap > h3 { margin: 0; font-size: 17px; }
.v4-cap > p { color: var(--ink-2); font-size: 15px; margin: 0; }
.v4-cap .v4-door { margin-top: auto; padding-top: 4px; align-self: flex-start; }
/* Two doors on one card (the DXF lane offers a phone door and a desktop
   door). The ROW takes the card floor, so its links must give up the auto
   margin they own when a card has only one -- left on, the first link eats
   the row's free space and the two doors stop sharing a baseline. The
   .v4-door-row margin-top:20px is meant for a panel, not a card floor
   already carrying .v4-cap's 10px gap. */
.v4-cap .v4-door-row { margin-top: auto; padding-top: 4px; }
.v4-cap .v4-door-row .v4-door { margin-top: 0; padding-top: 0; }
/* Card heading with a badge beside it. Every selector here is scoped to
   `.v4-cap-head` and every one uses `>`, for the reason spelled out above: the
   DXF card mounts a whole application inside a `.v4-cap`, and a descendant
   rule reaches into it. Nothing the Forgelet panel renders is wrapped in a
   `.v4-cap-head`, so these cannot leak the way `.v4-cap p` did.

   `.v4-cap > h3` no longer matches the heading (it is a grandchild now), so
   the two properties it supplied are restated here rather than left to the
   UA. */
.v4-cap-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
}
.v4-cap-head > h3 { margin: 0; font-size: 17px; }
.v4-cap-head > .v4-cert-mark {
  /* Smaller in a header row than it was standing alone: at 64px the seal
     out-weighed the words it certifies. `flex-shrink: 0` because a long
     heading wrapping to two lines must squeeze the text, never the badge. */
  width: 44px; height: 44px; flex-shrink: 0; margin: 0; align-self: center;
}
/* A state, not a sentence. `.v4-mark`'s monospace label idiom, turned down to
   card scale and given a rule so the hold reads as a stamp on the card rather
   than one more grey paragraph in the stack. */
.v4-note {
  border-left: 2px solid var(--gold);
  padding: 1px 0 1px 11px;
}
.v4-note > .v4-note-label {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--gold); opacity: .8;
  margin: 0 0 3px;
}
.v4-note > p { color: var(--ink-3); font-size: 13.5px; margin: 0; }
.v4-spec-list {
  margin: 0; padding: 0; list-style: none;
  color: var(--ink-3); font-size: 13.5px;
}
.v4-spec-list li { padding: 3px 0 3px 18px; position: relative; }
.v4-spec-list li::before { content: "—"; position: absolute; left: 0; color: var(--gold); opacity: .6; }


/* ---- DXF card: the in-place Forgelet quoter ---------------------------
   The card is the only one that grows a whole application inside it, so it
   takes the full grid row whenever the embed is enabled -- ALWAYS, not on
   drop. Widening it at the moment a file lands would reflow the two cards
   below out from under whoever just dropped it. */
.v4-dxf { display: block; }
.v4-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.v4-dxf-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; min-height: 132px; padding: 20px 16px; text-align: center;
  border: 1px dashed var(--gold); border-radius: 8px;
  background: rgba(212, 175, 55, .05);
  color: var(--ink-2); cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.v4-dxf-drop:hover, .v4-dxf-drop.is-hover { background: rgba(212, 175, 55, .12); }
.v4-dxf-drop-main { color: var(--gold); font-weight: 600; font-size: 15px; }
.v4-dxf-drop-sub { color: var(--ink-3); font-size: 13px; }
/* The "opening" line replaces the sub line rather than joining it -- a box
   that grows a row while you are dragging over it moves the target. */
.v4-dxf-drop-load { display: none; color: var(--ink-3); font-size: 13px; }
[data-state="loading"] .v4-dxf-drop-sub { display: none; }
[data-state="loading"] .v4-dxf-drop-load { display: block; }
/* Mounted: the panel replaces the static zone. Failed: the zone comes back
   and the doors on the card floor are the road -- never a dead card. */
[data-state="live"] .v4-dxf-drop { display: none; }
/* The sketch lane's door under the drop target: a text button, and it
   goes with the zone once the panel (which has its own tab) is live. */
.v4-dxf-alt {
  display: block; margin: 10px auto 0; padding: 0; border: 0; background: none;
  color: var(--gold); font: inherit; font-size: 13px; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.v4-dxf-alt:hover { color: #fff; }
[data-state="live"] .v4-dxf-alt { display: none; }
.v4-dxf-mount:empty { display: none; }

/* ---- BOM card: the material-list drop ---------------------------------
   Same drop-zone grammar as the DXF card, but this one never grows an app
   in place -- a good parse navigates to the review page, so the only states
   are idle, loading, and an error line under the zone. */
.v4-bom { display: block; }
.v4-bom-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; min-height: 132px; padding: 20px 16px; text-align: center;
  border: 1px dashed var(--gold); border-radius: 8px;
  background: rgba(212, 175, 55, .05);
  color: var(--ink-2); cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.v4-bom-drop:hover, .v4-bom-drop.is-hover { background: rgba(212, 175, 55, .12); }
.v4-bom-drop-main { color: var(--gold); font-weight: 600; font-size: 15px; }
.v4-bom-drop-sub { color: var(--ink-3); font-size: 13px; }
/* Reading replaces the sub line rather than joining it -- same no-moving-
   target rule as the DXF zone above. */
.v4-bom-drop-load { display: none; color: var(--ink-3); font-size: 13px; }
[data-state="loading"] .v4-bom-drop-sub { display: none; }
[data-state="loading"] .v4-bom-drop-load { display: block; }
.v4-bom-drop-err { display: block; color: #DC143C; font-size: 13px; margin-top: 8px; }
.v4-bom-drop-err:empty { display: none; }
.v4-bom-alt { color: var(--ink-3); font-size: 13px; margin: 10px 0 0; }
.v4-bom-alt a { color: var(--gold); }

/* Stock: products + teaser */
.v4-stock .v4-panel { max-width: 860px; }
.v4-counts-strip { color: var(--ink-2); margin: 0 0 6px; font-size: 15px; }
.v4-products { display: grid; grid-template-columns: 1fr; gap: 12px; }
.v4-product {
  border: 1px solid var(--line); border-radius: 8px;
  padding: 14px 14px 16px; background: rgba(10, 13, 20, .55);
  display: flex; flex-direction: column; gap: 6px;
}
.v4-product-name { margin: 0; font-size: 15.5px; font-weight: 700; }
.v4-product-specs { color: var(--ink-3); font-size: 13px; }
.v4-product-price { display: flex; align-items: baseline; gap: 10px; font-size: 17px; }
.v4-product-stock { color: var(--ink-4); font-size: 12.5px; }
.v4-product-actions { display: flex; align-items: center; gap: 14px; margin-top: auto; padding-top: 2px; }
.v4-product-actions .v4-door { white-space: nowrap; }

/* Products chapter: built-goods cards (PRODUCTS_CATALOG Phase 4). The
   .v4-built-* namespace is deliberate -- .v4-product* belongs to the stock
   chapter's store cards above. */
.v4-built .v4-panel { max-width: 860px; }
.v4-built-lede { color: var(--ink-2); margin: 0 0 14px; font-size: 15px; }
.v4-built-grid { display: grid; grid-template-columns: 1fr; gap: 12px; margin-bottom: 16px; }
.v4-built-card {
  border: 1px solid var(--line); border-radius: 8px;
  padding: 14px; background: rgba(10, 13, 20, .55);
  display: flex; flex-direction: column; gap: 6px;
}
.v4-built-img { width: 100%; max-width: 240px; height: auto; border-radius: 6px; align-self: center; }
.v4-built-name { margin: 4px 0 0; font-size: 15.5px; font-weight: 700; }
.v4-built-blurb { color: var(--ink-3); font-size: 13.5px; margin: 0; }
.v4-built-price { font-size: 17px; margin: 2px 0 4px; }
.v4-built-card .v4-door { margin-top: auto; white-space: nowrap; }
.v4-teaser-scroll { overflow-x: auto; }
.v4-teaser { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 460px; }
.v4-teaser th {
  text-align: left; color: var(--gold); font-weight: 600;
  border-bottom: 1px solid var(--panel-line); padding: 7px 10px 7px 0;
}
.v4-teaser td { border-bottom: 1px solid var(--line); padding: 7px 10px 7px 0; }
.v4-fineprint { font-size: 12.5px; margin: 10px 0 0; }
.v4-door-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 20px; }

/* Live windows (Phase 5): the screen rect is TRANSPARENT -- the pixels are
   blitted into the canvas behind the page at exactly this rect. Anything
   painted here would sit on top of them. */
.v4-views {
  display: grid; grid-template-columns: 1fr; gap: 12px;
  max-width: 760px; margin: 14px 0 0;
}
.v4-view {
  margin: 0; border: 1px solid var(--panel-line); border-radius: 8px;
  overflow: hidden; background: transparent;
}
.v4-view:hover { border-color: var(--gold); }
.v4-view-screen { aspect-ratio: 16 / 10; background: transparent; }
.v4-view-wide { max-width: 760px; margin: 14px 0 0; }

/* The laser-bed window: the reader's OWN part on the bed, so it gets the full
   strip width to itself rather than a third of a card. Server-rendered but
   [hidden] until the world reports the part actually placed — a hidden figure
   has a zero rect, which fails CardWindows' visibility cull before any render,
   so a reader who never drops a file pays nothing for it.

   It sits OUTSIDE .v4-panel, beside the other four windows, and that placement
   is load-bearing: .v4-panel and .v4-cap both paint rgba(10,13,20,.55) over
   the canvas (the page rides above it in the z-stack, per the note at the top
   of this block). Its first home was inside the DXF card, where that veil
   pinned the window's brightest pixel at 61/255 against the strip's 222 —
   a card window nested in a card is looking through half a stop of black, and
   no lamp in the world fixes it. Do not move it back in. */
.v4-view-bed { max-width: 760px; margin: 14px 0 0; }
.v4-view-note { color: var(--ink-2); font-size: 12px; }
.v4-bed-note {
  max-width: 760px; margin: 10px 0 0;
  color: var(--ink-2); font-size: 12px; line-height: 1.4;
}
.v4-view-wide .v4-view-screen { aspect-ratio: 21 / 9; }
.v4-view-cap {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px 14px; flex-wrap: wrap;
  padding: 8px 12px; background: var(--panel);
  border-top: 1px solid var(--line); font-size: 12.5px;
}
.v4-view-mark {
  font-family: var(--mono); font-size: 11px; letter-spacing: .13em;
  color: var(--gold); opacity: .8;
}
html.no-webgl .v4-view { display: none; }

/* Word reveal (Phase 5): headings are split by JS only when motion is
   welcome; without JS the heading is simply text. */
.v4-word {
  display: inline-block; opacity: 0; transform: translateY(.38em);
  transition: opacity .5s ease, transform .5s ease;
}
[data-split].is-in .v4-word { opacity: 1; transform: none; }

/* Work: proof */
.v4-quote { margin: 0 0 18px; border-left: 3px solid var(--gold); padding: 4px 0 4px 16px; }
.v4-quote p { font-size: 17px; color: var(--ink); }
.v4-quote-who { color: var(--ink-3); font-size: 14px; margin-top: 8px; }
.v4-letters { display: flex; flex-wrap: wrap; gap: 14px; margin: 0 0 14px; }
.v4-letter { display: flex; align-items: center; gap: 10px; }
.v4-letter-title { font-weight: 700; font-size: 14.5px; margin: 0; }
.v4-letter-ref { font-size: 12.5px; margin: 0; }
.v4-refs { color: var(--ink-2); margin: 0 0 14px; }
.v4-counters { display: flex; flex-wrap: wrap; gap: 22px; margin: 6px 0 14px; }
.v4-counter { display: flex; flex-direction: column; }
.v4-count { font-size: 30px; font-weight: 800; color: var(--gold); line-height: 1.1; }
.v4-count-label { font-size: 12.5px; color: var(--ink-3); }
.v4-proof-more { margin-top: 6px; }

/* Contact */
.v4-contact .v4-panel { max-width: 860px; }
.v4-contact-grid { display: grid; grid-template-columns: 1fr; gap: 20px; margin: 0 0 22px; }
.v4-contact-id { display: flex; align-items: flex-start; gap: 16px; }
.v4-badge-stamp { width: 84px; height: 84px; flex: none; opacity: .92; }
.v4-contact-name { font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--gold); margin: 0 0 6px; }
.v4-address { font-style: normal; line-height: 1.6; }
.v4-address a { color: var(--ink-2); text-decoration: none; }
.v4-address a:hover { color: #fff; }
.v4-hours { margin-top: 6px; font-size: 14px; }
.v4-contact-ways { display: flex; flex-direction: column; gap: 12px; }
.v4-contact-link {
  display: inline-flex; align-items: center; gap: 9px;
  color: var(--ink-2); text-decoration: none; font-size: 15px;
}
.v4-contact-link:hover { color: var(--gold-2); }
.v4-contact-doors { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.v4-footer-links {
  display: flex; flex-wrap: wrap; gap: 8px 18px;
  border-top: 1px solid var(--line); padding-top: 16px;
  font-size: 14px;
}
.v4-footer-links a { color: var(--ink-3); text-decoration: none; }
.v4-footer-links a:hover { color: var(--gold-2); }
.v4-copyright { margin-top: 12px; font-size: 12.5px; }

/* ---- quick purchase dialog -------------------------------------------- */
.v4-dialog {
  background: #0b0e15; color: var(--ink);
  border: 1px solid var(--panel-line); border-radius: 10px;
  padding: 0; width: min(440px, calc(100vw - 32px));
  box-shadow: 0 22px 60px rgba(0, 0, 0, .6);
}
.v4-dialog::backdrop { background: rgba(2, 3, 6, .72); }
.v4-dialog-head {
  display: flex; align-items: center; justify-content: space-between;
  margin: 0; padding: 14px 18px; border-bottom: 1px solid var(--line);
}
.v4-dialog-head h2 { margin: 0; font-size: 17px; }
.v4-dialog-close {
  background: none; border: 0; color: var(--ink-3); font-size: 24px;
  line-height: 1; cursor: pointer; padding: 2px 6px;
}
.v4-dialog-close:hover { color: #fff; }
.v4-dialog-body { padding: 16px 18px; }
.v4-dialog-name { font-weight: 700; margin: 0 0 2px; }
.v4-dialog-specs { font-size: 13.5px; margin: 0 0 4px; }
.v4-dialog-stock { color: var(--gold); font-size: 13px; margin: 0 0 14px; }
.v4-field { margin: 0 0 14px; }
.v4-field label, .v4-delivery legend { display: block; font-size: 13.5px; color: var(--ink-2); margin: 0 0 6px; }
.v4-qty-row { display: flex; align-items: center; gap: 8px; }
.v4-step {
  width: 34px; height: 34px; border-radius: 6px;
  border: 1px solid var(--line); background: #141822; color: var(--ink);
  font-size: 17px; cursor: pointer;
}
.v4-step:hover { border-color: var(--gold); }
.v4-dialog input[type="number"] {
  width: 84px; padding: 7px 10px; border-radius: 6px;
  border: 1px solid var(--line); background: #10141d; color: var(--ink);
  font: inherit; text-align: center;
}
.v4-delivery { border: 0; padding: 0; margin: 0 0 14px; }
.v4-delivery label {
  display: flex; align-items: center; gap: 8px;
  font-size: 14.5px; color: var(--ink); margin: 0 0 7px; cursor: pointer;
}
.v4-delivery input { accent-color: var(--gold); }
.v4-price-box { border-top: 1px solid var(--line); padding-top: 12px; font-size: 14.5px; }
.v4-price-box p { display: flex; justify-content: space-between; margin: 0 0 6px; }
.v4-price-total { font-size: 16.5px; font-weight: 700; }
.v4-store-ok { color: #58c17a; font-size: 14px; margin: 10px 0 0; }
.v4-store-err { color: #e26d6d; font-size: 14px; margin: 10px 0 0; }
.v4-dialog-actions {
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end;
  padding: 14px 18px; border-top: 1px solid var(--line);
}

/* ---- responsive -------------------------------------------------------- */
@media (max-width: 559px) {
  .v4-rail-label { display: none; }
  .v4-rail { right: 6px; }
  .v4-header-login { display: none; }
}
@media (max-width: 399px) {
  .v4-toggle-label { display: none; }
}
@media (min-width: 700px) {
  img.v4-brand-badge { display: block; }
  .v4-caps, .v4-training-cards, .v4-products, .v4-built-grid { grid-template-columns: 1fr 1fr; }
  .v4-caps .v4-cap-dxf { grid-column: 1 / -1; }
  .v4-views { grid-template-columns: repeat(3, 1fr); }
  .v4-work .v4-view-wide { max-width: 680px; }
  .v4-contact-grid { grid-template-columns: 1fr 1fr 1fr; }
  .v4-panel { padding: 32px 32px 36px; }
  /* Let the world show beside the copy: alternate panel pull. */
  .v4-shop .v4-panel { margin-right: auto; }
  .v4-stock .v4-panel { margin-left: auto; }
  .v4-work .v4-panel { margin-right: auto; max-width: 680px; }
  .v4-training .v4-panel { margin-left: auto; max-width: 820px; }
  .v4-contact .v4-panel { margin: 0 auto; }
}
@media (min-width: 1100px) {
  .v4-products { grid-template-columns: repeat(4, 1fr); }
}

/* ---- reduced motion / no-canvas --------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}
html.no-webgl .v4-scroll-cue-line { display: none; }
