/* ============================================================================
 * FantasyStakes — UI/UX Rev 4.3 · readability foundation and shell
 * WP3B · POR §5, §10, §31
 *
 * A REUSABLE FOUNDATION, NOT PER-CARD PATCHES. WP3B §9 asks for the Rev 4.3
 * readability system as tokens and shared classes rather than one-off fixes.
 * The scale itself lives in `tokens.css` as `--fs-r43-*`; this sheet applies it
 * to the shell chrome — masthead, tab header, bottom navigation, sheets — and
 * publishes the `.fs-r43-*` helpers the WP3B surfaces and later packages use.
 *
 * WHAT IT DELIBERATELY DOES NOT DO. It does not restyle the Rev 4.2 wager
 * cards, Pool cards, Action tiles, Week rails or Ledger statement. Those are
 * WP3C's, their geometry is measured at 375x667 by suites that would fail
 * loudly and correctly if their type changed underneath them, and §9 says not
 * to. The one exception is where the shell's own change would otherwise break
 * them — see the panel-height note on the tab bar.
 *
 * LOADED LAST. Several rules below intentionally override `shell.css` and
 * `components.css`; load order is what makes that work without editing those
 * files, and keeps the Rev 4.2 baseline legible as a baseline.
 * ========================================================================== */

/* ── Shared helpers, for WP3B surfaces and WP3C after it ──────────────────── */

.fs-r43-page-title {
  font-size: var(--fs-r43-page-title);
  font-weight: var(--fs-weight-strong);
  line-height: 1.2;
  color: var(--bone);
  letter-spacing: 0;
}

.fs-r43-section {
  font-size: var(--fs-r43-section);
  font-weight: var(--fs-weight-strong);
  line-height: 1.25;
  color: var(--bone);
  /* §5.2 — reduce excessive tracking. The Rev 4.2 eyebrow ran at .14em, which
   * at 9px was most of what made section headings hard to read at a glance. */
  letter-spacing: .01em;
  /* §5.2 — reduce unnecessary uppercase. Headings that name a table keep their
   * caps because the caps ARE the POR's wording (OVERALL STANDINGS); nothing
   * here forces caps onto copy that did not ask for them. */
  text-transform: none;
}

.fs-r43-card      { font-size: var(--fs-r43-card); line-height: 1.35; }
.fs-r43-secondary {
  font-size: var(--fs-r43-card-secondary);
  line-height: 1.45;
  color: var(--fs-r43-secondary);
}
.fs-r43-meta {
  font-size: var(--fs-r43-meta);
  line-height: 1.4;
  color: var(--fs-r43-tertiary);
}

/* Anything tappable reaches the practical minimum — §5.1, §31. */
.fs-r43-touch {
  min-height: var(--fs-r43-touch);
  min-width: var(--fs-r43-touch);
}

/* ── Masthead ─────────────────────────────────────────────────────────────── */

/* THE MASTHEAD PAYS FOR THE TAB BAR, and this is where it does it.
 *
 * §31's 44px navigation target makes the bottom bar about 5px taller, and every
 * pixel it gains comes off the panel above it. At 375x667 — the shortest
 * certified viewport — the Rev 4.2 wager cards had roughly 8px of slack, so
 * that alone would have clipped them, and §9 says not to restyle those cards in
 * this package.
 *
 * So the height is recovered HERE, in the shell WP3B owns, rather than by
 * shrinking a WP3C card: tighter masthead padding (the column carries two fewer
 * lines since §2.1 removed the revision and byline), a tagline at the metadata
 * step rather than the secondary one, and closer leading on it. The tagline is
 * brand rather than game state, which is why it is the line that gives way and
 * the tab header, cards and figures do not.
 *
 * The measured result at 375x667 is in the certification, not in this comment. */
.fs-mast {
  padding: 8px var(--fs-space-6) 6px;
}

/* A sentence now, not a spaced-out lockup line. Rev 4.2 ran it at .22em
 * tracking in all caps; the locked Rev 4.3 string is mixed-case prose.
 *
 * It wraps to two lines at 375px, which is what makes the lockup the taller of
 * the masthead's two columns and therefore what sets the masthead's height.
 * That is why the leading here is tight: this line is the one paying for the
 * navigation's touch targets. */
