/* Breakara Demolition — Regional Hub
 * ============================================================================
 *
 * ADAPTED FROM THE TEMPLATE PACKAGE IN `template/`, AND FROM NOTHING ELSE.
 *
 *   REMOVALS — Transportation, Removals and Logistics v2.5, by Ansonika.
 *   Placed by the operator; identity recorded in data/template.json.
 *
 * The template is the visual source of truth. What is carried across is its
 * STRUCTURE and its COMPONENT VOCABULARY, section by section, with the class
 * names kept so the lineage stays legible to the next reader:
 *
 *   #top_line   thin bar above the header, tagline left, contact right
 *   header      white, logo left, uppercase 13px menu right, sticky w/ shadow
 *   #hero       full-bleed cover behind an opacity mask, statement + CTA
 *   #get_quote  saturated full-width strip, statement left, outlined btn right
 *   #feat_home  dark band of three rounded feature boxes over a centred close
 *   .svc-card   image with a 3px accent underline, h3, copy, "read more" link
 *   .bg_content 470px full-bleed band, huge uppercase h3 flanked by hairlines
 *   #sub_header 150px cover on inner pages, title on a 30% black plate,
 *               breadcrumb right, `//` before the h1
 *   9/3 split   main column beside a sidebar of box_style_1 / quote_banner /
 *               box_style_2
 *   footer      #222, three columns, icon-led contact list
 *   #copy       accent-ground centred copyright bar
 *
 * WHAT WAS DELIBERATELY CHANGED, AND WHY. Recorded here and in DESIGN-DNA.md.
 *
 *   1. Accent hue. The template's green (#83c99f fill, #629976 ink) is a
 *      removals brand. Breakara's wordmark is charcoal #343333 with yellow
 *      #f6bd19, and the logo is a fixed brand asset. The template's two-tone
 *      accent structure — a light hue for fills and bands, a darker one for
 *      text and rules — is kept exactly and re-pointed onto the brand pair.
 *      Yellow measures 1.74:1 on white, so it never carries text; the ochre
 *      ink does, at 5.8:1.
 *   2. Secondary hue. The template's purple band (#663466 / #603160) becomes
 *      the wordmark charcoal. Same role, same weight, brand ink.
 *   3. Base size. The template sets 14px/1.5 body — a 2015 measure. This sets
 *      16px/1.62 and keeps the template's heading absolutes, scaled ~1.1. The
 *      proportions are the template's; the reading size is current.
 *   4. Web fonts. The template loads Roboto and Gochi Hand from Google. This
 *      site's CSP is self-only and no licensed font file ships with the
 *      package, so Roboto is requested where it is installed and falls back to
 *      a neutral grotesque. The Gochi Hand script accent is not faked with a
 *      substitute cursive: those two headings take the template's OWN other
 *      treatment for a band heading — uppercase, bold, flanked by hairlines,
 *      as .bg_content and #how_to h4 already do inside the package.
 *   5. Icon fonts. ElegantIcons and Fontello are not redistributed. Every
 *      glyph role they filled is an inline SVG or a CSS mark authored here.
 *   6. Photography. The package's demo photographs are Pixabay/Unsplash and
 *      its documentation states they are not included and are demo-only. None
 *      ships. Every image on this site is original artwork in assets/img/.
 */

:root {
  /* brand, sampled from the wordmark */
  --ink: #343333;
  --yellow: #f6bd19;
  --yellow-dark: #dfa806;
  --yellow-soft: #fdf3d8;
  --yellow-line: #f7d97e;
  --ochre: #7a5f00;

  /* template neutrals, carried across unchanged */
  --body: #565a5c;
  --muted: #7b7f81;
  --panel: #f9f9f9;
  --panel-2: #fafafa;
  --rule: #e2e2e0;
  --rule-dash: #d8d8d6;
  --dark: #222;
  --dark-2: #3d3c3c;
  --white: #fff;

  --font: Roboto, "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --container: 1170px;
  --gutter: 15px;
  --section: 60px;
  --shadow: 0 2px 10px -2px rgba(0, 0, 0, .41);
  --shadow-soft: 0 0 5px 0 rgba(0, 0, 0, .1);
  --ease: all .25s ease;

  /* Hazard stripes stand in for the template's pattern_green.png tile: the same
     job — texture over a flat accent band — drawn rather than shipped. */
  --stripes: repeating-linear-gradient(135deg, rgba(0, 0, 0, .05) 0 14px, rgba(0, 0, 0, 0) 14px 28px);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.62;
  color: var(--body);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
svg { display: block; }

h1, h2, h3, h4, h5 {
  color: var(--ink);
  font-weight: 700;
  line-height: 1.2;
  margin: 0 0 .6em;
  text-wrap: balance;
}
h2 { font-size: 28px; }
h3 { font-size: 24px; }
h4 { font-size: 19px; }
h5 { font-size: 17px; }
p { margin: 0 0 25px; }
p:last-child { margin-bottom: 0; }
strong { color: var(--ink); font-weight: 700; }
hr { margin: 34px 0; border: 0; border-top: 1px dotted var(--rule-dash); }

a { color: var(--ochre); text-decoration: none; transition: var(--ease); }
a:hover { color: var(--ink); }
:focus-visible { outline: 3px solid var(--ochre); outline-offset: 2px; }

/* The template's `a.link_normal` — a read-more with a trailing arrow glyph.
   The glyph came from ElegantIcons; this draws it. */
.link_normal { font-weight: 500; display: inline-block; min-height: 30px; padding: 5px 0; }
.link_normal::after { content: " \2192"; }
.link_normal:hover { text-decoration: underline; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 var(--gutter); }
.margin_60 { padding-top: var(--section); padding-bottom: var(--section); }
.gray_bg { background: var(--panel-2); }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
/* A skip link that stays 1x1 when focused takes a tab stop and shows the reader nothing. */
.sr-only:focus, .sr-only:focus-visible {
  position: fixed; top: 12px; left: 12px; z-index: 200;
  width: auto; height: auto; overflow: visible; clip: auto; clip-path: none;
  background: var(--yellow); color: var(--ink); font-weight: 700;
  padding: 13px 20px; border-radius: 3px; min-height: 46px; line-height: 20px;
}

/* ── 1.2 Buttons ──────────────────────────────────────────────────────────
   btn_1 is the template's primary: accent fill, uppercase, bold, 3px radius,
   hover to #333. btn_quote is the outlined-on-a-band variant. btn_full is the
   block form used in a sidebar. */
.btn_1, .btn_quote, .btn_full {
  display: inline-block; border: 0; border-radius: 3px; cursor: pointer;
  font: inherit; font-weight: 700; text-transform: uppercase; letter-spacing: .02em;
  transition: var(--ease); text-align: center;
}
.btn_1 {
  background: var(--yellow); color: var(--ink);
  padding: 13px 26px; font-size: 15px; min-height: 46px; line-height: 20px;
}
.btn_1:hover { background: var(--ink); color: var(--white); }
.btn_1.small { padding: 10px 20px; font-size: 14px; min-height: 42px; }
.btn_quote {
  background: none; color: var(--ink); border: 2px solid var(--ink);
  padding: 11px 24px; font-size: 15px; min-height: 46px; line-height: 20px;
  white-space: nowrap;
}
.btn_quote:hover { background: var(--ink); color: var(--yellow); }
.btn_full {
  display: block; width: 100%; background: var(--ink); color: var(--white);
  padding: 15px 18px; font-size: 15px; min-height: 48px;
}
.btn_full:hover { background: var(--ochre); color: var(--white); }

/* On a dark ground the outline button is white, per the template. */
.on-dark .btn_quote { color: var(--white); border-color: rgba(255, 255, 255, .75); }
.on-dark .btn_quote:hover { background: var(--white); color: var(--ink); }
.on-dark :focus-visible { outline-color: var(--yellow); }

/* ── 1.3 Structure: top line + header ────────────────────────────────────── */
#top_line {
  font-size: 14px;
  border-bottom: 1px solid rgba(0, 0, 0, .1);
  background: var(--white);
  color: var(--muted);
}
#top_line .container {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  min-height: 40px; flex-wrap: wrap;
}
#tag_line { font-size: 14px; }
#top_links { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; }
#top_links li { padding-left: 12px; margin-left: 12px; border-left: 1px solid rgba(0, 0, 0, .1); }
#top_links li:first-child { border-left: 0; margin-left: 0; padding-left: 0; }
#top_links a, #top_links span {
  color: var(--ink); font-weight: 700;
  display: inline-block; padding: 6px 0; min-height: 28px; line-height: 16px;
}
#top_links a:hover { color: var(--ochre); }

