/* ==========================================================================
   Z NOVI COMMONS — design system
   ========================================================================== */

/* Palette and type are the JMZ portfolio system, shared with the Northville
   Research Center and Rankin sites: Barlow / Barlow Condensed, a neutral
   #111111 ground and the #d32f2f brand red. Novi stays DARK — its photography
   was shot against a dark ground and inverting the site would strand it — so the
   system's neutral ramp runs in reverse here: #111111 is the page, #f2f2f3 the
   type. Only the roles are flipped, never the values. */
:root {
  --ink:        #111111;   /* --color-neutral-900 */
  --ink-2:      #1a1a1b;
  --ink-3:      #232324;
  --line:       rgba(242, 242, 243, .14);
  --line-2:     rgba(242, 242, 243, .24);
  --bone:       #f2f2f3;
  --bone-dim:   rgba(242, 242, 243, .66);
  --bone-faint: rgba(242, 242, 243, .52);  /* .48 is the 4.5:1 floor on #111111 */
  --accent:      #d32f2f;  /* --color-accent-500 — fills, rules, graphics */
  --accent-deep: #b71c1c;  /* --color-accent-600 — pressed / deep bands */
  /* #d32f2f measures 3.79:1 on #111111 — fine for a fill or a 2px rule, short of
     4.5:1 for the 11px tracked labels that carry it. Small red TEXT uses this
     tint instead: accent-400 (#cc5555) opened up two steps to clear 4.5:1
     (5.8:1) on the dark ground. Same hue, same family, legible at label size. */
  --accent-text: #e06a6a;
  --accent-dim:  rgba(211, 47, 47, .18);

  --font-display: 'Barlow Condensed', 'Helvetica Neue', Arial, sans-serif;
  --font-body:    'Barlow', 'Helvetica Neue', Arial, sans-serif;
  /* Tracked uppercase labels. Was JetBrains Mono; Barlow Condensed carries them
     now, which is why the sizes below are larger and the tracking tighter — a
     condensed face sets narrower per character than a monospace one. */
  --font-label:   'Barlow Condensed', 'Helvetica Neue', Arial, sans-serif;

  --pad:      clamp(20px, 5vw, 76px);
  --maxw:     1440px;
  --ease:     cubic-bezier(.22, 1, .36, 1);
  --ease-io:  cubic-bezier(.65, .05, .36, 1);
  --header-h: 58px;   /* Northville's bar is chrome, not a band */
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.62;
  font-weight: 400;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
img, picture, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, h5, h6, p { margin: 0; }
::selection { background: var(--accent); color: var(--ink); }

/* ---------- typography ---------- */
.display {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: .94;
  letter-spacing: -.012em;
  text-transform: uppercase;
  /* backstop: a long word breaks rather than spilling out of its column */
  overflow-wrap: break-word;
}
/* Sizes are capped so the longest word in the copy ("ENTREPRENEURS") still fits
   its column at 1440 without overflowing into the adjacent one. */
.d-xl  { font-size: clamp(2.7rem, 7.4vw, 7.1rem); }
.d-lg  { font-size: clamp(1.8rem, 3vw, 2.5rem); }   /* Northville: 40px */
.d-md  { font-size: clamp(1.55rem, 2.4vw, 2rem); }   /* Northville: 32px */
.d-sm  { font-size: clamp(1.28rem, 2.1vw, 1.72rem); letter-spacing: -.008em; }

.lede { font-size: clamp(1.02rem, 1.42vw, 1.28rem); line-height: 1.58; color: var(--bone-dim); }
.body-lg { font-size: clamp(.98rem, 1.15vw, 1.08rem); color: var(--bone-dim); }
.mono {
  font-family: var(--font-label);
  font-size: .82rem;
  letter-spacing: .105em;
  text-transform: uppercase;
  font-weight: 500;
  font-style: normal;
}
.accent { color: var(--accent-text); }

/* Section kicker — the solid red chip Northville puts above every section
   heading, in place of the hairline-rule-plus-red-text eyebrow this site used.
   Restyled here rather than in the markup so all ten generated pages inherit
   it. The rule that used to lead the label is gone. */
.eyebrow {
  display: inline-flex; align-items: center; width: fit-content;
  background: var(--accent);
  padding: 6px 14px;
  margin-bottom: clamp(14px, 1.6vw, 20px);
}
.eyebrow::before { content: none; }
.eyebrow span {
  font-family: var(--font-display); font-weight: 700;
  font-size: .875rem; letter-spacing: .05em; text-transform: uppercase;
  color: #ffffff;
}

/* ---------- layout ---------- */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--pad); }
.section { padding-block: clamp(34px, 3.4vw, 56px); position: relative; }
.section--tight { padding-block: clamp(28px, 2.8vw, 44px); }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ---------- blueprint frame ----------
   The registration marks from the portfolio design system: a hairline box with a
   surveyor's cross sitting proud of each corner. Northville draws them with four
   <i class="corner"> children, but every page here is generated by
   _build/build.js and the two leasing modules build their own DOM, so this
   version needs no markup at all — one pseudo-element, inset 6px outside the
   box, paints all four crosses as background layers. Add the class, get the
   frame; nothing downstream has to know about it.
   Requires a positioning context, so .blueprint sets one. */
.blueprint { position: relative; border: 1px solid var(--line); border-radius: 0; }
.blueprint::before {
  content: ''; position: absolute; inset: -6px; pointer-events: none; z-index: 2;
  --mark: rgba(242, 242, 243, .5);
  background:
    linear-gradient(var(--mark), var(--mark)) left 5px top 0 / 1px 11px no-repeat,
    linear-gradient(var(--mark), var(--mark)) left 0 top 5px / 11px 1px no-repeat,
    linear-gradient(var(--mark), var(--mark)) right 5px top 0 / 1px 11px no-repeat,
    linear-gradient(var(--mark), var(--mark)) right 0 top 5px / 11px 1px no-repeat,
    linear-gradient(var(--mark), var(--mark)) left 5px bottom 0 / 1px 11px no-repeat,
    linear-gradient(var(--mark), var(--mark)) left 0 bottom 5px / 11px 1px no-repeat,
    linear-gradient(var(--mark), var(--mark)) right 5px bottom 0 / 1px 11px no-repeat,
    linear-gradient(var(--mark), var(--mark)) right 0 bottom 5px / 11px 1px no-repeat;
}
/* Over a light panel (the site plan paints on paper) the grey marks vanish. */
.blueprint--ink::before { --mark: rgba(17, 17, 17, .55); }
/* NOT for anything that clips: the marks are painted 6px outside the box, so an
   overflow:hidden element (every .figure, .feat-media and .rail-item — they clip
   their own hover zoom) crops them off. Frame a wrapper instead. */

