/* The Brothers Mystery.

   The room is a canvas and every word is real HTML on top of it, so the text stays
   crisp at any zoom and can be highlighted a word at a time while it is read out.

   game.js sets --s on #stage to the canvas scale on every resize. The overlay sizes
   itself off --t instead, which is --s with a floor under it: see the note on
   #stage. Only the definition of --t refers to --s directly. */

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: #12131a;
  color: #8d93a6;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 100dvh;
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
  box-sizing: border-box;
  touch-action: manipulation;
}

#stage {
  /* --s is the canvas scale, set by game.js on every resize. Use it for anything
     that should track the size of the room.

     --t is the same number with a floor under it, and everything anybody has to
     read is sized off that instead. On a phone held sideways --s falls to about
     1.25, which put the dialogue at nine pixels: fine for an adult skim reading and
     no use at all to the seven year old this feature exists for. The room can
     afford to be small. The words cannot. */
  --s: 2;
  --t: max(1.6, var(--s));
  position: relative;
  line-height: 0;
  box-shadow: 0 0 0 2px #262b3b, 0 18px 44px rgba(0, 0, 0, 0.6);
}

#screen {
  display: block;
  background: #12131a;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}

#hint {
  margin: 0;
  font-size: 12px;
  text-align: center;
  max-width: 40em;
  line-height: 1.5;
}

@media (pointer: coarse), (max-height: 460px) {
  #hint { display: none; }
}

.sr {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

#rotate {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  text-align: center;
  font-size: 16px;
  line-height: 1.5;
  color: #e8e2d4;
  background: #12131a;
  z-index: 20;
}

@media (pointer: coarse) and (orientation: portrait) {
  #rotate { display: flex; }
}

/* ------------------------------------------------------------------- buttons */

#hud {
  position: absolute;
  top: calc(4px * var(--t));
  right: calc(4px * var(--t));
  display: flex;
  gap: calc(3px * var(--t));
  line-height: 1;
}

#hud button {
  font-size: calc(9px * var(--t));
  line-height: 1;
  padding: calc(3px * var(--t)) calc(4px * var(--t));
  border: 0;
  border-radius: calc(3px * var(--t));
  background: rgba(18, 19, 26, 0.72);
  color: #e8e2d4;
  cursor: pointer;
}

#hud button:hover { background: rgba(18, 19, 26, 0.9); }

/* Off reads as muted, on reads as lit, so the state is obvious without words. */
#raBtn { opacity: 0.45; filter: grayscale(1); }
#raBtn.on { opacity: 1; filter: none; background: rgba(226, 64, 47, 0.75); }

#nbBtn.ping { animation: ping 1.4s ease-out; }

@keyframes ping {
  0%, 100% { transform: none; }
  20% { transform: scale(1.25) rotate(-6deg); }
  50% { transform: scale(1.1) rotate(4deg); }
}

/* ----------------------------------------------------------------- overheard */

#heard {
  position: absolute;
  left: calc(6px * var(--t));
  right: calc(6px * var(--t));
  bottom: calc(6px * var(--t));
  font-size: calc(7.5px * var(--t));
  line-height: 1.45;
  color: #cfd6e6;
  text-align: center;
  font-style: italic;
  text-shadow: 0 calc(0.5px * var(--t)) calc(1.5px * var(--t)) #000;
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
  cursor: pointer;
}

#heard.show { opacity: 1; pointer-events: auto; }
#heard b { color: #ffd7a1; font-style: normal; }

/* ------------------------------------------------------------------ dialogue */

/* Anchored to the bottom and grown upward. A plain beat clears the characters'
   faces; a beat with choices on it does not, which is the usual bargain in this
   kind of game. Everything here is kept as tight as it can be without making the
   reading harder, since the reading is the point. */
#say {
  position: absolute;
  left: calc(6px * var(--t));
  right: calc(6px * var(--t));
  bottom: calc(5px * var(--t));
  box-sizing: border-box;
  max-height: calc(100% - 12px * var(--t));
  overflow-y: auto;
  padding: calc(4.5px * var(--t)) calc(6px * var(--t));
  border-radius: calc(4px * var(--t));
  background: rgba(14, 15, 22, 0.93);
  box-shadow: 0 0 0 calc(1px * var(--t)) rgba(200, 180, 140, 0.28);
  line-height: 1.45;
  cursor: pointer;
}

