/* Northside Plumbing — bold-trade.
   One red line runs from the top of the page to the phone number at the foot.
   Everything else is quiet: warm stone, deep petrol, one signal red. */

@font-face {
  font-family: "Bevan";
  src: url(bevan-subset.woff2) format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Five colours. Red only ever means "now": the call, and the jobs we come
     out for today. Nothing else on the page is allowed to use it. */
  --bg: #eae5da;          /* warm stone, the page */
  --ink: #16302c;         /* deep petrol, type and the dark fields */
  --muted: #45554f;       /* second voice on stone, 6.27:1 */
  --accent: #c0271a;      /* signal red, 4.7:1 on stone */
  --accent-ink: #fdf7ec;  /* type on red, 5.6:1 */
  --tint: #d5cbb6;        /* deeper stone: the plate, and the Dave field */
  --rule: #b3a893;        /* hairlines, never type */
  --pale: #b9cdc6;        /* second voice on petrol, 8.5:1 */

  /* Spacing: six steps, each about 1.7 times the last, so the jump between a
     cluster and a section is something you can see. */
  --s1: 0.375rem;
  --s2: 0.75rem;
  --s3: 1.375rem;
  --s4: 2.5rem;
  --s5: 4.5rem;
  --s6: 7.5rem;

  /* Type: display against body at about 5.9 to 1, which is louder than a
     normal page on purpose. */
  --t-mega: clamp(3rem, 7.4vw, 6.25rem);
  --t-huge: clamp(2.25rem, 6.6vw, 4.5rem);
  --t-big: clamp(2rem, 3.1vw, 2.6rem);
  --t-mid: 1.25rem;
  --t-say: 1.1875rem;
  --t-body: 1.0625rem;
  --t-small: 0.9375rem;
  --t-tiny: 0.8125rem;

  --display: "Bevan", "Rockwell", "Roboto Slab", Georgia, serif;
  --body: Corbel, "Avenir Next", Avenir, "Segoe UI", system-ui, sans-serif;

  --run: 10px;            /* the red line */
  --gutter: 1.25rem;
}

@media (min-width: 62em) {
  :root { --run: 14px; --gutter: 2.5rem; }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--t-body);
  line-height: 1.55;
  font-variant-numeric: lining-nums tabular-nums;
}

img { max-width: 100%; }

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 400;
  line-height: 0.98;
  margin: 0;
}

h1 { font-size: var(--t-mega); letter-spacing: -0.015em; }
h2 { font-size: var(--t-big); letter-spacing: -0.01em; }
h3 { font-size: var(--t-mid); line-height: 1.15; }

p { margin: 0 0 var(--s3); }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

a:where(:link, :visited) {
  transition: background-color 0.12s linear, color 0.12s linear;
}

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

#services :focus-visible,
#cta :focus-visible,
#contact :focus-visible {
  outline-color: var(--bg);
}

.hold {
  width: min(100% - (var(--gutter) * 2), 1240px);
  margin-inline: auto;
}

.jump {
  position: absolute;
  left: -9999px;
  background: var(--ink);
  color: var(--bg);
  padding: var(--s2) var(--s3);
}
.jump:focus {
  left: var(--s2);
  top: var(--s2);
  z-index: 20;
}

/* ---- the top ---------------------------------------------------------- */

.mast {
  border-bottom: 3px solid var(--ink);
  padding-block: var(--s2) var(--s3);
}

.mast__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s2) var(--s4);
}

.mark {
  font-family: var(--display);
  font-size: 1.0625rem;
  letter-spacing: 0.01em;
  text-decoration: none;
}

.mast__nav {
  display: flex;
  gap: var(--s3);
  margin-right: auto;
  font-size: var(--t-small);
}

.mast__nav a { display: inline-block; padding-block: 0.35rem; text-decoration-thickness: 2px; text-underline-offset: 3px; }
.mast__nav a:hover { color: var(--accent); }

