/* ==========================================================================
   VS INTERNATIONAL COLLEGE — LAYOUT
   --------------------------------------------------------------------------
   Composition primitives. Every class is namespaced `l-` and is new, so
   nothing here can collide with Bootstrap's grid or style.css. Pages are
   migrated off `.container` / `.row` / `.col-*` onto these progressively.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. CONTAINER
   -------------------------------------------------------------------------- */

.l-container {
  width: 100%;
  max-width: var(--vsic-container-lg);
  margin-inline: auto;
  padding-inline: var(--vsic-gutter);
}

.l-container--sm { max-width: var(--vsic-container-sm); }
.l-container--md { max-width: var(--vsic-container-md); }
.l-container--xl { max-width: var(--vsic-container-xl); }
.l-container--full { max-width: none; }

/* Escape a constrained parent to full viewport width. */
.l-container--bleed {
  width: 100vw;
  max-width: 100vw;
  margin-inline: calc(50% - 50vw);
  padding-inline: 0;
}

/* --------------------------------------------------------------------------
   2. SECTION RHYTHM
   Replaces legacy `section_gap`, `section_gap_top`, `section_gap_bottom`.
   -------------------------------------------------------------------------- */

.l-section {
  padding-block: var(--vsic-section-y);
}

.l-section--top    { padding-block: var(--vsic-section-y) 0; }
.l-section--bottom { padding-block: 0 var(--vsic-section-y); }
.l-section--tight  { padding-block: calc(var(--vsic-section-y) * 0.55); }
.l-section--flush  { padding-block: 0; }

/* Alternating surfaces for visual separation between adjacent sections. */
.l-section--subtle  { background: var(--vsic-surface-subtle); }
.l-section--muted   { background: var(--vsic-surface-muted); }
.l-section--inverse {
  background: var(--vsic-surface-inverse);
  color: var(--vsic-text-inverse);
}

/* Bare text inside a dark section must inherit the inverse colour, not the
   light-surface element default (base.css `p,label{color:text-secondary}`). */
.l-section--inverse p,
.l-section--inverse li,
.l-section--inverse label { color: inherit; }

/* --------------------------------------------------------------------------
   3. STACK — vertical flow with a single owned gap.
   -------------------------------------------------------------------------- */

.l-stack {
  display: flex;
  flex-direction: column;
  gap: var(--l-stack-gap, var(--vsic-space-md));
}

.l-stack--3xs { --l-stack-gap: var(--vsic-space-3xs); }
.l-stack--2xs { --l-stack-gap: var(--vsic-space-2xs); }
.l-stack--xs  { --l-stack-gap: var(--vsic-space-xs); }
.l-stack--sm  { --l-stack-gap: var(--vsic-space-sm); }
.l-stack--lg  { --l-stack-gap: var(--vsic-space-lg); }
.l-stack--xl  { --l-stack-gap: var(--vsic-space-xl); }

/* --------------------------------------------------------------------------
   4. CLUSTER — horizontal group that wraps gracefully.
   -------------------------------------------------------------------------- */

.l-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--l-cluster-gap, var(--vsic-space-sm));
}

.l-cluster--2xs { --l-cluster-gap: var(--vsic-space-2xs); }
.l-cluster--xs  { --l-cluster-gap: var(--vsic-space-xs); }
.l-cluster--md  { --l-cluster-gap: var(--vsic-space-md); }
.l-cluster--lg  { --l-cluster-gap: var(--vsic-space-lg); }

.l-cluster--between { justify-content: space-between; }
.l-cluster--center  { justify-content: center; }
.l-cluster--end     { justify-content: flex-end; }
.l-cluster--top     { align-items: flex-start; }
.l-cluster--stretch { align-items: stretch; }

/* --------------------------------------------------------------------------
   5. GRID — auto-fit card grids. No breakpoint maths required.
   -------------------------------------------------------------------------- */

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

.l-grid--sm-items { --l-grid-min: 13rem; }
.l-grid--lg-items { --l-grid-min: 22rem; }
.l-grid--xl-items { --l-grid-min: 28rem; }

