/* ================================================================
   HOME.CSS — Homepage-only styles
   Loaded only on the front page. All values use design tokens.

   Rebuilt 2026-09-13 as an app-style home screen: a compact banner
   instead of a full-viewport cinematic hero, search up front, and
   stacked horizontal-scroll rails (brands / shop-by-time / deals /
   new arrivals) instead of separate full-bleed marketing sections.
   ================================================================ */

/* The hero is position:fixed now (curtain technique below) and
   handles its own top clearance internally via --header-h, so body's
   own padding-top would just double it up — zeroed here the same way
   the Brands and About pages cancel it for their own fixed heroes. */
body.home {
    padding-top: 0;
}

/* ================================================================
   NAV — transparent-to-opaque on homepage
   ================================================================ */

body.home .site-nav:not(.is-scrolled) {
    background: transparent;
    box-shadow: none;
}

body.home .site-nav.is-scrolled {
    background: rgba(11, 37, 64, 0.94);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), var(--shadow-md);
}

/* ================================================================
   HERO — full-screen statement over real photography, pinned in place
   (position:fixed, behind everything) while the page scrolls — same
   curtain technique as the About/Brands page heroes (about.css /
   brands-page.css): .hero-statement__spacer reserves its height in
   normal flow so .home-content (every section below, opaque +
   z-index:1) scrolls up and over it, instead of the hero scrolling
   away with the rest of the page. A flat solid scrim sits between the
   photo and the content for legibility — not a gradient (standing
   rule), just one solid navy tone at fixed opacity.

   --header-h differs from the Brands/About pages: on desktop the nav
   is deliberately transparent over this hero (home.css's NAV rules
   below) and floats within its own space rather than pushing content
   down, so only the utility bar needs clearing here. On mobile the
   nav is replaced by the solid mobile-brand-bar, which does need full
   clearance the same way the other pages' fixed bars do. */

.hero-statement {
    --header-h: calc(var(--utility-bar-h) + var(--mobile-brand-bar-h));
    position: fixed;
    inset: 0;
    z-index: 0;
    padding-top: var(--header-h);
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    background: var(--color-navy-dark);
    overflow: hidden;
}

@media (min-width: 768px) {
    .hero-statement {
        --header-h: var(--utility-bar-h);
    }
}

.hero-statement__spacer {
    height: 100vh;
    height: 100dvh;
}

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

/* Same reason as about.css's .site-footer override — the footer is a
   sibling of <main>, not a child of .home-content, but it still needs
   pulling above the fixed hero's stacking level, and its sitewide
   margin-top (main.css) zeroed too, or that gap shows the hero
   through it. */
body.home .site-footer {
    position: relative;
    z-index: 2;
    margin-top: 0;
}

.hero-statement__bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    background-color: var(--color-navy-dark);
}

/* Blur-swipe crossfade — the outgoing photo drifts left and blurs away
   while the next drifts in from the right and sharpens (home.js walks
   .is-active/.is-exiting). The original slideshow mechanic, brought
   back at the user's request. */
.hero__slide {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center 32%;
    opacity: 0;
    /* 1.5 scale (up from 1.14) gives the parallax layer ~25% overscan
       on each edge — enough headroom for the much larger PARALLAX_MAX
       (home.js §4) to drift the whole background without ever exposing
       a hard edge. */
    transform: scale(1.5) translateX(6%);
    filter: blur(24px);
    transition: opacity 1.6s cubic-bezier(0.4, 0, 0.2, 1),
                transform 1.6s cubic-bezier(0.4, 0, 0.2, 1),
                filter 1.6s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 1;
}

.hero__slide.is-active {
    opacity: 1;
    transform: scale(1.5) translateX(0%);
    filter: blur(0);
    z-index: 2;
}

.hero__slide.is-exiting {
    opacity: 0;
    transform: scale(1.5) translateX(-6%);
    filter: blur(24px);
    z-index: 1;
}

.hero-statement__scrim {
    position: absolute;
    inset: 0;
    background: rgba(7, 25, 41, 0.82);
}

@media (prefers-reduced-motion: reduce) {
    .hero__slide { transition: none; transform: none; filter: none; }
}

.hero-statement__inner {
    position: relative;
    z-index: 1;
    max-width: 720px;
    margin-inline: auto;
    text-align: center;
    padding-block: var(--sp-16);
}

/* A quiet intro line, not a second headline — small, tracked-out
   uppercase (matches .section-label's vocabulary used sitewide) and a
   softer, less saturated blue than the solid brand blue, so it reads
   as a lead-in sitting just above the real headline instead of
   competing with it. Tight margin-bottom pulls it close to the
   headline so the two read as one grouped unit. */
.hero-statement__eyebrow {
    font-size: var(--text-xs);
    font-weight: var(--fw-semi);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: rgba(103, 136, 212, 0.85);
    margin-bottom: var(--sp-3);
}

.hero-statement__title {
    /* Low floor on purpose — "Some People Check the Time." is the
       longer of the two lines and needs to stay on one line even on
       a narrow phone; the old 1.75rem floor ignored the vw scaling
       below ~470px and forced a mid-phrase wrap. */
    font-size: clamp(1.05rem, 5.2vw, var(--text-4xl));
    font-weight: var(--fw-black);
    line-height: var(--lh-tight);
    letter-spacing: var(--ls-display);
    text-transform: uppercase;
    color: var(--color-white);
    margin-bottom: var(--sp-8);
    white-space: nowrap;
}

.hero-statement__actions {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--sp-3);
    margin-bottom: var(--sp-10);
}

/* Big pill CTA with a trailing circular icon badge that inverts on
   hover and its arrow swings from a diagonal to a flat "go" pointer —
   reference: lucky-powerpoint-520697.framer.app's "Circle Expand
   Button" — reinterpreted in the site's own navy/blue/white instead
   of that demo's gray/black/white. The badge is a single ::after (no
   extra markup): background-color draws the circle, background-image
   draws the arrow on top of it, and both cross-fade/swap together
   with the pill's own color flip. Rotating the whole badge (not just
   the arrow) is what makes a plain right-pointing glyph read as
   diagonal at rest — the circle itself looks identical at any
   rotation, so only the arrow inside visibly swings. */
