/* ===========================================================================
   Curtis Austin Contracting Services
   Built to concept 2 - Built Around Your Story.
   Mockup: design/mockup/home-864.png (864px native, built at 1200px, x1.389).

   Every value below traces to a measurement in design/SPEC.md. If a number
   here is not in SPEC.md, it is a bug - not a preference. The comment after
   each token is the mockup reading it came from.

   BUILT AT 1200, NOT 1440. Every value in this file was re-derived at
   1200/1440 of what it was, which is the same measurement read against a
   narrower page: the mockup is a set of ratios, and the build width is the
   one number that turns them into pixels. The `N mockup` comment beside each
   token is unchanged and still the reading it came from, so nothing here has
   stopped being traceable - only the multiplier moved.

   AND NO PHOTOGRAPH BLEEDS. Every rail that ran its art to the viewport edge
   now stops at the container, and every hero photograph sits inside the
   frame. Band BACKGROUNDS still run full width - the olive CTA, the olive
   statement band, the split band's olive half - because those are the page's
   ground, not its artwork, and stopping them at the gutter would turn a band
   into a box.
   =========================================================================== */

:root {
  /* --- Colour ---  SPEC section: Colour.
     Sampled by dominant-colour counting over flat regions, never named by eye.
     There is ONE cream. Every band except the call to action sits on it, and
     contrast comes from photography and the single olive band. */
  --cream:     #F2EDE4;
  --gutter:    #DDD7CA;   /* the ground OUTSIDE the 1200 sheet, desktop only */
  --sage:      #E4E4D6;   /* the process band, the one tinted band on the page */
  --olive:     #68684C;
  --gold:      #C0842C;
  --ink:       #130C09;   /* headings */
  --ink-body:  #342E2B;   /* body copy */
  --paper:     #FFFFFF;   /* the button on the olive band */

  /* --- Layout ---  SPEC section: Container. */
  --wrap:  1080px;        /* CONTENT width: ink extent x45 -> x822, 778 mockup */
  --gut:     60px;        /* canvas edge -> first ink = 45 mockup */
  --frame: calc(var(--wrap) + var(--gut) * 2);   /* what max-width has to be */

  /* --- Type ---  SPEC section: Type scale.
     Sizes from cap-height ink / 0.70; line-heights baseline to baseline. */
  --f-h1:      52px;  --lh-h1:      59px;   /* 42.5 apart */
  --f-h2:      38px;  --lh-h2:      43px;   /* 31 apart */
  --f-h3:      31px;  --lh-h3:      36px;   /* 26 apart */
  --f-cond:    32px;                        /* Steps band heading */
  --f-body:    15px;  --lh-body:    24px;   /* 17.5 apart */
  --lh-body-hero: 27px;                     /* the hero sets that size looser */
  /* Lifted off the measured value on purpose, and SPEC.md §Container calls for
     it: the 1200 rescale took small copy to 10px from 12, and 10px is below
     what step, card and rail copy should be set at. SPEC's own instruction is
     to lift --f-small/--lh-small alone rather than move the build width back.
     14 is where the three-cell rows still balance -- 15 runs the third card to
     five lines. Everything else stays on its measured value. */
  --f-small:   14px;  --lh-small:   22px;   /* 10/17 measured; see note above */
  --lh-small-loose: 25px;                   /* Guidance rail, was 20 */
  --f-micro:   13px;                        /* step numeral, card "learn more" */
  --f-label:   17px;  --lh-label:   22px;   /* card label */
  --f-nav:     15px;                        /* nav, buttons */

  /* --- Rhythm ---  SPEC section: Vertical rhythm. The ladder is closed:
     SYSTEM.md forbids an eighth value. */
  --pad-band:       61px;  /* Steps band top,    44 mockup */
  --pad-band-end:   43px;  /* Steps band bottom, 31 mockup */
  --pad-cta:        28px;  /* CTA band top,      20 mockup */
  --gap-block:      43px;  /* derived = --pad-band-end */
  --gap-head-rule:  23px;  /* heading ink -> gold rule */
  --gap-rule-body:  25px;  /* gold rule -> body */
  --gap-head-body:  48px;  /* heading -> body, no rule */
  --gap-body-btn:   43px;  /* body -> button */
  --gap-body-note:  35px;  /* body -> trailing note */
  --gap-tile:       11px;  /* gallery tile -> tile, both axes */
  --gap-label-copy: 19px;  /* card label -> card copy */

  /* --- Components ---  SPEC section: Components. */
  --btn-h:       40px;   --btn-w:      175px;   /* 126 x 29 mockup */
  --btn-hero-h:  52px;   --btn-hero-w: 198px;   /* 143 x 37 mockup */
  --btn-cta-w:  192px;                          /* 138 x 28 mockup */
  --disc:        77px;                          /* 55 mockup, steps and services */
  --rule-w:      50px;   --rule-h:       3px;   /* 36 x 2 mockup */
  --radius:       7px;   /* ASSUMPTION - inside the antialiasing at 864 */

  /* --- Band art ---  SPEC section: Components. */
  --hero-h:      539px;   /* 388 mockup */
  --intro-art:   518px;   /* 373 mockup wide */
  --intro-art-h: 310px;   /* 223 mockup tall */
  --guide-art:   562px;   /* 405 mockup wide, bleeds off the left edge */
  --guide-art-h: 325px;   /* 234 mockup tall */
  --gallery:     767px;   /* 552 mockup */
  --gallery-h:   369px;   /* 266 mockup */

  /* --- Fonts ---  SPEC section: Fonts. An identification, not a measurement:
     if the mockup used something else, this is where the swap happens. */
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-cond: "Oswald", "Arial Narrow", Arial, sans-serif;
  --font-body: "Lato", "Segoe UI", Helvetica, Arial, sans-serif;
}

/* A minimal reset. Everything else belongs to the design. */
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--gutter); }
body {
  margin: 0;
  /* The WHOLE site is 1200 wide, not just its content. Constraining the body
     rather than each band is what makes that true of the olive CTA, the olive
     statement band and the split band too - they were the last three things
     still running to the viewport edge. --frame is 1080 + two 60 gutters, so
     this is the same 1200 every other value was derived against.
     The cream used to propagate from body to the canvas, so the gutters were
     cream too and the sheet had no edge. html now carries --gutter, which
     stops that propagation and gives the sheet a visible edge above 1200.
     Below 1200 the body fills the window, so the gutters disappear on their
     own -- no media query does it. */
  max-width: var(--frame);
  margin-inline: auto;
  background: var(--cream);
  color: var(--ink-body);
  font: var(--f-body)/var(--lh-body) var(--font-body);
  -webkit-font-smoothing: antialiased;
}
img, picture, svg, video { display: block; max-width: 100%; height: auto; }
h1, h2, h3, p, figure, blockquote { margin: 0; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }

.wrap {
  max-width: var(--frame);
  margin-inline: auto;
  padding-inline: var(--gut);
}

/* --- Type roles ---------------------------------------------------------- */

.h1, .h2, .h3 {
  font-family: var(--font-display);
  font-weight: 500;
  color: var(--ink);
  text-transform: uppercase;
}
.h1 { font-size: var(--f-h1); line-height: var(--lh-h1); }
.h2 { font-size: var(--f-h2); line-height: var(--lh-h2); }
.h3 { font-size: var(--f-h3); line-height: var(--lh-h3); }

