/* ==========================================================================
   Holy Mother & Me — Alongside the Mother
   Core stylesheet. Tailwind (Play CDN) provides utilities; this file carries
   the design tokens, typography scale, atmosphere layers and components that
   utilities cannot express cleanly.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Warm gold, sampled from santomission.com. Names are unchanged so every
     page and utility class rebrands from this one block. Each pairing was
     checked against WCAG AA before it landed. */
  --ivory: #fbf7ef; /* warm page ground */
  --warm-white: #fffdf8; /* cards */
  --cream: #f5ebd9; /* alternate warm band */
  --champagne: #f1ce96; /* soft gold, accents on dark */
  --gold: #dfa85f; /* primary gold — fills, rules, icons */
  --antique: #8a5526; /* bronze INK — small text on light */
  --bronze: #6b5a4a; /* body copy */
  --brown: #3d3025; /* headings */
  --midnight: #241b13; /* deepest espresso */
  --navy: #453424; /* mid warm-brown band */

  /* Vertical rhythm. Three steps, not twelve near-identical clamps:
     section = the gap between chapters, block = between blocks inside one,
     tight   = a heading to the thing it introduces.

     The two section steps scale on vw, not vh. A phone and a laptop are within
     a couple of hundred pixels of each other in height, so a vh-keyed clamp
     sat on its floor at both ends and handed a 390px phone the same 96px of
     chapter padding as a 1440px desktop — the scale simply never moved. It
     also put -lg *below* the base step on most screens. Width is the axis that
     actually differs, and keying to it restores both the response and the
     order. */
  --space-section: clamp(3.25rem, 9vw, 6rem);
  --space-section-lg: clamp(4.25rem, 7.6vw, 7rem);
  --space-block: clamp(1.75rem, 3.5vh, 2.75rem);
  --space-tight: clamp(1.25rem, 2.2vh, 1.75rem);
  --gutter: clamp(1.5rem, 3vw, 3rem);

  /* Rounded, friendly geometry. */
  --r-xs: 8px;
  --r-sm: 12px;
  --r-md: 18px;
  --r-lg: 26px;

  --shadow-sm: 0 4px 16px -8px rgba(36, 27, 19, 0.28);
  --shadow-card: 0 14px 40px -18px rgba(36, 27, 19, 0.3);
  --shadow-lift: 0 22px 52px -20px rgba(36, 27, 19, 0.36);

  --ease-cinematic: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-veil: cubic-bezier(0.16, 1, 0.3, 1);

  /* Measure, not maximum. Copy sets to a comfortable line length instead of
     stretching to the viewport. */
  --shell: min(1180px, 100% - 3rem);
  --shell-narrow: min(860px, 100% - 3rem);
  /* 1180 is a measure for text. A chapter whose subject is a wide photograph
     is being held narrower than it wants, so it gets its own container —
     still inset and still framed, just not bound to the reading width. */
  --shell-wide: min(1325px, 100% - 3rem);

  --nav-h: 80px;
  /* Height once the header condenses. JS reads this to offset anchor scrolls,
     so the two can never drift apart. */
  --nav-h-pinned: 62px;
}

@media (max-width: 768px) {
  :root {
    --shell: min(1180px, 100% - 2.25rem);
    --shell-narrow: min(860px, 100% - 2.25rem);
    --shell-wide: min(1325px, 100% - 2.25rem);
    --nav-h: 68px;
    --nav-h-pinned: 58px;
  }
}

/* --------------------------------------------------------------------------
   2. Base
   Tailwind's preflight is switched off (see the config in index.html) so this
   file owns the reset. These rules replicate the parts of preflight the
   utilities depend on — notably the border defaults, without which
   `border-t` and friends would set a width against `border-style: none`.
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  border-width: 0;
  border-style: solid;
  border-color: currentColor;
}

h1,
h2,
h3,
h4,
h5,
h6,
p,
figure,
blockquote,
dl,
dd,
ul,
ol,
pre,
hr {
  margin: 0;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
}

ul,
ol {
  list-style: none;
  padding: 0;
}

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

b,
strong {
  font-weight: bolder;
}

button,
input,
select,
textarea {
  font-family: inherit;
  font-size: 100%;
  font-weight: inherit;
  line-height: inherit;
  color: inherit;
  margin: 0;
  padding: 0;
}

button {
  background-color: transparent;
  background-image: none;
  text-transform: none;
}

button,
[role="button"] {
  cursor: pointer;
}

hr {
  height: 0;
  color: inherit;
  border-top-width: 1px;
}

svg,
video,
canvas,
iframe,
embed,
object {
  display: block;
  vertical-align: middle;
}

[hidden] {
  display: none;
}

[inert] {
  pointer-events: none;
}

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

/* Lenis drives scroll when active; native smooth would fight it. */
html.lenis,
html.lenis body {
  height: auto;
}
html.lenis {
  scroll-behavior: auto;
}
.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}
.lenis.lenis-stopped {
  overflow: hidden;
}

body {
  margin: 0;
  background-color: var(--ivory);
  color: var(--brown);
  font-family:
    "Plus Jakarta Sans",
    ui-sans-serif,
    system-ui,
    -apple-system,
    "Segoe UI",
    sans-serif;
  font-size: 0.975rem;
  line-height: 1.68;
  font-weight: 400;
  letter-spacing: 0.002em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

@media (min-width: 768px) {
  body {
    font-size: 1.0125rem;
    line-height: 1.7;
  }
}

/* Ragging: balance short display lines, avoid orphans in body copy. */
h1,
h2,
h3,
h4,
blockquote {
  text-wrap: balance;
}
p,
li,
dd {
  text-wrap: pretty;
}

img {
  max-width: 100%;
  display: block;
  /* Without this, an <img width="1400" height="933"> whose CSS sets only a
     width keeps the height attribute as a presentational hint and renders
     1400-wide-by-933-tall — stretched. Every image that is meant to fill its
     box sets height from a class, which outranks this element selector, so
     the rule only reaches the images that should scale with their width. */
  height: auto;
}

::selection {
  background: var(--champagne);
  color: var(--brown);
}

/* Focus: always visible, always gold, never removed. */
:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 4px;
  border-radius: var(--r-xs);
}
.on-dark :focus-visible,
.is-dark :focus-visible {
  outline-color: var(--champagne);
}

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */
/* One family throughout. Display work is done with weight and tracking rather
   than a second face — sans at large sizes needs a smaller scale than the
   serif it replaces, or it reads as shouting. */
.font-display {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: -0.028em;
  line-height: 1.16;
}

.t-hero {
  font-size: clamp(2.4rem, 5.3vw, 4.4rem);
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -0.04em;
}

/* h1 on an inner page. Sits above every heading in the body — the page title
   was previously set at .t-section, the same size as the h2s beneath it, so
   it carried no rank. */
.t-page-title {
  font-size: clamp(2.05rem, 4.4vw, 3.1rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.035em;
}

/* Reserved for the few full-bleed quote moments (Divine Call, closing CTA).
   Sits between the hero and a section heading. */
.t-display {
  font-size: clamp(1.85rem, 3.7vw, 3rem);
  font-weight: 800;
  line-height: 1.14;
  letter-spacing: -0.035em;
}

/* h2 — a short section title. */
.t-section {
  font-size: clamp(1.55rem, 2.7vw, 2rem);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.03em;
}

/* h2 — a long statement that runs to several lines, so it sets smaller. */
.t-statement {
  font-size: clamp(2.3rem, 2.1vw, 1.85rem);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.025em;
}

/* h3 — card and sub-section titles. Kept well clear of h2 so the levels
   never read as the same size. */
.t-h3 {
  font-size: clamp(1.05rem, 1.4vw, 1.3rem);
  font-weight: 700;
  line-height: 1.34;
  letter-spacing: -0.015em;
}

/* h4 — dense list rows. */
.t-h4 {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.38;
  letter-spacing: -0.01em;
}

/* Quiet variant — the footer restatement of the hero line. */
.t-quote-sm {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-style: normal;
  font-weight: 500;
  font-size: 1.05rem;
  line-height: 1.45;
  letter-spacing: -0.012em;
}

.t-quote {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-style: normal;
  font-weight: 500;
  font-size: clamp(1.1rem, 1.85vw, 1.6rem);
  line-height: 1.5;
  letter-spacing: -0.015em;
}

/* Wide tracking earns its keep only at small sizes; 0.2em keeps eyebrows
   legible where 0.34em was pulling the letters apart. */
.t-eyebrow {
  font-size: 0.655rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  line-height: 1.5;
}

.t-lead {
  font-size: clamp(1.0125rem, 1.1vw, 1.1rem);
  line-height: 1.75;
}

/* Body copy is capped at a readable measure wherever it is not already
   constrained by the grid. */
.t-copy > p,
.t-copy > ul {
  max-width: 62ch;
}

/* Gold gradient text for accents — falls back to solid gold. */
.text-gilded {
  color: var(--gold);
  background: linear-gradient(
    100deg,
    var(--gold) 0%,
    var(--champagne) 50%,
    var(--gold) 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* --------------------------------------------------------------------------
   4. Layout helpers
   -------------------------------------------------------------------------- */
.shell {
  width: var(--shell);
  margin-inline: auto;
}

/* Narrow blocks sit inside the main shell rather than being centred on the
   viewport, so every section shares one left edge. Centred text inside them
   still reads as centred; the container no longer jumps. */
/* Below about 1230px this is the same container as .shell — both are down to
   100% - 3rem by then — so it only diverges where there is room to diverge. */
.shell-wide {
  width: var(--shell-wide);
  margin-inline: auto;
}

.shell-narrow {
  width: var(--shell);
  max-width: var(--shell);
  margin-inline: auto;
}
.shell-narrow > * {
  max-width: var(--shell-narrow);
  margin-inline: auto;
}

.chapter {
  position: relative;
  isolation: isolate;
}

/* Seam gradients that let one chapter bleed into the next. */
.seam-top-ivory::before,
.seam-bottom-ivory::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 22vh;
  pointer-events: none;
  z-index: 2;
}
.seam-top-ivory::before {
  top: 0;
  background: linear-gradient(to bottom, var(--ivory), rgba(251, 247, 239, 0));
}
.seam-bottom-ivory::after {
  bottom: 0;
  background: linear-gradient(to top, var(--ivory), rgba(251, 247, 239, 0));
}

.seam-top-midnight::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 26vh;
  background: linear-gradient(to bottom, var(--midnight), rgba(36, 27, 19, 0));
  pointer-events: none;
  z-index: 2;
}
.seam-bottom-midnight::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 26vh;
  background: linear-gradient(to top, var(--midnight), rgba(36, 27, 19, 0));
  pointer-events: none;
  z-index: 2;
}

/* --------------------------------------------------------------------------
   5. Atmosphere — grain, glow, veils
   -------------------------------------------------------------------------- */