/* ---------- grain ---------- */
.grain {
  position: fixed; inset: 0; z-index: 9998; pointer-events: none;
  opacity: .035; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- cursor (desktop only) ---------- */
.cursor {
  position: fixed; top: 0; left: 0; width: 34px; height: 34px;
  border: 1px solid var(--accent); border-radius: 50%;
  transform: translate3d(-100px, -100px, 0);
  pointer-events: none; z-index: 9999; display: none;
  transition: width .3s var(--ease), height .3s var(--ease), background-color .3s var(--ease), border-color .3s var(--ease), opacity .3s;
  will-change: transform;
}
.cursor.is-hot { width: 62px; height: 62px; background: var(--accent-dim); border-color: transparent; }
@media (hover: hover) and (pointer: fine) and (min-width: 1025px) {
  .cursor { display: block; }
}

/* ==========================================================================
   HEADER
   ========================================================================== */
/* A solid black bar in normal flow, like the Northville Research Center and
   Rankin headers — not a transparent film floating over the hero. Sticky rather
   than fixed, which is also what finally retires the --jmz-top-h workaround
   below: the portfolio strip is the first element in <body>, the header follows
   it in flow, and neither can paint over the other. */
.hdr {
  position: sticky; top: 0; z-index: 900;
  height: var(--header-h);
  display: flex; align-items: center;
  background: var(--ink);
  border-bottom: 1px solid transparent;
  transition: border-color .45s var(--ease), box-shadow .45s var(--ease);
}
.hdr.is-stuck { border-bottom-color: var(--line); box-shadow: 0 12px 28px rgba(0, 0, 0, .45); }

/* The JMZ portfolio strip (assets/js/property-switcher.js) is the first element
   in <body>, in normal flow. The header used to be fixed at top:0 and painted
   straight over it — on a phone the logo sat on "NORTHVILLE" and the burger on
   "TROY" — so it was pushed down by a measured --jmz-top-h. Now that the header
   is sticky and in flow, the strip simply scrolls away above it and nothing
   overlaps. site.js still measures the variable; nothing reads it any more. */
:root { --jmz-top-h: 0px; }
.hdr .wrap { display: flex; align-items: center; gap: clamp(16px, 2.4vw, 42px); }

/* The link was only as tall as the artwork (27px on a phone), which is not a
   tap target. The logo keeps its size; the link grows around it. */
.brand { flex: none; display: flex; align-items: center; min-height: 44px; }
.brand img { width: clamp(118px, 10vw, 150px); height: auto; }

.nav { display: flex; align-items: center; gap: clamp(12px, 1.45vw, 24px); margin-left: auto; }
.nav a {
  position: relative;
  font-family: var(--font-display); font-size: 1.02rem; font-weight: 600; letter-spacing: .012em;
  text-transform: uppercase; color: var(--bone); white-space: nowrap;
  padding-block: 6px; transition: color .3s var(--ease);
}
.nav a::after {
  content: ''; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px;
  background: var(--accent); transform: scaleX(0); transform-origin: right;
  transition: transform .45s var(--ease);
}
.nav a:hover { color: var(--accent-text); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); transform-origin: left; }
.nav a[aria-current="page"] { color: var(--bone); }

.hdr-cta { display: flex; align-items: center; gap: 14px; flex: none; }
.hdr-tel {
  font-family: var(--font-display); font-size: 1.02rem; font-weight: 600; letter-spacing: .012em;
  color: var(--bone); transition: color .3s;
}
.hdr-tel:hover { color: var(--accent-text); }

/* buttons */
/* The hover wipe is a background-size transition rather than a ::before overlay,
   so the label never depends on stacking order. */
.btn {
  --bg: var(--accent); --fg: #ffffff; --wipe: var(--bone);
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 46px; padding: 12px 26px;
  color: var(--fg);
  background-color: var(--bg);
  background-image: linear-gradient(var(--wipe), var(--wipe));
  background-repeat: no-repeat; background-position: bottom center; background-size: 100% 0%;
  font-family: var(--font-label); font-size: .82rem; letter-spacing: .085em; text-transform: uppercase; font-weight: 600;
  border: 1px solid var(--bg); border-radius: 0; cursor: pointer;
  transition: color .4s var(--ease), border-color .4s var(--ease), background-size .5s var(--ease);
}
.btn:hover { background-size: 100% 100%; }
.btn--ghost { --bg: transparent; --fg: var(--bone); --wipe: var(--accent); border-color: var(--line-2); }
.btn--ghost:hover { color: #ffffff; border-color: var(--accent); }
.btn--lg { min-height: 58px; padding: 16px 38px; font-size: .72rem; }
.btn--block { width: 100%; }

.btn-arrow { transition: transform .45s var(--ease); }
.btn:hover .btn-arrow { transform: translateX(5px); }

/* burger */
.burger {
  display: none; flex: none; width: 46px; height: 46px;
  background: none; border: 1px solid var(--line-2); cursor: pointer;
  align-items: center; justify-content: center; flex-direction: column; gap: 5px;
  transition: border-color .3s;
}
.burger:hover { border-color: var(--accent); }
.burger i { display: block; width: 17px; height: 1.5px; background: var(--bone); transition: transform .4s var(--ease), opacity .3s; }
.burger.is-open i:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.burger.is-open i:nth-child(2) { opacity: 0; }
.burger.is-open i:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* mobile menu */
.menu {
  position: fixed; inset: 0; z-index: 890;
  background: var(--ink); padding: calc(var(--header-h) + 20px) var(--pad) 40px;
  display: flex; flex-direction: column;
  overflow-y: auto; overscroll-behavior: contain;
  clip-path: inset(0 0 100% 0);
  transition: clip-path .72s var(--ease);
  visibility: hidden;
}
.menu.is-open { clip-path: inset(0 0 0 0); visibility: visible; }
.menu-list { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.menu-list a {
  display: flex; align-items: baseline; gap: 16px;
  padding: clamp(13px, 2.4vw, 20px) 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-display); font-weight: 700;
  text-transform: uppercase; letter-spacing: -.008em;
  font-size: clamp(1.55rem, 6.6vw, 2.5rem); line-height: 1;
  opacity: 0; transform: translateY(22px);
  transition: opacity .5s var(--ease), transform .5s var(--ease), color .3s;
}
.menu.is-open .menu-list a { opacity: 1; transform: none; transition-delay: calc(.16s + var(--i, 0) * .045s); }
.menu-list a:hover, .menu-list a[aria-current="page"] { color: var(--accent); }
.menu-list a em {
  font-family: var(--font-label); font-style: normal; font-size: .76rem;
  letter-spacing: .1em; color: var(--accent-text); flex: none;
}
.menu-foot {
  margin-top: auto; padding-top: 32px;
  display: flex; flex-direction: column; gap: 16px;
  opacity: 0; transition: opacity .5s var(--ease) .42s;
}
.menu.is-open .menu-foot { opacity: 1; }
.menu-foot .mono { color: var(--bone-faint); line-height: 1.9; }
.menu-foot a.mono:hover { color: var(--accent-text); }

@media (max-width: 1120px) {
  .nav, .hdr-tel { display: none; }
  .burger { display: flex; }
  .hdr .wrap { justify-content: space-between; }
  .hdr-cta { margin-left: auto; }
}
@media (max-width: 560px) {
  .hdr-cta .btn { display: none; }
}
body.is-locked { overflow: hidden; }

/* ==========================================================================
   HERO — home
   ========================================================================== */
/* Layering uses explicit positive z-indexes rather than negative ones — negative
   z-index children of an isolated stacking context drop out of the paint in some
   engines/headless configurations. */
.hero {
  position: relative; min-height: calc(100svh - var(--header-h));
  display: flex; flex-direction: column; justify-content: flex-end;
  padding-top: clamp(40px, 6vw, 80px); padding-bottom: 0;
  overflow: hidden;
}
.hero > .wrap { position: relative; z-index: 3; }
.hero-bg { position: absolute; inset: 0; z-index: 1; background: var(--ink); }
.hero-slide {
  position: absolute; inset: 0; opacity: 0;
  transition: opacity 1.5s var(--ease-io);
  will-change: opacity;
}
.hero-slide.is-active { opacity: 1; }
.hero-slide img {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.06);
}
.hero-slide.is-active img { animation: kenburns 9s linear forwards; }
@keyframes kenburns { from { transform: scale(1.045); } to { transform: scale(1.16); } }
/* Kept deliberately light: the building photography is the strongest asset on
   the page, so the scrim only darkens where type actually sits. The left-hand
   wash is the heavier of the two now — the hero carries four stacked lines
   since it took the Northville arrangement, and the lower ones land on bright
   lawn rather than on the sky the old two-line hero sat against. */
