/* Storyline Group — splash page.
   Depends on tokens.css (colour + type) and base.css (elements + primitives).

   ALL SIZING IS LITERAL PIXELS. Breakpoints match base.css:
     (base rules)             desktop — 901px and up
     @media (max-width:900px)  tablet
     @media (max-width:600px)  phone

   Wireframe stage: image slots are placeholders. */

/* No site header — the logotype sits in the hero instead, so the video runs
   full-bleed from the top of the page. */

/* =============================== HERO ================================= */

/* Framed rather than full-bleed. The frame colour lives on this wrapper, not on
   the body, so no other section is affected. Padding rather than a margin on
   .hero — a plain wrapper would let the hero's top margin collapse out of it. */
.hero-frame {
  background: var(--sl-cream);
  padding: 5px;
}

/* Radius is 10px, tighter than the 24px on the .media photo blocks — at this
   size a large radius reads as a rounded card rather than a framed edge. */
.hero {
  position: relative;
  min-height: 70vh;
  border-radius: 10px;
  /* Two rows: the logotype sits in the top corner, the headline block stays
     bottom-anchored in the 1fr row below it. Using grid rather than absolute
     positioning means the two can never overlap on a short viewport — the
     hero grows instead. */
  display: grid;
  grid-template-rows: auto 1fr;
  overflow: hidden;      /* clips the video and scrim to the rounded corners */
  background: var(--sl-ink);
  color: var(--sl-cream);
}

.hero__media {
  position: absolute;
  inset: 0;
  background: #2f2f2f;   /* shows through before the first frame paints */
}
.hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* No filter here, deliberately, and note there is no blur() either — the
     softening is BAKED INTO hero.mp4 and hero-poster.jpg, not applied in CSS.
     Doing it in the file means the sharp, identifiable face never ships, which
     is the whole point; it also costs no compositing per frame on phones and
     stays proportional to the image at every breakpoint, where a fixed-px CSS
     blur would read far heavier at 390px. Re-encode from the master, do not
     re-blur the shipped file. See docs/splash-wireframe-notes.md.

     The earlier saturate(0.68) contrast(1.04) existed solely to tame the
     original clip's out-of-palette magenta; this footage is already muted —
     warm wood, white shirt, a teal notebook that reads as the brand secondary.
     Removing it cost nothing measurable. Do not reintroduce it for contrast:
     it does not buy any. */
}

/* Scrim so butter type holds contrast over the footage. Two gradients:
   bottom-up for the headline block, plus a left wash because the subject sits
   left of centre in this clip, right where the headline lands — still true of
   the chosen footage, where she is roughly 25–45% across the frame.

   Every stop is 70% of what it was. The original values were tuned for the
   unblurred original clip; blurring the footage lifted contrast on its own, so
   the scrim had headroom it no longer needed and the hero was reading too dark.
   Both gradients were scaled together — an asymmetric version that cut the wash
   harder was measured and rejected, because the headline sits lower-LEFT and is
   protected by both, so cutting either one costs it.

   Measured over 15 frames with both gradients composited, sampling only pixels
   under the rendered glyph masks (median / worst pixel):
   logotype 13.00 / 6.79, headline 5.67 / 3.92, statement 9.13 / 4.65.

   The headline is the binding constraint. At 90px it is large text, so the
   requirement is 3:1 and 3.92 clears it by ~30% — but it no longer clears the
   4.5 AAA-large threshold, which it did before. Scaling to 85% instead of 70%
   puts it back over 4.5 if that is ever wanted. Do not lighten further without
   re-measuring: the next step down (60%) drops the headline to 3.55. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right,
      rgba(39,39,39,.38) 0%,
      rgba(39,39,39,.14) 55%,
      rgba(39,39,39,.04) 100%),
    linear-gradient(to top,
      rgba(39,39,39,.53) 0%,
      rgba(39,39,39,.27) 45%,
      rgba(39,39,39,.07) 100%);
}

/* Top row. position:relative lifts it above the video and scrim. */
.hero__brand {
  position: relative;
  padding-top: 48px;
}

.hero__logo {
  height: 135px;
  width: auto;
  display: block;
}

/* Bottom row. align-self:end anchors the headline block to the base of the
   hero; padding-top is only a minimum gap for the case where the hero is
   squeezed short enough that the two rows meet. */
