
/* ============================================================
   JOY RESTORED — joyrestored.com
   Brand system (per Joy Restored Brand Book, Edition 2026):
   Newsreader (display) · Hanken Grotesk (body/UI) · Montserrat (labels)
   Palette: Warm Ivory #EFEFEC · Paper #FCFBF7 · Ocean Blue #1B568D
            Sage #86ADA0 · Deep Sea #365B6D · Sky #6EC6E3 · Slate #3A475A
   Signature gradient (hero + final-CTA panels only): Deep Sea → Sage
   Textures: The Dawn (rising rings) · The Seed (dot field) · The Horizon
   ============================================================ */

:root {
  --ivory: #EFEFEC;
  --paper: #FCFBF7;
  --ocean: #1B568D;
  --sage: #86ADA0;
  --deep: #365B6D;
  --sky: #6EC6E3;
  --slate: #3A475A;
  --ink: #213240;
  --white: #FFFFFF;
  --sage-tint: #E3ECE7;
  --line: #E7E0D2;
  --grad: linear-gradient(150deg, #365B6D 0%, #3A6E7E 55%, #86ADA0 100%);
  --serif: "Newsreader", Georgia, serif;
  --sans: "Hanken Grotesk", "Helvetica Neue", Arial, sans-serif;
  --mont: "Montserrat", "Hanken Grotesk", Arial, sans-serif;
  /* One box radius for the whole site. Cards, panels, inputs, media
     frames and menus all take this; pills stay 999px and circles stay
     50%, because those are shapes rather than a corner size. */
  --radius: 8px;
  /* ---- One shadow recipe ----
     The same deep-sea ink and the same offset-to-blur ratio at five
     sizes. Level 2 keeps the name --shadow and keeps its value,
     because thirty-odd rules already ask for it by that name.

     Two inks, not two recipes: anything sitting on the hero gradient
     or another dark band needs a darker ink to register at all, so
     the -dark variants are the same geometry in the near-black those
     bands are built from. Rings, hairlines and the two deliberate
     coloured glows are not elevation and are not on this scale. */
  --shadow-0: 0 2px 6px rgba(54, 91, 109, 0.14);
  --shadow-1: 0 8px 20px rgba(54, 91, 109, 0.16);
  --shadow:   0 18px 45px rgba(54, 91, 109, 0.12);
  --shadow-2: var(--shadow);
  --shadow-3: 0 22px 48px rgba(54, 91, 109, 0.20);
  --shadow-4: 0 34px 78px rgba(54, 91, 109, 0.30);
  --shadow-1-dark: 0 8px 20px rgba(19, 32, 41, 0.28);
  --shadow-2-dark: 0 14px 34px rgba(19, 32, 41, 0.26);
  --shadow-3-dark: 0 22px 48px rgba(19, 32, 41, 0.34);
  --shadow-4-dark: 0 34px 78px rgba(19, 32, 41, 0.42);
  --maxw: 1120px;
}

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

html { scroll-behavior: smooth; }

body {
  font-family: var(--sans);
  font-weight: 300;
  font-size: 1.125rem;
  line-height: 1.7;
  color: var(--ink);
  background: var(--ivory);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

a { color: var(--ocean); }

/* ---- The focus ring ----
   One ring, on everything that takes focus. :where() keeps this at
   zero specificity, so any component that needs its own ring can still
   set one without a fight.

   [tabindex] is in the list because two things on this site are
   focusable without being controls: the podcast strip and the Decode
   log are both scroll containers a keyboard has to be able to reach.

   No border-radius here. The rule used to set 4px, which did not round
   the ring, it rounded the ELEMENT: focus a card and its corners
   changed shape. An outline follows whatever radius the element
   already has, so the right move is to say nothing. */
:where(a, button, summary, input, textarea, select, [tabindex]):focus-visible {
  outline: 2.5px solid var(--ocean);
  outline-offset: 3px;
}

/* On the dark grounds, ocean on deep sea is a ring nobody can see. */
:where(.hero, .cta-band, .site-footer, .decode-block, .decode-shell, .lib-top, .care-bar)
  :where(a, button, summary, input, textarea, select, [tabindex]):focus-visible {
  outline-color: var(--white);
}

.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 28px;
}

/* ---------- Type ---------- */

h1, h2, h3, .display {
  font-family: var(--serif);
  font-weight: 300;
  color: var(--deep);
  line-height: 1.12;
}

h1 { font-size: clamp(2.6rem, 6vw, 4.4rem); letter-spacing: -0.01em; }
h2 { font-size: clamp(2rem, 4vw, 2.9rem); letter-spacing: -0.005em; }
h3 { font-size: clamp(1.35rem, 2.4vw, 1.7rem); font-weight: 400; }

h1 em, h2 em {
  font-style: italic;
  font-weight: 300;
}

.label {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ocean);
}

.label--sage { color: var(--sage); }
.label--light { color: rgba(255, 255, 255, 0.75); }

.lede {
  font-size: 1.28rem;
  font-weight: 300;
  color: #46555E;
  max-width: 46ch;
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 17px 36px;
  border-radius: 999px;
  border: none;
  cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}

.btn:hover { transform: translateY(-2px); }

.btn--primary {
  background: var(--ocean);
  color: var(--white);
  box-shadow: var(--shadow-1);
}
.btn--primary:hover { background: #174a7b; }

.btn--light {
  background: var(--paper);
  color: var(--deep);
  box-shadow: var(--shadow-1-dark);
}

.btn--ghost {
  border: 1.7px solid var(--ocean);
  color: var(--ocean);
  background: transparent;
}
.btn--ghost:hover { background: rgba(27, 86, 141, 0.07); }

.btn--ghost-light {
  border: 1.7px solid rgba(255, 255, 255, 0.65);
  color: var(--white);
  background: transparent;
}
.btn--ghost-light:hover { background: rgba(255, 255, 255, 0.12); }

.btn-row {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  align-items: center;
}

.textlink {
  font-family: var(--sans);
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ocean);
  text-decoration: none;
  border-bottom: 1.7px solid var(--sage);
  padding-bottom: 4px;
}
.textlink:hover { border-color: var(--ocean); }

/* ---------- Header / Nav ---------- */

.site-header {
  /* Sticky: the header (and, on the homepage, the small-group ticker
     inside it) stays put while the page scrolls underneath. It still
     never shrinks; .is-scrolled only adds a shadow. */
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--ivory);
  border-bottom: 1px solid transparent;
}
.site-header.is-scrolled {
  border-bottom-color: var(--line);
  box-shadow: var(--shadow-1-dark);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 18px 28px;
  max-width: var(--maxw);
  margin: 0 auto;
}

.brand {
  font-family: var(--serif);
  font-size: 1.28rem;
  font-weight: 400;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--deep);
  text-decoration: none;
  white-space: nowrap;
}
.brand span { color: var(--ocean); }

.nav-links {
  display: flex;
  align-items: center;
  gap: 22px;
  list-style: none;
}

.nav-links a {
  font-family: var(--sans);
  font-size: 0.8rem;
  white-space: nowrap;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--deep);
  text-decoration: none;
  /* Symmetric on purpose. The active underline needs 5px and a 1.7px
     rule reserved BELOW the word; with nothing balancing it above, the
     box hung 4.5px lower than the Donate and Log In pills beside it,
     so the row of labels sat visibly below the pills and the logo.
     The top half is transparent and costs nothing but the balance. */
  padding-top: 5px;
  padding-bottom: 5px;
  border-top: 1.7px solid transparent;
  border-bottom: 1.7px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
/* Boxes, not text baselines: an inline <a> rides the line box of its
   li, which is what left Log In a pixel and a half below Donate. */
.nav-links > li { display: flex; align-items: center; }
.nav-links a, .nav-links .nav-top { display: inline-flex; align-items: center; }

.nav-links a:hover { color: var(--ocean); }
.nav-links a.active { color: var(--ocean); border-bottom-color: var(--sage); }

.nav-links .nav-cta {
  background: var(--ocean);
  color: var(--white);
  padding: 12px 24px;
  border-radius: 999px;
  border-bottom: none;
}
.nav-links .nav-cta:hover { background: #174a7b; color: var(--white); }

.nav-toggle { display: none; }

.nav-toggle-label {
  display: none;
  cursor: pointer;
  width: 30px;
  height: 22px;
  position: relative;
}
.nav-toggle-label span,
.nav-toggle-label span::before,
.nav-toggle-label span::after {
  content: "";
  position: absolute;
  height: 2px;
  width: 100%;
  border-radius: 2px;
  background: var(--deep);
  transition: transform 0.2s ease;
}
.nav-toggle-label span { top: 10px; }
.nav-toggle-label span::before { top: -9px; }
.nav-toggle-label span::after { top: 9px; }

@media (max-width: 1180px) {
  .nav-links { gap: 14px; }
  .nav-links a { font-size: 0.74rem; letter-spacing: 0.09em; }
  .nav-links .nav-cta { padding: 10px 18px; }
  .site-header .brand-img { height: 40px; }
}

/* ---------- Hero ---------- */

.hero {
  position: relative;
  background: var(--grad);
  color: var(--white);
  overflow: hidden;
}

.hero .ripple {
  position: absolute;
  right: -180px;
  top: 50%;
  transform: translateY(-50%);
  width: 720px;
  height: 720px;
  opacity: 0.35;
  pointer-events: none;
}

.hero-inner {
  position: relative;
  padding: 72px 28px 80px;
  max-width: var(--maxw);
  margin: 0 auto;
}

.hero h1 { color: var(--white); max-width: 16ch; margin: 22px 0 26px; }

.hero p {
  color: rgba(255, 255, 255, 0.88);
  font-size: 1.25rem;
  max-width: 52ch;
  margin-bottom: 42px;
}

.hero--sub .hero-inner { padding: 52px 28px 58px; }
.hero--sub p { margin-bottom: 0; }
.hero--sub .btn-row { margin-top: 40px; }

/* ---------- Sections ---------- */

section { padding: 96px 0; }

.section-head { max-width: 62ch; margin-bottom: 56px; }
.section-head h2 { margin: 16px 0 18px; }

/* ---- Card titles are clamped ----
   A title is a label for a card, not an essay in it. Three lines is
   more than any of them currently uses, so nothing is cut today; the
   clamp is here so that the day someone writes a fourteen-word title
   it shortens rather than pushing everything below it out of line
   with the card beside it. Cards laid out on shared rows (the ladder
   rungs, the course cards, the podcast strip) reserve their three
   lines as well, which is what makes those rows hold. */
:where(.card, .lib-card, .product-card, .sp-card, .course-card) h3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

/* ---- Heads asked to hold on one line ----
   These were breaking on their own measure, not on the viewport.
   .lede caps at 46ch, about 440px, and "An hour each, on Zoom, no
   cost. Take either one at any point on the path above." needs 722px;
   "Two workshops, whenever one fits." needs 626px against the head's
   62ch, which lands on 625, so it broke by a single pixel.

   A wider measure rather than white-space: nowrap, deliberately: this
   holds the line down to roughly an 820px viewport and then lets it
   wrap, which is what a phone needs and what nowrap would have taken
   away. Nothing here is long enough for 50rem to hurt the reading. */
.section-head--oneline,
.section-head--oneline .lede { max-width: 50rem; }

/* A phrase that must not be broken across two lines. Different job
   from the class above: that one widens a measure, this one keeps a
   sentence whole and lets it wrap down as a unit, for the places where
   a line was landing as "Rooted in / hope." Only ever put it on a
   short phrase, never a whole paragraph, or it will overflow a phone. */
.nobreak { white-space: nowrap; }

/* ---- The two-up cards share their rows too ----
   The free-workshop pairs on the three door pages are label, title,
   body, link. They happen to line up today because both titles run to
   one line; the moment one wraps, the body and the link beside it
   stop agreeing. Same subgrid treatment as the ladders, scoped to
   cards that actually carry a link, so the many other .card layouts
   on this site (forms, checklists, multi-paragraph panels) are left
   alone rather than having their paragraphs stacked into one row. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 901px) {
    .grid-2:has(> .card > .textlink) { grid-template-rows: auto auto 1fr auto; }
    .grid-2:has(> .card > .textlink) > .card {
      grid-row: span 4; display: grid; grid-template-rows: subgrid;
    }
    .grid-2:has(> .card > .textlink) > .card > .label    { grid-row: 1; justify-self: start; }
    .grid-2:has(> .card > .textlink) > .card > h3        { grid-row: 2; }
    .grid-2:has(> .card > .textlink) > .card > p         { grid-row: 3; }
    .grid-2:has(> .card > .textlink) > .card > .textlink { grid-row: 4; justify-self: start; }
  }
}

.section-alt { background: var(--paper); }
.section-sage { background: var(--sage-tint); }

.centered { text-align: center; }
.centered .section-head { margin-left: auto; margin-right: auto; }

/* ---------- Cards & grids ---------- */

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 36px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; }

.card {
  background: var(--paper);
  border-radius: var(--radius);
  padding: 44px 40px;
  box-shadow: var(--shadow);
}

.card h3 { margin: 18px 0 14px; }
.card p { color: #46555E; font-size: 1.05rem; }
.card .textlink { display: inline-block; margin-top: 24px; }

.card--feature {
  position: relative;
  overflow: hidden;
  background: var(--grad);
  color: var(--white);
}
.card--feature h3, .card--feature p { color: var(--white); }
.card--feature p { color: rgba(255,255,255,0.88); }
.card--feature .textlink { color: var(--white); border-color: rgba(255,255,255,0.6); }
.card--feature .ripple-corner {
  position: absolute;
  right: -120px;
  bottom: -120px;
  width: 340px;
  height: 340px;
  opacity: 0.3;
}

.icon-circle {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(27, 86, 141, 0.08);
}
.card--feature .icon-circle { background: rgba(255, 255, 255, 0.14); }

.icon-circle svg { width: 27px; height: 27px; }

/* ---------- Split layout ---------- */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 72px;
  align-items: center;
}

.split h2 { margin: 16px 0 20px; }
.split p + p { margin-top: 18px; }

/* ---- two prose columns, rather than prose beside a picture ----
   .split centres its two children, which is right when one side is a
   portrait: the photo and the paragraph beside it want a shared middle.
   Where BOTH sides are prose the centring is exactly what makes them
   look wrong, because the columns never hold the same amount of text,
   so neither the labels nor the headings line up and the pair reads as
   two loose blocks instead of one spread. This variant tops them out
   and, where subgrid is supported, puts label, heading and body on
   shared rows so all three align across the gutter however long the
   headings run. Paragraphs are wrapped in .split-body so each column
   is exactly three grid children. */
.split--text { align-items: start; }
.split--text .split-body p + p { margin-top: 18px; }
@supports (grid-template-rows: subgrid) {
  .split--text { grid-template-rows: auto auto auto; }
  .split--text > div {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 3;
    align-content: start;
  }
}
/* Once .split is one column there are no rows to share, and holding
   the span would stretch the first block over the second's rows. */
@media (max-width: 900px) {
  .split--text { grid-template-rows: none; }
  .split--text > div { display: block; grid-row: auto; }
}

.portrait-frame {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--grad);
  min-height: 460px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow);
}
.portrait-frame .ripple { width: 420px; height: 420px; opacity: 0.4; }
.portrait-frame .placeholder-note {
  position: absolute;
  bottom: 18px;
  left: 0; right: 0;
  text-align: center;
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.65);
}
.portrait-frame .monogram {
  font-family: var(--serif);
  font-style: italic;
  font-size: 6.5rem;
  color: rgba(255, 255, 255, 0.9);
}
.portrait-frame .portrait-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
}
.portrait-frame .monogram-img {
  width: 130px;
  height: 130px;
  border-radius: 50%;
  position: relative;
  box-shadow: var(--shadow-2-dark);
}

/* ---------- Quote band ---------- */

.quote-band {
  background: var(--deep);
  color: var(--white);
  position: relative;
  overflow: hidden;
}
.quote-band .ripple {
  position: absolute;
  left: -200px;
  top: 50%;
  transform: translateY(-50%);
  width: 640px; height: 640px;
  opacity: 0.18;
}
.quote-band blockquote {
  position: relative;
  font-family: var(--serif);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  line-height: 1.35;
  max-width: 30ch;
  margin: 0 auto;
  text-align: center;
}
.quote-band cite {
  display: block;
  margin-top: 28px;
  font-family: var(--sans);
  font-style: normal;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--sage);
}

/* ---------- Steps / numbered ---------- */

.steps { counter-reset: step; display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; }

.step {
  counter-increment: step;
  background: var(--paper);
  border-radius: var(--radius);
  padding: 40px 36px;
  box-shadow: var(--shadow);
}
.step::before {
  content: "0" counter(step);
  font-family: var(--serif);
  font-size: 2.4rem;
  font-weight: 300;
  color: var(--sage);
  display: block;
  margin-bottom: 14px;
}
.step h3 { margin-bottom: 12px; }
.step p { font-size: 1.02rem; color: #46555E; }

/* ---------- Pricing / packages ---------- */

.package {
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border-radius: var(--radius);
  padding: 46px 40px;
  box-shadow: var(--shadow);
  border-top: 5px solid var(--sage);
}
.package--featured { border-top-color: var(--ocean); }

.package .price {
  font-family: var(--serif);
  font-size: 2.5rem;
  font-weight: 300;
  color: var(--deep);
  margin: 20px 0 4px;
}
.package .price small {
  font-family: var(--sans);
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: #7C888E;
}
.package ul {
  list-style: none;
  margin: 26px 0 34px;
  flex-grow: 1;
}
.package li {
  padding: 10px 0 10px 34px;
  position: relative;
  font-size: 1.02rem;
  color: #46555E;
  border-bottom: 1px solid rgba(134, 173, 160, 0.25);
}
.package li:last-child { border-bottom: none; }
.package li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 16px;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1.7px solid var(--sage);
  background: radial-gradient(circle, var(--sage) 0 4px, transparent 4.5px);
}
.package .btn { align-self: flex-start; }

.badge {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--white);
  background: var(--ocean);
  border-radius: 999px;
  padding: 7px 16px;
  margin-bottom: 18px;
}

/* ---------- FAQ ---------- */

.faq { max-width: 780px; margin: 0 auto; }

.faq details {
  background: var(--paper);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  border: 1px solid rgba(134, 173, 160, 0.35);
  margin-bottom: 16px;
  overflow: hidden;
}

.faq summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  padding: 24px 30px;
  font-family: var(--serif);
  font-size: 1.22rem;
  color: var(--deep);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  font-family: var(--sans);
  font-weight: 300;
  font-size: 1.7rem;
  color: var(--sage);
  transition: transform 0.2s ease;
  flex-shrink: 0;
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details p {
  padding: 0 30px 26px;
  font-size: 1.04rem;
  color: #46555E;
}
.faq details p + p { padding-top: 0; margin-top: -10px; }

/* ---------- Podcast ---------- */

.episode {
  display: flex;
  align-items: center;
  gap: 28px;
  background: var(--paper);
  border-radius: var(--radius);
  padding: 28px 34px;
  box-shadow: var(--shadow);
  margin-bottom: 20px;
}

.episode .ep-art {
  flex-shrink: 0;
  width: 86px; height: 86px;
  border-radius: var(--radius);
  background: var(--grad);
  display: flex;
  align-items: center;
  justify-content: center;
}
.episode .ep-art svg { width: 34px; height: 34px; }

.episode .ep-meta { flex-grow: 1; }
.episode .ep-num {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--sage);
}
.episode h3 { margin: 6px 0 6px; font-size: 1.3rem; }
.episode p { font-size: 0.98rem; color: #46555E; }

.platform-row {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}
.platform-row a {
  font-family: var(--sans);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--deep);
  text-decoration: none;
  border: 1.7px solid rgba(54, 91, 109, 0.3);
  border-radius: 999px;
  padding: 12px 24px;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.platform-row a:hover { border-color: var(--ocean); color: var(--ocean); }

/* ---------- Contact / forms ---------- */

.contact-card {
  background: var(--paper);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 52px 48px;
}

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.form-grid .full { grid-column: 1 / -1; }

label {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--deep);
  margin-bottom: 9px;
}

input, textarea, select {
  width: 100%;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 300;
  color: var(--ink);
  background: var(--ivory);
  border: 1.7px solid rgba(54, 91, 109, 0.18);
  border-radius: var(--radius);
  padding: 15px 18px;
  transition: border-color 0.15s ease;
}
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--ocean);
}
textarea { resize: vertical; min-height: 150px; }

.form-success {
  margin-top: 16px;
  font-size: 1rem;
  font-weight: 500;
  color: var(--ocean);
}
.form-success[hidden] { display: none; }

/* ---------- CTA band (final CTA — gradient allowed) ---------- */

.cta-band {
  background: var(--grad);
  color: var(--white);
  position: relative;
  overflow: hidden;
  text-align: center;
}
.cta-band .ripple {
  position: absolute;
  right: -160px;
  bottom: -260px;
  width: 560px; height: 560px;
  opacity: 0.25;
  pointer-events: none;
}
.cta-band h2 { color: var(--white); max-width: 24ch; margin: 16px auto 20px; }
.cta-band p { color: rgba(255,255,255,0.85); max-width: 52ch; margin: 0 auto 40px; }
.cta-band .btn-row { justify-content: center; }
.cta-band .cta-alt {
  display: block;
  margin-top: 26px;
  font-family: var(--sans);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.85);
  text-decoration: none;
  border-bottom: none;
}
.cta-band .cta-alt:hover { color: var(--white); }

/* ---------- Footer ---------- */

.site-footer {
  background: var(--deep);
  color: rgba(255, 255, 255, 0.78);
  padding: 72px 0 40px;
  font-size: 0.98rem;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.15fr 1.3fr;
  gap: 44px;
  margin-bottom: 52px;
}

.footer-mono {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  box-shadow: var(--shadow-1-dark);
}

.site-footer .tagline {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.12rem;
  color: var(--sage);
  margin: 18px 0 14px;
  max-width: 30ch;
  line-height: 1.5;
}

.site-footer h4 {
  font-family: var(--sans);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--sage);
  margin-bottom: 20px;
}

.site-footer ul { list-style: none; }
.site-footer li { margin-bottom: 12px; }
.site-footer a {
  color: rgba(255, 255, 255, 0.78);
  text-decoration: none;
  font-size: 0.98rem;
}
.site-footer a:hover { color: var(--white); }

.footer-signup .signup-tag {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.05rem;
  color: rgba(255, 255, 255, 0.85);
  margin-bottom: 16px;
  text-transform: none;
  letter-spacing: 0;
}
.footer-signup .signup-row { display: flex; gap: 10px; }
.footer-signup input {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--white);
}
.footer-signup input::placeholder { color: rgba(255, 255, 255, 0.55); }
.footer-signup input:focus { border-color: var(--sage); }
.footer-signup .btn { padding: 14px 22px; font-size: 0.76rem; box-shadow: none; flex-shrink: 0; }

/* A grid track of 1fr still has min-width:auto, so it cannot shrink
   below its contents. The signup row is a flex row holding an input
   at its default intrinsic width next to a button with flex-shrink:0,
   and their combined min-content came to 419px - wider than a 390px
   phone. The track grew to fit and took the whole page sideways with
   it, on every page that has a footer. That is a min-content blowout,
   and the fix is to let the track and the input shrink. */
.footer-grid > * { min-width: 0; }
.footer-signup .signup-row { min-width: 0; }
.footer-signup .signup-row input { min-width: 0; width: auto; flex: 1 1 0; }
/* The Turnstile widget is injected INTO this flex row, and a Turnstile
   box is a fixed 300px that will not shrink. Input + widget + button
   came to 433px in a 334px row and pushed the page sideways on every
   phone. It only started doing that when the site key was fixed on
   27 Aug - before that the widget errored and rendered nothing, so it
   cost no width and hid this.

   The row wraps and the widget takes a line of its own. With
   appearance:"interaction-only" it is zero-height for almost everyone,
   so nothing moves; when Cloudflare does want to challenge someone it
   appears under the field, which is where it belongs anyway. */
.footer-signup .signup-row { flex-wrap: wrap; }
.footer-signup .signup-row .jr-turnstile { flex: 0 0 100%; width: 100%; }

/* ---- Waiver dialog ----
   Shown before checkout for anything that needs a participation
   agreement. Scrolls internally rather than growing the page, because
   on a phone the agreement text plus two fields plus a checkbox is
   taller than the viewport. */
