/* ==========================================================================
   Vivah · the home page
   --------------------------------------------------------------------------
   Loaded only by templates/public/home.html.twig. Everything shared with the
   other public pages is in site.css; what is here is the banner and the nine
   sections under it, none of which appear anywhere else.

   Where each section comes from is recorded above it. The short version: the
   BANNER is the wedding-site reference's floral hero doing design 2's job, the
   SECTION SET is design 1's, and every colour and face is the reference's.
   ========================================================================== */

/* The banner runs under the fixed header and pays for it in its own padding. */
.home-main {
  padding-top: 0;
}

/* ============================================================== 1. banner */

/*
 * The banner is the one place all three references meet, so it is worth saying
 * exactly how.
 *
 *   from the reference : the floral corners that bloom in, the falling petals, the
 *                        script line over the heading
 *   from Gretna Green  : THE COLOUR. Its hero is a slider of flat colour fields —
 *                        #fbb8ac, #bdba70, #dfc9ab — cross-fading into one another
 *                        about every six seconds. Ours is the same movement in this
 *                        palette's four tones: blush, rose, sand and sage.
 *   from design 2      : the arrangement — a couple beside the words
 *
 * It is NOT 100vh on a phone. A full-viewport banner means scrolling past a picture
 * to find out what the site is.
 */
.banner {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: flex;
  min-height: clamp(600px, 90vh, 880px);
  padding-top: var(--layout-header-h);
  /* The first tone is the banner's own ground, not a layer. With motion reduced every
     layer ends at opacity 0 and this is what remains — a still banner, not a blank one. */
  background-image: var(--gradient-hero);
}

/*
 * 🔑 ON A DESKTOP THE BANNER IS THE WHOLE FIRST SCREEN (owner, 2026-10-08). It was 90vh,
 * which left a strip of the next band's cream along the foot of the window — neither a full
 * screen nor a page with its next section in view. Now it is exactly the window, with a cue
 * at its foot (`.banner__scroll`) saying there is more.
 *
 * `min-height`, so a window too short for the words grows the banner rather than cutting
 * them; the type and the spacing below are sized from the window's HEIGHT as well as its
 * width so that on an ordinary laptop (about 650px of window) it does still fit.
 *
 * Still NOT on a phone, for the reason at the top of this section.
 */
@media (min-width: 60rem) {
  .banner {
    min-height: 100vh;
    min-height: 100svh;
  }
}

/*
 * The colour cycle.
 *
 * Three layers over the base, each fading in for its six-second turn: blush (the base)
 * for 0–6s, rose 6–12s, sand 12–18s, sage 18–24s, then round again. Each fade is 1.3s,
 * which is Gretna Green's own transition length, and adjacent fades overlap so the
 * colour moves rather than dipping back to blush between turns.
 *
 * 🔑 EVERY TONE IS GATED. A gradient is not one colour, so the contrast checker cannot
 * read it — but each of these is bounded by a `bg.hero-*` token at its edge, the gate
 * checks the eyebrow, the heading, the lead and the emphasis against all four, and the
 * centre stop is lighter than the edge by construction. Sixteen pairs, all passing.
 */
