/* Global: hide every scrollbar across the app; scrollable elements still scroll */
*, html, body {
  scrollbar-width: none !important;
  -ms-overflow-style: none !important;
}

/* Global: kill every focus outline. Mouse-click "stuck focus ring" is the main culprit —
   buttons keep :focus after click and the browser draws an outline. Eliminates the dark
   circle that lingers on the recap play button etc. */
*:focus,
*:focus-visible {
  outline: none !important;
  box-shadow: none !important;
}
*::-webkit-scrollbar,
html::-webkit-scrollbar,
body::-webkit-scrollbar {
  display: none !important;
  width: 0 !important;
  height: 0 !important;
  background: transparent !important;
}
*::-webkit-scrollbar-thumb,
*::-webkit-scrollbar-track,
*::-webkit-scrollbar-corner {
  display: none !important;
  background: transparent !important;
}

:root {
  --cream: #ffffff;
  --cream-dim: #f4f4f4;
  --graphite: #1a1a1a;
  --graphite-soft: #6a6a6a;
  --purple: #5b3a93;
  --hairline: #e5e5e5;
  --danger: #9b3a2e;
  --danger-soft: #b86840;
  --serif: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", system-ui, sans-serif;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", system-ui, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: #ffffff;
  color: var(--graphite);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", system-ui, sans-serif;
  font-weight: 400;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  height: 100vh;
  overflow: hidden;
  overscroll-behavior: none;
}

body { display: flex; justify-content: center; }


#app {
  width: 100%;
  max-width: 880px;
  height: 100vh;
  padding: 0 32px;
  display: flex;
  flex-direction: column;
}

.screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  height: 100%;
}

.hidden { display: none !important; }

.centered {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 18px;
  max-width: 460px;
  margin: 0 auto;
  width: 100%;
}

/* Sign in screen — reuses the menu-* logo classes so sizing matches the home page exactly. */
.signin-centered {
  align-items: center;
  gap: 22px;
}
/* Locked-down sign-in button. The global `button { background: var(--graphite) }` rule plus
   browser-default click states would otherwise show a dark flash on press; every non-hover
   state below explicitly forces the resting white background. Border is invisible by default
   and only appears on hover. */
button.signin-google-btn,
button.signin-google-btn:active,
button.signin-google-btn:focus,
button.signin-google-btn:focus-visible,
button.signin-google-btn:active:focus {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: #ffffff;
  color: var(--graphite);
  border: 1px solid transparent;
  padding: 10px 20px;
  border-radius: 999px;
  font-family: "Inter", system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
  align-self: center;
  appearance: none;
  -webkit-appearance: none;
  -webkit-tap-highlight-color: transparent;
  outline: none;
  box-shadow: none;
}
button.signin-google-btn:hover:not(:disabled),
button.signin-google-btn:hover:active:not(:disabled),
button.signin-google-btn:hover:focus:not(:disabled) {
  background: var(--cream-dim);
  border-color: var(--graphite-soft);
}
button.signin-google-btn:disabled {
  opacity: 0.5;
  cursor: default;
  background: #ffffff;
  border-color: transparent;
}
.signin-error {
  margin: 0;
  color: #b03030;
  font-family: "Inter", system-ui, sans-serif;
  font-size: 13px;
  text-align: center;
}

.prose { margin: 0; color: var(--graphite); }
.hint { color: var(--graphite-soft); font-size: 13px; margin: 0; line-height: 1.45; }

input, textarea, select, button {
  font: inherit;
  color: var(--graphite);
  background: transparent;
  border: none;
  outline: none;
}

input[type="text"], input[type="password"], input[type="number"], input:not([type]), textarea, select {
  background: var(--cream-dim);
  border-bottom: 1px solid var(--hairline);
  padding: 10px 12px;
  border-radius: 4px 4px 0 0;
  width: 100%;
  display: block;
  color: var(--graphite);
}
input:focus, textarea:focus, select:focus {
  border-bottom-color: var(--graphite);
}

label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: var(--graphite-soft);
  font-size: 13px;
  letter-spacing: 0.02em;
  margin-bottom: 12px;
}

button {
  background: var(--graphite);
  color: var(--cream);
  padding: 9px 18px;
  border-radius: 4px;
  cursor: pointer;
  align-self: flex-start;
  font-size: 15px;
}
button:hover { background: #1a1917; }
button:disabled { opacity: 0.5; cursor: default; }
button.ghost { background: transparent; color: var(--graphite-soft); }
button.ghost:hover { background: var(--cream-dim); color: var(--graphite); }
button.danger { color: var(--danger); background: transparent; }
button.danger:hover { background: var(--cream-dim); }
button.danger-soft { color: var(--danger-soft); background: transparent; }
button.danger-soft:hover { background: var(--cream-dim); }
button.small { font-size: 13px; padding: 6px 12px; }

.row { display: flex; gap: 8px; align-items: center; }
#wish-form .row { margin-top: 14px; justify-content: center; }

/* WISH screen — Lora bold heading + a textarea styled like the profile form boxes. */
.wish-heading {
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-weight: 600;
  color: var(--graphite);
  text-align: center;
  font-size: 16px;
  margin: 0 0 8px;
}

/* Seeding status line — Lora regular, body-style, matches the in-game narrative font. */
.seeding-status {
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-weight: 400;
  color: var(--graphite);
  font-size: 15px;
  line-height: 1.55;
  text-align: center;
  margin: 0;
}
#wish-form textarea {
  background: #ffffff;
  color: var(--graphite);
  border: 1px solid transparent;
  padding: 16px 18px;
  border-radius: 6px;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  line-height: 1.4;
  width: 100%;
  box-sizing: border-box;
  resize: none;
  transition: background 0.12s, border-color 0.12s;
}
#wish-form textarea::placeholder { color: var(--graphite-soft); opacity: 0.7; }
#wish-form textarea:hover { background: var(--cream-dim); border-color: var(--graphite-soft); }
#wish-form textarea:focus { outline: none; background: #ffffff; border-color: var(--graphite-soft); }

#wish-skip:hover { background: transparent; }

/* Menu doors */
/* Menu page — scrollable, tabbed */
#screen-menu {
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--hairline) transparent;
}

