/* =========================================================================
   Pete Gawtry Fitness — /workouts card system  v2   2026-08-27
   -------------------------------------------------------------------------
   ONE card. Every tier, same look, same way.

   Replaces the 187 per-tier rules in library.css that had each tier drifting
   into its own layout. Nothing in here is scoped to a tier id, on purpose —
   if a rule needs a #tier- prefix it does not belong in this file.

   The two skins are chosen by data-lib on <body>:
     data-lib="a"  STAGE  — cinematic. The movement is the card.
     data-lib="b"  INDEX  — editorial. A numbered catalogue that happens to move.
   Everything above the skin blocks is shared, so the two can never drift apart.
   ========================================================================= */

/* ---- THE ONE THAT MATTERS -----------------------------------------------
   site.css sets body{overflow-x:hidden}, which makes <body> a scroll container,
   and a position:sticky descendant of a scroll container never sticks. The rail
   tracked the page 1:1 and left the screen after ~2,000px of a 40,000px page,
   taking the tier nav and the only WCAG 2.2.2 stop control with it.

   Proved by substitution on the live page, not inferred:
     body overflow-x hidden -> railTop  2013 / -987 / -6987 / -12987 at
                               scrollY  0 / 3000 / 9000 / 15000
     body overflow-x clip   -> railTop  67 at scrollY 9000
     reverted to hidden     -> railTop  -6987 again
   `clip` still prevents horizontal scroll but does NOT create a scrollport.
   Scoped to this page's body so the other 118 pages are untouched. */
body[data-lib]{overflow-x:clip}

/* ---- the proof block, now four numbers -----------------------------------
   Pete: "I was on about The proof in three numbers.. it had 4 in before".
   The fourth is 63 categories - countable in the DOM of this very page, like
   the other three. Two-up on a phone, four across from 720px. Each label gets
   the same two-line sill so "Animated exercises" wrapping cannot stagger the row. */
#scale .stats--four{display:grid;grid-template-columns:repeat(2,1fr);gap:6px 10px}
#scale .stats--four .stat__l{min-height:2.6em;display:flex;align-items:flex-start;justify-content:center;text-align:center}
@media (min-width:720px){#scale .stats--four{grid-template-columns:repeat(4,1fr)}
  #scale .stats--four .stat__l{min-height:0}}

/* ---- 0. neutralise the old per-tier card layout -------------------------
   library.css and the page's inline block style each tier separately. Those
   rules are more specific than a bare class, so they are cancelled explicitly
   rather than fought selector-by-selector further down. */
/* tiers stack full width; the old sheet laid them out two-across as boxes */
#browse .lib-tiers{display:block;grid-template-columns:none}
#browse .lib-tier{margin:0 0 34px;background:none;border:0;box-shadow:none;border-radius:0}
#browse .lib-tier__bd{background:none;border:0;padding:0}
.lib-tier__bd{padding:0}
/* the accordion is gone: never let a stale data-collapsed hide a tier */
#browse .lib-tier[data-collapsed="1"] .lib-tier__bd{display:block}
#browse .lib-cats{display:grid;gap:var(--wk-gap);grid-template-columns:1fr;margin:0;padding:0;list-style:none;
  /* every card in a row is the same height, and the stages line up across it */
  grid-auto-rows:1fr}
#browse .lib-cats>li{margin:0;padding:0;list-style:none;min-width:0}
#browse .lib-cat__player{width:auto;aspect-ratio:auto;padding:0;overflow:visible}
#browse .lib-cat__player .pgfb{height:auto;margin:0;padding:0}

:root{
  --wk-gap:14px;
  --wk-card-r:20px;
  --wk-art:76px;          /* corner art box, mobile */
  --wk-pad:14px;
  --wk-stage-r:14px;
  --wk-head:130px;        /* eyebrow + 2-line title + 2-line blurb + padding.
                             Sized to the TALLEST head so every stage in a row starts
                             on the same line; measured, not guessed. */
}

/* ---- 1. the card ------------------------------------------------------- */
.wk-card{
  position:relative;
  display:flex;
  flex-direction:column;
  height:100%;
  background:linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.022));
  border:1px solid var(--line);
  border-radius:var(--wk-card-r);
  overflow:hidden;
  isolation:isolate;
  transition:border-color .22s var(--ease),transform .22s var(--ease),box-shadow .22s var(--ease);
}

/* the whole card is ONE link. The old markup had three anchors to the same
   href per card, which a screen reader reads three times.
   position:static is load-bearing: the stretched ::after below resolves against
   the nearest positioned ancestor. While this was position:relative the target
   covered only the top 92px of a 341px card, so tapping the animation - or the
   green OPEN - did nothing at all. */
.wk-card__hit{
  position:static;
  overflow:hidden;   /* contains the floated art */
  /* No sill in one column - there is no neighbour to line up with, so it would
     only add blank height. It comes in with the second column. */
  min-height:0;
  display:block;
  padding:var(--wk-pad);
  text-decoration:none;
  color:inherit;
}
.wk-card__hit::after{content:"";position:absolute;inset:0;z-index:4}  /* covers the whole card */

/* only the lines level with the art are inset. The art is 76px tall and ends
   before the blurb starts, so reserving a 100px column for the whole text block
   cost the blurb ~90px of measure on every wrapped line for nothing. */
