/* ───────────────────────────────────────────────────────────────────────────
   Holy Instant — the landing page.

   A quiet doorway, not a sales page. Warm paper by day, deep ink by night,
   one accent of candlelight gold. The whole discipline of the type is air:
   wide margins, generous leading, a narrow reading measure, and long pauses
   of empty space that are not empty — they are room to exhale.

   Colors are the app's own tokens (DesignSystem/Theme.swift), verbatim.
─────────────────────────────────────────────────────────────────────────── */

:root {

  /* ── the palette (light / paper is the default) ───────────────────────── */
  --paper:          #FAF6EF;   /* the page                                   */
  --ink:            #2B2620;   /* primary text — 13.9:1 on paper             */
  --ink-secondary:  #6B6357;   /* quieter text  —  5.5:1 on paper            */
  --accent:         #A8863C;   /* muted gold — for rules & glow, never body  */
  --hairline:       #E4DCC9;   /* a whisper of a line                        */
  --surface:        #F4EEE3;

  /* the deep-ink field of the aperture — the hero holds it in BOTH themes,
     because the light can only be seen against the dark. */
  --field-hi:       #171510;   /* the room. Theme.background(dark) — every corner
                                  of 7-stillness.png measures #171510.        */
  --field-mid:      #16130d;
  --field-lo:       #100e08;
  --on-field:       #EDE7DA;   /* text over the field — 14.81:1, measured    */
  --on-field-quiet: #A9A08D;   /* quieter text over the field —  7.04:1      */
  --field-gold:     #C9A860;   /* gold reads as light on the dark field — 8.04:1 */

  /* ── motion tokens (Matt's own easing) ────────────────────────────────── */
  --ease-out-soft: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-breath:   cubic-bezier(0.37, 0, 0.63, 1);  /* = (1-cos(πx))/2, the app's
                                                       cosine ease. max err 0.20% */
  --breath:        11s;        /* one whole breath, the app's own: StillnessView
                                  BreathCycle — 4 in, 1 HELD, 6 out.          */

  /* ── type ─────────────────────────────────────────────────────────────── */
  --serif: Palatino, "Palatino Linotype", "Iowan Old Style", "Book Antiqua",
           Georgia, "Times New Roman", serif;
  --sans:  -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
           Arial, system-ui, sans-serif;

  --measure: 34rem;            /* the reading measure — never wider          */
  --layout-wide: 72rem;
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-6: 3rem;
  --space-8: 4rem;
  --radius-panel: 2rem;
  --radius-device: 3.25rem;
  --radius-screen: 2.72rem;
  --device-padding: 9px;
  --device-bezel: #080808;
  --device-island: #050505;
  --device-shadow: 0 1.5rem 3.5rem rgba(43, 38, 32, 0.22);

  color-scheme: light dark;
}

/* deep-ink night mode — the reading sections turn to ink, the hero was
   already dark, so the page reads as one seamless dusk. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper:         #171510;
    --ink:           #EDE7DA;   /* 14.8:1 on ink                             */
    --ink-secondary: #A9A08D;   /*  7.0:1 on ink                             */
    --accent:        #C9A860;   /* on the dark page, gold is legible light   */
    --hairline:      #322D24;
    --surface:       #201D17;
    --device-shadow: 0 1.5rem 3.5rem rgba(0, 0, 0, 0.48);
  }
}


/* ── reset-ish, kept tiny ─────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(1.0625rem, 0.9rem + 0.6vw, 1.25rem);
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;                 /* the glow never spills a scrollbar   */
}

p { margin: 0; }

/* atom: one responsive device frame, shared by the doorway and gallery */
.device-frame {
  position: relative;
  overflow: hidden;
  margin: 0;
  padding: var(--device-padding);
  border: 1px solid color-mix(in srgb, var(--ink) 28%, transparent);
  border-radius: var(--radius-device);
  background: var(--device-bezel);
  box-shadow: var(--device-shadow);
}

.device-frame::after {
  position: absolute;
  top: 1.08rem;
  left: 50%;
  width: 28%;
  height: 1.55rem;
  border-radius: 999px;
  background: var(--device-island);
  content: "";
  transform: translateX(-50%);
}

.device-frame img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-screen);
}


