/* =====================================================================
   components.css — the shared component set
   Every component is token-driven, keyboard-usable, and works without JS.
   City variants restyle these by overriding tokens (and, where noted, a
   small number of documented component-level hooks).
   ===================================================================== */

/* ---------------------------------------------------------------------
   BUTTONS
   .btn                 base
   .btn--call           the emergency phone CTA (urgent color, tel: only)
   .btn--ghost          secondary, outlined
   .btn--quiet          text-only forward link
   Sizes: .btn--lg, .btn--sm
   Minimum target size is 44px tall so it is comfortable on a phone.
   ------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 44px;
  padding: var(--s-3) var(--s-5);
  border: 2px solid transparent;
  border-radius: var(--btn-radius, var(--radius));
  background: var(--c-accent);
  color: var(--c-text-invert);
  font-family: var(--font-ui);
  font-size: var(--t-base);
  font-weight: var(--fw-medium);
  line-height: 1.1;
  letter-spacing: var(--btn-tracking, 0);
  text-transform: var(--btn-transform, none);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
.btn:hover { color: var(--c-text-invert); transform: translateY(-1px); box-shadow: var(--shadow); }
.btn:active { transform: none; box-shadow: none; }

.btn--call { background: var(--c-action); color: var(--c-action-ink); }
.btn--call:hover { background: var(--c-action-hover); color: var(--c-action-ink); }
.btn--call .btn__num { font-variant-numeric: tabular-nums; }

.btn--ghost {
  background: transparent;
  border-color: currentColor;
  color: var(--c-link);
}
.btn--ghost:hover { background: var(--c-accent-soft); color: var(--c-link); box-shadow: none; }
.section--deep .btn--ghost { color: var(--c-text-invert); }
.section--deep .btn--ghost:hover { background: rgba(255,255,255,0.12); }

.btn--quiet {
  background: none; border: 0; padding: 0; min-height: 0;
  color: var(--c-link); text-decoration: underline;
}
.btn--quiet:hover { box-shadow: none; transform: none; }

.btn--lg { min-height: 52px; padding: var(--s-4) var(--s-6); font-size: var(--t-lead); }
.btn--sm { min-height: 38px; padding: var(--s-2) var(--s-4); font-size: var(--t-sm); }
.btn--block { width: 100%; }

/* ---------------------------------------------------------------------
   HEADER + NAVIGATION
   Mobile: hamburger toggles a drawer (JS). Without JS the nav is a plain
   visible list, so the site is never unnavigable.
   ------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--header-bg, var(--c-bg));
  color: var(--header-ink, inherit);
  border-bottom: var(--border);
  box-shadow: var(--shadow-sm);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 68px;
  padding-block: var(--s-2);
}

.brand { display: inline-flex; align-items: center; gap: var(--s-3); text-decoration: none; color: inherit; }
.brand__mark {
  display: grid; place-items: center;
  width: 40px; height: 40px;
  border-radius: var(--brand-mark-radius, var(--radius));
  background: var(--c-accent);
  color: var(--c-text-invert);
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  flex: none;
}
.site-header .btn--call { white-space: nowrap; }
.site-header .btn--call .btn__num { white-space: nowrap; }
.brand__logo {
  display: block;
  width: 100%; height: 100%;
  max-width: none;
  object-fit: contain;
}
.brand--logo-only { gap: 0; }
.brand--logo-only img { display: block; width: auto; height: 44px; max-width: 190px; object-fit: contain; }
.brand__name { font-family: var(--font-display); font-weight: var(--fw-display); font-size: 1.05rem; line-height: 1.1; }
.brand__city { display: block; font-family: var(--font-ui); font-size: var(--t-xs); font-weight: var(--fw-body); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--c-text-muted); }

.nav { display: none; }
.nav__list { display: flex; align-items: center; gap: var(--s-5); list-style: none; margin: 0; padding: 0; }
@media (min-width: 900px) {
  .nav__list { flex-wrap: nowrap; }
  .nav__link { white-space: nowrap; }
}
.nav__list li + li { margin-top: 0; }
.nav__link {
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  color: inherit;
  text-decoration: none;
  padding-block: var(--s-2);
  border-bottom: 2px solid transparent;
}
.nav__link:hover { border-bottom-color: var(--c-accent); color: inherit; }
/* aria-current="page" marks the active route — set it in the page markup. */
.nav__link[aria-current="page"] { border-bottom-color: var(--c-action); }
.nav__locations-toggle { border: 0; background: transparent; cursor: pointer; }
.nav__locations-toggle::after { content: "⌄"; margin-left: .35rem; font-size: .9em; }
.nav__locations-menu { display: none; list-style: none; margin: 0; padding: var(--s-3); background: var(--c-bg); border: var(--border); box-shadow: var(--shadow); }
.nav__locations-menu.is-open { display: grid; gap: var(--s-2); }
.nav__locations-menu a { display: block; padding: var(--s-2); color: inherit; text-decoration: none; }
.nav__locations-menu a:hover { background: var(--c-accent-soft); }
.nav__locations-label { padding: var(--s-2); font-family: var(--font-ui); font-size: var(--t-xs); font-weight: var(--fw-medium); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--c-text-muted); }