.wk-card__head{display:block}
.wk-card__eyebrow:empty{display:none}
.wk-card__eyebrow{
  display:block;
  font:800 10.5px/1.1 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.13em;
  text-transform:uppercase;
  color:var(--accent-4);
  margin:0 0 5px;
}
.wk-card__title{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  margin:0 0 4px;
  font-weight:800;
  font:800 19px/1.12 'Barlow Condensed','Barlow Condensed Fallback','Inter',sans-serif;
  letter-spacing:.005em;
  text-transform:uppercase;
  color:var(--ink);
}
.wk-card__blurb{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  margin:0;
  font:500 12.5px/1.42 'Inter','Inter Fallback',sans-serif;
  color:var(--mute);
}

/* ---- 2. the corner art -------------------------------------------------
   Transparent PNG straight onto the card. No plate, no watermark, no ring.
   Pete's call after seeing all three tested at true size (2026-08-27).
   Sized by a box so a tall bodymap and a wide bench both land the same. */
.wk-card__art{
  float:right;
  margin:0 0 6px 12px;
  z-index:2;
  width:var(--wk-art);
  height:var(--wk-art);
  object-fit:contain;
  object-position:top right;
  shape-outside:inset(0);
  pointer-events:none;
  /* a touch of lift so mid-grey kit separates from a mid-dark card without
     reading as an outline. Measured: subject luminance 54-108 vs card bg 16. */
  opacity:.96;
  transition:transform .3s var(--ease),opacity .3s var(--ease);
}

/* ---- 3. the badge ------------------------------------------------------
   Was top-right, which is now the art slot. Moved inline above the eyebrow so
   it can never collide, and it reads in source order where it belongs. */
.wk-card__flag{
  display:inline-flex;align-items:center;gap:4px;
  margin:0 0 7px;
  padding:3px 8px 3px 6px;
  border-radius:var(--radius-pill);
  background:rgba(240,192,74,.13);
  border:1px solid rgba(240,192,74,.42);
  color:var(--gold-3);
  font:800 9.5px/1 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.1em;text-transform:uppercase;
}
.wk-card__flag svg{width:10px;height:10px;fill:currentColor}

/* ---- 4. the stage — the movement, and the reason the page exists --------
   This used to be a collapsed <details>. It is now the largest thing on the
   card. Keeping the light plate look Pete signed off; only the framing moved. */
