/* ==========================================================================
   THOMAS BEACH PHOTOGRAPHY — DESIGN SYSTEM
   Editorial / fine-art portfolio. Static. No build step.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
:root {
    /* Color — warm bone page, cool near-black ink, brass as the only accent */
    --ink-100: #FBFAF7;          /* page background (warm bone) */
    --ink-95:  #F2EFE8;          /* tonal section background */
    --ink-90:  #E6E2D8;          /* hairlines on light surfaces */
    --ink-30:  #6E6A62;          /* muted text (~4.7:1 on ink-100) */
    --ink-20:  #3F3D3A;          /* secondary text */
    --ink-10:  #1A1B1E;          /* primary ink (cool, slight blue) */
    --ink-05:  #111214;          /* deeper ink for dark surfaces */
    --ink-00:  #0B0C0E;          /* near-black */

    --accent:        #B8956A;    /* warm brass */
    --accent-soft:   #D4B68A;    /* lighter brass for backgrounds */
    --accent-deep:   #8E6E48;    /* hover/active brass */

    /* Semantic */
    --bg:        var(--ink-100);
    --bg-muted:  var(--ink-95);
    --rule:      var(--ink-90);
    --text:      var(--ink-10);
    --text-muted:var(--ink-30);
    --text-soft: var(--ink-20);

    /* Typography */
    --font-display: 'Fraunces', 'Cormorant Garamond', 'Times New Roman', serif;
    --font-sans:    'Inter Tight', 'Inter', system-ui, -apple-system, sans-serif;
    --font-mono:    'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;

    /* Type scale */
    --t-eyebrow:  0.6875rem;     /* 11px */
    --t-caption:  0.75rem;       /* 12px */
    --t-small:    0.8125rem;     /* 13px */
    --t-body:     1.0625rem;     /* 17px */
    --t-lede:     1.3125rem;     /* 21px */
    --t-h4:       clamp(1.25rem, 1.6vw, 1.5rem);
    --t-h3:       clamp(1.75rem, 3vw, 2.5rem);
    --t-h2:       clamp(2.5rem, 5vw, 4.5rem);
    --t-display:  clamp(3.5rem, 9vw, 9rem);

    /* Tracking presets */
    --track-eyebrow: 0.18em;
    --track-display: -0.02em;
    --track-tight:   -0.01em;

    /* Spacing — 8px grid */
    --space-1:  0.25rem;
    --space-2:  0.5rem;
    --space-3:  0.75rem;
    --space-4:  1rem;
    --space-5:  1.5rem;
    --space-6:  2rem;
    --space-7:  3rem;
    --space-8:  4rem;
    --space-9:  6rem;
    --space-10: 8rem;
    --space-11: 12rem;

    /* Layout */
    --container: 1440px;
    --container-wide: 1680px;
    --container-narrow: 920px;
    --container-prose: 640px;
    --gutter: clamp(1rem, 4vw, 2.5rem);

    /* Motion */
    --ease-out-expo:    cubic-bezier(0.19, 1, 0.22, 1);
    --ease-out-quart:   cubic-bezier(0.25, 1, 0.5, 1);
    --ease-in-out-soft: cubic-bezier(0.65, 0, 0.35, 1);

    --d-1: 200ms;
    --d-2: 400ms;
    --d-3: 700ms;
    --d-4: 1000ms;

    /* Surface */
    --radius-card: 2px;
    --radius-pill: 999px;
    --radius-modal: 8px;

    /* Shadow — used sparingly */
    --shadow-soft: 0 24px 60px -28px rgba(11, 12, 14, 0.18);
    --shadow-lift: 0 40px 80px -32px rgba(11, 12, 14, 0.24);

    /* Nav */
    --nav-height: 84px;
    --nav-height-condensed: 64px;
}

/* --------------------------------------------------------------------------
   2. RESET & BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
    font-size: 16px;
    -webkit-text-size-adjust: 100%;
    text-rendering: optimizeLegibility;
    scroll-behavior: smooth;
    /* Pair with `body { overflow-x: hidden }` below — iOS Safari otherwise
       still permits horizontal scroll on wide elements even when body clips,
       because the html element is the actual scroll container. */
    overflow-x: hidden;
}

body {
    font-family: var(--font-sans);
    font-size: var(--t-body);
    font-weight: 400;
    line-height: 1.6;
    color: var(--text);
    background-color: var(--bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;
    font-feature-settings: 'ss01', 'cv11';
}

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

/* Smooth-scroll anchor target. The fixed nav covers the top of #main when
   "scrollIntoView" lands at exact y=0; scroll-margin-top backs the anchor off
   by the nav height so the section heading isn't tucked under the bar. */
:target, #main { scroll-margin-top: var(--nav-height); }

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

button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}

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

::selection { background: var(--accent); color: var(--bg); }

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

/* --------------------------------------------------------------------------
   3. TYPOGRAPHY
   -------------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    font-weight: 300;
    line-height: 1.05;
    letter-spacing: var(--track-tight);
    color: var(--text);
    font-feature-settings: 'ss01';
}

h1 { font-size: var(--t-h2); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-h4); }

.display {
    font-family: var(--font-display);
    font-weight: 300;
    font-size: var(--t-display);
    line-height: 0.96;
    letter-spacing: var(--track-display);
    font-variation-settings: 'opsz' 144, 'SOFT' 100;
}

.eyebrow {
    font-family: var(--font-mono);
    font-size: var(--t-eyebrow);
    font-weight: 500;
    letter-spacing: var(--track-eyebrow);
    text-transform: uppercase;
    color: var(--text-muted);
}

.eyebrow--accent { color: var(--accent); }
.eyebrow--light  { color: rgba(255, 255, 255, 0.78); }

.lede {
    font-family: var(--font-display);
    font-weight: 300;
    font-size: var(--t-lede);
    line-height: 1.45;
    color: var(--text-soft);
    letter-spacing: -0.005em;
}

.mono {
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.prose {
    max-width: var(--container-prose);
    margin: 0 auto;
}

.prose p { font-size: 1.0625rem; line-height: 1.75; margin-bottom: 1.25rem; color: var(--text-soft); }
.prose p:last-child { margin-bottom: 0; }
.prose p + p { text-indent: 0; }

.prose-dropcap p:first-child::first-letter {
    font-family: var(--font-display);
    font-weight: 300;
    font-size: 4.25em;
    line-height: 0.85;
    float: left;
    margin: 0.05em 0.12em 0 -0.04em;
    color: var(--text);
}

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

.container--wide   { max-width: var(--container-wide); }
.container--narrow { max-width: var(--container-narrow); }
.container--prose  { max-width: var(--container-prose); }

.section {
    padding-block: clamp(4rem, 10vw, 9rem);
}

.section--tight  { padding-block: clamp(3rem, 6vw, 5rem); }
.section--lg     { padding-block: clamp(6rem, 14vw, 12rem); }
.section--muted  { background: var(--bg-muted); }
.section--ink    { background: var(--ink-05); color: rgba(255,255,255,0.92); }

.section--ink h1, .section--ink h2, .section--ink h3, .section--ink h4 { color: #F5F2EC; }
.section--ink .eyebrow { color: rgba(255,255,255,0.62); }

.rule {
    height: 1px;
    background: var(--rule);
    border: 0;
    margin: 0;
}

.rule--ink { background: rgba(255,255,255,0.12); }

/* --------------------------------------------------------------------------
   5. BUTTONS
   -------------------------------------------------------------------------- */
.btn {
    --btn-fg: var(--text);
    --btn-bg: transparent;
    --btn-border: var(--text);

    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.95rem 1.6rem;
    font-family: var(--font-sans);
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--btn-fg);
    background: var(--btn-bg);
    border: 1px solid var(--btn-border);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background var(--d-1) var(--ease-out-quart),
                color var(--d-1) var(--ease-out-quart),
                border-color var(--d-1) var(--ease-out-quart),
                transform var(--d-2) var(--ease-out-expo);
    white-space: nowrap;
    position: relative;
    isolation: isolate;
}

