:root {
  --navy: #0a3254;
  --navy-deep: #05233c;
  --navy-soft: rgba(10, 50, 84, 0.97);
  --cream: #fcfcf4;
  --cream-muted: rgba(252, 252, 244, 0.78);
  --red: #cf3338;
  --red-deep: #b92b30;
  --gold: #b89b5f;
  --ink: #111111;
  --parchment: #f4efe1;
}

* {
  box-sizing: border-box;
  /* Kill double-tap-to-zoom everywhere. iOS Safari ignores the viewport's
     user-scalable=no, so touch-action is what actually stops it there.
     touch-action is NOT an inherited property, which is why this sits on the
     universal selector rather than on body. "manipulation" only drops the
     double-tap and legacy gestures, so scrolling and pinch-zoom still work.
     .viewer-canvas keeps its own touch-action: none (class beats *) so the
     joystick still receives raw pointer events. */
  touch-action: manipulation;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  color: var(--cream);
  background: var(--parchment);
  font-family: "Open Sans", Arial, sans-serif;
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  /* This is a guided, kiosk-style experience: no blue selection highlight
     when tapping copy, no grey flash on tap, no long-press save/callout
     menu. These three ARE inherited, so declaring them here is enough. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}

button {
  font: inherit;
  -webkit-tap-highlight-color: transparent;
  /* Kill the browser's double-tap-to-zoom on rapid button taps. */
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}

.hidden {
  display: none !important;
}

/* ===== 3D object viewer stage ===== */
.viewer {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: var(--parchment);
  overflow: hidden;
}

/* Faint atmospheric background texture behind the object. */
.viewer-map {
  position: absolute;
  inset: -6%;
  background: url("./assets/ui/panels-bg.png") center / cover no-repeat;
  opacity: 0.35;
  mix-blend-mode: multiply;
  pointer-events: none;
}

.viewer-canvas {
  /* Always full-bleed — nothing crops the object anymore. main.js shifts
     the camera's optical center to visually center it in the free space
     between the story panel and controls bar instead (viewer.js
     setFrameInsets), so it can render behind those UI bars once zoomed in
     rather than being cut off at their edge. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
}

/* ===== Loading splash ===== */
.landing-screen {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: calc(32px + env(safe-area-inset-top)) 28px calc(34px + env(safe-area-inset-bottom));
  overflow: hidden;
  text-align: center;
  color: var(--cream);
  background: var(--navy);
  opacity: 1;
  transition: opacity 0.45s ease, visibility 0.45s ease;
}

.landing-screen.is-dismissed {
  visibility: hidden;
  pointer-events: none;
  opacity: 0;
}

.landing-map {
  position: absolute;
  inset: -8%;
  background: url("./assets/ui/panels-bg.png") center / cover no-repeat;
  opacity: 0.4;
  mix-blend-mode: multiply;
  pointer-events: none;
}

.landing-content {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: clamp(26px, 5.4vh, 42px);
  transform: translateY(-4vh);
}

.landing-logo {
  width: clamp(196px, 57vw, 248px);
  height: auto;
  filter: drop-shadow(0 8px 22px rgba(0, 0, 0, 0.3));
  animation: landing-logo-breathe 2.6s ease-in-out infinite;
}

@keyframes landing-logo-breathe {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.035);
  }
}

.landing-title {
  margin: 0;
  color: var(--cream);
  font-family: "Hepta Slab", Georgia, "Times New Roman", serif;
  font-size: clamp(28px, 8.4vw, 34px);
  font-weight: 400;
  line-height: 1.3;
}

.landing-progress {
  position: relative;
  width: min(248px, 62vw);
  height: 14px;
  background: #d9d9d9;
  border-radius: 999px;
  overflow: hidden;
}

.landing-progress-bar {
  display: block;
  width: 0;
  height: 100%;
  background: var(--red);
  border-radius: 999px;
  transition: width 0.45s ease;
}

/* ===== Shared primitives ===== */
.ic {
  display: block;
}

.icon-btn {
  flex: none;
  display: grid;
  place-items: center;
  padding: 0;
  width: clamp(52px, 15vw, 60px);
  height: clamp(52px, 15vw, 60px);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.icon-btn .ic {
  width: 40%;
  height: 40%;
}

.icon-btn--red {
  background: var(--red);
  color: var(--cream);
}

.icon-btn--outline {
  background: transparent;
  border: 1px solid var(--red);
  color: var(--cream);
}

/* ===== Story panel (top) ===== */
.ui-layer {
  position: fixed;
  inset: 0;
  z-index: 30;
  pointer-events: none;
}

.story-ui {
  opacity: 1;
  transition: opacity 0.24s ease;
}

.story-panel,
.viewer-controls {
  pointer-events: auto;
}

.story-panel {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  padding: calc(env(safe-area-inset-top) + clamp(14px, 4vh, 20px)) clamp(14px, 4.5vw, 17px)
    clamp(16px, 3vh, 21px) clamp(20px, 8vw, 35px);
  color: var(--cream);
  background: var(--navy);
  box-shadow: 0 14px 28px rgba(0, 0, 0, 0.22);
}

.story-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 14px;
}