.nav-toggle {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: 44px; padding: var(--s-2) var(--s-3);
  background: none; border: var(--border); border-radius: var(--radius);
  color: inherit; font-family: var(--font-ui); font-weight: var(--fw-medium); cursor: pointer;
}
.nav-toggle__bars { position: relative; width: 18px; height: 2px; background: currentColor; }
.nav-toggle__bars::before, .nav-toggle__bars::after {
  content: ""; position: absolute; left: 0; width: 18px; height: 2px; background: currentColor;
}
.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after  { top: 6px; }

/* Drawer state, applied by JS only. */
.js .nav[data-drawer] { display: none; }
.js .nav[data-drawer].is-open {
  display: block;
  position: absolute; left: 0; right: 0; top: 100%;
  z-index: var(--z-drawer);
  background: var(--c-bg);
  border-bottom: var(--border);
  box-shadow: var(--shadow);
  padding: var(--s-4) var(--gutter) var(--s-5);
}
.js .nav[data-drawer].is-open .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
.js .nav[data-drawer].is-open .nav__link { display: block; padding: var(--s-3) 0; border-bottom: var(--border); }

@media (min-width: 900px) {
  .nav, .js .nav[data-drawer] { display: block; }
  .nav-toggle { display: none; }
  .js .nav[data-drawer].is-open { position: static; box-shadow: none; border: 0; padding: 0; }
  .js .nav[data-drawer].is-open .nav__list { flex-direction: row; align-items: center; gap: var(--s-5); }
  .js .nav[data-drawer].is-open .nav__link { display: inline-block; padding-block: var(--s-2); border-bottom: 2px solid transparent; }
  .nav__item--locations { position: relative; }
  .nav__locations-menu { position: absolute; top: calc(100% + .35rem); left: 0; min-width: 13rem; }
}

@media (max-width: 899px) {
  .js .nav[data-drawer].is-open .nav__item--locations { border-bottom: var(--border); }
  .js .nav[data-drawer].is-open .nav__locations-toggle { display: flex; width: 100%; align-items: center; justify-content: space-between; padding: var(--s-3) 0; color: inherit; text-align: left; }
  .js .nav[data-drawer].is-open .nav__locations-menu { position: static; margin: 0 0 var(--s-3); box-shadow: none; border: 0; border-left: 2px solid var(--c-accent); }
}

/* Header phone CTA — hidden on the narrowest screens where the fixed
   call bar already covers it. */
.site-header .btn--call { display: none; }
@media (min-width: 620px) { .site-header .btn--call { display: inline-flex; } }

/* ---------------------------------------------------------------------
   FIXED CALL BAR (mobile only)
   Phone-only CTA convention: one tel: link, nothing else.
   ------------------------------------------------------------------- */
.callbar {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: var(--z-callbar);
  display: flex;
  padding: var(--s-2) var(--s-3) calc(var(--s-2) + env(safe-area-inset-bottom));
  background: var(--c-bg);
  border-top: var(--border);
  box-shadow: 0 -6px 18px -12px rgba(18,38,52,0.5);
}
.callbar .btn { flex: 1; }
@media (min-width: 620px) { .callbar { display: none; } }
@media (max-width: 619px) { body { padding-bottom: 74px; } }

