/* S9/C6: two foundational rules from Bootstrap's reboot.css that the rest
   of this stylesheet was silently relying on — removing Bootstrap's CSS
   without them changed every element's width/height math (content-box vs
   the border-box every measurement below assumes) and added the browser's
   default 8px body margin back in, both of which are exactly the kind of
   layout-affecting change the class-by-class replacement above this
   comment (see "Bootstrap CSS replacement") wouldn't catch, since neither
   is a class. Reproduced here rather than left implicit again. */
*, *::before, *::after { box-sizing: border-box; }

/* Theme */
@font-face {
    /* Licensed The Seasons webfont supplied by Laurence. */
    font-family: 'Seasons';
    src: url('../fonts/theseasons-reg.woff2') format('woff2'),
         url('../fonts/theseasons-reg.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

/* 'Radiata' removed — the site never shipped the font files it pointed to
   (fonts/Radiata-Italic.woff2/.woff), so every use below now reads Lora instead. */

/* Lora is loaded via a real <link rel="stylesheet"> in partials/head-common.njk,
   not @import here — @import forces the browser to fetch and parse this whole
   stylesheet before it can even discover the font request, adding a full
   round-trip the <link> approach (discoverable by the preload scanner,
   fetchable in parallel with everything else in <head>) avoids. Same family,
   weights and display:swap as before — only how it's requested changed. */

.second-font {
    font-family: 'Lora', serif;
    font-style: italic;
    font-size: 22px !important;
    text-align: center;
}

.area-2-title {
    text-align: center;
    font-family: 'Lora', serif;
    font-style: italic;
    font-size: 22px !important;
}


body {
    margin: 0;
    background-color: #fefae7 !important;
}

.logo-title {
    font-family: 'Seasons', serif;
}

.logo-title-with-space {
    font-family: 'Seasons', serif;
    letter-spacing: 10px;
}

.p-text {
    font-family: 'Lora', serif;
    color: #836d63;
    font-size: 20px;
}

.p-text-lable {
    font-family: 'Lora', serif;
    color: #836d63;
    font-size: 16px;
}

.title-gold {
    color: #fab949;
    text-decoration: none;
    font-weight: 400;
    font-size: 30px;
    text-transform: uppercase;
    text-align: center;
}


.bg-img-bw {
    width: 100%;
    height: 50vh;
    object-fit: cover;
}


.hero {
    position: relative;
    width: 100%;
    height: 100vh;
    overflow: hidden;
}

.video-bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 1;
    opacity: 0;
    transition: opacity 0.5s ease;
}

.video-bg.loaded {
    opacity: 1;
}

.overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.3);
    z-index: 2;
}

.content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 3;
    text-align: center;
    width: 100%;
    padding: 20px;
}

.p-text-c {
    color: #fab949;
    text-align: center;
    font-family: 'Lora', serif;
    font-style: italic;
    font-size: 25px !important;
}

.contact-title {
    color: #fab949;
    text-align: center;
    font-family: 'Lora', serif;
    font-weight: 200;
}

.content h1 {
    font-size: 100px;
    color: #ffc107;
    font-weight: 100 !important;
    margin: 0;
}

@media (max-width: 768px) {
    .content h1 {
        font-size: 2rem;
    }
}

@media (max-width: 576px) {
    .content h1 {
        font-size: 1.5rem;
    }

    .second-font {
        font-size: 16px !important;
    }

    .area-2-title {
        font-size: 16px !important;
    }


    .p-text {
        font-size: 16px;
    }

    .p-text-c {
        font-size: 16px !important;
    }

    .content h1 {
        font-size: 50px;
    }

}

.hero::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    /* Replaces the former third-party "Video Loading" placeholder graphic
       — a third-party placeholder unrelated to this site, visible to every
       visitor until the video revealed (or, on failure, indefinitely). Now
       the real hero poster, set as a custom property on .hero itself
       (site/_includes/pages/index.njk) since a static stylesheet can't
       reference the CMS-selected image. */
    background-image: var(--hero-poster-url);
    background-size: cover;
    background-position: center;
    z-index: 0;
    opacity: 1;
    transition: opacity 0.5s ease;
}

.hero.video-loaded::before {
    opacity: 0;
}

.area1-video {
    position: relative;
    width: 100%;
    height: 50vh;
    overflow: hidden;
    background: #000;
    filter: grayscale(100%);
}


.video-width {
    padding: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.video-low-width {
    padding: 0;
    width: 100%;
    height: 60%;
    object-fit: cover;
}

.video-44-width {
    padding: 0% 20%;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.area2 {
    background-color: #ffffff;
    color: #836d63 !important;
}

.area-2-title {
    text-align: center;
    font-family: 'Lora', serif;
    font-style: italic;
    font-size: 22px !important;
}

.area-padding {
    padding: 10% 0px;
}

.area-padding-title {
    padding-top: 15%;
    padding-bottom: 2%;
}

.area-margin {
    margin-bottom: -50px;
}


.container-gap {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    column-gap: 0;
    row-gap: 0;

}

.area2-video-text-span {
    font-weight: 700;
    font-family: 'Lora', serif;
}

.area2-video-text-span-non-bold {
    font-weight: 400;
    font-family: 'Lora', serif;
}

.area2-video-text {
    text-align: center;
    color: #887367;
}

.area2-pb {
    padding-bottom: 10%;
}

.bg-white {
    background-color: #ffffff;
}

.area-pb {
    padding-bottom: 10%;
}

.img-margin {
    margin-top: 25%;
}

.enquiry-form {
    max-width: 600px;
    width: 100%;
}

.enquiry-form h1 {
    text-align: center;
    color: #d19b32;
    margin-bottom: 30px;
    font-weight: normal;
}

form {
    display: flex;
    flex-direction: column;
    gap: 25px;
}

label {
    display: flex;
    flex-direction: column;
    font-size: 1.1rem;
}

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="date"] {
    border: none;
    border-bottom: 2px solid #7b5c3b;
    padding: 6px 0;
    background: transparent;
    font-size: 1rem;
    outline: none;
    width: 100%;
}

button {
    margin-top: 20px;
    background-color: #d19b32;
    color: #fff;
    border: none;
    padding: 12px 20px;
    font-size: 1rem;
    cursor: pointer;
    border-radius: 4px;
    transition: background 0.3s;
}

button:hover {
    background-color: #b88226;
}

/* The enquiry submit button uses aria-disabled (not the disabled property)
   while sending/unconfirmed, specifically so it stays focusable — see
   js/enquiry.js. It carries no Bootstrap .btn class and there was no
   existing :disabled rule here for the browser's native disabled styling to
   have replaced, so this replicates that "busy, not clickable-looking"
   affordance explicitly. The JS re-entry guard, not this, is what actually
   blocks a second submit. */
button[aria-disabled="true"] {
    opacity: 0.65;
    cursor: not-allowed;
}


.play-button-overlay {
    /* Reset the global button styling for this icon-only overlay. */
    margin: 0;
    background: none;
    color: inherit;
    border-radius: 0;
    padding: 0;
    position: absolute;
    top: 30%;
    left: 50%;
    transform: translate(-50%, -50%);
    opacity: 0;
    transition: opacity 0.3s ease;
    cursor: pointer;
}

.play-button-overlay img {
    width: 100px;
    height: auto;
    filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.5));
}

.play-button-overlay:hover {
    /* Overrides the global button:hover gold tint above — this control has
       always just been an icon fading in, never a filled button. */
    background-color: transparent;
}

.col-12.col-md-6:hover .play-button-overlay {
    opacity: 1;
}

/* Keyboard-focused controls remain visible, with a two-colour focus ring
   that contrasts against both light and dark photography. */
.play-button-overlay:focus-visible {
    opacity: 1;
    outline: 2px solid #fff;
    outline-offset: 2px;
    box-shadow: 0 0 0 6px #000;
}

.play-button-overlay2 {
    position: absolute;
    top: 35%;
    left: 50%;
    transform: translate(-50%, -50%);
    opacity: 0;
    transition: opacity 0.3s ease;
    cursor: pointer;
}

.play-button-overlay2 img {
    width: 100px;
    height: auto;
    filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.5));
}


.col-12.col-md-6:hover .play-button-overlay2 {
    opacity: 1;
}

.cover-img-digital-films {
    padding: 0;
    width: 100%;
    height: 70%;
    object-fit: cover;
}

.cover-img-super8films {
    padding: 0% 20%;
    width: 100%;
    height: 100%;
}



@media (max-width:800px) {
    .second-font {
        font-size: 18px !important;
    }

    .area-2-title {
        font-size: 18px !important;
    }

    .title-gold {

        font-weight: 400;
        font-size: 22px;
    }

    .p-text-c {
        font-size: 18px !important;
    }

    .area-margin {
        margin-top: 25px !important;
    }

    .area-padding {
        margin-top: 20%;
    }
}

/* Testimonials strip (variant C — rating stat + short quotes + CTA) */
.testimonial-strip {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 40px;
    flex-wrap: wrap;
}

.testimonial-stat {
    text-align: center;
    flex: 0 0 auto;
}

.testimonial-stat-num {
    color: #fab949;
    font-size: 2.6rem;
    line-height: 1;
}

.testimonial-stat-cnt {
    font-family: 'Lora', serif;
    color: #887367;
    font-size: 13px;
    margin-top: 6px;
}

.testimonial-lines {
    flex: 1 1 320px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.testimonial-lines p {
    margin: 0;
    font-family: 'Lora', serif;
    font-style: italic;
    color: #836d63;
    font-size: 15px;
}

.testimonial-lines p strong {
    font-style: normal;
    color: #887367;
    font-size: 13.5px;
}

.testimonial-cta {
    flex: 0 0 auto;
}

.btn-gold {
    display: inline-block;
    background-color: #d19b32;
    color: #fff;
    text-decoration: none;
    font-family: 'Lora', serif;
    font-size: 14.5px;
    padding: 11px 26px;
    border-radius: 4px;
    transition: background 0.3s;
}

.btn-gold:hover {
    background-color: #b88226;
    color: #fff;
}

@media (max-width: 576px) {
    .testimonial-strip {
        gap: 24px;
    }

    .testimonial-stat-num {
        font-size: 2.2rem;
    }
}


















.photo-view-more {
    text-align: center;
    margin-top: 18px;
}

.btn-link {
    display: inline-block;
    color: #d19b32;
    text-decoration: none !important;
    font-family: 'Lora', serif;
    font-style: italic;
    font-size: 15px;
    transition: color 0.3s;
}

.btn-link:hover {
    color: #b88226;
}







@media (max-width: 576px) {

}

@media (prefers-reduced-motion: reduce) {

}

/* ===== Site-wide footer ===== */
.site-footer {
    --footer-gold: #96682a;
    background-color: #fefae7;
    border-top: 1px solid rgba(131, 109, 99, 0.22);
    padding: 38px 130px 30px;
}

.site-footer-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 48px;
}

.site-footer-wordmark {
    font-family: 'Seasons', Georgia, serif;
    font-size: 17px;
    font-weight: 300;
    letter-spacing: 0.42em;
    text-transform: uppercase;
    color: var(--footer-gold);
    line-height: 1;
}

.site-footer-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 30px;
}

.site-footer-nav a {
    font-family: 'Lora', Georgia, serif;
    font-size: 13px;
    color: #836d63;
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.2s ease;
}

.site-footer-nav a:hover {
    color: #5b4a41;
}

.site-footer-social {
    display: flex;
    gap: 18px;
}