.btn::after {
    content: '→';
    font-family: var(--font-sans);
    transform: translateX(0);
    transition: transform var(--d-2) var(--ease-out-expo);
    font-weight: 400;
}

/* External-link buttons get the diagonal "opens in new tab" arrow instead
   of the default forward arrow. Driven by the target attribute so every
   external btn is automatically consistent — no per-button HTML maintenance
   and no risk of the doubled-up "↗ →" we had on the prints page. */
.btn[target="_blank"]::after { content: '↗'; }

.btn:hover::after { transform: translateX(4px); }

.btn--primary {
    --btn-fg: var(--bg);
    --btn-bg: var(--ink-10);
    --btn-border: var(--ink-10);
}
.btn--primary:hover {
    --btn-bg: var(--accent);
    --btn-border: var(--accent);
    --btn-fg: var(--ink-10);
}

.btn--ghost {
    --btn-fg: var(--text);
    --btn-bg: transparent;
    --btn-border: var(--ink-90);
}
.btn--ghost:hover {
    --btn-border: var(--text);
}

.btn--light {
    --btn-fg: #F5F2EC;
    --btn-bg: transparent;
    --btn-border: rgba(255,255,255,0.4);
}
.btn--light:hover {
    --btn-bg: #F5F2EC;
    --btn-fg: var(--ink-10);
    --btn-border: #F5F2EC;
}

.btn--bare {
    padding: 0;
    border: 0;
    background: transparent;
    border-radius: 0;
    text-transform: none;
    letter-spacing: 0.02em;
    font-size: 0.9375rem;
    font-weight: 500;
    text-transform: none;
}
.btn--bare::after { font-size: 1.05em; }

.link-underline {
    position: relative;
    color: inherit;
    transition: color var(--d-1);
}
.link-underline::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -2px;
    height: 1px;
    background: currentColor;
    transform-origin: 100% 50%;
    transform: scaleX(0);
    transition: transform var(--d-2) var(--ease-out-expo);
}
.link-underline:hover::after {
    transform-origin: 0% 50%;
    transform: scaleX(1);
}

/* --------------------------------------------------------------------------
   6. NAVIGATION
   -------------------------------------------------------------------------- */
.main-nav {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 80;
    height: var(--nav-height);
    display: flex;
    align-items: center;
    transition:
        height var(--d-2) var(--ease-out-quart),
        background var(--d-2) var(--ease-out-quart),
        border-color var(--d-2) var(--ease-out-quart),
        backdrop-filter var(--d-2) var(--ease-out-quart),
        transform var(--d-2) var(--ease-out-quart);
    border-bottom: 1px solid transparent;
}

/* Three nav states */
.main-nav[data-state='transparent'] {
    background: linear-gradient(to bottom, rgba(11,12,14,0.32) 0%, rgba(11,12,14,0) 100%);
    color: #F5F2EC;
}
.main-nav[data-state='solid'] {
    background: rgba(251, 250, 247, 0.78);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    color: var(--text);
    border-bottom-color: var(--rule);
}
.main-nav[data-state='condensed'] {
    height: var(--nav-height-condensed);
    background: rgba(251, 250, 247, 0.94);
    backdrop-filter: saturate(180%) blur(24px);
    -webkit-backdrop-filter: saturate(180%) blur(24px);
    color: var(--text);
    border-bottom-color: var(--rule);
}

.main-nav.is-hidden { transform: translateY(-100%); }

.nav-container {
    width: 100%;
    max-width: var(--container-wide);
    margin-inline: auto;
    padding-inline: var(--gutter);
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--space-6);
}

.logo {
    position: relative;
    display: inline-flex;
    align-items: center;
    z-index: 2;
    /* Reserve a stable footprint so the picture-pair never reflows the nav */
    width: 54px;
    height: 42px;
    transition: width var(--d-2) var(--ease-out-quart), height var(--d-2) var(--ease-out-quart);
}

.logo-pic {
    position: absolute;
    inset: 0;
    display: block;
    transition: opacity var(--d-2) var(--ease-out-quart);
    pointer-events: none;
}

.logo-img {
    display: block;
    height: 100%;
    width: auto;
}

/* Default state: solid nav → dark logo */
.logo-pic--white { opacity: 0; }
.logo-pic--dark  { opacity: 1; }

/* Transparent (over-hero) state → white logo */
.main-nav[data-state='transparent'] .logo-pic--dark  { opacity: 0; }
.main-nav[data-state='transparent'] .logo-pic--white { opacity: 1; }


/* Condensed: shrink the wrapper, both pictures follow */
.main-nav[data-state='condensed'] .logo {
    width: 41px;
    height: 32px;
}

.nav-menu {
    display: flex;
    align-items: center;
    gap: var(--space-7);
    list-style: none;
    justify-content: center;
}

.nav-menu > li > a,
.nav-menu .nav-link {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: inherit;
    padding-block: 6px;
    transition: color var(--d-1);
}

.nav-menu .nav-link::after {
    content: '';
    position: absolute;
    left: 50%; bottom: -2px;
    width: 0; height: 1px;
    background: currentColor;
    transition: width var(--d-2) var(--ease-out-expo), left var(--d-2) var(--ease-out-expo);
}
.nav-menu .nav-link:hover::after,
.nav-menu .nav-link[aria-current='page']::after {
    width: 100%;
    left: 0;
}

.nav-menu .nav-link[aria-current='page'] {
    color: var(--accent);
}

.nav-cta-group {
    display: inline-flex;
    align-items: center;
    gap: var(--space-4);
    justify-self: end;
}

.nav-client-link {
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: inherit;
    opacity: 0.8;
    transition: opacity var(--d-1);
}
.nav-client-link:hover { opacity: 1; }

.nav-cta {
    padding: 0.625rem 1.1rem;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: inherit;
    border: 1px solid currentColor;
    border-radius: var(--radius-pill);
    transition: background var(--d-1), color var(--d-1), border-color var(--d-1);
}
.nav-cta:hover {
    background: currentColor;
    color: var(--bg);
}
.main-nav[data-state='transparent'] .nav-cta:hover { color: var(--ink-10); background: #F5F2EC; border-color: #F5F2EC; }

.nav-social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    color: inherit;
    opacity: 0.7;
    transition: opacity var(--d-1), transform var(--d-1);
    border-radius: 50%;
}
.nav-social:hover {
    opacity: 1;
    transform: translateY(-1px);
}
.nav-social svg {
    width: 18px;
    height: 18px;
    display: block;
    fill: currentColor;
}
.nav-social--linkedin svg {
    width: 20px;
    height: 20px;
}

/* Submenu trigger */
.has-submenu .nav-link-with-caret::before {
    content: '';
    display: inline-block;
    width: 4px; height: 4px;
    border-right: 1px solid currentColor;
    border-bottom: 1px solid currentColor;
    transform: rotate(45deg) translateY(-1px);
    margin-right: 4px;
    opacity: 0.7;
}

/* Mega panel — opens beneath nav */
.mega {
    position: fixed;
    top: var(--nav-height);
    left: 0; right: 0;
    background: rgba(251,250,247,0.97);
    backdrop-filter: saturate(180%) blur(24px);
    -webkit-backdrop-filter: saturate(180%) blur(24px);
    border-bottom: 1px solid var(--rule);
    color: var(--text);
    transform-origin: top;
    transform: translateY(-12px);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--d-2) var(--ease-out-quart),
                transform var(--d-2) var(--ease-out-quart),
                visibility 0s linear var(--d-2);
    z-index: 79;
}

.main-nav[data-state='condensed'] + .mega { top: var(--nav-height-condensed); }

