/* ==========================================================================
   Courses archive — filter rail, card additions
   Loaded only on the courses view of the Resources library.
   ========================================================================== */

/* --------------------------------------------------------------- layout ---
   Only the filters and the results are gridded. The hero above them is
   near-full-bleed by design (max-width: min(2160px, 100% - 20px) with a
   negative top margin tucking it under the header); making it a grid item
   boxes it into the content column. The rail matches the hero's rail rather
   than the narrower content rail, so the two line up. */
.ssrp-course-archive {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
  max-width: min(2160px, 100% - 20px);
  margin-inline: auto;
  /* The hero and the archive were flush against each other. 48px matches the
     top padding the horizontal filter bar used to carry
     (12-admin-utilities.css:784), so the rhythm below the hero is unchanged
     from the rest of the library. margin-block-start, not the shorthand, so it
     cannot clobber the inline auto above. */
  margin-block-start: 48px;
  /* The archive ended flush against footer.site-footer. 80px matches the bottom
     padding the old grid section carried (12-admin-utilities.css:1305), so the
     clearance before the footer is the same as everywhere else in the library. */
  margin-block-end: 80px;
}

/* .page #content-area, #left-area and .entry-content all carry
   overflow-x: clip, and a clipping ancestor silently disables position:sticky
   for everything inside it. The theme already has an escape hatch for the
   slider sections; this extends it rather than deleting the clip, which is
   guarding real horizontal overflow somewhere. */
.page:has(.ssrp-course-archive) #content-area,
.page:has(.ssrp-course-archive) #left-area,
.page:has(.ssrp-course-archive) .entry-content {
  overflow: visible;
}

/* A sticky element can only travel inside its container. On a short result
   set (Books has three cards) the results column was shorter than the rail,
   so the rail never stuck and scrolled away with the page while every other
   view held it in place. Give the results column at least the rail's own
   cap (viewport minus sticky offset minus gap) on desktop, so the container
   is always tall enough for the rail to stick. Whitespace under a short
   grid reads as deliberate; a sidebar that behaves differently per page does
   not. Under 1040px the rail is a bottom sheet and this does not apply. */
@media (min-width: 1041px) {
  .ssrp-course-archive .ssrp-course-results {
    min-height: calc(100vh - var(--ssrp-rail-top, 125px) - var(--ssrp-rail-gap, 24px));
    min-height: calc(100dvh - var(--ssrp-rail-top, 125px) - var(--ssrp-rail-gap, 24px));
  }
}

/* ----------------------------------------------------------------- rail --- */
/* The rail is a <dialog>. On desktop it is opened non-modally and put back in
   the flow; the sheet behaviour lives in the media query at the bottom. */
/* Where the rail sticks = the header's sticky top + the header's height
   (105px). These track 04-header.css: top 20px normally, 12px on short
   viewports, plus the admin bar. The same variable sets the scroll height
   below, so the rail can never run under the header or off the bottom. */
:root { --ssrp-rail-top: 125px; --ssrp-rail-gap: 24px; }
.admin-bar { --ssrp-rail-top: 157px; }
@media (max-height: 700px) {
  :root { --ssrp-rail-top: 117px; --ssrp-rail-gap: 16px; }
  .admin-bar { --ssrp-rail-top: 149px; }
}

