/* Horror Project 1 — interface only.

   Deliberately plain: flat greys, one face, square corners, no scanlines, no blur, no
   vignette, no CRT curvature. The look comes from the renderer's 320x240 target, vertex
   snapping and affine texture warping; the DOM stays out of the way. */

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: #000;
  color: #c8c8c4;
  overflow: hidden;
  font-family: "Lucida Console", "DejaVu Sans Mono", "Courier New", ui-monospace, monospace;
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: 0.04em;
  -webkit-font-smoothing: none;
  cursor: default;
}

body[data-state="play"],
body[data-state="ending"] { cursor: none; }

/* ---------------------------------------------------------------- the picture */
#view {
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  display: block;
  background: #000;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  z-index: 0;
}

/* collider debug overlay (F5), drawn in CSS pixels over the letterboxed view */
#overlay {
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  display: block;
  pointer-events: none;
  z-index: 1;
}

#crosshair {
  position: fixed;
  left: 50%;
  top: 50%;
  width: 3px;
  height: 3px;
  margin: -1px 0 0 -1px;
  background: #d8d8d2;
  opacity: 0;
  pointer-events: none;
  z-index: 2;
}
body[data-state="play"] #crosshair,
body[data-state="ending"] #crosshair { opacity: 0.7; }

/* ---------------------------------------------------------------- layers */
.layer {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #07080a;
  z-index: 60;
}
.layer.hidden { display: none; }

.panel {
  width: min(46rem, 84vw);
  padding: 2.2rem 2.4rem;
  background: #0b0d10;
  border: 1px solid #2a2f36;
  box-shadow: 0 0 0 1px #05060a inset;
  text-align: left;
}

.kicker {
  margin: 0 0 1.1rem 0;
  color: #5f6873;
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}

h1 {
  margin: 0 0 0.8rem 0;
  font-size: 2.1rem;
  font-weight: normal;
  letter-spacing: 0.14em;
  color: #e2e2dc;
  text-transform: uppercase;
}

h2 {
  margin: 0 0 1rem 0;
  font-size: 1.15rem;
  font-weight: normal;
  letter-spacing: 0.12em;
  color: #d6d6d0;
}

.tag {
  margin: 0 0 1.6rem 0;
  color: #8d949c;
}

.hint {
  margin: 0.5rem 0 0 0;
  color: #6a727c;
  font-size: 0.86rem;
}
.hint.tiny { font-size: 0.74rem; color: #4f565e; letter-spacing: 0.02em; }

.note { margin-top: 1.2rem; color: #a9b0b8; }
.note p { margin: 0.35rem 0 0 0; }

/* ---------------------------------------------------------------- the opening form */
label#formLabel {
  display: block;
  font-size: 0.8rem;
  letter-spacing: 0.3em;
  color: #6f7883;
  margin-bottom: 0.6rem;
}

#formInput {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 0.5rem 0.2rem;
  background: transparent;
  border: 0;
  border-bottom: 1px solid #39404a;
  color: #e8e8e2;
  font: inherit;
  font-size: 1.5rem;
  letter-spacing: 0.16em;
  outline: none;
}
#formInput:focus { border-bottom-color: #7f8a96; }

/* ---------------------------------------------------------------- note overlay */
#note {
  background: rgba(4, 4, 6, 0.86);
  opacity: 0;
  pointer-events: none;
  transition: opacity 140ms steps(4, end);
  z-index: 30;
}
#note.visible { opacity: 1; pointer-events: auto; }

/* the note is the sheet of paper the player just took off the wall, held up in the dark:
   warm paper, brown ink, so the thing read and the thing seen are the same object */
