/* =============================================================================
   inner-pages.css — Granth 2026 re-theme, inner pages
   -----------------------------------------------------------------------------
   Loaded on every page EXCEPT the front page (see header.php). Companion to
   css/main.css, which stays the homepage + service-page file.

   Same rule as main.css: if it can be a Tailwind utility it lives in the markup.
   What is here is what cannot be — the header inset, drawn decoration on
   ::before/::after, @keyframes, and state the script toggles on an ancestor.

     §1  inr-   shared inner-page primitives (hero, eyebrow, breadcrumb, CTA)
     §2  abt-   the About page only
     §3  bb-     Customize Your Brand — the sticky bar and the chip enter
     §4  cs26-  the Case Studies listing — the wall banner and the spotlight

   Every ported page except About adds nothing here — everything they need is a
   §1 primitive or a Tailwind utility in the markup, which is the target for a
   page, not an accident. Add a §n only when a page genuinely needs drawn
   decoration, @keyframes, or a state the script toggles.

   The Gravity Forms skin is NOT here. It applies to every form on the site,
   including any on the front page, and this file does not load there — so it
   lives at the end of main.css instead.

   Layer note: main.css fixes the order with `@layer theme, base, components,
   utilities;`. Everything below sits in `components` so Tailwind utilities in
   the markup still win, exactly like main.css §4-§8.
   ========================================================================== */

/* =============================================================================
   §1  SHARED INNER-PAGE PRIMITIVES
   ========================================================================== */

@layer components {
  /* --- the hero inset -------------------------------------------------------
     js/main.js puts .nhome-scroll at `position: fixed; top: 0` on desktop
     pointers, so an inner page begins *underneath* the bar. The homepage can
     use a flat 78px because its banner is cream either way; a dark hero has to
     clear the bar exactly or its top slides behind it.

     initHeaderInset() guards only on `header` existing, so it runs here too and
     writes --ctx-header-inset (0 when .nhome-scroll is not fixed). Same
     mechanism .ctx-hero uses — do not hard-code a height, the bar changes by
     ~60px depending on whether Brand Bucket wraps above the WhatsApp button. */
  .inr-hero {
    margin-top: var(--ctx-header-inset, var(--nhome-header-h));
  }

  /* The scrim. A single dark image behind display type fails contrast at the
     bottom edge where the copy sits, so the panel carries its own gradient
     rather than relying on the photograph being dark in the right places. */
  .inr-hero-panel {
    position: relative;
    isolation: isolate;
    overflow: hidden;
  }

  .inr-hero-panel::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(
      180deg,
      rgba(24, 23, 24, 0.15) 0%,
      rgba(24, 23, 24, 0.35) 45%,
      rgba(24, 23, 24, 0.82) 100%
    );
    pointer-events: none;
  }

  .inr-hero-panel > * {
    position: relative;
    z-index: 2;
  }

  /* --- the eyebrow ----------------------------------------------------------
     Small tan label with a rule running off each side. The rules are drawn
     rather than marked up so the label can be any length. */
  .inr-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 12px;
  }

  .inr-eyebrow::before,
  .inr-eyebrow::after {
    content: "";
    display: block;
    width: 28px;
    height: 1px;
    background: currentColor;
    opacity: 0.45;
  }

  /* --- breadcrumb separator ------------------------------------------------ */
  .inr-crumb > li + li::before {
    content: "";
    display: inline-block;
    width: 5px;
    height: 5px;
    margin: 0 10px 2px;
    border-radius: 50%;
    background: currentColor;
    opacity: 0.5;
  }

  /* --- the closing CTA panel ------------------------------------------------
     template-parts/cta-new.php laid white display type straight over a
     photograph. The photograph is light through its middle, which is exactly
     where the heading sits, so the panel carries its own scrim rather than
     trusting the picture to be dark in the right places.

     Same mechanism as .inr-hero-panel above, but weighted at the centre
     because this copy is centred, not bottom-set. Shared rather than
     per-page: cta-new.php was on the bottom of most old templates, so every
     port needs this. */
  .inr-cta-panel {
    position: relative;
    isolation: isolate;
    overflow: hidden;
  }

  .inr-cta-panel::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: radial-gradient(
      ellipse at 50% 50%,
      rgba(24, 23, 24, 0.86) 0%,
      rgba(24, 23, 24, 0.66) 58%,
      rgba(24, 23, 24, 0.5) 100%
    );
    pointer-events: none;
  }

  .inr-cta-panel > * {
    position: relative;
    z-index: 2;
  }
}

