/* Theme */
@font-face {
    /* fonts/theseasons-reg.otf — commercial web-font license confirmed (Laurence, 31 Aug 2026). */
    font-family: 'Seasons';
    src: url('../fonts/theseasons-reg.otf') format('opentype');
    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 {
    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 {
    /* Chunk 16: this is a real <button> now (was a <div>, unreachable by
       keyboard). Reset the global `button` rule above — its margin/background/
       padding/border-radius were never meant for an 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 play controls must reveal themselves — the hover rule
   above only shows them for a mouse over the containing column, which a
   keyboard user tabbing to the button never triggers.
   Review fix C1 — a genuine two-colour indicator per WCAG technique C40:
   https://www.w3.org/WAI/WCAG21/Techniques/css/C40. Three adjacent bands
   with no gap between them — black 0-2px, white 2-4px, black 4-6px from
   the button edge — so the white band is enclosed by black on both sides.
   Two single-colour rings were tried and measured first (white-only, then
   black-only outer): both failed WCAG 1.4.11's 3:1 non-text-contrast
   minimum against real Cloudinary film covers, because a flat colour only
   ever helps the half of the tonal range it contrasts with, and these
   photos have both bright and dark content near the button's fixed
   position. C40 solves this with two colours >=9:1 apart (here, 21:1):
   for ANY single background colour, at least one of white/black is
   guaranteed >=3:1 against it (contrast(white,L)>=3 whenever L<=0.30;
   contrast(black,L)>=3 whenever L>=0.10 — those ranges cover the entire
   [0,1] luminance interval between them). C40 explicitly disclaims image
   backgrounds and calls for a pixel-by-pixel check instead of assuming its
   closed-form guarantee transfers — done in artifacts/measure-focus-
   contrast.cjs (committed, with its raw output, so this is independently
   reproducible): sampling each band's local photo colour and taking the
   best of contrast(white, local) vs contrast(black, local) across all 11
   covers checked, the worst point on any cover was 4.85:1, comfortably
   over 3:1, with zero points below 3:1 anywhere. See docs/PROGRESS.md. */
.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%;
}



form {
    max-width: 750px;
    margin: 0 auto;
    padding: 25px 20px;
    border-radius: 12px;
    background: #fefae7;
    display: flex;
    flex-direction: column;
    gap: 15px;
}


form label {
    display: flex;
    flex-direction: column;
    font-size: 0.95rem;
    color: #333;
}


form input[type="text"],
form input[type="email"],
form input[type="tel"],
form input[type="date"],
form select {
    border: 1px solid #ccc;
    border-radius: 6px;
    padding: 8px 10px;
    font-size: 0.9rem;
    outline: none;
    transition: border-color 0.3s;
    font-family: 'Lora', serif;
    background-color: #fff;
    width: 100%;
}

form input:focus,
form select:focus {
    border-color: #d19b32;
}


form button {
    margin-top: 10px;
    background-color: #d19b32;
    color: #fff;
    border: none;
    padding: 10px 18px;
    font-size: 0.95rem;
    font-weight: 500;
    cursor: pointer;
    border-radius: 6px;
    transition: background 0.3s;
}

form button:hover {
    background-color: #b88226;
}

.success-message {
    display: none;
    padding: 20px;
    background-color: #4CAF50;
    color: white;
    margin-bottom: 20px;
    border-radius: 5px;
    text-align: center;
}

.success-message.show {
    display: block;
}

.error-message {
    display: none;
    padding: 20px;
    background-color: #f44336;
    color: white;
    margin-bottom: 20px;
    border-radius: 5px;
    text-align: center;
}

.error-message.show {
    display: block;
}

@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 samples slideshow (variant C) — gradient swatches stand in for real photography
   until real assets are supplied; see the NOTE above #photosamples in index.template.html. */
.photo-slideshow {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 32px;
}

.slideshow-viewport {
    overflow: hidden;
    width: 100%;
    max-width: 960px;
}

.slideshow-track {
    display: flex;
    width: 300%;
    transition: transform 0.55s cubic-bezier(0.65, 0, 0.35, 1);
}

.slideshow-page {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 18px;
    width: 33.3333%;
    flex: 0 0 auto;
}

.photo-swatch {
    aspect-ratio: 1 / 1;
    border-radius: 3px;
    background:
        repeating-linear-gradient(115deg, rgba(255, 255, 255, .06) 0 2px, transparent 2px 26px),
        linear-gradient(135deg, #a9927f, #8a7360 45%, #6f5a49);
}

.photo-swatch.photo-swatch-warm {
    background:
        repeating-linear-gradient(115deg, rgba(255, 255, 255, .07) 0 2px, transparent 2px 26px),
        linear-gradient(135deg, #e3b978, #c9924a 50%, #a8702f);
}

.photo-swatch.photo-swatch-deep {
    background:
        repeating-linear-gradient(115deg, rgba(255, 255, 255, .05) 0 2px, transparent 2px 26px),
        linear-gradient(135deg, #7a6552, #5f4d3d 50%, #453629);
}

.slideshow-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 17.6px;
    height: 44px;
    flex: 0 0 auto;
    padding: 0;
    border: none;
    border-radius: 4px;
    background-color: transparent;
    color: #fab949;
    cursor: pointer;
    transition: background-color 0.3s, color 0.3s;
}

.slideshow-arrow svg {
    width: 18px;
    height: 18px;
    display: block;
    flex-shrink: 0;
}

.slideshow-arrow:hover {
    background-color: #d19b32;
    color: #fff;
}

.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;
}

.slideshow-dots {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-top: 20px;
}

.slideshow-dots .dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background-color: #fab949;
    cursor: pointer;
}

.slideshow-dots .dot.active {
    outline: 1.5px solid #fab949;
    outline-offset: 3px;
}

@media (max-width: 576px) {
    .photo-slideshow {
        gap: 10px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .slideshow-track {
        transition: none;
    }
}

/* ===== Site-wide footer =====
   Single compact footer, every route — replaces the previous split between
   an inner-pages footer (partials/footer.njk, deleted) and a larger
   four-column homepage-only footer (partials/hp-footer.njk, deleted). See
   partials/site-footer.njk for the markup and the guarding rationale.

   --footer-gold holds the one gold value the wordmark and both social-icon
   SVGs share (set once here, read everywhere below) rather than repeating
   the hex twice; .site-footer-social-link overrides it locally on hover/
   focus so the icon recolours without a second rule needing to agree with
   the first. 130px/24px side padding matches every other section's own
   literal gutter value — this codebase has no shared spacing custom
   property to reference instead (checked before adding one single-use here
   would be inconsistent with how the rest of the file already does this). */
.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 redesign — approved mockup at design-explorations/canvas/home.
   Scoped to the homepage only (see docs/PROGRESS.md): every class below is
   prefixed hp- specifically so it cannot collide with or be affected by
   any existing selector, and none of the .area-, .p-text- or .logo-title
   rules above apply here. Exact values (padding, letter-spacing, sizes, colours)
   are taken directly from the mockup, not rounded to a grid. Values are
   locked to the existing palette (see css/style.css's own colours above);
   only NEW tints are #f2e2c4 (sand-light), #e4d9b8 (sand), #a8702f
   (gold-deep-dark), #e3b978 (gold-light), #fab949 (gold-bright), #c9924a
   (gold-mid), #887367 (ink2), #5b4a41 (ink-deep), #141110 (film-gate black)
   — all tints/shades of hues already in use, per the handoff's own
   "palette is locked" rule.
   ===================================================================== */

.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,
.hp-standin-rail,
.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-drawer-cta {
        margin-top: auto;
        flex: none;
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 50px;
        background: #d19b32;
        color: #fefae7;
        font-family: 'Lora', Georgia, serif;
        font-size: 12.5px;
        letter-spacing: 0.19em;
        text-transform: uppercase;
        text-decoration: none;
    }
    .site-mobile-burger:focus-visible,
    .site-drawer-close:focus-visible,
    .site-drawer-links a:focus-visible,
    .site-drawer-cta: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;
    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));
    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;
}

/* ---------- enquiry ---------- */

.hp-enquiry {
    background: #f2e2c4;
    padding: 84px 110px;
}

.hp-enquiry-inner {
    display: flex;
    flex-direction: column;
    gap: 34px;
    max-width: 940px;
    margin: 0 auto;
}

.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: 38px;
    font-weight: 300;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #b88226;
    line-height: 1.15;
    margin: 0;
}

