/* ============================================================
   THE HAT — SHARED THEME
   Layout + components. Property-agnostic: never hard-code a
   colour, font or brand value here. Always reference brand.css.
   ============================================================ */

/* ---------- Reset ---------- */
*,*::before,*::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--text-body);
  background: var(--bg-page);
  -webkit-font-smoothing: antialiased;
}
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }
h1,h2,h3,h4 { margin: 0; font-weight: 400; line-height: 1.08; }
p { margin: 0 0 1em; }
ul { margin: 0; padding: 0; list-style: none; }
:focus-visible { outline: 2px solid var(--smoke); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,*::before,*::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- Layout primitives ---------- */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.wrap--narrow { max-width: var(--maxw-narrow); }
.section { padding-block: var(--section-y); position: relative; overflow: hidden; }
.section--sage   { background: var(--bg-inverse); color: var(--text-inverse); }
.section--deep   { background: var(--smoke); color: var(--text-inverse); }
.section--cream  { background: var(--cream); }
.section--slate  { background: var(--smoke); color: var(--text-inverse); }
.section--stone  { background: var(--stone); color: var(--text-inverse); }
.section--tight  { padding-block: calc(var(--section-y) * .55); }

/* ---------- Type ---------- */
.display  { font-family: var(--font-display); font-weight: 400; letter-spacing: .005em; }
.hero-title { font-family: var(--font-display); font-weight: 400; font-size: var(--fs-hero); line-height: 1.02; }
.h1 { font-family: var(--font-display); font-size: var(--fs-h1); font-weight: 400; }
.h2 { font-family: var(--font-display); font-size: var(--fs-h2); font-weight: 400; }
.h3 { font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 400; }
.lead { font-size: var(--fs-lead); line-height: 1.6; color: var(--text-muted); max-width: 62ch; }
.section--sage .lead, .section--deep .lead, .section--slate .lead, .page-hero .lead { color: var(--text-on-sage-muted); }
.eyebrow {
  font-family: var(--font-body); font-size: var(--fs-eyebrow); font-weight: 500;
  letter-spacing: var(--tracking-eyebrow); text-transform: uppercase;
  color: var(--smoke); margin: 0 0 1rem;
}
.section--sage .eyebrow, .section--deep .eyebrow { color: var(--cream); opacity: .8; }
.section--slate .eyebrow, .section--stone .eyebrow { color: var(--cream); }
.script-note {
  font-family: var(--font-display); font-style: italic; font-size: var(--fs-lead);
  letter-spacing: .04em; opacity: .9;
}

/* Section heading block */
.sec-head { max-width: 68ch; margin-bottom: clamp(2rem,4vw,3.5rem); }
.sec-head--center { margin-inline: auto; text-align: center; }
.sec-head .h1, .sec-head .h2 { margin-bottom: .75rem; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6em;
  padding: .95em 2.1em; border: 0; border-radius: var(--radius-pill);
  background: var(--btn-bg); color: var(--btn-text);
  font-size: var(--fs-small); font-weight: 500;
  letter-spacing: var(--tracking-btn); text-transform: uppercase;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
  white-space: nowrap;
}
.btn:hover { background: var(--btn-bg-hover); transform: translateY(-2px); }
.btn--ghost {
  background: transparent; color: currentColor;
  box-shadow: inset 0 0 0 1px currentColor;
}
.btn--ghost:hover { background: rgba(255,255,255,.12); }
.section--cream .btn--ghost:hover, body > .section:not(.section--sage):not(.section--deep):not(.section--slate) .btn--ghost:hover { background: rgba(43,49,45,.07); }
.btn--cream { background: var(--cream); color: var(--sage-deep); }
.btn--cream:hover { background: var(--white); }
.site-header .btn { background: var(--sea); color: var(--cream); }
.btn-row { display: flex; flex-wrap: wrap; gap: .85rem; align-items: center; }

.link-arrow {
  display: inline-flex; align-items: center; gap: .55em;
  font-size: var(--fs-small); font-weight: 500;
  letter-spacing: var(--tracking-btn); text-transform: uppercase;
  padding-bottom: .35em; border-bottom: 1px solid currentColor;
  transition: gap var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.link-arrow:hover { gap: 1.1em; opacity: .75; }

/* ============================================================
   HEADER
   ============================================================ */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  height: var(--header-h);
  display: flex; align-items: center;
  background: transparent;
  transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.site-header.is-stuck {
  background: color-mix(in srgb, var(--sage) 96%, black);
  box-shadow: 0 1px 0 var(--rule-inverse);
}
.site-header--solid { background: var(--sage); }
.site-header__inner {
  width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter);
  display: flex; align-items: center; gap: 1.5rem;
}
/* On desktop the header gets a deeper inset than the page gutter, so the
   circular logo is not flush against the edge of the content column. */
@media (min-width: 1081px) {
  .site-header__inner { padding-inline: clamp(3rem, 7vw, 8rem); }
}
/* Header logo — the circular ring wordmark. It is the whole lockup: the
   property name is already inside the mark, so no adjacent text is needed.
   Size comes from --logo-size in brand.css; keep it under --header-h.
   --logo-x nudges it right and --logo-y down, applied to the lockup only so
   the phone and hamburger on the right do not move with it. --logo-y must not
   exceed (--header-h - --logo-size)/2 or the ring pokes out of the bar and
   gets clipped the moment the header turns opaque on scroll. */
.brand-lockup {
  display: flex; align-items: center; margin-right: auto; color: var(--white);
  margin-left: var(--logo-x); transform: translateY(var(--logo-y));
}
.brand-lockup__ring {
  width: var(--logo-size); height: var(--logo-size);
  flex: none; transition: transform 1.2s var(--ease);
}
.brand-lockup:hover .brand-lockup__ring { transform: rotate(30deg); }

.header-actions { display: flex; align-items: center; gap: 1.25rem; }
.header-phone {
  display: inline-flex; align-items: center; gap: .5em;
  color: var(--white); font-size: .85rem; font-weight: 500; letter-spacing: .06em;
  white-space: nowrap;
}
.header-phone svg { width: 15px; height: 15px; flex: none; }
.header-actions .btn { padding: .75em 1.6em; }
@media (max-width: 820px) { .header-phone { display: none; } }
@media (max-width: 560px) { .header-actions .btn { display: none; } }

/* ------------------------------------------------------------
   MENU TRIGGER — a plain hamburger, at every width.
   There is no inline desktop nav; the rosette dial below is the
   only navigation, so the trigger has to read unambiguously as
   a menu. Sizes come from the --burger-* tokens in brand.css.
   ------------------------------------------------------------ */
.nav-toggle {
  width: var(--burger-box); height: var(--burger-box);
  display: grid; place-content: center; gap: var(--burger-gap);
  border: 0; background: transparent; color: var(--white); padding: 0;
}
.nav-toggle span {
  display: block; width: var(--burger-w); height: var(--burger-t);
  background: currentColor;
  transition: transform .45s var(--ease), opacity .25s var(--ease);
}
/* The outer bars sit (thickness + gap) from the middle one, so that is exactly
   how far they travel to meet in the centre. Deriving it keeps the cross true
   at any size rather than hard-coding a pixel offset per breakpoint. */
body.nav-open .nav-toggle span:nth-child(1) {
  transform: translateY(calc(var(--burger-t) + var(--burger-gap))) rotate(45deg);
}
body.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
body.nav-open .nav-toggle span:nth-child(3) {
  transform: translateY(calc(-1 * (var(--burger-t) + var(--burger-gap)))) rotate(-45deg);
}

/* ============================================================
   THE ROSETTE DIAL — the whole navigation
   The open menu is a geometrically exact enlargement of the
   brand rosette: six tangent circles (R = 2r) with the star of
   negative space intact and the hat mark in the middle.
   See CLAUDE.md before touching the geometry.
   ============================================================ */
.dial {
  position: fixed; inset: 0; z-index: 99;
  background: var(--sage);
  display: grid; place-items: center; overflow-y: auto;
  padding: calc(var(--header-h) + 2vh) var(--gutter) 5vh;
  opacity: 0; visibility: hidden;
  transition: opacity .5s var(--ease), visibility .5s;
}
body.nav-open .dial { opacity: 1; visibility: visible; }
.dial__wrap { display: flex; flex-direction: column; align-items: center; gap: clamp(1.5rem,4vh,2.75rem); }

/* NB: never put overflow:hidden on the stage — the slate rims sit slightly
   outside it by design and would be clipped top and bottom. */
.dial__stage { position: relative; width: min(64vmin, 500px); aspect-ratio: 1; flex: none; }
.dial__hub {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  width: 17%; display: grid; place-items: center; color: var(--cream);
  opacity: 0; transition: opacity .5s var(--ease) .42s;
}
body.nav-open .dial__hub { opacity: 1; }
.dial__hub .hat-mark { width: 100%; height: auto; }

.petal {
  position: absolute; left: 50%; top: 50%; width: 33.333%; aspect-ratio: 1;
  display: grid; place-items: center; text-align: center; background: transparent;
  transform: translate(-50%,-50%) scale(.18); opacity: 0;
  transition: transform .65s var(--ease), opacity .45s var(--ease);
}
body.nav-open .petal {
  opacity: 1;
  transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) scale(1);
  transition-delay: calc(.08s + var(--i) * .06s);
}
/* Slate layer: 105.3% and shifted radially outward, which is what the whole
   rosette scaled 1.053x about its centre resolves to per circle. This is why
   the rim only ever shows on the outside and never leaks into the star hole. */
