/* Self-hosted type. No third-party font request — nothing about a visitor
   leaves our server just to render the page. */
@font-face{
  font-family:'Archivo';font-style:normal;font-weight:400;font-display:swap;
  src:url('fonts/Archivo-400.woff2') format('woff2');
}
@font-face{
  font-family:'Archivo';font-style:normal;font-weight:500;font-display:swap;
  src:url('fonts/Archivo-500.woff2') format('woff2');
}
@font-face{
  font-family:'Archivo';font-style:normal;font-weight:600;font-display:swap;
  src:url('fonts/Archivo-600.woff2') format('woff2');
}
@font-face{
  font-family:'Archivo';font-style:normal;font-weight:700;font-display:swap;
  src:url('fonts/Archivo-700.woff2') format('woff2');
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:300;font-display:swap;
  src:url('fonts/Inter-300.woff2') format('woff2');
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;
  src:url('fonts/Inter-400.woff2') format('woff2');
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;
  src:url('fonts/Inter-500.woff2') format('woff2');
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;
  src:url('fonts/Inter-600.woff2') format('woff2');
}

/* ============================================================
   Billy Penn Studios — shared stylesheet
   One source of truth for every page. Change it here, it changes
   everywhere. Linked by index.html, coworking.html, etc.
   ============================================================ */

