/* ============================================================================
   LOCAL ADDITIONS to the designer's web-blocks.css
   ----------------------------------------------------------------------------
   Everything here is OURS, not the designer's. It is kept in a separate file so
   a new drop can overwrite web-blocks.css wholesale without silently deleting
   it, which is exactly what would have happened on the 2026-08-05 (delivery 4)
   sync: the incoming bundle contains none of these selectors.

   Load order: tokens.css -> web-blocks.css (designer) -> this file.

   If the designer later ships an equivalent, delete the block here rather than
   letting the two fight.
   ============================================================================ */

/* ── Suit pips in running text (inc/pips.php) ─────────────────────────────────
   The designer's pip SVGs carry their own fills (heart/diamond red, club/spade
   black), so these only need sizing and alignment. Sized in em so a pip tracks
   whatever type it sits in, and nudged down slightly to sit on the baseline
   rather than ride high like the raw Unicode glyph does. */
.eg-web .eg-pip {
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  vertical-align: -0.08em;
  margin: 0 0.04em;
}

/* ── Rules stickies, the OLD core-group pattern only ─────────────────────
   Since 2026-10-18 the book's stickies are the el/sticky block, which carries
   its own CSS (blocks/sticky/style.css, the canon sticky colour tokens). The
   rules below are scoped to `.wp-block-group.eg-sticky`, the shape the old
   importer baked into pages not yet re-imported from the r175 bundle, so
   they no longer override the block. Delete them once every page has been
   re-imported. */
/* ── Rules stickies (animal callouts, ported from print blocks.css) ─────────
   The web bundle has never carried the sticky; only the print bundle does. The
   book's Rule / Tip / Good-to-know boxes carry the wolf, sparrow and fox, and
   the rules chapters are full of them, so they were ported across. */
.eg-web .wp-block-group.eg-sticky { display: flex; gap: var(--eg-w-sp-4); align-items: flex-start; margin: var(--eg-w-sp-6) 0; padding: var(--eg-w-sp-4) var(--eg-w-sp-5); background: var(--eg-paper-2); border-left: 3px solid var(--eg-ink); border-radius: 0 var(--eg-w-radius-card) var(--eg-w-radius-card) 0; }
/* motif is a core/image block (figure > img), so reset the figure and size the img */
.eg-web .wp-block-group.eg-sticky-motif { flex: 0 0 auto; margin: 0; align-self: center; }
.eg-web .wp-block-group.eg-sticky-motif img { display: block; width: 56px; height: auto; }
.eg-web .wp-block-group.eg-sticky-text { flex: 1 1 auto; min-width: 0; }
.eg-web .wp-block-group.eg-sticky-label { margin: 0 0 var(--eg-w-sp-1); font-family: var(--eg-display); font-style: italic; font-weight: 700; font-size: var(--eg-w-fs-h3); line-height: 1.15; }
.eg-web .wp-block-group.eg-sticky-body { margin: 0; font-family: var(--eg-serif); font-size: var(--eg-w-fs-body); line-height: var(--eg-w-lh-body); color: var(--eg-ink-2); }
.eg-web .wp-block-group.eg-sticky--rule { border-left-color: var(--eg-red); }
.eg-web .wp-block-group.eg-sticky--rule .eg-sticky-label { color: var(--eg-red); }
.eg-web .wp-block-group.eg-sticky--tip { border-left-color: var(--eg-pine); }
.eg-web .wp-block-group.eg-sticky--tip .eg-sticky-label { color: var(--eg-pine); }
.eg-web .wp-block-group.eg-sticky--info, .eg-web .wp-block-group.eg-sticky--note { border-left-color: var(--eg-gold); }
/* The RULE (red) and TIP (pine) labels clear contrast on paper-2 at 4.97:1 and
   8.25:1. Gold does not: --eg-gold on paper-2 measures 2.64:1, which fails even
   the 3:1 large-text floor, so the "Good to know" heading was the hardest thing
   on the page to read. Gold is fine in the book (ink on paper, different rules);
   it is not fine on screen.
   Rather than invent a colour, which is the designer's call, this darkens THEIR
   token: 65% gold against ink measures 4.95:1, clearing the 4.5 bar while still
   reading as the same gold. The rule (border) keeps the pure token, since a
   3px rule carries no text. */
