/* Performance Hub archive grid and resource card */

/* Archive layout */

.performance-hub-archive__empty {
    font-size: var(--text-base);
    color: var(--text-secondary);
}

/* Sidebar: override the large heading inherited from courses layout */

.courses .categories h2 {
    font-size: var(--text-base);
    font-weight: var(--font-bold);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    line-height: 1.4;
    margin-bottom: var(--space-2);
}

/* Grid: 3-col desktop / 2-col tablet / 1-col mobile */

.performance-hub-archive__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-6);
}

@media (width <= 1024px) {
    .performance-hub-archive__grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (width <= 480px) {
    .performance-hub-archive__grid {
        grid-template-columns: 1fr;
    }
}

/* Resource card */

.resource-card {
    background-color: var(--white);
    border-radius: var(--radius-lg);
    box-shadow: var(--space-1) var(--space-1) var(--space-2) var(--space-0) var(--shadow-medium);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    height: 420px;

    /* Anchor point for the stretched-link pattern (ABAU-1286). The title link's
       ::after fills the card so the whole card is a click target while the
       anchor stays semantically scoped to the title. */
    position: relative;
}

@media (width <= 1024px) {
    .resource-card {
        height: 450px;
    }
}

@media (width <= 480px) {
    .resource-card {
        height: auto;
    }
}

.resource-card__media {
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background-color: var(--bg-2);
    flex-shrink: 0;
}

.resource-card__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.lottie-player {
    width: 100%;
    height: 100%;
}

.resource-card__body {
    padding: var(--space-4) var(--space-5) var(--space-5);
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.resource-card__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

.resource-card__badge {
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-full);
    color: var(--white);
    background-color: var(--brand-main);
}

.resource-card__badge--podcast {
    background-color: var(--brand-main-dark);
}

.resource-card__badge--skills_challenge {
    background-color: var(--brand-main-darker);
}

.resource-card__duration {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    white-space: nowrap;
}

.resource-card__title {
    font-size: var(--heading-card);
    font-weight: var(--font-bold);
    line-height: var(--heading-card-lh);
    color: var(--brand-main);
    margin: var(--space-0);
}

.resource-card__subtitle {
    font-size: var(--text-base);
    color: var(--text-secondary);
    margin: var(--space-0);
}

.resource-card__description {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    line-height: 1.6;

    /* Line-clamp to 3 lines — modal carries the full WYSIWYG description.
       The previous max-height + hover-scroll pattern was replaced per Molly's
       2026-05-21 feedback (ABAU-1212) and the ABAU-1286 modal architecture. */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    overflow: hidden;
}

.resource-card__description p {
    margin: 0 0 var(--space-2);
}

.resource-card__description p:last-child {
    margin-bottom: 0;
}

/* "Downloadable resources" indicator (ABAU-1332) — informational pill at the
   foot of the card body, surfaced only when the resource has guide files.
   The actual download links live inside the modal; this is just a flag. */
.resource-card__downloads-indicator {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    margin: var(--space-3) 0 0;
    padding: 0;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    line-height: 1.4;
}

.resource-card__downloads-indicator-icon {
    /* Keep the emoji glyph baseline-stable across fonts. */
    font-size: 1em;
    line-height: 1;
}

/* Pagination */

.performance-hub-archive__pagination {
    margin-top: var(--space-8);
    display: flex;
    justify-content: center;
    gap: var(--space-2);
}

/* ==========================================================================
   Resource card — stretched-link trigger (ABAU-1286)
   ========================================================================== */

.resource-card__title-link {
    color: inherit;
    text-decoration: none;
}

.resource-card__title-link:hover {
    text-decoration: underline;
}

/* Stretches the title link's click target across the whole card without
   nesting the rest of the card inside the anchor (preserves screen-reader
   semantics — the link's accessible name is just the title). */
.resource-card__title-link::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
}

/* Any future independently-clickable element inside the card (category tag,
   on-card download icon, etc.) must layer above the stretched-link overlay. */
