/* ==========================================================
   ACT 3: AT THE CLINIC, THEN HOME
   Callie and Tay: A Story About Heat Stroke in Dogs

   Built to docs/design-language.md §9. Same 16:9 viewport card, same HUD pill and button
   geometry, same speech-bubble components as Acts 0–2, so the module reads as one piece.

   WHAT CHANGES HERE is the direction of travel. Act 1's HUD was warm and playful; Act 2's
   was cooled and clinical because the learner had gone outside the dog. Act 3 runs that
   backwards: it opens at Act 2's drained saturation under a cool clinical wash, and warms
   continuously back to full colour as Tay recovers — the Visual Asset Brief's
   "saturation returns at recovery in Act 3", carried on one custom property
   (--act3-saturation) rather than switched at a beat boundary.

   Every colour in this file comes from css/main.css. No new literals.
   ========================================================== */

.act3-container {
  position: relative;
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at 50% 30%, #FFFDFB 0%, var(--palette-peach-light) 65%, var(--palette-peach) 100%);
  padding: 1rem;
  box-sizing: border-box;
  overflow: hidden;
  min-height: 0;
}

/* Geometry matched to .act1-viewport-card / .act2-viewport-card.
   `isolation: isolate` keeps this screen's z-index scale (10 / 20 / 30 / 40 / 50) local, so
   it can never end up in an arms race with the Edit Mode chrome layered above the stage. */
.act3-viewport-card {
  position: relative;
  isolation: isolate;
  width: min(94vw, 1300px);
  aspect-ratio: 16 / 9;
  max-height: 84vh;
  border-radius: var(--radius-xl);
  overflow: hidden;
  min-height: 0;
  box-shadow: var(--elev-card);
  border: 4px solid var(--palette-warm-white);
  background: var(--surface-card-dark);
  user-select: none;
}

.act3-scene-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
  z-index: 10;
  /* Recovery ramp. 54% at the clinic door, 100% by the time she is climbing Callie. */
  filter: saturate(var(--act3-saturation, 100%));
  transition: filter var(--dur-escalation) ease;
}


/* ==========================================================
   CAST LAYER
   ========================================================== */
.act3-cast {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 11; /* Above scene image, below wash */
}


.act3-cast-img {
  opacity: 0;
}
.act3-cast-img.is-active {
  opacity: 1;
}
.act3-cast-img {
  position: absolute;
  height: auto;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
  filter: drop-shadow(0 14px 28px rgba(24, 20, 18, 0.35));
  transition: opacity 0.18s ease;
}

.act3-cast-callie {
  bottom: 4.4%;
}
.act3-cast-callie.is-state-relief { height: 50%; }
.act3-cast-callie.is-state-waiting { height: 31%; left: 3%; bottom: 17%; }
.act3-cast-callie.is-state-leaving, .act3-cast-callie.is-state-turned { right: 30%; left: auto; height: 50%; }
/* "One more thing." — she has turned around to face Reyes. */
.act3-cast-callie.is-state-turned { transform: scaleX(-1); }
.act3-cast-callie.is-state-handover { right: 31%; left: auto; height: 52%; } /* her own chair, clear of the one against the wall */
.act3-cast-callie.is-state-floor { height: 34%; }

[data-beat="verdict"] .act3-cast-callie.is-state-relief,
[data-beat="report"] .act3-cast-callie { left: 28%; }
[data-beat="tayReturn"] .act3-cast-callie,
[data-beat="nextTime"] .act3-cast-callie { left: 12%; }

.act3-cast-tay {
  bottom: 3%;
  height: 22%;
  /* Tay's Act 1 art faces right; in the treatment room she faces Callie on the left. */
  transform: scaleX(-1);
}
[data-beat="tayReturn"] .act3-cast-tay,
[data-beat="nextTime"] .act3-cast-tay { left: 36%; }
.act3-cast-tay.is-state-leading { right: 18%; left: auto; transform: none; }
.act3-cast-tay.is-state-turned { right: 18%; left: auto; }

.act3-cast-reyes {
  bottom: 4.4%;
  height: 52%;
  /* Reyes's art faces left. Whenever she stands to Callie's LEFT she is flipped so she is
     still facing the person she is talking to. */
  --act3-reyes-flip: 1;
  transform: scaleX(var(--act3-reyes-flip));
}
[data-beat="verdict"] .act3-cast-reyes,
[data-beat="report"] .act3-cast-reyes,
[data-beat="tayReturn"] .act3-cast-reyes,
[data-beat="nextTime"] .act3-cast-reyes { right: 26%; }
.act3-cast-reyes.is-state-aside { right: 52%; --act3-reyes-flip: -1; }
.is-entering[data-beat="verdict"] .act3-cast-reyes.is-active {
  animation: act3ReyesSlide 0.35s var(--ease-out-expo) forwards;
}

@keyframes act3ReyesSlide {
  from { transform: translateX(20px) scaleX(var(--act3-reyes-flip, 1)); }
  to { transform: translateX(0) scaleX(var(--act3-reyes-flip, 1)); }
}

/* ==========================================================
   LIGHT WASH
   One element, three moods. Never a decorative gradient on a character — this is ambient
   room light over a whole scene, which is what the asset brief specifies for each location.
   ========================================================== */

.act3-wash {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 12;
  transition: opacity var(--dur-escalation) ease-in-out;
}

/* Clinic: fluorescent, cold, slightly drained. Fades out as she recovers. */
.act3-wash.wash-clinical {
  background:
    linear-gradient(to bottom, rgba(148, 163, 184, 0.35) 0%, rgba(148, 163, 184, 0.12) 46%, transparent 100%),
    radial-gradient(circle at 76% 42%, rgba(186, 230, 253, 0.28) 0%, transparent 60%);
  opacity: var(--act3-cool-opacity, 0.42);
  mix-blend-mode: multiply;
}

/* Exam room: nothing on top of it. She is fine and the room is allowed to look it. */
.act3-wash.wash-clear {
  opacity: 0;
}

/* That evening. Warm, low, and dim at the edges — the Act 0 room after dark. */
.act3-wash.wash-evening {
  background:
    radial-gradient(circle at 30% 42%, rgba(255, 214, 150, 0.55) 0%, rgba(180, 102, 60, 0.5) 38%, rgba(64, 44, 60, 0.72) 100%),
    linear-gradient(to bottom, rgba(40, 30, 52, 0.45) 0%, rgba(58, 38, 44, 0.2) 42%, rgba(28, 20, 36, 0.6) 100%);
  opacity: 1;
  mix-blend-mode: multiply;
}

/* A second pass in screen mode puts the lamp back, so the room goes dim rather than muddy. */
.act3-wash.wash-evening::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 26% 46%, rgba(255, 196, 128, 0.3) 0%, transparent 52%);
  mix-blend-mode: screen;
}

/* ==========================================================
   HUD — TOP BAR (geometry matched to .act2-hud-bar)
   ========================================================== */

.act3-hud-bar {
  position: absolute;
  top: 1.25rem;
  left: 1.5rem;
  right: 1.5rem;
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  pointer-events: none;
  z-index: 40;
}

.act3-nav-bar {
  position: absolute;
  bottom: 1.25rem;
  left: 1.5rem;
  right: 1.5rem;
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  pointer-events: none;
  z-index: 40;
}

.act3-hud-group {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  pointer-events: auto;
}

