/* ==========================================================================
   MCC Catalyst Program Directory — Component Styles
   Scope: .catalyst-directory — all rules are scoped to this selector
   Host page already loads: Foundation CSS, app.css, Source Sans Pro
   Do NOT redeclare font-family, body font-size, or heading sizes.
   ========================================================================== */


/* --------------------------------------------------------------------------
   Design Tokens — all scoped to the component root
   -------------------------------------------------------------------------- */
.catalyst-directory {
  /* Colors */
  --cd-color-primary:        #4b3190;
  --cd-color-primary-hover:  #3a2570;
  --cd-color-link:           #5639a4;
  --cd-color-link-hover:     #507F2E;
  --cd-color-green:          #74b843;
  --cd-color-teal:           #00b0c7;
  --cd-color-surface:        #ffffff;
  --cd-color-surface-subtle: #f5f5f5;
  --cd-color-background:     #f9f9f9;
  --cd-color-border:         #e0e0e0;
  --cd-color-text-primary:   #444444;
  --cd-color-text-secondary: #666666;
  --cd-color-badge-new:      #fdbb30;
  --cd-color-badge-new-text: #000000;
  --cd-color-mylist-accent:  #4b3190;
  --cd-color-error:          #af282e;
  --cd-color-focus-ring:     #4b3190;
  /* Tab strip */
  --cd-tab-strip-tint:    rgba(75, 49, 144, 0.08);
  --cd-tab-strip-border:  rgba(75, 49, 144, 0.25);
  --cd-tab-ghost-border:  rgba(75, 49, 144, 0.20);

  /* ------------------------------------------------------------------
     Accent palette — the ONLY colour a card or modal takes from its
     program. Resolved from the program's DIVISION by getCardAccent() in
     mcc-program-directory.js, never from its topic, so a topic nobody has
     seen before renders correctly the moment it arrives.

     Two values per accent, and both are load-bearing:
       --cd-accent-X      the 4px rule. Decorative, no contrast floor.
       --cd-accent-X-ink  the topic label, set as text on white. Every ink
                          value clears 4.5:1 on --cd-color-surface; the rule
                          colours mostly do not, which is why they are two
                          tokens and not one.

     Values are the _refresh/style.css :root palette, written as literals
     because the finder page template does NOT load _refresh/style.css yet —
     var(--purple-primary) resolves to nothing there and would fall back
     silently. Names are chosen to survive that migration: --cd-accent-purple
     is --purple-primary, --cd-accent-green is --green-primary, and so on.
     The -ink values are darkened derivatives with no refresh twin.
     ------------------------------------------------------------------ */
  --cd-accent-purple:      #47348b;   /* = --purple-primary */
  --cd-accent-purple-ink:  #47348b;   /* 9.9:1 on white — dark enough as-is */
  --cd-accent-violet:      #5639a4;   /* = --purple-medium */
  --cd-accent-violet-ink:  #5639a4;   /* 8.3:1 */
  --cd-accent-cyan:        #00979a;   /* = --cyan-primary */
  --cd-accent-cyan-ink:    #007073;   /* 5.9:1 */
  --cd-accent-blue:        #258dad;   /* = --cyan-dark */
  --cd-accent-blue-ink:    #1f7691;   /* 5.2:1 */
  --cd-accent-green:       #74b843;   /* = --green-primary */
  --cd-accent-green-ink:   #44722a;   /* 5.7:1 */
  --cd-accent-gold:        #f3bd50;   /* = --yellow-primary */
  --cd-accent-gold-ink:    #8a5f00;   /* 5.7:1 */
  --cd-accent-orange:      #f37520;   /* = --orange-primary */
  --cd-accent-orange-ink:  #a3560f;   /* 5.4:1 */
  --cd-accent-red:         #c60f13;   /* = --red-primary */
  --cd-accent-red-ink:     #9e0c0f;   /* 8.4:1 = --red-dark */

  /* Resolved accent for the current card/modal. Defined here so it always
     resolves: an unknown data-cd-accent value lands on purple rather than on
     nothing. getCardAccent() warns in that case, so it is loud, not silent. */
  --cd-accent:      var(--cd-accent-purple);
  --cd-accent-ink:  var(--cd-accent-purple-ink);
  /* Thickness of the accent rule on both surfaces — one value, two places. */
  --cd-accent-rule: 4px;

  /* Typography — component overrides only; inherits base from app.css */
  --cd-font-size-base: 1rem;
  --cd-font-size-sm:   0.875rem;
  --cd-font-size-xs:   0.75rem;
  --cd-font-size-lg:   1.125rem;
  --cd-font-size-xl:   1.25rem;
  --cd-font-weight-regular: 400;
  --cd-font-weight-medium:  600;
  --cd-font-weight-bold:    700;
  --cd-line-height-body:    1.5;
  --cd-line-height-tight:   1.25;

  /* Spacing (4px base grid) */
  --cd-space-1:  0.25rem;
  --cd-space-2:  0.5rem;
  --cd-space-3:  0.75rem;
  --cd-space-4:  1rem;
  --cd-space-6:  1.5rem;
  --cd-space-8:  2rem;
  --cd-space-12: 3rem;
  --cd-space-16: 4rem;

  /* Motion */
  --cd-duration-fast:     150ms;
  --cd-duration-base:     200ms;
  --cd-easing-standard:   cubic-bezier(0.4, 0, 0.2, 1);
  --cd-easing-decelerate: cubic-bezier(0, 0, 0.2, 1);
  --cd-easing-accelerate: cubic-bezier(0.4, 0, 1, 1);

  /* Layout */
  /* My List badge — fixed to viewport bottom-right */
  --cd-mylist-badge-inset-bottom: 1.25rem;
  /* Modal save bar — sticky bottom strip height reference */
  --cd-modal-save-bar-height:     4.5rem;
  /* Search */
  --cd-search-bar-height:              52px;
  --cd-search-bar-height-active:       60px;
}

/* --------------------------------------------------------------------------
   Accent selection — one block, both surfaces

   Every element that paints an accent reads var(--cd-accent) /
   var(--cd-accent-ink). These rules are the only place a token name becomes a
   colour, so the card and the modal cannot drift: they set the same two custom
   properties from the same attribute, written by the same JS resolver.

   data-cd-accent (not data-accent, not data-band) per widget-integration-rules
   rule 11 — widget data-attributes carry the cd- prefix so they can never
   collide with Foundation's reserved trigger attributes.
   -------------------------------------------------------------------------- */
.catalyst-directory [data-cd-accent="purple"] { --cd-accent: var(--cd-accent-purple); --cd-accent-ink: var(--cd-accent-purple-ink); }
.catalyst-directory [data-cd-accent="violet"] { --cd-accent: var(--cd-accent-violet); --cd-accent-ink: var(--cd-accent-violet-ink); }
.catalyst-directory [data-cd-accent="cyan"]   { --cd-accent: var(--cd-accent-cyan);   --cd-accent-ink: var(--cd-accent-cyan-ink); }
.catalyst-directory [data-cd-accent="blue"]   { --cd-accent: var(--cd-accent-blue);   --cd-accent-ink: var(--cd-accent-blue-ink); }
.catalyst-directory [data-cd-accent="green"]  { --cd-accent: var(--cd-accent-green);  --cd-accent-ink: var(--cd-accent-green-ink); }
.catalyst-directory [data-cd-accent="gold"]   { --cd-accent: var(--cd-accent-gold);   --cd-accent-ink: var(--cd-accent-gold-ink); }
.catalyst-directory [data-cd-accent="orange"] { --cd-accent: var(--cd-accent-orange); --cd-accent-ink: var(--cd-accent-orange-ink); }
.catalyst-directory [data-cd-accent="red"]    { --cd-accent: var(--cd-accent-red);    --cd-accent-ink: var(--cd-accent-red-ink); }