.banner__tones {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.banner__tone {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: tone-turn 24s ease-in-out infinite both;
}

.banner__tone--rose {
  background-image: var(--gradient-hero-rose);
  animation-delay: 6s;
}

.banner__tone--sand {
  background-image: var(--gradient-hero-sand);
  animation-delay: 12s;
}

.banner__tone--sage {
  background-image: var(--gradient-hero-sage);
  animation-delay: 18s;
}

/* 1.3s of 24s is 5.4%; six seconds is 25%. */
@keyframes tone-turn {
  0% { opacity: 0; }
  5.4% { opacity: 1; }
  25% { opacity: 1; }
  30.4% { opacity: 0; }
  100% { opacity: 0; }
}

/*
 * 🔑 THE HEADER TURNS WITH THE BANNER — AND IT IS IN THIS FILE SO THAT ONLY THE HOME PAGE
 * GETS IT. `home.css` is linked by `templates/public/home.html.twig` alone, which is the
 * scoping mechanism already in place: the FAQ, the terms and the eight CMS pages have no
 * banner behind the header to synchronise with, and a header quietly cycling colours over
 * a page of text is just movement nobody asked for.
 *
 * Synchronised BY CONSTRUCTION rather than by eye: the same 24s period as `tone-turn`, the
 * same 5.4% (1.3s) crossfade, and both start at document load — so the scrim is never
 * showing a tone the banner behind it has already left.
 *
 * ⚠️ A MASK, NOT A GRADIENT, AND THAT IS THE WHOLE TRICK. The scrim in site.css is a
 * gradient fading to transparent, and gradients do not interpolate — animating between
 * four of them SNAPS from one to the next instead of crossfading. A flat background-color
 * tweens perfectly, so the colour is flat and the mask does the fading-out-downward: the
 * same picture, by a route the browser can actually animate.
 */
.site-header::before {
  background-image: none;
  background-color: var(--bg-hero-blush);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
  animation: header-tone 24s ease-in-out infinite both;
}

/*
 * 🔑 THE SCRIM STOPS SHORT OF THE TOP-RIGHT CORNER, BECAUSE THE FLOWERS ARE THERE NOW. The
 * banner's corner spray starts at the very top of the page (owner, 2026-10-08), which is
 * under the header — and under this scrim, which is solid at the top edge and would have
 * painted over the blooms. A second mask fades it out sideways before it reaches them; the
 * two are intersected, so the scrim is still what it was over the wordmark and the menu.
 * Nothing in that corner needed it: the one thing there is the register button, which
 * brings its own ground.
 */
@media (min-width: 48rem) {
  .site-header::before {
    -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 100%),
      linear-gradient(90deg, #000 0%, #000 calc(100% - 34vw), transparent calc(100% - 19vw));
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(180deg, #000 0%, transparent 100%),
      linear-gradient(90deg, #000 0%, #000 calc(100% - 34vw), transparent calc(100% - 19vw));
    mask-composite: intersect;
  }
}

@keyframes header-tone {
  0%, 20.8% { background-color: var(--bg-hero-blush); }
  25%, 45.8% { background-color: var(--bg-hero-rose); }
  50%, 70.8% { background-color: var(--bg-hero-sand); }
  75%, 95.8% { background-color: var(--bg-hero-sage); }
  100% { background-color: var(--bg-hero-blush); }
}

.banner__inner {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 0 clamp(var(--space-6), 4vw, var(--space-12));
  grid-template-columns: 1fr;
  align-items: center;
  width: 100%;
  text-align: center;
}

@media (min-width: 60rem) {
  .banner__inner {
    grid-template-columns: 1.15fr 0.85fr;
    text-align: left;
  }
}

.banner__copy {
  padding-block: clamp(var(--space-8), 5vh, var(--space-12)) clamp(var(--space-8), 9vh, var(--space-20));
}

/* Each child rises in turn. A stagger rather than one movement, because the eye reads
   an eyebrow, then a name, then a sentence, and the motion should agree with it. */
.banner__copy > * {
  animation: rise var(--duration-reveal) var(--ease-out) both;
}
.banner__copy > :nth-child(1) { animation-delay: 0.15s; }
.banner__copy > :nth-child(2) { animation-delay: 0.28s; }
.banner__copy > :nth-child(3) { animation-delay: 0.41s; }
.banner__copy > :nth-child(4) { animation-delay: 0.54s; }
.banner__copy > :nth-child(5) { animation-delay: 0.67s; }
.banner__copy > :nth-child(6) { animation-delay: 0.8s; }

.banner__title {
  font-size: clamp(2.25rem, 5.2vw, 4.25rem);
  line-height: 1.04;
}

/*
 * On a desktop the banner is one screen tall, so the heading is sized from the window's
 * height as well as its width: four lines of it are most of what has to fit. The words keep
 * a clear foot for the scroll cue, which is centred under them.
 */
@media (min-width: 60rem) {
  .banner__title {
    font-size: clamp(2.25rem, min(5.2vw, 7.1vh), 4.5rem);
  }
  .banner__copy {
    padding-block: clamp(var(--space-4), 3vh, var(--space-12)) max(11vh, 5.75rem);
  }
}

.banner__title em {
  font-style: normal;
  color: var(--brand-primary-800);
}

/*
 * 🔑 THE BANNER'S TYPE DARKENED WHEN ITS GROUND SATURATED, AND THAT IS THE TRADE.
 *
 * Gretna Green sets white over its olive and coral; measured, that is about 2:1, which is
 * a hero nobody with low vision can read. The same saturation with the darkest ink on top
 * measures 8.5:1 on the olive — so this banner takes its colour from the reference and its
 * ink from the palette, rather than copying a contrast failure along with the look.
 *
 * The eyebrow is the piece that actually cost something. 12px gold needs a ground of
 * luminance >= 0.783 and none of these tones reaches it, so the eyebrow is the deep rose
 * now. That was the open question left for Sujay after R3 and he answered it: stronger
 * colour, and the eyebrow gives way for it.
 */
.banner .eyebrow {
  color: var(--brand-primary-800);
}

.banner__lead {
  max-width: 34rem;
  margin: var(--space-5) auto 0;
  color: var(--text-primary);
}

@media (min-width: 60rem) {
  .banner__lead {
    margin-inline: 0;
  }
}

.banner__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-4) var(--space-6);
  margin-top: clamp(var(--space-6), 3vw, var(--space-8));
}

@media (min-width: 60rem) {
  .banner__actions {
    justify-content: flex-start;
  }
}

.banner__trust {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin: clamp(var(--space-6), 3vw, var(--space-8)) 0 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 60rem) {
  .banner__trust {
    justify-content: flex-start;
  }
}

.banner__trust li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  color: var(--brand-primary-800);
  background: color-mix(in srgb, var(--bg-surface) 70%, transparent);
  border: 1px solid var(--brand-accent-200);
  border-radius: var(--radius-full);
}

.banner__trust svg {
  color: var(--brand-primary-600);
}

/* The gaps between the words give way first when the window is short — see `.banner`. */
@media (min-width: 60rem) {
  .banner__lead {
    margin-top: clamp(var(--space-3), 2vh, var(--space-5));
  }
  .banner__actions,
  .banner__trust {
    margin-top: clamp(var(--space-4), 3vh, var(--space-8));
  }
}

/* A window that is both narrow and short — a tablet on its side — has no room for the four
   chips under the buttons, which wrap to two rows there. They repeat what the sentence above
   them says, so they are what gives way; measured, everything else then fits the window. */
@media (min-width: 60rem) and (max-width: 74.99rem) and (max-height: 46rem) {
  .banner__trust {
    display: none;
  }
}

/* ---- the cue to scroll ----
 *
 * A mouse with its wheel turning, and the two words under it. A link, so it is also the way
 * down for somebody who would rather click than scroll. See the note in _hero.html.twig.
 */
.banner__scroll {
  display: none;
}

@media (min-width: 60rem) {
  .banner__scroll {
    position: absolute;
    z-index: 3;
    left: 50%;
    bottom: clamp(var(--space-3), 2.4vh, var(--space-6));
    display: grid;
    justify-items: center;
    gap: var(--space-2);
    min-width: var(--layout-tap-target);
    translate: -50% 0;
    font-size: var(--text-2xs);
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--brand-primary-800);
    animation: rise var(--duration-reveal) var(--ease-out) 1.1s both;
  }

  .banner__scroll-mouse {
    position: relative;
    width: 1.5rem;
    height: 2.375rem;
    border: 1.5px solid currentColor;
    border-radius: var(--radius-full);
    transition: background-color var(--duration-base) var(--ease-standard);
  }

  .banner__scroll-mouse i {
    position: absolute;
    left: 50%;
    top: 0.4375rem;
    width: 0.1875rem;
    height: 0.5rem;
    margin-left: -0.09375rem;
    background: currentColor;
    border-radius: var(--radius-full);
    animation: scroll-cue 1.8s var(--ease-standard) infinite;
  }

  .banner__scroll:hover .banner__scroll-mouse {
    background-color: color-mix(in srgb, var(--bg-surface) 55%, transparent);
  }
}

@keyframes scroll-cue {
  0% {
    opacity: 0;
    transform: translateY(0);
  }
  25% {
    opacity: 1;
  }
  70% {
    opacity: 1;
    transform: translateY(0.75rem);
  }
  100% {
    opacity: 0;
    transform: translateY(0.875rem);
  }
}

