/* ==========================================================================
   lantern-48 — web build v1.2

   Written at night, over about three weeks, mostly badly. The colours are
   sampled off the actual brass with a phone camera, which is why they are
   such peculiar numbers.

   One of the colours in this file is not a colour. It is a word. It is not
   important and it will not help you, and I put it there because at some
   point in a project like this you have to be allowed one joke.
   ========================================================================== */

:root {
  --ink:        #0b0a09;
  --ink-2:      #16130f;
  --paper:      #e8e2d2;
  --paper-dim:  #a89f8a;
  --brass:      #c39a45;
  --brass-dim:  #7a6128;
  --flame:      #ffd58a;
  --blood:      #7d2b23;
  --hint:       #dec0de;   /* <- that one */
  --edge:       rgba(195,154,69,.22);

  --serif: Georgia, "Iowan Old Style", "Palatino Linotype", Palatino, "Times New Roman", serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --lamp: 0;   /* 0 → 1, driven from JS. everything warms as this rises. */
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0; padding: 0;
  min-height: 100%;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.62;
  overflow-x: hidden;
  overscroll-behavior: none;
}

body.cold  { background: #060505; }
body.lit   { background: #0d0b08; }

/* ---------- grain + vignette, always on, very cheap --------------------- */

#grain {
  position: fixed; inset: -50%;
  pointer-events: none; z-index: 90; opacity: .06;
  background-image:
    radial-gradient(circle at 20% 30%, #fff 0 1px, transparent 1px),
    radial-gradient(circle at 70% 60%, #fff 0 1px, transparent 1px),
    radial-gradient(circle at 45% 85%, #fff 0 1px, transparent 1px);
  background-size: 7px 7px, 11px 11px, 13px 13px;
  animation: shift .12s steps(3) infinite;
}
@keyframes shift {
  0%   { transform: translate(0,0); }
  33%  { transform: translate(-3px, 2px); }
  66%  { transform: translate(2px,-3px); }
  100% { transform: translate(0,0); }
}
#vignette {
  position: fixed; inset: 0; pointer-events: none; z-index: 89;
  background: radial-gradient(ellipse at 50% 45%, transparent 35%, rgba(0,0,0,.75) 100%);
}
@media (prefers-reduced-motion: reduce) {
  #grain { animation: none; }
  * { animation-duration: .01ms !important; transition-duration: .06s !important; }
}

/* ---------- screens ----------------------------------------------------- */

.screen {
  display: none;
  min-height: 100svh;
  padding: max(28px, env(safe-area-inset-top)) 20px 40px;
  animation: fade .9s ease both;
}
.screen.on { display: flex; align-items: center; justify-content: center; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.wrap { width: 100%; max-width: 34rem; margin: 0 auto; }
.wrap.wide { max-width: 46rem; }

h1 {
  font-size: clamp(1.9rem, 7vw, 2.7rem);
  font-weight: normal; letter-spacing: .02em;
  margin: .2em 0 .5em;
  color: var(--paper);
}
h2 {
  font-size: clamp(1.4rem, 5vw, 1.8rem);
  font-weight: normal; margin: 0 0 .2em;
}

.brass {
  font-family: var(--mono); font-size: 11px; line-height: 1.15;
  color: var(--brass-dim); margin: 0 0 1.4em; opacity: .8;
  white-space: pre;
}
.lede  { color: var(--paper-dim); margin: 0 0 1.1em; }
.sub   { color: var(--paper-dim); margin: 0 0 1.4em; font-size: .93rem; }
.foot  { color: #6b6355; font-size: .82rem; margin-top: 2.4em; font-style: italic; }
.err   { color: var(--blood); min-height: 1.6em; margin: .8em 0 0; font-style: italic; }
.hint-soft { color: #5d564a; font-size: .85rem; font-style: italic; margin-top: 2em; text-align: center; }

/* ---------- ignition form ----------------------------------------------- */

#seqform { margin-top: 2.4em; display: flex; flex-wrap: wrap; gap: 10px; }
#seqform label {
  width: 100%; font-size: .74rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--brass-dim);
}
input[type=text] {
  flex: 1 1 12rem; min-width: 0;
  background: rgba(255,255,255,.03);
  border: 1px solid var(--edge); border-radius: 2px;
  color: var(--paper); font-family: var(--serif); font-size: 1.05rem;
  padding: .7em .8em; letter-spacing: .04em;
}
input[type=text]:focus { outline: none; border-color: var(--brass); background: rgba(255,255,255,.055); }

button {
  background: transparent; border: 1px solid var(--brass-dim); border-radius: 2px;
  color: var(--brass); font-family: var(--serif); font-size: .95rem;
  padding: .7em 1.3em; cursor: pointer; letter-spacing: .06em;
  transition: background .25s, color .25s, border-color .25s;
}
button:hover, button:focus-visible { background: rgba(195,154,69,.12); color: var(--flame); outline: none; }

/* ---------- the knob ----------------------------------------------------- */

#knobscreen .wrap { text-align: center; }
.instruction { font-size: 1.25rem; color: var(--paper-dim); margin-bottom: 2.4em; font-style: italic; }

#knobstage { position: relative; width: min(72vw, 300px); margin: 0 auto; aspect-ratio: 1; }
#knob {
  width: 100%; height: 100%; position: relative; z-index: 2;
  touch-action: none; cursor: grab; display: block;
  filter: brightness(calc(.55 + var(--lamp) * .8));
}
#knob:active { cursor: grabbing; }
#knobbody { transform-origin: 100px 100px; }
#glow {
  position: absolute; inset: -60%; z-index: 1; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,213,138,.85) 0%, rgba(255,170,60,.28) 32%, transparent 68%);
  opacity: calc(var(--lamp) * var(--lamp));
  filter: blur(14px);
}
#knobmeter {
  position: relative; z-index: 3; margin: 2.2em auto 0;
  width: 74%; height: 2px; background: rgba(255,255,255,.09);
}
#knobmeter i {
  display: block; height: 100%; width: calc(var(--lamp) * 100%);
  background: var(--brass); transition: width .1s linear;
}
#knobstage.snap { animation: snap .5s; }
@keyframes snap {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-9px); }
  45% { transform: translateX(7px); }
  70% { transform: translateX(-4px); }
}