.act3-hud-pill {
  background: var(--surface-hud);
  backdrop-filter: blur(10px);
  color: var(--text-inverse);
  border: 1.5px solid var(--hairline-light);
  font-family: var(--font-family-display);
  font-size: 0.88rem;
  font-weight: 700;
  height: 38px;
  padding: 0 1rem;
  border-radius: var(--radius-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  box-shadow: var(--elev-3);
  box-sizing: border-box;
}



.act3-hud-pill.clock-pill {
  background: var(--surface-clock);
  border-color: var(--color-amber-tint);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}

/* Tay's status. §6.1: a pill that changes state changes its TEXT — IN BACK → STABLE →
   GOING HOME is the real signal, and the colour is only reinforcement. */
.act3-hud-pill.status-pill {
  font-weight: 800;
  letter-spacing: 0.04em;
  transition: background-color var(--dur-base) var(--ease-out-expo),
              border-color var(--dur-base) var(--ease-out-expo);
}

/* Unresolved. Deliberately neutral slate, not amber and not red — the clinic does not know
   anything yet and the interface must not pretend to. This is Beat 3A's whole engine. */
.act3-hud-pill.status-pill.tone-unknown {
  background: var(--surface-clock);
  border-color: var(--hairline-light);
  color: var(--text-on-dark-muted);
}

.act3-hud-pill.status-pill.tone-stable,
.act3-hud-pill.status-pill.tone-home {
  background: var(--color-success);
  border-color: var(--color-success-pale);
  color: var(--text-inverse);
}


/* ==========================================================
   BUTTONS (geometry matched to .act2-hud-btn)
   ========================================================== */

.act3-hud-btn {
  background: var(--surface-hud-btn);
  backdrop-filter: blur(8px);
  color: var(--text-inverse);
  border: 1.5px solid var(--hairline-light);
  font-family: var(--font-family-display);
  font-size: 0.92rem;
  font-weight: 700;
  height: 40px;
  padding: 0 1.2rem;
  border-radius: var(--radius-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  box-sizing: border-box;
  box-shadow: var(--elev-2);
  pointer-events: auto;
  transition: background-color var(--dur-fast) var(--ease-out-expo),
              border-color var(--dur-fast) var(--ease-out-expo),
              opacity var(--dur-fast) var(--ease-out-expo),
              transform var(--dur-fast) var(--ease-out-expo);
}

.act3-hud-btn:hover:not(:disabled),
.act3-hud-btn:focus-visible:not(:disabled) {
  background: var(--surface-hud-btn-hover);
  border-color: var(--hairline-light-strong);
  transform: translateY(-2px);
}

.act3-hud-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* The way out of Beat 3A. Present and focusable from the first frame — a deliberate wait
   is fine, a trap is not (design-language.md §7.5, and Nielsen's user control heuristic). */
.act3-hud-btn.act3-btn-quiet {
  height: 36px;
  font-size: 0.82rem;
  font-weight: 600;
  border: 1px solid var(--hairline-light-soft);
  box-shadow: var(--elev-1);
  white-space: nowrap;
  min-width: 5rem;
}

.act3-hud-btn.btn-action-primary {
  /* --color-heat, NOT --color-heat-bright: white on #EA580C is 3.56 and fails AA. */
  background: var(--color-heat);
  color: var(--text-inverse);
  border: 2px solid var(--color-amber-tint);
  font-weight: 800;
  box-shadow: 0 6px 20px rgba(194, 65, 12, 0.4);
}

.act3-hud-btn.btn-action-primary:hover:not(:disabled),
.act3-hud-btn.btn-action-primary:focus-visible:not(:disabled) {
  background: var(--color-heat-hover);
  border-color: var(--palette-warm-white);
  transform: translateY(-2px);
}

.act3-hud-btn.btn-action-primary.pulse-btn {
  animation: act3PulseBtn 1.8s infinite;
}

/* An invitation, not decoration (§5.2): it says "this is the control that continues the
   story". Elevation only — no coloured halo. */
@keyframes act3PulseBtn {
  0%, 100% { box-shadow: 0 6px 20px rgba(194, 65, 12, 0.4); }
  50% { box-shadow: 0 6px 28px rgba(194, 65, 12, 0.7); }
}

/* Focus rings, by ground (§7.2). Amber over the scene and the dark case file; teal on the
   cream cards. Offset stays at 3px so the ring is never clipped by the card's overflow. */
#screen-act3 button:focus-visible,
#screen-act3 [role="button"]:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-on-dark);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-sm);
}

#screen-act3 .act3-prevention-card button:focus-visible,
#screen-act3 .act3-end-card button:focus-visible,
#screen-act3 .act3-wait-panel button:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-on-light);
  outline-offset: var(--focus-ring-offset);
}

/* ==========================================================
   SPEECH LAYER
   ========================================================== */

.act3-speech-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 30;
}

/* A modal's z-index is only ever local to this layer (that is the point of keeping the scale
   contained). When the layer holds a scrimmed dialog it has to out-rank the HUD itself, or
   the chrome draws over the dialog and stays visually live while it is inert. */
.act3-speech-layer.has-modal {
  z-index: 45;
}

/* Transparent grouping element only — it must not become a layout or hit-testing box. */
.act3-recheck-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* --- Dr. Reyes's bubble ------------------------------------------------
   The third speaking voice in the module. §1.3 reserves warm/ember for Tay and
   white-with-brown-ink for Callie, and keeps dark-slate-and-amber for the truth stamp — a
   voice with no person attached. Reyes is a person in the room, so she keeps Callie's white
   ground and takes the cool/ink family's teal: teal-dark border and ink, info-blue speaker
   label. With the sound off and the text blurred she is still identifiable, which is the
   test §1.3 sets.

   Contrast: #244952 on #FFFFFF = 9.77 (text and border); #0369A1 on #FFFFFF = 5.93 (label).

   Her stem reads --stem-left, because Edit Mode writes --stem-left for every bubble that is
   not .callie-bubble (§8.2) — a variant that hardcoded `left` here would silently swallow
   the author's saved stem position. */
.speech-bubble.reyes-bubble {
  background: var(--palette-warm-white);
  border: 3px solid var(--palette-teal-dark);
  color: var(--palette-teal-dark);
}

.speech-bubble.reyes-bubble .speech-bubble-speaker {
  color: var(--color-info-strong);
}

#screen-act3 .speech-bubble .speech-bubble-speaker {
  flex-wrap: wrap;
  row-gap: 0.25rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* The report footer's byline is a single inline run — no wrapping there. */
.act3-recap-who .act3-business,
.act3-prevention-reply .act3-business {
  flex: none;
}

.speech-bubble.reyes-bubble .act3-reyes-dialogue {
  color: var(--palette-teal-dark);
}

.speech-bubble.reyes-bubble::before {
  content: '';
  position: absolute;
  bottom: -22px;
  left: var(--stem-left, 24px);
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 18px solid transparent;
  border-top: 22px solid var(--palette-teal-dark);
  z-index: 1;
}

.speech-bubble.reyes-bubble::after {
  content: '';
  position: absolute;
  bottom: -18px;
  left: calc(var(--stem-left, 24px) + 2px);
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 15px solid transparent;
  border-top: 19px solid var(--palette-warm-white);
  z-index: 2;
}

/* Her stage direction, riding the speaker label. She is never standing still and reciting. */
.act3-business {
  flex: 1 1 100%;
  font-family: var(--font-family-body);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-transform: none;
  font-style: italic;
  color: var(--palette-text-muted);
}

/* Bubble placement, per room. Positioned with left/top/right so Edit Mode's !important
   overrides land on properties that actually move the element (§8.2), and the stem offsets
   are custom properties for the same reason. */
/* Bubbles live in the band between the HUD and the cast's heads (13%–44% of the stage),
   so no face is ever covered. Each stem leans toward its speaker: Callie stands left of
   centre, so her bubble hangs to her upper right and the stem points back down-left; Reyes
   stands by the door, so hers hangs to her upper left and the stem points down-right; Tay
   is centred under hers. */
/* Bubbles never scroll: they grow to fit the line (the learner should never have to scroll
   dialogue). No overflow clipping either, or the stem below the box is cut off. Widths are
   set per speaker below so the longest lines still end above the heads. */
#screen-act3 .speech-bubble {
  top: 13%;
  overflow: visible;
}

/* Stems face the speaker. Each bubble is anchored by the edge NEAREST its speaker, with
   the stem at that end leaning in, so the tip lands over the speaker's head (tip = 34px in
   from the anchored edge for the base stems). Head positions per beat were measured at
   1440x900 (percent of the card width) and are noted beside each rule.
   - Bubble up-LEFT of the speaker: right-anchored, base Callie stem (right end, leans right).
   - Bubble up-RIGHT of the speaker: left-anchored, base Tay stem (left end, leans left).
   Long lines grow away from the speaker, never over them. */

/* Callie: up-left of her, stem on the right leaning right (the §6.3 base stem). */
.scene-clinic .act3-callie-bubble,
.scene-home .act3-callie-bubble {
  left: auto;
  right: 61%;            /* verdict / report: her head at ~36.4% */
  max-width: 34%;
  --stem-right: 28px;
}
[data-beat="tayReturn"] .act3-callie-bubble { right: 75.3%; max-width: 23%; }   /* on the floor, head ~22.1% */
[data-beat="nextTime"] .act3-callie-bubble { right: 76.9%; max-width: 22%; }    /* head ~20.5% */
.scene-home .act3-callie-bubble { right: 69%; max-width: 26%; }                 /* clear of her hair; she is to the right */