/* =============================================================================
   §2  ABOUT PAGE
   ========================================================================== */

@layer components {
  /* --- the hero scrim -------------------------------------------------------
     §1's .inr-hero-panel::after darkens top-to-bottom for a title that sits
     along the foot of the panel. The About copy is a left-hand column beside
     the mascot, so this scrim is weighted left-to-right and only lightly at
     the foot, which leaves the artwork on the right at full strength. Under
     992px the copy runs across the artwork (the panel is too narrow for the
     two to share it), so the bottom-weighted scrim comes back, heavier than
     §1's, for every width below lg. */
  .abt-hero .inr-hero-panel::after {
    background:
      linear-gradient(90deg, rgba(24, 23, 24, 0.84) 0%, rgba(24, 23, 24, 0.55) 38%, rgba(24, 23, 24, 0) 66%),
      linear-gradient(180deg, rgba(24, 23, 24, 0) 50%, rgba(24, 23, 24, 0.45) 100%);
  }

  @media (max-width: 991px) {
    .abt-hero .inr-hero-panel::after {
      background: linear-gradient(180deg, rgba(24, 23, 24, 0.25) 0%, rgba(24, 23, 24, 0.4) 30%, rgba(24, 23, 24, 0.92) 100%);
    }
  }

  /* --- the four-step flow ---------------------------------------------------
     Envision > Establish > Execute > Echo is a loop, not a list, so each card
     carries its step number as drawn decoration and every card but the last
     grows a connector on large screens. Numbering from the DOM keeps it correct
     if a step is added in ACF. */
  .abt-flow-grid {
    counter-reset: abt-step;
  }

  .abt-flow-card {
    counter-increment: abt-step;
    position: relative;
  }

  .abt-flow-card::before {
    content: counter(abt-step, decimal-leading-zero);
    position: absolute;
    top: 18px;
    right: 20px;
    font-family: var(--font-display), sans-serif;
    font-size: 14px;
    font-weight: 700;
    line-height: 1;
    color: var(--color-tan);
    opacity: 0.45;
  }

  /* The connector. Sits in the gutter between cards, so it is drawn on the card
     rather than added to the markup — and dropped in one column where there is
     no gutter to draw it in. */
  @media (width >= 992px) {
    .abt-flow-card:not(:last-child)::after {
      content: "";
      position: absolute;
      top: 50%;
      left: 100%;
      width: 24px;
      height: 1px;
      background: linear-gradient(
        90deg,
        var(--color-tan) 0%,
        rgba(178, 137, 111, 0) 100%
      );
      transform: translateY(-50%);
      pointer-events: none;
    }
  }

  /* --- the journey rail -----------------------------------------------------
     A timeline: one dashed rule with a dot per stat sitting on it.

     This was an SVG curve stretched behind the grid, which could never work —
     the dots are on a flat baseline, so a wave crossed the numbers instead of
     passing through them. A straight rule at the dots' own centre line is
     correct by construction, with no alignment maths to drift.

     Inset 10% each side because five equal columns put the outer dot centres at
     10% and 90%; the line should start and end on a dot, not run off the edge.
     Hidden below 992px, where the stats stack two-up and there is no rail. */
  .abt-journey-rail {
    position: relative;
  }

  @media (width >= 992px) {
    .abt-journey-rail::before {
      content: "";
      position: absolute;
      z-index: 0;
      top: 5px;
      left: 10%;
      right: 10%;
      border-top: 1px dashed rgba(178, 137, 111, 0.55);
      pointer-events: none;
    }
  }

  /* Stats paint above the rule so each dot masks it rather than being crossed. */
  .abt-journey-dot {
    position: relative;
    z-index: 1;
  }

  .abt-journey-dot::before {
    content: "";
    display: block;
    width: 11px;
    height: 11px;
    margin: 0 auto 14px;
    border-radius: 50%;
    background: var(--color-brand);
    border: 2px solid var(--color-cream);
    box-shadow: 0 0 0 3px rgba(178, 137, 111, 0.35);
  }

  /* --- the lens gallery -----------------------------------------------------
     Year filter. .is-active is toggled by the inline script on the page, so the
     lit state cannot be a utility on the markup. */
  .abt-lens-year {
    transition:
      color 250ms ease,
      background-color 250ms ease,
      border-color 250ms ease;
  }

  .abt-lens-year.is-active {
    background: var(--color-brand);
    border-color: var(--color-brand);
    color: #fff;
  }

  /* A trip the current year does not include. Hidden rather than removed so the
     filter is reversible without re-rendering. */
  .abt-lens-card[hidden] {
    display: none;
  }

  /* The caption plate. A gradient over the photograph, so it is drawn. */
  .abt-lens-card figcaption {
    background: linear-gradient(
      180deg,
      rgba(24, 23, 24, 0) 0%,
      rgba(24, 23, 24, 0.78) 62%,
      rgba(24, 23, 24, 0.92) 100%
    );
  }

  /* --- press + awards -------------------------------------------------------
     Logos are supplied by many different owners at many different weights, so
     they are levelled to greyscale at rest and come up to full colour on hover.
     Below 992px there is no hover, so they stay at full strength. */
  @media (width >= 992px) {
    .abt-logo {
      filter: grayscale(1);
      opacity: 0.55;
      transition:
        filter 300ms ease,
        opacity 300ms ease;
    }

    .abt-logo:hover,
    .abt-logo:focus-visible {
      filter: grayscale(0);
      opacity: 1;
    }
  }

  /* --- closing panel --------------------------------------------------------
     The grid wash behind the closing CTA. Drawn, and kept behind the copy. */
  .abt-close-panel {
    position: relative;
    isolation: isolate;
    overflow: hidden;
  }

  .abt-close-panel::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background-image:
      linear-gradient(rgba(178, 137, 111, 0.14) 1px, transparent 1px),
      linear-gradient(90deg, rgba(178, 137, 111, 0.14) 1px, transparent 1px);
    background-size: 64px 64px;
    mask-image: radial-gradient(
      ellipse at 50% 50%,
      #000 0%,
      transparent 78%
    );
    pointer-events: none;
  }

  .abt-close-panel > * {
    position: relative;
    z-index: 1;
  }
}

