/* ============================================================================
   03 · Los ocho formatos.  The second felt board, and the only board on the
   page whose children are in FLOW rather than pinned: the board has to take
   its height from eight prints in two rows, and an absolutely positioned
   composition on an auto-height board resolves to zero (MATERIALS.md trap 2).
   So the board is a flex column of five bands (tabs, headline, row, row,
   closing) and the "pinned" reading comes from the pins each object carries
   plus a tilt per object, all inside +-2deg.

   GEOMETRY (desktop >= 900px), measured at 1440 with --desk-pad = 2.6vw:
     desk margin      2 x 37.4 = 74.8        board outer  1365 x 1817
     oak frame        2 x 18   = 36          felt box     1329
     board padding    2 x 28.8 = 57.6        content      1272
     tabs             1272 x 48 at y 18      headline     661 x 202 at y 115
     grid             4 cols, gap 1.6vw = 23 -> column    301
     print            --pw = 13.2vw = 199    print height 343  (9/16)
     row 1            1272 x 555 at y 366    row 2        1272 x 555 at y 1030
     closing          1272 x 99  at y 1649   (strip 788, CTA card 352)
   At 1024 the eight tabs no longer fit on one line (955 > 894) and the row
   wraps to two, which is the documented behaviour, not a failure.

   THE DENSITY PROBLEM, and how it is solved.  The bodies are 103 to 178
   characters and the material they sit on, .kraft-tag, is tracked caps at
   .8rem. Nothing may be hidden, so no clamping: instead the tag is given the
   full column width (not the print width), its text comes from the type scale
   through a .t-small child, and the tag's own caps + .1em tracking are
   switched off for the sentence. 258px of measure inside the tag's padding is
   what makes the longest body (178 characters, s03.formats[1].body) five lines
   instead of the nine it would be on a tag the width of the print.
   ========================================================================= */

.s-03{
  /* full width, with a sliver of desk showing at each side: this board lies
     ON the desk, unlike the hero's board, which is the page's own header. */
  margin:0 var(--desk-pad);
  padding:0 clamp(14px,2vw,29px) clamp(30px,3.6vw,54px);

  display:flex;
  flex-direction:column;

  /* one print width for the whole section; the height follows from 9/16 */
  --pw:clamp(150px,13.2vw,208px);
}

/* the five bands. Explicit margins rather than one flex gap, because the air
   under the headline is a bigger beat than the air between the two rows. */
.s-03 .head{margin-top:clamp(18px,2vw,30px)}
.s-03 .grid{margin-top:var(--gap-object)}
.s-03 .grid + .grid{margin-top:clamp(26px,2.8vw,44px)}
.s-03 .foot{margin-top:var(--gap-object)}

/* ---------- the eight index tabs, along the top inner edge --------------- */
/* .index-tab is drawn to hang from an edge (rounded top corners, a shadow
   cast upwards, 3px lower when it is not the chosen one). The row gets just
   enough top padding for the pin heads to clear the frame, because .board is
   overflow:clip and a pin at --py:0% is pulled up by half its height. */
.s-03 .tabs{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  align-items:flex-start;
  gap:clamp(6px,.9vw,14px);
  padding-top:clamp(12px,1.1vw,17px);
}
.s-03 .tabs .pin{--pin-size:clamp(13px,1.15vw,18px)}
.s-03 .tabs .index-tab:nth-child(odd) .pin{--pr:-13deg}
.s-03 .tabs .index-tab:nth-child(even) .pin{--pr:11deg}
.s-03 .tabs .index-tab:nth-child(3n) .pin{--pr:19deg}

/* ---------- the headline strip, pinned under the tabs at the left -------- */
/* .paper, not .sheet or .card: both of those swap the floating felt shadow
   (--shadow-paper) for the desk shadow, and this block hangs on two pins. */
.s-03 .head{
  position:relative;
  isolation:isolate;
  align-self:flex-start;
  width:min(52%,680px);
  padding:clamp(20px,2.4vw,36px) clamp(18px,2.2vw,34px) clamp(24px,2.8vw,40px);
  transform:rotate(var(--rot,0deg));
  transform-origin:50% 0;
}
.s-03 .head .pin-a{--px:7%;--py:0%;--pr:-15deg}
.s-03 .head .pin-b{--px:93%;--py:0%;--pr:12deg}
 /* the two headline leaves are ONE sentence, so they are two hard lines on
    the desktop board (the break the comp shows) and flow as a paragraph on a
    phone, where a forced break at 26px in 290px would orphan a word. */