.mega.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition: opacity var(--d-2) var(--ease-out-quart),
                transform var(--d-2) var(--ease-out-quart),
                visibility 0s linear 0s;
}

.mega-inner {
    max-width: var(--container-wide);
    margin-inline: auto;
    padding: var(--space-8) var(--gutter) var(--space-9);
    display: grid;
    grid-template-columns: 0.6fr 0.7fr 1fr;
    gap: var(--space-8);
    align-items: start;
}

.mega-section h4 {
    font-family: var(--font-mono);
    font-size: var(--t-eyebrow);
    font-weight: 500;
    letter-spacing: var(--track-eyebrow);
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: var(--space-5);
}

.mega-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.mega-list a {
    display: inline-flex;
    align-items: baseline;
    gap: 0.6em;
    font-family: var(--font-display);
    font-weight: 300;
    font-size: clamp(1.5rem, 2.4vw, 2rem);
    line-height: 1.1;
    color: var(--text);
    transition: color var(--d-1), transform var(--d-2) var(--ease-out-expo);
}
.mega-list a .num {
    font-family: var(--font-mono);
    font-size: 0.6em;
    color: var(--text-muted);
    transform: translateY(-0.5em);
    transition: color var(--d-1);
}
.mega-list a:hover { color: var(--accent); transform: translateX(6px); }
.mega-list a:hover .num { color: var(--accent); }
.mega-list a.is-active { color: var(--accent); }

.mega-preview {
    aspect-ratio: 4/3;
    background: var(--ink-90);
    overflow: hidden;
    position: relative;
    border-radius: var(--radius-card);
}

.mega-preview img {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    opacity: 0;
    transform: scale(1.04);
    transition: opacity var(--d-3) var(--ease-out-quart), transform var(--d-4) var(--ease-out-expo);
}
.mega-preview img.is-active {
    opacity: 1;
    transform: scale(1);
}

.mega-preview-meta {
    position: absolute;
    left: var(--space-4);
    bottom: var(--space-4);
    color: #F5F2EC;
    text-shadow: 0 2px 16px rgba(0,0,0,0.4);
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.05em;
    opacity: 0;
    transition: opacity var(--d-2);
}
.mega-preview-meta.is-active { opacity: 1; }

/* Mobile toggle.
   Visible bars stay at 22×1.5px, but the hit target is 44×44 to clear WCAG
   2.5.5 (Target Size, Level AAA) and the equivalent Apple HIG / Material
   guidance. Without this, the burger is comfortably tappable on a 26-year-old
   thumb but uncomfortable for everyone else. */
.nav-toggle {
    display: none;
    flex-direction: column;
    gap: 5px;
    width: 44px;
    height: 44px;
    align-items: flex-end;
    justify-content: center;
    z-index: 100;
    /* Pull the visible bars to the right edge of the 44px box so the icon
       still aligns with the rest of the header bar. */
    padding: 8px 0 8px 22px;
    box-sizing: border-box;
    background: transparent;
    border: 0;
    color: inherit;
}
.nav-toggle span {
    display: block;
    width: 22px;
    height: 1.5px;
    background: currentColor;
    transition: transform var(--d-2) var(--ease-out-quart),
                opacity var(--d-1),
                width var(--d-2) var(--ease-out-quart);
}
.nav-toggle span:nth-child(2) { width: 14px; }
.nav-toggle.is-active span:nth-child(1) { transform: translateY(7px) rotate(45deg); width: 22px; }
.nav-toggle.is-active span:nth-child(2) { opacity: 0; }
.nav-toggle.is-active span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); width: 22px; }

/* When the mobile sheet is open, the nav sits on top of the cream sheet —
   force a dark, high-contrast X so the close affordance is unmistakable. */
body[data-sheet-open] .main-nav { color: var(--ink-10); }
body[data-sheet-open] .main-nav .logo-pic--white { opacity: 0; }
body[data-sheet-open] .main-nav .logo-pic--dark  { opacity: 1; }
body[data-sheet-open] .nav-toggle.is-active::after {
    content: 'Close';
    position: absolute;
    right: calc(100% + 0.65rem);
    top: 50%;
    transform: translateY(-50%);
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
    pointer-events: none;
    white-space: nowrap;
}
.nav-toggle { position: relative; }

/* Mobile sheet */
@media (max-width: 1024px) {
    .nav-toggle {
        display: inline-flex;
        /* With nav-menu and nav-cta-group hidden, the grid only has logo +
           toggle. Pin the toggle to the right edge of the row. */
        justify-self: end;
    }

    .nav-container {
        /* Two-track layout when only logo + toggle remain */
        grid-template-columns: auto 1fr;
    }

    .nav-menu, .nav-cta-group { display: none; }

    .mobile-sheet {
        position: fixed;
        inset: 0;
        background: var(--ink-100);
        z-index: 90;
        padding: calc(var(--nav-height) + 2rem) var(--gutter) 2rem;
        transform: translateY(-100%);
        transition: transform var(--d-3) var(--ease-out-quart);
        overflow-y: auto;
        display: flex;
        flex-direction: column;
        gap: var(--space-7);
    }
    .mobile-sheet.is-open { transform: translateY(0); }

    .mobile-sheet ul {
        list-style: none;
        display: flex;
        flex-direction: column;
        gap: var(--space-4);
    }
    /* Sheet *nav* links — big serif. Excluding `.btn` so the Book-a-Session
       and Client Galleries CTAs at the bottom of the sheet keep their own
       button typography and `--btn-fg`/`--btn-bg` color tokens. Without the
       :not(.btn) the .btn--primary ended up dark-on-dark and disappeared. */
    .mobile-sheet a:not(.btn) {
        font-family: var(--font-display);
        font-weight: 300;
        font-size: clamp(1.75rem, 6vw, 2.5rem);
        color: var(--text);
        line-height: 1.1;
    }
    .mobile-sheet .mobile-sub {
        padding-left: var(--space-4);
        border-left: 1px solid var(--rule);
        gap: var(--space-3);
    }
    .mobile-sheet .mobile-sub a {
        font-size: 1.25rem;
    }
    .mobile-sheet .mobile-section-label {
        font-family: var(--font-mono);
        font-size: var(--t-eyebrow);
        font-weight: 500;
        letter-spacing: var(--track-eyebrow);
        text-transform: uppercase;
        color: var(--text-muted);
        margin-bottom: var(--space-3);
    }
    .mobile-sheet .mobile-cta-row {
        margin-top: auto;
        display: flex;
        flex-direction: column;
        gap: var(--space-3);
    }
}

@media (min-width: 1025px) {
    .mobile-sheet { display: none !important; }
}

/* --------------------------------------------------------------------------
   7. HERO
   -------------------------------------------------------------------------- */
/* Hero text — always light against the dark cinematic veil.
   Title gets a subtle text-shadow halo for additional safety on busy frames. */
.hero .hero-title,
.hero .hero-tagline {
    text-shadow: 0 1px 32px rgba(11, 12, 14, 0.45);
}

.hero {
    position: relative;
    /* Use small-vh to avoid mobile URL-bar pop, fall back to vh */
    height: 100vh;
    height: 100svh;
    min-height: 640px;
    overflow: hidden;
    background: var(--ink-00);
    color: #F5F2EC;
    display: flex;
    align-items: center;
    isolation: isolate;
}

.hero-stage {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
}

.hero-slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    /* Long, gentle crossfade so the camera "dissolves" between scenes */
    transition: opacity 3.2s var(--ease-in-out-soft);
    will-change: opacity;
}
.hero-slide.is-active { opacity: 1; }

.hero-slide picture, .hero-slide img {
    width: 100%; height: 100%;
}

.hero-slide img {
    object-fit: cover;
    object-position: center;
    /* Continuous slow Ken-Burns drift on EVERY slide (active or not) so the
       camera is always in motion. No JS resets — when slides cross-fade
       both are mid-drift, eliminating any hard zoom-back. */
    transform: scale(1.04) translate3d(var(--px, 0), var(--py, 0), 0);
    animation: heroAlwaysDrift 38s var(--ease-in-out-soft) infinite alternate;
    will-change: transform;
}

