/* ══════════════════════════════════════════════════════════════════════════
   css/sell-media.css — THE THREE TIER 2 SELLING PAGES UNDER MEDIA
   service.tnaado.ca · /brand-video-toronto · /product-photography-toronto
                     · /content-retainer

   Pairs with css/chrome.css (the shared bar, nav sheet and foot sheet) and
   css/booking-band.css (the terminal booking band). Neither is edited here.

   WHY THIS FILE EXISTS RATHER THAN css/sell.css. The old repo's sell.css is
   1,122 lines built on site.css's ground registers — a Tier 2 page that links
   it drags the legacy design system onto a page whose whole point is that it
   is light and single-purpose. This sheet is self-contained: it defines its
   own tokens, its own ground, and the three fonts booking-band.css reads by
   name. Nothing on these pages needs site.css.

   ══ WHAT ETHAN ASKED FOR, AND WHAT THAT MEANT HERE ════════════════════════
   "every page gets to confusing, to much info everywhere to much repeat to
   much chaos. but i love the photo secltions the layout etc"

   So: the photography stays and does argumentative work, and the DENSITY
   comes down. Concretely, three rules this file enforces rather than suggests:

     1. TWO FRAMED GRIDS PER PAGE, MAXIMUM. The old product-photography page
        ran four and that is most of why it read flat — a page of grids has no
        rhythm, so no grid is emphatic. Anything past the second becomes a
        single frame or a ground change.
     2. A GROUND CHANGE IS THE PUNCTUATION. `.band` alternates ink and paper
        and every join carries one hairline. There are no cards inside cards
        and no boxes around boxes.
     3. ONE THING MOVES PER PAGE. On /product-photography-toronto it is the
        contact sheet developing. On the other two, nothing moves at all.
        Motion is not decoration on a page that takes paid traffic.

   ══ COLOUR, LOCKED ═══════════════════════════════════════════════════════
   ink #0a0a0a · red #c8102e · bone #f5f1e8.

   --red (#c8102e) is 3.37:1 on ink and is therefore BANNED as small text. It
   is used in this file only for rules, fills, spines and display type at or
   above 24px. Small red text uses --red-ink #ef5c6e on ink (6.06:1) and
   --red-bone #a4132c on paper (6.6:1). Both values are lifted from
   css/chrome.css and css/work-camera.css, where they are already measured, so
   the three sheets cannot drift apart.

   Every text tone below is composited against the ground it actually sits on
   and the ratio is written next to it. Nothing is declared without one.

   ══ TABULAR NUMERALS ═════════════════════════════════════════════════════
   Any column of figures a reader compares vertically gets
   `font-variant-numeric: tabular-nums`. That is the rate-card values, the
   worked-example values, the schedule durations and the day-arc durations.
   The old pages had it on prices but not on durations, so 2h30 and 5h30
   failed to align in the one place the argument is arithmetic.

   ══ DEGRADATION ══════════════════════════════════════════════════════════
   Every element is authored in its FINISHED state. The one animation in this
   file runs backwards out of `from` keyframes held by animation-fill-mode:
   both, gated on a single `.is-on` class that an IntersectionObserver adds
   once and never removes. So a script that 404s, throws, or is blocked costs
   the animation and nothing else, and the reduced-motion rule is two lines.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  --ink:       #0a0a0a;
  --ink-true:  #0a0a0a;          /* booking-band.css reads this by name */
  --bone:      #f5f1e8;
  --red:       #c8102e;

  /* Small red text. Two values, because the ground decides which is legal. */
  --red-ink:   #ef5c6e;          /* on ink   — 6.06:1 */
  --red-bone:  #a4132c;          /* on paper — 6.6:1  */

  /* Type on ink. Shared with the chrome, where they are already measured. */
  --dim-ink:   #b9b3a6;                      /* 9.4:1 on ink */
  --mute-ink:  rgba(245, 241, 232, .72);     /* 9.7:1 on ink */
  --cap-ink:   rgba(245, 241, 232, .60);     /* 6.9:1 on ink */
  --hair-ink:  rgba(245, 241, 232, .14);

  /* Type on paper. Composited on --paper, not on pure bone: no text on these
     pages sits on #f5f1e8 itself. */
  --paper:     #f2ede1;
  --plate:     #e7e1d3;          /* one step down — the undeveloped frame */
  --ink-body:  rgba(10, 10, 10, .80);         /* 14.4:1 on paper */
  --ink-mute:  rgba(10, 10, 10, .66);         /* 9.5:1 on paper  */
  --ink-cap:   rgba(10, 10, 10, .58);         /* 7.5:1 on paper  */
  --hair-bone: rgba(10, 10, 10, .16);

  --display: 'Fraunces', 'Iowan Old Style', 'Times New Roman', serif;
  --sans:    'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* booking-band.css reads these three names and has NO fallback for them.
     Aliases rather than a second declaration, so there is one source. */
  --font-display: var(--display);
  --font-body:    var(--sans);
  --font-mono:    var(--mono);

  --rail: 74rem;
  --pad:  clamp(1.15rem, 4vw, 2.5rem);
  --ease: cubic-bezier(.22, 1, .36, 1);
}