header {
  position: sticky; top: 0; z-index: 60;
  background: var(--white);
  box-shadow: var(--shadow);
}
header .container {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  min-height: 84px;
}
#logo img { height: 46px; width: auto; }

.main-menu { display: flex; align-items: center; gap: 4px; }
.main-menu a {
  display: block; color: var(--ink); font-size: 13.5px; font-weight: 500;
  text-transform: uppercase; letter-spacing: .03em;
  padding: 10px 11px; border-bottom: 3px solid transparent; transition: var(--ease);
}
.main-menu a:hover { color: var(--ochre); }
.main-menu a[aria-current="page"] { color: var(--ochre); border-bottom-color: var(--yellow); }
.hdr-cta { display: flex; align-items: center; gap: 12px; }

/* Mobile menu — the template's off-canvas panel with its dark ground. */
.cmn-toggle-switch {
  display: none; background: var(--ink); color: var(--white); border: 0;
  font: inherit; font-weight: 700; font-size: 14px; text-transform: uppercase;
  padding: 12px 16px; border-radius: 3px; min-height: 46px; cursor: pointer;
}
.layer { position: fixed; inset: 0; background: rgba(0, 0, 0, .5); z-index: 90; }
#main_menu_mobile {
  position: fixed; inset: 0 0 0 auto; width: min(86vw, 340px); z-index: 95;
  background: var(--ink); color: var(--white);
  transform: translateX(100%); transition: transform .25s ease;
  padding: 20px; overflow-y: auto;
}
#main_menu_mobile[data-open="true"] { transform: none; }
#main_menu_mobile a {
  display: block; color: var(--white); font-weight: 500; text-transform: uppercase;
  font-size: 14px; letter-spacing: .03em;
  padding: 14px 0; border-bottom: 1px solid rgba(255, 255, 255, .12);
}
#main_menu_mobile a:hover { color: var(--yellow); }
#main_menu_mobile .close {
  background: none; border: 1px solid rgba(255, 255, 255, .35); color: var(--white);
  font: inherit; padding: 10px 15px; border-radius: 3px; min-height: 44px; cursor: pointer;
  margin-bottom: 12px;
}
#main_menu_mobile :focus-visible { outline-color: var(--yellow); }

/* ── 2.1 Home: hero ───────────────────────────────────────────────────────
   The template's carousel slide: a cover photograph, an opacity mask over it,
   and the statement column inside the container. One still frame here — this
   site has no photography and a single considered statement beats a rotator
   that moves copy out from under the reader. */
#hero { position: relative; background: var(--ink); color: var(--white); overflow: hidden; }
#hero > picture { position: absolute; inset: 0; }
#hero > picture img { width: 100%; height: 100%; object-fit: cover; }
#hero .opacity-mask { position: relative; }
#hero .opacity-mask {
  background: linear-gradient(100deg, rgba(16, 16, 16, .92) 0%, rgba(16, 16, 16, .78) 46%, rgba(16, 16, 16, .40) 100%);
  padding: clamp(56px, 8vw, 104px) 0;
}
#hero .slide-text { max-width: 720px; }
#hero .kicker {
  display: inline-block; margin: 0 0 18px;
  color: var(--ink); background: var(--yellow);
  font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .12em;
  padding: 7px 13px; border-radius: 3px;
}
#hero h1 {
  color: var(--white); font-size: clamp(32px, 5vw, 52px); font-weight: 700;
  text-transform: uppercase; letter-spacing: -.01em; margin-bottom: .35em;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .35);
}
#hero .slide-subtitle {
  font-size: clamp(17px, 2.1vw, 20px); color: #e6e6e4; max-width: 60ch; margin-bottom: 30px;
}
#hero .slide-cta { display: flex; flex-wrap: wrap; gap: 14px; }

/* The hero's own routing strip: the three boroughs, sitting under the statement
   as service-area navigation rather than as the page's subject. */
.hero-areas {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 22px;
  margin-top: 34px; padding-top: 22px; border-top: 1px solid rgba(255, 255, 255, .22);
  font-size: 15px;
}
.hero-areas .label { color: #cfcfcd; text-transform: uppercase; letter-spacing: .08em; font-size: 13px; font-weight: 700; }
.hero-areas ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px 20px; }
.hero-areas a, .hero-areas span {
  display: inline-block; color: var(--white); font-weight: 500;
  padding: 6px 0; min-height: 28px;
}
.hero-areas a:hover { color: var(--yellow); }
.hero-areas a::after { content: " \203A"; color: var(--yellow); font-weight: 700; }
.hero-areas span { color: #b9b9b7; }

/* ── 2.1 Home: the accent strip under the hero ───────────────────────────── */
#get_quote {
  background-color: var(--yellow); background-image: var(--stripes);
  color: var(--ink); padding: 30px 0;
}
#get_quote .container {
  display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap;
}
#get_quote h2 { margin: 0; font-size: clamp(20px, 2.4vw, 26px); max-width: 46ch; }
#get_quote p { margin: 6px 0 0; font-weight: 500; }