@keyframes heroAlwaysDrift {
    from { transform: scale(1.00) translate3d(var(--px, 0), var(--py, 0), 0); }
    to   { transform: scale(1.08) translate3d(var(--px, 0), var(--py, 0), 0); }
}

/* Stagger animation start times by slide index (set via inline style in JS)
   so consecutive slides aren't in lockstep, giving each transition a
   different relative motion. */
.hero-slide:nth-child(odd) img  { animation-delay: 0s; }
.hero-slide:nth-child(even) img { animation-delay: -19s; }

/* Cinematic dark veil — single tone, gradient that lets more of the photo
   breathe through the middle while keeping the text legible at the bottom
   and the nav legible at the top.
   The radial layer is anchored at 25% / 60% of the VIEWPORT (not the content
   container) so on ultrawide screens it doesn't end up as a visible dark
   patch hovering in the middle while the photo runs bright on either side. */
.hero-wash {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
        /* Soft radial darkening centered on where the headline + tagline sit.
           Layered first so the directional gradients below still anchor the
           bottom-meta and nav rows on top of it. */
        radial-gradient(
            ellipse 75% 65% at 25% 60%,
            rgba(11, 12, 14, 0.38) 0%,
            rgba(11, 12, 14, 0.16) 36%,
            rgba(11, 12, 14, 0) 70%
        ),
        /* Top wash — gentle, doesn't crush the sky */
        linear-gradient(180deg, rgba(11,12,14,0.32) 0%, rgba(11,12,14,0) 24%),
        /* Bottom anchor — deeper darkness behind text + meta */
        linear-gradient(0deg,   rgba(11,12,14,0.62) 0%, rgba(11,12,14,0.24) 32%, rgba(11,12,14,0) 55%);
}

.hero-content {
    position: relative;
    z-index: 2;
    width: 100%;
    max-width: var(--container-wide);
    margin-inline: auto;
    /* Top: clear the nav · Bottom: clear the meta + scroll indicators */
    padding: calc(var(--nav-height) + clamp(1.5rem, 3vw, 3rem)) var(--gutter) calc(var(--space-9) + var(--space-5));
}

/* The soft local dark veil that used to live in .hero-content::before now
   lives in .hero-wash so it scales with the viewport instead of the
   max-1680px content container. Without that move, ultrawide displays got
   a visible "dark patch" hovering around the text while the photo
   continued bright on either side. */

.hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-family: var(--font-mono);
    font-size: var(--t-eyebrow);
    font-weight: 500;
    letter-spacing: var(--track-eyebrow);
    text-transform: uppercase;
    color: rgba(245, 242, 236, 0.78);
    margin-bottom: var(--space-5);
}
.hero-eyebrow::before {
    content: '';
    width: 32px; height: 1px;
    background: var(--accent);
}

.hero-title {
    font-family: var(--font-display);
    font-weight: 300;
    /* Slightly tighter cap so the title can't push past the bottom meta */
    font-size: clamp(3rem, 8.4vw, 8rem);
    line-height: 0.94;
    letter-spacing: -0.025em;
    color: #F5F2EC;
    font-variation-settings: 'opsz' 144, 'SOFT' 100;
    max-width: 14ch;
    margin: 0;
}

.hero-title .hero-line {
    display: block;
    overflow: hidden;
    /* Extra room so descenders (g, p, y) on Fraunces aren't clipped after
       the rise-from-below animation completes. */
    padding-bottom: 0.18em;
}
.hero-title .hero-line > span {
    display: block;
    transform: translateY(110%);
    animation: heroLineUp 1.4s var(--ease-out-expo) forwards;
}
.hero-title .hero-line:nth-child(1) > span { animation-delay: 0.25s; }
.hero-title .hero-line:nth-child(2) > span { animation-delay: 0.45s; }
.hero-title .hero-line:nth-child(3) > span { animation-delay: 0.65s; }
.hero-title em {
    font-style: italic;
    font-weight: 300;
    color: var(--accent-soft);
}

@keyframes heroLineUp {
    from { transform: translateY(110%); }
    to   { transform: translateY(0); }
}

.hero-tagline {
    margin-top: var(--space-6);
    font-family: var(--font-display);
    font-weight: 300;
    font-size: clamp(1.125rem, 1.6vw, 1.4rem);
    line-height: 1.5;
    color: rgba(245, 242, 236, 0.84);
    max-width: 38ch;
    opacity: 0;
    transform: translateY(20px);
    animation: heroFadeIn 1.2s var(--ease-out-expo) forwards;
    animation-delay: 0.95s;
}

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

.hero-meta {
    position: absolute;
    bottom: var(--space-6);
    left: var(--gutter);
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.06em;
    color: rgba(245, 242, 236, 0.78);
    opacity: 0;
    animation: heroFadeIn 1s var(--ease-out-expo) forwards;
    animation-delay: 1.15s;
}
.hero-meta .dot {
    width: 3px; height: 3px; border-radius: 50%;
    background: rgba(245, 242, 236, 0.4);
}
.hero-meta .num { color: var(--accent-soft); }

