/* ==========================================================================
   VS INTERNATIONAL COLLEGE — PAGE-SPECIFIC STYLES
   --------------------------------------------------------------------------
   Genuine one-off rules only, namespaced by page (`p-home`, `p-about`, …).

   RULES FOR THIS FILE
     1. If a pattern appears on two or more pages it belongs in
        components.css, not here.
     2. Nothing in here may duplicate a token — reference --vsic-* directly.
     3. This file replaces the nine per-template {% block extra_css %}
        blocks. As each page is migrated its inline <style> is deleted and
        whatever genuinely remains page-specific moves here.
   ========================================================================== */

/* ==========================================================================
   HOME
   ========================================================================== */

/* --------------------------------------------------------------------------
   HERO — full-viewport cinematic entrance
   Layer stack (back to front):
     0  .p-hero__media > img   the photograph, Ken Burns + parallax
     1  ::before / ::after     directional scrim + brand tint + bottom fade
     2  .p-hero__inner         content
     2  .p-hero__scroll        scroll cue
   -------------------------------------------------------------------------- */

.p-hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  /* Near-full viewport, capped so it never becomes absurd on tall screens,
     and floored so short screens keep a real hero. svh dodges the mobile
     URL-bar jump. Header height is subtracted so the fold isn't cramped. */
  min-height: clamp(32rem, 92svh, 54rem);
  padding-block: clamp(3rem, 2rem + 6vw, 6rem) clamp(4rem, 3rem + 5vw, 7rem);
  background-color: var(--vsic-navy-900);
  color: var(--vsic-text-inverse);
  overflow: hidden;
}

/* The photograph is oversized and inset negative so the Ken Burns zoom and
   the parallax drift never expose an edge. */
.p-hero__media {
  position: absolute;
  inset: -8% 0;
  z-index: 0;
}

.p-hero__bg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.p-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(
      95deg,
      rgba(6, 19, 36, 0.92) 0%,
      rgba(6, 19, 36, 0.72) 38%,
      rgba(6, 19, 36, 0.25) 72%,
      rgba(6, 19, 36, 0.45) 100%
    );
}

/* Softens the join between the hero and the section beneath it. */
.p-hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  z-index: 1;
  height: 9rem;
  background: linear-gradient(to top, var(--vsic-surface) 2%, rgba(6, 19, 36, 0) 100%);
  pointer-events: none;
}

.p-hero__inner {
  position: relative;
  z-index: 2;
  width: 100%;
}

.p-hero__content { max-width: 46rem; }

/* WIDE-SCREEN HERO COMPOSITION
   Headline and quick-link widgets were stacked in the same left-hand column,
   so on a desktop the whole hero crowded into the left ~46rem and the right
   half of the page carried nothing. From the desktop breakpoint they become
   two balanced columns sharing the full container width, both settled on the
   same baseline.

   Scoped with :has() so a hero WITHOUT widgets keeps the single-column
   treatment instead of collapsing into a half-width block. Browsers without
   :has() simply keep the previous stacked layout. */
@media (min-width: 62em) {
  .p-hero__inner:has(.p-hero__widgets) {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    align-items: end;
    column-gap: var(--vsic-space-2xl);
  }

  .p-hero__inner:has(.p-hero__widgets) .p-hero__content { max-width: none; }

  .p-hero__inner:has(.p-hero__widgets) .p-hero__widgets {
    margin-top: 0;
    grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  }

  /* NO WIDGETS CONFIGURED
     The hero then held a single 46rem block and left ~430px of the container
     empty on the right. Headline and call-to-action split into two columns
     sharing the same bottom edge, so the composition spans the full width and
     reads deliberately rather than crowded to the left. */
  .p-hero__inner:not(:has(.p-hero__widgets)) .p-hero__content {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    align-items: end;
    column-gap: var(--vsic-space-2xl);
  }

  .p-hero__inner:not(:has(.p-hero__widgets)) .p-hero__eyebrow { grid-column: 1; }

  .p-hero__inner:not(:has(.p-hero__widgets)) .p-hero__title {
    grid-column: 1;
    font-size: var(--vsic-text-5xl);
  }

  .p-hero__inner:not(:has(.p-hero__widgets)) .p-hero__actions {
    grid-column: 2;
    grid-row: 2;
    align-self: end;
    margin-top: 0;
    padding-bottom: var(--vsic-space-2xs);
  }
}

/* --- Sequenced entrance ---
   Children rise into place on load, staggered. Gated behind no-preference so
   reduced-motion users get the final state with no animation, and behind
   :not(.no-js) so a JS-less page is never left mid-animation. */
@media (prefers-reduced-motion: no-preference) {
  html:not(.no-js) .p-hero__content--enter > * {
    opacity: 0;
    transform: translateY(1.25rem);
    animation: p-hero-rise var(--vsic-duration-slow) var(--vsic-ease-out) forwards;
  }
  html:not(.no-js) .p-hero__content--enter > *:nth-child(1) { animation-delay: 0.15s; }
  html:not(.no-js) .p-hero__content--enter > *:nth-child(2) { animation-delay: 0.30s; }
  html:not(.no-js) .p-hero__content--enter > *:nth-child(3) { animation-delay: 0.45s; }
  html:not(.no-js) .p-hero__content--enter.p-hero__widgets { animation-delay: 0.55s; }
  html:not(.no-js) .p-hero__widgets.p-hero__content--enter > * { opacity: 1; transform: none; animation: none; }
  html:not(.no-js) .p-hero__widgets.p-hero__content--enter {
    opacity: 0;
    transform: translateY(1.25rem);
    animation: p-hero-rise var(--vsic-duration-slow) var(--vsic-ease-out) 0.55s forwards;
  }
}

@keyframes p-hero-rise {
  to { opacity: 1; transform: none; }
}

/* --- Scroll cue --- */
.p-hero__scroll {
  position: absolute;
  left: 50%;
  bottom: clamp(1rem, 2.5vw, 2rem);
  z-index: 2;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vsic-space-2xs);
  color: rgba(255, 255, 255, 0.72);
  text-decoration: none;
  transform: translateX(-50%);
  transition: color var(--vsic-duration-fast) var(--vsic-ease-out);
}

