/* ============================================================
   LAVOYA CATERERS — Production Stylesheet
   ============================================================ */

:root {
    --primary-dark: #191714;
    --warm-ivory: #F6F1E8;
    --soft-beige: #E8DED0;
    --muted-olive: #77745F;
    --luxury-bronze: #9A7553;
    --bronze-deep: #7E5E41;
    --white: #FFFFFF;
    --ink-soft: #565049;

    /* Motion system — one easing curve, three durations. */
    --ease: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
    --dur-fast: 0.22s;
    --dur: 0.4s;
    --dur-slow: 0.75s;

    /* Layout grid — nav, hero and every section align to these. */
    --container: 1440px;
    --gutter: 40px;
    --nav-h: 92px;
    --nav-h-scrolled: 68px;

    /* Spacing scale — a 4px base. Every margin, padding and gap on the
       page resolves to one of these steps; one-off pixel values are a
       bug, not a decision. The middle steps (12/20/28) are what an
       8-only scale misses, and they carry most of the type rhythm. */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 28px;
    --space-8: 32px;
    --space-10: 40px;
    --space-12: 48px;
    --space-14: 56px;
    --space-16: 64px;
    --space-20: 80px;
    --space-24: 96px;

    /* Vertical rhythm — every section uses one of these two, so the
       spacing between blocks stays even down the whole page.
       --section-y  plain sections on the page background
       --block-y    tinted or full-bleed bands, which carry their own
                    colour and so need less air to read as separate */
    --section-y: 120px;
    --block-y: 72px;

    /* One gap for the space under a section header, one for the gap
       between the two columns of a split section. Set once here so no
       section quietly invents its own. */
    --header-gap: var(--space-16);
    --split-gap: var(--space-20);

    --card-radius: 4px;

    /* Playfair Display runs optically larger than the Cormorant it
       replaced — bigger x-height, sturdier stems — so the display sizes
       below are set for it, not scaled from the old face. */
    --serif: 'Playfair Display', Georgia, 'Times New Roman', serif;
    --sans: 'Inter', sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html {
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--nav-h-scrolled) + 24px);
    -webkit-text-size-adjust: 100%;
}

body {
    background-color: var(--warm-ivory);
    color: var(--primary-dark);
    font-family: var(--sans);
    line-height: 1.6;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body.no-scroll { overflow: hidden; }

h1, h2, h3, h4 {
    font-family: var(--serif);
    font-weight: 400;
    line-height: 1.16;
    letter-spacing: -0.01em;
    text-wrap: balance;
}

p { text-wrap: pretty; }

h1 em, h2 em { font-style: italic; color: var(--luxury-bronze); }
.on-dark h2 em, .hero h1 em { color: inherit; font-style: italic; }

a { text-decoration: none; color: inherit; transition: color var(--dur) var(--ease), opacity var(--dur) var(--ease), border-color var(--dur) var(--ease); }
ul { list-style: none; }
button { font-family: inherit; background: none; border: none; cursor: pointer; color: inherit; }

/* Kills the 300ms double-tap-zoom wait on touch, and replaces the
   browser's default blue tap flash with the brand bronze. */
button, a, summary, label {
    touch-action: manipulation;
    -webkit-tap-highlight-color: rgba(154, 117, 83, 0.18);
}

img { max-width: 100%; display: block; object-fit: cover; }

/* Any rule below that sets `display` on an element would otherwise beat
   the UA's [hidden] rule and un-hide it. The progressive-enhancement
   controls (carousel arrows, mobile menu) all ship
   hidden and are revealed by main.js, so this has to hold. */
[hidden] { display: none !important; }

::selection { background: var(--luxury-bronze); color: var(--white); }

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

/* Skip link — first tab stop for keyboard and screen-reader users. */
.skip-link {
    position: fixed;
    top: 12px;
    left: 12px;
    z-index: 2000;
    padding: 12px 22px;
    background: var(--primary-dark);
    color: var(--white);
    font-size: 13px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    transform: translateY(-150%);
    transition: transform var(--dur) var(--ease);
}
.skip-link:focus-visible { transform: translateY(0); }

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

.container {
    max-width: var(--container);
    margin: 0 auto;
    padding-inline: var(--gutter);
}

/* padding-block only. Many sections carry both .container and
   .section-padding; a `padding: 120px 0` shorthand here would win on
   source order and silently erase the container's side gutter. */
.section-padding { padding-block: var(--section-y); }

/* The join straight after the hero. The hero already ends in its own
   band of dark, so a full section gap there reads as a hole rather
   than a breath — the rhythm goes tight here and generous between the
   peer sections that follow. */
.section-tight-top { padding-block-start: var(--block-y); }

/* ------------------------------------------------------------
   Buttons — shared sweep-fill hover
   ------------------------------------------------------------ */
.btn {
    position: relative;
    display: inline-block;
    padding: 16px 36px;
    font-size: 14px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    cursor: pointer;
    border: 1px solid transparent;
    font-weight: 500;
    overflow: hidden;
    isolation: isolate;
    transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease),
                border-color var(--dur) var(--ease), transform var(--dur-fast) var(--ease-soft);
}

.btn::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--luxury-bronze);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--dur-slow) var(--ease);
}
.btn:hover::before, .btn:focus-visible::before { transform: scaleX(1); }
.btn:hover, .btn:focus-visible { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(25,23,20,0.18); }
.btn:active { transform: translateY(0); box-shadow: 0 4px 12px rgba(25,23,20,0.16); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }
.btn:disabled:hover { transform: none; box-shadow: none; }
.btn:disabled::before { transform: scaleX(0); }

.btn-primary { background-color: var(--primary-dark); color: var(--white); }
.btn-primary:hover, .btn-primary:focus-visible { color: var(--white); }

.btn-outline {
    border: 1px solid var(--primary-dark);
    color: var(--primary-dark);
    background: transparent;
}
.btn-outline::before { background: var(--primary-dark); }
.btn-outline:hover, .btn-outline:focus-visible { color: var(--white); }

.btn-light { background: var(--white); color: var(--primary-dark); }
.btn-light:hover, .btn-light:focus-visible { color: var(--white); }

/* ------------------------------------------------------------
   Pill controls — the tab, filter and toggle buttons that used to
   read as plain text. Every one now carries a visible border, a
   hover fill and a clearly filled selected state.
   ------------------------------------------------------------ */
.pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    /* 13px padding keeps the control above a 40px touch target. */
    padding: 13px 26px;
    border: 1px solid rgba(25,23,20,0.22);
    border-radius: 999px;
    background: transparent;
    color: var(--primary-dark);
    font-size: 13px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 500;
    line-height: 1.2;
    cursor: pointer;
    transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
                border-color var(--dur) var(--ease), transform var(--dur-fast) var(--ease-soft),
                box-shadow var(--dur) var(--ease);
}