/* --------------------------------------------------------------------------
   Host heading neutraliser

   The finders render inside <main class="ge ..."> on the CMS page, and
   app.css:1662 styles `.ge h2` with background #7c69b0, padding 5px 15px and
   text-transform: uppercase. Widget rules always set font-size / colour /
   margin and so won those, but never declared the box or the casing — so the
   modal <h2> quietly carried a purple uppercase block the entire time. It was
   invisible only because .cd-modal-band painted a colour field behind it; the
   moment the band was retired (2026-08-19) it appeared.

   widget-integration-rules rule 2 says override heading styles explicitly in
   the widget scope. This does that for the properties the rule's own example
   omits, at every level rather than only the one that happens to be broken.

   Equal specificity to `.ge h2` (0,1,1), won on source order — this stylesheet
   loads after app.css. .cd-modal-title also restates these so the modal title
   does not depend on load order at all.
   -------------------------------------------------------------------------- */
.catalyst-directory h1,
.catalyst-directory h2,
.catalyst-directory h3,
.catalyst-directory h4,
.catalyst-directory h5,
.catalyst-directory h6 {
  background: none;
  padding: 0;
  text-transform: none;
}


/* Respect prefers-reduced-motion — collapse all durations to instant */
@media (prefers-reduced-motion: reduce) {
  .catalyst-directory,
  .catalyst-directory * {
    transition-duration: 0ms !important;
    animation-duration: 0ms !important;
  }
}


/* --------------------------------------------------------------------------
   Base Container
   -------------------------------------------------------------------------- */
.catalyst-directory {
  background: var(--cd-color-background);
  position: relative; /* containing block for absolute My List badge */
  box-sizing: border-box;
}

.catalyst-directory *,
.catalyst-directory *::before,
.catalyst-directory *::after {
  box-sizing: inherit;
}


/* --------------------------------------------------------------------------
   Utility: Screen-reader only
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}


/* --------------------------------------------------------------------------
   Tab Strip — Framed navigation band with folder-tab elevation
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-tab-strip {
  display: flex;
  align-items: stretch;
  gap: var(--cd-space-1);
  border-bottom: 1px solid var(--cd-color-border);
  background: var(--cd-color-background);
  margin: 0;
  padding: var(--cd-space-3) var(--cd-space-3) 0;
  list-style: none;
}

.catalyst-directory .cd-tab-strip[hidden] {
  display: none;
}

.catalyst-directory .cd-tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--cd-tab-ghost-border);
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  margin-bottom: 0;
  padding: var(--cd-space-3) var(--cd-space-2);
  min-height: 44px;
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
  font-weight: var(--cd-font-weight-regular);
  line-height: var(--cd-line-height-tight);
  cursor: pointer;
  transition:
    color var(--cd-duration-fast) var(--cd-easing-standard),
    background-color var(--cd-duration-fast) var(--cd-easing-standard),
    border-color var(--cd-duration-fast) var(--cd-easing-standard),
    box-shadow var(--cd-duration-fast) var(--cd-easing-standard);
  text-align: center;
}

.catalyst-directory .cd-tab:hover {
  color: var(--cd-color-text-primary);
  background: rgba(75, 49, 144, 0.04);
}

.catalyst-directory .cd-tab[aria-selected="true"] {
  color: var(--cd-color-primary);
  font-weight: var(--cd-font-weight-medium);
  background: var(--cd-color-surface);
  border-color: var(--cd-color-primary);
  border-top-width: 3px;
  /* Negative margin merges active tab with the strip's bottom border,
     creating the folder-opens-into-panel visual connection */
  margin-bottom: -1px;
  box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.08);
}

.catalyst-directory .cd-tab:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

@media (min-width: 640px) {
  .catalyst-directory .cd-tab {
    font-size: var(--cd-font-size-base);
    padding: var(--cd-space-3) var(--cd-space-6);
  }
}


/* --------------------------------------------------------------------------
   Tab Panels
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-tab-panel {
  display: none;
}

.catalyst-directory .cd-tab-panel.is-active {
  display: block;
}


/* --------------------------------------------------------------------------
   Filter Bar
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-filter-bar {
  background: var(--cd-color-surface-subtle);
  border: 1px solid var(--cd-color-border);
  border-radius: 10px;
  margin: 0 var(--cd-space-4) var(--cd-space-4);
  padding: var(--cd-space-1) var(--cd-space-4);
  display: flex;
  flex-direction: column;
  gap: 0;
}

.catalyst-directory .cd-filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--cd-space-2);
  padding: var(--cd-space-3) 0;
}

.catalyst-directory .cd-filter-row + .cd-filter-row {
  border-top: 1px solid var(--cd-color-border);
}

.catalyst-directory .cd-filter-chips-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
}

.catalyst-directory .cd-filter-chips-scroll {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cd-space-2);
  min-width: 0;
}

.catalyst-directory .cd-filter-row-label {
  font: inherit;
  background: none;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--cd-space-1);
  padding: var(--cd-space-1) 0;
  text-align: left;
  font-size: var(--cd-font-size-xs);
  color: var(--cd-color-text-secondary);
  font-weight: var(--cd-font-weight-medium);
  white-space: nowrap;
  flex-shrink: 0;
  min-width: 4rem;
}

.catalyst-directory .cd-filter-row-label::after {
  content: '';
  width: 0.4rem;
  height: 0.4rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-filter-row.is-collapsed .cd-filter-row-label::after {
  transform: rotate(-45deg);
}

.catalyst-directory .cd-filter-row-label:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

/* Collapsed: hide unselected chips, keep any already-active chip visible and removable */
.catalyst-directory .cd-filter-row.is-collapsed .cd-chip[aria-pressed="false"] {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .catalyst-directory .cd-filter-row-label::after {
    transition-duration: 0ms !important;
  }
}

/* Filter chip button */
.catalyst-directory .cd-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--cd-space-1);
  padding: var(--cd-space-2) var(--cd-space-3);
  background: var(--cd-color-surface);
  border: 1px solid var(--cd-color-border);
  border-radius: 100px;
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-primary);
  font-weight: var(--cd-font-weight-regular);
  line-height: var(--cd-line-height-tight);
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  min-height: 36px;
  min-width: 44px;
  transition:
    background-color var(--cd-duration-fast) var(--cd-easing-standard),
    color var(--cd-duration-fast) var(--cd-easing-standard),
    border-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-chip:hover {
  border-color: var(--cd-color-primary);
  color: var(--cd-color-primary);
}

.catalyst-directory .cd-chip[aria-pressed="true"] {
  background: var(--cd-color-primary);
  border-color: var(--cd-color-primary);
  color: #fff;
  font-weight: var(--cd-font-weight-medium);
}

.catalyst-directory .cd-chip-x,
.catalyst-directory .cd-chip-x svg {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  stroke: #fff;
  color: #fff;
  display: block;
  opacity: 0.8;
}

.catalyst-directory .cd-chip:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

@media (max-width: 639px) {
  .catalyst-directory .cd-filter-row {
    flex-direction: column;
    align-items: stretch;
  }
  .catalyst-directory .cd-filter-row-label {
    white-space: normal;
    min-width: 0;
  }
  .catalyst-directory .cd-filter-chips-wrap {
    width: 100%;
  }
  .catalyst-directory .cd-chip {
    max-width: 100%;
    white-space: normal;
    overflow-wrap: anywhere;
    text-align: left;
  }
}

/* "Clear all" inline link */
.catalyst-directory .cd-filter-clear {
  background: none;
  border: none;
  color: var(--cd-color-link);
  font-size: var(--cd-font-size-sm);
  text-decoration: underline;
  cursor: pointer;
  padding: var(--cd-space-1) var(--cd-space-2);
  white-space: nowrap;
  flex-shrink: 0;
}