.p-hero__scroll:hover { color: #fff; }

.p-hero__scroll-text {
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-semibold);
  letter-spacing: var(--vsic-tracking-caps);
  text-transform: uppercase;
}

.p-hero__scroll-line {
  position: relative;
  width: 1px;
  height: 2.5rem;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.28);
}

/* A lit segment falls down the line, over and over — the descent invitation. */
.p-hero__scroll-line::after {
  content: "";
  position: absolute;
  top: -60%;
  left: 0;
  width: 100%;
  height: 60%;
  background: linear-gradient(to bottom, transparent, #fff);
}

@media (prefers-reduced-motion: no-preference) {
  .p-hero__scroll-line::after {
    animation: p-hero-scroll 1.9s var(--vsic-ease-in-out) infinite;
  }
}

@keyframes p-hero-scroll {
  0%   { transform: translateY(0); }
  100% { transform: translateY(280%); }
}

/* The cue is decorative once the page is short or the user is deep in content;
   hide it on very short viewports where it would collide with the widgets. */
@media (max-height: 34rem) {
  .p-hero__scroll { display: none; }
}

.p-hero__eyebrow {
  display: inline-block;
  margin-bottom: var(--vsic-space-sm);
  padding: 0.375rem 0.875rem;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: var(--vsic-radius-pill);
  background: rgba(255, 255, 255, 0.08);
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-semibold);
  letter-spacing: var(--vsic-tracking-caps);
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.92);
}

.p-hero__title {
  margin: 0;
  font-family: var(--vsic-font-display);
  font-size: var(--vsic-text-4xl);
  font-weight: var(--vsic-weight-bold);
  line-height: var(--vsic-leading-tight);
  letter-spacing: var(--vsic-tracking-tight);
  color: #fff;
  text-shadow: 0 2px 24px rgba(6, 19, 36, 0.45);
}

.p-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vsic-space-sm);
  margin-top: var(--vsic-space-lg);
}

/* --- Quick-link widgets --- */

.p-hero__widgets {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: var(--vsic-space-sm);
  margin: var(--vsic-space-xl) 0 0;
  padding: 0;
  list-style: none;
}

.p-hero__widget-link {
  position: relative;
  display: grid;
  gap: var(--vsic-space-3xs);
  height: 100%;
  padding: var(--vsic-space-md) var(--vsic-space-lg) var(--vsic-space-md) var(--vsic-space-md);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--vsic-radius-lg);
  background: rgba(11, 31, 58, 0.55);
  color: inherit;
  text-decoration: none;
  transition: background-color var(--vsic-duration-normal) var(--vsic-ease-out),
              border-color var(--vsic-duration-normal) var(--vsic-ease-out),
              transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .p-hero__widget-link {
    background: rgba(11, 31, 58, 0.38);
    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));
  }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .p-hero__widget-link:hover { transform: translateY(var(--vsic-lift-sm)); }
}

.p-hero__widget-link:hover {
  background: rgba(11, 31, 58, 0.62);
  border-color: rgba(255, 255, 255, 0.34);
  color: inherit;
  text-decoration: none;
}

.p-hero__widget-title {
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-base);
  font-weight: var(--vsic-weight-semibold);
  color: #fff;
}

.p-hero__widget-text {
  font-size: var(--vsic-text-xs);
  line-height: var(--vsic-leading-normal);
  color: rgba(255, 255, 255, 0.72);
}

.p-hero__widget-arrow {
  position: absolute;
  top: var(--vsic-space-md);
  right: var(--vsic-space-sm);
  color: var(--vsic-brand-accent);
  font-size: var(--vsic-text-sm);
  transition: transform var(--vsic-duration-fast) var(--vsic-ease-out);
}

.p-hero__widget-link:hover .p-hero__widget-arrow { transform: translateX(3px); }

@media (max-width: 47.99em) {
  .p-hero { align-items: center; }
  .p-hero__actions .c-btn { flex: 1 1 100%; }
}

/* --------------------------------------------------------------------------
   FEATURE CARDS
   A feature may carry a background photograph. When it does the card flips
   to inverse text over a scrim, so admin-uploaded imagery can never make the
   copy unreadable.
   -------------------------------------------------------------------------- */

.p-feature .c-card__body { gap: var(--vsic-space-2xs); }
.p-feature .c-card__icon { margin-bottom: var(--vsic-space-2xs); }

.p-feature--image {
  background-image: var(--p-feature-image);
  background-size: cover;
  background-position: center;
  border-color: transparent;
}

.p-feature--image::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(11, 31, 58, 0.72) 0%, rgba(11, 31, 58, 0.9) 100%);
}

.p-feature--image .c-card__body { position: relative; }
.p-feature--image .c-card__title { color: #fff; }
.p-feature--image .c-card__text { color: rgba(255, 255, 255, 0.78); }

.p-feature--image .c-card__icon {
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
}

/* --------------------------------------------------------------------------
   ADMISSIONS BLOCK
   -------------------------------------------------------------------------- */

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

.p-admissions__lead {
  max-width: 34rem;
  margin: 0 0 var(--vsic-space-lg);
  font-size: var(--vsic-text-md);
  line-height: var(--vsic-leading-normal);
  color: var(--vsic-text-secondary);
}

.p-admissions__trust {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vsic-space-sm) var(--vsic-space-lg);
  margin: var(--vsic-space-lg) 0 0;
  padding: 0;
  list-style: none;
}

.p-admissions__trust li {
  display: flex;
  align-items: center;
  gap: var(--vsic-space-2xs);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-medium);
  color: var(--vsic-text-primary);
}

.p-admissions__trust .c-card__icon { --c-icon-size: 2.25rem; }

/* Media column: photograph plus an overlapping contact card. */
.p-admissions__media { position: relative; }

.p-admissions__frame {
  border-radius: var(--vsic-radius-xl);
  box-shadow: var(--vsic-shadow-lg);
}

