/* ===========================================================================
   TYPESET · the polish pass, 26 September 2026
   Loaded last of all. Every rule here was either found by measuring the
   rendered page (typecheck.py, 18 widths from 320 to 1920, in the real
   fonts) or is a correction the measurement could not see but the eye can.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1 · BREAKS, AUTHORED PER BREAKPOINT
   A <br> in a display heading is a design decision, and the right decision
   is not the same on a phone as on a desktop. "Gaudi / Villas" stacks on a
   desktop and runs on one line on a phone; the footer wordmark does the
   opposite. Each break says which it is. A real space always sits beside
   the break, so the words never fuse when it is switched off.
   --------------------------------------------------------------------------- */
@media (max-width: 899px) { .br-d { display: none; } }
@media (min-width: 900px) { .br-m { display: none; } }
.nowrap { white-space: nowrap; }

/* ---------------------------------------------------------------------------
   2 · HOW LINES END
   balance  headings, labels, captions, anything short enough that an even
            rag matters more than a full first line
   pretty   running text: the engine looks ahead and refuses to leave a
            short last line or a single word on it
   Both degrade to ordinary wrapping, and the non-breaking spaces set in the
   markup hold the line where either is unsupported.
   --------------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6,
.display, .sec-head, .statement__head, .hero__word,
.label, .sec-label, figcaption, dt, legend, button,
.hero__eyebrow, .hero__gloss, .plate__note, .bay__addr, .bay__stat,
.fact__u, .near__name, .near__note, .storey__t, .storey__d,
.argument__k, .argument__nh, .ambient__line, .plans__h, .plans__line,
.sheet__title, .sheet__sub, .chain__t, .chain__d, .locate__cap,
.lin__h, .lin__meta, .note__h, .menu__foot, .thumbbar {
  text-wrap: balance;
}
p, li, dd, blockquote,
.body, .lede, .sec-lede, .argument__v, .bay__copy, .note__p, .lin__p,
.argument__note p, .address__caveat, .argument__attrib, .plans__note {
  text-wrap: pretty;
}
/* ...except where balance is the better answer for a short p */
.sec-lede, .lede { text-wrap: pretty; }

/* Hyphenation is off everywhere. On a luxury page a hyphenated line reads as
   a column that was not wide enough; the fix for a bad rag is the copy or the
   measure, never a hyphen. */
html { hyphens: manual; -webkit-hyphens: manual; }

/* Opening quotes and the first punctuation of a line hang into the margin,
   so the letters align and not the marks. Safari, which is where Andy and
   most of this market read the page. */
html { hanging-punctuation: first last; }

/* Long unbroken strings on the narrowest phones: the email address. */
a[href^="mailto:"] { overflow-wrap: anywhere; }

/* ---------------------------------------------------------------------------
   3 · FIGURES
   Cormorant's default figures are oldstyle: right in running prose, where
   "June 2025" should sit in the line like a word. Wrong in a display figure,
   where "2,617" at 50px bounces between x-height and cap height.

   The old rules set both with font-feature-settings, which REPLACES rather
   than merges, so on every class="display num" element the later one won
   and the result was oldstyle tabular figures in the biggest numbers on the
   page. font-variant-* properties compose; that is the whole fix.
   --------------------------------------------------------------------------- */
.display, .num { font-feature-settings: normal; }
.display {
  font-variant-ligatures: common-ligatures contextual;
  font-variant-numeric: lining-nums proportional-nums;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
}
/* data that lines up in a column: tabular, so the digits stack */
.num { font-variant-numeric: lining-nums tabular-nums; }
/* a big standalone figure is not in a column: proportional, so a "1" does
   not stand in a box as wide as an "8" */
.display.num, .statement__facts dd.display { font-variant-numeric: lining-nums proportional-nums; }
/* the distance column and the bay prices are columns */
.near__d, .bay__price, .bay__stat, .thumbbar__price { font-variant-numeric: lining-nums tabular-nums; }
/* prose in the serif keeps its oldstyle figures */
.body p, .lin__p, .note__p, .bay__copy, .argument__v, .plans__line { font-variant-numeric: oldstyle-nums proportional-nums; }

/* ---------------------------------------------------------------------------
   4 · OPTICAL MARGIN
   A capital in Cormorant carries about 0.04em of side-bearing, so at 200px a
   headline sits nine pixels to the right of the text beneath it and looks
   indented. Each left-aligned display heading carries --ol, measured from
   the font for ITS OWN first glyph by typeset.py (an A or a W carries
   almost none, and gets none).
   --------------------------------------------------------------------------- */
.hero__word, .statement__head, .sec-head, .argument__nh, .plans__addr {
  margin-inline-start: var(--ol, 0);
}