.grain::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  opacity: 0.16;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}

.glow-gold {
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(60px);
  background: radial-gradient(
    circle,
    rgba(223, 168, 95, 0.5) 0%,
    rgba(223, 168, 95, 0.16) 42%,
    rgba(223, 168, 95, 0) 72%
  );
}

/* Warm cinematic grade applied over photography. */
.veil-warm::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(
      to top,
      rgba(36, 27, 19, 0.9) 0%,
      rgba(61, 48, 37, 0.45) 42%,
      rgba(61, 48, 37, 0.18) 72%,
      rgba(36, 27, 19, 0.4) 100%
    ),
    radial-gradient(
      120% 80% at 20% 78%,
      rgba(222, 122, 30, 0.32) 0%,
      rgba(222, 122, 30, 0) 60%
    );
}

.veil-deep::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(
      to right,
      rgba(36, 27, 19, 0.92) 0%,
      rgba(36, 27, 19, 0.66) 42%,
      rgba(36, 27, 19, 0.28) 100%
    ),
    linear-gradient(to top, rgba(36, 27, 19, 0.85), rgba(36, 27, 19, 0) 55%);
}

/* Media wrapper that reserves aspect and hides the parallax overscan. */
.media {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-md);
  background-color: #dbe4ec;
}
.media > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Parallax layers get overscan so movement never reveals an edge. */
.parallax-media > img {
  will-change: transform;
  transform: translate3d(0, 0, 0) scale(1.16);
}

/* --------------------------------------------------------------------------
   6. Rules, marks and small ornament
   -------------------------------------------------------------------------- */
.rule-gold {
  height: 1px;
  width: 100%;
  transform-origin: left center;
  background: linear-gradient(to right, var(--gold), rgba(223, 168, 95, 0));
  border: 0;
}

.rule-vertical {
  width: 1px;
  background: linear-gradient(
    to bottom,
    rgba(223, 168, 95, 0),
    var(--gold) 18%,
    var(--gold) 82%,
    rgba(223, 168, 95, 0)
  );
  transform-origin: top center;
}

/* A small latin cross: taller than it is wide, crossbar in the upper third,
   so it does not read as a plus sign. */
.mark-cross {
  display: inline-block;
  width: 16px;
  height: 24px;
  position: relative;
  opacity: 0.85;
}
.mark-cross::before,
.mark-cross::after {
  content: "";
  position: absolute;
  background: currentColor;
}
.mark-cross::before {
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1.5px;
  transform: translateX(-50%);
}
.mark-cross::after {
  top: 30%;
  left: 0;
  right: 0;
  height: 1.5px;
}

/* --------------------------------------------------------------------------
   7. Buttons
   -------------------------------------------------------------------------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.95rem 1.75rem;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
  text-decoration: none;
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  overflow: hidden;
  transition:
    color 0.55s var(--ease-cinematic),
    background-color 0.55s var(--ease-cinematic),
    border-color 0.55s var(--ease-cinematic),
    transform 0.55s var(--ease-cinematic);
}
.btn:hover {
  transform: translateY(-2px);
}
.btn .btn-arrow {
  transition: transform 0.55s var(--ease-cinematic);
}
.btn:hover .btn-arrow {
  transform: translateX(5px);
}

/* Flat solid fills, no gradients. Navy sits on the orange rather than white:
   white on this orange is about 2.3:1, which fails at button text sizes. */
/* Compact variant — the header CTA. */
.btn-sm {
  padding: 0.68rem 1.2rem;
  font-size: 0.85rem;
  min-height: 44px;
}

.btn-gold {
  background: var(--gold);
  color: var(--midnight);
}
.btn-gold:hover {
  background: var(--antique);
  color: #fff;
}

/* Solid navy — the reference's secondary action. */
.btn-navy {
  background: var(--brown);
  color: #fff;
}
.btn-navy:hover {
  background: var(--midnight);
}

.btn-ghost-light {
  border-color: rgba(255, 255, 255, 0.45);
  color: #fff;
  background: transparent;
}
.btn-ghost-light:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: #fff;
}

.btn-ghost-dark {
  border-color: rgba(102, 121, 138, 0.35);
  border-color: rgba(61, 48, 37, 0.28);
  color: var(--brown);
}
.btn-ghost-dark:hover {
  border-color: var(--gold);
  color: var(--brown);
  background: rgba(249, 190, 135, 0.16);
}

/* Text link with an underline that draws in. */
.link-quiet {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  text-decoration: none;
  color: var(--antique);
  /* 44px minimum touch height without changing where the text sits. */
  padding-block: 0.7rem 0.55rem;
  min-height: 44px;
}
.link-quiet::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0.55rem;
  height: 1px;
  width: 100%;
  background: currentColor;
  transform: scaleX(0.28);
  transform-origin: left center;
  transition: transform 0.6s var(--ease-cinematic);
}
.link-quiet:hover::after {
  transform: scaleX(1);
}
.on-dark .link-quiet {
  color: var(--champagne);
}

/* --------------------------------------------------------------------------
   8. Navigation
   -------------------------------------------------------------------------- */
.site-nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  transition:
    height 0.6s var(--ease-cinematic),
    background-color 0.6s var(--ease-cinematic),
    box-shadow 0.6s var(--ease-cinematic),
    backdrop-filter 0.6s var(--ease-cinematic);
}
.site-nav::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(
    to right,
    rgba(223, 168, 95, 0),
    rgba(223, 168, 95, 0.5),
    rgba(223, 168, 95, 0)
  );
  opacity: 0;
  transition: opacity 0.6s var(--ease-cinematic);
}
.site-nav.is-pinned {
  height: var(--nav-h-pinned);
  background: rgba(255, 255, 255);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 12px 40px -28px rgba(61, 48, 37, 0.65);
}
.site-nav.is-pinned::after {
  opacity: 1;
}

.nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-decoration: none;
  color: rgba(251, 247, 239, 0.82);
  padding: 0.45rem 0.7rem;
  transition: color 0.45s var(--ease-cinematic);
  white-space: nowrap;
}
.nav-link::after {
  content: "";
  position: absolute;
  left: 0.7rem;
  right: 0.7rem;
  bottom: 0.1rem;
  height: 1px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.5s var(--ease-cinematic);
}
.nav-link:hover::after,
.nav-link[aria-current="true"]::after,
.nav-link.is-active::after {
  transform: scaleX(1);
}
.nav-link:hover {
  color: var(--warm-white);
}
.site-nav.is-pinned .nav-link {
  color: var(--brown);
}
.site-nav.is-pinned .nav-link:hover,
.site-nav.is-pinned .nav-link[aria-current="true"],
.site-nav.is-pinned .nav-link.is-active {
  color: var(--brown);
}

/* ---- Dropdown ---- */
.nav-group {
  position: relative;
}
.nav-group__chev {
  transition: transform 0.4s var(--ease-cinematic);
  opacity: 0.6;
}
.nav-group.is-open .nav-group__chev {
  transform: rotate(180deg);
}

.nav-menu {
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 50%;
  translate: -50% 0;
  min-width: 260px;
  padding: 0.5rem;
  list-style: none;
  margin: 0;
  background: rgba(255, 255, 255, 0.95);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  backdrop-filter: blur(22px) saturate(150%);
  border: 1px solid rgba(61, 48, 37, 0.1);
  border-radius: var(--r-md);
  box-shadow: 0 34px 80px -36px rgba(61, 48, 37, 0.75);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition:
    opacity 0.4s var(--ease-cinematic),
    transform 0.4s var(--ease-cinematic),
    visibility 0.4s;
  z-index: 10;
}
.nav-group.is-open .nav-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
/* Bridges the gap between trigger and panel so the pointer can cross it. */
.nav-menu::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -0.5rem;
  height: 0.5rem;
}

.nav-menu a {
  display: block;
  padding: 0.65rem 0.8rem;
  border-radius: var(--r-xs);
  text-decoration: none;
  transition: background-color 0.32s ease;
}
.nav-menu a:hover,
.nav-menu a:focus-visible {
  background: rgba(249, 190, 135, 0.3);
}
.nav-menu a[aria-current="true"] {
  background: rgba(249, 190, 135, 0.22);
}
.nav-menu .nav-menu__label {
  display: block;
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 1.12rem;
  line-height: 1.2;
  color: var(--brown);
}
.nav-menu .nav-menu__note {
  display: block;
  font-size: 0.635rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--bronze);
  opacity: 0.62;
  margin-top: 0.25rem;
}

/* Block, not flex: the name and "& Me" must stay on one line, with the
   tagline beneath. Padding carries the 44px touch height instead. */
.wordmark {
  display: block;
  padding-block: 0.35rem;
  min-height: 44px;
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 1.18rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1;
  color: var(--warm-white);
  text-decoration: none;
  transition: color 0.5s var(--ease-cinematic);
  white-space: nowrap;
}
.wordmark b {
  font-weight: 600;
}
.wordmark span {
  font-weight: 300;
  opacity: 0.85;
}
.site-nav.is-pinned .wordmark {
  color: var(--brown);
}
.wordmark small {
  display: block;
  font-family: "Plus Jakarta Sans", sans-serif;
  font-size: 0.5rem;
  font-weight: 600;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--champagne);
  margin-top: 0.3rem;
  transition: color 0.5s var(--ease-cinematic);
}
.site-nav.is-pinned .wordmark small {
  color: var(--antique);
}

/* Language selector */
.lang {
  position: relative;
}
.lang-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: transparent;
  border: 1px solid rgba(251, 247, 239, 0.26);
  border-radius: 999px;
  padding: 0.5rem 0.9rem;
  font-family: inherit;
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(251, 247, 239, 0.9);
  cursor: pointer;
  transition: all 0.45s var(--ease-cinematic);
}
.lang-trigger:hover {
  border-color: var(--champagne);
}
.site-nav.is-pinned .lang-trigger {
  border-color: rgba(102, 121, 138, 0.3);
  color: var(--bronze);
}
.site-nav.is-pinned .lang-trigger:hover {
  border-color: var(--gold);
}
.lang-menu {
  position: absolute;
  top: calc(100% + 0.65rem);
  right: 0;
  min-width: 190px;
  background: rgba(255, 255, 255, 0.94);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(61, 48, 37, 0.1);
  border-radius: var(--r-md);
  box-shadow: 0 30px 70px -34px rgba(61, 48, 37, 0.7);
  padding: 0.45rem;
  list-style: none;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition:
    opacity 0.4s var(--ease-cinematic),
    transform 0.4s var(--ease-cinematic),
    visibility 0.4s;
}
.lang.is-open .lang-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.lang-menu button {
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  border-radius: var(--r-xs);
  padding: 0.6rem 0.8rem;
  font-family: inherit;
  font-size: 0.8rem;
  color: var(--brown);
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  transition: background-color 0.3s ease;
}
.lang-menu button:hover {
  background: rgba(249, 190, 135, 0.28);
}
.lang-menu button[aria-selected="true"]::after {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--gold);
  flex: none;
}
.lang-menu .lang-native {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 0.95rem;
  color: var(--bronze);
}