/* Where the cue lands. The page's own `scroll-padding-top` leaves a gap under the header for
   a heading, and measures the header at its full 92px although it has shrunk to 68px by the
   time the page has moved. A band should come right up to the bar, so both are taken back. */
.below-banner {
  display: block;
  height: 0;
  scroll-margin-top: calc((var(--space-4) + 1.5rem) * -1);
}

/* ---- the couple ----
 *
 * 🔑 A FULL-BODY FIGURE STANDING ON THE BANNER'S BOTTOM EDGE, and both halves of that are
 * load-bearing. FULL-BODY because the banner's colour moves: the earlier waist-up
 * illustration had its own cream arch painted in, which would have sat as a pink box on
 * the sand and sage tones. This one has a real alpha channel, so every tone shows through
 * it. STANDING ON THE EDGE because the earlier one was cropped flat under the waist and
 * that straight line floated in mid-air above the search card.
 */
.banner__art {
  position: relative;
  align-self: end;
  display: flex;
  justify-content: center;
  min-width: 0;
}

.banner__couple {
  position: relative;
  z-index: 1;
  width: auto;
  /* 78vh of a banner that is the whole window: the couple stands most of its height. */
  height: clamp(380px, 78vh, 820px);
  max-width: none;
  animation: rise var(--duration-bloom) var(--ease-out) 0.35s both;
}

/*
 * 🔑 ROOM UNDER THEIR FEET (owner, 2026-10-08). On a desktop the couple stood with their
 * sandals on the banner's very edge, which is the edge of the window now that the banner
 * fills it — they looked cut off by the screen rather than standing in the picture. A band
 * of the banner's own colour under them fixes that, and the figure gives up the same height
 * so its head stays clear of the header.
 */
@media (min-width: 60rem) {
  .banner__art {
    padding-bottom: clamp(var(--space-6), 5.5vh, var(--space-16));
  }
  .banner__couple {
    height: clamp(380px, 73vh, 780px);
  }
}

/* The wreath is a halo behind their heads, not a frame round their feet. */
.banner__wreath {
  position: absolute;
  z-index: 0;
  top: 0;
  left: 50%;
  width: clamp(300px, 34vw, 520px);
  translate: -50% -4%;
  opacity: 0.6;
  mix-blend-mode: multiply;
  animation: breathe 9s ease-in-out 1.4s infinite;
}

/*
 * 🔑 ON A PHONE THE COUPLE COMES FIRST. Decided on review (2026-09-16): stacked words-first,
 * the illustration — the one image that says what this site is — sat under the fold, below
 * a screen of type. Above the words it is the first thing seen, and at this height the
 * heading still arrives on the first screen under it.
 */
@media (max-width: 59.99rem) {
  .banner__art {
    order: -1;
    align-self: center;
    /* 🔑 AIR ABOVE THE PICTURE (owner, 2026-10-08): the wreath's top flowers were touching
       the underside of the phone's header. A MARGIN and not more padding, because the wreath
       is placed from this box's top edge — padding would have moved the couple down inside
       their own halo and left the halo where it was. */
    /* More again on 2026-10-11 (the owner: the hero photo should "move some down"). It was
       clamp(space-8, 10vw, space-12), about 39px on a 390px phone, and the flowers still read
       as touching the header. Now it is about 70px, under a header that is also 12px
       taller at the top of the home page (chrome.css), and the topmost flowers sit well
       clear of it. */
    margin-top: clamp(var(--space-16), 18vw, var(--space-20));
    padding-top: var(--space-4);
  }
  .banner__copy {
    padding-top: var(--space-4);
    /* Clear of the corner spray, which is 32vw wide and about 25vw tall: the last row of
       chips was sitting on its leaves. */
    padding-bottom: clamp(6.5rem, 30vw, 8rem);
  }
  .banner__couple {
    height: min(84vw, 380px);
  }
  .banner__wreath {
    width: min(78vw, 360px);
  }

  /*
   * 🔑 THE WORDS, UNCROWDED (owner, 2026-10-08: "this text is looking cluttered"). Four
   * centred blocks sat one under another at nearly the same weight: the eyebrow broke after
   * "WITH" and left "CARE" alone on a line, the heading left "of life." alone on a fourth, and
   * the sentence under it ran four loose lines at the body's desktop size and leading.
   *
   *   the eyebrow   one line, at a tracking that fits a 360px screen
   *   the heading   balanced, so its lines are the same length and nothing is orphaned
   *   the sentence  a size down, tighter, balanced, and set clear of the heading
   *
   * `text-wrap: balance` is ignored where it is not understood, and the text then wraps as
   * it did — which is the fallback, not a fault.
   */
  .banner .eyebrow {
    margin-bottom: var(--space-4);
    font-size: 0.6875rem;
    letter-spacing: 0.16em;
    text-wrap: balance;
  }
  .banner .script {
    margin-bottom: var(--space-2);
  }
  .banner__title {
    font-size: clamp(1.875rem, 8.4vw, 2.5rem);
    line-height: 1.12;
    text-wrap: balance;
  }
  .banner__lead {
    max-width: 21rem;
    margin-top: var(--space-5);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    text-wrap: balance;
  }
  .banner__actions {
    gap: var(--space-3) var(--space-6);
  }

  /* The four chips as two even pairs. Wrapped and centred, the second row was a different
     width from the first and sat off to one side of it — more of the same untidiness. */
  .banner__trust {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 22rem;
    margin-inline: auto;
  }
  .banner__trust li {
    justify-content: center;
    padding-inline: var(--space-2);
    letter-spacing: 0.04em;
    white-space: nowrap;
  }
}

/* ---- the floral corners ----
 *
 * The same corner rule as site.css: corner-a is the bottom-right piece, corner-b the
 * bottom-left one, a top corner is its piece flipped. Both sit fully INSIDE the banner.
 * The first version pushed them past the edge, and the top one ran behind the header's
 * register button while the bottom one was cut off by the fold.
 *
 * 🔑 THE TOP ONE STARTS AT THE TOP OF THE PAGE, NOT UNDER THE HEADER (owner, 2026-10-08).
 * It used to begin at `--layout-header-h`, which left a clean strip above it and made the
 * spray look as if it hung from the header's bottom edge. At `top: 0` it grows out of the
 * corner of the window itself, the way the bottom one grows out of its corner. The header is
 * transparent over the banner and its scrim stops short of this corner (see above), so the
 * blooms are not painted over; on a narrower desktop the tip of one sprig passes behind the
 * register button, which is a button lying on flowers and reads as that.
 */
