/* ============================================================
   Green & Co. - Kitchen and bath remodeling.

   THE FIELD RECORD.

   This page is a documented job file, not a described service. Two real
   remodels, walked from wreck to finish. Its structure is a drawn rail down
   the left that carries chapter numerals and stage metadata and never holds
   prose; the main field belongs to the photography, which is allowed to break
   past the rail and off the edge of the frame. Type arrives in two registers
   only: chapter-scale Cinzel that opens a chapter, and small Montserrat
   metadata in the rail. Paragraphs are rationed to one per chapter.

   Gold does exactly one job here: it marks POSITION IN THE SEQUENCE, which
   chapter you are in and which stage of a build you are looking at. It is
   never a decorative rule and never a bullet, so when it appears it means
   something. That is the whole accent budget.

   Built from the brand primitives in tokens.css and nothing else: the palette
   as tokenised, Cinzel and Montserrat, gold as accent only, the 2px structural
   radius. Values here are this page's decisions; rationale sits beside them.
   ============================================================ */

.rec {
  --rail: clamp(52px, 7vw, 116px);
  --gut: clamp(20px, 3vw, 40px);
  --ch-space: clamp(72px, 11vh, 150px);
  --hair: rgba(245, 245, 245, .16);
  --hair-ink: rgba(13, 13, 13, .16);

  background: var(--gc-black);
  color: var(--gc-text-on-dark);
  overflow-x: clip;
}

/* home.css sets a 15px bottom margin on .field, a class this page reuses for
   its own chapter body. On the LAST field on the page that margin escapes .rec
   and exposes 15px of the body's #F5F5F5 between two black surfaces, which
   reads as a white seam above the footer. Scoped to the final field only, so
   every approved interior spacing value is left exactly where it is. */
.rec > .ch:last-child > .field:last-child { margin-bottom: 0; }

/* Every chapter is the same two-column frame: a rail that holds position, and
   a field that holds the work. The rail's hairline is DRAWN, not implied by
   content, so the page keeps a spine even where a chapter is mostly empty. */
.ch {
  position: relative;
  /* The hairline is drawn AT --rail, so the field has to start past it or the
     text sits on the line. Caught by measuring, not by looking: 20 pixels of
     hairline fell inside a paragraph's first line box and dragged its worst-case
     contrast to 4.04 against a 5.77 median. The layout problem was the real one,
     the contrast reading was just how it surfaced. */
  padding-left: calc(var(--rail) + clamp(18px, 2.2vw, 38px));
  padding-right: var(--gut);
  padding-block: var(--ch-space);
}
.ch::before {
  content: "";
  position: absolute;
  left: var(--rail); top: 0; bottom: 0;
  width: 1px;
  background: var(--hair);
}
.ch--light { background: var(--gc-bg-light); color: var(--gc-text-on-light); }
.ch--light::before { background: var(--hair-ink); }

/* Rail contents. Metadata only: a numeral and short uppercase facts. Prose is
   forbidden here by design; the moment the rail carries a sentence it stops
   reading as an index and starts competing with the field. */
.rail {
  position: absolute;
  left: 0; top: var(--ch-space);
  width: var(--rail);
  padding-right: 14px;
  text-align: right;
}
.rail__num {
  display: block;
  font-family: var(--gc-font-serif);
  font-weight: var(--gc-weight-display);
  font-size: clamp(1.5rem, 2.6vw, 2.4rem);
  line-height: 1;
  color: var(--gc-accent);
}
.rail__meta {
  display: block;
  margin-top: 12px;
  /* Sized to the narrowest the rail ever gets. At .62rem/.24em the longest
     token ran 95px against an 87px usable rail at 1440 and clipped off the
     left edge. */
  font-size: .56rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--gc-text-muted);
  line-height: 2;
}
.ch--light .rail__meta { color: var(--gc-grey); }
/* tokens.css is explicit that raw gold on a light surface is 2.2:1 and fails.
   Measured here at 2.21 before this line existed. On light the numeral uses the
   ink variant, which is the same marker doing the same job at 4.8:1. */
.ch--light .rail__num { color: var(--gc-gold-ink); }

/* The field. Capped for reading; images are free to leave it. */
.field { max-width: 1180px; }

/* A chapter opens with one word at chapter scale. No label above it, no lede
   under it, nothing else in the band. The word IS the divider. */