.jr-modal-back {
  position: fixed; inset: 0; z-index: 2000;
  background: rgba(16, 34, 43, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 20px; overflow-y: auto;
}
.jr-modal {
  background: var(--paper); border-radius: var(--radius);
  box-shadow: 0 24px 60px rgba(16,34,43,0.28);
  padding: 30px 32px; max-width: 540px; width: 100%;
  max-height: calc(100vh - 40px); overflow-y: auto;
}
.jr-modal h2 { font-size: 1.5rem; margin: 0 0 10px; }
.jr-modal .jrw-sub { font-size: 0.95rem; color: #46555E; margin-bottom: 20px; line-height: 1.55; }
.jr-modal .jrw-l {
  display: block; margin: 0 0 6px; font-family: var(--sans);
  font-size: 0.95rem; font-weight: 600; text-transform: none;
  letter-spacing: 0; color: var(--ink);
}
.jr-modal input[type="text"], .jr-modal input[type="email"] { margin-bottom: 16px; }
.jrw-agree {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 14px 16px; border: 1.7px solid rgba(54,91,109,0.18);
  border-radius: var(--radius); background: var(--ivory);
  font-family: var(--sans); font-size: 0.93rem; font-weight: 400;
  text-transform: none; letter-spacing: 0; line-height: 1.5;
  color: var(--ink); cursor: pointer; margin: 4px 0 0;
}
.jrw-agree:has(input:checked) { border-color: var(--ocean); background: rgba(27,86,141,0.06); }
.jrw-agree input { width: auto; flex: 0 0 auto; margin-top: 3px; accent-color: var(--ocean); }
.jrw-err { color: #b4453b; font-size: 0.9rem; margin: 12px 0 0; }
.jrw-row { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 22px; }
@media (max-width: 560px) {
  .jr-modal { padding: 24px 20px; }
  .jrw-row .btn { width: 100%; }
}
.site-footer .form-success { color: var(--sage); }

.footer-mid {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  padding-top: 28px;
}

.social-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.28);
  color: rgba(255, 255, 255, 0.85);
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.social-icon:hover { background: var(--sage); border-color: var(--sage); color: var(--deep); }
.social-icon svg { width: 18px; height: 18px; }

.sagefire-badge { display: inline-block; line-height: 0; }
.sagefire-badge img { transition: transform 0.15s ease; }
.sagefire-badge:hover img { transform: translateY(-3px); }

.footer-base {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 26px;
}
.footer-base a { font-size: 0.85rem; color: rgba(255, 255, 255, 0.6); }

/* The crisis line rides on the copyright line rather than sitting
   under it, so the last row of the footer is one row. It is a flex
   item, not inline text, so on a narrow screen it drops whole
   underneath the copyright instead of reflowing through it. */
.footer-legal {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 16px;
  min-width: 0;
}
.footer-disclaimer {
  margin: 0;
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.45);
}

/* ---------- Utility ---------- */

.mt-1 { margin-top: 18px; }
.mt-2 { margin-top: 36px; }
.mt-3 { margin-top: 56px; }
.note {
  font-size: 0.88rem;
  color: #7C888E;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Responsive: layout ---------- */

@media (max-width: 900px) {
  .grid-2, .grid-3, .steps, .split, .form-grid { grid-template-columns: 1fr; }
  .grid-4 { grid-template-columns: 1fr 1fr; }
  .split { gap: 44px; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 36px; }
  .hero-inner { padding: 56px 28px 64px; }
  section { padding: 72px 0; }
  .episode { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 640px) {
  .grid-4 { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; }
}

/* ---------- Responsive: nav collapses below 1140px ---------- */

@media (max-width: 1140px) {
  .nav-toggle-label { display: block; }
  .nav-links {
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--ivory);
    border-bottom: 1px solid rgba(54, 91, 109, 0.12);
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease;
  }
  .nav-links li { width: 100%; }
  .nav-links a {
    display: block;
    padding: 18px 28px;
    font-size: 0.82rem;
    letter-spacing: 0.12em;
    border-bottom: 1px solid rgba(54, 91, 109, 0.08);
  }
  .nav-links .nav-cta { border-radius: 0; text-align: center; padding: 18px 28px; }
  .nav-links .nav-donate,
  .nav-links .nav-login { border: none; border-radius: 0; border-bottom: 1px solid rgba(54, 91, 109, 0.08); padding: 18px 28px; }
  .nav-links .nav-login:hover { background: none; color: var(--ocean); }
  .nav-toggle:checked ~ .nav-links { max-height: 640px; }
}

/* ---------- Brand lockup & monogram ---------- */
.brand-logo{ display:inline-flex; align-items:center; gap:12px; text-decoration:none; white-space:nowrap; }
.brand-img{ height:46px; width:auto; display:block; }
.brand-mono{ height:44px; width:44px; border-radius:50%; display:block; }
.site-header .brand-mono{ display:none; }
@media (max-width:600px){ .brand-mono{ height:36px; width:36px; } .site-header .brand-img{ height:38px; } }

/* Monogram used as podcast art */
.ep-art{ background:none !important; box-shadow:none !important; }
.ep-mono-img{ width:86px; height:86px; border-radius:50%; display:block; box-shadow:var(--shadow-1); }

/* ---------- Month timeline (Becoming) ---------- */
.timeline{ display:grid; grid-template-columns:repeat(2,1fr); gap:20px; }
.tl-item{ background:var(--paper); border-radius:var(--radius); padding:26px 28px; box-shadow:var(--shadow); border-left:4px solid var(--sage); }
.tl-item:nth-child(1){ border-left-color:var(--ocean); }
.tl-month{ font-family:var(--sans); font-size:0.72rem; font-weight:700; letter-spacing:0.2em; text-transform:uppercase; color:var(--ocean); }
.tl-item h3{ margin:8px 0 8px; font-size:1.24rem; }
.tl-item p{ font-size:0.96rem; color:#46555E; }
.tl-focus{ margin-top:12px; font-size:0.8rem; color:var(--sage); font-weight:600; letter-spacing:0.02em; }
@media (max-width:700px){ .timeline{ grid-template-columns:1fr; } }

/* ---------- Assessment engine ---------- */
.assess{ max-width:760px; margin:0 auto; }
.assess-card{ background:var(--paper); border-radius:var(--radius); box-shadow:var(--shadow); padding:40px 40px; }
.assess-progress{ position:sticky; top:74px; z-index:30; background:rgba(239,239,236,0.94); backdrop-filter:blur(8px); padding:14px 0 12px; margin-bottom:8px; }
.assess-count{ font-family:var(--sans); font-size:0.8rem; font-weight:600; letter-spacing:0.04em; color:var(--deep); margin-bottom:8px; }
.assess-bar{ height:8px; background:var(--sage-tint); border-radius:999px; overflow:hidden; }
.assess-bar > span{ display:block; height:100%; width:0; background:var(--grad); border-radius:999px; transition:width .3s ease; }
.q-section-head{ margin:34px 0 6px; }
.q-section-head .label{ display:block; margin-bottom:6px; }
.q-section-head h2{ font-size:1.7rem; }
.q-card{ background:var(--paper); border-radius:var(--radius); box-shadow:var(--shadow); padding:28px 32px; margin-bottom:16px; scroll-margin-top:150px; }
.q-num{ font-family:var(--sans); font-size:0.7rem; font-weight:700; letter-spacing:0.2em; text-transform:uppercase; color:var(--sage); }
.q-text{ font-family:var(--serif); font-size:1.26rem; color:var(--deep); line-height:1.35; margin:8px 0 20px; font-weight:400; }
.likert{ display:flex; flex-direction:column; gap:9px; }
.likert label{ display:flex; align-items:center; gap:13px; padding:12px 18px; border:1.7px solid rgba(54,91,109,0.16); border-radius: var(--radius); cursor:pointer; font-family:var(--sans); font-weight:400; font-size:0.98rem; text-transform:none; letter-spacing:0; color:var(--ink); margin:0; transition:border-color .13s ease, background .13s ease; }
.likert label:hover{ border-color:var(--sage); background:var(--sage-tint); }
.likert input{ width:auto; accent-color:var(--ocean); flex-shrink:0; margin:0; cursor:pointer; }
.likert label:has(input:checked){ border-color:var(--ocean); background:rgba(27,86,141,0.06); font-weight:600; color:var(--ocean); }
.assess-actions{ margin-top:26px; }
.assess-note{ font-size:0.86rem; color:#7C888E; margin-top:14px; }
.hidden{ display:none !important; }

/* results */
.result-ring{ width:190px; height:190px; margin:0 auto 10px; position:relative; }
.result-ring svg{ display:block; transform:rotate(-90deg); }
.result-ring .rv{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; }
.result-ring .rv b{ font-family:var(--serif); font-size:2.7rem; color:var(--deep); font-weight:400; line-height:1; }
.result-ring .rv small{ font-family:var(--sans); font-size:0.7rem; letter-spacing:0.16em; text-transform:uppercase; color:#7C888E; margin-top:4px; }
.result-band{ font-family:var(--serif); font-size:1.8rem; color:var(--ocean); text-align:center; margin:8px 0 6px; }
.result-blurb{ text-align:center; max-width:52ch; margin:0 auto 8px; color:#46555E; }
.result-sections{ display:grid; gap:14px; margin:30px 0 8px; }
.rs-top{ display:flex; justify-content:space-between; font-family:var(--sans); font-size:0.9rem; font-weight:600; color:var(--deep); margin-bottom:6px; }
.rs-bar{ height:10px; background:var(--sage-tint); border-radius:999px; overflow:hidden; }
.rs-bar > span{ display:block; height:100%; background:var(--grad); border-radius:999px; }

/* ---- By Design (Becoming month 5) ----
   The only assessment that is not a 1-10 scale: four written options
   per question, and a named result per dimension instead of a ring.
   Options run to two lines on a phone, so the radio aligns to the top
   of the text rather than its middle. */
.likert--choice label{ align-items:flex-start; line-height:1.45; }
.likert--choice input{ margin-top:4px; }
.q-letter{ font-family:var(--sans); font-weight:700; color:var(--ocean); margin-right:7px; letter-spacing:0.04em; }
.design-seg{ background:var(--sage-tint); border-radius:var(--radius); padding:20px 22px; text-align:left; }
.design-seg .rs-top{ margin-bottom:2px; }
.design-seg .rs-bar{ margin-top:12px; }
.ds-label{ font-family:var(--serif); font-size:1.35rem; color:var(--ocean); line-height:1.22; margin:2px 0 0; }
.ds-second{ font-family:var(--sans); font-size:0.88rem; color:#46555E; margin-top:5px; }
.ds-second b{ color:var(--deep); font-weight:600; }
.ds-blurb{ font-family:var(--sans); font-size:0.94rem; color:#46555E; line-height:1.55; margin:11px 0 0; text-align:left; max-width:none; }
@media (max-width:640px){
  .design-seg{ padding:16px 17px; }
  .ds-label{ font-size:1.16rem; }
}

/* assessment hub cards */
.assess-list{ display:grid; grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); gap:16px; }
.assess-tile{ display:flex; flex-direction:column; background:var(--paper); border-radius: var(--radius); box-shadow:var(--shadow); padding:24px 26px; text-decoration:none; border-top:4px solid var(--sage); transition:transform .15s ease; }
.assess-tile:hover{ transform:translateY(-4px); }
.assess-tile .at-month{ font-family:var(--sans); font-size:0.7rem; font-weight:700; letter-spacing:0.2em; text-transform:uppercase; color:var(--ocean); }
.assess-tile h3{ font-size:1.12rem; margin:8px 0 6px; }
.assess-tile p{ font-size:0.9rem; color:#46555E; }

/* ============================================================
   V2 COMPONENTS — offer cards, ladder, compare table, phases,
   checklists, waitlist forms, routes, domains, scripture
   ============================================================ */

/* ---- Offer cards (product ladder rows) ---- */
.offer-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; }

.offer-card {
  display: flex;
  flex-direction: column;
  background: var(--ivory);
  border: 1px solid rgba(134, 173, 160, 0.6);
  border-radius: var(--radius);
  padding: 34px 30px;
  text-decoration: none;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.offer-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.offer-card h3 { font-size: 1.38rem; margin-bottom: 10px; }
.offer-card p { font-size: 0.98rem; color: #46555E; flex-grow: 1; }
.offer-card .textlink { margin-top: 24px; align-self: flex-start; }

.offer-chip {
  align-self: flex-start;
  justify-self: start;          /* grid rows below: keep the pill its own width */
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ocean);
  border: 1.5px solid var(--sage);
  border-radius: 999px;
  padding: 6px 14px;
  margin-bottom: 18px;
  white-space: nowrap;
}

.offer-card--featured {
  position: relative;
  overflow: hidden;
  background: var(--grad);
  border-color: transparent;
}
.offer-card--featured h3 { color: var(--white); }
.offer-card--featured p { color: rgba(255, 255, 255, 0.88); }
.offer-card--featured .offer-chip { color: var(--white); border-color: rgba(255, 255, 255, 0.55); }
.offer-card--featured .textlink { color: var(--white); border-color: rgba(255, 255, 255, 0.6); }
.offer-card--featured .ripple-corner {
  position: absolute;
  right: -120px;
  bottom: -120px;
  width: 320px;
  height: 320px;
  opacity: 0.3;
  pointer-events: none;
}

@media (max-width: 1024px) { .offer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .offer-grid { grid-template-columns: 1fr; } }

/* ---- Ladder (numbered vertical rail) ---- */
.ladder { position: relative; max-width: 860px; counter-reset: rung; }
.ladder::before {
  content: "";
  position: absolute;
  left: 26px;
  top: 10px;
  bottom: 10px;
  width: 1.7px;
  background: rgba(134, 173, 160, 0.5);
}
.rung {
  position: relative;
  counter-increment: rung;
  display: flex;
  gap: 28px;
  padding-bottom: 40px;
}
.rung:last-child { padding-bottom: 0; }
.rung-num {
  flex-shrink: 0;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1.7px solid var(--sage);
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-size: 1.1rem;
  color: var(--deep);
  position: relative;
  z-index: 1;
}
.rung-num::before { content: "0" counter(rung); }
.rung-card {
  flex-grow: 1;
  background: var(--paper);
  border: 1px solid rgba(134, 173, 160, 0.45);
  border-radius: var(--radius);
  padding: 30px 32px;
}
.rung-card h3 { font-size: 1.36rem; margin-bottom: 8px; }
.rung-card p { font-size: 1rem; color: #46555E; }
.rung-card .offer-chip { margin-bottom: 14px; }
.rung-card .textlink { display: inline-block; margin-top: 18px; }
.rung--featured .rung-card {
  position: relative;
  overflow: hidden;
  background: var(--grad);
  border-color: transparent;
}
.rung--featured .rung-card h3 { color: var(--white); }
.rung--featured .rung-card p { color: rgba(255, 255, 255, 0.88); }
.rung--featured .rung-card .offer-chip { color: var(--white); border-color: rgba(255, 255, 255, 0.55); }
.rung--featured .rung-card .textlink { color: var(--white); border-color: rgba(255, 255, 255, 0.6); }
.rung--featured .rung-num { border-color: var(--ocean); color: var(--ocean); }

@media (max-width: 640px) {
  .ladder::before { left: 20px; }
  .rung { gap: 18px; }
  .rung-num { width: 40px; height: 40px; font-size: 0.95rem; }
  .rung-card { padding: 24px 22px; }
}

/* ---- Pull line ---- */
.pull-line {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  line-height: 1.4;
  color: var(--deep);
  border-left: 3px solid var(--sage);
  padding-left: 26px;
  max-width: 38ch;
}

/* ---- Compare table (approach) ---- */
.table-scroll { overflow-x: auto; }
.compare {
  width: 100%;
  min-width: 520px;
  border-collapse: collapse;
  background: var(--paper);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.compare th {
  font-family: var(--sans);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--deep);
  background: var(--sage-tint);
  text-align: left;
  padding: 20px 30px;
}
.compare td {
  padding: 20px 30px;
  font-size: 1.02rem;
  color: #46555E;
  border-bottom: 1px solid rgba(134, 173, 160, 0.3);
  vertical-align: top;
}
.compare tr:last-child td { border-bottom: none; }
.compare td:first-child { color: #7C888E; }
.compare td:last-child { color: var(--deep); font-weight: 500; }

/* ---- Phase cards (Formation Journey) ---- */
.phase-card {
  background: var(--paper);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  border-top: 5px solid var(--sage);
  padding: 40px 36px;
}
.phase-card--alt { border-top-color: var(--ocean); }
.phase-card .phase-meta {
  font-family: var(--sans);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sage);
  margin: 6px 0 16px;
}
.phase-card ul { list-style: none; }
.phase-card li {
  position: relative;
  padding: 9px 0 9px 30px;
  font-size: 0.99rem;
  color: #46555E;
  border-bottom: 1px solid rgba(134, 173, 160, 0.22);
}
.phase-card li:last-child { border-bottom: none; }
.phase-card li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 15px;
  width: 15px; height: 15px;
  border-radius: 50%;
  border: 1.7px solid var(--sage);
}

/* ---- Checklist (what's included) ---- */
.checklist {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 40px;
}
.checklist li {
  position: relative;
  padding: 13px 0 13px 38px;
  font-size: 1.02rem;
  color: #46555E;
  border-bottom: 1px solid rgba(134, 173, 160, 0.25);
}
.checklist li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 19px;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1.7px solid var(--sage);
  background: radial-gradient(circle, var(--sage) 0 4px, transparent 4.5px);
}
@media (max-width: 700px) { .checklist { grid-template-columns: 1fr; } }

/* ---- Status banner + waitlist forms ---- */
.status-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  background: var(--sage-tint);
  border: 1px solid rgba(134, 173, 160, 0.6);
  border-radius: var(--radius);
  padding: 18px 24px;
  font-size: 1rem;
  color: var(--deep);
}
.status-chip {
  flex-shrink: 0;
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--white);
  background: var(--ocean);
  border-radius: 999px;
  padding: 6px 15px;
}

.waitlist-form { max-width: 620px; }
.waitlist-form .form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-bottom: 18px;
}
.waitlist-form .form-row .full { grid-column: 1 / -1; }
@media (max-width: 640px) { .waitlist-form .form-row { grid-template-columns: 1fr; } }

/* ---- Route cards ("not sure where to start") ---- */
.route-card {
  background: var(--paper);
  border: 1px solid rgba(134, 173, 160, 0.5);
  border-radius: var(--radius);
  padding: 36px 32px;
  display: flex;
  flex-direction: column;
}
.route-card .route-q {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.3rem;
  color: var(--deep);
  line-height: 1.4;
  margin-bottom: 14px;
}
.route-card p { font-size: 0.98rem; color: #46555E; flex-grow: 1; }
.route-card .textlink { margin-top: 22px; align-self: flex-start; }

/* ---- Domains grid (approach) ---- */
.domain-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
  gap: 18px;
}
.domain {
  background: var(--paper);
  border-radius: var(--radius);
  border-top: 4px solid var(--sage);
  box-shadow: var(--shadow);
  padding: 26px 24px;
}
.domain h3 { font-size: 1.2rem; margin-bottom: 8px; }
.domain p { font-family: var(--serif); font-style: italic; font-size: 1rem; color: #46555E; line-height: 1.5; }

/* ---- Scripture close ---- */
.scripture {
  max-width: 640px;
  margin: 0 auto;
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.35rem, 2.8vw, 1.8rem);
  line-height: 1.5;
  color: var(--deep);
}
.scripture cite {
  display: block;
  margin-top: 18px;
  font-family: var(--sans);
  font-style: normal;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--sage);
}

/* ---- Care / boundary note ---- */
.care-note {
  background: var(--paper);
  border-left: 4px solid var(--sage);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 26px 30px;
  font-size: 1rem;
  color: #46555E;
  max-width: 760px;
}
.care-note strong { color: var(--deep); }

/* ============================================================
   BRAND BOOK LAYER — Joy Restored Brand Book, Edition 2026
   Montserrat for eyebrows/labels/buttons · Dawn & Seed textures
   ============================================================ */

/* Labels & accents set in Montserrat (brand book §03 Type) */
/* .nav-links a is deliberately NOT in this list. The dropdown tops
   ("Start Here", "Shop", "Resources", "Donate") are <button>s carrying
   .nav-top, which sets var(--sans); the plain links are <a>s and used
   to get pulled into Montserrat here, so the two halves of the same
   nav row rendered in different faces. Everything in the header now
   follows .nav-top. */
.label, .btn, .textlink, .badge, .offer-chip, .status-chip,
.ep-num, .tl-month, .q-num, .assess-tile .at-month, .site-footer h4,
.quote-band cite, .scripture cite, .platform-row a, .phase-card .phase-meta,
.compare th, .cta-band .cta-alt, .result-ring .rv small,
.portrait-frame .placeholder-note, form label, .form-grid label,
.waitlist-form label, .footer-signup label {
  font-family: var(--mont);
}
.likert label { font-family: var(--sans); } /* answer options stay body sans */

/* The Dawn — rings rising like a sunrise (gradient hero + CTA panels).
   One texture per layout: Dawn replaces the old SVG ripples here. */
.hero .ripple, .cta-band .ripple { display: none; }
.hero::before, .cta-band::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-radial-gradient(circle at 50% 135%,
    rgba(255, 255, 255, 0) 0 44px,
    rgba(255, 255, 255, 0.09) 44px 45px);
}

/* Paper cards carry the brand hairline (#E7E0D2) */
.card, .step, .faq details, .episode, .contact-card, .q-card,
.assess-card, .assess-tile, .domain, .tl-item, .package, .phase-card {
  border: 1px solid var(--line);
}
.package { border-top: 5px solid var(--sage); }
.package--featured { border-top-color: var(--ocean); }
.phase-card { border-top: 5px solid var(--sage); }
.phase-card--alt { border-top-color: var(--ocean); }
.assess-tile { border-top: 4px solid var(--sage); }
.domain { border-top: 4px solid var(--sage); }
.tl-item { border-left: 4px solid var(--sage); }
.tl-item:nth-child(1) { border-left-color: var(--ocean); }
.card--feature { border: none; }

/* ============================================================
   STRUCTURE BRIEF LAYER — three doors · five domains · motion
   ============================================================ */

/* Header: the JR avatar carries the brand alone (no wordmark) */
.site-header .brand-mono { display: block; height: 66px; width: 66px; }
.site-header .brand-img { display: none; }
.brand-logo img { flex: none; }

/* Nav donate button */
.nav-links .nav-donate {
  color: var(--ocean);
  border: 1.5px solid var(--sage);
  border-radius: 999px;
  padding: 10px 20px;
  border-bottom: 1.5px solid var(--sage);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.nav-links .nav-donate:hover,
.nav-links .nav-donate.active { background: var(--sage); border-color: var(--sage); color: var(--white); }

/* Nav log-in button.
   A pill, so it reads as a control rather than another place to read,
   and outlined rather than filled so it sits beside Donate without
   the two of them competing for the same eye. Ocean against Donate's
   sage keeps them told apart at a glance. */
.nav-links .nav-login {
  color: var(--ocean);
  border: 1.5px solid rgba(27, 86, 141, 0.45);
  border-radius: 999px;
  padding: 10px 20px;
  border-bottom: 1.5px solid rgba(27, 86, 141, 0.45);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.nav-links .nav-login:hover,
.nav-links .nav-login.active { background: var(--ocean); border-color: var(--ocean); color: var(--white); }

/* ---- Hero: split with portrait + parallax Dawn rings ---- */
.hero .rings, .hero .rings2 {
  position: absolute; inset: -12%; pointer-events: none;
  transition: transform 0.4s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.hero .rings {
  background: repeating-radial-gradient(circle at 50% 132%, rgba(255,255,255,0) 0 52px, rgba(255,255,255,0.10) 52px 53px);
  transform: translate(calc(var(--mx, 0) * 24px), calc(var(--my, 0) * 15px));
}
.hero .rings2 {
  display: none;
  background: none;
  transform: translate(calc(var(--mx, 0) * -16px), calc(var(--my, 0) * -11px));
}
.hero-grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 56px;
  align-items: center;
}
.hero-portrait {
  position: relative;
  justify-self: end;
  width: min(100%, 420px);
}
.hero-portrait img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 18%;
  border-radius: var(--radius);
  box-shadow: var(--shadow-4-dark);
}
.hero-portrait::before {
  content: "";
  position: absolute;
  inset: -22px;
  border: 1.5px solid rgba(255, 255, 255, 0.28);
  border-radius: calc(var(--radius) + 10px);
  pointer-events: none;
}
.hero-portrait .hp-tag {
  position: absolute;
  left: 22px; bottom: 20px;
  background: rgba(252, 251, 247, 0.92);
  color: var(--deep);
  border-radius: 999px;
  padding: 9px 18px;
  font-family: var(--mont);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  box-shadow: var(--shadow-1-dark);
}
@media (max-width: 940px) {
  .hero-grid { grid-template-columns: 1fr; gap: 40px; }
  .hero-portrait { justify-self: start; width: min(100%, 340px); }
}

/* ---- Door buttons (hero): one decision — which door ---- */
.door-lead {
  font-family: var(--mont);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
  margin-bottom: 14px;
}
.door-btns { display: flex; flex-direction: column; gap: 12px; max-width: 460px; }
.door-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  background: rgba(252, 251, 247, 0.94);
  color: var(--deep);
  text-decoration: none;
  border-radius: var(--radius);
  padding: 17px 22px;
  font-family: var(--serif);
  font-size: 1.18rem;
  overflow: hidden;
  transition: transform 0.25s ease, box-shadow 0.25s ease, background 0.25s ease;
}
.door-btn .db-arrow {
  flex: none;
  font-family: var(--sans);
  color: var(--sage);
  transition: transform 0.25s ease, color 0.25s ease;
}
.door-btn:hover {
  transform: translateX(6px);
  background: var(--paper);
  box-shadow: var(--shadow-2-dark);
}
.door-btn:hover .db-arrow { transform: translateX(4px); color: var(--ocean); }

/* ---- Door cards (the three doors, spelled out) ---- */
.door-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 42px 38px;
  text-decoration: none;
  overflow: hidden;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.door-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-3); }
.door-card .dc-feel {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: 1.5rem;
  line-height: 1.3;
  color: var(--deep);
  margin: 0 0 14px;
}
.door-card .dc-name {
  font-family: var(--mont);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--sage);
  margin-bottom: 16px;
}
.door-card p { font-size: 1rem; color: #46555E; flex-grow: 1; }
.door-card .textlink { margin-top: 24px; align-self: flex-start; }
.door-card::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 4px;
  background: var(--grad);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s ease;
}
.door-card:hover::after { transform: scaleX(1); }