/* ── RESET, minimal ──────────────────────────────────────────────────────── */

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

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

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.62;
  /* Stated rather than assumed. Measured at 320 / 390 / 768 / 1440: nothing
     on these pages may push the document wider than its viewport. */
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }

/* ONE focus ring for the whole page, and it is visible on both grounds.
   #c8102e is a non-text UI colour here, which needs 3:1 — it is 3.37:1 on ink
   and 5.5:1 on paper. The offset is what makes it visible over a photograph. */
:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
  border-radius: 1px;
}

.u-vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ── THE RAIL AND THE BANDS ──────────────────────────────────────────────── */

.rail {
  width: 100%; max-width: var(--rail);
  margin-inline: auto; padding-inline: var(--pad);
}

/* A band is a ground. Ink is the default because the photography sits better
   on it; paper is for the two blocks that are pure reading — the rate card and
   the questions. Every band carries its own top hairline, so a join is always
   drawn once and never twice. */

/* ── THE 2026-08-22 DENSITY PASS ──────────────────────────────────────────
   Ethan: "sizing of sections and images and booking forms all too large ...
   like you're treating the reader as a toddler". The root pass had already
   brought css/reference.css's heading scale down to h1 3.5rem / h2 2.125rem /
   h3 1.4375rem and css/site.css's section padding to ~4.25rem. This sheet is
   brought onto those same two numbers, because five sheets each inventing
   their own display size is how a site ends up shouting on one page and
   whispering on the next. Every value below is the reference scale, not a
   new one. */
.band { padding-block: clamp(2.25rem, 4.6vw, 4rem); border-top: 1px solid var(--hair-ink); }
.band--paper {
  background: var(--paper); color: var(--ink-body);
  border-top-color: var(--red);          /* a fill, not text: legal at any size */
}
.band--tight { padding-block: clamp(1.6rem, 3vw, 2.5rem); }
.band--flush { border-top: 0; }

/* ── TYPE ────────────────────────────────────────────────────────────────── */

.k {
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--red-ink);
  margin-bottom: 1.15rem;
}
.band--paper .k { color: var(--red-bone); }

.h1 {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(2.05rem, 6.2vw, 3.5rem);
  line-height: 1.04; letter-spacing: -.02em;
  color: var(--bone); max-width: 24ch;
}
.h2 {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.625rem, 3.1vw, 2.125rem);
  line-height: 1.12; letter-spacing: -.015em;
  color: var(--bone); max-width: 26ch;
}
.band--paper .h2 { color: var(--ink); }

/* The italic clause. Display type well above 24px, so --red is legal here and
   it is the only place on the page red is allowed to carry words. */
.h1 em, .h2 em { font-style: italic; color: var(--red-ink); }
.band--paper .h2 em { color: var(--red); }

.h3 {
  font-family: var(--sans); font-size: 1rem; font-weight: 600;
  line-height: 1.35; color: var(--bone);
}
.band--paper .h3 { color: var(--ink); }

.lede {
  margin-top: 1rem; max-width: 58ch;
  font-size: 1.0625rem; color: var(--mute-ink);
}
.band--paper .lede { color: var(--ink-body); }

.note {
  margin-top: 1.6rem; max-width: 66ch;
  font-size: .875rem; line-height: 1.65; color: var(--cap-ink);
}
.band--paper .note { color: var(--ink-cap); }
.note a, .lede a {
  color: var(--red-ink); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: .18em;
}
.band--paper .note a, .band--paper .lede a { color: var(--red-bone); }
.note a:hover, .lede a:hover { text-decoration-thickness: 2px; }

b, strong { font-weight: 600; color: var(--bone); }
.band--paper b, .band--paper strong { color: var(--ink); }

