/* clubs-c05.css — For Clubs C05 (Built for your gym floor), "Case to
   floor, one half at a time" (Alessandro, 9 Oct 2026; the cases as chosen
   on 8 Oct; recomposed twice on 9 Oct: after "a bit lazy … a balanced
   element for the station drawings", then so that each point sits with the
   visual that explains it: "this is explaining the first point of the
   section though, it's wrong to keep it later"). Classes gf- (gym floor)
   and gfp- (the floor band: the station setups in two halves); behaviour
   in clubs.js. Colours come from the surface roles only; the one energy
   accent is Vermilion: the lit Flux Pods and the connector's arrow.

   Composition (Chalk), on the 12-column grid: the heading (columns 1–8),
   then the three points in order, each item of the list a row of its own
   on the page's columns holding the visual that explains it, with a rule
   over each point's text. On desktop the text and the visuals alternate
   sides: the first point over its band on the left, the second point on
   the right of its cases, and the closing point across the page.
   1. .gf-point--setup, the floor band (Oyster, full bleed, its content on
      the page's own columns): "Quick participant setup" in columns 1–5
      over the class in two halves: "First half of the class" (Floor ·
      2 pods, Mixed · 4 pods) in columns 1–5, "Second half of the class"
      (Floor · 6 pods, Raised · 2 pods) in columns 8–12, and in columns 6–7
      the connector: its arrow standing on the floor between the halves, at
      pod height, and under it, on the names' line, "Kit rearranged at the
      central break" in the editorial italic. Each half's title, drawings
      and names share three rows with the other half's (subgrid), so both
      titles, all four drawings, the arrow and all five captions sit on
      common lines, and one floor line runs under them from edge to edge of
      the window. Without subgrid the band keeps the same columns and each
      pair of setups stands on its own floor.
   2. .gf-point--portable, back on Chalk (Chalk round the band as deep as
      the section's padding): the two charging cases (renders, D-30) in
      columns 1–6, each with its label on its open side and a short rule
      running to the case, and "Portable equipment" in columns 8–12 (under
      the second half), centred on the cases.
   3. .gf-point--space, the closing point, no visual: its rule runs across
      the page, the title in columns 1–6 and the text in columns 8–12 (the
      second point's column), on one first baseline. On desktop the Chalk
      over it is the section's padding too, so the cases row sits centred
      between the band and this rule.
   Below 1024 px: one column — the heading, then each point followed
   directly by its visual: the band (full bleed too: the point, then the
   halves one under the other and the connector between them, its arrow
   pointing down; on landscape phones from 780 px the halves side by side,
   the arrow pointing right), "Portable equipment" and the cases, then the
   closing point.

   Motion: each point's text arrives through the shared [data-arrive]
   primitive as it comes into view, its rule drawing left to right; the
   cases arrive through it too (a longer rise, settling to a slight tilt)
   and drift at two depths with the scroll (CSS scroll-driven animation
   where supported); each label travels with its case. clubs.js adds
   .is-live to the band's stations (.gfp) when motion is allowed and gives
   each drawing a layer of outlines (.gfp-ghost: where each piece stands in
   that setup). Live, the kit stands in one half (data-on) and goes to the
   other without stopping (a half stands about 3 s): the set half's pieces
   (each tablet, each Flux Pod with its stand) lift away in a quick
   left-to-right wave (--w: the piece's place across its half, 0 to 1),
   leaving their outlines on the floor, and the other half's are set down
   on theirs in the same sweep (the two waves overlap, so the kit never
   blinks out), pods lighting as they land; the change takes under 0.9 s.
   The half without its kit has its title and names in Muted Plum. The
   arrow is quiet (Muted Plum) while the kit is in the first half and
   lights from end to end in Vermilion as the kit moves to the second. The
   titles, names and connector never move. Without .is-live (no script,
   reduced motion, print) both halves are set and lit, all text is at full
   strength and the arrow is lit: the complete composed state. */
.gf { overflow-x: clip; }   /* the tilted cases and the full-bleed band never widen the page */
.gf__grid { row-gap: var(--space-6); }
.gf__title { margin: 0; }

/* =========================================================================
   The points, in order, each with its visual
   ========================================================================= */
/* each item a row on the page's own columns (the list spans the container,
   so its items' tracks are the page's) */
.gf-points { margin: 0; padding: 0; list-style: none; }
.gf-point {
  display: grid;
  grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  column-gap: var(--grid-gutter);
  row-gap: var(--space-6);
  min-width: 0;
}
.gf-point > * { grid-column: 1 / -1; min-width: 0; }
.gf-point--portable { margin-top: var(--section-pad); }   /* Chalk under the band as deep as the section's padding */
.gf-point--space { margin-top: var(--space-7); }

