/* ==========================================================================
   layout.css — deck shell, slide stacking, slide layouts, masonry grids

   Full-bleed system (desktop / landscape):
   - The stage fills the whole viewport. Header and footer float above it.
   - Images run to the screen edges (top, bottom and outer side).
   - Text sits inside margins that clear the floating header and footer.
   - Multi-image slides use a masonry grid with 4px seams; each slide has
     its own mix of portrait, landscape and panoramic frames.
   - Media alternates sides (layout-split--media-left) for rhythm.

   The deck behaviour (one slide at a time) only applies when JavaScript
   is available (html.js). Without JavaScript the slides stack as one page.
   ========================================================================== */

html,
body {
  background: var(--color-surface);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: 100%;
}

.js body {
  overflow: hidden;
  overscroll-behavior: none;
}

/* ---------- Deck shell ---------- */

.js .deck {
  position: fixed;
  inset: 0;
  height: 100vh;
  height: 100dvh;
  background: var(--color-surface);
}

.deck__header,
.deck__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-inline: var(--chrome-inset);
  z-index: 3;
}

.js .deck__header,
.js .deck__footer {
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none; /* only the chips and buttons catch clicks */
}

.js .deck__header {
  top: 0;
  height: var(--header-h);
  padding-top: env(safe-area-inset-top, 0);
}

.js .deck__footer {
  bottom: 0;
  height: var(--footer-h);
  padding-bottom: env(safe-area-inset-bottom, 0);
}

.deck__header > *,
.deck__footer > * {
  pointer-events: auto;
}

.no-js .deck__header {
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--color-rule);
}

.no-js .deck__footer {
  display: none;
}

.deck__stage {
  position: relative;
  outline: none;
}

.js .deck__stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

/* ---------- Slides ---------- */

/* A slide withdrawn with the `hidden` attribute is skipped entirely:
   not shown, not navigable, not counted (see js/slides.js). */
.slide[hidden] {
  display: none !important;
}

/* Visible-slide counter: drives the "05 —" eyebrow numbers so they stay
   sequential when a slide is hidden or restored, with or without JS. */
.deck__stage {
  counter-reset: slide;
}

.slide:not([hidden]) {
  counter-increment: slide;
}

.slide {
  background: var(--color-surface);
}

.no-js .slide {
  min-height: 100vh;
  border-bottom: 1px solid var(--color-rule);
}

.js .slide {
  position: absolute;
  inset: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--duration-slide) var(--ease-slide),
    visibility 0s linear var(--duration-slide);
}

.js .slide.is-active {
  opacity: 1;
  visibility: visible;
  transition:
    opacity var(--duration-slide) var(--ease-slide),
    visibility 0s linear 0s;
  z-index: 1;
}

.slide__inner {
  width: 100%;
  min-height: 100%;
}

/* Text column: vertically centred, never clipped when content is long.
   Padding clears the floating header and footer. */
.slide__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding-top: calc(var(--header-h) + var(--stage-pad-block));
  padding-bottom: calc(var(--footer-h) + var(--stage-pad-block));
}

.slide__text > :first-child {
  margin-top: auto;
}

.slide__text > :last-child {
  margin-bottom: auto;
}

/* ---------- Layout: split (text in margins + full-bleed media) ---------- */

.layout-split {
  --text-col: minmax(0, 0.9fr);
  --media-col: minmax(0, 1.1fr);
  display: grid;
  grid-template-columns: var(--text-col) var(--media-col);
  align-items: stretch;
}

.layout-split > .slide__text {
  padding-left: var(--gutter);
  padding-right: var(--column-gap);
}

.layout-split--cover {
  --text-col: minmax(0, 0.8fr);
  --media-col: minmax(0, 1.2fr);
}

.layout-split--wide-text {
  --text-col: minmax(0, 1.12fr);
  --media-col: minmax(0, 0.88fr);
}

.layout-split--project {
  --text-col: minmax(0, 1fr);
  --media-col: minmax(0, 1fr);
}

.layout-split--media-left {
  grid-template-columns: var(--media-col) var(--text-col);
}

.layout-split--media-left > .slide__media {
  order: -1;
}

.layout-split--media-left > .slide__text {
  padding-left: var(--column-gap);
  padding-right: var(--gutter);
}

/* Text-only slide (no media column) — slide 11 until brand assets are supplied */
.layout-split--text-only {
  grid-template-columns: minmax(0, 1fr);
}

.layout-split--text-only > .slide__text {
  max-width: calc(64rem + var(--gutter) * 2);
  padding-right: var(--gutter);
}

/* ---------- Media column ---------- */

.slide__media {
  position: relative;
  min-width: 0;
  min-height: 0;
}

.media-grid {
  position: absolute;
  inset: 0;
  display: grid;
  gap: var(--media-gap);
  grid-template-areas: "a";
}

.media-grid > .ph:nth-child(1) { grid-area: a; }
.media-grid > .ph:nth-child(2) { grid-area: b; }
.media-grid > .ph:nth-child(3) { grid-area: c; }
.media-grid > .ph:nth-child(4) { grid-area: d; }