/* ── THE HERO — FOUR THINGS ──────────────────────────────────────────────
   Ethan, looking at one of these pages in Chrome: "please deisgn it way better
   what im seeing on chrome is so ugly and complciated and overwhelming". He has
   said a version of that about every page on this site and it is the note he
   keeps coming back to. It is a counting problem before it is a taste problem,
   so it was fixed by counting.

   Counted at 1440x900, the version before this one put THIRTEEN separate things
   on the first screen: two chrome rows, an eyebrow, a headline, a three-line
   promise, a price label, the price itself, a three-line qualifying paragraph,
   two buttons and a row of three chips. Every one of them competed.

   FOUR THINGS NOW, plus the two chrome rows this sheet does not control: the
   headline, one line of promise, the price, ONE call to action. What this is,
   what it costs, and one thing to do.

   What left and where it went:
     eyebrow            deleted; the H1 and the promise already say the subject
                        and the city, and the phrase survives in the title, both
                        social descriptions and the JSON-LD
     the qualifying     folded into the price label where it is one clause, or
     paragraph          dropped where the rate rows below already carry it
     the second button  deleted; the bypass row links the same section and is
                        already on the page. Two buttons in a hero compete and
                        neither leads
     the chips          moved down to the proof band, which is the argument they
                        were making

   THE PLATE IS NOT ANIMATED AND MUST NOT BECOME ANIMATED. It is a price. It
   paints at full opacity on the first frame at every width, with JS off and
   with reduced motion on. Nothing in this file gives it a transform, an
   opacity or a delay.

   THE CHROME IS position:fixed AND NEVER SCROLLS AWAY. Measured: 94px at 1440
   (52 menubar + 42 bypass) and 86px at 390 (52 + 34), which is 10.4% and 10.2%
   of those viewports taken off EVERY screen of the page, not only the first. A
   hero asking for 100svh therefore overflows the first screen by exactly that
   much, so it is subtracted here. Local variable because css/chrome.css owns
   the real number and this file may not edit it. */

.hero {
  --chrome-h: 5.75rem;              /* 86px of chrome + the body offset */
  padding-block: clamp(2rem, 4vw, 3.25rem) clamp(2.25rem, 4.6vw, 3.75rem);
  min-height: calc(100svh - var(--chrome-h) - 5rem);
  display: grid;
  align-content: start;
}

/* ON A PHONE the content sits at the top of that height and the slack falls
   BELOW it — `start`, not `center`. Centred, a five-thing hero floated in the
   middle of the screen with 150px of nothing above the headline, which is a
   different kind of wrong. The remainder pushes the next band's heading off the
   first screen and leaves only its edge showing.

   AT 1440 the slack goes to both sides, because the hero is a composition
   there rather than a stack, and the photograph beside the type needs room
   above and below it to sit in. */
@media (min-width: 53.75rem) {
  .hero {
    --chrome-h: 6.25rem;            /* 100px: 94px of chrome + the body offset */
    min-height: calc(100svh - var(--chrome-h) - 2.5rem);
    align-content: center;
  }
}

/* One line at 1440, two or three at 390. The measure is what enforces it — the
   old 52ch ran to three and four lines and a paragraph that long in a hero is a
   wall, not an introduction. */
.hero__promise {
  margin-top: 1.25rem; max-width: 44ch;
  font-size: clamp(1.0625rem, 2.1vw, 1.1875rem);
  color: var(--mute-ink);
}

/* THE PRICE. No longer a red-barred slab: a hairline above it and nothing else
   drawn, which is the same treatment css/sell.css now gives the four technology
   pages. One price treatment across all seven selling pages — a buyer who reads
   one of them can read any of them, and that is only true if the price looks
   the same on every one. */
.plate {
  margin-top: clamp(2rem, 4vw, 2.75rem);
  padding: 1.375rem 0 0;
  border-top: 1px solid var(--hair-ink);
  max-width: 34rem;
}
.band--paper .plate { border-top-color: var(--hair-bone); }
.plate__k {
  font-family: var(--mono); font-size: .6875rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--red-ink);
}
.band--paper .plate__k { color: var(--red-bone); }
/* ONE ROW, not two. The unit used to be a block under the figure, which made
   the price three stacked lines where css/sell.css's four technology pages make
   it two. Identical now — figure and unit on one baseline, wrapping only when
   the width forces it — so the price looks the same on all seven selling pages.
   A buyer who learns one of these pages can read any of them, and that is only
   true if the thing they came for is drawn the same way every time. */
