/* ==========================================================================
   Birchwood Living — site.css
   Tokens are design-brief-v2.md's `## Tokens` block verbatim.
   No box-shadow exists in this file. Depth is hairlines, white photo frames,
   ground changes and overlap only. Radius is non-zero on controls only.
   ========================================================================== */

/* --- fonts: self-hosted, latin subset, nothing fetched at runtime --------- */
@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/archivo-latin-var.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Source Serif 4";
  src: url("/assets/fonts/source-serif-4-latin-var.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ---- colour: the reference palette, restored ---------------------------
     Round 1 substituted the client's logo palette (slate #2E343A, crimson
     #C2456A) for the reference's. The client's four-colour tree mark keeps its
     own colours inside the logo drawing and nowhere else; site chrome is the
     three literals acoe.jp declares in its own stylesheet plus its hairline.

     Measured contrast (design-brief-v2.md § Color):
       --ink   on --paper  10.34:1     --paper on --ink     10.34:1
       --ink   on --accent 10.09:1     --accent on --ink    10.09:1
       --muted on --paper   5.97:1     --muted on --panel    7.35:1
       --accent on --paper  1.07:1  <- INVISIBLE. See the rule below. */
  --paper: #EAE8DB;
  --panel: #FFFFFF;
  --ink: #28322E;
  --accent: #F9E169;
  --rule: #D9D6BF;
  --rule-strong: #8F8B72;
  --muted: #4F5854;
  --rule-field: #6E7A73;
  --scrim: rgba(0, 0, 0, .05);
  /* .76 is not a taste value. It is the lightest scrim that still guarantees
     --paper text clears 4.5:1 over a *pure white* photograph, which is the
     worst case; over a real photograph it reads as the reference's dark
     collage. It is the only way type is ever placed on an image here. */
  --photo-scrim: rgba(40, 50, 46, .76);

  /* --accent is a GROUND, a decorative graphic, or an accent on --ink.
     It is never text, never a hairline, never a border and never a focus ring
     on --paper: 1.07:1. Every use in this file obeys that. */

  /* type */
  --display: "Archivo", system-ui, sans-serif;
  --text: "Source Serif 4", Georgia, serif;

  --fs-display-xl: 96px;  --lh-display-xl: 88px;
  --fs-display-l: 64px;   --lh-display-l: 64px;
  --fs-rent: 40px;        --lh-rent: 40px;
  --fs-h2: 44px;          --lh-h2: 48px;
  --fs-h3: 26px;          --lh-h3: 32px;
  --fs-lead: 20px;        --lh-lead: 32px;
  --fs-body: 17px;        --lh-body: 27px;
  --fs-small: 14.5px;     --lh-small: 21px;
  --fs-label: 13px;       --lh-label: 16px;
  /* the two composition sizes v1 had no token for */
  --fs-cascade: clamp(40px, 7.4vw, 108px);
  --fs-statement: clamp(44px, 7.4vw, 104px);

  /* space — base 4px */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s6: 24px;
  --s8: 32px; --s12: 48px; --s16: 64px; --s24: 96px; --s30: 120px;
  --container: 1200px;
  --sec-y: 120px;
  --hero-top: 120px;
  --hero-bot: 120px;

  /* radius + depth */
  --r-media: 0; --r-panel: 0; --r-input: 0;
  --r-pill: 40px; --r-circle: 9999px;
  --frame: 2px solid var(--panel);
  --hair: 1px solid var(--rule);
  /* box-shadow is not a token. Nothing on this site casts a shadow. */

  /* motion */
  --dur-fast: .15s; --dur: .3s; --dur-slow: .5s;
  --ease: cubic-bezier(.4, 0, .2, 1);

  --header-h: 72px;
}

/* --- reset / base -------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--s16));
  /* clip, never hidden: it does not create a scroll container, so the sticky
     header and the sticky rails keep working. A guard, not a fix — and it is
     load-bearing now that the ribbon and the photo rail bleed past 100vw. */
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--text);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-variant-numeric: tabular-nums;
}

h1, h2, h3, h4 { margin: 0; font-weight: 400; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }
dl, dd { margin: 0; }
img { display: block; max-width: 100%; height: auto; border-radius: var(--r-media); }
figure { margin: 0; }
table { border-collapse: collapse; width: 100%; }

/* Links are --ink with an underline. The accent cannot do this job: #F9E169 on
   #EAE8DB is 1.07:1, so a yellow link would be invisible and would also make
   colour the only marker (WCAG 1.4.1). The reference's links are ink too. */
