/* ---------- Variables ---------- */
:root {
  --menu-width: 200px;
  --nav-text: #ffffff;
  --font-main: system-ui, -apple-system, "Segoe UI", sans-serif;
  --color-o: #C66C24; /* rust orange, project accent color "O" */

  /* ATM callout button — change these to restyle the button everywhere
     it's used. The icon is drawn with CSS, not an image file. */
  --atm-btn-icon-color: var(--color-o); /* circle fill */
  --atm-btn-icon-mark: #ffffff;         /* the "+" mark on the circle */
  --atm-btn-glow-rgb: 198, 108, 36;     /* same color as --color-o, as r,g,b for the glow's fade */
  --atm-btn-font: "Skranji", cursive;
  --atm-btn-pill-bg: #ececec;
  --atm-btn-text-color: #0d0c0c;

  /* Problem overlay text. Heading is bold Kalam and stays white;
     everything else in the overlay is regular Kalam at 16-18px on
     desktop, in this gray. */
  --overlay-font: "Kalam", cursive;
  --overlay-text-color: #a2a2a2;

  /* Ideation overlay ("Four Plays. One Problem.") — its own orange,
     different from the project's color "O" above, plus the red used
     only for play 4's low score chip. */
  --color-o2: #e67b2b;
  --color-chip-red: #e52e06;
}

/* ---------- Reset ---------- */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: var(--font-main);
  color: #222222;
  background: #040405; /* fills any space around the image on tall screens */
}