.pill:hover {
    border-color: var(--luxury-bronze);
    color: var(--luxury-bronze);
    transform: translateY(-2px);
}

.pill[aria-pressed="true"],
.pill[aria-selected="true"] {
    background: var(--primary-dark);
    border-color: var(--primary-dark);
    color: var(--white);
    box-shadow: 0 8px 20px rgba(25,23,20,0.22);
}

.pill[aria-pressed="true"]:hover,
.pill[aria-selected="true"]:hover {
    background: var(--bronze-deep);
    border-color: var(--bronze-deep);
    color: var(--white);
}

/* On the dark cuisine band the same pill inverts. */
.on-dark .pill {
    border-color: rgba(255,255,255,0.28);
    color: rgba(255,255,255,0.82);
}
.on-dark .pill:hover { border-color: var(--luxury-bronze); color: var(--white); }
.on-dark .pill[aria-selected="true"] {
    background: var(--luxury-bronze);
    border-color: var(--luxury-bronze);
    color: var(--white);
    box-shadow: 0 8px 22px rgba(154,117,83,0.4);
}
.on-dark .pill[aria-selected="true"]:hover { background: var(--bronze-deep); border-color: var(--bronze-deep); }

.label {
    text-transform: uppercase;
    letter-spacing: 0.2em;
    font-size: 12px;
    color: var(--luxury-bronze);
    margin-bottom: 20px;
    display: block;
}

/* ------------------------------------------------------------
   Media loading — reserves space, fades the image in
   ------------------------------------------------------------ */
.media {
    position: relative;
    overflow: hidden;
    background: var(--soft-beige);
}

.js .media img {
    opacity: 0;
    transition: opacity var(--dur-slow) var(--ease-soft), transform 1.2s var(--ease);
}
.js .media img.is-loaded { opacity: 1; }

/* Shimmer while the photo is in flight; removed once loaded. */
.js .media::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg,
        rgba(255,255,255,0) 20%,
        rgba(255,255,255,0.45) 50%,
        rgba(255,255,255,0) 80%);
    background-size: 220% 100%;
    animation: shimmer 1.6s infinite linear;
    pointer-events: none;
}
.js .media.is-settled::after { content: none; }

@keyframes shimmer {
    from { background-position: 180% 0; }
    to   { background-position: -80% 0; }
}

/* ============================================================
   1. NAVIGATION
   White over the dark hero, solid once scrolled.
   ============================================================ */
.site-header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 1000;
    padding: 22px 0;
    color: var(--white);
    transition: background-color var(--dur) var(--ease), padding var(--dur) var(--ease),
                box-shadow var(--dur) var(--ease), color var(--dur) var(--ease);
}

/* The header stays put at every scroll position. An auto-hiding
   header would put the nav out of reach on the way down the page. */
.site-header.scrolled {
    background: var(--white);
    color: var(--primary-dark);
    padding: 12px 0;
    box-shadow: 0 4px 20px rgba(0,0,0,0.06);
}

.nav-container {
    max-width: var(--container);
    margin: 0 auto;
    padding: 0 var(--gutter);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 24px;
}

/* ---- Brand lockup ------------------------------------------------
   Wordmark over a letterspaced descriptor, matching the LAVOYA /
   CATERING logo. `--logo-size` drives the whole lockup so the nav,
   footer and 404 variants stay in proportion from one value. */
.logo {
    --logo-size: 30px;
    display: inline-flex;
    align-items: center;
    line-height: 1;
}

/* The raster logo artwork already carries the fleuron, wordmark and
   CATERING descriptor. `--logo-size` still drives the whole lockup:
   the image renders 2.2× that value tall, the height of the old
   three-part CSS lockup, so nav, footer and 404 stay in proportion
   from one value. */
.logo-img {
    height: calc(var(--logo-size) * 2.2);
    width: auto;
    display: block;
    transition: filter var(--dur) var(--ease), opacity var(--dur) var(--ease);
}

/* Over the hero photo the header is transparent and white — the gold
   artwork sinks into warm photography there, so render it white until
   the solid header background takes over. */
.site-header:not(.scrolled) .logo-img { filter: brightness(0) invert(1); opacity: 0.94; }

.nav-links { display: flex; gap: 36px; }

.nav-links a {
    position: relative;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-weight: 500;
    opacity: 0.85;
    padding: 4px 0;
}

.nav-links a::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 1px;
    background: var(--luxury-bronze);
    transform: scaleX(0);
    transform-origin: right center;
    transition: transform var(--dur) var(--ease);
}

.nav-links a:hover { opacity: 1; }
.nav-links a:hover::after,
.nav-links a[aria-current="true"]::after { transform: scaleX(1); transform-origin: left center; }
.nav-links a[aria-current="true"] { opacity: 1; color: var(--luxury-bronze); }

.nav-cta .btn { padding: 12px 28px; font-size: 12px; }

.site-header .nav-cta .btn { background: var(--white); color: var(--primary-dark); }
.site-header .nav-cta .btn:hover, .site-header .nav-cta .btn:focus-visible { color: var(--white); }
.site-header.scrolled .nav-cta .btn { background: var(--primary-dark); color: var(--white); }

/* Scroll progress rail sits on the header's bottom edge. */
.scroll-progress {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    width: 100%;
    transform: scaleX(0);
    transform-origin: left center;
    background: var(--luxury-bronze);
    opacity: 0;
    transition: opacity var(--dur) var(--ease);
}
.site-header.scrolled .scroll-progress { opacity: 1; }

/* Mobile toggle — hamburger morphs to X */
.mobile-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 7px;
    width: 34px;
    height: 40px;
    z-index: 1001;
    position: relative;
}

.mobile-toggle span {
    display: block;
    width: 100%;
    height: 2px;
    background: currentColor;
    transition: transform var(--dur) var(--ease), opacity var(--dur-fast) var(--ease);
    transform-origin: center;
}

body.menu-open .mobile-toggle { color: var(--white); }
body.menu-open .mobile-toggle span:nth-child(1) { transform: translateY(9px) rotate(45deg); }
body.menu-open .mobile-toggle span:nth-child(2) { opacity: 0; }
body.menu-open .mobile-toggle span:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }

.mobile-menu {
    position: fixed;
    inset: 0 0 0 auto;
    width: 100%;
    height: 100vh;
    height: 100dvh;
    background: var(--primary-dark);
    color: var(--white);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    z-index: 999;
    opacity: 0;
    visibility: hidden;
    transform: translateX(100%);
    transition: transform var(--dur-slow) var(--ease), opacity var(--dur) var(--ease),
                visibility 0s linear var(--dur-slow);
}

