/* ==========================================================================
   Vivah · the public site
   --------------------------------------------------------------------------
   Every colour, size, radius, duration and easing here is a var(--token) from
   public/styles/tokens.css, which is generated from design/tokens/tokens.json.
   There is one exception and it is marked: the petal gradient, which is a 15px
   decoration that carries no type.

   The shape of the design, and where each part of it comes from:

     · the TYPE and the COLOUR are the wedding-site reference, entirely;
     · the BANNER is that reference's floral hero with design-2's job — a couple
       illustrated in the middle and a search strip across the bottom;
     · the SECTION SET below it is design-1's;
     · the MOTION is the reference's: things bloom, rise and settle rather than
       sliding in. Nothing here moves faster than --duration-base, and every
       animation is switched off wholesale under prefers-reduced-motion.

   It is a served file rather than a <style> block because this is a multi-page
   site: inlining it would re-send the whole design on every navigation and
   cache it on none of them.
   ========================================================================== */

/* --------------------------------------------------------------- 1. base */

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

/* `scroll-padding-top`, which keeps an in-page link's heading out from under the fixed
   header, is in chrome.css with the header it makes room for. */
html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg-canvas);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-md);
  font-weight: var(--weight-light);
  line-height: var(--leading-relaxed);
  font-variant-numeric: lining-nums;
  -webkit-font-smoothing: antialiased;
}

/* 🔴 NO HORIZONTAL SCROLL, EVER. Several sections here bleed a flower past the
   content edge on purpose, and every one of them is one mistake away from a page
   that drags sideways under a thumb. `clip` rather than `hidden`, so `position:
   sticky` on the header still works. */
html,
body {
  max-width: 100%;
  overflow-x: clip;
}

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

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--brand-secondary-700);
}

p {
  margin: 0 0 1em;
}

figure {
  margin: 0;
}

::selection {
  background: var(--brand-primary-200);
  color: var(--brand-secondary-700);
}

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

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

/* `.skip`, the skip link, is in chrome.css: it is part of the header partial now. */

/* ------------------------------------------------------------ 2. layout */

/* `.wrap` is in chrome.css: the header and the footer are laid out on it. */

/*
 * The header is out of flow, so something has to make room for it. Every page pays it
 * here; the home page's banner opts out and pays it in its own padding instead, because
 * it is the one section that wants to run underneath.
 */
main {
  padding-top: var(--layout-header-h);
}

.section {
  position: relative;
  padding-block: var(--layout-section);
}

.section--flush-top {
  padding-top: 0;
}

.section--blush {
  background: var(--bg-band-blush);
}
.section--rose {
  background: var(--bg-band-rose);
}
.section--sand {
  background: var(--bg-band-sand);
}
.section--sage {
  background: var(--bg-band-sage);
}
.section--surface {
  background: var(--bg-surface);
}

/* The deep band: the footer, and any section that should feel like an occasion. */
.section--ink {
  background: var(--bg-brand-panel);
  color: var(--text-on-brand);
}
.section--ink h1,
.section--ink h2,
.section--ink h3 {
  color: var(--text-on-brand);
}
.section--ink p {
  color: var(--text-on-brand-muted);
}

.center {
  text-align: center;
}

.prose {
  max-width: var(--measure-prose);
}

.prose ul {
  padding-left: var(--space-5);
}

.prose li + li {
  margin-top: var(--space-2);
}

.prose p,
.prose li {
  color: var(--text-secondary);
}

/* ------------------------------------------------- 3. section furniture */

/*
 * The four parts of a section head, in the order they are read:
 *
 *   eyebrow   a gold word in small caps, saying what kind of section this is
 *   script    the Pinyon line, which is ornament wearing the shape of a word
 *   title     the Cormorant heading, which is the actual sentence
 *   lead      one supporting line, never two
 *
 * Every one of them is optional. What is NOT optional is the order: a script
 * line under a title reads as a caption, and the whole effect depends on it
 * arriving first.
 */
.section-head {
  max-width: 680px;
  margin: 0 auto clamp(2.5rem, 5vw, 4.5rem);
  text-align: center;
}

.section-head--start {
  margin-inline: 0;
  text-align: left;
}

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

.section--ink .eyebrow {
  color: var(--brand-accent-on-brand);
}

.script {
  margin: 0 0 var(--space-1);
  font-family: var(--font-script);
  font-size: clamp(1.75rem, 3.2vw, 2.75rem);
  line-height: 1.25;
  color: var(--brand-primary-700);
  /* Pinyon's descenders are long and its ascenders are taller than its cap
     height, so it needs room a sans of the same size would not. */
  padding-block: 0.08em;
}

.section--ink .script {
  color: var(--brand-accent-on-brand);
}

.section-title {
  font-size: clamp(2rem, 4.6vw, 3.4rem);
}

/* The emphasis word inside a heading, the way both reference designs mark the
   subject of the sentence. */
.section-title em {
  font-style: normal;
  color: var(--brand-primary-800);
}