img {
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

ul {
  list-style: none;
}

/* ---------- Left side menu ---------- */
/* Transparent menu fixed on the left, on top of the image. */
.side-menu {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 10;
  width: var(--menu-width);
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: 32px;
  color: var(--nav-text);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

.logo {
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-decoration: none;
}

.logo-line-1 {
  color: var(--color-o2);
  font-family: var(--overlay-font);
  font-weight: 700;
  font-style: italic;
  font-size: 36px;
  line-height: 1;
  white-space: nowrap;
}

.logo-line-2 {
  color: #ffffff;
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: 36px;
  line-height: 1;
  white-space: nowrap;
}

/* Always-visible link back to the portfolio site, same icon/style as
   .winning-back. Hidden only while the Winning Play sequence's own Back
   button is showing (same top-left spot — one or the other, never both). */
.project-back {
  display: flex;
  align-items: center;
  gap: 0.5em;
  color: #ffffff;
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(13px, 1.5vw, 17px);
  text-decoration: none;
  white-space: nowrap;
  opacity: 0.9;
  transition: opacity 0.2s ease;
}

.project-back img {
  width: 1.3em;
  height: auto;
}

.project-back:hover,
.project-back:focus-visible {
  opacity: 1;
}

body.winning-open .project-back {
  opacity: 0;
  pointer-events: none;
}

.menu-links {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ---------- Scene ---------- */
/* The image fills the full width and its height follows its own ratio.
   No side bars, no cropping, no stretching. */
.scene-stage {
  position: relative;
  z-index: 2; /* sits above .winning-board-photo so it hides that photo
                 until it slides away */
  width: 100%;
  transition: transform 0.8s ease, transform-origin 0.8s ease;
}

/* clips the zoomed stage so it never causes a scrollbar. Positioned so
   .winning-board-photo (a direct child, sibling to .scene-stage) anchors
   to the hero section itself rather than drifting to whatever ancestor
   happens to be positioned further up the page. */
.scene {
  position: relative;
  overflow: hidden;
}

/* Each overlay zooms toward a different spot in the 1920 x 1083 scene
   image: the Problem overlay toward the ATM, the Ideation overlay toward
   the basketball hoop/backboard. */
body.problem-open .scene-stage {
  transform: scale(1.12);
  transform-origin: 65.1% 50.8%;
}

body.ideation-open .scene-stage {
  transform: scale(1.12);
  transform-origin: 75.5% 35%;
}

/* Winning Play: instead of zooming, the whole illustrated scene slides
   off to the left, uncovering the real photo that's been sitting behind
   it in .winning-board-photo (below) the entire time — a slide reveal
   rather than a zoom. */
body.winning-open .scene-stage {
  transform: translateX(-100%);
}

/* Hide all 3 trigger buttons while any overlay/reveal is open, so they
   don't peek out oddly from behind the zoomed/slid background. */
body.problem-open .atm-callout,
body.ideation-open .atm-callout,
body.winning-open .atm-callout {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.scene-bg {
  display: block;
  width: 100%;
  height: auto;
}

/* The real backboard photo. Sits full-screen behind .scene-stage from
   the very start (hidden only because the opaque scene sits on top of
   it, z-index 2 vs 1) — when "Winning Play" slides the scene away, this
   is simply what was underneath all along. */
.winning-board-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 1;
  pointer-events: none;
}

/* Returns to the hero scene. Same look as .ideation-back, positioned
   top-left just below the "ATM Journey" logo (which sits at the
   side-menu's own 32px padding). Hidden until winning-open, same
   pattern as the rest of this sequence. */
.winning-back {
  position: absolute;
  left: 32px;
  top: 32px; /* was 70px — the logo grew to 2 bold lines and now needs
                to sit below Back instead of overlapping it */
  z-index: 11; /* above .side-menu (10), so it's reachable even though
                  it sits close to the logo above it */
  display: flex;
  align-items: center;
  gap: 0.5em;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: #ffffff;
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(13px, 1.5vw, 17px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.winning-back img {
  width: 1.3em;
  height: auto;
}

body.winning-open .winning-back {
  opacity: 0.9;
  pointer-events: auto;
}

.winning-back:hover,
.winning-back:focus-visible {
  opacity: 1;
}

/* ---------- Winning Play: swish sequence ---------- */
/* All pieces below are positioned against the same 1920x1080 reference
   viewport as everything else in this file. script.js adds the -active
   classes below in sequence after the slide finishes; nothing here plays
   on its own. */

/* Basketball: starts off-screen left and low (like a shot from the
   court), arcs up and over, and lands centered on the rim. */
.winning-ball {
  position: absolute;
  left: -8%;
  top: 70%;
  width: 6.3%; /* matches the size of the ball the girl is dribbling in
                  the hero scene, measured from a screenshot */
  height: auto;
  z-index: 3;
  opacity: 0;
  pointer-events: none;
}

body.winning-ball-active .winning-ball {
  animation: winning-ball-fly 0.55s ease-in forwards;
}

@keyframes winning-ball-fly {
  0%   { left: -8%;  top: 70%; opacity: 1; transform: rotate(0deg); }
  50%  { left: 20%;  top: 8%;  transform: rotate(150deg); }
  100% { left: 45.9%; top: 39.3%; opacity: 1; transform: rotate(300deg); }
}

/* Continues straight on from winning-ball-fly's landing spot — the ball
   drops on through the net and out the bottom instead of freezing in
   place, then fades out like it's rolled away. Triggered a beat after
   winning-ball-active (see script.js), so it takes over the "animation"
   property right where the fly animation left it, no jump. */
body.winning-ball-drop-active .winning-ball {
  animation: winning-ball-drop 0.6s ease-in forwards;
}

@keyframes winning-ball-drop {
  0%   { left: 45.9%; top: 39.3%; opacity: 1; transform: rotate(300deg); }
  100% { left: 43.5%; top: 68%;   opacity: 0; transform: rotate(380deg); }
}

/* Front rim lip: sits on top of the ball so the ball reads as passing
   through the hoop. Scaled/positioned to match the board photo's own
   back attachment sliver (measured at left 43.3% / top 40.8% / width
   11.46% of the scene), so the two halves read as one continuous rim. */
.winning-rim-front {
  position: absolute;
  left: 43.3%;
  top: 40.8%;
  width: 11.46%;
  height: auto;
  opacity: 0; /* hidden until winning-open — same pattern as the board
                 photo and net below, so it doesn't float over the hero
                 scene before "Winning Play" is clicked */
  z-index: 4;
  pointer-events: none;
}

/* Net: idle static crop, same spot the whole time the photo is up. */
.winning-net-overlay {
  position: absolute;
  left: 44.3%;
  top: 42.1%;
  width: 9.52%;
  height: auto;
  opacity: 0;
  z-index: 5;
  pointer-events: none;
}

/* Waits for winning-ball-active (not winning-open) so these only appear
   once the 0.8s slide has fully finished — showing them immediately at
   click time left them floating over the old scene while it was still
   sliding away. */
body.winning-ball-active .winning-rim-front,
body.winning-ball-active .winning-net-overlay {
  opacity: 1;
}

/* Animated swish version, same spot, one layer higher — hidden until the
   ball lands, then script.js swaps it in for one play-through before
   swapping back to the static crop above. */
.winning-net-gif {
  position: absolute;
  left: 44.3%;
  top: 42.1%;
  width: 9.52%;
  height: auto;
  z-index: 6;
  opacity: 0;
  pointer-events: none;
}

body.winning-net-swish .winning-net-gif {
  opacity: 1;
}

body.winning-net-swish .winning-net-overlay {
  opacity: 0;
}

/* "SWISH!" pops in right as the ball lands, to the left of the board. */
.winning-swish {
  position: absolute;
  left: 43%;
  top: 20%; /* was 15% */
  margin: 0;
  color: #ffc53d;
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(28px, 4.5vw, 64px);
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transform: scale(0.5);
  z-index: 3;
  pointer-events: none;
}

body.winning-swish-active .winning-swish {
  animation: winning-swish-pop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

@keyframes winning-swish-pop {
  0%   { opacity: 0; transform: scale(0.5); }
  60%  { opacity: 1; transform: scale(1.15); }
  100% { opacity: 1; transform: scale(1); }
}

/* Summary panel: heading, score, CTA, process breadcrumb. Fades/slides in
   last, once the swish has landed. */
.winning-panel {
  position: absolute;
  right: 0%;
  bottom: calc(10% + 60px); /* the Netlify badge is a fixed-size, fixed-
                               position element (doesn't scale with the
                               page), so a pure % bottom wasn't enough
                               clearance on shorter viewports — adding a
                               flat 60px on top of the % fixes that at
                               any screen size */
  width: 36%;
  z-index: 3;
  background: rgba(0, 0, 0, 0.2);
  padding: 1.5em 2em;
  text-align: center;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
  pointer-events: none;
}

body.winning-panel-active .winning-panel {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.winning-panel-heading {
  margin: 0 0 0.4em;
  color: #ffffff;
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(18px, 2.2vw, 30px);
}

.winning-panel-score {
  margin: 0 0 1em;
  color: var(--color-o2);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(14px, 1.6vw, 19px);
}

.winning-panel-score-num {
  font-weight: 700;
}

.winning-panel-score-num::before {
  content: "→ ";
}

.winning-panel-cta {
  display: inline-block;
  margin: 0 0 1.2em;
  background: var(--color-o2);
  color: #0d0c0c;
  border: none;
  border-radius: 999px;
  padding: 0.7em 1.6em;
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(13px, 1.4vw, 17px);
  text-decoration: none; /* now an <a>, which underlines by default */
  cursor: pointer;
  transition: filter 0.2s ease;
}

.winning-panel-cta:hover,
.winning-panel-cta:focus-visible {
  filter: brightness(1.12);
}

.winning-panel-breadcrumb {
  margin: 0;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(11px, 1.1vw, 14px);
}

/* Dribbling GIF (624 x 660, transparent), placed over the seated girl.
   It sits at x=210, y=422 of the 1920 x 1083 scene image, at its natural
   size. Values are percentages of the scene, so it stays aligned at every
   screen size. Adjust left/top to nudge it. */
.scene-video {
  position: absolute;
  left: 10.9375%;   /* 210 / 1920 */
  top: 38.965%;     /* 422 / 1083 */
  width: 32.5%;     /* 624 / 1920 */
  height: auto;
}

/* Digital countdown on the billboard screen. Measured by mapping the
   reference image's own billboard-relative text positions onto this
   scene's actual billboard box (left 47.9% / top 3.5% / width 26.1% /
   height 24.2% of the 1920x1080 scene). */
.billboard-clock {
  position: absolute;
  left: 51.3%;
  top: 14%;
  width: 11.3%;
  height: auto;
  animation: billboard-clock-blink 1.8s steps(1) infinite; /* was 1s —
    slower blink, still instant on/off (not a fade) for an LED-display feel */
}

@keyframes billboard-clock-blink {
  0%, 49% { opacity: 0.85; }
  50%, 100% { opacity: 0; }
}

.billboard-hrs {
  position: absolute;
  left: 64.3%;
  top: 15%;
  width: 5.6%;
  height: auto;
  opacity: 0.85;
}

.billboard-ux-challenge {
  position: absolute;
  left: 63.5%;
  top: 20.5%; /* was 19.5%, then 21.5% — slightly less gap than that */
  width: 6.5%;
  height: auto;
  transform: rotate(0deg);
  transform-origin: left center;
  opacity: 0.85;
}

/* ATM callout button, placed on the floor below the ATM, overlapping its
   base. Position is a percentage of the scene image (1920 x 1083), so it
   stays on the same spot at every screen size. Its own size (font,
   padding, icon) is set in vw with NO effective ceiling, so it shrinks
   and grows exactly in step with the image at every desktop width — a
   fixed-px ceiling here was what made the button look oversized on
   screens narrower than 1920px (the image scaled down but the button
   didn't). Only a small floor keeps it readable on tiny phones. */
.atm-callout {
  position: absolute;
  left: 65.7%;   /* 1262 / 1920 */
  top: 64.2%;    /* 695 / 1083 */
  transform: translateY(-50%);
  z-index: 5;
  display: flex;
  align-items: center;
  font-size: clamp(11px, 0.99vw, 24px);
  /* reset default <button> styling, since this is a button, not a link */
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
}

/* Halo: the light disc behind the icon (same tone as the pill), with the
   orange circle inset inside it. Change --atm-btn-icon-color /
   --atm-btn-icon-mark / --atm-btn-pill-bg in :root to restyle it. It
   pulses gently to invite a click. */
.atm-callout-icon-halo {
  position: relative;
  flex: none;
  z-index: 2;
  width: 3.15em;
  height: 3.15em;
  margin-right: -1.26em;
  border-radius: 50%;
  background: var(--atm-btn-pill-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: atm-btn-pulse 2.4s ease-in-out infinite;
}

.atm-callout-icon {
  position: relative;
  width: 83%;
  height: 83%;
  border-radius: 50%;
  background: var(--atm-btn-icon-color);
}

.atm-callout-icon-bar-h,
.atm-callout-icon-bar-v {
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--atm-btn-icon-mark);
  border-radius: 999px; /* rounded ends, not square corners */
  transform: translate(-50%, -50%);
}

.atm-callout-icon-bar-h {
  width: 34%;
  height: 9%;
}

.atm-callout-icon-bar-v {
  width: 9%;
  height: 34%;
}

@keyframes atm-btn-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(var(--atm-btn-glow-rgb), 0.55);
    transform: scale(1);
  }
  70% {
    box-shadow: 0 0 0 14px rgba(var(--atm-btn-glow-rgb), 0);
    transform: scale(1.05);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(var(--atm-btn-glow-rgb), 0);
    transform: scale(1);
  }
}

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

.atm-callout-pill {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  background: var(--atm-btn-pill-bg);
  border-radius: 8px;
  padding: 0.5em 1.4em 0.5em 1.4em;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);
}

.atm-callout-text {
  display: inline-block;
  position: relative;
  top: 0.06em; /* the pill's padding is mathematically equal top and
                  bottom (measured 9.5px / 9.5px) — this small nudge
                  compensates for Kalam's own glyph weight sitting higher
                  in its line box than the box's true center, so the
                  visible ink looks centered too, not just the box */
  color: var(--atm-btn-text-color);
  font-family: var(--overlay-font); /* Kalam, both CTAs now */
  font-weight: 700;
  font-size: 16px;
  line-height: 1;
}

/* "Explore the ATM Problem" wraps to 2 lines (via <br>) — left-align them
   instead of letting them center relative to each other. */
#problem-trigger .atm-callout-text {
  text-align: left;
}

/* "The Ideation Plays" — same button, same icon/pulse animation and pill,
   just its own spot: floating between the hoop and the graffiti wall. */
.atm-callout--ideation {
  left: 75.4%;  /* 1448 / 1920 */
  top: 54.2%;   /* 587 / 1083 */
}

.atm-callout--ideation .atm-callout-text {
  white-space: nowrap;
}

/* "Winning Play" — same button again, at the basketball board's right
   corner (measured the same way: % of the 1920x1080 reference shot). */
.atm-callout--winning {
  left: 84%;    /* was 88% — nudged left so the pill clears the right edge */
  top: 28%;     /* a little below the board's own top-right corner (25.6%),
                   same "offset below the landmark" pattern as the other two */
}

.atm-callout--winning .atm-callout-text {
  white-space: nowrap;
}

/* ---------- Problem overlay ---------- */
/* A dimmed backdrop that fades/scales the card in and out. Hidden by
   default; .is-open (added by script.js) reveals it. */
.overlay-backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(4, 4, 5, 0);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.35s ease, background 0.35s ease, visibility 0.35s;
}

.overlay-backdrop.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  background: rgba(4, 4, 5, 0.6);
}

/* The card itself: same pattern as .scene-stage, everything inside is
   positioned as a percentage of the card's own 871 x 604 image (its
   current native size — update this if overlay bg.svg is replaced again
   with a different size), so it scales as one unit at any screen size. */
.overlay-card {
  position: relative;
  width: min(760px, 100%);
  aspect-ratio: 871 / 604;
  transform: scale(0.94) translateY(10px);
  opacity: 0;
  transition: transform 0.35s ease, opacity 0.35s ease;
  font-size: clamp(11px, 1.55vw, 16px); /* base unit other sizes below are in em of */
}

.overlay-backdrop.is-open .overlay-card {
  transform: scale(1) translateY(0);
  opacity: 1;
}

.overlay-card-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.overlay-close {
  position: absolute;
  top: 4%;
  right: 4%;
  width: 2em;
  height: 2em;
  background: none;
  border: none;
  color: #ffffff;
  font-size: 1.4em;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}

.overlay-heading {
  position: absolute;
  left: 7.6%;
  top: 6.5%;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.3em;
  color: #ffffff; /* the only overlay text that stays white, not gray */
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(20px, 2.6vw, 28px);
}

.overlay-heading-mark {
  width: 0.85em;
  height: auto;
}

.overlay-desc {
  position: absolute;
  left: 7.6%;
  top: 15.6%;
  width: 30.6%;
  margin: 0;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(13px, 1.6vw, 18px);
  line-height: 1.35;
}

/* New label near the ATM, added per the latest reference. */
.overlay-callout-text {
  position: absolute;
  right: 7.6%; /* matches the left margin used for "Problem", the description, and the notes */
  top: 44%;
  width: 24%; /* bounded like every other element here, instead of
                 nowrap — so it wraps instead of overflowing the card if
                 it ever runs out of room, rather than getting cropped */
  text-align: right;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(12px, 1.4vw, 16px);
}

/* Straight arrow into "Check Balance" (assets/images/arrow straight.svg).
   Sized and placed to match the reference exactly: it starts partway
   in (not from the card's left margin) and stops just short of the
   pill. width sets the visual size, height:auto follows its own ratio —
   an image scaled this way (both dimensions moving together) never
   distorts; only forcing width AND height independently would. */
.overlay-arrow {
  position: absolute;
  left: 21.9%;
  top: 39.2%;
  width: 12.5%;
  height: auto;
}

/* The 3 pill rows. Each is its own hand-drawn box file (top/mid/lower
   box) — since the 3 files aren't pixel-identical, their heights differ
   very slightly at the same width, which is fine (matches the hand-drawn
   look) and never distorts any one of them. */
.overlay-pill {
  position: absolute;
  left: 35.8%;
  width: 25.1%;
}

.overlay-pill-1 { top: 33.7%; }
.overlay-pill-2 { top: 47.2%; }
.overlay-pill-3 { top: 62.3%; }

.overlay-pill-bg {
  display: block;
  width: 100%;
  height: auto;
}

.overlay-pill-icon {
  position: absolute;
  left: 8%;
  top: 50%;
  transform: translateY(-50%);
  width: 19%; /* % of the pill's own width, same unit as its "left" and
                 the text's "left" below — so the gap between icon and
                 text stays fixed at every screen size instead of the two
                 scaling independently (which is what caused them to
                 touch) */
  height: auto;
}

.overlay-pill-text {
  position: absolute;
  left: 34%;
  top: 50%;
  transform: translateY(-50%);
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(12px, 1.4vw, 16px);
  white-space: nowrap;
}

/* Connector between pill 1→2 and 2→3 (assets/images/side arrow.svg).
   Sized by height (% of the card, same unit family as everything else
   here) with width:auto, since it's tall and narrow. */
.overlay-connector {
  position: absolute;
  left: 63.3%;
  width: auto;
  height: 8%;
  transform: translateY(-50%);
}

.overlay-connector-1 { top: 44.2%; }
.overlay-connector-2 { top: 60.3%; }

/* Curved arrow from the pills toward the hand/card illustration
   (assets/images/curve arrow.svg). Its top was previously overlapping
   pill 3 — fixed by measuring the actual gap below it in the reference. */
.overlay-bottom-arrow {
  position: absolute;
  left: 49.8%;
  top: 75.9%;
  width: 18.8%;
  height: auto;
}

.overlay-insert-atm {
  position: absolute;
  left: 71%;
  top: 50.75%;
  width: 23%;
  height: auto;
}

.overlay-note {
  position: absolute;
  left: 7.6%; /* matches "Problem" and the description's left edge */
  display: flex;
  align-items: center;
  gap: 0.6em;
}

.overlay-note-1 { top: 78.4%; }
.overlay-note-2 { top: 86.9%; }

.overlay-note-icon {
  width: 3em;
  height: auto;
}

.overlay-note-text {
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(12px, 1.4vw, 16px);
  line-height: 1.3;
  max-width: 9em;
}

/* ---------- Ideation overlay ("Four Plays. One Problem.") ---------- */
/* Uses .overlay-backdrop / .overlay-card / .overlay-close from the
   Problem overlay above — only the aspect ratio changes here, to match
   this card's own art (2 overlay bg.svg, 793 x 668). */
.overlay-card--ideation {
  aspect-ratio: 793 / 668;
  /* this card's own art is squarer than the Problem overlay's (1.19 vs
     1.44 ratio), so at the same 760px width it rendered noticeably
     taller — capping the width tighter here instead, so its on-screen
     footprint (and height) roughly matches the Problem overlay's card
     rather than dominating more of the screen. */
  width: min(625px, 100%);
}

.ideation-heading {
  position: absolute;
  left: 9.15%;
  top: 7.86%;
  margin: 0;
  color: #ffffff;
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(20px, 2.6vw, 28px);
}

.ideation-heading-accent {
  color: var(--color-o2);
}

/* Small curl pointing at the heading, and the longer curve pointing down
   at the ATM — both reuse arrows from the Problem overlay, just rotated
   to roughly match this design's direction. */
.ideation-arrow-heading {
  position: absolute;
  left: 1.5%;
  top: 6.6%;
  width: 6.1%;
  height: auto;
}

.ideation-arrow-atm {
  position: absolute;
  left: 67.6%;
  top: 10.3%;
  width: 8.6%;
  height: auto;
}

.ideation-desc {
  position: absolute;
  left: 9.15%;
  top: 17.5%;
  width: 63%;
  margin: 0;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(13px, 1.6vw, 18px);
  line-height: 1.35;
}

/* The 4 play cards. Each is its own rect file (rect 1-4.svg — rect 4's
   border is already orange in the file, marking it the winning play), so
   heights differ slightly between them just like the Problem overlay's
   pills, matching the hand-drawn look without distorting any of them.
   Clickable (per the "pick a play" line) with a small hover/focus zoom. */
.play-card {
  position: absolute;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  transition: transform 0.2s ease;
}

.play-card:hover,
.play-card:focus-visible {
  transform: scale(1.03);
  z-index: 2;
}

.play-card-1 { left: 8.14%; top: 34.46%; width: 40.18%; aspect-ratio: 321 / 177; }
.play-card-2 { left: 51.37%; top: 34.46%; width: 39.67%; aspect-ratio: 318 / 178; }
.play-card-3 { left: 8.14%; top: 61.67%; width: 40.69%; aspect-ratio: 321 / 189; }
.play-card-4 { left: 51.37%; top: 61.67%; width: 40.18%; aspect-ratio: 318 / 182; }

.play-card-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.play-number {
  position: absolute;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(11px, 1.3vw, 15px);
}

.play-title {
  position: absolute;
  margin: 0;
  color: #ffffff;
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(12px, 1.4vw, 16px); /* matches the Problem overlay's pill text */
  line-height: 1.3;
}

.play-title--bold {
  font-weight: 700;
}

.play-subtitle {
  display: inline-block;
  color: var(--overlay-text-color);
  white-space: nowrap;
}

.play-desc {
  position: absolute;
  margin: 0;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(12px, 1.4vw, 16px); /* matches the Problem overlay's pill text */
  line-height: 1.3;
}

.play-icon {
  position: absolute;
  height: auto;
}

/* Score chip: one shape (chip O.svg) reused for every card, now inlined
   directly as SVG markup and recolored via currentColor — orange by
   default, red only for play 4's low score. This replaced an earlier
   CSS mask-image version: masking a local SVG file is blocked by Chrome
   when the page is opened as a plain file:// document (only works
   through a real server like Live Server), which was invisible during
   my own testing since I was serving over http. Inline SVG has no such
   restriction, so it now works either way. */
.play-chip {
  position: absolute;
  aspect-ratio: 73 / 33;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-o2);
}