/* ---------------------------------------------------------------------
   HERO
   .hero            standard page hero
   .hero--image     adds the placeholder image layer + overlay
   ------------------------------------------------------------------- */
.hero {
  position: relative;
  background: var(--hero-bg, var(--c-bg-deep));
  color: var(--hero-ink, #ffffff);
  padding-block: clamp(3rem, 2rem + 6vw, 6.5rem);
  overflow: hidden;
}
.hero__media {
  position: absolute; inset: 0;
  background-color: var(--brand-900);
  background-image: var(--hero-overlay), var(--hero-image, none);
  background-size: cover;
  background-position: center;
}
.hero__inner { position: relative; z-index: 1; max-width: 46rem; }
/* Interior (non-image) heroes are a title block, not a stage: tighten them. */
.hero:not(.hero--image) { padding-block: clamp(2.25rem, 1.6rem + 3vw, 3.75rem); }
.hero h1 { color: inherit; margin-bottom: var(--s-4); }
.hero .lead { color: var(--hero-ink-soft, rgba(255,255,255,0.88)); }
.hero__points li { color: var(--hero-ink-soft, rgba(255,255,255,0.92)); }
.hero .eyebrow { color: var(--brand-300); }
.hero__actions { margin-top: var(--s-5); }
.hero__points { list-style: none; padding: 0; margin: var(--s-5) 0 0; display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5); font-size: var(--t-sm); }
.hero__points li { margin: 0; display: flex; align-items: center; gap: var(--s-2); }
.hero__points li::before { content: ""; width: 8px; height: 8px; border-radius: 2px; background: var(--c-action); flex: none; }

/* ---------------------------------------------------------------------
   CARDS
   ------------------------------------------------------------------- */
.card {
  display: flex; flex-direction: column;
  background: var(--c-bg);
  border: var(--card-border, var(--border));
  border-radius: var(--card-radius, var(--radius-lg));
  padding: var(--s-5);
  box-shadow: var(--card-shadow, none);
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.card h3 { margin-bottom: var(--s-2); }
.card p { color: var(--c-text-muted); }
.card__foot { margin-top: auto; padding-top: var(--s-4); }

/* Whole-card link: the <a> in the heading covers the card via ::after,
   which keeps one real focusable link for screen readers. */
.card--link { position: relative; }
.card--link:hover { box-shadow: var(--shadow); transform: translateY(-2px); border-color: var(--c-accent); }
.card--link h3 a { text-decoration: none; }
.card--link h3 a::after { content: ""; position: absolute; inset: 0; }
.card--link:focus-within { box-shadow: var(--shadow); border-color: var(--c-accent); }

.card__icon {
  width: 44px; height: 44px; margin-bottom: var(--s-4);
  display: grid; place-items: center;
  border-radius: var(--radius);
  background: var(--c-accent-soft);
  color: var(--c-accent);
}

/* ---------------------------------------------------------------------
   PROCESS STEPS
   ------------------------------------------------------------------- */
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; display: grid; gap: var(--s-5); }
@media (min-width: 760px) { .steps { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); } }
.steps li { margin: 0; padding-top: var(--s-5); border-top: 3px solid var(--c-rule); counter-increment: step; }
.steps li::before {
  content: counter(step, decimal-leading-zero);
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-h3);
  color: var(--c-accent);
  margin-bottom: var(--s-2);
}
.steps h3 { font-size: var(--t-h4); }
.steps p { color: var(--c-text-muted); margin-bottom: 0; }

/* ---------------------------------------------------------------------
   TRUST STRIP  (claims must stay generic until the operator supplies facts)
   ------------------------------------------------------------------- */
