/* DS-04 -- section layouts.
 *
 * Grid tracks are minmax(0, 1fr) everywhere. A bare 1fr has min-width: auto,
 * so one long service name pushes its track past its share and overflows the
 * document at 320px, which is the single most common way these builds fail
 * the responsive gate.
 */

.grid { display: grid; gap: var(--s5); margin: 0; padding: 0; list-style: none; }

.ratio { position: relative; }
.ratio img { display: block; width: 100%; height: auto; }

/* ---- hero: overhead photograph with inset detail ---------------------- */

.hero { padding-block: var(--s7) var(--s8); }

.hero__in { display: grid; gap: var(--s6); }

.hero__eyebrow {
  font-size: .875rem;
  line-height: 1.35;
  letter-spacing: .2em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--acc);
  margin: 0 0 var(--s4);
}

/* MATERIAL DISTINCTNESS: one overhead site plan assembled from unequal zones. */
@media (min-width: 1100px) {
  body.p-index main { display:grid; grid-template-columns:repeat(12,minmax(0,1fr)); align-items:start; background:var(--paper); overflow:clip; }
  body.p-index main > .sec { min-width:0; margin:0; }
  body.p-index main > .sec > .wrap { width:auto; max-width:none; }
  body.p-index .hero { grid-column:1/-1; grid-row:1; }
  body.p-index .svcp { grid-column:1/8; grid-row:2; transform:rotate(-.35deg); z-index:2; }
  body.p-index .appr { grid-column:8/-1; grid-row:2; transform:rotate(.45deg); }
  body.p-index .ruler { grid-column:1/-1; grid-row:3; }
  body.p-index .galp { grid-column:1/9; grid-row:4; }
  /* Staff is taller than Gallery. Let it span the Reviews row so the review
     band occupies the space that previously rendered as a blank half-page. */
  body.p-index .stfp { grid-column:9/-1; grid-row:4 / span 2; }
  body.p-index .stfp__list { grid-template-columns:1fr; }
  body.p-index .revp { grid-column:1/9; grid-row:5; transform:rotate(-.3deg); }
  body.p-index .faqp { grid-column:5/-1; grid-row:6; }
  body.p-index .cta { grid-column:1/-1; grid-row:7; }
}

.hero__lede {
  max-width: var(--measure);
  font-size: 1.125rem;
  margin: var(--s5) 0 var(--s6);
}

.hero__acts { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }

/* 375px: two actions may share a row only while each stays at least 148px
   wide. Below that they stack with a 12px gap, which is what flex-wrap plus
   this min-width does without a media query. */
.hero__acts .btn { min-width: 148px; }

.hero__second { min-height: 44px; display: inline-flex; align-items: center; }

.hero__fig { margin: 0; }

.hero__frame {
  position: relative;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
  /* 320px takes a 4:5 crop of the 4:3 file, 390px a 3:4, and from 768px the
     photograph is shown at its own ratio. object-fit does the cropping so no
     second file is needed for a breakpoint. */
  aspect-ratio: 4 / 5;
}

.hero__frame img { width: 100%; height: 100%; object-fit: cover; }

@media (min-width: 390px) { .hero__frame { aspect-ratio: 3 / 4; } }
@media (min-width: 768px) { .hero__frame { aspect-ratio: 4 / 3; } }

.hero__cap {
  margin-top: var(--s3);
  font-size: .8125rem;
  color: var(--acc);
}

/* the inset detail, and the magnifier that is its enhancement */

.mag { margin-top: calc(var(--s5) * -1); margin-inline-start: var(--s5); }

.mag__box {
  display: block;
  width: 140px;
  border: 1px solid var(--rule);
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg);
  box-shadow: 0 10px 26px rgba(0,0,0,.45);
}

.mag__box img { display: block; width: 100%; height: auto; }

.mag__label {
  display: block;
  padding: var(--s2) var(--s3);
  font-size: .8125rem;
  line-height: 1.35;
  min-height: 44px;
  border-top: 1px dashed var(--rule);
  color: var(--ink);
}

/* The magnifier is a <details>, so it opens on Enter or Space from the
   keyboard with no script at all. Open, the inset grows to 260px in place --
   it does not float over the photograph and it does not follow the pointer,
   because the reduced-motion arrangement has to be the same composition. */