.s-03 .head h2 span{display:block}

/* ---------- the two rows of four ---------------------------------------- */
.s-03 .grid{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(14px,1.6vw,26px);
  align-items:start;
}
.s-03 .fmt{
  display:flex;
  flex-direction:column;
  align-items:center;
}

/* the print: narrower than its column, so the paper tag under it reads as a
   label stuck across the bottom of the photograph, the way the comp shows it.
   margin:0 is load-bearing: a <figure> keeps the UA `margin:1em 40px`, and in
   a flex column that 16px bottom margin does not collapse, so it swallowed
   most of the stack overlap below (measured: 19px of pull became 3px). */
.s-03 .print{margin:0;width:var(--pw);height:auto}
.s-03 .print > .pin{--pin-size:clamp(15px,1.4vw,21px)}

/* hook accent: the three print accents of the hero, reused cyclically. No
   fourth colour is invented; the kicker is the whole accent line. */
.s-03 #fmt-1 .hook b,.s-03 #fmt-4 .hook b,.s-03 #fmt-7 .hook b{color:var(--hook-1)}
.s-03 #fmt-2 .hook b,.s-03 #fmt-5 .hook b,.s-03 #fmt-8 .hook b{color:var(--hook-2)}
.s-03 #fmt-3 .hook b,.s-03 #fmt-6 .hook b{color:var(--hook-3)}

/* pin angles (harmless at every width) */
.s-03 #fmt-1 > .pin{--pr:-19deg}   .s-03 #fmt-2 > .pin{--pr:11deg}
.s-03 #fmt-3 > .pin{--pr:-8deg}    .s-03 #fmt-4 > .pin{--pr:16deg}
.s-03 #fmt-5 > .pin{--pr:-13deg}   .s-03 #fmt-6 > .pin{--pr:20deg}
.s-03 #fmt-7 > .pin{--pr:-6deg}    .s-03 #fmt-8 > .pin{--pr:14deg}

/* ---------- every tilt, in one place ------------------------------------ */
/* All of it lives in a min-width query rather than in the partial's inline
   styles: below 900px the brief asks for no tilt, and an inline custom
   property cannot be overridden by a rule (only by !important, which is
   banned). Declaring the tilts only above 900px means the phone layout has
   nothing to undo. An id is (1,1,0) and would beat any mobile reset too,
   which is the third cascade trap in MATERIALS.md. */
@media (min-width: 900px){
  .s-03 .head{--rot:-.5deg}
  .s-03 .cross{--rot:.4deg}
  .s-03 .cta{--rot:-1.4deg}

  .s-03 #fmt-1{--rot:-1.6deg}   .s-03 #fmt-2{--rot:1.2deg}
  .s-03 #fmt-3{--rot:-.8deg}    .s-03 #fmt-4{--rot:1.7deg}
  .s-03 #fmt-5{--rot:1.4deg}    .s-03 #fmt-6{--rot:-1.8deg}
  .s-03 #fmt-7{--rot:.9deg}     .s-03 #fmt-8{--rot:-1.2deg}

  /* the caption pair leans the other way from its photograph */
  .s-03 .grid-a .fmt:nth-child(1) .cap{--rot:.8deg}
  .s-03 .grid-a .fmt:nth-child(2) .cap{--rot:-.9deg}
  .s-03 .grid-a .fmt:nth-child(3) .cap{--rot:1.1deg}
  .s-03 .grid-a .fmt:nth-child(4) .cap{--rot:-.6deg}
  .s-03 .grid-b .fmt:nth-child(1) .cap{--rot:-1deg}
  .s-03 .grid-b .fmt:nth-child(2) .cap{--rot:.7deg}
  .s-03 .grid-b .fmt:nth-child(3) .cap{--rot:-1.1deg}
  .s-03 .grid-b .fmt:nth-child(4) .cap{--rot:.6deg}
}

