/* Workflow carousel. One card in front at a time, three dots underneath.
   Pairs with workflow-carousel.js. See WORKFLOW-MODULE.md.

   Approved 2026-08-08: no visible deck behind the front card. The dots are the
   only thing that says there is more than one. */

/* The gap under the hero belongs here. It used to be supplied by each slide's
   kicker and headline, which were removed 2026-08-08 because the boundary pill
   already names the workflow. Two rules were meant to compensate and neither
   fires on this page: `.hero + .motion-field` matches nothing, because the
   hero's next sibling is `.carousel` and the motion-field is two levels down
   inside a slide; `.hero + .workflow-intro` matches nothing either, because
   there is no `.workflow-intro` in the carousel markup. That left an 8px gap
   and the hero buttons landed on the card.

   z-index is load-bearing too. `.hero` is z-index:10 and `.hero:before` is a
   radial glow inset to -35px below the hero box, then blurred by a further 8px,
   so it paints roughly 43px down over anything below it. The card has to sit
   above that. */
.carousel{
  position:relative;
  z-index:11;
  width:min(1120px, calc(100% - 48px));
  margin:2.25rem auto 0;
}

/* Slides stack in one place. Height is set by the script to the tallest, so the
   dots do not jump when a shorter workflow comes forward. */
.carousel-track{position:relative}

.wf-slide{
  position:absolute;
  top:0;left:0;right:0;
  opacity:0;
  visibility:hidden;
  /* visibility is deliberately NOT transitioned. Transitioning it means the
     outgoing slide stays hittable for the length of the transition, and it put
     a transition into the subtree that the controller then had to know to leave
     alone. Opacity does the visible work; visibility switches at once. */
  transition:opacity .45s ease;
}
.wf-slide.is-active{
  position:relative;
  opacity:1;
  visibility:visible;
}

/* The card is the outline the workflow draws for itself, so the slide adds no
   frame of its own. It only needs to not clip the boundary's shadow. */
.wf-slide .motion-field{overflow:visible}
.wf-slide .motion-field:after{display:none}

/* --- dots ---------------------------------------------------------------- */
/* Halved 2026-08-08, 9px to 5px. Taken down again 2026-08-09, 5px to 4px and
   the inactive fill from .18 to .12, on the note "a little bit smaller or
   fainter". The gap comes down with them so three dots still read as one
   cluster rather than as specks spread wide.

   The active dot keeps its terra fill rather than fading with the others. At
   4px a faint active dot stops being findable, and the dot row is the only
   thing telling you there are three workflows rather than one. */
/* Written by the script at every width and shown below 700px, which is where
   the slide is a scroll container at all. Whether a given slide has anything to
   scroll is a separate check in the script, so this is the breakpoint and not
   the whole answer. Hidden means hidden from screen readers too, which is what
   is wanted: above that width there is nothing to scroll. */
.carousel-hint{
  display:none;
  margin:1.4rem 0 0;
  text-align:center;
  color:var(--muted);
  font-size:.68rem;
  font-style:italic;
}

.carousel-dots{
  display:flex;
  justify-content:center;
  gap:10px;
  margin:1.75rem 0 0;
  padding:0;
}
.carousel-dots button{
  position:relative;
  width:4px;height:4px;
  padding:0;
  border:0;
  border-radius:50%;
  background:rgba(31,41,47,.12);
  cursor:pointer;
  transition:background .25s ease, transform .25s ease;
  -webkit-appearance:none;appearance:none;
}
/* A 4px dot is not a tap target. The hit area is grown by a pseudo element,
   which is why the button needs `position:relative` above.

   The height is a full 44px. The WIDTH is capped at the dot plus the gap, 14px
   since the dot came down to 4px on 2026-08-09,
   and deliberately not 44px: the pseudo elements are absolutely positioned with
   no z-index, so a 44px-wide one would extend 14.5px past each neighbour's
   centre and, painting later in DOM order, the third dot would swallow the taps
   meant for the first two. 15px each means they tile edge to edge with no
   overlap and no dead space between them. The whole row is live, so a thumb
   landing anywhere near a dot hits that dot and only that dot. */