.eg-web .wp-block-group.eg-sticky--info .eg-sticky-label, .eg-web .wp-block-group.eg-sticky--note .eg-sticky-label {
  color: color-mix(in srgb, var(--eg-gold) 65%, var(--eg-ink));
}
/* Older engines without color-mix keep a hand-computed equivalent of the same mix. */
@supports not (color: color-mix(in srgb, red, blue)) {
  .eg-web .wp-block-group.eg-sticky--info .eg-sticky-label, .eg-web .wp-block-group.eg-sticky--note .eg-sticky-label { color: #7D602B; }
}
@media (max-width: 640px) { .eg-web .wp-block-group.eg-sticky-motif img { width: 40px; } }

/* ── Sticky + contract-card margins, once nested inside .eg-prose (batch 2) ──
   Both components' labels/bodies are plain <p> (sticky) or <h3>/<p>
   (el/contract-cards) — the same tags G2's `.eg-web .eg-prose p/h3` rules
   reset for running prose. `.eg-web .eg-prose p` is TWO classes plus the tag
   (0,0,2,1); `.eg-sticky-label`/`.eg-sticky-body`/`.eg-rules-body` are each
   ONE class (0,0,1,0 in web-blocks.css / local), so the blanket prose rule
   wins and zeroes their intended margin. Chain onto `.eg-prose` (three
   classes) to win back the components' own spacing, same pattern as the E4
   callout-label fix. `.eg-rules-heading`'s h1-scale base margin-top is
   already beaten by `.eg-rules--compact .eg-rules-heading` (three classes)
   for margin-bottom, but margin-top is a SEPARATE longhand nothing else in
   web-blocks-local.css sets, so `.eg-prose h3`'s `var(--eg-w-sp-6)` top
   margin lands on top of the section's own border-top padding and doubles
   the gap between cards; reset it to the base 0 explicitly. */
.eg-web .eg-prose .eg-sticky-label { margin: 0 0 var(--eg-w-sp-1); }
.eg-web .eg-prose .eg-sticky-body { margin: 0; }
.eg-web .eg-prose .eg-rules-heading { margin-top: 0; }
.eg-web .eg-prose .eg-rules-body { margin: 0 0 var(--eg-w-sp-5); }

/* ── Prose tables (contract / scoring tables inside .eg-prose) ───────────────
   The rules chapters carry real markdown tables which arrive as core/table.
   The designer's bundle styles .eg-prose but not the core table inside it.

   width:auto (not 100%) + min-width is the same fix the G9/G17 comparison
   tables needed below (batch-1 lesson, re-hit by batch 2's rules chapters):
   width:100% pins the table to the column at any cost, so a wide contract
   table (5-6 columns) gets squeezed into 62ch instead of scrolling. auto lets
   it fill the column when the content fits and grow past it, inside the
   overflow-x:auto figure, when it does not. */
.eg-web .eg-prose .wp-block-table { margin: var(--eg-w-sp-6) 0; overflow-x: auto; }
.eg-web .eg-prose .wp-block-table table { table-layout: auto; width: auto; min-width: max(100%, 30rem); border-collapse: collapse; font-family: var(--eg-serif); font-size: var(--eg-w-fs-body); line-height: var(--eg-w-lh-body); }
.eg-web .eg-prose .wp-block-table th, .eg-web .eg-prose .wp-block-table td { padding: var(--eg-w-sp-3) var(--eg-w-sp-4); text-align: left; vertical-align: top; border-bottom: 1px solid var(--eg-ink-4); word-break: normal; overflow-wrap: normal; }
.eg-web .eg-prose .wp-block-table thead th { font-family: var(--eg-sans); font-size: var(--eg-w-fs-label); font-weight: 700; letter-spacing: var(--eg-track-caps); text-transform: uppercase; color: var(--eg-red-deep); background: var(--eg-paper-2); border-bottom: 2px solid var(--eg-red); }
.eg-web .eg-prose .wp-block-table tbody tr:last-child td { border-bottom: none; }

/* ── Contract cards: designer rules-section (H6), compact for a long list ──── */
.eg-web .eg-rules--compact { max-width: none; padding: var(--eg-w-sp-5) 0; border-top: 1px solid var(--eg-ink-4); }
.eg-web .eg-rules--compact .eg-rules-heading { font-size: var(--eg-w-fs-h3); margin-bottom: var(--eg-w-sp-3); }
.eg-web .eg-rules--compact .eg-rules-body { margin-bottom: var(--eg-w-sp-4); }
.eg-web .eg-rules-scope { font-family: var(--eg-sans); font-size: var(--eg-w-fs-label); font-weight: 700; letter-spacing: var(--eg-track-caps); text-transform: uppercase; color: var(--eg-gold); vertical-align: middle; }

/* Supporting points inside a pillar — no slot in the H2 specimen, so styled to
   sit under .eg-pillar-body in the same voice. */
.eg-web .eg-pillar-points { margin: var(--eg-w-sp-3) 0 0; padding-left: 1.1em; font-family: var(--eg-serif); font-size: var(--eg-w-fs-body); line-height: var(--eg-w-lh-body); color: var(--eg-ink-2); }
.eg-web .eg-pillar-points li + li { margin-top: var(--eg-w-sp-2); }

/* ── Book-scaffold placeholders (inc/book-scaffold.php) ───────────────────────
   "Content coming" notices: the dashed stub box for book-referenced pages not
   yet authored (a reader can land here straight from a printed QR code), and
   the one-line note on a game's downloads page while its cheat sheet is still
   gated on the book locking its numbers. el-, not eg- — neither is a designer
   component, both used to wear an invented eg- prefix that styled nothing
   (flagged by e2e/audit-design-provenance.mjs). The stub's border/padding
   come from Gutenberg block settings already inline on the markup; this only
   ties the border colour and label ink to the design system's own tokens
   instead of the inline style's default currentColor / body ink. */
.eg-web .el-stub { border-color: var(--eg-ink-4); }
.eg-web .el-stub__label { color: var(--eg-ink-3); }
.eg-web .el-sheet-pending { margin-top: var(--eg-w-sp-5); font-family: var(--eg-serif); font-style: italic; font-size: var(--eg-w-fs-small); color: var(--eg-ink-3); }

/* ============================================================================
   BLOG POST SHAPES — core Gutenberg blocks wearing the designer's classes
   ----------------------------------------------------------------------------
   The 26 blog posts carry G10 (FAQ), G13 (verdict) and G9 / G17 (tables) as
   core blocks with the designer's class names attached, written by
   scripts/blog_structure.py. Core blocks were chosen over custom ones so Greg
   keeps the normal Gutenberg editing experience.

   The cost of that choice is here: core owns some of the inner markup, so
   where the designer styles an element we cannot emit, the same declarations
   are re-pointed at the element core does emit. Only those bridges live below.
   Everything else still comes from the designer's own rules, which match on
   the class names already.
   ============================================================================ */

/* ── G10 FAQ: core/details ────────────────────────────────────────────────────
   Designer: <summary class="eg-faq-q"> + <span class="eg-faq-mark"> chevron +
   <div class="eg-faq-a"> around the answer. Core owns the summary's inner HTML
   (a decorative span there would be stripped on re-save) and wraps the answer
   in nothing at all, so: style the bare summary, draw the chevron with ::after,
   and address the answer as "the children that are not the summary". */
.eg-web .eg-faq-item > summary { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--eg-w-sp-4); padding: var(--eg-w-sp-4) 0; cursor: pointer; list-style: none; font-family: var(--eg-display); font-weight: 700; font-size: var(--eg-w-fs-h3); line-height: 1.3; color: var(--eg-ink); }
.eg-web .eg-faq-item > summary::-webkit-details-marker { display: none; }
.eg-web .eg-faq-item > summary::marker { content: ""; }
.eg-web .eg-faq-item > summary:hover { color: var(--eg-red-deep); }
.eg-web .eg-faq-item > summary::after { content: ""; flex: 0 0 auto; width: 9px; height: 9px; margin: 7px 3px 0 0; border-right: 2px solid var(--eg-red); border-bottom: 2px solid var(--eg-red); transform: rotate(45deg); transition: transform 120ms ease; }
.eg-web .eg-faq-item[open] > summary::after { transform: rotate(225deg); }
.eg-web .eg-faq-item > *:not(summary) { margin: 0 0 var(--eg-w-sp-5); max-width: 62ch; font-family: var(--eg-serif); font-size: var(--eg-w-fs-body); line-height: var(--eg-w-lh-body); color: var(--eg-ink-2); }
.eg-web .eg-faq-item > summary + * { margin-top: 0; }

