/* Accessibility layer.
   Everything here is driven by data-* attributes on <html>, so the settings
   screen only has to set an attribute — no per-element JS, no reflow logic, and
   nothing that can drift out of sync with the rendered UI.

     data-text-scale  normal | large | xlarge
     data-contrast    normal | high
     data-motion      full   | reduced
     data-hand        right  | left
     data-stick       normal | large

   Defaults are the unset state, so a save file from before these existed
   behaves exactly as it did. */

/* ---- text scale --------------------------------------------------------
   Scales the whole UI through one root font-size rather than touching each
   rule, so nothing can be missed. The 3D world is unaffected.
   ONLY rem-sized text follows this. Every size on the paper sheets
   (css/screens.css, .small in base.css) is in rem for exactly that reason —
   they were px, and this setting changed nothing a player could read. */
html[data-text-scale="large"]  { font-size: 118%; }
html[data-text-scale="xlarge"] { font-size: 136%; }

/* The HUD is positioned in vh/vw and must not grow with the text, or the
   reticle and chips march off their anchors. */
html[data-text-scale="large"]  #hud,
html[data-text-scale="xlarge"] #hud { font-size: 16px; }

/* ---- high contrast -----------------------------------------------------
   Raises the terminal palette to solid, saturated values and removes the
   effects that reduce legibility (glow blooms into thin type; scanlines cut
   through it). Deliberately overrides tokens, not individual rules. */
html[data-contrast="high"] {
  --term-green: #b6ffc8;
  --term-mid:   #8ff0a8;
  --term-dim:   #63c47f;
  --term-amber: #ffd08a;
  --term-red:   #ff8a83;
  --term-scan:  transparent;
}
/* The comms inset is the only phosphor surface left, so high contrast raises
   it and drops the effects that hurt thin type — glow blooms into it and the
   scanlines cut through it. The paper screens get their contrast from the
   document rules below, not from these tokens. */
html[data-contrast="high"] .comms { text-shadow: none; background-image: none; border-width: 2px; }
html[data-contrast="high"] .comms-head { border-bottom-width: 2px; }
html[data-contrast="high"] .docsheet { border: 2px solid var(--ink); }
html[data-contrast="high"] .drow { border-bottom-style: solid; }
html[data-contrast="high"] .dtable td { border-bottom-style: solid; }

/* PID/threat chips carry safety-critical meaning — outline them so they never
   rely on colour alone. */
html[data-contrast="high"] .chip,
html[data-contrast="high"] .threat-chip {
  outline: 2px solid currentColor;
  outline-offset: 1px;
  font-weight: bold;
}

/* Mission select cards: high contrast raises the AVAILABLE/LOCKED status line
   to fully opaque and pulls a locked card's desaturation back so its title
   and kicker stay legible — the same "dimming must not double as
   unreadable" rule the base styles now follow, just pushed further. */
html[data-contrast="high"] .mstate,
html[data-contrast="high"] .mbest {
  opacity: 1;
}
html[data-contrast="high"] .mcard.locked {
  filter: saturate(.55) brightness(.92);
}
html[data-contrast="high"] .mcard {
  border-width: 2px;
}
/* the armed (two-press) destructive choice keeps its red fill and gains a
   solid border so it never depends on colour alone */
html[data-contrast="high"] .docsheet button.armed { border-width: 3px; }
html[data-contrast="high"] .docsheet :focus-visible,
html[data-contrast="high"] .mcard:focus-visible { outline-width: 3px; }

/* ---- reduced motion ----------------------------------------------------
   Covers both the OS preference and an explicit in-game choice, because a
   player can want the game calmer without changing a system setting. */
html[data-motion="reduced"] .grain,
html[data-motion="reduced"] #grain,
html[data-motion="reduced"] .vignette-pulse { display: none !important; }

html[data-motion="reduced"] *,
html[data-motion="reduced"] *::before,
html[data-motion="reduced"] *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
}

@media (prefers-reduced-motion: reduce) {
  .grain, #grain { display: none; }
}

/* ---- handedness --------------------------------------------------------
   Swaps the two touch zones. Left-handed players currently have to aim with
   their off hand, which is not a preference so much as a handicap. */
html[data-hand="left"] .stick-zone.left  { left: auto; right: 0; }
html[data-hand="left"] .stick-zone.right { right: auto; left: 0; }
html[data-hand="left"] .touch-buttons {
  right: auto; left: 0;
  align-items: flex-start;
}

/* ---- stick / button size ----------------------------------------------
   Bigger targets for small screens and for anyone who finds the default
   fiddly. The zones stay inside the viewport — a control that extends off
   screen silently eats input. */
html[data-stick="large"] .stick-zone { width: 50%; height: 52%; }
html[data-stick="large"] .tbtn {
  min-width: 68px; min-height: 68px; font-size: 17px;
}
html[data-stick="large"] .tbtn.fire {
  min-width: 92px; min-height: 92px;
}

/* ---- focus ------------------------------------------------------------
   A visible focus ring on every interactive element, in the UI accent (paper
   sheets override it to ink, where amber fails contrast).
   Keyboard and switch-control users cannot navigate what they cannot see. */
:focus-visible {
  outline: 2px solid var(--accent, #e8b43c);
  outline-offset: 2px;
}

/* Anything visually hidden but needed by a screen reader. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
