* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  height: 100dvh;
  background: #0a0b1e;
  overflow: hidden;
  font-family: 'Nunito', system-ui, sans-serif;
  color: #f4f1ea;
  -webkit-tap-highlight-color: transparent;
}

#game {
  display: block;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  touch-action: none;
}

.pixel {
  font-family: 'Pixelify Sans', monospace;
}

#hud {
  position: fixed;
  top: 14px;
  left: 16px;
  z-index: 20;
  font-family: 'Pixelify Sans', monospace;
  font-size: 16px;
  color: #ecc34a;
  text-shadow: 2px 2px 0 #1a1428;
  pointer-events: none;
}

#hint {
  position: fixed;
  bottom: 14px;
  left: 16px;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  max-width: min(560px, calc(100vw - 32px));
  font-family: 'Pixelify Sans', monospace;
  font-size: 15px;
  line-height: 1;
  color: #c3c8ea;
  text-shadow: 1px 1px 0 #10122a;
  pointer-events: none;
}

/* one control = its keys, then what they do */
#hint .ctl {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: rgba(12, 14, 34, 0.72);
  border: 1px solid #2b2f57;
  border-radius: 7px;
  padding: 5px 9px;
}

#hint .key {
  display: inline-block;
  min-width: 20px;
  padding: 2px 6px;
  border: 1px solid #ecc34a;
  border-bottom-width: 3px;
  border-radius: 5px;
  background: rgba(30, 26, 12, 0.85);
  color: #ecc34a;
  font-size: 14px;
  text-align: center;
}

#hint .lbl {
  color: #9aa0c8;
  font-size: 14px;
}

body.touch #hint {
  display: none;
}

/* On-screen controls (phones/tablets) */
#touch {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 20;
  display: none;
  justify-content: space-between;
  align-items: flex-end;
  padding: 18px 18px 22px;
  pointer-events: none;
}

body.touch #touch {
  display: flex;
}

.pad {
  display: flex;
  gap: 14px;
  pointer-events: auto;
}

.btn {
  font-family: 'Pixelify Sans', monospace;
  font-size: 13px;
  color: #f4f1ea;
  background: rgba(20, 22, 52, 0.82);
  border: 3px solid #ecc34a;
  border-radius: 10px;
  width: 72px;
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  box-shadow: 0 4px 0 #1a1428;
  cursor: pointer;
}

.btn.wide {
  width: 104px;
}

.tri {
  display: block;
  width: 0;
  height: 0;
}

.tri-left {
  border-top: 18px solid transparent;
  border-bottom: 18px solid transparent;
  border-right: 28px solid #f4f1ea;
}

.tri-right {
  border-top: 18px solid transparent;
  border-bottom: 18px solid transparent;
  border-left: 28px solid #f4f1ea;
}

.tri-up {
  border-left: 18px solid transparent;
  border-right: 18px solid transparent;
  border-bottom: 28px solid #f4f1ea;
}

.btn.act {
  border-color: #34a853;
  color: #7cf0a0;
}

.btn:active {
  background: rgba(10, 11, 30, 0.95);
  box-shadow: 0 1px 0 #1a1428;
}

#btn-open {
  visibility: hidden;
}

#hearts {
  position: fixed;
  top: 46px;
  right: 16px;
  z-index: 20;
  font-size: 22px;
  letter-spacing: 4px;
  pointer-events: none;
  text-shadow: 2px 2px 0 #1a1428;
}

/* sits beside the sound button, same treatment */
#fullscreen {
  position: fixed;
  top: 10px;
  right: 56px;
  z-index: 58;
  width: 34px;
  height: 34px;
  font-size: 17px;
  line-height: 1;
  padding: 0;
  background: rgba(20, 22, 52, 0.82);
  border: 2px solid #ecc34a;
  border-radius: 8px;
  color: #ecc34a;
  cursor: pointer;
}

#fullscreen:hover {
  background: #ecc34a;
  color: #12101f;
}

#mute {
  position: fixed;
  top: 10px;
  right: 14px;
  /* above the chest modal and the finale, so sound is always one tap away.
     Only the boot terminal (z-index 60) is allowed to cover it. */
  z-index: 58;
  width: 34px;
  height: 34px;
  font-size: 17px;
  line-height: 1;
  padding: 0;
  background: rgba(20, 22, 52, 0.82);
  border: 2px solid #ecc34a;
  border-radius: 8px;
  color: #ecc34a;
  cursor: pointer;
}

