/* ============================================================
   The Simone Starter Pack 2.0 — members' workbook app
   Faithful build of the design handoff (cream + pink + espresso).
   Plain static CSS, no framework. Tokens per the design spec.
   ============================================================ */

/* Simone's own handwriting (constitution: script is always Simone Sharper) */
@font-face {
  font-family: "Simone Sharper";
  src: url("assets/SimoneSharper-Regular.ttf") format("truetype");
  font-display: swap;
}

:root {
  /* Colors */
  --sp-page:        #ffffff;
  --sp-cream:       #FCEBC7;   /* sidebar / warm surface */
  --sp-kraft:       #F3EAD8;   /* illustration slot fill */
  --sp-pink:        #D40F80;   /* brand/primary: active, links, accents */
  --sp-pink-fill:   #E6118C;   /* large solid fills: buttons, audio bar */
  --sp-pink-btn-hv: #c50d77;   /* hover on pink-filled buttons */
  --sp-pink-lnk-hv: #a80a63;   /* a:hover */
  --sp-pink-tint:   #FFE9F4;   /* chips */
  --sp-yellow:      #FFC42E;   /* highlight, glows, numbers, avatar */
  --sp-amber:       #F5A623;   /* completed dot */
  --sp-yellow-lt:   #FFE08A;   /* ::selection */
  --sp-espresso:    #3A2416;   /* "how it works" panel */
  --sp-espresso-tx: #E8DFD2;
  --sp-ink:         #241E38;   /* headings, primary text */
  --sp-prose:       #35304a;   /* long-form lesson body */
  --sp-muted:       #6a6480;
  --sp-muted-2:     #9a93a8;
  --sp-sidebar-tx:  #3a2f1e;
  --sp-sidebar-mut: #7a6a52;
  --sp-sidebar-cnt: #a08a68;
  --sp-blush:       #F7E5DE;
  --sp-hair:        rgba(36,30,56,0.12);
  --sp-hair-strong: rgba(36,30,56,0.16);

  /* Fields */
  --sp-field-bg:    #FBF8F2;

  /* Type */
  --sp-font:  "Quicksand", system-ui, -apple-system, sans-serif;
  --sp-hand:  "Simone Sharper", "Quicksand", cursive;
  --sp-mono:  "SF Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* Radius */
  --sp-r-card:  20px;
  --sp-r-pill:  32px;
  --sp-r-nav:   12px;
  --sp-r-panel: 28px;
  --sp-r-field: 14px;

  /* Shadow */
  --sp-sh-hover: 0 20px 40px rgba(36,30,56,0.10);
  --sp-sh-soft:  0 12px 30px rgba(36,30,56,0.06);
}

* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  background: var(--sp-page);
  color: var(--sp-ink);
  font-family: var(--sp-font);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--sp-pink); text-decoration: none; }
a:hover { color: var(--sp-pink-lnk-hv); }
::selection { background: var(--sp-yellow-lt); }

/* ---------- App shell ---------- */
.sp-app { display: grid; grid-template-columns: auto 1fr; grid-template-rows: 1fr auto; min-height: 100vh; background: var(--sp-page); }
/* container-type: inline-size turns .sp-main into a query container, so
   rules elsewhere can respond to how much width THIS element actually has
   (via @container) instead of only the viewport (@media). Needed because
   .sp-main's real width isn't just a function of viewport size -- it also
   shrinks by 306px whenever the sidebar is expanded, and a viewport-only
   media query has no way to know that. Added 2026-08-16 alongside the
   .pe-hero container-query fix in part.html; harmless on its own, doesn't
   change any existing layout by itself. */
.sp-main { min-width: 0; container-type: inline-size; }
.sp-main__inner { margin: 0 auto; padding: 56px 52px 40px; }
.sp-main__inner--wide   { max-width: 1080px; }
.sp-main__inner--narrow { max-width: 880px; padding: 46px 40px 60px; }

/* ---------- Sidebar ----------
   .sp-side-rail is the flex item that actually owns the width (and the
   collapse animation); <aside id="side"> fills 100% of it.
   IMPORTANT: this rail must NOT get align-self: flex-start (and must keep
   default flex "stretch"). .sp-side inside it is position: sticky, top: 0
   -- a sticky element can only stay stuck for as long as its containing
   block (this rail) still has height left to scroll through. If the rail
   is shorter than .sp-main's content (which a long lesson page always is,
   often several thousand px), the sidebar runs out of room and un-sticks
   partway down, leaving plain white page below it -- exactly the
   "sidebar cuts off mid-page" bug. Stretch keeps the rail matched to
   .sp-main's full height so the sidebar can stay stuck the whole way down.
   (An earlier version used align-self: flex-start to fix the toggle
   button landing off-screen -- see .sp-side__toggle below for the actual
   fix, which no longer depends on the rail's height at all.) */
.sp-side-rail { position: relative; flex-shrink: 0; width: 306px; transition: width 0.28s ease; }
body.sidebar-collapsed .sp-side-rail { width: 0; }

/* Two-part layout inside <aside>, same idea as the JM workbook's
   .wb-sidebar: a flex-shrink:0 "pinned" header (back capsule + brand)
   that never scrolls, and a flex:1 "scroll" region underneath it that
   carries its own overflow-y -- so only the nav list scrolls, not the
   header. */
.sp-side {
  width: 100%; height: 100vh;
  position: sticky; top: 0;
  overflow: hidden;
  background: var(--sp-cream); color: var(--sp-sidebar-tx);
  display: flex; flex-direction: column;
  transition: opacity 0.2s ease;
}
body.sidebar-collapsed .sp-side { opacity: 0; pointer-events: none; }
/* Extra bottom padding + a faint downward shadow give the pinned header a
   little visual separation from the scrolling list beneath it -- both share
   the same cream background, so without this the seam was hard to read
   while scrolling. */
.sp-side__pinned {
  flex-shrink: 0; padding: 30px 20px 20px; position: relative; z-index: 2;
  box-shadow: 0 6px 10px -8px rgba(58,47,30,0.4);
}
.sp-side__scroll {
  flex: 1; min-height: 0; overflow-y: auto;
  /* Top padding matches the visual weight of a divider (gap + 1px rule +
     gap) so the space above "Start Here" reads the same as the space
     above "The Six Parts" / "Join Joyful Marketing 2.0", which each sit
     right after a .sp-side__divider. */
  padding: 31px 20px 28px;
  display: flex; flex-direction: column; gap: 15px;
}
.sp-side__scroll::-webkit-scrollbar { width: 8px; }
.sp-side__scroll::-webkit-scrollbar-thumb { background: rgba(58,47,30,0.2); border-radius: 20px; }
/* Downloads + "Join Joyful Marketing 2.0" are the only two adjacent top-level
   nav links in the scroll column; tighten the flex-gap between just those two. */
.sp-side__scroll > .sp-nav + .sp-nav { margin-top: -9px; }
/* The Homebase row + its "Before You Start / About This Resource" subnav
   are wrapped together so they get the tight subnav-to-row spacing
   (from .sp-subnav's own margin) instead of the larger gap the
   .sp-side__scroll flex column uses to separate whole sections --
   matching how the six-parts accordion rows (built in JS, each part
   wrapped with its own subnav) already behave. */
.sp-navgroup { display: flex; flex-direction: column; }

/* Single collapse control, used at every breakpoint -- no separate mobile
   hamburger/top-bar/drawer system anymore. Text glyph in a rotating inner
   <span>, not a hand-drawn SVG path -- the same reliable technique already
   used by .sp-nav__caret elsewhere in this file, rather than a bespoke icon
   that turned out to render clipped/off-center.
   position: fixed (viewport-relative), not absolute against the rail: an
   earlier version used `position: absolute; top: 50%` against the rail,
   which needed align-self: flex-start on the rail to keep top: 50% from
   landing thousands of px down -- but that broke the sidebar's own
   position: sticky (see .sp-side-rail above). Fixed positioning sidesteps
   the rail's height entirely, exactly like the mobile block below already
   does, so both bugs are fixed without depending on each other. left is a
   hardcoded 306px matching the rail's expanded width (can't use a
   percentage the way absolute-against-rail did, since fixed positioning
   has no percentage-basis relationship to the rail at all). */
.sp-side__toggle {
  display: flex; align-items: center; justify-content: center;
  position: fixed; top: 50%; left: 306px; transform: translate(-50%, -50%);
  width: 26px; height: 48px;
  background: #fff; border: 1px solid var(--sp-hair-strong); border-radius: 8px;
  color: var(--sp-pink); cursor: pointer; z-index: 70; padding: 0;
  font-size: 16px; font-weight: 700; line-height: 1;
  box-shadow: 0 4px 12px rgba(36,30,56,0.08);
  transition: left 0.28s ease, background 0.2s ease;
}
.sp-side__toggle:hover { background: var(--sp-pink-tint); }
.sp-side__toggle .chev { display: inline-block; pointer-events: none; transition: transform 0.28s ease; }
body.sidebar-collapsed .sp-side__toggle .chev { transform: rotate(180deg); }
/* When collapsed, the rail (and sidebar) width goes to 0, so the toggle's
   left moves to the true left edge -- flush (translate(0, -50%)) instead
   of centered keeps the whole button on-screen there instead of half
   rendering off the edge of the viewport. */
body.sidebar-collapsed .sp-side__toggle { left: 0; transform: translate(0, -50%); border-radius: 0 8px 8px 0; }

/* Mobile-only dimming layer behind the drawer; see the max-width: 900px
   block below for the rest of the drawer behavior. */
.sp-backdrop { display: none; }

/* The brand lockup is the hand-drawn heart (which already carries the words
   "The Simone Starter Pack"), so the wordmark lives in the image rather than
   in text. The alt text keeps it readable to screen readers and to anyone
   browsing with images off. */
.sp-side__brand { display: block; text-align: center; padding: 2px 6px 4px; text-decoration: none; cursor: pointer; }
.sp-side__brandimg {
  display: block; width: 100%; max-width: 190px; height: auto; margin: 0 auto;
  transition: transform .18s ease;
}
.sp-side__brand:hover .sp-side__brandimg { transform: scale(1.03); }
/* The yellow "2.0" chip that used to sit beside the text wordmark was dropped
   2026-08-11 (Simone) once the heart became the lockup. Its .sp-side__chip
   rule went with it -- nothing else used the class. */