/* ── 2.1 Home: the dark feature band ─────────────────────────────────────── */
#feat_home { background: var(--ink); color: #dededc; }
#feat_home h2, #feat_home h3 { color: var(--white); }
#feat_home > .container > h2 {
  text-align: center; text-transform: uppercase; font-size: clamp(24px, 3vw, 34px);
  margin-bottom: 10px;
}
#feat_home .band-lead { text-align: center; font-size: 18px; max-width: 68ch; margin: 0 auto 40px; }
.feat-grid { display: grid; gap: 24px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.box_feat {
  background: var(--dark-2); border-radius: 10px; padding: 30px 26px; text-align: center;
  border-top: 4px solid var(--yellow);
}
.box_feat img, .box_feat svg { margin: 0 auto 18px; height: 72px; width: auto; }
.box_feat h3 { font-size: 19px; text-transform: uppercase; letter-spacing: .04em; color: var(--yellow); }
.box_feat h3::before, .box_feat h3::after { content: "/"; color: rgba(255, 255, 255, .45); }
.box_feat h3::before { margin-right: 9px; }
.box_feat h3::after { margin-left: 9px; }
/* The template centres this whole box, on copy two lines long. At four to six lines a centred
   paragraph reads as ragged on both edges, so the heading stays centred and the prose does not. */
.box_feat p { font-size: 15.5px; margin: 0; text-align: left; }
.band-close { text-align: center; margin-top: 44px; }
.band-close h3 {
  text-transform: uppercase; font-size: clamp(20px, 2.6vw, 28px); margin-bottom: 14px;
}
.band-close h3::before, .band-close h3::after {
  display: inline-block; width: 40px; height: 1px; content: ""; vertical-align: middle;
  background: rgba(255, 255, 255, .45);
}
.band-close h3::before { margin-right: 14px; }
.band-close h3::after { margin-left: 14px; }

/* ── 2.1 Home: the image-card row ─────────────────────────────────────────
   The template's three-up: image with a 3px accent underline, h3, copy, and a
   read-more. Four services here, so the row carries four. */
.section-head { max-width: 68ch; margin-bottom: 38px; }
.section-head.centred { margin-left: auto; margin-right: auto; text-align: center; }
.section-head h2 { text-transform: uppercase; font-size: clamp(24px, 3vw, 32px); }
.section-head p { font-size: 18px; margin-bottom: 0; }

.svc-grid { display: grid; gap: 30px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.svc-grid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.svc-card picture, .card picture, .split picture { display: block; }
.svc-card img, img.border {
  border-bottom: 3px solid var(--yellow);
  width: 100%; background: var(--panel);
}
/* Cards in a row have copy of different lengths. Without this the read-more of each card sits
   at a different height and the row looks unfinished rather than varied. */
.svc-card { display: flex; flex-direction: column; }
.svc-card .link_normal { margin-top: auto; }
.svc-card h3 { font-size: 20px; margin: 18px 0 .5em; }
.svc-card h3 a { color: var(--ink); }
.svc-card h3 a:hover { color: var(--ochre); }
.svc-card p { font-size: 15.5px; margin-bottom: 10px; }

/* ── 2.1 Home: three text columns ─────────────────────────────────────────── */
.col-3-text { display: grid; gap: 40px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.col-3-text h3 { font-size: 21px; }
.col-3-text p { font-size: 15.5px; }

/* ── The full-bleed band ─────────────────────────────────────────────────── */
.bg_content {
  min-height: 460px; display: flex; align-items: center; text-align: center;
  background: var(--ink) url("/assets/img/photo/band-clear-1280.jpg") no-repeat center center;
  background-image: image-set(url("/assets/img/photo/band-clear-1280.webp") type("image/webp"),
                              url("/assets/img/photo/band-clear-1280.jpg") type("image/jpeg"));
  background-size: cover;
  color: var(--white);
}
.bg_content .plate {
  width: 100%; padding: 70px 6%;
  background: linear-gradient(180deg, rgba(16, 16, 16, .58), rgba(16, 16, 16, .78));
}
.bg_content h2 {
  color: var(--white); font-size: clamp(26px, 4.4vw, 46px);
  text-transform: uppercase; margin-bottom: 18px;
}
.bg_content h2::before, .bg_content h2::after {
  display: inline-block; width: 50px; height: 1px; content: ""; vertical-align: middle;
  background: rgba(255, 255, 255, .5);
}
.bg_content h2::before { margin-right: 16px; }
.bg_content h2::after { margin-left: 16px; }
.bg_content p { font-size: 18px; max-width: 70ch; margin: 0 auto 26px; color: #e8e8e6; }

/* ── Inner pages: the sub header ─────────────────────────────────────────── */
#sub_header {
  background: var(--ink) url("/assets/img/photo/band-subheader-1280.jpg") no-repeat center center;
  background-image: image-set(url("/assets/img/photo/band-subheader-1280.webp") type("image/webp"),
                              url("/assets/img/photo/band-subheader-1280.jpg") type("image/jpeg"));
  background-size: cover;
  color: var(--white);
  padding: 46px 0 40px;
}
#sub_header .container { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; }
.main_title { background: rgba(0, 0, 0, .58); padding: 18px 20px; max-width: 760px; }
.main_title h1 {
  color: var(--white); font-size: clamp(24px, 3.4vw, 34px); margin: 0 0 8px;
  text-transform: uppercase;
}
.main_title h1::before { content: "// "; color: var(--yellow); }
.main_title p { margin: 0; font-size: 16px; color: #e6e6e4; }
/* Over a photograph the breadcrumb can land on a bright window or a pale wall, where a
   text-shadow alone is not enough. It takes the same plate the title does. */
#position {
  font-size: 14px; color: #e8e8e6; align-self: flex-end;
  background: rgba(0, 0, 0, .5); padding: 7px 12px; border-radius: 2px;
}
#position ol { list-style: none; margin: 0; padding: 0; display: flex; gap: 8px; flex-wrap: wrap; }
#position li + li::before { content: "\203A"; margin-right: 8px; color: rgba(255, 255, 255, .55); }
#position a { color: var(--white); display: inline-block; padding: 5px 0; min-height: 26px; }
#position a:hover { color: var(--yellow); }
#sub_header :focus-visible { outline-color: var(--yellow); }

/* ── Inner pages: 9/3 content split ─────────────────────────────────────── */
.content-grid { display: grid; gap: 40px; grid-template-columns: minmax(0, 8fr) minmax(0, 3.4fr); align-items: start; }
/* With no rail beside it, a 74ch measure left in a 1170px container fills half the width and
   strands the rest as void — which is what the privacy notice and everything after a full-width
   band looked like. Without a rail the column centres. */
.content-grid.no-side { grid-template-columns: minmax(0, 1fr); }
.content-grid.no-side .main-col { max-width: 82ch; margin: 0 auto; }
.main-col > section + section { margin-top: 44px; }
.main-col h2 { font-size: clamp(23px, 2.6vw, 28px); }
.main-col h3 { font-size: 21px; }
.main-col > section > p, .main-col > section > ul { max-width: 74ch; }

.side-col { position: sticky; top: 104px; }

/* ── Sidebar boxes, straight from the template ──────────────────────────── */
.box_style_1 { background: var(--panel); padding: 20px; margin-bottom: 24px; border: 1px solid var(--rule); }
.box_style_1 h3 {
  background: var(--ink); color: var(--white); text-align: center;
  padding: 15px 12px; text-transform: uppercase; font-size: 17px; letter-spacing: .04em;
  margin: -20px -20px 20px; border-bottom: 3px solid var(--yellow);
}
.box_style_1 h5 { margin-bottom: .4em; }
.box_style_1 p { font-size: 15px; margin-bottom: 0; }
.box_style_1 hr { margin: 18px 0; }

#cat_nav { list-style: none; margin: 0; padding: 0; font-weight: 500; }
#cat_nav li a {
  display: block; position: relative; background: var(--white); color: var(--ink);
  box-shadow: var(--shadow-soft); padding: 13px 34px 13px 13px; margin-bottom: 8px;
  min-height: 46px; font-size: 15.5px;
}
#cat_nav li a::after {
  content: "\203A"; position: absolute; right: 13px; top: 50%; transform: translateY(-50%);
  font-size: 20px; color: var(--ochre);
}
#cat_nav li a:hover { color: var(--ochre); }
#cat_nav li a[aria-current="page"] { background: var(--yellow); color: var(--ink); font-weight: 700; }
#cat_nav li a[aria-current="page"]::after { color: var(--ink); }
#cat_nav li:last-child a { margin-bottom: 0; }

.quote_banner { margin-bottom: 24px; }
.quote_banner a {
  display: block; background: var(--ink); color: var(--white);
  padding: 20px 18px; font-size: 17px; font-weight: 700; text-transform: uppercase;
  border-left: 5px solid var(--yellow); min-height: 62px;
}
.quote_banner a small { display: block; font-size: 13.5px; font-weight: 500; text-transform: none; color: #cfcfcd; margin-top: 4px; }
.quote_banner a:hover { background: var(--ochre); color: var(--white); }

.box_style_2 { border: 1px dashed var(--rule-dash); padding: 20px 22px; margin-bottom: 24px; }
.box_style_2 h4 { margin: 0 0 16px; font-size: 18px; }
.box_style_2 h5 { font-size: 16px; margin-bottom: .4em; }
.box_style_2 ul { padding-left: 20px; margin: 0 0 16px; }
.box_style_2 ul li { margin-bottom: 9px; font-size: 15px; }
.box_style_2 > :last-child { margin-bottom: 0; }

.box_style_3 {
  background-color: var(--ink); background-image: var(--stripes);
  color: #dededc; padding: 26px 24px; margin-bottom: 24px;
}
.box_style_3 h4 { color: var(--white); text-transform: uppercase; font-size: 17px; text-align: center; }
.box_style_3 h4::before, .box_style_3 h4::after {
  display: inline-block; width: 20px; height: 1px; content: ""; vertical-align: middle;
  background: rgba(255, 255, 255, .5);
}
.box_style_3 h4::before { margin-right: 10px; }
.box_style_3 h4::after { margin-left: 10px; }
.box_style_3 ul { list-style: none; margin: 0; padding: 0; }
.box_style_3 li { border-bottom: 1px dotted rgba(255, 255, 255, .22); }
.box_style_3 li:last-child { border-bottom: 0; }
.box_style_3 a, .box_style_3 li > span {
  display: block; color: var(--white); font-weight: 500; padding: 12px 0; min-height: 46px;
}
.box_style_3 a::after { content: " \203A"; color: var(--yellow); font-weight: 700; }
.box_style_3 a:hover { color: var(--yellow); }
.box_style_3 li > span { color: #b9b9b7; }
.box_style_3 p { font-size: 14.5px; margin: 14px 0 0; }
.box_style_3 :focus-visible { outline-color: var(--yellow); }

/* ── Content components ─────────────────────────────────────────────────── */

/* The template's icon-led feature list: the glyph is absolutely placed and the
   text is indented past it. */
ul.feat { list-style: none; margin: 0 0 20px; padding: 0; display: grid; gap: 26px; }
ul.feat.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
ul.feat li { position: relative; padding-left: 66px; }
ul.feat li img, ul.feat li svg { position: absolute; left: 0; top: 2px; width: 48px; height: 48px; }
ul.feat li h4 { margin-bottom: .35em; font-size: 17.5px; }
ul.feat li p { font-size: 15.5px; margin-bottom: 0; }

/* The template's about-page variant: the same list on a tinted, bordered plate. */
ul.feat.about { gap: 20px; }
ul.feat.about li {
  border: 1px solid var(--yellow-line); background: var(--yellow-soft);
  padding: 20px 22px 20px 88px;
}
ul.feat.about li img, ul.feat.about li svg { left: 22px; top: 20px; }
ul.feat.about li h4 { color: var(--ochre); }

ul.list_ok, ul.list_2 { list-style: none; margin: 0 0 22px; padding: 0; }
ul.list_ok li, ul.list_2 li { position: relative; padding-left: 27px; margin-bottom: 9px; }
ul.list_ok li::before {
  content: ""; position: absolute; left: 0; top: .44em;
  width: 15px; height: 9px; border-left: 3px solid var(--ochre); border-bottom: 3px solid var(--ochre);
  transform: rotate(-45deg);
}
ul.list_2 li::before {
  content: ""; position: absolute; left: 2px; top: .5em;
  width: 8px; height: 8px; background: var(--yellow); border: 2px solid var(--ochre);
}
.prose ul { padding-left: 22px; margin: 0 0 25px; }
.prose li { margin-bottom: 9px; }

/* Split block: authored artwork beside prose. The prose takes the larger share — an even
   split inside the 8/3 main column left both halves about thirty characters wide, which reads
   as two narrow columns rather than as text with a picture beside it. */
.split { display: grid; gap: 34px; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: center; }
.split--figleft { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.split figure { margin: 0; }
.split figcaption { font-size: 14px; color: var(--muted); margin-top: 8px; }

/* Card grid used for boroughs and for related services. */
.cards { display: grid; gap: 30px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.card { border: 1px solid var(--rule); background: var(--white); display: flex; flex-direction: column; }
.card img { width: 100%; border-bottom: 3px solid var(--yellow); }
.card .card-body { padding: 22px; display: flex; flex-direction: column; flex: 1; }
.card h3 { font-size: 20px; margin-bottom: .45em; }
.card p { font-size: 15.5px; }
.card .card-foot { margin-top: auto; padding-top: 12px; }
.card .pending { font-size: 14.5px; color: var(--muted); margin: 0; }

/* Numbered process steps — the template's list_order, as a row. */
.steps { display: grid; gap: 28px; grid-template-columns: repeat(4, minmax(0, 1fr)); list-style: none; margin: 0; padding: 0; }
.steps li { position: relative; padding-top: 4px; }
.steps .n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--yellow); color: var(--ink); font-weight: 700; font-size: 19px;
  margin-bottom: 14px;
}
.steps h3 { font-size: 18px; margin-bottom: .4em; }
.steps p { font-size: 15.5px; margin: 0; }

/* Sequence: a dependency chain with an owner per step. Numbered like the template's
   list_order, but each link also carries who drives it, and a connector shows that the
   order is not a preference. Counter-driven so the markup stays a plain <ol>. */
.sequence { list-style: none; counter-reset: seq; margin: 0 0 25px; padding: 0; display: grid; gap: 0; }
.sequence li {
  counter-increment: seq; position: relative;
  padding: 0 0 26px 62px; border-left: 2px solid var(--rule); margin-left: 21px;
}
.sequence li:last-child { border-left-color: transparent; padding-bottom: 0; }
.sequence .seq-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.sequence .seq-n {
  position: absolute; left: -22px; top: -2px;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--yellow); color: var(--ink);
  font-weight: 700; font-size: 18px; line-height: 42px; text-align: center;
}
.sequence .seq-n::before { content: counter(seq); }
.sequence li:last-child .seq-n { background: var(--ink); color: var(--yellow); }
.sequence h3 { font-size: 19px; margin: 0; }
.sequence .seq-owner { margin: 0 0 8px; }
.sequence .seq-owner span {
  display: inline-block; background: var(--panel); border: 1px solid var(--rule);
  border-radius: 2px; padding: 3px 10px; font-size: 13.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: var(--ochre);
}
.sequence li > p:last-child { font-size: 15.5px; margin: 0; max-width: 62ch; }
@media (max-width: 620px) {
  .sequence li { padding-left: 46px; margin-left: 18px; }
  .sequence .seq-n { width: 36px; height: 36px; line-height: 36px; font-size: 16px; left: -19px; }
}

/* Tables, per the template's striped table. */
.table-wrap { overflow-x: auto; margin-bottom: 25px; }
table { border-collapse: collapse; width: 100%; font-size: 15.5px; min-width: 520px; }
caption { text-align: left; font-size: 14.5px; color: var(--muted); padding-bottom: 10px; }
th, td { text-align: left; padding: 13px 15px; border-bottom: 1px solid var(--rule); vertical-align: top; }
thead th { background: var(--ink); color: var(--white); font-weight: 700; border-bottom: 0; }
tbody tr:nth-child(odd) { background: var(--panel); }

/* FAQ, built on <details> so it needs no script. */
.faq { border-top: 1px solid var(--rule); }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  list-style: none; cursor: pointer; padding: 18px 40px 18px 0; position: relative;
  font-weight: 700; color: var(--ink); font-size: 17.5px; min-height: 56px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  font-size: 26px; font-weight: 400; color: var(--ochre); line-height: 1;
}
.faq details[open] summary::after { content: "\2013"; }
.faq summary:hover { color: var(--ochre); }
.faq .answer { padding: 0 0 20px; max-width: 74ch; }
.faq .answer > :last-child { margin-bottom: 0; }

/* A pull-quote-weight callout for a regulatory point. */
.note {
  border-left: 5px solid var(--yellow); background: var(--panel);
  padding: 20px 24px; margin: 0 0 25px; max-width: 74ch;
}
.note p:last-child { margin-bottom: 0; }
.note strong { display: block; margin-bottom: 6px; text-transform: uppercase; font-size: 14px; letter-spacing: .05em; }

/* ── Footer ─────────────────────────────────────────────────────────────── */
footer { background: var(--dark); color: #c6c6c4; padding: 56px 0 24px; font-size: 15.5px; }
footer h3 { color: var(--white); font-size: 18px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; }
footer a { color: #dcdcda; }
footer a:hover { color: var(--yellow); }
footer ul { list-style: none; margin: 0; padding: 0; }
footer li a, footer li > span { display: inline-block; padding: 6px 0; min-height: 28px; }
.footer-grid { display: grid; gap: 40px; grid-template-columns: 3.4fr 2.2fr 2.2fr 3.2fr; }
.footer-brand img { height: 46px; width: auto; margin-bottom: 18px; }
.footer-brand p { font-size: 15.5px; }
#contact_details_footer li { position: relative; padding-left: 32px; margin-bottom: 14px; }
#contact_details_footer li::before {
  content: ""; position: absolute; left: 0; top: 7px; width: 20px; height: 20px;
  background: var(--yellow); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain; mask-size: contain;
}
#contact_details_footer li.phone::before {
  -webkit-mask-image: url("/assets/img/icon-phone.svg"); mask-image: url("/assets/img/icon-phone.svg");
}
#contact_details_footer li.area::before {
  -webkit-mask-image: url("/assets/img/icon-pin.svg"); mask-image: url("/assets/img/icon-pin.svg");
}
#contact_details_footer li.hours::before {
  -webkit-mask-image: url("/assets/img/icon-clock.svg"); mask-image: url("/assets/img/icon-clock.svg");
}
/* The number is a dialling target, not prose. In a narrow footer column it was breaking after
   the area code, which makes it read as two things. */
