/* Barnyard components: cards, bank notes, player tiles, pens, token rows. Built on tokens.css.
 * Every surface (game, guide, design page) renders these classes through public/ui/*.js. */
/* ---------- cards ---------- */
.hand { display: flex; flex-wrap: wrap; gap: 12px; }
.card { position: relative; width: 92px; height: 122px; border-radius: 13px; background: var(--card); box-shadow: var(--shadow); color: var(--ink); flex: none; font-family: var(--font); }
.card .nm { position: absolute; left: 4px; right: 4px; bottom: 9px; text-align: center; font-weight: 800; font-size: 0.8rem; line-height: 1.12; color: var(--ink); }
.card .art { position: absolute; left: 0; right: 0; top: 26px; display: grid; place-items: center; color: var(--c); }
/* Category colour shows on the card itself: drawing lines, corner mark and the Market Day pen icons. */
.card .spicons .cat { color: var(--c); }
.coin { display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 999px; background: var(--gold-soft); color: var(--gold); border: 1.5px solid currentColor; font-weight: 900; font-size: 0.72rem; font-variant-numeric: tabular-nums; }
.coin small { font-size: 0.55rem; font-weight: 900; margin-right: 1px; }
.pips { display: inline-flex; gap: 2px; align-items: center; }
.pips i { width: 5px; height: 5px; border-radius: 50%; background: currentColor; display: block; }
.pips i.e { background: transparent; box-shadow: inset 0 0 0 1.2px currentColor; }
/* The dot a card is about to fill (in a "where will it go" choice): filled, with a ring around it. */
.pips i.new { outline: 1.5px solid currentColor; outline-offset: 1.5px; margin: 0 2px; }

/* Cards: playing-card corner index. Frame stays neutral; category lives in the corner. */
.cardA { border: 1.5px solid var(--line); }
.cardA .idx { position: absolute; top: 7px; left: 7px; display: grid; justify-items: center; gap: 3px; color: var(--c); }
.cardA .idx .pips i { width: 4px; height: 4px; }
.cardA .val { position: absolute; top: 6px; right: 6px; }
.cardA .art { top: 30px; }
/* Art sits in a glow coloured opposite its own hue (measured into public/ui/tones.js): soft on a light card, deep on a
   dark card. A dark animal (Ox, Drake) on a dark card gets a light warm glow instead, since a deep colour won't lift it.
   No category tint: a pink glow behind a pink pig was no buffer at all. */
.cardA .art::before { content: ""; position: absolute; width: 78px; height: 78px; border-radius: 50%; z-index: 0;
  /* Each theme leaves the other theme's tone token unset (initial), so var() falls through to the next one. */
  --glow: var(--glow-d, color-mix(in srgb, var(--hue-glow, var(--glow-mid)) var(--pale-on), var(--hue-glow-d, var(--glow-mid))));
  /* Solid most of the way out, so the whole drawing (not just its middle) sits on the buffer; only the rim fades. */
  background: radial-gradient(circle closest-side, var(--glow) 0%, var(--glow) 45%, color-mix(in srgb, var(--glow) 55%, transparent) 70%, transparent 100%); }
.cardA.drawing-dark .art::before { --glow-d: var(--glow-dark); }
.cardA .art > * { position: relative; z-index: 1; }
/* Everything on a card sits above the drawing's glow: the art (and its glow) is the bottom layer, every other part of the
   face (corner index, value coin, name, and on printed cards the value table and rules text) a layer above it. */
.cardA { isolation: isolate; } /* keeps those layers inside the card, so overlapping cards stack as wholes */
.cardA > .art { z-index: 0; }
.cardA > :not(.art) { z-index: 1; }
/* Bills are banknotes: a note tinted in the denomination colour, a dashed inner border and a round emblem.
   Every figure and the emblem ring are gold (Gold = B$), so the note's colour alone carries the denomination. No corner numbers. */
.cardA.fam-money { background: var(--t); border: 2px solid var(--c); }
.cardA.fam-money .face { position: absolute; inset: 7px; border-radius: 8px; border: 1.3px dashed color-mix(in srgb, var(--c) 60%, transparent); display: grid; place-items: center; }
.cardA.fam-money .amt { width: 46px; height: 46px; border-radius: 50%; background: var(--card); border: 2px solid var(--gold); display: grid; place-items: center; font-weight: 900; font-size: 1.35rem; color: var(--gold); line-height: 1; }
.cardA.fam-money .amt small { font-size: .7rem; margin-right: 1px; }
.cardA.fam-action { border-top: 5px solid var(--c); }
/* Animals carry their pen colour on the bottom edge: a mirror of the action cards' top edge, so the two families stay distinct at a glance. */
.cardA.fam-animal { border-bottom: 5px solid var(--c); }
.cardA.fam-animal .nm { bottom: 7px; }
/* Any (Farm Dog): a meadow camouflage edge where animals carry their pen colour: it blends into any pen. */
/* The Farm Dog's edge has the same shape as an animal's (a 5px bottom border that curves into the corners) but shows the
   meadow camouflage: the border is transparent, and a camouflage layer clipped to the border box shows through it. */
.cardA.fam-wild { border: 1.5px solid var(--line); border-bottom: 5px solid transparent;
  background: linear-gradient(var(--card), var(--card)) padding-box, var(--camo) bottom / auto 7px repeat-x border-box; }
.cardA.fam-wild .nm { bottom: 7px; }
.cardA.fam-wild .anytag { display: block; font-size: 0.5rem; font-weight: 900; letter-spacing: 0.08em; color: var(--c); text-transform: uppercase; margin-top: 1px; }