/* Full-viewport menu background image — applied to body only when the menu screen is active.
   Body itself stays white during gameplay / life / scene / recap screens. */
body.on-menu {
  background: #ffffff url("menu.png") center center / cover no-repeat fixed;
}
/* White orb overlay: bottom half of a ball anchored above the viewport.
   Pulsates the gradient's interior OPACITY at each stop, including the outer edge so the orb can
   inflate from its current "big" rest state to nearly covering the entire viewport in white.
   Stop POSITIONS never move; only the alpha at each stop. */
@property --orb-core {
  syntax: '<color>';
  initial-value: rgba(255,255,255,1);
  inherits: false;
}
@property --orb-mid {
  syntax: '<color>';
  initial-value: rgba(255,255,255,0.85);
  inherits: false;
}
@property --orb-outer {
  syntax: '<color>';
  initial-value: rgba(255,255,255,0.45);
  inherits: false;
}
@property --orb-edge {
  syntax: '<color>';
  initial-value: rgba(255,255,255,0);
  inherits: false;
}
body.on-menu::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(
    circle at 50% -30vh,
    var(--orb-core)  0%,
    var(--orb-core)  38%,
    var(--orb-mid)   55%,
    var(--orb-outer) 72%,
    var(--orb-edge)  90%
  );
  animation: orb-pulse 10s ease-in-out infinite;
}
@keyframes orb-pulse {
  /* Start/end: big resting state (the previous "peak"). */
  0%, 100% {
    --orb-core:  rgba(255,255,255,1);
    --orb-mid:   rgba(255,255,255,0.85);
    --orb-outer: rgba(255,255,255,0.45);
    --orb-edge:  rgba(255,255,255,0);
  }
  /* Mid-cycle: orb inflates to nearly fill the viewport — page reads mostly white, sky barely shows. */
  50% {
    --orb-core:  rgba(255,255,255,1);
    --orb-mid:   rgba(255,255,255,1);
    --orb-outer: rgba(255,255,255,0.9);
    --orb-edge:  rgba(255,255,255,0.65);
  }
}
/* Lift menu content above the orb overlay so it stays clickable and readable. */
body.on-menu #app {
  position: relative;
  z-index: 1;
}
#screen-menu::-webkit-scrollbar { width: 4px; }
#screen-menu::-webkit-scrollbar-thumb { background: var(--hairline); border-radius: 2px; }

.menu-page {
  max-width: 820px;
  width: 100%;
  margin: 0 auto;
  padding: 56px 0 60px;
  display: flex;
  flex-direction: column;
  gap: 22px;
  min-height: 100vh;
  box-sizing: border-box;
}
.menu-title {
  font-size: 34px;
  font-weight: 600;
  text-align: center;
  margin: 0 0 6px;
  letter-spacing: -0.01em;
  color: var(--graphite);
  display: flex;
  justify-content: center;
  align-items: center;
  line-height: 0;
}
.menu-title-logo {
  display: block;
  width: 240px;
  max-width: 60vw;
  height: auto;
  user-select: none;
  -webkit-user-drag: none;
}
.menu-freeframe-link {
  display: block;
  text-align: center;
  line-height: 0;
  margin: 0 0 -6px;
}
.menu-freeframe-logo {
  display: inline-block;
  width: 80px;
  max-width: 20vw;
  height: auto;
  margin: 0;
  user-select: none;
  -webkit-user-drag: none;
}
.menu-tabs {
  display: flex;
  justify-content: center;
  gap: 28px;
  margin-bottom: 14px;
  padding-bottom: 12px;
}
.menu-tab {
  background: transparent;
  color: var(--graphite-soft);
  padding: 4px 2px;
  font-size: 15px;
  font-weight: 600;
  border-radius: 0;
  letter-spacing: 0;
  align-self: auto;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  transform: translateY(0);
  transition: transform 0.18s ease;
}
.menu-tab:hover:not(.locked):not(:disabled) { background: transparent; transform: translateY(-4px); }
.menu-tab.active { font-weight: 600; transform: translateY(-4px); }
/* Locked tabs (shown when profile isn't complete) — uniform grey, no hover lift, unclickable.
   `!important` overrides the inline `style="color: ..."` set in index.html on each tab. */
.menu-tab.locked,
.menu-tab:disabled {
  color: #b5b5b5 !important;
  cursor: default;
  pointer-events: none;
}
.menu-tab.locked .name-glyph,
.menu-tab:disabled .name-glyph {
  color: #b5b5b5 !important;
}

.menu-pane {
  display: none;
  flex-direction: column;
  gap: 18px;
}
.menu-pane.active { display: flex; }
/* Play pane: cards + try-again button vertically centered in the available space below the title/tabs,
   then biased UP slightly via bottom padding so the cards sit above the geometric center of the viewport. */
.menu-pane.active[data-pane="play"] {
  flex: 1;
  justify-content: center;
  padding-bottom: 14vh;
}

.profile-stats-line {
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-weight: 700;
  color: var(--graphite);
  text-align: center;
  font-size: 16px;
  margin: 0 0 12px;
  display: flex;
  justify-content: center;
  gap: 28px;
  flex-wrap: wrap;
}


.profile-soul-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 520px;
  align-self: center;
  width: 100%;
}
/* Form inputs styled to match the life-option cards: white box, Lora, soft rounded corners,
   subtle border on hover/focus. Applied to BOTH the profile soul form AND the onboarding soul form. */
