/* ==========================================================================
   VS INTERNATIONAL COLLEGE — COMPONENTS
   --------------------------------------------------------------------------
   Reusable UI, namespaced `c-`. All class names are new, so nothing here
   overrides Bootstrap or style.css — a component only appears once a
   template is migrated onto it.

   Phase 1 ships the foundational primitives that the header and footer
   (Phase 2) depend on: button, chip, card shell, glass surface, reveal.
   Page-level components — page_hero, filter_bar, pagination, lightbox,
   empty_state — land in Phase 4.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. BUTTON
   -------------------------------------------------------------------------- */

.c-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--vsic-space-2xs);
  padding: var(--c-btn-py, 0.875rem) var(--c-btn-px, 1.75rem);
  border: 1.5px solid transparent;
  border-radius: var(--vsic-radius-md);
  font-family: var(--vsic-font-button);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-semibold);
  line-height: 1;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: var(--vsic-transition-color),
              transform var(--vsic-duration-fast) var(--vsic-ease-out),
              box-shadow var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-btn:hover { text-decoration: none; }

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .c-btn:hover { transform: translateY(-2px); }
}

.c-btn:active { transform: translateY(0); }

.c-btn[disabled],
.c-btn[aria-disabled="true"] {
  opacity: 0.55;
  pointer-events: none;
}

/* Variants */
.c-btn--primary {
  background: var(--vsic-brand-primary);
  color: var(--vsic-text-inverse);
  box-shadow: var(--vsic-shadow-md);
}
.c-btn--primary:hover {
  background: var(--vsic-brand-primary-hover);
  color: var(--vsic-text-inverse);
  box-shadow: var(--vsic-shadow-lg);
}

.c-btn--secondary {
  background: var(--vsic-brand-secondary);
  color: var(--vsic-text-inverse);
  box-shadow: var(--vsic-shadow-glow);
}
.c-btn--secondary:hover {
  background: var(--vsic-brand-secondary-hover);
  color: var(--vsic-text-inverse);
}

.c-btn--accent {
  background: var(--vsic-brand-accent);
  color: var(--vsic-navy-900);
  box-shadow: var(--vsic-shadow-glow-accent);
}
.c-btn--accent:hover {
  background: var(--vsic-brand-accent-hover);
  color: var(--vsic-navy-900);
}

.c-btn--outline {
  background: transparent;
  color: var(--vsic-brand-primary);
  border-color: var(--vsic-border-strong);
}
.c-btn--outline:hover {
  color: var(--vsic-brand-secondary);
  border-color: var(--vsic-border-brand);
  background: var(--vsic-brand-secondary-soft);
}

.c-btn--ghost {
  background: transparent;
  color: var(--vsic-text-primary);
}
.c-btn--ghost:hover {
  background: var(--vsic-surface-muted);
  color: var(--vsic-text-primary);
}

/* On dark / hero backgrounds */
.c-btn--on-dark {
  background: rgba(255, 255, 255, 0.10);
  color: var(--vsic-text-inverse);
  border-color: rgba(255, 255, 255, 0.28);
  backdrop-filter: blur(var(--vsic-glass-blur));
  -webkit-backdrop-filter: blur(var(--vsic-glass-blur));
}
.c-btn--on-dark:hover {
  background: rgba(255, 255, 255, 0.18);
  color: var(--vsic-text-inverse);
}

/* Sizes */
.c-btn--sm { --c-btn-py: 0.625rem; --c-btn-px: 1.125rem; font-size: var(--vsic-text-xs); }
.c-btn--lg { --c-btn-py: 1.0625rem; --c-btn-px: 2.25rem; font-size: var(--vsic-text-base); }
.c-btn--block { display: flex; width: 100%; }

/* Icon-only */
.c-btn--icon {
  --c-btn-py: 0;
  --c-btn-px: 0;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--vsic-radius-circle);
}

/* --------------------------------------------------------------------------
   2. CHIP / TAG
   -------------------------------------------------------------------------- */

.c-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--vsic-space-3xs);
  padding: 0.375rem 0.875rem;
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-pill);
  background: var(--vsic-surface-subtle);
  color: var(--vsic-text-secondary);
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-medium);
  line-height: 1.4;
  text-decoration: none;
  transition: var(--vsic-transition-color);
}

.c-chip:hover {
  color: var(--vsic-brand-secondary);
  border-color: var(--vsic-border-brand);
  background: var(--vsic-brand-secondary-soft);
  text-decoration: none;
}

.c-chip--active,
.c-chip[aria-current="true"] {
  background: var(--vsic-brand-primary);
  border-color: var(--vsic-brand-primary);
  color: var(--vsic-text-inverse);
}

.c-chip--accent {
  background: var(--vsic-brand-accent-soft);
  border-color: color-mix(in srgb, var(--vsic-brand-accent) 30%, #fff);
  color: var(--vsic-on-accent-soft);
}

.c-chip--highlight {
  background: var(--vsic-brand-highlight-soft);
  border-color: var(--vsic-amber-200);
  color: var(--vsic-amber-800);
}

/* --------------------------------------------------------------------------
   3. EYEBROW — small uppercase label above a heading.
   -------------------------------------------------------------------------- */

.c-eyebrow {
  display: inline-block;
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-bold);
  letter-spacing: var(--vsic-tracking-caps);
  text-transform: uppercase;
  color: var(--vsic-brand-secondary);
}

/* --------------------------------------------------------------------------
   4. SURFACE / CARD SHELL
   The visual container. Card *content* patterns arrive in Phase 4.
   -------------------------------------------------------------------------- */

.c-surface {
  background: var(--vsic-surface);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  box-shadow: var(--vsic-shadow-sm);
}

.c-surface--flat   { box-shadow: none; }
.c-surface--raised { box-shadow: var(--vsic-shadow-md); }
.c-surface--float  { box-shadow: var(--vsic-shadow-lg); }
.c-surface--pad    { padding: var(--vsic-space-md); }
.c-surface--pad-lg { padding: var(--vsic-space-lg); }

/* Glass — for the header and stat cards. Falls back to a solid fill where
   backdrop-filter is unsupported, so text contrast is never at risk. */
.c-glass {
  background: var(--vsic-surface);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .c-glass {
    background: var(--vsic-glass-bg);
    border-color: var(--vsic-glass-border);
    backdrop-filter: blur(var(--vsic-glass-blur)) saturate(var(--vsic-glass-saturate));
    -webkit-backdrop-filter: blur(var(--vsic-glass-blur)) saturate(var(--vsic-glass-saturate));
  }

  .c-glass--dark {
    background: var(--vsic-glass-bg-dark);
    border-color: rgba(255, 255, 255, 0.14);
    color: var(--vsic-text-inverse);
  }
}

/* --------------------------------------------------------------------------
   5. INTERACTIVE DEPTH
   Opt-in 3D. Tilt angles are driven by interactions.js through
   --c-tilt-x / --c-tilt-y; without JS the hover lift alone still reads well.
   -------------------------------------------------------------------------- */

.c-lift {
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out),
              box-shadow var(--vsic-duration-normal) var(--vsic-ease-out);
  will-change: transform;
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .c-lift:hover {
    transform: translateY(var(--vsic-lift-md));
    box-shadow: var(--vsic-shadow-lg);
  }
}

.c-tilt {
  transform-style: preserve-3d;
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out),
              box-shadow var(--vsic-duration-normal) var(--vsic-ease-out);
  will-change: transform;
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .c-tilt[data-vsic-tilt]:hover {
    transform: perspective(var(--vsic-perspective))
               rotateX(var(--c-tilt-x, 0deg))
               rotateY(var(--c-tilt-y, 0deg))
               translateZ(0);
    box-shadow: var(--vsic-shadow-lg);
  }
}

/* Children can be pushed forward in Z for genuine parallax depth. */
.c-tilt__layer { transform: translateZ(var(--c-tilt-depth, 30px)); }

/* --------------------------------------------------------------------------
   6. REVEAL ON SCROLL
   Driven by animations.js. base.css guarantees these stay visible under
   reduced-motion and when JS is unavailable.
   -------------------------------------------------------------------------- */

[data-vsic-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity var(--vsic-duration-slow) var(--vsic-ease-out),
              transform var(--vsic-duration-slow) var(--vsic-ease-out);
}

[data-vsic-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

[data-vsic-reveal="left"]  { transform: translateX(-24px); }
[data-vsic-reveal="right"] { transform: translateX(24px); }
[data-vsic-reveal="scale"] { transform: scale(0.94); }
[data-vsic-reveal="fade"]  { transform: none; }

/* Stagger index set inline by the template or by animations.js. */
[data-vsic-reveal][style*="--vsic-reveal-delay"] {
  transition-delay: var(--vsic-reveal-delay, 0ms);
}

/* --------------------------------------------------------------------------
   7. SKIP LINK
   -------------------------------------------------------------------------- */

.c-skip-link {
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-brand-secondary);
}

/* --------------------------------------------------------------------------
   8. SITE HEADER
   Glass, sticky, with a mobile drawer. Replaces .header_area / .main_menu.
   -------------------------------------------------------------------------- */

.c-header {
  position: sticky;
  top: 0;
  z-index: var(--vsic-z-header);
}

/* Utility bar — contact details and audience shortcuts. */
/* The bar collapses its own HEIGHT on scroll (grid row 1fr -> 0fr), so the
   sticky header genuinely shrinks and the main bar rises to the top edge.

   A negative margin-top was tried first and is wrong here: the margin of a
   first child collapses THROUGH the parent, so it tried to move the whole
   sticky header up instead of shortening it. The header is pinned at top:0
   and cannot move, so the collapsed bar kept occupying its row and left an
   empty gap above the navigation. */