/* ---------- the rack ----------------------------------------------------- */

.rackhead { margin-bottom: 1.6em; }
.letters {
  font-family: var(--mono); font-size: 1.5rem; letter-spacing: .55em;
  color: var(--brass); min-height: 1.6em; margin: 0;
}
.letters .blank { color: #3a352c; }

#platelist { list-style: none; margin: 0; padding: 0; }
#platelist li {
  border-top: 1px solid rgba(255,255,255,.07);
  padding: 1.05em .2em; display: flex; align-items: baseline; gap: 1em;
  cursor: pointer; transition: background .2s, padding-left .2s;
}
#platelist li:last-child { border-bottom: 1px solid rgba(255,255,255,.07); }
#platelist li:hover:not(.locked) { background: rgba(195,154,69,.06); padding-left: .7em; }
#platelist li .n {
  font-family: var(--mono); color: var(--brass-dim); font-size: .95rem;
  min-width: 2.4em; letter-spacing: .05em;
}
#platelist li .t { flex: 1; }
#platelist li .t small { display: block; color: #6f6858; font-size: .82rem; font-style: italic; }
#platelist li .st { font-family: var(--mono); font-size: .78rem; color: #5b5449; letter-spacing: .1em; }
#platelist li.done .n, #platelist li.done .st { color: var(--brass); }
#platelist li.locked { opacity: .32; cursor: default; }

/* ---------- projection --------------------------------------------------- */