/* Burger */
.burger {
  width: 46px;
  height: 46px;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 0;
}
.burger span {
  display: block;
  width: 24px;
  height: 1.5px;
  background: var(--warm-white);
  transition:
    transform 0.55s var(--ease-cinematic),
    opacity 0.35s ease,
    background-color 0.5s var(--ease-cinematic);
}
.site-nav.is-pinned .burger span {
  background: var(--brown);
}
.burger[aria-expanded="true"] span {
  background: var(--warm-white);
}
.burger[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(7.5px) rotate(45deg);
}
.burger[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}
.burger[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-7.5px) rotate(-45deg);
}

/* Full-screen mobile menu */
.menu-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.7s var(--ease-veil),
    visibility 0.7s;
}
.menu-overlay.is-open {
  opacity: 1;
  visibility: visible;
}
.menu-overlay__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.menu-overlay__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.12);
  transition: transform 1.6s var(--ease-veil);
}
.menu-overlay.is-open .menu-overlay__bg img {
  transform: scale(1);
}
.menu-overlay__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      to bottom,
      rgba(36, 27, 19, 0.94),
      rgba(36, 27, 19, 0.86) 45%,
      rgba(69, 52, 36, 0.95)
    ),
    radial-gradient(
      70% 50% at 50% 30%,
      rgba(223, 168, 95, 0.26) 0%,
      rgba(223, 168, 95, 0) 70%
    );
}
.menu-overlay__inner {
  position: relative;
  z-index: 1;
  width: var(--shell);
  margin-inline: auto;
  padding: calc(var(--nav-h) + 2rem) 0 3rem;
  max-height: 100svh;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.menu-link {
  display: block;
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 300;
  font-size: clamp(2.1rem, 9vw, 3.4rem);
  line-height: 1.16;
  letter-spacing: -0.02em;
  color: var(--ivory);
  text-decoration: none;
  padding: 0.18em 0;
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 0.7s var(--ease-veil),
    transform 0.7s var(--ease-veil),
    color 0.4s ease;
}
.menu-overlay.is-open .menu-link {
  opacity: 1;
  transform: translateY(0);
}
.menu-link:hover {
  color: var(--champagne);
}
/* Nested Faith chapters inside the full-screen menu. */
.menu-sub {
  padding: 0 0 0.5rem 2.9rem;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 0.7s var(--ease-veil),
    transform 0.7s var(--ease-veil);
}
.menu-overlay.is-open .menu-sub {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 260ms;
}
.menu-sub a {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(251, 247, 239, 0.55);
  text-decoration: none;
  transition: color 0.4s ease;
}
.menu-sub a:hover,
.menu-sub a:focus-visible {
  color: var(--champagne);
}

.menu-link i {
  font-family: "Plus Jakarta Sans", sans-serif;
  font-style: normal;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.28em;
  color: var(--gold);
  vertical-align: super;
  margin-right: 0.9rem;
  opacity: 0.7;
}

/* --------------------------------------------------------------------------
   9. Reveal system
   -------------------------------------------------------------------------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(38px);
  transition:
    opacity 1.15s var(--ease-veil),
    transform 1.15s var(--ease-veil),
    filter 1.15s var(--ease-veil);
  filter: blur(6px);
}
[data-reveal="fade"] {
  transform: none;
}
[data-reveal="scale"] {
  transform: scale(0.965);
  filter: blur(4px);
}
[data-reveal].is-in {
  opacity: 1;
  transform: none;
  filter: blur(0);
}

/* Line-by-line heading reveal (built by JS). The padding/negative-margin pair
   gives descenders and italic overhang room inside the clipping box without
   changing the rendered line rhythm. */
.line-mask {
  display: block;
  overflow: hidden;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
  padding-right: 0.06em;
  margin-right: -0.06em;
}
.line-mask > span {
  display: block;
  transform: translateY(105%);
  transition: transform 1.25s var(--ease-veil);
}
.is-in .line-mask > span,
.line-mask.is-in > span {
  transform: translateY(0);
}

/* Staggered children */
[data-stagger] > * {
  opacity: 0;
  transform: translateY(34px);
  transition:
    opacity 1s var(--ease-veil),
    transform 1s var(--ease-veil);
}
[data-stagger].is-in > * {
  opacity: 1;
  transform: none;
}

/* Gold rule that draws itself */
.rule-draw {
  transform: scaleX(0);
  transition: transform 1.5s var(--ease-veil);
}
.is-in .rule-draw,
.rule-draw.is-in {
  transform: scaleX(1);
}
.rule-draw-y {
  transform: scaleY(0);
  transition: transform 1.5s var(--ease-veil);
}
.is-in .rule-draw-y,
.rule-draw-y.is-in {
  transform: scaleY(1);
}

/* --------------------------------------------------------------------------
   10. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--midnight);
}
/* No vertical bleed: every pixel of height the box gains beyond the hero is
   height that `cover` pays for by cropping the sides — and the Lady stands
   against the right edge. The parallax drift is sized to the zoom instead. */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.hero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Anchored top-right: the statue is the one thing that must never be cut,
     and she stands in that corner of the frame. Phones crop far too hard to
     hold her and the boy at once — see the portrait override below. */
  object-position: 92% 8%;
  /* 1.06 leaves 3% of headroom on each edge, which is exactly the drift the
     hero parallax asks for. Anything deeper starts eating her veil. */
  transform: scale(1.06);
  filter: saturate(0.96) contrast(1.02);
}

/* The photograph is warm and bright, and the copy sits along its bottom edge,
   so the grade is weighted downward rather than across. */
.hero__grade {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    /* Pool of shade under the copy column, held to the left so the lit statue
       and the candle bank on the right keep their glow. */
    radial-gradient(
      52% 46% at 26% 76%,
      rgba(36, 27, 19, 0.74) 0%,
      rgba(36, 27, 19, 0) 72%
    ),
    linear-gradient(
      to top,
      rgba(36, 27, 19, 0.95) 0%,
      rgba(36, 27, 19, 0.88) 24%,
      rgba(36, 27, 19, 0.52) 46%,
      rgba(36, 27, 19, 0.16) 64%,
      rgba(36, 27, 19, 0.5) 100%
    ),
    linear-gradient(
      to right,
      rgba(36, 27, 19, 0.66) 0%,
      rgba(36, 27, 19, 0.26) 40%,
      rgba(36, 27, 19, 0) 66%
    ),
    radial-gradient(
      70% 55% at 84% 40%,
      rgba(223, 168, 95, 0.14) 0%,
      rgba(0, 0, 0, 0) 72%
    );
}

/* How much of the frame survives depends on the window's shape, not its width,
   so the framing is keyed to aspect ratio. A tall window crops hard from the
   sides and has to stay pinned near the right edge to hold the statue. */
@media (min-width: 1024px) {
  .hero__bg img {
    object-position: 82% 8%;
  }
}

/* At 1.6:1 and wider the window is close to the photograph's own 1.84:1, so
   little or nothing is lost sideways. Releasing the frame back toward centre
   carries the boy out from behind the copy, and the statue still clears the
   right edge with room to spare. */
@media (min-width: 1024px) and (min-aspect-ratio: 8 / 5) {
  .hero__bg img {
    object-position: 55% 22%;
  }
}

/* On phones the crop is narrow and the copy spans the full width, so the
   side gradient only muddies the picture — the bottom one is enough. The top
   vignette is kept light: the statue's head sits up there in this crop. */
@media (max-width: 1023px) {
  .hero__grade {
    background: linear-gradient(
      to top,
      rgba(36, 27, 19, 0.94) 0%,
      rgba(36, 27, 19, 0.86) 30%,
      rgba(36, 27, 19, 0.48) 58%,
      rgba(36, 27, 19, 0.14) 80%,
      rgba(36, 27, 19, 0.3) 100%
    );
  }
}

/* --------------------------------------------------------------------------
   10b. Page header — the compact hero on inner pages
   -------------------------------------------------------------------------- */
/* Sticky, so the chapter beneath rides up over the banner rather than shoving
   it off the top. Every page-head is followed by an opaque .chapter, so once
   the banner is covered it is simply not seen — and JS drops it out of the
   paint entirely at that point, see .is-past below. */
.page-head {
  position: sticky;
  top: 0;
  z-index: 0;
  isolation: isolate;
  overflow: hidden;
  background: var(--midnight);
  padding-top: calc(var(--nav-h) + clamp(4.75rem, 10vh, 8rem));
  padding-bottom: clamp(4.75rem, 10vh, 8rem);
}
/* The chapter that scrolls over it. .chapter is already position:relative, so
   DOM order would mostly do this on its own — stated outright because the
   whole effect collapses silently if it ever stops being true. */
.page-head + .chapter {
  z-index: 1;
}
/* Once fully covered the banner is still a stuck, composited layer for the
   rest of the page. Hiding it keeps the layout and stops the paint. */
.page-head.is-past {
  visibility: hidden;
}
/* The copy is what zooms out and blurs. */
.page-head > .shell {
  will-change: transform, filter, opacity;
}
/* Nothing moves, so nothing needs pinning — and a stuck banner that never
   fades would sit behind the whole page for no reason. */
@media (prefers-reduced-motion: reduce) {
  .page-head {
    position: relative;
  }
  .page-head > .shell {
    will-change: auto;
  }
}
.page-head__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.page-head__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.08);
}
/* Several page-head photographs are bright (white Kerala churches, daylight
   skies), so the veil has to carry the contrast for the copy on its own. */
.page-head::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(
      to right,
      rgba(36, 27, 19, 0.96) 0%,
      rgba(36, 27, 19, 0.93) 46%,
      rgba(36, 27, 19, 0.72) 72%,
      rgba(36, 27, 19, 0.5) 100%
    ),
    linear-gradient(
      to top,
      rgba(36, 27, 19, 0.9),
      rgba(36, 27, 19, 0.3) 60%,
      rgba(36, 27, 19, 0.6) 100%
    );
}

/* Centred variant — the post page, where the head introduces a single article
   rather than a section of the site. The default veil above is weighted to the
   left because the copy is; centred copy needs it weighted to the middle, or
   the right half of every line sits on the bright part of the photograph. */
.page-head--centred .shell {
  text-align: center;
}
.page-head--centred .page-trail,
.page-head--centred .post-meta {
  justify-content: center;
}
.page-head--centred::before {
  background:
    radial-gradient(
      124% 104% at 50% 52%,
      rgba(36, 27, 19, 0.94) 0%,
      rgba(36, 27, 19, 0.88) 44%,
      rgba(36, 27, 19, 0.6) 100%
    ),
    linear-gradient(
      to top,
      rgba(36, 27, 19, 0.9),
      rgba(36, 27, 19, 0.34) 60%,
      rgba(36, 27, 19, 0.6) 100%
    );
}