.hp-enquiry-intro {
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    line-height: 1.78;
    color: #836d63;
    max-width: 520px;
    margin: 0;
}

.hp-enquiry-fields {
    display: flex;
    gap: 40px;
}

.hp-enquiry-field {
    display: flex;
    flex-direction: column;
    gap: 9px;
    flex: 1 1 0;
}

.hp-enquiry-field span {
    font-family: 'Lora', Georgia, serif;
    font-size: 11.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #887367;
    line-height: 1.5;
}

.hp-enquiry-field input {
    border: none;
    border-bottom: 1px solid #c9924a;
    padding-bottom: 11px;
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    color: #5b4a41;
    background: transparent;
    min-height: 26px;
    width: 100%;
}

.hp-enquiry-field input::placeholder {
    color: #a9927f;
    font-style: italic;
    opacity: 1;
}

.hp-enquiry-field input:focus {
    outline: none;
    border-bottom-color: #b88226;
}

.hp-enquiry-actions {
    display: flex;
    gap: 20px;
    align-items: center;
    justify-content: center;
    margin-top: 8px;
    flex-wrap: wrap;
}

.hp-enquiry-submit {
    font-family: 'Lora', Georgia, serif;
    font-size: 13px;
    letter-spacing: 0.19em;
    text-transform: uppercase;
    color: #fefae7;
    background: #d19b32;
    padding: 16px 42px;
    border: none;
    cursor: pointer;
}

