/* M21 sections ------------------------------------------------------------------
   The M21 page itself: hero, vision, architecture, experience, location and
   closing, in document order, with the responsive blocks for all of them at
   the end of the sheet. This is m21-landing's sections.css with the pieces
   the whole site now shares (display title, section opening, facts card,
   quote, slider rail, footer) moved out to patterns.css, unchanged. Layout
   lives here; the decisions it is built from live in tokens.css.
   -------------------------------------------------------------------------- */

/* Display headings ----------------------------------------------------------
   Every section title shares the light serif, uppercase, with a little air in
   the tracking. Sizes are set per heading below. */
.hero h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--w-light);
  letter-spacing: var(--track-display);
  line-height: var(--lead-display);
  text-transform: uppercase;
  font-variant-numeric: lining-nums;
}

/* Sentence-case statements: the programme titles. */
.programme-copy h3 {
  font-family: var(--font-display);
  font-weight: var(--w-light);
  letter-spacing: var(--track-title);
  line-height: var(--lead-title);
  /* Cormorant's default figures are old-style; the system reads lining
     everywhere so "M21" never drops to x-height. */
  font-variant-numeric: lining-nums;
}

/* Hero ------------------------------------------------------------------ */
.hero {
  position: relative;
  /* A screen tall, and taller only if the copy needs it. The centred copy
     block below sets the height; the media is pinned to it. */
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
  isolation: isolate;
  background: var(--charcoal-2);
  color: var(--cream);
}

.hero-image {
  position: absolute;
  z-index: -4;
  inset: -4%;
  background-image: url("../assets/m21/tower-000.jpg");
  background-repeat: no-repeat;
  background-size: auto 104%;
  background-position: 69% calc(50% + var(--hero-shift, 0px));
  filter: saturate(.68) contrast(1.05) brightness(.62);
  transform: scale(1.02);
}

.hero-video {
  position: absolute;
  z-index: -4;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Every viewport narrower than the clip's 16:9 crops sideways, and the
     narrower it gets the more the window drifts off the tower. Solving for a
     constant on-screen position lands on 47%, which holds the tower at just
     under two-thirds across from ultrawide down to a phone -- so this needs no
     per-breakpoint override. */
  object-position: 47% center;
  /* No global darkening: the wash below handles it, localised to the text
     side, so the planted facade stays readable. */
  filter: saturate(.95);
  transform: scale(1.04) translateY(calc(var(--hero-shift, 0px) * .6));
  pointer-events: none;
}

