/* ── the type scale, and which size means what ────────────────────────────────
   🔴 An audit of every page found --step--1 (15px) used 53 times against 13 for --step-0: the
   size meant for captions and metadata had become the site's body text, including the answers in
   the FAQ, the copy in every card and the steps of the process. That is why the type read as
   uneven — the same kind of sentence was one size in a card and another in an article.

   The rule now: **prose is --step-0, labels are --step--1.** A description, an answer, a step is
   prose. A breadcrumb, a caption, a counter, a tag, a table cell is a label.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── section heads ──────────────────────────────────────── */
.sec-head{max-width:64ch;margin-bottom:clamp(2.2rem,1.6rem + 2vw,3.6rem)}
.eyebrow{font-size:.7rem;letter-spacing:.26em;text-transform:uppercase;color:var(--brass);margin-bottom:1.1rem}
.sec-lede{color:var(--text-70);margin-top:1.1rem;max-width:58ch}

/* ── what we repair: two featured cards + a compact type grid ───── */
.feature-pair{display:grid;grid-template-columns:1fr 1fr;gap:1.4rem;margin-bottom:1.4rem}
/* A pair of one is not a pair. Without this the single card sits in the first of two columns and
   the second half of the band is black — which is exactly how it looked. */
.feature-pair-one{grid-template-columns:1fr}
/* With no photograph to sit beside, the card runs the whole band and a line of prose runs to about
   a hundred and sixty characters. Full width is right for the card; it is not right for the text. */
.feature-pair-one > .feature-card:not(.card-wide) .feature-body > p{max-width:80ch}
.feature-card{
  background:var(--night-2);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;display:flex;flex-direction:column;
  transition:transform .3s,box-shadow .3s;
}
.feature-card:hover{transform:translateY(-4px)}
.feature-card figure{margin:0;position:relative;overflow:hidden}
.feature-card img{width:100%;aspect-ratio:16/10;object-fit:cover;transition:transform .6s ease}
.feature-card:hover img{transform:scale(1.04)}
.feature-card figcaption{
  position:absolute;left:1rem;bottom:1rem;
  background:rgba(255,255,255,.16);backdrop-filter:blur(12px);
  border:1px solid rgba(255,255,255,.3);border-radius:100px;
  padding:.42rem .95rem;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--on-hero);
}
.feature-body{padding:clamp(1.4rem,1rem + 1.3vw,2rem);display:flex;flex-direction:column;gap:.85rem;flex:1}
.feature-body h3{font-size:var(--step-2)}
.feature-body p{color:var(--text-70);font-size:var(--step-0);margin:0}

/* the second row of service cards: same card, four across, shorter image */
.feature-quad{grid-template-columns:repeat(4,1fr);margin-bottom:0}
.feature-quad .feature-card img{aspect-ratio:4/3}
.feature-quad .feature-body{padding:1.4rem}
.feature-quad .feature-body h3{font-size:var(--step-1)}
.type{
  background:var(--night-2);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:1.6rem;transition:transform .3s,border-color .3s;
}
.type:hover{transform:translateY(-4px);border-color:var(--line-2)}
.type h3{font-size:var(--step-1);margin-bottom:.5rem}
.type p{color:var(--text-70);font-size:var(--step-0);margin:0 0 .7rem}
/* The surface of a card inside a light band. White by default; each dark palette redefines
   --panel once, so a component added later inherits the right color instead of staying white. */
.band-light{--panel:#fff;--panel-line:var(--line)}
.band-light .feature-card,.band-light .type{background:var(--panel);border-color:var(--panel-line)}

/* ── cards ──────────────────────────────────────────────── */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:1.1rem}
.card{
  position:relative;background:var(--night-2);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:clamp(1.5rem,1.1rem + 1.3vw,2.1rem);
  display:flex;flex-direction:column;gap:.85rem;
  transition:border-color .25s,transform .25s,background .25s;
}
.card:hover{border-color:var(--line-2);transform:translateY(-3px);background:var(--night-3)}
.card h3{padding-right:2.5rem}
.card p{color:var(--text-70);font-size:var(--step-0);margin:0}
.card-wide{grid-column:span 2}
.card-wide-inner{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(1.2rem,1rem + 1.5vw,2.4rem);align-items:center}
.card-wide-inner figure{margin:0}
/* Portrait was written for a card standing in a column. Turned on its side and given half a band,
   4/5 makes a picture nine hundred pixels tall beside four lines of text — the image stops being
   an illustration and becomes the section. Landscape is what a wide card wants. */
.card-wide-inner img{border-radius:var(--r);aspect-ratio:16/10;object-fit:cover}
.card-wide h3{margin-bottom:.7rem}

.mini{display:flex;flex-direction:column;gap:.5rem;font-size:var(--step-0);color:var(--text-70)}
.mini li{position:relative;padding-left:1.1rem}
.mini li::before{content:"";position:absolute;left:0;top:.7em;width:5px;height:5px;border-radius:50%;background:var(--brass);opacity:.8}

.ghost-link{
  margin-top:auto;align-self:flex-start;text-decoration:none;
  font-size:var(--step--1);font-weight:600;color:var(--text);
  display:inline-flex;align-items:center;gap:.4rem;transition:gap .2s,color .2s;
}
.ghost-link span{color:var(--brass)}
.ghost-link:hover{gap:.75rem;color:var(--brass)}

/* ── chips ──────────────────────────────────────────────── */
.chips{display:flex;flex-wrap:wrap;gap:.7rem}
.chips a{
  display:inline-block;text-decoration:none;padding:.78rem 1.3rem;border-radius:100px;
  background:var(--glass);border:1px solid var(--line);color:var(--text-70);
  font-size:var(--step--1);backdrop-filter:blur(10px);
  transition:border-color .2s,color .2s,background .2s,transform .2s;
}
.chips a:hover{border-color:var(--brass);color:var(--text);background:var(--brass-soft);transform:translateY(-2px)}

/* ── codes ──────────────────────────────────────────────── */
.codes-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,1rem + 4vw,4.5rem);align-items:start}
.codes-grid blockquote{
  margin:1.8rem 0;padding:1.2rem 1.5rem;border-left:2px solid var(--brass);
  background:var(--brass-soft);border-radius:0 var(--r) var(--r) 0;
  font-size:var(--step-0);color:var(--text);
}
.glass-table{
  background:var(--glass);backdrop-filter:blur(var(--blur));
  border:1px solid var(--line);border-radius:var(--r-lg);padding:1.6rem;
}
.table-cap{font-size:.7rem;letter-spacing:.24em;text-transform:uppercase;color:var(--text-45);margin-bottom:1.1rem}
.glass-table table{width:100%;border-collapse:collapse}
.glass-table th,.glass-table td{text-align:left;padding:.78rem .4rem;border-bottom:1px solid var(--line);font-size:var(--step--1)}
.glass-table tbody th{font-family:var(--display);font-size:1.1rem;color:var(--brass);width:4.5rem;font-weight:500}
.glass-table td{color:var(--text-70)}
.glass-table tr:last-child th,.glass-table tr:last-child td{border-bottom:0}
.table-note{margin:1rem 0 0;font-size:var(--step--1);color:var(--text-45)}