.c-header__utility {
  overflow: hidden;
  /* Comfortably above the tallest real value (≈37px on desktop, ≈68px when
     the contact details wrap on a phone) so the bar is never clipped. */
  max-height: 6rem;
  background: var(--vsic-brand-primary);
  color: rgba(255, 255, 255, 0.9);
  font-size: var(--vsic-text-xs);
  opacity: 1;
  transition: max-height var(--vsic-duration-normal) var(--vsic-ease-out),
              opacity var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-header__utility-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--vsic-space-2xs) var(--vsic-space-md);
  padding-block: var(--vsic-space-2xs);
  /* Padding is part of the border box, so a 0fr row still cannot reach zero
     while it is present. It collapses on the same curve as the row. */
  transition: padding-block var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-header.scrolled .c-header__utility-inner { padding-block: 0; }

.c-header__utility-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vsic-space-xs) var(--vsic-space-md);
  margin: 0;
  padding: 0;
  list-style: none;
}

.c-header__utility-item {
  display: inline-flex;
  align-items: center;
  gap: var(--vsic-space-3xs);
}

.c-header__utility-item i { color: var(--vsic-brand-accent); }

.c-header__utility a {
  color: inherit;
  text-decoration: none;
  transition: var(--vsic-transition-color);
}

.c-header__utility a:hover { color: #fff; text-decoration: underline; }

/* Scrolled: the bar collapses to zero height and fades. No gap is left — the
   main bar becomes the top edge of the sticky header, and it expands again
   symmetrically on the way back to the top. */
.c-header.scrolled .c-header__utility {
  max-height: 0;
  opacity: 0;
  pointer-events: none;
}

@media (max-width: 61.99em) {
  .c-header__utility-shortcuts { display: none; }
}

/* On a phone the contact details wrapped onto two lines and the header ate
   141px of an 812px screen. One quiet row that can be swiped instead. */
@media (max-width: 47.99em) {
  .c-header__utility-inner { flex-wrap: nowrap; }

  .c-header__utility-list {
    flex-wrap: nowrap;
    overflow-x: auto;
    /* Must be stated explicitly: `overflow-x: auto` alone computes overflow-y
       to `auto` too, which gives the row an automatic minimum height and stops
       the scrolled-state collapse from reaching zero. */
    overflow-y: hidden;
    min-height: 0;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }

  .c-header__utility-list::-webkit-scrollbar { display: none; }
  .c-header__utility-item { white-space: nowrap; }
}

/* Main bar */
.c-header__bar {
  background: var(--vsic-surface);
  border-bottom: 1px solid transparent;
  transition: background var(--vsic-duration-normal) var(--vsic-ease-out),
              box-shadow var(--vsic-duration-normal) var(--vsic-ease-out),
              border-color var(--vsic-duration-normal) var(--vsic-ease-out);
}

/* ---------------------------------------------------------------------------
   SCROLLED STATE — single-colour sticky nav

   The bar does NOT change colour. Scrolling collapses the blue utility strip
   above it (see .c-header__utility) and the white bar simply rises to the top
   edge of the viewport and stays there. Only depth changes: a hairline and a
   soft shadow appear so the bar separates from the content passing underneath.

   Because the surface never darkens, every child — menu links, icon buttons,
   the logo, CTA buttons — keeps the exact styling it has at the top of the
   page. There is deliberately no inverted text/logo/button state here: any
   such rule would now be white-on-white.
   --------------------------------------------------------------------------- */
.c-header.scrolled .c-header__bar {
  background: var(--vsic-surface);
  border-bottom-color: var(--vsic-border);
  box-shadow: var(--vsic-shadow-md);
}

.c-header__inner {
  display: flex;
  align-items: center;
  gap: var(--vsic-space-md);
  min-height: 4.5rem;
  padding-block: var(--vsic-space-2xs);
}

.c-header__brand {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  margin-right: auto;
}

.c-header__logo {
  height: clamp(2.25rem, 1.9rem + 1.6vw, 3.25rem);
  width: auto;
  object-fit: contain;
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-header__brand:hover .c-header__logo { transform: scale(1.04); }

/* The bar keeps one surface colour at every scroll position, so the logo never
   needs an inverted variant or a contrast plate — it is simply always the same
   mark on the same white background. */

@media (prefers-reduced-motion: reduce) {
  .c-header__brand,
  .c-header__logo { transition: none; }
}

/* --- Desktop navigation --- */
.c-nav { display: none; }

@media (min-width: 62em) {
  .c-nav {
    display: flex;
    align-items: center;
    gap: var(--vsic-space-3xs);
    margin: 0;
    padding: 0;
    list-style: none;
  }
}

.c-nav__item { position: relative; }

.c-nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--vsic-space-3xs);
  padding: var(--vsic-space-2xs) var(--vsic-space-xs);
  border-radius: var(--vsic-radius-sm);
  font-family: var(--vsic-font-nav);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-medium);
  color: var(--vsic-text-primary);
  text-decoration: none;
  white-space: nowrap;
  background: none;
  border: 0;
  cursor: pointer;
  transition: var(--vsic-transition-color);
}

.c-nav__link:hover { color: var(--vsic-brand-secondary); text-decoration: none; }

/* Animated active underline. */
.c-nav__link::after {
  content: "";
  position: absolute;
  left: var(--vsic-space-xs);
  right: var(--vsic-space-xs);
  bottom: 0.125rem;
  height: 2px;
  border-radius: 2px;
  background: var(--vsic-brand-secondary);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-nav__link:hover::after { transform: scaleX(0.6); }

/* Current page stays visible and is announced — never hidden. */
.c-nav__link[aria-current="page"] {
  color: var(--vsic-brand-secondary);
  font-weight: var(--vsic-weight-semibold);
}

.c-nav__link[aria-current="page"]::after { transform: scaleX(1); }

.c-nav__caret {
  font-size: 0.625em;
  transition: transform var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-nav__item.is-open .c-nav__caret { transform: rotate(180deg); }

/* --- Dropdown --- */
.c-dropdown {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  min-width: 14rem;
  padding: var(--vsic-space-2xs);
  margin: 0;
  list-style: none;
  background: var(--vsic-surface);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-md);
  box-shadow: var(--vsic-shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity var(--vsic-duration-fast) var(--vsic-ease-out),
              transform var(--vsic-duration-fast) var(--vsic-ease-out),
              visibility var(--vsic-duration-fast);
}

.c-nav__item.is-open > .c-dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* Keep the last dropdown inside the viewport. */
.c-nav__item:last-child > .c-dropdown { left: auto; right: 0; }

.c-dropdown__link {
  display: block;
  padding: var(--vsic-space-2xs) var(--vsic-space-xs);
  border-radius: var(--vsic-radius-sm);
  font-size: var(--vsic-text-sm);
  color: var(--vsic-text-secondary);
  text-decoration: none;
  transition: var(--vsic-transition-color);
}

.c-dropdown__link:hover {
  background: var(--vsic-brand-secondary-soft);
  color: var(--vsic-brand-secondary);
  text-decoration: none;
}

.c-dropdown__link[aria-current="page"] {
  background: var(--vsic-brand-secondary-soft);
  color: var(--vsic-brand-secondary);
  font-weight: var(--vsic-weight-semibold);
}

.c-dropdown__divider {
  height: 1px;
  margin: var(--vsic-space-3xs) 0;
  background: var(--vsic-border);
}

/* --- Header actions --- */
.c-header__actions {
  display: flex;
  align-items: center;
  gap: var(--vsic-space-2xs);
  flex-shrink: 0;
}

.c-header__cta { display: none; }

@media (min-width: 75em) {
  .c-header__cta { display: inline-flex; }
}

.c-header__icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  border-radius: var(--vsic-radius-sm);
  background: transparent;
  color: var(--vsic-text-primary);
  cursor: pointer;
  transition: var(--vsic-transition-color);
}

.c-header__icon-btn:hover {
  background: var(--vsic-surface-muted);
  color: var(--vsic-brand-secondary);
}

@media (min-width: 62em) {
  .c-header__toggle { display: none; }
}

/* Hamburger -> close, animated. */
.c-burger { position: relative; width: 1.25rem; height: 0.875rem; }

.c-burger span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out),
              opacity var(--vsic-duration-fast) var(--vsic-ease-out),
              top var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-burger span:nth-child(1) { top: 0; }
.c-burger span:nth-child(2) { top: 50%; margin-top: -1px; }
.c-burger span:nth-child(3) { top: calc(100% - 2px); }

[aria-expanded="true"] .c-burger span:nth-child(1) { top: 50%; margin-top: -1px; transform: rotate(45deg); }
[aria-expanded="true"] .c-burger span:nth-child(2) { opacity: 0; }
[aria-expanded="true"] .c-burger span:nth-child(3) { top: 50%; margin-top: -1px; transform: rotate(-45deg); }

/* --- Search panel --- */
.c-header__search {
  display: grid;
  grid-template-rows: 0fr;
  background: var(--vsic-surface);
  border-bottom: 1px solid transparent;
  transition: grid-template-rows var(--vsic-duration-normal) var(--vsic-ease-out),
              border-color var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-header__search.is-open {
  grid-template-rows: 1fr;
  border-bottom-color: var(--vsic-border);
}

.c-header__search-inner { overflow: hidden; }

.c-header__search-form {
  display: flex;
  align-items: center;
  gap: var(--vsic-space-2xs);
  padding-block: var(--vsic-space-sm);
}

.c-header__search-input {
  flex: 1;
  padding: var(--vsic-space-2xs) var(--vsic-space-sm);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-md);
  background: var(--vsic-surface-subtle);
  font-size: var(--vsic-text-base);
}

.c-header__search-input:focus {
  outline: none;
  border-color: var(--vsic-border-brand);
  background: var(--vsic-surface);
}

