/* =========================================================================
   Home page (v4, plus the v5 ledger: V2, V4 to V13, V19). Loads after
   /styles.css and /css/mocks.css, before /css/motion.css. Everything below
   describes a FINAL state; motion.css owns the mechanics and motion.js the
   timing. js/home.js adds the two pointer effects (hero dots, sport field).
   ========================================================================= */

/* --------------------------------------------------------------- hero -- */
:root {
  /* how far the dashboard is pulled up onto the ink hero */
  --pull: clamp(170px, 21vw, 300px);
}

.hero {
  position: relative;
  background: var(--ink);
  color: #ffffff;
  padding-block: clamp(72px, 8vw, 116px)
    calc(var(--pull) + clamp(24px, 3vw, 44px));
}
/* faint static dot field: one inline SVG tile, no gradient, no glow */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26'%3E%3Ccircle cx='1.5' cy='1.5' r='1' fill='%23ffffff' fill-opacity='0.085'/%3E%3C/svg%3E");
  background-size: 26px 26px;
  pointer-events: none;
}
/* V8: on the first mouse move js/home.js draws the same dots on a canvas
   at the same pitch and switches the tile off, so the swap is invisible */
.hero__dots {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.hero.has-dots::before {
  display: none;
}
.hero > .wrap {
  position: relative;
  z-index: 2;
}
.hero__inner {
  text-align: center;
}
.hero h1 {
  font-size: clamp(2.6rem, 6vw, 4.5rem);
  font-weight: 800;
  text-transform: uppercase;
  line-height: 1;
  letter-spacing: -0.028em;
  margin: 0 auto;
  max-width: 15ch;
  text-wrap: balance;
}
.hero__sub {
  margin: 24px auto 0;
  max-width: 58ch;
  font-size: 18px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.8);
  text-wrap: pretty;
}
.hero__scope {
  margin: 14px auto 0;
  max-width: 60ch;
  font-size: 14px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.6);
  text-wrap: balance;
}
.hero__ctas {
  display: flex;
  justify-content: center;
  margin-top: 32px;
}
.hero__ctas .btn--solid {
  padding-inline: 30px;
  font-size: 14.5px;
}

/* the full dashboard (partials/dashboard.html) floating over the seam.
   1080px lets the mock show its nav rail and side-by-side panels. */
.seam {
  background: var(--paper);
}
.hero__shot {
  position: relative;
  z-index: 2;
  max-width: 1080px;
  margin: calc(-1 * var(--pull)) auto 0;
}

/* ------------------------------------------------------- hero prop field --
   Sports gear leads the flat-lay; the back-office props sit behind it.
   Placed and sized in percent of the hero. Nothing crosses the centred
   headline measure and nothing sits where the dashboard rides up over the
   hero's lower edge, so every prop stays whole. Each rests at a slight
   tilt through the `rotate` property, which composes with the transforms
   motion.js writes (entrance, parallax) instead of being replaced by them.
   motion.js staggers them in once and parallaxes them on a fine pointer at
   900px and up.                                                          */
/* the field never grows past 1480px, so on wide screens the props keep
   their proportion to the hero's height */
.props {
  max-width: 1480px;
  margin-inline: auto;
}
/* left: the clipboard, the soccer ball, the whistle and the football, then
   the spreadsheet printout (V7) lying in the strip beside the dashboard with
   the calculator resting on it, and the check above the dashboard's edge */
.prop--clipboard  { left: 2%;     top: 6%;  width: 8.5%;  rotate: -7deg; }
.prop--soccer     { left: 14.5%;  top: 13%; width: 8.2%; }
.prop--whistle    { left: 3.2%;   top: 34%; width: 4.6%;  rotate: 10deg; }
.prop--football   { left: 11%;    top: 36%; width: 10.5%; rotate: -16deg; }
.prop--check      { left: 14.5%;  top: auto; bottom: calc(var(--pull) + 22px); width: 7%;   rotate: 6deg; }
/* the strip beside the dashboard is (100% - 1080px) / 2 wide; the sheet,
   the calculator and the form are sized from it so they stay whole */