/* ── luxury neighborhoods ───────────────────────────────── */
/* These are not municipalities — Brickell and Star Island are neighborhoods — so they
   sit apart from the city columns rather than being passed off as cities. */
.hoods{margin-top:clamp(2.4rem,1.8rem + 2vw,3.6rem);padding-top:2rem;border-top:1px solid var(--line)}
.hoods .table-cap{margin-bottom:1.4rem}
/* Room between a group's pills and the next group's caption: at 1.5rem the caption read as a label
   for the row above it rather than the row below. */
.hood-group{margin-bottom:1.9rem}
.hood-group:last-child{margin-bottom:0}
/* h4 in the coverage list, where the section heading is h2 and the county is h3; h3 on a location
   page, where this is one level up. Same label either way — the level follows the outline, not
   the look. */
.hood-group h4,.hood-group h3{
  margin:0 0 .8rem;font-family:var(--sans);font-size:var(--step--1);font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--text-45);
}

/* One wide photograph under the intro of a location page. Margin, not padding, so the band's own
   bottom padding still ends the section — otherwise the picture sits on the seam. */
.place-photo{margin:clamp(2rem,1.4rem + 2vw,3.2rem) 0 0;border-radius:var(--r-lg,18px);overflow:hidden}
.place-photo img{display:block;width:100%;height:clamp(220px,28vw,420px);object-fit:cover}

/* ── breadcrumbs ────────────────────────────────────────── */
/* Sits above the h1 inside the first band, so it takes the band's top padding away from itself
   rather than adding to it — otherwise the page starts with two stacked empty regions. */
/* The header is fixed, so a band that starts with a breadcrumb has to clear it first: 108px is
   what scroll-padding-top already uses for the same reason. Trimmed from the band's usual padding
   rather than added to it, so the breadcrumb does not push the h1 down a whole extra band. */
/* Inside a hero the header clearance is already part of the layout; the trail just needs room
   under it before the kicker. */
.hero .crumbs{margin-bottom:1.1rem}
.crumbs{margin-bottom:clamp(1.4rem,1rem + 1.2vw,2.2rem)}
.crumbs ol{display:flex;flex-wrap:wrap;gap:.35rem .6rem;list-style:none;margin:0;padding:0}
.crumbs li{display:flex;align-items:center;gap:.6rem;font-size:var(--step--1);color:var(--text-45)}
.crumbs li+li::before{content:"/";color:var(--text-45);opacity:.5}
.crumbs a{color:var(--text-70);text-decoration:none}
.crumbs a:hover{color:var(--brass)}
.crumbs [aria-current]{color:var(--text-70)}
.hoodlist{display:flex;flex-wrap:wrap;gap:.5rem}
.hoodlist a{
  display:inline-block;padding:.45rem .9rem;border-radius:100px;
  border:1px solid var(--line-2);background:var(--glass);
  text-decoration:none;font-size:var(--step--1);color:var(--text-70);
  transition:color .2s,border-color .2s;
}
.hoodlist a:hover{color:var(--text);border-color:var(--brass)}

/* the decoder — three tiles, because a modern code is three numbers and almost
   nobody explains that. This is the block people will screenshot. */
.decoder{display:grid;grid-template-columns:repeat(3,1fr);gap:.7rem;margin-bottom:.4rem}
.dec-part{
  position:relative;overflow:hidden;
  background:var(--night-2);border:1px solid var(--line);border-radius:var(--r);
  padding:1.2rem 1.1rem 1.15rem;
}
.dec-part::before{
  content:"";position:absolute;inset:0 0 auto 0;height:2px;
  background:linear-gradient(90deg,var(--brass),transparent);
}
.dec-part b{
  display:block;font-family:var(--display);font-weight:300;line-height:1;
  font-size:clamp(2rem,1.5rem + 2vw,2.9rem);letter-spacing:-.04em;color:var(--brass);
}
.dec-part span{
  display:block;margin-top:.75rem;
  /* .7rem, the same as every other micro-label on the site. It was .62rem — 9.92px — which is the
     smallest type anywhere here, and it is not decoration: these three words are what the block
     exists to teach, that a modern code is family, zone and issue. There is room for them; the
     tiles are ~420px wide on a desktop and full width on a phone. */
  font-size:.7rem;letter-spacing:.24em;text-transform:uppercase;color:var(--text-45);
}
.dec-part em{display:block;margin-top:.2rem;font-style:normal;font-size:var(--step--1);color:var(--text)}

.fmt{display:flex;flex-direction:column;gap:.8rem}
.fmt li{display:flex;align-items:baseline;gap:1rem;font-size:var(--step--1);color:var(--text-70)}
.fmt code{flex:none;min-width:5.6rem;text-align:center;padding:.3em .5em}
.fmt em{font-style:normal;color:var(--text)}

.codes-foot{
  display:flex;align-items:center;justify-content:space-between;gap:var(--gap);flex-wrap:wrap;
  margin-top:clamp(2rem,1.4rem + 2vw,3rem);padding-top:1.8rem;border-top:1px solid var(--line);
}
.codes-foot p{margin:0;max-width:41rem;font-size:var(--step-0);color:var(--text-70)}
.codes-foot .btn{flex:none}
.codes-alt{
  margin:1.6rem 0 0;padding:1.1rem 1.4rem;
  background:var(--aqua-soft);border:1px solid var(--line);border-radius:var(--r);
  font-size:var(--step--1);color:var(--text-70);
}
.codes-alt a{color:var(--aqua);text-underline-offset:3px}

/* ── showcase: full-bleed photo + glass panel ───────────── */
.showcase{position:relative;padding-block:clamp(5rem,3.5rem + 6vw,9rem);overflow:hidden}
.showcase-media{position:absolute;inset:0;z-index:0}
.showcase-media img{width:100%;height:100%;object-fit:cover}
/* 🔴 The wash was a hard-coded near-black, rgba(11,13,16,…), while the layer under it faded into
   var(--night). On the ocean palette the two happen to agree; on any other they do not. A white
   palette put a black slab across the middle of a white page with a visible seam at each end, and
   a green or a plum one got a gray haze that belongs to no palette at all — which is exactly the
   defect the hero scrim had until it became a token. Same tint, same token. */