.play-chip-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  fill: currentColor;
}

/* The chip art's marker-stroke shape is drawn on a tilt inside its own
   box (not rotated by CSS) — this rotates just the text to follow that
   same tilt, without also rotating (and re-tilting) the shape itself. */
.play-chip-text {
  position: relative;
  display: inline-block;
  transform: rotate(-10deg);
  color: #0d0c0c;
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(10px, 1.2vw, 13px);
}

.play-chip--red {
  color: var(--color-chip-red);
}

/* Per-card positions for number / title / description / icon / chip,
   measured as a percentage of that card's own box (same pattern as the
   Problem overlay's pills), so each stays put regardless of the small
   height differences between the 4 rect files. */
.play-card-1 .play-number  { left: 7.6%;  top: 12.8%; }
.play-card-1 .play-title   { left: 7.6%;  top: 33.3%; width: 48%; }
.play-card-1 .play-icon    { left: 48%;   top: 3%;    width: 34%; }
.play-card-1 .play-chip    { left: 62%;   top: 69%;   width: 25%; }

.play-card-2 .play-number  { left: 5.1%;  top: 13.2%; }
.play-card-2 .play-title   { left: 5.1%;  top: 39.5%; width: 55%; }
.play-card-2 .play-icon    { left: 58%;   top: 3%;    width: 34%; }
.play-card-2 .play-chip    { left: 62%;   top: 69%;   width: 25%; }