.mag[open] .mag__box { width: min(260px, 72vw); }

.mag__box, .mag__label { transition: width var(--t); }

@media (min-width: 768px) {
  .mag { margin-inline-start: var(--s8); }
  .mag__box { width: 180px; }
  .mag[open] .mag__box { width: 320px; }
}

@media (min-width: 1024px) {
  .hero__in { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); align-items: center; }
  .hero__fig { position: relative; }
  .mag { position: absolute; inset-block-end: var(--s6); inset-inline-start: calc(var(--s6) * -1); margin: 0; }
}

/* ---- page heads ------------------------------------------------------- */

.phead { padding-block: var(--s7) var(--s6); }
.phead__lede { font-size: 1.125rem; margin: var(--s5) 0 0; }

/* ---- service preview and the services list ---------------------------- */

.svcp__intro, .galp__intro, .stfp__intro { max-width: var(--measure); margin: var(--s5) 0 var(--s6); }

.svcp__list { grid-template-columns: minmax(0, 1fr); }
.svcp__item { padding: var(--s5); background: var(--bg); border: 2px solid var(--rule); border-radius: var(--radius); }
.svcp__p { margin: var(--s3) 0; }
.svcp__link { display: inline-flex; align-items: center; min-height: 44px; font-weight: 600; }

.price__q { font-size: .8125rem; letter-spacing: .12em; text-transform: uppercase; color: var(--acc); display: block; }
.price__v { font-size: 1.5rem; }

.svc__list { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }

/* Each priced service is its own band, joined to the next with the edging
   rule -- this is the layered terrace bands treatment section 6 asks for on
   this page specifically, not a card grid. */
.svc__row {
  display: grid;
  gap: var(--s4);
  padding-block: var(--s6);
  border-top: 2px dashed var(--rule);
}

.svc__row:first-child { border-top: 0; }
.svc__row:nth-child(even) { background: var(--band2); margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter); }

.svc__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--s3); }
.svc__fitlabel { font-size: .8125rem; letter-spacing: .12em; text-transform: uppercase; color: var(--acc); font-weight: 700; }
.svc__link { display: inline-flex; align-items: center; min-height: 44px; font-weight: 600; }

.how__list, .proc__list { grid-template-columns: minmax(0, 1fr); counter-reset: none; }
.how__no, .proc__no { font-size: 1.25rem; color: var(--act); margin: 0 0 var(--s2); }
.how__p, .proc__p { margin: var(--s2) 0 0; }

.note__p, .limit__p, .appr__p { margin: var(--s5) 0 0; font-size: 1.0625rem; }

/* ---- gallery ---------------------------------------------------------- */

.galp__list, .gal__list { grid-template-columns: minmax(0, 1fr); }
.gal__list { display: grid; gap: var(--s5); margin: 0; padding: 0; list-style: none; }

.galp__fig, .gal__fig { margin: 0; }
.galp__fig { border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden; }
.galp__cap { display: flex; gap: var(--s3); margin-top: var(--s3); font-size: .875rem; line-height: 1.35; }

/*
 * The fabric edge. Section 17 asks for "fabric-edge masks"; this is a clip-path
 * rather than a mask-image because a polygon needs no data URI, draws the same
 * under file:// and is supported everywhere the rest of this build is. The
 * teeth are generated so the pinking stays even at any column width, and the
 * border goes with them -- a 2px rule and a cut edge cannot both be true.
 */
.gal__fig { position: relative; }

.gal__frame {
  background: var(--deep);
  overflow: hidden;
  clip-path: polygon(0.00% 2.00%, 5.00% 0%, 10.00% 2.00%, 15.00% 0%, 20.00% 2.00%, 25.00% 0%, 30.00% 2.00%, 35.00% 0%, 40.00% 2.00%, 45.00% 0%, 50.00% 2.00%, 55.00% 0%, 60.00% 2.00%, 65.00% 0%, 70.00% 2.00%, 75.00% 0%, 80.00% 2.00%, 85.00% 0%, 90.00% 2.00%, 95.00% 0%, 100.00% 2.00%, 100.00% 98.00%, 95.00% 100%, 90.00% 98.00%, 85.00% 100%, 80.00% 98.00%, 75.00% 100%, 70.00% 98.00%, 65.00% 100%, 60.00% 98.00%, 55.00% 100%, 50.00% 98.00%, 45.00% 100%, 40.00% 98.00%, 35.00% 100%, 30.00% 98.00%, 25.00% 100%, 20.00% 98.00%, 15.00% 100%, 10.00% 98.00%, 5.00% 100%, 0.00% 98.00%);
}