.mast__tel {
  font-family: var(--display);
  color: var(--accent);
  font-size: 1.0625rem;
  text-decoration: none;
  border: 2px solid var(--accent);
  padding: 0.4rem 0.7rem;
}
.mast__tel:hover { text-decoration: underline; text-decoration-thickness: 3px; }

/* The phone scale is set here, not left to the clamps. 48/32/20 on 17 is a
   decision: 48 is the largest the promise can be and still set in three lines
   at 390, 32 keeps a clear step down to the 20px sub-headings where 28 did
   not, and the body stays 17 because it is read outdoors. The ratio is 2.82,
   and it is the scale most of this page's visitors will actually see. */
@media (max-width: 47.99em) {
  :root {
    --t-mega: 3rem;
    --t-big: 2rem;
    --t-mid: 1.25rem;
  }
  .mast { padding-block: var(--s2); }
  .mast__row { gap: var(--s1) var(--s3); }
  .mast__nav { order: 3; width: 100%; margin-right: 0; gap: var(--s4); }
  .mast__tel { margin-left: auto; }
}

/* ---- the hero --------------------------------------------------------- */

#hero { padding-block: var(--s4) var(--s5); }

.hero__row { display: grid; gap: var(--s4); }

.hero__run {
  border-left: var(--run) solid var(--accent);
  padding-left: var(--s3);
}

.say {
  font-size: var(--t-say);
  line-height: 1.4;
  max-width: 36rem;
  margin-block: var(--s3) var(--s4);
}

.ring {
  position: relative;
  display: inline-block;
  background: var(--accent);
  color: var(--accent-ink);
  border: 3px solid var(--ink);
  font-family: var(--display);
  font-size: 1.375rem;
  text-decoration: none;
  white-space: nowrap;
  padding: 0.75rem 1.5rem;
}

.ring::before {
  content: "";
  position: absolute;
  top: 50%;
  left: calc((var(--s3) + var(--run)) * -1);
  width: calc(var(--s3) + var(--run));
  height: var(--run);
  margin-top: calc(var(--run) / -2);
  background: var(--accent);
}

.ring:hover, .ring:focus-visible { background: var(--ink); color: var(--bg); }

.under {
  font-size: var(--t-small);
  color: var(--muted);
  margin: var(--s2) 0 0;
}

.hero__say .under { margin-left: calc(var(--run) + var(--s3)); }

.plate {
  background: var(--tint);
  border-top: 4px solid var(--ink);
  padding: var(--s3);
}

.plate__row {
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr);
  align-items: baseline;
  gap: var(--s3);
  margin: 0;
  padding-block: var(--s3);
  border-bottom: 1px solid var(--rule);
}
.plate__row:last-child { border-bottom: 0; }

.plate__big {
  font-family: var(--display);
  font-size: 2.25rem;
  line-height: 1;
  text-align: right;
}

.plate__what { font-size: var(--t-small); color: var(--muted); }

@media (max-width: 61.99em) {
  .plate { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); padding: 0 0 var(--s2); }
  .plate__row {
    display: block;
    padding: var(--s3) var(--s2) 0 var(--s2);
    border-bottom: 0;
    border-right: 1px solid var(--rule);
  }
  .plate__big { text-align: left; }
  .plate__row:first-of-type { padding-left: 0; }
  .plate__row:last-child { border-right: 0; padding-bottom: 0; }
  .plate__big { font-size: 1.875rem; min-width: 0; }
}

@media (min-width: 62em) {
  #hero { padding-block: var(--s6) var(--s6); }
  .hero__run { padding-left: var(--s4); }
  .hero__say .under { margin-left: calc(var(--run) + var(--s4)); }
  .say { font-size: 1.25rem; }
  .hero__row {
    grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
    gap: var(--s5);
    align-items: start;
  }
  .plate { padding: var(--s3) var(--s4) var(--s4); }
  .plate__row { grid-template-columns: 4.5rem minmax(0, 1fr); padding-block: var(--s3); }
  .plate__big { font-size: 3rem; }
  .plate__what { font-size: var(--t-body); }
  .ring::before {
    left: calc((var(--s4) + var(--run)) * -1);
    width: calc(var(--s4) + var(--run));
  }
}