.wk-card__stage{
  position:relative;
  margin:0 var(--wk-pad) var(--wk-pad);
  border-radius:var(--wk-stage-r);
  overflow:hidden;
  background:#0b0f16;
  z-index:1;
}
.wk-card__stage .pgfb,
.wk-card__stage .pgfb-lazy{margin:0;padding:0;height:auto}
/* the reserved shape before a board mounts — same box, so nothing shifts */
.wk-card__stage>.pgfb-lazy{
  display:block;aspect-ratio:var(--wk-stage-ar);
  border-radius:var(--wk-stage-r);
  background:linear-gradient(180deg,#171d28,#11161f);
  margin-bottom:34px;   /* the mounted plate's height, so nothing shifts */
}
body[data-lib="b"] .wk-card__stage>.pgfb-lazy{margin-bottom:26px}
.wk-card__stage>.pgfb-lazy>*{display:none}
.wk-card__stage .pgfb__head,
.wk-card__stage .pgfb__bar,
.wk-card__stage .pgfb__foot,
.wk-card__stage .pgfb__rowhead,
.wk-card__stage .pgfb__names{display:none}
.wk-card__stage .pgfb__rows{display:block;margin:0}
.wk-card__stage .pgfb__grid{grid-template-columns:1fr;gap:0}
.wk-card__stage .pgfb__cell{margin:0}
/* the board draws a 3px green rail down every row. Pete ruled it out on the card
   (2026-08-27): the plate reads cleaner without it. */
.wk-card__stage .pgfb__row::before,
.wk-card__stage .pgfb__row::after{display:none;content:none}
.wk-card__stage .pgfb__row{padding:0;border:0;background:none;border-radius:0}
/* THIS RULE OWNS THE STAGE SIZE ON THIS PAGE — more specific than the board's own
   .pgfb__screen rule, and it loads after it. Same settled geometry as the board: the screen
   is a BLOCK filling the card at a fixed --wk-stage-ar, so every card's clip box is identical
   to every other card's, and the plate falls below it. Read the ⛔ SETTLED DESIGN note in
   css/pgf-board.css before changing anything here — reverted 2026-08-31 and not to be
   restructured without asking Pete first. */
.wk-card__stage .pgfb__screen{
  border-radius:var(--wk-stage-r);
  aspect-ratio:var(--wk-stage-ar);
  height:auto;
}
/* The clip name. The board reserves two lines for it and sizes the inner span
   itself, which left a dead band under every plate and clipped long names
   mid-word. One line, ellipsis, no reserved gap. */
.wk-card__stage .pgfb__nm{height:auto;min-height:0;margin:0}
.wk-card__stage .pgfb__nm-i{
  display:block;font-size:inherit;line-height:1.32;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.wk-card__stage .pgfb__plate{padding:8px 10px 9px}
.wk-card__stage .pgfb__cell,
.wk-card__stage .pgfb__row,
.wk-card__stage .pgfb__grid{display:block;margin:0;padding:0}

/* ---- 5. the footer ----------------------------------------------------- */
.wk-card__meta{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  flex-wrap:nowrap;
  margin:0 var(--wk-pad) 0;
  /* Fixed. The movement count arrives per card once its board reports in, and
     letting that reflow the row moved whole tiers - measured CLS 3.69, with a
     single shift of 0.919 attributed to a tier section and its cards. A row
     that cannot change height cannot shift the page. */
  height:46px;padding:0;
  border-top:1px solid var(--line);
  font:700 12px/1 'Inter','Inter Fallback',sans-serif;
  color:var(--ink-2);
  font-variant-numeric:tabular-nums;
}
.wk-card__go{
  display:inline-flex;align-items:center;gap:5px;
  color:var(--accent);
  font:800 11.5px/1 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.06em;text-transform:uppercase;
  white-space:nowrap;
}
.wk-card__go svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .22s var(--ease)}

/* ---- 6. states --------------------------------------------------------- */
@media (hover:hover){
  .wk-card:hover{border-color:var(--accent-line);transform:translateY(-2px);
    box-shadow:0 22px 46px -26px rgba(0,0,0,.9)}
  .wk-card:hover .wk-card__art{transform:scale(1.06) translateY(-1px);opacity:1}
  .wk-card:hover .wk-card__go svg{transform:translateX(3px)}
}
.wk-card:focus-within{border-color:var(--accent-line)}
@supports selector(:has(*)){.wk-card__hit:focus-visible{outline:none}}
.wk-card:has(.wk-card__hit:focus-visible){
  outline:2px solid var(--accent-4);outline-offset:3px;border-color:var(--accent-line);
}

/* ---- 7. two columns and up --------------------------------------------- */
@media (min-width:640px){
  :root{--wk-gap:16px;--wk-art:84px;--wk-pad:16px}
  /* two columns and up: one sill so every stage in a row starts on the same line */
  .wk-card__hit{min-height:var(--wk-head)}
  #browse .lib-cats{grid-template-columns:repeat(2,1fr)}
  .wk-card__title{font-size:21px}
  .wk-card__blurb{font-size:13px}
}
@media (min-width:1040px){
  :root{--wk-gap:18px;--wk-art:92px}
  #browse .lib-cats{grid-template-columns:repeat(3,1fr)}
}

.wk-card__facts{display:flex;align-items:baseline;gap:7px;min-width:0;overflow:hidden}
.wk-card__facts>span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wk-card__moves{
  color:var(--accent-4);font-weight:800;
  padding-right:7px;border-right:1px solid var(--line-2);
}
.wk-card__moves[hidden]{display:none}

/* ---- long tiers show six, then the rest on request --------------------
   Every tier stays open. This only stops one tier (Specialisation is 18 deep)
   spending most of a phone-length page before the next one starts. */
#browse .wk-over[hidden]{display:none}
.wk-more{margin:12px 0 0}
.wk-more[hidden]{display:none}
.wk-more__b{
  display:inline-flex;align-items:center;gap:7px;
  min-height:44px;padding:0 16px;
  border:1px solid var(--line-2);border-radius:var(--radius-pill);
  background:var(--surface);color:var(--ink-2);
  font:800 11.5px/1 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.06em;text-transform:uppercase;cursor:pointer;
  transition:background .18s var(--ease),border-color .18s var(--ease),color .18s var(--ease);
}
.wk-more__b:hover,.wk-more__b:focus-visible{
  background:var(--accent-soft);border-color:var(--accent-line);color:var(--ink);
}
.wk-more__b svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .22s var(--ease)}
.wk-more__b[aria-expanded="true"] svg{transform:rotate(180deg)}

/* the stop control on the tier and category pages, which have no sticky bar */
.wk-hold-strip{display:flex;align-items:center;gap:11px;flex-wrap:wrap;margin:0 0 16px}
.wk-hold__hint{font:500 12px/1.4 'Inter','Inter Fallback',sans-serif;color:var(--mute-2)}