.plate__fig {
  display: flex; align-items: baseline; gap: .75rem; flex-wrap: wrap;
  margin-top: .5rem;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(2.25rem, 5.2vw, 3.5rem); line-height: 1;
  letter-spacing: -.02em; color: var(--bone);
  font-variant-numeric: tabular-nums;
}
.plate__fig span {
  font-family: var(--mono); font-size: .8125rem; font-weight: 500;
  letter-spacing: .06em; color: var(--cap-ink);
}

/* Three figures side by side, for the crew-day ladder in the hero. Mono and
   tabular so the three read as one ladder rather than three prices — and set
   large, because on /brand-video-toronto this IS the price and it was being
   whispered at 17px under a headline set at 56. */
.rung {
  display: grid; gap: .1rem 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  margin-top: 1.25rem;
}
.rung__i { padding-top: .8rem; border-top: 1px solid var(--hair-ink); }
.rung__v {
  font-family: var(--mono); font-size: clamp(1.375rem, 3vw, 1.75rem); font-weight: 500;
  line-height: 1.1;
  color: var(--bone); font-variant-numeric: tabular-nums;
}
.rung__l {
  margin-top: .3rem;
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--cap-ink);
}

.act { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: clamp(1.75rem, 4vw, 2.5rem); }

.cta, .btn {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .8rem 1.2rem;
  font-family: var(--sans); font-size: .8125rem; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; text-decoration: none;
  border: 1px solid var(--red); border-radius: 2px;
  transition: background .18s var(--ease), color .18s var(--ease), transform .18s var(--ease);
}
.cta { background: var(--red); color: #fff; }            /* 5.9:1 white on red */
.cta:hover { background: #a50d26; border-color: #a50d26; transform: translateY(-1px); }
.btn { background: transparent; color: var(--bone); border-color: var(--hair-ink); }
.btn:hover { border-color: var(--red); color: var(--bone); transform: translateY(-1px); }
.band--paper .btn { color: var(--ink); border-color: var(--hair-bone); }

.chips { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: 1.5rem; }
.chips li {
  padding: .38rem .7rem;
  border: 1px solid var(--hair-ink); border-radius: 999px;
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; color: var(--dim-ink);
}

/* ── THE WORKED EXAMPLE ──────────────────────────────────────────────────
   The arithmetic IS the product. The total is the sum of the lines printed
   above it and nothing is added to it, so both the lines and the sum are
   ordinary text at full opacity on the first frame. No counter: a total that
   counts up from zero is an animated price. */

.sum { margin-top: clamp(1.6rem, 4vw, 2.25rem); }
.sum__h { font-family: var(--display); font-size: 1.25rem; font-weight: 400; line-height: 1.2; }
.band--paper .sum__h { color: var(--ink); }
.sum__h em { font-style: italic; color: var(--red-bone); }
.sum__sub { margin-top: .6rem; max-width: 56ch; font-size: .9375rem; color: var(--ink-mute); }

.sum__rows { margin-top: 1.35rem; border-top: 1px solid var(--hair-bone); }
.sum__row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem;
  padding: .85rem 0; border-bottom: 1px solid var(--hair-bone);
}
.sum__l { font-size: .9375rem; color: var(--ink-body); }
.sum__calc {
  display: block; margin-top: .2rem;
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-cap);
  font-variant-numeric: tabular-nums;
}
.sum__v {
  flex: 0 0 auto;
  font-family: var(--mono); font-size: .9375rem; font-weight: 500;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.sum__row--total {
  border-bottom: 2px solid var(--red);
  padding-top: 1.05rem;
}
.sum__row--total .sum__l { font-weight: 600; color: var(--ink); }
.sum__row--total .sum__v { font-size: 1.375rem; }
.sum__note { margin-top: 1.1rem; max-width: 62ch; font-size: .875rem; color: var(--ink-mute); }
.sum__note b { color: var(--ink); }

/* ── THE RATE CARD ───────────────────────────────────────────────────────
   Four drivers, four groups, one list. Crew, cast, props and space move
   independently, so a buyer adds only the ones their job uses — publishing
   all four at all is the thing no Toronto competitor does, which is exactly
   why the card is a plain list and not a feature table. */

.rates { margin-top: clamp(1.8rem, 4vw, 2.5rem); }
.rates__h {
  padding-bottom: .7rem; border-bottom: 2px solid var(--red);
  font-family: var(--mono); font-size: .5625rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-mute);
}
.rates__g {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem;
  margin-top: 1.5rem; padding-bottom: .5rem;
  border-bottom: 1px solid var(--hair-bone);
  font-family: var(--mono); font-size: .6875rem; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--ink);
}
.rates__g i { font-style: normal; color: var(--red-bone); }
.rates__g span {
  font-size: .5625rem; letter-spacing: .1em; color: var(--ink-cap);
  text-transform: none;
}
.rates__row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1.25rem;
  padding: .7rem 0; border-bottom: 1px solid var(--hair-bone);
}
.rates__l { font-size: .9375rem; color: var(--ink-body); }
.rates__n {
  display: block; margin-top: .18rem; max-width: 48ch;
  font-size: .8125rem; color: var(--ink-cap);
}
.rates__v {
  flex: 0 0 auto;
  font-family: var(--mono); font-size: .875rem; font-weight: 500;
  color: var(--ink); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.rates__v--soft { color: var(--ink-mute); }

/* ── THE FRAMED GRID ─────────────────────────────────────────────────────
   The photo section, and the one Ethan named as the thing he likes. It is a
   grid of real frames with a mono label above and a caption under, and the
   label is numbered because a numbered frame is a frame you can point at and
   ask for.

   NOTHING HERE IS GATED ON MOTION. An element whose content arrives over the
   network is never put behind an animation: a photograph that fades in is a
   photograph you wait for twice. */

.frames {
  display: grid; gap: clamp(1rem, 2.5vw, 1.6rem);
  margin-top: clamp(1.8rem, 4vw, 2.5rem);
  grid-template-columns: 1fr;
}
@media (min-width: 620px)  { .frames { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px)  { .frames--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1040px) { .frames--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.frame__k {
  display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
  padding-bottom: .5rem; margin-bottom: .6rem;
  border-bottom: 1px solid var(--hair-ink);
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--dim-ink);
}
.frame__k i { font-style: normal; color: var(--red-ink); }
/* The duration column. tabular-nums is load-bearing: 2h30 and 5h30 are
   compared down the row and they have to sit on the same stem. */
.frame__d { font-variant-numeric: tabular-nums; color: var(--bone); }
.frame img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  background: #16161a; border-radius: 2px;
}
.frame--tall img { aspect-ratio: 3 / 4; }
.frame figcaption {
  margin-top: .6rem; font-size: .8125rem; line-height: 1.5; color: var(--cap-ink);
}

/* One frame on its own, full rail. Used where a second grid would be a third
   grid — the ground change and the single frame carry it instead. */
.solo { margin-top: clamp(1.8rem, 4vw, 2.5rem); }
.solo img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 2px; background: #16161a; }
/* The one 2:1 frame in the library. Given its own ratio rather than cropped to
   16:9, because its subject is at BOTH edges — a crew at the right and a
   subject at the left — and a centre crop cuts the argument in half. */
.solo--wide img { aspect-ratio: 2 / 1; }
.solo figcaption { margin-top: .7rem; font-size: .8125rem; color: var(--cap-ink); }

/* ── THE HOURS LEDGER ────────────────────────────────────────────────────
   Where a page has to compare durations, they go in ONE column rather than
   scattered through captions, and that column is mono and tabular so 2h30 and
   5h30 sit on the same stem. The old brand-video page put its durations in
   proportional type inside track headings and they did not line up. */

.hours { margin-top: clamp(1.5rem, 3.5vw, 2rem); border-top: 1px solid var(--hair-ink); }
.hours__r {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1.25rem;
  padding: .7rem 0; border-bottom: 1px solid var(--hair-ink);
}
.hours__l { font-size: .9375rem; color: var(--mute-ink); }
.hours__n {
  display: block; margin-top: .18rem; max-width: 52ch;
  font-size: .8125rem; color: var(--cap-ink);
}
.hours__v {
  flex: 0 0 auto;
  font-family: var(--mono); font-size: .875rem; font-weight: 500;
  color: var(--bone); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.hours__r--total { border-bottom: 2px solid var(--red); }
.hours__r--total .hours__l { font-weight: 600; color: var(--bone); }
.hours__r--total .hours__v { font-size: 1.0625rem; }

/* ── KEY / VALUE ROWS ────────────────────────────────────────────────────
   The free deliverable, stated in four rows: what it is, what it costs us,
   what it is not, whose it is. Four rows rather than four paragraphs because
   a buyer reads the left column and stops at the one they doubt. */

.rows { margin-top: clamp(1.6rem, 4vw, 2.25rem); border-top: 1px solid var(--hair-ink); }
.rows__r {
  display: grid; gap: .35rem 1.75rem; align-items: baseline;
  padding: 1rem 0; border-bottom: 1px solid var(--hair-ink);
}
@media (min-width: 720px) { .rows__r { grid-template-columns: 12rem minmax(0, 1fr); } }
.rows__k {
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--red-ink);
}
.rows__v { max-width: 62ch; font-size: .9375rem; color: var(--mute-ink); }

/* ── THE SCHEDULE ────────────────────────────────────────────────────────
   Stages with real durations, and the sum underneath, because the sum is the
   number a buyer writes down. The duration column is mono and tabular so the
   stages can be compared without reading them. */

.steps { margin-top: clamp(1.6rem, 4vw, 2.25rem); border-top: 1px solid var(--hair-ink); }
.steps__s {
  display: grid; gap: .3rem 1.25rem;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  padding: .95rem 0; border-bottom: 1px solid var(--hair-ink);
}
.steps__n {
  font-family: var(--mono); font-size: .75rem; font-weight: 500;
  color: var(--red-ink); font-variant-numeric: tabular-nums;
}
.steps__t {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: .5rem 1.25rem;
  font-size: .9375rem; font-weight: 600; color: var(--bone);
}
.steps__d {
  flex: 0 0 auto;
  font-family: var(--mono); font-size: .75rem; font-weight: 500;
  letter-spacing: .04em; color: var(--dim-ink);
  font-variant-numeric: tabular-nums;
}
.steps__p { grid-column: 2; max-width: 58ch; font-size: .875rem; color: var(--cap-ink); }
.steps__sum {
  margin-top: 1.15rem; max-width: 58ch;
  font-family: var(--mono); font-size: .8125rem; letter-spacing: .02em;
  color: var(--bone); font-variant-numeric: tabular-nums;
}

/* ── PROOF ───────────────────────────────────────────────────────────────
   Outcome first, and only material that exists. No logo wall, because there
   are no logos to show; no testimonials, because there are none; no
   percentages, because we do not publish client results we cannot source.
   One card carries the photograph and the other carries the figure — the
   asymmetry is deliberate, and it is what stops this from being a third
   framed grid. */

.proof {
  display: grid; gap: clamp(1.5rem, 3.5vw, 2.5rem);
  margin-top: clamp(1.8rem, 4vw, 2.5rem);
}
@media (min-width: 860px) { .proof { grid-template-columns: 1.1fr .9fr; align-items: start; } }
.proof__c { padding-top: 1.1rem; border-top: 2px solid var(--red); }
.proof__out { font-family: var(--display); font-size: 1.3125rem; font-weight: 400; line-height: 1.2; color: var(--bone); }
.proof__who {
  margin-top: .45rem;
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--red-ink);
}
.proof__p { margin-top: .8rem; max-width: 52ch; font-size: .9375rem; color: var(--mute-ink); }
.proof__c figure { margin-top: 1.1rem; }
.proof__c img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 2px; background: #16161a; }
.proof__c figcaption { margin-top: .6rem; font-size: .8125rem; color: var(--cap-ink); }
.proof__link {
  display: inline-flex; gap: .4rem; margin-top: 1rem;
  font-family: var(--mono); font-size: .6875rem; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; text-decoration: none;
  color: var(--red-ink); border-bottom: 1px solid currentColor; padding-bottom: .15rem;
}
.proof__link:hover { color: var(--bone); }