.catalyst-directory .cd-filter-clear:hover {
  color: var(--cd-color-link-hover);
}

.catalyst-directory .cd-filter-clear:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}


/* --------------------------------------------------------------------------
   Result Count Bar
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-result-bar {
  display: flex;
  align-items: center;
  padding: var(--cd-space-3) var(--cd-space-4) var(--cd-space-2);
}

.catalyst-directory .cd-result-count {
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
}

.catalyst-directory .cd-active-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cd-space-2);
  padding: 0 var(--cd-space-4) var(--cd-space-2);
}

.catalyst-directory .cd-active-filters .cd-chip {
  background: var(--cd-color-primary);
  border-color: var(--cd-color-primary);
  color: #fff;
  font-weight: var(--cd-font-weight-medium);
}

.catalyst-directory .cd-active-filters-clear {
  background: none;
  border: none;
  padding: var(--cd-space-1) var(--cd-space-2);
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-medium);
  color: var(--cd-color-text-secondary);
  text-decoration: underline;
  cursor: pointer;
  min-height: 0;
  min-width: 0;
}

.catalyst-directory .cd-active-filters-clear:hover {
  color: var(--cd-color-primary);
}

.catalyst-directory .cd-active-filters-clear:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}


/* --------------------------------------------------------------------------
   Tab-scoped search banner

   Shown only when a search arrived scoped to one tab (a Class Finder card
   linking in with ?tab=...&q=...). It has one job the results themselves
   can't do: say out loud that these results are one area's, and hand back
   the way to all of them. Sits directly above .cd-result-bar so the scope
   is read before the count it explains.
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-search-scope-note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--cd-space-2);
  margin: var(--cd-space-4) var(--cd-space-4) 0;
  padding: var(--cd-space-3) var(--cd-space-4);
  border: 1px solid var(--cd-color-border);
  border-left: 4px solid var(--cd-color-primary);
  border-radius: 6px;
  background: var(--cd-color-surface-subtle);
}

.catalyst-directory .cd-scope-note-text {
  margin: 0;
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-primary);
}

.catalyst-directory .cd-scope-note-text strong {
  font-weight: var(--cd-font-weight-medium);
}

.catalyst-directory .cd-scope-note-broaden {
  background: none;
  border: none;
  padding: var(--cd-space-1) var(--cd-space-2);
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-medium);
  color: var(--cd-color-link);
  text-decoration: underline;
  cursor: pointer;
  min-height: 0;
  min-width: 0;
}

.catalyst-directory .cd-scope-note-broaden:hover {
  color: var(--cd-color-primary-hover);
}

.catalyst-directory .cd-scope-note-broaden:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}


/* --------------------------------------------------------------------------
   Card Gallery Grid
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-card-gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--cd-space-6);
  /* The fixed My List badge clearance below the last card row now lives on
     .cd-pagination (always rendered, even as an empty spacer on a single
     page — see below), since pagination is what actually sits last in a
     panel now. This is just the ordinary gap above it. */
  padding: 0 var(--cd-space-4) var(--cd-space-2);
}

@media (min-width: 640px) {
  .catalyst-directory .cd-card-gallery {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  }
}


/* --------------------------------------------------------------------------
   Pagination
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--cd-space-2);
  /* Extra bottom clearance so the controls (or, on a single page, this
     empty spacer) are never hidden behind the always-visible fixed My
     List badge (≈ 44px + 1.25rem ≈ 4rem) — see renderPagination() in
     mcc-program-directory.js. */
  padding: var(--cd-space-4) var(--cd-space-4) calc(var(--cd-space-12) + 4rem);
}

.catalyst-directory .cd-pagination[hidden] {
  display: none;
}

.catalyst-directory .cd-page-numbers {
  display: flex;
  align-items: center;
  gap: var(--cd-space-1);
}

.catalyst-directory .cd-page-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--cd-space-1);
  min-width: 40px;
  height: 40px;
  padding: 0 var(--cd-space-3);
  background: var(--cd-color-surface);
  border: 1px solid var(--cd-color-border);
  border-radius: 6px;
  color: var(--cd-color-text-primary);
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-medium);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: none;
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard),
              border-color var(--cd-duration-fast) var(--cd-easing-standard),
              color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-page-numbers .cd-page-btn {
  padding: 0;
  justify-content: center;
}

.catalyst-directory .cd-page-btn i {
  width: 16px;
  height: 16px;
}

.catalyst-directory .cd-page-btn:hover:not(:disabled) {
  border-color: var(--cd-color-primary);
  color: var(--cd-color-primary);
}

.catalyst-directory .cd-page-btn:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

.catalyst-directory .cd-page-btn.is-current {
  background: var(--cd-color-primary);
  border-color: var(--cd-color-primary);
  color: #fff;
  cursor: default;
}

.catalyst-directory .cd-page-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.catalyst-directory .cd-page-ellipsis {
  color: var(--cd-color-text-secondary);
  padding: 0 var(--cd-space-1);
  user-select: none;
}

@media (max-width: 480px) {
  .catalyst-directory .cd-page-btn--prev span,
  .catalyst-directory .cd-page-btn--next span {
    display: none;
  }
}


/* --------------------------------------------------------------------------
   Program Card
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-card {
  background: var(--cd-color-surface);
  border: 1px solid var(--cd-color-border);
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  cursor: pointer;
  position: relative;
  transition:
    box-shadow var(--cd-duration-fast) var(--cd-easing-standard),
    transform var(--cd-duration-fast) var(--cd-easing-standard);
  animation: cdCardFadeIn var(--cd-duration-fast) var(--cd-easing-decelerate) both;
}

@keyframes cdCardFadeIn {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}

.catalyst-directory .cd-card:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  transform: translateY(-2px);
}

.catalyst-directory .cd-card:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

/* --- Accent rule (replaces the 80px colour block) ---
   A 4px rule at the card top, coloured by division. The card is
   overflow:hidden with an 8px radius, so the rule takes the top corners with
   it. flex-shrink:0 because .cd-card is a flex column and a 4px item is the
   first thing a shrink pass would eat. */
.catalyst-directory .cd-card-accent {
  display: block;
  height: var(--cd-accent-rule);
  background: var(--cd-accent);
  flex-shrink: 0;
}

/* --- Card eyebrow — topic label, division pill, New badge ---
   padding-right clears the absolutely-positioned bookmark button (36px wide
   at right:0.5rem). Without it a long topic runs under the button. */
.catalyst-directory .cd-card-eyebrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cd-space-1) var(--cd-space-2);
  padding-right: 40px;
  min-width: 0;
}

/* Topic label. Sentence case, always — never text-transform: uppercase.
   Some screen readers spell out strings that read as acronyms, and this data
   contains "Traffic Safety School (TSS)" and "ADD-8"; all-caps also measurably
   slows dyslexic readers, worst on the longest labels. It is differentiated
   from the body copy by weight, size and colour instead. */
.catalyst-directory .cd-card-topic {
  font-size: var(--cd-font-size-xs);
  font-weight: var(--cd-font-weight-bold);
  line-height: var(--cd-line-height-tight);
  color: var(--cd-accent-ink);
  min-width: 0;
  overflow-wrap: anywhere;
}

/* --- "New" badge --- */
.catalyst-directory .cd-badge-new {
  display: inline-block;
  background: var(--cd-color-badge-new);
  color: var(--cd-color-badge-new-text);
  font-size: var(--cd-font-size-xs);
  font-weight: var(--cd-font-weight-bold);
  line-height: var(--cd-line-height-tight);
  padding: 2px var(--cd-space-2);
  border-radius: 100px;
  white-space: nowrap;
}