/* ---- Five domains: connected nodes (a map, not a menu) ---- */
.domain-map {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  max-width: 880px;
  margin: 0 auto;
  padding: 26px 0 10px;
}
.domain-map::before {
  content: "";
  position: absolute;
  left: 7%; right: 7%;
  top: 76px;
  height: 1.5px;
  background: linear-gradient(90deg, rgba(134,173,160,0.15), rgba(134,173,160,0.75) 22%, rgba(134,173,160,0.75) 78%, rgba(134,173,160,0.15));
}
.dnode {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 19%;
  text-align: center;
}
.dnode .dn-circle {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: var(--paper);
  border: 1.5px solid var(--sage);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ocean);
  box-shadow: var(--shadow-1);
  transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
  position: relative;
}
.dnode .dn-circle::after {
  content: "";
  position: absolute;
  inset: -9px;
  border-radius: 50%;
  border: 1.5px solid rgba(134, 173, 160, 0.35);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.dnode:hover .dn-circle {
  transform: translateY(-6px);
  border-color: var(--ocean);
  box-shadow: var(--shadow-3);
}
.dnode:hover .dn-circle::after { opacity: 1; animation: dn-ring 1.6s ease-out infinite; }
@keyframes dn-ring {
  0% { transform: scale(0.92); opacity: 0.8; }
  100% { transform: scale(1.22); opacity: 0; }
}
.dnode .dn-circle svg { width: 40px; height: 40px; }
.dnode h3 { font-size: 1.16rem; }
.dnode p { font-family: var(--serif); font-style: italic; font-size: 0.92rem; color: #7C888E; line-height: 1.45; }
@media (max-width: 820px) {
  .domain-map { flex-wrap: wrap; justify-content: center; gap: 26px 18px; }
  .domain-map::before { display: none; }
  .dnode { width: 40%; }
}

/* ---- Scroll-reveal motion (calm: fade + small rise) ---- */
[data-reveal] { opacity: 0; transform: translateY(22px); transition: opacity 0.7s ease, transform 0.7s ease; }
[data-reveal].is-in { opacity: 1; transform: none; }
[data-reveal="stagger"] > * { opacity: 0; transform: translateY(22px); transition: opacity 0.6s ease, transform 0.6s ease; }
[data-reveal="stagger"].is-in > * { opacity: 1; transform: none; }
[data-reveal="stagger"].is-in > *:nth-child(2) { transition-delay: 0.1s; }
[data-reveal="stagger"].is-in > *:nth-child(3) { transition-delay: 0.2s; }
[data-reveal="stagger"].is-in > *:nth-child(4) { transition-delay: 0.3s; }
[data-reveal="stagger"].is-in > *:nth-child(5) { transition-delay: 0.4s; }

/* ---- Donate page ---- */
.give-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 46px 44px;
  max-width: 620px;
}
.amount-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 18px 0; }
.amount-btn {
  font-family: var(--mont);
  font-size: 1rem;
  font-weight: 600;
  color: var(--deep);
  background: var(--ivory);
  border: 1.7px solid rgba(54, 91, 109, 0.18);
  border-radius: var(--radius);
  padding: 16px 8px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.amount-btn:hover { border-color: var(--sage); }
.amount-btn.is-selected { background: var(--ocean); border-color: var(--ocean); color: var(--white); }
.freq-row { display: flex; gap: 10px; margin-bottom: 6px; }
.freq-btn {
  flex: 1;
  font-family: var(--mont);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--deep);
  background: var(--ivory);
  border: 1.7px solid rgba(54, 91, 109, 0.18);
  border-radius: 999px;
  padding: 13px 10px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.freq-btn.is-selected { background: var(--sage); border-color: var(--sage); color: var(--white); }
.custom-row { display: flex; align-items: center; gap: 10px; margin-bottom: 22px; }
.custom-row .currency { font-family: var(--serif); font-size: 1.4rem; color: var(--deep); }
@media (max-width: 560px) { .amount-grid { grid-template-columns: repeat(2, 1fr); } }

/* ---- Course cards (Stripe-powered library) ---- */
.course-card {
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 42px 38px;
}
/* Same shared rows as a ladder rung, for the same reason: one course
   title ran to two lines and the others to one, so the prices sat at
   two different heights and the row read crooked at exactly the point
   a buyer is comparing them. Chip, title, price, body, button, note.
   The body takes the slack so the buttons stay on the floor. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 901px) {
    .grid-3:has(> .course-card) { grid-template-rows: auto auto auto 1fr auto auto; }
    .course-card { grid-row: span 6; display: grid; grid-template-rows: subgrid; }
    .course-card > .offer-chip     { grid-row: 1; }
    .course-card > h3              { grid-row: 2; }
    .course-card > .price          { grid-row: 3; }
    .course-card > p:not(.pay-note) { grid-row: 4; }
    .course-card > .btn            { grid-row: 5; }
    .course-card > .pay-note       { grid-row: 6; }
  }
}

.course-card .price {
  font-family: var(--serif);
  font-size: 2.1rem;
  font-weight: 300;
  color: var(--deep);
  margin: 14px 0 6px;
}
.course-card p { color: #46555E; font-size: 1rem; flex-grow: 1; }
.course-card .btn { margin-top: 26px; align-self: flex-start; }
.pay-note { font-size: 0.86rem; color: #7C888E; margin-top: 14px; }

/* ---- Motion safety ---- */
@media (prefers-reduced-motion: reduce) {
  [data-reveal], [data-reveal="stagger"] > * { opacity: 1; transform: none; transition: none; }
  .hero .rings, .hero .rings2 { transition: none; transform: none; }
  .dnode:hover .dn-circle::after { animation: none; }
}

/* ---- Section background: soft sky (Restoration Journey etc.) ---- */
.section-sky { background: #EAF2F6; }

/* ---- Door icons (home hero) + per-page hero marks ---- */
.db-main { display: flex; align-items: center; gap: 14px; min-width: 0; }
.db-ico {
  flex: none;
  width: 36px; height: 36px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--di, var(--door-formation-ink));
  color: var(--dii, #fff);
}
.db-ico svg { width: 19px; height: 19px; }
.page-mark {
  width: 56px; height: 56px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--pm, var(--door-formation-ink));
  color: var(--pmi, #fff);
  margin-bottom: 20px;
  box-shadow: var(--shadow-2-dark);
}
.page-mark svg { width: 26px; height: 26px; }

/* ---- Product rows (door pages) ---- */
.prod-row-label {
  display: block;
  font-family: var(--mont);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--sage);
  margin: 0 0 16px;
}
.prod-row-label--paid { color: var(--ocean); margin-top: 44px; }

/* ---- Journey walker (JR avatar) ---- */
.j-walker { cursor: grab; }
.j-walker.is-drag { cursor: grabbing; }

/* The header no longer shrinks on scroll, so the badge just sits
   centered and stays there. The old .is-scrolled size rules are
   gone rather than overridden, so nothing fights over the height. */
@media (max-width: 600px) {
  .site-header .brand-mono { height: 50px; width: 50px; }
}

/* The header monogram carries the same lift as the footer one. */
.site-header .brand-mono { box-shadow: var(--shadow-1-dark); }

/* ---- Headline word rotor (from Hero Lab concept 03) ---- */
.rotor { display: inline-block; position: relative; height: 1.16em; overflow: hidden; vertical-align: bottom; }
.rotor .rotor-track { display: flex; flex-direction: column; transition: transform 0.6s cubic-bezier(0.65, 0, 0.35, 1); }
.rotor i { font-style: italic; height: 1.16em; line-height: 1.16; white-space: nowrap; }
.nav-badge-li { position: relative; width: 74px; height: 44px; align-self: stretch; }
.nav-sagefire-badge {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  display: block;
  transition: top 0.3s ease, transform 0.3s ease;
}
.nav-sagefire-badge img { width: 74px; height: auto; display: block; transition: transform 0.15s ease; filter: drop-shadow(0 6px 16px rgba(20, 40, 55, 0.25)); }
.nav-sagefire-badge:hover img { transform: translateY(-2px); }
@media (max-width: 940px) { .nav-badge-li { display: none; } }

/* ============================================================
   V4 LAYER — socials · journey arc · cohorts · Let's Decode That
   ============================================================ */

/* ---- Social icons (hero + footer) ---- */
.social-row { display: flex; gap: 12px; margin-top: 30px; }
.social-row .social-icon { border-color: rgba(255, 255, 255, 0.4); color: rgba(255, 255, 255, 0.9); }
.social-row .social-icon:hover { background: var(--paper); border-color: var(--paper); color: var(--deep); }
.footer-social-row { display: flex; gap: 10px; align-items: center; }

/* ---- The Restoration Journey (rhythm × domains, one arc) ---- */
.journey { position: relative; max-width: 980px; margin: 0 auto; }
.journey-svg { width: 100%; height: auto; display: block; }
.journey-svg .j-path { fill: none; stroke: rgba(134, 173, 160, 0.45); stroke-width: 2; }
.journey-svg .j-path-done { fill: none; stroke: var(--sage); stroke-width: 3; stroke-linecap: round; }
.journey-svg .j-node circle.j-dot { fill: var(--paper); stroke: var(--sage); stroke-width: 1.7; transition: stroke 0.2s ease, r 0.2s ease; cursor: pointer; }
.journey-svg .j-node.is-here circle.j-dot { stroke: var(--ocean); stroke-width: 2.4; }
.journey-svg .j-node text { font-family: var(--serif); font-size: 21px; fill: var(--deep); }
.journey-svg .j-node .j-icon { color: var(--ocean); pointer-events: none; }
.journey-svg .j-walker { transition: transform 0.12s linear; pointer-events: none; }
.journey-scrub { width: 100%; margin: 8px 0 26px; accent-color: var(--ocean); cursor: ew-resize; height: 28px; }
.journey-card {
  max-width: 640px;
  margin: 0 auto;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 34px 40px;
  text-align: center;
  min-height: 172px;
}
.journey-card .jc-kind {
  font-family: var(--mont);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--sage);
}
.journey-card h3 { font-size: 1.6rem; margin: 8px 0 10px; }
.journey-card p { color: #46555E; font-size: 1.02rem; }
.journey-hint { text-align: center; font-size: 0.85rem; color: #7C888E; margin-top: 14px; }

/* ---- Cohort calendar ---- */
.cohort-month { margin-bottom: 44px; }
.cohort-month h2 { font-size: 1.7rem; margin-bottom: 6px; }
.cohort-month .cm-empty { color: #7C888E; font-size: 0.98rem; font-style: italic; }
.cohort-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 18px; margin-top: 18px; }
.cohort-slot {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px 28px;
  cursor: pointer;
  text-align: left;
  font-family: var(--sans);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.cohort-slot:hover { transform: translateY(-4px); box-shadow: var(--shadow-3); border-color: var(--sage); }
.cohort-slot .cs-date { font-family: var(--mont); font-size: 0.68rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ocean); }
.cohort-slot h3 { font-size: 1.3rem; }
.cohort-slot .cs-time { font-size: 0.95rem; color: #46555E; }
.cohort-slot .cs-meta { display: flex; gap: 10px; align-items: center; margin-top: 6px; flex-wrap: wrap; }
.cohort-slot .cs-seats { font-size: 0.82rem; color: #7C888E; }
.cohort-slot.is-full { opacity: 0.55; cursor: default; }
.cohort-slot.is-full:hover { transform: none; box-shadow: none; border-color: var(--line); }

/* cohort detail modal */
.cohort-modal[hidden] { display: none; }
.cohort-modal {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(33, 50, 64, 0.55);
  backdrop-filter: blur(4px);
}
.cohort-modal .cmo-card {
  background: var(--paper);
  border-radius: var(--radius);
  box-shadow: var(--shadow-4-dark);
  max-width: 560px;
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
  padding: 44px 44px 38px;
  position: relative;
}
.cohort-modal .cmo-close {
  position: absolute; top: 18px; right: 20px;
  background: none; border: none; cursor: pointer;
  font-size: 1.6rem; color: #7C888E; line-height: 1;
}
.cohort-modal .cmo-when {
  display: inline-block;
  font-family: var(--mont); font-size: 0.7rem; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--white); background: var(--ocean);
  border-radius: 999px; padding: 7px 16px; margin-bottom: 16px;
}
.cohort-modal h2 { font-size: 1.8rem; margin-bottom: 10px; }
.cohort-modal .cmo-body p { color: #46555E; font-size: 1rem; margin-bottom: 12px; }
.cohort-modal .cmo-facts { list-style: none; margin: 18px 0 24px; }
.cohort-modal .cmo-facts li {
  position: relative; padding: 8px 0 8px 30px;
  font-size: 0.98rem; color: #46555E;
  border-bottom: 1px solid rgba(134, 173, 160, 0.22);
}
.cohort-modal .cmo-facts li:last-child { border-bottom: none; }
.cohort-modal .cmo-facts li::before {
  content: ""; position: absolute; left: 0; top: 14px;
  width: 14px; height: 14px; border-radius: 50%;
  border: 1.7px solid var(--sage);
}
.cohort-modal .price { font-family: var(--serif); font-size: 2rem; color: var(--deep); margin-bottom: 14px; }

/* ---- Let's Decode That ---- */
.tm { font-size: 0.55em; vertical-align: super; }
.clarity-card {
  max-width: 720px;
  margin: 0 auto;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 52px 52px 46px;
}
.clarity-card .cw-steps { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; margin: 30px 0; }
.clarity-card .cw-step { text-align: center; }
.clarity-card .cw-step .icon-circle { margin: 0 auto 12px; }
.clarity-card .cw-step h3 { font-size: 1.06rem; margin-bottom: 6px; }
.clarity-card .cw-step p { font-size: 0.9rem; color: #46555E; }
.isnt-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 24px 0 30px; }
.isnt-col { border-radius: var(--radius); padding: 20px 24px; font-size: 0.95rem; }
.isnt-col ul { list-style: none; }
.isnt-col li { padding: 6px 0; color: #46555E; }
.isnt-col--is { background: rgba(134, 173, 160, 0.14); border: 1px solid rgba(134, 173, 160, 0.4); }
.isnt-col--isnt { background: rgba(58, 71, 90, 0.06); border: 1px solid rgba(58, 71, 90, 0.15); }
.price-block {
  text-align: center;
  background: var(--ivory);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 26px;
  margin-bottom: 26px;
}
.price-block .pb-price { font-family: var(--serif); font-size: 2rem; color: var(--deep); }
.price-block p { color: #46555E; font-size: 0.95rem; }
@media (max-width: 680px) {
  .clarity-card { padding: 36px 26px; }
  .clarity-card .cw-steps, .isnt-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   decode tool (guided conversation)

   The conversation used to run straight down the page on the site's
   ordinary paper, which made the one paid tool on the site look like
   the least designed thing on it. It is a tile now, wearing the same
   surface Let's Decode That wears everywhere else it appears: the
   slate gradient, the seeded dot field, the sky rule along the top,
   the monogram in the corner and one slow pass of light across it.
   Someone who clicked a Decode card lands somewhere that plainly
   belongs to it.

   The tile is dark and the guide's bubbles stay light on purpose.
   Your Decoded Map arrives inside one of them and runs to several
   hundred words, and long-form reading wants dark text on a light
   ground however good the dark surface looks.
   ============================================================ */
.decode-shell {
  position: relative; overflow: hidden;
  max-width: 860px; margin: 0 auto;
  padding: 26px 30px 30px;
  border-radius: var(--radius);
  background: linear-gradient(158deg, #213240 0%, #3A475A 100%);
  border-top: 4px solid var(--sky);
  box-shadow: var(--shadow-3-dark);
  color: rgba(255, 255, 255, 0.9);
}
/* the seeded field, masked away from the lower left so the type at the
   bottom of the tile is never read through texture */
.decode-shell::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.13) 1.1px, transparent 1.2px),
    radial-gradient(rgba(255, 255, 255, 0.07) 1.1px, transparent 1.2px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  -webkit-mask-image: radial-gradient(ellipse 130% 110% at 90% 0%, #000 15%, transparent 82%);
          mask-image: radial-gradient(ellipse 130% 110% at 90% 0%, #000 15%, transparent 82%);
}
/* one slow pass of light, the same wave the Decode card and the Try It
   button use, at a third of the speed: this one is on screen for a
   whole conversation rather than for as long as a card is scrolled
   past, and anything quicker would be a distraction to type over */
.decode-shell::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(100deg,
    transparent 38%,
    rgba(110, 198, 227, 0.16) 50%,
    rgba(255, 255, 255, 0.10) 57%,
    transparent 70%);
  transform: translateX(-100%);
  animation: db-wave 11s ease-in-out infinite;
}
.decode-shell > * { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
  .decode-shell::after { animation: none; }
}
.decode-shell > .label { color: var(--sky); }
/* direct children only: Your Decoded Map arrives inside a light
   bubble and carries notes and labels of its own */
.decode-shell > .note { color: rgba(255, 255, 255, 0.6); }
.decode-shell > .note strong { color: rgba(255, 255, 255, 0.9); }
.decode-shell > .note a { color: #fff; }

/* the mark in the corner, the Guide's signature on its own surface */
.decode-shell .ds-mark {
  position: absolute; right: 22px; bottom: 18px; z-index: 0;
  width: 74px; height: auto; opacity: 0.10; pointer-events: none;
}
@media (max-width: 620px) { .decode-shell .ds-mark { display: none; } }

.decode-status {
  display: flex; justify-content: space-between; align-items: center; gap: 14px;
  font-family: var(--mont); font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  padding: 12px 0 14px; margin-bottom: 4px; flex-wrap: wrap;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.decode-status .textlink { color: var(--sky); }

/* The log is the tile's own scroll area rather than the page's, so the
   input row stays put while the conversation grows above it. min-height
   keeps the tile from starting as a sliver on the first question. */
.decode-log {
  display: flex; flex-direction: column; gap: 16px;
  margin: 16px 0 20px;
  min-height: 240px; max-height: min(60vh, 620px);
  overflow-y: auto;
  padding-right: 6px;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.28) transparent;
}
.decode-log::-webkit-scrollbar { width: 8px; }
.decode-log::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.22); border-radius: 999px;
}

.decode-msg {
  max-width: 85%; padding: 16px 22px; border-radius: var(--radius);
  font-size: 1rem; line-height: 1.55;
}
.decode-msg--guide {
  align-self: flex-start;
  background: var(--paper); border: 1px solid rgba(255, 255, 255, 0.18);
  color: var(--ink); border-bottom-left-radius: 6px;
  box-shadow: var(--shadow-1-dark);
}
/* Sky rather than ocean: ocean is a near neighbour of the tile itself,
   so the visitor's own words would have sunk into the background. */
.decode-msg--me {
  align-self: flex-end;
  background: linear-gradient(158deg, #6EC6E3 0%, #4FA9CD 100%);
  color: #12242E; border-bottom-right-radius: 6px;
  box-shadow: var(--shadow-1-dark);
}

.decode-input-row {
  display: flex; gap: 10px; align-items: flex-end;
  padding-top: 18px; border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.decode-input-row textarea {
  flex: 1; min-height: 88px;
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.22);
  color: #fff;
}
.decode-input-row textarea::placeholder { color: rgba(255, 255, 255, 0.45); }
.decode-input-row textarea:focus {
  border-color: var(--sky);
  background: rgba(255, 255, 255, 0.11);
}
@media (max-width: 620px) {
  .decode-shell { padding: 22px 18px 24px; border-radius: var(--radius); }
  .decode-msg { max-width: 93%; padding: 14px 17px; }
  .decode-input-row { flex-direction: column; align-items: stretch; }
}
/* ============================================================
   YOUR DECODED MAP, the report

   .decoded-map is the LIVE report a buyer receives; .decode-report is
   the sample on the three sample pages. They are the same document and
   they share every rule here, because the sample is what sells the
   thing and the map is what arrives, and a gap between the two is a
   promise broken at exactly the wrong moment.

   It is laid out as a document rather than as a run of web sections:
   a masthead with the wordmark, a ruled-off title block, numbered
   sections with a heading that can actually be found while scanning,
   the recommendations as a list of real rows instead of bullets, and
   a signed-off footer. It is worth $15 and it should look it, on
   screen and on paper.
   ============================================================ */
.decode-report,
.decoded-map {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 46px 48px 40px;
  margin-top: 10px;
  counter-reset: dr;
}
/* The live map arrives inside a guide bubble. The bubble is the wrong
   container for a document, so it steps out of the way and lets the
   sheet be the sheet. */
.decode-msg--guide:has(.decoded-map) {
  max-width: 100%;
  padding: 0; background: none; border: none; box-shadow: none;
}
.decode-msg--guide:has(.decoded-map) .decoded-map { margin-top: 0; }

/* ---- masthead ----
   No wrapper element: the live map emits label, h2 and note as three
   siblings and the samples do the same, so the rule under the title
   is drawn by the note rather than by a div that would have to be
   added in four places. */
.decode-report > .label,
.decoded-map > .label {
  display: block;
  color: var(--ocean);
  font-size: 0.72rem; letter-spacing: 0.3em;
}
.decode-report > h2,
.decoded-map > h2 {
  font-family: var(--serif); font-weight: 300;
  font-size: 1.85rem; line-height: 1.2; color: var(--deep);
  letter-spacing: -0.005em;
  margin: 12px 0 6px;
  /* clear of the wordmark, whatever the visitor called themselves */
  max-width: calc(100% - 128px);
}
.decode-report > .label,
.decoded-map > .label { max-width: calc(100% - 128px); }
.decode-report > .note,
.decoded-map > .note {
  margin: 0; padding-bottom: 24px;
  border-bottom: 2px solid var(--deep);
  font-family: var(--mont); font-size: 0.64rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: #7C888E;
  max-width: none;
}
/* the wordmark, top right, the way a letterhead carries it */
.decode-report::before,
.decoded-map::before {
  content: "";
  position: absolute; top: 46px; right: 48px;
  width: 104px; height: 30px;
  background: url("jr-logo-color.png") right top / contain no-repeat;
  opacity: 0.85; pointer-events: none;
}

/* ---- the encouragement, still the warmest block, now the report's
        opening rather than a section like the others ---- */
.decode-report .dr-encourage,
.decoded-map .dr-encourage { margin: 30px 0 4px; }

/* ---- numbered sections ----
   The number is what turns a stack of paragraphs into a document you
   can refer back to: "the bit in section four". .dr-encourage is
   deliberately outside the count, being the preamble. */
.decode-report .dr-sect,
.decoded-map .dr-sect {
  margin-top: 34px; padding-top: 28px;
  border-top: 1px solid var(--line);
}
.decode-report .dr-sect h3,
.decoded-map .dr-sect h3 {
  counter-increment: dr;
  display: flex; align-items: baseline; gap: 12px;
  font-family: var(--mont); font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--deep);
  margin-bottom: 14px;
}
.decode-report .dr-sect h3::before,
.decoded-map .dr-sect h3::before {
  content: counter(dr, decimal-leading-zero);
  flex: none;
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.1em;
  color: var(--sky);
}
.decode-report .dr-sect p,
.decode-report .dr-sect li,
.decoded-map .dr-sect p,
.decoded-map .dr-sect li {
  color: #46555E; font-size: 1.02rem; line-height: 1.72;
}
.decode-report .dr-sect p,
.decoded-map .dr-sect p { margin: 0; max-width: 68ch; }
.decode-report .dr-sect strong,
.decoded-map .dr-sect strong { color: var(--deep); font-weight: 600; }

/* ---- scripture ----
   One or two passages, never more. Set in the serif so they read as
   quoted rather than written, and the translation is named under every
   one of them: the World English Bible is public domain, which is the
   reason a map can be printed and handed to someone else, and saying
   so is the honest half of that.

   The selectors carry the .dr-sect in them on purpose, so they outrank
   the section's own p rule without reaching for !important. */
.decode-report .dr-sect .dr-verse,
.decoded-map .dr-sect .dr-verse {
  margin: 0;
  padding: 2px 0 2px 22px;
  border-left: 2px solid var(--sage);
}
.decode-report .dr-sect .dr-verse p,
.decoded-map .dr-sect .dr-verse p {
  font-family: var(--serif); font-size: 1.16rem; font-style: italic;
  font-weight: 300; line-height: 1.62; color: var(--deep);
  margin: 0; max-width: 62ch;
}
.decode-report .dr-sect .dr-verse cite,
.decoded-map .dr-sect .dr-verse cite {
  display: block; margin-top: 9px;
  font-family: var(--mont); font-style: normal;
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--ocean);
}
.decode-report .dr-sect .dr-verse cite span,
.decoded-map .dr-sect .dr-verse cite span {
  color: #7C888E; font-weight: 500; letter-spacing: 0.12em;
}
.decode-report .dr-sect p.dr-verse-why,
.decoded-map .dr-sect p.dr-verse-why {
  margin: 12px 0 26px; font-size: 0.95rem; color: #5B6A73;
}
.decode-report .dr-sect p.dr-verse-why:last-child,
.decoded-map .dr-sect p.dr-verse-why:last-child { margin-bottom: 0; }

/* ---- the recommendations ----
   Three things Chariti made, chosen for this person. As bullets they
   read as an afterthought at the bottom of a paragraph; as ruled rows
   they read as the shortlist they are. */
.decode-report .dr-sect ul,
.decoded-map .dr-sect ul { list-style: none; margin: 4px 0 0; padding: 0; }
.decode-report .dr-sect li,
.decoded-map .dr-sect li {
  padding: 16px 0 16px 20px;
  border-top: 1px solid var(--line);
  border-left: 2px solid var(--sage);
  margin: 0;
}
.decode-report .dr-sect li:first-child,
.decoded-map .dr-sect li:first-child { border-top: none; }
.decode-report .dr-sect li a,
.decoded-map .dr-sect li a {
  font-weight: 600; color: var(--ocean); text-decoration: none;
  border-bottom: 1.5px solid var(--sage); padding-bottom: 1px;
}
.decode-report .dr-sect li em,
.decoded-map .dr-sect li em {
  font-style: normal; font-family: var(--mont);
  font-size: 0.6rem; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--sage);
}

/* The closing call to action is a button in a paragraph; give it air. */
.decode-report .dr-sect .btn,
.decoded-map .dr-sect .btn { margin-top: 6px; }

@media (max-width: 640px) {
  .decode-report,
  .decoded-map { padding: 34px 24px 30px; border-radius: var(--radius); }
  .decode-report::before,
  .decoded-map::before { top: 34px; right: 24px; width: 82px; height: 24px; }
  .decode-report > h2,
  .decoded-map > h2 { font-size: 1.5rem; margin-top: 14px; }
}
.decoded-map .dr-sect .btn { margin-top: 6px; }
.dr-actions { margin-top: 26px; }

/* item 16: the map takes a while. Say so, rather than going silent.
   The waiting mark is the jR monogram turning slowly about its
   vertical axis, like a coin standing on edge. Horizontal, not a flat
   spin: a flat spin is a loading spinner and reads as machinery, while
   the turn reads as something being considered. Six seconds a
   revolution is deliberately slower than any spinner would be. */
.decode-wait { display: flex; align-items: center; gap: 12px; }
.decode-wait-mark {
  display: inline-flex; flex: none;
  width: 30px; height: 30px;
}
.decode-wait-mark .jr-globe { width: 100%; height: 100%; display: block; }

/* The turn. Each meridian's horizontal radius runs full width to
   nothing and back, which is what a great circle actually does when
   the sphere it is drawn on turns: R times the cosine of its angle.
   Half a turn is one cycle, because an ellipse is symmetric about the
   axis, so three meridians a third of a cycle apart read as one globe
   going round rather than three lines pulsing.

   rx as a CSS property, not an SMIL animate element: SMIL is
   deprecated in more than one engine and this is on a page someone is
   waiting in front of. */
.decode-wait-mark .jrg-mer {
  animation: jrg-turn 3.2s linear infinite;
}
.decode-wait-mark .jrg-mer--b { animation-delay: -1.067s; }
.decode-wait-mark .jrg-mer--c { animation-delay: -2.133s; }
@keyframes jrg-turn {
  0%   { rx: 31px; }
  50%  { rx: 0px; }
  100% { rx: 31px; }
}
@media (prefers-reduced-motion: reduce) {
  /* Still a globe, just not turning: the three meridians are left
     spread across the face rather than stacked on the pole line. */
  .decode-wait-mark .jrg-mer { animation: none; }
  .decode-wait-mark .jrg-mer--b { rx: 21px; }
  .decode-wait-mark .jrg-mer--c { rx: 10.5px; }
}
/* ---- the sign-off ----
   Two rules rather than one, the way the bottom of a printed document
   is closed off, and the mark repeated small so a page that has been
   printed and put in a drawer still says who wrote it. */
.decode-report .dr-foot,
.decoded-map .dr-foot {
  margin-top: 38px; padding-top: 20px;
  border-top: 2px solid var(--deep);
  font-size: 0.8rem; line-height: 1.6; color: #7C888E;
  max-width: 74ch;
}

@media print {
  .site-header, .site-footer, .decode-input-row, .decode-status,
  .decode-shell > .label, .decode-shell > .note, .btn { display: none !important; }
  /* the tile is a screen surface; on paper the map is the whole page */
  .decode-shell {
    background: none; box-shadow: none; border: none;
    padding: 0; max-width: none; color: var(--ink);
  }
  .decode-shell::before, .decode-shell::after, .decode-shell .ds-mark { display: none !important; }
  .decode-log { max-height: none; overflow: visible; min-height: 0; }
  .decode-msg--me, .decode-msg--guide:not(:has(.decoded-map)) { display: none !important; }
  .decode-report, .decoded-map {
    box-shadow: none; border: none; border-radius: 0;
    padding: 0; max-width: none;
  }
  .decode-report .dr-sect, .decoded-map .dr-sect { break-inside: avoid; }
}

/* ============================================================
   DOOR ICONS + WORKSHOP CALENDAR  (directive v3, sections 3 & 8)
   Icon artwork lives in door-icons.js, drawn once and reused.
   Door accents are named here so a door's icon and its colour
   always travel together, per directive section 3.
   ============================================================ */

/* Accents taken from the homepage hero door buttons, so a door's
   icon and its colour are the same everywhere (directive §3).
   --door-*-ink is the darkened version for text and thin strokes,
   because sage and sky are too light to read on paper. */
:root {
  --door-formation: #86ADA0;  --door-formation-ink: #4F8A78;
  --door-marriage:  #6EC6E3;  --door-marriage-ink:  #2E93BB;
  --door-healing:   #1B568D;  --door-healing-ink:   #1B568D;
  --door-cross:     #365B6D;  --door-cross-ink:     #365B6D;
}

.door-icon { width: 1.25em; height: 1.25em; flex: none; }

[data-door-icon] { display: inline-flex; align-items: center; }

.door-tag {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mont); font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  padding: 6px 13px 6px 10px; border-radius: 999px;
  border: 1px solid currentColor; white-space: nowrap;
}
.door--formation { color: var(--door-formation-ink); }
.door--marriage  { color: var(--door-marriage-ink); }
.door--healing   { color: var(--door-healing-ink); }
.door--cross     { color: var(--door-cross-ink); }

/* ---- filter bar ---- */
.cal-filters { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 34px; }
.cal-filter {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-family: var(--mont); font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  padding: 9px 16px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--paper); color: var(--slate);
}
.cal-filter[aria-pressed="true"] { border-color: currentColor; background: var(--white); }
.cal-filter[aria-pressed="false"] { opacity: 0.5; }

/* ---- view toggle ---- */
.cal-viewswitch { display: flex; gap: 4px; margin-left: auto; }
.cal-viewswitch button {
  font-family: var(--mont); font-size: 0.6rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; cursor: pointer;
  padding: 9px 15px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--paper); color: var(--slate);
}
.cal-viewswitch button[aria-pressed="true"] { background: var(--ocean); border-color: var(--ocean); color: var(--white); }

/* ---- month grid ---- */
.cal-monthbar { display: flex; align-items: center; gap: 18px; margin-bottom: 22px; }
.cal-monthbar h2 { font-size: 1.6rem; margin: 0; }
.cal-nav {
  width: 40px; height: 40px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--line); background: var(--paper); color: var(--slate);
  font-size: 1.1rem; line-height: 1; display: grid; place-items: center;
}
.cal-nav:hover:not(:disabled) { background: var(--white); }
.cal-nav:disabled { opacity: 0.3; cursor: default; }

.cal-grid {
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
}
.cal-dow {
  background: var(--ivory); padding: 12px 6px; text-align: center;
  font-family: var(--mont); font-size: 0.58rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: #7C888E;
}
.cal-cell { background: var(--paper); min-height: 116px; padding: 8px; }
.cal-cell--muted { background: #F7F5EF; }
.cal-cell--today .cal-daynum {
  background: var(--ocean); color: var(--white);
  border-radius: 50%; width: 26px; height: 26px;
  display: grid; place-items: center;
}
.cal-daynum { font-family: var(--mont); font-size: 0.74rem; font-weight: 600; color: #7C888E; margin-bottom: 6px; }

/* The chip is the colour, filled, with white on it.

   It used to be a white chip with a 3px coloured edge, which meant the
   colour, the one thing carrying which door or which programme an
   entry belongs to, was three pixels wide on a cell an inch across.
   Filled, a month reads at a glance.

   `color` is still the door or programme colour, set inline by
   calendar-core.js, because the fill takes it from currentColor. That
   is why the white is put on the children rather than on the chip: the
   chip has to keep its own colour to paint itself with. The icon is
   stroke="currentColor", so white reaches it the same way. */
.cal-event {
  display: flex; align-items: flex-start; gap: 6px;
  font-size: 0.78rem; line-height: 1.3; text-decoration: none;
  padding: 6px 8px; border-radius: var(--radius); margin-bottom: 5px;
  background: currentColor;
  box-shadow: var(--shadow-0);
}
.cal-event:hover { box-shadow: var(--shadow); }
.cal-event .door-icon { width: 14px; height: 14px; margin-top: 1px; color: #fff; }
.cal-event span { color: #fff; font-weight: 500; }
.cal-event .cal-event-time { color: rgba(255, 255, 255, 0.82); }
/* A later session of a run someone has already seen the start of. */
.cal-event--cont { opacity: 0.72; }

/* ---- list view ---- */
.cal-list { display: flex; flex-direction: column; gap: 16px; }
.cal-row {
  display: grid; grid-template-columns: 108px 1fr auto; gap: 26px; align-items: center;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 22px 26px; text-decoration: none;
  border-left: 4px solid currentColor;
}
.cal-row:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.cal-date { text-align: center; }
.cal-date .cal-mon {
  font-family: var(--mont); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
}
.cal-date .cal-day { font-family: var(--serif); font-size: 2.2rem; line-height: 1.1; color: var(--ink); }
.cal-row h3 { font-size: 1.3rem; margin: 0 0 6px; color: var(--ink); }
.cal-meta { font-size: 0.92rem; color: #7C888E; }
.cal-price { font-family: var(--serif); font-size: 1.5rem; color: var(--ink); white-space: nowrap; }

/* ---- empty state ---- */
.cal-empty {
  background: var(--paper); border: 1px dashed var(--line);
  border-radius: var(--radius); padding: 56px 40px; text-align: center;
}
.cal-empty h3 { margin-bottom: 12px; }
.cal-empty p { color: #46555E; max-width: 52ch; margin: 0 auto; }

@media (max-width: 860px) {
  /* The month grid is unreadable on a phone, so the list becomes
     the view, not a fallback (directive section 8). */
  .cal-viewswitch { display: none; }
  #cal-month { display: none !important; }
  .cal-row { grid-template-columns: 74px 1fr; gap: 18px; padding: 18px; }
  .cal-price { grid-column: 2; justify-self: start; font-size: 1.25rem; }
  .cal-date .cal-day { font-size: 1.8rem; }
}

/* ============================================================
   HOMEPAGE REFINEMENTS (2026-07-31)
   ============================================================ */

/* ---- Joy Restored wordmark in the hero ---- */
.hero-wordmark {
  width: clamp(190px, 20vw, 262px);
  height: auto;
  margin-bottom: 26px;
  filter: drop-shadow(0 6px 18px rgba(12, 32, 44, 0.32));
}
@media (max-width: 900px) { .hero-wordmark { margin-bottom: 20px; } }

/* ---- Door cards in section two now carry the door's own icon
        and accent, matching the hero buttons (directive §3) ---- */
.door-card .dc-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  margin-bottom: 22px;
  background: color-mix(in srgb, currentColor 14%, transparent);
  color: inherit;
}
.door-card .dc-ico .door-icon { width: 25px; height: 25px; }

/* The accent travels with the icon: name, underline and hover
   border all take the door's colour instead of the generic sage. */
.door-card.door--formation, .door-card.door--marriage, .door-card.door--healing { color: var(--door-formation-ink); }
.door-card.door--marriage { color: var(--door-marriage-ink); }
.door-card.door--healing  { color: var(--door-healing-ink); }
.door-card .dc-name { color: currentColor; }
.door-card p, .door-card .dc-feel { color: #46555E; }
.door-card .dc-feel { color: var(--deep); }
.door-card::after { background: currentColor; }
.door-card:hover { border-color: currentColor; }

/* ---- Admin link in the footer base ---- */
.footer-admin a {
  font-family: var(--mont);
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.38);
  text-decoration: none;
}
.footer-admin a:hover { color: rgba(255, 255, 255, 0.8); }

/* ============================================================
   THE RESTORATION JOURNEY, five domains x four movements
   Domain order is fixed by directive v3 §4:
   Spirit · Soul · Body · Relationships · Purpose.
   The four movements repeat inside every domain, which is the
   whole point of the section, so they are colour-coded once in
   the key and then read down each tile.
   ============================================================ */

:root {
  --mv-truth:    #1B568D;
  --mv-lament:   #365B6D;
  --mv-forgive:  #4F8A78;
  --mv-remember: #2E93BB;
}

.rj-head { max-width: 74ch; margin-left: auto; margin-right: auto; text-align: center; }
.rj-head .lede { margin-left: auto; margin-right: auto; }

.rj-key { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 22px; margin: 0 0 40px; }
.rj-key-item {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mont); font-size: 0.6rem; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--slate);
}
.rj-key-item i { width: 10px; height: 10px; border-radius: 50%; background: currentColor; flex: none; }
.rj-truth    { color: var(--mv-truth); }
.rj-lament   { color: var(--mv-lament); }
.rj-forgive  { color: var(--mv-forgive); }
.rj-remember { color: var(--mv-remember); }

.rj-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 18px; align-items: stretch; }

.rj-domain {
  display: flex; flex-direction: column; text-align: left;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 28px 22px 24px;
}
.rj-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--sage-tint); color: var(--deep); margin-bottom: 16px;
}
.rj-ico svg { width: 24px; height: 24px; }
.rj-domain h3 { font-size: 1.32rem; margin: 0 0 8px; }
/* Equal-height descriptions so all five movement lists start on the
   same line. Bottom-aligning them instead left the tops ragged,
   which read as a mistake rather than a choice. */