/* Breadcrumb-ish trail above the page title. */
.page-trail {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(249, 190, 135, 0.75);
}
.page-trail a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 0.15rem;
  margin-inline: -0.15rem;
  text-decoration: none;
  transition: color 0.4s ease;
}
.page-trail span[aria-hidden],
.page-trail > span {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.page-trail a:hover {
  color: var(--warm-white);
}
.page-trail span[aria-hidden] {
  opacity: 0.45;
}

.scroll-cue {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
  color: rgba(251, 247, 239, 0.6);
  text-decoration: none;
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  transition: color 0.5s ease;
}
.scroll-cue:hover {
  color: var(--champagne);
}
.scroll-cue__track {
  width: 1px;
  height: 62px;
  background: rgba(251, 247, 239, 0.22);
  position: relative;
  overflow: hidden;
}
.scroll-cue__track::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 40%;
  background: linear-gradient(to bottom, rgba(223, 168, 95, 0), var(--gold));
  animation: cue 2.6s var(--ease-cinematic) infinite;
}
@keyframes cue {
  0% {
    transform: translateY(-100%);
  }
  60%,
  100% {
    transform: translateY(250%);
  }
}

/* --------------------------------------------------------------------------
   11. Timeline
   -------------------------------------------------------------------------- */
.timeline {
  position: relative;
}
.timeline__spine {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(61, 48, 37, 0.12);
}
.timeline__spine i {
  position: absolute;
  inset: 0 0 auto 0;
  display: block;
  height: 100%;
  transform-origin: top center;
  transform: scaleY(var(--progress, 0));
  background: linear-gradient(
    to bottom,
    var(--champagne),
    var(--gold) 30%,
    var(--antique)
  );
}
@media (min-width: 900px) {
  .timeline__spine {
    left: 50%;
    transform: translateX(-50%);
  }
}

.tl-node {
  position: relative;
  padding-left: 2.25rem;
  padding-block: clamp(0.85rem, 1.7vw, 1.4rem);
}
.tl-node::before {
  content: "";
  position: absolute;
  left: -4.5px;
  top: calc(clamp(0.85rem, 1.7vw, 1.4rem) + 0.7rem);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--ivory);
  border: 1px solid var(--gold);
  transition:
    background-color 0.7s var(--ease-cinematic),
    box-shadow 0.7s var(--ease-cinematic);
}
.tl-node.is-in::before {
  background: var(--gold);
  box-shadow: 0 0 0 6px rgba(223, 168, 95, 0.16);
}

/* The whole entry is one row — fragment beside year, place, title and copy.
   Stacking these instead would roughly double the height of the chapter. */
.tl-inner {
  max-width: 30rem;
}
.tl-row {
  display: flex;
  align-items: flex-start;
  gap: clamp(0.9rem, 1.6vw, 1.35rem);
}
.tl-text {
  min-width: 0;
}

@media (min-width: 900px) {
  .tl-node {
    width: 50%;
    padding-left: 0;
    padding-right: 3.5rem;
  }
  .tl-node .tl-inner {
    margin-left: auto;
  }
  .tl-node::before {
    left: auto;
    right: -5.5px;
  }
  .tl-node:nth-of-type(even) {
    margin-left: 50%;
    padding-right: 0;
    padding-left: 3.5rem;
  }
  .tl-node:nth-of-type(even) .tl-inner {
    margin-left: 0;
  }
  .tl-node:nth-of-type(even)::before {
    right: auto;
    left: -5.5px;
  }
}

.tl-year {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 400;
  font-size: clamp(1.35rem, 2vw, 1.75rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--antique);
}
.tl-place {
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--bronze);
  margin-top: 0.3rem;
}
.tl-fragment {
  flex: none;
  width: clamp(80px, 10.5vw, 112px);
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: var(--r-sm);
  position: relative;
}
.tl-fragment::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(61, 48, 37, 0.4),
    rgba(61, 48, 37, 0)
  );
}
.tl-fragment img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.6s var(--ease-cinematic);
}
.tl-node:hover .tl-fragment img {
  transform: scale(1.06);
}

/* --------------------------------------------------------------------------
   12. Four Dreams
   -------------------------------------------------------------------------- */
.dreams-track {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
/* Only promise horizontal movement where it actually happens. */
.dreams-hint {
  display: none;
}

/* The horizontal layout only exists once JS has actually created the pinned
   ScrollTrigger. Without GSAP, without JS, or under reduced motion the panels
   stay stacked and every dream remains reachable. */
@media (min-width: 1024px) {
  .has-pin .dreams-hint {
    display: block;
  }

  .has-pin .dreams-viewport {
    height: 100svh;
    overflow: hidden;
  }
  .has-pin .dreams-track {
    flex-direction: row;
    height: 100svh;
    width: max-content;
    gap: 0;
  }
}

.dream-panel {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  min-height: 78svh;
  display: flex;
  align-items: flex-end;
}
@media (min-width: 1024px) {
  .has-pin .dream-panel {
    width: 54vw;
    min-height: 100svh;
    height: 100svh;
  }
}
.dream-panel__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.dream-panel__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.12);
  will-change: transform;
}
/* Two of the four dream photographs are very light, so the veil has to carry
   the text contrast on its own rather than relying on the image being dark. */
.dream-panel__veil {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(
      to top,
      rgba(36, 27, 19, 0.96) 6%,
      rgba(36, 27, 19, 0.82) 34%,
      rgba(36, 27, 19, 0.42) 66%,
      rgba(36, 27, 19, 0.24) 100%
    ),
    linear-gradient(
      to right,
      rgba(36, 27, 19, 0.78),
      rgba(36, 27, 19, 0.18) 62%,
      rgba(36, 27, 19, 0) 100%
    );
}
/* Compact card variant — the Four Dreams teaser on the home page. */
.dream-card {
  display: block;
  text-decoration: none;
  color: inherit;
}
.dream-card .media img {
  transition: transform 1.5s var(--ease-cinematic);
}
.dream-card:hover .media img,
.dream-card:focus-visible .media img {
  transform: scale(1.05);
}
.dream-card__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to top,
    rgba(36, 27, 19, 0.85),
    rgba(36, 27, 19, 0.15) 60%
  );
}
.dream-card__index {
  position: absolute;
  left: 1rem;
  bottom: 0.85rem;
  z-index: 2;
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 400;
  font-size: 1.9rem;
  font-weight: 800;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(249, 190, 135, 0.7);
  text-stroke: 1px rgba(249, 190, 135, 0.7);
}
.dream-card:hover .dream-card__name {
  color: var(--champagne);
}

.dream-index {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 300;
  font-size: clamp(3.4rem, 8vw, 6.5rem);
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.045em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(249, 190, 135, 0.55);
  text-stroke: 1px rgba(249, 190, 135, 0.55);
}

/* --------------------------------------------------------------------------
   13. Divine call — dust particles
   -------------------------------------------------------------------------- */
.dust {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}
.dust i {
  position: absolute;
  bottom: -10px;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: var(--champagne);
  opacity: 0;
  animation: rise linear infinite;
}
@keyframes rise {
  0% {
    transform: translate3d(0, 0, 0);
    opacity: 0;
  }
  12% {
    opacity: var(--peak, 0.5);
  }
  85% {
    opacity: var(--peak, 0.5);
  }
  100% {
    transform: translate3d(var(--drift, 20px), -102svh, 0);
    opacity: 0;
  }
}

/* --------------------------------------------------------------------------
   14. Statistics
   -------------------------------------------------------------------------- */
.stat {
  position: relative;
  padding: clamp(1.6rem, 3vw, 2.4rem) 0;
}
.stat__value {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 300;
  /* Capped so the widest value still clears its column at six-up. At the
     1180px shell that column is 170px, and "10,000+" — a glyph wider than the
     "2,000+" this was set for — runs about 3.7em, so 2.8rem is the ceiling. */
  font-size: clamp(1.75rem, 3vw, 2.8rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.035em;
  color: var(--champagne);
  font-variant-numeric: tabular-nums;
}
.stat__label {
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(251, 247, 239, 0.58);
  margin-top: 0.85rem;
}

/* --------------------------------------------------------------------------
   15. Cards — media, blog, projects
   -------------------------------------------------------------------------- */
/* A <button> now, not an <a>: every card opens the viewer rather than going
   anywhere. Buttons bring a UA background, border, padding, centred text and
   their own font, so all of it is cleared. Its children are <span>s because a
   button may only contain phrasing content — which means they need their
   display restoring, an inline <span class="media"> being no box at all. */
.card-media {
  position: relative;
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  background: var(--warm-white);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  transition:
    transform 0.5s var(--ease-cinematic),
    box-shadow 0.5s var(--ease-cinematic);
}
.card-media:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}
.card-media > span {
  display: block;
}
.card-media .media {
  /* 16:9, the frame a YouTube thumbnail arrives in. Cropping it to 4:3 cut
     the titling most of them carry across the lower third. */
  aspect-ratio: 16 / 9;
  border-radius: var(--r-md) var(--r-md) 0 0;
}
.card-media .media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card-media[hidden] {
  display: none;
}
.card-media .media img {
  transition:
    transform 1.5s var(--ease-cinematic),
    filter 1.5s var(--ease-cinematic);
}
.card-media:hover .media img {
  transform: scale(1.05);
  filter: brightness(1.03);
}

.play-btn {
  position: absolute;
  left: 1.25rem;
  bottom: 1.25rem;
  z-index: 2;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(251, 247, 239, 0.45);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--warm-white);
  transition:
    background-color 0.55s var(--ease-cinematic),
    transform 0.55s var(--ease-cinematic),
    border-color 0.55s var(--ease-cinematic);
}
.card-media:hover .play-btn {
  background: rgba(223, 168, 95, 0.92);
  border-color: rgba(223, 168, 95, 1);
  color: #221b12;
  transform: scale(1.06);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  font-size: 0.56rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  border: 1px solid rgba(251, 247, 239, 0.34);
  color: rgba(251, 247, 239, 0.92);
  background: rgba(36, 27, 19, 0.34);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  white-space: nowrap;
}
.pill-dark {
  border-color: rgba(102, 121, 138, 0.35);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-color: rgba(61, 48, 37, 0.16);
  color: var(--brown);
  background: rgba(61, 48, 37, 0.06);
}

/* --------------------------------------------------------------------------
   15b. Testimonials — video, audio and written, in any language
   -------------------------------------------------------------------------- */
/* --- Testimony page: masonry -------------------------------------------
   Written and recorded entries differ in height by design, so they flow in
   columns rather than being forced onto a shared baseline. */