/* --- Bookmark button ---
   It no longer sits on a coloured field, so it can't borrow the band's
   contrast: it carries its own neutral chip. Saved state uses the My List
   accent, not the program's — saved-ness belongs to My List, not the division. */
.catalyst-directory .cd-bookmark-btn {
  position: absolute;
  top: calc(var(--cd-accent-rule) + var(--cd-space-2));
  right: var(--cd-space-2);
  background: var(--cd-color-surface-subtle);
  border: 1px solid var(--cd-color-border);
  border-radius: 50%;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--cd-color-text-secondary);
  z-index: 2;
  transition:
    transform var(--cd-duration-fast) var(--cd-easing-standard),
    background-color var(--cd-duration-fast) var(--cd-easing-standard),
    border-color var(--cd-duration-fast) var(--cd-easing-standard),
    color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-bookmark-btn:hover {
  background: var(--cd-color-border);
  color: var(--cd-color-text-primary);
}

.catalyst-directory .cd-bookmark-btn.is-saved {
  background: var(--cd-color-surface);
  border-color: var(--cd-color-mylist-accent);
  color: var(--cd-color-mylist-accent);
}

.catalyst-directory .cd-bookmark-btn:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

.catalyst-directory .cd-bookmark-btn svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  display: block;
}

@keyframes cdBookmarkPop {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.3); }
  100% { transform: scale(1); }
}

.catalyst-directory .cd-bookmark-btn.pop {
  animation: cdBookmarkPop var(--cd-duration-fast) var(--cd-easing-standard);
}

/* --- Card body --- */
.catalyst-directory .cd-card-body {
  display: flex;
  flex-direction: column;
  gap: var(--cd-space-3);
  padding: var(--cd-space-4) var(--cd-space-4) var(--cd-space-2);
  flex: 1;
}

/* Program name — override app.css h3 sizes within cards */
.catalyst-directory .cd-card-name {
  font-size: var(--cd-font-size-lg);
  font-weight: var(--cd-font-weight-medium);
  color: var(--cd-color-text-primary);
  line-height: var(--cd-line-height-tight);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Description snippet */
.catalyst-directory .cd-card-desc {
  font-size: var(--cd-font-size-base);
  color: var(--cd-color-text-primary);
  line-height: var(--cd-line-height-body);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Metadata row */
.catalyst-directory .cd-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cd-space-1) var(--cd-space-3);
  margin: 0;
  list-style: none;
  padding: 0;
}

.catalyst-directory .cd-card-meta-item {
  display: inline-flex;
  align-items: center;
  gap: var(--cd-space-1);
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
}

.catalyst-directory .cd-card-meta-item svg {
  width: 14px;
  height: 14px;
  stroke: currentColor;
  flex-shrink: 0;
}

.catalyst-directory .cd-card-meta-item i[data-lucide] {
  width: 14px;
  height: 14px;
  display: inline-block;
  flex-shrink: 0;
}

/* Special notice inline callout */
.catalyst-directory .cd-card-notice {
  border: 1px solid #f59e0b;
  background: #fffbeb;
  color: #78350f;
  font-size: var(--cd-font-size-sm);
  padding: var(--cd-space-2) var(--cd-space-3);
  border-radius: 4px;
  display: flex;
  align-items: flex-start;
  gap: var(--cd-space-2);
  line-height: var(--cd-line-height-body);
}

.catalyst-directory .cd-card-notice svg,
.catalyst-directory .cd-card-notice i[data-lucide] {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  margin-top: 2px;
}

/* Section date chips */
.catalyst-directory .cd-section-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cd-space-2);
}

.catalyst-directory .cd-section-chip {
  font-size: var(--cd-font-size-xs);
  padding: 3px var(--cd-space-2);
  border: 1px solid var(--cd-color-border);
  border-radius: 4px;
  background: var(--cd-color-surface-subtle);
  color: var(--cd-color-text-secondary);
  cursor: pointer;
  transition:
    border-color var(--cd-duration-fast) var(--cd-easing-standard),
    color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-section-chip:hover,
.catalyst-directory .cd-section-chip.is-selected {
  border-color: var(--cd-color-primary);
  color: var(--cd-color-primary);
  background: #f0ecfa;
}

/* Card footer CTA */
.catalyst-directory .cd-card-footer {
  padding: var(--cd-space-2) var(--cd-space-4) var(--cd-space-4);
  margin-top: auto;
}

.catalyst-directory .cd-btn-primary {
  display: block;
  width: 100%;
  padding: var(--cd-space-3) var(--cd-space-4);
  background: var(--cd-color-primary);
  color: #fff !important;
  text-align: center;
  border: none;
  border-radius: 4px;
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-bold);
  cursor: pointer;
  text-decoration: none !important;
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-btn-primary:hover {
  background: var(--cd-color-primary-hover);
  color: #fff !important;
}

.catalyst-directory .cd-btn-primary:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

.catalyst-directory .cd-btn-secondary {
  display: block;
  width: 100%;
  padding: var(--cd-space-3) var(--cd-space-4);
  background: transparent;
  color: var(--cd-color-primary) !important;
  text-align: center;
  border: 1px solid var(--cd-color-primary);
  border-radius: 4px;
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-medium);
  cursor: pointer;
  text-decoration: none !important;
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-btn-secondary:hover {
  background: #f0ecfa;
}

.catalyst-directory .cd-btn-secondary:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

.catalyst-directory .cd-reg-closed-link {
  display: block;
  width: 100%;
  padding: var(--cd-space-3) var(--cd-space-4);
  background: transparent;
  color: var(--cd-color-text-secondary) !important;
  text-align: center;
  border: 1px solid var(--cd-color-border);
  border-radius: 4px;
  font-size: var(--cd-font-size-sm);
  text-decoration: none !important;
}


/* --------------------------------------------------------------------------
   Card Variant: Youth Programs — Grade Band Tag
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-grade-tag {
  display: inline-block;
  background: var(--cd-color-green);
  color: #fff;
  font-size: var(--cd-font-size-xs);
  font-weight: var(--cd-font-weight-medium);
  padding: 2px var(--cd-space-3);
  border-radius: 100px;
  align-self: flex-start;
}


/* --------------------------------------------------------------------------
   Card Variant: Career Spark — Cert Banner + Eligibility
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-cert-banner {
  background: #e0f7fa;
  border-left: 3px solid var(--cd-color-teal);
  padding: var(--cd-space-2) var(--cd-space-3);
  font-size: var(--cd-font-size-sm);
  color: #004d5c;
  border-radius: 0 4px 4px 0;
  display: flex;
  align-items: flex-start;
  gap: var(--cd-space-2);
  line-height: var(--cd-line-height-body);
}

.catalyst-directory .cd-cert-banner svg,
.catalyst-directory .cd-cert-banner i[data-lucide] {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  margin-top: 2px;
  stroke: var(--cd-color-teal);
}

.catalyst-directory .cd-eligibility-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.catalyst-directory .cd-eligibility-list li {
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
  padding-left: var(--cd-space-4);
  position: relative;
  margin: 0;
  line-height: var(--cd-line-height-body);
}

.catalyst-directory .cd-eligibility-list li::before {
  content: '•';
  position: absolute;
  left: var(--cd-space-2);
  color: var(--cd-color-teal);
}


/* --------------------------------------------------------------------------
   Skeleton Loading Cards
   -------------------------------------------------------------------------- */
@keyframes cdShimmer {
  0%   { background-position: -600px 0; }
  100% { background-position: 600px 0; }
}

.catalyst-directory .cd-skeleton-card {
  background: var(--cd-color-surface);
  border: 1px solid var(--cd-color-border);
  border-radius: 8px;
  overflow: hidden;
  min-height: 190px;
}

.catalyst-directory .cd-skeleton {
  background: linear-gradient(
    90deg,
    #e8e8e8 25%,
    #f4f4f4 50%,
    #e8e8e8 75%
  );
  background-size: 1200px 100%;
  animation: cdShimmer 1.6s infinite linear;
  border-radius: 4px;
}

/* Matches the real card's 4px accent rule. It used to be an 80px block, which
   promised a treatment the loaded card no longer renders. */
.catalyst-directory .cd-skeleton-band {
  height: var(--cd-accent-rule);
  border-radius: 0;
}

.catalyst-directory .cd-skeleton-line {
  height: 14px;
  margin: 16px 16px 8px;
}

.catalyst-directory .cd-skeleton-line.short {
  width: 55%;
}

/* Stands in for the topic label in the card eyebrow. */
.catalyst-directory .cd-skeleton-line.topic {
  height: 10px;
  width: 40%;
  margin-bottom: 14px;
}


/* --------------------------------------------------------------------------
   Empty State
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-empty-state {
  text-align: center;
  padding: var(--cd-space-16) var(--cd-space-4);
  color: var(--cd-color-text-secondary);
}

.catalyst-directory .cd-empty-state svg,
.catalyst-directory .cd-empty-state i[data-lucide] {
  width: 48px;
  height: 48px;
  stroke: var(--cd-color-text-secondary);
  color: var(--cd-color-text-secondary);
  margin: 0 auto var(--cd-space-4);
  display: block;
}

/* Override app.css h3 margin inside empty state */
.catalyst-directory .cd-empty-state h3 {
  font-size: var(--cd-font-size-lg);
  color: var(--cd-color-text-primary);
  margin: 0 0 var(--cd-space-4);
}

.catalyst-directory .cd-empty-or {
  margin: var(--cd-space-4) 0;
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
}

.catalyst-directory .cd-empty-contact {
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
}

/* Error state */
.catalyst-directory .cd-error-state {
  padding: var(--cd-space-8) var(--cd-space-4);
  text-align: center;
  color: var(--cd-color-error);
  font-size: var(--cd-font-size-sm);
}


/* --------------------------------------------------------------------------
   Card Detail Modal
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 1000;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  /* Hard ceiling: the sheet can never slide under the browser chrome.
     env(safe-area-inset-top) covers the Dynamic Island / notch on newer iPhones
     (≈59px on iPhone 14 Pro Max). 44px is the floor for older devices.
     The modal's max-height:100% then resolves against this padded content box,
     so it is physically impossible for the modal top to clip behind the URL bar. */
  padding-top: max(env(safe-area-inset-top, 0px), 44px);
}