.site-footer-social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 19px icon, 13px padding each side = 45px tap target — pads the
       anchor to clear the 44px minimum rather than enlarging the SVG. */
    padding: 13px;
    line-height: 0;
}

.site-footer-social-link svg {
    stroke: var(--footer-gold);
    transition: stroke 0.2s ease, fill 0.2s ease;
}

.site-footer-social-link svg circle:last-child {
    fill: var(--footer-gold);
}

.site-footer-social-link:hover,
.site-footer-social-link:focus-visible {
    --footer-gold: #7d581d;
}

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

.site-footer-bottom {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 26px;
    padding-top: 20px;
    border-top: 1px solid rgba(131, 109, 99, 0.22);
    font-family: 'Lora', Georgia, serif;
    font-size: 13px;
    color: #a9927f;
}

.site-footer-bottom a {
    color: #a9927f;
    text-decoration: none;
    transition: color 0.2s ease;
}

.site-footer-bottom a:hover {
    color: #726356;
}

@media (max-width: 999px) {
    .site-footer { padding: 32px 24px 26px; }
    .site-footer-row {
        flex-direction: column;
        align-items: center;
        gap: 22px;
        text-align: center;
    }
    .site-footer-nav { justify-content: center; }
    .site-footer-bottom {
        flex-direction: column;
        align-items: center;
        gap: 8px;
        text-align: center;
    }
}

@media (prefers-reduced-motion: reduce) {
    .site-footer-nav a,
    .site-footer-social-link svg,
    .site-footer-bottom a { transition: none; }
}

/* ===== Shared pattern for the new content pages (Videography, Photography,
   Super 8, Packages, About, Enquire, Locations hub/region/venue) ===== */
.page-header {
    padding: 14% 0 6%;
    text-align: center;
}

.page-header .page-eyebrow {
    display: block;
    font-family: 'Lora', serif;
    font-style: italic;
    color: #d19b32;
    font-size: 14px;
    letter-spacing: 0.04em;
    margin-bottom: 10px;
}

.page-header h1 {
    margin: 0;
}

.page-header .page-intro {
    max-width: 62ch;
    margin: 18px auto 0;
}

.page-section {
    padding: 4% 0;
}

.page-section h2 {
    margin-bottom: 4%;
}

.page-cta {
    text-align: center;
    padding: 6% 0 8%;
}

.page-cta .p-text {
    margin-bottom: 20px;
}

.venue-status-pending {
    background-color: #ffffff;
    border: 1px dashed #e4d9b8;
    border-radius: 6px;
    padding: 32px 24px;
    text-align: center;
    max-width: 60ch;
    margin: 0 auto;
}

.venue-status-pending p {
    margin: 0;
}

.location-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 24px;
}

.location-card {
    display: block;
    background-color: #ffffff;
    border: 1px solid #e4d9b8;
    border-radius: 6px;
    padding: 28px 24px;
    text-align: center;
    text-decoration: none;
    transition: border-color 0.3s, box-shadow 0.3s;
}

.location-card:hover {
    border-color: #d19b32;
    box-shadow: 0 8px 20px -14px rgba(60, 45, 15, 0.3);
}

.location-card .location-card-title {
    display: block;
    font-family: 'Seasons', serif;
    color: #fab949;
    text-transform: uppercase;
    letter-spacing: 1px;
    font-size: 1.3rem;
    margin-bottom: 8px;
}

.location-card .location-card-sub {
    display: block;
    font-family: 'Lora', serif;
    font-style: italic;
    color: #836d63;
    font-size: 14px;
}

@media (max-width: 576px) {
    .page-header {
        padding-top: 24%;
    }
}

/* ===== Homepage =====
   Homepage selectors use the hp- prefix to isolate them from shared and
   inner-page styles. */

.hp-page {
    font-family: 'Lora', Georgia, serif;
    color: #836d63;
    overflow: hidden;
}

.hp-section {
    /* Top padding stays above the homepage navbar's own 92px height
       (.site-navbar--hero is position:fixed for the whole page, not just
       the hero — see js/script.js's own comment on it) with a small
       margin, not 76px uniform: at 76px, scrolling a section flush to the
       viewport top put its own heading partly behind the fixed navbar. */
    padding: 100px 130px 56px;
}