/* ---------- states and markers ---------- */
.card.drawn::before { content: ""; position: absolute; top: -6px; right: -6px; width: 14px; height: 14px; border-radius: 50%; background: var(--event); box-shadow: 0 0 0 2.5px var(--bg); z-index: 2; }
.card.tossed::after { content: "✕"; position: absolute; top: -10px; right: -10px; width: 22px; height: 22px; border-radius: 50%; background: var(--loss); color: #fff; display: grid; place-items: center; font-size: 0.72rem; font-weight: 900; box-shadow: 0 0 0 2.5px var(--bg); z-index: 3; }
/* Received: the same green corner triangle as a pen slot, flush with the card's bottom-left corner. A card has room
   for an incoming arrow in it; a slot doesn't. */
.card.got::after { content: "↗"; position: absolute; bottom: -1.5px; left: -1.5px; z-index: 3; width: 36px; height: 36px;
  border-bottom-left-radius: 13px; background: var(--grass); clip-path: polygon(0 0, 0 100%, 100% 100%);
  color: var(--on-color); display: flex; align-items: flex-end; justify-content: flex-start; padding: 0 0 3px 5px; box-sizing: border-box;
  font-size: 0.82rem; font-weight: 900; line-height: 1; }
/* Sit it on the card's outer corner: past whichever border the family has (a 5 px bottom edge on animals, 2 px on bills). */
.cardA.fam-animal.got::after { bottom: -5px; }
.cardA.fam-money.got::after { bottom: -2px; left: -2px; }
.card.sel { box-shadow: 0 0 0 3px var(--ink), var(--shadow); transform: translateY(-4px); }
.card.idle { opacity: 0.5; }
.card.ghost { background: transparent; box-shadow: none; border: 1.5px dashed color-mix(in srgb, var(--loss) 55%, var(--surface)); }
.card.ghost > * { opacity: 0.38; }
.card.flying { background: transparent; box-shadow: none; border: 2px dashed var(--line); }
.card.flying > * { visibility: hidden; }
/* Bank breakdown: one stack of banknotes per denomination, figures in gold, count on the corner. */
.bstacks { display: flex; flex-wrap: wrap; gap: 20px 22px; padding: 14px 14px 10px 4px; }
/* Banknotes: tinted note, dashed inner border, round emblem, amount. */
.nbill { position: relative; display: inline-flex; }
.nbill .note { width: 82px; height: 44px; border-radius: 6px; background: var(--t); border: 2px solid var(--c); position: relative; z-index: 2;
  display: flex; align-items: center; gap: 6px; padding: 0 8px; box-shadow: inset 0 0 0 3px var(--t), inset 0 0 0 4.2px color-mix(in srgb, var(--c) 55%, transparent); }
.nbill .note::before { content: ""; position: absolute; inset: 5px; border: 1.2px dashed color-mix(in srgb, var(--c) 60%, transparent); border-radius: 3px; }
.nbill .emb { width: 18px; height: 18px; border-radius: 50%; background: var(--card); border: 1.5px solid var(--gold); flex: none; position: relative; z-index: 1; display: grid; place-items: center; }
.nbill .emb::after { content: ""; width: 1.5px; height: 9px; background: var(--gold); }
/* A paid-out ghost loses its gold: the emblem goes muted red with the rest of it. */
.nbill.ghost .emb { border-color: color-mix(in srgb, var(--loss) 55%, var(--surface)); }
.nbill.ghost .emb::after { background: color-mix(in srgb, var(--loss) 55%, var(--surface)); }
.nbill .amt { font-weight: 900; font-size: 1.1rem; color: var(--gold); position: relative; z-index: 1; font-variant-numeric: tabular-nums; }
.nbill .amt small { color: var(--gold); font-size: .72rem; margin-right: 1px; }
.nbill.n2 .note { box-shadow: inset 0 0 0 3px var(--t), inset 0 0 0 4.2px color-mix(in srgb, var(--c) 55%, transparent), 4px 4px 0 -2px var(--t), 4px 4px 0 0 var(--c); }
.nbill.n3 .note { box-shadow: inset 0 0 0 3px var(--t), inset 0 0 0 4.2px color-mix(in srgb, var(--c) 55%, transparent), 4px 4px 0 -2px var(--t), 4px 4px 0 0 var(--c), 8px 8px 0 -2px var(--t), 8px 8px 0 0 var(--c); }
.nbill .cnt { position: absolute; top: -11px; right: -11px; z-index: 3; min-width: 22px; height: 22px; padding: 0 6px; border-radius: 999px; background: var(--ink); color: var(--bg); font-size: 0.75rem; font-weight: 900; display: inline-grid; place-items: center; box-shadow: 0 0 0 2px var(--surface); }
/* Received: the plain green corner triangle of pen slots (no ↗: a note is too small for it), flush with its bottom-left corner. */
.nbill.got .note::after { content: ""; position: absolute; bottom: -2px; left: -2px; z-index: 3; width: 18px; height: 18px;
  border-bottom-left-radius: 6px; background: var(--grass); clip-path: polygon(0 0, 0 100%, 100% 100%); }
.nbill.ghost .note { background: transparent; border: 1.5px dashed color-mix(in srgb, var(--loss) 55%, var(--surface)); box-shadow: none; }
.nbill.ghost .note::before, .nbill.ghost .emb { opacity: .35; }
.nbill.ghost .amt { color: color-mix(in srgb, var(--loss) 55%, var(--surface)); }
.nbill.ghost .amt small { color: inherit; }

/* ---------- player tiles ---------- */
.tile { background: var(--surface); border: 1.5px solid var(--line); border-radius: 16px; width: 100%; max-width: 340px; overflow: hidden; }
.tile.turn { border-color: var(--barn); box-shadow: 0 0 0 1.5px var(--barn); }
.tile .who { display: flex; align-items: center; gap: 8px; padding: 10px 12px 4px; font-weight: 900; font-size: 1rem; min-width: 0; }
.tile .who .n { white-space: nowrap; } /* names are at most 12 characters, so they always fit */
.dot { width: 9px; height: 9px; border-radius: 50%; background: var(--grass); flex: none; }
.dot.away { background: #d39a1c; }
/* Actions left go before the word, as on your own turn control ("●●○ End turn"). */
.pill .pips { margin-right: 6px; color: inherit; vertical-align: middle; }
.pill { margin-left: auto; flex: none; font-size: 0.66rem; font-weight: 900; letter-spacing: 0.07em; padding: 2px 8px; border-radius: 999px; background: var(--barn); color: #fff; }
.pill.soft { background: var(--surface-2); color: var(--ink-soft); }
.status { display: flex; align-items: center; gap: 10px; padding: 4px 12px 10px; flex-wrap: wrap; }
.stat { display: inline-flex; align-items: center; gap: 4px; font-weight: 900; font-size: 0.9rem; font-variant-numeric: tabular-nums; }
.stat svg.ic { color: var(--ink-soft); }
.goal { display: inline-flex; align-items: center; gap: 6px; }
.goalbar { display: inline-flex; gap: 2px; }
/* Empty segments are outlined rectangles: the animals still needed, the same idea as a pen's empty slots. */
.goalbar i { width: 7px; height: 10px; border-radius: 2px; background: transparent; box-shadow: inset 0 0 0 1.3px color-mix(in srgb, var(--ink-soft) 60%, transparent); display: block; }
.goalbar i.on { background: var(--grass); box-shadow: none; }
.goalbar i:nth-child(3), .goalbar i:nth-child(7) { margin-right: 2px; } /* 10 segments read as 3-4-3 */
.farm { display: flex; gap: 6px; flex-wrap: wrap; padding: 9px 12px 11px; background: var(--bg); border-top: 1px solid var(--line); }
.farm .none { color: var(--ink-soft); font-size: 0.82rem; font-weight: 700; }
.pchip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 7px 3px 4px; border-radius: 999px; background: var(--card); border: 1.5px solid var(--line); }
/* Fenced = shaded in the pen's tint, no outline (outlines are reserved for selection). */
.pchip.fenced { background: var(--t); border-color: transparent; }
.pchip .pips i { width: 6px; height: 6px; }
.pchip .ex { display: inline-flex; color: var(--ink-soft); }
/* Extras sit after a thin rule, Farm Dog before Barn (the pen's own order), so they never read as more animals. */
.pchip .exs { display: inline-flex; align-items: center; gap: 3px; margin-left: 2px; padding-left: 5px; border-left: 1.5px solid color-mix(in srgb, var(--ink-soft) 35%, transparent); }

/* ---------- pen tiles ---------- */
.pen { background: var(--surface); border: 1.5px solid var(--line); border-radius: 16px; padding: 10px; width: 100%; max-width: 250px; }
.pen.fenced { background: var(--t); border-color: transparent; }
.pen .head { display: flex; align-items: center; gap: 7px; font-weight: 900; color: var(--ink); }
.pen .head .pips { margin-left: auto; color: var(--c); }
.pen .head .pips i { width: 8px; height: 8px; }
.pen .slots { display: flex; gap: 5px; flex-wrap: wrap; margin: 9px 0; }
.slot { width: 40px; height: 40px; border-radius: 10px; background: var(--card); border: 1.5px solid var(--line); display: grid; place-items: center; position: relative; }
.slot.empty { background: transparent; border: 1.5px dashed color-mix(in srgb, var(--c) 45%, transparent); }
/* Loss ghosts are a muted red: noticeable, but quieter than a live warning. */
.slot.lost { background: color-mix(in srgb, var(--loss) 6%, transparent); border: 1.5px dashed color-mix(in srgb, var(--loss) 55%, var(--surface)); }
.slot.lost svg { opacity: 0.35; }
/* Received: a green triangle in the slot's bottom-left corner; movable: a grey one bottom-right. Each runs from the
   corner to the middle of the two edges, so on one slot they meet at the bottom centre. Rings are reserved for selection. */
.slot.got::after { content: ""; position: absolute; bottom: -1.5px; left: -1.5px; width: calc(50% + 1.5px); height: calc(50% + 1.5px); border-bottom-left-radius: 10px;
  background: var(--grass); clip-path: polygon(0 0, 0 100%, 100% 100%); z-index: 2; }
.pens .slot.got::after { border-bottom-left-radius: 7px; }
/* A raised (movable) slot has a 4 px bottom edge: sit the triangles on it, flush with the slot's outer corner. */
.slot.movable.got::after { bottom: -4px; height: calc(50% + 4px); }
/* A Farm Dog in a pen: the same double rule as its card, so it stands out without dashes (dashes mean empty or lost). */
.slot.dog { border: 1.5px solid var(--line); background: var(--camo) bottom / auto 5px repeat-x, var(--card); }
/* The Barn is a slot of its own at the end of a fenced pen: something you attach, not a state. Set apart by a gap and a roof-shaped top. */
/* The space before the Barn sits on the slot before it, so a Barn that wraps to a new row still lines up with the slots above. */
.slots > :has(+ .barnslot) { margin-right: 6px; }
.slot.barnslot { border-radius: 14px 14px 6px 6px; border: 1.5px solid var(--line); background: var(--card); flex-direction: column; display: inline-flex; align-items: center; justify-content: center; gap: 0; }
.slot.barnslot.lost { background: color-mix(in srgb, var(--loss) 6%, transparent); border: 1.5px dashed color-mix(in srgb, var(--loss) 55%, var(--surface)); }
.slot.barnslot.lost svg, .slot.barnslot.lost b { opacity: 0.35; }
.slot.barnslot b { font-size: 0.58rem; font-weight: 900; color: var(--gold); line-height: 1; margin-top: -1px; }
.slot.barnslot.open { border: 1.5px dashed var(--line); background: transparent; }
.slot.barnslot.open svg { opacity: .28; filter: grayscale(1); }
/* Your turn: animals you may move look like raised tiles with a grip, the way draggable things look everywhere else. */
button.slot { font: inherit; padding: 0; cursor: pointer; color: inherit; }
/* While an animal is lifted: a dashed "New pen" tile at the end of your farm, when it may start one. */
button.pen.newpen { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; min-height: 96px;
  font: inherit; font-weight: 800; color: var(--grass); background: color-mix(in srgb, var(--grass) 6%, transparent);
  border: 2px dashed var(--grass); cursor: pointer; }
button.pen.newpen .slot.target { width: 32px; height: 32px; }
.slot.movable { border-bottom-width: 4px; border-color: color-mix(in srgb, var(--ink-soft) 45%, var(--line)); box-shadow: 0 3px 6px rgb(43 33 24 / .16); transform: translateY(-2px); cursor: grab; transition: transform .15s, box-shadow .15s; }
/* Move badge, bottom-right (the one corner no other marker uses): a bold double arrow, "move between pens". */
/* Movable: a small triangle in the bottom-right corner, the mirror of the received one (the raised edge says "tap me"). */
.slot.movable::before { content: ""; position: absolute; bottom: -4px; right: -1.5px; width: calc(50% + 1.5px); height: calc(50% + 4px); border-bottom-right-radius: 10px;
  background: var(--ink-soft); clip-path: polygon(100% 0, 100% 100%, 0 100%); z-index: 2; }
.pens .slot.movable::before { border-bottom-right-radius: 7px; }
@media (hover: hover) { .slot.movable:hover { transform: translateY(-4px); box-shadow: 0 6px 10px rgb(43 33 24 / .2); } }
/* With a mouse or trackpad, cards you can play lift a little on hover, and options brighten: a touch screen has no
   hover, so this only adds to what a tap already shows. */
@media (hover: hover) {
  button.card:not(:disabled):hover { transform: translateY(-4px); }
  .option:not(:disabled):hover { filter: brightness(1.04); }
}
.slot.lifted, .slot.lifted:hover { transform: translateY(-6px) scale(1.06); box-shadow: 0 0 0 3px var(--ink), 0 10px 16px rgb(0 0 0 / .2); z-index: 1; }
/* The "+" is drawn as two bars, not the text glyph, so it sits dead centre (a font's "+" rides on its baseline). */
.slot.target { border: 2px dashed var(--grass); color: transparent; font-size: 0; cursor: pointer;
  background: linear-gradient(var(--grass), var(--grass)) center / 42% 3px no-repeat, linear-gradient(var(--grass), var(--grass)) center / 3px 42% no-repeat,
    color-mix(in srgb, var(--grass) 12%, transparent); }
@media (prefers-reduced-motion: no-preference) { .slot.target { animation: beckon 1.2s ease-in-out infinite; } }
@keyframes beckon { 50% { transform: scale(1.08); } }
.ladder { display: flex; align-items: center; gap: 3px; font-size: 0.72rem; font-weight: 900; font-variant-numeric: tabular-nums; color: var(--ink-soft); }
.ladder span { padding: 1px 5px; border-radius: 6px; }
/* The current price is a solid gold coin-like tag: a fill, not an outline, so it reads as "current value" rather than "selected". */
.ladder span.now { background: var(--gold); color: var(--card); }
/* The step a preview moves the pen up to: ringed like the added pip (.pips i.new). */
/* The step the pen is at today, before the preview's added animal: solid gold, like the filled pips. */
.ladder span.was { background: color-mix(in srgb, var(--gold) 70%, var(--card)); color: var(--card); }
.ladder span.now.new { outline: 1.5px solid var(--gold); outline-offset: 1.5px; margin: 0 2px; }
/* The unit leads the ladder once, in coin gold, so the steps read as money without repeating B$ on each. */
.ladder span.unit { padding: 0 2px 0 0; color: var(--gold); font-size: 0.68rem; }
.badges { display: flex; gap: 6px; align-items: center; margin-left: auto; }
/* A status label, not a control: no outline (an outline reads as "selected"), just a soft fill of the badge colour. */
.badge { display: inline-flex; align-items: center; gap: 3px; font-size: 0.72rem; font-weight: 900; padding: 2px 8px 2px 4px; border-radius: 999px; background: color-mix(in srgb, currentColor 14%, var(--card)); }
.pen .foot { display: flex; align-items: center; gap: 6px; }

/* ---------- token rows (the taxonomy's pen groups) ---------- */
.formula { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-weight: 800; font-size: 0.86rem; }
.tok { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px 3px 4px; border-radius: 999px; background: var(--card); border: 1.5px solid var(--line); white-space: nowrap; }
.arrow { color: var(--ink-soft); font-weight: 900; }

@media (prefers-reduced-motion: no-preference) { .card { transition: transform .15s; } }

/* ---------- used by the game: tappable variants and live states ---------- */
/* A card or tile can be a button (the game's hand, rival tiles): strip button chrome, keep the face. */
button.card { padding: 0; min-height: 0; font: inherit; text-align: inherit; cursor: pointer; }
button.tile { display: block; padding: 0; min-height: 0; font: inherit; text-align: left; cursor: pointer; color: inherit; }
/* Held back while its deal or flight animation is still in the air. */
.card.dealing { visibility: hidden; }
.slot.held > svg { visibility: hidden; }
.stat .v { color: var(--ink); white-space: nowrap; }
/* Money is gold: the bank token's icon and amount, wherever it shows (status line, rival tiles). */
.stat.bank svg.ic, .stat.bank .v { color: var(--gold); }
.stat.over .v { color: var(--loss); }
.stat .lim { font-weight: 700; opacity: .7; }
.dot.off { background: var(--line); }
.tile.out { opacity: .5; }
/* A pen lost entirely (Land Grab, or its last animal taken): a ghost of the pen, like a ghost slot. */
.pen.ghost { background: transparent; border: 1.5px dashed color-mix(in srgb, var(--loss) 55%, var(--surface)); }
.pen .head .aside { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; font-size: .75rem; font-weight: 800; color: var(--loss); }

/* A farm of pens: two compact columns on a phone. Slots shrink so a Cattle pen (5) fits on one row where it can. */
.pens { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 158px), 1fr)); gap: 8px; }
.pens .pen { max-width: none; padding: 8px; }
.pens .slot { width: 27px; height: 27px; border-radius: 7px; }
.pens .slot svg.ic { width: 22px; height: 22px; }
.pens .pen .slots { gap: 4px; margin: 7px 0; }
.pens .pen .head { font-size: 0.86rem; gap: 5px; }
.pens .pen .head .pips i { width: 6px; height: 6px; }
.pens .pen .ladder { font-size: 0.66rem; gap: 1px; }
.pens .pen .badge span { display: none; }
.pens .pen .badge { padding: 2px; }

/* ---------- turn control (above the hand) ---------- */
.turnctl { display: inline-flex; align-items: center; justify-content: center; gap: 10px; flex: none; min-height: 44px; padding: 0 16px; border-radius: 999px; font-weight: 900; }
.turnctl .t-main { font-size: 1rem; font-weight: 900; white-space: nowrap; display: inline-flex; align-items: center; gap: 6px; }
.turnctl.mine { background: var(--barn); color: var(--on-color); }
/* Read-only: always as wide as its contents (dots, piece, name: names are at most 6 characters), never clipped. */
.turnctl.theirs { background: var(--surface-2); color: var(--ink-soft); flex: none; }
.turnctl.theirs .t-main { font-weight: 800; white-space: nowrap; }
/* Someone else's turn: their piece in the control's grey, so the control stays quiet. */
.ppiece.mute { background: none; padding: 0; }
/* The hourglass (ic("hourglass") inside .hourglass): sand runs from the top bulb to the bottom, then the glass turns
   over, again and again. Still, half-run, for anyone who prefers reduced motion. */