.play-card-3 .play-number  { left: 7.5%;  top: 14.9%; }
.play-card-3 .play-title   { left: 7.5%;  top: 31.9%; width: 55%; }
.play-card-3 .play-desc    { left: 7.5%;  top: 48.9%; width: 55%; }
.play-card-3 .play-icon    { left: 56%;   top: 8%;    width: 34%; }
.play-card-3 .play-chip    { left: 62%;   top: 62%;   width: 25%; }

.play-card-4 .play-number  { left: 5.1%;  top: 15.6%; }
.play-card-4 .play-title   { left: 5.1%;  top: 40%;   width: 55%; }
.play-card-4 .play-icon    { left: 59%;   top: 4%;    width: 34%; }
.play-card-4 .play-chip    { left: 62%;   top: 64%;   width: 25%; }

/* ---------- Ideation detail view (play 01) ---------- */
/* Shares .overlay-card--ideation with the grid view above; script.js
   toggles the "hidden" attribute on .ideation-view--grid /
   .ideation-view--detail to switch between them. Positions below are
   measured the same way as the grid: % of the card. */

.ideation-back {
  position: absolute;
  left: 3%;
  top: 3.7%; /* back button's own box is shorter than the close button's
                (27px vs 44.8px at max card size), so matching top:2% left
                their tops flush but centers off by ~9px; this value
                centers the back button on the close button's vertical
                center instead */
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.5em;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: #ffffff;
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(13px, 1.5vw, 17px);
  opacity: 0.9;
  transition: opacity 0.2s ease;
}