.panel.sheet {
  width: min(38rem, 82vw);
  background: #cfc7ae;
  background-image: linear-gradient(158deg, rgba(255,255,255,0.40), rgba(116,96,62,0.18));
  border: 1px solid #8d8770;
  box-shadow: 0 0.5rem 2rem rgba(0, 0, 0, 0.6);
  color: #2e2519;
}
.panel.sheet h2 {
  color: #403422;
  font-size: 0.95rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.panel.sheet #noteBody {
  color: #2b2217;
  font-size: 1.02rem;
  line-height: 1.75;
  min-height: 5rem;
}
.panel.sheet #noteBody p { margin: 0 0 0.7rem 0; }
.panel.sheet .hint { color: #6d6148; }

/* the page when it stops being paper */
#note.possessed { background: rgba(0, 0, 0, 0.94); }
#note.possessed .panel.sheet {
  background: #9c8b74;
  color: #1a100c;
  animation: sheetShake 0.12s steps(2, end) infinite;
  box-shadow: 0 0 0 1px #4a1010, 0 0.5rem 2rem rgba(0, 0, 0, 0.8);
}
#note.possessed .panel.sheet h2,
#note.possessed .panel.sheet #noteBody,
#note.possessed .panel.sheet .hint { color: #3a1212; }
@keyframes sheetShake {
  50% { transform: translate(2px, -1px) rotate(-0.4deg); }
}

#stillhere {
  z-index: 80;
  background: #000;
  color: #e6e2da;
}
#stillhere p {
  margin: 0;
  font-size: clamp(1.2rem, 4vw, 2rem);
  letter-spacing: 0.22em;
  text-transform: lowercase;
}

#jumpscare {
  position: fixed;
  inset: 0;
  z-index: 96;
  display: none;
  pointer-events: none;
  background: #1a0504;
}
#jumpscare.on {
  display: block;
  animation: woundHit 0.18s linear;
}
#jumpscare canvas {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
@keyframes woundHit {
  0% { filter: brightness(6) contrast(2.2); }
  12% { filter: brightness(2.2) contrast(1.6); }
  100% { filter: brightness(1) contrast(1.15); }
}

/* touch. Hidden until the body is marked, and only while there is something to do. */
#touch { display: none; }
body.touch[data-state="play"] #touch,
body.touch[data-state="read"] #touch,
body.touch[data-state="ending"] #touch { display: block; }
#touch .pad {
  position: fixed;
  bottom: 1.2rem;
  width: 42vw;
  height: 46vh;
  z-index: 40;
  touch-action: none;
}
#touchStick { left: 0; }
#touchLook { right: 0; }
#touchButtons {
  position: fixed;
  right: 0.6rem;
  bottom: 0.7rem;
  z-index: 41;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
#touchButtons button {
  min-width: 4.6rem;
  min-height: 2.75rem;
  padding: 0.4rem 0.6rem;
  background: rgba(8, 8, 10, 0.72);
  color: #d5d2cb;
  border: 1px solid #3a3a3a;
  font: inherit;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  touch-action: none;
}
#touchHold.down { color: #e6d27a; border-color: #8a7a3a; }

/* ---------------------------------------------------------------- voice, prompt, debug */
#subtitle {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 8vh;
  margin: 0 auto;
  width: min(50rem, 86vw);
  text-align: center;
  color: #dfe2e6;
  font-size: 1.1rem;
  line-height: 1.6;
  text-shadow: 0 2px 0 #000, 2px 0 0 #000, -2px 0 0 #000, 0 -2px 0 #000;
  opacity: 0;
  pointer-events: none;
  z-index: 20;
}
#subtitle.visible { opacity: 1; }

#prompt {
  position: fixed;
  left: 50%;
  top: calc(50% + 2.2rem);
  transform: translateX(-50%);
  color: #cfd3d8;
  font-size: 0.95rem;
  letter-spacing: 0.1em;
  text-shadow: 0 2px 0 #000, 2px 0 0 #000, -2px 0 0 #000, 0 -2px 0 #000;
  opacity: 0;
  pointer-events: none;
  z-index: 20;
}
#prompt.visible { opacity: 1; }

/* ---------------------------------------------------------------- the meters
   Three bars in one column in the upper left: the body, the mind, and the lamp under them. Each
   block keeps its own fixed position, so the column reads top to bottom in that order and the
   three can be read in one glance without crossing the picture. A bar is a plain percentage: the
   filled part is the colour of the thing it measures and the missing part is the dark track, so
   "80 % health" is four fifths red and one fifth nothing. */
.meter {
  position: fixed;
  left: 1.7rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms steps(4, end);
  z-index: 20;
}
body[data-state="play"] .meter,
body[data-state="ending"] .meter { opacity: 1; }

/* one block is a label line and a bar, 30 px all told, so a 2.1rem pitch leaves a small gap */
#hp { top: 1.7rem; }
#sanity { top: 3.8rem; }