.hourglass .hg-top, .hourglass .hg-bot { fill: var(--gold); }
.hourglass .hg-stream { fill: none; stroke: var(--gold); stroke-width: 1.6; stroke-linecap: round; stroke-dasharray: 2 2.5; }
.hourglass .hg-glass { fill: color-mix(in srgb, var(--surface) 70%, transparent); }
/* The hourglass drawing is narrow inside its square, so pull its neighbours in: the gaps read even. */
.turnctl .hourglass { display: inline-grid; margin-inline: -4px; }
/* A greyed piece has no disc, so its drawing (heavier at the bottom: stems, leaves) is lifted to sit on the capitals. */
.turnctl .name-unit .ppiece.mute { top: -0.1em; }
.hourglass .hg-turn { transform-box: view-box; transform-origin: 24px 24px; animation: hg-turn 3.2s ease-in-out infinite; }
.hourglass .hg-top { transform-box: view-box; transform-origin: 24px 21.5px; animation: hg-top 3.2s linear infinite; }
.hourglass .hg-bot { transform-box: view-box; transform-origin: 24px 39px; animation: hg-bot 3.2s linear infinite; }
.hourglass .hg-stream { animation: hg-stream 3.2s linear infinite; }
@keyframes hg-top { 0% { transform: scale(1, 1); } 78%, 100% { transform: scale(0.15, 0); } }
@keyframes hg-bot { 0% { transform: scale(0.15, 0); } 78%, 100% { transform: scale(1, 1); } }
@keyframes hg-stream { 0% { stroke-dashoffset: 0; opacity: 1; } 76% { stroke-dashoffset: -18; opacity: 1; } 78%, 100% { opacity: 0; } }
@keyframes hg-turn { 0%, 80% { transform: rotate(0deg); } 100% { transform: rotate(180deg); } }
@media (prefers-reduced-motion: reduce) { .hourglass .hg-turn, .hourglass .hg-top, .hourglass .hg-bot, .hourglass .hg-stream { animation: none; } .hourglass .hg-top { transform: scale(0.6, 0.5); } .hourglass .hg-bot { transform: scale(0.6, 0.5); } }
.turnctl .hourglass { display: inline-flex; color: var(--ink-soft); }
/* A player's piece and name kept together inside a sentence (nameUnit in tiles.js). */
.name-unit { display: inline-flex; align-items: baseline; gap: 4px; white-space: nowrap; vertical-align: baseline; }
/* The piece sits on the line like a capital letter: its disc centred on the text, not on the line box. */
.name-unit .ppiece { align-self: center; position: relative; top: 0.08em; }
/* Inside a sentence the piece scales with the text: about a capital letter's height plus its disc, at any font size. */
.name-unit .ppiece { padding: 0.1em; }
.name-unit .ppiece svg { width: 1em; height: 1em; }
/* History turn headings: the piece, the words and the "now" pill sit on one line. */
.turn-title { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.turn-title .now { margin-left: 0; }
/* In the small History heading the piece is letter-sized, on a visible disc, and sits on the text's centre line. */
.turn-title .name-unit .ppiece { top: 0; background: var(--surface); }
.ppiece.mute svg { filter: grayscale(1); opacity: 0.6; }
.turnctl .pips { gap: 4px; }
.turnctl .pips i { width: 8px; height: 8px; }
/* Out of actions: nudge toward ending the turn. */
.turnctl.done { animation: nudge 1.6s ease-in-out infinite; }
@keyframes nudge { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--barn) 55%, transparent); } 50% { box-shadow: 0 0 0 6px transparent; } }
@media (prefers-reduced-motion: reduce) { .turnctl.done { animation: none; } }
@media (max-width: 360px) { .turnctl { gap: 6px; padding-left: 12px; padding-right: 12px; } .turnctl .t-main { font-size: 0.92rem; } }

/* ---------- card back: the face-down card (the deal animation, the draw pile) ----------
   Solid barn red with the app icon's barn in the card colour, so a face-down card reads as "Barnyard" at a glance.
   The barn is a mask, so it takes var(--card) and follows the theme. */
.card-back, .fx-deal-back { border-radius: 13px; background: var(--barn); border: 3px solid var(--card);
  box-shadow: inset 0 0 0 3px color-mix(in srgb, var(--card) 22%, transparent), 0 4px 10px rgb(0 0 0 / .3); backface-visibility: hidden; }
.card-back { position: relative; }
.card-back::after, .fx-deal-back::after { content: ""; position: absolute; inset: 22% 16%; background: var(--card);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 512 512%22%3E%3Cpath fill-rule=%22evenodd%22 d=%22M96 260 256 128l160 132v148H96Z M136 280 256 182l120 98v104H136Z%22/%3E%3Cpath d=%22M206 384V300h100v84M206 300l100 84M306 300l-100 84%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%2216%22 stroke-linejoin=%22round%22/%3E%3Cpath d=%22M60 408h392%22 stroke=%22%23000%22 stroke-width=%2224%22 stroke-linecap=%22round%22/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 512 512%22%3E%3Cpath fill-rule=%22evenodd%22 d=%22M96 260 256 128l160 132v148H96Z M136 280 256 182l120 98v104H136Z%22/%3E%3Cpath d=%22M206 384V300h100v84M206 300l100 84M306 300l-100 84%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%2216%22 stroke-linejoin=%22round%22/%3E%3Cpath d=%22M60 408h392%22 stroke=%22%23000%22 stroke-width=%2224%22 stroke-linecap=%22round%22/%3E%3C/svg%3E") center / contain no-repeat; }

/* A narrow tile (the game's rival strip, the phone mock): thinner goal segments so the status line stays on one row. */
.tile.narrow .status { gap: 8px; flex-wrap: nowrap; }
.tile.narrow .goalbar i { width: 4px; height: 9px; }
.tile.narrow .goalbar i:nth-child(3), .tile.narrow .goalbar i:nth-child(7) { margin-right: 1px; }
@media (max-width: 360px) { .turnctl .pips i { width: 6px; height: 6px; } .turnctl .pips { gap: 3px; } }

/* ---------- screens around the game: home, lobby, guide ---------- */
.brand { display: inline-flex; gap: 6px; justify-content: center; }
/* Home: a fan of real cards, the same faces as in your hand. */
.fan { position: relative; height: 140px; display: flex; justify-content: center; margin: 4px 0 6px; }
.fan-card { position: absolute; top: 8px; transform: translateX(calc(var(--i) * 64px)) rotate(calc(var(--i) * 9deg)) translateY(calc(var(--i) * var(--i) * 8px)); transform-origin: 50% 120%; }
.fan-card .card { box-shadow: var(--shadow); }
.fan-card .card-back { width: 92px; height: 122px; }
/* Four cards spread a little tighter than three, so the fan fits a 320 px screen. */
.fan:has(.fan-card:nth-child(4)) .fan-card { transform: translateX(calc(var(--i) * 54px)) rotate(calc(var(--i) * 8deg)) translateY(calc(var(--i) * var(--i) * 6px)); }
/* Lobby: the room code as letter tiles. */
.roomcode { display: flex; gap: 8px; justify-content: center; margin: 6px 0 4px; }
.roomcode span { width: 52px; height: 64px; display: grid; place-items: center; border-radius: 12px; background: var(--card);
  border: 1.5px solid var(--line); border-bottom: 5px solid var(--barn); box-shadow: var(--shadow); font-size: 2.1rem; font-weight: 900; color: var(--ink); }
/* ---------- the home page: header, barn-red hero, steps, features, questions ---------- */
/* Each full-width band holds a .site-wrap: the page column, with the side gutter clearing a phone's side bars. */
.site-wrap { max-width: 1120px; margin: 0 auto; padding-left: max(16px, env(safe-area-inset-left, 0px)); padding-right: max(16px, env(safe-area-inset-right, 0px)); }
.site-head { background: var(--surface); border-bottom: 1px solid var(--line); }
.site-head .site-wrap { padding-block: 10px; display: flex; align-items: center; gap: 16px; }
.site-nav { display: flex; align-items: center; gap: 20px; margin-left: auto; }
.site-nav button.nav-link { color: var(--ink); text-decoration: none; min-height: 44px; }
.site-nav button.nav-link:hover { color: var(--barn); }
@media (max-width: 759px) { .site-nav .wide-only { display: none; } .site-nav { gap: 12px; } }

/* The hero: a barn-red band. Light text, the last headline line in gold; the play panel and pills keep card colours. */
.home-hero { background: var(--barn-band); color: var(--band-ink); }
.home-hero .site-wrap { padding-block: 48px 56px; display: flex; flex-wrap: wrap; gap: 40px; align-items: center; }
.home-pitch { flex: 999 1 460px; min-width: 0; display: flex; flex-direction: column; gap: 18px; }
.home-eyebrow { align-self: flex-start; background: var(--surface); color: var(--grass); border-radius: 999px; padding: 5px 14px; font-weight: 800; font-size: 0.875rem; }
.home-hero h1 { font-size: clamp(2.2rem, 6vw, 3.5rem); font-weight: 900; line-height: 1.05; letter-spacing: -0.01em; text-wrap: balance; }
.home-hero h1 .accent { color: var(--band-accent); display: block; }
.home-lede { margin: 0; font-size: 1.2rem; color: var(--band-soft); max-width: 34em; }
.home-hero .fan { width: 340px; max-width: 100%; height: 190px; margin: 0; scale: 1.2; transform-origin: 12% top; }
.fact-pills { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0; padding: 0; }
.fact-pills li { background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: 999px; padding: 5px 13px; font-weight: 700; font-size: 0.875rem; }
.play-panel { flex: 1 1 340px; max-width: 400px; background: var(--surface); color: var(--ink); border-radius: 18px; box-shadow: var(--shadow), 0 12px 32px rgb(0 0 0 / .18); padding: 26px; display: flex; flex-direction: column; gap: 12px; }
.play-panel h2 { font-size: 1.5rem; font-weight: 900; }
.play-panel > p.soft { margin: 0; font-size: 0.95rem; color: var(--ink-soft); }
.play-panel label { font-size: 0.875rem; font-weight: 700; color: var(--ink-soft); }
.play-panel .field { position: relative; }
.play-panel .field input { padding-right: 52px; }
.play-panel .name-count { position: absolute; right: 14px; top: 50%; transform: translateY(-50%); font-size: 0.8rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.play-panel button.primary { min-height: 52px; font-size: 1.05rem; }
.play-panel .or { display: flex; align-items: center; gap: 12px; color: var(--ink-soft); font-size: 0.875rem; margin: 4px 0; }
.play-panel .or::before, .play-panel .or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.play-panel .joinrow { display: flex; gap: 8px; }
.play-panel .joinrow input { flex: 1; min-width: 0; }
.play-panel .hint { margin: 0; font-size: 0.8rem; color: var(--ink-soft); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
@media (max-width: 759px) {
  .home-hero .site-wrap { padding-block: 36px 32px; gap: 20px; }
  .home-pitch { text-align: center; align-items: center; }
  .home-eyebrow { align-self: center; }
  .fact-pills { justify-content: center; }
  .home-hero .fan { order: -1; width: 100%; height: 150px; scale: 1; }
  .home-lede { font-size: 1.05rem; }
  .play-panel { max-width: none; }
}

/* Sections below the hero. */
.home-section .site-wrap { padding-block: 64px 0; }
.home-section h2 { font-size: clamp(1.6rem, 4vw, 2.1rem); font-weight: 900; text-align: center; text-wrap: balance; }
.home-section .sub { text-align: center; color: var(--ink-soft); max-width: 34em; margin: 8px auto 0; font-size: 1.05rem; }
.steps, .features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; margin: 32px 0 0; padding: 0; list-style: none; }
.step { background: var(--surface); border-radius: 16px; box-shadow: var(--shadow); padding: 22px; display: flex; flex-direction: column; gap: 12px; }
.step-n { width: 44px; height: 52px; display: grid; place-items: center; border-radius: 10px; background: var(--card); border: 1.5px solid var(--line); border-bottom: 5px solid var(--barn); font-weight: 900; font-size: 1.5rem; color: var(--ink); }
.step h3, .feature h3 { font-size: 1.1rem; font-weight: 800; margin: 0 0 4px; text-transform: none; letter-spacing: 0; color: var(--ink); }
.step p, .feature p { margin: 0; color: var(--ink-soft); }
.feature { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 20px; display: flex; gap: 14px; align-items: flex-start; }
.feature > div { min-width: 0; }
.feature a, .faq a { color: var(--barn); font-weight: 700; }
@media (max-width: 859px) {
  .steps, .features { grid-template-columns: minmax(0, 1fr); gap: 12px; margin-top: 20px; }
  .step { flex-direction: row; align-items: flex-start; gap: 14px; padding: 16px; }
  .step-n { flex: none; width: 38px; height: 46px; font-size: 1.25rem; }
}
.learn-banner { background: var(--gold-soft); border-radius: 20px; padding: 28px 32px; display: flex; flex-wrap: wrap; align-items: center; gap: 20px; }
.learn-banner > div { flex: 999 1 380px; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.learn-banner h2 { text-align: left; font-size: 1.6rem; }
.learn-banner p { margin: 0; color: var(--ink-soft); font-size: 1.05rem; }
.learn-banner a.btn-outline { display: inline-flex; align-items: center; min-height: 48px; padding: 0 20px; border-radius: 12px; background: var(--surface); color: var(--ink); border: 1px solid var(--line); font-weight: 800; text-decoration: none; }
.faq { max-width: 720px; margin: 24px auto 0; display: flex; flex-direction: column; gap: 10px; }
.faq details { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 0 20px; }
.faq summary { font-weight: 800; font-size: 1.05rem; min-height: 56px; display: flex; align-items: center; justify-content: space-between; gap: 12px; cursor: pointer; list-style: none; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 1.4rem; color: var(--ink-soft); font-weight: 700; }
.faq details[open] summary::after { content: "\2013"; }
.faq details p { margin: 0; color: var(--ink-soft); padding-bottom: 16px; }
.home-closing .site-wrap { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.home-closing p { margin: 0; color: var(--ink-soft); font-size: 1.05rem; }
.home-closing button.primary { margin-top: 10px; min-height: 52px; font-size: 1.05rem; padding: 0 28px; }
/* Small room code (the menu sheet): the same tiles at half size. */
.roomcode.small { gap: 4px; margin: 0; justify-content: flex-start; }
.roomcode.small span { width: 26px; height: 32px; border-radius: 7px; border-bottom-width: 3px; box-shadow: none; font-size: 1.05rem; }
.player-line .pname { display: inline-flex; align-items: center; gap: 6px; min-width: 0; font-weight: 800; }
.player-line .host { display: inline-flex; }
.player-line .pill.you { margin-left: 2px; }
.pastgame { padding: 10px 0; border-bottom: 1px solid var(--line); display: grid; gap: 6px; }
.pastgame:last-child { border-bottom: 0; }
.pg-n { font-weight: 900; }
/* The winner: trophy before the name, name in gold. */
.pg-scores .stat.won .pn, .pg-scores .stat.won .v { color: var(--gold); font-weight: 900; }
/* The fence means fenced animals, the same green as a filled goal bar. */
.pg-scores .stat.won svg.ic { color: var(--grass); }
.pg-scores .stat:not(.won) .v { color: var(--ink-soft); }
.pg-scores { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.pg-scores .stat { font-size: .88rem; gap: 4px; }
.pg-scores .stat.out { opacity: .6; }
/* Guide */
.facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 10px 0; }
.facts div { background: var(--card); border: 1.5px solid var(--line); border-radius: 12px; padding: 10px; display: flex; flex-direction: column; }
.facts strong { font-size: 1.3rem; font-weight: 900; }
.facts span { font-size: .8rem; color: var(--ink-soft); }
.places { display: grid; gap: 8px; margin: 10px 0; }
.place { display: grid; grid-template-columns: auto 1fr; gap: 2px 12px; align-items: start; background: var(--card); border: 1.5px solid var(--line); border-radius: 12px; padding: 10px 12px; }
.place dt { display: contents; }
.place dt svg.ic { grid-row: span 2; color: var(--ink-soft); }
.place dt span { font-weight: 900; color: var(--ink); }
.place dd { margin: 0; color: var(--ink-soft); font-size: .92rem; }

/* ---------- controls: buttons and text inputs ----------
   Zero-specificity (:where) base styles, so every component class (.card, .slot, .tile...) overrides them. */
:where(button) { font: inherit; border: 0; border-radius: 12px; min-height: 48px; padding: 0 18px;
  background: var(--surface-2); color: var(--ink); cursor: pointer; font-weight: 700; }
:where(button).primary { background: var(--barn); color: var(--on-color); }
:where(button).ghost { background: transparent; border: 1px solid var(--line); }
:where(button).small { min-height: 36px; padding: 0 12px; font-size: 0.9rem; }
:where(button):disabled { opacity: 0.45; cursor: default; }
:where(button, input):focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
:where(button).full { width: 100%; }
:where(input) { font: inherit; width: 100%; min-height: 48px; padding: 0 14px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink); }
:where(input).code { text-transform: uppercase; letter-spacing: 0.3em; font-weight: 800; text-align: center; }
/* The card guide link in a card's sheet head: the book and "Card guide" in the --info slate, dotted underline, no chip.
   Visible if you look, but quieter than any play. min-height keeps a comfortable tap target without adding visual weight. */
button.guide-link { display: inline-flex; align-items: center; gap: 5px; margin-top: 4px; padding: 0; min-height: 36px; background: none; border: 0; color: var(--info); font-size: 0.82rem; font-weight: 800; cursor: pointer; }
button.guide-link span { text-decoration: underline dotted; text-underline-offset: 3px; }
/* Link button: text actions ("How to play"). Barn, the brand colour; never the loss red, which no button carries. button.link-btn so .small's side padding can't indent it off its text column. */
button.link-btn { background: none; border: 0; color: var(--barn); font-weight: 700; min-height: 40px; padding: 0; text-align: left; text-decoration: underline; cursor: pointer; }
/* Icon buttons (voice, menu) and buttons with a leading icon. A live icon (voice on) turns green. */
.icon-btn { display: inline-flex; align-items: center; justify-content: center; }
.with-ic { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.icon-btn.live svg.ic { color: var(--grass); }
/* Slots and cards that are buttons keep their own size. */
button.slot { min-height: 0; border-radius: 10px; }
.pens button.slot { border-radius: 7px; }
.pens button.slot.barnslot, button.slot.barnslot { border-radius: 14px 14px 6px 6px; }
/* A row in a list of players (lobby, voice). */
.player-line { display: flex; align-items: center; gap: 10px; min-height: 48px; border-bottom: 1px solid var(--line); }
.player-line:last-child { border-bottom: 0; }
.player-line .grow { flex: 1; min-width: 0; }

/* Timed button: the action that happens on its own when a response window closes. It fills from the left as the
   time runs out (0% to 100% in --fill), so the button itself is the timer. The fill is the text colour at low
   strength, so it reads on a primary (barn) button and on a default one alike. */
button.timed, .turnctl.timed { position: relative; overflow: hidden; isolation: isolate; }
button.timed::before, .turnctl.timed::before { content: ""; position: absolute; inset: 0 auto 0 0; width: var(--fill, 0%); z-index: -1;
  background: color-mix(in srgb, currentColor 18%, transparent); transition: width .2s linear; }

/* Toast: a short message above the hand. It inverts the theme (ink background, page-colour text), so it contrasts in light and dark. */
#toast {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(160px + env(safe-area-inset-bottom));
  background: var(--ink); color: var(--bg); padding: 10px 16px; border-radius: 12px; z-index: 20;
  max-width: calc(100% - 32px); font-weight: 600; box-shadow: var(--shadow);
}

/* ---------- status light: your own connection. It sits on your profile button (top right) and in your menu;
   each rival's dot sits at the start of their tile. Never shifts the layout. ---------- */
.light { flex: none; display: inline-grid; place-items: center; width: 22px; height: 22px; margin-left: 4px; }
.light.ok::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--grass); }
/* Amber: solid while paused (tappable), blinking while reconnecting or sending. */
.light.busy::before, .light.paused::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--gold); }
.light.busy::before { animation: blink 0.9s ease-in-out infinite; }
@keyframes blink { 50% { opacity: 0.15; } }
@media (prefers-reduced-motion: reduce) { .light.busy::before { animation: none; opacity: 0.6; } }
button.light.paused { min-height: 0; padding: 0; width: 28px; height: 28px; border-radius: 50%; background: transparent; }