.section--ink .section-title em {
  color: var(--brand-accent-on-brand);
}

.section-lead {
  margin: var(--space-5) 0 0;
  color: var(--text-secondary);
}

.section-head--start .section-lead {
  margin-inline: 0;
}

/* The lead paragraph as the reference sets it: display italic, larger, quieter. */
.lead {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(var(--text-lg), 2.2vw, var(--text-2xl));
  line-height: var(--leading-snug);
  color: var(--text-secondary);
}

/* ---------------------------------------------------------- 4. ornament */

/*
 * The gold flourish, as an image and as a rule.
 *
 * `.flourish` is the drawn one from the art library; `.gold-rule` is the CSS one
 * for places that need a divider rather than a piece of ornament. Both fade at
 * their ends, which is what stops either reading as a box edge.
 */
.flourish {
  display: block;
  width: clamp(140px, 20vw, 220px);
  margin: var(--space-3) auto 0;
  opacity: 0.9;
}

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

.gold-rule {
  height: 1px;
  border: 0;
  margin: 0;
  background: var(--gradient-gold-rule);
}

/*
 * A floral piece placed against a section.
 *
 * `pointer-events: none` on every one of them: these sit over the corners of
 * sections that contain links and form fields, and a flower that eats a click on
 * a button behind it is the worst kind of decoration.
 */
.petalwork {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  /* The artwork is watercolour on white paper and the bands are tinted, so it
     always sits slightly brighter than its ground. Multiply marries them. */
  mix-blend-mode: multiply;
}

/*
 * 🔑 WHICH PIECE GOES IN WHICH CORNER — the rule, because it was got wrong once.
 *
 * The two corner pieces are L-shapes with the flowers at the angle:
 *
 *     corner-a   flowers bottom-RIGHT, one arm along the bottom, one up the right
 *     corner-b   flowers bottom-LEFT,  one arm along the bottom, one up the left
 *
 * So a LEFT corner takes corner-b and a RIGHT corner takes corner-a, and a TOP corner is
 * the same piece flipped vertically. The first version put corner-a top-left and rotated
 * corner-b into the bottom-right, which left both bouquets pointing INTO the page with
 * their stems reaching for the edge — a corner piece growing the wrong way.
 *
 * ⚠️ THE FLIP IS `scale`, NOT `transform`. Any animation on `transform` replaces a static
 * transform outright, so a mirrored piece that is ever animated un-mirrors itself every
 * cycle. The individual property composes with the animation instead.
 */
.petalwork--tl {
  top: 0;
  left: 0;
  width: clamp(120px, 18vw, 230px);
  scale: 1 -1;
}
.petalwork--tr {
  top: 0;
  right: 0;
  width: clamp(120px, 18vw, 230px);
  scale: 1 -1;
}
.petalwork--bl {
  bottom: 0;
  left: 0;
  width: clamp(120px, 18vw, 230px);
}
.petalwork--br {
  bottom: 0;
  right: 0;
  width: clamp(120px, 18vw, 230px);
}

/* The flat-vector blooms, scattered. Lower opacity is what folds design-2's
   saturated teal and violet into a blush palette without recolouring the art. */
.bloom {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  opacity: 0.55;
}

@media (max-width: 47.99rem) {
  /* Ornament is the first thing to go on a phone: it competes with the content
     for a 360px column and it is the part that is doing the least work. */
  .petalwork,
  .bloom {
    display: none;
  }
  .petalwork--keep {
    display: block;
    width: 34vw;
    opacity: 0.8;
  }
}

/* ----------------------------------------------------------- 5. controls */

/* `.btn` and its variants, and `.link-quiet`, are in chrome.css: the header and the footer
   draw with them, on the application's page too. What stays here is what only the public
   pages use. */

.section--ink .btn--outline {
  color: var(--text-on-brand);
  /* The outline pill is cream on a light band; on the ink band it is the outline alone. */
  background-color: transparent;
  border-color: var(--brand-accent-on-brand);
  box-shadow: none;
}

.section--ink .btn--outline:hover {
  color: var(--bg-brand-panel);
  background-image: none;
  background-color: var(--brand-accent-on-brand);
  border-color: var(--brand-accent-on-brand);
}

/*
 * The quiet link with a rule that grows. The rule is the whole control — it is
 * how the reference makes a text link feel like a button without drawing a box.
 */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--layout-tap-target);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--brand-primary-800);
  transition: color var(--duration-base) var(--ease-standard);
}

.link-arrow::after {
  content: '';
  width: 28px;
  height: 1px;
  background: currentColor;
  transition: width var(--duration-slow) var(--ease-out);
}

.link-arrow:hover::after {
  width: 48px;
}

.section--ink .link-arrow {
  color: var(--brand-accent-on-brand);
}

/* ------------------------------------------------------------- 6. cards */

.card {
  position: relative;
  padding: var(--space-6);
  background-color: var(--bg-surface);
  background-image: var(--gradient-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2), inset 0 1px 0 var(--sheen-top),
    inset 0 -1px 0 var(--sheen-bottom);
}

