
@font-face {
  font-family: 'Orpheus';
  src: url('/assets/Orpheus.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
}

:root {
  --c1: oklch(52% 0.12 317);   /* dominant: dusty violet */
  --c2: oklch(32% 0.086 287);  /* deep indigo-shadow */
  --c3: oklch(42% 0.097 297);  /* mid blue-violet */
  --c4: oklch(67% 0.092 307);  /* lighter violet */
  --c5: oklch(77% 0.076 332);  /* pale mauve */
  --c6: oklch(87% 0.065 347);  /* near-white rose */
}

*, *::before, *::after {
  margin: 0; padding: 0; box-sizing: border-box;
  font-variant-caps: normal;
}

html, body {
  width: 100%; height: 100%;
  background: #000;
  font-family: 'Orpheus', Georgia, serif;
  text-transform: lowercase;
}

/* CRT scanlines — GPU-composited via transform instead of background-position */
@keyframes scanlines {
  from { transform: translateY(0); }
  to   { transform: translateY(4px); }
}

/* CRT flicker — authentic phosphor behavior */
@keyframes flicker {
  0%   { opacity: 0.27861; }
  5%   { opacity: 0.34769; }
  10%  { opacity: 0.23604; }
  15%  { opacity: 0.90626; }
  20%  { opacity: 0.18128; }
  25%  { opacity: 0.83891; }
  30%  { opacity: 0.65583; }
  35%  { opacity: 0.67807; }
  40%  { opacity: 0.26559; }
  45%  { opacity: 0.84693; }
  50%  { opacity: 0.96019; }
  55%  { opacity: 0.08594; }
  60%  { opacity: 0.20313; }
  65%  { opacity: 0.71988; }
  70%  { opacity: 0.53455; }
  75%  { opacity: 0.37288; }
  80%  { opacity: 0.71428; }
  85%  { opacity: 0.70419; }
  90%  { opacity: 0.7003;  }
  95%  { opacity: 0.36108; }
  100% { opacity: 0.24387; }
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  /* Slightly taller than viewport so translateY(4px) never shows a gap */
  width: 100%; height: calc(100% + 4px);
  background: repeating-linear-gradient(
    to bottom,
    transparent          0px,
    transparent          2px,
    rgba(0,0,0,0.13)     2px,
    rgba(0,0,0,0.13)     4px
  );
  animation: scanlines 0.25s linear infinite;
  will-change: transform;
  pointer-events: none;
  z-index: 1000;
}

body::after {
  content: '';
  position: fixed;
  inset: 0;
  width: 100%; height: 100%;
  background: rgba(18, 16, 16, 0.1);
  animation: flicker 0.15s infinite;
  will-change: opacity;
  transform: translateZ(0);
  pointer-events: none;
  z-index: 1001;
}

/* Mask glow pulse — 3 shadows (down from 4) keeps the bloom, saves one filter pass */
@keyframes glow-pulse {
  0%, 100% {
    filter:
      drop-shadow(0 0 2px var(--c6))
      drop-shadow(0 0 8px var(--c1))
      drop-shadow(0 0 26px var(--c2));
  }
  50% {
    filter:
      drop-shadow(0 0 3px var(--c6))
      drop-shadow(0 0 13px var(--c1))
      drop-shadow(0 0 38px var(--c2));
  }
}

/* ─── LAYOUT ─────────────────────────────────────────────── */

.screen {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 36px 72px 36px;
  position: relative;
  box-shadow: inset 0 0 200px rgba(0, 0, 0, 0.9);
  filter: hue-rotate(15deg);
}

/* ─── BANDS ──────────────────────────────────────────────── */

.band {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.band-top { flex-direction: column; }
/* ─── CENTER ─────────────────────────────────────────────── */

.center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 28px;
  flex: 1;
  padding: 2vh 0 8px;
}

/* ─── MASK FACE ──────────────────────────────────────────── */

.mask-wrap {
  animation: glow-pulse 5s ease-in-out infinite;
  will-change: filter;
  flex: 0 0 auto;
}

/* Blink — whole eye group collapses to a flat line from center */
.eye-group {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  will-change: transform;
}

@keyframes blink-close {
  0%   { transform: scaleY(1); }
  20%  { transform: scaleY(0.04); }  /* snap flat */
  65%  { transform: scaleY(0.04); }  /* hold */
  100% { transform: scaleY(1); }     /* snap open */
}

.eye-group.blinking {
  animation: blink-close 220ms ease-in-out forwards;
}

/* ── KNOWING SMILE ──────────────────────────────────────────
   Mouth morphs via CSS d-property; crinkle lines fade in.
   Eye blink uses transform — no conflict. ── */

/* ── KNOWING SMILE — full face anatomy ─────────────────────────
   Corners lift ~20 SVG units. Cheeks push outward and up.
   Face outline bulges at the malar (cheekbone) level.
   Right corner always sits higher than left — the asymmetry is the secret. */

@keyframes mouth-upper-smile {
  /* Terrible joy — corners curl far up and outward like hooks.
     Mouth nearly doubles in width; right corner always higher.
     Center stays anchored near (400,450). */
  0%, 100% { d: path('M 363 452 C 375 444 390 443 400 447 C 410 443 425 444 439 449'); }
  30%, 70%  { d: path('M 338 415 C 358 440 385 449 400 450 C 415 449 444 438 466 408'); }
}
@keyframes mouth-lower-smile {
  /* Lower lip center dips slightly (468) — mouth opens a fraction.
     Corners match upper lip for closed seal at edges. */
  0%, 100% { d: path('M 363 452 Q 400 463 439 449'); }
  30%, 70%  { d: path('M 338 415 Q 400 468 466 408'); }
}

/* Cheeks push harder outward to accommodate the wider grin */
@keyframes cheek-left-smile {
  0%, 100% { d: path('M 345 390 L 325 450 L 340 510'); }
  30%, 70%  { d: path('M 340 386 L 296 428 L 320 502'); }
}
@keyframes cheek-right-smile {
  0%, 100% { d: path('M 455 390 L 475 450 L 460 510'); }
  30%, 70%  { d: path('M 460 386 L 504 428 L 480 502'); }
}
@keyframes cheek-bottom-smile {
  0%, 100% { d: path('M 375 510 L 400 520 L 425 510'); }
  30%, 70%  { d: path('M 365 516 L 400 530 L 435 516'); }
}

/* Face outline: stronger cheekbone bulge to support the wide grin */
@keyframes face-left-smile {
  0%, 100% { d: path('M 330 110 C 260 140 240 260 270 370 C 290 450 340 520 400 550'); }
  30%, 70%  { d: path('M 330 110 C 260 140 230 260 256 370 C 280 450 336 520 400 550'); }
}
@keyframes face-right-smile {
  0%, 100% { d: path('M 470 110 C 540 140 560 260 530 370 C 510 450 460 520 400 550'); }
  30%, 70%  { d: path('M 470 110 C 540 140 570 260 544 370 C 520 450 464 520 400 550'); }
}

@keyframes crinkle-appear {
  0%, 100% { opacity: 0; }
  30%, 70%  { opacity: 0.7; }
}

#mouth-upper.smiling  { animation: mouth-upper-smile  9s ease-in-out forwards; }
#mouth-lower.smiling  { animation: mouth-lower-smile  9s ease-in-out forwards; }
#cheek-left.smiling   { animation: cheek-left-smile   9s ease-in-out forwards; }
#cheek-right.smiling  { animation: cheek-right-smile  9s ease-in-out forwards; }
#cheek-bottom.smiling { animation: cheek-bottom-smile 9s ease-in-out forwards; }
#face-left.smiling    { animation: face-left-smile    9s ease-in-out forwards; }
#face-right.smiling   { animation: face-right-smile   9s ease-in-out forwards; }
.eye-crinkle           { opacity: 0; }
.eye-crinkle.smiling   { animation: crinkle-appear    9s ease-in-out forwards; }

.mask-wrap svg {
  height: 62vh;
  width: auto;
  /* Isolate SVG filter to its own GPU layer */
  transform: translateZ(0);
  will-change: opacity;
}

/* Visibility transitions driven by mask.ts */
.mask-wrap {
  transition: opacity 1.5s ease, transform 1.5s ease;
}
.mask-wrap.mask-hidden {
  opacity: 0;
  pointer-events: none;
  animation-play-state: paused;
}
.mask-wrap.mask-enlarged svg {
  height: 84vh;
}

/* Glow line classes — bright gets two passes for richness; others single pass */
.glow-line {
  fill: none;
  stroke: var(--c5);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: miter;
  filter: drop-shadow(0 0 4px rgba(190, 145, 170, 0.6));
}
.glow-line-bright {
  fill: none;
  stroke: var(--c6);
  stroke-width: 2.8;
  stroke-linecap: round;
  stroke-linejoin: miter;
  filter: drop-shadow(0 0 4px rgba(235, 190, 215, 0.8)) drop-shadow(0 0 12px rgba(180, 130, 165, 0.45));
}
.glow-line-faint {
  fill: none;
  stroke: var(--c4);
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 2px rgba(165, 125, 170, 0.5));
}