.p-admissions__expert {
  display: flex;
  align-items: center;
  gap: var(--vsic-space-sm);
  margin: calc(var(--vsic-space-xl) * -1) var(--vsic-space-md) 0;
  padding: var(--vsic-space-sm) var(--vsic-space-md);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface);
  box-shadow: var(--vsic-shadow-md);
}

.p-admissions__expert-text { display: grid; gap: 0.125rem; min-width: 0; }

.p-admissions__expert-text strong {
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-base);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
}

.p-admissions__expert-text span {
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-secondary);
}

.p-admissions__expert .c-btn--icon { margin-left: auto; width: 2.5rem; height: 2.5rem; }

.p-admissions__partners {
  margin-top: var(--vsic-section-y);
  padding-top: var(--vsic-section-y);
  border-top: 1px solid var(--vsic-border);
}

@media (max-width: 35.99em) {
  .p-admissions__expert {
    margin-inline: var(--vsic-space-2xs);
    padding: var(--vsic-space-xs) var(--vsic-space-sm);
  }
}

/* --------------------------------------------------------------------------
   PARTNER LOGOS
   `contain` fitting inside a fixed frame is what stops a tall logo and a wide
   logo from producing two different tile heights.
   -------------------------------------------------------------------------- */

.p-partner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vsic-space-2xs);
  height: 100%;
  padding: var(--vsic-space-md);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface);
  text-align: center;
  transition: border-color var(--vsic-duration-normal) var(--vsic-ease-out),
              box-shadow var(--vsic-duration-normal) var(--vsic-ease-out);
}

.p-partner:hover {
  border-color: var(--vsic-border-strong);
  box-shadow: var(--vsic-shadow-sm);
}

.p-partner__media {
  --c-media-ratio: 3 / 2;
  width: 100%;
  padding: 0;
  background: transparent;
}

/* Partner logos display in their original brand colours — no grayscale, at
   full opacity, from first paint. */
.p-partner__media img {
  opacity: 1;
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

/* Typographic tile used when a partner has no uploaded logo. Colours come
   from the theme tokens, so it tracks whatever the administrator configures. */
.p-partner__monogram {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 2;
  border-radius: var(--vsic-radius-md);
  background: var(--vsic-brand-secondary-soft);
}

.p-partner__monogram span {
  font-family: var(--vsic-font-display);
  font-size: var(--vsic-text-2xl);
  font-weight: var(--vsic-weight-bold);
  line-height: 1;
  color: var(--vsic-on-secondary-soft);
  text-transform: uppercase;
}

.p-partner__name {
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-medium);
  line-height: var(--vsic-leading-snug);
  color: var(--vsic-text-secondary);
}

/* ==========================================================================
   HOME — WHO WE ARE / WHY VSIC
   ========================================================================== */

/* Editorial intro: a statement on the left, supporting story on the right.
   Columns are balanced (roughly equal) and vertically centred so a short lead
   sits level with the heading rather than dropping to the bottom and leaving
   the right half looking empty. Collapses to one column below the split. */
.p-why__intro {
  display: grid;
  gap: var(--vsic-space-md) var(--vsic-space-2xl);
  margin-bottom: var(--vsic-space-2xl);
  grid-template-columns: 1fr;
}

/* The heading spans the FULL container width and the lead sits beneath it.

   A two-column split was tried and does not work for this content: the
   database heading is long while the supporting line is a single short
   sentence, so any split left a tall stack of heading lines crammed into the
   left half and an almost empty right half — exactly the "congested left,
   empty right" problem. Across the full width the same heading resolves to a
   couple of generous lines and the section reads as one spacious block. */
@media (min-width: 62em) {
  .p-why__intro {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--vsic-space-sm);
  }

  /* Long-form measure so the lead never runs the entire 1136px as one thin
     line, while still starting flush with the heading. */
  .p-why__lead { max-width: 72ch; }
}

.p-why__title {
  margin: var(--vsic-space-2xs) 0 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: var(--vsic-text-primary);
  text-wrap: balance;
}

.p-why__body { padding-bottom: 0; }

/* A quiet rule to the left of the lead ties it to the statement and gives the
   right column visual weight so the block reads balanced, not left-heavy. */
/* No ch cap: the grid column already sets a comfortable measure, and the cap
   was cutting the column short and re-opening the empty gap on the right. */
.p-why__lead {
  margin: 0;
  font-size: var(--vsic-text-md);
  line-height: var(--vsic-leading-relaxed);
  color: var(--vsic-text-secondary);
  text-wrap: pretty;
}

/* A quiet brand rule beneath the heading ties the lead to it. */
@media (min-width: 62em) {
  .p-why__body {
    padding-left: var(--vsic-space-md);
    border-left: 3px solid var(--vsic-brand-secondary-soft);
  }
}

/* A hairline above the grid ties the statement and the cards together. */
.p-why__grid {
  padding-top: var(--vsic-space-xl);
  border-top: 1px solid var(--vsic-border);
}

/* Numbered feature card. The index is a quiet editorial marker, top-right. */
.p-feature { position: relative; }

.p-feature__index {
  position: absolute;
  top: var(--vsic-space-md);
  right: var(--vsic-space-md);
  font-family: var(--vsic-font-display);
  font-size: var(--vsic-text-lg);
  font-weight: var(--vsic-weight-bold);
  line-height: 1;
  /* Soft brand-tinted watermark — reads as an intentional editorial numeral,
     not a near-invisible grey. Tracks the admin theme. */
  color: var(--vsic-neutral-300);
  color: color-mix(in srgb, var(--vsic-brand-secondary) 28%, var(--vsic-neutral-300));
  letter-spacing: var(--vsic-tracking-tight);
}

.p-feature--image .p-feature__index { color: rgba(255, 255, 255, 0.5); }

/* ==========================================================================
   HOME — ACADEMIC PROGRAMMES
   ========================================================================== */

/* A quiet lit hairline grows across the top of a programme card on hover —
   a restrained "focus" cue that reads as premium, not busy. */
