/* Hi Deformance, From Your Pal Jody! */ :root {
  /* Neo-classic Japanese: a true black ground, ink-print colour, and a
     dithered stipple that does the shading a gradient would otherwise do. */
  --ink: #000000;
  --ink-2: #0a0a0b;
  --ink-3: #141215;
  --strand: #6b92b5;
  --target: #fbf26f;
  --found: #b3a96e;
  --eye: #f3c8d9;
  --finale: #ff5a01;
  --muted: #744c54;
  --paper: #f4ecd8;
  --paper-dim: #b3a96e;
  /* Stipple tiles, written in from assets/tex at boot. */
  --tex-grain-faint: url("assets/tex/grain-faint.webp");
  --tex-grain-soft: url("assets/tex/grain-soft.webp");
  --tex-grain-mid: url("assets/tex/grain-mid.webp");
  --tex-grain-dense: url("assets/tex/grain-dense.webp");
  --tex-fade-left: url("assets/tex/fade-left.webp");
  --tex-fade-right: url("assets/tex/fade-right.webp");
  --tex-fade-down: url("assets/tex/fade-down.webp");
  --tex-fade-up: url("assets/tex/fade-up.webp");
  --tex-burst: url("assets/tex/burst.webp");
  --tex-ink-grain: url("assets/tex/ink-grain-soft.webp");
  --tex-ink-fade-up: url("assets/tex/ink-fade-up.webp");
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  --font-ui: "Barlow Condensed", "Oswald", "Arial Narrow", sans-serif;
  /* Bebas Neue — the album's own display face (was Anton, which is close but
     heavier and more compressed). */
  --font-display: "Bebas Neue", "Oswald", "Arial Narrow", "Impact", sans-serif;
  /* Cormorant Garamond — the high-contrast old-style serif from the album
     sleeve, used for prose so body copy carries the record's own voice. */
  --font-serif: "Cormorant Garamond", "EB Garamond", Georgia, "Times New Roman", serif;
  --step-0: clamp(0.95rem, 0.9rem + 0.25vw, 1.1rem);
  --step-1: clamp(1rem, 0.94rem + 0.3vw, 1.18rem);
  --ease: cubic-bezier(0.22, 0.68, 0.3, 1);
  --prox: 0;
  --glow: #f3c8d9;
  --sight: 700px;
  --fog-soft: 0.58;
  --flash-peak: 0.24;
}
*, *::before, *::after {
  box-sizing: border-box;
}
html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-ui);
  font-size: var(--step-0);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}