/* ── G13 verdict: core/columns ────────────────────────────────────────────────
   The designer's .eg-verdict is a grid and outranks .wp-block-columns on
   specificity already; these two lines only stop core's flex sizing (including
   its !important mobile stacking rule) from leaving stray tracks in the grid. */
.eg-web .eg-verdict.wp-block-columns { display: grid; }
.eg-web .eg-verdict > .wp-block-column { flex-basis: auto !important; }

/* ── G9 / G17 tables: core/table ──────────────────────────────────────────────
   Designer: figure.eg-cmp > div.eg-cmp-scroll > table.eg-cmptable. Core emits
   figure.wp-block-table > table.has-fixed-layout and regenerates that table
   class on save, so the figure becomes the scroll region and the table styles
   are re-pointed. has-fixed-layout is also undone: fixed layout splits a
   7-column table into equal slivers, while the whole point of a scroll strip
   is that columns take the width their content needs. */
.eg-web .wp-block-table.eg-cmp, .eg-web .wp-block-table.eg-bynum { margin: var(--eg-w-sp-6) 0; overflow-x: auto; scrollbar-width: thin; -webkit-overflow-scrolling: touch; padding-bottom: var(--eg-w-sp-2); }
.eg-web .wp-block-table.eg-cmp::-webkit-scrollbar, .eg-web .wp-block-table.eg-bynum::-webkit-scrollbar { height: 4px; }
.eg-web .wp-block-table.eg-cmp::-webkit-scrollbar-thumb, .eg-web .wp-block-table.eg-bynum::-webkit-scrollbar-thumb { background: var(--eg-red); }
/* width:auto (not 100%) is what lets the scroll strip earn its keep: the table
   fills the column when the content fits and grows past it when it does not,
   instead of being squeezed into the container at any cost. min-width keeps
   the designer's floor while still filling a wider column. */
