/* ═══════════════════════════════════════════════════════════════════════════
   MARBLELENS · THE LIVE DESIGN ENGINE

   Two layers occupy the same box: a graphite WIREFRAME that is always there,
   and a SKIN of the current business painted on top of it. `--fill` is the
   material level. At 1 the skin is flooded and you see a finished website; at
   0 it has drained away and you see the structure that was under it the whole
   time. Nothing crossfades — a surface is either holding pigment or it isn't.

   Per-surface stagger (--s) makes the material arrive THROUGH the structure
   instead of as one flat wipe, so a paused frame reads as a site mid-build.

   The preview is a real container-query container. Its layout responds to its
   own width, so narrowing it is genuine reflow, never a scaled picture.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 620vh → 434vh in the pacing pass: the palette drain / content swap /
   flood cycle reads at 30% less travel and gains momentum by it. */
.lab-stage { position: relative; height: 434vh; margin-top: var(--sec-gap); }
.lab-travel { position: absolute; inset: 0; pointer-events: none; }
.lab-sticky {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  display: grid; grid-template-rows: 1fr auto;
  align-content: center; justify-items: center; gap: clamp(0.6rem, 1.6vh, 1.2rem);
  padding: clamp(4.2rem, 9vh, 5.6rem) var(--gutter) clamp(1rem, 3vh, 2rem);
}

.lab {
  --fill: 1; --mid: 0; --out: 0;
  --w-bg: #f4efe3; --w-ink: #2c1d13; --w-accent: #b4762e;
  --w-display: var(--serif); --w-ui: var(--sans);
  --w-radius: 2px; --w-pad: 34px; --w-title: 44px; --w-split: 1fr 1fr;
  width: 100%; max-width: var(--container-wide);
  display: grid; grid-template-columns: minmax(0, 0.22fr) minmax(0, 1fr) minmax(0, 0.18fr);
  gap: clamp(1rem, 2.4vw, 2.2rem); align-items: center;
}

/* ── SYSTEM · the tokens, not decoration ─────────────────────────────────*/
.lab-cap {
  font-family: var(--mono); font-size: 0.56rem; letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--graphite-2); margin-bottom: var(--s-3);
}
.sys { margin: 0; display: grid; gap: 0.42rem; }
.sys-row {
  display: grid; grid-template-columns: 4.6rem 1fr; gap: 0.5rem; align-items: baseline;
  font-family: var(--mono); font-size: clamp(0.56rem, 0.78vw, 0.7rem);
  padding-bottom: 0.42rem; border-bottom: 1px solid var(--line-2);
}
.sys-row dt { color: var(--graphite-2); letter-spacing: 0.08em; }
.sys-row dd {
  margin: 0; color: var(--ink); letter-spacing: 0.04em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* the accent row carries the actual colour it names */
.sys-row[data-k="accent"] dd { display: flex; align-items: center; gap: 0.45em; }
.sys-row[data-k="accent"] dd::before {
  content: ""; width: 9px; height: 9px; border-radius: 2px;
  background: var(--chip, var(--w-accent)); box-shadow: 0 0 0 1px rgba(31,31,28,.16);
  flex: none;
}
/* a value that is currently being rewritten is briefly held in graphite */
.lab.draining .sys-row dd { color: var(--graphite-2); }
.sys-bar { margin-top: var(--s-4); height: 1px; background: var(--line); overflow: hidden; }
.sys-bar i { display: block; height: 100%; background: var(--accent);
  transform-origin: left; transform: scaleX(0); }

/* ── PREVIEW ─────────────────────────────────────────────────────────────*/
.lab-preview { min-width: 0; display: grid; justify-items: center; }
.viewport { --vw: 1240px; --scale: 1; width: 100%; display: grid; justify-items: center; gap: var(--s-3); }
.vp-frame {
  position: relative;
  width: 100%; aspect-ratio: 16 / 10;
  background: var(--paper-hi); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--sh-lift);
  padding: clamp(6px, 0.6vw, 10px); overflow: hidden;
}
/* The real container. Its width is the LOGICAL device width — 1240px even when
   the frame on screen is 700 — so the container query fires on the value that
   matters. The transform only fits it into the frame.
   ABSOLUTE deliberately: a transform scales what is painted, never what is
   laid out, so in flow this would claim 1240px of min-content and burst the
   whole section on a phone. */
