/* ================================================================
   ABOUT.CSS — About Us page only (page-about-us.php)
   Loaded only there. Reuses the sitewide .section-label/.section-title/
   .btn-primary/.btn-outline primitives from main.css for consistency
   with the rest of the site.
   ================================================================ */

/* ── Hero — real storefront photo behind the headline ────────────── */

/* Hero pins in place (position:fixed, behind everything) while the
   page scrolls; .about-hero__spacer reserves its height in normal
   flow so .about-content — one single positioned layer holding every
   section below — scrolls up and over it like a curtain, instead of
   the hero scrolling away with the rest of the page. */
.about-hero {
    position: fixed;
    inset: 0;
    z-index: 0;
    display: flex;
    align-items: center;
    overflow: hidden;
}

.about-hero__spacer {
    height: 100vh;
    height: 100dvh;
}

.about-content {
    position: relative;
    z-index: 1;
    background: var(--color-bg);
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    box-shadow: 0 -12px 40px rgba(7, 25, 41, 0.25);
}

/* The sitewide footer is a sibling of <main>, not a child of
   .about-content — but it already carries position:relative (see
   main.css), which is enough to pull it into the same root stacking
   order as .about-content's explicit z-index:1. Without its own
   z-index it landed BELOW that layer, so the still-pinned Sponsor
   photo (.people-pin, permanently position:fixed once reached — see
   the section-people comment) was painting over it. Bumping it above
   both .about-content and the pin fixes that, only on this page.
   Its sitewide margin-top (main.css) also has to go here specifically
   — that gap belongs to neither element, so it isn't covered by
   either one's opaque background, and the pinned photo was showing
   through that strip too. */
.site-footer {
    position: relative;
    z-index: 2;
    margin-top: 0;
}

.about-hero__bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center 30%;
    /* Scaled up so the parallax shift (about.js) always has overscan
       to move within — never exposes an edge. */
    transform: scale(1.15);
    will-change: transform;
}

.about-hero__scrim {
    /* Flat tint only — no gradient, same rule as every overlay
       elsewhere on this site. */
    position: absolute;
    inset: 0;
    background: rgba(7, 25, 41, 0.68);
}

.about-hero__grid {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-block: var(--sp-16);
    text-align: center;
}

.about-hero__content {
    max-width: 620px;
    margin-inline: auto;
}

.about-hero__eyebrow {
    display: inline-block;
    font-size: clamp(var(--text-base), 1.6vw, var(--text-lg));
    font-style: italic;
    font-weight: var(--fw-medium);
    color: var(--color-blue-light);
    margin-bottom: var(--sp-3);
}

.about-hero__title {
    font-size: clamp(3rem, 8vw, 5.5rem);
    font-weight: var(--fw-black);
    letter-spacing: var(--ls-display);
    line-height: 0.95;
    color: var(--color-white);
    margin-bottom: var(--sp-4);
}

.about-hero__sub {
    font-size: var(--text-lg);
    color: rgba(255, 255, 255, 0.8);
}

/* A slow breathing fade, not a hard blink — the one bit of motion in
   an otherwise still hero, small enough not to compete with the
   headline. Paused under prefers-reduced-motion (see rule below). */
.about-hero__scroll-hint {
    position: absolute;
    left: 50%;
    bottom: var(--sp-8);
    z-index: 1;
    transform: translateX(-50%);
    font-size: var(--text-xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.75);
    animation: about-scroll-hint-breathe 3.6s ease-in-out infinite;
}

@keyframes about-scroll-hint-breathe {
    0%, 100% { opacity: 0.3; }
    50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .about-hero__scroll-hint {
        animation: none;
    }
}

/* ── Opening narrative — a small crest, one centered manifesto
   paragraph, on the same off-white as the rest of the page. ─────── */

.section-story {
    position: relative;
    background: var(--color-bg);
}

.story-narrow {
    position: relative;
    max-width: 760px;
    margin-inline: auto;
    padding-block: clamp(var(--sp-16), 10vw, var(--sp-20));
    text-align: center;
}

.story-crest {
    height: 52px;
    width: auto;
    margin-inline: auto;
    margin-bottom: var(--sp-6);
}