/* each point's text: a rule over it, drawn as it arrives */
.gf-point__text { position: relative; padding-top: var(--space-5); }
.gf-point__text::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  border-top: 1px solid var(--on-line);
  transform-origin: left center;
}
.gf-point__text h3 { margin: 0 0 var(--space-3); }
.gf-point__text p { margin: 0; max-width: var(--measure); text-wrap: pretty; }   /* no last word alone on its line (same line counts, so no height moves) */

/* 1 · the floor band: full bleed — the margin takes it to both edges of the
   window and the padding brings its content back by the same amount, so
   the point and the stations stand on the page's own columns (.gf's
   overflow-x: clip absorbs a scrollbar's width in 100vw) */
.gf-point--setup {
  row-gap: var(--space-7);          /* the point to the two halves */
  margin-inline: calc(50% - 50vw);
  padding: var(--space-7) calc(50vw - 50%);
}

/* desktop: the heading on one line; text and visuals alternate sides */
@media (min-width: 1024px) {
  .gf__grid { row-gap: var(--space-8); }
  .gf__title { grid-column: 1 / span 8; }
  .gf-point--setup { row-gap: var(--space-8); padding-block: var(--space-8); }
  .gf-point--setup > .gf-point__text { grid-column: 1 / span 5; }
  /* 2 · the cases on the left, the point on the right, centred on them */
  .gf-point--portable > .gf-cases { grid-column: 1 / span 6; grid-row: 1; max-width: none; }
  .gf-point--portable > .gf-point__text { grid-column: 8 / span 5; grid-row: 1; align-self: center; }
  /* 3 · the closing point across the page: the title on the left, the text
     in the second point's column, on one first baseline */
  .gf-point--space { margin-top: var(--section-pad); }   /* the same Chalk as over the cases, so the cases row sits centred between the band and the closing point */
  .gf-point--space > .gf-point__text {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gutter);
    align-items: baseline;
  }
  .gf-point--space h3 { grid-column: 1 / span 6; margin: 0; }
  .gf-point--space p { grid-column: 8 / span 5; }
}

/* =========================================================================
   2 · The charging cases
   ========================================================================= */
/* the two cases on a diagonal: the tall soft case high on the right, the
   hard case low on the left and in front, their corners just meeting */
.gf-cases {
  --gf-gap: var(--space-4);         /* label to case */
  position: relative;
  width: 100%;
  max-width: 560px;
  margin-inline: auto;
  aspect-ratio: 1 / 1.02;
}
.gf-case { position: absolute; margin: 0; }
.gf-case img { display: block; width: 100%; height: auto; rotate: var(--gf-tilt, 0deg); }
.gf-case--tablets { --gf-tilt: -2.5deg; top: 0; right: 2%; width: 52%; }
.gf-case--pods { --gf-tilt: 2deg; left: 0; bottom: 0; width: 58%; z-index: 1; }

/* the labels: Text 650 at body size (17–20px), on each case's open side
   (the tablets case's left, above the hard case; the hard case's right,
   under the soft case), with a short rule over the label running to its
   case */
.gf-case figcaption {
  position: absolute;
  font-size: var(--text-body);
  font-weight: var(--weight-strong);
  line-height: 1.3;
  color: var(--on-text);
  text-wrap: balance;
}
.gf-case figcaption::before {
  content: "";
  display: block;
  width: calc(var(--space-6) + var(--gf-gap));
  height: 2px;
  margin-bottom: var(--space-2);
  background: currentColor;
}
.gf-case--tablets figcaption {
  right: 100%;
  top: 30%;
  width: 82%;                       /* the open corner left of the case */
  padding-right: var(--gf-gap);
  text-align: right;
}
.gf-case--tablets figcaption::before { margin-left: auto; margin-right: calc(-1 * var(--gf-gap)); }
/* phones: level with its own lid, clear of the Flux Pod case below */
@media (max-width: 639px) { .gf-case--tablets figcaption { top: 12%; } }
/* desktop: a little wider, so the label sets in two lines from 1024 px too
   (three ragged lines otherwise); its words still start inside the cases'
   columns */
@media (min-width: 1024px) { .gf-case--tablets figcaption { width: 96%; } }
.gf-case--pods figcaption {
  left: 94%;                        /* the hard case's own edge, inside its picture's margin */
  top: 58%;
  width: 76%;                       /* the open corner right of the case, to the box edge */
  padding-left: var(--gf-gap);
}
.gf-case--pods figcaption::before { margin-left: calc(-1 * var(--gf-gap)); }
/* landscape phones (wide but short): the pair fits the screen under the
   header; the labels take the free width beside it, so they keep two
   lines instead of four */