/* stylelint-disable no-descending-specificity -- intentional layering rule for nested interactives over the stretched-link */
.resource-card__body a:not(.resource-card__title-link),
.resource-card__media a {
    position: relative;
    z-index: 2;
}
/* stylelint-enable no-descending-specificity */

/* ==========================================================================
   Resource modal (ABAU-1286)
   ========================================================================== */

/* Modal architecture (ABAU-1332):
   - Outer `.resource-modal` provides the visual shell (gradient, border-radius,
     max-width / max-height). `overflow: hidden` clips inner scroll so the
     rounded top-right corner stays clean (no scrollbar slicing through it).
     Padding moves to `.resource-modal__inner` so the body's scrollbar lives
     inside the padded area, not flush against the radius.
     No `display` override here — jquery-modal toggles display:none ↔ inline-block
     itself; setting display in CSS would either reveal the modal on page load
     (specificity beats the plugin's `.modal { display: none }`) or be defeated
     by the plugin's inline style on open.
   - Inner `.resource-modal__inner` is the flex column: body scrolls, CTA pinned.
   - The max-height cap subtracts the sticky site header (`--clear-header-height`,
     129px desktop / 65px small) plus a 60px breadcrumb-safe buffer from each
     side of the viewport, so jquery-modal's vertical-align centering can't push
     the modal top under the header or `.breadcrumb-fullwrap`. */
.resource-modal {
    background: var(--brand-gradient);
    color: var(--white);
    max-width: 720px;
    width: 90%;
    overflow: hidden;
    border-radius: var(--radius-lg);
    padding: 0;
    /* close-modal anchors here (absolute) so it follows the rounded corners.
       jquery-modal's default top:-12.5px / right:-12.5px would be clipped by
       our overflow:hidden — see override below. */
    position: relative;
}

/* jquery-modal close X — pulled inside the rounded bounds instead of
   overhanging the corner (ABAU-1332). Scoped to .resource-modal so other
   modals on the site keep the plugin's default behaviour. */
.resource-modal a.close-modal {
    top: var(--space-3);
    right: var(--space-3);
    z-index: 3;
}

.resource-modal__inner {
    display: flex;
    flex-direction: column;
    /* Floor + ceiling on height:
       - min-height (620px) keeps the body readable on short laptop viewports
         where the calc-based max alone left only ~400px (Molly's feedback
         2026-05-29). When viewport is too short to honour both, min wins and
         the blocker's overflow:auto takes over — better than a cramped modal.
       - max-height caps growth so the modal still fits below the sticky
         header + .breadcrumb-fullwrap on tall viewports. */
    min-height: 620px;
    max-height: calc(100vh - (var(--clear-header-height) + 60px) * 2);
    padding: var(--space-7);
    box-sizing: border-box;
}

/* The body owns vertical scroll; CTA is its non-shrinking sibling. */
.resource-modal__body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding-bottom: var(--space-4);
    /* keep the scrollbar off the rounded edge by leaving a hair of inset */
    margin-right: calc(var(--space-2) * -1);
    padding-right: var(--space-2);
}

.resource-modal__badge {
    display: inline-block;
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-full);
    color: var(--brand-main);
    background-color: var(--white);
    margin-bottom: var(--space-4);
}

/* Fixed header region of the modal (ABAU-1332) — sits above the scrolling body
   and stays visible at all times. flex-shrink:0 keeps the media at its natural
   height; the scrolling body absorbs all the overflow pressure instead.
   Capped low so short-monitor viewers (Molly) keep most of the modal for
   readable content — the body scrolls freely beneath. */
.resource-modal__media {
    flex-shrink: 0;
    max-height: 15vh;
    overflow: hidden;
    border-radius: var(--radius-base);
    margin-bottom: var(--space-5);
}

.resource-modal__media img,
.resource-modal__media .lottie-player {
    width: 100%;
    max-height: 15vh;
    object-fit: contain;
    display: block;
}

.resource-modal__media:empty {
    display: none;
    margin: 0;
}