/* =============================================================================
   Reduced motion. The reveal classes are handled in main.css; this covers the
   transitions introduced above.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .abt-lens-year,
  .abt-logo {
    transition: none;
  }
}

/* =============================================================================
   §3  CUSTOMIZE YOUR BRAND  (bb-)
   -----------------------------------------------------------------------------
   Only the two things a Tailwind utility cannot express, because the script
   toggles them: the sticky bar's off-screen resting transform, and the chip
   enter state (the chips are created in JS, so there is no markup to put a
   starting class on).

   Everything else on that page is a §1 `inr-` primitive or a utility in
   templates/new-brand-bucket-one.php, which is the target for a ported page.
   ========================================================================== */

@layer components {

  /* The bar sits below the fold until the first pick. `inert` (toggled with
     .is-up in the template's script) is what keeps its link out of the tab
     order while it is parked, so it never needs `display: none` and can
     therefore transition. */
  .bb-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    transform: translateY(120%);
    transition: transform 260ms cubic-bezier(0.23, 1, 0.32, 1);
  }

  .bb-bar.is-up {
    transform: translateY(0);
  }

  /* Chips enter from slightly below, never from scale(0): nothing in the real
     world appears out of nothing. The attribute is set at create time and
     removed two frames later, so the transition has a start value to run from. */
  .bb-chip {
    transition:
      opacity 220ms cubic-bezier(0.23, 1, 0.32, 1),
      transform 220ms cubic-bezier(0.23, 1, 0.32, 1),
      color 200ms ease,
      border-color 200ms ease;
  }

  .bb-chip[data-enter] {
    opacity: 0;
    transform: translateY(6px);
  }

  @media (prefers-reduced-motion: reduce) {
    .bb-bar,
    .bb-chip {
      transition: none;
    }

    .bb-chip[data-enter] {
      opacity: 1;
      transform: none;
    }
  }
}

