/* ============================================================
   Holy Land Prayer : homepage
   Mobile first. Every value comes from tokens.css.
   ============================================================ */

/* ---------- 1. Reset and base ------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--s-4));
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--t-base);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video, iframe { display: block; max-width: 100%; }
img { height: auto; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--lh-head);
  letter-spacing: var(--track-head);
  margin: 0;
  color: var(--navy);
  text-wrap: balance;
}

p { margin: 0 0 var(--s-4); max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

a { color: var(--navy); text-underline-offset: 0.18em; }
a:hover { color: var(--navy-deep); }

ul, ol { margin: 0; padding: 0; list-style: none; }
figure, blockquote { margin: 0; }   /* the UA default is 1em 40px, which quietly ate 80px out of every card */

button, input, textarea, select { font: inherit; color: inherit; }

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

::selection { background: var(--gold); color: var(--navy-deep); }

.skip {
  position: absolute; left: var(--s-4); top: var(--s-4);
  transform: translateY(-200%);
  z-index: 200;
  background: var(--navy); color: var(--on-dark);
  padding: var(--s-3) var(--s-5);
  border-radius: var(--radius);
  text-decoration: none; font-weight: 600;
}
.skip:focus { transform: translateY(0); color: var(--on-dark); }

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

/* ---------- 2. Layout primitives ---------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--narrow { max-width: var(--wrap-narrow); }

/* Grid items default to min-width:auto, so one wide child (an image, a
   long token) can push a track past its container and get clipped. This
   is the fix, applied once rather than hunted per component. */
.hero__grid > *, .steps > *, .offer > *, .quotes > *, .cats > *,
.bumps > *, .footer__grid > *, .footer__cols > *, .timeline > * { min-width: 0; }

.section { padding-block: var(--section-y); }
.section--stone { background: var(--stone); }
.section--dark { background: var(--navy-deep); color: var(--on-dark); }
.section--dark h2, .section--dark h3 { color: var(--on-dark); }

.section-head { margin-bottom: var(--s-7); }
.section-head p { color: var(--ink-muted); font-size: var(--t-lead); }
.section--dark .section-head p { color: var(--on-dark-muted); }

/* the recurring label: small caps, wide tracking, gold tick */
.eyebrow {
  display: flex; align-items: center; gap: var(--s-3);
  font-family: var(--font-ui);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--navy);
  margin: 0 0 var(--s-4);
  max-width: none;
}
.eyebrow::before {
  content: ""; flex: none;
  width: 26px; height: 2px; background: var(--gold);
}
.section--dark .eyebrow { color: var(--gold); }
.eyebrow--plain::before { display: none; }

h2.h-xl { font-size: var(--t-xl); }
h2.h-2xl { font-size: var(--t-2xl); }

.lead { font-size: var(--t-lead); color: var(--ink-muted); }
.fine { font-size: var(--t-sm); color: var(--ink-muted); line-height: 1.5; }
.section--dark .fine, .footer .fine, .scripture .fine { color: var(--on-dark-muted); }

/* ---------- 3. Buttons -------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-3);
  min-height: 52px;
  padding: var(--s-3) var(--s-6);
  border: 2px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease), transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn--gold {
  background: var(--gold);
  color: var(--navy-deep);
  border-color: var(--gold);
  box-shadow: 0 2px 0 rgba(22, 22, 63, 0.18);
}
.btn--gold:hover { background: var(--gold-hover); border-color: var(--gold-hover); color: var(--navy-deep); }

.btn--navy { background: var(--navy); color: var(--paper); border-color: var(--navy); }
.btn--navy:hover { background: var(--navy-deep); border-color: var(--navy-deep); color: var(--paper); }

.btn--ghost { background: transparent; color: var(--navy); border-color: var(--line-strong); }
.btn--ghost:hover { border-color: var(--navy); background: rgba(32, 52, 111, 0.05); }

.btn--block { width: 100%; }
.btn--lg { min-height: 60px; font-size: var(--t-base); padding-inline: var(--s-7); }

/* ---------- 4. Header --------------------------------------------- */

.header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(251, 248, 243, 0.94);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.header__inner {
  height: var(--header-h);
  display: flex; align-items: center; gap: var(--s-4);
}

.brand { display: flex; align-items: center; gap: var(--s-3); text-decoration: none; margin-right: auto; }
.brand__mark { width: 40px; height: 40px; flex: none; }
.brand__text { display: flex; flex-direction: column; line-height: 1; }
.brand__name {
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.0625rem; color: var(--navy); letter-spacing: 0.01em;
}
.brand__place {
  font-family: var(--font-ui); font-size: 0.625rem; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-muted);
  margin-top: 3px;
}

.nav { display: none; }
.nav ul { display: flex; align-items: center; gap: var(--s-5); }
.nav a {
  font-size: var(--t-sm); font-weight: 500; color: var(--ink);
  text-decoration: none; padding-block: var(--s-2);
  border-bottom: 2px solid transparent;
}
.nav a:hover { color: var(--navy); border-bottom-color: var(--gold); }

.header .btn { min-height: 44px; padding-inline: var(--s-5); }
.header__cta { display: none; }

.navtoggle {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: 44px; padding: var(--s-2) var(--s-3);
  background: transparent; border: 1px solid var(--line-strong);
  border-radius: var(--radius); cursor: pointer;
  font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--navy);
}
.navtoggle svg { width: 18px; height: 18px; }

.header__mobile {
  display: none;
  border-top: 1px solid var(--line);
  padding: var(--s-4) 0 var(--s-6);
}
.header__mobile.is-open { display: block; }
.header__mobile ul { display: grid; gap: var(--s-1); margin-bottom: var(--s-5); }
.header__mobile a {
  display: block; padding: var(--s-3) 0;
  font-size: var(--t-base); font-weight: 500; color: var(--ink);
  text-decoration: none; border-bottom: 1px solid var(--line);
}

@media (min-width: 960px) {
  .nav, .header__cta { display: block; }
  .navtoggle, .header__mobile { display: none !important; }
  .brand__mark { width: 48px; height: 48px; }
  .brand__name { font-size: 1.1875rem; }
}

/* ---------- 5. Hero ------------------------------------------------ */

/* ---------------------------------------------------------------
   THE NAVE

   Five layers, bottom to top:
     0  .hero__ground   the film, or its poster frame, heavily sunk
     1  .hero::before   the light: bloom, vault, shaft, floor
     2  .hero__mote     large-scale mottle, so the field is uneven
     3  .hero::after    fine grain, so it is not plastic
     4  .wrap           the content

   The point of separating the light from the grain is that the
   light can breathe on a 19s cycle while the grain stays still.
   Grain that moves is snow, and snow is a different website.
--------------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
  background: var(--navy-deep);
  background-image: var(--nave-base);
  color: var(--on-dark);
  overflow: hidden;
  padding-block: var(--s-8) var(--s-9);
}

/* The film sits under everything, sunk far enough that it is the
   room rather than the subject. It is never the thing you look at;
   it is the reason the navy is not dead. */