.story-title-group {
  min-width: 0;
}

.story-kicker {
  display: block;
  margin: 0 0 2px;
  color: var(--cream);
  font-family: "Hepta Slab", Georgia, "Times New Roman", serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.3;
}

.story-panel h1 {
  margin: 0;
  color: var(--cream);
  font-family: "Hepta Slab", Georgia, "Times New Roman", serif;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.story-text {
  margin: clamp(14px, 3vh, 22px) 0 0;
  color: var(--cream);
  font-family: "Open Sans", Arial, sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.35;
  overflow-wrap: anywhere;
  overflow-y: auto;
  max-height: min(34vh, 240px);
  opacity: 1;
  transition: max-height 0.28s ease, opacity 0.2s ease, margin 0.28s ease;
}

.story-panel:not(.is-expanded) .story-text {
  max-height: 0;
  margin-top: 0;
  opacity: 0;
  overflow: hidden;
}

/* Collapse toggle straddling the panel's bottom edge */
.story-toggle {
  position: absolute;
  left: 50%;
  bottom: -11px;
  transform: translateX(-50%);
  width: 80px;
  height: 22px;
  display: grid;
  place-items: center;
  padding: 0;
  background: var(--cream);
  border: 1px solid #000;
  border-radius: 999px;
  cursor: pointer;
}

.story-toggle .ic {
  width: 18px;
  height: 10px;
  color: var(--navy);
  transition: transform 0.22s ease;
}

.story-toggle.is-hinting {
  animation: story-toggle-invite 1.9s ease-in-out infinite;
  box-shadow: 0 0 0 0 rgba(252, 252, 244, 0.38);
}

.story-toggle.is-hinting::after {
  content: "";
  position: absolute;
  inset: -5px;
  border: 1px solid rgba(252, 252, 244, 0.42);
  border-radius: 999px;
  pointer-events: none;
  animation: story-toggle-ring 1.9s ease-in-out infinite;
}

@keyframes story-toggle-invite {
  0%,
  100% {
    transform: translateX(-50%) translateY(0) scale(1);
  }
  45% {
    transform: translateX(-50%) translateY(3px) scale(1.03);
  }
}

@keyframes story-toggle-ring {
  0%,
  100% {
    opacity: 0;
    transform: scale(0.96);
  }
  45% {
    opacity: 1;
    transform: scale(1.08);
  }
}

/* Expanded => chevron points up (tap to collapse); collapsed => down */
.story-panel.is-expanded .story-toggle .ic {
  transform: rotate(180deg);
}

/* ===== Bottom controls ===== */
.viewer-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(env(safe-area-inset-bottom) + clamp(18px, 4vh, 30px));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 clamp(18px, 6vw, 28px);
}

.joystick-cluster {
  position: relative;
  display: flex;
  align-items: center;
  gap: clamp(14px, 5vw, 22px);
}

.round-btn {
  flex: none;
  display: grid;
  place-items: center;
  padding: 0;
  color: var(--ink);
  background: var(--cream);
  border: 1px solid #000;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.28);
  transition: transform 0.12s ease, background 0.12s ease, color 0.12s ease;
}

/*
 * This app hides .reset-btn (display:none below) — the 5s hold-then-ease-
 * home behavior already covers what a manual reset button would do, so it
 * stays wired up (viewer.reset() still fires) but off-screen.
 */
.reset-btn {
  display: none;
  position: absolute;
  left: clamp(18px, 6vw, 28px);
  width: clamp(44px, 12vw, 50px);
  height: clamp(44px, 12vw, 50px);
}

/*
 * Persistent overview-help toggle (Figma node 4113:13029, adapted: that
 * design stacks it above a visible reset button, but this app hides its
 * reset button — see above — so instead it sits in the same row as the
 * rest of the controls, vertically centered alongside .joystick-cluster
 * rather than stacked above anything). Square-rounded (7px) rather than
 * fully circular like the zoom/joystick buttons, matching the design's
 * shape differentiation for this control.
 */
