/* =====================================================================
   FOREST AT MIDNIGHT — stylesheet
   Palette: soot & brass steampunk, verdigris vines, blue blooms.
   Blurple appears ONLY in the Puzzle 1 horizon glow (it is the clue).
   ===================================================================== */
:root{
  --soot:       #16120e;   /* base background            */
  --umber:      #221a13;   /* raised panels              */
  --brass:      #b08d57;   /* primary metal              */
  --brass-hi:   #dcbd80;   /* polished highlight         */
  --copper:     #8a5a3b;   /* darker metal               */
  --verdigris:  #5e8272;   /* oxidized green / vines     */
  --bloom:      #7fa0e8;   /* blue flowers (theme tease) */
  --bloom2:     #a9bef0;   /* second species: paler bells (NOT blurple) */
  --phosphor:   #93d99b;   /* terminal green */
  --parchment:  #d9cdb8;   /* body text                  */
  --ash:        #8f8a80;   /* dim text                   */
  --blurple:    #5865f2;   /* RESERVED: puzzle-1 clue    */
  --blurple2:   #404eed;

  --display: 'IM Fell English SC', Georgia, serif;
  --whisper: 'IM Fell English', Georgia, serif;
  --osd:     'Special Elite', 'Courier New', monospace;
}

*{ margin:0; padding:0; box-sizing:border-box; }
::selection{ background:rgba(176,141,87,.4); color:#f0e6d2; }
html,body{ height:100%; }
body{
  background:
    radial-gradient(120% 100% at 50% 0%, #1c1610 0%, var(--soot) 60%);
  color:var(--parchment);
  font-family:var(--whisper);
  overflow:hidden;
  -webkit-font-smoothing:antialiased;
}
button{ font:inherit; color:inherit; background:none; border:none; cursor:pointer; }
button:focus-visible{ outline:1px dashed var(--brass); outline-offset:4px; }
.hidden{ display:none !important; }

/* ================= atmosphere layers ================= */

/* background gears — populated by JS */
#gearscape{
  position:fixed; inset:0; width:100%; height:100%;
  z-index:0; pointer-events:none; opacity:.5;
}
#gearscape .gear,      #gearfield .gear{ transform-box:fill-box; transform-origin:center; }
#gearscape .spin,      #gearfield .spin     { animation:spin 240s linear infinite; }
#gearscape .spin-rev,  #gearfield .spin-rev { animation:spin 180s linear infinite reverse; }
#gearscape .spin-fast, #gearfield .spin-fast{ animation:spin 120s linear infinite; }
@keyframes spin{ to{ transform:rotate(360deg); } }

/* light VHS residue (the theme ladder still passes through VHS) */
.vhs{ position:fixed; inset:0; pointer-events:none; z-index:50; }
.vhs::before{
  content:""; position:absolute; inset:0;
  background:repeating-linear-gradient(0deg, rgba(0,0,0,.14) 0 1px, transparent 1px 4px);
  mix-blend-mode:multiply;
}
.vhs::after{
  content:""; position:absolute; inset:0;
  background:radial-gradient(ellipse at center, transparent 58%, rgba(0,0,0,.5) 100%);
}
.grain{
  position:absolute; inset:-100px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  opacity:.035;
  animation:grain 900ms steps(4) infinite;
}
@keyframes grain{
  0%{ transform:translate(0,0); } 25%{ transform:translate(-30px,20px); }
  50%{ transform:translate(20px,-25px); } 75%{ transform:translate(-15px,-10px); }
  100%{ transform:translate(25px,15px); }
}

/* corner vines */
.vine{
  position:fixed; top:-8px; width:min(200px,26vw); z-index:39;
  pointer-events:none; opacity:.8;
}
.vine-left { left:-6px; }
.vine-right{ right:-6px; transform:scaleX(-1); }
.vine .stem { fill:none; stroke:var(--verdigris); stroke-width:3.5; stroke-linecap:round; opacity:.75; }
.vine .stem.thin{ stroke-width:2; opacity:.6; }
.vine .leaf { fill:var(--verdigris); opacity:.55; }
.vine .petal{ fill:var(--bloom); opacity:.85; }
.vine .pistil{ fill:var(--brass-hi); opacity:.9; }
.vine .flower.small .petal{ opacity:.7; }
.vine .bud{ fill:var(--bloom); opacity:.55; }
.vine .bellcup  { fill:var(--bloom2); opacity:.8; }
.vine .bellheart{ fill:var(--brass-hi); opacity:.8; }

/* ================= OSD ================= */
.osd{
  position:fixed; top:0; left:0; right:0; z-index:60;
  display:flex; justify-content:space-between;
  padding:20px 30px;
  font-family:var(--osd); font-size:clamp(15px,2vw,20px);
  color:var(--brass-hi);
  text-shadow:0 0 8px rgba(176,141,87,.45);
  letter-spacing:.12em;
  opacity:0; transition:opacity 1.6s ease;
  pointer-events:none;
}
.osd.on{ opacity:.9; }
#osdMode .blink{ animation:blink 1.4s steps(1) infinite; }
@keyframes blink{ 50%{ opacity:0; } }

/* the settings cog lives fixed top-right on EVERY scene — its being
   everywhere is the camouflage for what it does in the listening room */

/* ================= scenes ================= */
.scene{
  position:fixed; inset:0; z-index:10;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; padding:24px;
  opacity:0; visibility:hidden;
  transition:opacity 1.8s ease, visibility 0s linear 1.8s;
}
.scene.on{ opacity:1; visibility:visible; transition:opacity 1.8s ease; }

/* ================= menu ================= */
.title{
  font-family:var(--display); font-weight:400;
  font-size:clamp(40px,8vw,92px);
  letter-spacing:.04em; line-height:1.05;
  color:var(--parchment);
  text-shadow:0 0 28px rgba(176,141,87,.25), 0 2px 0 rgba(0,0,0,.6);
  transition:color 1.6s ease, text-shadow 1.6s ease;
}
/* menu daylight — the settings lamp works here too, purely as a red
   herring so its real job in the listening room hides in plain sight.
   The page loads with body.p2-dark on, so the menu opens at night.    */
#menu::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:
    radial-gradient(90% 60% at 50% 0%, #efe4c8 0%, transparent 60%),
    linear-gradient(180deg, #d9cdb0 0%, #e6dcc2 52%, #cfc0a0 100%);
  opacity:1; transition:opacity 1.6s ease;
}
body.p2-dark #menu::before{ opacity:0; }
body:not(.p2-dark) .title{
  color:#3c352c;
  text-shadow:0 0 26px rgba(255,246,220,.55), 0 2px 0 rgba(255,255,255,.35);
}
/* the tv only switches on once the warning is acknowledged */
.title.crt{ animation:crt-on 1.6s cubic-bezier(.25,.75,.3,1) both; }
/* old tv power-on: a hot horizontal line that snaps open vertically */
@keyframes crt-on{
  0%  { transform:scale(0,.004);  filter:brightness(9);   }
  42% { transform:scale(1,.004);  filter:brightness(7);   }
  58% { transform:scale(1,.02);   filter:brightness(5);   }
  75% { transform:scale(1,1.04);  filter:brightness(2.4); }
  86% { transform:scale(1,.985);  filter:brightness(1.5); }
  100%{ transform:none;           filter:none;            }
}
.menu-actions{ margin-top:58px; display:flex; flex-direction:column; gap:18px; }

/* engraved brass plate buttons */
.plate-btn{
  font-family:var(--osd); font-size:clamp(17px,2.4vw,22px);
  letter-spacing:.22em; color:var(--brass-hi);
  padding:12px 34px;
  background:linear-gradient(180deg, #2a2118, #1c1610);
  border:1px solid rgba(176,141,87,.55);
  border-radius:3px;
  box-shadow:inset 0 1px 0 rgba(220,189,128,.18), inset 0 -6px 12px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.6);
  transition:color .3s, border-color .3s, box-shadow .3s, letter-spacing .3s;
}
.plate-btn:hover{
  color:#f0dfb8; border-color:var(--brass-hi); letter-spacing:.3em;
  box-shadow:inset 0 1px 0 rgba(220,189,128,.3), inset 0 -6px 12px rgba(0,0,0,.5),
             0 0 18px rgba(176,141,87,.35);
}

/* blocked-audio notice */
.audio-notice{
  position:fixed; bottom:52px; left:50%; transform:translateX(-50%);
  z-index:61; font-family:var(--osd); font-size:13px; letter-spacing:.1em;
  color:var(--brass-hi); opacity:.85;
  background:rgba(24,19,14,.85); border:1px solid rgba(176,141,87,.4);
  border-radius:3px; padding:8px 16px; pointer-events:none;
}

/* ================= intro ================= */
.intro-clock{
  width:min(320px,64vw); height:min(320px,64vw);
  opacity:0; transition:opacity 2.2s ease;
}
.intro-clock.show{ opacity:1; }
.intro-clock.dim { opacity:.16; }   /* the fade before words (text reads over it) */
.intro-clock svg{ width:100%; height:100%; overflow:visible; }

/* shared clock parts (built by JS) */
.clock .rim    { fill:none; stroke:var(--brass); stroke-width:6; }
.clock .rim.in { stroke:var(--copper); stroke-width:2; opacity:.7; }
.clock .tick   { stroke:var(--brass-hi); stroke-width:2.5; opacity:.8; }
.clock .tick.min{ stroke-width:1; opacity:.35; }
/* Hands are positioned by trigonometry in main.js — no transforms —
   so they always stay anchored on the pin. Only the second hand
   carries a CSS rotation animation. */
.clock .hand   { stroke:var(--parchment); stroke-linecap:round; }
.clock .hand.hour  { stroke-width:6; }
.clock .hand.minute{ stroke-width:4; }
.clock .hand.second{
  stroke:var(--bloom); stroke-width:2;
  transform-box:view-box; transform-origin:50% 50%;
  animation:sweep 60s linear infinite;
}
.clock .pin    { fill:var(--brass-hi); }
.clock .gearbit{ fill:var(--copper); opacity:.5; transform-box:fill-box; transform-origin:center; }
.clock .gearbit.turn    { animation:spin 40s linear infinite; }
.clock .gearbit.turn-rev{ animation:spin 28s linear infinite reverse; }
.clock .crown  { fill:var(--brass); }
.clock .vinework{ fill:none; stroke:var(--verdigris); stroke-width:3; opacity:.75; stroke-linecap:round; }
.clock .leafwork{ fill:var(--verdigris); opacity:.55; }
.clock .petalwork{ fill:var(--bloom); opacity:.85; }
.clock .pistilwork{ fill:var(--brass-hi); }
@keyframes sweep{ to{ transform:rotate(360deg); } }

/* lantern clock (camping) */
.clock .frame    { fill:none; stroke:var(--brass); stroke-width:5; stroke-linecap:round; }
.clock .framefill{ fill:#241c13; stroke:var(--brass); stroke-width:3.5; }
.clock .lanternglow{ animation:lampflick 5s ease-in-out infinite; }
@keyframes lampflick{ 0%,100%{ opacity:.7; } 42%{ opacity:1; } 58%{ opacity:.62; } }

/* vhs counter clock (VHS) */
.clock .vhsshell { fill:#1d1712; stroke:var(--brass); stroke-width:3; }
.clock .vhswindow{ fill:#12100c; stroke:var(--copper); stroke-width:2; }
.clock .tapeline { stroke:var(--copper); stroke-width:2.5; opacity:.75; }
.clock .reel{
  fill:none; stroke:var(--brass-hi); stroke-width:3;
  transform-box:fill-box; transform-origin:center;
  animation:spin 9s linear infinite;
}
.clock .reel.rev{ animation-direction:reverse; }
.clock .reel .spoke{ stroke:var(--brass-hi); stroke-width:2; }
.clock .vhstext{ font-family:var(--osd); fill:var(--parchment); letter-spacing:.12em; }
.clock .vhstext.dim{ opacity:.55; }
.clock .vhstext .colon{ animation:blink 1s steps(1) infinite; }

/* hourglass · sunface · luna · compass · station */
.clock .glass{ fill:none; stroke:var(--brass-hi); stroke-width:2; opacity:.45; }
.clock .sand { fill:#c9a76a; opacity:.7; }
.clock .sandstream{
  stroke:#c9a76a; stroke-width:2.5; stroke-dasharray:3 6;
  animation:sandfall .9s linear infinite;
}
@keyframes sandfall{ to{ stroke-dashoffset:-9; } }
.clock .dialinset { fill:rgba(24,19,14,.88); stroke:var(--brass); stroke-width:2; }
.clock .ray       { fill:var(--brass); opacity:.75; }
.clock .ray.small { fill:var(--copper); opacity:.6; }
.clock .moonface  { fill:#d9cdb8; opacity:.1; }
.clock .crater    { fill:none; stroke:var(--brass-hi); stroke-width:1.5; opacity:.35; }
.clock .lunashadow{ fill:#000; opacity:.32; }
.clock .rosemajor { fill:var(--copper); opacity:.65; stroke:var(--brass); stroke-width:1; }
.clock .roseminor { fill:var(--brass); opacity:.35; }
.clock .cardinal  { font-family:var(--osd); font-size:19px; fill:var(--brass-hi); }
.clock .numeral   { font-family:var(--osd); font-size:23px; fill:var(--brass-hi); opacity:.9; }

/* astral clock (space) */
.clock .starlet  { fill:var(--parchment); }
.clock .orbitring{ fill:none; stroke:var(--brass); stroke-width:1.2; stroke-dasharray:3 7; opacity:.5; }
.clock .orbitwrap{ transform-box:view-box; transform-origin:50% 50%; animation:spin 36s linear infinite; }
.clock .orbitwrap.slow{ animation:spin 74s linear infinite reverse; }
.clock .planet   { fill:var(--bloom); opacity:.9; }
.clock .moonlet  { fill:var(--brass-hi); }

/* the monologue overlays the clock: the block's bottom edge is pinned
   below center, so each new line pushes the earlier ones UP across the
   clock face — the clock itself never moves.                          */
.intro-lines{
  position:absolute; left:50%; bottom:9vh; transform:translateX(-50%);
  width:min(640px,88vw);
  max-height:84vh; overflow:hidden;
  display:flex; flex-direction:column; justify-content:flex-end;
  gap:14px; align-items:center;
  pointer-events:none; z-index:2;
}
/* the top fade only applies once the monologue actually overflows the
   box — otherwise it dimmed the very first line for no reason (JS adds
   .clip when scrollHeight exceeds the frame)                          */
.intro-lines.clip{
  -webkit-mask-image:linear-gradient(180deg, transparent 0, #000 4.5em);
          mask-image:linear-gradient(180deg, transparent 0, #000 4.5em);
}
.intro-line{
  font-family:var(--whisper); font-style:italic;
  font-size:clamp(18px,2.6vw,25px); color:var(--parchment);
  max-width:30em;
  text-shadow:0 0 12px rgba(0,0,0,.85), 0 2px 6px rgba(0,0,0,.7);
  opacity:0; transform:translateY(8px);
  transition:opacity 2s ease, transform 2s ease;
}
.intro-line.on{ opacity:.92; transform:none; }
.skip-hint{
  position:absolute; bottom:32px;
  font-family:var(--osd); font-size:clamp(14px,1.8vw,17px); letter-spacing:.24em;
  color:var(--brass-hi); opacity:.8;
  text-shadow:0 0 10px rgba(176,141,87,.4);
  padding:10px 22px;
  border:1px solid rgba(176,141,87,.35); border-radius:3px;
  background:rgba(24,19,14,.55);
  transition:opacity .3s, border-color .3s, box-shadow .3s;
}
.skip-hint:hover{
  opacity:1; border-color:var(--brass-hi);
  box-shadow:0 0 16px rgba(176,141,87,.35);
}
/* once every line has been read, the skip hint turns into PROCEED and
   glows — the sparkles (spawned by JS) announce the change            */
.skip-hint.proceed{
  opacity:1; color:#f0dfb8; border-color:var(--brass-hi);
  letter-spacing:.3em;
  box-shadow:0 0 18px rgba(176,141,87,.45);
  animation:proceedglow 2.6s ease-in-out infinite;
}
@keyframes proceedglow{
  0%,100%{ box-shadow:0 0 18px rgba(176,141,87,.45); }
  50%    { box-shadow:0 0 28px rgba(220,189,128,.65); }
}
.skip-hint .burst-line{
  position:absolute; pointer-events:none;
  width:13px; height:2px; border-radius:1px;
  background:var(--brass-hi);
  box-shadow:0 0 6px rgba(220,189,128,.9);
  transform-origin:0 50%;               /* anchored on the button edge */
  opacity:0;
  transform:rotate(var(--a)) translateX(5px) scaleX(.4);
  animation:edgeburst .8s ease-out forwards;
}
@keyframes edgeburst{
  0%  { opacity:0; transform:rotate(var(--a)) translateX(5px)  scaleX(.4); }
  15% { opacity:1; }
  100%{ opacity:0; transform:rotate(var(--a)) translateX(32px) scaleX(1); }
}

/* ================= content warning (the page's opening) ================= */
.warn-wrap{ position:relative; }
.warn-plate{
  max-width:46em; padding:48px 58px;
  background:linear-gradient(180deg, rgba(42,33,24,.92), rgba(24,19,14,.92));
  border:1px solid rgba(176,141,87,.5); border-radius:3px;
  box-shadow:inset 0 1px 0 rgba(220,189,128,.15), 0 8px 30px rgba(0,0,0,.5);
}
.warn-title{
  font-family:var(--display); font-size:clamp(30px,5vw,46px);
  color:var(--parchment); margin-bottom:26px;
}
.warn-line{
  font-style:italic; color:var(--parchment); opacity:.85;
  font-size:clamp(18px,2.6vw,24px); line-height:1.65;
  margin-bottom:12px;
}
.warn-actions{
  margin-top:32px; display:flex; gap:18px; justify-content:center; flex-wrap:wrap;
}
/* gears and vines around the plate */
.warn-decor{ position:absolute; pointer-events:none; }
.warn-gear{ width:clamp(80px,12vw,130px); height:clamp(80px,12vw,130px); opacity:.55; }
.warn-gear.tl{ top:-46px; left:-52px; }
.warn-gear.br{ bottom:-46px; right:-52px; }
.warn-gear .gear{ transform-box:fill-box; transform-origin:center; animation:spin 70s linear infinite; }
.warn-gear.br .gear{ animation-direction:reverse; }
.warn-vine{ width:clamp(90px,13vw,140px); height:clamp(90px,13vw,140px); opacity:.85; }
.warn-vine.tr{ top:-40px; right:-46px; }
.warn-vine.bl{ bottom:-40px; left:-46px; transform:scale(-1); }
.warn-vine .stem{ fill:none; stroke:var(--verdigris); stroke-width:3; stroke-linecap:round; opacity:.75; }
.warn-vine .leaf{ fill:var(--verdigris); opacity:.55; }
.warn-vine .petal{ fill:var(--bloom); opacity:.85; }
.warn-vine .pistil{ fill:var(--brass-hi); opacity:.9; }
.warn-vine .bud{ fill:var(--bloom); opacity:.55; }

/* NOT YET: the screen goes dark and stays dark until a reload */
body.blackout{ background:#000; }
body.blackout > *{ display:none !important; }

/* the opening hides the run chrome; back-to-menu exists mid-run and
   once the terminal's recovery prompt is open (not mid-cinematic)    */
.eject{ display:none; }
body:has(#p1.on) .eject, body:has(#p2.on) .eject,
body:has(#p3.on) .eject{ display:block; }
body:has(#terminal.prompting) .eject{ display:block; z-index:69; }
body:has(#warning.on) .gear-btn{ display:none; }

/* ================= start-over confirmation ================= */
.modal{
  position:fixed; inset:0; z-index:70;
  display:flex; align-items:center; justify-content:center;
  background:rgba(8,6,4,.65); padding:24px;
}
.modal-plate{
  max-width:30em; padding:30px 38px; text-align:center;
  background:linear-gradient(180deg, rgba(42,33,24,.96), rgba(24,19,14,.96));
  border:1px solid rgba(176,141,87,.55); border-radius:3px;
  box-shadow:inset 0 1px 0 rgba(220,189,128,.18), 0 10px 34px rgba(0,0,0,.6);
}
.modal-text{
  font-style:italic; color:var(--parchment); opacity:.9;
  font-size:clamp(16px,2.2vw,20px); line-height:1.6;
}

/* ================= puzzle 1 ================= */
#p1{ justify-content:center; }
/* the lamp works in the clearing too: morning parchment behind the
   same blurple sunrise — the glow is the clue, it survives BOTH modes */
#p1::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:
    radial-gradient(90% 60% at 50% 0%, #efe4c8 0%, transparent 60%),
    linear-gradient(180deg, #d9cdb0 0%, #e6dcc2 52%, #cfc0a0 100%);
  opacity:1; transition:opacity 1.6s ease;
}
body.p2-dark #p1::before{ opacity:0; }
.horizon-glow{     /* the clue: a sunrise whose sky is Discord blurple */
  position:absolute; left:0; right:0; bottom:0; height:58vh;
  background:
    /* warm sunrise core hugging the horizon… */
    radial-gradient(52% 40% at 50% 100%,
      rgba(255,206,130,.44) 0%, rgba(243,153,104,.28) 36%,
      rgba(216,122,132,.16) 58%, transparent 76%),
    /* …blending up into the blurple sky wash */
    radial-gradient(130% 95% at 50% 115%,
      var(--blurple) 0%, var(--blurple2) 30%, rgba(64,78,237,.4) 52%, transparent 76%);
  opacity:.55; animation:breathe 9s ease-in-out infinite;
  pointer-events:none;
}
@keyframes breathe{ 0%,100%{ opacity:.42; } 50%{ opacity:.62; } }

/* the sun — half-risen behind the tree line, gold bleeding into blurple */
.sun{
  position:absolute; left:50%; bottom:9vh;
  width:clamp(84px,11vw,150px); height:clamp(84px,11vw,150px);
  transform:translateX(-50%);
  border-radius:50%;
  background:radial-gradient(circle at 50% 38%,
    #fff3d6 0%, #ffd98f 42%, #f2a668 74%, rgba(242,166,104,0) 100%);
  box-shadow:
    0 0 46px 18px rgba(255,206,130,.36),
    0 0 130px 70px rgba(235,140,110,.20),
    0 0 240px 140px rgba(88,101,242,.14);
  animation:sunbreathe 9s ease-in-out infinite;
  pointer-events:none;
}
@keyframes sunbreathe{ 0%,100%{ opacity:.82; } 50%{ opacity:.97; } }

.trees{ position:absolute; left:0; right:0; bottom:-2px; height:34vh; pointer-events:none; }
.trees svg{ width:100%; height:100%; display:block; }
.fireflies{ position:absolute; inset:0; pointer-events:none; }

/* foreground meadow — grass tufts and blue blooms (populated by JS).
   width:100% is load-bearing: an absolutely-positioned svg ignores
   left+right and falls back to its intrinsic width otherwise, which
   cropped the meadow to one side of the screen.                      */
.meadow{
  position:absolute; left:0; bottom:-2px; width:100%; height:19vh;
  pointer-events:none;
}
.meadow .blade { fill:none; stroke:#20291f; stroke-width:3; stroke-linecap:round; opacity:.9; }
.meadow .stemm { fill:none; stroke:#33493c; stroke-width:2.5; stroke-linecap:round; opacity:.95; }
.meadow .leafm { fill:#33493c; opacity:.8; }
.meadow .petalm{ fill:var(--bloom); opacity:.88; }
.meadow .pistilm{ fill:var(--brass-hi); opacity:.95; }
.meadow .budm  { fill:var(--bloom); opacity:.6; }
.meadow .bellm { fill:var(--bloom2); opacity:.85; }
.meadow .bellheartm{ fill:var(--brass-hi); opacity:.85; }
.meadow .sway{
  transform-box:fill-box; transform-origin:50% 100%;
  animation:sway 6.5s ease-in-out infinite;
}
/* the flower heads answer to a click (they force a ping) — only the
   heads are hit-targets, the rest of the meadow stays untouchable    */
.meadow .bloom-hit{ pointer-events:auto; cursor:pointer; }
@keyframes sway{ 0%,100%{ transform:rotate(-1.4deg); } 50%{ transform:rotate(1.7deg); } }

/* the code fragment plaque — plain text, deliberately not a link */
.plaque{
  position:relative; z-index:5;
  padding:20px 44px;
  background:linear-gradient(180deg, rgba(42,33,24,.85), rgba(24,19,14,.85));
  border:1px solid rgba(176,141,87,.5);
  border-radius:3px;
  box-shadow:inset 0 1px 0 rgba(220,189,128,.15), inset 0 -8px 16px rgba(0,0,0,.5),
             0 4px 18px rgba(0,0,0,.6);
}
.plaque::before, .plaque::after{   /* rivets */
  content:""; position:absolute; top:8px; width:6px; height:6px; border-radius:50%;
  background:radial-gradient(circle at 35% 35%, var(--brass-hi), var(--copper));
  box-shadow:0 0 3px rgba(0,0,0,.8);
}
.plaque::before{ left:8px; } .plaque::after{ right:8px; }
.plaque-code{
  font-family:var(--osd);
  font-size:clamp(26px,4.6vw,46px);
  letter-spacing:.18em;
  color:var(--parchment);
  text-shadow:0 0 14px rgba(88,101,242,.35);   /* the faintest blurple breath */
}
/* the answer box beneath the plaque */
.answer{ position:relative; z-index:5; margin-top:34px; }
.answer-box{
  font-family:var(--osd); font-size:clamp(15px,2vw,19px);
  letter-spacing:.14em; text-align:center;
  color:var(--parchment);
  width:min(340px,72vw); padding:11px 18px;
  background:linear-gradient(180deg, rgba(20,16,11,.88), rgba(38,30,21,.88));
  border:1px solid rgba(176,141,87,.5); border-radius:3px;
  box-shadow:inset 0 2px 10px rgba(0,0,0,.65);
  outline:none;
  transition:border-color .3s, box-shadow .3s;
}
.answer-box::placeholder{ color:var(--ash); opacity:.55; font-style:italic; letter-spacing:.08em; }
.answer-box:focus{
  border-color:var(--brass-hi);
  box-shadow:inset 0 2px 10px rgba(0,0,0,.65), 0 0 16px rgba(176,141,87,.25);
}
.answer-box.miss{ animation:miss .4s ease; }
@keyframes miss{
  0%,100%{ transform:none; }
  25%{ transform:translateX(-7px); }
  60%{ transform:translateX(6px); }
}
.answer.done .answer-box{ opacity:.35; }
.solved-line{
  position:relative; z-index:5;
  margin-top:22px; font-style:italic;
  color:var(--ash); font-size:clamp(15px,2vw,19px);
  min-height:1.5em;
  opacity:0; transition:opacity 2.4s ease;
}
.solved-line.on{ opacity:.85; }

/* ================= puzzle 2 : the listening room ================= */
/* Daylight by default; the settings lamp switches the room dark and
   the barcode goes translucent, letting the numbers underneath show. */
#p2::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:
    radial-gradient(90% 60% at 50% 0%, #efe4c8 0%, transparent 60%),
    linear-gradient(180deg, #d9cdb0 0%, #e6dcc2 52%, #cfc0a0 100%);
  opacity:1; transition:opacity 1.6s ease;
}
body.p2-dark #p2::before{ opacity:0; }

.gear-btn{
  position:fixed; top:16px; right:20px; z-index:61;
  width:52px; height:52px; padding:4px;
  opacity:.75; transition:opacity .3s, transform .6s ease;
}
.gear-btn:hover{ opacity:1; transform:rotate(22deg); }
.gear-btn svg{ width:100%; height:100%; }
.gear-btn path{ fill:var(--brass); fill-rule:evenodd; }

.settings-panel{
  position:fixed; top:76px; right:20px; z-index:61;
  display:flex; flex-direction:column; gap:16px;
  padding:18px 22px;
  background:linear-gradient(180deg, rgba(42,33,24,.94), rgba(24,19,14,.94));
  border:1px solid rgba(176,141,87,.55); border-radius:3px;
  box-shadow:inset 0 1px 0 rgba(220,189,128,.18), 0 6px 22px rgba(0,0,0,.45);
}
.set-row{ display:flex; align-items:center; gap:12px; }
.set-label{
  font-family:var(--osd); font-size:13px; letter-spacing:.18em;
  color:var(--brass-hi);
}
.mode-toggle{
  position:relative; width:48px; height:22px;
  border:1px solid rgba(176,141,87,.6); border-radius:11px;
  background:linear-gradient(180deg, #16110c, #241c13);
  box-shadow:inset 0 2px 6px rgba(0,0,0,.6);
}
.mode-toggle .knob{
  position:absolute; top:2px; left:3px; width:16px; height:16px; border-radius:50%;
  background:radial-gradient(circle at 35% 35%, var(--brass-hi), var(--copper));
  box-shadow:0 1px 3px rgba(0,0,0,.7);
  transition:left .35s ease;
}
.mode-toggle[aria-checked="true"] .knob{ left:27px; }
.panel-vol{
  -webkit-appearance:none; appearance:none;
  width:130px; height:4px;
  background:linear-gradient(90deg, var(--copper), var(--brass));
  border-radius:2px; outline:none; cursor:pointer;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.7);
}
.panel-vol::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:14px; height:14px; border-radius:50%;
  background:radial-gradient(circle at 35% 35%, var(--brass-hi), var(--copper));
  border:1px solid rgba(0,0,0,.5);
}
.panel-vol::-moz-range-thumb{
  width:14px; height:14px; border-radius:50%;
  background:radial-gradient(circle at 35% 35%, var(--brass-hi), var(--copper));
  border:1px solid rgba(0,0,0,.5);
}

/* two worn hour-dials flank the card — most of their engraving is
   gone; what's left (in config) is the whole clue                    */
.scan-row{
  position:relative; z-index:5;
  display:flex; align-items:center; justify-content:center;
  gap:clamp(16px,3vw,40px); flex-wrap:wrap;
}
.dial{ width:clamp(120px,15vw,180px); height:auto; }
.dial .rim, .dial .hub{ fill:none; stroke:#4a4136; transition:stroke 1.6s ease; }
.dial .rim{ stroke-width:3; }
.dial .hub{ stroke-width:2; }
.dial .div{ stroke:#4a4136; stroke-width:1.3; opacity:.45; transition:stroke 1.6s ease; }
.dial text{ font-family:var(--osd); transition:fill 1.6s ease; }
.dial .num{ fill:#3c352c; font-size:15px; }
.dial .ltr{ fill:var(--copper); font-size:16px; }
.dial .ctr{ fill:#3c352c; font-size:13px; letter-spacing:.06em; }
.dial .ctr-ltr{ fill:var(--copper); font-size:16px; }
body.p2-dark .dial .rim, body.p2-dark .dial .hub{ stroke:var(--brass); }
body.p2-dark .dial .div{ stroke:var(--brass); }
body.p2-dark .dial .num, body.p2-dark .dial .ctr{ fill:var(--brass-hi); }
body.p2-dark .dial .ltr, body.p2-dark .dial .ctr-ltr{ fill:var(--bloom); }
/* each lamp mode reveals its own surviving engravings */
.dial .marks-dk{ display:none; }
body.p2-dark .dial .marks-lit{ display:none; }
body.p2-dark .dial .marks-dk{ display:inline; }

/* the scan card: digits live UNDER the barcode; dark mode thins the
   barcode to let them through (spec: CSS opacity tied to the mode)   */
.scan-card{
  position:relative; z-index:5;
  border-radius:12px;
  box-shadow:0 8px 30px rgba(0,0,0,.35);
}
.scan-digits{
  position:absolute; inset:0; z-index:0;
  display:flex; align-items:center; justify-content:center;
  padding-left:2.6em;                 /* clear of the logo dot */
  font-family:var(--osd); font-size:clamp(15px,2.2vw,22px);
  letter-spacing:.16em; word-spacing:.5em; color:var(--brass-hi);
  text-shadow:0 0 14px rgba(220,189,128,.4);
  white-space:nowrap;
}
.scan-bars{
  position:relative; z-index:1; display:block;
  width:min(440px,84vw); height:auto;
  transition:opacity 1.6s ease;
}
body.p2-dark .scan-bars{ opacity:.07; }
.scan-bars .scan-bg { fill:#efe6d0; }
.scan-bars .scan-dot{ fill:#1d1712; }
.scan-bars .scan-bar{ fill:#1d1712; }

/* the room's dressing — corner gears, sigil circles, filigree arcs.
   Etched copper on the daylight parchment; brass once the lamp dies. */
.p2-decor{
  position:absolute; inset:0; width:100%; height:100%;
  z-index:0; pointer-events:none;
}
.p2-decor .gear { transform-box:fill-box; transform-origin:center; }
.p2-decor .spin     { animation:spin 240s linear infinite; }
.p2-decor .spin-rev { animation:spin 180s linear infinite reverse; }
.p2-decor .sigil{
  transform-box:fill-box; transform-origin:center;
  animation:spin 150s linear infinite;
}
.p2-decor .sigil.rev{ animation-direction:reverse; }
.p2-decor .sig-ring{ fill:none; stroke:var(--copper); stroke-width:2; opacity:.32; }
.p2-decor .sig-ring.dash{ stroke-dasharray:4 8; opacity:.26; }
.p2-decor .sig-tick{ stroke:var(--copper); stroke-width:1.5; opacity:.32; }
.p2-decor .sig-line{ fill:none; stroke:var(--copper); stroke-width:1.5; opacity:.28; }
.p2-decor .sig-node{ fill:var(--copper); opacity:.4; }
.p2-decor .fili{ fill:none; stroke:var(--copper); stroke-width:2; opacity:.24; stroke-linecap:round; }
body.p2-dark .p2-decor .sig-ring, body.p2-dark .p2-decor .sig-tick,
body.p2-dark .p2-decor .sig-line, body.p2-dark .p2-decor .fili{
  stroke:var(--brass); opacity:.4;
}
body.p2-dark .p2-decor .sig-node{ fill:var(--brass); opacity:.5; }

/* p2's answer line sits on parchment in daylight, soot in the dark —
   and now p1 and p3 wear the lamp too, so theirs match               */
#p2 .solved-line{ color:#5b544a; transition:color 1.6s ease, opacity 2.4s ease; }
body.p2-dark #p2 .solved-line{ color:var(--ash); }
#p1 .solved-line, #p3 .solved-line{ transition:color 1.6s ease, opacity 2.4s ease; }
body:not(.p2-dark) #p1 .solved-line,
body:not(.p2-dark) #p3 .solved-line{ color:#5b544a; }
#p2 .answer{ margin-top:38px; }

/* ---- p2 → p3: the cut. A seam slashes down the center of the room,
   then the two halves part slowly on the gearworks behind ---- */
.p2-slice{ position:fixed; inset:0; z-index:30; pointer-events:none; }
.p2-half{
  position:absolute; inset:0; overflow:hidden;
  /* opaque backing (the body's soot) so nothing shows through early */
  background:radial-gradient(120% 100% at 50% 0%, #1c1610 0%, var(--soot) 60%);
  transform:translateX(0);              /* also traps the fixed ghost inside */
  transition:transform 3s cubic-bezier(.6,.02,.35,1);
}
.p2-half.left { clip-path:inset(0 50% 0 0); }
.p2-half.right{ clip-path:inset(0 0 0 50%); }
/* the daylight the room wore — fades out with the lamp, like #p2::before */
.p2-half::before{
  content:""; position:absolute; inset:0;
  background:
    radial-gradient(90% 60% at 50% 0%, #efe4c8 0%, transparent 60%),
    linear-gradient(180deg, #d9cdb0 0%, #e6dcc2 52%, #cfc0a0 100%);
}
body.p2-dark .p2-half::before{ opacity:0; }
.p2-slice.open .p2-half.left { transform:translateX(-56vw); }
.p2-slice.open .p2-half.right{ transform:translateX(56vw); }
/* the blade: a SHORT bright segment that runs up the seam from below
   the frame and off the top — it never lingers as a standing line    */
.p2-seam{
  position:absolute; left:50%; top:100%; width:3px; height:22vh;
  transform:translateX(-50%);
  background:linear-gradient(180deg, transparent, #fff8e0 30%, var(--brass-hi) 72%, transparent);
  box-shadow:0 0 22px rgba(240,223,184,.9), 0 0 60px rgba(176,141,87,.6);
  opacity:0;
}
.p2-slice.cut .p2-seam{
  animation:sliceblade .7s cubic-bezier(.55,.06,.68,.19) forwards;
}
@keyframes sliceblade{
  0%  { opacity:1; transform:translate(-50%, 0); }
  100%{ opacity:1; transform:translate(-50%, calc(-100vh - 22vh)); }
}

/* ================= puzzle 3 : the gearworks ================= */
/* the environment clears away — nothing left but turning gears */
#gearfield{
  position:absolute; inset:0; width:100%; height:100%;
  z-index:0; pointer-events:none;
  transition:opacity 1.6s ease;
}
/* the lamp reaches the gearworks too: parchment daylight behind the
   wall, the gears fading to a lighter etching (like the p2 decor)    */
#p3::after{
  content:""; position:absolute; inset:0; z-index:-1;
  background:
    radial-gradient(90% 60% at 50% 0%, #efe4c8 0%, transparent 60%),
    linear-gradient(180deg, #d9cdb0 0%, #e6dcc2 52%, #cfc0a0 100%);
  opacity:1; transition:opacity 1.6s ease;
}
body.p2-dark #p3::after{ opacity:0; }
body:not(.p2-dark) #gearfield{ opacity:.6; }
/* daylight legibility: dark ink for the monologue and the labels */
body:not(.p2-dark) #p3 .intro-line{
  color:#3c352c; text-shadow:0 0 12px rgba(255,246,220,.6);
}
body:not(.p2-dark) #p3 .p3-label{ color:#6d4a2a; text-shadow:none; }
#p3 .intro-line{ transition:opacity 2s ease, transform 2s ease, color 1.6s ease; }
/* each gear in the wall wears a faint brass edge for definition;
   the huge depth-layer gears stay pure silhouette                    */
#gearfield .gear path{ stroke:rgba(220,189,128,.22); stroke-width:1.2; }
#gearfield .gear.deep path{ stroke:none; }
/* a quiet dark pool behind the words so the monologue and the two
   boxes read clean over the machinery — night only; in daylight the
   gears fade instead and the ink darkens                             */
#p3::before{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(60% 54% at 50% 50%,
    rgba(10,8,5,.8) 0%, rgba(10,8,5,.4) 55%, transparent 78%);
  opacity:1; transition:opacity 1.6s ease;
}
body:not(.p2-dark) #p3::before{ opacity:0; }
/* vines creeping over the gearworks — they cross ABOVE the answer
   boxes (interfering with the puzzle) but never catch the pointer    */
.p3-vines{
  position:absolute; inset:0; width:100%; height:100%;
  z-index:6; pointer-events:none; opacity:.85;
}
.p3-vines .stem{ fill:none; stroke:var(--verdigris); stroke-width:3.5; stroke-linecap:round; opacity:.8; }
.p3-vines .leaf{ fill:var(--verdigris); opacity:.6; }
.p3-vines .petal{ fill:var(--bloom); opacity:.85; }
.p3-vines .pistil{ fill:var(--brass-hi); opacity:.9; }
.p3-vines .bud{ fill:var(--bloom); opacity:.55; }
.p3-vines .bellm{ fill:var(--bloom2); opacity:.8; }
.p3-vines .bellheartm{ fill:var(--brass-hi); opacity:.8; }
.p3-lines{
  position:relative; z-index:5;
  width:min(680px,90vw);
  display:flex; flex-direction:column; gap:14px; align-items:center;
  margin-bottom:36px;
}
.answer3{
  position:relative; z-index:5;
  opacity:0; visibility:hidden;
  transition:opacity 2s ease, visibility 0s linear 2s;
}
.answer3.on{ opacity:1; visibility:visible; transition:opacity 2s ease; }
.answer3.done .answer-box{ opacity:.35; }
.p3-fields{ display:flex; gap:clamp(18px,3vw,34px); flex-wrap:wrap; justify-content:center; }
.p3-field{ display:flex; flex-direction:column; gap:10px; align-items:center; }
.p3-label{
  font-family:var(--osd); font-size:clamp(14px,1.8vw,17px);
  letter-spacing:.3em; color:var(--brass-hi);
  text-shadow:0 0 8px rgba(176,141,87,.4);
  transition:color 1.6s ease, text-shadow 1.6s ease;
}
.p3-field .answer-box{ width:min(240px,70vw); }
.submit-ghost{ position:absolute; left:-9999px; width:1px; height:1px; }

/* ================= the terminal ================= */
.terminal{ position:fixed; inset:0; z-index:68; background:#030503; }
/* CRT vignette — the glass curving away at the edges (retro) */
.terminal::after{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:3;
  box-shadow:inset 0 0 150px rgba(0,0,0,.75);
}
.term-text{
  position:absolute; inset:5vh 5vw;
  margin:0; overflow:hidden;
  font-family:Consolas, 'Courier New', ui-monospace, monospace;
  font-size:clamp(12px,1.6vw,16px); line-height:1.55;
  color:var(--phosphor); white-space:pre-wrap; word-break:break-all;
  text-shadow:0 0 7px rgba(126,214,138,.5);
  transition:opacity .4s ease;
}
.term-text.dim{ opacity:.22; }
.term-text::after{ content:"▮"; animation:blink 1s steps(1) infinite; }
.term-clock{
  position:absolute; left:50%; top:50%;
  width:min(48vh,72vw); height:min(48vh,72vw);
  transform:translate(-50%,-50%);
  /* the brass clocks re-lit in phosphor */
  filter:grayscale(1) sepia(1) hue-rotate(70deg) saturate(2.4) brightness(1.15);
  pointer-events:none;
}
.term-clock svg{ width:100%; height:100%; overflow:visible; }
.term-coords{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  font-family:Consolas, 'Courier New', ui-monospace, monospace;
  font-size:clamp(20px,4.2vw,54px); letter-spacing:.08em;
  color:var(--phosphor); text-shadow:0 0 18px rgba(126,214,138,.7);
  white-space:nowrap; pointer-events:none;
  opacity:0;
}
.term-coords.show{ opacity:1; animation:coordflash 2.2s steps(1) 1; }
@keyframes coordflash{
  0%{ opacity:0; } 12%{ opacity:1; } 24%{ opacity:0; }
  36%{ opacity:1; } 48%{ opacity:.2; } 60%{ opacity:1; }
}
.term-scan{
  position:absolute; inset:0; pointer-events:none;
  background:repeating-linear-gradient(0deg, rgba(0,0,0,.24) 0 2px, transparent 2px 4px);
  animation:termflicker 3.5s steps(70) infinite;
}
.term-scan::after{
  content:""; position:absolute; left:0; right:0; height:120px;
  background:linear-gradient(180deg, transparent, rgba(126,214,138,.06), transparent);
  animation:termroll 7s linear infinite;
}
@keyframes termflicker{ 0%,100%{ opacity:.72; } 8%{ opacity:.9; } 9%{ opacity:.7; }
  40%{ opacity:.82; } 41%{ opacity:.68; } 70%{ opacity:.88; } }
@keyframes termroll{ from{ top:-140px; } to{ top:100%; } }

/* ---- the recovery prompt: a live input at the foot of the glass ---- */
.term-form{
  position:absolute; left:5vw; right:5vw; bottom:6vh; z-index:2;
  display:flex; align-items:center; gap:.7em;
  font-family:Consolas, 'Courier New', ui-monospace, monospace;
  color:var(--phosphor);
}
.term-form::before{
  content:">";
  font-size:clamp(14px,1.8vw,18px);
  text-shadow:0 0 7px rgba(126,214,138,.5);
}
.term-input{
  flex:1; min-width:0;
  background:none; border:none; outline:none;
  border-bottom:1px solid rgba(126,214,138,.35);
  padding:6px 2px;
  font-family:inherit; font-size:clamp(14px,1.8vw,18px);
  letter-spacing:.12em;
  color:var(--phosphor); caret-color:var(--phosphor);
  text-shadow:0 0 7px rgba(126,214,138,.5);
  transition:border-color .3s;
}
.term-input:focus{ border-color:rgba(126,214,138,.7); }
.term-input.miss{ animation:miss .4s ease; }
/* while the prompt is open, the input's caret takes over from the
   boot log's blinking block                                          */
.terminal.prompting .term-text::after{ content:""; }

/* ================= the black veil (scene transitions) ================= */
.dawn{
  position:fixed; inset:0; z-index:45; pointer-events:none;
  background:#000; opacity:0;
  transition:opacity 1.9s ease;              /* the slow lift */
}
.dawn.cover{ opacity:1; transition:opacity 1s ease; }   /* the sink */
.dawn.snap { opacity:1; transition:none; }               /* dead air */

/* p1 → p2: going deeper — the clearing swells past the frame while
   the dark closes in                                                  */
#p1.descend{ animation:descend 1.6s cubic-bezier(.45,.05,.85,.5) forwards; }
@keyframes descend{
  to{ transform:scale(1.75); filter:blur(5px) brightness(.35); }
}

/* old tv: the gearworks clunk off… */
.scene.tv-off{ animation:tvoff .5s cubic-bezier(.65,0,.9,.4) forwards; }
@keyframes tvoff{
  0%  { transform:scale(1,1);        filter:none; }
  60% { transform:scale(1,.012);     filter:brightness(3.4); }
  82% { transform:scale(.5,.006);    filter:brightness(6); }
  100%{ transform:scale(.002,.002);  filter:brightness(9); }
}
/* …and the terminal warms back up */
.terminal.tv-on{ animation:tvon .55s cubic-bezier(.2,.7,.3,1) both; }
@keyframes tvon{
  0%  { transform:scale(0,.004);  filter:brightness(9); }
  45% { transform:scale(1,.004);  filter:brightness(6); }
  78% { transform:scale(1,1.03);  filter:brightness(2); }
  100%{ transform:none;           filter:none; }
}

/* ================= chrome ================= */
.eject{
  position:fixed; bottom:18px; left:24px; z-index:60;
  font-family:var(--osd); font-size:12px; letter-spacing:.16em;
  color:var(--ash); opacity:.35; transition:opacity .3s;
}
.eject:hover{ opacity:.85; }
.mute{
  position:fixed; bottom:18px; right:24px; z-index:60;
  font-family:var(--osd); font-size:14px; letter-spacing:.12em;
  color:var(--ash); opacity:.45; transition:opacity .3s;
}
.mute:hover{ opacity:.9; }

@media (prefers-reduced-motion: reduce){
  .grain, .horizon-glow, .sun, .meadow .sway, .clock .hand.second,
  #gearscape .spin, #gearscape .spin-rev, #gearscape .spin-fast,
  #gearfield .spin, #gearfield .spin-rev, #gearfield .spin-fast,
  .clock .gearbit.turn, .clock .gearbit.turn-rev,
  .clock .reel, .clock .orbitwrap, .clock .orbitwrap.slow,
  .clock .lanternglow, .answer-box.miss, .title,
  .skip-hint.proceed, .skip-hint .burst-line,
  .warn-gear .gear, .term-scan, .term-scan::after,
  .term-text::after, .clock .sandstream,
  #p1.descend, .scene.tv-off, .terminal.tv-on, .term-coords.show,
  .p2-decor .spin, .p2-decor .spin-rev, .p2-decor .sigil,
  .term-input.miss{
    animation:none !important; }
  .fireflies{ display:none; }
}