/* --------------------------------------------------------------------------
   9. MOBILE DRAWER
   -------------------------------------------------------------------------- */

.c-drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--vsic-z-backdrop);
  background: rgba(11, 31, 58, 0.5);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--vsic-duration-normal) var(--vsic-ease-out),
              visibility var(--vsic-duration-normal);
}

.c-drawer-backdrop.is-open { opacity: 1; visibility: visible; }

.c-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: var(--vsic-z-drawer);
  width: min(22rem, 88vw);
  display: flex;
  flex-direction: column;
  background: var(--vsic-surface);
  box-shadow: var(--vsic-shadow-xl);
  transform: translateX(100%);
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out);
  overscroll-behavior: contain;
}

.c-drawer.is-open { transform: translateX(0); }

.c-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vsic-space-sm);
  padding: var(--vsic-space-sm) var(--vsic-space-md);
  border-bottom: 1px solid var(--vsic-border);
}

.c-drawer__body {
  flex: 1;
  overflow-y: auto;
  padding: var(--vsic-space-sm) var(--vsic-space-md) var(--vsic-space-lg);
}

.c-drawer__list { margin: 0; padding: 0; list-style: none; }

.c-drawer__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vsic-space-2xs);
  width: 100%;
  padding: var(--vsic-space-xs) var(--vsic-space-2xs);
  border: 0;
  border-radius: var(--vsic-radius-sm);
  background: none;
  font-family: var(--vsic-font-nav);
  font-size: var(--vsic-text-md);
  font-weight: var(--vsic-weight-medium);
  color: var(--vsic-text-primary);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: var(--vsic-transition-color);
}

.c-drawer__link:hover {
  background: var(--vsic-surface-muted);
  color: var(--vsic-brand-secondary);
  text-decoration: none;
}

.c-drawer__link[aria-current="page"] {
  color: var(--vsic-brand-secondary);
  background: var(--vsic-brand-secondary-soft);
  font-weight: var(--vsic-weight-semibold);
}

.c-drawer__link[aria-expanded="true"] .c-nav__caret { transform: rotate(180deg); }

/* Sub-menu uses grid-rows so it animates without a fixed height. */
.c-drawer__submenu {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-drawer__submenu.is-open { grid-template-rows: 1fr; }

.c-drawer__submenu-inner { overflow: hidden; }

.c-drawer__submenu .c-drawer__link {
  padding-left: var(--vsic-space-md);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-regular);
  color: var(--vsic-text-secondary);
}

.c-drawer__footer {
  display: grid;
  gap: var(--vsic-space-2xs);
  padding: var(--vsic-space-md);
  border-top: 1px solid var(--vsic-border);
}

/* Lock background scroll while the drawer is open. */
body.has-drawer-open { overflow: hidden; }

/* --------------------------------------------------------------------------
   10. SITE FOOTER
   -------------------------------------------------------------------------- */

.c-footer {
  position: relative;
  overflow: hidden;
  background: var(--vsic-brand-primary);
  color: rgba(255, 255, 255, 0.78);
  padding-block: var(--vsic-space-2xl) var(--vsic-space-md);
}

/* Animated aurora background — decorative only. */
.c-footer__aura {
  position: absolute;
  inset: -30% -10% auto;
  height: 60%;
  pointer-events: none;
  background:
    radial-gradient(40% 60% at 20% 40%, rgba(37, 99, 235, 0.45) 0%, transparent 70%),
    radial-gradient(35% 55% at 75% 30%, rgba(6, 182, 212, 0.35) 0%, transparent 70%);
  filter: blur(40px);
  animation: c-footer-drift 24s var(--vsic-ease-in-out) infinite alternate;
}

@keyframes c-footer-drift {
  from { transform: translate3d(-4%, 0, 0) scale(1); }
  to   { transform: translate3d(6%, 4%, 0) scale(1.12); }
}

@media (prefers-reduced-motion: reduce) {
  .c-footer__aura { animation: none; }
}

/* Flex rather than grid: the number of footer_sections is admin-controlled,
   so the row must absorb any count. auto-fit grid tracks collapse to 0 and
   force awkward wrapping once a spanning item no longer fits. */
.c-footer__grid {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: var(--vsic-space-xl);
}

.c-footer__col {
  flex: 1 1 12rem;
  min-width: 0;
}

/* The newsletter column earns more room but still wraps cleanly. */
.c-footer__col--wide {
  flex: 1.7 1 20rem;
}

.c-footer__title {
  margin: 0 0 var(--vsic-space-sm);
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-md);
  font-weight: var(--vsic-weight-semibold);
  color: #fff;
}

.c-footer__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--vsic-space-2xs);
}

.c-footer__link {
  color: inherit;
  text-decoration: none;
  font-size: var(--vsic-text-sm);
  transition: var(--vsic-transition-color);
}

.c-footer__link:hover { color: var(--vsic-brand-accent); text-decoration: none; }

.c-footer__text { margin: 0; font-size: var(--vsic-text-sm); }

/* Newsletter */
.c-newsletter { display: grid; gap: var(--vsic-space-2xs); }

.c-newsletter__field {
  display: flex;
  gap: var(--vsic-space-3xs);
  padding: var(--vsic-space-3xs);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--vsic-radius-pill);
  background: rgba(255, 255, 255, 0.08);
  transition: border-color var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-newsletter__field:focus-within { border-color: var(--vsic-brand-accent); }

.c-newsletter__input {
  flex: 1;
  min-width: 0;
  padding: var(--vsic-space-2xs) var(--vsic-space-sm);
  border: 0;
  background: transparent;
  color: #fff;
  font-size: var(--vsic-text-sm);
}

.c-newsletter__input::placeholder { color: rgba(255, 255, 255, 0.5); }
.c-newsletter__input:focus { outline: none; }

.c-newsletter__submit {
  flex-shrink: 0;
  padding-inline: var(--vsic-space-md);
  border: 0;
  border-radius: var(--vsic-radius-pill);
  background: var(--vsic-brand-accent);
  color: var(--vsic-navy-900);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-semibold);
  cursor: pointer;
  transition: var(--vsic-transition-color);
}

.c-newsletter__submit:hover { background: var(--vsic-brand-accent-hover); }
.c-newsletter__submit[disabled] { opacity: 0.6; cursor: progress; }

/* Inline feedback replaces the old Bootstrap modal. */
.c-newsletter__feedback {
  min-height: 1.25rem;
  font-size: var(--vsic-text-xs);
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--vsic-duration-fast) var(--vsic-ease-out),
              transform var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-newsletter__feedback.is-visible { opacity: 1; transform: none; }
.c-newsletter__feedback--success { color: #6ee7b7; }
.c-newsletter__feedback--error { color: #fca5a5; }

/* Social */
.c-footer__social { display: flex; flex-wrap: wrap; gap: var(--vsic-space-2xs); }

.c-footer__social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--vsic-radius-circle);
  color: rgba(255, 255, 255, 0.85);
  text-decoration: none;
  transition: var(--vsic-transition-color),
              transform var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-footer__social-link:hover {
  background: var(--vsic-brand-accent);
  border-color: var(--vsic-brand-accent);
  color: var(--vsic-navy-900);
  transform: translateY(-2px);
}

.c-footer__bottom {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--vsic-space-sm);
  margin-top: var(--vsic-space-xl);
  padding-top: var(--vsic-space-md);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: var(--vsic-text-xs);
}

/* Bare <p>/<li> inside the dark footer must not fall back to the light-surface
   element default (base.css `p,label{color:text-secondary}`), which is
   unreadable on the brand-primary footer. Reclaim the footer's own colour. */
.c-footer p,
.c-footer li,
.c-footer label { color: inherit; }

.c-footer__bottom p { margin: 0; }

/* --------------------------------------------------------------------------
   11. SYLLABUS VIEWER (Phase 5 — dedicated page, not a modal)
   -------------------------------------------------------------------------- */

.c-syllabus__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vsic-space-2xs) var(--vsic-space-md);
  margin-block: var(--vsic-space-sm);
  font-size: var(--vsic-text-sm);
  color: var(--vsic-text-secondary);
}

.c-syllabus__meta-item { display: inline-flex; align-items: center; gap: var(--vsic-space-3xs); }

.c-syllabus__body { line-height: var(--vsic-leading-relaxed); }

.c-syllabus__body h1,
.c-syllabus__body h2,
.c-syllabus__body h3,
.c-syllabus__body h4 {
  margin-block: var(--vsic-space-lg) var(--vsic-space-2xs);
  font-family: var(--vsic-font-heading);
  color: var(--vsic-text-primary);
}

.c-syllabus__body h2 { font-size: var(--vsic-text-xl); }
.c-syllabus__body h3 { font-size: var(--vsic-text-lg); }
.c-syllabus__body ul,
.c-syllabus__body ol { padding-left: var(--vsic-space-md); }
.c-syllabus__body li { margin-bottom: var(--vsic-space-3xs); }

.c-syllabus__body table {
  width: 100%;
  border-collapse: collapse;
  margin-block: var(--vsic-space-md);
}

.c-syllabus__body th,
.c-syllabus__body td {
  padding: var(--vsic-space-2xs) var(--vsic-space-xs);
  border: 1px solid var(--vsic-border);
  text-align: left;
}

.c-syllabus__body th {
  background: var(--vsic-surface-subtle);
  font-family: var(--vsic-font-heading);
}

/* Wide CMS tables scroll rather than breaking the page. */
.c-syllabus__scroll { overflow-x: auto; }

.c-syllabus__pdf {
  width: 100%;
  height: min(80vh, 45rem);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-md);
  background: var(--vsic-surface-subtle);
}

.c-syllabus__nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--vsic-space-sm);
  margin-top: var(--vsic-space-xl);
  padding-top: var(--vsic-space-md);
  border-top: 1px solid var(--vsic-border);
}

