/* ============================================================
   VERTEX — Selinas Lane, Chadwell Heath
   Circular Spotify Head carries the display sizes; NB International
   carries everything set as text.  Palette is lifted from the brochure.
   ============================================================ */

/* ── fonts ────────────────────────────────────────────── */
@font-face{
  font-family:"Circular";src:url("../fonts/circular-bold.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Circular";src:url("../fonts/circular-black.woff2") format("woff2");
  font-weight:900;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"NB International";src:url("../fonts/nb-light.woff2") format("woff2");
  font-weight:300;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"NB International";src:url("../fonts/nb-regular.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"NB International";src:url("../fonts/nb-bold.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:swap;
}

:root{
  --green-900:#1b4318;              /* the brand's dark green   */
  --green-800:#235420;
  --lime:#b6f371;
  --indigo:#1d2670;
  --peri:#cfd1f9;                   /* specification ground     */
  --peri-pale:#e9eafc;              /* the schedules sit a shade lighter */
  --peri-mid:#8689e0;
  --cream:#fbf9e3;                  /* the icon badges          */
  /* the brochure rules the spec grids in the dark green, hairline weight —
     one hue, two strengths: bodies and rows, then heads and separators */
  --rule:rgba(27,67,24,.26);
  --rule-2:rgba(27,67,24,.5);
  --pink:#ffe8e8;                   /* sustainability ground    */
  --yellow:#fff59c;
  --ink:#1b4318;
  --white:#fff;
  --paper:#fbfbfd;

  --mute:rgba(255,255,255,.72);
  --mute-ink:rgba(27,67,24,.72);
  --mute-indigo:rgba(29,38,112,.7);   /* held-back indigo, for type on peri */
  --line:rgba(255,255,255,.2);
  --line-ink:rgba(27,67,24,.18);

  --display:"Circular",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --text:"NB International",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;

  --wrap:1440px;
  --pad:clamp(20px,4vw,64px);
  --bar:clamp(70px,8vh,86px);
  --ease:cubic-bezier(.22,.85,.3,1);
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
section[id]{scroll-margin-top:calc(var(--bar) + 14px)}
.hero{scroll-margin-top:0}

body{
  margin:0;background:var(--green-900);color:var(--white);
  font-family:var(--text);font-weight:400;line-height:1.6;
  /* clip, not hidden: overflow-x:hidden makes the body a scroll container and
     position:sticky then has nothing to stick to */
  -webkit-font-smoothing:antialiased;overflow-x:clip;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4,p,dl,dd,figure,table{margin:0}
ul{margin:0;padding:0;list-style:none}
table{border-collapse:collapse;width:100%}
sub{font-size:.7em}

.bleed{width:100%;padding-inline:var(--pad)}
.skip{position:absolute;left:-9999px;top:0;z-index:400;padding:12px 18px;background:var(--lime);color:var(--ink);font-weight:700}
.skip:focus{left:12px;top:12px}

/* ── type ─────────────────────────────────────────────── */
/* Headlines run light with the emphasis set bold, as the brochure does. That
   contrast needs a family with a 400: Circular ships here in Bold and Black
   only, where a 400 would silently resolve back to Bold, so the headlines take
   NB International — which is also the face the brochure sets them in. */
.h-display{
  font-family:var(--text);font-weight:400;
  font-size:clamp(1.85rem,4vw,3.4rem);line-height:1.05;letter-spacing:-.015em;
}
.h-display b{font-weight:700}
.eyebrow{
  font-family:var(--text);font-size:.68rem;font-weight:700;
  letter-spacing:.18em;text-transform:uppercase;
}
.lede{font-size:clamp(.92rem,1.05vw,1.05rem);line-height:1.65;font-weight:300;max-width:52ch;display:grid;gap:1em}
.lede b{font-weight:700}
.note{font-size:.72rem;font-weight:300;opacity:.72}

.sec{position:relative}
.sec--pad{padding:clamp(60px,9vh,124px) 0}
.sec__head{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(20px,4vw,64px);align-items:end;margin-bottom:clamp(32px,5vh,62px);
}
.sec__head--stack{grid-template-columns:minmax(0,1fr);gap:clamp(14px,2vh,22px);align-items:start}

/* reveal + lift */
.reveal{opacity:0;transform:translateY(24px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.reveal.is-in{opacity:1;transform:none}
.lift{
  opacity:0;transform:translateY(18px);
  transition:opacity .6s var(--ease),transform .6s var(--ease);
  transition-delay:calc(var(--i,0) * 70ms);
}
.is-in .lift{opacity:1;transform:none}

/* ── buttons ──────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  padding:15px 30px;border-radius:999px;border:1px solid transparent;
  font-family:var(--text);font-size:.74rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  cursor:pointer;transition:background .25s var(--ease),color .25s var(--ease),border-color .25s var(--ease);
}
.btn--sm{padding:11px 22px;font-size:.66rem}
.btn--solid{background:var(--lime);color:var(--green-900)}
.btn--solid:hover{background:var(--white)}

/* ── header ───────────────────────────────────────────── */
.head{
  position:fixed;inset:0 0 auto 0;z-index:200;
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  height:var(--bar);padding-inline:var(--pad);
  background:transparent;backdrop-filter:none;border-bottom:1px solid transparent;
  transition:background-color .4s var(--ease),backdrop-filter .4s var(--ease),border-color .4s;
}
/* it rides over the hero with nothing behind it, then fills once you scroll */
.head.is-on{background:rgba(27,67,24,.92);backdrop-filter:blur(14px);border-bottom-color:var(--line)}
.head__logo img{width:clamp(96px,9vw,128px)}
/* above the mobile breakpoint the hero carries its own lockup */
@media (min-width:721px){
  .head__logo{opacity:0;pointer-events:none;transition:opacity .35s var(--ease)}
  .head.is-on .head__logo{opacity:1;pointer-events:auto}
}
.head__nav{display:flex;align-items:center;gap:clamp(12px,1.7vw,28px)}
.head__nav a{font-size:.68rem;font-weight:700;letter-spacing:.15em;text-transform:uppercase;color:var(--mute);transition:color .25s}
.head__nav a:hover{color:var(--lime)}
.head__nav .btn{color:var(--green-900)}

.burger{display:none;background:none;border:0;padding:8px;margin-right:-8px;cursor:pointer;position:relative;z-index:2}
.burger span{display:block;width:26px;height:2px;background:var(--lime);margin:6px 0;transition:transform .3s var(--ease),opacity .2s}
.burger.is-on span:nth-child(1){transform:translateY(8px) rotate(45deg)}
.burger.is-on span:nth-child(2){opacity:0}
.burger.is-on span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}

/* ── hero ─────────────────────────────────────────────
   Two plates deep. The stage pins to the top for the length of the reveal,
   so the wordmark and rails hold still while the photograph pans underneath
   and uncovers the shed; once the plate is spent the whole hero scrolls away.
   The clip lives on the stage, NOT on .hero — overflow:hidden on an ancestor
   turns it into the scrollport and position:sticky stops working. */
.hero{
  --tb:0;                              /* reveal progress 0…1, fed by main.js */
  --tf:0;                              /* early-scroll progress 0…1, fed by main.js */
  --zoom:1.22;                         /* how far in the plate starts, before it pulls back */
  --img-h:calc(1.4144 * 100vw);        /* hero-bg.jpg is 2500 × 3536 */
  --slack:max(0px, calc(var(--img-h) - 100svh));
  position:relative;height:calc(100svh + var(--slack));min-height:640px;
  background:var(--green-900);border-bottom:3px solid var(--lime);
}
.hero__stage{
  position:sticky;top:0;height:100svh;overflow:hidden;isolation:isolate;
}
.hero__bg{
  position:absolute;z-index:-2;left:0;top:0;
  width:100%;height:calc(100svh + var(--slack));
  object-fit:cover;object-position:center top;
  /* the plate opens pushed in and eases back to true as the reveal runs, so the
     pan and the pull-back land together on the same frame */
  transform:translate3d(0,calc(var(--tb) * -1 * var(--slack)),0)
            scale(calc(var(--zoom) - (var(--zoom) - 1) * var(--tb)));
  /* the plate is far taller than the stage, so pin the zoom to the middle of the
     part you can actually see rather than the middle of the file */
  transform-origin:50% 50svh;
  will-change:transform;
}
.hero__veil{
  position:absolute;inset:0;z-index:-1;
  background:
    /* the detail line sits top-right over bright sky — darken that corner only,
       so the wordmark's lime ground on the left stays clean */
    radial-gradient(110% 70% at 100% 0%,rgba(20,50,15,.74) 0%,rgba(20,50,15,.24) 44%,rgba(20,50,15,0) 68%),
    linear-gradient(180deg,rgba(27,67,24,.30) 0%,rgba(27,67,24,0) 22%,rgba(27,67,24,0) 54%,rgba(27,67,24,.78) 100%);
}
/* the wordmark starts on the motive's lime ground; as the plate pans that ground
   slides away, so this comes up underneath it at the same rate */
.hero__veil::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(18,44,14,.66) 0%,rgba(18,44,14,.24) 30%,rgba(18,44,14,0) 52%);
  opacity:var(--tb);
}
.hero__in{
  position:relative;width:100%;height:100%;
  display:flex;flex-direction:column;justify-content:space-between;
  padding:calc(var(--bar) + clamp(12px,2.4vh,34px)) var(--pad) clamp(20px,3.4vh,40px);
}
.hero__top{display:flex;align-items:flex-start;justify-content:space-between;gap:24px}
/* the lockup clears the moment you start scrolling — the bar's mark takes over */
.hero__logo{
  opacity:calc(1 - var(--tf));
  transform:translate3d(0,calc(var(--tf) * -18px),0);
  transition:opacity .18s linear,transform .18s linear;
  will-change:opacity,transform;
}
.hero__logo img{width:clamp(210px,27vw,400px)}
.hero__side{
  display:grid;gap:2px;text-align:right;
  font-size:clamp(.78rem,1vw,1rem);font-weight:300;line-height:1.45;color:var(--white);
}
.hero__side b{font-family:var(--display);font-weight:700;font-size:clamp(.9rem,1.2vw,1.15rem);margin-bottom:3px}
.hero__foot{
  position:relative;
  display:flex;align-items:flex-end;justify-content:flex-end;gap:16px;
  font-size:.7rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
}
.hero__addr{display:grid;gap:3px;text-align:right}
.hero__addr b{font-weight:700}
.hero__addr i{font-style:normal;color:var(--lime)}
.hero__scroll{
  position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  width:24px;height:38px;border:1px solid rgba(255,255,255,.45);border-radius:13px;flex:none;
  display:grid;place-items:start center;padding-top:7px;
  opacity:calc(1 - var(--tb));transition:opacity .2s linear;   /* spent once the shed is up */
}
.hero__scroll span{width:2px;height:8px;background:var(--lime);border-radius:2px;animation:dropp 1.9s var(--ease) infinite}
@keyframes dropp{0%{transform:translateY(0);opacity:0}30%{opacity:1}100%{transform:translateY(15px);opacity:0}}

/* ── development ──────────────────────────────────────── */
.dev{background:var(--green-900);padding:clamp(60px,9vh,124px) 0}
.dev__in{display:grid;gap:clamp(30px,4.6vh,60px)}
.dev .lede{color:var(--mute)}
.dev .lede b{color:var(--lime)}
/* aerial.jpg is 2316x1638 and the top third is empty sky. Hold the frame at
   the cropped ratio and anchor the plate to the bottom, so the quarter that
   goes is all sky — the topmost label sits at 30% down, so it stays clear. */
.dev__shot{
  margin:0;border-radius:clamp(12px,1.2vw,22px);overflow:hidden;
  aspect-ratio:2316 / 1229;
}
.dev__shot img{width:100%;height:100%;object-fit:cover;object-position:center bottom}

/* ── specification ────────────────────────────────────────
   The brochure spread, mirrored: copy and schedules on the left over two
   grounds, the site plan on the right over indigo. The panels run to the
   page edges, so each carries its own padding rather than sharing .bleed. */
.spec{background:var(--peri-pale);color:var(--indigo)}
.spec .lede{color:rgba(29,38,112,.76)}
.spec .h-display{color:var(--indigo)}
.spec .eyebrow{color:rgba(29,38,112,.7);margin-bottom:clamp(14px,2vh,22px)}

.spec__grid{display:grid;grid-template-columns:minmax(0,1.14fr) minmax(0,.86fr);align-items:stretch}
/* the two grounds stack, and the lighter one takes up whatever height the
   plate on the other side leaves over */
.spec__body{display:grid;grid-template-rows:auto minmax(0,1fr);min-width:0}

.spec__intro{
  background:var(--peri);min-width:0;
  padding:clamp(36px,5.4vh,72px) clamp(20px,2.2vw,40px) clamp(28px,4vh,48px) var(--pad);
}
.spec__data{
  background:var(--peri-pale);min-width:0;
  padding:clamp(26px,3.4vh,40px) clamp(20px,2.2vw,40px) clamp(34px,5.4vh,72px) var(--pad);
}
.spec .sec__head{margin-bottom:0}

/* eight badges, four up — icon over label, each cell closed by a hairline */
.spec__list{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(16px,2vh,24px) 0;
  margin-top:clamp(24px,3.4vh,40px);
  --badge:clamp(42px,4vw,58px);
  --icon:clamp(22px,2.1vw,30px);
}
.spec__list li{
  display:grid;grid-template-columns:minmax(0,1fr);justify-items:center;
  align-content:start;text-align:center;gap:clamp(8px,1.1vh,12px);
  padding-inline:clamp(6px,.9vw,16px);
  border-left:1px solid var(--rule-2);
}
/* separators run between the cells only — nothing opens or closes the row. The
   first cell of each row keeps its border and hides it rather than dropping it,
   so every cell keeps identical metrics and the columns stay true from row to
   row. The column count changes per breakpoint, so the first-in-row selector is
   restated wherever it does. */
.spec__list li:nth-child(4n+1){border-left-color:transparent}
.spec__list li::before{
  content:"";grid-area:1/1;place-self:center;
  width:var(--badge);height:var(--badge);
  border-radius:50%;background:var(--cream);
}
.spec__list img{
  grid-area:1/1;place-self:center;
  width:var(--icon);height:var(--icon);object-fit:contain;
}
.spec__list span{font-size:clamp(.7rem,.8vw,.84rem);font-weight:400;line-height:1.35}

.plan{
  margin:0;min-width:0;background:var(--indigo);color:var(--white);
  display:grid;align-content:center;gap:clamp(14px,2vh,22px);
  padding:clamp(28px,4vh,48px) clamp(22px,2.4vw,44px) clamp(28px,4vh,48px) clamp(20px,2.2vw,40px);
}
/* the plan SVG has no ground of its own — the panel's indigo is what shows
   through its roads and yards, so nothing must paint over it */
.plan img{width:100%;height:auto}
.plan figcaption{font-size:.76rem;font-weight:300;color:var(--mute)}
.plan figcaption b{font-weight:700;color:var(--white)}

/* the two schedules stand abreast, so they get roughly half the right-hand
   column each and the cells run tighter than they would full-bleed — the .tbl
   fade still catches any residual overflow. Cell padding travels as a property
   rather than a selector override so the phone rules, which sit on .tbl itself,
   still win by proximity. */
.sched{
  display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:clamp(22px,3vh,34px) clamp(12px,1.2vw,20px);
  align-items:start;min-width:0;
  --cell-y:7px;--cell-x:2px;--cell-edge:clamp(6px,.7vw,10px);
}
/* the unit schedule is seven columns wide in half a page — the head is what
   sets the column widths, so that is where the room has to come from */
.sched .tbl thead th{font-size:.52rem;letter-spacing:.01em}
.sched .tbl caption{padding-bottom:9px}
.sched .tbl tbody tr.is-gap>*{padding-top:18px}
/* the seven-column table is wider than a phone: it scrolls in its own box, with
   a fade on the right so it reads as scrollable rather than as clipped */
.tbl{
  min-width:0;overflow-x:auto;
  /* the fade is painted in the ground it sits on, so it has to track
     .spec__data's lighter tint rather than the intro's peri */
  background:linear-gradient(to right,var(--peri-pale) 30%,rgba(233,234,252,0)),
             linear-gradient(to right,rgba(233,234,252,0),var(--peri-pale) 70%) 100% 0,
             radial-gradient(farthest-side at 0 50%,rgba(27,67,24,.22),rgba(27,67,24,0)),
             radial-gradient(farthest-side at 100% 50%,rgba(27,67,24,.22),rgba(27,67,24,0)) 100% 0;
  background-repeat:no-repeat;background-size:36px 100%,36px 100%,14px 100%,14px 100%;
  background-attachment:local,local,scroll,scroll;
}
.tbl caption{text-align:left;color:rgba(29,38,112,.7);padding-bottom:12px;border-bottom:1px solid var(--rule-2);margin-bottom:2px}
.tbl table{font-size:clamp(.7rem,.82vw,.84rem);white-space:nowrap}
.tbl th,.tbl td{padding:var(--cell-y,11px) var(--cell-x,8px);text-align:right;font-weight:400}
.tbl thead th{
  font-size:.6rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:rgba(29,38,112,.66);vertical-align:bottom;border-bottom:1px solid var(--rule-2);
}
/* the unit names are row headers, but only the totals carry any weight */
.tbl tbody th{text-align:left;font-weight:400}
.tbl th:first-child,.tbl td:first-child{text-align:left;padding-left:var(--cell-edge,10px)}
.tbl th:last-child,.tbl td:last-child{padding-right:var(--cell-edge,10px)}
.tbl tbody tr{border-bottom:1px solid var(--rule)}
.tbl tbody tr.is-gap>*{padding-top:26px}
.tbl tbody tr.is-total th,.tbl tbody tr.is-total td{font-weight:700;color:var(--indigo)}
/* the two schedules are one dataset split in half, so a unit lights up in both
   at once — see the pairing in main.js */
.tbl tbody tr[data-unit]{transition:background-color .15s linear}
.tbl tbody tr.is-hot{background:var(--lime)}
/* the unit schedule has no Total rows, so it carries blank ones in their place
   to keep the units level with the schedule beside it */
.tbl tbody tr.is-spacer td{padding-inline:0}

/* ── sustainability ─────────────────────────────────────
   The brand device is washed over the ground behind the copy — flat white,
   held back by opacity alone. motive-flat.svg is the same path as motive.svg
   with the internal gradient mask stripped, so it reads evenly top to bottom
   rather than fading out down the section. */
.esg{background:var(--pink);color:var(--green-900);isolation:isolate}
.esg::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:url("../img/motive-flat.svg") left center / auto 132% no-repeat;
  opacity:.5;
}
.esg__in{
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(30px,4vw,70px);align-items:center;
  padding-block:clamp(60px,9vh,124px);
}
.esg .lede{color:var(--mute-ink)}
.esg__body{display:grid;gap:clamp(28px,4vh,52px);min-width:0}

/* the column gap is carried as cell padding rather than grid gap, so the rule
   sits midway between neighbours instead of hard against the next label */
.esg__creds{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(22px,3vh,34px) 0}
.esg__creds li{
  display:grid;gap:clamp(10px,1.1vh,14px);
  justify-items:center;text-align:center;align-content:start;
  padding-inline:clamp(10px,1.4vw,22px);
  border-left:1px solid var(--rule);
}
.esg__creds li:nth-child(4n+1){border-left-color:transparent}
.esg__creds img{width:clamp(34px,3.2vw,46px);height:clamp(34px,3.2vw,46px);object-fit:contain}
.esg__creds span{font-size:clamp(.7rem,.82vw,.84rem);font-weight:400;line-height:1.35}

.esg__save{display:grid;gap:16px;padding-top:clamp(22px,3vh,34px);border-top:1px solid var(--rule)}
.esg__save ul{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,2.4vw,38px) 0}
.esg__save li{
  display:grid;gap:10px;justify-items:center;text-align:center;align-content:start;
  padding-inline:clamp(14px,2vw,32px);
}
/* between the three, not opening or closing the row */
.esg__save li{border-left:1px solid var(--rule)}
.esg__save li:first-child{border-left-color:transparent}
/* these three carry the section's headline numbers, so they run larger than
   the eight credentials above them */
.esg__save img{width:clamp(58px,5.6vw,84px);height:clamp(58px,5.6vw,84px);object-fit:contain}
.esg__save b{
  font-family:var(--display);font-weight:700;font-size:clamp(1.15rem,2.1vw,1.7rem);
  line-height:1;letter-spacing:-.02em;
}
.esg__save span{font-size:clamp(.7rem,.8vw,.82rem);font-weight:300;line-height:1.4;color:var(--mute-ink)}

.esg__shots{
  position:relative;margin:0;border-radius:clamp(12px,1.2vw,22px);overflow:hidden;
  min-height:clamp(340px,44vw,620px);
}
.esg__shots-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* the insets are buttons now — the circle and its crop move to the button so
   the photograph inside can simply fill it */
.esg__pip{
  position:absolute;border-radius:50%;overflow:hidden;border:4px solid var(--lime);
  width:clamp(96px,15vw,200px);aspect-ratio:1;
  padding:0;background:none;cursor:pointer;
  transition:transform .35s var(--ease),box-shadow .35s var(--ease);
}
.esg__pip img{width:100%;height:100%;object-fit:cover}
.esg__pip:hover,.esg__pip:focus-visible{transform:scale(1.06);box-shadow:0 10px 30px rgba(27,67,24,.28)}
.esg__pip:focus-visible{outline:2px solid var(--indigo);outline-offset:4px}
/* the incoming photograph is dealt on top of the outgoing one and brought up
   from nothing, so neither the plate nor a circle is ever empty mid-trade.
   The transition lives on .is-in alone: dropping the class takes the rule with
   it, so the reset back to zero is instant and invisible under a covered
   layer rather than a second fade the other way. */
.esg__fade{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;opacity:0;pointer-events:none;
}
.esg__fade.is-in{opacity:1;transition:opacity .32s var(--ease)}
.esg__pip[style*="--i:0"]{top:8%;right:6%}
.esg__pip[style*="--i:1"]{top:34%;right:26%}
.esg__pip[style*="--i:2"]{top:58%;right:4%}

/* ── gallery ──────────────────────────────────────────
   The brochure's mosaic: the reception plate runs two rows down the right,
   the dock range spans the first two columns, the shed the last two. */
.gal{background:var(--green-900);color:var(--white)}
.gal .lede{color:var(--mute)}
.gal__grid{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  grid-auto-rows:clamp(150px,17vw,260px);
  gap:clamp(10px,1.2vw,20px);
  grid-template-areas:
    "aerial    lobby     reception"
    "docks     docks     reception"
    "office    warehouse warehouse";
}
.gal__cell{
  padding:0;border:0;background:none;cursor:zoom-in;position:relative;overflow:hidden;
  border-radius:clamp(8px,.9vw,16px);
}
.gal__cell img{width:100%;height:100%;object-fit:cover;transition:transform .55s var(--ease)}
.gal__cell:hover img{transform:scale(1.045)}
.gal__cell:focus-visible{outline:2px solid var(--lime);outline-offset:3px}
.gal__cell--aerial{grid-area:aerial}
.gal__cell--lobby{grid-area:lobby}
.gal__cell--reception{grid-area:reception}
.gal__cell--docks{grid-area:docks}
.gal__cell--office{grid-area:office}
.gal__cell--warehouse{grid-area:warehouse}

/* ── location ─────────────────────────────────────────── */
.loc{background:var(--peri);color:var(--green-900)}
.loc .sec__head .eyebrow{color:var(--mute-indigo);margin-bottom:clamp(14px,2vh,22px)}
.loc__grid{display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);gap:clamp(30px,4vw,70px);align-items:start}
.loc__body{min-width:0;display:grid;gap:clamp(26px,3.6vh,44px);align-content:start}
.loc__body .sec__head{margin-bottom:0}
.loc__maps{margin:0;display:grid;gap:clamp(12px,1.6vw,22px);position:sticky;top:calc(var(--bar) + 20px)}
.loc__maps img{width:100%;height:auto;border-radius:clamp(10px,1vw,18px)}
.eliz{margin:0;display:grid;gap:12px}
.eliz figcaption{color:var(--indigo)}
.eliz img{width:100%;height:auto}
.loc .h-display{color:var(--green-900)}
.loc .lede{color:var(--mute-ink)}
.loc .note{color:var(--mute-ink);margin-top:-16px}