.showcase-media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,
               color-mix(in srgb,var(--scrim) 50%,transparent) 0 30%,
               color-mix(in srgb,var(--scrim) 82%,transparent) 100%),
             linear-gradient(to bottom,var(--night),transparent 18% 80%,var(--night));
}
.showcase-inner{position:relative;z-index:1;display:flex;justify-content:flex-end}
.glass-panel{
  background:var(--glass-strong);backdrop-filter:blur(var(--blur)) saturate(140%);
  border:1px solid var(--line-2);border-radius:var(--r-lg);
  padding:clamp(1.8rem,1.2rem + 2.4vw,3.2rem);
  box-shadow:0 40px 90px -40px rgba(0,0,0,.9),inset 0 1px 0 rgba(255,255,255,.08);
  max-width:640px;
}
.glass-panel h2{margin-bottom:1.6rem}
.facts{display:flex;flex-direction:column;gap:1rem;font-size:var(--step--1);color:var(--text-70)}
.facts li{padding-left:1.3rem;position:relative}
.facts li::before{content:"";position:absolute;left:0;top:.62em;width:7px;height:7px;border-radius:50%;background:var(--brass)}
.facts strong{color:var(--text);font-weight:600}

/* ── steps ──────────────────────────────────────────────── */
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:1.1rem}
.steps li{background:var(--night-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:1.7rem}
.step-n{display:block;font-family:var(--display);font-size:1.9rem;font-weight:300;color:var(--brass);margin-bottom:1rem;line-height:1}
.steps h3{margin-bottom:.5rem}
.steps p{font-size:var(--step-0);color:var(--text-70);margin:0}

/* ── cost ───────────────────────────────────────────────── */
.cost-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.1rem}
.cost{background:var(--night);border:1px solid var(--line);border-radius:var(--r-lg);padding:1.7rem;transition:border-color .25s}
.cost:hover{border-color:var(--line-2)}
.cost h3{font-family:var(--sans);font-size:var(--step-0);font-weight:600;margin-bottom:.5rem}
.cost .from{font-family:var(--display);font-size:var(--step-2);font-weight:500;color:var(--brass);margin:0 0 .55rem}
.cost p{font-size:var(--step-0);color:var(--text-70);margin:0}
.disclaimer{
  margin-top:1.6rem;padding:1.1rem 1.4rem;background:var(--brass-soft);
  border-radius:var(--r);font-size:var(--step--1);color:var(--text-70);border:1px solid color-mix(in srgb,var(--brass) 22%,transparent);
}

/* ── coverage ───────────────────────────────────────────── */
.coverage{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap)}
.county h3{padding-bottom:.9rem;border-bottom:1px solid var(--line-2);margin-bottom:1.1rem}
.county h3 a{color:inherit;text-decoration:none;transition:color .2s}
.county h3 a:hover{color:var(--brass)}
.citylist{columns:2;column-gap:1.4rem;font-size:var(--step--1)}
.citylist li{break-inside:avoid;margin-bottom:.5rem}
.citylist a{text-decoration:none;color:var(--text-70);transition:color .2s}
.citylist a:hover{color:var(--brass)}

/* The brief version, on every single before the call to action. Same three county columns as the
   homepage, one list each instead of two: six places reads as a note, twenty would be a second
   service-area page. */
.coverage-brief .citylist{columns:1}
.coverage-brief .county h3{font-size:var(--step-0);letter-spacing:.02em}
.coverage-brief .county h3 a{text-decoration:none;color:inherit}
.coverage-brief .county h3 a:hover{color:var(--brass)}
.coverage-brief .city-more a{color:var(--brass);opacity:.85}

/* coverage note */
.coverage-note{
  margin-top:2rem;padding-top:1.4rem;border-top:1px solid var(--line);
  font-size:var(--step--1);color:var(--text-70);max-width:78ch;
}
.coverage-note a{color:inherit;text-decoration:underline;text-underline-offset:3px}

/* ── cta ────────────────────────────────────────────────── */
/* 🔴 The bloom over this band was rgba(95,211,196,.14) — the ocean palette's own aqua, written as a
   literal. Every one of the other 24 palettes carried an ocean-teal glow across the band holding
   its call to action, under a heading in its own accent. */
.cta{padding-block:var(--band-y);background:
  radial-gradient(90% 130% at 50% 0%,color-mix(in srgb,var(--aqua) 14%,transparent),transparent 60%),var(--night-2)}
.cta-inner{display:flex;justify-content:center}
.cta-panel{max-width:820px;text-align:center}
.cta-panel .lede{color:var(--text-70);font-size:var(--step-1);margin-bottom:1.8rem}
.cta-actions{display:flex;flex-wrap:wrap;gap:.9rem;justify-content:center}
.evidence{margin-top:2.4rem;padding-top:1.6rem;border-top:1px solid var(--line)}
.evidence-title{font-size:.7rem;letter-spacing:.24em;text-transform:uppercase;color:var(--brass);margin-bottom:.9rem}
.evidence ul{display:flex;flex-wrap:wrap;gap:.5rem 1.2rem;font-size:var(--step--1);color:var(--text-45)}
.cta .evidence ul{justify-content:center}

/* ── faq ────────────────────────────────────────────────── */
.faq details{border:1px solid var(--line);border-radius:var(--r);margin-bottom:.7rem;background:var(--night-2);transition:border-color .2s}
.faq details[open]{border-color:var(--line-2)}
.faq summary{cursor:pointer;list-style:none;padding:1.2rem 3rem 1.2rem 1.4rem;position:relative;font-family:var(--display);font-weight:500;font-size:var(--step-0)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"";position:absolute;right:1.4rem;top:1.5rem;width:9px;height:9px;
  border-right:1.5px solid var(--brass);border-bottom:1.5px solid var(--brass);
  transform:rotate(45deg);transition:transform .24s;
}
.faq details[open] summary::after{transform:rotate(-135deg);top:1.7rem}
.faq p{color:var(--text-70);padding:0 1.4rem 1.3rem;margin:0;font-size:var(--step-0)}

/* ── footer ─────────────────────────────────────────────── */
.site-foot{background:var(--night-2);border-top:1px solid var(--line);padding-block:var(--band-y) 2rem}
.foot-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:var(--gap)}
.foot-note{margin-top:1.1rem;font-size:var(--step--1);color:var(--text-45);max-width:34ch}
.site-foot h3{font-family:var(--sans);font-size:.7rem;letter-spacing:.22em;text-transform:uppercase;color:var(--text-45);margin-bottom:1rem;font-weight:600}
.site-foot ul{display:flex;flex-direction:column;gap:.55rem;font-size:var(--step--1)}
/* The number sits above the contact menu rather than inside it: a tel: link stored as a menu item
   would keep whatever number it was given the day it was added. Same rhythm as a list row. */
.foot-call{margin:0 0 .55rem;font-size:var(--step--1)}
.site-foot a{text-decoration:none;color:var(--text-70)}
.site-foot a:hover{color:var(--brass)}
.legal{margin-top:3rem;padding-top:1.5rem;border-top:1px solid var(--line)}
.legal-links{display:flex;flex-wrap:wrap;gap:.7rem 1.6rem;margin-bottom:1.2rem}
.legal-links a{
  text-decoration:none;color:var(--text-70);font-size:.82rem;
  border-bottom:1px solid transparent;transition:color .2s,border-color .2s;
}
.legal-links a:hover{color:var(--brass);border-bottom-color:currentColor}
.legal p{font-size:.78rem;color:var(--text-45);max-width:84ch;margin:0}

