/* ==========================================================================
   11:11 — Elevenn Elevenn Archive Pvt Ltd
   Stylesheet — HTML5 / CSS3 only, no frameworks, no build step.

   CONTENTS
   01. Design tokens (colors, type, spacing)
   02. Reset & base
   03. Typography primitives
   04. Buttons & links
   05. Layout helpers
   06. Header & navigation
   07. Mobile navigation
   08. Hero
   09. About
   10. Services
   10b. Event types
   10c. Tiers & boundaries
   11. Process
   12. Portfolio (now the atmosphere / visual-direction grid)
   13. Testimonials (section removed from the page; styles kept)
   14. Call to action
   15. Contact & form
   16. Footer
   16b. WhatsApp contact
   17. Scroll reveal animations
   18. Reduced motion & print
   ========================================================================== */


/* ==========================================================================
   01. DESIGN TOKENS
   Change the palette, type and spacing scale here — everything else follows.
   ========================================================================== */
:root {
  /* --- Color -------------------------------------------------------------
     The three brand values below are the client's own, confirmed in the
     website brief (Q29) — not sampled, not invented:
       Midnight Navy   #0A1128   primary
       Champagne Gold  #D4AF37   accent   (Metallic Gold #C5A059 secondary)
       Warm Cream      #FDFBF7   background
     Everything else in this block is derived from those three, so the whole
     page can be re-tinted from here alone. Every ratio quoted below was
     measured with the WCAG formula — if you change a value, re-measure it and
     update the table in README.md rather than estimating. */
  --paper:      #FDFBF7;   /* page ground — warm cream (client) */
  --paper-alt:  #F2ECE0;   /* derived: alternating section band */
  --gold:       #D4AF37;   /* accent: rules, bullets, numerals (client) */
  --gold-metal: #C5A059;   /* secondary metallic gold (client) */
  --gold-deep:  #7F6220;   /* derived: the one gold dark enough for text on light */
  --gold-bright:#E8C86A;   /* derived: gold lifted toward paper, for the word
                              LEGEND over the two photographs — the champagne
                              gold itself measures about 2.5:1 there, under the
                              3:1 large-text floor. See README's contrast table. */
  --navy:       #0A1128;   /* headings, buttons, dark bands (client) */
  --white:      #FFFFFF;

  /* Derived tones */
  --navy-deep: #05080F;    /* the footer, one step deeper than the bands */
  --slate:     #586074;

  /* Channel triplets, so that no rgba() further down this file has to restate
     a brand colour by hand. Changing --navy above means changing --navy-rgb
     here too — they are the same colour written two ways. */
  --navy-rgb:  10 17 40;
  --paper-rgb: 253 251 247;
  --gold-rgb:  212 175 55;

  --hairline:       rgb(var(--navy-rgb) / 0.14);
  --hairline-soft:  rgb(var(--navy-rgb) / 0.08);
  --hairline-light: rgb(var(--paper-rgb) / 0.22);

  /* Semantic roles.
     Three deliberate steps of text contrast, all of which clear WCAG AA
     (4.5:1) on BOTH the paper and the alt background — measured, not guessed:
       --heading  18.1:1 on paper / 15.9:1 on alt
       --text      8.5:1 on paper /  7.5:1 on alt
       --muted     6.1:1 on paper /  5.3:1 on alt
     --accent is decorative only on light grounds (rules, bullets, numerals).
     Never put text in --accent there: the champagne gold measures 2.0:1 on
     paper and 1.8:1 on the alt band. Use --gold-deep (5.5:1 on paper, 4.9:1
     on alt) whenever a gold has to carry words on a light background.
     On the dark bands the plain --accent is not just safe but strong: it
     measures 8.9:1 on --navy and 9.5:1 on --navy-deep, which is why the
     process band's eyebrow and numerals are set in it. */
  --bg:            var(--paper);
  --bg-alt:        var(--paper-alt);
  --surface:       var(--white);
  --text:          #414B5C;
  --heading:       var(--navy);
  --muted:         var(--slate);
  --accent:        var(--gold);
  --error:         #9A3B2E;
  --placeholder:   #656E82;

  /* WhatsApp brand green — used only for the floating contact button. */
  --whatsapp:      #25D366;
  --whatsapp-dark: #128C7E;

  /* --- Typography ------------------------------------------------------- */
  --font-display: "Cormorant Garamond", "Times New Roman", Times, serif;
  --font-body:    "Montserrat", "Segoe UI", system-ui, -apple-system, sans-serif;

  --fs-eyebrow:   clamp(0.625rem, 0.58rem + 0.2vw, 0.7rem);
  --fs-small:     clamp(0.8125rem, 0.78rem + 0.16vw, 0.875rem);
  --fs-body:      clamp(0.9375rem, 0.9rem + 0.22vw, 1.0625rem);
  --fs-lede:      clamp(1.0625rem, 1rem + 0.42vw, 1.3125rem);
  --fs-h3:        clamp(1.375rem, 1.2rem + 0.8vw, 1.875rem);
  --fs-h2:        clamp(2rem, 1.35rem + 2.9vw, 3.75rem);
  --fs-h1:        clamp(2.75rem, 1.7rem + 4.6vw, 5.75rem);
  --fs-xl:        clamp(2.375rem, 1.5rem + 3.9vw, 4.75rem);

  --tracking-wide:  0.22em;
  --tracking-mid:   0.14em;
  --leading-tight:  1.06;
  --leading-body:   1.85;

  /* --- Spacing & layout -------------------------------------------------- */
  --container:      1320px;
  --container-pad:  clamp(1.25rem, 5vw, 4.5rem);
  --section-y:      clamp(4.5rem, 11vw, 9.5rem);
  --gap-sm:         clamp(0.75rem, 2vw, 1.25rem);
  --gap:            clamp(1.5rem, 3.5vw, 2.75rem);
  --gap-lg:         clamp(2.5rem, 6vw, 5.5rem);

  --header-h:       88px;

  /* --- Elevation -----------------------------------------------------------
     Two shadows, both cast in navy rather than black: a grey shadow on a warm
     cream page reads as dirt, a navy one reads as depth. Soft is the resting
     state for anything that sits above the page (cards, framed photographs);
     lift is the same shadow opened up on hover, so the movement is the shadow
     growing rather than a second effect appearing. */
  --shadow-soft: 0 1px 2px rgb(var(--navy-rgb) / 0.04),
                 0 10px 28px rgb(var(--navy-rgb) / 0.07);
  --shadow-lift: 0 2px 6px rgb(var(--navy-rgb) / 0.07),
                 0 22px 52px rgb(var(--navy-rgb) / 0.14);

  /* --- Motion ------------------------------------------------------------ */
  --ease:        cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-soft:   cubic-bezier(0.4, 0, 0.2, 1);
  --dur:         0.5s;
  --dur-slow:    0.9s;
}


/* ==========================================================================
   02. RESET & BASE
   ========================================================================== */
*,
*::before,
*::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 300;
  line-height: var(--leading-body);
  letter-spacing: 0.012em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden; /* safety net against accidental horizontal scroll */
}

/* Lock scrolling while the mobile menu is open */
body.is-locked { overflow: hidden; }

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

h1, h2, h3, h4 { margin: 0; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

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

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

/* Sections need breathing room under the sticky header when linked to */
section[id] { scroll-margin-top: calc(var(--header-h) + 8px); }

/* --- Focus visibility (never remove without a replacement) --------------- */
:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 3px;
  border-radius: 1px;
}
.process :focus-visible,
.hero :focus-visible,
.cta :focus-visible,
.site-footer :focus-visible {
  outline-color: var(--paper);
}

.skip-link {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -120%);
  z-index: 200;
  padding: 0.85rem 1.5rem;
  background: var(--navy);
  color: var(--paper);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus { transform: translate(-50%, 0); }

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


/* ==========================================================================
   03. TYPOGRAPHY PRIMITIVES
   ========================================================================== */