/* ───────────────────────────────────────────────────────────────────────────
   the hero — the aperture

   A single luminous seam of gold light rising through a deep, warm field of
   ink, recreated entirely in CSS. The field is a radial deep-ink ground; the
   light is five stacked elliptical gradients — a felt whole-field warmth, a
   candlelight haze, luminous gold, a bright white seam, and the concentrated
   heart of the instant — the same layering as the app icon.
─────────────────────────────────────────────────────────────────────────── */

.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;

  min-height: 100vh;                   /* fallback — pre-svh browsers (Safari <15.4) */
  min-height: 100svh;                  /* the SMALL viewport: the one WITH the toolbars
                                          showing. 100vh is the LARGE one, and content
                                          sized to it is what hides behind the bar.    */

  padding: 0 clamp(1.5rem, 6vw, 4rem);

  /* the badge sits at the bottom of this box, so this padding is the only thing
     between it and the chrome. it was `12vh` — the LARGE viewport — inside a box
     measured in svh: incoherent, and the reason the bottom gap drifted 66 → 96px
     across the three phones. it is svh now, like the box it pads.

     the safe-area floor is the guard for the day someone adds `viewport-fit=cover`
     to the viewport meta to get a full-bleed hero. today Safari does NOT extend the
     page under its bar (the inset resolves to 0), so nothing here needs it — which
     is exactly why it is a loaded gun: that one-line edit would drop the badge under
     the home indicator with nothing to catch it. now there is. */
  padding-bottom: max(
    clamp(3.5rem, 12svh, 7rem),
    env(safe-area-inset-bottom, 0px) + 2.5rem
  );

  overflow: hidden;
  text-align: center;

  /* dawn — the same light as the app icon, so the face of the app and its
     doorway are one image: a cream sky lifting off a warm horizon and sinking
     into deep ink, where the words come to rest. Held in both themes, like the
     icon; the reading below is what turns to paper or to night.

     THE HORIZON WAS RAISED (52% → 34%), and every stop with it. It had to be.
     The words are bottom-anchored, and on a 375×667 phone they begin at 55%
     depth — which is where the sun WAS. The app's own name measured 1.34:1
     against its own sunrise: cream on cream, invisible, on the smallest phone
     anyone reads this on. (The spec measured .hero__note against the gradient's
     bottom stop — 6.51:1, and that one was true — and nobody ever measured the
     two lines ABOVE it, where the light actually is.)

     A scrim behind the words was tried first and thrown away: any ink dark
     enough to carry the wordmark also swallows the sun, because on a short
     screen they occupy the SAME pixels. The words cannot move down (there is no
     room below them on an SE) — so the light moves up. Now the sun crests above
     the words and they rest in the ink beneath it, which is what the
     composition wanted all along. The dawn is unchanged in hue, order, and
     feel; only its horizon sits higher in the frame. */
  background:
    linear-gradient(180deg,
      #EFE8D8   0%,     /* cream sky            */
      #EADEC4  18%,
      #DCBE84  28%,     /* the warming toward light */
      #C59A52  34%,     /* the horizon          */
      #7A6038  43%,
      #3A2F1F  53%,     /* ink by here — ABOVE the SE's wordmark at 55% */
      #221C13  72%);    /* deep ink, under the words */
}

/* the sun cresting the horizon — a hot core inside a warm bloom inside a wide
   aura, stacked so the light reads as lit, not painted. A wide, low band rather
   than a tall seam, centred on the horizon line, and breathing. */
.hero__glow {
  position: absolute;
  z-index: -1;
  top: 34%;                            /* the horizon — raised with the dawn */
  left: 50%;
  width: min(150vw, 1100px);
  height: min(52svh, 560px);           /* shorter, so its lower aura stops short
                                          of the words instead of washing them */
  transform: translate(-50%, -50%);
  pointer-events: none;

  background:
    radial-gradient(closest-side, rgba(255,253,246,0.98) 0%, rgba(255,253,246,0) 64%) 50% 50% / 30% 22% no-repeat,
    radial-gradient(closest-side, rgba(255,242,214,0.72) 0%, rgba(255,242,214,0) 68%) 50% 50% / 54% 38% no-repeat,
    radial-gradient(closest-side, rgba(240,206,140,0.44) 0%, rgba(240,206,140,0) 72%) 50% 50% / 92% 58% no-repeat,
    radial-gradient(closest-side, rgba(190,150,80,0.24) 0%, rgba(190,150,80,0) 78%) 50% 50% / 132% 100% no-repeat;

  animation: breathe var(--breath) var(--ease-breath) infinite;
  will-change: opacity, transform, filter;
}