/* =============================================================================
   §4  CASE STUDIES LISTING  (cs26-)
   -----------------------------------------------------------------------------
   Port of two options from assets-2/granth-case-study-options/:

     14-counter-columns.html  ->  .cs26-wall    the banner
     04-spotlight-switcher.html -> .cs26-spot   the section under it

   Only what cannot be a Tailwind utility is here: the drawn scrims, the
   ::after hover plates, the state the two scripts toggle, and the transforms
   they write. Everything else is utilities in templates/new-case-studies-listing.php.

   THE PIN IS NOT `position: sticky`.
   ------------------------------------
   js/main.js turns .nhome-scroll into `position: fixed` + `transform` on
   desktop pointers (initSmoothScroll), and a sticky descendant of a fixed,
   transformed wrapper has no scrollport to stick to — it would simply never
   pin. .cs26-wall is therefore a plain tall track and initCaseWall() counter-
   translates .cs26-wall-stage inside it, the same mechanism .ctx-hero uses.
   The result is identical in both scroll modes, so there is one code path.

   Palette note: the options folder's base.css was extracted from the same
   Figma file as the theme, so --paper / --red / --tan are already
   --color-cream / --color-brand / --color-tan. Only the option's --coral
   (#F0484E) had no theme token; it resolves to --color-brand here rather than
   introducing a second red.
   ========================================================================== */