.hp-bg-cream { background: #fefae7; }
.hp-bg-white { background: #ffffff; }
.hp-bg-sand { background: #f2e2c4; }

.hp-section-inner {
    display: flex;
    flex-direction: column;
    gap: 32px;
}

.hp-section-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 60px;
}

.hp-section-head.hp-align-center {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 14px;
}

.hp-section-title {
    font-family: 'Seasons', Georgia, serif;
    font-size: 32px;
    font-weight: 300;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #b88226;
    line-height: 1.15;
    margin: 0;
}

.hp-section-link {
    display: inline-flex;
    gap: 10px;
    align-items: center;
    font-family: 'Lora', Georgia, serif;
    font-size: 13px;
    letter-spacing: 0.17em;
    text-transform: uppercase;
    color: #b88226;
    text-decoration: none;
    border-bottom: 1px solid #e3b978;
    padding-bottom: 6px;
    flex: none;
}

.hp-section-link:hover { color: #a8702f; }
.hp-section-link svg { flex: none; }

/* ---------- hero ---------- */

.hp-hero {
    position: relative;
    width: 100%;
    height: 100vh;
    min-height: 560px;
    overflow: hidden;
    background: #141110;
}

.hp-hero-media,
.hp-hero-poster {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.hp-hero-scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(20, 17, 16, 0.50) 0%, rgba(20, 17, 16, 0.20) 40%, rgba(20, 17, 16, 0.42) 100%);
    /* Must outrank .video-bg's own z-index: 1 — without an explicit value
       here this sits at the implicit z-index: auto/0, so CSS stacking rules
       paint the positioned z-index: 1 video ABOVE it (and above
       .hp-hero-content below) once .video-bg.loaded raises its opacity from
       0 to 1, regardless of DOM order. That's a real, shipped bug found
       while investigating "the hero text vanishes after a second" — the
       wordmark was never fading or being removed, the video was simply
       painting on top of it the moment it finished revealing. */
    z-index: 2;
}

.hp-hero-content {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 30px;
    padding: 0 130px;
    /* Same reason as .hp-hero-scrim's own z-index just above: must outrank
       .video-bg's z-index: 1, or the video paints over the wordmark once it
       finishes revealing. Below the navbar's own z-index: 50 (unrelated —
       the navbar was never affected by this, it already had an explicit
       z-index of its own). */
    z-index: 3;
}

.hp-wordmark-hero {
    font-family: 'Seasons', Georgia, serif;
    font-size: 76px;
    font-weight: 300;
    letter-spacing: 0.42em;
    text-indent: 0.42em;
    text-transform: uppercase;
    /* Back to cream — the navbar-gold trial above (.site-navbar--hero) is
       kept, but Laurence asked for just the hero H1 itself to stay white/
       cream rather than following it into gold too. */
    color: #fefae7;
    line-height: 1;
    margin: 0;
    text-align: center;
}

/* ---------- sitewide navbar (site-navbar.njk, every route) ----------
   One layout, two theme modifiers: --hero (the homepage, overlaying the
   hero video — transparent, cream-on-video text) and --plain (every other
   route — sticky, on the page's own cream background, gold text).

   Layout is a real 3-column grid with an explicit, in-flow centre track
   (1fr auto 1fr) — NOT flex with an absolutely-positioned, out-of-flow
   wordmark. An out-of-flow wordmark reserves no space in the row, so
   nothing stops the side groups from running underneath it (that was a
   real, shipped bug: "Packages" collided with the wordmark below ~1350px).
   With the wordmark in flow, its auto column reserves exactly what it
   needs, and each 1fr side column has an implicit content-based minimum
   width it will never be compressed below — so a too-narrow viewport
   produces overflow, not overlapping, illegible text, and the breakpoint
   below stops that overflow before it can happen.

   That breakpoint (1400px) is measured, not guessed. Rendered with real
   fonts, the left group is 394px, the wordmark 261px, the right group
   301px (956px of content). With Lora/Seasons still unloaded — the
   fallback-font condition that actually reproduced the original bug —
   system-serif widths measured directly come to 400/271/304px (975px).
   Because an unequal-content 1fr/auto/1fr grid gives ALL of a narrowing
   container's remaining slack to whichever side track has the smaller
   minimum (here, the right group) while the constrained side (left) sits
   pinned at its own content minimum, the gap on the constrained side does
   not open up gradually from the naive sum-of-minimums width (1216px
   loaded / 1235px fallback) — it stays at or near zero until the
   container is wide enough for an even fr split to clear the constrained
   side's minimum outright (measured: 0px of clearance at 1301px, 7px at
   1360px, 28px at 1401px, all under the fallback-font condition). 1400px
   is chosen from that curve, not the naive minimum, for a real margin —
   about 28px under the worst (fallback-font) case at the breakpoint
   itself, and about 47px at the design's own 1440px canvas width — and is
   shared by both themes so the collapse point is identical everywhere the
   navbar appears. */

.site-navbar {
    z-index: 50;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    padding: 0 130px;
    height: 92px;
    /* Background/border read from custom properties (set once per variant
       below, or continuously by js/script.js on the homepage — see the
       comment there for why there is deliberately no transition on this). */
    background-color: var(--nav-bg, transparent);
    border-bottom: 1px solid var(--nav-border, transparent);
}

.site-nav-group {
    display: flex;
    gap: 22px;
    align-items: center;
}

.site-nav-group.site-nav-right {
    justify-content: flex-end;
}

.site-nav-wordmark-wrap {
    text-align: center;
}

.site-wordmark {
    font-family: 'Seasons', Georgia, serif;
    font-size: 20px;
    font-weight: 300;
    letter-spacing: 0.5em;
    text-transform: uppercase;
    color: var(--nav-wordmark);
    line-height: 1;
    text-decoration: none;
}

.site-nav-link {
    font-family: 'Lora', Georgia, serif;
    font-size: 13px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--nav-link);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    padding-bottom: 3px;
    white-space: nowrap;
    /* border-bottom-color only — it's purely a hover/current-state reveal,
       unrelated to --nav-link, which is itself updated continuously on the
       homepage (see js/script.js) and must not have a competing transition. */
    transition: border-bottom-color 0.2s ease;
}

.site-nav-link:hover,
.site-nav-link[aria-current] {
    color: var(--nav-link-current);
    border-bottom-color: var(--nav-link-current);
}

.site-navbar :focus-visible {
    outline: 2px solid var(--nav-focus);
    outline-offset: 3px;
}

/* Homepage: overlays the hero video, transparent background, cream text —
   unchanged from the original homepage-only navbar's colours. Genuinely
   transparent (--nav-bg: transparent), not a solid colour animated to look
   transparent — js/script.js continuously mixes these towards
   .site-navbar--plain's own values below as the hero's bottom edge crosses
   the navbar, so the navbar reads as a see-through pane the whole time,
   never a colour swatch of its own. */
.site-navbar--hero {
    /* fixed, not absolute — it must follow scroll (stay pinned to the
       viewport) rather than scrolling away with the hero section it starts
       over. .hero has no transform/filter/will-change of its own, so it
       does not become this element's containing block and its
       overflow:hidden does not clip it — fixed positioning resolves against
       the real viewport straight through, confirmed in a live preview. */
    position: fixed;
    top: 0; left: 0; right: 0;
    --nav-bg: transparent;
    --nav-border: transparent;
    /* Cream, matching the hero wordmark's own colour (.hp-wordmark-hero,
       #fefae7) exactly — the gold-navbar trial tried earlier was reverted
       at Laurence's request, back to one consistent cream/white for both
       instead of pure white against the video. js/script.js's HERO_COLOR
       must be kept in sync (t=0 of the scroll-linked fill reads its own
       copy of these same values, not this rule). */
    --nav-wordmark: #fefae7;
    --nav-link: rgba(254, 250, 231, 0.92);
    --nav-link-current: #fab949;
    --nav-focus: #fab949;
}

/* Every other route: sticky on the page's own cream background. Colours
   are gold but darkened from the page's other gold accents specifically to
   clear WCAG AA (4.5:1) for 13px text on #fefae7 — #b88226/#a8702f (the
   accent gold used elsewhere) measure 3.20:1/3.99:1 and fail; #8f6526/
   #6f4e19 measure 4.94:1/7.21:1 (verified: relative-luminance contrast
   formula, sRGB-linearised). */
.site-navbar--plain {
    position: sticky;
    top: 0;
    --nav-bg: #fefae7;
    --nav-border: rgba(131, 109, 99, 0.16);
    --nav-wordmark: #8f6526;
    --nav-link: #8f6526;
    --nav-link-current: #6f4e19;
    --nav-focus: #8f6526;
}

/* ---------- mobile nav: closed bar + right drawer (site-navbar.njk) ----------
   Hidden above 900px — the desktop grid above (site-nav-group/
   site-nav-wordmark-wrap) is the navbar there, unchanged. Below 900px that
   grid is hidden instead and this bar/drawer pair takes over. Two
   mechanisms drive visibility together: the drawer/scrim start with the
   HTML `hidden` attribute (removed from the accessibility tree and layout
   entirely — the only thing screen readers and Tab order ever see when
   closed), and a `--open` class added a frame after `hidden` is cleared
   drives the slide/fade transition (js/script.js). `[hidden]` needs the
   extra specificity bump below or the plain .site-drawer/.site-drawer-scrim
   rule (an author rule) would otherwise beat the UA stylesheet's own
   [hidden]{display:none} at equal specificity and show it regardless. */
.site-mobile-bar,
.site-drawer-scrim,
.site-drawer { display: none; }

/* Every other mobile-only container this feature adds — dots for the hp-
   rails, the hp- stand-in rail, and the ip- mobile film rail — hidden here
   by default (desktop) so an unstyled block-level div never shows above
   900px; each gets its real display value back inside the matching
   @media (max-width: 900px) block. */
.hp-rail-dots,
.ip-rail-dots,
.ip-mobile-rail { display: none; }

@media (max-width: 900px) {
    .site-navbar {
        display: block;
        height: auto;
        padding: 0;
    }
    .site-nav-group,
    .site-nav-wordmark-wrap { display: none; }

    .site-mobile-bar {
        /* A real 40px/1fr/46px grid, not flex + an out-of-flow centred
           wordmark. The previous approach (position: absolute, centred
           independently of the burger) reserved no space of its own — at
           320px the unshrinking 44px/0.28em "GOLDEN FILMS" is ~264px wide,
           more than half the viewport, so it physically overlapped the
           burger's hit target (confirmed: an ordinary pointer click on the
           burger was intercepted by the wordmark's own ink). Column 1 is
           deliberately left empty in the markup — CSS grid still reserves
           its width regardless — so column 2 (the wordmark) sits centred
           between the bar's two edges, not shifted by the burger's own
           width the way flex's justify-content centring on only two real
           children would be.

           Column 1 is 40px, not 46px to match the burger's column 3 — the
           bar's own padding is asymmetric (24px left, 18px right, chosen
           to line the wordmark's old left edge up with other content while
           keeping the burger's own generous 46px hit target from pushing
           its right inset too wide), and an equal-width column 1/3 pair
           would leave column 2's own centre 3px off true bar-centre as a
           result (confirmed: centreX landed at 198px on a 390px viewport,
           not 195). 40 = 46 - (24 - 18) cancels that asymmetry out exactly,
           for any viewport width, not just the one it was checked at. */
        display: grid;
        grid-template-columns: 40px 1fr 46px;
        column-gap: 6px;
        align-items: center;
        min-height: 64px;
        padding: 14px 18px 14px 24px;
    }
    .site-mobile-wordmark {
        grid-column: 2;
        /* Grid items stretch to their column's full width by default, so
           text-align: center here centres within column 2's exact width —
           not the wordmark's own shrink-to-fit content width the way the
           old absolutely-positioned version did. */
        text-align: center;
        font-family: 'Seasons', Georgia, serif;
        /* Fluid, not two fixed sizes (44px / 28px at a single 576px
           breakpoint) — that pair still overlapped the burger at 320-390px
           (up to 36px of real ink-on-ink overlap at 320px, confirmed via a
           real Chromium render), because neither size was chosen against
           the space actually available once the burger's own column is
           subtracted. clamp() ties size continuously to viewport width
           instead, tuned against real rendered text width (Playwright
           measurement, not hand-computed font metrics) so it stays inside
           column 2 with a comfortable margin from 320px up through 900px.
           letter-spacing is left in em, so it scales down with font-size
           automatically rather than needing its own separate tuning. */
        /* Anchored against real measured text width (Playwright, the
           actual Seasons font, this exact letter-spacing), not guessed:
           "Golden Films" needs ~17px to fit column 2's ~166px width at a
           320px viewport, and column 2 is wide enough for the full 44px
           size by ~590px — clamp() interpolates between those two
           measured points, then holds flat at 44px above that. */
        font-size: clamp(17px, calc(-15px + 10vw), 44px);
        font-weight: 300;
        letter-spacing: 0.24em;
        text-transform: uppercase;
        color: var(--nav-wordmark);
        text-decoration: none;
        line-height: 1.15;
        /* No white-space: nowrap — with a real, definite column width (not
           shrink-to-fit), letting "Golden Films" wrap onto two centred
           lines below whatever width the clamp() above is tuned for is a
           graceful fallback (the row's min-height, not a fixed height, can
           grow to fit), not a bug: it keeps the full brand name legible
           instead of either overlapping the burger or being clipped. */
        /* +2px optical correction, unchanged from before this rewrite —
           all-caps text has no descenders, so its line box (what centring
           actually centres) sits visually higher than the glyphs' own true
           centre. Confirmed against a real screenshot, not
           getBoundingClientRect() (which measures the line box, not visual
           cap-height, so it isn't a reliable way to judge this specific
           kind of offset). */
        transform: translateY(2px);
    }
    .site-mobile-burger {
        grid-column: 3;
        width: 46px;
        height: 46px;
        margin: 0;
        /* The sitewide `button { margin-top: 20px; ... }` reset (meant for
           form submit buttons) was leaking onto this nav toggle: flexbox's
           align-items: center on .site-mobile-bar centres a flex item's
           MARGIN box, so that inherited 20px top margin — invisible but
           still part of the box — pushed the actual visible button 10px
           below true bar-centre (half the asymmetric margin). Confirmed via
           real pixel analysis of a screenshot, not just computed styles:
           the burger's ink was ~10-11px lower than the wordmark's true
           visual centre before this reset. */
        border: none;
        background: transparent;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 5px;
        align-items: center;
        justify-content: center;
        cursor: pointer;
    }
    .site-mobile-burger span {
        width: 20px;
        height: 1.5px;
        background: var(--nav-wordmark);
        display: block;
    }

    .site-drawer-scrim {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(20, 17, 16, 0.55);
        z-index: 90;
        opacity: 0;
        transition: opacity 0.3s ease;
    }
    .site-drawer-scrim.site-drawer-scrim--open { opacity: 1; }
    .site-drawer-scrim[hidden] { display: none; }

    .site-drawer {
        display: flex;
        flex-direction: column;
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        width: 288px;
        max-width: 86vw;
        background: #fefae7;
        padding: 18px 22px 24px;
        z-index: 91;
        transform: translateX(100%);
        transition: transform 0.3s ease;
        box-shadow: -8px 0 24px rgba(20, 17, 16, 0.16);
    }
    .site-drawer.site-drawer--open { transform: translateX(0); }
    .site-drawer[hidden] { display: none; }

    .site-drawer-close {
        align-self: flex-end;
        width: 46px;
        height: 46px;
        margin: 0;
        /* Same sitewide `button { margin-top: 20px; ... }` leak as
           .site-mobile-burger above — reset here too so the close button
           doesn't carry unintended extra space above it in the drawer's
           column stack. */
        border: none;
        background: transparent;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
    }
    .site-drawer-links {
        display: flex;
        flex-direction: column;
        margin-top: 8px;
        overflow-y: auto;
    }
    .site-drawer-links a {
        display: flex;
        align-items: center;
        min-height: 50px;
        font-family: 'Lora', Georgia, serif;
        font-size: 15px;
        letter-spacing: 0.13em;
        text-transform: uppercase;
        color: #5b4a41;
        text-decoration: none;
        border-bottom: 1px solid rgba(131, 109, 99, 0.22);
    }
    .site-drawer-links a[aria-current] { color: #96682a; }
    .site-mobile-burger:focus-visible,
    .site-drawer-close:focus-visible,
    .site-drawer-links a:focus-visible {
        outline: 2px solid #96682a;
        outline-offset: 2px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .site-drawer,
    .site-drawer-scrim { transition: none; }
}

/* min-width: 901px — this narrow-desktop/tablet fix (stacking the navbar
   to avoid the label-overlap defect the navbar review found) and the true
   mobile bar/drawer takeover below 900px are mutually exclusive states for
   the same .site-navbar element. Without this floor, this block's own
   display: flex/column at max-width: 1400px still matched at every mobile
   width too, and — appearing later in the file than the ≤900px block above
   — won the cascade there, silently overriding display: block and leaving
   .site-mobile-bar shrink-wrapped instead of full-width (a real, shipped
   bug: the mobile wordmark ended up ~95px from the left edge instead of
   the intended 24px, discovered while lining it up with the hero title). */
@media (min-width: 901px) and (max-width: 1400px) {
    .site-navbar {
        display: flex;
        flex-direction: column;
        height: auto;
        padding: 16px 24px;
        gap: 10px;
    }
    .site-nav-group { flex-wrap: wrap; justify-content: center; gap: 14px 18px; }
}

.hp-play-ring:focus-visible,
.hp-photo-chevron:focus-visible,
.hp-photo-dot:focus-visible {
    outline: 2px solid #fab949;
    outline-offset: 3px;
}

/* ---------- film cells: play ring, hover/focus-revealed ---------- */

.hp-play-ring {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    border: none;
    background: none;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.hp-play-ring:hover,
.hp-play-ring:focus-visible {
    opacity: 1;
    /* Overrides the global button:hover gold-tint rule (css/style.css,
       `button:hover`) — without this, the whole 2.39:1/4:3 frame this button
       covers (position:absolute; inset:0) filled with solid gold on hover,
       since the global rule's specificity (an element + a pseudo-class)
       beats this button's own unqualified `background: none` above it. Same
       fix already applied to .play-button-overlay:hover for the same reason. */
    background-color: transparent;
}

.hp-play-ring svg { pointer-events: none; }

/* ---------- digital films ---------- */

.hp-digital-grid {
    display: grid;
    /* 3 columns, not 2 — with the site's own 130px gutter at a 1920-wide
       1080p Chrome window, 2 columns/3 rows ran taller than the window
       itself (all 6 films had to be scrolled to, not just seen after the
       hero) — 3 columns/2 rows fits everything below the hero on one
       screen instead. column-gap stays 0, the same deliberate edge-to-edge
       choice the 2-column layout already made. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: 0;
    row-gap: 32px;
}

.hp-film-cell {
    margin: 0;
    display: flex;
    flex-direction: column;
}

.hp-film-frame {
    position: relative;
    width: 100%;
    aspect-ratio: 2.39 / 1;
    background: #141110;
    overflow: hidden;
}

.hp-film-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.hp-film-caption {
    display: flex;
    flex-direction: column;
    gap: 4px;
    align-items: center;
    text-align: center;
    padding-top: 12px;
}

.hp-film-couple {
    font-family: 'Seasons', Georgia, serif;
    font-size: 21px;
    letter-spacing: 0.06em;
    color: #5b4a41;
}

.hp-film-location {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 14.5px;
    color: #a9927f;
}

/* ---------- super 8 ---------- */

.hp-super8-grid {
    display: grid;
    /* 4 columns, not 2 — there are exactly 4 Super 8 films, so this is one
       row instead of two, the same "fits below the hero without scrolling
       further" fix as the digital-films grid just above. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 24px;
}

.hp-super8-cell {
    margin: 0;
    background: #141110;
    padding: 14px;
}

.hp-super8-frame {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
}

.hp-super8-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.hp-super8-caption {
    display: flex;
    align-items: baseline;
    gap: 12px;
    padding-top: 12px;
}

.hp-super8-num {
    font-family: 'Seasons', Georgia, serif;
    font-size: 15px;
    letter-spacing: 0.12em;
    color: #fab949;
    flex: none;
}

.hp-super8-text {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.hp-super8-couple {
    font-family: 'Seasons', Georgia, serif;
    font-size: 19px;
    letter-spacing: 0.06em;
    color: #f2e2c4;
}

.hp-super8-location {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 14px;
    color: rgba(254, 250, 231, 0.62);
}

/* ---------- photography carousel ---------- */

.hp-photo-row {
    display: flex;
    align-items: center;
    gap: 26px;
}

.hp-photo-chevron {
    width: 48px;
    height: 48px;
    flex: none;
    border-radius: 50%;
    border: 1px solid #e3b978;
    background: transparent;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    margin: 0;
    color: #b88226;
    transition: background-color 0.2s, color 0.2s;
}

.hp-photo-chevron:hover {
    background-color: #d19b32;
    color: #fff;
}

.hp-photo-chevron svg { pointer-events: none; }

.hp-photo-viewport {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    min-height: 1px;
}

.hp-photo-track {
    position: relative;
    width: 100%;
    height: 100%;
}

.hp-photo-page {
    /* top/left/width, deliberately not inset:0 — inset:0 would also pin
       height to the viewport's own height, and the viewport's height is
       exactly what JS measures FROM the active page (see render() in
       js/script.js). inset:0 here would make that circular: the page can't
       size itself until the viewport has a height, and the viewport can't
       get a height until some page has sized itself. Leaving height on
       auto lets each page size from its own content (the image grid) every
       time, independent of the viewport. */
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 26px;
    transition: transform 0.5s cubic-bezier(0.65, 0, 0.35, 1), opacity 0.4s ease;
}

/* Reduced motion: cross-fade in place, no horizontal movement at all. */
.hp-photo-track.hp-mode-fade .hp-photo-page {
    transform: none !important;
    transition: opacity 0.4s ease;
}

.hp-photo-frame {
    position: relative;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    background: #141110;
}

.hp-photo-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.hp-photo-dots {
    display: flex;
    gap: 11px;
    justify-content: center;
    align-items: center;
}

.hp-photo-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: block;
    padding: 0;
    margin: 0;
    background: transparent;
    border: 1px solid #c9924a;
    cursor: pointer;
}

.hp-photo-dot[aria-current="true"] {
    background: #d19b32;
    border-color: #d19b32;
}

/* ---------- where we film ---------- */

.hp-regions-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 44px;
}

.hp-region-card {
    display: flex;
    flex-direction: column;
    gap: 18px;
    text-decoration: none;
}

.hp-region-image {
    position: relative;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background: #141110;
}

.hp-region-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.hp-region-tbc {
    position: absolute;
    right: 10px;
    top: 10px;
    font-family: 'Lora', Georgia, serif;
    font-size: 10px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #fefae7;
    background: rgba(20, 17, 16, 0.55);
    padding: 4px 9px;
}

.hp-region-text {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.hp-region-name {
    font-family: 'Seasons', Georgia, serif;
    font-size: 24px;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: #b88226;
}

.hp-region-blurb {
    font-family: 'Lora', Georgia, serif;
    font-size: 14.5px;
    line-height: 1.65;
    color: #836d63;
}

.hp-region-card:focus-visible {
    outline: 2px solid #b88226;
    outline-offset: 4px;
}

/* ---------- testimonials ---------- */

.hp-testimonials-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    /* One row however many reviews: a fourth shares the row (see the :has
       rule beside .ip-reviews-grid) instead of wrapping. */
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 48px;
    align-items: start;
}

.hp-testimonial-card {
    display: flex;
    flex-direction: column;
    gap: 20px;
    border-top: 1px solid #e3b978;
    padding-top: 26px;
}

.hp-testimonial-stars {
    display: flex;
    gap: 4px;
}

.hp-testimonial-quote {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 17.5px;
    line-height: 1.75;
    color: #5b4a41;
    margin: 0;
}

.hp-testimonial-attribution {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.hp-testimonial-name {
    font-family: 'Seasons', Georgia, serif;
    font-size: 20px;
    letter-spacing: 0.07em;
    color: #b88226;
}

.hp-testimonial-meta {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 13.5px;
    color: #a9927f;
}

/* Each review's link to Google, and the "Read our Google reviews" link beneath
   a set of them (partials/review-card.njk). Quiet, so the quote leads. */
.hp-testimonial-source {
    align-self: flex-start;
    margin-top: 4px;
    font-family: 'Lora', Georgia, serif;
    font-size: 12px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    /* Deeper than the site gold (#b88226, ~3.2:1 on cream): at 12px this needs 4.5:1. */
    color: #8f6417;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.hp-testimonial-source:hover,
.hp-testimonial-source:focus-visible {
    color: #6f4c12;
}

.reviews-google-link {
    margin: 28px 0 0;
    text-align: center;
}

/* ---------- enquiry: short form (homepage) ---------- */

.hp-enquiry {
    background: #fefae7;
    padding: 96px 130px 100px;
}

.hp-enquiry-inner {
    display: flex;
    flex-direction: column;
    gap: 34px;
    max-width: 680px;
    margin: 0 auto;
    align-items: center;
    text-align: center;
}

.hp-enquiry-head {
    display: flex;
    flex-direction: column;
    gap: 12px;
    align-items: center;
    text-align: center;
}

.hp-enquiry-title {
    font-family: 'Seasons', Georgia, serif;
    font-size: 34px;
    font-weight: 300;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: #96682a;
    line-height: 1.15;
    margin: 0;
}

.hp-enquiry-fields {
    display: flex;
    gap: 44px;
    width: 100%;
    margin-top: 8px;
    text-align: left;
}

.hp-enquiry-field {
    display: flex;
    flex-direction: column;
    gap: 9px;
    flex: 1 1 0;
    min-width: 0;
}

.hp-enquiry-field span {
    font-family: 'Lora', Georgia, serif;
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #7f6b60;
    line-height: 1.5;
}

.hp-enquiry-field input {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    border: none;
    border-radius: 0;
    border-bottom: 1px solid #b88226;
    padding-bottom: 11px;
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    color: #5b4a41;
    background: transparent;
    min-height: 30px;
    width: 100%;
}

.hp-enquiry-field input::placeholder {
    color: #7f6b60;
    font-style: italic;
    opacity: 1;
}

.hp-enquiry-field input:focus {
    outline: 2px solid #96682a;
    outline-offset: 3px;
    border-bottom-color: #96682a;
}

.hp-enquiry-actions {
    display: flex;
    gap: 20px;
    align-items: center;
    justify-content: center;
    margin-top: 8px;
    flex-wrap: wrap;
    width: 100%;
}

.hp-enquiry-submit {
    font-family: 'Lora', Georgia, serif;
    font-size: 13px;
    letter-spacing: 0.19em;
    text-transform: uppercase;
    color: #fefae7;
    /* The navbar's gold (.site-navbar--plain), at the owners' request. */
    background: #8f6526;
    min-height: 52px;
    padding: 0 64px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    cursor: pointer;
}

.hp-enquiry-submit:hover { background: #6f4e19; }

.hp-enquiry-crosslink {
    font-family: 'Lora', Georgia, serif;
    font-size: 14.5px;
    line-height: 1.65;
    color: #7f6b60;
    text-align: center;
    margin: 0;
}

.hp-enquiry-crosslink a {
    color: #96682a;
    text-decoration: none;
    border-bottom: 1px solid #e3b978;
    padding-bottom: 2px;
}

.hp-enquiry-crosslink a:hover { border-bottom-color: #96682a; }

.hp-enquiry-crosslink a:focus-visible {
    outline: 2px solid #96682a;
    outline-offset: 2px;
}

/* ---------- enquiry status: shared success/error boxes (home + /enquire/) ----------
   Replaces what used to be inline styles set directly in index.njk/enquire.njk
   (#4CAF50/#f44336 Material colours, 5px radius). Hidden by default here,
   exactly like the inline style it replaces; js/enquiry.js still toggles
   visibility with element.style.display, which is normal runtime behaviour,
   not an authored inline style. */
.enquiry-status {
    display: none;
    gap: 14px;
    align-items: flex-start;
    padding: 20px 24px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}

.enquiry-status__icon { flex: none; margin-top: 2px; }

.enquiry-status__text {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1 1 240px;
    min-width: 0;
}

.enquiry-status__heading {
    font-family: 'Seasons', Georgia, serif;
    font-size: 21px;
    font-weight: 300;
    letter-spacing: 0.06em;
    margin: 0;
}

.enquiry-status__body {
    font-family: 'Lora', Georgia, serif;
    font-size: 15px;
    line-height: 1.6;
    margin: 0;
}

.enquiry-status--success {
    background: #f2e2c4;
    border: 1px solid #c9924a;
}

.enquiry-status--success .enquiry-status__heading { color: #5b4a41; }
.enquiry-status--success .enquiry-status__body { color: #6f5d54; }

.enquiry-status--error {
    background: rgba(168, 112, 47, 0.07);
    border: 1px solid #a8702f;
}

.enquiry-status--error .enquiry-status__heading,
.enquiry-status--error .enquiry-status__body { color: #8d5a1e; }
.enquiry-status--error .enquiry-status__body a { color: #8d5a1e; }

@media (prefers-reduced-motion: reduce) {
    /* Belt and braces: js/script.js already switches to .hp-mode-fade (no
       transform) when it detects this preference, but if JS hasn't run yet
       (or fails) this still stops any transform-based movement outright. */
    .hp-photo-page { transition: opacity 0.4s ease; }
}

/* Roughly 900px per the handoff: two-up grids go single column, the
   photography carousel shows one photograph at a time (handled in JS via
   matchMedia — see js/script.js), and the type scale steps down. */
/* =====================================================================
   Mobile (below 900px): the digital films, Super 8 and photography grids
   each become one horizontally-scrolling rail — native scroll, not a JS
   carousel (overflow-x:auto + scroll-snap; JS below only tracks/drives dot
   state and reduced-motion scroll-behaviour, it never intercepts touch or
   reimplements momentum). One shared mechanism, applied to each grid's own
   existing markup — the cards themselves (.hp-film-cell/.hp-super8-cell/
   .hp-photo-frame) are completely unchanged from desktop, only their
   container's layout changes. [data-rail] carries the mechanics generically
   (css/style.css here, js/script.js's initRail there); per-family width/
   gap is still set through the hp-/ip- prefixed class itself, per the
   sitewide prefix discipline. Scoped entirely inside the 900px query below
   (including this shared mechanics rule) — data-rail exists in the markup
   at every width, but only behaves like a rail below 900px; above it, the
   desktop grid/carousel each already has its own unrelated layout rule
   with higher specificity than a bare attribute selector, but this still
   keeps the mechanics themselves from ever applying to the desktop grid.
   ===================================================================== */
@media (max-width: 900px) {
    [data-rail] {
        display: flex;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    [data-rail]::-webkit-scrollbar { display: none; }

    .hp-section { padding: 56px 24px; }
    .hp-enquiry { padding: 56px 24px; }
    .hp-hero { height: 620px; min-height: 0; }
    .hp-hero-content { padding-left: 24px; padding-right: 24px; }
    /* Pivot: only one "Golden Films" on screen at mobile — the navbar's own
       (below), grown to the size this hero title used to be — not a second,
       separate hero title too. The h1 itself stays in the DOM rather than
       display:none, so the page still has a real, accessible h1 on mobile
       (screen readers/crawlers) — visually hidden the standard way
       (Bootstrap's own .visually-hidden technique, inlined here since it
       needs to apply only below this breakpoint, not unconditionally). */
    .hp-wordmark-hero {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }
    .hp-section-title { font-size: 26px; }
    .hp-enquiry-title { font-size: 26px; }

    /* ---------- digital films / Super 8 rails ---------- */
    .hp-digital-grid,
    .hp-super8-grid {
        display: flex;
        gap: 14px;
        margin-left: -24px;
        margin-right: -24px;
        padding: 0 24px;
        scroll-padding-left: 24px;
    }
    .hp-film-cell { flex: none; width: 300px; scroll-snap-align: start; }
    .hp-super8-cell { flex: none; width: 288px; scroll-snap-align: start; }
    /* The play ring has no hover state to reveal on a phone — stay visible,
       don't port the desktop hover-reveal (see .hp-play-ring's own rest/
       hover rule above; this simply removes the opacity:0 rest state for
       every viewport at or below this breakpoint). */
    .hp-film-cell .hp-play-ring,
    .hp-super8-cell .hp-play-ring { opacity: 1; }

    /* ---------- photography rail ---------- */
    .hp-photo-row { gap: 0; }
    .hp-photo-chevron { display: none; }
    /* min-width:0 is essential on this flex item: without it, its intrinsic
       six-card width expands the wrapper far beyond the phone viewport. The
       track then has almost nothing to overflow, so native swiping stalls and
       IntersectionObserver marks every card visible (ending on the last dot). */
    .hp-photo-viewport { width: 100%; min-width: 0; overflow: visible; }
    .hp-photo-track {
        gap: 14px;
        margin-left: -24px;
        margin-right: -24px;
        padding: 0 24px;
        scroll-padding-left: 24px;
    }
    /* .hp-photo-page groups exist for the desktop JS slider's 3-per-page
       transform (see js/script.js's rebuildPages) — display:contents keeps
       its children (the individual .hp-photo-frame images) in the DOM
       exactly where they are while removing the grouping div itself from
       layout, so .hp-photo-track's own flex/scroll-snap rules apply
       directly to the flattened set of frames, one per view, instead of to
       3-photo groups. The desktop carousel JS is itself gated to run only
       above this breakpoint (see the mobileQuery check in js/script.js) so
       nothing fights this for control of transform/opacity. */
    .hp-photo-page {
        display: contents;
    }
    .hp-photo-frame { flex: none; width: 250px; scroll-snap-align: start; position: static; opacity: 1 !important; transform: none !important; }
    .hp-photo-dots { padding-top: 4px; }

    /* Stand-in rail: shown only while featuredPhotography is empty (see
       index.njk) — the real carousel above and this share the same section,
       never both at once. */




    /* The old gradient-swatch stub (index.njk's else-branch, unrelated to
       this feature and otherwise untouched) is replaced at mobile by the
       stand-in rail above it — never both at once. */


    /* Shared dot component — reused by every rail above (hp- family) and
       by the inner-page rails below (ip- family gets its own selector,
       same declarations, so the CSS itself still isn't duplicated). Real
       <button>s, not spans: a visible 7px dot inside a 44px padded hit
       area, per the accessibility requirement below. */
    .hp-rail-dots,
    .ip-rail-dots {
        display: flex;
        gap: 9px;
        justify-content: center;
        align-items: center;
        padding-top: 4px;
    }
    .hp-rail-dot,
    .ip-rail-dot {
        width: 44px;
        height: 44px;
        padding: 0;
        margin: 0;
        border: none;
        background: transparent;
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .hp-rail-dot::before,
    .ip-rail-dot::before {
        content: '';
        display: block;
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: transparent;
        border: 1px solid #c9924a;
    }
    .hp-rail-dot[aria-current]::before,
    .ip-rail-dot[aria-current]::before {
        background: #d19b32;
        border-color: #d19b32;
    }
    .hp-rail-dot:focus-visible,
    .ip-rail-dot:focus-visible {
        outline: 2px solid #96682a;
        outline-offset: 2px;
    }

    /* ---------- where we film: stacked rows, not a rail ---------- */
    .hp-regions-grid { display: flex; flex-direction: column; }
    .hp-region-card {
        flex-direction: row;
        align-items: center;
        gap: 14px;
        min-height: 80px;
        border-top: 1px solid rgba(131, 109, 99, 0.22);
        padding-top: 16px;
    }
    .hp-regions-grid .hp-region-card:first-child { border-top: none; padding-top: 0; }
    .hp-region-image { width: 104px; flex: none; aspect-ratio: 3 / 2; }
    .hp-region-name { font-size: 19px; }
    .hp-region-blurb {
        font-size: 12.5px;
        line-height: 1.5;
        /* Truncated blurb, per the request — a phone row has no room for
           the full desktop copy at this width. */
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    /* ---------- testimonials: one card at a time, same rail mechanics —
       no peek (the mock shows a single card filling the section's own
       gutter, not a full-bleed strip), so this rail isn't full-bleed like
       the three above it. ---------- */
    .hp-testimonials-grid {
        display: flex;
        gap: 0;
        scroll-padding-left: 0;
    }
    .hp-testimonial-card { flex: none; width: 100%; scroll-snap-align: start; }

    .hp-enquiry-fields { flex-direction: column; gap: 24px; }
    .hp-enquiry-field input { min-height: 46px; padding-top: 12px; padding-bottom: 0; }
    .hp-enquiry-submit { padding: 0 42px; }
}

@media (max-width: 576px) {
    .hp-section-head:not(.hp-align-center) {
        flex-direction: column;
        align-items: flex-start;
        gap: 16px;
    }
    /* .site-mobile-wordmark's size is fluid (clamp(), set above in the
       900px block) across the whole mobile range now, replacing the old
       fixed 28px/0.2em override this breakpoint used to carry — that fixed
       pair was tuned by eye, not against the burger's reserved space, and
       still overlapped it at 320-390px. */
}

@media (prefers-reduced-motion: reduce) {
    [data-rail] { scroll-behavior: auto; }
}

/* ===== Inner pages =====
   Inner-page selectors use the ip- prefix to avoid collisions with shared
   and homepage styles. */

.ip-page {
    font-family: 'Lora', Georgia, serif;
    color: #836d63;
    overflow: hidden;
}

.ip-h1-reel {
    font-family: 'Seasons', Georgia, serif;
    font-size: 42px;
    font-weight: 300;
    line-height: 1.02;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #b88226;
    margin: 0;
}

.ip-h1 {
    font-family: 'Seasons', Georgia, serif;
    font-size: 40px;
    font-weight: 300;
    line-height: 1.05;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #b88226;
    margin: 0;
}

.ip-header {
    background: #fefae7;
    padding: 96px 130px;
}

.ip-header-reel {
    background: #fefae7;
    padding: 44px 130px 28px;
}

.ip-header-inner {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 860px;
}

.ip-intro {
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    line-height: 1.6;
    color: #5b4a41;
    max-width: 780px;
    margin: 4px 0 0;
}

/* S13/C7: contextual links from a service page to the location pages where
   its films were actually shot — replacing what aa3fedd removed with links
   that point somewhere more specific than "more films on the homepage". */
.ip-related-links {
    font-family: 'Lora', Georgia, serif;
    font-size: 14.5px;
    line-height: 1.65;
    color: #7f6b60;
    max-width: 780px;
    margin: 28px 0 0;
}

.ip-related-links a {
    color: #96682a;
    text-decoration: none;
    border-bottom: 1px solid #e3b978;
    padding-bottom: 1px;
}

.ip-related-links a:hover { border-bottom-color: #96682a; }

.ip-related-links a:focus-visible {
    outline: 2px solid #96682a;
    outline-offset: 2px;
}

.ip-section {
    background: #fefae7;
    padding: 60px 130px;
}

/* Service-page middle band. */
.ip-section-reel {
    background: #fefae7;
    padding: 32px 130px 56px;
}

.ip-section-white {
    background: #ffffff;
    padding: 92px 130px;
}

/* ---------- shared 3-column facts band (every reel-family page + about) ---------- */

.ip-cols3 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 52px;
}

.ip-cols3-item {
    display: flex;
    flex-direction: column;
    gap: 13px;
    border-top: 1px solid #e3b978;
    padding-top: 22px;
}

.ip-cols3-title {
    /* S7: was a <span> (inline, no box model of its own); now an <h3> so
       these titles are real document structure. The parent's flex `gap`
       already spaces it from the paragraph below, so margin is zeroed here
       to cancel the browser's default h3 margin — visually unchanged. */
    display: block;
    margin: 0;
    font-family: 'Seasons', Georgia, serif;
    font-size: 22px;
    font-weight: 400;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #b88226;
}

.ip-cols3-text {
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    line-height: 1.78;
    color: #836d63;
    margin: 0;
}

/* ---------- digital films: large stage + thumbnail rail ---------- */

.ip-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 2.39 / 1;
    background: #141110;
    overflow: hidden;
}

/* #filmStage only (videography.njk's own feature player) — not the bare
   .ip-stage class, which _venue.njk's own film grid also uses at its own,
   already-narrower grid-column width. Full-bleed at 2.39:1 ran ~695px
   tall; capped so the feature film and the rail below it both fit inside
   a 1080p Chrome window without scrolling, matching the request. */
#filmStage,
#filmRail {
    max-width: 1100px;
    margin-left: auto;
    margin-right: auto;
}

.ip-stage img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: opacity 0.35s ease;
}

.ip-stage iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: none;
    display: block;
}

/* .ip-stage img/.ip-stage-play both set their own `display`, which would
   otherwise outrank the browser's default [hidden]{display:none} UA rule —
   author styles always win a UA-vs-author tie regardless of specificity. */
.ip-stage [hidden] {
    display: none !important;
}

/* Venue pages (locations/_venue.njk) reuse the sitewide .play-button-overlay
   control inside an .ip-stage card. Its default rules (css/style.css above)
   assume the old Bootstrap .col-12.col-md-6:hover layout to reveal it and a
   fixed top:30% position sized for a shorter card — override both for this
   2.39:1 stage context. Always visible, matching every other "stage"-style
   play control in this redesign (hp-play-ring, ip-stage-play). */
.ip-stage .play-button-overlay {
    top: 50%;
    opacity: 1;
}

.ip-stage .play-button-overlay img {
    width: 70px;
}

.ip-stage-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    border: none;
    background: none;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.ip-stage-play:hover,
.ip-stage-play:focus-visible {
    opacity: 1;
    /* Same button:hover gold-tint override as .hp-play-ring above — without
       it this covers the whole 2.39:1 stage in solid gold on hover. */
    background-color: transparent;
}

.ip-stage-caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 30px 34px;
    background: linear-gradient(180deg, rgba(20, 17, 16, 0), rgba(20, 17, 16, 0.7));
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 30px;
    pointer-events: none;
}

.ip-stage-couple {
    font-family: 'Seasons', Georgia, serif;
    font-size: 34px;
    letter-spacing: 0.06em;
    color: #fefae7;
}

.ip-stage-location {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 15px;
    color: rgba(254, 250, 231, 0.76);
}

.ip-stage-count {
    font-family: 'Lora', Georgia, serif;
    font-size: 11px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: rgba(254, 250, 231, 0.66);
    flex-shrink: 0;
    white-space: nowrap;
}

.ip-rail {
    display: flex;
    gap: 14px;
    align-items: flex-start;
}

.ip-rail-item {
    display: flex;
    flex-direction: column;
    gap: 9px;
    flex: 1 1 0;
    min-width: 0;
    padding: 0;
    margin: 0;
    border: none;
    background: none;
    cursor: pointer;
    text-align: left;
}

.ip-rail-frame {
    display: block;
    position: relative;
    aspect-ratio: 2.39 / 1;
    overflow: hidden;
    background: #141110;
    outline: 1px solid rgba(131, 109, 99, 0.22);
    outline-offset: 0;
}

.ip-rail-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0.72;
    transition: opacity 0.2s ease;
}

.ip-rail-item.ip-active .ip-rail-frame {
    outline: 2px solid #d19b32;
    outline-offset: 3px;
}

.ip-rail-item.ip-active .ip-rail-frame img {
    opacity: 1;
}

.ip-rail-item:hover .ip-rail-frame img,
.ip-rail-item:focus-visible .ip-rail-frame img {
    opacity: 1;
}

.ip-rail-item:focus-visible .ip-rail-frame {
    outline: 2px solid #d19b32;
    outline-offset: 3px;
}

.ip-rail-label {
    font-family: 'Lora', Georgia, serif;
    font-size: 11px;
    letter-spacing: 0.1em;
    color: #a9927f;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ip-rail-item.ip-active .ip-rail-label {
    color: #b88226;
}

/* ---------- super 8: moving perforated strip ---------- */

.ip-strip-wrap {
    position: relative;
    /* Full-bleed breakout: the strip runs edge to edge of the viewport, past
       the section's own 130px side padding (96px/24px at narrower widths —
       see the matching negative-margin overrides below). */
    width: calc(100% + 260px);
    margin: 0 -130px;
    overflow: hidden;
}

.ip-strip-viewport {
    overflow: hidden;
    padding: 12px 0;
}

/* Deliberately NOT gated behind prefers-reduced-motion (per Laurence's
   request) — the strip keeps auto-scrolling for every visitor regardless of
   that OS/browser preference. Hovering or focusing a frame still pauses it
   (see the rule just below) and plays that film's own silent preview, so a
   visitor who wants it still can always stop it that way; it just no longer
   starts frozen by default. Because it no longer honours the OS preference,
   WCAG 2.2.2 needs a real, stationary pause control too — see
   .ip-strip-pause below and js/script.js's super8Strip block — rather than
   relying on hover/focus-pause alone. */
.ip-strip-track {
    display: flex;
    width: max-content;
    will-change: transform;
    animation: ip-strip-scroll 48s linear infinite;
}

/* Scoped to .ip-strip-viewport (the figures themselves), not the whole
   .ip-strip-wrap: the wrap also contains .ip-strip-pause below, a sibling
   of the viewport — scoping this to the wrap would mean simply focusing or
   hovering that unrelated button held the strip paused via this rule
   regardless of its own pressed state, so clicking it to resume would
   visibly do nothing while it still had focus. */
.ip-strip-viewport:hover .ip-strip-track,
.ip-strip-viewport:focus-within .ip-strip-track {
    animation-play-state: paused;
}

/* F2/D2 (user-requested pause, via #super8StripPause) and F3/D3 (paused
   automatically while .ip-strip-wrap is off screen, via an
   IntersectionObserver) both set this same class — js/script.js tracks
   which of the two asked for it internally so neither un-pauses a state the
   other one set, but the visual/CSS effect is identical either way. */
.ip-strip-wrap.ip-strip-paused .ip-strip-track {
    animation-play-state: paused;
}

.ip-strip-pause {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    background: rgba(20, 17, 16, 0.72);
    border: 1px solid rgba(254, 250, 231, 0.5);
    border-radius: 999px;
    cursor: pointer;
}

.ip-strip-pause-label {
    font-family: 'Lora', Georgia, serif;
    font-size: 12.5px;
    letter-spacing: 0.02em;
    color: #fefae7;
}

.ip-strip-pause:hover { border-color: #fefae7; }

.ip-strip-pause:focus-visible {
    outline: 2px solid #fefae7;
    outline-offset: 2px;
}

@keyframes ip-strip-scroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}

.ip-strip-figure {
    margin: 0;
    flex: none;
    width: 400px;
    position: relative;
    cursor: pointer;
}

.ip-strip-figure:focus-visible {
    outline: 2px solid #fab949;
    outline-offset: -2px;
}

.ip-strip-figure img {
    width: 100%;
    height: 300px;
    object-fit: cover;
    display: block;
}

.ip-strip-figure iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 300px;
    border: none;
    display: block;
}

/* Corner expand control: the hover/focus preview above is deliberately
   silent, tiny and chromeless (background=1 — no controls, no sound at
   all); this is the way to the real, full-sized, real-audio player
   instead — the same sitewide video-modal every other play control opens.
   Hidden until the figure itself is hovered/focused, not just this button
   — matches the reveal trigger the inline preview already uses, so both
   appear together. Explicit background-color on both states, not just
   rest: the global button:hover { background-color: #b88226 } rule would
   otherwise paint a gold square over the icon on hover — the exact bug
   already found and fixed on .hp-play-ring/.ip-stage-play earlier. */
.ip-strip-expand {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 1;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background-color: rgba(20, 17, 16, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.ip-strip-figure:hover .ip-strip-expand,
.ip-strip-figure:focus-within .ip-strip-expand,
.ip-strip-expand:focus-visible {
    opacity: 1;
}

.ip-strip-expand:hover,
.ip-strip-expand:focus-visible {
    background-color: rgba(20, 17, 16, 0.8);
    outline: 2px solid #fab949;
    outline-offset: 2px;
}

/* On hover, the site's gold and a slightly finer line. Keyboard focus keeps
   the brighter, heavier ring above, which has to stand out on any frame. */
.ip-strip-expand:hover {
    outline: 1.5px solid #d19b32;
}

.ip-strip-expand svg { pointer-events: none; }

.ip-strip-figure figcaption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 10px 12px;
    background: linear-gradient(180deg, rgba(20, 17, 16, 0), rgba(20, 17, 16, 0.72));
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
}

.ip-strip-figure-couple {
    font-family: 'Seasons', Georgia, serif;
    font-size: 17px;
    letter-spacing: 0.05em;
    color: #f2e2c4;
}

.ip-strip-figure-num {
    font-family: 'Lora', Georgia, serif;
    font-size: 10px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: rgba(254, 250, 231, 0.6);
}

/* ---------- photography: full-gallery teaser (replaces the old
   Cloudinary contact-sheet/stand-in rail — the real portfolio is now an
   external ~50-photo gallery; see photography.njk) ---------- */

.ip-gallery-teaser {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    text-align: center;
    background: #141110;
    padding: 76px 48px;
}

.ip-gallery-teaser-count {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 13.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #d19b32;
}

.ip-gallery-teaser-heading {
    font-family: 'Seasons', Georgia, serif;
    font-weight: 400;
    font-size: clamp(32px, 5vw, 46px);
    letter-spacing: 0.03em;
    color: #fefae7;
    margin: 0;
}

.ip-gallery-teaser-intro {
    font-family: 'Lora', Georgia, serif;
    font-size: 16.5px;
    line-height: 1.6;
    color: rgba(254, 250, 231, 0.78);
    max-width: 480px;
    margin: 0;
}

@media (max-width: 900px) {
    .ip-gallery-teaser { padding: 56px 24px; }
}

/* ---------- about ---------- */

.ip-about-grid {
    display: grid;
    grid-template-columns: 1fr 440px;
    gap: 70px;
    align-items: start;
}

.ip-about-text {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.ip-about-text p {
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    line-height: 1.7;
    color: #836d63;
    margin: 0;
}

.ip-about-photo-wrap {
    position: relative;
    margin-top: 20px;
}

/* An even halo: one line all the way round the photo, the same distance
   from it on every side. It used to be offset up and to the right. */
.ip-about-photo-frame {
    position: absolute;
    inset: -12.6px;
    border: 1px solid #e3b978;
}

.ip-about-photo-wrap img {
    position: relative;
    width: 100%;
    /* height: auto is not redundant with aspect-ratio here — it's the whole
       fix. The <img> carries real width/height HTML attributes (248x247,
       the source asset's own near-square dimensions), which act as a
       presentational hint at a lower cascade priority than any author CSS —
       but only lower than a rule that actually sets `height`. This rule
       never did, so the attribute-derived 247px height won by default,
       leaving nothing for aspect-ratio to solve (both dimensions were
       already definite: width from this rule, height from the attribute),
       and the ratio below was silently ignored — confirmed in an isolated
       test page, not just reasoned about; a real, shipped bug, not a
       redundant declaration. Explicitly setting height: auto is what makes
       aspect-ratio 4/5 the thing that actually determines height. */
    height: auto;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    display: block;
}

/* ---------- enquire: full form (/enquire/) ----------
   One centred column (previously a two-column grid with a sand info panel —
   dropped; the left column's job is now done by the intro paragraph above
   the form and the contact block below it). */

.ip-enquire-section { padding: 92px 130px 100px; }

.ip-enquire-column {
    max-width: 660px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 44px;
}

.ip-enquire-heading {
    font-family: 'Seasons', Georgia, serif;
    font-size: 54px;
    font-weight: 300;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #96682a;
    line-height: 1.05;
    margin: 0;
}

.ip-enquire-intro {
    font-family: 'Lora', Georgia, serif;
    font-size: 17px;
    line-height: 1.7;
    color: #836d63;
    margin: 0;
}

.ip-enquire-contact {
    display: flex;
    flex-direction: column;
    gap: 12px;
    border-top: 1px solid #e3b978;
    padding-top: 24px;
}

.ip-enquire-contact span {
    font-family: 'Lora', Georgia, serif;
    font-size: 15px;
    color: #836d63;
}

.ip-enquire-contact-reassure {
    font-style: italic;
    color: #7f6b60;
}

.eq-group {
    display: flex;
    flex-direction: column;
    gap: 22px;
}

/* Small gold asterisk beside a required field's label, and beside the
   "* Required" note near the submit button — one shared class so both
   read as the same mark. Decorative (aria-hidden): the fields it marks
   are already genuinely HTML-required and announce that natively.
   Specificity note: this needs to outrank .eq-field span's own color
   (it's nested inside that span), hence the doubled-up selectors below
   rather than a bare .eq-required-mark rule. */
.eq-required-mark {
    text-transform: none;
    letter-spacing: normal;
    margin-left: 2px;
}

.eq-field .eq-required-mark,
.eq-submit-note .eq-required-mark {
    color: #96682a;
}

.eq-submit-note .eq-required-mark {
    margin-left: 0;
    margin-right: 4px;
}

.eq-row {
    display: flex;
    gap: 36px;
}

.eq-field {
    display: flex;
    flex-direction: column;
    gap: 9px;
    flex: 1 1 0;
    min-width: 0;
}

.eq-field.full { flex-basis: 100%; }

.eq-field span {
    font-family: 'Lora', Georgia, serif;
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #7f6b60;
    line-height: 1.5;
}

.eq-field input,
.eq-field select,
.eq-field textarea {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    border: none;
    border-radius: 0;
    border-bottom: 1px solid #b88226;
    padding-bottom: 11px;
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    color: #5b4a41;
    background: transparent;
    min-height: 30px;
    width: 100%;
}

.eq-field textarea { resize: vertical; }

.eq-field input::placeholder,
.eq-field textarea::placeholder {
    color: #7f6b60;
    font-style: italic;
    opacity: 1;
}

.eq-field input:focus,
.eq-field select:focus,
.eq-field textarea:focus {
    outline: 2px solid #96682a;
    outline-offset: 3px;
    border-bottom-color: #96682a;
}

/* Selects match the underline fields exactly, plus a small chevron — native
   <select>, no JS, so keyboard and screen-reader behaviour stay default. */
.eq-field select {
    cursor: pointer;
    padding-right: 20px;
    background-repeat: no-repeat;
    background-position: right center;
    background-size: 11px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2396682a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 8.5 L12 15.5 L19 8.5'/%3E%3C/svg%3E");
}

.eq-submit-row {
    display: flex;
    align-items: center;
    gap: 24px;
    margin-top: 10px;
    flex-wrap: wrap;
}

.eq-submit-note {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 13.5px;
    color: #7f6b60;
}

.ip-enquire-submit {
    font-family: 'Lora', Georgia, serif;
    font-size: 13px;
    letter-spacing: 0.19em;
    text-transform: uppercase;
    color: #fefae7;
    /* The navbar's gold (.site-navbar--plain), at the owners' request. */
    background: #8f6526;
    padding: 16px 40px;
    border: none;
    cursor: pointer;
}

.ip-enquire-submit:hover { background: #6f4e19; }

/* ---------- locations hub ---------- */

.ip-region-cards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 48px;
    align-items: start;
}

.ip-region-card {
    display: flex;
    flex-direction: column;
    gap: 20px;
    text-decoration: none;
}

.ip-region-card:focus-visible {
    outline: 2px solid #b88226;
    outline-offset: 4px;
}

.ip-region-card-image {
    position: relative;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background: #141110;
}

.ip-region-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ip-region-card-tbc {
    position: absolute;
    right: 10px;
    top: 10px;
    font-family: 'Lora', Georgia, serif;
    font-size: 10px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #fefae7;
    background: rgba(20, 17, 16, 0.55);
    padding: 4px 9px;
}

.ip-region-card-count {
    position: absolute;
    left: 0;
    bottom: 0;
    background: #fefae7;
    color: #b88226;
    font-family: 'Lora', Georgia, serif;
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    padding: 9px 16px;
}

.ip-region-card-text {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.ip-region-card-name {
    font-family: 'Seasons', Georgia, serif;
    font-size: 28px;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: #b88226;
}

.ip-region-card-blurb {
    font-family: 'Lora', Georgia, serif;
    font-size: 15.5px;
    line-height: 1.78;
    color: #836d63;
    margin: 0;
}

/* ---------- region page: venue rows ---------- */

.ip-venue-rows {
    display: flex;
    flex-direction: column;
}

.ip-venue-row,
.ip-venue-row-draft {
    display: grid;
    grid-template-columns: 300px 1fr auto;
    gap: 40px;
    align-items: center;
    padding: 30px 0;
    border-top: 1px solid rgba(131, 109, 99, 0.22);
    text-decoration: none;
}

.ip-venue-rows > div:last-child {
    border-top: 1px solid rgba(131, 109, 99, 0.22);
}

.ip-venue-row-draft {
    opacity: 0.85;
}

.ip-venue-row-cover,
.ip-venue-row-nocover {
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background: #141110;
}

.ip-venue-row-nocover {
    border: 1px dashed #c9924a;
    background: #f2e2c4;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ip-venue-row-nocover span {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 13px;
    color: #a8702f;
}

.ip-venue-row-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ip-venue-row-text {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.ip-venue-row-name {
    font-family: 'Seasons', Georgia, serif;
    font-size: 28px;
    letter-spacing: 0.07em;
    color: #5b4a41;
}

.ip-venue-row-draft .ip-venue-row-name {
    color: #a9927f;
}

.ip-venue-row-badge {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 14.5px;
    color: #a9927f;
}

.ip-venue-row-meta {
    font-family: 'Lora', Georgia, serif;
    font-size: 14px;
    color: #836d63;
}

.ip-venue-row-view {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: 'Lora', Georgia, serif;
    font-size: 12px;
    letter-spacing: 0.17em;
    text-transform: uppercase;
    color: #b88226;
}

.ip-empty-region {
    border: 1px dashed #c9924a;
    background: #f2e2c4;
    padding: 76px 60px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    text-align: center;
}

.ip-empty-region-title {
    font-family: 'Seasons', Georgia, serif;
    font-size: 30px;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: #a8702f;
}

.ip-empty-region p {
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    line-height: 1.78;
    color: #836d63;
    max-width: 560px;
    margin: 0;
}

/* ---------- venue page ---------- */

/* A venue page's heading band: the name and breadcrumb on the page's own
   cream, in the navbar's gold (#8f6526, which clears WCAG AA on #fefae7 —
   see .site-navbar--plain). It was a 400px cover photo with cream text over
   it until the owners asked for the photo to go. */
.ip-venue-cover {
    background: #fefae7;
    padding: 72px 130px 56px;
}

.ip-venue-cover-content {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.ip-venue-cover-title {
    font-family: 'Seasons', Georgia, serif;
    font-size: 42px;
    font-weight: 300;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: #8f6526;
    line-height: 1.05;
    margin: 0;
}

.ip-venue-cover-region {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 15px;
    color: #8f6526;
}

.ip-venue-intro-text {
    font-family: 'Lora', Georgia, serif;
    font-size: 19px;
    line-height: 1.78;
    color: #5b4a41;
    /* Was constrained by .ip-venue-intro-grid's own 1fr column (the removed
       Region/Type/Films/Photographs fact table sat in the other, 380px,
       column) — a direct max-width here instead, now that grid is gone. */
    max-width: 860px;
    margin: 0;
}

.ip-venue-films-grid {
    display: grid;
    gap: 56px;
}

.ip-venue-photos-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 28px;
}

.ip-venue-related-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 38px;
}

.ip-venue-related-card {
    display: flex;
    flex-direction: column;
    gap: 14px;
    text-decoration: none;
}

.ip-venue-related-card:focus-visible {
    outline: 2px solid #b88226;
    outline-offset: 4px;
}

.ip-venue-related-image {
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background: #141110;
}

.ip-venue-related-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ip-venue-related-couple {
    font-family: 'Seasons', Georgia, serif;
    font-size: 21px;
    letter-spacing: 0.06em;
    color: #5b4a41;
}

.ip-venue-related-location {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 13.5px;
    color: #a9927f;
}

/* ---------- packages (draft) ---------- */

.ip-packages-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 40px;
    align-items: stretch;
}

.ip-package-card {
    display: flex;
    flex-direction: column;
    gap: 22px;
    padding: 44px 38px;
    background: #ffffff;
    border: 1px solid rgba(131, 109, 99, 0.22);
}

.ip-package-card.ip-featured {
    background: #f2e2c4;
    border-color: #e3b978;
}

.ip-package-title {
    font-family: 'Seasons', Georgia, serif;
    font-size: 27px;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: #b88226;
}

.ip-package-text {
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    line-height: 1.78;
    color: #836d63;
    margin: 0;
}

.ip-package-price {
    font-family: 'Lora', Georgia, serif;
    font-size: 22px;
    font-weight: 600;
    color: #3a2f28;
}

.ip-package-price-note,
.ip-package-hours {
    font-family: 'Lora', Georgia, serif;
    font-size: 14px;
    font-style: italic;
    color: #a8702f;
    margin-top: -14px;
}

.ip-package-includes {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.ip-package-includes li {
    font-family: 'Lora', Georgia, serif;
    font-size: 15px;
    line-height: 1.5;
    color: #5b4a41;
    padding-left: 18px;
    position: relative;
}

.ip-package-includes li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 9px;
    width: 6px;
    height: 6px;
    background: #d19b32;
}

/* Region/venue long-form body copy (A2) and the digital/photography facts
   paragraphs (A5) share this shape — a narrower reading column than the
   full-width sections around it. */
.ip-body-paragraphs {
    display: flex;
    flex-direction: column;
    gap: 20px;
    max-width: 760px;
    margin-top: 28px;
}

.ip-body-paragraphs p {
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    line-height: 1.78;
    color: #5b4a41;
    margin: 0;
}

/* FAQ (A3/G1) */
.ip-faq-list {
    display: flex;
    flex-direction: column;
    gap: 28px;
    max-width: 760px;
}

.ip-faq-item {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.ip-faq-question {
    font-family: 'Lora', Georgia, serif;
    font-size: 18px;
    font-weight: 600;
    color: #3a2f28;
    margin: 0;
}

.ip-faq-answer {
    font-family: 'Lora', Georgia, serif;
    font-size: 15.5px;
    line-height: 1.7;
    color: #5b4a41;
    margin: 0;
}

/* Service/package-page reviews (A6/G7) reuse the homepage's own
   .hp-testimonial-card markup so a review looks identical everywhere it
   appears; this just gives it a static (non-rail) grid to sit in. */
/* All of a page's reviews sit on one line at desktop widths. It was capped at
   900px with 280px-minimum columns, which only ever fitted two across, so a
   third review dropped to a second row however wide the screen. Now it spans
   the content width like the three-column block above it: up to three reviews
   take a third each, lined up with those columns, and a fourth or more share
   the row equally (see the :has rule below) rather than wrapping. */
.ip-reviews-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 52px;
    align-items: start;
}

.ip-reviews-grid:has(> :nth-child(4)),
.hp-testimonials-grid:has(> :nth-child(4)) {
    grid-template-columns: none;
}

/* Region and venue pages: one or two reviews are centred, each as wide as a
   third of the grid, instead of sitting in its left-hand columns. Empty
   tracks collapse (auto-fit), so three fill the row as they do elsewhere, and
   a fourth or more still share it through the :has rule above. */
.ip-reviews-grid--centred {
    grid-template-columns: repeat(auto-fit, calc((100% - 104px) / 3));
    justify-content: center;
}

/* A page with a single review shows all of it, so it gets a comfortable
   reading width, centred, rather than a third of the row. */
.ip-reviews-grid--single {
    grid-template-columns: minmax(0, 760px);
    justify-content: center;
}

/* Written as `> *`, not `p`, so the spacing rule just below (the same
   strength, and later) wins. As `.hp-testimonial-full p` it outranked
   `> * + *`, and a whole review's paragraphs ran together with no gap. */
.hp-testimonial-full > * {
    margin: 0;
}

.hp-testimonial-full > * + * {
    margin-top: 1em;
}

.hp-testimonial-full p + ul {
    margin-top: 0.6em;
}

/* A list the reviewer typed with dashes: a small gold dot in place of the
   dash, and a hanging indent so a point that wraps lines up under its own
   first word, not under the dot. */
.hp-testimonial-full ul {
    list-style: none;
    margin-bottom: 0;
    padding: 0;
}

.hp-testimonial-full li {
    position: relative;
    padding-left: 1.5em;
}

.hp-testimonial-full li + li {
    margin-top: 0.4em;
}

.hp-testimonial-full li::before {
    content: "";
    position: absolute;
    left: 0.45em;
    top: calc(0.875em - 2.5px);
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #d19b32;
}

.ip-location-reviews-heading {
    font-size: 26px;
    margin-bottom: 28px;
    text-align: center;
}

@media (max-width: 900px) {
    .ip-reviews-grid {
        grid-template-columns: 1fr;
        grid-auto-flow: row;
        gap: 40px;
    }
}

@media (max-width: 900px) {
    .ip-header,
    .ip-header-reel,
    .ip-section,
    .ip-section-reel,
    .ip-section-white { padding: 56px 24px; }
    .ip-strip-wrap { margin: 0 -24px; width: calc(100% + 48px); }
    .ip-h1-reel { font-size: 32px; }
    .ip-h1 { font-size: 30px; }
    .ip-cols3,
    .ip-about-grid,
    .ip-region-cards,
    .ip-venue-films-grid,
    .ip-venue-related-grid,
    .ip-packages-grid { grid-template-columns: 1fr; }
    .ip-venue-photos-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ip-enquire-heading { font-size: 38px; }
    .eq-row { flex-direction: column; gap: 22px; }
    .eq-field input,
    .eq-field select,
    .eq-field textarea { min-height: 46px; }
    .ip-enquire-submit { min-height: 52px; display: flex; align-items: center; justify-content: center; }
    .ip-venue-row,
    .ip-venue-row-draft { grid-template-columns: 1fr; gap: 16px; }
    /* The couple name at its full 34px plus the "01 / 06" position count
       don't both fit one row at phone widths — shrink and tighten rather
       than let the count wrap character-by-character. */
    .ip-stage-caption { padding: 16px 18px; gap: 12px; }
    .ip-stage-couple { font-size: 20px; }
    .ip-stage-location { font-size: 12px; }
    .ip-stage-count { font-size: 9px; letter-spacing: 0.12em; }

    /* ---------- videography / super-8-wedding-films: swap the desktop
       stage+thumbnail-rail (hover-crossfade — no hover on a phone, so
       nothing here to port) for the same full-card rail the homepage's own
       digital-films/Super-8 sections use — .ip-mobile-rail wraps a second
       markup block (videography.njk/super-8-wedding-films.njk) built from
       hp-film-cell/hp-super8-cell, hidden above this breakpoint by the
       inverse rule further down. Reusing those classes directly rather than
       inventing ip- equivalents of a component that's otherwise pixel-
       identical — the actual new class here is only the wrapper. ---------- */
    /* #filmStage, not the bare .ip-stage class — that class is reused
       unrelated on venue pages (_venue.njk's own film cards), which must
       stay visible and untouched here. */
    #filmStage,
    #filmRail,
    .ip-strip-wrap { display: none; }
    .ip-mobile-rail {
        display: flex;
        gap: 14px;
        margin-left: -24px;
        margin-right: -24px;
        padding: 0 24px;
        scroll-padding-left: 24px;
    }

    /* ---------- photography service page: the existing contact-sheet grid
       becomes the same rail mechanic, its own tiles unchanged. ---------- */
    .ip-contact-grid {
        display: flex;
        gap: 14px;
        margin-left: -24px;
        margin-right: -24px;
        padding: 0 24px;
        scroll-padding-left: 24px;
    }
    .ip-contact-tile { flex: none; width: 250px; }

    /* ---------- venue pages ---------- */
    .ip-venue-cover { padding: 48px 24px 36px; }
    .ip-venue-cover-title { font-size: 30px; }
}

/* Enquiry anti-spam field is available to form parsers but never enters the
   visual or keyboard flow. It is checked before any request is sent, and
   again by /api/enquiry. */
.enquiry-honeypot {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
    clip: rect(0 0 0 0) !important;
    clip-path: inset(50%) !important;
    white-space: nowrap !important;
}

/* ---------- Bootstrap CSS replacement (S9/C6) ----------
   The Bootstrap CDN stylesheet (~230KB) was loading for exactly one thing:
   the video modal (partials/video-modal.njk) and its own handful of utility
   classes. Every class that markup actually uses — checked by tokenizing
   every class="" attribute in site/_includes and matching against real
   Bootstrap 5.3 class names, not a substring count — is reproduced below.
   Nothing else in the codebase depends on Bootstrap's CSS at all (there is
   no .row/.col grid usage and no Bootstrap .navbar/.btn anywhere; the
   site's own navbar and buttons are unrelated custom classes that merely
   contain those words). The Bootstrap JS bundle stays, unchanged, on the
   CDN — it still does everything it always did (toggling .show/.fade,
   creating the backdrop, focus trap, Escape/outside-click, aria wiring);
   only the CSS that gives those states a visual effect moved here. */
.visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

.fade { transition: opacity .15s linear; }
.fade:not(.show) { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
    .fade { transition: none; }
}

.modal {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1055;
    display: none;
    width: 100%;
    height: 100%;
    overflow-x: hidden;
    overflow-y: auto;
    outline: 0;
}

.modal-dialog {
    position: relative;
    width: auto;
    margin: .5rem;
    pointer-events: none;
    transition: transform .3s ease-out;
    transform: translate(0, -50px);
}
.modal.show .modal-dialog { transform: none; }
@media (prefers-reduced-motion: reduce) {
    .modal-dialog { transition: none; }
}
@media (min-width: 576px) {
    .modal-dialog { max-width: 500px; margin: 1.75rem auto; }
    .modal-dialog-centered { min-height: calc(100% - 3.5rem); }
}

.modal-dialog-centered {
    display: flex;
    align-items: center;
    min-height: calc(100% - 1rem);
}

@media (min-width: 992px) {
    .modal-lg { max-width: 800px; }
}

.modal-content {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    pointer-events: auto;
    background-color: #fff;
    background-clip: padding-box;
    border: 1px solid rgba(0, 0, 0, .2);
    border-radius: .5rem;
    outline: 0;
}

.modal-header {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: space-between;
    padding: 1rem;
    border-bottom: 1px solid #dee2e6;
    border-top-left-radius: calc(.5rem - 1px);
    border-top-right-radius: calc(.5rem - 1px);
}

.modal-title { margin-bottom: 0; line-height: 1.5; }

.modal-body {
    position: relative;
    flex: 1 1 auto;
    padding: 1rem;
}

.bg-dark { background-color: #212529 !important; }
.border-0 { border: 0 !important; }
.py-2 { padding-top: .5rem !important; padding-bottom: .5rem !important; }
.p-0 { padding: 0 !important; }

.btn-close {
    box-sizing: content-box;
    width: 1em;
    height: 1em;
    padding: .25em;
    color: #000;
    background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center / 1em auto no-repeat;
    border: 0;
    border-radius: .375rem;
    opacity: .5;
}
.btn-close:hover { color: #000; text-decoration: none; opacity: .75; }
.btn-close:focus { outline: 0; box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25); opacity: 1; }
.btn-close-white { filter: invert(1) grayscale(100%) brightness(200%); }

.ratio {
    position: relative;
    width: 100%;
}
.ratio::before { display: block; padding-top: var(--bs-aspect-ratio); content: ""; }
.ratio > * { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.ratio-16x9 { --bs-aspect-ratio: 56.25%; }

.modal-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1050;
    width: 100vw;
    height: 100vh;
    background-color: #000;
}
.modal-backdrop.fade { opacity: 0; }
.modal-backdrop.show { opacity: .5; }

/* Set by Bootstrap's JS on <body> while a modal is open, to stop the page
   scrolling behind it. */
.modal-open { overflow: hidden; }


/* Homepage intro, pull-quotes, About block and the Google reviews line.
   These render copy that lived in content/pages/home.json and
   settings.testimonials but was never referenced by a template — see
   tests/reachability.test.cjs, which now fails the build if authored copy
   stops reaching its route. */
.hp-intro {
    max-width: 46ch;
    margin: 0 auto;
    padding: 56px 24px 0;
    text-align: center;
    font-family: Lora, Georgia, serif;
    font-size: 19px;
    line-height: 1.65;
    color: #6f5d54;
}
.hp-quote {
    max-width: 40ch;
    margin: 0 auto;
    padding: 64px 24px;
    text-align: center;
    font-family: 'The Seasons', Georgia, serif;
    font-size: clamp(1.25rem, 2.4vw, 1.75rem);
    line-height: 1.5;
    color: #8f6526;
}
.hp-about-grid {
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: 56px;
    align-items: center;
}
.hp-about-text p {
    font-family: Lora, Georgia, serif;
    font-size: 16px;
    line-height: 1.75;
    color: #6f5d54;
}
.hp-about-photo img {
    width: 100%;
    height: auto;
    display: block;
}
.hp-reviews-line {
    margin-top: 28px;
    text-align: center;
    font-family: Lora, Georgia, serif;
    font-size: 14px;
    color: #6f5d54;
}
.hp-reviews-line a {
    color: #8f6526;
    border-bottom: 1px solid #d19b32;
    text-decoration: none;
}
.hp-reviews-rating { color: #8f6526; }
@media (max-width: 900px) {
    .hp-about-grid { grid-template-columns: 1fr; gap: 32px; }
    .hp-quote { padding: 44px 24px; }
    .hp-intro { padding-top: 40px; font-size: 17px; }
}

/* Page eyebrow and the service pages' body block — both authored in
   content/pages/*.json (copy.eyebrow, copy.bodyHeading, copy.paragraphs)
   and previously unrendered. */
.ip-eyebrow {
    font-family: Lora, Georgia, serif;
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: #8f6526;
    margin: 0 0 12px;
}
.ip-body-block {
    max-width: 62ch;
    margin: 0 auto;
}
.ip-body-block p {
    font-family: Lora, Georgia, serif;
    font-size: 16px;
    line-height: 1.75;
    color: #6f5d54;
}
.ip-venue-cover-badge {
    display: inline-block;
    margin-bottom: 10px;
    font-family: Lora, Georgia, serif;
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #d19b32;
}

/* ---------- CTA layer (Task 2, docs/SITE_REVIEW_ACTIONS.md) ---------- */
/* Variants A/B: full-width closing band. Dark background, cream text — the
   same "closer" tone .ip-gallery-teaser already uses on Photography,
   extended sitewide rather than invented fresh. */
/* The CTA. One component sitewide — see partials/cta-band.njk for why this
   is a link on the page's own background rather than the filled button on a
   solid #30251f band it replaced. Matches the section links elsewhere on the
   site: letterspaced serif caps over a hairline gold underline. */
.cta {
    padding: 76px 24px 84px;
    text-align: center;
}
.cta-link {
    display: inline-block;
    font-family: Lora, Georgia, serif;
    font-size: 12.5px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: #8f6526;
    text-decoration: none;
    padding-bottom: 6px;
    border-bottom: 1px solid #d19b32;
    transition: color 0.25s ease, border-color 0.25s ease;
}
.cta-link:hover { color: #6f4e19; border-bottom-color: #6f4e19; }
.cta-link:focus-visible { outline: 2px solid #d19b32; outline-offset: 6px; }
@media (max-width: 900px) {
    .cta { padding: 56px 24px 62px; }
}
@media (prefers-reduced-motion: reduce) {
    .cta-link { transition: none; }
}


/* Cloudflare Turnstile's box on the enquiry forms. It is hidden unless a
   visitor has to tick it, so it only takes space when it has something in it. */
.enquiry-turnstile:not(:empty) {
    margin: 4px 0 16px;
}