.h-cond {
  font-family: var(--font-cond);
  font-weight: 500;
  font-size: var(--f-cond);
  line-height: 1.1;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.small { font-size: var(--f-small); line-height: var(--lh-small); }

/* The gold hairline. It carries the direction as much as the serif does,
   so it is a component, not a border on whatever happens to precede it. */
.rule {
  width: var(--rule-w);
  height: var(--rule-h);
  background: var(--gold);
  border: 0;
  margin: var(--gap-head-rule) 0 var(--gap-rule-body);
}
.rule--centre { margin-inline: auto; }

/* --- Buttons ------------------------------------------------------------- */

.btn {
  display: inline-flex;
  white-space: nowrap;
  align-items: center;
  justify-content: center;
  min-width: var(--btn-w);
  height: var(--btn-h);
  padding-inline: 22px;
  background: var(--olive);
  color: var(--cream);
  font-family: var(--font-cond);
  font-size: var(--f-nav);
  letter-spacing: 0.06em;   /* ASSUMPTION - inside the antialiasing at 864 */
  text-transform: uppercase;
  transition: background-color .18s ease;
}
.btn:hover, .btn:focus-visible { background: #55553D; }
.btn--hero { min-width: var(--btn-hero-w); height: var(--btn-hero-h); }
.btn--paper {
  min-width: var(--btn-cta-w);
  height: 39px;
  background: var(--paper);
  color: var(--ink);
}
.btn--paper:hover, .btn--paper:focus-visible { background: #ECE6DC; }

/* --- Header -------------------------------------------------------------- */

.site-header {
  height: 104px;                 /* 75 mockup */
  display: flex;
  align-items: center;
  gap: 33px;
}
/* The official wordmark. Jacob's specification, 4 September 2026, given in px
   rather than derived from a mockup -- so the tracking is px here too, not the
   em the rest of the stylesheet uses. The two gold rules that flanked the
   subtitle are gone with it. */
.brand { display: flex; align-items: center; gap: 14px; }
.brand__mark { width: 52px; height: 52px; flex: none; }
.brand__mark img { width: 100%; height: 100%; object-fit: contain; }
/* Not clipped to a circle: the mockup draws the figure on the cream with no
   disc behind it, and the extracted mark carries its own alpha. */
.brand__name {
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 1.5px;
  color: var(--ink);
  text-transform: uppercase;
  white-space: nowrap;
}
.brand__sub {
  display: block;
  margin-top: 8px;
  font-family: var(--font-cond);
  font-size: 10px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 2.2px;
  color: var(--gold);
  text-transform: uppercase;
  white-space: nowrap;
}
.nav { margin-left: auto; display: flex; gap: 32px; }
.navtoggle { display: none; }   /* only below 1100, where the links collapse */
.nav a {
  white-space: nowrap;
  font-family: var(--font-cond);
  font-size: var(--f-nav);
  letter-spacing: 0.06em;
  color: var(--ink);
  text-transform: uppercase;
  padding-block: 5px;
  border-bottom: 2px solid transparent;
}
.nav a:hover, .nav a[aria-current="page"] { border-bottom-color: var(--gold); }
.site-header .btn { margin-left: 28px; flex: none; }

/* --- Hero ---------------------------------------------------------------- */

/* The hero sits in the frame, not across the viewport, so everything
   positioned absolutely inside it measures against the container rather than
   against the window. That is what lets a photograph stop at the gutter while
   still being placed by a single `left`. */
.hero {
  position: relative;
  height: var(--hero-h);
  max-width: var(--frame);
  margin-inline: auto;
}
.hero__art { position: absolute; inset: 0 var(--gut); }
.hero__art .ph { height: 100%; border-radius: var(--radius); }

/* The hero photograph carries the copy on its left third, so that side needs
   a light field whatever the photograph does. The mockup's left edge reads as
   the page cream and clears to the photograph by about 62% across. */
.hero__scrim {
  position: absolute;
  inset: 0 var(--gut);
  /* Tuned against a real photograph rather than a render. The concept's hero
     was a dark dusk shot and a light scrim carried the copy easily; his own
     work is shot in daylight against white board-and-batten, so the heading
     needs a stronger hold on the left before it is readable. */
  background: linear-gradient(90deg,
    rgba(242,237,228,.97) 0%,
    rgba(242,237,228,.92) 26%,
    rgba(242,237,228,.62) 48%,
    rgba(242,237,228,.16) 68%,
    rgba(242,237,228,0) 82%);
}

.hero__inner {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
}
.hero__copy { max-width: 583px; }
.hero__copy p { max-width: 300px; }   /* longest line 214 mockup = 357 */
.hero .h1 { max-width: 583px; margin-bottom: 33px; }  /* longest line 370 mockup = 617 */
.hero__copy p { line-height: var(--lh-body-hero); }
.hero .btn { margin-top: var(--gap-body-btn); }

/* --- Home hero ------------------------------------------------------------
   Redrawn against design/mockup/home-1536.png (3 September 2026), which covers
   the hero only. Scale to the 1200 build is x0.78125, checked against the nav:
   14px ink there reads 15.6, and --f-nav is 15.

   Every other hero keeps its own measurements off the 864 mockups, so this is
   a modifier and none of the shared tokens moved.

   ONE KNOWN DEPARTURE. The mockup insets the photograph 55 (=43) from the
   canvas, where the page gutter is 60, so its hero is 1114 wide against 1080
   here. The gutter is the page's, set from the 864 mockup and used by every
   band below; widening the hero alone would leave it hanging past everything
   it sits on. Held at 60, and the 17px per side is the only geometry in this
   section that is not the new mockup's. */
/* The corner reads 12px in home-1536.png = 9.4 here, against the global
   --radius of 7 -- which SPEC still flags as an ASSUMPTION taken "inside the
   antialiasing at 864". The 1536 canvas is a better reading, but --radius
   rounds every photograph on every page, so it is taken locally here and the
   global assumption is left for a deliberate pass. */
.hero--home { height: 545px; }                 /* photo 112-808 = 697 mockup */
.hero--home .hero__art .ph { border-radius: 9px; }
/* The headline carries itself against the blown sky, but the 15px body copy
   and the button label do not. A soft cream field, gone by two thirds across,
   lifts them without bleaching the low sun the way the old scrim did. */
.hero--home .hero__art::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 9px;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(242,237,228,.74) 0%,
    rgba(242,237,228,.58) 22%,
    rgba(242,237,228,.30) 44%,
    rgba(242,237,228,.08) 58%,
    rgba(242,237,228,0) 68%);
}

/* 37 ink -> 52.9 mockup; tops 297/359/421 -> 62 apart. Smaller than --f-h1
   because the lines are longer: three of them now break after "house." */
.hero--home .h1 {
  /* 400, not the global 500. Measured on the same string rather than judged by
     eye: "MORE THAN A HOUSE." in home-1536.png has an ink density of 22.5% of
     its own bounding box, where real Playfair sets 22.2% at 400 and 25.8% at
     500. The 4% "narrow renderer" noted above was mostly this -- 500 sets the
     line 4.2% wider than the mockup, 400 only 2.6%. */
  font-weight: 400;
  font-size: 41px;
  line-height: 48px;
  /* The mockup's longest headline line reads 418, but real Playfair Display
     sets "MORE THAN A HOUSE." at 435 -- its renderer approximated the face and
     came out ~4% narrow. Matching its px would wrap the line it drew unwrapped,
     so the BREAKS are matched and the measure follows the real font. */
  max-width: 440px;
  margin-bottom: 27px;                         /* L3 baseline 458 -> body cap 495 */
}
/* Cap 'T' 14 ink -> 20 mockup -> 15.6, which is --f-body. Both lines run
   x137..482 mockup = 270, and the break falls after "construction,". */
.hero--home .hero__copy p {
  max-width: 305px;                            /* 270 mockup; 295 real, 322 with "and" */
  line-height: 25px;                           /* body tops 495 -> 527 */
}
.hero--home .btn { margin-top: 30px; }         /* body baseline 541 -> button 580 */
.hero--home .btn--hero { min-width: 169px; height: 42px; }   /* 216x54 mockup */

/* The copy sits inside the photograph rather than on the page gutter: 136
   mockup against the photo's own left edge at 55. */
.hero--home .hero__copy, .hero--home .btn { margin-left: 63px; }

/* --- Bands --------------------------------------------------------------- */

.band { padding-block: var(--pad-band) var(--pad-band-end); }

/* The process band is the one tinted field on the page. It spans the sheet,
   not the content width, so it reads as a band rather than a boxed card. */
.band--steps { background: var(--sage); }

/* The rail: art one side at its measured width, text the other.
   SYSTEM.md rule 1 - art never sits on the same side twice running. */
.rail {
  display: grid;
  align-items: center;
  gap: 50px;
}
.rail__text { max-width: 402px; }    /* 290 mockup, at body 21/29 */

/* Every rail sub-section is set the same, and the Homes rail is the model:
   heading at --f-h2, body at --f-body. The mockup does NOT draw them this way
   -- it sets Guidance and the Renovations closer at h3 over --f-small, and the
   inner pages at h3, so a reader met the same kind of section at two heading
   sizes and two body sizes depending on the page. Jacob's call, 3 September
   2026; recorded in SPEC.md alongside the --f-small lift.

   This is the one place a rail's TYPE is set. A rail rule below may set its
   own max-width, padding or grid -- that is geometry, measured per section and
   still traceable -- but it must not set font-size or line-height again. */
.rail__text .h2 {
  font-size: var(--f-h2);
  line-height: var(--lh-h2);
  /* The mockup's hand-placed line breaks were struck at 31px and produced
     orphans at 38 ("THE / DIFFERENCE IS", "MAKE ROOM / FOR / WHAT COMES").
     They are gone from the markup; the browser balances these instead, which
     holds whatever the cell width turns out to be. */
  text-wrap: balance;
}
.rail__text p   { font-size: var(--f-body); line-height: var(--lh-body); }

/* Intro - art LEFT, bleeding 22px past the container gutter (45 mockup). */
.rail--intro {
  grid-template-columns: var(--intro-art) minmax(0, 1fr);
  padding-inline: var(--gut);
  padding-block: 23px 0;          /* boundary 463 -> photo 480; photo bottom IS the boundary */
  gap: 55px;                      /* photo right 399 -> text 440 mockup */
}
.rail--intro .rail__art { height: var(--intro-art-h); }
.rail--intro .rail__art .ph { height: 100%; }

/* Homes - art RIGHT. The text cell is the narrow one here. */
.rail--homes {
  grid-template-columns: 264px var(--gallery);   /* 190 + 552 mockup = the full 1296 */
  gap: 48px;                                     /* text right 236 -> gallery 270 mockup */
  padding-block: 27px 25px;                      /* boundary 909 -> gallery 928; 1193 -> 1211 */
}
.rail--homes .rail__text { max-width: 264px; }   /* 190 mockup, body 21/29 */
.rail--homes .btn { margin-top: var(--gap-body-btn); }

/* Guidance - art LEFT and full-bleed to the viewport edge (x0 in the mockup). */
/* Guidance is a split PANEL, not a rail: photograph hard against the sheet's
   left edge, deep olive with cream copy filling the right. It was cream copy
   on the page ground beside a photograph, which read as one more band on the
   same field. The two halves meet with no gutter between them on purpose --
   the seam is the point. */
.rail--guide {
  grid-template-columns: var(--guide-art) minmax(0, 1fr);
  padding-inline: 0;
  padding-block: 0;
  gap: 0;
  align-items: stretch;
}
.rail--guide .rail__art { height: auto; min-height: var(--guide-art-h); }
.rail--guide .rail__art .ph { height: 100%; border-radius: 0; }
.rail--guide .rail__text {
  background: var(--olive);
  color: var(--cream);
  padding: 46px 58px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.rail--guide .rail__text .h2,
.rail--guide .signature__name { color: var(--cream); }
.rail--guide .rail__text p { color: rgba(242, 237, 228, .88); }
.rail--guide .signature__role { color: rgba(242, 237, 228, .62); }
/* The measured widths here (400 heading / 300 body) left the column two thirds
   full and drove the text 147px taller than the photograph beside it, so the
   block ran past Curtis at the top and the bottom. The grid already gives this
   cell 470px at the 1200 build; the text now uses it, which is what pulls the
   height back inside the frame. Capped rather than freed, because the rail
   spans the viewport and at 1600 the cell would otherwise run to 870. */
.rail--guide .rail__text { max-width: none; }
.rail--guide .rail__text p { max-width: 470px; }
.rail--guide .rail__text p + p { margin-top: 15px; }

.signature { margin-top: 11px; }   /* body ink 1363 -> signature 1371 = 8 mockup */
.signature__name {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 28px;
  line-height: 1;
  color: var(--ink);
}
.signature__role {
  margin-top: 7px;
  font-family: var(--font-cond);
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--ink-body);
  text-transform: uppercase;
}

/* --- Steps and Services: the row of three -------------------------------- */

.three {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.three__cell {
  display: grid;
  grid-template-columns: var(--disc) minmax(0, 1fr);
  gap: 18px;                       /* disc -> text, 13 mockup */
  align-items: start;
  padding-right: 33px;
}
.three__cell + .three__cell {
  border-left: 1px solid rgba(19, 12, 9, .12);
  padding-left: 37px;
}
/* The right padding separates a cell's text from the next cell's rule. The
   last cell has no next cell, so on that one it was 33px of dead margin
   against the container edge -- which is what pushed "Meaningful Additions"
   to four lines while its neighbours held three. */
.three__cell:last-child { padding-right: 0; }
.disc {
  width: var(--disc);
  height: var(--disc);
  border-radius: 50%;
  background: var(--olive);
  display: grid;
  place-items: center;
}
.disc svg { width: 37px; height: 37px; stroke: var(--cream); fill: none; stroke-width: 1.4; }
.step__num {
  font-family: var(--font-cond);
  font-size: var(--f-micro);
  letter-spacing: 0.12em;
  color: var(--gold);
}
.step__name, .card__name {
  font-family: var(--font-display);
  font-size: var(--f-label);
  line-height: var(--lh-label);
  color: var(--ink);
  text-transform: uppercase;
}
/* 108 mockup, which at the 1200 build measured 150 -- but the text column it
   sits in is 194px (232 in the first cell), so a seventh of every cell was
   dead space on top of the 33px padding already there. The paragraph now fills
   its column and the padding does the separating. */
.three__cell p { max-width: none; }

.band--steps .h-cond { text-align: center; }
.band--steps .three { margin-top: 0; }   /* .rule already carries --gap-rule-body */

.card__more {
  display: inline-block;
  margin-top: var(--gap-label-copy);
  font-family: var(--font-cond);
  font-size: var(--f-micro);
  letter-spacing: 0.16em;
  color: var(--ink);
  text-transform: uppercase;
  border-bottom: 1px solid transparent;
}
.card__more:hover, .card__more:focus-visible { border-bottom-color: var(--gold); }

/* Services: a row of three with no heading over it, so its band is bounded by
   the icon discs rather than by text - 27/19 mockup, not the Steps band's
   44/31. SYSTEM.md: only the Steps padding may be copied. */
.band--services { padding-block: 38px 27px; }

/* --- Gallery ------------------------------------------------------------- */

.gallery {
  display: grid;
  grid-template-columns: 348px minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: 204px minmax(0, 1fr);
  gap: var(--gap-tile);
  height: var(--gallery-h);
}
.gallery > :nth-child(1) { grid-row: 1 / span 2; }
.gallery > :nth-child(4) { grid-column: 2 / span 2; }

/* --- Call to action ------------------------------------------------------ */

.cta {
  position: relative;
  background: var(--olive);
  color: var(--cream);
  min-height: 254px;              /* 157 mockup = 218; raised so the drawing
     can grow: at 58% it wants 248px of height and the old 218 band only had
     204 to give. */
  display: flex;
  align-items: center;
  overflow: hidden;
}
.cta .h2 { color: var(--cream); }
.cta > .wrap { width: 100%; }    /* a flex item does not fill on its own */
.cta__copy {
  position: relative;
  max-width: 517px;
  margin-left: 62px;             /* copy at x88 mockup = 147 build, gutter is 72 */
}
.cta__copy p { margin-top: 12px; font-size: var(--f-small); line-height: var(--lh-small-loose); }
.cta .btn { margin-top: 22px; }
/* The drawing sits on the band's floor, not floating in the middle of it.
   The supplied PNG carried 126px of transparent margin under the ink against
   44 above, so a centred contain fit left a 44px gap below the house and only
   24 above it -- the file was doing the spacing, not the CSS. The asset is
   trimmed to its ink now, the box is wider, and the fit is bottom-anchored
   with 14px of floor left under it. */
.cta__art {
  position: absolute;
  top: 0;
  right: max(var(--gut), calc(50% - var(--wrap) / 2));
  width: 58%;
  height: calc(100% - 10px);
  opacity: .38;
}
.cta__art .ph { height: 100%; }
/* The gold line drawing of the turret house, supplied 3 September 2026 and the
   last placeholder on the page. Transparent PNG -> webp with its alpha intact,
   so the olive band shows through the linework; contain rather than cover
   because a house drawing cropped at the eaves is worse than a small one. */
.cta__art img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: right bottom;
}

/* --- Footer -------------------------------------------------------------- */

.site-footer { padding-block: 15px 17px; }   /* boundary 1750 -> text 1765; 1803 -> 1820 */
.site-footer .wrap {
  display: flex;
  align-items: center;
  gap: 37px;
  flex-wrap: wrap;
}
.footer__items { margin-left: auto; display: flex; align-items: center; gap: 33px; flex-wrap: wrap; }
.footer__item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-cond);
  font-size: 11px;
  letter-spacing: 0.10em;
  color: var(--ink-body);
  text-transform: uppercase;
}
.footer__item svg { width: 15px; height: 15px; stroke: var(--gold); fill: none; stroke-width: 1.5; }
.footer__link { border-bottom: 1px solid rgba(192, 132, 44, .45); padding-bottom: 1px; }
.footer__link:hover, .footer__link:focus-visible { border-bottom-color: var(--gold); }
.socials { display: flex; gap: 8px; }
.socials a {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--olive);
  display: grid;
  place-items: center;
}
.socials svg { width: 13px; height: 13px; fill: var(--cream); }