.ideation-back:hover,
.ideation-back:focus-visible {
  opacity: 1;
}

.ideation-back img {
  width: 1.3em;
  height: auto;
}

/* The close button is a sibling of both views, not nested inside either
   one — ".ideation-view--detail .overlay-close" (used here previously)
   never matched anything for that reason, so that fix silently did
   nothing. script.js toggles "showing-detail" on the card instead, which
   this can actually target. Value matches .ideation-back's own top
   exactly, so the two align. */
.overlay-card--ideation.showing-detail .overlay-close {
  top: 2%;
}

.detail-frame {
  position: absolute;
  left: 5.6%;  /* (100% - 88.8% width) / 2, so left and right margins match */
  top: 12%;    /* was 8%, then 15% (too far down toward the footer) — net
                  +4% now, still as one unit with the rest of the block */
  width: 88.8%;
  height: auto;
}

.detail-illustration {
  position: absolute;
  left: 12%;
  top: 22.3%;
  width: 29.6%;
  height: auto;
}

/* D2 icon.svg is a wider/shorter shape (280x195) than D1 icon.svg's more
   square 252x233, so the same width left it visibly smaller. Scaled up
   so both cover about the same on-screen area, keeping left/top as-is
   (it just grows a bit further right and down, still clear of the
   heading column, which starts at 49%). */