.dist{
  color:var(--indigo);
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  grid-template-rows:auto auto;grid-auto-rows:auto;
  column-gap:clamp(18px,2.4vw,44px);row-gap:0;
}
/* each column hands its header and list to the parent's rows, so a heading that
   wraps to two lines lifts every rule together instead of just its own */
.dist__col{display:grid;grid-template-rows:subgrid;grid-row:span 2}
.dist .eyebrow{
  display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  padding-bottom:10px;margin-bottom:6px;border-bottom:1px solid var(--rule-2);color:var(--indigo);
}
.dist .eyebrow i{font-style:normal;color:var(--mute-indigo);font-size:.6rem}
.dist li{display:flex;justify-content:space-between;gap:14px;padding:11px 0;border-bottom:1px solid var(--rule);font-size:clamp(.74rem,.86vw,.9rem)}
.dist li span{color:var(--mute-indigo);font-weight:300}
.dist li b{font-weight:700;white-space:nowrap}

.work__stats{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(20px,2.6vw,40px);
  --badge:clamp(46px,4.2vw,62px);
  --icon:clamp(26px,2.4vw,34px);
}
.work__stats li{display:grid;gap:10px;justify-items:start;padding-top:clamp(14px,2vh,20px);border-top:2px solid var(--rule-2)}
/* disc and icon share the first row; the icon is nudged in by half the
   difference so it centres inside a disc that stays flush left */