/* Foundation's [hidden] rule has no !important, so we must override at matching specificity */
.catalyst-directory .cd-modal-overlay[hidden] {
  display: none;
}

.catalyst-directory .cd-modal {
  background: var(--cd-color-surface);
  width: 100%;
  /* 100% resolves against the overlay's content-box (viewport height minus the
     padding-top ceiling above), not against vh. This is the correct constraint
     on iOS Safari where vh = layout viewport (includes area behind browser chrome)
     rather than the visible viewport. */
  max-height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 16px 16px 0 0;
  position: relative;
  animation: cdSlideUpModal var(--cd-duration-base) var(--cd-easing-decelerate) both;
}

/* Scrollable modal content area — close button lives outside this so it stays visible */
.catalyst-directory #cd-modal-body {
  overflow-y: auto;
  flex: 1;
  /* min-height: 0 is required. Flex items default to min-height: auto, which
     prevents shrinking below content height. Without this, when session content
     is tall enough to push the total flex column past max-height, the body
     refuses to shrink and the save bar gets clipped by overflow: hidden.
     With min-height: 0 the flex algorithm can properly constrain the body and
     leave the save bar visible at the modal bottom. */
  min-height: 0;
  overscroll-behavior: none;
}

@keyframes cdSlideUpModal {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

/* Modal drag handle (mobile) — touch-action:none lets the swipe-dismiss JS own this target */
.catalyst-directory .cd-modal-handle {
  width: 40px;
  height: 4px;
  background: var(--cd-color-border);
  background-clip: content-box; /* keep fill on the bar only, not the padding tap-target zone */
  border-radius: 2px;
  margin: var(--cd-space-2) auto;
  touch-action: none;
  cursor: grab;
  /* Expand tap target vertically without enlarging the visible bar */
  padding: 10px 0;
  box-sizing: content-box;
}

/* Close button. Same neutral chip as the card bookmark button, and for the
   same reason: with the colour field gone, white-on-translucent-black would be
   a ~1.9:1 glyph floating on white. */
.catalyst-directory .cd-modal-close {
  position: absolute;
  top: var(--cd-space-3);
  right: var(--cd-space-3);
  background: var(--cd-color-surface-subtle);
  border: 1px solid var(--cd-color-border);
  border-radius: 50%;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--cd-color-text-primary);
  cursor: pointer;
  z-index: 3;
  flex-shrink: 0;
}

.catalyst-directory .cd-modal-close:hover {
  background: var(--cd-color-border);
}

.catalyst-directory .cd-modal-close:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

/* --- Modal header (replaces the 100px colour block) ---
   The card treatment translated, not copied: the same 4px accent rule and the
   same sentence-case accent-coloured topic label, but the title is now ink on
   a real surface. The old white-on-colour title needed
   text-shadow: 0 1px 3px to survive an unpredictable field underneath it;
   with the field gone the shadow goes with it. */
.catalyst-directory .cd-modal-accent {
  display: block;
  height: var(--cd-accent-rule);
  background: var(--cd-accent);
}

/* Right padding clears the close button, which is absolutely positioned against
   .cd-modal (not this header): 36px wide + 1px border at right:0.75rem occupies
   the first 50px. 64px leaves it 14px of air. */
.catalyst-directory .cd-modal-heading {
  display: flex;
  flex-direction: column;
  gap: var(--cd-space-1);
  padding: var(--cd-space-4) calc(var(--cd-space-12) + var(--cd-space-4)) 0 var(--cd-space-4);
}

/* Modal topic label — same treatment as .cd-card-topic, so a program's topic
   and colour read identically whichever surface a visitor is on.
   Sentence case, always; see the note on .cd-card-topic. */
.catalyst-directory .cd-modal-topic {
  font-size: var(--cd-font-size-xs);
  font-weight: var(--cd-font-weight-bold);
  line-height: var(--cd-line-height-tight);
  color: var(--cd-accent-ink);
  overflow-wrap: anywhere;
}

/* Override app.css h2 for the modal title. background/padding/text-transform
   are not decoration here — they neutralise `.ge h2` (see the host heading
   neutraliser near the top of this file). Restated at 0,2,0 so this specific
   title wins even if stylesheet load order ever changes. */
.catalyst-directory .cd-modal-title {
  font-size: var(--cd-font-size-xl);
  font-weight: var(--cd-font-weight-bold);
  color: var(--cd-color-text-primary);
  margin: 0;
  line-height: var(--cd-line-height-tight);
  background: none;
  padding: 0;
  text-transform: none;
}

/* Modal content area */
.catalyst-directory .cd-modal-content {
  padding: var(--cd-space-4) var(--cd-space-4) var(--cd-space-6);
  display: flex;
  flex-direction: column;
  gap: var(--cd-space-6);
}

.catalyst-directory .cd-modal-section-heading {
  font-size: var(--cd-font-size-base);
  font-weight: var(--cd-font-weight-medium);
  color: var(--cd-color-text-primary);
  margin: 0 0 var(--cd-space-3);
  border-bottom: 1px solid var(--cd-color-border);
  padding-bottom: var(--cd-space-2);
}