/* The film is a band at the top, not a stretched full-height plate.
   Two reasons. Physically, the light and the room are above you in a
   nave and the floor is dark, so a band that dissolves downward is
   what the space actually does. Practically, the hero runs past
   1500px tall on a laptop and covering that with a 16:9 frame means
   a 2x upscale of a crop nobody can read. Banding it keeps the film
   near its native scale and lets it die into the navy exactly where
   the content gets dense. */
.hero__ground {
  position: absolute; left: 0; right: 0; top: 0; z-index: 0;
  height: clamp(420px, 82vh, 940px);
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom,
      rgba(0,0,0,1) 0%, rgba(0,0,0,1) 38%, rgba(0,0,0,0.55) 64%, rgba(0,0,0,0) 96%);
  mask-image: linear-gradient(to bottom,
      rgba(0,0,0,1) 0%, rgba(0,0,0,1) 38%, rgba(0,0,0,0.55) 64%, rgba(0,0,0,0) 96%);
}
.hero__ground img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
  /* Desaturated and darkened so it reads as stone in low light and
     never competes with the type sitting on it. */
  filter: saturate(0.66) brightness(0.62) contrast(1.05);
  opacity: 0.55;
  transform: scale(1.005);
  will-change: transform;
}
/* CYCLE 1, the room. 3.4 percent over 74 seconds, alternating, so it
   never resets and you can never catch it moving. This is not a Ken
   Burns push; at this rate the image travels about one pixel every two
   seconds. It exists so the plate is not dead, nothing more. */
@media (prefers-reduced-motion: no-preference) {
  .hero__ground img { animation: nave-room 74s var(--ease-breath) infinite alternate; }
}
@keyframes nave-room {
  from { transform: scale(1.005); }
  to   { transform: scale(1.039); }
}

/* The reading scrim.

   Measured, not guessed. With the film at full strength the gold
   eyebrow came out at 2.47:1 and the subhead at 4.28:1 against the
   brightest pixels of the limestone behind them. Type over a
   photograph always needs this; the only question is where to spend
   it. So the scrim is directional: heavy down the left column where
   every piece of hero type lives, gone by the right third where the
   prints sit on their own white mats, plus a band under the header.
   The film stays fully visible exactly where nothing has to be read. */
/* Note this sits on the ground element, not on the image, so the
   image can breathe underneath it while the scrim stays pinned. A
   scrim that drifts with its subject stops being a scrim. */
.hero__ground::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background:
    linear-gradient(to bottom,
      rgba(6, 8, 22, 0.82) 0%,
      rgba(6, 8, 22, 0.46) 11%,
      rgba(6, 8, 22, 0.14) 25%,
      rgba(6, 8, 22, 0) 40%),
    linear-gradient(96deg,
      rgba(6, 8, 22, 0.90) 0%,
      rgba(6, 8, 22, 0.84) 24%,
      rgba(6, 8, 22, 0.60) 40%,
      rgba(6, 8, 22, 0.22) 58%,
      rgba(6, 8, 22, 0.04) 74%,
      rgba(6, 8, 22, 0) 88%);
}
/* One column on a phone, so the type is over the whole width and the
   scrim has to be flat rather than directional. */
@media (max-width: 899px) {
  .hero__ground::after {
    background:
      linear-gradient(to bottom,
        rgba(6, 8, 22, 0.86) 0%,
        rgba(6, 8, 22, 0.66) 18%,
        rgba(6, 8, 22, 0.58) 46%,
        rgba(6, 8, 22, 0.62) 100%);
  }
}

/* The light itself. Sits over the film, which is what makes the
   film feel lit from inside the page rather than pasted in. */
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background:
    var(--nave-bloom),
    var(--nave-vault),
    var(--nave-falloff);
  pointer-events: none;
  will-change: opacity;
}

/* CYCLE 3, the shaft. The Rotunda oculus, on its own layer so it can
   travel independently of the candle rank below it. 37 seconds against
   the bloom's 19 and the mottle's 61: three periods that share no
   common factor, so the combined field takes over six hours to repeat.
   That is the whole trick. Any two cycles on related periods start
   visibly pulsing together within a minute. */
.hero__shaft {
  position: absolute; inset: 0 -14%; z-index: 2;
  pointer-events: none;
  background: var(--nave-shaft);
  will-change: transform;
}
@media (prefers-reduced-motion: no-preference) {
  .hero__shaft { animation: nave-shaft 37s var(--ease-breath) infinite alternate; }
}
@keyframes nave-shaft {
  from { transform: translate3d(-3.2%, 0, 0); }
  to   { transform: translate3d(3.2%, 0, 0); }
}

/* Large-scale mottle. Two noise scales is the whole trick: this one
   at baseFrequency 0.009 gives cloud-sized unevenness, the grain
   below at 0.85 gives film. One alone always looks synthetic. */
/* CYCLE 4, the air. 61 seconds. Inset far enough that the drift can
   never expose an edge. translate3d, not background-position, so this
   is a compositor move and costs no paint. */
.hero__mote {
  position: absolute; inset: -14%; z-index: 3;
  pointer-events: none;
  will-change: transform;
  opacity: 0.5; mix-blend-mode: soft-light;
  /* feColorMatrix saturate 0 is load bearing: feTurbulence writes an
     independent random value per channel, so without it this is coloured
     noise and it lays faint magenta and green blotches over the navy.
     Grain is luminance, not colour. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='700' height='700'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.009' numOctaves='4' seed='7'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='700' height='700' filter='url(%23m)'/%3E%3C/svg%3E");
  background-size: 780px 780px;
}
@media (prefers-reduced-motion: no-preference) {
  .hero__mote { animation: nave-air 61s linear infinite alternate; }
}
@keyframes nave-air {
  from { transform: translate3d(-2.4%, -1.6%, 0); }
  to   { transform: translate3d(2.4%, 1.6%, 0); }
}

/* film grain, so the navy field is not a flat plastic block */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  opacity: 0.30; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}
.hero > .wrap { position: relative; z-index: 5; }

/* CYCLE 2, the candle rank. 19 seconds, opacity only, 0.90 to 1.00, which
   is under a tenth of a stop. You should never catch it moving; you
   should only notice that the page is not dead. Opacity on a single
   composited layer, so it costs nothing per frame. */
@media (prefers-reduced-motion: no-preference) {
  .hero::before { animation: nave-breathe var(--cycle-flame) var(--ease-breath) infinite; }
}
@keyframes nave-breathe {
  0%, 100% { opacity: 0.90; }
  50%      { opacity: 1; }
}

.hero__grid { display: grid; gap: var(--s-7); }

.hero .eyebrow { color: var(--gold); }
.hero h1 {
  font-size: var(--t-2xl);
  line-height: var(--lh-tight);
  color: var(--on-dark);
  margin-bottom: var(--s-5);
}
.hero__sub {
  font-size: var(--t-lead);
  color: var(--on-dark-muted);
  max-width: 33rem;
}