.l-grid--gap-sm { --l-grid-gap: var(--vsic-space-sm); }
.l-grid--gap-lg { --l-grid-gap: var(--vsic-space-lg); }
.l-grid--gap-xl { --l-grid-gap: var(--vsic-space-xl); }

/* Fixed-column grids that collapse to one column on small screens. */
.l-grid--2,
.l-grid--3,
.l-grid--4 {
  grid-template-columns: 1fr;
}

@media (min-width: 40em) {
  .l-grid--2 { grid-template-columns: repeat(2, 1fr); }
  .l-grid--4 { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 60em) {
  .l-grid--3 { grid-template-columns: repeat(3, 1fr); }
  .l-grid--4 { grid-template-columns: repeat(4, 1fr); }
}

/* --------------------------------------------------------------------------
   6. SPLIT — asymmetric two-column (content + media).
   -------------------------------------------------------------------------- */

.l-split {
  display: grid;
  gap: var(--l-split-gap, var(--vsic-space-xl));
  align-items: center;
  grid-template-columns: 1fr;
}

/* Grid tracks default to min-width:auto, so a wide child — an Owl carousel
   stage, a long table, a pre block — can blow a 1fr track past its share and
   wreck the ratio. Letting children shrink to zero keeps the split honest. */
.l-split > * { min-width: 0; }

@media (min-width: 62em) {
  .l-split {
    grid-template-columns: var(--l-split-ratio, 1fr 1fr);
  }

  .l-split--content-first { --l-split-ratio: 1.1fr 0.9fr; }
  .l-split--media-first   { --l-split-ratio: 0.9fr 1.1fr; }
  .l-split--sidebar       { --l-split-ratio: minmax(0, 1fr) 20rem; }
  .l-split--sidebar-left  { --l-split-ratio: 20rem minmax(0, 1fr); }

  /* Flip visual order without touching DOM order (keeps reading order sane). */
  .l-split__media--first { order: -1; }
}

/* --------------------------------------------------------------------------
   7. MASONRY — used by the gallery. CSS grid with row spanning, which
   preserves DOM order (unlike CSS `columns`, which reads top-to-bottom
   per column and breaks keyboard/screen-reader flow).
   -------------------------------------------------------------------------- */

.l-masonry {
  display: grid;
  grid-template-columns: repeat(
    auto-fill,
    minmax(min(var(--l-masonry-min, 17rem), 100%), 1fr)
  );
  grid-auto-rows: var(--l-masonry-row, 8px);
  gap: 0 var(--vsic-space-md);
}

/* Item height is set by JS via --l-masonry-span; this is the fallback. */
.l-masonry__item {
  grid-row-end: span var(--l-masonry-span, 40);
  margin-bottom: var(--vsic-space-md);
}

/* Without JS the grid degrades to an even, still-attractive layout. */
.no-js .l-masonry,
.l-masonry--static {
  grid-auto-rows: auto;
  gap: var(--vsic-space-md);
}

.no-js .l-masonry__item,
.l-masonry--static .l-masonry__item {
  grid-row-end: auto;
  margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   8. ASPECT RATIOS — replaces the fixed-height `media-frame-*` classes.
   -------------------------------------------------------------------------- */

.l-ratio {
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--l-ratio, 16 / 9);
}

.l-ratio > img,
.l-ratio > video,
.l-ratio > iframe {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.l-ratio--square   { --l-ratio: 1 / 1; }
.l-ratio--portrait { --l-ratio: 3 / 4; }
.l-ratio--photo    { --l-ratio: 4 / 3; }
.l-ratio--wide     { --l-ratio: 16 / 9; }
.l-ratio--ultra    { --l-ratio: 21 / 9; }

/* --------------------------------------------------------------------------
   9. UTILITIES — deliberately minimal. This is not a utility framework.
   -------------------------------------------------------------------------- */

.l-center      { margin-inline: auto; }
.l-text-center { text-align: center; }
.l-measure     { max-width: var(--vsic-measure); }
.l-full-height { min-height: 100svh; }
.l-relative    { position: relative; }

/* Anything that must sit above a decorative background layer. */
.l-layer-content { position: relative; z-index: var(--vsic-z-raised); }
.l-layer-behind  { position: absolute; inset: 0; z-index: var(--vsic-z-below); }