#hearts .h {
  color: #ff5c7a;
}

#hearts .h.lost {
  color: #3a3f66;
}

#rotate-overlay {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: none;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 30px;
  background: #0a0b1e;
}

#rotate-overlay.show {
  display: flex;
}

.rotate-icon {
  width: 52px;
  height: 88px;
  border: 4px solid #ecc34a;
  border-radius: 10px;
  margin: 0 auto 22px;
  animation: rotate-hint 2.2s ease-in-out infinite;
}

@keyframes rotate-hint {

  0%,
  35% {
    transform: rotate(0deg);
  }

  55%,
  100% {
    transform: rotate(90deg);
  }
}

.rotate-msg {
  font-family: 'Pixelify Sans', monospace;
  font-size: 12px;
  line-height: 1.9;
  color: #ecc34a;
}

@media (prefers-reduced-motion: reduce) {
  .rotate-icon {
    animation: none;
  }
}

#loaderr-overlay {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: none;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 30px;
  background: #0a0b1e;
}

#loaderr-overlay.show {
  display: flex;
}

#loaderr-msg {
  max-width: 520px;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.7;
  color: #f4f1ea;
}

#loaderr-msg code {
  font-family: 'Pixelify Sans', monospace;
  color: #ecc34a;
  background: #141634;
  padding: 2px 6px;
  border-radius: 6px;
}

/* ---------- shared: content panel + achievement bar ----------
   This used to be an aged-parchment sheet with a torn clip-path. The ragged
   edge cut into the first and last lines of the text and into the photo, and
   dark brown on mottled tan was hard to read, so it is a plain panel now, in
   the same colours as the rest of the game. */
.parchment {
  position: relative;
  color: #f0e9dc;
  background: #191c3d;
  border: 1px solid #343a6b;
  border-radius: 10px;
  padding: 18px;
}

.achieve {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  background: linear-gradient(180deg, #1e2246, #141634);
  border: 2px solid #ecc34a;
  border-radius: 12px;
  padding: 11px 15px;
  box-shadow: 0 0 0 2px rgba(236, 195, 74, 0.14);
}

.achieve-badge {
  font-size: 26px;
  line-height: 1;
}

.achieve-title {
  font-family: 'Pixelify Sans', monospace;
  font-size: 14px;
  color: #ecc34a;
  line-height: 1.3;
}

.achieve-count {
  font-family: 'Pixelify Sans', monospace;
  font-size: 11px;
  color: #b9bde0;
  margin-top: 3px;
}

/* Chest modal */
#modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  overflow: hidden;
  overflow-anchor: none;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(6, 7, 20, 0.86);
}

#modal-overlay.show {
  display: flex;
}

.modal {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 94%;
  max-width: 880px;
  max-height: 90vh;
  overflow: hidden;
  background: #141634;
  border: 3px solid #ecc34a;
  border-radius: 16px;
  padding: 22px 22px 24px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .22s ease, transform .22s ease;
}

#modal-overlay.show .modal {
  opacity: 1;
  transform: translateY(0);
}

.modal-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 34px;
  height: 34px;
  z-index: 2;
  border: 2px solid #4a4f7a;
  background: rgba(20, 22, 52, 0.8);
  color: #cfd3f0;
  border-radius: 8px;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.modal-close:hover {
  border-color: #ecc34a;
  color: #ecc34a;
}

.achieve {
  margin: 0 0 18px;
}

.parchments {
  display: flex;
  flex: 1 1 auto;
  gap: 16px;
  align-items: stretch;
  min-height: 0;          /* lets the text column shrink so it can scroll */
}

.parchments .parchment {
  flex: 1 1 0;
  min-width: 0;
}

/* only the words scroll: the photo has nothing below it worth scrolling to,
   and scrolling it away while reading was the annoying part */
.parchment-text {
  overflow-y: auto;
  min-height: 0;
  /* The photos are several megabytes and arrive after the modal is on screen.
     When one lands the column grows, and the browser's scroll anchoring nudges
     the scroll position to keep what you were looking at still - which reads as
     the text scrolling itself. Nothing here needs anchoring. */
  overflow-anchor: none;
}

.parchment-photo {
  flex: 0 1 42%;
  align-self: flex-start;
  overflow: visible;
}

.wish {
  margin: 0;
  font-family: 'Georgia', 'Times New Roman', serif;
  font-size: 17px;
  line-height: 1.7;
  color: #f0e9dc;
  white-space: pre-wrap;
}

