/* ==========================================================================
   Master lead-gen website template
   Ported 1:1 from Mazhar's reference build (Next.js + Tailwind source):
   spacing, radii, type scale and hover states below mirror the original
   utility classes exactly. Only the accent color is tokenized, so each
   generated site can differ in hue without drifting from the design.
   ========================================================================== */

:root {
  --accent: #db5a16;
  --accent-dark: #b5470e;
  /* The accent, darkened only as far as it needs to be to clear WCAG AA
     (4.5:1) for small text on a light section. Generated per client and
     verified at build time, because the accent hue differs per site and
     the bright version was landing at 2.0-3.0:1 on every eyebrow label.
     Use for accent-coloured text under ~18px. Buttons, large headings and
     icons keep --accent. */
  --accent-ink: #c54c0d;
  /* The same idea pointing the other way, for accent text on the dark
     sections and page banners — darkening it there makes it worse. */
  --accent-on-dark: #db5a16;
  /* Reference uses accent at 10/20/30% alpha for tints, pills and borders. */
  --accent-10: rgba(219, 90, 22, 0.1);
  --accent-20: rgba(219, 90, 22, 0.2);
  --accent-30: rgba(219, 90, 22, 0.3);

  --dark: #1a1a1a;          /* brand-dark  */
  --light: #f8f9fa;         /* brand-light */
  --white: #ffffff;
  --black: #000000;         /* footer only */

  --gray-100: #f3f4f6;
  --gray-200: #e5e7eb;
  --gray-300: #d1d5db;
  --gray-400: #9ca3af;
  --gray-600: #4b5563;
  --gray-700: #374151;
  --gray-800: #1f2937;

  --container: 1280px;      /* max-w-7xl */
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

* { box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  /* Every in-page anchor (#areas, #services, "View all service areas") must
     clear the 80px fixed header — without this the target heading lands hidden
     behind the header, which reads as a broken jump on mobile and desktop. */
  scroll-padding-top: 92px;
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  font-family: var(--font);
  color: var(--gray-600);
  background: var(--white);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;             /* belt-and-braces: never allow sideways scroll */
}
/* Locks the page behind the open mobile menu so it can't scroll underneath. */
body.menu-open { overflow: hidden; }
h1, h2, h3, h4 { margin: 0; color: var(--dark); line-height: 1.2; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
ul { list-style: none; margin: 0; padding: 0; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 16px; }
@media (min-width: 640px) { .container { padding: 0 24px; } }
@media (min-width: 1024px) { .container { padding: 0 32px; } }

/* py-20 sm:py-28 */
.section { padding: 80px 0; }
@media (min-width: 640px) { .section { padding: 112px 0; } }
.section-dark  { background: var(--dark); }
.section-light { background: var(--light); }
.section-white { background: var(--white); }

/* ── Section headings ────────────────────────────────────────────────── */
.section-head { text-align: center; max-width: 672px; margin: 0 auto 56px; }
.section-head.wide-gap { margin-bottom: 64px; }
.eyebrow {
  color: var(--accent-ink); font-weight: 600; font-size: 14px;
  text-transform: uppercase; letter-spacing: .025em;
}
.section-head h2 { margin-top: 12px; font-size: 30px; font-weight: 800; letter-spacing: -0.02em; }
@media (min-width: 640px) { .section-head h2 { font-size: 36px; } }
.section-head p { margin-top: 16px; font-size: 18px; color: var(--gray-600); }
.section-dark .eyebrow, .page-banner .eyebrow, .cta-band .eyebrow { color: var(--accent-on-dark); }
.section-dark .section-head h2 { color: #fff; }
.section-dark .section-head p { color: var(--gray-300); }

/* ── Buttons ─────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600; border-radius: 6px; border: 2px solid transparent;
  cursor: pointer; transition: background-color .15s, border-color .15s, color .15s;
  padding: 10px 20px; font-size: 16px; white-space: nowrap;
}
/* White, by choice. On the brighter accents this is under the 4.5:1 WCAG wants
   for text this size (the amber measures 2.99:1). Keeping white and passing
   would mean darkening the accent itself to roughly #b55f17, which changes the
   brand colour rather than the label — so the label stays white and the
   shortfall is a known, accepted one. */
.btn-accent { background: var(--accent); color: #fff; }
.btn-accent:hover { background: var(--accent-dark); }
.btn-dark { background: var(--dark); color: #fff; }
.btn-dark:hover { background: var(--black); }
.btn-outline-light { background: transparent; border-color: #6b7280; color: #fff; }
.btn-outline-light:hover { border-color: #fff; }
/* An outline button on a light section. Kept for anywhere a secondary control
   genuinely should recede; the gallery's "view all" is NOT one of those — it is
   the only thing to press in that section, and every other button on a white
   background here is solid dark. */
.btn-outline { background: transparent; border-color: #d1d5db; color: var(--dark); }
.btn-outline:hover { border-color: var(--accent); color: var(--accent); }
/* px-8 py-4 text-lg */
.btn-lg { padding: 16px 32px; font-size: 18px; }
.btn-block { width: 100%; }

/* Optional-field marker and hint text on the quote form. Saying which fields
   are optional out loud is what makes a short form feel short. */
.field .opt {
  font-weight: 500; font-size: 12px; color: var(--gray-400);
  text-transform: none; letter-spacing: 0; margin-left: 6px;
}
.field-hint { display: block; margin-top: 6px; font-size: 12.5px; color: var(--gray-400); line-height: 1.5; }

/* ── Header (fixed, h-20) ────────────────────────────────────────────── */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  background: rgba(26,26,26,.95);
  backdrop-filter: blur(4px);
  box-shadow: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);
}
.header-inner {
  display: flex; align-items: center; justify-content: space-between;
  height: 80px; max-width: var(--container); margin: 0 auto; padding: 0 16px;
  /* The brand and the first nav link were touching — "SolutionsHome" — because
     space-between only guarantees a gap while there IS slack. This guarantees
     one whether or not there is. */
  gap: 28px;
}
@media (min-width: 640px) { .header-inner { padding: 0 24px; } }
@media (min-width: 1024px) { .header-inner { padding: 0 32px; } }
.brand { display: flex; flex-direction: column; line-height: 1.15; }
.brand-name { font-size: 20px; font-weight: 700; color: #fff; white-space: nowrap; }
@media (min-width: 640px) { .brand-name { font-size: 24px; } }
.brand-name .accent { color: var(--accent); }
.brand-tag { font-size: 12px; color: var(--gray-400); letter-spacing: .025em; white-space: nowrap; }
.nav { display: none; align-items: center; gap: 24px; }
@media (min-width: 768px) { .nav { display: flex; } }
@media (min-width: 1180px) { .nav { gap: 32px; } }
/* Tap-to-call in the header. It was a quiet outline while the quote button was
   up there competing with it; now that the button has gone it is the header's
   only call to action, so it gets the accent and reads as one. */
.nav a.nav-call {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--accent); color: #fff; font-weight: 700; white-space: nowrap;
  padding: 11px 18px; border-radius: 6px; border: 2px solid transparent;
  transition: background-color .15s;
}
.nav a.nav-call:hover { background: var(--accent-dark); color: #fff; }
.nav-call svg { width: 17px; height: 17px; color: currentColor; flex-shrink: 0; }
/* The drawer copy of it, where .nav a does not apply. */
.nav-mobile a.nav-call {
  background: var(--accent); color: #fff; font-weight: 700;
  padding: 12px 18px; border-radius: 6px; justify-content: center;
}
/* Below this the nav is too tight for a phone number AS WELL AS six links and
   the CTA: at 1088px the brand wrapped to two lines and the nav items wrapped
   with it. Measured, not guessed. The sticky call bar covers everything below,
   so no width is ever left without a number. */
@media (max-width: 1023px) { .nav .nav-call { display: none; } }
.nav-call-mobile { justify-content: center; }
.nav a { color: #e5e7eb; font-weight: 500; white-space: nowrap; transition: color .15s; }
.nav a:hover { color: var(--accent); }
/* The CTA lives inside .nav, so the nav-link rule above would otherwise win on
   specificity and render its label gray-200/500 instead of white/600. */
.nav a.btn { color: #fff; font-weight: 600; }
.nav a.btn:hover { color: #fff; }
/* Current page in the nav */
.nav a.active { color: var(--accent); }
.nav-mobile a.active { color: var(--accent); }
.nav-toggle { display: block; background: none; border: 0; color: #fff; padding: 8px; cursor: pointer; }
@media (min-width: 768px) { .nav-toggle { display: none; } }
.nav-toggle svg { width: 28px; height: 28px; }
/* Mobile drawer */
.nav-mobile { display: none; flex-direction: column; gap: 16px; padding-bottom: 24px; }
.nav-mobile.open { display: flex; }
@media (min-width: 768px) { .nav-mobile.open { display: none; } }
.nav-mobile a { color: #e5e7eb; font-weight: 500; padding: 4px 0; }
.nav-mobile a:hover { color: var(--accent); }
.nav-mobile a.btn { color: #fff; font-weight: 600; padding: 12px 20px; }

/* ── Hero (pt-32 pb-20 / sm:pt-40 sm:pb-28) ─────────────────────────── */
.hero {
  position: relative; padding: 128px 0 80px; overflow: hidden; text-align: center;
  background: linear-gradient(180deg, #141414 0%, var(--dark) 55%, #202020 100%);
}
@media (min-width: 640px) { .hero { padding: 160px 0 112px; } }

/* ── Hero photograph ───────────────────────────────────────────────────
   A real project photo behind the headline. Construction is bought with the
   eyes — a gradient alone shows the customer nothing you have built. The
   image is a real <img> (not a CSS background) so it can be preloaded and
   marked fetchpriority=high; it is the LCP element. */
.hero-photo { position: absolute; inset: 0; z-index: 0; }
.hero-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Two-stop scrim: heavier at the bottom/left where the text sits, lighter at
   top-right so the photo still reads. Without this the white headline fails
   contrast over bright areas of the image. */
.hero-photo::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(16,12,8,.78) 0%, rgba(16,12,8,.55) 42%, rgba(16,12,8,.80) 100%),
    linear-gradient(90deg, rgba(16,12,8,.30) 0%, rgba(16,12,8,0) 55%, rgba(16,12,8,.22) 100%);
}
/* When a photo is present the decorative orbs would muddy it. */
/* Each generated site uploads its OWN hero photo, so legibility cannot depend
   on any one image being dark. A soft text-shadow guarantees the headline and
   sub stay readable even over a bright photo, and the sub is lifted to near
   white for the same reason. */
.hero:has(.hero-photo) .hero-headline,
.hero:has(.hero-photo) .hero-sub { text-shadow: 0 2px 12px rgba(0,0,0,.55); }
.hero:has(.hero-photo) .hero-sub { color: rgba(255,255,255,.92); }
.hero:has(.hero-photo) .hero-trust .item { color: #fff; text-shadow: 0 1px 8px rgba(0,0,0,.5); border-top-color: rgba(255,255,255,.28); }
.hero:has(.hero-photo) .hero-badge { backdrop-filter: blur(4px); }

.hero .container { position: relative; z-index: 1; }
/* Sits over a photograph, so it cannot rely on the accent alone — amber text on
   a 20% amber wash measured ~4.2:1, under the 4.5 AA needs at this size, and
   this is the line carrying the trade and city. A near-opaque dark plate under
   white text is legible over any photo the owner uploads, which a translucent
   tint is not. */
/* This is the page's <h1>. Everything here is stated explicitly because the
   global heading rule sets colour and the browser sets a large default size,
   and neither is wanted: the element has to look exactly as it did as a span. */
.hero-badge {
  display: inline-block; background: rgba(17,17,17,.72); color: #fff;
  font-weight: 600; font-size: 14px; line-height: 1.5; padding: 7px 16px;
  border-radius: 9999px; border: 1px solid var(--accent-30);
  margin: 0 0 24px;
}
.hero .hero-headline { font-size: 36px; font-weight: 800; color: #fff; line-height: 1.25; margin-bottom: 24px; letter-spacing: -0.02em; }
@media (min-width: 640px) { .hero .hero-headline { font-size: 48px; } }
@media (min-width: 1024px) { .hero .hero-headline { font-size: 60px; } }
.hero .hero-headline .accent { color: var(--accent); }
.hero .hero-headline .brk { display: none; }
@media (min-width: 640px) { .hero .hero-headline .brk { display: block; } }
.hero-sub { font-size: 18px; color: var(--gray-300); max-width: 672px; margin: 0 auto 40px; }
@media (min-width: 640px) { .hero-sub { font-size: 20px; } }
.hero-ctas { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; }
@media (min-width: 640px) { .hero-ctas { flex-direction: row; } }
.hero-ctas .btn { width: 100%; }
@media (min-width: 640px) { .hero-ctas .btn { width: auto; } }
.hero-ctas .btn-accent { box-shadow: 0 10px 15px -3px var(--accent-20); }
.hero-trust { margin-top: 56px; display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; max-width: 768px; margin-left: auto; margin-right: auto; }
@media (min-width: 640px) { .hero-trust { grid-template-columns: repeat(4, 1fr); } }
.hero-trust .item {
  color: var(--gray-300); font-weight: 500; font-size: 14px;
  border-top: 1px solid var(--gray-700); padding-top: 16px;
}
@media (min-width: 640px) { .hero-trust .item { font-size: 16px; } }

/* ── Inner-page banner ─────────────────────────────────────────────────
   Compact dark header for Services / About / Contact. Deliberately much
   shorter than the home hero so inner pages get to their content fast,
   while keeping the same dark band + accent-orb treatment for continuity. */
.page-banner {
  position: relative; padding: 148px 0 64px; overflow: hidden; text-align: center;
  background: linear-gradient(180deg, #141414 0%, var(--dark) 62%, #1f1f1f 100%);
}
@media (min-width: 640px) { .page-banner { padding: 176px 0 80px; } }
.page-banner .container { position: relative; z-index: 1; }
.page-banner .eyebrow { display: block; margin-bottom: 12px; }
.page-banner h1 { font-size: 34px; font-weight: 800; color: #fff; letter-spacing: -0.02em; }
@media (min-width: 640px) { .page-banner h1 { font-size: 44px; } }
.page-banner p { margin: 16px auto 0; font-size: 18px; color: var(--gray-300); max-width: 640px; }
/* Breadcrumb-ish trail under the banner heading */
.crumbs { margin-top: 18px; font-size: 14px; color: var(--gray-400); }
.crumbs a { color: var(--gray-300); }
.crumbs a:hover { color: var(--accent); }
.crumbs span { color: var(--accent); }

/* ── CTA band ──────────────────────────────────────────────────────────
   Closing conversion prompt used at the foot of inner pages. */
.cta-band {
  text-align: center; padding: 72px 0; position: relative; overflow: hidden;
  background: linear-gradient(180deg, #1f1f1f 0%, var(--dark) 100%);
}
.cta-band .container { position: relative; z-index: 1; }
.cta-band h2 { color: #fff; font-size: 28px; font-weight: 800; letter-spacing: -0.02em; }
@media (min-width: 640px) { .cta-band h2 { font-size: 34px; } }
.cta-band p { color: var(--gray-300); margin: 14px auto 28px; max-width: 560px; font-size: 17px; }
.cta-band .btn-row { display: flex; flex-direction: column; gap: 14px; align-items: center; justify-content: center; }
@media (min-width: 640px) { .cta-band .btn-row { flex-direction: row; } }
.cta-band .btn { width: 100%; }
@media (min-width: 640px) { .cta-band .btn { width: auto; } }

/* ── About: split text + image ─────────────────────────────────────────*/
.split { display: grid; grid-template-columns: 1fr; gap: 40px; align-items: center; }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; gap: 56px; } }
.split-media { border-radius: 16px; overflow: hidden; aspect-ratio: 4 / 3; background: var(--gray-200); }
.split-media img { width: 100%; height: 100%; object-fit: cover; }
.split-body .eyebrow { display: block; margin-bottom: 12px; }
.split-body h2 { font-size: 30px; font-weight: 800; letter-spacing: -0.02em; margin-bottom: 16px; }
@media (min-width: 640px) { .split-body h2 { font-size: 36px; } }
.split-body p { color: var(--gray-600); margin-bottom: 16px; line-height: 1.7; }
.split-list { margin-top: 24px; display: flex; flex-direction: column; gap: 12px; }
.split-list li { display: flex; gap: 12px; align-items: flex-start; color: var(--gray-600); }
.split-list svg { width: 22px; height: 22px; color: var(--accent); flex-shrink: 0; margin-top: 1px; }

/* ── Home "short about" ────────────────────────────────────────────────
   Copy on the left, photo on the right with an accent badge overlapping its
   corner. The photo gives the section visual weight it lacked as a centered
   text block, and the mirrored layout (text-left) keeps it distinct from the
   About page's split, which leads with the image. */
.home-about { display: grid; grid-template-columns: 1fr; gap: 32px; align-items: center; }
/* Stacked: lead with the photo rather than stranding it below the CTA. */
.home-about .about-media { order: -1; }
@media (min-width: 900px) {
  .home-about { grid-template-columns: 1.05fr 1fr; gap: 64px; }
  .home-about .about-media { order: 0; }   /* side-by-side: photo on the right */
}
.home-about .eyebrow { display: block; margin-bottom: 12px; }
.home-about h2 { font-size: 30px; font-weight: 800; letter-spacing: -0.02em; margin-bottom: 18px; }
@media (min-width: 640px) { .home-about h2 { font-size: 36px; } }
.home-about p { color: var(--gray-600); font-size: 16.5px; line-height: 1.75; margin-bottom: 16px; }

/* Credibility numbers as a single bordered panel with divided columns —
   reads as a designed unit instead of three floating numbers. Stays 3-across
   at every width (the labels wrap rather than the third figure dropping to
   its own line, which looked broken on phones). */
.about-figures {
  display: grid; grid-template-columns: repeat(3, 1fr);
  background: var(--light); border: 1px solid var(--gray-100);
  border-radius: 12px; overflow: hidden; margin: 26px 0 28px;
}
.about-figures > div {
  padding: 18px 10px; text-align: center;
  border-right: 1px solid var(--gray-200);
}
.about-figures > div:last-child { border-right: 0; }
.about-figures .fig-num { font-size: 24px; font-weight: 800; color: var(--accent); letter-spacing: -0.02em; line-height: 1.1; }
@media (min-width: 480px) { .about-figures .fig-num { font-size: 28px; } }
.about-figures .fig-lbl { font-size: 12px; color: var(--gray-600); margin-top: 4px; line-height: 1.3; }
@media (min-width: 480px) { .about-figures .fig-lbl { font-size: 13px; } }

.about-media { position: relative; }
.about-media img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: 16px; display: block;
}
/* Badge tucked into the photo's lower-left corner. Hidden below 900px where
   the columns stack and it would crowd the text. */
.about-badge {
  display: none; position: absolute; left: -24px; bottom: -24px;
  background: var(--accent); color: #fff; border-radius: 14px;
  padding: 18px 22px; box-shadow: 0 18px 40px -12px rgba(0,0,0,.35); max-width: 210px;
}
@media (min-width: 900px) { .about-badge { display: block; } }
.about-badge .big { font-size: 26px; font-weight: 800; line-height: 1.1; }
.about-badge .small { font-size: 13px; opacity: .92; margin-top: 3px; line-height: 1.35; }

/* ── FAQ (native accordion, no JS) ─────────────────────────────────────*/
.faq-list { max-width: 820px; margin: 0 auto; }
.faq-item { border-bottom: 1px solid var(--gray-200); }
.faq-item summary {
  list-style: none; cursor: pointer; padding: 22px 40px 22px 0; position: relative;
  font-weight: 600; font-size: 17px; color: var(--dark); transition: color .15s;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--accent-ink); }
/* +/x indicator drawn with two rules so it needs no icon font */
.faq-item summary::before,
.faq-item summary::after {
  content: ""; position: absolute; right: 6px; top: 50%; background: var(--accent);
  transition: transform .2s;
}
.faq-item summary::before { width: 14px; height: 2px; margin-top: -1px; }
.faq-item summary::after { width: 2px; height: 14px; margin-top: -7px; right: 12px; }
.faq-item[open] summary { color: var(--accent-ink); }
.faq-item[open] summary::after { transform: rotate(90deg); opacity: 0; }
.faq-item .answer { padding: 0 40px 22px 0; color: var(--gray-600); line-height: 1.7; }
.section-dark .faq-item { border-color: rgba(255,255,255,.12); }
.section-dark .faq-item summary { color: #fff; }
.section-dark .faq-item .answer { color: var(--gray-300); }

/* ── Service cards ─────────────────────────────────────────────────────
   Flex rather than grid so a partial final row CENTERS. The service count is
   category-driven (10 by default), which in a rigid 3-up grid would leave a
   lone card hanging at the left edge and read as a mistake. */
.card-grid { display: flex; flex-wrap: wrap; gap: 32px; justify-content: center; }
.card-grid > .card { flex: 0 1 100%; }
@media (min-width: 640px) { .card-grid > .card { flex: 0 1 calc(50% - 16px); } }
@media (min-width: 1024px) { .card-grid > .card { flex: 0 1 calc(33.333% - 22px); } }
.card {
  background: var(--white); border-radius: 12px; padding: 32px;
  border: 1px solid var(--gray-100);
  box-shadow: 0 1px 2px rgba(0,0,0,.05);
  transition: box-shadow .2s;
}
.card:hover { box-shadow: 0 20px 25px -5px rgba(0,0,0,.1), 0 8px 10px -6px rgba(0,0,0,.1); }
/* No pictogram: the service name is the card's own graphic, so it carries the
   weight the icon tile used to. */
.card h3 { font-size: 23px; font-weight: 700; line-height: 1.25; margin-bottom: 14px; text-wrap: balance; }
.card p { color: var(--gray-600); line-height: 1.625; margin-bottom: 18px; }
.card-link {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--accent-ink); font-weight: 600; font-size: 14px;
  transition: gap .15s;
}
.card-link:hover { gap: 10px; }
.section-cta { text-align: center; margin-top: 56px; }

/* ── Services PAGE list ────────────────────────────────────────────────
   Landscape "catalog" rows, 2-up: title + description + a per-service quote
   link. Deliberately a different shape from the home teaser's portrait cards.
   No icon tile — see the note on .card above. */
.svc-list { display: grid; grid-template-columns: 1fr; gap: 20px; }
@media (min-width: 768px) { .svc-list { grid-template-columns: 1fr 1fr; gap: 24px; } }
.svc-item {
  display: flex; background: var(--white);
  border: 1px solid var(--gray-100); border-radius: 14px; padding: 26px 28px;
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.svc-item:hover { border-color: var(--accent-30); box-shadow: 0 14px 30px -12px rgba(0,0,0,.12); transform: translateY(-2px); }
.svc-body { min-width: 0; }
.svc-body h3 { font-size: 21px; font-weight: 700; margin-bottom: 8px; }
.svc-body p { color: var(--gray-600); font-size: 15px; line-height: 1.65; margin-bottom: 14px; }
.svc-link { display: inline-flex; align-items: center; gap: 6px; color: var(--accent-ink); font-weight: 600; font-size: 14px; }
.svc-link:hover { gap: 10px; }

/* ── Service areas (dark, 4-up) ──────────────────────────────────────── */
.area-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; max-width: 1024px; margin: 0 auto; }
@media (min-width: 640px) { .area-grid { gap: 16px; } }
@media (min-width: 640px) { .area-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .area-grid { grid-template-columns: repeat(4, 1fr); } }
.area-card {
  display: flex; align-items: center; gap: 9px;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1);
  border-radius: 8px; padding: 11px 13px;
  transition: background-color .15s, border-color .15s;
}
@media (min-width: 640px) { .area-card { gap: 12px; padding: 16px 20px; } }
.area-card:hover { background: var(--accent-10); border-color: var(--accent-30); }
.area-card svg { width: 16px; height: 16px; color: var(--accent); flex-shrink: 0; }
@media (min-width: 640px) { .area-card svg { width: 20px; height: 20px; } }
/* "Shreveport, LA" was wrapping onto two lines in a two-column grid on a phone,
   which is what made these cards twice as tall as they needed to be. */
.area-card span { color: #fff; font-weight: 500; font-size: 14px; line-height: 1.3; white-space: nowrap; }
@media (min-width: 640px) { .area-card span { font-size: 16px; white-space: normal; } }
.area-note { text-align: center; color: var(--gray-400); margin-top: 40px; }
.area-note a { color: var(--accent); font-weight: 600; }
.area-note a:hover { text-decoration: underline; }

/* ── Why Us — horizontal icon + text ─────────────────────────────────── */
.why-grid { display: grid; grid-template-columns: 1fr; gap: 24px; margin-bottom: 96px; }
@media (min-width: 640px) { .why-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .why-grid { grid-template-columns: repeat(3, 1fr); } }
/* Carded, matching the service cards. As bare icon-and-text on an empty white
   section these read as a loose list with a lot of dead space between them;
   the card gives each one an edge and makes the six read as a set. */
.why-item {
  display: flex; gap: 16px; padding: 24px;
  background: var(--white); border: 1px solid var(--gray-100); border-radius: 12px;
  box-shadow: 0 1px 2px rgba(0,0,0,.05);
  transition: box-shadow .2s, border-color .2s;
}
.why-item:hover { box-shadow: 0 20px 25px -5px rgba(0,0,0,.1), 0 8px 10px -6px rgba(0,0,0,.1); }
/* On a light section a white card needs an edge to sit on; on a white one the
   border does that job and the fill would vanish. */
.section-light .why-item { background: var(--white); }
.why-ic {
  width: 48px; height: 48px; border-radius: 8px; background: var(--accent-10);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.why-ic svg { width: 24px; height: 24px; color: var(--accent); }
.why-item h3 { font-size: 18px; font-weight: 700; margin-bottom: 4px; }
.why-item p { font-size: 14px; color: var(--gray-600); line-height: 1.625; }

/* ── How It Works — nested panel inside Why Us ───────────────────────── */
.steps-panel { background: var(--light); border-radius: 16px; padding: 32px; }
@media (min-width: 640px) { .steps-panel { padding: 48px; } }
.steps-head { text-align: center; margin-bottom: 48px; }
.steps-head h3 { font-size: 24px; font-weight: 800; letter-spacing: -0.02em; }
@media (min-width: 640px) { .steps-head h3 { font-size: 30px; } }
.steps-head p { margin-top: 8px; color: var(--gray-600); }
.steps-grid { display: grid; grid-template-columns: 1fr; gap: 32px; }
@media (min-width: 640px) { .steps-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .steps-grid { grid-template-columns: repeat(4, 1fr); } }
.step-top { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.step-num { font-size: 30px; font-weight: 800; color: var(--accent-30); }
.step-rule { display: none; height: 1px; background: var(--gray-300); flex: 1; }
@media (min-width: 1024px) { .step-rule { display: block; } }
/* Below the four-across layout the steps stack, so the rule that joined them
   horizontally has nothing to span. The sequence still needs to read as a
   sequence, so each step draws a line down to the next one instead. */
@media (max-width: 1023px) {
  .steps-grid { gap: 0; }
  .step { position: relative; padding-left: 44px; padding-bottom: 32px; }
  .step:last-child { padding-bottom: 0; }
  /* Starts below the number and runs down to the next step. */
  .step::before {
    content: ""; position: absolute; left: 13px; top: 28px; bottom: 0;
    width: 2px; background: var(--gray-200);
  }
  .step:last-child::before { display: none; }
  /* The number belongs IN the gutter beside the heading, not on a line of its
     own above it. Taken out of flow entirely so the heading starts at the top
     of the box and the two share a line. */
  .step-top {
    position: absolute; left: 0; top: 0; width: 28px;
    margin: 0; justify-content: center;
  }
  .step-num {
    width: 28px; text-align: center; font-size: 15px;
    /* The heading's own line box: 18px x 1.2. Matching it is what puts the two
       on one line rather than merely near each other. */
    line-height: 21.6px;
    color: var(--accent); background: var(--white);
    position: relative; z-index: 1;
  }
  .steps-panel .step-num { background: var(--light); }
  .step h3 { margin-top: 0; }
}
.step h3 { font-weight: 700; font-size: 18px; margin-bottom: 8px; }
.step p { font-size: 14px; color: var(--gray-600); line-height: 1.625; }

/* ── Reviews / testimonials ────────────────────────────────────────────
   Social proof is the missing piece in a trust purchase like remodeling —
   the customer is letting strangers into their home for weeks. Name + city +
   job type makes a review read as a real neighbor rather than filler. */
.review-grid { display: grid; grid-template-columns: 1fr; gap: 24px; }
@media (min-width: 700px) { .review-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .review-grid { grid-template-columns: repeat(3, 1fr); } }
.review {
  background: var(--white); border: 1px solid var(--gray-100); border-radius: 14px;
  padding: 28px 26px; box-shadow: 0 1px 2px rgba(0,0,0,.05);
  display: flex; flex-direction: column;
}
.review-stars { display: flex; gap: 3px; margin-bottom: 14px; }
.review-stars svg { width: 18px; height: 18px; color: var(--accent); }
/* margin: 0 on purpose — <blockquote> carries a browser default
   margin-inline of 40px, which was rendering the quote in a 170px column
   inside a 304px card and wrapping six lines of text into ten. */
.review-quote { color: var(--gray-700); font-size: 15.5px; line-height: 1.7; margin: 0 0 20px; flex: 1; }
.review-who { display: flex; align-items: center; gap: 12px; padding-top: 16px; border-top: 1px solid var(--gray-100); }
/* Initial-avatar instead of a stock headshot — honest, and it never looks
   like a fake stock person. */
.review-avatar {
  width: 42px; height: 42px; border-radius: 50%; flex-shrink: 0;
  background: var(--accent-10); color: var(--accent-ink);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 16px;
}
.review-name { font-weight: 700; color: var(--dark); font-size: 15px; }
.review-meta { font-size: 13px; color: var(--gray-600); margin-top: 1px; }
/* Aggregate line above the grid: "4.9  ★★★★★  from 47 reviews" */
.review-summary { display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap; margin-top: 18px; }
.review-summary .score { font-size: 30px; font-weight: 800; color: var(--dark); letter-spacing: -0.02em; }
.review-summary .stars { display: flex; gap: 3px; }
.review-summary .stars svg { width: 20px; height: 20px; color: var(--accent); }
.review-summary .count { color: var(--gray-600); font-size: 15px; }

/* ── Gallery ─────────────────────────────────────────────────────────────
   Owner-uploaded photos only — no captions and no service labels, so the
   dark bottom gradient the reference used purely for caption legibility is
   intentionally gone. Tiles are uniform 4:3 crops with a hover zoom. */
.gallery { display: grid; grid-template-columns: 1fr; gap: 24px; }
@media (min-width: 640px) { .gallery { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .gallery { grid-template-columns: repeat(3, 1fr); } }
.gallery-item { position: relative; aspect-ratio: 4 / 3; border-radius: 12px; overflow: hidden; background: var(--gray-200); }
.gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform .3s; }
.gallery-item:hover img { transform: scale(1.05); }

/* The full gallery page. Denser than the home teaser — you came here to look
   at the work, so more of it fits on screen. */
.gallery-full { gap: 18px; }
@media (min-width: 640px) { .gallery-full { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .gallery-full { grid-template-columns: repeat(3, 1fr); } }
.gallery-full .gallery-item { cursor: zoom-in; }

/* Home page: the link through to everything, shown only when there IS more. */
.gallery-more { text-align: center; margin-top: 36px; }

/* Lightbox. No library — a strict CSP on a generated static site blocks
   external scripts, and one bigger picture does not need one. */
.lightbox {
  display: none; position: fixed; inset: 0; z-index: 1000;
  background: rgba(9, 12, 18, .92);
  align-items: center; justify-content: center; padding: 28px;
}
.lightbox.open { display: flex; }
.lightbox img {
  max-width: min(1100px, 100%); max-height: 100%;
  object-fit: contain; border-radius: 10px;
  box-shadow: 0 30px 80px rgba(0,0,0,.5);
}
.lightbox-close {
  position: absolute; top: 18px; right: 22px;
  background: none; border: none; color: #fff;
  font-size: 40px; line-height: 1; cursor: pointer; opacity: .75;
}
.lightbox-close:hover { opacity: 1; }
/* A photo opening with no warning is jarring for anyone who asked not to see
   motion. */
@media (prefers-reduced-motion: reduce) {
  .gallery-item img { transition: none; }
  .gallery-item:hover img { transform: none; }
}

/* ── Blog index ────────────────────────────────────────────────────────
   Posts are written and published manually from the dashboard; the generator
   re-renders these as flat HTML so every post is crawlable on the client's
   own domain (a JS-loaded or off-domain blog earns no SEO value). */
.post-grid { display: grid; grid-template-columns: 1fr; gap: 28px; }
@media (min-width: 700px) { .post-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .post-grid { grid-template-columns: repeat(3, 1fr); } }
.post-card {
  display: flex; flex-direction: column; background: var(--white);
  border: 1px solid var(--gray-100); border-radius: 14px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(0,0,0,.05); transition: transform .18s, box-shadow .18s;
}
.post-card:hover { transform: translateY(-3px); box-shadow: 0 16px 32px -14px rgba(0,0,0,.16); }
.post-thumb { aspect-ratio: 16 / 9; background: var(--gray-200); overflow: hidden; }
.post-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .3s; }
.post-card:hover .post-thumb img { transform: scale(1.04); }
.post-body { padding: 24px 24px 26px; display: flex; flex-direction: column; flex: 1; }
.post-meta { font-size: 13px; color: var(--gray-600); margin-bottom: 10px; }
.post-card h2 { font-size: 19px; font-weight: 700; line-height: 1.35; margin-bottom: 10px; }
.post-card h2 a:hover { color: var(--accent-ink); }
.post-excerpt { color: var(--gray-600); font-size: 15px; line-height: 1.65; margin-bottom: 16px; flex: 1; }
.post-more { color: var(--accent-ink); font-weight: 600; font-size: 14.5px; }

/* ── Single post ───────────────────────────────────────────────────────
   Long-form reading: a ~68ch measure, generous leading, and real spacing
   between blocks. Anything wider than this gets tiring to read. */
.article { max-width: 760px; margin: 0 auto; min-width: 0; }
.article-head { margin-bottom: 30px; }
.article-head h1 { font-size: 32px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.2; margin-bottom: 14px; }
@media (min-width: 640px) { .article-head h1 { font-size: 40px; } }
.article-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; color: var(--gray-600); font-size: 14.5px; }

/* ── Post banner + sticky aside ───────────────────────────────────────────
   The title sits in the banner now. The banner's own h1 rule centres it,
   which is right for a section title and wrong for an article headline, so
   the post banner overrides the alignment and the measure. */
.post-banner { padding-bottom: 44px; text-align: left; }
.post-banner .container { max-width: 940px; }
.post-banner h1 { font-size: 30px; line-height: 1.22; margin-top: 14px; max-width: 22ch; }
@media (min-width: 640px) { .post-banner h1 { font-size: 40px; max-width: 26ch; } }
.post-banner .crumbs { justify-content: flex-start; }
.article-meta.on-dark { color: var(--gray-300); margin-top: 16px; }
.article-meta.on-dark .dot { background: var(--gray-600); }

.post-layout { display: grid; gap: 40px; align-items: start; }
@media (min-width: 1024px) {
  .post-layout { grid-template-columns: minmax(0, 1fr) 320px; gap: 48px; }
  /* The 760px measure is for a centred, full-width article. In the two-column
     layout the column already sets the measure, so keeping it would leave a
     strip of dead space between the text and the card. */
  .post-layout .article { margin: 0; max-width: none; }
  /* Sticky rather than fixed, so it stops at the end of the article instead of
     floating over the footer. 92px clears the fixed header. */
  .post-aside { position: sticky; top: 92px; }
}
.post-aside { display: flex; flex-direction: column; gap: 16px; }
.post-cta { background: var(--dark); border-radius: 14px; padding: 24px 22px; }
.post-cta h2 { color: #fff; font-size: 20px; font-weight: 800; letter-spacing: -0.01em; }
.post-cta p { color: var(--gray-300); font-size: 14px; line-height: 1.6; margin: 8px 0 18px; }
.post-cta .btn { width: 100%; }
.post-cta-call {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  margin-top: 10px; padding: 12px 16px; border-radius: 6px;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.16);
  color: #fff; font-weight: 700; font-size: 15px; white-space: nowrap;
}
.post-cta-call:hover { background: rgba(255,255,255,.13); }
.post-cta-call svg { width: 17px; height: 17px; color: var(--accent); flex-shrink: 0; }
.post-about { background: var(--light); border: 1px solid var(--gray-200); border-radius: 14px; padding: 20px 22px; }
.post-about .lbl {
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--gray-400); margin-bottom: 8px;
}
.post-about p { font-size: 14px; line-height: 1.65; color: var(--gray-600); }
.post-about-link { display: inline-block; margin-top: 12px; color: var(--accent-ink); font-weight: 700; font-size: 14px; }
.article-meta .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--gray-300); }
.article-hero { border-radius: 16px; overflow: hidden; aspect-ratio: 16 / 9; background: var(--gray-200); margin-bottom: 34px; }
.article-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }

.article-body { color: var(--gray-700); font-size: 17px; line-height: 1.75; }
.article-body > * + * { margin-top: 22px; }
.article-body h2 { font-size: 25px; font-weight: 800; color: var(--dark); letter-spacing: -0.02em; margin-top: 40px; }
.article-body h3 { font-size: 20px; font-weight: 700; color: var(--dark); margin-top: 32px; }
.article-body ul, .article-body ol { padding-left: 22px; }
.article-body li { margin-bottom: 10px; }
.article-body ul li { list-style: disc; }
.article-body ol li { list-style: decimal; }
.article-body a { color: var(--accent-ink); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.article-body strong { color: var(--dark); font-weight: 700; }
.article-body blockquote {
  border-left: 3px solid var(--accent); padding: 4px 0 4px 20px;
  color: var(--dark); font-size: 18px; font-style: italic;
}
.article-body img { width: 100%; border-radius: 12px; }

/* ── Contact ─────────────────────────────────────────────────────────── */
.contact-grid { display: grid; grid-template-columns: 1fr; gap: 40px; max-width: 1024px; margin: 0 auto; }
@media (min-width: 1024px) { .contact-grid { grid-template-columns: repeat(5, 1fr); } }
.form-card {
  background: var(--white); border-radius: 16px; border: 1px solid var(--gray-100);
  box-shadow: 0 1px 2px rgba(0,0,0,.05); padding: 24px;
}
@media (min-width: 640px) { .form-card { padding: 32px; } }
@media (min-width: 1024px) { .form-card { grid-column: span 3; } }
/* Heading inside the form card, so the form itself announces what it is. */
.form-head { margin-bottom: 22px; }
.form-head h2 { font-size: 22px; font-weight: 800; color: var(--dark); letter-spacing: -0.02em; }
.form-head p { margin-top: 6px; color: var(--gray-600); font-size: 15px; }
/* On the success state, drop the form heading so it doesn't sit above the
   "Request Sent!" confirmation. */
.form-card:has(.form-success.show) .form-head { display: none; }
/* The row's own gap handles the space between its two fields; the inner fields
   must NOT also carry margin-bottom, or stacked mobile fields get a double gap
   (row-gap + margin) and look far apart. */
.form-row { display: grid; grid-template-columns: 1fr; gap: 18px; margin-bottom: 18px; }
@media (min-width: 640px) { .form-row { grid-template-columns: repeat(2, 1fr); } }
.form-row .field { margin-bottom: 0; }
.field { margin-bottom: 18px; }
.field label { display: block; font-size: 14px; font-weight: 600; color: var(--dark); margin-bottom: 6px; }
.field input, .field select, .field textarea {
  width: 100%; padding: 10px 16px; border: 1px solid var(--gray-300); border-radius: 6px;
  font-family: inherit; font-size: 16px; color: var(--dark); background: #fff;
  transition: box-shadow .15s, border-color .15s;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: transparent; box-shadow: 0 0 0 2px var(--accent);
}
.field textarea { resize: none; min-height: 108px; }
.form-status { font-size: 14px; margin-bottom: 12px; min-height: 18px; }
.form-status.err { color: #dc2626; }
/* Success panel replaces the form, mirroring the reference's state swap. */
.form-success { display: none; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 64px 0; }
.form-success.show { display: flex; }
.form-success .tick { width: 64px; height: 64px; border-radius: 9999px; background: #dcfce7; display: flex; align-items: center; justify-content: center; margin-bottom: 16px; }
.form-success .tick svg { width: 32px; height: 32px; color: #16a34a; }
.form-success h3 { font-size: 20px; font-weight: 700; margin-bottom: 8px; }
.form-success p { color: var(--gray-600); max-width: 384px; }
.form-success button { margin-top: 24px; background: none; border: 0; color: var(--accent-ink); font-weight: 600; cursor: pointer; font-family: inherit; font-size: 16px; }
.form-success button:hover { text-decoration: underline; }

.contact-side { display: flex; flex-direction: column; gap: 20px; }
@media (min-width: 1024px) { .contact-side { grid-column: span 2; } }
.info-card { background: var(--dark); color: #fff; border-radius: 16px; padding: 24px; }
@media (min-width: 640px) { .info-card { padding: 32px; } }
.info-card h3 { color: #fff; font-size: 20px; font-weight: 700; margin-bottom: 20px; }
.info-row { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.info-row:last-child { margin-bottom: 0; }
.info-ic { width: 40px; height: 40px; border-radius: 8px; background: var(--accent-20); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.info-ic svg { width: 20px; height: 20px; color: var(--accent); }
.info-row .lbl { font-size: 12px; color: var(--gray-400); }
.info-row .val { font-weight: 600; color: #fff; word-break: break-word; transition: color .15s; }
a.info-row:hover .val { color: var(--accent); }
/* "Find Us" — social links inside the dark Contact Info card. The generator
   emits only the platforms that actually have a URL, so a business with just
   a Facebook page renders one icon rather than dead placeholders. */
.find-us { margin-top: 24px; padding-top: 20px; border-top: 1px solid rgba(255,255,255,.1); }
.find-us .lbl { font-size: 12px; color: var(--gray-400); margin-bottom: 12px; }
.social-row { display: flex; gap: 12px; }
.social-row a {
  width: 40px; height: 40px; border-radius: 8px; background: var(--accent-20);
  display: flex; align-items: center; justify-content: center;
  transition: background-color .15s;
}
.social-row a:hover { background: var(--accent); }
.social-row svg { width: 20px; height: 20px; color: var(--accent); transition: color .15s; }
.social-row a:hover svg { color: #fff; }

.area-info-card { background: var(--white); border-radius: 16px; border: 1px solid var(--gray-100); padding: 24px; flex: 1; }
@media (min-width: 640px) { .area-info-card { padding: 32px; } }
.area-info-card h3 { font-size: 20px; font-weight: 700; margin-bottom: 12px; }
.area-info-card p { font-size: 14px; color: var(--gray-600); line-height: 1.625; margin-bottom: 16px; }
.area-info-card .link { color: var(--accent-ink); font-weight: 600; font-size: 14px; }
.area-info-card .link:hover { text-decoration: underline; }

/* ── Footer (pure black) ─────────────────────────────────────────────── */
.site-footer { background: var(--black); color: var(--gray-400); }
.site-footer .container { padding-top: 64px; padding-bottom: 64px; }
.footer-grid { display: grid; grid-template-columns: 1fr; gap: 40px; }
@media (min-width: 640px) { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .footer-grid { grid-template-columns: repeat(4, 1fr); } }
.footer-brand-name { font-size: 20px; font-weight: 700; color: #fff; margin-bottom: 12px; }
.footer-brand-name .accent { color: var(--accent); }
.footer-blurb { font-size: 14px; line-height: 1.625; }
.footer-col h3 { color: #fff; font-weight: 600; font-size: 16px; margin-bottom: 14px; }
.footer-col li { margin-bottom: 0; }
/* Every footer column is one list read alongside the others, so the row rhythm
   is defined ONCE here and both the links and the service-area text take it.
   Stating it per column is how they drifted apart: the areas were a grid with
   its own row-gap and were inheriting the footer's 16px against the links'
   14px, so the two columns beside each other used different type AND a
   different pitch.
   The 1.4 line-height matters too — the body's 1.6 adds ~8px of leading per
   row, which is what made these columns tall in the first place. */
.footer-col a,
.footer-areas span {
  display: inline-block; font-size: 14px; line-height: 1.4; padding: 3px 0;
  word-break: break-word;
}
.footer-col a { transition: color .15s; }
.footer-col a:hover { color: var(--accent); }
/* Not links any more — they never went anywhere but /contact#areas. */
.footer-areas span { color: var(--gray-400); }
/* No row-gap: the padding above IS the spacing, and adding gap on top of it
   made every area row 2px taller than every service row next to it. */
.footer-areas { display: grid; grid-template-columns: repeat(2, 1fr); column-gap: 16px; row-gap: 0; }
.footer-col a.footer-cta { display: inline-block; margin-top: 8px; background: var(--accent); color: #fff; font-weight: 600; padding: 10px 20px; line-height: 1.2; border-radius: 6px; transition: background-color .15s; }
.footer-cta:hover { background: var(--accent-dark); color: #fff; }
.footer-bottom { border-top: 1px solid var(--gray-800); margin-top: 48px; padding-top: 32px; font-size: 14px; text-align: center; }
@media (max-width: 767px) {
  .footer-grid { gap: 24px; }
  .footer-col h3 { margin-bottom: 8px; }
  /* Both, or neither. This gave the links 4px and left the service areas on 3,
     which put the two columns 2px per row out of step on phones — the last
     place they were still misaligned after everything else was shared. */
  .footer-col a,
  .footer-areas span { padding: 4px 0; }
}

/* ── Mobile sticky call bar ────────────────────────────────────────────
   Always-visible tap-to-call bar pinned to the bottom on phones, so the
   number is reachable no matter how far the visitor has scrolled. Hidden on
   desktop, where the header CTA and contact card already cover it. */
/* Runs up to 1023px, not 767px: between those widths the nav is showing but is
   too tight to carry the number as well, so without this a tablet had no phone
   number anywhere above the footer. */
.mobile-call-bar { display: none; }
@media (max-width: 1023px) {
  /* A floating pill, not a bar welded to the bottom edge.
     Edge-to-edge and flush to the bottom, this butted straight into whatever
     the browser draws below it — on Safari that is a toolbar, and the two read
     as one tall block however slim the bar itself got. Detaching it from all
     three edges fixes that structurally rather than by shaving pixels: there is
     always a strip of page visible underneath, so the pill is obviously ours
     and the browser's chrome is obviously the browser's.
     It also stops mattering what any given browser draws down there, which was
     the other half of the problem — every one does it differently and they
     change it between versions. */
  .mobile-call-bar {
    display: flex; position: fixed; z-index: 60;
    left: 16px; right: 16px;
    bottom: calc(14px + env(safe-area-inset-bottom, 0px));
    align-items: center; justify-content: center; gap: 9px;
    background: var(--accent); color: #fff; font-weight: 700; font-size: 15px;
    /* 6px, the same as every .btn on the site. A fully rounded pill read as a
       different kind of control from the buttons it sits among. */
    padding: 13px 20px; border-radius: 6px;
    /* Reads as floating above the page rather than pinned to it. */
    box-shadow: 0 6px 20px rgba(0,0,0,.32), 0 2px 6px rgba(0,0,0,.2);
  }
  .mobile-call-bar svg { width: 18px; height: 18px; }
  /* The pill hovers over the page, so the last thing on it needs somewhere to
     go — without this the final footer row sits underneath and cannot be read. */
  .site-footer .container { padding-bottom: calc(64px + 62px + env(safe-area-inset-bottom, 0px)); }
  /* The pill hovers over the page, so the last thing on it needs somewhere to
     go — without this the final footer row sits underneath and cannot be read. */
}

/* ── Touch targets ───────────────────────────────────────────────────────
   Inline text links inside cards ("Get a quote", "Read more") were rendering
   ~20-22px tall. Fingers are not cursors: WCAG target-size guidance and every
   mobile platform's own guideline put the floor around 44px. Padding the link
   rather than the text keeps the desktop layout identical. */
@media (max-width: 1023px) {
  .card-link,
  .svc-link,
  .post-more,
  .area-note a,
  .area-info-card .link,
  .crumbs a {
    display: inline-flex; align-items: center;
    min-height: 44px;
  }
  /* Footer links need NO extra floor here. The shared base rule already gives
     every footer row 25.6px (14px x 1.4 plus 3px of padding either side),
     which clears WCAG 2.2's 24px minimum. Adding one on top only applied to
     the links, which put them 2px out of step with the service areas beside
     them — the exact mismatch this was meant to fix. 44px is the platform
     guideline for a PRIMARY control, and a footer nav link is not one. */
  .brand { min-height: 48px; justify-content: center; }
  .social-row a { min-width: 44px; min-height: 44px; }
  /* The menu button was a 28px icon in 8px of padding. */
  .nav-toggle { min-width: 44px; min-height: 44px; }
  .nav-mobile a { min-height: 44px; display: flex; align-items: center; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .gallery-item:hover img { transform: none; }
  html { scroll-behavior: auto; }
}