.testimonial-masonry {
  column-count: 1;
  column-gap: clamp(1.1rem, 2vw, 1.6rem);
}
@media (min-width: 700px) {
  .testimonial-masonry {
    column-count: 2;
  }
}
@media (min-width: 1080px) {
  .testimonial-masonry {
    column-count: 3;
  }
}
.testimonial-masonry .tcard {
  break-inside: avoid;
  width: 100%;
  margin-bottom: clamp(1.1rem, 2vw, 1.6rem);
}

/* --- Compact card: the home teaser -------------------------------------
   No hero image, quote at body size, a small round thumbnail carrying the
   attribution. Sized so three sit in a row. */
.tcard--compact .tcard__panel {
  display: none;
}
.tcard--compact .tcard__body {
  padding: clamp(1.15rem, 1.9vw, 1.45rem);
}
.tcard--compact .tcard__quote {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-style: normal;
  font-weight: 400;
  font-size: 0.94rem;
  line-height: 1.62;
  letter-spacing: 0;
  color: var(--bronze);
  margin-top: 0.85rem;
  margin-bottom: 1.15rem;
}
.tcard--compact .tcard__by {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-top: 1rem;
}
.tcard--compact .tcard__name {
  font-size: 0.84rem;
}
.tcard--compact .tcard__place {
  font-size: 0.6rem;
  letter-spacing: 0.12em;
}

.tcard__avatar {
  position: relative;
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--cream);
}
.tcard__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.tcard__avatar--mark {
  display: grid;
  place-items: center;
  font-family: "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--champagne);
  padding-top: 0.45rem;
}
/* Marks a recorded testimony without repeating the format pill. */
.tcard__avatar-badge {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--gold);
  color: var(--midnight);
  border: 2px solid var(--warm-white);
}

/* --- Home: a two-up slider ---------------------------------------------- */
.tslider {
  position: relative;
}
.tslider__track {
  display: flex;
  gap: clamp(1rem, 2vw, 1.5rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-block: 4px;
}
.tslider__track::-webkit-scrollbar {
  display: none;
}
/* Every slide takes the height of the tallest in the line, so a short
   written entry and a long recorded one still sit level. */
.tslider__track > .tcard {
  flex: 0 0 100%;
  scroll-snap-align: start;
  align-self: stretch;
  height: auto;
}
@media (min-width: 700px) {
  .tslider__track > .tcard {
    flex-basis: calc(50% - (clamp(1rem, 2vw, 1.5rem) / 2));
  }
}
@media (min-width: 1040px) {
  .tslider__track > .tcard {
    flex-basis: calc(33.333% - (clamp(1rem, 2vw, 1.5rem) * 2 / 3));
  }
}
@media (prefers-reduced-motion: reduce) {
  .tslider__track {
    scroll-behavior: auto;
  }
}

.tslider__nav {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-top: clamp(1.25rem, 2.4vw, 1.75rem);
}
.tslider__btn {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  border: 1px solid rgba(61, 48, 37, 0.22);
  color: var(--brown);
  background: var(--warm-white);
  transition:
    background-color 0.4s var(--ease-cinematic),
    color 0.4s var(--ease-cinematic),
    border-color 0.4s var(--ease-cinematic),
    opacity 0.3s ease;
}
.tslider__btn:hover:not([disabled]) {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--midnight);
}
.tslider__btn[disabled] {
  opacity: 0.3;
  cursor: default;
}
.tslider__count {
  margin-left: 0.4rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bronze);
}

.tcard {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid rgba(61, 48, 37, 0.09);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  background: var(--warm-white);
  transition:
    border-color 0.55s var(--ease-cinematic),
    transform 0.55s var(--ease-cinematic);
}
.tcard:hover {
  border-color: rgba(223, 168, 95, 0.85);
  transform: translateY(-3px);
}
.tcard__panel > .media {
  position: absolute;
  inset: 0;
  border-radius: var(--r-md) var(--r-md) 0 0;
}
.tcard .media img {
  transition: transform 1.5s var(--ease-cinematic);
}
.tcard:hover .media img {
  transform: scale(1.05);
}
.tcard__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to top,
    rgba(36, 27, 19, 0.7),
    rgba(36, 27, 19, 0) 55%
  );
}
.tcard:hover .play-btn {
  background: rgba(223, 168, 95, 0.92);
  border-color: var(--gold);
  color: #221b12;
  transform: scale(1.06);
}

/* Written testimonies have no thumbnail, so the quote does the work. */
.tcard--text {
  background: linear-gradient(
    160deg,
    rgba(245, 235, 217, 0.75),
    rgba(255, 255, 255, 0.9)
  );
}
/* The showcase card sets a written testimony larger; the compact card must
   not inherit that, so scope it away from the teaser. */
.tcard--text:not(.tcard--compact) .tcard__quote {
  font-size: clamp(1.15rem, 1.7vw, 1.4rem);
}

/* Every card opens with a panel of the same ratio — a photograph for video
   and audio, a quote plate for written entries — so the meta, quote and
   attribution rows line up across a row whether or not there is an image. */
.tcard__panel {
  position: relative;
  aspect-ratio: 16 / 9;
  flex: none;
}
/* A written entry needs a mark, not a whole empty plate. */
.tcard--text .tcard__panel {
  aspect-ratio: auto;
  min-height: 88px;
  display: grid;
  place-items: center;
  background:
    radial-gradient(
      120% 120% at 30% 0%,
      rgba(223, 168, 95, 0.14) 0%,
      rgba(223, 168, 95, 0) 60%
    ),
    linear-gradient(155deg, var(--cream) 0%, var(--warm-white) 70%);
  border-bottom: 1px solid rgba(61, 48, 37, 0.08);
}
.tcard--text .tcard__panel::after {
  content: "”";
  font-family: "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  line-height: 0.6;
  color: var(--champagne);
  font-size: 3.4rem;
  transform: translateY(0.18em);
  transition:
    transform 0.7s var(--ease-cinematic),
    color 0.5s ease;
}
.tcard--text:hover .tcard__panel::after {
  color: var(--gold);
  transform: translateY(0.18em) scale(1.06);
}

.tcard__body {
  padding: clamp(1.1rem, 2vw, 1.5rem);
  display: flex;
  flex-direction: column;
  flex: 1;
}
/* Attribution pins to the bottom so the baselines agree across the row. */
.tcard__quote {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.05rem, 1.5vw, 1.2rem);
  line-height: 1.42;
  color: var(--brown);
  margin-top: 0.9rem;
  margin-bottom: 1.3rem;
}
/* `margin-top: auto` pins the attribution to the bottom of the card, which is
   what keeps a row of cards agreeing on their baselines. */
.tcard__by {
  margin-top: auto;
  padding-top: 0.9rem;
  border-top: 1px solid rgba(61, 48, 37, 0.12);
}
.tcard__name {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--brown);
}
.tcard__place {
  display: block;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bronze);
  margin-top: 0.28rem;
}

/* Marks entries that are structure, not a real person's words. */
.pill-sample {
  border-color: rgba(222, 122, 30, 0.55);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-color: rgba(223, 168, 95, 0.45);
  background: rgba(223, 168, 95, 0.16);
  color: var(--antique);
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: inherit;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.5rem 1rem;
  border-radius: 999px;
  border: 1px solid rgba(102, 121, 138, 0.3);
  transition: all 0.45s var(--ease-cinematic);
  border-color: rgba(61, 48, 37, 0.2);
  color: var(--bronze);
}
.filter-chip:hover {
  border-color: var(--gold);
  color: var(--brown);
}
.filter-chip[aria-pressed="true"] {
  background: var(--brown);
  border-color: var(--brown);
  color: var(--ivory);
}

/* --------------------------------------------------------------------------
   15c. Articles — a banner beside its image, then a row of cards
   -------------------------------------------------------------------------- */
.post-hero {
  display: grid;
  grid-template-columns: 1fr;
  background: var(--warm-white);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: inherit;
  transition:
    transform 0.5s var(--ease-cinematic),
    box-shadow 0.5s var(--ease-cinematic);
}
.post-hero:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}
@media (min-width: 860px) {
  .post-hero {
    grid-template-columns: 1.05fr 1fr;
    align-items: stretch;
  }
}
/* Beside the copy the image takes whatever height the text sets. The picture
   is absolutely placed so it never feeds an intrinsic height back into the
   row — a percentage height against an indefinite row resolves to the image's
   natural size and turns a landscape crop into a portrait one. */
.post-hero__media {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 0;
}
.post-hero__media > img {
  position: absolute;
  inset: 0;
}
@media (min-width: 860px) {
  .post-hero__media {
    aspect-ratio: auto;
    align-self: stretch;
    min-height: 300px;
  }
}
.post-hero__tag,
.post-card__tag {
  position: absolute;
  left: 1rem;
  top: 1rem;
  z-index: 2;
}
.post-hero__body {
  padding: clamp(1.4rem, 2.6vw, 2.25rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.post-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 374px), 1fr));
  gap: clamp(1.1rem, 2vw, 1.75rem);
  margin-top: clamp(1.1rem, 2vw, 1.75rem);
}
.post-card {
  display: flex;
  flex-direction: column;
  background: var(--warm-white);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: inherit;
  transition:
    transform 0.5s var(--ease-cinematic),
    box-shadow 0.5s var(--ease-cinematic);
}
.post-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}
.post-card .media {
  border-radius: 0;
  flex: none;
}
.post-card__body {
  padding: clamp(1.05rem, 1.9vw, 1.4rem);
  display: flex;
  flex-direction: column;
  flex: 1;
}
.post-card__meta {
  margin-top: auto;
  padding-top: 1rem;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bronze);
}

.card-article .media img {
  transition: transform 1.6s var(--ease-cinematic);
}
.card-article:hover .media img {
  transform: scale(1.045);
}
.card-article h3 {
  transition: color 0.45s ease;
}
.card-article:hover h3 {
  color: var(--antique);
}

/* Copy is laid over the photograph. Two thirds of the panel is therefore
   given to a near-solid scrim — daylight photography cannot carry white text
   on its own — while the top third keeps the picture readable as a picture. */
.project-panel {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  min-height: clamp(430px, 58svh, 560px);
  display: flex;
  align-items: flex-end;
  text-decoration: none;
  transition:
    transform 0.5s var(--ease-cinematic),
    box-shadow 0.5s var(--ease-cinematic);
}
.project-panel:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}
.project-panel img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
  transform: scale(1.06);
  transition: transform 1.6s var(--ease-cinematic);
}
.project-panel:hover img {
  transform: scale(1.11);
}
.project-panel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    rgba(36, 27, 19, 0.97) 0%,
    rgba(36, 27, 19, 0.94) 46%,
    rgba(36, 27, 19, 0.82) 68%,
    rgba(36, 27, 19, 0.52) 86%,
    rgba(36, 27, 19, 0.3) 100%
  );
  transition: background 0.8s var(--ease-cinematic);
}
/* Description and action stay out of the way until the panel is hovered.
   Collapsed only where hovering is actually possible — touch, keyboard and
   reduced-motion users get the full copy up front. */