/* the slow breath, the app's own: four seconds in (ends 4/11 = 36.3636%), one
   held at the top (ends 5/11 = 45.4545%), six back out. transform / opacity /
   filter only, so nothing around it ever shifts. */
@keyframes breathe {
  0%       { opacity: 0.84; transform: translate(-50%, -50%) scale(0.98); filter: brightness(0.98); }
  36.3636% { opacity: 1;    transform: translate(-50%, -50%) scale(1.04); filter: brightness(1.05); }
  45.4545% { opacity: 1;    transform: translate(-50%, -50%) scale(1.04); filter: brightness(1.05); }
  100%     { opacity: 0.84; transform: translate(-50%, -50%) scale(0.98); filter: brightness(0.98); }
}

.hero__words { position: relative; }

.hero__device { display: none; }

.wordmark {
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(2.5rem, 1.6rem + 4.6vw, 4.25rem);
  line-height: 1.05;
  letter-spacing: 0.01em;
  color: var(--on-field);
  text-shadow: 0 1px 30px rgba(201, 168, 96, 0.18);
}

.hero__line {
  margin-top: clamp(0.75rem, 2svh, 1.25rem);
  font-size: clamp(1rem, 0.9rem + 0.5vw, 1.2rem);
  letter-spacing: 0.015em;
  color: var(--on-field-quiet);
}


/* ───────────────────────────────────────────────────────────────────────────
   THE PHONE — the same dawn, composed for a hand

   The desktop composition does not survive the trip. On a 375×667 iPhone the
   small viewport is 549px tall, and it spent the first 47% of that on sky
   before the first word: a blurry smudge, and then the name and the door
   crowded into the bottom third against Safari's floating bar. Three things
   change, and only here.

   1. THE SUN BECOMES A SUN. It was min(150vw, 1100px) × min(52svh, 560px) —
      562 × 285px on an SE, wider than the phone it is on, and its outermost
      aura (132% of that box) ran 742px across. That is not a light, it is
      weather. Capped to min(70vmin, 420px) it is 262px: it has an edge, so it
      has a core.

   2. THE HORIZON RISES WITH THE SKY, 34% → 23%. It has to. The words come up,
      and if the ink does not come up with them the wordmark lands on #A48047
      and measures 2.96:1 — cream on brass, a fail. This file already learned
      that law once at 52%; a phone is just where it bites soonest.

   3. THE WORDS LIFT OUT OF THE BOTTOM SIXTH. On an SE the wordmark moves from
      47% of the fold to 38%, the badge's artwork from 67% to 59%, and ~120px
      of clear ink opens under the note — comfortably past the ~90px of Safari
      chrome that 100svh has already excluded anyway. Belt, and braces.

   The breath is untouched: same element, same 11s, same 4-in / 1-held / 6-out.
   It is a smaller light, not a lesser one.

   (Portrait only. A landscape phone is ~330px of viewport for a full-height
    hero — the sky and the words cannot both fit, and that is a different
    composition than this one, not a smaller one. Unchanged, and still the
    weakest screen on the page.)
─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 600px) {

  .hero {
    padding-bottom: max(
      clamp(6.5rem, 22svh, 12rem),
      env(safe-area-inset-bottom, 0px) + 5rem
    );

    /* the same dawn, in the same order, at the same hues — a shorter sky */
    background:
      linear-gradient(180deg,
        #EFE8D8   0%,     /* cream sky            */
        #EADEC4  12%,
        #DCBE84  19%,     /* the warming toward light */
        #C59A52  23%,     /* the horizon          */
        #7A6038  29%,
        #3A2F1F  36%,     /* ink by here — ABOVE the wordmark at 38% */
        #221C13  55%);    /* deep ink, under the words */
  }

  .hero__glow {
    top: 23%;                          /* the horizon — raised with the dawn   */
    width: min(70vmin, 420px);
    height: min(38svh, 260px);
  }
}


