/* ─────────────────────────────────────────────────────────────────────────
   TOKENS
   ───────────────────────────────────────────────────────────────────────── */
:root{
  /* warm paper ground, after jane.energy */
  --paper:#f5f3ee;
  --paper-2:#ece8e0;
  --paper-3:#e3ded4;
  --white:#fffefb;

  --ink:#14181c;
  --ink-2:#6d6a62;      /* the warm gray of the two-tone headline tail */
  --ink-3:#8e8a80;
  --rule:#d9d4c9;
  --rule-2:#c8c2b5;

  --dark:#11161a;
  --dark-2:#1b2126;
  --dark-rule:#2c3439;
  --on-dark:#f2efe8;
  --on-dark-2:#9aa3a8;

  /* brand, used with restraint */
  --cyan:#00aeff;
  --navy:#23539c;
  --navy-d:#1a3f78;
  --orange:#ff6e00;

  --serif:"EB Garamond",Georgia,"Times New Roman",serif;
  --sans:"Inter",system-ui,-apple-system,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,monospace;

  --pad:clamp(1.25rem,5vw,4.5rem);
  --max:78rem;
  --band:clamp(4rem,9vw,7.5rem);
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--paper); color:var(--ink);
  font:400 clamp(.9375rem,.25vw + .9rem,1.0625rem)/1.65 var(--sans);
  -webkit-font-smoothing:antialiased;
}
img,svg{display:block; max-width:100%}
p{margin:0}
a{color:inherit}
:focus-visible{outline:2px solid var(--cyan); outline-offset:3px}
@media (prefers-reduced-motion:reduce){*{animation:none !important; transition:none !important}}

.wrap{max-width:var(--max); margin-inline:auto; padding-inline:var(--pad)}
.band{padding-block:var(--band)}

/* ── eyebrow: the letterspaced caps label above every section head ───────── */
/* Warm grey. These went blue and came straight back on 2026-08-23: with the
   heading halves, the feature titles and the buttons all carrying brand blue,
   a blue label above a blue heading was one job too many for the colour. An
   eyebrow is a label, not content, so grey is the right register. */
.eyebrow{
  font:500 .6875rem/1.5 var(--mono); letter-spacing:.18em; text-transform:uppercase;
  color:var(--ink-3); display:flex; align-items:flex-start; gap:.6rem;
}
/* The little cyan square that used to sit before every one of these is gone —
   Eric's call, site-wide. The rule is kept rather than deleted because the
   flex layout above still reads as intentional, and turning the mark back on
   is one line. */
.eyebrow::before{
  content:""; width:.5rem; height:.5rem; background:var(--cyan);
  flex:none; border-radius:1px; margin-top:.45em;
  display:none;
}
.eyebrow.is-center{justify-content:center}
.eyebrow.on-dark{color:var(--on-dark-2)}

/* ── the two-tone headline, the signature device of all three references ──
   <h2>Dark clause. <span>gray continuation</span></h2>                     */
.h-display{
  font-family:var(--serif); font-weight:400; letter-spacing:-.015em;
  line-height:1.06; margin:0; text-wrap:balance;
  font-size:clamp(2.25rem,5.6vw,4.5rem);
}
.h-sec{
  font-family:var(--serif); font-weight:400; letter-spacing:-.012em;
  line-height:1.12; margin:0; text-wrap:balance;
  font-size:clamp(1.875rem,4vw,3.25rem);
}
.h-display span,.h-stmt span{color:var(--ink-2)}
/* TWO-SENTENCE SECTION HEADINGS: one sentence near-black, the other brand navy
   (Eric, 2026-08-23). This used to be a warm grey, which read as de-emphasis
   rather than as a second beat. Blue is now the default for any <span> inside
   an .h-sec, so a heading split into two sentences picks it up without anyone
   remembering a class. .accent stays as an explicit alias for the same colour.
   The dark About band overrides below — navy on navy would vanish. */
.h-sec span,.h-sec .accent{color:var(--navy)}
/* the Jane statement paragraph — a big serif paragraph, not a heading */
.h-stmt{
  font-family:var(--serif); font-weight:400; letter-spacing:-.008em;
  line-height:1.22; margin:0; max-width:34ch;
  font-size:clamp(1.625rem,3.4vw,2.75rem);
}
.lede{
  font-size:clamp(1rem,.45vw + .92rem,1.1875rem); line-height:1.6;
  color:var(--ink-2); max-width:56ch;
}
.sec-hd{max-width:62rem}
.sec-hd .h-sec{margin-top:1.1rem}
.sec-hd .lede{margin-top:1.1rem}
.sec-hd.is-center{margin-inline:auto; text-align:center}
.sec-hd.is-center .lede{margin-inline:auto}

