/* ============================================================================
   GLOBAL ELITE CONCIERGE — Core design system
   Black · Cream · Sand · Gold, with a Moorish / Middle Eastern ornament layer.
   ========================================================================= */

/* ---------------------------------------------------------------- 1. TOKENS */
:root {
  /* ---- Brand constants. Identical in both themes. ---- */
  --cream:      #EAE6DB;
  --sand:       #CCBFAD;
  --gold:       #C8A55B;
  --gold-lt:    #E8D5A0;
  --gold-dk:    #8C6D33;
  --gold-sheen: linear-gradient(120deg, transparent 20%, rgba(232,213,160,.55) 48%, transparent 76%);

  /* Two gold gradients. The bright one reads on dark grounds; its pale midtone
     disappears on a light ground, so light surfaces get the deep one. */
  --gold-grad-bright: linear-gradient(105deg, #8C6D33 0%, #E8D5A0 28%, #C8A55B 52%, #E8D5A0 76%, #8C6D33 100%);
  --gold-grad-deep:   linear-gradient(105deg, #5E4519 0%, #A8842F 28%, #7A5C28 52%, #A8842F 76%, #5E4519 100%);
  --gold-grad:        var(--gold-grad-bright);

  /* Fixed darks, for surfaces that stay dark in BOTH themes — anything sitting
     over photography, where cream text is the only legible option. */
  --ink-fixed:  #08080A;
  --char-fixed: #101014;

  /* Text on a gold fill, and text on the warm section. Both of those grounds are
     light in either theme, so these never flip. */
  --on-gold:      #0B0B0C;
  --text-warm:    #14141A;
  --text-warm-mut:rgba(20, 20, 26, 0.74);

  /* ================= DARK THEME (default) ================= */
  --bg:         #000000;   /* page ground                      */
  --bg-alt:     #08080A;   /* alternating section              */
  --bg-raise:   #101014;   /* cards, form panels               */
  --bg-sunk:    #1A1A1F;   /* image placeholders               */
  --bg-invert:  #EAE6DB;   /* the one contrast section         */
  --bg-warm:    #CCBFAD;   /* founder section                  */

  --text:       #EAE6DB;
  --text-muted: rgba(204, 191, 173, 0.78);
  /* 0.55 measured at 3.90:1 on black — under AA. 0.64 lands at 4.7:1. */
  --text-dim:   rgba(204, 191, 173, 0.64);
  --text-invert:      #101014;
  --text-invert-mut:  rgba(16, 16, 20, 0.74);

  --line:       rgba(234, 230, 219, 0.12);
  --line-gold:  rgba(200, 165, 91, 0.28);

  --gold-on-bg:     #C8A55B;   /* gold that must read as TEXT on --bg        */
  --gold-on-invert: #7A5C28;   /* gold that must read as TEXT on --bg-invert */

  --field-bg:   rgba(234, 230, 219, 0.035);
  --field-bg-f: rgba(234, 230, 219, 0.06);
  --shadow-lg:  0 20px 50px rgba(0, 0, 0, .6);
  --scrim-top:  rgba(0, 0, 0, .9);
  --header-bg:  rgba(8, 8, 10, .86);

  /* Type */
  --font-display: "Cormorant Garamond", "Times New Roman", serif;
  --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --fs-hero:    clamp(2.9rem, 7.4vw, 7rem);
  --fs-display: clamp(2.4rem, 5.4vw, 4.9rem);
  --fs-title:   clamp(1.9rem, 3.6vw, 3.1rem);
  --fs-sub:     clamp(1.3rem, 2.2vw, 1.85rem);
  --fs-lead:    clamp(1.02rem, 1.35vw, 1.24rem);
  --fs-body:    clamp(0.95rem, 1.05vw, 1.05rem);
  --fs-small:   0.875rem;
  --fs-label:   0.69rem;

  /* Space */
  --gutter:     clamp(1.25rem, 5vw, 5.5rem);
  --section-y:  clamp(4.5rem, 9.5vw, 9rem);
  --max:        1460px;
  --max-text:   68ch;

  /* Motion */
  --ease:       cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out:cubic-bezier(0.65, 0, 0.35, 1);
  --t-fast:     .35s;
  --t-med:      .7s;
  --t-slow:     1.2s;

  --header-h:   86px;
}

/* ================= LIGHT THEME =================
   Set by the server from the gec_theme cookie, so the correct palette is in the
   markup on first paint and there is no flash of the wrong theme. */
:root[data-theme="light"] {
  --bg:         #F7F5F0;
  --bg-alt:     #EFEBE2;
  --bg-raise:   #FFFFFF;
  --bg-sunk:    #E4DFD4;
  --bg-invert:  #0B0B0C;   /* the contrast section flips to near-black */
  --bg-warm:    #E6DED0;

  /* Muted and dim are pushed darker than their dark-theme counterparts: the same
     opacity over a pale ground lands well under 4.5:1. Measured, not guessed. */
  --text:       #14141A;
  --text-muted: rgba(20, 20, 26, 0.82);
  --text-dim:   rgba(20, 20, 26, 0.68);
  --text-invert:      #EAE6DB;
  --text-invert-mut:  rgba(234, 230, 219, 0.76);

  --line:       rgba(20, 20, 26, 0.14);
  --line-gold:  rgba(140, 109, 51, 0.38);

  /* Gold flips: #C8A55B fails contrast on a pale ground, so text-gold darkens
     and the "on invert" gold brightens. Decorative gold stays as-is. */
  --gold-on-bg:     #7A5C28;
  --gold-on-invert: #C8A55B;

  --field-bg:   rgba(20, 20, 26, 0.035);
  --field-bg-f: rgba(255, 255, 255, 0.9);
  --shadow-lg:  0 20px 50px rgba(20, 20, 26, .16);
  --scrim-top:  rgba(0, 0, 0, .9);
  --header-bg:  rgba(247, 245, 240, .9);

  --gold-grad:  var(--gold-grad-deep);

  color-scheme: light;
}

:root { color-scheme: dark; }

/* Theme swap should feel deliberate, not like a page reload. */
:root.theme-ready body,
:root.theme-ready .section,
:root.theme-ready .card,
:root.theme-ready .footer {
  transition: background-color .45s var(--ease), color .45s var(--ease),
              border-color .45s var(--ease);
}

/* The header is excluded from the colour transition on purpose: its text tokens
   are also swapped by the .is-stuck class, and a transition spanning both
   changes settles on the wrong value. Background and border still cross-fade. */
:root.theme-ready .header {
  transition: background-color .45s var(--ease), border-color .45s var(--ease),
              height .5s var(--ease);
}

@media (max-width: 860px) { :root { --header-h: 68px; } }

/* ------------------------------------------------------------- 2. RESET */
*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; padding: 0; }

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

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 300;
  line-height: 1.75;
  letter-spacing: 0.012em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

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

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

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

button { background: none; border: 0; cursor: pointer; }

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

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

/* --------------------------------------------------------- 3. TYPOGRAPHY */
h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.t-hero    { font-size: var(--fs-hero);    line-height: 0.96; }
.t-display { font-size: var(--fs-display); }
.t-title   { font-size: var(--fs-title); }
.t-sub     { font-size: var(--fs-sub);  line-height: 1.22; }

.lead {
  font-size: var(--fs-lead);
  line-height: 1.72;
  color: var(--text-muted);
  font-weight: 300;
  max-width: var(--max-text);
}

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

/* Eyebrow label — letterspaced gold caps */
.label {
  display: inline-flex;
  align-items: center;
  gap: .7em;
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--gold-on-bg);
  line-height: 1;
}