.project-panel__reveal > div {
  overflow: hidden;
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .project-panel__reveal {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition:
      grid-template-rows 0.6s var(--ease-cinematic),
      opacity 0.45s var(--ease-cinematic);
  }
  .project-panel:hover .project-panel__reveal,
  .project-panel:focus-visible .project-panel__reveal,
  .project-panel:focus-within .project-panel__reveal {
    grid-template-rows: 1fr;
    opacity: 1;
  }

  /* With the copy tucked away there is nothing to protect, so the scrim
     lightens and the photograph comes forward. It deepens again only as the
     description slides in. */
  .project-panel::before {
    background: linear-gradient(
      to top,
      rgba(36, 27, 19, 0.9) 0%,
      rgba(36, 27, 19, 0.66) 18%,
      rgba(36, 27, 19, 0.3) 40%,
      rgba(36, 27, 19, 0.06) 64%,
      rgba(36, 27, 19, 0) 100%
    );
  }
  .project-panel:hover::before,
  .project-panel:focus-within::before {
    background: linear-gradient(
      to top,
      rgba(36, 27, 19, 0.97) 0%,
      rgba(36, 27, 19, 0.94) 46%,
      rgba(36, 27, 19, 0.82) 68%,
      rgba(36, 27, 19, 0.52) 86%,
      rgba(36, 27, 19, 0.3) 100%
    );
  }
  /* Title lifts as the copy comes in. */
  .project-panel__head {
    transition: transform 0.6s var(--ease-cinematic);
  }
}

/* --------------------------------------------------------------------------
   15d. Story frame — a rounded plate, with the copy in a panel laid over it
   -------------------------------------------------------------------------- */
/* Not a full-bleed chapter: the photograph is held inside the shell, rounded,
   and the copy sits on it in its own panel rather than directly on the frame. */
.story-frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  background: var(--midnight);
}
.story-frame__media {
  position: relative;
  aspect-ratio: 3 / 2;
}
.story-frame__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 64% 46%;
}
/* Light on purpose. The panel carries the text contrast on its own, so this
   only has to settle the picture down enough for the panel to sit on it. */
.story-frame__media::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(
      to right,
      rgba(36, 27, 19, 0.52) 0%,
      rgba(36, 27, 19, 0.24) 46%,
      rgba(36, 27, 19, 0) 72%
    ),
    linear-gradient(to top, rgba(36, 27, 19, 0.45), rgba(36, 27, 19, 0) 58%);
}
/* Narrow screens stack: photograph above, copy beneath it on the frame's own
   dark ground. A panel laid over a portrait crop would cover the whole photo. */
.story-frame__panel {
  position: relative;
  padding: clamp(1.5rem, 6vw, 2rem);
}

@media (min-width: 1024px) {
  /* The frame is sized by the panel, not by a fixed ratio — a ratio tall
     enough for the panel at 1440 is too short for it at 1024, where the copy
     wraps deeper, and the panel would spill past the rounded edge. Centring it
     in a flex row lets the frame grow instead, which also keeps the frame's
     shape close to the photograph's 1.79:1 so the crop stays shallow. */
  .story-frame {
    display: flex;
    align-items: center;
    min-height: clamp(30rem, 40vw, 36rem);
  }
  .story-frame__media {
    position: absolute;
    inset: 0;
    aspect-ratio: auto;
  }
  /* Held to 46%: the donkey's head falls at 53% of the frame and the panel
     must not reach it. */
  .story-frame__panel {
    width: min(35rem, 44%);
    margin: clamp(1rem, 3vw, 2.75rem);
    padding: clamp(1.75rem, 2.6vw, 2.5rem);
    border-radius: var(--r-md);
    border: 1px solid rgba(251, 247, 239, 0.16);
    box-shadow: var(--shadow-lift);
    /* Glass over the photograph. Combined with the veil beneath it the ground
       reads at ~0.88 opaque — dark enough to carry the copy without blur, but
       still light enough that the city wall ghosts through the glass rather
       than vanishing behind a solid block. */
    background: rgba(36, 27, 19, 0.64);
    -webkit-backdrop-filter: blur(8px) saturate(1);
    backdrop-filter: blur(8px) saturate(1);
  }
}

/* --------------------------------------------------------------------------
   15d-ii. Split chapter — copy on one side, the photograph running off the other
   -------------------------------------------------------------------------- */
/* The third treatment in the family, for a frame that will take neither of the
   other two. A nave shot down its own axis has the crucifix at dead centre, so
   .story-frame's panel would cut it in half; and setting the copy above a wide
   plate leaves the photograph as a passive band under a header. Splitting the
   chapter gives the picture its full height and keeps the copy off it entirely.
   The image is absolutely placed rather than gridded so the copy can stay in
   the ordinary .shell and line up with every other chapter's left edge. */
.split-chapter {
  position: relative;
  overflow: hidden;
}
.split-chapter__media {
  position: relative;
  aspect-ratio: 3 / 2;
}
.split-chapter__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Right of centre so the crucifix and the rosary fall in the part of the
     frame the copy does not take. Held low as well: on a very wide screen the
     media panel turns wider than the photograph and starts cropping top and
     bottom instead, and the rosary lies at 92% of the frame. */
  object-position: 85% 62%;
}
/* Feathered into the ground rather than butted against it — a hard vertical
   seam down the middle of a chapter reads as two chapters. */
.split-chapter__media::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    to top,
    rgba(69, 52, 36, 0.85) 0%,
    rgba(69, 52, 36, 0) 34%
  );
}

.split-chapter__copy {
  max-width: 36rem;
}

@media (min-width: 1024px) {
  /* The split is 40/60 of the shell, not of the viewport. Measured off the
     viewport it collapses at the wide end: the shell caps at 1180px and
     centres, so its left margin grows faster than 40vw does and the copy
     column is squeezed to nothing on a 2560px screen. Anchoring both edges to
     the shell keeps the copy at a constant measure and lets the picture take
     everything to the right edge — which lands it at 56–60% of the viewport
     across the whole range. */
  .split-chapter__copy {
    max-width: calc(var(--shell) * 0.4 - 2.5rem);
  }
  /* Floor tracks width, because the problem it solves is a width problem: the
     media panel is as tall as the chapter, and past about 2000px it grows
     wider than the photograph's own 1.79:1 and starts cropping top and bottom
     instead of the sides. The crucifix sits at 22% of the frame and the rosary
     at 92%, so there is very little to give. 27vw holds the panel near 2:1. */
  .split-chapter {
    min-height: clamp(32rem, 27vw, 60rem);
    display: flex;
    align-items: center;
  }
  .split-chapter__media {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: calc(50% - var(--shell) / 2 + var(--shell) * 0.4);
    aspect-ratio: auto;
  }
  .split-chapter__media::after {
    background: linear-gradient(
      to right,
      var(--navy) 0%,
      rgba(69, 52, 36, 0.55) 12%,
      rgba(69, 52, 36, 0) 34%
    );
  }
}

/* --------------------------------------------------------------------------
   15e. Post body — the only long-form prose on the site
   -------------------------------------------------------------------------- */
/* Everywhere else copy is set block by block with utilities, because every
   other block is hand-placed. An article body is written, not laid out, so it
   gets element styles instead and the markup stays plain HTML. */
.post-body {
  color: var(--bronze);
  font-size: 1.02rem;
  line-height: 1.85;
  /* .shell-narrow caps its children at 860px, which at this size runs to
     about 105 characters a line — far past what anyone reads comfortably.
     62ch lands near 70. Declared after that rule, so it wins on source
     order at equal specificity. */
  max-width: 62ch;
  margin-inline: auto;
}
.post-body > * + * {
  margin-top: 1.35em;
}
/* The opening paragraph carries the piece — set a step up, as the page heads
   do with .t-lead. */
.post-body > p:first-child {
  font-size: clamp(1.0125rem, 1.1vw, 1.1rem);
  line-height: 1.75;
  color: var(--brown);
}
.post-body h2 {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: clamp(1.3rem, 2.1vw, 1.85rem);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.025em;
  color: var(--brownd);
  margin-top: 2em;
}
.post-body h3 {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 1.06rem;
  font-weight: 700;
  letter-spacing: -0.012em;
  color: var(--brownd);
  margin-top: 2em;
}
.post-body h2 + *,
.post-body h3 + * {
  margin-top: 0.75em;
}
.post-body strong {
  color: var(--brownd);
  font-weight: 600;
}
.post-body a:not(.btn) {
  color: var(--antique);
  text-decoration: underline;
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(138, 85, 38, 0.4);
  transition: text-decoration-color 0.4s ease;
}
.post-body a:not(.btn):hover {
  text-decoration-color: var(--gold);
}
.post-body ul,
.post-body ol {
  padding-left: 0;
  list-style: none;
}
.post-body li + li {
  margin-top: 0.7em;
}
.post-body ul > li,
.post-body ol > li {
  position: relative;
  padding-left: 1.6rem;
}
/* A gold rule rather than a bullet glyph, so the list reads in the same
   vocabulary as the section rules. */
.post-body ul > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.82em;
  width: 0.7rem;
  height: 1px;
  background: var(--gold);
}
.post-body ol {
  counter-reset: post-list;
}
.post-body ol > li {
  counter-increment: post-list;
}
.post-body ol > li::before {
  content: counter(post-list);
  position: absolute;
  left: 0;
  top: 0;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--gold);
  line-height: 2.6;
}
/* Pull-quote. Flush left against a gold rule — the same device the chapters
   use for a quotation, at article scale. */
.post-body blockquote {
  margin-block: 2.2em;
  padding-left: clamp(1.25rem, 3vw, 2rem);
  border-left: 2px solid var(--gold);
}
.post-body blockquote p {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: clamp(1.15rem, 1.9vw, 1.45rem);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.02em;
  color: var(--brownd);
}
.post-body blockquote cite {
  display: block;
  margin-top: 0.9rem;
  font-size: 0.63rem;
  font-weight: 600;
  font-style: normal;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--antique);
}
.post-body figure {
  margin-block: 2.4em;
}
.post-body figure img {
  width: 100%;
  /* Height comes from the intrinsic ratio (see the img reset). The width and
     height attributes stay on the tag so the browser reserves the right space
     before the file arrives and the copy below it does not jump. */
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
}
.post-body figcaption {
  margin-top: 0.85rem;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--antique);
}
.post-body hr {
  margin-block: 2.6em;
  border: 0;
  height: 1px;
  background: linear-gradient(
    to right,
    rgba(223, 168, 95, 0.7),
    rgba(223, 168, 95, 0)
  );
}