/* Full-screen photo view. Screenshots of conversations are unreadable at
   thumbnail size, so any photo can be opened to fill the screen. */
#lightbox {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(5, 4, 12, 0.96);
  padding: 12px;
  touch-action: none;
}

#lightbox.show {
  display: flex;
}

#lb-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 4px;
  cursor: zoom-out;
}

/* zoomed: fills the width and scrolls, for long screenshots */
#lightbox.zoom {
  align-items: flex-start;
  overflow: auto;
  padding: 0;
}

#lightbox.zoom #lb-img {
  max-width: none;
  max-height: none;
  width: 100%;
  height: auto;
  border-radius: 0;
  cursor: zoom-in;
}

/* paging arrows, shown only when the set actually has more than one photo */
.lb-arrow {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  width: 46px;
  height: 64px;
  padding: 0;
  font: 30px/1 system-ui, sans-serif;
  color: #ecc34a;
  background: rgba(20, 22, 52, 0.85);
  border: 2px solid #ecc34a;
  border-radius: 8px;
  cursor: pointer;
  display: none;
}

#lightbox.multi .lb-arrow {
  display: block;
}

.lb-arrow:hover {
  background: #ecc34a;
  color: #12101f;
}

#lb-prev { left: 12px; }
#lb-next { right: 12px; }

#lb-close {
  position: fixed;
  top: 12px;
  right: 14px;
  z-index: 2;
  width: 42px;
  height: 42px;
  padding: 0;
  font: 26px/1 system-ui, sans-serif;
  color: #f0e9dc;
  background: rgba(20, 18, 40, 0.9);
  border: 2px solid #3a3357;
  border-radius: 8px;
  cursor: pointer;
}

#lb-close:hover {
  border-color: #ecc34a;
  color: #ecc34a;
}

.lb-arrow {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 44px;
  height: 60px;
  padding: 0;
  font: 30px/1 system-ui, sans-serif;
  color: #f0e9dc;
  background: rgba(20, 18, 40, 0.85);
  border: 2px solid #3a3357;
  border-radius: 8px;
  cursor: pointer;
}

.lb-arrow:hover {
  border-color: #ecc34a;
}

#lb-prev { left: 10px; }
#lb-next { right: 10px; }

#lb-count {
  position: fixed;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  padding: 5px 12px;
  font: 12px/1 'Pixelify Sans', monospace;
  letter-spacing: 2px;
  color: #b9a9d0;
  background: rgba(20, 18, 40, 0.85);
  border-radius: 6px;
}

/* a photo anywhere is a thing you can open */
.gallery img,
.letter-photo {
  cursor: zoom-in;
}

/* small hint sitting on the corner of a photo */
.photo-open {
  position: absolute;
  right: 8px;
  bottom: 8px;
  padding: 4px 9px;
  font: 11px/1 'Pixelify Sans', monospace;
  letter-spacing: 1px;
  color: #f0e9dc;
  background: rgba(12, 10, 26, 0.82);
  border: 1px solid #3a3357;
  border-radius: 6px;
  cursor: zoom-in;
  pointer-events: auto;
}

.photo-wrap {
  position: relative;
  display: block;
}

.gallery {
  display: flex;
  flex-direction: column;
}

.gallery img {
  display: block;
  width: 100%;
  max-height: 52vh;
  object-fit: contain;
  border-radius: 6px;
  border: 1px solid #343a6b;
  background: #0f1130;
}

.photo-ph {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 150px;
  border: 1px dashed #4a4f7a;
  border-radius: 6px;
  color: #8a90b8;
  text-align: center;
  padding: 18px;
  font-size: 14px;
  font-family: 'Georgia', serif;
}

.photo-ph code {
  font-family: 'Pixelify Sans', monospace;
  font-size: 10px;
  color: #7a4a1e;
  word-break: break-all;
}

.gal-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 12px;
}

.gal-arrow {
  width: 40px;
  height: 40px;
  border: 2px solid #4a4f7a;
  background: rgba(20, 22, 52, 0.8);
  color: #cfd3f0;
  border-radius: 8px;
  font-size: 20px;
  cursor: pointer;
}

.gal-arrow:hover {
  border-color: #ecc34a;
  color: #ecc34a;
}

.dots {
  display: flex;
  gap: 7px;
}

.dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #4a4f7a;
}