#contact_details_footer .phone a { font-size: 20px; font-weight: 700; color: var(--white); white-space: nowrap; }
#contact_details_footer .phone a:hover { color: var(--yellow); }

#copy {
  background-color: var(--yellow); background-image: var(--stripes);
  color: var(--ink); font-size: 14px; padding: 14px 0;
}
#copy .container { display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
#copy a { color: var(--ink); font-weight: 500; display: inline-block; padding: 4px 0; min-height: 26px; }
#copy :focus-visible { outline-color: var(--ink); }

/* ── Sticky mobile call bar ─────────────────────────────────────────────── */
#call_bar { display: none; }

/* ── Responsive ─────────────────────────────────────────────────────────── */
@media (max-width: 1100px) {
  .main-menu a { padding: 10px 8px; font-size: 13px; }
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 991px) {
  :root { --section: 42px; }
  .main-menu { display: none; }
  .cmn-toggle-switch { display: inline-block; }
  header .container { min-height: 72px; }
  #logo img { height: 40px; }

  .svc-grid, .svc-grid.three, .cards, .feat-grid, .col-3-text, .steps,
  ul.feat.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .content-grid { grid-template-columns: minmax(0, 1fr); }
  .side-col { position: static; }
  .split, .split.wide-text { grid-template-columns: minmax(0, 1fr); }
  #sub_header .container { display: block; }
  #position { margin-top: 16px; }
  .main_title { max-width: none; }
}

