/*! © 2026 JuJu Games — https://juju.games */
/* Backgammon. The board's whole geometry is one number: `--u`, a point's width in CSS
   pixels, set by backgammon.js on .bgm-stage along with the proportions (--pt-h, --bar-w,
   --tray-w, --man). Nothing here states a proportion of its own — the script measures the
   fitting box and both have to agree, so there is one copy of each number and it is there.

   Nothing here states a panel size either: mode 2 belongs to game-layout.css and the game
   only declares 'fill'. */

.game-root[data-game="backgammon"] {
  /* The board's surface. Kept as variables because every rule below reads them and they are
     the layer a board skin replaces. */
  --felt: #1f4436;
  --felt-lit: #2a5847;
  --frame: #6b4a2f;
  --frame-dark: #46301d;
  --pt-a: #e3d2b4;
  --pt-b: #b4553f;
  --man-you: radial-gradient(64% 64% at 36% 30%, #fdf8ef 0%, #e8dbc5 60%, #c9b596 100%);
  --man-them: radial-gradient(64% 64% at 36% 30%, #4b5566 0%, #2d3543 60%, #1b212b 100%);
  padding: clamp(12px, 2.4vw, 24px);
  border-color: rgba(18, 28, 24, .5);
  background: radial-gradient(120% 100% at 50% 0%, #2f4a41 0%, #243830 58%, #1d2d27 100%);
}

/* width:100% is load-bearing: the filling panel is a flex container, so without it .bgm is a
   flex item that shrinks to its contents — and its contents are sized from it. */
.bgm { display: flex; flex-direction: column; align-items: center; gap: 8px; width: 100%; }
/* Only the board's box may take the slack, or winning a game shrinks the board it was won on. */
.bgm > :not(.g-fit) { flex: none; }

.bgm-status {
  min-height: 1.35em; font-size: .92rem; font-weight: 600; color: var(--c-text-soft);
  text-align: center; transition: color .2s ease;
}
.bgm-status.bgm-alert { color: #c2703a; }
.bgm-pips {
  display: flex; gap: 8px; font-size: .82rem; font-variant-numeric: tabular-nums;
  color: var(--c-text-soft);
}
.bgm-pipsep { opacity: .5; }
.bgm-pipslabel { opacity: .75; }
/* Everything keyed to the dark ground goes in this block, because phones cancel that ground
   and get the page's own paper back. */
@media (min-width: 641px) {
  .bgm-status { color: #dbe8df; }
  .bgm-status.bgm-alert { color: #f0b068; }
  .bgm-pips { color: rgba(219, 232, 223, .7); }
}

.bgm-stage {
  position: relative; --u: 40px;
  background: var(--felt);
  border-radius: 6px;
  box-shadow: 0 6px 22px rgba(12, 26, 20, .32), 0 0 0 calc(var(--u) * .1) var(--frame),
              0 0 0 calc(var(--u) * .14) var(--frame-dark);
}
/* The bar and the tray are the frame showing through, so they are drawn as inserts rather
   than as gaps: a gap would let the felt's own gradient run under them. */
.bgm-bar, .bgm-tray {
  position: absolute; top: 0; height: 100%;
  background: linear-gradient(90deg, var(--frame-dark), var(--frame) 30%, var(--frame) 70%, var(--frame-dark));
}
.bgm-bar { left: calc(6 * var(--u)); width: calc(var(--bar-w) * var(--u)); }
.bgm-tray { left: calc(var(--tray-l) * var(--u)); width: calc(var(--tray-w) * var(--u)); }
.bgm-tray::before {
  content: ''; position: absolute; inset: calc(var(--u) * .08);
  border-radius: calc(var(--u) * .06); background: rgba(20, 12, 6, .3);
}

/* The player's home quarter, under the points. */
.bgm-home {
  position: absolute; left: calc(var(--l) * var(--u)); top: calc((var(--pt-h) + var(--mid)) * var(--u));
  width: calc(6 * var(--u)); height: calc(var(--pt-h) * var(--u)); background: var(--felt-lit);
}
/* Labels never take a press: the one in the tray sits over the tray's own tap target. */
.bgm-label {
  position: absolute; top: 0; left: 0; pointer-events: none; white-space: nowrap;
  transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%));
  font-size: max(9px, calc(var(--u) * .24)); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: rgba(236, 226, 206, .55);
}

.bgm-pts { position: absolute; inset: 0; }
.bgm-pt {
  position: absolute; cursor: default;
  left: calc(var(--l) * var(--u)); top: calc(var(--t) * var(--u));
  width: var(--u); height: calc(var(--pt-h) * var(--u));
}
/* The triangle itself is a child, so the point's own box stays a full rectangle and the tap
   target does not narrow to a spike at the tip. */
.bgm-pt::before {
  content: ''; position: absolute; inset: 0;
  clip-path: polygon(2% 0, 98% 0, 50% 100%);
}
.bgm-up::before { clip-path: polygon(2% 0, 98% 0, 50% 100%); }
.bgm-down::before { clip-path: polygon(50% 0, 98% 100%, 2% 100%); }
.bgm-light::before { background: var(--pt-a); }
.bgm-dark::before { background: var(--pt-b); }

/* ⚠️ A filter or a shadow on the triangle is cut away by its own clip-path. */
.bgm-pt.is-to { cursor: pointer; }
.bgm-pt.is-from::before { filter: brightness(1.15); }
.bgm-tray.is-to { cursor: pointer; box-shadow: inset 0 0 0 3px rgba(96, 186, 128, .95); }
.bgm-tray.is-coach { animation: bgm-traycoach 1.6s ease-in-out infinite; }
.bgm-bar.is-from { box-shadow: inset 0 0 0 3px rgba(96, 186, 128, .7); }
@keyframes bgm-traycoach {
  0%, 100% { box-shadow: inset 0 0 0 2px rgba(243, 200, 106, .45); }
  50% { box-shadow: inset 0 0 0 4px rgba(243, 200, 106, 1); }
}

/* Where a lifted checker can go: a ghost of it on top of the stack it would join, carrying
   the die that move spends. The press is taken by the point (or the tray) underneath. */
.bgm-marks { position: absolute; inset: 0; z-index: 35; pointer-events: none; }
/* ⚠️ Positioned by left/top, never by `transform`: `scale` is applied after `transform`, so a
   breathing scale on a transform-positioned node scales its position too and it wanders. */
.bgm-to {
  position: absolute; box-sizing: border-box;
  left: calc(var(--x) * var(--u)); top: calc(var(--y) * var(--u)); translate: -50% -50%;
  width: calc(var(--man) * var(--u)); height: calc(var(--man) * var(--u));
  display: grid; place-items: center; border-radius: 50%;
  border: max(2px, calc(var(--u) * .06)) dashed rgba(255, 255, 255, .92);
  background: rgba(255, 255, 255, .22);
  color: #fff; font-weight: 800; line-height: 1; font-size: max(11px, calc(var(--u) * .44));
  text-shadow: 0 0 2px rgba(0, 0, 0, .85), 0 1px 2px rgba(0, 0, 0, .6);
  animation: bgm-mark 1.5s ease-in-out infinite;
}
/* Landing here hits the checker standing on it. */
.bgm-to.is-hit { border-style: solid; border-color: #ffb36b; background: rgba(232, 128, 52, .5); }
@keyframes bgm-mark {
  0%, 100% { scale: 1; }
  50% { scale: 1.12; }
}

/* A checker is drawn over its point and the layer does not take the press, so a tap lands on
   the point underneath — which is what carries the move. The bar and the tray take their own. */
.bgm-men { position: absolute; inset: 0; pointer-events: none; }
.bgm-man {
  position: absolute; top: 0; left: 0; z-index: calc(var(--z, 0) + 1);
  width: calc(var(--man) * var(--u)); height: calc(var(--man) * var(--u));
  border-radius: 50%;
  transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%));
  transition: transform .34s cubic-bezier(.33, .1, .27, 1);
}
.bgm-man::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  box-shadow: 0 calc(var(--u) * .02) calc(var(--u) * .05) rgba(10, 16, 12, .45);
}
.bgm-you::before { background: var(--man-you); }
.bgm-them::before { background: var(--man-them); }
/* An inner disc, the way a real checker is turned. Every distance is a share of --u: the
   board is 26px a point on a phone and 70 on a monitor. */
.bgm-man::after {
  content: ''; position: absolute; inset: calc(var(--u) * .17); border-radius: 50%;
  border: calc(var(--u) * .02) solid rgba(0, 0, 0, .14);
}
/* The ring around a checker is its own child, so its animation never meets the ones on the
   checker itself (the hit, the refusal), which all run on `transform`. */
.bgm-halo {
  position: absolute; inset: calc(var(--u) * -.1); border-radius: 50%; pointer-events: none;
  border: calc(var(--u) * .065) solid transparent; opacity: 0;
}
.bgm-man.is-can .bgm-halo { opacity: 1; border-color: rgba(140, 222, 160, .95); animation: bgm-halo 1.6s ease-in-out infinite; }
.bgm-man.is-sel .bgm-halo {
  opacity: 1; border-color: #9cf0b0; box-shadow: 0 0 calc(var(--u) * .3) rgba(120, 230, 150, .75);
}
.bgm-man.is-coach .bgm-halo { opacity: 1; border-color: #f3c86a; animation: bgm-halo-big 1.6s ease-in-out infinite; }
.bgm-man.is-landed .bgm-halo { border-color: rgba(214, 224, 240, .95); animation: bgm-landed 1.1s ease-out; }
.bgm-man.is-off .bgm-halo { display: none; }
@keyframes bgm-halo {
  0%, 100% { transform: scale(1); opacity: .55; }
  50% { transform: scale(1.1); opacity: 1; }
}
@keyframes bgm-halo-big {
  0%, 100% { transform: scale(1); opacity: .35; }
  50% { transform: scale(1.22); opacity: .95; }
}
@keyframes bgm-landed {
  0% { transform: scale(1); opacity: 1; }
  100% { transform: scale(1.4); opacity: 0; }
}
.bgm-man.is-moving { z-index: 40; }
.bgm-man.is-no { animation: bgm-no .44s ease-out; }
.bgm-man.is-hit { z-index: 40; animation: bgm-hit .5s ease-out; }
/* Borne off: the checker lies flat in the tray, the way it is stacked on a real board. */
.bgm-man.is-off {
  height: calc(var(--u) * .24); border-radius: calc(var(--u) * .06);
  width: calc(var(--man) * var(--u));
}
.bgm-man.is-off::before, .bgm-man.is-off::after { border-radius: calc(var(--u) * .06); }
.bgm-man.is-off::after { inset: calc(var(--u) * .05) calc(var(--u) * .12); }

@keyframes bgm-hit {
  0% { transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%)) scale(1); }
  40% { transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%)) scale(1.25) rotate(14deg); }
  100% { transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%)) scale(1); }
}
@keyframes bgm-no {
  0%, 100% { transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%)); }
  20% { transform: translate(calc(var(--x) * var(--u) - 50% - var(--u) * .08), calc(var(--y) * var(--u) - 50%)); }
  40% { transform: translate(calc(var(--x) * var(--u) - 50% + var(--u) * .06), calc(var(--y) * var(--u) - 50%)); }
  60% { transform: translate(calc(var(--x) * var(--u) - 50% - var(--u) * .04), calc(var(--y) * var(--u) - 50%)); }
  80% { transform: translate(calc(var(--x) * var(--u) - 50% + var(--u) * .02), calc(var(--y) * var(--u) - 50%)); }
}
/* Across a resize the script changes --u, which moves all thirty checkers at once — they
   would slide to their new spots, and on the first deal out of the corner. */