.help-btn {
  position: absolute;
  left: clamp(18px, 6vw, 28px);
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  padding: 0;
  color: #000;
  background: var(--cream);
  border: 1px solid #000;
  border-radius: 7px;
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.28);
}

/*
 * While the overview is open, the button is reparented to <body> (see
 * detachOverviewBtnAboveScrim in main.js) so it can render above the scrim —
 * .ui-layer is a fixed+z-indexed stacking context, so no z-index on a
 * descendant alone can ever lift it above a separate top-level element like
 * .overview-overlay. left/top are set inline from its just-measured
 * (post-transform) position so it doesn't visually move; transform:none
 * cancels the resting translateY(-50%) so that pinned position isn't offset
 * a second time on top of itself.
 */
.help-btn.is-detached {
  position: fixed;
  bottom: auto;
  transform: none;
  z-index: 70;
}

/* ? and X occupy the same slot and crossfade/rotate between each other. */
.help-btn-icon {
  grid-area: 1 / 1;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  font: 700 16px/1 "Open Sans", Arial, sans-serif;
  transition: opacity 0.22s ease, transform 0.22s ease;
}

.help-btn-icon--question {
  opacity: 1;
  transform: rotate(0deg) scale(1);
}

.help-btn-icon--close {
  opacity: 0;
  transform: rotate(-90deg) scale(0.6);
}

.help-btn-icon--close .ic {
  width: 16px;
  height: 16px;
}

.help-btn.is-open .help-btn-icon--question {
  opacity: 0;
  transform: rotate(90deg) scale(0.6);
}

.help-btn.is-open .help-btn-icon--close {
  opacity: 1;
  transform: rotate(0deg) scale(1);
}

.help-btn:active,
.help-btn.pressed {
  transform: translateY(-50%) scale(0.96);
}

/* Detached (overlay open): resting position has no translateY, so the
   pressed state doesn't need it combined in either. */
.help-btn.is-detached:active,
.help-btn.is-detached.pressed {
  transform: scale(0.96);
}

@media (prefers-reduced-motion: reduce) {
  .help-btn-icon {
    transition: opacity 0.15s ease;
  }
  .help-btn-icon--question,
  .help-btn-icon--close {
    transform: none;
  }
}

.reset-btn .ic {
  width: 60%;
  height: 60%;
}

.zoom-btn {
  width: clamp(52px, 14vw, 60px);
  height: clamp(52px, 14vw, 60px);
}

.zoom-btn .ic {
  width: 48%;
  height: 48%;
}

/* Pressed / active feedback inverts to a dark disc (matches Figma) */
.round-btn:active,
.round-btn.pressed {
  transform: scale(0.94);
  background: var(--ink);
  color: var(--cream);
}

/* ===== Joystick ===== */
.joystick {
  position: relative;
  flex: none;
  width: clamp(78px, 22vw, 92px);
  height: clamp(78px, 22vw, 92px);
  border-radius: 50%;
  background: var(--cream);
  border: 1px solid #000;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.28), inset 0 2px 8px rgba(0, 0, 0, 0.12);
  touch-action: none;
  cursor: grab;
  outline: none;
}

.joystick.is-active {
  cursor: grabbing;
}

.joystick:focus-visible {
  box-shadow: 0 0 0 3px rgba(207, 51, 56, 0.6), 0 8px 18px rgba(0, 0, 0, 0.28);
}

.joystick-knob {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 58%;
  height: 58%;
  border-radius: 50%;
  background: var(--navy);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  transform: translate(-50%, -50%);
  transition: transform 0.001s linear;
}

.joystick-callout {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 14px);
  z-index: 1;
  width: max-content;
  max-width: min(78vw, 285px);
  padding: 8px 12px;
  color: var(--cream);
  background: rgba(0, 0, 0, 0.58);
  border-radius: 8px;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.28);
  font-size: 13px;
  font-weight: 700;
  line-height: 1.25;
  text-align: center;
  text-transform: lowercase;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, 4px);
  transition: opacity 0.24s ease, transform 0.24s ease, visibility 0s linear 0.24s;
}

/* Speech-bubble tail as a single true triangle (no border to fake, so just
   one CSS border-triangle in the same fill color as the bubble). */
.joystick-callout::after {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(100% - 1px); /* tuck under the box edge so no gap shows */
  width: 0;
  height: 0;
  transform: translateX(-50%);
  border-left: 7px solid transparent;
  border-right: 7px solid transparent;
  border-top: 8px solid rgba(0, 0, 0, 0.58);
}

.joystick-cluster.is-joystick-hinting .joystick-callout {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  animation: joystick-callout-float 2.1s ease-in-out infinite;
  transition-delay: 0s;
}