/* Description text */
.catalyst-directory .cd-modal-desc {
  font-size: var(--cd-font-size-base);
  color: var(--cd-color-text-primary);
  line-height: var(--cd-line-height-body);
  margin: 0;
}

/* Special notice block */
.catalyst-directory .cd-modal-notice {
  background: #fffbeb;
  border: 1px solid #f59e0b;
  border-radius: 6px;
  padding: var(--cd-space-4);
  display: flex;
  gap: var(--cd-space-3);
  color: #78350f;
  line-height: var(--cd-line-height-body);
  font-size: var(--cd-font-size-sm);
}

.catalyst-directory .cd-modal-notice svg,
.catalyst-directory .cd-modal-notice i[data-lucide] {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  stroke: #b45309;
  color: #b45309;
  margin-top: 1px;
}

/* Session card within modal */
.catalyst-directory .cd-modal-session {
  border: 1px solid var(--cd-color-border);
  border-radius: 6px;
  padding: var(--cd-space-4);
  display: flex;
  flex-direction: column;
  gap: var(--cd-space-2);
}

.catalyst-directory .cd-modal-session + .cd-modal-session {
  margin-top: var(--cd-space-3);
}

.catalyst-directory .cd-modal-session-date {
  font-weight: var(--cd-font-weight-medium);
  color: var(--cd-color-text-primary);
  font-size: var(--cd-font-size-base);
}

.catalyst-directory .cd-modal-session-detail {
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
  display: flex;
  align-items: center;
  gap: var(--cd-space-2);
  line-height: var(--cd-line-height-tight);
}

.catalyst-directory .cd-modal-session-detail svg,
.catalyst-directory .cd-modal-session-detail i[data-lucide] {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  stroke: currentColor;
}

.catalyst-directory .cd-modal-register-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--cd-space-2);
  margin-top: var(--cd-space-2);
  padding: var(--cd-space-2) var(--cd-space-4);
  background: var(--cd-color-primary);
  color: #fff !important;
  border-radius: 4px;
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-bold);
  text-decoration: none !important;
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-modal-register-btn:hover {
  background: var(--cd-color-primary-hover);
  color: #fff !important;
}

/* Instructor disclosure (details/summary) */
.catalyst-directory .cd-disclosure {
  font-size: var(--cd-font-size-sm);
}

.catalyst-directory .cd-disclosure summary {
  cursor: pointer;
  font-weight: var(--cd-font-weight-medium);
  color: var(--cd-color-link);
  padding: var(--cd-space-2) 0;
  list-style: none;
  user-select: none;
}

.catalyst-directory .cd-disclosure summary::-webkit-details-marker {
  display: none;
}

.catalyst-directory .cd-disclosure summary::after {
  content: ' ▾';
  font-size: var(--cd-font-size-xs);
}

.catalyst-directory .cd-disclosure[open] summary::after {
  content: ' ▴';
}

.catalyst-directory .cd-disclosure summary:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

.catalyst-directory .cd-bio-text {
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
  line-height: var(--cd-line-height-body);
  padding: var(--cd-space-2) 0 var(--cd-space-3);
  margin: 0;
}

/* Modal bottom Save button */
.catalyst-directory .cd-modal-save-btn {
  width: 100%;
  padding: var(--cd-space-3) var(--cd-space-4);
  background: transparent;
  color: var(--cd-color-primary);
  border: 1px solid var(--cd-color-primary);
  border-radius: 4px;
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-medium);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--cd-space-2);
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-modal-save-btn:hover {
  background: #f0ecfa;
}

.catalyst-directory .cd-modal-save-btn.is-saved {
  background: #f0ecfa;
  color: var(--cd-color-primary);
}

.catalyst-directory .cd-modal-save-btn:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

/* Career Spark modal additions */
.catalyst-directory .cd-modal-cert-banner {
  background: #e0f7fa;
  border-left: 3px solid var(--cd-color-teal);
  padding: var(--cd-space-3) var(--cd-space-4);
  font-size: var(--cd-font-size-sm);
  color: #004d5c;
  border-radius: 0 4px 4px 0;
  margin-bottom: var(--cd-space-2);
}

.catalyst-directory .cd-employer-note {
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
  margin-top: var(--cd-space-3);
  padding: var(--cd-space-3);
  background: var(--cd-color-surface-subtle);
  border-radius: 4px;
  line-height: var(--cd-line-height-body);
}

/* Desktop modal — centered sheet */
@media (min-width: 768px) {
  .catalyst-directory .cd-modal-overlay {
    align-items: center;
    /* On desktop the modal is centered, not bottom-anchored. Reset the mobile
       ceiling padding — desktop browsers don't have the same vh/visual-viewport
       mismatch as iOS Safari, and centering already keeps the modal on-screen. */
    padding-top: 0;
  }

  .catalyst-directory .cd-modal {
    width: 100%;
    max-width: 600px;
    max-height: min(88vh, 88dvh); /* dvh = dynamic viewport; vh fallback for older browsers */
    border-radius: 12px;
    animation: cdFadeScaleModal var(--cd-duration-base) var(--cd-easing-decelerate) both;
  }

  .catalyst-directory .cd-modal-handle {
    display: none;
  }
}

@keyframes cdFadeScaleModal {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}


/* --------------------------------------------------------------------------
   Modal sticky save bar
   Lives OUTSIDE #cd-modal-body (the scroll container) as a sibling inside
   .cd-modal, so it is always visible at the modal bottom regardless of
   how far the user has scrolled through the session list.
   flex-shrink:0 prevents the bar from being squeezed by the flex column.
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-modal-save-bar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  padding: var(--cd-space-3) var(--cd-space-4);
  /* Extra bottom padding for iOS home indicator */
  padding-bottom: calc(var(--cd-space-3) + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--cd-color-border);
  background: var(--cd-color-surface);
}

.catalyst-directory .cd-modal-save-bar-btn {
  flex: 1;
  padding: var(--cd-space-3) var(--cd-space-4);
  background: transparent;
  color: var(--cd-color-primary);
  border: 2px solid var(--cd-color-primary);
  border-radius: 4px;
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-medium);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--cd-space-2);
  min-height: 44px;
  transition:
    background-color var(--cd-duration-fast) var(--cd-easing-standard),
    color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-modal-save-bar-btn:hover {
  background: #f0ecfa;
}

.catalyst-directory .cd-modal-save-bar-btn.is-saved {
  background: var(--cd-color-primary);
  color: #fff;
  border-color: var(--cd-color-primary);
}

.catalyst-directory .cd-modal-save-bar-btn.is-saved:hover {
  background: var(--cd-color-primary-hover);
}

.catalyst-directory .cd-modal-save-bar-btn:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}


/* --------------------------------------------------------------------------
   My List — Floating Badge
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-mylist-badge {
  position: absolute;
  bottom: var(--cd-space-6);
  right: var(--cd-space-4);
  background: var(--cd-color-mylist-accent);
  color: #fff;
  border: none;
  border-radius: 100px;
  padding: var(--cd-space-2) var(--cd-space-4);
  display: inline-flex;
  align-items: center;
  gap: var(--cd-space-2);
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-medium);
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  z-index: 100;
  transition: transform var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-mylist-badge:hover {
  transform: translateY(-2px);
}

.catalyst-directory .cd-mylist-badge:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 2px;
}

.catalyst-directory .cd-mylist-badge svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: currentColor;
}

.catalyst-directory .cd-mylist-badge-count {
  background: rgba(255, 255, 255, 0.3);
  border-radius: 100px;
  padding: 0 var(--cd-space-2);
  font-size: var(--cd-font-size-xs);
  font-weight: var(--cd-font-weight-bold);
  min-width: 1.25rem;
  text-align: center;
}

@keyframes cdBadgePop {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.2); }
  100% { transform: scale(1); }
}

.catalyst-directory .cd-mylist-badge.pop .cd-mylist-badge-count {
  animation: cdBadgePop var(--cd-duration-fast) var(--cd-easing-standard);
}


/* --------------------------------------------------------------------------
   My List — Tray
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-mylist-tray {
  /* Fixed to the viewport so it stays above the fixed badge regardless of
     scroll position. z-index 901 puts it one layer above the badge (900). */
  position: fixed;
  /* badge-inset-bottom (1.25rem) + badge height (≈2.75rem) + gap (0.5rem) */
  bottom: calc(var(--cd-mylist-badge-inset-bottom) + env(safe-area-inset-bottom, 0px) + 3.5rem);
  right: var(--cd-space-4);
  width: min(360px, calc(100vw - 2rem));
  max-height: 480px;
  overflow-y: auto;
  background: var(--cd-color-surface);
  border: 1px solid var(--cd-color-border);
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
  z-index: 901;
  animation: cdSlideTray var(--cd-duration-base) var(--cd-easing-decelerate) both;
}