.hero-scroll {
    position: absolute;
    bottom: var(--space-6);
    right: var(--gutter);
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: rgba(245, 242, 236, 0.92);
    opacity: 0;
    animation: heroFadeIn 1s var(--ease-out-expo) forwards;
    animation-delay: 1.15s;
    cursor: pointer;
    transition: transform var(--d-2) var(--ease-out-expo), color var(--d-2);
}
.hero-scroll:hover { transform: translateY(3px); color: #F5F2EC; }
.hero-scroll:hover .hero-scroll-rule { background: rgba(245, 242, 236, 0.32); }

.hero-scroll-rule {
    position: relative;
    width: 1px; height: 92px;
    background: rgba(245, 242, 236, 0.22);
    overflow: hidden;
    transition: background var(--d-2);
}
.hero-scroll-rule::after {
    content: '';
    position: absolute;
    left: 0; top: 0;
    width: 100%; height: 38%;
    background: linear-gradient(180deg, var(--accent-soft) 0%, var(--accent) 100%);
    animation: scrollRule 2.6s var(--ease-in-out-soft) infinite;
}
@keyframes scrollRule {
    0%   { transform: translateY(-100%); opacity: 0; }
    18%  { opacity: 1; }
    82%  { opacity: 1; }
    100% { transform: translateY(265%); opacity: 0; }
}

/* Short viewports (laptops, landscape phones) — keep hero content clear of bottom meta */
@media (max-height: 760px) {
    .hero-title    { font-size: clamp(2.75rem, 6.4vw, 5.25rem); }
    .hero-tagline  { margin-top: var(--space-5); font-size: clamp(1rem, 1.4vw, 1.2rem); }
    .hero-eyebrow  { margin-bottom: var(--space-4); }
    .hero-content  { padding-top: calc(var(--nav-height) + 1rem); padding-bottom: calc(var(--space-8) + var(--space-4)); }
}

@media (max-width: 768px) {
    .hero-meta    { font-size: 0.6875rem; bottom: var(--space-5); }
    .hero-scroll  { display: none; }
    .hero-content { padding-bottom: calc(var(--space-8) + var(--space-3)); }
    .hero-title   { font-size: clamp(2.75rem, 12vw, 4.5rem); max-width: 12ch; }
    .hero-tagline { max-width: 32ch; }
}

@media (max-width: 480px) {
    .hero-eyebrow { font-size: 0.625rem; letter-spacing: 0.14em; }
}
@media (max-width: 360px) {
    .hero-eyebrow {
        flex-wrap: wrap;
        font-size: 0.6rem;
    }
    .hero-eyebrow::before { width: 24px; }
}

/* --------------------------------------------------------------------------
   8. INTRO BLOCK / QUIET SECTIONS
   -------------------------------------------------------------------------- */
.intro {
    padding: clamp(5rem, 14vw, 11rem) var(--gutter);
    text-align: center;
}

.intro-eyebrow { margin-bottom: var(--space-5); }

.intro-headline {
    font-family: var(--font-display);
    font-weight: 300;
    font-size: clamp(1.75rem, 3.2vw, 2.625rem);
    line-height: 1.25;
    letter-spacing: -0.012em;
    max-width: 22ch;
    margin: 0 auto var(--space-6);
}

.intro-headline em {
    font-style: italic;
    color: var(--accent-deep);
}

/* Inline body link in the intro headline (e.g. "custom websites" linking
   to /web-design.html). Underline-only so it doesn't fight the editorial
   typography, but stays clearly clickable. */
.intro-link {
    color: var(--text);
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 1.5px;
    text-underline-offset: 4px;
    transition: color var(--d-2);
}
.intro-link:hover {
    color: var(--accent-deep);
    text-decoration-color: var(--accent-deep);
}

.intro-meta {
    margin-top: var(--space-6);
    display: flex;
    justify-content: center;
    align-items: center;
    gap: var(--space-5);
    flex-wrap: wrap;
}

.intro-meta-item {
    display: inline-flex;
    align-items: baseline;
    gap: 0.55em;
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.intro-meta-item .num {
    font-family: var(--font-display);
    font-weight: 300;
    font-size: 1.6em;
    color: var(--text);
    letter-spacing: -0.02em;
}

.intro-rule {
    width: 64px;
    height: 1px;
    background: var(--accent);
    margin: var(--space-7) auto 0;
}

/* --------------------------------------------------------------------------
   9. BENTO — featured work grid
   -------------------------------------------------------------------------- */
.bento {
    padding: clamp(3rem, 6vw, 5rem) var(--gutter) clamp(5rem, 12vw, 9rem);
}

.bento-head {
    max-width: var(--container);
    margin: 0 auto var(--space-8);
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: var(--space-6);
    flex-wrap: wrap;
}
.bento-head-text { max-width: 36ch; }
.bento-head h2 {
    font-size: var(--t-h2);
    line-height: 1;
    letter-spacing: var(--track-display);
    margin-top: var(--space-3);
}
.bento-head h2 em { font-style: italic; color: var(--accent-deep); }

.bento-grid {
    max-width: var(--container);
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    /* Lock row heights so paired cells match within each row */
    grid-auto-rows: clamp(170px, 17vw, 250px);
    gap: clamp(0.75rem, 1.4vw, 1.25rem);
}

.bento-cell {
    position: relative;
    overflow: hidden;
    background: var(--ink-90);
    border-radius: var(--radius-card);
    isolation: isolate;
}

.bento-cell a {
    position: relative;
    display: block;
    width: 100%; height: 100%;
}

.bento-cell picture, .bento-cell img {
    width: 100%; height: 100%;
}
.bento-cell img {
    object-fit: cover;
    transition: transform 1.4s var(--ease-out-expo), filter var(--d-3) var(--ease-out-quart);
    will-change: transform;
}

.bento-cell::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(11,12,14,0.55), rgba(11,12,14,0.0) 38%, rgba(11,12,14,0.0) 65%, rgba(11,12,14,0.18) 100%);
    pointer-events: none;
    z-index: 1;
    transition: opacity var(--d-3);
}

.bento-cell:hover img { transform: scale(1.04); }

.bento-cell-meta {
    position: absolute;
    inset: 0;
    z-index: 2;
    padding: clamp(1rem, 2vw, 1.6rem);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    color: #F5F2EC;
    pointer-events: none;
}

.bento-cell-meta .eyebrow {
    color: rgba(245,242,236,0.78);
    margin-bottom: 0.5rem;
}

.bento-cell-meta h3 {
    font-family: var(--font-display);
    font-weight: 300;
    font-size: clamp(1.5rem, 2.4vw, 2.25rem);
    line-height: 1;
    color: #F5F2EC;
    letter-spacing: -0.01em;
    position: relative;
    display: inline-block;
}

.bento-cell-meta h3::after {
    content: '';
    position: absolute;
    left: 0; bottom: -6px;
    height: 1px; width: 0;
    background: var(--accent);
    transition: width var(--d-3) var(--ease-out-expo);
}

.bento-cell:hover .bento-cell-meta h3::after { width: 100%; }

.bento-cell-num {
    position: absolute;
    top: clamp(1rem, 2vw, 1.6rem);
    right: clamp(1rem, 2vw, 1.6rem);
    z-index: 2;
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.05em;
    color: rgba(245,242,236,0.85);
    pointer-events: none;
}

/* Layout: 12-col mosaic.
   Each row pairs two cells that share row-spans, so heights stay equal. */
.bento-cell--landscape   { grid-column: span 7; grid-row: span 2; }   /* row 1 */
.bento-cell--portraiture { grid-column: span 5; grid-row: span 2; }   /* row 1 */
.bento-cell--film        { grid-column: span 5; grid-row: span 2; }   /* row 2 */
.bento-cell--drone       { grid-column: span 7; grid-row: span 2; }   /* row 2 */
.bento-cell--couples     { grid-column: span 6; grid-row: span 2; }   /* row 3 */
.bento-cell--street      { grid-column: span 6; grid-row: span 2; }   /* row 3 */

@media (max-width: 1024px) {
    .bento-grid { grid-auto-rows: clamp(160px, 22vw, 220px); }
    .bento-cell--landscape, .bento-cell--portraiture { grid-column: span 12; grid-row: span 2; }
    .bento-cell--film, .bento-cell--drone            { grid-column: span 6;  grid-row: span 2; }
    .bento-cell--couples, .bento-cell--street        { grid-column: span 12; grid-row: span 2; }
}
@media (max-width: 640px) {
    .bento-grid { grid-auto-rows: clamp(220px, 60vw, 360px); }
    .bento-grid > .bento-cell { grid-column: span 12 !important; grid-row: span 1 !important; }
}

/* --------------------------------------------------------------------------
   10. BOOKING PLATE
   -------------------------------------------------------------------------- */
.plate {
    padding: clamp(4rem, 8vw, 7rem) var(--gutter);
}

.plate-inner {
    max-width: var(--container);
    margin-inline: auto;
    display: grid;
    grid-template-columns: 1.05fr 1fr;
    gap: clamp(2rem, 5vw, 4.5rem);
    align-items: center;
}

.plate-image {
    aspect-ratio: 5/6;
    overflow: hidden;
    background: var(--ink-90);
    border-radius: var(--radius-card);
    position: relative;
}
.plate-image img { width: 100%; height: 100%; object-fit: cover; }
.plate-image-tag {
    position: absolute;
    top: var(--space-4);
    left: var(--space-4);
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.05em;
    color: #F5F2EC;
    background: rgba(11,12,14,0.55);
    backdrop-filter: blur(8px);
    padding: 0.4rem 0.8rem;
    border-radius: var(--radius-pill);
}

.plate-content {
    max-width: 520px;
}
.plate-content .eyebrow { margin-bottom: var(--space-4); }
.plate-content h2 {
    font-size: clamp(2.25rem, 4.5vw, 3.75rem);
    line-height: 1.02;
    letter-spacing: var(--track-display);
    margin-bottom: var(--space-5);
}
.plate-content h2 em { font-style: italic; color: var(--accent-deep); }
.plate-content p {
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--text-soft);
    margin-bottom: var(--space-6);
    max-width: 42ch;
}

.plate-list {
    list-style: none;
    margin-bottom: var(--space-7);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    border-top: 1px solid var(--rule);
}
.plate-list li {
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--rule);
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-4);
    font-size: 0.9375rem;
}
.plate-list li span:first-child { color: var(--text); font-weight: 500; }
.plate-list li span:last-child {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    text-transform: uppercase;
}

