/* Renner Plumbing & Drain — the page on top of Broadsheet.
 *
 * Sibling of ../wexler/page.css. They share broadsheet.css and every
 * primitive in it, and they are meant to look like two papers set in the
 * same house style rather than one page with two accents. The differences
 * are structural and deliberate:
 *
 *   Wexler   headline in column one, deck beside it   credentials: label/value
 *            three photographs under "recent work"    services in four columns
 *
 *   Renner   headline centred across the measure      figures: big numerals
 *            a photo strip AND a diary table          services in two columns
 *
 * A company has volume and a one-van shop has attention, so one of these
 * pages counts things and the other one shows them.
 */

:root {
  /* Ink blue. Utility-department blue -- the colour of a water main drawing
     and a city permit. Clear of Marek's copper, alder-co's cyan, Nocturne's
     blurple, Vance's red, and clear of Wexler's verdigris next door: this
     pair has to read as one trade without reading as one business. */
  --color-accent: #17407e;
  --color-accent-ink: #ffffff;
  --color-accent-wash: #e6eaf2;
}

/* ------------------------------------------------------------- noscript --- */
.noscript {
  padding: 14px 18px;
  background: var(--color-accent-wash);
  border-bottom: var(--rule-hair) solid var(--color-divider);
}
.noscript p { margin: 0; font-size: 14.5px; }

/* ------------------------------------------------------------- masthead --- */
.mast { background: var(--color-bg); position: relative; z-index: 2; }
.mast__inner {
  display: flex; align-items: center; gap: clamp(14px, 3vw, 40px);
  padding-block: 18px 16px;
}
.mast__rule { border-top: var(--rule-bold) solid var(--color-rule); }

.brand { text-decoration: none; display: grid; gap: 1px; margin-right: auto; }
.brand__name {
  font-family: var(--font-heading); font-weight: 600;
  font-size: clamp(18px, 1.9vw, 23px); line-height: 1.1; letter-spacing: -0.01em;
}
.brand__tag { font-size: 12px; color: var(--color-neutral-600); letter-spacing: 0.02em; }

.nav { display: flex; flex-wrap: wrap; gap: 4px; }
.navlink {
  font: inherit; font-size: 14.5px;
  background: none; border: 0; cursor: pointer;
  padding: 7px 10px; color: var(--color-neutral-700);
  border-bottom: 2px solid transparent;
  transition: color 0.16s linear, border-color 0.16s linear;
}
.navlink:hover { color: var(--color-text); }
.navlink[aria-current="page"] { color: var(--color-text); border-bottom-color: var(--color-accent); }

.mast__call {
  font-weight: 600; font-size: 15px; text-decoration: none;
  padding: 10px 16px;
  border: var(--rule-hair) solid var(--color-rule);
  white-space: nowrap;
}
.mast__call:hover { background: var(--color-text); color: var(--color-bg); }

/* --------------------------------------------------------------- freeze --- */
/* The home page opens on the problem: ice running off a pipe strap, with the
   headline on the cold side of the frame and the company's figures set
   across the foot on a solid bar. Redesigned 2026-09-29 from a centred
   headline on paper -- the same shape Wexler had before it was asked to look
   "like HVAC", and the plainest first screen of the six demos.

   Not a copy of Wexler's banner, which is the nearest thing to it. Wexler's
   scrim is neutral ink and its right-hand column holds the owner; this one is
   navy, so the frame reads cold before a word is read, and it keeps the right
   of the picture for the pipe and puts the scale UNDER the copy instead of
   beside it. */
.freeze {
  --banner-ink: 8, 18, 36;
  /* The centred wrap's left margin -- see Wexler's banner for why every
     horizontal stop hangs off this rather than off the viewport edge. */
  --gx: max(0px, (100vw - 1240px) / 2);
  position: relative; isolation: isolate;
  display: grid; align-content: end;
  min-height: clamp(560px, 80vh, 720px);
}
.freeze__media { position: absolute; inset: 0; z-index: -1; overflow: hidden; }
.freeze__media img {
  width: 100%; height: 100%; object-fit: cover; object-position: 64% 42%;
  display: block;
}
/* Vertical pass: a little weight at the top under the masthead, then heavy at
   the foot so the copy and the figures bar sit on something. Horizontal pass:
   a dark plateau under the copy, anchored to --gx, falling away to leave the
   pipe and the ice lit on the right. First stop negative so narrow screens
   keep the flat plateau. */