.hero__inner {
  position: relative;
  align-self: end;
  padding-top: 40px;
  padding-bottom: 90px;
}

/* Sized down from the global display scale (110 / 84 / 48) at the same
   ratios, so the hero headline sits under the logo without crowding the
   rotating statement. */
.hero__headline {
  color: var(--sl-butter);
  font-size: 90px;
  max-width: 14ch;
}

/* Rotating service statement in the hero. Font size comes from
   .service-statement in base.css (36 / 31 / 20). Left in cream — butter is
   the headline's. */
.hero__statement { margin-top: 12px; }

@media (max-width: 900px) {
  .hero__brand { padding-top: 40px; }
  .hero__inner { padding-top: 32px; padding-bottom: 64px; }
  .hero__logo { height: 100px; }
  .hero__headline { font-size: 69px; }
}
@media (max-width: 600px) {
  .hero__brand { padding-top: 32px; }
  .hero__inner { padding-top: 24px; padding-bottom: 48px; }
  .hero__logo { height: 76px; }
  .hero__headline { font-size: 39px; }
}

/* Reduced motion: hold the poster frame instead of playing. */
@media (prefers-reduced-motion: reduce) {
  .hero__video { display: none; }
  .hero__media {
    background: #2f2f2f url("../assets/video/hero-poster.jpg") center / cover no-repeat;
  }

  /* Hero only: hold a single value rather than expanding to the full grid,
     which would swamp the hero. Nothing is lost — the complete service list is
     in the Moments that Matter section further down the page. */
  .hero__statement.service-statement { display: flex; font-size: 36px; }
  .hero__statement .service-statement__lead { display: inline; margin-bottom: 0; }
  .hero__statement .field--rotating { display: inline-block; }
  .hero__statement .field__viewport {
    height: 42px;
    overflow: hidden;
    border-bottom: 3px solid currentColor;
  }
  .hero__statement .field__list { display: block; padding-top: 0; max-width: none; }
  .hero__statement .field__item {
    height: 42px;
    line-height: 42px;
    white-space: nowrap;
    border-bottom: 0;
    padding-bottom: 0;
  }
  .hero__statement .field__item:not(:first-child) { display: none; }
}

/* ====================== BLOCK 2 — ISSUE TO IMPACT =====================
   Headline moved to the hero, so this section opens on its supporting
   paragraph. Set larger than body copy so it reads as a lede. */

.statement__body { margin-top: 32px; font-size: 25px; }

.statement__body--lede {
  margin-top: 0;
  font-family: "instrument-serif", "Instrument Serif Local", Georgia, serif;
  font-size: 36px;
  line-height: 1.4;
}
/* Full container width — overrides the 66ch measure that base.css puts on <p>. */
.statement__body--lede p { max-width: 100%; }

.statement__cta { margin-top: 32px; }

@media (max-width: 900px) {
  .statement__body { font-size: 23px; }
  .statement__body--lede { font-size: 30px; }
}
@media (max-width: 600px) {
  .statement__body { font-size: 20px; }
  .statement__body--lede { font-size: 24px; }
  .statement__body--lede p { max-width: none; }
}

/* ====== SHARED — SECTIONS CARRYING A PHOTO STACK (blocks 4 and 5b) =====
   A photo stack adds most of a section's height on its own, so these sections
   set their own padding rather than taking the global .section rhythm
   (128 / 96 / 64). Loaded after base.css, so these win at every width.
   Was .section--story, when block 4 was the only section with photos. */

.section--media { padding-top: 60px; padding-bottom: 60px; }

@media (max-width: 900px) {
  .section--media { padding-top: 48px; padding-bottom: 48px; }
}
@media (max-width: 600px) {
  .section--media { padding-top: 36px; padding-bottom: 36px; }
}

.split {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 80px;
  align-items: center;
}

/* Asymmetric stack, after the Success Stories deck: one tall block beside two
   shorter ones, offset so the column doesn't read as a plain grid. */