.prop--sheet      { left: calc((100% - 1080px) * .04);  top: auto; bottom: calc(var(--pull) - 196px); width: calc((100% - 1080px) * .39); rotate: -6deg; }
.prop--calculator { left: calc((100% - 1080px) * .19);  top: auto; bottom: calc(var(--pull) - 58px);  width: calc((100% - 1080px) * .25); rotate: 9deg; }

/* right: hockey leads at the top (V5) beside the volleyball (V4, the plain
   panel ball), the card, the goggles and the slipper, moved down from the
   top corner (V6), then the lacrosse head, baseball and form */
.prop--hockey     { right: 11%;   top: 3.5%; width: 11%;  rotate: -5deg; }
.prop--volleyball { right: 3.4%;  top: 5%;  width: 6.2%; }
.prop--card       { right: 2.5%;  top: 25%; width: 12.5%; rotate: 7deg; }
.prop--goggles    { right: 12%;   top: 42%; width: 8.5%;  rotate: -9deg; }
.prop--shoe       { right: 4.4%;  top: 45%; width: 3.6%;  rotate: 18deg; }
.prop--lacrosse   { right: 22.5%; top: auto; bottom: calc(var(--pull) + 20px); width: 4%;   rotate: 14deg; }
.prop--baseball   { right: 13.5%; top: auto; bottom: calc(var(--pull) + 22px); width: 5.2%; }
.prop--form       { right: calc((100% - 1080px) * .05); top: auto; bottom: calc(var(--pull) - 110px); width: calc((100% - 1080px) * .34); rotate: 5deg; }

/* 1100 to 1339: the dashboard spans almost the full width, so the lower
   row rides on its top edge */
@media (max-width: 1339px) {
  .prop--clipboard  { left: 1.5%;   top: 6%;  width: 8%; }
  .prop--soccer     { left: 12.5%;  top: 14%; width: 7.5%; }
  .prop--whistle    { left: 2.5%;   top: 33%; width: 4.4%; }
  .prop--football   { left: 9.5%;   top: 35%; width: 9.5%; }
  .prop--check      { left: 12.5%;  bottom: calc(var(--pull) + 24px); width: 7.5%; }
  .prop--sheet      { left: 1%;     bottom: calc(var(--pull) + 20px); width: 7.4%; rotate: -8deg; }
  .prop--calculator { left: 5.6%;   bottom: calc(var(--pull) + 10px); width: 5.2%; rotate: 10deg; }
  .prop--hockey     { right: 1.5%;  top: 3.5%; width: 10%; }
  .prop--volleyball { right: 14%;   top: 6%;  width: 5.8%; }
  .prop--card       { right: 2%;    top: 23%; width: 12%; }
  .prop--goggles    { right: 11%;   top: 41%; width: 8%; }
  .prop--shoe       { right: 3.4%;  top: 37%; width: 3.4%; }
  .prop--lacrosse   { right: 17.5%; bottom: calc(var(--pull) + 28px); width: 3.8%; }
  .prop--baseball   { right: 10.3%; bottom: calc(var(--pull) + 26px); width: 5%; }
  .prop--form       { right: 1.5%;  bottom: calc(var(--pull) + 24px); width: 6.8%; }
}
/* under 1200 the subhead takes a narrower measure so the side columns
   keep room for the field */
@media (max-width: 1199px) {
  .hero__sub   { max-width: 46ch; }
  .hero__scope { max-width: 50ch; }
}
/* 900 to 1099: fewer, smaller props hugging the edges */
@media (max-width: 1099px) {
  .prop--check,
  .prop--lacrosse,
  .prop--sheet,
  .prop--form { display: none; }
  .prop--clipboard  { left: 1.5%;   top: 6%;  width: 7.5%; }
  .prop--soccer     { left: 10.5%;  top: 14%; width: 7%; }
  .prop--whistle    { left: 2.5%;   top: 29%; width: 4%; }
  .prop--football   { left: 8%;     top: 44%; width: 9%; }
  .prop--calculator { left: 2%; bottom: calc(var(--pull) + 24px); width: 6%; rotate: -4deg; }
  .prop--hockey     { right: 7%;    top: 3%;  width: 9.5%; }
  .prop--volleyball { right: 1.8%;  top: 18.5%; width: 6%; }
  .prop--card       { right: 1.5%;  top: 31%; width: 12%; }
  .prop--goggles    { right: 9%;    top: 50%; width: 8.5%; }
  .prop--shoe       { right: 2.4%;  top: 49%; width: 3.2%; }
  .prop--baseball   { right: 8%;    bottom: calc(var(--pull) + 26px); width: 5%; }
}