.label::before {
  content: "";
  width: 1.9em; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold));
  flex: none;
}

.label--center::after {
  content: "";
  width: 1.9em; height: 1px;
  background: linear-gradient(90deg, var(--gold), transparent);
  flex: none;
}

/* Gold gradient text */
.gold-text {
  background: var(--gold-grad);
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  color: var(--gold-on-bg);
  -webkit-text-fill-color: transparent;
  animation: goldShift 9s linear infinite;
}

@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .gold-text { -webkit-text-fill-color: var(--gold-on-bg); color: var(--gold-on-bg); }
}

@keyframes goldShift {
  to { background-position: 200% center; }
}

.italic-accent {
  font-style: italic;
  font-weight: 300;
}

/* ------------------------------------------------------------ 4. LAYOUT */
.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.wrap--narrow { max-width: 1040px; }

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

/* Alternating section — one step off the page ground, in either theme. */
.section--alt { background: var(--bg-alt); }

/* The deliberate contrast section. Cream against the dark theme, near-black
   against the light one, so the page always has one inverted band.
   Rather than override each property, the block redefines the inherited tokens —
   everything nested picks the right colour up automatically. */
.section--invert {
  background: var(--bg-invert);
  --text:       var(--text-invert);
  --text-muted: var(--text-invert-mut);
  --text-dim:   var(--text-invert-mut);
  --gold-on-bg: var(--gold-on-invert);
  --bg-raise:   color-mix(in srgb, var(--bg-invert) 92%, var(--text-invert));
  --line:       color-mix(in srgb, var(--text-invert) 16%, transparent);
  color: var(--text);
}

