/* ───────────────────────────────────────────────────────────────────────────
   Parchment — the ground the wizarding sites are written on

   Served from `/shared/parchment.css` on every host (see `SHARED` in
   `Map/server.py`), so the quiz, the trail and the till all read as the same
   piece of paper without any of them keeping a copy.

   **The map is not on this stylesheet, deliberately.** `Map/assets/css/
   style.css` keeps its own parchment and is not to be edited to use this one —
   not before the event. The duplication is a few hundred bytes; editing the
   file the map's every pixel depends on, ten days out, to save them is a bad
   trade. Fold them together afterwards.

   What a page using this must provide for itself:

     * the two fonts — IM Fell English and IM Fell English SC
     * an inline <svg class="svg-defs"> carrying the #sketch and #sketch-fine
       filters. SVG filters resolve against the *document*, not the
       stylesheet, so a `filter: url(#sketch)` here is a dangling reference
       unless the markup defines one. They are eleven lines; each page carries
       them. `Quiz/index.html` has a copy to take.
   ─────────────────────────────────────────────────────────────────────────── */

:root {
  --ink:           #2a1a0b;
  --ink-soft:      #4c3517;
  --ink-faint:     rgba(42, 26, 11, 0.42);
  --parchment:     #e7d3a5;
  --parchment-lit: #f4e5c2;
  --parchment-dim: #cbac74;
  --burn:          #8a5f28;

  /* Right for a wrong answer and green for a right one, both taken a long way
     towards the paper. Pure #c00 on parchment looks like a browser error
     message; these read as a second and third colour of ink. */
  --ink-right:     #2f5d2a;
  --ink-wrong:     #8d2b1e;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

* { box-sizing: border-box; }

/* The ground colour goes on `html` alone, and every layer below is given a
   non-negative z-index. Both halves of that are load-bearing, and the reason
   is a painting-order rule that is very easy to get wrong:

     1. the root element's background
     2. negative z-index descendants
     3. **in-flow block backgrounds — including `body`'s own**
     4. …floats, inline content, then positioned descendants

   So `body { background }` paints at step 3, *over* anything sitting at step
   2. The first version of this file put the parchment at `z-index: -2` and
   the colour on `html, body` together, and the result was a flat brown page
   with the text on it: the paper, the scorching and the frame were all being
   painted and then covered up by the body. Nothing in the computed styles
   looked wrong, because nothing was wrong with them.

   Keeping the colour off `body` and the layers at 0 and above sidesteps the
   whole rule. See the z-index scale further down. */
html {
  background: #b99a63;
}

html, body {
  margin: 0;
  min-height: 100%;
  color: var(--ink);
  font-family: "IM Fell English", Georgia, "Times New Roman", serif;
  -webkit-text-size-adjust: 100%;
}

/* `hidden` has to win, and it needs `!important` to.
 *
 * The attribute gets its `display: none` from the *user agent* stylesheet,
 * and any author rule setting `display` outranks it — so one innocent
 * `.screen { display: grid }` silently un-hides every element in the document
 * carrying `hidden`. That is not a subtle failure when the hidden things are
 * whole screens: they all render, stacked, each a viewport tall, and the page
 * looks perfectly normal because the others are below the fold. `el.hidden =
 * true` appears to do nothing and the DOM insists it worked.
 *
 * Cheaper than remembering never to set `display` on anything that might one
 * day be hidden. */
[hidden] { display: none !important; }

/* Holds the filter definitions without taking any room. `width: 0` rather
   than `display: none`, which in several browsers stops the filters
   resolving at all. */
.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── The paper ──────────────────────────────────────────────────────────── */

/* The z-index scale, such as it is. All positioned, none negative:
 *
 *     0   .parchment    the ground
 *     1   the page's own content — a page using this stylesheet is expected
 *         to put its wrapper at `position: relative; z-index: 1`
 *     2   .stains       scorching and the fold, over the content
 *     3   .frame        the ruled border, over everything
 *
 * Stains and frame sit *above* the writing on purpose — that is how the prop
 * reads, ink on a page that has been burnt and folded rather than under a
 * clean overlay. Both are `pointer-events: none`, so nothing there can
 * swallow a tap.
 */

.parchment {
  position: fixed;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(ellipse 120% 90% at 28% 18%, var(--parchment-lit) 0%, transparent 55%),
    radial-gradient(ellipse 100% 80% at 82% 88%, #e3cb99 0%, transparent 60%),
    radial-gradient(ellipse 140% 120% at 50% 50%, var(--parchment) 40%, var(--parchment-dim) 100%);
}

/* Two turbulences: a tight one for the fibre and a very loose one for the
   mottling a sheet gets from being damp once. Baked as data URIs rather than
   generated, because this must not cost a repaint on a five-year-old phone.
   `fixed`, so scrolling a long question does not drag the paper's grain up
   the screen with it — paper does not do that. */
.parchment::after {
  content: "";
  position: fixed;
  inset: 0;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='260' height='260' filter='url(%23f)'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='700' height='700'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.011' numOctaves='5'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='700' height='700' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 260px 260px, 700px 700px;
  mix-blend-mode: multiply;
  opacity: 0.3;
  pointer-events: none;
}

/* Scorched edges and the shadow of a much-folded page. */
.stains {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  mix-blend-mode: multiply;
  background:
    radial-gradient(ellipse 88% 78% at 50% 50%, transparent 46%, rgba(122, 82, 33, 0.22) 82%, rgba(78, 47, 14, 0.48) 100%),
    linear-gradient(90deg, rgba(120, 82, 34, 0.30), transparent 12%, transparent 88%, rgba(120, 82, 34, 0.30)),
    linear-gradient(180deg, rgba(120, 82, 34, 0.26), transparent 10%, transparent 90%, rgba(120, 82, 34, 0.26));
}

/* Hand-ruled double border. */
.frame {
  position: fixed;
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  pointer-events: none;
  filter: url(#sketch);
}
.frame rect { fill: none; stroke: var(--ink-soft); vector-effect: non-scaling-stroke; }
.frame rect:first-child { stroke-width: 2; }
.frame rect + rect { stroke-width: 0.7; }

/* ── Ink ────────────────────────────────────────────────────────────────── */

.script {
  font-family: "IM Fell English SC", "IM Fell English", Georgia, serif;
  font-weight: 400;
  letter-spacing: 0.05em;
}

.rule {
  border: 0;
  height: 0;
  border-top: 1px solid var(--ink-soft);
  opacity: 0.5;
  width: 42%;
  margin: 0 auto;
}

/* ── Things to press ────────────────────────────────────────────────────── */

.btn {
  font-family: "IM Fell English SC", Georgia, serif;
  font-size: 16px;
  letter-spacing: 0.04em;
  color: var(--ink);
  background: rgba(238, 222, 184, 0.78);
  border: 1.5px solid var(--ink-soft);
  border-radius: 2px;
  padding: 12px 20px;
  cursor: pointer;
  box-shadow: 0 2px 0 rgba(80, 52, 18, 0.25);
  transition: transform 120ms var(--ease), background 200ms, opacity 200ms;
  filter: url(#sketch-fine);
  /* Stops iOS zooming the page when a control is tapped twice quickly, which
     on a quiz is not a double-tap but two children reaching at once. */
  touch-action: manipulation;
}
.btn:hover { background: rgba(244, 231, 199, 0.92); }
.btn:active { transform: translateY(2px); box-shadow: none; }
.btn:focus-visible { outline: 2px dashed var(--burn); outline-offset: 3px; }
.btn[disabled] { opacity: 0.38; cursor: default; box-shadow: none; }
.btn[disabled]:active { transform: none; }

/* The one that ends a screen: wide, and tall enough for a six-year-old's
   aim. 56px because 44 is the documented minimum and this is the button
   that gets pressed in a moving queue. */
.btn--big {
  display: block;
  width: 100%;
  min-height: 56px;
  font-size: 19px;
}

.field {
  width: 100%;
  padding: 10px 8px;
  font-family: "IM Fell English", Georgia, serif;
  font-style: italic;
  /* 16px is the floor at which iOS Safari stops zooming into a focused
     field. Below it, tapping the name box lurches the whole page. */
  font-size: 26px;
  text-align: center;
  color: var(--ink);
  background: transparent;
  border: none;
  border-bottom: 2px solid var(--ink-faint);
  border-radius: 0;          /* iOS rounds and insets text fields otherwise */
  -webkit-appearance: none;
}
.field::placeholder { color: rgba(42, 26, 11, 0.28); }
.field:focus { outline: none; border-bottom-color: var(--ink); }

/* ── Motion ─────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