.hero-statement__btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--sp-4) var(--sp-8);
    padding-right: 3.5rem;
    border-radius: var(--r-full);
    font-size: var(--text-sm);
    font-weight: var(--fw-bold);
    transition: background var(--t-base), color var(--t-base), transform var(--t-spring), border-color var(--t-base);
}

.hero-statement__btn::after {
    content: '';
    position: absolute;
    top: 50%;
    right: var(--sp-2);
    width: 2rem;
    height: 2rem;
    margin-top: -1rem;
    border-radius: 50%;
    background-repeat: no-repeat;
    background-position: center;
    background-size: 13px;
    transform: rotate(0deg);
    transition: background-color var(--t-base), border-color var(--t-base), transform var(--t-spring);
}

.hero-statement__btn--solid {
    background: var(--color-blue);
    color: var(--color-white);
}

.hero-statement__btn--solid::after {
    background-color: var(--color-white);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232655C2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M9 7h8v8'/%3E%3C/svg%3E");
}

.hero-statement__btn--solid:hover {
    background: var(--color-white);
    color: var(--color-navy);
    transform: translateY(-2px);
}

.hero-statement__btn--solid:hover::after {
    background-color: var(--color-navy);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M9 7h8v8'/%3E%3C/svg%3E");
    transform: rotate(45deg);
}

.hero-statement__btn--outline {
    border: 1.5px solid rgba(255, 255, 255, 0.4);
    color: var(--color-white);
}

.hero-statement__btn--outline::after {
    background-color: transparent;
    border: 1.5px solid rgba(255, 255, 255, 0.5);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M9 7h8v8'/%3E%3C/svg%3E");
}

.hero-statement__btn--outline:hover {
    border-color: var(--color-white);
    background: var(--color-white);
    color: var(--color-navy);
}

.hero-statement__btn--outline:hover::after {
    background-color: var(--color-navy);
    border-color: var(--color-navy);
    transform: rotate(45deg);
}

.hero-statement__btn:active { transform: scale(0.97); transition: transform var(--t-press); }

@media (prefers-reduced-motion: reduce) {
    .hero-statement__btn::after { transition: background-color var(--t-base), border-color var(--t-base); }
}

.hero-statement__divider {
    width: 64px;
    height: 1.5px;
    background: rgba(255, 255, 255, 0.3);
    margin: 0 auto var(--sp-8);
}

/* Mobile (<900px): an infinite marquee. Two identical .track copies sit
   side by side inside this row; both animate left by their own width
   (+ the gap to the next track) in lockstep, so as the first track
   scrolls fully out of view the second — pixel-identical — arrives to
   take its place and the loop jump is invisible. mask-image fades logos
   in/out at both edges as they cross, instead of a hard clip. */
.hero-statement__brands {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    overflow: hidden;
    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%);
}

.hero-statement__brands-track {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    flex-shrink: 0;
    animation: hero-brands-marquee 24s linear infinite;
}

@keyframes hero-brands-marquee {
    to { transform: translateX(calc(-100% - var(--sp-4))); }
}

@media (prefers-reduced-motion: reduce) {
    .hero-statement__brands-track { animation: none; }
    .hero-statement__brands-track[aria-hidden="true"] { display: none; }
    .hero-statement__brands { overflow-x: auto; mask-image: none; -webkit-mask-image: none; }
}

/* .hero-statement__brands-wrap is a sibling of .container (not nested
   inside it) precisely so this cap can go wider than .container's own
   1280px — nine logos need the room to read as genuinely big. Plain
   max-width + margin:auto here, no vw/transform breakout tricks. */
.hero-statement__brands-wrap {
    width: 100%;
}

/* On phones the floating pill tab-bar (position:fixed, bottom: ~12px,
   height 60px) sits on top of whatever's beneath it — including the
   very bottom of the hero, where the logo row lands. Giving the WHOLE
   .hero-statement extra bottom padding would also shrink the
   background layers (.hero-statement__bg/__scrim use inset:0 relative
   to it, so padding eats into them and the photo would stop reaching
   the true edge of the screen). Margin on this one last child instead:
   .hero-statement's flex justify-content:center then centers everything
   in the space above that margin, nudging the whole group up so the
   logos clear the tab bar — while the background, a separate sibling
   element, still fills 100% of the screen behind it either way. */
@media (max-width: 767px) {
    .hero-statement__brands-wrap {
        margin-bottom: calc(3.75rem + var(--sp-3) + var(--sp-4) + env(safe-area-inset-bottom, 0px));
    }
}

@media (min-width: 900px) {
    .hero-statement__brands-wrap {
        max-width: 1600px;
        margin-inline: auto;
        padding-inline: var(--sp-6);
    }
}

/* Desktop (≥900px): the marquee stops and the duplicate track is
   dropped — one static row, logos big and close together on one line. */
@media (min-width: 900px) {
    .hero-statement__brands {
        overflow: visible;
        mask-image: none;
        -webkit-mask-image: none;
        justify-content: center;
        gap: var(--sp-5);
    }

    .hero-statement__brands-track {
        animation: none;
        gap: var(--sp-5);
        /* The mobile marquee needs flex-shrink:0 so a track never
           shrinks below its natural width (that's what keeps the loop
           math exact) — but that same rule stops this now-single track
           from shrinking to fit the row on desktop, so it overflows and
           just centers-overflows off both edges instead. Allow it here. */
        flex-shrink: 1;
        min-width: 0;
        width: 100%;
    }

    .hero-statement__brands-track[aria-hidden="true"] {
        display: none;
    }
}

/* Static — real flat logo marks, already white. No hover animation,
   only the one-time entrance the whole row shares via [data-hero-in].
   Each logo sits in the SAME fixed-aspect box; object-fit: cover crops
   to fill it rather than shrinking to fit inside it (object-fit:
   contain) — the source files have wildly different natural aspect
   ratios (a wordmark vs. a wordmark-plus-crest-plus-subtext badge), and
   letterboxing them down to fit both dimensions made them read as much
   smaller/more different in size than they actually are. Uniform crop
   is what makes them look "the same size" next to each other. */
.hero-statement__brand {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    /* vw-relative, not a fixed px box — a flat 132px box was sized for
       the desktop breakout row and, applied unscaled below the 900px
       breakpoint too, read as oversized on real phones (reported "huge"
       on a Galaxy Ultra despite looking right in a 375px emulator —
       scaling with the viewport instead of a fixed number is what
       actually guarantees it looks the same, proportionally, on every
       real phone width, not just the one we happened to test). */
    width: clamp(72px, 21vw, 104px);
    aspect-ratio: 132 / 64;
    height: auto;
    opacity: 0.9;
    overflow: hidden;
}