.banner__flower {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  user-select: none;
  mix-blend-mode: multiply;
}

.banner__flower--tr {
  right: 0;
  top: 0;
  width: clamp(150px, 16vw, 230px);
  /* ⚠️ The flip pivots on transform-origin. At the top edge, `scale: 1 -1` mirrors the
     piece UPWARD out of the banner and behind the header, which is where it went the
     first time. Centred, it flips in place. */
  scale: 1 -1;
  transform-origin: center;
  animation: bloom-in-right var(--duration-bloom) var(--ease-out) 0.4s both;
}

.banner__flower--bl {
  left: 0;
  bottom: 0;
  width: clamp(150px, 16vw, 230px);
  transform-origin: 0 100%;
  animation: bloom-in-left var(--duration-bloom) var(--ease-out) 0.2s both;
}

@media (max-width: 47.99rem) {
  /* One flower, not two: at 360px a second one is over the heading. */
  .banner__flower--tr {
    display: none;
  }
  .banner__flower--bl {
    width: 32vw;
  }
}

/* ---- the petals ---- */

.petals {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

.petals i {
  position: absolute;
  top: -30px;
  left: var(--x);
  width: calc(15px * var(--s));
  height: calc(10px * var(--s));
  background: var(--gradient-petal);
  border-radius: var(--radius-petal);
  opacity: 0;
  animation: petal-fall var(--t) linear var(--delay) infinite;
}

/* ============================================================== 2. finder */

/*
 * The search, as a titled panel: a heading and a line of reassurance, the fields in two
 * columns straight on the panel, one full-width button, and the trust line under it — with
 * a flourish above and below. It began as the quick-search panel Sujay pointed at, with an
 * inner card titled "Quick match search"; the second review took that card and its title
 * out, because a card inside a card around four selects was chrome rather than structure.
 *
 * It replaces a single five-column strip across the whole content width, which put 400px
 * selects around two-digit ages and left the note floating under the middle of them.
 *
 * 🔑 IT POSTS TO /register, NOT TO A SEARCH. Nothing here is searchable by a stranger —
 * a bio-data is visible only to a devotee whose own profile the Board has approved — so
 * the honest thing for these answers to do is carry into registration, and the line
 * under the button says so.
 */
/*
 * SAND, NOT BLUSH. The banner directly above this is the blush wash, so a blush band
 * under it made the search card look like part of the banner that had come loose — two
 * adjacent surfaces the same colour with a seam between them. Sand is the next band in
 * the palette and it is warm enough to keep the ivory card reading as a card.
 */
.finder {
  position: relative;
  overflow: hidden;
  /* Tightened on review: this band is one card, and it was sitting in about as much air
     as the nine-section page below it uses between whole sections. */
  padding-block: clamp(var(--space-8), 4vw, var(--space-12));
  background: var(--bg-band-sand);
}

.finder__panel {
  position: relative;
  z-index: 1;
  max-width: 38rem;
  margin-inline: auto;
  padding: clamp(var(--space-5), 2.5vw, var(--space-6));
  text-align: center;
  background: var(--glass-bg);
  border: 1px solid var(--brand-accent-200);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-3), inset 0 1px 0 var(--sheen-top);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .finder__panel {
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
  }
}

.finder__panel .flourish {
  margin-block: 0;
}

/* The lower flourish is the upper one turned over, so the pair closes like brackets. */
.finder__panel .flourish--under {
  scale: 1 -1;
  margin-top: var(--space-4);
}

.finder__title {
  margin-top: var(--space-2);
  font-size: clamp(1.75rem, 3.2vw, 2.25rem);
}

.finder__lead {
  max-width: 32rem;
  margin: var(--space-2) auto var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* The form sits straight in the panel — no inner card, no padding of its own, no second
   title. See the note in templates/public/home/_finder.html.twig. */
.finder__form {
  text-align: left;
}

.finder__grid {
  display: grid;
  gap: var(--space-3) var(--space-4);
  grid-template-columns: 1fr;
  margin-bottom: var(--space-4);
}

@media (min-width: 36rem) {
  .finder__grid {
    grid-template-columns: 1fr 1fr;
  }
}

.field {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.field > label {
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--brand-accent-600);
}

.field select,
.field input {
  width: 100%;
  min-height: var(--layout-tap-target);
  padding: 0 var(--space-10) 0 var(--space-4);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text-primary);
  background-color: var(--bg-sunken);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-inset-well);
  /* The native arrow is a system blue triangle on Windows, which is the one piece of
     another palette this page could not otherwise talk out of appearing. The stroke is
     text.muted, written as a literal because a data URI cannot read a custom property. */
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23786A60' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  transition: border-color var(--duration-base) var(--ease-standard);
}

.field select:hover,
.field input:hover {
  border-color: var(--brand-primary-600);
}

.finder__trust {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-5);
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

.finder__trust li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.finder__trust svg {
  color: var(--brand-primary-600);
}

.finder__note {
  margin: var(--space-3) 0 0;
  font-size: var(--text-2xs);
  color: var(--text-muted);
}

/*
 * CORNER PIECES, NOT TWO SPRAYS FLOATING AT MID-HEIGHT.
 *
 * The band used to carry `spray-a` on the left and `spray-b` on the right — two different
 * files that read as the same bouquet twice, hanging in the middle of the empty space
 * either side of the card with nothing to sit against. The corner pieces are L-shaped and
 * grow along two edges, so they frame the card rather than flank it.
 *
 * 🔑 The corner rule is the same one the banner and site.css state, because it is a fact
 * about the artwork: a LEFT corner takes `corner-b`, a RIGHT corner takes `corner-a`.
 * Reversed, both bouquets point into the page with their stems reaching for the edge.
 *
 * 🔑 ONE SPRAY, TOP RIGHT (owner, 2026-10-08). There were two, one in each bottom corner;
 * the owner asked for a single one in the top-right corner and nothing at the foot. It is
 * `corner-a` turned over (`scale: 1 -1`, about its centre so it flips in place), which is
 * how the banner makes its own top-right piece.
 */