.joystick-cluster.is-joystick-hinting .joystick-knob {
  animation: joystick-knob-pulse 1.8s ease-in-out infinite;
}

@keyframes joystick-callout-float {
  0%,
  100% {
    transform: translate(-50%, 0);
  }
  50% {
    transform: translate(-50%, -5px);
  }
}

@keyframes joystick-knob-pulse {
  0%,
  100% {
    transform: translate(-50%, -50%) scale(1);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  }
  50% {
    transform: translate(-50%, -50%) scale(1.08);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.44), 0 0 0 8px rgba(10, 50, 84, 0.12);
  }
}

/* Snap back to center smoothly on release */
.joystick:not(.is-active) .joystick-knob {
  transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/*
 * Overview modal (Figma node 4113:13029). Persistent — reachable from the
 * .help-btn toggle above the reset button. Fade+scale entrance, same
 * base-hidden / .is-open pattern (no display:none, so the transition can
 * run) already used by .summary-overlay.
 */
.overview-overlay {
  position: fixed;
  inset: 0;
  z-index: 65;
  display: grid;
  place-items: center;
  padding: calc(env(safe-area-inset-top) + 12px) 24px calc(env(safe-area-inset-bottom) + 12px);
  background: rgba(10, 50, 84, 0.84);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.28s ease, visibility 0s linear 0.28s;
}

.overview-overlay.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.28s ease, visibility 0s;
}

.overview-card {
  width: min(302px, 100%);
  /* Content-driven height, capped by max-height so it never exceeds the
     available padded space. On a tall/normal screen it shrink-wraps to its
     3 steps with no leftover space below; on a short screen where content
     would overflow that cap, .overview-steps scrolls internally instead of
     the card stretching past its content or off-screen. */
  max-height: 100%;
  display: flex;
  flex-direction: column;
  /* The card itself never scrolls (overflow-y lives on .overview-steps,
     see below) — hidden here just clips content to the rounded corners so a
     tall step block can't square off the bottom edge. */
  overflow: hidden;
  color: var(--cream);
  background: rgba(10, 50, 84, 0.97);
  border: 3px solid var(--cream);
  border-radius: 19px;
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.4);
  transform: scale(0.94);
  transition: transform 0.28s ease;
}

.overview-overlay.is-open .overview-card {
  transform: scale(1);
}

/* Full-bleed cream header strip — card padding moved off .overview-card and
   onto .overview-steps instead, so this sits flush against the card's own
   top edge/corners without negative margins (which would fight
   .overview-steps' overflow-y). */
.overview-title {
  flex: none;
  margin: 0;
  padding: 22px 26px;
  color: #0a3254;
  background: #f5f6ef;
  border-radius: 16px 16px 0 0;
  font-family: "Open Sans", Arial, sans-serif;
  font-size: 30px;
  font-weight: 700;
  text-align: center;
}

.overview-steps {
  flex: 1 1 auto;
  /* Without this a flex item's default min-height:auto stops it from
     shrinking below its content size, so overflow-y would never actually
     kick in — it'd just push the card taller instead of scrolling. */
  min-height: 0;
  overflow-y: auto;
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
  display: grid;
  /* start, not center — centering a scrollable region's content can leave
     its start clipped off-screen above the scrollable area in some engines. */
  align-content: start;
  gap: 0;
  margin: 0;
  padding: 26px 26px 8px;
  list-style: none;
}

.overview-step {
  position: relative;
  display: grid;
  grid-template-columns: 32px 1fr;
  column-gap: 14px;
  padding-bottom: 28px;
}

/* Dashed connector between steps, running from just below the (top-aligned)
   number down to the top of the next step — skipped after the last step.
   Top-alignment makes this fixed offset reliable regardless of each step's
   text/icon height. */
.overview-step:not(.overview-step--last)::before {
  content: "";
  position: absolute;
  left: 16px;
  top: 34px;
  bottom: 0;
  border-left: 2px dashed rgba(252, 252, 244, 0.4);
}

.overview-step-num {
  grid-row: 1 / 3;
  /* Top-aligned (the default) so the number sits flush with the first line
     of its text. text-align centers the digit horizontally within the 32px
     column regardless of glyph width, so the dashed connector below lines
     up under any of them consistently. */
  text-align: center;
  font-family: "Open Sans", Arial, sans-serif;
  font-size: 40px;
  font-weight: 700;
  line-height: 1;
}

.overview-step-text {
  margin: 0 0 14px;
  font-family: "Open Sans", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.3;
}