/* --- Placeholders and unconfirmed facts ---------------------------------- */

/* Every photograph in the mockup is baked into the render and exists nowhere
   as a file. Until assets/MANIFEST.md comes back filled, each frame is a
   labelled box at its measured size - never a stock stand-in, which would
   ship. */
.ph {
  position: relative;
  background:
    repeating-linear-gradient(45deg,
      rgba(19, 12, 9, .045) 0 10px, rgba(19, 12, 9, .025) 10px 20px);
  border: 1px dashed rgba(19, 12, 9, .22);
  border-radius: var(--radius);
  display: grid;
  place-items: center;
  min-height: 67px;
  overflow: hidden;
}
.ph span {
  font-family: var(--font-cond);
  font-size: 10px;
  letter-spacing: 0.10em;
  color: rgba(19, 12, 9, .5);
  text-transform: uppercase;
  text-align: center;
  padding: 10px 13px;
}
.ph--bleed { border-radius: 0; }
.ph--dark { border-color: rgba(255, 255, 255, .3); }
.ph--dark span { color: rgba(255, 255, 255, .75); }

/* A fact the concept invented and the client has not confirmed. It stays
   VISIBLE. A plausible-looking placeholder is worse than an obvious gap,
   because it ships. */
.todo {
  display: inline-block;
  padding: 2px 7px;
  background: rgba(192, 132, 44, .16);
  border: 1px dashed var(--gold);
  border-radius: 3px;
  font-family: var(--font-cond);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: #6E4A12;
  text-transform: uppercase;
}

/* --- Responsive ---------------------------------------------------------
   SYSTEM.md section 5. These breakpoints are the only numbers on the page
   with no mockup behind them: one width was drawn. They sit where a measured
   column stops working at its measured type size. */

@media (max-width: 1100px) {
  .rail, .rail--intro, .rail--homes, .rail--guide {
    grid-template-columns: minmax(0, 1fr);
    gap: 33px;
    max-width: var(--wrap);
    padding-inline: var(--gut);
    padding-block: var(--pad-band) var(--pad-band-end);
  }
  .rail__art { order: -1; }        /* art first: the work before the words */
  .rail__text,
  .rail--homes .rail__text,
  .rail--guide .rail__text { max-width: 467px; }
  .rail--guide .rail__art .ph { border-radius: var(--radius); }
  .gallery { height: auto; grid-template-rows: 204px 167px; }
  .nav { display: none; }
  .three__cell { padding-right: 20px; }
  .three__cell + .three__cell { padding-left: 20px; }
}

@media (max-width: 767px) {
  .brand { gap: 10px; }
  .brand__mark { width: 42px; height: 42px; }
  .brand__name { font-size: 19px; letter-spacing: 1px; }
  .brand__sub { font-size: 8px; letter-spacing: 1.6px; }

  :root {
    --gut: 20px;
    --f-h1: 33px;   --lh-h1: 38px;
    --f-h2: 27px;   --lh-h2: 32px;
    --f-h3: 23px;   --lh-h3: 28px;
    --f-cond: 22px;
    --f-body: 15px; --lh-body: 22px;
  }
  .hero { height: auto; padding-block: 0 var(--pad-band-end); }
  /* `inset: 0 var(--gut)` is what contains the photograph on a wide screen;
     once the art is in flow, a left offset just shoves it off the side. */
  .hero__art { position: relative; inset: auto; height: 250px; margin-bottom: 27px; }
  .hero__scrim { display: none; }
  .hero__inner { display: block; }
  .hero__copy, .hero__copy p, .hero .h1 { max-width: none; }
  .cta__copy { margin-left: 0; }
  .three { grid-template-columns: minmax(0, 1fr); gap: 27px; }
  .three__cell + .three__cell {
    border-left: 0;
    border-top: 1px solid rgba(19, 12, 9, .12);
    padding-left: 0;
    padding-top: 27px;
  }
  .three__cell p { max-width: none; }
  .gallery { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; }
  .gallery > :nth-child(1), .gallery > :nth-child(4) { grid-row: auto; grid-column: auto; }
  .gallery > * { min-height: 167px; }
  .site-header { height: auto; padding-block: 17px; flex-wrap: wrap; gap: 13px; }
  .site-header .btn { margin-left: 0; }
  .footer__items { margin-left: 0; gap: 15px; }
  .cta__art { display: none; }
}

/* The wordmark's mobile header height. This has to sit AFTER the 1100 block,
   not with the rest of the mobile wordmark rules above it: 1100 also matches at
   760 and sets padding-block 17, so declared earlier it simply loses.

   min-height, not height. The 1100 block lets the header wrap so the button can
   drop below the brand, and a fixed 72 would clip it when it does. 72 is exact
   while the row fits and a floor once it cannot -- see SPEC. */
@media (max-width: 767px) {
  .site-header { min-height: 72px; padding-block: 0; align-items: center; }
}

/* ===========================================================================
   HOMES PAGE
   Mockup: design/mockup/homes-883.png (883px native, built at 1200px, x1.359).
   A different canvas from the home page, so every reading here was converted
   at its own scale. Shapes 3 and 4 in SYSTEM.md's catalogue - the captioned
   three-up and the two-up - are first drawn on this page and live here.

   Where this mockup's container reads 1331 against the home page's 1296, the
   home page wins: a 2.7% difference between two separately generated renders
   is drift, not a design decision, and one container is the point.
   =========================================================================== */

/* The hero photograph is INSET here, not full-bleed: it starts 285px in and
   runs to the right edge, so the copy sits on cream and needs no scrim. */
.hero--inset { height: 502px; }              /* 369 mockup */
.hero--inset .hero__art { left: 285px; }     /* photo x210 mockup */
.hero--inset .hero__scrim { display: none; }
.hero--inset .h1 { max-width: 467px; }       /* longest line 278 mockup = 453 */
.hero--inset .hero__copy p { max-width: 317px; }

/* Rail with the text LEFT and the art right. */
.rail--textleft {
  grid-template-columns: minmax(0, 1fr) 610px;   /* photo 449 mockup */
  gap: 91px;                                    /* text ends 333 -> photo 400 */
  padding-block: 23px 24px;                      /* boundary 438 -> photo 455; 679 -> 697 */
}
.rail--textleft .rail__art { height: 306px; }    /* 225 mockup */
.rail--textleft .rail__art .ph { height: 100%; }
.rail--textleft .rail__text { max-width: 308px; }/* heading 226 mockup */