.petal::before {
  content:""; position: absolute; z-index: 0; border-radius: 50%;
  width: 105.3%; height: 105.3%;
  left: calc(-2.65% + 5.3% * var(--ox));
  top:  calc(-2.65% + 5.3% * var(--oy));
  background: var(--sea);
  transition: transform .45s var(--ease);
}
.petal::after {
  content:""; position: absolute; z-index: 1; inset: 0; border-radius: 50%;
  background: var(--cream); transition: background .35s var(--ease);
}
/* Button typography rather than the display face: the petals previously read
   as decoration, and matching the type of every .btn on the site is what tells
   people they are pressable.
   text-indent cancels the trailing letter-space that letter-spacing adds after
   the final character — without it the label sits half a space left of the
   circle's true centre, which is visible at this size. */
.petal span {
  position: relative; z-index: 2;
  font-family: var(--font-body); font-weight: 500;
  font-size: clamp(.7rem, 2vmin, .9rem);
  letter-spacing: .13em; text-indent: .13em; text-transform: uppercase;
  line-height: 1.35; padding: 0 .9em;
  color: var(--sage-deep);
}
.petal:hover::after { background: var(--white); }
.petal:hover::before { transform: scale(1.07); }
/* Current page, matching the indicator the previous inline nav had */
.petal[aria-current="page"]::after { background: var(--white); }
.petal[aria-current="page"] span { font-style: italic; }

