/* ============================================================
   SECTION 01 — "WHAT WE BUILD", as a pinned horizontal slide.
   Chosen from six treatments on s01b.html (option E), founder-locked.

   Replaces: mono eyebrow → h2 → two ledes → a three-up card grid with a phone
   segmented control. That skeleton was the generic SaaS feature section, and it
   also argued against its own heading — three cards in a row are three separate
   objects, which is the opposite of "not separate apps you have to join up".

   ⚠️ NOTHING IN HERE MAY CARRY `data-rise`. The reveal sets
   `transform: none` on `.in` (site.css:304) and every moving part of this
   section IS a transform. trio.css:60 records the same collision from the other
   direction — the tilt and the reveal cannot share an element. The pin is the
   entrance; it needs no second one.
   ============================================================ */

/* Founder-directed: 01 keeps the flat warm off-white it had. It was briefly
   given the hero's ramp run backwards (mocha at the top, white at the bottom)
   and the founder reverted it — "keep So what is the system? like it was".
   The scoped --ink-3/--ink-4/--accent-ink went with it: those existed only
   because the ramp's top was #DECBB6, darker than the paper the tokens were
   solved against. On a flat #FFFEFC the root values are already correct, and a
   scope kept past the reason for it is the kind of thing that silently darkens
   a label three redesigns later. */
/* Reverted to the warm off-white, founder-directed. This section has now been
   #FFFEFC, then the hero's ramp run backwards, then #FFFEFC again, then a black
   slab, and now #FFFEFC once more. `.sec--ink` and its `data-theme="dark"` came
   off the element together — leaving either behind is how a section ends up
   with dark tokens on a light ground and no visible cause. 03 keeps the slab. */
.sec--flush { background: var(--paper-warm); }

/* Padding, founder-directed. This was `padding-block: 0` on the reasoning that
   a pinned section supplies its own rhythm — true of the SCROLL distance, false
   of the section's edges: the band starts flush against the top of the section
   and ends flush against the bottom, so the hero's edge and 02's edge each butt
   straight onto it with nothing in between. The pin does not care; it is
   sticky inside `.hzp`, and `.hzp` simply starts 96px lower. */
.sec--flush { padding-block: var(--s7); }
/* ⚠️ MORE AIR ABOVE THE HEADING, LESS BELOW — founder-directed, "add some
   padding top". The two are set separately now: the hero ends with its marquee
   flush against its own bottom edge, so 64px was all that separated a moving
   band of text from this section's first line. The bottom stays at --s6, since
   the section below it needs no help.
   96, not 128: the last time a number here was doubled the answer was "i meant
   like 10-20px". */
@media (max-width: 760px) { .sec--flush { padding-block: var(--s7) var(--s6); } }

/* the fragment mount. `on-paper` is the token hook dark.css already keys on for
   light surfaces — a NEW class name here would render every fragment off-white
   on white, silently, because that scope is an enumerated list. */
.fx { background: var(--white); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: var(--s3); }
.hzp__p .s1b__more { display: inline-flex; align-items: center; min-height: 44px; gap: 6px;
  font-size: var(--t-xs); font-weight: 600; color: var(--ink); }
.hzp__p .s1b__more::after { content: '→'; transition: transform var(--fast) var(--ease); }
.hzp__p .s1b__more:hover::after { transform: translateX(3px); }
.hzp__p .s1b__mores { display: flex; gap: var(--s4); }
.hzp__head h2 { font-family: var(--display); font-weight: var(--w-display);
  line-height: 1.05; letter-spacing: -0.02em; color: var(--ink); margin: 0; }
.hzp__head .s1b__lede { line-height: 1.45; color: var(--ink-3); }
.hzp__p .s1b__b { line-height: 1.5; color: var(--ink-3); }