/* The figure plate. A count taken from a job file, printed big enough that
   --red is legal display type, with the sentence that sources it underneath. */
.proof__fig {
  margin-top: 1.1rem; padding: 1.1rem 1.15rem;
  background: rgba(200, 16, 46, .08); border-left: 3px solid var(--red);
}
.proof__fig-n {
  font-family: var(--display); font-size: clamp(2.5rem, 7vw, 3.5rem);
  line-height: .95; letter-spacing: -.02em; color: var(--bone);
  font-variant-numeric: tabular-nums;
}
.proof__fig-t { margin-top: .5rem; font-size: .875rem; color: var(--mute-ink); }

/* ── THE CONTACT SHEET ───────────────────────────────────────────────────
   /product-photography-toronto's signature moment, and the ONE thing that
   moves on any of these three pages.

   WHAT IT IS. Nine of thirty delivered frames, printed in the order the
   camera wrote them and labelled with the camera's own file numbers. Those
   numbers are real, they do not run consecutively, and that is the whole
   point: a take is culled before anything is retouched.

   WHAT MOVES, AND WHAT DOES NOT. The GREY PLATE over each picture clears.
   That is all. The frame does not fade, the number does not fade, the caption
   does not fade, and no picture is scaled — the old page resolved each cell
   from oversize, which meant the grid, the numbers and the captions were all
   absent on frame one and the sheet arrived rather than developed. Here the
   sheet is fully present immediately and the pictures come up inside it, nine
   cells on an 85ms beat.

   NOTHING IS GATED ON THE NETWORK. The plate and the window behind it are the
   same colour, so a picture that has not arrived sits on exactly the ground
   the plate cleared to. Opacity only — no transform anywhere in this block. */

