/* Placeholder palette: swap for PeaceLink's real brand colours/logo when
   available (open item, CLAUDE.md "Visual identity: PeaceLink"). Deliberately
   dark throughout - the crisis opens at 3:12 AM, and the design's own ending
   screens are already "text on black" (docs/DESIGN.md). Contrast is verified
   AA (checked against the WCAG relative-luminance formula, not eyeballed)
   for every text/background pairing below; see notes at each pairing that
   isn't a simple text-on-page case. Mobile-first: base rules target small
   screens, a single breakpoint widens layouts on larger ones. */

:root {
  --color-bg: #0a0a0a;
  --color-text: #f0efe9; /* ~17:1 on --color-bg */
  --color-muted: #b3b0a8; /* ~9:1 on --color-bg, ~6:1 on the darkest sender tint below */
  --color-primary: #2f6b4f; /* button fill; paired only with white text (~6.3:1), never used as text-on-page */
  --color-primary-text: #ffffff;
  --color-accent-on-dark: #6fcf9b; /* brighter green for text/icons drawn directly on the page (~10:1) */
  --color-border: #63635c; /* ~3.3:1 non-text UI boundary, decorative only */
  --color-surface: #17181a; /* dark elevated surface, e.g. debrief callouts */
  --color-accent: #ff8a80; /* errors; ~8.7:1 on --color-bg */
  --color-link: #7fb0ff; /* ~9:1 on --color-bg */
  --focus-ring: #58a6ff;
  --max-width: 40rem;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  position: relative;
  background: var(--color-bg); /* fallback while the image loads, or if it fails */
  color: var(--color-text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 1rem;
  line-height: 1.5;
}

/* Site-wide background photo (CLAUDE.md content rules, decided 2026-09-29).
   A fixed, viewport-sized pseudo-element rather than
   `background-attachment: fixed` on body - that property is unreliable on
   iOS Safari, and this project is mobile-first. The 0.85-opacity black scrim
   keeps every existing text colour at its already-verified AA contrast even
   over the image's brightest areas (checked against the WCAG formula: the
   worst case, a pure-white pixel under this overlay, still leaves body text
   at ~13:1 and muted text at ~7.6:1 - both comfortably above 4.5:1). */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: linear-gradient(rgba(10, 10, 10, 0.85), rgba(10, 10, 10, 0.85)), url("../assets/images/nagasaki.jpg") center / cover
    no-repeat;
}

h1,
h2,
h3 {
  line-height: 1.2;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

a {
  color: var(--color-link);
}

:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}

/* focusHeading() (dom.js) sets tabindex="-1" and calls .focus() on the new
   screen's heading every time a screen renders, so screen-reader/keyboard
   users get told "the screen changed" without an aria-live region
   announcing the whole page. tabindex="-1" elements are never reachable by
   pressing Tab - only by script - so this ring can only ever be the result
   of that call, never a real keyboard user navigating here. Safe to drop:
   the focus move itself (what screen readers depend on) is unaffected. */
h1[tabindex="-1"]:focus-visible,
h2[tabindex="-1"]:focus-visible {
  outline: none;
}

.screen {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 1rem 1.25rem 3rem;
}

.loading,
.fatal-error {
  padding: 2rem 1.25rem;
  text-align: center;
}

.fatal-error {
  color: var(--color-accent);
}

/* Buttons */

.btn {
  display: inline-block;
  font-size: 1rem;
  padding: 0.75rem 1.25rem;
  border-radius: 0.375rem;
  border: 2px solid transparent;
  cursor: pointer;
  margin: 0.25rem 0.25rem 0.25rem 0;
  min-height: 2.75rem; /* comfortable touch target */
}

.btn-primary {
  background: var(--color-primary);
  color: var(--color-primary-text);
}

.btn-secondary {
  background: transparent;
  color: var(--color-accent-on-dark);
  border-color: var(--color-accent-on-dark);
}

.btn-choice {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--color-surface);
  color: var(--color-text);
  border-color: var(--color-border);
  margin: 0.375rem 0;
}