.work__stats li::before{
  content:"";grid-area:1/1;justify-self:start;align-self:center;
  width:var(--badge);height:var(--badge);border-radius:50%;background:var(--cream);
}
.work__stats img{
  grid-area:1/1;justify-self:start;align-self:center;
  width:var(--icon);height:var(--icon);object-fit:contain;
  margin-left:calc((var(--badge) - var(--icon)) / 2);
}
.work__stats b{
  font-family:var(--display);font-weight:700;font-size:clamp(1.5rem,3vw,2.5rem);
  line-height:1;letter-spacing:-.02em;color:var(--indigo);
}
.work__stats span{font-size:clamp(.7rem,.82vw,.84rem);font-weight:300;line-height:1.4;color:var(--mute-ink)}

/* ── contact ──────────────────────────────────────────── */
.contact{background:var(--green-900);padding:clamp(30px,4.5vh,60px) 0 clamp(40px,6vh,80px)}
.contact__in{padding-top:clamp(26px,4vh,50px)}

.w3w{
  display:grid;justify-items:end;gap:5px;text-align:right;margin-bottom:clamp(26px,4vh,48px);
  font-size:.72rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
}
.w3w b{color:var(--lime);font-weight:700}
.w3w span{color:var(--mute);font-weight:400}

.contact__body{display:grid;grid-template-columns:minmax(0,2.1fr) minmax(0,1fr);gap:clamp(28px,4vw,64px);align-items:start}
.contact__agents{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(22px,2.6vw,40px)}
.firm__logo{display:block;width:clamp(104px,10vw,150px);margin-bottom:clamp(18px,2.6vh,30px)}
.firm__logo--dtre{width:clamp(74px,7vw,104px)}
.agents{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(16px,2.2vw,24px)}
.agent{display:grid;gap:3px;font-size:clamp(.72rem,.84vw,.86rem)}
.agent b{color:var(--lime);font-weight:700;margin-bottom:4px}
.agent a{color:var(--mute);font-weight:300;transition:color .25s;word-break:break-word}
.agent a:hover{color:var(--white)}