.story-manifesto {
    font-size: clamp(var(--text-xl), 2.8vw, var(--text-2xl));
    line-height: var(--lh-relaxed);
    color: var(--color-navy);
}

/* ── Ribbon — a two-phrase ticker that scrolls horizontally as the
   page scrolls vertically (driven by window.scrollY, see about.js),
   not a timed auto-loop. Content is rendered twice back to back so
   the translateX can wrap at -50% with no visible seam. ──────────── */

.story-ribbon {
    position: relative;
    overflow: hidden;
    background: var(--color-navy);
    padding-block: var(--sp-4);
}

.story-ribbon__track {
    display: flex;
    align-items: center;
    width: max-content;
    white-space: nowrap;
    will-change: transform;
}

.story-ribbon__item {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-3);
    padding-inline: var(--sp-6);
    font-size: var(--text-sm);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--color-white);
    flex-shrink: 0;
}

.story-ribbon__item img {
    height: 16px;
    width: auto;
    flex-shrink: 0;
}

/* ── Facts — bento grid ───────────────────────────────────────────
   Two independent columns, not a shared row grid: the left column
   runs one big card into one medium card (different weights); the
   right column runs two matched cards into a CTA pill that's just
   whatever's left over. Each column sizes itself by its own content,
   so nothing has to be artificially stretched to line up with the
   other side. ─────────────────────────────────────────────────────── */

.section-facts {
    background: var(--color-bg);
    padding-block: var(--sp-12);
}

.facts-bento {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
}

@media (min-width: 720px) {
    .facts-bento {
        flex-direction: row;
        align-items: stretch;
    }
}

.facts-col {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
}

.facts-col--left { flex: 1.3; min-width: 0; }
.facts-col--right { flex: 1; min-width: 0; }

.facts-card {
    position: relative;
    background: var(--color-navy);
    border-radius: var(--r-xl);
    padding: var(--sp-6);
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    overflow: hidden;
    transition: transform var(--t-spring), box-shadow var(--t-spring);
}

.facts-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-card-hover);
}

/* Explicit min-heights (not just flex-grow ratios) so the size
   hierarchy actually reads at a glance — big is ~60% taller than
   medium, medium and match are each roughly the same again. */
.facts-card--big { flex-grow: 3; min-height: 320px; }
.facts-card--medium { flex-grow: 2; min-height: 190px; }

/* Match cards pack their content at the bottom edge instead of
   inheriting the base space-between — with only a number and a label
   (no long desc to anchor against), space-between stranded them at
   opposite ends of the card with an ugly empty gap between. */
.facts-card--match {
    flex-grow: 1;
    min-height: 180px;
    justify-content: flex-end;
}

/* This one card centers its content instead of packing to the
   bottom like its sibling match cards — the logo row needs even
   breathing room above and below it, down to the "9" / label text.
   flex-grow:0 (overriding the base match card's flex-grow:1) keeps
   it pinned to that natural size instead of stretching to soak up
   whatever extra height the column has to give — the photo card
   next to it can carry that slack far better than an empty gap
   around a logo row can. */
.facts-card--brands {
    flex-grow: 0;
    min-height: 130px;
    justify-content: center;
}

/* Real product photo (D1 Milano, one of the 9 brands we carry) as
   the background. A flat navy tint (the same --color-navy every
   other card uses as a solid fill) sits over the whole photo so this
   card reads as the same colour as its neighbours instead of
   whatever raw tone the photo happens to be — strong enough on the
   left for the text, sheer enough on the right that the watch still
   shows through. Flat block, not a gradient fade, same rule as every
   other overlay on this site. */
.facts-card--photo {
    background-size: cover;
    background-position: right center;
}

.facts-card--photo::before {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(11, 37, 64, 0.72);
}

.facts-card--match .facts-card__desc {
    font-size: var(--text-base);
    margin-bottom: var(--sp-2);
}

.facts-card__desc {
    position: relative;
    z-index: 1;
    font-size: var(--text-sm);
    color: rgba(255, 255, 255, 0.65);
    max-width: 30ch;
    margin-bottom: var(--sp-6);
}