.sticky-call{display:none}


/* ── long-form text ─────────────────────────────────────── */
/* The block at the foot of a landing page. Narrower than a full band on purpose: prose set to the
   full width of a 1440 viewport is unreadable, and this is the one section meant to be read
   straight through. */
.seo-text{position:relative;max-width:78ch}
.seo-text-body > :first-child{margin-top:0}
.seo-text-body h3{
  margin:2.2rem 0 .8rem;font-size:var(--step-1);letter-spacing:-.01em;
}
.seo-text-body h4{margin:1.6rem 0 .6rem;font-size:var(--step-0)}
.seo-text-body p{margin:0 0 1rem;color:var(--text-70);line-height:1.7}
/* The base stylesheet strips list markers site-wide, which is right for navigation and card
   bullets and wrong here: this is prose, and a list inside it has to look like a list. */
.seo-text-body ul{margin:0 0 1.2rem;padding-left:1.2rem;color:var(--text-70);list-style:disc}
.seo-text-body ol{margin:0 0 1.2rem;padding-left:1.3rem;color:var(--text-70);list-style:decimal}
.seo-text-body li{margin-bottom:.45rem;line-height:1.6}
.seo-text-body li::marker{color:var(--brass)}
.seo-text-body strong{color:var(--text)}
.seo-text-body a{color:var(--brass)}

/* Collapsed state is applied by the script, so a page with JavaScript off shows the whole block
   rather than a clipped one nobody can open. */
.seo-text.is-clipped .seo-text-body{max-height:22rem;overflow:hidden}
.seo-text-fade{display:none}
.seo-text.is-clipped .seo-text-fade{
  display:block;position:absolute;left:0;right:0;bottom:3.6rem;height:8rem;pointer-events:none;
  background:linear-gradient(to bottom,transparent,var(--night));
}
.band-light .seo-text.is-clipped .seo-text-fade{background:linear-gradient(to bottom,transparent,var(--sand))}
.seo-text-toggle{margin-top:1.4rem}
.seo-text.is-collapsible:not(.is-clipped):not(.is-open) .seo-text-toggle{margin-top:1.4rem}

/* On a wide screen the heading sat above 78ch of prose with the whole right half of the band
   empty, which read as a page that had run out of content. Two columns instead: the heading holds
   the left rail and travels with the reader, the article keeps its readable measure on the right.
   Below 1100px it collapses back to one column, which is what a phone wants anyway. */
/* The same emptiness, for the same reason, in two more places. "The short version" printed a
   display-size heading over four outlined boxes holding four words each, and "Most common calls"
   printed one over three bullets — both leaving the right half of a full-height band blank, which
   reads as a page that ran out of things to say. They take the rail treatment too, and the facts
   stop being boxes: a label and a value in a hairline row is a spec sheet, four bordered squares
   floating in a band are packaging. */
@media (min-width:1100px){
  /* One rail, five kinds of block beside it. It was written out three times, identically, because
     each block was given the treatment on a different day — so the next one to need it was going
     to be a fourth copy, and a change to the column width would have reached two of the four.

     🔴 Merging them showed that one of the three had never matched anything: `.chips` is printed
     inside `.shortcut`, never as a child of `.wrap`, so `:has(> .chips)` selected nothing on any
     of the 412 pages. Three copies is also three places for a selector to be quietly wrong in. */
  .wrap:has(> .seo-text),
  .wrap:has(> .code-facts),
  .wrap:has(> .steps-2),
  .wrap:has(> .mini-wide),
  .wrap:has(> .hoods-codes){
    display:grid;grid-template-columns:minmax(0,20rem) minmax(0,1fr);
    column-gap:clamp(2.5rem,4vw,5rem);align-items:start;
  }
  /* .seo-text is deliberately not here: its heading keeps the ordinary section spacing, because
     what sits beside it is prose rather than a panel. */
  .wrap:has(> .code-facts) > .sec-head,
  .wrap:has(> .steps-2) > .sec-head,
  .wrap:has(> .mini-wide) > .sec-head,
  .wrap:has(> .hoods-codes) > .sec-head{margin-bottom:0;text-align:left}
  .wrap:has(> .code-facts) > .sec-head h2,
  .wrap:has(> .steps-2) > .sec-head h2,
  .wrap:has(> .mini-wide) > .sec-head h2,
  .wrap:has(> .hoods-codes) > .sec-head h2{font-size:clamp(1.7rem,1.3rem + .8vw,2.3rem)}

  /* Four hairline rows on a black band left the section reading as a page with nothing on it, so
     the facts take the same glass panel the hero strip uses: two by two, one object with weight,
     rather than four lines floating in the dark. */
  .wrap:has(> .code-facts) > .code-facts{
    grid-template-columns:repeat(2,1fr);gap:0;max-width:none;
    background:var(--glass);backdrop-filter:blur(var(--blur));
    border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;
  }
  .wrap:has(> .code-facts) > .code-facts .code-fact{
    background:none;border:0;border-radius:0;padding:1.7rem 1.8rem;
    border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  }
  .wrap:has(> .code-facts) > .code-facts .code-fact:nth-child(2n){border-right:0}
  .wrap:has(> .code-facts) > .code-facts .code-fact:nth-last-child(-n+2){border-bottom:0}
  .wrap:has(> .code-facts) > .code-facts .table-cap{margin-bottom:.55rem}
  .band-light .wrap:has(> .code-facts) > .code-facts{background:var(--panel);border-color:var(--panel-line)}
  .band-light .wrap:has(> .code-facts) > .code-facts .code-fact{border-color:var(--panel-line)}

  /* Led panel: the figure holds the left of the glass, the qualifiers run down the right as rows.
     Three rows against one tall cell is what gives the panel a height worth the band it sits in —
     the even 2×2 was two rows tall and left a third of the section empty underneath. */
  .wrap:has(> .code-facts) > .code-facts-led{
    grid-template-columns:minmax(0,21rem) minmax(0,1fr);
  }
  .wrap:has(> .code-facts) > .code-facts-led > .fact-lead{
    padding:2.1rem 2.1rem 2.2rem;border-right:1px solid var(--line);
  }
  /* The rows share the panel's height with the figure beside them, so each one is taller than its
     own text. Centring the text in its row is what keeps the three evenly spaced instead of
     bunched at the top of three unequal boxes. */
  .wrap:has(> .code-facts) > .code-facts-led > .fact-rows{display:grid;gap:0;height:100%}
  .wrap:has(> .code-facts) > .code-facts-led .code-fact{
    border-right:0;display:flex;flex-direction:column;justify-content:center;
  }
  .wrap:has(> .code-facts) > .code-facts-led .code-fact:last-child{border-bottom:0}
  .code-facts-led .fact-figure{font-size:clamp(2.4rem,1.9rem + 1.6vw,3.4rem)}
  /* After the rule above, or "Priced after diagnosis" sets three words at 3.4rem and outshouts the
     price on every other service page. */
  .code-facts-led .fact-figure-plain{font-size:var(--step-1);line-height:1.2}
  .band-light .wrap:has(> .code-facts) > .code-facts-led > .fact-lead{border-color:var(--panel-line)}

  /* Four steps two by two inside the rail. Four in a row there gives each one about 170px, which
     is a column of broken words rather than a sentence. */
  .wrap:has(> .steps-2) > .steps-2{grid-template-columns:repeat(2,1fr)}
/* A cause card ends on the repair that answers it, with what that repair starts at. The link is
   pushed to the foot of the card so a row of them lines up however unevenly the text above runs.
   It reads as one line rather than as a two-column row: inline-flex put the name and the figure in
   separate columns, and a service name long enough to wrap then sat over two lines beside a price
   on one — which reads as a table nobody asked for. */
.steps li:has(> .step-fix){display:flex;flex-direction:column}
.step-fix{margin-top:auto;padding-top:1.1rem;display:block;line-height:1.5}
.step-from{color:var(--text-45);font-weight:400;white-space:nowrap}
.step-from::before{content:" — "}
.step-from span[aria-hidden]{color:var(--brass)}
  /* The unnumbered variant is a set, not a sequence, and it usually holds three — which in a
     two-column grid leaves the third alone beside a hole. Let it fit the count it actually has. */
  .wrap:has(> .steps-2) > .steps-plain{grid-template-columns:repeat(auto-fit,minmax(15rem,1fr))}

  /* The codes a generation can display are a dozen two-digit pills. Under a full-width heading
     they filled a third of one line and left the rest of a full-height band black. Beside the
     heading they are the width they need and the band is the height it earns. */
  /* Two rows beside the rail here — the pills and the link under them — so the heading spans both. */
  .wrap:has(> .hoods-codes) > .sec-head{grid-row:span 2}
  .wrap:has(> .hoods-codes) > .hoods-codes{margin-top:0;padding-top:0;border-top:0}
  .wrap:has(> .hoods-codes) > .codes-foot{grid-column:2;margin-top:1.6rem}
  /* Where the block follows a row of cards — the rest of the symptoms under the searched ones —
     it needs the gap the border used to give it. */
  .wrap:has(> .hoods-codes) > ul + .hoods-codes{margin-top:clamp(1.8rem,1.4rem + 1.4vw,2.8rem)}

  .wrap:has(> .mini-wide) > .mini-wide{max-width:64ch;gap:0}
  .wrap:has(> .mini-wide) > .mini-wide li{
    padding:.95rem 0 .95rem 1.4rem;border-top:1px solid var(--line);font-size:var(--step-0);color:var(--text-70);
  }
  .wrap:has(> .mini-wide) > .mini-wide li:last-child{border-bottom:1px solid var(--line)}
  .wrap:has(> .mini-wide) > .mini-wide li::before{top:1.5em}
  .band-light .wrap:has(> .mini-wide) > .mini-wide li{border-color:var(--ink-line)}

  .wrap:has(> .seo-text) > .sec-head{margin-bottom:0;position:sticky;top:6.5rem;text-align:left}
  /* The rail is narrower than a band, so the band-sized display face broke "Built-in" across three
     lines at the hyphen. Step it down rather than widen the rail and squeeze the prose. */
  .wrap:has(> .seo-text) > .sec-head h2{font-size:clamp(1.7rem,1.3rem + .8vw,2.3rem)}
  .wrap:has(> .seo-text) > .seo-text{max-width:70ch}
  .wrap:has(> .seo-text) > .evidence{grid-column:2;margin-top:2rem}
}