:focus-visible {
  outline: 2px solid var(--target);
  outline-offset: 3px;
}
kbd {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 0.92em;
  line-height: 1;
  padding: 0.28em 0.5em 0.18em;
  margin: 0 0.12em;
  color: var(--target);
  background: var(--ink);
  border: 1px solid color-mix(in srgb, var(--target) 55%, transparent);
  box-shadow: inset 0 0 0 2px var(--ink), inset 0 0 0 3px color-mix(in srgb, var(--target) 30%, transparent);
}
.viewport {
  position: fixed;
  inset: 0;
  overflow: hidden;
  cursor: crosshair;
  background:
    radial-gradient(120vmax 120vmax at 50% 50%, var(--ink-2) 0%, var(--ink) 55%, #050309 100%);
}
/* Stipple on the world itself, so the texture is present the whole time you
   play. Pink-tinted grain, faint, tiled small; sits under everything via a
   pseudo-element with a fixed size so it does not move with the world. */
.fog {
  position: fixed;
  inset: 0;
  z-index: 10;
  pointer-events: none;
  background: radial-gradient(circle at 50% 50%, transparent 0, transparent calc(var(--sight) * var(--fog-soft)), color-mix(in srgb, var(--ink) 35%, transparent) calc(var(--sight) * 0.7), color-mix(in srgb, var(--ink) 75%, transparent) calc(var(--sight) * 0.9), var(--ink) var(--sight), var(--ink) 100%);
}
.world {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
  will-change: transform;
}
.world__texture {
  position: absolute;
  inset: 0;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  mix-blend-mode: screen;
  pointer-events: none;
}
.strands {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}
.strand {
  fill: none;
  stroke: var(--strand);
  stroke-width: calc(0.9px + var(--w, 0.5) * 1.6px);
  opacity: calc((0.3 + var(--w, 0.5) * 0.28) + var(--prox) * 0.34);
  transition: opacity 300ms linear;
}
.strand.strand--radial {
  stroke-width: calc(1.5px + var(--w, 0.5) * 1.8px);
  opacity: calc((0.42 + var(--w, 0.5) * 0.2) + var(--prox) * 0.3);
}
.strand--tatter {
  stroke: color-mix(in srgb, var(--strand) 80%, var(--muted));
  stroke-width: calc(0.6px + var(--w, 0.5) * 1.1px);
  opacity: calc(0.14 + var(--w, 0.5) * 0.16);
  stroke-linecap: round;
}
.strand.is-walked {
  /* Warm gold so it clearly differs from the cool web, but kept THREAD-thin —
     colour does the work, not weight. Only a hair thicker than an unwalked
     strand, no glow: a heavy glowing line read as cartoonish. */
  stroke: color-mix(in srgb, var(--target) 55%, var(--found));
  stroke-width: calc(1px + var(--w, 0.5) * 1.7px);
  opacity: calc(0.9 + var(--prox) * 0.1);
}
.strand.strand--radial.is-walked {
  stroke-width: calc(1.6px + var(--w, 0.5) * 1.9px);
}
.spider {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 5;
  width: var(--spider-size, 108px);
  height: var(--spider-size, 108px);
  pointer-events: none;
  transform-origin: 50% 50%;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  filter: drop-shadow(0 0 14px rgba(0, 0, 0, 0.85));
  will-change: transform;
}
.spider.is-crawling {
  animation: spider-cycle var(--cycle, 620ms) step-end infinite;
}
.orb {
  position: absolute;
  opacity: var(--near, 1);
  transition: opacity 420ms linear;
  top: 0;
  left: 0;
  z-index: 3;
  width: var(--orb-size, 84px);
  height: var(--orb-size, 84px);
  margin: calc(var(--orb-size, 84px) / -2);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.orb__art {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 2px 8px color-mix(in srgb, var(--ink) 85%, transparent));
  transition: filter 400ms var(--ease);
}
.orb__art--pulse, .orb__art--spin {
  animation: orb-spin calc(var(--orb-anim-duration, 5.2s) * 4) linear infinite;
}
.orb {
  animation: orb-breathe var(--orb-anim-duration, 5.2s) ease-in-out infinite;
  will-change: transform;
}
@keyframes orb-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
@keyframes orb-breathe {
  0%, 100% {
    transform: scale(calc(1 - var(--orb-pulse, 0.04) * 2));
  }
  50% {
    transform: scale(calc(1 + var(--orb-pulse, 0.04) * 2));
  }
}
.orb__art--centre {
  animation: centre-spin 26s linear infinite;
  will-change: transform;
}
.orb.orb--finale {
  animation: centre-breathe 5.2s ease-in-out infinite;
  will-change: transform;
}
@keyframes centre-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
@keyframes centre-breathe {
  0%, 100% {
    transform: scale(0.94);
  }
  50% {
    transform: scale(1.06);
  }
}
.orb--finale.is-locked .orb__art--centre {
  animation-duration: 90s;
}
.orb.orb--finale.is-locked {
  animation-duration: 11s;
}
.orb--finale.is-open .orb__art--centre {
  animation-duration: 14s;
}
.orb.orb--finale.is-open {
  animation-duration: 3.4s;
}
.orb__spiral {
  position: relative;
  grid-area: 1 / 1;
  width: 190%;
  height: 190%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='s' x='-30%25' y='-30%25' width='160%25' height='160%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.022' numOctaves='4' seed='7' result='n'/%3E%3CfeDisplacementMap in='SourceGraphic' in2='n' scale='34' xChannelSelector='R' yChannelSelector='G' result='d'/%3E%3CfeGaussianBlur in='d' stdDeviation='5.5'/%3E%3C/filter%3E%3Cg filter='url(%23s)'%3E%3Cpath d='M100 100L101 100L102 101L102 102L102 103L102 105L100 106L99 107L97 107L94 107L92 106L90 104L88 102L87 98L87 95L88 91L90 87L93 84L97 82L101 81L106 81L112 82L116 85L121 89L124 94L126 100L126 107L124 113L121 120L116 125L109 129L102 132L94 132L86 131L78 127L71 121L66 114L62 105L61 95L63 85L67 76L73 68L82 61L92 57L103 55L114 56L125 60L135 67L143 76L149 88L151 100L150 113L147 126L139 137L130 147L117 153L104 157L89 157L75 154L62 146L50 136L42 123L37 108L36 92L39 76L46 61L57 48L71 38L87 32L104 30L122 32L139 39L154 50L165 64L173 81L177 100L175 119L169 138L158 155L143 168L125 178L105 183L84 182L64 177L45 166L30 151L18 132L12 111L11 89L15 67L26 46' fill='none' stroke='%23070a10' stroke-width='26' stroke-linecap='round' opacity='0.85'/%3E%3Cpath d='M100 100L101 100L102 101L102 102L102 103L102 105L100 106L99 107L97 107L94 107L92 106L90 104L88 102L87 98L87 95L88 91L90 87L93 84L97 82L101 81L106 81L112 82L116 85L121 89L124 94L126 100L126 107L124 113L121 120L116 125L109 129L102 132L94 132L86 131L78 127L71 121L66 114L62 105L61 95L63 85L67 76L73 68L82 61L92 57L103 55L114 56L125 60L135 67L143 76L149 88L151 100L150 113L147 126L139 137L130 147L117 153L104 157L89 157L75 154L62 146L50 136L42 123L37 108L36 92L39 76L46 61L57 48L71 38L87 32L104 30L122 32L139 39L154 50L165 64L173 81L177 100L175 119L169 138L158 155L143 168L125 178L105 183L84 182L64 177L45 166L30 151L18 132L12 111L11 89L15 67L26 46' fill='none' stroke='%231a1f2b' stroke-width='13' stroke-linecap='round' opacity='0.7'/%3E%3Cpath d='M100 100L101 100L102 101L102 102L102 103L102 105L100 106L99 107L97 107L94 107L92 106L90 104L88 102L87 98L87 95L88 91L90 87L93 84L97 82L101 81L106 81L112 82L116 85L121 89L124 94L126 100L126 107L124 113L121 120L116 125L109 129L102 132L94 132L86 131L78 127L71 121L66 114L62 105L61 95L63 85L67 76L73 68L82 61L92 57L103 55L114 56L125 60L135 67L143 76L149 88L151 100L150 113L147 126L139 137L130 147L117 153L104 157L89 157L75 154L62 146L50 136L42 123L37 108L36 92L39 76L46 61L57 48L71 38L87 32L104 30L122 32L139 39L154 50L165 64L173 81L177 100L175 119L169 138L158 155L143 168L125 178L105 183L84 182L64 177L45 166L30 151L18 132L12 111L11 89L15 67L26 46' fill='none' stroke='%2333394a' stroke-width='5' stroke-linecap='round' opacity='0.55'/%3E%3C/g%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  opacity: 0.7;
  filter: blur(1.5px);
  animation: spiral-turn 44s linear infinite reverse;
  pointer-events: none;
  will-change: transform;
}
.orb__spiral::after {
  content: "";
  position: absolute;
  inset: -18%;
  background-image: inherit;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  opacity: 0.5;
  filter: blur(4px);
  animation: spiral-turn 78s linear infinite;
}
.orb.is-found .orb__spiral {
  opacity: 0.26;
  animation-duration: 140s;
}
.orb.is-in-reach .orb__spiral {
  opacity: 0.92;
  animation-duration: 22s;
}
@keyframes spiral-turn {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
.orb__index {
  grid-area: 1 / 1;
  align-self: end;
  justify-self: center;
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  line-height: 1.35;
  white-space: nowrap;
  color: var(--ink);
  background: var(--target);
  border-radius: 0;
  padding: 0.08em 0.45em 0;
  transform: translateY(62%);
}
.orb.is-in-reach {
  animation: none;
  transform: scale(calc(1 + var(--orb-pulse, 0.04) * 2.6));
  transition: transform 420ms cubic-bezier(0.2, 1.1, 0.35, 1);
}
.orb.is-in-reach .orb__art {
  filter: drop-shadow(0 2px 10px color-mix(in srgb, var(--ink) 90%, transparent));
}
.orb.is-found .orb__art {
  filter: drop-shadow(0 0 12px color-mix(in srgb, var(--found) 55%, transparent)) saturate(0.5) brightness(0.8);
}
.orb.is-found {
  animation-duration: 22s;
}
.orb.is-found .orb__art {
  animation-duration: 180s;
}
.orb.is-found .orb__index {
  background: var(--found);
}
.orb--finale.is-locked .orb__art {
  filter: grayscale(1) brightness(0.35);
  animation-duration: calc(var(--orb-anim-duration, 3.4s) * 3.5);
}
.orb--finale.is-open .orb__art {
  filter: drop-shadow(0 0 46px color-mix(in srgb, var(--finale) 85%, transparent));
}
.orb--finale .orb__art--centre {
  animation-name: centre-spin;
}
.eye {
  position: absolute;
  opacity: var(--near, 0);
  top: 0;
  left: 0;
  z-index: 2;
  width: var(--eye-size, 18px);
  height: var(--eye-size, 18px);
  margin: calc(var(--eye-size, 18px) / -2);
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  background: radial-gradient(circle at 35% 30%, #fff 0%, color-mix(in srgb, var(--eye) 85%, white) 35%, color-mix(in srgb, var(--eye) 60%, transparent) 100%);
  box-shadow: 0 0 14px color-mix(in srgb, var(--eye) 70%, transparent);
  animation: shimmer 3s ease-in-out infinite;
  pointer-events: none;
}
.eye--art {
  border-radius: 0;
  background: none;
  box-shadow: none;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--eye) 55%, transparent));
  animation: eye-drift var(--eye-spin, 22s) linear infinite, shimmer 3s ease-in-out infinite;
}
@keyframes eye-drift {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
@keyframes shimmer {
  0%, 100% {
    opacity: calc(var(--near, 0) * 0.7);
  }
  50% {
    opacity: var(--near, 0);
  }
}
.eye.is-taken {
  opacity: 0;
  transform: rotate(-45deg) scale(0.2);
  transition: opacity 500ms var(--ease), transform 500ms var(--ease);
}
.eye--art.is-taken {
  animation: none;
  transform: scale(0.2);
}
.prompt {
  font-family: var(--font-ui);
  position: fixed;
  left: 50%;
  bottom: max(6vh, 4rem);
  transform: translateX(-50%);
  margin: 0;
  padding: 0.5rem 1rem;
  border: 1px solid color-mix(in srgb, var(--strand) 28%, transparent);
  border-radius: 0;
  background: color-mix(in srgb, var(--ink) 78%, transparent);
  backdrop-filter: blur(6px);
  color: var(--paper-dim);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 0.72rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms var(--ease);
  z-index: 20;
}
.prompt.is-visible {
  opacity: 1;
}
.gate {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  background:
    radial-gradient(100vmax 80vmax at 50% 40%, var(--ink-2) 0%, #03050A 70%);
  transition: opacity 600ms var(--ease);
}
.gate.is-open {
  opacity: 0;
  pointer-events: none;
}
.gate__inner {
  display: grid;
  gap: 0.9rem;
  justify-items: center;
  width: min(24rem, 100%);
  text-align: center;
}
.gate.is-wrong .gate__inner {
  animation: gate-shake 340ms ease-out;
}
@keyframes gate-shake {
  0%, 100% {
    transform: translateX(0);
  }
  20% {
    transform: translateX(-8px);
  }
  45% {
    transform: translateX(7px);
  }
  70% {
    transform: translateX(-4px);
  }
}
.gate__heading {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2rem, 1rem + 5vw, 3.4rem);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 0.9;
  color: var(--finale);
}
.gate__body {
  margin: 0 0 0.4rem;
  font-family: var(--font-ui);
  font-size: 1.02rem;
  letter-spacing: 0.03em;
  color: var(--paper-dim);
}
.gate__input {
  width: 100%;
  padding: 0.8rem 0.9rem;
  font-family: var(--font-ui);
  font-size: 1.1rem;
  letter-spacing: 0.16em;
  text-align: center;
  color: var(--paper);
  background: color-mix(in srgb, var(--ink) 70%, transparent);
  border: 1px solid color-mix(in srgb, var(--strand) 42%, transparent);
  border-radius: 0;
}
.gate__input:focus {
  outline: 2px solid var(--finale);
  outline-offset: 2px;
}
.gate__submit {
  width: 100%;
  padding: 0.8rem 1.6rem 0.7rem;
  font-family: var(--font-display);
  font-size: 1.15rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--paper);
  background: var(--finale);
  border: 0;
  border-radius: 0;
  cursor: pointer;
}
.gate__submit:hover {
  background: color-mix(in srgb, var(--finale) 80%, var(--target));
  color: var(--ink);
}
.gate__error {
  margin: 0;
  min-height: 1.4rem;
  font-family: var(--font-ui);
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  color: var(--eye);
  opacity: 0;
}
.gate__error.is-visible {
  opacity: 1;
}
.is-gated .splash {
  pointer-events: none;
}
.splash {
  position: fixed;
  inset: 0;
  height: 100dvh;
  z-index: 60;
  display: grid;
  place-items: center;
  overflow: hidden;
  isolation: isolate;
}
.splash__panes {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 200vmax;
  height: 200vmax;
  transform: translate(-50%, -50%) rotate(var(--cut-angle, -32deg));
  transform-origin: 50% 50%;
}
.splash__pane {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120vmax 90vmax at 50% 24%, color-mix(in srgb, var(--strand) 16%, var(--ink-2)) 0%, var(--ink) 58%, #03050A 100%);
  transition: transform var(--split, 900ms) cubic-bezier(0.6, 0, 0.3, 1);
  will-change: transform;
}
.splash__pane--l {
  clip-path: inset(0 0 50% 0);
}
.splash__pane--r {
  clip-path: inset(50% 0 0 0);
}
.splash__web {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.splash__web path {
  fill: none;
  stroke: var(--strand);
  stroke-width: 0.35;
  stroke-linejoin: miter;
  opacity: 0.2;
}
.splash__web .w-radial {
  stroke-width: 0.5;
  opacity: 0.26;
}
.splash__drop {
  position: absolute;
  top: 0;
  left: 72%;
  z-index: 2;
  transform: translateY(-100%);
  animation: spider-drop 1.9s cubic-bezier(0.34, 0.8, 0.3, 1) 0.5s forwards;
  pointer-events: none;
}
.splash__pendulum {
  transform-origin: 50% 0;
  animation: spider-swing 5.5s ease-in-out 2.4s infinite alternate;
}
.splash__thread {
  display: block;
  width: 1px;
  height: 30vh;
  margin: 0 auto;
  background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--strand) 70%, transparent) 14%, color-mix(in srgb, var(--strand) 85%, transparent));
}
.splash__hangspider {
  display: block;
  width: 224px;
  height: 224px;
  margin: -26px auto 0;
  background-image: url("../assets/art/spider1.webp");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  transform: rotate(0deg);
  filter: drop-shadow(0 8px 22px rgba(0, 0, 0, 0.85));
}
@keyframes spider-drop {
  0% {
    transform: translateY(-100%);
  }
  72% {
    transform: translateY(4%);
  }
  88% {
    transform: translateY(-2%);
  }
  100% {
    transform: translateY(0);
  }
}
@keyframes spider-swing {
  from {
    transform: rotate(-3.4deg);
  }
  to {
    transform: rotate(3.4deg);
  }
}
.splash__rain {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  transition: opacity 500ms linear;
}
.splash__flash {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background:
    radial-gradient(140vmax 90vmax at 62% -10%, color-mix(in srgb, var(--glow) 88%, var(--strand)) 0%, transparent 62%);
  mix-blend-mode: screen;
}
.splash__flash.is-strike {
  animation: strike 900ms ease-out;
}
.splash__flash.is-strike-double {
  animation: strike-double 1500ms ease-out;
}
@keyframes strike {
  0% {
    opacity: 0;
  }
  8% {
    opacity: var(--flash-peak, 0.24);
  }
  40% {
    opacity: calc(var(--flash-peak, 0.24) * 0.18);
  }
  100% {
    opacity: 0;
  }
}
@keyframes strike-double {
  0% {
    opacity: 0;
  }
  5% {
    opacity: calc(var(--flash-peak, 0.24) * 0.72);
  }
  20% {
    opacity: 0;
  }
  33% {
    opacity: var(--flash-peak, 0.24);
  }
  62% {
    opacity: calc(var(--flash-peak, 0.24) * 0.16);
  }
  100% {
    opacity: 0;
  }
}
body.no-flash .splash__flash {
  display: none;
}
/* Ordered-dither stipple, not noise. The reference's whole identity is
   screen-print halftone: regular dots at varying density, reading as ink
   shading. feTurbulence noise reads as television static and was the single
   most "generic dark UI" element on the page. */