/* Dr. Reyes: up-left of her too (the room opens that way), so her stem mirrors the base:
   on the right end, leaning right. */
.scene-clinic .act3-reyes-bubble {
  left: auto;
  right: 26.4%;          /* verdict: her head at ~71% */
  max-width: 34%;
  --stem-left: calc(100% - 52px);
}
.scene-clinic .act3-reyes-bubble::before {
  border-left: 18px solid transparent;
  border-right: 6px solid transparent;
}
.scene-clinic .act3-reyes-bubble::after {
  border-left: 15px solid transparent;
  border-right: 5px solid transparent;
}
[data-beat="report"] .act3-reyes-bubble,
[data-beat="nextTime"] .act3-reyes-bubble { right: 28%; }       /* head ~69.4% */
[data-beat="tayReturn"] .act3-reyes-bubble { right: 28.9%; }    /* head ~68.5% */

/* Tay: up-right of her, stem on the left leaning left (the §6.3 base stem). */
.scene-clinic .act3-tay-bubble {
  left: 39.5%;           /* tayReturn: her head at ~41.8% */
  right: auto;
  max-width: 23%;        /* stops short of Dr. Reyes (from ~64%) */
  --stem-left: 24px;
}
.scene-home .act3-tay-bubble {
  left: 56%;             /* just right of her face (~52%) on the couch */
  right: auto;
  max-width: 30%;
  --stem-left: 24px;
}

/* While the discharge sheet is up it fills the left of the room, so Dr. Reyes's bubble
   moves to her upper RIGHT (head ~40% in the handing-over pose), with the base stem on its
   left end leaning left, down to her. */
#act3-card:has(.act3-discharge-sheet) .act3-reyes-bubble {
  right: auto;
  left: 37.7%;
  max-width: 32%;
  --stem-left: 24px;
}
#act3-card:has(.act3-discharge-sheet) .act3-reyes-bubble::before {
  border-left: 6px solid transparent;
  border-right: 18px solid transparent;
}
#act3-card:has(.act3-discharge-sheet) .act3-reyes-bubble::after {
  border-left: 5px solid transparent;
  border-right: 15px solid transparent;
}

/* The recheck swaps sides: Reyes is left of centre (~42.5%), Callie right (~61%). */
[data-beat="recheck"] .act3-reyes-bubble { right: 54.9%; }
[data-beat="recheck"] .act3-callie-bubble {
  right: auto;
  left: 58.7%;
  --stem-right: calc(100% - 48px);   /* stem at the LEFT end... */
}
[data-beat="recheck"] .act3-callie-bubble::before {   /* ...leaning left, toward her */
  border-left: 6px solid transparent;
  border-right: 18px solid transparent;
}
[data-beat="recheck"] .act3-callie-bubble::after {
  border-left: 4px solid transparent;
  border-right: 15px solid transparent;
}

/* The Act 0 callback. Written for the learner — recognition is the payoff, so it names
   where they heard the line, not the shot number. Same component as Act 2's line tag. */

/* ==========================================================
   STAGE / HOLD CARDS
   The unspoken beats. Dark slate so they read as "the film", not as somebody talking.
   ========================================================== */

.act3-stage-card,
.act3-hold-card,
.act3-door-card {
  position: absolute;
  bottom: max(4rem, 22%);
  left: 50%;
  width: min(680px, 76%);
  transform: translateX(-50%);
  background: var(--surface-stamp);
  backdrop-filter: blur(8px);
  border: 1px solid var(--hairline-light-soft);
  border-radius: var(--radius-sm);
  padding: 0.75rem 1.25rem;
  box-shadow: var(--elev-4);
  pointer-events: auto;
}

.is-entering .act3-stage-card,
.is-entering .act3-hold-card,
.is-entering .act3-door-card {
  animation: act3SlideUpX 0.35s var(--ease-out-expo) forwards;
}

.act3-stage-card {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
}

.act3-stage-mark {
  color: var(--color-amber-tint);
  font-size: 0.8rem;
  flex-shrink: 0;
}

.act3-stage-line {
  font-family: var(--font-family-body);
  font-size: clamp(0.86rem, 1.1vw, 0.98rem);
  line-height: 1.5;
  color: var(--text-on-dark);
  font-style: italic;
}

.act3-hold-card {
  border-left: 4px solid var(--color-amber);
  text-align: center;
}

.act3-hold-line {
  font-family: var(--font-family-display);
  font-size: clamp(1rem, 1.3vw, 1.16rem);
  font-weight: 700;
  color: var(--text-on-dark);
}

.act3-hold-sub {
  margin-top: 0.25rem;
  font-family: var(--font-family-body);
  font-size: 0.84rem;
  line-height: 1.45;
  color: var(--text-on-dark-dim);
}

.act3-door-card {
  border-left: 4px solid var(--color-success-pale);
  text-align: center;
}

.act3-door-line {
  font-family: var(--font-family-display);
  font-size: clamp(1.05rem, 1.5vw, 1.35rem);
  font-weight: 800;
  letter-spacing: 0.01em;
  color: var(--text-on-dark);
}

/* ==========================================================
   BEAT 3A — THE WAIT
   Twelve seconds of nothing, which is what makes the vet's entrance land. Nothing here
   teaches, nothing here is scored, and the only control does nothing at all.
   ========================================================== */

/* Anchored right, not centred: Callie owns the left of the frame for the whole
   beat, and the copy sits beside her instead of on top of her. No transform of its own, so
   its entrance keyframe must not carry one either (§6.4). */






.act3-wait-sub {
  margin-top: 0.5rem;
  font-family: var(--font-family-display);
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--palette-text-muted);
}


/* Not a loading bar — a wait, shown honestly so it does not read as a hang. It is
   aria-hidden because the skip control in the nav is the accessible way past it. */




/* ==========================================================
   TRUTH STAMP — the flat third voice (§6.5)
   One measurement, one sentence, no argument. Four of them in this act, and every one is
   attached to something Callie did.
   ========================================================== */

.act3-truth-stamp {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: var(--surface-stamp);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(245, 158, 11, 0.5);
  border-left: 4px solid var(--color-amber);
  border-radius: var(--radius-sm);
  padding: 0.5rem 1rem;
  box-shadow: var(--elev-5);
  pointer-events: auto;
}

/* The measurement. --color-amber-pale on --color-amber-deep is 4.51 — it passes by 0.01,
   so neither value may be nudged (Appendix A watch list). */
.act3-truth-stamp-metric {
  flex-shrink: 0;
  background: var(--color-amber-deep);
  color: var(--color-amber-pale);
  border: 1px solid var(--color-amber-tint-2);
  border-radius: var(--radius-xs);
  font-family: var(--font-family-display);
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  padding: 0.25rem 0.5rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.act3-truth-stamp-line {
  font-family: var(--font-family-body);
  font-size: clamp(0.82rem, 1.1vw, 0.94rem);
  line-height: 1.45;
  color: var(--text-on-dark);
}

/* Inside the case file the stamp is a block in the flow, not a floating element. */
.act3-truth-stamp {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: var(--surface-stamp);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(245, 158, 11, 0.5);
  border-left: 4px solid var(--color-amber);
  border-radius: var(--radius-sm);
  padding: 0.5rem 1rem;
  box-shadow: var(--elev-5);
  pointer-events: auto;
}

/* ==========================================================
   BEAT 3C — THE REPORT CARD
   Act 1's counter and Act 2's four checks on one screen for the first and only time. Built
   as the dark case file (§6.4) because that is exactly the component this is a callback to —
   the same document the learner opened in Act 1, now filled in.
   ========================================================== */

.act3-recap-modal,
.act3-end-modal {
  position: absolute;
  inset: 0;
  background: var(--surface-scrim);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem 1.5rem;
  pointer-events: auto;
  z-index: 50;
}

.is-entering .act3-recap-modal,
.is-entering .act3-end-modal {
  animation: act3FadeIn var(--dur-fast) ease forwards;
}

/* Flex-centred, so there is no transform to be replaced by an entrance keyframe — the
   stampSlam / stampSlamCentered trap in §6.4 cannot bite here. */
/* Fixed to the available height rather than sized to its content: the file fills up as Reyes
   talks, and the card does not resize under the learner between the five steps. */
.act3-recap-card {
  width: min(1280px, 100%);
  height: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--surface-card-dark);
  border: 2px solid var(--color-info);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-modal), 0 0 40px -12px rgba(56, 189, 248, 0.5);
  overflow: hidden;
  min-height: 0;
}