.ideation-view--detail[data-view="detail-2"] .detail-illustration {
  width: 34%;
}

.detail-heading {
  position: absolute;
  left: 49%;
  top: 18.5%;
  width: 46%; /* keeps it from running past the frame's (now symmetric) right edge */
  margin: 0;
  white-space: nowrap; /* stays on one line, matching the reference, instead of wrapping and overlapping the description below it */
  color: #ffffff;
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(14px, 1.7vw, 19px);
}

.detail-desc {
  position: absolute;
  left: 49%;
  top: 27%;
  width: 41%;
  margin: 0;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(12px, 1.3vw, 15px);
  line-height: 1.4;
}

.detail-line {
  position: absolute;
  left: 49%;
  top: 43%;
  width: 29.6%;
  height: auto;
}

.detail-note {
  position: absolute;
  left: 49%;
  top: 47.5%;
  width: 38%;
  margin: 0;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(12px, 1.3vw, 15px);
  line-height: 1.4;
}

/* Play 03 swaps the single-paragraph .detail-note for a "Why It Works"
   heading plus a short checklist instead — measured from that reference
   image the same way as everything else here (% of the card). */
.detail-why-heading {
  position: absolute;
  left: 49%;
  top: 44.5%;
  margin: 0;
  color: #ffffff;
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: 16px;
}

.detail-check {
  position: absolute;
  left: 49%;
  display: flex;
  align-items: center;
  gap: 0.5em;
  margin: 0;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(12px, 1.3vw, 15px);
}

/* Squeezed into the same gap the single-line .detail-note used to fill
   (between the divider at 43% and the nav row starting at 67.8%) - this
   reference had 3 lines instead of 1, so the rows sit closer together
   than the heading's own top gap. */
.detail-check-1 { top: 49%; }
.detail-check-2 { top: 53%; }
.detail-check-3 { top: 57%; }

.detail-check-mark {
  color: #2ba12f;
  font-weight: 700;
}

/* The 3 mini nav cards. Clickable (per plays 2-4 eventually getting
   their own detail views) with a hover zoom for now, same pattern as
   the grid's play cards — but no click behavior yet, since their
   content/format hasn't been decided. */