.dial__tour {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 1.05em 3.4em; border-radius: var(--radius-pill);
  background: var(--sea); color: var(--cream);
  font-size: clamp(1rem, 2.4vw, 1.35rem); font-weight: 500;
  letter-spacing: var(--tracking-btn); text-transform: uppercase; white-space: nowrap;
  opacity: 0; transform: translateY(16px);
  transition: opacity .5s var(--ease) .46s, transform .5s var(--ease) .46s,
              background .35s var(--ease);
}
body.nav-open .dial__tour { opacity: 1; transform: none; }
.dial__tour:hover { background: var(--white); }

.dial__meta {
  display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; justify-content: center;
  font-size: var(--fs-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase;
  color: rgba(255,255,255,.68);
  opacity: 0; transition: opacity .5s var(--ease) .58s;
}
body.nav-open .dial__meta { opacity: 1; }
.dial__meta a:hover { color: var(--white); }
.dial__meta i { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .5; }

@media (max-height: 760px) {
  .dial__stage { width: min(52vmin, 400px); }
  .dial__tour { padding: .9em 2.6em; font-size: 1rem; }
}
@media (max-width: 420px) {
  .dial__stage { width: min(80vmin, 360px); }
  .petal span { font-size: .7rem; letter-spacing: .11em; text-indent: .11em; padding: 0 .6em; }
}

/* Mobile sticky action bar */
/* One edge-to-edge bar, square corners. gap:0 — the two halves are already
   different colours, so the 1px of bar background that used to show between
   them just read as a seam. Bottom padding carries the safe-area inset so the
   labels clear the home indicator on iOS. */
.action-bar {
  position: fixed; inset: auto 0 0 0; z-index: 98;
  display: none; gap: 0; background: var(--rule-inverse);
  box-shadow: 0 -6px 24px rgba(0,0,0,.16);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.action-bar a {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: .5em;
  padding: 1.05rem .5rem; background: var(--sage-deep); color: var(--white);
  font-size: .78rem; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
}
.action-bar a + a { background: var(--slate); }
.action-bar svg { width: 15px; height: 15px; }
@media (max-width: 1080px) {
  .action-bar { display: flex; }
  body { padding-bottom: 56px; }
}
body.nav-open .action-bar { display: none; }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative; min-height: min(100svh, 900px);
  /* Two rows: the content block centres in row 1, the scroll cue owns row 2.
     The cue used to be position:absolute, which let it sit underneath the
     button row on short/wide viewports. Keeping it in flow makes overlap
     structurally impossible. */
  display: grid; grid-template-rows: 1fr auto; place-items: center; text-align: center;
  background: var(--sage); color: var(--white);
  padding: calc(var(--header-h) + 4rem) var(--gutter) 2.25rem;
  overflow: hidden; isolation: isolate;
}
.hero--short { min-height: min(66svh, 660px); }
.hero__bg {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
}
.hero__scrim {
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(120% 90% at 50% 40%, rgba(76,85,79,.28), rgba(76,85,79,.72) 100%),
    linear-gradient(to bottom, rgba(76,85,79,.55), rgba(76,85,79,.25) 45%, rgba(76,85,79,.8));
}
/* Faded circle texture, drawn from the brand asset */
.hero__texture {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: url("../assets/brand/circles-texture.png") center/cover no-repeat;
  opacity: .85; mix-blend-mode: soft-light;
}
.hero__inner { position: relative; max-width: 62rem; }
.hero__eyebrow {
  font-size: var(--fs-eyebrow); font-weight: 500;
  letter-spacing: var(--tracking-eyebrow); text-transform: uppercase;
  color: var(--cream); margin-bottom: 1.4rem;
}
.hero__title { font-family: var(--font-display); font-weight: 400; font-size: var(--fs-hero); line-height: 1.02; margin-bottom: 1.25rem; }
.hero__title em { font-style: italic; }
.hero__sub { font-size: var(--fs-lead); color: rgba(255,255,255,.86); max-width: 46ch; margin: 0 auto 2.25rem; }
.hero .btn-row { justify-content: center; }

.hero__banner { max-width: 640px; margin: 0 auto clamp(1.5rem, 4vw, 2.5rem); }
.hero__banner-img { display: block; width: 100%; height: auto; }

/* Rotating ring wordmark */
.ring {
  width: clamp(210px, 30vw, 340px); aspect-ratio: 1;
  margin: 0 auto clamp(1.5rem, 4vw, 2.5rem);
  display: grid; place-items: center; position: relative;
}
.ring__img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  animation: spin 64s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.ring__mark { width: 22%; color: var(--white); }

/* Scroll cue */
.scroll-cue {
  display: grid; justify-items: center; gap: .6rem;
  margin-top: clamp(1.5rem, 4vh, 3rem);
  font-size: .65rem; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase;
  color: rgba(255,255,255,.62);
}
.scroll-cue i { display: block; width: 1px; height: 44px; background: linear-gradient(rgba(255,255,255,.75), transparent); }
/* No room for a scroll cue on short viewports — drop it rather than crowd the CTAs */
@media (max-height: 620px) { .scroll-cue { display: none; } }

/* Page hero (interior pages) */
.page-hero {
  background: var(--sage); color: var(--white);
  padding: calc(var(--header-h) + clamp(3.5rem,7vw,6rem)) 0 clamp(3.5rem,7vw,6rem);
  position: relative; overflow: hidden;
}
.page-hero::after {
  content:""; position: absolute; right: -6%; top: -30%;
  width: min(46vw, 560px); aspect-ratio: 576/632;
  background: url("../assets/brand/rosette.svg") center/contain no-repeat;
  opacity: .1; pointer-events: none;
}
.page-hero__inner { position: relative; z-index: 1; max-width: 58rem; }
.page-hero .h1 { margin-bottom: 1rem; }
.breadcrumb { font-size: var(--fs-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--cream); opacity: .75; margin-bottom: 1.25rem; }

/* ============================================================
   ROSETTE / CIRCLE MOTIF DEVICES
   ============================================================ */
.rosette { width: clamp(120px,16vw,200px); aspect-ratio: 576/632; }
.motif-divider { display: grid; place-items: center; padding-block: clamp(2rem,4vw,3.5rem); }
.motif-divider .rosette { width: clamp(64px,7vw,92px); opacity: .9; }
.motif-asterisk { font-family: var(--font-display); font-size: 2rem; line-height: 1; opacity: .5; }

/* Circle-masked media — the signature imagery treatment */
.circle-media { position: relative; border-radius: 50%; overflow: hidden; aspect-ratio: 1; background: var(--stone); }
.circle-media img, .circle-media svg { width: 100%; height: 100%; object-fit: cover; }

.rosette-media {
  position: relative; aspect-ratio: 576/632;
  -webkit-mask: url("../assets/brand/rosette-mask.svg") center/contain no-repeat;
          mask: url("../assets/brand/rosette-mask.svg") center/contain no-repeat;
  background: var(--sea);
}
.rosette-media img, .rosette-media svg { width: 100%; height: 100%; object-fit: cover; }

/* ============================================================
   SPLIT / FEATURE BLOCKS
   ============================================================ */
.split {
  display: grid; gap: clamp(2rem, 5vw, 5rem); align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; }
  .split--media-right > :first-child { order: 1; }
  .split--wide-text { grid-template-columns: 1.15fr .85fr; }
}
.split__body { max-width: 52ch; }
/* Every split heading is marked up as class="h1", so targeting .h2 alone
   matched nothing and left the heading with no bottom margin — it sat tight
   against the lead while the paragraph below it kept normal spacing.
   Mirrors .sec-head, which already covers both classes. */