/* ───────────────────────────────────────────────────────────────────────────
   the reading — passages, quote, ethos
─────────────────────────────────────────────────────────────────────────── */

main {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(3rem, 9vh, 5.5rem) clamp(1.5rem, 6vw, 3rem);
}

section { width: 100%; }

.home-story { width: 100%; }

.passages {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(2rem, 5vh, 3.25rem);      /* an intentional pause between breaths, not a void */
  max-width: var(--measure);
  margin-inline: auto;
}

.passage {
  max-width: var(--measure);
  font-size: clamp(1.125rem, 1rem + 0.7vw, 1.375rem);
  line-height: 1.72;
  text-align: left;                    /* prose reads left; centring is for a line, not a paragraph */
  text-wrap: pretty;                   /* even ragged edge, no orphans */
  color: var(--ink);
}


/* the pull-quote — serif, held between two soft gold rules */
.quote {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.75rem, 5vh, 2.75rem);
  margin: clamp(5rem, 16vh, 9rem) auto;
  max-width: var(--measure);
  text-align: center;
}

.quote__body {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(1.5rem, 1.1rem + 2vw, 2.375rem);
  line-height: 1.42;
  font-style: italic;
  color: var(--ink);
}

.quote__body p { margin: 0; }

.quote__cite {
  font-family: var(--sans);
  font-style: normal;
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  color: var(--ink-secondary);
}

/* a short seam of gold — the decorative use the gold is safe for on paper */
.rule {
  display: block;
  width: clamp(48px, 12vw, 80px);
  height: 1px;
  background: linear-gradient(90deg,
    transparent, var(--accent), transparent);
  opacity: 0.7;
}


.ethos {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(2rem, 6vh, 3rem);
  max-width: var(--measure);

  /* .ethos follows the full-bleed dark .offer, and had no block margin at all:
     its first line started at the black band's exact bottom edge (measured —
     .offer bottom 3065.48, .ethos top 3065.48), so "it keeps no account of You"
     read as crammed against the dark rather than resting after it. Same rhythm
     as .quote, which is the page's existing section step. */
  margin: clamp(5rem, 16vh, 9rem) auto;
  text-align: center;
}

/* Desktop is a composition, not an enlarged phone. The doorway meets the
   person with the name, the door, and one real screen in the first view; the
   story and the Course then share a spread instead of becoming two long voids. */