.fs-mast__tagline {
  margin-top: 2px;
  font-size: var(--fs-r43-meta);
  letter-spacing: 0;
  line-height: 1.2;
  color: var(--fs-r43-secondary);
}

/* The lockup word carries the brand and keeps its size; its leading does not
 * need to be loose when the tagline sits right under it. */
.fs-mast__word { line-height: 1; }

.fs-mast__meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--fs-space-2);
  font-size: var(--fs-r43-meta);
  color: var(--fs-r43-tertiary);
}

/* ── The secondary gear (§3.1) ────────────────────────────────────────────── */

.fs-gear {
  display: flex;
  align-items: center;
  justify-content: center;
  /* A 44px target, achieved with negative margin so the ICON stays optically
   * aligned with the meta column while the TOUCH AREA is full size. Padding
   * alone would have pushed the masthead 26px taller. */
  width: var(--fs-r43-touch);
  height: var(--fs-r43-touch);
  margin: -11px -12px -11px 0;
  padding: 0;
  background: none;
  border: none;
  color: var(--g1);
  cursor: pointer;
}

.fs-gear:active,
.fs-gear:hover { color: var(--gold); }

.fs-gear:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: -8px;
  border-radius: var(--fs-radius-cell);
}

.fs-gear__icon {
  display: block;
  width: 20px;
  height: 20px;
}

/* ── Tab header ───────────────────────────────────────────────────────────── */

.fs-tabhead__title {
  font-size: var(--fs-r43-page-title);
  font-weight: var(--fs-weight-strong);
  line-height: 1.2;
}

.fs-tabhead__sub {
  margin-top: 3px;
  font-size: var(--fs-r43-card-secondary);
  color: var(--fs-r43-secondary);
}

/* ── Bottom navigation — §31 ──────────────────────────────────────────────── */

/* THE PANEL-HEIGHT TRADE, STATED. Raising the label from 8px to 11px and the
 * target to 44px makes this bar taller, and the panel above it correspondingly
 * shorter — which is the exact mechanism that clipped the Rev 4.2 wager cards
 * when Sprint 8 grew the masthead. WP3B pays for it in the same frame: §2.1
 * removed the masthead's revision and author lines, which were two lines of
 * 11px meta plus their leading. The tab bar's padding is trimmed here so the
 * bar grows by less than the masthead shrank, and the layout suites measure
 * the result rather than taking this paragraph's word for it. */
.fs-tabbar {
  padding: var(--fs-space-1) var(--fs-space-1);
  padding-bottom: calc(var(--fs-space-1) + var(--fs-safe-bottom));
}

.fs-tabbar__item {
  /* §31 — a practical 44px target, and it is the ITEM that carries it rather
   * than the label, so the whole column is tappable. */
  min-height: var(--fs-r43-touch);
  justify-content: center;
  gap: 2px;
  padding: var(--fs-space-1) 1px;
}

.fs-tabbar__label {
  /* §5.1 — 11–12px, and 11px is what lets all five labels sit on one line at
   * 320px without crowding. `Standings` is the longest at nine characters. */
  font-size: var(--fs-r43-nav-label);
  line-height: 1.15;
  letter-spacing: 0;
  /* Never wrap. A two-line label makes one tab taller than its neighbours and
   * is how `Rules &<br>Settings` used to look. */
  white-space: nowrap;
}

/* §5.2 — the inactive label was `--g2` at roughly 2.3:1, which is not readable
 * at a glance and is precisely what the POR calls out. */
.fs-tabbar__item { color: var(--fs-r43-tertiary); }
.fs-tabbar__item.is-active { color: var(--gold); }

.fs-tabbar__icon {
  width: 20px;
  height: 20px;
}

/* ── Sheets ───────────────────────────────────────────────────────────────── */

/* The close control stays UPPER-RIGHT — Rev 4.3 §25, and OR-1 before it. This
 * rule changes its SIZE to a 44px target and nothing about its corner. */
.fs-sheet__close {
  min-width: var(--fs-r43-touch);
  min-height: var(--fs-r43-touch);
  display: flex;
  align-items: center;
  justify-content: center;
}

.fs-sheet__title { font-size: var(--fs-r43-section); }
.fs-sheet__sub {
  font-size: var(--fs-r43-card-secondary);
  color: var(--fs-r43-secondary);
}

/* ── The secondary menu ───────────────────────────────────────────────────── */