.vp-screen {
  container-type: inline-size;
  position: absolute; overflow: hidden;
  top: clamp(6px, 0.6vw, 10px); left: clamp(6px, 0.6vw, 10px);
  width: var(--vw); height: calc(var(--vw) / 1.6);
  transform: scale(var(--scale)); transform-origin: top left;
  background: var(--paper);
  border-radius: var(--radius-sm);
}
.vp-w { font-family: var(--mono); font-size: var(--t-label);
  letter-spacing: 0.16em; color: var(--graphite); }

/* the structure that was always underneath */
.wf { position: absolute; inset: 0; z-index: 0; opacity: calc(0.15 + var(--mid) * 0.85); }
.wf::before, .wf::after { content: ""; position: absolute; inset: 0; }
.wf::before {
  background-image:
    linear-gradient(var(--graphite-2) 1px, transparent 1px),
    linear-gradient(90deg, var(--graphite-2) 1px, transparent 1px);
  background-size: 6cqw 6cqw; opacity: 0.3;
}
.wf::after {
  /* the page's own skeleton, drawn in graphite */
  background:
    linear-gradient(var(--graphite) 0 0) no-repeat 0 9cqw / 100% 1px,
    linear-gradient(var(--graphite-2) 0 0) no-repeat 6cqw 20cqw / 34cqw 1px,
    linear-gradient(var(--graphite-2) 0 0) no-repeat 6cqw 26cqw / 26cqw 1px,
    linear-gradient(var(--graphite-2) 0 0) no-repeat 6cqw 46cqw / 88cqw 1px;
  opacity: 0.5;
}

/* ── THE SITE · real DOM, real text ──────────────────────────────────────*/
.site {
  position: absolute; inset: 0; z-index: 1;
  display: grid; grid-template-rows: auto auto 1fr;
  font-family: var(--w-ui);
  color: var(--w-ink);
  /* the ground itself is material: it drains with everything else */
  background: linear-gradient(var(--w-bg) 0 0) no-repeat;
  background-size: 100% calc(var(--fill) * 100%);
  transition: none;
}
/* every surface fills from the bottom, each a little behind the last (--s) */
.site .s-cta, .site .s-btn, .site .s-card-art, .site .art {
  --s: 0;
  background-image: linear-gradient(var(--w-accent) 0 0);
  background-repeat: no-repeat;
  background-position: bottom;
  background-size: 100% calc(clamp(0, (var(--fill) - var(--s)) / (1 - var(--s)), 1) * 100%);
}
/* THE EXPOSED STRUCTURE.
   When the material drains, the site's OWN boxes outline themselves in
   graphite — so what is revealed is the real structure of the layout that was
   just there, and it differs per business because the geometry does. Drawing a
   generic grid instead would make every drained frame identical and empty,
   and the drained frame is the most interesting composition in the section. */
.site .s-cta, .site .s-btn, .site .s-card-art, .site .art, .site .s-hero-art {
  box-shadow: inset 0 0 0 1px rgba(110, 106, 99, calc(var(--mid) * 0.75));
}
.site .s-hero-art { border-radius: var(--w-radius); }
/* type holds its place as a graphite rule while its words are being changed */
.s-head::after, .s-lede::after { content: none; }
.lab.draining .s-head, .lab.draining .s-lede, .lab.draining .s-card b,
.lab.draining .s-logo, .lab.draining .s-links {
  color: transparent;
  background: linear-gradient(rgba(110,106,99,calc(var(--mid) * 0.5)) 0 0) no-repeat;
  background-size: 100% 1px; background-position: 0 88%;
}