/*
 * The caption is a pinned garden job ticket: paper, a punched brass pin at the
 * top, a torn left rule and a ticket number above the line. It rides up over
 * the bottom of the photograph so the two read as one pinned object.
 */
.gal__cap {
  position: relative;
  display: block;
  margin: -28px var(--s4) 0;
  padding: var(--s5) var(--s4) var(--s4);
  background: #1F2E29;
  border: 2px solid var(--rule);
  border-inline-start: 2px dashed var(--act);
  border-radius: 3px;
  box-shadow: 0 2px 0 rgba(0, 0, 0, .35);
  font-size: .875rem;
  line-height: 1.45;
}

.gal__cap::before {
  content: "";
  position: absolute;
  inset-block-start: -9px;
  inset-inline-start: var(--s5);
  width: 16px;
  height: 16px;
  border: 2px solid var(--deep);
  border-radius: 50%;
  background: var(--hi);
}

/* the occasional pinned-card tilt section 17 allows -- every third ticket, not
   every one, so it reads as a pin that slipped rather than a pattern */
.gal__item:nth-child(3n) .gal__cap { transform: rotate(-1deg); }

.gal__no {
  display: block;
  margin-bottom: var(--s2);
  font-family: var(--font-h);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--act);
}

.gal__text { display: block; }

/* ---- prepared / on site / finished (gallery) ------------------------ */

.seq__h { font-size: clamp(1.5rem, 3vw, 2.25rem); margin: 0; }
.seq__intro { margin: var(--s4) 0 var(--s6); }
.seq__list { display: grid; gap: var(--s6); margin: 0; padding: 0; list-style: none; }
.seq__step { position: relative; }

.seq__label {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding-inline: var(--s3);
  background: var(--hi);
  color: var(--deep);
  font-family: var(--font-h);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  border-radius: 2px;
}

.seq__frame {
  margin-top: var(--s3);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}