/* Sheet close: an X in the sheet's top-right corner. The first block after it keeps clear of it. */
.sheet-x { position: absolute; top: 10px; right: 10px; width: 40px; padding: 0; border-radius: 50%; }
/* Timed close: the X's circle is a ring that fills clockwise (--fill, 0% to 100%) as a response window runs out. */
button.timer-x { border-color: transparent; }
button.timer-x::before { content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: conic-gradient(var(--barn) var(--fill, 0%), var(--line) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), var(--ink) calc(100% - 2.5px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 3px), var(--ink) calc(100% - 2.5px)); }
.sheet-x + * { padding-right: 44px; }

/* The Barnyard logo: the app icon's barn, in barn red on no background, top-left on every screen. */
.logo { position: relative; flex: none; display: inline-block; width: 32px; height: 32px; }
.logo svg { display: block; width: 100%; height: 100%; }
/* The logo with its wordmark (the lobby header). The bottom of the word and the bottom of the barn line up: flex
   puts the logo's box bottom on the text baseline, then the logo moves down by the empty band under the barn
   (3.75 of its 32 px) so the barn itself sits on the baseline. */
.lockup { display: inline-flex; align-items: baseline; gap: 8px; }
.lockup .logo { position: relative; top: 3.75px; }
.lockup .wordmark { font-weight: 900; font-size: 1.3rem; line-height: 1; letter-spacing: .01em; color: var(--barn); }

/* ---------- paying (approved 2026-11-02): one − / + row per bill value and per pen ---------- */
.stepper { display: flex; align-items: center; gap: 10px; padding: 6px 8px; margin-top: 6px; border-radius: 12px;
  border: 1.5px solid var(--line); background: var(--surface); }
