/*
 * Entertainment page — the capabilities accordion and its galleries.
 *
 * Lifted verbatim from the <style> block in the frozen static build's
 * entertainment.html (STATIC-REFERENCE.md is the authority on WHY any of this
 * looks the way it does). Kept as one page-scoped file rather than folded into
 * style.css because it is ~700 lines that no other page uses, and because
 * keeping it a straight copy means a future diff against the static build is
 * still meaningful.
 *
 * Enqueued only on the Entertainment page — see refinery_enqueue_assets().
 * Unlike front-page.css this is NOT scoped to a body class: the static source
 * had no wrapper scope, and inventing one would mean rewriting every selector
 * here, which is exactly the kind of hand-edit that makes the copy drift.
 */

    /* --- Selected Work section (dark) --- */
    /* padding-top cut from .section's 6rem on 2026-09-08 (Kay: "too much
       empty space above the accordion"). The gap was really TWO stacked
       spaces — the section's own 6rem plus the zesty snippet's margin — so
       trimming only the section leaves the snippet breathing where it should.
       The bottom is untouched; the complaint was specifically the top. */
    .work-section {
      background: var(--dark);
      color: var(--white);
      padding-top: 2.5rem;
    }
    .work-section .t-label { color: var(--chartreuse); }
    #work-heading { color: var(--white); }

    /* --- Capabilities accordion --- */
    .work-accordion-intro {
      max-width: 44rem;
      margin-top: 1.25rem;
      color: rgba(255, 255, 255, 0.72);
      font-size: clamp(1.0625rem, 1.4vw, 1.3125rem);
      line-height: 1.7;
    }

    .work-accordion {
      border-top: 1px solid rgba(255, 255, 255, 0.14);
    }

    .accordion-item {
      border-bottom: 1px solid rgba(255, 255, 255, 0.14);
    }

    .accordion-header {
      margin: 0;
    }

    .accordion-trigger {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 1.5rem;
      width: 100%;
      padding: 1.65rem 0.25rem;
      background: none;
      border: 0;
      cursor: pointer;
      text-align: left;
      color: var(--white);
      transition: color var(--transition-fast);
    }

    .accordion-trigger:hover,
    .accordion-trigger:focus-visible {
      color: rgba(255, 255, 255, 0.6);
    }

    .accordion-title {
      font-size: clamp(1.5rem, 3vw, 2.5rem);
      /* Poppins Black, all caps — the brush accent inside carries the contrast */
      font-weight: 900;
      text-transform: uppercase;
      line-height: 1.12;
      letter-spacing: -0.01em;
      /* Slides from left (closed) to centre (open) */
      position: relative;
      left: 0;
      transition: left var(--transition-med), transform var(--transition-med);
    }
    /* Brush caps render ~0.73x Poppins Black caps at the same em. Kay's values
       for inline section accents, shared with brands.html — the global
       .accent-brush (1.18em / -0.04em) was tuned against an earlier cut of the
       font and rides high. */
      /* Brush font removed 2026-08-13 — the accent is now Poppins Light 300 at
         the SAME size as the type it sits in, so no optical size-up or baseline
         correction. Every value here used to compensate for brush caps
         rendering ~0.73x Poppins caps; all of it is dead with the brush gone. */
    .accordion-title .accent-brush {
      font-size: 1em;
    }

    .accordion-item.is-open .accordion-title {
      left: 50%;
      transform: translateX(-50%);
    }
    @media (prefers-reduced-motion: reduce) {
      .accordion-title { transition: none; }
    }

    /* Plus / minus icon */
    .accordion-icon {
      position: relative;
      flex: 0 0 auto;
      width: 24px;
      height: 24px;
      color: rgba(255, 255, 255, 0.6);
      transition: color var(--transition-fast);
    }
    .accordion-item.is-open .accordion-icon {
      color: var(--chartreuse);
    }
    .accordion-icon::before,
    .accordion-icon::after {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      background: currentColor;
      transition: transform var(--transition-med), opacity var(--transition-med);
    }
    .accordion-icon::before {
      width: 24px;
      height: 2px;
      transform: translate(-50%, -50%);
    }
    .accordion-icon::after {
      width: 2px;
      height: 24px;
      transform: translate(-50%, -50%);
    }
    .accordion-item.is-open .accordion-icon::after {
      transform: translate(-50%, -50%) scaleY(0);
      opacity: 0;
    }

    /* Collapsible panel via grid-template-rows 0fr -> 1fr */
    .accordion-panel {
      display: grid;
      grid-template-rows: 0fr;
      transition: grid-template-rows var(--transition-med);
    }
    .accordion-item.is-open .accordion-panel {
      grid-template-rows: 1fr;
    }
    .accordion-panel-inner {
      /* Fallback for browsers without `overflow: clip` (Safari < 16). There the
         panel keeps clipping the full-bleed galleries horizontally — the
         collapse animation matters more than the breakout. */
      overflow: hidden;
      min-height: 0;
    }

    /* ⚠️ THIS PAIRING IS THE FULL-BLEED FIX (2026-08-29) — do not simplify it
       back to `overflow: hidden`.

       `overflow: hidden` here is load-bearing for the 0fr -> 1fr collapse
       above: it is what hides the panel's content while the grid row has no
       height. But `hidden` clips BOTH axes, so from the moment the galleries
       went edge to edge (2026-08-25) this box was quietly cutting them back to
       the panel's own width. Measured on the live Entertainment page: the
       breakout resolved to -7 -> 1803 as intended, then got clipped to the
       container at 210 -> 1586, losing ~210px off each side — roughly half a
       poster at both ends of every row.

       `overflow-x: visible` with `overflow-y: clip` keeps the vertical clipping
       the animation needs and lets the horizontal breakout escape. The two
       values must be `visible` + `clip` specifically: CSS coerces a `visible`
       axis to `auto` when the OTHER axis is `hidden` or `scroll`, which would
       hand the panel a scrollbar — but `clip` is explicitly exempt from that
       coercion, so this pair survives as written.

       Verified live: no horizontal scrollbar (scrollWidth == clientWidth),
       collapsed panel still measures 0px high, reopen restores full height. */
    @supports (overflow: clip) {
      .accordion-panel-inner {
        overflow-x: visible;
        overflow-y: clip;
      }
    }
    /* Sub-nav navigation snaps sections open/closed (no animation) so the scroll lands cleanly */
    .work-accordion.no-anim .accordion-panel,
    .work-accordion.no-anim .accordion-title {
      transition: none;
    }

    /* Anchor landing for #work. The hero's "Explore Capabilities" button that
       originally needed this was removed 2026-09-08, but the rule stays: a
       plain fragment link to #work scrolls the target to y=0, underneath the
       fixed site nav AND the sticky sub-nav, so the section header lands
       off-screen and reads as having jumped too far. Anything linking to
       #work still needs it — the sub-nav's own links do not, because
       script.js intercepts those and subtracts the offset itself, but only
       for links carrying data-section. 1rem of air so it does not sit flush
       against the bar. */
    .work-section {
      scroll-margin-top: calc(var(--nav-height) + var(--subnav-height) + 1rem);
    }

    /* Section intro — left-aligned copy boxed over a full-width image banner.
       Each section sets --banner-img on its .accordion-item (images in
       assets/images/entertainment-page/sections/, 2200x1000 web copies). */
    .accordion-text {
      position: relative;
      min-height: 420px;
      margin: 0.5rem 0 1.9rem;
      padding: 2.75rem 3rem;
      display: flex;
      flex-direction: column;
      justify-content: flex-end;
      align-items: flex-start;
      text-align: left;
      border-radius: 10px;
      overflow: hidden;
      color: rgba(255, 255, 255, 0.82);
      background-image:
        /* fade/vignette below the text — near-black at the base for legibility */
        linear-gradient(to top, rgba(5, 5, 5, 0.98) 0%, rgba(8, 8, 8, 0.62) 48%, rgba(26, 26, 26, 0) 75%),
        /* scrim on the boxed-text side */
        linear-gradient(100deg, rgba(26, 26, 26, 0.9) 0%, rgba(26, 26, 26, 0.5) 40%, rgba(26, 26, 26, 0.02) 65%),
        var(--banner-img, url('../images/keyart-section-header-web.jpg'));
      background-size: cover;
      background-position: center;
    }
    .accordion-text > * {
      max-width: 46%;
    }
    /* Alternate: text boxed on the right (copy stays left-aligned) */
    .accordion-text--right {
      align-items: flex-end;
      background-image:
        linear-gradient(to top, rgba(5, 5, 5, 0.98) 0%, rgba(8, 8, 8, 0.62) 48%, rgba(26, 26, 26, 0) 75%),
        linear-gradient(260deg, rgba(26, 26, 26, 0.9) 0%, rgba(26, 26, 26, 0.5) 40%, rgba(26, 26, 26, 0.02) 65%),
        var(--banner-img, url('../images/keyart-section-header-web.jpg'));
    }
    /* Per-section banner images. Alternates for #cap-ooh also in the sections
       folder: in-theater.jpg, specialty-ooh.jpg */
    /* Key Art supplied 2026-08-07 — the last section still on the placeholder
       fallback. This one has NO baked-in gradient, which is the correct source
       for this treatment: .accordion-text already lays two gradients over the
       image (a bottom vignette and a left scrim), so art that arrives
       pre-darkened gets double-darkened. */
    #cap-keyart   { --banner-img: url('../images/entertainment-page/sections/key-art-web.jpg'); }
    #cap-ooh      { --banner-img: url('../images/entertainment-page/sections/3d-digital-ooh-web.jpg'); }
    #cap-digital  { --banner-img: url('../images/entertainment-page/sections/digital-display-web.jpg'); }
    #cap-social   { --banner-img: url('../images/entertainment-page/sections/social-web.jpg'); }
    #cap-strategy { --banner-img: url('../images/entertainment-page/sections/concept-sketches-storyboarding-web.jpg'); }
    #cap-fyc      { --banner-img: url('../images/entertainment-page/sections/fyc-web.jpg'); }
    .accordion-text p {
      font-size: clamp(1.0625rem, 1.4vw, 1.3125rem);
      line-height: 1.7;
      margin: 0 0 0.95rem;
    }
    .accordion-text p:last-child {
      margin-bottom: 0;
    }
    @media (max-width: 900px) {
      .accordion-text {
        min-height: 340px;
        padding: 2rem 1.5rem;
      }
      .accordion-text > * {
        max-width: 100%;
      }
    }
    .accordion-callout {
      font-weight: 700;
      color: var(--white);
      font-style: italic;
    }
    /* "What We Do" is a nested disclosure inside each already-open section
       (2026-08-07). The capability lists run 4-6 groups deep and pushed the
       gallery far below the fold, so they start collapsed and this button
       expands them. Styled to match the old .accordion-list-label it replaced —
       same chartreuse micro-caps, still centred — so the panel reads the same
       when closed. width:fit-content + auto side margins is what centres a
       flex button; text-align on the parent wouldn't. */
    .accordion-list-toggle {
      display: flex;
      align-items: center;
      gap: 0.55rem;
      width: fit-content;
      margin: 1.25rem auto 0.9rem;
      padding: 0.25rem 0.15rem;
      background: none;
      border: 0;
      cursor: pointer;
      font-family: inherit;
      font-size: 0.78rem;
      font-weight: 700;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      color: var(--chartreuse);
      transition: opacity var(--transition-fast);
    }
    .accordion-list-toggle:hover,
    .accordion-list-toggle:focus-visible { opacity: 0.7; }

    /* Chevron: down = collapsed, up = expanded */
    .accordion-list-toggle .chev {
      width: 0.45rem;
      height: 0.45rem;
      border-right: 2px solid currentColor;
      border-bottom: 2px solid currentColor;
      transform: translateY(-0.12em) rotate(45deg);
      transition: transform var(--transition-fast);
    }
    .accordion-list-toggle[aria-expanded="true"] .chev {
      transform: translateY(0.08em) rotate(-135deg);
    }

    /* max-height, NOT the 0fr -> 1fr grid trick the outer .accordion-panel uses.
       That trick needs the collapsing row track to take its base size from the
       item's min-content contribution, but this panel is nested inside
       .accordion-panel-inner — itself a grid item carrying
       `overflow:hidden; min-height:0`. In that context the `1fr` resolved to
       0px and the panel never opened (verified: the .is-open class and the rule
       were both applied, computed grid-template-rows stayed 0px). max-height
       sidesteps it; initAccordion() sets the pixel value from scrollHeight and
       clears it to `none` after the transition so the panel can still reflow. */
    .accordion-list-panel {
      max-height: 0;
      overflow: hidden;
      opacity: 0;
      transition: max-height var(--transition-med), opacity var(--transition-med);
    }
    .accordion-list-panel.is-open { opacity: 1; }
    @media (prefers-reduced-motion: reduce) {
      .accordion-list-panel { transition: none; }
      .accordion-list-toggle .chev { transition: none; }
    }
    .accordion-list {
      list-style: none;
      padding: 0;
      margin: 0;
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
      gap: 0.5rem 1.5rem;
    }
    .accordion-list li {
      position: relative;
      padding-left: 1.1rem;
      font-size: 1rem;
      color: rgba(255, 255, 255, 0.75);
    }
    .accordion-list li::before {
      content: "";
      position: absolute;
      left: 0;
      top: 0.55em;
      width: 6px;
      height: 6px;
      border-radius: 50%;
      background: var(--chartreuse);
    }

    /* Grouped list — bold group header + indented sub-bullets */
    .accordion-list--grouped {
      grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
      gap: 1.85rem 1.75rem;
      align-items: start;
    }
    .accordion-list--grouped > .accordion-group {
      padding-left: 0;
    }
    .accordion-list--grouped > .accordion-group::before {
      display: none; /* the group is a header, not a bullet */
    }
    .accordion-group-title {
      display: block;
      margin-bottom: 0.6rem;
      font-size: 0.95rem;
      font-weight: 700;
      line-height: 1.35;
      color: var(--white);
    }
    .accordion-sublist {
      list-style: none;
      margin: 0;
      padding: 0;
      display: flex;
      flex-direction: column;
      gap: 0.4rem;
    }
    .accordion-sublist li {
      font-size: 0.95rem;
    }

    /* Full-width capability layout — 6 across on large screens.
       FLEX, not grid, and that's the whole point: sections hold 4, 5 or 6 groups
       (Awards & FYC has 4, Digital and Social have 5), and a grid with `1fr`
       tracks always left-aligns a short row against a 6-column template. Flex
       items at a 1/6 basis plus justify-content:center let a 4- or 5-item
       section sit as one centred block instead of hanging off to the left.
       --cols is the per-row count; the basis subtracts the (cols - 1) gaps. */
    .accordion-list--wide {
      --cols: 6;
      --col-gap: 1.75rem;
      max-width: none;
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      align-items: flex-start;
      gap: 1.85rem var(--col-gap);
      margin-bottom: 2.25rem;
    }
    .accordion-list--wide > .accordion-group {
      flex: 0 1 calc((100% - (var(--cols) - 1) * var(--col-gap)) / var(--cols));
    }
    /* Step the count down rather than letting flex-wrap guess — the group titles
       are 2-4 words and wrap hard below ~170px. */
    @media (max-width: 1240px) { .accordion-list--wide { --cols: 4; } }
    @media (max-width: 900px)  { .accordion-list--wide { --cols: 3; } }
    @media (max-width: 640px)  { .accordion-list--wide { --cols: 2; } }
    @media (max-width: 420px)  { .accordion-list--wide { --cols: 1; } }

    /* Stacked key-art gallery — two rows of five, all 2:3, flush + square.

       ⚠️ NO TEMPLATE USES THIS ANY MORE (2026-09-04): the Key Art section was
       the only caller and it moved to 'scroll'. Kept because
       refinery_render_gallery() still accepts `layout => 'stack'` — but note
       that it is now the one gallery layout that CROPS, since a five-column
       grid cannot also let each tile keep its own width. Anything brought back
       onto it needs that reconciled first. */
    .accordion-gallery--stack {
      display: grid;
      grid-template-columns: repeat(5, 1fr);
      gap: 0;
      padding: 0.5rem 0 0;
      overflow: visible;
    }
    .accordion-gallery--stack .keyart-item {
      aspect-ratio: 2 / 3;
      height: auto;
    }

    /* Portfolios: square corners, no gaps, no hover lift (applies to every section) */
    .accordion-gallery--stack .keyart-item,
    .accordion-gallery--scroll .keyart-item {
      border-radius: 0;
    }
    .accordion-gallery--stack .keyart-item:hover,
    .accordion-gallery--scroll .keyart-item:hover {
      transform: none;
      box-shadow: none;
    }

    /* Chartreuse "Case Study" strip at the foot of flagged tiles (future case-study link) */
    .keyart-case-strip {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 3;
      padding: 0.42rem 0.5rem;
      background: var(--chartreuse);
      color: var(--dark);
      font-size: 0.62rem;
      font-weight: 800;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      text-align: center;
    }
    .keyart-item--case .keyart-info {
      bottom: 1.7rem; /* clear the Case Study strip */
    }
    @media (max-width: 1024px) {
      .accordion-gallery--stack { grid-template-columns: repeat(4, 1fr); }
    }
    @media (max-width: 760px) {
      .accordion-gallery--stack { grid-template-columns: repeat(3, 1fr); }
    }
    @media (max-width: 500px) {
      .accordion-gallery--stack { grid-template-columns: repeat(2, 1fr); }
    }

    /* ── The section's out-link, inside an accordion panel (2026-09-04) ──────
       Michael / Claire, two notes on the same element:

       1. "'What we do' is center justified, but the 'explore all social
          content' is left justified. Can we either center justify everything,
          or left justify everything?" — centred, to match. Centring is the
          smaller move: .accordion-list-toggle is centred deliberately so the
          panel "reads the same when closed" as the label it replaced, and
          left-aligning it would undo that. width:fit-content + auto side
          margins is what centres a flex item; text-align on the parent will not.

       2. "Reduce space between the end of the deliverable galleries and the
          link… That link is closer to the next deliverable." Measured: 68px
          above (the carousel's 40px bottom margin plus this element's 28px
          top — they do not collapse, the panel is a grid container) against
          36px below. So the link sat nearer to the NEXT section than to the
          work it belongs to. Now ~18px above, 40px below.

       Scoped to .accordion-panel-inner: the "Trace more stories" link in the
       Case Studies section reuses this class outside any panel, and that
       section is left-aligned throughout. */
    .accordion-panel-inner .gallery-carousel {
      margin-bottom: 1.1rem;
    }
    /* ⚠️ THIS RULE OUTRANKS THE .accordion-explore BLOCK BELOW — two classes
       to its one — so the button's margins are set HERE, not there. When the
       link became a filled button (2026-09-09) a `margin: 2rem 0 2.5rem` went
       on the lower rule and did nothing: this one kept zeroing the top and the
       button sat welded to the gallery above it. Measured at 0px.
    
       The centring stays — that is what `auto` is doing, and it is right for a
       button that closes a section. Only the top margin is added. */
    .accordion-panel-inner .accordion-explore {
      display: flex;
      width: fit-content;
      margin: 2.5rem auto 3rem;
    }

    /* "Explore all the art" link */
    /* A BUTTON, NOT A TEXT LINK (2026-09-09, Kay: "make it a bigger, bolder
       button"). It closes every accordion section and was a chartreuse text
       link that read as a footnote to the gallery above it rather than as the
       way on to the rest of the work.

       Filled chartreuse with dark text, the same treatment .btn-primary uses,
       rather than composed from .btn — .accordion-explore is emitted by the
       template in five places and by the frozen script.js in a sixth, so the
       class has to carry its own appearance.

       ⚠️ Duplicated in brands.css. The two sheets are page-scoped and
       self-contained (see the note there) — restyle one, restyle both. */
    .accordion-explore {
      display: inline-flex;
      align-items: center;
      gap: 0.6rem;
      margin: 2rem 0 2.5rem;
      padding: 0.95rem 1.75rem;
      border-radius: 999px;
      background: var(--chartreuse);
      color: var(--dark);
      font-size: 1.125rem;
      font-weight: 700;
      letter-spacing: -0.01em;
      text-decoration: none;
      transition: gap var(--transition-fast), transform var(--transition-fast);
    }
    .accordion-explore:hover,
    .accordion-explore:focus-visible {
      color: var(--dark);
      transform: translateY(-2px);
    }
    .accordion-explore .arrow {
      display: inline-block;
      transition: transform var(--transition-fast);
    }
    .accordion-explore:hover { color: #eaf03a; }
    .accordion-explore:hover .arrow { transform: translateX(5px); }

    /* Client logo placeholders (rectangular) — swap for real logos when supplied */
    .logos-section .logo-item--placeholder {
      width: 128px;
      height: 46px;
      border-radius: 6px;
      background: rgba(71, 71, 71, 0.06);
      border: 1px dashed rgba(71, 71, 71, 0.28);
    }

    /* Per-section CTA (injected by initAccordion) */
    .accordion-cta {
      display: inline-flex;
      align-items: center;
      gap: 0.55rem;
      margin: 0.25rem 0 2rem;
      font-size: 1.0625rem;
      font-weight: 600;
      color: var(--chartreuse);
      letter-spacing: -0.01em;
      transition: gap var(--transition-fast);
    }
    .accordion-cta .arrow {
      display: inline-block;
      transition: transform var(--transition-fast);
    }
    .accordion-cta:hover {
      color: #eaf03a;
    }
    .accordion-cta:hover .arrow {
      transform: translateX(5px);
    }

    /* Gallery sits inside the panel, with breathing room before the next item */
    .accordion-gallery {
      padding-bottom: 2.5rem;
    }

    /* Horizontal scroll galleries (non-Key-Art sections) with mixed tile sizes */
    .gallery-carousel {
      position: relative;
      margin-bottom: 2.5rem;
    }
    .accordion-gallery--scroll {
      display: flex;
      gap: 0;
      padding: 14px 0;
      overflow-x: auto;
      scroll-snap-type: x proximity;
      scroll-behavior: smooth;
      -webkit-overflow-scrolling: touch;
      scrollbar-width: none;
    }
    .accordion-gallery--scroll::-webkit-scrollbar {
      display: none;
    }
    /* 🔴 FIXED HEIGHT, NATURAL WIDTH, NEVER CROP (2026-09-04, Kay — the same
       rule the splash rows got two days earlier, now applied everywhere).

       These tiles used to be one of THREE fixed shapes — 2:3, 1:1 or 16:10 —
       chosen by `_refinery_orientation`, which is a bare `h > w ? portrait :
       landscape` with no tolerance, and the art was cropped to fit. A 16:9 clip
       lost ~5% and nobody noticed. A 4:5 Instagram post counted as "portrait"
       and was cut to 2:3. A 9:16 vertical video lost ~16% top and bottom. That
       is Michael / Claire's "weird crops for the horizontal work" and their
       "what happens in social when all we have is vertical video?" — the same
       bug, asked twice.

       Now every tile is the row's height and as wide as its own art. The row
       becomes a run of mixed widths, which IS the design: a poster, a banner
       and a vertical cut are different shapes and the page should say so.

       --ar comes from the attachment, server-side (see inc/gallery-render.php
       for why intrinsic sizing will not do it). The 2/3 fallback only applies
       to a piece WordPress never measured. */
    .accordion-gallery--scroll .keyart-item {
      flex: 0 0 auto;
      height: clamp(210px, 24vw, 330px);
      width: auto;
      aspect-ratio: var(--ar, 2 / 3);
      scroll-snap-align: start;
    }

    /* `contain`, not `cover`. With the box built from --ar the two are the same
       thing for almost every piece — this is the backstop for the two cases
       where they are not: a file WordPress never measured (falls back to 2:3)
       and one whose ratio was clamped at 0.5 or 3.2. Those letterbox now
       instead of losing their edges. Same reasoning as portfolio.css. */
    .accordion-gallery--scroll .keyart-img,
    .accordion-gallery--scroll .keyart-video {
      object-fit: contain;
    }

    .gallery-arrow {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      width: 46px;
      height: 46px;
      border-radius: 50%;
      border: 1px solid rgba(255, 255, 255, 0.25);
      background: rgba(20, 20, 20, 0.72);
      backdrop-filter: blur(6px);
      -webkit-backdrop-filter: blur(6px);
      color: #fff;
      font-size: 1.6rem;
      line-height: 1;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      opacity: 0;
      transition: opacity var(--transition-fast), background var(--transition-fast), color var(--transition-fast);
      z-index: 4;
    }
    .gallery-arrow--prev { left: 10px; }
    .gallery-arrow--next { right: 10px; }
    .gallery-arrow:hover {
      background: var(--chartreuse);
      border-color: var(--chartreuse);
      color: var(--dark);
    }
    .gallery-carousel.has-overflow:hover .gallery-arrow {
      opacity: 1;
    }
    .gallery-arrow:disabled {
      opacity: 0 !important;
      pointer-events: none;
    }
    @media (hover: none) {
      .gallery-carousel.has-overflow .gallery-arrow:not(:disabled) {
        opacity: 0.92;
      }
    }

    .accordion-gallery .keyart-ph-label {
      position: absolute;
      bottom: 0.85rem;
      left: 0.9rem;
      font-size: 0.7rem;
      font-weight: 700;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      color: rgba(255, 255, 255, 0.55);
    }

    @media (max-width: 640px) {
      .accordion-trigger { padding: 1.25rem 0.25rem; }
      .accordion-gallery { grid-template-columns: repeat(2, 1fr); }
    }

    /* --- Hero reel (full-bleed sizzle video, no text over it) --- */
    .ent-reel {
      background: #000;
      /* ⚠️ WHATEVER IS FIRST OWNS THE NAV CLEARANCE; exactly one element
         should. The site nav is position:fixed, so the first block under it
         has to pad itself down by --nav-height or it starts underneath.

         History, because this has flipped twice: the reel carried it until
         2026-09-08, when the logo strip moved above the reel and took it.
         On 2026-09-09 the reel moved back on top — and nobody moved the
         padding back with it, so the video's top --nav-height sat behind the
         nav bar (Kay, 2026-09-14: "the hero video goes behind the top menu on
         load"). Brands never moved its reel and never lost it; the two rules
         now match again. */
      padding-top: var(--nav-height);
      line-height: 0;
    }
    .ent-reel-video {
      display: block;
      width: 100%;
      /* 56.25vw = a true 16:9 at full width; clamped so the headline below
         still breaks the fold on short screens. cover crops the excess. */
      height: clamp(240px, 56.25vw, 78vh);
      object-fit: cover;
      background: #000;
      /* Chartreuse rule closing the reel — the same underline the sub-nav and
         the .section-label dash use, thickened to 5px on 2026-08-24 (Kay).
         The site's other chartreuse rules are 2px, but they run under a ~120px
         nav link; across the full bleed that reads as a hairline, and 3px was
         still shy. .brand-reel-video carries the identical declaration; change
         both or neither. Sits on the VIDEO, not the section, so it hugs the
         frame even when the clamp shortens it. */
      border-bottom: 5px solid var(--chartreuse);
    }

    /* --- Hero intro type (centred, sits under the sizzle reel) ---
       Replaced the drifting key-art collage that used to back this block —
       removed 2026-08-04, it competed with the video directly above it. */
    /* DARKER THAN THE SECTION BELOW IT (Kay, 2026-09-09). .page-hero paints
       var(--dark) and the case-studies band under it carries .bg-dark — the
       same colour — so the two ran together as one field and the hero had no
       edge.

       --black (#0d0d0d) rather than a new value: the palette already carries a
       step below --dark and the footer uses it, so this is the existing dark
       end of the ramp rather than a fourth near-black invented for one
       section. */
    .ent-hero-intro {
      background: var(--black);
      padding: 4.5rem 0 4rem;
      text-align: center;
    }
    /* .section-label is a flex row with a chartreuse ::before dash, so it needs
       centring on the cross axis too — text-align alone won't move it. */
    .ent-hero-intro .section-label {
      justify-content: center;
    }
    .ent-hero-intro h1 {
      max-width: 20ch;      /* holds the display type to ~3 tight lines */
      margin: 0 auto 1.25rem;
      /* All-caps at Poppins' heaviest (900 — .t-display-lg is 800, and 900 is
         the top weight the Google Fonts link loads) so the Poppins lines hold
         their own against the brush accent. */
      text-transform: uppercase;
      font-weight: 900;
    }
    /* Brush accent size is per-context — brush caps relate optically to whatever
       type they sit beside, so this is tuned for THIS hero, not set globally. */
      /* Brush font removed 2026-08-13 — the accent is now Poppins Light 300 at
         the SAME size as the type it sits in, so no optical size-up or baseline
         correction. Every value here used to compensate for brush caps
         rendering ~0.73x Poppins caps; all of it is dead with the brush gone. */
    .ent-hero-intro .accent-brush {
      font-size: 1em;
    }
    .ent-hero-intro p {
      max-width: 62ch;
      margin: 0 auto 2rem;
      color: rgba(255, 255, 255, 0.65);
    }
    .ent-hero-actions {
      display: flex;
      flex-wrap: wrap;
      gap: 1rem;
      justify-content: center;
    }

    /* ── Awards band (chartreuse) ────────────────────────────────────────── */

    /* Wider than the stock .cta-content 700px: the headline is a full sentence
       and the tally below it wants four columns. */
    /* margin-inline:auto is the fix for "right side has much more space than
       the left" (2026-09-04, Michael / Claire). The shared .cta-content is
       max-width:700px with no auto margins, so every CTA band is a
       left-aligned block in a 1440px container — fine when the block is nearly
       as wide as the band, obvious here where this one widens to 1000px and
       left 32px / right 408px do not read as a deliberate asymmetry.
       Scoped to the awards band on purpose: the other CTA bands are narrower
       and were not raised. */
    .ent-awards-content {
      max-width: 1000px;
      margin-inline: auto;
    }

    /* Shared .cta-title tops out at 4rem, which was sized for a five-word
       headline. This one is a paragraph, so it steps down a tier. */
    .ent-awards .cta-title {
      font-size: clamp(1.75rem, 3.2vw, 3rem);
      margin-bottom: 2.75rem;
    }

    /* The "Our award wins include:" lede and the rule above the tally were both
       removed 2026-08-07 — the numbers introduce themselves. */
    .ent-awards-grid {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 2rem;
      list-style: none;
      margin: 0;
      padding: 0;
    }

    /* The R-roundel background treatment now lives in styles.css and applies to
       every chartreuse band, so there's nothing page-specific left here. */

    .ent-award {
      display: flex;
      flex-direction: column;
      /* Whole cell centres now (2026-08-07) — icon, number and label on one
         axis. Was flex-start with only the icon centred over the number, but
         "Golden Trailer Awards" wraps to two lines and a left-aligned ragged
         label under a centred trophy read as a mistake. */
      align-items: center;
      text-align: center;
      gap: 0.35rem;
    }

    /* Icon + number stay in their own shrink-to-fit column. Redundant now that
       the cell centres too, but it's what guarantees the trophy sits over the
       DIGITS rather than over the cell — which matters again if this ever goes
       back to left-aligned. */
    .ent-award-stack {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    /* Fixed-height box with the trophy sitting on its floor, so four statuettes
       of different proportions share one ground line. Heights are per-icon and
       inline on the <img> — see the note in the markup. */
    .ent-award-icon {
      display: flex;
      align-items: flex-end;
      height: 62px;
      margin-bottom: 0.9rem;
    }

    .ent-award-icon img {
      display: block;
      width: auto;   /* height comes from the inline style */
      /* The SVGs ship a near-black #010101 fill, which is the right weight on
         chartreuse — no filter needed. */
    }

    .ent-award-num {
      font-size: clamp(2.75rem, 5vw, 4.5rem);
      font-weight: 900;
      line-height: 0.9;
      letter-spacing: -0.04em;
      color: var(--dark);
    }

    .ent-award-name {
      font-size: 0.9375rem;
      font-weight: 600;
      line-height: 1.3;
      color: rgba(0, 0, 0, 0.65);
    }

    @media (max-width: 760px) {
      .ent-awards-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 1.75rem 1.5rem;
      }
    }

    /* ====================================================================
       WORDPRESS-ONLY ADDITIONS — everything above this line is a verbatim
       copy of the static build's <style> block, so keep new rules below it
       and the copy above stays diffable against entertainment.html.
       ==================================================================== */

    /* The server-rendered galleries deliberately omit the base
       `.accordion-gallery` class, because initAccordion() overwrites the
       innerHTML of anything carrying it. These are the only two rules that
       class held; the real styling lives in the --stack / --scroll modifiers,
       which the template applies directly. See inc/gallery-render.php. */
    .rfn-gallery {
      padding-bottom: 2.5rem;
    }
    .rfn-gallery .keyart-ph-label {
      position: absolute;
      bottom: 0.85rem;
      left: 0.9rem;
      font-size: 0.7rem;
      font-weight: 700;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      color: rgba(255, 255, 255, 0.55);
    }
    @media (max-width: 640px) {
      .rfn-gallery { grid-template-columns: repeat(2, 1fr); }
    }

    /* Motion tiles. GALLERY-MAP.md §9b: every destination was an <img> grid and
       an MP4 in an <img> renders nothing, so the 12 transcoded assets had
       nowhere to go. A <video> matches .keyart-img's box exactly, so it drops
       into the same tile with no layout change. */
    .keyart-video {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
      background: #0d0d0d;
    }

    /* Small corner mark so a motion tile is identifiable before hover — without
       it a paused video is indistinguishable from a still. */
    .keyart-item--motion::after {
      content: "";
      position: absolute;
      top: 0.7rem;
      right: 0.7rem;
      width: 0;
      height: 0;
      border-left: 9px solid rgba(255, 255, 255, 0.9);
      border-top: 6px solid transparent;
      border-bottom: 6px solid transparent;
      filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6));
      opacity: 0.85;
      transition: opacity 0.25s ease;
      z-index: 2;
      pointer-events: none;
    }
    .keyart-item--motion:hover::after,
    .keyart-item--motion:focus-visible::after {
      opacity: 0;
    }

    /* The case strip is an <a> here, not the static build's <span> — it now has
       a real case study to link to. Reset the inherited link styling so it reads
       identically to the static version. */
    a.keyart-case-strip {
      text-decoration: none;
      z-index: 3;
    }

    /* Placeholder slots sitting in a scroll row need a tile-sized box, or they
       collapse to their text. Six of the twelve destinations were still on zero
       assets when this page was built, so this is the state most sections are
       actually in. */
    .accordion-gallery--scroll .rfn-slot {
      flex: 0 0 auto;
      height: clamp(210px, 24vw, 330px);
      aspect-ratio: 2 / 3;
    }
    .accordion-gallery--stack .rfn-slot {
      aspect-ratio: 2 / 3;
      width: 100%;
    }

    /* --------------------------------------------------------------------
       CASE STUDIES — the taster row above the capabilities accordion.
       Cards themselves are the shared `.blog-card` component; only the
       section's own furniture lives here. (2026-08-24)
       -------------------------------------------------------------------- */
    /* No max-width (2026-09-04, Michael / Claire: "the text is oddly justified.
       Why does it not extend across the full page? Can it?").

       It was capped at 580px, which in a 1440px container left 828px of empty
       line to its right and wrapped one 118-character sentence into two ragged
       ones. The container is the measure now — it caps at 1440px, so this is
       one line on a desktop and wraps naturally below that.

       The old cap was there to leave room for the "the story behind it" zesty
       snippet. Measured on the live page: that snippet sits on its OWN row
       below this paragraph (its top is 48px past this one's bottom), not beside
       it, so there was never a collision to protect against. */
    .ent-cases-intro {
      color: rgba(255, 255, 255, 0.6);
      margin: 1.25rem 0 3rem;
    }

    /* The "Read every case study" link reuses .accordion-explore, whose top
       margin is tuned for sitting inside an accordion panel. Out here the grid
       above it already supplies that space. */
    .ent-cases .accordion-explore {
      margin: 2.25rem 0 0;
    }

    /* ── EN-4: collapse control on the Case Studies section ─────────────────
       Borrows .accordion-icon and the 0fr -> 1fr panel from the capabilities
       accordion above, but NOT .accordion-item — see the note in the template
       for why. That means the icon's open-state rules have to be restated here
       against .ent-cases.is-open, because the originals are written against
       .accordion-item.is-open and this section is not one. */
    .ent-cases-heading {
      margin: 0;
    }

    /* A <button> inherits neither font nor colour, so the heading's type would
       silently drop to the UA default the moment it moved inside one. */
    .ent-cases-trigger {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 1.5rem;
      width: 100%;
      padding: 0;
      background: none;
      border: 0;
      cursor: pointer;
      text-align: left;
      font: inherit;
      letter-spacing: inherit;
      text-transform: inherit;
      color: inherit;
      transition: color var(--transition-fast);
    }

    .ent-cases-trigger:hover,
    .ent-cases-trigger:focus-visible {
      color: rgba(255, 255, 255, 0.6);
    }

    .ent-cases.is-open .accordion-icon {
      color: var(--chartreuse);
    }

    .ent-cases.is-open .accordion-icon::after {
      transform: translate(-50%, -50%) scaleY(0);
      opacity: 0;
    }

    .ent-cases-panel {
      display: grid;
      grid-template-rows: 0fr;
      transition: grid-template-rows var(--transition-med);
    }

    .ent-cases.is-open .ent-cases-panel {
      grid-template-rows: 1fr;
    }

    /* `hidden` on BOTH axes here, unlike the capabilities panels which need
       overflow-x visible for their full-bleed galleries. Nothing in this
       section breaks out of the container, and the zesty snippet inside it
       leans into the right margin — which is margin, not overflow. */
    .ent-cases-panel-inner {
      overflow: hidden;
      min-height: 0;
    }

    /* The intro's 1.25rem top margin was doing the job of separating it from
       the heading. The heading is now a flush-padded button, so the panel
       supplies that space instead and the margin would double it. */
    .ent-cases-panel-inner > .ent-cases-intro {
      margin-top: 1.5rem;
    }

    @media (prefers-reduced-motion: reduce) {
      .ent-cases-panel { transition: none; }
    }

    /* --------------------------------------------------------------------
       FULL-BLEED ACCORDION GALLERIES (2026-08-25, Kay)

       The galleries inside each accordion section now run edge to edge like
       the main portfolio, instead of sitting inside the panel's container.

       Same idiom the portfolio already uses (`.keyart-grid.width-full` in
       assets/styles.css): 100vw plus a negative margin of half the difference
       between the container and the viewport. `overflow-x: clip` on the
       section is not optional — 100vw counts the scrollbar, so without it the
       breakout adds a horizontal scrollbar of exactly the scrollbar's width.
       That is the same trap the portfolio's #gallery rule documents.

       Applied to the wrappers rather than the tiles so the scroll rows keep
       their own overflow behaviour.
       -------------------------------------------------------------------- */
    .work-section {
      overflow-x: clip;
    }

    /* ⚠️ REVERTED 2026-09-08 (Kay: "we're switching back to contained, not
       full width"). The breakout above is kept in place — commented, not
       deleted — because it is the documented idiom and this has now flipped
       twice; the next change is likelier to be back to full-bleed than to
       something new.

       .gallery-carousel is NOT in the revert. It is the lightbox's own
       carousel and was never part of the accordion layout question; it stays
       edge to edge.

       `overflow-x: clip` on .work-section stays too. It costs nothing with
       contained galleries and it is what stops a stray breakout anywhere in
       the section handing the page a horizontal scrollbar. */
    .gallery-carousel {
      width: 100vw;
      max-width: 100vw;
      margin-left: calc(50% - 50vw);
      margin-right: calc(50% - 50vw);
    }

    /* Contained: the galleries sit inside the accordion panel's own width,
       which is the container. No width or margin of their own — inheriting
       the panel's box IS "contained", and setting an explicit width here
       would just be a second opinion about what the container is. */
    .accordion-gallery--stack,
    .accordion-gallery--scroll {
      width: auto;
      max-width: 100%;
      margin-left: 0;
      margin-right: 0;
      padding-left: 0;
      padding-right: 0;
    }

    /* The links under a gallery belong to the panel's text column, not to the
       full-bleed row above them — pull them back inside the container. */
    .accordion-explore,
    .accordion-cta {
      position: relative;
      z-index: 1;
    }

    /* ── Motion tiles: the sound toggle (2026-09-04) ─────────────────────────
       Michael / Claire: "Videos should have sound. They currently do not.
       Should have a way to pause or mute."

       Sits where the ::after play triangle sits, and the two swap: the triangle
       says "this moves" on an idle tile, the button says "this can be heard" on
       the one under the pointer. Both in the same corner so nothing shifts.

       Only reachable on hover/focus, EXCEPT once sound is on — then it stays
       visible on every tile, because a control that turned something on has to
       remain available to turn it off. Keyboard focus shows it too, so it is
       not a pointer-only feature. */
    .keyart-sound {
      position: absolute;
      top: 0.55rem;
      right: 0.55rem;
      z-index: 4;
      display: grid;
      place-items: center;
      width: 1.9rem;
      height: 1.9rem;
      padding: 0;
      border: 0;
      border-radius: 50%;
      background: rgba(0, 0, 0, 0.55);
      backdrop-filter: blur(3px);
      cursor: pointer;
      opacity: 0;
      transition: opacity 0.25s ease, background 0.25s ease;
    }
    .keyart-item--motion:hover .keyart-sound,
    .keyart-item--motion:focus-within .keyart-sound,
    .keyart-sound:focus-visible,
    .keyart-sound.is-on {
      opacity: 1;
    }
    .keyart-sound:hover { background: rgba(0, 0, 0, 0.78); }

    /* The speaker: a CSS triangle for the cone, a square for the body, and one
       arc for the wave — drawn rather than shipped as an icon file so it
       inherits currentColor and needs no second asset. The wave is what the
       on/off state changes; the cone stays, so the control still reads as
       "sound" when it is off. */
    .keyart-sound-icon {
      position: relative;
      width: 0.85rem;
      height: 0.85rem;
      color: #fff;
    }
    .keyart-sound-icon::before {
      content: "";
      position: absolute;
      left: 0;
      top: 50%;
      transform: translateY(-50%);
      border-style: solid;
      border-width: 0.32rem 0.3rem 0.32rem 0;
      border-color: transparent currentColor transparent transparent;
    }
    .keyart-sound-icon::after {
      content: "";
      position: absolute;
      right: 0.02rem;
      top: 50%;
      width: 0.3rem;
      height: 0.3rem;
      transform: translateY(-50%) rotate(-45deg);
      border-top: 1.5px solid currentColor;
      border-right: 1.5px solid currentColor;
      border-radius: 0 0.22rem 0 0;
      opacity: 0;
      transition: opacity 0.2s ease;
    }
    .keyart-sound.is-on { background: var(--chartreuse); }
    .keyart-sound.is-on .keyart-sound-icon { color: var(--dark); }
    .keyart-sound.is-on .keyart-sound-icon::after { opacity: 1; }

    /* A tile showing its sound control does not also need the "this moves"
       triangle — they occupy the same corner. */
    .keyart-item--motion:hover::after,
    .keyart-item--motion:focus-within::after {
      opacity: 0;
    }

    @media (prefers-reduced-motion: reduce) {
      .keyart-sound,
      .keyart-sound-icon::after { transition: none; }
    }