/* ---- the jobs, on the dark field -------------------------------------- */

#services {
  background: var(--ink);
  color: var(--bg);
  padding-block: var(--s4);
}

.jobs { display: grid; gap: var(--s3); }

.jobs__note, .route__note {
  color: var(--pale);
  font-size: var(--t-small);
  margin: var(--s3) 0 0;
  max-width: 26rem;
}
.route__note { color: var(--muted); }

.jobs__key {
  list-style: none;
  margin: var(--s3) 0 0;
  padding: 0;
  max-width: 26rem;
  font-size: var(--t-small);
  color: var(--pale);
}
.jobs__key li { display: flex; align-items: center; gap: var(--s2); padding-block: var(--s1); }
.jobs__key .when { grid-row: auto; flex: none; }

.jobs__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.jobs__list li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--s1) var(--s3);
  padding-block: 1rem;
  border-top: 1px solid rgba(185, 205, 198, 0.35);
}
.jobs__list li:last-child { border-bottom: 1px solid rgba(185, 205, 198, 0.35); }

.jobs__list h3 { grid-column: 1; }
.jobs__list p { grid-column: 1; margin: 0; color: var(--pale); }

.when {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  font-family: var(--display);
  font-size: var(--t-tiny);
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--pale);
  color: var(--pale);
}

.when--now {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

@media (min-width: 62em) {
  #services { padding-block: var(--s6); }
  .jobs {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.6fr);
    grid-template-areas: "head list" "shot list";
    gap: var(--s4) var(--s5);
    align-items: stretch;
  }
  .jobs:has(.is-empty) .jobs__head { display: flex; flex-direction: column; }
  .jobs:has(.is-empty) .jobs__key { margin-top: auto; padding-bottom: var(--s2); }
  .jobs__list li { padding-block: var(--s3); }
  .jobs__head { grid-area: head; }
  .jobs__list { grid-area: list; }
  .shot--job { grid-area: shot; }
  .jobs:has(.is-empty) { grid-template-areas: "head list"; }
}

/* ---- what happens, on the line ---------------------------------------- */

#how { padding-block: var(--s4); }

.route__row { display: grid; gap: var(--s3); }

.route {
  position: relative;
  list-style: none;
  counter-reset: stop;
  margin: 0;
  padding: 0;
}

.route li {
  position: relative;
  padding-left: 3.25rem;
  padding-bottom: var(--s3);
}
.route li:last-child { padding-bottom: 0; }

/* each joint is on the line, and each length of line runs from its own joint
   to the next one, so the run starts at joint one and stops at joint four */
.route li::before {
  counter-increment: stop;
  content: counter(stop);
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--display);
  font-size: 1.125rem;
}

.route li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: calc(1.125rem - (var(--run) / 2));
  top: 2.25rem;
  bottom: 0;
  width: var(--run);
  background: var(--accent);
}

.route h3 { padding-top: 0.15rem; }
.route p { margin: var(--s2) 0 0; max-width: 29rem; color: var(--muted); }

@media (min-width: 62em) {
  #how { padding-block: var(--s6); }
  .route li { padding-left: 4.5rem; padding-bottom: var(--s4); }
  .route li::before { width: 3rem; height: 3rem; font-size: 1.375rem; }
  .route li:not(:last-child)::after { left: calc(1.5rem - (var(--run) / 2)); top: 3rem; }
  .route h3 { padding-top: 0.4rem; }
  .route__row {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.7fr);
    gap: var(--s5);
    align-items: stretch;
  }
  .route__head { display: flex; flex-direction: column; justify-content: space-between; }
  .route__note { margin-bottom: var(--s2); }
}

/* ---- Dave, and the voices --------------------------------------------- */