.hero::before {
  content: "";
  position: absolute;
  z-index: -5;
  inset: 0;
  background:
    linear-gradient(90deg, #1c1b18 0%, #1f1e1b 38%, rgba(31, 30, 27, .85) 50%, rgba(31, 30, 27, .36) 77%, #242320 100%),
    url("../assets/m21/tower-000.jpg") center / cover;
  filter: blur(10px) saturate(.55) brightness(.6);
  transform: scale(1.05);
}

/* The copy is centred and sits in the lower third, so the wash is a deep
   foot band with a light vignette behind the statement and a thin band under
   the masthead. The middle of the frame — the tower's planted body — is left
   almost untouched. */
.hero-wash {
  position: absolute;
  z-index: -3;
  inset: 0;
  background:
    radial-gradient(ellipse 46% 30% at 50% 64%, rgba(27, 26, 23, .52), rgba(27, 26, 23, .24) 56%, transparent 100%),
    linear-gradient(0deg, rgba(24, 23, 20, .86) 0%, rgba(24, 23, 20, .44) 28%, transparent 58%),
    linear-gradient(180deg, rgba(24, 23, 20, .66) 0%, rgba(24, 23, 20, .3) 18%, transparent 34%);
}

/* ---------------------------------------------------------------------------
   Hero concepts. Base rules above are Concept A (still image, original grade).
   Concept B swaps in the video and the lighter, text-localised wash it needs.
   Both concepts share every other rule in this file.
   --------------------------------------------------------------------------- */

/* No old photo anywhere in Concept B. The video's poster (its own first frame)
   covers the gap before playback, so there is nothing to fall back to. */
.hero-mode-video .hero-image { display: none; }

.hero-mode-video .hero::before {
  background: linear-gradient(90deg, #1c1b18 0%, #1f1e1b 45%, #242320 100%);
  filter: none;
}

.hero-mode-video .hero-wash {
  background:
    radial-gradient(ellipse 44% 28% at 50% 64%, rgba(27, 26, 23, .48), rgba(27, 26, 23, .22) 56%, transparent 100%),
    linear-gradient(0deg, rgba(24, 23, 20, .84) 0%, rgba(24, 23, 20, .42) 28%, transparent 56%),
    linear-gradient(180deg, rgba(24, 23, 20, .62) 0%, rgba(24, 23, 20, .28) 18%, transparent 32%);
}

/* Five rows: space, name, statement, a smaller space, cue. The two flexible
   tracks split 2.2 : 1, which lands the name and its statement together in
   the lower third of the screen — under the tower's planted body rather than
   across it, and over the foot band where the type reads without a heavy
   wash. In flow rather than pinned, so a short viewport grows the hero
   instead of clipping it. */
.hero-copy {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  min-height: 100svh;
  padding: clamp(36px, 6vh, 64px) calc(var(--pad) + var(--rail)) calc(clamp(24px, 4vh, 48px) + env(safe-area-inset-bottom, 0px));
  display: grid;
  grid-template-rows: 2.2fr auto auto 1fr auto;
  justify-items: center;
  text-align: center;
  /* The headline is sized against this column rather than the viewport. */
  container-type: inline-size;
}

.hero h1 {
  /* A masthead rather than a display title: one line, held to a modest size
     so it reads as the page's name and not as its statement. It sits directly
     over the statement, a short breath apart. */
  grid-row: 2;
  font-size: clamp(34px, 4.4cqw, 60px);
  line-height: 1;
  letter-spacing: .06em;
  /* Optical centring: tracking adds space after the last letter too. */
  margin-right: -.06em;
  margin-bottom: clamp(18px, 3vh, 32px);
}

.hero-lead { grid-row: 3; max-width: 470px; }

.hero-lead > p {
  margin: 0;
  /* Two even lines rather than a full line and an orphan. */
  text-wrap: balance;
  font-size: clamp(16px, 1.2vw, 20px);
  font-weight: var(--w-light);
  line-height: 1.6;
  letter-spacing: .005em;
  color: rgba(var(--paper-rgb), .9);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 12px;
  margin-top: clamp(24px, 3.5vh, 36px);
}

.hero .scroll-cue { grid-row: 5; align-self: end; }

/* Vision ---------------------------------------------------------------- */
.vision, .experience, .closing { padding: var(--space-section) var(--pad); }

.vision-composition { position: relative; display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(300px, .72fr); column-gap: clamp(14px, 2vw, 32px); align-items: end; }
.plaza-image { margin: 0; }
.plaza-image img { width: 100%; aspect-ratio: 1.37 / 1; object-fit: cover; }

.vision-text { margin-top: clamp(64px, 8vw, 120px); display: grid; grid-template-columns: 1fr .72fr; gap: clamp(44px, 8vw, 134px); align-items: start; }
.vision-text > div p { max-width: 46ch; margin: 0; color: var(--ink-2); font-size: 17px; }

/* Architecture ---------------------------------------------------------- */
.architecture { padding: var(--space-section) var(--pad); }

/* Tower study: a black-and-white elevation, centred, with the programme
   called out beside it. Each call-out sits at its own height (--at, a
   percentage of the photo) and reaches the photo's edge with a short leader:
   the label to the left, the figure to the right. */
.tower-study { display: flex; justify-content: center; }
.tower-figure { width: min(34vw, 380px); margin: 0; }
.tower-plate { position: relative; }
.tower-plate img { width: 100%; aspect-ratio: 941 / 1376; object-fit: cover; filter: grayscale(1) contrast(1.06); }
.level-key { position: absolute; inset: 0; pointer-events: none; }
.key-line { position: absolute; top: var(--at); left: 0; width: 100%; height: 0; font-size: 11px; text-transform: uppercase; letter-spacing: .14em; white-space: nowrap; }
.key-line b,
.key-line small { position: absolute; top: 0; display: flex; align-items: center; gap: 14px; transform: translateY(-50%); }
.key-line b { right: 100%; }
.key-line small { left: 100%; font-size: 10px; color: var(--cream-2); }
.key-line b::after,
.key-line small::before { content: ""; flex: none; width: 44px; height: 1px; background: rgba(var(--paper-rgb), .45); }
/* Where each part sits on the photograph, top to bottom. */
.key-line:nth-child(1) { --at: 11%; }
.key-line:nth-child(2) { --at: 22%; }
.key-line:nth-child(3) { --at: 50%; }
.key-line:nth-child(4) { --at: 86%; }

/* Programme — four full-bleed views that swipe up over one another as the page
   scrolls, no clicking. Each panel box is taller than the screen: its frame
   pins to the top for --panel-hold, then the next panel — pulled up by one
   viewport with a negative margin — slides a full screen height over it while
   the one below stays pinned. Pure sticky, so the swipe tracks the scroll
   exactly and never runs on a timer. */
.programme {
  --panel-hold: 45vh;
  --panel-hold: 45svh;
  position: relative;
  /* Break out of .architecture's side padding to the full screen width. Using
     the section's own --pad keeps this scrollbar-safe, unlike 100vw. */
  margin: clamp(60px, 8vw, 110px) calc(var(--pad) * -1) calc(var(--space-section) * -1);
  border-top: 1px solid var(--line-light);
}
.programme-panel { position: relative; height: calc(200vh + var(--panel-hold)); height: calc(200svh + var(--panel-hold)); }
.programme-panel + .programme-panel { margin-top: -100vh; margin-top: -100svh; }
.programme-frame { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; display: flex; align-items: flex-end; background: var(--charcoal); }
.programme-panel + .programme-panel .programme-frame { border-top: 1px solid rgba(var(--paper-rgb), .35); }
.programme-image { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; }
.programme-veil { position: absolute; inset: 0; background: linear-gradient(0deg, rgba(29, 28, 25, .92), rgba(29, 28, 25, .42) 38%, rgba(29, 28, 25, .04) 72%), linear-gradient(90deg, rgba(29, 28, 25, .52), transparent 62%); }
.programme-copy { position: relative; width: min(820px, 100%); padding: 0 var(--pad) clamp(56px, 9vh, 104px); color: var(--cream); }
.programme-index { margin: 0 0 20px; font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: var(--cream-2); }
.programme-copy h3 { margin: 0 0 26px; font-size: clamp(40px, 5.4vw, 84px); line-height: .98; }
.programme-copy > p:not(.programme-index):not(.programme-data) { margin: 0; max-width: 38ch; font-weight: var(--w-light); color: rgba(var(--paper-rgb), .8); }
.programme-data { display: inline-block; margin: 34px 0 0; padding-top: 15px; border-top: 1px solid var(--line-light); font-size: 11px; text-transform: uppercase; letter-spacing: .16em; }

/* Experience ----------------------------------------------------------------
   The opening beside a rail of cards: the label, title and paragraph every
   section opens with in a narrow left column, the four interior views on the
   right, on a rail that runs on past the column's edge.
   -------------------------------------------------------------------------- */
.experience-grid {
  display: grid;
  grid-template-columns: minmax(0, .7fr) minmax(0, 1.3fr);
  gap: clamp(40px, 7vw, 118px);
  align-items: start;
}
.experience .section-opening { margin-bottom: 0; }

/* Location ------------------------------------------------------------------
   One full-bleed photograph, with the copy set over its darker left-hand
   side.
   -------------------------------------------------------------------------- */
.location { position: relative; height: max(580px, 72svh); color: var(--cream); overflow: hidden; background: var(--charcoal-2); isolation: isolate; }
.location-image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Scrim only where type sits: the left column and the base. The sunset and the
   sky on the right are left alone. */
.location-shade { position: absolute; inset: 0; background: linear-gradient(90deg, rgba(26, 25, 22, .86), rgba(26, 25, 22, .34) 46%, rgba(26, 25, 22, 0) 68%), linear-gradient(0deg, rgba(26, 25, 22, .82), rgba(26, 25, 22, .12) 42%, rgba(26, 25, 22, 0) 62%), linear-gradient(180deg, rgba(26, 25, 22, .42), transparent 22%); }
.location-copy { position: absolute; z-index: 2; left: var(--pad); bottom: clamp(56px, 8vw, 120px); width: min(760px, calc(100% - var(--pad) * 2)); }
.location-copy .display-title { white-space: normal; text-wrap: balance; }
.location-copy > p:nth-of-type(2) { width: min(460px, 70vw); margin: 0; max-width: 52ch; font-weight: var(--w-light); color: rgba(var(--paper-rgb), .84); }

/* Closing --------------------------------------------------------------- */
/* Closing: the same opening stack as every section, then one button. */
.closing .section-opening { margin-bottom: clamp(28px, 3vw, 40px); }

/* Responsive ----------------------------------------------------------------
   Dialog breakpoints live in components.css and the shared patterns carry
   their own; these are the M21 sections only.
   -------------------------------------------------------------------------- */

/* Below this the track beside the photo is too narrow for the longest value,
   so it drops under its own label instead of being squeezed off the edge. */
@media (max-width: 1180px) {
}

@media (max-width: 960px) {
  .hero-image { background-position: 66% calc(50% + var(--hero-shift, 0px)); }
  .vision-text { grid-template-columns: minmax(0, 1fr); }
  /* Stacked: the opening first, then the rail, with the same interval the
     Vision section keeps between its opening and its photograph. The rail
     runs edge to edge here, its cards starting on the section's own margin. */
  .experience-grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-intro); }
  .vision-composition { grid-template-columns: 1fr; }
  .vision-text { gap: 36px; }
  /* Below this width there is no room for a figure on the photo's right, so
     the label and its figure stack on the left and the photo takes the right
     half of the measure. */
  .tower-figure { width: 100%; }
  .tower-plate, .tower-figure figcaption { width: 50%; margin-left: auto; }
  .key-line { left: auto; right: 100%; width: 88%; height: auto; display: grid; justify-items: end; gap: 4px; transform: translateY(-50%); text-align: right; white-space: normal; }
  .key-line b, .key-line small { position: static; transform: none; }
  .key-line b { gap: 12px; }
  .key-line b::after { width: 28px; }
  .key-line small { display: block; padding-right: 40px; line-height: 1.4; letter-spacing: .1em; }
  .key-line small::before { display: none; }
  .programme { --panel-hold: 30vh; --panel-hold: 30svh; }
}