.stepper .grow { flex: 1; min-width: 0; display: flex; align-items: center; gap: 4px 10px; flex-wrap: wrap; }
.stepper .pay-what { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.stepper .pay-what > .small { white-space: nowrap; }
/* The fenced section's Barn line: quiet until you pick from a pen with a Barn, then a warning in loss red. */
.pay-barn { color: inherit; }
.pay-barn.on { color: var(--loss); font-weight: 700; }
/* Fenced pens stay visible but locked until the bank and unfenced pens are used up. */
.stepper.locked .grow { opacity: .45; }
.stepper button { min-width: 44px; font-size: 1.2rem; }
/* Fenced pens sit behind a fence: a green-tinted pen with a picket top edge, so the rows read as usable but
   clearly the last resort. The fence green is the fenced-badge and goal-bar green. */
.pay-fenced { position: relative; margin-top: 14px; padding: 14px 10px 10px; border-radius: 12px;
  background: color-mix(in srgb, var(--grass) 9%, var(--surface)); border: 1.5px solid color-mix(in srgb, var(--grass) 35%, transparent); }
/* The picket edge: the fence icon's pickets (pointed tops) on a rail, repeated along the top. */
.pay-fenced::before { content: ""; position: absolute; left: 10px; right: 10px; top: -7px; height: 12px;
  background: color-mix(in srgb, var(--grass) 70%, var(--surface));
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 12'%3E%3Cpath d='M0 3.5 2 0.5 4 3.5V12H0Z'/%3E%3Cpath d='M0 7h11v1.6H0Z'/%3E%3C/svg%3E") 0 0 / 11px 12px repeat-x;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 12'%3E%3Cpath d='M0 3.5 2 0.5 4 3.5V12H0Z'/%3E%3Cpath d='M0 7h11v1.6H0Z'/%3E%3C/svg%3E") 0 0 / 11px 12px repeat-x; }
.pay-fenced-h { display: flex; align-items: flex-start; gap: 8px; margin: 0 0 4px; color: var(--grass); }
.pay-fenced-h > span { display: grid; gap: 2px; color: var(--ink); }
.pay-fenced .stepper { background: var(--surface); }
/* The gate: fenced rows stay behind it until everything above is used, then open on purpose. */
.pay-fenced .pay-gate { margin-top: 8px; display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; }
.pay-fenced .pay-gate .sub { flex-basis: 100%; }

.total { font-weight: 700; margin: 6px 0 10px; }
/* Selling the farm: what goes, listed read-only. */
.sell-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; margin-top: 6px; border-radius: 12px; border: 1.5px solid var(--line); background: var(--surface); }

/* ---------- History (approved 2026-11-02): one block per turn, newest first ---------- */
.turn-block { border-radius: 12px; background: var(--surface-2); padding: 10px 14px; margin-top: 10px; }
.turn-block.mine { background: var(--gold-soft); }
.turn-title { margin: 0 0 4px; font-size: 0.85rem; text-transform: none; letter-spacing: 0; color: var(--ink); }
.turn-title .now { font-size: 0.7rem; font-weight: 700; color: var(--on-color); background: var(--barn); border-radius: 999px; padding: 1px 8px; margin-left: 6px; vertical-align: middle; }
.turn-block ul { margin: 0; padding-left: 1.1em; }
/* History lines: a 28 px icon column (drawing, bank note, action icon), then the move. Ending a turn is quiet. */
.turn-block ul.hist { list-style: none; padding: 0; display: grid; gap: 6px; }
.hist li { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 8px; align-items: center; margin: 0; }
.hist li > span:last-child { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.hist .hi { display: grid; place-items: center; }
.hist .dotm { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-soft); }
.hist li.end { color: var(--ink-soft); font-size: .85rem; }
.turn-block li { margin: 4px 0; font-size: 0.92rem; }

/* Profile button: your initial in a circle, your connection light on its corner. It opens your menu. */
button.profile { position: relative; flex: none; width: 40px; height: 40px; min-height: 0; padding: 0; border-radius: 50%;
  background: var(--surface-2); border: 1.5px solid var(--line); color: var(--ink); font-weight: 900; font-size: 1rem; }
button.profile .light { position: absolute; right: -5px; bottom: -5px; margin: 0; }
/* With a piece, the button shows it on its soft disc instead of the initial. */
button.profile .ini.piece { display: grid; place-items: center; }
/* Your menu is titled with your piece and your name. */
.title-piece { display: inline-flex; align-items: center; gap: 8px; }
/* End of game: the winner's row is gold, with the trophy after the name. */
.player-line.won { background: var(--gold-soft); border-radius: 10px; padding-inline: 8px; margin-inline: -8px; border-bottom-color: transparent; }
.player-line.won .pname { color: var(--ink); }
.won-mark { display: inline-flex; }
/* The winner's fenced count and its fence icon are green: the goal they reached. */
.player-line.won .stat svg.ic, .player-line.won .stat .v { color: var(--grass); }
button.profile .light::before { box-shadow: 0 0 0 2.5px var(--bg); }
.menu-me { display: flex; align-items: center; gap: 8px; margin: -4px 0 8px; color: var(--ink-soft); font-size: .9rem; }
.menu-me .light { margin: 0; width: 12px; }

/* ---------- sheets and option rows (approved 2026-11-02): every prompt and menu opens in a sheet ---------- */
.scrim { position: fixed; inset: 0; background: var(--scrim); z-index: 10; display: flex; align-items: flex-end; justify-content: center; }
.sheet {
  position: relative; width: 100%; max-width: 560px; max-height: 85vh; overflow-y: auto; background: var(--surface);
  border-radius: 18px 18px 0 0; padding: 16px 16px max(16px, env(safe-area-inset-bottom));
}
.sheet .card-face { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 8px; }
.sheet .card-face > div { min-width: 0; }
.sheet-status { display: flex; gap: 12px; flex-wrap: wrap; margin: 6px 0; padding: 0; }
.option { display: block; width: 100%; text-align: left; margin-top: 8px; padding: 10px 14px; line-height: 1.3; }
/* An option that names a pen shows its summary chip: "Add to (Pigs ●●○○)". */
.option .opt-pen { display: inline-flex; vertical-align: middle; margin-left: 4px; }
/* A row that names a pen: its label on the left, the stacked pen chip beside it, never wrapped under. */
.option:has(> .opt-pen) { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.option:has(> .opt-pen) .opt-pen { margin-left: 0; }
.option .sub { display: block; font-weight: 400; font-size: 0.85rem; color: var(--ink-soft); }
/* A warning option (Forfeit): red text on a faint red, never the primary fill. */
/* A destructive action that isn't a sheet row (the lobby's Close the room): loss-red words on a quiet button. */
.option + .option { margin-top: 10px; }
/* The sheet title gets room to breathe before the text, which may carry inline cards and chips (Locked Gate). */
.sheet h2 { margin: 0 0 12px; line-height: 1.3; }
.sheet h2 + p { line-height: 1.6; }
/* A pen choice's chip carries the pen's price ladder after a divider, so pen and B$ read as one unit. */
.pchip .pch-ladder { display: inline-flex; margin-left: 4px; padding-left: 7px; border-left: 1.5px solid color-mix(in srgb, var(--ink-soft) 35%, transparent); }
/* Stacked, like a pen tile: the pen on top, its price ladder underneath, as one small card. */
.pchip.stack { flex-wrap: wrap; border-radius: 9px; padding: 4px 8px; row-gap: 4px; }
.pchip.stack .pch-ladder { flex-basis: 100%; margin: 0; padding: 4px 0 0; border-left: 0; border-top: 1.5px solid color-mix(in srgb, var(--ink-soft) 35%, transparent); }
.pchip .pch-ladder .ladder { gap: 5px; font-size: .78rem; }
.option.primary .sub { color: inherit; opacity: 0.85; }
.option.with-ic { display: flex; justify-content: flex-start; flex-wrap: wrap; }
.option.with-ic .sub { flex-basis: 100%; }
.option svg.ic { display: inline-block; vertical-align: middle; margin-right: 6px; }
.option .inline-ic svg.ic { margin-right: 4px; }
.win { text-align: center; }
.player-line .grow { flex: 1; min-width: 0; }
/* After the standings: the rematch (host) or the wait (everyone else), then the ways out. */
.win-next { margin-top: 14px; }
.win-next > p { text-align: center; margin: 0; }
.win .trophy { display: flex; justify-content: center; margin-bottom: 4px; }
.vmark { display: inline-flex; vertical-align: middle; border-radius: 999px; padding: 1px; transition: box-shadow 0.12s; }
.topbar .inline-ic { margin-right: 2px; }
.option .sub svg.ic { margin-right: 1px; }
.scrim h2 .inline-ic svg.ic { margin: 0 2px; }

/* Your bank total, above the hand: a tappable rounded rectangle that opens the bank (pills are labels, not buttons).
   Its gold outline matches the Bank it and Cash in rows (.option.fallback), so everything that is your bank looks alike. */
button.bank-total { position: relative; overflow: hidden; min-height: 34px; padding: 0 8px 0 6px; border-radius: 9px; background: var(--surface); border: 2px solid var(--gold); font-weight: 900; }
/* Your goal count, above the hand: a button like the bank, outlined in the goal's green; it opens the pens it counts. */
button.goal-total { min-height: 34px; padding: 0 7px 0 5px; border-radius: 9px; background: var(--surface); border: 2px solid var(--grass); font-weight: 900; }
.title-goal { display: flex; align-items: center; gap: 8px; }
.title-goal svg.ic { color: var(--grass); --t: var(--grass); }
/* Money came in (green) or went out (red) since your last turn: the same corner triangle as a pen slot, bottom-left.
   Both in one turn: the triangle splits along its middle, red on the left edge and green on the bottom. */
.bank-total.gain::after, .bank-total.loss::after { content: ""; position: absolute; bottom: 0; left: 0; width: 17px; height: 17px;
  border-bottom-left-radius: 7px; clip-path: polygon(0 0, 0 100%, 100% 100%); background: var(--grass); } /* 7px: the inside of the 9px corner, past the 2px gold border */
.bank-total.loss::after { background: var(--loss); }
.bank-total.gain.loss::after { background: conic-gradient(from 0deg at 0 100%, var(--loss) 0 45deg, var(--grass) 45deg 90deg, transparent 90deg); }

/* Text helpers used inside sheets, and the Locked Gate card drawn inline in a sentence. */
.muted { color: var(--ink-soft); }
.empty { color: var(--ink-soft); font-size: 0.9rem; padding: 6px 0; }
.gate-chip { display: inline-flex; align-items: center; gap: 4px; vertical-align: middle; padding: 1px 8px 1px 4px; border: 1.5px solid var(--line); border-top: 4px solid var(--c); border-radius: 7px;
  background: var(--card); color: var(--ink); font-weight: 800; white-space: nowrap; }
.gate-chip.edge-bottom { border-top: 1.5px solid var(--line); border-bottom: 4px solid var(--c); }
/* An animal chip's drawing sits on its card's glow (same tokens and measured hues as .cardA .art::before). */
.gate-chip .cc-art { position: relative; display: inline-grid; place-items: center; }
.gate-chip .cc-art > * { position: relative; z-index: 1; }
.gate-chip .cc-art::before { content: ""; position: absolute; width: 30px; height: 30px; border-radius: 50%; z-index: 0;
  --glow: var(--glow-d, color-mix(in srgb, var(--hue-glow, var(--glow-mid)) var(--pale-on), var(--hue-glow-d, var(--glow-mid))));
  background: radial-gradient(circle closest-side, var(--glow) 0%, var(--glow) 45%, color-mix(in srgb, var(--glow) 55%, transparent) 70%, transparent 100%); }
.gate-chip.drawing-dark .cc-art::before { --glow-d: var(--glow-dark); }

/* Discarding: what the last tapped card does, below the hand (the turn control is the Discard button).
   A fixed height, with the description clamped to two lines, so the hand doesn't jump from card to card. */
/* The middle row fits the tallest line: an animal's pen preview over its worth (text cards get two lines). */
.discard-peek { display: grid; grid-template-rows: auto 4.9rem auto; align-content: start; gap: 2px; padding: 0 12px 6px 4px; overflow: hidden; }
.discard-peek > span { font-size: 0.9rem; color: var(--ink-soft); line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* An animal's line: the pen it fits (or would start) as the card sheet previews it, then what it's worth. */
.discard-peek > span:has(.dt-pen) { display: grid; gap: 3px; align-content: start; overflow: visible; }
.dt-pen { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.dt-label { white-space: nowrap; }
.dt-worth { display: block; }
.gold-money { color: var(--gold); font-weight: 900; }
.discard-peek em { font-style: normal; font-size: 0.82rem; font-weight: 700; color: var(--ink-soft); }
.sell-btn { margin-top: 14px; }

/* ---------- site footer (home, lobby, legal pages) and the legal pages ---------- */
/* Quiet and last on the page: small soft text, links in ink, never competing with the game's buttons. */
.site-footer { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; margin: 28px 0 8px; padding-top: 14px;
  border-top: 1px solid var(--line); font-size: .8rem; color: var(--ink-soft); }
.site-footer a { color: var(--ink-soft); text-decoration: underline; text-underline-offset: 2px; }
/* The legal pages: the game's page width and side gutters, safe areas included. */
.legal { max-width: 640px; margin: 0 auto; line-height: 1.6;
  padding: max(12px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(24px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }
.legal h1 { margin: 6px 0 2px; }
.legal p a, .legal li a { color: var(--barn); font-weight: 700; }
.legal h2 { font-size: 1.05rem; margin: 22px 0 6px; }
.legal ul { padding-left: 20px; display: grid; gap: 6px; }
.legal .legal-home { display: inline-flex; text-decoration: none; }

/* ---------- lobby (lobbyScreen in screens.js) ---------- */
/* The invite, the players and one main action. Everything rarer is in the profile menu. */
.lobby-invite { display: grid; justify-items: center; gap: 6px; text-align: center; padding: 20px 0 16px; }
.lobby-invite p { margin: 0; }
.lobby-invite .roomcode { margin: 2px 0 4px; }
.lobby-start { display: grid; gap: 6px; margin-top: 16px; text-align: center; }
.lobby-start p { margin: 0; }
.lobby-note { text-align: center; margin-top: 10px; }
/* ---------- invite (inviteScreen in screens.js): where a /<CODE> link lands, laid out like the lobby ---------- */
.topbar .home-link { display: inline-flex; text-decoration: none; color: inherit; }
.invite { display: flex; flex-direction: column; gap: 12px; padding: 20px 0 8px; }
.invite > .invite-eyebrow { align-self: center; background: var(--surface-2); color: var(--grass); border-radius: 999px; padding: 5px 14px; font-weight: 800; font-size: 0.875rem; }
.invite h1 { margin: 0; text-align: center; font-size: clamp(1.6rem, 6vw, 2.1rem); font-weight: 900; line-height: 1.1; text-wrap: balance; }
.invite-code .roomcode { margin: 0; }
.invite-text { margin: 0 auto; max-width: 30em; text-align: center; color: var(--ink-soft); }
.invite .panel h2 { margin: 0 0 6px; font-size: 1.05rem; }
.invite-join { display: flex; flex-direction: column; gap: 10px; margin-top: 4px; }
.invite-join label { font-size: 0.875rem; font-weight: 700; color: var(--ink-soft); }
.invite-join .field { position: relative; }
.invite-join .field input { padding-right: 52px; }
.invite-join .name-count { position: absolute; right: 14px; top: 50%; transform: translateY(-50%); font-size: 0.8rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.invite-join button.primary { min-height: 52px; font-size: 1.05rem; }
.invite-join .joinrow { display: flex; gap: 8px; }
.invite-join .joinrow input { flex: 1; min-width: 0; }
.invite-own { margin: 4px 0 0; text-align: center; font-size: 0.95rem; }
.invite-own a { color: var(--barn); font-weight: 800; }
/* The ways out of a room (exitActions in sheets.js): a full secondary button, then a plain link, centred. */
.exit-actions { display: grid; justify-items: center; gap: 6px; margin-top: 12px; }
.exit-actions .ghost.full { justify-self: stretch; }
/* A label above an input inside a sheet (Close the room's code box). */
.field-label { display: block; margin: 12px 0 6px; font-size: 0.85rem; color: var(--ink-soft); font-weight: 700; }
.sheet input.code { width: 100%; margin-bottom: 10px; }
/* A player's piece (playerPiece in tiles.js): their crop on the soft fill, like a pen portrait, so it reads as a
   playing piece rather than a sticker. */
.ppiece { display: inline-grid; place-items: center; flex: none; border-radius: 50%; padding: 4px; background: var(--surface-2); }
.ppiece svg { display: block; }
.tile.out .ppiece { opacity: 0.5; }
/* The lobby's piece picker (piecePicker in screens.js). */
.piece-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); gap: 8px; margin-top: 8px; }
.piece-pick { display: grid; place-items: center; min-height: 52px; padding: 6px; border-radius: 50%; aspect-ratio: 1; background: var(--surface-2); border: 2px solid transparent; }
.piece-pick.mine { border-color: var(--barn); }
.piece-pick:disabled { opacity: 0.3; }
/* In the lobby the picker sits in your own row, as a strip under your name that scrolls sideways. */
.piece-strip { display: flex; gap: 8px; overflow-x: auto; padding: 0 2px 10px 18px; scrollbar-width: none; }
.piece-strip .piece-pick { flex: none; width: 46px; min-height: 46px; }
.my-row { border-bottom: 1px solid var(--line); min-width: 0; }
.my-row .player-line { border-bottom: 0; }
/* A row into optional reference (optionRows' o.info: How to play): slate book and label, sub-line in soft ink. */
.option.info svg.ic, .option.info > span { color: var(--info); }
.option.info .sub { color: var(--ink-soft); }
/* A reason a card can't be played (optionRows' o.reason): a note, not a button. Slate edge and "i" (--info), words in ink. */
.opt-reason { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: 4px 12px 12px 4px; background: var(--surface); border-left: 4px solid var(--info); color: var(--ink); }
.opt-reason svg.ic { flex: none; color: var(--info); }
.opt-reason div { display: grid; gap: 2px; min-width: 0; }
.opt-reason .sub { color: var(--ink-soft); font-size: 0.9rem; }
/* A disabled button that says why: its label, then the reason as a smaller second line inside it. */
button.with-why { padding-block: 6px; line-height: 1.25; }
button.with-why .why { display: block; font-size: 0.8rem; font-weight: 600; }

/* ---------- the physical deck (public/ui/print.js): poker size, 63 x 88 mm ----------
   A printed card is the game's own card face (.card.cardA) at poker proportions: 92 x 128.5 card units, so 1 mm is
   92/63 units (--u). Everything the game's card has keeps its place and size; the extras (an animal's price ladder,
   rules text) sit under the name. `zoom: var(--pz)` scales the whole card for the page; set --pz on a container.
   Colours are the game's tokens, so .tone-light and .tone-dark give both editions. */
.card.pcard { --u: calc(92px / 63); zoom: var(--pz, 1.7); width: 92px; height: 128.5px; display: flex; flex-direction: column; align-items: center;
  padding: 28px 6px 7px; box-sizing: border-box; isolation: isolate; overflow: hidden; line-height: 1.2; text-align: left; }
.card.pcard .art { position: relative; inset: auto; width: 100%; height: 50px; flex: none; }
.card.pcard .nm { position: relative; inset: auto; margin-top: 4px; width: 100%; }
.card.pcard .pextra { margin-top: auto; width: 100%; display: grid; justify-items: center; }
.card.pcard .ptext { margin: 0; font-size: 4.3px; line-height: 1.3; font-weight: 700; text-align: center; color: var(--ink); text-wrap: pretty; }
.card.pcard .ptext b { font-weight: 900; }
/* Gold amounts in printed-card words, which the card sheet and discard strip reuse. */
.pgold { color: var(--gold); font-weight: 900; }
/* The printed card's extras join the layer above the glow (see .cardA > :not(.art)). */
.card.pcard > .pextra { position: relative; }
/* Animals: the game's face with the pen's value table along the bottom: the pen's portrait, then one step per fill level.
   No corner index: the portrait names the pen and the steps give the size. */
/* On animal, action and Farm Dog cards the name is the corner index, top-left like a playing card's (so an animal's shows in a
   pen column); the drawing takes the room the name left. */
.card.pcard.fam-animal { padding-top: 36.4px; padding-bottom: 8px; }
.card.pcard.fam-animal .nm, .card.pcard.fam-action .nm, .card.pcard.fam-wild .nm { position: absolute; top: 6px; left: 7px; height: 22px; width: auto;
  max-width: 44px; margin: 0; display: flex; align-items: center; text-align: left; font-size: 9px; line-height: 1.05; }
/* The drawing (85% of the screen card's) sits so the top of its glow meets the bottom of the value coin: the coin ends
   6 + 3.5 + 15 = 24.5 units down, and the glow is centred on the drawing box, so the box starts
   24.5 + (glow - box) / 2 = 36.4 units down on every card. */
/* The header band: title and value coin are both centred in the same 22-unit band across the top, so a one-line and a
   two-line title share the coin's middle line. The coin is smaller than the game's (15 units, about 10 mm). */
.card.pcard .val { top: 6px; right: 6px; height: 22px; display: flex; align-items: center; }
.card.pcard .coin { height: 15px; min-width: 25px; padding: 0 3.5px; font-size: 8.5px; border-width: 1.2px; }
.card.pcard .coin small { font-size: 5.6px; }
.card.pcard.fam-animal .art { height: 51px; }
.card.pcard.fam-animal .art svg { width: 49.3px; height: 49.3px; }
.cardA.pcard.fam-animal .art::before { width: 74.8px; height: 74.8px; }
.pvalues { display: flex; align-items: center; justify-content: center; gap: 3px; }
.ppen-name { display: flex; align-items: center; gap: 2.4px; color: var(--c); }
.ppen-name svg { width: 13px; height: 13px; }
.pstrip { display: flex; justify-content: center; align-items: end; gap: 1.6px; }
.pstep { display: grid; justify-items: center; gap: 1.6px; }
/* Every price sits in the same box as the fenced one's pill, so all the steps line up. */
.pstep b { display: inline-flex; align-items: center; height: 7.4px; box-sizing: border-box; padding: 0 .3px; border-radius: 2.4px;
  font-size: 6.2px; font-weight: 900; color: var(--gold); font-variant-numeric: tabular-nums; line-height: 1; white-space: nowrap; }
.pstep b small { font-size: 4.2px; margin-right: .3px; }
/* The fenced step: green, the game's Fenced colour, on the cards of its fan and its price. */
.pstep b.pfenced { color: var(--grass); }
.pstep.full .pfan i { border-color: var(--grass); color: var(--grass); background: color-mix(in srgb, var(--grass) 14%, var(--card)); }
.pstep.full .pfan i:last-child { background: var(--card); }
/* A fan of n small cards, the front one numbered: "n animals". */
.pfan { position: relative; flex: none; display: inline-block; height: 7px; width: calc(5px + (var(--n) - 1) * 1.3px); }
.pfan i { position: absolute; bottom: 0; left: calc(var(--x) * 1.3px); width: 5px; height: 7px; box-sizing: border-box; border-radius: 1px;
  background: color-mix(in srgb, var(--t) 70%, var(--card)); border: .5px solid var(--c); transform: rotate(calc(var(--k) * 5deg)); transform-origin: 50% 100%;
  display: grid; place-items: center; font-style: normal; font-weight: 900; font-size: 4.4px; line-height: 1; color: var(--c); }
.pfan i:last-child { background: var(--card); }
/* Action cards and the Farm Dog: the drawing under the corner, then the rules text centred in the space between the
   drawing and the bottom edge. */
.card.pcard.fam-action, .card.pcard.fam-wild { padding-top: 36.4px; }
.card.pcard.fam-action .art, .card.pcard.fam-wild .art { height: 47.6px; }
.card.pcard.fam-action .art svg, .card.pcard.fam-wild .art svg { width: 45.9px; height: 45.9px; }
.cardA.pcard.fam-action .art::before, .cardA.pcard.fam-wild .art::before { width: 71.4px; height: 71.4px; }
.card.pcard.fam-action .pextra, .card.pcard.fam-wild .pextra { flex: 1; margin: 0; display: grid; align-content: center; gap: 3px; }
/* Market Day's pens, above its rules text. */
.card.pcard .ppens .spicons { gap: 2px !important; }
.card.pcard .ppens .cat { color: var(--c); }
/* The back: the game's face-down card. */
.card.card-back.pcard { padding: 0; border-radius: 13px; }
/* Player aids and the deck list: a game card's frame, laid out as a reference card. */
.card.pcard.paid { display: grid; align-content: start; gap: calc(1.6 * var(--u)); padding: calc(3.6 * var(--u)); font-size: calc(2.6 * var(--u)); text-align: left; }
.card.pcard.paid p { margin: 0; font-weight: 700; line-height: 1.3; }
.card.pcard.paid h4 { margin: calc(1 * var(--u)) 0 0; font-size: calc(3.2 * var(--u)); font-weight: 900; text-transform: uppercase; letter-spacing: .06em; color: var(--barn); display: flex; align-items: center; gap: calc(1 * var(--u)); }
.card.pcard.paid h4 svg { width: calc(4 * var(--u)); height: calc(4 * var(--u)); }
.card.pcard.paid ol { margin: 0; padding-left: calc(4 * var(--u)); display: grid; gap: calc(.8 * var(--u)); font-weight: 700; line-height: 1.28; }
.pcard .paid-head { display: grid; grid-template-columns: repeat(3, 1fr); gap: calc(1.2 * var(--u)); }
.pcard .paid-head span { display: grid; justify-items: center; padding: calc(.9 * var(--u)) 0; border-radius: calc(2 * var(--u)); background: var(--barn); color: var(--on-color);
  font-size: calc(2.8 * var(--u)); font-weight: 900; text-transform: uppercase; letter-spacing: .08em; }
.pcard .paid-head b { font-size: calc(5.6 * var(--u)); line-height: 1; }
.pcard .paid-sub { color: var(--ink-soft); font-size: calc(2.4 * var(--u)); }
.pcard .paid-goal { display: grid; gap: calc(.6 * var(--u)); padding: calc(2 * var(--u)); border-radius: calc(2 * var(--u)); background: var(--surface); border: calc(.35 * var(--u)) solid var(--line); font-weight: 800; }
.pcard .paid-goal .paid-sub { font-weight: 700; }
.pcard .paid-goal span:first-child { display: flex; align-items: center; gap: calc(1 * var(--u)); font-weight: 900; color: var(--grass); }
.pcard .paid-goal svg { width: calc(4.5 * var(--u)); height: calc(4.5 * var(--u)); }
.pcard .paid-goal b { font-size: calc(4 * var(--u)); color: var(--ink); margin-right: calc(.8 * var(--u)); }
.pcard .paid-rule { padding: calc(1.8 * var(--u)); border-radius: calc(2 * var(--u)); border-left: calc(1 * var(--u)) solid var(--grass); background: var(--surface); font-weight: 700; line-height: 1.28; }
.pcard .paid-pens { display: grid; grid-template-columns: repeat(7, 1fr); gap: calc(.4 * var(--u)); }
.pcard .paid-pens span { display: grid; justify-items: center; gap: calc(.2 * var(--u)); color: var(--c); }
.pcard .paid-pens svg { width: calc(6 * var(--u)); height: calc(6 * var(--u)); }
.pcard .paid-pens b { color: var(--ink); font-size: calc(3.2 * var(--u)); line-height: 1; }
.pcard .paid-pens small { color: var(--gold); font-weight: 900; font-size: calc(2.1 * var(--u)); }
.pcard .paid-key { margin-top: calc(-1 * var(--u)) !important; font-size: calc(2.1 * var(--u)); color: var(--ink-soft); text-align: center; }
.pcard .plist { border-collapse: collapse; width: 100%; font-size: calc(2.05 * var(--u)); line-height: 1.15; font-weight: 800; }
.pcard .plist td { padding: 0; border-bottom: calc(.25 * var(--u)) solid var(--line); }
.pcard .plist td:first-child { display: flex; align-items: center; gap: calc(1 * var(--u)); }
.pcard .plist td:first-child svg { width: calc(3 * var(--u)); height: calc(3 * var(--u)); color: var(--c); flex: none; }
.pcard .plist td:last-child { text-align: right; font-variant-numeric: tabular-nums; }
/* The deck list's back: the QR code to the full rules. Everything is centred on the card and fills it: the code is
   48 mm wide, nearly the safe area's width, so a phone reads it from arm's length. */
.card.pcard.prules { align-content: center; justify-items: center; gap: calc(3 * var(--u)); }
.card.pcard.prules h4 { margin: 0; justify-content: center; font-size: calc(4.2 * var(--u)); }
.pcard .pqr { display: grid; justify-items: center; }
.pcard .pqr svg { width: calc(48 * var(--u)); height: calc(48 * var(--u)); border-radius: calc(1.5 * var(--u)); }
.pcard .pqr-sub { text-align: center; font-weight: 800 !important; }
.pcard .pqr-url { text-align: center; font-weight: 900 !important; color: var(--barn); font-size: calc(2.9 * var(--u)); letter-spacing: .01em; }
/* On the table, in card units (the container zooms; the cards inside don't zoom again). A pen is a column of cards,
   each covering all but the top 32 units (22 mm: the animal's name and the value coin) of the one before. Fenced pens turn sideways. */
.ppen, .pbank, .pguides { zoom: var(--pz, 1); }
.ppen .card.pcard, .pbank .card.pcard, .pguides .card.pcard { zoom: 1; }
.ppen { --h: calc(128.5px + (var(--n) - 1) * 32px); position: relative; flex: none; width: 92px; height: var(--h); }
.ppen-stack { position: absolute; left: 0; top: 0; width: 92px; height: var(--h); }
.ppen-card { position: absolute; left: 0; top: calc(var(--i) * 32px); }
.ppen.fenced { width: var(--h); height: 92px; }
.ppen.fenced .ppen-stack { transform-origin: 0 0; transform: translateX(var(--h)) rotate(90deg); }
/* A bank: cards turned sideways (top to the left), overlapping so each value shows. */
.pbank { position: relative; flex: none; height: 92px; width: calc(128.5px + (var(--n) - 1) * 70px); }
.pbank-card { position: absolute; top: 0; left: calc(var(--i) * 70px); width: 128.5px; height: 92px; }
.pbank-card > .card { transform-origin: 0 0; transform: translateY(92px) rotate(-90deg); }
/* Print guides: bleed (3 mm beyond the trim), the trim line and the safe zone (3 mm inside it). */
.pguides { --u: calc(92px / 63); position: relative; flex: none; padding: calc(3 * var(--u)); border-radius: 2px;
  background: repeating-linear-gradient(45deg, color-mix(in srgb, var(--loss) 22%, transparent) 0 calc(1 * var(--u)), transparent calc(1 * var(--u)) calc(2.4 * var(--u))); }
.pguides .card.pcard { border-radius: 0; box-shadow: none; }
.pguides .pg-trim, .pguides .pg-safe { position: absolute; pointer-events: none; }
.pguides .pg-trim { inset: calc(3 * var(--u)); border: 1px solid var(--loss); border-radius: calc(3.2 * var(--u)); }
.pguides .pg-safe { inset: calc(6 * var(--u)); border: 1px dashed var(--event); border-radius: calc(1.5 * var(--u)); }

/* ---------- the draw pile (drawPile in tiles.js), at the start of your hand ---------- */
/* The first thing in the hand's row, then a divider, then your cards. The whole row scrolls together, so on a phone
   the pile gives its space back to your cards as you scroll along. */
/* The pile's front card is exactly a card in your hand (92 x 122, same top), so the two read as one row. The cards
   behind it fan out 3 px to the right each. */
.dpile { position: relative; flex: none; width: 98px; height: 122px; padding: 0; border: 0; background: none; font: inherit; color: inherit; overflow: hidden; }
button.dpile { cursor: pointer; }
.dpile .card-back { position: absolute; top: 0; width: 92px; height: 122px; box-sizing: border-box; }
.dpile .dp-c3 { left: 6px; } .dpile .dp-c2 { left: 3px; } .dpile .dp-c1 { left: 0; }
.dpile .dp-c2, .dpile .dp-c3 { box-shadow: none; }
/* The divider: as tall as a card, the same 8 px from the pile as from your first card. */
.dp-sep { flex: none; width: 1.5px; height: 122px; margin: 0 -2px 0 2px; border-radius: 1px; background: var(--line); } /* 8 px from the pile and from your first card: the hand's 8 px gap, less half the line */
/* The game's "can't play now": half strength, faded as one stack so the cards beneath don't show through. */
.dp-stack { position: absolute; inset: 0; }
.dpile.idle .dp-stack { opacity: .5; }
.dpile .dp-hole { position: absolute; left: 0; top: 0; width: 92px; height: 122px; box-sizing: border-box; border-radius: 13px; border: 2px dashed color-mix(in srgb, var(--ink-soft) 50%, transparent); }
.dp-count { position: absolute; top: 12px; left: 46px; transform: translateX(-50%); display: inline-flex; align-items: center; gap: 3px; padding: 1px 7px 1px 5px; border-radius: 999px;
  background: var(--card); color: var(--ink); font-size: .74rem; font-weight: 900; box-shadow: var(--shadow); white-space: nowrap; }
.dpile.empty .dp-count { color: var(--ink-soft); } /* the count keeps its spot at the top, empty or not */
/* Its name along the bottom, in the card colour like the back's barn. */
.dp-name { position: absolute; left: 0; width: 92px; bottom: 11px; color: var(--card); font-size: .74rem; font-weight: 900; text-align: center; white-space: nowrap; letter-spacing: .01em; }
.dpile.empty .dp-name { color: var(--ink-soft); }

/* Market Day also carries its row of pen icons: a drawing 3% smaller keeps four lines of text on the card. */
.card.pcard.fam-action:has(.ppens) .art { height: 46px; }
.card.pcard.fam-action:has(.ppens) .art svg { width: 44.4px; height: 44.4px; }

/* A card sheet's actions sit in a tray under the card's information (approved 2026-11-04). The tray runs to the
   sheet's sides and bottom edge and scrolls with the sheet. Default rows take the sheet's surface so they stand out
   from the tray. */
.sheet .opt-tray { margin: 12px -16px calc(-1 * max(16px, env(safe-area-inset-bottom))); padding: 14px 16px max(16px, env(safe-area-inset-bottom));
  background: var(--surface-2); border-top: 1px solid var(--line); }
.sheet .opt-tray > h2 { margin-top: 0; }
.sheet .opt-tray > .option:first-child { margin-top: 0; }
.sheet .opt-tray .option:not(.primary):not([disabled]) { background: var(--surface); }
/* The Discard button: its dots are the progress, so they stay at full strength; only the word waits at half until
   every card is marked. */
.turnctl.discard-btn:disabled { opacity: 1; }
.turnctl.discard-btn:not(.ready) .t-main { opacity: 0.55; }

/* A pen's category inside a sentence (an animal's card sheet): its mark and name in the pen's colour. */
.inline-cat { display: inline-flex; align-items: center; gap: 3px; vertical-align: -3px; white-space: nowrap; }
.inline-cat svg.ic { display: inline-block; }
.inline-cat b { color: var(--ink); font-weight: 800; }

/* The fallback row (an action card's Cash in): under an "or" rule, the bank icon in a gold outline, never primary. */
.opt-or { display: flex; align-items: center; gap: 10px; margin: 12px 0 2px; font-size: 0.78rem; font-weight: 800; color: var(--ink-soft); }
.opt-or::before, .opt-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.option.with-lead { display: flex; align-items: center; gap: 12px; }
.option.with-lead svg.ic { margin: 0; flex: none; }
.option.fallback { background: var(--surface); border: 2px solid var(--gold); }
.sheet .opt-tray .option.fallback { background: var(--surface); }
.option.fallback svg.ic { color: var(--gold); margin: 0; flex: none; }
.opt-or + .option.fallback { margin-top: 8px; }

/* Tiles: Market Day's pens, two to a row (one on the narrowest phones), each its pen chip over "B$2 each rival". */
/* At most two to a row (one on the narrowest phones). */
/* Two to a row when every tile's content fits half the row; otherwise the whole group stacks (.stacked, set by
   fitOptionGrids), never a mix (approved 2026-11-05). */
.opt-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 8px; }
.opt-grid.stacked { grid-template-columns: 1fr; }
/* A single option always spans the full width (approved 2026-11-05): a lone tile takes the whole row. */
.opt-grid:has(> .option:only-child) { grid-template-columns: 1fr; }
.opt-grid .option.opt-tile { margin: 0; display: grid; justify-items: start; align-content: start; gap: 8px; padding: 12px; }
.option.opt-tile .tile-label { display: block; min-width: 0; overflow-wrap: anywhere; }
.option.opt-tile .sub { display: block; font-size: 0.85rem; color: inherit; opacity: 1; }
/* Regular weight (approved 2026-11-05): the coin alone carries the payoff, so the words beside it stay quiet. */
.option.opt-tile .sub:has(.coin) { display: inline-flex; align-items: center; gap: 6px; font-size: 0.95rem; font-weight: 500; }
/* The outlined option: a play drawn on the sheet's surface with a barn-red border instead of a red fill. */
.option.outline, .sheet .opt-tray .option.outline { background: var(--surface); border: 2px solid var(--barn); color: var(--ink); }
.option.outline .sub { color: var(--ink); }
.opt-tray > .opt-grid:first-child { margin-top: 0; }
/* A sheet's question, above its options (approved 2026-11-05): asked once, so the options don't repeat it. The step
   count shows only for plays that ask more than one thing. */
.opt-q { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 0 2px; font-weight: 800; font-size: 1rem; color: var(--ink); }
.opt-q .opt-step { margin-left: auto; font-size: 0.85rem; font-weight: 700; color: var(--ink-soft); }
.opt-q + .opt-grid { margin-top: 8px; }
/* A thin rule inside a pill (pen + price, player + bank), the same as the pen chip's extras rule. */
.chip-rule { flex: none; align-self: stretch; width: 1.5px; margin: 2px 2px; background: color-mix(in srgb, var(--ink-soft) 35%, transparent); }
.pchip.priced { padding-right: 3px; }
.pchip.priced .coin { flex: none; }
/* A player with their bank (playerChip in tiles.js). */
.plchip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px 3px 3px; border-radius: 999px; background: var(--card); border: 1.5px solid var(--line); white-space: nowrap; font-size: 0.92rem; }
.plchip .ppiece { padding: 3px; }
.plbank { display: inline-flex; align-items: center; gap: 3px; font-weight: 900; color: var(--gold); }
.plbank svg.ic { color: var(--gold); }
.plbank.empty, .plbank.empty svg.ic { color: var(--ink-soft); font-weight: 600; }

/* The ladder's "B$" label never splits across lines, even in a narrow tile. */
.ladder .unit { white-space: nowrap; }

/* The payment sheet (paySheet in sheets.js): section titles in bold small capitals, the reason as chips, and the Pay
   button fixed at the bottom of the sheet while everything above it scrolls. */
.pay-sec { display: flex; align-items: center; gap: 4px; margin: 14px 0 6px; font-size: 0.78rem; font-weight: 900; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink); }
.pay-sec svg.ic { color: var(--gold); }
.pay-why { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 0 4px; }
.pay-fenced-d { margin: 0 0 8px; }
.pay-foot { position: sticky; bottom: calc(-1 * max(16px, env(safe-area-inset-bottom))); margin: 8px -16px calc(-1 * max(16px, env(safe-area-inset-bottom))); padding: 10px 16px max(16px, env(safe-area-inset-bottom)); background: var(--surface); border-top: 1px solid var(--line); z-index: 1; }

/* penWorth (tiles.js): the pen, then its animals overlapping like the pen's round slots, then "[B$x] each". */
.pworth { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 3px 8px 3px 4px; border: 1.5px solid var(--line); border-radius: 999px; background: var(--card); }
.astack { display: inline-flex; }
.achip { display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--t); border: 2px solid var(--surface); box-shadow: 0 0 0 1px var(--line); }
.achip + .achip { margin-left: -12px; }
.pworth-each { font-size: 0.85rem; font-weight: 700; color: var(--ink-soft); }
/* In a payment row the count stays beside the pill: on a narrow phone the pill wraps inside itself instead. */
.stepper .pay-what:has(.pworth) { flex-wrap: nowrap; }
.pworth { min-width: 0; border-radius: 18px; }
.pworth-v { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }

/* Taking from a rival (Rustle, Barter): each pen's chip heads a row of square buttons, one per card, at two-thirds of
   the first size tried (approved 2026-11-05). Each drawing sits on its card's glow, as on the card. */
.opt-penhead { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.opt-squares { display: flex; gap: 6px; flex-wrap: wrap; }
.sheet .opt-tray .option.opt-sq { display: grid; place-items: center; align-content: center; gap: 2px; width: 62px; aspect-ratio: 1; padding: 3px; margin: 0;
  border-radius: 10px; border: 2px solid var(--barn); background: var(--surface); color: var(--ink); font-weight: 700; font-size: 0.7rem; line-height: 1.1; text-align: center; }
.sheet .opt-tray .option.opt-sq:disabled { opacity: 0.45; filter: grayscale(1); border-color: var(--line); }
.opt-sq .sq-art { position: relative; display: inline-grid; place-items: center; }
.opt-sq .sq-art > * { position: relative; z-index: 1; }
.opt-sq .sq-art::before { content: ""; position: absolute; width: 36px; height: 36px; border-radius: 50%; z-index: 0;
  --glow: var(--glow-d, color-mix(in srgb, var(--hue-glow, var(--glow-mid)) var(--pale-on), var(--hue-glow-d, var(--glow-mid))));
  background: radial-gradient(circle closest-side, var(--glow) 0%, var(--glow) 45%, color-mix(in srgb, var(--glow) 55%, transparent) 70%, transparent 100%); }
.opt-sq.drawing-dark .sq-art::before { --glow-d: var(--glow-dark); }
.opt-pens { display: inline-flex; gap: 4px; flex-wrap: wrap; }

/* The top bar (game, lobby): logo, a spacer, then the tools on the right. Shared, so the design page lays it out the same. */
.grow { flex: 1; min-width: 0; }
.topbar { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }

/* The B$ symbol (BUCKS in icons.js) stands where the letters "B$" stood, at their size: its 3 is as tall as a capital
   (Nunito's cap and digit ink: 0.719em up, digits 0.016em below), its line as tall as the $ (0.844em up, 0.125em down).
   viewBox 30 x 28 at 0.0299em a unit; the baseline is 2.24 units above the box's foot. The selectors repeat classes
   to outrank the printed cards' svg size rules, which would otherwise resize it. */
/* position: relative keeps the hidden "B$" inside the wrapper: absolutely placed, it would otherwise escape scrolling
   rows (the hand) and widen the page on phones. */
.bsym-w { position: relative; white-space: nowrap; margin-right: 0.04em; }
.bsym-w.bsym-w.bsym-w > svg.bsym.bsym { width: 0.896em; height: 0.837em; vertical-align: -0.067em; fill: none; stroke: currentColor; stroke-width: 4.6; stroke-linecap: round; stroke-linejoin: round; overflow: visible; }
.bsym .bsym-3 { stroke-linecap: butt; }

/* ---------- The deck list's back for now: a quick start pointing to the rulebook ---------- */
.pcard.pquick ol { margin: 0; padding-left: calc(4 * var(--u)); display: grid; gap: calc(1.4 * var(--u)); }
.pcard.pquick .pqs-book { margin-top: auto; display: flex; gap: calc(1 * var(--u)); align-items: center; font-weight: 800; color: var(--barn); }

/* ---------- The printed rulebook (rulebook.js): 62 x 87 mm pages, sized in real millimetres ---------- */
.rb-spreads { display: flex; flex-wrap: wrap; gap: 18px 26px; padding: 18px; background: var(--surface-2); border-radius: 14px; justify-content: center; }
.rb-spread { display: flex; box-shadow: 0 6px 18px color-mix(in srgb, var(--ink) 22%, transparent); }
.rb-page { position: relative; width: 62mm; height: 87mm; box-sizing: border-box; padding: 5mm 4.5mm 6mm; background: var(--card); color: var(--ink); font-family: var(--font); font-size: 2.65mm; line-height: 1.32; overflow: hidden; display: flex; flex-direction: column; gap: 1.6mm; }
.rb-spread .rb-page + .rb-page { box-shadow: inset 0.4mm 0 0 color-mix(in srgb, var(--ink) 10%, transparent); }
.rb-page p, .rb-page ol, .rb-page ul { margin: 0; }
.rb-page b { font-weight: 800; }
.rb-h { margin: 0; font-size: 3.7mm; line-height: 1.15; font-weight: 900; color: var(--barn); text-wrap: balance; }
.rb-h:not(:first-child) { margin-top: 1.4mm; }
.rb-small { font-size: 2.3mm; color: var(--ink-soft); }
.rb-big { font-size: 3.1mm; }
.rb-gold { color: var(--gold); font-weight: 900; }
.rb-folio { position: absolute; bottom: 2.4mm; left: 0; right: 0; text-align: center; font-size: 2.2mm; font-weight: 800; color: var(--ink-soft); }
.rb-table { border-collapse: collapse; width: 100%; font-size: 2.45mm; }
.rb-table td, .rb-table th { padding: 0.5mm 0.6mm; border-bottom: 0.2mm solid var(--line); text-align: left; vertical-align: middle; }
.rb-table td:last-child, .rb-table th:last-child { text-align: right; }
.rb-table th { font-size: 2.2mm; color: var(--ink-soft); font-weight: 800; }
.rb-table .rb-total td { font-weight: 900; border-bottom-width: 0.4mm; }
/* Page 4: each pen's value strip, the card's own, at 56% of its printed size (on the card it's zoom 2.59: 1 card px = 63/92 mm). */
.rb-pens { display: grid; gap: 0.7mm; }
.rb-penrow { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1.4mm; padding-bottom: 0.7mm; border-bottom: 0.2mm solid var(--line); }
.rb-penrow > b { color: var(--c); font-weight: 900; font-size: 2.6mm; text-align: right; }
.rb-strip { display: inline-flex; justify-self: start; zoom: 1.45; }
.rb-penrow .coin { font-size: 2.4mm; }
.rb-pen { display: inline-flex; align-items: center; gap: 0.6mm; color: var(--c); font-weight: 900; }
.rb-pen svg { width: 3.6mm; height: 3.6mm; }
.rb-eg { display: flex; justify-content: space-between; align-items: center; padding: 0.9mm 1.4mm; border-radius: 1.2mm; background: color-mix(in srgb, var(--grass) 12%, var(--card)); font-size: 2.6mm; }
.rb-eg > b { color: var(--grass); font-weight: 900; }
.rb-eg.rb-no { background: color-mix(in srgb, var(--ink) 6%, var(--card)); }
.rb-eg.rb-no > b { color: var(--ink-soft); }
.rb-steps { padding-left: 4mm; display: grid; gap: 1mm; }
.rb-list { padding-left: 4mm; display: grid; gap: 0.5mm; }
.rb-fig { display: flex; justify-content: center; align-items: flex-start; gap: 1.6mm; }
.rb-card { display: inline-block; }
.rb-card .card.pcard, .rb-card .ppen { zoom: var(--pz); }
.rb-card .ppen .card.pcard { zoom: 1; }
.rb-table-fig { gap: 4mm; align-items: center; }
.rb-dog { display: flex; gap: 1.2mm; align-items: flex-start; padding: 1mm 1.4mm; border-radius: 1.2mm; background: color-mix(in srgb, var(--base-wild) 12%, var(--card)); font-size: 2.45mm; }
.rb-dog > .rb-card { flex: none; }
.rb-turn { display: grid; gap: 1.2mm; }
.rb-turn > div { display: flex; gap: 1.6mm; align-items: baseline; }
.rb-turn > div > b { flex: none; width: 4.4mm; height: 4.4mm; border-radius: 50%; background: var(--barn); color: var(--band-ink); display: inline-grid; place-items: center; font-size: 2.6mm; transform: translateY(0.7mm); }
.rb-act { display: flex; gap: 1.6mm; align-items: flex-start; }
.rb-act b { color: var(--c); font-weight: 900; }
.rb-act .rb-n { font-size: 2.2mm; color: var(--ink-soft); font-weight: 700; }
.rb-act p { font-size: 2.45mm; line-height: 1.28; color: var(--ink); }
.rb-act > .rb-card { flex: none; }
.rb-act .spicons svg { width: 2.8mm; height: 2.8mm; }
.rb-qr { display: grid; gap: 1.2mm; }
.rb-qr > div { display: grid; grid-template-columns: 11mm 1fr; gap: 1.2mm; font-size: 2.45mm; line-height: 1.25; }
.rb-qr > div > b { color: var(--barn); font-weight: 900; }
.rb-cover-page { background: var(--barn); color: var(--band-ink); justify-content: center; }
.rb-cover { display: grid; justify-items: center; gap: 2.2mm; text-align: center; }
.rb-logo { width: 22mm; height: 22mm; padding: 2.6mm; box-sizing: border-box; border-radius: 50%; background: var(--barn-trim); display: grid; }
.rb-logo .logo, .rb-logo-s .logo { width: 100%; height: 100%; }
.rb-title { font-size: 11mm; font-weight: 900; line-height: 1; letter-spacing: -0.01em; }
.rb-tag { font-size: 4.2mm; font-weight: 800; color: var(--band-accent); }
.rb-herd { display: flex; gap: 1mm; padding: 1.6mm 2.4mm; border-radius: 99mm; background: var(--barn-trim); }
.rb-herd svg { width: 6mm; height: 6mm; }
.rb-facts { font-size: 2.6mm; font-weight: 800; }
.rb-back-page .rb-back { margin-top: auto; display: flex; align-items: center; justify-content: center; gap: 1.6mm; font-size: 5mm; font-weight: 900; color: var(--barn); }
.rb-logo-s { width: 7mm; height: 7mm; display: grid; }
.rb-credits { text-align: center; font-size: 2.1mm; }
@media (max-width: 640px) { .rb-spread { flex-direction: column; } .rb-spreads { padding: 10px; } }

/* ---------- The fence (approved 2026-11-06, "G4"): a fenced pen's share of the goal ----------
   A run of pointed pickets in the pen's colour on a rail behind them, one picket per animal. The same run leads a
   fenced pen's header, sits on its chip on rival tiles, and makes up the goal bar, pen by pen, then pale pickets for
   what's still needed. A Farm Dog's picket is crooked while Rustle can take it, upright with a barn-red point once a
   Barn guards it. The goal's rosette and its numbers are the goal's green. */
.goal:not(.classic) > svg.ic { color: var(--grass); --t: var(--grass); }
.goal:not(.classic) .v, .goal:not(.classic) .v .soft { color: var(--grass); }
.goalbar.fences { gap: 4px; align-items: flex-end; }
.fence-run { display: inline-flex; gap: 2.5px; align-items: flex-end;
  background: linear-gradient(color-mix(in srgb, var(--c) 70%, var(--ink)) 0 0) 0 64% / 100% 2px no-repeat; }
.fence-run i { display: block; width: 7px; height: 12px; background: var(--c); border-radius: 0 0 1.5px 1.5px;
  clip-path: polygon(50% 0, 100% 30%, 100% 100%, 0 100%, 0 30%); transform-origin: 50% 100%; }
.fence-run.narrow i { width: 4px; height: 11px; }
.fence-run.rest { --c: color-mix(in srgb, var(--ink-soft) 40%, var(--surface)); }
.fence-run.rest i { background: color-mix(in srgb, var(--ink-soft) 28%, var(--surface)); }
.fence-run i.dog-risk { transform: rotate(16deg); }
.fence-run i.dog-safe { background: linear-gradient(var(--barn) 0 30%, var(--c) 30% 100%); }
/* Inside the goal bar the classic bar's segment rules (.goalbar i: outline, 3-4-3 gaps, sizes) must not reach the pickets. */
.goalbar.fences .fence-run i { box-shadow: none; margin-right: 0; border-radius: 0 0 1.5px 1.5px; background: var(--c); width: 7px; height: 12px; }
.goalbar.fences .fence-run.rest i { background: color-mix(in srgb, var(--ink-soft) 28%, var(--surface)); }
.goalbar.fences .fence-run i.dog-safe { background: linear-gradient(var(--barn) 0 30%, var(--c) 30% 100%); }
.goalbar.fences .fence-run.narrow i, .tile.narrow .goalbar.fences .fence-run i { width: 4px; height: 11px; }
.pen .head .pen-fence { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; }
.pen .head .pen-fence > svg.ic { color: var(--grass); --t: var(--grass); }
/* In a fenced pen the animals (and its Barn) stand free: no slot boxes. A Farm Dog Rustle can still take keeps its box;
   so does anything you can tap on your turn (a movable animal, the Barn you can discard). */
.pen.fence .slot:not(.at-risk):not(.movable):not(.lost):not(.held):not(.lifted) { background: transparent; border-color: transparent; }
/* An open pen carries the same coloured bottom edge as the animal cards. */
.pen:not(.fenced):not(.ghost) { border-bottom: 5px solid var(--c); }
/* The moment a pen is fenced: its pickets pop up in turn, and its animals glow in turn with them, on the pen, its chip
   and its run in the goal bar. Played once (the game keeps the class on for the animation's length only). */
.fence-run.fx i { animation: fence-pop .6s calc(var(--k) * .15s + var(--fx-shift, 0s)) both; }
.pen.fx .slots > :nth-child(1) { --k: 0; } .pen.fx .slots > :nth-child(2) { --k: 1; } .pen.fx .slots > :nth-child(3) { --k: 2; }
.pen.fx .slots > :nth-child(4) { --k: 3; } .pen.fx .slots > :nth-child(5) { --k: 4; } .pen.fx .slots > :nth-child(6) { --k: 5; }
.pen.fx .slots > .slot:not(.barnslot) { animation: fence-glow .6s calc(var(--k, 0) * .15s + var(--fx-shift, 0s)) both; }
@keyframes fence-pop { 0% { transform: none; filter: none; } 40% { transform: translateY(-2px) scale(1.25); filter: brightness(1.2); } 100% { transform: none; filter: none; } }
.fence-run.fx i.dog-risk { animation-name: fence-pop-crooked; }
@keyframes fence-pop-crooked { 0% { transform: rotate(16deg); } 40% { transform: rotate(16deg) translateY(-2px) scale(1.25); filter: brightness(1.2); } 100% { transform: rotate(16deg); } }
@keyframes fence-glow { 0% { box-shadow: 0 0 0 0 transparent; } 40% { box-shadow: 0 0 0 3px var(--c); } 100% { box-shadow: 0 0 0 0 transparent; } }
@media (prefers-reduced-motion: reduce) { .fence-run.fx i, .pen.fx .slots > .slot { animation: none; } }
/* Your own status line on a phone has no room for the whole fence: below 520 px it shows the rosette and "4/10" (tap it
   for the goal sheet, which shows the fenced pens); wider screens show the fence bar there too. Rival tiles always do. */
.goal.compact .goal-of { display: none; }
@media (max-width: 519px) { .goal.compact .goalbar { display: none; } .goal.compact .goal-of { display: inline; } }