/* ══════════════════════════════════════════════════════════════════════
   2026-09-08 — Kay's pass. Four changes, all overrides so the rules they
   modify stay diffable against the static build.
   ══════════════════════════════════════════════════════════════════════ */

/* 1. THE CLIENT STRIP IS A HEADER NOW, SO IT HAS TO BE THINNER.
   It moved above the reel, and at the shared 3rem the chartreuse read as a
   yellow masthead rather than a strip of logos. The band is cut to roughly a
   third and the logo track loses its own vertical padding with it. */
/* No nav clearance here any more — the strip sits below the reel again, so
   the reel owns it again since 2026-09-14. See the note on .ent-reel. */
.logos-section--slim {
  padding: 0.9rem 0;
}

.logos-section--slim .logos-label {
  display: none;
}

.logos-section--slim .logo-item {
  /* ROW height, not per-image height — this is the house mechanism (the same
     one the ≤768px block in style.css uses) and the reason matters: each logo
     carries its own inline height, optically compensated in
     assets/logos/build-logos.py and scaled 1.5x in the markup. Capping the
     images at some absolute px would clamp the tall ones and leave the short
     ones alone, which is exactly the compensation being thrown away. Moving
     the row and letting the images cap to it keeps every ratio intact. */
  height: 52px;
}

