/* home-feedback.css — homepage H08 Feedback (#feedback): the Workout
   Summary device (Alessandro, 8 Oct 2026: "1 · Device"), switched by
   "Steps and arrows" (Alessandro, 9 Oct 2026: "1 · Steps and arrows",
   chosen on the 9 Oct review page, since removed). Classes wsd-; behaviour
   in home-feedback.js.

   .wsd-grid      1024 px and wider: the heading left and the lead right,
                  above the device (12 Oct 2026: also from 1200 px, where
                  the copy had been a side column); narrower, one column
   .wsd-dev       the device, a size container (wsd-dev): the control row
                  (.wsd-ctl) and the stage (.wsd-dev__stage) with the frame
   .wsd-steps     "Today · In detail · Over time": aria tabs. 640 px of
                  device and wider: three numbered step buttons above the
                  frame, its width, joined by arrows (1 Today → 2 In detail
                  → 3 Over time); each looks pressable (an edge, a fill on
                  hover, a 1 px press), the chosen one Ink with its number
                  lit Vermilion. Phones: a segmented control (.wsd-seg: a
                  Chalk well with a Muted Plum edge, the chosen segment an
                  Ink pill), held under the header while the screen is read
   .wsd-pager     previous / next. Wide: two round buttons astride the
                  frame's edges at its middle (previous from the second
                  screen; next wraps from the last to the first). Phones:
                  next alone, the Vermilion action naming the next screen
                  ("In detail →"), at rest under the screen; a swipe works too
   .wsd-scr       the three Workout Summary screens rebuilt as live HTML
                  (website/workout-summary-cards/cards.html, example data as
                  designed), every size the app's own (design px) times one
                  unit, --u. 640 px and wider: the wide composition inside
                  an 8 px Ink frame (Today: date and headline left with
                  "Also today" under them, the moment right; One bout: the
                  chart left, the numbers and levels right; The long view:
                  the three abilities side by side), --u the largest that
                  fits the frame and the window under the header with the
                  steps (0.85–1.3; on desktop never under 1.1, 12 Oct
                  2026); narrower, the app's own column at phone
                  width. In-app navigation is left out and "Built at" names
                  are plain text, so nothing looks clickable that is not.
   Motion: the copy and the frame arrive (motion.js); switching slides the
   track inside .wsd-dev__window (the Ink rim stays whole; on phones the
   chosen screen comes in from its side) and the incoming screen's run,
   chart or trend lines draw (.is-play) the first time it is shown; a screen
   seen before comes back finished. Nothing changes by itself. Default
   style = the three screens one under the other, complete, no control (no
   JS; with JS the live layout from first paint); under reduced motion the
   switch works without slide or draw. */

.wsd-grid { display: grid; row-gap: var(--space-7); }
.wsd-copy { display: grid; row-gap: var(--space-5); align-content: start; }
.wsd-copy h2 { margin: 0; }
.wsd-text .t-lead { margin: 0 0 var(--space-4); }
/* desktop: the copy row above the device at every width (desktop check,
   12 Oct 2026; Alessandro approved after the mobile/desktop size checks).
   From 1200 px the copy had been a 4-column side column: the H2 in four
   lines of one or two words, the lead at 25–34 characters a line. Now the
   H2 takes two lines in 6 columns, the lead the other 6, 46–55 characters
   a line from 1280 px (5 columns gave 35–46), and the device the full row */
@media (min-width: 1024px) {
  .wsd-copy { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--grid-gutter); align-items: end; }
  .wsd-copy h2 { grid-column: 1 / span 6; }
  .wsd-text { grid-column: 7 / span 6; }
}

/* ---- the device ------------------------------------------------------------
   A size container. Phones (under 640 px of device): the control, then the
   screen in the app's own column (--u = the column / 360, at most 1.15: the
   column stops at 414 px and centres with its control, so between phone
   and tablet widths the screen never outgrows the section's own type or
   the window). 640 px and wider: the wide composition in an 8 px Ink
   frame, --u the largest that fits the width (680 design px across) and
   the window's height under the header with the steps above the frame,
   their gap and some air (104 px) for the tallest screen (--wsd-h, One
   bout), between 0.85 and 1.3 (on desktop 1.1 at least: the short-window
   block at the end). --u is set on the device's children, so the steps
   and the frame share it. */
.wsd-dev {
  container: wsd-dev / inline-size;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}
.wsd-dev > * { --u: min(100cqi / 360, 1.15px); }
.wsd-dev__stage { position: relative; }
.wsd-dev__frame {
  --wsd-slide: 560ms;
  position: relative;
  border-radius: calc(16 * var(--u));
}
/* the window clips the sliding track inside the rim (the frame itself does
   not clip), so the Ink rim stays whole mid-slide; vertical scrolling
   stays native over it, a horizontal swipe changes the screen. clip, not
   hidden: focus or script cannot scroll the window sideways (hidden is the
   fallback for browsers without clip; home-feedback.js resets it there) */
.wsd-dev__window { overflow: hidden; overflow: clip; border-radius: calc(16 * var(--u)); touch-action: pan-y; }
.wsd-dev__track { display: grid; gap: var(--space-5); }   /* without JS: one under the other */
/* with JS (html.js, set in the head before first paint): the live layout
   from the first frame, one screen and the control's row reserved, so
   nothing collapses when home-feedback.js starts */