.ssrp-course-rail[open],
.ssrp-course-rail {
  position: sticky;
  /* inset FIRST: the UA stylesheet positions an open dialog, so the shorthand
     has to clear those edges — but it is a shorthand, so writing it after `top`
     silently resets top to auto and sticky never engages. */
  inset: auto;
  top: var(--ssrp-rail-top, 125px);
  display: block;
  width: auto;
  max-width: none;
  /* Taller than the room below its sticky top? Scroll inside the rail rather
     than pushing the bottom groups off-screen (the Level and Duration groups
     were unreachable on a 900px-tall window). dvh so a phone's collapsing
     browser chrome does not leave a dead band; vh fallback first. */
  max-height: calc(100vh - var(--ssrp-rail-top, 125px) - var(--ssrp-rail-gap, 24px));
  max-height: calc(100dvh - var(--ssrp-rail-top, 125px) - var(--ssrp-rail-gap, 24px));
  margin: 0;
  padding: 0 18px 18px;
  border: 1px solid #e4e9ef;
  border-radius: 14px;
  background: #fff;
  color: inherit;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: #c9d2dc transparent;
}
.ssrp-course-rail:not([open]) { display: none; }
.ssrp-course-rail::backdrop { background: rgba(3, 7, 18, 0.5); }

.ssrp-course-rail__head {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 16px 0 12px;
  background: #fff;
  border-bottom: 1px solid #eef2f6;
}
.ssrp-course-rail__title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.ssrp-course-rail__clear {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--blue-500, #1995e2);
  cursor: pointer;
}
.ssrp-course-rail__clear:disabled { color: #b6c0cc; cursor: default; }
.ssrp-course-rail__close { display: none; }

.ssrp-course-rail__group {
  padding: 14px 0 5px;
}

.ssrp-course-rail__legend {
  margin: 0 0 9px;
  font-family: var(--font-condensed, "Barlow Condensed", sans-serif);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #8794a3;
}
.ssrp-course-rail__help {
  margin: -4px 0 8px;
  font-size: 12px;
  line-height: 1.45;
  color: #8794a3;
}

.ssrp-course-rail__check {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  font-size: 14.5px;
  color: #17181c;
  cursor: pointer;
}
.ssrp-course-rail__check input {
  flex: none;
  width: 17px;
  height: 17px;
  accent-color: var(--blue-500, #1995e2);
  cursor: pointer;
}
.ssrp-course-rail__check span {
  flex: 1 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 9px;
}
/* The count is the last item in the row, so its width decides where the pips
   before it land: shrink-to-fit meant a two-digit count ("14") was 6.6px wider
   than a one-digit one and pulled that row's pips left by exactly that much.
   A fixed min-width with the digits right-aligned holds the column still —
   3ch covers up to three figures, and tabular-nums (already set) makes every
   digit the same width so the reservation is exact rather than approximate. */
.ssrp-course-rail__check em {
  flex: 0 0 auto;
  min-width: 3ch;
  text-align: right;
  font-style: normal;
  font-size: 12.5px;
  color: #8794a3;
  font-variant-numeric: tabular-nums;
}
.ssrp-course-rail__check:hover span { color: var(--blue-500, #1995e2); }
/* A category with nothing in it still appears, so the filter always offers the
   full set — it is simply not selectable. */
.ssrp-course-rail__check.is-empty { opacity: 0.45; cursor: default; }
.ssrp-course-rail__check.is-empty:hover span { color: inherit; }

.ssrp-course-rail__dot {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--cat, #cbd5e1);
}

/* Same dots as the cards, so a rail row and a card read as one scale. */
.ssrp-course-rail__pips {
  display: inline-flex;
  gap: 4px;
  flex: none;
  margin-left: auto;
  padding-right: 8px;
}
.ssrp-course-rail__pip {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: #dce3ea;
}
.ssrp-course-rail__pip.is-on { background: var(--blue-500, #1995e2); }

.ssrp-course-rail__switchrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  font-size: 14.5px;
}
.ssrp-course-rail__switch {
  position: relative;
  flex: none;
  width: 42px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: #d7dde5;
  cursor: pointer;
  transition: background 0.18s ease;
}
.ssrp-course-rail__switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.18s ease;
}
.ssrp-course-rail__switch[aria-checked="true"] { background: var(--blue-500, #1995e2); }
.ssrp-course-rail__switch[aria-checked="true"]::after { transform: translateX(18px); }

.ssrp-course-rail__search,
.ssrp-course-rail__select {
  width: 100%;
  font: inherit;
  font-size: 14px;
  border: 1px solid #cbd5e1;
  background: #fff;
}
.ssrp-course-rail__search { padding: 11px 14px; border-radius: 999px; }
.ssrp-course-rail__select { padding: 10px 12px; border-radius: 8px; }
.ssrp-course-rail__search:focus,
.ssrp-course-rail__select:focus {
  outline: 2px solid var(--blue-500, #1995e2);
  outline-offset: 1px;
  border-color: var(--blue-500, #1995e2);
}

.ssrp-course-rail__foot { display: none; }

/* -------------------------------------------------------------- results --- */
.ssrp-course-resultbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.ssrp-course-resultbar__count {
  margin: 0;
  font-size: 14px;
  color: #55606d;
  font-variant-numeric: tabular-nums;
}
.ssrp-course-resultbar__count b { color: #0b1420; }

.ssrp-course-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0 2px;
}
.ssrp-course-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border: 1px solid #d7dde5;
  border-radius: 999px;
  background: #fff;
  font: inherit;
  font-size: 13px;
  color: #17181c;
  cursor: pointer;
}
.ssrp-course-chip:hover { border-color: var(--blue-500, #1995e2); color: var(--blue-500, #1995e2); }

.ssrp-course-empty {
  margin-top: 18px;
  padding: 48px 24px;
  text-align: center;
  color: #55606d;
  background: #fff;
  border: 1px dashed #d7dde5;
  border-radius: 14px;
}

/* Skip layout and paint for cards that are nowhere near the viewport. This is
   what makes holding the whole catalogue in the DOM affordable, and therefore
   what lets the facet counts be true. The intrinsic size must match the real
   card box or the scrollbar jumps as cards resolve; the grid track is
   minmax(293px, 1fr) with aspect-ratio 3/4. */
.ssrp-course-archive [data-course-id] {
  content-visibility: auto;
  contain-intrinsic-size: auto 450px;
}
/* content-visibility: auto applies PAINT containment permanently — not only
   while the card is skipped — and paint containment clips to the padding box.
   The flip rotates in 3D with perspective, so the rotating faces extend beyond
   that box and were being sliced off mid-animation. Dropping to `visible`
   while the card is hovered or focused removes the containment for exactly the
   moment the animation needs it, and restores it the instant the pointer
   leaves. contain-intrinsic-size matches the real card box, so nothing shifts
   as containment comes and goes. */
.ssrp-course-archive [data-course-id]:hover,
.ssrp-course-archive [data-course-id]:focus-within {
  content-visibility: visible;
}
.ssrp-course-archive [data-course-id][hidden] { display: none !important; }

/* ---------------------------------------------------------------- toolbar --
   Desktop hides it: the rail is already visible, so a trigger would be noise. */
.ssrp-course-toolbar { display: none; }

/* --------------------------------------------------------------- mobile ---
   Under 1040px a sticky sidebar has nowhere to go: stacked, the rail is ~715px
   tall and pushes the first course a full screen down the page. It collapses
   to one control and opens as a bottom sheet over the results. */
@media (max-width: 1040px) {
  .ssrp-course-archive { grid-template-columns: 1fr; }

  /* Pinned to the BOTTOM of the viewport, not the top: on a phone the filter
     control is a thumb target, and the bottom edge is where the thumb already
     is. It also stops the control competing with the site header for the top
     of the screen, and puts the trigger next to the sheet it opens — the sheet
     rises from the same edge. Fixed rather than sticky so it is reachable from
     anywhere in a long grid without scrolling back up. */
  .ssrp-course-toolbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 0;
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-top: 1px solid #e4e9ef;
    box-shadow: 0 -4px 20px rgba(3, 7, 18, 0.08);
  }
  /* The bar floats over the grid, so the last row needs room to clear it or it
     can never be fully scrolled into view. */
  .ssrp-course-results { padding-bottom: 76px; }
  /* While the sheet is open it has its own footer with the same two actions —
     two bars stacked at the bottom would be one too many. */
  body.ssrp-rail-open .ssrp-course-toolbar { display: none; }
  .ssrp-course-toolbar__count {
    margin: 0;
    font-size: 13.5px;
    color: #55606d;
    font-variant-numeric: tabular-nums;
  }
  .ssrp-course-toolbar__count b { color: #0b1420; }
  .ssrp-course-toolbar__btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px;
    border: 1px solid #cbd5e1;
    border-radius: 999px;
    background: #fff;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    color: #0b1420;
    cursor: pointer;
  }
  /* The only clue about what is applied once the sheet is shut. */
  .ssrp-course-toolbar__n {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--blue-500, #1995e2);
    color: #fff;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
  }
  .ssrp-course-toolbar__n[hidden] { display: none; }

  /* showModal() hoists the dialog into the top layer, above every ancestor
     stacking context — which is the only reliable way out of Divi's
     .et_pb_column (z-index 2) / .et_builder_inner_content (z-index 1). */
  .ssrp-course-rail[open] {
    position: fixed;
    inset: auto 0 0 0;
    top: auto;
    width: 100%;
    max-width: none;
    max-height: 86vh;
    /* No reserved bottom padding: the footer is sticky, so it already occupies
       flow space at the end of the content. Padding here would push it up off
       the sheet's bottom edge and let rows scroll underneath it. */
    padding: 0 18px;
    border: 0;
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -8px 40px rgba(3, 7, 18, 0.28);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .ssrp-course-rail__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: 50%;
    background: #f1f5f9;
    font-size: 19px;
    line-height: 1;
    color: #45505d;
    cursor: pointer;
  }
  .ssrp-course-rail__foot {
    position: sticky;
    bottom: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 -18px;
    padding: 12px 18px calc(12px + env(safe-area-inset-bottom));
    background: #fff;
    border-top: 1px solid #eef2f6;
  }
  .ssrp-course-rail__footclear {
    flex: 0 0 auto;
    padding: 12px 16px;
    border: 1px solid #cbd5e1;
    border-radius: 999px;
    background: #fff;
    font: inherit;
    font-size: 14px;
    color: #45505d;
    cursor: pointer;
  }
  .ssrp-course-rail__apply {
    flex: 1 1 auto;
    padding: 13px 18px;
    border: 0;
    border-radius: 999px;
    background: var(--blue-500, #1995e2);
    color: #fff;
    font: inherit;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
  }
  /* Stop the page behind the sheet scrolling with it. */
  body.ssrp-rail-open { overflow: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  .ssrp-course-rail,
  .ssrp-course-rail__switch,
  .ssrp-course-rail__switch::after { transition: none; }
}

/* ==========================================================================
   Grid + card chrome inside the archive
   ========================================================================== */

/* The shared .resource-archive-grid__cards track is repeat(4, 450px) — fixed
   columns sized for the old full-width grid. Inside a results column that now
   sits beside a 300px rail, that overflows by ~766px. A fluid track fills
   whatever width the column has and reflows instead of overflowing. */
.ssrp-course-archive .ssrp-course-grid {
  grid-template-columns: repeat(auto-fill, minmax(293px, 1fr));
}

/* The card keeps its aspect; the wrapper only carries filter state. */
.ssrp-course-grid__item { min-width: 0; }
.ssrp-course-grid__item > .ssrp-course-card-flip { height: 100%; }



/* --------------------------------------------------- single-column cards ---
   Below ~642px the grid track (minmax(293px, 1fr) + 24px gap) can no longer
   fit two columns, so every card spans the full width. At the portrait 3/4 the
   theme uses elsewhere that makes each card ~473px tall — roughly half a phone
   screen apiece, so two cards fill the viewport and browsing becomes a chore.

   3/2 halves the height (355x473 -> 355x236) and turns the card landscape,
   which is the right shape for a full-width row: the eye scans down a list,
   not across a single tall poster.

   Both the aspect declarations have to be answered — .ssrp-card carries
   `aspect-ratio: 3/4 !important` (06-cards.css:13) and the flip wrapper sets
   its own (line 23) — so the override needs the same weight on the first. */
@media (max-width: 641px) {
  .ssrp-course-archive .ssrp-course-card-flip {
    aspect-ratio: 3 / 2;
  }
  .ssrp-course-archive .ssrp-card,
  .ssrp-course-archive .ssrp-card__inner {
    aspect-ratio: 3 / 2 !important;
  }

  /* .ssrp-course-card carries `max-width: 460px` — sized for the portrait card
     in a slider, where it never binds because the track is narrower than that.
     At one column the card wants the full ~585px, so the FRONT was capped at
     460 while the back face (not a .ssrp-course-card, so uncapped) stayed full
     width: the card visibly changed width when it flipped. Lift the cap here
     only; every other surface keeps it. */
  .ssrp-course-archive .ssrp-course-card {
    max-width: none;
  }

  /* The theme hides the emblem below 768px, where the portrait card had no room
     for it. The landscape card does, and the emblem is the card's category
     signal — so it comes back. */
  .ssrp-course-archive .ssrp-course-card__header-right {
    display: flex;
  }

  /* With the frame that much shorter, object-fit: cover crops hard — so say
     WHICH part survives. Centred horizontally, anchored to the top third
     vertically: subjects in these stills sit high in frame (faces, stages,
     signage), and centre-cropping a landscape window out of a portrait photo
     cuts their heads off. */
  .ssrp-course-archive .ssrp-card__img {
    object-position: center 33%;
  }

  /* The card keeps its own intrinsic height rather than being stretched to a
     row, so the grid must not equalise them. */
  .ssrp-course-archive .ssrp-course-grid { align-items: start; }

  /* On the back, the description is flex: 1 and stretches to fill — in the
     taller portrait card its text filled that box, but in the landscape card
     the same 40 words run about three lines and left a ~200px void INSIDE the
     description element. Sizing it to its content and pinning the footer with
     margin-top: auto puts the whitespace where it reads as deliberate: between
     the two groups, not inside a text block. */
  .ssrp-course-archive .ssrp-course-card-back__description {
    flex: 0 1 auto;
  }
  /* No margin-top: auto here — the CTA already carries one, and two autos split
     the free space between them, opening a second gap instead of closing the
     first. Stats sit with the text; the button keeps the bottom. */
}

/* ------------------------------------------------------- type selector -----
   One rail for every resource type (3.13.134). The type lives in the rail as
   its first group — a dropdown that navigates — rather than a row above the
   grid, so nothing pushes the results below the fold. */
.ssrp-course-rail__typeform { margin: 0; }
.ssrp-course-rail__group--type {
  padding-top: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eef2f6;
}
.ssrp-course-rail__select--type {
  font-weight: 600;
  color: #030712;
}

/* ------------------------------------------------------------ event promo ---
   The one upcoming event pinned first in Courses. Same card as a course; the
   status chip says what it is. Coming soon = not a link anywhere. */
.ssrp-event-promo-card__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.ssrp-event-promo-card__state {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  border-radius: 999px;
  font-family: var(--font-condensed, inherit);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.ssrp-event-promo-card__state.is-coming-soon { background: #ffd166; color: #030712; }
.ssrp-event-promo-card__state.is-open { background: var(--blue-500, #1995e2); color: #fff; }
.ssrp-event-promo-card.is-coming-soon .ssrp-event-promo-card__front { cursor: default; }
.ssrp-event-promo-card.is-coming-soon .ssrp-course-card__title { opacity: 0.92; }
.ssrp-course-card-back__note { margin: auto 0 0; font-size: 13px; color: #7b8794; }