.hero-statement__brand img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

@media (min-width: 900px) {
    .hero-statement__brand {
        flex: 1 1 0;
        min-width: 0;
        width: auto;
        max-width: 172px;
        aspect-ratio: 132 / 64;
        height: auto;
    }
}

/* ── Live weather/time pill — small, sits above the eyebrow, click/tap
   toggles between the time reading and the weather reading (home.js
   swaps the text + icon; this file just styles the shell + variants).
   Colors stay inside the brand's blue/navy family — data-tod (time of
   day) picks the tint, never an off-brand hue (no sunset-orange, etc). */
.hero-weather {
    --hw-bg:     rgba(255, 255, 255, 0.06);
    --hw-border: rgba(255, 255, 255, 0.16);

    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    /* .hero-statement__inner is text-align:center, which is what
       actually centers an inline-flex box like this one horizontally —
       margin-bottom is the only margin doing real work here. */
    margin-bottom: var(--sp-4);
    padding: var(--sp-2) var(--sp-4);
    border: 1px solid var(--hw-border);
    border-radius: var(--r-full);
    background: var(--hw-bg);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    font-family: inherit;
    cursor: pointer;
    transition: background var(--t-base), border-color var(--t-base), transform var(--t-spring);
}

.hero-weather:hover {
    border-color: rgba(255, 255, 255, 0.3);
    transform: translateY(-1px);
}

.hero-weather:active {
    transform: translateY(0) scale(0.97);
    transition: transform var(--t-press);
}

.hero-weather__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 15px;
    height: 15px;
    color: rgba(255, 255, 255, 0.7);
}

.hero-weather__icon svg {
    width: 100%;
    height: 100%;
}

.hero-weather__text {
    font-size: 0.8rem;
    font-weight: var(--fw-normal);
    letter-spacing: 0.02em;
    color: rgba(255, 255, 255, 0.85);
    font-variant-numeric: tabular-nums;
}

/* Time-of-day variants — same navy/blue family throughout, just a
   different weight of it: brighter/whiter by day, deeper/dimmer at
   night, a small blue lift at dawn and dusk. */
.hero-weather[data-tod="dawn"] {
    --hw-bg: rgba(103, 136, 212, 0.14);
    --hw-border: rgba(103, 136, 212, 0.32);
}

.hero-weather[data-tod="day"] {
    --hw-bg: rgba(255, 255, 255, 0.08);
    --hw-border: rgba(255, 255, 255, 0.22);
}

.hero-weather[data-tod="evening"] {
    --hw-bg: rgba(38, 85, 194, 0.16);
    --hw-border: rgba(38, 85, 194, 0.34);
}

.hero-weather[data-tod="night"] {
    --hw-bg: rgba(7, 25, 41, 0.5);
    --hw-border: rgba(255, 255, 255, 0.10);
}

@media (max-width: 480px) {
    .hero-weather {
        padding: var(--sp-1) var(--sp-3);
        gap: var(--sp-1);
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-weather:hover { transform: none; }
}

/* ── Entrance — a confident, staggered fade-up, not a snap-on-load.
   Driven by [data-hero-in] index (0-4), animated in home.js as soon as
   fonts/layout are ready rather than a fixed CSS delay, so it never
   fires against a half-painted page. */
[data-hero-in] {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out);
}

.hero-statement.is-in [data-hero-in="0"] { transition-delay: 0.05s; }
.hero-statement.is-in [data-hero-in="1"] { transition-delay: 0.16s; }
.hero-statement.is-in [data-hero-in="2"] { transition-delay: 0.28s; }
.hero-statement.is-in [data-hero-in="3"] { transition-delay: 0.38s; }
.hero-statement.is-in [data-hero-in="4"] { transition-delay: 0.46s; }
.hero-statement.is-in [data-hero-in="5"] { transition-delay: 0.55s; }

.hero-statement.is-in [data-hero-in] {
    opacity: 1;
    transform: translateY(0);
}

/* Any "3" — 3T's own initial — picked out in brand blue wherever a live
   or theme-authored time reading appears (shop-by-time rail, etc). */
.digit-brand {
    color: var(--color-blue);
}

@media (max-width: 480px) {
    .hero-statement__actions { flex-direction: column; width: 100%; }
    .hero-statement__btn { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
    [data-hero-in] { transition: opacity 0.4s linear; transform: none; }
}

/* "View Brands" anchor-scrolls here — clear the fixed utility bar + nav */
#shop-by-brand {
    scroll-margin-top: calc(var(--utility-bar-h) + var(--nav-h) + var(--sp-4));
}

/* ================================================================
   TRUST STRIP — one slim row, everything said once and briefly.
   ================================================================ */

.trust-strip-slim {
    background: var(--color-bg);
    padding-block: var(--sp-4);
    border-bottom: 1px solid var(--color-border);
}

.trust-strip-slim__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--sp-3) var(--sp-8);
}

.trust-strip-slim__row a {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--text-xs);
    font-weight: var(--fw-semi);
    color: var(--color-blue);
    white-space: nowrap;
}

.trust-strip-slim__row svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    color: var(--color-blue);
}

/* ── Horizontal ticker — a small fixed-width window; the row of 4
   lines is wider than it, so it scrolls sideways to reveal them. Which
   part is showing is driven by scroll position (home.js sets
   --trust-ticker-x directly, no CSS transition on it — this should
   track the scroll 1:1, not lag/ease behind it), not a timer, so it
   genuinely "scrolls as you scroll" rather than autoplaying
   independently of what the visitor is doing. */
.trust-ticker {
    position: relative;
    /* Wide enough to fit all 4 lines at once (~654px measured) plus
       fade-edge margin — the point is a continuous scroll-tied drift
       with all 4 always visible, not a narrow window revealing one
       or two at a time. */
    width: min(100%, 46rem);
    overflow: hidden;
    mask-image: linear-gradient(to right, transparent 0, black 24px, black calc(100% - 24px), transparent 100%);
    -webkit-mask-image: linear-gradient(to right, transparent 0, black 24px, black calc(100% - 24px), transparent 100%);
}