@media (max-width: 767px) {
  #top_line { display: none; }
  .bg_content { min-height: 340px; }
  .bg_content .plate { padding: 48px 6%; }
  /* The template drops these hairlines on a narrow screen, where a two-line heading breaks
     between them and leaves a rule stranded mid-phrase. Same rule, same reason, here. */
  .bg_content h2::before, .bg_content h2::after,
  .band-close h3::before, .band-close h3::after { display: none; }
  #get_quote .container { display: block; }
  #get_quote .btn_quote { margin-top: 18px; }
}

@media (max-width: 520px) {
  /* Two footer columns at this width leave the contact details about 150px wide, which is
     narrower than the phone number they carry. */
  .footer-grid { grid-template-columns: minmax(0, 1fr); gap: 30px; }
}

@media (max-width: 620px) {
  /* Below this the header cannot hold the logo, the call button and the menu toggle at once, so
     the call moves to the sticky bar. The bar measures 62px at every width from 320 up — 19px
     padding around a 24px line — so the body clears 70px and content never ends underneath it. */
  .hdr-cta .btn_1 { display: none; }
  body { padding-bottom: 70px; }
  #call_bar {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 80;
    background: var(--yellow); box-shadow: 0 -2px 10px -2px rgba(0, 0, 0, .4);
  }
  #call_bar a {
    flex: 1; text-align: center; padding: 19px 12px; min-height: 62px; line-height: 24px;
    color: var(--ink); font-weight: 700; font-size: 17px; text-transform: uppercase;
  }
  #call_bar :focus-visible { outline-color: var(--ink); outline-offset: -3px; }

  .svc-grid, .svc-grid.three, .cards, .feat-grid, .col-3-text, .steps,
  ul.feat.two { grid-template-columns: minmax(0, 1fr); }
  #hero .slide-cta { display: grid; }
  #hero .slide-cta > * { text-align: center; }
  .box_style_1 { padding: 16px; }
  .box_style_1 h3 { margin: -16px -16px 16px; }
}

@media (min-width: 992px) {
  /* A breakpoint-scoped control has to leave the tab order and the a11y tree,
     not merely the viewport. */
  #main_menu_mobile, .layer, .cmn-toggle-switch { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
}

@media print {
  header, #top_line, #call_bar, .side-col, #get_quote { display: none; }
}

/* ==========================================================================
   THE REFINEMENT PASS — 2026-08-25
   ==========================================================================
   The hub is the property a visitor is most likely to see BESIDE a Point, so it
   is refined last and against the finished Points rather than before them.

   Measured on the served build rather than judged from the source:

     - getComputedStyle over every element of the home page returned exactly ONE
       distinct box-shadow, `--shadow`, used on the stuck header. `--shadow-soft`
       is declared in the token block and used nowhere at all. So no card, image
       or panel on any page could say it sat above the page.
     - ZERO animations and ZERO reveal targets. No js class on <html>.
     - Every section was 60px top and bottom.
     - `--muted` is #7b7f81: 4.04:1 on white, below the 4.5:1 floor, on the
       utility line and every figure caption.
     - `--ease` is `all .25s ease`. The Bronx property's own stylesheet carries a
       comment about exactly this: "explicit properties, never `all`: a blanket
       transition also animates inherited visibility, which can leave menu links
       invisible after opening". The sibling recorded the hazard and the hub kept
       the hazard.

   WHAT WAS ALREADY RIGHT, AND IS LEFT ALONE. The hero mask is already
   directional — `linear-gradient(100deg, .92 -> .40)`, heaviest under the copy
   and clearing across the frame — which is the treatment this pass introduced on
   the Points. The display range already runs 52px to 32px. The hero already
   carries a kicker chip, two real actions and a service-area routing strip. This
   pass finishes a good composition rather than repairing a poor one.

   THE MOTIF IS THE CUT, AND HERE THAT IS CORRECT. `--stripes` already runs at
   135 degrees on the accent strip, the logo is a hazard square with a diagonal
   slice, and this repository records no anti-pattern against it. **Brooklyn is
   the exception in this cluster, not the rule** — its own DESIGN-DNA forbids a
   hazard-tape motif by name and its refinement is orthogonal for that reason.
   Checked before assuming, rather than after.
   ========================================================================== */

/* -------- H.1 Tokens the pass needs ------------------------------------ */
:root {
  --lift-1: 0 1px 2px rgba(28, 24, 16, .05), 0 2px 8px -3px rgba(28, 24, 16, .09);
  --lift-2: 0 2px 5px rgba(28, 24, 16, .06), 0 12px 26px -8px rgba(28, 24, 16, .16);
  --lift-3: 0 4px 10px rgba(28, 24, 16, .07), 0 26px 52px -14px rgba(28, 24, 16, .26);

  --ease-out: cubic-bezier(.22, .61, .36, 1);

  /* One period of the 135deg / 28px hatching measured along the x axis:
     28 / cos(45deg). Translating the pattern by exactly this lands it on
     pixel-identical content, which is what makes the drift seamless. */
  --hatch-step: 39.598px;

  /* WAS #7b7f81 — 4.04:1 on white, below the floor for ordinary-size text, and
     it carries the utility line, every figure caption, the card pending note and
     every table caption. #6f7375 is 4.79:1 on white, 4.55:1 on --panel #f9f9f9
     and 4.61:1 on --panel-2 #fafafa, so it passes on every ground in this file. */
  --muted: #6f7375;

  /* WAS `all .25s ease`. A blanket transition animates every property a browser
     can interpolate, including ones inherited from a state change nobody meant
     to animate — the Bronx stylesheet documents a menu whose links stayed
     invisible after opening for exactly this reason. Same duration, same easing,
     named properties only. */
  --ease: color .25s ease, background-color .25s ease, border-color .25s ease,
          box-shadow .25s ease, opacity .25s ease;
}

