/* =====================================================================
   Timed Content Section
   Slack-inspired pattern: vertical list of nav items on the left, each
   with its own progress bar that fills 0→100% over the section's
   data-auto-advance ms. Right column shows one tile per slide, only the
   active tile is opacity:1 (others fade out). 3 tile layouts: image-only,
   rte-only, image-and-rte (image at top with optional green→coral tint).
   ===================================================================== */

.timed-content { /* default white background inherited from .section--white */ }

/* Two-column grid: nav ~40% / tile ~60%. Equal-min so tiles can never
   shrink below 320px on narrower screens (forces stack on mobile). */
.timed-content__grid {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(320px, 7fr);
    gap: 64px;
    align-items: start;
}

/* ---------- LEFT NAV ------------------------------------------------ */

.timed-content__nav {
    display: flex;
    flex-direction: column;
    gap: 0;
}
.timed-content__nav-item {
    /* Reset native <button> styling */
    appearance: none;
    background: transparent;
    border: 0;
    padding: 22px 0 24px;
    text-align: left;
    cursor: pointer;
    color: inherit;
    font-family: inherit;
    /* Flex row: vertical progress pill on the left, content beside it.
       align-items: stretch so the pill stretches to the nav item's full
       height; the content column drives that height. */
    display: flex;
    align-items: stretch;
    gap: 28px;
    width: 100%;
    /* Mobile touch hardening:
       • -webkit-tap-highlight-color: transparent — kill the dark grey
         flash iOS Safari paints on tap by default. The brand has its
         own active treatment via the --active class; the flash on top
         of it reads as a glitch.
       • -webkit-touch-callout: none — disable the long-press context
         menu (copy / share / look-up) that iOS Safari pops on a sustained
         press of a link-like element. The press + bounce of that menu
         was contributing to the "press-and-glitch" feel.
       • user-select: none — prevents text-selection drag from kicking
         in if the user happens to press on the title text. Pairs with
         the callout disable to make a press behave like a button press,
         not a text-grab.
       • touch-action: manipulation — allows pan + pinch-zoom but kills
         the 300ms double-tap-zoom delay so taps register instantly.
       None of these affect desktop behaviour. */
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    user-select: none;
    touch-action: manipulation;
}
.timed-content__nav-item:focus-visible {
    outline: 2px solid var(--coral);
    outline-offset: 4px;
    border-radius: 4px;
}

/* Vertical progress pill — hidden on inactive items so only the active
   slide's countdown shows. On the active item the empty track is visible
   as a faint background, with the green→coral gradient fill growing from
   top to bottom over the section's data-auto-advance ms.
   JS sets height on .timed-content__progress-bar each frame via rAF.
   `cursor: default` so the pill doesn't get the pointer affordance the
   parent button gives — paired with the JS check that ignores clicks
   inside .timed-content__progress, this makes only the text area
   feel clickable. */
.timed-content__progress {
    position: relative;
    width: 14px;
    flex-shrink: 0;
    border-radius: 999px;
    overflow: hidden;
    background: rgba(0, 56, 69, 0.10);
    opacity: 0;
    transition: opacity 0.3s ease;
    cursor: default;
}
.timed-content__nav-item--active .timed-content__progress {
    opacity: 1;
}
.timed-content__progress-bar {
    /* Bar always covers the FULL pill, painting the full green→coral
       gradient at its intended scale. We reveal it top-down via clip-path —
       JS sets the bottom inset every frame so the gradient is uncovered
       progressively. This keeps the gradient anchored to the pill's full
       height: early on you see only the green top portion, and the coral
       lower portion only becomes visible as the fill approaches the bottom.
       (Previously height grew 0→100% with the gradient on the bar itself,
       so the bar always had coral at its bottom edge — wrong feel.) */
    position: absolute;
    inset: 0;
    /* Blue → coral gradient — matches the .text-gradient highlight stops
       in style.css (#4da8b5 teal-blue → #f0845e coral) so the timer pill
       reads as part of the same brand-accent family as gradient headings. */
    background: linear-gradient(to bottom, #4da8b5, #f0845e);
    border-radius: 999px;
    clip-path: inset(0 0 100% 0);
    /* No transition: JS sets clip-path every frame via rAF; a CSS
       transition would fight it and add lag. */
}

/* Wrap the title/subtitle/link in a flex child so it takes the remaining
   width beside the progress pill. */
.timed-content__nav-body {
    flex: 1;
    min-width: 0;
}

.timed-content__nav-title {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text-heading);
    line-height: 1.25;
    transition: color 0.3s ease, opacity 0.3s ease;
}
/* Subtitle + link are HIDDEN on inactive nav items — only the active
   slide's full message is visible. max-height + opacity + margin animate
   together for a smooth reveal/collapse; display:none would jump the
   layout. The "page jumps" issue this previously caused (when the
   section is embedded inside the horizontal scroll lock pin and the
   pin's natural height feeds into the un-stick scroll threshold) is
   now fixed externally via a JS-set min-height on the embedded section
   in main.js — measured once at init from the "all items expanded"
   state — so the embedded section can never shrink below its largest
   possible cycling state. */