.profile-soul-form input,
.profile-soul-form select,
.profile-soul-form textarea,
#soul-form input,
#soul-form select,
#soul-form textarea,
#token-inline-input {
  background: #ffffff;
  color: var(--graphite);
  border: 1px solid transparent;
  padding: 16px 18px;
  border-radius: 6px;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  line-height: 1.4;
  width: 100%;
  box-sizing: border-box;
  transition: background 0.12s, border-color 0.12s;
}
.profile-soul-form input::placeholder,
.profile-soul-form textarea::placeholder,
#soul-form input::placeholder,
#soul-form textarea::placeholder,
#token-inline-input::placeholder {
  color: var(--graphite-soft);
  opacity: 0.7;
}
.profile-soul-form select,
#soul-form select { appearance: none; -webkit-appearance: none; cursor: pointer; }
.profile-soul-form input:hover,
.profile-soul-form select:hover,
.profile-soul-form textarea:hover,
#soul-form input:hover,
#soul-form select:hover,
#soul-form textarea:hover,
#token-inline-input:hover {
  background: var(--cream-dim);
  border-color: var(--graphite-soft);
}
.profile-soul-form input:focus,
.profile-soul-form select:focus,
.profile-soul-form textarea:focus,
#soul-form input:focus,
#soul-form select:focus,
#soul-form textarea:focus,
#token-inline-input:focus {
  outline: none;
  background: #ffffff;
  border-color: var(--graphite-soft);
}
.profile-soul-form textarea,
#soul-form textarea { resize: none; }
/* When a select has no value chosen, the first option text serves as the placeholder — render
   it in the same dimmed style as the input/textarea placeholders. */
.profile-soul-form select:has(option[value=""]:checked),
#soul-form select:has(option[value=""]:checked) { color: var(--graphite-soft); opacity: 0.7; }

.profile-actions-row {
  display: flex;
  justify-content: center;
  gap: 18px;
  flex-wrap: wrap;
  margin-top: 24px;
  margin-bottom: 48px;
}
/* Match the "More options" button style — only the text color shifts on hover, no background box. */
.profile-actions-row button.ghost:hover { background: transparent; }

.play-heading {
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  color: var(--graphite);
  text-align: center;
  font-size: 26px;
  font-weight: 600;
  margin: 0;
}
.menu-cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 8px auto 4px;
  max-width: 520px;
  width: 100%;
}
.menu-card {
  background: #ffffff;
  color: var(--graphite);
  border: 1px solid transparent;
  padding: 16px 18px;
  border-radius: 6px;
  text-align: left;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  line-height: 1.4;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, transform 0.08s;
  align-self: stretch;
  width: 100%;
}
.menu-card:hover { background: var(--cream-dim); border-color: var(--graphite-soft); }
.menu-card:active { transform: translateY(1px); }
.cards-loading {
  color: var(--graphite-soft);
  font-style: italic;
  text-align: center;
  padding: 18px;
  font-size: 14px;
}
#cards-refresh { align-self: center; margin-top: 4px; }
#cards-refresh:hover { background: transparent; }

.menu-card-suggest {
  align-self: stretch;
  text-align: center;
  color: var(--graphite-soft);
  background: transparent;
  border: 1px dashed var(--hairline);
  margin-top: 4px;
}
.menu-card-suggest:hover { color: var(--graphite); background: var(--cream-dim); border-color: var(--graphite-soft); }

.suggest-life-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--cream-dim);
  padding: 14px;
  border-radius: 6px;
  margin-top: 8px;
}
.suggest-life-form textarea {
  width: 100%;
  background: var(--cream);
  padding: 10px 12px;
  border-radius: 4px;
  resize: none;
  font: inherit;
  color: var(--graphite);
  border: 1px solid var(--hairline);
  min-height: 70px;
}
.suggest-life-form .row { justify-content: flex-end; }
/* Past-lives list — matches the life-option cards exactly: 520px column, white box, Lora,
   cream-dim hover. Adds the same 48px bottom margin as the profile actions row. */
.past-lives {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 8px auto 48px;
  max-width: 520px;
  width: 100%;
}
.past-life {
  background: #ffffff;
  color: var(--graphite);
  border: 1px solid transparent;
  padding: 16px 18px;
  border-radius: 6px;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  line-height: 1.4;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, transform 0.08s;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  text-align: left;
}
.past-life:hover { background: var(--cream-dim); border-color: var(--graphite-soft); }
.past-life:active { transform: translateY(1px); }
.past-life:focus-visible { outline: 2px solid var(--graphite-soft); outline-offset: 2px; }
.past-life-label {
  flex: 1;
  min-width: 0;
}

/* Play icon — large play-in-circle, inside the past-life card, no box around it.
   Inverted hover: darker by default, softens on hover. */
.past-life-play {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  color: var(--graphite);
  cursor: pointer;
  transition: color 0.12s, transform 0.08s;
}
.past-life-play:hover { color: var(--graphite-soft); }
.past-life-play:active { transform: translateY(1px); }
.past-life-play:focus-visible { outline: 2px solid var(--graphite-soft); outline-offset: 2px; border-radius: 50%; }
.past-life-play svg { width: 24px; height: 24px; display: block; }


/* Game transcript */
.transcript {
  flex: 1;
  padding: 56px 0 32px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
  min-height: 0;
  scrollbar-width: none;
  max-width: 600px;
  margin: 0 auto;
  width: 100%;
}
.transcript::-webkit-scrollbar { display: none; }

.line {
  white-space: pre-wrap;
  word-wrap: break-word;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  line-height: 1.6;
}
/* Keep the Yarndings glyph in its own font even inside story lines. */
.line .name-glyph { font-family: "Yarndings 12", monospace; }
/* Recap text is also story-grade. */
#recap-text { font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif; font-size: 15px; line-height: 1.65; }
.line.narration { color: var(--graphite); }
.line.dialogue { color: var(--graphite); }
.line.dialogue .name { font-weight: 600; margin-right: 0.15em; }
.name-glyph {
  font-family: "Yarndings 12", monospace;
  font-weight: 400;
  margin-right: 0.18em;
  display: inline-block;
  font-size: 1.05em;
  vertical-align: baseline;
  /* Uncopyable — keep glyphs out of selection / clipboard / drag */
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-drag: none;
}
.contact-name .name-glyph { font-size: 1em; }
.line.player {
  color: var(--graphite-soft);
  padding-left: 16px;
  border-left: 2px solid var(--hairline);
  position: relative;
}
.line.player.from-suggestion {
  border-left-color: var(--purple);
  opacity: 0.92;
}
.line.player .edit-btn {
  position: absolute;
  top: 0;
  right: 0;
  background: transparent;
  color: var(--graphite-soft);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", system-ui, sans-serif;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 3px;
  opacity: 0;
  transition: opacity 0.12s;
  letter-spacing: 0.04em;
}
.line.player:hover .edit-btn { opacity: 0.7; }
.line.player .edit-btn:hover { opacity: 1; background: transparent; color: var(--graphite); }
.transcript.archived .edit-btn { display: none !important; }