.resource-modal__title {
    color: var(--white);
    font-size: var(--heading-sub);
    font-weight: var(--font-bold);
    margin: 0 0 var(--space-2);

    /* tabindex=-1 focus target — suppress the default focus outline since
       focus here is programmatic (screen-reader announcement), not user-driven */
    outline: none;
}

.resource-modal__subtitle {
    color: var(--white);
    font-size: var(--text-base);
    margin: 0 0 var(--space-3);
}

.resource-modal__subtitle:empty {
    display: none;
}

.resource-modal__duration {
    display: inline-block;
    font-size: var(--text-sm);
    opacity: 0.85;
    margin-bottom: var(--space-4);
}

.resource-modal__duration:empty {
    display: none;
}

.resource-modal__description {
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    margin-bottom: var(--space-6);
}

.resource-modal__description :is(p, ul, ol) {
    margin: 0 0 var(--space-3);
}

/* Inherits .button (flex + margin:0 auto → centred). Colour overridden for the
   gradient background; bold weight (ABAU-1332) scoped to the modal CTA so the
   global .button class is untouched.
   flex-shrink:0 keeps the CTA out of the scrolling body — it always sits at
   the bottom of the modal regardless of body length. */
.resource-modal__cta {
    background-color: var(--white);
    color: var(--brand-main);
    font-weight: var(--font-bold);
    flex-shrink: 0;
    margin-top: var(--space-4);
}

.resource-modal__downloads {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-top: var(--space-4);
}

.resource-modal__downloads[hidden] {
    display: none;
}

.resource-modal__download {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--white);
    font-size: var(--text-sm);
    text-decoration: underline;
}

.resource-modal__download::before {
    content: '↓';
    font-weight: var(--font-bold);
    text-decoration: none;
}

/* Presence-only entry (contract v2.1) — the download exists in SSA-LMS but is
   not publicly linkable. Renders as informational text with a document glyph
   and muted appearance, so users see the content exists without thinking it's
   clickable. */
.resource-modal__download--unlinked {
    text-decoration: none;
    cursor: default;
    opacity: 0.8;
}

.resource-modal__download--unlinked::before {
    content: '📄';
    font-weight: normal;
}

/* Near-fullscreen modal on small phones with a small whitespace gutter
   so the modal reads as a panel, not the whole browser (ABAU-1332).

   1. `.jquery-modal.blocker` ships with `padding: 20px` from the plugin which
      would push a 100vw/100vh modal past the viewport. Override the padding
      via :has() to the smaller gutter we want (12px) — scoped so other plugin
      modals keep the default.
   2. Modal sized as `calc(100vw|100dvh - gutter * 2)` so it sits inside the
      gutter cleanly. `100dvh` (not `100vh`) is essential on iOS where `100vh`
      includes the area behind the address bar and would cut the CTA off the
      bottom.
   3. Media shrunk further (~10vh) so most of the screen goes to the readable
      body, which is the only scrollable region.
   4. Border-radius restored — with whitespace around the modal, rounded
      corners read better than the previous edge-to-edge sharp corners. */
@media (width <= 480px) {
    .jquery-modal.blocker:has(> .resource-modal) {
        padding: 12px;
    }
    .resource-modal {
        width: calc(100vw - 24px);
        height: calc(100dvh - 24px);
        max-width: none;
        border-radius: var(--radius-base);
    }
    .resource-modal__inner {
        min-height: 0; /* override the desktop 720px floor — phone fills its own viewport */
        max-height: 100%;
        height: 100%;
        padding: var(--space-5);
    }
    /* Media on mobile (per Molly 2026-05-29): wrapper grows to 30vh (3x the
       previous 10vh cap) and the image fills the wrapper edge-to-edge with
       `object-fit: cover` instead of letterboxing via the desktop `contain`.
       Lottie keeps its natural contain behaviour — SVG-based animations
       shouldn't be cropped. */
    .resource-modal__media,
    .resource-modal__media img,
    .resource-modal__media .lottie-player {
        max-height: 30vh;
    }
    .resource-modal__media img {
        width: 100%;
        height: 30vh;
        object-fit: cover;
    }
}