.hp-enquiry-submit:hover { background: #b88226; }

.hp-enquiry-fallback {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 13.5px;
    color: #a9927f;
}

.hp-enquiry-fallback a { color: #a9927f; }

@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; }
    .hp-photo-viewport { 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. */
    .hp-standin-rail {
        gap: 14px;
        margin-left: -24px;
        margin-right: -24px;
        padding: 0 24px;
        scroll-padding-left: 24px;
    }
    .hp-standin-cell { flex: none; width: 250px; scroll-snap-align: start; position: relative; aspect-ratio: 4 / 5; overflow: hidden; background: #141110; }
    .hp-standin-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
    .hp-standin-badge {
        position: absolute; left: 9px; bottom: 9px;
        font-family: 'Lora', Georgia, serif; font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase;
        color: #fefae7; background: rgba(20, 17, 16, 0.55); padding: 4px 7px; border: 1px dashed rgba(254, 250, 231, 0.6);
    }
    /* 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. */
    .photo-slideshow, .slideshow-dots { display: none; }

    /* 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 { min-height: 52px; padding: 0 42px; display: flex; align-items: center; justify-content: center; }
}

@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 redesign - approved mockups at design-explorations/canvas/pages.
   Twelve routes: videography, super-8-wedding-films, photography, about,
   enquire, packages, the locations hub, three region pages and two venue
   pages. Every class is prefixed ip- (inner pages), the same isolation
   discipline as the homepage's hp- prefix, and for the same reason: it
   cannot collide with or be affected by anything above it. These pages
   keep the site's existing shared navbar and footer (partials/site-navbar.njk,
   partials/site-footer.njk) unchanged - only each page's own body content is
   new here.
   Two families, per the handoff: videography/super8/photography share one
   skeleton (a 68px h1 band, then the page's own treatment, then a white
   3-column band) and come from a different design direction (the Reel);
   everything else is a 54px h1 with 96px/130px section padding (Fullscreen
   Hero). Header/section padding for the fullscreen-hero family is
   deliberately consistent across all its pages (96px 130px) rather than
   chasing the small per-page variation in the source generator - that
   variation reads as authoring noise, not a deliberate per-page spec.
   ===================================================================== */

.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;
}

.ip-section {
    background: #fefae7;
    padding: 60px 130px;
}

/* Reel family (videography/super8/photography) middle band — HANDOFF-PAGES.md
   gives this an exact, different padding (110px) from the Fullscreen Hero
   family's default (96px) used everywhere else, so it gets its own class
   rather than sharing .ip-section. */
.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 {
    font-family: 'Seasons', Georgia, serif;
    font-size: 22px;
    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;
    background: #141110;
    padding: 16px 0 18px;
    overflow: hidden;
}

.ip-strip-sprockets {
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 14px;
}

.ip-strip-sprockets span {
    width: 22px;
    height: 13px;
    border-radius: 2px;
    background: #f2e2c4;
    display: block;
    flex: none;
}

.ip-strip-viewport {
    overflow: hidden;
    padding: 12px 0;
}

.ip-strip-track {
    display: flex;
    gap: 10px;
    width: max-content;
    will-change: transform;
    animation: ip-strip-scroll 48s linear infinite;
}

.ip-strip-wrap:hover .ip-strip-track,
.ip-strip-wrap:focus-within .ip-strip-track {
    animation-play-state: paused;
}

@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;
}

.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: contact-sheet grid ---------- */

.ip-contact-grid {
    display: grid;
    /* 8 columns, not 4 — at 4 (2 rows for the 8 stand-ins) the grid ran
       past a 1080p Chrome window on its own; one row fits the header and
       every tile on screen together. */
    grid-template-columns: repeat(8, minmax(0, 1fr));
    gap: 16px;
}

.ip-contact-tile {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.ip-contact-frame {
    position: relative;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    background: #141110;
}

.ip-contact-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ip-contact-select {
    position: absolute;
    inset: 6px;
    border: 2px solid #fab949;
    pointer-events: none;
}

.ip-contact-meta {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}

.ip-contact-num {
    font-family: 'Lora', Georgia, serif;
    font-size: 10px;
    letter-spacing: 0.16em;
    color: #a9927f;
}

.ip-contact-standin {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 10px;
    color: #a8702f;
}

/* ---------- shared pending/dashed notice, e.g. photography-pending ---------- */

.ip-notice {
    display: inline-flex;
    gap: 10px;
    align-items: center;
    border: 1px dashed #a8702f;
    padding: 10px 14px;
    background: rgba(254, 250, 231, 0.7);
    align-self: flex-start;
}

.ip-notice span {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 12.5px;
    color: #a8702f;
}

/* ---------- 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;
}

.ip-about-photo-frame {
    position: absolute;
    inset: -20px -20px 20px 20px;
    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 ---------- */

.ip-enquire-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 70px;
    align-items: start;
}

.ip-enquire-info {
    display: flex;
    flex-direction: column;
    gap: 26px;
}

.ip-enquire-info p {
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    line-height: 1.7;
    color: #836d63;
    margin: 0;
}

.ip-enquire-contact {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 14px;
    border-top: 1px solid #e3b978;
    padding-top: 26px;
}

.ip-enquire-contact span {
    font-family: 'Lora', Georgia, serif;
    font-size: 15px;
    color: #836d63;
}

.ip-enquire-panel {
    background: #f2e2c4;
    padding: 52px 54px;
}

.ip-enquire-fields-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 32px 36px;
}

