/* ==========================================================================
   THE LEDGE — styles. Tokens first: change a token, the whole site follows.
   Colours and fonts are set in P1 from the student's own picks.
   ========================================================================== */

:root {
  /* colour tokens — measured from the student's palette pin (assets/src/palette.png), P1 2026-10-11 */
  --paper: #eef1f3;          /* P — Blue Dolphin's hue lifted to off-white */
  --concrete: #bec7cd;       /* C — Blue Dolphin (measured) */
  --steel: #828a92;          /* Sea Lion (measured) — rules, muted text on dark */
  --chimney: #4a5256;        /* Chimney (measured) — muted text on paper (7.0:1) */
  --ink: #262a2e;            /* K — Cinder (measured) — text, borders */
  --night: #101016;          /* Black Metal (measured) — the dark grounds: hero, film, footer */
  --accent: #d72f1a;         /* A — vermilion, measured (sunlit) from the student's look reference (assets/src/look-reference.png).
                                The same red is painted inside the house's recesses, so page and photos share one colour.
                                Fills and lines; white text on it is 4.87:1 */
  --accent-text: #ce2d19;    /* A darkened a hair along its own hue — small red text on paper (4.62:1) */
  --accent-glow: #e6412d;    /* A lifted along its own hue — small red text on the night ground (4.65:1) */
  --on-accent: #ffffff;      /* text ON the red (4.87:1); ink on red is only 2.97:1 */
  --ink-soft: rgba(16, 16, 22, .72);
  --paper-soft: rgba(238, 241, 243, .78);

  /* type tokens — self-hosted in assets/fonts (P1). Neue Haas Display sits around Semibold, so the display weight is 600 */
  --w-display: 600;
  --w-word: 700;            /* the giant wordmarks: THE LEDGE, MERIDIAN */
  --f-display: "Inter", "Helvetica Neue", Arial, sans-serif;   /* stand-in for Neue Haas Grotesk (student pin) */
  --f-text: "Inter", "Helvetica Neue", Arial, sans-serif;
  --f-mono: "JetBrains Mono", ui-monospace, Consolas, monospace;

  /* motion tokens — bucket U (locked on approval, see BUILD-LOG) */
  --e-out: cubic-bezier(.16, 1, .3, 1);       /* ≈ expo.out */
  --e-back: cubic-bezier(.34, 1.56, .64, 1);  /* ≈ back.out(1.7) — the rise overshoot */
  --e-snap: cubic-bezier(.3, 1.3, .6, 1);     /* ≈ back.out(1.25) — the drone snap */
  --t-reveal: .7s;
  --small: .36;                               /* drone frame at rest, fraction of the viewport */

  --gutter: clamp(18px, 4vw, 64px);
}

/* ---------- ground ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 17px/1.55 var(--f-text);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}
img, video, canvas { display: block; max-width: none; }
a { color: inherit; }
.off { display: none !important; }
.mono { font-family: var(--f-mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; }
.sec-label { font-family: var(--f-mono); font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--accent-text); }
[data-dark] .sec-label { color: var(--accent-glow); }
#house .sec-label, #site .sec-label { color: var(--ink); }   /* accent-text on Blue Dolphin is 3.0:1 — fails */
.sec-head h2 {
  font: var(--w-display) clamp(48px, 7.4vw, 128px)/.9 var(--f-display);
  letter-spacing: -.04em; margin: 14px 0 0;
}

/* ---------- reveals (CSS owns these; IntersectionObserver adds .in) ---------- */
[data-r] { opacity: 0; transform: translateY(40px); transition: transform var(--t-reveal) var(--e-back), opacity .3s linear; }
[data-r].in { opacity: 1; transform: none; }
[data-clip] { clip-path: inset(100% -0.1em -0.3em -0.1em); transition: clip-path var(--t-reveal) var(--e-out); }
[data-clip].in { clip-path: inset(-0.1em -0.1em -0.3em -0.1em); }   /* the window extends below the box: descenders (g, p, y) hang past a .9 line-height (P9) */