.seq__p { margin: var(--s4) 0 0; font-size: .9375rem; color: #B9CAC5; }

/* ---- staff ------------------------------------------------------------ */

.stf__list, .stfp__list { grid-template-columns: minmax(0, 1fr); }
.stf__card { border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden; background: #2A3C3A; height: 100%; }
.stf__fig { margin: 0; }
.stf__body { padding: var(--s5); }
.stf__role { color: var(--acc); font-weight: 600; margin: var(--s2) 0; }
.stf__bio { margin: 0; color: #B9CAC5; }

/*
 * Service-focus tags: the two parts of the list this role actually works on,
 * drawn as the site-plan system's 12px paper labels so a record reads as a
 * pinned card rather than a profile block. They are real links into the
 * Services page, so a visitor can go straight from a role to the work.
 */
.stf__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin: var(--s4) 0 0;
  padding: 0;
  list-style: none;
}

.stf__tag {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 var(--s3);
  border: 1px dashed var(--rule);
  border-radius: 4px;
  background: var(--band2);
  color: var(--ink);
  font-family: var(--font-h);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
}

.stf__tag:hover, .stf__tag:focus-visible {
  border-style: solid;
  border-color: var(--act);
  color: var(--act);
}

.focus__list { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s5) 0 0; padding: 0; list-style: none; }
.focus__list a { display: inline-flex; align-items: center; min-height: 44px; padding-inline: var(--s4); border: 1px solid var(--rule); border-radius: var(--radius); text-decoration: none; }
.focus__list a:hover { background: var(--band2); }

/* ---- about ------------------------------------------------------------ */

.abt__cols { display: grid; gap: var(--s5); }
.prin__list { grid-template-columns: minmax(0, 1fr); }

/*
 * Pattern pieces. A pattern piece is paper with one corner cut square off, a
 * edge-allowance line dashed in from the edge and a punched hole to hang it by,
 * so that is what the card is -- drawn on the element, no extra markup, nothing
 * to load. The clip cuts the card's own edge, which is the point: a cut corner
 * has no border along the cut.
 */
.prin__item {
  position: relative;
  padding: var(--s6) var(--s5) var(--s5);
  background: #1F2E29;
  clip-path: polygon(0 0, calc(100% - 22px) 0, 100% 22px, 100% 100%, 0 100%);
}

/* the edge allowance */
.prin__item::before {
  content: "";
  position: absolute;
  inset: 10px;
  border: 2px dashed var(--rule);
  pointer-events: none;
}

/* the punched hole */
.prin__item::after {
  content: "";
  position: absolute;
  inset-block-start: var(--s4);
  inset-inline-start: var(--s4);
  width: 14px;
  height: 14px;
  border: 2px solid var(--rule);
  border-radius: 50%;
  background: var(--band);
}

.prin__h { margin: 0; font-size: 1.0625rem; }
.prin__p { margin: var(--s3) 0 0; }

/*
 * The four-step measurement line: one continuous rule with a brass node at each
 * point. It runs down the column here and turns horizontal at 1024, where the
 * four steps finally sit side by side.
 */
.proc__list { position: relative; }

.proc__list::before {
  content: "";
  position: absolute;
  inset-block: 13px;
  inset-inline-start: 11px;
  width: 2px;
  background: var(--ink);
}

.proc__step {
  position: relative;
  padding-inline-start: var(--s7);
}

.proc__step::before {
  content: "";
  position: absolute;
  inset-block-start: 4px;
  inset-inline-start: 3px;
  width: 18px;
  height: 18px;
  border: 2px solid var(--deep);
  border-radius: 50%;
  background: var(--hi);
}

.proc__no {
  font-family: var(--font-h);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.place__frame { border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden; }
.place__cap { margin-top: var(--s3); font-size: .8125rem; color: var(--acc); }

/* ---- reviews ---------------------------------------------------------- */

.revp__list, .rev__list { grid-template-columns: minmax(0, 1fr); }
/*
 * Fitting tickets. Section 17 asks for handwritten-style cards "using the
 * approved body font for readability", which rules out a script face -- so the
 * handwriting is carried by the object instead of the letterforms: paper, a
 * brass eyelet punched through the top corner, an accent-coloured edging line
 * run inside the edge, and the odd ticket pinned up a degree out of true.
 *
 * The edging line is var(--act), the accent colour. The about page's plan
 * pieces use a var(--rule) dashed line for the chalked edge allowance. Same
 * technique, two different marks, and they never appear on the same page.
 */
.rev__card {
  position: relative;
  height: 100%;
  padding: var(--s6) var(--s5) var(--s5);
  background: #253732;
  border: 1px solid var(--rule);
  border-radius: 3px;
  box-shadow: 0 2px 0 rgba(0, 0, 0, .35);
}

/* the edged border */
.rev__card::before {
  content: "";
  position: absolute;
  inset: 8px;
  border: 2px dashed var(--act);
  border-radius: 2px;
  opacity: .5;
  pointer-events: none;
}

/* the punched eyelet the ticket hangs by */
.rev__card::after {
  content: "";
  position: absolute;
  inset-block-start: 14px;
  inset-inline-end: 14px;
  width: 14px;
  height: 14px;
  border: 2px solid var(--deep);
  border-radius: 50%;
  background: var(--hi);
}

/* the occasional pinned-card tilt section 17 allows -- two of six, not all six */
.rev__item:nth-child(4) .rev__card { transform: rotate(1deg); }
.rev__item:nth-child(6) .rev__card { transform: rotate(-1deg); }

.rev__no {
  position: relative;
  font-family: var(--font-h);
  font-size: .875rem;
  letter-spacing: .12em;
  color: var(--act);
  margin: 0 0 var(--s3);
}

.rev__q, .revp__q { margin: 0; position: relative; }
.rev__q p, .revp__q p { margin: 0; }

/* the one oversized lead quote */
.rev__item--lead .rev__card { padding: var(--s7) var(--s6) var(--s6); }
.rev__item--lead .rev__q p {
  font-family: var(--font-h);
  font-size: clamp(1.125rem, 2.6vw, 1.5rem);
  line-height: 1.4;
}
.rev__item--lead .rev__q { max-width: var(--measure); }

.rev__foot { position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s3); margin-top: var(--s4); padding-top: var(--s3); border-top: 1px dashed var(--rule); }
.rev__by, .revp__by { font-weight: 700; margin: 0; }

/* the service label, as a paper label rather than a plain link */
.rev__svc {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--s3);
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--band2);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
}

