/* ==========================================================================
   Responsive overrides (mobile-first system uses progressive max-width queries)
   ========================================================================== */

/* ----- Large desktop (1200–1440) ----- */
@media (max-width: 1240px) {
    .footer-grid { gap: var(--sp-5); }
}

/* ----- Tablet landscape ----- */
@media (max-width: 1024px) {
    :root {
        --header-h: 108px;
        --fs-4xl: 3rem;
        --fs-3xl: 2.25rem;
    }

    .section            { padding: var(--sp-8) 0; }
    .two-col            { gap: var(--sp-7); }
    .grid-4             { grid-template-columns: repeat(2, 1fr); }

    /* (The main-menu serif step-down that used to live here is gone: the
       hamburger now takes over at 1240px, so the inline bar never renders at
       this width and the drawer sets its own type size.) */

    /* Hero slider — pull arrows in a touch on tablet */
    .hero-arrow         { width: 50px; height: 50px; }
    .hero-arrow-prev    { left: var(--sp-4); }
    .hero-arrow-next    { right: var(--sp-4); }
    .stats              { grid-template-columns: repeat(4, 1fr); }
    .gallery-grid       { grid-template-columns: repeat(3, 1fr); }
    .footer-grid        { grid-template-columns: 1fr 1fr; }
    .footer-brand       { grid-column: 1 / -1; }

    .cta-band-inner     { gap: var(--sp-5); }
}

/* ----- Hamburger threshold -----
   Raised 880px → 1240px (the --container width). Ten top-level items at the
   current labels need ~918px of bar; the 1240px container only spares ~959px
   once the wordmark and its gap are removed, and below that the bar has less
   room than it needs. Since every label is a single unbreakable word
   (FilmoGraphy, Television, Bibliography), a squeezed bar cannot reflow — it
   clips the last item instead. So the inline bar is shown only where it
   genuinely fits, and the drawer (which works at any width) takes over below.
   NOTE: main.js gates the tap-to-expand handlers on the same 1240px value —
   change both together or submenus stop opening in the drawer. */