.facts-card__num,
.facts-card__label {
    position: relative;
    z-index: 1;
}

/* A large, faint crest bleeding off the corner — the one bit of
   decorative depth on the flagship card, an image watermark rather
   than a gradient glow (this theme never uses gradient fills). */
.facts-card__watermark {
    position: absolute;
    right: -12%;
    bottom: -14%;
    height: 78%;
    width: auto;
    opacity: 0.07;
    pointer-events: none;
}

.facts-card__num {
    display: block;
    font-size: clamp(2.75rem, 6vw, 4rem);
    font-weight: var(--fw-black);
    letter-spacing: var(--ls-display);
    line-height: 1;
    color: var(--color-white);
}

.facts-card__num--sm {
    font-size: clamp(2rem, 4vw, 2.5rem);
}

.facts-card__label {
    display: block;
    margin-top: var(--sp-2);
    font-size: var(--text-sm);
    color: rgba(255, 255, 255, 0.65);
}

.facts-card__rating {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-2);
}

/* Two stacked star rows, not five flat glyphs — the filled row is
   clipped to the exact rating (98% ≈ 4.9/5) so the stars themselves
   show the real number instead of rounding up to a full 5. */
.facts-card__stars {
    position: relative;
    display: inline-block;
    font-size: clamp(1.3rem, 2.2vw, 1.6rem);
    letter-spacing: 4px;
    line-height: 1;
}

.facts-card__stars-track {
    display: block;
    color: rgba(255, 255, 255, 0.18);
}

.facts-card__stars-fill {
    position: absolute;
    inset: 0;
    overflow: hidden;
    white-space: nowrap;
    color: var(--color-blue-light);
}

.facts-card__num-suffix {
    font-size: 0.4em;
    font-weight: var(--fw-bold);
    color: rgba(255, 255, 255, 0.5);
    margin-left: 2px;
}

.facts-card__rating-footer {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
}

.facts-card__rating-footer .facts-card__label {
    margin-top: 0;
}

.facts-card__review-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    flex-shrink: 0;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.3);
    color: var(--color-white);
    border-radius: var(--r-lg);
    padding: var(--sp-2) var(--sp-4);
    font-size: var(--text-sm);
    font-weight: var(--fw-bold);
    transition: background var(--t-fast), border-color var(--t-fast);
}

.facts-card__review-btn-logo {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.facts-card__review-btn:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.6);
}

.facts-card__review-btn-arrow {
    display: inline-block;
    font-size: 0.8em;
    margin-left: 2px;
    transition: transform var(--t-fast);
}

.facts-card__review-btn:hover .facts-card__review-btn-arrow {
    transform: translateX(2px);
}

/* Brand-logo marquee — .facts-brand-window is the fixed clipped
   frame; .facts-brand-track is a CSS-only infinite auto-scroll (the
   PHP renders the 9 logos twice back to back, and the animation
   loops by translating exactly one set-width, -50%, so the seam is
   invisible). Same duplicate-and-wrap technique as the story ribbon
   ticker, just time-driven instead of scroll-linked. Every logo sits
   in an identical box and is recoloured white via filter, so 9
   differently-shaped brand marks read as one consistent set instead
   of each having its own size and colour. */
.facts-brand-window {
    width: 100%;
    min-width: 0;
    height: 64px;
    overflow: hidden;
    margin-bottom: var(--sp-5);
}

.facts-brand-track {
    display: flex;
    width: max-content;
    animation: facts-brand-scroll 16s linear infinite;
}

.facts-brand-track__item {
    flex: 0 0 118px;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.facts-brand-track__item img {
    max-height: 64px;
    max-width: 104px;
    width: auto;
    object-fit: contain;
    filter: brightness(0) invert(1);
    opacity: 0.6;
}

@keyframes facts-brand-scroll {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .facts-brand-track { animation: none; }
}

.facts-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-3);
    background: transparent;
    border: 2px solid var(--color-navy);
    color: var(--color-navy);
    border-radius: var(--r-xl);
    padding-block: calc(var(--sp-6) - 2px);
    font-size: var(--text-base);
    font-weight: var(--fw-black);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    transition: background var(--t-fast), color var(--t-fast);
}