.dot.on {
  background: #ecc34a;
}

/* Game over */
#gameover-overlay {
  position: fixed;
  inset: 0;
  z-index: 55;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 28px;
  background: rgba(6, 7, 20, 0.9);
}

#gameover-overlay.show {
  display: flex;
}

.over-title {
  font-family: 'Pixelify Sans', monospace;
  font-size: clamp(20px, 6vw, 38px);
  color: #ff6f91;
  text-shadow: 3px 3px 0 #1a1428;
  margin: 0 0 16px;
}

.over-msg {
  font-size: clamp(15px, 2.6vw, 19px);
  line-height: 1.6;
  color: #cfd3f0;
  margin: 0 0 24px;
}

/* Final celebration */
#final-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
}

#final-overlay.show {
  display: block;
}

#confetti {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.final-inner {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  gap: 18px;
  overflow: auto;
  background: rgba(6, 7, 20, 0.55);
}

.final-parchment {
  width: 100%;
  max-width: 640px;
  padding: 30px 28px;
}

.final-title {
  font-family: 'Pixelify Sans', monospace;
  font-size: clamp(20px, 6vw, 38px);
  color: #ecc34a;
  margin: 0 0 6px;
  line-height: 1.25;
}

.final-name {
  font-family: 'Pixelify Sans', monospace;
  font-size: clamp(14px, 4.2vw, 22px);
  color: #b9a9d0;
  margin: 0 0 16px;
}

.final-msg {
  font-family: 'Georgia', 'Times New Roman', serif;
  font-size: clamp(16px, 2.6vw, 20px);
  line-height: 1.7;
  color: #f0e9dc;
  white-space: pre-wrap;
}

.hearts {
  margin: 16px 0 0;
  font-size: 24px;
  color: #c23b57;
  letter-spacing: 8px;
}

.final-btn {
  font-family: 'Pixelify Sans', monospace;
  font-size: 12px;
  color: #f4f1ea;
  background: rgba(20, 22, 52, 0.9);
  border: 3px solid #ecc34a;
  border-radius: 10px;
  padding: 14px 22px;
  cursor: pointer;
  box-shadow: 0 4px 0 #1a1428;
}

.final-btn:active {
  box-shadow: 0 1px 0 #1a1428;
}

/* Closed until the day */
#gate-overlay {
  position: fixed; inset: 0; z-index: 80; display: none;
  background: #0b0a14; color: #f0e9dc;
  align-items: center; justify-content: center; text-align: center; padding: 24px;
}
#gate-overlay.show { display: flex; }
.gate-inner { max-width: 520px; }
#gate-title-txt {
  font-size: clamp(20px, 5vw, 30px); font-weight: 400;
  letter-spacing: 4px; margin: 0 0 16px; color: #ecc34a;
}
#gate-msg { font-size: 15px; line-height: 1.7; margin: 0 0 22px; color: #d8cfe8; }
#gate-count {
  font: 15px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: 3px; color: #9a8ab0;
}

/* Finale: three marks, drawn from memory */
/* Full-screen photo. Above everything except the boot terminal, so it can be
   opened from the chest gallery and from the letter alike. */
#lightbox {
  position: fixed;
  inset: 0;
  z-index: 59;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  /* fully opaque: at 95% the on-screen movement arrows underneath showed
     through, and looked like gallery arrows that did nothing */
  background: #05040c;
  cursor: zoom-out;
}

#lightbox.show {
  display: flex;
}

#lb-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 4px;
  cursor: default;
}

#lb-close {
  position: fixed;
  top: 12px;
  right: 14px;
  width: 42px;
  height: 42px;
  padding: 0;
  font: 26px/1 system-ui, sans-serif;
  color: #ecc34a;
  background: rgba(20, 22, 52, 0.85);
  border: 2px solid #ecc34a;
  border-radius: 8px;
  cursor: pointer;
}

#lb-close:hover {
  background: #ecc34a;
  color: #12101f;
}

/* anything that opens full screen says so on hover */
.letter-photo,
#m-gallery img {
  cursor: zoom-in;
}

/* Seal: the mark has to be drawn before a chest will open */
#seal-overlay {
  position: fixed;
  inset: 0;
  z-index: 46;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 14px;
  background: rgba(6, 5, 14, 0.92);
}

#seal-overlay.show {
  display: flex;
}

.seal-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
  color: #f0e9dc;
}