/* ---------------------------------------------------------------
   THE TRUST NUMBER

   The strongest fact they own, stated for the first time. It gets
   the one piece of real glass on the page: a lamp vitrine, warm at
   the shoulder, cooling to the foot, lit along the top lip. It is
   an object holding a number, not a stat card.
--------------------------------------------------------------- */
.trust {
  position: relative;
  margin: var(--s-6) 0;
  padding: var(--s-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--lamp-edge);
  background-image: var(--lamp-sheen), var(--lamp-fill);
  box-shadow:
    inset 0 1px 0 var(--lamp-rim),
    inset 0 -1px 0 var(--lamp-base),
    var(--lamp-cast);
  overflow: hidden;
}
/* The gold seam at the shoulder, where a lamp is mounted. It is the
   only hard edge on the panel and it stops the glass floating. */
.trust::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg,
      rgba(248, 166, 27, 0) 0%,
      rgba(248, 166, 27, 0.85) 18%,
      rgba(255, 200, 110, 0.95) 46%,
      rgba(248, 166, 27, 0.6) 74%,
      rgba(248, 166, 27, 0) 100%);
}
.trust__n {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-num);
  font-weight: 600;
  line-height: 0.92;
  letter-spacing: -0.02em;
  color: var(--gold);
  /* tabular so the count cannot change the layout width while it
     runs, which is the thing that makes counters look like slot
     machines */
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.trust__label {
  display: block;
  margin-top: var(--s-3);
  font-size: var(--t-lead);
  color: var(--on-dark);
  max-width: 26rem;
}
.trust__note {
  display: block; margin-top: var(--s-2);
  font-size: var(--t-sm); color: var(--on-dark-muted); max-width: 30rem;
}

/* The number is told, then explained. The label and the note hold
   back until the count has landed, so the sequence reads as a
   sentence rather than a block that faded in. */
.js .trust__label, .js .trust__note { opacity: 0; }
.trust.is-told .trust__label,
.trust.is-told .trust__note {
  opacity: 1;
  transition: opacity 700ms var(--ease-settle);
}
.trust.is-told .trust__note { transition-delay: 260ms; }

/* One breath as the number settles, and only one. Not a pulse: it
   brightens once, the way a wick catches, and then holds. */
.trust.is-told .trust__n {
  animation: told-catch 1400ms var(--ease-breath) 1;
}
@keyframes told-catch {
  0%   { text-shadow: 0 0 0 rgba(248, 166, 27, 0); }
  38%  { text-shadow: 0 0 26px rgba(255, 190, 90, 0.42); }
  100% { text-shadow: 0 0 0 rgba(248, 166, 27, 0); }
}

/* the prayer box: the site's one job */
.prayerbox {
  background: var(--paper);
  color: var(--ink);
  border-radius: var(--radius-lg);
  padding: var(--s-5);
  box-shadow: var(--shadow-dark);
  border-top: 4px solid var(--gold);
}
.prayerbox__label {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--navy);
  margin-bottom: var(--s-2);
}
.prayerbox textarea {
  display: block; width: 100%;
  min-height: 122px;
  padding: var(--s-3) var(--s-4);
  background: #fff;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius);
  font-family: var(--font-ui);
  font-size: var(--t-base);
  line-height: 1.55;
  resize: vertical;
}
.prayerbox textarea::placeholder { color: #6E6960; }
.prayerbox textarea:focus { border-color: var(--navy); }
.prayerbox .btn { margin-top: var(--s-4); }
.prayerbox__help {
  margin: var(--s-3) 0 0;
  font-size: var(--t-sm); color: var(--ink-muted); line-height: 1.5;
  max-width: none;
}
.prayerbox__help strong { color: var(--ink); font-weight: 600; }

.assure {
  display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5);
  margin-top: var(--s-5);
  font-size: var(--t-sm); color: var(--on-dark-muted);
}
.assure li { display: flex; align-items: center; gap: var(--s-2); }
.assure svg { width: 16px; height: 16px; flex: none; color: var(--gold); }

/* The film is the room now, not a card in it. All that survives of
   the old player is the credit, because "we filmed this" is the
   claim that mattered and the YouTube frame was never carrying it. */
.filmcredit {
  display: inline-flex; align-items: center; gap: var(--s-3);
  margin-top: var(--s-5);
  padding: var(--s-2) var(--s-4) var(--s-2) var(--s-3);
  border-radius: 999px;
  border: 1px solid var(--lamp-edge);
  background-image: var(--lamp-fill);
  box-shadow: inset 0 1px 0 var(--lamp-rim), inset 0 -1px 0 var(--lamp-base);
  font-size: var(--t-xs); font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--on-dark);
  max-width: none;
}
.filmcredit .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--gold); flex: none;
  box-shadow: 0 0 0 3px rgba(248, 166, 27, 0.18);
}
/* The dot is a lit wick, not a recording light. Very slow, very
   small, and it stops entirely under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .filmcredit .dot { animation: wick 5.5s var(--ease-breath) infinite; }
}
@keyframes wick {
  0%, 100% { box-shadow: 0 0 0 3px rgba(248, 166, 27, 0.14); }
  50%      { box-shadow: 0 0 0 5px rgba(248, 166, 27, 0.05); }
}

/* ---------------------------------------------------------------
   PROOF, above the fold: prints, laid down

   These are photographs of physical objects, so they are presented
   as physical objects: a warm mat, a real cast shadow, and a small
   rotation off square. They arrive by being laid down, one after
   the other, which is the one place on the page where the motion
   is describing what the business actually does.
--------------------------------------------------------------- */
.evidence { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); }
.evidence__item {
  background: linear-gradient(168deg, #FDFBF7 0%, var(--paper) 58%, #F3EDE3 100%);
  padding: var(--s-2) var(--s-2) var(--s-4);
  border-radius: var(--radius-sm);
  /* two shadows: a tight contact shadow where the print meets the
     surface, and a long soft one for the height. One shadow always
     reads as a CSS box. */
  box-shadow:
    0 1px 2px rgba(4, 7, 20, 0.5),
    0 18px 40px rgba(4, 7, 20, 0.46);
  transform: rotate(-1.1deg);
  transition: transform var(--dur-slow) var(--ease-settle),
              box-shadow var(--dur-slow) var(--ease-settle);
}
.evidence__item:nth-child(2) { transform: rotate(1.3deg); }
.evidence__item:hover, .evidence__item:nth-child(2):hover {
  transform: rotate(0deg) translateY(-2px);
  box-shadow: 0 1px 2px rgba(4, 7, 20, 0.4), 0 26px 54px rgba(4, 7, 20, 0.5);
}
.evidence__item img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: 2px; background: var(--stone-deep);
}

/* The laying down. Starts higher, larger and further off square,
   and settles. No overshoot: a print does not bounce. The stagger
   between the two is what makes it read as a pair of hands rather
   than a transition. */