@layer components {

  /* ===========================================================================
     §4.1  THE WALL — four columns drifting behind a centre plate
     ======================================================================== */

  .cs26-wall {
    /* Clears the bar the same way .inr-hero and .ctx-hero do. Never hard-code
       a height: the header grows ~60px when Brand Bucket wraps. */
    margin-top: var(--ctx-header-inset, var(--nhome-header-h));

    position: relative;
    height: 230vh;
    background: #0b0807;

    --cs26-gap: 16px;
    --cs26-shot: 38vh;
  }

  .cs26-wall-stage {
    position: relative;
    height: calc(100vh - var(--ctx-header-inset, var(--nhome-header-h)));
    height: calc(100svh - var(--ctx-header-inset, var(--nhome-header-h)));
    overflow: hidden;
  }

  .cs26-wall.is-panning .cs26-wall-stage {
    will-change: transform;
  }

  .cs26-cols {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--cs26-gap);
    padding: var(--cs26-gap);
  }

  .cs26-col {
    display: flex;
    flex-direction: column;
    gap: var(--cs26-gap);
  }

  .cs26-wall.is-panning .cs26-col {
    will-change: transform;
  }

  .cs26-shot {
    position: relative;
    flex: 0 0 auto;
    height: var(--cs26-shot);
    border-radius: 16px;
    overflow: hidden;
    background: #1a1412;
    display: block;
  }

  .cs26-shot img {
    width: 100%;
    max-width: none;
    height: 100%;
    object-fit: cover;
    transition: transform 1s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .cs26-shot:hover img {
    transform: scale(1.05);
  }

  /* Drawn, not marked up: the label needs a floor to sit on and the images
     range from a dark film still to a near-white illustration. */
  .cs26-shot::after {
    content: "";
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 0.45s;
    background: linear-gradient(0deg, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0) 52%);
  }

  .cs26-shot:hover::after,
  .cs26-shot:focus-visible::after {
    opacity: 1;
  }

  .cs26-shot-label {
    position: absolute;
    left: 10px;
    right: 10px;
    bottom: 10px;
    z-index: 2;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.4s, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .cs26-shot:hover .cs26-shot-label,
  .cs26-shot:focus-visible .cs26-shot-label {
    opacity: 1;
    transform: none;
  }

  /* The centre plate. A flat overlay greys the whole wall; the ellipse keeps
     the frames bright at the edges and only buries them behind the copy.

     The stops are held opaque further out than the option file's, which
     assumed a dark set of images. Granth's case-study thumbnails are mostly
     bright — pale product shots, white UI, an illustrated burger — and at the
     option's 0.62 the copy's outer corners sat on legible artwork. */
  .cs26-plate {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: grid;
    place-items: center;
    pointer-events: none;
    background: radial-gradient(
      ellipse 78% 66% at 50% 50%,
      rgba(11, 8, 7, 0.97) 0%,
      rgba(11, 8, 7, 0.95) 46%,
      rgba(11, 8, 7, 0.72) 74%,
      rgba(11, 8, 7, 0.34) 100%
    );
  }

  .cs26-plate > * {
    pointer-events: auto;
  }

  /* ---------------------------------------------------------------------------
     The index under the wall. The hover plate is inset past the row on both
     sides, which only a ::before can do without changing the grid.
     ------------------------------------------------------------------------ */
  .cs26-row {
    position: relative;
    display: grid;
    grid-template-columns: 52px minmax(0, 1.3fr) minmax(0, 1fr) 92px 46px;
    align-items: center;
    gap: 22px;
    padding: 19px 6px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  }

  .cs26-row:first-of-type {
    border-top: 1px solid rgba(0, 0, 0, 0.08);
  }

  .cs26-row::before {
    content: "";
    position: absolute;
    left: -14px;
    right: -14px;
    inset-block: 0;
    z-index: -1;
    border-radius: 14px;
    background: rgba(236, 28, 36, 0.1);
    opacity: 0;
    transition: opacity 0.4s;
  }

  .cs26-row:hover::before,
  .cs26-row:focus-visible::before {
    opacity: 1;
  }

  /* ---------------------------------------------------------------------------
     Responsive ladder. Four columns is the design; each step drops the
     rightmost column rather than squeezing all four to an unreadable width.
     initCaseWall() re-measures on these same widths.
     ------------------------------------------------------------------------ */
  @media (max-width: 1180px) {
    .cs26-cols {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .cs26-col[data-col="4"] {
      display: none;
    }

    /* Fewer, wider columns put brighter frames closer to the copy. */
    .cs26-plate {
      background: radial-gradient(
        ellipse 104% 72% at 50% 50%,
        rgba(11, 8, 7, 0.97) 0%,
        rgba(11, 8, 7, 0.95) 50%,
        rgba(11, 8, 7, 0.8) 78%,
        rgba(11, 8, 7, 0.42) 100%
      );
    }
  }

  @media (max-width: 860px) {
    .cs26-wall {
      height: 215vh;
      --cs26-gap: 12px;
      --cs26-shot: 32vh;
    }

    .cs26-cols {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .cs26-col[data-col="3"] {
      display: none;
    }

    .cs26-shot {
      border-radius: 14px;
    }

    .cs26-row {
      grid-template-columns: 38px minmax(0, 1fr) 40px;
      gap: 14px;
    }
  }

  @media (max-width: 520px) {
    .cs26-wall {
      height: 200vh;
      --cs26-gap: 10px;
      --cs26-shot: 26vh;
    }

    /* The plate is taller than it is wide on a phone — the ellipse follows. */
    .cs26-plate {
      background: radial-gradient(
        ellipse 118% 78% at 50% 50%,
        rgba(11, 8, 7, 0.98) 0%,
        rgba(11, 8, 7, 0.96) 52%,
        rgba(11, 8, 7, 0.84) 80%,
        rgba(11, 8, 7, 0.5) 100%
      );
    }
  }

  /* Short landscape viewports: keep the plate from crowding the wall. */
  @media (max-height: 560px) {
    .cs26-wall {
      --cs26-shot: 44vh;
    }
  }

  /* No pin, no drift: the wall becomes a short static grid. */
  @media (prefers-reduced-motion: reduce) {
    .cs26-wall {
      height: auto;
    }

    .cs26-wall-stage {
      height: auto;
      transform: none !important;
    }

    .cs26-cols {
      position: static;
      height: auto;
    }

    .cs26-col {
      transform: none !important;
    }

    .cs26-col .cs26-shot:nth-child(n + 3) {
      display: none;
    }

    .cs26-plate {
      position: static;
      background: #0b0807;
      padding-block: clamp(50px, 8vw, 80px);
    }
  }

  /* ===========================================================================
     §4.2  THE SPOTLIGHT — one case study at a time on a dark stage
     -----------------------------------------------------------------------
     Every panel, shot and card is printed by PHP and only switched here, so
     all eight case studies are in the HTML for a crawler and for a reader with
     no JavaScript (who gets the first one, fully formed).
     ======================================================================== */

  .cs26-spot {
    position: relative;
    width: 100%;
    background: #120e0c;
    border-radius: 28px;
    overflow: hidden;
    isolation: isolate;
    height: clamp(600px, 80vh, 780px);
  }

  .cs26-spot-shot {
    position: absolute;
    inset: 0;
    opacity: 0;
    transform: scale(1.08);
    transition: opacity 0.9s cubic-bezier(0.22, 1, 0.36, 1),
      transform 2.4s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .cs26-spot-shot.is-on {
    opacity: 1;
    transform: scale(1);
  }

  .cs26-spot-shot img {
    width: 100%;
    max-width: none;
    height: 100%;
    object-fit: cover;
  }

  /* Two gradients: one across for the client index, one up for the copy.
     Both are deeper than the option file's — same reason as the wall's plate,
     the real thumbnails are far brighter than the ones it was drawn against,
     and the description ran across a lit photograph at the option's values. */
  .cs26-spot-wash {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(
        90deg,
        rgba(10, 7, 6, 0.95) 0%,
        rgba(10, 7, 6, 0.84) 32%,
        rgba(10, 7, 6, 0.4) 66%,
        rgba(10, 7, 6, 0.6) 100%
      ),
      linear-gradient(
        0deg,
        rgba(10, 7, 6, 0.95) 0%,
        rgba(10, 7, 6, 0.82) 34%,
        rgba(10, 7, 6, 0) 68%
      );
  }

  .cs26-spot-glow {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    opacity: 0.5;
    background: radial-gradient(circle at 78% 22%, rgba(236, 28, 36, 0.2), transparent 46%);
  }

  /* The stage's two columns. `display` is HERE and not a `grid` utility in the
     markup on purpose: §4.3 has to switch this off below 1024px, and a
     utility in @layer utilities beats any rule in @layer components whatever
     its specificity or media query — the layer would simply never hide and
     the desktop tab strip would stack on top of the phone carousel. Every
     other value on this element is still a utility. */
  .cs26-spot-layer {
    display: grid;
  }

  /* --- the vertical client index ------------------------------------------ */
  .cs26-spot-list button {
    all: unset;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 0;
    font-family: var(--font-display);
    font-weight: 900;
    letter-spacing: -0.02em;
    font-size: clamp(15px, 1.35vw, 19px);
    color: rgba(255, 255, 255, 0.32);
    transition: color 0.35s, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .cs26-spot-list button:hover {
    color: rgba(255, 255, 255, 0.7);
    transform: translateX(5px);
  }

  .cs26-spot-list button:focus-visible {
    outline: 2px solid var(--color-brand);
    outline-offset: 3px;
    border-radius: 6px;
  }

  .cs26-spot-list button i {
    width: 0;
    height: 2px;
    flex: 0 0 auto;
    background: var(--color-brand);
    border-radius: 2px;
    transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .cs26-spot-list button[aria-selected="true"] {
    color: #fff;
    transform: translateX(5px);
  }

  .cs26-spot-list button[aria-selected="true"] i {
    width: 22px;
  }

  /* --- the copy panels ------------------------------------------------------
     All eight are stacked; the lit one is the only one in flow for the reader.
     `visibility` rather than `display` so the fade has something to fade. */
  .cs26-spot-panel {
    position: absolute;
    inset: auto 0 0 0;
    opacity: 0;
    visibility: hidden;
    transform: translateY(14px);
    transition: opacity 0.34s ease, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1),
      visibility 0s linear 0.34s;
  }

  .cs26-spot-panel.is-on {
    position: relative;
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity 0.34s ease 0.13s, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.13s,
      visibility 0s;
  }

  /* The oversized outline numeral. -webkit-text-stroke has no utility. */
  .cs26-spot-ghost {
    position: absolute;
    right: 0;
    top: -6px;
    font-weight: 900;
    line-height: 0.8;
    letter-spacing: -0.06em;
    font-size: clamp(110px, 17vw, 240px);
    color: transparent;
    -webkit-text-stroke: 1.5px rgba(255, 255, 255, 0.16);
    pointer-events: none;
    user-select: none;
	  display: none !important;
  }

  /* --- the progress rail --------------------------------------------------- */
  .cs26-spot-rail {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    display: flex;
    gap: 4px;
    padding: 0 clamp(24px, 3.2vw, 52px) 18px;
  }

  .cs26-spot-rail i {
    flex: 1;
    height: 3px;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.16);
    overflow: hidden;
  }

  .cs26-spot-rail i b {
    display: block;
    height: 100%;
    width: 0;
    background: var(--color-brand);
    border-radius: 3px;
  }

  .cs26-spot-rail i.is-done b {
    width: 100%;
  }

  .cs26-spot-rail i.is-live b {
    width: 100%;
    transition: width var(--cs26-dur, 6500ms) linear;
  }

  .cs26-spot-rail i.is-live.is-held b {
    transition: none;
  }

  /* ===========================================================================
     §4.3  THE SPOTLIGHT ON SMALL SCREENS
     -----------------------------------------------------------------------
     The vertical index and the full-bleed stage give way to a peeking-card
     slider. The card is split — image on top, solid plate under it — because
     these images run from a dark film still to a near-white illustration and
     text over a gradient only reads on half of them.
     ======================================================================== */

  .cs26-mcar {
    display: none;
  }

  @media (max-width: 1024px) {
    /* Edge to edge so the neighbour cards clip on the viewport, not a box. */
    .cs26-spot {
      height: auto;
      border-radius: 0;
      width: 100vw;
      margin-inline: calc(50% - 50vw);
    }

    .cs26-spot-shot,
    .cs26-spot-glow {
      display: none;
    }

    .cs26-spot-wash {
      background: linear-gradient(180deg, #171312 0%, #0b0807 58%);
    }

    .cs26-spot-layer {
      display: none;
    }

    .cs26-mcar {
      display: block;
      position: relative;
      z-index: 3;
      padding-top: 20px;
    }

    .cs26-mstage {
      position: relative;
      touch-action: pan-y;
    }

    /* An in-flow, invisible box gives the absolutely-placed cards their height. */
    .cs26-msizer {
      width: calc(100% - 56px);
      margin-inline: auto;
      aspect-ratio: 3 / 4;
      max-height: 66svh;
      visibility: hidden;
    }

    .cs26-mcard {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 50%;
      width: calc(100% - 56px);
      border-radius: 18px;
      overflow: hidden;
      background: #141010;
      transform-origin: 50% 50%;
      display: flex;
      flex-direction: column;
      box-shadow: 0 20px 48px rgba(0, 0, 0, 0.5);
      transition: transform 0.55s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s ease;
      will-change: transform;
    }

    .cs26-mstage.is-dragging .cs26-mcard {
      transition: none;
    }

    .cs26-mcard .cs26-mpic {
      position: relative;
      flex: 1 1 auto;
      min-height: 0;
      overflow: hidden;
      background: #1a1412;
    }

    .cs26-mcard .cs26-mpic img {
      position: absolute;
      inset: 0;
      width: 100%;
      max-width: none;
      height: 100%;
      object-fit: cover;
    }

    .cs26-mcard .cs26-mg {
      position: absolute;
      inset: 0;
      background: linear-gradient(
        180deg,
        rgba(0, 0, 0, 0.42) 0%,
        rgba(0, 0, 0, 0) 34%,
        rgba(20, 16, 16, 0.55) 100%
      );
    }

    /* The card behind the active one is dimmed rather than blurred. */
    .cs26-mcard .cs26-mdim {
      position: absolute;
      inset: 0;
      background: #0b0807;
      opacity: 0.5;
      transition: opacity 0.45s;
      pointer-events: none;
    }

    .cs26-mcard.is-on .cs26-mdim {
      opacity: 0;
    }

    .cs26-mcard h3,
    .cs26-mcard p {
      display: -webkit-box;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }

    .cs26-mcard h3 {
      -webkit-line-clamp: 2;
    }

    .cs26-mcard p {
      -webkit-line-clamp: 2;
    }

    /* Bare chevrons on the card edges, 44px of target underneath them. */
    .cs26-marrow {
      position: absolute;
      top: 50%;
      z-index: 20;
      width: 44px;
      height: 44px;
      padding: 0;
      display: grid;
      place-items: center;
      border: 0;
      background: transparent;
      color: #fff;
      cursor: pointer;
      transform: translateY(-50%);
      filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.85));
      transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
    }

    .cs26-marrow.is-prev {
      left: 6px;
    }

    .cs26-marrow.is-next {
      right: 6px;
    }

    .cs26-marrow:active {
      transform: translateY(-50%) scale(0.88);
    }

    /* The rail flows under the slider instead of sitting on the stage floor. */
    .cs26-spot-rail {
      position: static;
      padding: 16px 20px 20px;
    }
  }

  @media (max-width: 400px) {
    .cs26-msizer {
      width: calc(100% - 46px);
      aspect-ratio: 5 / 7;
    }

    .cs26-mcard {
      width: calc(100% - 46px);
    }

    .cs26-mcard p {
      -webkit-line-clamp: 3;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .cs26-spot-shot,
    .cs26-spot-panel,
    .cs26-mcard {
      transition: none;
    }
  }
}