#seal-title {
  margin: 0;
  font-family: 'Pixelify Sans', monospace;
  font-size: 15px;
  letter-spacing: 2px;
  color: #ecc34a;
}

#seal-pad {
  width: min(300px, 78vw, 56vh);
  height: min(300px, 78vw, 56vh);
  background: #100e1c;
  border: 2px solid #2f2a44;
  touch-action: none;
  cursor: crosshair;
}

#seal-hint {
  margin: 0;
  min-height: 18px;
  max-width: 380px;
  font-size: 12.5px;
  line-height: 1.45;
  color: #b9a9d0;
}

.seal-actions {
  display: flex;
  gap: 8px;
}

/* landscape phone: pad beside the words, so nothing scrolls */
@media (max-height: 560px) and (orientation: landscape) {
  .seal-card {
    flex-direction: row;
    align-items: center;
    gap: 20px;
    text-align: left;
  }

  .seal-card > #seal-pad {
    order: 2;
    width: min(80vh, 42vw);
    height: min(80vh, 42vw);
  }

  #seal-title,
  #seal-hint,
  .seal-actions {
    max-width: 42vw;
  }
}

/* Briefing: shown once, before the first world */
#brief-overlay {
  position: fixed;
  inset: 0;
  z-index: 45;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 18px;
  background: rgba(6, 5, 14, 0.9);
}

#brief-overlay.show {
  display: flex;
}

.brief-card {
  max-width: 560px;
  width: 100%;
  max-height: 92vh;
  overflow-y: auto;
  padding: 20px 22px;
  background: #12101f;
  border: 2px solid #3a3357;
  border-radius: 10px;
  text-align: left;
  color: #f0e9dc;
}

#brief-title {
  margin: 0 0 12px;
  font-family: 'Pixelify Sans', monospace;
  font-size: 17px;
  letter-spacing: 3px;
  color: #ecc34a;
}

/* the opening letter is prose, the how-it-works panel is a list; a panel may
   carry either */
#brief-prose p {
  margin: 0 0 12px;
  font-size: 14px;
  line-height: 1.68;
  color: #e4dcf2;
}

#brief-prose:empty {
  display: none;
}

#brief-lines {
  margin: 0 0 16px;
  padding-left: 18px;
}

#brief-lines:empty {
  display: none;
}

#brief-lines li {
  margin: 0 0 9px;
  font-size: 14px;
  line-height: 1.6;
  color: #d8cfe8;
}

#brief-ok {
  display: block;
  margin: 0 0 0 auto;
}

#fin-overlay {
  position: fixed; inset: 0; z-index: 55; display: none;
  background: #0b0a14; color: #f0e9dc;
  overflow-y: auto; padding: 20px 16px 40px;
  text-align: center;
}
#fin-overlay.show { display: block; }
.fin-col { display: contents; }   /* portrait: the column is invisible, items stack as before */
#fin-intro { max-width: 620px; margin: 6px auto 14px; line-height: 1.6; font-size: 15px; }
#fin-sockets { display: flex; gap: 14px; justify-content: center; margin: 10px 0 14px; }
.fin-socket {
  width: 72px; height: 72px; border: 2px solid #2f2a44;
  display: flex; align-items: center; justify-content: center;
  background: #100e1c;
}
.fin-socket.active { border-color: #ecc34a; }
.fin-socket.done { border-color: #6fd08a; }
.fin-socket canvas { width: 100%; height: 100%; }
#fin-pad {
  /* square, and never taller than the room actually available */
  width: min(320px, 84vw, 52vh);
  height: min(320px, 84vw, 52vh);
  background: #100e1c; border: 2px solid #2f2a44; touch-action: none; cursor: crosshair;
}

/* A landscape phone is wide and very short, so the stacked column did not fit
   and she had to scroll mid-drawing. Here the stage becomes two columns: what
   she needs to read on the left, the pad on the right, both sized to the height
   of the screen rather than to the text. */
/* Portrait phone: the finale is exempt from the rotate prompt, so it has to be
   comfortable held upright - one column, pad sized to the width. */
@media (orientation: portrait) {
  #fin-stage {
    display: block;
  }

  #fin-pad {
    width: min(320px, 82vw);
    height: min(320px, 82vw);
    margin: 0 auto;
  }

  #fin-letter {
    max-width: 100%;
  }

  #fin-letter-body p {
    font-size: 14px;
  }
}