/* ==========================================================================
   PHASE 3 — PAGE-LEVEL COMPONENTS
   --------------------------------------------------------------------------
   Everything below is shared by two or more page templates. Anything that
   turns out to be used by exactly one page belongs in pages.css instead.
   ========================================================================== */

/* --------------------------------------------------------------------------
   12. MEDIA FRAME
   The single answer to "cards resize because someone uploaded a huge image".

   A .c-media is an aspect-ratio box. The image fills it with object-fit:
   cover, so the card's height is decided by the design, never by the upload.
   Because the ratio is declared in CSS the browser reserves the space before
   the image arrives — zero layout shift.

   Use --c-media-ratio (or a modifier) to pick the ratio per component.
   -------------------------------------------------------------------------- */

.c-media {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: var(--c-media-ratio, 16 / 9);
  background: var(--vsic-surface-muted);
  /* Paints the rounded corner correctly while a child transform is running. */
  isolation: isolate;
}

.c-media > img,
.c-media > video,
.c-media > iframe {
  width: 100%;
  height: 100%;
  object-fit: var(--c-media-fit, cover);
  object-position: var(--c-media-position, center);
  /* No zoom-on-hover anywhere. Opacity is the only image transition. */
  transition: opacity var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-media--square   { --c-media-ratio: 1 / 1; }
.c-media--portrait { --c-media-ratio: 3 / 4; }
.c-media--figure   { --c-media-ratio: 4 / 5; }
.c-media--photo    { --c-media-ratio: 4 / 3; }
.c-media--wide     { --c-media-ratio: 16 / 9; }
.c-media--ultra    { --c-media-ratio: 21 / 9; }

/* Logos, crests and transparent PNGs must not be cropped. */
.c-media--contain {
  --c-media-fit: contain;
  background: var(--vsic-surface);
  padding: var(--vsic-space-sm);
}

/* Skeleton shimmer while the image decodes. The shimmer sits behind the
   image; animations.js cross-fades the image in on load (see below) and stops
   the shimmer once the frame is marked .is-loaded. */
.c-media--skeleton::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(
    100deg,
    var(--vsic-surface-muted) 30%,
    var(--vsic-neutral-200) 50%,
    var(--vsic-surface-muted) 70%
  );
  background-size: 200% 100%;
  animation: c-skeleton 1.4s var(--vsic-ease-linear) infinite;
}

@keyframes c-skeleton {
  from { background-position: 150% 0; }
  to   { background-position: -50% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .c-media--skeleton::before { animation: none; }
}

/* Image sits above the shimmer. */
.c-media--skeleton > img { position: relative; z-index: 1; }

/* PROGRESSIVE FADE-IN
   The hidden state is scoped to html:not(.no-js): the inline script in the
   <head> removes .no-js the instant JS runs, so a browser with JS disabled
   never applies the hide and the picture is simply visible.

   .is-instant (cached image) skips the transition; .is-loaded (freshly
   decoded) fades. Once loaded the shimmer is switched off. */
html:not(.no-js) .c-media--skeleton.is-loading:not(.is-loaded) > img { opacity: 0; }

.c-media--skeleton > img {
  transition: opacity var(--vsic-duration-slow) var(--vsic-ease-out);
}

.c-media--skeleton.is-loaded > img { opacity: 1; }
.c-media--skeleton.is-instant > img { transition: none; }
.c-media--skeleton.is-loaded::before { animation: none; opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  html:not(.no-js) .c-media--skeleton.is-loading > img { opacity: 1; }
}

/* Gradient scrim so overlaid text stays legible on any photograph. */
.c-media__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(11, 31, 58, 0.78) 0%,
    rgba(11, 31, 58, 0.28) 45%,
    rgba(11, 31, 58, 0) 100%
  );
  pointer-events: none;
}

/* A badge pinned inside the frame (category, date, "Pinned"). */
.c-media__tag {
  position: absolute;
  top: var(--vsic-space-2xs);
  left: var(--vsic-space-2xs);
  z-index: 1;
}

.c-media__tag--end { left: auto; right: var(--vsic-space-2xs); }

/* --------------------------------------------------------------------------
   13. CARD
   One shell, many contents. Every card on the site is this component plus a
   modifier — that is what makes program / news / faculty / event cards agree
   with each other on radius, border, padding and hover.
   -------------------------------------------------------------------------- */

.c-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  height: 100%;
  background: var(--vsic-surface);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  box-shadow: var(--vsic-shadow-xs);
  transition: border-color var(--vsic-duration-normal) var(--vsic-ease-out),
              box-shadow var(--vsic-duration-normal) var(--vsic-ease-out),
              transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .c-card--interactive:hover {
    transform: translateY(var(--vsic-lift-md));
    border-color: var(--vsic-border-strong);
    box-shadow: var(--vsic-shadow-md);
  }
}

/* Keyboard users get the same affordance as the mouse hover. */
.c-card--interactive:focus-within {
  border-color: var(--vsic-border-brand);
  box-shadow: var(--vsic-shadow-md);
}

.c-card--flat { box-shadow: none; }
.c-card--plain { border: 0; background: transparent; box-shadow: none; }

.c-card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: var(--vsic-space-2xs);
  padding: var(--c-card-pad, var(--vsic-space-md));
}

.c-card__body--lg { --c-card-pad: var(--vsic-space-lg); }
.c-card__body--sm { --c-card-pad: var(--vsic-space-sm); }

.c-card__eyebrow {
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-semibold);
  letter-spacing: var(--vsic-tracking-wide);
  text-transform: uppercase;
  color: var(--vsic-brand-secondary);
}

.c-card__title {
  margin: 0;
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-md);
  font-weight: var(--vsic-weight-semibold);
  line-height: var(--vsic-leading-snug);
  color: var(--vsic-text-primary);
}

.c-card__title a {
  color: inherit;
  text-decoration: none;
  transition: var(--vsic-transition-color);
}

.c-card__title a:hover { color: var(--vsic-brand-secondary); text-decoration: none; }

/* Stretched link: the whole card is clickable, but only one real anchor
   exists — so screen readers and the tab order stay correct. */
.c-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}

/* Controls that must stay clickable above a stretched link. */
.c-card__above { position: relative; z-index: 2; }

.c-card__text {
  margin: 0;
  font-size: var(--vsic-text-sm);
  line-height: var(--vsic-leading-normal);
  color: var(--vsic-text-secondary);
}

/* Clamp CMS copy so uneven text lengths cannot stagger a grid of cards. */
.c-card__text--clamp {
  display: -webkit-box;
  -webkit-line-clamp: var(--c-clamp, 3);
  line-clamp: var(--c-clamp, 3);
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.c-clamp-1 { --c-clamp: 1; }
.c-clamp-2 { --c-clamp: 2; }
.c-clamp-4 { --c-clamp: 4; }

/* Footer pinned to the bottom regardless of body length — the reason every
   card in a row lines its call-to-action up on the same baseline. */
.c-card__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vsic-space-2xs) var(--vsic-space-sm);
  margin-top: auto;
  padding-top: var(--vsic-space-sm);
}

.c-card__footer--divided {
  border-top: 1px solid var(--vsic-border);
  margin-top: var(--vsic-space-sm);
}

/* Metadata row — date, author, reading time, file size. */
.c-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vsic-space-3xs) var(--vsic-space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-muted);
}

.c-meta__item {
  display: inline-flex;
  align-items: center;
  gap: var(--vsic-space-3xs);
}

.c-meta__item i { color: var(--vsic-text-muted); font-size: 0.95em; }

/* Icon tile used by feature / stat / value cards. */
.c-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--c-icon-size, 3rem);
  height: var(--c-icon-size, 3rem);
  border-radius: var(--vsic-radius-md);
  background: var(--vsic-brand-secondary-soft);
  color: var(--vsic-brand-secondary);
  font-size: calc(var(--c-icon-size, 3rem) * 0.45);
  line-height: 1;
}

.c-card__icon--lg { --c-icon-size: 3.5rem; }
.c-card__icon--accent {
  background: var(--vsic-brand-accent-soft);
  color: var(--vsic-on-accent-soft);
}
.c-card__icon--solid {
  background: var(--vsic-brand-primary);
  color: var(--vsic-text-inverse);
}

/* Horizontal card — list rows (notices, search results, library items). */
.c-card--row {
  flex-direction: row;
  align-items: stretch;
}

.c-card--row > .c-media {
  flex: 0 0 var(--c-row-media, 14rem);
  max-width: var(--c-row-media, 14rem);
  aspect-ratio: auto;
}

@media (max-width: 47.99em) {
  .c-card--row { flex-direction: column; }
  .c-card--row > .c-media {
    flex: none;
    max-width: none;
    aspect-ratio: var(--c-media-ratio, 16 / 9);
  }
}

/* --------------------------------------------------------------------------
   14. FACULTY / PERSON CARD
   Photographs are the hardest content to make consistent: staff portraits
   arrive at every size and crop. A fixed 4/5 frame with top-biased focus
   keeps heads in shot and every card the same height.
   -------------------------------------------------------------------------- */

/* PERSON CARD (founders, leadership, faculty)
   The card is width-capped and centred. Without the cap a carousel that shows
   a single item on a narrow viewport stretched the card to the full container,
   and a 4/5 portrait then rendered ~830px tall — the photograph swallowed the
   card and the uploaded image was scaled far past its natural size, which
   looks blurry. Capping the card keeps one portrait size everywhere, whatever
   the breakpoint or the number of visible slides. */