.s-nav {
  display: flex; align-items: center; gap: 3cqw;
  padding: 4cqw var(--w-pad); border-bottom: 1px solid rgba(31,31,28,.10);
  opacity: var(--fill);
}
.s-logo {
  font-family: var(--w-display); font-weight: 700;
  font-size: 2.4cqw; letter-spacing: 0.16em;
}
.s-links { display: flex; gap: 2.4cqw; margin-left: auto; font-size: 1.5cqw;
  letter-spacing: 0.04em; opacity: 0.72; }
.s-cta {
  --s: 0.35;
  padding: 1.1cqw 2.4cqw; font-size: 1.4cqw; color: var(--w-bg);
  border-radius: var(--w-radius); white-space: nowrap;
}
.s-hero {
  display: grid; grid-template-columns: var(--w-split);
  gap: 4cqw; align-items: center; padding: 5cqw var(--w-pad);
}
.s-head {
  font-family: var(--w-display); font-weight: 700;
  font-size: calc(var(--w-title) * 0.1cqw * 10 / 12.4);
  line-height: 1.04; letter-spacing: -0.01em; margin: 0 0 2cqw;
  white-space: pre-line; color: var(--w-ink);
  opacity: var(--fill);
}
.s-lede { font-size: 1.6cqw; opacity: calc(var(--fill) * 0.74); margin-bottom: 3cqw; }
.s-btn {
  --s: 0.5;
  display: inline-block; padding: 1.4cqw 3cqw; font-size: 1.5cqw;
  color: var(--w-bg); border-radius: var(--w-radius);
}
/* the product, drawn. Geometry changes per business — this is layout proof,
   not a swapped photograph. */
.s-hero-art { position: relative; aspect-ratio: 4 / 3; }
.art { position: absolute; border-radius: var(--w-radius); }
[data-art="bag"] .art-a { left: 22%; right: 22%; top: 6%; bottom: 0; --s: 0.1; border-radius: 2px 2px 0 0; }
[data-art="bag"] .art-b { left: 30%; right: 30%; top: 0; height: 12%; --s: 0.3; opacity: 0.55; }
[data-art="plate"] .art-a { left: 12%; right: 12%; top: 10%; bottom: 10%; border-radius: 50%; --s: 0.1; }
[data-art="plate"] .art-b { left: 30%; right: 30%; top: 28%; bottom: 28%; border-radius: 50%; --s: 0.4; opacity: 0.5; }
[data-art="bottle"] .art-a { left: 36%; right: 36%; top: 14%; bottom: 0; --s: 0.1; border-radius: 14px 14px 4px 4px; }
[data-art="bottle"] .art-b { left: 43%; right: 43%; top: 0; height: 18%; --s: 0.35; border-radius: 4px; }

.s-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.4cqw;
  padding: 0 var(--w-pad) 5cqw; align-content: start; }
.s-card { display: grid; gap: 1.2cqw; }
/* tinted, not solid: three full-accent panels turn a restrained palette into
   a block of colour, and the accent belongs on the product and the action */
.s-card-art {
  display: block; height: 9cqw; border-radius: var(--w-radius);
  background-image: linear-gradient(
    color-mix(in srgb, var(--w-accent) 24%, var(--w-bg)) 0 0);
}
.s-card:nth-child(1) .s-card-art { --s: 0.55; }
.s-card:nth-child(2) .s-card-art { --s: 0.66; }
.s-card:nth-child(3) .s-card-art { --s: 0.77; }
.s-card b { font-size: 1.5cqw; font-weight: 600; opacity: var(--fill); }