@media (max-height: 560px) and (orientation: landscape) {
  #fin-overlay {
    padding: 10px 14px;
    overflow: hidden;
  }

  #fin-stage {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 22px;
    height: 100vh;
    height: 100dvh;
    text-align: left;
  }

  .fin-col {
    display: flex;   /* landscape: becomes a real column beside the pad */
    flex-direction: column;
    justify-content: center;
    max-width: 46vw;
  }

  #fin-intro {
    margin: 0 0 10px;
    font-size: 13px;
    line-height: 1.45;
    max-height: 34vh;
    overflow-y: auto;
  }

  #fin-sockets {
    justify-content: flex-start;
    gap: 10px;
    margin: 0 0 10px;
  }

  .fin-socket {
    width: 54px;
    height: 54px;
  }

  #fin-hint {
    margin: 8px 0 0;
    font-size: 12px;
    line-height: 1.4;
    text-align: left;
  }

  #fin-actions {
    margin-top: 8px;
  }

  .fin-btn {
    padding: 8px 14px;
    font-size: 12px;
    margin: 0;
  }

  #fin-pad {
    width: min(86vh, 46vw);
    height: min(86vh, 46vw);
    flex: 0 0 auto;
  }

  /* the letter still scrolls - it is meant to be read, not drawn on */
  #fin-letter {
    max-height: 100vh;
    max-height: 100dvh;
    overflow-y: auto;
  }
}
#fin-hint { min-height: 22px; color: #b9a9d0; font-size: 13px; margin: 10px auto; max-width: 560px; }
.fin-btn {
  font-family: inherit; font-size: 13px; letter-spacing: 1px;
  padding: 10px 18px; margin: 4px;
  background: #1a1730; color: #f0e9dc; border: 2px solid #3a3357; cursor: pointer;
}
.fin-btn:hover { border-color: #ecc34a; }
#fin-letter { display: none; max-width: 640px; margin: 0 auto; text-align: left; }
#fin-letter.show { display: block; }
.letter-title {
  font-family: 'Pixelify Sans', monospace;
  font-size: 20px;
  letter-spacing: 3px;
  color: #ecc34a;
  text-align: center;
  margin: 0 0 14px;
}

.letter-portrait {
  display: block;
  margin: 0 auto 10px;
  image-rendering: pixelated;
  width: 150px;
  height: 150px;
}

/* Photos always run down the page, one after another. Side by side made each
   one too small to read, and these are screenshots of conversations. */
.letter-photos {
  display: block;
  margin: 0 0 18px;
}

.letter-photos .letter-photo + .letter-photo {
  margin-top: 10px;
}

.letter-photo {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid #2f2a44;
  border-radius: 4px;
}

.letter-strip {
  display: block;
  width: 100%;
  height: auto;
  margin: 26px 0 4px;
  border: 1px solid #2f2a44;
}

#fin-letter-body p { line-height: 1.7; font-size: 15px; margin: 0 0 16px; }
#fin-letter-body .sec { color: #ecc34a; font-size: 12px; letter-spacing: 3px; margin: 22px 0 6px; }
#fin-actions2 { text-align: center; margin: 20px 0 10px; }
#print-area { display: none; }
@media print {
  /* The printed page is meant to look like the final screen, not like a
     document. Dark ground, same type, same gold headings. Browsers drop
     background colours on paper unless told otherwise, hence print-color-adjust
     - in Chrome's dialog this is the "Background graphics" checkbox. */
  @page {
    margin: 0;
  }

  /* The screen sets html/body to one viewport tall with overflow hidden. On
     paper that clipped the dark ground to the height of the text and left the
     rest of the sheet white, so both are released here. */
  html,
  body {
    height: auto !important;
    min-height: 0 !important;
    overflow: visible !important;
    background: #0b0a14 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  body > * {
    display: none !important;
  }

  #print-area {
    display: block !important;
    position: relative;
    background: #0b0a14;
    color: #f0e9dc;
    font-family: 'Nunito', system-ui, sans-serif;
    padding: 16mm 18mm;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* A fixed layer is re-painted on every sheet, so page two onwards is dark
     too - a background that only follows the content stops at the last line. */
  #print-area::before {
    content: '';
    position: fixed;
    top: -2mm;
    left: -2mm;
    right: -2mm;
    bottom: -2mm;
    background: #0b0a14;
    z-index: -1;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  #print-area .letter-title {
    font-family: 'Pixelify Sans', monospace;
    font-size: 15pt;
    letter-spacing: 3pt;
    color: #ecc34a;
    text-align: center;
    margin: 0 0 8mm;
  }

  #print-area .letter-portrait {
    display: block;
    width: 34mm;
    height: 34mm;
    margin: 0 auto 6mm;
    image-rendering: pixelated;
  }

  #print-area .letter-strip {
    display: block;
    width: 100%;
    height: auto;
    margin: 9mm 0 2mm;
    border: 0.4pt solid #2f2a44;
    break-inside: avoid;
    break-after: avoid;
  }

  #print-area .sec {
    color: #ecc34a;
    font-size: 8pt;
    letter-spacing: 3pt;
    margin: 0 0 4mm;
    break-after: avoid;
  }

  #print-area .letter-photos {
    display: block;
    margin: 0 0 6mm;
  }

  #print-area .letter-photo {
    display: block;
    width: 100%;
    max-height: 150mm;          /* never taller than the page it sits on */
    object-fit: contain;
    margin: 0 0 4mm;
    border: 0.4pt solid #2f2a44;
    break-inside: avoid;        /* a photo must not be sliced in half */
  }

  #print-area p {
    font-size: 10.5pt;
    line-height: 1.75;
    margin: 0 0 5mm;
    orphans: 3;
    widows: 3;
  }
}