.p-program { isolation: isolate; }

.p-program::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 2;
  background: var(--vsic-gradient-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .p-program:hover::before,
  .p-program:focus-within::before { transform: scaleX(1); }
}

/* ==========================================================================
   HOME — ACHIEVEMENTS (dark glass band)
   ========================================================================== */

.p-achieve {
  position: relative;
  overflow: hidden;
  background: var(--vsic-gradient-hero);
}

/* Decorative aura — two soft brand-coloured glows, slow drift. Purely
   background, so it sits behind the content layer. */
.p-achieve__aura {
  position: absolute;
  inset: -20% -10% auto;
  height: 80%;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(42% 60% at 22% 30%, rgba(37, 99, 235, 0.42) 0%, transparent 70%),
    radial-gradient(38% 55% at 78% 40%, rgba(6, 182, 212, 0.34) 0%, transparent 70%);
  filter: blur(46px);
  animation: p-achieve-drift 26s var(--vsic-ease-in-out) infinite alternate;
}

@keyframes p-achieve-drift {
  from { transform: translate3d(-3%, 0, 0) scale(1); }
  to   { transform: translate3d(5%, 4%, 0) scale(1.14); }
}

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

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

.p-achieve__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vsic-space-2xs);
  padding: var(--vsic-space-lg) var(--vsic-space-md);
  border-radius: var(--vsic-radius-lg);
  text-align: center;
}

.p-achieve__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--vsic-radius-md);
  background: rgba(255, 255, 255, 0.1);
  color: var(--vsic-brand-accent);
  font-size: var(--vsic-text-lg);
}

.p-achieve__value {
  font-family: var(--vsic-font-display);
  font-size: var(--vsic-text-4xl);
  font-weight: var(--vsic-weight-bold);
  line-height: 1;
  letter-spacing: var(--vsic-tracking-tight);
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.p-achieve__label {
  margin: 0;
  font-size: var(--vsic-text-sm);
  color: rgba(255, 255, 255, 0.78);
}

/* ==========================================================================
   COURSE DETAIL
   ========================================================================== */

/* --------------------------------------------------------------------------
   SEMESTER TABS
   Bootstrap 4 owns the behaviour and the .active class; these rules only
   replace its appearance. On narrow screens the strip scrolls sideways
   rather than wrapping into a ragged block of buttons.
   -------------------------------------------------------------------------- */

.p-course__tabs { margin-top: var(--vsic-space-md); }

.p-course__tabs .nav-tabs {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--vsic-space-3xs);
  overflow-x: auto;
  margin: 0 0 var(--vsic-space-lg);
  padding: 0 0 var(--vsic-space-3xs);
  border: 0;
  border-bottom: 1px solid var(--vsic-border);
  list-style: none;
  scrollbar-width: thin;
}

.p-course__tabs .nav-item { flex: 0 0 auto; margin: 0; }

.p-course__tabs .nav-link {
  position: relative;
  border: 0;
  border-radius: var(--vsic-radius-sm) var(--vsic-radius-sm) 0 0;
  background: transparent;
  padding: var(--vsic-space-2xs) var(--vsic-space-sm);
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-sm);
  font-weight: var(--vsic-weight-medium);
  color: var(--vsic-text-secondary);
  white-space: nowrap;
  cursor: pointer;
  transition: var(--vsic-transition-color);
}

.p-course__tabs .nav-link:hover {
  background: var(--vsic-surface-subtle);
  color: var(--vsic-brand-secondary);
}

.p-course__tabs .nav-link.active {
  background: transparent;
  color: var(--vsic-brand-secondary);
  font-weight: var(--vsic-weight-semibold);
}

/* The underline sits on the container's own border line. */
.p-course__tabs .nav-link.active::after {
  content: "";
  position: absolute;
  left: var(--vsic-space-2xs);
  right: var(--vsic-space-2xs);
  bottom: calc(var(--vsic-space-3xs) * -1 - 1px);
  height: 2px;
  border-radius: 2px;
  background: var(--vsic-brand-secondary);
}

/* --------------------------------------------------------------------------
   SUBJECT CARD
   -------------------------------------------------------------------------- */

.p-subject__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vsic-space-3xs);
  margin-bottom: var(--vsic-space-3xs);
}

.p-subject .c-card__title { font-size: var(--vsic-text-base); }

/* --------------------------------------------------------------------------
   AT-A-GLANCE FACT LIST
   -------------------------------------------------------------------------- */

.p-course__facts { margin: 0; }

.p-course__fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vsic-space-sm);
  padding-block: var(--vsic-space-2xs);
  font-size: var(--vsic-text-sm);
}

.p-course__fact + .p-course__fact { border-top: 1px solid var(--vsic-border); }

.p-course__fact dt { margin: 0; color: var(--vsic-text-secondary); font-weight: var(--vsic-weight-regular); }

.p-course__fact dd {
  margin: 0;
  text-align: right;
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
}

/* ==========================================================================
   ABOUT
   ========================================================================== */

/* Welcome media frame — a slightly larger radius and a soft shadow give the
   introduction image a premium, framed-print feel. */
.p-about__frame {
  border-radius: var(--vsic-radius-xl);
  box-shadow: var(--vsic-shadow-lg);
}

.p-about__media-col { position: relative; }

/* Owl replaces the slider's children with its own stage, so the frame needs
   to fill whatever width the item lands at. */
.p-about__slider .owl-item .c-media { width: 100%; }

.p-about__video {
  border-radius: var(--vsic-radius-lg);
  box-shadow: var(--vsic-shadow-md);
  background: var(--vsic-navy-950);
}

/* --------------------------------------------------------------------------
   OUR JOURNEY — alternating editorial story rows
   -------------------------------------------------------------------------- */

.p-story__row { align-items: center; }

/* Even rows flip: image moves to the right, text to the left. DOM order is
   unchanged (image first) so the reading order stays image → text; only the
   visual columns swap, and only once there is room for two columns. */