.finder__corner {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 0;
  width: clamp(200px, 20vw, 300px);
  scale: 1 -1;
  transform-origin: center;
  pointer-events: none;
  user-select: none;
  mix-blend-mode: multiply;
}

@media (max-width: 71.99rem) {
  .finder__corner {
    display: none;
  }
}

/* ========================================================= 3. why choose us */

/*
 * Design 1's three arched panels. Theirs are a circle, an arch and a circle in
 * three different pastels; ours are all arches in one palette, because three
 * different tints of blush read as a printing error rather than as a scheme.
 */
.why {
  position: relative;
  overflow: hidden;
}

.why__grid {
  display: grid;
  gap: clamp(var(--space-5), 2.5vw, var(--space-8));
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}

/* Every other card is nudged down, the way design 1 staggers its three panels.
   It is a decoration that only works when they are side by side, so it is inside
   the breakpoint that guarantees that. */
/*
 * ⚠️ `translate`, NOT `transform`. These cards also reveal on scroll, and the reveal's
 * `.is-visible { transform: none }` outranks this selector — so as `transform` the stagger
 * was applied, then deleted the moment each card arrived, and all four sat in a flat row.
 */
@media (min-width: 60rem) {
  .why__grid > :nth-child(even) {
    translate: 0 var(--space-8);
  }
}

.why__card {
  text-align: center;
}

.why__card .card-icon {
  margin-inline: auto;
}

/* ============================================================ 4. community */

/*
 * The figures. Design 2 sets four counters under illustrated portraits; here
 * each figure sits inside the watercolour wreath, which is the piece of art in
 * the library that is literally a ring.
 *
 * ⚠️ THE NUMBER IS IN THE MARKUP AND THE SCRIPT ONLY COUNTS TOWARD IT. A crawler
 * and a visitor with JavaScript blocked read the real figure; the count-up is
 * decoration on top of a page that is already correct.
 */
/*
 * CENTRED AS A GROUP, NOT SPREAD ACROSS THE ROW.
 *
 * This was a grid stretching every figure to `1fr`, so two figures stood at the far
 * quarters of a 1240px row with an empty middle between them. And two is not an edge case
 * here: a figure of zero is deliberately not rendered, so the row loses a member exactly
 * when a count is empty. Flex with centring holds one, two or three together.
 */
.figures {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(var(--space-6), 5vw, var(--space-16));
  margin: 0;
  padding: 0;
  text-align: center;
}

/*
 * ⚠️ `column-reverse` IS WHAT LIFTS THE NUMBER ABOVE ITS LABEL, and it is load-bearing:
 * a <dl> requires <dt> before its <dd>, so the markup reads label-then-number and only
 * the presentation is the other way round. Writing the pair backwards in the HTML is the
 * shortcut, and it has been taken twice — PublicPagesTest catches it each time.
 */
.figure {
  position: relative;
  display: flex;
  flex-direction: column-reverse;
  /*
   * 🔴 `flex-end` IS THE TOP, AND THE DEFAULT PUT THE WREATHS AT DIFFERENT HEIGHTS.
   * In a column-REVERSE box main-start is the bottom edge, so the default packing
   * (`flex-start`) stacked each figure from the bottom up — and a figure whose label runs
   * to three lines had its wreath pushed higher than a neighbour whose label runs to two.
   * Packing to main-end lines every wreath up along the top.
   */
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-2);
  width: min(100%, 12rem);
}

.figure__ring {
  position: relative;
  display: grid;
  place-items: center;
  width: clamp(9rem, 16vw, 11.5rem);
  aspect-ratio: 1;
  margin: 0;
}

.figure__ring img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
}

.figure__value {
  position: relative;
  z-index: 1;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3.4vw, 2.6rem);
  line-height: 1;
  color: var(--brand-primary-800);
  font-variant-numeric: tabular-nums lining-nums;
}

.figure__label {
  max-width: 18ch;
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
  color: var(--text-secondary);
}

/*
 * 🔑 ON A PHONE THE THREE FIGURES STAND IN ONE ROW (2026-10-08). Wrapped, they were three
 * wreaths one under another — a whole screen of scrolling to read three numbers, which are
 * meant to be taken in together. Side by side each is about a hundred pixels across, which
 * is all a four-figure number in a ring needs.
 */
@media (max-width: 47.99rem) {
  .figures {
    flex-wrap: nowrap;
    align-items: flex-start;
    gap: var(--space-3);
  }
  .figure {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
  }
  .figure__ring {
    width: 100%;
    max-width: 7.5rem;
  }
  .figure__value {
    font-size: var(--text-xl);
  }
  .figure__label {
    font-size: var(--text-2xs);
  }
}

/* ============================================================== 5. quote */

/*
 * The verse, beside the devotee couple with their hands joined.
 *
 * It used to be the verse alone with two flat-vector blooms floating at the edges, and
 * the right-hand one spun: its mirroring was a static `transform` and its float was a
 * `transform` animation, so the animation replaced the mirror and the flower flipped
 * through zero width on every cycle. Nothing in this section moves now — it is the
 * stillest band on the page on purpose, because it is the one that asks to be read.
 */
.quote__split {
  display: grid;
  gap: clamp(var(--space-8), 5vw, var(--space-16));
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 56rem) {
  .quote__split {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  }
}

/* An arch, because the illustration is a couple at a temple and an arch is a doorway. */
.quote__art {
  justify-self: center;
  width: min(100%, 22rem);
  aspect-ratio: 2 / 3;
  overflow: hidden;
  border: 1px solid var(--brand-accent-200);
  border-radius: 999px 999px var(--radius-xl) var(--radius-xl);
  box-shadow: var(--shadow-3);
  background: var(--bg-band-rose);
}

.quote__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.quote__words {
  text-align: center;
}

@media (min-width: 56rem) {
  .quote__words {
    text-align: left;
  }
  .quote__words .flourish {
    margin-inline: 0;
  }
}

.quote blockquote {
  margin: var(--space-5) 0 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  line-height: var(--leading-snug);
  color: var(--brand-secondary-700);
}

.quote figcaption {
  margin-top: var(--space-6);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--brand-accent-600);
}

/* ========================================================= 6. how it works */

