/* ---------- Header ---------- */
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--container-pad);
  background: var(--color-paper-raised);
  border-bottom: 1px solid var(--color-line);
  position: sticky;
  top: 0;
  z-index: 100;
}

.site-header__logo img {
  height: 36px;
  width: auto;
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

/* Below the nav breakpoint, the compact header shows only the logo and
   the hamburger toggle — phone and the primary CTA are already reachable
   via the sticky bottom bar and the mobile nav panel, so repeating them
   in the cramped top bar just forces awkward text-wrapping. Matches the
   approved Concept B (refined) mobile composition. */
.site-header__phone,
.site-header__actions .btn--primary {
  display: none;
}

@media (min-width: 62em) {
  .site-header__phone,
  .site-header__actions .btn--primary {
    display: inline-flex;
  }
}

.site-header__phone {
  align-items: center;
  gap: var(--space-2);
  font-weight: 700;
  font-size: var(--text-base);
  text-decoration: none;
  color: var(--color-ink);
  white-space: nowrap;
}
.site-header__phone .icon {
  color: var(--color-red);
}

/* ---------- Primary navigation (desktop) ---------- */
.nav {
  display: none;
}

@media (min-width: 62em) {
  .nav {
    display: flex;
    gap: var(--space-6);
    align-items: center;
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .nav a {
    color: var(--color-ink);
    text-decoration: none;
    font-weight: 600;
    font-size: var(--text-base);
  }

  .nav a[aria-current="page"] {
    color: var(--color-red);
  }
}

/* Services dropdown — operable by mouse, keyboard, and touch.
   [aria-expanded] is toggled by src/js/nav.js; :focus-within is a
   no-JS fallback so tabbing into the panel still reveals it. */
.nav__dropdown {
  position: relative;
}

.nav__dropdown-toggle {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  font: inherit;
  font-weight: 600;
  color: var(--color-ink);
  cursor: pointer;
  padding: var(--space-2) 0;
}

.nav__dropdown-panel {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 220px;
  background: var(--color-paper-raised);
  border: 1px solid var(--color-line);
  border-top: 3px solid var(--color-red);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-review);
  padding: var(--space-2) 0;
  list-style: none;
  margin: var(--space-2) 0 0;
  z-index: 10;
}

.nav__dropdown[aria-expanded="true"] .nav__dropdown-panel,
.nav__dropdown:focus-within .nav__dropdown-panel {
  display: block;
}

.nav__dropdown-panel a {
  display: block;
  padding: var(--space-2) var(--space-4);
  font-weight: 400;
  color: var(--color-ink);
  text-decoration: none;
}
.nav__dropdown-panel a:hover,
.nav__dropdown-panel a:focus-visible {
  background: var(--color-tint);
}

/* ---------- Mobile navigation ---------- */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: none;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

@media (min-width: 62em) {
  .nav-toggle {
    display: none;
  }
}

.mobile-nav {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--color-paper-raised);
  z-index: 200;
  padding: var(--space-5);
  overflow-y: auto;
}

.mobile-nav[data-open="true"] {
  display: block;
}

.mobile-nav__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: none;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  margin-bottom: var(--space-5);
}

.mobile-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.mobile-nav li {
  border-bottom: 1px solid var(--color-line);
}

.mobile-nav a,
.mobile-nav__group-toggle {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-4) 0;
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: none;
  background: none;
  border: none;
  font-family: inherit;
  cursor: pointer;
}

.mobile-nav__submenu {
  display: none;
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0 0 0 var(--space-4);
}

.mobile-nav__submenu[data-open="true"] {
  display: block;
}

.mobile-nav__submenu a {
  font-size: var(--text-base);
  font-weight: 400;
  padding: var(--space-2) 0;
}

@media (min-width: 62em) {
  .mobile-nav {
    display: none !important;
  }
}

/* ---------- Sticky mobile call/quote bar ---------- */
.sticky-cta {
  position: sticky;
  bottom: 0;
  display: flex;
  background: var(--color-charcoal);
  z-index: 90;
}

.sticky-cta a {
  flex: 1;
  text-align: center;
  padding: var(--space-4);
  color: var(--color-white);
  text-decoration: none;
  font-weight: 700;
  font-size: var(--text-base);
  min-height: 44px;
}

.sticky-cta a:first-child {
  border-right: 1px solid #3a342a;
}

.sticky-cta a:last-child {
  background: var(--color-red);
}