/* ─── TEXT ───────────────────────────────────────────────── */

.entity-speech {
  font-size: 1.2rem;
  line-height: 1.95;
  color: var(--c6);
  text-align: center;
  letter-spacing: 0.035em;
  filter: drop-shadow(0 0 8px var(--c5)) drop-shadow(0 0 20px var(--c1));
}

.fortune-verse {
  font-size: 1.0rem;
  line-height: 2.0;
  color: var(--c3);
  text-align: center;
  letter-spacing: 0.04em;
  filter: drop-shadow(0 0 6px var(--c2));
}

.entity-interpret {
  font-size: 1.0rem;
  line-height: 2.0;
  color: var(--c5);
  text-align: center;
  letter-spacing: 0.03em;
  max-width: 500px;
  filter: drop-shadow(0 0 8px var(--c4)) drop-shadow(0 0 16px var(--c1));
}

/* ─── SIGIL SLOTS ─────────────────────────────────────────── */

.sigil-slot {
  display: block;
  transition: opacity 1.2s ease;
  pointer-events: none;
}

.sigil-slot svg {
  display: block;
  fill: var(--c5);
}

/* Morph display — matches mask brightness and glow */
#sigil-top {
  animation: none;
  opacity: 1;
}
#sigil-morph-svg {
  display: block;
  fill: var(--c6);
  animation: glow-pulse 5s ease-in-out infinite;
  transform: translateZ(0);
  will-change: filter;
}

