@charset "UTF-8";
/* ==========================================================================
   Bible Games — shared theme  (shared/theme.css)
   --------------------------------------------------------------------------
   Night and gold. "Light in the darkness": deep indigo night, warm light
   falling from above, everything of value framed in carved olive wood banded
   with gold. The same world as Christian Reversi, Jesus Chess and Jesus
   Checkers, so a visitor moving between the hub and a game never feels they
   left.

   --------------------------------------------------------------------------
   WHAT BELONGS IN THIS FILE, AND WHAT DOES NOT

   IN:   design tokens, the resets everything relies on, accessibility
         primitives, the focus ring, the self-check report, and the
         preference blocks (reduced motion, forced colours, more contrast,
         print).

   OUT:  layout. Every page has its own shape — the hub is a scrolling grid of
         tiles, a game is a fixed-height flex column — and pouring both into
         one file is how a change to the hub silently breaks a game. Each page
         keeps its own styles.css for layout, and loads this first.

   The test for "does it belong here?" is simple: could a page reasonably want
   it DIFFERENT? If yes, it is not shared.

   --------------------------------------------------------------------------
   HOW A PAGE LOADS IT

     <link rel="stylesheet" href="/biblegames/shared/theme.css?v=...">
     <link rel="stylesheet" href="styles.css?v=...">

   In that order. The page's own file comes second so it can override, and
   both carry ?v=<mtime> so a deploy is never masked by a cache.

   Re-theming the WHOLE SITE is now one edit: change section 1 here.
   --------------------------------------------------------------------------
   Contents
     1. Design tokens
     2. Resets and the things that must always win
     3. Accessibility primitives
     4. The self-check report (?check=1)
     5. Reduced motion, forced colours, more contrast, print
   ========================================================================== */

/* -------------------------------------------------------------------------- */
/* 1. Design tokens                                                           */
/* -------------------------------------------------------------------------- */

:root {
  /* Night sky. */
  --bg-deep: #08061a;
  --bg-mid: #171034;
  --bg-glow: rgba(255, 214, 138, 0.28);
  --bg-beam: rgba(255, 226, 168, 0.05);

  /* Carved olive wood, banded with gold — the frame around anything precious. */
  --frame-1: #7a5a26;
  --frame-2: #2e2008;
  --frame-3: #c9a24f;

  /* Gold, from candle-light to old leaf. */
  --gold-1: #fff3b0;
  --gold-2: #ffcc33;
  --gold-3: #b7860b;
  --gold-glow: rgba(255, 204, 51, 0.34);

  /* Ink, in three levels.
       --text        anything the visitor reads to use the page.
       --text-dim    supporting text: labels, hints, instructions.
       --text-faint  DECORATIVE ONLY — never for anything a visitor must read.
                     If you are reaching for it to quieten something the
                     visitor needs, the answer is --text-dim and a smaller
                     size.

     --text-dim was #b6a9d2 until it measured 4.18:1 on small text sitting
     under the warm glow at the top of a page. Lifted to clear 4.5:1 while
     staying visibly quieter than --text. Do not darken it again without
     re-running BibleGames_Contrast.py. */
  --text: #f4eeff;
  --text-dim: #c2b6dd;
  --text-faint: #8d82ab;

  /* Panels — a lit surface standing slightly proud of the night. */
  --panel-1: rgba(46, 34, 92, 0.72);
  --panel-2: rgba(26, 18, 58, 0.86);
  --panel-edge: rgba(255, 214, 130, 0.22);
  --panel-edge-lit: rgba(255, 214, 130, 0.85);
  --panel-shadow: rgba(3, 2, 12, 0.55);

  /* The only two non-gold accents on the site, so they always mean
     "look here". Used by the self-check report and by right/wrong feedback. */
  --ok: #86e6a8;
  --warn: #ff9c6e;

  /* Type. System stacks only — no webfont request, so a page paints
     immediately and looks the same offline as online. */
  --font-ui: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  --font-display: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia,
                  'Times New Roman', serif;
  --font-mono: ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;

  /* Motion. A page that animates a value MUST keep its JavaScript timing in
     step with the token it animates; see --dur-verse-fade in the hub. */
  --dur: 180ms;

  /* Rhythm */
  --radius: 14px;
}