.display {
  font-family: var(--font-display);
  font-weight: 300;
  color: var(--heading);
  line-height: var(--leading-tight);
  letter-spacing: -0.012em;
  text-wrap: balance;
}
.display--lg { font-size: var(--fs-h2); }
.display--xl { font-size: var(--fs-xl); }
.display em {
  font-style: italic;
  font-weight: 300;
}

/* The brand line is set WHERE moments BECOME LEGEND: capitals throughout, with
   the italic "moments" and the gold "legend" breaking them. Both exceptions are
   defined here because the line appears twice — the hero h1 and the closing
   heading — and the two must not drift apart.

   The capitals are a CSS transform on the headings themselves (see .hero__title
   and .cta__title), and those two rules also drop their <em> back to lowercase.
   This one only colours the last word. */
.word-gold { color: var(--gold-bright); }

.eyebrow {
  margin: 0 0 clamp(1rem, 2vw, 1.5rem);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--muted);
}
.eyebrow--light { color: rgb(var(--paper-rgb) / 0.78); }
/* On the one band with a known solid dark background, the eyebrow can take the
   brand gold outright — 4.95:1 on --navy. Over the hero and CTA photographs it
   stays light, because the colour behind it there is whatever the photograph
   happens to be. */
.process .eyebrow--light { color: var(--accent); }

.lede {
  font-size: var(--fs-lede);
  font-weight: 300;
  line-height: 1.7;
  color: var(--text);
}

.disclaimer {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  max-width: 62ch;
  font-size: var(--fs-small);
  color: var(--muted);
  font-style: italic;
  line-height: 1.7;
}


/* ==========================================================================
   04. BUTTONS & LINKS
   ========================================================================== */
.btn {
  --btn-bg: transparent;
  --btn-fg: var(--navy);
  --btn-bd: var(--navy);

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  min-height: 52px;
  padding: 0.95rem 2.1rem;
  border: 1px solid var(--btn-bd);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-body);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
/* The fill sweeps up from the bottom on hover — quiet, not flashy */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--btn-fill, var(--navy));
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform var(--dur) var(--ease);
}
.btn:hover::before,
.btn:focus-visible::before { transform: scaleY(1); }

.btn--solid {
  --btn-bg: var(--navy);
  --btn-fg: var(--paper);
  --btn-bd: var(--navy);
  --btn-fill: var(--slate);
}
.btn--solid:hover,
.btn--solid:focus-visible { color: var(--paper); border-color: var(--slate); }

.btn--outline { --btn-fill: var(--navy); }
.btn--outline:hover,
.btn--outline:focus-visible { color: var(--paper); }

.btn--light {
  --btn-fg: var(--paper);
  --btn-bd: rgb(var(--paper-rgb) / 0.65);
  --btn-fill: var(--paper);
}
.btn--light:hover,
.btn--light:focus-visible { color: var(--navy); border-color: var(--paper); }

/* The one loud button on the site: solid champagne gold under navy type. It
   marks the start-a-brief action wherever it appears — hero, mobile menu,
   closing band, and the form's own submit — and nothing else. Enquire in the
   header stays an outline, because a page where every button is gold has no
   primary action at all.

   Safe by measurement, not by eye: navy on the gradient's darkest stop
   (--gold-metal) is 7.6:1, on the brand gold 8.9:1 and on --gold-bright
   11.5:1, so every pixel of the fill clears AA for body-sized type. The inset
   highlight along the top edge is what makes it read as metal rather than
   mustard; the shadow beneath it is navy, like every other shadow here. */
.btn--gold {
  --btn-fg: var(--navy);
  --btn-bd: transparent;
  background-image: linear-gradient(135deg,
    var(--gold-bright) 0%, var(--gold) 48%, var(--gold-metal) 100%);
  box-shadow:
    inset 0 1px 0 rgb(var(--paper-rgb) / 0.5),
    var(--shadow-soft);
  font-weight: 600;
}
/* The sweep-up fill the base .btn provides, in a brighter gold — the button
   polishes rather than changes colour. */
.btn--gold::before {
  background-image: linear-gradient(135deg,
    var(--gold) 0%, var(--gold-bright) 52%, var(--gold) 100%);
}
.btn--gold:hover,
.btn--gold:focus-visible {
  color: var(--navy);
  box-shadow:
    inset 0 1px 0 rgb(var(--paper-rgb) / 0.6),
    var(--shadow-lift);
}

.btn--sm { min-height: 42px; padding: 0.7rem 1.4rem; }
.btn--block { width: 100%; }

@media (max-width: 559px) {
  .btn--block-sm { width: 100%; }
}

/* Text link with a nudging arrow */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--navy);
  padding-bottom: 0.4rem;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  transition: background-size var(--dur) var(--ease), color var(--dur) var(--ease);
}
.link-arrow__icon {
  display: inline-block;
  transition: transform var(--dur) var(--ease);
}
.link-arrow:hover .link-arrow__icon,
.link-arrow:focus-visible .link-arrow__icon { transform: translateX(6px); }
.link-arrow:hover { background-size: 0% 1px; }
.link-arrow--light { color: var(--paper); }


/* ==========================================================================
   05. LAYOUT HELPERS
   ========================================================================== */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

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

.section-head {
  max-width: 46rem;
  margin-bottom: clamp(2.75rem, 6vw, 5rem);
}
.section-head__lede {
  margin-top: clamp(1rem, 2vw, 1.5rem);
  max-width: 48ch;
  font-size: var(--fs-body);
  color: var(--muted);
  line-height: 1.8;
}
.section-head--light .display { color: var(--paper); }
.section-head--light .section-head__lede { color: rgb(var(--paper-rgb) / 0.7); }


/* ==========================================================================
   06. HEADER & NAVIGATION
   ========================================================================== */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-sm);
  min-height: var(--header-h);
  padding-block: 1rem;
}

/* Over the hero the header is transparent with light type;
   .is-scrolled is toggled by js/script.js */
.site-header .logo,
.site-header .nav-link,
.site-header .btn { color: var(--paper); }
.site-header .btn--outline { --btn-bd: rgb(var(--paper-rgb) / 0.6); --btn-fill: var(--paper); }
.site-header .btn--outline:hover,
.site-header .btn--outline:focus-visible { color: var(--navy); border-color: var(--paper); }
.site-header .logo__sub { color: rgb(var(--paper-rgb) / 0.7); }

/* Reading progress, drawn along the header's own bottom edge. It only appears
   once the header has taken its cream background — over the hero there is no
   edge for it to sit on, and a gold line across a photograph would read as a
   loading bar. --scroll-progress is published by js/script.js on the same
   scroll pass that toggles .is-scrolled, so this costs no extra listener. */
.site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  transform: scaleX(var(--scroll-progress, 0));
  transform-origin: left center;
  background: linear-gradient(90deg,
    var(--gold-metal), var(--gold) 55%, var(--gold-bright));
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
  pointer-events: none;
}
.site-header.is-scrolled::after { opacity: 1; }

.site-header.is-scrolled {
  background: rgb(var(--paper-rgb) / 0.94);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom-color: var(--hairline-soft);
}
.site-header.is-scrolled .logo,
.site-header.is-scrolled .nav-link,
.site-header.is-scrolled .btn { color: var(--navy); }
.site-header.is-scrolled .logo__sub { color: var(--muted); }
.site-header.is-scrolled .btn--outline { --btn-bd: var(--navy); --btn-fill: var(--navy); }
.site-header.is-scrolled .btn--outline:hover,
.site-header.is-scrolled .btn--outline:focus-visible { color: var(--paper); }
.site-header.is-scrolled .nav-toggle__bars span { background: var(--navy); }

/* --- Wordmark -----------------------------------------------------------
   "11:11" is a numeric mark, so it needs different treatment from a lettered
   one: lining figures (Cormorant defaults to old-style, which would drop the
   1s to x-height), tighter tracking, and a lightened colon. */