.js .evidence__item { opacity: 0; transform: translateY(-14px) rotate(-4.5deg) scale(1.035); }
.js .evidence__item:nth-child(2) { transform: translateY(-18px) rotate(5deg) scale(1.035); }
.evidence.is-in .evidence__item {
  opacity: 1; transform: rotate(-1.1deg);
  transition: opacity 520ms var(--ease-settle), transform var(--dur-settle) var(--ease-settle);
}
.evidence.is-in .evidence__item:nth-child(2) {
  transform: rotate(1.3deg);
  transition-delay: 190ms;   /* the second print is laid after the first */
}
.evidence__cap {
  display: block; margin-top: var(--s-3); padding-inline: var(--s-2);
  font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-muted); line-height: 1.45;
}
.evidence__cap b { display: block; color: var(--navy); letter-spacing: 0.06em; }

.hero__proofnote {
  margin-top: var(--s-4);
  font-size: var(--t-sm); color: var(--on-dark-muted); max-width: none;
}

.minquote {
  margin: var(--s-5) 0 0;
  padding-left: var(--s-5);
  border-left: 2px solid var(--gold);
}
.minquote p {
  margin: 0;
  font-family: var(--font-display); font-style: italic;
  font-size: var(--t-lead); line-height: 1.42; color: var(--on-dark);
  max-width: none;
}
.minquote figcaption {
  margin-top: var(--s-3);
  font-size: var(--t-xs); font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--gold);
}

/* Mobile hero order. The two columns collapse into one flow so the
   proof photographs land in the first screen, above the fold, which is
   the whole point of moving them out of the middle of the page. */
@media (max-width: 899px) {
  .hero { padding-block: var(--s-6) var(--s-8); }
  .hero__grid { gap: var(--s-5); }
  .evidence { gap: var(--s-3); }
  .evidence__item { padding: 6px 6px 12px; }
  .evidence__item img { aspect-ratio: 1 / 1; }
  /* display:contents promotes the grandchildren to grid items, so the
     min-width reset has to follow them down a level */
  .hero__main, .hero__aside { display: contents; }
  .hero__main > *, .hero__aside > * { min-width: 0; }

  .hero .eyebrow      { order: 1; margin-bottom: 0; font-size: 0.75rem; letter-spacing: 0.1em; }
  .hero h1            { order: 2; margin-bottom: 0; }
  .trust              { order: 3; margin: 0; padding: var(--s-4); }
  .evidence           { order: 4; }
  .hero__proofnote    { order: 5; margin-top: calc(var(--s-3) - var(--s-5)); }
  .hero__sub          { order: 6; }
  .prayerbox          { order: 7; }
  .filmcredit         { order: 8; margin-top: 0; justify-self: start; }
  .minquote           { order: 9; margin-top: 0; }
  .assure             { order: 10; margin-top: 0; }

  .trust__n { line-height: 0.95; }
  .trust__label { margin-top: var(--s-2); font-size: var(--t-base); }
  .trust__note { font-size: 0.8125rem; }
}

@media (min-width: 900px) {
  .hero { padding-block: var(--s-9) var(--s-9); }
  .hero__grid {
    grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
    gap: var(--s-8);
    align-items: start;
  }
  .hero__aside { display: grid; gap: var(--s-5); position: sticky; top: calc(var(--header-h) + var(--s-5)); }
  .prayerbox { padding: var(--s-6); }
}

/* ---------- 6. Steps ---------------------------------------------- */

.steps { display: grid; gap: var(--s-6); counter-reset: step; }
.step { position: relative; }
.step__img {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--stone-deep);
  box-shadow: var(--shadow-sm);
}
.step__img img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.step__n {
  position: absolute; left: var(--s-4); top: var(--s-4); z-index: 2;
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--gold); color: var(--navy-deep);
  font-family: var(--font-display); font-size: 1.25rem; font-weight: 700;
  box-shadow: 0 3px 10px rgba(22, 22, 63, 0.35);
}
.step h3 { font-size: var(--t-md); margin: var(--s-4) 0 var(--s-2); }
.step p { color: var(--ink-muted); }

.timeline {
  margin-top: var(--s-7);
  display: grid; gap: var(--s-4);
  padding: var(--s-5);
  background: var(--stone);
  border-left: 3px solid var(--gold);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.timeline li { display: flex; gap: var(--s-4); align-items: baseline; }
.timeline b {
  font-family: var(--font-display); font-size: var(--t-md);
  color: var(--navy); flex: none; min-width: 4.5rem;
}
.timeline span { color: var(--ink-muted); font-size: var(--t-sm); }

@media (min-width: 760px) {
  .steps { grid-template-columns: repeat(3, 1fr); gap: var(--s-5); }
  .timeline { grid-template-columns: repeat(3, 1fr); gap: var(--s-5); padding: var(--s-6); }
  .timeline li { flex-direction: column; gap: var(--s-1); }
}

/* ---------- 7. Offer ----------------------------------------------- */

.offer { display: grid; gap: var(--s-6); }

.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.card__head {
  padding: var(--s-5);
  background: var(--navy-deep);
  color: var(--on-dark);
  display: flex; flex-wrap: wrap; gap: var(--s-4);
  align-items: baseline; justify-content: space-between;
}
.card__head h3 { color: var(--on-dark); font-size: var(--t-lg); margin: 0; }
.card__head .price {
  font-family: var(--font-display); font-size: var(--t-lg); font-weight: 600;
  color: var(--gold); white-space: nowrap;
}
.card__body { padding: var(--s-5); }

.includes { display: grid; gap: var(--s-3); }
.includes li {
  display: grid; grid-template-columns: 22px 1fr; gap: var(--s-3);
  align-items: start; font-size: var(--t-base); color: var(--ink);
}
.includes svg { width: 22px; height: 22px; color: var(--navy); margin-top: 2px; }

/* the three bumps: additions to a sacred act, not upsells */
.bumps { display: grid; gap: var(--s-4); }
.bump {
  position: relative;
  display: grid; grid-template-columns: auto 1fr;
  gap: var(--s-4);
  padding: var(--s-4);
  background: #fff;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.bump:hover { border-color: var(--navy); }
.bump:has(input:checked) {
  border-color: var(--navy);
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--navy), var(--shadow-sm);
}
.bump:has(input:focus-visible) { outline: 3px solid var(--focus); outline-offset: 3px; }

.bump input {
  appearance: none; -webkit-appearance: none;
  width: 26px; height: 26px; margin: 2px 0 0;
  border: 2px solid var(--line-strong); border-radius: var(--radius-sm);
  background: #fff; cursor: pointer; flex: none;
  display: grid; place-content: center;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.bump input::after {
  content: ""; width: 13px; height: 8px;
  border-left: 2.5px solid var(--navy-deep); border-bottom: 2.5px solid var(--navy-deep);
  transform: rotate(-45deg) scale(0); transform-origin: center;
  transition: transform 160ms var(--ease);
  margin-top: -3px;
}
.bump input:checked { background: var(--gold); border-color: var(--gold); }
.bump input:checked::after { transform: rotate(-45deg) scale(1); }

.bump__title {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-2) var(--s-3);
  font-family: var(--font-display); font-size: var(--t-md); font-weight: 600;
  color: var(--navy); line-height: 1.25;
}
.bump__price { font-family: var(--font-ui); font-size: var(--t-sm); font-weight: 700; color: var(--ink); letter-spacing: 0.02em; }
.bump__desc { margin: var(--s-2) 0 0; font-size: var(--t-sm); color: var(--ink-muted); line-height: 1.55; max-width: 36rem; }
.tag {
  display: inline-block;
  padding: 3px var(--s-2);
  background: var(--gold); color: var(--navy-deep);
  border-radius: 3px;
  font-family: var(--font-ui); font-size: 0.625rem; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
}

/* what the visitor typed in the hero, carried down to the checkout so the
   handoff is visible rather than implied */
.echo {
  margin-top: var(--s-5);
  padding: var(--s-4);
  background: var(--stone);
  border-left: 3px solid var(--gold);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.echo__label {
  display: block;
  font-size: var(--t-xs); font-weight: 700; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--ink-muted);
}
.echo__text {
  margin: var(--s-2) 0 var(--s-2);
  font-family: var(--font-display); font-size: var(--t-base);
  line-height: 1.5; color: var(--ink); max-width: none;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.echo__edit { font-size: var(--t-sm); font-weight: 600; }

.total {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-4);
  margin-top: var(--s-5);
  padding-top: var(--s-5);
  border-top: 2px solid var(--navy);
}
.total__label {
  font-family: var(--font-display); font-size: var(--t-md); font-weight: 600; color: var(--navy);
}
.total__val {
  font-family: var(--font-display); font-size: var(--t-xl); font-weight: 700;
  color: var(--navy); line-height: 1;
  font-variant-numeric: lining-nums tabular-nums;
}
.total__note { margin: var(--s-2) 0 0; }

.pay {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3);
  margin-top: var(--s-5); padding-top: var(--s-5); border-top: 1px solid var(--line);
}
.pay__chip {
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  font-size: var(--t-xs); font-weight: 600; color: var(--ink-muted);
  background: #fff;
}

