/* H&S Plumbing — site stylesheet. The simple layout, set in the first version's type.

   TYPE. Every page loads the same Google Fonts link (two families) and nothing else.
   - Stick No Bills 800, the stencil, in capitals: headings only, 40 px and up (its M
     falls apart below that). Either fitted to the column (.lockup) or at one size.
   - Archivo at 68% width, weight 800 or 900, in capitals ("condensed capitals"):
     the business name, phone numbers, buttons, item titles, form labels, small labels.
   - Archivo at normal width, 400 or 600: running text, 18 px. Nothing under 14 px.
   COLOUR. Near-black for the top of a page, the closing band and the footer. Warm paper
   for everything in between. Lime for the action only: the call button, a form's send
   button, the pinned call bar, and the focus ring on black. Never lime behind words.
   LAYOUT. One column, one idea per screen: a heading, a sentence or two, at most one
   action. Square corners. No icons, tags, shadows, gradients, animation or heavy rules.
   Phone first (375 px). Desktop starts at 900 px.
   PHOTOS. One look (graded to the same slightly warm white, see work/ASSETS.md), one
   shape for a photo inside a section (4:5, edge to edge on phones), one photo per screen.

   PARTS, in file order. Each one can be used on any page as it is:
   tokens · fallback faces · base · condensed capitals · stencil and lockup · text ·
   wrap, band, split · masthead · top · buttons · photo · list · form · review ·
   questions · footer · callbar */

/* ------------------------------------------------------------------ tokens
   Colours, type sizes and spacing. Change a value here, not inside a part. */
:root {
  --black: #0B0B0B;
  --paper: #F1EDE3;
  --lime: #C8F03C;                       /* actions only. Text on lime is black. */
  --white: #FFFFFF;                      /* the inside of a form field */

  /* These three switch with the background. Paper values here, black values in "band". */
  --soft: rgb(11 11 11 / .7);            /* quieter text: captions, fine print, small labels */
  --line: rgb(11 11 11 / .22);           /* the thin 1 px rule */
  --ring: var(--black);                  /* the focus ring */

  --font-display: "Stick No Bills", "Impact", "Haettenschweiler", "Stencil Fallback", sans-serif;
  --font-caps: "Archivo", "Caps Fallback", sans-serif;
  --font-text: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --cap-space: .1em;                     /* word-spacing in condensed capitals, so words do not run together */

  --t-body: 1.125rem;                    /* 18  running text */
  --t-lead: 1.125rem;                    /* the sentence under a page's h1 */
  --t-cap: 1rem;                         /* 16  photo captions */
  --t-label: .9375rem;                   /* 15  form labels and small labels, in capitals */
  --t-small: .875rem;                    /* 14  fine print. Nothing goes smaller. */
  --t-quote: 1.375rem;                   /* 22  the review */
  --t-name: clamp(1.5rem, 7.2vw, 1.75rem);          /* the business name */
  --t-tel: 1.25rem;                                 /* the phone number in the masthead */
  --t-btn: 1.5rem;                                  /* 24  buttons */
  --t-btn-big: 1.875rem;                            /* 30  a lime button */
  --t-item: min(3rem, calc(var(--col) / 6.95));     /* item titles: "The inspection" fits a phone */
  --t-stencil: clamp(2.5rem, 13vw, 4rem);           /* a stencil heading that is not a lockup */

  --gutter: 16px;                        /* space at the left and right page edge */
  --wrap: 32rem;                         /* widest the content gets (the phone column) */
  --col: min(calc(100vw - 2 * var(--gutter)), var(--wrap));   /* the phone column as a length */
  --gap: 88px;                           /* space between sections (was 56: too tight on a phone) */
  --measure: 27em;                       /* widest a paragraph gets, about 60 characters */
  --tap: 3.25rem;                        /* 52  smallest height of a button or a field */
}
@media (min-width: 900px) {
  :root {
    --t-lead: 1.375rem;
    --t-quote: 1.875rem;
    --t-name: 2.25rem;
    --t-tel: 1.625rem;
    --t-btn: clamp(1.25rem, 2vw, 1.625rem);
    --t-btn-big: clamp(1.75rem, 2.8vw, 2.25rem);
    --t-item: min(4.5rem, 4.9vw);
    --t-stencil: 4.5rem;
    --gutter: 40px;
    --wrap: 1200px;
    --gap: 112px;
  }
}