.detail-nav {
  position: absolute;
  top: 67.8%;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: transform 0.2s ease;
}

.detail-nav:hover,
.detail-nav:focus-visible {
  transform: scale(1.03);
  z-index: 2;
}

/* Equal width and a single shared aspect-ratio for all 3 (they previously
   used each SVG's own native ratio — 1.90 / 1.87 / 1.81 — which combined
   with mismatched widths made card 03 visibly narrower than 02 and 04).
   Row margins (5.6% each side) match the D1 frame above, instead of
   nearly touching both edges. */
/* Now 4 boxes (01 was added, joining 02-04), so the math changed:
   4 equal boxes + 3 gaps within the same 5.6% side margins as before. */
.detail-nav-1 { left: 5.6%;  width: 20.7%; aspect-ratio: 215 / 115; height: auto; }
.detail-nav-2 { left: 28.3%; width: 20.7%; aspect-ratio: 215 / 115; height: auto; }
.detail-nav-3 { left: 51%;   width: 20.7%; aspect-ratio: 215 / 115; height: auto; }
.detail-nav-4 { left: 73.7%; width: 20.7%; aspect-ratio: 215 / 115; height: auto; }

.detail-nav-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.detail-nav-number {
  position: absolute;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(9px, 1.1vw, 12px); /* 4 boxes are shorter than the
    previous 3 (same margins, less width each), so text is sized down to
    keep fitting rather than distorting the box art to be taller */
}

.detail-nav-number--accent {
  color: var(--color-o2);
}

.detail-nav-title {
  position: absolute;
  color: var(--overlay-text-color); /* matches .detail-note's gray */
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.2;
}

.detail-nav-title--accent {
  color: var(--color-o2);
}

.detail-nav-icon {
  position: absolute;
  height: auto;
}

/* Number, title, and icon now use the same top/left recipe on all 3
   cards (they didn't before — that inconsistency, not the card art, was
   what made card 04 look cramped/misaligned against 02 and 03). Only
   left/width for the icon and title vary slightly per card to account
   for each card's own width and icon shape. */
.detail-nav-1 .detail-nav-number { left: 5%;   top: 15%; }
.detail-nav-1 .detail-nav-title  { left: 5%;   top: 45%; width: 58%; }
.detail-nav-1 .detail-nav-icon   { left: 66%;  top: 13%; width: 17%; }

.detail-nav-2 .detail-nav-number { left: 5%;   top: 15%; }
.detail-nav-2 .detail-nav-title  { left: 5%;   top: 45%; width: 58%; }
.detail-nav-2 .detail-nav-icon   { left: 66%;  top: 13%; width: 17%; }

.detail-nav-3 .detail-nav-number { left: 5%;   top: 15%; }
.detail-nav-3 .detail-nav-title  { left: 5%;   top: 45%; width: 55%; }
.detail-nav-3 .detail-nav-icon   { left: 64%;  top: 13%; width: 20%; }

.detail-nav-4 .detail-nav-number { left: 5%;   top: 15%; }
.detail-nav-4 .detail-nav-title  { left: 5%;   top: 45%; width: 90%; }
.detail-nav-4 .detail-nav-icon   { left: 63%;  top: 13%; width: 17%; }

.detail-footer-text {
  position: absolute;
  left: 5.6%; /* matches the frame/nav-row left margin, instead of 1.5% */
  top: 88%;   /* vertically centered against the CTA button below/beside it */
  margin: 0;
  color: var(--overlay-text-color);
  font-family: var(--overlay-font);
  font-weight: 400;
  font-size: clamp(12px, 1.4vw, 16px);
}

/* Winning-play CTA: destination still to be decided, so it's not wired
   to anything yet — just the hover state and a gentle recurring "pop"
   to draw the eye, same spirit as the pulsing callout buttons on the
   scene. Hover uses brightness rather than an extra transform, so it
   doesn't fight with the animation's own scale. */
.detail-winning-cta {
  position: absolute;
  left: 64%;   /* was 62% — gives clearer margin from the footer text on
                  the left, and from the card's right edge (right edge
                  now 90%, matching the nav row's own margin better) */
  top: 87%;    /* vertically centered against the footer text beside it */
  width: 26%;  /* was 24% — narrowing this (to 22%) wrapped the text to
                  2 lines, which then overflowed above/below the pill
                  shape since the text box no longer matched it */
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  animation: detail-winning-pop 2.2s ease-in-out infinite;
}

.detail-winning-cta:hover,
.detail-winning-cta:focus-visible {
  filter: brightness(1.15);
}

.detail-winning-cta-bg {
  display: block;
  width: 100%;
  height: auto;
}

.detail-winning-cta-text {
  position: absolute;
  inset: 18% 5%; /* was inset:0 — text filled the whole pill with no
                    breathing room. 12% horizontal wrapped the text to 2
                    lines (too narrow), so this uses less side inset and
                    more top/bottom, plus a smaller font, to keep it on
                    one line while still sitting clear of the edges */
  display: flex;
  align-items: center;
  justify-content: center;
  color: #0d0c0c;
  font-family: var(--overlay-font);
  font-weight: 700;
  font-size: clamp(10px, 1.15vw, 13px);
}

@keyframes detail-winning-pop {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
  .detail-winning-cta {
    animation: none;
  }
}

/* ---------- Responsive ---------- */
/* On tablets and phones the left menu would cover the scene, so it becomes
   a bar above the image. The image and the girl keep the same percentage
   positions, so they stay aligned at every width. */