/* under 900: five small props at the corners. The hockey stick and the
   card above the headline (the two eager images), the football, soccer
   ball and volleyball in the band between the Get Started pill and the
   dashboard's top edge. (.props raises specificity over motion.css, which
   loads later and sets max-width: none on every .prop.) */
@media (max-width: 899px) {
  .hero {
    padding-block: clamp(96px, 16vw, 132px) calc(var(--pull) + 96px);
  }
  .prop--desk { display: none; }
  .props .prop--hockey     { left: 2%;  right: auto; top: 10px; width: 20%; max-width: 72px; rotate: -4deg; }
  .props .prop--card       { right: 3%; left: auto; top: 14px; width: 18%; max-width: 96px; rotate: 7deg; }
  .props .prop--football   { left: 3%;  top: auto; bottom: calc(var(--pull) + 20px); width: 16%; max-width: 116px; rotate: -12deg; }
  .props .prop--soccer     { left: 27%; top: auto; bottom: calc(var(--pull) + 14px); width: 11%; max-width: 72px; }
  .props .prop--volleyball { right: 5%; top: auto; bottom: calc(var(--pull) + 16px); width: 13%; max-width: 92px; }
}

/* keeps a hyphenated compound on one line in the scope line */
.nowrap {
  white-space: nowrap;
}

/* -------------------------------------------------------- sport field ----
   V10 (partials/sports.html). Jason's line, set large across the page,
   inside a field of 32 unlabeled sport glyphs so no sport feels left out.
   1100px and up: each glyph sits in the band above (data-z="t") or below
   ("b") the statement, or in the flank beside it ("l", "r"); --x and --y
   are fractions of that zone, so the statement's box is never crossed at
   any width. Below 1100px: a tidy band of two brick rows above and below
   (data-pz, --px, --py). --r tilts through the `rotate` property, so the
   reveal's transform stays its own and ends at identity; --k sets the ink
   tone through colour, never opacity; --s is the glyph size. Strokes stay
   a true 1.5px at every size (non-scaling). motion.js reveals the glyphs
   once in DOM order, which runs outward from the statement.            */
.sport-field {
  --pad: clamp(24px, 3vw, 44px);
  --band: clamp(136px, 12vw, 176px);
  /* the statement's measure; the flanks take what is left either side */
  --sw: min(1000px, 100vw - 280px);
  position: relative;
  overflow: hidden;
  background: var(--paper);
  padding-block: var(--pad);
}
.sport-field__wrap {
  position: relative;
  z-index: 1;
  padding-block: var(--band);
}
.sport-field__line {
  max-width: var(--sw);
  margin: 0 auto;
  font-size: clamp(1.9rem, 4.1vw, 3.5rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.032em;
  text-align: center;
  text-wrap: balance;
  color: var(--ink);
}
.sport-field__em {
  color: var(--purple);
}
/* above the wrap (whose padding covers the bands) so each glyph gets its
   hover; the layer itself lets every other pointer through */
.sport-field__glyphs {
  position: absolute;
  z-index: 2;
  top: var(--pad);
  bottom: var(--pad);
  left: 0;
  right: 0;
  max-width: 1480px;
  margin-inline: auto;
  pointer-events: none;
}
.sport-field__g {
  position: absolute;
  width: var(--s);
  height: var(--s);
  margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
  rotate: var(--r);
  color: rgb(17 17 17 / var(--k));
  pointer-events: auto;
}
.sport-field__svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  transition:
    color 180ms ease,
    scale 280ms var(--ease);
}
.sport-field__svg * {
  vector-effect: non-scaling-stroke;
}
@media (min-width: 1100px) {
  .sport-field__g[data-z="t"] {
    left: calc(var(--x) * 100%);
    top: calc(var(--y) * var(--band));
  }
  .sport-field__g[data-z="b"] {
    left: calc(var(--x) * 100%);
    top: calc(100% - var(--band) + var(--y) * var(--band));
  }
  .sport-field__g[data-z="l"],
  .sport-field__g[data-z="r"] {
    top: calc(var(--band) + (100% - 2 * var(--band)) * var(--y));
  }
  .sport-field__g[data-z="l"] {
    left: calc((100% - var(--sw)) / 2 * var(--x));
  }
  .sport-field__g[data-z="r"] {
    left: calc(100% - (100% - var(--sw)) / 2 * (1 - var(--x)));
  }
}
@media (max-width: 1099px) {
  .sport-field {
    --pad: clamp(20px, 4vw, 36px);
    --band: clamp(100px, 13vw, 128px);
    --sw: 100%;
  }
  .sport-field__line {
    font-size: clamp(1.6rem, 5.4vw, 2.6rem);
    line-height: 1.12;
  }
  .sport-field__glyphs {
    left: var(--gutter);
    right: var(--gutter);
  }
  .sport-field__g {
    --s: clamp(28px, 4.4vw, 34px);
    rotate: calc(var(--r) * 0.5);
  }
  /* the 16 desktop repeats step out; the band keeps one of each sport */
  .sport-field__g[data-pz="x"] {
    display: none;
  }
  .sport-field__g[data-pz="t"] {
    left: calc(var(--px) * 100%);
    top: calc(var(--py) * var(--band));
  }
  .sport-field__g[data-pz="b"] {
    left: calc(var(--px) * 100%);
    top: calc(100% - var(--band) + var(--py) * var(--band));
  }
}
/* hover, like the hero props: the glyph turns purple, lifts, and wiggles
   once; the field itself drifts toward the pointer (js/home.js) */