#about {
  position: relative;
  background: var(--tint);
  padding-block: var(--s4);
}

.who { display: grid; gap: var(--s3); }

.who__say p { max-width: 29rem; margin-top: var(--s3); }

.tickets {
  list-style: none;
  margin: var(--s3) 0 0;
  padding: 0;
  max-width: 34rem;
  font-size: var(--t-small);
  color: var(--muted);
}
.tickets li { padding-block: var(--s1); border-top: 1px solid var(--rule); }

.voices { margin-top: var(--s4); }

.voice {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s1) var(--s3);
  margin: 0;
  padding-block: var(--s3);
  border-top: 2px solid var(--ink);
}
.voice:last-child { border-bottom: 2px solid var(--ink); }

.voice blockquote { margin: 0; }
.voice blockquote p { font-size: 1.1875rem; line-height: 1.45; max-width: 34rem; }
.voice figcaption { font-size: var(--t-small); color: var(--muted); }

@media (min-width: 62em) {
  #about { padding-block: var(--s6); }
  .who {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    grid-template-areas: "say shot" "voices voices";
    gap: var(--s5);
    align-items: start;
  }
  .who__say { grid-area: say; }
  .shot--team { grid-area: shot; }
  .voices { grid-area: voices; }
  .who:has(.is-empty) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "say" "voices";
  }
  .who:has(.is-empty) .who__say {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: 0 var(--s5);
  }
  .who:has(.is-empty) .who__say h2 { grid-column: 1 / -1; }
  .who:has(.is-empty) .tickets { margin-top: var(--s3); }
  .voice { grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; padding-block: var(--s4); }
  .voice blockquote p { font-size: 1.375rem; }
}

/* ---- the last word, where the line ends -------------------------------- */

#cta {
  background: var(--accent);
  color: var(--accent-ink);
  padding-block: var(--s4);
}

.last { display: grid; gap: var(--s3); }

.last__act { position: relative; }

/* The run arrives at the number. It drops from the top edge of the red field
   to the middle of the number and turns right into it, and it is ink there
   because red on red is nothing. The red length above the boundary only
   appears when the section above is a stone one, so deleting an optional
   section can never leave a stub floating on the dark field. */
.last__num {
  position: relative;
  margin: 0;
  padding-left: calc(var(--run) + var(--s3));
}

.last__num::before,
.last__num::after {
  content: "";
  position: absolute;
  left: 0;
  background: var(--ink);
}
/* The riser stops in the gap above the number, which on a phone is the row
   gap: any taller and it draws over the paragraph stacked above it. */
.last__num::before {
  top: calc(var(--s3) * -1);
  height: calc(var(--s3) + 50%);
  width: var(--run);
}
.last__num::after {
  top: 50%;
  margin-top: calc(var(--run) / -2);
  width: calc(var(--run) + var(--s3));
  height: var(--run);
}

.last__act::before { content: ""; display: none; }
#how + #cta .last__act::before,
#about + #cta .last__act::before {
  display: block;
  position: absolute;
  left: 0;
  top: calc((var(--s4) + var(--s3) + 1px) * -1);
  width: var(--run);
  height: var(--s3);
  background: var(--accent);
}

.last__say p { max-width: 29rem; margin-top: var(--s3); }

.huge {
  display: inline-block;
  white-space: nowrap;
  font-family: var(--display);
  font-size: var(--t-huge);
  line-height: 1;
  letter-spacing: -0.01em;
  text-decoration: none;
}
.huge:hover, .huge:focus-visible { text-decoration: underline; text-decoration-thickness: 5px; text-underline-offset: 8px; }

.under--light { color: var(--accent-ink); }
.under--light a { display: inline-block; padding-block: 0.25rem; text-underline-offset: 3px; }