@media (max-width: 1240px) {
    /* position/z-index: the hamburger becomes the drawer's close button, so it
       has to paint above the panel. Untouched it is a non-positioned sibling of
       .primary-nav inside .site-header's stacking context, which means the open
       drawer covered it — the X was invisible and its taps landed on the drawer,
       leaving the scrim and Escape as the only ways back out. */
    .nav-toggle         { display: flex; position: relative; z-index: 101; }

    /* Opening the drawer tucks the utility bar away exactly as scrolling does
       (same properties, same transition) — the drawer hides it anyway on a
       phone, and collapsing it keeps the X on the compact header row, level
       with the brand at the top of the panel instead of ~40px below it. */
    body.nav-open .topbar {
        max-height: 0;
        opacity: 0;
        margin-bottom: 0;
        padding-bottom: 0;
        border-bottom-color: transparent;
        pointer-events: none;
    }

    .primary-nav {
        position: fixed;
        top: 0;
        right: -100%;
        width: min(360px, 88vw);
        /* dvh, not vh. On a phone 100vh is the height with browser chrome
           RETRACTED, so the drawer box ran ~90px past the visible fold: the last
           menu row (Contact) sat inside the panel but off the bottom of the
           screen, and because the panel is position:fixed there was nothing to
           scroll to reach it. dvh tracks the chrome as it collapses. vh is kept
           first as the fallback for browsers without dvh. */
        height: 100vh;
        height: 100dvh;
        background: var(--bg-elev);
        border-left: 1px solid var(--border);
        /* Top padding was calc(--header-h + sp-5) — written as though the drawer
           slid in UNDER the header. It does not: .primary-nav is a child of
           .site-header carrying z-index 99, so the open panel paints over the
           header's own brand and top bar. The reserved band was therefore not
           clearing anything, it was ~128px of empty panel above the drawer's
           logo — and since --header-h is a fixed 108px while the real bar is
           70px once the top bar tucks away, 58px of that was dead even by its
           own reckoning. The drawer now opens with its own header row: sp-3
           matches .site-header's top padding, so the brand lines up with the X. */
        padding: var(--sp-3) var(--sp-5) var(--sp-5);
        overflow-y: auto;
        overscroll-behavior: contain;
        /* visibility is animated alongside the slide so that while the drawer is
           parked off-screen its eleven links leave the tab order and the
           accessibility tree. Without it, every page below 1240px opened with
           eleven invisible tab stops between the logo and the page content.
           Not display:none — that would kill the transition. */
        visibility: hidden;
        transition: right var(--t-med) var(--ease), visibility var(--t-med) var(--ease);
        z-index: 99;
        box-shadow: var(--shadow-lg);
    }
    .primary-nav.open   { right: 0; visibility: visible; }

    /* Brand block at the top of the slide-in drawer: logo name + caption,
       aligned with the menu items and separated by a hairline rule. */
    .nav-drawer-brand {
        display: inline-flex;
        align-items: center;
        margin-bottom: var(--sp-4);
        padding-bottom: var(--sp-4);
        border-bottom: 1px solid var(--border);
        text-decoration: none;
    }
    .nav-drawer-brand .wordmark      { gap: 7px; animation: var(--wm-float); }
    .nav-drawer-brand .wordmark-name { font-size: 1.5rem; }
    .nav-drawer-brand .wordmark-tag  { display: inline-flex; font-size: 0.58rem; letter-spacing: 0.28em; }

    /* Qualified to .primary-nav .nav-list so it can actually beat the (0,2,0)
       desktop rule in main.css rather than relying on .nav-item{width:100%}
       below to compensate. */
    .primary-nav .nav-list { flex-direction: column; align-items: stretch; gap: 0; }
    .nav-item           { width: 100%; border-bottom: 1px solid var(--border); }
    .nav-link           {
        /* display:flex + width:100% are what make this row full-width. It
           inherits inline-flex from main.css, which shrink-wraps to the text —
           so the row LOOKED full width (the <li> is) but only the words were
           tappable, and the space-between below had nothing to distribute, so
           the chevron sat against the label instead of at the right edge. */
        display: flex;
        width: 100%;
        padding: var(--sp-4) 0;
        font-size: var(--fs-base);
        justify-content: space-between;
    }

    /* Mobile drawer: dropdown becomes an in-line, collapsible block */
    .dropdown {
        position: static;
        opacity: 1;
        visibility: visible;
        transform: none;
        background: transparent;
        background-image: none;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        padding: 0;
        min-width: 0;
        overflow: visible;
        display: none;
    }
    .nav-item.has-dropdown.expanded .dropdown { display: block; }

    .dropdown-header {
        padding: var(--sp-3) 0 var(--sp-3) var(--sp-4);
        border-bottom: 1px solid var(--border);
        gap: 4px;
    }
    .dropdown-header::after { display: none; }
    .dropdown-eyebrow   { font-size: 0.58rem; letter-spacing: 0.28em; }
    .dropdown-subtitle  { font-size: 0.9rem; }

    .dropdown-list { padding: var(--sp-2) 0; }

    .dropdown-link {
        grid-template-columns: 1fr auto;
        padding: var(--sp-3) var(--sp-4);
        border-radius: 0;
        column-gap: var(--sp-3);
    }
    .dropdown-link-label { font-size: 0.95rem; }
    /* Arrow visible by default in mobile (no hover state on touch) */
    .dropdown-arrow      { opacity: 0.5; transform: none; font-size: 0.9rem; }
    .dropdown-link:hover { background: rgba(201, 169, 97, 0.05); padding-left: var(--sp-5); }

    /* Nested submenu (Direction): inline, collapsible, indented one level */
    .dropdown-sublist {
        position: static;
        opacity: 1;
        visibility: visible;
        transform: none;
        background: transparent;
        background-image: none;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        min-width: 0;
        max-width: none;
        padding: 0 0 0 var(--sp-4);
        display: none;
    }
    .has-subdropdown.expanded > .dropdown-sublist { display: block; }
    /* There is no hover on touch, so the open state is the cue: the caret turns
       to point down and brightens while the submenu is expanded. */
    .has-subdropdown.expanded > .dropdown-link .dropdown-arrow {
        transform: rotate(90deg);
        color: var(--accent-hover);
    }

    /* ----- Social row at the foot of the drawer -----
       Sits below the last menu item, after a rule, so the menu reads first and
       the follow links close it off. */
    .nav-social-block {
        display: block;
        margin-top: var(--sp-5);
        padding-top: var(--sp-5);
        border-top: 1px solid var(--border);
    }
    .nav-social-label {
        display: block;
        margin-bottom: var(--sp-4);
        font-family: var(--font-sans);
        font-size: 0.6rem;
        font-weight: 600;
        letter-spacing: 0.28em;
        text-transform: uppercase;
        color: var(--text-dim);
    }
    /* Six across, one line, at every phone width. .social-icons is a wrapping
       flex row of fixed 40px discs, which needs 324px for six and so dropped
       IMDb onto a second line inside a 343px drawer (303px of content). As a
       six-track grid capped at 46px the chips instead shrink to whatever the
       drawer gives them — 45px at 390px wide, ~34px at 320px, still over the
       24px minimum target — and space-between keeps the row flush at both ends
       like the menu items above it. */
    .nav-social {
        display: grid;
        grid-template-columns: repeat(6, minmax(0, 46px));
        justify-content: space-between;
        gap: var(--sp-2);
    }

    /* Brand colours — the one place on the site the champagne palette is broken
       on purpose. A social mark is recognised by its colour before its shape,
       and six identical gold discs read as ornament rather than as links.
       Carried as custom properties, not as background/color directly, so the
       resting and hover rules below can both consume them from ONE declaration
       per platform — .social-icons a:hover otherwise repaints every chip gold,
       and it would take a :hover rule per platform to hold the brand fill. */
    .nav-social .social-link--facebook  { --brand: #1877f2; --brand-ink: #fff; }
    /* X's own black would disappear into the drawer, so it keeps a hairline. */
    .nav-social .social-link--twitter   { --brand: #0a0a0a; --brand-ink: #fff; --brand-edge: rgba(255,255,255,0.38); }
    .nav-social .social-link--instagram { --brand: radial-gradient(circle at 28% 106%, #fdf497 0%, #fdf497 5%, #fd5949 45%, #d6249f 60%, #285aeb 90%); --brand-ink: #fff; }
    .nav-social .social-link--youtube   { --brand: #ff0000; --brand-ink: #fff; }
    .nav-social .social-link--wikipedia { --brand: #f4f4f2; --brand-ink: #202122; }
    .nav-social .social-link--imdb      { --brand: #f5c518; --brand-ink: #000; }

    .nav-social a,
    .nav-social a:hover,
    .nav-social a:focus-visible {
        width: 100%;
        height: auto;
        aspect-ratio: 1;                    /* square, so the disc stays round */
        background: var(--brand, var(--bg-card));
        color: var(--brand-ink, var(--text-muted));
        border-color: var(--brand-edge, transparent);
    }
    /* Glyph tracks the chip so it stays proportionate as the row shrinks. */
    .nav-social a svg { width: 44%; height: 44%; }
    /* No hover on touch, so the pressed state is what has to read: the chip
       dips and dims rather than swapping colour, which would lose the brand. */
    .nav-social a:active   { transform: translateY(1px); filter: brightness(0.88); }
    .nav-social a:hover    { transform: translateY(-2px); filter: brightness(1.1); }
    .nav-social a:focus-visible {
        outline: 2px solid var(--accent);
        outline-offset: 3px;
    }

    /* Page scroll-lock + scrim behind the open drawer. These belong with the
       drawer, so they follow it up to the 1240px threshold. */
    body.nav-open       { overflow: hidden; }
    body.nav-open::before {
        content: '';
        position: fixed;
        inset: 0;
        background: rgba(0,0,0,0.5);
        z-index: 98;
    }
}

/* ----- Tablet portrait -----
   Small-screen chrome that is NOT tied to the nav drawer, so it keeps its
   original 880px threshold rather than following the hamburger up to 1240. */
@media (max-width: 880px) {
    /* Utility top bar compacts on small screens: drop the long email text
       (keep the mail icon as the tap target); phone + socials stay on one line. */
    .topbar-inner   { font-size: 0.72rem; gap: var(--sp-3); }
    .topbar-contact { gap: var(--sp-4); }
    .topbar-item--email .topbar-txt { display: none; }
    /* With the addresses hidden, a second mail icon would be a duplicate with
       no label to tell it apart — drop it and keep the primary as the tap
       target. Both addresses are still listed in the footer and on /contact. */
    .topbar-item--email-alt { display: none; }
    .topbar-social  { gap: var(--sp-3); }
    .topbar-social svg { width: 15px; height: 15px; }
    /* Those 15px glyphs were the whole hit box. Negative margin absorbs the
       padding so the row does not grow, but the tap area does. */
    .topbar-item,
    .topbar-social a { padding: 8px; margin: -8px; }

    .site-header {
        background: rgba(10, 10, 10, 0.92);
        backdrop-filter: blur(20px);
        padding: var(--sp-3) 0;
        border-bottom: 1px solid var(--border);
    }

    /* Family tree: smaller nodes on tablets */
    .ftree { --ftree-node: clamp(66px, 13vw, 108px); --ftree-stem: 1.85rem; }

    /* Contact: the form needs the full width before the two columns get tight,
       so this stacks one step earlier than .two-col does. */
    .contact-layout { grid-template-columns: 1fr; gap: var(--sp-6); }
    /* Once stacked, the details column (two cards + six social tiles) pushes the
       form roughly a screen and a half down the page — and the form is what the
       visitor came for. Put it first; the contact details read perfectly well
       underneath it. This also brings the post-submit confirmation into view. */
    .contact-panel  { order: -1; }
}

/* ----- Mobile landscape ----- */
@media (max-width: 768px) {
    :root {
        --fs-4xl: 2.5rem;
        --fs-3xl: 2rem;
        --fs-2xl: 1.5rem;
        --fs-xl:  1.25rem;
        --sp-9: 4rem;
        --sp-10: 5rem;
    }

    /* .container-narrow was left out here, so narrow-column pages kept a 24px
       gutter while everything else dropped to 16px — a visible mismatch when a
       narrow section sits above or below a full-width one. */
    .container,
    .container-narrow   { padding: 0 var(--sp-4); }
    .section            { padding: var(--sp-7) 0; }

    .hero               { min-height: 90vh; }
    .hero-actions       { flex-direction: column; align-items: stretch; }
    .hero-actions .btn  { width: 100%; justify-content: center; }

    /* ----- Hero slideshow on phones: swipe + dots take over ----- */
    .hero-slider            { min-height: 88vh; min-height: 88svh; }
    /* The slide padding and the container-query width formula that used to sit
       here are both gone: the photo covers the frame at every width now, and on
       a phone that is the only thing that works — a 1.5:1 photo laid out whole
       inside a 0.46:1 portrait frame is a 200px band adrift in empty gradient.
       Covering costs a hard crop instead (a phone shows roughly a third of the
       width), which is what --focus in data/site.php exists to aim. */
    .hero-copy              { padding: calc(var(--header-h) + var(--sp-6)) var(--sp-5) var(--sp-9); }
    .hero-slide-subtitle    { font-size: var(--fs-base); }
    .hero-slide-actions     { flex-direction: column; align-items: stretch; width: 100%; max-width: 360px; margin: 0 auto; }
    .hero-slide-actions .btn{ width: 100%; justify-content: center; }
    .hero-controls          { bottom: var(--sp-6); gap: var(--sp-3); }
    /* The dots are a 4px-tall bar — well under the 24px minimum target size
       (WCAG 2.5.8) on touch. Transparent vertical padding grows the tap area
       to 26px while background-clip keeps the visible bar exactly 30x4. */
    .hero-dot               {
        width: 30px;
        padding: 11px 0;
        box-sizing: content-box;
        background-clip: content-box;
    }
    .hero-dot::after        { inset: 11px 0; }
    .hero-slider .hero-scroll-cue { display: none; }

    .grid-3,
    .grid-2             { grid-template-columns: 1fr; }
    .gallery-grid       { grid-template-columns: repeat(2, 1fr); }
    .masonry            { column-count: 2; }
    .art-wall           { column-count: 2; column-gap: var(--sp-4); }
    .stats              { grid-template-columns: repeat(2, 1fr); gap: var(--sp-6); }
    .stat-number        { font-size: var(--fs-3xl); }

    .two-col            { grid-template-columns: 1fr; gap: var(--sp-6); }
    .two-col-image      { order: -1; aspect-ratio: 16 / 10; }

    /* About portrait: narrower frame and a tighter nameplate inset once the
       two columns stack. */
    .about-portrait         { max-width: 360px; }
    .about-portrait-plate   { left: var(--sp-4); right: var(--sp-4); bottom: var(--sp-4); }
    /* The warm bloom sits at inset -10% on each side. On desktop the portrait
       is narrower than its column so that spill has room, but once the columns
       stack the portrait fills the container and the bloom pushed ~33px past
       the viewport (body{overflow-x:hidden} clipped it, but it still widened
       the document). Keep the glow within the frame at this width. */
    .about-portrait::after  { inset: auto 0 -7% 0; }

    .form-grid          { grid-template-columns: 1fr; }
    .contact-panel      { padding: var(--sp-5); }
    .contact-card       { padding: var(--sp-4); gap: var(--sp-3); }
    .cta-band-inner     { grid-template-columns: 1fr; }
    .subscribe-form     { flex-direction: column; }
    .subscribe-form .btn{ width: 100%; }

    .footer-grid        { grid-template-columns: 1fr; gap: var(--sp-6); padding-bottom: var(--sp-6); }
    .footer-bottom-inner{ justify-content: center; text-align: center; }

    /* Compact wordmark: smaller name; the caption stays visible (header, drawer
       and footer) — just tightened to fit the narrower viewport. */
    .wordmark-name              { font-size: 1.35rem; }
    .wordmark-tag               { font-size: 0.56rem; letter-spacing: 0.26em; }
    .wordmark--footer .wordmark-name { font-size: 1.75rem; }
    .wordmark--footer .wordmark-tag  { display: inline-block; font-size: 0.6rem; letter-spacing: 0.28em; }

    .scroll-top         { bottom: var(--sp-4); right: var(--sp-4); width: 44px; height: 44px; }

    /* Family tree: branches can't follow wrapped rows, so collapse to centred
       photo clusters hanging off the trunk + junction dots (the spine stays). */
    .ftree__row          { flex-wrap: wrap; width: auto; max-width: 100%; row-gap: var(--sp-5); }
    .ftree__row::before,
    .ftree__node::before { display: none; }
    .ftree__node         { width: clamp(96px, 27vw, 124px); }

    /* Orator expanding gallery: no room to expand on phones, so lay the panels
       out as a tidy 2-column tile grid (still tap-to-open in the lightbox). */
    .xrow   { display: grid; grid-template-columns: repeat(2, 1fr); height: auto; gap: var(--sp-3); }
    .xpanel { aspect-ratio: 4 / 5; }
    /* An odd count left a half-empty last row with a conspicuous hole beside it.
       Let a lone trailing tile run the full width instead, in a landscape crop
       so it does not tower over the pairs above it. */
    .xrow > .xpanel:last-child:nth-child(odd) { grid-column: 1 / -1; aspect-ratio: 16 / 10; }
}

/* Extra-small phones: tighten further */
@media (max-width: 380px) {
    .wordmark-name              { font-size: 1.15rem; letter-spacing: 0.005em; }
    .wordmark-tag               { font-size: 0.52rem; letter-spacing: 0.2em; }
    .nav-drawer-brand .wordmark-name { font-size: 1.3rem; }
    .wordmark--footer .wordmark-name { font-size: 1.5rem; }
    .wordmark--footer .wordmark-tag  { letter-spacing: 0.22em; }
}

/* ----- Small mobile ----- */
@media (max-width: 480px) {
    :root {
        --fs-base: 0.95rem;
        --sp-5: 1.25rem;
    }
    .hero               { padding-top: calc(var(--header-h) + var(--sp-4)); }
    .hero-copy          { padding-top: calc(var(--header-h) + var(--sp-4)); }
    .hero-slide-lead    { font-size: var(--fs-base); }
    .gallery-grid       { grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
    .masonry            { column-count: 2; column-gap: var(--sp-2); }
    .art-wall           { column-count: 2; column-gap: var(--sp-3); }
    .timeline           { padding-left: var(--sp-6); }
    .timeline-item::before { left: calc(-1 * var(--sp-6) + 2px); }

    /* Family tree: smaller crest + trunk on small phones (node size is set by
       the <=768px rule above, which already gives a comfortable 2–3 per line) */
    .ftree::before      { top: 74px; }
    .ftree__crest       { width: clamp(104px, 32vw, 132px); }

    /* Orator gallery: smaller caption numerals on small phones */
    .xpanel__no         { font-size: var(--fs-xl); }

    /* Follow tiles: two across leaves too little room for the handle beside the
       chip on a phone, so they go single file. */
    .social-tiles       { grid-template-columns: 1fr; }
}

/* ----- Brand wordmark — touch animation -----
   A different pass from the desktop one, and a cheaper one.

   Desktop loops two things that repaint the glyphs on every frame: a
   filter: drop-shadow() glow, and the .wordmark::after sheen. That is fine on a
   pointer machine and wrong on a phone, where the same loop runs behind the
   drawer slide and never stops costing battery. A permanent slow drift is also
   the easiest kind of motion to miss on a mark this small.

   So touch gets a beat instead of a drift: one near-white highlight crosses the
   letters and then rests (a single background pass per 5s, no filter, no
   sheen), the tagline's hairline stretches and settles on transform: scaleX,
   and the drawer's brand — the logo this animation is really for, since it is
   the first thing in the open menu — floats 2px on its own slower cycle. The
   last two are transform/opacity only, so they stay on the compositor.

   Keyed on (hover: none) as well as a width so a tablet gets the touch pass
   while a narrow desktop window keeps the pointer one. Everything is expressed
   as the tokens declared in main.css, so nothing here has to unset anything. */
@media (max-width: 768px), (hover: none) {
    :root {
        /* one narrow near-white band inside the champagne gold, rather than the
           desktop tile's even ripple: the highlight is what travels, and the
           gold on either side of it stays where it is */
        --wm-gradient: linear-gradient(100deg,
            #a88845 0%, #c9a961 26%, #f7ecd0 44%, #fffaf2 50%, #f7ecd0 56%, #c9a961 74%, #a88845 100%);
        /* a 3.2x tile keeps the highlight narrow relative to the name, so it
           reads as a glint crossing the letters and not as a colour change */
        --wm-gradient-size: 320% auto;
        --wm-rest-pos: 100% 50%;
        --wm-anim-name: wm-shine 5s var(--ease-out) infinite;
        /* the tagline catches the same light a beat later */
        --wm-anim-tag:  wm-shine 5s var(--ease-out) 0.4s infinite;
        --wm-anim-rule: wm-line-sweep 5s var(--ease-out) infinite;
        --wm-sheen: none;
        --wm-float: wm-float 6s ease-in-out infinite;
    }
}

/* ----- Touch target sizes -----
   WCAG 2.5.8 asks for 24x24 CSS px. Measured on a phone, the breadcrumb links
   were 43x19 and the footer contact links 22px tall. Both sit inside flex
   parents (.breadcrumb is inline-flex, .contact-list li is a column flex), so
   their children are blockified and vertical padding does grow the hit box.
   Padding only — the type size and colours are unchanged.

   Keyed on (hover: none) rather than a width, because the thing that makes a
   24px target too small is a fingertip, not a narrow window. At max-width:768px
   this missed every tablet — an iPad in portrait is 820px wide and just as
   touch-only as a phone. */
@media (hover: none) {
    .breadcrumb a   { padding: 5px 2px; }
    .contact-list a { padding: 5px 0; }
    .footer-links a { padding: 4px 0; display: inline-block; }
}

/* ----- 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;
    }
    .reveal { opacity: 1; transform: none; }

    /* The about-portrait sheen is pure motion — with transitions flattened it
       would only ever flash, so drop it rather than snap it across. */
    .about-portrait-sheen { display: none; }
}