a { color: var(--ink); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--muted); }
a, button, input, select, textarea, summary {
  transition-property: color, background-color, border-color, opacity;
  transition-duration: var(--dur);
  transition-timing-function: var(--ease);
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.site-footer :focus-visible,
.section--ink :focus-visible,
.hero--ink :focus-visible,
.band--statement :focus-visible,
.comm-index :focus-visible,
.split__pane :focus-visible { outline-color: var(--paper); }
/* on the accent band the ground is #F9E169, where --paper would be 1.06:1 */
.section--accent :focus-visible { outline-color: var(--ink); }

/* --- utility ------------------------------------------------------------- */
.wrap { width: min(var(--container), 100% - 32px); margin-inline: auto; }
/* A band runs 0 -> 100vw regardless of the container it is written inside.
   This is what makes the page a sequence of grounds rather than a column of
   sections on one ground — brand.md § Composition, "Full-bleed colour blocks". */
.bleed {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

.display {
  font-family: var(--display);
  font-weight: 400;
  font-stretch: 118%;
  text-transform: uppercase;
}
/* WCAG 1.4.12 Text Spacing. The four metrics a reader may impose — 1.5x line
   height, 2x paragraph spacing, 0.12em letter spacing, 0.16em word spacing —
   push a single long uppercase display word past the viewport at 320px, and
   `html { overflow-x: clip }` then cuts the end off it rather than scrolling
   to it, which is loss of content. Breaking the word is ugly; losing half of
   it is a failure. This only ever engages when one word is wider than its
   line, so at every normal setting it changes nothing. */
.display, .cascade, .cascade__line, .statement, .footer-word, h1, h2, h3 { overflow-wrap: break-word; }
.d-xl { font-size: min(var(--fs-display-xl), 7.4vw); line-height: .95; letter-spacing: -.014em; }
.d-l  { font-size: var(--fs-display-l); line-height: var(--lh-display-l); letter-spacing: -.01em; }
h2, .h2 { font-family: var(--display); font-weight: 500; font-stretch: 110%; text-transform: uppercase;
          font-size: var(--fs-h2); line-height: var(--lh-h2); letter-spacing: normal; }
h3, .h3 { font-family: var(--display); font-weight: 500; font-stretch: 112%; text-transform: uppercase;
          font-size: var(--fs-h3); line-height: var(--lh-h3); }
.lead { font-size: var(--fs-lead); line-height: var(--lh-lead); }
.small { font-size: var(--fs-small); line-height: var(--lh-small); }
.measure { max-width: 66ch; }
/* The 13px +0.06em uppercase token. It is a COLUMN HEADER and a SPEC TERM and
   nothing else — never an eyebrow above a heading, which is the commonest
   generated-page tell (round 1, finding 2; design-brief-v2.md pass 2, 5a). */
.label {
  font-family: var(--display); font-weight: 500; font-stretch: 112%;
  font-size: var(--fs-label); line-height: var(--lh-label);
  letter-spacing: .06em; text-transform: uppercase;
}
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: var(--s4); top: -100px; z-index: 200;
  background: var(--ink); color: var(--paper); padding: var(--s3) var(--s6);
  border-radius: var(--r-pill); text-decoration: none;
}
.skip-link:focus { top: var(--s3); color: var(--paper); }

/* --- the ribbon ----------------------------------------------------------
   The site's signature device (brand.md § Composition). The weave is two
   layers: the ribbon under the display type, and one strand over it. Round 4
   shipped the over-layer as a full-hero `--front` SVG on all 30 routes, which
   put it across 28 page titles and under the home cascade — misplaced in both
   directions at once. There is no `--front` layer any more. Everything at
   hero scale is `--back`, and the single crossing the device needs lives
   inside the cascade line it crosses, as `.cascade__weave` below.

   Decorative, aria-hidden, pointer-events: none — it carries no information,
   so its 1.07:1 against the ground is not a 1.4.11 concern, and for the same
   reason it may never be the only marker of anything. Four placements
   site-wide, not one per section. */
.ribbon {
  position: absolute; left: 50%; transform: translateX(-50%);
  width: 100vw; height: 100%; top: 0;
  pointer-events: none;
  fill: none;
  stroke: var(--accent);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ribbon--back { z-index: 0; }
.ribbon--white { stroke: var(--panel); }
/* Round 6. A stroke has ONE width for its whole length, and a constant thick
   stroke is exactly what made the hero ribbon read as a marker scribble rather
   than a drawn line. The hero ribbons are now outlines that are filled, so the
   line tapers: ~3px at the ends and ~9px at its heaviest. They also drop
   preserveAspectRatio="none" for "xMidYMid slice", because a filled outline
   under a non-uniform scale would be stretched to a different weight at every
   hero height — which is the same bug, arrived at from the other side. And
   there is one primary line with one short secondary, not four strands: the
   round-4 hero had a near-vertical run down the right edge crossing another
   strand at close to a right angle, which is what read as a scribble. */
.ribbon--drawn {
  fill: var(--accent); stroke: none;
  /* A drawn outline has to be scaled UNIFORMLY or the line is a different
     weight at every hero height, which is the round-4 preserveAspectRatio bug
     arrived at from the other side. Each drawn ribbon's viewBox is the
     measured box of the hero it belongs to at 1440, so at 1440 one unit is one
     pixel and the drawing is exact; slice keeps the scale uniform elsewhere
     and lets the line bleed past the edges, which is what the reference does.
     The 1440px cap is the other half of the same idea: the content container
     stops growing at 1200, so if the ribbon kept spanning the viewport its
     geometry would slide across the type as the window widened — at 2000 the
     primary line ran straight behind the hero paragraph, which at 1440 it
     passes well below. Capped, the composition at 1440 IS the composition at
     2560, with 120px of bleed each side of the container. */
  width: min(100vw, 1440px);
}
.ribbon--drawn.ribbon--white { fill: var(--panel); }
/* The weave. Round 4 measured 3 of 916 glyph columns touched on / — the front
   strand ran UNDER the cascade rather than through it, so the home page was
   the one page missing the signature device. It is no longer a full-hero
   overlay guessing at where the letters are: it is anchored inside the last
   cascade line, whose box is the text's own box (width: fit-content), so it
   crosses the same four letters near their bottoms at every size. ~7% of cap
   height at a shallow angle, which is the ratio the reference uses on ONE
   ROOF. It is a positioned descendant of the line, so it paints above the
   line's own inline text without needing a z-index. */
.cascade__weave {
  position: absolute; inset: 0; width: 100%; height: 100%;
  overflow: visible; pointer-events: none;
  fill: var(--accent); stroke: none;
}
.has-ribbon { position: relative; }
.has-ribbon > .wrap { position: relative; }
/* Everything in the wrap paints ABOVE the front strand by default, so a
   yellow stroke can never land on a pill label or a line of copy. The display
   type is the one exception and is listed second so it wins on specificity:
   being crossed is the device. `.home-hero` is named rather than the `h1`
   inside it because the h1 is not a direct child there. */
.has-ribbon > .wrap > * { position: relative; z-index: 3; }
.has-ribbon > .wrap > h1,
.has-ribbon > .wrap > .home-hero,
.has-ribbon > .wrap > .statement { z-index: 1; }

/* --- section rhythm ------------------------------------------------------ */
.section { padding-block: var(--sec-y); }
.section--tight { padding-block: var(--s16); }
.section--ink { background: var(--ink); color: var(--paper); padding-block: var(--sec-y); }
.section--ink a:not(.btn) { color: var(--paper); }
.section--ink .rule, .section--ink hr { border-color: rgba(234, 232, 219, .3); }
/* the #F9E169 full-bleed band — home-03/04. Ink on it is 10.09:1. */
.section--accent { background: var(--accent); color: var(--ink); padding-block: var(--sec-y); }
.section--accent a:not(.btn) { color: var(--ink); }
.hero { padding-block: var(--hero-top) var(--hero-bot); }
.hero--tight { padding-bottom: var(--s12); }
.hero--tighter { padding-bottom: var(--s8); }
.hero--ink { background: var(--ink); color: var(--paper); padding-block: 128px var(--s16); }
.section > * + .block, .block + .block { margin-top: var(--s12); }
.section-head + * { margin-top: 40px; }
.body + .actions, .measure + .actions { margin-top: var(--s6); }
.prose p + p { margin-top: var(--s6); }

/* --- header --------------------------------------------------------------
   The reference's header is three elements and no bottom rule: the boundary
   between header and page is the ground change alone (brand.md § Composition).
   Round 3's header carried a mark, a wordmark, five links, a phone number, a
   TTY string, a hairline, two buttons and a border. The chrome goes; the link
   list stays, because hiding five links behind a hamburger at 1440px trades a
   real usability regression for a silhouette. */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--paper);
}
.site-header__bar {
  min-height: var(--header-h);
  display: flex; align-items: center; gap: var(--s8);
}
.brand { display: flex; align-items: center; gap: var(--s3); text-decoration: none; color: var(--ink); flex: 0 0 auto; }
.brand:hover { color: var(--ink); }
/* The client's confirmed mark: the geometric BRG monogram, white bevelled
   letters on their own black plaque, derived from BRG-Profile-png.png (see
   MARK_IMG in scripts/gen.py). It is a WIDE lockup — 1.728:1 after the 6%
   plaque margin — so it is sized by height and given `width:auto`; nothing
   here may force it square, and the header bar must not letterbox it.
   Square corners, because it is media, not a control. */
.brand__mark { height: 38px; width: auto; display: block; flex: 0 0 auto; }
.brand__word {
  font-family: var(--display); font-weight: 500; font-stretch: 122%;
  text-transform: uppercase; font-size: 21px; letter-spacing: -.01em; line-height: 1;
}
.site-nav { margin-left: auto; display: flex; align-items: center; gap: var(--s8); }
.site-nav .site-header__contact, .site-nav > .btn { display: none; }
.site-nav__list { display: flex; align-items: center; gap: var(--s6); }
.site-nav__link {
  font-family: var(--display); font-weight: 500; font-stretch: 108%;
  font-size: 16px; line-height: 22px;
  color: var(--ink); text-decoration: none; padding-block: var(--s3);
  border-bottom: 2px solid transparent;
}
.site-nav__link:hover { color: var(--muted); }
/* --accent here would be 1.07:1 on --paper, i.e. no marker at all. */
.site-nav__link[aria-current="page"] { border-bottom-color: var(--ink); }
.site-header__contact {
  font-size: var(--fs-small); line-height: var(--lh-small);
  display: flex; gap: var(--s4); align-items: center; white-space: nowrap;
}
.site-header__contact .hairline {
  width: 1px; align-self: stretch; margin-block: 2px; background: var(--rule);
}
.site-header__contact a { color: var(--ink); text-decoration: none; }
.site-header__contact a:hover { color: var(--muted); text-decoration: underline; }
.site-header__actions { display: flex; gap: var(--s2); flex: 0 0 auto; align-items: center; }
.nav-toggle { display: none; }

/* --- buttons -------------------------------------------------------------
   Three filled treatments plus the arrow badge. The badge is a 24px circle
   with its own ground inside the pill, carrying a 45-degree glyph — it is not
   a "→" appended to a text run. It is aria-hidden and the pill's own label is
   the complete accessible name. Evidence for it: brand.md § Composition,
   "Arrow badges", which lists every pill on the reference that carries one. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s4);
  min-height: 44px; padding: 0 var(--s6);
  font-family: var(--display); font-weight: 500; font-stretch: 108%;
  font-size: 16px; line-height: 20px;
  border-radius: var(--r-pill); border: 1px solid transparent;
  text-decoration: none; cursor: pointer;
  transition-property: color, background-color, border-color;
  transition-duration: var(--dur-slow);
  transition-timing-function: var(--ease);
}
.btn__badge {
  flex: 0 0 26px; width: 26px; height: 26px;
  display: inline-grid; place-items: center;
  border-radius: var(--r-circle);
}
.btn__badge svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.7; }
/* a pill WITH a badge pulls its right padding in so the badge sits inset.
   Written this way round on purpose: where :has() is unsupported the rule is
   dropped and every pill stays symmetrically padded, which is the harmless
   outcome. The inverse selector would have left badge-less pills lopsided. */