/* ---------- Masonry templates (one per slide) ----------
   a, b, c, d = 1st, 2nd, 3rd, 4th image in the HTML.            */

/* 01, 04, 10, 12 — single full-bleed image */
.media-grid--single {
  grid-template-areas: "a";
}

/* 02 — reserved: two-image practice layout. Not in use in Step 2
   (slide 02 uses --single until a second authentic photograph exists). */
.media-grid--practice {
  grid-template-rows: 1.5fr 1fr;
  grid-template-areas:
    "a"
    "b";
}

/* 03 — two portraits over a panorama */
.media-grid--capabilities {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1.35fr 1fr;
  grid-template-areas:
    "a b"
    "c c";
}

/* 05 — panorama hero, tall master plan, two landscapes */
.media-grid--oasis {
  grid-template-columns: 1.15fr 1fr;
  grid-template-rows: 1.15fr 1fr 1fr;
  grid-template-areas:
    "a a"
    "b c"
    "b d";
}

/* 06 — landscape hero over a square and a portrait */
.media-grid--brazil {
  grid-template-columns: 1.4fr 1fr;
  grid-template-rows: 1.1fr 1fr;
  grid-template-areas:
    "a a"
    "b c";
}

/* 07 — pinwheel: wide hero, portrait sports, portrait site plan, wide landscape */
.media-grid--park {
  grid-template-columns: 1.15fr 0.75fr 1.15fr;
  grid-template-rows: 1.1fr 1fr;
  grid-template-areas:
    "a a c"
    "b d d";
}

/* 03 How We Work (v1.6; formerly 08) — two drawings over a wide drawing */
.media-grid--technical {
  grid-template-columns: 1.35fr 1fr;
  grid-template-rows: 1.4fr 1fr;
  grid-template-areas:
    "a c"
    "b b";
}

/* Reserved (unused since v1.5): tall + narrow portraits over a panorama.
   Slide 09 now uses .layout-portfolio (project cards). */
.media-grid--additional {
  grid-template-columns: 1.3fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-areas:
    "a b"
    "a b"
    "c c";
}

/* 11 — reserved: panorama over two portraits. Not in use in Step 2
   (slide 11 is text-only until brand assets are supplied). */
.media-grid--ecosystem {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1.25fr;
  grid-template-areas:
    "c c"
    "a b";
}

/* ---------- Layout: statement (text-led, two balanced columns) ----------
   Used on slides 02 and 10 while their photographs are pending.
   Left: eyebrow + heading. Right: body text (and list), behind a hairline. */

.layout-statement {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  column-gap: var(--column-gap);
  align-items: center;
  align-content: center;
  max-width: calc(84rem + var(--gutter) * 2);
  padding: calc(var(--header-h) + var(--stage-pad-block)) var(--gutter) calc(var(--footer-h) + var(--stage-pad-block));
}

.statement__lead,
.statement__body {
  min-width: 0;
}

.statement__body {
  padding-left: var(--column-gap);
  border-left: 1px solid var(--color-rule);
}

/* ---------- Layout: process (head + bleed media above, steps below) ---------- */

.layout-process {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  grid-template-areas:
    "head  media"
    "steps steps";
}

.layout-process__head {
  grid-area: head;
  padding-left: var(--gutter);
  padding-right: var(--column-gap);
  padding-bottom: var(--stage-pad-block);
}

.layout-process__media {
  grid-area: media;
  min-height: 12rem;
}

.layout-process__steps {
  grid-area: steps;
  padding: calc(var(--stage-pad-block) + 0.5rem) var(--gutter) calc(var(--footer-h) + var(--stage-pad-block) * 0.5);
}

/* ---------- Layout: portfolio (slide 09 — Selected Projects) ----------
   Heading block, then one row of project cards inside the margins.
   Cards share one image ratio (4:3) so the row reads as a set. */

.layout-portfolio {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-fluid);
  padding: calc(var(--header-h) + var(--stage-pad-block)) var(--gutter) calc(var(--footer-h) + var(--stage-pad-block));
}

.portfolio__head {
  min-width: 0;
}

.project-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-5) clamp(0.75rem, 1.4vw, 1.5rem);
}

/* ---------- Layout: practice (slide 02 — The Practice) ----------
   v1.6: practice statement, capabilities and team on one text-led slide.
   Intro across the top; capabilities (left) and team (right) below. */

.layout-practice {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
  grid-template-areas:
    "intro intro"
    "caps  team";
  gap: var(--space-fluid) var(--column-gap);
  align-content: center;
  padding: calc(var(--header-h) + var(--stage-pad-block)) var(--gutter) calc(var(--footer-h) + var(--stage-pad-block));
}

.practice__intro {
  grid-area: intro;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: var(--column-gap);
  align-items: end;
}

.practice__capabilities {
  grid-area: caps;
  min-width: 0;
}

.practice__team {
  grid-area: team;
  min-width: 0;
}