/* Small capsule back-link, matching the size of the equivalent
   "Back to the course library" capsule used in Joyful Marketing (see
   .back-capsule in workbook/doors-v20.css) rather than the previous
   full-size pill button. */
.sp-side__back {
  display: inline-flex; align-self: flex-start; align-items: center; gap: 6px;
  margin: 0 0 14px; padding: 5px 14px;
  background: #fff; border: 1px solid rgba(212,15,128,0.18); border-radius: 999px;
  color: var(--sp-pink); font-weight: 500; font-size: 12px;
}
.sp-side__back:hover { background: var(--sp-pink-tint); border-color: rgba(212,15,128,0.3); color: var(--sp-pink); }

/* Margins are intentionally zeroed out here -- the .sp-side flex column's own
   "gap: 8px" is what creates the vertical rhythm between every item (brand,
   group heading, divider, nav rows...), so all of those gaps stay equal. Only
   horizontal margin remains, to inset the text/rule from the sidebar edge. */
.sp-side__group {
  font-family: var(--sp-hand); font-weight: 600; font-size: 30px;
  color: var(--sp-pink); margin: 0 8px; transform: rotate(-1.5deg);
}

/* Thin section-divider rule, same muted gray as unselected nav text --
   separates Start Here / The Six Parts / Join Joyful Marketing 2.0.
   flex-shrink: 0 keeps it from being squeezed to invisible when the sidebar's
   accordion content grows taller than the viewport (a bare 1px-tall flex item
   otherwise has "min-height: auto" and can get shrunk toward 0 under
   pressure -- that's what was causing it to intermittently disappear). */
.sp-side__divider { height: 1px; flex-shrink: 0; background: rgba(122,106,82,0.28); margin: 0 8px; border: 0; }