.logos-section--slim .logo-item img {
  max-height: 100%;
  width: auto;
}

/* Mobile: ~40% smaller (Kay, 2026-09-08 — "too big"). Again the ROW is what
   moves, so every logo scales together and build-logos.py's compensation
   survives. 52px -> 31px is a 40% cut; the track gap comes down with it or
   the logos end up marooned in space that no longer suits them.

   ⚠️ This has to outrank the ≤768px block in style.css, which sets
   .logo-item { height: 46px } for the strip in its old position. Same
   breakpoint, and style.css loads AFTER this sheet — so the extra class in
   .logos-section--slim .logo-item is doing real work here, not decoration. */
@media (max-width: 768px) {
  .logos-section--slim .logo-item {
    height: 31px;
  }

  .logos-section--slim .logos-track {
    gap: 1.75rem;
  }
}

/* 2. ACCORDION SECTION HEROES: NO BACKGROUND IMAGE, TEXT FULL WIDTH.
   The banner treatment stacked two gradients over a 2200x1000 photo and then
   squeezed the copy into 46% of the box so it stayed off the art. With the
   art gone (Kay: "remove background image, make text full container width")
   both the scrim and the 46% cap are pointless, and the 420px min-height is
   just a tall empty box. */
.accordion-text,
.accordion-text--right {
  background-image: none;
  background-color: rgba(255, 255, 255, 0.03);
  min-height: 0;
  padding: 2rem 2.25rem;
  align-items: flex-start;
}