/* Badge + wordmark sit side by side; the wordmark stacks internally. */
.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  line-height: 1;
}
.logo__text {
  display: inline-flex;
  flex-direction: column;
  gap: 0.3rem;
}
.logo__mark {
  font-family: var(--font-display);
  font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
  font-weight: 500;
  letter-spacing: 0.12em;
  white-space: nowrap;
  font-variant-numeric: lining-nums;
  font-feature-settings: "lnum" 1;
}
/* The colon carries the brand's pause — set it back so the numerals lead */
.logo__colon {
  opacity: 0.55;
  padding-inline: 0.02em;
}
/* The badge sub-text, "Bespoke Occasions & Curation". At 28 characters it is
   far longer than the tagline it replaced, so the tracking is eased off and it
   is withheld until there is genuinely room for it beside the nav — on a phone
   it would push the wordmark into the hamburger. */
.logo__sub {
  display: none;
  font-size: 0.5625rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--muted);
}
@media (min-width: 1140px) { .logo__sub { display: block; } }
.logo__mark--sm { font-size: 1.375rem; }
.logo__mark--footer { font-size: clamp(1.625rem, 1.3rem + 1.1vw, 2.125rem); color: var(--paper); }

/* --- Brand badge (images/logo.png) ---------------------------------------
   The client's crowned 11:11 monogram, gold on near-black. The file is already
   a circle with transparent corners, so the radius here is belt and braces —
   it keeps the crop circular if the file is ever replaced with a square one.

   Because the mark carries its own dark ground it needs no light/dark pair: it
   holds up over the hero photograph and on the ivory scrolled header alike.
   The ring and the halo are what make it read as a struck medallion rather
   than a photo cut out with scissors — the gold hairline picks the edge out
   against the hero's dark upper third, and the navy halo does the same job on
   cream, where a black disc otherwise sits flat on the paper.

   `object-fit: cover` with a square box guards against a non-square
   replacement file distorting into an oval. */
.logo__badge {
  display: block;
  flex: none;
  /* 52px is the ceiling, not a preference: the header is 88px tall with 1rem of
     padding above and below, which leaves exactly 56px of usable height. A badge
     any larger than 52px would set the header's height itself and the gap either
     side of it would vanish. */
  width: clamp(42px, 3.6vw, 52px);
  height: clamp(42px, 3.6vw, 52px);
  object-fit: cover;
  border-radius: 50%;
  box-shadow:
    0 0 0 1px rgb(var(--gold-rgb) / 0.45),
    0 2px 10px rgb(var(--navy-rgb) / 0.28);
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
/* Hover belongs to the whole lockup, not the image: the badge and the wordmark
   are one link, so lighting up only half of it on hover looks like a bug. */
.logo:hover .logo__badge {
  transform: scale(1.04);
  box-shadow:
    0 0 0 1px rgb(var(--gold-rgb) / 0.85),
    0 4px 16px rgb(var(--navy-rgb) / 0.34);
}
.logo__badge--sm { width: 38px; height: 38px; }
/* The footer badge stands alone above the wordmark rather than beside it, so
   nothing caps it the way the header height caps the one above — it is sized to
   stay clearly the largest instance of the mark on the page. */
.logo__badge--footer {
  width: clamp(64px, 6vw, 80px);
  height: clamp(64px, 6vw, 80px);
  margin-bottom: 1.1rem;
  /* On the navy footer the halo has nothing to sit against, so the ring does
     the work alone and is set a little stronger. */
  box-shadow: 0 0 0 1px rgb(var(--gold-rgb) / 0.55);
}

/* Inline lockup used in the mobile-menu header, where the badge sits beside
   the wordmark on one line rather than above a tagline. */
.logo--inline {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}

/* --- Desktop nav --------------------------------------------------------- */
.nav-desktop { display: none; }
.nav-desktop__list {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 2.6vw, 2.5rem);
}
.nav-link {
  position: relative;
  display: inline-block;
  padding-block: 0.35rem;
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  transition: opacity var(--dur) var(--ease);
}
.nav-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur) var(--ease);
}
.nav-link:hover::after,
.nav-link:focus-visible::after,
.nav-link.is-active::after { transform: scaleX(1); transform-origin: left; }

.site-header__actions {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.5rem);
}
.site-header__cta { display: none; }

/* --- Hamburger ----------------------------------------------------------- */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin-right: -12px;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
}
.nav-toggle__bars {
  display: block;
  position: relative;
  width: 26px;
  height: 10px;
}
.nav-toggle__bars span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--paper);
  transition: background-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.nav-toggle__bars span:first-child { top: 0; }
.nav-toggle__bars span:last-child  { bottom: 0; width: 70%; }
.nav-toggle:hover .nav-toggle__bars span:last-child { width: 100%; }

@media (min-width: 960px) {
  .nav-desktop { display: block; }
  .site-header__cta { display: inline-flex; }
  .nav-toggle { display: none; }
}


/* ==========================================================================
   07. MOBILE NAVIGATION
   ========================================================================== */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 150;
}
.mobile-nav[hidden] { display: none; }

.mobile-nav__backdrop {
  position: absolute;
  inset: 0;
  background: rgb(var(--navy-rgb) / 0.45);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.mobile-nav__panel {
  position: absolute;
  inset: 0 0 0 auto;
  width: min(30rem, 100%);
  display: flex;
  flex-direction: column;
  padding: 1.75rem var(--container-pad) 2.5rem;
  background: var(--paper);
  transform: translateX(100%);
  transition: transform var(--dur-slow) var(--ease);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.mobile-nav.is-open .mobile-nav__backdrop { opacity: 1; }
.mobile-nav.is-open .mobile-nav__panel { transform: translateX(0); }

.mobile-nav__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: calc(var(--header-h) - 2rem);
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--hairline-soft);
  color: var(--navy);
}
.mobile-nav__close {
  width: 48px;
  height: 48px;
  margin-right: -12px;
  background: none;
  border: 0;
  font-size: 1.9rem;
  line-height: 1;
  color: var(--navy);
  cursor: pointer;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.mobile-nav__close:hover { transform: rotate(90deg); }

.mobile-nav__list {
  display: flex;
  flex-direction: column;
  padding-block: clamp(1.5rem, 5vw, 3rem);
}
.mobile-nav__list li {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
}
.mobile-nav.is-open .mobile-nav__list li { opacity: 1; transform: none; }
.mobile-nav.is-open .mobile-nav__list li:nth-child(1) { transition-delay: 0.10s; }
.mobile-nav.is-open .mobile-nav__list li:nth-child(2) { transition-delay: 0.16s; }
.mobile-nav.is-open .mobile-nav__list li:nth-child(3) { transition-delay: 0.22s; }
.mobile-nav.is-open .mobile-nav__list li:nth-child(4) { transition-delay: 0.28s; }
.mobile-nav.is-open .mobile-nav__list li:nth-child(5) { transition-delay: 0.34s; }

.mobile-nav__list a {
  display: block;
  padding-block: 0.7rem;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 6vw, 2.5rem);
  font-weight: 300;
  color: var(--navy);
  border-bottom: 1px solid var(--hairline-soft);
  transition: color var(--dur) var(--ease), padding-left var(--dur) var(--ease);
}
.mobile-nav__list a:hover { color: var(--slate); padding-left: 0.5rem; }

.mobile-nav__foot { margin-top: auto; }
.mobile-nav__meta {
  margin-top: 1.25rem;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
}


/* ==========================================================================
   08. HERO
   ========================================================================== */