.js .wsd-dev__track { display: flex; gap: 0; }
.js .wsd-scr { flex: 0 0 100%; min-width: 0; }

@container wsd-dev (max-width: 639.98px) {
  .js .wsd-scr:not(.is-active) { display: none; }
  .wsd-ctl, .wsd-dev__stage { width: 100%; max-width: 414px; margin-inline: auto; }
}
@container wsd-dev (min-width: 640px) {
  .wsd-dev > * {
    --rim: 8px;
    --wsd-h: 502;
    --u: clamp(0.85px, min((100cqi - 2 * var(--rim)) / 680, (100vh - var(--header-h) - 104px - 2 * var(--rim)) / var(--wsd-h)), 1.3px);
  }
  .wsd-dev__frame {
    width: calc(680 * var(--u) + 2 * var(--rim));
    max-width: 100%;
    margin-inline: auto;
    padding: var(--rim);
    background: var(--color-brand-ink);
    border-radius: calc(16 * var(--u) + var(--rim));
  }
  .wsd-dev__track { gap: var(--rim); }
  .js .wsd-scr:not(.is-active) { visibility: hidden; }
  .wsd-dev.is-live .wsd-dev__track { gap: 0; transform: translateX(calc(var(--k, 0) * -100%)); }
  .wsd-dev.is-live .wsd-scr:not(.is-active) { visibility: hidden; transition: visibility 0s linear var(--wsd-slide); }
  .wsd-dev.is-ready .wsd-dev__track { transition: transform var(--wsd-slide) cubic-bezier(0.65, 0, 0.2, 1); }
}

/* phones: the chosen screen comes in from the side it lives on; only on a
   switch (.is-entering, set by home-feedback.js) */
@keyframes wsd-in-next { from { opacity: 0; transform: translateX(32px); } }
@keyframes wsd-in-prev { from { opacity: 0; transform: translateX(-32px); } }
@media (prefers-reduced-motion: no-preference) {
  .wsd-scr.is-entering[data-enter="next"] { animation: wsd-in-next 420ms var(--ease-out); }
  .wsd-scr.is-entering[data-enter="prev"] { animation: wsd-in-prev 420ms var(--ease-out); }
}

/* ---- the control row (.wsd-ctl) --------------------------------------------
   Holds the tablist. Phones: held under the header while the screen is
   read, one --space-2 below the header's 1 px rule, on a Chalk strip so
   the screen never shows round it. Without JS it is not shown at all. */
.wsd-ctl { position: relative; display: flex; align-items: center; gap: var(--space-2); }
.wsd-ctl > [role="tablist"] { flex: 1 1 auto; min-width: 0; }
/* with JS: the control's row reserved from first paint (base.css hides
   [hidden] with !important; the script then removes the attribute) */
.js .wsd-ctl > [role="tablist"][hidden] { display: flex !important; visibility: hidden; }
html:not(.js) .wsd-ctl { display: none; }
@container wsd-dev (max-width: 639.98px) {
  .wsd-ctl { position: sticky; top: calc(var(--header-h) + 1px + var(--space-2)); z-index: 3; }
  .wsd-ctl::before { content: ""; position: absolute; inset: calc(-1 * var(--space-2) - 1px) calc(-1 * var(--page-margin)); z-index: -1; background: var(--on-bg); }
}
/* a phone on its side (under 500 px tall): the header already takes a
   sixth of the screen, so the control stays in place above the screen
   instead of holding another sixth; the next button and swipe remain */
@media (max-height: 500px) {
  @container wsd-dev (max-width: 639.98px) {
    .wsd-ctl { position: relative; top: auto; }
    .wsd-ctl::before { content: none; }
  }
}

/* the segmented control (phones): Chalk well, Muted Plum edge, the chosen
   segment an Ink pill with a Chalk label in Text 650 (a moving shape, not
   colour alone) */
.wsd-seg {
  position: relative;
  display: flex;
  padding: 4px;
  background: var(--on-bg);
  border: 1px solid var(--on-control);
  border-radius: var(--radius-control);
}
.wsd-seg__pill {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 0;
  width: var(--wsd-pw, 0px);
  border-radius: 5px;
  background: var(--color-brand-ink);
  transform: translateX(var(--wsd-px, 0px));
}
.wsd-seg.is-ready .wsd-seg__pill { transition: transform 420ms var(--ease-out), width 420ms var(--ease-out); }

/* the steps. Phones: segments of the held well, a number disc beside each
   label (from 316 px of device; the chosen disc lit Vermilion). Wide: three
   step buttons above the frame, the frame's width, joined by arrows; each
   looks pressable (an edge, a fill on hover, a 1 px press) and the chosen
   one is Ink */
