/* Ink & paper: the Séance's letterpress material. Tokens, faces, grain, the two-pass
   print, browser surfaces, the lockup and the loader. Every surface stylesheet builds
   on these. */

@font-face { font-family: 'Ultra'; src: url('fonts/ultra.woff2') format('woff2'); font-display: swap; }
@font-face { font-family: 'Big Shoulders Display'; src: url('fonts/big-shoulders-display.woff2') format('woff2'); font-weight: 100 900; font-display: swap; }
@font-face { font-family: 'IM Fell English'; src: url('fonts/im-fell-english.woff2') format('woff2'); font-display: swap; }
@font-face { font-family: 'IM Fell English'; src: url('fonts/im-fell-english-italic.woff2') format('woff2'); font-style: italic; font-display: swap; }

:root {
  /* Midnight-indigo stock, two inks, and gaslight (light only, never ink). */
  --stock: #171b3d;
  --stock-deep: #0c0f26;
  --stock-raised: #20265a;
  --bone: #efe5cd;
  --bone-dim: #bfb6a0;      /* 8.1:1 on --stock */
  --oxblood: #a8262d;       /* large type and fills only: 2.4:1 on stock */
  --oxblood-deep: #7a141b;
  --gas: #f5bb4d;

  --face-fat: 'Ultra', 'Rockwell Extra Bold', serif;
  --face-gothic: 'Big Shoulders Display', 'Oswald', sans-serif;
  --face-roman: 'IM Fell English', Georgia, serif;

  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --space-1: 4px; --space-2: 8px; --space-3: 16px; --space-4: 24px; --space-5: 40px; --space-6: 64px;

  --light: 1;   /* fraction of footlights still burning */
  --voice: 0;   /* the spirit's voice level 0..1, set every frame */
  --flicker: 0; /* shared gaslight flicker -1..1 */

  /* Paper fibre, and the worn-woodtype mask: speckled alpha where ink failed to take. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' seed='4'/%3E%3CfeColorMatrix values='0 0 0 0 .93 0 0 0 0 .9 0 0 0 0 .8 0 0 0 .09 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)'/%3E%3C/svg%3E");
  --worn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.55' numOctaves='3' seed='9'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='0 1 1 1 1 1 1 1'/%3E%3C/feComponentTransfer%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23w)'/%3E%3C/svg%3E");
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100%; }
body {
  background: var(--stock-deep);
  color: var(--bone);
  font-family: var(--face-roman);
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
body::after { /* paper fibre over everything, under nothing interactive */
  content: ''; position: fixed; inset: 0; z-index: 90; pointer-events: none;
  background: var(--grain); opacity: .9; mix-blend-mode: overlay;
}
h1, h2, h3 { margin: 0; font-weight: normal; text-wrap: balance; }

/* ---------- Browser surfaces, themed from the palette ---------- */
::selection { background: var(--oxblood); color: var(--bone); }
html { scrollbar-color: var(--oxblood-deep) var(--stock-deep); scrollbar-width: thin; caret-color: var(--gas); }
a { color: inherit; text-underline-offset: .2em; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--gas); outline-offset: 4px; border-radius: 1px; }
[tabindex="-1"]:focus { outline: none; } /* headings take focus on screen change, for screen readers only */

/* ---------- Ink ---------- */
.ink { -webkit-mask-image: var(--worn); mask-image: var(--worn); -webkit-mask-size: 220px; mask-size: 220px; }
.gothic { font-family: var(--face-gothic); font-weight: 800; text-transform: uppercase; letter-spacing: .02em; line-height: .95; }
.fat { font-family: var(--face-fat); line-height: .9; letter-spacing: .01em; }

/* The two-pass print: oxblood lands first, off register; the bone pass follows and
   settles on top. Used for every reveal: the bill, each spoken word, each notice. */
.print { animation: print .9s var(--ease-out) both; animation-delay: var(--d, 0s); }
@keyframes print {
  0%   { color: transparent; text-shadow: 5px 3px 0 var(--oxblood); filter: blur(1.5px); }
  45%  { color: transparent; text-shadow: 2px 1px 0 var(--oxblood); filter: blur(0); }
  100% { color: inherit;     text-shadow: 1px .5px 0 rgba(168, 38, 45, .55); }
}

/* ---------- Buttons: printed billing lines ---------- */
.btn {
  font: 800 1.05rem/1 var(--face-gothic); text-transform: uppercase; letter-spacing: .12em;
  color: var(--bone); background: transparent; cursor: pointer; touch-action: manipulation;
  min-height: 44px; padding: .8rem 1.4rem; border: 2px solid currentColor; border-radius: 0;
  transition: background-color .2s, color .2s, transform .12s var(--ease-out);
}
.btn:hover { background: var(--bone); color: var(--stock); box-shadow: none; }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn[aria-busy="true"] { opacity: .5; cursor: progress; }
.btn-stamp { background: var(--oxblood); border-color: var(--oxblood); color: var(--bone); }
.btn-stamp:hover { background: var(--bone); border-color: var(--bone); color: var(--oxblood-deep); }

.icon { width: 1em; height: 1em; fill: currentColor; flex: none; }

/* ---------- Lockup ---------- */
.brand {
  position: fixed; top: max(16px, env(safe-area-inset-top)); left: max(16px, env(safe-area-inset-left)); z-index: 60;
  display: flex; align-items: center; gap: 12px;
}
.brand a { display: block; opacity: .8; transition: opacity .25s; }
.brand a:hover { opacity: 1; }
.brand img { display: block; width: auto; }
.logo-fish { height: 22px; }      /* optically matched: the cap heights line up */
.logo-livekit { height: 15.5px; }
.brand-x { font: 600 1rem/1 var(--face-gothic); color: var(--bone-dim); }

/* ---------- Loader: the print run ---------- */
.loader {
  position: fixed; inset: 0; z-index: 50; display: grid; place-content: center; justify-items: center; gap: var(--space-4);
  background: var(--stock-deep); transition: opacity .7s var(--ease-out), visibility .7s;
  text-align: center; padding: var(--space-4);
}
.loader.done { opacity: 0; visibility: hidden; }
.loader-title { font-size: clamp(3.4rem, 14vw, 6rem); color: var(--bone); }
.loader-text { font: italic 1.15rem/1.4 var(--face-roman); color: var(--bone-dim); margin: 0; min-height: 1.5em; }
.loader-rule { width: min(260px, 60vw); height: 3px; background: rgba(239, 229, 205, .12); }
.loader-rule span { display: block; height: 100%; background: var(--oxblood); transform-origin: left; transform: scaleX(0); transition: transform .5s var(--ease-out); }
.loader-retry[hidden] { display: none; }

/* ---------- Screens ---------- */
main { position: relative; z-index: 10; }
.screen { display: none; min-height: 100dvh; }
.screen.active { display: block; }

.debug {
  position: fixed; right: 8px; bottom: 8px; z-index: 95; max-width: min(46ch, 90vw); max-height: 40vh; overflow: auto;
  background: rgba(0, 0, 0, .85); color: #9fe39f; font: 11px/1.4 ui-monospace, monospace; padding: 8px; margin: 0; white-space: pre-wrap;
}

@media (max-width: 640px) {
  .brand { gap: 9px; }
  .logo-fish { height: 18px; }
  .logo-livekit { height: 12.5px; }
}

@media (prefers-reduced-motion: reduce) {
  .print { animation: none; }
  .loader-rule span { transition: none; }
}