.mobile-menu.active {
    opacity: 1;
    visibility: visible;
    transform: translateX(0);
    transition: transform var(--dur-slow) var(--ease), opacity var(--dur) var(--ease),
                visibility 0s linear 0s;
}

.mobile-menu a {
    font-family: var(--serif);
    font-size: clamp(30px, 8vw, 42px);
    margin: 10px 0;
    opacity: 0;
    transform: translateY(24px);
}

/* Links stagger in behind the panel. */
.mobile-menu.active a {
    animation: menuItemIn 0.55s var(--ease) forwards;
}
.mobile-menu.active a:nth-child(1) { animation-delay: 0.12s; }
.mobile-menu.active a:nth-child(2) { animation-delay: 0.17s; }
.mobile-menu.active a:nth-child(3) { animation-delay: 0.22s; }
.mobile-menu.active a:nth-child(4) { animation-delay: 0.27s; }
.mobile-menu.active a:nth-child(5) { animation-delay: 0.32s; }
.mobile-menu.active a:nth-child(6) { animation-delay: 0.37s; }
.mobile-menu.active a:nth-child(7) { animation-delay: 0.42s; }

@keyframes menuItemIn {
    to { opacity: 1; transform: translateY(0); }
}

.mobile-menu a:hover { color: var(--luxury-bronze); }

.mobile-menu .menu-contact {
    margin-top: 40px;
    font-size: 14px;
    opacity: 0.6;
    letter-spacing: 0.05em;
    text-align: center;
    padding: 0 24px;
}

/* ============================================================
   2. HERO
   ============================================================ */
/* min-height, not height: on a short or zoomed viewport the hero grows
   with its copy instead of clipping it. The top padding reserves the
   fixed header's band, so the eyebrow can never ride up under the
   LAVOYA logo — which is exactly what it used to do. */
/* Sized to its content plus a margin, not to the whole viewport. At
   100dvh the four blocks inside sat in the middle of a 900px box with
   ~160px of dead air above the eyebrow and ~115px below the buttons,
   and the fold landed below the first section rather than teasing it.
   min-height keeps it generous on tall screens; the content plus
   padding sets the floor, so nothing can be squeezed or overlap. */
.hero {
    min-height: min(82vh, 720px);
    min-height: min(82dvh, 720px);
    position: relative;
    display: flex;
    align-items: center;
    padding-top: calc(var(--nav-h) + var(--space-8));
    padding-bottom: var(--space-16);
    color: var(--white);
    overflow: hidden;
    isolation: isolate;
}

/* z-index 0 (not -1) keeps the layer inside the hero's own stacking
   context — a negative index can slip behind the page background. */
.hero-bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    background: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.42)),
                url('https://images.unsplash.com/photo-1519225421980-715cb0215aed?auto=format&fit=crop&q=80&w=2070') center/cover no-repeat;
    transform: scale(1.05);
    animation: slowZoom 24s infinite alternate ease-in-out;
}

@keyframes slowZoom {
    from { transform: scale(1.05); }
    to { transform: scale(1.15); }
}

/* width:100% matters: as a flex item the container would otherwise
   shrink-to-fit and centre itself, pushing the headline off the
   gutter that the logo and every section below align to. */
.hero > .container { position: relative; z-index: 2; width: 100%; }

/* No extra padding — the hero headline aligns to the same gutter
   as the logo and every section below it. */
.hero-content { max-width: 900px; }

.js .hero-content > * {
    opacity: 0;
    transform: translateY(30px);
    animation: heroIn 1s var(--ease) forwards;
}
.js .hero-content > *:nth-child(2) { animation-delay: 0.15s; }
.js .hero-content > *:nth-child(3) { animation-delay: 0.3s; }
.js .hero-content > *:nth-child(4) { animation-delay: 0.45s; }

@keyframes heroIn {
    to { opacity: 1; transform: translateY(0); }
}

.hero-eyebrow {
    text-transform: uppercase;
    letter-spacing: 0.28em;
    font-size: 13px;
    margin-bottom: var(--space-4);
    display: block;
}

/* 76px over a 16ch measure broke this headline across four lines and
   left it shouting over its own photograph. At 4.4vw it settles at
   ~60px on a desktop, and the wider measure lets it read in three —
   still the largest thing on the page, no longer the only thing.
   The tightened line-height is what a display serif wants at this
   size; 1.16 is the same ratio the section headings use. */
.hero h1 {
    font-size: clamp(32px, 4.4vw, 60px);
    line-height: 1.16;
    max-width: 20ch;
    margin-bottom: var(--space-5);
}

.hero p {
    font-size: 18px;
    line-height: 1.6;
    max-width: 56ch;
    margin-bottom: var(--space-8);
    font-weight: 300;
    opacity: 0.92;
}

.hero-btns { display: flex; gap: var(--space-4); flex-wrap: wrap; }

.hero .btn-outline { border-color: var(--white); color: var(--white); }
.hero .btn-outline::before { background: var(--white); }
.hero .btn-outline:hover, .hero .btn-outline:focus-visible { color: var(--primary-dark); }
.hero .btn:hover, .hero .btn:focus-visible { box-shadow: 0 12px 28px rgba(0,0,0,0.35); }

/* ============================================================
   3. BRAND INTRODUCTION
   ============================================================ */
/* Equal columns and a fixed image-block height, so the copy column
   and the picture column share one centre line and one baseline —
   the text no longer floats above a picture that runs past it. */
.intro-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--split-gap);
    align-items: center;
}

.intro-text { align-self: center; }
.intro-text h2 { font-size: clamp(30px, 3.9vw, 52px); margin-bottom: var(--space-5); }

.intro-text p {
    font-size: 18px;
    color: var(--ink-soft);
    margin-bottom: var(--space-8);
    max-width: 520px;
}

.text-link {
    display: inline-block;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-size: 13px;
    border-bottom: 1px solid var(--primary-dark);
    padding-bottom: 5px;
}
.text-link:hover { color: var(--luxury-bronze); border-color: var(--luxury-bronze); }

/* The whole composition is boxed to one height, so nothing spills
   past the section any more — the 50px hack that used to push the
   stats strip down is gone with it. */
.intro-images {
    position: relative;
    height: 560px;
}

.img-large {
    position: absolute;
    inset: 0 0 0 22%;
    border-radius: var(--card-radius);
}
.img-large img, .img-small img { width: 100%; height: 100%; }

.img-small {
    position: absolute;
    left: 0;
    bottom: 48px;
    width: 52%;
    height: 300px;
    border: 12px solid var(--warm-ivory);
    border-radius: var(--card-radius);
}

/* ============================================================
   4. STATS
   ============================================================ */
.stats-strip {
    background: var(--soft-beige);
    padding: var(--block-y) 0;
    border-top: 1px solid rgba(0,0,0,0.05);
}

.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    text-align: center;
    gap: 30px;
}