/* ---------- cursor ---------- */
#cursor { position: fixed; inset: 0; z-index: 1000; pointer-events: none; }
#cursor .ring, #cursor .dot { position: absolute; left: 0; top: 0; }
#cursor .ring b {
  display: block; width: 28px; height: 28px; margin: -14px 0 0 -14px; border-radius: 50%;
  border: 1.5px solid var(--ink); background: transparent;
  transition: scale .3s var(--e-back), background-color .2s linear, border-color .2s linear;
}
#cursor .dot { width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; border-radius: 50%; background: var(--ink); }
#cursor.hover .ring b { scale: 2.2; background: color-mix(in srgb, var(--accent) 15%, transparent); border-color: var(--accent); }
#cursor.on-dark .ring b { border-color: var(--paper); }
#cursor.on-dark .dot { background: var(--paper); }
#cursor.on-film { mix-blend-mode: difference; }
#cursor.on-film .ring b { border-color: #fff; }
#cursor.on-film .dot { background: #fff; }
html.has-cursor, html.has-cursor a, html.has-cursor button, html.has-cursor .room { cursor: none; }
html.has-cursor input, html.has-cursor textarea { cursor: text; }

/* ---------- nav (no backdrop-filter, ever — it sits over the playing film) ---------- */
#nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 500;
  display: flex; align-items: center; gap: 32px;
  padding: 18px var(--gutter);
  color: var(--ink); border-bottom: 1px solid transparent;      /* ink over the hero: the sky is pale (ink 5.2:1, paper 2.4:1) */
}
#nav.solid { background: var(--paper); color: var(--ink); border-bottom-color: var(--ink); }
#nav { transition: transform .35s var(--e-out); }
#nav.away { transform: translateY(-100%); }   /* steps aside while the drone film is full-bleed */
#nav .brand { font: var(--w-display) 15px/1 var(--f-display); letter-spacing: .32em; text-decoration: none; text-transform: uppercase; }
#nav .links { display: flex; gap: 26px; margin-left: auto; }
#nav .links a { font-family: var(--f-mono); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; }
#nav .links a:hover { color: var(--accent-text); }
#nav .cta {
  font: 700 13px/1 var(--f-text); letter-spacing: .06em; text-transform: uppercase; text-decoration: none;
  background: var(--accent); color: var(--on-accent); padding: 13px 20px; border-radius: 0;
  transition: transform .25s var(--e-back);
}
#nav .cta:hover { transform: translateY(-2px); }
@media (max-width: 760px) {
  #nav { padding: 14px 18px; }
  #nav .links { display: none; }
  #nav .cta { margin-left: auto; }
}

/* ---------- hero: plate · type · house · line ---------- */
#hero { position: relative; height: 100vh; height: 100svh; overflow: hidden; overflow: clip; background: var(--night); color: var(--paper); }
#heroBg, #heroFg, #heroBgImg, #heroFgImg {
  position: absolute; left: -16px; top: -16px; width: calc(100% + 32px); height: calc(100% + 32px);
}
#heroBgImg, #heroFgImg { object-fit: cover; }
#heroBg, #heroBgImg { z-index: 1; }
#heroType {
  position: absolute; left: 0; top: 0; z-index: 2; margin: 0;
  font: var(--w-word) clamp(96px, 17vw, 300px)/.8 var(--f-display);
  letter-spacing: -.045em; text-transform: uppercase; white-space: nowrap;
  color: var(--ink);                                             /* on the pale sky: ink 6.6:1, paper 1.9:1 */
}
#heroType .w { display: inline-block; clip-path: inset(100% 0 0 0); transition: clip-path .7s var(--e-out); }
#hero.in #heroType .w { clip-path: inset(0 0 0 0); }
#heroFg, #heroFgImg { z-index: 3; }
#hero .hero-line, #hero .hero-meta { position: absolute; z-index: 4; bottom: 5vh; margin: 0; }
#hero .hero-line {                                               /* a plate too: the scrub behind it is busy (worst-case 2.4:1 bare) */
  left: var(--gutter); max-width: 34ch; font-size: 18px; line-height: 1.4;
  padding: 14px 18px 15px; background: var(--ink-soft); color: var(--paper);
}
#hero .hero-meta {                                               /* a solid plate: the surf behind it defeats any text colour */
  right: var(--gutter); padding: 16px 20px 15px; background: var(--night); color: var(--paper);
  font-family: var(--f-mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; text-align: right;
}
#hero .hero-meta b { display: block; font: var(--w-display) clamp(22px, 2.2vw, 34px)/1 var(--f-display); letter-spacing: -.02em; color: var(--accent-glow); margin-bottom: 8px; }
@media (max-width: 760px) {   /* phones: the two plates stack instead of colliding */
  #hero .hero-line { bottom: calc(5vh + 82px); right: var(--gutter); max-width: none; font-size: 16px; }
}