.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 100vh;
  min-height: 100svh; /* avoids the mobile browser-chrome jump */
  padding-block: calc(var(--header-h) + 3rem) clamp(6rem, 14vh, 9rem);
  overflow: hidden;
  isolation: isolate;
}
.hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
  animation: hero-settle 2.6s var(--ease) both;
}
@keyframes hero-settle {
  from { transform: scale(1.07); }
  to   { transform: scale(1); }
}
/* Layered overlay: darker at the base so the text always clears contrast */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Tuned against the current hero image — the client's own crest artwork,
     gold on midnight navy. It replaced a chamber-concert photograph on
     22 Aug 2026, and the alphas went up two points with it: the pale wing
     feathers behind the headline are brighter than that photograph's stone,
     and the gold word LEGEND sits directly on them. At the photograph's
     values the gold measured 3.23:1 — over the 3:1 floor for large text, but
     with nothing to spare on a word that is itself gold on gold.

     Measured worst-pixel behind each text element, on the composite render:
     eyebrow 10.3:1, headline 6.4:1, the gold LEGEND 4.1:1, lede 5.9:1,
     second lede 6.5:1, button 11.4:1, link 8.8:1 — every one clear of 4.5:1
     except the two display words, which only have to clear 3:1.

     ⚠ These figures belong to THIS image. Swap it and re-measure all seven
     before shipping: hide .hero__inner, screenshot the bare background, and
     take the worst pixel inside each text element's bounding box. Translucent
     text (the eyebrow at 0.78, the ledes at 0.92) has to be composited against
     each pixel first, or the number comes out flattering and wrong. */
  background:
    linear-gradient(to bottom,
      rgb(var(--navy-rgb) / 0.62) 0%,
      rgb(var(--navy-rgb) / 0.60) 38%,
      rgb(var(--navy-rgb) / 0.74) 100%),
    linear-gradient(to right, rgb(var(--navy-rgb) / 0.32), rgb(var(--navy-rgb) / 0.12));
}

/* The scroll cue is absolutely positioned about 100px up from the hero's bottom
   edge (a 24–44px offset, a 56px rule and its label). Once the client's
   two-paragraph statement went in, the copy block outgrows 100vh on a 768px-tall
   laptop, and at the 14vh floor above the buttons finished 5px inside the cue —
   measured, not guessed. So wherever the cue is actually drawn (it is hidden
   below 560px) the hero reserves the cue's own height beneath the copy. */
@media (min-width: 560px) {
  .hero { padding-bottom: clamp(8.5rem, 16vh, 10rem); }
}

.hero__inner {
  position: relative;
  max-width: 60rem;
  text-align: center;
  margin-inline: auto;
}
.hero__eyebrow { margin-bottom: clamp(1.25rem, 3vw, 2rem); }
.hero__title {
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  font-weight: 300;
  line-height: 1.04;
  /* Capitals need the opposite tracking from lowercase: the -0.015em that
     tightens "Where moments" jams the flat sides of W-H-E-R-E together, so the
     capitalised line gets a little air instead. */
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--paper);
  text-wrap: balance;
}
/* "moments" is the one word that stays lowercase, and the italic is what makes
   the break look deliberate rather than like a missed shift key. */
.hero__title em {
  font-style: italic;
  text-transform: lowercase;
}

.hero__lede {
  margin: clamp(1.5rem, 3.5vw, 2.25rem) auto 0;
  max-width: 46ch;
  font-size: var(--fs-lede);
  font-weight: 300;
  line-height: 1.75;
  color: rgb(var(--paper-rgb) / 0.92);
}
/* Second half of the client's hero statement. Same voice, quieter setting: one
   step down in size and a shorter gap above, so the pair reads as one block
   rather than two ledes competing, and the hero still fits 100svh on a 375px
   phone. Colour is deliberately left inherited at 0.92 alpha — this text is
   smaller than the lede above it over the same photograph, so it needs at
   least as much contrast, not less. */
.hero__lede--sub {
  margin-top: clamp(0.85rem, 2vw, 1.15rem);
  max-width: 54ch;
  font-size: var(--fs-body);
  line-height: 1.7;
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(1.25rem, 3vw, 2.25rem);
  margin-top: clamp(2.25rem, 5vw, 3.25rem);
}

/* Reveal the hero content once, on load */
.hero__eyebrow,
.hero__title,
.hero__lede,
.hero__actions {
  animation: rise-in 1.1s var(--ease) both;
}
.hero__title    { animation-delay: 0.12s; }
.hero__lede     { animation-delay: 0.24s; }
.hero__actions  { animation-delay: 0.36s; }
@keyframes rise-in {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}

/* --- Scroll cue ---------------------------------------------------------- */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(1.5rem, 4vh, 2.75rem);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
  color: rgb(var(--paper-rgb) / 0.8);
  animation: rise-in 1.1s var(--ease) 0.6s both;
}
.scroll-cue__label {
  font-size: 0.5625rem;
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}
.scroll-cue__line {
  position: relative;
  width: 1px;
  height: 56px;
  background: rgb(var(--paper-rgb) / 0.3);
  overflow: hidden;
}
.scroll-cue__line::after {
  content: "";
  position: absolute;
  inset: 0 auto auto 0;
  width: 1px;
  height: 40%;
  background: var(--paper);
  animation: cue-slide 2.4s var(--ease-soft) infinite;
}
@keyframes cue-slide {
  0%   { transform: translateY(-100%); }
  60%  { transform: translateY(250%); }
  100% { transform: translateY(250%); }
}
.scroll-cue:hover { color: var(--paper); }

@media (max-width: 559px) {
  .scroll-cue { display: none; } /* the hero already fills a small screen */
}


/* ==========================================================================
   09. ABOUT
   ========================================================================== */
.about { background: var(--bg); }
.about__grid {
  display: grid;
  gap: var(--gap-lg);
  align-items: center;
}
.about__content { max-width: 44rem; }
.about__content .display { margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem); }
.about__body {
  margin-top: 1.25rem;
  max-width: 52ch;
  color: var(--muted);
}
.about__content .link-arrow { margin-top: clamp(1.75rem, 4vw, 2.5rem); }

.about__media {
  position: relative;
  margin: 0;
}
.about__img {
  width: 100%;
  object-fit: cover;
  filter: saturate(0.94);
}
.about__img--main { aspect-ratio: 3 / 4; }
.about__img--inset { display: none; }

@media (min-width: 720px) {
  .about__img--inset {
    display: block;
    position: absolute;
    right: -1.5rem;
    bottom: -2.5rem;
    width: 46%;
    aspect-ratio: 4 / 3;
    border: 10px solid var(--paper);
  }
}
@media (min-width: 1024px) {
  .about__grid {
    grid-template-columns: 1fr 0.92fr;
    gap: clamp(3rem, 7vw, 7rem);
  }
  .about__media { padding-bottom: 2.5rem; }
  .about__img--inset {
    right: auto;
    left: -3.5rem;
    bottom: 0;
    width: 52%;
  }
}


/* ==========================================================================
   10. SERVICES
   ========================================================================== */
.services { background: var(--bg-alt); }

/* These were hairline-divided columns — one grid, 1px gaps, the hairline colour
   showing through as the dividers. They are cards now, with real gutters,
   because a card needs somewhere to cast its shadow: at a 1px gap each card's
   shadow fell on its neighbour and the row read as a smudge rather than three
   liftable things. The quieter hairline treatment survives one section down, on
   the experiences and tiers grids, which is what keeps the two apart. */
.services__grid {
  display: grid;
  gap: clamp(1.25rem, 2.2vw, 2rem);
}
@media (min-width: 760px) {
  .services__grid { grid-template-columns: repeat(3, 1fr); }
}

/* Given a card's own material — a hairline, a top-to-bottom lightening and a
   navy shadow — rather than being a tinted rectangle. On a page this flat the
   three service cards are the first thing that should feel liftable, and the
   hover then only has to open the shadow and raise the card 4px. */