/* Boot terminal */
#term-overlay {
  position: fixed; inset: 0; z-index: 60;
  background: #05060a; color: #9fe6a6;
  font: 13px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  padding: 18px 16px 26px; overflow-y: auto;
  display: none; -webkit-user-select: none; user-select: none;
}
#term-overlay.show { display: block; }
#term-body { white-space: pre-wrap; word-break: break-word; }
#term-line { display: flex; align-items: baseline; }
#term-prompt { color: #6fd08a; white-space: pre; }

/* A real input, dressed to look like the rest of the line. Mirroring a hidden
   field into a span meant managing the caret by hand, which soft keyboards do
   not cooperate with - typing came out backwards and deletion did nothing.
   Letting the browser own the text removes that whole class of problem. */
#term-input {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: #d8ffdc;
  caret-color: #9fe6a6;
  font: inherit;
  line-height: inherit;
}

#term-input::selection { background: #1d4a2c; }

#term-input:disabled {
  opacity: 0;
}
#term-skip {
  position: fixed; right: 14px; bottom: 12px;
  color: #46704e; font-size: 11px; letter-spacing: 2px;
  cursor: pointer; padding: 6px 10px; border: 1px solid #1d3322;
}
#term-skip:hover { color: #9fe6a6; }
/* nginx's own 502 page: browser defaults, nothing added */
#gate502 {
  position: fixed; inset: 0; z-index: 70; display: none;
  background: #ffffff; color: #000;
  font-family: "Times New Roman", Times, serif;
  font-size: 16px; padding: 8px; overflow: auto;
}
#gate502.show { display: block; }
#gate502 h1 { font-size: 2em; font-weight: bold; margin: 0.67em 0; }
#gate502 hr { border: 0; border-top: 1px solid #000; margin: 0.5em 0; }

/* Loading screen */
#loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 30px;
  background: #0a0b1e;
}

#loading-overlay.hidden {
  display: none;
}

.load-title {
  font-family: 'Pixelify Sans', monospace;
  font-size: 20px;
  color: #ecc34a;
  margin-bottom: 20px;
  text-shadow: 2px 2px 0 #1a1428;
}

.load-bar {
  width: min(80vw, 320px);
  height: 16px;
  border: 2px solid #ecc34a;
  border-radius: 10px;
  background: #141634;
  overflow: hidden;
}

.load-fill {
  height: 100%;
  width: 0%;
  background: #ecc34a;
  transition: width .15s ease;
}

.load-pct {
  font-family: 'Pixelify Sans', monospace;
  font-size: 12px;
  color: #b9bde0;
  margin-top: 12px;
}

#load-start {
  margin-top: 22px;
}

@media (max-width: 620px) {
  .parchments {
    flex-direction: column-reverse;   /* photo above, words below */
  }

  .parchment-photo {
    flex: 0 0 auto;
  }

  .parchment-text {
    min-height: 0;
  }

  .gallery img {
    max-height: 32vh;
  }
}

@media (prefers-reduced-motion: reduce) {
  .modal {
    transition: none;
  }

  .load-fill {
    transition: none;
  }
}