.overview-step-icon {
  grid-column: 2;
  display: flex;
  justify-content: center;
  color: var(--cream);
}

/* ===== Summary overlay ===== */
.summary-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  padding-top: calc(env(safe-area-inset-top) + 8px);
  color: var(--cream);
  background: var(--navy);
  transform: translateX(100%);
  visibility: hidden;
  will-change: transform;
  transition: transform 0.42s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s linear 0.42s;
}

.summary-overlay.is-open {
  transform: translateX(0);
  visibility: visible;
  transition: transform 0.42s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s;
}

.summary-shift {
  transform: translateX(-100%);
  transition: transform 0.42s cubic-bezier(0.4, 0, 0.2, 1);
}

.summary-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: clamp(8px, 2vh, 14px) clamp(14px, 4.5vw, 17px) clamp(18px, 3vh, 26px) clamp(20px, 8vw, 35px);
}

.summary-header h2 {
  margin: 0;
  color: var(--cream);
  font-family: "Hepta Slab", Georgia, "Times New Roman", serif;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.3;
}

.summary-list {
  min-height: 0;
  padding: 0 clamp(20px, 8vw, 32px) calc(env(safe-area-inset-bottom) + 30px);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--cream) transparent;
}

.summary-list::-webkit-scrollbar {
  width: 7px;
}

.summary-list::-webkit-scrollbar-track {
  background: transparent;
}

.summary-list::-webkit-scrollbar-thumb {
  background: var(--cream);
  border-radius: 999px;
}

.summary-item {
  padding: clamp(22px, 4vh, 32px) 0;
}

.summary-item h3 {
  margin: 0 0 clamp(16px, 3vh, 22px);
  color: var(--cream);
  font-family: "Hepta Slab", Georgia, "Times New Roman", serif;
  font-size: 30px;
  font-weight: 700;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

/* Painting slot — real artwork drops in via .summary-figure img.
   The slot is landscape (342/262) but the artwork is portrait, so the image
   is fitted whole rather than cropped and the leftover space reads as a
   white mat around it. */
.summary-figure {
  margin: 0 0 clamp(16px, 3vh, 22px);
  width: 100%;
  aspect-ratio: 342 / 262;
  border-radius: 2px;
  background: #ffffff;
  border: 1px solid rgba(252, 252, 244, 0.45);
  overflow: hidden;
}

.summary-figure img {
  display: block;
  width: 100%;
  height: 100%;
  /* contain (not cover) so the whole artwork stays visible, centered in the
     slot with white on the sides instead of being cropped to fill. */
  object-fit: contain;
  object-position: center;
}

.summary-item p {
  margin: 0;
  color: var(--cream);
  font-family: "Open Sans", Arial, sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* Longer-form sections appended after the short blurb above (see
   panel.summaryExtended) — each its own sub-heading plus one or more
   paragraphs, so a smidge smaller than .summary-item h3 to read as
   secondary to the artifact's own title. */
.summary-section-heading {
  margin: clamp(24px, 4.5vh, 34px) 0 clamp(10px, 2vh, 14px);
  color: var(--cream);
  font-family: "Hepta Slab", Georgia, "Times New Roman", serif;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

/* Qualified with .summary-item (not just .summary-section-text alone) so
   this beats .summary-item p's margin:0 on specificity (0-2-0 vs 0-1-1) —
   otherwise that pre-existing, more-specific rule silently wins and zeroes
   the bottom margin on every one of these paragraphs, not just the last,
   regardless of which rule comes later in the file. */
.summary-item .summary-section-text {
  margin: 0 0 14px;
  color: var(--cream);
  font-family: "Open Sans", Arial, sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.summary-item .summary-section-text:last-child {
  margin-bottom: 0;
}

/* ===== Press feedback ===== */
.icon-btn:active,
.icon-btn.pressed {
  transform: scale(0.96);
}

.story-toggle:active,
.story-toggle.pressed {
  transform: translateX(-50%) scale(0.96);
}

/* Short viewports: tighten the expanded panel so it never crowds the controls */
@media (max-height: 720px) {
  .story-text {
    max-height: 26vh;
  }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .landing-logo {
    animation: none;
  }

  .story-text,
  .summary-overlay,
  .summary-overlay.is-open,
  .summary-shift,
  .story-ui,
  .joystick-callout,
  .joystick:not(.is-active) .joystick-knob {
    transition-duration: 0.001s;
  }

  .joystick-cluster.is-joystick-hinting .joystick-knob,
  .joystick-cluster.is-joystick-hinting .joystick-callout,
  .story-toggle.is-hinting,
  .story-toggle.is-hinting::after {
    animation: none;
  }
}