/* ---------------------------------------------------------------------------
   5 · LIGHT ON DARK
   Subpixel antialiasing renders light type on a dark ground a weight too
   heavy on a Mac. Grayscale on the dark grounds only; on the bone ground the
   thin Cormorant needs every bit of weight it has.
   --------------------------------------------------------------------------- */
.section--dark, .hero, .ascent, .ambient, .twilight, .foot, .menu, .thumbbar,
.argument__note, .curtain, .facade, .inside, .address {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ---------------------------------------------------------------------------
   6 · MEASURE AND LEADING
   Running text wants 60 to 72 characters on a desktop and a little under 40
   on a phone. Leading opens as the measure widens, because the eye has
   further to travel back.
   --------------------------------------------------------------------------- */
.statement__body p, .lin__p, .note__p { max-width: 64ch; }
.bay__copy { max-width: 52ch; }
.sec-lede { max-width: 36ch; }
@media (min-width: 900px) {
  .statement__body p { line-height: 1.68; }
}

/* ---------------------------------------------------------------------------
   7 · DISPLAY LEADING
   Cormorant's ascenders and descenders are long. At 0.92 a "g" on the first
   line of a two-line head can touch the cap of the next; 0.98 is the tightest
   the face takes without a collision at any size on this page.
   --------------------------------------------------------------------------- */
.sec-head, .statement__head { line-height: 0.98; }
.hero__word { line-height: 0.94; }

/* ---------------------------------------------------------------------------
   8 · LAYOUT FACTS THE MEASUREMENT EXPOSED
   --------------------------------------------------------------------------- */

/* THE FACT BAND.
   On a desktop, desktop.css places the facts in the right-hand column of the
   statement, which held four soft facts comfortably and cannot hold six hard
   ones: at 1440 each cell was 76px, "$2.9M" was clipped to "$2.9" and
   "Private" ran out of the frame. The six now run as a band under the whole
   statement, full width, and the figures are sized so that six genuinely fit
   where six are shown. desktop.css also carried padding-top: 2rem, which in
   the hairline grid showed the rule colour as a grey bar across the top on
   every screen; gone. */
.statement__facts { padding-top: 0 !important; border-top: 1px solid var(--rule); }
@media (min-width: 900px) {
  .statement__facts {
    grid-column: 1 / -1;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: clamp(2.5rem, 5vw, 4.5rem);
  }
  .statement__facts dd.display { font-size: clamp(2.2rem, 3.2vw, 3.1rem); }
}
@media (min-width: 1100px) {
  .statement__facts { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

/* "4 + office" is one unit and must not break, so on the narrowest phones
   the four-up spec becomes two by two rather than running off the screen. */
@media (max-width: 380px) {
  .bay__spec { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; row-gap: 1rem; }
}

/* The ambient line is a two-line poem, "Four doors / on a street of forty.",
   and 18ch was two characters short of its second line. */
.ambient__line { max-width: 23ch; }

/* The footer sign-off stacks on a phone; the separator only belongs where
   the two halves share a line. */
@media (max-width: 899px) { .sep-d { display: none; } }

/* ---------------------------------------------------------------------------
   9 · THE HERO GLOSS
   Was Archivo set italic with no italic loaded: a slant the browser invented.
   It is now true Cormorant italic, which is also the right voice for a line
   that describes rather than labels, sitting under a serif wordmark.
   --------------------------------------------------------------------------- */
.hero__phon {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-variation-settings: normal;
  letter-spacing: 0.005em;
  text-transform: none;
  font-size: 1.28em;
  line-height: 1.25;
}

/* ---------------------------------------------------------------------------
   10 · THE RISE, WITHOUT A JUMP
   Split words are inline-blocks. On the baseline they pick up strut space on
   every line; aligned to the top of the line box they do not, so the split
   heading has the same line pitch as the text it replaces. site.js also locks
   the heading's height for the length of the rise, and overflow stays visible
   so no descender is ever clipped by that lock.
   --------------------------------------------------------------------------- */
[data-rise] .word { vertical-align: top; }
[data-rise] { overflow: visible; }

/* ---------------------------------------------------------------------------
   11 · ARCHIVO AT TEXT SIZE
   Archivo's word space is 0.200em, tight for a text face (most sit at 0.25
   to 0.28), and at 16px on a phone that is 3.2px between words. Where two
   open counters meet across it, "look grown", the words read as one.
   Opened by 0.045em, which is under a pixel, and exactly the pixel that was
   missing. A grotesque this tightly spaced also wants a hair of tracking at
   small sizes; more on the dark grounds, where light type on dark closes up.
   Display sizes are untouched: tight is right for a headline.
   --------------------------------------------------------------------------- */
body, p, li, dd, .lede, .sec-lede, .argument__note p, .bay__copy {
  word-spacing: 0.045em;
}
p, li, dd { letter-spacing: 0.004em; }
.section--dark p, .section--dark li, .argument__note p, .foot p, .menu p {
  letter-spacing: 0.012em;
}
.display, .sec-head, .statement__head, .hero__word, .label, .sec-label,
.hero__phon, .near__name, .argument__v, .argument__nh {
  word-spacing: normal;
}

/* ---------------------------------------------------------------------------
   12 · CAPITALS ARE FOR LABELS
   Tracked capitals suit one to four words. Set as sentences they read
   slowly, because the eye finds words largely by their ascenders and
   descenders and capitals have none. The attribution under the argument ran
   to seven lines of capitals, and the distance caveat to four. Both are now
   small sentence-case notes, which is what they are.
   --------------------------------------------------------------------------- */
.argument__attrib, .address__caveat {
  text-transform: none !important;
  letter-spacing: 0.012em !important;
  font-size: clamp(0.78rem, 3.2vw, 0.84rem) !important;
  line-height: 1.62 !important;
  font-variation-settings: "wdth" 100, "wght" 400;
}

/* ---------------------------------------------------------------------------
   13 · THE HERO, PER BREAKPOINT
   Centred on a desktop, where a side-bearing correction would only pull the
   wordmark about 10px off centre; the correction belongs to left-aligned type.
   The price appeared twice on a desktop, in the gloss and in the corner. The
   corner keeps it there; on a phone the corner is hidden and the gloss keeps
   it. Once per screen.
   --------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .hero__word { margin-inline-start: 0; }
  .hero__gloss .hero__sep, .hero__gloss > span:last-child { display: none; }
}

/* ---------------------------------------------------------------------------
   14 · AT A GLANCE
   The statement section is gone; its six facts are a band of their own,
   straight under the hero, on the bone ground between two dark sections.
   --------------------------------------------------------------------------- */
.glance {
  background: var(--ground);
  padding-block: clamp(2.2rem, 7vw, 4.8rem);
}
.glance .statement__facts { margin-top: 0 !important; }

/* ---------------------------------------------------------------------------
   15 · THE SMALLEST PHONES
   Two rows whose middle column was a plain 1fr, which cannot shrink below
   its longest unbreakable run, so at 320px the row pushed out of its box.
   --------------------------------------------------------------------------- */
.near__i { grid-template-columns: 2.1rem minmax(0, 1fr) auto; }
@media (max-width: 360px) {
  .near__name { font-size: 1.06rem; }
  .near__i { gap: 0.6rem; }

  /* the bay row: numeral, then details over price, rather than three
     columns fighting for 280px */
  .bay button {
    grid-template-columns: auto minmax(0, 1fr) !important;
    column-gap: 0.9rem; row-gap: 0.3rem;
    padding-inline: 1rem;
  }
  .bay__n { grid-row: 1 / span 2; align-self: center; }
  .bay__price { grid-column: 2; justify-self: start !important; text-align: left !important; }
}

/* The numeral column was sized to its content, and I, II, III and IV are four
   different widths, so the address beside them stepped right on every row.
   A fixed column, wide enough for III, with the numerals centred in it: one
   left edge for the whole list. */
@media (max-width: 899px) {
  .bay button { grid-template-columns: 2.2rem minmax(0, 1fr) auto; }
  .bay__n { justify-self: center; text-align: center; width: 100%; }
}
@media (max-width: 360px) {
  .bay button { grid-template-columns: 2.2rem minmax(0, 1fr) !important; }
}

/* The gloss against a 208px wordmark read as a footnote. Lifted on desktop
   only; on a phone the wordmark is a quarter of the size and 1.28 is right. */
@media (min-width: 900px) { .hero__phon { font-size: 1.62em; } }

/* ---------------------------------------------------------------------------
   16 · SECTION NUMBERS WITHOUT AN EM DASH
   House rule: no em dashes anywhere. The "02: The idea" labels were the last
   ones on the page. The separator is now a hairline drawn by CSS: the same
   rhythm, and a drawn line is exact where the dash glyph brings its own weight
   and sidebearings in a wide Archivo.
   --------------------------------------------------------------------------- */
.sec-label__n { color: var(--amber-deep); }
.section--dark .sec-label__n, .address .sec-label__n { color: var(--amber); }
.sec-label__n::after {
  content: "";
  display: inline-block;
  width: 1.8em; height: 1px;
  margin: 0 0.75em 0 0.8em;
  background: currentColor;
  opacity: 0.55;
  vertical-align: 0.32em;
}