.ch__word {
  font-family: var(--gc-font-serif);
  font-weight: var(--gc-weight-display);
  /* The min matters more than the max here. At 3.2rem the floor governed every
     viewport under 465px, and the longest chapter word ("Estimate") measured
     348px inside a 282px content box at 360. A single word cannot wrap, so it
     pushed the whole field to 348 and dragged the estimate chapter's phone,
     email, service area and reply time out to the right, where overflow-x: clip
     cut them off in silence. The clip is still needed by the estimate form, which
     leaves the frame on mobile, so it stays and the floor comes down instead: at
     2.2rem the 11vw term governs on every phone and the longest word fits with
     room to spare. Re-measure this if a longer chapter word is ever added. */
  /* Ceiling pulled down from 8.5rem. At 1440 the chapter dividers measured 136px
     against a 67px H1, so the largest type on the opening screen was a navigation
     label rather than the offer. This is an ads landing page before it is an
     editorial object; the chapter word still dominates its own band, at about
     1.35x the H1 instead of 2.03x. */
  font-size: clamp(2.2rem, 11vw, 6.5rem);
  line-height: .92;
  letter-spacing: .005em;
  margin: 0 0 clamp(28px, 4vw, 56px);
  text-wrap: balance;
}
/* One paragraph per chapter, then the chapter stops explaining itself. */
.ch__lede {
  margin: 0;
  max-width: 58ch;
  font-size: 1.04rem;
  line-height: 1.72;
  color: var(--gc-text-muted);
  text-wrap: pretty;
}
.ch--light .ch__lede { color: var(--gc-grey); }
.ch__act { margin: clamp(28px, 3.6vw, 42px) 0 0; }

.detail-intro__rule {
  display: block;
  width: 48px;
  height: 2px;
  margin-bottom: 20px;
  background: var(--gc-gold);
}
.detail-intro__title {
  margin: 0 0 24px;
  color: var(--gc-text-on-dark);
  font-family: var(--gc-font-serif);
  font-size: 40px;
  font-weight: var(--gc-weight-display);
  letter-spacing: var(--gc-tracking-display);
  line-height: 1.1;
  text-wrap: balance;
}
.detail-intro--light .detail-intro__rule { background: var(--gc-gold-ink); }
.detail-intro--light .detail-intro__title { color: var(--gc-text-on-light); }

@media (max-width: 780px) {
  .detail-intro__rule { width: 40px; }
  .detail-intro__title { font-size: 28px; }
  .rail__num {
    position: relative;
    left: 12px;
    width: 20px;
    font-size: 18px;
    text-align: left;
  }
}

/* ---------- Cover ----------
   Not a photograph with type laid over it. A black cover sheet carrying the
   record's title, with one frame of the finished work inset beside it,
   overlapping a charcoal panel and running off the right edge so it reads as a
   fragment of a larger set rather than as a backdrop. Nothing is scrimmed, so
   the photograph is seen at full strength and the type sits on solid ink. */
.cover-ch { padding-block: 0; }
.cover-ch .rail { top: clamp(48px, 7vh, 96px); }
.cover {
  position: relative;
  min-height: calc(100svh - var(--nav-h, 68px));
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(24px, 4vw, 64px);
  padding-block: clamp(48px, 7vh, 96px);
}
/* No cap on the container: the title and the sub want very different measures,
   so each sets its own. Capping the container choked the title into six lines
   and the paragraph into seven words a line. */
.cover__type { max-width: 100%; }
.cover__title {
  font-family: var(--gc-font-serif);
  font-weight: var(--gc-weight-display);
  font-size: clamp(2.4rem, 5.4vw, 4.8rem);
  line-height: 1.04;
  letter-spacing: .012em;
  margin: 0;
  max-width: 13ch;
  text-wrap: balance;
}
.cover__sub {
  margin: clamp(20px, 2.6vw, 30px) 0 0;
  max-width: 40ch;
  font-size: 1.02rem;
  line-height: 1.65;
  color: var(--gc-text-muted);
  text-wrap: pretty;
}
.cover__act { display: flex; flex-wrap: wrap; gap: 14px; margin-top: clamp(26px, 3.4vw, 38px); }

/* The frame breaks the field on purpose: it overhangs the right edge of the
   viewport, which is the page's first signal that images are not contained. */
.cover__frame {
  position: relative;
  margin-right: calc(-1 * var(--gut));
  align-self: center;
}
.cover__frame::before {
  content: "";
  position: absolute;
  top: clamp(-28px, -2.4vw, -16px); bottom: clamp(-28px, -2.4vw, -16px);
  left: clamp(-34px, -3vw, -18px);
  width: 58%;
  background: var(--gc-charcoal);
}
.cover__img {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--gc-radius);
  display: block;
}
.cover__cap {
  position: relative;
  display: block;
  margin-top: 14px;
  /* Left, not right: this frame deliberately overhangs the viewport, so anything
     aligned to its right edge is aligned to a point off screen. */
  text-align: left;
  font-size: .62rem; letter-spacing: .24em; text-transform: uppercase;
  font-weight: 600; color: var(--gc-text-muted);
}