.assurance-card {
  padding: var(--s-5);
  background: var(--navy-deep);
  color: var(--on-dark);
  border-radius: var(--radius-lg);
}
.assurance-card h3 { color: var(--gold); font-size: var(--t-md); margin-bottom: var(--s-3); }
.assurance-card p { color: var(--on-dark-muted); font-size: var(--t-sm); line-height: 1.6; }
.assurance-card p + p { margin-top: var(--s-3); }

@media (min-width: 900px) {
  .offer { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); align-items: start; }
  .card__body { padding: var(--s-6); }
  .card__head { padding: var(--s-5) var(--s-6); }
  .assurance-card { position: sticky; top: calc(var(--header-h) + var(--s-5)); }
}

.offer-divider {
  display: flex; align-items: center; gap: var(--s-4);
  margin: var(--s-6) 0 var(--s-5);
}
.offer-divider h4 {
  font-family: var(--font-display); font-size: var(--t-md); font-weight: 600;
  color: var(--navy); margin: 0; white-space: nowrap;
}
.offer-divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* ---------- 8. Testimonials ---------------------------------------- */

.quotes { display: grid; gap: var(--s-5); }
.quote {
  position: relative;
  padding: var(--s-6) var(--s-5) var(--s-5);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.quote::before {
  content: "\201C";
  position: absolute; top: -0.16em; left: var(--s-4);
  font-family: var(--font-display); font-size: 5rem; font-weight: 600;
  color: var(--gold); line-height: 1;
}
.quote blockquote { margin: 0; }
.quote p {
  font-family: var(--font-display);
  font-size: var(--t-lead); line-height: 1.5; color: var(--ink);
  max-width: none;
}
.quote figcaption {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3);
  margin-top: var(--s-4); padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}
.quote__name {
  font-size: var(--t-sm); font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--navy);
}
.quote__cat {
  font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-muted);
  padding: 3px var(--s-2); border: 1px solid var(--line-strong); border-radius: 3px;
}
.quote--feature { background: var(--navy-deep); border-color: var(--navy-deep); }
.quote--feature p { color: var(--on-dark); font-size: var(--t-md); }
.quote--feature figcaption { border-top-color: var(--on-dark-line); }
.quote--feature .quote__name { color: var(--gold); }
.quote--feature .quote__cat { color: var(--on-dark-muted); border-color: var(--on-dark-line); }

@media (min-width: 760px) {
  .quotes { grid-template-columns: repeat(2, 1fr); }
  .quote--feature { grid-column: 1 / -1; }
  .quote--feature p { font-size: var(--t-lg); line-height: 1.4; }
}

/* ---------- 9. Scripture band --------------------------------------- */

.scripture {
  position: relative;
  padding-block: var(--section-y);
  background: var(--navy-deep);
  overflow: hidden;
}
.scripture__bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0.55;
}
.scripture::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, rgba(22, 22, 63, 0.93) 0%, rgba(22, 22, 63, 0.79) 55%, rgba(22, 22, 63, 0.88) 100%);
}
.scripture .wrap { position: relative; z-index: 2; }
.scripture blockquote { margin: 0; max-width: 30rem; }
.scripture p {
  font-family: var(--font-display); font-style: italic; font-weight: 400;
  font-size: var(--t-xl); line-height: 1.28; color: var(--on-dark);
  letter-spacing: -0.01em; max-width: none;
}
.scripture cite {
  display: block; margin-top: var(--s-5);
  font-family: var(--font-ui); font-style: normal;
  font-size: var(--t-sm); font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--gold);
}

/* ---------- 10. Categories ----------------------------------------- */

.cats { display: grid; gap: var(--s-3); grid-template-columns: repeat(2, 1fr); }
.cat {
  display: flex; flex-direction: column; justify-content: space-between;
  gap: var(--s-5);
  min-height: 128px;
  padding: var(--s-4);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.cat:hover {
  border-color: var(--navy); transform: translateY(-2px);
  box-shadow: var(--shadow-sm);
}
.cat__name {
  font-family: var(--font-display); font-size: var(--t-md); font-weight: 600;
  color: var(--navy); line-height: 1.15;
}
.cat__n {
  display: block;
  font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-muted);
}
.cat__n b { color: var(--ink); font-variant-numeric: tabular-nums; }
.cat::after {
  content: ""; display: block; width: 22px; height: 2px; background: var(--gold);
  transition: width var(--dur) var(--ease);
}
.cat:hover::after { width: 40px; }

@media (min-width: 620px) { .cats { grid-template-columns: repeat(3, 1fr); } }

/* ---------- 11. Closing CTA ---------------------------------------- */

.closer { text-align: center; }
.closer h2 { font-size: var(--t-2xl); margin-bottom: var(--s-4); }
.closer p { margin-inline: auto; text-align: center; }
.closer .btn { margin-top: var(--s-6); }
.closer .eyebrow { justify-content: center; }