/* ── buttons, after lucaiq ──────────────────────────────────────────────── */
.btn{
  display:inline-flex; align-items:center; gap:.55rem; text-decoration:none;
  font:600 .9375rem/1 var(--sans); padding:.95rem 1.4rem; border-radius:2px;
  border:1px solid transparent; transition:background .18s, color .18s, border-color .18s;
  white-space:nowrap;
}
.btn svg{flex:none}
.btn--fill{background:var(--navy); color:#fff; border-color:var(--navy)}
.btn--fill:hover{background:var(--navy-d); border-color:var(--navy-d)}
.btn--line{background:transparent; color:var(--ink); border-color:var(--rule-2)}
.btn--line:hover{border-color:var(--ink); background:rgba(0,0,0,.03)}
.btn--onphoto{background:var(--white); color:var(--ink); border-color:var(--white)}
.btn--onphoto:hover{background:#fff}
.btn--ghostphoto{background:rgba(255,255,255,.10); color:#fff; border-color:rgba(255,255,255,.55); backdrop-filter:blur(6px)}
.btn--ghostphoto:hover{background:rgba(255,255,255,.2); border-color:#fff}
.btn-row{display:flex; flex-wrap:wrap; gap:.75rem}

/* ── header, after derya.ai ──────────────────────────────────────────────
   Sits ON the footage, not above it: a translucent dark bar with a hairline
   under it, so the video runs to the very top of the window. Logo hard left
   with the nav immediately beside it (derya keeps both left and pushes only
   the actions right), and the CTA is a white block with a cyan arrow tile
   welded to its right edge.                                               */
.hdr{
  position:fixed; inset:0 0 auto; z-index:50;
  background:rgba(9,13,16,.42); backdrop-filter:blur(10px) saturate(120%);
  border-bottom:1px solid rgba(255,255,255,.13);
  transition:background .3s, border-color .3s, box-shadow .3s;
}
.hdr-in{display:flex; align-items:center; gap:clamp(1rem,3vw,2.25rem); min-height:4.75rem}
.hdr-logo{display:flex; align-items:center; gap:.6rem; text-decoration:none; flex:none}
/* taller than derya's single-word mark because this logo is a lockup — the
   "Control Your Cold Chain" line under the wordmark is unreadable below 2rem.
   TWO FILES, NOT A FILTER. brightness(0) invert(1) used to make the supplied
   logo white here, which also flattened the blue iceberg into a solid white
   disc — the badge lost its whole drawing. assets/img/logo-onDark.webp is a
   dark-background version instead: the badge keeps the blue mountains inside
   a white outline, and only the wordmark is knocked out, so the tagline stays
   readable. Derived from the supplied raster by recolouring only the
   desaturated ink left of the badge edge (ffmpeg geq) — clean at header size,
   but an official white/SVG logo is still worth requesting. The original is
   correct on the paper header, so both ship and .is-stuck swaps them. */
.hdr-logo img{height:clamp(2.25rem,3vw,2.75rem); width:auto}
.hdr .logo-light{display:none}
.hdr.is-stuck .logo-dark{display:none}
.hdr.is-stuck .logo-light{display:block}
.hdr-nav{display:flex; gap:clamp(.9rem,2vw,1.75rem)}
.hdr-nav a{
  font:500 .875rem/1 var(--sans); color:rgba(255,255,255,.82);
  text-decoration:none; padding:.4rem 0; transition:color .18s;
}
.hdr-nav a:hover{color:#fff}
.hdr-act{display:flex; align-items:center; gap:1rem; flex:none; margin-left:auto}
/* the phone number came out of the header on 2026-08-22 and went back in the
   same day at Eric's direction. It hides with the nav below 60rem — a phone
   already has tel: from the footer, and the row has no width to spare. */
.hdr-tel{font:500 .8125rem/1 var(--mono); color:rgba(255,255,255,.7); text-decoration:none; letter-spacing:.02em}
.hdr-tel:hover{color:#fff}
/* derya's split CTA: label block + arrow tile, one target, no gap between */
.cta-split{display:inline-flex; align-items:stretch; text-decoration:none; border-radius:2px; overflow:hidden}
/* sentence case at Eric's direction (2026-08-22). The tracking came down with
   the caps — .06em is what makes uppercase readable and what makes lowercase
   look spaced out — and the size went up a step, since lowercase at 13px next
   to the logo read as fine print. */
.cta-split span{
  display:flex; align-items:center; background:var(--white); color:var(--ink);
  font:600 .875rem/1 var(--sans); letter-spacing:.01em;
  padding:.8rem 1.1rem; transition:background .18s, color .18s;
}
.cta-split i{
  display:flex; align-items:center; justify-content:center; width:2.6rem;
  background:var(--cyan); color:#00293d; transition:background .18s, color .18s;
}
.cta-split:hover span{background:#fff}
.cta-split:hover i{background:var(--navy); color:#fff}
/* scrolled state — flips to paper */
.hdr.is-stuck{background:rgba(245,243,238,.94); border-bottom-color:var(--rule)}
.hdr.is-stuck .hdr-nav a{color:var(--ink-2)}
.hdr.is-stuck .hdr-nav a:hover{color:var(--ink)}
.hdr.is-stuck .hdr-tel{color:var(--ink-3)}
.hdr.is-stuck .hdr-tel:hover{color:var(--ink)}
.hdr.is-stuck .cta-split span{background:var(--navy); color:#fff}
.hdr.is-stuck .cta-split i{background:var(--navy-d); color:#fff}
/* ── mobile menu ────────────────────────────────────────────────────────
   Below 60rem the bar keeps only the logo and the burger. The Inquire CTA
   and the phone number move INTO the panel rather than staying in the bar:
   at 320px the logo lockup alone is 215px, and logo + CTA + burger does not
   fit in 272px of usable width. The panel is the header's own dropdown, not
   a <dialog>, because it must sit under the fixed bar and inherit its
   backdrop rather than cover it. */
/* visible to a screen reader, not on screen — the burger is three bars with
   no text, so its label has to live somewhere */
.sr{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
}
/* Both of these must be hidden by DEFAULT and revealed inside the query, not
   hidden inside it — the panel's display:none lived only in the max-width
   block at first, so above 60rem it fell back to <nav>'s block and dumped a
   second unstyled nav under the header. */
.hdr-burger{display:none}
.mnav{display:none}
@media (max-width:60rem){
  .hdr-nav,.hdr-tel{display:none}
  .hdr-act .cta-split{display:none}
  .hdr-burger{
    display:block; appearance:none; -webkit-appearance:none;
    background:transparent; border:0; padding:.7rem .35rem; cursor:pointer;
    width:2.75rem; height:2.75rem; margin-right:-.35rem;
  }
  .hdr-burger span{
    display:block; height:1.5px; width:1.375rem; margin-inline:auto;
    background:#fff; border-radius:1px;
    transition:transform .22s ease, opacity .18s ease;
  }
  .hdr-burger span + span{margin-top:.3125rem}
  .hdr.is-stuck .hdr-burger span{background:var(--ink)}
  /* the three bars become an X */
  .hdr.is-open .hdr-burger span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
  .hdr.is-open .hdr-burger span:nth-child(2){opacity:0}
  .hdr.is-open .hdr-burger span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

  /* the bar is 42%-opaque glass, which is fine for a single row over footage
     and not fine behind five lines of nav — a bright frame of the flythrough
     shows straight through. While the panel is open the whole header goes
     near-solid. */
  .hdr.is-open{background:rgba(9,13,16,.95)}
  .hdr.is-open.is-stuck{background:rgba(245,243,238,.98)}
  .mnav{
    display:none; border-top:1px solid rgba(255,255,255,.13);
    padding:.5rem clamp(1.25rem,5vw,2rem) clamp(1.5rem,4vw,2rem);
    max-height:calc(100dvh - 4.75rem); overflow-y:auto;
  }
  .hdr.is-open .mnav{display:block}
  .mnav a.mn{
    display:block; padding:.95rem 0; text-decoration:none;
    border-bottom:1px solid rgba(255,255,255,.10);
    font:500 1.0625rem/1.2 var(--sans); color:rgba(255,255,255,.9);
  }
  .mnav a.mn:last-of-type{border-bottom:0}
  .mnav .mn-foot{display:flex; flex-direction:column; gap:.9rem; margin-top:1.1rem}
  .mnav .mn-tel{
    font:500 .9375rem/1 var(--mono); letter-spacing:.02em;
    color:rgba(255,255,255,.75); text-decoration:none; padding:.5rem 0;
  }
  .mnav .btn{width:100%; justify-content:center}
  /* scrolled state: the bar is paper, so the panel has to be too */
  .hdr.is-stuck .mnav{border-top-color:var(--rule)}
  .hdr.is-stuck .mnav a.mn{color:var(--ink); border-bottom-color:var(--rule)}
  .hdr.is-stuck .mnav .mn-tel{color:var(--ink-3)}
}
@media (prefers-reduced-motion:reduce){ .hdr-burger span{transition:none} }

/* ── sticky Inquire bar, phones only ────────────────────────────────────
   The page is long — the FAQ added a lot — and on a phone the only CTA was at
   the very top and the very bottom (Eric, 2026-08-23). This one appears once
   the hero is scrolled past and hides again over the Inquire section itself,
   so it never sits on top of the form it is pointing at.

   Positioned above the safe-area inset so it clears the iOS home bar, and the
   page gets bottom padding to match so the footer's last line is never stuck
   underneath it. */
.stickybar{display:none}
@media (max-width:60rem){
  .stickybar{
    display:block; position:fixed; left:0; right:0;
    bottom:calc(env(safe-area-inset-bottom, 0px));
    z-index:40; padding:.6rem clamp(.85rem,4vw,1.25rem) .7rem;
    background:rgba(245,243,238,.94);
    -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
    border-top:1px solid var(--rule);
    transform:translateY(115%); transition:transform .26s cubic-bezier(.2,.7,.2,1);
    pointer-events:none;
  }
  .stickybar.is-on{transform:translateY(0); pointer-events:auto}
  .stickybar .btn{width:100%; justify-content:center; padding-block:.95rem}
  /* room for it, so nothing is permanently hidden behind the bar */
  body{padding-bottom:5rem}
  /* the mobile menu owns the screen while open — two stacked CTAs is noise */
  .hdr.is-open ~ .stickybar{transform:translateY(115%)}
}
@media (max-width:60rem) and (prefers-reduced-motion:reduce){
  .stickybar{transition:none}
}
/* Below 26rem the header is genuinely tight: the logo lockup is ~165px and
   "INQUIRE NOW" is 40px wider than the "INQUIRE" it replaced (2026-08-21), so
   at 320px the pair overran the row and the button's arrow chip was cut off at
   the screen edge. The chip goes rather than the label — it is decoration, and
   the label is the conversion path. */
@media (max-width:26rem){
  .hdr-in{gap:.6rem}
  .hdr-logo img{height:1.9rem}
  .cta-split span{font-size:.75rem; letter-spacing:.04em; padding:.7rem .75rem}
  .cta-split i{display:none}
}

/* ── hero: the flythrough video ─────────────────────────────────────────
   The <img> is the base layer — the poster frame, which is also the video's
   own first frame, so it is the LCP image, the no-video fallback, and the
   whole hero under reduced motion. The <video> sits on top of it and is
   transparent until its first frame decodes, so there is no flash and no
   second picture. Both cover-fit the same way.                            */
.hero{position:relative; min-height:min(50rem,100svh); display:flex; align-items:flex-end; overflow:hidden; background:var(--dark)}
.hero-media{position:absolute; inset:0}
.hero-media img,.hero-media video{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:50% 50%;
}
/* scrim: dark at the bottom where the type sits, lighter up top. Lighter
   than the still-image version was — the footage is already dimmed by
   IMG_DIM in the canvas, and stacking both buried the building. */
.hero-media::after{
  content:""; position:absolute; inset:0; z-index:2;
  background:
    linear-gradient(to top,rgba(8,12,15,.88) 0%,rgba(8,12,15,.64) 26%,rgba(8,12,15,.28) 58%,rgba(8,12,15,.42) 100%);
}
.hero-vid{z-index:1}
.hero-in{position:relative; z-index:3; width:100%; padding-block:clamp(3rem,7vw,5.5rem) clamp(3rem,6vw,4.5rem); padding-top:9rem}
/* the footage passes under the type, and some frames are bright — the racking
   aisle and the white roof both are. A shadow is cheaper than scrimming the
   whole hero darker, and it holds contrast on every frame of the loop. */
.hero .eyebrow{
  color:rgba(255,255,255,.9); text-shadow:0 1px 14px rgba(0,8,16,.8);
  font-size:clamp(.8125rem,.95vw,1.0625rem); letter-spacing:.2em;
}
/* no cyan square on this one: at this size the mark reads as a bullet next to
   a standalone line rather than as the section-label device it is elsewhere */
.hero .eyebrow::before{display:none}
.hero .h-display{
  color:#fff; margin-top:1.15rem; max-width:22ch;
  font-size:clamp(2.25rem,6.2vw,5.25rem); line-height:1.02;
  text-wrap:normal;   /* the break is authored, not balanced */
  text-shadow:0 2px 34px rgba(0,8,16,.6), 0 1px 3px rgba(0,8,16,.4);
}
/* the headline is two authored lines, so it never re-wraps into three.
   color:inherit because the shared `.h-display span` rule would otherwise
   drop both lines to the two-tone gray. */
.hero .h-display .ln{display:block; color:inherit}
/* both hero buttons on one width, so the pair reads as a pair — left to
   themselves the two labels come out at different widths and the pair reads
   as an accident. The white one is the primary and carries the arrow; the
   colours were flipped at Eric's direction (2026-08-21), so "Inquire Now" is
   white and "Our Properties" is the glass button, while the left-to-right
   order stays as it was. */
.hero .btn-row{margin-top:2.25rem}
.hero .btn-row .btn{min-width:12.5rem; justify-content:center}

/* ── concept strip under the hero ────────────────────────────────────────
   One sentence, then the four things a unit actually gives you, in a
   hairline-ruled four-up with circled icons — the layout Eric marked up.  */
.concept{background:var(--paper); padding-block:clamp(3.5rem,7vw,5.5rem)}
/* Paragraph on top, the three points in a row underneath — Eric's second
   pass on the canvas. It was briefly two columns (paragraph left, points
   stacked right) and before that a single centred line measured to the em.
   The paragraph keeps a measure rather than running the full 1104px, since
   44px type across the whole band is too long a line to read. */
.concept-grid{display:block}
.concept .h-stmt{max-width:44ch}
/* .accent beats the shared `.h-stmt span` grey rule */
.concept .h-stmt .accent{color:var(--navy)}
.pts{
  display:grid; grid-template-columns:repeat(4,1fr);
  gap:clamp(1.25rem,2.5vw,2.25rem);
  margin-top:clamp(2.25rem,4.5vw,3.25rem);
  padding-top:clamp(1.5rem,3vw,2rem);
  border-top:1px solid var(--rule);
}
.pt{display:grid; grid-template-columns:auto 1fr; gap:.95rem; align-items:start}
.pt .ic{
  width:2.75rem; height:2.75rem; border-radius:50%; flex:none;
  border:1px solid var(--rule-2); background:var(--white);
  display:grid; place-items:center; color:var(--navy);
}
/* the four feature titles are brand blue too (Eric, 2026-08-23) — 6.16:1 on
   this band's paper-2 ground at 13px bold */
.pt b{display:block; font:700 .8125rem/1.3 var(--sans); letter-spacing:.03em; text-transform:uppercase; color:var(--navy)}
/* all four of these are a single short sentence now (Eric, 2026-08-22);
   balance keeps any that do wrap from orphaning a last word */
.pt p{margin-top:.45rem; font-size:.875rem; line-height:1.5; color:var(--ink-2); text-wrap:balance}
@media (max-width:64rem){ .pts{grid-template-columns:repeat(2,1fr); gap:1.75rem clamp(1.25rem,3vw,2.25rem)} }
@media (max-width:40rem){ .pts{grid-template-columns:1fr; gap:0} .pt{border-top:1px solid var(--rule); padding-block:1.15rem} .pts > .pt:first-child{border-top:0} }

/* ── hairline three-column feature row, after jane.energy ───────────────── */
.hair{display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(1.25rem,3vw,2.5rem); margin-top:clamp(2.5rem,5vw,4rem)}
.hair > div{border-top:1px solid var(--rule-2); padding-top:1.1rem}
.hair b{display:block; font:600 .9375rem/1.4 var(--sans); margin-bottom:.5rem}
.hair p{font-size:.9375rem; color:var(--ink-2); line-height:1.6}
@media (max-width:52rem){ .hair{grid-template-columns:1fr} }

/* ── markets ────────────────────────────────────────────────────────────── */
.mkts{display:grid; grid-template-columns:repeat(3,1fr); gap:1.25rem; margin-top:clamp(2.5rem,5vw,3.5rem)}
/* a very slight lift on hover — Eric's request. transform and box-shadow
   only, so it stays on the compositor; the 1.012 scale is about 5px on a
   354px card, which reads as the card coming forward rather than growing. */
.mkt{
  background:var(--white); border:1px solid var(--rule); border-radius:3px;
  display:flex; flex-direction:column; overflow:hidden;
  transition:transform .22s cubic-bezier(.2,.7,.2,1), box-shadow .22s ease;
}
.mkt:hover{transform:scale(1.012); box-shadow:0 12px 28px rgba(20,20,19,.10)}
@media (prefers-reduced-motion:reduce){ .mkt:hover{transform:none} }
.mkt-img{aspect-ratio:16/10; background:var(--paper-3); position:relative; overflow:hidden}
.mkt-img img{width:100%; height:100%; object-fit:cover}
.mkt-body{padding:1.35rem 1.35rem 1.5rem; display:flex; flex-direction:column; gap:.85rem; flex:1}
.mkt-top{display:flex; align-items:flex-start; justify-content:space-between; gap:.75rem}
.mkt h3{font-family:var(--serif); font-weight:400; font-size:1.5rem; line-height:1.15; margin:0; letter-spacing:-.01em}
.mkt .region{font:500 .625rem/1 var(--mono); letter-spacing:.14em; text-transform:uppercase; color:var(--ink-3); margin-top:.5rem; display:block}
.badge{
  flex:none; font:600 .5625rem/1 var(--mono); letter-spacing:.12em; text-transform:uppercase;
  padding:.35rem .5rem; border-radius:2px; white-space:nowrap;
}
/* dates, not statuses: none of the three is open yet, so the badge carries
   the delivery month. Navy on tint reads as information; the orange live
   badge is retired for now but kept in case a site opens. */
.badge--date{background:#eaf2f8; color:var(--navy); border:1px solid #c5dced}
.badge--live{background:#fff1e6; color:#a34700; border:1px solid #ffcfa8}
.badge--build{background:var(--paper-2); color:var(--ink-3); border:1px solid var(--rule-2)}
.mkt .addr{font:400 .8125rem/1.5 var(--mono); color:var(--ink-2)}
.mkt .why{font-size:.9375rem; color:var(--ink-2); line-height:1.6}
/* the use-case tag row that used to close each card is gone — Eric's call.
   Its hairline is reused for the card's footer row: Brochure and Video on the
   left, the Inquire button hard right (Eric, 2026-08-23). margin-top:auto sits
   on the FOOTER, not on the links, so the three footers line up across the row
   even though the "why" paragraphs differ in length. The two text links share
   a group so the button stays pinned right whatever they wrap to. */
.mkt-foot{
  margin-top:auto; padding-top:.9rem; border-top:1px solid var(--rule);
  display:flex; align-items:center; justify-content:space-between;
  gap:.5rem 1rem; flex-wrap:wrap;
}
.mkt .vid{
  display:inline-flex; align-items:center; gap:.5rem;
  font:600 .8125rem/1 var(--sans); color:var(--navy); text-decoration:none;
}
.mkt .vid:hover{color:var(--navy-d); text-decoration:underline}
.mkt .vid svg{flex:none}
/* deliberately smaller than any other button on the page: three of these sit
   in a row, and they must not outweigh the hero's Inquire Now or the header's */
.mkt .inq{
  flex:none; display:inline-flex; align-items:center; gap:.4rem;
  font:600 .75rem/1 var(--sans); padding:.55rem .75rem; border-radius:2px;
  border:1px solid var(--navy); background:var(--navy); color:#fff;
  text-decoration:none; transition:background .18s, border-color .18s;
}
.mkt .inq:hover{background:var(--navy-d); border-color:var(--navy-d)}
.mkt .inq svg{flex:none}
/* TOUCH TARGETS. A 15px-tall line of link text is fine under a
   cursor, too small under a thumb, and it sits inches from two other targets.
   On touch or narrow screens the three card controls get vertical padding to
   clear ~44px; the footer's own padding comes down to match, so the row looks
   the same and only the hit area grows. */
@media (max-width:60rem), (hover:none){
  .mkt-foot{padding-top:.3rem}
  .mkt .vid,
  .mkt .broc{padding-block:.85rem}
  .mkt .inq{padding-block:.8rem}
}
@media (max-width:60rem){ .mkts{grid-template-columns:1fr} .mkt-img{aspect-ratio:21/9} }

/* ── clear height: the 18ft vs 28ft comparison ─────────────────────────── */
.ch{
  margin:clamp(2.5rem,5vw,3.5rem) 0 0; background:var(--white);
  border:1px solid var(--rule); border-radius:3px;
  padding:clamp(1.25rem,3vw,2.25rem);
}
.ch svg{width:100%; height:auto; display:block}
/* landscape on a desktop, stacked portrait on a phone — see TWO DRAWINGS, ONE
   FIGURE in the section comment for why this is a swap and not a rescale.
   The portrait one is capped so it renders near 1:1 instead of ballooning to
   30px labels on a tablet.

   These selectors are .ch-qualified on purpose: `.ch svg` above sets
   display:block at specificity (0,1,1), so a bare `.chsvg--tall{display:none}`
   at (0,1,0) loses to it and BOTH drawings render. A media query adds no
   specificity of its own, which is what makes that failure look like the
   query is being ignored. */
.ch .chsvg--tall{display:none}
@media (max-width:56rem){
  .ch .chsvg--wide{display:none}
  .ch .chsvg--tall{display:block; max-width:22rem; margin-inline:auto}
}
/* the diagram responds to hover: the side you point at brightens and shows
   its own volume and tier count, the other dims. :has() does the dimming, so
   there is no JS — and no hover state at all on touch, which is correct. */
.chsvg .side,.chsvg .box,.chsvg .detail,.chsvg .pal rect{transition:opacity .18s ease, stroke .18s ease, fill .18s ease}
.chsvg .detail{opacity:0}
.chsvg .side:hover .detail{opacity:1}
.chsvg .side:hover .box{stroke:var(--navy); stroke-width:2}
.chsvg .side:hover .pal rect{fill:#a9d6f0}
.chsvg:has(.s18:hover) .s28{opacity:.32}
.chsvg:has(.s28:hover) .s18{opacity:.32}

/* ── the diagram builds itself when it comes into view ───────────────────
   The drawing used to arrive fully formed and reveal a little on hover, which
   meant the page's strongest argument — the same footprint holding 80% more —
   landed as a static picture. It now assembles: the 18 ft box draws, its three
   tiers stack bottom-up, the 28 ft box grows to full height, its two extra
   tiers slide in, the arrow draws, and the counter runs 275 -> 500.

   HOW IT IS BUILT
   - .ch starts with .is-armed (added by script, so no-JS visitors see the
     finished drawing and lose nothing).
   - .is-built is added once by an IntersectionObserver at 35% visibility.
   - Everything between is CSS transition with a per-element delay. No rAF, no
     scroll handler, nothing on the scroll thread, and it plays once.
   - The 28 ft box grows via transform:scaleY from its own bottom edge, which
     is a compositor property; the pallets fade and rise 8 units.

   REDUCED MOTION gets the finished state immediately — this is decorative
   emphasis, and 2.2s of movement is exactly what that setting is for. */
.ch.is-armed .chsvg--wide .box,
.ch.is-armed .chsvg--wide .pal rect,
.ch.is-armed .chsvg--wide .shelf line,
.ch.is-armed .chsvg--wide .dim,
.ch.is-armed .chsvg--wide .cap,
.ch.is-armed .chsvg--wide .gain{opacity:0}
.ch.is-armed .chsvg--wide .s28 .grow{transform:scaleY(.643); transform-origin:0 250px}

.ch.is-armed.is-built .chsvg--wide .box,
.ch.is-armed.is-built .chsvg--wide .pal rect,
.ch.is-armed.is-built .chsvg--wide .shelf line,
.ch.is-armed.is-built .chsvg--wide .dim,
.ch.is-armed.is-built .chsvg--wide .cap,
.ch.is-armed.is-built .chsvg--wide .gain{opacity:1}
.ch.is-armed.is-built .chsvg--wide .s28 .grow{transform:scaleY(1)}

.ch.is-armed .chsvg--wide .box{transition:opacity .45s ease}
.ch.is-armed .chsvg--wide .s28 .grow{transition:transform .75s cubic-bezier(.22,.75,.2,1) .45s}
.ch.is-armed .chsvg--wide .pal rect,
.ch.is-armed .chsvg--wide .shelf line{transition:opacity .34s ease, transform .34s ease}
.ch.is-armed .chsvg--wide .dim,
.ch.is-armed .chsvg--wide .cap{transition:opacity .4s ease}
.ch.is-armed .chsvg--wide .gain{transition:opacity .5s ease}

/* pallets rise into place; tier index drives the delay so they stack upward */
.ch.is-armed .chsvg--wide .pal rect{transform:translateY(8px)}
.ch.is-armed.is-built .chsvg--wide .pal rect{transform:translateY(0)}
.ch.is-armed .chsvg--wide .t1 rect,.ch.is-armed .chsvg--wide .t1 line{transition-delay:.30s}
.ch.is-armed .chsvg--wide .t2 rect,.ch.is-armed .chsvg--wide .t2 line{transition-delay:.44s}
.ch.is-armed .chsvg--wide .t3 rect,.ch.is-armed .chsvg--wide .t3 line{transition-delay:.58s}
.ch.is-armed .chsvg--wide .s28 .t1 rect,.ch.is-armed .chsvg--wide .s28 .t1 line{transition-delay:1.05s}
.ch.is-armed .chsvg--wide .s28 .t2 rect,.ch.is-armed .chsvg--wide .s28 .t2 line{transition-delay:1.19s}
.ch.is-armed .chsvg--wide .s28 .t3 rect,.ch.is-armed .chsvg--wide .s28 .t3 line{transition-delay:1.33s}
.ch.is-armed .chsvg--wide .s28 .t4 rect,.ch.is-armed .chsvg--wide .s28 .t4 line{transition-delay:1.47s}
.ch.is-armed .chsvg--wide .s28 .t5 rect,.ch.is-armed .chsvg--wide .s28 .t5 line{transition-delay:1.61s}
.ch.is-armed .chsvg--wide .s18 .dim,.ch.is-armed .chsvg--wide .s18 .cap{transition-delay:.72s}
.ch.is-armed .chsvg--wide .s28 .dim,.ch.is-armed .chsvg--wide .s28 .cap{transition-delay:1.75s}
.ch.is-armed .chsvg--wide .gain{transition-delay:1.95s}

@media (prefers-reduced-motion:reduce){
  .ch.is-armed .chsvg--wide *{opacity:1 !important; transform:none !important; transition:none !important}
}
/* Four cells on one hairline: three deltas, then the calculator button as the
   fourth — Eric's layout. Icons sit beside each number rather than above it,
   which is what closed up the white space the numbers left. The gap is
   uniform, so the cells stay evenly spaced whatever the label lengths.

   The fourth column is 1.35fr rather than 1fr: Eric asked for the button to
   read louder (2026-08-21), and "See how much you can save" plus the arrow
   needs about 290px at the larger type. The three numbers give up ~20px each
   to pay for it, which is why .deltas b is a notch smaller than .h-sec — at
   the old 36px "+44,000 ft³" no longer fits its column on one line. */
.deltas{
  display:grid; grid-template-columns:repeat(3,1fr) 1.35fr;
  gap:clamp(1rem,2vw,1.75rem); margin-top:clamp(2rem,4vw,2.75rem);
}
.deltas > div{
  border-top:1px solid var(--rule-2); padding-top:1.1rem;
  display:grid; grid-template-columns:auto 1fr; gap:.9rem; align-items:start;
}
.deltas .ic{
  width:2.5rem; height:2.5rem; border-radius:50%; flex:none;
  border:1px solid var(--rule-2); background:var(--white);
  display:grid; place-items:center; color:var(--navy); margin-top:.15rem;
}
.deltas b{
  display:block; font-family:var(--serif); font-weight:400;
  font-size:clamp(1.5rem,2.55vw,2rem); line-height:1; letter-spacing:-.02em;
  color:var(--navy); white-space:nowrap;
}
.deltas span{
  display:block; margin-top:.5rem; font:500 .6875rem/1.5 var(--mono);
  letter-spacing:.12em; text-transform:uppercase; color:var(--ink-3);
}
/* the fourth cell is the button, so it has no icon column and its caption
   sits underneath rather than beside. Bigger type and deeper padding than a
   default .btn, on purpose — this is the loudest thing in the section. */
.deltas .act{display:block}
.deltas .act .btn{
  width:100%; justify-content:center;
  font-size:1.0625rem; padding:1.15rem 1.25rem;
  box-shadow:0 1px 2px rgba(0,42,74,.24);
}
.deltas .act p{margin-top:.75rem; font-size:.875rem; line-height:1.5; color:var(--ink-3)}
/* Two-up: the button takes the full second row rather than sitting in a
   half-width cell, so it does not have to shrink its label to fit. */
@media (max-width:64rem){
  .deltas{grid-template-columns:repeat(2,1fr); gap:1.75rem clamp(1rem,2vw,1.75rem)}
  .deltas .act{grid-column:1 / -1}
  .deltas .act .btn{max-width:24rem}
}
@media (max-width:40rem){
  .deltas{grid-template-columns:1fr}
  /* the label is 25 characters and .btn is nowrap by default, which would
     overflow a 320px screen — let it wrap and centre instead */
  .deltas .act .btn{max-width:none; white-space:normal; text-align:center}
}

/* ── founders: the one full-colour band ────────────────────────────────
   Brand navy rather than the near-black it used to be — Eric found that too
   aggressive. Only this section uses .dark; the footer sets its own ground,
   so it stays near-black. All four tints below clear 5.5:1 on #23539c. */
.dark{background:var(--navy); color:#e8f1f7}
/* THE ONE-LINE HEADLINE RULE IS RETIRED (Eric, 2026-08-24). It read, from
   2026-08-21: "Eric wants this headline on ONE line. It is 51 characters, so at
   the shared .h-sec size it needs about 1050px and .sec-hd caps at 992px —
   hence the wider box and the slightly smaller size of its own."

   That held while the headline was alone on its row. Once the Preferred Freezer
   mark went in, a full-width single line forced the badge underneath it and
   opened a large dead gap before "Our vision". Eric's call: put the mark beside
   the headline and let the headline wrap. Two balanced lines make a block of
   type the badge can sit against, and the row closes the gap.

   text-wrap:balance is what keeps it from breaking as one long line plus an
   orphan; browsers without it just get a normal ragged wrap, which is fine. */
#about .sec-hd{max-width:none}
#about .h-sec{font-size:clamp(1.875rem,3.25vw,2.75rem); text-wrap:balance; margin-top:0}

.about-hd{
  display:flex; align-items:center;
  gap:clamp(.9rem,1.8vw,1.6rem);
  margin-top:1.1rem;
}
/* width:max-content, not a max-width cap. A wrapped block always fills the
   width it is given, so any ch cap left the box wider than the words and held
   the mark away from them. With the break written into the markup, max-content
   resolves to the longest line and the box hugs the type exactly — so the gap
   below is the whole distance between the words and the badge. */
.about-hd .h-sec{flex:0 1 auto; min-width:0; width:max-content; max-width:100%}

/* NO PLATE BEHIND THE MARK (Eric, 2026-08-24). A white plate was tried first,
   on the reasoning that Preferred Freezer's #00519d would be lost against this
   band's #23539c. It is not: the badge carries a white keyline all the way
   round, so the arch still reads, and the two blues sitting close makes it look
   like it belongs on the band rather than pasted onto it. A one-colour reverse
   version was also tried and discarded for the same reason — it threw away the
   brand's own colour to solve a problem that was not there. The mark goes on
   the band exactly as it is. */
.about-hd .pfs-chip{flex:none; display:block}
.about-hd .pfs-chip img{height:clamp(5rem,8vw,6.75rem); width:auto}

/* Below 56rem the row would squeeze the headline to a column of two or three
   words. Stack instead — and down here the badge sits ABOVE the headline, so
   the gap it used to open lands under the eyebrow where there is already
   space, not between the headline and the vision copy. */
@media (max-width:56rem){
  .about-hd{flex-direction:column-reverse; align-items:flex-start; gap:1.35rem}
  /* back to a normal wrapping block down here — max-content would run the
     headline off the side of a phone. text-wrap:balance takes over the breaks. */
  .about-hd .h-sec{width:auto; max-width:none; font-size:clamp(1.875rem,4vw,2.5rem)}
  .hd-br{display:none}
}

/* the vision paragraph — serif, between lede and heading in size. Measure has
   moved twice: 62ch left the right half of the band empty, two columns were
   too much of a newspaper. It is one paragraph at 84ch — wider than it began,
   short of the full 1104px band, and about as long a line as a serif this
   size can carry (Eric, 2026-08-22). */
#about .vision{
  max-width:84ch;
  margin-bottom:clamp(2.75rem,5.5vw,4rem);
}
#about .v-copy{
  margin-top:1.1rem; font-family:var(--serif); font-weight:400;
  font-size:clamp(1.1875rem,1.6vw,1.4375rem); line-height:1.55;
  letter-spacing:-.006em; color:#dbe9f3;
}
/* "Our vision" and "Our team" are subheads rather than mono eyebrows at Eric's
   direction (2026-08-22): serif, clearly headings, but a long way short of the
   band's h2 so the hierarchy still reads top-down. The hairlines under the
   vision paragraph and above each headshot came out at the same time — with
   real subheads doing the dividing, the rules were saying it twice. */
#about .subh{
  font-family:var(--serif); font-weight:400; margin:0;
  font-size:clamp(1.375rem,1.8vw,1.625rem); line-height:1.2;
  letter-spacing:-.008em; color:#f6fafd;
}
#about .fdrs{margin-top:clamp(1.25rem,2.5vw,1.75rem)}
.dark .h-sec{color:#f6fafd}
.dark .h-sec span{color:#c3d6ea}
.dark .lede{color:#cfe0ec}
/* no bright cyan anywhere in here, including the eyebrow's square */
.dark .eyebrow{color:#c3d6ea}
.fdrs{display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(1.5rem,3vw,2.5rem); margin-top:clamp(2.5rem,5vw,4rem)}
.fdr{padding-top:0}
/* real headshots from unitcold.com/about, cropped to circles. Capped at 12rem
   rather than filling the column — a 341px circle dominates the row, and the
   three photos were taken in three different rooms, so smaller reads calmer. */
.fdr .shot{
  display:block; width:min(12rem,100%); aspect-ratio:1/1; object-fit:cover;
  object-position:50% 20%; border-radius:50%; margin-bottom:1.5rem;
  background:rgba(255,255,255,.08);
}
.fdr h4{font-family:var(--serif); font-weight:400; font-size:1.5rem; line-height:1.15; margin:0 0 .35rem; color:#f6fafd}
.fdr .role{font:500 .625rem/1.3 var(--mono); letter-spacing:.13em; text-transform:uppercase; color:#c3d6ea; display:block; margin-bottom:1.1rem}
.fdr ul{list-style:none; margin:0; padding:0; display:grid; gap:.7rem}
.fdr li{
  font-size:.9375rem; line-height:1.5; color:#cfe0ec;
  padding-left:1.1rem; position:relative;
}
.fdr li::before{content:""; position:absolute; left:0; top:.62em; width:.3rem; height:.3rem; background:#7fa8c4; border-radius:1px}
@media (max-width:60rem){ .fdrs{grid-template-columns:1fr} }

/* ── fit by segment ────────────────────────────────────────────────────── */
.fits{display:grid; grid-template-columns:repeat(2,1fr); gap:0 clamp(2rem,5vw,4rem); margin-top:clamp(2.5rem,5vw,3.5rem)}
.fit{display:grid; grid-template-columns:2.5rem 1fr; gap:1.1rem; padding:1.35rem 0; border-top:1px solid var(--rule)}
/* navy, not cyan: at .8125rem the cyan is about 2.3:1 on this paper and was
   the last bright-blue accent left on the page (Eric, 2026-08-22) */
.fit .n{font:500 .8125rem/1.5 var(--mono); color:var(--navy)}
.fit b{display:block; font:600 1rem/1.4 var(--sans); margin-bottom:.4rem}
.fit p{font-size:.9375rem; color:var(--ink-2); line-height:1.6}
@media (max-width:60rem){ .fits{grid-template-columns:1fr} }

/* ── FAQs ──────────────────────────────────────────────────────────────
   Native <details>. The marker is suppressed and replaced with a CSS chevron
   that flips on [open], because the default triangle differs between engines
   and cannot be styled. Capped at 62rem: an answer running the full 1104px
   band would be a 130-character line. */
.faqs{margin-top:clamp(2rem,4vw,3rem); max-width:62rem}
.faq-g + .faq-g{margin-top:clamp(2.25rem,4.5vw,3.25rem)}
.faq-h{
  font-family:var(--serif); font-weight:400; margin:0 0 .5rem;
  font-size:clamp(1.25rem,1.7vw,1.5rem); line-height:1.2; letter-spacing:-.008em;
}
.faq{border-top:1px solid var(--rule)}
.faq:last-child{border-bottom:1px solid var(--rule)}
.faq summary{
  list-style:none; cursor:pointer; display:flex; align-items:flex-start;
  justify-content:space-between; gap:1.5rem; padding:1.05rem 0;
  font:600 1rem/1.45 var(--sans); color:var(--ink);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--navy)}
.faq summary:focus-visible{outline:2px solid var(--cyan); outline-offset:3px}
.faq summary::after{
  content:""; flex:none; width:.5rem; height:.5rem; margin-top:.4rem;
  border-right:1.5px solid var(--ink-3); border-bottom:1.5px solid var(--ink-3);
  transform:rotate(45deg); transform-origin:60% 60%; transition:transform .18s ease;
}
.faq[open] summary{color:var(--navy)}
.faq[open] summary::after{transform:rotate(-135deg); border-color:var(--navy)}
.faq p{
  margin:-.15rem 0 1.25rem; padding-right:2.5rem; max-width:80ch;
  font-size:.9375rem; line-height:1.65; color:var(--ink-2);
}
@media (prefers-reduced-motion:reduce){ .faq summary::after{transition:none} }

/* ── CTA + form ────────────────────────────────────────────────────────── */
/* Named areas rather than source order, because the photo has to sit under the
   heading on a desktop and under the FORM on a phone (Eric, 2026-08-23). The
   form spans both rows on the left-right layout. */
.cta-grid{
  display:grid; grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);
  grid-template-areas:"copy form" "photo form";
  /* minmax(0,1fr), not 1fr: a plain 1fr track keeps an automatic minimum of
     min-content, and for a replaced element with height:100% that is its
     intrinsic height — which left the photo overhanging the form by ~18px. */
  grid-template-rows:auto minmax(0,1fr);
  gap:clamp(2rem,5vw,4.5rem); align-items:start;
}
.cta-copy{grid-area:copy}
.cta-grid form{grid-area:form}
.inq-photo{grid-area:photo}
/* The image is a finished graphic carrying its own type top and bottom, so it
   cannot simply be cropped from either edge. assets/img/inquire.webp is a
   SPLICE of the 1024x1024 original: rows 25-660 (headline, subline, the whole
   scene) stacked straight onto rows 820-1004 (the floor carrying NOW
   PRE-LEASING, the markets and the logo). The ~160px of empty floor between
   them is what came out. The seam sits below the point where both yellow floor
   lines have already left the frame, so there is no line to kink — 1024x818,
   aspect 1.25 instead of 1.0.

   It then STRETCHES to fill its grid row, which is what makes its bottom edge
   land on the form's bottom edge at any width rather than only at 1440. The
   composite is within ~3% of the row's own ratio, so object-fit:cover trims
   about six pixels of ceiling and floor padding — nothing legible. */
.inq-photo{
  width:100%; height:100%; min-height:0; align-self:stretch;
  object-fit:cover; display:block;
  border:1px solid var(--rule); border-radius:3px;
}

/* ── property video lightbox ────────────────────────────────────────────
   A native <dialog>, so Escape, focus trapping and the backdrop come from
   the platform rather than from script. The three card links are ordinary
   anchors straight to the mp4, so they still work with JS off — the
   handler only intercepts to play in place. */
.vidbox{
  border:0; padding:0; background:transparent; max-width:min(64rem,92vw);
  width:100%; color:var(--on-dark);
}
.vidbox::backdrop{background:rgba(8,12,15,.82)}
.vidbox video{width:100%; height:auto; display:block; background:#000; border-radius:3px}
.vidbox-bar{display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:0 0 .8rem}
.vidbox-t{font:500 .6875rem/1 var(--mono); letter-spacing:.16em; text-transform:uppercase; color:rgba(255,255,255,.82)}
.vidbox-x{
  appearance:none; border:1px solid rgba(255,255,255,.4); background:transparent;
  color:#fff; font:600 .8125rem/1 var(--sans); padding:.5rem .85rem;
  border-radius:2px; cursor:pointer;
}
.vidbox-x:hover{background:rgba(255,255,255,.16); border-color:#fff}

/* ── calculator lightbox ────────────────────────────────────────────────
   Same pattern as the video box, but holding an iframe. Eric asked for the
   calculator to open in place rather than navigate away (2026-08-22) — the
   standalone page had no route back except the browser's Back button.
   Nearly full-viewport, because the calculator is a working tool with its
   own columns and needs the room. */
.calcbox{
  border:0; padding:0; background:transparent;
  width:min(78rem,94vw); max-width:none; height:min(88vh,60rem); max-height:none;
}
.calcbox::backdrop{background:rgba(8,12,15,.82)}
.calcbox-in{display:flex; flex-direction:column; height:100%}
.calcbox iframe{
  flex:1; width:100%; border:0; display:block;
  background:var(--paper); border-radius:3px;
}
.calcbox-bar{display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:0 0 .8rem}
.calcbox-t{font:500 .6875rem/1 var(--mono); letter-spacing:.16em; text-transform:uppercase; color:rgba(255,255,255,.82)}

/* ── brochure lightbox ──────────────────────────────────────────────────
   Same dialog as the calculator, sized for a portrait page rather than a
   wide tool. The trigger is now an explicit "Brochure" link in each card's
   footer (Eric, 2026-08-23) — it was a click anywhere on the card plus a
   linked heading, which worked but was invisible until you tried it. */
.docbox{
  border:0; padding:0; background:transparent;
  width:min(58rem,94vw); max-width:none; height:min(92vh,64rem); max-height:none;
}
.docbox::backdrop{background:rgba(8,12,15,.86)}
.docbox-in{display:flex; flex-direction:column; height:100%}
.docbox iframe{flex:1; width:100%; border:0; display:block; background:var(--paper-3); border-radius:3px}
.docbox-bar{display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:0 0 .8rem}
.docbox-t{font:500 .6875rem/1 var(--mono); letter-spacing:.16em; text-transform:uppercase; color:rgba(255,255,255,.82)}
.docbox-acts{display:flex; align-items:center; gap:.6rem}
.docbox-dl{
  font:600 .8125rem/1 var(--sans); color:rgba(255,255,255,.82);
  text-decoration:none; padding:.5rem .3rem;
}
.docbox-dl:hover{color:#fff; text-decoration:underline}

/* the brochure link, matching the video link beside it */
.mkt .broc{
  display:inline-flex; align-items:center; gap:.5rem;
  font:600 .8125rem/1 var(--sans); color:var(--navy); text-decoration:none;
}
.mkt .broc:hover{color:var(--navy-d); text-decoration:underline}
.mkt .broc svg{flex:none}
.mkt-links{display:inline-flex; align-items:center; gap:clamp(.85rem,2vw,1.25rem); flex-wrap:wrap}
form{background:var(--white); border:1px solid var(--rule); border-radius:3px; padding:clamp(1.35rem,3vw,2.25rem)}
.f2{display:grid; grid-template-columns:1fr 1fr; gap:1rem}
.fld{display:grid; gap:.45rem; margin-bottom:1rem}
.fld label{font:500 .8125rem/1 var(--sans); color:var(--ink-2)}
.fld input,.fld select,.fld textarea{
  font:400 .9375rem/1.4 var(--sans); color:var(--ink); background:var(--paper);
  border:1px solid var(--rule-2); border-radius:2px; padding:.7rem .8rem; width:100%;
}
.fld textarea{min-height:6rem; resize:vertical}
.fld input:focus,.fld select:focus,.fld textarea:focus{outline:2px solid var(--cyan); outline-offset:1px; border-color:var(--cyan)}
form .btn{width:100%; justify-content:center; margin-top:.4rem}
.form-note{margin-top:.9rem; font-size:.8125rem; color:var(--ink-3); line-height:1.55; text-align:center}
/* single column, and the photo drops below the form. No row to stretch into
   here, so it goes back to its own aspect ratio. */
@media (max-width:64rem){
  .cta-grid{
    grid-template-columns:1fr;
    grid-template-rows:auto;
    grid-template-areas:"copy" "form" "photo";
    gap:clamp(1.75rem,4vw,2.5rem);
  }
  .inq-photo{height:auto; aspect-ratio:1024/818}
}
@media (max-width:36rem){ .f2{grid-template-columns:1fr} }

/* ── footer ────────────────────────────────────────────────────────────── */
.ft{background:var(--dark); color:var(--on-dark-2); padding-block:clamp(3rem,6vw,4.5rem) 2rem; font-size:.875rem}
.ft-top{display:grid; grid-template-columns:1.4fr 1fr 1fr; gap:2.5rem; padding-bottom:2.5rem; border-bottom:1px solid var(--dark-rule)}
/* same fix as the header: the dark-background file, not a filter that would
   flatten the iceberg into a white disc */
/* the lockup is now the whole first column, so it is roughly twice the header
   size — big enough to hold the column on its own without the tagline. It is
   capped on width too, because the lockup is wide and at 1.4fr the column can
   otherwise let it run into the Properties list. */
.ft img{height:clamp(3rem,4.5vw,4.25rem); width:auto; max-width:100%; margin-bottom:0}
.ft h4{font:500 .625rem/1 var(--mono); letter-spacing:.14em; text-transform:uppercase; color:var(--on-dark-2); margin:0 0 1rem}
.ft ul{list-style:none; margin:0; padding:0; display:grid; gap:.6rem}
.ft a{text-decoration:none; color:var(--on-dark-2); transition:color .18s}
.ft a:hover{color:var(--on-dark)}
/* same touch-target reasoning as the property cards: a 16px line of text in a
   list of eight is a hard thumb target. On touch or narrow screens the rows
   get padding and the list gap comes off, so the footer grows a little rather
   than a lot. */
@media (max-width:60rem), (hover:none){
  .ft ul{gap:0}
  .ft ul a{display:inline-block; padding-block:.7rem}
  .hdr-logo{padding-block:.4rem}
  .cta-split span{padding-block:.95rem}
}
.ft-btm{padding-top:1.75rem; display:flex; flex-wrap:wrap; gap:1rem 2rem; justify-content:space-between; font-size:.8125rem; color:#6a7378}
@media (max-width:60rem){ .ft-top{grid-template-columns:1fr 1fr} .ft-top > :first-child{grid-column:1/-1} }

/* ── reveal on scroll ──────────────────────────────────────────────────── */
.rv{opacity:0; transform:translateY(18px); transition:opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1)}
.rv.in{opacity:1; transform:none}
@media (prefers-reduced-motion:reduce){ .rv{opacity:1; transform:none} }

/* ══════════════════════════════════════════════════════════════════════════
   PROPERTY PAGES
   Added 2026-08-24. One page per building, at /locations/<slug>/.

   WHY THEY EXIST. Search intent for this product is geographic — "cold
   storage for lease Houston" wants a page that is ABOUT Houston. A single
   homepage covering three markets is about all three and therefore fully
   about none of them, and the three markets compete for the same page.

   WHAT MAKES EACH ONE NOT-DUPLICATE. Address, opening date, the walkthrough
   video for that building, the brochure for that building, the construction
   camera, and a location rationale taken from that brochure's own distance
   table. The shared unit spec is common to all three by design — it is the
   product — so it sits BELOW the fold on each page, under the material that
   differs. Everything above .pspec is unique per property.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── breadcrumb ─────────────────────────────────────────────────────────── */
.crumb{font:500 .6875rem/1 var(--mono); letter-spacing:.1em; text-transform:uppercase;
       color:var(--ink-3); display:flex; gap:.5rem; align-items:center; flex-wrap:wrap}
.crumb a{text-decoration:none; color:var(--ink-3); border-bottom:1px solid transparent}
.crumb a:hover{color:var(--ink); border-bottom-color:var(--rule-2)}
.crumb span[aria-current]{color:var(--ink)}

/* ── property hero ──────────────────────────────────────────────────────────
   Shorter than the homepage hero (60svh vs 100svh) on purpose: this page is
   consulted, not landed on cold, so the facts need to be reachable sooner. */
.php{min-height:min(38rem,72svh)}
.php .hero-in{padding-top:8rem}
.php .h-display{font-size:clamp(2.35rem,5.4vw,4.15rem)}
.php-meta{display:flex; flex-wrap:wrap; gap:.6rem 1.25rem; align-items:center; margin-top:1.15rem}
.php-addr{font:400 1rem/1.45 var(--sans); color:rgba(255,255,255,.86); margin:0}
.php .badge--date{background:rgba(255,255,255,.14); color:#fff; border-color:rgba(255,255,255,.4)}

/* ── key facts strip, directly under the hero ───────────────────────────────
   After diligencesquared's under-hero strip. Four items so a buyer can
   self-select before scrolling — audit §3.1, the same argument that put
   numbers in the homepage concept strip. */
.pfacts{background:var(--dark); color:var(--on-dark); border-top:1px solid var(--dark-rule)}
.pfacts-in{display:grid; grid-template-columns:repeat(4,1fr); gap:1px; background:var(--dark-rule)}
.pfacts .pf{background:var(--dark); padding:1.6rem clamp(1rem,2vw,1.75rem)}
.pfacts .pf dt{font:500 .625rem/1 var(--mono); letter-spacing:.14em; text-transform:uppercase;
                color:var(--on-dark-2); margin:0 0 .55rem}
.pfacts .pf dd{margin:0; font-family:var(--serif); font-size:clamp(1.3rem,2.1vw,1.7rem);
                line-height:1.2; font-weight:400}
.pfacts .pf dd small{display:block; font:400 .8125rem/1.4 var(--sans); color:var(--on-dark-2); margin-top:.35rem}
@media (max-width:60rem){ .pfacts-in{grid-template-columns:repeat(2,1fr)} }
@media (max-width:30rem){ .pfacts-in{grid-template-columns:1fr} }

/* ── two-column body: media left, prose right ───────────────────────────── */
.psplit{display:grid; grid-template-columns:1.15fr .85fr; gap:clamp(1.75rem,4vw,3.5rem); align-items:start}
@media (max-width:56rem){ .psplit{grid-template-columns:1fr} }
.pfig{margin:0; border:1px solid var(--rule); background:var(--white)}
.pfig img,.pfig video{width:100%; display:block; aspect-ratio:16/10; object-fit:cover}
.pfig figcaption{padding:.85rem 1.1rem; font:400 .8125rem/1.5 var(--sans); color:var(--ink-2);
                 border-top:1px solid var(--rule)}

/* ── construction camera ────────────────────────────────────────────────────
   .plive-embed holds a 16:9 iframe once a real stream URL exists. Until then
   .plive-wait renders in its place. Do not delete the placeholder markup —
   swapping it for the iframe is a two-line edit, documented in the page. */
.plive{border:1px solid var(--rule); background:var(--white)}
.plive-embed{position:relative; aspect-ratio:16/9; background:var(--dark)}
.plive-embed iframe{position:absolute; inset:0; width:100%; height:100%; border:0}
/* Not 16/9. The offline state is a short notice, not a placeholder standing in
   for the frame — held at video height it renders as a 40rem empty box. The
   live .plive-embed keeps the real 16/9. */
.plive-wait{min-height:15rem; display:flex; flex-direction:column; align-items:center;
            justify-content:center; gap:.75rem; text-align:center; padding:3rem 2rem;
            background:var(--paper-2); border-bottom:1px solid var(--rule)}
.plive-wait p{font:400 .9375rem/1.55 var(--sans); color:var(--ink-2); max-width:26rem}
.plive-dot{display:inline-flex; align-items:center; gap:.5rem; font:500 .625rem/1 var(--mono);
           letter-spacing:.14em; text-transform:uppercase; color:var(--ink-3)}
.plive-dot::before{content:""; width:7px; height:7px; border-radius:50%; background:var(--rule-2)}
.plive.is-live .plive-dot{color:#b4231f}
.plive.is-live .plive-dot::before{background:#d0342c; animation:plivepulse 2s ease-in-out infinite}
@keyframes plivepulse{0%,100%{opacity:1}50%{opacity:.35}}
.plive-foot{padding:.9rem 1.1rem; display:flex; justify-content:space-between; gap:1rem;
            align-items:center; flex-wrap:wrap}

/* ── the shared unit spec ───────────────────────────────────────────────── */
/* Grid lines are drawn by each CELL's outline, not by letting a rule-coloured
   grid background show through the 1px gaps. With the background method any
   row that is not completely full renders its empty tracks as grey blocks, and
   these lists are whatever length the property data happens to be. */
.pspec{display:grid; grid-template-columns:repeat(3,1fr); gap:1px;
       background:var(--white); border:1px solid var(--rule); margin-top:2rem}
.pspec div{background:var(--white); padding:1.15rem 1.25rem; box-shadow:0 0 0 1px var(--rule)}
.pspec dt{font:500 .625rem/1 var(--mono); letter-spacing:.13em; text-transform:uppercase;
          color:var(--ink-3); margin:0 0 .45rem}
.pspec dd{margin:0; font-family:var(--serif); font-size:1.3rem; line-height:1.2}
@media (max-width:56rem){ .pspec{grid-template-columns:repeat(2,1fr)} }
@media (max-width:26rem){ .pspec{grid-template-columns:1fr} }

/* ── brochure / downloads row ───────────────────────────────────────────── */
.pdl{display:flex; gap:1rem; flex-wrap:wrap; margin-top:1.75rem}

/* ── locations hub ──────────────────────────────────────────────────────── */
.hub-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(1rem,2vw,1.5rem)}
@media (max-width:56rem){ .hub-grid{grid-template-columns:1fr} }
.hub-grid .mkt-body{gap:.7rem}
.hub-card-link{text-decoration:none; color:inherit; display:flex; flex-direction:column; height:100%}
/* the "also leasing" row on a property page always holds exactly two cards —
   the other two markets — so it gets its own two-up grid rather than sitting
   in the three-column hub grid with a third of the row empty. */
.hub-grid--two{grid-template-columns:repeat(2,1fr)}
@media (max-width:56rem){ .hub-grid--two{grid-template-columns:1fr} }

/* ══════════════════════════════════════════════════════════════════════════
   PROPERTIES DROPDOWN  (added 2026-08-24)

   The Properties nav item now opens a menu of the three property pages, so a
   visitor can reach Norton/Seabrook/Lake Worth from any page without going
   through the hub first.

   NO JAVASCRIPT. It opens on :hover and on :focus-within, which means a
   keyboard tab into the parent link reveals it and the three items are then in
   the tab order naturally. A script-driven menu would need aria-expanded
   bookkeeping, Escape handling and an outside-click listener to do the same
   job — this needs none of it, and it cannot desync from the DOM.

   THE PARENT LINK STILL WORKS. On the homepage it scrolls to the properties
   section as before; elsewhere it goes to /locations/. Opening the menu never
   swallows the click, so nothing that used to work stopped working.

   TOUCH. There is no hover on a touch screen, so a tap on the parent simply
   follows the link — to the hub, which lists all three. That is the correct
   fallback, and it is why the parent is a real href and not a button.
   ═════════════════════════════════════════════════════════════════════════ */
.hdr-nav .nav-sub{position:relative; display:flex; align-items:center}
.hdr-nav .nav-sub > a{display:inline-flex; align-items:center; gap:.32rem}
.hdr-nav .nav-sub > a svg{flex:none; transition:transform .18s ease}
.hdr-nav .nav-sub:hover > a svg,
.hdr-nav .nav-sub:focus-within > a svg{transform:rotate(180deg)}

/* the pointer has to cross the gap between the bar and the panel without the
   menu closing under it — this pad spans it and belongs to the same :hover */
.hdr-nav .nav-sub::after{content:""; position:absolute; top:100%; left:0; right:0; height:.75rem}

.subnav{
  position:absolute; top:100%; left:-.85rem; margin-top:.75rem; min-width:15.5rem;
  padding:.4rem; display:grid;
  /* Opaque, not translucent like the header bar. The bar can afford to let
     the hero through; a menu of links cannot — on the paper header the section
     heading behind it read straight through a .97 alpha fill. Solid also means
     no dependence on backdrop-filter, which does not render in headless
     Chromium and so could never be checked in a screenshot. */
  background:#111a20;
  border:1px solid rgba(255,255,255,.16);
  box-shadow:0 16px 34px rgba(0,0,0,.32);
  opacity:0; visibility:hidden; transform:translateY(-5px);
  transition:opacity .16s ease, transform .16s ease, visibility 0s linear .16s;
}
.hdr-nav .nav-sub:hover .subnav,
.hdr-nav .nav-sub:focus-within .subnav{
  opacity:1; visibility:visible; transform:none;
  transition:opacity .16s ease, transform .16s ease, visibility 0s;
}
.subnav a{
  display:block; padding:.6rem .8rem; text-decoration:none;
  font:500 .875rem/1.25 var(--sans); color:rgba(255,255,255,.9);
}
.subnav a small{
  display:block; margin-top:.22rem;
  font:400 .625rem/1.3 var(--mono); letter-spacing:.11em; text-transform:uppercase;
  color:rgba(255,255,255,.55);
}
.subnav a:hover{background:rgba(255,255,255,.09); color:#fff}
.subnav a:hover small{color:rgba(255,255,255,.7)}
.subnav .subnav-all{
  margin-top:.3rem; padding-top:.65rem;
  border-top:1px solid rgba(255,255,255,.14);
  font-size:.8125rem; color:rgba(255,255,255,.7);
}

/* paper header state — same menu, inverted */
.hdr.is-stuck .subnav{background:var(--white); border-color:var(--rule); box-shadow:0 16px 32px rgba(20,20,19,.13)}
.hdr.is-stuck .subnav a{color:var(--ink)}
.hdr.is-stuck .subnav a small{color:var(--ink-3)}
.hdr.is-stuck .subnav a:hover{background:rgba(0,0,0,.05)}
.hdr.is-stuck .subnav a:hover small{color:var(--ink-2)}
.hdr.is-stuck .subnav .subnav-all{border-top-color:var(--rule); color:var(--ink-2)}

/* ── the same three links inside the mobile panel ────────────────────────────
   Below 60rem .hdr-nav is display:none and the burger panel takes over, so the
   dropdown is irrelevant there. The locations are listed inline instead — an
   accordion inside a panel that is already an overlay is a second layer of
   disclosure for three links, which is not worth it. */
@media (max-width:60rem){
  .mnav .mn-subs{display:grid; padding:.1rem 0 .85rem 1rem; border-bottom:1px solid rgba(255,255,255,.13)}
  .mnav a.mn-sub{
    padding:.5rem 0; text-decoration:none;
    font:500 .9375rem/1.3 var(--sans); color:rgba(255,255,255,.72);
  }
  .mnav a.mn-sub small{
    display:block; margin-top:.15rem;
    font:400 .625rem/1.3 var(--mono); letter-spacing:.11em; text-transform:uppercase;
    color:rgba(255,255,255,.45);
  }
  .mnav a.mn.mn-parent{border-bottom:0; padding-bottom:.35rem}
  .hdr.is-stuck .mnav .mn-subs{border-bottom-color:var(--rule)}
  .hdr.is-stuck .mnav a.mn-sub{color:var(--ink-2)}
  .hdr.is-stuck .mnav a.mn-sub small{color:var(--ink-3)}
}

/* ══════════════════════════════════════════════════════════════════════════
   BROKER DATA SECTIONS  (added 2026-08-24)

   The building spec, the plans and the distance table all came off the
   Newmark/Buildout listings. They reuse .pspec and .pfig rather than inventing
   new furniture — only the three things below are actually new.
   ═════════════════════════════════════════════════════════════════════════ */

/* plans grid — the sheets are 4:3-ish and full of small type, so they get two
   up on a desktop and one up on a phone, and every one opens full size in a
   new tab. Not a lightbox: these are drawings people pinch-zoom and print, and
   a new tab hands them the browser's own zoom instead of a JS approximation. */
.pplans{display:grid; grid-template-columns:repeat(2,1fr); gap:clamp(1rem,2.5vw,1.75rem)}
@media (max-width:52rem){ .pplans{grid-template-columns:1fr} }
.pplans .pfig img{aspect-ratio:auto; height:auto}
.pplans .pfig a{display:block}
.pplans .pfig a:hover{opacity:.93}

/* distance table */
.pdist{margin:0; border-top:1px solid var(--rule)}
.pdist-row{
  display:flex; justify-content:space-between; align-items:baseline; gap:1.25rem;
  padding:.7rem 0; border-bottom:1px solid var(--rule);
}
.pdist dt{margin:0; font:400 .9375rem/1.4 var(--sans); color:var(--ink)}
.pdist dd{
  margin:0; flex:none; font:500 .8125rem/1 var(--mono);
  letter-spacing:.04em; color:var(--navy); white-space:nowrap;
}

/* the distance figure should not crop — an access map is unreadable cropped */
#distances .pfig img{aspect-ratio:auto; height:auto}


/* ── honeypot ───────────────────────────────────────────────────────────────
   Hidden by position, not by display:none or visibility:hidden — some bots
   skip fields hidden those ways, which defeats the point. Off-screen with a
   1px box keeps it in the DOM and fillable, while no sighted user can reach
   it and tabindex="-1" plus aria-hidden keep it away from keyboards and
   screen readers. */
.hp{
  position:absolute; left:-9999px; top:auto;
  width:1px; height:1px; overflow:hidden;
}