.btn:has(.btn__badge) { padding-right: var(--s3); }

.btn--primary { background: var(--ink); color: var(--paper); }
.btn--primary:hover { background: #1B2320; color: var(--paper); }
.btn--primary .btn__badge { color: var(--accent); background: rgba(234, 232, 219, .12); }
/* The site's main filled pill. Ink ground, paper label, accent badge — which
   is the reference's own "Find Your Stay". Kept on the class name every page
   function already calls, so this is a restyle and not 30 edits. */
.btn--accent { background: var(--ink); color: var(--paper); }
.btn--accent:hover { background: #1B2320; color: var(--paper); }
.btn--accent .btn__badge { color: var(--accent); background: rgba(234, 232, 219, .12); }
/* The yellow pill. ONLY over a photograph or on an --ink ground: on --paper
   its own edge would be 1.07:1, so the control's boundary would be invisible
   (WCAG 1.4.11). Ink label on it is 10.09:1. */
.btn--gold { background: var(--accent); color: var(--ink); }
.btn--gold:hover { background: #F4D33F; color: var(--ink); }
.btn--gold .btn__badge { color: var(--ink); background: rgba(40, 50, 46, .12); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn--ghost:hover { background: var(--ink); color: var(--paper); }
.btn--ghost .btn__badge { color: currentColor; }
.btn:active { border-color: var(--ink); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }
.section--ink .btn--primary, .section--ink .btn--accent,
.hero--ink .btn--primary, .hero--ink .btn--accent,
.band--statement .btn--accent, .comm-index .btn--accent {
  background: var(--accent); color: var(--ink);
}
.section--ink .btn--primary:hover, .section--ink .btn--accent:hover,
.hero--ink .btn--primary:hover, .hero--ink .btn--accent:hover,
.band--statement .btn--accent:hover, .comm-index .btn--accent:hover {
  background: #F4D33F; color: var(--ink);
}
.section--ink .btn--accent .btn__badge, .section--ink .btn--primary .btn__badge,
.hero--ink .btn--accent .btn__badge, .hero--ink .btn--primary .btn__badge,
.band--statement .btn--accent .btn__badge, .comm-index .btn--accent .btn__badge {
  color: var(--ink); background: rgba(40, 50, 46, .12);
}
.section--ink .btn--ghost, .hero--ink .btn--ghost,
.band--statement .btn--ghost, .comm-index .btn--ghost { color: var(--paper); border-color: var(--paper); }
.section--ink .btn--ghost:hover, .hero--ink .btn--ghost:hover,
.band--statement .btn--ghost:hover, .comm-index .btn--ghost:hover { background: var(--paper); color: var(--ink); }
.actions { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }
.icon-btn {
  width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-circle); border: 1px solid var(--ink);
  background: transparent; color: var(--ink); cursor: pointer;
  transition-property: color, background-color; transition-duration: .2s; transition-timing-function: var(--ease);
}
.icon-btn:hover { background: var(--ink); color: var(--paper); }

/* --- W1: the cascade ----------------------------------------------------
   home-00, measured at 1440x900: TOGETHER x=293, UNDER x=450, ONE ROOF x=453.
   Line 1 sets the left edge; lines 2 and 3 step right together and the last
   line is the longest, so the silhouette is a wedge opening to the right. It
   is a stagger — not a left-aligned block and not a centred one.

   ROUND 6, THE COLLISION. The first build gave the h1 the whole container and
   parked the paragraph inside its right-hand portion with position:absolute.
   Measured with CDP, the two boxes intersected at 1280, 1440, 1600, 1800, 2000
   and 2560 — every width — and the long middle line ran straight through the
   copy. A nudge cannot fix that, because the two elements were sharing one
   rectangle by construction. They are now two grid TRACKS: the display column
   and the copy column cannot occupy the same space at any width, and the only
   thing that has to be checked is that the longest line fits its own track. */
/* tall enough that the rail below it starts at about 70% of a 900px
   viewport and is therefore cut by the fold, as it is on home-00 */
.hero--home { padding-block: var(--s30) var(--s16); overflow: hidden; }
.home-hero {
  position: relative;
  /* The wrap's own width, restated in viewport units so it can be used inside
     a font-size calc (a percentage there would resolve against the parent font
     size, not the container). 40px rather than the wrap's 32px gutter is a
     deliberate 8px of slack for a classic scrollbar, which 100vw includes and
     the wrap's 100% does not. */
  --hero-w: min(var(--container), calc(100vw - 40px));
  --hero-copy-w: clamp(244px, 21vw, 300px);
  --hero-disp-w: calc(var(--hero-w) - var(--hero-copy-w) - var(--s8));
  /* 1 - the deepest cascade indent below. Kept as a unitless factor because a
     percentage cannot be divided inside the fit calc. */
  --cascade-room: .84;
  /* The divisor is the MEASURED advance width, in em, of the longest cascade
     line set in Archivo 400 at font-stretch 122% and -.022em. Archivo at 122%
     is wide: the first pass guessed 6.55em and the line overflowed its track
     by 213px at 1440, which is the round-4 bug in a new place. Measured with
     CDP instead: "APARTMENT" is the widest of the three at 7.49em, not "BUILDINGS".
     Dividing the display track by it is what guarantees the longest line fits
     its own column rather than running into the copy column or off the
     container — re-measured at 320/768/1280/1440/1920/2560 after every change
     to the cascade text. If the copy changes, re-measure and update this. */
  --cascade-size: min(var(--fs-cascade), calc(var(--hero-disp-w) * var(--cascade-room) / 7.6));
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--hero-copy-w);
  column-gap: var(--s8);
  align-items: start;
}
.cascade { grid-column: 1; grid-row: 1; display: block; }
.cascade__line {
  display: block; width: fit-content; white-space: nowrap; position: relative;
  font-family: var(--display); font-weight: 400; font-stretch: 122%;
  text-transform: uppercase;
  font-size: var(--cascade-size); line-height: .92; letter-spacing: -.022em;
}
/* The reference's stagger, rescaled to the display track rather than the whole
   container: on home-00 the indents are 14.4% and 27.5% of a container whose
   display block runs to 79% of it, i.e. 18% and 35% of the block itself. Here
   the copy column is a real track rather than an overlay, so the block is
   narrower and the step is shallower — the wedge is the same shape, opening to
   the right, with the longest line last. */
.cascade__line:nth-child(1) { margin-left: 6%; }
.cascade__line:nth-child(2) { margin-left: 16%; }
.cascade__line:nth-child(3) { margin-left: 16%; }
/* The paragraph sits in the RIGHT-HAND TRACK and level with the middle line —
   the reference's arrangement, x 890-1145 against UNDER at y 290-370. The
   offset is a multiple of the cascade's own size, so it tracks the type. */
.home-hero__copy {
  grid-column: 2; grid-row: 1; align-self: start;
  margin-top: calc(var(--cascade-size) * .82);
  font-size: var(--fs-body); line-height: 26px;
}
.home-hero__cta { grid-column: 1; grid-row: 2; margin-top: var(--s12); margin-left: 16%; }

/* --- W1: the staggered photo rail ---------------------------------------
   home-00/home-01 are one element across two viewports: a horizontal run of
   property photographs at six different widths and a 45px sawtooth of vertical
   offsets, bleeding off both viewport edges and deliberately cut by the fold.

   It is NOT a marquee. The reference animates its equivalent with @keyframes;
   Birchwood's animation budget is CSS transitions and scroll reveal only, and
   a perpetually moving band is the wrong instinct for a page whose job is to
   let someone read ten rents. It is a plain scroll container the reader drives.
   brand.md § Motion, "What Birchwood may and may not carry across". */
.rail {
  position: relative; z-index: 3;
  margin-top: var(--s24);
  display: flex; align-items: flex-start; gap: var(--s6);
  overflow-x: auto; overflow-y: hidden;
  padding-bottom: var(--s6);
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
}
.rail__item {
  flex: 0 0 auto; scroll-snap-align: center;
  text-decoration: none; color: var(--ink);
}
.rail__item img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; border: var(--frame); }
.rail__cap { display: block; padding-top: var(--s3); }
.rail__name {
  display: block;
  font-family: var(--display); font-weight: 500; font-stretch: 112%;
  text-transform: uppercase; font-size: 17px; line-height: 22px; letter-spacing: normal;
}
.rail__where { display: block; font-size: var(--fs-small); line-height: var(--lh-small); color: var(--muted); }
.rail__item:hover .rail__name { color: var(--muted); }
/* the sawtooth: six widths, four offsets, cycling. Irregular on purpose — a
   regular grid is the thing this element exists not to be. */
.rail__item:nth-child(6n+1) { width: 260px; margin-top: 44px; }
.rail__item:nth-child(6n+2) { width: 320px; margin-top: 0; }
.rail__item:nth-child(6n+3) { width: 240px; margin-top: 68px; }
.rail__item:nth-child(6n+4) { width: 300px; margin-top: 20px; }
.rail__item:nth-child(6n+5) { width: 250px; margin-top: 52px; }
.rail__item:nth-child(6n+6) { width: 340px; margin-top: 8px; }

/* --- full-bleed statement band: display type over a photograph -----------
   The only place on the site where type sits on an image. The scrim is fixed
   at --photo-scrim so --paper text clears 4.5:1 over any photograph including
   a white one. Per brand.md § Imagery the statement is always restated in
   plain body copy beneath, and it is never used over an interior. */
.band--statement {
  position: relative; isolation: isolate;
  min-height: 460px; display: grid; align-items: center;
  padding-block: var(--s24);
  color: var(--paper); background: var(--ink);
}
.band--statement > img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
}
.band--statement::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--photo-scrim);
}
.statement {
  font-family: var(--display); font-weight: 400; font-stretch: 118%;
  text-transform: uppercase;
  font-size: var(--fs-statement); line-height: .96; letter-spacing: -.018em;
}
.band--statement .measure { margin-top: var(--s8); max-width: 54ch; }