/* -------- H.2 Surfaces, and the one photograph that is a surface --------
   `.svc-card` is not a panel: it is a photograph, a heading and a paragraph on
   the page ground, so giving the BLOCK a shadow would draw a box that is not
   there. The photograph is the surface, and it is the thing that lifts. */
.svc-card img, img.border, .card img { box-shadow: var(--lift-1); transition: transform .5s var(--ease-out), box-shadow .34s var(--ease-out); }
.svc-card picture, .card picture { display: block; overflow: hidden; }
.svc-card:hover img, .svc-card:focus-within img { transform: scale(1.04); box-shadow: var(--lift-2); }

.card { box-shadow: var(--lift-1); transition: transform .34s var(--ease-out), box-shadow .34s var(--ease-out), border-color .2s ease; }
.card:hover, .card:focus-within {
  /* Up and to the RIGHT, along the brand's own diagonal. */
  transform: translate3d(3px, -7px, 0);
  box-shadow: var(--lift-3);
  border-color: var(--yellow-line);
}

/* -------- H.3 The cut, drawn rather than found in place ----------------
   A hazard rule under a section head, ending on the logo's own diagonal and
   scaling out from its left edge as the block arrives. It is the pass's
   quietest and most-repeated moment and it ties the sections to each other.

   THE REST STATE IS SCOPED TO `.js`, AND THAT IS THE WHOLE SAFETY ARGUMENT.
   An unscoped `scaleX(0)` is a mark that only a script can restore, so it would
   be silently ABSENT for a reader whose JavaScript never ran. */
.section-head { position: relative; }
.section-head h2::after {
  content: ""; display: block;
  width: 64px; height: 4px; margin-top: 18px;
  background: var(--yellow);
  clip-path: polygon(0 0, 100% 0, calc(100% - 4px) 100%, 0 100%);
  transform-origin: left center;
  transition: transform .78s var(--ease-out) .12s;
}
.js .section-head h2::after { transform: scaleX(0); }
.js .section-head.is-in h2::after { transform: scaleX(1); }

/* -------- H.4 The hero carries a CLIP, and therefore no drift ----------
   OPERATOR INSTRUCTION 2026-08-25: give this hero the video treatment the Staten
   Island baseline runs. That also RESOLVES the open loop STATE.json has carried
   since 2026-08-20 — "whether this site gets a video hero is a design decision" —
   and the 14MB file that had been sitting unreferenced in assets/vid/ is now the
   master behind it.

   THE KEN BURNS DRIFT THIS PASS ADDED IS REMOVED, AND THAT IS NOT A REGRESSION.
   Earlier today this section animated `#hero > picture img` at 34 seconds and six
   per cent of scale, because the hero was a still and a still hero was the one
   dead surface on the page. It is not a still any more. Scaling a clip under its
   own playback is two motions arguing, and it is the reason the Staten Island
   baseline leaves its own hero as the ONE section its refinement pass gave no
   drift. The hub now has the same reason and takes the same decision.

   The poster keeps doing the work it always did: it paints immediately, carries
   the LCP, and is the whole hero for anyone who never receives the clip. */
.hero-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 0;
  pointer-events: none;
}
/* The clip sits ON the poster, so both are in the same stacking position and the
   mask and the container stay above both. `#hero > picture` is `display: contents`
   and its <img> is `position: absolute; inset: 0`, so the video simply takes the
   same box. Until site.js attaches a src the element paints nothing and the poster
   shows through. */
#hero .opacity-mask { position: relative; z-index: 1; }

/* -------- H.5 The accent strip drifts along its own axis ----------------
   `#get_quote` already carries the 135 degree hatching and sat perfectly still.
   It is the brand's own mark, so it moves in the brand's own direction: one
   hatch period along the diagonal, about eight pixels a second, and it is the
   only continuous motion on the page below the fold.

   Seamless BY CONSTRUCTION rather than by easing: the layer is one full period
   wider than the band and travels exactly one period, so the frame it ends on is
   pixel-identical to the one it started on and there is no reset to see.

   The hatching moves to a pseudo-element so the band's own colour stays put and
   only the texture travels. `overflow: hidden` is required because the layer now
   starts one period LEFT of a full-bleed element, and without it every width
   would gain a horizontal scrollbar. */
#get_quote { position: relative; overflow: hidden; background-image: none; }
#get_quote > .container { position: relative; z-index: 1; }
#get_quote::before {
  content: ""; position: absolute; top: 0; bottom: 0;
  left: calc(var(--hatch-step) * -1);
  width: calc(100% + var(--hatch-step));
  background-image: var(--stripes);
  animation: hatch-drift 5s linear infinite;
  pointer-events: none;
}
@keyframes hatch-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(var(--hatch-step), 0, 0); }
}

/* -------- H.6 Controls press --------------------------------------------
   A button that changes colour on hover and nothing else is a link with a
   background. */
.btn, .btn_1, a.btn, button.btn {
  box-shadow: 0 1px 2px rgba(28, 24, 16, .12);
  transition: var(--ease), transform .2s var(--ease-out);
}
.btn:hover, .btn_1:hover, .btn:focus-visible, .btn_1:focus-visible { transform: translateY(-2px); box-shadow: var(--lift-2); }
.btn:active, .btn_1:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(28, 24, 16, .12); }

/* The "read more" arrow travels, and it cannot orphan: a non-breaking space has
   no line-break opportunity in front of it, and the travel is on margin-left so
   the glyph moves without the layout moving. */
.link_normal { transition: color .2s ease; }
.link_normal::after { transition: margin-left .24s var(--ease-out); }
.link_normal:hover::after, .link_normal:focus-visible::after { margin-left: 5px; }

/* -------- H.7 Tap targets ------------------------------------------------
   The probe measured 20 controls under 44px. The header nav sits at 36px and the
   hero's service-area routing strip at 28px, both because their padding is on an
   inline-level box that does not grow the line. The `a.sr-only` at 1x1 is the
   skip link and is correct: it is 1x1 until focused, which is what makes it
   invisible and reachable at the same time.

   The nav's flex gap absorbs the extra padding, so the space between labels is
   unchanged and only the hit area grows.

   The FIRST version of this rule missed most of them, and the way it missed is
   worth recording: it guessed `#main_menu` when the navigation is `#main-menu`,
   and a selector that matches nothing fails silently. Written now against the
   ids and classes the served page actually carries, checked by reading them off
   the DOM rather than off the source.

   `a.sr-only` at 1x1 is the skip link and is CORRECT: it is 1x1 until focused,
   which is exactly what makes it invisible to a pointer and reachable by a
   keyboard. It stays.

   AND ONE OF THEM LOST ON SPECIFICITY, WHICH IS THE SAME CLASS OF TRAP AS THE
   DEAD HOVER. `footer li a` further up sets `min-height: 28px` and is (0,0,3);
   a rule written at `footer a` is (0,0,2) and loses to it however late it is
   declared. The footer links kept reporting at 37px while the source said 44,
   and only reading `min-height` off the computed style found it. Matched at the
   same shape here. */
#main-menu a,
#top_line a,
.hero-areas a, .hero-areas span,
.link_normal,
.card-foot a,
footer li a, footer li > span,
footer a, #footer a { min-height: 44px; display: inline-flex; align-items: center; }
/* .link_normal is pushed to the foot of a card by `margin-top: auto`, which needs
   it to stay a block-level flex item in that context rather than an inline one. */
.svc-card .link_normal, .card .link_normal { display: flex; justify-content: flex-start; }

/* Two pixels short is still short. `.btn_1.small` declared min-height: 42px,
   which reads as a considered number and is under the floor the full-size button
   already meets. */
.btn_1.small { min-height: 44px; }

/* The borough card's heading is also its link, and an inline box inside an h3 is
   as tall as its line. It is a real navigation target sitting beside a real
   button, so it gets the same floor as everything else. */
.card h3 a, .card-body h3 a { display: inline-flex; align-items: center; min-height: 44px; }