/* The ramp opens early, at gx + 600, because the brass is the point of the
   picture: a first pass that kept the plateau running on to gx + 780 turned
   the pipe olive. That only works because the deck is capped at 42ch below
   -- at 50ch its first line ran 170px past the plateau into the ramp and
   measured 4.77:1 at 1440px, so the choice was a darker pipe or a shorter
   line, and a shorter line is also the better hero measure. */
.freeze__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg,
      rgba(var(--banner-ink), 0.42) 0%,
      rgba(var(--banner-ink), 0.10) 30%,
      rgba(var(--banner-ink), 0.24) 62%,
      rgba(var(--banner-ink), 0.84) 100%),
    linear-gradient(90deg,
      rgba(var(--banner-ink), 0.40) calc(var(--gx) - 320px),
      rgba(var(--banner-ink), 0.86) var(--gx),
      rgba(var(--banner-ink), 0.82) calc(var(--gx) + 600px),
      rgba(var(--banner-ink), 0.28) calc(var(--gx) + 740px),
      rgba(var(--banner-ink), 0.02) calc(var(--gx) + 940px));
}
.freeze__inner { width: 100%; padding-block: clamp(40px, 6vw, 80px) clamp(30px, 4vw, 48px); }

/* Every on-photo colour qualified with .freeze -- .freeze__d is (0,1,0)
   exactly like .deck, and source order is not a thing to lean on. */