@media (min-width: 62em) {
  .p-story__row--reverse .p-story__media { order: 2; }
}

.p-story__frame {
  border-radius: var(--vsic-radius-lg);
  box-shadow: var(--vsic-shadow-md);
}

.p-story__text { position: relative; }

.p-story__index {
  font-family: var(--vsic-font-display);
  font-size: var(--vsic-text-2xl);
  font-weight: var(--vsic-weight-bold);
  line-height: 1;
  color: var(--vsic-neutral-300);
  color: color-mix(in srgb, var(--vsic-brand-secondary) 28%, var(--vsic-neutral-300));
  letter-spacing: var(--vsic-tracking-tight);
}

.p-story__title {
  margin: 0;
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-xl);
  font-weight: var(--vsic-weight-bold);
  line-height: var(--vsic-leading-snug);
  color: var(--vsic-text-primary);
}

/* --------------------------------------------------------------------------
   MISSION / VISION / VALUES — clean icon cards
   Icon-led rather than photo-backed, so the copy is always legible and the
   three cards read as one calm set. A top accent bar keys each card to its
   icon colour on hover.
   -------------------------------------------------------------------------- */

.p-mvv__card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--vsic-space-2xs);
  padding: var(--vsic-space-lg);
  overflow: hidden;
  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);
}

.p-mvv__card .c-card__icon { margin-bottom: var(--vsic-space-2xs); }

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

/* ==========================================================================
   LEADERSHIP MESSAGE
   ========================================================================== */

/* The portrait floats and the message wraps around it. The fixed frame is
   what stops a landscape upload from producing a different column width. */
.p-leader__photo {
  float: left;
  width: min(17.5rem, 42%);
  margin: 0.25rem var(--vsic-space-lg) var(--vsic-space-md) 0;
  border-radius: var(--vsic-radius-lg);
  box-shadow: var(--vsic-shadow-md);
}

@media (max-width: 47.99em) {
  .p-leader__photo {
    float: none;
    width: 100%;
    max-width: none;
    margin: 0 0 var(--vsic-space-md);
  }
}

/* Anything after the message must clear the floated portrait. */
.p-leader__signature,
.p-leader__author,
.p-leader .c-syllabus__nav { clear: both; }

.p-leader__signature { margin-top: var(--vsic-space-lg); }
.p-leader__signature img { max-height: 5.5rem; width: auto; }

.p-leader__author {
  display: grid;
  gap: 0.125rem;
  margin-top: var(--vsic-space-lg);
  padding-top: var(--vsic-space-sm);
  border-top: 1px solid var(--vsic-border);
}

.p-leader__author strong {
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-md);
  color: var(--vsic-text-primary);
}

.p-leader__author span { font-size: var(--vsic-text-sm); color: var(--vsic-text-secondary); }

.p-leader__contact {
  display: inline-flex;
  align-items: center;
  gap: var(--vsic-space-3xs);
  margin-top: var(--vsic-space-3xs);
  font-size: var(--vsic-text-sm);
}

.p-leader__contact a { color: var(--vsic-text-link); text-decoration: none; }
.p-leader__contact a:hover { text-decoration: underline; }

/* Related-message row inside the sidebar panel. */
.p-leader__related { justify-content: flex-start; gap: var(--vsic-space-2xs); }

.p-leader__related img {
  flex-shrink: 0;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--vsic-radius-circle);
  object-fit: cover;
  background: var(--vsic-surface-muted);
}

.p-leader__related-name {
  display: block;
  font-weight: var(--vsic-weight-medium);
  color: var(--vsic-text-primary);
  line-height: var(--vsic-leading-snug);
}

.p-leader__related small { color: var(--vsic-text-muted); font-size: var(--vsic-text-xs); }
.p-leader__related:hover .p-leader__related-name { color: var(--vsic-brand-secondary); }

/* ==========================================================================
   GALLERY
   ========================================================================== */

.p-gallery__filters {
  display: grid;
  gap: var(--vsic-space-2xs);
  margin-block: var(--vsic-space-md) var(--vsic-space-lg);
}

/* Child categories sit one visual step in from their parent. */
.p-gallery__chip--sub {
  margin-left: var(--vsic-space-sm);
  font-weight: var(--vsic-weight-regular);
  border-style: dashed;
}

.p-gallery__grid { margin-bottom: var(--vsic-space-xl); }

/* NOTE: content-visibility is deliberately NOT applied to these tiles.
   Each carries data-vsic-reveal (a scroll fade-up); size containment from
   content-visibility suppresses that reveal and the tiles never appear. The
   grid is also paginated, so the render saving would be marginal. The heavy
   case — the detail photo wall, which has no reveal and can hold hundreds of
   tiles — gets the optimisation instead (see .p-gallery__wall below). */

/* --------------------------------------------------------------------------
   IMAGE-FORWARD TILE — the gallery + category grids
   The photograph fills the whole card; title, date and category ride over a
   gradient scrim. Detail (caption + tags) sits folded below the fold and
   slides up on hover. The image itself never moves — motion lives in the
   overlay, so the photograph stays crisp and still.

   Interaction model (no nested links):
   - a transparent .p-gallery__surface button covers the frame → quick-view
     lightbox. It sits UNDER the caption.
   - .p-gallery__caption is pointer-events:none, so clicks on empty caption
     space fall through to the surface button; only its real links
     (title, tags) re-enable pointer events and win.
   -------------------------------------------------------------------------- */

.p-gallery__tile {
  position: relative;
  display: block;
  border-radius: var(--vsic-radius-lg);
  overflow: hidden;
  isolation: isolate;
  background: var(--vsic-surface-muted);
  box-shadow: var(--vsic-shadow-sm);
  transition: box-shadow var(--vsic-duration-normal) var(--vsic-ease-out),
              transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

.p-gallery__tile:hover,
.p-gallery__tile:focus-within {
  box-shadow: var(--vsic-shadow-lg);
  transform: translateY(-4px);
}

/* The media fills the tile; keep its corners flush with the tile radius. */
.p-gallery__tile .c-media { border-radius: 0; }

/* Persistent scrim, deepened on hover so revealed text stays legible. */
.p-gallery__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to top,
    rgba(6, 19, 36, 0.86) 0%,
    rgba(6, 19, 36, 0.52) 32%,
    rgba(6, 19, 36, 0.05) 62%,
    rgba(6, 19, 36, 0) 100%
  );
  pointer-events: none;
  transition: opacity var(--vsic-duration-normal) var(--vsic-ease-out);
}

