/* Colchis frame: every selector is fenced off [data-cf] (gen-css.mjs --fence). */
/* ==========================================================================
   a11y.css — accessibility layer for Rex vs Mummies (cross defense)

   LOAD ORDER MATTERS. This sheet must be the LAST stylesheet in <head>,
   after cross-board.css, because cross-board.css contains:

       .cross-game :is(button,a,select,input,textarea):focus        {outline:none!important}
       .cross-game :is(button,a,select,input,textarea):focus-visible{outline:none!important; filter:drop-shadow(...)}

   ...which removes the focus indicator outright (WCAG 2.4.7 / 1.4.11). Every
   focus rule below is written at higher specificity AND with !important so it
   wins the cascade regardless.

   Sections
     1. Utilities .............. .visually-hidden, .skip-link
     2. Focus indicators ....... dual-tone ring, 3:1 against adjacent colours
     3. Board grid ............. row wrappers, gridcell focus
     4. aria-disabled mirrors .. keeps the :disabled look on focusable gates
     5. Target size ............ WCAG 2.2 2.5.8 hit-area padding
     6. Motion ................. the half of the reduced-motion reset game.css misses
     7. Responsible gaming ..... autoplay panel + reality check
     8. Forced colours
   ========================================================================== */

/* ---------------------------------------------------------------- *
 * 1. Utilities
 * ---------------------------------------------------------------- */

/* Available to assistive tech, invisible on screen, and — because it is
   absolutely positioned — NOT a grid item, so it cannot disturb the
   `display:grid` <body> the desktop layout uses. */
.visually-hidden:where(:not([data-cf],[data-cf] *)) {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-links:where(:not([data-cf],[data-cf] *)) { position: fixed; top: 0; left: 0; z-index: 2147483000; }

.skip-link:where(:not([data-cf],[data-cf] *)) {
  position: absolute;
  top: -200px; left: 8px;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 18px;
  border: 2px solid #ffffff;
  border-radius: 8px;
  background: #06120f;
  color: #ffffff;                 /* 18.6:1 on #06120f */
  font: 700 15px/1.2 Barlow, Arial, sans-serif;
  text-decoration: underline;
  white-space: nowrap;
}
.skip-link:nth-of-type(2):where(:not([data-cf],[data-cf] *)) { left: 210px; }
.skip-link:focus:where(:not([data-cf],[data-cf] *)) { top: 8px; }

/* ---------------------------------------------------------------- *
 * 2. Focus indicators  (WCAG 2.4.7 Focus Visible, 1.4.11 Non-text Contrast,
 *    2.4.11 Focus Not Obscured, and the 2.4.13 Focus Appearance shape)
 *
 * A dual-tone ring: a 3px white outline with a near-black 3px halo outside
 * it. Whatever the adjacent colour is — the gold gate frame #ecbb60, the
 * teal gate fill #173c3d, the plum tile #432338 — at least one of the two
 * tones clears 3:1 against it, and the two tones clear 18:1 against each
 * other. The ring is never removed, only relocated for clipped hosts.
 * ---------------------------------------------------------------- */

:root:where(:not([data-cf],[data-cf] *)) {
  --a11y-ring: #ffffff;
  --a11y-halo: #05100d;
  --a11y-ring-width: 3px;
}

body :is(button, a, select, input, textarea, summary, [tabindex]):focus-visible:where(:not([data-cf],[data-cf] *)), body.cross-game :is(button, a, select, input, textarea, summary, [tabindex]):focus-visible:where(:not([data-cf],[data-cf] *)), html body.cross-game .cross-gate:focus-visible:where(:not([data-cf],[data-cf] *)), html body.cross-game .corner-gate:focus-visible:where(:not([data-cf],[data-cf] *)) {
  outline: var(--a11y-ring-width) solid var(--a11y-ring) !important;
  outline-offset: 2px !important;
  box-shadow:
    0 0 0 2px var(--a11y-halo),
    0 0 0 8px var(--a11y-halo) !important;
  /* Keep the game's own glow as a bonus cue; it is not the indicator. */
  filter: drop-shadow(0 0 4px #b9efcf) !important;
  border-radius: inherit;
}

/* Keyboard users who tab into a <select> inside the dialog. */
body.cross-game :is(select, input[type="checkbox"]):focus-visible:where(:not([data-cf],[data-cf] *)) {
  outline-offset: 3px !important;
}

/* Windows high-contrast / users who force their own focus ring. */
@media (prefers-contrast: more) {
  :root:where(:not([data-cf],[data-cf] *)) { --a11y-ring-width: 4px; }
}

/* ---------------------------------------------------------------- *
 * 3. Board grid
 *
 * The row wrappers a11y.mjs inserts are layout-transparent: `display:contents`
 * means the 25 tiles remain direct grid items of #board, and every tile
 * already carries an explicit grid-row/grid-column, so nothing moves.
 * ---------------------------------------------------------------- */

.a11y-grid:where(:not([data-cf],[data-cf] *)),
.a11y-row:where(:not([data-cf],[data-cf] *)) { display: contents; }

/* Tiles are `overflow:hidden`, and #board is only 4px-gapped, so the cell
   ring is drawn inside the tile instead of outside it. It still uses two
   tones and is still at least 3px thick. */
.cross-game .board .tile:focus-visible:where(:not([data-cf],[data-cf] *)),
.cross-game #board .tile:focus-visible:where(:not([data-cf],[data-cf] *)) {
  outline: 3px solid var(--a11y-ring) !important;
  outline-offset: -3px !important;
  box-shadow:
    inset 0 0 0 6px var(--a11y-halo),
    0 0 0 2px var(--a11y-halo) !important;
  z-index: 7;
}

/* Some assistive-tech setups focus a cell programmatically without the
   heuristic that drives :focus-visible. Never leave that invisible. */
.cross-game #board .tile:focus:where(:not([data-cf],[data-cf] *)) {
  outline: 3px solid var(--a11y-ring) !important;
  outline-offset: -3px !important;
}