.accordion-text > * {
  max-width: 100%;
}

/* 2b. THE INTRO LIVES INSIDE "WHAT WE DO" (2026-09-18). Kay: "move the text
   intro field (like the 'key art is where a campaign is won or lost' section)
   inside the collapsed What We Do dropdown, above the bullet points. Same on
   all of those accordions." An open section now goes header -> What We Do
   toggle -> gallery, and the copy only appears with the list it introduces.
   The markup moved in page-entertainment.php; this rule only closes the gap
   the block used to leave above itself, since the toggle's own bottom margin
   now does that job. The max-height animation is unaffected: initAccordion()
   measures scrollHeight at click time, so the intro is counted. */
.accordion-list-panel-inner > .accordion-text {
  margin-top: 0.25rem;
}

/* 3. INNER GALLERIES: JUSTIFIED ROWS, CONTAINED, NO HORIZONTAL SCROLL.
   Every section used to render `layout => scroll` — a flex row with
   overflow-x:auto and hidden scrollbars, so work ran off the right edge with
   nothing saying so. That became a fixed 5-up grid at 2:3 (0.37.0), which
   fixed the scroll and introduced a worse fault: it CROPPED EVERYTHING TO KEY
   ART'S SHAPE. Not everything here is key art. A 10:1 leaderboard in a 2:3 box
   shows 7% of itself.

   ⚠️ This is the standing rule, not a new preference — "KEY ART IS NEVER
   CROPPED … pieces do not share a ratio and that is fine" (Kay, 2026-09-02).
   The fixed grid broke it; this restores it.

   THE MECHANISM IS THE PORTFOLIO'S, NOT A NEW ONE. `.keyart-grid.is-justified`
   in portfolio.css solves exactly this and carries two hard-won fixes in its
   comments — the ×100 on flex-grow, and aspect-ratio rather than a fixed
   height. Read that file before touching any number here. The rules are
   repeated rather than shared because the two sheets are enqueued on different
   pages and each is kept self-contained, the same arrangement
   `.accordion-explore` has.

   `--ar` is already on every tile: refinery_gallery_tile() emits it from the
   attachment's real dimensions, so nothing in the templates changes.

   ⚠️ THE `limit => 15` IN page-entertainment.php NO LONGER MEANS THREE ROWS.
   It caps PRODUCTIONS. With uniform 2:3 tiles five per row made that exactly
   three; with mixed ratios a row holds as many as fit, so 15 lands at roughly
   two to four rows depending on what is in the section. The cap is still doing
   its job — keeping a section from running for screens — it just cannot
   promise a row count any more. */