/* ---- SEARCH — the primary way into 63 categories ----------------------- */
.wk-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.wk-rail__top{display:flex;align-items:center;gap:8px;margin:0 0 8px}
.wk-find{position:relative;flex:1 1 auto;min-width:0;display:flex;align-items:center}
.wk-find__l{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.wk-find__i{
  position:absolute;left:12px;width:16px;height:16px;pointer-events:none;
  fill:none;stroke:var(--mute);stroke-width:2;stroke-linecap:round;
}
.wk-find__in{
  width:100%;min-height:44px;
  padding:0 46px 0 36px;
  border:1px solid var(--line-2);
  border-radius:var(--radius-pill);
  background:var(--surface-2);
  color:var(--ink);
  font:600 14px/1 'Inter','Inter Fallback',sans-serif;
  -webkit-appearance:none;appearance:none;
}
.wk-find__in::placeholder{color:var(--mute-2);font-weight:500}
.wk-find__in::-webkit-search-cancel-button{display:none}
.wk-find__in:focus{outline:2.5px solid var(--accent);outline-offset:2px;border-color:var(--accent-line);background:var(--surface-3)}
.wk-find__in:focus-visible{outline:2px solid var(--accent-4);outline-offset:2px}
.wk-find:focus-within .wk-find__i{stroke:var(--accent-4)}
/* 44x44 of tappable area around a 32px dot - the target is the rule, the
   circle is only what you see. */
.wk-find__x{
  position:absolute;right:0;
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;padding:0;
  border:0;background:none;cursor:pointer;
}
.wk-find__x::before{
  content:"";position:absolute;width:32px;height:32px;
  border-radius:50%;background:var(--surface-3);
}
.wk-find__x svg{position:relative}
.wk-find__x svg{width:13px;height:13px;fill:none;stroke:var(--ink-2);stroke-width:2.2;stroke-linecap:round}
.wk-find__x:hover svg,.wk-find__x:focus-visible svg{stroke:var(--ink)}
.wk-find__out{
  margin:8px 0 0;
  font:700 12px/1.35 'Inter','Inter Fallback',sans-serif;
  color:var(--accent-4);
}
.wk-find__out[hidden]{display:none}
/* Every class in this sheet that sets display AND is toggled by [hidden] needs
   this guard, or the attribute silently does nothing. */
.wk-find__x[hidden]{display:none}
/* the routes step aside while a search is running - you are not browsing then */
.wk-searching .wk-rail__scroll{display:none}
.wk-searching .lib-tier__all{display:none}

/* ---- HOLD — the single stop for 63 animating cards --------------------- */
.wk-hold{
  display:inline-flex;align-items:center;gap:8px;
  min-height:44px;padding:0 16px 0 13px;
  border:1px solid var(--line-2);border-radius:var(--radius-pill);
  background:var(--surface-2);color:var(--ink);
  font:800 12.5px/1 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.06em;text-transform:uppercase;cursor:pointer;
  transition:background .18s var(--ease),border-color .18s var(--ease);
}
.wk-hold:hover,.wk-hold:focus-visible{background:var(--accent-soft);border-color:var(--accent-line)}
.wk-hold__i{
  width:12px;height:12px;flex:none;border-radius:2px;
  background:linear-gradient(90deg,var(--accent) 0 3.5px,transparent 3.5px 8.5px,var(--accent) 8.5px 12px);
}
.wk-hold.is-held .wk-hold__i{
  background:var(--accent);
  clip-path:polygon(12% 4%,12% 96%,94% 50%);
  border-radius:1px;
}
.wk-hold__note{
  margin:2px 0 22px;max-width:52ch;
  font:500 12px/1.45 'Inter','Inter Fallback',sans-serif;color:var(--mute-2);
}
/* held: freeze every clip without unmounting anything */
.wk-held .wk-card__stage video,
.wk-held .wk-card__stage img{animation-play-state:paused!important}

/* =========================================================================
   TIER — the pill, and the sticky rail that makes 10 of them navigable
   ========================================================================= */
/* 44px chips + 9px padding = a 62px bar; the tier heads clear it. */
.wk-rail{
  position:sticky;
  top:calc(var(--nav-h) - 1px);
  z-index:30;
  margin:0 0 18px;
  padding:9px 0;
  background:linear-gradient(180deg,var(--bg) 62%,rgba(10,14,23,.86));
  backdrop-filter:blur(9px);
  -webkit-backdrop-filter:blur(9px);
  border-bottom:1px solid var(--line);
}
.wk-rail__in{display:block}
.wk-rail__in .wk-hold{flex:none;min-height:44px;min-width:44px;padding:0 11px;font-size:10.5px;gap:6px}
/* The label stays at every width. Sr-onlying it below 560px left the page's only
   motion stop as a bare glyph - and the label IS the accessible name. */
.wk-rail__scroll{flex:1 1 auto;min-width:0;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 18px,#000 calc(100% - 26px),transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 18px,#000 calc(100% - 26px),transparent 100%);
  display:flex;gap:7px;overflow-x:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;scroll-snap-type:x proximity;
  /* one shorthand, last. The longhand padding-right:26px used to sit above a
     `padding:1px 2px` shorthand that silently wiped it, so the mask had nothing
     to fade into and permanently half-erased the last chip. */
  padding:1px 26px 1px 18px;
}
.wk-rail__scroll::-webkit-scrollbar{display:none}
.wk-rail a{
  flex:none;scroll-snap-align:start;
  display:inline-flex;align-items:center;gap:6px;
  min-height:44px;padding:0 11px;
  border:1px solid var(--line-2);
  border-radius:var(--radius-pill);
  background:var(--surface);
  color:var(--ink-2);
  font:800 10.5px/1 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.03em;text-transform:uppercase;
  text-decoration:none;white-space:nowrap;
  transition:background .18s var(--ease),color .18s var(--ease),border-color .18s var(--ease);
}
.wk-rail a b{font-weight:800;color:var(--mute-2);font-variant-numeric:tabular-nums;margin-right:1px}
.wk-rail a:hover,.wk-rail a:focus-visible{background:var(--accent-soft);color:var(--ink);border-color:var(--accent-line)}
.wk-rail a[aria-current="true"]{background:var(--grad-green);border-color:transparent;color:var(--btn-ink)}
.wk-rail a[aria-current="true"] b{color:rgba(6,35,13,.62)}

/* On a short screen (landscape phone, or 400% zoom at the 1.4.10 reflow target)
   68px of nav + a 117px bar is over half the viewport. The bar gives up its
   sticky behaviour rather than the content giving up its room. */
@media (max-height:560px){
  .wk-rail{position:static}
  .wk-tier{scroll-margin-top:12px}
  .wk-card{scroll-margin-top:12px}
}

/* On a desktop the ten chips could never all show, at any width. They need
   1148px of run (1085px of chip + 63px of gaps) and #browse's column is capped
   at 1180px by workouts.html's own inline style, so the scroller only ever
   offered 1092px - a permanent 100px overflow that cut "10 Mobility" mid-word
   at EVERY viewport above 1268px. It was never a narrow-window problem, it was
   the column, so no amount of tightening the chips fixes it: they already fill
   1148 of the 1180 the column has.

   From 1280px the bar steps out of the column and takes the window - the same
   full-bleed-band / centred-inner shape the site nav directly above it already
   uses - and the chips centre in it. Nothing else moves. The search row stays
   pinned to the column, and the bar is still 117px tall, so .wk-tier's and
   .wk-card's scroll-margin-top below still clear it. If you ever change the
   bar's height here, change those two with it.

   overflow-x:auto and the edge mask are deliberately LEFT ON. Should the chips
   ever outgrow the window again - a font fallback with wider metrics, a renamed
   tier - this degrades back to the scroll rail it is on a phone, rather than
   clipping. `safe center` is what stops a centred flex row from putting its own
   first item out of reach when it does overflow.

   The longhands below land AFTER the padding shorthand on .wk-rail__scroll.
   That direction is safe; it is a shorthand landing after a longhand that
   silently wipes it, which is what half-erased the last chip once before. */
@media (min-width:1280px){
  .wk-rail{margin-inline:calc(50% - 50vw)}
  .wk-rail__top,
  .wk-find__out{max-width:1180px;margin-inline:auto;padding-inline:var(--pad)}
  .wk-rail__scroll{justify-content:safe center;padding-inline:26px}
}
.wk-tier{margin:0 0 34px;scroll-margin-top:calc(var(--nav-h) + 74px)}
.wk-card{scroll-margin-top:calc(var(--nav-h) + 84px)}
.wk-tier__hd{
  display:flex;align-items:baseline;gap:11px;
  margin:0 0 4px;padding:0;
}
.wk-tier__no{
  flex:none;
  font:900 13px/1 'Inter','Inter Fallback',sans-serif;
  color:var(--accent);
  font-variant-numeric:tabular-nums;
  letter-spacing:.04em;
}
.wk-tier__name{
  margin:0;
  font:800 clamp(30px,7.8vw,42px)/.98 'Barlow Condensed','Barlow Condensed Fallback','Inter',sans-serif;
  text-transform:uppercase;letter-spacing:.004em;color:var(--ink);
}
.wk-tier__cnt{
  margin-left:auto;flex:none;
  font:800 11px/1 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.07em;text-transform:uppercase;color:var(--mute-2);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
.lib-tier__blurb{
  margin:0 0 15px;max-width:62ch;
  font:500 13.5px/1.5 'Inter','Inter Fallback',sans-serif;color:var(--mute);
}
.lib-tier__all{margin:14px 0 0}
#browse .lib-tier__all{margin:14px 0 0;text-align:left}
#browse .lib-tier__all a{
  display:inline-flex;align-items:center;gap:6px;min-height:44px;
  font:800 12px/1.25 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.05em;text-transform:uppercase;color:var(--accent);
  text-decoration:none;border-bottom:1px solid rgba(75,221,100,.4);
}
.lib-tier__all a:hover{text-decoration:underline;text-underline-offset:4px}

/* =========================================================================
   SKIN A — "STAGE".  Cinematic. The movement is the card.
   ========================================================================= */
body[data-lib="a"]{
  /* The clips are portrait-to-square (measured: 338x812, 950x1000, 1170x1000,
     895x1000). A 4:3 landscape plate rendered a 950x1000 clip at 228x240 and
     left 29% of the plate empty - and the 338x812 outlier wasted 69%. A square
     plate is the shape the artwork actually is. This is variant A's trade: the
     movement gets the room, and the page is longer for it. */
  --wk-stage-ar:1/1;
  --wk-card-r:20px;
  --wk-stage-r:14px;
  --wk-head:130px;        /* eyebrow + 2-line title + 2-line blurb + padding.
                             Sized to the TALLEST head so every stage in a row starts
                             on the same line; measured, not guessed. */
}
body[data-lib="a"] .wk-card{
  background:linear-gradient(180deg,rgba(255,255,255,.062),rgba(255,255,255,.02));
  box-shadow:0 18px 40px -30px rgba(0,0,0,.9);
}
/* Fixed, so the lazy reserve below can match it exactly. A guessed reserve
   measured CLS 3.53 across a scroll to 20,000px; the shift was 18px per card,
   invisible on any one card and ruinous over 63. */
body[data-lib="a"] .wk-card__stage .pgfb__plate{
  font-size:13px;height:52px;display:flex;align-items:center;
}
/* one line clipped 3 of 12 names mid-word with no way to read the rest */
body[data-lib="a"] .wk-card__stage .pgfb__nm-i{
  white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
}
body[data-lib="a"] .wk-card__stage>.pgfb-lazy{margin-bottom:52px}  /* == plate height */
body[data-lib="a"] .wk-card__stage .pgfb__screen{
  box-shadow:0 8px 22px -12px rgba(0,0,0,.85);
}
body[data-lib="a"] .wk-tier__name{letter-spacing:.01em}
/* =========================================================================
   SKIN B — "INDEX".  Editorial. A numbered catalogue that happens to move.
   ========================================================================= */
/* B answers the same question differently. A gives the movement the whole column
   and accepts a long page. B puts two cards across even on a phone: the clip is
   smaller, but four fit a screen instead of one and a half, and 63 categories
   become scannable. That trade is the whole difference between the variants. */
body[data-lib="b"]{
  --wk-stage-ar:1/1;
  --wk-card-r:12px;
  --wk-stage-r:9px;
  --wk-pad:11px;
  --wk-art:44px;
  --wk-gap:9px;
}
body[data-lib="b"] #browse .lib-cats{grid-template-columns:repeat(2,minmax(0,1fr))}
body[data-lib="b"] .wk-card__hit{
  padding-right:calc(var(--wk-art) + var(--wk-pad) + 4px);
  min-height:0;
}
body[data-lib="b"] .wk-card__blurb{display:none}   /* no room for it two-up; the title carries */
body[data-lib="b"] .wk-card__title{font-size:13.5px;line-height:1.18}
body[data-lib="b"] .wk-card__eyebrow{font-size:9.5px;letter-spacing:.11em;margin-bottom:3px}
body[data-lib="b"] .wk-card__meta{font-size:12px}
body[data-lib="b"] .wk-card__moves{padding-right:6px}
body[data-lib="b"] .wk-card__flag{
  position:absolute;top:0;left:0;z-index:3;
  margin:0;border-radius:0 0 8px 0;padding:3px 7px 3px 5px;font-size:9px;
}
body[data-lib="b"] .wk-card--rec .wk-card__hit{padding-top:24px}
/* Two-up leaves ~171px of card. Everything below keeps a row of cards the same
   height and stops any string wrapping into a third line, because ragged card
   heights are what makes a dense grid look broken. */

/* the text block is a fixed sill so every stage in a row starts on the same line */
body[data-lib="b"]{--wk-head:86px}
body[data-lib="b"] .wk-card--rec .wk-card__hit{--wk-head:100px}
body[data-lib="b"] .wk-card__title{
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden;
}
/* At 171px a truncated string is worse than no string. Below 640px the card
   carries only what fits whole: index, title, clip, session count, arrow.
   The frequency and the movement count return at 640px where there is room. */
@media (max-width:639px){
  /* Kept visible, not hidden with font-size:0 - days-per-week is the single most
     useful filter on the page, and a zero-size label still reaches the
     accessible name, which gave sighted and screen-reader users different cards. */
  body[data-lib="b"] .wk-card__eyebrow{font-size:9.5px;letter-spacing:.1em;color:var(--accent-4)}
  body[data-lib="b"] .wk-card__moves{display:none}
  body[data-lib="b"] .wk-card__facts{font-size:12px}
  /* the clip name cannot fit whole at 171px, so it does not appear as a stub */
  body[data-lib="b"] .wk-card__stage .pgfb__plate{display:none}
  body[data-lib="b"] .wk-card__stage>.pgfb-lazy{margin-bottom:0}
}
/* the clip name under the plate: one line, never two */
body[data-lib="b"] .wk-card__stage .pgfb__nm{
  display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-size:10.5px;line-height:1.3;
}
body[data-lib="b"] .wk-card__stage .pgfb__plate{
  padding:6px 8px;font-size:10.5px;height:26px;display:flex;align-items:center;
}
/* the stage is pinned to the bottom of the card so the meta line always aligns */

body[data-lib="b"] .wk-card__meta{
  flex-direction:column;align-items:flex-start;gap:4px;
  height:54px;padding:6px var(--wk-pad) 8px;
}
body[data-lib="b"] .wk-card__facts{
  flex-wrap:nowrap;width:100%;min-width:0;
  font-size:12px;letter-spacing:.01em;
}
body[data-lib="b"] .wk-card__facts>span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
body[data-lib="b"] .wk-card__moves{border-right:0;padding-right:0}
@media (min-width:640px){
  body[data-lib="b"] .wk-card__moves{border-right:1px solid var(--line-2);padding-right:7px}
}
body[data-lib="b"] .wk-card__go{font-size:12px;letter-spacing:.06em}
@media (min-width:640px){
  body[data-lib="b"]{--wk-art:56px;--wk-pad:13px}
  body[data-lib="b"] .wk-card__blurb{display:block;font-size:12px}
  body[data-lib="b"] #browse .lib-cats{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (min-width:1040px){
  body[data-lib="b"] #browse .lib-cats{grid-template-columns:repeat(4,minmax(0,1fr))}
}
body[data-lib="b"] .wk-card{
  background:var(--bg-2);
  border-color:var(--line-2);
  box-shadow:none;
}
/* the index rule: a hairline accent rail down the left edge of every card */
body[data-lib="b"] .wk-card::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:2px;z-index:3;
  background:linear-gradient(180deg,var(--accent),rgba(75,221,100,0));
  opacity:.55;transition:opacity .22s var(--ease);
}
body[data-lib="b"] .wk-card:hover::before{opacity:1}
body[data-lib="b"] .wk-card__title{
  font-family:'Inter','Inter Fallback',sans-serif;
  font-size:16px;font-weight:800;line-height:1.2;
  text-transform:none;letter-spacing:-.005em;
}
body[data-lib="b"] .wk-card__eyebrow{color:var(--mute-2);letter-spacing:.15em}
body[data-lib="b"] .wk-card__stage{
  margin:auto 0 0;border-radius:0;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
}
body[data-lib="b"] .wk-card__stage .pgfb__screen{border-radius:0}
body[data-lib="b"] .wk-card__meta{
  margin:0;padding:11px var(--wk-pad) 12px;border-top:0;
  font-size:11.5px;letter-spacing:.03em;
}
body[data-lib="b"] .wk-card__art{opacity:.94}
body[data-lib="b"] .wk-tier__name{
  font-family:'Inter','Inter Fallback',sans-serif;
  /* was clamp(19px,4.4vw,24px), which put a 19px tier head against a 16px card
     title and undid the ladder A had. Live at 390px, ~28px against 13.5px. */
  font-size:clamp(28px,7.2vw,36px);font-weight:800;line-height:1.02;
  text-transform:none;letter-spacing:-.02em;
}
body[data-lib="b"] .wk-tier{
  border-top:1px solid var(--line);padding-top:20px;
}
body[data-lib="b"] .wk-rail a{border-radius:7px}
@media (min-width:640px){
  body[data-lib="b"] .wk-card__title{font-size:17px}
}