@media (min-width: 62em) {
  .sticky-cta {
    display: none;
  }
}

/* ---------- Footer ----------
   Light, warm background (not the previous near-black charcoal) — chosen
   specifically so the real Prime Painting logo (dark-red "Prime", black
   "Painting", both opaque) reads with strong contrast without altering
   the logo asset itself. --color-tint is the same warm neutral already
   used for alternating section rhythm elsewhere on the page, so this
   stays inside the approved Concept B (refined) palette rather than
   introducing a new color. */
.site-footer {
  background: var(--color-tint);
  color: var(--color-ink);
}

.site-footer__rule {
  height: 3px;
  background: var(--color-red);
}

.site-footer__cols {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--space-6);
  padding: var(--space-7) var(--container-pad);
}

@media (max-width: 48em) {
  .site-footer__cols {
    grid-template-columns: 1fr 1fr;
  }
}

/* Class-based, not `.site-footer h5` — the heading level here is h2.
   (Phase 5D QA: the previous h5 skipped straight from h1/h2 content,
   an invalid heading order per axe/Lighthouse. h2 is used rather than
   h3 because this same footer partial also renders on pages — Contact,
   Request a Quote, Thank You — whose only prior heading is h1, where
   h3 would itself be a skip.) Styling is intentionally decoupled from
   the heading level so it can't silently break again if the level ever
   needs to change. */
.site-footer__heading {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  margin: 0 0 var(--space-3);
}

.site-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--text-base);
}

.site-footer li {
  margin-bottom: var(--space-2);
}

.site-footer__bottom {
  border-top: 1px solid var(--color-line);
  padding: var(--space-4) var(--container-pad);
  font-size: var(--text-xs);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* ---------- Cards (service cards, review cards) ---------- */
.card {
  background: var(--color-paper-raised);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.card__body {
  padding: var(--space-4);
}

.card__name {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: 700;
  margin: 0 0 var(--space-2);
}

.card__desc {
  color: var(--color-muted);
  font-size: var(--text-xs);
  margin: 0;
}

.card--link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: border-color var(--transition-fast);
}
.card--link:hover {
  border-color: var(--color-red);
}

/* ---------- Hero ----------
   Split layout — a real photo on one side, a solid text panel on the
   other — never text laid over the photo. This is the pattern the
   Concept B refinement pass established specifically to avoid the
   readability/crop problems the old design had; it's reused everywhere
   a hero is needed, homepage included.

   The `position:absolute;inset:0` + sized, `overflow:hidden` wrapper is
   deliberate: a plain `height:100%` on the <img> silently fails to crop
   when the parent's height isn't definite (exactly the bug found and
   fixed during the Concept B design pass) — this pattern can't regress
   that way. */
.hero {
  display: grid;
  grid-template-columns: 1fr;
}

@media (min-width: 60em) {
  .hero {
    grid-template-columns: 1.3fr 1fr;
  }
}

.hero__photo {
  position: relative;
  height: 320px;
  overflow: hidden;
}

@media (min-width: 60em) {
  .hero__photo {
    height: 560px;
  }
}

.hero__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero__panel {
  background: var(--color-charcoal);
  color: var(--color-white);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-6) var(--container-pad);
}

/* Homepage-only refinement (owner-approved, not a Concept 3B token
   change) — a deep oxblood/burgundy derived from --color-red's hue,
   replacing charcoal for just this one panel. Scoped to this modifier
   rather than --color-charcoal or .hero__panel itself so the identical
   .hero__panel markup on exterior-painting.html is unaffected. */
.hero__panel--home {
  background: #52110d;
}

.hero__eyebrow {
  color: #e3a99c;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: var(--space-3);
}

.hero__panel h1 {
  color: var(--color-white);
  margin-bottom: var(--space-3);
}

.hero__panel p {
  color: #d9d2c6;
  max-width: 46ch;
}

/* Any outline button placed on a dark panel needs light text/border —
   the base .btn--outline is tuned for light backgrounds (var(--color-ink)
   on transparent), which is invisible here otherwise. */
.hero__panel .btn--outline {
  border-color: #fff;
  color: #fff;
}

/* ---------- Credibility strip ---------- */
.credibility-strip {
  text-align: center;
  padding: var(--space-4) var(--container-pad);
  background: var(--color-tint);
  font-size: var(--text-xs);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-6);
}

.credibility-strip strong {
  color: var(--color-red);
}

