/* Brightloom Cleaning — first-party domestic / commercial cleaning template (S115).
   All imagery is authored CSS. No media, fonts, icons, embeds, CDNs, analytics or tracking.

   Voice: FRESH, BRIGHT AND AIRY. Clean white cards on a barely-there cyan wash, a bright cyan and a
   sunshine yellow, friendly medium-weight sans and generous 18px radii — set against haulwell's
   heavy indigo/coral caps, greenfold's oat/green serif and voltway's dark amber. A cleaning firm
   sells sparkle and trust, so the page is light, roomy and sunny.

   This template carries an INSTANT-QUOTE calculator (see cleaning-quote.js): a client-side tool that
   turns bedrooms, bathrooms, the type of clean and a few extras into an honest cleaner-hours and
   price RANGE — the single most-asked question in the trade. No API, no key, no network, no cost,
   and framed as an estimate throughout, never a fixed quote. */

:root {
  --cyan: #0e97c4;
  --cyan-deep: #0b7ba1;
  --cyan-soft: #e3f3fa;
  --sun: #ffcb2e;
  --sun-deep: #eab000;
  --ink: #14303a;
  --muted: #556a72;
  --wash: #f3fbfd;
  --card: #ffffff;
  --line: #dbe8ec;
  --radius: 18px;
  --sans: "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Theming for the shared scripted assistant (assistant.js reads these). */
  --assistant-accent: #0e97c4;
  --assistant-accent-ink: #fff;
  --assistant-panel: #ffffff;
  --assistant-ink: #14303a;
  --assistant-muted: #556a72;
  --assistant-soft: #e3f3fa;
  --assistant-line: #dbe8ec;

  /* text-safe accents (S116): same hue and saturation, darkened only in lightness
     until they meet WCAG AA on white. The bright originals stay for fills and art. */
  --sun-text: #967100;
  --sun-deep-text: #947000;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--wash);
}
h1, h2, h3 { font-weight: 700; line-height: 1.14; letter-spacing: -0.015em; }
a { color: inherit; }
ul, ol { list-style: none; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.skip-link {
  position: absolute; left: 1rem; top: -3rem; z-index: 12;
  background: var(--cyan); color: #fff; padding: 0.55rem 1.1rem;
  border-radius: 0 0 12px 12px; text-decoration: none; font-weight: 700;
  transition: top 0.15s ease;
}
.skip-link:focus { top: 0; }
:focus-visible { outline: 3px solid var(--sun-deep); outline-offset: 2px; }

/* ---------- Header + navigation ---------- */
.site-header {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.05rem 1.35rem; background: var(--wash);
  border-bottom: 1px solid var(--line); position: relative;
}
.wordmark {
  font-size: 1.5rem; font-weight: 800; letter-spacing: -0.02em;
  text-decoration: none; color: var(--cyan-deep); white-space: nowrap;
}
.wordmark span[aria-hidden] { color: var(--sun-deep-text); }
.nav-disclosure summary {
  list-style: none; cursor: pointer; user-select: none;
  font-weight: 700; padding: 0.55rem 1.1rem;
  border: 2px solid var(--cyan); border-radius: 999px; color: var(--cyan-deep);
}
.nav-disclosure summary::-webkit-details-marker { display: none; }
.nav-disclosure[open] summary { background: var(--cyan); color: #fff; }
.nav-disclosure nav {
  position: absolute; right: 1.35rem; left: 1.35rem; top: calc(100% + 0.5rem); z-index: 9;
  display: flex; flex-direction: column; gap: 0.2rem;
  background: var(--card); border: 1px solid var(--line); border-radius: 16px;
  padding: 0.9rem; box-shadow: 0 18px 38px rgba(14, 151, 196, 0.18);
}
.nav-disclosure nav a:not(.button) { text-decoration: none; font-weight: 700; padding: 0.6rem 0.8rem; border-radius: 10px; color: var(--cyan-deep); }
.nav-disclosure nav a:not(.button):hover { background: var(--cyan-soft); }

/* Desktop inline nav is OPTED INTO by main.js (matchMedia adds .nav-inline and sets [open]).
   A closed <details> does not render its children, so pure CSS cannot inline this menu at desktop
   widths — without JavaScript the summary button stays visible and usable instead. */
.nav-disclosure.nav-inline summary { display: none; }
.nav-disclosure.nav-inline nav {
  position: static; flex-direction: row; align-items: center; gap: 0.4rem;
  background: none; border: 0; padding: 0; box-shadow: none;
}
.nav-disclosure.nav-inline nav a { padding: 0.45rem 0.8rem; }

.header-call { display: none; }
@media (max-width: 799px) {
  .site-header { gap: 0.6rem; }
  .header-call { display: inline-block; margin-left: auto; }
}
@media (max-width: 479px) {
  .site-header { padding: 0.8rem 0.9rem; gap: 0.45rem; }
  .wordmark { font-size: 1.2rem; }
  .header-call { font-size: 0.9rem; }
  .nav-disclosure summary { padding: 0.42rem 0.85rem; font-size: 0.9rem; }
}

/* ---------- Buttons ---------- */
.button {
  display: inline-block; text-decoration: none; text-align: center;
  font-weight: 700; font-size: 1rem;
  background: var(--cyan); color: #fff;
  border: 2px solid var(--cyan); border-radius: 999px;
  padding: 0.8rem 1.8rem; cursor: pointer;
  transition: background 0.15s ease, transform 0.12s ease;
}
.button:hover { background: var(--cyan-deep); border-color: var(--cyan-deep); transform: translateY(-1px); }
.button-small { padding: 0.5rem 1.1rem; font-size: 0.94rem; }
.button-outline { background: transparent; color: var(--cyan-deep); border-color: var(--cyan); }
.button-outline:hover { background: var(--cyan); color: #fff; }
.button-sun { background: var(--sun); color: var(--ink); border-color: var(--sun-text); }
.button-sun:hover { background: var(--sun-deep); border-color: var(--sun-deep-text); }
.button-light { background: #fff; color: var(--cyan-deep); border-color: #fff; }
.button-light:hover { background: var(--cyan-soft); border-color: var(--cyan-soft); }
.call-link { font-weight: 700; color: var(--cyan-deep); text-decoration: none; white-space: nowrap; }
.call-link:hover { text-decoration: underline; }

/* ---------- Hero ---------- */
.hero { background: var(--wash); padding: 3rem 1.35rem 2.5rem; }
.hero-inner {
  max-width: 70rem; margin: 0 auto;
  display: grid; grid-template-columns: 1fr; gap: 2rem; align-items: center;
}
@media (min-width: 900px) { .hero-inner { grid-template-columns: 1.05fr 1fr; gap: 3rem; } }
.eyebrow {
  display: inline-block; font-size: 0.82rem; font-weight: 700;
  color: var(--cyan-deep); background: var(--cyan-soft);
  border-radius: 999px; padding: 0.35rem 0.95rem; margin-bottom: 1.1rem;
}
.hero h1 { font-size: clamp(2.4rem, 5.6vw, 3.8rem); max-width: 15ch; }
.hero h1 em { font-style: normal; color: var(--cyan); position: relative; }
.hero h1 em::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0.05em; height: 0.28em; background: var(--sun); z-index: -1; border-radius: 3px; }
.hero-sub { margin-top: 1.1rem; font-size: 1.12rem; max-width: 44ch; color: var(--muted); }
.hero-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.7rem; }
.hero-badges { display: flex; flex-wrap: wrap; gap: 0.5rem 1.3rem; margin-top: 1.5rem; }
.hero-badges li { font-size: 0.93rem; font-weight: 600; color: var(--cyan-deep); padding-left: 1.3rem; position: relative; }
.hero-badges li::before {
  content: ""; position: absolute; left: 0; top: 0.42em;
  width: 0.7rem; height: 0.7rem; border-radius: 50%; background: var(--sun);
}
.hero-plate { height: clamp(250px, 38vw, 380px); border-radius: var(--radius); border: 1px solid var(--line); display: block; width: 100%; object-fit: cover;}

/* ---------- Notice strip ---------- */
.notice { background: var(--cyan); color: #fff; padding: 1.15rem 1.35rem; }
.notice p { max-width: 70rem; margin: 0 auto; text-align: center; font-size: 0.98rem; }
.notice strong { color: inherit; }

/* ---------- Section frame + filter strip ---------- */
.section { max-width: 70rem; margin: 0 auto; padding: 3rem 1.35rem; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.section-head h2, .band h2 { font-size: clamp(1.8rem, 4vw, 2.6rem); }
.section-intro { margin-top: 0.6rem; max-width: 52ch; color: var(--muted); }
.filter-count { color: var(--cyan-deep); font-weight: 700; }

.strip { background: var(--cyan-soft); padding: 1.4rem 1.35rem; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.filter-form {
  max-width: 70rem; margin: 0 auto;
  display: grid; grid-template-columns: 1fr; gap: 0.85rem; align-items: end;
}
@media (min-width: 700px) { .filter-form { grid-template-columns: 1fr 1fr auto; } }
.filter-form .field label { color: var(--cyan-deep); font-size: 0.9rem; font-weight: 700; }
.filter-form select {
  width: 100%; margin-top: 0.35rem; padding: 0.7rem 0.8rem;
  font: inherit; color: var(--ink); background: var(--card);
  border: 1px solid var(--line); border-radius: 12px;
}

/* ---------- Cards ---------- */
.item-grid { display: grid; grid-template-columns: 1fr; gap: 1.4rem; margin-top: 1.9rem; }
@media (min-width: 620px) { .item-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .item-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; } }

.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.card:hover { transform: translateY(-3px); box-shadow: 0 16px 32px rgba(14, 151, 196, 0.16); }
.card-body { padding: 1.2rem 1.35rem 1.45rem; }
.card-head { display: flex; justify-content: space-between; gap: 0.75rem; align-items: baseline; }
.card-title { font-size: 1.25rem; }
.card-where { font-size: 0.86rem; font-weight: 700; color: var(--sun-deep-text); white-space: nowrap; }
.card-meta { margin-top: 0.45rem; color: var(--muted); font-size: 0.96rem; }
.card-tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.85rem; }
.card-tags li {
  font-size: 0.78rem; font-weight: 600; color: var(--cyan-deep);
  background: var(--cyan-soft); border-radius: 999px; padding: 0.22rem 0.75rem;
}
.card-art { height: 210px; display: block; width: 100%; object-fit: cover;}
.filter-empty { margin-top: 1.9rem; padding: 1.5rem; background: var(--card); border: 1px dashed var(--line); border-radius: var(--radius); }

/* ---------- CSS artwork (all imagery is authored gradients) ----------
   Construction rules, all learned by LOOKING at renders (see the library's art-rule list):
   1. `background-repeat: no-repeat` on the shared selector — a fractional layer tiles otherwise.
   2. Parts of an object must TOUCH, or they read as unrelated marks.
   3. Round things are DISCRETE radial-gradients sized in PIXELS (a % circle in a wide box is an
      ellipse); a glow needs a GRADUAL falloff or it renders as a solid disc. */

.art-spray, .art-window, .art-bucket, .art-mop, .art-sparkle {
  background-repeat: no-repeat;
  background-color: var(--cyan-soft);
}

/* Spray bottle: a body with a label, a trigger head sitting ON it, a nozzle off the top and a
   little burst of droplets fanning up from the nozzle. Parts overlap so they read as one object. */
/* Sparkling window: a framed pane with cross bars, a diagonal shine streak and a sparkle. */
/* Bucket of soapy water with bubbles rising off it. */
/* Mop: a handle and a fringed head on a floor. */
/* A just-cleaned surface: soft shine spots over a bright cyan sweep (gradual falloffs, not discs). */
/* ---------- The instant-quote estimator — this template's signature tool ---------- */
.estimator {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.75rem; margin-top: 1.9rem;
}
.estimator h2, .estimator h3 { font-size: 1.35rem; }
.estimator > p { color: var(--muted); margin-top: 0.5rem; max-width: 58ch; }
.est-controls { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-top: 1.5rem; }
@media (min-width: 680px) { .est-controls { grid-template-columns: repeat(2, 1fr); } }
.est-controls .field label { display: block; font-weight: 600; font-size: 0.95rem; }
.est-controls input, .est-controls select {
  width: 100%; margin-top: 0.35rem; padding: 0.72rem 0.8rem;
  font: inherit; color: var(--ink); background: var(--wash);
  border: 1px solid var(--line); border-radius: 12px;
}
.est-extras { margin-top: 0.3rem; }
.est-extras legend { font-weight: 600; font-size: 0.95rem; margin-bottom: 0.4rem; }
.est-check { display: flex; flex-wrap: wrap; gap: 0.6rem 1.2rem; }
.est-check label { display: inline-flex; align-items: center; gap: 0.45rem; font-weight: 500; }
.est-check input { width: auto; margin: 0; accent-color: var(--cyan); }
.est-out { margin-top: 1.6rem; border-top: 1px solid var(--line); padding-top: 1.4rem; }
.est-list { display: grid; grid-template-columns: 1fr; gap: 0; }
@media (min-width: 620px) { .est-list { grid-template-columns: 1fr 1fr; column-gap: 2.5rem; } }
.est-list li { display: flex; align-items: baseline; gap: 0.75rem; padding: 0.6rem 0; border-bottom: 1px solid var(--line); }
.est-list .what { color: var(--ink); }
.est-list .leader { flex: 1; border-bottom: 2px dotted var(--line); transform: translateY(-0.25em); min-width: 1.5rem; }
.est-list .qty { font-weight: 700; color: var(--cyan-deep); white-space: nowrap; }
.est-total {
  margin-top: 1.25rem; padding: 1rem 1.2rem; background: var(--cyan-soft);
  border-radius: 14px; display: flex; flex-wrap: wrap; gap: 0.5rem 1rem;
  align-items: baseline; justify-content: space-between;
}
.est-total .label { font-weight: 700; color: var(--cyan-deep); }
.est-total .value { font-size: 1.6rem; font-weight: 800; color: var(--cyan-deep); }
.est-caveat { margin-top: 1rem; font-size: 0.93rem; color: var(--muted); max-width: 62ch; }

/* The landing page leads with the tool (S125). The trust marks that used to live in the
   prose strip ABOVE the fold now sit under the calculator, where they answer the second
   question in this trade ("am I tied in?") right where the price has just been given. */
.estimator-trust { margin-top: 1.4rem; }

/* ---------- Feature grid + bands ---------- */
.feature-grid { display: grid; grid-template-columns: 1fr; gap: 1.3rem; margin-top: 1.9rem; }
@media (min-width: 700px) { .feature-grid { grid-template-columns: 1fr 1fr 1fr; } }
.feature-grid li { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.6rem; }
.feature-grid h3 { font-size: 1.2rem; margin-bottom: 0.45rem; }
.feature-grid p { color: var(--muted); font-size: 0.97rem; }

.band { background: var(--cyan); color: #fff; padding: 3.5rem 1.35rem; text-align: center; }
.band h2 { color: #fff; }
.band p { max-width: 50ch; margin: 0.9rem auto 1.7rem; color: #ffffff; }

/* ---------- Interior pages ---------- */
.page { max-width: 70rem; margin: 0 auto; padding: 1.5rem 1.35rem 3rem; }
.breadcrumb a { font-weight: 600; text-decoration: none; color: var(--muted); }
.breadcrumb a:hover { color: var(--cyan-deep); }
.page-hero { padding: 1.5rem 0 0.5rem; }
.page-hero h1 { font-size: clamp(2.1rem, 5.5vw, 3.2rem); }
.page-hero p { margin-top: 0.9rem; max-width: 54ch; color: var(--muted); }

/* ---------- Forms (preview-safe) ---------- */
.form-layout { display: grid; grid-template-columns: 1fr; gap: 2rem; margin-top: 1.9rem; }
@media (min-width: 860px) { .form-layout { grid-template-columns: 1.4fr 1fr; } }
.book-form {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.75rem; display: grid; grid-template-columns: 1fr; gap: 1rem; align-self: start;
}
@media (min-width: 620px) { .book-form { grid-template-columns: 1fr 1fr; } .field-wide { grid-column: 1 / -1; } }
.field label { display: block; font-weight: 600; font-size: 0.95rem; }
.label-optional { font-weight: 400; color: var(--muted); }
.field input, .field textarea, .field select {
  width: 100%; margin-top: 0.35rem; padding: 0.72rem 0.8rem;
  font: inherit; color: var(--ink); background: var(--wash);
  border: 1px solid var(--line); border-radius: 12px;
}
.book-form .button { justify-self: start; }
.form-status { grid-column: 1 / -1; font-weight: 600; color: var(--cyan-deep); min-height: 1.4em; }

.panel { background: var(--cyan-soft); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.75rem; align-self: start; }
.panel h2 { font-size: 1.35rem; }
.steps { counter-reset: step; margin-top: 1.2rem; }
.steps li { counter-increment: step; position: relative; padding: 0 0 1.25rem 3rem; }
.steps li::before {
  content: counter(step);
  position: absolute; left: 0; top: -0.05rem;
  width: 2rem; height: 2rem; display: grid; place-items: center;
  font-weight: 700; color: var(--ink); background: var(--sun); border-radius: 50%;
}
.steps h3 { font-size: 1.1rem; }
.steps p { color: var(--muted); font-size: 0.96rem; }
.note { margin-top: 1.5rem; color: var(--muted); font-size: 0.95rem; max-width: 60ch; }

/* ---------- Footer ---------- */
footer {
  background: var(--ink); color: #9db6bf;
  padding: 2.6rem 1.35rem;
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1.25rem;
}
.wordmark-footer { font-size: 1.4rem; font-weight: 800; letter-spacing: -0.02em; color: #fff; margin-bottom: 0.5rem; }
footer .call-link { color: var(--sun); }
.footer-truth { max-width: 34ch; font-size: 0.88rem; color: #6f8b95; align-self: end; }
/* Build credit — carried by every template in this library, matching the deployed demos. */
.footer-powered { margin-top: 0.9rem; font-size: 0.85rem; color: #6f8b95; }
.footer-powered a { color: #fff; text-decoration: underline; text-underline-offset: 2px; }
.footer-powered a:hover { color: var(--sun); }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .button:hover, .card:hover { transform: none; }
}

/* --- Touch targets ------------------------------------------------ S116
   A standalone control needs 44x44 CSS px (Apple HIG; WCAG 2.5.5 AAA, and 2.5.8 AA
   sets a 24px floor). The S116 polish pass measured the header phone link at 23px
   and the Menu button at 35px on a 390px viewport, on every template in the library.
   On a trades site the phone number IS the conversion — it was rendering at half the
   required size at exactly the width most visitors arrive on.

   Layout only, no colour, so this block is copy-paste identical across every palette
   in the library. Inline links inside prose are deliberately NOT touched: both WCAG
   target-size rules exempt them, and padding them out would wreck the body copy. */
@media (max-width: 799px) {
  .header-call,
  .nav-disclosure summary,
  .nav-disclosure nav .call-link,
  .button,
  .button-small,
  button[type="submit"] {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}