.hero-scrim {
  position: absolute; inset: 0; z-index: 2;
  /* Northville's exact wash: bottom only, nothing across the left. The building
     is the strongest asset on the page and a curtain over it is a loss. */
  background: linear-gradient(to top, rgba(17, 17, 17, .75) 0%, rgba(17, 17, 17, .1) 60%, rgba(17, 17, 17, 0) 100%);
}
@media (max-width: 760px) {
  .hero-scrim {
    background: linear-gradient(to top, rgba(17, 17, 17, .88) 0%, rgba(17, 17, 17, .5) 52%, rgba(17, 17, 17, .06) 100%);
  }
}

/* Northville pads its hero 27px on every side rather than using the page's
   wrap gutter, so the copy sits tight to the left edge. */
.hero > .wrap.hero-inner { padding-inline: clamp(20px, 2.4vw, 28px); }
.hero-inner { padding-bottom: clamp(20px, 2.4vw, 28px); }
/* ---- hero: copy on the left, the availability card on the right ----
   The Northville Research Center hero layout. The card is a light plate over
   the photography so it reads as a form and not as more hero furniture; it
   keeps the system's square corners rather than Northville's 12px radius,
   because nothing else on this site is rounded. */
.hero-inner {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: clamp(24px, 4vw, 64px);
}
.hero-copy { min-width: 0; max-width: 46rem; }
.hero-form {
  flex: none; width: 232px;
  display: flex; flex-direction: column; gap: 6px;
  padding: 12px;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  /* the one rounded box on the site, because it is Northville's one rounded box */
  border-radius: 12px;
  box-shadow: 0 24px 48px rgba(0, 0, 0, .35);
  /* clears the JMZ switcher pill, which is fixed to this same corner */
  margin-bottom: 58px;
}
.hero-form-t {
  font-family: var(--font-display); font-weight: 700;
  font-size: .875rem; letter-spacing: .005em;
  color: #111111;
}
/* Sentence case, not tracked caps — the single loudest difference between the
   two heroes at a glance. */
.hero-form label {
  display: flex; flex-direction: column; gap: 2px;
  font-family: var(--font-body); font-size: .688rem; letter-spacing: 0;
  text-transform: none; color: #52525b;
}
.hero-form input, .hero-form textarea {
  width: 100%; min-height: 32px; padding: 6px 8px;
  font-family: var(--font-body); font-size: .75rem; line-height: 1.4;
  color: #111111; background: #ffffff;
  border: 1px solid #d4d4d8; border-radius: var(--radius, 4px);
  transition: border-color .3s var(--ease);
}
.hero-form textarea { min-height: 58px; resize: vertical; }
.hero-form input::placeholder, .hero-form textarea::placeholder { color: #71717a; }
.hero-form input:focus, .hero-form textarea:focus { outline: none; border-color: var(--accent); }
.hero-form-b {
  margin-top: 2px; min-height: 34px; padding: 8px 16px; cursor: pointer;
  background: var(--accent-deep); color: #ffffff; border: 1px solid var(--accent-deep);
  border-radius: var(--radius, 4px);
  font-family: var(--font-body); font-size: .75rem; font-weight: 500;
  letter-spacing: .01em; text-transform: none;
  transition: background-color .3s var(--ease), border-color .3s var(--ease);
}
.hero-form-b:hover { background: var(--accent-deep); border-color: var(--accent-deep); }
/* Below 1000px the hero has no room beside the copy, and the full contact form
   is one scroll away — the same call Northville makes. */
@media (max-width: 1000px) {
  .hero-inner { display: block; }
  .hero-form { display: none; }
}

.hero h1 { max-width: 22ch; }  /* "43000 W. 9 Mile Road" is 20 characters */
/* ---- hero type, sized to match the Northville Research Center hero ----
   Northville sets the headline at 60px, the property/city line at 20px body,
   and the descriptor at 22px condensed bold. Novi's .d-xl ran to 114px at
   1440 — a different scale entirely — so the hero overrides it rather than the
   shared display ramp, which the rest of the site still uses. The clamps keep
   the same proportions down to a phone, where Northville drops to 38px.
   The badge is Northville's 14px condensed 700 at 6px/14px padding. */
.hero h1.d-xl { font-size: clamp(2.4rem, 4.2vw, 3.75rem); line-height: 1.02; }
.hero-name {
  margin-top: var(--space-hero-gap, 13px);
  font-family: var(--font-body); font-size: clamp(1rem, 1.4vw, 1.25rem);
  font-weight: 400; line-height: 1.45;
}
.hero-price {
  margin-top: 8px;
  font-family: var(--font-body); font-size: clamp(.95rem, 1.15vw, 1.06rem);
  color: var(--bone);
  text-shadow: 0 1px 3px rgba(17, 17, 17, .85), 0 2px 20px rgba(17, 17, 17, .9);
}
.hero .hero-sub {
  margin-top: 7px;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.12rem, 1.53vw, 1.375rem); line-height: 1.25;
  letter-spacing: .02em; color: var(--bone);
}
@media (max-width: 760px) {
  .hero h1.d-xl { font-size: 2.375rem; }
  .hero-name { font-size: .875rem; }
  .hero .hero-sub { font-size: 1.05rem; }
}

.hero h1 .ln { display: block; overflow: hidden; }
/* The clip that makes the rise-in work would crop a wrapped headline to its
   first line on a narrow phone, so below 520px the animation gives way. */