/* ------------------------------------------------------------------ fallback faces
   What shows for the moment before the web fonts arrive: Arial Bold, shrunk until its
   capitals are no wider than the real face, so fitted lines and button labels hold their
   shape and nothing spills. For the stencil, Impact is tried first: on a device that
   has it, its widths are within a few percent of the stencil's as it is. */
@font-face {
  font-family: "Stencil Fallback"; font-weight: 800; size-adjust: 71%;
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Arial");
}
@font-face {
  font-family: "Caps Fallback"; font-weight: 800 900; size-adjust: 78%;
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Arial");
}

/* ------------------------------------------------------------------ base */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; background: var(--black); }
body {
  margin: 0;
  background: var(--paper);
  color: var(--black);
  font: 400 var(--t-body)/1.6 var(--font-text);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, p, ul, ol, figure, blockquote { margin: 0; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: .18em; }
[hidden] { display: none !important; }
:focus-visible { outline: 3px solid var(--ring); outline-offset: 3px; }

/* ------------------------------------------------------------------ condensed capitals
   Heavy Archivo at 68% width, in capitals, with a little air between the words.
   .caps puts any element in it, at the size it already has.
   h3 is a small heading in it. .label is a small quiet line in it (a rating, a source).
   The other names in this list are parts further down the file. */
.caps, h3, .label, .masthead__name, .masthead__tel, .btn, .or-call a,
.field label, .review figcaption b {
  font-family: var(--font-caps);
  font-weight: 800;
  font-stretch: 68%;
  text-transform: uppercase;
  word-spacing: var(--cap-space);
}
h3, .masthead__name, .btn, .or-call a { font-weight: 900; }
h3 { font-size: 1.5rem; line-height: 1; }
.label { font-size: var(--t-label); line-height: 1.2; letter-spacing: .05em; color: var(--soft); }

/* ------------------------------------------------------------------ stencil and lockup
   h1 and h2 are set in the stencil, in capitals, at one size, and wrap where they must.
   .stencil gives any other element the same.

   .lockup is the poster treatment. Each line of the heading is its own
   <span class="l" style="--em: N"> and is sized to fill the column exactly.
   --em is the width of that line in ems, in Stick No Bills 800 capitals; the line's
   font-size is the column width divided by --em.
   To add a line: put its words in the ST list in work/tmp/measure-1019.html, open it in
   the browser pane from the preview server and read the "st" row (no --dump-dom: this
   Mac's Chrome hangs on it), take that number, add about .012 so it can never touch the edge, and write that as --em.
   A line with --em above 8.57 comes out under 40 px on a 375 px phone: break it in two.
   Measured so far:
     You deal with us. 7.3 · We deal with 5.59 · the city. 3.515
     Name, number, 6.14 · what's going on. 7.055
     That's not your job. 8.54 (with letter-spacing: -.005em) · It's ours. 3.85
     Questions 4.22 · I get asked. 4.735
     If you haven't called 8.575 (with letter-spacing: -.012em) · H&S Plumbing, 6.04
     I don't know 5.255 · who you're calling. 8.35 · Privacy 3.17 · Got it. 2.66
     Added 2026-10-19 (measured in work/tmp/measure-1019.html, +.012 included):
     Don't like the price? 8.531 · You owe us 4.762 · nothing. 3.549 · Smack in 3.683
     the middle. 4.626 · Word of mouth. 6.726 · Quit guessing 5.654 · what the repair 6.898
     is gonna cost. 6.017
   line-height .77 puts the top of each line box on the top of the capitals, and the
   negative margin takes off what is left under the baseline, so the space between two
   lines is the same in every lockup: 3.4% of the column. */
h1, h2, .stencil, .lockup {
  font-family: var(--font-display);
  font-size: var(--t-stencil);
  font-weight: 800;
  line-height: .9;
  text-transform: uppercase;
  text-wrap: balance;
}
.lockup {
  container-type: inline-size;
  max-width: 45rem;                      /* a lockup alone on a wide desktop page stops here */
  overflow-x: clip;
  --lw: var(--col);                      /* the column width; replaced by 100cqi just below */
}
@supports (width: 1cqi) { .lockup { --lw: 100cqi; } }
.lockup .l {
  display: block;
  white-space: nowrap;
  font-size: calc(var(--lw) / var(--em));
  line-height: .77;
  margin-bottom: -.07em;
}
.lockup .l + .l { margin-top: calc(var(--lw) * .034); }
/* Desktop browsers without container units: work the lockup's column out from the screen.
   In the top it is the text column; anywhere else, the left side of a .split. */
@media (min-width: 900px) {
  @supports not (width: 1cqi) {
    .lockup { --c: calc(min(100vw, 1280px) - 80px); --lw: calc((var(--c) - 96px) * 5 / 11); }
    .top .lockup { --lw: calc(var(--c) - 56px - max(320px, var(--c) * .36)); }
  }
}

/* ------------------------------------------------------------------ text
   A plain <p> is running text. .lead is the sentence under a page's h1.
   .quiet is the same size, softer. .small is fine print. .strong stands out a little.
   .tel is a phone number inside a sentence. .or-call is "Or call" with the number big. */
p { max-width: var(--measure); text-wrap: pretty; }
h1 + p, h2 + p { margin-top: 18px; }
p + p { margin-top: 14px; }
.lead { font-size: var(--t-lead); line-height: 1.45; text-wrap: balance; }
.quiet, .small { color: var(--soft); }
.small { font-size: var(--t-small); line-height: 1.45; }
.strong, .tel { font-weight: 600; }
.tel { white-space: nowrap; }
.or-call a {
  display: inline-block;                 /* with the two lines below: a 48 px tap area, and nothing moves */
  padding-block: 11px;
  margin-block: -11px;
  margin-left: .15em;
  font-size: 1.625rem;
  line-height: 1;
  white-space: nowrap;
  text-decoration-thickness: 2px;
  text-decoration-skip-ink: none;
  text-underline-offset: .16em;
}

/* ------------------------------------------------------------------ wrap, band, split
   .wrap   centres the content and gives it the page gutters.
   .band   a full-width section. Add .band--paper or .band--black.
           Two paper bands in a row share one gap, not two.
           A page's closing band is a .band--black: a heading, one line, .actions.
   .split  inside a band. Phones: its children stack. Desktop: the first child (the
           heading) sits on the left and the second on the right. A third child comes
           last on phones and goes under the heading on desktop (a photo).
           .split--end lines the right side up with the foot of the heading. */
.wrap {
  max-width: calc(var(--wrap) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.band { padding-block: var(--gap); }
.band--paper { background: var(--paper); color: var(--black); }
.band--paper + .band--paper { padding-top: 0; }
.band--black, .top, .footer, .callbar {
  background: var(--black);
  color: var(--paper);
  --soft: rgb(241 237 227 / .72);
  --line: rgb(241 237 227 / .28);
  --ring: var(--lime);
}
.split > * + * { margin-top: 40px; }
@media (min-width: 900px) {
  .split {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    grid-template-rows: auto 1fr;
    column-gap: clamp(3rem, 7vw, 6rem);
    align-items: start;
  }
  .split > * + * { margin-top: 0; }
  .split > :nth-child(2) { grid-column: 2; grid-row: 1 / span 2; }
  .split > :nth-child(3) { grid-column: 1; grid-row: 2; margin-top: 40px; }
  .split--end > :nth-child(2) { align-self: end; }
}

/* ------------------------------------------------------------------ masthead
   The business name on the left, the phone number on the right. No menu.
   On the landing page the name is plain text; on other pages it may hold a link home. */
.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  max-width: calc(var(--wrap) + 2 * var(--gutter));
  min-height: 3.5rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.masthead__name { font-size: var(--t-name); line-height: 1; white-space: nowrap; }
.masthead__name a { text-decoration: none; }
.masthead__tel {
  display: inline-flex;
  align-items: center;
  min-height: 3rem;
  font-size: var(--t-tel);
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
}

/* ------------------------------------------------------------------ top
   The near-black first screen of a page: .masthead, then .top__body holding
   .top__photo (optional) and .top__text (the h1, a .lead, .actions, a .label).
   Phones: the photo runs edge to edge and is the part that gives, so the heading and
   both buttons stay on the first screen. Desktop: text left, photo right, same height.
   Nothing sits on the photo (the tab that said who he is was removed on 2026-10-19:
   tags break the calm rule). Aim the crop with style="--focus: 50% 22%" on the <img>
   (from the left, from the top). Preload the photo in <head> with the same srcset. */
.top__body { max-width: calc(var(--wrap) + 2 * var(--gutter)); margin-inline: auto; }
.top__photo { position: relative; height: 15rem; overflow: hidden; }
.top__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 15%);
}
.top__text { padding: 18px var(--gutter) 20px; }
.top__text .lead { margin-top: 16px; }
.actions + .label { margin-top: 14px; }
@media (max-width: 899px) {
  @supports (min-height: 100svh) {
    .top { display: flex; flex-direction: column; min-height: min(100svh, 51rem); }
    .top__body { display: flex; flex: 1 1 auto; flex-direction: column; width: 100%; }
    .top__photo { flex: 1 1 0; height: auto; min-height: 9rem; }
  }
}
@media (max-width: 899px) and (max-height: 620px) {
  .top__photo { min-height: 6.5rem; }    /* a very short screen: keep the call button on it */
}
@media (min-width: 900px) {
  .masthead { min-height: 5rem; }
  .top__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(20rem, 36%);
    column-gap: 3.5rem;
    padding: 0 var(--gutter) 3.5rem;
  }
  .top__photo { grid-column: 2; grid-row: 1; height: auto; min-height: 24rem; }
  .top__text { grid-column: 1; grid-row: 1; padding: 0; }
  .top__text .lead { margin-top: 2rem; line-height: 1.35; }
  .top__text .lead span { display: block; }       /* one sentence to a line */
  .actions + .label { margin-top: 1.25rem; }
}