.contact__mark{display:grid;justify-items:end;gap:12px;text-align:right}
.contact__mark img{width:clamp(130px,13vw,190px)}
.cta-bar{display:flex;gap:12px;flex-wrap:wrap;justify-content:flex-end;margin-top:clamp(10px,1.6vh,18px)}

/* ── footer ───────────────────────────────────────────── */
.foot{background:var(--green-800);padding:clamp(26px,4vh,44px) var(--pad);border-top:1px solid var(--line)}
.foot__legal{font-size:.62rem;font-weight:300;line-height:1.6;color:rgba(255,255,255,.56)}

/* ── lightbox ─────────────────────────────────────────── */
.lbox{
  position:fixed;inset:0;z-index:300;background:rgba(15,38,13,.95);backdrop-filter:blur(6px);
  display:grid;place-items:center;gap:14px;padding:clamp(20px,4vw,50px);
  opacity:0;transition:opacity .3s var(--ease);
}
.lbox[hidden]{display:none}
.lbox.is-on{opacity:1}
.lbox img{max-width:min(96vw,1400px);max-height:84vh;object-fit:contain;border-radius:8px;background:var(--white)}
.lbox p{font-size:.7rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--mute)}
.lbox__x{position:absolute;top:20px;right:24px;background:none;border:0;color:#fff;font-size:2.4rem;line-height:1;cursor:pointer}

/* ══ RESPONSIVE ══════════════════════════════════════════ */
@media (max-width:1180px){
  .head__nav{
    position:fixed;inset:0;height:100svh;
    flex-direction:column;align-items:center;justify-content:center;
    gap:clamp(4px,1.2vh,12px);padding:0 var(--pad);text-align:center;
    background:var(--green-900);
    opacity:0;visibility:hidden;
    transition:opacity .4s var(--ease),visibility 0s linear .4s;
  }
  .head__nav.is-on{opacity:1;visibility:visible;transition-delay:0s,0s}
  .head__nav a{
    font-size:clamp(1rem,4.2vw,1.45rem);font-weight:700;letter-spacing:.08em;padding:8px 0;
    opacity:0;transform:translateY(16px);
    transition:opacity .45s var(--ease),transform .45s var(--ease),color .25s;
  }
  .head__nav.is-on a{opacity:1;transform:none}
  .head__nav.is-on a:nth-child(1){transition-delay:.08s}
  .head__nav.is-on a:nth-child(2){transition-delay:.13s}
  .head__nav.is-on a:nth-child(3){transition-delay:.18s}
  .head__nav.is-on a:nth-child(4){transition-delay:.23s}
  .head__nav.is-on a:nth-child(5){transition-delay:.28s}
  .head__nav.is-on a:nth-child(6){transition-delay:.33s}
  .head__nav.is-on a:nth-child(7){transition-delay:.4s}
  .head__nav .btn{margin-top:clamp(16px,3vh,30px);font-size:.74rem;padding:15px 32px}
  .head__logo{position:relative;z-index:2}
  .burger{display:block}

  .sec__head{grid-template-columns:minmax(0,1fr);gap:clamp(16px,2.4vh,26px)}
  /* the spread unstacks into full-width bands: copy and badges, then the
     schedules, then the plate — each keeps its own ground */
  .spec__grid{grid-template-columns:minmax(0,1fr)}
  .spec__intro{padding:clamp(44px,7vh,96px) var(--pad) clamp(38px,5.5vh,68px)}
  .spec__data{padding:clamp(34px,4.6vh,56px) var(--pad) clamp(44px,7vh,96px)}
  .plan{padding:clamp(34px,5vh,60px) var(--pad)}
  /* stacked, the column is the whole page — left to fill it the plate would
     run to 1500px tall, so cap it and centre it instead */
  .plan img{max-width:min(100%,680px);margin-inline:auto}
  /* full width now, so give the cells their breathing room back */
  /* full width now, but it narrows all the way to the phone breakpoint, so the
     cells and the head scale with it rather than sitting on one fixed value */
  .sched{
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:clamp(26px,3.6vh,44px) clamp(26px,3.4vw,50px);
    --cell-y:11px;--cell-x:clamp(3px,.7vw,8px);
  }
  .sched .tbl thead th{font-size:clamp(.53rem,.62vw,.6rem);letter-spacing:.03em}
  .esg__in{grid-template-columns:minmax(0,1fr);gap:clamp(30px,4vh,50px)}
  .esg__creds{grid-template-columns:repeat(3,minmax(0,1fr))}
  .esg__creds li:nth-child(4n+1){border-left-color:var(--rule)}
  .esg__creds li:nth-child(3n+1){border-left-color:transparent}
  .dist{grid-template-columns:repeat(2,minmax(0,1fr))}
  .dist__col ul{padding-bottom:clamp(18px,2.4vw,40px)}
  .loc__grid{grid-template-columns:minmax(0,1fr);gap:clamp(30px,4vh,48px)}
  .loc__maps{position:static;grid-template-columns:repeat(2,minmax(0,1fr))}
  .contact__body{grid-template-columns:minmax(0,1fr);gap:clamp(28px,4vh,44px)}
  .contact__mark{justify-items:start;text-align:left}
  .cta-bar{justify-content:flex-start}
}

@media (max-width:720px){
  /* the bar already shows the logo here — drop the hero's copy but keep the h1
     in the accessibility tree, it is the page's only one */
  .hero__logo{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  /* A phone screen is taller than the plate is at 100vw, so the natural slack
     computes to zero and there would be nothing to uncover. Give the plate an
     explicit depth instead and let cover crop the width. */
  .hero{--slack:46svh}
  .hero__top{justify-content:flex-end}
  .hero__side{text-align:left}
  .hero__foot{flex-direction:column;align-items:flex-start;gap:14px;font-size:.6rem}
  .hero__addr{text-align:left;justify-items:start}
  .hero__scroll{display:none}

  /* icon grids go two-up and centre, icon over text */
  .spec__list{grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(22px,3.4vh,32px) 0}
  .spec__list li{gap:10px;padding-inline:clamp(6px,2vw,14px)}
  .spec__list li:nth-child(4n+1){border-left-color:var(--rule-2)}
  .spec__list li:nth-child(odd){border-left-color:transparent}
  .esg__creds{grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(22px,3.4vh,32px) 0}
  .esg__creds li{padding-inline:clamp(6px,2vw,14px)}
  .esg__creds li:nth-child(3n+1){border-left-color:var(--rule)}
  .esg__creds li:nth-child(odd){border-left-color:transparent}
  .spec__list{--badge:clamp(38px,10vw,48px);--icon:clamp(20px,5.2vw,26px)}
  .esg__creds img{width:clamp(38px,10vw,48px);height:clamp(38px,10vw,48px)}
  .esg__save ul{grid-template-columns:minmax(0,1fr);gap:26px}
  .esg__save li{padding-inline:0;border-left-color:transparent}
  .esg__pip{width:clamp(84px,24vw,120px)}

  .sched{grid-template-columns:minmax(0,1fr)}
  /* tighten the schedules so the numbers stop clipping mid-figure */
  .tbl table{font-size:.66rem}
  .tbl{--cell-y:9px;--cell-x:5px}
  .tbl thead th{font-size:.53rem;letter-spacing:.02em}

  .dist{grid-template-columns:minmax(0,1fr)}
  .dist .eyebrow{min-height:0}
  .work__stats{grid-template-columns:minmax(0,1fr)}
  .loc__maps{grid-template-columns:minmax(0,1fr)}
  /* the mosaic collapses to a simple two-up on a phone */
  .gal__grid{
    grid-template-columns:repeat(2,minmax(0,1fr));
    grid-auto-rows:clamp(120px,32vw,180px);
    grid-template-areas:"aerial lobby" "docks docks" "reception office" "warehouse warehouse";
  }
  .contact__agents{grid-template-columns:minmax(0,1fr);gap:clamp(26px,5vh,38px)}
  .w3w{justify-items:start;text-align:left}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .reveal,.lift{opacity:1;transform:none;transition:none}
  .hero__scroll span{animation:none}
  .hero{--zoom:1}
  .hero__logo{transform:none;transition:none}
  .head__nav a{opacity:1;transform:none;transition:none}
  .tbl tbody tr[data-unit]{transition:none}
  .esg__pip,.esg__fade{transition:none}
  .esg__pip:hover,.esg__pip:focus-visible{transform:none}
  .gal__cell img{transition:none}
  .gal__cell:hover img{transform:none}
  .burger span{transition:none}
}