/* --- the community index rows (on --ink) ---------------------------------
   home-06 / index-homes-00 draw a yellow chip carrying an ordinal, 01..13.
   Birchwood's four communities are not a sequence, so the same chip carries
   the count of apartments available there. Same device, real information —
   see design-brief-v2.md pass 2, "Numbered markers". */
.comm-index { background: var(--ink); color: var(--paper); padding-block: var(--sec-y); }
.comm-index a:not(.btn) { color: var(--paper); }
.comm-index__head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 420px); gap: var(--s16); align-items: end; }
.comm-list { margin-top: var(--s16); border-top: 1px solid rgba(234, 232, 219, .3); }
.comm-row {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) minmax(0, 220px) 140px;
  gap: var(--s6); align-items: center;
  padding: var(--s6) 0; border-bottom: 1px solid rgba(234, 232, 219, .3);
  text-decoration: none; color: var(--paper);
  transition-property: background-color; transition-duration: var(--dur); transition-timing-function: var(--ease);
}
.comm-row:hover { background: rgba(234, 232, 219, .07); color: var(--paper); }
.chip {
  display: grid; place-items: center; width: 44px; height: 52px;
  background: var(--accent); color: var(--ink);
  font-family: var(--display); font-weight: 600; font-stretch: 112%;
  font-size: 22px; line-height: 1; font-variant-numeric: tabular-nums lining-nums;
}
.chip__n { display: block; }
.comm-row__name {
  display: block;
  font-family: var(--display); font-weight: 400; font-stretch: 118%;
  text-transform: uppercase; font-size: 34px; line-height: 40px; letter-spacing: -.01em;
}
.comm-row__where { display: block; }
.comm-row__where, .comm-row__street { font-size: var(--fs-small); line-height: var(--lh-small); color: rgba(234, 232, 219, .72); }
.comm-row__from { text-align: right; white-space: nowrap; font-size: var(--fs-lead); }

/* --- panel that overlaps the band above it -------------------------------
   home-08: a #FFFFFF panel 1200px wide sitting ON TOP of the full-bleed band
   behind it, with the band visibly running out from under its top and sides.
   The reference produces it with a sticky -100vh scrub; this is the same
   picture with a negative margin and no scroll listener. */
.panel--lift { margin-top: calc(-1 * var(--s16)); position: relative; z-index: 2; }
.section--lifted { padding-top: 0; }

/* --- the Rent Ledger ----------------------------------------------------- */
.ledger { width: 100%; }
.ledger__head th {
  font-family: var(--display); font-weight: 500; font-stretch: 112%;
  text-transform: uppercase; font-size: var(--fs-label); line-height: var(--lh-label);
  letter-spacing: .06em; text-align: left; padding: 0 var(--s6) var(--s3);
  border-bottom: 2px solid var(--rule-strong); color: var(--ink);
}
.ledger__head th:last-child { text-align: right; }
/* RESPONSIVE AUDIT, round 5 — WCAG 1.4.10 Reflow.
   The Rent Ledger is a data table, and 1.4.10 explicitly exempts data tables
   from the no-two-dimensional-scrolling rule. What it does not exempt is
   losing the table: between 900px (where the ledger reflows to blocks) and
   ~1100px the table needed 759px inside a 672px content box, and because
   `html { overflow-x: clip }` guards the page, the right-hand columns were
   silently cut off rather than scrolled to. A scroll container is the correct
   answer for a table and restores the lost columns. */
.ledger-panel { background: var(--panel); border: var(--hair); padding: var(--s8) var(--s8) 0; overflow-x: auto; }
/* Round 3, finding 1. Only the address was a link: the row measured
   1150x145 and the <a> inside it 495x49 — 17.6% of it — so the photo, the
   size, the availability date, the rent and the row arrow were all dead, on
   seven routes, including the home page where the rows are the conversion
   path. The link now stretches over its whole row. */
.ledger__row { border-bottom: var(--hair); position: relative; }
.ledger__link::after { content: ""; position: absolute; inset: 0; }
.ledger__go { position: relative; z-index: 1; }
.ledger__row:last-child { border-bottom: 0; }
.ledger__cell { padding: var(--s6) var(--s6) var(--s6) 0; vertical-align: middle; }
.ledger__c-photo { width: 120px; }
.ledger__c-rent { text-align: right; white-space: nowrap; padding-right: 0; }
.ledger__c-avail { white-space: nowrap; }
.ledger__link { display: block; text-decoration: none; color: var(--ink); }
.ledger__link:hover { color: var(--ink); }
.ledger__row:hover .ledger__addr, .ledger__link:hover .ledger__addr { color: var(--muted); }
.ledger__photo {
  width: 96px; height: 96px; object-fit: cover;
  border: var(--frame); background: var(--rule);
}
.ledger__addr {
  font-family: var(--display); font-weight: 500; font-stretch: 118%;
  text-transform: uppercase; font-size: 21px; line-height: 26px; letter-spacing: normal;
  transition-property: color; transition-duration: var(--dur); transition-timing-function: var(--ease);
}
.ledger__addr, .ledger__where, .ledger__spec, .ledger__sqft, .ledger__avail { display: block; }
.ledger__where { font-size: var(--fs-small); line-height: var(--lh-small); color: var(--muted); margin-top: 2px; }
.ledger__spec { font-size: var(--fs-body); line-height: var(--lh-body); }
.ledger__sqft { font-size: var(--fs-small); color: var(--muted); }
.ledger__avail { font-size: var(--fs-body); }
.ledger__avail--none { color: var(--muted); }
/* The rent's prominence is its size, not a colour. The accent cannot set text
   on --panel (1.14:1) and the ledger is no longer the page's opening argument,
   so it gets quieter rather than louder. */