.fs-menu {
  display: flex;
  flex-direction: column;
  gap: var(--fs-space-1);
  margin-top: var(--fs-space-3);
}

.fs-menu__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--fs-space-4);
  width: 100%;
  min-height: var(--fs-r43-touch);
  padding: var(--fs-space-3) var(--fs-space-4);
  background: var(--card);
  border: var(--fs-border);
  border-radius: var(--fs-radius-cell);
  font-family: inherit;
  color: var(--bone);
  text-align: left;
  cursor: pointer;
}

.fs-menu__row.is-pending {
  cursor: default;
  background: none;
  border-style: dashed;
}

.fs-menu__row:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: 2px;
}

.fs-menu__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.fs-menu__label {
  font-size: var(--fs-r43-card);
  font-weight: var(--fs-weight-medium);
}

.fs-menu__help {
  font-size: var(--fs-r43-meta);
  line-height: 1.4;
  color: var(--fs-r43-secondary);
}

.fs-menu__chev {
  flex: 0 0 auto;
  font-size: var(--fs-r43-section);
  color: var(--g1);
}

.fs-menu__soon {
  flex: 0 0 auto;
  font-size: var(--fs-r43-meta);
  color: var(--fs-r43-tertiary);
}

/* ── WP3D · source identity and Yahoo attribution ──────────────────────────
 *
 * TWO TREATMENTS, BOTH DELIBERATELY QUIET.
 *
 * The source chip states where the league's data comes from. It lives in the
 * masthead meta column beside the gear and the COMMISSIONER badge, because it
 * is the same kind of fact — true, persistent, and secondary to the product.
 * It must never compete with FantasyStakes, the league name, the week or the
 * gameplay (Rev 4.3 §22, WP3D §16).
 *
 * THE LABEL CARRIES THE MEANING, NOT THE COLOUR. Every state is readable text;
 * the accent only distinguishes. A GM who cannot perceive the accent still
 * reads DEMO, and a screen reader reads it too. Colour is never the signal.
 */

/* ONE ROW FOR THE CHIP AND THE GEAR. Measured: giving the chip a row of its
 * own added 16px to the masthead and clipped both wager cards at 375x667.
 * The chip is shorter than the gear, so sharing its line is free. */
.fs-mast__metarow {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--fs-space-2);
  /* The row may not grow the column past what the lockup can spare. */
  max-width: 100%;
  min-width: 0;
}

.fs-source {
  display: flex;
  align-items: center;
  min-width: 0;
}

.fs-source__label {
  font-size: var(--fs-size-eyebrow);
  /* TIGHTER THAN THE EYEBROW TRACK. The standard tracking is set for headings
   * with room; here every em of letter-spacing is width taken off the wordmark
   * beside it, and the label is short enough to stay legible without it. */
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--g2);
  border: var(--fs-border-edge);
  border-radius: var(--fs-radius-cell);
  padding: 1px 5px;
  white-space: nowrap;
  /* Bounded so no state string can widen the meta column and squeeze the
   * lockup — the failure mode recorded in shell.js renderMasthead(). The
   * longest label is YAHOO · NOT SYNCED YET; this fits it whole at 320px. */
  max-width: 148px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* DEMO IS THE ONE STATE THAT MUST BE UNMISTAKABLE (Rev 4.3 §21), so it takes
 * the gold treatment the COMMISSIONER badge already uses for "this session is
 * not ordinary". It is a product accent, not a debug badge: no alarm red, no
 * hazard hatching, no monospace, no brackets. */
.fs-source[data-source-state="demo"] .fs-source__label {
  color: var(--gold);
  background: var(--goldbg);
  border-color: var(--gold);
}

/* ── The Yahoo attribution ─────────────────────────────────────────────────
 *
 * A page-footer source disclosure. Last thing on the panel, smallest type,
 * tertiary colour — the same subordination `.fs-legal` uses, and for the same
 * reason. It is required, it is readable, and it is not the headline.
 *
 * IT SITS ABOVE THE BOTTOM NAVIGATION, never over it: the panel scrolls inside
 * its own region and this is ordinary flow content at the end of it, not a
 * fixed overlay. Rev 4.3 §23 forbids anything that impairs the persistent nav.
 */