/* ---------- the caption group: one physical stack ----------------------- */
/* Fix after gate 2 (verifier 03.1): the pair used to float in open felt under
   the print. It is now one stack of three papers, as in the approved mockup:
   the print, the name tag lying OVER its bottom edge (19px at 1440), and the
   kraft tag tucked UNDER the name tag (9px). One tilt for the pair, so the two
   papers stay parallel to each other and only the photograph above them is off
   true.
   Two traps this hit. (1) The old -17px on .cap did almost nothing: .fmt-title
   is an <h3> with no .t-* class, so it kept the UA `margin-block:1em`, and that
   positive child margin collapsed with .cap's negative one (net -4.6px). Every
   element in the stack now sets `margin` explicitly. (2) z-order has to be
   written, because the kraft tag comes after the name tag in the DOM and would
   paint on top of it: name tag --z-lift, kraft tag --z-paper, both resolved
   inside .cap, which is a stacking context because it is transformed. */
.s-03 .cap{
  width:100%;
  margin-top:calc(-1 * clamp(14px,1.32vw,19px));
  transform:rotate(var(--rot,0deg));
  transform-origin:50% 0;
}

.s-03 .fmt-title{
  margin:0;
  z-index:var(--z-lift);
  padding:clamp(8px,.9vw,13px) clamp(10px,1.1vw,16px);
}

/* .fmt-body is the one place this section overrides a material's own type.
   .kraft-tag is a tracked-caps LABEL; these leaves are sentences of up to 178
   characters, and the approved comp itself draws them as sentence-case small
   text on kraft. So: block instead of inline-block (full column measure),
   caps and the .1em tracking off (both are inherited properties, so they have
   to be reset on the tag itself), left aligned for a five-line measure, and
   the size comes from the scale through the .t-small child rather than from
   any font-size in this file. Requested from the manager: a .kraft-tag
   variant that holds a sentence, so this override can be deleted. */
.s-03 .fmt-body{
  display:block;
  margin:calc(-1 * clamp(7px,.65vw,10px)) 0 0;   /* tucks under the name tag */
  z-index:var(--z-paper);
  padding:calc(clamp(10px,1.05vw,15px) + clamp(7px,.65vw,10px)) clamp(11px,1.15vw,17px) clamp(11px,1.15vw,16px);
  text-align:left;
  text-transform:none;
  letter-spacing:normal;
}
/* only --kraft-ink reaches AA on kraft (MATERIALS.md 11): .t-small brings
   --ink-soft with it, which is 3.2:1 on this surface. */
.s-03 .fmt-body .t-small{color:var(--kraft-ink)}
.s-03 .fmt-link{
  display:block;
  margin-top:clamp(7px,.8vw,11px);
}

/* the status note of the Ugly ads format, folded into that card's kraft tag as
   its last line (verifier 03.2), so the four cells of the row stay top-aligned
   instead of one of them carrying a second floating box. It is our own
   `adapted` line now, so no stamp is injected and no .is-plain workaround is
   needed on kraft any more. */
.s-03 .fmt-status{
  display:block;
  margin-top:clamp(9px,1vw,14px);
}

/* ---------- the spotlight (behaviour-contract 3) ------------------------- */
/* site.js puts .has-spot on this section and .is-spot on the chosen print.
   Everything else on the board steps back; the chosen print lifts and its
   whole cell comes forward so a neighbouring caption cannot cross it. */
.s-03.has-spot [data-spot-item]:not(.is-spot){
  opacity:.55;
  transform:scale(.98) rotate(var(--rot,0deg));
}
.s-03.has-spot .fmt:not(:has(.is-spot)) .cap{opacity:.55}
.s-03 [data-spot-item].is-spot{
  opacity:1;
  transform:translateY(-8px) scale(1.04) rotate(var(--rot,0deg));
}
.s-03 .fmt:has(.is-spot){position:relative;z-index:var(--z-float)}