.ledger__rent {
  font-family: var(--display); font-weight: 600; font-stretch: 118%;
  font-size: var(--fs-rent); line-height: var(--lh-rent); letter-spacing: -.012em;
  color: var(--ink); font-variant-numeric: tabular-nums lining-nums;
  display: block;
}
.ledger__per { display: block; font-size: var(--fs-small); color: var(--muted); }
.ledger__rent-foot { display: flex; align-items: baseline; justify-content: flex-end; gap: var(--s6); }
.ledger__go { font-size: 20px; line-height: 1; color: var(--muted); }
.ledger__foot {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s3);
  border-top: var(--hair); padding: var(--s4) 0;
  font-size: var(--fs-small); color: var(--muted);
}
.ledger-panel .ledger__foot { padding: var(--s4) 0; }
.ledger-sort { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; }
.ledger-sort__lab { font-size: var(--fs-small); color: var(--muted); }
.sort-btn {
  font-family: var(--display); font-weight: 500; font-stretch: 108%;
  font-size: 15px; line-height: 20px;
  background: transparent; border: 1px solid var(--rule-field); border-radius: var(--r-pill);
  min-height: 34px; padding: 0 var(--s4); color: var(--ink); cursor: pointer;
}
.sort-btn:hover { border-color: var(--ink); }
.sort-btn[aria-pressed="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* ledger as a list (community + unit pages) */
.ledger-list > li { border-bottom: var(--hair); }
.ledger-list > li:first-child { border-top: 2px solid var(--rule-strong); }
.ledger-list .ledger__link {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr) 220px 160px;
  align-items: center;
  padding: var(--s6) 0; gap: var(--s6);
}
.ledger-list .ledger__main { display: block; min-width: 0; }
.ledger-list .ledger__spec { min-width: 0; }
.ledger-list .ledger__side { text-align: right; }
.section--ink .ledger-list > li, .comm-index .ledger-list > li { border-bottom-color: rgba(234, 232, 219, .3); }
.section--ink .ledger__link, .comm-index .ledger__link { color: var(--paper); }

/* --- canonical hairline spec row ----------------------------------------- */
.specrow { display: flex; flex-wrap: wrap; border: var(--hair); background: var(--panel); }
.specrow__cell {
  flex: 1 1 0; min-width: 140px; padding: var(--s4) var(--s6);
  border-left: var(--hair);
}
.specrow__cell:first-child { border-left: 0; }
.specrow__k { display: block; color: var(--muted); }
.specrow__v {
  display: block; margin-top: var(--s1);
  font-family: var(--display); font-weight: 600; font-stretch: 118%;
  font-size: 24px; line-height: 30px; text-transform: uppercase;
  font-variant-numeric: tabular-nums lining-nums;
}
.specrow__v--rent { color: var(--ink); }
.specrow__v--none { color: var(--muted); }

/* --- the hairline meta line (property-00's "5 MIN WALK · 47㎡ · MODISH 1BR")
   The reference joins these with middle dots, which is a tell in its own right
   and which check_tells() fails the build on. Hairlines do the same job. */
.metaline {
  display: flex; flex-wrap: wrap; align-items: center;
  font-family: var(--display); font-weight: 500; font-stretch: 110%;
  text-transform: uppercase; font-size: 17px; line-height: 24px; letter-spacing: .01em;
}
.metaline > span + span {
  margin-left: var(--s4); padding-left: var(--s4); border-left: 1px solid currentColor;
}

/* --- hairline term / value rows ------------------------------------------ */
.terms { border-top: 2px solid var(--rule-strong); }
.terms > div, .terms__row {
  display: grid; grid-template-columns: minmax(220px, 34%) 1fr;
  gap: var(--s6); padding: var(--s6) 0; border-bottom: var(--hair);
  align-items: baseline;
}
.terms dt, .terms__k {
  font-family: var(--display); font-weight: 500; font-stretch: 112%;
  text-transform: uppercase; font-size: var(--fs-h3); line-height: var(--lh-h3); margin: 0;
}
.terms dd, .terms__v { margin: 0; }
.terms__v--none { color: var(--muted); }
.terms--compact dt, .terms--compact .terms__k {
  font-size: var(--fs-label); line-height: var(--lh-label); letter-spacing: .06em;
}
.terms--compact > div, .terms--compact .terms__row { padding: var(--s4) 0; align-items: baseline; }

/* --- full-bleed photographic band ---------------------------------------- */
.band { width: 100%; }
.band img { width: 100%; aspect-ratio: 3 / 1; object-fit: cover; object-position: center 38%; }

/* --- gallery mosaic ------------------------------------------------------ */
.mosaic {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: var(--s6);
  aspect-ratio: 1200 / 384;
}
.mosaic__tile { margin: 0; min-height: 0; }
.mosaic__tile .photo-btn { height: 100%; }
.mosaic__tile img { width: 100%; height: 100%; object-fit: cover; border: var(--frame); }
.mosaic__tile--lead { grid-row: span 2; }
.mosaic__tile--lead img { height: 100%; }
.photo-btn { display: block; padding: 0; border: 0; background: none; cursor: pointer; width: 100%; }
.photo-btn img { transition-property: opacity; transition-duration: .2s; transition-timing-function: linear; }
.photo-btn:hover img { opacity: .88; }

/* photo strip (unit page + mobile mosaic) */
.strip-wrap { margin-top: var(--s6); }
.strip__nav {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s6); margin-top: var(--s4);
}
.strip__count { font-size: var(--fs-small); line-height: var(--lh-small); color: var(--muted); font-variant-numeric: tabular-nums; }
.strip__btns { display: flex; gap: var(--s2); }
.strip__btns .icon-btn[disabled] { opacity: .35; cursor: default; }
.strip__btns .icon-btn[disabled]:hover { background: transparent; color: var(--ink); }
.strip-wrap[data-overflow="false"] .strip__btns { display: none; }
.strip { display: flex; gap: var(--s6); overflow-x: auto; padding-bottom: var(--s3); scroll-snap-type: x proximity; }
.strip > * { scroll-snap-align: start; }
.strip > * { flex: 0 0 260px; }
.strip img { width: 260px; height: 174px; object-fit: cover; border: var(--frame); }

/* --- W3: the index / preview split ---------------------------------------
   index-homes-00 and home-06/07. Facts carried across: the photograph bleeds
   to the VIEWPORT edge, not the container; the name is set large in --paper
   directly ON the photograph with no panel behind it; the fact tiles are 1px
   outlines on the photograph; the CTA is a yellow pill at the bottom left; and
   the previewed row is marked by inverting its chip, not by a wash. */
.split {
  display: grid; grid-template-columns: minmax(300px, 34%) 1fr;
  align-items: stretch;
  width: 100vw; margin-left: calc(50% - 50vw);
  padding-left: max(16px, calc(50vw - var(--container) / 2));
}
.split__list { border-top: var(--hair); }
.split__row {
  display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: var(--s4);
  width: 100%; text-align: left; background: none; border: 0;
  border-bottom: var(--hair); padding: var(--s6) var(--s8) var(--s6) 0;
  color: var(--ink); text-decoration: none; cursor: pointer; align-items: start;
  transition-property: color; transition-duration: var(--dur); transition-timing-function: var(--ease);
}
.split__chip {
  grid-row: span 2;
  display: grid; place-items: center; width: 44px; height: 52px;
  background: var(--accent); color: var(--ink);
  font-family: var(--display); font-weight: 600; font-stretch: 112%;
  font-size: 22px; line-height: 1; font-variant-numeric: tabular-nums lining-nums;
  transition-property: background-color, color; transition-duration: var(--dur); transition-timing-function: var(--ease);
}
/* the active row inverts its chip — no background wash on the row */
.split__row[aria-current="true"] .split__chip { background: var(--ink); color: var(--accent); }
.split__row:hover .split__name { color: var(--muted); }
.split__row-top { display: block; }
.split__name {
  font-family: var(--display); font-weight: 400; font-stretch: 118%;
  text-transform: uppercase; font-size: 30px; line-height: 34px; letter-spacing: -.008em;
  transition-property: color; transition-duration: var(--dur); transition-timing-function: var(--ease);
}
.split__count { display: block; font-size: var(--fs-small); color: var(--muted); }
.split__row-bot { display: flex; justify-content: space-between; gap: var(--s4); margin-top: var(--s1); font-size: var(--fs-small); color: var(--muted); }
.split__from { white-space: nowrap; }
.split__preview { position: relative; min-height: 620px; overflow: hidden; isolation: isolate; }
.split__pane {
  position: absolute; inset: 0; opacity: 0; visibility: hidden;
  transition-property: opacity; transition-duration: var(--dur); transition-timing-function: var(--ease);
}
.split__pane[data-active="true"] { opacity: 1; visibility: visible; }
.split__pane > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; }
.split__pane::after { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--photo-scrim); }
/* the name is on the photograph, not in a box — brand.md § Composition */
.split__overlay {
  position: absolute; inset: 0; padding: var(--s12);
  display: flex; flex-direction: column; justify-content: space-between;
  color: var(--paper);
}
.split__overlay .d-l { font-size: min(var(--fs-display-l), 5.4vw); line-height: 1; }
.split__overlay p { font-size: var(--fs-small); margin-top: var(--s2); }
.split__facts { display: flex; flex-wrap: wrap; gap: var(--s3); margin-bottom: var(--s6); }
.split__facts .tile { border-color: var(--paper); min-width: 118px; }
.split__foot { margin-top: auto; }