/* PERSON CARD (founders, leadership, faculty)

   The photograph is shown WHOLE — `contain`, never `cover`. Cropping to a
   fixed ratio cut the edges off uploads and, on a tall portrait, pushed faces
   out of frame. The uploaded picture is now never cropped, never stretched and
   never enlarged past its natural size; it simply sits inside a frame of fixed
   height on a soft backdrop, so cards stay perfectly aligned no matter what
   dimensions an administrator uploads.

   The card deliberately has NO max-width. It used to be capped at 19rem, which
   in a three-across carousel slot of ~400px left ~96px of dead space beside
   every card and read as an oversized gap. The card now fills its slot and the
   spacing is owned by the carousel/grid gap alone. */
.c-person {
  --c-media-ratio: 4 / 5;
  --c-media-fit: contain;
  width: 100%;
  height: 100%;
  text-align: center;
}

/* One fixed frame height across every card, on every breakpoint. The
   aspect-ratio governs narrow slots; the cap stops a wide slot from producing
   an oversized portrait. */
.c-person .c-media {
  max-height: 19rem;
  padding: var(--vsic-space-2xs);
  background: var(--vsic-surface-muted);
}

/* A grid of people sits tighter than the generic --gap-lg (32px) it used to
   inherit, so the row reads as one connected group: 1rem between columns and
   1.5rem between rows. Matches the 16px carousel gap on the home page. */
.l-grid:has(> .c-person) {
  gap: var(--vsic-space-md) var(--vsic-space-sm);
}

/* The text block carries real weight so the card does not read as a photo
   with a caption. */
.c-person__body {
  align-items: center;
  gap: var(--vsic-space-3xs);
  padding: var(--vsic-space-md) var(--vsic-space-sm) var(--vsic-space-lg);
}

.c-person__name {
  margin: 0;
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-md);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
}

.c-person__role {
  margin: 0;
  font-size: var(--vsic-text-sm);
  color: var(--vsic-brand-secondary);
  font-weight: var(--vsic-weight-medium);
}

.c-person__dept {
  margin: 0;
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-muted);
}

.c-person__contact {
  display: grid;
  gap: var(--vsic-space-3xs);
  margin: 0;
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-secondary);
}

.c-person__contact a { color: inherit; text-decoration: none; }
.c-person__contact a:hover { color: var(--vsic-brand-secondary); text-decoration: underline; }

.c-person__social {
  display: flex;
  justify-content: center;
  gap: var(--vsic-space-3xs);
  margin-top: auto;
  padding-top: var(--vsic-space-sm);
}

.c-social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-circle);
  color: var(--vsic-text-secondary);
  font-size: var(--vsic-text-sm);
  text-decoration: none;
  transition: var(--vsic-transition-color);
}

.c-social-link:hover {
  background: var(--vsic-brand-secondary-soft);
  border-color: var(--vsic-border-brand);
  color: var(--vsic-brand-secondary);
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   15. PAGE HERO — interior page banner. Not the home hero.
   -------------------------------------------------------------------------- */

.c-page-hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(2.5rem, 1.4rem + 5.5vw, 5rem);
  background: var(--vsic-gradient-hero);
  color: var(--vsic-text-inverse);
}

/* Bare text on the dark banner inherits its light colour instead of the
   light-surface element default from base.css. */
.c-page-hero p,
.c-page-hero li,
.c-page-hero label { color: inherit; }

/* Optional photograph behind the gradient. */
/* Two classes deep, and !important, to outrank style.css's
   `img[src*="fallbackImage"] { object-fit: contain !important }`. That rule
   is right for a card thumbnail — a placeholder should not be cropped — and
   wrong for a full-bleed backdrop, which has to fill the band. */
.c-page-hero .c-page-hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover !important;
  opacity: 0.28;
}

.c-page-hero__inner { position: relative; z-index: 1; }

.c-page-hero__title {
  margin: 0;
  font-family: var(--vsic-font-display);
  font-size: var(--vsic-text-3xl);
  font-weight: var(--vsic-weight-bold);
  line-height: var(--vsic-leading-tight);
  letter-spacing: var(--vsic-tracking-tight);
  color: #fff;
}

.c-page-hero__lead {
  max-width: 46rem;
  margin: var(--vsic-space-xs) 0 0;
  font-size: var(--vsic-text-md);
  line-height: var(--vsic-leading-normal);
  color: rgba(255, 255, 255, 0.82);
}

/* Light variant for pages where a dark band would be too heavy. */
.c-page-hero--subtle {
  background: var(--vsic-surface-subtle);
  border-bottom: 1px solid var(--vsic-border);
  color: var(--vsic-text-primary);
}

.c-page-hero--subtle .c-page-hero__title { color: var(--vsic-text-primary); }
.c-page-hero--subtle .c-page-hero__lead { color: var(--vsic-text-secondary); }

/* --------------------------------------------------------------------------
   16. BREADCRUMB
   -------------------------------------------------------------------------- */

.c-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vsic-space-3xs) var(--vsic-space-2xs);
  margin: 0 0 var(--vsic-space-sm);
  padding: 0;
  list-style: none;
  font-size: var(--vsic-text-xs);
  color: rgba(255, 255, 255, 0.7);
}

.c-breadcrumb a { color: inherit; text-decoration: none; }
.c-breadcrumb a:hover { color: #fff; text-decoration: underline; }

.c-breadcrumb li + li::before {
  content: "/";
  margin-right: var(--vsic-space-2xs);
  opacity: 0.5;
}

.c-breadcrumb [aria-current="page"] { color: #fff; font-weight: var(--vsic-weight-medium); }

.c-page-hero--subtle .c-breadcrumb { color: var(--vsic-text-muted); }
.c-page-hero--subtle .c-breadcrumb a:hover { color: var(--vsic-brand-secondary); }
.c-page-hero--subtle .c-breadcrumb [aria-current="page"] { color: var(--vsic-text-primary); }

/* --------------------------------------------------------------------------
   17. SECTION HEAD — eyebrow, title, lead, optional trailing action.
   -------------------------------------------------------------------------- */

.c-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--vsic-space-sm) var(--vsic-space-lg);
  margin-bottom: var(--vsic-space-xl);
}

.c-section-head__text { max-width: 44rem; }

.c-section-head__title {
  margin: var(--vsic-space-3xs) 0 0;
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-2xl);
  font-weight: var(--vsic-weight-bold);
  line-height: var(--vsic-leading-snug);
  letter-spacing: var(--vsic-tracking-tight);
  color: var(--vsic-text-primary);
}

.c-section-head__lead {
  margin: var(--vsic-space-2xs) 0 0;
  font-size: var(--vsic-text-base);
  line-height: var(--vsic-leading-normal);
  color: var(--vsic-text-secondary);
}

.c-section-head--center {
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.c-section-head--center .c-section-head__text { margin-inline: auto; }

/* On an inverse section the text has to flip too. */
.l-section--inverse .c-section-head__title { color: #fff; }
.l-section--inverse .c-section-head__lead { color: rgba(255, 255, 255, 0.78); }
.l-section--inverse .c-eyebrow { color: var(--vsic-brand-accent); }

/* Text link with a trailing arrow — "View all programmes". */
.c-link-more {
  display: inline-flex;
  align-items: center;
  gap: var(--vsic-space-3xs);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-brand-secondary);
  text-decoration: none;
  white-space: nowrap;
}

.c-link-more:hover { color: var(--vsic-text-link-hover); text-decoration: none; }

.c-link-more i {
  transition: transform var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-link-more:hover i { transform: translateX(3px); }

/* --------------------------------------------------------------------------
   18. BADGE — status, priority, category. Smaller and squarer than a chip.
   -------------------------------------------------------------------------- */

.c-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--vsic-space-3xs);
  padding: 0.25rem 0.625rem;
  border-radius: var(--vsic-radius-xs);
  background: var(--vsic-surface-muted);
  color: var(--vsic-text-secondary);
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-semibold);
  letter-spacing: var(--vsic-tracking-wide);
  line-height: 1.35;
  text-transform: uppercase;
  white-space: nowrap;
}

.c-badge--primary   { background: var(--vsic-brand-primary-soft); color: var(--vsic-brand-primary); }
.c-badge--secondary { background: var(--vsic-brand-secondary-soft); color: var(--vsic-on-secondary-soft); }
.c-badge--accent    { background: var(--vsic-brand-accent-soft); color: var(--vsic-on-accent-soft); }
.c-badge--success   { background: #dcfce7; color: #15803d; }
.c-badge--warning   { background: var(--vsic-amber-100); color: var(--vsic-amber-800); }
.c-badge--danger    { background: #fee2e2; color: #b91c1c; }
.c-badge--solid     { background: var(--vsic-brand-primary); color: var(--vsic-text-inverse); }

/* Sits on top of a photograph — needs its own contrast. */
.c-badge--overlay {
  background: rgba(11, 31, 58, 0.82);
  color: #fff;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* A small leading dot for priority indicators. */
.c-badge__dot {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: var(--vsic-radius-circle);
  background: currentColor;
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   19. DATE BLOCK — stacked day / month, used by event and notice cards.
   -------------------------------------------------------------------------- */

.c-date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 3.75rem;
  padding: var(--vsic-space-2xs) var(--vsic-space-3xs);
  border-radius: var(--vsic-radius-md);
  background: var(--vsic-brand-primary);
  color: var(--vsic-text-inverse);
  line-height: 1.1;
  text-align: center;
}

.c-date__day {
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-lg);
  font-weight: var(--vsic-weight-bold);
}

.c-date__month {
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-semibold);
  letter-spacing: var(--vsic-tracking-wide);
  text-transform: uppercase;
  opacity: 0.85;
}

.c-date--soft {
  background: var(--vsic-brand-secondary-soft);
  color: var(--vsic-on-secondary-soft);
}

/* --------------------------------------------------------------------------
   20. FORM CONTROLS
   Scoped to .c-form so Bootstrap's .form-control keeps working untouched on
   any template that has not been migrated.
   -------------------------------------------------------------------------- */

.c-form { display: grid; gap: var(--vsic-space-md); }

.c-form__grid {
  display: grid;
  gap: var(--vsic-space-md);
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
}

.c-field { display: grid; gap: var(--vsic-space-3xs); }

.c-field--full { grid-column: 1 / -1; }

.c-label {
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-medium);
  color: var(--vsic-text-primary);
}