/* ---- Rates (homepage booking plate) ----------------------------------- */
.rates {
    margin: var(--space-5) 0 var(--space-7);
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}
.rates-group-label {
    font-family: var(--font-mono);
    font-size: var(--t-eyebrow);
    font-weight: 500;
    letter-spacing: var(--track-eyebrow);
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: var(--space-3);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--rule);
}
.rates-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}
.rates-list li {
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--rule);
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-4);
    font-size: 0.9375rem;
    line-height: 1.4;
    transition: padding-left var(--d-2) var(--ease-out-quart);
}
.rates-list li:last-child { border-bottom: 0; }
.rates-list li:hover { padding-left: 0.4rem; }

.rates-name {
    color: var(--text);
    font-weight: 500;
    font-size: 1rem;
}
.rates-name-mod {
    color: var(--text-muted);
    font-weight: 400;
    font-style: italic;
    margin-left: 0.15em;
}
.rates-meta {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
    text-align: right;
    flex-shrink: 0;
}
.rates-meta strong {
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    font-size: 1.0625rem;
    letter-spacing: -0.01em;
    text-transform: none;
    color: var(--text);
    margin-left: 0.2em;
}
.rates-list--quote .rates-meta {
    color: var(--accent-deep);
}

.rates-cta {
    display: flex;
    align-items: center;
    gap: var(--space-6);
    flex-wrap: wrap;
}

@media (max-width: 880px) {
    .plate-inner { grid-template-columns: 1fr; }
    .plate-image { aspect-ratio: 4/5; }
}
@media (max-width: 540px) {
    .rates-list li { flex-wrap: wrap; gap: 0.25rem; }
    .rates-meta { text-align: left; }
}

/* --------------------------------------------------------------------------
   11. LATEST FRAMES STRIP
   -------------------------------------------------------------------------- */
.frames {
    padding: clamp(4rem, 8vw, 7rem) var(--gutter);
    background: var(--bg-muted);
}

.frames-head {
    max-width: var(--container);
    margin: 0 auto var(--space-8);
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: var(--space-5);
    flex-wrap: wrap;
}

.frames-head h2 {
    font-size: clamp(2rem, 4.5vw, 3.5rem);
    line-height: 1;
    letter-spacing: var(--track-display);
}
.frames-head h2 em { font-style: italic; color: var(--accent-deep); }

.frames-grid {
    max-width: var(--container);
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: clamp(0.5rem, 1vw, 0.75rem);
}

.frames-grid a {
    display: block;
    aspect-ratio: 4/5;
    overflow: hidden;
    background: var(--ink-90);
    border-radius: var(--radius-card);
    position: relative;
}
.frames-grid img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform var(--d-3) var(--ease-out-expo), filter var(--d-2);
}
.frames-grid:hover a img { filter: brightness(0.6); }
.frames-grid a:hover img { transform: scale(1.04); filter: brightness(1); }

.frames-grid a:nth-child(2) { aspect-ratio: 5/7; transform: translateY(20px); }
.frames-grid a:nth-child(4) { aspect-ratio: 5/7; transform: translateY(20px); }

@media (max-width: 880px) {
    .frames-grid { grid-template-columns: repeat(2, 1fr); }
    .frames-grid a:nth-child(n) { transform: none; aspect-ratio: 4/5; }
}

/* Dynamic strip — when js/photo-strip.js has populated [data-photo-strip],
   the layout switches from staggered-grid to a single justified row whose
   tile widths come from the photos' real aspect ratios. */
.frames-grid[data-photo-strip].is-populated {
    display: flex;
    flex-direction: row;
    gap: clamp(0.5rem, 1vw, 0.75rem);
}
.frames-grid[data-photo-strip].is-populated > .photo-strip-tile {
    flex: 0 0 auto;
    aspect-ratio: auto;
    transform: none;
    overflow: hidden;
    background: var(--ink-90);
    border-radius: var(--radius-card);
    position: relative;
    display: block;
}
.frames-grid[data-photo-strip].is-populated > .photo-strip-tile img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: transform var(--d-3) var(--ease-out-expo), filter var(--d-2);
    display: block;
}
.frames-grid[data-photo-strip].is-populated:hover > .photo-strip-tile img { filter: brightness(0.6); }
.frames-grid[data-photo-strip].is-populated > .photo-strip-tile:hover img { transform: scale(1.04); filter: brightness(1); }

.frames-grid[data-photo-strip].is-populated.is-stacked {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
}
.frames-grid[data-photo-strip].is-populated.is-stacked > .photo-strip-tile {
    width: 100%;
    height: auto;
}

/* Crossfade in the live photos when js/photo-strip.js swaps the static
   fallback. `is-swapping` is set for one frame on the first swap, then
   removed; the opacity transition does the rest. Without this the
   container goes from "5 different images" to "5 new images" in a single
   frame, which reads as a late-pop. The fade hides that boundary. */
.frames-grid[data-photo-strip].is-populated {
    opacity: 1;
    transition: opacity 220ms ease-out;
}
.frames-grid[data-photo-strip].is-populated.is-swapping {
    opacity: 0;
}

/* --------------------------------------------------------------------------
   12. TESTIMONIAL
   -------------------------------------------------------------------------- */
.testimonial {
    padding: clamp(5rem, 10vw, 9rem) var(--gutter);
    background: var(--ink-05);
    color: rgba(255,255,255,0.92);
    text-align: center;
    position: relative;
    overflow: hidden;
}

.testimonial::before {
    content: '“';
    position: absolute;
    top: -0.05em;
    left: 50%;
    transform: translateX(-50%);
    font-family: var(--font-display);
    font-size: clamp(20rem, 40vw, 32rem);
    line-height: 1;
    color: rgba(184, 149, 106, 0.06);
    pointer-events: none;
    z-index: 0;
}

.testimonial-inner {
    position: relative;
    z-index: 1;
    max-width: 920px;
    margin-inline: auto;
}

.testimonial .eyebrow {
    color: var(--accent-soft);
    margin-bottom: var(--space-6);
}

/* Stage wraps the track + arrows so they share the same row */
.testimonial-stage {
    position: relative;
    display: grid;
    grid-template-columns: 48px 1fr 48px;
    align-items: center;
    gap: clamp(0.5rem, 2vw, 2rem);
    max-width: 980px;
    margin: 0 auto;
}

.testimonial-track {
    position: relative;
    /* JS sets explicit height to match the active quote — smooth transition. */
    height: 14rem;
    transition: height var(--d-3) var(--ease-out-quart);
    overflow: visible;
}

.testimonial-quote {
    position: absolute;
    inset: 0;
    opacity: 0;
    transform: translateY(12px);
    transition: opacity var(--d-3), transform var(--d-3) var(--ease-out-quart);
    pointer-events: none;
}
.testimonial-quote.is-active { opacity: 1; transform: translateY(0); pointer-events: auto; }

.testimonial-quote blockquote {
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 300;
    font-size: clamp(1.25rem, 2.2vw, 1.875rem);
    line-height: 1.45;
    color: #F5F2EC;
    letter-spacing: -0.005em;
    margin: 0 auto var(--space-5);
    max-width: 60ch;
}

/* Prev/next arrow buttons */
.testimonial-arrow {
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid rgba(245, 242, 236, 0.18);
    border-radius: 50%;
    color: rgba(245, 242, 236, 0.78);
    cursor: pointer;
    transition: border-color var(--d-2), color var(--d-2),
                background var(--d-2), transform var(--d-2) var(--ease-out-quart);
    position: relative;
    z-index: 2;
}
.testimonial-arrow:hover {
    border-color: var(--accent-soft);
    color: #F5F2EC;
    background: rgba(184, 149, 106, 0.08);
    transform: scale(1.06);
}
.testimonial-arrow:focus-visible {
    outline: 2px solid var(--accent-soft);
    outline-offset: 4px;
}
.testimonial-arrow span {
    width: 9px;
    height: 9px;
    border-top: 1px solid currentColor;
    border-right: 1px solid currentColor;
    display: block;
}
.testimonial-arrow--prev span { transform: rotate(-135deg) translate(-1px, -1px); }
.testimonial-arrow--next span { transform: rotate(45deg)   translate(-1px, -1px); }

