/* base.css — shared across all markets.
   Generated from the rules that were byte-identical across the market
   stylesheets at extraction time, so adopting it cannot change any
   existing site's appearance. Market-specific rules live in market.css, which loads after
   this file and wins on equal specificity. Do not hand-edit: regenerate
   with _template/tools/split-css.mjs. */

*, *::before, *::after { box-sizing: border-box; }
img, svg { display: block; max-width: 100%; }
p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }
a:hover { color: var(--primary-dark); }
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: 1.25rem; }
.section--muted { background: var(--muted); }
.section--muted-soft { background: var(--muted-2); border-block: 1px solid var(--border); }
.section--dark { background: var(--secondary); color: var(--secondary-foreground); }
.section--brand { background: var(--primary); color: var(--primary-foreground); }
.center { text-align: center; }
.mx-auto { margin-inline: auto; }
.stack > * + * { margin-top: 1rem; }
.eyebrow--gold { color: var(--accent); }
.section-head.center { margin-inline: auto; }
.skip-link { position: absolute; left: 0.5rem; top: -100px; z-index: 999; padding: 0.7rem 1.1rem; background: var(--primary); color: #fff; font-weight: 600; border-radius: var(--radius-btn); transition: top 0.15s ease; }
.skip-link:focus { top: 0.5rem; color: #fff; }
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--primary); color: #fff; border-color: var(--primary); }
.btn--primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); color: #fff; }
.btn--onbrand { background: #fff; color: var(--primary); border-color: #fff; }
.btn--onbrand:hover { background: var(--muted); color: var(--primary-dark); }
.btn--outline { background: #fff; color: var(--primary); border-color: var(--border-strong); }
.btn--outline:hover { background: var(--muted); border-color: var(--primary); color: var(--primary-dark); }
.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.arrow-link:hover { text-decoration: underline; }
.arrow-link::after { content: "\2192"; transition: transform 0.15s ease; }
.arrow-link:hover::after { transform: translateX(3px); }
.topbar strong { color: var(--accent); }
.topbar a { color: #fff; font-weight: 600; }
.header-inner { display: flex; align-items: center; gap: 1rem; min-height: var(--header-h); }
.nav-toggle { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.7rem; background: #fff; border: 1px solid var(--border-strong); border-radius: var(--radius-btn); font: inherit; font-size: 0.85rem; font-weight: 600; color: var(--secondary); cursor: pointer; }
.nav-toggle:hover { background: var(--muted); }
.site-nav { display: none; }
.site-nav a:hover { background: var(--muted); color: var(--primary); }
.header-cta { display: none; }
.mobile-nav.is-open { display: block; }
.mobile-nav ul { list-style: none; margin: 0 0 0.9rem; padding: 0; }
.mobile-nav a[aria-current="page"] { color: var(--primary); }
.mobile-nav .btn { width: 100%; }
.crumbs ol { display: flex; flex-wrap: wrap; gap: 0.4rem; list-style: none; margin: 0; padding: 0; }
.crumbs a { color: var(--muted-foreground); text-decoration: none; }
.crumbs a:hover { color: var(--primary); text-decoration: underline; }
.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }
.grid--4 { grid-template-columns: 1fr; }
.split { display: grid; gap: 2.25rem; align-items: start; }
.grid > *, .split > *, .steps > *, .features > *, .stats > *, .footer-grid > * { min-width: 0; }
.feature { display: flex; gap: 0.85rem; }
.card .arrow-link { margin-top: auto; padding-top: 1rem; }
.info-list li { display: flex; gap: 0.8rem; }
.info__value { font-weight: 600; color: var(--foreground); text-decoration: none; overflow-wrap: anywhere; }
.form-grid { display: grid; gap: 1rem; }
.field { display: flex; flex-direction: column; gap: 0.35rem; }
.field textarea { min-height: 120px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--primary); }
fieldset { margin: 0 0 1.25rem; padding: 0; border: 0; }
.form-status { margin-top: 1rem; padding: 0.85rem 1rem; border-radius: var(--radius-btn); background: var(--muted); border: 1px solid var(--border); font-size: 0.9rem; }
.form-status:empty { display: none; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.faq summary::-webkit-details-marker { display: none; }
.faq details[open] summary::after { content: "\2212"; }
.faq summary:hover { background: var(--muted-2); }
.prose img, .prose table { max-width: 100%; }
.prose li { margin-bottom: 0.4rem; }
th, td { padding: 0.7rem 1rem; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
tbody tr:last-child td { border-bottom: 0; }
.photo-ph--tall { min-height: 340px; }
.photo-ph svg { margin: 0 auto 0.6rem; color: var(--border-strong); }
.site-footer a { color: rgb(255 255 255 / 0.78); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.footer-grid { display: grid; gap: 2rem; padding-block: 3rem; align-items: start; }
/* align-items: start is load-bearing. Grid items stretch by default, so the
   brand column was being sized by the 7-item services list beside it and the
   heading below it was pushed down to clear the taller row. */
.footer-brand { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.9rem; }
.callbar a.is-primary { background: var(--primary); color: #fff; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---- photo-fig -------------------------------------------------------
   Shared image component used by both the generated pages and the five
   hand-written ones. Replaces the .photo-ph placeholder block that used to
   render the literal words "Photo needed" as body copy. */
.photo-fig { margin: 0; }
.photo-fig img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-card, 10px);
  border: 1px solid var(--border, #e2ded6);
  background: var(--muted, #f4f1ea);
}
.photo-fig figcaption {
  margin-top: 0.6rem;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--muted-foreground, #5c5c5c);
}

/* ---- card--link ------------------------------------------------------
   Index-page cards that are themselves the link. */
a.card--link { text-decoration: none; color: inherit; display: block; }
a.card--link h3 { margin-top: 0; }
a.card--link:hover { border-color: var(--primary, #8e2f22); }
a.card--link .arrow-link { margin-top: 0.75rem; display: inline-block; }

/* ---- pill-list -------------------------------------------------------
   Used for nearby-neighborhood and related-type link lists. */
.pill-list { list-style: none; padding: 0; margin: 1rem 0 0; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.pill-list li a,
.pill-list li {
  display: inline-block;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--border, #e2ded6);
  border-radius: 999px;
  font-size: 0.9rem;
  text-decoration: none;
  color: inherit;
  background: #fff;
}
.pill-list li a:hover { border-color: var(--primary, #8e2f22); color: var(--primary, #8e2f22); }

/* ---- header overflow guard -------------------------------------------
   The primary nav grew when services / rug types / areas were added, and
   on the market with the longest brand string that pushed .header-cta
   past the viewport at 1440px. Flex children default to min-width:auto
   and refuse to shrink below their content, so the row overflowed instead
   of compressing. These two rules let it compress, and the clip stops any
   future nav addition from reintroducing a horizontal scrollbar. */
.site-header .header-inner { min-width: 0; }
.site-header .site-nav { min-width: 0; flex-shrink: 1; }
.site-header .site-nav ul { flex-wrap: nowrap; }
body { overflow-x: clip; }

/* ---- media queries, ascending (mobile-first) ---------------------- */

/* ---- audit fixes, 2026-09-02 -----------------------------------------

   1. Tables were escaping the viewport at 390px. Because body carries
      overflow-x: clip, the overflowing columns were being *clipped* rather
      than reachable by scrolling — the data was simply gone on a phone.
      Making the table its own scroll container keeps it readable. */

/* 2. Tap targets. Nav and footer links rendered 16-18px tall on mobile,
      below the 24px minimum, so they were fiddly to hit accurately. Only
      padding changes; type scale and colour are untouched. */

/* 3. Measure. Between 720px and 1000px the layout is still single-column
      but the container has widened, so body copy was running 77-89
      characters per line against a 60-75 target. Above 1000px the split
      layout already constrains it (62-76cpl measured), and below 720px the
      viewport does. So the cap is scoped to the band that needs it and
      changes nothing at phone or desktop width.

      Calibrated, not guessed: `ch` is the width of the "0" glyph, which in
      Inter is materially wider than the average character, so 68ch measured
      out at 86 real characters per line. 56ch lands at ~71. */

/* ---- media queries, ascending (mobile-first) ---------------------- */

/* ---- media queries, ascending (mobile-first) ---------------------- */

/* ---- media queries, ascending (mobile-first) ---------------------- */

/* ---- header crowding ------------------------------------------------
   The primary nav grew (services, rug types, areas) and on the market with
   the longer brand string the nav items were overrunning their own box and
   colliding with the header CTA. `nowrap` + `min-width: 0` stops the row
   overflowing the page, but it does not stop the items overlapping what
   sits beside them, so the earlier overflow fix hid this rather than
   solving it.

   Measured: the nav needs 555px and had 431px; the reassurance note beside
   the CTA occupies ~200px. The note is duplicated in the topbar and in the
   hero, so it is the right thing to drop when space is tight. */

/* Below 1200px the nav is still tight even without the note, so tighten
   item spacing there. Font size is untouched — only the gaps move. */

/* ---- media queries, ascending (mobile-first) ---------------------- */
@media (min-width: 560px) {
  .features { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 620px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .form-grid--2 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 720px) {
  .footer-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 720px) and (max-width: 999px) {
  main p,
  main .lead,
  main li {
    max-width: 56ch;
  }
  main .center p,
  main .center .lead {
    margin-inline: auto;
  }
}
@media (min-width: 900px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .stats { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 980px) {
  .steps { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1000px) {
  .footer-grid { grid-template-columns: 1.5fr 1fr 1fr 1.2fr; gap: 2.5rem; }
}
@media (min-width: 1024px) {
  .nav-toggle { display: none; }
  .site-nav { display: block; }
  .mobile-nav, .mobile-nav.is-open { display: none; }
  .callbar { display: none; }
}
@media (min-width: 1024px) and (max-width: 1199px) {
  .site-header .site-nav ul { gap: 0; }
  .site-header .site-nav ul a { padding-inline: 0.4rem; }
}
@media (max-width: 719px) {
  main table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  main table caption { text-align: left; }
}
@media (max-width: 1023px) {
  .mobile-nav ul a,
  .site-footer ul a,
  .footer-bottom a,
  .crumbs a,
  .toc a {
    display: inline-block;
    padding-block: 0.3rem;
    min-height: 24px;
  }
  .pill-list li a { min-height: 24px; }
}
@media (max-width: 1359px) {
  .header-cta__note { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
@media print {
  .site-header, .callbar, .topbar, .site-footer { display: none; }
}