/* Reply affordance — shown on hover over narration / dialogue lines */
.line.narration, .line.dialogue {
  position: relative;
}
.line.narration .reply-btn, .line.dialogue .reply-btn {
  position: absolute;
  top: 0;
  right: 0;
  background: transparent;
  color: var(--graphite-soft);
  font-size: 13px;
  padding: 2px 8px;
  border-radius: 3px;
  opacity: 0;
  transition: opacity 0.12s;
  letter-spacing: 0.04em;
}
.line.narration:hover .reply-btn, .line.dialogue:hover .reply-btn {
  opacity: 0.7;
}
.line.narration .reply-btn:hover, .line.dialogue .reply-btn:hover {
  opacity: 1;
  background: var(--cream-dim);
  color: var(--graphite);
}
.transcript.archived .reply-btn { display: none !important; }

/* Reply chip in composer */
.reply-chip {
  background: var(--cream-dim);
  border-left: 2px solid var(--purple);
  padding: 6px 10px 6px 12px;
  border-radius: 3px;
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 12px;
  color: var(--graphite-soft);
  margin-bottom: 6px;
}
.reply-chip-arrow { color: var(--purple); font-size: 13px; }
.reply-chip-label { font-style: italic; }
.reply-chip-text {
  color: var(--graphite);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.reply-chip-clear {
  background: transparent;
  color: var(--graphite-soft);
  font-size: 14px;
  padding: 0 4px;
  line-height: 1;
  border-radius: 3px;
}
.reply-chip-clear:hover { color: var(--graphite); background: var(--cream); }

/* Reply chip inside player message in transcript */
.line.player .reply-context {
  display: flex;
  gap: 6px;
  align-items: baseline;
  font-size: 12px;
  color: var(--graphite-soft);
  margin-bottom: 4px;
  font-style: italic;
}
.line.player .reply-context-arrow { color: var(--purple); font-style: normal; }
.line.player .reply-context-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.line.player.editing {
  padding: 8px 12px 8px 16px;
  background: var(--cream-dim);
  border-radius: 0 4px 4px 0;
}
.edit-textarea {
  width: 100%;
  background: var(--cream);
  padding: 8px 10px;
  border-radius: 3px;
  resize: none;
  font: inherit;
  color: var(--graphite);
  min-height: 36px;
  border: 1px solid var(--hairline);
  display: block;
}
.edit-actions {
  display: flex;
  gap: 6px;
  margin-top: 6px;
}
.edit-actions button {
  font-family: "Inter", system-ui, sans-serif;
  font-size: 12px;
  padding: 4px 10px;
}

.line.reflection {
  margin-top: 28px;
  padding-top: 22px;
  border-top: 1px solid var(--hairline);
  color: var(--graphite);
}
/* When the reflection is the only thing in the transcript (e.g. the recap-position past view),
   suppress the top divider — there's nothing above it for it to separate from. */
.transcript .line.reflection:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.line.system {
  color: var(--graphite-soft);
  font-size: 13px;
  font-style: italic;
}
.line.end-of-life {
  margin-top: 36px;
  text-align: center;
}
.end-of-life-controls {
  display: flex;
  justify-content: center;
  padding: 18px 0 32px;
}
.end-of-life-controls button {
  padding: 12px 28px;
}

.inline-retry {
  background: var(--cream-dim);
  color: var(--graphite);
  font-size: 12px;
  padding: 2px 10px;
  margin-left: 6px;
  border-radius: 3px;
  font-style: normal;
}
.inline-retry:hover { background: var(--graphite); color: var(--cream); }

/* Composer */
.composer, .scene-end-controls, .request-prompt {
  flex-shrink: 0;
  background: #ffffff;
  padding: 14px 0 22px;
  border-top: 1px solid var(--hairline);
  display: flex;
  gap: 8px;
  max-width: 600px;
  width: 100%;
  margin: 0 auto;
}
.composer {
  flex-direction: column;
  align-items: stretch;
}
.composer textarea {
  background: #ffffff;
  color: var(--graphite);
  border: 1px solid transparent;
  padding: 16px 18px;
  border-radius: 6px;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  line-height: 1.4;
  min-height: 52px;
  max-height: 200px;
  resize: none;
  width: 100%;
  box-sizing: border-box;
  transition: background 0.12s, border-color 0.12s;
}
.composer textarea::placeholder { color: var(--graphite-soft); opacity: 0.7; }
.composer textarea:hover { background: var(--cream-dim); border-color: var(--graphite-soft); }
.composer textarea:focus { outline: none; background: #ffffff; border-color: var(--graphite-soft); }
.composer-buttons {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  align-items: center;
}
.composer-buttons button {
  font-size: 13px;
  padding: 6px 14px;
}
/* Immerse sits on the LEFT, separated from the suggest/continue/send cluster on the right. */
.composer-immerse { margin-right: auto; }
/* Suggest + Continue + Copy transcript — ghost buttons in the composer / scene-end area.
   Only the text color shifts on hover, no box. */
#suggest:hover, #continue-narrative:hover, #copy-transcript:hover { background: transparent; color: var(--graphite); }

/* Scene end controls */
.scene-end-controls {
  flex-direction: column;
  align-items: stretch;
}
.scene-end-controls textarea {
  background: var(--cream-dim);
  padding: 10px 12px;
  border-radius: 4px;
  min-height: 40px;
  max-height: 160px;
  resize: none;
  font: inherit;
  color: var(--graphite);
  width: 100%;
}
.scene-end-buttons { display: flex; gap: 8px; }
.scene-qa-row {
  display: flex;
  gap: 6px;
  align-items: flex-end;
}
.scene-qa-row textarea {
  flex: 1;
  background: #ffffff;
  color: var(--graphite);
  border: 1px solid transparent;
  padding: 16px 18px;
  border-radius: 6px;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  line-height: 1.4;
  min-height: 52px;
  max-height: 160px;
  resize: none;
  box-sizing: border-box;
  transition: background 0.12s, border-color 0.12s;
}
.scene-qa-row textarea::placeholder { color: var(--graphite-soft); opacity: 0.7; }
.scene-qa-row textarea:hover { background: var(--cream-dim); border-color: var(--graphite-soft); }
.scene-qa-row textarea:focus { outline: none; background: #ffffff; border-color: var(--graphite-soft); }
.scene-qa-row button { flex-shrink: 0; }

/* Archivist Q&A: render as plain chat — question matches a player message, answer matches body. */
.line.archivist-q {
  color: var(--graphite-soft);
  padding-left: 16px;
  border-left: 2px solid var(--hairline);
}
.line.archivist-a {
  color: var(--graphite);
}

/* Request prompt */
.request-prompt {
  flex-direction: column;
  align-items: stretch;
}
.request-prompt textarea {
  background: #ffffff;
  color: var(--graphite);
  border: 1px solid transparent;
  padding: 16px 18px;
  border-radius: 6px;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  line-height: 1.4;
  min-height: 60px;
  max-height: 200px;
  resize: none;
  width: 100%;
  box-sizing: border-box;
  transition: background 0.12s, border-color 0.12s;
}
.request-prompt textarea::placeholder { color: var(--graphite-soft); opacity: 0.7; }
.request-prompt textarea:hover { background: var(--cream-dim); border-color: var(--graphite-soft); }
.request-prompt textarea:focus { outline: none; background: #ffffff; border-color: var(--graphite-soft); }
.request-buttons { display: flex; gap: 8px; }

#retcon-prompt select {
  background: #ffffff;
  color: var(--graphite);
  border: 1px solid transparent;
  padding: 16px 18px;
  border-radius: 6px;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  line-height: 1.4;
  width: 100%;
  box-sizing: border-box;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
#retcon-prompt select:hover { background: var(--cream-dim); border-color: var(--graphite-soft); }
#retcon-prompt select:focus { outline: none; background: #ffffff; border-color: var(--graphite-soft); }

/* Scene navigation arrows — top center */
.scene-nav {
  position: fixed;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 5;
}
.nav-arrow {
  background: transparent;
  color: var(--graphite-soft);
  padding: 4px 10px;
  font-size: 16px;
  border-radius: 3px;
  align-self: center;
}
.nav-arrow:hover:not(:disabled) { background: transparent; color: var(--graphite); }
.nav-arrow:disabled { opacity: 0.25; cursor: default; background: transparent; }
.nav-arrow:disabled:hover { background: transparent; color: inherit; cursor: default; }
.nav-label {
  color: var(--graphite-soft);
  font-size: 12px;
  letter-spacing: 0.04em;
  min-width: 110px;
  text-align: center;
}

/* Top-right menu */
.menu {
  position: fixed;
  top: 12px;
  right: 14px;
  font-size: 13px;
}
/* Save and exit — same position + visual treatment the Settings dropdown used to have. */
.save-exit-btn {
  position: fixed;
  top: 12px;
  right: 14px;
  z-index: 5;
  background: transparent;
  color: var(--graphite-soft);
  padding: 6px 10px;
  font-size: 13px;
  letter-spacing: 0.04em;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.save-exit-btn:hover { background: transparent; color: var(--graphite); }
.save-exit-btn:active,
.save-exit-btn:focus,
.save-exit-btn:focus-visible { background: transparent !important; outline: none !important; box-shadow: none !important; }
.save-exit-btn:disabled,
.save-exit-btn:disabled:hover {
  opacity: 0.35;
  cursor: default;
  color: var(--graphite-soft);
  background: transparent;
}
body.immerse-active .save-exit-btn,
body.replay-active .save-exit-btn,
body.world-recap-active .save-exit-btn { display: none; }
/* Mute toggle — visually paired with .nav-arrow: transparent, no hover box, just a color shift. */
.mute-toggle {
  position: fixed;
  top: 15px;
  left: 318px;
  z-index: 5;
  background: transparent;
  border: 0;
  padding: 4px 10px;
  color: var(--graphite-soft);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  line-height: 0;
  border-radius: 3px;
}
.mute-toggle:hover { background: transparent; color: var(--graphite); }

/* During archive, hover animations on locked controls are visually misleading — flatten them. */
body.is-archiving #copy-transcript,
body.is-archiving #copy-transcript:hover {
  color: var(--graphite-soft);
  background: transparent;
  cursor: default;
}
body.is-archiving .nav-arrow,
body.is-archiving .nav-arrow:hover,
body.is-archiving .nav-arrow:hover:not(:disabled) {
  color: var(--graphite-soft);
  background: transparent;
  cursor: default;
}
.mute-toggle .mute-icon { display: inline-block; }
.mute-toggle .mute-icon-off { display: none; }
.mute-toggle.is-muted .mute-icon-on { display: none; }
.mute-toggle.is-muted .mute-icon-off { display: inline-block; }
body.immerse-active .mute-toggle,
body.replay-active .mute-toggle { display: none; }
.menu summary {
  cursor: pointer;
  list-style: none;
  color: var(--graphite-soft);
  padding: 6px 10px;
  font-size: 13px;
  letter-spacing: 0.04em;
  user-select: none;
  background: transparent;
  -webkit-tap-highlight-color: transparent;
  outline: none;
}
.menu summary:hover { color: var(--graphite); }
.menu summary:active,
.menu summary:focus,
.menu summary:focus-visible { background: transparent !important; outline: none !important; box-shadow: none !important; }
.menu summary::-webkit-details-marker { display: none; }
.menu-inner {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 6px;
  background: var(--cream-dim);
  border-radius: 6px;
  padding: 6px;
  min-width: 180px;
}
/* Only the fixed-position in-game settings menu absolutely-anchors its dropdown. */
.menu .menu-inner {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 2px;
  z-index: 10;
}
.menu button {
  display: block;
  background: transparent;
  color: var(--graphite);
  padding: 6px 10px;
  text-align: left;
  width: 100%;
  border-radius: 4px;
  font-size: 13px;
}
.menu button:hover { background: var(--cream); }
.menu-tray { margin-top: 18px; align-self: center; }

/* Settings menu locked during archive — visually dimmed, unclickable. */
.menu.locked-during-archive {
  pointer-events: none;
  opacity: 0.35;
}
.menu.locked-during-archive summary { cursor: default; }

/* Scene nav arrows disabled style (already-disabled buttons get a little extra dimming). */
.scene-nav button:disabled {
  cursor: default;
  opacity: 0.4;
}

/* Primer screen */
.primer-centered { max-width: 540px; }
.primer-text {
  white-space: pre-wrap;
  line-height: 1.65;
  color: var(--graphite);
  font-size: 16px;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  margin-bottom: 22px;
}
.primer-actions {
  justify-content: center;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}
/* Begin button matches the wish-form Enter button exactly — global button defaults, no extra
   line-height that would push it taller. */
.primer-actions button {
  align-self: center;
}
.primer-actions button.ghost { color: var(--graphite-soft); }
.primer-actions button.ghost:hover { background: transparent; color: var(--graphite); }
.primer-tweak-status {
  color: var(--graphite-soft);
  font-size: 12px;
  font-style: italic;
  text-align: center;
  margin-top: 8px;
}

/* Left-side trays wrapper — fixed flex column so trays push each other naturally */
/* People rail — persistent left column, no box, full height */
.people-rail {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 300px;
  padding: 0 22px;
  display: flex;
  flex-direction: column;
  z-index: 4;
  pointer-events: none;
}
.people-rail .contacts-list { pointer-events: auto; }

.contacts-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--hairline) transparent;
  background: transparent;
  padding: 18px 0 12px;
  border-radius: 0;
  max-height: none;
}
.contacts-list::-webkit-scrollbar { width: 4px; }
.contacts-list::-webkit-scrollbar-thumb { background: var(--hairline); border-radius: 2px; }
.contacts-list::-webkit-scrollbar-track { background: transparent; }

.contact {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 4px 6px;
  margin: 0 -6px;
  border-radius: 4px;
}
.contact-name {
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-weight: 600;
  font-size: 14px;
}
.contact-desc { color: var(--graphite-soft); font-size: 12px; }
.contacts-empty { color: var(--graphite-soft); font-size: 12px; font-style: italic; }

/* Commitments styling removed — TIMEKEEPER owns calendar + open loops. */

/* Soul dossier modal */
.soul-modal-card {
  max-width: 560px;
  max-height: 80vh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--hairline) transparent;
}
.soul-modal-card::-webkit-scrollbar { width: 4px; }
.soul-modal-card::-webkit-scrollbar-thumb { background: var(--hairline); border-radius: 2px; }
.soul-shape {
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-weight: 400;
  color: var(--graphite);
  font-size: 15px;
  line-height: 1.5;
  max-width: 520px;
  width: 100%;
  align-self: center;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.soul-shape-line { margin: 0; }
.soul-episodic {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 280px;
  overflow-y: auto;
  scrollbar-width: thin;
}
.soul-episode {
  color: var(--graphite);
  font-size: 13px;
  line-height: 1.45;
  padding-left: 12px;
  border-left: 2px solid var(--hairline);
}
.soul-episode-life {
  color: var(--graphite-soft);
  font-size: 11px;
  font-style: italic;
  letter-spacing: 0.04em;
}


/* Streaming cursor */
.cursor::after {
  content: "▍";
  color: var(--graphite-soft);
  margin-left: 2px;
  animation: blink 1.1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* Recap screen */
.recap {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 60px 0 32px;
  overflow-y: auto;
  scrollbar-width: none;
}
.recap::-webkit-scrollbar { display: none; }
#recap-text {
  white-space: pre-wrap;
  color: var(--graphite);
  line-height: 1.65;
}
.recap-qa {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#recap-qa-history {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.recap-q {
  color: var(--graphite-soft);
  padding-left: 14px;
  border-left: 2px solid var(--hairline);
}
.recap-a {
  color: var(--graphite);
  white-space: pre-wrap;
}
#recap-qa-input-wrap textarea {
  background: var(--cream-dim);
  padding: 10px 12px;
  border-radius: 4px;
  min-height: 52px;
  max-height: 160px;
  resize: none;
  font: inherit;
  color: var(--graphite);
  width: 100%;
}
#recap-qa-input-wrap .row { margin-top: 8px; }
.recap-end {
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}
.recap-status {
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  color: var(--graphite-soft);
  font-style: italic;
  padding: 40px 0;
  text-align: center;
}
.recap-video {
  width: 100%;
  max-width: 960px;
  display: block;
  margin: 0 auto;
  border-radius: 12px;
  background: #000;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.18);
}

/* Inline access-token entry on the Play tab — shown when no unconsumed token exists. */
.token-inline {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 24px 24px 40px;
  max-width: 440px;
  margin: 0 auto;
  width: 100%;
}
.token-inline-title {
  margin: 0;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 16px;
  color: var(--graphite);
  text-align: center;
}
#token-inline-submit,
#token-inline-submit:hover {
  align-self: center;
  background: transparent;
  color: var(--graphite-soft);
}
#token-inline-submit:hover { color: var(--graphite); }

