/* ============================================================
   Townline — Home Services client template
   Reusable base for landscaping / plumbing / electrical / HVAC /
   roofing / painting / masonry / contracting / cleaning / tree
   service / auto repair / pest control clients.

   Deliberately NOT the Townline brand — this is the CLIENT's site.
   Demo content below is a fictional example: "Ridgeline Landscaping".
   To reuse for a real client, see the checklist comment at the top
   of index.html.
   ============================================================ */

:root {
  --ink: #1A2433;
  --ink-muted: #5C6675;
  --bg: #F5F7FA;
  --surface: #FFFFFF;
  --surface-alt: #EAEFF4;
  --primary: #1E4B72;
  --primary-strong: #163A5A;
  --primary-contrast: #FFFFFF;
  --accent: #E2622F;
  --accent-strong: #C24F22;
  --star: #E0A93A;
  --line: #DCE2E8;
  --shadow: rgba(20, 30, 45, 0.14);

  --font-heading: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', Consolas, monospace;

  --radius: 4px;
  --radius-lg: 6px;

  --max: 1120px;
}

/* Deliberately no prefers-color-scheme dark-mode block here. The per-business
   theme system (see previews/generate_previews.py THEMES) only overrides
   --primary/--accent/--radius/--font per client — it doesn't define a dark
   palette per theme. A generic dark override previously fought with that
   system (wrong ink/bg/surface against the client's real primary/accent) and
   broke real preview pages for any visitor with OS dark mode on. If dark mode
   support is wanted later, it needs a dark variant defined per THEME entry,
   not one global override.*/

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.6;
  margin: 0;
}

a { color: var(--primary); }
a:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
img { max-width: 100%; display: block; }

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 1.5rem; }

h1, h2, h3 { text-wrap: balance; font-family: var(--font-heading); }

/* ---------- Townline preview banner (uses Townline's own brand colors,
   deliberately distinct from the site palette below, to signal this
   strip is Townline speaking, not the business) ---------- */