.timed-content__nav-subtitle {
    font-size: 1.3125rem;
    line-height: 1.5;
    color: var(--text-body);
    margin-top: 0;
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    /* No transition on the INACTIVE state — when an item loses .active
       its subtitle collapses INSTANTLY. The new active item still gets
       the smooth 0.45s reveal via the rule below. This kills the
       overlapping period where both items' subtitles were partly
       visible (which briefly inflated the section's natural height and
       caused intermittent layout jumps even with the min-height lock). */
    transition: none;
}
.timed-content__nav-item--active .timed-content__nav-subtitle {
    margin-top: 10px;
    max-height: 360px;
    opacity: 0.85;
    /* Smooth reveal applied when this item GAINS .active. */
    transition: max-height 0.45s ease, opacity 0.3s ease, margin-top 0.45s ease;
}
/* Link wrapper collapses with the same max-height + opacity pattern as
   the subtitle. Stable embedded-section height (which prevents the pin
   from jumping when this collapses) is handled by the JS-set
   min-height in main.js — see comment on .timed-content__nav-subtitle
   above. */
.timed-content__nav-link-wrap {
    margin-top: 0;
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    /* Instant collapse on losing .active — same reasoning as the
       subtitle above. The smooth reveal is on the active rule. */
    transition: none;
    position: relative;
    z-index: 2;
}
.timed-content__nav-item--active .timed-content__nav-link-wrap {
    margin-top: 18px;
    max-height: 80px;
    opacity: 1;
    overflow: visible;
    transition: max-height 0.45s ease, opacity 0.3s ease, margin-top 0.45s ease, overflow 0s linear 0s;
}

/* Measurement state — JS toggles each slide active one at a time at
   init and reads section.offsetHeight to find the tallest cycling
   state (the upper bound). Transitions disabled so each measurement
   is the resting natural height, not mid-animation. The class is
   removed before paint, so users never see the cycling. */
.timed-content--measuring * {
    transition-duration: 0s !important;
}
.timed-content__nav-link {
    /* Sits inside .timed-content__nav-link-wrap so visual styles come
       from .btn / .btn--coral / .btn--sm — nothing to do here. */
}
.timed-content__nav-link:hover {
    text-decoration: underline;
}
.timed-content__nav-link .btn__arrow {
    transition: transform 0.2s ease;
}
.timed-content__nav-link:hover .btn__arrow {
    transform: translateX(3px);
}

/* Inactive nav state — title slightly dim, no progress fill (handled by
   JS setting width:0%). Subtitle stays visible — matches Slack's pattern
   where you can read all options at once. */
.timed-content__nav-item:not(.timed-content__nav-item--active) .timed-content__nav-title {
    opacity: 0.5;
}
/* Hover-only — touch devices fire :hover on press and clear it on
   release/scroll, which would make the title flicker 0.5 → 0.85 → 0.5
   over ~600ms (0.3s transition each way) every time the user just
   pressed-and-scrolled. @media (hover: hover) gates this rule to
   devices with a real hover capability (mouse-driven desktop) so
   mobile presses don't trigger the opacity dance. */
@media (hover: hover) {
    .timed-content__nav-item:not(.timed-content__nav-item--active):hover .timed-content__nav-title {
        opacity: 0.85;
    }
}