.sp-nav {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 14px; border-radius: var(--sp-r-nav);
  color: var(--sp-sidebar-mut); font-weight: 600; font-size: 14.5px;
  cursor: pointer;
}
.sp-nav:hover { background: rgba(58,47,30,0.06); color: var(--sp-sidebar-tx); }
.sp-nav--part { color: var(--sp-sidebar-tx); font-weight: 700; }
.sp-nav.is-active { background: var(--sp-pink); color: #fff; font-weight: 700; }
.sp-nav.is-active .sp-dot { background: #fff; }
.sp-nav__label { flex: 1; }
.sp-nav__count { font-size: 11px; color: var(--sp-sidebar-cnt); }
.sp-nav.is-active .sp-nav__count { color: rgba(255,255,255,0.7); }

/* Part header row: the part name links straight to its overview page
   (part.html), while the caret is a separate control that just expands/
   collapses the episode sublist -- two different jobs, so two elements,
   sitting side by side rather than nested (a button can't live inside a
   link tag). */
.sp-navrow { display: flex; align-items: center; gap: 2px; }
.sp-navrow .sp-nav--part { flex: 1; min-width: 0; }
.sp-nav__caret {
  flex-shrink: 0; width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: 8px;
  color: var(--sp-sidebar-mut); font-size: 11px; cursor: pointer;
  transition: transform .15s ease, background .15s ease, color .15s ease;
}
.sp-nav__caret:hover { background: rgba(58,47,30,0.06); color: var(--sp-sidebar-tx); }
.sp-nav__caret.is-open { transform: rotate(180deg); }

.sp-dot { width: 10px; height: 10px; border-radius: 50%; background: rgba(58,47,30,0.25); flex-shrink: 0; position: relative; }
.sp-dot--sm { width: 9px; height: 9px; }
.sp-dot--done { background: var(--sp-amber); }
.sp-dot--prog { background: var(--sp-pink); }
/* Completed part -> a tiny checkmark instead of a plain dot. */
.sp-dot--done::after {
  content: "\2713"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 8px; font-weight: 700; line-height: 1;
}

.sp-subnav {
  margin: 2px 0 6px 20px; padding-left: 14px;
  border-left: 1.5px solid rgba(58,47,30,0.14);
  display: flex; flex-direction: column; gap: 1px;
}
.sp-subnav.is-hidden { display: none; }
.sp-unit {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 12px; border-radius: 9px;
  font-size: 14.5px; font-weight: 500; color: #8a795c;
}
.sp-unit:hover { background: rgba(212,15,128,0.08); }
.sp-unit .sp-udot { width: 8px; height: 8px; border-radius: 50%; background: rgba(58,47,30,0.22); flex-shrink: 0; position: relative; }
.sp-unit.is-current { color: var(--sp-pink); background: rgba(212,15,128,0.1); font-weight: 700; }
.sp-unit.is-current .sp-udot { background: var(--sp-pink); }
.sp-unit.is-done .sp-udot { background: var(--sp-amber); }
/* Completed episode -> a tiny checkmark instead of a plain dot. */
.sp-unit.is-done .sp-udot::after {
  content: "\2713"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 6px; font-weight: 700; line-height: 1;
}

.sp-side__signout {
  margin-top: 10px; padding: 10px 12px 6px;
  border-top: 1px solid rgba(122,106,82,0.15);
}
.sp-side__signout a {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; color: rgba(58,47,30,0.35); text-decoration: none;
  font-weight: 500; transition: color 0.15s;
}
.sp-side__signout a:hover { color: rgba(58,47,30,0.55); }
.sp-side__signout svg { flex-shrink: 0; }

.sp-side__foot { margin-top: auto; }
.sp-side__member {
  display: flex; align-items: center; gap: 10px;
  padding: 12px; margin-top: 20px;
  border-top: 1px solid rgba(58,47,30,0.14);
}
.sp-avatar {
  display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 50%; background: var(--sp-yellow); color: var(--sp-ink);
  font-weight: 700; font-size: 14px;
}
.sp-side__member b { font-weight: 700; font-size: 13.5px; color: var(--sp-sidebar-tx); }
.sp-side__member small { font-size: 12px; color: var(--sp-sidebar-cnt); display: block; }

/* ---------- Shared bits ---------- */
.sp-kicker {
  font-weight: 700; font-size: 13px; letter-spacing: 2.5px; color: var(--sp-pink);
}
.sp-hand { font-family: var(--sp-hand); font-weight: 600; color: var(--sp-pink); }
/* "The Lesson" heading -- sized to match the sidebar's "The Six Parts"
   group heading (.sp-side__group), so the two hand-lettered labels read
   as the same visual weight. */
.sp-hand--lesson-title { font-size: 30px; transform: rotate(-1deg); }
.sp-btn {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 15px 30px; background: var(--sp-pink-fill); color: #fff;
  border: 0; border-radius: 34px; font-family: var(--sp-font);
  font-weight: 700; font-size: 16px; cursor: pointer;
}
.sp-btn:hover { background: var(--sp-pink-btn-hv); color: #fff; }
.sp-btn--sm { padding: 12px 20px; font-size: 14.5px; border-radius: 30px; }
.sp-btn--outline {
  background: transparent; color: var(--sp-ink); border: 2px solid var(--sp-ink);
}
.sp-btn--outline:hover { background: var(--sp-ink); color: #fff; }
.sp-textlink {
  font-weight: 700; font-size: 16px; color: var(--sp-ink);
  border-bottom: 2px solid rgba(36,30,56,0.2); padding-bottom: 2px;
}
.sp-textlink:hover { border-color: var(--sp-pink); color: var(--sp-pink); }

/* ---------- Homebase: hero ---------- */
.sp-hero { display: grid; grid-template-columns: 1.02fr 0.98fr; gap: 40px; align-items: center; }
.sp-hero__h1 {
  font-weight: 700; font-size: 56px; line-height: 1.0;
  margin: 16px 0 0; color: var(--sp-ink); letter-spacing: -1px;
}
.sp-hero__h1 span { color: var(--sp-pink); }
/* #hero-greeting ("Welcome," / "Welcome back,") is a span purely so JS can
   retarget its text for the new-user state -- it was never meant to pick up
   the pink styling above, which is for the name span only. */
.sp-hero__h1 #hero-greeting { color: var(--sp-ink); }
.sp-hero__lede { font-size: 18px; line-height: 1.6; max-width: 460px; margin: 20px 0 0; color: #4c4661; }
.sp-hero__art { position: relative; display: grid; place-items: center; }
.sp-hero__glow {
  position: absolute; width: 74%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,196,46,0.34), rgba(255,196,46,0) 70%);
}
.sp-hero__img { position: relative; width: 100%; max-width: 470px; mix-blend-mode: multiply; }

/* --- Hero box-opening animation --- */
.sp-hero__anim { position: relative; width: 100%; max-width: 470px; display: grid; place-items: center; }
.sp-hero__anim .sp-hero__frame {
  grid-area: 1 / 1; width: 100%; max-width: 470px;
  opacity: 0; transition: opacity 0.9s ease;
}
.sp-hero__anim .sp-hero__frame.is-on { opacity: 1; }

/* rotating sunburst rays over the box mouth (drawn, near-zero weight) */
.sp-hero__rays {
  grid-area: 1 / 1; place-self: center; z-index: 2; pointer-events: none;
  width: 66%; aspect-ratio: 1; border-radius: 50%;
  translate: 0 -6%; scale: 0.55; opacity: 0;
  transition: opacity 0.5s ease, scale 0.9s ease;
  background: repeating-conic-gradient(from 0deg,
    rgba(255,196,46,0.55) 0deg 5deg, rgba(255,196,46,0) 5deg 17deg);
  -webkit-mask: radial-gradient(circle, #000 16%, rgba(0,0,0,0.55) 40%, transparent 68%);
          mask: radial-gradient(circle, #000 16%, rgba(0,0,0,0.55) 40%, transparent 68%);
  mix-blend-mode: screen;
  animation: sp-rays-spin 12s linear infinite;
}
.sp-hero__anim.is-burst .sp-hero__rays { opacity: 0.9; scale: 1; }
@keyframes sp-rays-spin { to { rotate: 360deg; } }

/* sparkles flying up out of the box */
.sp-hero__sparks {
  grid-area: 1 / 1; place-self: center; z-index: 3; pointer-events: none;
  position: relative; width: 72%; aspect-ratio: 1; translate: 0 -6%;
  opacity: 0; transition: opacity 0.4s ease;
}
.sp-hero__anim.is-burst .sp-hero__sparks { opacity: 1; }
.sp-hero__sparks i {
  position: absolute; font-style: normal; color: #FFD84D;
  text-shadow: 0 0 6px rgba(255,196,46,0.8); opacity: 0;
}
.sp-hero__anim.is-burst .sp-hero__sparks i { animation: sp-spark 1.8s ease-out infinite; }
@keyframes sp-spark {
  0%   { opacity: 0; transform: translateY(0) scale(0.4) rotate(0deg); }
  25%  { opacity: 1; }
  70%  { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-58px) scale(1) rotate(35deg); }
}
/* pause/play toggle, always available in the corner -- the box loops on
   its own, but anyone who wants it still can stop it */
.sp-hero__replay {
  position: absolute; top: 4px; right: 4px; z-index: 5;
  width: 26px; height: 26px; border-radius: 50%; padding: 0;
  display: grid; place-items: center; cursor: pointer;
  background: var(--sp-pink); color: #fff; border: none;
  box-shadow: 0 3px 10px rgba(36,30,56,0.18);
  opacity: 0.82; transform: scale(1);
  transition: opacity 0.2s ease, transform 0.2s ease, background 0.15s ease;
}
.sp-hero__replay:hover { opacity: 1; transform: scale(1.08); background: var(--sp-pink-fill, #E6118C); }
.sp-hero__replay svg { width: 13px; height: 13px; display: block; }

@media (prefers-reduced-motion: reduce) {
  .sp-hero__anim .sp-hero__frame { transition: none; }
  .sp-hero__rays, .sp-hero__sparks, .sp-hero__sparks i { animation: none; }
  .sp-hero__replay { transition: opacity 0.2s ease; }
}

.sp-resume {
  display: flex; align-items: center; gap: 18px; margin-top: 28px;
  padding: 18px 22px; background: #fff; border: 1px solid rgba(36,30,56,0.13);
  border-radius: 16px; box-shadow: var(--sp-sh-soft); max-width: 480px;
}
.sp-resume__eyebrow { font-weight: 700; font-size: 11.5px; letter-spacing: 1.5px; color: var(--sp-muted-2); }
.sp-resume__label { font-weight: 700; font-size: 17px; margin-top: 3px; color: var(--sp-ink); }
.sp-resume__count { font-size: 12.5px; font-weight: 600; color: var(--sp-muted-2); margin-top: 8px; }

.sp-progress { height: 5px; background: #EFEBF2; border-radius: 20px; overflow: hidden; margin-top: 11px; }
.sp-progress > i { display: block; height: 100%; background: var(--sp-pink); border-radius: 20px; }
.sp-progress--thin { height: 4px; margin-top: 0; }

.sp-hero__cta { display: flex; flex-wrap: wrap; align-items: center; gap: 22px; margin-top: 26px; }

/* ---------- Homebase: parts grid ---------- */
.sp-section { padding-top: 54px; }
/* New-user Homebase (hero-resume hidden, shorter hero overall) sits a
   touch too far from "Explore in any order you like" with the standard
   54px gap -- trimmed slightly for that state only. Applied via JS
   alongside the other new-user tweaks, home.html. */
.sp-section--tight { padding-top: 34px; }
.sp-section__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap; margin-bottom: 30px;
  border-bottom: 1px solid var(--sp-hair); padding-bottom: 20px;
}
.sp-section__h2 { font-weight: 700; font-size: 44px; margin: 8px 0 0; letter-spacing: -0.5px; }
.sp-section__sub { max-width: 360px; font-size: 15px; line-height: 1.55; color: #4c4661; margin: 0; }

.sp-parts { display: grid; grid-template-columns: repeat(auto-fill, minmax(288px, 1fr)); gap: 26px; }
.sp-part {
  display: flex; flex-direction: column; background: #fff;
  border: 1px solid rgba(36,30,56,0.13); border-radius: var(--sp-r-card);
  overflow: hidden; color: var(--sp-ink);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.sp-part:hover { transform: translateY(-5px); box-shadow: var(--sp-sh-hover); color: var(--sp-ink); }
.sp-part__slot {
  position: relative; height: 236px; overflow: hidden; background-color: var(--sp-kraft);
  background-image: radial-gradient(ellipse at 50% 35%, var(--sp-pink-tint) 0%, var(--sp-kraft) 72%);
  display: grid; place-items: center; padding: 16px;
}
.sp-part__badge {
  position: absolute; top: 14px; left: 14px; z-index: 1;
  display: flex; align-items: baseline; gap: 6px; font-weight: 700;
}
.sp-part__badge span:first-child { font-size: 11px; letter-spacing: 1px; color: #9a8a6c; }
.sp-part__badge span:last-child { font-size: 21px; color: var(--sp-pink); }
.sp-part__slot img {
  position: absolute; top: 16px; right: 16px; bottom: 0; left: 16px;
  width: calc(100% - 32px); height: calc(100% - 16px);
  object-fit: contain; object-position: center center;
}
/* Parts 3 (frame) and 6 (plunger) use near-full-bleed photos with almost
   no transparent margin, unlike the other four parts' more spacious
   illustrations -- so at wider desktop card widths, where the fixed
   236px slot height is the binding constraint, these two photos fill
   the slot corner-to-corner and sit right under the "PART N" badge,
   making it hard to read. On narrow (mobile) cards this isn't an issue
   -- card width becomes the binding constraint instead, so the photo
   renders smaller with natural clearance at the top. Fix: on desktop
   only, nudge the photo down slightly so there's always a clear strip
   of the kraft background behind the badge, without touching mobile
   (which already looks right) or the other four parts' spacing. */
@media (min-width: 901px) {
  .sp-part__slot img { top: 26px; height: calc(100% - 26px); }
}
/* All six part photos share one uniform slot height so the row of cards
   lines up cleanly -- same photo size, same headline baseline, same
   caption baseline per row. Previously this was tiered per part (186 /
   206 / 224px) to crop tighter around each object, but that made photo
   height -- and therefore the title/caption start position -- differ
   card to card. object-fit:cover still crops each (untouched, correctly
   proportioned) image from the top, full width preserved, nothing
   stretched; only the amount shown differs slightly by image now. */
.sp-part__ph {
  text-align: center; font-family: var(--sp-mono); font-size: 10.5px;
  line-height: 1.6; color: #8a795c; max-width: 200px; letter-spacing: 0.2px;
}
.sp-part__ph b { display: block; font-weight: 700; letter-spacing: 1px; margin-bottom: 5px; color: #b0a184; }
.sp-part__body { padding: 22px 24px 24px; display: flex; flex-direction: column; flex: 1; }
.sp-part__title { font-weight: 700; font-size: 25px; line-height: 1.1; margin: 0; letter-spacing: -0.3px; min-height: 56px; display: flex; align-items: flex-start; }
.sp-part__desc { font-size: 14.5px; line-height: 1.55; margin: 9px 0 0; color: #4c4661; flex: 1; }
.sp-part__meta { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; }
.sp-part__meta b { font-weight: 700; font-size: 13px; color: var(--sp-muted-2); }
.sp-part__meta span { font-weight: 700; font-size: 13.5px; color: var(--sp-pink); }
.sp-part__prog-wrap { margin-top: 18px; }

/* ---------- Homebase: before you start (letter) ---------- */
.sp-letter {
  background: #fff; border: 1px solid rgba(36,30,56,0.13);
  border-radius: var(--sp-r-panel); padding: 44px 50px 40px; max-width: 640px;
}
.sp-letter__h2 { font-weight: 700; font-size: 32px; margin: 0 0 20px; letter-spacing: -0.4px; color: var(--sp-ink); }
/* Simone's portrait sits at the FOOT of the letter, under the handwritten
   sign-off -- it used to be a 96px thumbnail beside the heading (Simone,
   2026-08-12: "make my photo much bigger and put it in the bottom"). The
   .sp-letter__intro flex row and .sp-letter__photo thumbnail it needed went
   with it; nothing else in the app used either class. */
.sp-letter__portrait { margin: 28px 0 0; }
.sp-letter__portrait img {
  display: block; width: 100%; max-width: 340px; height: auto; margin: 0 auto;
  border-radius: 18px; box-shadow: var(--sp-sh-soft);
}
.sp-letter p { font-size: 16px; line-height: 1.7; color: #4c4661; margin: 0 0 16px; }
.sp-letter p:last-child { margin: 0; }
.sp-letter__sign { margin-top: 4px; }
.sp-letter__sign .sp-hand { font-size: 29px; font-weight: 400; line-height: 1.15; display: inline-block; margin-top: 2px; }

/* ---------- Homebase: how it works ---------- */
.sp-how {
  background: var(--sp-ink); border-radius: var(--sp-r-panel);
  padding: 50px 50px 54px; color: #FBF5EC; position: relative; overflow: hidden;
}
.sp-how .sp-kicker { color: var(--sp-yellow); }
.sp-how__h2 { font-weight: 700; font-size: 42px; margin: 10px 0 38px; letter-spacing: -0.5px; }
.sp-how__cols { display: grid; grid-template-columns: repeat(3, 1fr); position: relative; }
.sp-how__col { padding: 4px 30px; border-right: 1px solid rgba(255,255,255,0.14); }
.sp-how__col:first-child { padding-left: 0; }
.sp-how__col:last-child { padding-right: 0; border-right: 0; }
.sp-how__num { font-weight: 700; font-size: 27px; color: var(--sp-yellow); }
.sp-how__col h3 { font-weight: 700; font-size: 19px; line-height: 1.3; margin: 12px 0 8px; min-height: 50px; }
.sp-how__col p { font-size: 14.5px; line-height: 1.6; color: var(--sp-espresso-tx); margin: 0; }

/* ---------- Homebase: JM band + footer ---------- */
.sp-band {
  display: flex; align-items: center; justify-content: space-between; gap: 28px;
  flex-wrap: wrap; background: var(--sp-blush); border-radius: 24px; padding: 32px 40px;
}
.sp-band__h3 { font-weight: 700; font-size: 28px; margin: 8px 0 0; line-height: 1.12; letter-spacing: -0.3px; }
.sp-band__h3 em { font-style: italic; }
.sp-band p { font-size: 14.5px; line-height: 1.55; color: #6a5a52; margin: 10px 0 0; }

.sp-foot {
  margin-top: 30px; padding: 22px 0 10px;
  display: flex; flex-direction: column; gap: 14px;
  border-top: 1px solid rgba(36,30,56,0.1);
}
.sp-foot__row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.sp-foot b { font-weight: 700; font-size: 15px; }
.sp-foot b span { color: var(--sp-pink); }
.sp-foot small { font-size: 13px; color: var(--sp-muted-2); }
.sp-foot .sp-foot__art {
  font-family: var(--sp-hand); font-size: 22px; color: var(--sp-pink);
  text-align: center; letter-spacing: 0.2px;
}
.sp-foot .sp-foot__copyright {
  font-size: 12px; color: var(--sp-muted-2); text-align: center;
}
.sp-foot--global {
  grid-column: 1 / -1; margin-top: 0;
  flex-direction: row; align-items: center;
  padding: 16px 22px; gap: 0;
}
.sp-foot--global .sp-foot__copyright { flex: 1; }
.sp-foot--global .sp-foot__art { display: none; }
/* Mobile: sign-out left + print right on same row, copyright below */
@media (max-width: 900px) {
  .sp-foot--global {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    padding: 16px 22px;
  }
  .sp-foot--global .sp-foot__signout {
    grid-row: 1; grid-column: 1;
    justify-self: start; align-self: center;
    margin: 0;
  }
  .sp-foot--global .sp-foot__copyright {
    grid-row: 2; grid-column: 1 / -1;
    text-align: center;
    flex: unset;
  }
}
.sp-foot__signout {
  display: inline-flex; align-items: center; gap: 4px;
  align-self: flex-start;
  background: transparent; color: var(--sp-muted-2);
  padding: 4px 11px; border-radius: 999px;
  font-family: 'Quicksand', sans-serif; font-size: 10px;
  text-decoration: none; border: 1px solid currentColor;
  opacity: 0.55; transition: opacity 0.2s;
}
.sp-foot__signout:hover { opacity: 0.85; }
.sp-foot__signout svg { flex-shrink: 0; }

/* ---------- Lesson ---------- */
.sp-crumb { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 13.5px; color: var(--sp-muted-2); }
.sp-crumb a { color: var(--sp-muted-2); }
.sp-crumb a:hover { color: var(--sp-pink); }
.sp-crumb span.here { color: var(--sp-pink); }

/* The part illustration used to sit inline in the lesson hero, but it's really
   part-level decoration (the same one image, reused across every episode in
   a part) rather than anything specific to this lesson -- so it lives on the
   Part overview page (part.html) instead, where it gets a proper, uncramped
   showcase. Lesson pages stay lean: badge, then the player leads straight in.
   The on-screen title is dropped too (the player already says it) but the h1
   itself stays in the markup, visually hidden, so screen readers + the
   printed worksheet still get a real heading -- see .sp-lead__h1 below and
   its print-kit override. */
.sp-lead { margin-top: 18px; }

/* audio "coming soon" state for episodes not yet published */
.sp-soon-audio {
  display: flex; flex-direction: column; gap: 6px;
  background: var(--sp-kraft); border-radius: 16px; padding: 20px 24px; margin-top: 8px;
}
.sp-soon-audio b { font-size: 14px; font-weight: 600; color: var(--sp-pink); }
.sp-soon-audio span { font-size: 15px; line-height: 1.55; color: var(--sp-muted); }
.sp-lead__tags { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; font-size: 13px; letter-spacing: 2px; color: var(--sp-pink); }
.sp-lead__tags .chip { background: var(--sp-pink-tint); border-radius: 20px; padding: 5px 12px; }
/* the episode title, sitting next to the chip -- a touch bigger and looser
   than the chip's all-caps tracking, since it's reading as a title here,
   not a short label. Magenta to match the brand pink used on the chip. */
.sp-lead__tags .part { color: var(--sp-pink); font-size: 15px; letter-spacing: 0.3px; }
/* on screen: not shown (the player right below already carries the title) --
   kept in the DOM, visually hidden, so it still exists for screen readers and
   is restored to a normal visible heading for print (see print-kit.css). */
.sp-lead__h1 {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.sp-lead__sub { font-size: 18px; color: var(--sp-muted); margin: 10px 0 0; font-weight: 500; }

.sp-audio {
  margin-top: 28px; display: flex; align-items: center; gap: 18px;
  background: var(--sp-pink-fill); border-radius: 18px; padding: 18px 22px; color: #fff;
}
.sp-audio__btn {
  flex-shrink: 0; display: grid; place-items: center; width: 52px; height: 52px;
  border-radius: 50%; background: #fff; color: var(--sp-pink-fill); cursor: pointer; font-size: 18px; border: 0;
}
.sp-audio__btn:hover { background: #FFD1E8; }
.sp-audio__body { flex: 1; min-width: 0; }
.sp-audio__title { font-weight: 700; font-size: 14.5px; }
.sp-audio__row { display: flex; align-items: center; gap: 10px; margin-top: 9px; }
.sp-audio__time { font-size: 11.5px; color: rgba(255,255,255,0.85); font-variant-numeric: tabular-nums; }
.sp-audio__track { flex: 1; height: 5px; background: rgba(255,255,255,0.16); border-radius: 20px; overflow: hidden; }
.sp-audio__track > i { display: block; height: 100%; width: 34%; background: var(--sp-yellow); border-radius: 20px; }
.sp-audio__embed { margin-top: 14px; }              /* real embed slot */
.sp-embed-note { font-family: var(--sp-mono); font-size: 10.5px; color: #b0a8bc; margin-top: 8px; letter-spacing: 0.3px; }

/* Disclaimer under the player for an episode that mentions a since-closed
   program (see data.js `episodeNote`). Quiet sans, sentence case, muted --
   not the mono-caps "costume" the constitution bans for small labels. */
.sp-episode-note { font-family: var(--sp-font); font-size: 12.5px; line-height: 1.5; color: var(--sp-muted); margin-top: 10px; }
.sp-episode-note a { font-size: inherit; }

.sp-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.sp-links a {
  display: inline-flex; align-items: center; gap: 8px; padding: 10px 16px;
  border: 1.5px solid var(--sp-hair-strong); border-radius: 30px;
  font-weight: 700; font-size: 14px; color: var(--sp-ink);
}
.sp-links a:hover { border-color: var(--sp-pink); color: var(--sp-pink); }

.sp-lesson { margin-top: 40px; padding-top: 30px; border-top: 1px solid var(--sp-hair); }
.sp-lesson__body { margin-top: 16px; }
.sp-lesson__body p { font-size: 18.5px; line-height: 1.74; color: var(--sp-prose); margin: 0 0 20px; }
.sp-lesson__body blockquote {
  margin: 30px 0; padding: 4px 0 4px 24px; border-left: 4px solid var(--sp-yellow);
  font-weight: 700; font-size: 25px; line-height: 1.3; color: var(--sp-ink); letter-spacing: -0.4px;
}
.sp-lesson__list { margin: 0 0 20px; padding-left: 26px; }
.sp-lesson__list--plain { list-style: none; padding-left: 0; }
.sp-lesson__list li { font-size: 18.5px; line-height: 1.62; color: var(--sp-prose); margin: 0 0 12px; padding-left: 4px; }
.sp-lesson__list li::marker { color: var(--sp-pink); font-weight: 700; }
.sp-lesson__list li:has(.sp-lesson__list-note) { margin-bottom: 22px; }
.sp-lesson__list-note { display: block; margin-top: 6px; font-size: 15.5px; line-height: 1.55; color: var(--sp-muted-2); font-weight: 400; }
.sp-ep-link { color: var(--sp-pink); font-weight: 700; text-decoration: none; border-bottom: 1.5px solid rgba(212,15,128,0.35); }
.sp-ep-link:hover { border-color: var(--sp-pink); color: var(--sp-pink-lnk-hv); }

.sp-lesson__img { margin: 32px 0; }
.sp-lesson__img img {
  width: 100%; display: block; border-radius: 16px;
  box-shadow: var(--sp-sh-soft); border: 1px solid var(--sp-hair);
}
.sp-lesson__img figcaption { margin-top: 10px; font-size: 13.5px; color: var(--sp-muted-2); text-align: center; }

/* Part headings that link out to the part overview page: look exactly like
   the plain heading until hover, so it doesn't read as a normal inline link. */
.sp-lesson__h a { color: inherit; text-decoration: none; }
.sp-lesson__h a:hover { color: var(--sp-pink); }

.sp-lesson__divider { display: flex; justify-content: center; align-items: center; gap: 10px; margin: 34px 0; }
.sp-lesson__divider::before, .sp-lesson__divider::after { content: ""; flex: 1; height: 1px; background: var(--sp-hair); }
.sp-lesson__divider span { width: 6px; height: 6px; border-radius: 50%; background: var(--sp-pink); opacity: 0.5; }

/* Footnote-style citation links, e.g. "$16.7 trillion[1]" */
.sp-lesson__body sup.sp-cite { margin-left: 1px; }
.sp-lesson__body sup.sp-cite a {
  color: var(--sp-pink); font-weight: 700; text-decoration: none;
  font-size: 11px; padding: 0 1px;
}
.sp-lesson__body sup.sp-cite a:hover { text-decoration: underline; }

/* Print-only "Sources" list -- see lesson.html for how `lesson.sources` builds this. */
.sp-print-sources { display: none; }
@media print {
  .sp-print-sources {
    display: block; margin-top: 30px; padding-top: 18px; border-top: 1px solid var(--sp-hair);
  }
  .sp-print-sources h3 { font-size: 14px; font-weight: 700; margin: 0 0 8px; color: var(--sp-ink); }
  .sp-print-sources ol { margin: 0; padding-left: 20px; }
  .sp-print-sources li { font-size: 10.5px; line-height: 1.6; color: #4c4661; word-break: break-all; }
}

.sp-lesson__h {
  position: relative; margin: 20px 0 20px;
  font-weight: 800; font-size: 21px; line-height: 1.3; color: var(--sp-ink); letter-spacing: -0.3px;
}
.sp-lesson__body > .sp-lesson__h:first-child { margin-top: 0; }

.sp-exercise {
  margin-top: 30px; background: #FFF6DF; border: 1.5px solid #F3D992;
  border-radius: 18px; padding: 22px 26px;
}
.sp-exercise .sp-hand { color: #b8860b; font-size: 17px; transform: rotate(-1deg); display: inline-block; }
.sp-exercise p { font-size: 16px; line-height: 1.6; color: #5c4a1e; margin: 8px 0 0; font-weight: 500; }

.sp-turn { margin-top: 46px; padding-top: 34px; border-top: 1px solid var(--sp-hair); }
.sp-turn__head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.sp-turn__head h2 { font-weight: 700; font-size: 36px; margin: 0; letter-spacing: -1px; }
.sp-turn__head .sp-hand { font-size: 17px; }
.sp-turn__intro { font-size: 16px; color: var(--sp-muted); margin: 10px 0 0; }
.sp-questions { display: flex; flex-direction: column; gap: 26px; margin-top: 28px; }
.sp-q__head { display: flex; gap: 13px; align-items: flex-start; }
.sp-q__num {
  flex-shrink: 0; display: grid; place-items: center; width: 28px; height: 28px;
  border-radius: 50%; background: var(--sp-pink-tint); color: var(--sp-pink);
  font-weight: 700; font-size: 14px; margin-top: 2px;
}
.sp-q__text { font-size: 16.5px; line-height: 1.55; font-weight: 600; color: var(--sp-ink); margin: 0; }
.sp-q__label {
  font-size: 17.5px; line-height: 1.5; font-weight: 700; color: var(--sp-ink);
  margin: 12px 0 -6px; padding-top: 20px; border-top: 1px dashed var(--sp-hair-strong);
}
.sp-questions > .sp-q__label:first-child { padding-top: 0; border-top: none; margin-top: 0; }
.sp-q__label--center { text-align: center; }
.sp-tracker__subtext { display: block; font-size: 14px; font-weight: 400; color: var(--sp-muted-2); margin-top: 6px; }
/* fill-in-the-blank inline underline, used in place of literal "____" runs
   in question copy -- a plain underscore string renders as a broken/dotted
   line in Quicksand, so this swaps in one continuous solid rule instead. */
.sp-blank {
  display: inline-block; width: 7em; height: 1px; margin: 0 2px -3px;
  border-bottom: 1.5px solid currentColor;
}
.sp-q__field { margin-top: 12px; padding-left: 41px; }
textarea.sp-field {
  width: 100%; min-height: 108px; resize: vertical; font-family: var(--sp-font);
  font-size: 16px; line-height: 1.6; color: var(--sp-ink); background: var(--sp-field-bg);
  border: 1.5px solid var(--sp-hair-strong); border-radius: var(--sp-r-field);
  padding: 14px 16px; outline: none; transition: border-color 0.15s ease, box-shadow 0.15s ease;
  overflow-y: hidden; /* box auto-grows to fit typed content (see print-kit.js) */
}
textarea.sp-field:focus { border-color: var(--sp-pink); box-shadow: 0 0 0 3px rgba(212,15,128,0.12); background: #fff; }
textarea.sp-field::placeholder { color: #a89fb2; }
.sp-turn__note {
  margin: 30px 0 0; padding: 18px 20px; border-radius: var(--sp-r-field);
  background: var(--sp-pink-tint); color: var(--sp-prose);
  font-size: 16.5px; line-height: 1.6; font-weight: 500;
}

/* Lesson-specific bonus callout (e.g. Ep 2's plug for the free-standing
   Garbage Post Challenge site). Sits in the same slot as .sp-exercise
   ("try it this week") but in brand pink, since it's an outbound offer
   rather than an in-lesson instruction. */
.sp-lesson-promo {
  margin-top: 30px; background: var(--sp-pink-tint); border: 1.5px solid #F7B9DA;
  border-radius: var(--sp-r-card); padding: 24px 28px;
}
.sp-lesson-promo .sp-hand { font-size: 16px; display: inline-block; transform: rotate(-1deg); }
.sp-lesson-promo__title {
  font-size: 19px; font-weight: 700; color: var(--sp-ink); line-height: 1.35;
  margin: 6px 0 8px;
}
.sp-lesson-promo__text { font-size: 15.5px; line-height: 1.6; color: var(--sp-prose); margin: 0 0 14px; }
.sp-lesson-promo__list { margin: 0 0 18px; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 7px; }
.sp-lesson-promo__list li {
  font-size: 15px; line-height: 1.5; color: var(--sp-prose); font-weight: 500;
  display: flex; gap: 9px; align-items: baseline;
}
.sp-lesson-promo__list li::before { content: "✓"; color: var(--sp-pink); font-weight: 700; flex-shrink: 0; }
.sp-lesson-promo__cta {
  display: inline-block; font-weight: 700; font-size: 15px; color: #fff;
  background: var(--sp-pink-fill); padding: 12px 22px; border-radius: 999px;
  text-decoration: none; transition: transform 0.15s ease, background 0.15s ease;
}
.sp-lesson-promo__cta:hover { background: var(--sp-pink); transform: translateY(-2px); }

.sp-lesson-nav {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 44px; padding-top: 26px; border-top: 1px solid var(--sp-hair);
}
/* Previous/Next/Mark as done render at an identical FIXED size (width AND
   height, not min-width/auto-height) regardless of their text, so "Mark as
   done" vs "✓ Done for now" vs "← Previous" can never differ — box-sizing:
   border-box (set globally, line 60) means the border on .sp-prev/.sp-done-btn
   is absorbed inside that fixed box rather than adding to it, so .sp-next
   (borderless) still matches exactly. Tightened down from the old
   210px/44-ish-implicit sizing per Julie, 2026-09-01 — "shorter" pills, same
   rule at both breakpoints. text-overflow:ellipsis is just a safety net;
   nothing currently in use should ever need it. */
.sp-prev, .sp-next, .sp-done-btn, .sp-lesson-nav__spacer {
  width: 150px; height: 40px;
  flex-shrink: 0;
  padding: 0 14px;
  font-size: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sp-prev {
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--sp-muted);
  border: 1.5px solid var(--sp-hair-strong); border-radius: var(--sp-r-pill);
  font-weight: 700;
}
.sp-prev:hover { border-color: var(--sp-pink); color: var(--sp-pink); }
/* placeholder keeps the three-column layout balanced when there's no Previous. */
.sp-lesson-nav__spacer { visibility: hidden; font-weight: 700; }
.sp-done-btn {
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid rgba(36,30,56,0.2); background: #fff; color: var(--sp-ink);
  border-radius: var(--sp-r-pill); font-family: var(--sp-font); font-weight: 700; cursor: pointer;
}
.sp-done-btn.is-done { background: #FFF4DE; color: #96660A; border-color: rgba(245,166,35,0.45); }
.sp-next { display: inline-flex; align-items: center; justify-content: center; background: var(--sp-pink-fill); color: #fff; border-radius: var(--sp-r-pill); font-weight: 700; }
.sp-next:hover { background: var(--sp-pink-btn-hv); color: #fff; }
/* This media query must stay AFTER the .sp-prev/.sp-done-btn/.sp-next base
   rules above — same specificity, so if it were placed earlier in the file
   (as it briefly was) the later unconditional base rules would win the
   cascade on mobile and silently cancel these overrides out. 2026-09-01. */
@media (max-width: 560px) {
  /* Explicit 2-row grid instead of relying on flex-wrap: at this small a
     fixed size, all three buttons can fit on one flex line together, which
     would wedge Mark as done in next to Next instead of giving it its own
     row (flex-wrap only wraps when content doesn't fit — the same bug
     surfaced first on JM's equivalent buttons, 2026-09-01). Grid positions
     are unconditional, so Previous/Next always sit top-left/top-right and
     Mark as done always centers on its own row below, regardless of
     viewport width. */
  .sp-lesson-nav {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px 10px;
  }
  .sp-lesson-nav__spacer { display: none; }
  .sp-prev, .sp-next, .sp-done-btn { width: 122px; height: 34px; padding: 0 10px; font-size: 12px; }
  .sp-prev { grid-column: 1; grid-row: 1; justify-self: start; }
  .sp-next { grid-column: 2; grid-row: 1; justify-self: end; }
  .sp-done-btn { grid-column: 1 / -1; grid-row: 2; justify-self: center; }
  /* Keep "Apple Podcasts" + "Spotify" together on one line by dropping
     the "Prefer your own app?" label to its own line above them. */
  .sp-listen__label { flex-basis: 100%; }
}

/* Before You Start has no "Previous" (it's the first page) -- just one
   custom-copy button ("Next: A Quick Tour →") that needs to sit at the
   right edge of the row at every width. The generic .sp-lesson-nav rules
   above assume two children (or the fixed-size .sp-prev/.sp-next pair) and
   only right-align a lone child via flex's justify-content on wide
   screens -- under the 560px breakpoint they switch to a 2-column grid
   that auto-places a single unmatched child (plain .sp-btn) into the LEFT
   column, undoing the alignment. This modifier keeps flex + right-alignment
   unconditionally so the single button never reflows left. */
.sp-lesson-nav--next-only { justify-content: flex-end; }
@media (max-width: 560px) {
  .sp-lesson-nav--next-only { display: flex; }
}

/* ---------- "coming soon" placeholder lesson ---------- */
.sp-soon { margin-top: 40px; padding: 40px 32px; text-align: center; background: var(--sp-cream); border-radius: var(--sp-r-card); }
.sp-soon h2 { font-weight: 700; font-size: 26px; margin: 0 0 8px; color: var(--sp-ink); }
.sp-soon p { font-size: 16px; line-height: 1.6; color: var(--sp-sidebar-mut); margin: 0 auto; max-width: 420px; }

/* ---------- Mobile menu bar ----------
   A fixed bar at the top of the screen on phones, carrying the hamburger icon,
   the course brand mark, and the words that say what it is. Hidden entirely on desktop. */
.sp-mobile-bar { display: none; }
@media (max-width: 900px) {
  .sp-mobile-bar {
    display: flex; align-items: center; gap: 10px;
    position: fixed; top: 0; left: 0; right: 0; height: 50px; z-index: 65;
    margin: 0; padding: 0 14px; border: none;
    border-bottom: 1px solid rgba(58,47,30,0.1);
    background: var(--sp-cream); box-shadow: 0 2px 10px rgba(58,47,30,0.06);
    color: var(--sp-pink); cursor: pointer;
    font: inherit; text-align: left;
  }
  .sp-mobile-bar__icon {
    width: 24px; height: 24px; object-fit: contain; flex-shrink: 0;
  }
  .sp-mobile-bar__text {
    flex: 1; min-width: 0;
    font-family: var(--sp-font); font-size: 14.5px;
    font-weight: 700; color: var(--sp-ink); line-height: 1.2;
  }
  .sp-mobile-bar__text small {
    display: block; font-size: 10px; font-weight: 700;
    letter-spacing: 0.8px; text-transform: uppercase;
    color: rgba(58,47,30,0.4); line-height: 1.2;
  }
  .sp-mobile-bar + .sp-app .sp-main__inner,
  .sp-mobile-bar + .sp-app .sp-main__inner--narrow { padding-top: 70px; }
  body.sidebar-collapsed .sp-mobile-bar + .sp-app .sp-side__toggle { display: none !important; }
  body:not(.sidebar-collapsed) .sp-mobile-bar { display: none; }
}
@media print { .sp-mobile-bar { display: none !important; } }

/* ---------- Responsive: mobile-first collapse ----------
   Still driven by the one .sp-side__toggle -- no separate hamburger/top-bar
   -- but on narrow screens the sidebar switches from "real column that
   shares width with .sp-main" to a fixed overlay drawer. A real column
   was resizing/squeezing the page content every time it opened, which
   is exactly what a flex sibling changing width does; taking it out of
   flow with position: fixed means .sp-main never sees it and never
   reflows because of it. */
@media (max-width: 900px) {
  .sp-side-rail { width: 0; }
  .sp-side {
    position: fixed; top: 0; left: 0; z-index: 60;
    width: min(306px, 84vw); max-width: 84vw;
    height: 100vh; height: 100dvh;  /* dvh = the actually-visible height on iOS, so the
                                       nav scrolls fully instead of hiding its bottom items
                                       (Downloads / Join JM) behind the Safari toolbar */
    transform: translateX(-100%);
    transition: transform 0.28s ease;
    box-shadow: 0 0 44px rgba(36,30,56,0.24);
  }
  body:not(.sidebar-collapsed) .sp-side { transform: translateX(0); opacity: 1; pointer-events: auto; }
  .sp-side__toggle {
    position: fixed; top: 50%; left: 0; transform: translate(0, -50%);
    border-radius: 0 8px 8px 0;
    transition: left 0.28s ease, background 0.2s ease;
  }
  body:not(.sidebar-collapsed) .sp-side__toggle { left: min(306px, 84vw); transform: translate(-50%, -50%); }
  .sp-backdrop {
    display: block; position: fixed; inset: 0; z-index: 55;
    background: rgba(36,30,56,0.42); opacity: 0; pointer-events: none;
    transition: opacity 0.28s ease;
  }
  body:not(.sidebar-collapsed) .sp-backdrop { opacity: 1; pointer-events: auto; }
  body:not(.sidebar-collapsed) { overflow: hidden; }
  .sp-side__pinned { padding-top: 20px; }
  .sp-side__brand { padding: 0; }
  /* A little extra left clearance, scoped to mobile only (this is NOT
     touching desktop padding, which is what caused misalignment last
     round) -- the collapsed sidebar toggle sits fixed at the true left
     edge (0-26px), and everything below is now centered rather than
     hugging that edge, but on a narrow phone the centered block can still
     get close enough to overlap it without this. */
  .sp-main__inner, .sp-main__inner--narrow { padding: 32px 20px 22px 20px; }
  /* Full center, not just a centered block with left-aligned text inside
     it -- that hybrid didn't hold up once real content (buttons, a card,
     a wrapping CTA row) was in the mix: the "Continue the course" button
     and "How it works" link ended up wrapping and left-stuck, colliding
     with the sidebar toggle. Centering everything (headline, copy, the
     resume card, the button row, and the "Explore in any order" section
     head below) reads as intentional at this in-between width instead of
     looking like a narrow column accidentally stranded on the left. */
  .sp-hero { grid-template-columns: 1fr; gap: 28px; max-width: 480px; margin: 0 auto; text-align: center; }
  .sp-hero__art { order: -1; justify-items: center; }
  .sp-hero__lede { margin-left: auto; margin-right: auto; }
  .sp-resume { margin-left: auto; margin-right: auto; text-align: left; }
  .sp-hero__cta { justify-content: center; }
  .sp-hero__h1 { font-size: 40px; }
  .sp-section__head { flex-direction: column; align-items: center; text-align: center; }
  .sp-section__h2 { font-size: 32px; }
  .sp-how { padding: 32px 26px 36px; }
  .sp-how__cols { grid-template-columns: 1fr; gap: 24px; }
  .sp-how__col { padding: 0 0 24px; border-right: 0; border-bottom: 1px solid rgba(255,255,255,0.14); }
  .sp-how__col:last-child { padding-bottom: 0; border-bottom: 0; }
  .sp-how__col h3 { min-height: 0; }
  .sp-lead__h1 { font-size: 33px; }
  .sp-letter { padding: 32px 26px 30px; }
  .sp-letter__h2 { font-size: 27px; }
  .sp-letter__portrait { margin-top: 24px; }
  .sp-letter__portrait img { max-width: 260px; }
}

/* ===== 10x10 challenge tracker (Ep 2) ===== */
.sp-tracker { margin: 4px 0 22px; break-inside: avoid; text-align: center; }
.sp-tracker__grid {
  display: grid; grid-template-columns: repeat(10, 1fr); gap: 6px;
  max-width: 480px; margin: 0 auto;
}
.sp-tracker__cell {
  font-family: inherit; font-size: 12px; font-weight: 600; color: var(--sp-muted);
  aspect-ratio: 1; width: 100%; border: 1px solid rgba(36,30,56,0.16); border-radius: 7px;
  background: #fff; cursor: pointer; padding: 0; transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.sp-tracker__cell:hover { border-color: var(--sp-pink); }
.sp-tracker__cell.is-on { background: var(--sp-pink); border-color: var(--sp-pink); color: #fff; }
.sp-tracker__count { margin: 10px 0 0; font-size: 13px; font-weight: 600; color: var(--sp-muted-2); }
.sp-tracker__divider { border-top: 1px dashed var(--sp-hair-strong); margin: 18px 0 4px; }
.sp-tracker__celebrate {
  display: none; margin: 12px auto 0; padding: 10px 20px; border-radius: var(--sp-r-pill);
  background: var(--sp-pink-tint); color: var(--sp-pink); font-weight: 700; font-size: 15px;
  text-align: center; width: fit-content;
}
.sp-tracker__celebrate.is-on { display: block; animation: sp-tracker-pop .5s ease; }
@keyframes sp-tracker-pop {
  0% { transform: scale(0.85); opacity: 0; }
  60% { transform: scale(1.06); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@media print {
  .sp-tracker__celebrate { display: none !important; }
}
@media (max-width: 560px) {
  .sp-tracker__grid { max-width: 100%; gap: 4px; }
  .sp-tracker__cell { font-size: 10px; border-radius: 5px; }
}
@media print {
  /* aspect-ratio-based sizing doesn't reliably compute a height inside CSS
     Grid during headless/print rendering (Julie, 2026-08-18: cells were
     printing invisible -- present in the DOM, zero height). Force an
     explicit height here instead of relying on aspect-ratio for print. */
  .sp-tracker__grid { grid-auto-rows: 34px !important; }
  .sp-tracker__cell {
    display: inline-block !important;
    aspect-ratio: unset !important; height: 34px !important;
    border: 1px solid #999 !important; color: #000 !important; background: #fff !important;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .sp-tracker__cell.is-on { background: #ddd !important; }
  .sp-tracker__count { display: none !important; }
}
@media print {
  /* Keep the tracker (title + instructions + grid) together on its own
     page instead of it trailing at the bottom of the previous page's
     content, and keep the Week 1-4 reflection questions that follow it
     starting on a clean page of their own too (Julie, 2026-08-21). */
  .sp-q__label--center { page-break-before: always; break-before: page; }
  .sp-tracker { page-break-after: always; break-after: page; }
}

/* ===== listen-elsewhere buttons under the player ===== */
.sp-listen { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 16px 0 0; }
.sp-listen__label { font-size: 13px; color: var(--sp-muted-2); }
.sp-listen__btn {
  font-size: 13.5px; font-weight: 600; color: var(--sp-ink); text-decoration: none;
  border: 1px solid rgba(36,30,56,0.16); border-radius: 999px; padding: 7px 15px;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.sp-listen__btn:hover { border-color: var(--sp-pink); background: var(--sp-pink-tint); color: var(--sp-pink); }

/* ===== worksheet / transcript toggle ===== */
.sp-toggle { display: inline-flex; gap: 4px; margin: 28px 0 10px; background: rgba(36,30,56,0.05); padding: 4px; border-radius: 14px; }
.sp-toggle__tab {
  font-family: inherit; font-size: 15px; font-weight: 700; color: var(--sp-muted);
  background: transparent; border: 0; border-radius: 10px; padding: 9px 18px; cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.sp-toggle__tab:hover { color: var(--sp-ink); }
.sp-toggle__tab.is-active { background: #fff; color: var(--sp-pink); box-shadow: 0 1px 4px rgba(36,30,56,0.12); }
.sp-view[hidden] { display: none; }

/* ===== in-page transcript ===== */
.sp-transcript__body { margin-top: 6px; }
.sp-transcript__body p { font-size: 18px; line-height: 1.74; color: var(--sp-ink); margin: 0 0 1.15em; }
.sp-transcript__body p:last-child { margin-bottom: 0; }
.sp-transcript__loading { color: var(--sp-muted-2); font-style: italic; }

/* ===== "Keep it on your phone" home-screen mockup (quick-tour.html) =====
   Ported from the workbook's own .howto-hs-* rules (workbook-howto.css) for the
   "Add to Home Screen" section. Same drawn-not-photographed reasoning: the only
   real thing on it is the app icon and its name, both read live off the actual
   install artwork, so restyle or re-icon the app and this picture stays true. */
.sp-hs-share-icon { display: inline-block; vertical-align: -2px; }

@media (min-width: 601px) {
  .sp-hs-layout { display: flex; align-items: flex-start; gap: 32px; }
  .sp-hs-text { flex: 1 1 auto; min-width: 0; }
  .sp-hs-layout .sp-hs-homescreen { flex: 0 0 auto; margin-top: 0; }
}
.sp-hs-homescreen { margin: 24px 0 0; padding: 0; }
.sp-hs-homescreen figcaption { margin-top: 11px; font-size: 14px; font-style: italic; opacity: 0.65; }

/* The bezel. */
.sp-hs-phone {
  width: 196px; height: 424px; box-sizing: border-box;
  border: 7px solid #2f2a33; border-radius: 28px;
  box-shadow: 0 12px 28px -14px rgba(0,0,0,0.45);
  zoom: 0.82;
}
.sp-hs-screen {
  width: 100%; height: 100%; box-sizing: border-box;
  display: flex; flex-direction: column; padding: 7px 12px 0; border-radius: 21px;
  /* Deliberately not the Starter Pack's own cream/pink -- the home screen belongs
     to the reader, not to us. */
  background: #45404e; overflow: hidden;
}
.sp-hs-status {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 3px; height: 15px; font-family: var(--sp-font); font-size: 9px;
  font-weight: 600; color: #fff;
}
.sp-hs-batt {
  width: 15px; height: 7px; border: 1px solid rgba(255,255,255,0.75); border-radius: 2px;
  background: linear-gradient(to right, rgba(255,255,255,0.75) 65%, transparent 65%);
  background-clip: content-box;
}
.sp-hs-grid {
  flex: 1; display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 15px 9px; align-content: start; padding-top: 11px;
}
.sp-hs-app { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.sp-hs-sq { display: block; width: 32px; height: 32px; border-radius: 22%; background: rgba(255,255,255,0.15); }
.sp-hs-nm { display: block; width: 22px; height: 4px; border-radius: 2px; background: rgba(255,255,255,0.15); }
.sp-hs-app-sp .sp-hs-sq { background: none; box-shadow: 0 3px 7px -2px rgba(0,0,0,0.55); }
.sp-hs-app-sp .sp-hs-nm {
  width: auto; height: auto; border-radius: 0; background: none;
  font-family: var(--sp-font); font-size: 7.5px; font-weight: 500; line-height: 1.2;
  letter-spacing: 0.01em; color: #fff; white-space: nowrap;
}
.sp-hs-dock { display: flex; justify-content: space-between; padding: 8px 10px; border-radius: 16px; background: rgba(255,255,255,0.10); }
.sp-hs-bar { width: 62px; height: 3px; margin: 7px auto 6px; border-radius: 2px; background: rgba(255,255,255,0.55); }

/* ===== A QUICK TOUR (quick-tour.html) =====
   Orientation page: how saving works, what the dots mean, how to get around.
   Modeled on the JM workbook's .howto-* rules (workbook-howto.css) but in the
   Starter Pack's own design language (Quicksand, cream/pink/espresso tokens).
   ====================================================================== */

/* The page itself. Uses the same width as the default --narrow (880px, see
   .sp-main__inner--narrow) so it matches every other Starter Pack page —
   this used to override to 820px, which was narrower than the default and
   caused the footer copy to wrap unlike anywhere else in the Starter Pack. */
.sp-qt-page h1 { text-align: center; }

.sp-qt-lede {
  font-size: 17px; line-height: 1.7; color: var(--sp-prose);
  text-align: center; max-width: 600px; margin: 14px auto 40px;
}

/* ── Each section is a <details> accordion ───────────────────────────── */
.sp-qt-block {
  margin-bottom: 12px;
  border: 1.5px solid rgba(212,15,128,0.14);
  border-radius: 16px;
  background: #fffdf9;
  overflow: hidden;
}
/* The sign-off at the end stays frameless, so it reads as the end of
   the page rather than another row you forgot to open. */
section.sp-qt-block {
  margin-top: 40px; margin-bottom: 40px;
  border: none; border-radius: 0; background: none;
}

.sp-qt-block-head {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 20px; cursor: pointer;
  list-style: none;
  transition: background 0.18s ease;
}
.sp-qt-block-head::-webkit-details-marker { display: none; }
.sp-qt-block-head:hover { background: rgba(212,15,128,0.05); }
.sp-qt-block[open] > .sp-qt-block-head { background: rgba(212,15,128,0.05); }
.sp-qt-block-head:focus-visible { outline: 2px solid var(--sp-pink); outline-offset: -2px; }
.sp-qt-block > .sp-qt-block-head h2 { margin: 0; flex: 1; min-width: 0; }

/* Chevron: right when closed, down when open. */
.sp-qt-block-head::after {
  content: ''; flex-shrink: 0; width: 8px; height: 8px;
  border-right: 2px solid var(--sp-pink); border-bottom: 2px solid var(--sp-pink);
  transform: rotate(-45deg); margin-right: 3px;
  transition: transform 0.22s ease;
}
.sp-qt-block[open] > .sp-qt-block-head::after { transform: rotate(45deg); margin-right: 0; }

.sp-qt-block-body { padding: 14px 20px 20px; }

.sp-qt-block h2 {
  font-family: var(--sp-font); font-weight: 700; font-size: 18px;
  line-height: 1.35; color: var(--sp-pink); margin: 0 0 14px;
}
.sp-qt-block p {
  font-family: var(--sp-font); font-size: 16.5px; line-height: 1.7;
  color: var(--sp-prose); margin: 0 0 14px;
}
.sp-qt-block p:last-child { margin-bottom: 0; }
.sp-qt-block b { color: var(--sp-ink); font-weight: 700; }

/* Simone's handwritten sign-off. */
.sp-qt-block p.sp-qt-signature {
  font-family: var(--sp-hand); font-size: 28px; line-height: 1.35;
  color: var(--sp-pink); margin-top: 14px !important;
}

/* ── Bulleted list inside an accordion ───────────────────────────────── */
.sp-qt-list {
  font-family: var(--sp-font); font-size: 16.5px; line-height: 1.7;
  color: var(--sp-prose); margin: 0; padding-left: 22px;
}
.sp-qt-list li { margin-bottom: 9px; }
.sp-qt-list li:last-child { margin-bottom: 0; }
.sp-qt-list li.sp-qt-list-item-buttons { margin-bottom: 16px; }
.sp-qt-list + p { margin-top: 16px; }

/* ── Legend (the dots explained) ─────────────────────────────────────── */
.sp-qt-legend {
  background: rgba(255,255,255,0.6); border: 1px solid var(--sp-hair);
  border-radius: 12px; padding: 6px 22px; margin: 0 0 18px;
}
.sp-qt-legend-row {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 16px 0; border-bottom: 1px solid var(--sp-hair);
}
.sp-qt-legend-row:last-child { border-bottom: none; }
.sp-qt-legend-text {
  font-family: var(--sp-font); font-size: 15.5px; line-height: 1.6;
  color: var(--sp-prose);
}

/* Inline dot pictures — same circles the sidebar draws, restated here
   so the legend and the real thing can't drift. */
.sp-qt-dot {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; width: 14px; height: 14px; border-radius: 50%;
  margin-top: 5px; font-size: 7px; font-weight: 700; color: #fff;
}
.sp-qt-dot--empty { background: rgba(58,47,30,0.25); }
.sp-qt-dot--white { background: #fff; border: 1.5px solid rgba(58,47,30,0.35); }
.sp-qt-dot--prog  { background: var(--sp-pink); }
.sp-qt-dot--done  { background: var(--sp-amber); }
.sp-qt-dot--done::after { content: "\2713"; }

/* ── Inline tracker pictures (CSS-drawn, not screenshots) ──────────── */
.sp-qt-tracker-demo {
  background: rgba(255,255,255,0.6); border: 1px solid var(--sp-hair);
  border-radius: 12px; padding: 18px 22px; margin: 14px 0;
}
.sp-qt-tracker-demo-label {
  font-family: var(--sp-font); font-size: 13px; font-weight: 600;
  color: var(--sp-muted-2); margin-bottom: 10px; text-transform: uppercase;
  letter-spacing: 0.04em;
}
.sp-qt-tracker-bar {
  height: 5px; background: #EFEBF2; border-radius: 20px; overflow: hidden;
  margin-bottom: 6px;
}
.sp-qt-tracker-bar > i { display: block; height: 100%; background: var(--sp-pink); border-radius: 20px; }
.sp-qt-tracker-count {
  font-family: var(--sp-font); font-size: 12.5px; font-weight: 600;
  color: var(--sp-muted-2);
}

/* ── Inline player illustration ─────────────────────────────────────── */
/* Redrawn 2026-08-28 to match the rebuilt custom player (sp-audio-player.js/css):
   cover art + eyebrow/title, then [back-10 · play · forward-10 · speed], then a
   seek bar with current/total time, then a foot row with the "Pick up where
   you left off" resume note (left) and "Show notes" link (right). Drawn in CSS, not a
   screenshot, so it can't quietly go out of date — same convention as the rest
   of this file. Kept in its own sp-qt-player-* namespace, separate from the
   real player's spa__* classes, since this is an illustration, not the real
   component. */
.sp-qt-player-demo {
  background: #fff; border: 1px solid var(--sp-hair);
  border-radius: 14px; padding: 16px 18px 14px; margin: 14px 0 18px;
  max-width: 420px;
}
.sp-qt-player-top {
  display: flex; align-items: center; gap: 12px; margin-bottom: 12px;
}
.sp-qt-player-cover {
  width: 48px; height: 48px; border-radius: 10px; background: var(--sp-pink-tint, #ffe3f0);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  overflow: hidden;
}
.sp-qt-player-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sp-qt-player-meta { min-width: 0; }
.sp-qt-player-eyebrow {
  font-family: var(--sp-font); font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--sp-muted-2);
  margin-bottom: 2px;
}
.sp-qt-player-title {
  font-family: var(--sp-font); font-size: 14px; font-weight: 700; color: #2a2118;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sp-qt-player-controls {
  display: flex; align-items: center; gap: 16px; margin-bottom: 12px;
}
.sp-qt-player-controls .sp-qt-pc-btn {
  display: inline-flex; align-items: center; justify-content: center;
  color: #444; font-family: var(--sp-font);
}
.sp-qt-player-controls .sp-qt-pc-skip {
  width: 28px; height: 28px; position: relative;
}
.sp-qt-player-controls .sp-qt-pc-skip-num {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  font-size: 8px; font-weight: 700; color: #444; margin-top: 1px;
}
.sp-qt-player-play {
  width: 38px; height: 38px; border-radius: 50%; background: #222;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.sp-qt-player-play svg { margin-left: 2px; }
.sp-qt-player-controls .sp-qt-pc-speed {
  margin-left: auto; font-size: 13px; font-weight: 700; color: #444;
}
.sp-qt-player-seekrow {
  display: flex; align-items: center; gap: 10px; margin-bottom: 10px;
}
.sp-qt-player-time {
  font-family: var(--sp-font); font-size: 11px; font-weight: 600; color: var(--sp-muted-2);
  min-width: 28px;
}
.sp-qt-player-time:last-child { text-align: right; }
.sp-qt-player-seek {
  flex: 1; height: 5px; border-radius: 20px; background: #EFEBF2; overflow: hidden;
}
.sp-qt-player-seek > i { display: block; height: 100%; background: var(--sp-pink); border-radius: 20px; }
.sp-qt-player-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap;
}
.sp-qt-player-resume {
  font-family: var(--sp-font); font-size: 11.5px; color: var(--sp-muted-2);
}
.sp-qt-player-resume b { color: var(--sp-pink); font-weight: 700; }
.sp-qt-player-restart {
  color: var(--sp-pink); font-weight: 700; text-decoration: underline;
  text-underline-offset: 2px; margin-left: 6px;
}
.sp-qt-player-notes {
  font-family: var(--sp-font); font-size: 12.5px; font-weight: 700; color: var(--sp-pink);
}

/* ── Pictures of the app's own controls ──────────────────────────────── */
/* Same reasoning as the JM workbook (howtoButtonRow): these are spans,
   not buttons, because a pressable button that does nothing is worse
   than a picture of one. Pointer-events off, no hover lift. */
.sp-qt-ui-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 12px 0 2px;
}
.sp-qt-ui-row .sp-done-btn,
.sp-qt-ui-row .sp-prev,
.sp-qt-ui-row .sp-next,
.sp-qt-ui-row .sp-btn {
  pointer-events: none; cursor: default;
}
/* DOM order here is Previous, Mark as done, Next (matches the real footer's
   markup) but this row is inline in a bullet, so it can wrap at widths the
   real footer never sees. Plain flex-wrap would then split it wherever it
   runs out of room — e.g. Previous+Mark-as-done on one line, Next stranded
   alone on the next — instead of grouping like the real mobile footer
   (Previous+Next together, Mark as done on its own line). Reordering
   visually to Previous, Next, Mark as done means if it does wrap, the first
   two to run out of room are always Previous+Next, so Mark as done is what
   drops alone — matching the real thing regardless of exact wrap width.
   Julie, 2026-09-01. */
.sp-qt-ui-row .sp-next { order: 1; }
.sp-qt-ui-row .sp-done-btn { order: 2; }
/* .sp-prev/.sp-next/.sp-done-btn now render at a fixed width+height (set on
   the base rule) with align-items:center doing the vertical centering, so
   they no longer need a padding/font-size override here to look right next
   to real prose text — removing it also means this demo row can never drift
   out of sync with the real buttons' size again. .sp-btn is a different,
   not-fixed-size class still used elsewhere in this row (e.g. the inline
   print button below), so it keeps its own line-height:normal fix — a real
   button starts from line-height:normal; this sits in a list that sets 1.7
   and inherits it, making it taller than the real thing. */
.sp-qt-ui-row .sp-btn { line-height: normal; font-size: 13px; padding: 10px 18px; }

/* The print button, shown inside a sentence. position:static undoes the
   real button's fixed-corner placement; inline-flex puts it on the line.
   Doubled class selector (.sp-print-btn.sp-qt-ui-print) beats the base
   .sp-print-btn from print-kit.css, which loads later. */
.sp-print-btn.sp-qt-ui-print {
  position: static; display: inline-flex; vertical-align: -2px;
  margin: 0 2px; padding: 6px 12px; font-size: 12px; box-shadow: none;
  pointer-events: none; cursor: default;
}

/* ── Nested part accordions inside the curriculum block ───────────────── */
/* These sit inside .sp-qt-block-body and look like smaller, lighter
   versions of the outer accordion — no border of their own, just a
   tinted background and a bit less padding. */
.sp-qt-part {
  margin-bottom: 8px; border-radius: 12px;
  background: rgba(212,15,128,0.04); overflow: hidden;
}
.sp-qt-part:last-child { margin-bottom: 0; }
.sp-qt-part-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; cursor: pointer; list-style: none;
  transition: background 0.18s ease;
}
.sp-qt-part-head::-webkit-details-marker { display: none; }
.sp-qt-part-head:hover { background: rgba(212,15,128,0.07); }
.sp-qt-part[open] > .sp-qt-part-head { background: rgba(212,15,128,0.07); }
.sp-qt-part-head:focus-visible { outline: 2px solid var(--sp-pink); outline-offset: -2px; }
.sp-qt-part-head h3 {
  margin: 0; flex: 1; min-width: 0;
  font-family: var(--sp-font); font-weight: 700; font-size: 17px;
  line-height: 1.3; color: var(--sp-ink);
}
.sp-qt-part-head h3 a { color: inherit; text-decoration: none; }
.sp-qt-part-head h3 a:hover { color: var(--sp-pink); }
/* Chevron, same as the outer accordion but slightly smaller. */
.sp-qt-part-head::after {
  content: ''; flex-shrink: 0; width: 7px; height: 7px;
  border-right: 1.5px solid var(--sp-pink); border-bottom: 1.5px solid var(--sp-pink);
  transform: rotate(-45deg); margin-right: 2px;
  transition: transform 0.22s ease;
}
.sp-qt-part[open] > .sp-qt-part-head::after { transform: rotate(45deg); margin-right: 0; }
.sp-qt-part-body { padding: 4px 16px 16px; }
.sp-qt-part-body p {
  font-family: var(--sp-font); font-size: 15.5px; line-height: 1.65;
  color: var(--sp-prose); margin: 0 0 10px;
}
.sp-qt-part-body p:last-child { margin-bottom: 0; }
/* The episode bullet lists inside each part. Styled to match .sp-lesson__list
   but slightly smaller since they're nested two levels deep. */
.sp-qt-part-list {
  margin: 8px 0 0; padding-left: 22px;
  font-family: var(--sp-font); font-size: 15.5px; line-height: 1.6;
  color: var(--sp-prose);
}
.sp-qt-part-list li { margin-bottom: 8px; padding-left: 2px; }
.sp-qt-part-list li:last-child { margin-bottom: 0; }
.sp-qt-part-list li::marker { color: var(--sp-pink); font-weight: 700; }

/* The part illustration thumbnail in the curriculum sub-accordion header. */
.sp-qt-part-art {
  flex: 0 0 44px; height: 36px; border-radius: 8px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background-color: var(--sp-kraft);
  background-image: radial-gradient(ellipse at 50% 35%, var(--sp-pink-tint) 0%, var(--sp-kraft) 72%);
}
.sp-qt-part-art img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* ── Six-parts map ───────────────────────────────────────────────────── */
.sp-qt-map {
  display: flex; flex-direction: column; gap: 14px; margin-top: 20px;
}
.sp-qt-map-card {
  display: flex; align-items: center; gap: 18px;
  padding: 16px 20px 16px 16px; border: 1px solid var(--sp-hair);
  background: rgba(255,255,255,0.6); border-radius: 14px;
  text-decoration: none; color: var(--sp-ink);
  transition: transform 0.2s, box-shadow 0.2s;
}
.sp-qt-map-card:hover {
  transform: translateY(-2px); box-shadow: 0 10px 24px -12px rgba(0,0,0,0.25);
  color: var(--sp-ink);
}
.sp-qt-map-art {
  flex: 0 0 72px; height: 56px; border-radius: 10px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background-color: var(--sp-kraft);
  background-image: radial-gradient(ellipse at 50% 35%, var(--sp-pink-tint) 0%, var(--sp-kraft) 72%);
}
.sp-qt-map-art img { max-width: 100%; max-height: 100%; object-fit: contain; }
.sp-qt-map-body { flex: 1; min-width: 0; }
.sp-qt-map-title {
  font-family: var(--sp-font); font-weight: 700; font-size: 17px;
  line-height: 1.2; color: var(--sp-ink);
}
.sp-qt-map-desc {
  font-family: var(--sp-font); font-size: 14px; line-height: 1.55;
  color: var(--sp-prose); margin-top: 4px;
}
.sp-qt-map-count {
  font-family: var(--sp-font); font-weight: 700; font-size: 12px;
  color: var(--sp-pink); margin-top: 3px;
}
.sp-qt-map-arrow {
  flex-shrink: 0; font-size: 1.1rem; color: var(--sp-pink);
  transition: transform 0.2s;
}
.sp-qt-map-card:hover .sp-qt-map-arrow { transform: translateX(4px); }

/* ── Sign-out capsule shown inline ───────────────────────────────────── */
.sp-qt-signout-pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 500; color: rgba(58,47,30,0.68);
  border: 1.5px solid rgba(58,47,30,0.32); border-radius: 999px;
  padding: 4px 12px; vertical-align: -1px; margin: 0 2px;
  cursor: default; pointer-events: none;
}
.sp-qt-signout-pill svg { flex-shrink: 0; }

/* ── Responsive ──────────────────────────────────────────────────────── */
@media (max-width: 600px) {
  .sp-qt-page { max-width: 100%; }
  .sp-qt-block h2 { font-size: 17px; }
  .sp-qt-block p, .sp-qt-list { font-size: 16px; }
  .sp-qt-map-art { flex-basis: 56px; height: 44px; }
  .sp-qt-map-title { font-size: 16px; }
  .sp-qt-map-card { gap: 12px; padding: 14px; }
  .sp-qt-lede { font-size: 16px; }
}