/* ============================================================
   E — PINNED HORIZONTAL SCROLL.  Founder-directed: the section holds still and
   the three parts travel across it, one replacing the last, with the card and
   the type moving at different rates.

   HOW A VERTICAL SCROLL BECOMES A HORIZONTAL ONE, WITHOUT A SCRIPT.
   The 300vw track is translated by a CSS scroll-driven animation bound to the
   band's own view-timeline, so the browser maps scroll position to X offset on
   the compositor. No scroll listener, no rAF loop, nothing that can jank, be a
   frame late, or be missing on first paint.

   `animation-range: contain 0% contain 100%` is the span in which the container
   covers the viewport. For a subject taller than the scrollport that is where
   the sticky child is locked — near enough exactly, and the holds absorb the
   remainder (see the keyframes below).

   THE PARALLAX. Card and headline share the timeline and the range and travel
   in OPPOSITE directions. That is what makes it read as depth rather than as a
   slideshow: across the full pin the track moves 200vw while the headline
   drifts 60px one way and the card 90px the other, so the two planes separate.
   The card's rotation is written INSIDE its keyframes — transform is a single
   property, so a separate `rotate()` rule would be overwritten the instant the
   animation took hold and the card would snap flat mid-scroll.

   WHEN IT CANNOT RUN. Two cases, one fallback. Safari and Firefox have no
   scroll-driven animations, and a reduced-motion reader has asked not to be
   moved. Both get the same thing: the pin is dropped and the track becomes an
   ordinary horizontal scroller with snap points — a real version of the same
   idea, three panels you move through sideways, rather than a broken one. That
   fallback is the only reason a pinned section is safe to ship at all.
   ============================================================ */
/* A PINNED BAND, NOT A PINNED SCREEN.

   Three founder notes converge here and the resolution is one construction, so
   the history is worth keeping:
     1. "covers the entire screen"  → the section owned the viewport.
     2. "reduce the section height" → 84vh at top:8vh, which changed nothing:
        what fills the viewport during a pin is the pin's own tall container, so
        the 8vh of "page" above and below was more of the same empty section.
     3. "its gotta pin the viewport" → the pin itself was never the problem.

   The problem was that the sticky child was the HEIGHT OF THE VIEWPORT. A pin
   that tall can only ever own the screen. A pin 660px tall, centred, leaves
   ~240px of viewport that is not the band — and because the container is only
   200vh rather than 340, the hero's bottom edge is still in that space when the
   band locks and section 02's top is in it before the band lets go. The band
   holds still, the panels slide across it, and the page is visibly still a page.

   The container also dropped 340vh → 200vh: the stretch of scrolling this
   section commands is now about one screen instead of two and a half, which is
   what "reduce the section height" was really asking for. This section is 620px
   of layout against 488–1018px for every other section on the page.

   `top` is a max() so the band never gets pushed off a short viewport: on
   anything under ~710px tall it pins near the top instead of being centred at a
   negative offset. */
.hzp { height: 250vh; position: relative;
  view-timeline-name: --hzp; view-timeline-axis: block; }
.hzp__pin { position: sticky; top: max(var(--s3), calc(50vh - 330px));
  height: 660px; overflow: hidden;
  display: flex; flex-direction: column; justify-content: center; }
/* The heading is a flex item, centred WITH the track. It was absolutely
   positioned to the top of the pinned viewport, which on a tall screen left it
   300px above the panels, reading as though it belonged to the section before. */
.hzp__head { padding-inline: max(var(--gutter), calc(50vw - var(--max) / 2));
  margin-bottom: var(--s4); pointer-events: none; }
.hzp__head h2 { max-width: 18ch; font-size: clamp(26px, 2.8vw, 38px); }
.hzp__head .s1b__lede { font-size: var(--t-sm); max-width: 52ch; margin-top: var(--s2); }
/* ⚠️ THE ACCORDION'S MARKUP IS INERT ON DESKTOP. The label and the fold are
   `display: contents`, so their children lay out exactly as they did when they
   were direct children of `.hzp__copy` — the pinned slide is not restyled, it
   simply has two boxes in it that generate none. The radios and the chevron are
   `display: none`. Verified by measurement, not by eye: panel positions and
   heights are identical either side of the change. */
.hzp__r, .hzp__cv { display: none; }
.hzp__lab, .hzp__fold, .hzp__foldi { display: contents; }

.hzp__track { display: flex; width: 400vw; will-change: transform;
  animation: hzp-slide linear both;
  animation-timeline: --hzp; animation-range: contain 0% contain 100%; }