.stat-item h3 {
    font-size: 56px;
    color: var(--luxury-bronze);
    /* Tabular figures stop the number jittering as it counts up. */
    font-variant-numeric: tabular-nums;
}

.stat-item p {
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-size: 12px;
    margin-top: 5px;
}

/* ============================================================
   5. SERVICES / OCCASIONS
   ============================================================ */
/* One header treatment for every section on the page — same gap under
   the heading, same gap under the block. Sections used to run 80 / 60 /
   50 here, which is what made the page feel unevenly spaced. */
.services-header { text-align: center; margin-bottom: var(--header-gap); }
.services-header h2 { font-size: clamp(28px, 3.6vw, 48px); margin-bottom: var(--space-5); }
.services-header p { max-width: 700px; margin: 0 auto; color: var(--ink-soft); }

.services-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-5);
}

.service-card {
    position: relative;
    display: block;
    height: 600px;
    overflow: hidden;
    color: var(--white);
    background: var(--soft-beige);
}

.service-card img {
    width: 100%;
    height: 100%;
}

.service-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    z-index: 2;
    width: 100%;
    padding: 40px;
    background: linear-gradient(transparent, rgba(0,0,0,0.85));
    color: var(--white);
    transform: translateY(40px);
    transition: transform var(--dur-slow) var(--ease);
}

.service-overlay h3 { font-size: 30px; margin-bottom: 8px; }
.service-overlay p {
    font-size: 14px;
    opacity: 0;
    transition: opacity var(--dur-slow) var(--ease);
}

.service-card:hover img,
.service-card:focus-visible img { transform: scale(1.08); }
.service-card:hover .service-overlay,
.service-card:focus-visible .service-overlay { transform: translateY(0); }
.service-card:hover .service-overlay p,
.service-card:focus-visible .service-overlay p { opacity: 0.9; }

/* Touch devices have no hover — keep the copy visible. */
@media (hover: none) {
    .service-overlay { transform: translateY(0); }
    .service-overlay p { opacity: 0.9; }
}

/* ============================================================
   6. CUISINE (dark section)
   ============================================================ */
.cuisine-section {
    background: var(--primary-dark);
    color: var(--white);
    padding: var(--section-y) 0;
}

.cuisine-header { margin-bottom: var(--header-gap); }
.cuisine-header h2 { font-size: clamp(28px, 3.6vw, 48px); margin-bottom: var(--space-5); }
.cuisine-header p { opacity: 0.7; max-width: 560px; }

/* The tablist sits in its own control bar row, centred under the
   section heading. */
.cuisine-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--header-gap);
    border-bottom: 1px solid rgba(255,255,255,0.1);
    padding-bottom: var(--space-8);
}

.cuisine-nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

/* Sizing only — the pill class supplies the border, fill and states. */
.cuisine-btn { font-size: 13px; padding: 13px 26px; }

.cuisine-display {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--split-gap);
    align-items: center;
    transition: opacity var(--dur) var(--ease-soft);
}
.cuisine-display.is-swapping { opacity: 0; }

/* The info column is now the taller of the two, and it varies by
   cuisine — so the photo tracks the row height rather than fixing it. */
.cuisine-img { position: relative; min-height: 500px; width: 100%; align-self: stretch; display: grid; }
.cuisine-img img { width: 100%; height: 100%; grid-area: 1 / 1; }

/* Prev / next sit on the left and right edges of the photo, which is
   what tells you the picture slides. The tablist above stays the
   primary control; these are a second route to the same five panels. */
.cuisine-arrow {
    position: absolute;
    top: 50%;
    z-index: 3;
    width: 52px;
    height: 52px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    color: var(--white);
    background: rgba(25,23,20,0.68);
    border: 1px solid rgba(255,255,255,0.55);
    backdrop-filter: blur(6px);
    transform: translateY(-50%);
    transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease),
                color var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.cuisine-arrow svg { width: 15px; height: 15px; fill: currentColor; }
.cuisine-arrow-prev { left: var(--space-4); }
.cuisine-arrow-next { right: var(--space-4); }

.cuisine-arrow:hover,
.cuisine-arrow:focus-visible {
    background: var(--luxury-bronze);
    border-color: var(--luxury-bronze);
    color: var(--white);
}
.cuisine-arrow:active { background: var(--bronze-deep); border-color: var(--bronze-deep); }

/* The photo darkens slightly at both edges so the two white glyphs
   never land on a pale dish and disappear. ::before, not ::after —
   .media already owns ::after for the loading shimmer. */
.cuisine-img::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(90deg, rgba(0,0,0,0.32), rgba(0,0,0,0) 24%,
                                       rgba(0,0,0,0) 76%, rgba(0,0,0,0.32));
}

.cuisine-info { align-self: center; }
.cuisine-info h3 { font-size: clamp(26px, 2.8vw, 38px); margin-bottom: 18px; color: var(--luxury-bronze); }
.cuisine-info p { font-size: 17px; opacity: 0.8; max-width: 520px; }

/* Four highlights per cuisine. A hairline rule replaces the bullet —
   the list has to sit beside a 500px photo without shouting. */
.cuisine-points {
    margin-top: 34px;
    max-width: 520px;
    display: grid;
    gap: 22px;
}

.cuisine-points li {
    position: relative;
    padding-left: 34px;
}

.cuisine-points li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 9px;
    width: 20px;
    height: 1px;
    background: var(--luxury-bronze);
}

.point-name {
    display: block;
    font-size: 12px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    font-weight: 500;
    color: var(--luxury-bronze);
    margin-bottom: 7px;
}

.point-desc {
    display: block;
    font-size: 15px;
    line-height: 1.65;
    opacity: 0.72;
}

/* ============================================================
   7. LIVE EXPERIENCES (horizontal carousel)
   ============================================================ */
/* --live-media-h keeps the side arrows centred on the photo row rather
   than on the whole card, which includes the caption below it. */
.live-carousel { position: relative; --live-media-h: 300px; }

.live-scroll-container {
    display: flex;
    gap: var(--space-10);
    overflow-x: auto;
    padding: var(--space-10) 4px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scroll-padding-left: 4px;
    cursor: grab;
}

.live-scroll-container::-webkit-scrollbar { display: none; }
.live-scroll-container.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.live-scroll-container.is-dragging * { pointer-events: none; }

/* A definite width, not a minimum. With `flex: 0 0 auto` and only a
   min-width, each card sized to its own paragraph — they came out
   ~566px wide, which on a phone made every card wider than the screen
   and left the snap points landing mid-card. */
.live-item {
    flex: 0 0 auto;
    width: min(400px, 78vw);
    scroll-snap-align: start;
}
.live-item .media { height: var(--live-media-h); margin-bottom: var(--space-5); }
.live-item img { height: 100%; width: 100%; }
.live-item h3 { font-size: 28px; margin-bottom: var(--space-2); }
.live-item p { color: var(--ink-soft); font-size: 15px; }