/* ---------- Featured work ----------
   Same absolute-fill pattern as the hero photo, applied to each cell so
   a portrait-oriented source photo can never distort the grid. */
.featured-grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-auto-rows: 220px;
  gap: var(--space-2);
}

@media (min-width: 48em) {
  .featured-grid {
    grid-template-columns: 1.4fr 1fr;
    grid-template-rows: 1fr 1fr;
    height: 460px;
    grid-auto-rows: unset;
  }
}

.featured-grid__cell {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-md);
}

.featured-grid__cell.is-large {
  grid-row: span 1;
}

@media (min-width: 48em) {
  .featured-grid__cell.is-large {
    grid-row: span 2;
  }
}

.featured-grid__cell img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------- How it works ---------- */
.process {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-6);
}

.process__step {
  max-width: 190px;
  text-align: center;
}

.process__num {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--color-red);
  color: var(--color-white);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto var(--space-3);
  font-weight: 700;
}

.process__step h3 {
  font-size: var(--text-lg);
  margin-bottom: var(--space-2);
}

.process__step p {
  font-size: var(--text-xs);
  color: var(--color-muted);
  margin: 0;
}

/* ---------- Google Reviews (live, client-rendered) ----------
   The section always ships an honest static fallback (heading + link to
   the real Google profile) in the page's own HTML. google-reviews.js
   swaps .reviews__fallback for .reviews__live only once a Maps API key
   is configured and the request succeeds — see
   src/_data/googleReviews.js. Nothing here hard-codes stars, a count, or
   review text. */
.reviews {
  text-align: center;
}

.reviews__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  margin-top: var(--space-4);
}

/* Deliberately smaller/quieter than the read-reviews .btn--outline next
   to it — reading and writing a review are kept as visually distinct
   actions, not a pair of equal-weight buttons. */
.reviews__write-link {
  font-size: var(--text-xs);
  color: var(--color-muted);
  text-decoration: underline;
}

.reviews__write-link:hover {
  color: var(--color-red);
}

.reviews__live {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}

.reviews__summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  color: var(--color-muted);
}

.reviews__stars {
  color: #d9a441;
  font-size: var(--text-h3);
  letter-spacing: 0.1em;
}

.reviews__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  max-width: 56rem;
  margin-inline: auto;
  text-align: left;
  list-style: none;
  padding: 0;
}

/* auto-fit rather than a fixed column count (same pattern as
   .gallery-grid) — the number of reviews Google returns can vary run to
   run (owner-requested exclusions, fewer than 5 total, etc.), so a fixed
   3-up grid could leave a single stretched card orphaned on its own row.
   Cards instead keep a consistent width and wrap naturally at whatever
   count is actually rendered. */
@media (min-width: 48em) {
  .reviews__list {
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  }
}

.reviews__card {
  background: var(--color-paper-raised);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-review);
  padding: var(--space-4);
}

.reviews__card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.reviews__author {
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: none;
}

.reviews__author:hover {
  color: var(--color-red);
}

.reviews__text {
  color: var(--color-ink);
  font-size: var(--text-base);
  margin-bottom: var(--space-2);
}

.reviews__time {
  color: var(--color-muted);
  font-size: var(--text-xs);
  margin-bottom: 0;
}

.reviews__attribution {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: 0;
}

/* Official, unmodified Google Maps attribution logo (see
   src/assets/images/attribution/) — rendered at its native aspect
   ratio; height stays within Google's required 16-19dp range. */
.reviews__google-maps-logo {
  display: block;
  height: 18px;
  width: auto;
}

.reviews__data-attributions {
  font-size: var(--text-xs);
  color: var(--color-muted);
}

/* ---------- Chips ----------
   Generic small-tag component — originally built just for the homepage's
   service-area list, generalized here so the Exterior Painting page can
   reuse it for "surfaces we paint" rather than inventing a near-identical
   component. */
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: center;
  margin-top: var(--space-5);
}

.chip {
  font-size: var(--text-xs);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-line);
  border-radius: 99px;
  background: var(--color-paper-raised);
}

/* ---------- FAQ (native <details>/<summary> — no JS needed) ---------- */
.faq {
  max-width: 720px;
  margin: 0 auto;
}

.faq__item {
  border-bottom: 1px solid var(--color-line);
}

.faq__item summary {
  padding: var(--space-4) 0;
  font-weight: 700;
  font-size: var(--text-lg);
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
}