/* ── error code index ───────────────────────────────────── */
.code-search{
  display:flex;align-items:center;gap:.7rem;margin-bottom:1.4rem;
  background:var(--glass);border:1px solid var(--line-2);border-radius:100px;
  padding:.75rem 1.2rem;backdrop-filter:blur(10px);max-width:34rem;
}
.code-search svg{width:19px;height:19px;color:var(--brass);flex:none}
.code-search input{
  flex:1;background:none;border:0;outline:0;color:var(--text);
  font-family:var(--sans);font-size:var(--step-0);min-width:0;
}
.code-search input::placeholder{color:var(--text-45)}
.code-count{font-size:var(--step--1);color:var(--text-45);margin:-.6rem 0 1.1rem}
/* auto-fill rather than a fixed column count: 231 codes on a phone is one column, on a desktop it
   is four, and neither should need a media query to say so */
.code-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));gap:.6rem}
/* Every tile the same height, and each line clamped, so a code common to five product lines does
   not stretch the row it sits in. The grid is what makes 231 of these scannable at all. */
.code-list a{
  display:grid;grid-template-rows:auto 1fr auto;gap:.25rem;height:100%;min-height:6.4rem;
  padding:.85rem 1rem;border:1px solid var(--line);border-radius:var(--r);
  background:var(--night-2);text-decoration:none;
  transition:border-color .2s,transform .2s,background .2s;
}
.code-what,.code-series{
  display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;
}
.code-what{-webkit-line-clamp:2}
.code-series{-webkit-line-clamp:1}
.code-more{margin-top:1.6rem}
.code-list a:hover{border-color:var(--brass);transform:translateY(-2px);background:var(--night-3)}
.code-key{font-family:var(--display);font-size:var(--step-0);color:var(--brass);letter-spacing:.02em}
.code-what{font-size:var(--step--1);color:var(--text-70);line-height:1.4}
.code-series{font-size:.72rem;color:var(--text-45);letter-spacing:.02em}
.code-empty{margin-top:1.2rem;color:var(--text-70);max-width:60ch}
.band-light .code-list a{background:var(--panel);border-color:var(--panel-line)}
.band-light .code-key{color:var(--accent-light)}

/* The facts strip on an error code page: four short columns, because each one is a fact rather
   than a paragraph and stacking them would read as a form. */
.code-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));gap:1.4rem}
.code-fact{
  padding:1.2rem 1.3rem;border:1px solid var(--line);border-radius:var(--r);
  background:var(--night-2);
}
.code-fact p:last-child{margin:0;color:var(--text-70);font-size:var(--step--1);line-height:1.55}
.code-fact .code-key{font-size:var(--step-2);color:var(--brass)}
.band-light .code-fact{background:var(--panel);border-color:var(--panel-line)}

/* ── the led panel: one figure, then the qualifiers ───────────────────────────
   A price given the same weight as a warranty sentence is a price nobody sees. The lead fact gets
   display type at the size the section headings use, and the three that qualify it become hairline
   rows — a spec sheet under a headline, rather than four squares of equal importance.
   Mobile first: one column, the figure on top, the rows beneath it. */
/* No card around the lead on a phone, so no padding either: an indented figure sits half a
   centimeter to the right of the heading above it and reads as a mistake. The panel's own padding
   comes back with the panel, at the width where there is one. */