/* ------------------------------------------------------------------ buttons
   .btn--call  the big lime button: the one main action of a screen ("Get a call back",
               or "Call (832) 388-7703" where calling is the action). Its label sits in a
               <span> and is sized as if it were "Call (832) 388-7703" (8.25 em) set as
               wide as the button, so every big button has the same type size.
   .btn--lime  any other lime button: a form's send button, the one in the call bar.
   .btn--line  the second choice, outlined in the colour of the text around it.
   .actions    holds one or two buttons: stacked and full width on phones, in a row on
               desktop (still stacked inside a .split). One lime button to a screen. */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--tap);
  padding: 0 1rem;
  border: 2px solid transparent;
  border-radius: 0;
  background: none;
  color: inherit;
  font-size: var(--t-btn);
  line-height: 1;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.btn--lime, .btn--call {
  min-height: 4rem;
  border-color: var(--lime);
  background: var(--lime);
  color: var(--black);
  font-size: var(--t-btn-big);
}
.band--paper .btn--lime, .band--paper .btn--call { border-color: var(--black); }
.btn--call { container-type: inline-size; min-height: max(4rem, calc(var(--col) * .187)); padding: 0; }
.btn--call span { font-size: calc((var(--col) - 2rem) / 8.25); }
@supports (width: 1cqi) { .btn--call span { font-size: calc((100cqi - 2rem) / 8.25); } }
.btn--line { border-color: currentColor; }
@media (hover: hover) {
  .btn--lime:hover, .btn--call:hover { background: var(--white); }
  .btn--line:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: .16em; }
}
.actions { display: grid; gap: 10px; margin-top: 16px; }
.actions + .or-call { margin-top: 22px; }        /* "Or call (832) 388-7703", quiet, under a band's one button */
@media (min-width: 900px) {
  .btn { min-height: 4.25rem; padding: 0 1.75rem; }
  .btn--call { container-type: normal; min-height: 4.25rem; padding: 0 1.75rem; }
  .btn--call span { font-size: var(--t-btn-big); }
  .actions { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 1.75rem; }
  .actions .btn { width: auto; }
  .split .actions { display: grid; }               /* beside a heading they stay stacked */
  .split .actions .btn { width: 100%; }
}

