/* Lifeline: the daily map puzzle. A full-bleed Leaflet stage with a dark
   game console docked over it, and a paper story sheet for the reveal.
   Styles are mobile-first: the base rules dress a phone, the media query at
   the bottom loosens things up for wider screens. */

.lifeline-body {
  overflow: hidden;
  --lifeline-display: "Iowan Old Style", Palatino, Georgia, serif;
}

.lifeline-stage { position: fixed; inset: 0; z-index: 0; }

/* ---------- header ---------- */

.lifeline-header {
  position: fixed; top: 0; left: 0; right: 0;
  display: flex; align-items: baseline; gap: 14px;
  padding: 14px 16px;
  background: linear-gradient(to bottom, rgba(15, 23, 36, 0.85), rgba(15, 23, 36, 0));
  pointer-events: none;
  z-index: 1100;
}
.lifeline-wordmark {
  font-family: var(--lifeline-display);
  font-style: italic; font-weight: 700; font-size: 24px;
  color: #fff; text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}
.lifeline-number { font-style: normal; font-weight: 400; font-size: 17px; color: #e8c876; }
.lifeline-date { display: none; font-size: 14px; color: rgba(255, 255, 255, 0.85); text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); }

/* Mid-game escape hatch; the header itself ignores the pointer, so the
   button opts back in. Once solved, the solved face's Play again takes over. */
.lifeline-restart {
  display: none; margin-left: auto; pointer-events: auto;
  font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, 0.85);
  background: rgba(15, 23, 36, 0.55); border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 999px; padding: 6px 12px; cursor: pointer;
}
.lifeline--normal:not(.lifeline--over) .lifeline-restart,
.lifeline--hardcore:not(.lifeline--over) .lifeline-restart { display: inline-block; }
.lifeline-restart:hover { border-color: #e8c876; color: #e8c876; }

/* ---------- console ---------- */

/* The console stays offstage until the chooser deals a mode; before that it
   would just be an empty box floating over the map. */
.lifeline-console { display: none; }
.lifeline--normal .lifeline-console, .lifeline--hardcore .lifeline-console { display: block; }

.lifeline-console {
  position: fixed; left: 50%; bottom: 12px; transform: translateX(-50%);
  width: min(600px, calc(100vw - 16px));
  background: rgba(18, 28, 44, 0.94);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid #2c405c;
  border-radius: 16px;
  padding: 0 14px 16px;
  color: #e8edf4;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
  z-index: 1100;
}

/* A miss rocks the whole console. The keyframes must carry the centering
   translate, or the shake would fling it half a screen sideways. */
@keyframes lifeline-shudder {
  10%, 50%, 90% { transform: translateX(-50%) translateX(-5px); }
  30%, 70% { transform: translateX(-50%) translateX(5px); }
}
.lifeline-console--shudder { animation: lifeline-shudder 0.4s ease; }

/* The hint ladder burns across the console's top edge, one segment per rung.
   The rungs wear the console's rounded corners themselves, since the console
   can't clip its children without also clipping the dossier above. */
.lifeline-rungs { display: flex; gap: 3px; margin: 0 -14px 12px; border-radius: 16px 16px 0 0; overflow: hidden; }
.lifeline-rung { flex: 1; height: 5px; background: #24374f; transition: background 0.4s; }
.lifeline-rung--lit { background: #e8c876; }
.lifeline-rung--burn { background: #d64545; }

/* One reserved line for the newest hint, alive from the first deal so a
   hint landing never moves the console. */
.lifeline-ticker {
  display: flex; align-items: baseline; gap: 8px; width: 100%; margin-bottom: 12px;
  background: none; border: none; padding: 0; cursor: pointer; text-align: left;
  font-family: inherit; font-size: 15px; color: #5d7292;
  white-space: nowrap; overflow: hidden;
  user-select: none; -webkit-user-select: none;
}
.lifeline-ticker b {
  font-size: 11px; font-weight: 600; letter-spacing: 2px; text-transform: uppercase;
  color: #e8c876; flex-shrink: 0;
}
.lifeline-ticker span { overflow: hidden; text-overflow: ellipsis; }
.lifeline-ticker--live { color: #e8edf4; }
.lifeline-ticker .lifeline-ticker-count {
  flex-shrink: 0; margin-left: auto;
  font-size: 13px; color: #8fa3bc;
}

/* The full dossier floats above the console while the ticker is held,
   animating only opacity and a small slide: nothing below ever shifts. */
.lifeline-dossier {
  position: absolute; left: 0; right: 0; bottom: calc(100% + 10px);
  background: rgba(18, 28, 44, 0.96); border: 1px solid #2c405c; border-radius: 12px;
  padding: 12px 14px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  font-size: 15px; line-height: 1.4;
  opacity: 0; transform: translateY(6px); pointer-events: none;
  transition: opacity 0.25s, transform 0.25s;
}
.lifeline-dossier--open { opacity: 1; transform: none; }
.lifeline-dossier b {
  display: block;
  font-size: 11px; font-weight: 600; letter-spacing: 2px; text-transform: uppercase;
  color: #e8c876; margin-bottom: 3px;
}
.lifeline-dossier div { color: #8fa3bc; margin-bottom: 2px; }
.lifeline-dossier div:last-child { color: #e8edf4; margin-bottom: 0; }

/* One face per mode, plus the shared solved face: Normal keeps all twelve
   cards on the table to the end; Hardcore keeps just the latest miss above
   the input. */
.lifeline-lineup { display: none; grid-template-columns: repeat(3, 1fr); gap: 7px; }
.lifeline--normal:not(.lifeline--over) .lifeline-lineup { display: grid; animation: lifeline-face-in 0.25s ease; }

.lifeline-misses { display: none; }
.lifeline--hardcore:not(.lifeline--over) .lifeline-misses { display: block; animation: lifeline-face-in 0.25s ease; }
.lifeline--hardcore .lifeline-entry:not(:first-child) { display: none; }
.lifeline--hardcore .lifeline-log { margin-bottom: 10px; }

@keyframes lifeline-face-in {
  from { opacity: 0; transform: translateX(14px); }
}

.lifeline-card {
  font-size: 14px; line-height: 1.3; min-height: 48px; padding: 8px 6px; text-align: center;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: #101d30; border: 1px solid #2c405c; border-radius: 10px;
  cursor: pointer; color: #e8edf4;
  transition: opacity 0.3s, border-color 0.2s;
}
.lifeline-card:hover { border-color: #e8c876; }
.lifeline-card--guessed { opacity: 0.4; cursor: default; }
.lifeline-card--guessed:hover { border-color: #2c405c; }
.lifeline-card--won {
  border-color: #2e9d63; background: rgba(46, 157, 99, 0.18);
  box-shadow: 0 0 10px rgba(46, 157, 99, 0.45);
}
.lifeline-card--missed { border-color: #d64545; box-shadow: 0 0 8px rgba(214, 69, 69, 0.5); }

/* The blank line belongs to Hardcore; Normal plays by pointing. */
.lifeline-guessrow { display: none; gap: 8px; }
.lifeline--hardcore:not(.lifeline--over) .lifeline-guessrow { display: flex; }

/* The solved face: the day's result and a door back into the story, since
   the sheet can be closed and the map deserves lingering over. */
.lifeline-solved { display: none; }
.lifeline--over .lifeline-solved {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  animation: lifeline-face-in 0.25s ease;
}
.lifeline--over .lifeline-ticker { display: none; }
.lifeline-solved { flex-wrap: wrap; }
.lifeline-solved > span { font-size: 15px; color: #8fa3bc; }
.lifeline-solved-actions { display: flex; gap: 8px; margin-left: auto; }
.lifeline-story-btn, .lifeline-again-btn {
  background: #101d30; border: 1px solid #e8c876; border-radius: 10px;
  color: #e8c876; font-size: 15px; font-weight: 600; white-space: nowrap;
  padding: 12px 14px; cursor: pointer;
}
.lifeline-story-btn:hover, .lifeline-again-btn:hover { background: #16263c; }
.lifeline-again-btn { border-color: #2c405c; color: #e8edf4; }
.lifeline-input {
  flex: 1; min-width: 0; font-size: 16px; color: #e8edf4;
  background: #101d30; border: 1px solid #2c405c; border-radius: 10px;
  padding: 12px 14px; outline: none;
}
.lifeline-input:focus { border-color: #e8c876; box-shadow: 0 0 0 2px rgba(232, 200, 118, 0.25); }
.lifeline-input::placeholder { color: #5d7292; }
.lifeline-input:disabled { opacity: 0.5; }
.lifeline-guess-btn {
  font-size: 16px; font-weight: 600; color: #14202f;
  background: #e8c876; border: none; border-radius: 10px;
  padding: 0 20px; cursor: pointer;
}
.lifeline-guess-btn:hover { filter: brightness(1.06); }
.lifeline-guess-btn:disabled { opacity: 0.6; cursor: wait; }

.lifeline-log { display: flex; flex-direction: column; gap: 6px; max-height: 38vh; overflow-y: auto; }
.lifeline-log:empty { display: none; }
.lifeline-entry {
  font-size: 14px; line-height: 1.45; padding: 8px 10px;
  background: #101d30; border-radius: 8px; color: #8fa3bc;
}
.lifeline-entry b { color: #e8edf4; font-weight: 600; }

.lifeline-toast {
  position: fixed; left: 50%; bottom: 108px; transform: translateX(-50%) translateY(8px);
  background: #f4eede; color: #2a2118;
  font-size: 15px; font-weight: 600;
  padding: 10px 18px; border-radius: 999px;
  opacity: 0; pointer-events: none; transition: opacity 0.25s, transform 0.25s;
  z-index: 1200;
}
.lifeline-toast--show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---------- mode chooser ---------- */

.lifeline-chooser {
  position: fixed; inset: 0; z-index: 1250;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(10, 16, 26, 0.55);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.lifeline-chooser--done { display: none; }
.lifeline-chooser-card {
  width: min(600px, 100vw);
  background: rgba(18, 28, 44, 0.97);
  border: 1px solid #2c405c; border-bottom: none;
  border-radius: 18px 18px 0 0;
  padding: 22px 18px calc(22px + env(safe-area-inset-bottom));
  box-shadow: 0 -12px 50px rgba(0, 0, 0, 0.5);
}
.lifeline-chooser-card .lifeline-eyebrow { color: #8fa3bc; margin-bottom: 10px; }
.lifeline-chooser-title {
  font-family: var(--lifeline-display);
  font-size: 22px; font-weight: 700; color: #e8edf4; margin-bottom: 8px;
}
.lifeline-howto { font-size: 15px; line-height: 1.45; color: #b4c2d4; margin-bottom: 8px; }
.lifeline-howto + .lifeline-mode { margin-top: 16px; }
.lifeline-mode {
  display: flex; flex-direction: column; gap: 3px; width: 100%; text-align: left;
  background: #101d30; border: 1px solid #2c405c; border-radius: 12px;
  padding: 14px 16px; margin-bottom: 10px; cursor: pointer;
  color: #e8edf4; transition: border-color 0.2s;
}
.lifeline-mode:last-child { margin-bottom: 0; }
.lifeline-mode:hover { border-color: #e8c876; }
.lifeline-mode b { font-size: 18px; color: #e8c876; }
.lifeline-mode span { font-size: 14.5px; color: #8fa3bc; }

/* ---------- map furniture ---------- */

/* Every label on the map is a life card: colored year chips over a place
   line, one family for endpoints and waypoints alike. */
.lifeline-lifecard {
  background: rgba(15, 23, 36, 0.88); color: #fff;
  border: none; border-radius: 8px;
  text-align: center; padding: 5px 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}
.lifeline-lifecard.leaflet-tooltip-top::before { border-top-color: rgba(15, 23, 36, 0.88); }
.lifeline-lifecard small { display: block; font-size: 11px; font-weight: 400; color: #c8d4e4; margin-top: 4px; }
.lifeline-chips { display: flex; gap: 4px; align-items: center; justify-content: center; }
.lifeline-chip {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.3px; color: #fff;
  padding: 2px 7px; border-radius: 5px;
}
.lifeline-chip--origin { background: #2e9d63; }
.lifeline-chip--terminus { background: #d64545; }
.lifeline-chip--waypoint { background: #b8860b; }
.lifeline-chip--mystery {
  border: 1px dashed #5d7292; color: #8fa3bc;
  font-family: var(--lifeline-display); padding: 1px 8px;
}
.lifeline-chip--name {
  color: #e8c876; font-family: var(--lifeline-display);
  font-style: italic; font-size: 13px; padding: 1px 4px;
}

/* The full-circle pin: origin and terminus fused into one split disc, with
   a slow gold breath to say this dot is the whole puzzle. */
.lifeline-fused svg { display: block; width: 22px; height: 22px; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4)); }
.lifeline-fused::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid rgba(232, 200, 118, 0.8);
  animation: lifeline-breathe 2.6s ease-out infinite;
}
@keyframes lifeline-breathe {
  0% { transform: scale(1); opacity: 0.8; }
  70%, 100% { transform: scale(2.4); opacity: 0; }
}
.lifeline-mystery-q {
  color: #44536b; font-size: 20px; font-weight: 700; text-align: center;
  font-family: var(--lifeline-display);
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.7);
}

/* ---------- story sheet ---------- */

.lifeline-sheet {
  position: fixed; left: 0; right: 0; bottom: 0;
  width: 100vw; max-height: 82vh;
  background: #f4eede; color: #2a2118;
  border-radius: 18px 18px 0 0;
  transform: translateY(105%);
  transition: transform 0.6s cubic-bezier(0.3, 1, 0.3, 1);
  overflow-y: auto;
  box-shadow: 0 -18px 50px rgba(0, 0, 0, 0.5);
  padding: 26px 22px calc(30px + env(safe-area-inset-bottom));
  font-family: var(--lifeline-display);
  z-index: 1300;
}
.lifeline-sheet--open { transform: translateY(0); }
.lifeline-eyebrow {
  font-family: var(--bs-body-font-family, system-ui);
  font-size: 12px; font-weight: 600; letter-spacing: 2px; text-transform: uppercase;
  color: #8a7a5e; margin-bottom: 10px;
}
.lifeline-sheet-name { font-size: 32px; line-height: 1.1; margin-bottom: 6px; }
.lifeline-sheet-route { font-family: var(--bs-body-font-family, system-ui); font-size: 14.5px; color: #6b5d44; margin-bottom: 4px; }
.lifeline-sheet-delta { font-style: italic; font-size: 15.5px; color: #8a7a5e; margin-bottom: 18px; }
.lifeline-sheet p { font-size: 17px; line-height: 1.55; margin-bottom: 14px; }
.lifeline-rule { border: none; border-top: 1px solid #d8cdb4; margin: 18px 0; opacity: 1; }
.lifeline-sheet-close {
  position: absolute; top: 14px; right: 14px;
  font-size: 22px; line-height: 1;
  background: none; border: none; color: #8a7a5e; cursor: pointer;
  padding: 8px 10px; border-radius: 8px;
}
.lifeline-sheet-close:hover { background: rgba(0, 0, 0, 0.06); }

.lifeline-lineuproll ul { list-style: none; padding: 0; margin: 0; }
.lifeline-lineuproll li {
  font-family: var(--bs-body-font-family, system-ui);
  font-size: 14.5px; color: #4a3e30; margin-bottom: 8px; line-height: 1.4;
}
.lifeline-lineuproll li i { font-family: var(--lifeline-display); color: #8a7a5e; }

.lifeline-sheet-actions { display: flex; flex-direction: column; gap: 9px; }
.lifeline-sheet-actions form { display: contents; }
.lifeline-absorb, .lifeline-sheet-btn {
  font-family: var(--bs-body-font-family, system-ui);
  font-size: 15.5px; font-weight: 600;
  border-radius: 10px; padding: 13px 16px; cursor: pointer;
  border: 1px solid #c9bc9e; background: transparent; color: #2a2118;
  text-align: left; display: flex; justify-content: space-between; align-items: center; gap: 10px;
  width: 100%;
}
.lifeline-sheet-btn:hover { background: rgba(0, 0, 0, 0.05); }
.lifeline-absorb { background: #2a2118; color: #f4eede; border-color: #2a2118; }
.lifeline-absorb:hover { background: #40342a; }
.lifeline-absorb--done { background: #ede4cf; color: #6b5d44; border-color: #d8cdb4; cursor: default; }
.lifeline-absorb--done:hover { background: #ede4cf; }
.lifeline-keep {
  display: block;
  font-family: var(--bs-body-font-family, system-ui);
  font-size: 14.5px; color: #6b5d44; margin-top: 6px;
}
.lifeline-sharegrid { font-size: 14px; letter-spacing: 1px; }
.lifeline-swarm-note {
  font-style: italic; font-size: 15.5px; color: #6b5d44; margin-top: 14px;
}

/* ---------- wider screens ---------- */

@media (min-width: 761px) {
  .lifeline-header { padding: 14px 20px; }
  .lifeline-date { display: inline; }
  .lifeline-console { bottom: 18px; }
  .lifeline-lineup { grid-template-columns: repeat(4, 1fr); }
  .lifeline-chooser { align-items: center; }
  .lifeline-chooser-card {
    width: min(440px, calc(100vw - 32px));
    border-radius: 18px; border-bottom: 1px solid #2c405c;
    padding: 24px 22px;
  }
  .lifeline-sheet {
    left: auto; top: 0; width: min(420px, 100vw); max-height: none;
    border-radius: 0;
    transform: translateX(105%);
    box-shadow: -18px 0 50px rgba(0, 0, 0, 0.5);
    padding: 26px 28px 30px;
  }
  .lifeline-sheet--open { transform: translateX(0); }
}

/* Keyboard players get the same gold (or ink, on the sheet) the pointer sees. */
.lifeline-console button:focus-visible, .lifeline-chooser button:focus-visible {
  outline: 2px solid #e8c876; outline-offset: 2px;
}
.lifeline-sheet button:focus-visible { outline: 2px solid #2a2118; outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .lifeline-sheet, .lifeline-toast, .lifeline-rung, .lifeline-card, .lifeline-chooser, .lifeline-dossier { transition: none; }
  .lifeline-lineup, .lifeline-misses, .lifeline--over .lifeline-solved, .lifeline-console--shudder { animation: none; }
  .lifeline-fused::after { animation: none; opacity: 0; }
}