@media (hover: hover) and (pointer: fine) {
  .sport-field__g:hover .sport-field__svg {
    color: var(--purple);
    scale: 1.16;
    animation: glyphWiggle 620ms var(--ease);
  }
}
@keyframes glyphWiggle {
  0% {
    rotate: 0deg;
  }
  22% {
    rotate: -12deg;
  }
  50% {
    rotate: 8deg;
  }
  76% {
    rotate: -3deg;
  }
  100% {
    rotate: 0deg;
  }
}
@media (prefers-reduced-motion: reduce) {
  .sport-field__g:hover .sport-field__svg {
    scale: none;
    animation: none;
  }
}

/* ------------------------------------------------------------ platform --
   Eight tabs (Hm8) switching on hover (Hm7, app.js). On desktop every panel
   shares one grid cell and the hidden ones keep their box, invisible, so
   the section is always as tall as its tallest panel: hovering down the
   list never moves anything below it.                                    */
.solution__layout {
  display: grid;
  grid-template-columns: 272px minmax(0, 1fr);
  gap: clamp(20px, 3vw, 36px);
  align-items: start;
}
.tablist {
  display: flex;
  flex-direction: column;
  gap: 2px;
  position: sticky;
  top: 92px;
}
.tab {
  display: flex;
  align-items: baseline;
  gap: 12px;
  width: 100%;
  min-height: 48px;
  padding: 13px 16px;
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.3;
  text-align: left;
  color: var(--muted);
  background: none;
  border: 0;
  border-radius: var(--radius-s);
  cursor: pointer;
  transition:
    color 140ms ease,
    background-color 140ms ease,
    box-shadow 140ms ease;
}
.tab__num {
  flex: none;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}
.tab:hover {
  color: var(--ink);
  background: rgba(17, 17, 17, 0.035);
}
.tab[aria-selected="true"] {
  background: var(--paper);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--hairline);
}
.tab[aria-selected="true"] .tab__num {
  color: var(--purple);
}