/* ------------------------------------------------------------------ photo
   <figure class="photo"> with an <img> and a plain <figcaption> that says what is in
   the picture and nothing else. No frame, nothing on top of it. Without a modifier the
   picture keeps its own shape. .photo--wide (4:3), .photo--square and .photo--tall
   (4:5) crop it; aim the crop with style="--focus: 50% 5%" on the <img>. */
.photo img { width: 100%; }
.photo--wide img, .photo--square img, .photo--tall img {
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}
.photo--wide img { aspect-ratio: 4 / 3; }
.photo--square img { aspect-ratio: 1; }
.photo--tall img { aspect-ratio: 4 / 5; }
.photo figcaption { margin-top: 8px; font-size: var(--t-cap); line-height: 1.4; color: var(--soft); }
/* .photo--bleed: on phones the picture runs to both screen edges (the caption keeps the
   gutter). On desktop it stays in its column. */
@media (max-width: 899px) {
  .photo--bleed { margin-inline: calc(-1 * var(--gutter)); }
  .photo--bleed figcaption { padding-inline: var(--gutter); }
}
@media (min-width: 900px) {
  .photo--tall { max-width: 26rem; }              /* a 4:5 picture beside a heading stays a picture, not a wall */
}

/* ------------------------------------------------------------------ list
   <ul class="list">: a few points, each an <h3> title in big condensed capitals and
   one sentence. Space separates them, not rules. No numbers, no tags. */