/* ---------- 12. Footer --------------------------------------------- */

.footer { background: var(--navy-deep); color: var(--on-dark-muted); padding-block: var(--s-8) var(--s-6); }
.footer a { color: var(--on-dark-muted); text-decoration: none; overflow-wrap: anywhere; }
.footer a:hover { color: var(--gold); text-decoration: underline; }
.footer h3 {
  font-family: var(--font-ui); font-size: var(--t-xs); font-weight: 700;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--on-dark); margin-bottom: var(--s-4);
}
.footer__grid { display: grid; gap: var(--s-7); }
.footer__cols { display: grid; gap: var(--s-6); grid-template-columns: repeat(2, 1fr); }
.footer li + li { margin-top: var(--s-2); }
.footer__brand { display: flex; gap: var(--s-4); align-items: flex-start; }
.footer__brand svg { width: 84px; height: 84px; flex: none; }
.footer__brand p { font-size: var(--t-sm); line-height: 1.6; }

/* the newsletter lives here, not in a modal over the prayer form */
.signup { display: grid; gap: var(--s-3); max-width: 26rem; }
.signup input {
  width: 100%; min-height: 48px;
  padding: var(--s-3) var(--s-4);
  background: rgba(251, 248, 243, 0.06);
  border: 1px solid var(--on-dark-line);
  border-radius: var(--radius);
  color: var(--on-dark); font-size: var(--t-sm);
}
.signup input::placeholder { color: #9AA1BC; }
.signup input:focus { border-color: var(--gold); background: rgba(251, 248, 243, 0.1); }

.footer__base {
  margin-top: var(--s-7); padding-top: var(--s-5);
  border-top: 1px solid var(--on-dark-line);
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5);
  justify-content: space-between; align-items: center;
  font-size: var(--t-sm);
}

@media (min-width: 900px) {
  .footer__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.55fr) minmax(0, 1.05fr); gap: var(--s-7); }
  .footer__cols { grid-template-columns: repeat(3, 1fr); }
}

/* ---------- 13. Motion --------------------------------------------- */

.js .reveal { opacity: 0; transform: translateY(18px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity 620ms var(--ease), transform 620ms var(--ease);
}
.reveal.is-in.d1 { transition-delay: 80ms; }
.reveal.is-in.d2 { transition-delay: 160ms; }
.reveal.is-in.d3 { transition-delay: 240ms; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal, .reveal.is-in { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* ================================================================
   17. DEPTH AND MOTION

   Added after the client's note that the first build was correct
   but boring. Everything here is either light, glass, or one of
   eight animations. The animations are enumerated so any one of
   them can be removed without touching the others.
   ================================================================ */

/* ---------- 17.1 Glass, and its degradation --------------------
   backdrop-filter is the only expensive thing in this file, so it
   is opt-in rather than opt-out: it is applied only where there is
   genuinely varied content behind the panel (the hero, over the
   film) and only on pointer devices wide enough to be a laptop.
   Everywhere else the gradient fill carries it alone, which is why
   the fill is tuned to be legible at zero blur.
---------------------------------------------------------------- */
@media (min-width: 900px) and (hover: hover) {
  .trust, .filmcredit {
    -webkit-backdrop-filter: blur(var(--lamp-blur)) saturate(1.15);
    backdrop-filter: blur(var(--lamp-blur)) saturate(1.15);
  }
}
/* No backdrop-filter support at all: deepen the fill so the panel
   still separates from the film behind it. */
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .trust {
    background-image: var(--lamp-sheen),
      linear-gradient(168deg,
        rgba(46, 44, 78, 0.86) 0%,
        rgba(34, 36, 76, 0.88) 40%,
        rgba(24, 26, 62, 0.92) 100%);
  }
}

/* ---------- 17.2 Light on the other dark bands -----------------
   The scripture band, the closing band and the footer are the same
   room as the hero, so they are lit the same way rather than being
   flat navy slabs. Weaker, because they are not the subject.
---------------------------------------------------------------- */
.section--dark, .footer {
  position: relative;
  isolation: isolate;
  background-image: var(--nave-base);
}
.section--dark::before, .footer::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  pointer-events: none;
  background: var(--nave-bloom), var(--nave-vault), var(--nave-falloff);
  opacity: 0.72;
}
/* The footer is a dense block of small muted links, and the shared
   bloom sits at 18 percent across and 84 percent down, which in a
   short band is directly behind the copyright line. Measured: it took
   the base line to 1.38:1 and the links to 3.38:1. The footer keeps
   the vault and the floor and loses the candle: light there was
   decoration and it was costing legibility. */
.footer::before {
  background:
    radial-gradient(64% 74% at 82% -14%,
      rgba(44, 76, 150, 0.30) 0%,
      rgba(30, 50, 106, 0.13) 38%,
      rgba(16, 26, 62, 0) 76%),
    linear-gradient(to bottom,
      rgba(4, 7, 18, 0) 0%,
      rgba(4, 7, 18, 0.22) 62%,
      rgba(4, 7, 18, 0.40) 100%);
  opacity: 1;
}
.section--dark > *, .footer > * { position: relative; z-index: 1; }
/* The closing band is the last thing before the footer, so its
   bloom is pushed to the centre: the page ends lit rather than
   fading out at one corner. */
.section--dark::before {
  background:
    radial-gradient(60% 62% at 50% 108%,
      rgba(255, 188, 92, 0.26) 0%,
      rgba(250, 166, 44, 0.15) 17%,
      rgba(232, 138, 30, 0.075) 34%,
      rgba(190, 106, 26, 0.03) 55%,
      rgba(140, 76, 22, 0) 100%),
    var(--nave-vault),
    var(--nave-falloff);
}

/* A gold seam on the offer card header, matching the trust lamp. */
.card__head { position: relative; }
.card__head::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg,
      rgba(248, 166, 27, 0) 0%, rgba(248, 166, 27, 0.9) 22%,
      rgba(255, 200, 110, 0.95) 50%, rgba(248, 166, 27, 0.7) 78%,
      rgba(248, 166, 27, 0) 100%);
}

/* ---------- 17.3 Header earns its state -----------------------
   Flat and transparent over the hero, then it gains its rule, its
   blur and its shadow once you have left the hero behind. A header
   that is always in its scrolled state is a header that never
   tells you anything.
---------------------------------------------------------------- */
/* The bar overlays the hero rather than sitting on a paper strip
   above it, so the nave reaches the very top of the viewport and the
   transparent state has something to be transparent over. The hero
   is pulled up by exactly the bar height and pads itself back out. */
