/* ==========================================================================
   INDEX ROW REVEAL — KEPT. treatments.php only.
   Built 2026-08-25 as a test against the photo bands, and CHOSEN 2026-08-26.
   Greg: "we're going back to the idea with the animated line and text. So the
   option with the text only is the better one, and we do it in this way."

   IT REVEALS RIGHT TO LEFT NOW, NOT LEFT TO RIGHT — changed 2026-08-26 on his
   description of what it should do: "each section will reveal itself from
   right to left in a delayed fashion. So the first row, second row, third one,
   fourth one, they're coming in and being snapped to the line from the right
   side."

   THAT DIRECTION IS THE POINT, not a preference. Opening left to right, a row
   started at the line and grew away from it. Opening right to left, the LAST
   thing to arrive is the row's left edge — which is the edge that sits against
   the curve. The row finishes by landing on the line, which is what "snapped to
   the line" means to anyone watching it.

   THE LINE IT LISTENS TO NOW DRAWS ON ARRIVAL, NOT ON SCROLL. main.js owns
   that (`.section-lines--once`); this file did not change to accommodate it,
   because the trigger was always "how far along is the line", never "where is
   the scroll". That is why swapping the driver underneath cost nothing.

   STILL TWO FILES, AND THAT IS NOW A CHOICE RATHER THAN A HOLDING PATTERN.
   They were separate so they could be deleted in one move; they are kept
   separate because they are the only page-scoped behaviour on the site and
   style.css is already 7,400 lines shipping to eight pages. Merging them buys
   nothing and risks the other seven. The one-shot LINE did go into main.js,
   because that is shared machinery with an opt-in class.

   EVERY HIDDEN STATE IS SCOPED TO .js-rows, which the script adds. Without
   the script the four families are simply there, which is the correct
   fallback: a contents list does not depend on an animation to be read.
   ========================================================================== */

/* ==========================================================================
   TWO GROUPS, TWO DIFFERENT ANIMATIONS — Greg, 2026-08-26

   "Everything with those animated lines should be treated separately from the
   prices and the descriptions. When I first load the page the blue line starts
   to animate, and then just TANTRA / THREE LEVELS, just MASSAGE / NO TANTRA NO
   AGENDA, only FOR THE BODY and only FOR THE SPIRIT will be animated together
   with the line. The other blocks -- the names of the treatments with the
   prices -- should be treated as a separate block, which will allow us a
   completely different animation, without the JavaScript, using just CSS
   reveal from right to left as a delay chain."

   GROUP A -- THE FAMILY LABELS. Tied to the line, because they are the thing
   the line is drawing past. Driven by js/index-reveal.js, which opens each one
   at the moment the drawn curve reaches that label's own height. That timing
   cannot be written as a CSS delay: it is measured off the path.

   GROUP B -- THE ROWS. Pure CSS, no JavaScript, a fixed delay chain. They are
   a list of names and prices and they have nothing to do with where the curve
   has got to.

   WHY SPLITTING THEM IS THE RIGHT CALL AND NOT JUST A DIFFERENT ONE. The two
   halves were one clipped block, so the prices could only ever move when the
   line reached them -- which tied the most ordinary content on the page to the
   most expensive machinery on it. Now the labels answer to the drawing and the
   list answers to nothing, and the list keeps working with the script deleted.
   ========================================================================== */

/* --- GROUP A: the labels, with the line ---------------------------------- */
.tr-index.js-rows .tri-fam-name {
  /* RIGHT TO LEFT: the inset is on the LEFT edge, so the visible area starts at
     the label's right end and closes leftwards, finishing against the curve.
     The row lands ON the line rather than growing away from it, which is what
     "snapped to the line from the right side" means to anyone watching it.

     AND IT IS A CLIP RATHER THAN A TRANSFORM, which is not a stylistic call.
     This label's left edge is measured against the curve to a hundredth of a
     pixel by buildWave in main.js, using getBoundingClientRect -- and a
     transform changes what that returns. A label sliding in from the right
     would be measured mid-flight on any pass that landed during the animation.
     A clip changes what is painted and nothing else. */
  clip-path: inset(0 0 0 100%);
}
.tr-index.js-rows .tri-fam.is-in .tri-fam-name {
  clip-path: inset(0 0 0 0);
  transition: clip-path 760ms cubic-bezier(.33, 0, .1, 1);
}

/* --- GROUP B: the rows, on their own ------------------------------------- */
@keyframes tri-rows-in {
  from { clip-path: inset(0 0 0 100%); }
  to   { clip-path: inset(0 0 0 0); }
}
.tr-index-list {
  /* `both` so the list holds the closed state through its delay rather than
     flashing open first. */
  animation: tri-rows-in 720ms cubic-bezier(.33, 0, .1, 1) both;
}
/* nth-of-type, NOT nth-child. The two line svgs are siblings of the families
   inside .tr-index, so nth-child would count them and every delay would be two
   places out. nth-of-type counts divs, and the four families are the only
   divs here.

   THE DELAYS TRACK THE LINE WITHOUT BEING TIED TO IT. Measured, the curve
   reaches the four labels at roughly 1.0s, 1.6s, 2.1s and 2.6s after the page
   opens. Each list follows its own label by about a fifth of a second, so the
   chain reads as label-then-prices, four times over -- while staying a plain
   CSS animation that knows nothing about the drawing. If ONCE_DUR in main.js
   changes, these want a look; nothing breaks if they are left, they just drift
   out of step. */