/* GENUINE REFLOW — container queries on the preview's own width */
@container (max-width: 900px) {
  .s-links { display: none; }
  .s-hero { grid-template-columns: 1fr; gap: 3cqw; }
  .s-hero-art { aspect-ratio: 16 / 9; }
  .s-head { font-size: 5.4cqw; }
  .s-lede, .s-btn, .s-cta, .s-card b { font-size: 2.2cqw; }
  .s-logo { font-size: 3.4cqw; }
}
@container (max-width: 560px) {
  .s-nav { padding: 5cqw 5cqw; }
  .s-hero { padding: 6cqw 5cqw; }
  .s-cards { grid-template-columns: 1fr; gap: 3cqw; padding: 0 5cqw 6cqw; }
  .s-card-art { height: 18cqw; }
  .s-head { font-size: 7cqw; }
  .s-lede, .s-btn, .s-cta, .s-card b { font-size: 3.2cqw; }
  .s-logo { font-size: 4.4cqw; }
}

/* ── IDENTITY ────────────────────────────────────────────────────────────*/
.lab-id { min-width: 0; }
.id-brand { font-family: var(--serif); font-weight: 700;
  font-size: clamp(1rem, 1.5vw, 1.4rem); letter-spacing: 0.1em; color: var(--ink); }
.id-genre { font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--graphite); margin-top: 0.3em; }
.id-pal { display: flex; gap: 5px; margin: var(--s-3) 0 0; padding: 0; list-style: none; }
.id-pal li { width: 16px; height: 16px; border-radius: 2px; box-shadow: 0 0 0 1px rgba(31,31,28,.14); }

/* ── THE CONCLUSION ──────────────────────────────────────────────────────*/
.lab-out {
  margin: 0; opacity: var(--out, 0);
  transform: translateY(calc((1 - var(--out, 0)) * 10px));
  pointer-events: none;
}
.lab-out.on { pointer-events: auto; }
.lab-legend {
  display: block; margin-top: var(--s-5); text-align: center;
  font-size: var(--t-small); color: var(--graphite);
}

/* ── RESPONSIVE COMPOSITION · recombined, not shrunk ─────────────────────*/
@media (max-width: 1100px) {
  .lab { grid-template-columns: minmax(0, 0.28fr) minmax(0, 1fr); }
  .lab-id {
    grid-column: 1 / -1; display: flex; align-items: baseline; gap: var(--s-4);
    padding-top: var(--s-3); border-top: 1px solid var(--line);
  }
  .lab-id .lab-cap { margin: 0; }
  .id-genre { margin: 0; }
  .id-pal { margin: 0 0 0 auto; }
}
@media (max-width: 820px) {
  /* the preview takes the room; the system peeks from beneath it, which is
     the honest mobile version of "code changes, site changes" */
  .lab-stage { height: 364vh; }
  .lab { grid-template-columns: 1fr; gap: var(--s-3); }
  .lab-preview { order: -1; }
  .lab-system { width: 100%; }
  .sys { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.3rem 1rem; }
  .sys-row { grid-template-columns: 3.6rem 1fr; padding-bottom: 0.3rem; }
  .sys-bar { margin-top: var(--s-3); }
  .vp-frame { aspect-ratio: 4 / 3; }
}
@media (max-width: 520px) {
  .lab-stage { height: 322vh; }
  .sys { grid-template-columns: 1fr; }
  .sys-row:nth-child(n+5) { display: none; }   /* four tokens is enough here */
  .lab-id { flex-wrap: wrap; gap: var(--s-2) var(--s-3); }
}