.rev__svc:hover, .rev__svc:focus-visible { background: var(--hi); color: var(--deep); }

/* ---- faq -------------------------------------------------------------- */

.faqg__h { font-size: clamp(1.5rem, 3vw, 2.25rem); }
.faqg__sub { color: var(--acc); margin: var(--s2) 0 var(--s5); }

.faq__item { border-top: 2px dashed var(--rule); }
.faq__item:last-of-type { border-bottom: 2px dashed var(--rule); }

.faq__q {
  display: flex;
  align-items: center;
  min-height: 56px;
  padding: var(--s4) var(--s7) var(--s4) var(--s4);
  font-family: var(--font-h);
  font-weight: 700;
  font-size: 1.0625rem;
  cursor: pointer;
  list-style: none;
  position: relative;
}

.faq__q::-webkit-details-marker { display: none; }

/*
 * The brass marker: a piece of the crew's hardware rather than a brass
 * coloured "+", which on this ground would have been thin to read as well as a
 * weak answer to the word marker.
 */
.faq__q::after {
  content: "+";
  position: absolute;
  inset-inline-end: var(--s4);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 4px;
  background: var(--hi);
  color: var(--deep);
  font-size: 1rem;
  line-height: 1;
}

.faq__item[open] .faq__q::after { content: "\2212"; }

/*
 * An open panel sits on paper. The inline padding is on the closed row too, so
 * opening one paints a surface instead of nudging the question sideways.
 */
.faq__item[open] {
  background: #1F2E29;
  box-shadow: inset 3px 0 0 var(--hi);
}

.faq__a { padding: 0 var(--s4) var(--s5); }
.faq__a p { margin: 0; }

.faq__escape { margin: var(--s5) 0 0; padding: var(--s4); background: var(--band2); border-radius: var(--radius); }

/* ---- contact ---------------------------------------------------------- */

.con__grid { display: grid; gap: var(--s7); }
/*
 * The pinned hours card: paper, a brass pin punched through the top edge and a
 * degree out of true. The tilt bleeds about two pixels sideways, which the
 * wrap's 16px gutter absorbs at 320 -- it cannot reach the document edge.
 */
.cd__hcard {
  position: relative;
  margin-top: var(--s6);
  padding: var(--s6) var(--s5) var(--s5);
  background: #1F2E29;
  border: 1px solid var(--rule);
  border-radius: 3px;
  box-shadow: 0 2px 0 rgba(0, 0, 0, .35);
  transform: rotate(-1deg);
}

.cd__hcard::before {
  content: "";
  position: absolute;
  inset-block-start: -9px;
  inset-inline-start: 50%;
  transform: translateX(-50%);
  width: 16px;
  height: 16px;
  border: 2px solid var(--deep);
  border-radius: 50%;
  background: var(--hi);
}

.cd__hh { margin: 0; }
.cd__hours { margin: var(--s4) 0 0; }
.cd__hours dt { font-size: .8125rem; letter-spacing: .12em; text-transform: uppercase; color: var(--acc); font-weight: 700; margin-top: var(--s4); }
.cd__hours dd { margin: var(--s2) 0 0; }