.trust { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.trust__item { display: flex; gap: var(--s-3); align-items: flex-start; }
.trust__item strong { display: block; font-family: var(--font-ui); }
.trust__item span { font-size: var(--t-sm); color: var(--c-text-muted); }

/* ---------------------------------------------------------------------
   FAQ — native <details>, no JS required
   ------------------------------------------------------------------- */
.faq { border-top: var(--border); }
.faq__item { border-bottom: var(--border); }
.faq__item summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  padding: var(--s-4) 0;
  font-family: var(--font-display);
  font-size: var(--t-h4);
  cursor: pointer;
  list-style: none;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: "+";
  font-family: var(--font-ui);
  font-size: 1.5rem;
  line-height: 1;
  color: var(--c-accent);
  transition: transform var(--dur) var(--ease);
  flex: none;
}
.faq__item[open] summary::after { content: "\2013"; }
.faq__item > div { padding-bottom: var(--s-4); max-width: var(--measure); color: var(--c-text-muted); }

/* ---------------------------------------------------------------------
   CALL PANEL — the repeated mid-page and end-of-page phone CTA
   ------------------------------------------------------------------- */
.callpanel {
  display: grid; gap: var(--s-5); align-items: center;
  padding: var(--s-6);
  border-radius: var(--radius-lg);
  background: var(--callpanel-bg, var(--c-accent-soft));
  border-left: 6px solid var(--c-action);
}
@media (min-width: 780px) { .callpanel { grid-template-columns: minmax(0,1fr) auto; } }
.callpanel h2 { margin-bottom: var(--s-2); }
.callpanel p { margin-bottom: 0; color: var(--c-text-muted); }
.section--deep .callpanel { background: rgba(255,255,255,0.08); }
.section--deep .callpanel p { color: rgba(255,255,255,0.82); }

/* ---------------------------------------------------------------------
   PLACEHOLDER MEDIA
   Every image slot ships as a labelled placeholder so nobody mistakes a
   stand-in for a real photo of a real job.
   ------------------------------------------------------------------- */
.ph {
  position: relative;
  display: grid; place-items: center;
  aspect-ratio: var(--ph-ratio, 4 / 3);
  border: 2px dashed var(--ink-300);
  border-radius: var(--radius-lg);
  background:
    repeating-linear-gradient(45deg, var(--ink-075) 0 12px, transparent 12px 24px),
    var(--c-bg-alt);
  color: var(--c-text-muted);
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  text-align: center;
  padding: var(--s-4);
  overflow: hidden;
}
.ph--wide { --ph-ratio: 16 / 9; }
.ph--square { --ph-ratio: 1 / 1; }
.ph--tall { --ph-ratio: 3 / 4; }
.ph__label { max-width: 22rem; }
.ph__label strong { display: block; font-weight: var(--fw-medium); color: var(--c-text); }

/* Inline text placeholder for business details (name, address, phone). */
/* Inline placeholder tint. Only for details the operator has NOT supplied.
   Supplied data (e.g. the public phone number) must never carry it. */
.ph-text {
  background: var(--urgent-100);
  border-bottom: 1px dashed var(--urgent-600);
  padding: 0 0.15em;
  font-style: normal;
  white-space: nowrap;
}

/* ---------------------------------------------------------------------
   BREADCRUMBS
   ------------------------------------------------------------------- */
.crumbs { font-size: var(--t-sm); color: var(--c-text-muted); padding-block: var(--s-4); }
.crumbs ol { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; margin: 0; padding: 0; }
.crumbs li { margin: 0; display: flex; align-items: center; gap: var(--s-2); }
.crumbs li + li::before { content: "/"; color: var(--ink-300); }

/* ---------------------------------------------------------------------
   RELATED / INTERNAL LINK BLOCK
   ------------------------------------------------------------------- */