/* Warm sand band. Light in BOTH themes, so its text never flips. */
.section--warm {
  background: var(--bg-warm);
  --text:       var(--text-warm);
  --text-muted: var(--text-warm-mut);
  --text-dim:   var(--text-warm-mut);
  /* The sand ground is light but not pale, so gold has to go deeper here than
     it does on the cream sections: #7A5C28 measured 3.43:1, #5E4519 gives 4.9:1. */
  --gold-on-bg: #5E4519;
  --line:       rgba(20, 20, 26, .18);
  color: var(--text);
}

.section--invert .lead,
.section--warm   .lead { color: var(--text-muted); }

.section-head { margin-bottom: clamp(2.5rem, 5vw, 4.5rem); }

.section-head--center {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.3rem;
}

.section-head--center .lead { margin-inline: auto; text-align: center; }

.stack-sm { display: flex; flex-direction: column; gap: 1rem; }
.stack    { display: flex; flex-direction: column; gap: 1.6rem; }
.stack-lg { display: flex; flex-direction: column; gap: 2.4rem; }

/* ---------------------------------------------------- 5. MOORISH ORNAMENT */

/* Zellige — 8-point star (khatam) tessellation, used as a whisper-level texture */
.zellige {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72' viewBox='0 0 72 72'%3E%3Cg fill='none' stroke='%23C8A55B' stroke-width='.9' opacity='.42'%3E%3Cpolygon points='49,36 42.2,38.8 42.2,42.2 38.8,42.2 36,49 33.2,42.2 29.8,42.2 29.8,38.8 23,36 29.8,33.2 29.8,29.8 33.2,29.8 36,23 38.8,29.8 42.2,29.8 42.2,33.2'/%3E%3Cpolygon points='13,0 6.2,2.8 6.2,6.2 2.8,6.2 0,13 -2.8,6.2 -6.2,6.2 -6.2,2.8 -13,0 -6.2,-2.8 -6.2,-6.2 -2.8,-6.2 0,-13 2.8,-6.2 6.2,-6.2 6.2,-2.8'/%3E%3Cpolygon points='85,0 78.2,2.8 78.2,6.2 74.8,6.2 72,13 69.2,6.2 65.8,6.2 65.8,2.8 59,0 65.8,-2.8 65.8,-6.2 69.2,-6.2 72,-13 74.8,-6.2 78.2,-6.2 78.2,-2.8'/%3E%3Cpolygon points='13,72 6.2,74.8 6.2,78.2 2.8,78.2 0,85 -2.8,78.2 -6.2,78.2 -6.2,74.8 -13,72 -6.2,69.2 -6.2,65.8 -2.8,65.8 0,59 2.8,65.8 6.2,65.8 6.2,69.2'/%3E%3Cpolygon points='85,72 78.2,74.8 78.2,78.2 74.8,78.2 72,85 69.2,78.2 65.8,78.2 65.8,74.8 59,72 65.8,69.2 65.8,65.8 69.2,65.8 72,59 74.8,65.8 78.2,65.8 78.2,69.2'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 72px 72px;
}