.service {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(2rem, 4vw, 3.25rem) clamp(1.5rem, 3vw, 2.75rem) clamp(2.5rem, 5vw, 3.75rem);
  border: 1px solid var(--hairline-soft);
  background-color: var(--bg-alt);
  background-image: linear-gradient(180deg,
    rgb(var(--paper-rgb) / 0.9) 0%, rgb(var(--paper-rgb) / 0) 62%);
  box-shadow: var(--shadow-soft);
  transition: background-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.service:hover,
.service:focus-within {
  background-color: var(--paper);
  border-color: rgb(var(--gold-rgb) / 0.35);
  box-shadow: var(--shadow-lift);
  transform: translateY(-4px);
}

.service__index {
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--muted); /* not --accent: the gold measures 2.5:1 on this band */
}
.service__title {
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 400;
  line-height: 1.18;
  color: var(--heading);
}
.service__text {
  margin-top: 1rem;
  color: var(--text);
  max-width: 34ch;
}
.service__list {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  padding-top: clamp(1.25rem, 2.5vw, 1.5rem);
  border-top: 1px solid var(--hairline-soft);
  display: grid;
  gap: 0.6rem;
  font-size: var(--fs-small);
  color: var(--muted);
  line-height: 1.6;
}
.service__list li {
  position: relative;
  padding-left: 1.4rem;
}
.service__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.6rem;
  height: 1px;
  background: var(--accent);
}

/* A rule that draws itself across the base of the column on hover */
.service__rule {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: var(--navy);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-slow) var(--ease);
}
.service:hover .service__rule,
.service:focus-within .service__rule { transform: scaleX(1); }


/* ==========================================================================
   10b. EVENT TYPES
   A plain three-across grid of what the company runs. Deliberately quieter
   than the Services cards above it: those are the offer, this is the range,
   and two competing card treatments in a row would fight each other.
   ========================================================================== */
/* --bg, not --bg-alt: Services directly above already uses the alt band, and
   two alt bands in a row would read as one very long section. */
.event-types { background: var(--bg); }

.event-grid {
  display: grid;
  gap: clamp(1.75rem, 3.5vw, 2.75rem);
}
@media (min-width: 620px)  { .event-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .event-grid { grid-template-columns: repeat(3, 1fr); } }

/* The rule above each name is the hairline plus a short gold segment laid over
   its left end, which runs out to the full width on hover. Decorative only —
   the champagne gold measures 2.0:1 here and may never carry a word. */
.event-type {
  position: relative;
  padding-top: clamp(1.1rem, 2vw, 1.5rem);
  border-top: 1px solid var(--hairline);
}
.event-type::before {
  content: "";
  position: absolute;
  inset: -1px auto auto 0;
  width: 2.5rem;
  height: 1px;
  background: linear-gradient(90deg, var(--gold), rgb(var(--gold-rgb) / 0.15));
  transition: width var(--dur-slow) var(--ease);
}
.event-type:hover::before { width: 100%; }
.event-type__name {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.625rem);
  font-weight: 400;
  line-height: 1.2;
  color: var(--heading);
}
.event-type__text {
  margin-top: 0.75rem;
  max-width: 34ch;
  font-size: var(--fs-small);
  line-height: 1.75;
  color: var(--muted);
}
/* Optional caps line under the name — used by the tiers grid to carry the
   guest ceiling. --gold-deep, not --accent: this is text on a light ground,
   where the champagne gold measures 2.0:1. */
.event-type__meta {
  margin-top: 0.55rem;
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  color: var(--gold-deep);
}


/* ==========================================================================
   10c. TIERS & BOUNDARIES
   The three packages, plus the short list of work the company turns down.
   The tiers reuse .event-grid / .event-type wholesale rather than inventing a
   third card treatment — they are the same shape of content (a name and a
   sentence) and a page with three near-identical bespoke card styles reads as
   indecision, not variety. Only the band colour separates them.
   ========================================================================== */
.tiers { background: var(--bg-alt); }

/* Capped at a readable measure. These paragraphs are the commercial small
   print — pricing floor, lead times, travel, payment schedule — and at the
   full 1320px container they ran to well over 150 characters a line. */
.tiers__note {
  margin-top: clamp(2rem, 4vw, 3rem);
  max-width: 62ch;
  font-size: var(--fs-small);
  line-height: 1.8;
  color: var(--muted);
}
.tiers__note p + p { margin-top: 1rem; }
.tiers__note strong { color: var(--heading); font-weight: 500; }

/* The "what we don't do" block. Bordered rather than carded, so it reads as a
   footnote to the offer above it and never competes with the tiers. */
.boundaries {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding: clamp(1.5rem, 3vw, 2.25rem) clamp(1.5rem, 3vw, 2.5rem);
  border: 1px solid var(--hairline);
}
.boundaries__title {
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  font-weight: 400;
  color: var(--heading);
}
.boundaries__list {
  margin-top: 1rem;
  display: grid;
  gap: 0.75rem;
}
@media (min-width: 860px) {
  .boundaries__list { grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 3vw, 2.5rem); }
}
.boundaries__list li {
  position: relative;
  padding-left: 1.4rem;
  font-size: var(--fs-small);
  line-height: 1.75;
  color: var(--muted);
}
/* A decorative dash, not a character in the text — hence aria-invisible ::before
   and the accent gold, which is allowed here precisely because it carries no
   words. */
.boundaries__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.85em;
  width: 0.7rem;
  height: 1px;
  background: var(--accent);
}


/* ==========================================================================
   11. PROCESS  (dark band)
   ========================================================================== */
.process {
  position: relative;
  overflow: hidden;
  background: var(--navy);
  color: rgb(var(--paper-rgb) / 0.72);
}
/* A single soft gold light thrown from above the band. It is the only place on
   the page where the brand colour behaves like light rather than ink, and it
   is what stops 900px of flat navy reading as a black hole between two cream
   sections. Kept under 10% so it never becomes a background of its own. */
.process::before {
  content: "";
  position: absolute;
  inset: -35% -10% auto;
  height: 90%;
  background: radial-gradient(52% 60% at 50% 0%,
    rgb(var(--gold-rgb) / 0.09), rgb(var(--gold-rgb) / 0) 70%);
  pointer-events: none;
}
.process > * { position: relative; }
.process__list {
  display: grid;
  gap: clamp(2.25rem, 5vw, 3rem);
  counter-reset: step;
}
@media (min-width: 640px) { .process__list { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .process__list { grid-template-columns: repeat(4, 1fr); } }

.step {
  position: relative;
  padding-top: clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid var(--hairline-light);
}
/* The numerals are where the brand gold earns its place: large display type on
   the one solid dark band, which is the only context where this gold carries
   enough contrast to be used as a colour rather than a hairline. At 85% over
   --navy the champagne gold measures 6.64:1 — comfortably past the 4.5:1 body
   floor, never mind the 3:1 large-text one — and resolves to the full 8.89:1
   on hover. */
.step__num {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.4rem + 3vw, 3.5rem);
  font-weight: 300;
  line-height: 1;
  color: rgb(var(--gold-rgb) / 0.85);
  transition: color var(--dur-slow) var(--ease);
  /* see the @supports block below for the poured-metal version */
}
.step:hover .step__num { color: var(--accent); }
/* Poured metal: the numerals take the gold as a vertical gradient rather than a
   flat fill. Behind @supports because background-clip: text with transparent
   type is invisible where it is unsupported — the flat gold above stays the
   truth for those browsers. Every stop of the gradient is one of the three
   brand golds, measuring 7.6:1 (metal), 8.9:1 (gold) and 11.5:1 (bright) on
   --navy, so no part of a numeral is weaker than the flat colour it replaces. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .step__num {
    background-image: linear-gradient(175deg,
      var(--gold-bright) 0%, var(--gold) 52%, var(--gold-metal) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    transition: filter var(--dur-slow) var(--ease);
  }
  .step:hover .step__num { color: transparent; filter: brightness(1.15); }
}

.step__title {
  margin-top: clamp(1rem, 2vw, 1.5rem);
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--paper);
}
.step__text {
  margin-top: 0.9rem;
  max-width: 32ch;
  font-size: var(--fs-body);
  line-height: 1.8;
}

/* Timeline and the client's own homework for each phase. Set in the accent
   gold, which on this band measures 8.9:1 — the one place in the site where
   the brand colour can carry small text outright. */