:root{
  --ink:#0A0A0A;
  --ink-soft:#1A1A1A;
  --paper:#F4F1EC;
  --paper-2:#EAE5DE;
  --white:#FFFFFF;
  --accent:#71201C;       /* oxblood */
  --accent-hi:#8E2A24;    /* hover */
  --rule:rgba(10,10,10,.14);
  --rule-dark:rgba(255,255,255,.18);
  --header-h:76px;
  --gutter:clamp(20px,5vw,88px);
  --display:'Archivo',-apple-system,'Helvetica Neue',Arial,sans-serif;
  --body:'Inter',-apple-system,'Helvetica Neue',Arial,sans-serif;
  --ease:cubic-bezier(.16,.84,.44,1);
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0;padding-top:var(--header-h);background:var(--paper);color:var(--ink);
  font-family:var(--body);font-weight:400;font-size:18px;line-height:1.6;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img{display:block;width:100%;height:100%;object-fit:cover}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{font-family:var(--display);font-weight:600;letter-spacing:-.025em;line-height:.98;margin:0;text-transform:uppercase}
p{margin:0}

/* ---------- shared bits ---------- */
.eyebrow{
  font-family:var(--body);font-size:11px;font-weight:600;
  letter-spacing:.22em;text-transform:uppercase;
}
.rule-link{
  display:inline-block;font-family:var(--body);font-size:12px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;padding-bottom:7px;
  border-bottom:1.5px solid currentColor;
}
/* a larger arrow link, for when it's the main thing to click in a section */
.rule-link--lg{font-size:15px;letter-spacing:.13em;padding-bottom:10px;border-bottom-width:2px}
.rule-link span{display:inline-block;transition:transform .45s var(--ease)}
.rule-link:hover span{transform:translateX(6px)}

.btn{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--body);font-size:14.5px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;line-height:1;
  padding:17px 44px;border:1.5px solid transparent;cursor:pointer;
  transition:background .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease);
}
.btn--solid{background:var(--accent);color:#fff}
.btn--solid:hover{background:var(--accent-hi)}
.btn--lg{padding:21px 54px;font-size:18px;letter-spacing:.12em}
.btn--white{background:#fff;color:var(--ink)}
.btn--white:hover{background:var(--paper-2);color:var(--ink)}
.btn--ghost-light{border-color:rgba(255,255,255,.55);color:#fff}
.btn--ghost-light:hover{background:#fff;color:var(--ink);border-color:#fff}
.btn--ink{background:var(--ink);color:#fff}
.btn--ink:hover{background:#fff;color:var(--ink)}

/* ---------- header : solid black bar, FIXED height, never reflows ---------- */
.hdr{
  position:fixed;inset:0 0 auto 0;height:var(--header-h);z-index:100;
  display:flex;align-items:center;gap:clamp(20px,3.4vw,54px);
  padding:0 var(--gutter);
  background:var(--ink);
  border-bottom:1px solid var(--rule-dark);
}

/* nav sits dead centre of the bar: the slot and the buttons each take an equal
   share of the leftover space, so the nav lands in the middle regardless of
   how wide either side happens to be */
.nav{display:flex;align-items:center;gap:clamp(14px,2.1vw,32px);flex:0 0 auto}
.nav a{
  position:relative;color:#fff;font-size:16.5px;font-weight:500;
  letter-spacing:.08em;text-transform:uppercase;padding:6px 0;white-space:nowrap;
}
.nav a::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1.5px;
  background:#fff;transform:scaleX(0);transform-origin:left;
  transition:transform .4s var(--ease);
}
.nav a:hover::after,.nav a[aria-current]::after{transform:scaleX(1)}

.hdr__cta{display:flex;align-items:center;justify-content:flex-end;gap:10px;flex:1 1 0}
.hdr__cta .btn{padding:11px 25px;font-size:13.5px;letter-spacing:.12em}

/* left slot: address cross-fades to the script mark once the hero scrolls away.
   Fixed width, so the nav never moves — the two items just swap opacity. */
.hdr__slot{position:relative;flex:1 1 0;min-width:212px;height:36px}
.hdr__slot>*{
  position:absolute;left:0;top:50%;transform:translateY(-50%);
  transition:opacity .55s var(--ease);
}
.hdr__meta{
  opacity:1;white-space:nowrap;color:#fff;
  text-decoration:underline;text-decoration-color:rgba(255,255,255,.4);
  text-underline-offset:5px;
  transition:opacity .55s var(--ease),text-decoration-color .3s var(--ease);
  /* tracking is tuned so this runs to roughly the same width as the logo
     that replaces it, so the swap happens in place rather than jumping */
  font-size:17.5px;letter-spacing:.13em;text-transform:uppercase;
  left:4px;   /* sits just inside the logo's left edge */
}
/* it's a link to the Google Maps listing — underline firms up on hover */
.hdr__meta:hover{text-decoration-color:#fff}
/* the city only fits alongside a centred six-item nav on very wide screens */
/* the city only fits alongside a centred seven-item nav on very wide screens */
@media(max-width:1820px){.hdr__meta-city{display:none}}
.hdr__logo{opacity:0;pointer-events:none;display:block;width:auto;height:34px}
.hdr__logo img{width:auto;height:100%;object-fit:contain;object-position:left center}
/* pointer-events off once faded, or the invisible link still catches clicks */
.hdr.is-scrolled .hdr__meta{opacity:0;pointer-events:none}
.hdr.is-scrolled .hdr__logo{opacity:1;pointer-events:auto}

/* interior pages have a short hero, so show the mark immediately */
.hdr--solid .hdr__meta{opacity:0;pointer-events:none}
.hdr--solid .hdr__logo{opacity:1;pointer-events:auto}

.burger{display:none;background:none;border:0;padding:10px;cursor:pointer;flex:none}
.burger i{display:block;width:22px;height:1.5px;background:#fff;margin:5px 0;transition:transform .4s var(--ease),opacity .3s var(--ease)}
.burger[aria-expanded="true"] i:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
.burger[aria-expanded="true"] i:nth-child(2){opacity:0}
.burger[aria-expanded="true"] i:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

/* collapse earlier again now the nav carries seven items, not six */
@media(max-width:1400px){
  .nav{display:none}
  .hdr__cta{margin-left:auto}
  .hdr__cta .btn--ghost-light{display:none}
  .burger{display:block}
  .hdr{gap:14px}
  /* no hero to scroll past on a phone before the bar matters — show the mark always */
  .hdr__slot{flex:0 0 auto;min-width:0;width:auto;height:30px}
  .hdr__meta{display:none}
  .hdr__logo{opacity:1;pointer-events:auto;height:30px;position:static;transform:none}
}

/* mobile menu */
.mnav{
  position:fixed;inset:0;z-index:99;background:var(--ink);
  padding:calc(var(--header-h) + 26px) var(--gutter) 44px;
  display:none;flex-direction:column;overflow-y:auto;
}
.mnav.open{display:flex}
.mnav a{
  color:#fff;font-family:var(--display);font-weight:600;text-transform:uppercase;
  font-size:clamp(25px,7.5vw,42px);letter-spacing:-.025em;
  padding:17px 0;border-bottom:1px solid var(--rule-dark);
  transition:color .3s var(--ease);
}
.mnav a:hover{color:var(--accent-hi)}
.mnav__meta{
  margin-top:auto;padding-top:34px;color:rgba(255,255,255,.6);
  font-size:12px;letter-spacing:.14em;text-transform:uppercase;line-height:2;
}
body.nav-open{overflow:hidden}

/* ---------- hero ---------- */
.hero{
  position:relative;overflow:hidden;
  height:calc(100vh - var(--header-h));
  height:calc(100svh - var(--header-h));
  min-height:560px;
}
.hero__media{position:absolute;inset:0}
/* linear, not eased — an ease front-loads the movement, which is what made
   the drift feel quick even over a long duration */
.hero__media img{transform:scale(1.07);animation:heroDrift 24s linear forwards}
@keyframes heroDrift{to{transform:scale(1)}}

/* scrim ONLY where the type sits — photo stays rich top-right */
.hero__scrim{
  position:absolute;inset:0;
  background:
    linear-gradient(100deg,rgba(6,6,6,.80) 0%,rgba(6,6,6,.58) 28%,rgba(6,6,6,.16) 55%,rgba(6,6,6,0) 76%),
    linear-gradient(to top,rgba(6,6,6,.68) 0%,rgba(6,6,6,.12) 34%,rgba(6,6,6,0) 58%);
}

.hero__inner{
  position:relative;height:100%;display:flex;flex-direction:column;
  justify-content:flex-end;padding:0 var(--gutter) clamp(46px,7vh,86px);
  color:#fff;
}
/* script wordmark, the lead element of the home hero */
.hero__mark{
  display:block;width:auto;flex:none;
  height:clamp(38px,4.6vw,58px);
  margin-bottom:clamp(18px,2.6vw,32px);
}
.hero__mark img{
  width:auto;height:100%;object-fit:contain;object-position:left bottom;
  filter:drop-shadow(0 2px 20px rgba(0,0,0,.5));
}
.hero h1{
  /* wide enough that the second sentence holds one line — the <br> in the
     markup is what decides where it breaks, not the container running out */
  font-size:clamp(28px,4.6vw,73px);max-width:24ch;
  text-shadow:0 2px 40px rgba(0,0,0,.34);
}
.hero__sub{
  max-width:55ch;margin-top:26px;font-size:clamp(18px,1.45vw,22px);
  font-weight:300;line-height:1.55;color:rgba(255,255,255,.92);
}
.hero__acts{display:flex;flex-wrap:wrap;align-items:center;gap:14px 30px;margin-top:40px}
.hero__foot{
  display:flex;flex-wrap:wrap;gap:8px 34px;align-items:center;
  justify-content:center;   /* mirrors the centred nav in the bar above */
  /* a deep gap here is what lifts the wordmark, headline and button up the
     frame — the strip stays pinned to the bottom, the content rides higher */
  margin-top:clamp(60px,15vh,160px);padding-top:22px;
  border-top:1px solid rgba(255,255,255,.22);
  color:rgba(255,255,255,.75);font-size:15px;letter-spacing:.12em;text-transform:uppercase;
}
.hero__foot b{font-weight:600;color:#fff}
/* keeps the white, adds a faint underline so it reads as a link */
.hero__foot-link{
  color:#fff;text-decoration:underline;
  text-decoration-color:rgba(255,255,255,.4);text-underline-offset:4px;
  transition:text-decoration-color .3s var(--ease);
}
.hero__foot-link:hover{text-decoration-color:#fff}

/* subtle scroll cue, bottom-right of the hero */
.hero__scroll{
  position:absolute;right:0;bottom:clamp(38px,6vh,76px);z-index:3;
  color:rgba(255,255,255,.55);
  transition:color .4s var(--ease);
  animation:scrollBob 2.8s ease-in-out infinite;
}
.hero__scroll:hover{color:#fff}
.hero__scroll svg{display:block;width:15px;height:auto}
@keyframes scrollBob{
  0%,100%{transform:translateY(0)}
  50%{transform:translateY(7px)}
}
/* a scroll hint is pointless on touch, and it would crowd the wrapped strip */
@media(max-width:1000px){.hero__scroll{display:none}}

/* ---------- interior page hero : shorter, no full-viewport takeover ---------- */
.hero--page{
  height:auto;min-height:0;
  aspect-ratio:auto;
}
/* min-height, not height — so a longer intro paragraph makes the hero taller
   instead of getting clipped on a short window */
.hero--page{height:auto;min-height:clamp(400px,62vh,600px)}
.hero--page .hero__inner{
  height:auto;min-height:clamp(400px,62vh,600px);
  padding-top:clamp(44px,6vh,80px);
}
/* same size as the home hero — only the max-width differs, because interior
   headlines run longer and need the room for their own <br> breaks to hold */
.hero--page h1{font-size:clamp(28px,4.6vw,73px);max-width:30ch}
.hero--page .hero__eyebrow{color:rgba(255,255,255,.8);margin-bottom:22px}
.hero--page .hero__sub{max-width:54ch;margin-top:22px}
.hero--page .hero__acts{margin-top:32px}
/* lifts the hero copy off the bottom edge instead of bottom-anchoring it */
.hero--text-high .hero__inner{justify-content:center}
/* sits the copy near the top of the frame, clear of the subject below */
.hero--text-top .hero__inner{
  justify-content:flex-start;
  padding-top:clamp(48px,8vh,104px);
}

/* ---------- generic section ---------- */
.sec{padding:clamp(42px,5.1vw,74px) var(--gutter)}
/* where two sections stack, the seam doesn't need both full paddings —
   this is what kills the dead band between a section end and the next heading */
.sec + .sec{padding-top:clamp(28px,3.1vw,46px)}
.sec--paper2{background:var(--paper-2)}
.sec--tight{padding-top:clamp(34px,3.9vw,58px)}
/* for sections ending in a short element, where full bottom padding reads heavy */
.sec--tight-b{padding-bottom:clamp(30px,3.3vw,50px)}
.lede{max-width:1180px}
.lede__label{display:flex;align-items:center;gap:16px;color:var(--accent);margin-bottom:30px}
.lede__label::after{content:"";flex:1;max-width:120px;height:1px;background:currentColor;opacity:.4}
.lede h2{font-size:clamp(30px,4.3vw,64px);max-width:20ch}
/* for a heading whose own line breaks should decide the shape, rather than
   the 20ch measure breaking it somewhere else first */
.lede h2.h2--wide,
.band h2.h2--wide{max-width:34ch}
/* steps the type down just enough for a long line to hold inside a narrow
   split column, instead of breaking to a third line */
.lede h2.h2--fit{font-size:clamp(28px,3.6vw,53px);max-width:34ch}
.lede__body{
  max-width:60ch;margin-top:30px;font-size:clamp(18px,1.45vw,22px);
  font-weight:300;line-height:1.62;color:#39352F;
}
/* inline links inside body copy read as links: underlined, accent on hover.
   :not(.rule-link) keeps the arrow links below a lede styled as buttons. */
.lede__body a:not(.rule-link){
  color:inherit;
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-underline-offset:3px;
  text-decoration-color:rgba(57,53,47,.42);
  transition:color .25s var(--ease),text-decoration-color .25s var(--ease);
}
.lede__body a:not(.rule-link):hover{
  color:var(--accent);
  text-decoration-color:var(--accent);
}
.lede .rule-link{margin-top:38px;color:var(--ink)}
.lede .rule-link:hover{color:var(--accent)}

/* ---------- divider rule ----------
   A plain horizontal line between blocks. Sits full width of the section's
   content area. --dark for use on the ink band or footer. ------------------ */
.rule{
  border:0;height:1px;background:var(--rule);
  margin:clamp(46px,5.4vw,82px) 0;
}
.rule--dark{background:var(--rule-dark)}
/* pulls the line tight under whatever it follows */
.rule--tight{margin:clamp(26px,3vw,42px) 0}

/* ---------- pull quote ---------- */
.pullq{
  margin:clamp(28px,3.4vw,46px) 0 0;
  padding-left:clamp(20px,2.4vw,34px);
  border-left:2px solid var(--accent);
  max-width:60ch;
}
.pullq p{
  font-family:var(--display);font-weight:500;
  font-size:clamp(19px,1.85vw,27px);line-height:1.3;
  letter-spacing:-.015em;color:var(--ink);
}
.pullq cite{
  display:block;margin-top:16px;font-family:var(--body);
  font-size:13px;font-style:normal;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:#6B655D;
}
.pullq cite a{text-decoration:underline;text-decoration-color:var(--rule);text-underline-offset:3px}
.pullq cite a:hover{color:var(--accent);text-decoration-color:var(--accent)}

/* ---------- module grid (Equinox 3-up pattern) ---------- */
.grid{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(16px,2.1vw,34px);margin-top:clamp(36px,4.7vw,66px);
}
@media(max-width:1000px){.grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){.grid{grid-template-columns:1fr}}

.card{display:block;background:transparent}
.card__media{position:relative;aspect-ratio:3/2;overflow:hidden;background:#DCD6CE}
.card__media img{transition:transform 1.1s var(--ease),filter .6s var(--ease)}
.card:hover .card__media img{transform:scale(1.045)}
.card__tint{
  position:absolute;inset:0;
  background:linear-gradient(to top,rgba(8,8,8,.55),rgba(8,8,8,.05) 52%,rgba(8,8,8,0));
  transition:opacity .6s var(--ease);
}
.card:hover .card__tint{opacity:.72}
.card__body{padding:24px 2px 0}
.card h3{font-size:clamp(18px,1.5vw,23px)}
.card__desc{margin-top:12px;font-size:18px;font-weight:300;line-height:1.6;color:#443F39;max-width:34ch}
/* the card's call to action — sized up so it reads as the thing to click,
   not as a caption under the description */
.card .rule-link{
  margin-top:22px;font-size:14px;letter-spacing:.14em;
  padding-bottom:9px;border-bottom-width:2px;border-bottom-color:var(--ink);
}
.card:hover .rule-link{color:var(--accent);border-bottom-color:var(--accent)}

/* ---------- pricing tiers (coworking, leasing) ---------- */
.tiers{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(16px,2vw,30px);margin-top:clamp(28px,3.2vw,48px);
}
@media(max-width:1100px){.tiers{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.tiers{grid-template-columns:1fr}}

.tier{display:flex;flex-direction:column;background:#fff;border:1px solid var(--rule)}
.tier__media{position:relative;aspect-ratio:3/2;overflow:hidden;background:#DCD6CE}
.tier__media img{transition:transform 1.1s var(--ease)}
.tier:hover .tier__media img{transform:scale(1.04)}
.tier__body{padding:22px 22px 24px;display:flex;flex-direction:column;flex:1}
.tier h3{font-size:clamp(17px,1.4vw,21px)}
.tier__price{
  margin-top:12px;font-family:var(--display);font-size:14.5px;font-weight:600;
  letter-spacing:.05em;text-transform:uppercase;color:var(--accent);
}
.tier__desc{margin-top:16px;font-size:18px;font-weight:300;color:#443F39;line-height:1.62}
.tier__cta{margin-top:auto;padding-top:26px}
.tier__cta .rule-link{font-size:11.5px;border-bottom-color:var(--rule)}
.tier:hover .tier__cta .rule-link{color:var(--accent);border-bottom-color:var(--accent)}

/* ---------- amenities : text-only hairline grid ---------- */
.amen{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:1px;background:var(--rule);
  margin-top:clamp(28px,3.2vw,48px);
  border:1px solid var(--rule);
}
@media(max-width:1100px){.amen{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.amen{grid-template-columns:1fr}}

/* white cards that invert to solid black on hover */
.amen__item{
  position:relative;overflow:hidden;
  background:#fff;padding:clamp(20px,1.9vw,28px);
  transition:background .4s var(--ease);
}

/* --- optional photo reveal: add class .amen__item--photo and an <img> --------
   The photo sits over the black and under the text, at partial opacity, so the
   copy stays readable no matter how bright the picture is. ------------------- */
.amen__item h3,
.amen__item p{position:relative;z-index:2}
.amen__item img{
  position:absolute;inset:0;z-index:1;opacity:0;transform:scale(1.07);
  transition:opacity .5s var(--ease),transform 1.3s var(--ease);
}
/* On hover (or press, on touch) the paragraph clears out and the photo comes
   up to near-full strength. The heading stays so the card is still labelled. */
.amen__item--photo:hover img,
.amen__item--photo:active img{opacity:.94;transform:scale(1)}
.amen__item--photo:hover p,
.amen__item--photo:active p{opacity:0}
/* On a phone the card photo is switched off entirely, so cards look the same
   as an un-hovered card on desktop: white, dark text, always readable.

   Earlier this dimmed the photo behind white type instead. Two problems with
   that. Nothing triggers it reliably — (hover:none) alone is no good, since
   Chrome's device toolbar often still reports hover:hover and a touchscreen
   laptop reports both — and even when it did fire, the card went dark on a
   phone and white on desktop, which read as two different designs.

   The photo reveal stays a desktop hover treat. There is no hover on a phone,
   so nothing is actually lost. */
@media (hover:none), (max-width:760px){
  .amen__item--photo img{display:none}
  /* Cards are completely static here — no invert, no photo, paragraph always
     visible. The invert is keyed to :hover and :active, and :active fires on
     touch: on iOS it can stay latched after a tap, leaving a card stuck black
     while you scroll past it. Nothing to reveal on a phone anyway. */
  .amen__item:hover,
  .amen__item:active{background:#fff}
  .amen__item:hover h3,
  .amen__item:active h3{color:var(--ink)}
  .amen__item:hover p,
  .amen__item:active p{color:#443F39;opacity:1}
  .amen__item:hover a,
  .amen__item:active a{color:inherit;text-decoration-color:var(--rule)}

  /* Tapped open. site.js toggles .is-open, which does what hover does on a
     desktop. Must come after the :hover/:active resets above — same
     specificity, so source order decides. */
  .amen__item.is-open{background:var(--ink)}
  .amen__item.is-open h3{color:#fff}
  .amen__item.is-open p{color:rgba(255,255,255,.82)}
  .amen__item--photo.is-open img{display:block;opacity:.94;transform:scale(1)}
  .amen__item--photo.is-open p{opacity:0}
  .amen__item--photo{cursor:pointer}
}
.amen__item h3{
  font-size:16px;letter-spacing:.06em;color:var(--ink);
  transition:color .4s var(--ease);
}
.amen__item p{
  margin-top:14px;font-size:18px;font-weight:300;line-height:1.66;
  color:#443F39;transition:color .4s var(--ease),opacity .4s var(--ease);
}
.amen__item a{
  color:inherit;text-decoration:underline;
  text-decoration-color:var(--rule);text-underline-offset:3px;
  transition:color .3s var(--ease),text-decoration-color .3s var(--ease);
}
.amen__item:hover{background:var(--ink)}
.amen__item:hover h3{color:#fff}
.amen__item:hover p{color:rgba(255,255,255,.78)}
.amen__item:hover a{color:#fff;text-decoration-color:rgba(255,255,255,.5)}

/* --- amenity cards on a phone ------------------------------------------
   Eight cards stacked one per row is a very long scroll. Same treatment as
   the chips: one row that swipes sideways, bled to both screen edges so a
   card is visibly cut off at the right and it reads as scrollable.

   The 1px-gap hairline grid can't survive as a flex row, so each card takes
   its own border and a real gap instead. Must come after the grid rules
   above to win on `display`. --------------------------------------------- */
@media(max-width:760px){
  .amen{
    display:flex;flex-wrap:nowrap;
    overflow-x:auto;
    scroll-snap-type:x proximity;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    gap:10px;
    background:transparent;
    border:0;
    margin-left:calc(-1 * var(--gutter));
    margin-right:calc(-1 * var(--gutter));
    padding:0 var(--gutter);
  }
  .amen::-webkit-scrollbar{display:none}
  .amen__item{
    flex:0 0 76%;
    scroll-snap-align:start;
    border:1px solid var(--rule);
  }
}

/* ---------- gallery grid (filming, gallery) ---------- */
.gal{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(10px,1.4vw,20px);margin-top:clamp(28px,3.2vw,48px);
}
@media(max-width:1000px){.gal{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.gal{grid-template-columns:1fr}}
/* landscape rather than square: a third less height, and it suits the content —
   these are rooms and sets, which a square crop was cutting into */
.gal figure{margin:0;position:relative;overflow:hidden;aspect-ratio:3/2;background:#DCD6CE}
.gal img{transition:transform 1.1s var(--ease)}
.gal figure:hover img{transform:scale(1.05)}
.gal figcaption{
  position:absolute;left:0;right:0;bottom:0;padding:16px 18px;
  background:linear-gradient(to top,rgba(8,8,8,.85),rgba(8,8,8,0));
  color:#fff;font-size:13.5px;font-weight:300;line-height:1.45;
  opacity:0;transform:translateY(8px);
  transition:opacity .45s var(--ease),transform .45s var(--ease);
}
.gal figure:hover figcaption{opacity:1;transform:none}
/* touch devices have no hover, so the credits would never appear at all —
   show them permanently wherever hovering isn't possible */
@media(hover:none){
  .gal figcaption{opacity:1;transform:none}
}

/* ---------- split : text left, image right, image height == text height ----------
   The media column stretches to whatever the text column needs, so the picture
   fills the gap beside the copy instead of adding height below it. */
.split{
  display:grid;grid-template-columns:1.05fr 1fr;
  gap:clamp(30px,4.5vw,70px);align-items:stretch;
}
.split .lede{max-width:none}
.split__media{position:relative;overflow:hidden;background:#DCD6CE;min-height:260px}
/* faded vintage variant — mostly desaturated, warm cast, lifted blacks,
   and slightly transparent so it settles into the paper rather than sitting on it */
/* nudges the image past the frame to clip the white paper edge on a scan */
.split__media--trim img{transform:scale(1.05)}
.split__media--trim:hover img{transform:scale(1.08)}
/* stops a photo stretching to match a tall column of copy beside it */
.split__media--cap{align-self:center;min-height:0;aspect-ratio:16/9}
.split__media--bw{background:var(--paper-2)}
.split__media--bw img{
  filter:grayscale(1) sepia(.1) contrast(.9) brightness(1.06);
  opacity:.9;object-position:center 64%;
}
.split__media img{position:absolute;inset:0;transition:transform 1.2s var(--ease)}
.split__media:hover img{transform:scale(1.03)}
/* wider media column, for when the picture is the point */
.split--media-lg{grid-template-columns:1fr 1.4fr}

/* historic plan filling the whole right-hand column, shown complete rather
   than cropped, sitting on the section's own paper colour */
.split__map{position:relative;align-self:stretch;min-height:340px;overflow:hidden}
.split__map img{
  position:absolute;inset:0;
  object-fit:cover;object-position:center;
}
/* shift the visible crop down the source, to stop the lower part being cut off */
.split__map--low img{object-position:center 72%}
/* fills its whole side of the section — taller, and bleeding to the right edge */
.split__map--full{min-height:clamp(420px,52vh,660px);margin-right:calc(-1 * var(--gutter))}
/* stops a map or photo stretching to match a tall column of copy. Must be an
   aspect-ratio, not a max-height: the img inside is absolutely positioned, so
   it gives the box no height of its own and a capped box collapses to zero. */
.split__map--cap{align-self:center;min-height:0;aspect-ratio:16/9}
@media(max-width:900px){
  .split__map--full{min-height:0;margin-right:0}
}

/* two images side by side, so neither has to run tall */
.split__pair{
  display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(10px,1.2vw,18px);
  align-self:center;
}
.split__pair figure{
  position:relative;overflow:hidden;margin:0;background:#DCD6CE;
  aspect-ratio:4/3;
}
.split__pair img{position:absolute;inset:0;transition:transform 1.2s var(--ease)}
.split__pair figure:hover img{transform:scale(1.03)}
/* standing on its own in a section rather than as a split's media column */
.sec > .split__pair{margin-top:clamp(28px,3.2vw,48px)}
/* stacked variant: two wide strips, one above the other */
.split__pair--stack{grid-template-columns:1fr}
.split__pair--stack figure{aspect-ratio:5/2}
/* a map or document: shown whole rather than cropped, on white */
.split__pair-item--doc{background:#fff;border:1px solid var(--rule)}
.split__pair-item--doc img{object-fit:contain;padding:10px}
.split__pair-item--doc:hover img{transform:none}
/* a wordmark or logo: shown whole on ink, with room around it */
.split__pair-item--mark{background:var(--ink)}
.split__pair-item--mark img{object-fit:contain;padding:16%}
.split__pair-item--mark:hover img{transform:none}
/* a panorama shown whole: full width of its column, natural height, no crop */
.split__pano{align-self:center;margin:0;overflow:hidden;background:#DCD6CE}
.split__pano img{height:auto;object-fit:fill;transition:transform 1.2s var(--ease)}
.split__pano:hover img{transform:scale(1.02)}
/* a column of media: a wide strip above a pair, all sharing one gap */
.split__col{display:grid;gap:clamp(10px,1.2vw,18px);align-self:center}
.split__col .split__pair{align-self:auto}
/* archival credit, laid over the foot of a strip */
.split__pair figcaption{
  position:absolute;left:0;right:0;bottom:0;
  padding:22px 16px 11px;
  font-size:12px;letter-spacing:.055em;line-height:1.35;color:rgba(255,255,255,.92);
  background:linear-gradient(to top,rgba(0,0,0,.62),rgba(0,0,0,0));
}

@media(max-width:900px){
  .split{grid-template-columns:1fr;gap:30px}
  .split--media-lg{grid-template-columns:1fr}
  .split__media{aspect-ratio:3/2;min-height:0}
  .split__map{min-height:0;aspect-ratio:4/3}
  .split__pair{grid-template-columns:1fr;align-self:stretch}
  .split__pair figure{aspect-ratio:16/10}
}

/* ---------- chips : short labelled lists (looks, options) ---------- */
.chips{display:flex;flex-wrap:wrap;gap:9px;margin-top:clamp(20px,2.4vw,32px)}
.chips span,
.chips button{
  border:1px solid var(--rule);background:#fff;padding:15px 20px;
  font-family:var(--body);font-size:13.5px;font-weight:500;letter-spacing:.095em;
  text-transform:uppercase;color:#3A3733;white-space:nowrap;cursor:default;
  transition:background .4s var(--ease),color .4s var(--ease),border-color .4s var(--ease);
}
.chips button{cursor:pointer}
/* same invert-on-hover as the amenity cards; .is-on marks the chip whose
   photo is currently showing in the stage */
.chips span:hover,
.chips button:hover,
.chips button:focus-visible,
.chips button.is-on{background:var(--ink);color:#fff;border-color:var(--ink)}

/* --- chips on a phone -------------------------------------------------
   Wrapping turns a long chip list into a tower of full-width blocks, because
   each label is nowrap and the padding is generous. Instead: one row that
   scrolls sideways, the way search filter pills do.

   The negative margins bleed the row to both screen edges and the matching
   padding keeps the first chip aligned to the gutter. That's what makes it
   read as scrollable — a chip is visibly cut off at the right, rather than
   the row just stopping neatly at the margin. -------------------------- */
@media(max-width:760px){
  .chips{
    flex-wrap:nowrap;
    overflow-x:auto;
    scroll-snap-type:x proximity;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    margin-left:calc(-1 * var(--gutter));
    margin-right:calc(-1 * var(--gutter));
    padding:2px var(--gutter);
    /* stops the focus ring on a tabbed chip getting clipped by overflow */
    scroll-padding-inline:var(--gutter);
  }
  .chips::-webkit-scrollbar{display:none}
  .chips span,
  .chips button{
    flex:0 0 auto;
    scroll-snap-align:start;
    padding:12px 15px;
    font-size:12.5px;
    letter-spacing:.08em;
  }
}

/* ---------- looks stage : one frame, many photos, chips swap them ---------- */
.looks__stage{
  position:relative;align-self:stretch;overflow:hidden;
  background:#DCD6CE;min-height:300px;
}
.looks__stage img{
  position:absolute;inset:0;opacity:0;
  transition:opacity .55s var(--ease);
}
.looks__stage img.is-on{opacity:1}
/* a caption tied to one frame — fades in and out with its photo, and sits
   inside the frame so it works the same on a phone as on a desktop */
.stage__cap{
  position:absolute;left:0;right:0;bottom:0;z-index:2;margin:0;
  padding:44px 22px 18px;
  font-size:16px;line-height:1.5;color:rgba(255,255,255,.95);
  background:linear-gradient(to top,rgba(0,0,0,.74),rgba(0,0,0,0));
  opacity:0;transition:opacity .55s var(--ease);pointer-events:none;
}
.stage__cap.is-on{opacity:1}
/* caps a stage sitting beside a long column of copy — without this the frame
   stretches to match the text and ends up dominating the section */
.looks__stage--cap{align-self:center;aspect-ratio:3/2;min-height:0}
/* shorter again, for a section with a short column of copy beside it */
.looks__stage--short{align-self:center;aspect-ratio:16/9;min-height:0}
/* a wide band: a touch taller than stretching to a two-line lede would give */
.looks__stage--band{align-self:center;aspect-ratio:9/4;min-height:0}
/* a scanned frame: nudged past its edges to clip the white paper border */
.looks__stage img.is-scan{transform:scale(1.05)}
/* a logo rather than a photo: shown whole, on white, with room around it */
.looks__stage img.is-mark{object-fit:contain;padding:9%;background:#fff}
/* a tall portrait in a wide frame: hold the top of the shot, not the middle */
.looks__stage img.is-top{object-position:center top}
@media(max-width:900px){.looks__stage{aspect-ratio:3/2;min-height:0}}

/* ---------- dark statement band ---------- */
.band{position:relative;background:var(--ink);color:#fff;overflow:hidden}
.band__media{position:absolute;inset:0;opacity:.3}
.band__media img{filter:grayscale(.5)}
.band__inner{
  position:relative;padding:clamp(52px,7.2vw,104px) var(--gutter);
  max-width:1180px;
}
.band .eyebrow{color:rgba(255,255,255,.6)}
.band h2{font-size:clamp(30px,4.8vw,74px);max-width:19ch;margin-top:28px}
.band__sub{
  max-width:52ch;margin-top:28px;font-size:clamp(18px,1.45vw,22px);
  font-weight:300;line-height:1.6;color:rgba(255,255,255,.84);
}
/* inline links on the ink band: underlined in white rather than accent, which
   would go nearly black against this background */
.band__sub a{
  color:#fff;
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-underline-offset:3px;
  text-decoration-color:rgba(255,255,255,.45);
  transition:text-decoration-color .25s var(--ease);
}
.band__sub a:hover{text-decoration-color:#fff}
/* for short one-sentence versions that should hold a single line on desktop */
.band__sub--wide{max-width:84ch}

/* --- band with something beside the copy ---------------------------------
   The right column is auto-width so the artwork sets its own size and the
   copy takes the rest. Stacks below 900px. Unused at the moment — the
   coworking flyers came out again. -------------------------------------- */
.band__split{
  display:grid;grid-template-columns:1fr auto;
  gap:clamp(30px,4.5vw,80px);align-items:center;
}
@media(max-width:900px){.band__split{grid-template-columns:1fr}}
.band__acts{display:flex;flex-wrap:wrap;gap:14px 18px;margin-top:44px}
/* a second row of actions sits tight under the first */
.band__acts + .band__acts{margin-top:16px}

/* ---------- stats strip ---------- */
.stats{
  display:grid;grid-template-columns:repeat(4,1fr);
  border-top:1px solid var(--rule);
}
@media(max-width:820px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat{padding:clamp(27px,3.4vw,47px) clamp(18px,2.4vw,40px);border-right:1px solid var(--rule)}
.stat:last-child{border-right:0}
@media(max-width:820px){
  .stat:nth-child(2n){border-right:0}
  .stat:nth-child(-n+2){border-bottom:1px solid var(--rule)}
}
.stat__k{font-family:var(--display);font-size:clamp(28px,3.4vw,50px);font-weight:600;letter-spacing:-.03em;line-height:1}
.stat__l{margin-top:14px;font-size:12px;font-weight:500;letter-spacing:.15em;text-transform:uppercase;color:#6B655D}

/* ---------- footer ---------- */
.ftr{background:var(--ink);color:rgba(255,255,255,.68);padding:clamp(50px,6.3vw,86px) var(--gutter) 40px}
.ftr__top{
  display:grid;grid-template-columns:1.4fr 1fr 1fr;
  gap:clamp(30px,4vw,64px);padding-bottom:60px;border-bottom:1px solid var(--rule-dark);
}
@media(max-width:900px){.ftr__top{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.ftr__top{grid-template-columns:1fr}}
.ftr__mark{height:44px;width:auto;margin-bottom:26px}
.ftr__mark img{width:auto;height:100%;object-fit:contain}
.ftr__addr{font-size:17.5px;font-weight:300;line-height:1.75}
.ftr__addr a:hover{color:#fff}
.ftr h4{font-size:12px;letter-spacing:.18em;color:#fff;margin-bottom:20px}
.ftr ul{list-style:none;margin:0;padding:0;display:grid;gap:13px}
.ftr ul a{font-size:17px;font-weight:300;transition:color .3s var(--ease)}
.ftr ul a:hover{color:#fff}
.ftr__bot{
  display:flex;flex-wrap:wrap;justify-content:space-between;gap:18px;
  padding-top:30px;font-size:12px;letter-spacing:.08em;
}
.ftr__social{display:flex;gap:22px}
.ftr__social a{text-transform:uppercase;letter-spacing:.16em;font-size:11.5px;font-weight:500}
.ftr__social a:hover{color:#fff}

/* ---------- reveal on scroll ----------
   Content is VISIBLE by default. It only gets hidden once the inline head
   script has confirmed JS is alive by adding .js-reveal to <html>, and that
   marker is stripped again if site.js never checks in. So a blocked or slow
   script costs you the animation, never the content. */
.js-reveal .rv{
  opacity:0;transform:translateY(26px);
  transition:opacity .95s var(--ease),transform .95s var(--ease);
}
.js-reveal .rv.in{opacity:1;transform:none}
/* .rv--slow : arrives late and gently, so it doesn't compete with the heading
   next to it. Never revealed at page load — always waits to be scrolled to. */
.js-reveal .rv--slow{
  transform:translateY(14px);
  transition-duration:2.1s;
}
@media(prefers-reduced-motion:reduce){
  .js-reveal .rv{opacity:1;transform:none;transition:none}
  .hero__media img{animation:none;transform:none}
  .hero__scroll{animation:none}
  html{scroll-behavior:auto}
}

/* ---------- Instagram glyph ---------- */
/* drawn rather than shipped as an image: it scales, it inherits the footer's
   colour, and it costs no request */
.ftr__ig{
  width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.6;
  opacity:.72;transition:opacity .3s var(--ease);
}
.ftr__ig .ftr__ig-dot{fill:currentColor;stroke:none}
.ftr__social a:hover .ftr__ig{opacity:1}


/* sits between the Inquire button and the burger, so it reads as part of the
   right-hand cluster rather than as another nav item. Drawn, not shipped as an
   image: it scales, takes the header's white, and costs no request. */
/* on a phone the bar is logo + Inquire + burger — keep the glyph, tighten it up */
@media(max-width:1400px){
    }

/* ---------- Instagram glyph in the band action row ---------- */
/* sits beside Inquire and Call, sized to the buttons' cap height so the three
   read as one row. Drawn, not shipped as an image: scales, takes the band's
   white, costs no request. */
.band__ig{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  color:#fff;opacity:.85;transition:opacity .3s var(--ease),transform .3s var(--ease);
}
.band__ig:hover{opacity:1;transform:translateY(-2px)}
.band__ig svg{width:58px;height:58px;fill:none;stroke:currentColor;stroke-width:1.35}
.band__ig .band__ig-dot{fill:currentColor;stroke:none}
@media(max-width:640px){.band__ig svg{width:48px;height:48px}}

/* ---------- research credit ---------- */
/* a byline for the page, not a footer: set small and quiet, above a hairline,
   so it reads as the end of a document rather than site furniture */
.credit{
  max-width:74ch;margin:clamp(34px,4vw,54px) 0 0;
  padding-top:22px;border-top:1px solid var(--rule);
  font-size:14px;line-height:1.6;font-weight:300;color:#6B655D;
}
/* links inside the credit read as links without shouting */
.credit a{text-decoration:underline;text-decoration-color:var(--rule);text-underline-offset:3px;transition:color .3s var(--ease),text-decoration-color .3s var(--ease)}
.credit a:hover{color:var(--accent);text-decoration-color:var(--accent)}
/* a shade shorter than --cap, for a section whose column of copy runs short */
.looks__stage--cap-s{aspect-ratio:5/3}

/* --- chips scroller: make the overflow visible ------------------------
   The row scrolls on a phone, but the scrollbar is hidden, so on a resized
   desktop window there was no cue that anything sat off to the right. A soft
   fade on the trailing edge says "keep going" without adding chrome. The mask
   is only applied while the row actually overflows. -------------------- */
@media(max-width:760px){
  .chips{
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 46px),transparent);
            mask-image:linear-gradient(to right,#000 calc(100% - 46px),transparent);
  }
}

/* --- home hero on a phone ---------------------------------------------
   The desktop hero is a fixed viewport-height box with overflow hidden, and
   the content column is pinned to the bottom. On a narrow screen the stack
   (wordmark, headline, intro, button, info strip) grows taller than the box,
   so the top of the headline was being cut off behind the header.

   min-height instead of height lets the section grow with its content, so
   nothing can ever be clipped. The rest is tightening: a larger headline so
   it reads as a hero rather than body copy, a smaller intro, and the info
   strip left-aligned since centring reads as ragged once it wraps. ------- */
@media(max-width:760px){
  .hero{
    height:auto;
    min-height:calc(100svh - var(--header-h));
  }
  .hero__inner{
    height:auto;
    min-height:calc(100svh - var(--header-h));
    padding-bottom:36px;
  }
  .hero__mark{height:30px;margin-bottom:16px}
  .hero h1{font-size:clamp(31px,8.4vw,44px);max-width:18ch}
  .hero__sub{
    margin-top:16px;max-width:40ch;
    font-size:16px;line-height:1.5;
  }
  .hero__acts{margin-top:24px}
  .hero__acts .btn--lg{padding:17px 34px;font-size:15px;letter-spacing:.1em}
  .hero__foot{
    justify-content:flex-start;
    margin-top:32px;padding-top:16px;
    gap:5px 16px;font-size:12px;letter-spacing:.09em;
  }
  /* the interior pages carry a short hero already — leave those alone */
  .hero--page,.hero--page .hero__inner{min-height:clamp(340px,52vh,480px)}
}