@media (min-width: 720px) {
  .hero {
    display: grid;
    grid-template-columns: minmax(20rem, 30rem) minmax(13rem, 18rem);
    gap: clamp(var(--space-6), 8vw, 7rem);
    justify-content: center;
    align-items: center;
    min-height: min(52rem, 88svh);
    padding: var(--space-8) clamp(var(--space-4), 7vw, 7rem);
    text-align: left;
    background:
      radial-gradient(circle at 69% 27%, rgba(255, 248, 225, 0.88) 0 5%, rgba(218, 180, 108, 0.32) 15%, transparent 34%),
      linear-gradient(135deg, #5d4829 0%, #2f281d 42%, #171510 100%);
  }

  .hero__glow {
    top: 29%;
    left: 69%;
    width: min(58vw, 760px);
  }

  .hero__words {
    justify-self: end;
    width: 100%;
  }

  .hero__device {
    display: block;
    width: min(100%, 18rem);
    transform: rotate(1.5deg);
  }

  .hero__device--breathing img {
    display: block;
    width: 100%;
    height: auto;
    filter: drop-shadow(0 2rem 3rem rgba(4, 4, 8, 0.34));
  }

  .hero__line { max-width: 24rem; }

  .hero .badge { margin-inline: 0; }

  main {
    padding: clamp(var(--space-8), 9vw, 7rem) clamp(var(--space-4), 7vw, 7rem);
  }

  .home-story {
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(17rem, 0.92fr);
    gap: clamp(var(--space-8), 9vw, 8rem);
    align-items: center;
    max-width: var(--layout-wide);
  }

  .passages { align-items: stretch; }

  .quote {
    position: sticky;
    top: var(--space-8);
    margin: 0;
  }

  .offer {
    min-height: 0;
    margin-top: clamp(var(--space-8), 10vw, 8rem);
    padding-block: clamp(var(--space-8), 10vw, 8rem);
  }

  .ethos {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: clamp(var(--space-8), 9vw, 8rem);
    align-items: center;
    max-width: 58rem;
    text-align: left;
  }
}

@media (min-width: 720px) and (max-width: 899px) {
  .hero {
    grid-template-columns: minmax(18rem, 1fr) 14rem;
    gap: var(--space-6);
    padding-inline: var(--space-6);
  }

  .hero__device { width: 14rem; }
}

/* ───────────────────────────────────────────────────────────────────────────
   the App Store badge — Apple's own lockup, never ours

   Apple's marketing guidelines require their provided artwork, at their clear
   space and minimum size. It ships inline (no request, no asset, sharp at any
   density) in BOTH official variants, and the page shows whichever one has the
   contrast: the black badge on paper (19.49:1), the white badge on night stock.

   The hero is the exception — its field is the dark end of the dawn gradient
   (#221C13) in BOTH themes, so it always wears the WHITE badge. The black one
   measures 1.24:1 there: invisible. Measured, not guessed.
─────────────────────────────────────────────────────────────────────────── */

.badge {
  display: inline-block;
  padding: 24px;                    /* clear space: 50% of the mark's height */
  border-radius: 8px;
  transition: transform 200ms var(--ease-out-soft);
}

.badge__art {
  display: block;
  height: 48px;                     /* ≥ 44px, Apple's own touch-target floor */
  width: auto;
}

/* one variant at a time. light is the default; night swaps below. */
.badge__art--dark { display: none; }

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

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

/* on the field, the ring has to be gold-on-dark (8.04:1), not paper's accent */
.badge--on-field:focus-visible { outline-color: var(--field-gold); }

/* the hero wears white in both themes — the dawn's floor is dark either way */
.badge--on-field .badge__art--light { display: none; }
.badge--on-field .badge__art--dark  { display: block; }

@media (prefers-color-scheme: dark) {
  .badge__art--light { display: none; }
  .badge__art--dark  { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  .badge { transition: none; }
  .badge:hover { transform: none; }
}

/* the line under each badge: what it costs, which is nothing */
.hero__note {
  margin-top: 0.25rem;
  font-size: 0.9375rem;
  letter-spacing: 0.015em;
  color: var(--on-field-quiet);     /* 6.51:1 on the gradient's floor #221C13 */
}

.badge-block {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.badge__note {
  margin-top: 0.25rem;
  font-size: 0.9375rem;
  letter-spacing: 0.08em;
  color: var(--ink-secondary);      /* 5.49:1 on paper */
}


/* ── footer — the year, and a line ────────────────────────────────────────── */

.footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: clamp(3rem, 10vh, 5rem) 1.5rem clamp(3.5rem, 10vh, 5rem);
  border-top: 1px solid var(--hairline);
  text-align: center;
  color: var(--ink-secondary);
}

.footer__mark {
  font-family: var(--serif);
  font-size: 1rem;
  letter-spacing: 0.03em;
}

.footer__love {
  font-size: 0.875rem;
  letter-spacing: 0.04em;
}

/* the three doors, in a single quiet row — same ink + hairline-underline as
   the support link, so nothing here shouts. */
.footer__nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  margin-bottom: 0.75rem;
  font-size: 0.875rem;
}

/* the underline is the ONLY thing that says "link" — link text is the same ink
   as body text. so it cannot be a whisper. --hairline is 1.27:1 on paper (and
   1.33:1 on ink): invisible, and a WCAG 1.4.1 failure, because colour alone was
   never carrying it either. the underline is --ink-secondary: 5.49:1 / 7.04:1.
   --hairline keeps its structural job — the footer rule, the .doc__updated rule
   — where a low ratio is the correct answer. */
.footer__nav a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--ink-secondary);
  padding-bottom: 1px;
  transition: border-color 240ms var(--ease-out-soft);
}

/* hover strengthens the affordance — it never weakens it. (gold on paper is
   3.17:1: legal as a rule, but a step DOWN from the 5.49:1 it would replace.) */
.footer__nav a:hover { border-bottom-color: var(--ink); }