.fact-lead{padding:0 0 1.6rem}
.fact-figure{
  font-family:var(--display);font-size:var(--step-3);line-height:1;letter-spacing:-.02em;
  color:var(--brass);margin:.35rem 0 0;
}
/* "from" is a qualifier, not part of the number. Set at the figure's size it takes a line of its
   own and leaves the price stranded underneath — so it goes above it, at the size of a caption. */
.fact-from{
  display:block;font-family:var(--sans);font-size:var(--step--1);line-height:1.2;
  letter-spacing:.16em;text-transform:uppercase;color:var(--text-45);margin-bottom:.45rem;
}
/* Some jobs have no figure at all — "Priced after diagnosis". A sentence at 3.4rem is shouting. */
.fact-figure-plain{font-size:var(--step-1);line-height:1.2;color:var(--text);max-width:14ch}
.fact-caption{margin:.9rem 0 0;color:var(--text-70);font-size:var(--step--1);line-height:1.55;max-width:34ch}
.fact-cta{margin-top:1.5rem;display:flex;flex-wrap:wrap;align-items:center;gap:.75rem 1.1rem}
.fact-call{margin:0;font-size:var(--step--1);color:var(--text-70)}
.fact-call .tel-link{color:var(--text);white-space:nowrap}
/* 🔴 gap:0 here is a desktop value that leaked down. Above 1100px these rows live INSIDE the led
   panel, where they lose their radius and border and become hairline rows of a spec sheet — butting
   is the whole look, and the rule that does it sets its own gap:0 in that context. Below 1100px
   there is no panel: each row is still a rounded, bordered card, and three of them stacked with no
   gap meet at the corners and pinch. Same class of defect as the hero's buttons welded to the form.
   1.4rem matches .code-facts-led, so the cards keep one rhythm however they are grouped. */
.fact-rows{display:grid;gap:1.4rem}
.code-facts-led{display:grid;grid-template-columns:1fr;gap:1.4rem}
.code-facts-led .code-fact{padding:1.1rem 1.3rem}

/* ── the visit, in order ──────────────────────────────────────────────────────
   Three bullets under "what the work includes" was the thinnest band on the site, and it described
   a visit without describing its order — which is the only part of it that reassures anybody.

   It reuses `.steps`, the process strip the homepage already uses, rather than a second numbered
   list with its own classes: the twelve palettes each recolor `.step-n` by name, so a private
   copy would have rendered the base palette's teal on a black band. `.steps-2` is the only
   addition — the same component in two columns, because a single page's rail leaves it half the
   width the homepage gives it. */
.steps-2{grid-template-columns:repeat(2,1fr)}
/* A cause card ends on the repair that answers it, with what that repair starts at. The link is
   pushed to the foot of the card so a row of them lines up however unevenly the text above runs.
   It reads as one line rather than as a two-column row: inline-flex put the name and the figure in
   separate columns, and a service name long enough to wrap then sat over two lines beside a price
   on one — which reads as a table nobody asked for. */
.steps li:has(> .step-fix){display:flex;flex-direction:column}
.step-fix{margin-top:auto;padding-top:1.1rem;display:block;line-height:1.5}
.step-from{color:var(--text-45);font-weight:400;white-space:nowrap}
.step-from::before{content:" — "}
.step-from span[aria-hidden]{color:var(--brass)}

/* Search and the unit pills share a row on a desktop and stack on a phone, where a 34rem search
   box and four pills side by side would each get half of nothing. */
.code-controls{display:flex;flex-wrap:wrap;align-items:center;gap:1rem 1.4rem;margin-bottom:1.4rem}
.code-controls .code-search{margin-bottom:0;flex:1 1 22rem}
.code-pills{display:flex;flex-wrap:wrap;gap:.5rem}
.code-pill{
  display:inline-flex;align-items:center;gap:.5rem;
  padding:.55rem 1rem;border-radius:100px;text-decoration:none;
  border:1px solid var(--line-2);background:var(--glass);
  color:var(--text-70);font-size:var(--step--1);
  transition:color .2s,border-color .2s,background .2s;
}
.code-pill:hover{color:var(--text);border-color:var(--brass)}
.code-pill.is-active{color:var(--night);background:var(--brass);border-color:var(--brass);font-weight:600}
.code-pill-n{
  font-size:.72rem;letter-spacing:.02em;opacity:.75;
  padding:.05rem .45rem;border-radius:100px;background:rgba(255,255,255,.08);
}
.code-pill.is-active .code-pill-n{background:rgba(0,0,0,.14);opacity:.9}

/* A phone number inside prose. Underlined rather than only colored: in a paragraph, color alone
   is not enough to mark a link, and this is the link that matters most on the page. */
.tel-link{color:var(--brass);text-decoration:underline;text-underline-offset:.18em;white-space:nowrap}
.tel-link:hover{color:var(--text)}
.band-light .tel-link{color:var(--accent-light)}

/* ── the two shortcuts on a symptom page ────────────────── */
/* One section where there used to be two identical ones: a code names the subsystem, a model number
   says which parts to bring. Side by side they read as a choice; stacked they read as a repeat. */
/* align-items:start, not stretch. Where one panel holds a dozen codes and the other holds five
   model numbers, stretching the short one leaves a glass box half full of nothing — worse than two
   panels that are honestly different heights. */
.shortcuts{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.4rem,1rem + 2vw,2.6rem);align-items:start}
.shortcut{
  background:var(--glass);backdrop-filter:blur(var(--blur));
  border:1px solid var(--line);border-radius:var(--r-lg);padding:clamp(1.4rem,1rem + 1.4vw,2rem);
}
.band-light .shortcut{background:var(--panel);border-color:var(--panel-line)}
.shortcut .chips{margin-bottom:1.2rem}
/* A list that is a direct child of the panel — the models, which need no family headings — has no
   .hood-group margin under it, so its note sat against the last pill. */
.shortcut > .hoodlist{margin-bottom:1.2rem}
/* One panel, not two. Eight of the twelve symptom pages have no models attached, and a lone panel
   in a two-column grid is the same empty half this fleet keeps arriving at from new directions. */
.shortcuts-one{grid-template-columns:1fr}
.shortcut-note{margin:0;font-size:var(--step--1);color:var(--text-45);line-height:1.6}
.shortcut-note a{display:block;margin-top:.5rem;color:var(--brass);text-decoration:none}
.shortcut-note a:hover{text-decoration:underline;text-underline-offset:3px}

/* A code and what it names, on one row. As bare chips these were three strings of digits, and a
   reader matching the display against them had to open all three to find out which was theirs. */
/* Capped, because on a page with one panel the panel is the full band and a single code stretched
   across twelve hundred pixels reads as a rule with two words on it rather than as a row. */