.step__meta {
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--hairline-light);
  max-width: 32ch;
  display: grid;
  gap: 0.4rem;
}
.step__meta dt {
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  color: var(--accent);
}
.step__meta dd {
  margin: 0 0 0.5rem;
  font-size: 0.8125rem;
  line-height: 1.65;
  color: rgb(var(--paper-rgb) / 0.72);
}
.step__meta dd:last-child { margin-bottom: 0; }


/* ==========================================================================
   12. PORTFOLIO
   ========================================================================== */
.portfolio { background: var(--bg); }

.gallery {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

.shot { margin: 0; }
.shot__frame {
  position: relative;
  overflow: hidden;
  background: var(--paper-alt);
  /* A gold hairline drawn inside the frame, and the page's resting shadow
     under it, so the photographs sit on the cream rather than being holes cut
     in it. Both are inset/box shadows on the frame itself, which is already
     the overflow clip — no extra element. */
  box-shadow:
    inset 0 0 0 1px rgb(var(--gold-rgb) / 0.16),
    var(--shadow-soft);
  transition: box-shadow var(--dur-slow) var(--ease);
}
.shot:hover .shot__frame {
  box-shadow:
    inset 0 0 0 1px rgb(var(--gold-rgb) / 0.4),
    var(--shadow-lift);
}
.shot__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* A gentle, consistent grade so photos from different sources feel like one
     set — full colour returns on hover */
  filter: saturate(0.74) contrast(1.03);
  transition: transform 1.1s var(--ease), filter var(--dur-slow) var(--ease);
}
/* Warm wash that lifts away on hover */
.shot__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgb(var(--gold-rgb) / 0.16), rgb(var(--navy-rgb) / 0.18));
  opacity: 1;
  transition: opacity var(--dur-slow) var(--ease);
  pointer-events: none;
}
.shot:hover .shot__frame img { transform: scale(1.045); filter: saturate(1) contrast(1); }
.shot:hover .shot__frame::after { opacity: 0; }

.shot__caption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1.25rem;
  padding-top: clamp(0.85rem, 1.6vw, 1.15rem);
}
.shot__label {
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--muted);
}
.shot__title {
  font-family: var(--font-display);
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.375rem);
  font-weight: 400;
  font-style: italic;
  color: var(--heading);
}

/* Mobile: a single generous column */
.shot__frame { aspect-ratio: 4 / 5; }

@media (min-width: 600px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
  .shot--a .shot__frame,
  .shot--d .shot__frame { aspect-ratio: 4 / 5; }
  .shot--b .shot__frame,
  .shot--c .shot__frame,
  .shot--e .shot__frame,
  .shot--f .shot__frame,
  .shot--g .shot__frame { aspect-ratio: 3 / 4; }
  /* The Konark wheel is a wide stone relief — cropping it to portrait would
     cut the wheel off at both hubs, so it keeps a landscape frame at every
     width. */
  .shot--h .shot__frame { aspect-ratio: 3 / 2; }
}

/* Desktop: an asymmetric editorial layout on a 12-column grid */
@media (min-width: 900px) {
  .gallery {
    grid-template-columns: repeat(12, 1fr);
    align-items: start;
  }
  .shot--a { grid-column: 1 / span 7; }
  .shot--b { grid-column: 8 / span 5; margin-top: clamp(2.5rem, 6vw, 5rem); }
  .shot--c { grid-column: 1 / span 5; }
  .shot--d { grid-column: 6 / span 7; margin-top: clamp(2rem, 5vw, 4rem); }
  .shot--e { grid-column: 1 / span 6; }
  .shot--f { grid-column: 7 / span 6; margin-top: clamp(2.5rem, 6vw, 4.5rem); }
  /* Fourth row mirrors the second: narrow portrait left, wide landscape right,
     with the right-hand tile dropped so the row does not sit on one baseline. */
  .shot--g { grid-column: 1 / span 5; }
  .shot--h { grid-column: 6 / span 7; margin-top: clamp(2rem, 5vw, 4rem); }

  .shot--a .shot__frame { aspect-ratio: 3 / 2; }
  .shot--b .shot__frame { aspect-ratio: 3 / 4; }
  .shot--c .shot__frame { aspect-ratio: 4 / 5; }
  .shot--d .shot__frame { aspect-ratio: 3 / 2; }
  .shot--e .shot__frame { aspect-ratio: 4 / 3; }
  .shot--f .shot__frame { aspect-ratio: 4 / 3; }
  .shot--g .shot__frame { aspect-ratio: 3 / 4; }
  .shot--h .shot__frame { aspect-ratio: 3 / 2; }
}


/* ==========================================================================
   13. TESTIMONIALS
   ========================================================================== */
.testimonials { background: var(--bg-alt); }

.testimonials__grid {
  display: grid;
  gap: clamp(2.5rem, 5vw, 3.5rem);
}
@media (min-width: 860px) {
  .testimonials__grid { grid-template-columns: repeat(3, 1fr); }
  .quote + .quote {
    padding-left: clamp(2rem, 3.5vw, 3rem);
    border-left: 1px solid var(--hairline);
  }
}

.quote {
  margin: 0;
  display: flex;
  flex-direction: column;
}
.quote__mark {
  font-family: var(--font-display);
  font-size: 3.25rem;
  line-height: 0.6;
  color: var(--accent);
  margin-bottom: 1.25rem;
}
.quote__text { margin: 0; }
.quote__text p {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 1.05rem + 0.75vw, 1.625rem);
  font-style: italic;
  font-weight: 300;
  line-height: 1.5;
  color: var(--heading);
  text-wrap: pretty;
}
.quote__author {
  margin-top: auto;
  padding-top: clamp(1.5rem, 3vw, 2rem);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--navy);
}
.quote__meta {
  display: block;
  margin-top: 0.5rem;
  font-weight: 400;
  letter-spacing: var(--tracking-mid);
  color: var(--muted);
}


/* ==========================================================================
   14. CALL TO ACTION
   ========================================================================== */
.cta {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(28rem, 62vh, 40rem);
  padding-block: clamp(5rem, 12vw, 8rem);
  overflow: hidden;
  isolation: isolate;
  text-align: center;
}
.cta__media { position: absolute; inset: 0; z-index: -2; }
.cta__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 40%;
}
/* Left at the values it has always had: the current CTA photograph is a low-key
   interior, and re-measuring after the swap showed every text element already
   comfortable — eyebrow 9.3:1, heading 5.8:1, body 10.3:1, button 15.0:1, all
   against a 4.5:1 floor (the heading would only have needed 3:1). As with the
   hero, these belong to THIS photograph; swap it and measure again. */
.cta__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgb(var(--navy-rgb) / 0.55), rgb(var(--navy-rgb) / 0.68));
}
.cta__inner { position: relative; max-width: 48rem; }
.cta__inner .display { color: var(--paper); }
/* The tagline sits above the CTA heading as a small brand signature */
.cta__eyebrow { margin-bottom: clamp(1rem, 2.5vw, 1.5rem); }
/* Same treatment as the hero h1 — the two are the same line and bookend the
   page, so they are capitalised, tracked and broken identically. */
.cta__title {
  letter-spacing: 0.01em;
  text-transform: uppercase;
}
.cta__title em { text-transform: lowercase; }
.cta__text {
  margin: clamp(1.25rem, 3vw, 1.75rem) auto clamp(2.25rem, 5vw, 3rem);
  max-width: 40ch;
  font-size: var(--fs-lede);
  color: rgb(var(--paper-rgb) / 0.9);
}


/* ==========================================================================
   15. CONTACT & FORM
   ========================================================================== */
.contact { background: var(--bg); }
.contact__grid {
  display: grid;
  gap: var(--gap-lg);
  align-items: start;
}
@media (min-width: 1024px) {
  .contact__grid {
    grid-template-columns: 0.85fr 1fr;
    gap: clamp(3rem, 7vw, 7rem);
  }
  .contact__intro { position: sticky; top: calc(var(--header-h) + 3rem); }
}