.eg-web .wp-block-table.eg-cmp table, .eg-web .wp-block-table.eg-bynum table { table-layout: auto; width: auto; border-collapse: collapse; }
.eg-web .wp-block-table.eg-cmp table { min-width: max(100%, 30rem); font-family: var(--eg-sans); }
.eg-web .wp-block-table.eg-bynum table { min-width: max(100%, 26rem); }
/* The theme sets word-break:break-word for long prose. In a 7-column table it
   shatters headings into "Playe rs" and "Contrac ts", so cells opt out: a
   comparison table wraps between words or it scrolls, it never hyphenates. */
.eg-web .wp-block-table.eg-cmp th, .eg-web .wp-block-table.eg-cmp td,
.eg-web .wp-block-table.eg-bynum th, .eg-web .wp-block-table.eg-bynum td { word-break: normal; overflow-wrap: normal; }
.eg-web .wp-block-table.eg-cmp th, .eg-web .wp-block-table.eg-cmp td,
.eg-web .wp-block-table.eg-bynum th, .eg-web .wp-block-table.eg-bynum td { padding: var(--eg-w-sp-3) var(--eg-w-sp-4); text-align: center; border: 0; border-bottom: 1px solid var(--eg-rule); }
.eg-web .wp-block-table.eg-cmp th, .eg-web .wp-block-table.eg-cmp td { vertical-align: top; }
.eg-web .wp-block-table.eg-bynum th, .eg-web .wp-block-table.eg-bynum td { vertical-align: baseline; }
/* The row-label column: the designer marks it <th scope="row">, core keeps it
   a <td>, so the first cell of every body row is addressed by position. */