/* WHAT DELIBERATELY STAYS UNDER 44px, with the reason.
   `a.sr-only` is the skip link at 1x1. That is not a defect, it is the mechanism:
   it is one pixel until it takes focus, which is exactly what makes it invisible
   to a pointer and reachable by a keyboard. Padding it would put a permanent
   44px void at the top of every page. The probe cannot tell the two cases apart
   and reports it every run; it is adjudicated here rather than silenced. */

/* -------- H.8 Section rhythm --------------------------------------------
   Every section was 60px top and bottom, so the page had a metre and no
   emphasis. The two full-bleed moments that are meant to land harder get more
   room than the sections that merely continue. */
.bg_content { padding: calc(var(--section) * 1.2) 0; }
#get_quote { padding: 38px 0; }

/* -------- H.9 The motion vocabulary -------------------------------------
   This site had NO reveal of any kind. Four families now arrive differently, and
   the difference says what kind of thing is arriving:

     a section head           rises a little, quickly, and gets out of the way
     a card or column         arrives along the cut, up and to the right
     a photograph             rises and settles out of a very slight scale
     a full-bleed band        enters from the left

   NOTHING IS HIDDEN UNTIL A SCRIPT HAS CONFIRMED IT CAN UNHIDE IT. Every rest
   state is scoped to `.js`, which boot.js sets from <head> before first paint. */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 20px, 0);
  transition: opacity .62s var(--ease-out), transform .62s var(--ease-out);
}
.js .section-head[data-reveal] {
  transform: translate3d(0, 12px, 0);
  transition-duration: .46s;
}
.js .svc-card[data-reveal],
.js .card[data-reveal],
.js .col-3-text > div[data-reveal],
.js .area-item[data-reveal] { transform: translate3d(-10px, 26px, 0); }
.js .split picture[data-reveal],
.js figure[data-reveal] { transform: translate3d(0, 24px, 0) scale(.985); }
.js [data-reveal].is-in { opacity: 1; transform: none; }

/* AND THE COLLISION THAT CREATES, RESTATED RATHER THAN LEFT TO LUCK.
   `.js [data-reveal].is-in { transform: none }` is (0,3,0) and `.card:hover` is
   (0,1,1). A card is itself a reveal target, so the FINISHED REVEAL OUTRANKS THE
   LIFT on every card a reader can actually point at, and the hover does nothing
   while looking perfectly correct in the source. Declared at a weight that wins,
   next to the rule it loses to. */
.js .card[data-reveal].is-in:hover,
.js .card[data-reveal].is-in:focus-within { transform: translate3d(3px, -7px, 0); }

/* ==========================================================================
   H.10 THE SERVICES SHOWCASE — SiteKit animated-carousel-v1, 2026-08-25
   ==========================================================================
   Declared at project.ui_contracts.services_showcase on explicit operator
   instruction. Before it the four services were a static four-up grid and this
   repository was a legacy candidate, which preflight --post-refine correctly
   failed on the UI-contract rule as migration debt.

   SiteKit's behaviours.js owns the endless loop, the clone sets on both sides,
   the arrows and every hold on automatic motion, and carries SITEKIT-CAROUSEL-V1
   which production-integrity.mjs requires of any page declaring
   [data-carousel-autoplay]. safeguards.css already makes the track a native
   scroll container, already sets every child to flex: 0 0 auto, and already
   exempts an autoplaying track from snapping for its whole life.

   THE CARD WIDTHS DECIDE WHETHER IT MOVES AT ALL. behaviours.js measures the
   ORIGINAL cards, never the cloned track, so a set that already fits gets no
   clones, no controls and NO MOTION — deliberately, because arrows that cannot
   act read as broken. `.svc-grid` fitted all four cards inside the 1140px
   content width exactly, at 263px each. Ported at that width the carousel would
   have been contract-compliant, validator-clean and permanently still.
   ========================================================================== */

.showcase { position: relative; }

/* -------- H.10.1 The controls -------------------------------------------
   Inside [data-carousel], because that is where the contract looks for them.
   Real <button>s with real accessible names: an icon-only control that answers
   only a click is a control for a pointer and for nobody else.

   Graphite on white, not hazard. This page already carries a filled-yellow
   primary action in the header, in the hero and on the accent strip; a pair of
   yellow arrows beside the service cards would compete with the call button for
   the same attention and win, which is the wrong outcome on a hub whose whole
   job is the call. */
.showcase-nav { display: flex; justify-content: flex-end; gap: 10px; margin: -8px 0 18px; }
.cbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  border: 1px solid var(--rule); border-radius: 3px;
  background: var(--white); color: var(--ink);
  font-size: 17px; line-height: 1; cursor: pointer;
  box-shadow: var(--lift-1);
  transition: background-color .2s ease, color .2s ease, border-color .2s ease,
              transform .22s var(--ease-out), box-shadow .22s var(--ease-out);
}
.cbtn:hover { background: var(--yellow); border-color: var(--yellow); color: var(--ink); box-shadow: var(--lift-2); }
/* The travel matches the direction the control moves the track, so the button
   states which way it is about to go before it is pressed. */
.cbtn[data-carousel-prev]:hover { transform: translateX(-2px); }
.cbtn[data-carousel-next]:hover { transform: translateX(2px); }
.cbtn:active { transform: translateY(1px); box-shadow: var(--lift-1); }
.cbtn:focus-visible { outline: 3px solid var(--ochre); outline-offset: 3px; }

/* -------- H.10.2 The track ----------------------------------------------
   `overflow-x: auto` computes overflow-y to auto as well, so a photograph that
   lifts on hover is clipped by its own track unless the track is padded. The
   negative inline margin puts the cards back on the container's own edge, so the
   row starts where every other section on the page starts. */
.showcase-track {
  gap: 30px;
  margin: 0 -6px;
  padding: 8px 6px 26px;
  list-style: none;
  /* The arrows are the affordance here, and a scrollbar under a track that is
     always drifting is a control that appears to move on its own. Finger,
     trackpad and keyboard scrolling are untouched. */
  scrollbar-width: none;
}
.showcase-track::-webkit-scrollbar { display: none; }
.showcase-item { display: flex; }
.showcase-item > .svc-card { width: 100%; }

/* -------- H.10.3 How many cards a width shows ---------------------------
   4 x basis + 3 x 30 must exceed the track. Percentages resolve against the
   track, so anything at or above 26% overflows on its own. */
.showcase-item { flex: 0 0 84%; }                                   /* 4 x 84% = 336% of W */

@media (min-width: 560px) { .showcase-item { flex-basis: 62%; } }   /* 248% of W */
@media (min-width: 768px) { .showcase-item { flex-basis: 46%; } }   /* 184% of W */
@media (min-width: 992px) { .showcase-item { flex-basis: 40%; } }   /* 160% of W */

@media (min-width: 1200px) {
  /* 29% of the 1140px content width is 330.6px, so the set measures
     4 x 330.6 + 3 x 30 = 1412.4 against a 1140 track: 272px of overflow, which is
     most of a card pitch of real travel. Roughly 3.2 cards are visible, which is
     also the composition that tells a reader the row continues.

     THE OLD GRID WAS 263px AND FITTED EXACTLY. Never narrow these without
     re-checking the overflow, and never widen the container without doing the
     same. The failure mode is silent: a still carousel that passes every gate. */
  .showcase-item { flex-basis: clamp(288px, 29%, 342px); }
}

/* -------- H.10.4 The pace ------------------------------------------------
   data-carousel-speed="28", in px/second, inside the behaviour's 10-70 clamp.
   The card pitch at the widest breakpoint is 330.6 + 30 = 360.6px, so a card
   advances one place every 12.9 seconds — inside the eight to fourteen the
   refine stage asks for.

   NO data-reveal ON A CARD. The behaviour clones the set at runtime and the
   reveal observer only watches what it queried at boot, so a cloned card would
   sit at opacity 0 for ever. The reveal is on the showcase root, which is never
   cloned. The card is otherwise unchanged from the static grid it still renders
   in elsewhere, and the two must not drift apart. */