.facts-cta:hover {
    background: var(--color-navy);
    color: var(--color-white);
}

.facts-cta__dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--color-navy);
    animation: facts-cta-pulse 1.8s ease-in-out infinite;
    transition: background var(--t-fast);
}

.facts-cta:hover .facts-cta__dot {
    background: var(--color-white);
}

@keyframes facts-cta-pulse {
    0%, 100% { opacity: 0.4; }
    50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .facts-cta__dot { animation: none; }
}

/* ── Brands — same poster-card look AND the same slow ambient
   auto-drift rail as the homepage's Shop by Brand (home.css's
   .rail/.rail--brands/.brand-card), copied rather than shared since
   this page doesn't load home.css/home.js. The card set is rendered
   twice back to back (page-about-us.php) so about.js's drift can loop
   seamlessly against half the track's scrollWidth, same technique as
   the story ribbon and the facts brand marquee elsewhere on this
   page — still freely swipeable by hand at any time. ──────────────── */

.section-brands {
    padding-block: clamp(var(--sp-16), 8vw, var(--sp-20));
}

.section-brands > .container > .section-title {
    margin-bottom: var(--sp-8);
}

.about-brands-rail {
    display: flex;
    gap: var(--sp-4);
    overflow-x: auto;
    overflow-y: hidden;
    padding-inline: var(--container-pad);
    padding-block: var(--sp-2);
    scrollbar-width: none;
    -ms-overflow-style: none;
    max-width: var(--container-max);
    margin-inline: auto;
    mask-image: linear-gradient(to right, transparent 0, black 48px, black calc(100% - 48px), transparent 100%);
    -webkit-mask-image: linear-gradient(to right, transparent 0, black 48px, black calc(100% - 48px), transparent 100%);
}

.about-brands-rail::-webkit-scrollbar { display: none; }

.about-brand-card {
    display: block;
    flex: 0 0 auto;
    width: 148px;
    aspect-ratio: 9 / 16;
    border-radius: var(--r-lg);
    overflow: hidden;
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    transition: transform var(--t-spring), box-shadow var(--t-base);
}

@media (min-width: 768px) {
    .about-brand-card { width: 176px; }
}

.about-brand-card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.about-brand-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-card-hover);
}

.about-brand-card:active {
    transform: translateY(0) scale(0.97);
    transition: transform var(--t-press);
}

@media (prefers-reduced-motion: reduce) {
    .about-brand-card:hover { transform: none; box-shadow: var(--shadow-sm); }
}

/* ── Founder / Sponsor — pinned scroll-crossfade ──────────────────
   .people-scroller is a tall (240vh) container; .people-pin sticks to
   the viewport for the full scroll of that container, giving 140vh of
   scroll "budget" during which about.js drives the founder → sponsor
   opacity crossfade directly off scroll position (scroll-scrubbed —
   no timer, no easing lag, just tracks the scrollbar 1:1). Both
   photos already carry their spotlight vignette baked in (see the
   PHP comment above), so no extra CSS filter/scrim gymnastics are
   needed here beyond a flat text-legibility scrim.

   Unlike a normal sticky element, .people-pin never "releases" back
   into the document once its scroll budget runs out — it just stays
   fixed, exactly like .about-hero does for the rest of the page (see
   above). What makes it look like it goes away is .people-cover: a
   second, independently positioned + opaque layer (holding Brands
   onward) that slides up over it, the same curtain trick nested one
   level deeper. */

.section-people {
    position: relative;
    z-index: 0;
    background: var(--color-navy);
}

.people-scroller {
    position: relative;
    height: 240vh;
}

/* position:sticky would be the obvious choice here, but this site
   sets overflow-x:hidden on <body> (to stop other full-bleed sections
   causing horizontal scroll) — and that single declaration is enough
   to make Chromium/WebKit quietly ignore sticky on any descendant,
   however deep. Same fixed+spacer workaround already proven on the
   hero: .people-pin defaults to position:absolute pinned to the top
   of .people-scroller, and about.js flips it to position:fixed while
   .people-scroller is in view — and, unlike the hero's own scroller,
   simply stays fixed once past it too (see the comment above), so
   .people-cover can curtain over it instead of it scrolling away. */