.choice-list {
  display: flex;
  flex-direction: column;
}

.credits {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.9rem;
  color: var(--color-muted);
  margin: 1.5rem 0;
}

.credits img {
  flex: 0 0 auto;
}

.credits-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.credits a {
  color: inherit;
}

.version-tag {
  font-size: 0.7rem;
  color: var(--color-muted);
}

/* Language switcher */

.language-switcher {
  display: flex;
  gap: 0.75rem;
  justify-content: flex-end;
  font-size: 0.9rem;
  margin-bottom: 1rem;
}

.language-switcher a[aria-current="true"] {
  font-weight: bold;
  text-decoration: none;
  color: var(--color-text);
}

/* Content warning / landing */

.banner {
  background: var(--color-surface);
  border-left: 4px solid var(--color-accent-on-dark);
  padding: 0.75rem 1rem;
  margin: 1rem 0;
}

/* Role select */

.role-grid {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.role-card {
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  padding: 1rem;
}

.role-situation {
  color: var(--color-muted);
  font-style: italic;
}

/* Prologue */

.screen-count {
  color: var(--color-muted);
  font-size: 0.875rem;
}

.prologue-actions {
  margin-top: 1.5rem;
}

/* Crisis */

.screen-crisis {
  padding-top: 0;
}

.crisis-header {
  position: sticky;
  top: 0;
  background: var(--color-bg);
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--color-border);
  z-index: 1;
}

.crisis-timer {
  font-size: 1.25rem;
  font-weight: bold;
  margin: 0;
  font-variant-numeric: tabular-nums;
  padding: 0.15rem 0.4rem;
  border-radius: 0.25rem;
}

/* A single, non-repeating pulse marking a cost jump ("chiedi conferma"
   skipping time forward). Gated behind prefers-reduced-motion: reduce so it
   never fires for users who've asked for less motion - it's a nice-to-have
   cue, not the only signal (the log entry "Hai perso N secondi." carries the
   same information for aria-live/screen-reader users regardless). */
@media (prefers-reduced-motion: no-preference) {
  .crisis-timer.timer-jump {
    animation: timer-flash 700ms ease-out;
  }
}

@keyframes timer-flash {
  0% {
    background-color: var(--color-primary);
    color: var(--color-primary-text);
  }
  100% {
    background-color: transparent;
    color: inherit;
  }
}

.crisis-log {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem 0;
}

/* Two-tier alignment simulating a multi-person exchange: the player's own
   notes stay flush left (see .message-note below); every incoming message,
   regardless of sender, is indented and tinted so it visually reads as
   "someone else speaking". */
.message {
  background: var(--sender-bg, var(--color-surface));
  border-radius: 0.5rem;
  padding: 0.75rem 1rem;
  margin-left: 1.5rem;
}

.message-sender {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: bold;
  margin: 0 0 0.25rem;
}

.sender-icon {
  flex: 0 0 auto;
  color: var(--color-muted);
}

.message-text {
  margin: 0 0 0.25rem;
}

.message-text:last-child {
  margin-bottom: 0;
}

.message-reliability {
  color: var(--color-muted);
  font-size: 0.875rem;
  margin: 0.25rem 0 0;
}

.message-note {
  /* Flush left, no indent, no tint: this is the player's own line, not an
     incoming message, so it deliberately looks different from .message. */
  color: var(--color-muted);
  font-size: 0.875rem;
  font-style: italic;
  margin: 0.5rem 0;
}

/* The one confirmation that must never read as "nothing happened": some
   options (e.g. "Convoca la sala crisi") have no cost and no other visible
   effect, so this note is the ONLY feedback the click occurred. Deliberately
   heavier than a plain note: not italic, full-strength text colour, an
   accent border and a checkmark. */
.message-note-choice {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--color-text);
  font-style: normal;
  font-weight: 600;
  font-size: 1rem;
  border-left: 3px solid var(--color-accent-on-dark);
  padding-left: 0.6rem;
}

.message-note-choice .sender-icon {
  color: var(--color-accent-on-dark);
}