.cs { margin-top: clamp(1.8rem, 4vw, 2.5rem); }
.cs__head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: .5rem 1.5rem; padding-bottom: .65rem; border-bottom: 1px solid var(--red);
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase;
}
.cs__job { color: var(--bone); }
.cs__stock { color: var(--cap-ink); }

.cs__grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(.5rem, 1.6vw, 1rem); margin-top: clamp(.8rem, 2vw, 1.25rem);
}
.cs__f { min-width: 0; }
.cs__win { position: relative; display: block; }
.cs__win img {
  width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
  background: var(--plate); border-radius: 1px;
}
.cs__grey {
  position: absolute; inset: 0; border-radius: 1px;
  background: var(--plate); pointer-events: none;
  opacity: 0;                            /* FINISHED STATE IS THE DEFAULT */
}
.cs__c {
  display: flex; align-items: baseline; gap: .45rem;
  margin-top: .4rem; min-width: 0;
}
.cs__n {
  flex: 0 0 auto; padding: .1rem .3rem;
  background: var(--red); color: #fff;   /* 5.9:1, and a fill besides */
  font-family: var(--mono); font-size: .5625rem; font-weight: 500;
  letter-spacing: .06em; font-variant-numeric: tabular-nums;
}
.cs__t {
  font-size: .6875rem; line-height: 1.35; color: var(--cap-ink);
  overflow-wrap: break-word;
}