.wsd-step {
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 6px;
  border: 0;
  border-radius: 5px;
  background: none;
  color: var(--on-text);
  font-size: var(--text-ui);
  font-weight: var(--weight-regular);
  line-height: 1.2;
  white-space: nowrap;
  text-align: left;
  cursor: pointer;
  transition: color 200ms var(--ease-out), background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
/* the label, then a 0-height reserver of its Text 650 width, so choosing
   never shifts the row */
.wsd-step__t { display: inline-flex; flex-direction: column; }
.wsd-step__t::after { content: attr(data-label); content: attr(data-label) / ""; height: 0; overflow: hidden; visibility: hidden; font-weight: var(--weight-strong); }
@media (hover: hover) { .wsd-step:hover .wsd-step__t { text-decoration: underline; text-underline-offset: 0.2em; } }   /* a tap leaves no underline behind */
.wsd-step[aria-selected="true"] { color: var(--color-text); font-weight: var(--weight-strong); }
.wsd-step[aria-selected="true"] .wsd-step__t { text-decoration: none; }
/* phones: the chosen label turns Chalk as the pill arrives under it, not
   before (on a long jump the pill needs ~400 ms); the outgoing label at once */
@media (prefers-reduced-motion: no-preference) {
  @container wsd-dev (max-width: 639.98px) {
    .wsd-step[aria-selected="true"] { transition-delay: 120ms; }
  }
}
.wsd-step:focus-visible { outline-offset: 1px; }
.wsd-step__n {
  flex: none;
  display: none;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: 0.8125rem;
  font-weight: var(--weight-strong);
  line-height: 1;
  transition: background-color 200ms var(--ease-out), border-color 200ms var(--ease-out), color 200ms var(--ease-out);
}
.wsd-step[aria-selected="true"] .wsd-step__n { background: var(--color-brand-energy); border-color: var(--color-brand-energy); color: var(--color-brand-ink); }
.wsd-step__to { display: none; }
@container wsd-dev (min-width: 316px) { .wsd-step__n { display: inline-grid; } }

@container wsd-dev (min-width: 640px) {
  .wsd-ctl { width: calc(680 * var(--u) + 2 * var(--rim)); max-width: 100%; margin-inline: auto; }
  .js .wsd-ctl > .wsd-steps[hidden] { display: grid !important; }
  .wsd-steps {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20px minmax(0, 1fr) 20px minmax(0, 1fr);
    column-gap: var(--space-2);
    padding: 0;
    border: 0;
    background: none;
  }
  .wsd-steps .wsd-seg__pill { display: none; }
  .wsd-step {
    justify-content: flex-start;
    gap: var(--space-3);
    min-height: 56px;
    padding: 0 var(--space-4);
    border: 1px solid var(--on-control);
    border-radius: var(--radius-control);
  }
  .wsd-step__n { display: inline-grid; width: 28px; height: 28px; font-size: var(--text-caption); }
  .wsd-step:hover .wsd-step__t { text-decoration: none; }
  @media (hover: hover) { .wsd-step:hover:not([aria-selected="true"]) { background: var(--color-surface-reading); border-color: var(--on-text); } }
  .wsd-step:active { transform: translateY(1px); }
  .wsd-step[aria-selected="true"] { background: var(--color-brand-ink); border-color: var(--color-brand-ink); }
  .wsd-step__to { display: block; align-self: center; width: 20px; height: 20px; fill: none; stroke: var(--on-muted); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
}
/* larger text (mobile check, 12 Oct 2026; Alessandro approved after the
   mobile/desktop size checks): under the page query of base.css (text set
   larger than a 320 px phone shows it) the labels keep the room and may
   take two lines ("In / detail", "Over / time"); the number discs step
   aside, as on the narrowest devices. Nothing changes at the default size */
@container page (width < 20rem) {
  .wsd-step { white-space: normal; }
  .wsd-step__n { display: none; }
}

/* previous / next. Phones: next alone, the Vermilion action naming the
   next screen ("In detail →"), at rest under the screen. Wide: two round
   buttons astride the frame's edges, at its middle (the name only for
   screen readers); they cover the screen's own side margin, never its
   content. Previous hides on the first screen (home-feedback.js); without
   JS the pager is not shown */
.wsd-pager { position: relative; z-index: 2; display: flex; justify-content: flex-end; gap: var(--space-2); }
.js .wsd-pager[hidden] { display: flex !important; visibility: hidden; }
.wsd-pager__btn {
  --on-focus: var(--color-focus-reading);
  --on-focus-gap: var(--color-bg-reading);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-width: 48px;
  height: 48px;
  padding: 0;
  border: 1px solid var(--color-border-control-reading);
  border-radius: 24px;
  background: var(--color-bg-reading);
  color: var(--color-text-reading);
  font-size: var(--text-ui);
  font-weight: var(--weight-strong);
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.wsd-pager__btn svg { flex: none; width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform var(--duration-fast) var(--ease-out); }
.wsd-pager__btn--prev svg { transform: scaleX(-1); }
.wsd-pager__btn--next { padding: 0 var(--space-4) 0 var(--space-5); background: var(--color-action-bg); border-color: var(--color-action-bg); color: var(--color-action-text); }
/* hover only with a pointer that hovers: after a tap the button would
   keep its hover fill and nudged arrow */
@media (hover: hover) {
  .wsd-pager__btn--prev:hover { background: var(--color-surface-reading); }
  .wsd-pager__btn--prev:hover svg { transform: scaleX(-1) translateX(2px); }
  .wsd-pager__btn--next:hover { background: var(--color-action-hover); border-color: var(--color-action-hover); }
  .wsd-pager__btn--next:hover svg { transform: translateX(2px); }
}
.wsd-pager__btn:active { transform: translateY(1px); }
@container wsd-dev (max-width: 639.98px) {
  .wsd-pager { margin-top: var(--space-4); }   /* at rest under the screen, never over it */
  .wsd-pager__btn--prev { display: none; }   /* back = the steps or a swipe */
}
@container wsd-dev (min-width: 640px) {
  .wsd-pager { position: absolute; inset: 0; display: block; pointer-events: none; }
  .js .wsd-pager[hidden] { display: block !important; }
  .wsd-pager__btn { position: absolute; top: 50%; width: 52px; height: 52px; border-radius: 26px; pointer-events: auto; box-shadow: 0 0 0 3px var(--on-bg); }
  .wsd-pager__btn--prev { left: 0; translate: -50% -50%; }
  .wsd-pager__btn--next { right: 0; padding: 0; translate: 50% -50%; }
  .wsd-pager__word {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}

/* ---- the screens (live), app sizes x --u -------------------------------- */
.wsd-scr {
  position: relative;
  padding: calc(26 * var(--u)) calc(20 * var(--u)) calc(30 * var(--u));
  border-radius: calc(16 * var(--u));
  box-shadow: inset 0 0 0 1px var(--on-line);   /* the screen's own 1 px edge */
  font-size: calc(16 * var(--u));
  line-height: 1.4;
}
.wsd-scr:focus-visible { outline-offset: calc(-1 * var(--focus-width) - 2px); box-shadow: none; }
:where(.wsd-scr) p { margin: 0; }
:where(.wsd-scr) :is(ul, ol) { list-style: none; }
.wsd-s-label {
  display: block;
  font-size: calc(13 * var(--u));
  font-weight: var(--weight-strong);
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.wsd-s-muted { color: var(--on-muted); }
.wsd-s-h1 {
  font-size: calc(34 * var(--u));
  font-weight: var(--weight-strong);
  font-variation-settings: var(--type-display-axes);
  line-height: 1.06;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
.wsd-s-h1 .ed { line-height: 1; }
.wsd-s-foot { margin-top: calc(18 * var(--u)); padding-top: calc(14 * var(--u)); border-top: 1px solid var(--on-line); font-size: calc(15 * var(--u)); }

/* -- today -- */
.wsd-s-head { display: flex; align-items: center; justify-content: space-between; gap: calc(12 * var(--u)); padding-bottom: calc(14 * var(--u)); border-bottom: 1px solid var(--on-line); }
.wsd-s-wm { width: calc(96 * var(--u)); height: auto; }
.wsd-s-wm--print { display: none; }   /* the Ink-letter artwork, for paper (print block below) */
.wsd-s-tag { font-size: calc(14 * var(--u)); color: var(--on-muted); }
.wsd-s-lead .wsd-s-label { margin-top: calc(26 * var(--u)); }
.wsd-s-lead .wsd-s-h1 { margin-top: calc(10 * var(--u)); }
.wsd-s-peak { margin-top: calc(24 * var(--u)); padding: calc(20 * var(--u)); border-radius: calc(12 * var(--u)); }
.wsd-s-peak__num { display: flex; align-items: flex-end; gap: calc(14 * var(--u)); margin-top: calc(10 * var(--u)); }
.wsd-s-peak__big {
  margin-left: calc(-4 * var(--u));
  font-size: calc(128 * var(--u));
  font-weight: var(--weight-strong);
  font-variation-settings: var(--type-display-axes);
  line-height: 0.8;
  letter-spacing: -0.03em;
}
.wsd-s-peak__cap { padding-bottom: calc(4 * var(--u)); font-size: calc(17 * var(--u)); line-height: 1.3; }
.wsd-s-run { display: flex; justify-content: space-between; margin-top: calc(22 * var(--u)); }
.wsd-s-run i { display: block; width: calc(9 * var(--u)); height: calc(34 * var(--u)); border-radius: calc(3 * var(--u)); background: var(--color-brand-energy); }
.wsd-s-peak__line { margin-top: calc(18 * var(--u)); font-size: calc(23 * var(--u)); line-height: 1.22; }
.wsd-s-also { margin-top: calc(30 * var(--u)); }
.wsd-s-card { margin-top: calc(12 * var(--u)); padding: calc(20 * var(--u)); border: 1px solid var(--on-line); border-radius: calc(12 * var(--u)); }
.wsd-s-also__num { display: flex; align-items: baseline; gap: calc(10 * var(--u)); margin-top: calc(12 * var(--u)); }
.wsd-s-also__big { font-size: calc(64 * var(--u)); font-weight: var(--weight-strong); font-variation-settings: var(--type-display-axes); line-height: 0.9; }
.wsd-s-also__unit { font-size: calc(17 * var(--u)); }
.wsd-s-was { display: inline-flex; align-items: center; gap: calc(4 * var(--u)); margin-left: auto; font-size: calc(15 * var(--u)); color: var(--on-muted); }
.wsd-s-was svg { width: calc(16 * var(--u)); height: calc(16 * var(--u)); transform: rotate(-90deg); fill: none; stroke: var(--color-brand-energy); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.wsd-s-also__cap { margin-top: calc(6 * var(--u)); font-size: calc(16 * var(--u)); }

/* -- one bout -- */
.wsd-s-btitle { padding-top: calc(4 * var(--u)); }
.wsd-s-btitle__name { display: flex; align-items: center; justify-content: space-between; gap: calc(12 * var(--u)); }
.wsd-s-chip {
  flex: none;
  padding: calc(6 * var(--u)) calc(10 * var(--u));
  border-radius: calc(8 * var(--u));
  background: var(--color-surface-reading);
  color: var(--color-text-reading);
  font-size: calc(14 * var(--u));
  font-weight: var(--weight-strong);
  line-height: 1.3;
}
.wsd-s-when { margin-top: calc(8 * var(--u)); font-size: calc(15 * var(--u)); }
.wsd-s-chart { margin-top: calc(22 * var(--u)); padding: calc(20 * var(--u)); border-radius: calc(12 * var(--u)); }
.wsd-s-chart__top { display: flex; align-items: baseline; justify-content: space-between; gap: calc(12 * var(--u)); }
.wsd-s-chart__top .wsd-s-muted { font-size: calc(14 * var(--u)); }
.wsd-s-chart__svg { width: 100%; height: auto; margin-top: calc(14 * var(--u)); overflow: visible; }
.wsd-s-chart__svg text { font-family: var(--font-primary); font-variation-settings: var(--type-text-axes); font-size: 13px; }
.wsd-c-grid line { stroke: var(--on-line); stroke-width: 1; }
.wsd-c-lev text { fill: var(--on-muted); }
.wsd-c-step line { stroke: var(--on-muted); stroke-width: 1.5; }
.wsd-c-bars rect { fill: var(--color-brand-energy); }
.wsd-c-miss rect { fill: var(--on-bg); }
.wsd-c-sw circle { fill: var(--on-muted); }
.wsd-c-brk path { fill: none; stroke: var(--on-text); stroke-width: 1.6; }
.wsd-c-brk text { fill: var(--on-text); font-weight: var(--weight-strong); }
.wsd-c-mark { fill: var(--on-text); stroke: var(--on-bg); stroke-width: 2.5; }
.wsd-s-chart__cap { margin-top: calc(10 * var(--u)); font-size: calc(14 * var(--u)); line-height: 1.4; }
.wsd-s-keys { margin-top: calc(16 * var(--u)); padding-top: calc(6 * var(--u)); border-top: 1px solid var(--on-line); }
.wsd-s-keys li { display: grid; grid-template-columns: calc(22 * var(--u)) minmax(0, 1fr); gap: calc(10 * var(--u)); align-items: start; padding-top: calc(12 * var(--u)); font-size: calc(15 * var(--u)); line-height: 1.4; }
.wsd-s-key { width: calc(22 * var(--u)); height: auto; margin-top: calc(3 * var(--u)); }
.wsd-s-key--brk path { fill: none; stroke: var(--on-text); stroke-width: 1.6; }
.wsd-s-key--dot circle { fill: var(--on-text); stroke: var(--on-bg); stroke-width: 2; }
.wsd-s-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: calc(16 * var(--u)) 0 0; overflow: hidden; border-radius: calc(12 * var(--u)); }
.wsd-s-stats > div { padding: calc(16 * var(--u)) calc(18 * var(--u)) calc(18 * var(--u)); }
.wsd-s-stats > div:nth-child(odd) { border-right: 1px solid var(--on-line); }
.wsd-s-stats > div:nth-child(-n+2) { border-bottom: 1px solid var(--on-line); }
.wsd-s-stats dt { color: var(--on-muted); font-size: calc(12 * var(--u)); font-weight: var(--weight-strong); line-height: 1.2; letter-spacing: 0.08em; text-transform: uppercase; }
.wsd-s-stats dd { margin: calc(8 * var(--u)) 0 0; font-size: calc(26 * var(--u)); font-weight: var(--weight-strong); line-height: 1.1; }
.wsd-s-stats small { font-size: calc(16 * var(--u)); font-weight: var(--weight-regular); }
.wsd-s-levels { margin-top: calc(28 * var(--u)); }
.wsd-s-levels ol { margin-top: calc(10 * var(--u)); }
.wsd-s-levels li { display: flex; align-items: flex-start; justify-content: space-between; gap: calc(12 * var(--u)); padding: calc(13 * var(--u)) 0; border-top: 1px solid var(--on-line); font-size: calc(16 * var(--u)); line-height: 1.35; }
.wsd-s-levels li:last-child { border-bottom: 1px solid var(--on-line); }
.wsd-s-levels__r { text-align: right; }
.wsd-s-sub { display: block; color: var(--on-muted); font-size: calc(14 * var(--u)); }
.wsd-s-mark { display: inline-block; width: calc(10 * var(--u)); height: calc(10 * var(--u)); margin-left: calc(6 * var(--u)); border-radius: 50%; background: var(--color-brand-energy); vertical-align: calc(1 * var(--u)); }

/* -- the long view -- */
.wsd-s-lhead .wsd-s-h1 { margin-top: calc(10 * var(--u)); }
.wsd-s-lede { margin-top: calc(10 * var(--u)); font-size: calc(17 * var(--u)); line-height: 1.5; }
.wsd-s-ability { margin-top: calc(26 * var(--u)); padding-top: calc(22 * var(--u)); border-top: 1px solid var(--on-line); }
.wsd-s-ability__name { font-size: calc(23 * var(--u)); font-weight: var(--weight-strong); line-height: 1.2; }
.wsd-s-ability__what { margin-top: calc(4 * var(--u)); font-size: calc(15 * var(--u)); line-height: 1.4; }
.wsd-s-ability__row { display: flex; align-items: flex-end; gap: calc(14 * var(--u)); margin-top: calc(14 * var(--u)); }
.wsd-s-score {
  flex: none;
  min-width: calc(92 * var(--u));
  font-size: calc(76 * var(--u));
  font-weight: var(--weight-strong);
  font-variation-settings: var(--type-display-axes);
  line-height: 0.82;
  letter-spacing: -0.02em;
}
.wsd-s-spark { flex: 1 1 0; min-width: 0; height: calc(62 * var(--u)); }   /* xMaxYMax: today at the right edge */
.wsd-sp-base { stroke: var(--on-line); stroke-width: 1; }
.wsd-sp-line { fill: none; stroke: var(--on-muted); stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.wsd-sp-last { stroke: var(--color-brand-energy); stroke-width: 2.6; stroke-linecap: round; }
.wsd-sp-dots circle { fill: var(--on-muted); }
.wsd-sp-now { fill: var(--color-brand-energy); }
.wsd-s-ability__trend { display: flex; flex-wrap: wrap; justify-content: space-between; gap: calc(4 * var(--u)) calc(10 * var(--u)); margin-top: calc(14 * var(--u)); font-size: calc(16 * var(--u)); }
.wsd-s-ability__trend .wsd-s-muted { font-size: calc(15 * var(--u)); }
.wsd-s-built { display: flex; flex-wrap: wrap; align-items: center; gap: calc(6 * var(--u)) calc(18 * var(--u)); margin-top: calc(14 * var(--u)); font-weight: var(--weight-strong); }
.wsd-s-built .wsd-s-label { font-size: calc(12 * var(--u)); }

/* -- the wide compositions (frame 640 px and wider; 680 design px across) -- */
@container wsd-dev (min-width: 640px) {
  .wsd-scr { padding: calc(20 * var(--u)) calc(26 * var(--u)) calc(22 * var(--u)); }
  .wsd-scr--today, .wsd-scr--bout {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: calc(28 * var(--u));
    align-content: start;
  }
  /* today: the bar across; date and headline left with "Also today" under
     them, the moment right */
  .wsd-scr--today { grid-template-areas: "head head" "lead peak" "also peak"; grid-template-rows: auto auto 1fr; }
  .wsd-s-head { grid-area: head; }
  .wsd-s-lead { grid-area: lead; }
  .wsd-s-lead .wsd-s-label { margin-top: calc(22 * var(--u)); }
  /* the moment fills its column; any height to spare is shared between its
     parts, so the card never shows one hole */
  .wsd-s-peak { grid-area: peak; display: flex; flex-direction: column; justify-content: space-between; margin-top: calc(24 * var(--u)); }
  .wsd-s-peak > * + * { margin-top: calc(14 * var(--u)); }
  .wsd-s-also { grid-area: also; align-self: end; margin-top: calc(24 * var(--u)); }
  /* one bout: the title across (the session line at its right), the chart
     left, the numbers and the levels right */
  .wsd-scr--bout { grid-template-areas: "title title" "chart stats" "chart levels"; grid-template-rows: auto auto 1fr; }
  .wsd-s-btitle { grid-area: title; display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: calc(8 * var(--u)) calc(20 * var(--u)); padding-top: 0; }
  .wsd-s-btitle__name { justify-content: flex-start; gap: calc(16 * var(--u)); }
  .wsd-s-when { margin-top: 0; }
  /* a little tighter than the phone, so the bout fits one window */
  .wsd-s-chart { grid-area: chart; margin-top: calc(18 * var(--u)); padding: calc(18 * var(--u)); }
  .wsd-s-chart__svg { margin-top: calc(12 * var(--u)); }
  .wsd-s-keys li { padding-top: calc(10 * var(--u)); }
  .wsd-s-stats { grid-area: stats; margin-top: calc(18 * var(--u)); }
  .wsd-s-stats > div { padding: calc(14 * var(--u)) calc(18 * var(--u)) calc(15 * var(--u)); }
  .wsd-s-levels { grid-area: levels; margin-top: calc(18 * var(--u)); }
  .wsd-s-levels ol { margin-top: calc(8 * var(--u)); }
  .wsd-s-levels li { padding-block: calc(9 * var(--u)); }
  /* the long view: the heading across, the three abilities side by side */
  .wsd-s-lhead { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: calc(28 * var(--u)); align-items: end; }
  .wsd-s-lhead .wsd-s-label { grid-column: 1 / -1; }
  .wsd-s-lede { max-width: 30em; padding-bottom: calc(3 * var(--u)); }
  .wsd-s-abilities { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: calc(24 * var(--u)); margin-top: calc(10 * var(--u)); }
  .wsd-s-ability { margin-top: 0; }
  .wsd-s-ability__what { min-height: calc(2 * 1.4em); }
  /* the score over its trend line, so the line keeps the app's own size */
  .wsd-s-ability__row { flex-direction: column; align-items: stretch; gap: calc(10 * var(--u)); }
  .wsd-s-spark { flex: none; width: 100%; }
  .wsd-s-ability__trend { flex-direction: column; }
  .wsd-s-built { row-gap: calc(4 * var(--u)); }
  .wsd-s-built .wsd-s-label { flex-basis: 100%; }
}

/* -- motion: the run reps up, the level bars draw left to right with their
   step-ups, then the misses, switches and the record bracket; the trend
   lines draw and today's point lands. Only once home-feedback.js has set
   .is-anim (motion allowed); the screen being shown gets .is-play. -- */
.wsd-c-bars rect, .wsd-c-step line, .wsd-c-mark, .wsd-sp-now { transform-box: fill-box; }
.wsd-c-bars rect { transform-origin: 0 50%; }
.wsd-c-step line { transform-origin: 50% 100%; }
.wsd-c-mark, .wsd-sp-now { transform-origin: 50% 50%; }
.wsd-s-run i { transform-origin: 50% 100%; }
@media (prefers-reduced-motion: no-preference) {
  .wsd-dev.is-anim .wsd-scr:not(.is-play) .wsd-s-run i { transform: scaleY(0); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-s-run i { transition: transform 460ms cubic-bezier(0.2, 0.7, 0.2, 1); transition-delay: calc(var(--wsd-d, 300ms) + var(--n, 0) * 55ms); }
  .wsd-dev.is-anim .wsd-scr:not(.is-play) .wsd-s-peak__big { opacity: 0; transform: translateY(calc(16 * var(--u))); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-s-peak__big { transition: opacity 420ms var(--ease-out), transform 520ms var(--ease-out); transition-delay: calc(var(--wsd-d, 300ms) - 120ms); }

  .wsd-dev.is-anim .wsd-scr:not(.is-play) .wsd-c-bars rect { transform: scaleX(0); }
  .wsd-dev.is-anim .wsd-scr:not(.is-play) .wsd-c-step line { transform: scaleY(0); }
  .wsd-dev.is-anim .wsd-scr:not(.is-play) .wsd-c-mark { transform: scale(0); }
  .wsd-dev.is-anim .wsd-scr:not(.is-play) :is(.wsd-c-miss, .wsd-c-sw, .wsd-c-brk) { opacity: 0; }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-c-bars rect { transition: transform 400ms var(--ease-out); transition-delay: calc(var(--wsd-d, 300ms) + var(--k, 0) * 380ms); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-c-step line { transition: transform 120ms linear; transition-delay: calc(var(--wsd-d, 300ms) + 380ms + var(--k, 0) * 380ms); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-c-mark { transition: transform 320ms cubic-bezier(0.3, 1.4, 0.5, 1); transition-delay: calc(var(--wsd-d, 300ms) + 800ms); }
  .wsd-dev.is-anim .wsd-scr.is-play :is(.wsd-c-miss, .wsd-c-sw) { transition: opacity 320ms var(--ease-out); transition-delay: calc(var(--wsd-d, 300ms) + 1100ms); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-c-brk { transition: opacity 320ms var(--ease-out); transition-delay: calc(var(--wsd-d, 300ms) + 1220ms); }

  .wsd-dev.is-anim .wsd-scr .wsd-sp-line { stroke-dasharray: 1; }
  .wsd-dev.is-anim .wsd-scr:not(.is-play) .wsd-sp-line { stroke-dashoffset: 1; }
  .wsd-dev.is-anim .wsd-scr:not(.is-play) :is(.wsd-sp-dots, .wsd-sp-last) { opacity: 0; }
  .wsd-dev.is-anim .wsd-scr:not(.is-play) .wsd-sp-now { transform: scale(0); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-sp-line { transition: stroke-dashoffset 900ms var(--ease-out); transition-delay: calc(var(--wsd-d, 300ms) + var(--a, 0) * 140ms); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-sp-dots { transition: opacity 600ms var(--ease-out); transition-delay: calc(var(--wsd-d, 300ms) + var(--a, 0) * 140ms); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-sp-last { transition: opacity 200ms var(--ease-out); transition-delay: calc(var(--wsd-d, 300ms) + 850ms + var(--a, 0) * 140ms); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-sp-now { transition: transform 320ms cubic-bezier(0.3, 1.4, 0.5, 1); transition-delay: calc(var(--wsd-d, 300ms) + 950ms + var(--a, 0) * 140ms); }

  /* the drawn state ends on an identity transform, not on none (13 Oct
     2026): ending on none re-laid out the size container at each bar's
     end, a run of 25–46 ms frames on a slow phone. Same draw */
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-s-run i { transform: scaleY(1); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-s-peak__big { transform: translateY(0); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-c-bars rect { transform: scaleX(1); }
  .wsd-dev.is-anim .wsd-scr.is-play .wsd-c-step line { transform: scaleY(1); }
  .wsd-dev.is-anim .wsd-scr.is-play :is(.wsd-c-mark, .wsd-sp-now) { transform: scale(1); }
}

/* ---- reduced motion: no slide or press; the composed state at once ----- */
@media (prefers-reduced-motion: reduce) {
  .wsd-dev__frame { --wsd-slide: 0ms; }
  .wsd-dev.is-ready .wsd-dev__track,
  .wsd-seg.is-ready .wsd-seg__pill,
  .wsd-step,
  .wsd-step__n,
  .wsd-pager__btn,
  .wsd-pager__btn svg { transition: none; }
  .wsd-step:active, .wsd-pager__btn:active { transform: none; }
}

/* ---- phones: word floors (mobile check, third pass, 12 Oct 2026) ---------
   Alessandro approved after the mobile/desktop size checks; replaces the
   9 Oct floors (12 to 14.5 px). Under a 640 px device the screen keeps --u
   for its numbers, big figures, spacing and proportions; only the words
   stop shrinking, at the site's own type roles: sentences and rows 16 px
   (Text UI), captions, secondary lines, the date and the tag 14 px
   (Caption), the bold uppercase labels 13 px, the chart's words 13 px as
   drawn. Each role keeps its design size times --u above its floor, so at
   430 px only the 12-unit labels move (12.9 to 13 px). px floors, like
   --u: under a larger text setting the screen stays one picture of the
   app (rem floors let its sentences outgrow its headings, and clipped the
   stats labels at 200 %). */
@container wsd-dev (max-width: 639.98px) {
  .wsd-scr {
    --wsd-f-body: 16px;    /* sentences, rows (Text UI) */
    --wsd-f-sec: 14px;     /* captions, secondary lines, date, tag (Caption) */
    --wsd-f-label: 13px;   /* bold uppercase app labels */
    font-size: max(var(--wsd-f-body), calc(16 * var(--u)));
  }
  .wsd-s-label { font-size: max(var(--wsd-f-label), calc(13 * var(--u))); }
  .wsd-s-stats dt, .wsd-s-built .wsd-s-label { font-size: max(var(--wsd-f-label), calc(12 * var(--u))); }
  .wsd-s-tag, .wsd-s-chip, .wsd-s-chart__top .wsd-s-muted, .wsd-s-sub, .wsd-s-chart__cap { font-size: max(var(--wsd-f-sec), calc(14 * var(--u))); }
  .wsd-s-foot, .wsd-s-was, .wsd-s-when, .wsd-s-ability__trend .wsd-s-muted { font-size: max(var(--wsd-f-sec), calc(15 * var(--u))); }
  .wsd-s-keys li, .wsd-s-ability__what { font-size: max(var(--wsd-f-body), calc(15 * var(--u))); }
  .wsd-s-also__cap, .wsd-s-levels li, .wsd-s-ability__trend { font-size: max(var(--wsd-f-body), calc(16 * var(--u))); }
  .wsd-s-peak__cap, .wsd-s-also__unit, .wsd-s-lede { font-size: max(var(--wsd-f-body), calc(17 * var(--u))); }
  /* the chart is drawn at --u (viewBox 280 wide in the 360 column), so its
     words are set in viewBox units: 15 at a 330 px device, one less for
     every 15 px wider, never under 13; as drawn, 13 px or more at any
     phone width */
  .wsd-s-chart__svg text { font-size: max(13px, calc(15px - (100cqi - 330px) / 15)); }
}
/* the long view on a narrow phone: at 16 px "Up from your last sessions."
   and "From 11 bouts" no longer share a line with air between them, so the
   count sits under the sentence for all three abilities (as in the wide
   composition), never on one and not the others */
@container wsd-dev (max-width: 349.98px) {
  .wsd-s-ability__trend { flex-direction: column; }
}
/* narrower still (a 320 px phone): "Built at" over its challenge names, as
   in the wide composition, so a name never wraps alone */
@container wsd-dev (max-width: 314.98px) {
  .wsd-s-built { row-gap: calc(4 * var(--u)); }
  .wsd-s-built .wsd-s-label { flex-basis: 100%; }
}
/* a phone on its side (under 500 px tall) with the wide composition: no
   size of the tallest screen fits the window under the header, so the
   window no longer holds --u at its 0.85 floor (words at 10–14 px); it
   follows the width alone, as on a tablet (13–19 px at 844 × 390) */
@media (max-height: 500px) {
  @container wsd-dev (min-width: 640px) {
    .wsd-dev > * { --u: clamp(0.85px, (100cqi - 2 * var(--rim)) / 680, 1.3px); }
  }
}
/* ---- desktop: short windows (desktop check, 12 Oct 2026) ----------------
   Alessandro approved after the mobile/desktop size checks. A maximised
   browser is 130–170 px shorter than its screen, so the window held --u at
   its 0.85 floor and the labels at 10 px (1280 × 585). From 1024 px --u
   stays at 1.1 or more (unless the width allows less), so sentences are
   17.6 px or more and captions 15.4; the labels and the chart's words stop
   at 14 px, each label keeping its design size times --u above that. In
   a window under about 710 px tall the device is then taller than the
   window and scrolls with the page, whole and in order */
@media (min-width: 1024px) and (min-height: 501px) {
  @container wsd-dev (min-width: 640px) {
    .wsd-dev > * { --u: clamp(min(1.1px, (100cqi - 2 * var(--rim)) / 680), min((100cqi - 2 * var(--rim)) / 680, (100vh - var(--header-h) - 104px - 2 * var(--rim)) / var(--wsd-h)), 1.3px); }
    .wsd-s-label { font-size: max(14px, calc(13 * var(--u))); }
    .wsd-s-stats dt, .wsd-s-built .wsd-s-label { font-size: max(14px, calc(12 * var(--u))); }
    .wsd-s-chart__svg text { font-size: 14px; }
  }
}

/* ---- print and Save as PDF (10 Oct 2026) --------------------------------
   shell.css prints every surface on the Chalk roles with no fill, so here
   the Today screen's wordmark swaps to the Ink-letter artwork (a second
   <img>, as in the header) and the chosen step, a Chalk label on an Ink
   fill on screen, prints as an Ink label in an Ink outline; the phones'
   Ink pill goes with the other fills */
@media print {
  .wsd-s-wm { display: none; }
  .wsd-s-wm.wsd-s-wm--print { display: block; }
  .wsd-seg__pill { display: none; }
  .wsd-step[aria-selected="true"] { background: none; border-color: var(--on-text); color: var(--on-text); }
}