.bgm-stage.is-resizing .bgm-man,
.bgm-stage:not(.is-live) .bgm-man { transition: none; }

/* --- dice -------------------------------------------------------------------------- */
.bgm-dice { position: absolute; inset: 0; pointer-events: none; }
.bgm-die {
  position: absolute; top: 0; left: 0; z-index: 30;
  width: calc(var(--u) * .78); height: calc(var(--u) * .78);
  transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%));
  display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
  padding: calc(var(--u) * .08); gap: calc(var(--u) * .02);
  border-radius: calc(var(--u) * .13);
  box-shadow: 0 calc(var(--u) * .03) calc(var(--u) * .07) rgba(8, 18, 14, .45);
  transition: opacity .25s ease;
}
.bgm-die-you { background: linear-gradient(160deg, #fbf6ec, #e2d7c3); }
.bgm-die-them { background: linear-gradient(160deg, #46505f, #272e39); }
.bgm-pip { border-radius: 50%; }
.bgm-die-you .bgm-pip.on { background: #2b2118; }
.bgm-die-them .bgm-pip.on { background: #f2ece1; }
.bgm-die.is-spent { opacity: .28; }
.bgm-die.is-rolling { animation: bgm-roll .42s ease-out; }
@keyframes bgm-roll {
  0% { transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%)) scale(.5) rotate(-120deg); }
  60% { transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%)) scale(1.18) rotate(18deg); }
  100% { transform: translate(calc(var(--x) * var(--u) - 50%), calc(var(--y) * var(--u) - 50%)) scale(1) rotate(0); }
}
.bgm-stage:not(.is-live) .bgm-die { animation: none; }

/* The roll button on the board, standing where the player's dice will land. Positioned like
   .bgm-to, for the same reason. */
.bgm-rollhere {
  position: absolute; z-index: 45;
  left: calc(var(--x) * var(--u)); top: calc(var(--y) * var(--u)); translate: -50% -50%;
  min-width: calc(var(--u) * 2.2); height: max(26px, calc(var(--u) * .9)); padding: 0 calc(var(--u) * .45);
  border: 0; border-radius: 999px; cursor: pointer;
  background: #3f9a5f; color: #fff; font: inherit; font-weight: 700;
  font-size: max(12px, calc(var(--u) * .36));
  box-shadow: 0 calc(var(--u) * .05) calc(var(--u) * .14) rgba(8, 18, 14, .45);
  animation: bgm-rollwait 1.8s ease-in-out infinite;
}
.bgm-rollhere[hidden] { display: none; }
.bgm-rollhere:hover { background: #47ab6a; }
.bgm-rollhere.is-coach { animation: bgm-rollcoach 1.6s ease-in-out infinite; }
@keyframes bgm-rollwait {
  0%, 100% { scale: 1; }
  50% { scale: 1.06; }
}
@keyframes bgm-rollcoach {
  0%, 100% { scale: 1; box-shadow: 0 0 0 calc(var(--u) * .06) rgba(243, 200, 106, .45); }
  50% { scale: 1.08; box-shadow: 0 0 0 calc(var(--u) * .16) rgba(243, 200, 106, .95); }
}

/* --- controls ---------------------------------------------------------------------- */
.bgm-controls { display: flex; gap: 10px; justify-content: center; align-items: center; flex-wrap: wrap; }
.bgm-btn { font-size: .86rem; padding: 7px 14px; }
/* An action that is not available goes grey — not translucent, and it stays readable. Roll
   needs its own rule: it is the primary button, so greying the text alone leaves a filled
   violet button that still reads as the thing to press while the opponent is thinking. */
.bgm-btn.bgm-off { color: #98a0a6; }
.bgm-roll:not(.bgm-off) { background: #3f9a5f; }
.bgm-roll:not(.bgm-off):hover { background: #47ab6a; }
.bgm-roll.bgm-off { background: #46574f; border-color: transparent; color: #9fb0a7; }
.bgm-select {
  font-size: .86rem; padding: 7px 10px; border-radius: 8px;
  border: 1px solid var(--c-border); background: var(--c-surface); color: var(--c-text);
}
.bgm-fs { display: inline-flex; align-items: center; gap: 7px; }
/* Two nested corners read as "expand" at any size; U+26F6 tofus on Windows and Android. */
.bgm-fsicon {
  position: relative; display: inline-block; width: .85em; height: .72em;
  border: 2px solid currentColor; border-radius: 2px;
}
.bgm-fsicon::before {
  content: ''; position: absolute; inset: 2px;
  border-top: 2px solid currentColor; border-bottom: 2px solid currentColor; opacity: .45;
}

/* --- the first game's cards ---------------------------------------------------------- */
/* top/left are written by placeCoach(). */
.bgm-coach {
  position: absolute; top: 0; left: 0; z-index: 50;
  width: min(88%, 300px); padding: 12px 14px 11px; border-radius: 14px;
  background: #fffaf0; color: #2a211a; text-align: center;
  box-shadow: 0 10px 30px rgba(10, 20, 16, .35);
}
.bgm-coach p { margin: 0; font-size: .87rem; line-height: 1.45; }
.bgm-coach-btns { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 10px; }
.bgm-coach .bgm-btn { background: #f0e6d6; color: #2a211a; border: 0; }
.bgm-coach .bgm-go { background: #3f9a5f; color: #fff; }

/* The way the player's checkers travel, drawn under the opening card. The path is measured
   in pathLength units (100), so the dash draws it whatever the board's size. */
.bgm-path { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 36; pointer-events: none; overflow: visible; }
.bgm-path path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.bgm-path-shade { stroke: rgba(10, 18, 14, .45); stroke-width: .34; stroke-dasharray: 100; animation: bgm-draw 3.6s ease-in-out infinite; }
.bgm-path-line { stroke: #f3c86a; stroke-width: .16; stroke-dasharray: 100; animation: bgm-draw 3.6s ease-in-out infinite; }
.bgm-path-head { stroke: #f3c86a; stroke-width: .16; animation: bgm-head 3.6s ease-in-out infinite; }
@keyframes bgm-draw {
  0% { stroke-dashoffset: 100; opacity: 1; }
  55%, 85% { stroke-dashoffset: 0; opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes bgm-head {
  0%, 52% { opacity: 0; }
  58%, 85% { opacity: 1; }
  100% { opacity: 0; }
}

/* --- the result card ---------------------------------------------------------------- */
/* Over the board, not under it: the card has to land inside the game area. */
.bgm-end { position: absolute; inset: 0; z-index: 60; display: grid; place-items: center; pointer-events: none; }
.bgm-end:empty { display: none; }
.bgm-end > * { pointer-events: auto; max-width: min(92%, 360px); }
.bgm-end .result-card {
  background: #22352d; border: 1px solid rgba(240, 232, 218, .16); color: #f3ead9;
  padding: 18px 22px 20px; border-radius: 16px; text-align: center;
  box-shadow: 0 18px 44px rgba(8, 18, 14, .5);
}
.bgm-end .result-done { color: #f7eeda; }
.bgm-end .result-value { color: #f7eeda; font-size: 2.2rem; line-height: 1.15; margin-top: 2px; }
.bgm-end .result-best { color: rgba(243, 234, 219, .74); font-size: .84rem; margin: 8px 0 0; }
.bgm-end .result-egg {
  color: #e6bb63; background: rgba(224, 178, 86, .14); font-size: .84rem;
  padding: 5px 14px; margin: 10px 0 0; border: 1px solid rgba(224, 178, 86, .3);
}
.bgm-end .result-card .btn { margin-top: 16px; }
.bgm-soft { text-align: center; }
.bgm-stage.bgm-won { animation: bgm-won 1.1s ease-out; }
@keyframes bgm-won {
  0% { box-shadow: 0 6px 22px rgba(12, 26, 20, .32), 0 0 0 calc(var(--u) * .1) var(--frame), 0 0 0 calc(var(--u) * .14) var(--frame-dark); }
  40% { box-shadow: 0 6px 22px rgba(12, 26, 20, .32), 0 0 0 calc(var(--u) * .1) #caa25e, 0 0 0 calc(var(--u) * .2) rgba(202, 162, 94, .45); }
  100% { box-shadow: 0 6px 22px rgba(12, 26, 20, .32), 0 0 0 calc(var(--u) * .1) var(--frame), 0 0 0 calc(var(--u) * .14) var(--frame-dark); }
}

/* --- Mode 1: page-embedded ----------------------------------------------------------- */
/* The board takes what the window leaves, capped at an absolute 620px of height: a viewport
   share here would be no cap at all. */
.bgm .g-fit {
  position: relative; display: grid; place-items: center; width: 100%;
  height: clamp(220px, calc(100svh - 270px), 620px);
}

/* --- Mode 3: phone -------------------------------------------------------------------- */
/* Budgeted from the measured chrome so the controls stay above the fold. The board is wider
   than it is tall, so on a portrait phone the WIDTH is what binds: the box has to be given
   the height that width implies (1.2 is the board's own ratio), or it keeps the difference
   as dead space between the board and the buttons — 160px of it at 390x844. Both terms come
   off the viewport, so the box never asks the board how big it is. */
@media (max-width: 640px) {
  .game-root[data-game="backgammon"] { background: none; border: 0; padding: 0; margin-inline: -8px; }
  .bgm .g-fit { height: min(56svh, calc((100vw - 16px) / 1.2)); min-height: 180px; }
  .bgm-controls { gap: 8px; }
  .bgm-btn, .bgm-select { font-size: .8rem; padding: 6px 10px; }
  .bgm-fslabel { display: none; }
  /* On a topic page the "?" of How to play sits at the right end of the status line's row. */
  .game-howto-wrap .bgm-status { padding-inline: 24px; }
  /* At this size the white ring vanishes on the pale points without a dark line either side. */
  .bgm-to {
    box-shadow: 0 0 0 max(1px, calc(var(--u) * .03)) rgba(8, 18, 14, .5),
                inset 0 0 0 max(1px, calc(var(--u) * .03)) rgba(8, 18, 14, .5);
  }
}

/* --- Mode 2: page-filling ------------------------------------------------------------- */
/* Only what goes INSIDE the panel. :not(.bgm-full) on every page-mode rule: full screen is a
   separate mode with its own sizing and these selectors outrank its own. */
html.fills-window .bgm:not(.bgm-full) { height: 100%; justify-content: center; }
html.fills-window .bgm:not(.bgm-full) .g-fit { flex: 1 1 0; min-height: 0; height: auto; }

/* Rails, for the two modes that can afford them. The board is 1.2 times as wide as it is
   tall, so the rails' 289px comes out of the dimension that binds: they pay only once the
   panel is wider than `1.2 x its own height + 146`. Mode 1 is left stacked — its panel is
   capped at .container and its board is already at the 620px ceiling there, so rails would
   buy it nothing. The test is "do rails beat stacking", never "do the rails fit".

   Two entries below because the split header has already handed 380px to the pills: without
   the split that line is a window ratio of about 1.4 at every height this mode runs at, with
   it the same line lands near 11/6, and between 5/3 (where the split engages, in
   game-layout.css) and 11/6 the rails would take more than they give back.

   The board reads the panel's PUBLISHED size rather than recomputing it — --fill-w /
   --fill-h already carry whichever header shape is in force, so the split's 380 never
   appears here. 289 is this game's own spend: the panel's padding, both 110px rails, the 14px
   between each rail and the board, and ~9px outside each rail. ⚠️ The frame is the stage's
   box-shadow, outside the box the board is sized into, so the 14px has to cover it: 0.14u,
   under 11px because this mode's height cap holds u under ~78. With no room for it the frame
   lay 5–8px over the status text and the buttons whenever the board's width was what bound. */
@media (min-aspect-ratio: 7/5) and (max-aspect-ratio: 5/3) and (min-width: 1000px),
       (min-aspect-ratio: 11/6) and (min-width: 1000px) {
  html.fills-window .bgm:not(.bgm-full) {
    display: grid; gap: 0; align-items: center;
    grid-template-columns:
      minmax(0, 1fr) 110px 14px auto 14px 110px minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto auto minmax(0, 1fr);
  }
  html.fills-window .bgm:not(.bgm-full) .g-fit {
    grid-area: 1 / 4 / -1 / 5; flex: none;
    height: calc(var(--fill-h) - 20px); width: calc(var(--fill-w) - 289px);
  }
  html.fills-window .bgm:not(.bgm-full) .bgm-status {
    grid-area: 2 / 2 / 3 / 3; width: 110px; text-align: left; font-size: .85rem;
  }
  html.fills-window .bgm:not(.bgm-full) .bgm-pips {
    grid-area: 3 / 2 / 4 / 3; width: 110px; flex-direction: column; gap: 2px;
  }
  html.fills-window .bgm:not(.bgm-full) .bgm-pips .bgm-pipsep { display: none; }
  html.fills-window .bgm:not(.bgm-full) .bgm-controls {
    grid-area: 2 / 6 / 4 / 7; width: 110px; flex-direction: column; align-items: stretch;
  }
  html.fills-window .bgm:not(.bgm-full) .bgm-controls > * { width: 100%; justify-content: center; padding-inline: 6px; white-space: nowrap; }
}

/* --- Mode 4: full screen --------------------------------------------------------------- */
/* Written outside every media query: mode 2's copy lives inside a window-height query and
   full screen on a tall monitor falls outside it. */
body.bgm-locked { overflow: hidden; }
.bgm.bgm-full {
  position: fixed; inset: 0; z-index: 200; margin: 0; padding: 12px;
  background: radial-gradient(120% 100% at 50% 0%, #2f4a41 0%, #24382f 58%, #1d2d27 100%);
  justify-content: center;
}
.bgm.bgm-full .g-fit { flex: 1 1 0; min-height: 0; height: auto; }
.bgm.bgm-full .bgm-status { color: #dbe8df; }
.bgm.bgm-full .bgm-status.bgm-alert { color: #f0b068; }
.bgm.bgm-full .bgm-pips { color: rgba(219, 232, 223, .7); }
@media (max-width: 640px) { .bgm.bgm-full { padding: 8px 5px; } }
/* Full screen spends nothing on the pill gutters, so the line stays at about 1.4 whatever
   the height — a landscape phone gets rails here too. The gap between each rail and the board
   is the board's frame plus 4px. Full screen has no height cap, so it cannot be a fixed width:
   the frame is 0.14u and u is at most (100svh − 24px) / 11.8 here, which keeps the frame under
   1.19svh. The board's width then takes both rails, the padding, both gaps and ~10px outside
   each rail. */
@media (min-aspect-ratio: 7/5) {
  .bgm.bgm-full {
    display: grid; gap: 0; align-items: center;
    grid-template-columns:
      minmax(0, 1fr) 110px calc(1.19svh + 4px) auto calc(1.19svh + 4px) 110px minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto auto minmax(0, 1fr);
  }
  .bgm.bgm-full .g-fit {
    grid-area: 1 / 4 / -1 / 5; flex: none;
    height: calc(100svh - 24px); width: calc(100vw - 273px - 2.38svh);
  }
  .bgm.bgm-full .bgm-status { grid-area: 2 / 2 / 3 / 3; width: 110px; text-align: left; font-size: .85rem; }
  .bgm.bgm-full .bgm-pips { grid-area: 3 / 2 / 4 / 3; width: 110px; flex-direction: column; gap: 2px; }
  .bgm.bgm-full .bgm-pips .bgm-pipsep { display: none; }
  .bgm.bgm-full .bgm-controls {
    grid-area: 2 / 6 / 4 / 7; width: 110px; flex-direction: column; align-items: stretch;
  }
  .bgm.bgm-full .bgm-controls > * { width: 100%; justify-content: center; padding-inline: 6px; white-space: nowrap; }
}