.trust-ticker__track {
    display: flex;
    align-items: center;
    gap: var(--sp-8);
    width: max-content;
    padding-inline: var(--sp-2);
    transform: translateX(calc(-1 * var(--trust-ticker-x, 0px)));
}

.trust-ticker__item {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--text-xs);
    font-weight: var(--fw-semi);
    color: var(--color-text-muted);
    white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    .trust-ticker { mask-image: none; -webkit-mask-image: none; overflow-x: auto; }
    .trust-ticker__track { transform: none !important; }
}

@media (max-width: 640px) {
    .trust-strip-slim__row {
        justify-content: space-between;
    }
}

/* ================================================================
   GENDER SPLIT — two big tiles (mobile: stacked, desktop: side by
   side), not small pills. Real product photography, dimmed with a
   flat scrim (no gradient) for text legibility.
   ================================================================ */

/* Side by side even on phones — stacked was two 220px-tall photos back
   to back, a lot of scroll-past height for two tiles that are really
   just a fork in the road ("men's" vs "ladies'"), not content in
   themselves. */
.gender-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-2);
    padding: var(--sp-4) var(--container-pad);
}

@media (min-width: 700px) {
    .gender-split {
        gap: var(--sp-3);
        padding: var(--sp-6) var(--container-pad);
        padding-inline: var(--container-pad);
        max-width: var(--container-max);
        margin-inline: auto;
    }
}

.gender-tile {
    position: relative;
    display: flex;
    align-items: flex-end;
    height: 160px;
    border-radius: var(--r-lg);
    overflow: hidden;
}

@media (min-width: 700px) {
    .gender-tile { height: 340px; border-radius: var(--r-xl); }
}

.gender-tile__img {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    background-color: var(--color-navy);
    transition: transform var(--t-slow);
}

.gender-tile:hover .gender-tile__img { transform: scale(1.05); }

.gender-tile__scrim {
    position: absolute;
    inset: 0;
    background: rgba(7, 25, 41, 0.22);
}

.gender-tile__content {
    position: relative;
    z-index: 1;
    padding: var(--sp-3);
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
}

@media (min-width: 700px) {
    .gender-tile__content { padding: var(--sp-5); gap: var(--sp-2); }
}

.gender-tile__title {
    font-size: var(--text-sm);
    font-weight: var(--fw-black);
    letter-spacing: var(--ls-display);
    color: var(--color-white);
}

@media (min-width: 700px) {
    .gender-tile__title { font-size: var(--text-xl); }
}

.gender-tile__cta {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    width: fit-content;
    font-size: 0.625rem;
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--color-white);
    padding: var(--sp-1) var(--sp-3);
    border: 1.5px solid rgba(255, 255, 255, 0.5);
    border-radius: var(--r-full);
    transition: border-color var(--t-fast), background var(--t-fast);
}

@media (min-width: 700px) {
    .gender-tile__cta {
        gap: var(--sp-2);
        font-size: var(--text-xs);
        padding: var(--sp-2) var(--sp-4);
    }
}

.gender-tile:hover .gender-tile__cta {
    border-color: var(--color-white);
    background: rgba(255, 255, 255, 0.1);
}

@media (prefers-reduced-motion: reduce) {
    .gender-tile:hover .gender-tile__img { transform: none; }
}

/* ================================================================
   RAILS — the core of the new home feed. Horizontal-scroll strips,
   edge-to-edge (not boxed in .container) so scrolling feels
   continuous, like a real app feed rather than a boxed website grid.
   ================================================================ */

.rail-section {
    padding-block: var(--sp-6);
}

.rail-section + .rail-section {
    border-top: 1px solid var(--color-border);
}

.rail-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-4);
    margin-bottom: var(--sp-4);
}

.rail-title {
    font-size: var(--text-lg);
    font-weight: var(--fw-black);
    letter-spacing: var(--ls-display);
    color: var(--color-text);
}

.rail-header__hint {
    font-size: var(--text-xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--color-blue);
}

.rail {
    display: flex;
    gap: var(--sp-4);
    overflow-x: auto;
    /* Setting only overflow-x leaves overflow-y at its CSS-spec-mandated
       computed value of "auto" (never "visible") whenever the explicit
       axis scrolls — so every rail was quietly auto-vertical-scrollable
       too, and a card's hover lift (translateY, a few px) could get
       clipped at the top edge by that same auto overflow box. Pinning
       overflow-y to hidden removes both symptoms at once. */
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    padding-inline: var(--container-pad);
    padding-block: var(--sp-2);
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.rail::-webkit-scrollbar { display: none; }
.rail > * { scroll-snap-align: start; flex-shrink: 0; }

/* Shop by Brand specifically: the slow auto-drift (home.js) fights
   scroll-snap's own "settle on the nearest card" correction — every
   snap adjustment was a tiny stutter on top of the drift, which is
   most of what read as "not smooth". Off entirely for this one rail.
   Left/right edges fade instead of cutting cards off flat, and on
   wide desktops this rail gets the SAME max-width + centering the
   gender-split tiles above it already have (.rail is edge-to-edge
   by design for every other rail — this is the one exception, since
   it needs to visually line up with .gender-split immediately above
   it rather than bleed to the true viewport edge). */
.rail--brands {
    scroll-snap-type: 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%);
}

/* ── Brand cards ──────────────────────────────────────────────────
   Full designed poster art (product photo + styled background + the
   brand's own wordmark baked into the image), not a small circular
   avatar + separate text label — the brand name is already in the
   artwork, so no label element is needed below it. */

.brand-card {
    display: block;
    flex-shrink: 0;
    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) {
    .brand-card { width: 176px; }
}

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

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

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

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

/* ── Moment avatars (shop-by-time-of-day) ────────────────────────
   Same "story circle" idea as the brand rail, but the ring color
   itself runs light → dark across the four moments (solid colors
   only, no gradients) so the row reads as morning turning to night. */

.moment-avatar {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-2);
    width: 92px;
}

.moment-avatar__ring {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 80px;
    height: 80px;
    border-radius: 50%;
    padding: 3px;
    transition: transform var(--t-spring);
}

.moment-avatar__ring img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: contain;
    background: var(--color-white);
    padding: 10px;
}