/* ── REDUCED MOTION · resolved, real and usable ─────────────────────────*/
@media (prefers-reduced-motion: reduce) {
  .lab-stage, .lab-stage.is-static { height: auto; }
  .lab-sticky { position: static; height: auto; padding-block: 0; }
  .lab-out { opacity: 1; transform: none; pointer-events: auto; }
  .sys-bar i { transform: scaleX(1); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE PAGE SHOT 07 BUILT, NOW ACTUALLY RUNNING

   This block is what the section OPENS with, before the chapter heading. It
   exists because of what used to be in that position: the beat spent 28
   seconds turning paper into a website, the pin let go, and a new chapter
   immediately announced itself — the proof evaporated at the exact moment it
   should have become usable.

   CONTINUITY IS THE GENERATED PIXELS. Every image in this block is a straight
   rectangular crop of a decoded frame of the film the beat above scrubs — the
   bottle at 8.5s, the product row at 18.3s, the campaign at 22.0s, the finished
   website at 30.0s — now in a real fluid grid at real size. Nothing is redrawn
   and nothing is reconstructed; the frame stops being a film and becomes media.
   Re-cut with site/tools/cut-site-media.py if the take is ever replaced. These
   were Shot 03's crops until this film landed, and a stale set puts the beat
   the film REPLACED directly underneath it.

   AND THE MOTION STOPS. There is no scroll-linked anything below this line and
   no entrance animation: the cinematic vocabulary belongs to the beat above,
   and a real page simply is. The only movement left is the CTA answering a
   pointer, which is feedback, not choreography.
   ═══════════════════════════════════════════════════════════════════════════ */
.live-site {
  width: 100%; max-width: var(--container-wide);
  margin-inline: auto; padding-inline: var(--gutter);
  /* it sits at the very top of the section, so it takes the section's own top
     padding rather than adding a second one */
  padding-block-end: var(--sec-gap);
}

/* ── HERO ─────────────────────────────────────────────────────────────────
   Two columns that are genuinely two columns, not a scaled picture of them.
   The switch is a single container-driven decision, not a stack of patches. */
.ls-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(1.75rem, 1rem + 4vw, 5rem);
}
.ls-say { display: flex; flex-direction: column; align-items: start; gap: clamp(0.7rem, 0.4rem + 0.9vw, 1.15rem); }

.ls-eyebrow {
  font-family: var(--mono); font-size: clamp(0.62rem, 0.55rem + 0.2vw, 0.74rem);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--graphite);
}
.ls-title {
  font-family: var(--serif); font-weight: 600;
  /* the one place on this page allowed to be large */
  font-size: clamp(2rem, 1.1rem + 3.6vw, 4rem);
  line-height: 1.04; letter-spacing: -0.005em; color: var(--ink);
  max-width: 18ch;
}
.ls-copy {
  font-size: clamp(0.95rem, 0.88rem + 0.36vw, 1.12rem);
  line-height: 1.58; color: var(--ink); opacity: 0.82;
  max-width: 46ch;
}
.ls-act {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(0.8rem, 0.5rem + 1vw, 1.6rem);
  margin-top: clamp(0.35rem, 0.2rem + 0.6vw, 0.9rem);
}
/* the primary control is the SAME control the chapter heading already offers
   (data-create="website"), styled as this page's own rather than re-invented */
.ls-cta {
  display: inline-flex; align-items: center; gap: 0.7em;
  padding: 0.85em 1.4em; cursor: pointer;
  font-family: var(--sans); font-weight: 600; font-size: var(--t-small);
  color: var(--ink); background: var(--paper-hi);
  border: 1px solid var(--accent); border-radius: var(--radius-sm);
  box-shadow: var(--sh-pin);
  transition: transform var(--dur-fast) var(--ease-mount),
              box-shadow var(--dur-fast) var(--ease-out),
              background var(--dur-fast);
}
.ls-cta:hover  { transform: translateY(-2px); box-shadow: var(--sh-mount); background: var(--paper); }
.ls-cta:active { transform: translateY(0) scale(0.985); }
.ls-cta .arr   { transition: transform var(--dur-fast) var(--ease-out); }
.ls-cta:hover .arr { transform: translateX(3px); }
.ls-alt {
  padding: 0; cursor: pointer; background: none; border: 0;
  font-family: var(--mono); font-size: clamp(0.68rem, 0.62rem + 0.2vw, 0.78rem);
  letter-spacing: 0.06em; color: var(--graphite);
  border-bottom: 1px solid var(--line); padding-bottom: 0.2em;
  transition: color var(--dur-fast), border-color var(--dur-fast);
}
.ls-alt:hover { color: var(--ink); border-color: var(--ink); }