.contact__intro .lede { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); max-width: 38ch; }

/* min-width:0 stops long input values from forcing the grid column wider */
.contact__intro,
.contact__form-wrap { min-width: 0; }

.contact__details {
  margin: clamp(2.5rem, 5vw, 3.5rem) 0 0;
  display: grid;
  gap: 1.5rem;
}
/* Stacked on the narrowest screens — a 6.5rem label column plus a long email
   address does not fit inside 320px. Two columns from 26rem upward. */
.contact__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.35rem;
  align-items: start;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--hairline-soft);
}
@media (min-width: 26em) {
  .contact__row {
    grid-template-columns: 6.5rem 1fr;
    gap: 1rem;
  }
}
.contact__row dt {
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 0.25em;
}
.contact__row dd {
  margin: 0;
  min-width: 0;
  font-size: var(--fs-small);
  line-height: 1.7;
  color: var(--heading);
  overflow-wrap: anywhere; /* long email addresses must never push the page wide */
}
.contact__row a {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  transition: background-size var(--dur) var(--ease);
}
.contact__row a:hover { background-size: 0% 1px; }

/* <address> defaults to italic in every browser — the studio address should
   read in the same voice as the rest of the contact block */
.contact__row address {
  font-style: normal;
  line-height: 1.7;
}

/* Qualifiers under a contact value — "by prior appointment", "concierge active
   at weekends". Quieter than the value they belong to, but still AA. */
.contact__fine {
  display: inline-block;
  margin-top: 0.35rem;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--muted);
}

/* Marks values that are still placeholders. Deliberately visible: a dotted
   underline signals "not final" to anyone reviewing the page, and it costs
   nothing to delete this class once the real details are in. */
/* Currently unused: every contact value on the page is now the client's real
   one. Kept because the next unknown value should be marked, not invented —
   wrap it in this class and the dotted rule says "not final" to anyone
   reviewing the page. --gold-deep, since --gold measures 2.0:1 here. */
.is-placeholder {
  border-bottom: 1px dotted var(--gold-deep);
  padding-bottom: 1px;
}

/* --- Form ---------------------------------------------------------------- */
.form__grid {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2rem) clamp(1.25rem, 3vw, 2.25rem);
}
@media (min-width: 560px) {
  .form__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .field--full { grid-column: 1 / -1; }
}

.field { display: flex; flex-direction: column; min-width: 0; }

.field__label {
  margin-bottom: 0.65rem;
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  color: var(--heading);
}
/* --gold-deep, not --accent. The champagne gold measures 2.0:1 on paper, and
   this asterisk is the only thing marking a field as required. */
.req { color: var(--gold-deep); }

.field__input {
  width: 100%;
  padding: 0.7rem 0 0.85rem;
  background: transparent;
  border: 0;
  /* Also --gold-deep: an input underline is a UI boundary, which WCAG asks to
     clear 3:1. The plain gold manages 2.0:1 here; --gold-deep measures 5.5:1
     on paper and 4.9:1 on the alt band. */
  border-bottom: 1px solid var(--gold-deep);
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 300;
  color: var(--navy);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
  -webkit-appearance: none;
  appearance: none;
}
.field__input::placeholder { color: var(--placeholder); opacity: 1; }
.field__input:hover { border-bottom-color: var(--slate); }
.field__input:focus {
  outline: none;
  border-bottom-color: var(--navy);
  box-shadow: 0 1px 0 0 var(--navy);
}
.field__input:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 4px;
}

.field__textarea {
  resize: vertical;
  min-height: 9rem;
  line-height: 1.7;
}

/* Custom select chevron (inline SVG data URI keeps it dependency-free) */
.field__select-wrap { position: relative; }
.field__select {
  padding-right: 2rem;
  cursor: pointer;
  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 fill='none' stroke='%236D6258' stroke-width='1.2' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.25rem center;
  background-size: 12px 8px;
}
.field__select:invalid { color: var(--placeholder); }
.field__select option { color: var(--navy); }

/* Date inputs need a nudge to match the other fields across browsers */
.field__input[type="date"] { min-height: 3rem; }
.field__input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: 0.5;
  cursor: pointer;
}

.field__hint {
  margin-top: 0.55rem;
  font-size: 0.75rem;
  color: var(--muted);
  line-height: 1.5;
}

.field__error {
  margin-top: 0.55rem;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--error);
  min-height: 0;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.field__error:not(:empty) { opacity: 1; transform: none; }
/* Errors are marked by text + border colour, never colour alone */
.field.has-error .field__input { border-bottom-color: var(--error); }
.field.has-error .field__label { color: var(--error); }

/* --- Checkbox group (Event Intent) ---------------------------------------
   A <fieldset> rather than a <select multiple>: multi-selects are close to
   unusable on a phone, and every option here has to be readable at a glance.
   The fieldset is stripped of its default chrome and its <legend> is styled to
   match .field__label exactly, so the group sits in the grid as if it were an
   ordinary field. */
.field__group {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.field__legend {
  padding: 0;
  margin-bottom: 0.65rem;
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  color: var(--heading);
}
.checks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.check {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 1rem;
  border: 1px solid var(--hairline);
  font-size: var(--fs-small);
  line-height: 1.4;
  color: var(--text);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.check:hover { border-color: var(--gold-deep); }
.check__box {
  width: 0.95rem;
  height: 0.95rem;
  flex: none;
  border: 1px solid var(--gold-deep);
  transition: background-color var(--dur) var(--ease);
}
/* State is carried by the filled box AND the darkened border, never by colour
   alone — the same rule the error styling follows. */
.check input:checked ~ .check__box {
  background: var(--navy);
  border-color: var(--navy);
}
.check:has(input:checked) {
  border-color: var(--navy);
  background: var(--surface);
}
/* The native input stays in the layout for hit-testing and keyboard focus; it
   is only visually replaced, never display:none, which would remove it from
   the accessibility tree. */
.check input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
}
.check:focus-within {
  outline: 2px solid var(--navy);
  outline-offset: 3px;
}

.form__note {
  margin: clamp(1.75rem, 3vw, 2.25rem) 0 1.5rem;
  font-size: 0.75rem;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.form__summary {
  margin-top: 1.25rem;
  padding: 0.9rem 1.1rem;
  border-left: 2px solid var(--error);
  background: rgba(154, 59, 46, 0.06);
  font-size: var(--fs-small);
  color: var(--error);
}
.form__summary[hidden] { display: none; }

/* --- Success panel ------------------------------------------------------- */
.form-success {
  padding: clamp(2rem, 5vw, 3.25rem);
  background: var(--white);
  border: 1px solid var(--hairline-soft);
  text-align: center;
  animation: rise-in 0.7s var(--ease) both;
}
.form-success[hidden] { display: none; }
.form-success__mark {
  display: block;
  width: 46px;
  height: 46px;
  margin: 0 auto clamp(1.25rem, 3vw, 1.75rem);
  border: 1px solid var(--accent);
  border-radius: 50%;
  position: relative;
}
.form-success__mark::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 48%;
  width: 14px;
  height: 7px;
  border-left: 1px solid var(--navy);
  border-bottom: 1px solid var(--navy);
  transform: translate(-50%, -50%) rotate(-45deg);
}
.form-success__title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 400;
  color: var(--heading);
  line-height: 1.25;
}
.form-success__text {
  margin: 1rem auto clamp(1.75rem, 4vw, 2.25rem);
  max-width: 44ch;
  font-size: var(--fs-small);
  color: var(--muted);
  line-height: 1.75;
}
.form-success code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.9em;
  color: var(--slate);
}
.form.is-hidden { display: none; }


/* ==========================================================================
   16. FOOTER
   ========================================================================== */
/* One step deeper than the process band, so the two dark areas read as
   foreground and floor rather than the same slab repeated. */