.accordion-gallery--stack,
.accordion-gallery--scroll {
  --row-h: clamp(150px, 17vw, 260px);

  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 0;
  padding: 0.5rem 0 0;
  overflow-x: visible;
  scroll-snap-type: none;
}

.accordion-gallery--stack .keyart-item,
.accordion-gallery--scroll .keyart-item {
  /* Height from the RATIO, never fixed — a fixed height makes the box wider
     than the image whenever a row has leftover space, and cover trims the top
     and bottom. See the long note in portfolio.css. */
  aspect-ratio: var(--ar, 0.667);
  height: auto;

  /* ×100 is load-bearing: flex-grow factors summing to under 1 on a line leave
     the remainder as a gap, and a lone portrait tile sums to 0.667. Multiplying
     every factor by the same constant changes no proportion. */
  flex-grow: calc(var(--ar, 0.667) * 100);
  flex-shrink: 1;
  flex-basis: calc(var(--ar, 0.667) * var(--row-h));
  min-width: 0;
}

/* Soaks up the last row's leftover space so three tiles on a final line do not
   stretch to triple size. Zero height, so no visual footprint. */
.accordion-gallery--stack::after,
.accordion-gallery--scroll::after {
  content: "";
  flex-grow: 1000000;
  flex-basis: 0;
  height: 0;
}