.ip-enquire-field {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.ip-enquire-field.ip-wide {
    grid-column: span 2;
}

.ip-enquire-field span {
    font-family: 'Lora', Georgia, serif;
    font-size: 11.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #887367;
    line-height: 1.5;
}

/* Gold asterisk marking the first three (real) required fields, plus the
   "* Required" note beside the submit button — one shared class so both
   read as the same mark rather than two different golds. Decorative
   (aria-hidden) in both places: the two fields that are genuinely
   HTML-required already announce that themselves via the required
   attribute; the third (wedding date) is a soft ask, not enforced, so it
   gets the same visual nudge without a false aria-required claim. */
.ip-required-mark {
    color: #b88226;
    text-transform: none;
    letter-spacing: normal;
    margin-left: 2px;
}

.ip-enquire-note .ip-required-mark {
    margin-left: 0;
    margin-right: 3px;
}

.ip-enquire-field input {
    border: none;
    border-bottom: 1px solid #c9924a;
    padding-bottom: 12px;
    font-family: 'Lora', Georgia, serif;
    font-size: 16px;
    color: #5b4a41;
    background: transparent;
    min-height: 26px;
    width: 100%;
}

.ip-enquire-field input::placeholder {
    color: #a9927f;
    font-style: italic;
    opacity: 1;
}

.ip-enquire-field input:focus {
    outline: none;
    border-bottom-color: #b88226;
}

.ip-enquire-actions {
    margin-top: 38px;
    display: flex;
    gap: 18px;
    align-items: center;
    flex-wrap: wrap;
}

.ip-enquire-submit {
    font-family: 'Lora', Georgia, serif;
    font-size: 13px;
    letter-spacing: 0.19em;
    text-transform: uppercase;
    color: #fefae7;
    background: #d19b32;
    padding: 16px 40px;
    border: none;
    cursor: pointer;
}

.ip-enquire-submit:hover { background: #b88226; }

.ip-enquire-note {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 13px;
    color: #a9927f;
}

/* ---------- 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 ---------- */

.ip-venue-cover {
    position: relative;
    width: 100%;
    height: 400px;
    overflow: hidden;
    background: #141110;
}

.ip-venue-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ip-venue-cover-scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(20, 17, 16, 0.16), rgba(20, 17, 16, 0.6));
}

.ip-venue-cover-content {
    position: absolute;
    left: 130px;
    bottom: 58px;
    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: #fefae7;
    line-height: 1.05;
    margin: 0;
}

.ip-venue-cover-region {
    font-family: 'Lora', Georgia, serif;
    font-style: italic;
    font-size: 15px;
    color: rgba(254, 250, 231, 0.82);
}

.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;
}

@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-enquire-grid,
    .ip-enquire-fields-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-field.ip-wide { grid-column: span 1; }
    .ip-enquire-field input,
    .ip-enquire-field textarea { min-height: 46px; }
    .ip-enquire-submit { min-height: 52px; }
    .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 { height: 260px; }
    .ip-venue-cover-content { left: 24px; right: 24px; bottom: 20px; }
    .ip-venue-cover-title { font-size: 30px; }
}

@media (prefers-reduced-motion: reduce) {
    .ip-strip-track { animation: none !important; transform: none !important; }
}

/* Enquiry anti-spam field is available to form parsers but never enters the
   visual or keyboard flow. It is checked before any EmailJS request. */
.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;
}

.enquiry-privacy {
    margin: 12px 0 0;
    max-width: 62ch;
    color: #745f50;
    font-family: 'Lora', Georgia, serif;
    font-size: 0.75rem;
    line-height: 1.55;
}