.carousel-dots button:before{
  content:"";
  position:absolute;
  top:50%;left:50%;
  width:14px;height:44px;
  transform:translate(-50%,-50%);
}
.carousel-dots button:hover{background:rgba(31,41,47,.3)}
.carousel-dots button:focus-visible{
  outline:2px solid var(--teal);
  outline-offset:3px;
}

/* The active dot is just a filled dot. The progress ring that used to sit
   around it was removed 2026-08-08: it drew attention to the countdown instead
   of to the diagram. The script still tracks --progress, so the ring can come
   back by restoring a pseudo element here. */
.carousel-dots button[aria-current="true"]{
  background:var(--terra);
  transform:scale(1.15);
}

/* Nothing moves for a reader who has asked for less motion; the slide simply
   swaps and the dots still work. */
@media (prefers-reduced-motion:reduce){
  .wf-slide{transition:none}
  .carousel-dots button{transition:none}
}

@media (max-width:520px){
  .carousel{width:calc(100% - 28px)}
  /* No margin-top here. The 700px block further down sets it at the same
     specificity and matches at this width too, so it wins on order. */
  .carousel-dots{gap:9px}
  /* Hit area follows the gap down so the tiles still meet without overlapping. */
  .carousel-dots button:before{width:13px}
}

/* --- narrow: hold the diagram readable and let it scroll ------------------ */
/* The stage is a fixed 1120x500 canvas that a script fits to the viewport, so
   on a phone it simply gets smaller. Measured on staging 2026-08-23 at 390px:
   the fitted scale is 0.3125, the canvas paints 350x122, and all 30 pieces of
   text inside it land under 4px, 29 of them under 3px, median 2.2px. That is
   texture, not something a person can read.

   Scaling cannot fix it. The smallest label is 5.44px in the source, so getting
   it to a readable 11px needs a scale near 2.0, which paints the canvas at
   2263px, about six phone screens wide. So the diagram is held at a fixed size
   and the slide scrolls sideways under a thumb instead. Approved 2026-08-23 as
   the interim answer, with a phone-specific composition still the real fix.

   This mirrors .wf-still on /artifacts so the two pages behave the same way.
   The stage is anchored left rather than centred: centring it inside a scroll
   container puts 166px of the diagram, the entire first column, to the LEFT of
   the scroll origin at 390px, where scrollLeft cannot go below 0 and no swipe
   reaches it. /artifacts had exactly that fault and was starting the flow at
   column two on a phone; it is fixed in the same branch as this, so both pages
   now anchor left and there is no difference left between them.

   Only the slide scrolls. overscroll-behavior-x keeps the gesture from chaining
   out to the page, which never scrolls sideways. The carousel has no swipe
   handler of its own, so this does not compete with changing slides; the dots
   remain the only way to do that. */
@media (max-width:700px){
  .wf-slide{
    overflow-x:auto;
    -webkit-overflow-scrolling:touch;
    overscroll-behavior-x:contain;
  }
  /* Height tracks the held canvas exactly rather than the viewport clamp, which
     is sized for a diagram that shrinks to fit. The padding is for the boundary
     pill and the slabs, which paint outside the motion-field box. */
  /* .carousel on the front makes this (0,3,0), which beats the (0,2,0) of
     .workflow-section .motion-field outright. Before it the two tied and this
     rule won only because of where the sheets load, which is not a margin worth
     resting a clipped diagram on. Winning on specificity does not depend on
     load order, or on that rule continuing to match nothing on this page. */
  .carousel .wf-slide .motion-field{
    height:calc(var(--still-scale,.62) * 500px);
    padding-bottom:8px;
  }
  .wf-slide .stage{
    left:0;
    transform:scale(var(--still-scale,.62));
    transform-origin:top left;
  }
  /* Sideways scrolling has no affordance of its own, so the hint says so. It is
     a real element written by workflow-carousel.js rather than generated
     content, because generated content is not dependably read out and cannot be
     referenced by aria-describedby. */
  .carousel-hint{display:block;margin-top:1.1rem}
  .carousel-dots{margin-top:.55rem}
}