/* `contain`, not `cover`: the tile's ratio now matches the image's, so they are
   identical in the normal case. They diverge only when --ar is missing or
   wrong — cover would silently crop those, contain letterboxes them. */
.accordion-gallery--stack .keyart-item img,
.accordion-gallery--stack .keyart-item video,
.accordion-gallery--scroll .keyart-item img,
.accordion-gallery--scroll .keyart-item video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* 4. The portfolio CTA that replaced the hero buttons. Heading removed
   2026-09-08; the button is centred and is now the whole section.
   text-align on the container rather than margin:auto on the button, because
   .btn is inline-flex — auto margins do nothing to it without also making it
   a block, which would stretch it to the full container width. */
.ent-portfolio-cta .container {
  text-align: center;
}

/* Shorter button copy on a phone (Kay, 2026-09-11: "update the button text on
   the accordion items so they fit on one line"). Two spans in the markup, one
   shown per breakpoint — CSS cannot rewrite text, and a pill that wraps onto
   two lines on a 390px screen is a lozenge, not a button. Desktop copy is
   unchanged. */
.ae-copy--short { display: none; }
@media (max-width: 768px) {
  .ae-copy--long  { display: none; }
  .ae-copy--short { display: inline; }

  /* Adam, 2026-09-11: "More stories from brief to launch" still wrapped on
     his phone. Tighter tracking, a touch less size and side padding, and no
     wrapping — the pill is a single line or it is not a pill. Phones only. */
  .accordion-explore {
    letter-spacing: -0.035em;
    font-size: 1.0625rem;
    padding-left: 1.25rem;
    padding-right: 1.25rem;
    white-space: nowrap;
  }
}