.is-entering .act3-recap-card {
  animation: act3CardRise var(--dur-base) var(--ease-out-expo) forwards;
}

.act3-recap-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.5rem 1.5rem;
  border-bottom: 1px solid var(--hairline-light-soft);
}

.act3-recap-badge {
  background: var(--color-info-strong);
  color: var(--text-inverse);
  border-radius: var(--radius-xs);
  font-family: var(--font-family-display);
  font-size: 0.72rem;
  font-weight: 900;
  letter-spacing: 0.09em;
  padding: 0.25rem 0.5rem;
}

.act3-recap-title {
  flex: 1;
  min-width: 14rem;
  font-family: var(--font-family-display);
  font-size: 1.35rem;
  font-weight: 800;
  line-height: 1.2;
  color: var(--text-inverse);
}

.act3-recap-subtitle {
  display: block;
  margin-top: 0.25rem;
  font-family: var(--font-family-body);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--text-on-dark-dim);
  font-variant-numeric: tabular-nums;
}

/* Act 1's counter, cashed out one last time. Text carries the count, not the colour. */
.act3-recap-hints {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--color-success);
  color: var(--text-inverse);
  border: 1px solid var(--color-success-pale);
  border-radius: var(--radius-pill);
  font-family: var(--font-family-display);
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  padding: 0.25rem 0.75rem;
}


.act3-recap-content {
  display: flex;
  flex: 1;
  min-height: 0;
}

.act3-recap-right {
  width: 33%;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.5rem 1rem;
  min-height: 0;
  overflow-y: auto;
  border-left: 1px solid var(--hairline-light-soft);
}

/* In the recap the discharge sheet is a block in the flow beneath the verdict stamps, not the
   floating in-world object it is in the recheck beat. */
.act3-recap-right .act3-discharge-sheet {
  position: static;
  width: auto;
  margin: 0;
  animation: none;
}
.act3-truth-stamp {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: var(--surface-stamp);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(245, 158, 11, 0.5);
  border-left: 4px solid var(--color-amber);
  border-radius: var(--radius-sm);
  padding: 0.5rem 1rem;
  box-shadow: var(--elev-5);
  pointer-events: auto;
}
.act3-recap-right .act3-discharge-sheet li,
.act3-recap-right .act3-discharge-sheet p,
.act3-recap-right .act3-discharge-sheet span {
  font-size: 0.8rem;
  line-height: 1.35;
}
.act3-recap-right .act3-discharge-sheet {
  padding: 0.5rem 0.75rem 0.75rem;
}
.act3-recap-right .act3-discharge-sheet li {
  padding: 0.25rem 0;
}
.act3-recap-left .act3-timeline-item {
  padding: 0.25rem 0.5rem;
}

.act3-recap-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}

.act3-recap-panel-head .act3-panel-title {
  margin: 0;
}

.act3-btn-table-toggle {
  height: 30px;
  font-size: 0.75rem;
  padding: 0 0.8rem;
}

/* Four signs, two rows: glyph + sign name + stage numeral and word, never colour alone. */
.act3-recap-chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
}
.act3-recap-chips .act3-stage-chip {
  white-space: nowrap;
}

.act3-stage-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.act3-recap-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0.5rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  scrollbar-width: thin;
  scrollbar-color: var(--color-info-mid) transparent;
}

.act3-recap-body::-webkit-scrollbar { width: 6px; }
.act3-recap-body::-webkit-scrollbar-thumb {
  background: var(--color-info-mid);
  border-radius: var(--radius-pill);
}

.act3-recap-panel {
  border: 1px solid var(--hairline-light-faint);
  border-radius: var(--radius-sm);
  padding: 0.5rem 1rem;
}

.is-entering .act3-recap-panel {
  animation: act3FadeIn var(--dur-base) var(--ease-out-expo) forwards;
}

.act3-panel-title {
  font-family: var(--font-family-display);
  font-size: 0.75rem;
  font-weight: 900;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-amber-tint);
  margin-bottom: 0.5rem;
}

.act3-panel-foot {
  margin-top: 0.75rem;
  font-family: var(--font-family-display);
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--text-on-dark-muted);
}

/* --- The four checks --------------------------------------------------- */

.act3-recap-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-family-body);
}

.act3-recap-table th,
.act3-recap-table td {
  text-align: left;
  vertical-align: top;
  padding: 0.5rem 0.5rem;
  border-bottom: 1px solid var(--hairline-light-faint);
}

.act3-recap-table thead th {
  font-family: var(--font-family-display);
  font-size: 0.72rem;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-on-dark-dim);
}

.act3-recap-table tbody tr:last-child th,
.act3-recap-table tbody tr:last-child td {
  border-bottom: 0;
}

.act3-cell-sign {
  font-family: var(--font-family-display);
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--color-amber-tint);
  white-space: nowrap;
}

.act3-cell-reported {
  font-size: clamp(0.82rem, 1.1vw, 0.92rem);
  line-height: 1.4;
  color: var(--text-on-dark-muted);
}

.act3-cell-note {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: var(--text-on-dark-dim);
  font-style: italic;
}

.act3-cell-stage { white-space: nowrap; }

/* Stage is a NUMERAL and a WORD before it is a colour (§7.3). This module is about a
   colour-read symptom; the interface does not get to model bad practice. */
.act3-stage-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  border-radius: var(--radius-xs);
  font-family: var(--font-family-display);
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
}

/* A ring, not a translucent plate. The plate lightened the chip's own ground under the
   numeral and dropped it to 3.06:1 — on the one element that carries the stage signal without
   relying on colour, which is exactly the element that cannot fail. With the ring the numeral
   sits on the chip's own ground and inherits its audited pairing. */
.act3-stage-no {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15rem;
  height: 1.15rem;
  border-radius: var(--radius-xs);
  border: 1.5px solid currentColor;
  font-variant-numeric: tabular-nums;
}

/* --color-amber-pale on --color-amber-deep = 4.51 (do not nudge either value). */
.act3-stage-chip.stage-1 {
  background: var(--color-amber-deep);
  color: var(--color-amber-pale);
}

/* #FFFFFF on --color-heat = 5.18. */
.act3-stage-chip.stage-2 {
  background: var(--color-heat);
  color: var(--text-inverse);
}

/* #FFFFFF on --color-danger = 6.04. */
.act3-stage-chip.stage-3 {
  background: var(--color-danger);
  color: var(--text-inverse);
}

/* --- How often each sign is logged ------------------------------------- */

.act3-prevalence-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.act3-prevalence-row {
  display: grid;
  grid-template-columns: 7rem 1fr 3.2rem;
  align-items: center;
  gap: 0.75rem;
  height: 1.5rem;
}

.act3-prevalence-label {
  font-family: var(--font-family-display);
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--text-on-dark-muted);
}

.act3-prevalence-track {
  height: 10px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
  min-height: 0;
}

/* Bar LENGTH and the numeral both carry the value, so the chart survives being read in
   greyscale — the same construction as Act 1's temperature gauge (§6.8). */
.act3-prevalence-fill {
  display: block;
  height: 100%;
  background: var(--color-info);
  border-radius: var(--radius-pill);
}

.act3-prevalence-value {
  font-family: var(--font-family-display);
  font-size: 0.95rem;
  font-weight: 800;
  color: var(--text-on-dark);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* --- Her afternoon ------------------------------------------------------ */

.act3-recap-timeline {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
}

.act3-timeline-item {
  display: grid;
  grid-template-columns: 4.6rem 1fr;
  align-items: start;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-xs);
  border-left: 3px solid transparent;
}

.act3-timeline-item.is-widest {
  border-left-color: var(--color-amber);
  background: rgba(245, 158, 11, 0.1);
}

.act3-timeline-time {
  font-family: var(--font-family-display);
  font-size: 0.8rem;
  font-weight: 800;
  color: var(--color-amber-tint);
  font-variant-numeric: tabular-nums;
}


.act3-timeline-copy {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-family: var(--font-family-body);
  font-size: 0.84rem;
  line-height: 1.4;
  color: var(--text-on-dark-dim);
}

.act3-timeline-copy strong {
  font-family: var(--font-family-display);
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--text-on-dark-muted);
}

