/* ============================================================
   Stack, part two — section 07. "What was hard." 20 technique terms
   (copy-deck-index-v4.md §07, trimmed from 25 — see skills-scatter.js),
   thrown outside the frame, gathering into a grid as you scroll;
   scatter again on the way back up. Mechanic ported from
   refer/scatter-queues.html (there: 12 flat colour swatches); scaled up
   to real terms, which needed more columns and shorter tiles to still
   fit one pinned viewport rather than clipping under .sc__stick's
   overflow:hidden.
   ============================================================ */

/* .stackAll/.stackAll__stick (stack-arc.css) own the shared sticky box
   now — the grid and the orbit ring are two layers inside the SAME
   pinned stage, not two separate sections (see EXCEPTIONS.md). --cols
   lives on .stackAll for the same reason. Gather-cycle share of the
   combined run is 220vh (GATHER_FRAC in skills-scatter.js), Uncover's
   own dedicated slide is 100vh, both untouched by the merge — same
   absolute scroll budget as before, just measured against the shared
   section instead of this file's own standalone one. */

/* Uncover — refer/cover-uncover_1.html's "Uncover" transition, not the
   earlier solid wipe (see EXCEPTIONS.md). Panel A is this stage's own
   already-gathered content — no duplicate to keep in sync. It gets a
   dedicated 100vh at the very end of the grid's own share of the shared
   run (GATHER_FRAC in skills-scatter.js), so the slide only starts once
   the cards are fully gathered and held, and doesn't eat into that
   cycle's own tuned timing. Panel B previews About's own header,
   exactly like Work Cover's Panel B previews the Work intro — the real
   #about header is hidden while this stage is pinned (see about.css),
   so it isn't shown twice in a row. */
.sc__panA, .sc__panB{
  position:absolute; inset:0; will-change:transform;
}
/* justify-content:flex-start, not center — with bigger cards/heading
   clearance, a centred grid taller than the remaining space clipped
   symmetrically top AND bottom under .sc__stick's overflow:hidden,
   hiding whichever cards landed outside either edge (their gathered,
   at-rest position, not their mid-flight one — which is why a card
   still animating INTO place stayed visible after others "vanished").
   Anchoring to the top means only the bottom can ever clip, and only
   on genuinely short viewports — predictable instead of silently
   swallowing rows from both ends. */
.sc__panA{
  z-index:2; background:var(--bg);
  display:flex; flex-direction:column; align-items:center; justify-content:flex-start;
  padding-top:var(--scatter-pad-top);
}
@media (max-width:640px){ .sc__panA{ padding-top:var(--scatter-pad-top-mobile); } }
/* the leading edge — without it the two planes read as one surface.
   Panel A is the one on top, exiting leftward (skills-scatter.js), so
   its trailing/right edge is the seam dragged across Panel B — same
   asymmetry refer/cover-uncover_1.html's own uncover mode uses. */
.sc__panA::after{
  content:''; position:absolute; top:0; bottom:0; right:0; width:1px;
  background:var(--border);
}

/* justify-content:flex-end, not center — owner report: with the lede
   text vertically centred, the pin's release handed off into #about's
   next paragraph (real document flow, starting right at THIS
   viewport's bottom edge) with a huge empty gap between them — roughly
   half the screen, since centred text sits nowhere near that bottom
   edge. Anchoring this panel's content to the bottom means the lede is
   already close to where the handoff happens, so #about's own next
   line picks up right after it with no visible gap. */
.sc__panB{
  z-index:1; background:var(--bg);
  display:flex; flex-direction:column; justify-content:flex-end;
  align-items:flex-start; text-align:left;
  max-width:var(--container); margin-inline:auto;
  padding-inline:var(--pad-inline); padding-bottom:var(--sp-10);
}
/* Owner request: once the slide finishes, keep scrolling within this
   same panel — the heading settles up a little and a lede line fades
   in beneath it — before handing off into #about's own normal-flow
   body right where this leaves off. #panB-head gets its own
   will-change since skills-scatter.js now animates its transform on
   top of the (already-settled) slide transform .sc__panB itself
   carries — two independent transforms on parent/child compose fine. */
#panB-head{ will-change:transform; }
.sc__panB-lede{
  margin-top:var(--sp-5); max-width:44ch;
  font-size:var(--fs-t2); color:var(--text-muted);
  opacity:0; will-change:opacity;
}

