/* RFD-Minimatex: JetBrains Mono only, square shapes.
   The room is white. Now and then the Board inverts it (html.inv). */
:root {
  --bg: #f1f1f1;
  --ink: #0d1014;
  --text: rgba(13, 16, 20, 0.74);
  --soft: rgba(13, 16, 20, 0.55);
  --faint: rgba(13, 16, 20, 0.36);
  --alt: #0d1014;
  --accent: #E89768;
  --info: #6CB4EE;
  --crit: #E56767;
  --vignette: rgba(0, 0, 0, 0.16);
  --scanline: rgba(0, 0, 0, 0.045);
  --grain: 0.09;
  --font: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color-scheme: light;
}
:root.inv {
  --bg: #0d1014;
  --ink: #f1f1f1;
  --text: #d3d3d3;
  --soft: rgba(255, 255, 255, 0.6);
  --faint: #6b7078;
  --alt: #E89768;
  --vignette: rgba(0, 0, 0, 0.6);
  --scanline: rgba(0, 0, 0, 0.22);
  --grain: 0.07;
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; border-radius: 0; }
[hidden] { display: none !important; }

html, body { height: 100%; }
html { background: var(--bg); }
body {
  margin: 0;
  overflow: hidden;
  background: var(--bg);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

/* ---- atmosphere ---- */
.grain {
  position: fixed; inset: -50%; z-index: 40; pointer-events: none; opacity: var(--grain);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  animation: grain 0.9s steps(5) infinite;
}
@keyframes grain {
  0% { transform: translate(0, 0); }
  20% { transform: translate(-4%, 3%); }
  40% { transform: translate(3%, -2%); }
  60% { transform: translate(-2%, -4%); }
  80% { transform: translate(4%, 2%); }
  100% { transform: translate(0, 0); }
}
.scan {
  position: fixed; inset: 0; z-index: 41; pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 45%, rgba(0, 0, 0, 0) 55%, var(--vignette) 100%),
    repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0) 0 2px, var(--scanline) 2px 3px);
}

/* ---- gate ---- */
.gate {
  position: fixed; inset: 0; z-index: 30;
  display: grid; place-items: center;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  background: var(--bg);
}

.contact {
  appearance: none; background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 400;
  letter-spacing: 0.34em; text-transform: uppercase;
  color: var(--soft);
  display: inline-flex; align-items: center; gap: 12px;
  min-height: 44px; padding: 12px 18px;
}
/* nothing eases: hovering snaps, with a short colour-split twitch */
.contact:hover { color: var(--ink); }
.contact:hover .contact-text { animation: shake 0.07s steps(2) 3; }
.contact:hover .cursor { background: var(--accent); }
.contact:focus-visible { outline: 1px solid var(--accent); outline-offset: 6px; color: var(--ink); }
.cursor {
  width: 7px; height: 12px; background: currentColor;
  animation: blink 1.1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

.gate.closing .contact { color: var(--ink); }
.gate.closing .contact-text { animation: shake 0.08s steps(2) infinite; }
@keyframes shake {
  0% { transform: translate(0, 0); text-shadow: 2px 0 var(--info), -2px 0 var(--crit); }
  100% { transform: translate(-1px, 1px); text-shadow: -2px 0 var(--info), 2px 0 var(--crit); }
}

/* ---- the pyramid, and nothing else ---- */
.stage { position: fixed; inset: 0; z-index: 10; }
.stage canvas { display: block; width: 100%; height: 100%; }

/* ---- the lines, surfacing at the bottom ---- */
.whisper {
  position: absolute; left: 50%; bottom: calc(env(safe-area-inset-bottom, 0px) + clamp(28px, 7vh, 72px));
  transform: translateX(-50%);
  width: min(62ch, calc(100% - 2 * max(16px, env(safe-area-inset-left, 0px))));
  margin: 0; text-align: center;
  font-size: clamp(12px, 1.5vw, 15px); font-weight: 400; line-height: 1.75;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text);
  overflow-wrap: anywhere;
}
/* on its way out: torn sideways with a colour split while the letters decay */
.whisper.dying { white-space: pre-wrap; animation: tear 0.09s steps(2) infinite; }
.whisper.bare .alt::before, .whisper.bare .alt::after { color: transparent; }
@keyframes tear {
  0% { transform: translateX(calc(-50% + 3px)); text-shadow: 2px 0 var(--info), -2px 0 var(--crit); }
  100% { transform: translateX(calc(-50% - 2px)) skewX(-8deg); text-shadow: -2px 0 var(--info), 2px 0 var(--crit); }
}
.chev { color: var(--accent); }
.alt { color: var(--alt); }
.alt::before { content: '['; color: var(--accent); }
.alt::after { content: ']'; color: var(--accent); }
.alt.scramble { color: var(--info); text-shadow: 1px 0 var(--crit); }
.typing::after {
  content: ''; display: inline-block; width: 0.55em; height: 1em; margin-left: 2px;
  background: var(--accent); vertical-align: -0.15em;
  animation: blink 0.9s steps(1) infinite;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .grain, .cursor, .typing::after, .contact-text, .whisper { animation: none !important; }
}