.p-gallery__tile:hover .p-gallery__scrim,
.p-gallery__tile:focus-within .p-gallery__scrim { opacity: 1; }

/* Quick-view surface: transparent hit area over the photo. */
.p-gallery__surface {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
}

/* Category badge, pinned top-left, glassy so it reads on any photo. */
.p-gallery__badge {
  position: absolute;
  top: var(--vsic-space-sm);
  left: var(--vsic-space-sm);
  z-index: 4;
  display: inline-flex;
  align-items: center;
  padding: 0.3em 0.75em;
  border-radius: var(--vsic-radius-pill);
  background: rgba(255, 255, 255, 0.9);
  color: var(--vsic-brand-primary);
  font-size: var(--vsic-text-xs);
  font-weight: var(--vsic-weight-semibold);
  letter-spacing: 0.01em;
  backdrop-filter: blur(6px);
  pointer-events: none;
}

/* Centre cue — the zoom / play affordance revealed on hover. */
.p-gallery__cue {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: var(--vsic-radius-circle);
  background: rgba(255, 255, 255, 0.94);
  color: var(--vsic-brand-primary);
  font-size: var(--vsic-text-lg);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.85);
  transition: opacity var(--vsic-duration-normal) var(--vsic-ease-out),
              transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

.p-gallery__tile:hover .p-gallery__cue,
.p-gallery__tile:focus-within .p-gallery__cue {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* A video badge is content, not an affordance — always on, sits low so it
   never collides with the hover cue's scale-in. */
.p-gallery__cue--play { opacity: 1; transform: translate(-50%, -50%); }
.p-gallery__tile:hover .p-gallery__cue--play,
.p-gallery__tile:focus-within .p-gallery__cue--play {
  transform: translate(-50%, -50%) scale(1.06);
}

/* Overlaid caption block anchored to the bottom of the frame. */
.p-gallery__caption {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: var(--vsic-space-3xs);
  padding: var(--vsic-space-md);
  color: #fff;
  pointer-events: none;
}

.p-gallery__caption-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vsic-space-2xs);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--vsic-text-xs);
  color: rgba(255, 255, 255, 0.82);
}

.p-gallery__caption-meta li {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
}

/* Thin dot separators between meta items. */
.p-gallery__caption-meta li + li::before {
  content: "";
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.5);
}

.p-gallery__caption-title {
  margin: 0;
  font-size: var(--vsic-text-lg);
  font-weight: var(--vsic-weight-semibold);
  line-height: 1.25;
}

.p-gallery__caption-title a {
  color: #fff;
  text-decoration: none;
  pointer-events: auto;
}

.p-gallery__caption-title a:hover,
.p-gallery__caption-title a:focus-visible { text-decoration: underline; }

/* Folded detail — caption text + tags — that slides up on hover. */
.p-gallery__reveal {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows var(--vsic-duration-normal) var(--vsic-ease-out),
              opacity var(--vsic-duration-normal) var(--vsic-ease-out);
}

.p-gallery__tile:hover .p-gallery__reveal,
.p-gallery__tile:focus-within .p-gallery__reveal {
  grid-template-rows: 1fr;
  opacity: 1;
}

.p-gallery__reveal > * { overflow: hidden; }

.p-gallery__reveal-text {
  margin: var(--vsic-space-3xs) 0 0;
  font-size: var(--vsic-text-sm);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.9);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

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

.p-gallery__tags a {
  display: inline-flex;
  padding: 0.2em 0.6em;
  border-radius: var(--vsic-radius-pill);
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  font-size: var(--vsic-text-xs);
  text-decoration: none;
  pointer-events: auto;
  transition: background-color var(--vsic-duration-fast) var(--vsic-ease-out);
}

.p-gallery__tags a:hover,
.p-gallery__tags a:focus-visible { background: rgba(255, 255, 255, 0.32); }

/* Touch devices have no hover: reveal detail and show the cue up front. */
@media (hover: none) {
  .p-gallery__reveal { grid-template-rows: 1fr; opacity: 1; }
  .p-gallery__reveal > * { overflow: visible; }
  .p-gallery__cue { opacity: 1; transform: translate(-50%, -50%); }
}

@media (prefers-reduced-motion: reduce) {
  .p-gallery__tile,
  .p-gallery__cue,
  .p-gallery__reveal { transition: none; }
  .p-gallery__tile:hover,
  .p-gallery__tile:focus-within { transform: none; }
}

.p-gallery__zoom,
.p-gallery__play {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--vsic-radius-circle);
  background: rgba(255, 255, 255, 0.92);
  color: var(--vsic-brand-primary);
  font-size: var(--vsic-text-md);
  opacity: 0;
  transform: scale(0.9);
  transition: opacity var(--vsic-duration-normal) var(--vsic-ease-out),
              transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

.p-gallery__trigger:hover .p-gallery__zoom,
.p-gallery__trigger:hover .p-gallery__play,
.p-gallery__trigger:focus-visible .p-gallery__zoom,
.p-gallery__trigger:focus-visible .p-gallery__play {
  opacity: 1;
  transform: none;
}

/* A video is content, not a hover affordance — its play badge is always on. */
.p-gallery__play { opacity: 1; transform: none; }

/* Touch devices have no hover, so the icon must be visible from the start. */
@media (hover: none) {
  .p-gallery__zoom { opacity: 1; transform: none; }
  .p-gallery__trigger { background: rgba(6, 19, 36, 0.12); }
}

/* --------------------------------------------------------------------------
   PHOTO WALL — the gallery detail page
   -------------------------------------------------------------------------- */