.footer__nav a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* the separator carries no meaning (aria-hidden), but at 50% it was 2.09:1 —
   below the 3:1 floor and needlessly faint. it reads at --ink-secondary. */
.footer__dot { color: var(--ink-secondary); }


/* the donation line that used to live here is gone, and so are .support /
   .support__link. it asked for money on a page whose support doc opens with
   "there is no purchase, no subscription, and no account." */


/* ───────────────────────────────────────────────────────────────────────────
   document pages — support & privacy

   The same paper, ink, and measure as the doorway, but laid for reading a
   little longer: a quiet masthead that walks home, a narrow column, headings
   that differ from body on weight and color, never font.
─────────────────────────────────────────────────────────────────────────── */

.masthead {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: clamp(3rem, 10vh, 5rem) 1.5rem clamp(1.5rem, 5vh, 2.5rem);
  text-align: center;
}

.masthead__mark {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.75rem, 1.4rem + 1.6vw, 2.375rem);
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
}

/* the mark is the way home from every doc page, and it was the one link on the
   site with no focus ring of its own. it has one now. */
.masthead__mark:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 3px;
}

/* gold is light, never a letterform: --accent is 3.17:1 on paper, which is legal
   for a rule and illegal for a word. the kicker is an <h1>. it reads in ink. */
.masthead__kicker {
  font-size: 0.875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-secondary);   /* 5.49:1 on paper — measured */
}

.doc {
  max-width: var(--measure);
  margin: 0 auto;
  padding: clamp(1rem, 4vh, 2rem) clamp(1.5rem, 6vw, 3rem) clamp(4rem, 12vh, 6rem);
}

.doc__lede {
  font-size: clamp(1.125rem, 1rem + 0.7vw, 1.375rem);
  line-height: 1.7;
  color: var(--ink);
  text-wrap: pretty;
}

.doc h2 {
  margin: clamp(2.5rem, 7vh, 3.5rem) 0 0.75rem;
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.375rem, 1.15rem + 1vw, 1.75rem);
  line-height: 1.3;
  color: var(--ink);
}

.doc p {
  margin: 0 0 1.1rem;
  color: var(--ink);
  text-wrap: pretty;
}

.doc p.quiet { color: var(--ink-secondary); }

.doc a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--ink-secondary);   /* 5.49:1 / 7.04:1 — the only affordance */
  padding-bottom: 1px;
  transition: border-color 240ms var(--ease-out-soft);
}

.doc a:hover { border-bottom-color: var(--ink); }

.doc a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.doc__updated {
  margin-top: clamp(2.5rem, 7vh, 3.5rem);
  padding-top: 1.25rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.875rem;
  letter-spacing: 0.02em;
  color: var(--ink-secondary);
}


/* ───────────────────────────────────────────────────────────────────────────
   the offer — a dark band in the middle of the reading, and a door in it

   You have read four passages and the Course's own opening. this is as still
   as a web page can get You. so here, and not at the top or the end, is the
   invitation. it asks for nothing and it is easy to walk past.
─────────────────────────────────────────────────────────────────────────── */

.offer {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: clamp(1.25rem, 3.5vh, 2rem);
  min-height: 80svh;
  width: 100vw;                          /* full-bleed out of main's measure  */
  margin-inline: calc(50% - 50vw);
  padding: clamp(3rem, 10vh, 6rem) 1.5rem;
  background: var(--field-hi);
  text-align: center;
}

/* the seam of gold above the door — decorative, and gold is always safe as light */
.rule--on-field {
  width: 44px;
  height: 2px;
  background: var(--field-gold);
  opacity: 0.85;
}

.offer__lede {
  max-width: var(--measure);
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.25rem, 1.05rem + 0.9vw, 1.625rem);
  line-height: 1.5;
  color: var(--on-field);                /* 14.81:1 on the field — measured   */
}

.offer__note {
  max-width: var(--measure);
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--on-field-quiet);          /*  7.04:1 on the field — measured   */
}

.offer__after {
  max-width: var(--measure);
  margin-top: clamp(1.5rem, 5vh, 3rem);
  font-size: 1rem;
  color: var(--on-field-quiet);
}