/* Shape 3: the captioned three-up. Photograph, gold numeral, serif name,
   condensed caption. */
.band--featured { padding-block: 28px 30px; }    /* boundary 698 -> ink 719; 981 -> 1003 */
.band--featured .h-cond { text-align: center; }

/* A measured gap is ink to ink; a CSS margin is box to box, and the box is
   taller than the ink by its half-leading. Every gap in this band is the
   measured one MINUS that leading, which is why these numbers are smaller
   than the tokens the home page uses for the same two elements. */
.band--featured .rule { margin: 8px auto 13px; } /* ink gaps 18 and 20 */
.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap-tile);                          /* 8 mockup = 13, same as the home gallery */
}
.card__shot { height: 235px; }                   /* 173 mockup */
.card__meta {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr);    /* numeral x40, name x67 mockup */
  margin-top: 20px;                              /* ink gap 34, less the name's leading */
  align-items: baseline;
}
.card__caption {
  grid-column: 2;
  margin-top: 7px;                               /* ink gap 24, less both leadings */
  font-family: var(--font-cond);
  font-size: 11px;
  letter-spacing: 0.10em;
  color: var(--ink-body);
  text-transform: uppercase;
}

/* Shape 4: the two-up. A looser gap than the gallery's - measured, not chosen. */
.band--pair { padding-block: 3px 28px; }         /* art-bounded: 1004 -> 1006; 1171 -> 1191 */
.pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;                                     /* 13 mockup */
}
.pair > * { height: 226px; }                     /* 166 mockup */

.band--three-up { padding-block: 37px 45px; }    /* 1192 -> ink 1219; 1291 -> 1324 */

/* Details rail: art LEFT and bleeding to the viewport edge, like Guidance. */
.rail--detail {
  grid-template-columns: 560px minmax(0, 1fr);   /* photo 412 mockup, x0 */
  padding-inline: var(--gut);
  padding-block: 7px 0;
  gap: 50px;                                     /* photo ends 411 -> text 448 */
}
.rail--detail .rail__art { height: 259px; }      /* 191 mockup */
.rail--detail .rail__art .ph { height: 100%; }
.rail--detail .rail__text { max-width: 400px; }   /* 317 measured, but that was
   struck against an h3 heading; at --f-h2 it stranded "THE" alone on line one.
   The cell has 470px of grid to give, so widening it costs no other section. */

@media (max-width: 1100px) {
  .rail--textleft, .rail--detail {
    grid-template-columns: minmax(0, 1fr);
    gap: 33px;
    max-width: var(--frame);
    padding-inline: var(--gut);
    padding-block: var(--pad-band) var(--pad-band-end);
  }
  .rail--textleft .rail__text, .rail--detail .rail__text { max-width: 467px; }
  .rail--detail .rail__art .ph { border-radius: var(--radius); }
  .hero--inset { height: auto; padding-block: 0 var(--pad-band-end); }
  .hero--inset .hero__art { position: relative; left: 0; height: 250px; margin-bottom: 27px; }
}