.split__body .h1, .split__body .h2 { margin-bottom: 1rem; }

/* ============================================================
   CARD GRIDS
   ============================================================ */
.grid { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }

.card {
  background: var(--white); border-radius: var(--radius-md); overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.section--sage .card, .section--deep .card { background: rgba(255,255,255,.07); color: var(--white); box-shadow: inset 0 0 0 1px var(--rule-inverse); }
.card:hover { transform: translateY(-5px); box-shadow: 0 16px 44px rgba(43,49,45,.14); }
.card__media { aspect-ratio: 4/3; background: var(--cream); position: relative; }
.card__media img, .card__media svg { width: 100%; height: 100%; object-fit: cover; }
.card__body { padding: clamp(1.25rem,2vw,1.9rem); display: flex; flex-direction: column; gap: .6rem; flex: 1; }
.card__body .h3 { font-family: var(--font-display); }
.card__meta {
  font-size: var(--fs-small); letter-spacing: .1em; text-transform: uppercase;
  color: var(--smoke); font-weight: 500;
}
.section--sage .card__meta { color: var(--cream); }
.card__foot { margin-top: auto; padding-top: .75rem; }

/* Amenity item — icon + label, no card chrome */
.amenity-list { display: grid; gap: clamp(1rem,2vw,1.6rem); grid-template-columns: repeat(auto-fit, minmax(min(100%,15rem),1fr)); }
.amenity {
  display: flex; gap: 1rem; align-items: flex-start;
  padding-top: 1.25rem; border-top: 1px solid var(--rule);
}
.section--sage .amenity, .section--deep .amenity, .section--slate .amenity { border-color: var(--rule-inverse); }
.amenity__dot { width: 34px; height: 34px; flex: none; border-radius: 50%; background: var(--smoke); display: grid; place-items: center; color: var(--white); }
/* Alternate the dot colour so a long amenity list gets some rhythm */
.amenity-list .amenity:nth-child(3n+2) .amenity__dot { background: var(--sea); }
.amenity-list .amenity:nth-child(3n+3) .amenity__dot { background: var(--stone); }
.section--sage .amenity__dot { background: var(--cream); color: var(--sage-deep); }
.amenity__dot svg { width: 17px; height: 17px; }
.amenity__text { flex: 1; }
.amenity__text strong { display: block; font-weight: 500; font-size: .98rem; margin-bottom: .1rem; }
.amenity__text span { font-size: var(--fs-small); color: var(--text-muted); }
.section--sage .amenity__text span, .section--deep .amenity__text span { color: var(--text-on-sage-muted); }

/* Simple two-column spec lists (mirrors the leasing-office decal) */
.spec-cols { display: grid; gap: clamp(2rem,5vw,4rem); grid-template-columns: repeat(auto-fit, minmax(min(100%,18rem),1fr)); }
.spec-col > .eyebrow { padding-bottom: .9rem; border-bottom: 1px solid var(--rule-inverse); margin-bottom: 1.25rem; }
.spec-col li { position: relative; padding-left: 1.5rem; margin-bottom: .7rem; font-size: .97rem; }
.spec-col li::before { content: "—"; position: absolute; left: 0; opacity: .55; }

/* ============================================================
   FLOORPLANS
   ============================================================ */
.plan {
  display: grid; gap: clamp(1.5rem,4vw,3.5rem); align-items: center;
  grid-template-columns: 1fr; padding-block: clamp(2.5rem,5vw,4.5rem);
  border-top: 1px solid var(--rule);
}
/* The filter hides plans with the hidden attribute. That relies on the browser's
   [hidden] { display: none }, which is a user-agent rule — the author rule above
   sets display: grid and wins, so the attribute alone does nothing. This restores
   it. Same trap as .amap__group[hidden]. */
.plan[hidden] { display: none; }
.plan:first-of-type { border-top: 0; padding-top: 0; }
@media (min-width: 860px) { .plan { grid-template-columns: 1fr 1.1fr; } }
.plan__media { background: var(--cream); border-radius: var(--radius-md); padding: clamp(1rem,2vw,2rem); aspect-ratio: 4/3; display: grid; place-items: center; }
.plan__media img, .plan__media svg { width: 100%; height: 100%; object-fit: contain; }
.plan__name { font-family: var(--font-display); font-size: var(--fs-h2); font-weight: 400; margin-bottom: .35rem; }
.plan__stats { display: flex; flex-wrap: wrap; gap: 0 2rem; margin: 1.25rem 0; padding-block: 1rem; border-block: 1px solid var(--rule); }
.plan__stat { min-width: 6rem; }
.plan__stat dt { font-size: var(--fs-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--smoke); margin-bottom: .2rem; }
.plan__stat dd { margin: 0; font-size: 1.05rem; font-weight: 500; }

/* Filter chips */
/* Chips take .btn's metrics — same padding, weight, tracking and hover lift —
   so a filter row reads as the same family of control as every other button.
   Unpressed mirrors .btn--ghost (hairline in currentColor); pressed mirrors the
   primary .btn, via the same tokens rather than a hard-coded colour. */
.chips { display: flex; flex-wrap: wrap; gap: .75rem; margin-bottom: clamp(2rem,4vw,3rem); }
.chip {
  display: inline-flex; align-items: center; justify-content: center;
  padding: .95em 2.1em; border: 0; border-radius: var(--radius-pill);
  background: transparent; color: currentColor;
  box-shadow: inset 0 0 0 1px currentColor;
  font-size: var(--fs-small); font-weight: 500;
  letter-spacing: var(--tracking-btn); text-transform: uppercase; white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.chip:hover { background: rgba(43,49,45,.07); transform: translateY(-2px); }
.chip[aria-pressed="true"] { background: var(--btn-bg); color: var(--btn-text); box-shadow: none; }
.chip[aria-pressed="true"]:hover { background: var(--btn-bg-hover); }

/* ============================================================
   GALLERY
   ============================================================ */
.gallery { columns: 3; column-gap: clamp(.75rem,1.5vw,1.25rem); }
@media (max-width: 900px) { .gallery { columns: 2; } }
@media (max-width: 560px) { .gallery { columns: 1; } }
.gallery figure { margin: 0 0 clamp(.75rem,1.5vw,1.25rem); break-inside: avoid; border-radius: var(--radius-md); overflow: hidden; background: var(--cream); position: relative; }
.gallery img, .gallery svg { width: 100%; height: auto; transition: transform .8s var(--ease); }
.gallery figure:hover img, .gallery figure:hover svg { transform: scale(1.04); }
.gallery figcaption {
  position: absolute; inset: auto 0 0 0; padding: 1.5rem 1rem .8rem;
  background: linear-gradient(transparent, rgba(43,49,45,.72));
  color: var(--white); font-size: var(--fs-small); letter-spacing: .08em; text-transform: uppercase;
}

/* ============================================================
   NEIGHBOURHOOD
   ============================================================ */
.hood-grid { display: grid; gap: clamp(1.5rem,3vw,2.5rem); grid-template-columns: repeat(auto-fit, minmax(min(100%,16rem),1fr)); }
.hood { text-align: center; }
.hood .circle-media { margin: 0 auto 1.25rem; width: min(100%, 15rem); }
.hood .h3 { margin-bottom: .4rem; }
.hood p { font-size: var(--fs-small); color: var(--text-muted); margin: 0; }
.section--sage .hood p { color: var(--text-on-sage-muted); }

.stat-row { display: grid; gap: clamp(1.5rem,3vw,2rem); grid-template-columns: repeat(auto-fit, minmax(min(100%,11rem),1fr)); text-align: center; }
.stat__num { font-family: var(--font-display); font-size: clamp(2.4rem,5vw,3.6rem); font-weight: 400; line-height: 1; margin-bottom: .4rem; }
.stat__label { font-size: var(--fs-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; opacity: .8; }

/* ============================================================
   INCENTIVES
   ============================================================ */
.offer {
  border-radius: var(--radius-md); padding: clamp(1.75rem,3vw,2.75rem);
  background: var(--white); display: flex; flex-direction: column; gap: .8rem;
  box-shadow: inset 0 0 0 1px var(--rule);
}
.offer--feature { background: var(--sage); color: var(--white); box-shadow: none; }
.offer__tag {
  align-self: flex-start; padding: .4em 1em; border-radius: var(--radius-pill);
  background: var(--smoke); color: var(--white);
  font-size: .68rem; font-weight: 600; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase;
}
.offer--feature .offer__tag { background: var(--cream); color: var(--sage-deep); }
.offer__value { font-family: var(--font-display); font-size: clamp(1.9rem,3.6vw,2.8rem); font-weight: 400; line-height: 1; }
.offer p { font-size: var(--fs-small); color: var(--text-muted); margin: 0; }
.offer--feature p { color: var(--text-on-sage-muted); }
.offer__foot { margin-top: auto; padding-top: 1rem; }

/* ============================================================
   HAT FAMILY — cards on the dedicated page
   Each sibling keeps its own brand accent colour, so the cards
   sit on white tiles over the cream ground rather than on sage.
   ============================================================ */
.family-cards {
  display: grid; gap: clamp(1rem,2vw,1.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%,15rem),1fr));
}
.family-card {
  background: var(--white); border-radius: var(--radius-md);
  padding: clamp(1.5rem,3vw,2rem); text-align: center;
  display: flex; flex-direction: column;
  box-shadow: inset 0 0 0 1px var(--rule);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.family-card:hover { transform: translateY(-4px); box-shadow: 0 14px 38px rgba(43,49,45,.12); }
.family-card__art { height: 76px; display: grid; place-items: center; margin-bottom: 1.25rem; }
.family-card__art img { max-height: 76px; width: auto; max-width: 100%; }
.family-card__art .rosette { width: 58px; }
.family-card__name { font-family: var(--font-display); font-size: 1.15rem; font-weight: 400; margin: 0 0 .2rem; }
.family-card__city { font-size: var(--fs-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--stone); margin: 0; }
.family-card__foot {
  margin: auto 0 0; padding-top: 1.1rem;
  font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--smoke);
}
.family-card--current { background: var(--sage); box-shadow: none; color: var(--white); }
.family-card--current:hover { transform: none; box-shadow: none; }
.family-card--current .family-card__city { color: var(--cream); opacity: .8; }
.family-card--current .family-card__foot { color: var(--cream); }

/* ============================================================
   CONTACT
   ============================================================ */
.contact-grid { display: grid; gap: clamp(2rem,5vw,4rem); grid-template-columns: 1fr; }
@media (min-width: 900px) { .contact-grid { grid-template-columns: .9fr 1.1fr; } }
.info-block + .info-block { margin-top: 2rem; padding-top: 2rem; border-top: 1px solid var(--rule); }
.section--sage .info-block + .info-block { border-color: var(--rule-inverse); }
.info-block .eyebrow { margin-bottom: .6rem; }
.info-block a { border-bottom: 1px solid currentColor; padding-bottom: 1px; }
.info-block p { margin-bottom: .3rem; }
.hours { display: grid; gap: .35rem; font-size: .97rem; }
.hours div { display: flex; justify-content: space-between; gap: 1.5rem; max-width: 22rem; }
.hours dt { opacity: .8; }

.map-frame { border-radius: var(--radius-md); overflow: hidden; background: var(--cream); aspect-ratio: 4/3; }
.map-frame iframe { width: 100%; height: 100%; border: 0; display: block; }

/* Form */
.form { display: grid; gap: 1.1rem; }
.form__row { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%,13rem),1fr)); }
.field { display: grid; gap: .4rem; }
.field label { font-size: var(--fs-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; opacity: .85; }
.field input, .field select, .field textarea {
  font: inherit; font-size: .97rem; color: inherit;
  padding: .8em 1em; border: 1px solid var(--rule); border-radius: var(--radius-sm);
  background: var(--white); width: 100%;
}
.section--sage .field input, .section--sage .field select, .section--sage .field textarea {
  background: rgba(255,255,255,.08); border-color: var(--rule-inverse); color: var(--white);
}
.section--sage .field select option { color: var(--ink); }
.field textarea { min-height: 7rem; resize: vertical; }
.form__note { font-size: var(--fs-small); opacity: .7; }

/* ============================================================
   CTA BAND
   ============================================================ */
.cta-band { background: var(--smoke); color: var(--white); text-align: center; padding-block: clamp(3.5rem,7vw,6rem); position: relative; overflow: hidden; }
.cta-band::before, .cta-band::after {
  content:""; position: absolute; width: min(34vw,380px); aspect-ratio: 1; border-radius: 50%;
  background: rgba(255,255,255,.09); pointer-events: none;
}
.cta-band::before { left: -8%; bottom: -40%; }
.cta-band::after  { right: -6%; top: -45%; }
.cta-band__inner { position: relative; z-index: 1; }
.cta-band .h1 { margin-bottom: .9rem; }
.cta-band .lead { margin: 0 auto 2rem; color: rgba(255,255,255,.88); }
.cta-band .btn-row { justify-content: center; }

/* ============================================================
   FOOTER
   ============================================================ */
.site-footer { background: var(--sage-deep); color: var(--white); padding-block: clamp(3rem,6vw,5rem) 2rem; }
.footer-top { display: grid; gap: clamp(2rem,4vw,3.5rem); grid-template-columns: repeat(auto-fit, minmax(min(100%,14rem),1fr)); }
.footer-brand { max-width: 22rem; }
.footer-brand .ring { width: 150px; margin: 0 0 1.25rem; }
.footer-brand .ring__img { animation-duration: 90s; }
.footer-brand p { font-size: var(--fs-small); color: var(--text-on-sage-muted); }
.footer-col h3 { font-size: var(--fs-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--cream); margin-bottom: 1.1rem; font-weight: 500; }
.footer-col li { margin-bottom: .6rem; }
.footer-col a, .footer-col p { font-size: var(--fs-small); color: var(--text-on-sage-muted); transition: color var(--dur) var(--ease); }
.footer-col a:hover { color: var(--white); }
.footer-col address { font-style: normal; font-size: var(--fs-small); color: var(--text-on-sage-muted); line-height: 1.8; }
.footer-bottom {
  margin-top: clamp(2.5rem,5vw,4rem); padding-top: 1.5rem; border-top: 1px solid var(--rule-inverse);
  display: flex; flex-wrap: wrap; gap: 1rem 2rem; justify-content: space-between; align-items: center;
  font-size: .78rem; color: rgba(255,255,255,.6);
}
.footer-bottom a { border-bottom: 1px solid transparent; }
.footer-bottom a:hover { border-color: currentColor; }
.footer-legal { max-width: 46rem; font-size: .72rem; line-height: 1.6; }

/* Mobile footer order: ring centred on its own row, then Visit beside the
   blurb, then Explore beside Contact. The ring and the blurb are siblings
   inside .footer-brand, so display:contents dissolves that wrapper and lets
   both sit directly in the grid — only then can `order` interleave them with
   the columns. Source order stays sensible for screen readers. */
@media (max-width: 700px) {
  .footer-top { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
  .footer-brand { display: contents; }
  .footer-brand .ring { grid-column: 1 / -1; order: 1; margin: 0 auto 1.75rem; }
  .footer-col--visit   { order: 2; }
  /* The Visit column carries an h3; the blurb does not, so left to itself it
     floats a heading's height higher than the address beside it. Bottom-align
     it so the two blocks finish on the same line. */
  .footer-brand p      { order: 3; margin: 0; align-self: end; }
  .footer-col--explore { order: 4; }
  .footer-col--contact { order: 5; }
  /* the email is one long token and would otherwise push past a half-width column */
  .footer-col a { overflow-wrap: anywhere; }
}
/* Below this the two columns get too narrow to read, so it stacks — the order
   above still applies, giving ring, Visit, blurb, Explore, Contact. */
@media (max-width: 400px) {
  .footer-top { grid-template-columns: 1fr; }
  .footer-brand .ring { grid-column: 1; }
}

/* ============================================================
   FAMILY STRIP
   A deliberate light break between the Smoky Blue CTA band and
   the Succulent footer. The sibling logos are full-colour
   lockups with black wordmarks, so they need a light ground —
   and the palette break reads as "this is the wider family,
   not this building".
   ============================================================ */
.family-strip {
  background: var(--cream-warm); color: var(--ink);
  padding-block: clamp(3rem,6vw,5rem); text-align: center;
  position: relative; overflow: hidden;
}
.family-strip .eyebrow { color: var(--smoke); }
.family-strip .h2 { margin-bottom: .6rem; }
.family-strip__intro { max-width: 52ch; margin: 0 auto; color: var(--text-muted); font-size: var(--fs-small); }
.family-strip__logos {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.25rem,3vw,2.5rem) clamp(1rem,2.5vw,2rem);
  margin-block: clamp(2.25rem,4vw,3.25rem);
  align-items: start;
}
@media (max-width: 900px) { .family-strip__logos { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 420px) { .family-strip__logos { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------
   Two rules keep the nine lockups optically aligned:

   1. Every tile shares the SAME two-row grid — a fixed caption
      row, then the logo row — with the image explicitly placed
      in row 2. The caption row is reserved even on the eight
      tiles that have no caption, so Giroux's "You are here"
      cannot push its logo out of line with the others.
   2. The logos are constrained by HEIGHT, not width. Their
      aspect ratios span 1.83–1.91, so at a fixed width their
      heights would differ by 4.3% and the wordmarks would
      visibly drift. At a fixed height the wordmark bands agree
      to within 1.7%, because all nine share the same internal
      lockup layout (hat / THE HAT / place name).
   ------------------------------------------------------------ */
.family-logo {
  display: grid; grid-template-rows: var(--fam-cap-h) auto;
  /* The gap must live on the grid, not as a margin on the caption. Applied
     here it separates the two rows on every tile identically, so the logo row
     shifts down by the same amount on all nine and the alignment survives. */
  row-gap: var(--fam-cap-gap);
  justify-items: center; align-items: center;
  padding: .75rem .5rem; border-radius: var(--radius-md);
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.family-logo img {
  grid-row: 2;
  height: var(--fam-logo-h); width: auto; max-width: 100%;
  /* Each sibling brand keeps its own accent colour; the wordmarks are
     black, which sits fine on the cream ground. */
  transition: opacity var(--dur) var(--ease);
  opacity: .88;
}
.family-logo:hover { background: var(--white); transform: translateY(-3px); }
.family-logo:hover img { opacity: 1; }
/* Current property: shown, not linked, captioned ABOVE the lockup. */
.family-logo--current img { opacity: 1; }
.family-logo--current small {
  grid-row: 1; align-self: end;
  font-size: .62rem; letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase; color: var(--stone);
}

/* ============================================================
   PLACEHOLDER GRAPHIC (v1 only — swap for real photography)
   ============================================================ */
.ph { display: grid; place-items: center; width: 100%; height: 100%; background: var(--sea); color: var(--white); position: relative; overflow: hidden; }
.ph--cream { background: var(--cream); color: var(--sage); }
.ph--sage  { background: var(--sage);  color: var(--cream); }
.ph--stone { background: var(--stone); color: var(--white); }
.ph--smoke { background: var(--smoke); color: var(--cream); }
.ph::before {
  content:""; position: absolute; inset: -10%;
  background: url("../assets/brand/rosette.svg") center/58% no-repeat;
  opacity: .16;
}
.ph__label {
  position: relative; z-index: 1; text-align: center; padding: 1rem;
  font-size: .68rem; font-weight: 500; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase;
  line-height: 1.7; opacity: .82;
}

/* ---------- Reveal on scroll ---------- */
[data-reveal] { opacity: 0; transform: translateY(22px); transition: opacity .9s var(--ease), transform .9s var(--ease); }
[data-reveal].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { [data-reveal] { opacity: 1; transform: none; } }

/* ---------- Utilities ---------- */
.center { text-align: center; }
.mt-0 { margin-top: 0; } .mb-0 { margin-bottom: 0; }
.stack > * + * { margin-top: 1rem; }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