.card--lift {
  transition: transform var(--duration-slow) var(--ease-out),
    box-shadow var(--duration-slow) var(--ease-out);
}

.card--lift:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-3), inset 0 1px 0 var(--sheen-top),
    inset 0 -1px 0 var(--sheen-bottom);
}

/*
 * The arched card, which is the one shape in this design that is not a
 * rectangle. Design 1 puts its three "why choose us" panels in soft arches and
 * circles; an arch is also a temple doorway, which is the right association here
 * and the reason it is worth a non-standard radius.
 */
.card--arch {
  border-radius: var(--radius-2xl) var(--radius-2xl) var(--radius-lg) var(--radius-lg);
}

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

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

/* The round icon well at the top of a feature card. */
.card-icon {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  margin-bottom: var(--space-4);
  color: var(--brand-primary-700);
  background-image: var(--gradient-brand-soft);
  border: 1px solid var(--brand-accent-200);
  border-radius: var(--radius-full);
}

.card-icon svg {
  width: 26px;
  height: 26px;
}

/* -------------------------------------------------------------- 7. grid */

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

.grid--2 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
}

.grid--3 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

.grid--4 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

/* A two-column split where one side is art and the other is words. */
.split {
  display: grid;
  gap: clamp(var(--space-8), 5vw, var(--space-16));
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 60rem) {
  .split {
    grid-template-columns: 1fr 1fr;
  }
  .split--art-first > :first-child {
    order: -1;
  }
}

/* ------------------------------------------------------ 8–9. header, footer */

/*
 * In chrome.css. They are the ONE header and footer of the whole site — around the React
 * application as well as these pages — and the application's page cannot load this file,
 * whose base rules would restyle everything under it.
 */

/* ------------------------------------------------------------ 10. motion */

/*
 * Scroll reveal.
 *
 * `.no-js` on <body> is removed by the site script, and until it is, every
 * revealed element is fully visible. That ordering is the whole contract: a
 * reveal implemented the other way round leaves the page blank for anybody whose
 * script was blocked, which on a marketing page is the entire content.
 */
body:not(.no-js) [data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity var(--duration-reveal) var(--ease-standard),
    transform calc(var(--duration-reveal) + 200ms) var(--ease-out);
  transition-delay: var(--reveal-delay, 0s);
}

body:not(.no-js) [data-reveal].is-visible {
  opacity: 1;
  transform: none;
  filter: none;
}

/*
 * 🔑 MORE THAN ONE WAY TO ARRIVE (2026-10-08, the owner's request: "different styles" of
 * animation). Everything used to rise 28px and fade, which on a page of twelve sections is
 * one motion seen forty times. The value of `data-reveal` now chooses: a bare attribute still
 * rises; `left` and `right` come in from the side they sit on, for two things facing each
 * other; `zoom` settles down from slightly small, for a card or a figure; `blur` comes into
 * focus without moving, for a heading; `flip` turns up from flat, for the one or two things
 * on a page that should feel like a card being turned over.
 *
 * Only the STARTING state differs. Every one of them ends at `.is-visible` above — no
 * transform, no filter — so a variant cannot leave anything half-arrived.
 */
body:not(.no-js) [data-reveal='left'] {
  transform: translateX(-44px);
}

body:not(.no-js) [data-reveal='right'] {
  transform: translateX(44px);
}

body:not(.no-js) [data-reveal='zoom'] {
  transform: scale(0.9);
}

body:not(.no-js) [data-reveal='blur'] {
  transform: none;
  filter: blur(12px);
  transition: opacity var(--duration-reveal) var(--ease-standard),
    filter var(--duration-reveal) var(--ease-out);
  transition-delay: var(--reveal-delay, 0s);
}

body:not(.no-js) [data-reveal='flip'] {
  transform: perspective(900px) rotateX(-18deg) translateY(24px);
  transform-origin: 50% 100%;
}

/* On a phone a sideways entrance is a sideways scrollbar for the length of the transition
   unless its section clips — and a 44px slide is a third of nothing at 390px. Shorter. */
@media (max-width: 47.99rem) {
  body:not(.no-js) [data-reveal='left'] {
    transform: translateX(-20px);
  }
  body:not(.no-js) [data-reveal='right'] {
    transform: translateX(20px);
  }
}

/*
 * PARALLAX. An element with `data-parallax` drifts against the scroll: site.js writes how far
 * its section is from the middle of the screen into `--parallax` (in pixels, already
 * multiplied by the element's own rate), and this moves it by that much.
 *
 * 🔑 `translate`, NOT `transform` — the rule this stylesheet already keeps for every static
 * placement. These are the floral corners and the illustrations, and nearly all of them also
 * animate `transform` (they bloom, sway and rise). The individual property composes with
 * that animation instead of replacing it.
 *
 * ⚠️ NOT FOR ANYTHING THAT ALREADY SETS `translate` (the banner's wreath centres itself with
 * it). A second `translate` would not add to the first; it would replace it.
 */