.act3-timeline-flag {
  grid-column: 3;
  margin-top: 0.25rem;
  font-family: var(--font-family-display);
  font-size: 0.7rem;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-amber-tint);
}

/* --- Reyes and Callie, under the chart ---------------------------------- */

.act3-recap-footer {
  border-top: 1px solid var(--hairline-light-soft);
  padding: 0.5rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Capped so the chart above it always keeps the majority of the card — the panels are the
   point of this beat, the dialogue is the walk-through. */
.act3-recap-dialogue {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1;
  overflow-y: auto;
  padding: 1.5rem;
}

.act3-recap-line {
  border-left: 3px solid var(--hairline-light-soft);
  padding-left: 0.75rem;
}

.act3-recap-line.line-reyes { border-left-color: var(--color-info); }
.act3-recap-line.line-callie { border-left-color: var(--color-amber-tint); }

.act3-recap-who {
  display: block;
  font-family: var(--font-family-display);
  font-size: 0.72rem;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-on-dark-dim);
  margin-bottom: 0.25rem;
}

.act3-recap-who .act3-business { color: var(--text-on-dark-dim); }

.act3-recap-text {
  font-family: var(--font-family-body);
  font-size: clamp(0.88rem, 1.15vw, 1rem);
  line-height: 1.5;
  color: var(--text-on-dark);
  /* §9: body copy gets a measure. */
  max-width: 68ch;
}

.act3-recap-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.act3-recap-nav-left {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}





/* ==========================================================
   BEAT 3D — TAY'S RETURN
   ========================================================== */

/* Her voice has been gone since one line in Act 2. That absence is the mechanism; this
   names it once, on her first line, and then gets out of the way. */


/* ==========================================================
   BEAT 3E — NEXT TIME
   Prevention framed forward. Every option is correct: this is Callie deciding what changes,
   not a quiz, so nothing here is marked wrong and nothing is required.
   ========================================================== */

.act3-prevention-card,
.act3-end-card {
  max-height: 100%;
  overflow-y: auto;
  background: var(--palette-cream);
  border: 3px solid var(--palette-warm-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-modal);
  padding: 1rem 1.5rem;
  pointer-events: auto;
}

/* The prevention card is NOT modal — it is a choice the learner makes with the room still
   live behind it, so it has no scrim and the HUD stays reachable. It positions itself, which
   means it is centred on both axes and its entrance must end on translate(-50%, -50%). The
   X-only keyframe here would drop the vertical centring the moment it finished (§6.4). */
.act3-prevention-card {
  position: absolute;
  top: 50%;
  left: 50%;
  max-height: 82%;
  z-index: 45;
  transform: translate(-50%, -50%);
}

.is-entering .act3-prevention-card {
  animation: act3CardInCentered var(--dur-base) var(--ease-out-expo) forwards;
}

/* The close screen is flex-centred by its own scrim, so it has no transform to preserve. */
.is-entering .act3-end-card {
  animation: act3CardRise var(--dur-base) var(--ease-out-expo) forwards;
}

.act3-prevention-badge,
.act3-end-badge {
  display: inline-block;
  background: var(--palette-teal-dark);
  color: var(--text-inverse);
  font-family: var(--font-family-display);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius-xs);
}

.act3-prevention-title {
  margin-top: 0.75rem;
  font-family: var(--font-family-display);
  font-size: clamp(1.1rem, 1.7vw, 1.45rem);
  font-weight: 800;
  line-height: 1.2;
  color: var(--palette-brown-dark);
}

.act3-prevention-sub {
  margin-top: 0.5rem;
  font-family: var(--font-family-body);
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--palette-text-muted);
}

.act3-prevention-count {
  font-family: var(--font-family-display);
  font-weight: 800;
  color: var(--palette-teal-dark);
  font-variant-numeric: tabular-nums;
}

.act3-prevention-options {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
  margin-top: 1rem;
  align-items: start;
}

/* A chosen option and its answer are one unit. `align-items: start` above stops an answered
   column from stretching its unanswered neighbour to match. */
.act3-prevention-item {
  display: flex;
  flex-direction: column;
}

.act3-prevention-option {
  width: 100%;
  display: grid;
  grid-template-columns: 1.6rem 1fr;
  grid-template-areas:
    'icon label'
    '.    state';
  align-items: start;
  gap: 0.25rem 0.5rem;
  text-align: left;
  background: var(--palette-warm-white);
  border: 2px solid var(--palette-peach-dark);
  border-radius: var(--radius-sm);
  padding: 0.75rem 1rem;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out-expo),
              border-color var(--dur-fast) var(--ease-out-expo),
              transform var(--dur-fast) var(--ease-out-expo);
}

.act3-prevention-option:hover,
.act3-prevention-option:focus-visible {
  border-color: var(--palette-teal);
  transform: translateY(-2px);
}

.act3-prevention-option:active { transform: translateY(0); }

/* Chosen is a glyph AND a word before it is a colour (§7.3), and aria-pressed carries it
   to assistive tech. The green is the third signal, not the only one. */
.act3-prevention-option.is-chosen {
  background: var(--palette-sage-light);
  border-color: var(--color-success);
}

.act3-prevention-icon {
  grid-area: icon;
  font-size: 1.05rem;
  line-height: 1.2;
}

.act3-prevention-label {
  grid-area: label;
  font-family: var(--font-family-display);
  font-size: 0.94rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--palette-brown-dark);
}

.act3-prevention-state {
  grid-area: state;
  margin-top: 0.25rem;
  font-family: var(--font-family-display);
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--palette-text-muted);
}

.act3-prevention-option.is-chosen .act3-prevention-state {
  color: var(--palette-brown-dark);
}

.act3-prevention-reply-wrap {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-base) var(--ease-out-expo);
}
.is-chosen > .act3-prevention-reply-wrap {
  grid-template-rows: 1fr;
}
@media (prefers-reduced-motion: reduce) {
  .act3-prevention-reply-wrap {
    transition: none;
  }
}
/* The clip is the grid item: it carries no padding or border of its own, so at 0fr it is
   exactly 0px tall and nothing of the reply peeks out. Collapsed replies are also hidden from
   hit-testing and screen readers. */
.act3-prevention-reply-clip {
  overflow: hidden;
  min-height: 0;
  visibility: hidden;
  transition: visibility 0s linear var(--dur-base);
}
.is-chosen > .act3-prevention-reply-wrap > .act3-prevention-reply-clip {
  visibility: visible;
  transition-delay: 0s;
}
/* Chosen is final — the button stays readable but no longer invites a second click. */
.act3-prevention-option.is-chosen {
  cursor: default;
}
.act3-prevention-reply {
  margin-top: 0.5rem;
  background: var(--palette-warm-white);
  border-left: 5px solid var(--palette-teal-dark);
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.75rem;
  box-shadow: var(--elev-1);
}

.act3-prevention-reply .act3-recap-text {
  font-size: clamp(0.82rem, 1.05vw, 0.92rem);
}

.act3-prevention-reply .act3-recap-who { color: var(--color-info-strong); }
.act3-prevention-reply .act3-recap-text { color: var(--palette-brown-dark); }

/* ==========================================================
   BEAT 3F — THE DISCHARGE SHEET
   An in-world object: the chart Reyes has been writing on all act, torn off and handed over.
   Deliberately NOT a printable job aid — the beats doc cuts the glovebox card, so this
   leaves with Callie, not with the learner.
   ========================================================== */

.act3-discharge-sheet {
  position: absolute;
  bottom: max(4rem, 22%);
  right: 1.5rem;
  width: min(280px, 24%);
  background: var(--palette-warm-white);
  border: 1px solid var(--palette-peach-dark);
  border-top: 5px solid var(--palette-teal-dark);
  border-radius: var(--radius-sm);
  box-shadow: var(--elev-4);
  padding: 0.75rem 1rem 1rem;
  pointer-events: auto;
  z-index: 32;
}

.is-entering .act3-discharge-sheet {
  animation: act3SlideInRight var(--dur-base) var(--ease-out-expo) forwards;
}

.act3-discharge-header {
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--palette-peach);
  margin-bottom: 0.5rem;
}

.act3-discharge-badge {
  display: block;
  font-family: var(--font-family-display);
  font-size: 0.78rem;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--palette-teal-dark);
}

.act3-discharge-patient {
  display: block;
  margin-top: 0.25rem;
  font-family: var(--font-family-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--palette-text-muted);
}