@media (max-width: 520px) {
  .hero h1 .ln { overflow: visible; }
  .hero h1 .ln > span { animation: fadeUp .95s var(--ease) backwards; }
}
.hero h1 .ln > span {
  display: block;
  animation: riseIn 1.05s var(--ease) backwards;
  animation-delay: calc(.12s + var(--i, 0) * .11s);
}
@keyframes riseIn { from { transform: translateY(105%); } to { transform: translateY(0); } }

.hero-sub {
  margin-top: clamp(20px, 2.6vw, 32px); max-width: 46ch;
  color: var(--bone);
  text-shadow: 0 1px 3px rgba(17, 17, 17, .8), 0 2px 20px rgba(17, 17, 17, .9);
  animation: fadeUp .95s var(--ease) .48s backwards;
}
/* Over photography the accent red loses to bright glass and sky, so the hero
   eyebrow runs in bone and lets the rule carry the accent. */
/* The scrim is deliberately light so the building reads, so legibility is carried
   by the type itself — a tight shadow for edge contrast plus a wide one for halo. */
.hero .eyebrow span { color: var(--bone); text-shadow: 0 1px 3px rgba(17, 17, 17, .9), 0 2px 18px rgba(17, 17, 17, .95); }
.hero h1 { text-shadow: 0 2px 6px rgba(17, 17, 17, .5), 0 6px 46px rgba(17, 17, 17, .7); }
@keyframes fadeUp { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }

.price-row {
  display: flex; flex-wrap: wrap; gap: 12px;
  margin-top: clamp(24px, 3vw, 36px);
  animation: fadeUp .95s var(--ease) .6s backwards;
}
.price-chip {
  display: flex; align-items: baseline; gap: 10px;
  padding: 11px 20px; border: 1px solid var(--line-2);
  background: rgba(17, 17, 17, .42); backdrop-filter: blur(8px);
}
.price-chip b { font-family: var(--font-display); font-weight: 700; font-size: 1.06rem; letter-spacing: 0; }
.price-chip span { font-family: var(--font-label); font-size: .76rem; letter-spacing: .09em; text-transform: uppercase; color: var(--bone-faint); }

.hero-actions {
  display: flex; flex-wrap: wrap; gap: 12px;
  margin-top: clamp(28px, 3.4vw, 42px);
  animation: fadeUp .95s var(--ease) .72s backwards;
}

.hero-bar {
  border-top: 1px solid var(--line);
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: 20px; padding-block: 18px;
  animation: fadeUp .9s var(--ease) .9s backwards;
}
.hero-bar .mono { color: var(--bone-faint); }
.hero-dots { display: flex; flex-wrap: wrap; gap: 7px; justify-content: center; min-width: 0; }
.hero-dots button {
  width: 22px; height: 2px; padding: 13px 0; border: 0; cursor: pointer;
  background: var(--line-2); background-clip: content-box;
  box-sizing: content-box; transition: background-color .4s var(--ease);
}
.hero-dots button.is-on { background: var(--accent); }
.hero-count { text-align: right; white-space: nowrap; }
.hero-count b { color: var(--accent-text); font-weight: 500; }
@media (max-width: 720px) {
  .hero-bar { grid-template-columns: 1fr auto; gap: 14px; }
  .hero-bar .hero-loc { display: none; }
  .hero-dots { justify-content: flex-start; gap: 5px; row-gap: 0; }
  /* the bar narrows on a phone but the hit box must not — 2.5.5 */
  .hero-dots button { width: 14px; padding: 13px 8px; }
}

/* The vertical SCROLL cue is gone. It was pinned to the right gutter, which is
   exactly where the availability card now sits, and Northville's hero has no
   cue at all. Removed from the markup in _build/build.js too. */

/* ==========================================================================
   PAGE HERO (interior pages)
   ========================================================================== */
.phero {
  position: relative; overflow: hidden;
  padding-top: clamp(70px, 11vw, 148px);
  padding-bottom: clamp(52px, 8vw, 108px);
  border-bottom: 1px solid var(--line);
  background: var(--ink);
}
.phero > .wrap { position: relative; z-index: 3; }
.phero-bg { position: absolute; inset: 0; z-index: 1; }
.phero-bg img { width: 100%; height: 100%; object-fit: cover; }
.phero::after {
  content: ''; position: absolute; inset: 0; z-index: 2;
  background:
    linear-gradient(to top, var(--ink) 1%, rgba(17, 17, 17, .62) 42%, rgba(17, 17, 17, .4) 100%),
    linear-gradient(to right, rgba(17, 17, 17, .74) 0%, rgba(17, 17, 17, .24) 52%, rgba(17, 17, 17, .05) 82%);
}
@media (max-width: 760px) {
  .phero::after {
    background: linear-gradient(to top, var(--ink) 2%, rgba(17, 17, 17, .82) 46%, rgba(17, 17, 17, .58) 100%);
  }
}
.phero h1 { max-width: 17ch; }
.phero .lede { margin-top: clamp(18px, 2.2vw, 26px); max-width: 56ch; }
.crumb { display: flex; align-items: center; gap: 9px; margin-bottom: 20px; color: var(--bone-faint); }
.crumb a { transition: color .3s; }
.crumb a:hover { color: var(--accent-text); }
.crumb i { font-style: normal; color: var(--accent-text); opacity: .8; }

/* ==========================================================================
   REVEALS
   ========================================================================== */
[data-reveal] {
  opacity: 0; transform: translateY(30px);
  transition: opacity .95s var(--ease), transform .95s var(--ease);
  transition-delay: calc(var(--i, 0) * .075s);
}
[data-reveal].is-in { opacity: 1; transform: none; }
[data-reveal="fade"] { transform: none; }
[data-reveal="clip"] { opacity: 1; transform: none; clip-path: inset(0 0 100% 0); transition: clip-path 1.15s var(--ease); }
[data-reveal="clip"].is-in { clip-path: inset(0 0 0 0); }
[data-reveal="left"] { transform: translateX(-34px); }
[data-reveal="right"] { transform: translateX(34px); }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1 !important; transform: none !important; clip-path: none !important; transition: none !important; }
  .hero-slide.is-active img { animation: none; }
  .hero h1 .ln > span, .hero-sub, .price-row, .hero-actions, .hero-bar { animation: none !important; }
  .marquee-track { animation: none !important; }
}

/* ==========================================================================
   INTRO / SPLIT
   ========================================================================== */
.split { display: grid; gap: clamp(30px, 4.4vw, 74px); align-items: start; }
/* A d-lg heading in a 5fr column has ~510px at 1440, and "NOVI COMMONS" needs about
   9.3 font-sizes of width, so cap it rather than let it wrap to four lines.
   (Sized with vw, not container units — .sticky-col lives in here and layout
   containment would break its stickiness.) */
.split .d-lg { font-size: clamp(1.8rem, 3vw, 2.5rem); }