/* The 16 unopened cells are hidden by `.cross-game .tile.locked
   {visibility:hidden!important}` (cross-board.css). `visibility:hidden` prunes
   an element from the accessibility tree AND makes it unfocusable, so before
   the first expansion a screen-reader user could perceive only 9 of the 25
   cells and the keyboard could not reach the rest.

   Swap the hiding mechanism for one that is pixel-identical but keeps the cell
   in the tree: fully transparent and inert to the pointer. When such a cell
   takes keyboard focus it paints as an empty outlined square, so the focus
   position is always visible (SC 2.4.7). `.tile.locked.preview-target` is dead
   CSS — no module ever adds that class — so nothing depends on the old
   behaviour. */
.cross-game #board .tile.locked:where(:not([data-cf],[data-cf] *)) {
  visibility: visible !important;
  opacity: 0;
  pointer-events: none;
}
.cross-game #board .tile.locked > *:where(:not([data-cf],[data-cf] *)) { visibility: hidden !important; }
.cross-game #board .tile.locked:focus:where(:not([data-cf],[data-cf] *)),
.cross-game #board .tile.locked:focus-visible:where(:not([data-cf],[data-cf] *)) {
  opacity: 1;
  background: none !important;
  background-image: none !important;
  border-color: transparent !important;
  box-shadow:
    inset 0 0 0 3px var(--a11y-ring),
    inset 0 0 0 6px var(--a11y-halo) !important;
}

/* #board is `overflow:visible!important`, so the gate rings are never clipped. */

/* ---------------------------------------------------------------- *
 * 4. aria-disabled mirrors
 *
 * a11y.mjs converts the eight board purchase buttons from `disabled` to
 * `aria-disabled="true"` so screen-reader and keyboard users can still reach
 * them and hear *why* they are unavailable. These rules reproduce, exactly,
 * the appearance the `:disabled` selectors used to give them.
 * ---------------------------------------------------------------- */

.cross-game #board button[aria-disabled="true"]:where(:not([data-cf],[data-cf] *)) {
  cursor: default;
  opacity: .53;
  filter: saturate(.35);
}
.cross-game #board .cross-gate[aria-disabled="true"]:where(:not([data-cf],[data-cf] *)) {
  cursor: default;
  color: #abc3bf;   /* 9.2:1 on the gate's darkest fill #091e26 */
  opacity: 1;
  filter: none;
}
.cross-game #board .corner-gate[aria-disabled="true"]:where(:not([data-cf],[data-cf] *)) {
  cursor: default;
  opacity: 1;
  filter: saturate(.45);
}
/* A focused unavailable gate must still show its ring at full strength. */
.cross-game #board button[aria-disabled="true"]:focus-visible:where(:not([data-cf],[data-cf] *)) {
  opacity: 1;
  filter: none !important;
}