.p-gallery__head { margin-bottom: var(--vsic-space-lg); }

/* Large albums are handled by native lazy-loading + async decoding on each
   <img>, plus the fixed-ratio skeleton frame that reserves space (no CLS).
   content-visibility was trialled here and removed: near the viewport edge it
   can leave a tile blank until the browser's proximity heuristic renders it,
   which is unacceptable for a gallery. Lazy-loading gives the fetch/decode
   saving without that flash. */

/* CLEAN PHOTO WALL
   A flat, evenly-spaced grid of square thumbnails — a timeless gallery, no 3D
   tilt or glare. Each cell is a quiet button that reveals a zoom cue and a soft
   scrim on hover/focus; the lightbox does the rest. */
.p-gallery__wall {
  margin-bottom: var(--vsic-space-xl);
}

.p-gallery__cell {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-md);
  overflow: hidden;
  background: var(--vsic-surface-muted);
  cursor: zoom-in;
  transition: transform var(--vsic-duration-normal) var(--vsic-ease-out),
              border-color var(--vsic-duration-normal) var(--vsic-ease-out),
              box-shadow var(--vsic-duration-normal) var(--vsic-ease-out);
}

.p-gallery__cell:hover,
.p-gallery__cell:focus-visible {
  z-index: 3;
  transform: translateY(var(--vsic-lift-sm));
  border-color: var(--vsic-border-strong);
  box-shadow: var(--vsic-shadow-md);
}

.p-gallery__cell .c-media { border-radius: 0; }

/* Centred zoom cue, fades in on hover/focus. */
.p-gallery__cell .p-gallery__zoom {
  position: absolute;
  inset: 0;
  margin: auto;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.9);
  transition: opacity var(--vsic-duration-normal) var(--vsic-ease-out),
              transform var(--vsic-duration-normal) var(--vsic-ease-out);
}

.p-gallery__cell:hover .p-gallery__zoom,
.p-gallery__cell:focus-visible .p-gallery__zoom {
  opacity: 1;
  transform: scale(1);
}

/* A soft tint under the icon so it reads against a bright photograph. */
.p-gallery__cell::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(6, 19, 36, 0);
  pointer-events: none;
  transition: background-color var(--vsic-duration-normal) var(--vsic-ease-out);
}

.p-gallery__cell:hover::after,
.p-gallery__cell:focus-visible::after { background: rgba(6, 19, 36, 0.28); }

@media (prefers-reduced-motion: reduce) {
  .p-gallery__cell,
  .p-gallery__cell .p-gallery__zoom { transition: none; }
  .p-gallery__cell:hover,
  .p-gallery__cell:focus-visible { transform: none; }
}

.p-gallery__related {
  margin-top: var(--vsic-space-2xl);
  padding-top: var(--vsic-space-xl);
  border-top: 1px solid var(--vsic-border);
}

/* --------------------------------------------------------------------------
   CLOSING CALL TO ACTION
   -------------------------------------------------------------------------- */

.p-gallery__cta {
  display: grid;
  justify-items: center;
  gap: var(--vsic-space-2xs);
  margin-top: var(--vsic-space-2xl);
  padding: var(--vsic-space-xl) var(--vsic-space-md);
  border-radius: var(--vsic-radius-xl);
  background: var(--vsic-surface-subtle);
  border: 1px solid var(--vsic-border);
  text-align: center;
}

.p-gallery__cta .c-section-head__lead { max-width: 42rem; }
.p-gallery__cta .l-cluster { margin-top: var(--vsic-space-sm); }

/* ==========================================================================
   NOTICES
   ========================================================================== */

/* A notice is a horizontal row: date block, then the body. On narrow screens
   the date drops above the text rather than squeezing the title. */
.p-notice__row {
  display: flex;
  gap: var(--vsic-space-md);
  align-items: flex-start;
}

.p-notice__main { flex: 1; min-width: 0; display: grid; gap: var(--vsic-space-2xs); }

.p-notice--featured { border-left: 3px solid var(--vsic-brand-accent); }

@media (max-width: 35.99em) {
  .p-notice__row { flex-direction: column; gap: var(--vsic-space-sm); }
  .p-notice .c-date { flex-direction: row; width: auto; gap: var(--vsic-space-3xs); padding-inline: var(--vsic-space-2xs); }
}

.p-notices__featured {
  margin-bottom: var(--vsic-space-xl);
  padding: var(--vsic-space-lg);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface-subtle);
  border: 1px solid var(--vsic-border);
}

/* Notice detail — poster-style cover, shown whole and height-capped. */
.p-notice__cover {
  display: flex;
  justify-content: center;
  margin: 0 0 var(--vsic-space-lg);
  padding: var(--vsic-space-sm);
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  background: var(--vsic-surface-subtle);
}

.p-notice__cover img {
  width: auto;
  max-width: 100%;
  max-height: 32rem;
  height: auto;
  border-radius: var(--vsic-radius-sm);
  object-fit: contain;
}

.p-notice__related { display: block; }
.p-notice__related-title {
  display: block;
  font-weight: var(--vsic-weight-medium);
  line-height: var(--vsic-leading-snug);
  color: var(--vsic-text-primary);
}
.p-notice__related small { color: var(--vsic-text-muted); font-size: var(--vsic-text-xs); }
.p-notice__related:hover .p-notice__related-title { color: var(--vsic-brand-secondary); }

/* --------------------------------------------------------------------------
   NOTICE POPUP
   Built on the shared .c-modal shell. The dialog width is fixed and the
   cover image lives in a fixed-height band shown with object-fit: contain,
   so a portrait, landscape or square upload all produce the same popup size
   and the whole image is always visible.
   -------------------------------------------------------------------------- */

.notice-popup { --c-modal-w: 38rem; }

.notice-popup__dialog { text-align: center; }

.notice-popup__track { min-height: 0; display: flex; flex-direction: column; }

/* Only the active slide participates in layout, so the dialog is sized by one
   notice at a time rather than the tallest. */