/* Same box model as .container — see method.css's .m__head for the
   same fix, same reasoning. top was --sp-7 (48px) — less than the fixed
   header's own real height (~88-96px, --sp-6 padding-block each side
   plus its line height), so this pinned stage's own content, sitting
   right at the true viewport top, was close enough to graze under it.
   --sp-9 clears it with real margin. align-items:baseline (was
   flex-start) so .sc__pct's single line of text lines up with the
   eyebrow's own baseline instead of its box's top edge — a bare <span>
   and a <p> don't share the same line-height metrics, so flex-start
   let them drift out of alignment with each other. */
.sc__head{
  position:absolute; top:var(--sp-9); left:0; right:0; z-index:3;
  max-width:var(--container); margin-inline:auto;
  padding-inline:var(--pad-inline);
  display:flex; justify-content:space-between; align-items:baseline; gap:var(--sp-5);
  pointer-events:none;
}
.sc__pct{
  font-size:var(--fs-t4); letter-spacing:var(--ls-caps); color:var(--text-muted);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}

/* the gathered state is a plain grid — nothing computes it; JS only
   ever applies an offset from wherever the grid already put each tile.
   Gap stepped up (was --sp-3) to give the now-larger cards room to
   breathe instead of crowding each other. */
.q{
  display:grid; grid-template-columns:repeat(var(--cols),1fr);
  gap:var(--sp-4); width:min(92vw,1040px);
}

/* Owner request: cards should read as 3D objects catching light while
   they fly, not flat outlined swatches — same --shadow token as the
   Work cards and Stack's own tiles (dark theme gets a faint light glow
   instead of a further-darkening shadow; see EXCEPTIONS.md). Sized up
   twice now (was 78px, then 92px) plus the type inside bumped a step —
   owner asked for both the card and its font larger, not just the card. */
.skill{
  position:relative; overflow:hidden; min-height:118px;
  will-change:transform;
  background:var(--surface);
  border-radius:var(--r-md); box-shadow:0 14px 28px -16px var(--shadow);
  display:flex; flex-direction:column; justify-content:space-between;
  padding:var(--sp-4) var(--sp-5);
}
.skill__n{
  font-size:13px; letter-spacing:var(--ls-caps); color:var(--text-muted);
  font-variant-numeric:tabular-nums;
}
/* Anton's floor is 24px; these tiles run as small as ~16px, so per
   system_2.md's own rule this isn't a display line — Inter 500 instead.
   .skill isn't a heading tag, so no override is needed against the
   global h1-h3 Anton rule; declared for clarity anyway. */
.skill__name{
  font-family:var(--font-text); font-weight:500;
  font-size:clamp(15px,1.5vw,18px); line-height:1.2;
}

/* The three "tailed" lines (Abstention, At-most-once delivery,
   Row-level security) carry an extra descriptive clause — deliberately
   uneven against the 17 flat terms around them. At 5 columns they land
   in one shared grid row (positions 13-15), so that row alone grows to
   fit the extra line without disturbing the others. */
.skill--tailed{ min-height:132px; }
.skill__tail{
  display:block; margin-top:var(--sp-2);
  font-size:12.5px; line-height:1.35; color:var(--text-muted);
}

/* Narrow screens: 4 columns keeps this to 7 rows instead of 9, but still
   needs smaller tiles to clear the pinned 100vh stage without clipping. */
@media (max-width:640px){
  .q{ gap:10px; }
  .skill{ min-height:88px; padding:10px 12px; }
  .skill__n{ font-size:11px; }
  .skill__name{ font-size:13px; line-height:1.2; }
  .skill--tailed{ min-height:122px; }
  .skill__tail{ font-size:11px; line-height:1.3; }
}

@media (prefers-reduced-motion:reduce){
  /* .stackAll/.stackAll__stick's own reduced fallback is in
     stack-arc.css now — this stage is shared, not this file's own
     section. Component-level fallbacks (this grid's own layers/cards)
     stay here. */
  .skill{ transform:none !important; }
  /* No slide: skills-scatter.js's animation loop never runs under
     reduced motion, so Panel B (About's preview) would otherwise sit
     frozen mid-transform. Hide it and let #about's own real header
     (site.css) show normally instead — the one working handoff left
     once nothing here is animating. */
  .sc__panA{ position:static; transform:none !important; padding-top:0; padding-block:var(--sp-7); }
  .sc__panA::after{ display:none; }
  .sc__panB{ display:none; }
  /* .sc__head is position:absolute normally; without this it would
     stay absolute against .stackAll (position:relative, 560vh tall)
     once its own parent .sc__panA goes static above — landing nowhere
     near the flat grid it's actually meant to sit above. */
  .sc__head{ position:static; padding:0; margin-bottom:var(--sp-6); }
}