.linklist { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.linklist a {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: var(--border); border-radius: var(--radius);
  text-decoration: none; font-family: var(--font-ui); font-weight: var(--fw-medium);
}
.linklist a:hover { border-color: var(--c-accent); background: var(--c-accent-soft); }
.linklist a::after { content: "\2192"; color: var(--c-accent); }

/* Sticky sidebar rail used on service pages. */
.rail { display: grid; gap: var(--s-5); }
@media (min-width: 900px) { .rail { position: sticky; top: 92px; } }
.rail__box { border: var(--border); border-radius: var(--radius-lg); padding: var(--s-5); background: var(--c-bg-alt); }
.rail__box h3 { font-size: var(--t-h4); }

/* ---------------------------------------------------------------------
   FOOTER
   ------------------------------------------------------------------- */
.site-footer {
  background: var(--footer-bg, var(--c-bg-deep));
  color: var(--c-text-invert);
  padding-block: var(--s-7) var(--s-6);
  margin-top: var(--section-y);
}
.site-footer a { color: rgba(255,255,255,0.86); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.site-footer h3 { font-size: var(--t-h4); color: inherit; }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li + li { margin-top: var(--s-2); }
.site-footer__bar {
  margin-top: var(--s-6); padding-top: var(--s-4);
  border-top: 1px solid rgba(255,255,255,0.18);
  font-size: var(--t-sm); color: rgba(255,255,255,0.7);
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5); justify-content: space-between;
}

/* FOOTER LEGAL: privacy / terms / accessibility row inside the footer bar.
   Links sit brighter than the surrounding bar text so they clear AA contrast
   on the dark footer, and they are underlined so they do not rely on color
   alone. Wraps to its own line on narrow screens. */
.footer-legal { flex: 1 1 auto; }
.footer-legal ul {
  display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4);
  list-style: none; margin: 0; padding: 0; justify-content: center;
}
.footer-legal li { margin: 0; }
.site-footer .footer-legal a {
  color: rgba(255,255,255,0.94);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .2em;
}
.site-footer .footer-legal a:hover { color: #fff; text-decoration-thickness: 2px; }
.footer-legal a[aria-current="page"] { font-weight: var(--fw-medium); }
@media (max-width: 640px) {
  .footer-legal ul { justify-content: flex-start; }
}

/* COST PLANNING: semantic cards remain readable with CSS or without it. */
.cost-planning__intro { max-width: 52rem; margin-bottom: var(--s-6); }
.cost-grid { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.cost-card, .cost-severity__grid article { padding: var(--s-5); background: var(--c-bg); border: var(--border); border-radius: var(--radius-lg); }
.cost-card--feature { grid-column: span 1; background: var(--c-bg-deep); color: var(--c-text-invert); border-color: transparent; }
.cost-card--feature p, .cost-card--feature a { color: rgba(255,255,255,.88); }
.cost-card--feature a { text-decoration-thickness: 2px; text-underline-offset: .18em; }
.cost-card__label { margin-bottom: var(--s-2); font-family: var(--font-ui); font-size: var(--t-xs); font-weight: var(--fw-medium); letter-spacing: var(--tracking-label); text-transform: uppercase; }
.cost-card__range { margin-bottom: var(--s-3); color: var(--c-accent); font-family: var(--font-display); font-size: clamp(1.55rem, 1.2rem + 1vw, 2.15rem); font-weight: var(--fw-display); line-height: 1; }
.cost-card--feature .cost-card__range { color: var(--c-action); }
.cost-card h3, .cost-severity h4 { font-size: var(--t-h4); margin-bottom: var(--s-2); }
.cost-card p:last-child, .cost-severity__grid p:last-child { margin-bottom: 0; color: var(--c-text-muted); }
.cost-severity { display: grid; gap: var(--s-5); margin-top: var(--s-5); padding: var(--s-6); border-left: 5px solid var(--c-action); background: var(--c-accent-soft); }
.cost-severity h3 { margin-bottom: 0; }
.cost-severity__grid { display: grid; gap: var(--s-3); grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }
.cost-severity__grid article { border-top: 4px solid var(--c-accent); }
.cost-planning__notes { display: grid; gap: var(--s-5); margin-top: var(--s-5); padding-top: var(--s-5); border-top: var(--border); }
.cost-planning__notes ul { margin-bottom: 0; }
.cost-planning__disclaimer { padding: var(--s-4); background: var(--c-bg); border: var(--border); border-radius: var(--radius); }
@media (min-width: 900px) { .cost-card--feature { grid-column: span 2; } .cost-planning__notes { grid-template-columns: minmax(0,1.15fr) minmax(16rem,.85fr); } }
@media (max-width: 480px) { .cost-card, .cost-severity { padding: var(--s-4); } .cost-card__range { font-size: 1.5rem; } }