/* =========================================================================
   TIER PAGES — the same card, so the same floor applies to their furniture
   ========================================================================= */
/* The breadcrumb and the footer link back were 14-17px tall. min-height grows
   the hit box without moving the text, so nothing looks different and both
   clear 44px. */
body[data-lib] .lx-crumb a,
body[data-lib] .lx-sec--foot a,
body[data-lib] p > a[href="/workouts"]{
  display:inline-flex;align-items:center;min-height:44px;
}
body[data-lib] .lx-crumb ol{display:flex;flex-wrap:wrap;align-items:center;gap:0 6px}
/* the tier grid uses the same one-up / two-up / three-up rhythm as /workouts */
body[data-lib] ul.lx-grid{
  display:grid;gap:var(--wk-gap);grid-template-columns:1fr;grid-auto-rows:1fr;
  margin:0;padding:0;list-style:none;
}
body[data-lib] ul.lx-grid>li{margin:0;padding:0;list-style:none;min-width:0}
@media (min-width:640px){body[data-lib] ul.lx-grid{grid-template-columns:repeat(2,1fr)}}
@media (min-width:1040px){body[data-lib] ul.lx-grid{grid-template-columns:repeat(3,1fr)}}

/* =========================================================================
   WORKOUT GROUPS — the library card, applied to the recursive group panels
   -------------------------------------------------------------------------
   These were built separately: muscle map and animation as two equal 3:2
   plates, each watermarked, with the movement chooser floating over the clip
   and the group's numbers sat in the head. Same shape as everywhere else now:

       eyebrow  ·  TITLE  ·  blurb            [ map, small, top right ]
       ------------- the movement, square, the main event -------------
       clip name
       chooser
       facts ------------------------------------------ ACTION

   Restyled, not rebuilt. library-recursive.js owns the chooser and mounts the
   clip into .lx-rx__media, so every class it queries is left in place and only
   the boxes move. The one structural change is done in CSS: the panel stops
   being an absolutely-positioned stage and becomes a flex column, so the name
   and the chooser sit BELOW the clip on the card - the reference card's
   rhythm - without a single magic offset to drift.
   ========================================================================= */