.people-pin {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    overflow: hidden;
}

.people-cover {
    position: relative;
    z-index: 1;
    background: var(--color-bg);
}

.people-slide {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    opacity: 0;
}

.people-slide--founder {
    opacity: 1;
}

.people-slide__bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
}

.people-slide__scrim {
    position: absolute;
    inset: 0;
    background: rgba(7, 25, 41, 0.25);
}

.people-slide__text {
    position: relative;
    z-index: 1;
    padding-bottom: clamp(var(--sp-12), 8vw, var(--sp-20));
    max-width: 640px;
}

/* The clamp() above tops out at --sp-12 (48px) on a narrow phone —
   plenty of clearance on desktop/tablet, but the fixed mobile
   .tab-bar (main.css) alone is 60px tall plus its own ~12px gap off
   the bottom edge, so 48px of padding let it sit over the quote.
   Centering the text instead (tried first) traded that for a worse
   problem — on a short phone it landed the text over the person's
   face instead, since the face sits a fixed ~26-44% down the photo
   regardless of viewport height while the tab-bar's height doesn't
   scale down with it. Staying bottom-anchored (like desktop) and
   just clearing the tab-bar's actual height keeps text off the face
   on every viewport, same as it already was on desktop. */
@media (max-width: 767px) {
    .people-slide__text {
        padding-bottom: calc(3.75rem + var(--sp-3) + var(--sp-6) + env(safe-area-inset-bottom, 0px));
    }
}

.person-row__byline {
    font-size: var(--text-xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.7);
    margin-bottom: var(--sp-4);
}

.person-row__quote {
    font-size: clamp(1.5rem, 3.2vw, 2.25rem);
    font-weight: var(--fw-medium);
    line-height: var(--lh-tight);
    color: var(--color-white);
}

/* Mobile-only reframe. Both source photos are 1600x900 with the
   person off to one side (founder's face sits around x≈420 of 1600;
   sponsor's around x≈1130) rather than centered — on desktop that's
   fine since .people-pin's 100vh there is wide enough that cover-fit
   is width-driven and shows the photo's full width. On a phone
   .people-pin is just as tall but far narrower, so the same cover-fit
   becomes height-driven instead: the image's full height always
   fills the box with zero vertical slack, which forces WAY more
   horizontal zoom to still "cover" — only the center ~25-30% of the
   1600px width ends up visible. background-position:center (the
   desktop-perfect default) was pointing that narrow window at the
   image's literal midpoint, x=800 — nowhere near either person — so
   both read as "not visible" on phones. Repointed per-slide to each
   person's actual position instead of a shared center value; no
   change to background-size, so neither is any more "zoomed" than
   the default cover crop already was. */
@media (max-width: 767px) {
    #peopleFounder .people-slide__bg {
        background-position: 20% center;
    }

    #peopleSponsor .people-slide__bg {
        background-position: 78% center;
    }
}

/* Reduced motion: the pin/crossfade IS the motion, so there's no
   watered-down version of it — instead just stack both slides as
   normal, static, full-height sections so the sponsor's photo and
   quote stay reachable rather than stuck at opacity:0 forever. */
@media (prefers-reduced-motion: reduce) {
    .people-scroller {
        height: auto;
    }

    .people-pin {
        position: static;
        height: auto;
    }

    .people-slide {
        position: relative;
        inset: auto;
        height: 70vh;
        opacity: 1;
    }
}

/* ── Gallery wall ─────────────────────────────────────────────────
   Full-bleed, fixed-height window onto several vertical columns of
   real photos, each column auto-scrolling continuously (pure CSS
   @keyframes — always perfectly smooth, no rAF/JS needed since
   nothing here needs to pause for a manual drag). Columns alternate
   direction (odd ones up, even ones down) for a bit of visual
   rhythm, and a mask-image fades the top/bottom edges so tiles
   appear to dissolve in and out rather than getting cut off flat. */

.section-gallery {
    padding-block: clamp(var(--sp-12), 8vw, var(--sp-16)) 0;
    background: var(--color-surface);
    overflow: hidden;
}