.eg-web .wp-block-table.eg-cmp tbody td:first-child { font-size: var(--eg-w-fs-small); font-weight: 600; color: var(--eg-ink-2); text-align: left; }
.eg-web .wp-block-table.eg-cmp thead th { font-size: var(--eg-w-fs-label); font-weight: 700; letter-spacing: var(--eg-track-caps); text-transform: uppercase; color: var(--eg-ink); border-bottom: 2px solid var(--eg-red); }
.eg-web .wp-block-table.eg-cmp thead th:first-child { text-align: left; }
.eg-web .wp-block-table.eg-cmp tbody td { font-size: var(--eg-w-fs-small); line-height: var(--eg-w-lh-small); color: var(--eg-ink); font-variant-numeric: tabular-nums; }
.eg-web .wp-block-table.eg-bynum thead th { font-family: var(--eg-display); font-weight: 700; font-size: var(--eg-w-fs-h3); line-height: var(--eg-w-lh-h3); color: var(--eg-ink); border-bottom: 2px solid var(--eg-red); }
.eg-web .wp-block-table.eg-bynum tbody td { font-family: var(--eg-sans); font-size: var(--eg-w-fs-h3); font-weight: 700; color: var(--eg-ink); font-variant-numeric: lining-nums tabular-nums; }
.eg-web .wp-block-table.eg-bynum tbody td:first-child { font-family: var(--eg-sans); font-size: var(--eg-w-fs-label); font-weight: 600; letter-spacing: var(--eg-track-caps); text-transform: uppercase; color: var(--eg-ink-3); text-align: left; }
.eg-web .wp-block-table.eg-cmp tbody tr:last-child td, .eg-web .wp-block-table.eg-bynum tbody tr:last-child td { border-bottom: 0; }
.eg-web .wp-block-table.eg-cmp figcaption, .eg-web .wp-block-table.eg-bynum figcaption { caption-side: top; text-align: left; margin: 0 0 var(--eg-w-sp-3); font-family: var(--eg-sans); font-size: var(--eg-w-fs-label); font-weight: 700; letter-spacing: var(--eg-track-caps); text-transform: uppercase; color: var(--eg-red-deep); }
/* Focus ring for the keyboard-reachable scroll region (see eg-web.js). */
.eg-web .wp-block-table[tabindex]:focus-visible { outline: 2px solid var(--eg-red); outline-offset: 2px; }

/* ── E4 print-tip: core/group(aside) + core/paragraph ─────────────────────────
   E4 IS G5-CALLOUT (MAP-WEB.json), reused rather than a new shell. The
   designer's LABEL is a <span class="eg-callout-label">; core's closest
   native block for text is a <p>. web-blocks.css's `.eg-callout p` rule
   (specificity 0,1,1) beats `.eg-callout-label` alone (0,1,0) once the label
   is also a <p>, silently reverting it to the body callout's serif/ink-2
   treatment instead of the eyebrow. Chain onto the label's own class, one
   selector step more specific than the body rule, rather than re-adding a
   raw <span> that the block editor would strip on the next save. */
.eg-web .eg-callout > .eg-callout-label { margin: 0 0 var(--eg-w-sp-2); font-family: var(--eg-sans); font-size: var(--eg-w-fs-label); font-weight: 700; letter-spacing: var(--eg-track-caps); text-transform: uppercase; color: var(--eg-red-deep); }

/* ── E1/E2/E3 downloads, D1-D5 decks: no bridge needed ────────────────────────
   E1/E2/E3 nest a real <ul>/<li>/<a>/<span> format-chooser inside core/list,
   and single-game/single-deck/deck-card are dynamic PHP blocks emitting the
   designer's literal markup (SSOT-derived content, per the rule that reaches
   for a dynamic block instead of core Gutenberg blocks). Nothing here fights
   web-blocks.css, so there is nothing to re-point. */

/* ── Contract name index (game landing) ──────────────────────────────────────
   A wrapping row of contract names under the H6 rules-section shell. It
   replaced fifteen per-contract sections: once the engine notes were removed
   there was no body left, so each shell rendered as a lone heading above a
   hairline and the section became a column of empty rows.

   The chips themselves are the designer's .eg-badge, so nothing here styles
   them; this only lays them out and quiets the list semantics. */
.eg-web .el-contract-index { display: flex; flex-wrap: wrap; gap: var(--eg-w-sp-2) var(--eg-w-sp-3); list-style: none; margin: 0; padding: 0; }
.eg-web .el-contract-index__note { margin: var(--eg-w-sp-4) 0 0; font-family: var(--eg-serif); font-size: var(--eg-w-fs-small); color: var(--eg-ink-3); }