/* ---------- figures ---------- */
#figures { background: var(--paper); padding: 16vh var(--gutter) 14vh; }
.figure-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 7vh 2vw; margin-top: 6vh; }
.figure { grid-column: span 6; border-top: 1px solid var(--ink); padding-top: 18px; }
.figure:nth-child(2) { grid-column: 8 / span 5; margin-top: 12vh; }
.figure:nth-child(3) { grid-column: 2 / span 5; }
.figure:nth-child(4) { grid-column: 8 / span 5; margin-top: 8vh; }
.figure .num {
  display: block; font: var(--w-word) clamp(64px, 9vw, 160px)/.9 var(--f-display);
  letter-spacing: -.04em; font-variant-numeric: tabular-nums;
}
.figure .num .unit { font-size: .34em; letter-spacing: 0; margin-left: .22em; }
.figure .lbl { display: block; margin-top: 14px; }
@media (max-width: 760px) { .figure, .figure:nth-child(n) { grid-column: 1 / -1; margin-top: 0; } }

/* ---------- the house: pinned image, scrolling text ---------- */
#house { position: relative; display: grid; grid-template-columns: 7fr 5fr; background: var(--concrete); }
#houseStage { position: sticky; top: 0; height: 100vh; height: 100svh; padding: 12vh 0 8vh var(--gutter); }
#houseImgs { position: relative; width: 100%; height: 100%; overflow: hidden; overflow: clip; background: var(--night); }
#houseImgs img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; visibility: hidden; }
#houseImgs img.on { visibility: visible; }
#houseImgs img.cut { animation: cutIn .28s var(--e-out) both; }
@keyframes cutIn { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
.house-count { position: absolute; left: var(--gutter); bottom: 8vh; z-index: 2; color: var(--paper); background: var(--night); padding: 9px 12px 8px; }   /* a plate: surf behind */
.house-text { padding: 0 var(--gutter) 0 4vw; }
.house-par { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; justify-content: center; max-width: 30ch; }
.house-par h3 { font: var(--w-display) clamp(34px, 3.6vw, 60px)/.95 var(--f-display); letter-spacing: -.035em; margin: 12px 0 22px; }
.house-par p { margin: 0; font-size: 19px; line-height: 1.5; }
@media (max-width: 860px) {
  #house { grid-template-columns: 1fr; }
  #houseStage { height: 70svh; padding: 10vh 18px 0; }
  .house-count { left: 36px; bottom: 18px; }
  .house-par { min-height: 70svh; }
}

/* ---------- drone reveal: the showpiece ---------- */
#drone { position: relative; height: 360vh; background: var(--night); color: var(--paper); }
.drone-stage { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; overflow: clip; }
.drone-grid {
  position: absolute; inset: -20vh 0; opacity: .14; pointer-events: none;
  background-image: linear-gradient(var(--paper) 1px, transparent 1px), linear-gradient(90deg, var(--paper) 1px, transparent 1px);
  background-size: 120px 120px;
}
#droneFrame {
  position: absolute; inset: 0; z-index: 2; overflow: hidden; background: #000;
  transform: scale(var(--small)); transform-origin: 50% 50%;
  transition: transform .55s var(--e-snap);
}
#droneStory img, #droneVideo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
#droneStory img { visibility: hidden; }
#droneStory img.on { visibility: visible; }
.drone-head {
  position: absolute; left: 0; right: 0; z-index: 3; margin: 0; text-align: center; pointer-events: none;
  font: var(--w-word) clamp(56px, 8.4vw, 150px)/.86 var(--f-display); letter-spacing: -.04em; text-transform: uppercase;
  transition: transform .55s var(--e-out);
}
#droneHeadTop { top: calc(50% - var(--small) * 50svh - 2.4vh); transform: translateY(-100%); }
#droneHeadBot { top: calc(50% + var(--small) * 50svh + 2.4vh); }
#droneLine {
  position: absolute; left: 0; width: 100%; height: 2px; z-index: 4; background: var(--accent);
  top: calc(50% + var(--small) * 50svh); transform: scaleX(var(--small));
  transition: transform .55s var(--e-snap);
}
#drone.snapped #droneFrame { transform: scale(1); }
#drone.snapped #droneHeadTop { transform: translateY(calc((1 - var(--small)) * -50svh - 100% - 4vh)); }
#drone.snapped #droneHeadBot { transform: translateY(calc((1 - var(--small)) * 50svh + 4vh)); }
#drone.snapped #droneLine { transform: translateY(calc((1 - var(--small)) * 50svh - 2px)) scaleX(1); }
#droneCard {
  position: absolute; left: var(--gutter); bottom: 7vh; z-index: 5;
  display: grid; gap: 6px; min-width: 300px; padding: 20px 24px 22px;
  background: var(--night); visibility: hidden;   /* solid: over bright footage a translucent card drops the red counter under 4.5:1 */
}
#drone.snapped #droneCard.live { visibility: visible; }
#droneCard .count { color: var(--accent-glow); }
#droneCard .label { font: 700 13px/1 var(--f-text); letter-spacing: .24em; text-transform: uppercase; }
#droneCard .fig { font: var(--w-word) clamp(48px, 6vw, 96px)/.9 var(--f-display); letter-spacing: -.035em; margin-top: 6px; }
#droneCard .line { font-size: 16px; opacity: .9; }
#droneCard.out { animation: cardOut .09s linear both; }
#droneCard.in { animation: cardIn .14s var(--e-out) both; }
#droneCard.in .fig { animation: figUp .3s var(--e-back) both; }
@keyframes cardOut { from { clip-path: inset(0 0 0 0); } to { clip-path: inset(100% 0 0 0); } }
@keyframes cardIn { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes figUp { from { transform: translateY(6px); } to { transform: none; } }

/* ---------- interiors gallery ---------- */
#interiors { background: var(--paper); padding: 16vh var(--gutter) 18vh; }
.room-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 9vh 2.2vw; margin-top: 9vh; perspective: 1000px; }
.room { margin: 0; transform-style: preserve-3d; container-type: inline-size; }
.room .frame { position: relative; overflow: hidden; overflow: clip; background: var(--concrete); }
.room .shift { position: absolute; inset: -12px; }
.room img { width: 100%; height: 100%; object-fit: cover; }
.room figcaption { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 18px; margin-top: 14px; border-top: 1px solid var(--ink); padding-top: 10px; }
.room figcaption b { font: var(--w-display) clamp(18px, 1.5vw, 24px)/1 var(--f-display); letter-spacing: -.02em; white-space: nowrap; }   /* narrow cards stack the detail below instead */
.room figcaption span { font-family: var(--f-mono); font-size: 12px; letter-spacing: .06em; text-align: right; max-width: 34ch; }
@container (max-width: 420px) {   /* narrow cards (the stair): caption stacks, left-aligned (P9) — placed AFTER the caption rules it overrides */
  .room figcaption { flex-direction: column; }
  .room figcaption span { text-align: left; max-width: none; }
}
@media (max-width: 860px) { .room { grid-column: 1 / -1 !important; margin-top: 0 !important; } }