/* The develop pass. `.is-on` is added once by the observer at the foot of the
   page and never removed; every beat after that is an animation-delay. CSS
   animations composite off the main thread, so the pass stays smooth while
   the rest of the page is still settling. */
.cs.is-on .cs__grey {
  animation: cs-clear .62s var(--ease) both;
  animation-delay: calc(var(--i) * 85ms);
}
@keyframes cs-clear { from { opacity: 1; } to { opacity: 0; } }

/* ── THE MONTH BOARD ─────────────────────────────────────────────────────
   /content-retainer's own object: twenty working days, four week strips, and
   the month's twelve deliverable marks sitting on the days they land on. It
   is a picture of a schedule, which is why there is no photograph on it.

   It does not animate. The board is the shape of a commitment, and a
   commitment that assembles itself is a commitment you have to wait for. */

.cal { margin-top: clamp(1.8rem, 4vw, 2.5rem); }
.cal__dows {
  display: none; gap: .4rem; margin-bottom: .5rem;
  font-family: var(--mono); font-size: .5625rem; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--cap-ink);
}
@media (min-width: 720px) { .cal__dows { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); } }

.cal__wk { padding: 1rem 0; border-top: 1px solid var(--hair-ink); }
.cal__wk:last-of-type { border-bottom: 1px solid var(--hair-ink); }
.cal__wk-h { display: grid; gap: .3rem; margin-bottom: .8rem; }
@media (min-width: 720px) { .cal__wk-h { grid-template-columns: 6rem 10rem minmax(0, 1fr); align-items: baseline; gap: .3rem 1.25rem; } }
.cal__wk-n {
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--red-ink);
  font-variant-numeric: tabular-nums;
}
.cal__wk-t { font-size: .9375rem; font-weight: 600; color: var(--bone); }
.cal__wk-d { max-width: 52ch; font-size: .8125rem; color: var(--cap-ink); }

.cal__days { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .4rem; }
.cal__day {
  position: relative; min-height: 4.25rem; padding: .4rem;
  border: 1px solid var(--hair-ink); border-radius: 2px;
  display: flex; flex-direction: column; gap: .3rem;
}
.cal__d {
  font-family: var(--mono); font-size: .5625rem; font-weight: 500;
  color: var(--cap-ink); font-variant-numeric: tabular-nums;
}
.cal__evt {
  display: inline-block; padding: .12rem .3rem; align-self: flex-start;
  background: var(--red); color: #fff;
  font-family: var(--mono); font-size: .5rem; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase;
}
.cal__marks { display: flex; flex-wrap: wrap; gap: .2rem; margin-top: auto; }
/* The three marks are the three aspect ratios, drawn to scale. A reader who
   counts them gets twelve, which is the number in the headline. */