.notice-popup__slide { display: none; flex-direction: column; min-height: 0; }
.notice-popup__slide.is-active {
  display: flex;
  /* The slide owns the scroll now that the poster sizes itself, so a tall
     image plus a long body can never overflow the dialog. */
  overflow-y: auto;
  overscroll-behavior: contain;
  animation: notice-fade 0.35s var(--vsic-ease-out);
}

@keyframes notice-fade { from { opacity: 0.4; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .notice-popup__slide.is-active { animation: none; } }

/* The notice image is an announcement poster, so it is shown WHOLE and as
   large as the viewport allows.

   The band used to be locked to a 12–18rem height, which shrank a portrait
   poster until its text was unreadable. Now the frame follows the image:
   `width/height: auto` means the picture is never scaled beyond its natural
   size (so it can never go blurry), while the max rules keep the tallest
   upload inside the dialog. `contain` guarantees nothing is ever cropped. */
.notice-popup__media {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--vsic-space-sm);
  background: var(--vsic-surface-subtle);
  border-bottom: 1px solid var(--vsic-border);
}

.notice-popup__media img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: min(56svh, 32rem);
  object-fit: contain;
  border-radius: var(--vsic-radius-sm);
}

.notice-popup__body {
  padding: var(--vsic-space-lg) var(--vsic-space-lg) var(--vsic-space-xl);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.notice-popup__title {
  margin: 0 0 var(--vsic-space-2xs);
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-xl);
  font-weight: var(--vsic-weight-semibold);
  line-height: var(--vsic-leading-snug);
  letter-spacing: var(--vsic-tracking-tight);
  color: var(--vsic-text-primary);
  text-wrap: balance;
}

.notice-popup__text {
  margin: 0 auto var(--vsic-space-md);
  max-width: 32rem;
  font-size: var(--vsic-text-base);
  line-height: var(--vsic-leading-relaxed);
  color: var(--vsic-text-secondary);
  text-align: center;
}

.notice-popup__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vsic-space-2xs);
  justify-content: center;
}

/* Buttons read as a matched pair rather than two differently sized pills. */
.notice-popup__actions .c-btn { min-width: 10rem; justify-content: center; }

/* Prev / next arrows. Centred on the dialog rather than pinned to a fixed
   media height, which no longer exists. */
.notice-popup__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 4;
  width: 2.5rem;
  height: 2.5rem;
  background: var(--vsic-glass-bg, rgba(255, 255, 255, 0.9));
  color: var(--vsic-brand-primary);
  border: 1px solid var(--vsic-border);
  box-shadow: var(--vsic-shadow-sm);
}

.notice-popup__prev { left: var(--vsic-space-2xs); }
.notice-popup__next { right: var(--vsic-space-2xs); }

.notice-popup__dots {
  display: flex;
  justify-content: center;
  gap: var(--vsic-space-3xs);
  padding: 0 0 var(--vsic-space-md);
}

.notice-popup__dot {
  width: 0.5rem;
  height: 0.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--vsic-radius-pill);
  background: var(--vsic-border-strong);
  cursor: pointer;
  transition: width var(--vsic-duration-fast) var(--vsic-ease-out),
              background-color var(--vsic-duration-fast) var(--vsic-ease-out);
}

.notice-popup__dot.is-active { width: 1.25rem; background: var(--vsic-brand-secondary); }

@media (max-width: 35.99em) {
  .notice-popup__body { padding: var(--vsic-space-md) var(--vsic-space-sm) var(--vsic-space-lg); }
  .notice-popup__actions .c-btn { flex: 1 1 100%; min-width: 0; }
  /* A tall poster must not push the text and buttons off a short phone
     screen, so it yields more height on small viewports. */
  .notice-popup__media img { max-height: min(42svh, 22rem); }
  .notice-popup__media { padding: var(--vsic-space-2xs); }
}

/* ==========================================================================
   JOURNAL / NEWS
   ========================================================================== */

.p-journal__cover {
  flex: 0 0 7rem;
  max-width: 7rem;
  aspect-ratio: 3 / 4;
  border-radius: var(--vsic-radius-md);
}

@media (max-width: 47.99em) {
  .p-journal__cover { flex-basis: 5.5rem; max-width: 5.5rem; }
}

.p-journal__authors {
  margin: 0;
  font-size: var(--vsic-text-sm);
  font-style: italic;
  color: var(--vsic-text-secondary);
}

.p-journal__byline {
  margin: var(--vsic-space-2xs) 0 0;
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
}

.p-journal__block { margin-bottom: var(--vsic-space-xl); }
.p-journal__block > .c-section-head__title { margin-bottom: var(--vsic-space-2xs); }

.p-journal__figure { margin: var(--vsic-space-md) 0; }
.p-journal__figure img { border-radius: var(--vsic-radius-md); }
.p-journal__figure figcaption {
  margin-top: var(--vsic-space-3xs);
  font-size: var(--vsic-text-xs);
  color: var(--vsic-text-muted);
}

/* ==========================================================================
   CONTACT
   ========================================================================== */

.p-contact__block-title {
  margin: 0 0 var(--vsic-space-3xs);
  font-family: var(--vsic-font-heading);
  font-size: var(--vsic-text-base);
  font-weight: var(--vsic-weight-semibold);
  color: var(--vsic-text-primary);
}

.p-contact__strong { margin: 0; font-weight: var(--vsic-weight-medium); color: var(--vsic-text-primary); }
.p-contact__strong a { color: inherit; text-decoration: none; }
.p-contact__strong a:hover { color: var(--vsic-brand-secondary); text-decoration: underline; }
.p-contact__block .c-card__text { margin: 0; }

.p-contact__map-head { margin: var(--vsic-section-y) 0 var(--vsic-space-lg); text-align: center; }
.p-contact__map-head .c-section-head__lead { margin-inline: auto; }

.p-contact__map {
  border: 1px solid var(--vsic-border);
  border-radius: var(--vsic-radius-lg);
  box-shadow: var(--vsic-shadow-sm);
}

.p-contact__faq { margin-top: var(--vsic-section-y); }