@media (min-width: 1100px) {
  .cover { min-height: calc(100vh - var(--nav-h, 68px) - 150px); }
  #kitchen { padding-top: 28px; }
  #kitchen .rail { top: 28px; }
}

/* ---------- Actions ----------
   Two on the page, and the gold fill is the one place the accent is a surface
   rather than a marker, because requesting an estimate is what the page is for. */
.rec .btn-rec {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 50px; padding: 0 1.7em;
  border-width: 1px; border-style: solid; border-color: transparent;
  border-radius: var(--gc-radius);
  font-family: var(--gc-font-sans); font-weight: 600;
  font-size: .78rem; letter-spacing: .14em; text-transform: uppercase;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background var(--gc-motion-fast) var(--gc-motion-ease),
              color var(--gc-motion-fast) var(--gc-motion-ease),
              border-color var(--gc-motion-fast) var(--gc-motion-ease);
}
.rec .btn-rec--go { background: var(--gc-cta-bg); color: var(--gc-cta-text); }
.rec .btn-rec--go:hover { background: var(--gc-gold-soft); }
.rec .btn-rec--line { background: transparent; color: var(--gc-text-on-dark); border-color: rgba(245,245,245,.4); }
.rec .btn-rec--line:hover { border-color: var(--gc-accent); color: var(--gc-accent); }
.rec .ch--light .btn-rec--line { color: var(--gc-text-on-light); border-color: rgba(13,13,13,.4); }
.rec .ch--light .btn-rec--line:hover { border-color: var(--gc-black); background: var(--gc-black); color: var(--gc-offwhite); }

@media (max-width: 900px) {
  /* Asymmetric on purpose. The top pad is the gap under the fixed nav and wants
     the full step; the bottom pad is a chapter transition that the Kitchen
     chapter's own top padding is already paying for, so it takes about half. */
  .cover { grid-template-columns: 1fr; align-items: start; min-height: 0;
           padding-block: clamp(48px, 7vh, 96px) clamp(24px, 3vh, 40px); }
  .cover__type { max-width: 100%; }
  .cover__frame::before { display: none; }
  .cover__img { aspect-ratio: 3 / 2; }
  .cover__cap { text-align: left; }
}
@media (max-width: 640px) {
  .rec { --rail: 40px; }
  .rail { top: calc(var(--ch-space) * .7); }
  .rail__meta { display: none; }   /* 40px cannot hold letterspaced metadata legibly */
  .ch { padding-block: calc(var(--ch-space) * .8); }
  /* .cover-ch already asks for zero chapter padding, but it is a single class and
     so is .ch, and this block comes later in the file. The hero was quietly
     getting 68px back at the top and bottom on every phone, which is most of the
     206px of empty ink that sat between the hero caption and the Kitchen word.
     Restated here so the hero's own rule survives its own breakpoint. */
  .cover-ch { padding-block: 0; }
  .cover__act { flex-direction: column; align-items: stretch; }
}

/* ---------- Kitchen proof sequence ----------
   The photographs are evidence, so each keeps its complete native frame. On
   desktop they pass a single held marker. Below desktop each caption becomes a
   stage header welded above its full-bleed photograph, with the detail copy
   immediately below. The captions remain the source content. JavaScript only
   mirrors their text into the aria-hidden desktop marker, so a no-script view
   loses no meaning. */