/* ---------- RIGHT TILES --------------------------------------------- */

/* Tile container — fixed aspect ratio so the page doesn't reflow when
   tiles swap. Base is 4:3 (height = 75% of width) — matches the natural
   nav height on tablets/small desktops where the left column extends
   further due to text wrapping, and on any size with 5+ nav items where
   the left column is taller still. The desktop-with-few-items override
   below flattens this to 5:3. */
.timed-content__tiles {
    position: relative;
    aspect-ratio: 4 / 3;
    width: 100%;
}

/* Large screens (≥1200px) AND ≤4 nav items: flatten to 5:3 so the tile
   height matches the left nav (4 items: 1 expanded + 3 collapsed). With
   5+ items the left grows taller anyway, so we keep 4:3 to avoid the
   tile being shorter than the nav; with viewports <1200px the nav also
   grows taller via text wrapping, same reasoning. :has() lets us detect
   "has a 5th nav-item" purely in CSS — modern browser support is solid
   (Chrome/Safari/Firefox all current). */
@media (min-width: 1200px) {
    .timed-content__grid:not(:has(.timed-content__nav-item:nth-child(5))) .timed-content__tiles {
        aspect-ratio: 5 / 3;
    }
}
.timed-content__tile {
    position: absolute;
    inset: 0;
    border-radius: var(--radius, 16px);
    overflow: hidden;
    background: var(--bg-white, #ffffff);
    box-shadow: var(--shadow-md, 0 12px 32px rgba(0, 0, 0, 0.08));
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.6s ease;
}
.timed-content__tile--active {
    opacity: 1;
    pointer-events: auto;
}

/* Layout: IMAGE ONLY — fills the whole rounded tile. */
.timed-content__tile--image-only .timed-content__tile-image {
    position: absolute;
    inset: 0;
}
.timed-content__tile--image-only .timed-content__tile-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Layout: RTE ONLY — padded text block, vertically centred. */
.timed-content__tile--rte-only .timed-content__tile-body {
    padding: 48px 56px;
    height: 100%;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.timed-content__tile--rte-only .timed-content__tile-body > *:first-child { margin-top: 0; }
.timed-content__tile--rte-only .timed-content__tile-body > *:last-child  { margin-bottom: 0; }

/* Tile RTE body text — match Content Grid Section RTE size (1.3125rem)
   so the tile reads like the rest of the site's body copy. Covers both
   "RTE only" and "Image and RTE" layouts. */
.timed-content__tile-body,
.timed-content__tile-body p,
.timed-content__tile-body li {
    font-size: 1.3125rem;
    line-height: 1.55;
}

/* Layout: IMAGE AND RTE — image at the top (~50% height) with optional
   green→coral tint, RTE body below. Matches the insight-card pattern. */
.timed-content__tile--image-and-rte {
    display: grid;
    grid-template-rows: minmax(180px, 50%) 1fr;
}
.timed-content__tile--image-and-rte .timed-content__tile-image--top {
    position: relative;
    overflow: hidden;
}
.timed-content__tile--image-and-rte .timed-content__tile-image--top img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
/* Tint overlay — works for both "Image only" (image fills the whole tile)
   and "Image and RTE" (image fills the top half) layouts because the
   selector targets the tinted image wrapper directly, regardless of
   which layout modifier its parent tile carries. */
.timed-content__tile-image--tinted .timed-content__tile-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg,
        rgba(2, 61, 54, 0.75) 0%,
        rgba(3, 88, 78, 0.6) 50%,
        rgba(246, 171, 147, 0.5) 100%);
    pointer-events: none;
}
.timed-content__tile--image-and-rte .timed-content__tile-body {
    padding: 28px 32px 32px;
    overflow-y: auto;
}
.timed-content__tile--image-and-rte .timed-content__tile-body > *:first-child { margin-top: 0; }
.timed-content__tile--image-and-rte .timed-content__tile-body > *:last-child  { margin-bottom: 0; }

/* ---------- Section background variants ----------------------------- */

/* Dark green: white text, lighter progress track so the empty pill
   stays visible against the dark background. The fill keeps the same
   green→coral gradient (reads fine on either bg). */
