/* The workflow: what a school hands over, and what comes back. One tab per kind of work, then
   four numbered steps joined by a hairline, each an emblem, a title and a short explanation
   (gradescope's "Use Your Existing Assignments", measured in .design-refs/reference/gradescope/
   DISSECTION.md 3.1). Markup: src/workflow.js. The tab strip is the subjects strip
   (.subject-tabs and .subject-tab in styles.css), so the two read as one control.

   Every text that changes with the tab is its own element tagged with the tabs it serves
   (data-for). The root names the tab on show (data-show) and the rule near the end hides the
   rest. A text two tabs share is one element, so it holds still when the tab changes: between
   the Margin tabs, steps 3 and 4 never move.

   Motion is gated on the scroll and plays once. When the row gets .in from the site's reveal
   observer, each emblem settles a beat after the one before and the hairline fills toward it
   from the left (from the top on a phone). A tab change cross-fades the texts that change, in
   220 ms. The resting state is the final state: with no script, or with motion reduced, the
   hairline is full, the emblems sit still and a tab change is instant. Nothing loops. */

.wf-section{background:var(--white)}

.wf{
  --wf-d:clamp(150px,12.4vw,176px); /* the emblem */
  --wf-g:clamp(16px,2vw,28px);      /* between the columns */
  --wf-n:34px;                      /* the numbered disc */
  --wf-beat:420ms;                  /* from one emblem settling to the next */
  margin-top:clamp(26px,3vw,40px);
}
/* room for the focus ring inside the strip's scroll box */
.wf .wf-tabs{padding:6px 6px 12px;margin:-6px -6px 0}
.wf-panel{margin-top:clamp(22px,2.8vw,36px);border-radius:var(--r-md)}
.wf-panel:focus-visible{outline-offset:10px}

/* ---------- the row ---------- */

.wf-steps{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:auto auto auto;column-gap:var(--wf-g)}
/* the three rows are shared, so every title sits on one line above the texts */
.wf-step{position:relative;display:grid;grid-row:span 3;grid-template-rows:subgrid;justify-items:center;text-align:center}
.wf-step:nth-child(2){--k:1}
.wf-step:nth-child(3){--k:2}
.wf-step:nth-child(4){--k:3}

/* the hairline: a segment from each emblem to the next, the rule as the track, the green on top */
.wf-step::before,.wf-step::after{content:'';position:absolute;z-index:0;top:calc(var(--wf-d) / 2 - 1px);left:calc(50% + var(--wf-d) / 2 - 2px);width:calc(100% + var(--wf-g) - var(--wf-d) + 4px);height:2px;border-radius:2px}
.wf-step::before{background:var(--rule)}
.wf-step::after{background:var(--emerald);transform-origin:left center}
.wf-step:last-child::before,.wf-step:last-child::after{content:none}

/* ---------- the emblem ---------- */

.wf-emblem{position:relative;z-index:1;width:var(--wf-d);height:var(--wf-d);border-radius:50%;background:var(--paper);color:var(--emerald-ink);display:grid;place-items:center}
.wf-n{position:absolute;left:calc(var(--wf-d) * .146 - var(--wf-n) / 2);top:calc(var(--wf-d) * .146 - var(--wf-n) / 2);width:var(--wf-n);height:var(--wf-n);border-radius:50%;background:var(--navy);color:var(--white);font-family:var(--font-display);font-weight:700;font-size:15px;line-height:1;display:grid;place-items:center;box-shadow:0 0 0 4px var(--white);font-variant-numeric:tabular-nums}
.wf-ico{grid-area:1/1;width:60%;height:60%}
.wf-ico svg{display:block;width:100%;height:100%;overflow:visible;stroke-width:2}
.wf-ico svg *{vector-effect:non-scaling-stroke}
.wf-ico .pg{fill:var(--white)}
.wf-ico .ac{fill:var(--emerald-wash)}
.wf-ico .dot{fill:currentColor;stroke:none}
.wf-ico .glint{fill:var(--white);stroke:none}

/* ---------- the words ---------- */