/* ---------------------------------------------------------------- *
 * 5. Target size (WCAG 2.2 SC 2.5.8, Minimum 24x24; 44x44 practical bar)
 *
 * Hit areas are grown with a transparent pseudo-element overlay, which does
 * not change any box size and therefore cannot move the imperative JS layout
 * in round-controls.mjs.
 * ---------------------------------------------------------------- */

@media (pointer: coarse) {
  .cross-game .auto-indicator:where(:not([data-cf],[data-cf] *)),
  .cross-game .paytable-toggle:where(:not([data-cf],[data-cf] *)) {
    position: relative;
  }
  .cross-game .auto-indicator:where(:not([data-cf],[data-cf] *))::before,
  .cross-game .paytable-toggle:where(:not([data-cf],[data-cf] *))::before {
    content: "";
    position: absolute;
    left: 0; right: 0;
    top: 50%;
    height: 44px;
    transform: translateY(-50%);
  }
  /* The footer squares drop to 31x55 at the narrowest breakpoint. 31px clears
     SC 2.5.8 (24x24) but not the 44px bar; widen the hit area only. */
  .cross-game footer .square:where(:not([data-cf],[data-cf] *)),
  .cross-game header .square:where(:not([data-cf],[data-cf] *)) { position: relative; }
  .cross-game footer .square:where(:not([data-cf],[data-cf] *))::before,
  .cross-game header .square:where(:not([data-cf],[data-cf] *))::before {
    content: "";
    position: absolute;
    top: 0; bottom: 0;
    left: 50%;
    width: 44px;
    min-height: 44px;
    transform: translateX(-50%);
  }
}

/* ---------------------------------------------------------------- *
 * 6. Motion
 *
 * game.css already ships the standard reduced-motion reset, but it sets only
 * `animation-duration:.01ms`. Without `animation-iteration-count:1`, every
 * `infinite` keyframe loop in the build (22 of them across cross-board.css,
 * frames-motion.css and game.css) keeps looping forever at 0.01ms, which is
 * both a residual flicker risk and a pointless CPU cost. This closes it.
 * ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *:where(:not([data-cf],[data-cf] *)), *:where(:not([data-cf],[data-cf] *))::before, *:where(:not([data-cf],[data-cf] *))::after {
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
  }
  .outpost-fog:where(:not([data-cf],[data-cf] *)), .outpost-candle:where(:not([data-cf],[data-cf] *)), .scene-rex:where(:not([data-cf],[data-cf] *)) { transition: none !important; }
}

/* ---------------------------------------------------------------- *
 * 7. Responsible gaming
 *
 * Both blocks are position:fixed, so mounting them anywhere — including
 * directly on the CSS-grid <body> — is layout-inert: a fixed-position child
 * of a grid container is out of flow and is not a grid item.
 * ---------------------------------------------------------------- */

.rg-autoplay:where(:not([data-cf],[data-cf] *)) {
  position: fixed;
  top: var(--rg-autoplay-top, calc(env(safe-area-inset-top, 0px) + 8px));
  left: var(--rg-autoplay-left, 50%);
  translate: var(--rg-autoplay-translate, -50% 0);
  z-index: 2147482000;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-width: 232px;
  max-width: min(420px, calc(100vw - 24px));
  padding: 10px 16px;
  border: 2px solid #9fe3c7;
  border-radius: 12px;
  background: #04120f;            /* text below is >= 10:1 on this */
  box-shadow: 0 8px 28px #000c;
  color: #eafff4;
  font: 600 13px/1.35 Barlow, Arial, sans-serif;
  text-align: center;
}
.rg-autoplay[hidden]:where(:not([data-cf],[data-cf] *)) { display: none; }