.proofseq {
  margin: 0 0 var(--ch-space);
  /* Below 1100 this component is pulled full-bleed (see the max-width: 1099px
     rule), which puts its own left edge at the viewport, past the rail. The
     PHOTOS want that: they are evidence and they earn the full frame. The text
     does not. Captions were inset a flat 20px from the bleed edge, which landed
     them 20px LEFT of the rail hairline, so every caption paragraph in the
     chapter ran straight through the line. This puts the text back on the page's
     content frame, the same left edge as the chapter word above it. */
  --caption-inset: calc(var(--rail) + clamp(18px, 2.2vw, 38px));
}
.proofseq__marker-track { display: none; }
.proofseq__photos {
  display: grid;
  gap: 56px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.proofseq__stage { margin: 0; }
.proofseq__figure {
  display: grid;
  margin: 0;
}
.proofseq__caption { display: contents; }
.proofseq__caption-head {
  display: grid;
  grid-row: 1;
  margin: 0 var(--gut) 18px var(--caption-inset);
  color: var(--gc-text-on-dark);
  font-family: var(--gc-font-serif);
  font-weight: var(--gc-weight-display);
}
.proofseq__caption-head::after {
  content: "";
  display: block;
  grid-row: 2;
  width: 44px;
  height: 1px;
  margin-top: 10px;
  background: var(--gc-gold);
}
.proofseq__caption-number {
  grid-row: 1;
  color: var(--gc-gold);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: .18em;
}
.proofseq__caption-word {
  grid-row: 3;
  margin-top: 12px;
  font-size: clamp(44px, calc(28.5px + 3.96vw), 72px);
  line-height: .95;
  letter-spacing: -.02em;
  text-transform: uppercase;
  white-space: nowrap;
}
.proofseq__plate {
  position: relative;
  grid-row: 2;
  width: 100%;
  background: var(--gc-black);
}
.proofseq__plate::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border: 1px solid rgba(200, 162, 77, .35);
}
.proofseq__img {
  display: block;
  width: 100%;
  height: auto;
}
.proofseq__photo-tag-track {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: block;
  padding: 12px;
  pointer-events: none;
}
.proofseq__photo-tag {
  position: sticky;
  top: 85px;
  display: block;
  width: max-content;
  padding: 7px 9px;
  color: var(--gc-gold);
  background: var(--gc-black);
  font-family: var(--gc-font-serif);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: .16em;
}
.proofseq__caption-copy {
  grid-row: 3;
  max-width: 42ch;
  margin: 16px var(--gut) 0 var(--caption-inset);
  color: var(--gc-text-muted);
  font-size: 16px;
  line-height: 1.6;
}
.proofseq__caption-meta {
  grid-row: 4;
  margin: 12px var(--gut) 0 var(--caption-inset);
  color: rgba(200, 162, 77, .85);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.55;
  letter-spacing: .16em;
  text-transform: uppercase;
}

@media (max-width: 1099px) {
  .proofseq {
    position: relative;
    z-index: 1;
    width: 100vw;
    margin-left: calc(-1 * (var(--rail) + clamp(18px, 2.2vw, 38px)));
    /* The chapter word and the first stage word are both large serif display and
       sat 43px apart, so they read as two stacked headings rather than a chapter
       followed by its first piece of evidence. */
    margin-top: clamp(56px, 7vw, 76px);
  }
  /* Three numerals were on screen at once in the first phone-height of this
     chapter: the gold chapter numeral in the rail, this one 92px under it in
     almost the same size and exactly the same gold, and the tag burned into the
     corner of the photograph below. The photo tag is the one that does real work,
     because it sits ON the thing it numbers. This one is the redundant middle
     term, and dropping it is what makes the opening stop reading as scattered.
     The stage words stay: BEFORE, DURING and AFTER carry the sequence on their
     own, in source order, for a screen reader as much as for an eye. */
  .proofseq__caption-number { display: none; }
  /* Welded, as the component comment above promises. 18px was a gap; this is a
     join, so the header reads as belonging to the photograph under it rather
     than floating between two of them. */
  .proofseq__caption-head { margin-bottom: 14px; }
}