.split--5-7 { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.split--6-6 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.split--7-5 { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
@media (max-width: 900px) { .split--5-7, .split--6-6, .split--7-5 { grid-template-columns: 1fr; } }

.sticky-col { position: sticky; top: calc(var(--header-h) + 34px); }
@media (max-width: 900px) { .sticky-col { position: static; } }

.figure { position: relative; overflow: hidden; background: var(--ink-2); }
.figure img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.figure:hover img { transform: scale(1.045); }
.figure--tall { aspect-ratio: 4 / 5; }
.figure--wide { aspect-ratio: 16 / 10; }
.figure--sq   { aspect-ratio: 1 / 1; }
.figure--band { aspect-ratio: 21 / 8; }
@media (max-width: 760px) { .figure--band { aspect-ratio: 4 / 3; } }

/* Copy flanked by a photo on each side — the arrangement the live site uses under
   "Welcome To Novi Commons". */
.trio {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(24px, 3.4vw, 56px); align-items: center;
}
.trio-media { aspect-ratio: 4 / 5; }
.trio-body {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: clamp(14px, 1.7vw, 20px);
  container-type: inline-size;
}
.trio-body .eyebrow { margin-bottom: 0; }
@supports (width: 1cqw) { .trio-body .d-md { font-size: min(2rem, 10.4cqw); } }
@media (max-width: 1000px) {
  .trio { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .trio-body { grid-column: 1 / -1; order: -1; align-items: center; text-align: center; }
}
@media (max-width: 620px) {
  .trio { grid-template-columns: 1fr; }
  .trio-media { aspect-ratio: 4 / 3; }
}
.figure-tag {
  position: absolute; left: 0; bottom: 0;
  background: var(--ink); color: var(--accent-text);
  padding: 9px 15px; font-family: var(--font-label);
  font-size: .76rem; letter-spacing: .1em; text-transform: uppercase;
}

/* ==========================================================================
   STATS / FACT ROW
   ========================================================================== */
.facts { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--line); }
.fact { padding: clamp(24px, 3vw, 40px) clamp(14px, 2vw, 30px); border-bottom: 1px solid var(--line); border-right: 1px solid var(--line); }
.fact:last-child { border-right: 0; }
.fact b { display: block; font-family: var(--font-display); font-weight: 700; font-size: clamp(1.9rem, 3.6vw, 3.1rem); line-height: 1; letter-spacing: -.015em; }
.fact span { display: block; margin-top: 10px; color: var(--bone-faint); }
@media (max-width: 800px) {
  .facts { grid-template-columns: repeat(2, 1fr); }
  .fact:nth-child(2n) { border-right: 0; }
}


/* ==========================================================================
   HERO BADGE / STAT ROW / HIGHLIGHT CARDS / CTA BAND
   The Northville Research Center homepage arrangement: a "FOR LEASE" plate over
   the photography, a four-up figure row under it, highlight cards with a red
   disc icon and blueprint corners, and a closing call-to-action band.
   ========================================================================== */
.hero-badge {
  display: inline-block; width: fit-content;
  margin-bottom: clamp(14px, 1.8vw, 20px);
  /* Northville's badge, to the pixel: 14px Barlow Condensed 700, 6px/14px. */
  padding: 6px 14px;
  background: #ffffff; color: #111111;
  font-family: var(--font-display); font-weight: 700;
  font-size: .875rem; letter-spacing: .04em; text-transform: uppercase;
}
.hero-name {
  color: var(--bone);
  text-shadow: 0 1px 3px rgba(17, 17, 17, .8), 0 2px 20px rgba(17, 17, 17, .9);
}

/* four figures on one rule-divided row, red numerals like Northville's */
.stats {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border-block: 1px solid var(--line);
}
.stats > div {
  padding: clamp(24px, 3.2vw, 44px) clamp(12px, 2vw, 28px);
  text-align: center; border-right: 1px solid var(--line);
}
.stats > div:last-child { border-right: 0; }
.stats b {
  display: block; font-family: var(--font-display); font-weight: 700;
  font-size: clamp(2.1rem, 4vw, 3.4rem); line-height: 1; letter-spacing: -.012em;
  color: var(--accent-text);
}
.stats span {
  display: block; margin-top: 10px;
  font-family: var(--font-label); font-size: .78rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--bone-faint);
}
@media (max-width: 800px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats > div:nth-child(2n) { border-right: 0; }
  .stats > div:nth-child(-n+2) { border-bottom: 1px solid var(--line); }
}

/* highlight cards — dark plate, red disc, registration marks, lift on hover */
.hcards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 2.2vw, 26px); }
@media (max-width: 1000px) { .hcards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px)  { .hcards { grid-template-columns: 1fr; } }
.hcard {
  background: var(--ink-2);
  padding: clamp(22px, 2.6vw, 34px);
  display: flex; flex-direction: column; gap: 12px;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.hcard:hover {
  transform: translateY(-8px);
  border-color: var(--accent);
  box-shadow: 0 18px 34px rgba(211, 47, 47, .3);
}
.hcard:hover::before { --mark: var(--accent); }
.hcard-ico {
  width: 52px; height: 52px; flex: none; border-radius: 50%;
  background: var(--accent); display: grid; place-items: center;
}
.hcard-ico svg { width: 26px; height: 26px; }
.hcard h3 {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  letter-spacing: -.006em; line-height: 1.12;
  font-size: clamp(1.12rem, 1.5vw, 1.34rem); color: var(--bone);
}
.hcard p { font-size: .95rem; line-height: 1.6; color: var(--bone-dim); }

/* closing call to action */
.ctaband {
  background: var(--accent-deep);
  padding: clamp(52px, 7vw, 96px) var(--pad);
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: clamp(14px, 1.8vw, 20px);
}
.ctaband h2 { font-size: clamp(1.9rem, 3vw, 2.25rem); color: #ffffff; }  /* Northville: 36px */
.ctaband p { font-size: clamp(1rem, 1.35vw, 1.18rem); color: rgba(255, 255, 255, .88); max-width: 56ch; }
.ctaband-actions { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 8px; }
.ctaband .btn { --bg: #ffffff; --fg: #111111; --wipe: #111111; }
.ctaband .btn:hover { color: #ffffff; }
.ctaband .btn--ghost { --bg: transparent; --fg: #ffffff; --wipe: #ffffff; border-color: rgba(255, 255, 255, .6); }
.ctaband .btn--ghost:hover { color: #111111; border-color: #ffffff; }


/* ---------- 2D / 3D plan switch ----------
   The orbiting model is not for everybody. The measured drawing is flat, still
   and reads at a glance; the model shows the building. The visitor picks, and
   the choice sticks for the session. */
.pswitch {
  display: inline-flex; gap: 6px; flex-wrap: wrap;
  margin-bottom: clamp(14px, 1.8vw, 20px);
}
.pswitch button {
  min-height: 44px; padding: 10px 20px; cursor: pointer;
  background: none; color: var(--bone);
  border: 1px solid var(--line-2);
  font-family: var(--font-label); font-size: .82rem; font-weight: 600;
  letter-spacing: .085em; text-transform: uppercase;
  transition: background-color .3s var(--ease), border-color .3s var(--ease), color .3s var(--ease);
}
.pswitch button:hover { border-color: var(--accent); }
.pswitch button[aria-pressed="true"] {
  background: var(--accent); border-color: var(--accent); color: #ffffff;
}
/* display:none rather than [hidden], which a display rule elsewhere can outrank */
.pane[hidden] { display: none; }

/* ==========================================================================
   MARQUEE
   ========================================================================== */
.marquee { overflow: hidden; border-block: 1px solid var(--line); padding-block: clamp(16px, 2.2vw, 26px); }
.marquee-track { display: flex; width: max-content; animation: marq 44s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes marq { to { transform: translateX(-50%); } }
.marquee-track span {
  display: inline-flex; align-items: center; gap: clamp(20px, 3vw, 46px);
  padding-right: clamp(20px, 3vw, 46px);
  font-family: var(--font-display); font-weight: 700;
  text-transform: uppercase; letter-spacing: -.008em;
  font-size: clamp(1.35rem, 3.1vw, 2.55rem); line-height: 1;
  color: transparent; -webkit-text-stroke: 1px rgba(242, 242, 243, .34);
}
.marquee-track span:nth-child(even) { color: var(--bone); -webkit-text-stroke: 0; }
.marquee-track span::after { content: '\25C6'; font-size: .34em; color: var(--accent); -webkit-text-stroke: 0; }

/* ==========================================================================
   CARD GRID (offerings / who we serve / amenities)
   ========================================================================== */
.grid { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1000px) { .grid--4 { grid-template-columns: repeat(2, 1fr); } .grid--3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .grid--4, .grid--3, .grid--2 { grid-template-columns: 1fr; } }

.cell {
  position: relative; background: var(--ink);
  padding: clamp(24px, 2.9vw, 42px);
  display: flex; flex-direction: column; gap: 14px;
  transition: background-color .5s var(--ease);
  overflow: hidden;
}
.cell::after {
  content: ''; position: absolute; left: 0; top: 0; width: 100%; height: 2px;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  transition: transform .6s var(--ease);
}
.cell:hover { background: var(--ink-2); }
.cell:hover::after { transform: scaleX(1); }
.cell-num { font-family: var(--font-label); font-size: .76rem; letter-spacing: .11em; color: var(--accent-text); }
.cell h3 { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; letter-spacing: -.008em; font-size: clamp(1.02rem, 1.4vw, 1.2rem); line-height: 1.14; }
.cell p { color: var(--bone-faint); font-size: .938rem; line-height: 1.62; }
.cell-ico { width: 56px; height: 56px; object-fit: contain; margin-bottom: 4px; transition: transform .55s var(--ease); }
/* Icon cells centre as a unit — a centred icon over left-aligned text reads as a
   mistake rather than a choice. */
.cell--ico { align-items: center; text-align: center; }
.cell:hover .cell-ico { transform: scale(1.09) rotate(-3deg); }
.cell-more { margin-top: auto; padding-top: 8px; display: inline-flex; align-items: center; gap: 8px; color: var(--accent-text); }
.cell-more .btn-arrow { transition: transform .4s var(--ease); }
.cell:hover .cell-more .btn-arrow { transform: translateX(5px); }

/* portrait cells (who we serve) */
/* "Who we serve" and "Amenities" share the compact icon cell — a full-bleed square
   sized the icon at 62% of the column, which was enormous at any real width. */

/* ==========================================================================
   FEATURE (image + list, alternating)
   ========================================================================== */
/* Open editorial split — no framing box. The bordered panel read as cramped and
   made the photo feel like a thumbnail rather than the subject. */
.feat {
  display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  gap: clamp(26px, 4vw, 72px); align-items: center;
}
.feat + .feat { margin-top: clamp(48px, 7vw, 112px); }
.feat-media { position: relative; overflow: hidden; aspect-ratio: 4 / 3; background: var(--ink-2); }
.feat-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 1.4s var(--ease); }
.feat:hover .feat-media img { transform: scale(1.05); }
.feat-body {
  display: flex; flex-direction: column; justify-content: center;
  gap: clamp(14px, 1.8vw, 22px); align-items: flex-start;
  container-type: inline-size;
}
.feat-body .eyebrow { margin-bottom: 0; }
/* Display type in a narrow column can outrun it — "ENTREPRENEURS" is the longest
   word in the copy and measures ~10.1x its font-size wide, so it needs the column
   to be at least 10.1 font-sizes across. Sizing against the container makes that
   hold at every viewport; the clamp is the fallback without container units. */
.feat-body .d-lg { font-size: clamp(1.6rem, 2.6vw, 2.5rem); }
@supports (width: 1cqw) {
  .feat-body .d-lg { font-size: min(2.5rem, 9.6cqw); }
  .feat-body .d-md { font-size: min(2rem, 9.6cqw); }
}
.feat--rev .feat-media { order: 2; }
@media (max-width: 880px) {
  .feat { grid-template-columns: 1fr; gap: 24px; }
  .feat--rev .feat-media { order: 0; }
}

/* spec list */
.specs { display: flex; flex-direction: column; margin-top: 4px; }
.specs li {
  display: grid; grid-template-columns: auto 1fr; gap: 14px; align-items: start;
  padding: 13px 0; border-top: 1px solid var(--line);
  font-size: .95rem; color: var(--bone-dim); line-height: 1.55;
}
.specs li:last-child { border-bottom: 1px solid var(--line); }
.specs li::before {
  content: ''; width: 5px; height: 5px; margin-top: 10px;
  background: var(--accent); flex: none; transform: rotate(45deg);
}
.specs li b { color: var(--bone); font-weight: 600; }

/* ==========================================================================
   PHOTO RAIL (drag gallery)
   ========================================================================== */
.rail-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-bottom: clamp(22px, 2.6vw, 34px); }
.rail {
  display: flex; gap: clamp(10px, 1.4vw, 20px);
  overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: 18px; scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
  cursor: grab;
}
.rail.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.rail::-webkit-scrollbar { height: 3px; }
.rail::-webkit-scrollbar-track { background: var(--line); }
.rail::-webkit-scrollbar-thumb { background: var(--accent); }
.rail-item {
  flex: none; width: clamp(258px, 40vw, 560px); scroll-snap-align: start;
  aspect-ratio: 3 / 2; overflow: hidden; background: var(--ink-2); position: relative;
}
.rail-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); pointer-events: none; }
.rail-item:hover img { transform: scale(1.05); }
.rail-item b {
  position: absolute; left: 0; bottom: 0; background: var(--ink); color: var(--accent-text);
  font-family: var(--font-label); font-weight: 500; font-size: .76rem; letter-spacing: .1em;
  padding: 8px 13px;
}

/* ==========================================================================
   SHOWCASE — big photo carousel beside copy
   ========================================================================== */
.showcase {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(28px, 4.5vw, 76px); align-items: center;
}
.showcase--flip .showcase-media { order: 2; }
.showcase-body { display: flex; flex-direction: column; gap: clamp(14px, 1.8vw, 22px); align-items: flex-start; }
.showcase-body .eyebrow { margin-bottom: 0; }
@media (max-width: 900px) {
  .showcase { grid-template-columns: 1fr; gap: 28px; }
  .showcase--flip .showcase-media { order: 0; }
}

.cshow { position: relative; }
.cshow-track {
  display: flex; gap: clamp(14px, 2vw, 26px);
  overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; cursor: grab;
  padding-bottom: 4px;
}
.cshow-track::-webkit-scrollbar { display: none; }
.cshow.is-dragging .cshow-track { cursor: grabbing; scroll-snap-type: none; }
/* 3:2 editorial tiles — the source photos were circular crops, which read as a
   gimmick on a commercial property site. */
.cshow-slide {
  flex: none; width: 100%; scroll-snap-align: center;
  aspect-ratio: 3 / 2; position: relative; display: block;
  overflow: hidden; background: var(--ink-2);
}
.cshow-slide img { width: 100%; height: 100%; object-fit: cover; pointer-events: none; transition: transform 1.2s var(--ease); }
.cshow-slide:hover img { transform: scale(1.04); }

.cshow-ui {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: clamp(14px, 1.8vw, 22px);
}
.cshow-dots { display: flex; flex-wrap: wrap; gap: 6px; margin-right: auto; min-width: 0; }
.cshow-dots button {
  width: 26px; height: 2px; padding: 13px 2px; border: 0; cursor: pointer;
  background: var(--line-2); background-clip: content-box;
  box-sizing: content-box; transition: background-color .4s var(--ease);
}
.cshow-dots button.is-on { background: var(--accent); }
.cshow-btn {
  width: 46px; height: 46px; flex: none;
  display: grid; place-items: center;
  background: none; border: 1px solid var(--line-2); color: var(--bone);
  cursor: pointer;
  transition: background-color .35s var(--ease), border-color .35s var(--ease), color .35s var(--ease);
}
.cshow-btn:hover:not(:disabled) { background: var(--accent); border-color: var(--accent); color: #ffffff; }
.cshow-btn:disabled { opacity: .3; cursor: default; }
.cshow-count { color: var(--bone-faint); }
.cshow-count b { color: var(--accent-text); font-weight: 500; }

/* circular photo cluster (home carousels).
   These source images are already circular crops on a transparent canvas, so no
   frame or background is applied — only a ring on hover. */
/* auto-flow:column lays every child out in one equal-width row without having to
   hard-code a count per cluster (they range from 2 to 4 photos). */
/* horizontal scroll-snap carousel: larger images that visitors can swipe/scroll
   through, instead of a cramped grid of tiny circles. */
.orbit {
  display: flex; gap: clamp(14px, 1.6vw, 22px);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
  padding-bottom: 10px; scrollbar-width: none; cursor: grab;
}
.orbit::-webkit-scrollbar { display: none; }
.orbit:active { cursor: grabbing; }
.orbit-img {
  flex: 0 0 clamp(220px, 24vw, 300px);
  aspect-ratio: 1 / 1; border-radius: 50%; position: relative;
  scroll-snap-align: center; overflow: hidden;
  transition: transform .7s var(--ease);
}
@media (max-width: 620px) { .orbit-img { flex-basis: 78%; } }
.orbit-img::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  border: 1px solid var(--accent); opacity: 0; transform: scale(.92);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.orbit-img img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.orbit-img:hover { transform: translateY(-6px) scale(1.03); }
.orbit-img:hover::after { opacity: 1; transform: scale(1.05); }

/* ==========================================================================
   ACCORDION (FAQ)
   ========================================================================== */
.acc { border-top: 1px solid var(--line); }
.acc-item { border-bottom: 1px solid var(--line); }
.acc-btn {
  width: 100%; background: none; border: 0; cursor: pointer; text-align: left;
  display: grid; grid-template-columns: auto 1fr auto; gap: clamp(12px, 2vw, 24px);
  align-items: start; padding: clamp(18px, 2.3vw, 26px) 0;
  transition: color .35s var(--ease);
}
.acc-btn:hover { color: var(--accent-text); }
.acc-btn .q-num { font-family: var(--font-label); font-size: .76rem; letter-spacing: .1em; color: var(--accent-text); padding-top: .48em; }
.acc-btn .q-txt {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1rem, 1.55vw, 1.24rem); line-height: 1.3; letter-spacing: -.004em;
}
.acc-btn .q-ico { position: relative; width: 15px; height: 15px; flex: none; margin-top: .42em; }
.acc-btn .q-ico::before, .acc-btn .q-ico::after {
  content: ''; position: absolute; left: 50%; top: 50%; background: var(--accent);
  transform: translate(-50%, -50%); transition: transform .45s var(--ease), opacity .3s;
}
.acc-btn .q-ico::before { width: 15px; height: 1.5px; }
.acc-btn .q-ico::after  { width: 1.5px; height: 15px; }
.acc-item.is-open .q-ico::after { transform: translate(-50%, -50%) rotate(90deg); opacity: 0; }
.acc-panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .55s var(--ease); }
.acc-item.is-open .acc-panel { grid-template-rows: 1fr; }
.acc-panel > div { overflow: hidden; }
.acc-panel p {
  padding: 0 clamp(0px, 3vw, 40px) clamp(20px, 2.4vw, 28px) clamp(28px, 4.6vw, 52px);
  color: var(--bone-dim); font-size: .97rem; max-width: 80ch;
}
.acc-panel a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }

/* ==========================================================================
   CONTACT / FORM
   ========================================================================== */
.contact {
  position: relative; overflow: hidden;
  border-top: 1px solid var(--line);
  background: var(--ink);
}
.contact > .wrap { position: relative; z-index: 3; }
/* The source background is a near-white architectural drawing; inverted it becomes
   a light-on-dark blueprint that belongs on this palette. */
.contact-bg { position: absolute; inset: 0; z-index: 1; }
.contact-bg img { width: 100%; height: 100%; object-fit: cover; filter: invert(1) grayscale(1); opacity: .62; }
.contact::after {
  content: ''; position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(115deg, rgba(17, 17, 17, .9) 0%, rgba(17, 17, 17, .66) 52%, rgba(17, 17, 17, .88) 100%);
}
.form { display: grid; gap: 14px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 640px) { .form-row { grid-template-columns: 1fr; } }
.field { position: relative; }
.field > label {
  display: block; margin-bottom: 8px;
  font-family: var(--font-label); font-size: .76rem; letter-spacing: .095em;
  text-transform: uppercase; color: var(--accent-text);
}
.field input, .field select, .field textarea {
  width: 100%; background: rgba(242, 242, 243, .035);
  border: 1px solid var(--line); border-radius: 0;
  padding: 15px 17px; color: var(--bone); font-size: .95rem;
  transition: border-color .35s var(--ease), background-color .35s var(--ease);
  min-height: 52px;
}
.field textarea { resize: vertical; min-height: 128px; line-height: 1.55; }
.field input::placeholder, .field textarea::placeholder { color: var(--bone-faint); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent); background: rgba(242, 242, 243, .06);
}
.field select {
  appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23d32f2f' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 17px center;
  padding-right: 44px;
}
.field select option { background: var(--ink-2); color: var(--bone); }
.form-note { color: var(--bone-faint); font-size: .8rem; }
.form-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; }