/* The closing button reuses .accordion-explore (2026-09-11) so it matches the
   five section buttons above it. Its own margins are tuned for sitting inside
   an accordion panel; out here the section's padding is the spacing, and
   `inline-flex` centres under the container's text-align. */
.ent-portfolio-cta .accordion-explore {
  margin: 0;
}

/* .is-row-trimmed is gone (2026-09-09). Hiding a trailing partial row was the
   first answer to "end on a complete row"; entertainment.js now nudges
   --row-h until the last line fills instead, so nothing is hidden.

   Set by that same code when the last line came out nearly full: dropping the
   spacer's grow lets flexbox stretch that line to the edge like any other.
   The spacer itself stays in the stylesheet — it is still what stops a badly
   short last line from blowing up, and it still applies whenever this class
   is absent. */
.accordion-gallery--stack.is-last-row-full::after,
.accordion-gallery--scroll.is-last-row-full::after {
  flex-grow: 0;
}

/* Tiles past the fourth row, when the gallery has more work than it shows.
   The template fetches a surplus on purpose and entertainment.js decides how
   much of it fits — see the note there.

   `display: none` rather than visibility: the tile has to leave the flex line
   entirely, and it also stops the browser fetching the image, which is what
   makes over-fetching cheap. */
.keyart-item.is-row-overflow {
  display: none;
}

/* ── Mobile spacing (Kay, 2026-09-09) ─────────────────────────────────────
   Two complaints, both about dead vertical space on a phone where it costs a
   third of a screen rather than a tenth. */
@media (max-width: 768px) {
  /* 1. "Remove the gap above the Entertainment button at the bottom."
        .section--tight is still 3rem, and the accordion above it already ends
        on its own padding plus the explore button's 2.5rem bottom margin — so
        three spacings stacked into one gap with nothing in it. The button is
        the only thing in this section, so it does not need a band of its own
        on top of the one it is sitting in. */
  .ent-portfolio-cta.section--tight {
    padding-top: 0;
  }

  /* 2. "Tighten header text spacing above and below copy." The hero is
        centred type on a phone and was carrying desktop padding at both ends;
        with no artwork beside it the air reads as the page not having
        started. Roughly halved. */
  .ent-hero-intro {
    padding: 2.25rem 0 1.75rem;
  }

  .ent-hero-intro .t-body-lg {
    margin-top: 0.75rem;
  }
}