@media (max-width: 720px) {
    .testimonial-stage { grid-template-columns: 36px 1fr 36px; gap: var(--space-3); }
    .testimonial-arrow { width: 36px; height: 36px; }
}

.testimonial-attr {
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(245,242,236,0.6);
    /* Inline-flex so the row of [avatar · author] / · time / · Google link
       stays vertically centered no matter the avatar height. Wraps cleanly
       on narrow viewports because each segment is its own inline element. */
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4em;
    justify-content: center;
}

/* Author name + avatar form a tight unit so they never line-break apart. */
.testimonial-author {
    display: inline-flex;
    align-items: center;
    gap: 0.55em;
}

/* Reviewer profile photo from the Google Places API. Round, small, with a
   subtle border so it reads against the testimonial's dark background. */
.testimonial-avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    border: 1px solid rgba(245, 242, 236, 0.18);
    background: rgba(245, 242, 236, 0.06);
}

.testimonial-dots {
    display: flex;
    gap: var(--space-3);
    justify-content: center;
    margin-top: var(--space-7);
}
/* Visible indicator stays a 24×1px line, but the hit target wraps it in a
   44×44 transparent button via padding so it clears WCAG 2.5.5. Without this
   the line itself is a 24×1px tap area and unusably small on touch. */
.testimonial-dot {
    position: relative;
    width: 24px; height: 1px;
    background: rgba(255,255,255,0.18);
    transition: background var(--d-1);
    cursor: pointer;
    border: 0;
    padding: 0;
}
.testimonial-dot::before {
    content: "";
    position: absolute;
    /* 44px-tall hit area centered on the 1px line. Horizontal expansion is
       only 6px each side so adjacent dots' hit areas don't overlap (gap is
       12px). Total tap area = 36×44, which exceeds Apple HIG's 44px height
       requirement and gets close to WCAG 2.5.5 on width. */
    inset: -22px -6px;
}
.testimonial-dot.is-active { background: var(--accent-soft); }

/* --------------------------------------------------------------------------
   13. FOOTER
   -------------------------------------------------------------------------- */
.main-footer {
    background: var(--ink-05);
    color: rgba(245,242,236,0.78);
    padding: clamp(3rem, 6vw, 5rem) var(--gutter) 2rem;
}

.footer-inner {
    max-width: var(--container);
    margin-inline: auto;
}

.footer-top {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr 1fr;
    gap: var(--space-7);
    align-items: start;
    padding-bottom: var(--space-7);
    border-bottom: 1px solid rgba(255,255,255,0.08);
}

.footer-brand-mark {
    font-family: var(--font-display);
    font-weight: 300;
    font-size: clamp(2rem, 4vw, 3rem);
    line-height: 1;
    color: #F5F2EC;
    letter-spacing: -0.01em;
}
.footer-brand-tag {
    margin-top: var(--space-3);
    font-size: 0.9375rem;
    line-height: 1.5;
    color: rgba(245,242,236,0.62);
    max-width: 32ch;
}

.footer-col h4 {
    font-family: var(--font-mono);
    font-size: var(--t-eyebrow);
    font-weight: 500;
    letter-spacing: var(--track-eyebrow);
    text-transform: uppercase;
    color: rgba(245,242,236,0.42);
    margin-bottom: var(--space-4);
}

.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 0.6rem; }
.footer-col a {
    color: rgba(245,242,236,0.78);
    font-size: 0.9375rem;
    transition: color var(--d-1);
}
.footer-col a:hover { color: var(--accent-soft); }

.footer-bottom {
    margin-top: var(--space-5);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-5);
    flex-wrap: wrap;
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.05em;
    color: rgba(245,242,236,0.42);
}

.footer-bottom .back-top {
    color: rgba(245,242,236,0.6);
    transition: color var(--d-1);
}
.footer-bottom .back-top:hover { color: var(--accent-soft); }
.footer-bottom .back-top::after {
    content: ' ↑';
}

/* Legal links in the footer bottom — discreet, sit between the copyright
   and back-to-top link. Required for SMS regulatory discoverability
   (TCR/CTIA want Privacy + Terms linked from every page). */
.footer-legal { display: inline-flex; gap: 0.5rem; align-items: center; }
.footer-legal a { color: rgba(245,242,236,0.6); transition: color var(--d-1); }
.footer-legal a:hover { color: var(--accent-soft); }

@media (max-width: 880px) {
    .footer-top { grid-template-columns: 1fr 1fr; }
    .footer-brand { grid-column: span 2; }
}
@media (max-width: 540px) {
    .footer-top { grid-template-columns: 1fr; }
    .footer-brand { grid-column: span 1; }
}

/* --------------------------------------------------------------------------
   14. PAGE HEADERS (used on About, Contact, Book, etc.)
   -------------------------------------------------------------------------- */
.page-header {
    padding: calc(var(--nav-height) + clamp(4rem, 9vw, 8rem)) var(--gutter) clamp(3rem, 6vw, 5rem);
    text-align: center;
    position: relative;
}

.page-header .eyebrow { margin-bottom: var(--space-4); }
.page-header h1 {
    font-size: clamp(3rem, 8vw, 6.5rem);
    line-height: 0.95;
    letter-spacing: -0.025em;
    margin-bottom: var(--space-5);
}
.page-header h1 em { font-style: italic; color: var(--accent-deep); }
.page-header .lede { max-width: 56ch; margin: 0 auto; }

/* --------------------------------------------------------------------------
   15. ABOUT
   -------------------------------------------------------------------------- */
.about-grid {
    max-width: var(--container);
    margin: 0 auto;
    padding: clamp(2rem, 6vw, 5rem) var(--gutter);
    display: grid;
    grid-template-columns: 0.85fr 1fr;
    gap: clamp(2.5rem, 6vw, 6rem);
    align-items: start;
}

.about-portrait {
    position: sticky;
    top: calc(var(--nav-height) + 2rem);
    aspect-ratio: 1/1;
    overflow: hidden;
    border-radius: var(--radius-card);
    background: var(--ink-90);
}
.about-portrait img { width: 100%; height: 100%; object-fit: cover; }

.about-text { max-width: 55ch; }
.about-text h2 {
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    margin-bottom: var(--space-5);
    line-height: 1.1;
}
.about-text p {
    font-size: 1.0625rem;
    line-height: 1.75;
    color: var(--text-soft);
    margin-bottom: var(--space-5);
}
.about-text .pullquote {
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 300;
    font-size: clamp(1.4rem, 2.4vw, 2rem);
    line-height: 1.35;
    color: var(--text);
    border-left: 1px solid var(--accent);
    padding-left: var(--space-5);
    margin: var(--space-7) 0;
}

@media (max-width: 880px) {
    .about-grid { grid-template-columns: 1fr; }
    .about-portrait { position: static; max-width: 480px; margin-inline: auto; }
}

/* Stat row */
.stats {
    background: var(--bg-muted);
    padding: clamp(3rem, 6vw, 5rem) var(--gutter);
}
.stats-inner {
    max-width: var(--container);
    margin-inline: auto;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-7);
    border-block: 1px solid var(--rule);
    padding-block: clamp(2rem, 4vw, 3rem);
}
.stat {
    text-align: center;
}
.stat .num {
    font-family: var(--font-display);
    font-weight: 300;
    font-size: clamp(3.5rem, 7vw, 6rem);
    line-height: 0.9;
    letter-spacing: -0.025em;
    color: var(--text);
    margin-bottom: var(--space-3);
}
.stat .num em { font-style: italic; color: var(--accent-deep); }
.stat .label {
    font-family: var(--font-mono);
    font-size: var(--t-eyebrow);
    font-weight: 500;
    letter-spacing: var(--track-eyebrow);
    text-transform: uppercase;
    color: var(--text-muted);
}