.freeze .freeze__k { color: #c8d4e6; }
.freeze .freeze__h { color: #fff; margin-top: 14px; max-width: 12ch; }
.freeze .freeze__d { color: #e3e8f0; margin-top: 20px; max-width: 42ch; }
.freeze__a { margin-top: clamp(22px, 2.8vw, 30px); }
.freeze .freeze__f { margin-top: 16px; color: #c3cedf; }
/* A white fill, not the accent. An ink-blue button on a navy frame keeps its
   own text contrast but loses its SHAPE -- it measures fine and cannot be
   seen. White on the photograph, ink-blue text, the way the HVAC demo does
   it for the same reason. */
.freeze .btn-primary { background: #fff; border-color: #fff; color: var(--color-accent); }
.freeze .btn-primary:hover { background: #dfe7f3; border-color: #dfe7f3; }
.freeze .btn-ghost { color: #fff; border-color: rgba(255, 255, 255, 0.6); }
.freeze .btn-ghost:hover { background: #fff; color: var(--color-accent); border-color: #fff; }

/* The figures bar: Renner blue, full bleed, the four numbers big. It is the
   company's whole case -- eight on payroll, answered at 3am -- set as the
   ground the banner stands on. */
.figbar {
  background: var(--color-accent);
  border-top: var(--rule-bold) solid #fff;
}
.figbar__inner {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
}
/* :nth-of-type, NOT :nth-child. The list host's first child is its
   <template>, so under :nth-child the "8" is child 2 -- "even" -- and every
   divider lands one cell to the right: indented under the copy on desktop, a
   rule down the outside edge and none down the middle on a phone.
   :nth-of-type counts only the divs. */
.figbar__cell {
  padding: 18px clamp(14px, 2vw, 24px) 20px 0;
  border-bottom: var(--rule-hair) solid rgba(255, 255, 255, 0.22);
}
.figbar__cell:nth-of-type(odd) { border-right: var(--rule-hair) solid rgba(255, 255, 255, 0.22); }
.figbar__cell:nth-of-type(even) { padding-left: clamp(14px, 2vw, 24px); }
.figbar__n {
  margin: 0;
  font-family: var(--font-heading); font-weight: 600;
  font-size: clamp(34px, 4.4vw, 58px); line-height: 1; letter-spacing: -0.02em;
  color: #fff;
}
.figbar__k {
  margin: 8px 0 0;
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  line-height: 1.4; color: #d7e0ee; max-width: 22ch;
}
@media (min-width: 820px) {
  .figbar__inner { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .figbar__cell { border-bottom: 0; padding-block: 22px 24px; }
  .figbar__cell:nth-of-type(odd) { border-right: 0; }
  /* One row of four: a rule and an indent before every cell but the first,
     so the "8" lines up with the headline above it. */
  .figbar__cell:nth-of-type(n+2) {
    border-left: var(--rule-hair) solid rgba(255, 255, 255, 0.22);
    padding-left: clamp(16px, 2vw, 26px);
  }
}

/* --------------------------------------------------------------- figures --- */
/* .cells is still the About page's credentials strip. */
.cells { margin-bottom: clamp(30px, 4.5vw, 56px); }

/* ---------------------------------------------------------------- band --- */
/* The risers band lives in the Buildings section now. */
.band__img { filter: saturate(0.94); }
.comm__band { margin-bottom: clamp(24px, 3.5vw, 40px); }

/* ------------------------------------------------------------- section --- */
.sec { padding-block: 0 clamp(34px, 5vw, 68px); }
.sec__head {
  padding-top: clamp(22px, 3vw, 34px);
  margin-bottom: clamp(18px, 2.6vw, 30px);
  border-top: var(--rule-bold) solid var(--color-rule);
}
.sec__head .h2 { margin-top: 10px; max-width: 26ch; }
.sec__more { margin: 24px 0 0; }
.sec__note { margin-top: 20px; max-width: 62ch; }
/* The first section after the banner. .sec carries no top padding because
   every section opens on its own ruled head -- but straight under a dark
   full-bleed banner the 3px rule needs air, or it reads as the banner's
   bottom edge. */
.sec--first { padding-top: clamp(40px, 5.5vw, 72px); }

/* ---------------------------------------------------------------- tiles --- */
/* Services on the home page, as a ruled 3 x 2 grid instead of five long rows:
   half the height, and it scans by column instead of by paragraph. The
   services page keeps the rows below, because that one is the reference and
   this one is the index. Wexler lists its services as four-column rows, so
   the pair do not share a device here either. */
.tiles { display: grid; gap: clamp(14px, 1.8vw, 22px); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 620px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 960px) { .tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* The list host steps out of the way, so its generated tiles and the
   authored "more" tile after it are siblings in one grid. */
.tiles__list { display: contents; }
.tile {
  display: flex; flex-direction: column; gap: 8px;
  margin: 0; padding: clamp(18px, 2vw, 24px);
  background: var(--color-surface);
  border: var(--rule-hair) solid var(--color-divider);
  border-top: var(--rule-bold) solid var(--color-accent);
}
.tile__n { color: var(--color-accent); margin: 0; }
.tile__t { margin: 0; }
.tile__b { margin: 0; color: var(--color-neutral-700); font-size: 15px; }
/* margin-top: auto sends the price to the foot of every tile, so a row of
   three ends on one line whatever length the descriptions are. */
.tile__m {
  margin: auto 0 0; padding-top: 12px;
  border-top: var(--rule-hair) solid var(--color-divider);
  font-size: 13.5px; font-weight: 600; color: var(--color-accent);
}
/* The sixth tile is a link: same frame, the wash for a ground, and it names
   the two services that did not fit instead of saying "more". */
.tile--more {
  font: inherit; text-align: left; cursor: pointer;
  background: var(--color-accent-wash); color: inherit;
  transition: background 0.18s linear;
}
.tile--more .tile__t, .tile--more .tile__b { display: block; }
.tile--more:hover { background: #d9e1ef; }
.tile__go {
  margin-top: auto; padding-top: 12px;
  border-top: var(--rule-hair) solid var(--color-accent);
  font-size: 14.5px; font-weight: 600; color: var(--color-accent);
}

/* ------------------------------------------------------------- services --- */
/* Two columns, not Wexler's four: the number and the name travel together
   on the left, the description and the price stack on the right. On a list
   of seven that reads faster than four thin columns. */
.svc { border-top: var(--rule-hair) solid var(--color-divider); }
.svc__row {
  display: grid; gap: 8px clamp(20px, 3.5vw, 60px);
  padding: 22px 0;
  border-bottom: var(--rule-hair) solid var(--color-divider);
}
.svc__lead { display: flex; align-items: baseline; gap: 14px; }
.svc__n { color: var(--color-accent); flex: none; }
.svc__t { margin: 0; }
.svc__b { margin: 0; color: var(--color-neutral-700); }
.svc__m { margin-top: 6px; color: var(--color-accent); font-weight: 600; }

@media (min-width: 840px) {
  .svc__row { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); align-items: start; }
  /* Without this the price lands in column one on row two, under the title
     instead of under the description it qualifies -- auto-placement fills
     the next free cell, and the next free cell is the empty one on the left. */
  .svc__m { grid-column: 2; }
}

/* ------------------------------------------------------------ the strip --- */
.strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 2.4vw, 28px); }
@media (max-width: 859px) { .strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 559px) { .strip { grid-template-columns: minmax(0, 1fr); } }
.shot { margin: 0; }
.shot img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.shot figcaption {
  margin-top: 10px; padding-top: 9px;
  border-top: var(--rule-hair) solid var(--color-divider);
}

/* ---------------------------------------------------------- the diary --- */
/* A real <table>, because it is one: four columns of the same kind of fact,
   and a screen reader should get the header association. */
.diary { width: 100%; border-collapse: collapse; margin-top: clamp(28px, 4vw, 48px); }
.diary__cap { text-align: left; padding-bottom: 10px; }
.diary th, .diary td {
  text-align: left; padding: 11px 14px 11px 0;
  border-bottom: var(--rule-hair) solid var(--color-divider);
  font-size: 14.5px;
}
.diary th {
  border-bottom: var(--rule-bold) solid var(--color-rule);
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--color-neutral-600);
}
.diary td:first-child { font-weight: 600; color: var(--color-text); }
.diary td { color: var(--color-neutral-700); }
.diary tr:hover td { background: var(--color-accent-wash); }

@media (max-width: 639px) {
  /* Four columns do not fit a phone, so each row becomes its own small
     block with the header as a prefix. */
  .diary thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .diary tr { display: block; padding: 12px 0; border-bottom: var(--rule-hair) solid var(--color-divider); }
  .diary td { display: block; border: 0; padding: 1px 0; }
  .diary td:first-child { font-size: 16px; }
  .diary td:nth-child(3)::before { content: 'Booked '; color: var(--color-neutral-500); }
  .diary td:nth-child(4)::before { content: 'On site '; color: var(--color-neutral-500); }
}

/* ----------------------------------------------------------- commercial --- */
.comm { display: grid; gap: clamp(20px, 3vw, 44px); }
@media (min-width: 820px) { .comm { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.comm__list { list-style: none; margin: 0; padding: 0; border-top: var(--rule-hair) solid var(--color-divider); }
.comm__item {
  padding: 11px 0 11px 22px; position: relative;
  border-bottom: var(--rule-hair) solid var(--color-divider);
  font-size: 15px; color: var(--color-neutral-700);
}
.comm__item::before {
  content: ''; position: absolute; left: 0; top: 19px;
  width: 9px; height: 2px; background: var(--color-accent);
}

/* -------------------------------------------------------------- quotes --- */
.quotes { display: grid; gap: clamp(18px, 2.6vw, 32px); margin-top: 22px; }
@media (min-width: 760px) { .quotes { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.quote {
  margin: 0; padding: 20px 20px 18px;
  background: var(--color-surface);
  border: var(--rule-hair) solid var(--color-divider);
  border-top: var(--rule-bold) solid var(--color-accent);
}
.quote__q { margin: 0 0 14px; font-family: var(--font-heading); font-weight: 600; font-size: 18px; line-height: 1.4; }
.quote__w { font-size: 12.5px; color: var(--color-neutral-600); }

/* ------------------------------------------------------------ coverage --- */
.cover { display: grid; gap: clamp(24px, 4vw, 56px); }
@media (min-width: 760px) { .cover { grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr); } }
.areas { display: flex; flex-wrap: wrap; gap: 7px; margin: 12px 0 16px; }
.hours { margin-top: 12px; border-top: var(--rule-hair) solid var(--color-divider); }
.hours__row {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 8px 0; font-size: 14.5px;
  border-bottom: var(--rule-hair) solid var(--color-divider);
}
.hours__row span:first-child { color: var(--color-neutral-600); }

/* ------------------------------------------------------------ keepring --- */
.kr {
  padding: clamp(24px, 3.5vw, 44px);
  background: var(--color-accent-wash);
  border-top: var(--rule-bold) solid var(--color-accent);
}
.kr__h { margin-top: 10px; max-width: 26ch; }
.kr__b { margin-top: 14px; max-width: 62ch; }
.kr__steps { list-style: none; margin: 26px 0 0; padding: 0; display: grid; gap: 0; }
@media (min-width: 900px) { .kr__steps { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.kr__step {
  display: block; padding: 14px 18px 16px 0;
  border-top: var(--rule-hair) solid var(--color-accent);
}
.kr__n { display: block; color: var(--color-accent); margin-bottom: 6px; }
.kr__x { font-size: 14.5px; line-height: 1.5; color: var(--color-neutral-700); }

/* ----------------------------------------------------------- subpages --- */
.page { padding-block: clamp(30px, 4.5vw, 60px) clamp(16px, 2.4vw, 26px); }
.page__h { margin-top: 12px; max-width: 18ch; }
.page__deck { margin-top: 20px; }

.about { display: grid; gap: clamp(24px, 4vw, 52px); align-items: start; }
@media (min-width: 880px) { .about { grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr); } }
.about__cells { margin-top: 30px; }
.about__fig { margin: 0; }
.about__fig img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.about__fig figcaption { margin-top: 10px; padding-top: 9px; border-top: var(--rule-hair) solid var(--color-divider); }

/* ----------------------------------------------------------------- faq --- */
.faq { border-top: var(--rule-hair) solid var(--color-divider); }
.faq__item { border-bottom: var(--rule-hair) solid var(--color-divider); }
.faq__h { margin: 0; font: inherit; }
.faq__q {
  width: 100%; display: flex; gap: 20px; justify-content: space-between; align-items: baseline;
  font: inherit; font-family: var(--font-heading); font-weight: 600; font-size: 18px;
  text-align: left; background: none; border: 0; cursor: pointer;
  padding: 18px 0; color: var(--color-text);
}
.faq__sign { flex: none; width: 14px; color: var(--color-accent); font-family: var(--font-body); }
.faq__sign::before { content: '+'; }
.faq__q[aria-expanded="true"] .faq__sign::before { content: '\2013'; }
.faq__a { display: none; padding: 0 0 20px; }
.faq__a[data-open] { display: block; }
.faq__a .body { max-width: 68ch; }

/* ----------------------------------------------------------------- cta --- */
.cta { background: var(--color-accent); color: #fff; }
.cta__inner {
  display: flex; flex-wrap: wrap; gap: 22px; align-items: center; justify-content: space-between;
  padding-block: clamp(30px, 4.5vw, 56px);
}
.cta__h { max-width: 20ch; }
/* Solid, not white at 78%. The translucent version measures fine by eye and
   lies to any harness that reads the computed colour without compositing it
   -- this is white-at-78%-over-#17407e, resolved once, here. */
.cta__f { margin-top: 10px; color: #ccd5e2; }
.cta .btn-primary { background: #fff; border-color: #fff; color: var(--color-accent); }
.cta .btn-primary:hover { background: var(--color-text); border-color: var(--color-text); color: #fff; }

/* ---------------------------------------------------------------- foot --- */
.foot { background: var(--color-sunk); border-top: var(--rule-hair) solid var(--color-divider); }
.foot__inner {
  display: grid; gap: clamp(20px, 3vw, 44px);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  padding-block: clamp(28px, 4vw, 48px);
}
.foot__inner .label { margin-bottom: 10px; }
.foot__inner .fine { color: var(--color-neutral-700); }
.foot__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.foot__link {
  font: inherit; font-size: 13.5px; background: none; border: 0; padding: 0;
  cursor: pointer; color: var(--color-neutral-700); text-align: left;
}
.foot__link:hover { color: var(--color-text); text-decoration: underline; }

/* --------------------------------------------------------------- small --- */
@media (max-width: 719px) {
  .mast__inner { flex-wrap: wrap; }
  .brand { width: 100%; margin-right: 0; }
  .nav { margin-right: auto; }
  .cell { border-right: 0; border-bottom: var(--rule-hair) solid var(--color-divider); padding-right: 0; }
  .cells { grid-template-columns: minmax(0, 1fr); }
  /* On a phone the copy spans the full width, so the desktop scrim's dark
     plateau covered the WHOLE frame and the pipe vanished into flat navy --
     a photograph nobody could see. Here the banner is taller and the scrim is
     vertical only: the top of the frame stays light enough to show the strap
     and the ice, and the copy, which sits at the foot, gets the dark. */
  .freeze { min-height: clamp(700px, 96vh, 920px); }
  .freeze__media img { object-position: 72% 30%; }
  .freeze__scrim {
    background: linear-gradient(180deg,
      rgba(var(--banner-ink), 0.32) 0%,
      rgba(var(--banner-ink), 0.12) 30%,
      rgba(var(--banner-ink), 0.40) 100%);
  }
  /* The dark is hung off the COPY, not the banner. A first pass faded to
     dark at 38% of the banner's height, and the kicker measured 3.79:1 at
     600px, because where the copy lands in a percentage fade depends on how
     tall the phone is and how many lines the deck wraps to. Anchored to the
     copy block, the fade finishes 40px above the kicker on every phone, and
     the frame above it stays light enough to see the pipe. */
  .freeze__inner { position: relative; }
  .freeze__inner::before {
    content: ''; position: absolute; z-index: -1;
    left: 0; right: 0; bottom: 0; top: -160px;
    background: linear-gradient(180deg,
      rgba(var(--banner-ink), 0) 0,
      rgba(var(--banner-ink), 0.86) 160px,
      rgba(var(--banner-ink), 0.92) 100%);
  }
  .cta__inner { align-items: flex-start; }
}