/* the one way to /app. a link, never a button: the page has already given away
   its whole gift, and this only offers more of it. it is ALWAYS visible — it is
   the site's only path to that page, so it cannot be gated behind the instant
   the way .offer__after is. the underline is the only thing that says "link"
   here (this file's own law), and on the field it has to be --on-field-quiet
   (7.04:1), not paper's --ink-secondary (1.87:1 on the field — invisible). */
.offer__more {
  max-width: var(--measure);
  font-size: 0.9375rem;
}

.offer__more a {
  color: var(--on-field);                       /* 14.81:1 — measured */
  text-decoration: none;
  border-bottom: 1px solid var(--on-field-quiet); /* 7.04:1 — the affordance */
  padding-bottom: 2px;
  transition: border-color 240ms var(--ease-out-soft);
}

.offer__more a:hover { border-bottom-color: var(--on-field); }

.offer__more a:focus-visible {
  outline: 2px solid var(--field-gold);
  outline-offset: 3px;
  border-radius: 2px;
}

/* a candle-lit doorframe: transparent, with a gold hairline. gold as a border
   is 8.04:1 on the field and legal; gold as a letterform never is. */
.still-btn {
  min-height: 44px;
  padding: 8px 24px;                     /* Theme.Spacing.sm / .lg            */
  border-radius: 14px;                   /* Theme.Radius.md                   */
  background: transparent;
  border: 1px solid var(--field-gold);   /* 8.04:1 — measured                 */
  color: var(--on-field);                /* 14.81:1 — measured                */
  font: 500 1.0625rem/1.2 var(--sans);   /* the app's .callout.weight(.medium) */
  cursor: pointer;
  transition: border-color 240ms var(--ease-out-soft);
}

.still-btn:hover { border-color: var(--on-field); }

.still-btn:focus-visible {
  outline: 2px solid var(--field-gold);
  outline-offset: 3px;
}

/* the button is hidden in the markup and revealed by javascript only once
   dialog.showModal is proven to exist. a door that cannot open is never drawn. */
.still-btn[hidden] { display: none; }


/* ───────────────────────────────────────────────────────────────────────────
   THE INSTANT — the app's own stillness, running on the page

   the room goes #171510. one gold light breathes the app's breath — four in,
   one held, six out — five whole times, so it always ends on a completed
   exhale. then it fades to one real line of the Course and holds it in the
   dark for nine seconds before it lets You go.

   no timer. no ring. no count. no chime. no "well done." You cannot fail at
   it, and You cannot finish it. it closes the moment You want it to.
─────────────────────────────────────────────────────────────────────────── */

#instant {
  width: 100%;  max-width: 100%;
  height: 100%; max-height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--field-hi);
  color: var(--on-field);
  overscroll-behavior: contain;
  opacity: 0;
  transition:
    opacity 800ms var(--ease-out-soft),   /* the app's 0.8s dissolve, exactly */
    display 800ms allow-discrete,
    overlay 800ms allow-discrete;
}

#instant[open] {
  display: grid;
  place-items: center;
  opacity: 1;
  transition-duration: 700ms;
}