body[data-lib] .lx-rx__card{
  position:relative;
  background:linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.022));
  border:1px solid var(--line);
  border-radius:var(--wk-card-r);
  overflow:hidden;
}
body[data-lib] .lx-rx__card[open]{border-color:var(--accent-line)}

/* ---- head: eyebrow, title, blurb — stacked, clear of the corner art ---- */
body[data-lib] .lx-rx__summary{
  display:block;
  padding:var(--wk-pad) calc(var(--wk-art) + var(--wk-pad) + 12px) 0 var(--wk-pad);
  /* the art is --wk-art tall and hangs from --wk-pad, so the head has to be at
     least that deep or the muscle map lands on the first row of fact pills */
  min-height:calc(var(--wk-art) + var(--wk-pad) + 6px);
  list-style:none;
}
body[data-lib] .lx-rx__summary::-webkit-details-marker{display:none}
body[data-lib] .lx-rx__summary::marker{content:""}
/* was a 36px boxed badge sat in its own grid column; the reference card's
   eyebrow is plain green type above the title, so the box goes */
body[data-lib] .lx-rx__step{
  display:block;width:auto;height:auto;margin-bottom:4px;
  place-items:initial;
  border:0;border-radius:0;background:none;
  font:900 11px/1 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.1em;color:var(--accent);
  font-variant-numeric:tabular-nums;
}
body[data-lib] .lx-rx__name b{
  display:block;
  font:800 19px/1.12 'Barlow Condensed','Barlow Condensed Fallback','Inter',sans-serif;
  letter-spacing:.005em;text-transform:uppercase;color:var(--ink);
}
body[data-lib] .lx-rx__name>span{
  display:block;margin-top:3px;
  font:500 12.5px/1.42 'Inter','Inter Fallback',sans-serif;color:var(--mute);
}
/* the head already toggles the card; a second "View group" chip in the corner
   only fought the muscle map for the same 76px */