.wf-swap{display:grid;width:100%}
.wf-swap>*{grid-area:1/1}
.wf-title{align-items:end;margin-top:22px}
.wf-title h3{margin:0;font-size:20px;line-height:1.25;letter-spacing:-.01em;color:var(--navy)}
.wf-text{align-items:start;margin-top:8px}
.wf-text p{margin:0;font-size:14px;line-height:1.55;color:var(--slate);text-wrap:pretty}

.wf-more{margin-top:clamp(20px,2.6vw,32px)}
/* the site's thread link, standing alone: its hairline is the underline, so the browser's goes */
.wf-more .thread-link{margin-top:0;text-decoration:none}
.wf-more .thread-link:hover::after{width:100%}
.wf-more .thread-link:hover .arrow{transform:translateX(4px)}

/* ---------- the tab on show ---------- */

.wf[data-show='exams'] [data-for]:not([data-for~='exams']),
.wf[data-show='tests'] [data-for]:not([data-for~='tests']),
.wf[data-show='homework'] [data-for]:not([data-for~='homework']),
.wf[data-show='assignments'] [data-for]:not([data-for~='assignments']),
.wf[data-show='code'] [data-for]:not([data-for~='code']),
.wf[data-show='questions'] [data-for]:not([data-for~='questions']){opacity:0;visibility:hidden;--wf-off:.22s}

/* ---------- narrow: the row becomes a column ----------
   Emblem left, words right, and the hairline runs down from one emblem to the next. The emblem
   keeps the row's size on a tablet and comes down to 92px on a phone, where the words need the
   width beside it. */

@media (max-width:959px){
  .wf{--wf-d:clamp(92px,18vw,150px);--wf-n:clamp(26px,3.6vw,32px);--wf-gap:26px}
  .wf-steps{grid-template-columns:minmax(0,1fr);grid-template-rows:none;row-gap:var(--wf-gap)}
  .wf-step{grid-row:auto;grid-template-rows:auto 1fr;grid-template-columns:var(--wf-d) minmax(0,1fr);column-gap:18px;justify-items:stretch;text-align:left}
  .wf-emblem{grid-row:1 / span 2}
  .wf-title,.wf-text{grid-column:2;max-width:560px}
  .wf-title{align-items:start;margin-top:12px}
  .wf-title h3{font-size:18px}
  .wf-n{font-size:calc(var(--wf-n) * .48);box-shadow:0 0 0 3px var(--white)}
  .wf-step::before,.wf-step::after{top:calc(var(--wf-d) - 2px);left:calc(var(--wf-d) / 2 - 1px);width:2px;height:calc(100% - var(--wf-d) + var(--wf-gap) + 4px)}
  .wf-step::after{transform-origin:center top}
}
@media (max-width:599px){
  .wf-ico svg{stroke-width:1.75}
}

/* ---------- motion ---------- */

@media (prefers-reduced-motion:no-preference){
  /* the row arrives once, when the site's reveal observer gives it .in. The row itself does not
     rise: the emblems settle a beat apart, and the hairline fills toward each one as it lands.
     The waiting pose carries no transition, so taking it up when the script starts is instant
     and never plays backwards; only the arrival moves */
  .js .wf-steps.reveal{transform:none}
  .js .wf-emblem{transform:translateY(14px) scale(.92)}
  .js .wf-step::after{transform:scaleX(0)}
  .js .wf-steps.in .wf-emblem{transform:none;transition:transform .62s var(--ease-out) calc(var(--k,0) * var(--wf-beat))}
  .js .wf-steps.in .wf-step::after{transform:none;transition:transform .34s cubic-bezier(.45,0,.25,1) calc(var(--k,0) * var(--wf-beat) + 120ms)}

  /* a tab change: what changes cross-fades, what two tabs share holds still */
  .wf [data-for]{transition:opacity .22s var(--ease),visibility 0s linear var(--wf-off,0s)}
}
@media (prefers-reduced-motion:no-preference) and (max-width:959px){
  .js .wf-step::after{transform:scaleY(0)}
}