@media (max-width: 640px) {
    .stats-inner { grid-template-columns: 1fr; gap: var(--space-5); }
}

/* Working notes / kit list */
.kit {
    padding: clamp(4rem, 8vw, 7rem) var(--gutter);
}
.kit-inner {
    max-width: var(--container-narrow);
    margin-inline: auto;
}
.kit-head { margin-bottom: var(--space-7); }
.kit-rows {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
    border-top: 1px solid var(--rule);
}
.kit-row {
    display: grid;
    grid-template-columns: 0.4fr 1fr;
    gap: var(--space-5);
    padding-block: var(--space-5);
    border-bottom: 1px solid var(--rule);
}
.kit-row dt {
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding-top: 0.2em;
}
.kit-row dd {
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--text);
}

/* --------------------------------------------------------------------------
   16. SCROLL REVEALS
   -------------------------------------------------------------------------- */
[data-reveal] {
    opacity: 0;
    transform: translateY(28px);
    transition: opacity 1s var(--ease-out-quart), transform 1.1s var(--ease-out-expo);
    will-change: opacity, transform;
}
[data-reveal].is-revealed {
    opacity: 1;
    transform: translateY(0);
}

[data-reveal-image] {
    overflow: hidden;
    position: relative;
    /* Subtle fade-in, no opaque curtain. The previous version layered a
       background-coloured ::before that scaled from scaleY(1) to scaleY(0)
       on reveal — caught mid-animation, the panel rendered as a half-height
       opaque rectangle covering the bottom of the image, which is the
       "weird half transparent rectangle under the photographs" people kept
       seeing on the home hero/bento on slower scrolls. The image's own
       gentle scale-up is plenty of reveal motion on its own. */
    opacity: 0;
    transition: opacity 0.9s var(--ease-out-quart);
}
[data-reveal-image].is-revealed {
    opacity: 1;
}
[data-reveal-image] img {
    transform: scale(1.08);
    transition: transform 1.6s var(--ease-out-expo);
}
[data-reveal-image].is-revealed img {
    transform: scale(1);
}

/* Reveal stagger */
[data-reveal-stagger] > * { transition-delay: calc(var(--i, 0) * 80ms); }

/* --------------------------------------------------------------------------
   17. ACCESSIBILITY / REDUCED MOTION
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    .hero-slide.is-active img { animation: none; transform: scale(1); }
    [data-reveal], [data-reveal-image] { opacity: 1; transform: none; }
}

/* Skip link */
.skip-link {
    position: absolute;
    top: -100px;
    left: 1rem;
    z-index: 200;
    padding: 0.6rem 1rem;
    background: var(--ink-10);
    color: var(--bg);
    font-size: 0.875rem;
    border-radius: 4px;
    transition: top var(--d-1);
}
.skip-link:focus { top: 1rem; }

/* --------------------------------------------------------------------------
   ABOUT — moments strip (additional portraits)
   -------------------------------------------------------------------------- */
.about-moments {
    padding: clamp(3rem, 6vw, 5rem) var(--gutter) clamp(1rem, 3vw, 2rem);
}
.about-moments-inner {
    max-width: var(--container);
    margin-inline: auto;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(1rem, 2.5vw, 2rem);
}
.about-moment {
    margin: 0;
    position: relative;
    overflow: hidden;
    border-radius: var(--radius-card);
    background: var(--ink-90);
}
.about-moment picture, .about-moment img {
    display: block;
    width: 100%;
    height: 100%;
}
.about-moment img {
    aspect-ratio: 4 / 5;
    object-fit: cover;
    transition: transform 1.2s var(--ease-out-expo);
}
.about-moment:hover img { transform: scale(1.03); }
.about-moment figcaption {
    position: absolute;
    left: var(--space-4);
    bottom: var(--space-4);
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(245,242,236,0.92);
    padding: 0.4rem 0.7rem;
    background: rgba(11,12,14,0.42);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border-radius: var(--radius-pill);
}
@media (max-width: 720px) {
    .about-moments-inner { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   TESTIMONIAL — "All reviews on Google" link
   -------------------------------------------------------------------------- */
.testimonial-source {
    margin-top: var(--space-6);
    text-align: center;
    /* Stack the rating, link, and attribution vertically with breathing room
       so each line reads on its own. Mobile defaults to wrap thanks to the
       inline-flex children below. */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
}
.testimonial-source a {
    color: rgba(245,242,236,0.62);
    transition: color var(--d-1);
}
.testimonial-source a:hover {
    color: var(--accent-soft);
}

/* "★ 5.0 from 16 Google reviews" — sits above the "All reviews" link. The
   star uses the same accent-soft color as the active testimonial dot so the
   eye groups the rating with the rest of the testimonial section. */
.testimonial-rating {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35rem;
    font-family: var(--font-mono);
    font-size: var(--t-caption);
    letter-spacing: 0.06em;
    color: rgba(245,242,236,0.85);
}
.testimonial-rating[hidden] { display: none; }
.testimonial-stars {
    color: var(--accent-soft);
    font-size: 1em;
    line-height: 1;
}
.testimonial-count {
    color: rgba(245,242,236,0.55);
    font-size: 0.875em;
}

/* Required Google attribution per Places API ToS. Tiny and muted — meets
   the requirement without competing visually with the actual reviews. */
.testimonial-attribution {
    font-size: 0.625rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: rgba(245,242,236,0.4);
}
.testimonial-attr a {
    color: inherit;
    transition: color var(--d-1);
}
.testimonial-attr a:hover { color: var(--accent-soft); }

/* --------------------------------------------------------------------------
   NOT FOUND (404) — moved out of the inline <style> block in 404.html so we
   can drop 'unsafe-inline' from the production CSP.
   -------------------------------------------------------------------------- */
.nf {
    min-height: 100vh;
    display: grid;
    place-items: center;
    text-align: center;
    padding: var(--gutter);
    background: var(--ink-05);
    color: #F5F2EC;
    position: relative;
    overflow: hidden;
}
.nf-bg {
    position: absolute; inset: 0;
    background-image: url('../images/landscape/landscape_046_large.webp');
    background-size: cover;
    background-position: center;
    filter: grayscale(0.6) brightness(0.45);
    transform: scale(1.05);
    animation: nfDrift 30s ease-in-out infinite alternate;
}
@keyframes nfDrift { to { transform: scale(1.1) translate(-2%, -1%); } }
.nf-wash {
    position: absolute; inset: 0;
    background: radial-gradient(ellipse at center, rgba(11,12,14,0.2) 0%, rgba(11,12,14,0.75) 100%);
}
.nf-content {
    position: relative; z-index: 2;
    max-width: 640px;
}
.nf-num {
    font-family: var(--font-display);
    font-weight: 300;
    font-size: clamp(8rem, 28vw, 22rem);
    line-height: 0.85;
    letter-spacing: -0.04em;
    margin-bottom: var(--space-5);
    font-variation-settings: 'opsz' 144;
    color: #F5F2EC;
}
.nf-num em { font-style: italic; color: var(--accent-soft); }
.nf h1 {
    color: #F5F2EC;
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    margin-bottom: var(--space-4);
}
.nf p {
    color: rgba(245,242,236,0.7);
    margin-bottom: var(--space-7);
}
.nf .btn { color: #F5F2EC; border-color: rgba(255,255,255,0.4); }
.nf .btn:hover { background: #F5F2EC; color: var(--ink-10); border-color: #F5F2EC; }