.is-parallax {
  translate: 0 var(--parallax, 0px);
  will-change: translate;
}

/*
 * A ROW OF CARDS THAT SLIDES, ON A PHONE (`data-slider`). Four cards stacked one under
 * another are four screens of scrolling to read sixty words; side by side under a thumb they
 * are one. It is a scroll container with snap points and not a script: the browser's own
 * momentum, reachable by keyboard, and with the script blocked still a row that scrolls.
 * site.js adds the dots under it and nothing else.
 *
 * From 48rem it is whatever grid the element already was — none of this applies.
 *
 * `position: relative`, for the reason written on `Stepper` in the application: a scroll
 * container clips an absolutely placed child only when it is that child's containing block.
 */
@media (max-width: 47.99rem) {
  /* `body` in front, for the weight: a page's own stylesheet loads after this one and says
     what grid its row is (`.why__grid { display: grid }`), at the same specificity as a bare
     attribute selector. On a phone the row is a slider whatever grid it is on a desk. */
  body [data-slider] {
    position: relative;
    display: flex;
    grid-template-columns: none;
    gap: var(--space-4);
    margin-inline: calc(var(--layout-gutter) * -1);
    padding: var(--space-2) var(--layout-gutter) var(--space-5);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--layout-gutter);
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  body [data-slider]::-webkit-scrollbar {
    display: none;
  }

  body [data-slider] > * {
    flex: 0 0 78%;
    scroll-snap-align: center;
  }

  /* A slid card arrives by sliding. The rise it would have done is under the fold of a row
     nobody scrolls down through, and a card still fading in as it is dragged looks broken. */
  body:not(.no-js) [data-slider] > [data-reveal] {
    opacity: 1;
    transform: none;
    filter: none;
  }
}

.slider-dots {
  display: none;
}

@media (max-width: 47.99rem) {
  .slider-dots {
    display: flex;
    justify-content: center;
    gap: var(--space-2);
    margin-top: calc(var(--space-2) * -1);
  }

  /* Marks, not buttons: the row is dragged, and a 6px dot is nobody's tap target. */
  .slider-dots i {
    width: 6px;
    height: 6px;
    background: var(--border-strong);
    border-radius: var(--radius-full);
    opacity: 0.45;
    transition: width var(--duration-base) var(--ease-out),
      opacity var(--duration-base) var(--ease-standard),
      background-color var(--duration-base) var(--ease-standard);
  }

  .slider-dots i.is-current {
    width: 22px;
    background: var(--brand-primary-700);
    opacity: 1;
  }
}

/*
 * A CARD THAT LEANS TOWARD THE POINTER (`data-tilt`, set by site.js on fine pointers only).
 * `--tilt-x` and `--tilt-y` are degrees, a few at most. Under a thumb there is no pointer to
 * lean toward and a card is simply a card.
 *
 * 🔴 THE SELECTOR IS THIS LONG ON PURPOSE. `body:not(.no-js) [data-reveal].is-visible`
 * (0,3,1) sets `transform: none`, and it outranked `.card--lift:hover` (0,2,0) — so a card
 * that had arrived by reveal never lifted on hover at all. The lift has been dead on every
 * revealed card since the reveal was written; this is specific enough to put it back.
 */
body:not(.no-js) .card--lift[data-reveal].is-visible:hover,
.card--lift:hover {
  transform: perspective(900px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) translateY(-6px);
}

body:not(.no-js) .card--lift[data-reveal].is-visible {
  transition: transform var(--duration-base) var(--ease-out),
    box-shadow var(--duration-slow) var(--ease-out), opacity var(--duration-reveal) var(--ease-standard);
}

/* The icon well turns gold and tips as its card is hovered — the one detail on a card that
   says the hover was noticed, where a lift alone can be missed. */
.card--lift .card-icon {
  transition: rotate var(--duration-slow) var(--ease-out), background-color var(--duration-base) var(--ease-standard),
    color var(--duration-base) var(--ease-standard);
}

.card--lift:hover .card-icon {
  rotate: -8deg;
  color: var(--brand-accent-600);
}

/* The maha-mantra band is the footer's last strip now, and its rules went with it:
   chrome.css, "the mantra". */

/* The floral corners open rather than appear: they grow from the corner they are
   anchored to, which is why each has its own transform-origin. */
@keyframes bloom-in-left {
  from {
    opacity: 0;
    transform: translate(-8%, 8%) scale(0.9);
  }
}

@keyframes bloom-in-right {
  from {
    opacity: 0;
    transform: translate(8%, -8%) scale(0.9);
  }
}

@keyframes sway {
  50% {
    transform: rotate(1.1deg);
  }
}

@keyframes sway-back {
  50% {
    transform: rotate(-1.3deg);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(26px);
  }
}

@keyframes float-soft {
  50% {
    transform: translateY(-10px);
  }
}