.gallery-wall {
    position: relative;
    display: flex;
    gap: var(--sp-4);
    height: 640px;
    margin-block: clamp(var(--sp-10), 6vw, var(--sp-14));
    padding-inline: var(--container-pad);
    mask-image: linear-gradient(to bottom, transparent 0, black 14%, black 86%, transparent 100%);
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, black 14%, black 86%, transparent 100%);
}

.gallery-wall__col {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
    animation: gallery-wall-up 46s linear infinite;
}

.gallery-wall__col--reverse {
    animation-name: gallery-wall-down;
}

.gallery-wall__tile {
    flex: 0 0 auto;
    width: 100%;
    height: 240px;
    border-radius: var(--r-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}

.gallery-wall__tile img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

@keyframes gallery-wall-up {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(0, -50%, 0); }
}

@keyframes gallery-wall-down {
    from { transform: translate3d(0, -50%, 0); }
    to   { transform: translate3d(0, 0, 0); }
}

@media (max-width: 640px) {
    .gallery-wall { height: 480px; }
    .gallery-wall__tile { height: 180px; }
    /* Only 2 columns' worth of room on a phone — hide the rest rather
       than squeeze 4 columns down to illegible slivers. */
    .gallery-wall__col:nth-child(n+3) { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .gallery-wall__col { animation: none; }
    .gallery-wall { height: auto; overflow-y: auto; }
}

.gallery-cta {
    margin-top: var(--sp-4);
    text-align: center;
}

/* ── Visit / CTA band ─────────────────────────────────────────────
   "Visit Us" is the centered title outside the card (.section-
   heading-center, shared with every other section heading on this
   page). The place name + hours sit inside the card as a caption
   over the photo, which drifts on a scroll-linked parallax
   (.visit-card__bg is scaled up for overscan, same technique as the
   hero background). A small text+arrow pill anchors the bottom. */

.section-visit {
    padding-block: clamp(var(--sp-12), 8vw, var(--sp-16));
}

.section-visit .section-heading-center {
    margin-bottom: clamp(var(--sp-6), 4vw, var(--sp-8));
}

.visit-card {
    position: relative;
    display: flex;
    align-items: center;
    border-radius: var(--r-2xl);
    overflow: hidden;
    height: clamp(280px, 34vw, 380px);
    padding-inline: var(--sp-8);
}

.visit-card__bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center 25%;
    transform: scale(1.2);
    will-change: transform;
}

/* Flat tint, not a gradient — same rule as every other photo overlay
   on this site. The storefront photo already has its own dark navy
   half (the map background), so this just keeps text legible without
   fighting that. */
.visit-card__scrim {
    position: absolute;
    inset: 0;
    background: rgba(7, 25, 41, 0.45);
}

.visit-card__info {
    position: relative;
    z-index: 1;
}

.visit-card__place {
    font-size: var(--text-xl);
    font-weight: var(--fw-black);
    letter-spacing: var(--ls-display);
    color: var(--color-white);
    margin-bottom: var(--sp-4);
}

.visit-hours {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}

.visit-hours li {
    display: flex;
    gap: var(--sp-4);
    font-size: var(--text-sm);
    color: rgba(255, 255, 255, 0.8);
}

.visit-hours li span:first-child {
    font-weight: var(--fw-semi);
    color: var(--color-white);
    min-width: 90px;
}

.visit-card__arrow-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    margin-top: var(--sp-5);
    padding: var(--sp-3) var(--sp-5);
    border-radius: var(--r-lg);
    background: rgba(7, 25, 41, 0.4);
    border: 1px solid rgba(255, 255, 255, 0.45);
    color: var(--color-white);
    font-size: var(--text-base);
    font-weight: var(--fw-bold);
    transition: background var(--t-fast), border-color var(--t-fast);
}

.visit-card__arrow-btn svg {
    width: 17px;
    height: 17px;
}

.visit-card__arrow-btn:hover {
    background: rgba(255, 255, 255, 0.15);
    border-color: var(--color-white);
}

@media (prefers-reduced-motion: reduce) {
    .gallery-item:hover img { transform: none; }
}