/* Companion rule: [hidden] must win over the display value above */
.catalyst-directory .cd-mylist-tray[hidden] {
  display: none;
}

@keyframes cdSlideTray {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

.catalyst-directory .cd-mylist-tray-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--cd-space-3) var(--cd-space-4);
  border-bottom: 1px solid var(--cd-color-border);
  position: sticky;
  top: 0;
  background: var(--cd-color-surface);
}

.catalyst-directory .cd-mylist-tray-title {
  font-weight: var(--cd-font-weight-medium);
  font-size: var(--cd-font-size-base);
}

.catalyst-directory .cd-mylist-tray-clear {
  background: none;
  border: none;
  color: var(--cd-color-link);
  font-size: var(--cd-font-size-sm);
  cursor: pointer;
  text-decoration: underline;
}

.catalyst-directory .cd-mylist-tray-clear:hover {
  color: var(--cd-color-link-hover);
}

.catalyst-directory .cd-mylist-items {
  padding: var(--cd-space-2) 0;
}

.catalyst-directory .cd-mylist-item {
  display: flex;
  align-items: flex-start;
  gap: var(--cd-space-3);
  padding: var(--cd-space-3) var(--cd-space-4);
  border-bottom: 1px solid var(--cd-color-border);
  cursor: pointer;
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-mylist-item:hover {
  background: var(--cd-color-surface-alt);
}

.catalyst-directory .cd-mylist-item:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: -2px;
}

.catalyst-directory .cd-mylist-item:last-child {
  border-bottom: none;
}

.catalyst-directory .cd-mylist-item-info {
  flex: 1;
  min-width: 0;
}

.catalyst-directory .cd-mylist-item-name {
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-medium);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--cd-color-text-primary);
}

.catalyst-directory .cd-mylist-item-meta {
  font-size: var(--cd-font-size-xs);
  color: var(--cd-color-text-secondary);
  margin-top: var(--cd-space-1);
}

.catalyst-directory .cd-mylist-item-actions {
  display: flex;
  align-items: center;
  gap: var(--cd-space-2);
  flex-shrink: 0;
}

.catalyst-directory .cd-mylist-item-register {
  display: inline-block;
  margin-top: var(--cd-space-2);
  padding: var(--cd-space-1) var(--cd-space-3);
  background: var(--cd-color-primary);
  color: #fff !important;
  font-size: var(--cd-font-size-xs);
  font-weight: var(--cd-font-weight-medium);
  text-decoration: none !important;
  border-radius: var(--cd-radius-sm);
  white-space: nowrap;
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-mylist-item-register:hover {
  background: var(--cd-color-primary-hover);
}

.catalyst-directory .cd-mylist-remove {
  background: none;
  border: none;
  color: var(--cd-color-text-secondary);
  cursor: pointer;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  flex-shrink: 0;
  font-size: 1rem;
  line-height: 1;
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-mylist-remove:hover {
  background: #fee2e2;
  color: var(--cd-color-error);
}

.catalyst-directory .cd-mylist-remove:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

.catalyst-directory .cd-mylist-empty-msg {
  padding: var(--cd-space-6) var(--cd-space-4);
  text-align: center;
  font-size: var(--cd-font-size-sm);
  color: var(--cd-color-text-secondary);
  line-height: var(--cd-line-height-body);
}


/* --------------------------------------------------------------------------
   Search Bar — Inline search field above the tab strip
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-search-bar {
  display: flex;
  align-items: center;
  gap: var(--cd-space-2);
  margin: var(--cd-space-3) var(--cd-space-4);
  padding: var(--cd-space-1) var(--cd-space-2) var(--cd-space-1) var(--cd-space-3);
  background: var(--cd-color-surface);
  border: 1.5px solid var(--cd-color-border);
  border-radius: 10px;
  transition: border-color var(--cd-duration-fast) var(--cd-easing-standard),
              box-shadow var(--cd-duration-fast) var(--cd-easing-standard);
}

/* Focus state — border elevates to primary + soft glow, now on the shell */
.catalyst-directory .cd-search-bar:focus-within {
  border-color: var(--cd-color-primary);
  box-shadow: 0 0 0 3px rgba(75, 49, 144, 0.12);
}

/* Icon — always visible, shrinks font color with bar state */
.catalyst-directory .cd-search-bar-icon {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  color: var(--cd-color-text-secondary);
  transition: color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-search-bar:focus-within .cd-search-bar-icon {
  color: var(--cd-color-primary);
}

/* The actual input — shell now owns border/surface/focus; this is a bare field */
.catalyst-directory .cd-search-input {
  flex: 1;
  min-width: 0;
  margin: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  padding: var(--cd-space-2) 0;
  outline: none;
  /* 18px+ prevents iOS Safari auto-zoom on input focus */
  font-size: 18px;
  font-family: inherit;
  color: var(--cd-color-text-primary);
  -webkit-appearance: none;
  appearance: none;
  /* Minimum touch target height for mobile */
  min-height: 40px;
}

.catalyst-directory .cd-search-input::placeholder {
  color: var(--cd-color-text-secondary);
}

/* Remove browser default clear button — custom X button handles clearing */
.catalyst-directory .cd-search-input::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

/* Clear (X) and Commit (↵) buttons inside the bar */
.catalyst-directory .cd-search-clear,
.catalyst-directory .cd-search-commit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  min-height: 0;
  margin: 0;
  padding: 0;
  background: var(--cd-color-surface-subtle);
  border: 1px solid var(--cd-color-border);
  border-radius: 8px;
  color: var(--cd-color-text-secondary);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard),
              color var(--cd-duration-fast) var(--cd-easing-standard),
              border-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-search-clear:hover {
  background: var(--cd-color-surface-subtle);
  color: var(--cd-color-text-primary);
}

.catalyst-directory .cd-search-commit {
  color: var(--cd-color-primary);
}

.catalyst-directory .cd-search-commit:hover {
  background: rgba(75, 49, 144, 0.08);
}

.catalyst-directory .cd-search-clear:focus-visible,
.catalyst-directory .cd-search-commit:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

/* Companion [hidden] rules — must win over display:flex above */
.catalyst-directory .cd-search-clear[hidden],
.catalyst-directory .cd-search-commit[hidden] {
  display: none;
}

/* When a search query is active: tint shell border to signal committed state */
.catalyst-directory.has-search .cd-search-bar {
  border-color: var(--cd-color-primary);
  box-shadow: 0 0 0 2px rgba(75, 49, 144, 0.08);
}





@media (prefers-reduced-motion: reduce) {
  .catalyst-directory .cd-search-bar-icon,
  .catalyst-directory .cd-search-input,
  .catalyst-directory .cd-search-clear,
  .catalyst-directory .cd-search-commit {
    transition-duration: 0ms !important;
  }
}


/* --------------------------------------------------------------------------
   Filter Collapse Toggle + Collapsible Panel
   -------------------------------------------------------------------------- */
.catalyst-directory .cd-filters-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--cd-space-2);
  width: auto;
  margin: var(--cd-space-3) var(--cd-space-4);
  padding: var(--cd-space-2) var(--cd-space-3);
  background: var(--cd-color-surface-subtle);
  border: 1px solid var(--cd-color-border);
  border-radius: 8px;
  text-align: left;
  font-size: var(--cd-font-size-sm);
  font-weight: var(--cd-font-weight-medium);
  color: var(--cd-color-text-primary);
  cursor: pointer;
  min-height: 40px;
  transition: background-color var(--cd-duration-fast) var(--cd-easing-standard),
              border-color var(--cd-duration-fast) var(--cd-easing-standard),
              color var(--cd-duration-fast) var(--cd-easing-standard);
}