body[data-lib] .lx-rx__open{display:none}

/* The evidence pills run from 1 row to 5 depending on the group, and while they
   sat between the blurb and the clip they pushed every card's movement to a
   different height - two cards side by side started their animation 34px apart.
   Ordered below the clip instead: the head is now three fixed lines on every
   card, so the movements line up across a row the way the tier cards do. */
body[data-lib] .lx-rx__body{
  padding:0 var(--wk-pad);
  display:flex;flex-direction:column;
}
body[data-lib] .lx-rx__panels{order:1}
body[data-lib] .lx-rx__facts{order:2}
body[data-lib] .lx-rx__workouts{order:3}

/* ---- the muscle evidence, as quiet pills under the movement ------------ */
body[data-lib] .lx-rx__facts{
  margin:11px 0 0;padding:0;list-style:none;
  display:flex;flex-wrap:wrap;gap:6px;
}
body[data-lib] .lx-rx__facts li{
  padding:4px 9px;border:1px solid var(--line-2);border-radius:var(--radius-pill);
  background:var(--surface);
  font:700 10.5px/1 'Inter','Inter Fallback',sans-serif;color:var(--ink-2);
}

/* ---- the muscle map: small, top right, straight on the card ------------ */
body[data-lib] .lx-rx__panels{display:block;gap:0}
body[data-lib] .lx-rx__panel--art{
  position:absolute;top:var(--wk-pad);right:var(--wk-pad);z-index:3;
  width:var(--wk-art);height:var(--wk-art);
  aspect-ratio:auto;border:0;background:none;box-shadow:none;overflow:visible;
  pointer-events:none;
}
body[data-lib] .lx-rx__panel--art::after{display:none;content:none}
body[data-lib] .lx-rx__panel--art .lx-rx__media{inset:0;overflow:visible}
body[data-lib] .lx-rx__panel--art .lx-rx__artwork{
  width:100%;height:100%;object-fit:contain;object-position:top right;
}
body[data-lib] .lx-rx__logo{display:none}