@media (min-width: 1100px) {
  .proofseq {
    display: grid;
    grid-template-columns: 460px minmax(0, 1fr);
    align-items: stretch;
    width: calc(100vw - var(--rail) - clamp(18px, 2.2vw, 38px));
  }
  .proofseq__marker-track {
    position: relative;
    grid-column: 1;
    grid-row: 1;
    min-width: 0;
    overflow: visible;
  }
  .has-proofseq-js .proofseq__marker-track { display: block; }
  .proofseq__marker {
    position: sticky;
    top: 34vh;
    min-height: 390px;
    padding: 0 16px 36px 72px;
    overflow: visible;
  }
  .proofseq__marker-mask {
    overflow: hidden;
  }
  .proofseq__marker-mask--word {
    margin-left: -72px;
  }
  .proofseq__marker-mask > * {
    opacity: 1;
    transform: translateY(0);
  }
  .proofseq__marker-mask--rule > * {
    transform: translateY(0) scaleX(1);
    transform-origin: left center;
  }
  .proofseq__marker.is-swapping-out .proofseq__marker-mask > * {
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity 180ms cubic-bezier(.4, 0, 1, 1), transform 180ms cubic-bezier(.4, 0, 1, 1);
  }
  .proofseq__marker.is-swapping-out .proofseq__marker-mask--rule > * {
    transform: translateY(-6px) scaleX(1);
  }
  .proofseq__marker.is-preparing-in .proofseq__marker-mask > * {
    opacity: 0;
    transform: translateY(14px);
    transition: none;
  }
  .proofseq__marker.is-preparing-in .proofseq__marker-mask--rule > * {
    transform: translateY(14px) scaleX(0);
  }
  .proofseq__marker.is-swapping-in .proofseq__marker-mask > * {
    opacity: 1;
    transform: translateY(0);
  }
  .proofseq__marker.is-swapping-in .proofseq__marker-mask--number > * {
    transition: opacity 300ms cubic-bezier(.22, 1, .36, 1), transform 300ms cubic-bezier(.22, 1, .36, 1);
  }
  .proofseq__marker.is-swapping-in .proofseq__marker-mask--rule > * {
    transform: translateY(0) scaleX(1);
    transition: opacity 300ms 60ms cubic-bezier(.22, 1, .36, 1), transform 300ms 60ms cubic-bezier(.22, 1, .36, 1);
  }
  .proofseq__marker.is-swapping-in .proofseq__marker-mask--word > * {
    transition: opacity 380ms 100ms cubic-bezier(.22, 1, .36, 1), transform 380ms 100ms cubic-bezier(.22, 1, .36, 1);
  }
  .proofseq__marker.is-swapping-in .proofseq__marker-mask--copy > * {
    transition: opacity 320ms 170ms cubic-bezier(.22, 1, .36, 1), transform 320ms 170ms cubic-bezier(.22, 1, .36, 1);
  }
  .proofseq__marker.is-swapping-in .proofseq__marker-mask--meta > * {
    transition: opacity 320ms 230ms cubic-bezier(.22, 1, .36, 1), transform 320ms 230ms cubic-bezier(.22, 1, .36, 1);
  }
  .proofseq__marker-number {
    margin: 0;
    color: var(--gc-gold);
    font-family: var(--gc-font-serif);
    font-size: 20px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: .18em;
  }
  .proofseq__marker-rule {
    display: block;
    width: 64px;
    height: 1px;
    margin-top: 16px;
    background: var(--gc-gold);
  }
  .proofseq__marker-word {
    position: relative;
    z-index: 2;
    margin: 18px 0 0;
    color: var(--gc-offwhite);
    font-family: var(--gc-font-serif);
    font-size: 104px;
    font-weight: 500;
    line-height: .9;
    letter-spacing: -.035em;
    white-space: nowrap;
  }
  .proofseq__marker-copy {
    max-width: 34ch;
    margin: 22px 0 0;
    color: var(--gc-text-muted);
    font-size: 17px;
    line-height: 1.55;
  }
  .proofseq__marker-meta {
    margin: 24px 0 0;
    color: rgba(200, 162, 77, .85);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.55;
    letter-spacing: .16em;
    text-transform: uppercase;
    white-space: nowrap;
  }
  .proofseq__progress {
    position: absolute;
    top: 0;
    bottom: 36px;
    left: -36px;
    display: grid;
    grid-template-rows: repeat(3, 1fr) auto;
    gap: 6px;
    width: 20px;
  }
  .proofseq__progress-segment {
    display: block;
    width: 2px;
    min-height: 0;
    background: rgba(200, 162, 77, .25);
    transition: background 110ms var(--gc-motion-ease);
  }
  .proofseq__progress-segment.is-active { background: var(--gc-gold); }
  .proofseq__progress-count {
    margin-left: -4px;
    color: var(--gc-gold);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .12em;
    writing-mode: vertical-rl;
  }
  .proofseq__photos {
    grid-column: 2;
    grid-row: 1;
    gap: 48px;
    min-width: 0;
  }
  .proofseq__photo-tag-track { padding: 20px; }
  .proofseq__photo-tag {
    font-size: 12px;
  }
  .has-proofseq-js .proofseq__stage:not(.is-active) .proofseq__img { opacity: .62; }
  .has-proofseq-js .proofseq__img { transition: opacity 220ms var(--gc-motion-ease); }
  .has-proofseq-js .proofseq__caption {
    display: block;
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .proofseq__marker,
  .proofseq__progress-segment,
  .proofseq__img { transition: none; }
  .proofseq__marker-mask { overflow: visible; }
  .proofseq__marker-mask > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ---------- Baths ----------
   Static by design. Both bands sit on the chapter's own light ground and on the
   page's content frame: the .ch padding box, capped at the same 1180px as
   .field. So the section word, the proof pair, the feature intro and the
   feature photo all share one left edge and one right edge at every width, and
   that shared frame is the only structure carrying the section now that it is
   one continuous tone.

   Two earlier decisions were reversed here on 2026-08-23, both on Gage's call
   after a live pass. The proof pair was on a full-bleed black ground (chosen
   because white subway tile dissolves into the light ground) and it bled to the
   viewport's right edge. On review the bleed read as an accidental crop rather
   than a deliberate full-bleed, because the cut landed mid-object on the
   vanity. The hairline outline on the photos is what now buys the white tile an
   edge on the light ground; it is drawn with outline-offset so it costs zero
   layout and cannot disturb the paired-height geometry below.

   Every image keeps its native aspect and every caption is in normal document
   flow, with no JavaScript or sticky behavior. */
#baths { padding-bottom: 0; }
/* Vertical rhythm is copied off the Kitchen chapter, measured, not guessed:
   there the section word sits 15px above its proof and the proof clears its
   closing block by 99px. While this band was black those two paddings read as
   the band's own inset; on one continuous tone they stacked into a 192px hole
   between the captions and the feature intro. Top padding goes to zero on both
   bands so the section opens exactly like Kitchen and breaks once, not twice. */
.bath-proof-band { padding-block: 0 var(--gc-space-9); }
.bath-proof {
  max-width: 1180px;
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  /* 1fr / 2fr is not a taste call. DURING is 0.75 portrait and AFTER is 1.50
     landscape, so a 1:2 column ratio resolves both to the same height off a
     shared top line at any container width with zero cropping. Change the ratio
     and the shared top line stops being shared. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: 40px;
  align-items: start;
}
.bath-proof__figure,
.bath-feature__photo { margin: 0; }
.bath-proof__photo {
  position: relative;
  width: 100%;
  max-width: 100%;
}
.bath-proof__photo > img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  object-fit: contain;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  /* Drawn inside the box, so it frames the photo without adding a single pixel
     of layout. A real border would add 2px per axis and pull the pair's
     computed heights apart. */
  outline: 1px solid var(--hair-ink);
  outline-offset: -1px;
}
.bath-proof .proofseq__photo-tag-track { padding: 16px; }
.bath-proof .proofseq__photo-tag { position: static; }
.bath-proof__caption { margin-top: 24px; }
.bath-proof__word {
  margin: 0;
  color: var(--gc-text-on-light);
  font-family: var(--gc-font-serif);
  /* 6.4vw, not 6.7. The stage word lives in the 1fr column, which is one third
     of the grid; when the grid stopped bleeding to the viewport that column got
     narrower and DURING closed to 1.8px of its own column edge between 800 and
     1080. Caught by stagesweep.mjs, not by looking: at 1440 and at 391 this
     value is clamped to the max and the min, so both spot checks were clean. */
  font-size: clamp(44px, 6.4vw, 72px);
  font-weight: var(--gc-weight-display);
  letter-spacing: -.02em;
  line-height: .95;
  text-transform: uppercase;
}
.bath-proof__rule {
  display: block;
  width: 48px;
  height: 2px;
  margin-top: 16px;
  background: var(--gc-gold);
}
.bath-proof__copy {
  margin: 16px 0 0;
  max-width: var(--gc-measure);
  color: var(--gc-grey);
  font-family: var(--gc-font-sans);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.6;
  text-wrap: pretty;
}
.bath-proof__meta {
  /* Gold as TEXT on a light ground has to be the ink variant. Raw --gc-gold is
     2.2:1 here; it was legal only while this band was black. */
  margin: 12px 0 0;
  color: var(--gc-gold-ink);
  font-family: var(--gc-font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .16em;
  line-height: 1.4;
  text-transform: uppercase;
}

.bath-feature-band { padding-block: 0 var(--gc-space-9); }
.bath-feature-band__inner { max-width: 1180px; }
.bath-feature-band .detail-intro .ch__lede { max-width: var(--gc-measure); }
.bath-feature {
  display: grid;
  grid-template-columns: minmax(0, 720fr) minmax(0, 456fr);
  /* Same gutter as the proof pair above, so the section reads as one grid. It
     was absent entirely before, which put the headline's first glyph flush
     against the tile at every width. */
  gap: 40px;
  margin-top: 56px;
}
.bath-feature__photo img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  outline: 1px solid var(--hair-ink);
  outline-offset: -1px;
}
.bath-feature__copy { align-self: center; margin-top: 0; }
.bath-feature__title {
  margin: 0;
  color: var(--gc-text-on-light);
  font-family: var(--gc-font-serif);
  font-size: 24px;
  font-weight: var(--gc-weight-display);
  line-height: 1.1;
}
.bath-feature__body {
  margin: 16px 0 0;
  color: var(--gc-grey);
  font-family: var(--gc-font-sans);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.6;
  text-wrap: pretty;
}
.bath-feature__copy .ch__act { margin-top: 32px; }

@media (max-width: 1200px) {
  .bath-proof {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: 32px;
  }
  .bath-feature { gap: 32px; }
}

@media (max-width: 780px) {
  .bath-proof-band,
  .bath-feature-band { padding-block: 0 var(--gc-space-8); }
  .bath-proof { grid-template-columns: 1fr; gap: 56px; }
  .bath-proof .proofseq__photo-tag-track { padding: 12px; }
  .bath-proof__word { font-size: 44px; }
  .bath-proof__rule { width: 40px; }
  .bath-proof__copy { font-size: 15px; line-height: 1.65; }
  .bath-proof__meta { font-size: 10px; }
  .bath-feature { grid-template-columns: 1fr; }
  .bath-feature__copy { margin-top: 24px; }
  .bath-feature__copy .btn-rec { width: 100%; min-height: 48px; }
}

@media (prefers-reduced-motion: reduce) {
  #baths,
  #baths *,
  #baths *::before,
  #baths *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ---------- Scope ----------
   The lists sit beside a frame, which is the sequence's own image-then-type
   grammar rather than a new device. Before this the chapter was two rules of text
   on an empty field. */
.scope {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  gap: clamp(24px, 4vw, 60px);
  align-items: start;
  margin-top: clamp(30px, 4vw, 48px);
}
/* The frame hugs its image rather than stretching to the taller column, or the
   mount grows a slab of charcoal under the photograph. */
.scope__frame {
  align-self: start;
  background: var(--gc-charcoal);
  border-radius: var(--gc-radius);
  display: grid;
  place-items: center;
  padding: clamp(8px, 1vw, 16px);
}
.scope__img {
  display: block;
  width: 100%;
  height: auto;
  max-height: clamp(230px, 62vh, 620px);
  object-fit: contain;
  border-radius: var(--gc-radius);
}
/* One list per row in the right column. Two side by side inside a half-width
   column wrapped nearly every line ("Soaking tubs and walk-in / showers"). */
.scope .cols { margin-top: 0; grid-template-columns: 1fr; gap: clamp(22px, 3vw, 34px); }

/* ---------- Scope columns ----------
   No bullet glyphs. Gold is reserved for position on this page, and a grey dash
   in front of every line is exactly the decorative tic the rule exists to stop.
   Hairlines do the separating instead. */
.cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(28px, 5vw, 72px);
}
.col__label {
  margin: 0 0 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--hair);
  font-size: .64rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--gc-text-on-dark);
}
.col__list { list-style: none; margin: 0; padding: 0; }
.col__list li {
  padding-block: 11px;
  border-bottom: 1px solid rgba(245, 245, 245, .08);
  color: var(--gc-text-on-dark);
  font-size: .98rem;
  line-height: 1.5;
}