.timed-content.section--deep .timed-content__nav-title { color: #ffffff; }
.timed-content.section--deep .timed-content__nav-subtitle { color: rgba(255, 255, 255, 0.8); }
/* The nav link is rendered as a .btn .btn--coral .btn--sm pill, which
   already provides its own colour (var(--dark-blue) on a coral fill).
   An earlier override here forced color:var(--coral) which made the
   pill text invisible against the coral background on dark-green
   sections — removed so the base .btn--coral colour applies on every
   section variant. */
.timed-content.section--deep .timed-content__progress { background: rgba(255, 255, 255, 0.15); }

/* ---------- Match-image-height variant -----------------------------
   Editor toggle (matchImageHeight) — useful when a section has 6+ nav
   items that would otherwise overhang an aspect-ratio-fixed tile,
   leaving an awkward empty gap below the image. In this mode:
     • Grid items stretch to fill the row track so the tile cell
       takes the same height as the nav cell.
     • The tile's aspect-ratio is dropped so it can be free-height.
     • The nav gets min-height: var(--nav-max-h), where --nav-max-h is
       set by main.js's lockHeight() after measuring the nav's max
       height across every single-active state. Without this, the row
       track would shrink each time a shorter-content nav item became
       active and the tile would JUMP up and down. Locking the nav to
       its max height keeps the tile rock-steady across slide changes.
   Mobile (≤900px) resets these so the stacked layout still works —
   see the bottom of this file. */
.timed-content--match-image-height .timed-content__grid {
    align-items: stretch;
}
.timed-content--match-image-height .timed-content__tiles {
    /* Drop the desktop 4:3 / 5:3 height so the tile can stretch to
       fill the grid row's height instead. */
    aspect-ratio: auto;
}
.timed-content--match-image-height .timed-content__nav {
    /* `--nav-max-h` is set inline on the section by main.js after the
       lockHeight measurement cycle. Falls back to `auto` if the JS
       hasn't run yet (initial paint), and to `auto` if the toggle is
       on but JS measurement didn't capture a nav height (shouldn't
       happen, but a sensible fallback). */
    min-height: var(--nav-max-h, auto);
}

/* ---------- Mobile: stack ------------------------------------------ */

@media (max-width: 900px) {
    /* Flex-column the section + container + grid so the JS-locked section
       height (set inline by main.js, see "lockHeight") is distributed
       between the nav (top, natural height) and the tile (bottom, fixed
       aspect-ratio).
       Why this matters: with the default document-flow stacking, the tile
       sits immediately below the nav, so as the nav shrinks/grows when the
       active slide changes (subtitle + link wrap revealing/collapsing) the
       tile's Y position visibly JUMPS up and down. Pinning the tile to the
       BOTTOM of the section's fixed height puts the variable space into the
       gap between nav and tile instead, keeping the tile rock-steady — same
       guarantee the desktop layout already gets from being side-by-side. */
    .timed-content {
        display: flex;
        flex-direction: column;
    }
    .timed-content > .container {
        flex: 1;
        display: flex;
        flex-direction: column;
        min-height: 0;
    }
    .timed-content__grid {
        display: flex;
        flex-direction: column;
        /* Reset the desktop 2-col grid */
        grid-template-columns: none;
        /* Gap removed — the tile's margin-top: auto below provides the
           variable separation. A non-zero gap here would just shift the
           gap-size baseline; auto distributes whatever's left. */
        gap: 0;
        flex: 1;
        min-height: 0;
    }
    .timed-content__tiles {
        /* Pinned to the bottom of the (height-locked) section. Auto top
           margin eats up the slack as the nav shrinks, so the tile's Y
           never moves between slide changes. */
        margin-top: auto;
        aspect-ratio: 4 / 3;
        min-height: 0;
    }
    .timed-content__tile--rte-only .timed-content__tile-body {
        padding: 32px 28px;
    }
    /* Mobile reset for matchImageHeight — the toggle is desktop-only.
       When stacked, the nav must NOT be locked to its desktop max-height
       (that would create a huge empty gap below it), and the tile must
       keep its 4:3 aspect-ratio (set above). */
    .timed-content--match-image-height .timed-content__nav {
        min-height: 0;
    }
    .timed-content--match-image-height .timed-content__tiles {
        aspect-ratio: 4 / 3;
    }
}