/* stacked variant, used below 900px and where a preview pane is unavailable */
.stack-list { display: none; gap: var(--s12); }
.stack-card { display: block; text-decoration: none; color: var(--ink); }
.stack-card:hover .split__name { color: var(--muted); }
.stack-card img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; border: var(--frame); }
.stack-card__body { padding-top: var(--s4); border-top: var(--hair); margin-top: var(--s4); }
.stack-card .split__row-top { display: flex; justify-content: space-between; gap: var(--s4); align-items: baseline; }

/* --- the sticky in-page bar (property-01..06) ---------------------------- */
.subbar {
  position: sticky; top: var(--header-h); z-index: 60;
  background: var(--paper); border-bottom: var(--hair);
  padding-block: var(--s3);
}
.subbar__inner { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }
.subbar__spacer { margin-left: auto; }

/* --- amenities ----------------------------------------------------------- */
.amen-group + .amen-group { margin-top: var(--s12); }
.amen-group h3 { padding-bottom: var(--s3); border-bottom: var(--hair); }
.amen-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--s6); margin-top: var(--s6); align-items: stretch;
}
.amen { display: flex; gap: var(--s3); align-items: center; font-size: 16px; line-height: 22px; min-height: 40px; }
.amen > span:last-child { text-wrap: balance; }
.amen__tile {
  flex: 0 0 40px; width: 40px; height: 40px; display: grid; place-items: center;
  background: var(--scrim);
}
.amen__tile svg { width: 24px; height: 24px; }

/* --- pills (availability filters) ---------------------------------------- */
.pillbar {
  position: sticky; top: var(--header-h); z-index: 60;
  background: var(--paper); border-bottom: var(--hair);
  padding-block: var(--s3);
  display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center;
}
.pill {
  display: inline-flex; align-items: center; gap: var(--s2); min-height: 40px;
  padding: 0 var(--s6); border-radius: var(--r-pill); border: 1px solid var(--rule-field);
  font-family: var(--display); font-weight: 500; font-stretch: 108%;
  font-size: 15px; line-height: 20px;
  color: var(--ink); text-decoration: none; background: transparent;
  transition-property: background-color, border-color, color;
  transition-duration: var(--dur-slow); transition-timing-function: var(--ease);
}
.pill:hover { border-color: var(--ink); color: var(--ink); }
.pill[aria-current="page"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.pill[aria-current="page"] .pill__n { color: var(--accent); }
.pill__n { font-variant-numeric: tabular-nums; color: var(--muted); }
.pillbar__spacer { margin-left: auto; }

/* --- forms --------------------------------------------------------------- */
.panel { background: var(--panel); border: var(--hair); padding: var(--s12); }
.field + .field { margin-top: var(--s6); }
.field label { display: block; font-family: var(--display); font-weight: 500; font-stretch: 108%;
  font-size: 15px; line-height: 20px; margin-bottom: var(--s2); }
.field input, .field select, .field textarea {
  width: 100%; font-family: var(--text); font-size: var(--fs-body); line-height: var(--lh-body);
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--rule-field); border-radius: var(--r-input);
  padding: var(--s3) var(--s4); min-height: 48px;
  transition-property: border-color; transition-duration: .25s; transition-timing-function: ease;
}
.field textarea { min-height: 132px; resize: vertical; }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--ink); }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--ink); }
.field input:disabled, .field select:disabled, .field textarea:disabled { opacity: .5; background: var(--paper); }
.field__hint { font-size: var(--fs-small); color: var(--muted); margin-top: var(--s2); }
.contact-row__k { display: block; font-family: var(--display); font-weight: 600; font-stretch: 108%; font-size: 15px; line-height: 20px; }
.val--none { color: var(--muted); }
.note-lang { margin-top: var(--s6); color: var(--muted); max-width: 66ch; }
.form-status { margin-top: var(--s6); font-size: var(--fs-small); }
.contact-panel { display: grid; grid-template-columns: minmax(280px, 38%) 1fr; }
.contact-panel__left { padding: var(--s12); border-right: var(--hair); }
.contact-panel__right { padding: var(--s12); }
.contact-rows { border-top: var(--hair); }
.contact-rows > div { display: grid; grid-template-columns: 24px 1fr; gap: var(--s3);
  padding: var(--s4) 0; border-bottom: var(--hair); }
.contact-rows svg { width: 20px; height: 20px; margin-top: 3px; }
.contact-rows .contact-row__k { color: var(--muted); }
.contact-rows .val { display: block; }
.contact-rows a { color: var(--ink); }
.contact-rows a:hover { color: var(--muted); }

