/* ==========================================================================
   LAYOUT — the grid, the section rhythm, the alignment contract.

   GESTALT: CONTINUITY + SYMMETRY
   Every section on every page uses .section > .shell > .grid. That means one
   left edge and one right edge run the full height of the site, uninterrupted.
   The eye follows that line and reads the page as one object rather than a
   stack of unrelated blocks.
   ========================================================================== */

/* --- Shell: the horizontal field ----------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--grid-max);
  margin-inline: auto;
  padding-inline: var(--grid-pad);
}
.shell--wide { max-width: var(--grid-max-wide); }
.shell--narrow { max-width: 52rem; }
.shell--flush { padding-inline: 0; }

/* --- Grid: 12 columns ----------------------------------------------------- */

.grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  gap: var(--grid-gutter);
}
.grid--rows-lg { row-gap: var(--space-8); }
.grid--rows-xl { row-gap: var(--space-9); }

/* Column spans. Mobile-first: everything is full width until 48rem.
   Span and start are set as SEPARATE longhands. Using the `grid-column`
   shorthand for the span would reset grid-column-end to auto the moment a
   `.start-*` class also applied, collapsing the item to a single track. */
[class*="col-"] { grid-column: 1 / -1; }

@media (min-width: 48rem) {
  [class*="col-"] { grid-column-start: auto; grid-column-end: auto; }

  .col-2  { grid-column-end: span 2; }
  .col-3  { grid-column-end: span 3; }
  .col-4  { grid-column-end: span 4; }
  .col-5  { grid-column-end: span 5; }
  .col-6  { grid-column-end: span 6; }
  .col-7  { grid-column-end: span 7; }
  .col-8  { grid-column-end: span 8; }
  .col-9  { grid-column-end: span 9; }
  .col-10 { grid-column-end: span 10; }
  .col-12 { grid-column-end: span 12; }

  .start-2 { grid-column-start: 2; }
  .start-3 { grid-column-start: 3; }
  .start-4 { grid-column-start: 4; }
  .start-6 { grid-column-start: 6; }
  .start-7 { grid-column-start: 7; }
  .start-8 { grid-column-start: 8; }
  .start-9 { grid-column-start: 9; }
  .start-10 { grid-column-start: 10; }
}

/* Tablet intermediate: halves and full widths before thirds and offsets. */
@media (min-width: 48rem) and (max-width: 63.99rem) {
  .col-md-6  { grid-column-end: span 6; }
  .col-md-12 { grid-column-end: span 12; }
  [class*="start-"]:not(.start-md-2) { grid-column-start: auto; }
  .start-md-2 { grid-column-start: 2; }
}

/* --- Section: the vertical rhythm ----------------------------------------
   PROXIMITY: the section gap is always larger than any gap inside a section,
   so groups separate without rules or boxes doing the work.               */

.section {
  position: relative;
  padding-block: var(--space-section);
}
.section--lg { padding-block: var(--space-section-lg); }
.section--sm { padding-block: clamp(var(--space-7), 3vw + 1rem, var(--space-8)); }
.section--flush-top { padding-block-start: 0; }
.section--flush-bottom { padding-block-end: 0; }

/* Figure/ground: alternating planes, never more than two in a row. */
.section--ground { background: var(--color-ground); }
.section--alt { background: var(--color-ground-alt); }
.section--surface { background: var(--color-surface); }
.section--inverse { background: var(--color-inverse); color: var(--color-text-on-dark); }
/* .is-inverse only re-points the tokens; something still has to paint the
   plane. Without this the "dark" band renders on the body's bone ground. */
.section.is-inverse { background: var(--color-ground); color: var(--color-text); }

/* Hairline seam between two same-colored sections — closure without a box. */
.section--seam { border-block-start: var(--border-hair); }

/* --- Stack: vertical proximity utility ------------------------------------ */

.stack > * + * { margin-block-start: var(--stack-gap, var(--space-4)); }
.stack--1 { --stack-gap: var(--space-1); }
.stack--2 { --stack-gap: var(--space-2); }
.stack--3 { --stack-gap: var(--space-3); }
.stack--4 { --stack-gap: var(--space-4); }
.stack--5 { --stack-gap: var(--space-5); }
.stack--6 { --stack-gap: var(--space-6); }
.stack--7 { --stack-gap: var(--space-7); }
.stack--8 { --stack-gap: var(--space-8); }

/* --- Cluster: horizontal grouping ----------------------------------------- */

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--cluster-gap, var(--space-4));
}
.cluster--2 { --cluster-gap: var(--space-2); }
.cluster--3 { --cluster-gap: var(--space-3); }
.cluster--5 { --cluster-gap: var(--space-5); }
.cluster--6 { --cluster-gap: var(--space-6); }
.cluster--between { justify-content: space-between; }
.cluster--center { justify-content: center; }
.cluster--baseline { align-items: baseline; }

/* --- Auto grid: equal cards, similarity enforced --------------------------- */

.auto-grid {
  display: grid;
  gap: var(--grid-gutter);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--auto-min, 17rem)), 1fr));
}
.auto-grid--sm { --auto-min: 13rem; }
.auto-grid--lg { --auto-min: 22rem; }
/* auto-fit packs as many columns as will fit, which leaves a single orphaned
   card in the last row whenever the count does not divide by the column count
   — and an orphan reads as a missing item rather than a deliberate stop.
   mh_grid_class() picks this when the count divides by two but not by three. */
@media (min-width: 60rem) {
  .auto-grid--2 { grid-template-columns: repeat(2, 1fr); }
}

/* --- Split: two-column editorial block ------------------------------------ */

.split {
  display: grid;
  gap: clamp(var(--space-6), 4vw, var(--space-9));
  align-items: center;
}
/* When one column runs much longer than the other — a full biography beside a
   single portrait — centering strands the short column in the middle of the
   long one. Opting into a shared top edge keeps CONTINUITY with the section
   above instead. */
.split--top { align-items: start; }
@media (min-width: 60rem) {
  .split { grid-template-columns: var(--split-ratio, 1fr 1fr); }
  .split--media-first > .split__media { order: -1; }
  .split--wide-text { --split-ratio: 1.15fr 0.85fr; }
  .split--wide-media { --split-ratio: 0.85fr 1.15fr; }
}

/* --- Alignment helpers ---------------------------------------------------- */

.text-center { text-align: center; }
.mx-auto { margin-inline: auto; }
.measure { max-width: var(--measure); }
.measure--tight { max-width: var(--measure-tight); }
.center-column { max-width: var(--measure); margin-inline: auto; text-align: center; }
.full-bleed {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}