.act3-discharge-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.act3-discharge-item {
  display: grid;
  grid-template-columns: 1.3rem 1fr;
  gap: 0.5rem;
  align-items: start;
}

.act3-discharge-glyph {
  font-size: 0.9rem;
  line-height: 1.3;
}

.act3-discharge-copy {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-family: var(--font-family-body);
  font-size: 0.76rem;
  line-height: 1.45;
  color: var(--palette-text-muted);
}

.act3-discharge-copy strong {
  font-family: var(--font-family-display);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--palette-brown-dark);
}

/* ==========================================================
   THE CLOSE
   Not a score. The act's whole claim is that every number is a verdict on this playthrough,
   so the last screen states what this learner actually did and then gets out of the way.
   ========================================================== */

.act3-end-card { text-align: center; }

.act3-end-title {
  margin-top: 0.75rem;
  font-family: var(--font-family-display);
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--palette-brown-dark);
}

.act3-end-line {
  margin: 0.5rem auto 0;
  max-width: 46ch;
  font-family: var(--font-family-body);
  font-size: 1rem;
  line-height: 1.55;
  color: var(--palette-text-muted);
}

.act3-end-recap {
  list-style: none;
  margin: 0.5rem 0;
  border-top: 1px solid var(--palette-peach);
  text-align: left;
}

.act3-end-recap li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.25rem;
  border-bottom: 1px solid var(--palette-peach);
}

.act3-end-recap-label {
  font-family: var(--font-family-body);
  font-size: 0.88rem;
  color: var(--palette-text-muted);
}

.act3-end-recap-value {
  font-family: var(--font-family-display);
  font-size: 0.92rem;
  font-weight: 800;
  color: var(--palette-brown-dark);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.act3-end-close {
  margin: 0 auto 0.75rem;
  max-width: 44ch;
  font-family: var(--font-family-body);
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--palette-brown-med);
}

.act3-end-close strong {
  display: block;
  margin-top: 0.25rem;
  font-family: var(--font-family-display);
  font-weight: 800;
  color: var(--palette-brown-dark);
}

.act3-end-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* ==========================================================
   MOTION
   Entrances are 0.25–0.35s on --ease-out-expo (§5.2). Only one loop exists on this screen —
   the primary-button pulse — and it is an invitation, which is the only thing a loop is
   allowed to be.
   ========================================================== */

@keyframes act3FadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* No centring transform to preserve — for elements that position themselves with
   left/right/bottom rather than a translate. */
@keyframes act3SlideUp {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* X-axis centring only. Ends on translateX(-50%). */
@keyframes act3SlideUpX {
  from { opacity: 0; transform: translateX(-50%) translateY(10px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

@keyframes act3StampIn {
  from { opacity: 0; transform: translateX(-50%) translateY(14px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* Both axes. Ends on translate(-50%, -50%). */
@keyframes act3CardInCentered {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.96); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

/* No transform to preserve — the report card is flex-centred by its scrim. */
@keyframes act3CardRise {
  from { opacity: 0; transform: translateY(14px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes act3SlideInRight {
  from { opacity: 0; transform: translateX(20px); }
  to { opacity: 1; transform: translateX(0); }
}

/* Reduced motion (§5.3). Loops are killed outright; entrances are SHORTENED, never removed,
   because act3SlideUpX / act3StampIn / act3CardInCentered each carry the element's centring
   transform in their final frame. Remove them and the element jumps. */
@media (prefers-reduced-motion: reduce) {
  #screen-act3 .act3-hud-btn.btn-action-primary.pulse-btn {
    animation: none;
  }

  #screen-act3 .act3-stage-card,
  #screen-act3 .act3-hold-card,
  #screen-act3 .act3-door-card,
  #screen-act3 .act3-wait-panel,
  #screen-act3 .act3-voice-return-banner,
  #screen-act3 .act3-truth-stamp,
  #screen-act3 .act3-recap-modal,
  #screen-act3 .act3-recap-card,
  #screen-act3 .act3-end-modal,
  #screen-act3 .act3-recap-panel,
  #screen-act3 .act3-prevention-card,
  #screen-act3 .act3-prevention-reply,
  #screen-act3 .act3-discharge-sheet,
  #screen-act3 .act3-end-card,
  #screen-act3 .speech-bubble {
    animation-duration: 0.01s;
    animation-delay: 0s;
  }

  #screen-act3 .act3-scene-img,
    #screen-act3 .act3-wash,
  #screen-act3 .act3-wait-bar-fill {
    transition: none;
  }
}

/* ==========================================================
   RESPONSIVE (§9)
   ========================================================== */

@media (max-width: 768px) {
  .act3-viewport-card { aspect-ratio: 4 / 3; }

  .act3-hud-bar,
  .act3-nav-bar {
    left: 0.75rem;
    right: 0.75rem;
  }

  .act3-hud-pill {
    height: 32px;
    font-size: 0.76rem;
    padding: 0 0.75rem;
  }

  .act3-hud-btn {
    height: 34px;
    font-size: 0.8rem;
    padding: 0 0.75rem;
  }

  /* Bubbles stop trying to point at people on a 4:3 crop and stack along the bottom. */
  .act3-callie-bubble,
  .act3-reyes-bubble,
  .act3-tay-bubble {
    top: auto !important;
    bottom: max(4rem, 22%);
    left: 4% !important;
    right: auto !important;
    max-width: 92% !important;
  }

  .act3-wait-panel {
    left: 4%;
    right: 4%;
    width: auto;
  }

  /* On a 4:3 phone card there is not enough height to pin a header, scroll a body and pin a
     footer — the header alone consumed the whole card. The case file becomes one scrolling
     column instead, so all of it is reachable at the cost of seeing less at once. */
  .act3-recap-modal,
  .act3-end-modal {
    padding: 0.5rem;
  }

  .act3-recap-card {
    display: block;
    overflow-y: auto;
  }

  .act3-recap-content {
    display: block;
  }
  .act3-recap-right {
    width: 100%;
    border-left: none;
    border-top: 1px solid var(--hairline-light-soft);
  }


  .act3-recap-header {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--surface-card-dark);
    padding: 0.5rem 0.75rem 0.5rem;
    gap: 0.5rem;
  }

  .act3-recap-badge { font-size: 0.62rem; padding: 0.25rem 0.5rem; }

  .act3-recap-title {
    min-width: 0;
    flex: 1 1 100%;
    font-size: 1rem;
  }

  .act3-recap-subtitle { font-size: 0.7rem; }
  .act3-recap-hints { font-size: 0.66rem; padding: 0.25rem 0.5rem; }

  
.act3-recap-content {
  display: flex;
  flex: 1;
  min-height: 0;
}

.act3-recap-right {
  width: 36%;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--hairline-light-soft);
}

.act3-recap-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}

.act3-recap-panel-head .act3-panel-title {
  margin: 0;
}

.act3-btn-table-toggle {
  height: 30px;
  font-size: 0.75rem;
  padding: 0 0.8rem;
}

.act3-recap-chips {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.act3-stage-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.act3-recap-body {
    overflow: visible;
    padding: 0.5rem 0.75rem;
  }

  .act3-recap-footer {
    position: sticky;
    bottom: 0;
    padding: 0.5rem 0.75rem;
  }

  .act3-recap-dialogue { max-height: none; overflow: visible; }
  .act3-recap-panel { padding: 0.5rem 0.75rem; }

  .act3-recap-card,
  .act3-prevention-card,
  .act3-end-card {
    width: 96%;
  }

  .act3-prevention-options { grid-template-columns: 1fr; }

  .act3-recap-table thead { display: none; }

  .act3-recap-table tbody tr {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.25rem 0.5rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--hairline-light-faint);
  }

  .act3-recap-table th,
  .act3-recap-table td {
    border-bottom: 0;
    padding: 0.25rem 0;
  }

  .act3-cell-reported { grid-column: 1 / -1; }

  .act3-prevalence-row { grid-template-columns: 5.5rem 1fr 2.8rem; }

  .act3-discharge-sheet {
    position: static;
    width: auto;
    margin: 4rem 1rem 0;
  }
}

@media (max-height: 700px) {
  .act3-recap-card,
  .act3-prevention-card,
  .act3-end-card {
    padding: 0.9rem 1.1rem;
  }

  .act3-recap-header { padding: 0.75rem 1rem 0.5rem; }
  
.act3-recap-content {
  display: flex;
  flex: 1;
  min-height: 0;
}

.act3-recap-right {
  width: 36%;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--hairline-light-soft);
}

.act3-recap-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}

.act3-recap-panel-head .act3-panel-title {
  margin: 0;
}

.act3-btn-table-toggle {
  height: 30px;
  font-size: 0.75rem;
  padding: 0 0.8rem;
}

.act3-recap-chips {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.act3-stage-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.act3-recap-body { padding: 0.75rem 1rem; gap: 0.75rem; }
  .act3-recap-footer { padding: 0.75rem 1rem; }
  .act3-recap-dialogue { max-height: none; }
  .act3-end-recap li { padding: 0.5rem 0.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  .act3-cast-img {
    transition-duration: 0.01s !important;
  }
  .act3-cast-reyes {
    animation-duration: 0.01s !important;
  }
}

#screen-act3 .speech-bubble-text, #screen-act3 .speech-bubble-text span {
  font-family: var(--font-family-display);
  font-size: clamp(1rem, 1.25vw, 1.2rem);
  font-weight: 600;
  line-height: 1.4;
}

#screen-act3 .speech-bubble-text {
  font-size: clamp(1rem, 1.25vw, 1.2rem);
}
/* The span rule above sets every span to 600; Tay's sound is the one span that is 800 (§6.3). */
#screen-act3 .speech-bubble-text .tay-onomatopoeia {
  font-weight: 800;
}

.act3-timeline-next-time-row {
  display: block;
  margin-top: 0.25rem;
  font-family: var(--font-family-body);
  font-size: 0.8rem;
  color: var(--palette-text-muted);
}
.act3-timeline-next-time-row .act3-timeline-flag {
  display: inline-block;
  margin-top: 0;
  margin-right: 0.25rem;
}

/* Living room: Tay is asleep on the right-hand cushion, so her bubble sits over her. */
.scene-home .act3-tay-bubble {
  left: 48%;
  --stem-left: 30%;
}

/* Anchor each bubble by its BOTTOM edge so the stem sits just above the speaker's head no
   matter how long the line is. Heads: Callie/Reyes ≈ 44–47% from the top of the stage, Tay
   ≈ 80%; in the living room Callie ≈ 35%, Tay on the cushion ≈ 55%. */
#screen-act3 .scene-clinic .act3-callie-bubble,
#screen-act3 .scene-clinic .act3-reyes-bubble {
  top: auto;
  bottom: 59%;
}
#screen-act3 .scene-clinic .act3-tay-bubble {
  top: auto;
  bottom: 30%;
}
#screen-act3 .scene-home .act3-callie-bubble {
  top: auto;
  bottom: 69%;
}
#screen-act3 .scene-home .act3-tay-bubble {
  top: auto;
  bottom: 49%;
  left: 58%;
  max-width: 30%;
  --stem-left: 18%;
}