.list { padding: 0; list-style: none; }
.list > li + li { margin-top: 34px; }
.list h3 { font-size: var(--t-item); line-height: .9; white-space: nowrap; }
.list h3 + p { margin-top: 10px; }

/* ------------------------------------------------------------------ form
   .form holds .field blocks (a label in capitals above a white box), then a .btn--lime,
   then the lines under it. .field--half puts two fields side by side (first and last
   name). .field--select goes on the field that holds a <select> and draws its arrow.
   .field__note is the plain "optional" beside a label.
   The field in use gets a thick dark outline. It never turns lime. */
.form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px 12px;
}
.form > * { grid-column: 1 / -1; }
.form > .field--half { grid-column: auto; }
.form > .btn { margin-top: 4px; }
.form > .consent + .btn { margin-top: -4px; }      /* the consent line sits right on the button */
.form > .btn + p { margin-top: 2px; }
.form > p + p { margin-top: -8px; }
.field { position: relative; min-width: 0; }
.field label {
  display: block;
  margin-bottom: 5px;
  font-size: var(--t-label);
  line-height: 1.2;
  letter-spacing: .05em;
}
.field__note {
  margin-left: 6px;
  font: 400 var(--t-small)/1.2 var(--font-text);
  letter-spacing: 0;
  word-spacing: 0;
  text-transform: none;
  color: var(--soft);
}
.field input, .field select, .field textarea {
  display: block;
  width: 100%;
  min-height: 3.375rem;                  /* 54 */
  margin: 0;
  padding: 0 13px;
  border: 2px solid var(--black);
  border-radius: 0;
  background: var(--white);
  color: var(--black);
  font: 600 var(--t-body)/1.3 var(--font-text);
  -webkit-appearance: none;
  appearance: none;
}
.field textarea { min-height: 5.75rem; padding-block: 11px; resize: vertical; }
.field select { padding-right: 2.75rem; }
.field--select::after {                  /* the drop-down arrow, drawn with borders */
  content: "";
  position: absolute;
  right: 17px;
  bottom: 22px;
  border: 7px solid transparent;
  border-top: 9px solid var(--black);
  border-bottom: 0;
  pointer-events: none;
}
.field :focus { outline: 3px solid var(--black); outline-offset: 0; }
.field :-webkit-autofill {               /* keeps an autofilled box white */
  -webkit-box-shadow: 0 0 0 100px var(--white) inset;
  -webkit-text-fill-color: var(--black);
}