@media (max-width: 900px) {
  :root {
    --nav-text: #ffffff;
  }

  .side-menu {
    position: static;
    width: 100%;
    padding: 16px;
    gap: 8px;
    background: #040405;
    text-shadow: none;
  }

  .logo-line-1,
  .logo-line-2 {
    font-size: 1.1rem;
  }

  .menu-links {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 8px 20px;
    font-size: 0.9rem;
  }
}

/* Narrow phones: the callout shrinks to just the "+" icon, so it doesn't
   crowd the small scene. */
@media (max-width: 480px) {
  .atm-callout-icon-halo {
    margin-right: 0;
  }

  .atm-callout-pill {
    display: none;
  }
}

/* Narrow phones: the Problem overlay switches from exact positions on
   the hand-drawn card art to a plain panel where everything stacks
   normally, top to bottom. Tested down to real 500px-wide screens, the
   art-positioned version above holds up fine; only below that does the
   card get too narrow for the description/pills/circle to avoid
   overlapping, so this is where it switches over. */
@media (max-width: 520px) {
  .overlay-card {
    width: 100%;
    max-width: 380px;
    aspect-ratio: unset;
    max-height: 88vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 22px 18px;
    background: #0d1620;
    border: 2px solid var(--color-o);
    border-radius: 18px;
    font-size: 14px;
  }

  /* the hand-drawn card art and the connectors/arrows that were tuned to
     exact spots on it no longer apply once content flows normally */
  .overlay-card-bg,
  .overlay-arrow,
  .overlay-connector,
  .overlay-bottom-arrow {
    display: none;
  }

  .overlay-close {
    top: 10px;
    right: 10px;
  }

  .overlay-heading,
  .overlay-desc,
  .overlay-callout-text,
  .overlay-pill,
  .overlay-insert-atm,
  .overlay-note {
    position: static;
    left: auto;
    top: auto;
    width: auto;
    transform: none;
  }

  .overlay-heading {
    font-size: 22px;
  }

  .overlay-callout-text {
    order: 5; /* moves it visually next to the illustration, after the pills */
    text-align: center;
    font-size: 13px;
  }

  .overlay-pill {
    display: flex;
    align-items: center;
    gap: 10px;
    border: 2px solid rgba(255, 255, 255, 0.5);
    border-radius: 999px;
    padding: 10px 16px;
  }

  .overlay-pill-bg {
    display: none; /* using a plain CSS border here instead, so it can never stretch at a height the art wasn't drawn for */
  }

  .overlay-pill-icon,
  .overlay-pill-text {
    position: static;
    transform: none;
  }

  .overlay-pill-text {
    font-size: 14px;
  }

  .overlay-insert-atm {
    width: 130px;
    margin: 4px auto 0;
    display: block;
  }

  .overlay-note {
    align-items: flex-start;
  }

  .overlay-note-text {
    font-size: 13px;
  }

  /* ---- Ideation overlay: same idea, applied to its own elements ---- */
  .overlay-card--ideation {
    width: 100%;
    max-width: 380px;
    aspect-ratio: unset;
    max-height: 88vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 22px 18px;
    background: #0d1620;
    border: 2px solid var(--color-o2);
    border-radius: 18px;
    font-size: 14px;
  }

  /* the card art and the 2 decorative arrows were tuned to exact spots
     on it, so they no longer apply once content flows normally */
  .overlay-card--ideation .overlay-card-bg,
  .ideation-arrow-heading,
  .ideation-arrow-atm {
    display: none;
  }

  .ideation-heading,
  .ideation-desc {
    position: static;
    left: auto;
    top: auto;
    width: auto;
  }

  .ideation-heading {
    font-size: 20px;
    padding-right: 28px; /* clears the close button at very narrow widths */
  }

  /* The 4 x rect-art positioned cards become a single stacked column of
     plain bordered cards (rect 3's file-baked orange border is replaced
     here with the same color via CSS, since the art itself is hidden). */
  .play-card {
    position: static;
    left: auto;
    top: auto;
    width: 100%;
    aspect-ratio: unset;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 14px 16px;
    border: 2px solid rgba(255, 255, 255, 0.4);
    border-radius: 14px;
  }

  .play-card-3 {
    border-color: var(--color-o2);
  }

  .play-card-bg {
    display: none; /* plain CSS border above instead, so it can't stretch at a height the art wasn't drawn for */
  }

  .play-number,
  .play-title,
  .play-desc,
  .play-icon,
  .play-chip {
    position: static;
    left: auto;
    top: auto;
    width: auto;
    transform: none;
  }

  .play-title {
    order: 1;
  }

  .play-desc {
    order: 2;
  }

  .play-icon {
    order: 3;
    width: 56px;
    align-self: flex-start;
  }

  /* Qualified with .overlay-card--ideation so this ties (rather than
     loses) on specificity with the desktop ".play-card-1 .play-chip"
     etc. rules, which otherwise still win for left/top/width — the
     grouped reset above is a single class and loses that fight. That
     was invisible for the other elements (position:static makes left/
     top no-ops regardless of who "wins"), but .play-chip needs
     position:relative for its inline SVG child, which does honor
     left/top, so the leftover desktop offset was actually moving it. */
  .overlay-card--ideation .play-chip {
    position: relative;
    left: auto;
    top: auto;
    order: 4;
    align-self: flex-end;
    width: 90px;
  }
}