@media (min-width: 62em) {
  #cta { padding-block: var(--s6); }
  .last {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: var(--s5);
    align-items: start;
  }
  .last__num { padding-left: calc(var(--run) + var(--s4)); }
  .last__num::before { top: calc((var(--s6) + 1px) * -1); height: calc(var(--s6) + 1px + 50%); }
  .last__num::after { width: calc(var(--run) + var(--s4)); }
  #how + #cta .last__act::before,
  #about + #cta .last__act::before {
    top: calc((var(--s6) + var(--s4) + 1px) * -1);
    height: var(--s4);
  }
}

/* ---- the foot ---------------------------------------------------------- */

#contact {
  background: var(--ink);
  color: var(--pale);
  padding-block: var(--s4);
  font-size: var(--t-small);
}

.foot { display: grid; gap: var(--s3); }

.mark--foot { color: var(--bg); font-size: 1.0625rem; margin-bottom: var(--s2); }

.foot a { display: inline-block; padding-block: 0.25rem; color: var(--bg); text-underline-offset: 3px; }
.foot a:hover { color: var(--accent-ink); }

.foot p { margin-bottom: var(--s1); }

.hours { border-collapse: collapse; text-align: left; }
.hours caption { text-align: left; color: var(--bg); font-family: var(--display); font-size: 1.0625rem; padding-bottom: var(--s2); }
.hours th, .hours td { padding: var(--s1) var(--s3) var(--s1) 0; border-top: 1px solid rgba(185, 205, 198, 0.35); font-weight: normal; }
.hours td { color: var(--bg); }

.foot__end {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1) var(--s4);
  margin-top: var(--s3);
  padding-top: var(--s3);
  border-top: 1px solid rgba(185, 205, 198, 0.35);
  font-size: var(--t-tiny);
}
.foot__end p { margin: 0; }

@media (min-width: 62em) {
  #contact { padding-block: var(--s6) var(--s5); }
  .foot { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr); gap: var(--s5); }
}

/* ---- photographs ------------------------------------------------------- */

.shot { margin: 0; background: var(--bg); border-top: 4px solid var(--ink); }
#services .shot { border-top-color: var(--bg); }
.shot img { display: block; width: 100%; height: 100%; object-fit: cover; }
.shot--job { aspect-ratio: 3 / 2; overflow: hidden; }
.shot--team { aspect-ratio: 4 / 3; overflow: hidden; }

/* No photograph yet: the slot leaves, and the row it sat in becomes one
   full-width column. Nothing is left stranded beside a hole. */
.shot.is-empty { display: none; }

@media (max-width: 61.99em) {
  /* On a phone the last section stacks, so the run has no stone above it to
     come down from: it starts at the top of the number and elbows in, rather
     than rising into the paragraph above. */
  .last__num::before { top: 0; height: 50%; }
  #how + #cta .last__act::before,
  #about + #cta .last__act::before { display: none; }
  .shot--job { aspect-ratio: 18 / 5; }
  .shot--team { aspect-ratio: 18 / 5; }
  .voices { margin-top: var(--s3); }
}

/* 320 is a real phone, not an edge case: every step of the scale drops one
   notch so the page still ends inside the ceiling */
/* 320, decided the same way: 42/28/18 on 17, a ratio of 2.47, which is the
   largest promise that still sets in four lines on the narrowest phone. */
@media (max-width: 22.5em) {
  :root {
    --s3: 1rem;
    --s4: 1.75rem;
    --s5: 3rem;
    --t-mega: 2.625rem;
    --t-big: 1.75rem;
    --t-mid: 1.125rem;
  }
  .ring { font-size: 1.125rem; padding: 0.6rem 1rem; }
  .jobs__list li { padding-block: 0.8125rem; }
  .voice { padding-block: var(--s3); }
  .plate__big { font-size: 1.5rem; }
  .route li { padding-left: 2.75rem; }
  .route li::before { width: 2rem; height: 2rem; font-size: 1rem; }
  .route li:not(:last-child)::after { left: calc(1rem - (var(--run) / 2)); top: 2rem; }
}

@media (prefers-reduced-motion: reduce) {
  a:where(:link, :visited) { transition: none; }
}