@media (min-width: 640px) and (max-width: 1023px) and (max-height: 540px) {
  .gf-cases { max-width: min(560px, calc((100svh - var(--header-h) - var(--space-7)) / 1.02)); }
  .gf-case--tablets figcaption { width: 150%; }
  .gf-case--pods figcaption { width: 120%; }
}

/* =========================================================================
   1 · The floor band's stations: the class in two halves
   ========================================================================= */
.gfp {
  --gfp-gap: 0px;                   /* phones: the two drawings of a pair meet (each has its own margin round its pieces) */
  display: grid;
  row-gap: var(--space-6);
}
@media (min-width: 640px) {
  .gfp { --gfp-gap: var(--space-6); }   /* between the two setups of a half */
}

.gfp-half { min-width: 0; }
.gfp-half__lab {
  margin: 0 0 var(--space-5);
  font-size: var(--text-lead);      /* 19–24px: the halves' titles, under the point's title, above the case labels */
  font-weight: var(--weight-strong);
  line-height: 1.3;
  color: var(--on-text);
}
.gfp-setups { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.gfp-setup { margin: 0; min-width: 0; }
/* each pair's floor: one line under the pair, running past both drawings
   (each drawing's box ends on the floor, y 152 in the drawing). From 1024 px
   with subgrid the band draws one floor under all four instead */
.gfp-fig { padding-inline: calc(var(--gfp-gap) / 2); border-bottom: 2px solid var(--on-line); }
.gfp-setup figcaption {
  padding-top: var(--space-3);
  font-size: var(--text-ui);
  font-weight: var(--weight-strong);
  line-height: 1.25;
  text-align: center;
  color: var(--on-text);
}

/* the setup drawings: the homepage's front views (7 Oct), drawn as the
   product screens draw the pods (Ink housing, Vermilion top); the tablet
   and its stand quieter, in Muted Plum */
.gfp-svg { display: block; width: 100%; max-width: 300px; height: auto; margin-inline: auto; overflow: visible; color: var(--on-text); }
.gfp-ln {
  fill: none;
  stroke: currentColor;
  stroke-width: 2px;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.gfp-pod__body { fill: currentColor; }
.gfp-pod__top { fill: var(--color-brand-energy); }    /* lit: the composed state */
.gfp-tab { color: var(--on-muted); }
.gfp-screen { fill: var(--on-line); }
/* the outlines (live only, added by clubs.js): where each piece stands */
.gfp-ghost { display: none; }

/* the connector: its label (.ed, the editorial italic: the point of the
   band, in its own voice), then the arrow (Vermilion; a line with a
   chevron head). Stacked (below 1024 px) the arrow points down, beside the
   label, from the first half to the second */
.gfp-break {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin: 0;
  font-size: var(--text-body);
  line-height: 1.25;
  text-wrap: balance;
  color: var(--on-text);
}
.gfp-break__lab { order: 1; }
.gfp-arrow {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 16px;
  color: var(--color-brand-energy);
}
.gfp-arrow__line {
  position: relative;
  width: 2px;
  height: var(--space-8);
  border-radius: 1px;
  background: currentColor;
}
/* the lit run over the line (live: drawn as the kit moves to the second half) */
.gfp-arrow__line::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--color-brand-energy);
  transform-origin: center top;
}
.gfp-arrow__head {
  width: 11px;
  height: 11px;
  margin-top: -10px;                /* its tip on the line's end */
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  border-radius: 0 0 1px 0;
  rotate: 45deg;                    /* pointing down */
}

/* desktop: the halves side by side on the page's own columns (the band's
   item spans all twelve), the connector between them (without subgrid:
   centred on the drawings) */