.catalyst-directory .cd-filters-toggle::after {
  content: '';
  width: 0.45rem;
  height: 0.45rem;
  margin-left: var(--cd-space-1);
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform var(--cd-duration-base) var(--cd-easing-standard);
}

@media (prefers-reduced-motion: reduce) {
  .catalyst-directory .cd-filters-toggle::after {
    transition-duration: 0ms !important;
  }
}

.catalyst-directory .cd-filters-toggle:hover {
  background: var(--cd-color-surface-subtle);
  color: var(--cd-color-text-primary);
}

.catalyst-directory .cd-filters-toggle[aria-expanded="true"] {
  background: rgba(75, 49, 144, 0.06);
  border-color: var(--cd-color-primary);
  color: var(--cd-color-primary);
}

.catalyst-directory .cd-filters-toggle[aria-expanded="true"]::after {
  transform: translateY(1px) rotate(-135deg);
}

.catalyst-directory .cd-filters-toggle:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 2px;
}

.catalyst-directory .cd-filters-toggle svg {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  stroke: currentColor;
}

/* Numeric badge showing active filter count */
.catalyst-directory .cd-filters-toggle-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--cd-color-primary);
  color: #fff;
  font-size: var(--cd-font-size-xs);
  font-weight: var(--cd-font-weight-bold);
  border-radius: 100px;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 var(--cd-space-1);
  margin-left: var(--cd-space-1);
}

/* Companion [hidden] rule: must win over display:inline-flex above */
.catalyst-directory .cd-filters-toggle-badge[hidden] {
  display: none;
}

/* Collapsible filter panel */
.catalyst-directory .cd-filters-collapse {
  overflow: hidden;
}

/* Companion [hidden] rule */
.catalyst-directory .cd-filters-collapse[hidden] {
  display: none;
}


/* --------------------------------------------------------------------------
   Unified Search Results Panel
   -------------------------------------------------------------------------- */

/* Companion [hidden] rule: must win over .cd-tab-panel.is-active display:block */
.catalyst-directory #cd-search-results-panel[hidden] {
  display: none;
}

/* Division label pill — identifies which division a card belongs to
   when shown in the unified cross-tab search results view */
.catalyst-directory .cd-card-division-label {
  display: inline-block;
  font-size: var(--cd-font-size-xs);
  font-weight: var(--cd-font-weight-medium);
  padding: 2px var(--cd-space-2);
  border-radius: 100px;
  background: var(--cd-color-surface-subtle);
  border: 1px solid var(--cd-color-border);
  color: var(--cd-color-text-secondary);
  line-height: var(--cd-line-height-tight);
  white-space: nowrap;
}


/* ==========================================================================
   Back-to-top FAB
   Circular ↑ button that appears once the user scrolls past the component's
   tab strip. Lives at document.body (moved by JS, same pattern as the My List
   badge) so position:fixed is immune to CMS ancestor CSS transforms.

   Positioned directly above the My List badge on the right side:
   bottom = badge-bottom (1.25rem) + badge-height (≈2.75rem) + gap (0.5rem)
   z-index 899 — one below the badge (900) so badge always reads on top.
   ========================================================================== */
.cd-back-to-top {
  /* Self-contained tokens */
  --cd-color-primary:    #4b3190;
  --cd-color-focus-ring: #4b3190;
  --cd-duration-fast:    150ms;
  --cd-duration-base:    200ms;
  --cd-easing-standard:  cubic-bezier(0.4, 0, 0.2, 1);

  position: fixed;
  /* badge bottom (1.25rem) + badge height (≈2.75rem) + gap (0.5rem) */
  bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px) + 2.75rem + 0.5rem);
  right: 1rem;
  z-index: 899;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid var(--cd-color-primary);
  background: #fff;
  color: var(--cd-color-primary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
  transition:
    opacity var(--cd-duration-base) var(--cd-easing-standard),
    transform var(--cd-duration-base) var(--cd-easing-standard),
    background-color var(--cd-duration-fast) var(--cd-easing-standard);
}

.cd-back-to-top.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

.cd-back-to-top:hover {
  background: var(--cd-color-primary);
  color: #fff;
}

.cd-back-to-top:focus-visible {
  outline: 3px solid var(--cd-color-focus-ring);
  outline-offset: 3px;
}

.cd-back-to-top svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  flex-shrink: 0;
}

@media (prefers-reduced-motion: reduce) {
  .cd-back-to-top {
    transition-duration: 0ms !important;
  }
}


/* ==========================================================================
   My List badge — fixed viewport position (element moved to document.body by JS)
   Self-contained design tokens because .catalyst-directory inherited values
   are not available once the element is a child of <body>.

   z-index: 900 — clears typical CMS nav layers (100–400), sits below the
   modal overlay (1000) and the tray (901) so the modal always appears on top.

   The badge is shown at all times (even when the list is empty) so first-time
   visitors immediately understand the "My List" convenience feature is there.
   ========================================================================== */
.cd-mylist-badge {
  /* Self-contained tokens */
  --cd-color-mylist-accent: #4b3190;
  --cd-color-focus-ring:    #4b3190;
  --cd-duration-fast:       150ms;
  --cd-easing-standard:     cubic-bezier(0.4, 0, 0.2, 1);

  position: fixed;
  bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
  right: 1rem;
  z-index: 900;
  background: var(--cd-color-mylist-accent);
  color: #fff;
  border: none;
  border-radius: 100px;
  padding: 0.5rem 1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.28);
  min-height: 44px;
  transition:
    transform 150ms cubic-bezier(0.4, 0, 0.2, 1),
    box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* [hidden] companion — must win over `display: inline-flex` above */
.cd-mylist-badge[hidden] {
  display: none;
}

.cd-mylist-badge:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.32);
}

.cd-mylist-badge:focus-visible {
  outline: 3px solid rgba(255, 255, 255, 0.85);
  outline-offset: 3px;
}

/* Subtle visual when no items are saved — badge is still fully present
   so first-time visitors see the feature exists. */
.cd-mylist-badge.is-empty {
  opacity: 0.82;
}

.cd-mylist-badge svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: currentColor;
  flex-shrink: 0;
}

.cd-mylist-badge .cd-mylist-badge-count {
  background: rgba(255, 255, 255, 0.3);
  border-radius: 100px;
  padding: 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  min-width: 1.25rem;
  text-align: center;
}

/* Pop animation — reuses global @keyframes cdBadgePop declared in scoped block above */
.cd-mylist-badge.pop .cd-mylist-badge-count {
  animation: cdBadgePop 150ms cubic-bezier(0.4, 0, 0.2, 1);
}

@media (prefers-reduced-motion: reduce) {
  .cd-mylist-badge {
    transition-duration: 0ms !important;
  }
  .cd-mylist-badge.pop .cd-mylist-badge-count {
    animation-duration: 0ms !important;
  }
}
