/* Shared searchable-switcher component — powers BOTH the Products switcher
 * (_product_switcher.html) AND the Subjects switcher (_subject_switcher.html).
 *
 * Class-based (BEM-ish `.product-switcher__*`) so BOTH instances share the
 * exact layout/appearance while carrying distinct ids (product-* vs subject-*);
 * accents are driven by `.is-accent-<token>` custom-property rules, NOT fragile
 * positional/index selectors. The compiled tailwind-main.css omits many of the
 * utility classes the markup would otherwise need (backdrop-blur, arbitrary
 * widths, slim scrollbars), so this file supplies the full layout + glass
 * appearance and renders correctly regardless of Tailwind's build state.
 *
 * No inline styles / scripts anywhere — CSP-safe. Colour contrast targets
 * WCAG 2.2 AA on the dark (#0b1020-ish) glass panel.
 */

/* Two adjacent switchers (Products + Subjects) share one navbar flex group so
 * `justify-between` can't push them apart; this gap survives even when the
 * compiled Tailwind omits `gap-2`. */
.nav-switcher-group {
  align-items: center;
  gap: 0.5rem;
}

/* ---------------------------------------------------------------------------
 * Accent tokens — one rule-set per allowed accent drives `--accent`
 * (a bright hue for icons/borders/rings) + `--accent-soft` (translucent fill).
 * ------------------------------------------------------------------------- */