/* ---- the movement: THE LIBRARY CARD'S STAGE, not a copy of it ----------
   pgf-group-stage.js replaces the bespoke 3:2 panel with the board's own cell
   and gives the wrapper .wk-card__stage, so the whole stage section above
   styles it - same plate, same scanlines, same 52px name plate, same square.
   There is deliberately nothing here that describes how a clip looks: a second
   description is a second thing to drift.

   Only the box it sits in is ours, because it is inside .lx-rx__body which is
   already padded, and .wk-card__stage carries the card's own side margins. */
body[data-lib] .lx-rx__card .wk-card__stage{margin:12px 0 0}

/* If the player core never arrives the original panel stays, and it must still
   not be the old 3:2 watermarked plate sitting next to the new card. */
body[data-lib] .lx-rx__panel--animation{margin-top:12px;width:100%}
body[data-lib] .lx-rx__panel--animation .lx-rx__logo{display:none}

/* ---- the foot: the reference card's meta row, doing a real job ---------
   The session list was a plain "12 workouts" disclosure buried under the
   panels. It is the card's only genuine action, so it becomes the foot - same
   46px, same rule above it, same green uppercase call to the right. */
body[data-lib] .lx-rx__workouts{
  margin:12px 0 0;padding:0;
  border-top:1px solid var(--line);
}
body[data-lib] .lx-rx__workouts>summary{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  height:46px;padding:0;list-style:none;cursor:pointer;
  font:700 12px/1 'Inter','Inter Fallback',sans-serif;
  color:var(--ink-2);
  font-variant-numeric:tabular-nums;
}
body[data-lib] .lx-rx__workouts>summary::-webkit-details-marker{display:none}
body[data-lib] .lx-rx__workouts>summary::marker{content:""}
body[data-lib] .lx-rx__workouts>summary::after{
  content:"See sessions";
  color:var(--accent);
  font:800 11.5px/1 'Inter','Inter Fallback',sans-serif;
  letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;
}
body[data-lib] .lx-rx__workouts[open]>summary::after{content:"Hide sessions"}
body[data-lib] .lx-rx__workouts>summary:focus-visible{
  outline:2px solid var(--accent-line);outline-offset:2px;border-radius:6px;
}
body[data-lib] .lx-rx__workouts>ul{margin:2px 0 0;padding:0 0 var(--wk-pad)}

@media (hover:hover){
  body[data-lib] .lx-rx__workouts>summary:hover{color:var(--ink)}
  body[data-lib] .lx-rx__card:hover{border-color:var(--accent-line)}
}

/* ---- desktop: the same card, one size up ------------------------------ */
@media (min-width:640px){
  body[data-lib] .lx-rx__name b{font-size:21px}
}

/* =========================================================================
   REDUCED MOTION + PRINT
   ========================================================================= */
@media (prefers-reduced-motion:reduce){
  .wk-card,.wk-card__art,.wk-card__go svg,.wk-rail a{transition:none}
  .wk-card:hover{transform:none}
  .wk-card:hover .wk-card__art{transform:none}
}
@media print{
  .wk-rail{display:none}
  .wk-card{break-inside:avoid;border-color:#999}
  .wk-card__stage{display:none}
}

/* =========================================================================
   NARROW THREE-UP BAND — the only width where the card foot truncates
   -------------------------------------------------------------------------
   Measured on /workouts-splits, not guessed. The grid goes to three columns
   somewhere under 1120px and the card lands at 332px; there the foot clips
   both facts by exactly 3px each - "219 movem..." and "36 sessions · 4 we...".
   At 1160px the card is 345px and nothing truncates; at 1024px it is two
   columns at 463px. So it is a ~75px band, and it needs ~6px, not a redesign.

   Taken off the type and the gaps rather than the fixed 46px height: that
   height is what holds CLS at zero when each board reports its movement count
   in, so nothing here may make the row able to change height.
   ========================================================================= */
@media (min-width:1024px) and (max-width:1159px){
  .wk-card__meta{font-size:11.5px;gap:7px}
  .wk-card__facts{gap:6px}
  .wk-card__moves{padding-right:6px}
  .wk-card__go{font-size:11px;letter-spacing:.05em}
}