/* IT SLIDES, IT DOES NOT SCROLL.  Founder-directed, and the distinction is the
   whole behaviour: a linear scroll-to-X mapping lets the reader stop anywhere,
   including halfway between two panels, where the section shows two half-
   sentences and no complete thought. Every resting position has to be a panel.

   So the track HOLDS. Each panel owns a flat band of the range and the move
   between them happens in an 11% band with a strong ease-in-out — which spends
   its time at the ENDS of the band and crosses the centre fastest, so the slide
   leaves and arrives gently while the genuinely ambiguous frame, the one showing
   two half-panels, is the quickest part of the move. Holds are 67% across four
   panels (20/16/16/15) and the three slides take 11% each.

   The holds also absorb the one imprecision in this layout. `contain` is the
   span where the container covers the viewport; the STICKY period of a band
   shorter than the viewport is not exactly that span. The two differ by a little
   at each end — and because both ends are holds, the difference lands inside a
   flat keyframe and is invisible. It would not be if the track moved linearly. */
@keyframes hzp-slide {
  0%,  20% { transform: translate3d(0,0,0);       animation-timing-function: cubic-bezier(0.76,0,0.24,1); }
  31%, 47% { transform: translate3d(-100vw,0,0);  animation-timing-function: cubic-bezier(0.76,0,0.24,1); }
  58%, 74% { transform: translate3d(-200vw,0,0);  animation-timing-function: cubic-bezier(0.76,0,0.24,1); }
  85%,100% { transform: translate3d(-300vw,0,0); }
}

.hzp__p { flex: 0 0 100vw; width: 100vw; display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,0.92fr); gap: var(--s6);
  align-items: center;
  padding-inline: max(var(--gutter), calc(50vw - var(--max) / 2)); }
.hzp__n { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; color: var(--accent-ink); }
.hzp__h { font-family: var(--display); font-weight: var(--w-display);
  font-size: clamp(40px, 5.4vw, 80px); line-height: 0.95; letter-spacing: -0.045em;
  color: var(--ink); max-width: 11ch;
  /* The bottom margin is in em, not a spacing token, and it exists because
     `line-height: 0.95` makes the box SMALLER than the ink it holds: the
     descender of "review pack" hangs below the line box, so the description's
     24px of margin-top measured 24px and looked like about eight. An em value
     scales with the clamped headline, so the optical gap holds at 40px and at
     80px instead of being right at one size. */
  margin: var(--s3) 0 0.14em; }
/* THE COPY DOES NOT MOVE. ALL THE PARALLAX IS ON THE CARD.
   Two bugs died here, and the second is why the first fix was not enough.
     1. The lead animation was on `.hzp__h` ALONE, so during a hold the headline
        parked 46px right of the eyebrow and description belonging to it. Three
        lines of one paragraph, two left edges.
     2. Moving it to the whole column fixed that and left a subtler version:
        the lead steps one notch per hold, so each panel's copy came to rest at
        a DIFFERENT x — 120, 166, 212. Panel 3's copy sat 92px right of panel
        1's, and every panel but the first was indented from the pinned heading
        above it. Internally aligned, externally drifting.
   Parallax only needs the two planes to move RELATIVE to each other, and the
   card already travels +64 → 0 → −64 on its own. Giving the copy zero motion
   keeps that separation and makes the left margin a constant: every panel, at
   every hold, lands on the same gutter as the heading. Alignment by
   construction beats alignment by arithmetic. */
/* Card and headline hold on exactly the same bands as the track, so the card is
   STILL while a panel is settled and only separates during the slide. Parallax
   that ran continuously would have the card drifting under a stationary panel,
   which reads as a rendering fault rather than as depth. */
.hzp__p .s1b__b { font-size: var(--t-md); max-width: 42ch; margin-top: var(--s3); }
.hzp__p .s1b__mores { margin-top: var(--s3); }
.hzp__ui { box-shadow: var(--lift-4); will-change: transform;
  animation: hzp-lag linear both;
  animation-timeline: --hzp; animation-range: contain 0% contain 100%; }
/* the rotation lives INSIDE the keyframes: transform is a single property, so a
   separate `rotate()` rule would be overwritten the instant the animation took
   hold and the card would snap flat mid-slide. */
@keyframes hzp-lag {
  0%,  20% { transform: translate3d(64px,0,0)  rotate(-2.5deg); animation-timing-function: cubic-bezier(0.76,0,0.24,1); }
  31%, 47% { transform: translate3d(21px,0,0)  rotate(-0.8deg); animation-timing-function: cubic-bezier(0.76,0,0.24,1); }
  58%, 74% { transform: translate3d(-21px,0,0) rotate(0.8deg);  animation-timing-function: cubic-bezier(0.76,0,0.24,1); }
  85%,100% { transform: translate3d(-64px,0,0) rotate(2.5deg); }
}