/* ---------- Process track ----------
   One horizontal line rather than four boxes, because a process is something you
   move along. It was drafted to bleed off the right edge for that effect, and
   measured at 1440 it does not: scrollWidth equals clientWidth, all four steps
   fit. Left fitting on purpose rather than widened until it overflowed. This is a
   conversion page, and putting steps behind a horizontal scroll on a desktop
   viewport hides content to buy a gesture. It becomes a real scrollable track
   only where the viewport genuinely cannot hold four columns. */
.track {
  list-style: none;
  margin: clamp(48px, 7vw, 88px) calc(-1 * var(--gut)) 0 0;
  padding: 0 var(--gut) 4px 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(228px, 1fr);
  gap: clamp(20px, 3vw, 44px);
  overflow-x: auto;
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
}
.track:focus-visible { outline: 2px solid var(--gc-accent); outline-offset: 6px; }
.track__step { padding-top: 20px; border-top: 1px solid var(--hair); }
.track__num {
  display: block;
  font-family: var(--gc-font-serif);
  font-weight: var(--gc-weight-display);
  font-size: 1.35rem;
  line-height: 1;
  color: var(--gc-text-on-dark);
  opacity: .55;      /* process steps stay secondary to the gold chapter position */
  margin-bottom: 10px;
}
.track__txt {
  margin: 0;
  color: var(--gc-text-muted);
  font-size: .95rem;
  line-height: 1.55;
  text-wrap: pretty;
}