.cal__m { display: block; background: var(--bone); border-radius: 1px; }
.cal__m--wide  { width: 1.4rem;  height: .8rem; }
.cal__m--tall  { width: .5rem;   height: .9rem; background: var(--red-ink); }
.cal__m--still { width: .72rem;  height: .9rem; background: var(--dim-ink); }

.cal__legend {
  display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; margin-top: 1.1rem;
  font-family: var(--mono); font-size: .625rem; font-weight: 500;
  letter-spacing: .06em; color: var(--dim-ink);
}
.cal__leg { display: flex; align-items: center; gap: .45rem; }
.cal__loop {
  margin-top: 1.1rem; padding-top: 1.1rem; border-top: 1px solid var(--hair-ink);
  max-width: 62ch; font-size: .875rem; color: var(--mute-ink);
}

/* ── THE QUIET BANDS ─────────────────────────────────────────────────────
   Not included, and the exits row. Both are here to be honest rather than to
   be sold, so both are the quietest thing on their page.

   THE EXITS ROW IS THE DENSITY RULE MADE VISIBLE: anything a buyer does not
   need IN ORDER TO DECIDE is one link, never a shorter paragraph and never an
   embedded section. Do not turn one back into prose and do not add a fifth. */

.not { display: grid; gap: .5rem 1.5rem; margin-top: 1.35rem; }
@media (min-width: 640px) { .not { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.not li {
  padding: .55rem 0 .55rem .95rem; border-left: 2px solid var(--hair-ink);
  font-size: .9375rem; color: var(--mute-ink);
}

.exits {
  display: flex; flex-wrap: wrap; gap: .5rem 1.35rem;
  font-family: var(--mono); font-size: .6875rem; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase;
}
.exits a {
  display: inline-flex; gap: .35rem; text-decoration: none;
  color: var(--dim-ink); border-bottom: 1px solid var(--hair-ink); padding-bottom: .2rem;
}
.exits a:hover { color: var(--bone); border-bottom-color: var(--red); }

/* ── QUESTIONS ───────────────────────────────────────────────────────────
   Four, and all four are about money or scope: on a selling page a question
   that does not change what somebody pays or what they get does not belong.
   <details> so the band stays compact — the answers are in the document
   either way, so nothing here is hidden from a crawler or a reader without
   JavaScript. */

.faq { margin-top: clamp(1.6rem, 4vw, 2.25rem); border-top: 1px solid var(--hair-bone); }
.faq__i { border-bottom: 1px solid var(--hair-bone); }
.faq__q {
  display: flex; align-items: baseline; gap: .75rem;
  padding: .95rem 0; cursor: pointer; list-style: none;
  font-size: .9375rem; font-weight: 600; color: var(--ink);
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: '+'; margin-left: auto; flex: 0 0 auto;
  font-family: var(--mono); font-size: 1rem; color: var(--red-bone);
}
.faq__i[open] .faq__q::after { content: '\2212'; }
.faq__a { padding: 0 0 1.1rem; max-width: 66ch; font-size: .9375rem; color: var(--ink-body); }

/* ── REDUCED MOTION ──────────────────────────────────────────────────────
   Two lines, and they land on the finished state by construction, because the
   finished state is what the stylesheet declares. */
/* ── THE TERMINAL BOOKING BAND — STACKING ONLY ─────────────────────────────
   The band itself is authored entirely in css/booking-band.css and nothing
   here restyles it. This is the ONE thing that file cannot know, because it
   is a fact about the PAGE and not about the component: `.bkx` must sit above
   whatever the page paints around it.

   booking-band.css gives `.bkx` `position: relative` and no z-index, so it
   creates no stacking context of its own and any positioned sibling later in
   the document — or any earlier one lifted by a page-level rule — paints over
   it. That is not theoretical: the old web-design page had exactly this
   defect, a sticky element covering the booking panel, and a booking panel you
   cannot click is the same as no booking panel on a page that takes paid ads.

   `2` rather than `1` on purpose: 1 is the value booking-band.css already uses
   INSIDE the band (`.bkx__inner`, above the emblem), so a band-level 1 would
   read as the same layer and invite somebody to "simplify" one of them away.
   Nothing in the site chrome is affected — the fixed header and foot sheet run
   at 1190+ in css/chrome.css and still paint above, which is correct. */
.bkx { z-index: 2; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