.tri-fam:nth-of-type(1) .tr-index-list { animation-delay: 1.2s; }
.tri-fam:nth-of-type(2) .tr-index-list { animation-delay: 1.75s; }
.tri-fam:nth-of-type(3) .tr-index-list { animation-delay: 2.25s; }
.tri-fam:nth-of-type(4) .tr-index-list { animation-delay: 2.75s; }

/* THE ROWS ARE CLIPPED, THE LINES ARE NOT. Both svgs are siblings of the
   families, not children, so the curve keeps drawing across a row that has not
   opened yet -- which is the whole effect: the line arrives first and the words
   come in to meet it. */

/* The reveal is a decoration on a list that is already legible, so someone who
   has asked not to be moved gets the list. Both groups, since they are now two
   mechanisms and each would otherwise have to be remembered separately. */
@media (prefers-reduced-motion: reduce) {
  .tr-index.js-rows .tri-fam-name,
  .tr-index.js-rows .tri-fam.is-in .tri-fam-name { clip-path: none; transition: none; }
  .tr-index-list { animation: none; clip-path: none; }
}

/* ==========================================================================
   GROUP B, IMAGE VARIANT — the photographic bands (.trx-panel)
   ==========================================================================
   Same job as .tr-index-list above and the same keyframe, on a different
   element. Greg, 2026-08-26, replacing the text rows with bands: "instead of
   using JavaScript to animate the treatments and the prices, we will use CSS."

   IT IS THE BAND THAT CLIPS, NOT THE LIST ON IT. Clipping the list would slide
   the words in over a photograph that was already sitting there, which reads as
   two elements arriving. Clipping the panel brings the picture and its type in
   as one object, from the right, landing on the line.

   A LITTLE SLOWER THAN THE TEXT ROWS — 820ms against 720. A band is a much
   larger object travelling the same distance, and at the text version's speed
   it read as a flick rather than as something arriving.

   THE DELAYS TRACK THE LINE WITHOUT BEING TIED TO IT, exactly as above:
   measured, the curve reaches the four labels at about 0.8, 1.5, 2.0 and 2.5
   seconds after the page opens, and each band follows its own label by roughly
   a fifth of a second. If ONCE_DUR in main.js changes, these want a look. */
/* ⚠ THESE RULES ARE INERT SINCE 2026-08-26 AND MUST NOT BE DELETED CASUALLY.
   Two image indexes ran side by side that day and Greg kept the one that
   slides, so nothing on the page uses this wipe any more -- `.trx--slide
   .trx-panel { animation: none; clip-path: none }` in style.css switches it
   off.

   THE TRAP: the closed state below is the DEFAULT, not a keyframe. Remove the
   `trx--slide` class from the <nav> thinking it is a redundant modifier and
   every band goes invisible, because this clip comes back with no animation
   left to open it. Delete both together or neither.

   Kept rather than cut because the wipe is a real alternative Greg may want
   back, and because references/web-effects/README.md points at it.

   ---

   IT WAITS FOR THE SECTION TO ARRIVE, AND THAT WAS A CORRECTION RATHER THAN
   A CHOICE. Written first as a bare animation on the element, it fired 1.0 to
   2.7 seconds after PAGE LOAD wherever the section happened to be -- which is
   fine while the index is the first thing on the page, and silently wrong the
   moment anything is put above it. A second copy went in above this one on
   2026-08-26 and the working section's reveal was spent before a reader could
   possibly have scrolled to it: four bands already open, nothing to see.

   NO NEW JAVASCRIPT. `.is-in` is the class the site's one IntersectionObserver
   in main.js already puts on every `.reveal` element, and this nav has carried
   `.reveal--rise` since it was built. The effect is still CSS; it is the
   TRIGGER that is shared with the rest of the page, which is what it should
   have been from the start.

   THE CLOSED STATE IS THE DEFAULT, not the first keyframe. `both` holds the
   from-state through the delay, but only once the animation exists -- before
   `.is-in` there is no animation, so without this the bands would sit open and
   then snap shut on arrival. */
/* LEFT TO RIGHT, NOT RIGHT TO LEFT -- Greg, 2026-08-26: "let's change the
   direction of the wipe. Make it from left to right instead of right to left."

   SO IT IS ITS OWN KEYFRAME NOW, not `tri-rows-in`. The bands used to share
   that one with the text rows above, and the text version is parked above the
   footer as a finished reference -- flipping a shared keyframe would have
   quietly turned it round too.

   WHAT THE FLIP DOES, and it is a different reading rather than a lesser one.
   Right to left, the LAST edge to appear was the band's left edge, so the band
   finished by landing against the curve. Left to right, that edge is the FIRST
   thing there and the band unrolls away from it -- which reads as the line
   producing the band rather than the band arriving at the line. The inset moves
   from the left side to the right side; nothing else changes. */
@keyframes trx-wipe-in {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
.trx-panel { clip-path: inset(0 100% 0 0); }
.tr-index.is-in .trx-panel {
  animation: trx-wipe-in 820ms cubic-bezier(.33, 0, .1, 1) both;
}
.trx .tri-fam:nth-of-type(1) .trx-panel { animation-delay: 1.0s; }
.trx .tri-fam:nth-of-type(2) .trx-panel { animation-delay: 1.7s; }
.trx .tri-fam:nth-of-type(3) .trx-panel { animation-delay: 2.2s; }
.trx .tri-fam:nth-of-type(4) .trx-panel { animation-delay: 2.7s; }

@media (prefers-reduced-motion: reduce) {
  .trx-panel,
  .tr-index.is-in .trx-panel { animation: none; clip-path: none; }
}