.rj-def { font-size: 0.94rem; color: #46555E; margin: 0 0 18px; min-height: 4.5em; }

.rj-moves {
  list-style: none; margin: 0; padding: 18px 0 0; border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 12px;
}
.rj-moves li {
  position: relative; padding-left: 15px;
  font-size: 0.88rem; line-height: 1.5; color: #46555E;
}
.rj-moves li::before {
  content: ""; position: absolute; left: 0; top: 6px;
  width: 6px; height: 6px; border-radius: 50%; background: currentColor;
}
.rj-moves b {
  display: block;
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  margin-bottom: 3px;
}
/* The dot and the label take the movement colour; the sentence
   stays neutral so five tiles of this don't turn into confetti. */
.rj-moves li > b { color: currentColor; }
.rj-moves li { color: inherit; }
.rj-moves li.rj-truth,
.rj-moves li.rj-lament,
.rj-moves li.rj-forgive,
.rj-moves li.rj-remember { color: inherit; }
.rj-moves li.rj-truth::before    { background: var(--mv-truth); }
.rj-moves li.rj-lament::before   { background: var(--mv-lament); }
.rj-moves li.rj-forgive::before  { background: var(--mv-forgive); }
.rj-moves li.rj-remember::before { background: var(--mv-remember); }
.rj-moves li.rj-truth > b    { color: var(--mv-truth); }
.rj-moves li.rj-lament > b   { color: var(--mv-lament); }
.rj-moves li.rj-forgive > b  { color: var(--mv-forgive); }
.rj-moves li.rj-remember > b { color: var(--mv-remember); }

.rj-foot { text-align: center; max-width: 70ch; margin-left: auto; margin-right: auto; }
.rj-foot .textlink { white-space: nowrap; }

@media (max-width: 1100px) { .rj-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 760px)  { .rj-grid { grid-template-columns: repeat(2, 1fr); gap: 14px; } }
@media (max-width: 520px)  { .rj-grid { grid-template-columns: 1fr; } }

/* ============================================================
   PRODUCT PATH, the ladder behind each door drawn as a journey
   Free and paid get distinct treatments so the price is legible
   before you read a word, and neither is plain white.
   ============================================================ */

.path { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 22px; }

.path-step {
  position: relative; display: flex; flex-direction: column;
  text-decoration: none; padding-top: 34px;
}
/* The connector: two half-width rules per step, meeting under the
   dot, so the line is continuous but never overshoots the ends. */
.path-step::before, .path-step::after {
  content: ""; position: absolute; top: 7px; height: 2px;
  background: var(--line); z-index: 1;
}
.path-step::before { left: 0; right: 50%; }
.path-step::after  { left: 50%; right: 0; }
.path-step:first-child::before, .path-step:last-child::after { display: none; }

.ps-dot {
  position: absolute; top: 0; left: 50%; margin-left: -8px;
  width: 16px; height: 16px; border-radius: 50%; z-index: 2;
  background: var(--paper); border: 2px solid var(--sage);
}
.path-step.is-paid .ps-dot { border-color: var(--ocean); }
.path-step.is-apply .ps-dot { border-color: var(--deep); background: var(--deep); }

.ps-card {
  flex: 1; display: flex; flex-direction: column;
  border-radius: var(--radius); padding: 24px 22px 22px;
  border: 1px solid transparent;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.path-step:hover .ps-card { transform: translateY(-4px); box-shadow: var(--shadow); }

/* Free: sage tint. Paid: cool blue tint. Application: deep, inverted. */
.path-step.is-free  .ps-card { background: var(--sage-tint); border-color: #CFDFD8; }
.path-step.is-paid  .ps-card { background: #E8EFF5; border-color: #CBDCE9; }
.path-step.is-apply .ps-card { background: var(--grad); border-color: transparent; }
.path-step.is-apply .ps-card h3,
.path-step.is-apply .ps-card p { color: var(--white); }
.path-step.is-apply .ps-card p { color: rgba(255, 255, 255, 0.86); }

.ps-chip {
  align-self: flex-start;
  justify-self: start;          /* grid rows below: keep the pill its own width */
  font-family: var(--mont); font-size: 0.58rem; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  padding: 5px 11px; border-radius: 999px; margin-bottom: 13px;
}
.path-step.is-free  .ps-chip { background: #4F8A78; color: #fff; }
.path-step.is-paid  .ps-chip { background: var(--ocean); color: #fff; }
.path-step.is-apply .ps-chip { background: rgba(255, 255, 255, 0.2); color: #fff; }

.ps-card h3 { font-size: 1.14rem; margin: 0 0 8px; color: var(--ink); }
.ps-card p { font-size: 0.92rem; color: #46555E; margin: 0; flex-grow: 1; }
.ps-go {
  margin-top: 16px;
  font-family: var(--mont); font-size: 0.58rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--ocean);
}
.path-step.is-free .ps-go { color: #3d6b5c; }
.path-step.is-apply .ps-go { color: #fff; }

/* ---- A ladder is one set of rows, not five separate stacks ----

   A rung is chip, title, meta, body, link. Not every rung has a meta
   line, and a title runs to one line or two depending on the product,
   so laid out independently each card started its body copy at its
   own height: five cards side by side with five different first lines
   of text, and the meta lines, where they existed at all, floating at
   five different heights. It read as five cards that happened to be
   next to each other rather than one row.

   Subgrid gives the whole ladder one set of tracks and every card
   hangs its slots on them, so the chips sit on one line, the titles
   on one line, the meta on one, the body on one and the links on one,
   whatever any single card happens to contain. The slots are assigned
   explicitly rather than auto-placed, because auto-placement is what
   put the body copy in the meta row on the cards with no meta.

   The body row takes the slack, so the links stay on the floor.

   Only while the rungs are actually side by side. Stacked on a phone
   there is no row to align to, and reserving an empty meta slot on
   every card would be dead space for nothing. */
@supports (grid-template-rows: subgrid) {
  /* Which slot each thing sits in. A grid-row on a flex item is
     ignored, so these are inert until a card below becomes a grid,
     and they can be stated once for both breakpoints. */
  .ps-card > .ps-chip { grid-row: 1; }
  .ps-card > h3       { grid-row: 2; }
  .ps-card > .ps-meta { grid-row: 3; }
  .ps-card > p        { grid-row: 4; }
  .ps-card > .ps-go   { grid-row: 5; }

  /* Shared rows only while the rungs really are a row. The six-rung
     ladders stack at 1080px and the shorter ones at 900px, which is
     why this is stated twice rather than once at the lower of the
     two: a stacked ladder given a row's tracks would hand the first
     card all the leftover height and leave the rest short. */
  @media (min-width: 901px) {
    .path:not(.path--six) { grid-template-rows: auto auto auto 1fr auto; }
    .path:not(.path--six) > .path-step {
      grid-row: span 5; display: grid; grid-template-rows: subgrid;
    }
    .path:not(.path--six) > .path-step > .ps-card {
      grid-row: 1 / -1; display: grid; grid-template-rows: subgrid;
    }
  }
  @media (min-width: 1080px) {
    .path--six { grid-template-rows: auto auto auto 1fr auto; }
    .path--six > .path-step {
      grid-row: span 5; display: grid; grid-template-rows: subgrid;
    }
    .path--six > .path-step > .ps-card {
      grid-row: 1 / -1; display: grid; grid-template-rows: subgrid;
    }
  }
}

@media (max-width: 900px) {
  /* Vertical on small screens: the connector moves to the left rail. */
  .path { grid-auto-flow: row; grid-auto-columns: auto; gap: 16px; }
  .path-step { padding-top: 0; padding-left: 34px; }
  .path-step::before { left: 7px; right: auto; top: 0; bottom: 50%; width: 2px; height: auto; }
  .path-step::after  { left: 7px; right: auto; top: 50%; bottom: 0; width: 2px; height: auto; }
  .ps-dot { top: 50%; left: 0; margin-left: 0; margin-top: -8px; }
}

/* ---- Calendar: three months at a time, several events per day ---- */
.cal-month-block + .cal-month-block { margin-top: 34px; }
.cal-month-name {
  font-family: var(--mont); font-size: 0.64rem; font-weight: 600;
  letter-spacing: 0.2em; text-transform: uppercase; color: #7C888E;
  margin: 0 0 12px;
}
.cal-event-time {
  display: block; font-style: normal; font-size: 0.7rem;
  color: #7C888E; margin-top: 1px;
}
/* A day with more than one slot gets a little more room rather than
   squeezing both entries into a single-event cell. */
.cal-cell--multi { min-height: 150px; }

/* ============================================================
   HERO TEXTURE OPTIONS  (preview at /hero-textures.html)
   Three, each built from a texture the Brand Book already names,
   so whichever is chosen is on-brand rather than merely pretty:
   The Dawn (rising rings) · The Seed (dot field) · The Horizon.
   All three sit UNDER the existing ring artwork and above the
   gradient, at low opacity, and none of them touch legibility.
   ============================================================ */

.hero--tex { position: relative; }
.hero--tex > .hero-inner { position: relative; z-index: 2; }
.hero--tex::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
}

/* 1 · THE DAWN, wide rings rising from below the fold. Quietest
      of the three; reads as light rather than pattern. */
.hero--tex-dawn::before {
  background:
    repeating-radial-gradient(circle at 50% 128%,
      rgba(255, 255, 255, 0.075) 0 1.7px,
      transparent 1.7px 74px);
  -webkit-mask-image: linear-gradient(to top, #000 8%, transparent 92%);
          mask-image: linear-gradient(to top, #000 8%, transparent 92%);
}

/* 2 · THE SEED, a fine dot field on the diagonal. The most
      "textile" of the three, closest to letterpress paper. */
.hero--tex-seed::before {
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.16) 1.1px, transparent 1.2px),
    radial-gradient(rgba(255, 255, 255, 0.10) 1.1px, transparent 1.2px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  -webkit-mask-image: radial-gradient(ellipse 120% 90% at 30% 20%, #000 20%, transparent 78%);
          mask-image: radial-gradient(ellipse 120% 90% at 30% 20%, #000 20%, transparent 78%);
}

/* 3 · THE HORIZON, soft strata, like light through water.
      The most architectural, and the one that most changes the
      feel of the panel. */
.hero--tex-horizon::before {
  background:
    repeating-linear-gradient(174deg,
      rgba(255, 255, 255, 0.055) 0 1.5px,
      transparent 1.5px 26px),
    repeating-linear-gradient(174deg,
      rgba(10, 38, 52, 0.10) 0 1px,
      transparent 1px 78px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 4%, #000 46%, transparent 98%);
          mask-image: linear-gradient(to bottom, transparent 4%, #000 46%, transparent 98%);
}

/* ============================================================
   THE LIBRARY, everything behind an access code
   Reading-first layout: narrow measure, generous leading, and
   printable, because people work through these with a pen.
   ============================================================ */

.lib-top {
  background: var(--deep); color: #fff; padding: 14px 0;
  font-family: var(--mont); font-size: 0.6rem; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
}
.lib-top .wrap { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.lib-top a { color: rgba(255,255,255,0.82); text-decoration: none; }
.lib-top a:hover { color: #fff; }
.lib-top .lib-sep { color: rgba(255,255,255,0.35); }

.lib-wrap { max-width: 780px; margin: 0 auto; padding: 56px 28px 90px; }
.lib-wrap h1 { font-size: clamp(2rem, 4vw, 2.9rem); line-height: 1.12; margin-bottom: 10px; }
.lib-kicker {
  font-family: var(--mont); font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--sage);
  display: block; margin-bottom: 14px;
}
.lib-sub { font-size: 1.12rem; color: #46555E; margin-bottom: 8px; }

.lib-step {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 30px 32px; margin-top: 26px;
}
.lib-step h2 { font-size: 1.5rem; margin: 0 0 6px; }
.lib-step h3 { font-size: 1.06rem; margin: 22px 0 8px; }
.lib-step p { font-size: 1.02rem; color: #46555E; margin-bottom: 12px; }
.lib-step p:last-child { margin-bottom: 0; }
.lib-num {
  font-family: var(--mont); font-size: 0.58rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--ocean);
  display: block; margin-bottom: 8px;
}

.lib-say {
  border-left: 3px solid var(--sage); padding: 4px 0 4px 18px;
  font-family: var(--serif); font-style: italic; font-size: 1.16rem;
  color: var(--deep); margin: 16px 0;
}
.lib-scripture { font-size: 0.92rem; color: #7C888E; font-style: normal; display: block; margin-top: 6px; }

.lib-check { list-style: none; padding: 0; margin: 14px 0; }
.lib-check li {
  position: relative; padding-left: 30px; margin-bottom: 11px;
  font-size: 1rem; color: #46555E;
}
.lib-check li::before {
  content: ""; position: absolute; left: 0; top: 3px;
  width: 17px; height: 17px; border: 1.7px solid var(--sage);
  border-radius: 4px; background: #fff;
}
.lib-fill {
  display: block; border-bottom: 1.5px dashed var(--line);
  height: 30px; margin: 8px 0 16px;
}
.lib-note {
  background: var(--sage-tint); border-radius: var(--radius);
  padding: 18px 20px; font-size: 0.96rem; color: #3d5a51; margin: 18px 0;
}
.lib-warn {
  background: #FBF1EC; border-left: 3px solid #A04326;
  border-radius: 0 var(--radius) var(--radius) 0; padding: 18px 20px;
  font-size: 0.96rem; color: #7a3a22; margin: 18px 0;
}
.lib-believers {
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  background: rgba(27,86,141,0.1); color: var(--ocean);
  padding: 4px 10px; border-radius: 999px; display: inline-block; margin-bottom: 10px;
}
.lib-cols { columns: 2; column-gap: 34px; }
.lib-cols li { break-inside: avoid; }
@media (max-width: 620px) { .lib-cols { columns: 1; } }

/* Library index + Becoming portal module list */
.lib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 18px; margin-top: 30px; }
.lib-card {
  display: block; background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 24px 24px 22px; text-decoration: none;
  transition: transform .3s ease, box-shadow .3s ease;
}
.lib-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.lib-card h3 { font-size: 1.16rem; margin: 8px 0 6px; color: var(--ink); }
.lib-card p { font-size: 0.92rem; color: #46555E; margin: 0; }
.lib-card .lib-mnum {
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--sage);
}
.lib-card.is-locked { opacity: 0.5; }
.lib-card.is-locked:hover { transform: none; box-shadow: none; opacity: 0.68; }
/* The release date on a month of Becoming that has not arrived. Same
   voice as .lib-mnum above it, sitting at the foot of the card so it
   reads as the card's status rather than its title. */
.lib-lock {
  display: block; margin-top: 10px;
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; color: #7C888E;
}
.lib-phase {
  font-family: var(--mont); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; color: #7C888E;
  margin: 38px 0 4px; display: block;
}
.lib-pillar {
  display: inline-block; font-family: var(--mont); font-size: 0.52rem;
  font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase;
  background: var(--ocean); color: #fff; padding: 3px 9px;
  border-radius: 999px; margin-left: 6px;
}
.lib-toc { list-style: none; padding: 0; margin: 26px 0 0; }
.lib-toc li { border-top: 1px solid var(--line); }
.lib-toc a { display: block; padding: 13px 0; text-decoration: none; color: var(--ink); font-size: 1.02rem; }
.lib-toc a:hover { color: var(--ocean); }

@media print {
  .lib-top, .site-footer, .lib-noprint { display: none !important; }
  .lib-step { border: none; padding: 0; margin-top: 24px; break-inside: avoid; }
  .lib-wrap { padding: 0; max-width: none; }
}

.buy-error { color: #A04326; font-size: 0.94rem; margin-top: 12px; }
.hero .buy-error, .cta-band .buy-error { color: #FFD9CC; }

/* ---- Givebutter giving window (donate page) ---- */
.gb-card {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 30px 28px 24px;
}
.gb-frame {
  border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); background: #fff;
}
.gb-frame iframe {
  display: block; width: 100%; height: 720px; border: 0;
}
@media (max-width: 900px) { .gb-frame iframe { height: 660px; } }

/* ============================================================
   HERO v2 — shorter, doors louder, portrait top-aligned,
   small-group ticker along the bottom.
   ============================================================ */

/* Shorter: the hero's job is to get someone through a door, not
   to be a poster. Tighter padding, tighter copy, bigger doors. */
.hero > .hero-inner { padding: 46px 28px 40px; }
.hero .hero-wordmark { margin-bottom: 18px; }
.hero h1 { margin: 0 0 16px; font-size: clamp(2.1rem, 4.4vw, 3.3rem); max-width: 18ch; }
.hero p { font-size: 1.1rem; margin-bottom: 26px; max-width: 46ch; }
.hero .door-lead { margin-bottom: 12px; }

/* Portrait tops out level with "Wherever", not with the wordmark,
   so the two columns start on the same line. */
.hero-grid { align-items: start; }
.hero-portrait { margin-top: var(--hero-portrait-offset, 100px); }
@media (max-width: 940px) { .hero-portrait { margin-top: 0; } }

/* Each door carries its own free product beside it. */
.door-btns { max-width: 620px; gap: 14px; }
.door-row { display: flex; gap: 10px; align-items: stretch; }
.door-row .door-btn { flex: 1 1 auto; font-size: 1.24rem; padding: 19px 22px; }
.door-free {
  flex: 0 0 auto; display: flex; flex-direction: column; justify-content: center;
  text-decoration: none; text-align: center; white-space: nowrap;
  border-radius: var(--radius); padding: 10px 18px;
  background: rgba(255, 255, 255, 0.13);
  border: 1px solid rgba(255, 255, 255, 0.34);
  color: #fff;
  font-family: var(--mont); font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; line-height: 1.5;
  transition: background 0.25s ease, transform 0.25s ease;
}
.door-free b {
  display: block; font-size: 0.58rem; letter-spacing: 0.2em;
  color: #BFE6D6; font-weight: 700;
}
.door-free:hover { background: rgba(255, 255, 255, 0.24); transform: translateY(-2px); }
@media (max-width: 620px) {
  .door-row { flex-direction: column; gap: 6px; }
  .door-free { text-align: left; align-items: flex-start; }
}

.hero-decode { color: rgba(255,255,255,0.8); margin-top: 18px; }
.hero-decode a { color: #fff; }

/* ---- Small-group ticker along the bottom of the hero ---- */
.hero-ticker {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 20px;
  background: rgba(12, 36, 48, 0.34);
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  padding: 12px 28px;
}
.ht-label {
  flex: none;
  font-family: var(--mont); font-size: 0.58rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}
.ht-viewport { flex: 1 1 auto; overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent); mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent); }
.ht-track { display: flex; gap: 34px; width: max-content; animation: ht-scroll 42s linear infinite; }
.ht-track:hover { animation-play-state: paused; }
.ht-item {
  display: inline-flex; align-items: center; gap: 9px; white-space: nowrap;
  color: rgba(255, 255, 255, 0.92); text-decoration: none; font-size: 0.98rem;
}
.ht-item .door-icon { width: 16px; height: 16px; opacity: 0.9; }
.ht-item:hover { color: #fff; text-decoration: underline; text-underline-offset: 4px; }
.ht-item .ht-dot { width: 5px; height: 5px; border-radius: 50%; background: rgba(255,255,255,0.4); }
@keyframes ht-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .ht-track { animation: none; }
  .ht-viewport { overflow-x: auto; }
}
@media (max-width: 760px) { .ht-label { display: none; } .hero-ticker { padding: 10px 18px; } }

/* ---- Item 8: section-two icons solid and dark, like the hero ---- */
.door-card .dc-ico { background: currentColor; }
.door-card .dc-ico .door-icon { color: #fff; }

/* Hero v2 tuning: trim everything except the doors, which get louder.
   The portrait offset lines its top edge up with "Wherever", measured
   rather than guessed. */
.hero .hero-wordmark { width: clamp(150px, 15vw, 200px); margin-bottom: 14px; }
.hero h1 { font-size: clamp(1.95rem, 3.6vw, 2.8rem); margin: 0 0 14px; max-width: 20ch; }
.hero p { font-size: 1.05rem; margin-bottom: 22px; }
.hero .door-lead { font-size: 0.66rem; margin-bottom: 10px; }
.hero .hero-decode { margin-top: 14px; font-size: 0.95rem; }
.hero-portrait { width: min(100%, 360px); --hero-portrait-offset: 162px; }
.hero > .hero-inner { padding: 40px 28px 34px; }
.hero-portrait { --hero-portrait-offset: 123px; }

/* The hero inherited 96px of generic section padding top and bottom.
   .hero-inner and the ticker own their own spacing, so that padding
   was just dead teal — and it was most of why the hero felt long. */
.hero { padding-top: 0; padding-bottom: 0; }
.hero > .hero-inner { padding: 52px 28px 40px; }
.hero--sub > .hero-inner { padding: 62px 28px 66px; }

/* ---- Item 12: the Restoration Journey arc, with movement ---- */
.rj-arc { margin: 6px 0 -6px; }
.rj-arc svg { display: block; width: 100%; height: 132px; overflow: visible; }
.rj-curve {
  fill: none; stroke: rgba(54, 91, 109, 0.28);
  stroke-width: 2; stroke-linecap: round; stroke-dasharray: 5 9;
}
.rj-stops circle { fill: var(--paper); stroke: var(--deep); stroke-width: 2; }
.rj-traveller circle {
  fill: var(--deep); stroke: rgba(255, 255, 255, 0.85); stroke-width: 2.5;
}

/* The tiles light up in turn, in step with the traveller: a 20s loop
   split five ways, so the highlight lands roughly under the dot. */
.rj-domain { transition: box-shadow .6s ease, border-color .6s ease, transform .6s ease; }
.rj-grid .rj-domain { animation: rj-lift 20s linear infinite; }
.rj-grid .rj-domain:nth-child(1) { animation-delay:  0s; }
.rj-grid .rj-domain:nth-child(2) { animation-delay: -16s; }
.rj-grid .rj-domain:nth-child(3) { animation-delay: -12s; }
.rj-grid .rj-domain:nth-child(4) { animation-delay:  -8s; }
.rj-grid .rj-domain:nth-child(5) { animation-delay:  -4s; }
/* Deliberately no transform here. The tiles are inside a
   [data-reveal="stagger"] block whose entrance animates transform,
   and a keyframe animation on the same property wins over it, which
   left the tiles stranded mid-entrance. Shadow and border only. */
@keyframes rj-lift {
  0%, 14%   { box-shadow: var(--shadow-3); border-color: var(--sage); background: #fff; }
  20%, 100% { box-shadow: none; border-color: var(--line); background: var(--paper); }
}
@media (prefers-reduced-motion: reduce) {
  .rj-grid .rj-domain { animation: none; }
  .rj-traveller { display: none; }
}
@media (max-width: 1100px) { .rj-arc { display: none; } }

/* ---- Item 13: classy texture on The Better Question ---- */
.section--texture { position: relative; overflow: hidden; }
.section--texture > * { position: relative; z-index: 1; }
.section--texture::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    radial-gradient(rgba(54, 91, 109, 0.10) 1.1px, transparent 1.2px),
    radial-gradient(rgba(54, 91, 109, 0.06) 1.1px, transparent 1.2px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  -webkit-mask-image: radial-gradient(ellipse 110% 80% at 78% 30%, #000 12%, transparent 76%);
          mask-image: radial-gradient(ellipse 110% 80% at 78% 30%, #000 12%, transparent 76%);
}

/* ============================================================
   PATH v2 — items 14, 15, 16
   14: every rung now carries the depth the Formation Journey card
       had, instead of that card being the only designed one.
   15: a figure walks the rail above and lights each rung.
   16: "In a small group" is called out as the featured rung.
   ============================================================ */

/* ---- 15: the rail the figure walks ---- */
.path-walk { position: relative; height: 42px; margin: 0 0 6px; }
.pw-line {
  position: absolute; left: 0; right: 0; top: 50%;
  height: 2px; background: var(--line); border-radius: 2px;
}
.pw-figure {
  position: absolute; top: 50%; left: 0;
  width: 38px; height: 38px; margin-left: -19px;
  border-radius: 50%; display: grid; place-items: center;
  background: var(--grad); color: #fff;
  box-shadow: var(--shadow-1);
  will-change: transform;
}
.pw-figure svg { width: 20px; height: 20px; }
@media (max-width: 900px) { .path-walk { display: none; } }

/* ---- 14: all rungs get the premium treatment ---- */
.ps-card {
  position: relative; overflow: hidden;
  border-width: 1px; border-style: solid;
  box-shadow: var(--shadow-1);
}
/* A soft sheen across the top of every card, like the gradient one. */
.ps-card::after {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--grad); opacity: .55;
}
.path-step.is-free  .ps-card { background: linear-gradient(168deg, #EDF4F0 0%, #E0EBE5 100%); border-color: #CBDCD4; }
.path-step.is-paid  .ps-card { background: linear-gradient(168deg, #EDF3F9 0%, #DDE9F2 100%); border-color: #C6D9E8; }
.path-step.is-apply .ps-card { background: var(--grad); border-color: transparent; }
.path-step.is-apply .ps-card::after { background: rgba(255,255,255,.5); }

/* The lit state, driven by path-walker.js */
.path-step .ps-card { transition: transform .45s ease, box-shadow .45s ease, border-color .45s ease; }
.path-step.is-lit .ps-card {
  transform: translateY(-6px);
  box-shadow: var(--shadow-3);
  border-color: var(--sage);
}
.path-step.is-lit .ps-dot { box-shadow: 0 0 0 6px rgba(134, 173, 160, 0.28); }
.ps-dot { transition: box-shadow .45s ease; }

/* ---- 16: the small-group rung, called out ---- */
.path-step.is-featured .ps-card {
  border-color: var(--ocean);
  box-shadow: var(--shadow-2);
}
.path-step.is-featured .ps-card::after { opacity: 1; height: 5px; }
.ps-flag {
  position: absolute; top: 0; right: 0;
  background: var(--ocean); color: #fff;
  font-family: var(--mont); font-size: 0.5rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  padding: 5px 10px; border-radius: 0 0 0 var(--radius);
}
.path-step.is-featured .ps-dot { border-color: var(--ocean); background: var(--ocean); }

/* ---- Course video embeds (Becoming / Stop the Spiral portals) ---- */
.lib-video {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  margin: 4px 0 18px; border-radius: var(--radius); overflow: hidden;
  background: #10222B;
}
.lib-video iframe,
.lib-video video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* Self-hosted course video is object-fit: contain so a clip that was
   exported at another aspect ratio letterboxes inside the frame
   instead of being cropped. */
.lib-video video { object-fit: contain; background: #10222B; }
.lib-step img { max-width: 100%; height: auto; border-radius: var(--radius); }

/* ---- Self-hosted course audio (served from R2 behind /media/*) ---- */
.lib-audio { margin: 4px 0 18px; }
.lib-audio audio { width: 100%; display: block; }
.lib-audio .lib-audio-dl { margin-top: 12px; }

/* ============================================================
   DESIGN ROUND 2026-07-31 (evening) — hero + homepage refinements
   ============================================================ */

/* Item 1: the three Free buttons share one width, so the column of
   doors reads as a grid instead of a ragged edge. */
.door-row .door-free { flex: 0 0 176px; width: 176px; }

/* Item 2: door path text bolder. */
.door-row .door-btn { font-weight: 600; }
.door-row .door-btn .db-main { font-weight: 600; }

/* Item 5: an explicit "Click here" pill on each door, so nobody
   wonders whether the big rows are buttons. */
.db-open {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  background: var(--ocean); color: #fff;
  border-radius: 999px; padding: 8px 14px;
  font-family: var(--mont); font-size: 0.58rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; white-space: nowrap;
  transition: background 0.25s ease, transform 0.25s ease;
}
.db-open .db-arrow { color: #fff; font-family: var(--sans); font-size: 0.8rem; }
.door-btn:hover .db-open { background: #174a7b; transform: translateX(3px); }
.door-btn:hover .db-open .db-arrow { transform: none; color: #fff; }
@media (max-width: 480px) { .db-open { display: none; } }

/* Ticker sits between the header and the hero, and scrolls away with the
   page. Solid deep background, thin seam on top. */
.hero-ticker {
  background: var(--deep);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}

/* Item 9: Chariti's name pill sits under the photo, not on it. */
.hero-portrait .hp-tag {
  position: static;
  display: block;
  width: fit-content;
  margin: 16px auto 0;
  left: auto; bottom: auto;
}

/* Item 11: door names as pills, coloured to match their door icon. */
.door-card .dc-name {
  display: inline-block;
  align-self: flex-start;
  border-radius: 999px;
  padding: 7px 14px;
  color: #fff;
}
.door-card.door--formation .dc-name { background: var(--door-formation-ink); }
.door-card.door--marriage  .dc-name { background: var(--door-marriage-ink); }
.door-card.door--healing   .dc-name { background: var(--door-healing-ink); }

/* Item 12: the arc traveller is the JR monogram riding a white coin,
   and every stop sits on the curve (coords are in the SVG). */
.rj-traveller circle {
  fill: #fff; stroke: var(--deep); stroke-width: 1.5;
}

/* Item 12: the four movements line up row-for-row across all five
   domains. The description keeps a fixed height so every list starts
   level, then the list becomes a 4-row grid that fills the tile, so
   each movement row (and the rule above it) is the same height in
   every column. */
.rj-def { min-height: 5.1em; margin-bottom: 12px; }
.rj-moves {
  flex-grow: 1;
  display: grid;
  grid-template-rows: repeat(4, 1fr);
  gap: 0;
  padding: 0;
  border-top: none;
}
.rj-moves li {
  border-top: 1px solid var(--line);
  padding: 12px 0 10px 15px;
}
.rj-moves li::before { top: 18px; }

/* Item 13: the tagline closes the Come-as-you-are band, on two lines. */
.cta-band .cta-tagline {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: 1.5rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.92);
  margin: 34px auto 0;
  max-width: none;
}

/* Item 7: Chariti in a circle on the Donate page. */
.donate-portrait {
  width: 156px; height: 156px; border-radius: 50%;
  object-fit: cover; object-position: 50% 20%;
  border: 5px solid #fff;
  box-shadow: var(--shadow-3-dark);
  margin-bottom: 22px;
}

/* ============================================================
   HERO TEXTURES, ROUND 2 — four NEW options, deliberately not
   from the Brand Book (preview at /hero-textures.html).
   Same contract as round 1: they sit under the ring artwork,
   above the gradient, and never touch legibility.
   ============================================================ */

/* 4 · THE LINEN — a fine woven crosshatch on the diagonal, like
      cloth under raking light. */
.hero--tex-linen::before {
  background:
    repeating-linear-gradient(45deg,
      rgba(255, 255, 255, 0.065) 0 1px, transparent 1px 9px),
    repeating-linear-gradient(-45deg,
      rgba(255, 255, 255, 0.065) 0 1px, transparent 1px 9px);
  -webkit-mask-image: radial-gradient(ellipse 130% 100% at 50% 0%, #000 30%, transparent 85%);
          mask-image: radial-gradient(ellipse 130% 100% at 50% 0%, #000 30%, transparent 85%);
}

/* 5 · THE CURRENT — long drifting waves, water seen from above.
      Two wave sets slightly out of phase make a slow moiré. */
.hero--tex-current::before {
  background:
    repeating-radial-gradient(ellipse 160% 40% at 50% -20%,
      rgba(255, 255, 255, 0.05) 0 2px, transparent 2px 46px),
    repeating-radial-gradient(ellipse 170% 45% at 60% 130%,
      rgba(255, 255, 255, 0.06) 0 2px, transparent 2px 58px);
}

/* 6 · THE TOPO — two families of offset contour rings, like a
      topographic map of ground being remade. */
.hero--tex-topo::before {
  background:
    repeating-radial-gradient(circle at 12% 110%,
      rgba(255, 255, 255, 0.055) 0 1.6px, transparent 1.6px 42px),
    repeating-radial-gradient(circle at 95% -15%,
      rgba(255, 255, 255, 0.05) 0 1.6px, transparent 1.6px 54px);
}

/* 7 · THE EMBERS — a loose drift of soft points in three sizes,
      sparks rising, the least geometric of the seven. */
.hero--tex-embers::before {
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.20) 1px, transparent 1.6px),
    radial-gradient(rgba(255, 255, 255, 0.12) 1.4px, transparent 2.1px),
    radial-gradient(rgba(255, 255, 255, 0.07) 2px, transparent 2.8px);
  background-size: 58px 74px, 94px 118px, 148px 166px;
  background-position: 8px 12px, 40px 60px, 90px 30px;
  -webkit-mask-image: linear-gradient(112deg, #000 20%, transparent 88%);
          mask-image: linear-gradient(112deg, #000 20%, transparent 88%);
}

/* Between 1100 and 1320px the five columns get narrow enough for a
   4-line description; give the def more reserved height there so the
   movement rows stay level across all five domains. */
@media (min-width: 1101px) and (max-width: 1320px) {
  .rj-def { min-height: 6.8em; }
}

/* ============================================================
   DESIGN ROUND 2026-07-31 (late) — Brian's 10-item list
   ============================================================ */

/* Item 1: the calendar door filters wear their door colour, and fill
   solid with white text while switched on. */
.cal-filter.door--formation { color: var(--door-formation-ink); }
.cal-filter.door--marriage  { color: var(--door-marriage-ink); }
.cal-filter.door--healing   { color: var(--door-healing-ink); }
.cal-filter[aria-pressed="true"].door--formation { background: var(--door-formation-ink); border-color: var(--door-formation-ink); color: #fff; }
.cal-filter[aria-pressed="true"].door--marriage  { background: var(--door-marriage-ink);  border-color: var(--door-marriage-ink);  color: #fff; }
.cal-filter[aria-pressed="true"].door--healing   { background: var(--door-healing-ink);   border-color: var(--door-healing-ink);   color: #fff; }

/* Item 2: shorter ticker. */
.hero-ticker { padding: 7px 28px; }
@media (max-width: 760px) { .hero-ticker { padding: 6px 18px; } }

/* Item 3: Click-here pills, arrowless, and barely there.

   Frosted rather than filled. The door row it sits on is paper at 94%
   over the hero gradient, so a pill that blurs what is behind it
   picks up a little of that gradient at its edges and otherwise
   disappears into the row. A hairline is what keeps it reading as a
   control at all.

   The LABEL is not barely visible, and cannot be white. White needs a
   dark ground, and a dark ground is the opposite of the ask; on near
   white paper the only legible ink is the ocean the rest of the row
   already uses. The box recedes, the words stay readable.

   backdrop-filter is progressive: without it the pill is simply the
   35% white wash, which is still the quiet thing it is meant to be. */
.db-open {
  background: rgba(255, 255, 255, 0.35);
  -webkit-backdrop-filter: blur(7px) saturate(1.2);
          backdrop-filter: blur(7px) saturate(1.2);
  border: 1px solid rgba(27, 86, 141, 0.20);
  color: rgba(27, 86, 141, 0.82);
  padding: 8px 16px;
}
.door-btn:hover .db-open {
  background: rgba(255, 255, 255, 0.62);
  border-color: rgba(27, 86, 141, 0.38);
  color: var(--ocean);
  transform: none;
}

/* Item 4: the door line never wraps — "My marriage is hurting" stays
   on one line. */
.door-row .door-btn { font-size: 1.08rem; }
.door-btn .db-main { white-space: nowrap; }
@media (max-width: 1200px) and (min-width: 941px) { .door-row .door-btn { font-size: 1rem; } }

/* Item 6: Chariti's photo centres vertically in the hero. */
.hero-grid { align-items: center; }
.hero-portrait { margin-top: 0; --hero-portrait-offset: 0px; align-self: center; }

/* Item 7: the Three Doors pills are all the same size — full card
   width — with the text centred. */
.door-card .dc-name {
  align-self: stretch;
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  min-height: 52px;
}

/* Item 9: the podcast carousel. Native scroll-snap strip; the arrows
   just nudge it a card at a time. */
.pod-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; max-width: none; }
.pod-nav { display: flex; gap: 8px; }
.pod-arrow {
  width: 44px; height: 44px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--line); background: var(--paper); color: var(--deep);
  font-size: 1rem; transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.pod-arrow:hover { background: var(--deep); border-color: var(--deep); color: #fff; }
.pod-carousel {
  display: flex; gap: 18px;
  overflow-x: auto; scroll-snap-type: x proximity;
  padding: 4px 4px 18px;
  /* No scrollbar. The strip walks itself (see site.js), so the bar
     under it was a control nobody needed and a grey line drawn across
     the section. The track is still a real scroll container, so
     trackpad, touch, the arrows and the keyboard all still work. */
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-mask-image: linear-gradient(90deg, #000 96%, transparent);
          mask-image: linear-gradient(90deg, #000 96%, transparent);
}
.pod-carousel::-webkit-scrollbar { width: 0; height: 0; display: none; }
.pod-card {
  flex: 0 0 300px; scroll-snap-align: start;
  display: flex; flex-direction: column; align-items: flex-start;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 26px 24px;
  text-decoration: none; color: inherit;
  transition: transform .25s ease, box-shadow .25s ease;
}
.pod-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-3); }
/* Square, always. The tile is a fixed ratio rather than whatever the
   feed happens to send, so a run of episodes with mismatched artwork
   still reads as one row of cards. */
.pod-card .pod-art {
  width: 54px; aspect-ratio: 1; border-radius: var(--radius); overflow: hidden;
  background: var(--grad); display: flex; align-items: center; justify-content: center;
  margin-bottom: 16px;
}
.pod-card .pod-art img { width: 38px; height: 38px; border-radius: 50%; }
/* Real cover art fills the tile; the monogram fallback above stays a
   mark centred on the gradient, because it is a badge and covering the
   tile with it would only show its own pale ground as a square. */
.pod-card .pod-art--photo img {
  width: 100%; height: 100%; border-radius: 0; object-fit: cover;
}
.pod-card p { font-size: 0.95rem; color: #46555E; margin-bottom: 14px; }
.pod-card--cta { background: var(--sage-tint); }
@media (max-width: 640px) { .pod-card { flex-basis: 260px; } .pod-nav { display: none; } }

/* Item 8: hard alignment for the five domain cards. On the 5-across
   desktop grid every card shares the SAME row tracks via subgrid, so
   the icon row, title row, description row and each movement row (and
   the rule above it) sit at identical heights in all five columns —
   no matter how the text wraps. */
@media (min-width: 1101px) {
  @supports (grid-template-rows: subgrid) {
    .rj-grid { grid-template-rows: repeat(7, auto); }
    .rj-grid .rj-domain {
      display: grid;
      grid-template-rows: subgrid;
      grid-row: span 7;
      align-content: start;
    }
    .rj-grid .rj-domain .rj-moves { display: contents; }
    .rj-grid .rj-domain .rj-def { min-height: 0; }
  }
}

/* ============================================================
   DESIGN ROUND 2026-07-31 (night) — six follow-ups
   ============================================================ */

/* Item 1: Option 6 replacement — The Grain. Fine diagonal streaks,
   like rain caught in low light. Nothing circular in it. */
.hero--tex-grain::before {
  background:
    repeating-linear-gradient(115deg,
      rgba(255, 255, 255, 0.075) 0 1.2px, transparent 1.2px 7px),
    repeating-linear-gradient(115deg,
      rgba(255, 255, 255, 0.045) 0 2px, transparent 2px 23px);
  -webkit-mask-image: linear-gradient(115deg, #000 30%, transparent 95%);
          mask-image: linear-gradient(115deg, #000 30%, transparent 95%);
}

/* Item 3: The Better Question texture, turned up so it reads as a
   deliberate surface rather than a rumour. */
.section--texture::before {
  background-image:
    radial-gradient(rgba(54, 91, 109, 0.22) 1.4px, transparent 1.6px),
    radial-gradient(rgba(54, 91, 109, 0.13) 1.4px, transparent 1.6px);
  background-size: 24px 24px, 24px 24px;
  background-position: 0 0, 12px 12px;
  -webkit-mask-image: radial-gradient(ellipse 130% 100% at 78% 30%, #000 30%, transparent 92%);
          mask-image: radial-gradient(ellipse 130% 100% at 78% 30%, #000 30%, transparent 92%);
}

/* Item 4: the closing tagline sits on one line (wraps only when the
   viewport forces it). */
.cta-band .cta-tagline { white-space: nowrap; }
@media (max-width: 560px) { .cta-band .cta-tagline { white-space: normal; } }

/* Item 5: the report's lead piece — encouragement first, visually
   the warmest block on the page. */
.dr-encourage {
  background: var(--sage-tint);
  border-left: 3px solid var(--sage);
  border-radius: var(--radius);
  padding: 22px 24px;
  margin: 22px 0 6px;
}
.dr-encourage h3 {
  font-family: var(--mont); font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; color: #3d5a51;
  margin: 0 0 10px;
}
.dr-encourage p {
  font-family: var(--serif); font-size: 1.18rem; line-height: 1.6;
  color: var(--deep); margin: 0 0 10px;
}
.dr-encourage p:last-child { margin-bottom: 0; }

/* Item 6: platform links under the homepage podcast carousel. */
.pod-platforms { margin-top: 4px; font-size: 0.92rem; color: #46555E; }
.pod-platforms a { color: var(--ocean); text-decoration: none; border-bottom: 1.5px solid var(--sage); padding-bottom: 2px; }
.pod-platforms a:hover { color: #174a7b; }

/* ============================================================
   TEXTURE DECISION 2026-07-31: Option 1 "The Dawn" on every
   gradient hero, Option 2 "The Seed" as the companion texture
   through the rest of the site. The old hard contour rings
   (.rings overlays + the 44px ::before rings) are retired.
   ============================================================ */

/* Rings off, site-wide. */
.hero .rings, .hero .rings2 { display: none; }

/* 1 · The Dawn on all heroes (home + every sub-page hero): wide soft
   rings rising from below the fold, exactly the Option 1 preview. */
.hero::before {
  background: repeating-radial-gradient(circle at 50% 128%,
    rgba(255, 255, 255, 0.075) 0 1.7px,
    transparent 1.7px 74px);
  -webkit-mask-image: linear-gradient(to top, #000 8%, transparent 92%);
          mask-image: linear-gradient(to top, #000 8%, transparent 92%);
}

/* 2 · The Seed on the closing CTA band, in white — the companion
   texture, so hero and band read as a family without twinning. */
.cta-band::before {
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.16) 1.1px, transparent 1.2px),
    radial-gradient(rgba(255, 255, 255, 0.10) 1.1px, transparent 1.2px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  -webkit-mask-image: radial-gradient(ellipse 120% 90% at 30% 20%, #000 20%, transparent 78%);
          mask-image: radial-gradient(ellipse 120% 90% at 30% 20%, #000 20%, transparent 78%);
}

/* 2 · The Seed, whisper-quiet in ink, across the ivory alt sections
   so the texture pair runs through the whole site. Backgrounds of
   cards and panels paint over it; it lives only on the open paper. */
.section-alt { position: relative; }
.section-alt::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    radial-gradient(rgba(54, 91, 109, 0.075) 1.1px, transparent 1.2px),
    radial-gradient(rgba(54, 91, 109, 0.05) 1.1px, transparent 1.2px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  -webkit-mask-image: radial-gradient(ellipse 120% 100% at 50% 0%, #000 25%, transparent 90%);
          mask-image: radial-gradient(ellipse 120% 100% at 50% 0%, #000 25%, transparent 90%);
}

/* ============================================================
   DESIGN ROUND 2026-07-31 (v) — five follow-ups
   ============================================================ */

/* Item 2: the hero tagline holds one line at desktop widths. */
.hero .hero-tagline { white-space: nowrap; max-width: none; }
@media (max-width: 700px) { .hero .hero-tagline { white-space: normal; } }

/* Item 1: the decode line under the doors — one line, with the name
   as a transparent (ghost) button. */
.hero-decode { display: flex; align-items: center; gap: 12px; white-space: nowrap; }
.decode-ghost {
  display: inline-flex; align-items: center;
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.10);
  color: #fff !important;
  border-radius: 999px; padding: 9px 18px;
  font-family: var(--mont); font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; text-decoration: none;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.decode-ghost:hover { background: rgba(255, 255, 255, 0.22); border-color: rgba(255, 255, 255, 0.8); }

/* ---- the product name beside the page title ----
   The page is headed "The Joy Restored Guide", which is what the tool
   IS; "Let's Decode That" is what it is CALLED everywhere else on the
   site, so the two have to be visible together or a visitor arriving
   from a Decode card cannot tell they have landed on it. It rides
   beside the h1 as a chip rather than becoming a second line, and
   drops underneath on a narrow screen. */
/* The h1's measure is set for a headline reading as prose, and the
   chip does not fit inside it, so it dropped onto a line of its own,
   which is the one thing it must not do. The heading gets the width
   the chip needs and no more. */
.hero h1:has(.ldt-name) { max-width: 660px; }
.ldt-name {
  display: inline-flex; align-items: center;
  vertical-align: middle;
  margin-left: 16px;
  border: 1px solid rgba(110, 198, 227, 0.55);
  background: rgba(110, 198, 227, 0.14);
  color: var(--sky);
  border-radius: 999px; padding: 8px 16px 7px;
  font-family: var(--mont); font-size: 0.66rem; font-weight: 600;
  font-style: normal; letter-spacing: 0.14em; text-transform: uppercase;
  white-space: nowrap;
}
@media (max-width: 700px) {
  .ldt-name { display: inline-flex; margin: 14px 0 0; font-size: 0.6rem; }
}
@media (max-width: 620px) { .hero-decode { white-space: normal; flex-wrap: wrap; } }

/* Item 3: the Let's Decode That ad card — gradient, seeded, with a
   ghost button. Replaces the plain status banner on 14 pages. */
.decode-ad {
  position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: space-between; gap: 28px;
  background: var(--grad); color: #fff;
  border-radius: var(--radius);
  padding: 26px 32px; margin-top: 34px;
}
.decode-ad::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.14) 1.1px, transparent 1.2px),
    radial-gradient(rgba(255, 255, 255, 0.08) 1.1px, transparent 1.2px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  -webkit-mask-image: radial-gradient(ellipse 120% 100% at 85% 0%, #000 15%, transparent 80%);
          mask-image: radial-gradient(ellipse 120% 100% at 85% 0%, #000 15%, transparent 80%);
}
.decode-ad .da-main { position: relative; }
.decode-ad .da-kicker {
  display: block;
  font-family: var(--mont); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: #BFE6D6; margin-bottom: 8px;
}
.decode-ad p { margin: 0; font-size: 1rem; color: rgba(255, 255, 255, 0.92); max-width: 62ch; }
.decode-ad .da-btn {
  position: relative; flex: none; white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.10);
  color: #fff; text-decoration: none;
  border-radius: 999px; padding: 13px 24px;
  font-family: var(--mont); font-size: 0.64rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
.decode-ad .da-btn:hover { background: rgba(255, 255, 255, 0.22); border-color: rgba(255, 255, 255, 0.85); transform: translateY(-2px); }
@media (max-width: 760px) {
  .decode-ad { flex-direction: column; align-items: flex-start; gap: 18px; padding: 24px; }
}

/* Item 4: the journey's closing sentence holds one line. */
.rj-foot-line { white-space: nowrap; }
@media (max-width: 900px) { .rj-foot-line { white-space: normal; } }
.rj-foot .textlink { display: inline-block; margin-top: 10px; }

/* Item 5: the ivory alt sections carry the SAME weight of Seed as
   The Better Question, so the texture reads as one system. */
.section-alt::before {
  background-image:
    radial-gradient(rgba(54, 91, 109, 0.22) 1.4px, transparent 1.6px),
    radial-gradient(rgba(54, 91, 109, 0.13) 1.4px, transparent 1.6px);
  background-size: 24px 24px, 24px 24px;
  background-position: 0 0, 12px 12px;
  -webkit-mask-image: radial-gradient(ellipse 130% 100% at 50% 0%, #000 30%, transparent 92%);
          mask-image: radial-gradient(ellipse 130% 100% at 50% 0%, #000 30%, transparent 92%);
}

/* ============================================================
   DESIGN ROUND 2026-08-04 — the product ladder reads by kind

   Until now free-vs-paid was a sage tint against a blue tint, and
   the one genuinely designed card on any door page was the
   Formation Journey. Three changes fix that:

   1  Assessments are their own kind of thing, not merely "free":
      they are Sky, the one palette colour nothing else uses.
   2  Everything you pay for wears the Formation Journey's deep
      gradient, so price is legible before a word is read.
   3  Live offers carry a LIVE flag in the corner, because "you
      will be in a room with Chariti" is the thing being sold.

   Plus: the header ticker's door icons sit in a filled circle of
   their own door's colour, and Let's Decode That is a block on
   the right of the top section rather than a full-width band.
   ============================================================ */

/* ---- 1 · The assessment rung, in Sky ---- */
.path-step.is-assess .ps-card {
  background: linear-gradient(168deg, #EAF7FC 0%, #D4EDF8 100%);
  border-color: #A9DCEF;
}
.path-step.is-assess .ps-card::after { background: var(--sky); opacity: 1; }
.path-step.is-assess .ps-chip { background: var(--sky); color: #123243; }
.path-step.is-assess .ps-go   { color: #0F5F7B; }
.path-step.is-assess .ps-dot  { border-color: var(--sky); background: var(--sky); }
.path-step.is-assess.is-lit .ps-card { border-color: var(--sky); }

/* ---- 2 · Every paid rung gets the Formation Journey treatment ---- */
.path-step.is-paid .ps-card {
  background: var(--grad);
  border-color: transparent;
}
.path-step.is-paid .ps-card::after { background: rgba(255, 255, 255, 0.5); }
.path-step.is-paid .ps-card h3 { color: var(--white); }
.path-step.is-paid .ps-card p  { color: rgba(255, 255, 255, 0.86); }
.path-step.is-paid .ps-chip { background: rgba(255, 255, 255, 0.2); color: #fff; }
.path-step.is-paid .ps-go   { color: #fff; }
.path-step.is-paid .ps-dot  { border-color: var(--deep); background: var(--deep); }
/* The featured rung keeps its emphasis, now as a brighter edge on
   the gradient rather than a different background. */
.path-step.is-featured .ps-card { border-color: var(--sky); }
.path-step.is-featured .ps-card::after { background: var(--sky); opacity: 1; height: 5px; }
.path-step.is-featured .ps-dot { border-color: var(--sky); background: var(--sky); }

/* ---- 3 · The LIVE flag ---- */
.ps-live {
  position: absolute; top: 0; right: 0; z-index: 3;
  display: inline-flex; align-items: center; gap: 6px;
  background: #fff; color: var(--deep);
  font-family: var(--mont); font-size: 0.5rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  padding: 5px 10px 5px 9px; border-radius: 0 0 0 var(--radius);
}
.ps-live::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: #D2544A; animation: ps-live-pulse 1.9s ease-in-out infinite;
}
@keyframes ps-live-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.75); }
}
@media (prefers-reduced-motion: reduce) { .ps-live::before { animation: none; } }
/* Inline LIVE marker for prose and buttons elsewhere on the site. */
.live-tag {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--deep); background: rgba(110, 198, 227, 0.24);
  padding: 4px 11px; border-radius: 999px;
}
.live-tag::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: #D2544A; animation: ps-live-pulse 1.9s ease-in-out infinite;
}
.live-tag--light { color: #fff; background: rgba(255, 255, 255, 0.18); }
@media (prefers-reduced-motion: reduce) { .live-tag::before { animation: none; } }

/* ---- 4 · Ticker icons in their door's colour ---- */
.ht-item .ht-ico {
  flex: none; width: 23px; height: 23px; border-radius: 50%;
  display: inline-grid; place-items: center;
  background: var(--ti, var(--door-formation-ink)); color: var(--tii, #fff);
}
.ht-item .ht-ico .door-icon { width: 13px; height: 13px; opacity: 1; }

/* ---- 5 · Let's Decode That, a block on the right ----
   It sells across all three doors, so it takes the neutral Slate
   panel with a Sky edge rather than any one door's colour, and it
   must not read as another paid rung. */
.path-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 350px);
  gap: 46px; align-items: start; margin-bottom: 40px;
}
.path-top > .section-head { margin-bottom: 0; }

.decode-block {
  position: relative; overflow: hidden;
  padding: 25px 24px 24px; border-radius: var(--radius);
  background: linear-gradient(158deg, #213240 0%, #3A475A 100%);
  border-top: 4px solid var(--sky);
  box-shadow: var(--shadow-2-dark);
  color: #fff;
}
.decode-block::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.13) 1.1px, transparent 1.2px),
    radial-gradient(rgba(255, 255, 255, 0.07) 1.1px, transparent 1.2px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  -webkit-mask-image: radial-gradient(ellipse 130% 110% at 90% 0%, #000 15%, transparent 82%);
          mask-image: radial-gradient(ellipse 130% 110% at 90% 0%, #000 15%, transparent 82%);
}
/* The white wordmark, small, in the bottom right corner. The Guide is
   the one thing on these pages that answers in Joy Restored's voice
   without Chariti in the room, so the tile signs itself. Set as a
   background on ::after rather than an <img> in the markup, because
   this block is duplicated across eighteen pages by hand and there is
   no generator for it. ::before is already the dot field. */
.decode-block::after {
  content: "";
  position: absolute; right: 20px; bottom: 18px;
  width: 78px; height: 44px;                  /* 1091x618, kept in ratio */
  background: url("jr-logo-white.png") right bottom / contain no-repeat;
  /* Signed in white, not in grey. At 0.5 the mark sank far enough into
     the slate behind it to read as a watermark someone had left switched
     on; the tile is meant to sign itself, so it signs itself legibly. */
  opacity: 0.92;
  pointer-events: none;
}
.decode-block > * { position: relative; z-index: 1; }
.decode-block .db-kicker {
  display: block;
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.19em; text-transform: uppercase;
  color: var(--sky); margin-bottom: 9px;
}
.decode-block p {
  margin: 0; font-size: 0.94rem; line-height: 1.6;
  color: rgba(255, 255, 255, 0.88);
}
.decode-block .db-cta {
  display: inline-block; margin-top: 18px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.1);
  color: #fff; text-decoration: none;
  border-radius: 999px; padding: 11px 20px;
  font-family: var(--mont); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
.decode-block .db-cta:hover {
  background: rgba(255, 255, 255, 0.22);
  border-color: rgba(255, 255, 255, 0.85);
  transform: translateY(-2px);
}
/* On pages with no ladder to sit beside, the block still hangs on
   the right of the top section. It is pulled up over the bottom
   edge of the hero so the space to its left reads as the hero
   rather than as an empty band nobody meant to leave there. */
.decode-rail {
  display: flex; justify-content: flex-end;
  position: relative; z-index: 3;
  margin-top: -58px;
}
.decode-rail > .decode-block { width: 350px; max-width: 100%; }

/* ---- 5b · the block, moved into the hero ----
   It now rides in the hero itself rather than in a band underneath,
   filling the empty right half the sub-heroes always had, and it
   leads with the name at full size instead of a 0.56rem kicker. */
.hero--sub.has-decode > .hero-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 370px);
  gap: 54px;
  align-items: center;
}
.hero--sub.has-decode .hero-copy > :last-child { margin-bottom: 0; }

.decode-block--hero {
  /* Slightly deeper than the band version: on the hero's own gradient
     it needs its own weight to stay a distinct object. */
  box-shadow: var(--shadow-3-dark);
  border-top-width: 5px;
  /* A quarter taller than the 330px it came to on its own content.
     The extra height is put between the copy and the button rather
     than into the padding, so it reads as room around the offer and
     not as a box with a hole in the middle of it. A minimum rather
     than a height: on a phone the paragraph already runs past this,
     and the tile should grow with it rather than clip. */
  min-height: 413px;
  display: flex; flex-direction: column;
}
/* Two classes on purpose: a later rule further down this file sets
   margin-top on .decode-block .db-cta at the same specificity, so an
   override here has to outrank it rather than hope to follow it. */
.decode-block.decode-block--hero .db-cta {
  margin-top: auto; align-self: flex-start;
}
.decode-block .db-title {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.55rem, 2.5vw, 2.05rem);
  line-height: 1.12;
  letter-spacing: -0.005em;
  color: #fff;
  margin: 0 0 11px;
}

/* ---- the face on the other end of the call ----
   Fifteen minutes with a stranger is easier to book once you have seen
   who you are booking it with, so the Quick Chat hero carries her
   photo instead of describing her. It fills the empty right half the
   sub-heroes have, the same half .has-decode uses, and it stacks under
   the copy before the two would start squeezing each other. The crop
   sits above centre because the source is a tall headshot and a
   centred square takes the top of her head off. */
.hero--face > .hero-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 260px);
  gap: 54px;
  align-items: center;
}
.hero--face .hero-copy > :last-child { margin-bottom: 0; }
.qc-face { margin: 0; }
.qc-face img {
  width: 100%; max-width: 240px; height: auto;
  aspect-ratio: 1 / 1; object-fit: cover; object-position: 50% 32%;
  display: block; margin: 0 auto;
  border-radius: 50%;
  border: 4px solid rgba(255, 255, 255, 0.28);
  box-shadow: var(--shadow-3-dark);
}
.qc-face figcaption {
  margin-top: 14px; text-align: center;
  font-family: var(--mont); font-size: 0.58rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
}
@media (max-width: 900px) {
  .hero--face > .hero-inner { grid-template-columns: 1fr; gap: 32px; }
  .qc-face img { max-width: 172px; }
}

/* The path head no longer shares its row with the block. */
.path-top--solo { grid-template-columns: minmax(0, 1fr); }

@media (max-width: 900px) {
  .path-top { grid-template-columns: 1fr; gap: 28px; }
  .decode-rail { justify-content: stretch; margin-top: -40px; }
  .decode-rail > .decode-block { width: 100%; }
  /* Stack under the hero copy rather than squeezing the headline. */
  .hero--sub.has-decode > .hero-inner { grid-template-columns: 1fr; gap: 34px; }
}

/* ============================================================
   NEW PAGES 2026-08-04
   The Turning · A Way Through · Go Bags · Dream Interpretation
   ============================================================ */

/* The Turning and A Way Through reuse Becoming's month timeline for
   their schedules. It has a .tl-month label but no time label, so
   one is added rather than borrowing a label meant for months. */
.tl-time {
  font-family: var(--mont); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--ocean);
}

/* ---- Go Bags: the before and the after, side by side ----
   The whole page turns on one comparison, so it is the first thing
   under the hero and it is the only place a photograph is this big. */
.gb-compare {
  display: grid; grid-template-columns: 1fr 1fr; gap: 26px;
  align-items: stretch;
}
.gb-shot {
  margin: 0; display: flex; flex-direction: column;
  border-radius: var(--radius); overflow: hidden;
  background: var(--paper); box-shadow: var(--shadow);
}
/* Both photographs are pre-cropped to this box's ratio, so cover
   barely crops. Direct child only, so a caption image would not be
   caught by it. */
.gb-shot > img {
  width: 100%; height: 420px; object-fit: cover; object-position: 50% 50%;
}
.gb-shot figcaption {
  padding: 20px 22px 22px; font-size: 0.96rem; color: #46555E;
}
.gb-tag {
  display: block; margin-bottom: 7px;
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
}
.gb-tag--before { color: #8A7F72; }
.gb-tag--after  { color: var(--ocean); }

@media (max-width: 820px) {
  .gb-compare { grid-template-columns: 1fr; }
  .gb-shot > img { height: 320px; }
}

/* ---- Dream Interpretation: the partner code, and the embed ---- */
.promo-code {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; width: 100%; margin-top: 18px;
  padding: 15px 18px; border-radius: var(--radius);
  border: 2px dashed rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.12);
  cursor: pointer; font: inherit; text-align: left;
  transition: background 0.15s ease;
}
.promo-code:hover { background: rgba(255, 255, 255, 0.22); }
.promo-code-value {
  font-family: var(--mont); font-weight: 700; font-size: 1.05rem;
  letter-spacing: 0.06em; color: #fff;
}
.promo-code-action {
  font-family: var(--mont); font-size: 0.55rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72); white-space: nowrap;
}
.dream-embed {
  position: relative; width: 100%; height: 720px;
  border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--shadow);
  background: #fff;
}
.dream-embed iframe { width: 100%; height: 100%; border: 0; display: block; }
@media (max-width: 820px) { .dream-embed { height: 560px; } }

/* The compact pair, for the homepage teaser: same two frames, small
   enough to sit beside the copy in a .split column. */
.gb-compare--mini { gap: 14px; }
.gb-compare--mini .gb-shot > img { height: 188px; }
.gb-compare--mini .gb-shot figcaption { padding: 13px 15px 15px; font-size: 0.84rem; line-height: 1.45; }
.gb-compare--mini .gb-tag { font-size: 0.5rem; margin-bottom: 5px; }
@media (max-width: 820px) {
  .gb-compare--mini { grid-template-columns: 1fr 1fr; }
  .gb-compare--mini .gb-shot > img { height: 150px; }
}

/* ============================================================
   RESTORATION JOURNEY, the lit tile wears the paid palette
   (2026-08-04)

   The five domains used to light up by turning white with a sage
   edge, which read as "highlighted" but connected to nothing. They
   now take the same Deep Sea to Sage gradient the paid products
   wear, so the moment a domain lights up it is visibly the same
   system as the Formation Journey card and every purchasable rung.

   Two mechanics worth knowing before editing:

   1  The gradient lives on a ::before whose OPACITY animates.
      background-image does not interpolate, so animating the
      background directly would snap rather than fade.
   2  Every animated element reads its offset from --rj-delay,
      which is set once per tile and inherits to the children and
      to the pseudo-element. Without that, the five delays would
      have to be repeated for each of the seven animated
      selectors.
   ============================================================ */

.rj-grid .rj-domain:nth-child(1) { --rj-delay:   0s; }
.rj-grid .rj-domain:nth-child(2) { --rj-delay: -16s; }
.rj-grid .rj-domain:nth-child(3) { --rj-delay: -12s; }
.rj-grid .rj-domain:nth-child(4) { --rj-delay:  -8s; }
.rj-grid .rj-domain:nth-child(5) { --rj-delay:  -4s; }

.rj-domain { position: relative; overflow: hidden; }
.rj-domain > * { position: relative; z-index: 1; }
.rj-domain::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: var(--grad); opacity: 0;
}

/* Every animated part of a tile, on one clock. */
.rj-grid .rj-domain,
.rj-grid .rj-domain::before,
.rj-grid .rj-domain h3,
.rj-grid .rj-domain .rj-def,
.rj-grid .rj-domain .rj-ico,
.rj-grid .rj-domain .rj-moves,
.rj-grid .rj-domain .rj-moves li,
.rj-grid .rj-domain .rj-moves li > b,
.rj-grid .rj-domain .rj-moves li::before {
  animation-duration: 20s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-delay: var(--rj-delay, 0s);
}

.rj-grid .rj-domain::before        { animation-name: rj-glow; }
.rj-grid .rj-domain h3             { animation-name: rj-ink-strong; }
.rj-grid .rj-domain .rj-def        { animation-name: rj-ink-soft; }
.rj-grid .rj-domain .rj-ico        { animation-name: rj-ico-lit; }
.rj-grid .rj-domain .rj-moves      { animation-name: rj-rule-lit; }
.rj-grid .rj-domain .rj-moves li   { animation-name: rj-ink-body; }

/* The tile itself keeps its shadow-and-border animation, minus the
   old white background, which the gradient overlay now supplies. */
@keyframes rj-lift {
  0%, 14%   { box-shadow: var(--shadow-3); border-color: transparent; }
  20%, 100% { box-shadow: none; border-color: var(--line); }
}

@keyframes rj-glow       { 0%, 14% { opacity: 1; }              20%, 100% { opacity: 0; } }
@keyframes rj-ink-strong { 0%, 14% { color: #fff; }             20%, 100% { color: var(--ink); } }
@keyframes rj-ink-soft   { 0%, 14% { color: rgba(255,255,255,.85); } 20%, 100% { color: #46555E; } }
@keyframes rj-ink-body   { 0%, 14% { color: rgba(255,255,255,.9); }  20%, 100% { color: var(--ink); } }
@keyframes rj-ico-lit {
  0%, 14%   { background: rgba(255, 255, 255, 0.2); color: #fff; }
  20%, 100% { background: var(--sage-tint); color: var(--deep); }
}
@keyframes rj-rule-lit {
  0%, 14%   { border-top-color: rgba(255, 255, 255, 0.28); }
  20%, 100% { border-top-color: var(--line); }
}

/* The four movements keep their identity when lit, but the ink
   versions of Truth and Lament vanish on a deep ground, so each
   gets a light twin used only for the lit half of the cycle. */
.rj-grid .rj-domain .rj-moves li.rj-truth    > b { animation-name: rj-mv-truth; }
.rj-grid .rj-domain .rj-moves li.rj-lament   > b { animation-name: rj-mv-lament; }
.rj-grid .rj-domain .rj-moves li.rj-forgive  > b { animation-name: rj-mv-forgive; }
.rj-grid .rj-domain .rj-moves li.rj-remember > b { animation-name: rj-mv-remember; }
.rj-grid .rj-domain .rj-moves li.rj-truth::before    { animation-name: rj-dot-truth; }
.rj-grid .rj-domain .rj-moves li.rj-lament::before   { animation-name: rj-dot-lament; }
.rj-grid .rj-domain .rj-moves li.rj-forgive::before  { animation-name: rj-dot-forgive; }
.rj-grid .rj-domain .rj-moves li.rj-remember::before { animation-name: rj-dot-remember; }

@keyframes rj-mv-truth    { 0%,14% { color: #9CD0EE; } 20%,100% { color: var(--mv-truth); } }
@keyframes rj-mv-lament   { 0%,14% { color: #C3DBE3; } 20%,100% { color: var(--mv-lament); } }
@keyframes rj-mv-forgive  { 0%,14% { color: #A9DCC9; } 20%,100% { color: var(--mv-forgive); } }
@keyframes rj-mv-remember { 0%,14% { color: #9DE2F6; } 20%,100% { color: var(--mv-remember); } }
@keyframes rj-dot-truth    { 0%,14% { background: #9CD0EE; } 20%,100% { background: var(--mv-truth); } }
@keyframes rj-dot-lament   { 0%,14% { background: #C3DBE3; } 20%,100% { background: var(--mv-lament); } }
@keyframes rj-dot-forgive  { 0%,14% { background: #A9DCC9; } 20%,100% { background: var(--mv-forgive); } }
@keyframes rj-dot-remember { 0%,14% { background: #9DE2F6; } 20%,100% { background: var(--mv-remember); } }

/* Reduced motion: no cycling at all, and every tile stays in its
   readable resting state rather than frozen mid-gradient. */
@media (prefers-reduced-motion: reduce) {
  .rj-grid .rj-domain,
  .rj-grid .rj-domain::before,
  .rj-grid .rj-domain h3,
  .rj-grid .rj-domain .rj-def,
  .rj-grid .rj-domain .rj-ico,
  .rj-grid .rj-domain .rj-moves,
  .rj-grid .rj-domain .rj-moves li,
  .rj-grid .rj-domain .rj-moves li > b,
  .rj-grid .rj-domain .rj-moves li::before { animation: none; }
  .rj-domain::before { opacity: 0; }
}

/* ============================================================
   LET'S DECODE THAT, the two sample reports (2026-08-04)
   ============================================================ */

/* The picker on lets-decode-that.html. The prompt IS the button:
   people recognise their own situation faster than they read a
   label like "Sample report 2". */
.sample-picker { margin-top: 34px; }
.sp-lead {
  text-align: center; margin: 0 0 16px;
  font-size: 0.95rem; color: #46555E;
}
.sp-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.sp-card {
  display: flex; flex-direction: column; justify-content: space-between;
  gap: 14px; padding: 22px 22px 20px;
  border-radius: var(--radius);
  background: linear-gradient(168deg, #EAF7FC 0%, #D4EDF8 100%);
  border: 1px solid #A9DCEF;
  text-decoration: none;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.sp-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.sp-quote {
  font-family: var(--serif); font-style: italic;
  font-size: 1.04rem; line-height: 1.45; color: var(--ink);
}
.sp-go {
  font-family: var(--mont); font-size: 0.58rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; color: #0F5F7B;
}
@media (max-width: 700px) { .sp-row { grid-template-columns: 1fr; } }

/* The prompt block at the top of each sample, so a reader can see
   what went in as well as what came back. */
.dr-prompt {
  margin: 0 0 22px; padding: 20px 22px;
  border-radius: var(--radius);
  background: var(--sage-tint);
  border-left: 4px solid var(--sage);
}
.dr-prompt .drp-label {
  display: block; margin-bottom: 8px;
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.19em; text-transform: uppercase; color: #3d6b5c;
}
.dr-prompt p {
  margin: 0; font-family: var(--serif); font-style: italic;
  font-size: 1.14rem; line-height: 1.5; color: var(--ink);
}

/* ============================================================
   LIVE, at twice the size (2026-08-04)

   The corner flag was set at the same 0.5rem as the "Most people
   start here" ribbon it replaced, which undersold the one thing
   that separates these products from a recording. Doubled: type,
   padding and the pulse dot all scale together so it stays a
   badge rather than becoming loose text in a corner.
   ============================================================ */
.ps-live {
  font-size: 1rem;
  letter-spacing: 0.14em;
  padding: 9px 17px 9px 15px;
  gap: 9px;
  border-radius: 0 0 0 var(--radius);
}
.ps-live::before { width: 12px; height: 12px; }

/* The inline marker on the two live product pages moves with it,
   so the hero and the card read as the same label. It sits in a
   sentence rather than a corner, so it lands a little under the
   card flag's size. */
.live-tag {
  font-size: 0.86rem;
  letter-spacing: 0.13em;
  padding: 6px 15px;
  gap: 8px;
}
.live-tag::before { width: 9px; height: 9px; }

/* A doubled flag needs the card to give it room, or it collides with
   the price chip on the narrower rungs. That room used to be pushed
   onto the chip of the live rungs alone, which stepped their price
   and title 26px below every other card in the row. Now the whole
   ladder reserves the flag's line, so prices and titles sit on one
   baseline whether or not a rung is live.

   Horizontal ladders only. Stacked cards run the full width, the flag
   sits far right of the chip, and nothing collides. */
.path-step .ps-live + .ps-chip { margin-top: 0; }
@media (min-width: 901px) {
  .path .ps-card { padding-top: 50px; }
}

/* ============================================================
   Primary nav dropdowns  (markup from tools/build-nav.mjs)
   Six top-level items; four open a menu. Desktop opens on hover
   and on focus; touch and keyboard use the aria-expanded toggle
   driven by site.js.
   ============================================================ */

.nav-item { position: relative; }

/* top-level trigger, styled to match the plain <a> siblings */
.nav-top {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--deep);
  background: none;
  border: 0;
  /* balanced the same way .nav-links a is, so the menu tops and the
     plain links share one optical line */
  border-top: 1.7px solid transparent;
  border-bottom: 1.7px solid transparent;
  padding: 5px 0;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.nav-top:hover { color: var(--ocean); }
.nav-top:focus-visible { outline: 2px solid var(--ocean); outline-offset: 4px; }
/* the section owning the current page reads as selected */
.nav-item.has-current > .nav-top { color: var(--ocean); border-bottom-color: var(--sage); }

.nav-caret { width: 10px; height: 6px; flex: none; transition: transform 0.18s ease; }
.nav-item.is-open > .nav-top .nav-caret { transform: rotate(180deg); }

/* the menu itself */
.nav-menu {
  position: absolute;
  top: 100%;
  left: -14px;
  min-width: 244px;
  margin-top: 10px;
  padding: 8px;
  list-style: none;
  /* Opaque, deliberately. This panel opens over the hero and over the
     portrait in it, and anything less than a solid ground turns the
     menu into a window onto a photograph. No transparency, no blur. */
  background: var(--white);
  background-color: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
  z-index: 70;
}
/* a hover bridge across the 10px gap so the menu does not close mid-travel */
.nav-item.has-menu::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 0; right: 0;
  height: 12px;
}
.nav-item.is-open > .nav-menu,
.nav-item.has-menu:hover > .nav-menu,
.nav-item.has-menu:focus-within > .nav-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.nav-links .nav-menu a {
  display: block;
  padding: 10px 14px;
  border-radius: var(--radius);
  border-bottom: 0;
  font-size: 0.76rem;
  letter-spacing: 0.07em;
  text-transform: none;
  font-weight: 500;
  color: var(--slate);
  white-space: nowrap;
}
.nav-links .nav-menu a:hover,
.nav-links .nav-menu a:focus-visible { background: var(--sage-tint); color: var(--ocean); }
.nav-links .nav-menu a.active { color: var(--ocean); background: var(--sage-tint); border-bottom: 0; }

@media (max-width: 1180px) {
  .nav-top { font-size: 0.74rem; letter-spacing: 0.09em; }
}

/* ---------- collapsed nav: menus become accordions ---------- */
@media (max-width: 1140px) {
  .nav-item { width: 100%; }
  .nav-top {
    display: flex;
    justify-content: space-between;
    width: 100%;
    padding: 18px 28px;
    font-size: 0.82rem;
    letter-spacing: 0.12em;
    border-bottom: 1px solid rgba(54, 91, 109, 0.08);
  }
  .nav-item.has-current > .nav-top { border-bottom-color: rgba(54, 91, 109, 0.08); }
  .nav-item.has-menu::after { content: none; }

  .nav-menu {
    position: static;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: var(--paper);
    opacity: 1;
    visibility: visible;
    transform: none;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.22s ease;
  }
  /* hover must NOT open these on touch; only the explicit toggle does */
  .nav-item.has-menu:hover > .nav-menu { max-height: 0; }
  .nav-item.is-open > .nav-menu,
  .nav-item.has-menu:focus-within > .nav-menu { max-height: 420px; }

  .nav-links .nav-menu a {
    border-radius: 0;
    padding: 15px 28px 15px 44px;
    font-size: 0.8rem;
    border-bottom: 1px solid rgba(54, 91, 109, 0.06);
  }
  /* the panel is taller now that it holds four accordions */
  .nav-toggle:checked ~ .nav-links { max-height: min(78vh, 900px); overflow-y: auto; }
}

/* ============================================================
   Direct-intent bar (homepage, directly under the hero)
   For people who already know what they want. Intentionally
   understated so it never competes with the three doors.
   ============================================================ */
.quick-bar {
  background: var(--ivory);
  border-bottom: 1px solid var(--line);
}
.quick-bar-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 22px;
  padding: 13px 28px;
}
.qb-label {
  font-family: var(--sans);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--slate);
  opacity: 0.85;
}
.qb-links { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 20px; }
.qb-links a {
  position: relative;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ocean);
  text-decoration: none;
  border-bottom: 1.5px solid transparent;
  padding-bottom: 2px;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.qb-links a:hover,
.qb-links a:focus-visible { border-bottom-color: var(--sage); }
/* middot separators between the links, not after the last */
.qb-links a + a::before {
  content: "\00b7";
  position: absolute;
  left: -11px;
  color: var(--line);
  border: 0;
}
@media (max-width: 560px) {
  .quick-bar-inner { flex-direction: column; gap: 8px; padding: 14px 20px; }
  .qb-links { justify-content: center; gap: 6px 18px; }
}

/* ============================================================
   Founders lockup (About) — Chariti and Casey side by side
   ============================================================ */
.founders-band { padding: 64px 0 8px; }
/* Half size. The two photographs used to fill the measure; capped and
   centred they read as portraits on the page rather than as the page. */
.founders {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  max-width: 560px;
  margin: 0 auto;
}
.founder { margin: 0; }
.founder-photo {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  background: var(--sage-tint);
  aspect-ratio: 912 / 1136;
}
.founder-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.founder figcaption { padding-top: 18px; }
.founder-name {
  display: block;
  font-family: var(--serif);
  font-size: 1.5rem;
  line-height: 1.2;
  color: var(--ink);
}
.founder-role {
  display: block;
  margin-top: 4px;
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sage);
}
.founder figcaption p {
  margin-top: 12px;
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--slate);
}
.founders-note {
  margin-top: 34px;
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.12rem;
  color: var(--deep);
}
@media (max-width: 760px) {
  /* they stay side by side now: at half size two columns still fit, and
     stacking them would undo the size change on the narrowest screens */
  .founders { gap: 16px; max-width: 340px; }
  .founder-name { font-size: 1.2rem; }
  .founders-band { padding: 46px 0 4px; }
}

/* ============================================================
   SageFire Collective band (About)
   SageFire brand greens, deliberately distinct from Joy Restored's
   ocean/sage so it reads as "a company they belong to", not JR itself.
   ============================================================ */
:root {
  --sf-deep:  #0B3A3C;
  --sf-green: #1FA64A;
  --sf-leaf:  #12673E;
}
.sf-band {
  background: var(--paper);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.sf-inner {
  display: grid;
  grid-template-columns: 1.25fr 0.75fr;
  gap: 56px;
  align-items: center;
}
.sf-copy h2 { margin-bottom: 14px; }
.sf-copy p { color: var(--slate); margin-bottom: 14px; max-width: 56ch; }
.sf-copy .btn { margin-top: 12px; }

.btn--sage {
  background: var(--sf-deep);
  color: var(--white);
  border: 1px solid var(--sf-deep);
}
.btn--sage:hover { background: var(--sf-leaf); border-color: var(--sf-leaf); color: var(--white); }

.sf-lockup { display: flex; justify-content: center; }
.sf-mark {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 34px 40px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
  box-shadow: var(--shadow);
  text-decoration: none;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.sf-mark:hover { transform: translateY(-3px); box-shadow: var(--shadow-3); }
.sf-mark img { width: 92px; height: auto; display: block; }
.sf-wordmark { display: block; text-align: center; line-height: 1; }
.sf-w1 {
  display: block;
  font-family: var(--mont);
  font-weight: 800;
  font-size: 1.42rem;
  letter-spacing: 0.02em;
  color: var(--sf-deep);
}
.sf-w2 {
  display: block;
  margin-top: 6px;
  font-family: var(--mont);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--sf-green);
}
@media (max-width: 860px) {
  .sf-inner { grid-template-columns: 1fr; gap: 36px; }
  .sf-lockup { justify-content: flex-start; }
}

/* ============================================================
   The Root Map  (root-map.html + root-map.js)
   Its own small palette: parchment, soil, moss, gold, clay.
   Deliberately warmer than the rest of the site — this page is
   a diagram, not a sales surface.
   ============================================================ */
:root {
  --rm-parchment: #F6F1E7;
  --rm-soil:      #4A3B2C;
  --rm-moss:      #6B7A5A;
  --rm-gold:      #C9A34E;
  --rm-clay:      #B5654B;
}

.rootmap { background: var(--rm-parchment); padding: 78px 0 90px; }
.rm-head { max-width: 62ch; margin-bottom: 18px; }
.rm-head h1 {
  font-family: var(--serif);
  font-size: clamp(2.1rem, 4.4vw, 3.1rem);
  font-weight: 400;
  line-height: 1.12;
  color: var(--rm-soil);
  margin: 10px 0 14px;
}
.rm-head h1 em { font-style: italic; color: var(--rm-moss); }
.rm-head p { color: #5C5140; line-height: 1.65; }

.rm-key { display: flex; gap: 26px; flex-wrap: wrap; margin-top: 20px; }
.rm-key-item {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--sans); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: #6E6250;
}
.rm-key-ico { width: 17px; height: 17px; color: var(--rm-moss); }
.rm-key-bloom { color: var(--rm-gold); }

.rm-figure { margin: 6px 0 0; }
.rm-scroll { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; }
.rm-svg { display: block; width: 100%; min-width: 900px; height: auto; }
.rm-caption {
  margin-top: 10px; font-size: 0.8rem; color: #7A6E5C; font-style: italic;
}

/* branches */
.rm-path { fill: none; stroke: var(--rm-soil); stroke-linecap: round; }
.rm-trunk  { stroke-width: 9;   opacity: 0.92; }
.rm-branch { stroke-width: 4.6; opacity: 0.78; }
.rm-twig   { stroke-width: 2;   opacity: 0.5; }

/* nodes */
.rm-dot { fill: var(--rm-soil); }
.rm-dot--page { fill: var(--rm-moss); }
.rm-glyph--free { color: var(--rm-moss); }
.rm-glyph--paid { color: var(--rm-gold); }
.rm-hit-area { fill: transparent; }
.rm-hit { cursor: pointer; }

.rm-label {
  font-family: var(--serif);
  fill: var(--rm-soil);
  font-size: 20px;
  /* Three long roots cross far more often than six short ones did, so
     every label carries a parchment halo and a hairline root passing
     behind it no longer strikes through the words. */
  paint-order: stroke fill;
  stroke: var(--rm-parchment);
  stroke-width: 5px;
  stroke-linejoin: round;
}
.rm-label--branch {
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  fill: #6E6250;
  /* the middle root's label sits directly over its own root, so it takes
     a wider halo than the leaf labels inherit */
  stroke-width: 7px;
}
.rm-tag {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  fill: var(--rm-clay);
  opacity: 0;
  transition: opacity 0.18s ease;
  paint-order: stroke fill;
  stroke: var(--rm-parchment);
  stroke-width: 5px;
  stroke-linejoin: round;
}

/* trace-the-path-home: light one route, dim the rest */
.rm-svg .rm-path, .rm-svg .rm-node { transition: opacity 0.2s ease; }
.rm-svg.is-tracing .rm-path,
.rm-svg.is-tracing .rm-node { opacity: 0.22; }
.rm-svg.is-tracing .rm-path.is-lit,
.rm-svg.is-tracing .rm-node.is-lit { opacity: 1; }
.rm-svg.is-tracing .rm-path.is-lit { stroke: var(--rm-gold); }
.rm-node--leaf:hover .rm-tag,
.rm-hit:focus-visible .rm-tag { opacity: 1; }
.rm-node--leaf:hover .rm-label--leaf { fill: var(--rm-clay); }
.rm-hit:focus-visible .rm-label--leaf { fill: var(--rm-clay); }
.rm-hit:focus-visible .rm-hit-area {
  fill: rgba(201, 163, 78, 0.16);
  stroke: var(--rm-gold);
  stroke-width: 1.5;
}

/* nodes fade in after the branches finish drawing */
.rm-nodes--pending { opacity: 0; }
#rm-nodes { transition: opacity 520ms ease; }

@media (prefers-reduced-motion: reduce) {
  .rm-nodes--pending { opacity: 1; }
  #rm-nodes, .rm-svg .rm-path, .rm-svg .rm-node, .rm-tag { transition: none; }
}

/* the written-out equivalent */
.rm-index {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 28px 34px;
  margin-top: 58px;
  padding-top: 40px;
  border-top: 1px solid #E2D8C6;
}
.rm-index-head {
  grid-column: 1 / -1;
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #7A6E5C;
  margin: 0;
}
.rm-index-col h3 {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--rm-moss);
  margin-bottom: 12px;
}
.rm-index-col ul { list-style: none; margin: 0; padding: 0; }
.rm-index-col li { margin-bottom: 9px; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.rm-index-col a {
  font-family: var(--serif);
  font-size: 1.02rem;
  color: var(--rm-soil);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.rm-index-col a:hover { color: var(--rm-clay); border-bottom-color: var(--rm-clay); }
.rm-idx-tag {
  font-family: var(--sans);
  font-size: 0.56rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
}
.rm-idx-tag--paid { background: rgba(201,163,78,.18); color: #8A6B1F; }
.rm-idx-tag--free { background: rgba(107,122,90,.16); color: #4E5C3E; }

@media (max-width: 700px) {
  .rootmap { padding: 54px 0 66px; }
  .rm-caption::after { content: " Scroll the diagram sideways to see it all."; }
}

/* the map link rides at the end of the direct-intent bar, quieter than the rest */
.qb-map {
  font-family: var(--sans);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  color: var(--slate);
  opacity: 0.8;
  text-decoration: none;
  padding-left: 22px;
  border-left: 1px solid var(--line);
  transition: opacity 0.15s ease;
}
.qb-map span { color: var(--ocean); font-weight: 600; white-space: nowrap; }
.qb-map:hover { opacity: 1; }
@media (max-width: 860px) {
  .qb-map { padding-left: 0; border-left: 0; }
}

/* ---- Root Map: door branches + tree silhouette (added 2026-08-05) ---- */
/* The three doors read as the main paths: thicker, and in their own colours. */
.rm-branch--door { stroke-width: 6.4; opacity: 0.9; }
.rm-branch--formation { stroke: #4F8A78; }
.rm-branch--marriage  { stroke: #2E93BB; }
.rm-branch--healing   { stroke: #1B568D; }
.rm-label--door { font-size: 15px; fill: var(--rm-soil); letter-spacing: 0.13em; }

/* decorative outline of a whole tree, sitting behind the diagram */
.rm-silhouette {
  fill: none;
  stroke: var(--rm-soil);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.085;
}
.rm-svg.is-tracing .rm-silhouette { opacity: 0.05; }

/* ---- Merch page ---- */
.merch-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.merch-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px 22px;
  min-height: 120px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.merch-kind {
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sage);
}
.merch-line { font-family: var(--serif); font-size: 1.05rem; color: var(--ink); }
@media (max-width: 560px) { .merch-grid { grid-template-columns: 1fr; } }

/* ---- door icons inside the Start Here dropdown (added 2026-08-05) ---- */
.nav-links .nav-menu a { display: flex; align-items: center; gap: 10px; }
.nav-door-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; flex: none; border-radius: 50%; color: var(--di);
}
.nav-door-ico svg { width: 14px; height: 14px; }
.nav-door-ico--formation { --di: #4F8A78; background: rgba(134,173,160,.22); }
.nav-door-ico--marriage  { --di: #2E93BB; background: rgba(110,198,227,.24); }
.nav-door-ico--healing   { --di: #1B568D; background: rgba(27,86,141,.14); }
@media (max-width: 1140px) { .nav-links .nav-menu a { padding-left: 28px; } }

/* About: prose runs full measure now that the third portrait is gone.
   It used to sit inside .split, which supplied the paragraph rhythm. */
.prose-column { max-width: 66ch; }
.prose-column p { margin-bottom: 1.1em; }
.prose-column p:last-child { margin-bottom: 0; }

/* ---- Legal pages (terms, privacy) ----
   Twenty-two numbered sections with nested lists. The headings were
   inline-styled per element when this page had six of them; at this
   length that is unreadable and drifts. */
.legal h2 { font-size: 1.32rem; margin: 40px 0 12px; }
.legal h2:first-child { margin-top: 0; }
.legal p { margin-bottom: 1.05em; }
.legal ul { margin: 0 0 1.15em 1.35em; }
.legal li { margin-bottom: 0.55em; line-height: 1.6; }
.legal ul ul { margin: 0.55em 0 0.2em 1.3em; }
.legal a { text-decoration: underline; }

/* Dreams: the embed folded into the How It Works section */
.dream-look { margin-top: 46px; }
.dream-look .lede { margin-bottom: 20px; }

/* ---- one line, on a screen wide enough to hold it ----
   Two sentences on the Dreams page are meant to be read as a single
   line rather than a paragraph. The measure caps come off and the
   type is sized to fit the wrap; below the breakpoint they wrap
   normally again, because a line that runs off the screen is worse
   than a line that breaks. */
.oneline { max-width: none; }
@media (min-width: 1040px) {
  .oneline { white-space: nowrap; }
  .dream-look .lede.oneline { font-size: 0.95rem; line-height: 1.6; }
}

/* ---- Root Map, inverted: roots below ground, tree above ---- */
.rm-tree { fill: none; stroke: var(--rm-soil); stroke-linecap: round; stroke-linejoin: round; }
.rm-canopy {
  fill: rgba(107,122,90,.13);
  stroke: var(--rm-moss);
  stroke-width: 2.4;
  opacity: .85;
}
.rm-tree-trunk { fill: rgba(74,59,44,.16); stroke: var(--rm-soil); stroke-width: 2.4; opacity: .8; }
.rm-limb { stroke: var(--rm-soil); stroke-width: 2; opacity: .45; }
.rm-fruit { fill: var(--rm-gold); stroke: none; opacity: .55; }

.rm-ground line {
  stroke: var(--rm-soil);
  stroke-width: 1.6;
  opacity: .3;
  stroke-dasharray: 7 9;
}

/* the tree stays put while a root path is being traced */
.rm-svg.is-tracing .rm-tree,
.rm-svg.is-tracing .rm-ground { opacity: .5; }
.rm-tree, .rm-ground { transition: opacity .2s ease; }

/* ---- the grown tree above the ground line (procedural, root-map.js) ---- */
.rm-wood {
  fill: none;
  stroke: var(--rm-soil);
  stroke-linecap: round;
  opacity: .62;
}
.rm-leaf { stroke: none; }
.rm-leaf--0 { fill: #6B7A5A; }
.rm-leaf--1 { fill: #8CA268; }
.rm-leaf--2 { fill: #A9BC86; }

/* ============================================================
   SageFire Collective band (About)
   Borrowed from sagefirecollective.com/the-clapham-sect: ground-dark
   field, ember glow rising from below, serif eyebrow at wide tracking,
   italic kicker, centred lockup, ember CTA. Joy Restored already loads
   Newsreader, so the serif matches without another font request.
   ============================================================ */
:root {
  --sf-ground:         #132029;
  --sf-ember:          #C4611E;
  --sf-firelight:      #E7AC4B;
  --sf-firelight-soft: #F0C778;
  --sf-ink-faint:      #7F8A87;
  --sf-rule:           rgba(234, 223, 200, .14);
}

.sf-close {
  position: relative;
  overflow: hidden;
  text-align: center;
  padding: 116px 0 124px;
  border-top: 1px solid var(--sf-rule);
  border-bottom: 1px solid var(--sf-rule);
  background:
    radial-gradient(110% 80% at 50% 130%, rgba(196, 97, 30, .20) 0%, rgba(196, 97, 30, 0) 58%),
    linear-gradient(180deg, var(--sf-ground) 0%, #0F1A21 100%);
}
.sf-eyebrow {
  display: inline-block;
  font-family: var(--serif);
  font-size: .74rem;
  letter-spacing: .34em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--sf-firelight);
  margin-bottom: 1.4rem;
}
.sf-close h2 {
  font-family: var(--serif);
  font-weight: 300;
  color: #F4EFE4;
  font-size: clamp(1.9rem, 3.6vw, 2.9rem);
  line-height: 1.16;
  max-width: 20ch;
  margin: 0 auto;
}
.sf-body {
  max-width: 58ch;
  margin: 1.8rem auto 0;
  color: #C9CFC9;
  line-height: 1.72;
}
.sf-pull {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.35rem, 2.6vw, 1.95rem);
  line-height: 1.36;
  color: var(--sf-firelight-soft);
  margin: 2.2rem auto 2.6rem;
  /* 36ch, not 34ch: at 34ch the kicker broke three ways and left
     "it." alone on the last line. 36ch sets it as two even lines. */
  max-width: 36ch;
}
.sf-brand { margin-bottom: 2.1rem; }
/* real SageFire marks; the Clapham page sets these at 54px / 32px */
.sf-mark-img   { width: 54px; height: auto; display: block; margin: 0 auto 16px; opacity: .95; }
.sf-lockup-img { height: 32px; width: auto; display: block; margin: 0 auto; }
.sf-wordmark { display: block; line-height: 1; }
.sf-w1 {
  display: block;
  font-family: var(--mont);
  font-weight: 700;
  font-size: 1.24rem;
  letter-spacing: .06em;
  color: #F4EFE4;
}
.sf-w2 {
  display: block;
  margin-top: 7px;
  font-family: var(--mont);
  font-weight: 500;
  font-size: .66rem;
  letter-spacing: .36em;
  text-transform: uppercase;
  color: var(--sf-firelight);
}
.sf-cta {
  display: inline-flex;
  align-items: center;
  font-family: var(--serif);
  font-size: 1rem;
  letter-spacing: .02em;
  color: var(--sf-ground);
  background: var(--sf-firelight);
  padding: 14px 30px;
  border-radius: 999px;
  text-decoration: none;
  transition: background .3s ease, transform .3s ease, box-shadow .3s ease;
  /* Ember halo, lifted from the Clapham Sect page's .cta so the button
     sits in the same firelight as the rest of the band. The blur is
     larger than the spread is negative, so it reads as a glow under
     the pill rather than a drop shadow behind it. */
  box-shadow: 0 18px 40px -18px rgba(231, 172, 75, .6);
}
.sf-cta:hover {
  background: var(--sf-firelight-soft);
  transform: translateY(-2px);
  box-shadow: 0 22px 46px -18px rgba(231, 172, 75, .75);
}
.sf-cta:focus-visible { outline: 2px solid var(--sf-firelight-soft); outline-offset: 4px; }
.sf-emberline {
  margin-top: 2.8rem;
  font-size: .74rem;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--sf-ink-faint);
}
@media (max-width: 700px) { .sf-close { padding: 82px 0 88px; } }

/* The bar now carries two peer links rather than a label plus a list. */
.quick-bar-inner { justify-content: center; gap: 10px 30px; }
.qb-map + .qb-map { padding-left: 30px; border-left: 1px solid var(--line); }
@media (max-width: 860px) {
  .qb-map + .qb-map { padding-left: 0; border-left: 0; }
}

/* ============================================================
   Hero-treatment cards (Coaching, Speaking)
   Same gradient field and white type as the hero, so the card
   grid reads as an extension of it rather than a light panel.
   ============================================================ */
.card--hero {
  position: relative;
  overflow: hidden;
  background: var(--grad);
  color: var(--white);
  border: 0;
  box-shadow: var(--shadow-3-dark);
}
/* the hero's faint ring texture, so the fields are not flat */
.card--hero::before {
  content: "";
  position: absolute;
  right: -70px;
  top: -90px;
  width: 260px;
  height: 260px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow:
    0 0 0 34px rgba(255, 255, 255, 0.055),
    0 0 0 70px rgba(255, 255, 255, 0.035);
  pointer-events: none;
}
.card--hero > * { position: relative; }
.card--hero h3 { color: var(--white); }
.card--hero p { color: rgba(255, 255, 255, 0.85); }
.card--hero .label { color: rgba(255, 255, 255, 0.72); }
.card--hero a:not(.btn) { color: var(--white); text-decoration: underline; }
.card--hero .btn--primary { background: var(--white); color: var(--deep); }
.card--hero .btn--primary:hover { background: var(--ivory); color: var(--deep); }

/* .btn--ghost is ocean-on-transparent, which disappears on a hero card.
   Inside one, it takes the light treatment instead. */
.card--hero .btn--ghost {
  border-color: rgba(255, 255, 255, 0.55);
  color: var(--white);
}
.card--hero .btn--ghost:hover {
  border-color: var(--white);
  background: rgba(255, 255, 255, 0.10);
  color: var(--white);
}

/* ---- textlinks inside hero cards need the light treatment too ---- */
.card--hero .textlink { color: #CFE7DD; }
.card--hero .textlink:hover { color: var(--white); }
.card--hero .label--sage { color: #BFE6D6; }

/* ---- Item 4: the two links under the hero read larger ---- */
.qb-map { font-size: 0.92rem; letter-spacing: 0.01em; }
.qb-map span { font-weight: 700; }
.quick-bar-inner { padding: 17px 28px; }

/* ---- Item 5: the colour wordmark introduces the three doors ---- */
.doors-wordmark { display: flex; justify-content: center; margin: 0 0 42px; }
.doors-wordmark img { width: min(320px, 62vw); height: auto; display: block; }
@media (max-width: 640px) { .doors-wordmark { margin-bottom: 30px; } }

/* ---- header monogram: larger, and genuinely hanging below the bar ----
   The header sizes to its content, so simply growing the logo grew the
   header with it and nothing ever overhung. A negative bottom margin keeps
   the extra height out of the layout, so the badge spills past the edge. */
.site-header { overflow: visible; }
.site-header .brand-logo { position: relative; z-index: 3; align-self: flex-start; }
.site-header .brand-mono {
  height: 112px; width: 112px;
  margin-bottom: -56px;
  transform: none;
}
@media (max-width: 900px) {
  .site-header .brand-mono { height: 84px; width: 84px; margin-bottom: -40px; }
}
@media (max-width: 600px) {
  .site-header .brand-mono { height: 68px; width: 68px; margin-bottom: -30px; }
}

/* ---- Item 8: "Free" and price type reads larger everywhere ---- */
.door-free { font-size: 0.72rem; padding: 12px 20px; }
.door-free b { font-size: 0.70rem; letter-spacing: 0.16em; }
.price, .cal-price, .ws-price, .pb-price { font-size: 1.28em; }
.offer-chip { font-size: 0.78rem; }

/* ---- the three-doors heading and the wordmark share one line ---- */
.doors-head {
  max-width: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
}
.doors-head-copy { max-width: 62ch; }
.doors-head .doors-wordmark { margin: 0; flex: 0 0 auto; justify-content: flex-end; }
.doors-head .doors-wordmark img { width: min(300px, 26vw); }
@media (max-width: 900px) {
  .doors-head { flex-direction: column; align-items: flex-start; gap: 26px; }
  .doors-head .doors-wordmark { justify-content: flex-start; }
  .doors-head .doors-wordmark img { width: min(260px, 58vw); }
}

/* ---- free chips: the fixed 176px clipped the longer labels ---- */
.door-row .door-free { flex: 0 0 208px; width: 208px; }
@media (max-width: 560px) { .door-row .door-free { flex: 0 0 auto; width: auto; } }

/* ---- Merch: real product cards, mirroring the Printful store ---- */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(288px, 1fr));
  gap: 22px;
  margin-top: 8px;
}
.product-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  box-shadow: var(--shadow);
  transition: transform .25s ease, box-shadow .25s ease;
}
.product-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-3); }
.product-shot {
  aspect-ratio: 1 / 1;
  display: grid;
  place-items: center;
  background: var(--sage-tint);
}
.product-shot img { width: 84px; height: 84px; border-radius: 50%; opacity: .55; }
.product-body { padding: 26px 26px 28px; display: flex; flex-direction: column; flex: 1; }
.product-kind {
  font-family: var(--sans); font-size: .64rem; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; color: var(--sage);
}
.product-card h3 { font-size: 1.32rem; margin: 8px 0 10px; }
.product-card p { font-size: .95rem; color: #46555E; flex-grow: 1; margin-bottom: 16px; }
.product-meta {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px; margin-bottom: 14px;
}
.product-price {
  font-family: var(--mont); font-weight: 700; font-size: 1.18rem; color: var(--ocean);
}
.product-sizes {
  font-family: var(--sans); font-size: .78rem; letter-spacing: .08em; color: var(--slate);
}
.shop-all { margin-top: 40px; }
.shop-all .note { margin-top: 12px; }

/* a real product photograph fills its tile, unlike the monogram placeholder */
.product-shot--photo { background: var(--white); padding: 0; }
.product-shot--photo img {
  width: 100%; height: 100%; border-radius: 0; opacity: 1; object-fit: cover;
}

/* ============================================================
   PRODUCT LADDER, 2026-08-05
   A spec line under each rung's title, and the six-rung layout
   the formation paths now need.
   ============================================================ */

/* Cadence, format, prerequisite. The one line a buyer scans for
   before they read anything else, so it sits above the prose. */
.ps-meta {
  display: block;
  font-family: var(--mont);
  font-size: 0.58rem; font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase;
  line-height: 1.55;
  color: #5B6B76;
  margin: -2px 0 10px;
}
/* Free and assessment rungs are light cards; paid and application
   rungs both carry the deep gradient, so their spec line has to turn
   over with the rest of the type on them. */
.path-step.is-free  .ps-meta { color: #3D6B5C; }
.path-step.is-paid  .ps-meta,
.path-step.is-apply .ps-meta { color: rgba(255, 255, 255, 0.82); }

/* Six rungs have to hold one row, so the cards give up padding and
   a little type rather than wrapping to a second line.

   They also go vertical earlier than the shorter ladders do. Four
   rungs are still comfortable at 900px; six are down to about 128px
   a card by then, which is narrower than the titles want. So the
   six-rung ladders switch to the stacked rail at 1080px instead,
   reusing the same connector geometry as the 900px rule below. */
@media (max-width: 1079px) {
  /* the six-column track is desktop only; stacked, one column */
  .path--six { grid-template-columns: minmax(0, 1fr); }
  .path--six { grid-auto-flow: row; grid-auto-columns: auto; gap: 16px; }
  .path--six .path-step { padding-top: 0; padding-left: 34px; }
  .path--six .path-step::before { left: 7px; right: auto; top: 0; bottom: 50%; width: 2px; height: auto; }
  .path--six .path-step::after  { left: 7px; right: auto; top: 50%; bottom: 0; width: 2px; height: auto; }
  .path--six .ps-dot { top: 50%; left: 0; margin-left: 0; margin-top: -8px; }
  /* stacked: no flag row to reserve */
  .path--six .ps-card { padding-top: 24px; }
}
@media (min-width: 1080px) {
  /* An explicit six-column track rather than one column per rung, so a
     ladder with five rungs still gets six-rung cards and simply leaves
     the last column empty (the marriage ladder on products.html). */
  .path--six { grid-auto-flow: row; grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .path--six { gap: 13px; }
  /* 44px top reserves the six-rung flag (32px tall) on every card. */
  .path--six .ps-card { padding: 44px 16px 17px; }
  .path--six .ps-card h3 { font-size: 0.99rem; line-height: 1.26; margin-bottom: 7px; }
  .path--six .ps-card p { font-size: 0.845rem; line-height: 1.5; }
  .path--six .ps-chip { font-size: 0.53rem; letter-spacing: 0.13em; padding: 4px 9px; margin-bottom: 11px; }
  .path--six .ps-meta { font-size: 0.535rem; letter-spacing: 0.06em; margin-bottom: 9px; }
  .path--six .ps-go { font-size: 0.53rem; letter-spacing: 0.11em; margin-top: 13px; }
  .path--six .ps-live { font-size: 0.53rem; }
}

/* ============================================================
   Speaking topics, on shared rows  (speaking.html)

   Every tile holds the same four lines: eyebrow, title, how many
   sessions, blurb. The titles run from three words to seven, so a
   tile with a two-line title used to push its session count and its
   blurb a line lower than the tiles either side of it, and a row of
   six read as six different formats.

   Subgrid fixes it at the source rather than by guessing a
   min-height: each tile hands its four rows back to the grid, so
   every row is as tall as the tallest tile in that band and all
   four lines land on one baseline across the row. Where subgrid is
   missing, the tiles fall back to a reserved two-line title, which
   is right for all but the longest of them.
   ============================================================ */
.grid-3--topics > .card h3 { min-height: 2.5em; }
@supports (grid-template-rows: subgrid) {
  .grid-3--topics > .card {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 4;
    align-content: start;
    row-gap: 0;
  }
  /* handed back to the grid, so the reserved height is not needed */
  .grid-3--topics > .card h3 { min-height: 0; }
  /* ::before is the ring texture, absolutely positioned: keep it out
     of the row count or it takes a row of its own */
  .grid-3--topics > .card::before { grid-area: 1 / 1; }
}
@media (max-width: 900px) {
  /* one column: nothing to align against, so the rows come apart */
  .grid-3--topics > .card { display: block; }
  .grid-3--topics > .card h3 { min-height: 0; }
}

/* ---- Speaking: how long each topic runs, and the lead time ---- */
.talk-length {
  display: inline-block;
  font-family: var(--mont);
  font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.17em; text-transform: uppercase;
  color: var(--deep);
  background: var(--sage-tint);
  border-radius: 999px; padding: 5px 12px;
  margin: 0 0 12px;
}
/* The lead time is a condition of booking, not a footnote, so it
   carries a rule rather than sitting in the same grey as the rest. */
.invite-lead {
  border-left: 3px solid var(--sky);
  padding-left: 14px;
}

/* ---- Forms sitting on a deep card ----
   card--hero paints the deep gradient, but form labels inherit the
   same deep ink they use on paper, so on that ground they vanish.
   Applies to the speaking invitation and The Turning application. */
.card--hero .waitlist-form label,
.card--hero .form-grid label,
.card--hero form label {
  color: rgba(255, 255, 255, 0.92);
}
.card--hero .waitlist-form .form-success { color: #fff; }

/* ============================================================
   FOOTER, consolidated 2026-08-05
   It ran 1003px on desktop and 1392px on a phone, taller than the
   screen in both cases, mostly because fifteen Explore links were
   stacked in a single column. The list now flows in two columns and
   the vertical rhythm is tightened throughout. Markup is untouched:
   the footer is duplicated across 42 pages and has no generator, so
   every change here is a stylesheet change on purpose.
   ============================================================ */
.site-footer { padding: 44px 0 24px; }

/* Column widths only above the 900px breakpoint: below it the older
   rules collapse the grid to two columns and then one, and an
   unscoped declaration here would win on source order and hold the
   three-column track all the way down to a phone. */
@media (min-width: 901px) {
  .footer-grid { grid-template-columns: 1.1fr 1.15fr; }
}
.footer-grid { gap: 40px; margin-bottom: 26px; }
.footer-mono { width: 48px; height: 48px; }
.site-footer .tagline { font-size: 1.04rem; margin: 12px 0 8px; }
.site-footer h4 { margin-bottom: 13px; }

/* Two columns turn fifteen rows into eight. break-inside keeps a
   wrapped label like "Dream Interpretation" from splitting across
   the column gap. */
.site-footer .footer-grid ul {
  column-count: 2;
  column-gap: 24px;
}
.site-footer .footer-grid li {
  margin-bottom: 8px;
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
}

.footer-signup .signup-tag { margin-bottom: 12px; }
.footer-mid { padding-top: 18px; }
.footer-base { margin-top: 16px; }

@media (max-width: 700px) {
  .site-footer { padding: 34px 0 20px; }
  .footer-grid { gap: 28px; margin-bottom: 20px; }
}

/* ============================================================
   FOOTER, condensed again 2026-08-08

   The 08-05 pass fixed the fifteen-row Explore column but left the
   footer generous everywhere else: 44px of top padding, a 58px
   monogram, 1.04rem type and four separate stacked bands. On a page
   like /products it was still the tallest thing after the content.

   This tightens the type scale, the paddings and the gaps together
   rather than any one of them hard, so the proportions hold. Still
   CSS only: the footer is hand-duplicated across 42 pages.
   ============================================================ */
.site-footer { padding: 34px 0 16px; font-size: 0.9rem; }
.footer-grid { gap: 30px; margin-bottom: 18px; }
.footer-mono { width: 40px; height: 40px; }
.site-footer .tagline { font-size: 0.94rem; margin: 9px 0 6px; line-height: 1.45; }
.site-footer h4 { font-size: 0.68rem; letter-spacing: 0.2em; margin-bottom: 9px; }
.site-footer a { font-size: 0.9rem; }
.site-footer .footer-grid li { margin-bottom: 5px; }
.footer-signup .signup-tag { font-size: 0.94rem; margin-bottom: 9px; }
.footer-signup .btn { padding: 11px 18px; font-size: 0.7rem; }
.footer-signup input { padding: 11px 13px; font-size: 0.92rem; }
.footer-mid { padding-top: 13px; gap: 16px; }
.social-icon { width: 33px; height: 33px; }
.social-icon svg { width: 15px; height: 15px; }
.sagefire-badge img { width: 74px !important; }
.footer-base { margin-top: 11px; font-size: 0.79rem; }
.footer-base a { font-size: 0.79rem; }

/* ---- the crisis line on a small screen ----
   It is the one sentence in the footer that has to be read by
   someone who is not browsing. Below the width that can hold it
   beside the copyright, .footer-legal has already wrapped it onto
   its own row, so all it needs here is the smaller type. It is
   never allowed to run off the screen, because a crisis number
   doing that is the one failure that actually matters. */
.footer-disclaimer { font-size: 0.79rem; }

/* ============================================================
   COACHING: intensives grouped by door
   Each group takes its door's ink for the rule, the icon chip and
   the heading, so the three paths are told apart at a glance
   rather than by reading the titles.
   ============================================================ */
.ip-group { margin-bottom: 46px; }
.ip-group:last-of-type { margin-bottom: 0; }

.ip-head {
  display: flex; align-items: center; gap: 14px;
  padding-bottom: 12px; margin-bottom: 22px;
  border-bottom: 2px solid currentColor;   /* door ink, via .door--* */
}
.ip-head h3 {
  font-size: 1.42rem; margin: 0; color: inherit; flex-grow: 1;
}
.ip-head .textlink { flex-shrink: 0; font-size: 0.82rem; }
.ip-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
  background: currentColor;
}
.ip-ico svg { width: 19px; height: 19px; color: #fff; }

/* The tiles themselves stay neutral. The group already carries the
   colour, and tinting every card as well turns the section into
   three blocks of flat colour. */
.ip-card { display: flex; flex-direction: column; }
.ip-card h4 {
  font-family: var(--serif); font-weight: 400;
  font-size: 1.12rem; line-height: 1.25;
  margin: 0 0 7px; color: var(--ink);
}
.ip-card p { font-size: 0.92rem; color: #46555E; margin: 0 0 14px; }
.ip-card p:last-of-type { flex-grow: 1; }
.ip-chip {
  align-self: flex-start;
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  background: var(--ocean); color: #fff;
  padding: 5px 11px; border-radius: 999px; margin-bottom: 12px;
}
/* Scoped through .ip-card so it outranks `.ip-card p` above, which
   would otherwise hand the spec line the 0.92rem body size and let
   it shout over the title it is supposed to sit under. */
.ip-card p.ip-meta {
  font-family: var(--mont); font-size: 0.575rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: #5B6B76; line-height: 1.55;
  margin: 0 0 10px;
}
@media (max-width: 700px) {
  .ip-head { flex-wrap: wrap; gap: 10px; }
  .ip-head h3 { font-size: 1.24rem; }
}

/* ---- Calendar: the free / paid pair beside the door filters ----
   The door buttons carry their door's colour. Cost is not a door, so
   these take the neutral slate ink and a divider keeps the two
   filter families from reading as one row of six. */
.cal-filter-sep {
  width: 1px; align-self: stretch; margin: 0 4px;
  background: var(--line);
}
.cal-filter--cost { color: var(--slate); }
.cal-filter--cost[aria-pressed="true"] {
  background: var(--slate); border-color: var(--slate); color: #fff;
}
@media (max-width: 620px) {
  .cal-filter-sep { display: none; }
}

/* ============================================================
   LEAD GATE, the name + email asked before anything free opens
   Sits inside .assess-card and on resource pages, so it takes a
   quiet inset panel rather than a second card outline.
   ============================================================ */
.lead-gate {
  background: var(--sage-tint);
  border: 1px solid #CFDFD8;
  border-radius: var(--radius);
  padding: 24px 22px 22px;
  margin: 22px 0 4px;
}
.lg-title {
  font-family: var(--serif); font-weight: 400;
  font-size: 1.24rem; line-height: 1.25;
  margin: 0 0 8px; color: var(--ink);
}
.lg-note {
  font-size: 0.9rem; line-height: 1.6;
  color: #46555E; margin: 0 0 18px;
}
.lg-row {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 14px; margin-bottom: 18px;
}
.lg-row label {
  display: block;
  font-family: var(--mont); font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--deep); margin-bottom: 7px;
}
.lg-row input {
  width: 100%; box-sizing: border-box;
  padding: 13px 14px; border-radius: var(--radius);
  border: 1px solid rgba(54, 91, 109, 0.22);
  background: var(--white); color: var(--ink);
  font-family: var(--sans); font-size: 0.98rem;
}
.lg-row input:focus {
  outline: none; border-color: var(--sage);
  box-shadow: 0 0 0 3px rgba(134, 173, 160, 0.28);
}
.lg-err {
  margin: 12px 0 0; font-size: 0.9rem; color: #B4453B;
}
@media (max-width: 560px) {
  .lg-row { grid-template-columns: 1fr; }
}

/* ---- the gate, with the scorecard it buys sitting next to it ----
   The picture answers "what do I get for my email" before the email is
   asked for. When the gate opens it hides itself, the column collapses
   and the scorecard centres under the intro on its own. */
.gate-split {
  display: grid;
  grid-template-columns: 1fr 296px;
  gap: 30px;
  align-items: start;
  margin-top: 22px;
}
/* the gate is in a column now, not the full card: two inputs abreast in
   that width leaves each of them too narrow to read what you typed */
.gate-split .lg-row { grid-template-columns: 1fr; gap: 12px; }
/* once the gate has opened it hides itself, so the picture takes the
   middle instead of leaving an empty column beside it */
.gate-split:has(> .gate-split-form > [hidden]) {
  grid-template-columns: 1fr;
  justify-items: center;
}
.gate-split .lead-gate { margin-top: 0; }
.scorecard-peek { margin: 0; width: 100%; max-width: 320px; }
.scorecard-peek svg {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 10px 26px rgba(27, 86, 141, 0.13));
}
.scorecard-peek figcaption {
  margin-top: 12px;
  font-size: 0.82rem;
  line-height: 1.55;
  color: #7C888E;
  text-align: center;
}
.scorecard-peek .sp-eyebrow {
  font-family: var(--mont); font-size: 10px; font-weight: 700;
  letter-spacing: 0.2em; fill: var(--sage);
}
.scorecard-peek .sp-pct {
  font-family: var(--serif); font-size: 30px; fill: var(--ink);
}
.scorecard-peek .sp-small {
  font-family: var(--sans); font-size: 11px; fill: #7C888E;
}
.scorecard-peek .sp-band {
  font-family: var(--serif); font-size: 20px; font-style: italic; fill: var(--ocean);
}
.scorecard-peek .sp-rows text {
  font-family: var(--sans); font-size: 12px; fill: #46555E;
}
@media (max-width: 780px) {
  .gate-split { grid-template-columns: 1fr; gap: 26px; }
  .scorecard-peek { max-width: 320px; margin: 0 auto; }
}


/* ============================================================
   ALL PRODUCTS (products.html), three ladders on one page.

   The rungs themselves are the SAME component the three door pages
   use (.path / .path-step / .ps-*), markup and all, so a product
   tile looks identical wherever a visitor meets it. Nothing below
   restyles a rung.

   What this file adds is the door heading that sits above each
   ladder, and the door's colour on the two pieces that are
   otherwise generic on every path: the rail the figure walks, and
   the ring that lights under the rung it is standing on. Colour
   comes from the same --door-* tokens the nav and the calendar
   filters use, so a section here reads as the door a visitor met
   on the homepage.

   Each section sets --dr / --dr-ink / --dr-wash once and everything
   inside inherits them. Adding a fourth door = one more .od--* line.
   ============================================================ */

.od { --dr: var(--door-cross); --dr-ink: var(--door-cross-ink); --dr-wash: rgba(54, 91, 109, 0.10); }
.od--formation { --dr: var(--door-formation); --dr-ink: var(--door-formation-ink); --dr-wash: rgba(134, 173, 160, 0.22); }
.od--marriage  { --dr: var(--door-marriage);  --dr-ink: var(--door-marriage-ink);  --dr-wash: rgba(110, 198, 227, 0.24); }
.od--healing   { --dr: var(--door-healing);   --dr-ink: var(--door-healing-ink);   --dr-wash: rgba(27, 86, 141, 0.14); }

.od + .od { margin-top: 86px; }

/* ---- door header ---- */
.od-head {
  display: flex; align-items: flex-start; gap: 20px;
  padding-bottom: 22px; margin-bottom: 30px;
  border-bottom: 2px solid var(--dr);
}
.od-ico {
  flex: none; width: 54px; height: 54px; border-radius: 50%;
  display: grid; place-items: center;
  /* The same mark the home page draws: the door's ink colour as a
     solid circle with a white icon on it. This used to be a pale wash
     circle with a tinted icon, which made the three doors here look
     like a different set of icons from the three in the hero. */
  color: #fff; background: var(--dr-ink);
}
.od-ico svg { width: 27px; height: 27px; }
.od-titles { flex: 1 1 auto; min-width: 0; }
.od-label {
  display: block;
  font-family: var(--mont); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--dr-ink); margin-bottom: 7px;
}
.od-titles h2 {
  font-size: 1.72rem; line-height: 1.2; margin: 0 0 6px; color: var(--ink);
}
.od-titles p { font-size: 0.98rem; color: #46555E; margin: 0; }
.od-more {
  flex: none; align-self: center;
  font-family: var(--mont); font-size: 0.58rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--dr-ink); text-decoration: none;
  border: 1px solid currentColor; border-radius: 999px;
  padding: 9px 17px; white-space: nowrap;
  transition: background .25s ease, color .25s ease;
}
.od-more:hover { background: var(--dr-ink); color: #fff; }

/* ---- the walker takes the door's colour ----
   The rail and the lit ring are the only generic-sage pieces of a
   path; tinting them is what makes three ladders on one page read
   as three different doors. The rungs are left alone on purpose. */
.od .pw-line { background: var(--dr); opacity: .55; }
.od .path-step.is-lit .ps-dot { box-shadow: 0 0 0 6px var(--dr-wash); }
.od .path-step.is-lit .ps-card { border-color: var(--dr); }

/* ---- jump row under the hero ---- */
.od-jump { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
.od-jump a {
  --dr-ink: var(--door-cross-ink); --dr-wash: rgba(54, 91, 109, 0.10);
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--mont); font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--dr-ink); text-decoration: none;
  background: var(--white); border: 1px solid currentColor;
  border-radius: 999px; padding: 10px 18px 10px 12px;
  transition: background .25s ease, color .25s ease;
}
.od-jump a.od--formation { --dr-ink: var(--door-formation-ink); --dr-wash: rgba(134, 173, 160, 0.22); }
.od-jump a.od--marriage  { --dr-ink: var(--door-marriage-ink);  --dr-wash: rgba(110, 198, 227, 0.24); }
.od-jump a.od--healing   { --dr-ink: var(--door-healing-ink);   --dr-wash: rgba(27, 86, 141, 0.14); }
.od-jump .od-ico { width: 26px; height: 26px; }
.od-jump .od-ico svg { width: 15px; height: 15px; }
.od-jump a:hover { background: var(--dr-ink); color: #fff; }
.od-jump a:hover .od-ico { background: rgba(255, 255, 255, 0.22); color: #fff; }

/* Anchors have to clear the sticky header when jumped to. */
.od[id] { scroll-margin-top: 96px; }

@media (max-width: 760px) {
  .od-head { flex-wrap: wrap; gap: 14px; }
  .od-more { align-self: flex-start; }
  .od-titles h2 { font-size: 1.42rem; }
}
@media (max-width: 560px) {
  .od + .od { margin-top: 60px; }
}

/* ============================================================
   ROUND 2 TWEAKS (2026-08-07)
   ============================================================ */

/* ---- 2: "Start free. Go deeper when you're ready." on one line ----
   The second clause is one thought and read as broken when the line
   split through it. 62ch of body text is narrower than the same line
   set at h2 size, so the heading needed the extra measure. Wrapping
   comes back on small screens, where one line is not possible. */
.path-top--solo .section-head { max-width: 84ch; }
.path-top--solo .section-head h2 em { white-space: nowrap; }
@media (max-width: 720px) {
  .path-top--solo .section-head h2 em { white-space: normal; }
}

/* ---- 3: the quick bar carries real weight ----
   "See the FREE Workshop Calendar" is the busiest link on the home
   page and was set smaller than the body copy around it. Both links
   move together so the bar stays one row of equals. */
.qb-map { font-size: 1.08rem; }
.qb-map span { font-weight: 700; }
@media (max-width: 640px) { .qb-map { font-size: 1rem; } }

/* ---- 5: podcast tiles ----
   The episode title is the thing someone scans for, so it leads now
   that the "Episode" line is gone. The mic sits opposite the artwork
   and gives the card a podcast signature at a glance. */
.pod-card { position: relative; }
.pod-card h3 {
  font-size: 1.62rem; line-height: 1.16; margin: 10px 0 10px;
  font-family: var(--serif); font-weight: 400; letter-spacing: -0.005em;
}

/* ---- The row does not stagger ----
   Episode titles run from four words to twelve and the blurbs come
   out of the feed at whatever length the feed sends, so every card
   used to start its blurb, and land its Listen, at its own height.

   Both blocks are clamped AND given the matching minimum, which is
   the pair that does the work: the clamp stops a long one growing,
   the minimum stops a short one shrinking, and the two together mean
   every card in the strip has the same shape. Listen is pushed to the
   floor on top of that, so a card that somehow still differs cannot
   drag its button up with it. */
.pod-card h3 {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
  min-height: calc(3 * 1.16em);
}
.pod-card p {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
  line-height: 1.55;
  min-height: calc(3 * 1.55em);
}

/* Listen as a ghost button rather than a text link: it is the one
   thing on the card you press, and on a card that is itself a link it
   needs to look like the target rather than like more prose. A span,
   not a button, because the whole card is already an <a> and nesting
   a control inside a link is invalid and unusable with a keyboard. */
.pod-listen {
  display: inline-block; margin-top: auto;
  font-family: var(--mont); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ocean);
  border: 1.7px solid var(--ocean); border-radius: 999px;
  padding: 10px 22px;
  transition: background .18s ease, color .18s ease;
}
.pod-card:hover .pod-listen { background: var(--ocean); color: var(--white); }
.pod-mic {
  position: absolute; top: 26px; right: 24px;
  width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--ocean); background: rgba(110, 198, 227, 0.22);
  transition: background .25s ease, color .25s ease;
}
.pod-mic svg { width: 20px; height: 20px; }
.pod-card:hover .pod-mic { background: var(--ocean); color: #fff; }
/* The art tile and the mic share a row, so the title clears both. */
.pod-card .pod-art { margin-bottom: 12px; }
@media (max-width: 640px) {
  .pod-card h3 { font-size: 1.42rem; }
  .pod-mic { top: 22px; right: 20px; width: 34px; height: 34px; }
}

/* ---- 4: two calendars ----
   calendar.html is free workshops; intensives.html is the paid group
   intensives, where colour means WHICH INTENSIVE rather than which
   door. Two intensives can sit behind the same door and still have to
   be told apart on the grid, so the colour travels on an inline --pc
   set from cohort-data.json. .cal-event already draws its left border
   from currentColor, so the grid needed nothing new. */
.cal-crosslink {
  font-size: 0.95rem; color: #5B6B76;
  margin: -18px 0 30px;
}
.cal-filter--prog {
  color: var(--pc); border-color: currentColor;
}
.cal-filter--prog[aria-pressed="true"] {
  background: var(--pc); border-color: var(--pc); color: #fff;
}
.cal-swatch {
  width: 11px; height: 11px; border-radius: 3px; flex: none;
  background: var(--pc); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.cal-filter--prog[aria-pressed="true"] .cal-swatch {
  background: #fff; box-shadow: none;
}

/* ============================================================
   CALENDARS, round 2026-08-07

   Three things both calendars were missing, and one that was there
   but invisible:

     .cal-ask       which door are you in, asked before the grid
     .cal-howto     that an entry is a link you can act on
     .is-nudge      a ring on the Month/List switch until it is used
     .cal-swap      the other calendar, as a card rather than a caption
   ============================================================ */

/* ---- the chooser ----
   Dark on purpose: this is the first question the page asks, and on a
   page that is otherwise a pale grid it needs to read as the thing you
   answer before anything else. Same deep-sea gradient the Quick Chat
   block wears, so it is a known surface rather than a one-off. */
.cal-ask {
  background: linear-gradient(158deg, #2C5766 0%, #3F7A72 100%);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--radius);
  padding: 24px 26px 26px;
  margin: 0 0 26px;
}
.cal-ask-q {
  font-family: var(--serif);
  font-size: 1.3rem; line-height: 1.25;
  color: var(--white); margin: 0 0 16px;
}
.cal-ask-row { display: flex; flex-wrap: wrap; gap: 10px; }
.cal-ask-btn {
  display: inline-flex; align-items: center; gap: 10px; cursor: pointer;
  font-family: var(--mont); font-size: 0.66rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  padding: 12px 20px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.08);
  color: #EFEFEC;
  transition: border-color .2s ease, background .2s ease, color .2s ease, box-shadow .2s ease;
}
.cal-ask-btn:hover {
  border-color: #fff; background: rgba(255, 255, 255, 0.18); box-shadow: none;
}
.cal-ask-ico { display: inline-flex; }
.cal-ask-ico .door-icon { width: 19px; height: 19px; }
/* Each button carries its door's colour in --dc rather than in
   `color`. On this dark ground the door inks are too dark to sit on
   directly, so the pressed state inverts instead: white pill, door
   colour for the label and the icon (which draws in currentColor).
   That keeps the door identity and stays legible in both states. */
.cal-ask-btn { --dc: var(--deep); }
.cal-ask-btn.door--formation { --dc: var(--door-formation-ink); }
.cal-ask-btn.door--marriage  { --dc: var(--door-marriage-ink); }
.cal-ask-btn.door--healing   { --dc: var(--door-healing-ink); }
.cal-ask-btn[aria-pressed="true"] {
  background: var(--white); border-color: var(--white); color: var(--dc);
  box-shadow: var(--shadow-1-dark);
}
.cal-ask.is-answered .cal-ask-btn[aria-pressed="false"] { opacity: 0.62; }

/* ---- click a date to register, and the view switch beside it ----
   One bar carries both of the things a visitor needs before touching
   the grid: that a date is a link, and that there is a list. The
   switch sits hard right inside the same pill rather than up in the
   filter row, where it was being read as another filter. */
.cal-howto {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: rgba(110, 198, 227, 0.13);
  border: 1px solid rgba(110, 198, 227, 0.45);
  border-radius: 999px;
  padding: 10px 12px 10px 22px;
  margin: 0 0 24px;
  font-size: 0.98rem; color: var(--deep);
}
.cal-howto-say {
  margin: 0; flex: 1 1 auto; min-width: 0;
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}
.cal-howto strong { font-weight: 600; color: var(--ink); }
.cal-howto-or { color: #5B6B76; font-size: 0.9rem; }
/* Inside the pill the switch takes a white ground, so it still reads
   as a control rather than dissolving into the tinted bar. */
.cal-howto .cal-viewswitch {
  margin-left: 0; flex: none;
  background: var(--white);
  border-radius: 999px;
  padding: 4px 6px 4px 12px;
  box-shadow: var(--shadow-0);
}
.cal-howto .cal-viewswitch button { border-color: transparent; background: transparent; }
.cal-howto .cal-viewswitch button[aria-pressed="true"] {
  background: var(--ocean); border-color: var(--ocean); color: var(--white);
}
@media (max-width: 640px) {
  .cal-howto { border-radius: var(--radius); padding: 14px 18px; }
  .cal-howto .cal-viewswitch { width: 100%; justify-content: center; }
}
/* A tap mark that keeps pulsing, so the line is noticed rather than
   read past. It is the one instruction on the page that changes
   whether anyone books anything. */
.cal-howto-tap {
  position: relative; flex: none;
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--ocean);
}
.cal-howto-tap::before,
.cal-howto-tap::after {
  content: ""; position: absolute; inset: -1px; border-radius: 50%;
  border: 2px solid var(--ocean);
  animation: cal-ping 2.2s cubic-bezier(.2, .6, .3, 1) infinite;
}
.cal-howto-tap::after { animation-delay: 1.1s; }
@keyframes cal-ping {
  0%   { transform: scale(1);   opacity: .75; }
  70%  { transform: scale(2.7); opacity: 0; }
  100% { transform: scale(2.7); opacity: 0; }
}

/* ---- the view switch, until it has been used once ---- */
.cal-viewswitch-label {
  align-self: center; margin-right: 4px;
  font-family: var(--mont); font-size: 0.58rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; color: #7C888E;
}
.cal-viewswitch.is-nudge {
  position: relative; border-radius: 999px;
}
.cal-viewswitch.is-nudge::after {
  content: ""; position: absolute; inset: -7px -9px; border-radius: 999px;
  border: 2px solid var(--ocean); pointer-events: none;
  animation: cal-ring 2.4s ease-in-out infinite;
}
/* A ring says "look here" but not "why". The label says the why, and
   turns ocean while the ring is running so the two read as one thing. */
.cal-viewswitch.is-nudge .cal-viewswitch-label { color: var(--ocean); }
@keyframes cal-ring {
  0%, 100% { opacity: 0; transform: scale(1.05); }
  40%      { opacity: .85; transform: scale(1); }
  70%      { opacity: .35; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .cal-howto-tap::before, .cal-howto-tap::after,
  .cal-viewswitch.is-nudge::after { animation: none; }
  .cal-viewswitch.is-nudge::after { opacity: .7; }
}

/* ---- the other calendar ---- */
.cal-swap {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center; gap: 22px;
  margin-top: 34px; padding: 24px 28px;
  border-radius: var(--radius);
  background: linear-gradient(160deg, #EDF3F9 0%, #E2ECF4 100%);
  border: 1px solid #C6D9E8;
  text-decoration: none; color: inherit;
  transition: transform .25s ease, box-shadow .25s ease;
}
.cal-swap--free {
  background: linear-gradient(160deg, #EDF4F0 0%, #DFEAE4 100%);
  border-color: #CBDCD4;
}
.cal-swap:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.cal-swap-ico {
  display: grid; place-items: center; flex: none;
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--white); color: var(--ocean);
  box-shadow: var(--shadow-0);
}
.cal-swap--free .cal-swap-ico { color: #3D6B5C; }
.cal-swap-ico .door-icon { width: 25px; height: 25px; }
.cal-swap-body { display: flex; flex-direction: column; min-width: 0; }
.cal-swap-kicker {
  font-family: var(--mont); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.19em; text-transform: uppercase; color: #7C888E;
  margin-bottom: 5px;
}
.cal-swap-title {
  font-family: var(--serif); font-size: 1.32rem; line-height: 1.2; color: var(--ink);
}
.cal-swap-note { font-size: 0.9rem; line-height: 1.5; color: #5B6B76; margin-top: 6px; }
.cal-swap-go {
  flex: none;
  font-family: var(--mont); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.15em; text-transform: uppercase; color: var(--ocean);
  white-space: nowrap;
}
.cal-swap--free .cal-swap-go { color: #3D6B5C; }
@media (max-width: 760px) {
  .cal-swap { grid-template-columns: auto 1fr; gap: 16px; padding: 20px; }
  .cal-swap-go { grid-column: 2; margin-top: 12px; white-space: normal; }
  .cal-ask-btn { font-size: 0.6rem; padding: 11px 15px; }
}

/* the key: same colours, with what each one actually is */
.cal-legend {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  margin: 0 0 30px;
}
.cal-key {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 12px 14px; border-radius: var(--radius);
  background: var(--paper); border: 1px solid var(--line);
  border-left: 4px solid var(--pc);
  text-decoration: none; color: inherit;
  transition: box-shadow .25s ease, transform .25s ease;
}
.cal-key:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.cal-key .cal-swatch { margin-top: 5px; }
.cal-key-body { display: flex; flex-direction: column; min-width: 0; }
.cal-key-body strong {
  font-family: var(--serif); font-weight: 400;
  font-size: 1.02rem; line-height: 1.25; color: var(--ink);
}
.cal-key-meta {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px;
  font-family: var(--mont); font-size: 0.58rem; font-weight: 600;
  letter-spacing: 0.11em; text-transform: uppercase;
  color: #7C888E; margin-top: 6px;
}
/* Price and session count are the two facts a buyer is here for, so
   they lead the line and the running time follows them. */
.cal-key-meta .cal-key-price {
  font-family: var(--serif); font-weight: 400; font-size: 1.05rem;
  letter-spacing: 0; text-transform: none; color: var(--ink);
}
.cal-key-meta .cal-key-sessions {
  padding: 3px 9px; border-radius: 999px;
  background: var(--pc); color: #fff; opacity: .92;
}
/* The list rows take the programme colour on their left edge too, so
   month view and list view agree about what belongs to what. */
#cal-list .cal-row { border-left: 4px solid currentColor; }
#cal-list .cal-row h3, #cal-list .cal-row .cal-price { color: var(--ink); }
@media (max-width: 560px) {
  .cal-legend { grid-template-columns: minmax(0, 1fr); }
  .cal-crosslink { margin: -8px 0 24px; }
}

/* ============================================================
   ROUND 3 TWEAKS (2026-08-07)
   ============================================================ */

/* ---- 1: the three cross-door tiles wear their own brand ----
   These three are not Joy Restored products in the way the rungs
   above them are: one is the JR Guide, and two are partners with
   their own front doors. So each takes the colour it already has
   where it actually lives, and a visitor recognises it before
   reading the title.

   They keep .is-paid for the white type and the card mechanics;
   only the surface and the accent change.

   Let's Decode That  = the .decode-block treatment used in every
                        hero on this site (slate gradient, sky rule)
   Dream Interpretation = Dreams Like Daniel's --indigo / --twilight
                        / --periwinkle, from dreamslikedaniel.com
   Formation Council  = the Council's --ground / --firelight,
                        from sagefirecollective.com/formation-council */
.path-step.is-decode  .ps-card { background: linear-gradient(158deg, #213240 0%, #3A475A 100%); }
.path-step.is-dreams  .ps-card { background: linear-gradient(158deg, #232159 0%, #4A4699 100%); }
.path-step.is-council .ps-card { background: linear-gradient(158deg, #132029 0%, #213640 100%); }

.path-step.is-decode  .ps-card { --acc: #6EC6E3; --acc-ink: #123243; }
.path-step.is-dreams  .ps-card { --acc: #8A87D6; --acc-ink: #14122E; }
.path-step.is-council .ps-card { --acc: #E7AC4B; --acc-ink: #2A1B06; }

.path-step.is-decode  .ps-card, .path-step.is-dreams  .ps-card,
.path-step.is-council .ps-card { border-color: transparent; }
.path-step.is-decode  .ps-card::after, .path-step.is-dreams  .ps-card::after,
.path-step.is-council .ps-card::after { background: var(--acc); opacity: 1; }
.path-step.is-decode  .ps-chip, .path-step.is-dreams  .ps-chip,
.path-step.is-council .ps-chip { background: var(--acc); color: var(--acc-ink); }
.path-step.is-decode  .ps-go, .path-step.is-dreams  .ps-go,
.path-step.is-council .ps-go { color: var(--acc); }
.path-step.is-decode  .ps-dot { border-color: #3A475A; background: #3A475A; }
.path-step.is-dreams  .ps-dot { border-color: #4A4699; background: #4A4699; }
.path-step.is-council .ps-dot { border-color: #213640; background: #213640; }
/* the walker's lit ring follows the tile rather than the section */
.od .path-step.is-decode.is-lit  .ps-card,
.od .path-step.is-dreams.is-lit  .ps-card,
.od .path-step.is-council.is-lit .ps-card { border-color: var(--acc); }

/* ---- 3: the "Come as you are" line breaks in two, not three ----
   52ch is the right measure for the short CTA paragraphs elsewhere
   in this band, but this one is 135 characters and broke into three
   ragged lines. The <br> puts the break at the sentence boundary;
   the wider measure stops each half wrapping again. Both are off on
   phones, where two lines is not possible and forcing it only makes
   the rag worse. */
.cta-band p.cta-two-line { max-width: 82ch; }
@media (max-width: 760px) {
  .cta-band p.cta-two-line { max-width: 52ch; }
  .cta-lb { display: none; }
}

/* ---- 4: Work With Chariti, two plain buttons that line up ----
   The cards hold different amounts of copy, so the buttons only
   line up if the card is a column and the button is pushed to the
   bottom of it rather than sitting under the paragraph. */
.wwc-grid .card--hero { display: flex; flex-direction: column; }
.wwc-grid .card--hero p { flex-grow: 1; }
.wwc-btn { align-self: flex-start; margin-top: 26px; }

/* ---- 5: the wordmark over "Come as you are" ----
   Half the size it runs at elsewhere: the doors wordmark is
   min(320px, 62vw), so this is min(160px, 31vw). */
.cta-wordmark {
  width: min(160px, 31vw); height: auto;
  margin: 0 auto 22px; display: block;
}
@media (max-width: 640px) { .cta-wordmark { margin-bottom: 18px; } }

/* ============================================================
   ROUND 4 TWEAKS (2026-08-07)
   ============================================================ */

/* ---- 1: the sample reports read as buttons ----
   The whole card is still the link; .sp-go just stops being a quiet
   caption and becomes the thing you click. .btn brings the shape and
   the uppercase, so only the fit inside the card is set here. */
.sp-card .sp-go.btn {
  align-self: flex-start;
  padding: 13px 26px;
  font-size: 0.72rem; letter-spacing: 0.13em;
  color: #fff;
}
.sp-card:hover .sp-go.btn { box-shadow: var(--shadow-1); }

/* ---- 2: How It Works sits on the dark surface ----
   Same slate the JR Guide uses everywhere else on this page, so the
   explanation of the Guide looks like the Guide rather than like the
   rest of the site. */
.clarity-card--dark {
  background: linear-gradient(158deg, #213240 0%, #3A475A 100%);
  border-color: transparent;
  color: #fff;
  box-shadow: var(--shadow-3-dark);
}
.clarity-card--dark .label { color: var(--sky); }
.clarity-card--dark h2,
.clarity-card--dark .cw-step h3 { color: #fff; }
.clarity-card--dark .note,
.clarity-card--dark .cw-step p { color: rgba(255, 255, 255, 0.82); }
.clarity-card--dark .icon-circle { background: rgba(110, 198, 227, 0.16); }
.clarity-card--dark a:not(.btn) { color: var(--sky); }
/* the two columns inside keep their meaning, just on a dark ground.
   The li rule further up sets its own slate colour, so it has to be
   answered here or the list stays dark grey on a dark card. */
.clarity-card--dark .isnt-col { background: rgba(255, 255, 255, 0.07); color: #fff; }
.clarity-card--dark .isnt-col li { color: #fff; }

/* ---- the Guide card, lifted into the hero ----
   The card is the whole point of the page, so it starts inside the
   hero's bottom edge rather than a full section below it. The lift has
   to beat `section { padding: 96px 0 }` before it overlaps anything,
   which is why the numbers look large. */
.clarity-card--lifted {
  margin-top: clamp(-165px, -12vw, -112px);
  position: relative;
  z-index: 3;
}
@media (max-width: 760px) {
  .clarity-card--lifted { margin-top: -104px; }
}

/* ---- the travelling outline ----
   A faint sky ring around the whole card, with one brighter arc
   orbiting it. Built as a conic gradient masked down to a 2px ring, so
   it follows the 22px corners instead of squaring them off.

   The angle is a registered custom property because a raw
   conic-gradient `from` value is not animatable. Where @property is
   unsupported the angle simply never advances and the ring sits still,
   which is a static accent outline rather than a broken one. */
@property --ldt-ang {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
.clarity-card--glow { position: relative; }
.clarity-card--glow::before {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: calc(var(--radius) + 3px);   /* the card's radius, plus the 3px it sits outside */
  padding: 3px;
  background: conic-gradient(from var(--ldt-ang),
    rgba(110, 198, 227, 0.32) 0deg,
    rgba(110, 198, 227, 0.32) 195deg,
    rgba(110, 198, 227, 0.62) 250deg,
    rgba(150, 222, 245, 1) 288deg,
    #FFFFFF 302deg,
    rgba(150, 222, 245, 1) 316deg,
    rgba(110, 198, 227, 0.62) 352deg,
    rgba(110, 198, 227, 0.32) 360deg);
  /* keep only the 2px band: paint the full box, punch out the middle */
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  animation: ldt-orbit 9s linear infinite;
  pointer-events: none;
}
@keyframes ldt-orbit { to { --ldt-ang: 360deg; } }
@media (prefers-reduced-motion: reduce) {
  .clarity-card--glow::before { animation: none; }
}

/* ---- 3: the rotor on the Speaking headline ----
   The home hero rotates an italic phrase; this one rotates a plain
   noun mid-sentence, so it must not inherit the italic. */
.rotor--plain i { font-style: normal; }

/* ---- 4: the wordmark inside the invite tile ----
   The card is left-aligned, unlike the centred CTA bands, so the
   wordmark sits with the copy instead of over it. */
.invite-wordmark { margin: 0 0 20px; }

/* ============================================================
   ROUND 5 + 6 (2026-08-07)
   ============================================================ */

/* ---- 1 + 2: the partner pages lead with the offer ----
   Dreams Like Daniel and the Formation Council are both "here is
   someone else's good thing" pages. The offer card now rides in the
   hero beside the headline instead of halfway down behind a jump
   link, and the prose below condenses to a three-step strip so the
   partner's own site clears the fold. Both pages share this. */
.partner-offer {
  align-self: center;
  padding: 30px 28px 26px;
  border-radius: var(--radius);
  box-shadow: var(--shadow-3-dark);
}
.partner-offer h3 { color: #fff; margin: 10px 0 10px; }
.partner-offer p { color: rgba(255, 255, 255, 0.88); font-size: 0.94rem; }
.partner-offer .promo-code { margin-top: 16px; }

.partner-how { padding-bottom: 0; }
.pk-head { max-width: 62ch; margin-bottom: 26px; }
.pk-head h2 { margin: 14px 0 0; font-size: clamp(1.6rem, 3vw, 2.1rem); }
.pk-steps {
  display: grid; gap: 18px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.pk-step {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 22px 20px 20px;
}
.pk-num {
  display: inline-grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: rgba(27, 86, 141, 0.10); color: var(--ocean);
  font-family: var(--mont); font-size: 0.78rem; font-weight: 700;
  margin-bottom: 12px;
}
.pk-step h3 { font-size: 1.04rem; margin: 0 0 6px; }
.pk-step p { font-size: 0.9rem; line-height: 1.55; color: #46555E; margin: 0; }
.pk-note { margin-top: 20px; max-width: 74ch; }
@media (max-width: 820px) {
  .pk-steps { grid-template-columns: minmax(0, 1fr); }
}

/* ---- 3: the booking page names the kind, then the room ---- */
.ws-title-kind {
  display: block;
  font-family: var(--mont); font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
  margin-bottom: 12px;
}

/* ---- 4: the intensives colour-code and say what the price buys ----
   --pc is the programme's colour from cohort-data.json, the same value
   the intensives calendar draws with, so two runs of one intensive look
   like each other on both pages. */
.cohort-slot { border-left: 4px solid var(--pc, var(--line)); }
.cohort-slot:hover { border-color: var(--line); border-left-color: var(--pc, var(--sage)); }
.cohort-slot .cs-date { color: var(--pc, var(--ocean)); }
.cohort-slot .offer-chip.cs-price {
  background: var(--pc, var(--ocean)); color: #fff; border-color: transparent;
}
.cohort-slot[hidden] { display: none; }

.cohort-key {
  display: flex; flex-wrap: wrap; gap: 10px 22px;
  padding: 0 0 26px; margin-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.ck-item {
  display: inline-flex; align-items: baseline; gap: 9px;
  font-size: 0.92rem; color: var(--ink);
}
.ck-dot {
  width: 11px; height: 11px; border-radius: 3px; flex: none;
  background: var(--pc); transform: translateY(1px);
}
.ck-item em {
  font-style: normal;
  font-family: var(--mont); font-size: 0.56rem; font-weight: 600;
  letter-spacing: 0.11em; text-transform: uppercase; color: #7C888E;
}

/* ---- new 1: which door each intensive belongs to ---- */
.cohort-filters { margin-bottom: 30px; }
.cs-topline { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cs-door {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: rgba(54, 91, 109, 0.09);
}
.cs-door svg { width: 16px; height: 16px; }
.cs-door.door--formation { color: var(--door-formation-ink); background: rgba(134, 173, 160, .22); }
.cs-door.door--marriage  { color: var(--door-marriage-ink);  background: rgba(110, 198, 227, .24); }
.cs-door.door--healing   { color: var(--door-healing-ink);   background: rgba(27, 86, 141, .14); }

/* ---- new 2: the Try It button asks to be noticed ----
   A wave travels the button on a slow loop and again on hover. It is
   the brand ripple flattened into a band, not a generic shine, and it
   stops entirely for anyone who asked for reduced motion. */
.decode-block .db-cta {
  position: relative; overflow: hidden; isolation: isolate;
  margin-top: 22px;
  padding: 16px 34px;
  font-size: 0.72rem; letter-spacing: 0.18em;
  background: rgba(110, 198, 227, 0.20);
  border-color: rgba(110, 198, 227, 0.75);
  box-shadow: 0 10px 26px rgba(110, 198, 227, 0.22);
}
.decode-block .db-cta::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg,
    transparent 35%,
    rgba(110, 198, 227, 0.55) 50%,
    rgba(255, 255, 255, 0.38) 58%,
    transparent 72%);
  transform: translateX(-100%);
  animation: db-wave 3.6s ease-in-out infinite;
}
.decode-block .db-cta:hover {
  background: rgba(110, 198, 227, 0.34);
  border-color: #fff;
  box-shadow: 0 14px 32px rgba(110, 198, 227, 0.36);
}
.decode-block .db-cta:hover::before { animation-duration: 1.2s; }
@keyframes db-wave {
  0%        { transform: translateX(-100%); }
  55%, 100% { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
  .decode-block .db-cta::before { animation: none; }
}

/* ============================================================
   ROUND 7 (2026-08-07)
   ============================================================ */

/* ---- 3: What We Believe, on the dark ground ----
   These six are the spine of the whole site, and they read as
   throwaway on the same pale card as everything else. The slate the
   JR Guide uses gives them weight, and a sky rule along the top ties
   them to each other as one set rather than six separate notes. */
.card--belief {
  position: relative; overflow: hidden;
  background: linear-gradient(158deg, #213240 0%, #3A475A 100%);
  color: #fff;
  border: none;
  padding: 38px 34px 34px;
  box-shadow: var(--shadow-3-dark);
  transition: transform .3s ease, box-shadow .3s ease;
}
.card--belief::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--sky); opacity: .8;
}
/* The same dot field the JR Guide block wears, so the two dark
   surfaces on this site are recognisably the same material. */
.card--belief::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.12) 1.1px, transparent 1.2px),
    radial-gradient(rgba(255, 255, 255, 0.06) 1.1px, transparent 1.2px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  -webkit-mask-image: radial-gradient(ellipse 130% 110% at 90% 0%, #000 15%, transparent 82%);
          mask-image: radial-gradient(ellipse 130% 110% at 90% 0%, #000 15%, transparent 82%);
}
.card--belief > * { position: relative; z-index: 1; }
.card--belief h3 {
  color: #fff; font-size: 1.16rem; line-height: 1.28; margin: 0 0 10px;
}
.card--belief p { color: rgba(255, 255, 255, 0.84); margin: 0; }
.card--belief:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-3-dark);
}

/* ============================================================
   The Rhythm, on dark ground  (approach.html)

   Truth, Lament, Forgiveness, Remembering are the spine of the
   whole practice and they were reading as four ordinary paper
   cards. They take the same slate material the JR Guide and the
   belief cards already wear, so this site has one dark surface
   rather than three, and the four movements now read as the
   weight-bearing thing on the page.
   ============================================================ */
.card--dark {
  position: relative; overflow: hidden;
  background: linear-gradient(158deg, #213240 0%, #3A475A 100%);
  border: none;
  color: #fff;
  box-shadow: var(--shadow-3-dark);
  transition: transform .3s ease, box-shadow .3s ease;
}
/* the accent rule along the top, and the same dot field */
.card--dark::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--sage); opacity: .85;
}
.card--dark::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.12) 1.1px, transparent 1.2px),
    radial-gradient(rgba(255, 255, 255, 0.06) 1.1px, transparent 1.2px);
  background-size: 26px 26px, 26px 26px;
  background-position: 0 0, 13px 13px;
  -webkit-mask-image: radial-gradient(ellipse 130% 110% at 90% 0%, #000 15%, transparent 82%);
          mask-image: radial-gradient(ellipse 130% 110% at 90% 0%, #000 15%, transparent 82%);
}
.card--dark > * { position: relative; z-index: 1; }
.card--dark h3 { color: #fff; }
.card--dark p { color: rgba(255, 255, 255, 0.84); }
/* the sage eyebrow is a mid-tone: it needs lifting off this ground */
.card--dark .label--sage { color: #A9D0C2; }
.card--dark .textlink { color: #A9D0C2; border-color: rgba(169, 208, 194, 0.5); }
.card--dark .textlink:hover { color: #fff; border-color: #fff; }
.card--dark:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-3-dark);
}

/* ---- 4: the donate footnotes are not footnotes ----
   Where the money actually goes, and that it is tax-deductible, are
   the two things a giver most wants to read. They were set at .88rem
   in the muted grey used for asides. */
.note--large {
  font-size: 1.06rem;
  line-height: 1.65;
  color: #46555E;
  max-width: 68ch;
}
.note--large a { font-weight: 600; }
@media (max-width: 640px) { .note--large { font-size: 1rem; } }

/* ============================================================
   ROUND 8 (2026-08-07)
   ============================================================ */

/* ---- the dark How It Works card: the last two dark-on-dark bits ----
   The card was inverted but .sp-lead and .pay-note kept the grey they
   wear on paper, which on this surface is unreadable. Everything else
   inside either sits on a light panel of its own (the price block, the
   sample cards) or was already turned over. */
.clarity-card--dark { color: rgba(255, 255, 255, 0.88); }
.clarity-card--dark .sp-lead { color: rgba(255, 255, 255, 0.82); }
.clarity-card--dark .pay-note { color: rgba(255, 255, 255, 0.78); }

/* ============================================================
   QUICK CHAT  (quick-chat.html)

   A free 15-minute call, booked through Cal.com. The page's whole job
   is to make the embed feel like a contained tool inside a Joy
   Restored page rather than a widget dropped on one, so the embed sits
   in a card of its own and everything around it stays in the site's
   type. The widget will not take our fonts; that is expected and not
   worth fighting.
   ============================================================ */
/* Wider than a form would need: the Google scheduler puts a month grid
   and a time-slot column side by side, and squeezing it narrow makes it
   stack and scroll inside its own frame, which we cannot style. */
.qc-embed-wrap {
  max-width: 780px; margin: 0 auto;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 10px;
  overflow: hidden;
}
.qc-embed { min-width: 300px; height: 700px; }
@media (max-width: 640px) {
  /* On a phone the scheduler stacks, so it needs the height back. */
  .qc-embed { height: 720px; }
}

.qc-fallback {
  max-width: 780px; margin: 14px auto 0;
  text-align: center; font-size: 0.9rem; color: #5B6B76;
}
/* Until the booking link exists, an honest panel with somewhere else
   to go, rather than an embed pointed at nothing. */
.qc-pending { padding: 46px 30px 40px; text-align: center; }
.qc-pending h2 { font-size: clamp(1.5rem, 3vw, 2rem); margin: 12px 0 12px; }
.qc-pending p { color: #46555E; max-width: 46ch; margin: 0 auto 8px; }

.qc-smallprint {
  max-width: 680px; margin: 18px auto 0;
  text-align: center; font-size: 0.88rem; line-height: 1.6; color: #5B6B76;
}

.qc-reassure {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px;
  max-width: 760px; margin: 46px auto 0;
}
.qc-item { text-align: center; }
.qc-item .icon-circle { margin: 0 auto 12px; }
.qc-item h3 { font-size: 1.08rem; margin: 0 0 5px; }
.qc-item p { font-size: 0.92rem; color: #5B6B76; margin: 0; }
@media (max-width: 620px) {
  .qc-reassure { grid-template-columns: 1fr; gap: 22px; }
  .qc-embed-wrap { padding: 6px; }
}

/* ---- the same block, in Quick Chat's colours ----
   Structurally the .decode-block the Guide uses, so there is no second
   card component; only the surface and the accent change, and it lies
   down into a row because it sits full-width rather than in a hero
   column. The Guide keeps the slate; this one takes Deep Sea and sage,
   so the two never read as the same offer. */
.decode-block--chat {
  display: flex; align-items: center; justify-content: space-between;
  gap: 30px; flex-wrap: wrap;
  background: linear-gradient(158deg, #2C5766 0%, #3F7A72 100%);
  border-top-color: var(--sage);
  /* align-items centres inside the PADDING box, which does not include
     the 4px accent stripe, so the inherited 25px top left the copy and
     the button sitting ~5px low in the bar as the eye sees it. Taking
     the stripe out of the top padding puts the visible gaps at 24px
     either side. This bar is a single short row, which is the only
     place the offset is noticeable, so the taller .decode-block card
     keeps its own padding. */
  padding-top: 20px;
}
.decode-block--chat .db-chat-copy { flex: 1 1 380px; min-width: 0; }
.decode-block--chat .db-kicker { color: #BFE6D6; }
.decode-block--chat .db-title { margin-bottom: 6px; font-size: clamp(1.4rem, 2.2vw, 1.8rem); }
.decode-block--chat .db-cta { margin-top: 0; flex: none; }
/* the shimmer belongs to the paid tool; this one is free and quiet */
.decode-block--chat .db-cta::before { content: none; }
.decode-block--chat .db-cta:hover { background: rgba(255, 255, 255, 0.24); border-color: #fff; }
/* the wordmark is the Guide's signature, not this card's */
.decode-block--chat::after { content: none; }

/* ---- the Quick Chat invitations dotted around the site ----
   Deliberately quieter than a product rung: on a door page this sits
   under the ladder and must not compete with it. */
.qc-invite {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  justify-content: center; text-align: center;
  margin-top: 30px; padding: 16px 24px;
  border: 1px dashed rgba(54, 91, 109, 0.3);
  border-radius: 999px;
  background: rgba(134, 173, 160, 0.08);
  font-size: 0.97rem; color: #46555E;
}
.qc-invite .textlink { border-color: currentColor; }
@media (max-width: 560px) {
  .qc-invite { border-radius: var(--radius); }
}

/* ---- shimmer, shared ----
   Same wave the Try It button wears, lifted out so any button can take
   it. .db-cta now uses this too rather than carrying its own copy. */
.btn--shimmer { position: relative; overflow: hidden; isolation: isolate; }
.btn--shimmer::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg,
    transparent 35%,
    rgba(110, 198, 227, 0.55) 50%,
    rgba(255, 255, 255, 0.38) 58%,
    transparent 72%);
  transform: translateX(-100%);
  animation: db-wave 3.6s ease-in-out infinite;
}
.btn--shimmer:hover::before { animation-duration: 1.2s; }
@media (prefers-reduced-motion: reduce) {
  .btn--shimmer::before { animation: none; }
}
/* ---- the same wave, on a product tile ----
   Let's Decode That is the one rung on the All Products page that is a
   live tool rather than a document, and the shimmer is already this
   site's way of saying so on its buttons. .ps-card is relative and
   clipped already, and ::after is the top sheen, so the wave takes
   ::before and the tile's own content is lifted above it. */
.ps-card--shimmer::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(100deg,
    transparent 35%,
    rgba(110, 198, 227, 0.30) 50%,
    rgba(255, 255, 255, 0.22) 58%,
    transparent 72%);
  transform: translateX(-100%);
  animation: db-wave 3.6s ease-in-out infinite;
}
.ps-card--shimmer > * { position: relative; z-index: 1; }
.path-step:hover .ps-card--shimmer::before { animation-duration: 1.2s; }
@media (prefers-reduced-motion: reduce) {
  .ps-card--shimmer::before { animation: none; }
}

/* ---- the Merch rung shows the thing it sells ----
   Every other rung on that ladder sells something you cannot
   photograph. This one sells a mug, so it shows the mug. */
.ps-shot {
  display: block; width: 74px; height: 74px; flex: none;
  object-fit: cover; border-radius: var(--radius);
  margin: 0 0 12px;
  box-shadow: var(--shadow-0);
}
/* Out of the flow once the ladder shares its rows. It is the one
   element on any rung that no other rung has, so in a slot of its own
   it would have opened 86px of nothing on every card beside it. Up in
   the corner it costs the row nothing and still shows the mug, which
   was the point of it. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 901px) {
    .ps-card .ps-shot {
      position: absolute; top: 14px; right: 14px; margin: 0;
      width: 56px; height: 56px;
    }
  }
}

/* On the solid ocean button the wave needs to read as light passing
   over it, not as a second colour. */
.btn--primary.btn--shimmer::before {
  background: linear-gradient(100deg,
    transparent 35%,
    rgba(255, 255, 255, 0.30) 50%,
    rgba(255, 255, 255, 0.52) 58%,
    transparent 72%);
}

/* ---- Let's Decode That hero: the hook before the explanation ----
   The page used to open by describing the mechanism. It now opens on
   the feeling that brings someone here, and explains second. On
   .hero--sub every p has margin-bottom:0, so this line sets its own. */
.hero p.ldt-hook {
  font-family: var(--serif);
  font-size: 1.9rem;
  line-height: 1.3;
  color: var(--white);
  max-width: 24ch;
  margin-bottom: 20px;
}
.hero p.ldt-hook em { font-style: italic; color: var(--sky); }
@media (max-width: 720px) { .hero p.ldt-hook { font-size: 1.5rem; } }

/* ---- "Her Story" under the hero portrait ----
   Deliberately quieter than the ghost pill in the hero copy: that one
   sells a product, this one just offers context. It mirrors the
   .hp-tag above it and centres under the same portrait column. */
.hp-story {
  display: block;
  width: fit-content;
  margin: 10px auto 0;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 999px;
  padding: 7px 16px;
  color: #fff;
  text-decoration: none;
  font-family: var(--mont);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.hp-story:hover { background: rgba(255, 255, 255, 0.18); border-color: rgba(255, 255, 255, 0.85); }

/* The header is sticky and does not shrink, so an anchored section has
   to leave room for it or its heading lands underneath. */
#her-story { scroll-margin-top: 96px; }

/* ---- Care note band ----
   Sits under the quick bar in the same ivory register so it reads as
   part of the page furniture rather than an alert. The 988 number is a
   tel: link because most people meeting this line are on a phone. */
.care-bar {
  background: var(--ivory);
  border-bottom: 1px solid var(--line);
}
.care-bar-inner {
  margin: 0 auto;
  padding: 11px 28px;
  text-align: center;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--slate);
}
.care-bar-inner strong { color: var(--deep); }
.care-bar-inner a {
  color: var(--ocean);
  font-weight: 600;
  text-underline-offset: 3px;
}
@media (max-width: 620px) { .care-bar-inner { padding: 12px 20px; font-size: 0.82rem; } }

/* ---- Episode date + runtime on the podcast tiles ----
   The tiles are ordered newest first, so the date is what makes that
   order readable; the runtime answers the other question people ask
   before pressing play. Sits between the title and the blurb, and
   site.js renders the same line when /api/podcast is wired up. */
.pod-card .pod-meta {
  display: block;
  margin: -2px 0 10px;
  font-family: var(--mont);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #7C888E;
}

/* ---- Turnstile ----
   The widget runs in "interaction-only" mode: for nearly every visitor
   Cloudflare never draws anything, and this box must not leave a gap
   above the submit button.

   :empty alone is not enough, because Turnstile injects an iframe into
   the container whether or not it ends up showing a challenge. So the
   spacing hangs off :has(), and a browser without :has() support simply
   gets a challenge with no margin around it, which is a cosmetic
   problem on a path most people never see. Never a layout gap on the
   path everyone does. */
.jr-turnstile:empty {
  display: none;
}

.jr-turnstile:has(iframe) {
  margin: 4px 0 18px;
}

/* Keeps a short sentence from breaking mid-phrase. Used on the 988
   crisis line, which read badly split across two lines. It still
   wraps to its own line when the paragraph runs out of room, it just
   never breaks inside itself. */
.nowrap { white-space: nowrap; }

/* ---------- Course tiles: play badge (2026-08-25) ----------
   The squares on a course index did not read as openable. Scoped to
   .lib-card--play so the library shelf, which uses .lib-card for PDF
   guides, never claims to play anything. */
.lib-card--play { position: relative; padding-right: 74px; }
.lib-card--play::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 24px;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: var(--sage);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 14'%3E%3Cpath d='M1.5 1.2 L10.8 7 L1.5 12.8 Z' fill='%23fff'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 54% center;
  background-size: 12px 14px;
  transition: transform .3s ease;
}
.lib-card--play:hover::after { transform: translateY(-50%) scale(1.08); }
/* A drip-locked month greys with the card; it must not look clickable. */
.lib-card--play.is-locked:hover::after { transform: translateY(-50%); }

@media (max-width: 520px) {
  .lib-card--play { padding-right: 64px; }
  .lib-card--play::after { right: 18px; width: 32px; height: 32px; }
}