.preview-banner-strip { background: #1F4438; color: #F4EFDD; padding: 0.65rem 0; font-size: 0.85rem; }
.preview-banner-strip .wrap { display: flex; align-items: center; justify-content: center; gap: 1rem; flex-wrap: wrap; text-align: center; }
.preview-banner-strip strong { font-weight: 700; }
.preview-banner-strip a.claim-btn {
  background: #A6462A; color: #fff; padding: 0.35rem 0.9rem; border-radius: 3px;
  text-decoration: none; font-weight: 700; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em;
}
.preview-banner-strip a.claim-btn:hover { background: #8A3A22; }

/* ---------- Top utility bar ---------- */
.top-bar {
  background: var(--primary-strong);
  color: var(--primary-contrast);
  font-size: 0.85rem;
}
.top-bar .wrap {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 1.5rem;
  gap: 1rem;
  flex-wrap: wrap;
}
.top-bar a { color: var(--primary-contrast); text-decoration: none; font-weight: 600; }
.top-bar .badges { display: flex; gap: 1.25rem; opacity: 0.92; }

/* ---------- Header ---------- */
.site-header { background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 10; }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1.5rem; gap: 1rem; }
.logo {
  display: inline-flex; align-items: center; gap: 0.5rem; font-family: var(--font-heading); font-weight: 800;
  font-size: 1.35rem; color: var(--ink); text-decoration: none; letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; max-width: 100%;
}
.logo span { color: var(--primary); }
.logo-icon { width: 1.35rem; height: 1.35rem; flex-shrink: 0; color: var(--accent); }

/* Image-based logo (opt-in via logo_image) — real client artwork instead of
   the text lockup. Sized to the header's own line-height rather than the
   text logo's font-size, and freed from the text logo's nowrap/ellipsis
   rules (irrelevant for an <img>). */
.logo.logo-has-image { white-space: normal; overflow: visible; }
.logo-image { height: 3.6rem; width: auto; max-width: 100%; display: block; }
@media (max-width: 780px) { .logo-image { height: 2.6rem; } }

.nav-toggle { display: none; background: none; border: none; cursor: pointer; padding: 0.4rem; }

.site-nav ul { list-style: none; display: flex; gap: 1.5rem; margin: 0; padding: 0; align-items: center; }
.site-nav a { font-weight: 600; font-size: 0.95rem; color: var(--ink); text-decoration: none; }
.site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--primary); }
.nav-cta {
  background: var(--accent);
  color: #fff;
  padding: 0.6rem 1.1rem;
  border-radius: var(--radius);
  font-weight: 700;
  text-decoration: none;
}
.nav-cta:hover { background: var(--accent-strong); color: #fff; }

@media (max-width: 780px) {
  .nav-toggle { display: block; }
  .logo { font-size: 0.98rem; }
  .site-nav { display: none; position: absolute; top: 100%; left: 0; right: 0; background: var(--surface); border-bottom: 1px solid var(--line); box-shadow: 0 8px 16px var(--shadow); }
  .site-nav.open { display: block; }
  .site-nav ul { flex-direction: column; align-items: stretch; gap: 0; padding: 0.5rem 0; }
  .site-nav li { padding: 0; }
  .site-nav a { display: block; padding: 0.9rem 1.5rem; }
  .site-nav .nav-cta { margin: 0.75rem 1.5rem; text-align: center; }
  .top-bar .wrap { flex-direction: column; align-items: flex-start; gap: 0.3rem; }
}

/* ---------- Header structural variants ---------- */

/* Style B "clean-cta" (M&M Auto Mechanic): a thin, subtle dark announcement
   bar carries the address and rating above a clean primary-colored header —
   just logo, nav links, and a single "Call Now" CTA. Replaces the old
   cluttered treatment that packed phone + two badges into the header itself
   alongside the nav CTA. */
.announcement-bar { background: var(--ink); color: rgba(255,255,255,0.72); font-size: 0.78rem; }
.announcement-bar .wrap { display: flex; justify-content: center; gap: 2rem; padding: 0.45rem 1.5rem; flex-wrap: wrap; }
.announcement-item { display: inline-flex; align-items: center; gap: 0.4rem; }
.announcement-icon { width: 0.85rem; height: 0.85rem; flex-shrink: 0; opacity: 0.85; }
@media (max-width: 780px) { .announcement-bar .wrap { gap: 1rem; justify-content: flex-start; } }

.site-header.style-b { background: var(--primary); border-bottom: none; }
.site-header.style-b .logo { color: #fff; }
.site-header.style-b .logo span { color: rgba(255,255,255,0.75); }
.site-header.style-b .site-nav a { color: rgba(255,255,255,0.85); }
.site-header.style-b .site-nav a:hover, .site-header.style-b .site-nav a[aria-current="page"] { color: #fff; }
.site-header.style-b .nav-toggle { color: #fff; }
@media (max-width: 780px) {
  .site-header.style-b .site-nav { background: var(--primary-strong); border-bottom: none; }
  .site-header.style-b .site-nav a { color: #fff; }
}

/* Style C "centered": logo on its own centered row, full nav centered below
   it — a two-row header instead of one split row. Falls back to the
   standard mobile pattern under 780px. */
@media (min-width: 781px) {
  .site-header.style-c .wrap { flex-direction: column; gap: 0.6rem; padding: 1.1rem 1.5rem 1.25rem; }
  .site-header.style-c .site-nav ul { justify-content: center; }
}

/* Style D "minimal": no top-bar; phone appears as a plain nav link instead
   of a badge strip. Quieter than the default. */
.site-header.style-d .nav-phone-item a { font-weight: 600; }

/* ---------- Hero ---------- */
/* This rule is the gradient-only fallback for a business with no photo yet.
   Businesses with a hero_image (generate_previews.py) get the full
   background-image (gradient + photo) set inline instead of through a
   --hero-image custom property — a url() inside a custom property resolves
   relative to the STYLESHEET it's read in, not the HTML page, so that
   approach silently broke relative image paths. The gradient itself is
   built from each business's own theme color via color-mix(), not a fixed
   dark overlay, so the tint always matches that business's palette. */
.hero {
  background-image: linear-gradient(135deg, color-mix(in srgb, var(--primary) 88%, transparent) 0%, color-mix(in srgb, var(--primary-strong) 82%, transparent) 100%), var(--hero-image, none);
  background-size: cover;
  background-position: center;
  background-color: var(--primary);
  color: #fff;
  position: relative;
  padding: 4.5rem 0 6rem;
  clip-path: polygon(0 0, 100% 0, 100% 92%, 0 100%);
}
.hero .wrap { position: relative; z-index: 1; }
.hero h1 { font-size: clamp(2rem, 5vw, 3rem); font-weight: 800; line-height: 1.08; margin: 0 0 1rem; max-width: 20ch; letter-spacing: -0.01em; }
.hero h1 .highlight { color: var(--accent); }
.hero.layout-framed h1 .highlight { color: var(--accent); }
.hero p { font-size: 1.15rem; color: rgba(255,255,255,0.88); max-width: 48ch; margin: 0 0 2rem; }
.hero-ctas { display: flex; gap: 1rem; flex-wrap: wrap; }

/* Hero kicker (opt-in via hero_kicker): a small styled line above the
   headline for a "master authority" statement instead of a casual pill. */
.hero-kicker {
  font-family: var(--font-heading); font-size: 1.05rem; font-weight: 600; font-style: italic;
  letter-spacing: 0.01em; color: var(--accent); margin: 0 0 0.85rem;
}

/* Heritage seal (opt-in via heritage_seal): a small emblem badge, e.g. an
   "Est. 1980" mark, instead of a plain stat pill. */
.heritage-seal {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  width: 5.5rem; height: 5.5rem; border-radius: 50%; border: 2px solid var(--accent);
  background: rgba(255,255,255,0.06); text-align: center; margin-top: 1.75rem;
}
.heritage-seal-year { font-family: var(--font-heading); font-weight: 700; font-size: 1rem; color: var(--accent); }
.heritage-seal-label {
  font-size: 0.58rem; text-transform: uppercase; letter-spacing: 0.06em; color: rgba(255,255,255,0.85);
  margin-top: 0.2rem; line-height: 1.2; padding: 0 0.5rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 0.98rem;
  padding: 0.85rem 1.5rem;
  border-radius: var(--radius);
  text-decoration: none;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.btn-accent { background: var(--accent); color: #fff; box-shadow: 0 2px 8px rgba(0,0,0,0.12); }
.btn-accent:hover { background: var(--accent-strong); transform: translateY(-2px); box-shadow: 0 8px 18px rgba(0,0,0,0.18); }
.btn-outline { background: transparent; color: #fff; border-color: rgba(255,255,255,0.7); }
.btn-outline:hover { background: rgba(255,255,255,0.12); transform: translateY(-2px); }
.btn-primary { background: var(--primary); color: #fff; box-shadow: 0 2px 8px rgba(0,0,0,0.12); }
.btn-primary:hover { background: var(--primary-strong); transform: translateY(-2px); box-shadow: 0 8px 18px rgba(0,0,0,0.18); }

/* ---------- Credentials bar (opt-in via credentials_bar) ---------- */
.credentials-bar { background: var(--surface-alt); border-bottom: 1px solid var(--line); padding: 1rem 0; }
.credentials-bar .wrap { display: flex; flex-wrap: wrap; justify-content: center; gap: 2.5rem; }
.credential-item { display: flex; align-items: center; gap: 0.6rem; font-size: 0.86rem; font-weight: 600; color: var(--ink); }
.credential-icon { width: 1.2rem; height: 1.2rem; color: var(--accent); flex-shrink: 0; }
@media (max-width: 780px) { .credentials-bar .wrap { gap: 1.25rem; justify-content: flex-start; } }

/* ---------- Trust strip ---------- */
.trust-strip { margin-top: -3.25rem; position: relative; z-index: 2; }
.trust-strip .wrap {
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: 0 12px 30px var(--shadow);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
  padding: 1.5rem;
}
.trust-item { text-align: center; padding: 0.5rem; }
.trust-item strong { display: block; font-family: var(--font-heading); font-size: 1.15rem; color: var(--ink); }
.trust-item span { font-size: 0.85rem; color: var(--ink-muted); }
.stars { color: var(--star); letter-spacing: 0.05em; }

/* Elevated trust strip: icon above each stat, vertical dividers between
   columns, so it reads as one structured unit instead of plain text
   floating across the seam between hero and page. */
.trust-strip-elevated .wrap { padding: 1.75rem 1.5rem; }
.trust-strip-elevated .trust-item { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; }
.trust-strip-elevated .trust-icon { width: 1.5rem; height: 1.5rem; color: var(--accent); }
@media (min-width: 561px) {
  .trust-strip-elevated .trust-item:not(:first-child) { border-left: 1px solid var(--line); }
}

/* ---------- Hero layout variants (structural, not just color) ---------- */

/* "split": straight-edge hero, two columns — copy left, a bordered fact
   card right. Trust info lives inside the hero, no floating strip after. */
.hero.layout-split { clip-path: none; padding: 4rem 0; }
.hero.layout-split .hero-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: 2.5rem; align-items: center; }
.hero.layout-split .fact-card { background: var(--surface); border-radius: var(--radius-lg); padding: 1.5rem 1.75rem; box-shadow: 0 12px 30px var(--shadow); }
.hero.layout-split .fact-card .trust-item { text-align: left; padding: 0.7rem 0; border-bottom: 1px solid var(--line); }
.hero.layout-split .fact-card .trust-item:last-child { border-bottom: none; }
@media (max-width: 780px) { .hero.layout-split .hero-grid { grid-template-columns: 1fr; } }

/* Urgent badge above the headline (opt-in via urgent_badge) */
.urgent-badge {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.25);
  color: #fff; font-size: 0.82rem; font-weight: 600;
  padding: 0.45rem 1rem; border-radius: 999px; margin-bottom: 1.25rem;
}
.urgent-dot {
  width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent);
  flex-shrink: 0;
}
.urgent-badge.on-light { background: var(--surface-alt); border-color: var(--line); color: var(--ink); }

/* ---------- Two-panel hero (opt-in via layout="twopanel") — a true 50/50
   split, not a shared photo backdrop: clean left panel + a dark
   self-contained diagnostic intake card on the right. ---------- */
.hero.layout-twopanel { background: var(--surface); color: var(--ink); clip-path: none; padding: 0; }
.hero.layout-twopanel .twopanel-grid { display: grid; grid-template-columns: 1fr 1fr; min-height: 560px; }
.hero.layout-twopanel .twopanel-left { padding: 4rem 3rem; display: flex; flex-direction: column; justify-content: center; }
.hero.layout-twopanel .twopanel-right { background: var(--primary); padding: 4rem 3rem; display: flex; align-items: center; justify-content: center; }
.hero.layout-twopanel h1 { color: var(--ink); }
.hero.layout-twopanel p { color: var(--ink-muted); }
.hero.layout-twopanel .btn-accent { align-self: flex-start; margin-bottom: 2rem; }
.trust-badge-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.trust-badge-list li { display: flex; align-items: center; gap: 0.75rem; font-weight: 600; color: var(--ink); font-size: 0.95rem; }
.trust-badge-list-icon { width: 1.3rem; height: 1.3rem; color: var(--accent); flex-shrink: 0; }
.diagnostic-card { background: var(--surface); border-radius: var(--radius-lg); padding: 2rem; width: 100%; max-width: 420px; box-shadow: 0 16px 40px rgba(0,0,0,0.3); }
.diagnostic-eyebrow { font-family: var(--font-heading); font-weight: 700; font-size: 0.95rem; color: var(--ink); margin: 0 0 1rem; }
.diagnostic-form { display: flex; flex-direction: column; gap: 1rem; }
.diagnostic-form input[type="tel"] { width: 100%; }
@media (max-width: 900px) {
  .hero.layout-twopanel .twopanel-grid { grid-template-columns: 1fr; min-height: 0; }
  .hero.layout-twopanel .twopanel-left { padding: 3rem 1.5rem 2.5rem; }
  .hero.layout-twopanel .twopanel-right { padding: 2.5rem 1.5rem 3rem; }
}

/* Dispatch card (opt-in via dispatch_card): replaces the plain vertical
   trust-fact list with a call-to-action card — one-tap call button, a row
   of clickable service pills, and a short availability note. */
.dispatch-card { background: var(--surface); border-radius: var(--radius-lg); padding: 1.75rem; box-shadow: 0 12px 30px var(--shadow); }
.dispatch-eyebrow { font-family: var(--font-heading); font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted); font-weight: 700; margin: 0 0 1rem; }
.dispatch-call { width: 100%; justify-content: center; margin-bottom: 1.25rem; }
.dispatch-phone-icon { width: 1.1rem; height: 1.1rem; }
.dispatch-pills { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.dispatch-pill {
  flex: 1 1 auto; text-align: center; font-size: 0.85rem; font-weight: 600; color: var(--ink);
  border: 1px solid var(--line); border-radius: 999px; padding: 0.55rem 1rem; text-decoration: none;
  transition: all 0.15s ease;
}
.dispatch-pill:hover { background: var(--surface-alt); border-color: var(--primary); }
.dispatch-note { margin: 1.1rem 0 0; font-size: 0.82rem; color: var(--ink-muted); text-align: center; }

/* "framed": hero sits on the page background, not full-bleed color — a
   bordered card with a top accent bar, trust facts as a chip row. Calmer,
   more document-like than the bold color-block layouts. */
/* A background-image wash was tried here first (twice) and never read well —
   this layout's photo was fighting a light page background no matter how
   light the tint got, especially with a bright/low-contrast source photo.
   Fix: stop blending the photo into the background at all. It's now a real,
   fully-saturated image panel next to the text, not an atmospheric wash. */
.hero.layout-framed {
  background: var(--bg);
  color: var(--ink); clip-path: none; padding: 5rem 0;
}
.hero.layout-framed .wrap { display: grid; grid-template-columns: 1.1fr 1fr; gap: 3rem; align-items: center; }
.hero.layout-framed .frame-card { background: var(--surface); border: 1px solid var(--line); border-top: 6px solid var(--accent); border-radius: var(--radius-lg); padding: 2.5rem; box-shadow: 0 8px 24px var(--shadow); }
.hero.layout-framed .framed-photo {
  background-size: cover;
  background-position: center;
  border-radius: var(--radius-lg);
  min-height: 380px;
  box-shadow: 0 16px 36px var(--shadow);
}
@media (max-width: 780px) {
  .hero.layout-framed .wrap { grid-template-columns: 1fr; }
  .hero.layout-framed .framed-photo { order: -1; min-height: 220px; }
}
.hero.layout-framed h1 { color: var(--ink); }
.hero.layout-framed p { color: var(--ink-muted); }
.hero.layout-framed .chip-row { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.75rem; }
.hero.layout-framed .chip { background: var(--surface-alt); border: 1px solid var(--line); border-radius: 999px; padding: 0.45rem 1rem; font-size: 0.85rem; font-weight: 700; color: var(--ink); }
.hero.layout-framed .chip strong { color: var(--primary); margin-right: 0.35rem; }
.hero.layout-framed .btn-outline { color: var(--ink); border-color: var(--line); }
.hero.layout-framed .btn-outline:hover { background: var(--surface-alt); }

/* ---------- Interior page header ---------- */
.page-hero { background: var(--surface-alt); padding: 3rem 0; border-bottom: 1px solid var(--line); }
.page-hero h1 { font-size: clamp(1.8rem, 4vw, 2.4rem); margin: 0 0 0.75rem; color: var(--ink); }
.page-hero p { color: var(--ink-muted); font-size: 1.05rem; max-width: 60ch; margin: 0; }

/* ---------- Sections ---------- */
.section { padding: 5rem 0 4rem; }
.section-alt { background: var(--surface-alt); }
/* Optional rich-dark section (opt-in per business) for visual rhythm between
   a light lead-capture strip and the next section, instead of always
   stepping light-gray/white/light-gray. */
.section-dark { background: var(--primary); color: rgba(255,255,255,0.92); }
.section-dark .section-head h2 { color: #fff; }
.section-dark .section-head p { color: rgba(255,255,255,0.72); }
.section-dark .eyebrow { color: var(--accent); }
.section-dark .service-card {
  background: color-mix(in srgb, var(--primary-strong) 55%, transparent);
  border-color: rgba(255,255,255,0.14);
  border-top-color: var(--accent);
}
.section-dark .service-card h3 { color: #fff; }
.section-dark .service-card p { color: rgba(255,255,255,0.72); }
.section-dark .service-card a { color: var(--accent); }
.section-head { max-width: 60ch; margin: 0 0 2.5rem; }
.eyebrow { font-family: var(--font-heading); font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); font-weight: 700; margin: 0 0 0.5rem; }
.section-head h2 { font-size: clamp(1.6rem, 3.5vw, 2.1rem); margin: 0 0 0.75rem; color: var(--ink); }
.section-head p { color: var(--ink-muted); font-size: 1.05rem; margin: 0; }

/* ---------- Services grid ---------- */
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.5rem; }
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; }

.service-card {
  background: var(--surface); border: 1px solid var(--line); border-top: 4px solid var(--primary);
  border-radius: var(--radius); padding: 1.5rem;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.service-card:hover { transform: translateY(-4px); box-shadow: 0 14px 28px var(--shadow); }
.service-card h3 { font-size: 1.05rem; margin: 0 0 0.6rem; color: var(--ink); }
.service-card p { margin: 0 0 1rem; color: var(--ink-muted); font-size: 0.95rem; }
.service-card a { font-weight: 700; font-size: 0.9rem; text-decoration: none; }
.service-card a:hover { text-decoration: underline; }
.service-card.detail { scroll-margin-top: 5.5rem; }
/* Photo service card (opt-in per service via an `image` field): a real
   background photo with a bottom-heavy dark wash instead of a plain white
   box, so "What We Do" reads as visual proof rather than a text list. */
.service-card.photo-card {
  background-size: cover; background-position: center; background-color: var(--primary-strong);
  border: none; border-radius: var(--radius-lg);
  min-height: 260px; display: flex; flex-direction: column; justify-content: flex-end; color: #fff;
}
.service-card.photo-card h3 { color: #fff; }
.service-card.photo-card p { color: rgba(255,255,255,0.85); }
.service-card.photo-card a { color: #fff; text-decoration: underline; }
.photo-card .card-tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.85rem; }
.photo-card .card-tag {
  background: rgba(255,255,255,0.15); border: 1px solid rgba(255,255,255,0.3); color: #fff;
  font-size: 0.7rem; font-weight: 600; padding: 0.25rem 0.6rem; border-radius: 999px;
}
.service-card ul { list-style: none; padding: 0; margin: 0 0 1rem; }
.service-card ul li { position: relative; padding-left: 1.5rem; margin-bottom: 0.5rem; font-size: 0.92rem; color: var(--ink-muted); }
.service-card ul li::before {
  content: ""; position: absolute; left: 0; top: 0.2em; width: 1rem; height: 1rem;
  background-color: var(--primary);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* ---------- Bento service grid (opt-in via service_grid_style="bento") ----------
   One service flagged primary=True spans a 2x2 block; the rest fill the
   remaining 2x2 area as 1x1 tiles with a line icon, instead of a uniform
   row of identical boxes. */
.bento-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(150px, auto);
  grid-auto-flow: row dense;
  gap: 1.25rem;
}
.bento-tile {
  grid-column: span 1; grid-row: span 1;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.5rem; position: relative;
  display: flex; flex-direction: column; justify-content: flex-end;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.bento-tile:hover { transform: translateY(-4px); box-shadow: 0 14px 28px var(--shadow); }
.bento-tile h3 { font-size: 1.02rem; margin: 0 0 0.5rem; color: var(--ink); }
.bento-tile p { margin: 0 0 0.85rem; color: var(--ink-muted); font-size: 0.9rem; }
.bento-tile a { font-weight: 700; font-size: 0.88rem; text-decoration: none; }
.bento-icon { width: 1.9rem; height: 1.9rem; color: var(--accent); margin-bottom: 1rem; }
.bento-primary {
  grid-column: span 2; grid-row: span 2;
  background: var(--primary); border-color: transparent; padding: 2rem;
}
.bento-primary h3 { color: #fff; font-size: 1.4rem; }
.bento-primary p { color: rgba(255,255,255,0.82); font-size: 1rem; }
.bento-primary a { color: #fff; }
.bento-badge {
  position: absolute; top: 1.25rem; right: 1.25rem;
  background: var(--accent); color: #fff; font-family: var(--font-heading); font-weight: 700;
  font-size: 0.66rem; letter-spacing: 0.07em; text-transform: uppercase;
  padding: 0.35rem 0.75rem; border-radius: 999px;
}
@media (max-width: 900px) {
  .bento-grid { grid-template-columns: repeat(2, 1fr); }
  .bento-primary { grid-column: span 2; grid-row: span 1; min-height: 220px; }
}
@media (max-width: 560px) {
  .bento-grid { grid-template-columns: 1fr; }
  .bento-tile, .bento-primary { grid-column: span 1; }
}

/* 3-column variant (opt-in via bento_columns=3) — for exactly 4 tiles (one
   primary + 3 secondary): primary spans 2 cols/1 row, and the last tile
   flagged wide=True spans 2 cols to balance the second row, instead of the
   4-column/2x2-primary layout used when there are 5 tiles. */
.bento-3col { grid-template-columns: repeat(3, 1fr); }
.bento-3col .bento-primary { grid-column: span 2; grid-row: span 1; }
.bento-3col .bento-wide { grid-column: span 2; }
@media (max-width: 900px) {
  .bento-3col { grid-template-columns: repeat(2, 1fr); }
  .bento-3col .bento-primary, .bento-3col .bento-wide { grid-column: span 2; }
}
@media (max-width: 560px) {
  .bento-3col .bento-primary, .bento-3col .bento-wide, .bento-3col .bento-tile { grid-column: span 1; }
}

/* ---------- Combined workflow + trust split (opt-in via trust_timeline_style) ---------- */
.trust-timeline-split { display: grid; grid-template-columns: 1.1fr 1fr; gap: 3rem; align-items: start; }
.timeline { position: relative; margin-top: 1.75rem; padding-left: 2.75rem; }
.timeline::before { content: ""; position: absolute; left: 1.1rem; top: 0.5rem; bottom: 0.5rem; width: 2px; background: var(--line); }
.timeline-step { position: relative; padding-bottom: 2rem; }
.timeline-step:last-child { padding-bottom: 0; }
.timeline-marker {
  position: absolute; left: -2.75rem; top: 0; width: 2.2rem; height: 2.2rem; border-radius: 50%;
  background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-heading); font-weight: 800;
}
.timeline-step h3 { margin: 0 0 0.3rem; font-size: 1.05rem; color: var(--ink); }
.timeline-step p { margin: 0; color: var(--ink-muted); font-size: 0.92rem; }
.trust-card { background: var(--primary); color: #fff; border-radius: var(--radius-lg); padding: 2rem; margin-top: 1.75rem; }
.trust-card .eyebrow { color: var(--accent); }
.trust-card h3 { color: #fff; margin: 0 0 1.5rem; }
.trust-badge { display: flex; gap: 0.9rem; align-items: flex-start; margin-bottom: 1.5rem; }
.trust-badge:last-child { margin-bottom: 0; }
.trust-badge-icon { width: 1.4rem; height: 1.4rem; flex-shrink: 0; color: var(--accent); margin-top: 0.15rem; }
.trust-badge h4 { margin: 0 0 0.2rem; color: #fff; font-size: 1rem; }
.trust-badge p { margin: 0; color: rgba(255,255,255,0.75); font-size: 0.88rem; }
@media (max-width: 780px) { .trust-timeline-split { grid-template-columns: 1fr; } }

/* ---------- Value props ---------- */
.value-item { display: flex; gap: 1rem; align-items: flex-start; }
.value-bullet {
  flex-shrink: 0;
  width: 2.25rem; height: 2.25rem;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-heading); font-weight: 800; font-size: 1rem;
}
.value-item h3 { font-size: 1.02rem; margin: 0 0 0.3rem; }
.value-item p { margin: 0; color: var(--ink-muted); font-size: 0.92rem; }

/* ---------- Process steps ("how we work") ---------- */
.process-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.75rem; counter-reset: step; }
.process-step { position: relative; padding-top: 0.25rem; }
.process-number {
  font-family: var(--font-heading); font-weight: 800; font-size: 2.2rem;
  color: var(--accent); opacity: 0.35; line-height: 1; margin-bottom: 0.5rem;
}
.process-step h3 { font-size: 1.02rem; margin: 0 0 0.4rem; color: var(--ink); }
.process-step p { margin: 0; color: var(--ink-muted); font-size: 0.92rem; }

/* Card variant (opt-in): a bordered card with a small round numeral badge,
   instead of a giant faded numeral floating on flat background — reads less
   like a manual, more like a designed step sequence. */
.process-grid-cards .process-step {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.75rem 1.5rem; box-shadow: 0 4px 14px var(--shadow);
}
.process-grid-cards .process-number {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem; border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent); opacity: 1; font-size: 1.1rem; margin-bottom: 0.9rem;
}

/* ---------- Quick estimate band (compact lead form right under the hero) ---------- */
.quick-estimate { background: var(--surface-alt); border-bottom: 1px solid var(--line); padding: 1.75rem 0; }
.quick-estimate .wrap { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; }
.quick-estimate-copy { flex: 1 1 240px; }
.quick-estimate-copy h2 { font-size: 1.15rem; margin: 0 0 0.2rem; color: var(--ink); }
.quick-estimate-copy p { margin: 0; color: var(--ink-muted); font-size: 0.9rem; }
.quick-estimate-formwrap { flex: 2 1 380px; }
.quick-estimate-form { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.quick-estimate-form input, .quick-estimate-form select {
  flex: 1 1 140px; padding: 0.7rem 0.9rem; border: 1px solid var(--line);
  border-radius: var(--radius); font-family: var(--font-body); font-size: 0.92rem;
}
.quick-estimate-form textarea {
  flex: 1 1 100%; padding: 0.7rem 0.9rem; border: 1px solid var(--line);
  border-radius: var(--radius); font-family: var(--font-body); font-size: 0.92rem;
  min-height: 2.8rem; resize: vertical;
}
.quick-estimate-form button { flex: 0 0 auto; white-space: nowrap; }
.quick-estimate-note { margin: 0.6rem 0 0; font-size: 0.78rem; color: var(--ink-muted); }

/* Elevated variant (opt-in via quick_estimate.elevated): the whole band
   sits on a light slate backdrop with the form itself in its own bordered,
   shadowed card, instead of a bare strip spanning the full page width. */
.quick-estimate-elevated { background: #F1F5F9; padding: 2.5rem 0; }
.quick-estimate-elevated .wrap {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 2rem; box-shadow: 0 12px 30px var(--shadow);
}

/* Selection chips (opt-in via quick_estimate.chip_options): radio inputs
   styled as pills instead of a free-text field or dropdown. */
.chip-group { display: flex; flex-wrap: wrap; gap: 0.6rem; flex: 1 1 100%; }
.chip-option { position: relative; }
.chip-option input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.chip-option span {
  display: inline-block; padding: 0.6rem 1.1rem; border: 1px solid var(--line); border-radius: 999px;
  font-size: 0.85rem; font-weight: 600; color: var(--ink); cursor: pointer; background: var(--surface);
  transition: all 0.15s ease;
}
.chip-option input:checked + span { background: var(--primary); border-color: var(--primary); color: #fff; }
.chip-option input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- Local FAQ (native <details>, no JS) ---------- */
.faq-list { max-width: 72ch; }
.faq-item { border-bottom: 1px solid var(--line); padding: 1.1rem 0; }
.faq-item summary {
  cursor: pointer; font-family: var(--font-heading); font-weight: 700;
  font-size: 1rem; color: var(--ink); list-style: none; display: flex;
  justify-content: space-between; align-items: center; gap: 1rem;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; font-size: 1.3rem; color: var(--accent); flex-shrink: 0; }
.faq-item[open] summary::after { content: "\2212"; }
.faq-item p { margin: 0.75rem 0 0; color: var(--ink-muted); font-size: 0.95rem; line-height: 1.6; }

/* Two-column card variant (opt-in): each FAQ in its own rounded container
   instead of one long list of lines stretching across empty space. */
.faq-list-cards { max-width: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 1rem; }
.faq-list-cards .faq-item { border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 1.25rem 1.5rem; background: var(--surface); }

/* Boxed two-column variant (opt-in): the whole FAQ list sits inside one
   light-gray bounded container instead of stretching full-width. */
.faq-list-boxed {
  max-width: none; background: var(--surface-alt); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1rem 2.5rem; display: grid; grid-template-columns: 1fr 1fr; gap: 0 3rem;
}
@media (max-width: 700px) { .faq-list-boxed { grid-template-columns: 1fr; padding: 0.5rem 1.5rem; } }

/* ---------- Why-us photo split (opt-in via value_props_image) ---------- */
.why-split { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: center; }
.value-list { display: flex; flex-direction: column; gap: 1.5rem; margin-top: 1.5rem; }
.why-photo { background-size: cover; background-position: center; border-radius: var(--radius-lg); min-height: 340px; box-shadow: 0 16px 36px var(--shadow); }
@media (max-width: 780px) {
  .why-split { grid-template-columns: 1fr; }
  .why-photo { order: -1; min-height: 220px; }
}

/* ---------- Style/inspiration gallery grid (opt-in via style_gallery) ---------- */
.style-gallery-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.25rem; }
.style-gallery-item {
  aspect-ratio: 4 / 3; background-size: cover; background-position: center;
  border-radius: var(--radius-lg); position: relative; overflow: hidden; box-shadow: 0 8px 20px var(--shadow);
}
.style-gallery-tag {
  position: absolute; left: 0.9rem; bottom: 0.9rem;
  background: rgba(0,0,0,0.55); color: #fff; font-family: var(--font-heading); font-weight: 700;
  font-size: 0.8rem; padding: 0.4rem 0.85rem; border-radius: 999px;
}

/* ---------- Review-card placeholder grid (opt-in via review_cards_style) —
   same honest "added when claimed" content as .content-placeholder, laid out
   like real review cards instead of one dashed box. ---------- */
.review-card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.5rem; }
.review-card { background: var(--surface); border: 1px dashed var(--line); border-radius: var(--radius-lg); padding: 1.75rem 1.5rem; }
.review-stars { display: flex; gap: 0.25rem; margin: 0.75rem 0; }
.review-star { width: 1.05rem; height: 1.05rem; fill: var(--star); stroke: var(--star); }
.review-card p { margin: 0; font-size: 0.92rem; font-style: italic; color: var(--ink-muted); line-height: 1.6; }

/* ---------- Testimonial ---------- */
.testimonial { max-width: 68ch; margin: 0 auto; text-align: center; }
.testimonial .stars { font-size: 1.2rem; display: block; margin-bottom: 1rem; }
.testimonial blockquote { font-family: var(--font-heading); font-size: 1.3rem; font-weight: 600; line-height: 1.45; margin: 0 0 1rem; color: var(--ink); }
.testimonial cite { font-style: normal; color: var(--ink-muted); font-size: 0.92rem; }

/* ---------- Service area ---------- */
.town-list { list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0.75rem; padding: 0; margin: 0; }
.town-list li { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 0.85rem 1rem; font-weight: 600; }
/* ---------- Content placeholder (info we don't have yet, filled in with the
   business owner after they claim the site — not a gap to hide) ---------- */
.content-placeholder {
  background: var(--surface-alt);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
}
.placeholder-tag {
  display: inline-block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
  margin-bottom: 0.75rem;
}
.content-placeholder p { margin: 0; font-size: 0.92rem; font-style: italic; color: var(--ink-muted); line-height: 1.6; }
.content-placeholder.inline { padding: 1rem 1.25rem; }

.map-placeholder {
  background: var(--surface-alt);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  min-height: 260px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-muted);
  font-size: 0.9rem;
  text-align: center;
  padding: 1.5rem;
}

/* ---------- Gallery ---------- */
.gallery-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.25rem; }
.gallery-item { border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--line); }
.gallery-photo {
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255,255,255,0.85);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 0.85rem;
  text-align: center;
  padding: 1rem;
  background: linear-gradient(135deg, var(--primary), var(--primary-strong));
}
.gallery-caption { padding: 0.85rem 1rem; font-size: 0.88rem; color: var(--ink-muted); background: var(--surface); }

/* ---------- Final CTA band ---------- */
.cta-band { background: linear-gradient(135deg, var(--primary-strong) 0%, var(--primary) 100%); color: #fff; text-align: center; }
.cta-band h2 { color: #fff; margin: 0 0 0.6rem; }
.cta-band p { color: rgba(255,255,255,0.85); margin: 0 0 1.75rem; }
.cta-band .phone-big { font-family: var(--font-mono); font-size: 1.4rem; font-weight: 700; color: #fff; text-decoration: none; }

/* ---------- Forms ---------- */
.form-grid { display: grid; gap: 1.25rem; max-width: 560px; }
label { display: block; font-weight: 700; font-size: 0.85rem; color: var(--ink); margin-bottom: 0.4rem; }
input, textarea, select {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.7rem 0.85rem;
}
input:focus, textarea:focus, select:focus { outline: 2px solid var(--primary); outline-offset: 1px; }
textarea { resize: vertical; min-height: 120px; }

.contact-direct { display: flex; flex-direction: column; gap: 0.9rem; font-size: 1rem; }
.contact-direct a { color: var(--primary); text-decoration: none; font-weight: 600; }
.contact-direct a:hover { text-decoration: underline; }
.hours-table { width: 100%; border-collapse: collapse; font-size: 0.92rem; margin-top: 0.5rem; }
.hours-table td { padding: 0.4rem 0; border-bottom: 1px solid var(--line); color: var(--ink-muted); }
.hours-table td:last-child { text-align: right; color: var(--ink); font-weight: 600; }

/* ---------- Footer ---------- */
.site-footer { background: var(--ink); color: rgba(255,255,255,0.75); padding: 3rem 0 2rem; margin-top: 2rem; }
.site-footer .wrap { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 2rem; }
.site-footer h4 { color: #fff; font-size: 0.85rem; letter-spacing: 0.06em; text-transform: uppercase; margin: 0 0 1rem; }
.site-footer a { color: rgba(255,255,255,0.75); text-decoration: none; font-size: 0.92rem; }
.site-footer a:hover { color: #fff; }
.site-footer ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.footer-bottom { max-width: var(--max); margin: 2.5rem auto 0; padding: 1.5rem 1.5rem 0; border-top: 1px solid rgba(255,255,255,0.15); font-size: 0.8rem; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
.footer-bottom a { color: rgba(255,255,255,0.6); }

@media (max-width: 480px) {
  .hero { padding: 3.5rem 0 5rem; }
  .footer-bottom { flex-direction: column; }
}

/* ---------- Sticky mobile CTA bar (opt-in via sticky_mobile_cta) ---------- */
.sticky-mobile-cta { display: none; }
@media (max-width: 780px) {
  body.has-sticky-cta { padding-bottom: 4.75rem; }
  .sticky-mobile-cta {
    display: flex; gap: 0.75rem; position: fixed; bottom: 0; left: 0; right: 0; z-index: 30;
    background: var(--surface); padding: 0.75rem 1rem; border-top: 1px solid var(--line);
    box-shadow: 0 -4px 16px var(--shadow);
  }
  .sticky-mobile-cta .btn { flex: 1 1 0; justify-content: center; }
}