/* Arrows flank the track on the left and right, level with the middle
   of the photos, so the direction of travel is unmistakable. They sit
   just inside the edge rather than centred underneath, where they read
   as page furniture instead of as a control on this row. */
.carousel-controls { display: contents; }

.carousel-btn {
    position: absolute;
    z-index: 4;
    top: calc(var(--space-10) + var(--live-media-h) / 2);
    transform: translateY(-50%);
    width: 52px;
    height: 52px;
    border: 1px solid var(--primary-dark);
    border-radius: 50%;
    background: var(--white);
    color: var(--primary-dark);
    display: grid;
    place-items: center;
    box-shadow: 0 6px 18px rgba(25,23,20,0.16);
    transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
                border-color var(--dur) var(--ease), opacity var(--dur) var(--ease),
                transform var(--dur-fast) var(--ease-soft), box-shadow var(--dur) var(--ease);
}
.carousel-btn svg { width: 16px; height: 16px; fill: currentColor; }

.carousel-btn-prev { left: calc(var(--space-5) * -1); }
.carousel-btn-next { right: calc(var(--space-5) * -1); }

.carousel-btn:hover:not(:disabled) {
    background: var(--luxury-bronze);
    color: var(--white);
    border-color: var(--luxury-bronze);
    transform: translateY(-50%) scale(1.06);
    box-shadow: 0 12px 26px rgba(25,23,20,0.24);
}
.carousel-btn:active:not(:disabled) { transform: translateY(-50%) scale(1); }
.carousel-btn:disabled { opacity: 0.28; cursor: not-allowed; box-shadow: none; }

/* Hint and Pause sit on one line under the track, centred as a pair. */
.live-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-5);
    margin-top: var(--space-4);
}

.scroll-hint {
    text-align: center;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    opacity: 0.4;
    margin: 0;
}


/* ============================================================
   8. FEATURED WEDDING
   ============================================================ */
.featured-wedding {
    background: var(--soft-beige);
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    align-items: center;
}

.featured-info { padding: var(--space-24) var(--split-gap); }
.featured-info h2 { font-size: clamp(34px, 4vw, 56px); margin-bottom: var(--space-8); }
.featured-info > p { margin-bottom: var(--space-10); opacity: 0.8; }

.featured-meta {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-8);
    margin-bottom: var(--space-10);
}

.meta-item span { font-size: 12px; text-transform: uppercase; opacity: 0.6; display: block; letter-spacing: 0.08em; }
.meta-item p { font-size: 18px; font-weight: 500; }

.featured-images {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 300px 300px;
    gap: 15px;
    padding: 40px;
}

.featured-images .media { height: 100%; }
.featured-images img { width: 100%; height: 100%; }
.f-img-1 { grid-row: span 2; }

/* ============================================================
   9. PROCESS STEPS — interactive cards
   Each card is an accordion: header button, always-visible summary,
   and a panel that expands. Hover, focus and the open state all
   read differently, so the row is never a flat block of text.
   ============================================================ */
/* stretch, not start: all four cards take the height of the tallest,
   so opening one no longer leaves a ragged row of three short cards
   beside one long one. The row resizes as a unit when the open card
   changes, which reads as the panel driving the grid. */
.steps-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-6);
    align-items: stretch;
}

.step-item {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: var(--space-7) var(--space-6) var(--space-6);
    background: var(--white);
    border: 1px solid rgba(25,23,20,0.09);
    border-radius: var(--card-radius);
    overflow: hidden;
    transition: transform var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease),
                border-color var(--dur) var(--ease);
}

/* A hairline across the card top draws in as the step scrolls into
   view. One pixel, matching the bronze rules used beside the cuisine
   highlights — a heavier bar reads as a status stripe, which is not
   what this is. */
.step-item::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 1px;
    background: var(--luxury-bronze);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 1s var(--ease), background-color var(--dur) var(--ease);
}
.reveal.active .step-item::before { transform: scaleX(1); }
.steps-grid .step-item:nth-child(2)::before { transition-delay: 0.12s; }
.steps-grid .step-item:nth-child(3)::before { transition-delay: 0.24s; }
.steps-grid .step-item:nth-child(4)::before { transition-delay: 0.36s; }

.step-item:hover,
.step-item:focus-within {
    transform: translateY(-6px);
    border-color: rgba(154,117,83,0.45);
    box-shadow: 0 18px 40px rgba(25,23,20,0.12);
}

.step-head {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    margin: 0 0 var(--space-4);
    text-align: left;
}

.step-num {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: 1px solid rgba(154,117,83,0.5);
    font-family: var(--serif);
    font-size: 20px;
    line-height: 1;
    color: var(--luxury-bronze);
    background: rgba(154,117,83,0.06);
    transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
                border-color var(--dur) var(--ease), transform var(--dur) var(--ease-soft);
}

.step-item:hover .step-num {
    background: var(--luxury-bronze);
    border-color: var(--luxury-bronze);
    color: var(--white);
    transform: scale(1.06);
}

.step-label {
    font-family: var(--serif);
    font-size: 24px;
    line-height: 1.2;
    flex: 1 1 auto;
    transition: color var(--dur) var(--ease);
}
.step-item:hover .step-label { color: var(--luxury-bronze); }

.step-summary { color: var(--ink-soft); font-size: 15px; margin-bottom: var(--space-4); }

/* The detail is always on the page — see the note in index.html. It is
   pushed to the bottom of the card (margin-top: auto) so the four cards
   share one baseline for this block however the summary above it wraps,
   which is what makes the row read as four equal cards rather than four
   boxes of the same height with the text floating at different points. */
.step-detail {
    margin-top: auto;
    padding-top: var(--space-3);
    border-top: 1px solid rgba(25,23,20,0.08);
}

.step-detail > p {
    font-size: 14.5px;
    color: var(--ink-soft);
}

/* ============================================================
   10. GALLERY
   ============================================================ */
.gallery-filters {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 14px;
    margin-bottom: 50px;
}

/* The pill class supplies the border, fill and states. */
.filter-btn { padding: 13px 26px; }

.gallery-grid {
    columns: 3 300px;
    column-gap: 20px;
}

.gallery-item {
    break-inside: avoid;
    margin-bottom: 20px;
    display: block;
    width: 100%;
    padding: 0;
    overflow: hidden;
    position: relative;
    background: var(--soft-beige);
    transition: opacity var(--dur) var(--ease-soft), transform var(--dur) var(--ease-soft);
}

/* Two-step hide keeps the reflow from snapping. */
.gallery-item.is-hiding { opacity: 0; transform: scale(0.96); }
.gallery-item.hidden { display: none; }