.wa {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 46px; padding: 12px 24px;
  border: 1px solid var(--line-2); color: var(--bone);
  font-family: var(--font-label); font-size: .82rem; letter-spacing: .085em; text-transform: uppercase;
  transition: border-color .35s var(--ease), color .35s var(--ease), background-color .35s var(--ease);
}
.wa svg { width: 15px; height: 15px; fill: #25D366; flex: none; }
.wa:hover { border-color: #25D366; background: rgba(37, 211, 102, .08); }

.contact-aside { display: flex; flex-direction: column; gap: clamp(22px, 2.6vw, 34px); }
.info-row { display: grid; gap: 6px; padding-block: 16px; border-top: 1px solid var(--line); }
.info-row:last-of-type { border-bottom: 1px solid var(--line); }
.info-row a, .info-row span { font-size: 1.02rem; color: var(--bone); transition: color .3s; }
.info-row a:hover { color: var(--accent-text); }

/* ==========================================================================
   FOOTER
   ========================================================================== */
.ftr { border-top: 1px solid var(--line); background: var(--ink); position: relative; overflow: hidden; }
.ftr-top { display: grid; grid-template-columns: minmax(0, 1.25fr) repeat(2, minmax(0, 1fr)); gap: clamp(30px, 4vw, 64px); padding-block: clamp(46px, 6vw, 88px); }
@media (max-width: 860px) { .ftr-top { grid-template-columns: 1fr 1fr; } .ftr-brand { grid-column: 1 / -1; } }
@media (max-width: 520px) { .ftr-top { grid-template-columns: 1fr; } }
.ftr-brand img { width: clamp(196px, 17vw, 232px); height: auto; margin-bottom: 28px; }
.ftr h4 { font-family: var(--font-label); font-size: .76rem; letter-spacing: .11em; text-transform: uppercase; color: var(--accent-text); margin-bottom: 18px; font-weight: 500; }
.ftr-links { display: flex; flex-direction: column; gap: 11px; }
.ftr-links a, .ftr-contact a, .ftr-contact span { color: var(--bone-dim); font-size: .938rem; transition: color .3s; }
.ftr-links a:hover, .ftr-contact a:hover { color: var(--accent-text); }
.ftr-contact { display: flex; flex-direction: column; gap: 14px; }
.ftr-contact li { display: grid; gap: 3px; }
.ftr-contact em { font-style: normal; font-family: var(--font-label); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--bone-faint); }
.ftr-bot {
  border-top: 1px solid var(--line); padding-block: 22px;
  display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: center; justify-content: space-between;
}
.ftr-bot p, .ftr-bot a { font-family: var(--font-label); font-size: .76rem; letter-spacing: .07em; text-transform: uppercase; color: var(--bone-faint); }
.ftr-bot a:hover { color: var(--accent-text); }

.ftr-word {
  font-family: var(--font-display); font-weight: 700;
  text-transform: uppercase; letter-spacing: -.008em; line-height: .78;
  /* sized so the 12-character wordmark ("NOVI COMMONS") never exceeds the padded wrap width */
  font-size: min(8rem, 8.4vw);
  color: transparent; -webkit-text-stroke: 1px rgba(242, 242, 243, .1);
  padding-bottom: clamp(10px, 2vw, 26px); user-select: none; white-space: nowrap;
  text-align: center; overflow: hidden;
}

/* to-top */
/* Sits 58px higher than its own inset so it clears the JMZ portfolio switcher
   pill, which is fixed to the same bottom-right corner. */
.totop {
  position: fixed; right: clamp(14px, 2vw, 26px); bottom: calc(clamp(14px, 2vw, 26px) + 58px); z-index: 850;
  width: 46px; height: 46px; display: grid; place-items: center;
  background: var(--accent); color: #ffffff; border: 0; cursor: pointer;
  opacity: 0; pointer-events: none; transform: translateY(12px);
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.totop.is-on { opacity: 1; pointer-events: auto; transform: none; }

/* JMZ portfolio switcher (assets/js/property-switcher.js) is fixed at
   z-index 2147483000 by design, so it lands on top of anything this site puts
   over the page — it covered the suite popup's action buttons, exactly as it
   did on the Rankin site. The shared file is never edited to fix this; the host
   page hides the widget while an overlay owns the screen. Two classes outrank
   the widget's own single-class rule, so this needs no !important and no
   lowering of its z-index.
     body.lm-open  — suite details popup (leasing-map.js)
     body.is-locked — mobile menu */
body.lm-open .jmz-sw,
body.is-locked .jmz-sw { display: none; }

/* The switcher's container is a fixed flex column holding the pill AND its
   collapsed panel, so its box reaches ~250px up the bottom-right corner even
   while the panel is invisible — and at z-index 2147483000 it silently ate
   every click landing there. It cost taps on whatever sits in that corner:
   found while clicking the site plan's southern suites, which simply did not
   respond. The shared switcher file is byte-identical across the three sites
   and is not edited, so the container stops taking pointer events here and the
   pill takes them back; the panel already manages its own (none when closed,
   auto when open). */
.jmz-sw { pointer-events: none; }
.jmz-sw-btn { pointer-events: auto; }

/* ==========================================================================
   MISC
   ========================================================================== */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 1000;
  background: var(--accent); color: #ffffff; padding: 12px 20px;
  font-family: var(--font-label); font-size: .82rem; letter-spacing: .085em; text-transform: uppercase;
}
.skip:focus { left: 8px; top: 8px; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.note {
  border-left: 2px solid var(--accent); padding: 4px 0 4px 20px;
  color: var(--bone-dim); font-size: .97rem;
}
/* comfortable touch targets for the inline text links on small screens */
@media (max-width: 760px) {
  .ftr-links a, .ftr-contact a, .cell-more, .info-row a, .ftr-bot a, .crumb a { padding-block: 7px; }
  .ftr-links { gap: 4px; }
}

.center { text-align: center; }
.mt-l { margin-top: clamp(30px, 4vw, 54px); }
.mt-m { margin-top: clamp(18px, 2.4vw, 28px); }
.mt-s { margin-top: 14px; }
.maxw-60 { max-width: 60ch; }
.maxw-46 { max-width: 46ch; }