/* ---------- Ask ----------
   The form sits on the page's own ink as an inset charcoal panel. Fields are
   hairline-ruled rather than boxed, so the block reads as part of the record
   instead of a widget dropped onto it. */

/* The chapter's bottom padding put 68 to 100px of empty ink between the send
   button and the footer, with the rail hairline still running down through it
   because .ch::before spans the section top to bottom. A hairline that outlives
   its content reads as leftover space rather than structure. The footer carries
   its own top padding, so the chapter can end where its content ends. */
#estimate { padding-bottom: 0; }
.ask {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(32px, 5vw, 80px);
  align-items: start;
}
.ask__facts { margin: clamp(28px, 4vw, 44px) 0 0; }
.ask__facts > div {
  display: grid;
  grid-template-columns: minmax(96px, 30%) 1fr;
  gap: 16px;
  padding-block: 13px;
  border-top: 1px solid var(--hair);
}
.ask__facts dt {
  font-size: .62rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--gc-text-muted);
  padding-top: 3px;
}
.ask__facts dd { margin: 0; color: var(--gc-text-on-dark); font-size: 1rem; }
.ask__facts a { color: inherit; text-decoration: none; }
.ask__facts a:hover { color: var(--gc-accent); }


/* The estimate form's own styles moved to styles/leadform-dark.css on
   2026-08-26 so the ad landing page can load them without this whole file.
   What remains here is field-record-specific: the facts list above, and the
   phone-width full-bleed below that depends on --rail and --gut. */