/* Access token modal — shown when an unredeemed user tries to start a life. */
.token-modal {
  position: fixed;
  inset: 0;
  z-index: 9300;
  display: flex;
  align-items: center;
  justify-content: center;
}
.token-modal.hidden { display: none; }
.token-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.token-modal-card {
  position: relative;
  width: min(420px, calc(100% - 40px));
  background: #ffffff;
  border-radius: 12px;
  padding: 32px 28px 24px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.18);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.token-modal-title {
  margin: 0;
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 16px;
  color: var(--graphite);
  text-align: center;
}
.token-modal-hint {
  margin: 0;
  font-family: "Inter", system-ui, sans-serif;
  font-size: 12px;
  color: var(--graphite-soft);
  text-align: center;
}
#token-input {
  font-family: "Inter", system-ui, sans-serif;
  font-size: 15px;
  padding: 10px 14px;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  background: var(--cream-dim);
  color: var(--graphite);
  letter-spacing: 0.02em;
  outline: none !important;
}
#token-input:focus { background: #ffffff; border-color: var(--graphite-soft); }
#token-input::placeholder { color: var(--graphite-soft); opacity: 0.55; }
.token-error {
  margin: 0;
  color: #b03030;
  font-family: "Inter", system-ui, sans-serif;
  font-size: 12px;
  text-align: center;
}
.token-modal-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-top: 4px;
}
.token-modal-actions button { font-size: 13px; padding: 8px 16px; }