.tabpanels {
  position: relative;
}
.tabpanel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  gap: clamp(20px, 3vw, 40px);
  align-items: start;
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-l);
  padding: clamp(24px, 3vw, 36px);
}
.tabpanel--mock {
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
}
.tabpanel > .viz {
  align-self: stretch;
  min-height: 272px;
}
.tabpanel__mock {
  min-width: 0;
}
@media (min-width: 901px) {
  .tabpanels {
    display: grid;
  }
  .tabpanels > .tabpanel {
    grid-area: 1 / 1;
  }
  .tabpanels > .tabpanel[hidden] {
    display: grid !important;
    visibility: hidden;
  }
  /* a mock may set visibility: visible on a child (the lifecycle's
     up-next note does), which would show through a hidden panel */
  .tabpanels > .tabpanel[hidden] * {
    visibility: hidden !important;
  }
}
.tabpanel.is-shown {
  animation: tabFade 200ms var(--ease) both;
}
@keyframes tabFade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
/* the new mocks get the same small rise as the v3 viz on a tab change */
.tabpanel.is-shown .rdash,
.tabpanel.is-shown .rbud,
.tabpanel.is-shown .rcoa,
.tabpanel.is-shown .rvlc {
  animation: vizRise 220ms var(--ease) both;
}
.tabpanel h3 {
  font-size: clamp(1.3rem, 1.9vw, 1.6rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.018em;
  margin: 0;
  text-wrap: balance;
}
.tabpanel .lede {
  margin-top: 14px;
  font-size: 16.5px;
}
/* the copy column's list only: the mocks carry their own ul, ol and li */
.tabpanel__copy ul {
  margin-top: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.tabpanel__copy li {
  position: relative;
  padding-left: 22px;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--muted);
}
.tabpanel__copy li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 6px;
  height: 6px;
  background: var(--purple);
}
/* v3 product mocks shown inside a tab panel: slightly shorter field */
.viz {
  padding: 28px 24px;
}

@media (max-width: 1080px) and (min-width: 901px) {
  .solution__layout {
    grid-template-columns: 236px minmax(0, 1fr);
  }
  .tabpanel,
  .tabpanel--mock {
    grid-template-columns: minmax(0, 1fr);
  }
  .tabpanel > .viz {
    min-height: 240px;
  }
}
@media (max-width: 900px) {
  .solution__layout {
    grid-template-columns: 1fr;
  }
  .tablist {
    position: static;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }
  .tab {
    align-items: flex-start;
    padding: 12px 14px;
    font-size: 13.5px;
    gap: 8px;
    background: var(--paper);
    box-shadow: inset 0 0 0 1px var(--hairline);
  }
  .tab:hover {
    background: var(--paper);
  }
  .tab__num {
    padding-top: 1px;
  }
  .tab[aria-selected="true"] {
    box-shadow: inset 0 0 0 1px var(--ink);
  }
  .tabpanel,
  .tabpanel--mock {
    grid-template-columns: 1fr;
  }
}

/* ------------------------------------------------------ approval flow -- */
.section-head--after-chapter {
  margin-bottom: clamp(28px, 3.5vw, 44px);
}
.section-head--after-chapter .section-sub {
  margin-top: 0;
  font-size: 18px;
  max-width: 58ch;
}

.flow {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.flow__steps {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-l);
  padding: clamp(24px, 3vw, 36px);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
.step {
  position: relative;
  padding-top: 42px;
}
.step::before {
  content: "";
  position: absolute;
  top: 15px;
  left: 30px;
  right: -16px;
  height: 1px;
  background: var(--hairline);
}
.step:last-child::before {
  display: none;
}
.step__dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 30px;
  height: 30px;
  border-radius: var(--pill);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}
.step--done .step__dot {
  background: var(--ink);
  border-color: var(--ink);
  color: #ffffff;
}
.step--active .step__dot {
  background: var(--purple);
  border-color: var(--purple);
  color: #ffffff;
}
.step--done::before {
  background: var(--ink);
}
.step h3 {
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: -0.005em;
  margin: 0;
}
/* the meta line only; must not catch .step__dot */
.step h3 + span {
  display: block;
  margin-top: 6px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--faint);
}
.info-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 2px;
  color: var(--purple);
  text-decoration: none;
  font-size: 12px;
}
.info-dot:hover {
  color: var(--ink);
}