/* A pulse, not a turn. The reference's version rotates as well, and a wreath rocking
   on its axis behind a couple reads as something going round — which is exactly the
   motion this design was asked not to have. */
@keyframes breathe {
  50% {
    opacity: 0.8;
    transform: scale(0.97);
  }
}

@keyframes petal-fall {
  0% {
    opacity: 0;
    transform: translate3d(0, 0, 0) rotate(0deg);
  }
  10% {
    opacity: 0.85;
  }
  50% {
    transform: translate3d(calc(var(--drift) * 1px), 46vh, 0) rotate(200deg);
  }
  90% {
    opacity: 0.7;
  }
  100% {
    opacity: 0;
    transform: translate3d(calc(var(--drift) * -0.6px), 92vh, 0) rotate(460deg);
  }
}

/*
 * 🔴 ONE RULE, EVERYTHING OFF.
 *
 * Every animation on this site is decoration: falling petals, swaying flowers,
 * a heading rising into place. A devotee who has asked their operating system
 * for less motion gets a page that is complete and still, and no individual
 * animation has to remember to opt out.
 */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  body:not(.no-js) [data-reveal] {
    opacity: 1;
    transform: none;
    filter: none;
  }
  /* site.js does not run the parallax at all under reduced motion; this is the belt to that
     pair of braces, for a value left behind by a setting changed mid-visit. */
  .is-parallax {
    translate: none;
  }
}

/* ------------------------------------------------------------- 11. print */

@media print {
  .petalwork,
  .bloom,
  .petals {
    display: none !important;
  }
  body {
    background: none;
  }
}

/* =========================================================== 12. documents
 *
 * The FAQ, the terms and every CMS page. They differ in words and not in shape,
 * so they share one vocabulary: a head with a breadcrumb, a rail of anchors down
 * the left, and a measured column of prose beside it.
 *
 * It lives in site.css rather than in three <style> blocks because it WAS three
 * <style> blocks — near-identical ones, which had already drifted: the CMS page
 * called its wrapper `.page-head` and the other two called theirs `.doc-head`,
 * and the two had different padding.
 * ------------------------------------------------------------------------- */

/*
 * 🔑 A DOCUMENT OPENS ON A BAND, NOT ON A BARE HEADING (2026-10-08). These pages — how it
 * works, the FAQ, the terms, every CMS page — were a breadcrumb and an h1 on the page's own
 * cream, set hard left: on a desktop the words filled the left third of the screen and the
 * rest was empty, which read as a page that had not finished loading. Each now opens on the
 * home page's blush wash, centred, with the gold flourish under its title and the floral
 * corner in the band's own corner — the same sheet of paper as the home page, a page on.
 *
 * It is drawn on `.doc-head` itself, by two pseudo-elements, so the three templates that use
 * the class did not have to change. The band is `100vw` wide behind a centred box; `main`
 * clips sideways so that is never a scrollbar, and `clip` (not `hidden`) leaves the FAQ's
 * sticky rail working.
 */
main:has(.doc-head) {
  overflow-x: clip;
}

.doc-head {
  position: relative;
  isolation: isolate;
  margin-bottom: clamp(var(--space-8), 5vw, var(--space-16));
  padding-block: clamp(var(--space-8), 5vw, var(--space-16)) clamp(var(--space-8), 5vw, var(--space-12));
  text-align: center;
}

.doc-head::before {
  content: '';
  position: absolute;
  z-index: -2;
  /* Up under the header, so the bar is over the band and not over a strip of cream. */
  inset-block: calc(var(--layout-header-h) * -1) 0;
  left: 50%;
  width: 100vw;
  translate: -50% 0;
  background: linear-gradient(180deg, var(--bg-band-rose) 0%, var(--bg-band-blush) 62%, var(--bg-band-sand) 100%);
  border-bottom: 1px solid var(--brand-accent-200);
}

/* corner-a is the bottom-RIGHT piece — the corner rule further up this file. */
.doc-head::after {
  content: '';
  position: absolute;
  z-index: -1;
  right: calc(50% - 50vw);
  bottom: 0;
  width: clamp(110px, 15vw, 220px);
  aspect-ratio: 760 / 591;
  background: url('../images/site/corner-a-420.webp') right bottom / contain no-repeat;
  mix-blend-mode: multiply;
  pointer-events: none;
  animation: bloom-in-left var(--duration-bloom) var(--ease-out) 0.2s both;
  transform-origin: 100% 100%;
}

/* What is in the band arrives in order: where you are, the title, then what it says. */
.doc-head > * {
  animation: rise var(--duration-reveal) var(--ease-out) both;
}

.doc-head > :nth-child(2) {
  animation-delay: 0.12s;
}

.doc-head > :nth-child(n + 3) {
  animation-delay: 0.24s;
}

.doc-head h1::after {
  content: '';
  display: block;
  width: clamp(120px, 18vw, 190px);
  aspect-ratio: 900 / 158;
  margin: var(--space-4) auto 0;
  background: url('../images/site/flourish-900.webp') center / contain no-repeat;
}