.c-label__required { color: var(--vsic-danger); margin-left: 0.125rem; }

.c-input,
.c-select,
.c-textarea {
  width: 100%;
  padding: 0.75rem var(--vsic-space-sm);
  border: 1px solid var(--vsic-border-strong);
  border-radius: var(--vsic-radius-md);
  background: var(--vsic-surface);
  color: var(--vsic-text-primary);
  font-family: var(--vsic-font-body);
  font-size: var(--vsic-text-base);
  line-height: 1.4;
  transition: border-color var(--vsic-duration-fast) var(--vsic-ease-out),
              box-shadow var(--vsic-duration-fast) var(--vsic-ease-out),
              background-color var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-input::placeholder,
.c-textarea::placeholder {
  color: var(--vsic-text-muted);
  opacity: 1;
}

.c-input:hover,
.c-select:hover,
.c-textarea:hover { border-color: var(--vsic-neutral-400); }

/* One focus treatment for the whole site: brand border + soft ring. */
.c-input:focus,
.c-select:focus,
.c-textarea:focus {
  outline: none;
  border-color: var(--vsic-border-brand);
  box-shadow: 0 0 0 3px var(--vsic-brand-secondary-soft);
}

.c-textarea { min-height: 8rem; resize: vertical; }

.c-select {
  appearance: none;
  padding-right: var(--vsic-space-xl);
  /* Inline chevron — no extra HTTP request, no icon font dependency. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2364748b' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--vsic-space-sm) center;
  background-size: 1rem;
  cursor: pointer;
}

.c-input[disabled],
.c-select[disabled],
.c-textarea[disabled] {
  background: var(--vsic-surface-muted);
  color: var(--vsic-text-muted);
  cursor: not-allowed;
}

/* Validation. Colour is never the only signal — the message carries the
   meaning, so this also works for colour-blind users. */
.c-input[aria-invalid="true"],
.c-select[aria-invalid="true"],
.c-textarea[aria-invalid="true"],
.c-field--error .c-input,
.c-field--error .c-select,
.c-field--error .c-textarea {
  border-color: var(--vsic-danger);
}

.c-input[aria-invalid="true"]:focus,
.c-field--error .c-input:focus {
  box-shadow: 0 0 0 3px #fee2e2;
}

.c-help {
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-muted);
}

.c-error {
  display: flex;
  align-items: flex-start;
  gap: var(--vsic-space-3xs);
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-medium);
  color: var(--vsic-danger);
}

/* Checkbox / radio row */
.c-check {
  display: flex;
  align-items: flex-start;
  gap: var(--vsic-space-2xs);
  font-size: var(--vsic-text-sm);
  color: var(--vsic-text-secondary);
  cursor: pointer;
}

.c-check input {
  flex-shrink: 0;
  width: 1.05rem;
  height: 1.05rem;
  margin-top: 0.15rem;
  accent-color: var(--vsic-brand-secondary);
  cursor: pointer;
}

/* Search field with a leading icon. */
.c-search { position: relative; display: flex; }

.c-search__icon {
  position: absolute;
  left: var(--vsic-space-sm);
  top: 50%;
  transform: translateY(-50%);
  color: var(--vsic-text-muted);
  pointer-events: none;
  font-size: var(--vsic-text-base);
}

.c-search .c-input { padding-left: var(--vsic-space-xl); }

/* --------------------------------------------------------------------------
   21. FILTER BAR — search + selects + chips above a listing.
   -------------------------------------------------------------------------- */

.c-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--vsic-space-sm);
  padding: var(--vsic-space-md);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface-subtle);
}

.c-filters__field { flex: 1 1 12rem; min-width: 0; display: grid; gap: var(--vsic-space-3xs); }
.c-filters__field--grow { flex: 2 1 18rem; }
.c-filters__actions { display: flex; flex-wrap: wrap; gap: var(--vsic-space-2xs); }

.c-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vsic-space-2xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Horizontal scroll instead of a wrapping pile on narrow screens. */
@media (max-width: 47.99em) {
  .c-chips--scroll {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: var(--vsic-space-3xs);
    scroll-snap-type: x proximity;
  }
  .c-chips--scroll::-webkit-scrollbar { display: none; }
  .c-chips--scroll > * { flex: 0 0 auto; scroll-snap-align: start; }
}

/* Result count / sort row. */
.c-result-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--vsic-space-sm);
  font-size: var(--vsic-text-sm);
  color: var(--vsic-text-secondary);
}

/* --------------------------------------------------------------------------
   22. TABLE
   Academic style: no vertical rules, generous row height, sticky header.
   The wrapper is what makes wide tables scroll instead of breaking layout.
   -------------------------------------------------------------------------- */

.c-table-wrap {
  width: 100%;
  overflow-x: auto;
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface);
  -webkit-overflow-scrolling: touch;
}

.c-table {
  width: 100%;
  min-width: 34rem;
  margin: 0;
  border-collapse: collapse;
  font-size: var(--vsic-text-sm);
}

.c-table th,
.c-table td {
  padding: var(--vsic-space-xs) var(--vsic-space-sm);
  text-align: left;
  vertical-align: middle;
}

.c-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--vsic-surface-subtle);
  border-bottom: 1px solid var(--vsic-border-strong);
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-semibold);
  letter-spacing: var(--vsic-tracking-wide);
  text-transform: uppercase;
  color: var(--vsic-text-secondary);
  white-space: nowrap;
}

.c-table tbody tr + tr { border-top: 1px solid var(--vsic-border); }

.c-table tbody tr {
  transition: background-color var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-table tbody tr:hover { background: var(--vsic-surface-subtle); }

.c-table td strong { color: var(--vsic-text-primary); font-weight: var(--vsic-weight-semibold); }

.c-table__num { text-align: right; font-variant-numeric: tabular-nums; }
.c-table__actions { text-align: right; white-space: nowrap; }

/* --------------------------------------------------------------------------
   23. PAGINATION
   -------------------------------------------------------------------------- */

.c-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--vsic-space-3xs);
  margin: var(--vsic-space-xl) 0 0;
  padding: 0;
  list-style: none;
}

.c-pagination__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  height: 2.5rem;
  padding-inline: var(--vsic-space-2xs);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-sm);
  background: var(--vsic-surface);
  color: var(--vsic-text-secondary);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-medium);
  text-decoration: none;
  transition: var(--vsic-transition-color);
}

.c-pagination__link:hover {
  border-color: var(--vsic-border-brand);
  color: var(--vsic-brand-secondary);
  background: var(--vsic-brand-secondary-soft);
  text-decoration: none;
}

.c-pagination__link[aria-current="page"] {
  background: var(--vsic-brand-primary);
  border-color: var(--vsic-brand-primary);
  color: var(--vsic-text-inverse);
}

.c-pagination__link[aria-disabled="true"] {
  opacity: 0.45;
  pointer-events: none;
}

.c-pagination__gap {
  display: inline-flex;
  align-items: flex-end;
  height: 2.5rem;
  padding-inline: var(--vsic-space-3xs);
  color: var(--vsic-text-muted);
}

/* --------------------------------------------------------------------------
   24. EMPTY STATE
   -------------------------------------------------------------------------- */

.c-empty {
  display: grid;
  justify-items: center;
  gap: var(--vsic-space-2xs);
  padding: var(--vsic-space-2xl) var(--vsic-space-md);
  border: 1px dashed var(--vsic-border-strong);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface-subtle);
  text-align: center;
}

.c-empty__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: var(--vsic-radius-circle);
  background: var(--vsic-surface-muted);
  color: var(--vsic-text-muted);
  font-size: var(--vsic-text-xl);
}

.c-empty__title {
  margin: var(--vsic-space-2xs) 0 0;
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-md);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
}

.c-empty__text {
  margin: 0;
  max-width: 32rem;
  font-size: var(--vsic-text-sm);
  color: var(--vsic-text-secondary);
}

/* --------------------------------------------------------------------------
   25. ALERT / MESSAGE
   -------------------------------------------------------------------------- */

.c-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--vsic-space-2xs);
  padding: var(--vsic-space-sm) var(--vsic-space-md);
  border: 1px solid var(--vsic-border);
  border-left: 3px solid var(--vsic-brand-secondary);
  border-radius: var(--vsic-radius-md);
  background: var(--vsic-surface-subtle);
  font-size: var(--vsic-text-sm);
  color: var(--vsic-text-secondary);
}

.c-alert__icon { flex-shrink: 0; margin-top: 0.1rem; color: var(--vsic-brand-secondary); }
.c-alert p { margin: 0; }

.c-alert--success { border-left-color: var(--vsic-success); background: #f0fdf4; }
.c-alert--success .c-alert__icon { color: var(--vsic-success); }
.c-alert--warning { border-left-color: var(--vsic-warning); background: var(--vsic-amber-50); }
.c-alert--warning .c-alert__icon { color: var(--vsic-amber-700); }
.c-alert--danger  { border-left-color: var(--vsic-danger); background: #fef2f2; }
.c-alert--danger .c-alert__icon { color: var(--vsic-danger); }

/* --------------------------------------------------------------------------
   26. ACCORDION — FAQ and curriculum. Uses <details>, so it works with no
   JavaScript at all and is keyboard accessible for free.
   -------------------------------------------------------------------------- */

.c-accordion { display: grid; gap: var(--vsic-space-2xs); }

.c-accordion__item {
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-md);
  background: var(--vsic-surface);
  overflow: hidden;
  transition: border-color var(--vsic-duration-fast) var(--vsic-ease-out),
              box-shadow var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-accordion__item[open] {
  border-color: var(--vsic-border-strong);
  box-shadow: var(--vsic-shadow-xs);
}

.c-accordion__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vsic-space-sm);
  padding: var(--vsic-space-sm) var(--vsic-space-md);
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-base);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
  cursor: pointer;
  list-style: none;
  transition: var(--vsic-transition-color);
}