/* -------- H.9b The FAQ, bounded and centred -----------------------------
   Measured on the served page: a question row was 1140px wide and its own
   answer 638px, because `.faq .answer` carried a 74ch measure and `.faq`
   carried none. So every summary stretched the full container while the text
   underneath it sat at not much over half that width. production-integrity
   reports the missing bound and is right about the consequence.

   The heading is bounded WITH the block rather than left at full width. A
   left-aligned full-container heading over a centred block reads as misaligned,
   which is the note the Staten Island property already carries about its own
   FAQ. `:has()` scopes it to the heading that actually precedes an FAQ, so no
   other section head is touched; where `:has()` is unsupported the heading
   simply keeps the width it has today. */
.faq { max-width: 74ch; margin-inline: auto; }
/* CENTRED, on operator instruction 2026-08-25, and it is also what the rest of
   the cluster does: Manhattan's `.faq__heading` is `text-align: center` with the
   note that a left-aligned full-container heading over a centred block reads as
   misaligned, and the Staten Island baseline records the FAQ as "centred, which
   is what the block is for". Bounding the box was half the job; the text inside
   it was still ranged left. */
section:has(> .faq) > h2 { max-width: 74ch; margin-inline: auto; text-align: center; }

/* ==========================================================================
   H.12 THE HERO LEAD FORM — 2026-08-26
   ==========================================================================
   Operator instruction: add the form and wire it, in the hero.

   THE HERO IS NOW TWO COLUMNS. The statement keeps the left and the form takes
   the right, which is the same relationship the Staten Island baseline uses and
   the reason the hero mask was already directional: it is heaviest on the left
   where the copy is and clears to the right, which is exactly where a light card
   now sits. The treatment that was already correct for the photograph turns out
   to be correct for the form too.

   BELOW 62rem THE FORM GOES UNDER THE STATEMENT rather than beside it. A form
   squeezed into half of a phone screen is a form nobody completes, and stacking
   is what the single-column grid does anyway. */
.hero-grid { display: grid; gap: 40px; align-items: center; }
@media (min-width: 62rem) {
  .hero-grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 56px; }
  .hero-form { justify-self: end; width: 100%; max-width: 27rem; }
}

/* -------- H.12.1 The form is a card, because it is a surface -------------
   This is the one place on the page where a surface genuinely IS above another:
   a light panel on a photograph. It takes the top of the elevation scale, and a
   4px hazard edge so the brand owns the moment rather than the browser's default
   white. */
.lead-form {
  background: var(--white);
  border-top: 4px solid var(--yellow);
  border-radius: var(--radius, 3px);
  box-shadow: var(--lift-3);
  padding: 26px 26px 22px;
  color: var(--ink);
  text-align: left;
}
.lead-form-heading { font-size: 1.18rem; margin: 0 0 16px; color: var(--ink); }

.lead-row { display: grid; gap: 0 14px; }
@media (min-width: 30rem) { .lead-row { grid-template-columns: 1fr 1fr; } }

.lead-field { margin: 0 0 14px; }
.lead-field label {
  display: block; font-size: .82rem; font-weight: 700; letter-spacing: .02em;
  color: var(--ink); margin-bottom: 6px;
}
.lead-optional { font-weight: 400; color: var(--muted); letter-spacing: 0; }
.lead-field input,
.lead-field textarea {
  width: 100%; box-sizing: border-box;
  font: inherit; font-size: .97rem; color: var(--ink);
  background: var(--white);
  border: 1px solid var(--rule); border-radius: 2px;
  padding: 11px 12px;
  /* 44px minimum, like every other control on the site. A field a thumb misses
     is a lead lost at the last step. */
  min-height: 44px;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.lead-field textarea { min-height: 66px; resize: vertical; }
.lead-field input:hover,
.lead-field textarea:hover { border-color: #c9c9c6; }
.lead-field input:focus-visible,
.lead-field textarea:focus-visible {
  outline: 3px solid var(--ochre); outline-offset: 2px; border-color: var(--yellow);
}

/* THE HONEYPOT IS NOT `display: none`. A field a bot can detect as hidden is a
   field it learns to skip, and some assistive technology skips display:none too,
   which is why it also carries aria-hidden and tabindex="-1". Positioned out of
   the flow instead, so it occupies no space and is never reachable by keyboard,
   pointer or screen reader. */
.lead-hp {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.lead-actions { margin: 4px 0 0; }
.lead-actions .btn_1 { width: 100%; text-align: center; }

/* The status line is `role="status" aria-live="polite"`, so it is announced when
   it changes and silent when empty. It reserves no space until it has something
   to say, because an empty gap under a button reads as a missing element. */
.lead-status { margin: 12px 0 0; font-size: .9rem; line-height: 1.45; }
.lead-status:empty { display: none; }
.lead-status[data-state="busy"]  { color: var(--body); }
.lead-status[data-state="ok"]    { color: #1c6b3a; font-weight: 700; }
.lead-status[data-state="error"] { color: #a3261c; font-weight: 700; }

.lead-noscript { margin: 0 0 12px; font-size: .9rem; color: var(--body); }
.lead-consent { margin: 12px 0 0; font-size: .8rem; line-height: 1.5; color: var(--muted); }

/* -------- H.12.2 Two primaries in one region, and why that is allowed ----
   The hero now carries a filled call button and a filled submit. The probe reads
   that as two competing primary actions and it is a fair reading of the pixels,
   but they are one action per REGION: the statement column offers the call, the
   form column offers the send, and the card's elevation is what makes the second
   region a region rather than a loose second button. The Staten Island baseline
   makes the same argument for the same composition.

   The submit is deliberately NOT the ghost variant. A form whose send control is
   quieter than the button beside it is a form the reader is being steered away
   from, which is the opposite of adding one. */

/* ==========================================================================
   H.11 THE REDUCED-MOTION PATH, RESTATED
   ==========================================================================
   THIS BLOCK IS LOAD-BEARING AND MUST STAY LAST IN THIS FILE.

   The stylesheet already carries `@media (prefers-reduced-motion: reduce)
   { * { transition: none !important; animation: none !important } }` further up.
   That block is NOT enough and would have shipped a broken page: it resets
   transition and animation and it does NOT reset `opacity` or `transform`. Every
   reveal above arms itself at `opacity: 0`, so a reader who asked for less motion
   would have got a page whose content was permanently invisible, with the
   transition meant to reveal it switched off.

   That is also the exact condition render-probe.mjs raises as a hard INVARIANT
   rather than a suspicion, because the probe captures WITH the preference
   emulated — so the screenshots meant to prove this design would have been
   screenshots of the defect.

   `transform: none` is the identity transform, which is what the drawn rule
   wants: a bar that never animates is a bar at full width. */
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js .section-head[data-reveal],
  .js .svc-card[data-reveal],
  .js .card[data-reveal],
  .js .col-3-text > div[data-reveal],
  .js .area-item[data-reveal],
  .js .split picture[data-reveal],
  .js figure[data-reveal] { opacity: 1 !important; transform: none !important; }

  .js .section-head h2::after { transform: none !important; }

  /* The hero no longer animates: it carries a clip instead of a drift, and
     site.js refuses to attach the clip at all under this preference, so the
     poster is what a reduced-motion reader sees and it never moves. The old
     `#hero > picture img` entry is gone with the drift it was resetting. This is
     the CSS half of that guarantee, kept as a floor in case a future pass gives
     the hero a transform again. */
  #hero > picture img, .hero-video,
  #get_quote::before { animation: none !important; transform: none !important; }

  /* And the hover travel, consistently. Suppressing transforms on reveal targets
     already killed the card lift; the buttons, the service photographs and the
     carousel controls are not reveal targets and would otherwise still displace
     themselves while their neighbours did not. Nothing about the affordance is
     lost — every one still answers a pointer with its elevation and its colour. */
  .btn:hover, .btn_1:hover, .btn:focus-visible, .btn_1:focus-visible,
  .btn:active, .btn_1:active,
  .svc-card:hover img, .svc-card:focus-within img,
  .cbtn:hover, .cbtn:active { transform: none !important; }
}