.field { margin-bottom: var(--s5); }
.field__opt { font-size: .8125rem; color: #B9CAC5; margin: var(--s2) 0 0; }
/* --act is 4.36 against --band2, measured, and this is 13px text. The same
   rust two steps darker clears 4.5 on all four of the site's surfaces. */
.field__req { font-size: .8125rem; color: #EDEF9F; font-weight: 700; }

/*
 * The work order. The field numbers are a CSS counter, not nine typed numbers,
 * so the sequence cannot fall out of step when a field moves; and both this and
 * the 50px rule are scoped to .cform, so the footer subscribe form keeps the
 * site-wide 44px accessibility floor.
 */
.cform { counter-reset: fieldno; }

.cform .field > label::before {
  counter-increment: fieldno;
  content: counter(fieldno, decimal-leading-zero);
  display: inline-block;
  min-width: 28px;
  height: 20px;
  margin-inline-end: var(--s2);
  background: var(--hi);
  color: var(--deep);
  font-family: var(--font-h);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .06em;
  line-height: 20px;
  text-align: center;
  border-radius: 2px;
}

.cform .field input, .cform .field select { min-height: 50px; }

/* the two pieces of copy a visitor has a legal interest in: full size, page
   ground, no decoration of any kind */
.cform__consent { margin: var(--s5) 0; font-size: 1rem; line-height: 1.6; color: var(--ink); }
.cform__status { margin: var(--s5) 0 0; min-height: 44px; font-size: 1rem; line-height: 1.6; }
.alt__in { display: grid; gap: var(--s4); justify-items: start; }

/* ---- privacy ---------------------------------------------------------- */

.pv__date { margin: var(--s5) 0 0; font-weight: 700; }

/*
 * Section 17: "a clean pattern-sheet grid with numbered clauses and one faint
 * measurement rail. Do not place mulch texture behind body text."
 *
 * The grid is the GROUND the sheet lies on -- two gradients, no image, no
 * request. The sheet itself is flat paper, so every line of body copy sits on
 * one solid colour. That is the second sentence of the direction, and it is
 * the reason the grid is on .pv and not on .pv__body.
 */
.pv {
  background-color: var(--band2);
  background-image:
    repeating-linear-gradient(to right, rgba(242, 247, 246, .05) 0 1px, transparent 1px 32px),
    repeating-linear-gradient(to bottom, rgba(242, 247, 246, .05) 0 1px, transparent 1px 32px);
}

.pv__body {
  position: relative;
  counter-reset: clause;
  padding: var(--s5) var(--s4) var(--s5) var(--s6);
  background: #1F2E29;
  border: 2px solid var(--rule);
  border-radius: 3px;
}

/* the measurement rail: one rule with a tick every 16px, in the sheet's left
   margin. It measures the sheet -- it never passes behind a word. */
.pv__body::before {
  content: "";
  position: absolute;
  inset-block: var(--s5);
  inset-inline-start: var(--s3);
  width: 9px;
  border-inline-start: 2px solid rgba(109, 176, 156, .55);
  background-image: repeating-linear-gradient(to bottom, rgba(109, 176, 156, .55) 0 2px, transparent 2px 16px);
  pointer-events: none;
}

.pv__sec { padding-block: var(--s6); border-top: 2px dashed var(--rule); }
.pv__sec:first-child { border-top: 0; }
.pv__h { font-size: clamp(1.25rem, 2.5vw, 1.75rem); margin-bottom: var(--s4); }

/* numbered clauses: a counter, so the sequence cannot fall out of step when a
   clause is added, moved or removed */
.pv__h::before {
  counter-increment: clause;
  content: "Clause " counter(clause, decimal-leading-zero);
  display: block;
  margin-bottom: var(--s2);
  font-family: var(--font-h);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--act);
}

.pv__sec p + p { margin-top: var(--s4); }

/* ---- maintenance-route illustration (services) ------------------------------ */
/*
 * Section 17: "one maintenance-route illustration between rows three and four". It is
 * an inline SVG so that it needs no network request, no asset entry and no
 * fallback -- it draws identically with JavaScript off and under file://.
 */

.svc__stitch {
  padding-block: var(--s6);
  border-top: 2px dashed var(--rule);
}

.stitch { margin: 0; }
.stitch__svg { display: block; width: 100%; height: auto; }

.stitch__cloth path {
  fill: none;
  stroke: var(--rule);
  stroke-width: 2;
  stroke-dasharray: 10 8;
}

.stitch__thread {
  fill: none;
  stroke: var(--act);
  stroke-width: 3;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.stitch__pin { fill: none; stroke: var(--hi); stroke-width: 4; stroke-linecap: round; }
.stitch__head { fill: var(--hi); }

.stitch__cap {
  max-width: var(--measure);
  margin: var(--s4) 0 0;
  font-size: .9375rem;
  color: #B9CAC5;
}

/* ---- site-visit ruler (home) --------------------------------------------- */
/*
 * Section 17: "a horizontal 4-step site-visit ruler between Services and Gallery".
 * The rail is a real ruler edge -- 2px of ink with brass ticks every 16px and a
 * longer tick every 96px -- and the four steps hang off it. It is painted on the
 * list, so it cannot push the page wider than the viewport at 320px.
 */

.ruler__h { font-size: clamp(1.5rem, 3vw, 2.25rem); margin: 0; }
.ruler__intro { max-width: var(--measure); margin: var(--s4) 0 var(--s6); }

.ruler__list {
  position: relative;
  display: grid;
  gap: var(--s6);
  margin: 0;
  padding: var(--s6) 0 0;
  list-style: none;
  counter-reset: none;
}

.ruler__list::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  height: 14px;
  border-top: 2px solid var(--rule);
  background-image:
    repeating-linear-gradient(90deg, var(--hi) 0 2px, transparent 2px 16px),
    repeating-linear-gradient(90deg, var(--hi) 0 2px, transparent 2px 96px);
  background-size: 100% 6px, 100% 12px;
  background-repeat: no-repeat;
  background-position: 0 2px, 0 2px;
  pointer-events: none;
}

.ruler__step { position: relative; padding-top: var(--s2); }

.ruler__no {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  height: 24px;
  padding-inline: var(--s2);
  background: var(--hi);
  color: var(--deep);
  font-family: var(--font-h);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .08em;
  border-radius: 2px;
}

.ruler__sh { font-size: 1.0625rem; margin: var(--s3) 0 var(--s2); }
.ruler__p { margin: 0; color: #B9CAC5; font-size: .9375rem; }

/* ---- material swatches (home cta) ------------------------------------- */
/*
 * Section 17 asks for "a three-swatch material strip beside the contact CTA",
 * and for 24-40px fabric swatches site-wide. The chips are 36px and carry the
 * edging as a dashed inner edge; the material names beside them are the accessible
 * content, so the strip is information rather than three coloured squares.
 */

.cta__swatches {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  margin: var(--s5) 0 0;
  padding: var(--s4);
  list-style: none;
  border: 2px dashed var(--rule);
  border-radius: var(--radius);
  background: var(--bg);
}

.swatch { display: flex; align-items: center; gap: var(--s3); }

.swatch__chip {
  flex: none;
  width: 36px;
  height: 36px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  box-shadow: inset 0 0 0 2px var(--bg), inset 0 0 0 3px rgba(0, 0, 0, .35);
}

.swatch__chip--mulch { background: #6B4A33; }
.swatch__chip--granite { background: #8A8F8C; }
.swatch__chip--turf { background: #4E7D3A; }

.swatch__label {
  font-family: var(--font-h);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* ---- cta and subscribe ------------------------------------------------ */

.cta__in { display: grid; gap: var(--s5); }
.cta__p { max-width: var(--measure); margin: 0; }
.cta__actions { display: flex; flex-wrap: wrap; gap: var(--s3); }
.cta__actions .btn { min-width: 148px; }

/* ---- 404 -------------------------------------------------------------- */

/*
 * Section 17: "a 'pattern piece missing' motif with one outlined planting shape
 * and three recovery links. Keep the message direct and under one viewport."
 *
 * One shape. The edge that is present is an ink cutting line; the lower corner
 * that is absent is a faint dotted ghost of where it should be. The band is
 * deliberately shallow below 768 so the whole page clears a 320x568 viewport,
 * which is measured rather than assumed.
 */
.nf { padding-block: var(--s5); }

.nf__wrap { display: grid; gap: var(--s4); }
/* the shape grows with the screen rather than in one step, so the message
   clears a 320x568 viewport without the piece becoming a token at 414 */
.nf__fig { margin: 0; width: 100%; max-width: clamp(88px, 28vw, 240px); }
.nf__svg { display: block; width: 100%; height: auto; }
.nf__msg { max-width: var(--measure); }

.nf__cut {
  fill: none;
  stroke: var(--ink);
  stroke-width: 2.5;
  stroke-dasharray: 9 7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* where the piece is not */
.nf__gone {
  fill: none;
  stroke: var(--rule);
  stroke-width: 2.5;
  stroke-dasharray: 2 8;
  stroke-linecap: round;
}

.nf__grain { fill: none; stroke: var(--act); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.nf__notch { fill: none; stroke: var(--hi); stroke-width: 3; stroke-linecap: round; }

.nf__code {
  margin: 0;
  font-family: var(--font-h);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: .18em;
  color: var(--act);
}

/* the site's h1 is clamp(2.25rem, 11vw, 3.75rem), which is two 35px lines of
   heading before the message has even started. It comes back at 768. */
.nf__h1 { margin: var(--s2) 0 0; font-size: clamp(1.75rem, 8vw, 2.75rem); }
.nf__p { margin: var(--s4) 0 0; }
.nf__links { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s4); }
.nf__links a { display: inline-flex; align-items: center; min-height: 44px; }
.nf__book { margin: var(--s4) 0 0; }

/* ---- breakpoints ------------------------------------------------------ */

/* 414px: two compact metadata columns are allowed, and nothing else changes
   -- body content and forms stay single column, which section 7 requires. */
@media (min-width: 414px) {
  .cd__hours { columns: 2; column-gap: var(--s5); }
  .cd__hours dt, .cd__hours dd { break-inside: avoid; }
}

/* 768px: the desktop identity begins. Two-column sections activate and the
   gallery goes to two columns. */
@media (min-width: 768px) {
  /* the four steps stay in one column to 1024: four ordered steps in a 2x2
     block do not read in order, and four columns at 768 leave 160px a step */
  .svcp__list, .prin__list, .how__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .galp__list, .gal__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .seq__list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s5); }
  .stf__list, .stfp__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .revp__list, .rev__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* the lead ticket takes the full width at every multi-column width */
  .rev__item--lead { grid-column: 1 / -1; }
  .abt__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s7); }
  .svc__row { grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); gap: var(--s7); }
  .svc__head { flex-direction: column; align-items: flex-start; }
  .cta__in { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
  /* the swatch strip joins the action column, so it stands beside the CTA copy
     rather than under it */
  .cta__swatches { grid-column: 2; margin-top: 0; }
  .ruler__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .con__grid { grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); }
  /* the pattern piece stands beside the message once there is room for it */
  .nf { padding-block: var(--s8); }
  .nf__wrap { grid-template-columns: 240px minmax(0, 1fr); gap: var(--s8); align-items: center; }
  .nf__fig { max-width: 240px; }
  .nf__h1 { font-size: clamp(3.25rem, 7vw, 7rem); }
  .nf__links { margin-top: var(--s6); }
  .nf__book { margin-top: var(--s5); }
  /* the sheet takes a wider margin once there is room for one */
  .pv__body { padding: var(--s7) var(--s6) var(--s7) var(--s8); }
  .pv__body::before { inset-inline-start: var(--s5); }
}

/* 1024px: the bands reach full depth, the gallery goes to three columns
   because these plates are portrait, and the staff row shows all four. */
@media (min-width: 1024px) {
  .svcp__list, .prin__list, .how__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .galp__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .gal__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .stf__list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .proc__list { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  /* the measurement line turns and runs across the row */
  .proc__list::before {
    inset-block: auto;
    inset-block-start: 12px;
    inset-inline: 12px;
    width: auto;
    height: 2px;
  }

  .proc__step { padding-inline-start: 0; padding-block-start: var(--s6); }
  .proc__step::before { inset-block-start: 3px; inset-inline-start: 3px; }
  .ruler__list { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s5); }
  .rev__list, .revp__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* 1600px: the content is already centred at 1320px by --max. The gallery is
   the one band allowed to run wider, to 1600px, because a full-bleed row of
   material photographs is compositional rather than accidental. */
@media (min-width: 1600px) {
  .gal__wrap { max-width: 1600px; }
}

/* ---- landscaping: the botanical frame ---------------------------------
 * Section 4 of the Landscaping recommendation: a 1px frame in the frame
 * colour with a 14px radius and a 5px organic underline, and photographs
 * printed slightly less saturated with a touch more contrast.
 */
.hero__frame, .mag__box, .galp__fig, .seq__frame, .place__frame, .stf__fig {
  border-bottom: 5px solid var(--acc);
}
.mag__box { border-radius: var(--radius); }
.hero__frame img, .mag__box img, .ratio img { filter: saturate(.88) contrast(1.08); }

/* aajwebz-mailto-nowrap — an address is one token, never split across lines */
a[href^="mailto:"] {
  overflow-wrap: normal;
  word-break: normal;
  white-space: nowrap;
  display: inline-block;
  max-width: 100%;
}
@media (max-width: 380px) {
  a[href^="mailto:"] { font-size: 0.88em; }
}