.site-footer {
  background: var(--navy-deep);
  color: rgb(var(--paper-rgb) / 0.68);
  padding-top: clamp(3.5rem, 8vw, 6rem);
}
.site-footer__grid {
  display: grid;
  gap: clamp(2.25rem, 5vw, 3.5rem);
  padding-bottom: clamp(3rem, 6vw, 4.5rem);
}
@media (min-width: 640px) {
  .site-footer__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .site-footer__grid { grid-template-columns: 1.5fr 1fr 1fr 1.3fr; }
}
.site-footer__brand,
.site-footer__col { min-width: 0; }

/* The third setting of the brand line, and it follows the hero and the closing
   heading: capitals, "moments" lowercase and italic, "legend" gold. The line
   used to be italic throughout — that is why the italic moves onto the <em>
   here rather than being added to it. At this size the capitals need more
   tracking than the display sizes do, hence 0.06em against their 0.01em.
   --gold-bright measures 12.3:1 on --navy-deep, so the word is if anything
   safer here than over the photographs it was chosen for. */
.site-footer__tagline {
  margin-top: 1.1rem;
  font-family: var(--font-display);
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  letter-spacing: 0.06em;
  line-height: 1.5;   /* the body's 1.75 leaves a hole between the two lines
                         this wraps onto in the footer column */
  text-transform: uppercase;
  color: var(--paper);
}
.site-footer__tagline em {
  font-style: italic;
  text-transform: lowercase;
}
/* The registered name under the wordmark — the eyebrow setting used across the
   page, but brighter than the footer's body colour and tracked wider, so the
   column reads name, then brand line, then paragraph, each clearly a different
   voice rather than three rows of the same grey. */
.site-footer__name {
  margin-top: 0.8rem;
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgb(var(--paper-rgb) / 0.86);
}

.site-footer__heading {
  margin-bottom: 1.35rem;
  font-family: var(--font-body);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--paper);
}
.site-footer__list { display: grid; gap: 0.85rem; font-size: var(--fs-small); }
.site-footer__list a {
  display: inline-block;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size var(--dur) var(--ease), color var(--dur) var(--ease);
}
.site-footer__list a:hover { color: var(--paper); background-size: 100% 1px; }

/* --- Social links with brand marks ---------------------------------------
   Two classes beat the one-class-one-type `.site-footer__list a` above, which
   is what lets the underline move off the anchor and onto the word. Running
   that growing underline beneath the icon as well would read as a
   strikethrough through the glyph. */
.site-footer__list .social-link {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  background-image: none;
}
.social-link__icon {
  width: 16px;
  height: 16px;
  flex: none;
  fill: currentColor;
  /* Held slightly back so the word leads and the marks read as quiet
     companions rather than badges. */
  opacity: 0.7;
  transition: opacity var(--dur) var(--ease);
}
.social-link:hover .social-link__icon,
.social-link:focus-visible .social-link__icon { opacity: 1; }

.social-link__label {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size var(--dur) var(--ease);
}
.social-link:hover .social-link__label,
.social-link:focus-visible .social-link__label { background-size: 100% 1px; }

.site-footer__note {
  max-width: 30ch;
  margin-bottom: 1.35rem;
  font-size: var(--fs-small);
  line-height: 1.75;
}
/* Same paragraph, reused in the brand column, where it follows the brand line
   instead of leading a column — so the margins swap ends and it is allowed a
   few more characters per line, the brand column being the widest of the four. */
.site-footer__note--brand {
  max-width: 36ch;
  margin-top: 1.15rem;
  margin-bottom: 0;
}


.site-footer__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  padding-block: clamp(1.5rem, 3vw, 2rem);
  border-top: 1px solid var(--hairline-light);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  color: rgb(var(--paper-rgb) / 0.5);
}
.site-footer__fineprint { font-style: italic; }

/* At the very bottom of the page the floating WhatsApp button lands on top of
   this bar. Reserve room for it so the copyright line is never sitting under
   a green circle. 50px button + its 1rem offset, plus a little air. */
@media (max-width: 767px) {
  .site-footer__bar { padding-bottom: calc(50px + 1rem + 1.25rem); }
}


/* ==========================================================================
   16b. WHATSAPP CONTACT
   Bottom-right on every screen size. Sits above page content but below the
   mobile navigation panel so it can never cover that panel's close button.
   ========================================================================== */
.wa-float {
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 120;
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.85rem 1.15rem;
  border-radius: 999px;
  background: var(--whatsapp);
  color: #06301A;
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  line-height: 1;
  box-shadow: 0 6px 20px rgb(var(--navy-rgb) / 0.28);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.wa-float:hover,
.wa-float:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgb(var(--navy-rgb) / 0.34);
}
.wa-float__icon {
  width: 22px;
  height: 22px;
  flex: none;
  fill: #06301A;
}
/* The label is a bonus on wide screens; below that the mark speaks for itself
   and a pill of text would crowd the thumb zone. */
.wa-float__label { display: none; }
@media (min-width: 768px) {
  .wa-float__label { display: inline; }
}

/* On a phone this is a circle, not a pill, and a smaller one. A floating
   button always sits on top of whatever is beneath it, so on a 360px screen
   the difference between 59px and 50px is the difference between crowding the
   hero's second call to action and clearing it. */
@media (max-width: 767px) {
  .wa-float {
    width: 50px;
    height: 50px;
    padding: 0;
    justify-content: center;
    gap: 0;
  }
  .wa-float__icon { width: 24px; height: 24px; }
}
/* Hidden while the mobile menu is open — it would float over the panel. */
body.is-locked .wa-float { opacity: 0; pointer-events: none; }

/* The same mark, inline in the contact details list */
/* Sits under the tel: link in the Concierge row rather than beside it — they
   are the same number reached two ways, and side by side they read as two
   numbers. `flex` (not inline-flex) puts it on its own line; `width: fit-content`
   keeps the underline as short as the text. */
.contact__wa {
  display: flex;
  width: fit-content;
  margin-top: 0.5rem;
  align-items: center;
  gap: 0.5rem;
  color: var(--heading);
  /* --gold-deep, not --accent: the champagne gold underline measures 2.0:1 on
     paper, and this rule is the link's only affordance. */
  border-bottom: 1px solid var(--gold-deep);
  padding-bottom: 1px;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.contact__wa:hover { color: var(--gold-deep); border-color: var(--gold-deep); }
.contact__wa svg { width: 17px; height: 17px; fill: var(--whatsapp-dark); flex: none; }


/* ==========================================================================
   17. SCROLL REVEAL
   Elements marked data-reveal start hidden ONLY when JavaScript is available
   (the inline snippet in <head> swaps .no-js for .js on <html>). js/script.js
   then adds .is-visible with an IntersectionObserver. Without JS, nothing is
   ever hidden.
   ========================================================================== */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity var(--dur-slow) var(--ease),
              transform var(--dur-slow) var(--ease);
  will-change: opacity, transform;
}
.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Children of a .stagger container cascade in one after another */
.stagger.is-visible > * {
  animation: rise-in 0.9s var(--ease) both;
}
.stagger.is-visible > *:nth-child(1) { animation-delay: 0.05s; }
.stagger.is-visible > *:nth-child(2) { animation-delay: 0.17s; }
.stagger.is-visible > *:nth-child(3) { animation-delay: 0.29s; }
.stagger.is-visible > *:nth-child(4) { animation-delay: 0.41s; }
.stagger.is-visible > *:nth-child(5) { animation-delay: 0.53s; }
.stagger.is-visible > *:nth-child(6) { animation-delay: 0.65s; }


/* ==========================================================================
   18. REDUCED MOTION & PRINT
   ========================================================================== */
@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;
  }

  .js [data-reveal] { opacity: 1; transform: none; }
  .hero__img { animation: none; }
  .scroll-cue__line::after { animation: none; }
  .shot:hover .shot__frame img { transform: none; }
}

@media print {
  .site-header,
  .mobile-nav,
  .scroll-cue,
  .cta__media { display: none !important; }
  body { background: #fff; color: #000; }
  .js [data-reveal] { opacity: 1 !important; transform: none !important; }
}