.faq__item summary::-webkit-details-marker {
  display: none;
}

.faq__item summary::after {
  content: "+";
  color: var(--color-red);
  font-size: 1.4em;
  line-height: 1;
  flex-shrink: 0;
}

.faq__item[open] summary::after {
  content: "\2212";
}

.faq__item p {
  padding-bottom: var(--space-4);
  color: var(--color-muted);
  max-width: none;
}

/* ---------- Simple photo gallery ----------
   Uniform grid for supplementary real project photos — a lighter-weight
   alternative to .featured-grid for pages that have more images than fit
   the "one large + two supporting" editorial treatment. Same crop-safe
   position:absolute pattern as .hero__photo / .featured-grid. */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-3);
}

.gallery-grid__cell {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-md);
  aspect-ratio: 4 / 3;
}

.gallery-grid__cell img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------- Service rows (services.html hub) ----------
   A photography-led alternative to seven identical cards: each service
   gets a real photo and its own short pitch, alternating sides for
   rhythm. Stacks to a single column on narrow screens, photo always on
   top there for readability. */
.service-rows {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.service-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  align-items: center;
  padding-block: var(--space-8);
  border-bottom: 1px solid var(--color-line);
}

.service-rows > .service-row:last-child {
  border-bottom: none;
}

@media (min-width: 48em) {
  .service-row {
    flex-direction: row;
  }

  .service-row:nth-child(even) {
    flex-direction: row-reverse;
  }
}

.service-row__photo {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-md);
  aspect-ratio: 4 / 3;
  width: 100%;
}

@media (min-width: 48em) {
  .service-row__photo {
    flex: 1 1 42%;
    aspect-ratio: 3 / 2;
  }
}

.service-row__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.service-row__body {
  flex: 1 1 55%;
}

.service-row__body h2 {
  margin-bottom: var(--space-3);
}

/* ---------- Forms (Quick Contact / Request a Quote) ----------
   Shared markup for both Netlify-backed forms. Deliberately plain —
   square-cornered inputs matching --radius-sm (the same radius as
   .btn), no card chrome, no floating labels — so the forms read as
   part of the site rather than an embedded generic form widget. */
.form {
  max-width: 36rem;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.form__row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.form__label {
  font-weight: 700;
  font-size: var(--text-base);
}

.form__required {
  color: var(--color-red);
  font-weight: 400;
}

.form__hint {
  font-size: var(--text-xs);
  color: var(--color-muted);
  font-weight: 400;
}

.form__input,
.form__textarea {
  font: inherit;
  color: var(--color-ink);
  background: var(--color-paper-raised);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  width: 100%;
}

.form__textarea {
  resize: vertical;
  min-height: 7rem;
}

.form__input:focus-visible,
.form__textarea:focus-visible {
  outline: 3px solid var(--color-red);
  outline-offset: 1px;
}

.form__fieldset {
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  padding: var(--space-4) var(--space-5) var(--space-5);
  margin: 0;
}

.form__legend {
  font-weight: 700;
  font-size: var(--text-base);
  padding: 0 var(--space-2);
}

.form__checkbox-group {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-3) var(--space-5);
  margin-top: var(--space-3);
}

.form__checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
}

.form__checkbox input[type="checkbox"] {
  width: 20px;
  height: 20px;
  accent-color: var(--color-red);
  flex-shrink: 0;
}

.form__checkbox label {
  font-size: var(--text-base);
}

/* Netlify honeypot — kept in the DOM for spam-bot detection but removed
   from the accessibility tree and tab order via display:none, per
   Netlify's own documented pattern. Real visitors never see or reach it. */
.form__honeypot {
  display: none;
}

.form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-5);
}

/* ---------- Contact methods (Contact page) ---------- */
.contact-methods {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5) var(--space-7);
  margin-bottom: var(--space-6);
}

.contact-methods__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.contact-methods__label {
  font-size: var(--text-xs);
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.contact-methods__value {
  font-size: var(--text-lg);
  font-weight: 700;
}

/* ---------- Centered prose ----------
   A single text block that should sit centered under a centered
   heading, rather than the default block behavior of sitting flush
   against its container's start edge. `max-width: 68ch` already comes
   from the base `p` rule (base.css) — this class only adds what that
   rule doesn't: centering the box itself, and keeping its own text
   centered independent of whatever alignment the parent section uses. */
.prose-centered {
  margin-inline: auto;
  text-align: center;
}