/* ── G6 post-card / G7 post-grid (blog index, batch 3) ────────────────────────
   The designer's G6 unit is a single <a class="eg-postcard"> wrapping every
   slot. A Query Loop's post-template item cannot be an <a>: WP wraps each
   post in its own container and expects block children inside it, not a
   single anchor around dissimilar blocks (post-terms, post-title,
   post-excerpt all need to stay independently editable). The bridge is a
   "stretched link": post-title's own <a> (isLink) is given an absolutely
   positioned ::after that covers the whole card, so the entire card is
   clickable through ONE real, keyboard-reachable link, the same outcome the
   designer's single <a> gets, without collapsing the card back into
   unstyled wp:html. */
.eg-web .eg-postcard { position: relative; }
.eg-web .eg-postcard-title a { text-decoration: none; color: inherit; }
.eg-web .eg-postcard-title a::after { content: ""; position: absolute; inset: 0; }
/* post-terms (kicker) keeps its own link underneath the stretched title link;
   it is reachable by keyboard tab order, just not the visible click target,
   same tradeoff the stretched-link pattern always makes. */

/* post-template renders its repeat as <ul><li>…</li></ul>; eg-postgrid is a
   plain CSS grid (.eg-web .eg-postgrid { display:grid; ... }, web-blocks.css)
   that expects its immediate children to BE the cards. display:contents on
   the <li> removes it from the box tree so the card inside becomes a direct
   grid item, without touching list semantics assistive tech still sees. */
.eg-web ul.eg-postgrid { list-style: none; margin: 0; padding: 0; }
.eg-web ul.eg-postgrid > li { display: contents; }

/* Read-time addendum (inc/eg-blog-postcard.php) is a plain <span>, no eg-*
   class, appended after post-date's own markup; it inherits .eg-postcard-meta
   directly and needs nothing of its own. */

/* ── A5 pagination (blog index, batch 3) ───────────────────────────────────────
   query-pagination-numbers accepts a className on the BLOCK, not on the <a>
   elements it generates per page, so the individual links stay core's own
   `page-numbers` / `page-numbers current` / `page-numbers dots` classes. Same
   bridge shape as the E4/callout label above: re-point the designer's
   eg-pager-link / eg-pager-current / eg-pager-gap declarations at what core
   actually emits, inside the .eg-pager wrapper WP DOES let us class directly.
   query-pagination-previous/next DO accept className (set to eg-pager-link in
   the template directly), so only the numbers need the bridge. Known gap: at
   a boundary core OMITS the previous/next link entirely rather than printing
   the designer's --off placeholder span, so the row is not guaranteed to hold
   its width across the first/last page the way A5's spec asks for; reported,
   not silently patched around with an invented markup. */
.eg-web .eg-pager .page-numbers {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 var(--eg-w-sp-3);
  font-family: var(--eg-sans); font-size: var(--eg-w-fs-small); font-weight: 600;
  text-decoration: none; border-radius: 2px; font-variant-numeric: tabular-nums;
  color: var(--eg-ink-2); border: 1px solid var(--eg-ink-4);
}
.eg-web .eg-pager .page-numbers:hover { color: var(--eg-red-deep); border-color: var(--eg-red); }
.eg-web .eg-pager .page-numbers.current { color: var(--eg-paper); background: var(--eg-ink); border-color: var(--eg-ink); }
.eg-web .eg-pager .page-numbers.dots { color: var(--eg-ink-4); border: 0; min-width: 0; }

/* ── Horizontal-scroll edge cue ───────────────────────────────────────────────
   The designer DID specify an affordance for the mobile scroll rows — a 4px
   red scrollbar (web-blocks.css: `.eg-whand::-webkit-scrollbar-thumb`, and the
   same pair on .eg-pile-cards / .eg-cmp-scroll / .eg-dcomp-row). It never
   reaches a real phone: iOS Safari and Android Chrome use OVERLAY scrollbars,
   which are hidden at rest and ignore ::-webkit-scrollbar styling entirely.
   Measured on staging at 360px: the c11 puzzle hand hides 348px of a ten-card
   hand, the Alpine Tarok deck row hides 514px (106px still hidden at 768px),
   the Zwanzigerrufen rules table hides 224px — with nothing on screen saying
   so, so a ten-card hand reads as a four-card hand.

   The fix has to be scrollbar-independent, hence a mask on the container
   itself. Those designer rules stay exactly as they are: on a desktop with
   classic scrollbars the reader gets both, and if a future drop ships its own
   cue this block is the one to delete.

   State comes from eg-web.js, which sets data-eg-scrollcue to the edge(s) that
   still have content beyond them and REMOVES the attribute when the container
   does not scroll — so a row that fits carries no mask at all, and the fade
   only ever sits over content that is already cut off. No transition, so
   nothing here needs a prefers-reduced-motion branch: mask-image gradients do
   not interpolate reliably between these three shapes, and a fade that eases
   in behind your thumb mid-scroll is worse than one that is simply correct.

   `black` here is a mask alpha channel, not a colour — masks read only the
   alpha of the gradient, so no palette value is introduced (and none would
   work: the cue must be transparent to whatever sits behind it). The only
   tunable is the fade width, taken from the designer's spacing scale. */