@media (min-width: 1024px) {
  .gfp {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--grid-gutter);
  }
  .gfp-half__lab { margin-bottom: var(--space-6); }
  .gfp-half--1 { grid-column: 1 / span 5; grid-row: 1; }
  .gfp-half--2 { grid-column: 8 / span 5; grid-row: 1; }
  .gfp-setups { column-gap: var(--grid-gutter); }
  .gfp-fig { padding-inline: 0; }
  .gfp-break {
    grid-column: 6 / span 2;
    grid-row: 1;
    flex-direction: column;
    align-self: center;
    gap: var(--space-3);
    text-align: center;
  }
  .gfp-break__lab { order: 0; }
  .gfp-arrow { flex-direction: row; width: 100%; max-width: 160px; }
  .gfp-arrow__line { flex: 1; width: auto; height: 2px; }
  .gfp-arrow__line::after { transform-origin: left center; }
  .gfp-arrow__head { margin: 0 0 0 -10px; rotate: -45deg; }   /* pointing right */

  /* with subgrid: the stations' columns are the page's and the halves
     share three rows (titles, drawings, names), so everything sits on
     common lines. The connector comes apart into those rows: the arrow
     stands on the floor in the drawings' row, at pod height, so the kit
     visibly travels along the floor from half to half; its label sits in
     the names' row with the names' own space above it, which sets its
     first baseline on theirs (measured: within 1px, 1024–1920). One floor
     line runs under the drawings and the arrow, from edge to edge of the
     window */
  @supports (grid-template-rows: subgrid) {
    .gfp { grid-template-columns: subgrid; grid-template-rows: auto auto auto; row-gap: 0; }
    .gfp-half { grid-row: 1 / span 3; display: grid; grid-template-rows: subgrid; }
    .gfp-setups { grid-row: 2 / span 2; grid-template-rows: subgrid; }
    .gfp-setup { grid-row: span 2; display: grid; grid-template-rows: subgrid; }
    .gfp-fig { align-self: end; border-bottom: 0; }
    .gfp-break { display: contents; }
    .gfp-arrow {
      grid-column: 6 / span 2;
      grid-row: 2;
      align-self: end;
      width: auto;
      max-width: none;
      margin-bottom: var(--space-2);
    }
    .gfp-break__lab {
      grid-column: 6 / span 2;
      grid-row: 3;
      padding-top: var(--space-3);
      text-align: center;
    }
    .gfp::before {
      content: "";
      grid-column: 1 / -1;
      grid-row: 3;
      align-self: start;
      margin-inline: calc(50% - 50vw);
      border-top: 2px solid var(--on-line);
    }
  }
}

/* ---- live: the kit goes from half to half ---- */
.gfp.is-live .gfp-ghost { display: inline; }
.gfp.is-live .gfp-ghost .gfp-ln {
  fill: none;
  stroke: var(--on-muted);
  stroke-width: 1.5px;
  stroke-dasharray: 3 4;
  opacity: 0.6;
}
/* phones: a finer dash, so the small outlines keep their shape */
@media (max-width: 639px) { .gfp.is-live .gfp-ghost .gfp-ln { stroke-dasharray: 2 2.5; } }

/* the half without its kit: its title and names in Muted Plum (they dim
   as its pieces lift and come back as the kit lands) */
.gfp.is-live .gfp-half :is(.gfp-half__lab, figcaption) {
  color: var(--on-muted);
  transition: color 240ms var(--ease-out);
}
.gfp.is-live[data-on="1"] .gfp-half--1 :is(.gfp-half__lab, figcaption),
.gfp.is-live[data-on="2"] .gfp-half--2 :is(.gfp-half__lab, figcaption) {
  color: var(--on-text);
  transition-delay: 120ms;
}

/* every piece leaves and arrives on its own, in a wave across its half:
   off = lifted away (above, transparent); the half the kit is in = set
   down. Out from 0 to about 0.42 s, in from 0.12 s to about 0.84 s: the
   two waves overlap (the halves are different places, so nothing needs
   clearing first), and the kit sweeps left to right along the arrow
   without a blank beat (measured: at least 4 of the 18 pieces showing at
   every moment of either change) */
.gfp.is-live .gfp-pc {
  opacity: 0;
  transform: translateY(-16px);
  transform-box: fill-box;
  transition: opacity 180ms cubic-bezier(0.4, 0, 1, 1), transform 260ms cubic-bezier(0.4, 0, 1, 1);
  transition-delay: calc(var(--w, 0) * 240ms);
}
.gfp.is-live[data-on="1"] .gfp-half--1 .gfp-pc,
.gfp.is-live[data-on="2"] .gfp-half--2 .gfp-pc {
  opacity: 1;
  transform: none;
  transition-duration: 240ms, 420ms;
  transition-timing-function: var(--ease-out), cubic-bezier(0.25, 1.3, 0.5, 1);   /* a small settle on landing */
  transition-delay: calc(120ms + var(--w, 0) * 300ms);
}
/* the pods go dark as they lift and light once they have landed */
.gfp.is-live .gfp-pc .gfp-pod__top { fill: currentColor; transition: fill 120ms var(--ease-out); }
.gfp.is-live[data-on="1"] .gfp-half--1 .gfp-pc .gfp-pod__top,
.gfp.is-live[data-on="2"] .gfp-half--2 .gfp-pc .gfp-pod__top {
  fill: var(--color-brand-energy);
  transition-delay: calc(420ms + var(--w, 0) * 300ms);
}