.fs-attribution {
  margin-top: var(--fs-space-3);
  padding-top: var(--fs-space-2);
  border-top: var(--fs-border-hair);
  text-align: center;
  /* NEVER SHRINKS AND NEVER GROWS. On the flexed panels it is terminal content,
   * not a participant in the height negotiation above it. */
  flex: 0 0 auto;
}

/* PLAY PAYS FOR IT OUT OF ITS OWN BOTTOM PADDING. `.fs-zones` ended the panel
 * with `space-4` of breathing room; the source line now ends the Pools zone and
 * its own margin provides that separation, so the padding is redundant. This
 * matters at 375x667, where the Versus carousel has almost no slack — measured
 * 128px of rail for a 128px card at HEAD — and every pixel spent below the
 * zones comes out of a wager card. With the line inside Pools and this padding
 * released, the card measures 133px in 133px. */
#panel-league .fs-zones { padding-bottom: 0; }

.fs-attribution__link {
  font-size: var(--fs-size-micro);
  line-height: 1.4;
  color: var(--g2);
  /* UNDERLINED, so it is recognisable as a link without relying on colour —
   * and it keeps normal anchor semantics, so it is keyboard-focusable and
   * announced as a link with no ARIA needed. */
  text-decoration: underline;
  text-underline-offset: 2px;
}

.fs-attribution__link:hover,
.fs-attribution__link:focus-visible {
  color: var(--g1);
}


/* ==========================================================================
 * WP3E - final responsive, accessibility and PWA hardening
 * ==========================================================================
 *
 * Nothing here redesigns anything. Every rule closes a defect that was
 * MEASURED across the certification matrix - 320x568 through 1440x900, both
 * orientations, ordinary GM and commissioner - and each records what it
 * measured, because the numbers are the reason the rule exists.
 */

/* -- A - the Versus carousel may grow, and the rail may scroll -------------
 *
 * THE ONE FIX THAT CLOSES BOTH CARRY-FORWARD ISSUES, because both were the
 * same defect wearing two hats.
 *
 * MEASURED, before: the carousel item was pinned to 100% of the rail's height
 * whatever the card inside it needed. Where the rail was shorter than the card,
 * the card was simply cut off:
 *
 *     320x568  card needs 127px, rail gives  76px   - 51px of markets lost
 *     360x640  card needs 127px, rail gives  83px
 *     568x320  landscape - the same, at every landscape width measured
 *     375x667  commissioner: needs 127px, rail gives 76px
 *
 * The commissioner case looked like a masthead problem and the 320 case looked
 * like a small-screen problem. Both were this: a rail too short for its card,
 * with no way for the card to say so.
 *
 * min-height INSTEAD OF height is the whole change. Where the card fits, the
 * item still fills the rail and behaves exactly as certified. Where it does
 * not, the item grows to the card and the rail scrolls - the intentional
 * vertical scrolling Rev 4.3 permits, arrived at by letting content be measured
 * rather than by hiding any of it. Scroll snapping is untouched: each card
 * still parks at the top of the rail.
 *
 * WHAT WAS NOT DONE, deliberately: no market removed, no card content hidden,
 * no type shrunk below the readability floor, no density increase. */
.fs-carousel__item {
  height: auto;
  min-height: 100%;
}

/* -- B - the masthead keeps the wordmark legible at every width ------------
 *
 * MEASURED, before: the meta column is sized by its widest row, and the
 * COMMISSIONER badge is 93px of it. With nothing bounding the column, the
 * lockup was squeezed until the tagline wrapped to a third line and the
 * masthead grew from 71px to 87px:
 *
 *     320  commissioner: lockup  37px   - the wordmark itself was crushed
 *     360  commissioner: lockup  77px
 *     375  commissioner: lockup  92px
 *     390  commissioner: lockup 107px
 *
 * CAPPING THE COLUMN IS THE STRUCTURAL FIX, and it is preferred over shrinking
 * any text. The lockup keeps at least half the row, so the wordmark and its
 * tagline always have room; the meta column takes what is left and its own
 * contents ellipsize inside it. Nothing is removed: the commissioner indicator,
 * the provider chip and the gear all still render. */
.fs-mast__meta {
  max-width: 48%;
  min-width: 0;
}

.fs-mast__lockup {
  min-width: 0;
  flex: 1 1 auto;
}

.fs-ident {
  min-width: 0;
  max-width: 100%;
}