.hero {
  margin-top: calc(var(--header-h) * -1);
  padding-top: calc(var(--s-8) + var(--header-h));
}
@media (min-width: 900px) {
  .hero { padding-top: calc(var(--s-9) + var(--header-h)); }
}
@media (max-width: 899px) {
  .hero { padding-top: calc(var(--s-6) + var(--header-h)); }
}
.header {
  background: rgba(251, 248, 243, 0);
  border-bottom-color: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transition: background 320ms var(--ease-settle),
              border-color 320ms var(--ease-settle),
              box-shadow 320ms var(--ease-settle);
}
.header.is-stuck {
  background: rgba(251, 248, 243, 0.93);
  border-bottom-color: var(--line);
  box-shadow: 0 1px 0 rgba(27, 29, 38, 0.03), 0 8px 24px rgba(27, 29, 38, 0.07);
  -webkit-backdrop-filter: blur(12px) saturate(1.4);
  backdrop-filter: blur(12px) saturate(1.4);
}
/* Over the hero the header sits on navy, so its contents invert.
   Without this the navy brand name is 1.4:1 on the hero field. */
.header:not(.is-stuck) .brand__name,
.header:not(.is-stuck) .navtoggle { color: var(--on-dark); }
.header:not(.is-stuck) .brand__place { color: var(--on-dark-muted); }
/* brand mark inversion now lives with the other utilities, 17.12 */
.header:not(.is-stuck) .nav a { color: var(--on-dark); }
.header:not(.is-stuck) .nav a:hover { color: #fff; }
.header:not(.is-stuck) .navtoggle { border-color: var(--on-dark-line); }
/* No-JS: the class never lands, so pin the solid state permanently
   rather than leaving pale type on a pale ground once you scroll. */
html:not(.js) .header {
  background: rgba(251, 248, 243, 0.93);
  border-bottom-color: var(--line);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

/* ---------- 17.4 Scripture: typographic timing ----------------
   The line is spoken, then attributed. A single fade on the whole
   block says nothing; holding the citation back by two thirds of a
   second is the difference between a quote and someone quoting.
---------------------------------------------------------------- */
.scripture__bg {
  transform: scale(1.055);
  transition: transform 2600ms var(--ease-settle), opacity 1600ms var(--ease-settle);
}
.js .scripture__bg { opacity: 0; }
.scripture.is-in .scripture__bg { opacity: 0.55; transform: scale(1); }

.js .scripture blockquote p, .js .scripture cite { opacity: 0; transform: translateY(10px); }
.scripture.is-in blockquote p {
  opacity: 1; transform: none;
  transition: opacity 900ms var(--ease-settle), transform 900ms var(--ease-settle);
  transition-delay: 240ms;
}
.scripture.is-in cite {
  opacity: 1; transform: none;
  transition: opacity 760ms var(--ease-settle), transform 760ms var(--ease-settle);
  transition-delay: 940ms;    /* the beat between the verse and its name */
}

/* ---------- 17.5 Testimonials: the mark, then the words -------
   The gold quotation mark arrives first and alone, which is the
   cheapest possible way to make a fade feel authored.
---------------------------------------------------------------- */
.js .quote::before { opacity: 0; transform: translateY(6px); }
.quote.is-in::before {
  opacity: 1; transform: none;
  transition: opacity 520ms var(--ease-settle), transform 520ms var(--ease-settle);
}
.js .quote blockquote, .js .quote figcaption { opacity: 0; }
.quote.is-in blockquote { opacity: 1; transition: opacity 640ms var(--ease-settle) 200ms; }
.quote.is-in figcaption { opacity: 1; transition: opacity 640ms var(--ease-settle) 340ms; }

/* ---------- 17.6 The offer, quietly ---------------------------
   Ticking a bump draws a gold rule down its left edge. It is the
   same gesture as the seam on the lamp and the card header, so the
   page has one way of saying "this is chosen".
---------------------------------------------------------------- */
.bump::before {
  content: ""; position: absolute; left: -1.5px; top: -1.5px; bottom: -1.5px;
  width: 3px; border-radius: 3px 0 0 3px;
  background: var(--gold);
  transform: scaleY(0); transform-origin: top;
  transition: transform 420ms var(--ease-settle);
}
.bump:has(input:checked)::before { transform: scaleY(1); }

/* The contribution total is the number the whole section is for, so
   it is never allowed to snap. It lifts one pixel and cross-fades. */
.total__val { display: inline-block; }
.total__val.is-changed { animation: total-settle 340ms var(--ease-settle) 1; }
@keyframes total-settle {
  0%   { opacity: 0; transform: translateY(4px); }
  100% { opacity: 1; transform: none; }
}

/* ---------- 17.7 Steps: the number strikes --------------------
   The gold disc scales up from nothing as the step arrives, so the
   sequence counts itself rather than appearing all at once.
---------------------------------------------------------------- */
.js .step__n { opacity: 0; transform: scale(0.72); }
.step.is-in .step__n {
  opacity: 1; transform: none;
  transition: opacity 420ms var(--ease-settle) 260ms, transform 520ms var(--ease-settle) 260ms;
}

/* ---------- 17.8 Reduced motion: static, complete, correct ----
   Not "shorter". Every element that this file starts in a hidden,
   offset, scaled or rotated state is put back to its finished
   state explicitly, and every keyframe animation is cancelled.
   A meaningful share of this audience has vestibular sensitivity
   and a meaningful share of the rest is on a device where the
   film should never have downloaded.
---------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .js .reveal, .reveal.is-in,
  .js .evidence__item, .evidence.is-in .evidence__item,
  .js .trust__label, .js .trust__note,
  .js .scripture blockquote p, .js .scripture cite,
  .js .quote::before, .js .quote blockquote, .js .quote figcaption,
  .js .step__n,
  .js .scripture__bg {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
  }
  /* the two prints keep their printed-object tilt, because that is
     composition rather than motion */
  .js .evidence__item, .evidence.is-in .evidence__item { transform: rotate(-1.1deg) !important; }
  .js .evidence__item:nth-child(2), .evidence.is-in .evidence__item:nth-child(2) { transform: rotate(1.3deg) !important; }
  .js .scripture__bg { opacity: 0.55 !important; }
  .hero::before, .hero__shaft, .hero__mote, .hero__ground img,
  .filmcredit .dot, .trust.is-told .trust__n { animation: none !important; }
  .hero__ground img { transform: scale(1.005) !important; }
  .hero__shaft, .hero__mote { transform: none !important; }
  .bump::before { transition: none !important; }
  .header { transition: none !important; }
}

/* ---------- 17.9 Category tiles: their own photographs ---------
   Nine dark navy-tinted crops of the real archive, replacing six
   pieces of generic stock served at 340x305 and stretched three
   times. The type stays WHITE and is never gold: gold measures
   2.48:1 on these fields and even a lightened gold reaches only
   3.15:1, failing the large-text threshold as well as body. The
   scrim below is belt and braces on white, which the fields
   already clear at 4.98:1 or better across 97 percent of pixels.
---------------------------------------------------------------- */
.cats { display: grid; gap: var(--s-3); grid-template-columns: repeat(2, 1fr); }
.cat {
  position: relative; display: block;
  aspect-ratio: 4 / 3;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--navy-deep);
  text-decoration: none;
  box-shadow: 0 1px 2px rgba(4, 7, 20, 0.16), 0 10px 26px rgba(4, 7, 20, 0.14);
  transition: box-shadow var(--dur-slow) var(--ease-settle);
}
.cat > picture { position: absolute; inset: 0; }
.cat img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  /* Slow, and inside a fixed frame, so it reads as a camera move
     rather than a card lifting off the page. */
  transition: transform 1100ms var(--ease-settle);
}
.cat::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  /* Measured: the gold-lamp tile is the brightest of the nine and the
     name came out at 4.54:1 on a 375 phone, which clears 4.5 by four
     hundredths. That is not a pass, it is a coin toss on another
     device. Deepened for real margin. */
  background: linear-gradient(to top,
      rgba(9, 10, 30, 0.88) 0%, rgba(9, 10, 30, 0.64) 32%,
      rgba(9, 10, 30, 0.30) 56%, rgba(9, 10, 30, 0.06) 78%,
      rgba(9, 10, 30, 0) 100%);
}
.cat__body {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; justify-content: flex-end;
  gap: var(--s-2);
  height: 100%;
  padding: var(--s-4);
}
.cat__name {
  font-family: var(--font-display); font-size: var(--t-md); font-weight: 600;
  color: #FFFFFF; line-height: 1.1;
  text-shadow: 0 1px 10px rgba(6, 8, 24, 0.55);
}
.cat__n {
  display: block;
  font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: rgba(255, 255, 255, 0.86);
  text-shadow: 0 1px 8px rgba(6, 8, 24, 0.6);
}
.cat__n b { color: #FFFFFF; font-variant-numeric: tabular-nums; }
/* the gold underscore, kept: it is the one gold gesture that works
   on a photograph because it is a rule and not text */
.cat::after {
  content: ""; position: absolute; z-index: 2;
  left: var(--s-4); bottom: 0;
  width: 26px; height: 3px; background: var(--gold);
  transition: width 460ms var(--ease-settle);
}
.cat:hover::after, .cat:focus-visible::after { width: 62px; }
.cat:hover img { transform: scale(1.045); }
.cat:hover { box-shadow: 0 1px 2px rgba(4, 7, 20, 0.2), 0 16px 38px rgba(4, 7, 20, 0.22); }
@media (min-width: 620px) { .cats { grid-template-columns: repeat(3, 1fr); } }
@media (prefers-reduced-motion: reduce) {
  .cat img { transition: none !important; }
  .cat:hover img { transform: none !important; }
}

/* ---------- 17.10 The closing band ----------------------------
   The page ends on a photograph rather than on flat navy, sunk far
   enough that it is a room and not a subject.
---------------------------------------------------------------- */
.closer-band { overflow: hidden; }
.closer-band > picture { position: absolute; inset: 0; z-index: 0; }
.closer-band__bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  object-position: 26% 42%;
  filter: saturate(0.62) brightness(0.5) contrast(1.04);
  opacity: 0.26;
}
.closer-band::before { z-index: 1; }
.closer-band > .wrap { position: relative; z-index: 2; }