/*
 * Design 2's exact arrangement: two columns of steps with the couple
 * illustration standing between them. On a phone it collapses to one column and
 * the illustration goes to the top, because four steps read as a list and a
 * picture between steps two and three would break it in half.
 */
.steps {
  display: grid;
  gap: clamp(var(--space-8), 4vw, var(--space-12));
  grid-template-columns: 1fr;
  align-items: center;
}

@media (min-width: 64rem) {
  .steps {
    grid-template-columns: 1fr minmax(16rem, 22rem) 1fr;
  }
}

.steps__art {
  order: -1;
  justify-self: center;
  width: min(100%, 22rem);
}

@media (min-width: 64rem) {
  .steps__art {
    order: 0;
    width: 100%;
  }
}

/*
 * 🔴 `list-style: none` IS THE FIX FOR A DOUBLE NUMBER, NOT A TIDY-UP.
 *
 * These are real `<ol>`s — the steps ARE ordered, and `.step__n` says in its own markup
 * that it is `aria-hidden` decoration over ordering the list already carries. But a list
 * whose marker is left on renders BOTH: the browser's "1." at the text edge and the
 * badge beside it, so every step was numbered twice on the live page. `display: grid`
 * does not suppress a marker, which is what made it easy to miss when this was written.
 *
 * The margin and padding go with it: a UA gives an <ol> ~40px of `padding-inline-start`
 * for the markers that are no longer there, and `.step` does its own indenting for the
 * badge.
 */
.steps__col {
  display: grid;
  gap: clamp(var(--space-6), 3vw, var(--space-10));
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  position: relative;
  padding-left: calc(var(--space-12) + var(--space-2));
}

/*
 * An OUTLINED numeral, not a filled gold disc.
 *
 * The foil disc with its drop shadow was the last of the retired design still standing on
 * this page — a chrome-looking token in a system whose ornament is otherwise a hairline, a
 * flourish and a watercolour. A thin gold ring with the figure in display type sits in the
 * same family as the gold rule and the section eyebrows, and it stops the badge shouting
 * louder than the step heading beside it.
 *
 * `accent-600` rather than the ornament gold: this one carries a numeral, so it is type
 * and takes the 4.5:1 token (5.29:1 on the sage band this section uses).
 */
.step__n {
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: var(--space-12);
  height: var(--space-12);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  line-height: 1;
  color: var(--brand-accent-600);
  border: 1px solid var(--brand-accent-200);
  border-radius: var(--radius-full);
}

/*
 * 🔑 THE STEPS ARE JOINED BY A THREAD (2026-10-08). Four numbered rings down a column were
 * four separate things; a gold hairline from each ring to the next makes them one path,
 * which is what "how it works" is a picture of. The ring takes the band's own colour as its
 * ground so the thread runs behind it and not through the numeral.
 */
.step__n {
  z-index: 1;
  background: var(--bg-band-sage);
  transition: color var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard), scale var(--duration-base) var(--ease-out);
}

.step:hover .step__n {
  color: var(--brand-primary-800);
  border-color: var(--brand-accent-500);
  scale: 1.08;
}

.steps__col .step:not(:last-child)::before {
  content: '';
  position: absolute;
  left: calc(var(--space-12) / 2);
  top: var(--space-12);
  /* Down through the gap to the next ring. */
  bottom: calc(clamp(var(--space-6), 3vw, var(--space-10)) * -1);
  width: 1px;
  background: linear-gradient(180deg, var(--brand-accent-500), var(--brand-accent-200));
}

/* On a phone the two lists are one column, so the thread carries on from step two to three. */
@media (max-width: 63.99rem) {
  .steps {
    gap: clamp(var(--space-6), 3vw, var(--space-10));
  }
  .steps__art {
    margin-bottom: var(--space-4);
  }
  .steps__col:first-of-type .step:last-child::before {
    content: '';
    position: absolute;
    left: calc(var(--space-12) / 2);
    top: var(--space-12);
    bottom: calc(clamp(var(--space-6), 3vw, var(--space-10)) * -1);
    width: 1px;
    background: linear-gradient(180deg, var(--brand-accent-500), var(--brand-accent-200));
  }
}

.step h3 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-lg);
}

.step p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* ============================================================ 7. featured */

.featured__grid {
  display: grid;
  gap: clamp(var(--space-5), 2.5vw, var(--space-6));
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

/*
 * 🔒 A FEATURED CARD CARRIES NO PHOTOGRAPH AND NO NAME. What is on it is what
 * App\Homepage\FeaturedProfiles builds — age, occupation, city, centre,
 * initiation, rounds — and that is the whole list. A face on the public home
 * page is a devotee's likeness shown to anyone who visits, which is not what
 * they agreed to when they uploaded it for the Board to review.
 */
.featured__card dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-4);
  margin: 0;
  font-size: var(--text-sm);
}

.featured__card dt {
  color: var(--text-muted);
}

.featured__card dd {
  margin: 0;
  color: var(--text-primary);
}

.featured__crest {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin-bottom: var(--space-5);
  color: var(--brand-primary-700);
  background-image: var(--gradient-brand-soft);
  border: 1px solid var(--brand-accent-200);
  border-radius: var(--radius-full);
}

/* ============================================================= 8. stories */

.stories {
  position: relative;
  overflow: hidden;
}

/*
 * A scroll container with snap points, not a transform slider. A touch device
 * gets its own momentum for free, the keyboard reaches every card by tabbing,
 * and with the script blocked it is still a usable horizontal list.
 */
.stories__track {
  display: flex;
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--layout-gutter);
  padding-block: var(--space-2) var(--space-6);
  /* The scrollbar is chrome, and this is a row of three cards. */
  scrollbar-width: none;
}

.stories__track::-webkit-scrollbar {
  display: none;
}

.stories__slide {
  flex: 0 0 min(100%, 22rem);
  scroll-snap-align: start;
}

.story blockquote {
  margin: 0 0 var(--space-5);
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--text-md);
  line-height: var(--leading-snug);
  color: var(--text-primary);
}

.story figcaption {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--brand-accent-600);
}

.carousel__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.carousel__btn {
  display: grid;
  place-items: center;
  width: var(--layout-tap-target);
  height: var(--layout-tap-target);
  color: var(--brand-primary-800);
  background: var(--bg-surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-full);
  transition: background-color var(--duration-base) var(--ease-standard),
    color var(--duration-base) var(--ease-standard);
}