/* Click-outside backdrop for past-life replay (transparent — the 18px window margins are clickable). */
.world-recap-backdrop {
  position: fixed;
  inset: 0;
  z-index: 9099;
  background: transparent;
  cursor: default;
}

/* World Recap overlay — near-fullscreen window, expands from "Watch your World" button. */
.world-recap-overlay {
  position: fixed;
  background: #000;
  z-index: 9100;
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.18);
  will-change: transform, opacity;
  opacity: 0;
}
.world-recap-overlay.hidden { display: none; opacity: 0; }

/* Loader inside the overlay — same sky background + Lora semibold black text as immerse loading,
   but with a single status line (no hint subline). */
.world-recap-status {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  color: var(--graphite);
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  font-style: normal;
  font-weight: 400;
  line-height: 1.55;
  background: #ffffff url("menu.png") center center / cover no-repeat;
  pointer-events: none;
  overflow: hidden;
}
.world-recap-status::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(
    circle at 50% -30%,
    var(--orb-core)  0%,
    var(--orb-core)  38%,
    var(--orb-mid)   55%,
    var(--orb-outer) 72%,
    var(--orb-edge)  90%
  );
  animation: orb-pulse 10s ease-in-out infinite;
}
.world-recap-status > * { position: relative; z-index: 1; }

