/* ============================================================
 * Conditions — deck-specific additions on top of styles.css
 * Loaded AFTER styles.css, so equal-specificity rules here win.
 * ============================================================ */

/* ---- Shot = tile (clipped, fixed ratio) + caption (outside) --
 * styles.css gives .tile `overflow:hidden` + a fixed aspect-ratio,
 * so anything inside it gets cropped. Captions live outside it.
 * ------------------------------------------------------------ */
.shot { margin: 0; }

/* styles.css sets `.section { align-items: center }`. In a column flex
   that shrinks every row to its content width, so a grid holding only
   placeholders (no intrinsic width) collapses to ~140px. Stretch them. */
.section.two-up { align-items: stretch; }

/* 16:9 for cinematic frames — styles.css defaults two-up to 4/3,
   which crops the top and bottom off a scope frame. */
.section.two-up .tile { aspect-ratio: 16 / 9; }

/* Full-width row. Needs the .section.two-up prefix to outweigh
   `.section.two-up .grid { grid-template-columns: 1fr 1fr }`. */
.section.two-up .grid.grid-1 { grid-template-columns: 1fr; }

/* Consecutive grids in one section need air between them. */
.section.two-up .grid + .grid { margin-top: 2.2rem; }

.shot figcaption {
  margin-top: .8rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .74rem;
  letter-spacing: .06em;
  color: rgba(255, 255, 255, .5);
}

/* ---- Placeholder slot -------------------------------------- */
.ph {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  width: 100%;
  height: 100%;
  background:
    repeating-linear-gradient(
      45deg,
      rgba(112, 32, 130, .16) 0 12px,
      rgba(112, 32, 130, .03) 12px 24px
    ),
    #000000;
  border: 1px dashed rgba(199, 125, 255, .45);
  border-radius: 2px;
}

/* Standalone placeholders (not inside a ratio-locked .tile) carry
   their own ratio. Inside a .tile, the tile owns it. */
.img-wrap .ph.ph-portrait { aspect-ratio: 3 / 4; height: auto; }
.img-wrap .ph.ph-wide     { aspect-ratio: 16 / 9; height: auto; }

.ph-tag {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .68rem;
  letter-spacing: .18em;
  color: var(--brand-secondary);
}
.ph-note {
  font-size: .82rem;
  letter-spacing: .02em;
  color: rgba(255, 255, 255, .42);
  text-align: center;
  max-width: 24ch;
  line-height: 1.4;
}

/* ---- VO pull line in section heads -------------------------- */
.vo {
  font-size: clamp(1rem, 1.5vw, 1.18rem);
  font-weight: 300;
  font-style: italic;
  line-height: 1.5;
  color: rgba(255, 255, 255, .55);
  border-left: 2px solid var(--brand-primary);
  padding-left: 1.1rem;
  margin: 0 0 1.4rem;
  max-width: 46ch;
}

/* ---- Closing colophon -------------------------------------- */
.colophon {
  text-align: center;
  margin-top: 2.4rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .7rem;
  letter-spacing: .14em;
}

@media (max-width: 768px) {
  .ph-note { font-size: .76rem; }
  .vo { padding-left: .8rem; }
  .section.two-up .grid + .grid { margin-top: 1.4rem; }
}

/* ---- Cover meta ---------------------------------------------
 * styles.css lays .hero-meta out as a single non-wrapping flex row.
 * Six loose spans overflow a 375px viewport (right edge hit 433px)
 * and run together into one mushy line on desktop. Pair them up.
 * ------------------------------------------------------------ */
.hero-inner { max-width: min(1200px, 100%); }

.hero-meta {
  flex-wrap: wrap;
  gap: 1rem 4.5rem;
  align-items: flex-start;
}
.meta-pair {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .55rem;
  text-align: center;   /* label sits centred over its value */
}

@media (max-width: 768px) {
  .hero-meta { gap: .9rem 1.4rem; justify-content: center; }
  .meta-pair { text-align: center; align-items: center; }
}

/* ---- Title-card hero ----------------------------------------
 * The cover image IS the title (chrome lettering from the spot),
 * so there is no typeset <h1> to sit on top of it.
 * styles.css dims .hero-bg img to opacity .55 under a dark
 * gradient, which crushes the chrome flat — both are cancelled.
 * object-fit: contain guarantees the lettering never crops at any
 * viewport; the card is already on black so the letterbox is
 * invisible against the section background.
 * ------------------------------------------------------------ */