.photo-stack {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
/* Aspect ratio lives on .media so it applies to real photos and placeholders
   alike; the <img> fills and crops to it. */
.photo-stack .media { aspect-ratio: 1 / 1; }
.photo-stack .media > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Slow enough to read as a settle rather than a snap. */
  transition: transform 700ms cubic-bezier(0.22, 0.61, 0.36, 1),
              filter    700ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* The container clips to its rounded corners, so the image scales inside a
   fixed frame — the crop moves, the layout does not. */
.photo-stack .media:hover > img {
  transform: scale(1.06);
  filter: brightness(1.04) saturate(1.06);
}

@media (prefers-reduced-motion: reduce) {
  .photo-stack .media:hover > img { transform: none; }
}
.photo-stack > :first-child {
  grid-row: span 2;
  aspect-ratio: 3 / 5;
  margin-top: 52px;
}

@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; gap: 52px; }
  .photo-stack > :first-child { margin-top: 0; }
}

/* ================== BLOCK 5 — MOMENTS THAT MATTER ===================== */

/* Body scale, not the subhead scale — it sets up the service list rather than
   heading it. Inherits 18/17/16 from body; no size of its own. */
.services__lede { max-width: 46ch; }

.services__prompt {
  font-family: "instrument-serif", "Instrument Serif Local", Georgia, serif;
  font-size: 36px;
  margin-top: 52px;
  margin-bottom: 20px;
}

/* Service index. Each row is prefixed with the brand's vertical bar — the mark
   from the logotype that also anchors the ledes — with a hairline rule per row
   echoing the fillable-field device. */
.services__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-rows: repeat(4, auto);
  grid-auto-flow: column;          /* 01-04 down the left, 05-08 down the right */
  column-gap: 80px;
  max-width: 1100px;
}
.services__list li {
  display: flex;
  align-items: baseline;
  gap: 20px;
  padding-top: 18px;
  padding-bottom: 18px;
  border-bottom: 1px solid color-mix(in srgb, currentColor 26%, transparent);
  font-family: "instrument-serif", "Instrument Serif Local", Georgia, serif;
  font-size: 28px;
  line-height: 1.2;
}
.services__list li::before {
  content: "";
  flex: none;
  width: 3px;
  height: 22px;
  background: currentColor;
  /* nudges the bar off the baseline so it centres on the x-height */
  transform: translateY(3px);
}

@media (max-width: 900px) {
  .services__prompt { font-size: 31px; }
  .services__list { column-gap: 48px; }
  .services__list li { font-size: 24px; padding-top: 15px; padding-bottom: 15px; }
  .services__list li::before { height: 19px; }
}
@media (max-width: 600px) {
  .services__prompt { font-size: 26px; margin-top: 40px; }
  .services__list { grid-template-rows: none; grid-auto-flow: row; }
  .services__list li { font-size: 20px; gap: 14px; padding-top: 12px; padding-bottom: 12px; }
  .services__list li::before { height: 17px; transform: translateY(2px); }
}

/* ================= BLOCK 5b — THE CLOSING QUESTION =================== */

/* Split out of block 5. As the last paragraph inside the teal services section
   it read as a footnote to the eight-row list; on its own ground it is the
   section's last word.

   Ground is --sl-orange, set on the section in index.html. This is a departure
   from the palette rules — orange is a secondary, and it lands between the teal
   and sky blocks, so the page runs three secondary grounds in a row. Flagged
   for sign-off; see the wireframe notes. Ink text only (7.51:1); cream on
   orange is 1.87:1 and fails.

   Anchored with the 6px bold bar, deliberately heavier than the 3px bars on the
   service rows, and the closing question sits on its own line at the same serif
   size as block 5's "Your team for", so the block ends on the question.

   No max-width on the copy: its measure is governed by the grid column. */

/* Photo stack mirrored — photos left, copy right, the reverse of block 4.
   Source order keeps the copy first, so it still leads on mobile and in the
   reading order; only the desktop grid is flipped. Block 4's 1.05/0.95 column
   ratio is reversed too, so the copy keeps the wider side. */
.closing__split { grid-template-columns: 0.95fr 1.05fr; }
.closing__split > .closing__inner { grid-column: 2; grid-row: 1; }
.closing__split > .photo-stack    { grid-column: 1; grid-row: 1; }

/* Stack mirrored again inside the group: the two squares take the left column,
   the tall block moves to the right. Placing only the tall one is enough — the
   squares auto-flow into the free cells of column 1, in source order. The 52px
   offset rides with the tall block, so the left column still starts higher. */