.doc-head .doc-lead,
.doc-head .doc-meta {
  margin-inline: auto;
  justify-content: center;
}

/* A notice in the band is still a notice: centred as a box, read from the left. */
.doc-head .doc-notice {
  margin-inline: auto;
  text-align: left;
}

/* The rule under the head did the band's job when there was no band. */
.page-rule {
  display: none;
}

.crumbs {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}

.crumbs a {
  color: var(--text-secondary);
}

.crumbs a:hover {
  color: var(--brand-primary-800);
  text-decoration: underline;
}

.crumbs svg {
  flex-shrink: 0;
  color: var(--brand-accent-500);
}

.doc-head h1 {
  font-size: clamp(2rem, 4.6vw, 3.25rem);
}

.doc-lead {
  max-width: var(--measure-prose);
  margin: var(--space-5) 0 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(var(--text-md), 2vw, var(--text-lg));
  line-height: var(--leading-snug);
  color: var(--text-secondary);
}

.doc-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-6);
  margin: var(--space-5) 0 0;
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.doc-meta span {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.doc-meta svg {
  color: var(--brand-accent-500);
}

/* A standing note at the top of a document — "awaiting legal review" and its like.
   Warning-toned rather than blush: it is the one thing on the page that is not the
   document, and it has to be told apart from it. */
.doc-notice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  max-width: var(--measure-prose);
  margin-top: var(--space-8);
  padding: var(--space-5);
  background: var(--status-warning-100);
  border-left: 3px solid var(--status-warning-600);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
}

.doc-notice svg {
  flex-shrink: 0;
  margin-top: 0.15em;
  color: var(--status-warning-700);
}

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

/* ---- the rail and the column ---- */

.doc-layout {
  display: grid;
  gap: clamp(var(--space-8), 4vw, var(--space-16));
  grid-template-columns: 1fr;
  padding-bottom: var(--layout-section);
}

@media (min-width: 64rem) {
  .doc-layout {
    grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
    align-items: start;
  }
}

/*
 * The rail is sticky on a wide screen and an ordinary list on a narrow one. On a
 * phone it is the first thing under the heading, which is the right place for a
 * table of contents — it is how a reader decides whether to read the rest.
 */
.doc-rail h2 {
  margin: 0 0 var(--space-4);
  font-family: var(--font-body);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--brand-accent-600);
}

.doc-rail ol {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.doc-rail a {
  display: flex;
  align-items: center;
  min-height: 2.25rem;
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  border-left: 2px solid var(--border-subtle);
  transition: color var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard);
}

.doc-rail a:hover {
  color: var(--brand-primary-800);
  border-left-color: var(--brand-primary-600);
}

@media (min-width: 64rem) {
  .doc-rail {
    position: sticky;
    top: calc(var(--layout-header-h) + var(--space-6));
  }
}

/* The topic you are reading, as the reader scrolls (site.js marks it). */
.doc-rail a[aria-current='true'] {
  color: var(--brand-primary-800);
  border-left-color: var(--brand-primary-600);
}

/*
 * 🔑 ON A PHONE THE CONTENTS STAY AT THE TOP (2026-10-11, the owner: the FAQ's four links
 * "hide at top" as soon as you scroll). Below 64rem the rail is a bar of pills pinned under
 * the header, edge to edge, that scrolls sideways when it has more than fits (the Terms page
 * has a dozen clauses). site.js lights the topic being read and keeps its pill in view.
 *
 * ⚠️ THE LAYOUT STOPS BEING A GRID HERE, AND THAT IS WHAT MAKES `sticky` WORK. A grid item's
 * containing block is its own grid area, and in one column the rail's area is only as tall
 * as the rail. A sticky element cannot leave its containing block, so it scrolled away with
 * its row. As a block, the rail's containing block is the whole layout, the answers included.
 */
@media (max-width: 63.99rem) {
  .doc-layout {
    display: block;
  }

  .doc-rail {
    position: sticky;
    top: var(--site-header-h, var(--layout-header-h));
    z-index: 5;
    margin: 0 calc(var(--layout-gutter) * -1) var(--space-8);
    padding: var(--space-2) var(--layout-gutter);
    background: var(--glass-bg);
    border-bottom: 1px solid var(--glass-border);
    -webkit-backdrop-filter: blur(var(--glass-blur));
    backdrop-filter: blur(var(--glass-blur));
  }

  /* The bar is the contents; its heading is still there for a screen reader. */
  .doc-rail h2 {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .doc-rail ol {
    display: flex;
    gap: var(--space-2);
    overflow-x: auto;
    scrollbar-width: none;
  }

  .doc-rail ol::-webkit-scrollbar {
    display: none;
  }

  .doc-rail li {
    flex: none;
  }

  .doc-rail a {
    min-height: var(--layout-tap-target);
    padding: 0 var(--space-4);
    font-size: var(--text-xs);
    white-space: nowrap;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-full);
  }

  .doc-rail a:hover,
  .doc-rail a[aria-current='true'] {
    color: var(--brand-primary-800);
    background: var(--brand-primary-100);
    border-color: var(--brand-primary-500);
  }

  /* A topic followed from the bar lands below the bar as well as the header. */
  .doc-layout [id] {
    scroll-margin-top: calc(var(--layout-header-h) + 4.5rem);
  }
}