#scene { padding: 0; position: relative; }
#scene.on { display: block; }
#wall {
  position: relative; width: 100%; height: 100svh; overflow: hidden;
  background: #0a0908;
}
#beam {
  position: absolute; inset: 0; pointer-events: none; z-index: 6;
  background: radial-gradient(ellipse at 50% 44%, rgba(255,224,170,.09) 0%, transparent 62%);
  mix-blend-mode: screen;
  animation: flicker 5.5s ease-in-out infinite;
}
@keyframes flicker {
  0%,100% { opacity: 1; } 42% { opacity: .93; } 44% { opacity: 1; }
  71% { opacity: .88; } 73% { opacity: .99; }
}
#projected { position: absolute; inset: 0; }
#caption {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  padding: 1.1em 1.3em calc(1.1em + env(safe-area-inset-bottom));
  background: linear-gradient(transparent, rgba(6,5,5,.92) 45%);
  color: var(--paper-dim); font-size: .95rem; text-align: center;
  pointer-events: none; font-style: italic;
}
#caption b { color: var(--flame); font-style: normal; font-weight: normal; }
#eject {
  position: fixed; top: max(14px, env(safe-area-inset-top)); right: 14px; z-index: 30;
  font-size: .78rem; padding: .5em .9em; letter-spacing: .12em;
  opacity: .5;
}
#eject:hover { opacity: 1; }

/* ---------- generic scene furniture -------------------------------------- */

.room { position: absolute; inset: 0; }
.tap {
  position: absolute; cursor: pointer;
  transition: filter .3s, opacity .3s, transform .3s;
}
.tap:hover { filter: brightness(1.35); }
.centered {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding: 2em 1.6em; gap: 1.1em;
}
.big-letter {
  font-family: var(--serif); font-size: clamp(5rem, 30vw, 11rem);
  color: var(--flame); text-shadow: 0 0 44px rgba(255,213,138,.55);
  animation: bloom 2.2s ease both;
}
@keyframes bloom { from { opacity: 0; transform: scale(.7); filter: blur(16px); } to { opacity: 1; transform: none; filter: none; } }

.pale { color: #100e0c; }          /* on a dark wall this is very nearly nothing */
.faint { color: rgba(232,226,210,.075); }

/* ---------- crash --------------------------------------------------------- */

#crash.on { display: block; background: #fff; color: #111; padding: 3.2em 1.4em; }
#crashtext {
  font-family: var(--mono); font-size: 12.5px; line-height: 1.55;
  white-space: pre-wrap; word-break: break-word; max-width: 44rem; margin: 0 auto;
  color: #1b1b1b;
}

/* ---------- terminal ------------------------------------------------------ */

#termbtn {
  position: fixed; left: 12px; bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 60; font-family: var(--mono); font-size: .8rem;
  padding: .45em .7em; opacity: .38;
}
#termbtn:hover { opacity: 1; }
#terminal {
  position: fixed; inset: auto 0 0 0; z-index: 80;
  max-height: 66svh; display: flex; flex-direction: column;
  background: rgba(4,4,4,.965); border-top: 1px solid var(--edge);
  padding: .9em .9em calc(.9em + env(safe-area-inset-bottom));
  font-family: var(--mono); font-size: 13px; line-height: 1.55;
  animation: rise .28s ease both;
}
@keyframes rise { from { transform: translateY(100%); } to { transform: none; } }
#termout { overflow-y: auto; white-space: pre-wrap; color: #9fbf9c; padding-bottom: .6em; }
#termout .u { color: var(--brass); }
#termout .w { color: var(--blood); }
#termform { display: flex; gap: .5em; align-items: center; border-top: 1px solid rgba(255,255,255,.08); padding-top: .6em; }
#termform .prompt { color: var(--brass); }
#termin {
  flex: 1; background: transparent; border: 0; outline: none;
  color: #cfe0cd; font-family: var(--mono); font-size: 13px; padding: .2em 0;
}

/* ---------- toast ---------------------------------------------------------- */

#toast {
  position: fixed; left: 50%; bottom: calc(22px + env(safe-area-inset-bottom));
  transform: translate(-50%, 130%); z-index: 95;
  background: rgba(10,9,8,.94); border: 1px solid var(--edge);
  color: var(--paper-dim); padding: .7em 1.1em; border-radius: 2px;
  font-size: .87rem; max-width: 88vw; text-align: center;
  transition: transform .4s cubic-bezier(.2,.9,.3,1);
  pointer-events: none;
}
#toast.up { transform: translate(-50%, 0); }

/* ---------- utility --------------------------------------------------------- */

.shhh { position: absolute; left: -9999px; }
a { color: var(--brass); }