.zellige--fade {
  -webkit-mask-image: radial-gradient(ellipse 80% 62% at 50% 50%, #000 5%, transparent 72%);
  mask-image: radial-gradient(ellipse 80% 62% at 50% 50%, #000 5%, transparent 72%);
}

.zellige--top {
  -webkit-mask-image: linear-gradient(to bottom, #000, transparent 58%);
  mask-image: linear-gradient(to bottom, #000, transparent 58%);
}

/* Mashrabiya — fine lattice, denser than zellige */
.mashrabiya {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: .32;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cg fill='none' stroke='%23C8A55B' stroke-width='.6' opacity='.5'%3E%3Cpath d='M20 0 L40 20 L20 40 L0 20 Z'/%3E%3Cpath d='M0 0 L40 40 M40 0 L0 40'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 40px 40px;
}

/* Arabesque divider — gold hairline broken by a khatam node */
.divider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.1rem;
  width: 100%;
  color: var(--gold-on-bg);
}

.divider::before,
.divider::after {
  content: "";
  height: 1px;
  flex: 1 1 auto;
  max-width: 190px;
  background: linear-gradient(90deg, transparent, var(--line-gold), transparent);
}

.divider .khatam { width: 13px; height: 13px; flex: none; opacity: .85; }

/* Moorish keyhole arch — applied to imagery via SVG clip-path */
.arch {
  clip-path: url(#gec-arch);
  -webkit-clip-path: url(#gec-arch);
}

/* Arch-shaped frame with a gold hairline outline */
.arch-frame {
  position: relative;
  isolation: isolate;
}

/* The clip lives on the image, and the reveal on .arch-clip around it, so that
   anything deliberately overflowing the frame (a badge, a caption) is not
   clipped away with it. */
.arch-clip {
  width: 100%;
  height: 100%;
}

.arch-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  clip-path: url(#gec-arch);
  -webkit-clip-path: url(#gec-arch);
}

.arch-frame::after {
  content: "";
  position: absolute;
  inset: -10px;
  border: 1px solid var(--line-gold);
  border-radius: 50% 50% 0 0 / 34% 34% 0 0;
  pointer-events: none;
  z-index: 2;
}

/* --------------------------------------------------------- 6. COMPONENTS */

/* Buttons ------------------------------------------------------------- */
.btn {
  --btn-pad-y: 1.02rem;
  --btn-pad-x: 2.2rem;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .8em;
  padding: var(--btn-pad-y) var(--btn-pad-x);
  font-family: var(--font-body);
  font-size: .745rem;
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  overflow: hidden;
  transition: color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease);
}

.btn:active { transform: translateY(1px); }

.btn__ico { width: 1.05em; height: 1.05em; flex: none; transition: transform var(--t-fast) var(--ease); }
.btn:hover .btn__ico { transform: translateX(4px); }

/* Primary — solid gold */
.btn--gold {
  color: var(--on-gold);
  background: var(--gold-grad);
  background-size: 200% auto;
  border: 1px solid transparent;
  transition: background-position .9s var(--ease), transform var(--t-fast) var(--ease);
}

.btn--gold:hover { background-position: 100% center; }

/* Secondary — gold hairline outline that fills on hover */
.btn--outline {
  color: var(--text);
  border: 1px solid var(--line-gold);
  background: transparent;
}

.btn--outline::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gold);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform .5s var(--ease);
  z-index: -1;
}

.btn--outline:hover { color: var(--on-gold); border-color: var(--gold-on-bg); }
.btn--outline:hover::before { transform: scaleY(1); }

/* .btn--light removed: .btn--outline now derives its colours from the inherited
   theme tokens, so it works on light and dark sections alike. */

.btn--sm { --btn-pad-y: .78rem; --btn-pad-x: 1.5rem; font-size: .68rem; }

/* Text link with animated gold rule */
.link-u {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .6em;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold-on-bg);
  padding-bottom: .42rem;
}

.link-u::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--line-gold);
  transform-origin: right;
  transition: transform .55s var(--ease), background-color .55s var(--ease);
}