/* ─── SIGIL FRAME ────────────────────────────────────────── */

#sigil-frame {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 999; /* below scanlines (1000), above .screen content */
}

.sf-cell {
  position: absolute;
  width: 50px;
  height: 50px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  filter: drop-shadow(0 0 3px var(--c5)) drop-shadow(0 0 8px var(--c1));
}

.sf-cell svg {
  width: 100%;
  height: auto;
  display: block;
  fill: var(--c5);
}

/* ─── CEREMONY OVERLAY ───────────────────────────────────── */

#ceremony-overlay {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 500; /* above content, below sigil frame (999) and scanlines (1000) */
  pointer-events: none;
}

#ceremony-overlay.overlay-low {
  align-items: flex-end;
  padding-bottom: 12vh;
}

.ceremony-text {
  text-align: center;
  max-width: 600px;
  padding: 0 40px;
  pointer-events: auto;
}

/* DIVINE loading layout — morph centered, narration below */
.divine-layout {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 48px;
  pointer-events: auto;
}

#morph-slot {
  display: flex;
  align-items: center;
  justify-content: center;
}

#morph-slot #sigil-morph-svg {
  display: block;
  width: 440px;
  height: 132px;
}

#input-display {
  margin-top: 20px;
  min-height: 2em;
  border-bottom: 1px solid var(--c3);
  padding-bottom: 4px;
  color: var(--c6);
  filter: drop-shadow(0 0 8px var(--c5)) drop-shadow(0 0 20px var(--c1));
}

.input-cursor {
  display: inline-block;
  width: 0;
  border-left: 2px solid var(--c5);
  margin: 0 1px;
  animation: cursor-blink 1s step-end infinite;
}

@keyframes cursor-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

/* Spinner warp — filled sigil displacement crossfade during short waits.
   Vertically centered between mask chin and bottom sigil frame border.
   Chin ≈ 64vh + 36px; frame inner edge ≈ 100vh − 50px.
   Midpoint = (64vh + 36px + 100vh − 50px) / 2 = 82vh − 7px.
   Offset by half spinner height (50px) for centering. */
.sigil-spinner {
  position: absolute;
  top: calc(82vh - 7px - 50px);
  left: 50%;
  transform: translateX(-50%);
  width: 100px;
  height: 100px;
  display: grid;
}

.sigil-spinner svg {
  fill: var(--c5);
  height: 100%;
  width: auto;
  max-width: 100%;
  display: block;
}

.qr-container {
  max-width: 280px;
  margin: 0 auto 24px;
}
.qr-container svg {
  width: 100%;
  height: auto;
}