/* ---------- the closing line and the CTA card --------------------------- */
.s-03 .foot{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--gap-object);
}
.s-03 .cross{
  flex:1 1 auto;
  max-width:62%;
  padding:clamp(11px,1.3vw,18px) clamp(22px,2.6vw,44px);
  transform:rotate(var(--rot,0deg));
  transform-origin:50% 50%;
}
.s-03 .cross .pin-a{--px:3%;--py:50%;--pr:-16deg}
.s-03 .cross .pin-b{--px:97%;--py:50%;--pr:21deg}
.s-03 .cta{
  flex:0 0 auto;
  width:min(30%,352px);
  transform-origin:50% 0;
}
.s-03 .cta .pin{--pr:-21deg}

/* ============================================================================
   MOTION
   1. Entry. Brief 03 asks for one thing: "prints settle in reading order".
      The trigger is the ROW, not the cell, and the settle is on the cells:
      one IntersectionObserver hit per row reveals its four cells 70ms apart
      through --i (0..3, set in the partial). Two reasons for the row as the
      trigger rather than eight separate [data-reveal] objects: the stagger
      then finishes in 730ms instead of 1.2s, and a 555px-tall row is always
      inside the viewport when any part of it is, so nothing in this section
      can be left at opacity 0 by a viewport that only shows part of an
      1817px board (the reduced-motion parity capture does exactly that).
      The headline, the tabs and the closing row therefore carry no reveal:
      they are complete the moment the section exists, in both motion modes.
   2. Spotlight. Dimming seven prints instantly reads as a glitch, so opacity
      joins the transform transition the print material already owns.
   ========================================================================= */
@media (prefers-reduced-motion: no-preference){
  /* the row itself never hides: it is only the trigger. This has to outrank
     materials' default variant (html.reveal-ready [data-reveal]:not(.pinned)),
     hence the extra .grid class. */
  html.reveal-ready .s-03 .grid[data-reveal="row"]{opacity:1;transform:none}

  html.reveal-ready .s-03 .grid[data-reveal="row"] .fmt{
    opacity:0;
    transform:translateY(12px);
  }
  html.reveal-ready .s-03 .grid[data-reveal="row"].is-in .fmt{
    opacity:1;
    transform:none;
    transition:
      opacity 520ms cubic-bezier(.2,.8,.25,1) calc(var(--i,0) * 70ms),
      transform 520ms cubic-bezier(.2,.8,.25,1) calc(var(--i,0) * 70ms);
  }

  .s-03 .print{
    transition:transform .22s cubic-bezier(.2,.8,.25,1), box-shadow .22s ease, opacity .22s ease;
  }
  .s-03 .cap{transition:opacity .22s ease}
}

/* ============================================================================
   MOBILE  < 900px.  The tabs wrap to as many rows as they need (never a
   nested scroller), the two grids drop to two columns each, every tilt goes
   to zero so two columns of paper still read as a grid, and the pins stay.
   The board is overflow:clip, so nothing here can reach the page's horizontal
   scroll.  390px: desk margin 12, frame 10, board padding 12 -> content 322,
   two columns of 155 with a 12px gutter, print 155x276.
   ========================================================================= */
@media (max-width: 899px){
  .s-03{
    margin:0 12px;
    padding:0 12px 28px;
    --pw:100%;
  }

  .s-03 .tabs{gap:6px;padding-top:11px;justify-content:flex-start}
  .s-03 .tabs .pin{--pin-size:12px}

  .s-03 .head{
    width:100%;
    margin-top:16px;
    padding:18px 15px 22px;
  }
  .s-03 .head h2 span{display:inline}

  .s-03 .grid{
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:24px 12px;
    margin-top:22px;
  }
  .s-03 .grid + .grid{margin-top:24px}
  /* three classes, so this wins over anything the desktop block set by id */
  .s-03 .grid .print{width:100%;height:auto}
  /* 26cqw of a 155px print is 40px: below the 44px tap target, so the play
     button gets an explicit diameter on phones. */
  .s-03 .play{--d:44px}
  .s-03 .hook{--hook-y:33%}

  .s-03 .cap{margin-top:-14px}
  .s-03 .fmt-body{margin-top:-8px;padding:18px 11px 11px}

  .s-03 .foot{
    flex-direction:column;
    align-items:stretch;
    gap:18px;
    margin-top:24px;
  }
  .s-03 .cross{max-width:none;padding:12px 20px}
  .s-03 .cta{width:100%}
}