/* the media is the generated frame, mounted — not framed in a device */
.ls-media { margin: 0; }
.ls-media img {
  display: block; width: 100%; height: auto;
  /* the crop already carries the sheet's own cut edge and shadow, so the page
     must not add a card, a border or a radius around it */
}

/* ── THE LOWER-EDGE CUE ───────────────────────────────────────────────────
   A rule and a label. Not a bouncing chevron and not a scroll hint: the page
   says there is more by naming what is next. */
.ls-more {
  display: flex; align-items: center; gap: 0.9em;
  margin-top: clamp(2.5rem, 1.5rem + 4vw, 5.5rem);
  font-family: var(--mono); font-size: clamp(0.62rem, 0.57rem + 0.18vw, 0.74rem);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--graphite);
}
.ls-more .ls-rule { flex: 0 0 clamp(2rem, 6vw, 5rem); height: 1px; background: var(--line); }

/* ── ONE BAND, THEN STOP ──────────────────────────────────────────────────
   Enough continuation to prove the hero became a page. auto-fit means the
   count reflows on its own; there is no per-breakpoint card rule. */
.ls-band {
  margin-top: clamp(1rem, 0.6rem + 1.6vw, 2rem);
  display: grid; gap: clamp(1rem, 0.6rem + 2vw, 2.4rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}
.ls-card { margin: 0; }
/* ONE ASPECT ACROSS THE ROW. The three crops come out of different frames at
   different shapes (the still is 1.06, the other two ~1.36), so at natural
   height the cards ended at three different depths and their captions stepped
   down the row like a broken staircase. A shared ratio + cover is an OUTER
   presentation crop of an already-cropped frame — it alters no pixel inside one
   — and it is what makes the three read as a set rather than three leftovers. */
.ls-card img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 4 / 3; object-fit: cover; object-position: center;
}
.ls-card figcaption {
  margin-top: 0.85em;
  font-size: clamp(0.82rem, 0.78rem + 0.2vw, 0.94rem);
  line-height: 1.5; color: var(--ink); opacity: 0.78;
}
.ls-card figcaption b {
  display: block; font-family: var(--mono); font-weight: 500;
  font-size: 0.72em; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--graphite); opacity: 1; margin-bottom: 0.35em;
}

/* ── REFLOW, NOT SHRINK ───────────────────────────────────────────────────
   `display: contents` dissolves .ls-say so its children become grid items of
   .ls-hero directly and can be ordered around the media. That is what gives
   the phone the reading order the desktop cannot have — headline, then the
   visual, then the explanation, then the control — instead of a narrower
   version of a two-column layout. */
@media (max-width: 900px) {
  .ls-hero { grid-template-columns: 1fr; gap: clamp(1rem, 0.6rem + 2vw, 1.8rem); }
  .ls-say { display: contents; }
  .ls-eyebrow { grid-row: 1; }
  .ls-title   { grid-row: 2; max-width: 20ch; }
  /* CAP THE MEDIA ONCE IT IS STACKED. Full-bleed is right on a phone, but the
     same rule on a 768 tablet gave the hero image ~1300px of a 1024 viewport —
     you got a headline, then a wall of bottle, and had to scroll twice to reach
     the sentence explaining it. Capping the WIDTH (not the height) shrinks it
     proportionally and never crops the crop. Below ~544px the cap is inert, so
     phones keep the full-bleed image they should have. */
  .ls-media {
    grid-row: 3; margin-block: clamp(0.3rem, 1vw, 0.9rem);
    width: 100%; max-width: 34rem; justify-self: start;
  }
  .ls-copy    { grid-row: 4; }
  .ls-act     { grid-row: 5; }
}