/* --- map ----------------------------------------------------------------- */
.map { width: 100%; aspect-ratio: 16 / 9; background: var(--rule); border: var(--hair); }
.map--tall { aspect-ratio: 21 / 9; }
.maplibregl-ctrl-attrib { font-family: var(--text); font-size: 11px; }
.locate {
  display: grid; grid-template-columns: minmax(380px, 460px) minmax(0, 1fr);
  gap: var(--s6); align-items: stretch; margin-top: var(--s8);
}
.locate .places { grid-template-columns: minmax(0, 1fr); align-content: start; }
.locate .map { aspect-ratio: auto; height: 100%; min-height: 420px; }
.places { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s6); }
.places__box { border: var(--hair); background: var(--panel); padding: var(--s6); }
.places__box h3 { font-size: var(--fs-label); letter-spacing: .06em; }
.places__list { margin-top: var(--s4); border-top: var(--hair); }
.place-btn {
  display: flex; width: 100%; gap: var(--s4); justify-content: space-between; align-items: baseline;
  background: none; border: 0; border-bottom: var(--hair); padding: var(--s3) 0;
  text-align: left; font-family: var(--text); font-size: var(--fs-body); color: var(--ink); cursor: pointer;
  transition-property: color, background-color; transition-duration: .2s; transition-timing-function: var(--ease);
}
.place-btn:hover, .place-btn[data-highlight="true"] { color: var(--muted); }
.place-btn__d { font-size: var(--fs-small); color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.map-note { font-size: var(--fs-small); color: var(--muted); margin-top: var(--s3); }
/* A pin carries information, so it needs 3:1 against the map. #F9E169 on
   OpenFreeMap's light tiles does not have it; --ink does. */
.map-pin {
  width: 18px; height: 18px; border-radius: var(--r-circle);
  background: var(--ink); border: 2px solid var(--panel);
}
.map-pin--place { width: 12px; height: 12px; background: var(--muted); }
.maplibregl-popup-content {
  border-radius: 0; padding: var(--s4); font-family: var(--text); font-size: var(--fs-small);
  border: var(--hair); box-shadow: none;
}

/* --- outlined fact tiles ------------------------------------------------- */
.tiles { display: flex; flex-wrap: wrap; gap: var(--s4); }
.tile { border: 1px solid var(--ink); padding: var(--s4) var(--s6); min-width: 132px; }
.tile .label { color: inherit; }
.tile__v {
  display: block; font-family: var(--display); font-weight: 600; font-stretch: 118%;
  font-size: 30px; line-height: 36px; text-transform: uppercase; font-variant-numeric: tabular-nums lining-nums;
}
.section--ink .tile, .comm-index .tile { border-color: var(--paper); }

/* --- document template (accessibility / privacy / criteria) -------------- */
.doc { display: grid; grid-template-columns: 240px minmax(0, 720px); gap: var(--s24); }
.doc__nav { align-self: start; position: sticky; top: calc(var(--header-h) + var(--s6)); }
.doc__nav li + li { margin-top: var(--s3); }
.doc__nav a { color: var(--ink); text-decoration: none; font-size: var(--fs-small); }
.doc__nav a:hover { color: var(--muted); text-decoration: underline; }
.doc__body > * + * { margin-top: var(--s6); }
.doc__body h2 { margin-top: var(--s16); }
.doc__body h2:first-child { margin-top: 0; }
.doc__body h3 { margin-top: var(--s8); }
.doc__body ul { list-style: disc; padding-left: 1.2em; }
.doc__body li + li { margin-top: var(--s2); }
.table { border-top: 2px solid var(--rule-strong); }
.table th, .table td { text-align: left; padding: var(--s3) var(--s4) var(--s3) 0; border-bottom: var(--hair); vertical-align: top; }
.table th { font-family: var(--display); font-weight: 500; font-stretch: 112%; text-transform: uppercase;
  font-size: var(--fs-label); letter-spacing: .06em; }
.table td { font-size: var(--fs-small); line-height: var(--lh-small); }

/* --- sitemap ------------------------------------------------------------- */
.sitemap-grid { display: grid; grid-template-columns: 1fr 280px; gap: var(--s24); align-items: start; }
.sitemap-group + .sitemap-group { margin-top: var(--s12); }
.sitemap-list { border-top: 2px solid var(--rule-strong); margin-top: var(--s4); }
.sitemap-list li { border-bottom: var(--hair); }
.sitemap-list a { display: flex; justify-content: space-between; gap: var(--s6); flex-wrap: wrap;
  padding: var(--s3) 0; color: var(--ink); text-decoration: none; }
.sitemap-list a:hover { color: var(--muted); }
.sitemap-list .meta {
  font-size: var(--fs-small); line-height: var(--lh-small); color: var(--muted);
  display: flex; flex-direction: column; align-items: flex-end; text-align: right;
  min-width: 0;
}
.sitemap-list .meta__path { overflow-wrap: anywhere; }
.sitemap-name { min-width: 0; overflow-wrap: anywhere; }
.start-here { border: var(--hair); background: var(--panel); padding: var(--s6); position: sticky; top: calc(var(--header-h) + var(--s6)); }
.start-here ul { margin-top: var(--s4); }
.start-here li + li { margin-top: var(--s3); }

/* --- unit page ----------------------------------------------------------- */
.unit-grid { display: grid; grid-template-columns: minmax(0, 720px) 380px; gap: var(--s24); align-items: start; }
.unit-rail { position: sticky; top: calc(var(--header-h) + var(--s6)); border: var(--hair); background: var(--panel); padding: var(--s8); }
.unit-rail__rent { font-family: var(--display); font-weight: 600; font-stretch: 118%;
  font-size: var(--fs-rent); line-height: var(--lh-rent); color: var(--ink);
  letter-spacing: -.012em; font-variant-numeric: tabular-nums lining-nums; }
.unit-rail__spec { margin-top: var(--s2); display: flex; flex-wrap: wrap; align-items: baseline; }
.unit-rail__spec > span + span {
  margin-left: var(--s3); padding-left: var(--s3); border-left: var(--hair);
}
.unit-rail hr { border: 0; border-top: var(--hair); margin: var(--s6) 0; }
.unit-rail .btn { width: 100%; }
.unit-rail .btn + .btn { margin-top: var(--s3); }
.feature-list { border-top: var(--hair); margin-top: var(--s6); }
.feature-list li { display: grid; grid-template-columns: 10px 1fr; gap: var(--s3);
  padding: var(--s3) 0; border-bottom: var(--hair); }
.feature-list b { font-weight: 600; }
.feature-list .dot { width: 6px; height: 6px; background: var(--ink); margin-top: 10px; }

/* --- review quote -------------------------------------------------------- */
.quote { border-top: 2px solid var(--rule-strong); border-bottom: 2px solid var(--rule-strong); padding-block: var(--s12); }
.quote blockquote { margin: 0; font-family: var(--display); font-weight: 400; font-stretch: 112%;
  font-size: var(--fs-h2); line-height: var(--lh-h2); text-transform: none; }
.quote figcaption { margin-top: var(--s6); font-size: var(--fs-small); color: var(--muted); }

/* --- footer -------------------------------------------------------------- */
.site-footer { background: var(--ink); color: var(--paper); padding-block: var(--s24) var(--s12); position: relative; overflow: hidden; }
/* The ribbon is allowed behind the wordmark and no further. --paper body text
   over #F9E169 is 1.06:1, so a strand reaching the blurb or the link columns
   would erase them outright. Height is fixed rather than a percentage because
   the footer's own height changes with the link lists. */
.site-footer .ribbon { height: 400px; }

/* On a light ground the ribbon crossing type is free: --ink over #F9E169 is
   10.09:1, so a strand can run straight through a headline and the letters
   still read. That is the reference's whole device.

   On an --ink ground it inverts and breaks: the type is --paper, and --paper
   over #F9E169 is 1.06:1, so a full-strength strand would erase every letter
   it crossed. The reference never has this problem because its ribbon always
   runs on the cream ground. Dropping the opacity to .42 composites the stroke
   to about #777544 against --ink, which holds the 148px footer wordmark and
   the 64px /residents title at 3.87:1 — past the 3:1 that WCAG 1.4.3 asks of
   large text, with the 4.5:1 body-text case never arising because no strand
   reaches body copy on any dark ground. */
.site-footer .ribbon, .hero--ink .ribbon, .section--ink .ribbon,
.comm-index .ribbon { opacity: .42; }
/* .42 buys the 3:1 that large text needs and no more. The crossing strand that
   used to run through /residents' 20px lead paragraph (20px regular is not
   large text: it needs 4.5:1 and was getting 3.87:1) no longer exists on any
   interior route — see the ribbon block at the top of this file. What is left
   on a dark ground is the back layer, whose line clears the copy, and the
   footer's single strand behind the 148px wordmark. */
.site-footer > .wrap { position: relative; z-index: 1; }
.site-footer a:not(.btn) { color: var(--paper); text-decoration: none; }
.site-footer a:hover { color: #FFFFFF; text-decoration: underline; }
.footer-top { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s16); }
.footer-word {
  font-family: var(--display); font-weight: 400; font-stretch: 125%;
  text-transform: uppercase; font-size: clamp(52px, 10.3vw, 148px); line-height: .86;
  letter-spacing: -.02em; color: var(--paper); margin: 0;
}
.footer-word span { display: block; }
.footer-grid { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: var(--s16); align-items: start; }
.footer-blurb { max-width: 34ch; font-size: var(--fs-small); line-height: var(--lh-small); }
.footer-col li + li { margin-top: var(--s3); }
.footer-col__head {
  display: block; margin-bottom: var(--s4); color: var(--paper);
  font-family: var(--display); font-weight: 600; font-stretch: 108%;
  font-size: 15px; line-height: 20px;
}
.footer-legal {
  margin-top: var(--s16); padding-top: var(--s6); border-top: 1px solid rgba(234, 232, 219, .3);
  display: grid; grid-template-columns: auto 1fr; gap: var(--s4);
  font-size: var(--fs-small); line-height: var(--lh-small);
}
.footer-legal p + p { margin-top: var(--s2); }
.footer-legal a { text-decoration: underline; text-underline-offset: 3px; }
.footer-legal__end {
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s8);
  justify-content: space-between; align-items: baseline;
}
/* The Equal Housing Opportunity insignia, drawn inline (EHO_MARK in
   scripts/gen.py). It is a meaningful graphic, not decoration: it carries its
   own <title>, and it is stroked in --paper on the --ink footer ground, 12.6:1,
   so it clears WCAG 1.4.11's 3:1 for graphical objects with room to spare. */
.eho { width: 40px; height: 40px; display: block; color: var(--paper); }

/* The BRG monogram is a 1.728:1 lockup, so it is sized by height with
   width:auto. On the green-black footer the plaque variant would disappear
   into the ground; this is the knockout, whose letter faces are --paper and
   whose bevels let the ground through. */