/* ---------- 17.11 The team photograph slot --------------------
   Styled ahead of an asset that does not exist yet, so that
   dropping the file in and uncommenting the figure in index.html
   is the entire task. While the slot is empty nothing reserves
   space and nothing renders.
---------------------------------------------------------------- */
.whois { margin: 0 0 var(--s-6); }
.whois img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius);
  background: rgba(251, 248, 243, 0.06);
}
.whois figcaption {
  margin-top: var(--s-3);
  font-size: var(--t-xs); font-weight: 600;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--gold);
}

/* ---------- 17.12 Utilities ------------------------------------
   These replace the last inline style attributes. The serving rail
   sets `default-src 'none'`; if its style-src ever lands without
   'unsafe-inline', an inline style attribute stops applying and the
   layout quietly degrades. Cheap insurance, and better practice.
---------------------------------------------------------------- */
.defs { position: absolute; }
.brand__mark { color: var(--navy); }
.header:not(.is-stuck) .brand__mark { color: var(--paper); }
.footer__brand svg { color: var(--paper); }
.closer .eyebrow--plain { justify-content: center; }
.closer .lead { color: var(--on-dark-muted); }
.assurance-card .u-gold { color: var(--gold); }
.u-mt-3 { margin-top: var(--s-3); }
.u-mt-5 { margin-top: var(--s-5); }
.u-mt-6 { margin-top: var(--s-6); }
.u-full { width: 100%; }
.u-op-30 { object-position: 50% 30%; }

/* ---------- 14. Print ---------------------------------------------- */

@media print {
  .header, .footer, .btn, .hero__ground, .hero__shaft, .hero__mote { display: none !important; }
  .hero { background: #fff !important; }
  .hero h1, .trust__n, .trust__label, .hero__sub { color: #000 !important; }
  body { background: #fff; color: #000; }
}

/* ---------- 15. Bump thumbnails ------------------------------------ */
/* the optional additions are real objects, so they are shown as objects */

.bump { grid-template-columns: auto minmax(0, 1fr); }
.bump:has(.bump__thumb) { grid-template-columns: auto minmax(0, 1fr) 64px; }
/* The class sits on the <picture>, not the <img>. A <picture> wrapping
   the image makes the PICTURE the grid item, so styling the inner img
   left the real grid child unstyled: on a phone the auto column then
   sized itself to the raw image and squeezed the description down to
   two words a line. Style the grid item; let the img fill it. */
.bump__thumb {
  display: block;
  width: 64px; height: 78px;
  border-radius: 3px;
  overflow: hidden;
  background: var(--stone-deep);
  box-shadow: var(--shadow-sm);
  align-self: start;
}
.bump__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* On a phone the third column starves the description, so the picture of
   the thing you are adding becomes a strip under it instead. */
@media (max-width: 559px) {
  .bump, .bump:has(.bump__thumb) { grid-template-columns: auto minmax(0, 1fr); gap: var(--s-3); }
  .bump__thumb {
    grid-column: 1 / -1;
    width: 100%; height: 104px;
    margin-top: var(--s-1);
  }
  .bump__thumb img { object-position: 50% 26%; }
}

@media (min-width: 560px) {
  .bump:has(.bump__thumb) { grid-template-columns: auto minmax(0, 1fr) 88px; }
  .bump__thumb { width: 88px; height: 106px; }
}

/* ---------- 16. Demo notice ---------------------------------------- */
/* the prototype has no backend; a submit says so rather than dying quietly */

.notice {
  display: flex; gap: var(--s-3); align-items: flex-start;
  margin-top: var(--s-4);
  padding: var(--s-3) var(--s-4);
  background: rgba(248, 166, 27, 0.16);
  border-left: 3px solid var(--gold);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: var(--t-sm); line-height: 1.5; color: var(--ink);
}
.section--dark .notice, .hero .notice { color: var(--on-dark); background: rgba(248, 166, 27, 0.2); }
.prayerbox .notice { color: var(--ink); }