/* height:auto preserves each photo's own aspect ratio in the
   masonry columns, while the width/height attrs reserve the box. */
.gallery-item img { width: 100%; height: auto; transition: transform var(--dur-slow) var(--ease); }
.gallery-item:hover img { transform: scale(1.05); }

.js .gallery-item img {
    opacity: 0;
    transition: opacity var(--dur-slow) var(--ease-soft), transform var(--dur-slow) var(--ease);
}
.js .gallery-item img.is-loaded { opacity: 1; }

.gallery-item::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(25,23,20,0.28);
    opacity: 0;
    transition: opacity var(--dur) var(--ease);
    pointer-events: none;
}
.gallery-item:hover::after,
.gallery-item:focus-visible::after { opacity: 1; }

.gallery-zoom {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 48px;
    height: 48px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: rgba(255,255,255,0.92);
    color: var(--primary-dark);
    opacity: 0;
    transform: scale(0.8);
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
    pointer-events: none;
    z-index: 2;
}
.gallery-zoom svg { width: 18px; height: 18px; fill: currentColor; }
.gallery-item:hover .gallery-zoom,
.gallery-item:focus-visible .gallery-zoom { opacity: 1; transform: scale(1); }

.gallery-empty {
    text-align: center;
    padding: 40px 0;
    color: var(--ink-soft);
}

/* ------------------------------------------------------------
   Lightbox
   ------------------------------------------------------------ */
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 1200;
    background: rgba(15,13,11,0.94);
    display: grid;
    place-items: center;
    padding: 40px;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur) var(--ease-soft), visibility 0s linear var(--dur);
}

.lightbox.active {
    opacity: 1;
    visibility: visible;
    transition: opacity var(--dur) var(--ease-soft), visibility 0s linear 0s;
}

.lightbox-figure {
    margin: 0;
    max-width: min(1100px, 100%);
    max-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
}

.lightbox-img {
    max-width: 100%;
    max-height: calc(100vh - 180px);
    width: auto;
    height: auto;
    object-fit: contain;
    opacity: 0;
    transform: scale(0.97);
    transition: opacity var(--dur) var(--ease-soft), transform var(--dur) var(--ease);
}
.lightbox.is-ready .lightbox-img { opacity: 1; transform: scale(1); }

.lightbox-caption {
    color: rgba(255,255,255,0.75);
    font-size: 14px;
    text-align: center;
    letter-spacing: 0.04em;
}

.lightbox-close,
.lightbox-nav {
    position: absolute;
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    color: var(--white);
    background: rgba(255,255,255,0.1);
    transition: background-color var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.lightbox-close:hover, .lightbox-nav:hover { background: rgba(255,255,255,0.24); }
.lightbox-close svg, .lightbox-nav svg { width: 18px; height: 18px; fill: currentColor; }

.lightbox-close { top: 24px; right: 24px; }
.lightbox-prev { left: 24px; top: 50%; transform: translateY(-50%); }
.lightbox-next { right: 24px; top: 50%; transform: translateY(-50%); }

/* ============================================================
   11. TESTIMONIALS — card grid
   Every quote is on the page at once. No carousel, no timer, and
   nothing that moves out from under a reader mid-sentence.
   ============================================================ */
.testimonial-section {
    background: var(--white);
    padding: var(--section-y) 0;
}

.testimonial-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 28px;
    align-items: stretch;
}

.testimonial-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 44px 34px 34px;
    background: var(--warm-ivory);
    border: 1px solid rgba(25,23,20,0.08);
    border-radius: var(--card-radius);
    overflow: hidden;
    transition: transform var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease),
                border-color var(--dur) var(--ease);
}

/* Hairline, to match the step cards and the cuisine highlight rules —
   the same bronze accent at the same weight everywhere it appears. */
.testimonial-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 1px;
    background: var(--luxury-bronze);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--dur-slow) var(--ease);
}

.testimonial-card:hover,
.testimonial-card:focus-within {
    transform: translateY(-6px);
    border-color: rgba(154,117,83,0.45);
    box-shadow: 0 20px 44px rgba(25,23,20,0.12);
}
.testimonial-card:hover::before,
.testimonial-card:focus-within::before { transform: scaleX(1); }

.quote-mark {
    position: absolute;
    top: 6px;
    right: 22px;
    font-family: var(--serif);
    font-size: 120px;
    line-height: 1;
    color: var(--luxury-bronze);
    opacity: 0.14;
    pointer-events: none;
}

/* Off-screen sprite that holds the star symbol. */
.svg-sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.testimonial-rating {
    display: flex;
    gap: 5px;
    margin-bottom: 18px;
}
.testimonial-rating svg {
    width: 17px;
    height: 17px;
    fill: var(--luxury-bronze);
}

.testimonial-text {
    font-family: var(--serif);
    font-size: 21px;
    line-height: 1.5;
    font-style: italic;
    /* Pushes the attribution to the bottom, so the three cards line
       their names up regardless of quote length. */
    flex: 1 1 auto;
    margin-bottom: 28px;
}

.testimonial-meta {
    display: flex;
    align-items: center;
    gap: 14px;
    padding-top: 22px;
    border-top: 1px solid rgba(25,23,20,0.1);
}

.testimonial-avatar {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: var(--luxury-bronze);
    color: var(--white);
    font-size: 14px;
    letter-spacing: 0.06em;
    font-weight: 500;
}

.testimonial-person { display: flex; flex-direction: column; gap: 3px; }

.testimonial-author {
    font-family: var(--serif);
    font-size: 20px;
    line-height: 1.2;
    color: var(--primary-dark);
}

.testimonial-role {
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--ink-soft);
}

/* ============================================================
   12. FAQ
   ============================================================ */
.faq-section { max-width: 900px; margin: 0 auto; }

.faq-item { border-bottom: 1px solid rgba(0,0,0,0.1); }

.faq-item summary {
    list-style: none;
    cursor: pointer;
    padding: 28px 48px 28px 0;
    font-family: var(--serif);
    font-size: 24px;
    position: relative;
    transition: color var(--dur) var(--ease);
}

.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--luxury-bronze); }

.faq-item summary::after {
    content: '+';
    position: absolute;
    right: 5px;
    top: 50%;
    transform: translateY(-50%);
    font-family: var(--sans);
    font-size: 24px;
    font-weight: 300;
    color: var(--luxury-bronze);
    transition: transform var(--dur) var(--ease);
}