.doc-body,
.page-body {
  max-width: var(--measure-prose);
}

/* A CMS page is one column, and one column of reading belongs in the middle of the screen.
   (`.doc-body` sits beside a rail and stays where its grid puts it.) */
.page-body {
  margin-inline: auto;
  padding-bottom: var(--space-8);
}

/*
 * What to do next, at the foot of a page that explains something. A visitor who has read
 * "How it works" to the end has one question left, and it used to be answered by the footer.
 */
.page-next {
  position: relative;
  max-width: 46rem;
  margin: clamp(var(--space-8), 5vw, var(--space-16)) auto var(--layout-section);
  padding: clamp(var(--space-8), 5vw, var(--space-12)) clamp(var(--space-5), 4vw, var(--space-12));
  text-align: center;
  background-color: var(--bg-surface);
  background-image: var(--gradient-brand-soft);
  border: 1px solid var(--brand-accent-200);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-2), inset 0 1px 0 var(--sheen-top);
}

.page-next p {
  max-width: 34rem;
  margin: var(--space-3) auto 0;
  color: var(--text-secondary);
}

/* Drawn as a heading and written as a paragraph — see the note in page.html.twig. */
.page-next .page-next__title {
  /* `auto` at the sides: it is a paragraph with the paragraphs' max-width, and with no
     side margin it sat at the left of the card over a centred sentence. */
  margin: 0 auto;
  font-family: var(--font-display);
  font-size: clamp(var(--text-xl), 3vw, var(--text-2xl));
  line-height: var(--leading-snug);
  color: var(--text-primary);
}

.page-next__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

@media (max-width: 30rem) {
  .page-next__actions .btn {
    width: 100%;
  }
}

.doc-body p,
.doc-body li,
.page-body p,
.page-body li {
  color: var(--text-secondary);
}

.doc-body h2,
.page-body h2 {
  margin: clamp(var(--space-10), 5vw, var(--space-16)) 0 var(--space-4);
  font-size: var(--text-2xl);
}

.doc-body h3,
.page-body h3 {
  margin: var(--space-8) 0 var(--space-3);
  font-size: var(--text-lg);
}

.doc-body > :first-child,
.page-body > :first-child {
  margin-top: 0;
}

.page-body ul,
.page-body ol,
.doc-body ul,
.doc-body ol {
  padding-left: var(--space-6);
}

.page-body li + li,
.doc-body li + li {
  margin-top: var(--space-2);
}

.page-body a,
.doc-body a,
.doc-lead a {
  color: var(--brand-info-700);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* The fading gold rule between a document's head and its body. */
.page-rule {
  height: 1px;
  border: 0;
  margin: 0 0 var(--space-10);
  background: var(--gradient-gold-rule);
}

.clause + .clause {
  margin-top: clamp(var(--space-10), 5vw, var(--space-16));
}

.doc-foot,
.faq-more {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  max-width: var(--measure-prose);
  margin-top: clamp(var(--space-12), 6vw, var(--space-20));
  padding: var(--space-6);
  background-color: var(--bg-surface);
  background-image: var(--gradient-surface);
  border: 1px solid var(--brand-accent-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
}

.doc-foot p,
.faq-more p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.faq-more h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-lg);
}

.faq-group + .faq-group {
  margin-top: clamp(var(--space-12), 6vw, var(--space-16));
}

.faq-group > h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-2xl);
}

.faq-group > p {
  max-width: var(--measure-prose);
  color: var(--text-secondary);
}

/* ---- the accordion, in both of its forms ----
 *
 * 🔑 THE FAQ PAGE USES <details> AND THE HOME PAGE DOES NOT, ON PURPOSE.
 *
 * A <details> cannot animate its own height, which is why the home page's short
 * accordion is a button over a region — there the opening IS the interaction, and
 * four questions snapping open is the jarring part of every FAQ built the other way.
 *
 * But a <details> has something the button pattern cannot have: a browser opens one
 * automatically when a fragment inside it is targeted. The FAQ page is a document
 * whose entire rail is deep links into it, and an answer that stayed shut when
 * somebody followed a link to it would be a broken page.
 *
 * They are styled together here so the two read as one control.
 */
.faq-list {
  display: grid;
  gap: var(--space-3);
}

details.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;
}

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

details.faq-item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--layout-tap-target);
  padding: var(--space-4) var(--space-5);
  font-family: var(--font-display);
  font-size: var(--text-md);
  color: var(--brand-secondary-700);
  cursor: pointer;
  list-style: none;
  transition: background-color var(--duration-base) var(--ease-standard);
}