/* ---------- site & plan ---------- */
#site { background: var(--concrete); padding: 16vh var(--gutter) 16vh; }
.site-grid { display: grid; grid-template-columns: 5fr 7fr; gap: 4vw; align-items: center; margin-top: 8vh; perspective: 1000px; }
#siteMassing { margin: 0; will-change: transform; }   /* its own layer: the blurred drop-shadow is drawn once, the tilt only moves it (P9 perf) */
#siteMassing img { width: 100%; height: auto; filter: drop-shadow(var(--sx, 0px) 30px 30px rgba(16, 16, 22, .28)); }
#siteSection { position: relative; margin: 0; }
#siteSection svg { width: 100%; height: auto; overflow: visible; }
#siteSection .draw { stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1.2s cubic-bezier(.65, 0, .35, 1); }
#siteSection .ln { fill: none; stroke: var(--ink); stroke-width: 2; stroke-linecap: square; stroke-linejoin: miter; }
#siteSection .cut { stroke-width: 7; }
#siteSection .thin { stroke-width: 1.2; }
#siteSection .dim { stroke-width: 1; }
#siteSection .acc { stroke: var(--accent); stroke-width: 5; }
#siteSection .dash { stroke-width: 1.5; }
#siteSection .hatch { fill: url(#rockHatch); opacity: 0; transition: opacity .8s linear 1s; }
#siteSection .hatch-line { stroke: var(--ink); stroke-width: 1; }
#siteSection.in .hatch { opacity: .28; }
#siteSection .ext { stroke-dasharray: 4 4; opacity: 0; transition: opacity .6s linear 1.2s; }   /* not a .draw line: the draw-on owns stroke-dasharray */
#siteSection.in .ext { opacity: 1; }
#siteSection .tag { color: var(--ink); }
#siteSection.in .draw { stroke-dashoffset: 0; }
#siteSection .tag { position: absolute; transform: translate(-50%, -100%); font-family: var(--f-mono); font-size: 12px; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }
@media (max-width: 860px) { .site-grid { grid-template-columns: 1fr; } }