/* THE BADGE SHRINKS BEFORE THE WORDMARK DOES. It is a label, not a control,
 * and a narrowed one still reads as the commissioner marker. */
.fs-ident__badge {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* -- C - touch targets, without paying for them in masthead height ---------
 *
 * THE GEAR ALREADY SOLVED THIS and the note beside it explains how: a 44px hit
 * area achieved with padding and cancelled with negative margin, so the TOUCH
 * TARGET is full size while the OPTICAL box stays 24px and the meta column does
 * not grow. Sign out gets the same treatment rather than a new one.
 *
 * MEASURED, before: Sign out 24px, Request Top-Off 32px. */
.fs-ident__out {
  min-height: var(--fs-r43-touch);
  padding-top: 10px;
  padding-bottom: 10px;
  margin-top: -10px;
  margin-bottom: -10px;
  display: inline-flex;
  align-items: center;
}

.fs-topoff {
  min-height: var(--fs-r43-touch);
  display: inline-flex;
  align-items: center;
}

/* THE ATTRIBUTION LINK IS A REAL TARGET TOO. Measured at 14px - below even the
 * 24px floor. It sits at the end of a panel that scrolls, so it can simply be
 * given the room rather than a negative-margin trick. */
.fs-attribution__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--fs-r43-touch);
  padding: 0 var(--fs-space-3);
}

/* -- D - safe areas on every edge, not only two ----------------------------
 *
 * The tokens defined top and bottom; a notched phone in LANDSCAPE puts the
 * cutout on a SIDE, and nothing was reserving it. The panel, the masthead, the
 * gate and the navigation all take the horizontal insets so no content and no
 * tab can sit underneath one.
 *
 * DESKTOP PAYS NOTHING: env() resolves to 0px where there is no inset, which is
 * every desktop browser and every phone in portrait without a side cutout. */
.fs-app {
  padding-left: max(var(--fs-safe-left), 0px);
  padding-right: max(var(--fs-safe-right), 0px);
}

/* IT GOES ON THE FRAME, NOT ON THE CHILDREN, and that distinction was learned
 * the expensive way. Setting `padding-left`/`padding-right` on `.fs-mast`
 * OVERWROTE the horizontal gutter its own shorthand had set — measured: the
 * gear's optical alignment relies on a -12px right margin against that gutter,
 * and with the gutter gone the icon painted 12px past the viewport edge and the
 * app frame reported 402px inside a 390px window.
 *
 * The frame has no horizontal padding of its own, so it can carry the insets
 * without displacing anything, and every child keeps the gutter it was
 * designed with. */

/* -- E - reduced motion ----------------------------------------------------
 *
 * FOUR TRANSITIONS EXIST IN THE WHOLE PRODUCT, all of them a 0.12-0.15s
 * transform on a press state. They are non-essential decoration, so a reader
 * who has asked for less motion gets none of it.
 *
 * THE STATE CHANGE ITSELF IS KEPT. This removes the ANIMATION, not the
 * feedback: a pressed control still changes, it simply arrives immediately.
 * 0.01ms rather than none, so any transitionend handler still fires. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* -- F - focus is always visible -------------------------------------------
 *
 * A BASELINE, NOT A REPLACEMENT. Components that already draw their own focus
 * treatment keep it; this is the floor beneath everything else, so no
 * interactive control can be reached by keyboard without being seen.
 *
 * :focus-visible rather than :focus, so a mouse press does not leave a ring
 * behind - the browser decides when the ring is wanted, which is what that
 * pseudo-class is for. */
:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

/* -- G - desktop stays readable --------------------------------------------
 *
 * Rev 4.3 is mobile-first and stays mobile-first: the phone layout is CENTRED
 * and CONSTRAINED on a wide screen rather than stretched into line lengths
 * nobody can track. This is not a desktop redesign - it is the same product,
 * not pulled out of shape. */
@media (min-width: 768px) {
  .fs-app {
    max-width: 520px;
    margin: 0 auto;
    border-left: var(--fs-border-hair);
    border-right: var(--fs-border-hair);
  }
}