.faq-item[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.faq-item[open] summary { color: var(--luxury-bronze); }

/* Answer slides open instead of popping. */
.faq-answer {
    overflow: hidden;
    display: grid;
    grid-template-rows: 1fr;
}

.faq-item p {
    padding: 0 40px 28px 0;
    color: var(--ink-soft);
    max-width: 760px;
}

.faq-item[open] .faq-answer { animation: faqOpen var(--dur) var(--ease-soft); }

@keyframes faqOpen {
    from { opacity: 0; transform: translateY(-8px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ============================================================
   13. CTA
   ============================================================ */
.cta-box {
    background: linear-gradient(rgba(0,0,0,0.7), rgba(0,0,0,0.7)),
                url('https://images.unsplash.com/photo-1511795409834-ef04bbd61622?auto=format&fit=crop&q=80&w=2069') center/cover;
    background-color: var(--primary-dark);
    padding: var(--section-y) var(--gutter);
    text-align: center;
    color: var(--white);
}

.cta-box .label { color: var(--white); }
.cta-box h2 { font-size: clamp(36px, 5.5vw, 72px); margin-bottom: 30px; max-width: 1000px; margin-inline: auto; }
.cta-box .btn-light:hover, .cta-box .btn-light:focus-visible { color: var(--white); }

/* ============================================================
   14. ENQUIRY FORM
   ============================================================ */
.enquiry-container {
    display: grid;
    grid-template-columns: 1fr 1.5fr;
    gap: var(--split-gap);
}

.enquiry-intro h2 { font-size: clamp(32px, 4vw, 52px); }
.enquiry-intro > p { margin-top: var(--space-5); opacity: 0.7; }

.enquiry-contact { margin-top: var(--space-10); }
.enquiry-contact p { margin-bottom: var(--space-2); }
.enquiry-contact a { border-bottom: 1px solid transparent; }
.enquiry-contact a:hover { color: var(--luxury-bronze); border-color: var(--luxury-bronze); }

.form-note { font-size: 13px; opacity: 0.55; margin-top: var(--space-6); }

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-8);
}

.form-group { margin-bottom: var(--space-8); position: relative; }

.form-group label {
    display: block;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 10px;
    opacity: 0.6;
    transition: opacity var(--dur) var(--ease), color var(--dur) var(--ease);
}

.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 15px 0;
    background: transparent;
    border: none;
    border-bottom: 1px solid rgba(0,0,0,0.15);
    font-family: inherit;
    font-size: 16px;
    color: var(--primary-dark);
    outline: none;
    border-radius: 0;
    transition: border-color var(--dur) var(--ease);
}

.form-group textarea { resize: vertical; min-height: 96px; }

/* Bronze underline sweeps in from the left on focus. */
.form-group::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 1px;
    background: var(--luxury-bronze);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--dur) var(--ease);
    pointer-events: none;
}
.form-group:focus-within::after { transform: scaleX(1); }
.form-group:focus-within label { opacity: 1; color: var(--luxury-bronze); }

.form-group select { cursor: pointer; }
.form-group select:invalid { color: rgba(25,23,20,0.42); }