/* Progress. A pinned section is a page that has stopped scrolling, and without
   a mark of how far through you are that reads as the page having frozen. */
.hzp__prog { position: absolute; left: 0; right: 0; bottom: var(--s3);
  display: flex; gap: var(--s2); justify-content: center; }
.hzp__tick { width: 64px; height: 2px; background: var(--line-2); overflow: hidden; }
.hzp__tick i { display: block; height: 100%; background: var(--accent);
  transform-origin: left; transform: scaleX(0);
  animation: hzp-fill linear both; animation-timeline: --hzp; }
/* a tick fills during the SLIDE that brings its panel in, not gradually across
   the hold — the indicator has to agree with what the eye just saw move. */
.hzp__tick:nth-child(1) i { animation: none; transform: scaleX(1); }
.hzp__tick:nth-child(2) i { animation-range: contain 20% contain 31%; }
.hzp__tick:nth-child(3) i { animation-range: contain 47% contain 58%; }
.hzp__tick:nth-child(4) i { animation-range: contain 74% contain 85%; }
@keyframes hzp-fill { to { transform: scaleX(1); } }

@supports not (animation-timeline: view()) {
  /* ⚠️ VISUALLY HIDDEN, NOT `display: none`. The desktop rule takes the radios
     out of the box tree entirely, which is right there and wrong here: a
     display:none input cannot be focused, so Tab would skip the only control
     this section has. Off-screen and zero-opacity keeps it in the tab order. */
  .hzp__r { display: block; position: absolute; opacity: 0; width: 1px; height: 1px;
    margin: 0; pointer-events: none; }
  .hzp { height: auto; }
  .hzp__pin { position: static; height: auto; overflow: visible; }
  .hzp__head { padding-inline: var(--gutter); }
  .hzp__track { width: auto; animation: none; overflow-x: auto; gap: var(--s3);
    scroll-snap-type: x mandatory; padding-inline: var(--gutter); scrollbar-width: none; }
  .hzp__track::-webkit-scrollbar { display: none; }
  .hzp__p { flex: 0 0 min(88vw, 900px); width: auto; scroll-snap-align: center;
    padding-inline: 0; grid-template-columns: 1fr; gap: var(--s4); }
  .hzp__ui, .hzp__tick i { animation: none; transform: none; }
  .hzp__prog { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  /* ⚠️ VISUALLY HIDDEN, NOT `display: none`. The desktop rule takes the radios
     out of the box tree entirely, which is right there and wrong here: a
     display:none input cannot be focused, so Tab would skip the only control
     this section has. Off-screen and zero-opacity keeps it in the tab order. */
  .hzp__r { display: block; position: absolute; opacity: 0; width: 1px; height: 1px;
    margin: 0; pointer-events: none; }
  .hzp { height: auto; }
  .hzp__pin { position: static; height: auto; overflow: visible; }
  .hzp__head { padding-inline: var(--gutter); }
  .hzp__track { width: auto; animation: none; overflow-x: auto; gap: var(--s3);
    scroll-snap-type: x mandatory; padding-inline: var(--gutter); }
  .hzp__p { flex: 0 0 min(88vw, 900px); width: auto; scroll-snap-align: center;
    padding-inline: 0; grid-template-columns: 1fr; gap: var(--s4); }
  .hzp__ui, .hzp__tick i { animation: none; transform: none; }
  .hzp__prog { display: none; }
}

@media (max-width: 900px) {
  /* ⚠️ AN ACCORDION, AND NOTHING MOVES ON SCROLL. Founder-chosen: design 03 off
     /s01m.html, after "i dont like the scroll based sliding or things like
     that". This supersedes the pinned horizontal slide that was here — the pin,
     the 400vw track, the slide keyframes, the progress ticks and the 2000px
     scroll container are all off below 900. Desktop keeps every one of them.

     The four names are always on screen and one body is always open, so nothing
     is behind a gesture and the section cannot be empty. It is a radio group
     with labels and no script: a checkbox version can open all four (the stack,
     with extra taps) and can close all four (a section showing nothing). */
  /* ⚠️ VISUALLY HIDDEN, NOT `display: none`. The desktop rule takes the radios
     out of the box tree entirely, which is right there and wrong here: a
     display:none input cannot be focused, so Tab would skip the only control
     this section has. Off-screen and zero-opacity keeps it in the tab order. */
  .hzp__r { display: block; position: absolute; opacity: 0; width: 1px; height: 1px;
    margin: 0; pointer-events: none; }
  .hzp { height: auto; }
  .hzp__pin { position: static; height: auto; overflow: visible; }
  .hzp__head { padding-inline: var(--gutter); margin-bottom: var(--s5); }
  /* the same reset for the same reason — this clamp was solved for a 660px
     pinned band that does not exist below 900. Three sections at 32 and one at
     27 was the page having two ideas about a section heading. */
  .hzp__head h2 { font-size: var(--t-xl); line-height: 1.02;
    letter-spacing: var(--track); max-width: 15ch; }
  /* ⚠️ THE LEDE IS BACK ON THE PHONE, and it was SHORTENED rather than
     duplicated. Founder-directed: "add short description to so what is the
     system? title".
     It read "These are the parts of it. Not separate apps you have to join up —
     every one of them reads from, and writes to, the same record" — 127
     characters, four lines on a phone, which is why it was hidden when this
     section became an accordion. The alternative was a second, shorter copy
     shown only here, and two copies of one claim in one file is how the two
     stop agreeing. One sentence now, 70 characters, two lines at 390 — and it
     still carries the part D-142.2 protects: not separate apps, one record. */
  .hzp__head .s1b__lede { font-size: var(--t-sm); max-width: 42ch; }

  .hzp__track { display: block; width: auto; animation: none; overflow: visible;
    padding-inline: var(--gutter); border-top: 1px solid var(--line); }
  .hzp__p { display: block; width: auto; flex: none; padding: 0;
    border-bottom: 1px solid var(--line); }

  /* ⚠️ THE ROW IS A GRID WITH A FIXED NUMBER COLUMN, not a flex row, and the
     open body is indented to match it. As a flex row the number's width was
     whatever "01" happened to measure, and the body underneath started at the
     NUMBER — so the title and its own sentence did not share a left edge, which
     is the thing the eye notices before it notices anything else here.
     One track width, used twice: the column and the fold's indent. Change it
     once and they cannot drift.

     Padding down from --s3 to --s2: `min-height` already sets the closed row at
     64, so the extra 16 was only ever adding height to a row that had it. */
  .hzp__lab { display: grid; grid-template-columns: var(--s01-n) minmax(0,1fr) auto;
    align-items: center; gap: var(--s2);
    min-height: 64px; padding-block: var(--s2); cursor: pointer; }
  .hzp { --s01-n: 26px; }
  .hzp__n { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em;
    color: var(--ink-4); flex: 0 0 auto; }
  /* ⚠️ THE TRIGGER HALF OF THE EYEBROW COMES OFF, BY HIDING AN ELEMENT — not by
     clipping a string. The full label reads "01 — SOMEONE RINGS", which is a
     caption above a heading and too long for a row that already carries a name
     and a chevron; the number on its own is a row number, not a caption.
     The first attempt capped the box at 2.2em with `overflow: hidden`, which
     works until the font metric moves a pixel and the row shows "01 —". Text is
     never cut to length; the part that is not wanted is given its own span and
     that span is what goes. */
  .hzp__nw { display: none; }
  .hzp__h { font-size: var(--t-lg); margin: 0; max-width: none; }
  /* the row's own tap state, in place of the OS flash base.css removes: the
     name and the chevron darken for the length of the press. A background tint
     would be the grey slab again in a nicer colour. */
  .hzp__lab:active .hzp__h { color: var(--brand); }
  .hzp__lab:active .hzp__cv { border-color: var(--brand); }
  .hzp__cv { display: block; margin-left: auto; width: 9px; height: 9px;
    border-right: 1.5px solid var(--ink-4); border-bottom: 1.5px solid var(--ink-4);
    transform: rotate(45deg) translateY(-2px);
    transition: transform var(--base) var(--ease); }

  /* ⚠️ `grid-template-rows: 0fr -> 1fr`, NOT `display: none` and NOT a
     `max-height` guess. Founder-directed: animate the open and the close.
     `display` cannot be transitioned at all, and a max-height cap has to be a
     number bigger than the tallest body — which makes the collapse start
     instantly and the open finish early, and breaks the moment a body grows
     past the guess. A `0fr` grid track animates to the content's OWN height, so
     the timing is right whatever the copy does and there is no number to keep
     in sync.
     ⚠️ THE PADDING IS ON THE INNER BOX. On the outer one it survives the
     collapse and every shut row keeps 48px of empty space under it. */
  .hzp__fold { display: grid; grid-template-rows: 0fr; overflow: hidden;
    padding-left: calc(var(--s01-n) + var(--s2));
    transition: grid-template-rows var(--base) var(--ease); }
  /* ⚠️ `display: block`, EXPLICITLY. The desktop rule above makes this
     `display: contents` so the pinned slide is untouched — and a box that
     generates no box cannot be a grid item, so `min-height: 0` had nothing to
     apply to and the `0fr` track never collapsed. The fold toggled visibility
     correctly and never changed height, which looks like the transition being
     ignored rather than the box being absent. */
  /* ⚠️ AND NO PADDING WHILE SHUT. `min-height: 0` zeroes the item's CONTENT
     box, which is what lets a `0fr` track collapse at all — but padding is not
     content, so 48px of it survived and every closed row kept a 48px gap under
     it. The space is added with the open state instead. */
  .hzp__foldi { display: block; min-height: 0; overflow: hidden; padding-bottom: 0;
    /* ⚠️ AND IT GOES `visibility: hidden` WHEN SHUT, on a delay. A 0fr track
       clips the body to nothing but leaves it FOCUSABLE — Tab would walk a
       keyboard user into a link they cannot see. The delay is what keeps the
       animation: visibility flips only after the collapse has finished. Same
       mechanism the header's Solutions panel uses. */
    visibility: hidden; transition: visibility 0s linear var(--base); }
  .hzp__fold .s1b__b { font-size: var(--t-sm); line-height: 1.55; color: var(--ink-3);
    margin-top: var(--s2); }
  /* the link sat 24 under the body and is 44 tall for a thumb — 68px for one
     line. 16 is enough separation once the body above it ends in a full stop. */
  .hzp__fold .s1b__mores { margin-top: var(--s2); }
  .hzp__p .s1b__more { min-height: 44px; }
  /* the artefact does not come to the phone. The row plus its sentence is the
     whole of this design; the fragments are on the product pages, which is
     where there is room to read them. */
  .hzp__p .fx { display: none; }
  .hzp__prog { display: none; }

  #s01-0:checked ~ .hzp__track .hzp__p:nth-of-type(1) .hzp__fold,
  #s01-1:checked ~ .hzp__track .hzp__p:nth-of-type(2) .hzp__fold,
  #s01-2:checked ~ .hzp__track .hzp__p:nth-of-type(3) .hzp__fold,
  #s01-3:checked ~ .hzp__track .hzp__p:nth-of-type(4) .hzp__fold { grid-template-rows: 1fr; }
  #s01-0:checked ~ .hzp__track .hzp__p:nth-of-type(1) .hzp__foldi,
  #s01-1:checked ~ .hzp__track .hzp__p:nth-of-type(2) .hzp__foldi,
  #s01-2:checked ~ .hzp__track .hzp__p:nth-of-type(3) .hzp__foldi,
  #s01-3:checked ~ .hzp__track .hzp__p:nth-of-type(4) .hzp__foldi {
    visibility: visible; transition-delay: 0s; padding-bottom: var(--s4); }
  #s01-0:checked ~ .hzp__track .hzp__p:nth-of-type(1) .hzp__cv,
  #s01-1:checked ~ .hzp__track .hzp__p:nth-of-type(2) .hzp__cv,
  #s01-2:checked ~ .hzp__track .hzp__p:nth-of-type(3) .hzp__cv,
  #s01-3:checked ~ .hzp__track .hzp__p:nth-of-type(4) .hzp__cv {
    transform: rotate(225deg) translateY(-2px); }
  /* the input is off-screen, so the visible focus ring has to be put on the row
     it drives or a keyboard user has nothing to follow */
  #s01-0:focus-visible ~ .hzp__track .hzp__p:nth-of-type(1) .hzp__lab,
  #s01-1:focus-visible ~ .hzp__track .hzp__p:nth-of-type(2) .hzp__lab,
  #s01-2:focus-visible ~ .hzp__track .hzp__p:nth-of-type(3) .hzp__lab,
  #s01-3:focus-visible ~ .hzp__track .hzp__p:nth-of-type(4) .hzp__lab {
    outline: 2px solid var(--brand-hot); outline-offset: 2px; }
  @media (prefers-reduced-motion: reduce) {
    .hzp__cv, .hzp__fold { transition: none; }
    .hzp__foldi { transition: visibility 0s; }
  }
}