.code-keys{list-style:none;margin:0 0 1.2rem;padding:0;display:grid;gap:.55rem;max-width:34rem}
.code-keys a{
  display:flex;align-items:baseline;gap:.9rem;text-decoration:none;
  padding:.7rem .9rem;border:1px solid var(--line);border-radius:var(--r);
  background:var(--night-2);transition:border-color .2s,background .2s,transform .2s;
}
.code-keys a:hover{border-color:var(--brass);background:var(--brass-soft);transform:translateY(-2px)}
.code-keys-n{font-family:var(--display);color:var(--brass);letter-spacing:.02em;white-space:nowrap}
.code-keys-m{color:var(--text-70);font-size:var(--step--1);line-height:1.4}
.band-light .code-keys a{background:var(--panel);border-color:var(--panel-line)}
@media (max-width:820px){.shortcuts{grid-template-columns:1fr}}

/* ── the booking embed, before it has anything to show ────────────────────────
   The form is a third-party single-page app: the iframe answers, then its script
   and stylesheet load, then it asks an API for its catalog, and only then does
   it paint. Until that happens the frame is empty — and we were painting it
   white, 840 pixels of it, in the middle of a black page. On a slow connection
   that white rectangle is what a visitor sees where the booking form should be.

   So the frame stays the color of the panel around it and says what it is
   doing, and the white arrives with the form rather than a second before it.

   --embed-min is the space held for the form before it paints, and it is the
   only reason this page's CLS is zero. It was 840 in three separate files,
   measured against the iframe; the script embed paints taller — 1047 at desk
   width, 925 at 390 — so the reservation is measured again here and kept in one
   place. A site whose provider hands it a different form overrides the variable
   from Theme Options rather than editing a stylesheet shared by 25 sites. */
.embed{position:relative;border-radius:var(--r);overflow:hidden;background:var(--night-2);min-height:var(--embed-min)}
.embed iframe{
  width:100%;min-height:var(--embed-min);border:0;display:block;border-radius:var(--r);
  background:transparent;opacity:0;transition:opacity .35s ease;
}
.embed.is-ready iframe{opacity:1;background:#fff}
/* Once the form is there it decides its own height. The reservation is a guess made before
   anything has rendered, and a guess that is 24px generous leaves a strip of panel color under
   a white card — which reads as a rendering error rather than as spare room. */
.embed.is-ready{min-height:0}

/* The standby form went in.
   🔴 It needs more height than the script embed, and the reason is worth knowing: the frame renders
   ProLeadService's own page, heading and all, and that heading is the one this site hides — it
   repeats the "Book a diagnostic visit" standing directly above it. Inside a frame there is nothing
   to hide it with, so the same three steps take about 200px more. Left at the 690 reserved for the
   script version, the form gets its own scrollbar inside the card, which is the shape of thing
   people do not scroll.
   An iframe on another origin cannot be measured from here, so a number is the honest answer, and
   it is generous rather than exact: too tall costs a strip of panel color, too short costs a
   scrollbar over the fields somebody is trying to fill in.
   The empty container the script never filled stays in the box but out of the way — hidden rather
   than removed, because the provider's script may still be running and looking for it by id. */
.embed.is-standby{min-height:var(--embed-standby)}
.embed.is-standby > div:empty{display:none}
.embed.is-standby iframe{min-height:var(--embed-standby);height:var(--embed-standby)}
.embed.is-standby.is-ready{min-height:0}
.embed-wait{
  position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.9rem;text-align:center;padding:2rem;color:var(--text-70);font-size:var(--step--1);
  transition:opacity .35s ease;
}
.embed.is-ready .embed-wait{opacity:0;pointer-events:none}
/* The form is late. The spinner goes — eight more seconds of it says nothing new — and a message
   with the phone number takes its place, inside the space still being held for the form.
   🔴 The reserved height is deliberately NOT dropped here. `is-ready` drops it because the form has
   arrived and sets its own height; doing that on a timer is exactly what collapsed the box to zero
   and left a heading above an empty rectangle. */
.embed.is-late .embed-wait{opacity:0;pointer-events:none}
.embed-late{
  position:absolute;inset:0;display:none;flex-direction:column;align-items:center;justify-content:center;
  gap:.7rem;text-align:center;padding:2rem;color:var(--text-70);font-size:var(--step--1);
}
.embed.is-late .embed-late{display:flex}
.embed.is-ready .embed-late{display:none}
.embed-late a{color:var(--brass);font-size:var(--step-1);font-weight:600;text-decoration:none}
.embed-late a:hover,.embed-late a:focus-visible{text-decoration:underline}
.embed-wait::before{
  content:"";width:26px;height:26px;border-radius:50%;
  border:2px solid var(--line-2);border-top-color:var(--brass);
  animation:embed-spin 900ms linear infinite;
}
@keyframes embed-spin{to{transform:rotate(360deg)}}

/* The booking form's own accent.
   As an iframe it was unreachable, and its blue step markers and links read as a foreign object on
   black and gold — an open question we were going to have to ask the provider about. The script
   embed paints into this page's DOM, so one variable settles it: the form ships a Tailwind palette
   and takes its accent from --color-blue-700.

   Not --brass. Gold on the form's white card measures 1.85:1, which fails the gate at any size.
   --accent-light is the palette's own accent chosen to read on a light ground — 5.68:1 for the
   pilot's bronze — which is exactly what this card is. Scoped to the embed so nothing else on the
   page inherits it.

   🔴 It was the literal #8A5E1D, which is the pilot's bronze and nobody else's: every other site
   in the fleet was going to carry a booking form in Sub-Zero's colors under its own heading. */
#schedule-appointment{
  --color-blue-700:var(--accent-light);
  --color-blue-600:var(--accent-light);
  --color-blue-500:var(--accent-light);
}

/* 🔴 And it has to be set on the calendar itself, not inherited from the embed.
   VCalendar declares the whole scale on its own container through a `.vc-blue` class, and a custom
   property set directly on an element beats one inherited from an ancestor whatever the specificity
   of the ancestor's rule. The first attempt put these on #schedule-appointment and the day stayed
   #2563eb — the variables were there, and the calendar was overwriting them on itself.

   A scale rather than one value: VCalendar uses the light end for the today-outline and for hover
   and the dark end for text on tinted ground, so setting them all to one color makes a day
   somebody is merely hovering look like the day they picked. Mixed from --accent-light towards
   white and towards black, which reproduces the hand-picked bronze scale this replaced to within a
   couple of levels — and gets the other 24 palettes right, which the bronze did not. */