.is-accent-green  { --accent: #34d399; --accent-soft: rgba(52, 211, 153, 0.16); }
.is-accent-purple { --accent: #a78bfa; --accent-soft: rgba(167, 139, 250, 0.16); }
.is-accent-blue   { --accent: #60a5fa; --accent-soft: rgba(96, 165, 250, 0.16); }
.is-accent-amber  { --accent: #fbbf24; --accent-soft: rgba(251, 191, 36, 0.16); }
.is-accent-pink   { --accent: #f472b6; --accent-soft: rgba(244, 114, 182, 0.16); }
.is-accent-teal   { --accent: #2dd4bf; --accent-soft: rgba(45, 212, 191, 0.16); }
.is-accent-slate  { --accent: #94a3b8; --accent-soft: rgba(148, 163, 184, 0.16); }

/* Sensible fallback if an item somehow lacks an accent class.
 *
 * The guard on the drawer arm is load-bearing, not defensive noise. This
 * rule sits AFTER the `.is-accent-*` palette above and matches at the same
 * (0,1,0) specificity, so an unguarded `.mobile-nav-product` wins on source
 * order and overrides EVERY explicit accent. MEASURED in the open drawer:
 * `is-accent-blue`, `is-accent-purple`, `is-accent-amber`, `is-accent-teal`
 * and `is-accent-pink` rows ALL computed `--accent: #34d399`. The accent
 * system had been inert on this surface for its whole life; nothing looked
 * broken, because a uniformly green drawer is a plausible design.
 *
 * `:not([class*="is-accent-"])` is (0,2,0) but only ever MATCHES an item
 * that genuinely lacks an accent class, so it restores exactly the stated
 * intent instead of competing with the palette.
 *
 * The `.product-switcher__item` arm is DELIBERATELY left unguarded: the
 * desktop dropdown carries the identical defect, and recolouring it is a
 * separate visual decision from decluttering the mobile drawer.
 *
 * The two arms stay in ONE grouped head rather than being split into two
 * rules. Splitting them created a second top-level `.product-switcher__item`
 * rule ABOVE the one that carries the desktop item's `min-height`, and
 * `test_product_switcher_a11y.py` extracts the FIRST rule with that head —
 * so it read the accent rule, found no `min-height`, and reported the
 * desktop 44px tap target as missing. A selector list evaluates each arm
 * independently, so grouping costs nothing: `.product-switcher__item` still
 * matches everything at (0,1,0), unchanged. */
.product-switcher__item,
.mobile-nav-product:not([class*="is-accent-"]) {
  --accent: #34d399;
  --accent-soft: rgba(52, 211, 153, 0.16);
}

/* ---------------------------------------------------------------------------
 * Container + trigger
 * ------------------------------------------------------------------------- */
.product-switcher {
  position: relative;
}

.product-switcher__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;         /* 44px tap target */
  padding: 0.5rem 1rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: #ffffff;
  background-color: rgba(14, 22, 80, 0.6);
  border: 1px solid rgba(45, 58, 130, 0.9);
  border-radius: 0.625rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease;
}

.product-switcher__trigger:hover {
  background-color: rgba(27, 38, 102, 0.9);
  border-color: rgba(52, 211, 153, 0.55);
}

.product-switcher__trigger:focus-visible {
  /* SC 1.4.11 focus-indicator contrast: composited over the bg-gray-800 navbar
   * a 0.45-alpha mint ring only reached 2.70:1. 0.9 alpha -> 6.47:1 (>= 3:1),
   * an unambiguous focus indicator. */
  outline: none;
  box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.9);
}

.product-switcher__trigger-glyph {
  width: 1.05rem;
  height: 1.05rem;
  color: #6ee7b7;
  flex-shrink: 0;
}

.product-switcher__chevron {
  width: 1rem;
  height: 1rem;
  margin-inline-start: 0.125rem;
  color: #cbd5e1;
  flex-shrink: 0;
  transition: transform 0.2s ease;
}

.product-switcher__trigger[aria-expanded="true"] .product-switcher__chevron {
  transform: rotate(180deg);
}

/* ---------------------------------------------------------------------------
 * Full-screen frosted backdrop behind the open dropdown.
 * ------------------------------------------------------------------------- */
#product-dropdown-backdrop {
  position: fixed;
  inset: 0;
  z-index: 40;
  background-color: rgba(7, 12, 46, 0.6);
  -webkit-backdrop-filter: blur(24px);
  backdrop-filter: blur(24px);
}

#product-dropdown-backdrop.hidden {
  display: none;
}

/* ---------------------------------------------------------------------------
 * Dropdown panel (glass).
 * ------------------------------------------------------------------------- */
#product-dropdown,
.product-switcher__panel {
  position: absolute;
  inset-inline-start: 0;
  top: calc(100% + 0.75rem);
  width: 26rem;
  max-width: calc(100vw - 2rem);
  z-index: 50;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 1rem;
  border: 1px solid rgba(27, 38, 102, 0.85);
  background-image: linear-gradient(
    to bottom,
    rgba(7, 12, 46, 0.94),
    rgba(4, 7, 31, 0.97)
  );
  -webkit-backdrop-filter: blur(24px);
  backdrop-filter: blur(24px);
  box-shadow:
    0 25px 50px -12px rgba(0, 0, 0, 0.6),
    0 0 0 1px rgba(255, 255, 255, 0.05);
  transform-origin: top;
  animation: product-switcher-in 0.16s ease-out;
}

@keyframes product-switcher-in {
  from { opacity: 0; transform: translateY(-0.375rem) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ---------------------------------------------------------------------------
 * Sticky search header.
 * ------------------------------------------------------------------------- */
.product-switcher__search {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.75rem 0.875rem;
  border-bottom: 1px solid rgba(27, 38, 102, 0.6);
  background-image: linear-gradient(
    to right,
    rgba(52, 211, 153, 0.10),
    rgba(96, 165, 250, 0.10)
  );
}

.product-switcher__search-icon {
  width: 1.125rem;
  height: 1.125rem;
  color: #94a3b8;
  flex-shrink: 0;
}

.product-switcher__search-input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 2.5rem;
  padding: 0.375rem 0.25rem;
  font-size: 1rem;              /* >=16px: no iOS zoom */
  color: #f8fafc;
  background: transparent;
  border: none;
  outline: none;
}

.product-switcher__search-input::placeholder {
  color: #94a3b8;
}

.product-switcher__search-input:focus-visible {
  outline: none;
}

.product-switcher__search:focus-within {
  box-shadow: inset 0 0 0 1px rgba(52, 211, 153, 0.5);
}

/* ---------------------------------------------------------------------------
 * Scrollable list.
 * ------------------------------------------------------------------------- */
.product-switcher__list {
  list-style: none;
  margin: 0;
  padding: 0.375rem;
  overflow-y: auto;
  max-height: min(60vh, 30rem);
  scrollbar-width: thin;
  scrollbar-color: rgba(148, 163, 184, 0.5) transparent;
}

.product-switcher__list::-webkit-scrollbar {
  width: 8px;
}

.product-switcher__list::-webkit-scrollbar-thumb {
  background-color: rgba(148, 163, 184, 0.45);
  border-radius: 9999px;
}

.product-switcher__list::-webkit-scrollbar-track {
  background: transparent;
}

.product-switcher__row {
  margin: 0;
  padding: 0;
}

/* ---------------------------------------------------------------------------
 * Compact item rows.
 * ------------------------------------------------------------------------- */
.product-switcher__item {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0.625rem 0.75rem;
  min-height: 2.75rem;         /* 44px tap target */
  color: #f1f5f9;
  text-decoration: none;
  border-radius: 0.625rem;
  border-inline-start: 2px solid transparent;
  transition:
    background-color 0.15s ease,
    border-color 0.15s ease;
}

/* Hover + JS-driven "active option" share the same highlight. */
.product-switcher__item:hover,
.product-switcher__item.is-active {
  background-color: var(--accent-soft);
  border-inline-start-color: var(--accent);
}

.product-switcher__item:focus-visible,
.product-switcher__item.is-active {
  outline: none;
  box-shadow: inset 0 0 0 1px var(--accent);
}

/* Current-subject marker ("you are here" on the Subjects switcher). Shares the
 * `is-active` class the roving keyboard highlight uses (the client re-seeds it
 * on open so it persists), and a thicker accent bar + solid accent name make
 * the currently-open subject stand out from its siblings. */
.product-switcher__item.is-active {
  border-inline-start-width: 3px;
}

.product-switcher__item.is-active .product-switcher__item-name {
  color: var(--accent);
}

.product-switcher__item-icon {
  flex-shrink: 0;
  width: 2.25rem;
  height: 2.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.625rem;
  color: var(--accent);
  background-color: var(--accent-soft);
  border: 1px solid var(--accent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.product-switcher__icon-svg {
  width: 1.15rem;
  height: 1.15rem;
}

.product-switcher__item-text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
}

.product-switcher__item-name {
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.25;
  color: #f8fafc;
}

.product-switcher__item-subtitle {
  font-size: 0.75rem;
  line-height: 1.3;
  color: #cbd5e1;              /* AA on dark glass */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.product-switcher__item-chevron {
  flex-shrink: 0;
  width: 1rem;
  height: 1rem;
  color: #64748b;
  transition:
    color 0.15s ease,
    transform 0.15s ease;
}

.product-switcher__item:hover .product-switcher__item-chevron,
.product-switcher__item.is-active .product-switcher__item-chevron {
  color: var(--accent);
  transform: translateX(2px);
}

/* ---------------------------------------------------------------------------
 * Empty state + live status.
 * ------------------------------------------------------------------------- */
.product-switcher__empty {
  margin: 0;
  padding: 1.5rem 1rem;
  text-align: center;
  font-size: 0.875rem;
  color: #94a3b8;
}

.product-switcher__status {
  margin: 0;
  padding: 0.375rem 0.875rem 0.625rem;
  font-size: 0.6875rem;
  color: #94a3b8;
  border-top: 1px solid rgba(27, 38, 102, 0.5);
}

/* ---------------------------------------------------------------------------
 * Mobile drawer product rows (reuses the accent tokens above).
 * ------------------------------------------------------------------------- */

/* Small muted section heading in the mobile drawer ("Products", "Subjects").
 * Uppercase + tracked, consistent with the drawer's muted text.
 *
 * STICKY, so the group heading stays on screen while a 14-subject list
 * scrolls under it — the reader never loses track of which group a row
 * belongs to. A sticky heading MUST paint an opaque background or the
 * rows scroll visibly through the letters; the background is a token, not
 * a literal, so the light palette flips with everything else. */
.mobile-nav-section-label {
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 0.375rem 0 0.125rem;
  padding: 0.375rem 0.25rem 0.25rem;
  /* Bleed back across the scroll container's focus-ring gutter, or rows
   * scroll visibly through a sliver either side of the opaque label. */
  margin-inline: calc(-1 * var(--kais-drawer-body-gutter, 0px));
  padding-inline: calc(0.25rem + var(--kais-drawer-body-gutter, 0px));
  background: var(--kais-drawer-bg-1, #070c2e);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--kais-drawer-muted, #94a3b8);
}

.mobile-nav-product {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.mobile-nav-product__icon {
  flex-shrink: 0;
  width: 1.75rem;
  height: 1.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.5rem;
  color: var(--accent);
  background-color: var(--accent-soft);
  border: 1px solid var(--accent);
}

.mobile-nav-product__icon .product-switcher__icon-svg {
  width: 1rem;
  height: 1rem;
}

.mobile-nav-product__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}

.mobile-nav-product__name {
  font-weight: 600;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

/* The description WRAPS. It used to be `white-space: nowrap` + ellipsis,
 * which cut all four product descriptions mid-word on a 384px phone
 * ("Adaptive AI tutoring across every su…") — a row that reads as broken
 * rather than abbreviated. `line-clamp: 2` bounds it so a long
 * translation cannot grow the row without limit; the -webkit-box pair is
 * the fallback engines still require. */
.mobile-nav-product__subtitle {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  margin-top: 0.0625rem;
  font-size: 0.6875rem;
  line-height: 1.35;
  color: var(--kais-drawer-text-2, #cbd5e1);
  overflow-wrap: anywhere;
}

/* --- Compact variant: subject rows ---------------------------------------
 * A subject's "subtitle" is its abbreviation, so the stacked two-line
 * treatment printed the same word twice ("Python" over "Python") fourteen
 * times over — the drawer's single largest source of scroll. Compact rows
 * put the name and a quiet trailing chip on ONE line. The abbreviation
 * stays in the DOM: it is the desktop switcher's search token and a real
 * shorthand for the long titles ("Introduction To Transformers With
 * Pytorch" / "ITT-pt"). */
.mobile-nav-product--compact .mobile-nav-product__text {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
}

/* The name WRAPS rather than ellipsising: it is the row's primary label,
 * and "Introduction To Transformers With Pytorch" does not fit one line
 * beside its chip at 320px (measured). Only the two or three longest
 * subjects take a second line. */
.mobile-nav-product--compact .mobile-nav-product__name {
  min-width: 0;
  flex: 1 1 auto;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* The chip is NEUTRAL, not accented. `--accent` is a single fixed hue with
 * no light variant, so `--accent` on `--accent-soft` measured 7.12:1 on the
 * dark drawer and 1.64:1 on the light one (painted pixels, 384px) — a
 * light-theme half-flip that no token sweep catches, because both halves
 * ARE tokens. The row's accent still reads off the icon beside it, which
 * is a graphic, not body text. */
.mobile-nav-product--compact .mobile-nav-product__subtitle {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  margin-top: 0;
  padding: 0.0625rem 0.375rem;
  border-radius: 999px;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.4;
  color: var(--kais-drawer-muted, #94a3b8);
  background-color: var(--kais-drawer-veil-3, rgba(255, 255, 255, 0.06));
  border: 1px solid var(--kais-drawer-border-soft, rgba(27, 38, 102, 0.5));
  white-space: nowrap;
}

/* --- The subject icon is an ACCENT PIP, not a glyph ----------------------
 * MEASURED in the open drawer: 12 icons, 4 UNIQUE shapes. Every subject row
 * carried the SAME open-book mark — `_subject_icon.html` says so of itself
 * ("a single static open-book mark ... never keyed on a catalog value") —
 * so eight to fourteen identical 24px drawings stacked vertically, carrying
 * no information whatever and forming the drawer's largest block of visual
 * noise.
 *
 * The per-subject ACCENT is the thing that actually distinguishes one row
 * from the next, so the boxed glyph collapses to a 10px accent pip: the
 * colour survives, the repeated drawing does not, and the 14px of width it
 * gives back lets fewer long subject names wrap to a second line.
 *
 * Scoped to `.mobile-nav-product--compact`, which only the mobile drawer's
 * subject rows carry. The DESKTOP Subjects dropdown paints from
 * `.product-switcher__item-icon` — a disjoint class — and keeps its icon;
 * doing this in the SHARED `_subject_icon.html` instead would have taken
 * the desktop glyph with it.
 *
 * The pip is decorative: its span is `aria-hidden="true"` and the row's
 * accessible name is the visible subject text beside it. */
.mobile-nav-product--compact .mobile-nav-product__icon {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 999px;
  /* Solid accent, not the translucent `--accent-soft` wash the glyph box
   * used — at 10px a 16%-alpha fill is invisible. Token with a fallback:
   * a literal here would be invisible to the light-theme token sweep. */
  background-color: var(--accent, #34d399);
  border: 0;
}

/* The repeated open-book mark itself. Hidden rather than deleted from
 * `_subject_icon.html`, so the desktop switcher keeps rendering it from the
 * one shared include and the two surfaces cannot drift apart. */
.mobile-nav-product--compact .mobile-nav-product__icon .product-switcher__icon-svg {
  display: none;
}

/* ---------------------------------------------------------------------------
 * Utility: honour the [hidden] attribute even when display utilities load.
 * ------------------------------------------------------------------------- */
[hidden] {
  display: none !important;
}

/* ---------------------------------------------------------------------------
 * Reduced motion: kill entrance animation + transforms/transitions.
 * ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  #product-dropdown,
  .product-switcher__panel {
    animation: none;
  }

  .product-switcher__trigger,
  .product-switcher__chevron,
  .product-switcher__item,
  .product-switcher__item-chevron {
    transition: none;
  }

  .product-switcher__trigger[aria-expanded="true"] .product-switcher__chevron {
    transform: none;
  }

  .product-switcher__item:hover .product-switcher__item-chevron,
  .product-switcher__item.is-active .product-switcher__item-chevron {
    transform: none;
  }
}

/* ===========================================================================
 * Subjects switcher — master/detail hover+active flyout (SUBJECTS ONLY).
 *
 * A pure-CSS, CSP-safe detail panel that reveals each subject's tagline +
 * description + a static "5 AI teachers per topic" line to the RIGHT of the
 * dropdown, on pointer :hover AND on the JS-driven `.is-active` option (the
 * roving keyboard highlight AND the server-marked current subject). DOM focus
 * never lands on a row — the ARIA combobox keeps focus on #subject-search — so
 * `:focus-within` cannot fire; `.is-active` is the keyboard/current channel.
 *
 * EVERY selector below is scoped under #subject-dropdown / #subject-list, so the
 * Products switcher (#product-*) is completely untouched. The flyout inherits
 * `--accent` / `--accent-soft` from its `.is-accent-*` parent item, so it is
 * tinted with the subject's own hue and reads correctly on the dark glass.
 * ========================================================================= */

/* The flyout is absolutely positioned against #subject-dropdown (already a
 * positioned box via .product-switcher__panel — DO NOT change its position, or
 * the panel stops anchoring below the trigger). The panel must not CLIP the
 * flyout, so override the shared `overflow: hidden` here. The inner
 * .product-switcher__list keeps its own `overflow-y: auto` scroll, but because
 * the list is NOT positioned it is not the flyout's containing block, so the
 * absolutely-positioned flyout escapes the list's clipping and is bounded only
 * by this (now visible) panel. */
#subject-dropdown {
  overflow: visible;
}

#subject-dropdown .subject-switcher__detail {
  position: absolute;
  top: 0;
  left: calc(100% + 12px);
  z-index: 60;
  width: min(20rem, 32vw);
  box-sizing: border-box;
  padding: 0.9rem 1rem;
  border-radius: 0.85rem;
  border: 1px solid rgba(27, 38, 102, 0.85);
  border-left: 3px solid var(--accent, #60a5fa);
  background-image: linear-gradient(
    to bottom,
    rgba(7, 12, 46, 0.97),
    rgba(4, 7, 31, 0.98)
  );
  -webkit-backdrop-filter: blur(24px);
  backdrop-filter: blur(24px);
  box-shadow:
    0 25px 50px -12px rgba(0, 0, 0, 0.6),
    0 0 0 1px rgba(255, 255, 255, 0.05);
  color: #f1f5f9;
  text-align: start;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateX(6px);
  transition:
    opacity 0.22s ease,
    transform 0.22s cubic-bezier(0.175, 0.885, 0.32, 1.275),
    visibility 0.22s ease;
}

/* Left-pointing caret bridging the flyout back toward the panel: an accent
 * outer triangle with a surface-coloured inner triangle laid over it. */
#subject-dropdown .subject-switcher__detail::before {
  content: "";
  position: absolute;
  top: 1.15rem;
  left: -8px;
  width: 0;
  height: 0;
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  border-right: 8px solid var(--accent, #60a5fa);
}

#subject-dropdown .subject-switcher__detail::after {
  content: "";
  position: absolute;
  top: 1.15rem;
  left: -6px;
  width: 0;
  height: 0;
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  border-right: 8px solid rgba(7, 12, 46, 0.97);
}

#subject-dropdown .subject-switcher__detail-tagline {
  display: block;
  font-size: 0.9rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--accent, #60a5fa);
}

#subject-dropdown .subject-switcher__detail-desc {
  display: block;
  margin-top: 0.45rem;
  font-size: 0.8rem;
  font-weight: 400;
  line-height: 1.55;
  color: #cbd5e1;              /* AA muted body on the dark glass */
}

#subject-dropdown .subject-switcher__detail-teachers {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.65rem;
  padding-top: 0.55rem;
  border-top: 1px solid rgba(27, 38, 102, 0.6);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--accent, #60a5fa);
}

#subject-dropdown .subject-switcher__detail-teachers i {
  flex: 0 0 auto;
  font-size: 0.8rem;
}

/* Reveal on pointer hover (mouse) AND on the JS-active option (keyboard nav +
 * the server-marked current subject). The row never receives DOM focus, so
 * :focus-within is intentionally NOT part of this selector. Kept non-interactive
 * (pointer-events: none) — it is a description, not a target. */
#subject-list .product-switcher__row:hover .subject-switcher__detail,
#subject-list .product-switcher__item.is-active .subject-switcher__detail {
  opacity: 1;
  visibility: visible;
  pointer-events: none;
  transform: translateX(0);
}

/* Reduced motion: reveal instantly — no slide, no transition. */
@media (prefers-reduced-motion: reduce) {
  #subject-dropdown .subject-switcher__detail {
    transition: none;
    transform: none;
  }

  #subject-list .product-switcher__row:hover .subject-switcher__detail,
  #subject-list .product-switcher__item.is-active .subject-switcher__detail {
    transform: none;
  }
}