.splash__grain {
  position: absolute;
  inset: 0;
  /* Above the vignette (z-2), which was painting black over it at the edges. */
  z-index: 4;
  pointer-events: none;
  /* Even faint grain across everything, plus a heavier tide rising from the
     foot of the screen. The pink tint comes from the tile colour underneath. */
  background-image: var(--tex-fade-up), var(--tex-grain-soft);
  background-repeat: repeat, repeat;
  background-size: 220px 62%, 150px 150px;
  background-position: bottom, top left;
  opacity: 0.7;
  mix-blend-mode: screen;
}
/* A second stipple field, orange, bleeding in from the right edge — the
   two-tone split of the reference image rendered as texture rather than a
   hard colour block. */
.splash__grain::after {
  content: "";
  position: absolute;
  inset: 0;
  /* fade-right is pink dots; tint to orange with a blend-friendly filter.
     brightness(0) first makes them solid black, THEN the sepia/hue chain has
     a non-black source to work from. */
  background-image: var(--tex-fade-right);
  background-size: 42vw 100%;
  background-repeat: no-repeat;
  background-position: right;
  opacity: 0.7;
  filter: brightness(0.4) sepia(1) saturate(6) hue-rotate(-8deg) brightness(1.6);
}
.splash__vignette {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    radial-gradient(115% 95% at 50% 44%, transparent 0%, transparent 40%, rgba(0, 0, 0, 0.6) 78%, rgba(0, 0, 0, 0.96) 100%);
}
.splash__inner {
  position: relative;
  z-index: 5;
  width: min(36rem, 92vw);
  max-height: 100dvh;
  padding: clamp(1rem, 3vh, 2rem) 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(0.5rem, 1.6vh, 1.4rem);
  text-align: center;
  transition: opacity 260ms var(--ease), transform 420ms var(--ease);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.splash__logo {
  width: min(20rem, 62vw);
  height: clamp(3rem, 13vmin, 8rem);
  flex: none;
  margin: 0 auto;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  filter: drop-shadow(0 0 24px rgba(0, 0, 0, 0.6));
}
.splash__titlewrap {
  position: relative;
  flex: none;
}
/*/* Paint drips hanging off the wordmark. Each is a thin column with a rounded
   bead at the tip, growing downward on a slow loop with a long pause — wet
   paint gathering and running, not a steady drizzle. Staggered so they never
   move in unison. prefers-reduced-motion freezes them part-way down.
.splash__drips {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 0;
  pointer-events: none;
}
.drip {
  position: absolute;
  top: -9px;
  width: 3px;
  height: 0;
  border-radius: 0 0 3px 3px;
  transform-origin: top;
  animation: drip-run var(--drip-dur, 9s) var(--drip-delay, 0s) ease-in;
  animation-fill-mode: forwards;
	z-index: -1;
}
.drip::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 9px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  transform: translateX(-50%);
  background: inherit;	z-index: -1;

}
.drip--1 {
  left: 14%;
  background: var(--target);
  --drip-dur: 8s;
  --drip-delay: 0.4s;
  --drip-max: 26px;
}
.drip--2 {
  left: 33%;
  background: var(--target);
  --drip-dur: 11s;
  --drip-delay: 3.1s;
  --drip-max: 20px;
}
.drip--3 {
  left: 52%;
  background: var(--target);
  --drip-dur: 9.5s;
  --drip-delay: 1.7s;
  --drip-max: 28px;
}
.drip--4 {
  left: 71%;
  background: var(--target);
  --drip-dur: 12s;
  --drip-delay: 5.2s;
  --drip-max: 26px;
}
.drip--5 {
  left: 88%;
  background: var(--target);
  --drip-dur: 10s;
  --drip-delay: 2.4s;
  --drip-max: 22px;
}
@keyframes drip-run {
  /* Long dry pause, a swelling bead, then a slow run and a fade as it thins. 
  0%, 18% {
    height: 0;
    opacity: 0;
  }
  24% {
    height: 4px;
    opacity: 0.9;
  }
  70% {
    height: var(--drip-max, 40px);
    opacity: 0.85;
  }
  100% {
    height: var(--drip-max, 40px);
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .drip {
    animation: none;
    height: calc(var(--drip-max, 40px) * 0.5);
    opacity: 0.7;
  }
}*/
.splash__title {
  margin: 0;
  flex: none;
  font-family: var(--font-display);
  font-size: min(clamp(2rem, 1rem + 8vw, 6rem), 13vh);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.86;
  text-wrap: balance;
  color: var(--target);
  text-shadow: 0 0 34px rgba(0, 0, 0, 0.9);
}
.splash__body {
  margin: 0 auto;
  max-width: 34rem;
  flex: none;
  font-family: var(--font-serif);
  font-size: clamp(1.15rem, 1rem + 0.6vw, 1.5rem);
  line-height: 1.45;
  letter-spacing: 0;
  color: color-mix(in srgb, var(--paper) 90%, transparent);
}
.splash__body em {
  font-style: normal;
  color: var(--target);
  letter-spacing: 0.04em;
}
.splash__enter:hover {
  box-shadow: 0 10px 34px color-mix(in srgb, var(--finale) 50%, transparent);
}
.splash__safety {
  margin: 0;
  flex: none;
}
.splash__safety-btn {
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  padding: 0.6rem 0.9rem 0.5rem;
  line-height: 1;
  color: var(--ink);
  background: color-mix(in srgb, var(--muted) 80%, var(--paper));
  border: 1px solid color-mix(in srgb, var(--muted) 80%, var(--paper));
}
.splash__safety-btn:hover {
  color: color-mix(in srgb, var(--muted) 70%, var(--paper));
  background: none;
}
.splash__safety-btn[aria-pressed="true"] {
  color: var(--ink);
  background: var(--eye);
  border-color: var(--eye);
}
.splash__keys {
  margin: 0;
  flex: none;
  font-family: var(--font-serif);
  font-size: clamp(0.95rem, 0.85rem + 0.3vw, 1.2rem);
  letter-spacing: 0;
  text-transform: none;
  color: color-mix(in srgb, var(--paper) 70%, var(--muted));
  line-height: 2.1;
}
.splash__sep {
  display: inline-block;
  width: 1px;
  height: 0.9em;
  margin: 0 0.7em -0.05em;
  background: color-mix(in srgb, var(--target) 45%, transparent);
  vertical-align: middle;
}
.splash__blade {
  position: absolute;
  top: 50%;
  left: 0;
  z-index: 4;
  width: 100%;
  height: 3px;
  margin-top: -1.5px;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: linear-gradient(to right, transparent, var(--glow) 8%, var(--glow) 92%, transparent);
  box-shadow: 0 0 26px 5px color-mix(in srgb, var(--glow) 65%, transparent);
  opacity: 0;
  pointer-events: none;
}
.splash.is-cutting .splash__blade {
  animation: blade var(--cut, 340ms) cubic-bezier(0.85, 0, 0.15, 1) forwards;
}
@keyframes blade {
  0% {
    transform: scaleX(0);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    transform: scaleX(1);
    opacity: 1;
  }
}
.splash.is-cutting .splash__inner {
  opacity: 0;
  transform: scale(0.97);
}
.splash.is-split .splash__pane--l {
  transform: translateY(-105%) translateX(-4%) rotate(-2deg);
}
.splash.is-split .splash__pane--r {
  transform: translateY(105%) translateX(4%) rotate(2deg);
}
.splash.is-split .splash__rain {
  opacity: 0;
}
.splash.is-split .splash__blade {
  opacity: 0;
  transition: opacity 300ms linear;
}
.is-revealing .viewport {
  animation: settle 1500ms cubic-bezier(0.16, 0.9, 0.28, 1) both;
}
.is-revealing .strands {
  animation: ink-in 1700ms ease-out 260ms both;
}
.is-revealing .spider {
  animation: arrive 800ms cubic-bezier(0.2, 1.3, 0.4, 1) 900ms both;
}
.is-revealing .hud__counts > *, .is-revealing .hud__actions > * {
  animation: fade-up 620ms var(--ease) both;
}
.is-revealing .hud__counts > *:nth-child(1) {
  animation-delay: 1500ms;
}
.is-revealing .hud__counts > *:nth-child(2) {
  animation-delay: 1600ms;
}
.is-revealing .hud__actions > *:nth-child(1) {
  animation-delay: 1700ms;
}
.is-revealing .hud__actions > *:nth-child(2) {
  animation-delay: 1780ms;
}
.is-revealing .hud__actions > *:nth-child(3) {
  animation-delay: 1860ms;
}
.is-revealing .pad, .is-revealing .action {
  animation: fade-up 620ms var(--ease) 1900ms both;
}
.is-revealing .fog {
  animation: fog-close 2000ms ease-in-out both;
}
@keyframes settle {
  from {
    transform: translate3d(0, 0, 0) scale(1.08);
  }
  to {
    transform: translate3d(0, 0, 0) scale(1);
  }
}
@keyframes ink-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes arrive {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes fog-close {
  from {
    opacity: 0;
  }
  60% {
    opacity: 0.4;
  }
  to {
    opacity: 1;
  }
}
.hud {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  padding: max(1rem, env(safe-area-inset-top)) 1.2rem 1rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 700ms var(--ease) 300ms;
}
.hud.is-visible {
  opacity: 1;
  pointer-events: auto;
}
.hud__counts {
  display: flex;
  gap: 1.6rem;
}
.hud__stat {
  display: grid;
  gap: 0.2rem;
}
.hud__label {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  letter-spacing: 0.02em;
  text-transform: none;
  color: color-mix(in srgb, var(--target) 78%, var(--paper));
}
.hud__value {
  font-size: var(--step-1);
  font-weight: 500;
  color: var(--target);
  font-variant-numeric: tabular-nums;
}
.hud__actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.hud__btn {
  --tint: var(--strand);
  font-size: 0.86rem;
  letter-spacing: 0.12em;
  padding: 0.62rem 0.9rem 0.52rem;
  line-height: 1;
  color: var(--ink);
  background: var(--tint);
  border: 1px solid var(--tint);
}
.hud__btn:hover {
  color: var(--tint);
  background: color-mix(in srgb, var(--ink-2) 82%, transparent);
}
.hud__btn--blue {
  --tint: var(--strand);
}
.hud__btn--green {
  --tint: var(--target);
}
.hud__btn--pink {
  --tint: var(--eye);
}
.hud__btn--red {
  --tint: var(--finale);
}
/* Filled with a light tint, so the inset frame is ink. */
.hud__btn {
  --frame: var(--ink);
}
.hud__btn--red {
  margin-left: 0.5rem;
}
.btn, .hud__btn, .board__btn, .splash__safety-btn, .action, .reveal__cta, .presave__cta, .board__close {
  --frame: var(--ink);
  position: relative;
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  border-radius: 0;
  cursor: pointer;
  transition: background-color 160ms var(--ease), color 160ms var(--ease), border-color 160ms var(--ease), transform 160ms var(--ease);
}
/* Offset frame: a border floating a few px inside the button edge, drawn on a
   pseudo-element so it sits over the fill without affecting layout. This is the
   double-framed stamp look — filled block, inset keyline. */
.btn::before, .hud__btn::before, .board__btn::before, .splash__safety-btn::before, .action::before, .reveal__cta::before, .presave__cta::before, .board__close::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 2px solid var(--frame);
  opacity: 0.55;
  pointer-events: none;
  transition: opacity 160ms var(--ease), inset 160ms var(--ease);
}
.btn:hover::before, .hud__btn:hover::before, .board__btn:hover:not([disabled])::before, .action:hover::before, .reveal__cta:hover::before, .presave__cta:hover::before, .board__close:hover::before {
  inset: 5px;
  opacity: 0.9;
}
.board__btn[disabled]::before {
  opacity: 0.2;
}
.btn--danger {
  font-size: min(clamp(1rem, 0.85rem + 0.6vw, 1.5rem), 4.2vh);
  letter-spacing: 0.14em;
  padding: clamp(0.55rem, 1.4vh, 0.75rem) clamp(1.4rem, 5vw, 2.4rem) clamp(0.45rem, 1.2vh, 0.65rem);
  color: var(--paper);
  background: var(--finale);
  border: 0;
  line-height: 1;
}
.btn--danger:hover {
  transform: translateY(-2px);
  background: color-mix(in srgb, var(--finale) 82%, var(--target));
  color: var(--ink);
}
.btn--danger:active {
  transform: translateY(0);
}
.btn--primary {
  font-size: clamp(1.1rem, 0.9rem + 0.6vw, 1.5rem);
  letter-spacing: 0.16em;
  padding: 0.7rem 2.6rem 0.6rem;
  color: var(--ink);
  background: var(--target);
  border: 0;
  line-height: 1;
}
.btn--primary:hover {
  transform: translateY(-2px);
  background: var(--glow);
}
.btn--primary:active {
  transform: translateY(0);
}
.cryptogram {
  font-family: var(--font-mono);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.7em;
  row-gap: 0.35em;
  font-size: clamp(0.68rem, 0.52rem + 0.5vw, 0.86rem);
}
.cryptogram__word {
  display: inline-flex;
  gap: 0.12em;
  align-items: baseline;
  white-space: nowrap;
}
.cryptogram__punct {
  color: var(--paper-dim);
}
.cryptogram__cell {
  display: inline-block;
  min-width: 0.85em;
  text-align: center;
  color: var(--paper-dim);
  border-bottom: 1px solid color-mix(in srgb, var(--strand) 30%, transparent);
  transition: color 300ms var(--ease), border-color 300ms var(--ease);
}
.cryptogram__cell.is-solved {
  color: var(--target);
  border-bottom-color: transparent;
  font-weight: 600;
}
.cryptogram__cell.is-flipping {
  /* No fill mode: the moment the animation ends the cell reverts to whatever
     .is-solved specifies. An earlier version ended the keyframes on
     color: var(--target) with `both`, which PINNED every just-revealed letter
     yellow forever — the last letter collected stayed highlighted across every
     title. The flash now lives only in the middle of the flip. */
  animation: flip 520ms var(--ease);
  animation-delay: var(--flip-delay, 0ms);
}
@keyframes flip {
  0% {
    transform: rotateX(0deg);
  }
  45% {
    transform: rotateX(90deg);
    color: var(--target);
  }
  100% {
    transform: rotateX(0deg);
  }
}
.cryptogram--large {
  font-size: clamp(1.05rem, 0.7rem + 1.6vw, 1.9rem);
  letter-spacing: 0.03em;
  justify-content: center;
}
.board {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  padding: clamp(1.2rem, 4vh, 2.4rem) clamp(1rem, 5vw, 3rem) max(clamp(1.2rem, 4vh, 2.4rem), env(safe-area-inset-bottom));
  background: var(--finale);
  transform: translateY(101%);
  transition: transform 480ms cubic-bezier(0.5, 0, 0.2, 1);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.board.is-open {
  transform: none;
}
.board__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  width: min(58rem, 100%);
  margin: 0 auto clamp(1rem, 3vh, 2rem);
  flex: none;
}
.board__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  font-size: clamp(1.8rem, 1rem + 4vw, 3.6rem);
  line-height: 0.9;
  color: var(--ink);
}
.board__close {
  position: relative;
  font-family: var(--font-display);
  font-size: 1rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.66rem 1.3rem 0.56rem;
  background: var(--target);
  border: 0;
  color: var(--ink);
  cursor: pointer;
  flex: none;
  transition: background-color 160ms var(--ease), color 160ms var(--ease);
}
.board__close:hover {
  background: none;
  color: var(--target);
}
.board__list {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  width: min(58rem, 100%);
  display: grid;
  gap: 0.4rem;
  flex: 1;
  align-content: start;
}
.board__row {
  display: grid;
  grid-template-columns: 2.4rem 1fr auto;
  gap: 1rem;
  align-items: center;
  padding: 0.6rem 0 0.6rem 0.8rem;
  border-left: 3px solid transparent;
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 22%, transparent);
}
.board__row:last-child {
  border-bottom: 0;
}
.board__row.is-found {
  border-left-color: var(--ink);
}
.board__num {
  font-family: var(--font-display);
  font-size: 1.15rem;
  letter-spacing: 0.04em;
  color: color-mix(in srgb, var(--ink) 78%, var(--finale));
}
.board__row.is-found .board__num {
  color: var(--ink);
}
/* Unsolved: dark, regular weight, underlined. Still fully readable, because
   the ciphertext is the puzzle — a player has to be able to run frequency
   analysis on it. */