.c-accordion__summary::-webkit-details-marker { display: none; }
.c-accordion__summary:hover { color: var(--vsic-brand-secondary); }

.c-accordion__summary::after {
  content: "";
  flex-shrink: 0;
  width: 0.6rem;
  height: 0.6rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-accordion__item[open] > .c-accordion__summary::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}

.c-accordion__panel {
  padding: 0 var(--vsic-space-md) var(--vsic-space-md);
  font-size: var(--vsic-text-sm);
  line-height: var(--vsic-leading-relaxed);
  color: var(--vsic-text-secondary);
}

.c-accordion__panel > :first-child { margin-top: 0; }
.c-accordion__panel > :last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   27. QUOTE / TESTIMONIAL
   -------------------------------------------------------------------------- */

.c-quote {
  display: flex;
  flex-direction: column;
  gap: var(--vsic-space-md);
  height: 100%;
  padding: var(--vsic-space-lg);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface);
}

.c-quote__mark {
  font-family: var(--vsic-font-display);
  font-size: 2.5rem;
  line-height: 0.6;
  color: var(--vsic-brand-accent);
}

.c-quote__text {
  margin: 0;
  font-size: var(--vsic-text-md);
  line-height: var(--vsic-leading-relaxed);
  color: var(--vsic-text-primary);
}

.c-quote__author {
  display: flex;
  align-items: center;
  gap: var(--vsic-space-2xs);
  margin-top: auto;
  font-style: normal;
  min-width: 0;
  text-align: left;
}

/* The name/role column takes the remaining width. `min-width: 0` on its own
   is not enough: the avatar is stretched to 100% by owl-carousel's
   `.owl-carousel .owl-item img` rule, leaving this column at zero width, which
   wrapped the author's name one character per line and blew the card height
   out to ~790px. Both halves are pinned below. */
.c-quote__author > span {
  flex: 1 1 auto;
  min-width: 0;
}

.c-quote__name,
.c-quote__role { overflow-wrap: anywhere; }

/* The selector is doubled up (and repeated under .owl-item) purely to outrank
   owl-carousel's `.owl-carousel .owl-item img { width: 100% }`, which would
   otherwise stretch this avatar across the whole caption row. */
.c-quote__avatar,
.owl-carousel .owl-item img.c-quote__avatar {
  flex: 0 0 2.75rem;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--vsic-radius-circle);
  object-fit: cover;
  object-position: center 25%;
  background: var(--vsic-surface-muted);
}

.c-quote__name {
  display: block;
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
}

.c-quote__role {
  display: block;
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-muted);
}

/* --------------------------------------------------------------------------
   28. STAT
   -------------------------------------------------------------------------- */

.c-stat {
  display: flex;
  align-items: center;
  gap: var(--vsic-space-sm);
  padding: var(--vsic-space-md);
}

.c-stat__value {
  font-family: var(--vsic-font-display);
  font-size: var(--vsic-text-2xl);
  font-weight: var(--vsic-weight-bold);
  line-height: 1;
  letter-spacing: var(--vsic-tracking-tight);
  color: var(--vsic-brand-primary);
  font-variant-numeric: tabular-nums;
}

.c-stat__label {
  margin: var(--vsic-space-3xs) 0 0;
  font-size: var(--vsic-text-sm);
  color: var(--vsic-text-secondary);
}

.l-section--inverse .c-stat__value { color: #fff; }
.l-section--inverse .c-stat__label { color: rgba(255, 255, 255, 0.75); }

/* Divided row of stats — a single band rather than four floating cards. */
.c-stat-band {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface);
  box-shadow: var(--vsic-shadow-sm);
  overflow: hidden;
}

.c-stat-band > .c-stat + .c-stat { border-left: 1px solid var(--vsic-border); }

/* The border must follow the wrap, so drop it when the grid stacks. */
@media (max-width: 47.99em) {
  .c-stat-band > .c-stat + .c-stat {
    border-left: 0;
    border-top: 1px solid var(--vsic-border);
  }
}

/* --------------------------------------------------------------------------
   29. TIMELINE — About page history.
   -------------------------------------------------------------------------- */

.c-timeline {
  position: relative;
  display: grid;
  gap: var(--vsic-space-lg);
  margin: 0;
  padding: 0 0 0 var(--vsic-space-lg);
  list-style: none;
}

.c-timeline::before {
  content: "";
  position: absolute;
  left: 0.3125rem;
  top: 0.5rem;
  bottom: 0.5rem;
  width: 2px;
  background: var(--vsic-border);
}

.c-timeline__item { position: relative; }

.c-timeline__item::before {
  content: "";
  position: absolute;
  left: calc(var(--vsic-space-lg) * -1);
  top: 0.45rem;
  width: 0.75rem;
  height: 0.75rem;
  border: 2px solid var(--vsic-brand-secondary);
  border-radius: var(--vsic-radius-circle);
  background: var(--vsic-surface);
}

.c-timeline__year {
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-bold);
  letter-spacing: var(--vsic-tracking-wide);
  color: var(--vsic-brand-secondary);
}

.c-timeline__title {
  margin: var(--vsic-space-3xs) 0 var(--vsic-space-3xs);
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-md);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
}

.c-timeline__text {
  margin: 0;
  font-size: var(--vsic-text-sm);
  line-height: var(--vsic-leading-normal);
  color: var(--vsic-text-secondary);
}

/* --------------------------------------------------------------------------
   30. PROSE — admin-authored rich text (notice bodies, article content).
   The CMS emits bare HTML, so these are element selectors scoped to a class.
   -------------------------------------------------------------------------- */

.c-prose {
  font-size: var(--vsic-text-base);
  line-height: var(--vsic-leading-relaxed);
  color: var(--vsic-text-secondary);
}

.c-prose > :first-child { margin-top: 0; }
.c-prose > :last-child { margin-bottom: 0; }

.c-prose h2,
.c-prose h3,
.c-prose h4 {
  margin: var(--vsic-space-lg) 0 var(--vsic-space-2xs);
  font-family: var(--vsic-font-heading);
  font-weight: var(--vsic-weight-semibold);
  line-height: var(--vsic-leading-snug);
  color: var(--vsic-text-primary);
}

.c-prose h2 { font-size: var(--vsic-text-xl); }
.c-prose h3 { font-size: var(--vsic-text-lg); }
.c-prose h4 { font-size: var(--vsic-text-md); }

.c-prose p { margin: 0 0 var(--vsic-space-sm); }

.c-prose a {
  color: var(--vsic-text-link);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.c-prose a:hover { color: var(--vsic-text-link-hover); }

.c-prose ul,
.c-prose ol { margin: 0 0 var(--vsic-space-sm); padding-left: var(--vsic-space-md); }
.c-prose li { margin-bottom: var(--vsic-space-3xs); }

.c-prose blockquote {
  margin: var(--vsic-space-md) 0;
  padding: var(--vsic-space-2xs) 0 var(--vsic-space-2xs) var(--vsic-space-md);
  border-left: 3px solid var(--vsic-brand-accent);
  font-size: var(--vsic-text-md);
  color: var(--vsic-text-primary);
}

.c-prose img {
  height: auto;
  margin-block: var(--vsic-space-md);
  border-radius: var(--vsic-radius-md);
}

.c-prose figure { margin: var(--vsic-space-md) 0; }
.c-prose figcaption {
  margin-top: var(--vsic-space-3xs);
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-muted);
}

.c-prose hr {
  margin-block: var(--vsic-space-lg);
  border: 0;
  border-top: 1px solid var(--vsic-border);
}

/* CMS tables are the most common source of horizontal overflow. */
.c-prose table {
  width: 100%;
  margin-block: var(--vsic-space-md);
  border-collapse: collapse;
  font-size: var(--vsic-text-sm);
}

.c-prose th,
.c-prose td {
  padding: var(--vsic-space-2xs) var(--vsic-space-xs);
  border: 1px solid var(--vsic-border);
  text-align: left;
}

.c-prose th { background: var(--vsic-surface-subtle); font-weight: var(--vsic-weight-semibold); }

/* --------------------------------------------------------------------------
   31. LIGHTBOX — gallery viewer.
   -------------------------------------------------------------------------- */

.c-lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--vsic-z-lightbox);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--vsic-space-md);
  background: rgba(6, 19, 36, 0.92);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--vsic-duration-normal) var(--vsic-ease-out),
              visibility var(--vsic-duration-normal);
}

.c-lightbox.is-open { opacity: 1; visibility: visible; }

.c-lightbox__figure {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vsic-space-sm);
  max-width: min(72rem, 100%);
  max-height: 100%;
  margin: 0;
}

.c-lightbox__frame {
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  min-height: 0;
}

/* The image is bounded by the viewport, never by its own pixel size, so a
   6000px upload and a 600px upload present identically. */
.c-lightbox__img {
  max-width: 100%;
  max-height: 78vh;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--vsic-radius-md);
  box-shadow: var(--vsic-shadow-xl);
  background: var(--vsic-navy-950);
}

/* Video keeps a 16/9 box instead of shrink-wrapping to nothing. */
.c-lightbox__iframe {
  width: min(72rem, 90vw);
  height: auto;
  aspect-ratio: 16 / 9;
  max-height: 78vh;
  border: 0;
}