.hero.title-card { background: #000000; }
.hero.title-card .hero-bg img { opacity: 1; object-fit: contain; }
.hero.title-card .hero-bg::after { background: none; }

.hero.title-card .hero-inner {
  width: 100%;
  max-width: none;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  padding: clamp(1.75rem, 5vh, 3.5rem) 2rem;
}
.hero.title-card .hero-meta { margin-bottom: 0; }
.hero.title-card .hero-sub  { margin-top: 0; }

/* ---- Title card: text anchored to the lettering --------------
 * Measured from the artwork: the chrome lettering occupies
 * 35.4%–61.1% of the card's height. The meta block and the sub
 * line are anchored to those bounds rather than to the viewport,
 * so they hug the letters at every size instead of drifting to
 * the screen edges.
 * ------------------------------------------------------------ */
.hero.title-card .hero-card {
  position: relative;
  text-align: center;   /* .hero-inner used to carry this; it is gone now */
  width: min(100%, calc((100vh - 5rem) * 1.784));
  max-width: 1600px;
  aspect-ratio: 2048 / 1148;
  margin: 0 auto;
}
.hero.title-card .hero-card > img {
  /* Resting zoom, so the lettering fills more of the frame than a
     plain `contain` fit allows. deck.js re-applies the same base
     value, so the two must be kept in step (BASE_SCALE). */
  transform: scale(1.15);
  transform-origin: center;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.hero.title-card .hero-meta {
  position: absolute;
  left: 0; right: 0;
  bottom: 76%;            /* zoomed lettering starts at 33.2% */
  margin: 0;
  justify-content: center;
}
.hero.title-card .hero-sub {
  position: absolute;
  left: 0; right: 0;
  top: 73%;               /* zoomed lettering ends at 62.8% */
  margin: 0;
}

/* Complementary purple on the small type. Values stay near-white
   so there is still a hierarchy against the labels. */
.hero.title-card .label    { color: var(--brand-secondary); opacity: .85; }
.hero.title-card .val      { color: #f2eaf6; }
.hero.title-card .hero-sub {
  color: var(--brand-secondary);
  opacity: .9;
  font-size: clamp(.9rem, 1.05vw, 1.12rem);
  letter-spacing: .22em;
}

/* Phones: the card is only ~210px tall, so percentage anchoring
   would collide the blocks. Fall back to a normal stack. */
@media (max-width: 768px) {
  .hero.title-card .hero-card {
    width: 100%;
    aspect-ratio: auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2rem;
    min-height: 100vh;
  }
  .hero.title-card .hero-card > img {
    position: static;
    height: auto;
    aspect-ratio: 2048 / 1148;
  }
  .hero.title-card .hero-meta,
  .hero.title-card .hero-sub { position: static; }
}

/* ---- Parallax ------------------------------------------------ */
.hero.title-card .hero-card > img,
.hero.title-card [data-px-text] { will-change: transform; }

@media (prefers-reduced-motion: reduce) {
  /* No parallax, but keep the zoom — the text is positioned against
     the zoomed letterform bounds, so dropping it would misalign both
     blocks. */
  .hero.title-card .hero-card > img   { transform: scale(1.15) !important; }
  .hero.title-card [data-px-text]     { transform: none !important; opacity: 1 !important; }
}

/* ---- Bento grid ----------------------------------------------
 * Two frames side by side, then a full-width row directly beneath.
 * `.wide` spans both columns — used for the money shot and for the
 * video. Collapses to a single column on phones.
 * ------------------------------------------------------------ */
.bento {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem;
  align-items: start;
}
.bento .wide { grid-column: 1 / -1; }

/* Video sits in the same ratio-locked tile as the stills. */
.tile video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  background: #000;
}

@media (max-width: 768px) {
  .bento { grid-template-columns: 1fr; gap: 1.4rem; }
}

/* ---- Video: poster state ------------------------------------
 * Without this the video reads as just another gallery tile,
 * because the poster IS a frame from the same scene as the stills
 * above it. The purple wash plus the play target say "this one
 * moves" before anyone hovers.
 *
 * Native controls are withheld until first play — a control bar
 * sitting under the poster is the other thing that made it look
 * like a still with furniture on it.
 * ------------------------------------------------------------ */
.video-shot .tile { position: relative; cursor: pointer; }

.video-tint {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg,
      rgba(112, 32, 130, .34) 0%,
      rgba(58, 12, 78, .52) 100%);
  transition: opacity .45s ease;
}

.video-play {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: clamp(64px, 7vw, 96px);
  height: clamp(64px, 7vw, 96px);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  transition: opacity .35s ease, transform .35s ease;
}
.video-play svg { width: 100%; height: 100%; display: block; }
.video-play circle {
  fill: rgba(10, 4, 14, .42);
  stroke: rgba(255, 255, 255, .92);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
}
.video-play path { fill: #fff; }

.video-shot .tile:hover .video-play { transform: translate(-50%, -50%) scale(1.07); }
.video-play:focus-visible {
  outline: 2px solid var(--brand-secondary);
  outline-offset: 6px;
  border-radius: 50%;
}

/* Once playing, the wash and the target get out of the way. */
.tile.is-playing .video-tint,
.tile.is-playing .video-play { opacity: 0; pointer-events: none; }
.tile.is-playing { cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .video-tint, .video-play { transition: none; }
}

/* ---- Section 01 portrait + caption ---------------------------
 * .img-wrap is a clipped fixed-ratio box, so a caption inside it
 * would be cut off. The figure becomes the grid child instead and
 * carries the order rules that styles.css puts on .img-wrap —
 * otherwise the image stops re-ordering above the copy on mobile.
 * ------------------------------------------------------------ */
.section.two-col .portrait-shot { margin: 0; }
.section.two-col.image-right .portrait-shot { order: 2; }

@media (max-width: 768px) {
  .section.two-col.image-right .portrait-shot { order: 0; }
}

/* ---- Video placeholder --------------------------------------
 * Same purple wash and play target as a real video tile, so a
 * sequence that has not been made yet still reads as "this one
 * will move" rather than as a missing image.
 * ------------------------------------------------------------ */
.ph.ph-video {
  gap: 1.1rem;
  background:
    linear-gradient(180deg,
      rgba(112, 32, 130, .34) 0%,
      rgba(58, 12, 78, .52) 100%),
    #000000;
  border: 1px dashed rgba(199, 125, 255, .45);
}
.ph-play {
  width: clamp(56px, 6vw, 84px);
  height: clamp(56px, 6vw, 84px);
  display: block;
  opacity: .55;
}
.ph-play circle {
  fill: rgba(10, 4, 14, .35);
  stroke: rgba(255, 255, 255, .75);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
}
.ph-play path { fill: rgba(255, 255, 255, .85); }

/* ---- Section 01: pull the two columns together ----------------
 * styles.css uses `grid-template-columns: 1fr 1fr` across the full
 * section width, while `.copy` caps at 48ch. On a wide screen the
 * text stops well short of its column and the image fills all of
 * its own, so the pair reads as pinned to opposite edges with a
 * hole in the middle.
 *
 * Fixed-ish column widths, centred, with the image column the
 * narrower of the two — so the image also comes down in size.
 * minmax(0, …) lets both shrink before the mobile breakpoint.
 * ------------------------------------------------------------ */
.section.two-col {
  /* 30rem is the narrowest the copy column goes before the display
     type starts breaking badly — 'help ourselves.' onto three lines and
     an orphaned 'it.' on the pull quote. The body copy runs shorter than
     that and rags right, which is fine; the headline is what sets the
     column width. */
  grid-template-columns: minmax(0, 30rem) minmax(0, 23rem);
  justify-content: center;
  gap: clamp(1.75rem, 3vw, 3rem);
}

@media (max-width: 768px) {
  .section.two-col { grid-template-columns: 1fr; justify-content: stretch; }
}

/* ---- Everything on one black --------------------------------
 * styles.css paints tiles and image wraps on `--bg-elev: #0F0F10`
 * while the page is `--bg: #000000`. Because the tiles are rounded,
 * that lighter box haloes out at the corners and reads as a
 * different, slightly warm background against the full black
 * between sections. Collapse the two.
 * ------------------------------------------------------------ */
:root {
  /* #050505 is rgb(5,5,5) — a dark grey, not black. Against the true
     black inside the artwork and the <video> element it reads as a
     charcoal surround. Everything is pure black. */
  --bg:      #000000;
  --bg-elev: #000000;
}

/* ============================================================
 * ONE PAGE WIDTH
 * Every section's content sits in the same centred column, so the
 * left edge lines up all the way down the deck. styles.css only
 * sets section padding, which means content width tracked the
 * viewport and section 01 (a centred grid) sat on a different
 * left edge from the two-up heads above and below it.
 * ============================================================ */
:root { --content: 1280px; }

.section.two-up > .head,
.section.two-up > .bento {
  width: 100%;
  max-width: var(--content);
  margin-inline: auto;
}

/* Section 01 aligns LEFT within that same column rather than
   centring — that is what puts its copy on the same left edge as
   every heading. The columns stay narrow and adjacent so the pair
   does not spread; the slack goes to the right. */
.section.two-col {
  width: 100%;
  /* The section IS the grid, so its own padding sits inside this box —
     unlike the two-up heads, which are capped inside an already-padded
     parent. Adding the padding back into the cap puts both on the same
     left edge, and still lets the padding do its job on narrow screens
     where the max-width does not bind. */
  max-width: calc(var(--content) + 2 * clamp(1.5rem, 5vw, 6rem));
  margin-inline: auto;
  justify-content: start;
}

/* ---- Closing colophon ----------------------------------------
 * `.dim` caps at 56ch, so the colophon was a narrow box parked at
 * the left of the 800px closing block. text-align centred the text
 * inside the box, not the box itself.
 * ------------------------------------------------------------ */
/* Specific enough to beat `.section .dim { max-width: 37ch }`, which
   would otherwise re-cap the colophon and park it left of centre. */
.section .colophon { max-width: none; margin-inline: auto; }

/* ---- Deliberate headline breaks -------------------------------
 * Desktop only — at phone widths these land mid-line and read as
 * mistakes. */
@media (max-width: 768px) {
  br.dtop { display: none; }
}

/* ---- Title card: blend the edges into the page ---------------
 * The artwork's own outer rows are near-black (07090b / 050606),
 * but the 1.15 resting zoom crops them away and exposes the
 * brighter nebula, so the card met the page in a hard charcoal
 * seam top and bottom.
 *
 * Masked rather than baked into the asset, so the source stays
 * untouched. Vertical only: the lettering runs to ~4% and ~96%
 * horizontally once zoomed, so a side fade would eat the outer
 * letters. The mask is on the <img> alone — the meta and sub are
 * siblings, so their opacity is unaffected.
 * ------------------------------------------------------------ */
.hero.title-card .hero-card > img {
  -webkit-mask-image: linear-gradient(to bottom,
      transparent 0%, #000 15%, #000 85%, transparent 100%);
  mask-image: linear-gradient(to bottom,
      transparent 0%, #000 15%, #000 85%, transparent 100%);
}

/* ---- Password gate: desktop hint ------------------------------
 * The template styles everything else about #pw-gate. This note is
 * the one piece it does not ship — it nudges phone viewers to open
 * the link on a desktop before they judge the deck on a 375px
 * screen it was never laid out for.
 * ------------------------------------------------------------ */
#pw-gate .pw-note {
  margin: 3rem 0 0;
  max-width: 30ch;
  padding: .9rem 1.4rem;
  border-radius: 6px;
  background: var(--brand-accent);
  color: #150c02;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .8rem;
  font-weight: 500;
  letter-spacing: .08em;
  line-height: 1.6;
  text-transform: uppercase;
  text-align: center;
}
#pw-gate .label {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .72rem;
  letter-spacing: .18em;
}

/* Gate scaled to match the Ford one — the template's title is half
   the size and reads timid next to it. */
#pw-gate .title {
  font-family: var(--font-tight);
  font-weight: 900;
  font-size: clamp(3rem, 11vw, 8rem);
  line-height: .9;
  letter-spacing: -.045em;
  color: #fff;
  margin: 0 0 2.5rem;
}
#pw-gate .label { margin-bottom: 1.25rem; }
#pw-gate form { width: min(90vw, 420px); }

/* The turnaround sheet is a document, not a picture — its callout
   type has to stay readable, so it is not cropped to the gallery
   ratio like the shot tiles are. */
.tile.tile-sheet { aspect-ratio: auto; }
.tile.tile-sheet img { height: auto; object-fit: contain; }

/* Belt and braces: anything that painted the old near-black. */
html, body { background: #000000; }
.hero, .section { background: #000000; }
.hero.title-card { background: #000000; }

/* ---- Vertical rhythm -----------------------------------------
 * styles.css gives every section `min-height: 100vh` plus up to
 * 8rem of vertical padding, so consecutive sections stack a full
 * empty screen of black between their content. Sections here are
 * tall enough on their own — they hold full-width imagery — so the
 * viewport floor just adds dead air.
 * ------------------------------------------------------------ */
.section,
/* styles.css sets `padding-top/bottom: 4rem` directly on .section.two-up,
   which outranks a bare `.section` rule — so it has to be named here or
   every gallery section keeps the tighter spacing. */
.section.two-up {
  min-height: 0;
  padding-block: clamp(7rem, 12vh, 10rem);
}

/* The closing line wants air in front of it — it should arrive after
   a pause rather than straight off the last video. */
.section.closing { padding-top: clamp(13rem, 26vh, 20rem); }

/* ---- Section 01: symmetric margins ----------------------------
 * The image sits on the RIGHT edge of the shared content column,
 * so the gap from image to window edge matches the gap from window
 * edge to the text — the two margins read as a pair. The image is
 * also given more of the column than the copy needs.
 * ------------------------------------------------------------ */
.section.two-col {
  grid-template-columns: minmax(0, 30rem) minmax(0, 34rem);
  justify-content: space-between;
}

/* ---- Body measure ---------------------------------------------
 * 56ch runs long under a display headline — the eye has to travel
 * too far back for the next line and the block reads as a wall.
 * ~37ch is two thirds of that. Applied to the paragraphs rather
 * than to `.head`, so the headline keeps its own wider measure.
 * ------------------------------------------------------------ */
.section .lede,
.section .dim { max-width: 37ch; }
/* Only the 56ch cap from styles.css needs lifting here — NOT the shared
   `--content` cap, which is what keeps these heads on the same left edge
   as everything else. Setting `none` broke that alignment. */
.section.two-up .head { max-width: var(--content); }

/* Higher specificity than `.section .dim { max-width: 37ch }`, which is
   declared later in this file and was re-capping the colophon to 249px. */
.section.closing .colophon { max-width: none; margin-inline: auto; }

/* ============================================================
 * LIGHTBOX — click any gallery image to view it uncropped
 * The tiles crop to 16:9 with object-fit: cover, so a still is
 * never seen whole in the deck itself. Ported from the Cricket
 * example (PIPELINE.md §6 lists it as cherry-pickable).
 * ============================================================ */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1500;
  display: none;
  background: rgba(0, 0, 0, .94);
}
.lightbox.open { display: block; }
body.lb-open { overflow: hidden; }

.lightbox .lb-stage {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 4vw, 4rem);
}
.lightbox .lb-img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 4px;
}

.lightbox button {
  position: absolute;
  z-index: 2;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .16);
  color: #fff;
  border-radius: 999px;
  cursor: pointer;
  line-height: 1;
  font-family: var(--font-sans);
  transition: background .2s ease, border-color .2s ease;
}
.lightbox button:hover { background: rgba(255, 255, 255, .14); }
.lightbox button:focus-visible {
  outline: 2px solid var(--brand-secondary);
  outline-offset: 3px;
}
.lightbox .lb-close {
  top: clamp(1rem, 2vw, 2rem);
  right: clamp(1rem, 2vw, 2rem);
  width: 44px; height: 44px;
  font-size: 1.6rem;
}
.lightbox .lb-prev,
.lightbox .lb-next {
  top: 50%;
  transform: translateY(-50%);
  width: 52px; height: 52px;
  font-size: 2rem;
}
.lightbox .lb-prev { left: clamp(.75rem, 2vw, 2rem); }
.lightbox .lb-next { right: clamp(.75rem, 2vw, 2rem); }