.world-recap-video {
  width: 100%;
  height: 100%;
  display: block;
  background: #000;
  /* Zoom-to-fit the 16:9 canvas into the overlay's near-fullscreen aspect — no black bars in
     the browser preview. The downloaded file is still pristine 16:9. */
  object-fit: cover;
}

.world-recap-download {
  position: absolute;
  bottom: 18px;
  right: 18px;
  z-index: 5;
  color: #ffffff;
  background: rgba(0, 0, 0, 0.42);
  padding: 6px 14px;
  border-radius: 999px;
  font-family: "Inter", system-ui, sans-serif;
  font-size: 12px;
  text-decoration: none;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.world-recap-download:hover { background: rgba(0, 0, 0, 0.62); }

/* Return home — bottom-center floating action on the recap overlay. Visually identical to Download. */
.world-recap-return-home {
  position: absolute;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  color: #ffffff;
  background: rgba(0, 0, 0, 0.42);
  border: 0;
  padding: 6px 14px;
  border-radius: 999px;
  font-family: "Inter", system-ui, sans-serif;
  font-size: 12px;
  cursor: pointer;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.world-recap-return-home:hover { background: rgba(0, 0, 0, 0.62); }

/* Center play-button overlay — only chrome we show on the recap video. */
.world-recap-play-overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 4;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  border: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background 0.15s ease, opacity 0.18s ease;
  pointer-events: auto;
}
.world-recap-play-overlay:hover { background: rgba(0, 0, 0, 0.75); }
.world-recap-play-overlay.hidden { display: none; }
.world-recap-play-overlay svg { width: 32px; height: 32px; fill: #ffffff; margin-left: 4px; }

/* While the recap overlay is up, hide everything behind it including the people-rail. */
body.world-recap-active #transcript,
body.world-recap-active .composer,
body.world-recap-active .scene-end-controls,
body.world-recap-active .scene-nav,
body.world-recap-active .menu,
body.world-recap-active .mute-toggle,
body.world-recap-active .people-rail,
body.world-recap-active .end-of-life-controls { visibility: hidden; }
body.world-recap-active { overflow: hidden; }

/* ========== IMMERSE / REACTOR overlay ========== */

#immerse:hover { background: transparent; color: var(--graphite); }
#immerse:disabled { background: transparent; color: var(--graphite-soft); opacity: 0.45; cursor: default; }
#immerse:disabled:hover { background: transparent; color: var(--graphite-soft); }
/* Replay variant: when the player has already immersed in this scene, the Immerse button
   becomes a Replay control with a play-triangle prefix. */
#immerse.is-replay {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
#immerse.is-replay::before {
  content: "▶";
  font-size: 9px;
  line-height: 1;
  color: inherit;
}

.immerse-overlay {
  position: fixed;
  background: #000;
  z-index: 9100;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 8px 28px rgba(0,0,0,0.18);
  will-change: transform, opacity;
  opacity: 0;
}
.immerse-overlay.hidden { display: none; opacity: 0; }

body.immerse-active { overflow: hidden; }
/* While the immersion is running, hide the body-area chrome behind it. The people-rail
   stays visible. There is intentionally no click-outside-to-exit — the player sits through
   the full 15 seconds. */
body.immerse-active #transcript,
body.immerse-active .composer,
body.immerse-active .scene-end-controls,
body.immerse-active #request-prompt,
body.immerse-active #retcon-prompt,
body.immerse-active #wish-prompt,
body.immerse-active .scene-nav,
body.immerse-active .menu {
  visibility: hidden !important;
}

.immerse-stage {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.immerse-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}
.immerse-status {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  color: var(--graphite);
  font-family: "Lora", "Iowan Old Style", "Charter", Georgia, serif;
  font-size: 15px;
  font-style: normal;
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: 0;
  background: #ffffff url("menu.png") center center / cover no-repeat;
  pointer-events: none;
  overflow: hidden;
}
/* Breathing orb on the loading state — same as the menu, scoped to the immerse window. */
.immerse-status::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(
    circle at 50% -30%,
    var(--orb-core)  0%,
    var(--orb-core)  38%,
    var(--orb-mid)   55%,
    var(--orb-outer) 72%,
    var(--orb-edge)  90%
  );
  animation: orb-pulse 10s ease-in-out infinite;
}
.immerse-status > * {
  position: relative;
  z-index: 1;
}
.immerse-status-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}
.immerse-status-hint {
  color: var(--graphite-soft, #8a8780);
  font-family: "Inter", system-ui, sans-serif;
  font-size: 13px;
  font-style: normal;
  line-height: 1.5;
}
.immerse-status.hidden { display: none; }

.immerse-hud {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.immerse-hud.hidden { display: none; }

.immerse-controls {
  position: absolute;
  bottom: 26px; left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: flex-end;
  gap: 24px;
}
.immerse-wasd,
.immerse-arrows {
  display: flex; flex-direction: column; align-items: center;
  gap: 4px;
}
.immerse-wasd .wrow,
.immerse-arrows .arow { display: flex; gap: 4px; }
.immerse-wasd .wkey,
.immerse-arrows .akey {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  background: rgba(0,0,0,0.55);
  color: rgba(255,255,255,0.55);
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: 4px;
  font-family: "Inter", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  transition: background 0.08s ease, color 0.08s ease;
}
.immerse-wasd .wkey.active,
.immerse-arrows .akey.active {
  background: rgba(255,255,255,0.92);
  color: #000;
  border-color: #fff;
}
.immerse-wasd .wkey.wk-disabled,
.immerse-arrows .akey.wk-disabled {
  opacity: 0.25;
  text-decoration: line-through;
}

.immerse-timer {
  position: absolute;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  color: #ffffff;
  font-family: "Inter", system-ui, sans-serif;
  font-size: 32px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.55);
}

/* "Hold down, WASD or arrows" tip — dead-center on the immerse stage. Same typographic
   treatment as the timer counter. Visible from HUD reveal, fades out after 3 seconds. */
.immerse-overlay-tip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  color: #ffffff;
  font-family: "Inter", system-ui, sans-serif;
  font-size: 32px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.55);
  text-align: center;
  pointer-events: none;
  opacity: 1;
  transition: opacity 0.6s ease-out;
}
.immerse-overlay-tip.faded { opacity: 0; }