.board .cryptogram__cell {
  color: color-mix(in srgb, var(--ink) 90%, var(--finale));
  font-weight: 400;
  border-bottom-color: color-mix(in srgb, var(--ink) 45%, transparent);
}
/* Solved: WHITE, and heavy.
   These two states were previously both near-black — 1.09:1 apart, which is
   visually identical. A player could not tell a decrypted letter from
   ciphertext, so the board looked like it was repeating letters at random.
   Light-on-dark versus dark-on-light is the only difference that survives a
   glance across twelve rows. */
/* A decrypted letter is stamped: paper glyph on its own black chip. This is
   the only way to make solved unmistakable from unsolved on a mid-luminance
   orange, where dark-on-orange and light-on-orange are too close to each
   other. It also reads as a hanko stamp, which suits the theme. */
.board .cryptogram__cell.is-solved {
  color: var(--paper);
  font-weight: 700;
  background: var(--ink);
  border-bottom-color: transparent;
  padding: 0.05em 0.16em;
  margin: 0 0.02em;
}
/* Floor raised to 19.2px so the bold solved letters clear the WCAG
   large-text threshold (18.66px bold) at every viewport width. */
.board .cryptogram {
  font-size: clamp(1.2rem, 0.9rem + 0.8vw, 1.5rem);
}
.board .cryptogram--large {
  font-size: 1rem;
}
.board__controls {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}
.board__btn {
  font-family: var(--font-display);
  font-size: 0.92rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.62rem 0.95rem 0.52rem;
  line-height: 1;
  border-radius: 0;
  cursor: pointer;
  transition: background-color 160ms var(--ease), color 160ms var(--ease), opacity 160ms var(--ease);
}
.board__btn--listen {
  --frame: var(--target);
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--target);
}
.board__btn--listen:hover:not([disabled]) {
  background: none;
  color: var(--ink);
}
.board__btn--listen.is-playing {
  background: var(--target);
  border-color: var(--target);
  color: var(--ink);
}
.board__btn--listen[disabled] {
  border-color: color-mix(in srgb, var(--ink) 40%, transparent);
  color: color-mix(in srgb, var(--ink) 78%, transparent);
  cursor: not-allowed;
}
.board__btn--stop {
  --frame: var(--eye);
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--eye);
}
.board__btn--stop:hover:not([disabled]) {
  background: none;
  color: var(--ink);
}
.board__btn--stop[disabled] {
  border-color: color-mix(in srgb, var(--ink) 32%, transparent);
  background: none;
  color: color-mix(in srgb, var(--ink) 72%, transparent);
  cursor: not-allowed;
}
.reveal__controls {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
  margin-top: 1.8rem;
}
.reveal__controls .board__btn--listen {
  --frame: var(--ink);
  border-color: var(--found);
  background: var(--found);
  color: var(--ink);
}
.reveal__controls .board__btn--listen:hover:not([disabled]) {
  background: none;
  color: var(--found);
}
.reveal__controls .board__btn--listen.is-playing {
  background: var(--found);
  color: var(--ink);
}
.reveal__controls .board__btn--stop {
  --frame: var(--ink);
  border-color: var(--eye);
  background: var(--eye);
  color: var(--ink);
}
.reveal__controls .board__btn--stop:hover:not([disabled]) {
  background: none;
  color: var(--eye);
}
.reveal__controls .board__btn--stop[disabled] {
  border-color: color-mix(in srgb, var(--muted) 40%, transparent);
  color: color-mix(in srgb, var(--muted) 70%, transparent);
}
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  background: color-mix(in srgb, #040207 82%, transparent);
  backdrop-filter: blur(10px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 320ms var(--ease);
}
.modal.is-open {
  opacity: 1;
  pointer-events: auto;
}
.modal__panel {
  position: relative;
  width: min(38rem, 100%);
  padding: 2.6rem 2.2rem 2.2rem;
  background: var(--ink-2);
  border: 1px solid color-mix(in srgb, var(--strand) 26%, transparent);
  border-radius: 0;
  transform: translateY(14px) scale(0.98);
  transition: transform 380ms var(--ease);
}
.modal.is-open .modal__panel {
  transform: none;
}
.modal__close {
  position: absolute;
  top: 0.8rem;
  right: 0.9rem;
  width: 2.2rem;
  height: 2.2rem;
  display: grid;
  place-items: center;
  font-size: 1.3rem;
  line-height: 1;
  background: var(--target);
  border: 0;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 160ms var(--ease), color 160ms var(--ease);
}
.modal__close::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 2px solid var(--ink);
  opacity: 0.55;
  pointer-events: none;
  transition: opacity 160ms var(--ease), inset 160ms var(--ease);
}
.modal__close:hover {
  background: none;
  color: var(--target);
}
.modal__close:hover::before {
  inset: 5px;
  opacity: 0.9;
}
.modal__body {
  max-height: min(72vh, 40rem);
  overflow-y: auto;
}
.reveal {
  text-align: center;
}
/* Roughly half the splash size. It is a signature here, not a title — the
   heading below it carries the announcement. */