.eg-web [data-eg-scrollcue] {
  --eg-scrollcue-w: var(--eg-w-sp-6);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}
.eg-web [data-eg-scrollcue="end"] {
  -webkit-mask-image: linear-gradient(to right, black calc(100% - var(--eg-scrollcue-w)), transparent 100%);
          mask-image: linear-gradient(to right, black calc(100% - var(--eg-scrollcue-w)), transparent 100%);
}
.eg-web [data-eg-scrollcue="start"] {
  -webkit-mask-image: linear-gradient(to right, transparent 0, black var(--eg-scrollcue-w));
          mask-image: linear-gradient(to right, transparent 0, black var(--eg-scrollcue-w));
}
.eg-web [data-eg-scrollcue="both"] {
  -webkit-mask-image: linear-gradient(to right, transparent 0, black var(--eg-scrollcue-w), black calc(100% - var(--eg-scrollcue-w)), transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, black var(--eg-scrollcue-w), black calc(100% - var(--eg-scrollcue-w)), transparent 100%);
}
/* A mask applies to the element's whole rendering, outline included, so it
   would eat the focus ring on the keyboard-reachable table figures above
   (`.wp-block-table[tabindex]:focus-visible`). A focused scroll region has a
   better signal than the fade anyway — it has the ring — so drop the mask
   while it is focused rather than ship a scroll region a keyboard user cannot
   see they have landed on. */
.eg-web [data-eg-scrollcue]:focus-visible {
  -webkit-mask-image: none;
          mask-image: none;
}

/* ============================================================================
   el/score-calculator — narrow-viewport rescue
   ----------------------------------------------------------------------------
   The calculator is the one page someone opens WHILE counting a pile at the
   table, i.e. on a phone, so 360px is its primary viewport, not its edge case.
   Measured on staging at 360px before this block existed:

     .eg-calc__player-name   21.2 x 43.6px   (about one character visible)
     .eg-calc__radio > input 13 x 13px       (half the 24px tap-target floor)
     .eg-calc__stat-label    11.52px type    (under the 12px legibility floor)

   The name field's 21px came from the seat row's fixed track list
   (`grid-template-columns: 1fr 5rem 3.5rem` in the block's own style.css):
   the VP field and the running total take 136px + 16px of gaps off the top,
   and at 360px the tally panel's content box is only 173px wide, so the name
   gets whatever is left. Nothing was "too small" — the row simply does not fit
   on a phone and had no instruction to do anything else.

   Lives here, not in the block's style.css, because these are ours; and it is
   prefixed `.eg-web` (two classes) so it outranks the block stylesheet's
   single-class rules regardless of which of the two the browser loads first.
   ============================================================================ */

/* The seat row's real constraint is the TALLY PANEL's width, not the viewport:
   above 44rem the block's own media query splits into two columns, so each
   panel is roughly half as wide as the page. A container query asks the
   question that actually matters ("does this row fit?") once, instead of
   guessing at it twice in viewport terms. */
.eg-web .eg-calc__panel--tally { container-type: inline-size; container-name: eg-calc-tally; }

/* Base (narrow) = stacked: the name gets the full width of the panel on its
   own line, with the hand's points and the running total underneath it. The
   hairline separates one seat from the next now that a seat is two lines. */