@media (max-width: 767px) {
  .cards, .pair { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .card__shot, .pair > * { height: 183px; }
  .hero--inset .h1, .hero--inset .hero__copy p { max-width: none; }
}

/* ===========================================================================
   OUR APPROACH PAGE
   Mockup: design/mockup/our-approach-862.png (862px native, x1.392).
   First drawing of SYSTEM.md shapes 5 and 7 - the numbered alternating rail
   and the split band - so both live here.
   =========================================================================== */

.hero--approach { height: 552px; }               /* photo band 101-501 = 400 */
.hero--approach .hero__art {
  left: 541px;                                   /* photo x390 of content 29-840 */
  bottom: auto;
  height: 509px;                                 /* photo rows 101-469 = 369 */
}
.hero--approach .h1 { max-width: 433px; }
.hero--approach .hero__copy p { max-width: 300px; }

/* The eyebrow above the H1. New in our-approach-870.png; gold condensed caps,
   the same family and tracking the step numerals use. */
.eyebrow {
  font-family: var(--font-cond);
  font-size: var(--f-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 14px;
}

/* Rail, now an outlined card with the photograph flush inside its left half
   (our-approach-870.png: photo x30-430 of a card spanning the full content
   width, text beginning at x455). It was a plain rail with a 43px gap. */
.rail--approach {
  grid-template-columns: 533px minmax(0, 1fr);   /* photo 49.3% of content */
  gap: 0;
  padding-block: 0;
  border: 1px solid rgba(19, 12, 9, .12);
  border-radius: var(--radius);
  overflow: hidden;
  align-items: stretch;
}
.rail--approach .rail__art { height: 386px; }    /* card rows 503-782 = 279 */
.rail--approach .rail__art .ph { height: 100%; border-radius: 0; border: 0; }
.rail--approach .rail__text {
  /* "PERSONAL GUIDANCE." sets 407 and "CLEAR DECISIONS." 342, so a content
     width between them gives the mockup's three lines. 444 - 74 padding = 370.
     Balance is off here on purpose: the mockup's break is deliberately uneven
     and balance evens it into "GUIDANCE. CLEAR". */
  max-width: 444px;
  align-self: center;
  padding: 34px 40px 34px 34px;                  /* text ink starts x455, card x430 */
}
.rail--approach .rail__text .h2 { text-wrap: normal; }
.rail--approach .rail__text p { max-width: 344px; }   /* 247 mockup */

/* Shape 5, restructured. Four outlined cards in a 2x2 grid, photograph flush
   inside each card's left, instead of four full-width rows alternating the art
   side. The alternation was the old band's whole rhythm; the grid replaces it,
   so the :nth-child rule that enforced it is gone rather than left dangling. */
.band--steps4 { padding-block: 25px 10px; }
.band--steps4 .h-cond { text-align: center; }
.band--steps4 .rule { margin: 8px auto 17px; }

.steps4 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;                                     /* card gap 14 mockup */
}
.step4 {
  display: grid;
  grid-template-columns: 57% minmax(0, 1fr);     /* photo 228 of a 401 card */
  align-items: stretch;
  border: 1px solid rgba(19, 12, 9, .12);
  border-radius: var(--radius);
  overflow: hidden;
  padding-block: 0;
}
.step4__art { order: -1; height: auto; min-height: 254px; }  /* photo LEFT in all four */
.step4__art .ph { height: 100%; border-radius: 0; border: 0; }
.step4__text {
  max-width: none;
  align-self: center;
  padding: 22px 22px 22px 24px;
}
.step4 .step__num { display: block; margin-bottom: 5px; }
.step4 .h2 { margin-bottom: 15px; }

/* Shape 7, restructured. The olive is an inset rounded block rather than a
   full-bleed half-band, and the photograph and the cream card sit inside it as
   one rounded unit on the right.

   NOTE, because it reverses a decision recorded in SPEC.md: that note says
   "band BACKGROUNDS still run full width ... stopping them at the gutter turns
   a band into a box." This mockup draws exactly that box, olive 31-838 inside
   a canvas of 870. It is done here because the mockup draws it here, and the
   other five pages still bleed -- so the two treatments now coexist. Worth a
   decision before a sixth page is built. */
.split--boxed {
  display: grid;
  /* The mockup's unit is 573 wide with 27 to the olive's right edge = 600.
     Held at 578 instead: its renderer sets the olive heading ~4% narrow, so at
     600 the real face takes "YOU SHOULD ALWAYS KNOW" to a fourth line. 22px
     off the unit buys the heading its three lines and keeps the 48px gap
     between the copy and the photograph, which shaving the padding would not. */
  grid-template-columns: minmax(0, 1fr) 578px;
  max-width: var(--wrap);
  margin-inline: auto;
  min-height: 366px;                             /* olive 1300-1565 = 265 */
  margin-block: 37px 48px;                       /* steps end 1273, CTA starts 1600 */
  background: var(--olive);
  border-radius: var(--radius);
  align-items: center;
}
.split--boxed .split__olive {
  background: none;
  padding: 52px 34px 46px 43px;                  /* ink x62, olive edge x31 */
}
.split--boxed .split__panel {
  display: grid;
  grid-template-columns: 52% minmax(0, 1fr);     /* photo 222 of the 428 unit */
  align-self: stretch;
  margin: 18px 27px 18px 0;                      /* unit 390-818, olive ends 838 */
  border-radius: var(--radius);
  overflow: hidden;
}
.split--boxed .split__art .ph { height: 100%; border-radius: 0; border: 0; }
.split--boxed .split__cream {
  background: var(--cream);
  padding: 28px 22px;
}
.split--boxed .split__cream .h3 { text-wrap: balance; }
.split__olive {
  background: var(--olive);
  color: var(--cream);
  padding: 43px 42px 29px var(--gut);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.split__olive .h3 { color: var(--cream); max-width: 583px; }
.split__cream {
  padding: 43px var(--gut) 29px 50px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.split__cream p { font-size: var(--f-small); line-height: var(--lh-small-loose); max-width: 350px; }

/* The three reassurance items inside the olive half: gold line icons, no
   discs, hairline between - shape 9's weight, on a dark ground. */
.assure { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 28px; }
.assure > div { padding-right: 18px; }
.assure > div + div { border-left: 1px solid rgba(242, 237, 228, .25); padding-left: 18px; }
.assure svg { width: 25px; height: 25px; stroke: var(--cream); fill: none; stroke-width: 1.3; }
.assure p {
  margin-top: 8px;
  font-family: var(--font-cond);
  font-size: 11px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
}

/* The closing band, also an inset rounded block on this page, carrying the
   house line drawing rather than the photograph the 862 mockup asked for. */
.cta--boxed {
  max-width: var(--wrap);
  margin-inline: auto;
  border-radius: var(--radius);
  overflow: hidden;
}
.cta--boxed > .wrap { max-width: none; padding-inline: 43px; }
.cta--boxed .cta__copy { margin-left: 0; max-width: 580px; }   /* heading sets 564 */
.cta--boxed { min-height: 254px; }
.cta--boxed .cta__art { right: 24px; width: 60%; }

@media (max-width: 1100px) {
  .rail--approach {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .rail--approach .rail__art { height: 250px; }
  .rail--approach .rail__text { max-width: none; }
  .hero--approach { height: auto; padding-block: 0 var(--pad-band-end); }
  .hero--approach .hero__art { position: relative; left: 0; height: 250px; margin-bottom: 27px; }
  .steps4 { grid-template-columns: minmax(0, 1fr); }
  .step4 { grid-template-columns: 45% minmax(0, 1fr); }
  .split--boxed { grid-template-columns: minmax(0, 1fr); }
  .split--boxed .split__panel { margin: 0 22px 22px; }
  .split__olive, .split__cream { padding-inline: var(--gut); }
  .split--boxed .split__olive { padding-inline: 34px; }
  .split--boxed .split__cream { padding-inline: 26px; }
}

@media (max-width: 767px) {
  .assure { grid-template-columns: minmax(0, 1fr); gap: 15px; }
  .assure > div + div { border-left: 0; border-top: 1px solid rgba(242,237,228,.25); padding-left: 0; padding-top: 15px; }
  .hero--approach .h1, .hero--approach .hero__copy p { max-width: none; }
}

/* ===========================================================================
   RENOVATIONS PAGE
   Mockup: design/mockup/renovations-883.png (883px native, x1.359).
   Same canvas as the Homes page, so the same conversion - and the same
   decision on the container: this mockup's ink extent reads 1259 against the
   home page's 1296, which is the 3% drift between two separately generated
   renders and not a second container. --wrap wins.

   Two things are drawn here for the first time:
     - SYSTEM.md shape 6, the before/after pair with its caption chips
     - a hairline BETWEEN bands. Five of them, and they are the only thing
       separating six cream bands that would otherwise run together.
   =========================================================================== */

/* A fourth heading size, and the first new type role since SPEC.md.

   It is measured, not chosen: four headings on this page (before/after, new
   space, renovation-without, and the CTA) solve to 27-30 against the home
   page's H3 at 36 by the same string-width method, and their baseline pitch
   reads 20-22 mockup = 33-36 build. Both readings land on 29/34, and 34/29 is
   1.17 - the same ratio H1, H2 and H3 all carry.

   The intro heading is NOT this size. It solves to 33 and pitches at 25 (41
   build), which is H3. That one band running larger than the four below it is
   the page's own hierarchy, not drift: the difference shows in both readings
   and it shows by eye. */
:root {
  --f-h4: 24px;  --lh-h4: 28px;   /* solved from 4 headings, x1.359 */
}
.h4 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--f-h4);
  line-height: var(--lh-h4);
  color: var(--ink);
  text-transform: uppercase;
}

/* The band separator. Measured at 630, 934, 1137, 1331 and 1438 as a 2px run
   sampling #E3DBD0 against the #EDE7E0 cream - which is a 1px rgba(19,12,9,.12)
   hairline resolved down to 883, since 0.12 x (883/1440) = 0.074 and the
   sampled delta is 0.07. That is the same hairline the row of three and the
   numbered rail already use, so it is the system's line, not a new value.

   It sits on the section rather than on .wrap so it spans the viewport, which
   is what the mockup draws: the line runs edge to edge, past the container. */
.rband { border-top: 1px solid rgba(19, 12, 9, .12); }

/* Hero - full-bleed photograph with the scrim, like the home page and unlike
   Homes and Our Approach, whose heroes are inset. The photograph runs x0-882
   and fades to cream by the left third. */
.hero--reno { height: 446px; }                   /* photo 70-397 = 328 mockup */
.hero--reno .h1 { max-width: 350px; }            /* "HOME AGAIN." 236 mockup = 385 */
.hero--reno .hero__copy p { max-width: 325px; }  /* longest body line 235 mockup */

/* Intro rail - art LEFT, bleeding 15px inside the container gutter (x33
   mockup against the text gutter at 51). */
.rail--reno-intro {
  grid-template-columns: 638px minmax(0, 1fr);   /* photo 469 mockup */
  padding-inline: var(--gut);
  gap: 52px;                                     /* photo ends 501 -> text 539 */
  padding-block: 12px 20px;                      /* 403 -> photo 412; 615 -> 630 */
}
.rail--reno-intro .rail__art { height: 278px; }  /* 204 mockup */
.rail--reno-intro .rail__art .ph { height: 100%; }
.rail--reno-intro .rail__text p { max-width: 256px; } /* body 188 mockup */
/* The cell is sized to the HEADING, not to the body - the .rail--guide
   pattern. "WHAT COMES NEXT." measures 198 mockup = 323 build, but 323 is the
   width it has at the size this mockup draws it (it solves to 33); set at H3
   the same string needs 358, and a cell of 323 breaks it after "COMES", which
   the mockup does not. The paragraph keeps its own measured measure. */
.rail--reno-intro .rail__text { max-width: 300px; }

/* Shape 3 again - the captioned three-up, first drawn on Homes. Same numeral,
   same serif name; the caption is the one difference. Homes captions a
   photograph with a place (condensed caps, "OLIVE BRANCH, MS"); this page
   captions it with a sentence, so it is set as copy and not as a label. */
.rband--ways { padding-block: 24px 17px; }       /* 631 -> heading ink 649; 922 -> 934 */
.rband--ways .h-cond { text-align: center; }
.rband--ways .rule { margin: 7px auto 11px; }    /* ink gaps 15 and 13, less leading */
.rband--ways .card__shot { height: 227px; }      /* 167 mockup */
.card__note {
  grid-column: 2;
  max-width: 201px;                              /* 148 mockup - it wraps well
     inside the card, which is drawn rather than accidental: the caption
     measure is 241 in a card 429 wide */
  margin-top: 7px;                               /* ink gap 19, less both leadings */
  font-size: var(--f-body);
  line-height: var(--lh-body);                   /* it solves to 16 with a
     baseline pitch of 26, and 26/16 is 1.63 - the body ratio, not the small
     one. So this is body copy on a render that runs ~10% small, and it takes
     the body pair. At --f-small it fits the 241 measure in two lines where
     the mockup sets three. */
  color: var(--ink-body);
}

/* Shape 6 - the before/after pair. Two photographs at DIFFERENT widths, which
   is what separates it from shape 4's two-up: the before is a narrow 254 and
   the after runs 670, so the band reads left to right as the room opening up.
   Each carries an olive chip in its lower-left corner. */
.rband--ba { padding-block: 20px 20px; }         /* 935 -> photo 950; 1122 -> 1137 */
.ba {
  display: grid;
  grid-template-columns: 293px 212px minmax(0, 1fr);  /* 156 and 411 mockup */
  column-gap: 8px;                              /* photo to photo, 6 mockup */
  align-items: center;
}
.ba__text { max-width: 288px; }                  /* sized to the heading:
     "BETTER FLOW. A HOME" is 181 mockup = 295 at the size drawn, and needs 340
     at h4 to keep the line the mockup breaks after "HOME" */
.ba__text p { max-width: 248px; }                /* body 183 mockup */
.ba__shot { position: relative; height: 234px; } /* 172 mockup */
/* .ph span already styles every label inside a placeholder frame, and it wins
   on specificity over a bare .chip - so the chip is selected through .ph. */
.ph .chip {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 22px;                                  /* 16 mockup */
  padding-block: 0;
  display: inline-flex;
  align-items: center;
  padding-inline: 17px;
  background: var(--olive);
  color: var(--cream);
  font-family: var(--font-cond);
  font-size: 11px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  border-radius: 0 5px 0 var(--radius);          /* it sits into the photograph's
     rounded corner, so only the inner corner is squared off */
}

/* New space rail - art RIGHT and full-bleed to the viewport edge.
   SYSTEM.md rule 1 holds across the page: intro art LEFT, then a band of
   cards, then the before/after pair, then this one RIGHT, then a row with no
   art, then the closing rail LEFT. No two adjacent bands hold their art the
   same way. */
.rail--reno-new {
  grid-template-columns: 328px minmax(0, 1fr);   /* photo x322 mockup = 525 */
  padding-inline: var(--gut);
  gap: 50px;
  padding-block: 3px 2px;                        /* the photograph is the band */
}
.rail--reno-new .rail__art { height: 259px; }    /* 191 mockup */
.rail--reno-new .rail__art .ph { height: 100%; }
.rail--reno-new .rail__text { max-width: 267px; }/* body 196 mockup */

/* Shape 2 - the row of three, unchanged from the home page's Services band.
   Only the band padding is this page's. */
.rband--three { padding-block: 22px 28px; }      /* 1332 -> disc 1348; 1418 -> 1438 */

/* Closing rail - art LEFT, full-bleed, and its bottom edge IS the CTA
   boundary: the photograph runs into the olive band with no cream between. */
.rail--reno-close {
  grid-template-columns: 614px minmax(0, 1fr);   /* photo 452 mockup, x0 */
  padding-inline: var(--gut);
  gap: 53px;                                     /* photo ends 451 -> text 490 */
  padding-block: 2px 0;
}
.rail--reno-close .rail__art { height: 238px; }  /* 175 mockup */
.rail--reno-close .rail__art .ph { height: 100%; }
.rail--reno-close .rail__text { max-width: 278px; }   /* heading 204 mockup */
.rail--reno-close .rail__text p { max-width: 278px; }

@media (max-width: 1100px) {
  .rail--reno-intro, .rail--reno-new, .rail--reno-close {
    grid-template-columns: minmax(0, 1fr);
    gap: 33px;
    max-width: var(--frame);
    padding-inline: var(--gut);
    padding-block: var(--pad-band) var(--pad-band-end);
  }
  .rail--reno-intro .rail__text,
  .rail--reno-new .rail__text,
  .rail--reno-close .rail__text { max-width: 467px; }
  .rail--reno-new .rail__art .ph,
  .rail--reno-close .rail__art .ph { border-radius: var(--radius); }
  .hero--reno { height: auto; padding-block: 0 var(--pad-band-end); }
  .ba { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 18px; }
  .ba__text { grid-column: 1 / -1; max-width: 467px; margin-bottom: 33px; }
}

@media (max-width: 767px) {
  :root { --f-h4: 20px; --lh-h4: 24px; }
  .hero--reno .h1, .hero--reno .hero__copy p { max-width: none; }
  .rband--ways .card__shot { height: 183px; }
  .card__note { max-width: none; }
  .ba { grid-template-columns: minmax(0, 1fr); }
  .ba__shot { height: 183px; }
}

/* ===========================================================================
   ABOUT PAGE
   Mockup: design/mockup/about-864.png (864px native, x1.389 — the home page's
   own canvas, so the conversion is the home page's too).

   The page the whole brief turns on: it is the one that says there are two
   owners. SYSTEM.md shape 4, the two-up, carries them, and it is unequal here
   on purpose — Curtis's frame is 557 against Roline's 507, because her cell is
   the one that takes the divider's padding.

   It reuses the Renovations band hairline (.rband) at three boundaries, and
   the Renovations h4 at three headings, which is the first time either has
   been wanted twice. Neither is new here.
   =========================================================================== */

/* Hero — photograph INSET from the left, like Homes and Our Approach. The
   copy sits on cream and needs no scrim. This one carries a gold rule between
   the H1 and the body, which the other three heroes do not, and its button is
   the STANDARD size: it reads 118x29 mockup = 197x48, which is --btn, not the
   238x62 --btn-hero the other heroes use.

   ITS H1 IS SMALLER THAN --f-h1, and that is measured three ways on the home
   page's own canvas, so it is not drift:
     - cap ink 25 against the home page's 28
     - two lines width-solve to 52.3 where the home page's own strings solve
       to 56 through the same code
     - and the fit settles it. The photograph starts at mockup x310, leaving
       425 build for the copy; "RELATIONSHIPS." is drawn 410 wide. At --f-h1
       the same string needs 487 and runs into the photograph.
   Line-height is the measured baseline pitch, 37 mockup. */
.hero--about { height: 436px; }                  /* photo 69-383 = 314 mockup */
.hero--about .h1 { font-size: 43px; line-height: 52px; }
.hero--about .hero__art { left: 431px; }         /* photo x310 mockup */
.hero--about .hero__scrim { display: none; }
.hero--about .h1 { max-width: 433px; }           /* the cell is sized to the
     heading at the token size: "RELATIONSHIPS." reads 246 mockup = 410, which
     is its width at the ~52 this render draws; at --f-h1 it needs 487 */
.hero--about .hero__copy p { max-width: 317px; } /* longest line 208 mockup */
.hero--about .hero__copy .rule { margin-bottom: 18px; }  /* rule 238 -> body ink 252 */

/* Intro rail — art RIGHT, and the text cell is INDENTED, not at the gutter.
   That indent is structural rather than drift: the leaf line drawing occupies
   x30-140 of the mockup, and the copy starts at x143 = 238 build. The drawing
   is Jacob's to supply (assets/MANIFEST.md), so the space it sits in is held
   open rather than closed up. */
.rail--about-intro {
  grid-template-columns: minmax(0, 1fr) 604px;   /* photo 435 mockup */
  padding-left: 198px;                           /* text x143 mockup - the
     leaf drawing's space, held open. Structural, not a bleed. */
  padding-right: var(--gut);
  gap: 50px;                                     /* text ends 348 -> photo 396 */
  padding-block: 0 17px;                         /* photo top IS the band top */
}
.rail--about-intro .rail__art { height: 302px; } /* 218 mockup */
.rail--about-intro .rail__art .ph { height: 100%; }
.rail--about-intro .rail__text { max-width: 308px; }   /* heading 205 mockup =
     342 at the size drawn, 353 at H3 */

/* Shape 4 — the two-up, carrying the two owners.

   Two equal columns split at mockup x430, where the hairline runs. Curtis's
   photograph fills his column (x99-431); Roline's is inset 47 by the divider's
   padding (x458-760), which is why the frames are 557 and 507 and not one
   number. The block is 1103 wide inside a 1296 container and centres. */
.band--people { padding-block: 27px 31px; }      /* 627 -> heading ink 646; copy 965 -> 987 */
.band--people .h-cond { text-align: center; }
.band--people .rule { margin: 5px auto 17px; }   /* ink gaps 12 and 8, less leading */
.pair--people {
  max-width: 919px;                             /* x99 -> x761 mockup */
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.pair--people > * + * {
  border-left: 1px solid rgba(19, 12, 9, .12);   /* the divider, mockup x430 */
  padding-left: 39px;                            /* photo x458 against x431 */
}
.owner { text-align: center; }
.owner__shot { height: 250px; }                  /* 180 mockup */
.owner .h3 { margin-top: 12px; }                 /* photo 861 -> name ink 870 */
.owner__role {
  margin-top: 7px;
  font-family: var(--font-cond);
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--gold);
  text-transform: uppercase;
}
.owner p {
  max-width: 292px;                              /* 208 mockup */
  margin-inline: auto;
}
.owner .rule { margin: 10px auto 13px; }         /* role ink 899 -> 910 -> copy 923 */

/* The olive statement band. About and Our Approach each carry one mid-page and
   still close on the olive CTA — SYSTEM.md §1: a page ENDS on olive, it does
   not carry olive only once. Our Approach draws it as shape 7, the split band;
   this one runs the full width with the house drawing behind its right, which
   is the CTA's shape without the ask. */
.statement {
  position: relative;
  background: var(--olive);
  color: var(--cream);
  min-height: 240px;                             /* 988-1160 = 173 mockup */
  display: flex;
  align-items: center;
  overflow: hidden;
}
.statement > .wrap { width: 100%; }
.statement__copy {
  position: relative;
  max-width: 383px;                              /* sized to the heading: "ONE
     SHARED STANDARD." is 483 at the size drawn, 450 at H3 */
  margin-left: 28px;                             /* copy x63 mockup = 105 */
}
.statement .h3 { color: var(--cream); }
.statement__copy p {
  margin-top: 17px;                              /* heading ink 1064 -> body 1088 */
  max-width: 283px;                              /* body line 1, 198 mockup */
}
.statement__art {
  position: absolute;
  top: 0;
  right: max(var(--gut), calc(50% - var(--wrap) / 2));
  width: 43%;
  height: 100%;
  opacity: .35;
}
.statement__art .ph { height: 100%; }

/* Shape 2 — the row of three, unchanged from the home page's Services band. */
.band--guides { padding-block: 25px 32px; }      /* 1161 -> heading ink 1179; 1293 -> 1316 */
.band--guides .h-cond { text-align: center; }
.band--guides .rule { margin: 6px auto 7px; }    /* ink gaps 10 and 5, less leading */
/* Each cell carries its own rule between the label and the copy, which the
   home page's Services cells do not. */
.band--guides .three__cell .rule { margin: 4px 0 10px; }
.band--guides .three__cell p { max-width: 138px; }  /* 98 mockup, narrower than
     the home page's 180 - this band sets four lines a cell where Services sets
     three */

/* "Proudly local" — art LEFT, bleeding 24px inside the container gutter. */
.rail--about-local {
  grid-template-columns: 543px minmax(0, 1fr);   /* photo 391 mockup */
  padding-inline: var(--gut);
  gap: 61px;                                     /* photo ends 416 -> text 460 */
  padding-block: 18px 12px;                      /* 1317 -> photo 1330; 1481 -> 1490 */
}
.rail--about-local .rail__art { height: 211px; } /* 152 mockup */
.rail--about-local .rail__art .ph { height: 100%; }
.rail--about-local .rail__text { max-width: 333px; }  /* heading 222 mockup */
/* Body at --f-body on a tight leading, not at --f-small. The width settles it
   the way it settled the hero: "We live and work in the communities we serve."
   is drawn 317 wide, which is that string at 15px. At --f-small it is 218, and
   the line runs on past the break the mockup makes. The measured pitch is 22,
   so it takes the nearer of the two measured small line-heights. */
.rail--about-local .rail__text p {
  max-width: 317px;                              /* body 214 mockup = 357 at the
     size drawn, 380 at --f-body, which keeps the mockup's break after
     "serve." */
  line-height: var(--lh-small-loose);            /* pitch 13.5 mockup = 22 */
}
/* The service area, set as the footer sets it — same icon, same weight. It is
   the one place on the page that names where he works. */
.rail--about-local .footer__item { margin-top: 27px; }  /* body 1435 -> ink 1454 */

/* "We're with you" — text LEFT, art RIGHT and inset from the container edge
   rather than bleeding: the photograph ends at mockup x801 against a container
   edge at x828. */
.rail--about-close {
  grid-template-columns: minmax(0, 1fr) 561px;   /* photo 404 mockup */
  gap: 50px;
  padding-block: 19px 12px;                      /* 1491 -> text ink 1505; 1652 -> 1662 */
}
.rail--about-close .rail__art { height: 210px; }/* 151 mockup */
.rail--about-close .rail__art .ph { height: 100%; }
/* Wider than the 358 the mockup draws for this cell, and the reason is the
   second signature. The mockup's is an unreadable scrawl standing in for a
   name nobody had yet; "Roline Saunders Austin" set as type is far longer than
   that squiggle, and two real names side by side do not fit 358. The heading
   and the paragraph keep their own measured measures. */
.rail--about-close .rail__text { max-width: 417px; }
.rail--about-close .rail__text p {
  max-width: 252px;                              /* body 181 mockup - and that
     is the string "You'll always know who is responsible," at 15px, which is
     where the mockup breaks it */
  line-height: var(--lh-small-loose);
}

/* Two signatures side by side, and one caption under both. Roline's is set as
   type like his: MANIFEST #13 is her signature scanned, and until it arrives
   neither is an image, so the pair stays consistent. */
.signatures { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 20px; }
.signatures .signature__name { font-size: 25px; }
.signature--pair { margin-top: 15px; }           /* body ink 1596 -> signature 1607 */

@media (max-width: 1100px) {
  .rail--about-intro, .rail--about-local, .rail--about-close {
    grid-template-columns: minmax(0, 1fr);
    gap: 33px;
    max-width: var(--frame);
    padding-inline: var(--gut);
    padding-block: var(--pad-band) var(--pad-band-end);
  }
  .rail--about-intro .rail__text,
  .rail--about-local .rail__text,
  .rail--about-close .rail__text { max-width: 467px; }
  .hero--about { height: auto; padding-block: 0 var(--pad-band-end); }
  .hero--about .hero__art { position: relative; left: 0; height: 250px; margin-bottom: 27px; }
  .statement__art { display: none; }
  .statement__copy { margin-left: 0; }
}

@media (max-width: 767px) {
  .hero--about .h1, .hero--about .hero__copy p { max-width: none; }
  .pair--people { grid-template-columns: minmax(0, 1fr); gap: 33px; }
  .pair--people > * + * { border-left: 0; padding-left: 0; }
  .owner__shot { height: 200px; }
  .signatures { gap: 13px; }
}

/* ===========================================================================
   CONTACT PAGE
   Mockup: design/mockup/contact-887.png (887px native, x1.353).

   The only page on the site that is not purely static, and the only one whose
   failure mode is silent: see api/contact.js. Everything below is the form's
   appearance; whether it POSTS is that file's problem, and it does.

   Draws SYSTEM.md shapes 8 and 9 — the form and its side panel, and the
   gold-icon three-up — for the first and only time, and carries shape 2 as
   well, which is what makes the two weights of that row visible rather than
   arbitrary: an olive disc where the row is a step, a gold line icon where it
   is reassurance.
   =========================================================================== */

:root {
  /* The side panel's ground, and the site's SECOND surface colour. The first
     five pages hold to one cream on purpose; this is a CARD, not a band, and
     the mockup tints it: sampled #EFE4D9 against this render's #F1EBE2 cream,
     a delta of 2/7/9 carried onto --cream. SYSTEM.md shape 8 already named it
     ("a bordered card on a slightly warmer tint"), so it is a value the system
     expected rather than a second cream let in through the back door. */
  --tint: #F0E6DB;
  --hair: rgba(19, 12, 9, .12);      /* the band and cell hairline, named now
     that four pages use it */
}

.hero--contact { height: 426px; }                /* photo 71-381 = 311 mockup */
.hero--contact .hero__art { left: 418px; }       /* photo x309 mockup */
.hero--contact .h1 { max-width: 383px; }         /* "TELL US WHAT" 245 mockup */
.hero--contact .hero__copy p { max-width: 321px; }  /* longest line 237 mockup */

/* Shape 8 — the form and its side panel. */
.band--form { padding-block: 42px 41px; }        /* 386 -> heading ink 417; button 915 -> 945 */
.formband {
  display: grid;
  grid-template-columns: 621px minmax(0, 1fr);   /* form 459 mockup, panel 285 */
  gap: 52px;                                     /* form ends 516 -> panel 555 */
  align-items: start;
}
.formband > .rail__text { max-width: none; }
.formband .h2 + .rule { margin: 24px 0 20px; }   /* ink 435 -> 453 -> 468 */
.formband__intro p { max-width: 444px; }         /* 328 mockup */

/* --- The form ------------------------------------------------------------ */

.form { margin-top: 32px; }                      /* intro ink 496 -> label 520 */
.form__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 34px;                                     /* field to field, 25 mockup */
}
.form__row + .form__row { margin-top: 32px; }    /* input 564 -> label 588 */
.field label,
.form__legend {
  display: block;
  margin-bottom: 11px;                           /* label ink 526 -> input 534 */
  font-family: var(--font-cond);
  font-size: 12px;                               /* cap ink 7 against the panel
     label's 12, which solves to 26 */
  letter-spacing: 0.10em;
  color: var(--ink-body);
  text-transform: uppercase;
}
.field input,
.field textarea {
  display: block;
  width: 100%;
  height: 43px;                                  /* 32 mockup */
  padding: 0 13px;
  background: transparent;
  border: 1px solid rgba(19, 12, 9, .22);
  border-radius: 3px;
  font: var(--f-body)/var(--lh-body) var(--font-body);
  color: var(--ink);
  transition: border-color .18s ease;
}
.field textarea {
  height: 113px;                                 /* 84 mockup */
  padding: 12px 13px;
  resize: vertical;
}
.field input:focus,
.field textarea:focus { outline: none; border-color: var(--olive); }
.field--wide { grid-column: 1 / -1; }

/* The three-way project picker. Real radio inputs, styled as the cards the
   mockup draws — a div listening for clicks would not be reachable by
   keyboard and would not submit with the form. */
.planning { margin-top: 27px; }                  /* input 634 -> label ink 654 */
.planning__opts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;                                     /* 15 mockup */
}
.planning__opts label {
  display: flex;
  align-items: center;
  gap: 13px;
  height: 67px;                                  /* 49 mockup */
  padding-inline: 17px;
  border: 1px solid rgba(19, 12, 9, .22);
  border-radius: 3px;
  font-family: var(--font-cond);
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink);
  text-transform: uppercase;
  cursor: pointer;
  margin-bottom: 0;
  transition: border-color .18s ease, background-color .18s ease;
}
.planning__opts svg {
  width: 25px;
  height: 25px;
  flex: none;
  stroke: var(--ink);
  fill: none;
  stroke-width: 1.4;
}
.planning input { position: absolute; opacity: 0; pointer-events: none; }
.planning input:checked + label {
  border-color: var(--olive);
  background: rgba(104, 104, 76, .10);
}
.planning input:focus-visible + label { outline: 2px solid var(--olive); outline-offset: 2px; }