#schedule-appointment .vc-container,
#schedule-appointment .vc-blue{
  --vc-accent-100:color-mix(in srgb,var(--accent-light) 12%,#fff);
  --vc-accent-200:color-mix(in srgb,var(--accent-light) 25%,#fff);
  --vc-accent-300:color-mix(in srgb,var(--accent-light) 45%,#fff);
  --vc-accent-400:color-mix(in srgb,var(--accent-light) 70%,#fff);
  --vc-accent-500:color-mix(in srgb,var(--accent-light) 88%,#fff);
  --vc-accent-600:var(--accent-light);
  --vc-accent-700:color-mix(in srgb,var(--accent-light) 80%,#000);
  --vc-accent-800:color-mix(in srgb,var(--accent-light) 64%,#000);
  --vc-accent-900:color-mix(in srgb,var(--accent-light) 46%,#000);
}

/* ── the form's own typography, which this theme was quietly wrecking ──────────
   🔴 The embed ships Tailwind, and Tailwind declares its utilities inside
   `@layer`. A rule outside any layer beats a layered rule no matter how specific
   the layered one is — so `h1{font-size:var(--step-4)}` in 01-base.css was
   overriding `.text-4xl` on the form's own heading. Measured: 78px where the
   provider asked for 36, in Sora, with our -0.032em tracking pulling the letters
   together. On a phone that heading ran three lines and took most of the screen
   before the first field.

   None of this is visible as a bug in either stylesheet on its own. It only
   exists because our CSS and theirs now share a document, which is the price of
   the script embed being reachable at all — the same reachability that let us
   set the accent above.

   So: give their headings a size of our choosing rather than ours by accident. */
#schedule-appointment :is(h1,h2,h3,h4){
  font-size:clamp(1.25rem,1.1rem + .5vw,1.5rem);
  line-height:1.25;letter-spacing:normal;margin:0;
}
#schedule-appointment p{margin:0}

/* The form's title says the same thing as the heading directly above it — "Book a
   diagnostic visit" in the hero panel, the section heading in the booking band.
   Two titles stacked read as two pages, and on a phone the second one cost a
   screenful before anything could be filled in. The line under it is kept: it
   tells you how long this will take, which our heading does not.

   Tied to the provider's markup, so if they restructure it stops applying and
   the title comes back — visible, not broken. */
#schedule-appointment header > p:first-child,
#schedule-appointment header > h1{display:none}
#schedule-appointment header{margin-bottom:1.4rem}

/* `min-h-screen` on their outer div: the form was always exactly one viewport
   tall, whatever it had to show. */
#schedule-appointment > div{min-height:0}
/* Their py-12/py-16 was set for a full-page form, not for a card inside a panel
   that already has its own padding. */
#schedule-appointment > div > div{padding-block:clamp(1.6rem,1.2rem + 1.5vw,2.2rem)}

/* The step strip — 1 SERVICE / 2 SCHEDULE / 3 CONTACT — is a flex row with `flex-1` on each step
   and a fixed gap, which needs about 400px. The hero panel is narrower than that between roughly
   1000 and 1240, where the hero is still two columns but the form's column is not yet wide: the
   third step overhung its own list by 7px on 22 pages. Letting the row wrap costs a line there and
   changes nothing at any other width. */
#schedule-appointment nav ol{flex-wrap:wrap;row-gap:.55rem}

/* The form is narrower on a phone and so is its reservation. */
@media (max-width:820px){:root{--embed-min:700px;--embed-standby:980px}}
@media (prefers-reduced-motion:reduce){.embed-wait::before{animation:none}}


/* ── hover, brought up to the house recipes ───────────────────────────────────
   Two of them exist already and are worth naming, because everything below just
   follows one or the other:

     a card   — transition on transform, translateY(-3px or -4px) on hover, and
                the border warming a step. .feature-card, .card and .type.
     a pill    — border to brass, text to full, background to brass-soft, and a
                2px lift. .chips a is the reference.

   The components below were built at different times and never got either, which
   is the whole reason a page can feel half-finished while every section on it is
   correct. prefers-reduced-motion already kills every transition on the site in
   05-responsive.css, so nothing here needs its own guard. */

/* The numbered/plain step cards: the process strip, the visit steps, the cost
   factors, the symptom causes, the model notes. Five sections, one component, and
   until now the only one of the card family that did not answer the pointer. */
.steps li{transition:transform .3s,border-color .3s,background .3s}
.steps li:hover{transform:translateY(-3px);border-color:var(--line-2);background:var(--night-3)}
.step-n{transition:color .3s,opacity .3s}
.steps li:hover .step-n{opacity:1}
/* The card lifts, so the link inside it should look like it is going somewhere —
   the same nudge .ghost-link gives on its own hover. */
.steps li:hover .ghost-link{gap:.75rem;color:var(--brass)}
.band-light .steps li:hover{background:var(--panel)}

/* A glass panel is not a link and must not pretend to be one, so it warms its
   border and stops there — enough to say "this is one object", not enough to
   promise a click. */
.shortcut{transition:border-color .3s}
.shortcut:hover{border-color:var(--line-2)}

/* The caption badge rides on the card's photograph; when the card lifts and the
   image scales, a badge that stays exactly as it was reads as pinned to the page
   rather than to the picture. */
.feature-card figcaption{transition:background .3s,border-color .3s}
.feature-card:hover figcaption{background:rgba(255,255,255,.24);border-color:rgba(255,255,255,.45)}

/* The icon tile inside an appliance type card. */

/* A pill that changes color but does not move was the odd one out among pills. */
.hoodlist a{transition:color .2s,border-color .2s,background .2s,transform .2s}
.hoodlist a:hover{background:var(--brass-soft);transform:translateY(-2px)}

/* The question is the control here — the whole summary is clickable and only the
   chevron ever acknowledged it. */
.faq summary{transition:color .2s}
.faq summary:hover{color:var(--brass)}
.faq summary::after{transition:transform .24s,border-color .2s}
.faq summary:hover::after{border-color:var(--text)}

/* Facts panel cells that carry a link — the generation on a code page, the series
   on a model page. The cell stays put; the link behaves like a link. */
.code-fact a{
  color:var(--text);text-decoration:none;
  border-bottom:1px solid var(--line-2);padding-bottom:1px;
  transition:color .2s,border-color .2s;
}
.code-fact a:hover{color:var(--brass);border-color:var(--brass)}

/* ── the one entrance animation on this site ──────────────────────────────────
   Cards rise a few pixels and fade in the first time their row reaches the
   viewport, staggered across the row. Deliberately small: this is a page about
   somebody's broken refrigerator, not a showreel, and an entrance that announces
   itself is an entrance that gets in the way the second time a visitor scrolls
   past it. It plays once and the element is left alone afterwards.

   The rules are gated behind html.js-reveal, which the script adds. Without
   JavaScript, or before the script runs, nothing is hidden — a reveal that starts
   from opacity:0 in the stylesheet is a page that stays blank when a script fails,
   and this fleet has shipped worse for less.

   Only opacity and transform, so nothing reflows and nothing moves the layout:
   the same reason the site measures CLS at 0.00 and should keep doing so.
   prefers-reduced-motion is handled globally in 05-responsive.css. */
.js-reveal .reveal{opacity:0;transform:translateY(12px)}
.js-reveal .reveal.is-in{
  opacity:1;transform:none;
  transition:opacity .5s cubic-bezier(.22,.61,.36,1),transform .5s cubic-bezier(.22,.61,.36,1);
}