/* ========== Immerse inline takeover replay ========== */

.immerse-replay-backdrop {
  position: fixed;
  inset: 0;
  z-index: 9099;
  background: transparent;
}
.immerse-replay-takeover {
  position: fixed;
  background: #000;
  border-radius: 18px;
  overflow: hidden;
  z-index: 9100;
  opacity: 0;
  will-change: transform, opacity;
  box-shadow: 0 8px 28px rgba(0,0,0,0.18);
}

/* While a replay is playing, hide the body-area chrome so nothing peeks behind the takeover.
   The people-rail (sidebar) stays visible — that's the whole point of the layout. */
body.replay-active #transcript,
body.replay-active .composer,
body.replay-active .scene-end-controls,
body.replay-active #request-prompt,
body.replay-active #retcon-prompt,
body.replay-active #wish-prompt,
body.replay-active .scene-nav,
body.replay-active .menu {
  visibility: hidden !important;
}
.immerse-replay-takeover-video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}
.immerse-replay-takeover-label {
  position: absolute;
  left: 0; right: 0; bottom: 14px;
  color: rgba(255,255,255,0.85);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", system-ui, sans-serif;
  font-style: normal;
  font-weight: 400;
  text-align: center;
  letter-spacing: 0;
  font-size: 13px;
  pointer-events: none;
}

/* ========== Inline transcript line: "You immersed.  Replay" ========== */

.immerse-replay-wrap {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", system-ui, sans-serif;
  font-style: normal;
  font-weight: 400;
  color: var(--graphite-soft);
  font-size: 13px;
  letter-spacing: 0;
  margin: 8px 0;
}
.immerse-replay-affordance {
  background: transparent;
  border: none;
  color: var(--graphite-soft);
  font-family: inherit;
  font-size: 13px;
  letter-spacing: 0;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.immerse-replay-affordance::before {
  content: "▶";
  font-size: 9px;
  line-height: 1;
  color: inherit;
}
.immerse-replay-affordance:hover { color: var(--graphite); background: transparent; }
.past-scene-replay-wrap {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  gap: 18px;
  margin: 16px 0;
}
/* Copy transcript button piggybacks on .immerse-replay-affordance for color/font/hover but
   suppresses the ▶ triangle prefix the replay variant uses. */
.past-scene-copy-btn::before { content: none; }

/* ========== MOBILE ==========
   Phone-sized screens: shift all content up (reduce top padding on every major container),
   and hide Immerse / Replay entirely — Reactor WebRTC doesn't work reliably on mobile and
   the player has no easy way to use the keyboard controls anyway. */
@media (max-width: 640px) {
  /* Shift content up modestly + give generous bottom padding so the last item isn't kissing
     the viewport edge / hidden behind mobile browser chrome.
     min-height: auto is critical — without it, min-height: 100vh holds the box at viewport size
     and our padding-bottom gets absorbed into it instead of extending the scrollable area. */
  .centered { justify-content: flex-start; padding-top: 44px; padding-bottom: 120px; min-height: auto; }
  .menu-page { padding-top: 44px; padding-bottom: 120px; min-height: auto; }
  .menu-title-logo { height: auto; }
  .recap { padding-top: 44px; padding-bottom: 120px; min-height: auto; }
  .transcript.archived { padding-bottom: 120px; }
  .primer-centered { padding-top: 44px; padding-bottom: 120px; min-height: auto; }
  /* Sign-in screen has minimal content — keep it vertically centered like desktop, but offset
     up ~80px because iOS Safari's 100vh measures past the visible toolbar areas, so true center
     reads slightly low. Extra padding-bottom pulls the centered block higher in the actual space. */
  .signin-centered { justify-content: center; padding-top: 24px; padding-bottom: 144px; min-height: 100vh; }

  /* Immerse / Replay entry point — gone on mobile. */
  #immerse,
  .composer-immerse { display: none !important; }

  /* Tighter menu tabs (Play / Past lives / Profile / Soul) and stats line on mobile.
     Stats line becomes a 2-col grid so the four chips read as a tidy 2x2: lives+scenes on
     row 1, hours+tokens on row 2. */
  .menu-tabs { gap: 18px; }
  .menu-tab { font-size: 13px; padding: 4px 1px; }
  .profile-stats-line {
    font-size: 13px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 18px;
    row-gap: 6px;
    justify-items: center;
  }
}