.c-lightbox__caption {
  max-width: 46rem;
  margin: 0;
  font-size: var(--vsic-text-sm);
  line-height: var(--vsic-leading-normal);
  color: rgba(255, 255, 255, 0.82);
  text-align: center;
}

.c-lightbox__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--vsic-radius-circle);
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  font-size: var(--vsic-text-lg);
  line-height: 1;
  cursor: pointer;
  transition: var(--vsic-transition-color);
}

.c-lightbox__btn:hover { background: rgba(255, 255, 255, 0.22); color: #fff; }

.c-lightbox__close { position: absolute; top: var(--vsic-space-md); right: var(--vsic-space-md); }

.c-lightbox__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

.c-lightbox__nav--prev { left: var(--vsic-space-md); }
.c-lightbox__nav--next { right: var(--vsic-space-md); }

.c-lightbox__count {
  position: absolute;
  bottom: var(--vsic-space-md);
  left: 50%;
  transform: translateX(-50%);
  font-size: var(--vsic-text-xs);
  letter-spacing: var(--vsic-tracking-wide);
  color: rgba(255, 255, 255, 0.7);
}

@media (max-width: 47.99em) {
  .c-lightbox { padding: var(--vsic-space-2xs); }
  .c-lightbox__nav--prev { left: var(--vsic-space-2xs); }
  .c-lightbox__nav--next { right: var(--vsic-space-2xs); }
  .c-lightbox__img { max-height: 66vh; }
}

/* --------------------------------------------------------------------------
   32. MODAL / DIALOG — notice popup and any future dialog.
   -------------------------------------------------------------------------- */

.c-modal {
  position: fixed;
  inset: 0;
  z-index: var(--vsic-z-modal);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--vsic-space-md);
  background: rgba(6, 19, 36, 0.62);
  opacity: 0;
  transition: opacity var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-modal.is-open { display: flex; opacity: 1; }

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .c-modal {
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
  }
}

.c-modal__dialog {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: var(--c-modal-w, 40rem);
  max-height: calc(100vh - var(--vsic-space-xl));
  max-height: calc(100svh - var(--vsic-space-xl));
  overflow: hidden;
  background: var(--vsic-surface);
  border-radius: var(--vsic-radius-lg);
  box-shadow: var(--vsic-shadow-xl);
  transform: translateY(12px);
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

.c-modal.is-open .c-modal__dialog { transform: none; }

.c-modal__close {
  position: absolute;
  top: var(--vsic-space-2xs);
  right: var(--vsic-space-2xs);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-circle);
  background: var(--vsic-glass-bg, rgba(255, 255, 255, 0.9));
  color: var(--vsic-text-primary);
  font-size: var(--vsic-text-lg);
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--vsic-shadow-sm);
  transition: var(--vsic-transition-color);
}

.c-modal__close:hover {
  background: var(--vsic-surface-muted);
  color: var(--vsic-brand-primary);
}

.c-modal__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* --------------------------------------------------------------------------
   33. CAROUSEL CONTROLS
   Owl Carousel is still the engine — these only restyle the chrome it emits,
   so every existing `.owl-carousel` initialisation keeps working.
   -------------------------------------------------------------------------- */

.c-carousel .owl-nav {
  display: flex;
  justify-content: center;
  gap: var(--vsic-space-2xs);
  margin-top: var(--vsic-space-md);
}

.c-carousel .owl-nav button.owl-prev,
.c-carousel .owl-nav button.owl-next {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--vsic-border) !important;
  border-radius: var(--vsic-radius-circle);
  background: var(--vsic-surface) !important;
  color: var(--vsic-text-secondary) !important;
  font-size: var(--vsic-text-md);
  line-height: 1;
  transition: var(--vsic-transition-color);
}

.c-carousel .owl-nav button.owl-prev:hover,
.c-carousel .owl-nav button.owl-next:hover {
  border-color: var(--vsic-border-brand) !important;
  background: var(--vsic-brand-secondary-soft) !important;
  color: var(--vsic-brand-secondary) !important;
}

.c-carousel .owl-nav button.disabled { opacity: 0.4; }

.c-carousel .owl-dots {
  display: flex;
  justify-content: center;
  gap: var(--vsic-space-3xs);
  margin-top: var(--vsic-space-md);
}

.c-carousel .owl-dots button.owl-dot span {
  display: block;
  width: 0.5rem;
  height: 0.5rem;
  margin: 0;
  border-radius: var(--vsic-radius-pill);
  background: var(--vsic-border-strong);
  transition: width var(--vsic-duration-fast) var(--vsic-ease-out),
              background-color var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-carousel .owl-dots button.owl-dot.active span {
  width: 1.5rem;
  background: var(--vsic-brand-secondary);
}

/* Owl sets each item to its own height; stretching makes cards in a row
   match, which is what .c-card's height:100% needs to work. */
.c-carousel .owl-stage { display: flex; }
.c-carousel .owl-item { display: flex; }
.c-carousel .owl-item > * { width: 100%; }

/* --------------------------------------------------------------------------
   34. RESOURCE / DOWNLOAD ROW — library materials, syllabus files, notices.
   -------------------------------------------------------------------------- */

.c-resource {
  display: flex;
  align-items: center;
  gap: var(--vsic-space-sm);
  padding: var(--vsic-space-sm) var(--vsic-space-md);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-md);
  background: var(--vsic-surface);
  text-decoration: none;
  transition: border-color var(--vsic-duration-fast) var(--vsic-ease-out),
              background-color var(--vsic-duration-fast) var(--vsic-ease-out);
}

.c-resource:hover {
  border-color: var(--vsic-border-brand);
  background: var(--vsic-brand-secondary-soft);
  text-decoration: none;
}

.c-resource__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--vsic-radius-sm);
  background: var(--vsic-brand-secondary-soft);
  color: var(--vsic-brand-secondary);
}

.c-resource__text { min-width: 0; flex: 1; }

.c-resource__name {
  display: block;
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
  overflow-wrap: anywhere;
}

.c-resource__meta {
  display: block;
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-muted);
}

/* --------------------------------------------------------------------------
   35. SIDEBAR / ASIDE PANEL
   -------------------------------------------------------------------------- */

.c-panel {
  padding: var(--vsic-space-md);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface);
}

.c-panel + .c-panel { margin-top: var(--vsic-space-md); }

.c-panel__title {
  margin: 0 0 var(--vsic-space-sm);
  padding-bottom: var(--vsic-space-2xs);
  border-bottom: 1px solid var(--vsic-border);
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-base);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
}

.c-panel--sticky {
  position: sticky;
  top: calc(var(--vsic-scroll-offset, 6rem) + var(--vsic-space-sm));
}

/* Vertical link list inside a panel. */
.c-list { display: grid; gap: var(--vsic-space-3xs); margin: 0; padding: 0; list-style: none; }

.c-list__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vsic-space-2xs);
  padding: var(--vsic-space-2xs) var(--vsic-space-xs);
  border-radius: var(--vsic-radius-sm);
  font-size: var(--vsic-text-sm);
  color: var(--vsic-text-secondary);
  text-decoration: none;
  transition: var(--vsic-transition-color);
}

.c-list__link:hover {
  background: var(--vsic-brand-secondary-soft);
  color: var(--vsic-brand-secondary);
  text-decoration: none;
}

.c-list__link[aria-current="page"],
.c-list__link.is-active {
  background: var(--vsic-brand-secondary-soft);
  color: var(--vsic-brand-secondary);
  font-weight: var(--vsic-weight-semibold);
}

.c-list__count {
  flex-shrink: 0;
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-muted);
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   36. MOTION & DEPTH UTILITIES  (Phase 1 — cinematic foundation)
   Driven by animations.js. Every effect is a progressive enhancement: it
   degrades to the plain, fully-visible element under reduced-motion or no JS.
   ========================================================================== */

/* PARALLAX
   The transform is written inline by animations.js. The element must be able
   to overflow its slot without clipping the layout, so parents that hold a
   parallax layer should set their own overflow. will-change is applied only
   while motion is allowed, so it costs nothing under reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  [data-vsic-parallax] { will-change: transform; }
}

/* A framed image that drifts inside its own overflow-clipped frame. Pair with
   .c-media: the image is sized larger than the frame so the drift never
   exposes an edge. */
.c-media--parallax { overflow: hidden; }
.c-media--parallax > img {
  height: 116%;
  top: -8%;
  position: relative;
}

@media (prefers-reduced-motion: reduce) {
  .c-media--parallax > img { height: 100%; top: 0; }
}

/* SHEEN
   A single soft highlight sweep across a surface on hover — the "glass
   reflection" micro-interaction. Opt-in via .c-sheen on a positioned,
   overflow-hidden element (buttons and cards qualify). Purely decorative and
   pointer-transparent, so it never affects layout or hit-testing. */
.c-sheen { position: relative; overflow: hidden; }

.c-sheen::after {
  content: "";
  position: absolute;
  top: 0;
  left: -75%;
  width: 50%;
  height: 100%;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(255, 255, 255, 0.35) 50%,
    transparent 100%
  );
  transform: skewX(-18deg);
  opacity: 0;
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .c-sheen:hover::after {
    opacity: 1;
    animation: c-sheen-sweep var(--vsic-duration-slow) var(--vsic-ease-out);
  }
}

@keyframes c-sheen-sweep {
  from { left: -75%; }
  to   { left: 125%; }
}

/* KEN BURNS
   A barely-there slow zoom for a lone hero photograph — the drift makes a
   still image feel alive without a hover trigger. Only on decorative
   backdrops, never on content images that must stay crisp. */
@media (prefers-reduced-motion: no-preference) {
  .c-kenburns {
    animation: c-kenburns 18s var(--vsic-ease-in-out) infinite alternate;
    will-change: transform;
  }
}

@keyframes c-kenburns {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.06) translate3d(1.5%, -1.5%, 0); }
}