/* Date · reading time · formats, under the title. */
.post-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem 0.9rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(251, 247, 239, 0.62);
}
.post-meta__dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--gold);
}

/* --------------------------------------------------------------------------
   16. Collage (Catholic life)
   -------------------------------------------------------------------------- */
.collage {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(0.65rem, 1.4vw, 1.25rem);
}
.collage .media {
  border-radius: var(--r-xs);
}
.collage .media img {
  transition: transform 1.8s var(--ease-cinematic);
}
.collage .media:hover img {
  transform: scale(1.05);
}
.collage-a {
  grid-column: span 6;
  aspect-ratio: 3 / 2;
}
.collage-b {
  grid-column: span 3;
  aspect-ratio: 1;
}
.collage-c {
  grid-column: span 3;
  aspect-ratio: 1;
}
.collage-d {
  grid-column: span 6;
  aspect-ratio: 16 / 9;
}
@media (min-width: 900px) {
  .collage-a {
    grid-column: span 4;
    aspect-ratio: 4 / 3;
  }
  .collage-b {
    grid-column: span 2;
    aspect-ratio: 3 / 4;
    margin-top: clamp(1.5rem, 4vw, 3.5rem);
  }
  .collage-c {
    grid-column: span 2;
    aspect-ratio: 3 / 4;
    margin-top: clamp(-3.5rem, -3vw, -1rem);
  }
  .collage-d {
    grid-column: span 4;
    aspect-ratio: 16 / 10;
  }
}

/* --------------------------------------------------------------------------
   17a. Gallery — album listing
   -------------------------------------------------------------------------- */
/* 300px floor lands three-up in the shell, so six albums fill two clean rows
   rather than leaving a four-then-two orphan. */
.album-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: clamp(1.75rem, 3vw, 2.75rem) clamp(1.25rem, 2.2vw, 2rem);
}

/* A <button> now, not an <a>: it opens a dialog rather than going anywhere,
   and the six hrefs it used to carry pointed at a gallery/ directory that was
   never created. Buttons bring their own agenda — UA background, border,
   padding, centred text, inherited-but-not-quite font — so all of it is
   cleared here rather than relying on the reset. */
.album-card {
  display: block;
  width: 100%;
  text-align: inherit;
  text-decoration: none;
  color: inherit;
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  position: relative;
}

/* Album pages carry their own head and breadcrumb, so the in-grid crumb bar
   the drill-down needed is gone with it. */

/* The sub-album names, listed on the parent card so a card that leads
   somewhere says where it leads. */
.album-card__inside {
  margin-top: 0.6rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  line-height: 1.6;
  color: var(--antique);
}
.on-dark .album-card__inside {
  color: var(--champagne);
}

.album-card__go svg {
  transition: transform 0.5s var(--ease-cinematic);
}

/* A single plate peeking out below the cover — reads as "more prints
   underneath" without becoming a card. */
.album-card__stack {
  position: relative;
  padding-bottom: 7px;
}
.album-card__stack::before {
  content: "";
  position: absolute;
  left: 9px;
  right: 9px;
  bottom: 0;
  height: 26px;
  border-radius: var(--r-sm);
  background: rgba(69, 52, 36, 0.1);
  border: 1px solid rgba(69, 52, 36, 0.16);
  transition: transform 0.7s var(--ease-cinematic);
}
.on-dark .album-card__stack::before {
  background: rgba(251, 247, 239, 0.1);
  border-color: rgba(251, 247, 239, 0.18);
}
.album-card:hover .album-card__stack::before {
  transform: translateY(4px);
}

.album-card .media {
  aspect-ratio: 4 / 3;
  position: relative;
  z-index: 1;
}
.album-card .media img {
  transition: transform 1.5s var(--ease-cinematic);
}
.album-card:hover .media img,
.album-card:focus-visible .media img {
  transform: scale(1.05);
}
.album-card .media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to top,
    rgba(36, 27, 19, 0.62),
    rgba(36, 27, 19, 0) 52%
  );
}

.album-card__count {
  position: absolute;
  left: 0.85rem;
  bottom: 0.8rem;
  z-index: 2;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ivory);
}
.album-card__go {
  position: absolute;
  right: 0.85rem;
  bottom: 0.8rem;
  z-index: 2;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--ivory);
  border: 1px solid rgba(251, 247, 239, 0.4);
  background: rgba(36, 27, 19, 0.3);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition:
    background-color 0.5s var(--ease-cinematic),
    color 0.5s var(--ease-cinematic),
    border-color 0.5s var(--ease-cinematic);
}
.album-card:hover .album-card__go,
.album-card:focus-visible .album-card__go {
  background: var(--gold);
  border-color: var(--gold);
  color: #221b12;
}

/* Album cards sit on a dark band on the home page and on ivory on the gallery
   page, so their colours come from context instead of being baked in. */
.album-card__name {
  font-family: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  font-weight: 400;
  font-size: clamp(1.05rem, 1.4vw, 1.3rem);
  line-height: 1.34;
  margin-top: 1rem;
  color: var(--brown);
  transition: color 0.4s ease;
}
.album-card__blurb {
  font-size: 0.86rem;
  line-height: 1.6;
  margin-top: 0.45rem;
  color: var(--bronze);
}
.album-card:hover .album-card__name {
  color: var(--antique);
}

.on-dark .album-card__name {
  color: var(--ivory);
}
.on-dark .album-card__blurb {
  color: rgba(251, 247, 239, 0.72);
}
.on-dark .album-card:hover .album-card__name {
  color: var(--champagne);
}

/* --------------------------------------------------------------------------
   17b. Masonry + lightbox — used by the album pages
   -------------------------------------------------------------------------- */
.masonry {
  column-count: 2;
  column-gap: clamp(0.65rem, 1.2vw, 1.15rem);
}
@media (min-width: 700px) {
  .masonry {
    column-count: 3;
  }
}
@media (min-width: 1100px) {
  .masonry {
    column-count: 4;
  }
}
.masonry-item {
  border-radius: var(--r-sm);
  break-inside: avoid;
  margin-bottom: clamp(0.65rem, 1.2vw, 1.15rem);
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
  position: relative;
  overflow: hidden;
  border-radius: var(--r-xs);
}
.masonry-item img {
  width: 100%;
  height: auto;
  transition:
    transform 1.4s var(--ease-cinematic),
    filter 1.4s var(--ease-cinematic);
}
.masonry-item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(36, 27, 19, 0.55),
    rgba(36, 27, 19, 0) 55%
  );
  opacity: 0;
  transition: opacity 0.7s var(--ease-cinematic);
}
.masonry-item:hover img {
  transform: scale(1.045);
}
.masonry-item:hover::after,
.masonry-item:focus-visible::after {
  opacity: 1;
}
.masonry-item figcaption {
  position: absolute;
  left: 1rem;
  right: 1rem;
  bottom: 0.9rem;
  z-index: 2;
  text-align: left;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ivory);
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 0.7s var(--ease-cinematic),
    transform 0.7s var(--ease-cinematic);
}
.masonry-item:hover figcaption,
.masonry-item:focus-visible figcaption {
  opacity: 1;
  transform: translateY(0);
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(12, 14, 20, 0.96);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.55s var(--ease-veil),
    visibility 0.55s;
}
.lightbox.is-open {
  opacity: 1;
  visibility: visible;
}
.lightbox__figure {
  margin: 0;
  max-width: min(1200px, 100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  transform: scale(0.94);
  transition: transform 0.7s var(--ease-veil);
}
.lightbox.is-open .lightbox__figure {
  transform: scale(1);
}
/* The stage holds either a photograph or a player, so the sizing that used to
   sit on the <img> lives here and both inherit it. */
.lightbox__stage {
  display: flex;
  justify-content: center;
}
.lightbox__figure img {
  max-height: min(76svh, 900px);
  width: auto;
  max-width: 100%;
  margin-inline: auto;
  object-fit: contain;
  border-radius: var(--r-xs);
  box-shadow: 0 50px 120px -40px rgba(0, 0, 0, 0.9);
}

/* Video: the poster stands in until it is asked for. */
.lightbox__poster {
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  max-width: 100%;
  line-height: 0;
}
.lightbox__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 78px;
  height: 78px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--gold);
  color: var(--midnight);
  box-shadow: 0 20px 50px -14px rgba(0, 0, 0, 0.7);
  transition:
    transform 0.5s var(--ease-cinematic),
    background-color 0.5s var(--ease-cinematic);
}
.lightbox__poster:hover .lightbox__play,
.lightbox__poster:focus-visible .lightbox__play {
  transform: scale(1.08);
  background: var(--champagne);
}
/* Sized by width, not by the 16:9 box, so a tall window does not push the
   player past the caption. */
.lightbox__video {
  width: min(1200px, 100%);
  max-height: min(76svh, 900px);
  aspect-ratio: 16 / 9;
  border-radius: var(--r-xs);
  overflow: hidden;
  background: #000;
  box-shadow: 0 50px 120px -40px rgba(0, 0, 0, 0.9);
}
.lightbox__video iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
.lightbox__caption {
  text-align: center;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(251, 247, 239, 0.66);
}
.lightbox__btn {
  position: absolute;
  z-index: 2;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(251, 247, 239, 0.08);
  border: 1px solid rgba(251, 247, 239, 0.26);
  color: var(--ivory);
  cursor: pointer;
  transition:
    background-color 0.45s ease,
    border-color 0.45s ease,
    transform 0.45s ease;
}
.lightbox__btn:hover {
  background: rgba(223, 168, 95, 0.85);
  border-color: var(--gold);
  color: #1b1610;
}
.lightbox__close {
  top: clamp(1rem, 3vw, 2rem);
  right: clamp(1rem, 3vw, 2rem);
}
.lightbox__prev {
  left: clamp(0.5rem, 2vw, 2rem);
  top: 50%;
  transform: translateY(-50%);
}
.lightbox__next {
  right: clamp(0.5rem, 2vw, 2rem);
  top: 50%;
  transform: translateY(-50%);
}
.lightbox__prev:hover,
.lightbox__next:hover {
  transform: translateY(-50%) scale(1.06);
}

/* --------------------------------------------------------------------------
   18. Contact + footer
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Contact panel — an address, then direct lines, then the marks
   -------------------------------------------------------------------------- */
/* This replaces .social-row, which gave six identical full-width rows to six
   things of quite different weight: a postal address that is read rather than
   clicked, three lines worth a name and a handle, and three logos anyone
   recognises unlabelled. Each now gets the shape it needs. */