.carousel__btn:hover:not(:disabled) {
  color: var(--text-inverse);
  background: var(--brand-primary-700);
  border-color: var(--brand-primary-700);
}

.carousel__btn:disabled {
  opacity: 0.35;
  cursor: default;
}

.carousel__dots {
  display: flex;
  gap: var(--space-2);
}

.carousel__dot {
  width: 8px;
  height: 8px;
  padding: 0;
  background: var(--brand-primary-200);
  border-radius: var(--radius-full);
  transition: background-color var(--duration-base) var(--ease-standard);
}

.carousel__dot[aria-current='true'] {
  background: var(--brand-primary-700);
}

/* The visual dot is 8px; the thing a thumb has to hit is 44. */
.carousel__dot {
  position: relative;
}
.carousel__dot::after {
  content: '';
  position: absolute;
  inset: -18px;
}

/* ================================================================= 9. FAQ */

/*
 * Design 1's accordion, one question per row on a card.
 *
 * ⚠️ NOT <details>. A <details> element cannot animate its own height, and six
 * questions snapping open is the jarring part of every FAQ that uses one. The
 * markup keeps the ARIA a disclosure needs — a button with aria-expanded and
 * aria-controls over a region — and with the script blocked every panel is
 * simply open, which is a readable page rather than a broken one.
 */
.faq-list {
  display: grid;
  gap: var(--space-3);
  max-width: 52rem;
  margin-inline: auto;
}

.faq-item {
  background-color: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition: border-color var(--duration-base) var(--ease-standard),
    box-shadow var(--duration-base) var(--ease-standard);
}

.faq-item.is-open {
  border-color: var(--brand-accent-200);
  box-shadow: var(--shadow-2);
}

.faq-item__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  min-height: var(--layout-tap-target);
  padding: var(--space-4) var(--space-5);
  text-align: left;
  font-family: var(--font-display);
  font-size: var(--text-md);
  color: var(--brand-secondary-700);
  transition: background-color var(--duration-base) var(--ease-standard);
}

.faq-item__trigger:hover {
  background: var(--bg-sunken);
}

.faq-item__chevron {
  flex-shrink: 0;
  color: var(--brand-primary-600);
  transition: transform var(--duration-base) var(--ease-standard);
}

.faq-item.is-open .faq-item__chevron {
  transform: rotate(180deg);
}

/* The script sets an explicit pixel height to animate between; `height: auto` is
   what it falls back to when the script never runs. */
.faq-item__body {
  height: auto;
  overflow: hidden;
  transition: height var(--duration-slow) var(--ease-standard);
}

.faq-item__body > div {
  padding: 0 var(--space-5) var(--space-5);
  max-width: var(--measure-prose);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* =============================================================== 10. CTA */

.closing {
  position: relative;
  overflow: hidden;
  text-align: center;
}

.closing__title {
  font-size: clamp(1.875rem, 4.2vw, 3rem);
}

.closing__lead {
  max-width: 36rem;
  margin: var(--space-5) auto 0;
}

.closing__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-4) var(--space-6);
  margin-top: clamp(var(--space-8), 4vw, var(--space-10));
}

.closing__promises {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-6);
  margin: clamp(var(--space-8), 4vw, var(--space-10)) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--text-xs);
  color: var(--text-on-brand-muted);
}

.closing__promises li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.closing__promises svg {
  color: var(--brand-accent-on-brand);
}

/* ==================================================== 11. the CMS banners */

/*
 * An administrator's own banners, when any are published. They REPLACE the
 * banner above rather than stacking under it — two heroes is not a design
 * decision anybody made, it is what happens when nobody decides.
 */
.promo {
  position: relative;
  overflow: hidden;
  padding-block: calc(var(--layout-header-h) + clamp(1.5rem, 4vw, 3.5rem))
    clamp(3rem, 7vw, 6rem);
  background-image: var(--gradient-hero);
}

.promo__slide[hidden] {
  display: none !important;
}

.promo__inner {
  display: grid;
  gap: clamp(var(--space-6), 4vw, var(--space-12));
  align-items: center;
  grid-template-columns: 1fr;
  text-align: center;
}

@media (min-width: 60rem) {
  .promo__inner {
    grid-template-columns: 1.2fr 1fr;
    text-align: left;
  }
  .promo__slide--full_bleed .promo__inner {
    grid-template-columns: 1fr;
    text-align: center;
    justify-items: center;
  }
}

.promo__title {
  font-size: clamp(2rem, 4.8vw, 3.5rem);
  line-height: 1.06;
}

.promo__body {
  max-width: 36rem;
  margin: var(--space-5) auto 0;
  color: var(--text-secondary);
}

@media (min-width: 60rem) {
  .promo__slide:not(.promo__slide--full_bleed) .promo__body {
    margin-inline: 0;
  }
}

.promo__profile {
  display: grid;
  justify-items: center;
  gap: var(--space-2);
  text-align: center;
}

.promo__profile-code {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--brand-accent-600);
}

/* ===================================================== 10. motion, second round */

/*
 * 🔑 THE BANNER ANSWERS THE POINTER (2026-10-08). On a desktop the couple, the wreath behind
 * them and the falling petals each shift a little as the pointer crosses the banner — by
 * different amounts and in different directions, which is what makes three flat layers read
 * as a scene with depth. site.js keeps `--px` and `--py` (−1 to 1, from the banner's centre)
 * on the banner; with the script blocked, or motion reduced, both stay at 0 and nothing here
 * moves.
 *
 * ⚠️ NOT THE CORNER FLOWERS. They are anchored to their corners and stay there — see the
 * note on `PARALLAX_ART` in site.js, which is the same decision about the scroll.
 *
 * The couple already drifts with the scroll (`.is-parallax`, site.css, as `--parallax`); this
 * rule restates that and adds the pointer to it, because `translate` is one property.
 */
.banner {
  --px: 0;
  --py: 0;
}

.banner__couple.is-parallax {
  translate: calc(var(--px) * -14px) calc(var(--parallax, 0px) + var(--py) * -8px);
  transition: translate 600ms var(--ease-out);
}