.lightbox .lb-meta {
  position: absolute;
  left: 0; right: 0;
  bottom: clamp(.9rem, 2vh, 1.6rem);
  text-align: center;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .7rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .45);
  pointer-events: none;
}

/* Say it is clickable before anyone tries. */
.bento .tile img,
.section.two-col .img-wrap img { cursor: zoom-in; }

@media (max-width: 768px) {
  .lightbox .lb-prev, .lightbox .lb-next { width: 42px; height: 42px; font-size: 1.5rem; }
}

/* ---- Small type, one notch up --------------------------------
 * The template's mono sizes (0.70–0.75rem) are squint-small on a
 * large screen, and this deck leans on them for chapter markers,
 * eyebrows and the cover meta. Raised together so the mono scale
 * stays consistent rather than drifting per element.
 * ------------------------------------------------------------ */
.eyebrow                 { font-size: .82rem; }
.label                   { font-size: .8rem; }
.chapter-marker          { font-size: .8rem; }
.section .colophon       { font-size: .8rem; }
.lightbox .lb-meta       { font-size: .78rem; }
#pw-gate .label          { font-size: .8rem; }
#pw-gate .pw-note        { font-size: .86rem; }

/* ---- Room to park the closing line ---------------------------
 * Without trailing space the last line can only ever sit at the
 * bottom of the window. This lets it scroll up to the middle.
 * ------------------------------------------------------------ */
.section.closing { padding-bottom: clamp(16rem, 45vh, 32rem); }