.moment-avatar__ring--light   { background: var(--color-gray-300); }
.moment-avatar__ring--mid     { background: var(--color-blue); }
.moment-avatar__ring--dark    { background: var(--color-navy-light); }
.moment-avatar__ring--darkest { background: var(--color-navy-dark); }

.moment-avatar:hover .moment-avatar__ring { transform: scale(1.05); }
.moment-avatar:active .moment-avatar__ring { transform: scale(0.96); transition: transform var(--t-press); }

.moment-avatar__time {
    font-size: var(--text-sm);
    font-weight: var(--fw-black);
    font-variant-numeric: tabular-nums;
    color: var(--color-text);
}

.moment-avatar__label {
    font-size: 0.6875rem;
    font-weight: var(--fw-semi);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
}

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

/* ================================================================
   CAROUSEL — New Arrivals. Boxed to match the container width above/
   below it instead of bleeding to the true viewport edge like the
   free .rail rows do. The card set renders TWICE in front-page.php
   (real + an aria-hidden duplicate) so home.js §9 can wrap scrollLeft
   back to the start once it passes the end of the real set — an
   invisible loop since the duplicate is identical underneath (same
   "duplicate + modulo" technique as the brand rail's own auto-drift).

   Two different interaction models by breakpoint, deliberately: on
   phone it's a plain native swipe-scroll strip (no arrows — see
   .carousel__arrow below, hidden until 768px); at 768px+ the viewport
   itself stops being scrollable (overflow-x switches to hidden) and
   the arrows become the ONLY way to move, exactly one card per click
   (home.js §9) — not a free drag/wheel-scroll surface on desktop. */

.carousel {
    position: relative;
    /* Capped + centered to match the boxed width every section above it
       uses (.container, .gender-split, .rail--brands) — unlike the free-
       scroll .rail rows, this one shouldn't bleed to the true viewport
       edge on wide desktops or it reads as oddly oversized next to them. */
    max-width: var(--container-max);
    margin-inline: auto;
}

.carousel__viewport {
    overflow-x: auto;
    overflow-y: hidden;
    padding-inline: var(--container-pad);
    padding-block: var(--sp-2);
    scrollbar-width: none;
    -ms-overflow-style: none;
    scroll-snap-type: x proximity;
}

.carousel__viewport::-webkit-scrollbar { display: none; }

@media (min-width: 768px) {
    .carousel__viewport { overflow-x: hidden; }
}

.carousel__track {
    display: flex;
    gap: var(--sp-4);
}

.carousel__card {
    scroll-snap-align: start;
    flex: 0 0 auto;
    width: 168px;
}

@media (min-width: 640px) {
    .carousel__card { width: 200px; }
}

@media (min-width: 1024px) {
    .carousel__card { width: 224px; }
}

@media (prefers-reduced-motion: reduce) {
    .carousel__viewport { scroll-snap-type: none; }
}

.carousel__arrow {
    display: none;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: var(--r-full);
    border: 1px solid var(--color-border);
    background: var(--color-white);
    color: var(--color-navy);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    transition: transform var(--t-spring), box-shadow var(--t-base), background var(--t-fast);
}

.carousel__arrow svg {
    width: 20px;
    height: 20px;
}

.carousel__arrow--prev { left: var(--sp-2); }
.carousel__arrow--next { right: var(--sp-2); }

@media (min-width: 768px) {
    .carousel__arrow { display: flex; }
    .carousel__arrow--prev { left: var(--sp-4); }
    .carousel__arrow--next { right: var(--sp-4); }
}

.carousel__arrow:hover {
    background: var(--color-navy);
    color: var(--color-white);
    box-shadow: var(--shadow-card-hover);
    transform: translateY(-50%) scale(1.06);
}

.carousel__arrow:active {
    transform: translateY(-50%) scale(0.96);
    transition: transform var(--t-press);
}

.carousel__arrow:disabled {
    opacity: 0.35;
    cursor: default;
    box-shadow: none;
}

.carousel__arrow:disabled:hover {
    background: var(--color-white);
    color: var(--color-navy);
    transform: translateY(-50%);
}

/* ================================================================
   VISIT US — dark "hero" style: map + real store photo side by side,
   with a floating glass bar (contact info | location + directions)
   overlapping the seam between them. Optional background photo via
   Customizer → Visit Us Background; flat --color-navy-dark otherwise
   (no gradient scrim once a photo IS set either — flat tint only,
   same rule as every overlay elsewhere on this site).
   ================================================================ */

.visit-hero {
    position: relative;
    background: var(--color-navy-dark);
    padding-block: var(--sp-16) var(--sp-20);
    overflow: hidden;
}

.visit-hero__bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    /* Scaled up so the (deliberately large) parallax drift in home.js
       has room to move the image vertically without ever exposing an
       edge — same overscan trick the main hero slideshow uses, just a
       much bigger scale since this parallax travels much further.
       This value is duplicated in home.js (it re-states the scale
       every frame alongside the dynamic offset) — keep both in sync. */
    transform: scale(1.4);
    will-change: transform;
}

/* Source photo (assets/images/visit-us-bg.jpg) is already pre-darkened
   on export, not the raw bright product shot — this flat navy scrim on
   top is a second, guaranteed layer of dimming so body text always
   stays legible regardless of how bright any future replacement photo
   is. Flat color, not a gradient — same rule as every overlay
   elsewhere on this site. */
.visit-hero__scrim {
    position: absolute;
    inset: 0;
    background: rgba(7, 25, 41, 0.72);
}

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

.visit-hero__title {
    text-align: center;
    font-size: var(--text-2xl);
    font-weight: var(--fw-semi);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--color-white);
    margin-bottom: var(--sp-10);
}

.visit-hero__media {
    position: relative;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--sp-4);
    margin-bottom: var(--sp-12);
}

@media (min-width: 768px) {
    .visit-hero__media {
        grid-template-columns: 1fr 1fr;
        margin-bottom: var(--sp-16);
    }
}

.visit-hero__map,
.visit-hero__photo {
    position: relative;
    aspect-ratio: 4 / 3;
    border-radius: var(--r-lg);
    overflow: hidden;
    box-shadow: var(--shadow-md);
}

/* Mobile: a short wide map strip above a taller store photo — matches
   the stacked layout brief, rather than reusing the desktop's equal
   4:3 boxes for both. */