.eg-web .eg-calc__player {
  grid-template-columns: 1fr auto;
  grid-template-areas: "name name" "vp total";
  gap: var(--eg-w-sp-2);
  margin-bottom: var(--eg-w-sp-3);
  padding-bottom: var(--eg-w-sp-3);
  border-bottom: 1px solid var(--eg-calc-line);
}
.eg-web .eg-calc__player:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: 0; }
.eg-web .eg-calc__player-name { grid-area: name; }
.eg-web .eg-calc__player-vp { grid-area: vp; }
.eg-web .eg-calc__player-total { grid-area: total; min-width: 3.5rem; }

/* 14rem of panel leaves the name ~90px on one line, which is where the single
   row stops being a lie. Measured panel content boxes: 360px -> 212px stacked,
   768px -> 251px single row, 1280px -> 271px single row, so the desktop
   layout the designer drew is untouched and only the phone changes. */
@container eg-calc-tally (min-width: 14rem) {
  .eg-web .eg-calc__player {
    grid-template-columns: 1fr 5rem 3.5rem;
    grid-template-areas: "name vp total";
    margin-bottom: var(--eg-w-sp-2);
    padding-bottom: 0;
    border-bottom: 0;
  }
}

/* Stat captions ("base", "pips", "Card Points") were 0.72rem = 11.52px, below
   the design system's own smallest caption size. --eg-w-fs-label IS 12px, the
   floor, so this adopts the token rather than inventing a size. Type-only —
   nothing reflows, which is why it is not gated on viewport. */
.eg-web .eg-calc__stat-label { font-size: var(--eg-w-fs-label); line-height: var(--eg-w-lh-label); }

/* The radios are the browser's own control, so they arrive Chrome-blue;
   accent-color paints them in the system's red at no layout cost. */
.eg-web .eg-calc__radio input[type="radio"] { accent-color: var(--eg-red-deep); }

/* Phone only — the block's two-column split happens at 44rem, so 639px is the
   last width that is unambiguously one column and a hand holding a phone.
   (The designer's bundle already uses `@container eg-web (max-width: 639px)`
   for the same purpose, so this reads as part of the same system.) */
@container eg-web (max-width: 639px) {
  /* 28px of shell padding plus 19px of panel padding ate 95px of a 360px
     screen. Pulled back to the system's own 16px/12px steps, which hands the
     tally panel ~38px back — the difference between a usable field and a
     nameplate. */
  .eg-web .eg-calc { padding: var(--eg-w-sp-4); }
  .eg-web .eg-calc__panel { padding: var(--eg-w-sp-3); }
  .eg-web .eg-calc__mode { padding: var(--eg-w-sp-3); }

  /* 13px radio -> 24px, the WCAG 2.2 target-size minimum. Left at the
     designer's size on pointer-driven widths, where it is not a tap target. */
  .eg-web .eg-calc__radio input[type="radio"] {
    inline-size: 24px;
    block-size: 24px;
    flex: 0 0 auto;
    margin: 0;
  }
  /* One choice per line: at 360px the two labels already wrapped mid-sentence
     into an ambiguous stack where the radio no longer read as belonging to the
     text beside it. */
  .eg-web .eg-calc__radio { display: flex; align-items: center; margin: 0 0 var(--eg-w-sp-2); }
  .eg-web .eg-calc__radio:last-of-type { margin-bottom: 0; }

  /* Three stat tiles across a 212px panel leave ~60px each; let them fall onto
     a second line rather than shave the numbers. */
  .eg-web .eg-calc__readout { flex-wrap: wrap; gap: var(--eg-w-sp-2); }
  .eg-web .eg-calc__readout .eg-calc__stat { flex: 1 1 4.5rem; }

  /* In the pip grid, "Empty four held ×0" wraps to two lines where "Trull ×4"
     next to it does not, so the two inputs sat on different baselines and the
     row read as broken. Give each field its own column and push the input to
     the bottom of it, so the inputs line up whatever the label does.
     :not([hidden]) is load-bearing, not decoration — the "empty four" field
     is markup-hidden on the five games that do not use it (view.js unhides it
     only when config.emptyFour is set), and a bare `display: flex` here beats
     the UA's `[hidden] { display: none }` on specificity, which would show a
     Zwanzigerrufen-only input on Dappen and Slovenian Tarok. */
  .eg-web .eg-calc__pips .eg-calc__field:not([hidden]) { display: flex; flex-direction: column; justify-content: space-between; }
}