#who {
  font-size: calc(6.5px * var(--t));
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #ffd7a1;
  margin-bottom: calc(1.5px * var(--t));
}

#line {
  font-size: calc(9.5px * var(--t));
  color: #f2ede1;
  cursor: pointer;
}

/* Narration, when nobody is speaking, sits back a little. */
#say.narration #line { color: #dbd8cd; font-style: italic; }

#stageDir {
  margin-top: calc(2px * var(--t));
  font-size: calc(6.5px * var(--t));
  color: #9aa2b6;
  font-style: italic;
}

#more {
  margin-top: calc(3px * var(--t));
  font-size: calc(6px * var(--t));
  color: #7f879b;
  text-align: right;
}

#opts {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--t));
  margin-top: calc(3.5px * var(--t));
}

.opt {
  font: inherit;
  font-size: calc(7.5px * var(--t));
  text-align: left;
  line-height: 1.35;
  padding: calc(2.5px * var(--t)) calc(4.5px * var(--t));
  border: 0;
  border-left: calc(2px * var(--t)) solid #e2402f;
  border-radius: calc(2px * var(--t));
  background: rgba(255, 255, 255, 0.07);
  color: #f2ede1;
  cursor: pointer;
}

.opt:hover { background: rgba(255, 255, 255, 0.14); }

/* The word being spoken. Deliberately loud: it is a reading aid, not decoration. */
.w.on {
  background: #ffd23f;
  color: #241a12;
  border-radius: 0.18em;
  box-shadow: 0 0 0 0.1em #ffd23f;
}

/* Used when the browser gives us no word events, so at least the line lights up. */
.all { background: rgba(255, 210, 63, 0.22); border-radius: 0.18em; }

/* ------------------------------------------------------- notebook and cover */

#book, #cover, #openText, #board, #solved {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(8px * var(--t));
  box-sizing: border-box;
  background: rgba(10, 11, 16, 0.82);
  line-height: 1.5;
}

#book[hidden], #cover[hidden], #openText[hidden],
#board[hidden], #solved[hidden] { display: none; }

/* The last page and the end sit on nearly black rather than on the room, because by
   then the room has stopped being the point. */
#board { background: rgba(8, 9, 13, 0.94); }
#solved { background: #0b0c11; }

.page {
  width: 100%;
  max-width: calc(210px * var(--t));
  max-height: 100%;
  overflow-y: auto;
  box-sizing: border-box;
  padding: calc(8px * var(--t)) calc(10px * var(--t)) calc(10px * var(--t));
  border-radius: calc(3px * var(--t));
  background: #f4efe2;
  color: #2c2418;
  box-shadow: 0 calc(6px * var(--t)) calc(14px * var(--t)) rgba(0, 0, 0, 0.5);
}

/* Ruled paper, drawn rather than shipped as an image. Only on the cover, where
   there is no list to fall out of step with: ruling the notebook page as well put
   a line through the middle of every entry that wrapped onto two lines. */
#cover .page {
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent calc(2.2em - 1px),
    rgba(120, 140, 170, 0.3) calc(2.2em - 1px),
    rgba(120, 140, 170, 0.3) 2.2em);
}

.page h2 {
  margin: 0 0 calc(6px * var(--t));
  font-size: calc(10px * var(--t));
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #7a3f2c;
}

#notes {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: calc(9px * var(--t));
}

#notes li {
  padding: calc(3px * var(--t)) 0;
  border-bottom: 1px solid rgba(120, 140, 170, 0.4);
  cursor: pointer;
}

#notes li:last-child { border-bottom: 0; }
#notes li:hover { color: #7a3f2c; }
#notes .empty { margin: 0; font-style: italic; color: #6d6250; }

.tip {
  margin: calc(6px * var(--t)) 0 0;
  font-size: calc(6.5px * var(--t));
  font-style: italic;
  color: #6d6250;
}

.rule {
  height: calc(1px * var(--t));
  background: #2c2418;
  opacity: 0.5;
  margin: calc(10px * var(--t)) 0 calc(6px * var(--t));
}