@media (max-width: 900px) {
  .ask { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .scope { grid-template-columns: 1fr; }
}
/* The track needs about 1050px to hold four columns at its 228px minimum. Above
   that it is one line, as designed. Below it, it was a horizontal scroller from
   660 all the way to 1150: at 660 it hid 382px of step 04 behind a gesture, and
   at 1024 it cut "Finish clean and walk the work with the homeowner" mid-word at
   the frame edge. That is the exact thing the rule above refuses to do on a
   conversion page, and it survived because the track was only ever measured at
   1440 and at 390. Two by two through the whole band: nothing hidden, no
   gesture, and the width actually used. */
@media (max-width: 1179px) and (min-width: 641px) {
  .track {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    overflow-x: visible;
    margin-right: 0;
    padding-right: 0;
    row-gap: clamp(28px, 3.4vw, 44px);
  }
}

@media (max-width: 640px) {
  .cols { grid-template-columns: 1fr; gap: 34px; }
  /* Stack, do not scroll. At 390 the track held 880px of content in a 332px box,
     so steps 03 and 04 were off screen and 02 was cut mid-word at the viewport
     edge, which reads as broken text rather than as a scroller. The desktop rule
     already refuses to hide steps behind a horizontal gesture on a conversion
     page; this is the same reasoning applied where it actually mattered. */
  .track {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: 1fr;
    overflow-x: visible;
    margin-right: 0;
    padding-right: 0;
    gap: 0;
  }
  /* The rule under a step is the NEXT step's border-top, so with no bottom
     padding the sentence sat on the line with only its own descender for
     clearance. 18 above the numeral, 20 below the sentence. */
  .track__step { padding-block: 18px 20px; }

  /* The form leaves the rail on phones, and this is a hard requirement rather
     than a composition preference. Cloudflare Turnstile at data-size="flexible"
     has a 300px MINIMUM width; measured at 360 it forced the form to 348px inside
     a 282px field, which widened the whole chapter and pushed the phone number,
     email, service area and reply time past the viewport edge where
     overflow-x: clip removed them without a trace. Proven by deleting the widget
     in the live page: every width snapped back to 282.

     So the estimate form is the one element still permitted to leave the frame.
     Clean from about 348px of viewport upward. Below that the widget's own floor
     exceeds the screen and nothing in this stylesheet can fix it; it would need
     Turnstile's compact size. */
  .ask__form {
    /* Positioned, so it paints above the chapter's rail hairline. The hairline is an
       absolutely positioned ::before, which paints above non-positioned descendants,
       so on mobile the line ran straight through the full-bleed form and its labels
       sat to the left of the content edge the rest of the page holds. */
    position: relative;
    margin-inline: calc(-1 * (var(--rail) + clamp(18px, 2.2vw, 38px))) calc(-1 * var(--gut));
    /* The panel is allowed to leave the frame; its CONTENTS are not, if there is
       any room to hold them. A flat 10px put every label 48px left of the edge the
       rest of the page keeps, which is what made the form read as a separate,
       misplaced object once it was stacked. So: take the page's own left inset
       whenever doing so still leaves Turnstile its 300px floor, and give the floor
       priority below that, because a widget wider than the screen is a worse
       failure than a soft left edge. Resolves to the full 58px from 404 up, tapers
       through the 360s, and bottoms out at 10px where the screen genuinely cannot
       pay for both. */
    padding-left: max(10px, min(calc(var(--rail) + clamp(18px, 2.2vw, 38px)), calc(100vw - 300px - var(--gut) - 12px)));
    padding-right: var(--gut);
    border-radius: 0;
  }

  /* The fact list stacks on phones, and this is the second hard minimum in this
     chapter rather than a style choice. Two columns meant a 96px label track plus
     a 16px gap plus an email address that cannot break, which measured 157px, for
     a 269px floor against 242px of available field at 320. Stacked, the widest
     unbreakable token is the email alone and it fits. */
  .ask__facts > div { grid-template-columns: 1fr; gap: 4px; }
  .ask__facts dt { padding-top: 0; }
}