/* Recap timeline: the "next time" row is the payload; keep both rows compact so all four
   items and their advice stay on one screen. */
.act3-recap-left .act3-timeline-copy,
.act3-recap-left .act3-timeline-next-time-row {
  font-size: 0.8rem;
  line-height: 1.35;
}

.act3-recap-right .act3-discharge-list {
  gap: 0.25rem;
}
.act3-recap-right .act3-discharge-item {
  padding: 0.25rem 0;
}
.act3-recap-right .act3-discharge-label {
  font-size: 0.8rem;
}
.act3-recap-right .act3-discharge-sub {
  font-size: 0.7rem;
  line-height: 1.25;
}
.act3-recap-right .act3-discharge-header {
  margin-bottom: 0.25rem;
}

#screen-act3 .scene-clinic .has-sheet .act3-discharge-sheet {
  right: auto;
  left: 1.5rem;
}

.act3-recap-right .act3-truth-stamp-line {
  font-size: 0.82rem;
  line-height: 1.35;
}
.act3-recap-right .act3-discharge-sheet {
  padding: 0.25rem 0.75rem 0.5rem;
}


/* ==========================================================
   SOURCES CARD
   ========================================================== */

.act3-end-modal {
  gap: 1.5rem;
}

.act3-end-card {
  width: 52%;
}

.act3-sources-card {
  width: 45%;
  max-height: 100%;
  overflow-y: auto;
  background: var(--surface-card-dark);
  border: 2px solid var(--color-info);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-modal), 0 0 40px -12px rgba(56, 189, 248, 0.5);
  padding: 1rem 1.5rem;
  pointer-events: auto;
}

.is-entering .act3-sources-card {
  animation: act3CardRise var(--dur-base) var(--ease-out-expo) forwards;
}

.act3-sources-badge {
  display: inline-block;
  background: var(--palette-teal-dark);
  color: var(--text-inverse);
  font-family: var(--font-family-display);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius-xs);
}

.act3-sources-title {
  margin-top: 0.75rem;
  font-family: var(--font-family-display);
  font-size: clamp(1.1rem, 1.7vw, 1.45rem);
  font-weight: 800;
  line-height: 1.2;
  color: var(--text-on-dark);
}

.act3-mla-list {
  list-style: none;
  margin: 1rem 0 0 0;
  padding: 0;
  font-family: var(--font-family-body);
  font-size: 0.8rem;
  line-height: 1.4;
}

.act3-mla-list li {
  padding-left: 1.5rem;
  text-indent: -1.5rem;
  margin-bottom: 0.5rem;
  overflow-wrap: anywhere;
  color: var(--text-on-dark);
}
/* Links on the dark card: pale info blue, underlined (colour is never the only cue). */
.act3-mla-list a {
  color: var(--color-info-pale);
  text-decoration: underline;
  text-underline-offset: 2px;
  pointer-events: auto;
}
.act3-mla-list a:hover {
  color: var(--text-inverse);
  text-decoration-thickness: 2px;
}
.act3-mla-list a:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-on-dark);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

@media (max-height: 700px) {
  .act3-mla-list {
    font-size: 0.8rem;
  }
}

@media (max-width: 768px) {
  .act3-end-modal {
    flex-direction: column;
    gap: 1rem;
    overflow-y: auto;
  }
  .act3-end-card,
  .act3-sources-card {
    width: 96%;
    max-height: none;
  }
}

#screen-act3 .speech-bubble:not(.is-new-line) {
  animation: none;
}

/* Numbered markers where the discharge sheet and the prevention list used to carry emoji
   (design-language.md §3.3). §6.7 square badge, sized to the existing 1.3–1.6rem icon column. */
.act3-icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.3rem;
  height: 1.3rem;
  border-radius: var(--radius-xs);
  font-family: var(--font-family-display);
  font-size: 0.75rem;
  font-weight: 800;
  line-height: 1;
  background: var(--palette-sage-light);
  color: var(--palette-brown-dark);
}

#screen-act3 .tay-onomatopoeia {
  font-weight: 800;
  color: var(--color-heat);
  font-style: normal;
  text-transform: uppercase;
  margin-right: 0.2rem;
}

#screen-act3 .tay-sub-dialogue {
  font-style: italic;
  color: var(--color-heat-deep);
}


/* ==========================================================
   TAKEAWAY CARD
   ========================================================== */

.act3-takeaway-scrim {
  position: absolute;
  inset: 0;
  background: var(--surface-scrim);
  backdrop-filter: blur(8px);
  z-index: 60;
  pointer-events: auto;
}

.act3-takeaway {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(94%, 940px);
  max-height: 92%;
  background: var(--palette-warm-white);
  border: 3px solid var(--palette-teal-dark);
  border-radius: var(--radius-lg);
  box-shadow: var(--elev-modal);
  z-index: 65;
  display: flex;
  flex-direction: column;
  pointer-events: auto;
  animation: stampSlamCentered 0.35s var(--ease-out-expo) forwards;
}

.act3-takeaway-header {
  padding: 1.5rem 1.5rem 0.5rem;
}

.act3-takeaway-badge {
  display: inline-block;
  background: var(--palette-teal-dark);
  color: var(--text-inverse);
  font-family: var(--font-family-display);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius-xs);
  margin-bottom: 0.5rem;
}

.act3-takeaway-title {
  margin: 0;
  font-family: var(--font-family-display);
  font-size: clamp(1.2rem, 2vw, 1.6rem);
  font-weight: 800;
  color: var(--palette-brown-dark);
}