.flow__activity {
  background: var(--field);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-l);
  padding: clamp(20px, 2.4vw, 28px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.act {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid var(--hairline);
  font-size: 13px;
  line-height: 1.45;
}
.act:first-child {
  padding-top: 0;
}
.act:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
.act p {
  flex: 1;
  min-width: 0;
  color: var(--muted);
}
.act b {
  color: var(--ink);
  font-weight: 600;
}
.act time {
  font-size: 11.5px;
  color: var(--faint);
  flex: none;
}
.act .avatar {
  width: 28px;
  height: 28px;
}

@media (max-width: 900px) {
  .flow__steps {
    grid-template-columns: 1fr;
    gap: 4px;
  }
  .step {
    padding: 0 0 0 46px;
    min-height: 52px;
  }
  .step::before {
    top: 30px;
    bottom: -4px;
    left: 15px;
    right: auto;
    width: 1px;
    height: auto;
  }
  .step__dot {
    top: 0;
  }
}

/* the four dots fill in order and the rail between them draws left to right */
.js [data-steps] .step__dot {
  opacity: 0;
  transform: scale(0.72);
}
.js [data-steps] .step::before {
  transform: scaleX(0);
  transform-origin: left center;
}
.js .is-in [data-steps] .step__dot {
  opacity: 1;
  transform: none;
  transition:
    opacity 320ms var(--ease),
    transform 420ms var(--ease);
}
.js .is-in [data-steps] .step::before {
  transform: none;
  transition: transform 520ms var(--ease);
}
.js .is-in [data-steps] .step:nth-child(1) .step__dot {
  transition-delay: 60ms;
}
.js .is-in [data-steps] .step:nth-child(2) .step__dot {
  transition-delay: 260ms;
}
.js .is-in [data-steps] .step:nth-child(3) .step__dot {
  transition-delay: 460ms;
}
.js .is-in [data-steps] .step:nth-child(4) .step__dot {
  transition-delay: 660ms;
}
.js .is-in [data-steps] .step:nth-child(1)::before {
  transition-delay: 120ms;
}
.js .is-in [data-steps] .step:nth-child(2)::before {
  transition-delay: 320ms;
}
.js .is-in [data-steps] .step:nth-child(3)::before {
  transition-delay: 520ms;
}
@media (max-width: 900px) {
  .js [data-steps] .step::before {
    transform: scaleY(0);
    transform-origin: center top;
  }
}
@media (prefers-reduced-motion: reduce) {
  .js [data-steps] .step__dot,
  .js [data-steps] .step::before {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* --------------------------------------------------------------- donut --
   Hm11: hover or focus shows a category's amount (app.js). The rows sit on
   section--field, so the hot row uses a darker neutral than --field.     */
.spend {
  display: grid;
  grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
}
.donut {
  position: relative;
  width: 100%;
  max-width: 320px;
  margin-inline: auto;
}
.donut svg {
  width: 100%;
  height: auto;
  transform: rotate(-90deg);
}
.arc {
  fill: none;
  stroke-width: 36;
  cursor: pointer;
  transition:
    opacity 160ms ease,
    stroke-width 160ms ease;
}
.arc.is-dim {
  opacity: 0.28;
}
.arc.is-hot {
  stroke-width: 42;
}
.donut__hole {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  text-align: center;
}
.donut__value {
  display: block;
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
}
.donut__label {
  display: block;
  margin-top: 4px;
  font-size: 12.5px;
  color: var(--faint);
}
.spend__hint {
  margin: 0 0 18px;
  font-size: 13px;
  color: var(--faint);
}
.legend {
  border-top: 1px solid var(--hairline);
}
.cl-row {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr) 48px 86px;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 16px 8px 16px 8px;
  border-bottom: 1px solid var(--hairline);
  background: none;
  border-left: 0;
  border-right: 0;
  border-top: 0;
  font: inherit;
  font-size: 14.5px;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 140ms ease;
}
.cl-row:hover,
.cl-row.is-hot {
  background: #f0f0ee;
}
.cl-swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
}
.cl-pct,
.cl-amount {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  text-align: right;
}
.cl-amount {
  color: var(--ink);
  font-weight: 600;
}
@media (max-width: 820px) {
  .spend {
    grid-template-columns: 1fr;
  }
  .cl-row {
    grid-template-columns: 14px minmax(0, 1fr) 42px 78px;
    gap: 10px;
    font-size: 13.5px;
  }
}

/* ------------------------------------------------------ pinned chapters --
   The words sit in the middle ~22% of the viewport height. Photo tiles
   (and one small product row) assemble in the bands above and below them
   while pinned: data-pin-item, scrubbed by motion.js. Every tile is sized
   with min(vw, svh) so it stays in its band at any desktop aspect, and
   the chapter is exactly 100svh tall while pinned, so % positions map to
   the viewport. Reduced motion shows the same arrangement, at rest.     */
.chapter--b .chapter__display {
  font-size: clamp(2rem, 5.1vw, 4.4rem);
}
.tile {
  display: block;
  height: auto;
  max-width: none;
  object-fit: cover;
  border-radius: 14px;
  background: #1d1d1d;
}
.tile--a-hockey,
.tile--b-dugout,
.tile--b-volleyball {
  aspect-ratio: 4 / 5;
}
.tile--a-volunteers,
.tile--a-soccer,
.tile--a-parents,
.tile--b-swim,
.tile--b-dance,
.tile--b-lacrosse {
  aspect-ratio: 3 / 2;
}

/* the product rows riding with the photos */
.frag-row,
.frag-ledger {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border-radius: var(--radius-s);
  background: var(--paper);
  color: var(--ink);
  font-size: 12.5px;
  white-space: nowrap;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
}
.frag-row__t {
  color: var(--muted);
}
.frag-ledger {
  justify-content: space-between;
  gap: 28px;
  min-width: 232px;
}
.frag-ledger b {
  font-variant-numeric: tabular-nums;
}
.frag-row .status {
  flex: none;
}

@media (min-width: 900px) {
  .chapter__tiles {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
  }
  .tile,
  .tile-chip {
    position: absolute;
  }
  .tile {
    box-shadow: 0 30px 60px rgba(0, 0, 0, 0.45);
  }
  [data-pin][data-state="scrub"] .tile,
  [data-pin][data-state="scrub"] .tile-chip {
    will-change: transform, opacity;
  }

  /* A: volunteers and hockey above, the approval row, soccer and the
     stands below */
  .tile--a-volunteers {
    left: 4%;
    top: 11%;
    width: min(20vw, 32svh);
  }
  .tile--a-hockey {
    right: 5%;
    top: 6%;
    width: min(14vw, 23svh);
  }
  .tile-chip--a {
    left: 36%;
    top: 21%;
  }
  .tile--a-soccer {
    left: 7%;
    bottom: -3%;
    width: min(28vw, 50svh);
  }
  .tile--a-parents {
    right: 4%;
    bottom: 7%;
    width: min(22vw, 40svh);
  }

  /* B: dugout, swim, dance above; lacrosse, a ledger row, volleyball below */
  .tile--b-dugout {
    left: 4%;
    top: 6%;
    width: min(14vw, 23svh);
  }
  .tile--b-swim {
    left: 29%;
    top: 12%;
    width: min(19vw, 33svh);
  }
  .tile--b-dance {
    right: 5%;
    top: 11%;
    width: min(21vw, 36svh);
  }
  .tile--b-lacrosse {
    left: 8%;
    bottom: 5%;
    width: min(25vw, 45svh);
  }
  .tile-chip--b {
    left: 45%;
    bottom: 15%;
  }
  .tile--b-volleyball {
    right: 8%;
    bottom: -4%;
    width: min(16vw, 26svh);
  }
}
@media (min-width: 900px) and (max-width: 1180px) {
  .tile-chip--a {
    left: 30%;
  }
  .tile-chip--b {
    left: 40%;
  }
}

/* phone and tablet: no pin (motion.js), the words and then a tidy collage */
@media (max-width: 899px) {
  .chapter {
    flex-direction: column;
    align-items: stretch;
  }
  .chapter__tiles {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    width: 100%;
    max-width: var(--maxw);
    margin: clamp(32px, 6vw, 48px) auto 0;
    padding-inline: var(--gutter);
  }
  .tile {
    width: 100%;
    min-width: 0;
  }
  .tile-chip {
    display: none;
  }
  .tile--a-hockey {
    grid-column: 1;
    grid-row: 1 / span 2;
    height: 100%;
    aspect-ratio: auto;
  }
  .tile--a-soccer {
    grid-column: 2;
    grid-row: 1;
  }
  .tile--a-parents {
    grid-column: 2;
    grid-row: 2;
  }
  .tile--a-volunteers {
    grid-column: 1 / -1;
    grid-row: 3;
    aspect-ratio: 16 / 9;
  }

  .tile--b-swim {
    grid-column: 1 / -1;
    grid-row: 1;
    aspect-ratio: 16 / 9;
  }
  .tile--b-dugout {
    grid-column: 1;
    grid-row: 2;
  }
  .tile--b-volleyball {
    grid-column: 2;
    grid-row: 2;
  }
  .tile--b-lacrosse {
    grid-column: 1;
    grid-row: 3;
  }
  .tile--b-dance {
    grid-column: 2;
    grid-row: 3;
  }
}

/* --------------------------------------------------------- pull quote --
   Hm13 + V2. One quote, large, on ink, across the full width. The prism
   film is gone (Jason: the prism lives in the closing bands only). The two
   drawn [R] brackets, in the purple lifted for ink, frame the quote and
   draw once as it arrives: the Our Story pull-quote device Jason likes. */
.quote-sec {
  position: relative;
  overflow: hidden;
  padding-top: clamp(112px, 11vw, 168px);
}
.section--field + .quote-sec .sheet {
  background: var(--field);
}
.quote-sec > .wrap {
  position: relative;
  z-index: 2;
}
.quote-sec__head {
  margin-bottom: clamp(36px, 4.6vw, 64px);
}
.quote-sec__head .h2 {
  max-width: 22ch;
}
.pull {
  position: relative;
  margin: 0;
  padding: clamp(34px, 4vw, 58px) clamp(28px, 4.6vw, 72px)
    clamp(30px, 3.4vw, 50px);
}
.quote-sec .pull .pull__bracket {
  position: absolute;
  width: clamp(30px, 3.6vw, 52px);
  height: clamp(30px, 3.6vw, 52px);
  color: var(--purple-lift);
}
.quote-sec .pull .pull__bracket path {
  stroke-width: 2.5;
}
.pull__bracket--tl {
  top: 0;
  left: 0;
}
.pull__bracket--br {
  right: 0;
  bottom: 0;
  rotate: 180deg;
}
.pull__quote p {
  font-size: clamp(1.35rem, 2.95vw, 2.65rem);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: #ffffff;
  /* hang the opening quote mark so the text edge stays true */
  text-indent: -0.4em;
  text-wrap: pretty;
}
/* after motion.js splits the quote into masked lines, only the first line
   hangs, and each mask gets room on the left so the mark is not clipped */
.pull__quote .rl-line {
  padding-left: 0.5em;
  margin-left: -0.5em;
}
.pull__quote .rl-line + .rl-line {
  text-indent: 0;
}
.pull__who {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: clamp(28px, 3.2vw, 44px);
  padding-left: 22px;
}
.pull__who::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 8px;
  background: var(--purple-lift);
}
.pull__name {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.005em;
}
.pull__role {
  font-size: 14.5px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.68);
}
@media (max-width: 899px) {
  .quote-sec__head {
    margin-bottom: 24px;
  }
  .pull {
    padding: 30px 18px 26px 22px;
  }
}

/* -------------------------------------------------------- who we serve -- */
.roles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
}
.role {
  display: flex;
  flex-direction: column;
  background: var(--field);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-l);
  overflow: hidden;
}
.role__photo {
  width: 100%;
  height: auto;
  aspect-ratio: 5 / 4;
  object-fit: cover;
  background: var(--hairline);
}
.role__photo--treasurer {
  object-position: 50% 68%;
}
.role__photo--board {
  object-position: 50% 50%;
}
.role__photo--manager {
  object-position: 50% 30%;
}
.role__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: clamp(22px, 2.6vw, 30px);
}
.role__body .eyebrow {
  margin: 0;
}
.role h3 {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.2;
  margin: 0;
  text-wrap: balance;
}
.role__body > p:last-child {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--muted);
  margin: 0;
}
@media (max-width: 860px) {
  .roles {
    grid-template-columns: 1fr;
  }
  .role__photo {
    aspect-ratio: 16 / 10;
  }
}

.works {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 32px;
  padding-top: 28px;
  border-top: 1px solid var(--hairline);
}
.works__label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-right: 6px;
}
.works__more {
  margin-top: 12px;
}