/* Safari draws its own triangle and ignores `list-style`, so both are needed. */
details.faq-item > summary::-webkit-details-marker {
  display: none;
}

details.faq-item > summary:hover {
  background: var(--bg-sunken);
}

details.faq-item > summary:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: -2px;
}

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

details.faq-item[open] .faq-chevron {
  transform: rotate(180deg);
}

details.faq-item > div {
  padding: 0 var(--space-5) var(--space-5);
  max-width: var(--measure-prose);
}

details.faq-item > div p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/*
 * 🔑 AN ANSWER OPENS, WHERE IT USED TO APPEAR (2026-10-08). The note above says a <details>
 * cannot animate its own height, and until recently it could not. Two newer things together
 * can: `::details-content` is the box the browser hides, and `interpolate-size` lets a
 * height run from 0 to `auto`. Inside `@supports`, so a browser without them opens the
 * answer at once, exactly as before — nothing depends on this.
 *
 * Still a <details>: find-in-page and a link to an answer open it, which is the reason this
 * page uses one.
 */
@supports (interpolate-size: allow-keywords) and selector(::details-content) {
  details.faq-item {
    interpolate-size: allow-keywords;
  }

  details.faq-item::details-content {
    block-size: 0;
    overflow: clip;
    opacity: 0;
    transition: block-size 320ms var(--ease-out), opacity 240ms var(--ease-standard),
      content-visibility 320ms allow-discrete;
  }

  details.faq-item[open]::details-content {
    block-size: auto;
    opacity: 1;
  }

  @media (prefers-reduced-motion: reduce) {
    details.faq-item::details-content {
      transition: none;
    }
  }
}

/* ---- the standalone notice page (unsubscribe) ---- */

.notice {
  max-width: 40rem;
  margin: clamp(var(--space-8), 5vw, var(--space-16)) auto;
  padding: clamp(var(--space-6), 4vw, var(--space-10));
  background-color: var(--bg-surface);
  background-image: var(--gradient-surface);
  border: 1px solid var(--brand-accent-200);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-2);
}

.notice h1 {
  margin-bottom: var(--space-5);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
}

.notice form {
  margin: var(--space-6) 0;
}

/* ---- the 404 ----
 *
 * The couple in an arch beside the words, the same arrangement as the home page's
 * quote band — so a stranger who follows a stale link lands somewhere that is visibly
 * the same site, rather than on a line of text.
 */
.lost {
  display: grid;
  gap: clamp(var(--space-8), 5vw, var(--space-16));
  align-items: center;
  grid-template-columns: 1fr;
  padding-block: clamp(var(--space-12), 8vw, var(--space-24));
  text-align: center;
}

@media (min-width: 48rem) {
  .lost {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    text-align: left;
  }
}

.lost__art {
  justify-self: center;
  width: min(70vw, 20rem);
  aspect-ratio: 5 / 6;
  overflow: hidden;
  border: 1px solid var(--brand-accent-200);
  border-radius: 999px 999px var(--radius-xl) var(--radius-xl);
  box-shadow: var(--shadow-3);
}

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

.lost h1 {
  font-size: clamp(2rem, 4.6vw, 3.25rem);
}

.lost .lead {
  max-width: 34rem;
  margin-top: var(--space-5);
}

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

@media (min-width: 48rem) {
  .lost .lead {
    margin-inline: 0;
  }
  .lost__actions {
    justify-content: flex-start;
  }
}

/*
 * 🔑 A CMS PAGE READS AS A DESIGNED PAGE, NOT A DOCUMENT (2026-10-08). The body is HTML an
 * administrator wrote — headings and paragraphs, nothing to hang a class on — so the shape
 * comes from the elements themselves: the opening paragraph is the page's lead, set in the
 * display italic; each h2 carries the short gold rule; and each h3 opens a block of its
 * own, ruled off from the one above with a gold tick at its left. "How it works" is five
 * such blocks, and it used to be five paragraphs.
 */
.page-body > p:first-child {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(var(--text-lg), 2.2vw, var(--text-xl));
  line-height: var(--leading-snug);
  color: var(--brand-secondary-700);
}

.page-body h2::after {
  content: '';
  display: block;
  width: 3rem;
  height: 2px;
  margin-top: var(--space-3);
  background: var(--gradient-gold-foil);
  border-radius: var(--radius-full);
}

.page-body h3 {
  position: relative;
  margin-top: var(--space-8);
  padding: var(--space-6) 0 0 var(--space-5);
  border-top: 1px solid var(--border-subtle);
}

.page-body h3::before {
  content: '';
  position: absolute;
  left: 0;
  top: calc(var(--space-6) + 0.2em);
  width: 3px;
  height: 1em;
  background: var(--brand-accent-500);
  border-radius: var(--radius-full);
}

.page-body h3 + p,
.page-body h3 + ul,
.page-body h3 + ol {
  padding-left: var(--space-5);
}

.page-body h2 + h3 {
  border-top: 0;
  margin-top: var(--space-4);
}
