/* Quill & Compass — "A Thousand Worlds" world-morph prototype.
   Bold, illustrated, attitude-forward. Per-realm look driven by CSS vars set in JS.
   The swap happens UNDER the poof flash, so backgrounds don't need to tween.

   Re-skinned 2026-08-04 from the near-black era. NOTE the shape of this page: the
   --r-* vars below are only the FIRST-PAINT defaults — realms.js overwrites all five
   of them per realm (realms.js:156-158), so the palette that matters lives there.
   The stage is not parchment-bright and is not meant to be: it is the same sheet of
   paper with the house lights DOWN, gelled a different colour per realm, so the
   motes and the die still read against it. Paper DNA, dimmed — not a black void.
   NO PALETTE LIVES HERE beyond that: colour and type come from tokens.css, which
   realms.html now loads FIRST (it used to pull Cinzel Decorative + Source Serif Pro
   from Google Fonts, so it resolved different faces from the rest of the site). */
:root{
  --r-bg-1:#4a5238; --r-bg-2:#20241a; --r-accent:#dfe4b4; --r-ink:#e6e6ce;
  --r-glow:186,198,126;
  --r-plate:#1b2014;   /* the ink the realm's horizon is cut in; set per realm by JS */
  /* committed defaults for the press. ?tune only overrides these — deleting the panel
     block in realms.js and marketing-site/dev/ removes the feature with no effect here. */
  --plate-scale:1;     /* how tall the cut stands */
  --plate-ink:1;       /* how hard the plate is inked */
  --plate-off:1;       /* how far off-register it lands before it snaps home */
  --plate-lift:0px;    /* the whole horizon up or down the sheet */
  /* the offset a cut-out casts on the sheet beneath it — flat, zero blur */
  --cut-lift-sm:2px 2px 0 rgba(20,14,8,.45);
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{background-color:var(--r-bg-2);color:var(--r-ink);font-family:var(--font-body);
  -webkit-font-smoothing:antialiased;overflow:hidden}

/* paper grain over the whole thing — printed, not rendered. Was mix-blend-mode:overlay,
   which is a lift device for dark grounds; multiply is how grain sits in a sheet. */
body::after{content:"";position:fixed;inset:0;z-index:50;pointer-events:none;opacity:.05;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* the page-local .rtop / .rbrand / .rtop-tag header is gone — this page now uses the
   shared .qnav plaque (nav.css). The realm's name is carried by the <h1> and by the
   masthead's current-page marker, so the old duplicate corner tag retired with it. */

/* ---- the realm stage: dimmed paper, gelled per realm ---- */
.realm{position:relative;width:100vw;height:100svh;overflow:hidden;isolation:isolate;
  background-color:var(--r-bg-2);
  background-image:
    url('./assets/parchment-grain.svg'),
    radial-gradient(95% 85% at 50% 36%, rgba(var(--r-glow),.16), transparent 62%),
    radial-gradient(140% 120% at 50% 125%, var(--r-bg-1), var(--r-bg-2) 78%);
  background-size:220px 220px, cover, cover;
  background-repeat:repeat,no-repeat,no-repeat;
  background-blend-mode:soft-light,normal,normal}
/* ---- the printed plate: a cut horizon per realm ----
   Additive layer. Sits at the same z as #atmos but EARLIER in the DOM, so the air
   prints over the land without renumbering any existing z-index. Art is the site's
   own woodcut cast (cast.js) — nothing new was drawn for this. */
.realm-plates{position:absolute;inset:0;z-index:1;pointer-events:none;color:var(--r-plate);overflow:hidden;
  transform:translateY(var(--plate-lift,0px))}
.rw-item{position:absolute;pointer-events:none;
  transform:translateX(var(--ox,0px));
  transition:transform .55s var(--snap)}
.rw-item:not(.is-span){transform:translateX(-50%) translateX(var(--ox,0px))}
.rw-item > svg{display:block;height:100%;width:auto;fill:currentColor}
/* cast.css fills a knockout with parchment, which is right on a paper page and wrong
   here: on the dimmed stage a skull's eye socket or the castle's gate arch would print
   as a BRIGHT disc. On this page a cut shows the ground through the plate instead. */
.realm-plates .cut{fill:var(--r-bg-1)}
.rw-item.is-span > svg{width:100%}
/* the press comes into register: each band is struck a few px off and snaps home
   under the existing 580ms lamp surge, so a realm change reads as a plate being
   printed rather than a gel being swapped. */
.realm-plates.is-struck .rw-item{--ox:0px}

#atmos,#die,#burst{position:absolute;inset:0;width:100%;height:100%;display:block}
#atmos{z-index:1}
#die{z-index:2;cursor:pointer}
#burst{z-index:5;pointer-events:none}
/* was mix-blend-mode:screen — the poof now reads as the lamp surging on the sheet */
.flash{position:absolute;inset:0;z-index:4;pointer-events:none;opacity:0;
  background:radial-gradient(62% 62% at 50% 46%, rgba(var(--r-glow),1), rgba(var(--r-glow),.35) 48%, transparent 76%)}
.flash.is-poof{animation:poof .58s ease-out}
@keyframes poof{0%{opacity:0}20%{opacity:.85}100%{opacity:0}}

/* ---- the bold type ---- */
.realm-copy{position:absolute;z-index:3;left:clamp(1.2rem,6vw,5.5rem);top:clamp(5.5rem,16vh,10rem);
  max-width:min(60rem,84vw);pointer-events:none}
.realm-kicker{font-family:var(--font-body);font-weight:700;text-transform:uppercase;letter-spacing:.42em;
  font-size:clamp(.72rem,1.3vw,.95rem);color:rgba(var(--r-glow),.95);margin:0 0 .7rem;
  opacity:0;transform:translateY(8px)}
/* the 60px bloom is gone: on paper a heading is pressed, so the only shadow left is
   the hard offset of the block against the sheet. */
.realm-title{font-family:var(--font-display);font-weight:600;line-height:.86;margin:0;
  font-size:clamp(3rem,11vw,9rem);color:var(--r-accent);transform:skewX(-7deg);
  text-shadow:5px 5px 0 rgba(20,14,8,.5);letter-spacing:.005em}
.realm-title .word{display:block;line-height:.82}
.realm-title .ch{display:inline-block;opacity:0;transform:translateY(36px) skewX(7deg)}
/* this used to read `.realm-title.is-in .ch`, but realms.js only ever puts `is-in` on
   .realm-copy (realms.js:171) — never on the title — so every character stayed at
   opacity:0 and the page's <h1> never appeared at all. The kicker survived only
   because its selector is a descendant match. Matched to where the class lands. */
.realm-copy.is-in .realm-title .ch{animation:chIn .55s cubic-bezier(.2,.9,.25,1) forwards}
.is-in .realm-kicker,.realm-copy.is-in .realm-kicker{animation:kickIn .5s ease-out forwards}
.realm-copy.is-in .realm-kicker{animation:kickIn .5s ease-out forwards}

.realm-flavour{position:absolute;z-index:3;left:clamp(1.2rem,6vw,5.5rem);bottom:clamp(6rem,16vh,9rem);
  max-width:min(36rem,82vw);font-size:clamp(1.06rem,1.7vw,1.5rem);line-height:1.45;font-style:italic;
  color:var(--r-ink);margin:0;pointer-events:none;
  opacity:0;transform:translateY(10px);transition:opacity .6s ease,transform .6s ease}
.realm-flavour.is-in{opacity:1;transform:none}

/* ---- roll prompt: a cut chip of lit stock, not a blurred glass pill ---- */
.roll-prompt{position:absolute;z-index:6;right:clamp(1.4rem,5vw,5rem);bottom:clamp(2rem,9vh,5rem);
  display:inline-flex;align-items:center;gap:.6rem;cursor:pointer;
  background-color:var(--paper-100);border:1px solid var(--ink-500);color:var(--ink-900);
  font-family:var(--font-body);font-weight:700;letter-spacing:.14em;text-transform:uppercase;font-size:.8rem;
  padding:.75rem 1.25rem;border-radius:999px;box-shadow:var(--cut-lift-sm);
  transition:transform .16s var(--snap),box-shadow .16s var(--snap),background-color .16s var(--snap);
  animation:cue 2.6s ease-in-out infinite}
.roll-prompt:hover{background-color:var(--paper-300);transform:translate(-1px,-1px);box-shadow:4px 4px 0 rgba(20,14,8,.45)}
.roll-prompt:active{transform:translate(1px,1px);box-shadow:1px 1px 0 rgba(20,14,8,.45)}
.roll-prompt:focus-visible{outline:2px solid var(--paper-100);outline-offset:3px}
.roll-prompt__die{font-size:1.2rem}

/* ---- realm dots ---- */
.realm-dots{position:absolute;z-index:6;left:50%;transform:translateX(-50%);bottom:clamp(1.4rem,4vh,2.4rem);
  display:flex;gap:.7rem}
.realm-dots i{width:9px;height:9px;border-radius:50%;background:rgba(244,233,207,.24);transition:.4s;display:block}
.realm-dots i.on{background:var(--r-accent);transform:scale(1.25)}

.realm-foot{position:absolute;z-index:6;right:clamp(1.4rem,5vw,5rem);top:clamp(6rem,16vh,9rem);
  max-width:18rem;text-align:right;font-size:.74rem;line-height:1.5;color:rgba(244,233,207,.52);
  margin:0;pointer-events:none}

/* The plain pages. This page is a full-bleed stage with no footer to hang them in
   — every other page carries them in .qc-foot__legal-nav or .foot-legal-nav — so
   they sit in the one empty corner instead. Deliberately quiet, but NOT dimmed to
   illegibility: --r-ink at .78 clears 4.5:1 against every realm's ground, where the
   .52 used by .realm-foot above (decorative flavour text) would not. */
.realm-legal{position:absolute;z-index:6;left:clamp(1.2rem,6vw,5.5rem);bottom:clamp(1.2rem,3.5vh,2rem);
  display:flex;flex-wrap:wrap;gap:.1rem .85rem;margin:0}
.realm-legal a{position:relative;
  font-family:var(--font-body);font-weight:700;font-size:.68rem;
  letter-spacing:.12em;text-transform:uppercase;
  color:rgba(244,233,207,.78);text-decoration:none;padding:.2rem 0;
  border-bottom:2px solid transparent;transition:color .18s var(--calm),border-color .18s var(--calm)}
.realm-legal a + a::before{content:"";position:absolute;left:-.44rem;top:.3em;bottom:.3em;
  width:1px;background:rgba(244,233,207,.3)}
.realm-legal a:hover{color:var(--r-accent);border-bottom-color:var(--r-accent)}
.realm-legal a:focus-visible{outline:2px solid var(--r-accent);outline-offset:3px}

@keyframes chIn{to{opacity:1;transform:translateY(0) skewX(7deg)}}
@keyframes kickIn{to{opacity:1;transform:translateY(0)}}
@keyframes cue{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}

@media (max-width:760px){
  .realm-copy{top:6.5rem;left:1.2rem;right:1.2rem}
  .realm-foot{display:none}
  /* .realm-dots is centred on the same line, so the routes stay hard left */
  .realm-legal{left:1.2rem;bottom:1.1rem;gap:.1rem .7rem}
  .realm-legal a{font-size:.62rem;letter-spacing:.1em}
  .roll-prompt{left:50%;right:auto;transform:translateX(-50%);bottom:4.5rem}
  /* the hover/active nudges must not fight the centring transform on mobile */
  .roll-prompt:hover,.roll-prompt:active{transform:translateX(-50%)}
  .realm-flavour{bottom:8.5rem}
}
/* reduced motion still APPLIES the state — only the tween is skipped.
   `?motion` forces the animated build on a machine with the OS setting on; realms.js
   reads the same flag, so the JS and CSS can never disagree about which build is live. */
@media (prefers-reduced-motion:reduce){
  :root:not(.force-motion) .rw-item{transition:none}
}
@media (prefers-reduced-motion:reduce){
  .realm-title .ch{animation:none;opacity:1;transform:skewX(7deg)}
  .realm-copy .realm-kicker{animation:none;opacity:1;transform:none}
  .roll-prompt{animation:none}
  .roll-prompt:hover,.roll-prompt:active{transform:none}
  .flash.is-poof{animation:poofReduced .4s ease-out}
}
@media (prefers-reduced-motion:reduce) and (max-width:760px){
  .roll-prompt:hover,.roll-prompt:active{transform:translateX(-50%)}
}
@keyframes poofReduced{0%{opacity:0}40%{opacity:.5}100%{opacity:0}}