@media (min-width: 60rem) {
  .banner__wreath {
    translate: calc(-50% + var(--px) * 20px) calc(-4% + var(--py) * 12px);
    transition: translate 900ms var(--ease-out);
  }

  .banner .petals {
    translate: calc(var(--px) * 30px) calc(var(--py) * 16px);
    transition: translate 1200ms var(--ease-out);
  }
}

/*
 * 🔑 THE FOUR VALUES TAKE TURNS (2026-10-08). On a wide screen one card at a time is lit — a
 * gold edge, a little larger, its icon turned — for a few seconds, then the next. Four
 * identical white cards in a row are read as one block and skipped; a light moving along
 * them gets each one read. site.js moves `.is-lit` (`[data-spotlight]`) and stops while a
 * pointer or the keyboard is on the row, so it never takes a card away from somebody reading.
 *
 * `scale`, not `translate` or `transform`: every other card is already nudged down with
 * `translate`, and `transform` is the hover's and the reveal's.
 */
.why__card {
  transition: transform var(--duration-base) var(--ease-out), box-shadow var(--duration-slow) var(--ease-out),
    opacity var(--duration-reveal) var(--ease-standard), scale var(--duration-slow) var(--ease-out);
}

.why__card.is-lit {
  scale: 1.04;
  box-shadow: 0 0 0 1px var(--brand-accent-500), var(--shadow-3), inset 0 1px 0 var(--sheen-top);
}

.why__card.is-lit .card-icon {
  rotate: -8deg;
  color: var(--brand-accent-600);
}

/*
 * 🔑 THE STEPS FILL IN AS THEY ARE REACHED (2026-10-08). Scrolling down "How it works", each
 * numbered ring turns solid as its step comes up the screen and the thread to the next one
 * draws itself downward — the path is walked rather than shown. site.js adds `.is-live` to
 * the list when it is going to do this and `.is-reached` to each step in turn; without
 * `.is-live` the thread is simply drawn, as it was.
 */
.steps.is-live .steps__col .step::before {
  scale: 1 0;
  transform-origin: 50% 0;
  transition: scale 700ms var(--ease-out) 150ms;
}

.steps.is-live .steps__col .step.is-reached::before {
  scale: 1 1;
}

.steps.is-live .step__n {
  transition: color var(--duration-slow) var(--ease-standard), background-color var(--duration-slow) var(--ease-standard),
    border-color var(--duration-slow) var(--ease-standard), scale var(--duration-slow) var(--ease-out),
    box-shadow var(--duration-slow) var(--ease-standard);
}

/* Ivory on the deep rose: `text.on-brand` on `brand.primary-800`, a gated pair. */
.steps.is-live .step.is-reached .step__n {
  color: var(--text-on-brand);
  background-color: var(--brand-primary-800);
  border-color: var(--brand-primary-800);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand-accent-200) 80%, transparent);
}

.steps.is-live .step h3,
.steps.is-live .step p {
  transition: opacity var(--duration-slow) var(--ease-standard);
}

@media (prefers-reduced-motion: reduce) {
  .banner__couple.is-parallax,
  .banner__wreath,
  .banner .petals,
  .why__card {
    transition: none;
  }
}

/* ============================================= 11. the lower sections, 2026-10-08 */

/*
 * 🔑 THE QUESTIONS, WITH THEIR HEADING BESIDE THEM. On a wide screen the heading stands at
 * the left and stays there (sticky) while the questions run down the right — two columns
 * the width of the page, where it was one narrow column in the middle of it. Below 64rem it
 * is the centred stack it always was.
 */
@media (min-width: 64rem) {
  .home-faq > .wrap {
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    gap: var(--space-6) clamp(var(--space-10), 6vw, var(--space-20));
    align-items: start;
  }

  .home-faq .section-head {
    position: sticky;
    top: calc(var(--site-header-h, 68px) + var(--space-10));
    grid-row: 1 / span 2;
    max-width: none;
    margin: 0;
    text-align: left;
  }

  .home-faq .section-head .flourish {
    margin-inline: 0;
  }

  .home-faq .faq-list {
    grid-column: 2;
    max-width: none;
    margin: 0;
  }

  .home-faq .home-faq__more {
    grid-column: 2;
    margin-top: var(--space-6) !important;
    text-align: left;
  }
}

/* A question answers the pointer: it steps a little to the right and its edge turns gold. */
.faq-item {
  transition: translate var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-standard),
    box-shadow var(--duration-base) var(--ease-standard);
}

@media (hover: hover) {
  .faq-item:hover {
    translate: 4px 0;
    border-color: var(--brand-accent-500);
  }
}

/*
 * 🔑 THE CLOSING BAND IS LIT. It was a flat slab of ink — the darkest and stillest thing on
 * the page, at the moment the page asks for something. A warm glow rises behind the words,
 * breathing slowly, and the banner's petals fall through it. Everything stays behind the
 * text (the wrap is lifted above both).
 */
.closing::before {
  content: '';
  position: absolute;
  inset: -20% -10% auto;
  height: 140%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--brand-accent-on-brand) 26%, transparent), transparent 70%);
  pointer-events: none;
  animation: breathe 9s ease-in-out infinite;
}

.closing > .wrap {
  position: relative;
  z-index: 2;
}

.closing .petals i {
  opacity: 0;
}

/* The arch stands a little proud of the page and settles as it is passed. */
.quote__art {
  transition: box-shadow var(--duration-slow) var(--ease-standard), rotate var(--duration-slow) var(--ease-out);
}

@media (hover: hover) {
  .quote__art:hover {
    rotate: -1.2deg;
    box-shadow: var(--shadow-4);
  }
}

/* A large opening mark behind the verse, in the palette's gold at a whisper. */
.quote__words {
  position: relative;
}

.quote__words::before {
  content: '\201C';
  position: absolute;
  top: -0.42em;
  left: -0.08em;
  z-index: 0;
  font-family: var(--font-display);
  font-size: clamp(8rem, 16vw, 13rem);
  line-height: 1;
  color: var(--brand-accent-200);
  pointer-events: none;
}

.quote__words > * {
  position: relative;
  z-index: 1;
}

@media (max-width: 55.99rem) {
  .quote__words::before {
    left: 50%;
    translate: -50% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .closing::before {
    animation: none;
  }
  .faq-item,
  .quote__art {
    transition: none;
  }
}
