/* ========================================
   MIRA LANDING PAGE - Slide Deck Styles
   Deck-specific styles. Load AFTER base.css.
   Shared styles (fonts, reset, accent system, ambient layers,
   site header, page-frame, frame-furniture, reduced-motion base,
   mobile base) live in base.css. This file contains only the
   slide-deck mechanics on top of that foundation.
   ======================================== */

/* Scope: prevent the deck page from scrolling.
   The `.landing-body` class on <body> is how the deck opts out
   of base.css's default `overflow-y: auto`. */
body.landing-body {
   overflow: hidden;
}

/* Typed custom property for the CTA breath animation.
   Registering as <number> lets the browser interpolate it smoothly
   between keyframes so box-shadow calc() expressions can read it
   as a continuous 0..1 signal. */
@property --breath {
   syntax: '<number>';
   inherits: false;
   initial-value: 0;
}

/* Slide-local accent — so each slide's kicker, scanlines, and media border
   always pick up their own color regardless of which slide is active. */
.slide--magenta { --accent: #c0f; --accent-rgb: 204 0 255; }
.slide--cyan    { --accent: #0ff; --accent-rgb: 0 255 255; }
.slide--lime    { --accent: #0f0; --accent-rgb: 0 255 0; }
.slide--yellow  { --accent: #ff0; --accent-rgb: 255 255 0; }
.slide--pink    { --accent: #f0a; --accent-rgb: 255 0 170; }

/* ========================================
   SLIDE DECK CONTAINER
   ======================================== */

.slide-deck {
   position: relative;
   z-index: 4;
   display: flex;
   flex-direction: row;
   width: 800vw;
   height: 100vh;
   transition: transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

/* ========================================
   INDIVIDUAL SLIDE
   ======================================== */

.slide {
   flex: 0 0 100vw;
   width: 100vw;
   height: 100vh;
   display: flex;
   flex-direction: column;
   justify-content: center;
   position: relative;
}

.slide-content {
   max-width: 65ch;
   margin: 0 auto;
   padding: 4rem 2rem;
}

/* Split layout: text left, media right */
.slide--split {
   flex-direction: row;
   align-items: center;
   gap: 4rem;
   padding: 0 8vw;
}

.slide--split .slide-text {
   flex: 1;
   max-width: 60ch;
}

.slide--split .slide-media {
   flex: 1;
   display: flex;
   align-items: center;
   justify-content: center;
   min-height: 320px;
   border: 1px dashed rgb(var(--accent-rgb) / 0.2);
   border-radius: 4px;
   background: rgb(var(--accent-rgb) / 0.025);
   position: relative;
}

.slide--split .slide-media::before {
   content: "";
   position: absolute;
   inset: 6px;
   border: 1px solid rgb(var(--accent-rgb) / 0.08);
   border-radius: 2px;
   pointer-events: none;
}

.slide--split .slide-media:empty::after {
   content: 'MEDIA · ' attr(data-label);
   font-family: 'IBM Plex Mono', monospace;
   font-size: 0.7rem;
   text-transform: uppercase;
   letter-spacing: 0.22em;
   color: rgb(var(--accent-rgb) / 0.35);
}

.slide--split .slide-media img,
.slide--split .slide-media video {
   max-width: 100%;
   max-height: 60vh;
   border-radius: 4px;
}

/* ASCII-art media variant: strip the picture-frame treatment
   and render the characters big in IBM Plex Mono. */
.slide--split .slide-media--ascii {
   border: none;
   background: transparent;
}

.slide--split .slide-media--ascii::before {
   display: none;
}

.ascii-art {
   margin: 0;
   font-family: 'IBM Plex Mono', monospace;
   font-size: clamp(2.5rem, 7vw, 5.5rem);
   font-weight: 300;
   line-height: 1;
   letter-spacing: 0.02em;
   color: rgba(250, 246, 238, 0.88);
   white-space: pre;
   user-select: none;
}

/* Mirror layout: flip text/media horizontally — creates a palindromic
   rhythm across slides 2-6 (default → mirror × 3 → default). */
.slide--split.slide--mirror {
   flex-direction: row-reverse;
}

/* Splash and CTA are centered, not split */
.slide--splash,
.slide--cta {
   flex-direction: column;
}

/* Subtle scanline overlay — only on the two centered slides.
   Reinforces CRT instrument reading without interfering with body copy. */
.slide--splash::after,
.slide--cta::after {
   content: "";
   position: absolute;
   inset: 0;
   pointer-events: none;
   z-index: 1;
   background: repeating-linear-gradient(
      to bottom,
      transparent 0,
      transparent 3px,
      rgb(var(--accent-rgb) / 0.022) 3px,
      rgb(var(--accent-rgb) / 0.022) 4px
   );
}

.slide--splash .slide-content,
.slide--cta .slide-content {
   position: relative;
   z-index: 2;
}

/* ========================================
   SLIDE TYPOGRAPHY
   ======================================== */

.slide-heading {
   font-size: clamp(2rem, 5vw, 3.5rem);
   font-weight: 100;
   line-height: 1.1;
   letter-spacing: -0.02em;
   margin-bottom: 2rem;
   color: #faf6ee;
}

.slide-heading--large {
   font-size: clamp(2.5rem, 7vw, 4.5rem);
   letter-spacing: -0.025em;
}

.slide-body {
   font-size: 1.05rem;
   line-height: 1.8;
   color: rgba(250, 246, 238, 0.82);
   max-width: 52ch;
}

.slide-body + .slide-body {
   margin-top: 1.25rem;
}

/* Slide kicker — binder between eyebrow and heading.
   The hairline underline is how accent color bleeds into the text region. */
.slide-kicker {
   display: inline-block;
   font-family: 'IBM Plex Mono', monospace;
   font-size: 0.72rem;
   text-transform: uppercase;
   letter-spacing: 0.22em;
   color: rgb(var(--accent-rgb) / 0.72);
   margin-bottom: 1.25rem;
   padding-bottom: 0.75rem;
   border-bottom: 1px solid rgb(var(--accent-rgb) / 0.3);
}

/* ========================================
   SLIDE ACCENT COLORS (heading override)
   ======================================== */

.slide--magenta .slide-heading { color: #c0f; }
.slide--cyan .slide-heading { color: #0ff; }
.slide--lime .slide-heading { color: #0f0; }
.slide--yellow .slide-heading { color: #ff0; }
.slide--pink .slide-heading { color: #f0a; }

/* ========================================
   SPLASH SLIDE (Slide 1)
   ======================================== */

.slide--splash {
   text-align: center;
}

.slide--splash .slide-content {
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: center;
}

.slide--splash .slide-heading {
   font-style: italic;
   opacity: 0.95;
}

/* ========================================
   REFLECTION SLIDE
   A moment to stop. Body text on a narrow reading column,
   centered vertically, left-aligned so multi-sentence prose reads cleanly.
   ======================================== */

.slide--reflection {
   flex-direction: column;
}

.slide--reflection .slide-content {
   max-width: 48ch;
   padding: 4rem 2rem;
   text-align: left;
}

.slide--reflection .slide-body {
   font-size: 1.1rem;
   line-height: 1.85;
}

.slide--reflection .slide-body + .slide-body {
   margin-top: 1.5rem;
}

.slide--reflection .slide-content > * {
   opacity: 0;
   transform: translateY(14px);
   transition: opacity 0.7s cubic-bezier(0.2, 0.8, 0.2, 1),
               transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.slide.is-active.slide--reflection .slide-content > * {
   opacity: 1;
   transform: translateY(0);
}

.slide.is-active.slide--reflection .slide-content > *:nth-child(1) { transition-delay: 0.18s; }
.slide.is-active.slide--reflection .slide-content > *:nth-child(2) { transition-delay: 0.32s; }
.slide.is-active.slide--reflection .slide-content > *:nth-child(3) { transition-delay: 0.44s; }

/* Dual-column variant: main thesis on the left, developer aside on the right.
   Grid so the two blocks anchor to the top and collapse cleanly on mobile. */
.slide--reflection .slide-content--dual {
   max-width: 88ch;
   display: grid;
   grid-template-columns: 1.35fr 1fr;
   gap: 4rem;
   align-items: start;
}

.reflection-main {
   display: flex;
   flex-direction: column;
   gap: 1.5rem;
}

.reflection-note {
   position: relative;
}

.reflection-note-label {
   display: inline-block;
   font-family: 'IBM Plex Mono', monospace;
   font-size: 0.68rem;
   text-transform: uppercase;
   letter-spacing: 0.24em;
   color: rgb(var(--accent-rgb) / 0.75);
   margin-bottom: 1.25rem;
   padding-bottom: 0.65rem;
   border-bottom: 1px solid rgb(var(--accent-rgb) / 0.35);
}

.reflection-note .slide-body {
   font-size: 1.02rem;
   line-height: 1.8;
   color: rgba(250, 246, 238, 0.72);
}

/* ========================================
   CTA SLIDE (Slide 7)
   — convergence hairline + oversized instrument button
   ======================================== */

.slide--cta {
   text-align: center;
}

.slide--cta .slide-content {
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 2.5rem;
}

.slide--cta .slide-content::before {
   content: "";
   position: absolute;
   top: -6rem;
   left: 50%;
   width: 1px;
   height: 9rem;
   background: linear-gradient(
      to bottom,
      transparent 0%,
      rgb(var(--accent-rgb) / 0.12) 35%,
      rgb(var(--accent-rgb) / 0.62) 85%,
      rgb(var(--accent-rgb) / 0.75) 100%
   );
   transform: translateX(-0.5px);
}

.slide--cta .slide-kicker {
   border-color: rgb(var(--accent-rgb) / 0.38);
}

.cta-tagline {
   font-size: 1.25rem;
   color: rgba(250, 246, 238, 0.72);
   letter-spacing: 0.01em;
}

.cta-button {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   height: 64px;
   padding: 0 56px;
   background: var(--accent);
   color: #000;
   font-family: 'IBM Plex Mono', monospace;
   font-weight: 500;
   font-size: 0.88rem;
   text-transform: uppercase;
   letter-spacing: 0.22em;
   text-decoration: none;
   border-radius: 2px;
   --breath: 0;
   transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1),
               box-shadow 0.4s ease;
   box-shadow:
      0 0 0 1px rgb(var(--accent-rgb) / calc(0.4 + 0.25 * var(--breath))),
      0 0 calc(40px + 18px * var(--breath)) rgb(var(--accent-rgb) / calc(0.35 + 0.17 * var(--breath))),
      0 0 calc(80px + 44px * var(--breath)) rgb(var(--accent-rgb) / calc(0.15 + 0.07 * var(--breath)));
   animation: cta-breathe 4.5s linear infinite;
}

/* Empirical tidal breathing, modeled from pneumotachograph flow-time data.
   Inspiration 0-40%: half-cosine rise (active muscular drive, peak flow mid-inhale).
   Inspiratory hold 40-45%: brief dwell at peak tidal volume (~225ms).
   Expiration 45-95%: exponential decay (passive elastic recoil, tPTEF/tE ~= 0.3),
   with original uncompressed decay values shifted +5% to make room for the hold.
   End-expiratory pause 95-100%: dwell at FRC before next inspiration (~225ms).
   Cycle = 4.5s (~13.3 breaths/min, healthy adult resting rate).
   --breath is a normalized 0..1 signal; the box-shadow calc() expressions
   on .cta-button interpolate between base and peak glow intensity. */
@keyframes cta-breathe {
   0%   { --breath: 0;    }
   5%   { --breath: 0.04; }
   10%  { --breath: 0.15; }
   15%  { --breath: 0.31; }
   20%  { --breath: 0.50; }
   25%  { --breath: 0.69; }
   30%  { --breath: 0.85; }
   35%  { --breath: 0.96; }
   40%  { --breath: 1.00; }
   45%  { --breath: 1.00; }
   50%  { --breath: 0.66; }
   55%  { --breath: 0.44; }
   60%  { --breath: 0.29; }
   65%  { --breath: 0.19; }
   70%  { --breath: 0.12; }
   75%  { --breath: 0.07; }
   80%  { --breath: 0.04; }
   85%  { --breath: 0.02; }
   90%  { --breath: 0.01; }
   95%, 100% { --breath: 0; }
}

.cta-button:hover {
   transform: translateY(-2px);
   animation-play-state: paused;
   box-shadow:
      0 0 0 1px var(--accent),
      0 0 62px rgb(var(--accent-rgb) / 0.6),
      0 0 140px rgb(var(--accent-rgb) / 0.3);
}

.cta-button:active {
   transform: translateY(0);
}

.cta-button:focus-visible {
   outline: 2px solid #fff;
   outline-offset: 3px;
}

/* ========================================
   NAVIGATION BUTTONS
   ======================================== */

@keyframes bounce-smush {
   0%   { transform: translateY(-50%) translateX(0) scaleX(1) scaleY(1); }
   15%  { transform: translateY(-50%) translateX(-10px) scaleX(1.25) scaleY(0.8); }
   35%  { transform: translateY(-50%) translateX(5px) scaleX(0.88) scaleY(1.15); }
   50%  { transform: translateY(-50%) translateX(-3px) scaleX(1.08) scaleY(0.94); }
   65%  { transform: translateY(-50%) translateX(1px) scaleX(0.97) scaleY(1.03); }
   80%  { transform: translateY(-50%) translateX(-0.5px) scaleX(1.02) scaleY(0.99); }
   100% { transform: translateY(-50%) translateX(0) scaleX(1) scaleY(1); animation-fill-mode: forwards; }
}

.slide-nav {
   position: fixed;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
   pointer-events: none;
   z-index: 20;
}

.slide-nav-btn {
   position: absolute;
   top: 50%;
   transform: translateY(-50%);
   width: 44px;
   height: 44px;
   padding: 0;
   background: transparent;
   border: none;
   cursor: pointer;
   pointer-events: auto;
   opacity: 0.4;
   display: flex;
   align-items: center;
   justify-content: center;
   transition: opacity 0.3s ease, transform 0.2s ease;
}

.slide-nav-btn img {
   width: 100%;
   height: 100%;
   object-fit: contain;
   filter: invert(1);
   pointer-events: none;
   transition: filter 0.3s ease;
}

.slide-nav-btn--prev img {
   transform: scaleX(-1);
}

.slide-nav-btn:hover {
   opacity: 1;
}

.slide-nav-btn:hover img {
   filter: invert(1) drop-shadow(0 0 10px rgb(var(--accent-rgb) / 0.85));
}

.slide-nav-btn:active {
   transform: translateY(-50%) scale(0.92);
}

.slide-nav-btn:focus-visible {
   outline: 2px solid var(--accent);
   outline-offset: 4px;
}

.slide-nav-btn--prev {
   left: 22px;
}

.slide-nav-btn--next {
   right: 22px;
}

.slide-nav-btn:disabled {
   opacity: 0.12;
   cursor: not-allowed;
}

/* ========================================
   PROGRESS INDICATOR
   ======================================== */

.slide-progress {
   position: fixed;
   bottom: 36px;
   left: 50%;
   transform: translateX(-50%);
   display: flex;
   gap: 10px;
   z-index: 20;
}

.slide-progress-dot {
   width: 8px;
   height: 8px;
   border-radius: 50%;
   background: rgba(250, 246, 238, 0.22);
   border: none;
   padding: 0;
   cursor: pointer;
   transition: background 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}

.slide-progress-dot:hover {
   background: rgba(250, 246, 238, 0.55);
}

.slide-progress-dot:focus-visible {
   outline: 2px solid var(--accent);
   outline-offset: 3px;
}

.slide-progress-dot.active {
   background: var(--accent);
   transform: scale(1.3);
   box-shadow: 0 0 14px rgb(var(--accent-rgb) / 0.6);
}

/* ========================================
   SLIDE CONTENT ENTRANCE ANIMATION
   Hide children of non-active slides; active slide cascades them in
   with staggered delays. First slide has is-active at page load so
   its content is visible on first paint (no initial fade-in).
   ======================================== */

.slide-text > *,
.slide--splash .slide-content > *,
.slide--cta .slide-content > * {
   opacity: 0;
   transform: translateY(14px);
   transition: opacity 0.7s cubic-bezier(0.2, 0.8, 0.2, 1),
               transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.slide.is-active .slide-text > *,
.slide.is-active.slide--splash .slide-content > *,
.slide.is-active.slide--cta .slide-content > * {
   opacity: 1;
   transform: translateY(0);
}

.slide.is-active .slide-text > *:nth-child(1),
.slide.is-active.slide--splash .slide-content > *:nth-child(1),
.slide.is-active.slide--cta .slide-content > *:nth-child(1) {
   transition-delay: 0.18s;
}
.slide.is-active .slide-text > *:nth-child(2),
.slide.is-active.slide--cta .slide-content > *:nth-child(2) {
   transition-delay: 0.32s;
}
.slide.is-active .slide-text > *:nth-child(3),
.slide.is-active.slide--cta .slide-content > *:nth-child(3) {
   transition-delay: 0.44s;
}
.slide.is-active .slide-text > *:nth-child(4),
.slide.is-active.slide--cta .slide-content > *:nth-child(4) {
   transition-delay: 0.54s;
}
.slide.is-active .slide-text > *:nth-child(5) {
   transition-delay: 0.62s;
}

/* ========================================
   REDUCED MOTION — deck-specific additions
   base.css handles the shared selectors (ambient-grain, ambient-vignette,
   site-auth-btn, page-frame, frame-furniture, frame-numeral, frame-total).
   This block adds deck-specific selectors.
   ======================================== */

@media (prefers-reduced-motion: reduce) {
   .slide-deck,
   .cta-button,
   .slide-text > *,
   .slide--splash .slide-content > *,
   .slide--cta .slide-content > *,
   .slide--reflection .slide-content > *,
   .slide-progress-dot,
   .slide-nav-btn,
   .slide-nav-btn img {
      transition: none !important;
      animation: none !important;
   }

   .slide-text > *,
   .slide--splash .slide-content > *,
   .slide--cta .slide-content > *,
   .slide--reflection .slide-content > * {
      opacity: 1 !important;
      transform: none !important;
   }
}

/* ========================================
   MOBILE: VERTICAL SCROLL STACK
   base.css handles the shared mobile rules (site-header, site-logo,
   site-auth, site-auth-btn, page-frame, frame-furniture, ambient-vignette).
   This block adds deck-specific mobile behavior.
   ======================================== */

@media (max-width: 768px) {
   /* Body stays overflow: hidden on mobile too — the slide-deck is its own
      scroll container (see .slide-deck rules below), so body-level scroll
      would fight deck-level scroll-snap. Keeping body locked also pins the
      page-frame, site-header, and ambient layers to the viewport while the
      deck scrolls underneath. */

   /* Re-reveal the viewport chrome that base.css hides on mobile for other
      pages — but scoped to the landing body so secondary pages (auth, docs,
      blog) keep their current mobile treatment untouched. The frame, furniture,
      and vignette are viewport-fixed, so slides scroll under them while the
      chrome stays put, mirroring desktop's instrument-panel feel.
      landing.js attaches an IntersectionObserver that updates body data-accent
      as the user scrolls, which drives the frame's color transition just like
      click-nav does on desktop. */
   body.landing-body .page-frame {
      display: block;
      border-width: 3px;
   }

   body.landing-body .frame-furniture {
      display: block;
   }

   body.landing-body .ambient-vignette {
      display: block;
   }

   body.landing-body .frame-mark {
      width: 12px;
      height: 12px;
   }

   body.landing-body .frame-mark--tl { top: 12px;    left: 12px; }
   body.landing-body .frame-mark--tr { top: 12px;    right: 12px; }
   body.landing-body .frame-mark--bl { bottom: 12px; left: 12px; }
   body.landing-body .frame-mark--br { bottom: 12px; right: 12px; }

   body.landing-body .frame-position {
      bottom: 20px;
      left: 20px;
      gap: 0.45rem;
   }

   body.landing-body .frame-numeral {
      font-size: 2.4rem;
   }

   body.landing-body .frame-total {
      font-size: 0.6rem;
      letter-spacing: 0.12em;
   }

   .slide-nav,
   .slide-progress {
      display: none;
   }

   /* Slide-deck becomes its own scroll container on mobile: fixed 100vh
      viewport, scroll-snap mandatory on the Y axis. Every scroll gesture
      settles on a slide's top edge. -webkit-overflow-scrolling: touch
      preserves iOS momentum so the snap doesn't feel stuttery. */
   .slide-deck {
      flex-direction: column;
      width: 100%;
      height: 100vh;
      overflow-x: hidden;
      overflow-y: auto;
      scroll-snap-type: y mandatory;
      -webkit-overflow-scrolling: touch;
      transition: none;
   }

   .slide {
      flex: 0 0 auto;
      min-height: 100vh;
      width: 100%;
      border-left: none;
      /* Hairline section delimiter in the slide's own accent — replaces the
         old 25px solid bar, which read as a cheap divider rather than a
         section boundary. var(--accent) resolves per-slide via .slide--magenta
         etc., so each seam picks up the color of the section below. */
      border-top: 1px solid rgb(var(--accent-rgb) / 0.32);
      /* Scroll-snap targets: each slide's top edge is a snap point, and
         scroll-snap-stop: always forces the browser to halt at the very
         first snap point it crosses during a gesture. Without `always` a
         hard fling would skip past two or three slides at once. */
      scroll-snap-align: start;
      scroll-snap-stop: always;
   }

   .slide:first-child {
      border-top: none;
   }

   /* Content padding gets headroom top and bottom so the now-visible frame
      furniture (fixed header up top, frame numeral bottom-left) never crowds
      the copy. 1.75rem sides keeps body text clear of the corner marks. */
   .slide-content {
      padding: 5.5rem 1.75rem 5rem;
   }

   /* Stack split slides on mobile */
   .slide--split {
      flex-direction: column;
      gap: 2.5rem;
      padding: 5.5rem 1.75rem 5rem;
   }

   /* Mirror variant must also collapse to column on mobile.
      Without this, the 2-class .slide--split.slide--mirror selector
      (declared outside the media query) keeps its higher specificity
      row-reverse rule, leaving mirrored slides crammed side-by-side
      at ~130px column width on phones. Matching specificity here wins. */
   .slide--split.slide--mirror {
      flex-direction: column;
   }

   .slide--split .slide-text {
      max-width: 100%;
   }

   /* ASCII art sits below the text on mobile — prose leads, decoration
      follows. The desktop side-by-side rhythm doesn't translate to a narrow
      column; bumping it to the end turns it into a section coda instead. */
   .slide--split .slide-media {
      min-height: 160px;
      order: 0;
   }

   /* ASCII shrinks so a 5-glyph run like "├──┼──┼──┤" doesn't overflow a
      narrow column. clamp is more aggressive than desktop's 7vw. */
   .ascii-art {
      font-size: clamp(2rem, 11vw, 3.75rem);
   }

   .slide-heading {
      font-size: clamp(1.9rem, 7vw, 2.6rem);
   }

   .slide-heading--large {
      font-size: clamp(2.25rem, 9vw, 3.25rem);
   }

   .slide-body {
      font-size: 1rem;
      line-height: 1.75;
   }

   .slide-kicker {
      font-size: 0.66rem;
      letter-spacing: 0.2em;
      margin-bottom: 1.25rem;
   }

   /* Content entrance animation disabled on mobile — scroll provides arrival */
   .slide-text > *,
   .slide--splash .slide-content > *,
   .slide--cta .slide-content > *,
   .slide--reflection .slide-content > * {
      opacity: 1;
      transform: none;
      transition: none;
   }

   /* Reflection padding on mobile matches other slide-content defaults */
   .slide--reflection .slide-content {
      padding: 5.5rem 1.75rem 5rem;
   }

   /* Dual-column reflection collapses to a single column on mobile */
   .slide--reflection .slide-content--dual {
      grid-template-columns: 1fr;
      gap: 2.25rem;
   }

   /* Reflection note is a distinct voice (developer aside) — give it a
      hairline top border so the visual break from the main passage survives
      the grid collapse. Without this, the two blocks read as one continuous
      body. */
   .reflection-note {
      padding-top: 1.75rem;
      border-top: 1px solid rgb(var(--accent-rgb) / 0.24);
   }

   .reflection-note .slide-body {
      font-size: 0.98rem;
   }

   /* CTA button resizing for touch */
   .cta-button {
      height: 60px;
      padding: 0 44px;
      font-size: 0.82rem;
   }

   /* CTA convergence hairline — bring it back, scaled. Desktop uses
      top:-6rem/height:9rem; mobile keeps the same 2:3 ratio at 2/3 scale.
      The hairline → kicker → heading arrival sequence is load-bearing for
      the final slide's "destination" feel and shouldn't be dropped. */
   .slide--cta .slide-content::before {
      display: block;
      top: -4rem;
      height: 6rem;
   }
}

/* ========================================
   LARGE DESKTOP — deck-specific
   base.css handles shared 1400px+ rules (frame-numeral size, frame-mark size,
   frame-position offset).
   ======================================== */

@media (min-width: 1400px) {
   .slide-content {
      max-width: 60ch;
   }

   .slide-heading {
      font-size: 3.5rem;
   }

   .slide-heading--large {
      font-size: 4.5rem;
   }

   .slide-body {
      font-size: 1.15rem;
   }
}