.act3-takeaway-body {
  padding: 0 1.5rem;
  overflow-y: auto;
  scrollbar-width: thin;
}

/* More below: the foot of the scroll area fades, over the row that peeks out. */
.act3-takeaway-body.has-more {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 36px), rgba(0, 0, 0, 0.3));
  mask-image: linear-gradient(to bottom, #000 calc(100% - 36px), rgba(0, 0, 0, 0.3));
}

.act3-takeaway-body::-webkit-scrollbar {
  width: 6px;
}
.act3-takeaway-body::-webkit-scrollbar-thumb {
  background: var(--palette-brown-light);
  border-radius: 3px;
}

/* ---- The sheet as an infographic -------------------------------------
   Four bands, read top to bottom: the numbers, the habits, the warning signs as an
   early-to-late scale, and what to do. Text sits on light grounds only (dark text, AA);
   colour marks the stage but the stage name always says it too (§7.3). */
.act3-tk-subtitle {
  margin: 0.35rem 0 0;
  font-family: var(--font-family-body);
  font-size: 0.98rem;
  line-height: 1.45;
  color: var(--palette-text-muted);
}

.act3-tk-stats {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.6rem;
}
.act3-tk-stat {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.8rem 0.85rem;
  background: var(--color-heat-tint);
  border: 2px solid var(--color-amber-tint);
  border-radius: var(--radius-md);
}
.act3-tk-stat-value {
  font-family: var(--font-family-display);
  font-size: clamp(1.6rem, 2.6vw, 2.1rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-heat);
}
.act3-tk-stat-text {
  font-family: var(--font-family-body);
  font-size: 0.82rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--palette-text-dark);
}

.act3-tk-band {
  margin: 1.1rem 0 0;
}
.act3-tk-band-title {
  margin: 0 0 0.55rem;
  font-family: var(--font-family-display);
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--palette-teal-dark);
}

.act3-tk-habits {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.6rem;
}
.act3-tk-habit {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.65rem 0.75rem;
  background: var(--text-inverse);
  border: 1.5px solid var(--palette-peach-light);
  border-radius: var(--radius-md);
}
.act3-tk-icon-wrap {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--palette-teal-dark);
  display: grid;
  place-items: center;
}
.act3-tk-icon {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: var(--text-inverse);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.act3-tk-habit-copy {
  font-family: var(--font-family-body);
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--palette-text-dark);
}
.act3-tk-habit-copy strong {
  display: block;
  font-family: var(--font-family-display);
  font-size: 0.92rem;
  font-weight: 800;
  color: var(--palette-brown-dark);
}

.act3-tk-note {
  margin: -0.2rem 0 0.6rem;
  font-family: var(--font-family-body);
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--palette-text-muted);
}
/* The scale: one continuous early -> late bar across the top of three stage columns. */
.act3-tk-scale {
  list-style: none;
  margin: 0;
  padding: 10px 0 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.6rem;
  position: relative;
}
.act3-tk-scale::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--color-amber), var(--color-heat-bright), var(--color-danger));
}
.act3-tk-stage {
  padding: 0.65rem 0.75rem;
  border-radius: var(--radius-md);
  border-top: 4px solid;
}
.act3-tk-stage-1 { background: var(--color-amber-pale); border-top-color: var(--color-amber); }
.act3-tk-stage-2 { background: var(--color-heat-tint); border-top-color: var(--color-heat-bright); }
.act3-tk-stage-3 { background: color-mix(in srgb, var(--color-danger-pale) 35%, white); border-top-color: var(--color-danger); }
.act3-tk-stage-name {
  display: block;
  margin-bottom: 0.3rem;
  font-family: var(--font-family-display);
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--palette-brown-dark);
}
.act3-tk-stage ul {
  margin: 0;
  padding-left: 1rem;
}
.act3-tk-stage ul li {
  font-family: var(--font-family-body);
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--palette-text-dark);
}
.act3-tk-stage ul li + li { margin-top: 0.25rem; }

.act3-tk-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.5rem;
}
.act3-tk-step {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.65rem 0.7rem;
  background: var(--text-inverse);
  border: 1.5px solid var(--palette-teal-dark);
  border-radius: var(--radius-md);
  font-family: var(--font-family-body);
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--palette-text-dark);
}
.act3-tk-step-num {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--palette-teal-dark);
  color: var(--text-inverse);
  font-family: var(--font-family-display);
  font-size: 0.85rem;
  font-weight: 800;
  display: grid;
  place-items: center;
}
.act3-tk-footer-line {
  margin: 0.7rem 0 0.2rem;
  padding: 0.7rem 0.9rem;
  background: var(--palette-teal-dark);
  color: var(--text-inverse);
  border-radius: var(--radius-md);
  font-family: var(--font-family-display);
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.4;
}

.act3-takeaway-footer {
  padding: 1rem 1.5rem 1.5rem;
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
}

@media (max-width: 900px) {
  .act3-tk-stats { grid-template-columns: repeat(2, 1fr); }
  .act3-tk-habits { grid-template-columns: repeat(2, 1fr); }
  .act3-tk-steps { grid-template-columns: 1fr; }
  .act3-tk-step { flex-direction: row; align-items: flex-start; }
  .act3-tk-step-num { flex: 0 0 auto; }
}
@media (max-width: 560px) {
  .act3-tk-habits,
  .act3-tk-scale { grid-template-columns: 1fr; }
}

/* On phones and short screens the scene card is only ~350x260, and a sheet inside it had
   no room left for its body (it collapsed to 0px). There the sheet leaves the card and takes
   the whole screen; nothing above it is transformed, so fixed is relative to the viewport. */
@media (max-width: 768px), (max-height: 560px) {
  .act3-takeaway-scrim {
    position: fixed;
  }
  .act3-takeaway {
    position: fixed;
    width: calc(100vw - 16px);
    max-height: calc(100dvh - 16px);
  }
  .act3-takeaway-header { padding: 1rem 1rem 0.25rem; }
  .act3-takeaway-body { padding: 0 1rem; min-height: 0; }
  .act3-takeaway-footer { padding: 0.75rem 1rem 1rem; }
}

/* Print copy of the takeaway card, built on demand by the Print button (see act3-screen.js).
   One page, colours kept (it is an infographic, the colour is part of it). */
#act3-print-root {
  display: none;
}

/* Print: one US Letter page (8.5 x 11 in) with 0.5 in safe margins on every side, so the
   printable area is 7.5 x 10 in (720 x 960 CSS px). The on-screen sheet is untouched; these
   rules only style the body-level print copy (#act3-print-root). */
@media print {
  @page {
    size: 8.5in 11in;
    margin: 0.5in;
  }
  html, body, #app {
    height: auto;
    overflow: visible;
    background: var(--text-inverse);
  }
  body > :not(#act3-print-root) {
    display: none !important;
  }
  #act3-print-root {
    display: block;
    color: var(--palette-text-dark);
    font-family: var(--font-family-body);
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    width: auto;
    margin: 0;
    /* Scaled to the 7.5 in width, the sheet fits the 10 in page on one sheet. Measured by
       rendering a Letter PDF in headless Chromium: 0.90 is the largest that stays on one page,
       0.92 spills to a second. 0.88 keeps a buffer for other browsers' fonts and printers. */
    zoom: 0.88;
  }
  #act3-print-root .act3-takeaway-body {
    overflow: visible;
    max-height: none;
    padding: 0;
  }
  #act3-print-root .act3-takeaway-header { padding: 0 0 0.3rem; }
  #act3-print-root .act3-tk-stats { grid-template-columns: repeat(4, 1fr); }
  #act3-print-root .act3-tk-habits { grid-template-columns: repeat(3, 1fr); }
  #act3-print-root .act3-tk-scale { grid-template-columns: repeat(3, 1fr); }
  #act3-print-root .act3-tk-steps { grid-template-columns: repeat(5, 1fr); }
  #act3-print-root .act3-tk-step { flex-direction: column; }
  #act3-print-root .act3-tk-band,
  #act3-print-root .act3-tk-stat,
  #act3-print-root .act3-tk-habit,
  #act3-print-root .act3-tk-step { break-inside: avoid; }
  #act3-print-root .act3-tk-print-credit {
    display: block;
    margin-top: 0.6rem;
    font-size: 8pt;
    color: var(--palette-text-muted);
  }
}

@media (prefers-reduced-motion: reduce) {
  .act3-takeaway {
    animation-duration: 0.01s !important;
  }
}