/* the arrow: quiet while the kit is in the first half; as it moves to the
   second, the lit run draws from the first half to the second and the head
   lights as it arrives; on the way back it fades */
.gfp.is-live .gfp-arrow { color: var(--on-muted); }
.gfp.is-live .gfp-arrow__line::after {
  opacity: 0;
  scale: 1 0;
  transition: opacity 280ms var(--ease-out), scale 0s 280ms;
}
.gfp.is-live[data-on="2"] .gfp-arrow__line::after {
  opacity: 1;
  scale: 1 1;
  transition: opacity 0s 120ms, scale 620ms var(--ease-out) 120ms;
}
.gfp.is-live .gfp-arrow__head { transition: border-color 200ms var(--ease-out); }
.gfp.is-live[data-on="2"] .gfp-arrow__head { border-color: var(--color-brand-energy); transition-delay: 520ms; }
@media (min-width: 1024px) {
  .gfp.is-live .gfp-arrow__line::after { scale: 0 1; }
}

/* landscape phones from 780 px (wide but short): the two halves side by
   side with the connector between them, its arrow pointing right, so the
   band fits one screen and the kit is seen going from half to half (the
   halves stacked are about three screens tall there). Below 780 px the
   names would break ("Mixed · 4 / pods"), so the halves stay stacked */
@media (min-width: 780px) and (max-width: 1023px) and (max-height: 540px) {
  .gfp {
    --gfp-gap: 0px;
    grid-template-columns: minmax(0, 1fr) minmax(0, 8.5rem) minmax(0, 1fr);
    column-gap: var(--space-5);
  }
  .gfp-half--1 { grid-column: 1; grid-row: 1; }
  .gfp-half--2 { grid-column: 3; grid-row: 1; }
  .gfp-break {
    grid-column: 2;
    grid-row: 1;
    flex-direction: column;
    align-self: center;
    gap: var(--space-3);
    text-align: center;
  }
  .gfp-break__lab { order: 0; }
  .gfp-arrow { flex-direction: row; width: 100%; }
  .gfp-arrow__line { flex: 1; width: auto; height: 2px; }
  .gfp-arrow__line::after { transform-origin: left center; }
  .gfp-arrow__head { margin: 0 0 0 -10px; rotate: -45deg; }   /* pointing right */
  .gfp.is-live .gfp-arrow__line::after { scale: 0 1; }
}

/* set at once (the band going live, reduced motion switched on or off) */
.gfp.gfp-instant, .gfp.gfp-instant *, .gfp.gfp-instant *::after { transition: none !important; }

/* ---- motion ---- */
@media (prefers-reduced-motion: no-preference) {
  /* each point's rule draws left to right as its text arrives */
  .motion-ready .gf-point__text[data-arrive]:not(.is-in)::before { transform: scaleX(0); }
  .motion-ready .gf-point__text[data-arrive]::before { transition: transform calc(var(--duration-expressive) * 2) var(--ease-out); }

  /* the cases: a longer rise with a turn, settling to their tilt */
  .motion-ready .gf-cases[data-arrive]:not(.is-in) .gf-case { opacity: 0; transform: translateY(80px) rotate(-7deg); }
  .motion-ready .gf-cases[data-arrive]:not(.is-in) .gf-case--pods { transform: translateY(110px) rotate(8deg); }
  .motion-ready .gf-cases[data-arrive] .gf-case {
    transition: opacity 420ms var(--ease-out), transform 900ms cubic-bezier(0.18, 0.9, 0.24, 1.08);
    transition-delay: calc(var(--i, 0) * 180ms);
  }
}

/* the cases drift at two depths while the section passes (scroll-linked, so
   it moves only as the visitor scrolls); the drift is on the figure, so each
   label moves with its case */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .gf-case {
      animation: gf-drift linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }
    .gf-case--tablets { --gf-drift: 44px; }
    .gf-case--pods { --gf-drift: 16px; }
  }
  /* phones and tablets: the cases sit right under their point; a shorter drift */
  @media (prefers-reduced-motion: no-preference) and (max-width: 1023px) {
    .gf-case--tablets { --gf-drift: 16px; }
    .gf-case--pods { --gf-drift: 6px; }
  }
}
@keyframes gf-drift {
  from { translate: 0 var(--gf-drift, 30px); }
  to { translate: 0 calc(-1 * var(--gf-drift, 30px)); }
}