.closing__split .photo-stack > :first-child { grid-column: 2; grid-row: 1 / span 2; }
.closing__body { font-size: 22px; line-height: 1.45; }
/* The bar sits on the body copy alone — the question carries its own weight and
   reads as a step out of the anchored passage, not part of it. Padding matches
   .bar-anchor's 6px border + 20px padding so both text edges still line up. */
.closing__question {
  font-family: "instrument-serif", "Instrument Serif Local", Georgia, serif;
  /* Styling, not semantic stress — so italic lives here rather than in an <em>.
     The kit carries a real Instrument Serif italic; the self-hosted fallback
     has roman only, so that layer would synthesise an oblique. */
  font-style: italic;
  font-size: 34px;
  line-height: 1.15;
  margin-top: 20px;
  padding-left: 26px;
}

@media (max-width: 900px) {
  /* .closing__body already caps at 22px, so it needs no step here. */
  .closing__question { font-size: 31px; }
  /* Re-collapse to one column: .split's own collapse rule sits earlier in this
     file, so at equal specificity the base .closing__split ratio above wins and
     the two columns would survive. Drop the placement too, so the copy stacks
     above the photos. */
  .closing__split { grid-template-columns: 1fr; }
  .closing__split > .closing__inner,
  .closing__split > .photo-stack { grid-column: auto; grid-row: auto; }
}
@media (max-width: 600px) {
  .closing__body { font-size: 20px; }
  .closing__question { font-size: 26px; }
}

/* =============== BLOCK 6 — BRING US YOUR HARD PROBLEM ================= */

/* Matches the h2 treatment used in blocks 4 and 5 — Instrument Serif at the
   standard heading sizes, not the Rift display face. */
.pitch__headline { max-width: none; }
/* No font-size — inherits the body scale (18 / 17 / 16), matching block 4's
   copy and the services note. */
.pitch__body { margin-top: 14px; max-width: 66ch; }

/* ================ BLOCKS 6 + 7 — PITCH + CONTACT FORM ================
   The pitch copy and the form sit side by side in one butter section. */

.pitch {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 80px;
  align-items: start;
}

/* The stacked tagline lockup that used to sit in the footer. Ink cut, not the
   footer's cream one — this section's ground is sky, not charcoal. Same 52px
   height it had down there.

   Sits below the email address as a sign-off, left-aligned with the copy above.
   Stacked logotype without the tagline — the tagline lockup is not used here. */
.pitch__logo { display: block; height: 110px; width: auto; margin: 20px 0 0; }

.contact__direct { margin-top: 22px; }
.contact__email {
  font-family: "instrument-serif", "Instrument Serif Local", Georgia, serif;
  font-size: 36px;
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.form { display: grid; gap: 20px; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }

.form label {
  display: block;
  font-family: "aileron", "Aileron Local", system-ui, sans-serif;
  font-weight: 700;
  font-size: 15px;
  margin-bottom: 4px;
}
/* On the butter ground a transparent field disappears — give inputs the cream
   background so they read as fields. */
.form input,
.form textarea {
  width: 100%;
  padding: 14px 18px;
  font: inherit;
  color: inherit;
  background: var(--sl-cream);
  border: 2px solid rgba(39, 39, 39, 0.18);
  border-radius: 12px;
}
.form textarea { min-height: 128px; resize: vertical; }
.form input:focus,
.form textarea:focus { outline: none; border-color: var(--sl-ink); }

@media (max-width: 900px) {
  .pitch { grid-template-columns: 1fr; gap: 52px; }
  .contact__email { font-size: 31px; }
}
@media (max-width: 600px) {
  .form__row { grid-template-columns: 1fr; }
  .contact__email { font-size: 26px; }
}

/* =============================== FOOTER =============================== */

/* Just deep enough for the one line of meta type — the logo that used to set
   this footer's height is gone, so the padding is a 20px step top and bottom
   rather than the old 40/35 that framed the mark. */
.site-footer {
  background: var(--sl-ink);
  color: var(--sl-cream);
  padding: 20px 0;
}
.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 20px;
}
.site-footer .meta { margin: 0; opacity: .7; }