.meterLabel {
  margin: 0 0 0.35rem 0;
  font-size: 0.66rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: #6a727c;
  text-shadow: 0 1px 0 #000;
}
.meterLabel b { font-weight: normal; letter-spacing: 0.06em; color: #8d949c; }

.meterBar {
  width: 8.6rem;
  height: 0.42rem;
  background: #0a0c0f;
  border: 1px solid #333a42;
  box-shadow: 0 0 0 1px #05060a inset;
}
#hpFill, #sanityFill { display: block; height: 100%; width: 100%; }

/* the body is the warning colour of the three, and the only one that is not a mood */
#hpFill { background: #b8392c; }
#hp .meterLabel b { color: #bd766c; }

/* the mind is a dark lavender: cold, and deliberately close to the colour of the dark itself */
#sanityFill { background: #6f6096; }
#sanity .meterLabel b { color: #a294c0; }

/* ---------------------------------------------------------------- the lamp gauge
   The lamp is the only thing the player holds, so its gauge closes the column of bars in the
   upper left. It is part of play rather than an overlay: the bar is the charge, and it pulses on
   steps while the hand is winding, so "I am shaking the lamp" and "the lamp is coming back" are
   one read. The fill's own colour is written by `js/game.js` from the light the cell is giving --
   yellow at full, greyish yellow as it dims -- rather than by a class here, because the ramp is a
   continuous one. */
#lamp {
  position: fixed;
  left: 1.7rem;
  top: 5.9rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms steps(4, end);
  z-index: 20;
}
body[data-state="play"] #lamp,
body[data-state="ending"] #lamp { opacity: 1; }

#lampLabel {
  margin: 0 0 0.35rem 0;
  font-size: 0.66rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: #6a727c;
  text-shadow: 0 1px 0 #000;
}
#lampLabel b { font-weight: normal; letter-spacing: 0.06em; color: #8d949c; }

#lampBar {
  width: 8.6rem;
  height: 0.42rem;
  background: #0a0c0f;
  border: 1px solid #333a42;
  box-shadow: 0 0 0 1px #05060a inset;
}
/* full charge, and the colour `js/game.js` fades from. The class rules below change the label
   and the pulse only: the fill's colour is the light level, and an inline style outranks a
   class, so a colour rule here would be a rule that never applies. */
#lampFill { display: block; height: 100%; width: 100%; background: #d9c451; }

/* the beam is about to die: the same threshold the voice warns at */
#lamp.low #lampLabel { color: #9a7c48; }
#lamp.low #lampLabel b { color: #c9a45e; }

/* the hand is working. The pulse is stepped, like everything else on this screen. */
#lamp.charging #lampLabel { color: #cfc7ae; }
#lamp.charging #lampLabel b { color: #e8e0c2; }
#lamp.charging #lampFill { animation: lampCharge 460ms steps(2, end) infinite; }
@keyframes lampCharge {
  0% { opacity: 1; }
  50% { opacity: 0.42; }
  100% { opacity: 1; }
}

/* The readout is a developer's overlay and the meters now hold the upper left, so it takes the
   other corner: both are legible at once and neither hides the other. */
#debug {
  position: fixed;
  right: 0.8rem;
  top: 0.8rem;
  text-align: right;
  color: #9fe08a;
  font-size: 0.7rem;
  line-height: 1.45;
  text-shadow: 0 1px 0 #000;
  opacity: 0;
  pointer-events: none;
  z-index: 21;
  white-space: pre-line;
}
#debug.visible { opacity: 1; }

/* ---------------------------------------------------------------- the end */
#fade {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 2.2s linear;
  z-index: 40;
}
#fade.visible { opacity: 1; }

#card { z-index: 50; background: #000; }

#again {
  margin-top: 1.6rem;
  padding: 0.7rem 1.6rem;
  background: #14171b;
  border: 1px solid #39404a;
  color: #c8c8c4;
  font: inherit;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
}
#again:hover, #again:focus { background: #1d2228; border-color: #6d7883; outline: none; }

/* ---------------------------------------------------------------- failure */
.fatal {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  background: #000;
  color: #b04a4a;
  white-space: pre-wrap;
  text-align: center;
  z-index: 99;
}