.rg-autoplay-spins:where(:not([data-cf],[data-cf] *)) { margin: 0; font: 800 17px/1.2 Barlow, Arial, sans-serif; color: #ffffff; }
.rg-autoplay-net:where(:not([data-cf],[data-cf] *))   { margin: 0; color: #eafff4; }
.rg-autoplay-limits:where(:not([data-cf],[data-cf] *)){ margin: 0; color: #cfe6da; font-size: 12px; }  /* 11.3:1 on #04120f */
.rg-autoplay[data-trend="up"]   .rg-autoplay-net:where(:not([data-cf],[data-cf] *)) { color: #a9f08a; } /* 12.3:1 */
.rg-autoplay[data-trend="down"] .rg-autoplay-net:where(:not([data-cf],[data-cf] *)) { color: #ffc9b8; } /* 11.9:1 */

/* One tap, always reachable, never obscured: the panel is the topmost
   non-dialog layer and the button fills its width. */
.rg-stop:where(:not([data-cf],[data-cf] *)) {
  display: block;
  width: 100%;
  min-height: 44px;
  margin: 2px 0 0;
  padding: 10px 18px;
  border: 2px solid #ffffff;
  border-radius: 8px;
  background: #7a1226;
  color: #ffffff;                 /* 9.9:1 on #7a1226 */
  font: 800 15px/1 Barlow, Arial, sans-serif;
  letter-spacing: .6px;
  cursor: pointer;
}
.rg-stop:hover:where(:not([data-cf],[data-cf] *)) { background: #99182f; }

.rg-reality-check:where(:not([data-cf],[data-cf] *)) { display: block; }
.rg-reality-check .rg-ledger:where(:not([data-cf],[data-cf] *)) {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 6px 18px;
  margin: 14px 0;
  padding: 12px 14px;
  border: 1px solid #6f8a7c;
  border-radius: 8px;
  background: #0a1a16;
}
.rg-reality-check dt:where(:not([data-cf],[data-cf] *)) { margin: 0; color: #d7e7dd; font-weight: 600; }   /* 12.4:1 */
.rg-reality-check dd:where(:not([data-cf],[data-cf] *)) { margin: 0; color: #ffffff; font-weight: 800; text-align: right; }
.rg-reality-check[data-trend="up"]   dd:last-of-type:where(:not([data-cf],[data-cf] *)) { color: #a9f08a; }
.rg-reality-check[data-trend="down"] dd:last-of-type:where(:not([data-cf],[data-cf] *)) { color: #ffc9b8; }

.rg-note:where(:not([data-cf],[data-cf] *)) {
  margin: 8px 0;
  color: #d5e3d6;                 /* 11.6:1 on the #0b1512 dialog fill */
  font: 400 13px/1.55 Barlow, Arial, sans-serif;
}

.rg-options .rg-field:where(:not([data-cf],[data-cf] *)),
.rg-options .rg-check:where(:not([data-cf],[data-cf] *)) { display: flex; align-items: center; gap: 10px; margin: 10px 0; }
.rg-options .rg-field label:where(:not([data-cf],[data-cf] *)) { flex: 1; text-align: left; }
.rg-options select:where(:not([data-cf],[data-cf] *)) { min-height: 44px; padding: 6px 10px; }
.rg-options input[type="checkbox"]:where(:not([data-cf],[data-cf] *)) { width: 24px; height: 24px; flex: none; }
.rg-options .rg-check label:where(:not([data-cf],[data-cf] *)) { flex: 1; text-align: left; }

.rg-actions:where(:not([data-cf],[data-cf] *)) { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.rg-actions .action:where(:not([data-cf],[data-cf] *)) { min-height: 44px; }

/* ---------------------------------------------------------------- *
 * 8. Forced colours
 * ---------------------------------------------------------------- */

@media (forced-colors: active) {
  body :is(button, a, select, input, textarea, [tabindex]):focus-visible:where(:not([data-cf],[data-cf] *)), .cross-game #board .tile:focus-visible:where(:not([data-cf],[data-cf] *)) {
    outline: 3px solid Highlight !important;
    outline-offset: 2px !important;
    box-shadow: none !important;
    filter: none !important;
    forced-color-adjust: none;
  }
  .rg-autoplay:where(:not([data-cf],[data-cf] *)), .rg-stop:where(:not([data-cf],[data-cf] *)), .skip-link:where(:not([data-cf],[data-cf] *)) { forced-color-adjust: auto; }
  .cross-game #board button[aria-disabled="true"]:where(:not([data-cf],[data-cf] *)) { opacity: 1; filter: none; }
}