.reveal__logo {
  width: min(11rem, 46vw);
  height: clamp(1.8rem, 6vmin, 3.4rem);
  margin: 0 auto 1.2rem;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  filter: drop-shadow(0 0 14px rgba(0, 0, 0, 0.55));
}
.reveal--locked .reveal__eyebrow {
  color: var(--muted);
}
.reveal--locked {
  opacity: 0.94;
}
.reveal--finale .reveal__eyebrow {
  color: var(--finale);
}
.reveal--finale .reveal__heading {
  color: var(--target);
}
.orb__seal {
  grid-area: 1 / 1;
  width: 62%;
  height: 62%;
  pointer-events: none;
  background:
    linear-gradient(45deg, transparent 46%, var(--muted) 46%, var(--muted) 54%, transparent 54%), linear-gradient(-45deg, transparent 46%, var(--muted) 46%, var(--muted) 54%, transparent 54%);
  opacity: 0.75;
  transition: opacity 500ms var(--ease);
}
.orb--finale.is-open .orb__seal {
  opacity: 0;
}
.reveal__eyebrow {
  margin: 0 0 1.2rem;
  font-size: 0.66rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--found);
}
.reveal__heading {
  margin: 0 0 1rem;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.6rem, 1.2rem + 2vw, 2.4rem);
}
.reveal__hint, .reveal__body {
  margin: 1.4rem 0 0;
  font-family: var(--font-serif);
  font-size: 1.4rem;
  line-height: 1.45;
  letter-spacing: 0;
  color: color-mix(in srgb, var(--paper) 88%, transparent);
}
.reveal__play {
  margin-top: 1.8rem;
  min-width: 10rem;
  padding: 0.95rem 2rem 0.85rem;
  font-family: var(--font-display);
  font-size: 1.1rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--found);
  background: none;
  border: 1px solid color-mix(in srgb, var(--found) 55%, transparent);
  border-radius: 0;
  cursor: pointer;
  transition: background-color 160ms var(--ease), color 160ms var(--ease);
}
.reveal__play:hover {
  color: var(--ink);
  background: var(--found);
}
.reveal__play.is-playing {
  color: var(--ink);
  background: var(--target);
  border-color: var(--target);
}
.reveal__play.is-playing:hover {
  background: var(--paper);
}
.reveal__cta {
  display: inline-block;
  margin-top: 1.8rem;
  padding: 1rem 2.4rem 0.9rem;
  background: var(--finale);
  color: var(--ink);
  text-decoration: none;
  letter-spacing: 0.14em;
  font-size: 1.15rem;
  line-height: 1;
}
.reveal__cta:hover {
  background: var(--target);
}
.reveal__body--sub {
  margin-top: 0.4rem;
  color: color-mix(in srgb, var(--paper-dim) 78%, transparent);
}
.presave {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  margin-top: 1.8rem;
}
.presave__email {
  flex: 1 1 14rem;
  min-width: 0;
  padding: 0.75rem 0.9rem;
  font-family: var(--font-ui);
  font-size: 1rem;
  color: var(--paper);
  background: color-mix(in srgb, var(--ink) 70%, transparent);
  border: 1px solid color-mix(in srgb, var(--strand) 40%, transparent);
  border-radius: 0;
}
.presave__email::placeholder {
  color: color-mix(in srgb, var(--muted) 70%, var(--paper-dim));
}
.presave__email:focus {
  outline: 2px solid var(--finale);
  outline-offset: 2px;
}
.presave__cta {
  flex: 0 0 auto;
  position: relative;
  padding: 0.95rem 1.6rem 0.85rem;
  font-family: var(--font-display);
  font-size: 1.05rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--paper);
  background: var(--finale);
  border: 0;
  border-radius: 0;
  cursor: pointer;
}
.presave__cta:hover {
  background: color-mix(in srgb, var(--finale) 80%, var(--target));
  color: var(--ink);
}
.oops {
  display: grid;
  gap: 1.2rem;
  justify-items: center;
}
.oops__art {
  width: min(18rem, 70%);
  height: auto;
}
.oops__text {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 1.1rem;
  line-height: 1.5;
  color: var(--paper-dim);
}
.minimap {
  position: fixed;
  right: 1.2rem;
  bottom: max(1.2rem, env(safe-area-inset-bottom));
  z-index: 25;
  width: 132px;
  height: 132px;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--strand) 34%, transparent);
  border-radius: 0;
  background: color-mix(in srgb, var(--ink) 74%, transparent);
  backdrop-filter: blur(6px);
  overflow: hidden;
  opacity: 0;
  transform: scale(0.9);
  pointer-events: none;
  cursor: pointer;
  transition: opacity 600ms var(--ease), transform 600ms var(--ease), width 420ms var(--ease), height 420ms var(--ease), inset 420ms var(--ease), background-color 420ms var(--ease);
}
.minimap.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.minimap svg {
  width: 100%;
  height: 100%;
  display: block;
}
.minimap__hint, .minimap__close {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  padding: 0.24rem 0;
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--strand);
  background: color-mix(in srgb, var(--ink) 82%, transparent);
}
.minimap__close {
  display: none;
}
.minimap.is-expanded {
  inset: 0;
  width: 100%;
  height: 100%;
  right: auto;
  bottom: auto;
  z-index: 46;
  border: 0;
  padding: clamp(1.5rem, 5vmin, 4rem);
  background:
    radial-gradient(120% 100% at 50% 50%, color-mix(in srgb, var(--ink-2) 96%, transparent) 0%, color-mix(in srgb, #03050A 97%, transparent) 100%);
  backdrop-filter: blur(14px);
  cursor: zoom-out;
}
.minimap.is-expanded .minimap__hint {
  display: none;
}
.minimap.is-expanded .minimap__close {
  display: block;
  top: max(1rem, env(safe-area-inset-top));
  bottom: auto;
  left: auto;
  right: max(1rem, env(safe-area-inset-right));
  width: auto;
  padding: 0.7rem 1rem 0.6rem;
  font-size: 1rem;
  color: var(--ink);
  background: var(--strand);
}
.minimap__edge {
  fill: none;
  stroke: transparent;
  stroke-width: 14;
}
.minimap__edge.is-walked {
  stroke: color-mix(in srgb, var(--found) 60%, transparent);
}
.minimap.is-expanded .minimap__edge {
  stroke-width: 9;
}
.minimap.is-expanded .minimap__edge.is-walked {
  stroke: color-mix(in srgb, var(--found) 78%, transparent);
}
.minimap__mark {
  fill: var(--target);
  opacity: 0.9;
}
.minimap__spider {
  fill: var(--eye);
}
.minimap.is-expanded .minimap__spider {
  fill: var(--eye);
  r: 55;
}
.is-mapped .fog {
  opacity: 0;
  transition: opacity 300ms linear;
}
.splash__keys-touch {
  display: none;
}
.is-touch .splash__keys-desk {
  display: none;
}
.is-touch .splash__keys-touch {
  display: inline;
}
.stick {
  position: fixed;
  z-index: 28;
  width: 116px;
  height: 116px;
  margin: -58px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--strand) 40%, transparent);
  background: color-mix(in srgb, var(--ink-2) 45%, transparent);
  backdrop-filter: blur(3px);
  opacity: 0;
  transform: scale(0.8);
  pointer-events: none;
  transition: opacity 160ms var(--ease), transform 160ms var(--ease);
}
.stick.is-active {
  opacity: 1;
  transform: scale(1);
}
.stick__nub {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 46px;
  height: 46px;
  margin: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--strand) 70%, var(--glow));
  box-shadow: 0 0 18px color-mix(in srgb, var(--strand) 60%, transparent);
  transform: translate(-50%, -50%);
}
.action {
  position: fixed;
  left: 50%;
  bottom: calc(max(6vh, 4rem) + 3.6rem);
  z-index: 29;
  transform: translateX(-50%) scale(0.9);
  padding: 1rem 2rem 0.9rem;
  font-size: 1.05rem;
  letter-spacing: 0.14em;
  line-height: 1;
  color: var(--ink);
  background: var(--target);
  border: 0;
  box-shadow: 0 8px 28px color-mix(in srgb, var(--ink) 70%, transparent);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
}
.action.is-visible {
  opacity: 1;
  transform: translateX(-50%) scale(1);
  pointer-events: auto;
}
body:not(.is-touch) .action {
  display: none;
}
.pad {
  position: fixed;
  left: max(0.9rem, env(safe-area-inset-left));
  bottom: max(0.9rem, env(safe-area-inset-bottom));
  z-index: 27;
  display: none;
  grid-template-columns: repeat(3, var(--pad-size, 52px));
  grid-template-rows: repeat(3, var(--pad-size, 52px));
  gap: 3px;
  opacity: 0.72;
  transition: opacity 200ms var(--ease);
}
.is-touch .pad {
  display: none;
}
.is-touch.is-playing .pad {
  display: grid;
}
.pad:hover, .pad:focus-within {
  opacity: 1;
}
.pad__btn {
  position: relative;
  border: 1px solid color-mix(in srgb, var(--strand) 34%, transparent);
  background: color-mix(in srgb, var(--ink-2) 62%, transparent);
  backdrop-filter: blur(4px);
  cursor: pointer;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
}
.pad__btn::before {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 32%;
  height: 32%;
  border-top: 2px solid color-mix(in srgb, var(--strand) 90%, var(--paper));
  border-right: 2px solid color-mix(in srgb, var(--strand) 90%, var(--paper));
  transform: rotate(var(--rot, 0deg));
}
.pad__btn--n {
  --rot: -45deg;
}
.pad__btn--ne {
  --rot: 0deg;
}
.pad__btn--e {
  --rot: 45deg;
}
.pad__btn--se {
  --rot: 90deg;
}
.pad__btn--s {
  --rot: 135deg;
}
.pad__btn--sw {
  --rot: 180deg;
}
.pad__btn--w {
  --rot: 225deg;
}
.pad__btn--nw {
  --rot: 270deg;
}
.pad__btn.is-held {
  background: color-mix(in srgb, var(--target) 82%, transparent);
  border-color: var(--target);
}
.pad__btn.is-held::before {
  border-color: var(--ink);
}
.pad__hub {
  border: 1px solid color-mix(in srgb, var(--muted) 30%, transparent);
  background: color-mix(in srgb, var(--ink) 40%, transparent);
}
.hints {
  position: fixed;
  left: 50%;
  bottom: max(1rem, env(safe-area-inset-bottom));
  z-index: 31;
  width: min(21rem, 88vw);
  transform: translate(-50%, 12px);
  padding: 1rem 1.1rem 0.9rem;
  background: color-mix(in srgb, var(--ink-2) 95%, transparent);
  border: 1px solid color-mix(in srgb, var(--strand) 34%, transparent);
  backdrop-filter: blur(10px);
  font-family: var(--font-ui);
  opacity: 0;
  pointer-events: none;
  transition: opacity 320ms var(--ease), transform 320ms var(--ease);
}
.hints.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
body:not(.is-touch) .hints {
  display: none;
}
.hints__line {
  margin: 0 0 0.45rem;
  font-size: 0.92rem;
  letter-spacing: 0.03em;
  color: var(--paper-dim);
}
.hints__key {
  display: inline-block;
  min-width: 3.4rem;
  margin-right: 0.5rem;
  font-family: var(--font-display);
  font-size: 0.86rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--target);
}
.hints__close {
  margin-top: 0.5rem;
  width: 100%;
  padding: 0.5rem;
  font-family: var(--font-display);
  font-size: 0.95rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--strand);
  border: 0;
  border-radius: 0;
  cursor: pointer;
}
.toasts {
  position: fixed;
  left: 50%;
  top: 5.5rem;
  z-index: 45;
  display: grid;
  gap: 0.5rem;
  justify-items: center;
  transform: translateX(-50%);
  pointer-events: none;
}
.toast {
  font-family: var(--font-ui);
  padding: 0.6rem 1.1rem;
  border-radius: 0;
  border: 1px solid color-mix(in srgb, var(--eye) 40%, transparent);
  background: color-mix(in srgb, var(--ink-2) 92%, transparent);
  color: var(--paper);
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 400ms var(--ease), transform 400ms var(--ease);
  backdrop-filter: blur(8px);
  white-space: nowrap;
}
.toast.is-in {
  opacity: 1;
  transform: none;
}
.toast--major {
  border-color: var(--target);
}
.toast__tail {
  color: var(--paper-dim);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 0.66rem;
}
.toast__glyph {
  display: inline-block;
  min-width: 1.4em;
  text-align: center;
  color: var(--eye);
  font-weight: 700;
  font-size: 0.95rem;
}
.noscript {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--ink);
  z-index: 100;
}
@media (max-width: 640px) {
  .hud {
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    padding: max(0.6rem, env(safe-area-inset-top)) 0.7rem 0.6rem;
  }
  .hud__counts {
    gap: 0.8rem;
  }
  .hud__label {
    font-size: 0.66rem;
    letter-spacing: 0.14em;
  }
  .hud__value {
    font-size: 0.98rem;
  }
  .hud__actions {
    gap: 0.3rem;
    flex-wrap: nowrap;
  }
  .hud__btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    padding: 0 0.55rem;
    font-size: 0.78rem;
    letter-spacing: 0.04em;
  }
  .hud__btn--red {
    margin-left: 0.2rem;
  }
  .minimap {
    width: 66px;
    height: 66px;
    top: calc(max(0.6rem, env(safe-area-inset-top)) + 3.6rem);
    right: max(0.7rem, env(safe-area-inset-right));
    bottom: auto;
  }
  .action {
    left: auto;
    right: max(0.9rem, env(safe-area-inset-right));
    bottom: calc(max(0.9rem, env(safe-area-inset-bottom)) + 0.4rem);
    transform: scale(0.9);
    font-size: 0.98rem;
    padding: 0.75rem 1.3rem 0.65rem;
    min-height: 48px;
  }
  .action.is-visible {
    transform: scale(1);
  }
  .pad {
    --pad-size: 50px;
  }
  .hints {
    left: max(0.9rem, env(safe-area-inset-left));
    transform: translate(0, 12px);
    bottom: calc(max(0.9rem, env(safe-area-inset-bottom)) + 10.6rem);
    width: min(20rem, calc(100vw - 1.8rem));
  }
  .hints.is-visible {
    transform: translate(0, 0);
  }
  .board {
    padding: 1rem 0.8rem max(1rem, env(safe-area-inset-bottom));
  }
  .board__row {
    grid-template-columns: 1.9rem 1fr;
    grid-template-areas: "num title""num controls";
    gap: 0.35rem 0.6rem;
    padding: 0.55rem 0 0.55rem 0.6rem;
  }
  .board__num {
    grid-area: num;
  }
  .board__controls {
    grid-area: controls;
    justify-self: start;
  }
  .board__btn {
    min-height: 40px;
    display: inline-flex;
    align-items: center;
  }
  .board__close {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .modal {
    padding: 0.7rem;
  }
  .modal__panel {
    padding: 2.6rem 1rem 1.4rem;
  }
  .modal__close {
    min-width: 44px;
    min-height: 44px;
  }
  .toast {
    white-space: normal;
    text-align: center;
    max-width: 84vw;
  }
  .toasts {
    top: 4.4rem;
  }
  .splash__logo {
    height: clamp(2.6rem, 11vmin, 5rem);
  }
  .splash__keys {
    display: none;
  }
}
@media (max-width: 379px) {
  .pad {
    --pad-size: 44px;
  }
  .action {
    bottom: calc(max(0.9rem, env(safe-area-inset-bottom)) + 9.2rem);
    font-size: 0.9rem;
    padding: 0.6rem 1rem 0.5rem;
  }
  .hints {
    bottom: calc(max(0.9rem, env(safe-area-inset-bottom)) + 9.4rem);
  }
  .hud__btn {
    font-size: 0.7rem;
    padding: 0 0.4rem;
  }
  .hud__label {
    font-size: 0.6rem;
  }
}
@media (max-height: 460px) {
  .splash__logo {
    display: none;
  }
  .splash__keys {
    display: none;
  }
  .splash__body {
    font-size: 0.82rem;
    line-height: 1.35;
  }
  .pad {
    --pad-size: 42px;
  }
  .minimap {
    display: none;
  }
}
.is-touch .prompt {
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .eye {
    animation: none;
  }
  .spider.is-crawling {
    animation-duration: var(--cycle, 620ms) !important;
    animation-iteration-count: infinite !important;
  }
  .orb, .orb__art, .orb__spiral {
    animation: none !important;
  }
  .splash__blade {
    display: none;
  }
  .splash.is-split .splash__pane--l, .splash.is-split .splash__pane--r {
    transform: none;
    opacity: 0;
  }
}