.link-u:hover::after { background: var(--gold); transform: scaleX(1.02); }
.link-u .btn__ico { transition: transform var(--t-fast) var(--ease); }
.link-u:hover .btn__ico { transform: translateX(5px); }

/* Cards ---------------------------------------------------------------- */
.card {
  position: relative;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  overflow: hidden;
  transition: border-color var(--t-med) var(--ease), transform var(--t-med) var(--ease);
}

.card:hover { border-color: var(--line-gold); }

/* Media with a slow zoom on hover */
.media {
  position: relative;
  overflow: hidden;
  background: var(--bg-sunk);
}

.media > img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.5s var(--ease), filter 1.5s var(--ease);
}

.media--dim > img { filter: brightness(.62); }

a:hover > .media > img,
.card:hover .media > img,
.media:hover > img { transform: scale(1.06); }

.media__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,.88) 0%, rgba(0,0,0,.42) 38%, rgba(0,0,0,.06) 72%);
  pointer-events: none;
}

/* Forms ---------------------------------------------------------------- */
.field { position: relative; display: flex; flex-direction: column; gap: .55rem; }

.field label {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.field .req { color: var(--gold-on-bg); }

.field input,
.field textarea,
.field select {
  width: 100%;
  padding: 1.02rem 1.15rem;
  background: rgba(234,230,219,.035);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: .96rem;
  font-weight: 300;
  transition: border-color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}

.field textarea { resize: vertical; min-height: 132px; line-height: 1.7; }

.field input::placeholder,
.field textarea::placeholder { color: rgba(204,191,173,.4); }

.field input:focus,
.field textarea:focus,
.field select:focus {
  outline: none;
  border-color: var(--gold-on-bg);
  background: rgba(234,230,219,.06);
}

.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23C8A55B' stroke-width='1.4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.15rem center;
  padding-right: 2.8rem;
  cursor: pointer;
}

.field select option { background: var(--bg-raise); color: var(--text); }

.field .err {
  font-size: .78rem;
  color: #E2857B;
  letter-spacing: .02em;
  text-transform: none;
  min-height: 1.1em;
}

.field.has-error input,
.field.has-error textarea,
.field.has-error select { border-color: #E2857B; }

/* Honeypot — visually hidden but reachable by bots */
.hp {
  position: absolute !important;
  left: -9999px;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}

.form-note {
  font-size: .8rem;
  color: var(--text-dim);
  line-height: 1.6;
}

/* Visually hidden, still announced */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px; left: var(--gutter);
  z-index: 200;
  padding: .9rem 1.5rem;
  background: var(--gold);
  color: var(--on-gold);
  font-size: .75rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  transition: top .3s var(--ease);
}

.skip-link:focus { top: 1rem; }

/* ------------------------------------------------------- 7. SCROLL REVEAL */
[data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 1s var(--ease), transform 1s var(--ease);
  transition-delay: var(--d, 0ms);
  will-change: opacity, transform;
}

[data-reveal].is-in { opacity: 1; transform: none; }

[data-reveal="fade"]  { transform: none; }
[data-reveal="left"]  { transform: translateX(-34px); }
[data-reveal="right"] { transform: translateX(34px); }
[data-reveal="scale"] { transform: scale(.955); }

/* On narrow screens the horizontal reveals become vertical. A 34px sideways
   offset on a 375px viewport puts the element past the edge until it animates
   in — body overflow-x:hidden conceals the scrollbar but the document can still
   be panned on some mobile browsers. Sideways motion also reads poorly in a
   single column. */
@media (max-width: 900px) {
  [data-reveal="left"],
  [data-reveal="right"] { transform: translateY(26px); }
}

/* Masked line rise for headlines.
   The mask has to clear the descenders or it shaves the tail off letters like
   the "g" in "Design". Cormorant Garamond's ink reaches 1.076em below the line
   box top, while .t-hero sets line-height to 0.96em — so the mask needs at least
   0.116em of extra depth. The old 0.12em left 0.4px of clearance at 1440px,
   which sub-pixel rounding and the fallback font's metrics both ate into.
   0.22em gives real headroom; the negative margin keeps the layout unchanged. */