/* ------------------------------------------------------------------ review
   <figure class="review">: a <blockquote> as plain text, a little larger and heavier
   than running text, and a <figcaption> saying where it is from (put the source in a
   <b>). No drawn quote marks, no highlight. Quote reviews word for word. */
.review blockquote p { max-width: 25em; font-size: var(--t-quote); font-weight: 600; line-height: 1.35; }
.review figcaption { margin-top: 18px; font-size: var(--t-small); line-height: 1.4; color: var(--soft); }
.review figcaption b { display: block; margin-bottom: 2px; font-size: 1.0625rem; letter-spacing: .05em; color: var(--black); }
.review + p { margin-top: 24px; }

/* ------------------------------------------------------------------ questions
   <div class="questions"> holding <details> blocks, all closed until tapped. The
   question is the <summary>, the answer a <p>. Plus when shut, minus when open. */
.questions { border-top: 1px solid var(--line); }
.questions details { border-bottom: 1px solid var(--line); }
.questions summary {
  position: relative;
  display: block;
  padding: 16px 2.75rem 16px 0;
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.25;
  list-style: none;
  cursor: pointer;
}
.questions summary::-webkit-details-marker { display: none; }
.questions summary::before, .questions summary::after {      /* the plus: two thin bars */
  content: "";
  position: absolute;
  top: 1.75rem;
  right: 2px;
  width: 1rem;
  height: 2px;
  background: currentColor;
}
.questions summary::after { transform: rotate(90deg); }
.questions details[open] summary::after { display: none; }
.questions details p { padding-bottom: 24px; }

/* ------------------------------------------------------------------ footer
   Near-black, small text: the legal name, the town, the phone number, the privacy link. */
.footer {
  padding-block: 20px 24px;
  border-top: 1px solid var(--line);
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--soft);
}
.footer p { max-width: none; margin-top: 0; text-wrap: balance; }
.footer a { display: inline-block; padding-block: 8px; color: var(--paper); white-space: nowrap; }

/* ------------------------------------------------------------------ callbar
   Under 900 px wide only: one lime call button pinned to the bottom of the screen, as
   wide as the column and no wider. It stays hidden until the page's script adds .is-on
   (once the top buttons have scrolled away, and not while a form or another pair of
   buttons is on screen, or a field has focus).
   Without the script it never shows, and the page still works. */
.callbar { display: none; }
@media (max-width: 899px) {
  .callbar.is-on {
    display: block;
    position: fixed;
    inset: auto 0 0;
    z-index: 10;
    padding: 8px var(--gutter) calc(8px + env(safe-area-inset-bottom, 0px));
  }
  .callbar .btn {                        /* no wider than the column above it (a tablet, a phone on its side) */
    max-width: var(--wrap);
    min-height: 3.5rem;
    margin-inline: auto;
    font-size: clamp(1.25rem, 6.6vw, 1.625rem);
  }
}