@media (max-width: 680px) {
  :root { --rail: 11px; }

  .hero-copy {
    padding: clamp(28px, 5vh, 48px) calc(var(--pad) + var(--rail)) calc(clamp(22px, 4vh, 40px) + env(safe-area-inset-bottom, 0px));
  }
  .hero::before { background: #1c1b18; }
  .hero-image { inset: 0; background-size: auto 100%; background-position: 63% bottom; filter: saturate(.65) brightness(.62); }
  /* The phone frames the tower tightly, so the vignette is wider and the
     bands deeper than on a desktop. */
  .hero-wash { background: radial-gradient(ellipse 74% 28% at 50% 62%, rgba(24, 23, 20, .56), rgba(24, 23, 20, .26) 60%, transparent 100%), linear-gradient(0deg, rgba(24, 23, 20, .92) 0%, rgba(24, 23, 20, .5) 30%, transparent 62%), linear-gradient(180deg, rgba(24, 23, 20, .68) 0%, rgba(24, 23, 20, .3) 16%, transparent 32%); }
  .hero-mode-video .hero-image { filter: saturate(.9) brightness(.88); }
  .hero-mode-video .hero-wash { background: radial-gradient(ellipse 74% 28% at 50% 62%, rgba(24, 23, 20, .5), rgba(24, 23, 20, .22) 60%, transparent 100%), linear-gradient(0deg, rgba(24, 23, 20, .9) 0%, rgba(24, 23, 20, .46) 30%, transparent 60%), linear-gradient(180deg, rgba(24, 23, 20, .62) 0%, rgba(24, 23, 20, .28) 16%, transparent 30%); }
  .hero h1 { font-size: clamp(30px, 11cqw, 44px); }
  .hero-lead { max-width: none; width: 100%; }
  .hero-lead > p { font-size: 15px; line-height: 1.5; }
  /* Two buttons rarely share a phone row; when they wrap, each takes the row. */
  .hero-actions { gap: 10px; margin-top: 22px; }
  .hero-actions .small-cta { flex: 1 1 auto; min-height: 44px; padding: 0 18px; }
  .vision, .experience, .closing, .architecture { padding-top: 92px; padding-bottom: 92px; }
  .plaza-image img { aspect-ratio: .84; }
  .vision-text { margin-top: 72px; }
  /* hyphens is the safety net: if the word still cannot fit a very narrow
     screen it breaks rather than being clipped by the section. */
  /* The silhouette gives back a little width so the level detail can sit
     under its own label rather than being dropped from the page. */
  .tower-plate, .tower-figure figcaption { width: 58%; }
  .key-line { width: 68%; }
  /* The photo is short here and each call-out is two lines, so the top pair
     is spread a little further than the tower's own proportions. */
  .key-line:nth-child(1) { --at: 8%; }
  .key-line:nth-child(2) { --at: 26%; }
  .key-line b { gap: 10px; font-size: 10px; }
  .key-line b::after { width: 22px; }
  .key-line small { padding-right: 32px; font-size: 9px; letter-spacing: .08em; }
  .programme { --panel-hold: 20vh; --panel-hold: 20svh; }
  .programme-copy { padding-bottom: 44px; }
  .programme-copy h3 { margin-bottom: 20px; font-size: clamp(34px, 9.5vw, 58px); font-weight: var(--w-regular); }
  .programme-data { margin-top: 26px; }
  .experience-grid { gap: 72px; }
  .location { height: max(520px, 70svh); }
  /* The copy runs the full width here, so the scrim has to as well. */
  .location-shade { background: linear-gradient(0deg, rgba(26, 25, 22, .92), rgba(26, 25, 22, .6) 42%, rgba(26, 25, 22, .08) 74%), linear-gradient(180deg, rgba(26, 25, 22, .5), transparent 20%); }
  .location-copy > p:nth-of-type(2) { width: 100%; }
}

/* The narrowest phones: five lines of hero copy beside a 92px dial leaves the
   paragraph roughly 170px of measure, which is under ten characters a line at
   15px. Drop a step so it stays readable rather than shredded. */
@media (max-width: 359px) {
  .hero-lead > p { font-size: 14px; line-height: 1.45; }
}

/* Landscape phones ----------------------------------------------------------
   A 390px-tall viewport is the case none of the width breakpoints catch: the
   hero's height floor pushed the headline off the screen. Everything here is
   height-driven, so it applies to a short window on a laptop too.
   -------------------------------------------------------------------------- */
@media (orientation: landscape) and (max-height: 560px) {
  .hero-copy {
    padding: clamp(18px, 4vh, 28px) calc(var(--pad) + var(--rail)) calc(16px + env(safe-area-inset-bottom, 0px));
  }
  .hero h1 { font-size: clamp(26px, 4cqw, 40px); }
  .hero-lead > p { font-size: 15px; line-height: 1.45; }
  .hero-actions { margin-top: 16px; }
  .hero-actions .small-cta { min-height: 40px; }

  /* The pinned panels are sized off the viewport, so a short one needs a
     shorter hold or each swipe costs several screens of scrolling. */
  .programme { --panel-hold: 12vh; --panel-hold: 12svh; }
  .location { height: max(420px, 80svh); }
}

@media (prefers-reduced-motion: reduce) {
  /* No stacked swipe: the panels simply follow one another down the page. */
  .programme-panel { height: auto; }
  .programme-panel + .programme-panel { margin-top: 0; }
  .programme-frame { position: static; height: 86vh; height: 86svh; }
}

/* Integration ---------------------------------------------------------------
   The one adjustment the parent site's header asks of the page: the hero's
   copy starts below the fixed bar rather than under it. With the name down
   beside the statement, the bar only sets the floor of the open space above.
   Last in the sheet so it holds at every breakpoint above.
   -------------------------------------------------------------------------- */
.hero-copy { padding-top: calc(var(--header-h) + clamp(6px, 1.5vh, 16px)); }