/* Inline validation */
.field-error {
    display: block;
    font-size: 12.5px;
    color: #A33A3A;
    margin-top: 8px;
    min-height: 0;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.form-group.has-error input,
.form-group.has-error select,
.form-group.has-error textarea { border-bottom-color: #A33A3A; }
.form-group.has-error .field-error { opacity: 1; transform: translateY(0); }
.form-group.has-error label { color: #A33A3A; opacity: 1; }
.form-group.has-error::after { background: #A33A3A; }

.form-status {
    margin-top: 20px;
    font-size: 15px;
    display: none;
    padding: 16px 20px;
    border-left: 2px solid currentColor;
    background: rgba(0,0,0,0.02);
}
.form-status.success { display: block; color: #3E6B3E; }
.form-status.error { display: block; color: #A33A3A; }

.form-fallback {
    display: none;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 18px;
}
.form-fallback.active { display: flex; }
.form-fallback .btn { padding: 13px 26px; font-size: 12px; }

.honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* ============================================================
   FOOTER
   ============================================================ */
/* --section-y on top so the join above the footer matches every other
   section join on the page; a shorter tail below, because the colophon
   is the last thing and needs no run-out. */
footer {
    background: var(--primary-dark);
    color: var(--white);
    padding: var(--section-y) 0 var(--space-10);
}

.footer-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: 60px;
    margin-bottom: 80px;
}

.footer-logo { --logo-size: 34px; margin-bottom: 24px; }
.footer-tagline { opacity: 0.6; max-width: 320px; }

.footer-col h3 { font-size: 18px; margin-bottom: 25px; color: var(--luxury-bronze); }
.footer-col ul li { margin-bottom: 12px; opacity: 0.7; font-size: 14px; }
.footer-col ul li a:hover { color: var(--luxury-bronze); opacity: 1; }

.footer-bottom {
    padding-top: 40px;
    padding-bottom: 24px;
    border-top: 1px solid rgba(255,255,255,0.08);
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    font-size: 12px;
    opacity: 0.5;
}

/* The WhatsApp bubble and back-to-top button are fixed to the
   bottom-right corner, so at the very end of the page they land on this
   row. Reserve their column rather than let them sit on the colophon. */
.footer-bottom > :last-child { padding-right: 76px; }

/* ============================================================
   FLOATING ACTIONS
   ============================================================ */
.whatsapp-float {
    position: fixed;
    bottom: 28px;
    right: 28px;
    width: 58px;
    height: 58px;
    background: #25D366;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 998;
    box-shadow: 0 8px 24px rgba(0,0,0,0.25);
    transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.whatsapp-float:hover { transform: translateY(-4px) scale(1.05); box-shadow: 0 12px 30px rgba(0,0,0,0.3); }
.whatsapp-float svg { width: 30px; height: 30px; fill: var(--white); }

.to-top {
    position: fixed;
    bottom: 98px;
    right: 28px;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: var(--primary-dark);
    color: var(--white);
    display: grid;
    place-items: center;
    z-index: 998;
    opacity: 0;
    visibility: hidden;
    transform: translateY(12px);
    box-shadow: 0 6px 18px rgba(0,0,0,0.2);
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
                visibility 0s linear var(--dur), background-color var(--dur) var(--ease);
}
.to-top.visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
                visibility 0s linear 0s, background-color var(--dur) var(--ease);
}
.to-top:hover { background: var(--luxury-bronze); }
.to-top svg { width: 15px; height: 15px; fill: currentColor; }

/* ============================================================
   SCROLL REVEAL
   Only applied when JS is running — see the .js class set in
   the document head. Without JS every section stays visible.
   ============================================================ */
.js .reveal {
    opacity: 0;
    transform: translateY(40px);
    transition: opacity 1s var(--ease-soft), transform 1s var(--ease);
}

.js .reveal.active { opacity: 1; transform: translateY(0); }

/* Staggered children inside a revealed block.
   `translate` rather than `transform`, so a card can still use its own
   transform for the hover lift without the two rules fighting. */
.js .reveal .stagger > * {
    opacity: 0;
    translate: 0 24px;
    transition: opacity 0.8s var(--ease-soft), translate 0.8s var(--ease);
}
.js .reveal.active .stagger > * { opacity: 1; translate: 0 0; }

/* Cards inside a stagger need their hover transitions back — the
   shorthand above would otherwise replace them and the lift would
   snap instead of easing. */
.js .reveal .stagger > .step-item,
.js .reveal .stagger > .testimonial-card {
    transition: opacity 0.8s var(--ease-soft), translate 0.8s var(--ease),
                transform var(--dur) var(--ease-soft), box-shadow var(--dur) var(--ease),
                border-color var(--dur) var(--ease);
}

.js .reveal.active .stagger > *:nth-child(2) { transition-delay: 0.08s; }
.js .reveal.active .stagger > *:nth-child(3) { transition-delay: 0.16s; }
.js .reveal.active .stagger > *:nth-child(4) { transition-delay: 0.24s; }

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

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

    .js .reveal,
    .js .reveal .stagger > *,
    .js .hero-content > *,
    .mobile-menu a { opacity: 1; transform: none; translate: none; }

    .js .media img,
    .js .gallery-item img { opacity: 1; }
    .js .media::after { content: none; }
    .hero-bg { animation: none; transform: scale(1.05); }
    .live-scroll-container { scroll-snap-type: none; }
    .reveal.active .step-item::before { transform: scaleX(1); }
    .step-item:hover, .step-item:focus-within { transform: none; }
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1024px) {
    /* One gutter value drives the nav and every section, so the two
       never drift apart at this breakpoint. */
    :root {
        --nav-h: 84px;
        --nav-h-scrolled: 64px;
        --gutter: 30px;
        --section-y: 100px;
        --block-y: 64px;
    }

    .nav-links, .nav-cta { display: none; }
    .mobile-toggle { display: flex; }

    .intro-grid, .cuisine-display, .featured-wedding, .enquiry-container {
        grid-template-columns: 1fr;
    }
    /* One step down the scale for the two-column gaps, so the columns
       stay related to each other as the page narrows. */
    :root { --split-gap: var(--space-14); --header-gap: var(--space-14); }

    .intro-images { height: 480px; }
    .services-grid { grid-template-columns: 1fr 1fr; }
    .service-card { height: 480px; }
    .steps-grid { grid-template-columns: 1fr 1fr; gap: var(--space-5); }
    .testimonial-card { padding: 34px 26px 28px; }
    .testimonial-text { font-size: 18px; margin-bottom: var(--space-6); }
    .quote-mark { font-size: 92px; right: 16px; }
    .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--space-10); }
    .featured-info { padding: var(--space-20) var(--space-10); }
    .lightbox { padding: 24px; }
    .lightbox-prev { left: 10px; }
    .lightbox-next { right: 10px; }
    .lightbox-close { top: 14px; right: 14px; }
}

@media (max-width: 768px) {
    :root {
        --gutter: 24px;
        --section-y: 80px;
        --block-y: 56px;
        --split-gap: var(--space-10);
        --header-gap: var(--space-12);
    }

    /* A phone screen is tall and narrow, so the same content needs more
       of it — but not all of it, or the first section never hints at
       itself above the fold. */
    .hero {
        min-height: min(82dvh, 660px);
        padding-top: calc(var(--nav-h) + var(--space-6));
        padding-bottom: var(--space-14);
    }
    .hero-eyebrow { font-size: 12px; letter-spacing: 0.24em; }
    .hero h1 { max-width: 18ch; }
    .hero p { font-size: 16px; margin-bottom: var(--space-7); }
    .hero-btns .btn { flex: 1 1 auto; text-align: center; }
    .services-grid, .steps-grid, .stats-grid, .testimonial-grid { grid-template-columns: 1fr; }
    /* Matching heights only earn their keep when cards sit side by side.
       Stacked one per column, a stretched card is just a tall empty box
       with nothing to line up against. */
    .steps-grid { align-items: start; }
    .stats-grid { gap: var(--space-10); }
    .testimonial-grid { gap: var(--space-5); }
    .featured-info { padding: var(--space-12) var(--space-6); }
    .featured-images { padding: 24px; grid-template-rows: 200px 200px; }
    .cuisine-controls { padding-bottom: var(--space-6); }
    .cuisine-nav { gap: var(--space-2); }
    .cuisine-btn { padding: 13px 20px; font-size: 12px; }
    .cuisine-img { min-height: 0; height: 340px; }
    .cuisine-arrow { width: 44px; height: 44px; }
    .cuisine-arrow-prev { left: var(--space-2); }
    .cuisine-arrow-next { right: var(--space-2); }
    .cuisine-points { margin-top: var(--space-7); gap: var(--space-5); }
    .gallery-grid { columns: 2 150px; column-gap: 14px; }
    .gallery-item { margin-bottom: 14px; }
    .gallery-filters { gap: 10px; }
    .filter-btn { padding: 13px 20px; font-size: 12px; }
    .live-carousel { --live-media-h: 220px; }
    /* One card fills the track with the next one peeking in, so it is
       obvious there is more to swipe to. */
    .live-item { width: min(320px, 82vw); }
    .live-scroll-container { gap: var(--space-6); }
    /* Inside the track at this width — the page gutter is too narrow to
       hang a 46px control off the edge of it. */
    .carousel-btn { width: 46px; height: 46px; }
    .carousel-btn-prev { left: var(--space-1); }
    .carousel-btn-next { right: var(--space-1); }
    .intro-images { height: 420px; }
    .img-small { bottom: 24px; height: 220px; width: 55%; border-width: 8px; }
    .form-row { grid-template-columns: 1fr; gap: 0; }
    .faq-item summary { font-size: 20px; }
    footer { padding: var(--section-y) 0 var(--space-8); }
    .footer-grid { margin-bottom: var(--space-12); }
    .whatsapp-float { bottom: 20px; right: 20px; width: 52px; height: 52px; }
    .to-top { bottom: 82px; right: 20px; width: 42px; height: 42px; }
    .lightbox-img { max-height: calc(100vh - 150px); }
}

@media (max-width: 420px) {
    .footer-grid { grid-template-columns: 1fr; }
    /* Colophon stacks here, so the floats need clearing below it
       rather than beside it. */
    .footer-bottom { padding-bottom: 92px; }
    .footer-bottom > :last-child { padding-right: 0; }
    .logo { --logo-size: 24px; }
    .footer-logo { --logo-size: 28px; }
    .live-item { width: min(260px, 84vw); }
    .intro-images { height: 340px; }
    .img-small { height: 170px; bottom: 16px; }
    .step-label { font-size: 21px; }
    .testimonial-card { padding: 30px 22px 24px; }
}