@media (max-width: 767px) {
    .visit-hero__map { aspect-ratio: 2 / 1; }
    .visit-hero__photo { aspect-ratio: 4 / 3; }
}

.visit-hero__map iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
    /* Dark-mode tint so the default light Google Maps style sits at
       home in this section instead of a jarring bright rectangle. */
    filter: invert(92%) hue-rotate(180deg) brightness(0.95) contrast(0.9) saturate(0.7);
}

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

/* ── Floating contact bar ─────────────────────────────────────────
   Four flat segments in a row on desktop — email | phone | location |
   a solid Get Directions block — separated by hairline dividers, the
   directions block set apart by its own solid fill instead of a 4th
   divider (it's already unmistakably distinct). Stacks to one centered
   column on mobile, same segments/dividers, just vertical. */

.visit-hero__bar {
    display: flex;
    flex-direction: column;
    background: rgba(11, 37, 64, 0.72);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: var(--r-lg);
    overflow: hidden; /* keeps the solid CTA block inside the rounded corners */
    box-shadow: var(--shadow-card-hover);
}

@media (min-width: 768px) {
    .visit-hero__bar {
        position: absolute;
        left: 50%;
        bottom: 0;
        transform: translate(-50%, 40%);
        width: min(960px, 92%);
        flex-direction: row;
        align-items: stretch;
    }
}

.visit-hero__bar-divider {
    width: 100%;
    height: 1px;
    background: rgba(255, 255, 255, 0.14);
}

@media (min-width: 768px) {
    .visit-hero__bar-divider {
        width: 1px;
        height: auto;
    }
}

.visit-hero__bar-item {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-3);
    padding: var(--sp-5) var(--sp-6);
    font-size: var(--text-sm);
    font-weight: var(--fw-semi);
    color: var(--color-white);
    text-align: center;
    transition: color var(--t-fast);
}

a.visit-hero__bar-item:hover { color: var(--color-blue-light); }

.visit-hero__bar-item svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    color: var(--color-blue-light);
}

.visit-hero__bar-item--location {
    font-weight: var(--fw-normal);
    color: rgba(255, 255, 255, 0.85);
    line-height: var(--lh-relaxed);
}

/* Shortened to "Muscat, Sultanate of Oman" (the business name is already
   the whole bar's context, no need to repeat it) specifically so this
   fits one line at any width down to the smallest phone — nowrap here
   is a guarantee, not just a preference. */
.visit-hero__bar-item--location span {
    white-space: nowrap;
}

@media (min-width: 768px) {
    .visit-hero__bar-item { flex: 1; }
    .visit-hero__bar-item--location { flex: 1.3; }
}

/* CTA — a real pill button sitting inside its own bar segment (same
   padding/centering as the other three), not a full-bleed rectangle. */
.visit-hero__bar-cta-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--sp-5) var(--sp-6);
}

@media (min-width: 768px) {
    .visit-hero__bar-cta-wrap { flex: 1; }
}

.visit-hero__bar-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-6);
    background: var(--color-white);
    color: var(--color-navy-dark);
    border-radius: var(--r-full);
    font-size: var(--text-sm);
    font-weight: var(--fw-bold);
    white-space: nowrap;
    box-shadow: var(--shadow-sm);
    transition: background var(--t-fast), color var(--t-fast), transform var(--t-spring), box-shadow var(--t-base);
}

.visit-hero__bar-cta svg { width: 16px; height: 16px; }

.visit-hero__bar-cta:hover {
    background: var(--color-blue-light);
    color: var(--color-white);
    box-shadow: var(--shadow-card-hover);
    transform: translateY(-2px);
}

.visit-hero__bar-cta:active {
    transform: translateY(0) scale(0.96);
    transition: transform var(--t-press);
}

@media (prefers-reduced-motion: reduce) {
    .visit-hero__bar-cta:hover { transform: none; }
}

/* ================================================================
   REVIEWS — separate light section beneath the dark Visit Us block.
   ================================================================ */

.reviews-section {
    padding-block: var(--sp-16);
}

.reviews-section__header {
    text-align: center;
    max-width: 560px;
    margin-inline: auto;
    margin-bottom: var(--sp-10);
}

/* ── Marquee — 1-3 auto-scrolling vertical columns ───────────────
   Base/fallback state IS the flat grid below (also what reduced-motion
   and no-JS visitors get); home.js §11 reshuffles the same card
   elements into .reviews-marquee__col columns (each duplicated once
   for the loop) and adds .is-animated, which is what the rules below
   actually target. Column count matches the old grid's breakpoints so
   the two states line up size-wise instead of jumping. */

.visit-section__reviews-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--sp-4);
}

@media (min-width: 700px) {
    .visit-section__reviews-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1100px) {
    .visit-section__reviews-grid { grid-template-columns: repeat(3, 1fr); }
}

.reviews-marquee {
    position: relative;
}

/* Fixed height + edge fade only apply once columns are actually
   looping — the un-animated states (reduced-motion, no-JS, or a
   genuine single narrow column) render every review inline instead,
   so clipping/fading them here would just cut real content off. */
.reviews-marquee.is-animated {
    height: 460px;
    /* Top/bottom fade — an opacity mask, not a visible color gradient,
       same technique .rail--brands already uses on its left/right
       edges (see home.css) — consistent with the sitewide no-visible-
       gradients rule. */
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, black 64px, black calc(100% - 64px), transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0, black 64px, black calc(100% - 64px), transparent 100%);
}

/* Shorter still on phones — a single column doesn't need as much
   vertical real estate to feel alive, and the fade zone shrinks to
   match so it doesn't eat a disproportionate share of a shorter box. */
@media (max-width: 699px) {
    .reviews-marquee.is-animated {
        height: 320px;
        -webkit-mask-image: linear-gradient(to bottom, transparent 0, black 32px, black calc(100% - 32px), transparent 100%);
        mask-image: linear-gradient(to bottom, transparent 0, black 32px, black calc(100% - 32px), transparent 100%);
    }
}

.reviews-marquee__viewport {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--sp-4);
    height: 100%;
}

.reviews-marquee.is-animated .reviews-marquee__viewport {
    display: flex;
    flex-direction: row;
    overflow: hidden;
}