/* -- H - the summary strip reaches its Rev 4.3 size ------------------------
 *
 * MEASURED, before: labels 9px and values 18px, which are the Rev 4.2 sizes.
 * Rev 4.3 SS5.1 sets summary-strip labels at 13-14px and values at 22-24px,
 * and WP3B raised the titles, the section headings and the navigation but
 * never reached the strip - so four tabs were still reporting the GM's money
 * at the old scale. The strip is where a GM reads what they have; it is the
 * last place that should have been left small.
 *
 * THE CELL ABSORBS IT. The strip is a fixed row above scrollable content, so
 * the extra height comes out of the region below it - which every panel can
 * now scroll. Nothing is truncated and no cell wraps: the four labels are
 * short by design and the values are tabular figures. */
.fs-strip__label {
  font-size: var(--fs-r43-meta);   /* 13px — SS5.1 */
  min-height: 0;
  margin-bottom: 2px;
  /* SS5.2 - less shouting. The label reads as a label without the tracking. */
  letter-spacing: .01em;
  text-transform: none;
}

.fs-strip__value {
  font-size: 22px;
  line-height: 1.1;
}

/* -- I - a short viewport lets the PANEL scroll ----------------------------
 *
 * MEASURED, before: at 568x320 the Account panel held 348px of content in a
 * 205px box with overflow hidden. The bottom of the Ledger, the disclosures
 * beneath it and the attribution were all simply unreachable - no scrollbar,
 * no gesture, nothing.
 *
 * WHY IT ONLY BITES IN LANDSCAPE. Each panel is a fixed header over its own
 * scrolling region, which is exactly right when the panel is tall: the header
 * stays put and the content moves under it. Turn the phone sideways and the
 * panel is 205px tall, the fixed chrome eats most of it, and the inner region
 * has nowhere left to be.
 *
 * SCOPED TO SHORT VIEWPORTS ON PURPOSE. 520px clears every landscape phone in
 * the matrix (320, 375, 390 and 430 tall) and no portrait one (568 and up), so
 * the certified portrait behaviour is untouched and the inner rails keep their
 * own scrolling everywhere it works. */