.rise {
  display: block;
  overflow: hidden;
  padding-bottom: .22em;
  margin-bottom: -.22em;
}

.rise > span {
  display: block;
  /* Must exceed mask height / line height, or the tops of the glyphs peek into
     the padding before the reveal runs. Mask is 1.18em over a 0.96em line, so
     anything under ~123% leaves a sliver showing. */
  transform: translateY(135%);
  transition: transform 1.15s var(--ease);
  transition-delay: var(--d, 0ms);
}

.is-in .rise > span,
.rise.is-in > span { transform: none; }

/* Image clip reveal */
[data-reveal="clip"] {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1.35s var(--ease);
  transition-delay: var(--d, 0ms);
}

[data-reveal="clip"].is-in { clip-path: inset(0 0 0 0); }

/* ------------------------------------------- 7b. PHOTO-BACKED SURFACES */

/* Small cards where the photograph IS the background — a service tile, a
   destination card, a gallery caption. There is no scrim of ours to lighten, so
   these keep cream type in both themes; a photo card reads correctly on a pale
   page the same way a photograph does in a printed magazine. */
.tile__body,
.dest__body,
.shot__cap,
.post__cat {
  --text:       #EAE6DB;
  --text-muted: rgba(234, 230, 219, .84);
  --text-dim:   rgba(234, 230, 219, .64);
  --gold-on-bg: #C8A55B;
  --line:       rgba(234, 230, 219, .2);
  --gold-grad:  var(--gold-grad-bright);
  color: var(--text);
}

/* The hero is different: its scrim is ours, so it follows the theme. In dark it
   is a deep wash carrying cream type; in light it becomes a pale wash carrying
   dark type, and the photograph sits behind the words rather than under them.
   Without this the first screen looks identical in both themes. */
:root:not([data-theme="light"]) .hero,
:root:not([data-theme="light"]) .phero,
:root:not([data-theme="light"]) body.has-hero .header:not(.is-stuck) {
  --text:       #EAE6DB;
  --text-muted: rgba(234, 230, 219, .84);
  --text-dim:   rgba(234, 230, 219, .64);
  --gold-on-bg: #C8A55B;
  --line:       rgba(234, 230, 219, .2);
  --gold-grad:  var(--gold-grad-bright);
  color: var(--text);
}

/* Light theme: the hero and the header above it inherit the page tokens, so the
   headline, the sub-text, the menu and the lockup all go dark. */
:root[data-theme="light"] .hero,
:root[data-theme="light"] .phero {
  color: var(--text);
}

/* The inverted band runs opposite the page, so its gold gradient does too. */
.section--invert { --gold-grad: var(--gold-grad-deep); }
:root[data-theme="light"] .section--invert { --gold-grad: var(--gold-grad-bright); }
.section--warm { --gold-grad: var(--gold-grad-deep); }

/* ------------------------------------------------ 7c. THEME TOGGLE */
.theme-btn {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 38px; height: 38px;
  flex: none;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--text-muted);
  transition: color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease);
}

/* Same reasoning as .nav__link — the header swaps these tokens, so colour is
   applied instantly and only the rotation animates. */
.theme-btn {
  transition: border-color var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease);
}

.theme-btn:hover {
  color: var(--gold-on-bg);
  border-color: var(--line-gold);
  transform: rotate(-18deg);
}

.theme-btn svg { width: 16px; height: 16px; }

/* Only one glyph shows at a time: moon while dark, sun while light. */
.theme-btn .ico-sun  { display: none; }
:root[data-theme="light"] .theme-btn .ico-sun  { display: block; }
:root[data-theme="light"] .theme-btn .ico-moon { display: none; }

/* ------------------------------------------------- 8. REDUCED MOTION */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

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

  [data-reveal] { opacity: 1 !important; transform: none !important; clip-path: none !important; }
  .rise > span { transform: none !important; }
  .gold-text { animation: none; }
}