.footer-lockup { display: flex; align-items: flex-end; gap: var(--s6); flex-wrap: wrap; }
.footer-mark { height: 38px; width: auto; display: block; flex: 0 0 auto; margin-bottom: .18em; }

/* --- lightbox ------------------------------------------------------------ */
.lightbox { position: fixed; inset: 0; z-index: 200; background: rgba(40, 50, 46, .96);
  display: grid; grid-template-rows: auto 1fr auto; padding: var(--s4); }
.lightbox[hidden] { display: none; }
.lightbox__bar { display: flex; justify-content: space-between; align-items: center; color: var(--paper); }
.lightbox__bar .icon-btn { border-color: var(--paper); color: var(--paper); }
.lightbox__bar .icon-btn:hover { background: var(--paper); color: var(--ink); }
.lightbox__stage { display: grid; place-items: center; min-height: 0; }
.lightbox__stage img { max-width: 100%; max-height: 100%; object-fit: contain; border: var(--frame); }
.lightbox__count { color: var(--paper); font-size: var(--fs-small); }

/* --- 404 / 410 ----------------------------------------------------------- */
.gone .actions { margin-top: var(--s8); }

/* --- scroll reveal: default visible, additive only -----------------------
   Every revealed element is opacity:1 and untransformed by default. The reveal
   is added only inside a prefers-reduced-motion: no-preference guard, so the
   two states carry identical content and a reduced-motion render is a pixel
   match apart from the animation itself. Sections do not animate in; only the
   elements that already had it, plus the new rail tiles. */
.ledger__row, .ledger-list > li, .mosaic__tile, .comm-row { opacity: 1; transform: none; }
/* .rail__item is deliberately NOT revealed: the rail is its own scroll
   container, so `view()` would resolve against the rail rather than the page
   and could strand a tile at opacity 0 — losing content, not just motion. */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .ledger__row, .ledger-list > li, .mosaic__tile, .comm-row {
      animation: reveal .5s var(--ease) both;
      animation-timeline: view();
      animation-range: entry 10% cover 30%;
    }
  }
}
@keyframes reveal {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* --- WCAG 2.2 SC 2.5.8 Target Size (Minimum) ------------------------------
   24 x 24 CSS px, with the criterion's own exceptions. A link sitting inside
   a sentence is exempt ("Inline"), and this site leans on that heavily and
   correctly — body copy is not re-spaced. Two other exceptions carry most of
   the rest: "Spacing" (a 24px circle on each target's centre must not reach
   another target) covers the nav links and the footer columns, and
   "Equivalent" covers a duplicated control.
   What is NOT covered, and is fixed here, is a standalone link that is the
   only thing on its line and is stacked hard against the next one: the
   apartment rail's phone number and "Before you apply", the contact panel's
   LinkedIn value, and the sitemap's "Start here" list at 320px. Each measured
   20-22px tall with a neighbour inside the 24px circle. They are given a real
   24px box by padding, not by growing the type, so nothing about the setting
   changes. Sourced: https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html */
.unit-rail p.small > a:only-child,
.contact-rows .val > a:only-child,
.start-here li > a,
.actions > a.small,
.doc__nav ol li > a,
.footer-legal__end > a {
  display: inline-flex; align-items: center; min-height: 24px;
}
.unit-rail p.small + p.small { margin-top: var(--s2); }
.start-here li + li { margin-top: var(--s1); }

/* Apartment discovery: shared search controls and location-based availability. */
.home-hero { grid-template-columns: minmax(0, 1fr); --hero-disp-w: var(--hero-w); --cascade-size: clamp(32px, 6.4vw, 92px); }
.home-hero .cascade__line { margin-left: 0; }
.home-hero__cta { margin-left: 0; }
.rail__cap { padding-top: var(--s6); }
.stack-card__body { padding-block: var(--s6); }
.finder-controls { max-width: 980px; margin: 0 auto; text-align: center; }
.finder-controls h2 { margin-bottom: var(--s8); }
.finder-form label { display: block; margin-bottom: var(--s4); font-family: var(--text); font-size: clamp(18px, 2vw, 26px); }
.finder-search { display: flex; gap: var(--s4); margin-bottom: var(--s8); }
.finder-search input { min-width: 0; flex: 1; border: 1px solid var(--ink); background: transparent; padding: 20px 24px; color: var(--ink); font: inherit; border-radius: 0; }
.finder-sizes { display: flex; justify-content: center; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s4); }
.finder-sizes .pill[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
.finder-status { margin-block: var(--s8) var(--s4); }
.finder-map { height: 540px; border: 1px solid var(--rule); background: var(--paper); }
.finder-pin { border: 1px solid var(--paper); border-radius: 24px; background: var(--ink); color: var(--paper); padding: 10px 16px; font: 600 15px var(--display); cursor: pointer; box-shadow: 0 3px 12px #0003; white-space: nowrap; }
.finder-pin:hover, .finder-pin:focus-visible { background: var(--accent); color: var(--ink); }
.finder-pin--dot { width: 30px; height: 30px; padding: 0; border: 4px solid var(--paper); border-radius: 50% 50% 50% 0; }
.finder-popup { font: 16px/1.5 var(--display); color: var(--ink); padding: 12px; }
.finder-popup p { margin: 4px 0 12px; font-size: 14px; }
.finder-popup ul { list-style: none; padding: 0; max-height: 220px; overflow: auto; }
.finder-popup li + li { margin-top: 12px; }
.finder-list { margin-top: var(--s6); }
.finder-list summary { cursor: pointer; padding-block: 12px; }
.finder-list li { margin-block: 12px; }
@media (max-width: 600px) {
  .finder-search { flex-direction: column; }
  .finder-search input { width: 100%; padding: 16px; }
  .finder-map { height: 440px; }
  .finder-sizes .pill { padding: 12px 16px; }
  .home-hero .cascade__line { font-size: clamp(26px, 6.3vw, 40px); }
}
.finder-note { margin-top: var(--s8); color: var(--muted); }
.finder-note + .finder-status { margin-top: var(--s3); }
.finder-popup small { display: block; color: var(--muted); margin-top: 4px; }
.map-pin { cursor: pointer; }
.stack-card__body { display: block; margin-top: 0; border-top: 0; }
.finder-map .maplibregl-popup-close-button { width: 32px; height: 32px; font-size: 22px; }
.finder-pin--dot:hover, .finder-pin--dot:focus-visible { border-color: var(--ink); }

/* Kiara vendor credit: the same assets and dark-footer lockup as Aria Idlewild. */
.footer-kiara { border-top: 1px solid rgba(216,210,196,.2); max-width: 340px; margin-top: 26px; padding-top: 24px; }
.footer-kiara a { display: inline-flex; align-items: center; gap: 10px; color: #C3C7CB; font-family: var(--display); font-size: 10px; letter-spacing: .24em; white-space: nowrap; text-decoration: none; }
.footer-kiara img { height: 20px; width: auto; display: block; }
.footer-kiara .footer-kiara__word { height: 17px; filter: brightness(0) invert(.86); }
.footer-kiara a:hover { opacity: .72; }
.footer-kiara a:focus-visible { outline: 2px solid var(--accent); outline-offset: 5px; }
@media (max-width: 900px) {
  .footer-kiara a { min-height: 44px; }
}
@media (max-width: 640px) {
  .footer-kiara { max-width: none; }
}
@media (max-width: 360px) {
  .footer-kiara a { gap: 8px; font-size: 9px; letter-spacing: .18em; }
  .footer-kiara .footer-kiara__word { height: 15px; }
}

/* Accessible footer help and control over automatically updating inventory. */
.footer-legal__marks { display: flex; align-items: center; align-self: start; gap: 12px; }
.footer-accessibility { display: inline-flex; align-items: center; justify-content: center; width: 44px; min-height: 44px; color: var(--paper); }
.footer-accessibility svg { width: 36px; height: 36px; flex: 0 0 36px; fill: none; stroke: currentColor; stroke-width: 1.8; }

/* Smaller headings for the three apartment-size landing pages. */
.service-heading { font-size: clamp(24px, 5vw, 64px); line-height: 1.08; letter-spacing: -.01em; max-width: 24ch; }