/* ---------- construction timelapse ---------- */
#build { background: var(--night); color: var(--paper); padding: 16vh var(--gutter) 16vh; overflow: hidden; overflow: clip; }
.build-wrap { display: grid; grid-template-columns: 8fr 4fr; gap: 3vw; align-items: end; margin-top: 8vh; }
#buildStage { position: relative; margin: 0; aspect-ratio: 16 / 9; overflow: hidden; background: #000; }
#buildStage img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; visibility: hidden; }
#buildStage img.on { visibility: visible; }
#buildStage img.cut { animation: cutIn .28s var(--e-out) both; }
#buildRail { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
#buildRail li { display: grid; grid-template-columns: 56px 1fr; align-items: center; gap: 14px; color: var(--steel); }
#buildRail li i { height: 2px; background: rgba(238, 241, 243, .18); position: relative; overflow: hidden; }
#buildRail li i::after { content: ""; position: absolute; inset: 0; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform .25s var(--e-out); }
#buildRail li.done, #buildRail li.now { color: var(--paper); }
#buildRail li.done i::after, #buildRail li.now i::after { transform: scaleX(1); }
#buildRail li.now span { color: var(--accent-glow); }
#buildLine { margin: 4vh 0 0; min-height: 3.2em; font: var(--w-display) clamp(20px, 1.7vw, 28px)/1.2 var(--f-display); letter-spacing: -.015em; }
@media (max-width: 860px) { .build-wrap { grid-template-columns: 1fr; } }

/* ---------- enquiry ---------- */
#enquiry { background: var(--paper); padding: 16vh var(--gutter) 16vh; }
#enquiry .lead { max-width: 44ch; font-size: 19px; margin: 24px 0 0; }
#enquiryForm { display: grid; grid-template-columns: 1fr 1fr; gap: 34px 3vw; margin-top: 8vh; max-width: 1100px; }
#enquiryForm label { display: grid; gap: 8px; font-family: var(--f-mono); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; }
#enquiryForm .wide { grid-column: 1 / -1; }
#enquiryForm input, #enquiryForm textarea {
  font: 400 16px/1.4 var(--f-text); color: var(--ink); background: transparent;
  border: 0; border-bottom: 1px solid var(--ink); border-radius: 0; padding: 12px 0; min-height: 44px;
}
#enquiryForm textarea { min-height: 120px; resize: vertical; }
#enquiryForm input:focus, #enquiryForm textarea:focus { outline: none; border-bottom: 2px solid var(--accent); }
#enquirySend {
  justify-self: start; min-height: 56px; padding: 0 34px; border: 0; border-radius: 0; cursor: pointer;
  background: var(--ink); color: var(--paper); font: 700 14px/1 var(--f-text); letter-spacing: .12em; text-transform: uppercase;
  transition: transform .25s var(--e-back), background-color .15s linear;
}
#enquirySend:hover { background: var(--accent); color: var(--on-accent); transform: translateY(-2px); }
#enquiryForm .msg { grid-column: 1 / -1; font-family: var(--f-mono); font-size: 13px; min-height: 1.4em; color: var(--accent-text); }
#enquiryForm.sent > :not(.ok) { display: none; }
#enquiryForm .ok { display: none; grid-column: 1 / -1; font: var(--w-display) clamp(34px, 4vw, 64px)/1 var(--f-display); letter-spacing: -.03em; text-transform: uppercase; }
#enquiryForm.sent .ok { display: block; }
@media (max-width: 760px) { #enquiryForm { grid-template-columns: 1fr; } }

/* ---------- footer ---------- */
#footer { background: var(--night); color: var(--paper); padding: 14vh var(--gutter) 5vh; overflow: hidden; overflow: clip; }
.foot-word { font: var(--w-word) clamp(80px, 18vw, 300px)/.8 var(--f-display); letter-spacing: -.05em; text-transform: uppercase; white-space: nowrap; display: inline-block; }   /* size is fitted by JS to the footer's width */
.foot-small { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px 30px; margin-top: 8vh; border-top: 1px solid var(--steel); padding-top: 18px; color: var(--paper-soft); }

/* ---------- reduced motion: everything readable, nothing gated on scroll ---------- */
html.rm *, html.rm *::before, html.rm *::after { transition-duration: 0s !important; animation-duration: 0s !important; }
html.rm [data-r] { opacity: 1; transform: none; }
html.rm [data-clip], html.rm #heroType .w { clip-path: none; }
html.rm #drone { height: auto; }
html.rm .drone-stage { position: relative; }
html.rm .drone-head { display: none; }