@media (min-width: 700px) {
    .reviews-marquee__viewport { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1100px) {
    .reviews-marquee__viewport { grid-template-columns: repeat(3, 1fr); }
}

.reviews-marquee__col {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    height: 100%;
}

.reviews-marquee__col-track {
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
    will-change: transform;
}

.reviews-marquee.is-animated .reviews-marquee__col-track {
    animation-name: reviews-marquee-scroll;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

@keyframes reviews-marquee-scroll {
    from { transform: translateY(0); }
    to   { transform: translateY(-50%); }
}

/* Deliberately keeps scrolling under a hovered card rather than
   pausing the whole column — the card itself lifts instead, so
   there's still a hover response without the "everything freezes"
   feel. flex-shrink:0 (kept below) means the lift never squeezes
   neighboring cards in the track. */
.review-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--r-lg);
    padding: var(--sp-5);
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    flex-shrink: 0;
    box-shadow: var(--shadow-sm);
    transition: transform var(--t-spring), box-shadow var(--t-base), border-color var(--t-fast);
}

.review-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-card-hover);
    border-color: var(--color-blue-light);
}

@media (prefers-reduced-motion: reduce) {
    .review-card:hover { transform: none; }
}

.review-card__stars {
    color: var(--color-blue);
    font-size: var(--text-md);
    letter-spacing: 2px;
}

.review-card__text {
    font-size: var(--text-sm);
    color: var(--color-text);
    line-height: var(--lh-relaxed);
    flex-grow: 1;
}

.review-card__author {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--text-xs);
    font-weight: var(--fw-semi);
    color: var(--color-text-muted);
}

.review-card__author img {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
}

/* Real Google reviews always include a profile photo; placeholder ones
   don't have one to show, so a flat initial-letter circle stands in —
   same size/position as the real photo would take. */
.review-card__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--color-navy);
    color: var(--color-white);
    font-size: var(--text-xs);
    font-weight: var(--fw-bold);
    flex-shrink: 0;
}

.visit-section__reviews-note {
    font-size: var(--text-xs);
    font-weight: var(--fw-semi);
    color: var(--color-blue);
    background: var(--color-blue-light, rgba(38, 85, 194, 0.08));
    border: 1px dashed var(--color-blue);
    border-radius: var(--r-md, var(--r-lg));
    padding: var(--sp-2) var(--sp-3);
    margin-bottom: var(--sp-4);
}

/* ================================================================
   SOCIAL — "Follow Along" band. Header is boxed like every other
   section; the photo wall below it bleeds full-bleed to the true
   viewport edge (not boxed) so it reads as an open-ended wall of
   photos rather than a contained gallery.
   ================================================================ */

.social-section {
    padding-block: var(--sp-16);
    border-top: 1px solid var(--color-border);
}

.social-section__cta {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    margin-top: var(--sp-2);
}

.social-section__cta svg {
    width: 18px;
    height: 18px;
}

/* ── Bento photo wall ─────────────────────────────────────────────
   Real photography, no card chrome — deliberately NOT a recreation
   of Instagram's own app UI (avatar/handle row, like-comment-share
   icons, caption line); that borrowed UI used to read as a foreign
   widget dropped into an otherwise original design system. Just the
   photos, full-bleed, varying column widths/heights for visual
   rhythm (a wide "hero" shot, then a narrower column of two stacked
   shots, repeating — see $toman_render_ig_columns in front-page.php).
   Drifts sideways on its own forever (home.js §12, same slow-nudge +
   duplicate-the-set loop as the Shop by Brand rail, §7) while
   staying a plain native horizontal scroller underneath. */

.ig-mosaic {
    margin-top: var(--sp-10);
    height: 420px;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.ig-mosaic::-webkit-scrollbar { display: none; }

.ig-mosaic__track {
    display: flex;
    align-items: stretch;
    gap: var(--sp-3);
    height: 100%;
    width: max-content;
    padding-inline: var(--container-pad);
}

.ig-mosaic__col {
    flex: 0 0 auto;
    height: 100%;
    display: block;
    border-radius: var(--r-lg);
    overflow: hidden;
    background: var(--color-gray-100);
}

.ig-mosaic__col--hero {
    width: 300px;
}

.ig-mosaic__col--hero img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--t-slow);
}

.ig-mosaic__col--hero:hover img {
    transform: scale(1.04);
}

.ig-mosaic__col--split {
    width: 190px;
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    background: none;
}

.ig-mosaic__tile {
    flex: 1 1 0;
    min-height: 0;
    display: block;
    border-radius: var(--r-lg);
    overflow: hidden;
    background: var(--color-gray-100);
}

.ig-mosaic__tile img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--t-slow);
}

.ig-mosaic__tile:hover img {
    transform: scale(1.04);
}

@media (max-width: 640px) {
    .ig-mosaic { height: 300px; }
    .ig-mosaic__col--hero { width: 210px; }
    .ig-mosaic__col--split { width: 135px; }
}

@media (prefers-reduced-motion: reduce) {
    .ig-mosaic__col--hero img,
    .ig-mosaic__tile img { transition: none; }
}

/* ================================================================
   PRESS — full-bleed "In the News" slideshow. One slide per
   publication, crossfaded (home.js §12), switched via the thumbnail
   rail bottom-right — same interaction as a hero image switcher, just
   scoped to this one section instead of the whole page.
   ================================================================ */

.press-section {
    padding-block: var(--sp-16) 0;
    border-top: 1px solid var(--color-border);
}

.press-section__header {
    text-align: center;
    max-width: 480px;
    margin-inline: auto;
    margin-bottom: var(--sp-8);
}

.press-hero {
    position: relative;
    height: 600px;
    overflow: hidden;
    background: var(--color-navy-dark);
}

/* Shorter and wider on phones on purpose — background-size:cover on
   a narrow-but-tall box (the old 520px) is height-driven, which only
   has room to show a ~925px-wide slice of this 1920px photo. Fine
   for the Alwatan slide (gift bags, nothing off-center), but the
   Times of Oman slide has both co-owners standing far apart near the
   two edges of the frame, so that slice cropped straight through
   both of their faces. Shortening the box turns the crop
   width-driven instead, trading vertical space for a wider slice —
   at 400px it's wide enough to keep both of them in frame (checked
   against their actual positions in the source photo) with room
   still left for the quote/citation/link beneath. */