.form__note {
  max-width: 392px;                              /* it breaks after "plans," */
  margin-top: 20px;                              /* textarea 830 -> ink 845 */
  font-size: var(--f-small);
  line-height: var(--lh-small-loose);
  color: var(--ink-body);
}
.form__send { margin-top: 32px; }                /* note ink 861 -> button 885 */
.form__send .btn { border: 0; cursor: pointer; }
.form__send .btn[disabled] { opacity: .6; cursor: default; }
/* The line that tells a visitor what actually happened. It is never written
   optimistically: see api/contact.js. */
.form__status {
  margin-top: 13px;
  font-size: var(--f-small);
  line-height: var(--lh-small-loose);
  min-height: 20px;
}
.form__status--ok { color: #3F6B34; }
.form__status--bad { color: #A3341F; }

/* --- The side panel ------------------------------------------------------ */

.panel {
  background: var(--tint);
  border: 1px solid rgba(19, 12, 9, .10);
  border-radius: 10px;
  padding: 45px 33px 33px;                       /* panel top 408 -> heading ink 441 */
  text-align: center;
}
.panel .h4 { }
.panel .rule { margin: 10px auto 28px; }         /* ink 456 -> rule 470 -> disc 497 */
.panel__item {
  display: grid;
  grid-template-columns: 63px minmax(0, 1fr);    /* disc 47 mockup */
  gap: 30px;                                     /* disc 632 -> text 654 */
  align-items: center;
  text-align: left;
}
.panel__item + .panel__item { margin-top: 32px; }/* disc top 497 -> 567 = 70 mockup */
.panel__item .disc { width: 63px; height: 63px; }
.panel__item .disc svg { width: 28px; height: 28px; }
.panel__label {
  font-family: var(--font-cond);
  font-size: 22px;                               /* "EMAIL US" 52 mockup = 84 */
  letter-spacing: 0.06em;
  color: var(--ink);
  text-transform: uppercase;
}
.panel__value {
  margin-top: 5px;
  font-family: var(--font-cond);
  font-size: 17px;                               /* the value line reads one
     step down from its label, 137 mockup for the email */
  letter-spacing: 0.04em;
  color: var(--ink-body);
  text-transform: uppercase;
}
.panel__art { margin: 22px auto 0; max-width: 275px; }
.panel__art .ph { min-height: 158px; }
.panel__note {
  margin-top: 23px;
  font-size: var(--f-body);
  line-height: var(--lh-body);
  color: var(--ink-body);
}

/* --- What happens next: shape 2, with the numerals the home page's Steps
       band uses. Its cell dividers are DASHED and warm here, where the home
       page's are solid ink at .12 - measured, not restyled. ---------------- */
.band--next { padding-block: 32px 32px; }        /* 946 -> heading ink 970; copy 1080 -> 1104 */
.band--next .h-cond { text-align: center; }
.band--next .rule { margin: 7px auto 22px; }
.band--next .three__cell + .three__cell {
  border-left: 1px dashed rgba(192, 132, 44, .40);
}
/* This band's step names are CONDENSED, where the home page's Steps band sets
   the same element in the serif. Measured, not restyled: "WE'LL MAP THE NEXT
   STEP" is drawn 221 build wide, which is Oswald at 25 and nothing near
   Playfair at --f-label. */
.band--next .step__name {
  font-family: var(--font-cond);
  font-size: 21px;
  line-height: 1.15;
  letter-spacing: 0.04em;
}
.band--next .three__cell p { max-width: 167px; }
/* Tighter cell gutters than the home page's Services row: this band's text
   column measures 273 build (cell 3, x682-850 mockup) and the label is one
   line at that width. */
.band--next .three__cell { padding-right: 10px; }
.band--next .three__cell + .three__cell { padding-left: 22px; }

/* --- The rail: art LEFT at the gutter, text and signature right ---------- */
.rail--contact {
  grid-template-columns: 517px minmax(0, 1fr);   /* photo 382 mockup */
  gap: 48px;                                     /* photo ends 425 -> text 461 */
  padding-block: 27px 26px;                      /* 1105 -> photo 1125; 1340 -> 1359 */
}
.rail--contact .rail__art { height: 292px; }     /* 216 mockup */
.rail--contact .rail__art .ph { height: 100%; }
.rail--contact .rail__text { max-width: 358px; } /* heading line 2, 260 mockup */
.rail--contact .rail__text p { max-width: 338px; }  /* body 247 mockup */

/* --- "You don't need to have everything figured out" --------------------- */
.band--figured { padding-block: 38px 38px; }     /* 1360 -> heading ink 1388; copy 1491 -> 1520 */
.figured {
  display: grid;
  grid-template-columns: 450px minmax(0, 1fr);
  gap: 50px;
  align-items: center;
}
.figured__text { max-width: 433px; }             /* sized to the heading:
     "EVERYTHING FIGURED OUT." is 435 at the size drawn, 498 at H3 */
.figured__text p {
  max-width: 333px;                              /* body 238 mockup */
  font-size: var(--f-small);
  line-height: var(--lh-small-loose);
}

/* Shape 9 — the gold-icon three-up. The same row as shape 2 in a lighter
   weight: a gold line icon and no disc, centred, each under its own rule.
   Contact is the page that carries both, one band above the other, which is
   what makes the distinction visible rather than arbitrary. */
.goldthree {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  text-align: center;
}
.goldthree > div { padding-inline: 15px; }
.goldthree > div + div { border-left: 1px dashed rgba(192, 132, 44, .40); }
.goldthree svg {
  width: 48px;                                   /* 36 mockup */
  height: 48px;
  margin-inline: auto;
  stroke: var(--gold);
  fill: none;
  stroke-width: 1.3;
}
.goldthree h3 {
  margin-top: 22px;                              /* icon 1416 -> label ink 1432 */
  font-family: var(--font-cond);
  font-size: 18px;                               /* "YOUR IDEAS" 57 mockup = 93 */
  letter-spacing: 0.06em;
  color: var(--ink);
  text-transform: uppercase;
}
.goldthree .rule { margin: 10px auto 13px; }
.goldthree p { font-size: var(--f-small); line-height: var(--lh-small-loose); }

@media (max-width: 1100px) {
  .formband { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .rail--contact {
    grid-template-columns: minmax(0, 1fr);
    gap: 33px;
    padding-block: var(--pad-band) var(--pad-band-end);
  }
  .rail--contact .rail__text { max-width: 467px; }
  .hero--contact { height: auto; padding-block: 0 var(--pad-band-end); }
  .hero--contact .hero__art { position: relative; left: 0; height: 250px; margin-bottom: 27px; }
  .figured { grid-template-columns: minmax(0, 1fr); gap: 33px; }
  .figured__text { max-width: 467px; }
}

@media (max-width: 767px) {
  .hero--contact .h1, .hero--contact .hero__copy p { max-width: none; }
  .form__row { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .form__row + .form__row { margin-top: 20px; }
  .planning__opts { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .planning__opts label { height: 53px; }
  .band--next .three__cell + .three__cell { border-left: 0; border-top: 1px dashed rgba(192,132,44,.40); }
  .goldthree { grid-template-columns: minmax(0, 1fr); gap: 27px; }
  .goldthree > div + div { border-left: 0; border-top: 1px dashed rgba(192,132,44,.40); padding-top: 27px; }
  .panel { padding-inline: 20px; }
}

/* ===========================================================================
   FILLED FRAMES
   A frame keeps its `.ph` class when a real photograph goes into it, so every
   height and every `.ph { height: 100% }` rule above still applies and no
   layout rule had to change. The modifier only takes the placeholder's own
   dressing off.
   =========================================================================== */
.ph--filled { background: none; border: 0; }
/* <picture> is inline by default and carries no height, so an img inside one
   has nothing for `height: 100%` to resolve against and falls back to its
   intrinsic size. The hero is the only place using <picture> today; this makes
   the wrapper transparent to the layout so any future one behaves too. */
/* Pinned, not `height: 100%`. .ph is a grid whose row is sized by its content,
   so a percentage height on the item is circular and silently resolves to
   auto -- the picture took the image's intrinsic 362 inside a 280 box and only
   looked right because .ph clips. Absolute against .ph's existing
   position: relative gives the wrapper the box's real height. */
.ph--filled picture { position: absolute; inset: 0; display: block; }
.ph--filled img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}


/* ===========================================================================
   THE COLLAPSED MENU, BELOW 1100
   The 1100 block above hides .nav outright, which left that range with no
   navigation at all -- a gap that predates this pass but got worse when
   "Plan Your Home" moved inside the nav. The hamburger therefore lives at
   1100, not at the 768 the rest of the mobile work uses, so the whole
   collapsed range gets a real menu. Sizing stays in the 768 block below.
   =========================================================================== */
@media (max-width: 1100px) {
  .site-header { position: relative; }
  .navtoggle {
    display: grid;
    gap: 5px;
    margin-left: auto;
    width: 46px; height: 46px;
    align-content: center; justify-items: end;
    padding: 0 2px; background: none; border: 0; cursor: pointer;
  }
  .navtoggle span {
    display: block; width: 26px; height: 2px;
    background: var(--ink);
    transition: transform .18s, opacity .18s;
  }
  body.nav-open .navtoggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  body.nav-open .navtoggle span:nth-child(2) { opacity: 0; }
  body.nav-open .navtoggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  .nav {
    display: none;
    position: absolute;
    top: 100%;              /* under the header, whatever height it is */
    left: 0; right: 0;
    margin: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px var(--gut) 20px;
    background: var(--cream);
    border-top: 1px solid rgba(19, 12, 9, .12);
    box-shadow: 0 14px 24px rgba(19, 12, 9, .10);
    z-index: 30;
  }
  body.nav-open .nav { display: flex; }
  .nav a {
    padding-block: 14px;
    font-size: 15px;
    border-bottom: 1px solid rgba(19, 12, 9, .10);
  }
  .nav a:hover, .nav a[aria-current="page"] { border-bottom-color: rgba(19, 12, 9, .10); color: var(--gold); }
  .nav .btn { margin: 16px 0 0; width: 100%; border-bottom: 0; }
  .nav .btn:hover { color: var(--cream); }
}

/* ===========================================================================
   MOBILE, BELOW 768
   Jacob's specification, 4 September 2026. Everything here is mobile-only and
   overrides the blocks above rather than editing them, so the desktop build is
   untouched and one deletion reverts the lot. It is last in the file on
   purpose: several rules below restate what the 1100 and 767 blocks already
   set, and the cascade is what makes them stick.
   =========================================================================== */
@media (max-width: 767px) {

  /* --- global ---------------------------------------------------------- */
  /* The coloured rails come off: below 768 the sheet IS the window. */
  html { background: var(--cream); }

  :root {
    --gut: 20px;                       /* side padding */
    --f-body:  16px;  --lh-body:  26px;   /* body floor, 15 -> 16 */
    --f-small: 16px;  --lh-small: 26px;   /* small copy is body-sized here */
    --lh-small-loose: 27px;
    --f-micro: 12px;                      /* label floor, 13 -> 12 is a RAISE
                                             at mobile: --f-micro was 13 and the
                                             uppercase condensed labels read
                                             smaller than their size, so 12 is
                                             the floor the spec asks for and the
                                             tracking below carries the rest. */
  }
  .btn { height: 46px; }                  /* tap target floor */

  /* Section rhythm: 60 between every pair, once. Padding on both neighbours
     is what made it 112 -- two sections each contributing 56. The gap is a
     margin on the section BOUNDARY now, so it is stated once and cannot
     double; the coloured bands keep their own smaller inner padding, which
     sits inside their background and does not add to the gap. */
  main > section + section { margin-top: 60px; }
  .rail, .rail--intro, .rail--homes { padding-block: 0; }
  .band { padding-block: 40px; }
  .cta { padding-block: 34px; }

  /* --- header: 68 tall, logo left, hamburger right --------------------- */
  .site-header {
    height: 68px;
    min-height: 0;
    padding-block: 0;
    flex-wrap: nowrap;
    gap: 0;
    position: relative;
    z-index: 20;
    background: var(--cream);
  }
  .brand__mark { width: 40px; height: 40px; }
  .brand__name { font-size: 18px; }
  .brand__sub  { font-size: 8px; }

  /* the hamburger and the panel are set in the 1100 block above; only the
     header's own height changes here */

  /* --- hero: 280 photograph, cream card lapping it by 40 ---------------- */
  .hero--home { height: auto; padding-block: 0 0; }
  .hero--home .hero__art {
    position: relative;
    inset: auto;
    height: 280px;
    margin-bottom: 0;   /* the 767 block sets 27 here, which was eating 27 of
                           the card's -40 and leaving a 13px lap */
  }
  .hero--home .hero__art .ph { border-radius: 0; }
  .hero--home .hero__art::after { display: none; }   /* the copy is off the photo now */
  .hero--home .hero__inner {
    position: relative;
    height: auto;
    display: block;
    /* Inset from the sides so the 40px lap can be SEEN. Full-bleed, a cream
       card lapping a photograph on a cream page is invisible -- it just reads
       as a shorter photograph, which is the "photo, then text" this was meant
       to stop. The photo showing either side of the card's top corners is what
       makes it a card. Copy therefore sits 40 from the screen edge here, not
       the global 20. */
    margin: -40px var(--gut) 0;
    padding: 30px var(--gut) 34px;
    background: var(--cream);
    max-width: none;
  }
  .hero--home .hero__copy, .hero--home .h1, .hero--home .hero__copy p { margin-left: 0; max-width: none; }
  /* Three lines, as specified. 40px and three lines are mutually exclusive on
     a real phone: the longest of the three, "MORE THAN A HOUSE.", sets 418px
     and a 390 screen has 350 to give -- which is why it was breaking to four.
     So 40 is the ceiling, reached at ~460 and above, and the size steps down
     with the viewport only as far as the three lines need. */
  .hero--home .h1 {
    /* Retuned for the inset card: the measure is now 100vw minus the card's
       20 either side and its 20 padding either side, so 80 rather than 46. */
    font-size: clamp(25px, calc((100vw - 82px) / 10.6), 40px);
    line-height: 1.1;
    margin-bottom: 18px;
  }
  .hero--home .hero__copy p { font-size: 16px; line-height: 26px; }
  .hero--home .btn { margin: 24px 0 0; height: 46px; }

  /* --- process: three compact rows on sage ------------------------------ */
  .band--steps .three { gap: 24px; }
  .band--steps .three__cell {
    grid-template-columns: 52px minmax(0, 1fr);
    gap: 16px;
    padding: 0;
    align-items: center;
  }
  .band--steps .three__cell + .three__cell { border-top: 0; padding-top: 0; }
  .band--steps .disc { width: 52px; height: 52px; }
  .band--steps .disc svg { width: 24px; height: 24px; }
  .band--steps .step__num { margin-bottom: 2px; }
  .band--steps .h2 { margin-bottom: 4px; }

  /* --- gallery: heading first, then a real grid ------------------------- */
  .rail--homes .rail__text { order: -1; }     /* undoes .rail__art{order:-1} */
  .rail--homes .rail__art  { order: 0; }
  .rail--homes .btn { margin-bottom: 28px; }
  .gallery {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    gap: 8px;
    height: auto;
  }
  .gallery > * { min-height: 0; }
  .gallery > :nth-child(1) { grid-column: 1 / span 2; grid-row: auto; height: 220px; }
  .gallery > :nth-child(2), .gallery > :nth-child(3) { height: 168px; }
  .gallery > :nth-child(4) { grid-column: 1 / span 2; height: 190px; }
  /* NOT .gallery .ph here: that is the grid item itself, and at (0,2,0) it
     ties with .gallery > :nth-child(n) and wins on order, which silently threw
     away every tile height above and left the images at their intrinsic size. */
  .gallery img { height: 100%; }

  /* --- Curtis: portrait and olive panel as ONE card --------------------- */
  .rail--guide { gap: 0; padding-block: 0; }   /* the boundary margin gives the gap */
  .rail--guide .rail__art { height: 300px; min-height: 0; margin-bottom: 0; }
  .rail--guide .rail__art .ph { border-radius: 0; }
  .rail--guide .rail__text { padding: 28px; max-width: none; }
  .rail--guide .rail__text .h2 { font-size: 30px; line-height: 34px; }
  .rail--guide .rail__text p { font-size: 16px; line-height: 26px; max-width: none; }

  /* --- service cards ----------------------------------------------------- */
  .band--services .three__cell {
    grid-template-columns: 54px minmax(0, 1fr);
    gap: 16px;
    padding: 20px 0;
    align-items: start;
  }
  .band--services .three__cell + .three__cell { padding-top: 20px; }
  .band--services .disc { width: 54px; height: 54px; }
  .band--services .disc svg { width: 25px; height: 25px; }
  .band--services .card__more { margin-top: 10px; }

  /* --- footer: stacked and centred -------------------------------------- */
  .site-footer { padding-block: 40px 44px; }
  .site-footer .wrap { flex-direction: column; align-items: center; gap: 22px; text-align: center; }
  .footer__items { flex-direction: column; align-items: center; gap: 18px; margin-left: 0; }
  .footer__item { justify-content: center; }
  .brand { justify-content: center; }
}

/* A narrow-phone step for the H1 only. At 360 the About hero sets
   "RELATIONSHIPS." 344px wide against 320 of content, which pushed the whole
   document 4px past the viewport. Predates the mobile pass -- found testing
   it. Scaling the heading is better than overflow-wrap, which would break the
   word mid-syllable rather than reflow it. */
@media (max-width: 400px) {
  :root { --f-h1: 29px; --lh-h1: 34px; }
  /* About sets its own 43/52 rather than the token, so the token step above
     never reaches it -- that is the one actually overflowing. */
  .hero--about .h1 { font-size: 29px; line-height: 34px; }
}