@media (max-height: 520px) {
  .fs-panel {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* -- J - the week switch is a real target ---------------------------------
 *
 * MEASURED, before: 32px. It is how a GM moves between weeks on Wrap Up, and
 * it is a control like any other. */
.fs-wkswitch__opt {
  min-height: var(--fs-r43-touch);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}


/* -- K - the Pools grid keeps its cards whole -----------------------------
 *
 * MEASURED AT HEAD, BEFORE THIS PACKAGE: a Pool card needs 74px and the grid
 * was giving it 31px at 320x568 and 60px at 375x667. The 2x2 grid was sharing
 * a flexed zone by dividing it, so as the zone shrank the rows shrank with it
 * and the cards were cut rather than the zone admitting it had run out of room.
 * This is pre-existing - the WP3E brief lists Pools cards at 320 among the
 * things that must not clip - and the summary strip reaching its Rev 4.3 size
 * made it 10px worse, so it is closed here rather than carried.
 *
 * ROWS SIZED BY CONTENT, ZONE SCROLLS WHEN IT MUST. `auto` rows mean a card is
 * as tall as the card needs; `align-content: start` stops the tracks being
 * stretched or centred into the leftover space; `overflow-y: auto` gives the
 * zone somewhere to put what does not fit.
 *
 * THE 2x2 CONCEPT IS UNTOUCHED AND SO IS THE SLATE. Two columns, four
 * contests, same order. Nothing is removed and nothing is hidden - the zone
 * scrolls, which is what Rev 4.3 permits when geometry runs out. */
.fs-pools {
  grid-auto-rows: auto;
  align-content: start;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* -- L - the Pool row is a real target ------------------------------------
 *
 * MEASURED, before: 39px. It opens the Pool sheet, so it is a control. */
.fs-poolrow {
  min-height: var(--fs-r43-touch);
}


/* -- K2 - the Pools grid, corrected at the source of the decision ---------
 *
 * `tabs.css` states the Rev 4.2 trade-off in its own words: a Pool card
 * "compresses and clips instead", chosen so that all four stayed visible
 * without the zone scrolling. That was a deliberate call and it is the one
 * WP3E supersedes: the brief lists Pools cards at 320x568 among the things
 * that must not clip, and forbids solving geometry by hiding content.
 *
 * SO THE PRIORITY INVERTS. The card keeps its content and the ZONE scrolls
 * when four of them will not fit. Two columns, four contests, same order -
 * nothing removed, nothing hidden. `grid-template-rows` has to be overridden
 * explicitly because `1fr 1fr` sizes EXPLICIT tracks and `grid-auto-rows`
 * reaches only implicit ones. */
.fs-pools {
  grid-template-rows: none;
  /* `max-content`, NOT `auto`. An `auto` track in a grid whose container has a
   * definite height still takes part in distributing that height, so the rows
   * came back sized to the container (measured: 47.7px each in a 100px zone)
   * while the card needed 74px. `max-content` sizes the row to the card and
   * lets the zone overflow — which it is now allowed to do. */
  grid-auto-rows: max-content;
}

.fs-pool {
  /* The two rules that made the card give way. A grid item may now insist on
   * its own content height, and nothing inside it is cut. */
  min-height: var(--fs-r43-touch);
  overflow: visible;
}


/* -- B2 - the narrowest phones need a little more meta column -------------
 *
 * MEASURED, after B: at 320px the 48% cap left the provider chip 125px for a
 * label that needs 127 - `YAHOO . NOT SYNCED YET`, the longest of the six - and
 * it ellipsized. A truncated provider state is a state a GM cannot read, which
 * is the one thing the chip exists to avoid.
 *
 * 52% AT 360 AND BELOW, and 48% above it. That buys the chip 12px, which is
 * enough for the longest label, and still leaves the lockup 154px for an
 * ordinary GM and 145px for a commissioner - both above the 140px floor the
 * wordmark needs. Two numbers, both measured, neither guessed. */
@media (max-width: 360px) {
  /* THE 320px MASTHEAD, SOLVED WITH MEASUREMENTS RATHER THAN GUESSES.
   *
   * At 320px, five things want the same row: the wordmark, the tagline, the
   * provider chip, the COMMISSIONER badge and the gear. The longest reachable
   * chip label — YAHOO · NOT SYNCED YET — needs 115px, the gear is a 44px
   * touch target, and the row between them needs 162px in total. The lockup
   * needs 131px for the wordmark at its normal size. 162 + 131 + the gap is
   * 298px, and a 320px masthead with 16px gutters offers 288px.
   *
   * So ten pixels have to come from somewhere, and the order in which they are
   * taken is the whole point. §6 prefers compact structure over shrinking
   * text, so structure gives first and copy is never truncated:
   *
   *   1. the gutter narrows to 12px — not below, because the gear's optical
   *      -12px overhang would then paint past the viewport edge
   *   2. the row gap gives up its remaining slack
   *   3. the meta cap is loosened to what the chip actually needs, since the
   *      lockup is no longer the thing under pressure
   *   4. only then does the wordmark step down one notch
   *
   * Everything above 360px is untouched by all four. */
  .fs-mast {
    padding-left: 12px;
    padding-right: 12px;
    gap: var(--fs-space-2);
  }

  /* THE CAP IS SET TO WHAT THE CHIP ROW MEASURES, not to a percentage.
   *
   * A percentage was tried and was wrong in an instructive way. 58% cleared the
   * chip at 320 and then, at 360, handed the commissioner's identity row —
   * team name, COMMISSIONER badge, SIGN OUT — 195px it was happy to use. The
   * lockup fell to 136px, the tagline wrapped to a third line, and the masthead
   * grew to 82px: a fix for one role that broke the other.
   *
   * The chip row needs 166px at its longest and does not vary with viewport
   * width, so the cap does not either. The identity row, which has three
   * ellipsis-capable items and no natural limit, is held to the same number
   * rather than being allowed to set it. */
  .fs-mast__meta { max-width: 170px; }

  /* And the chip gives up its remaining tracking rather than its last word. */
  .fs-source__label {
    letter-spacing: 0;
    padding-left: 4px;
    padding-right: 4px;
  }

  /* THE LOCKUP STEPS DOWN ONE NOTCH, and only here. A wordmark that wraps or
   * clips is worse than one a few points smaller, and this is the last lever
   * after the structural ones above.
   *
   * 18px IS NOT A READABILITY COMPROMISE. Rev 4.3 §5.1 governs page titles,
   * section headings, card text and navigation; the brand lockup is none of
   * those, and 18px is at or above every one of those floors. Nothing else in
   * the masthead moves. */
  .fs-mast__word { font-size: 18px; }
}