#coverPick {
  display: flex;
  gap: calc(6px * var(--t));
  flex-wrap: wrap;
  min-height: calc(18px * var(--t));
  align-items: center;
}

.pick {
  font: inherit;
  font-size: calc(12px * var(--t));
  padding: calc(4px * var(--t)) calc(12px * var(--t));
  border: calc(1px * var(--t)) solid #2c2418;
  border-radius: calc(3px * var(--t));
  background: transparent;
  color: #2c2418;
  cursor: pointer;
}

.pick:hover { background: #2c2418; color: #f4efe2; }

/* The name, once written, in ink. */
.written {
  font-size: calc(14px * var(--t));
  color: #2c3c8a;
  transform: rotate(-2deg);
  letter-spacing: 0.02em;
}

/* ------------------------------------------------------------- the last page */

/* Filled in slots, which stay on the page while the next question is asked, so the
   player can see the case being written down under their own hand. */
.slotRow {
  display: flex;
  align-items: baseline;
  gap: calc(5px * var(--t));
  padding: calc(2px * var(--t)) 0;
  border-bottom: 1px solid rgba(120, 140, 170, 0.4);
}

.slotAsk {
  font-size: calc(6.5px * var(--t));
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #7a3f2c;
  flex: 0 0 auto;
}

.slotVal { font-size: calc(11px * var(--t)); }

#boardAsk {
  margin-top: calc(6px * var(--t));
  font-size: calc(8px * var(--t));
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #7a3f2c;
}

#boardAsk:empty { margin-top: 0; }

.names {
  display: flex;
  flex-wrap: wrap;
  gap: calc(4px * var(--t));
  margin-top: calc(4px * var(--t));
}

.names:empty { margin-top: 0; }

.pickName {
  font: inherit;
  font-size: calc(9px * var(--t));
  padding: calc(2.5px * var(--t)) calc(7px * var(--t));
  border: calc(1px * var(--t)) solid #2c2418;
  border-radius: calc(2px * var(--t));
  background: transparent;
  color: #2c2418;
  cursor: pointer;
}

.pickName:hover:not(:disabled) { background: #2c2418; color: #f4efe2; }

/* Crossed off rather than removed, so the player can see the list running out. */
.pickName.struck {
  text-decoration: line-through;
  text-decoration-thickness: calc(1px * var(--t));
  opacity: 0.45;
  cursor: default;
}

/* The one line left on the page once every living person has been crossed off.
   Nobody tells the player what goes on it. */
.blankLine {
  flex: 0 0 100%;      /* always on its own line, under the crossed off names */
  width: calc(96px * var(--t));
  margin-top: calc(3px * var(--t));
  height: calc(15px * var(--t));
  border: 0;
  border-bottom: calc(1.5px * var(--t)) solid #2c3c8a;
  background: transparent;
  cursor: pointer;
  animation: waiting 1.8s ease-in-out infinite;
}

@keyframes waiting {
  0%, 100% { border-bottom-color: #2c3c8a; }
  50% { border-bottom-color: #8f9ad4; }
}

.said {
  margin: calc(7px * var(--t)) 0 0;
  min-height: calc(24px * var(--t));
  font-size: calc(9px * var(--t));
  font-style: italic;
  color: #43382a;
  cursor: pointer;
}

/* ------------------------------------------------------------------ the end */

.endPage { text-align: center; }

.by {
  margin: 0;
  font-size: calc(8px * var(--t));
  font-style: italic;
  color: #6d6250;
}

.solvedLine {
  margin: calc(3px * var(--t)) 0;
  font-size: calc(9.5px * var(--t));
  color: #2c2418;
  cursor: pointer;
}

#againBtn { margin-top: calc(8px * var(--t)); font-size: calc(9.5px * var(--t)); }

#openText {
  flex-direction: column;
  background: #0b0c11;
  cursor: pointer;
  text-align: center;
}

.openLine {
  margin: 0;
  max-width: calc(190px * var(--t));
  font-size: calc(11px * var(--t));
  line-height: 1.6;
  color: #f2ede1;
}

#openText .tip { color: #5f6678; }