@media (prefers-reduced-motion: no-preference) {
  .message-note-choice {
    animation: note-pop 300ms ease-out;
  }
}

@keyframes note-pop {
  from {
    opacity: 0;
    transform: translateY(-3px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.crisis-decision {
  padding: 0.5rem 0 1rem;
}

/* The countdown for the CURRENT question, distinct from the elapsed-time
   clock pinned in the sticky header above - the two used to occupy the same
   spot and overlap (whichever one the last render happened to show). */
.decision-timer {
  font-weight: bold;
  font-variant-numeric: tabular-nums;
  color: var(--color-accent-on-dark);
  margin: 0 0 0.5rem;
}

/* Shown whenever nothing is awaiting a decision, so a long real gap between
   scripted beats doesn't read as the app being stuck. Reveals nothing about
   what's coming or when - only that the crisis is still live. The pulse is a
   slow, low-contrast breathing (3s cycle), nowhere near flash-risk territory,
   and is dropped entirely under reduced motion. */
.ambient-status {
  color: var(--color-muted);
  font-size: 0.875rem;
  font-style: italic;
  text-align: center;
  padding: 0.5rem 0;
}

@media (prefers-reduced-motion: no-preference) {
  .ambient-status {
    animation: ambient-pulse 3s ease-in-out infinite;
  }
}

@keyframes ambient-pulse {
  0%,
  100% {
    opacity: 0.55;
  }
  50% {
    opacity: 1;
  }
}

/* Result */

.result-columns {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  margin: 1.5rem 0;
}

.result-column ul {
  padding-left: 1.25rem;
  margin: 0.25rem 0 0;
}

.result-hint {
  color: var(--color-muted);
  font-size: 0.875rem;
  font-style: italic;
  margin: 0 0 1rem;
}

.timeline-group + .timeline-group {
  margin-top: 0.9rem;
}

/* The game's core thesis, shown after every ending regardless of outcome:
   even the best play only reaches a near miss, never a clean win. Set apart
   visually so it reads as the closing word on the outcome, not just another
   detail paragraph. */
.cannot-win {
  font-weight: 600;
  font-size: 1.0625rem;
  border-top: 1px solid var(--color-border);
  margin-top: 1.25rem;
  padding-top: 1rem;
}

.timeline-time {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-accent-on-dark);
  margin: 0;
}

.result-outcome {
  border-top: 3px solid var(--color-accent-on-dark);
  padding-top: 1rem;
}

.variant-name {
  font-weight: bold;
  color: var(--color-muted);
}

.result-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Debrief */

.debrief-card {
  border-bottom: 1px solid var(--color-border);
  padding: 1rem 0;
}

.debrief-question {
  font-weight: bold;
}

.debrief-sources {
  font-size: 0.875rem;
  color: var(--color-muted);
  padding-left: 1.25rem;
}

.impact-source-tag {
  color: var(--color-muted);
}


.cta-list {
  list-style: none;
  padding-left: 0;
  margin: 0.75rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  background: var(--color-surface);
  padding: 1rem;
  border-radius: 0.5rem;
}

.cta-link a {
  display: flex;
  align-items: center;
  gap: 1rem;
  color: var(--color-text);
  text-decoration: none;
}

.cta-link a:hover,
.cta-link a:focus-visible {
  text-decoration: underline;
}

.cta-image {
  width: 88px;
  height: 88px;
  flex: 0 0 auto;
  border-radius: 0.5rem;
}

.debrief-casualties {
  background: var(--color-surface);
  padding: 1rem;
  border-radius: 0.5rem;
  margin: 1.5rem 0;
}

.debrief-share {
  margin: 1.5rem 0;
}

.share-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

/* Wider screens */
@media (min-width: 48rem) {
  .role-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
  }

  /* result-columns stays vertical (whatHappened / whatYouKnew /
     whatYouDidnt, in that order) at every width - not side-by-side. */
}

/* Respect reduced-motion preferences; the game has no essential animation. */
@media (prefers-reduced-motion: reduce) {
  * {
    scroll-behavior: auto !important;
  }
}