@media (max-width: 699px) {
    .press-hero { height: 400px; }
}

.press-hero__slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    pointer-events: none;
    transition: opacity 700ms var(--ease-out);
    z-index: 1;
}

.press-hero__slide.is-active {
    opacity: 1;
    pointer-events: auto;
    z-index: 2;
}

@media (prefers-reduced-motion: reduce) {
    .press-hero__slide { transition: none; }
}

.press-hero__bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    transform: scale(1);
}

/* Slow Ken Burns drift on whichever slide is active — only runs once
   per activation (animation-fill-mode: forwards holds the end state,
   so it doesn't reset/replay every frame), restarts naturally each
   time a slide regains .is-active the same way the content stagger
   below does. */
.press-hero__slide.is-active .press-hero__bg {
    animation: press-ken-burns 9s var(--ease-out) forwards;
}

@keyframes press-ken-burns {
    from { transform: scale(1); }
    to   { transform: scale(1.08); }
}

/* Flat tint, not a gradient — same rule as every other overlay on this
   site. The source photos are already dimmed/spotlighted exports, so
   this only needs to add a little more, not do all the work itself. */
.press-hero__scrim {
    position: absolute;
    inset: 0;
    background: rgba(7, 25, 41, 0.5);
}

.press-hero__content {
    position: relative;
    z-index: 1;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    max-width: 640px;
    padding: var(--sp-10) var(--container-pad);
}

/* Staggered fade-up, one child at a time — replays every time a slide
   regains .is-active (class removal + re-addition restarts a CSS
   animation), which is exactly what home.js's thumbnail click does. */
.press-hero__content > * { opacity: 0; }

.press-hero__slide.is-active .press-hero__content > * {
    animation: press-content-in 650ms var(--ease-out) both;
}

.press-hero__slide.is-active .press-hero__content > *:nth-child(1) { animation-delay: 50ms; }
.press-hero__slide.is-active .press-hero__content > *:nth-child(2) { animation-delay: 130ms; }
.press-hero__slide.is-active .press-hero__content > *:nth-child(3) { animation-delay: 210ms; }
.press-hero__slide.is-active .press-hero__content > *:nth-child(4) { animation-delay: 290ms; }
.press-hero__slide.is-active .press-hero__content > *:nth-child(5) { animation-delay: 370ms; }

@keyframes press-content-in {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .press-hero__slide.is-active .press-hero__bg { animation: none; }
    .press-hero__content > * { opacity: 1 !important; animation: none !important; transform: none !important; }
}

.press-hero__content .section-label--on-dark {
    margin-bottom: var(--sp-4);
}

.press-hero__quote {
    font-size: clamp(1.375rem, 3vw, 2.25rem);
    font-weight: var(--fw-black);
    letter-spacing: var(--ls-display);
    line-height: 1.25;
    color: var(--color-white);
    margin-bottom: var(--sp-3);
}

/* The literal quote marks — bigger and dimmer than the quote itself so
   they read as a decorative accent, not part of the sentence. First
   and last in DOM order either way, so they land correctly at the
   visual start/end of an RTL quote without any extra mirroring. */
.press-hero__quote-mark {
    font-size: 1.3em;
    line-height: 0;
    vertical-align: -0.18em;
    color: rgba(255, 255, 255, 0.45);
}

.press-hero__quote-mark--start { margin-inline-end: 0.05em; }
.press-hero__quote-mark--end { margin-inline-start: 0.05em; }

.press-hero__quote[dir="rtl"] {
    text-align: right;
}

.press-hero__translation {
    font-size: var(--text-sm);
    font-style: italic;
    color: rgba(255, 255, 255, 0.6);
    margin-bottom: var(--sp-4);
}

.press-hero__citation {
    font-size: var(--text-sm);
    font-weight: var(--fw-semi);
    color: rgba(255, 255, 255, 0.85);
    margin-bottom: var(--sp-6);
}

.press-hero__citation-dot {
    color: rgba(255, 255, 255, 0.4);
    margin-inline: 2px;
}

.press-hero__link {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    width: fit-content;
    padding-bottom: 2px;
    color: var(--color-white);
    font-weight: var(--fw-bold);
    font-size: var(--text-sm);
    border-bottom: 1.5px solid rgba(255, 255, 255, 0.4);
    transition: border-color var(--t-fast), gap var(--t-spring);
}

.press-hero__link:hover {
    border-color: var(--color-white);
    gap: var(--sp-3);
}

.press-hero__link svg { width: 16px; height: 16px; }

.press-hero__thumbs {
    position: absolute;
    z-index: 3;
    bottom: var(--sp-5);
    right: var(--sp-5);
    display: flex;
    gap: var(--sp-2);
}

/* Real newspaper logos now — a white card the logo sits on (object-fit:
   contain, own padding) rather than a cover-fit photo tile, since a
   masthead logo needs to show in full, not get cropped like a photo. */
.press-hero__thumb {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 56px;
    min-width: 84px;
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--r-md);
    border: 2px solid transparent;
    background: var(--color-white);
    opacity: 0.65;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    transition: opacity var(--t-fast), border-color var(--t-fast), transform var(--t-spring), box-shadow var(--t-base);
}

/* Countdown to the next auto-advance — fills left to right over the
   same 6.5s as home.js's timer, driven entirely by JS (not a CSS
   .is-active trigger) so it can freeze mid-fill on hover and restart
   from empty rather than resuming, matching the JS interval's own
   pause/restart (a clean resume would show the bar finishing early). */
.press-hero__thumb-timer {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: var(--color-blue-light);
    transform: scaleX(0);
    transform-origin: left;
    z-index: 1;
}

@keyframes press-thumb-timer {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
    .press-hero__thumb-timer { display: none; }
}

.press-hero__thumb img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.press-hero__thumb:hover {
    opacity: 0.9;
    transform: translateY(-2px);
    box-shadow: var(--shadow-card-hover);
}

.press-hero__thumb.is-active {
    opacity: 1;
    border-color: var(--color-blue-light);
}

.press-hero__thumb:active {
    transform: translateY(0) scale(0.95);
    transition: transform var(--t-press);
}

@media (min-width: 700px) {
    .press-hero__thumb { height: 64px; min-width: 100px; }
}

@media (prefers-reduced-motion: reduce) {
    .press-hero__thumb:hover { transform: none; }
}