/* -------------------------------------------------------------------------- */
/* 2. Resets and the things that must always win                              */
/* -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

/*
 * `hidden` must always win.
 *
 * The browser's own rule is only `[hidden] { display: none }`, which ANY later
 * `display` declaration beats on specificity. That has already cost this site
 * a real bug: `.btn { display: inline-flex }` overrode it, so a Next button
 * stayed on screen through a fresh question — and clicking it skipped the
 * question without answering. Every DOM assertion passed; only a screenshot
 * showed it.
 *
 * One rule, here, fixes the whole class of bug for every page at once. This is
 * the single best reason for this file to exist.
 */
[hidden] {
  display: none !important;
}

/* -------------------------------------------------------------------------- */
/* 3. Accessibility primitives                                                */
/* -------------------------------------------------------------------------- */

/* Present to a screen reader, invisible on screen. */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/*
 * The three-step focus ring.
 *
 * Writing only the third rule — the common shortcut — leaves anyone on an
 * older browser with NO visible focus at all. All three:
 *
 *   1. every browser gets a ring on :focus;
 *   2. browsers that understand :focus-visible take it off for mouse clicks;
 *   3. and put it back for the keyboard.
 *
 * The extra two rules cost four lines. [tabindex] is included so a page can
 * make a panel focusable — a game moving focus to its question, for example —
 * without having to remember to restyle the ring.
 */
a:focus,
button:focus,
[tabindex]:focus {
  outline: 3px solid var(--gold-1);
  outline-offset: 3px;
}

a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
[tabindex]:focus:not(:focus-visible) {
  outline: none;
}

a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--gold-1);
  outline-offset: 3px;
}

::selection {
  background: var(--gold-2);
  color: #241703;
}

/* -------------------------------------------------------------------------- */
/* 4. The self-check report (?check=1)                                        */
/* -------------------------------------------------------------------------- */

/*
 * Styled here because the MARKUP is shared too — bgs_report() in
 * shared/page.php emits exactly these classes. Markup and its styling have to
 * travel together, or one page's report quietly stops matching its own CSS.
 *
 * The report is the one thing allowed to break a game's no-scroll rule: it is
 * a maintenance view, not the game, and a diagnostic you cannot scroll is
 * worse than useless.
 */
.report {
  position: fixed;
  inset: 0;
  z-index: 40;
  overflow: auto;
  padding: 24px;
  background: rgba(8, 6, 26, 0.97);
  font-family: var(--font-mono);
  font-size: 0.86rem;
}

.report__title {
  margin: 0 0 12px;
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--gold-1);
}

.report__subtitle {
  margin: 18px 0 8px;
  font-size: 0.95rem;
  color: var(--gold-2);
}

.report__line {
  margin: 0 0 14px;
  font-weight: 700;
}

.report__line.is-ok   { color: var(--ok); }
.report__line.is-warn { color: var(--warn); }

.report__stats {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 18px;
  margin: 0;
}

.report__stats dt { color: var(--text-dim); }
.report__stats dd { margin: 0; color: var(--text); }

.report__list {
  margin: 0;
  padding-left: 1.2em;
  color: var(--warn);
}

.report__list li {
  margin-bottom: 6px;
  line-height: 1.5;
}

/* -------------------------------------------------------------------------- */
/* 5. Reduced motion, forced colours, more contrast, print                    */
/* -------------------------------------------------------------------------- */

/*
 * Reduced motion removes the TRANSITIONS, not the behaviour. Buttons still
 * light up and verses still change — instantly. Motion can cause nausea and
 * migraine; losing the feature would be a different kind of harm.
 *
 * 0.01ms rather than 0s on purpose: a duration of exactly zero stops some
 * browsers firing transitionend, and any script waiting on that event would
 * hang forever.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/*
 * Windows High Contrast throws our palette away wholesale, which would leave
 * every panel as an invisible rectangle. Ask for system borders explicitly and
 * hand the focus ring over to the system Highlight colour.
 */
@media (forced-colors: active) {
  .report {
    background: Canvas;
    color: CanvasText;
  }

  .report__line.is-ok,
  .report__line.is-warn,
  .report__list {
    color: CanvasText;
  }

  a:focus,
  a:focus-visible,
  button:focus,
  button:focus-visible,
  [tabindex]:focus,
  [tabindex]:focus-visible {
    outline: 3px solid Highlight;
  }
}

/* Keep our palette, but firm it up. */
@media (prefers-contrast: more) {
  :root {
    --text-dim: #e6dcff;
    --text-faint: #c3b9dd;
    --panel-edge: rgba(255, 214, 130, 0.7);
  }
}

/* A printed page is a list of addresses for a parent or a children's worker. */
@media print {
  .report,
  .visually-hidden {
    display: none !important;
  }
}