@starting-style { #instant[open] { opacity: 0; } }

#instant::backdrop { background: var(--field-hi); }

/* the native scroll lock — the page keeps its place underneath */
body:has(#instant[open]) { overflow: hidden; }

.instant__close {
  position: absolute;
  top: 8px;
  right: 8px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 50%;
  color: var(--on-field-quiet);
  opacity: 0.7;                          /* 4.05:1 on the room — measured.
                                            the app draws it at 0.55 → 2.97:1,
                                            which is under the floor.          */
  cursor: pointer;
  transition: opacity 240ms var(--ease-out-soft);
}

.instant__close:hover { opacity: 1; }

.instant__close:focus-visible {
  opacity: 1;
  outline: 2px solid var(--field-gold);
  outline-offset: 2px;
}

.instant__close svg { width: 20px; height: 20px; }

/* the light and the line share one cell: the line arrives where the light was */
.instant__light,
.instant__rest { grid-area: 1 / 1; }

.instant__light {
  width: min(78vmin, 560px);
  aspect-ratio: 1;
  border-radius: 50%;
  /* the app: RadialGradient(accent @ .30 + .20·fullness → accent @ .02) */
  background: radial-gradient(circle closest-side,
    rgba(201, 168, 96, 0.50) 0%,
    rgba(201, 168, 96, 0.02) 100%);

  /* the resting end of the breath — and the animation's own last frame, so
     when the five breaths finish there is nothing to jump back to. */
  transform: scale(0.62);
  opacity: 0.60;

  animation: instant-breath var(--breath) var(--ease-breath) 5;
  transition: opacity 1100ms var(--ease-out-soft);
  will-change: transform, opacity;
}

/* scale 0.62 → 1.00 is the app's restedScale → fullScale. opacity 0.60 → 1.00
   multiplies the authored 0.50 centre down to 0.30 — the app's exact alpha
   ramp, delivered on compositor-only properties. */
@keyframes instant-breath {
  0%       { transform: scale(0.62); opacity: 0.60; }   /*  0s — fully exhaled */
  36.3636% { transform: scale(1);    opacity: 1;    }   /*  4s — full inhale   */
  45.4545% { transform: scale(1);    opacity: 1;    }   /*  5s — the held beat */
  100%     { transform: scale(0.62); opacity: 0.60; }   /* 11s — exhaled again */
}

/* the closing line: one real idea-title of the Workbook, and its lesson */
.instant__rest {
  max-width: min(var(--measure), 88vw);
  padding: 0 1.5rem;
  text-align: center;
  opacity: 0;
  transition: opacity 1100ms var(--ease-out-soft);
}

#instant.is-resting .instant__rest { opacity: 1; }

/* when the line arrives, the pacer steps back (it is only ever visible under
   reduced motion, where it was the breath's stand-in) */
#instant.is-resting .instant__breath {
  opacity: 0;
  transition: opacity 1100ms var(--ease-out-soft);
}

.instant__line {
  font-family: var(--serif);
  font-size: clamp(1.375rem, 1.1rem + 1.2vw, 1.875rem);
  line-height: 1.5;
  color: var(--on-field);                /* 14.81:1 — measured                */
}

.instant__ref {
  margin-top: 1.25rem;
  font-size: 0.875rem;
  letter-spacing: 0.08em;
  color: var(--on-field-quiet);          /*  7.04:1 — measured                */
}

/* the pacer. under normal motion the light is the pacer and this is read only
   by a screen reader; when motion is refused it becomes the visible one. */
.instant__breath {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ───────────────────────────────────────────────────────────────────────────
   motion — restrained, and it honours a request for stillness

   The fade-in is progressive enhancement, and it can never strand content.
   Every passage is VISIBLE BY DEFAULT — with no javascript, with a failed
   observer, or with reduced-motion on, it is simply present from first paint.
   The hidden-then-revealed state is armed only by `html.reveal-on`, a class
   javascript adds ONLY once a live IntersectionObserver is already watching
   (and a timed backstop reveals everything regardless). So the light of the
   words can dim only where there is a mechanism certain to bring it back.
─────────────────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: no-preference) {
  html.reveal-on [data-reveal] {
    opacity: 0;
    transform: translateY(14px);
    transition:
      opacity   560ms var(--ease-out-soft),
      transform 560ms var(--ease-out-soft);
  }
  html.reveal-on [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }
}

/* stillness does not shout: kill the ambient breath, hold the light at full */
@media (prefers-reduced-motion: reduce) {
  .hero__glow {
    animation: none;
    opacity: 1;
  }

  /* the instant is the same gift, not a lesser one. the light does not pulse —
     it holds at the app's own steady value, glow(fullness: 0.82). and the
     breath sentence, silent under motion, becomes the visible pacer: one text
     node, two presentations. the line still comes, and it still holds. */
  .instant__light {
    animation: none;
    transform: scale(0.9316);
    opacity: 0.928;
  }

  .instant__breath {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip-path: none;
    white-space: normal;

    grid-area: 1 / 1;
    align-self: end;
    max-width: min(var(--measure), 88vw);
    padding: 0 1.5rem clamp(1rem, 6vh, 3rem);
    text-align: center;
    font-size: 1rem;
    line-height: 1.7;
    color: var(--on-field-quiet);        /* 7.04:1 on the room — measured */
    text-wrap: pretty;
  }
}