.contact-place__label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--antique);
}
.contact-place__lines {
  margin-top: 0.85rem;
  font-style: normal;
  font-size: 1.02rem;
  line-height: 1.65;
  color: var(--brownd);
}
.contact-place__mail {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: 0.9rem;
  /* The tap target keeps its 44px without the gap it would otherwise open up
     above and below the line. */
  padding-block: 0.7rem;
  font-size: 0.9rem;
  color: var(--antique);
  text-decoration: underline;
  text-underline-offset: 0.22em;
  text-decoration-color: rgba(138, 85, 38, 0.35);
  transition:
    color 0.4s ease,
    text-decoration-color 0.4s ease;
  overflow-wrap: anywhere;
}
.contact-place__mail:hover {
  color: var(--brownd);
  text-decoration-color: var(--gold);
}
.contact-place__mail svg {
  flex: none;
}

.contact-lines {
  margin-top: 1.35rem;
  border-top: 1px solid rgba(61, 48, 37, 0.12);
}
.contact-line {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.95rem 0;
  border-bottom: 1px solid rgba(61, 48, 37, 0.1);
  text-decoration: none;
  color: inherit;
  transition:
    padding-left 0.55s var(--ease-cinematic),
    border-color 0.55s ease;
}
.contact-line:hover {
  padding-left: 0.55rem;
  border-color: rgba(223, 168, 95, 0.7);
}
.contact-line__icon {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  border: 1px solid rgba(61, 48, 37, 0.18);
  color: var(--brown);
  transition:
    background-color 0.5s var(--ease-cinematic),
    border-color 0.5s var(--ease-cinematic),
    color 0.5s var(--ease-cinematic);
}
.contact-line:hover .contact-line__icon {
  background: var(--gold);
  border-color: var(--gold);
  color: #221b12;
}
.contact-line__label {
  display: block;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--brownd);
}
.contact-line__handle {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.8rem;
  color: var(--bronze);
  overflow-wrap: anywhere;
}

.contact-social {
  margin-top: auto;
  padding-top: 1.5rem;
}
.contact-social__label {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--antique);
}
.contact-social__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 0.85rem;
}
.contact-social__link {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  border: 1px solid rgba(61, 48, 37, 0.18);
  color: var(--brown);
  transition:
    background-color 0.45s var(--ease-cinematic),
    border-color 0.45s var(--ease-cinematic),
    color 0.45s var(--ease-cinematic),
    transform 0.45s var(--ease-cinematic);
}
.contact-social__link:hover {
  background: var(--gold);
  border-color: var(--gold);
  color: #221b12;
  transform: translateY(-2px);
}

/* --------------------------------------------------------------------------
   18b. Footer — one brand block, four equal link columns
   -------------------------------------------------------------------------- */
.footer-grid {
  display: grid;
  gap: clamp(2.25rem, 4vw, 3.5rem);
}
@media (min-width: 1024px) {
  .footer-grid {
    grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
    align-items: start;
  }
}

/* Equal tracks at every width, so no column can tower over its neighbours. */
.footer-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.25rem) clamp(1.25rem, 2.5vw, 2rem);
}
@media (min-width: 640px) {
  .footer-cols {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.footer-col__title {
  font-size: 0.655rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--champagne);
}
.footer-col__links {
  margin-top: 0.65rem;
}

/* 40px rows: comfortably past the 24px WCAG 2.5.8 minimum, and tight enough
   that a four-item column does not leave a void beside a three-item one. */
.footer-link {
  display: flex;
  align-items: center;
  min-height: 40px;
  font-size: 0.86rem;
  color: rgba(251, 247, 239, 0.72);
  text-decoration: none;
  transition:
    color 0.4s ease,
    transform 0.5s var(--ease-cinematic);
}
.footer-link:hover {
  color: var(--champagne);
  transform: translateX(4px);
}

.footer-social {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.6rem;
}
.footer-social__link {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: rgba(251, 247, 239, 0.8);
  border: 1px solid rgba(251, 247, 239, 0.22);
  transition:
    background-color 0.45s var(--ease-cinematic),
    color 0.45s var(--ease-cinematic),
    border-color 0.45s var(--ease-cinematic),
    transform 0.45s var(--ease-cinematic);
}
.footer-social__link:hover {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--midnight);
  transform: translateY(-2px);
}

.footer-base {
  margin-top: clamp(2rem, 4vh, 3rem);
  padding-top: 1.5rem;
  border-top: 1px solid rgba(251, 247, 239, 0.12);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  font-size: 0.72rem;
  color: rgba(251, 247, 239, 0.6);
}
.footer-base__note {
  color: var(--champagne);
}

/* --------------------------------------------------------------------------
   19. Reduced motion — strip transforms, keep meaning
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  [data-reveal],
  [data-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
  .line-mask > span {
    transform: none !important;
  }
  .rule-draw {
    transform: scaleX(1) !important;
  }
  .rule-draw-y {
    transform: scaleY(1) !important;
  }
  .hero__bg img,
  .dream-panel__media img,
  .project-panel img,
  .parallax-media > img,
  .menu-overlay__bg img {
    transform: none !important;
  }
  .timeline__spine i {
    transform: scaleY(1) !important;
  }
  .dust,
  .scroll-cue__track::after {
    display: none;
  }
  .hero__bg {
    inset: 0;
  }
}

/* Utility: honour reduced motion for JS-driven pieces too. */
.no-motion .dust {
  display: none;
}

/* --------------------------------------------------------------------------
   20. Cross-cutting surface details
   -------------------------------------------------------------------------- */
.lightbox__figure img {
  border-radius: var(--r-md);
}

.collage .media {
  border-radius: var(--r-md);
}

.btn-ghost-dark:hover {
  border-color: var(--gold);
  color: var(--brown);
  background: rgba(223, 168, 95, 0.12);
}

.filter-chip[aria-pressed="true"] {
  background: var(--brown);
  border-color: var(--brown);
  color: #fff;
}

.tl-node::before {
  background: var(--ivory);
  border-color: var(--gold);
}

/* --------------------------------------------------------------------------
   21. Rhythm utilities — one scale, applied by name
   -------------------------------------------------------------------------- */
.section-y {
  padding-block: var(--space-section);
}
.section-y-lg {
  padding-block: var(--space-section-lg);
}
.section-pb {
  padding-bottom: var(--space-section);
}
.block-mt {
  margin-top: var(--space-block);
}
.tight-mt {
  margin-top: var(--space-tight);
}
.grid-gutter {
  gap: var(--space-block) var(--gutter);
}

/* --------------------------------------------------------------------------
   21. Contact — form and detail panels
   -------------------------------------------------------------------------- */
/* Both cards fill the grid row, so the form and the channel list end on the
   same line rather than one running past the other. */
.panel-card {
  display: flex;
  flex-direction: column;
  background: var(--warm-white);
  border: 1px solid rgba(61, 48, 37, 0.09);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  padding: clamp(1.4rem, 2.4vw, 1.9rem);
}
.panel-card--dark {
  background: var(--midnight);
  border-color: transparent;
}

.form-card {
  background: var(--warm-white);
  border: 1px solid rgba(61, 48, 37, 0.09);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  padding: clamp(1.4rem, 2.6vw, 2.1rem);
  /* Flex, not grid: matching the channel card's height leaves spare room, and
     it belongs in the message box rather than spread between the fields. */
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
}
.field--grow {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 160px;
}
.field--grow textarea.field__input {
  flex: 1 1 auto;
}

.form-grid {
  display: grid;
  gap: 1.15rem;
}
@media (min-width: 560px) {
  .form-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.field__label {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--brown);
  margin-bottom: 0.45rem;
}
.field__req {
  color: var(--antique);
}

.field__input {
  width: 100%;
  min-height: 48px;
  padding: 0.75rem 0.95rem;
  font-family: inherit;
  font-size: 0.94rem;
  color: var(--brown);
  background: var(--ivory);
  border: 1px solid rgba(61, 48, 37, 0.16);
  border-radius: var(--r-xs);
  transition:
    border-color 0.35s ease,
    box-shadow 0.35s ease,
    background-color 0.35s ease;
}
textarea.field__input {
  min-height: 140px;
  resize: vertical;
  line-height: 1.6;
}
.field__input::placeholder {
  color: rgba(107, 90, 74, 0.6);
}
.field__input:hover {
  border-color: rgba(61, 48, 37, 0.3);
}
.field__input:focus {
  outline: none;
  background: var(--warm-white);
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(223, 168, 95, 0.28);
}

/* Native select keeps its own arrow on some platforms; hide it and draw one
   that matches the rest of the system. */
.field__select {
  position: relative;
}
.field__select .field__input {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.6rem;
}
.field__chev {
  position: absolute;
  right: 1rem;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--bronze);
}

.field__input[aria-invalid="true"] {
  border-color: #a8361f;
  background: rgba(168, 54, 31, 0.04);
}
.field__input[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px rgba(168, 54, 31, 0.22);
}
.field__err {
  margin-top: 0.4rem;
  font-size: 0.78rem;
  font-weight: 500;
  color: #8f2d19;
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem 1.25rem;
  margin-top: 0.25rem;
}
.form-note {
  font-size: 0.78rem;
  color: var(--bronze);
  max-width: 34ch;
}

.form-status {
  font-size: 0.86rem;
  font-weight: 500;
  border-radius: var(--r-xs);
  padding: 0.85rem 1rem;
  display: none;
}
.form-status.is-ok {
  display: block;
  color: #2f5d3a;
  background: rgba(47, 93, 58, 0.09);
  border: 1px solid rgba(47, 93, 58, 0.24);
}
.form-status.is-err {
  display: block;
  color: #8f2d19;
  background: rgba(168, 54, 31, 0.07);
  border: 1px solid rgba(168, 54, 31, 0.24);
}

/* Contact panel: the surplus height left over when this card is shorter than
   the form beside it now pools above the social marks — .contact-social takes
   it with margin-top:auto — instead of being spread across the rows. Three
   rows sharing it would have stretched each one out of proportion; six rows
   could absorb it, three cannot. */

/* The two contact columns each run heading → intro → card. Reserving the same
   intro height keeps both cards starting on the same line even when the copy
   wraps to a different number of lines. */
@media (min-width: 1024px) {
  .col-intro {
    min-height: 3.4rem;
  }
}

/* --------------------------------------------------------------------------
   22. Contact columns — equal height without overflowing the section
   --------------------------------------------------------------------------
   `height: 100%` resolved against the grid row, so a card needing more than
   that row escaped the section and covered the band below — the submit button
   ended up unclickable. `flex: 1` was no better: its 0% basis drops the card
   out of the column's intrinsic height, so the row sized itself from the
   shorter column and the taller card overflowed again.

   An `auto` basis keeps each card's natural height in the row calculation and
   still lets the shorter one grow to match. */
.contact-col {
  display: flex;
  flex-direction: column;
}
.contact-col > .form-card,
.contact-col > .panel-card {
  flex: 1 1 auto;
}
