/* ==========================================================================
   Mobi-Vac service page components.
   Loaded after styles.css, which supplies the tokens.
   ========================================================================== */

/* ---------- service hero, with the quote form sitting in it ---------- */
.shero { position: relative; background: var(--indigo); overflow: hidden; }
.shero__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 42%; }
/* matches the homepage hero overlay exactly */
.shero::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(96deg, rgba(33,22,82,.75) 0%, rgba(33,22,82,.58) 46%, rgba(33,22,82,.16) 100%);
}
.shero__inner {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(32px, 4vw, 52px);
  /* the form is the tall column, so centre the headline against it rather than
     letting it sit up against the breadcrumb */
  align-items: center;
  padding-top: clamp(18px, 2.6vh, 34px); padding-bottom: clamp(26px, 4vh, 48px);
}
/* breadcrumb stays at the top of the band, out of the centred group */
.shero__crumbs { position: absolute; top: clamp(14px, 2vh, 26px); left: 0; right: 0; z-index: 3; }
.shero h1 { color: #fff; margin-bottom: 26px; max-width: 15ch; font-size: clamp(1.9rem, 3.6vw, 2.9rem); }
.shero__sub { color: #F7F7F7; font-size: clamp(.98rem, 1.3vw, 1.1rem); line-height: 1.5; max-width: 52ch; margin: 0 0 20px; }

.crumbs { display: flex; flex-wrap: wrap; gap: 8px; font-size: 13px; margin: 0; color: rgba(255,255,255,.6); }
.crumbs a { color: rgba(255,255,255,.8); }
.crumbs a:hover { color: var(--amber); text-decoration: none; }
.crumbs span { color: rgba(255,255,255,.45); }

.pill {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--amber); color: #fff;
  font-size: 12px; font-weight: 700; letter-spacing: .07em;
  padding: 7px 14px; border-radius: 99px; margin: 0 0 24px;
}

.checks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.checks li { display: flex; align-items: flex-start; gap: 11px; color: #fff; font-size: 14.5px; line-height: 1.45; }
.checks svg { flex: none; margin-top: 3px; color: var(--amber); }

/* the form card itself */

/* ---------- two column body with a sticky rail ---------- */
.layout { display: grid; grid-template-columns: minmax(0, 1fr) 356px; gap: 60px; align-items: start; }
/* The rail travels with the reader; 96px clears the sticky header.
   max-height is the safety net: on a short viewport the rail scrolls internally
   rather than having its bottom card clipped where it can never be reached. */
/* The rail is a plain column by default, so it is always fully visible.
   Two earlier attempts failed: capping its height clipped the bottom card, and a fade
   mask to disguise that just turned the last card's grey to white. Instead it only
   becomes sticky when the window is tall enough to show the whole thing. */
.rail { display: flex; flex-direction: column; gap: 14px; }
@media (min-height: 740px) {
  .rail { position: sticky; top: 96px; }
}

.pricecard { background: var(--indigo); border-radius: var(--radius); padding: 24px 24px 22px; color: #fff; }
.pricecard .eyebrow { margin-bottom: 8px; }
.pricecard__fig { font-family: 'Montserrat', sans-serif; font-weight: 700; font-size: 1.95rem; color: #fff; line-height: 1.1; }
.pricecard__unit { font-size: 12.5px; color: rgba(255,255,255,.7); margin: 3px 0 12px; }
.pricecard__fig--gst { margin-bottom: 12px; }
.pricecard__gst { font-family: 'Open Sans', system-ui, -apple-system, sans-serif; font-weight: 400; font-size: 13px; color: rgba(255,255,255,.8); margin-left: 2px; vertical-align: top; position: relative; top: 3.5px; }
.pricecard__note { font-size: 13px; color: rgba(255,255,255,.8); line-height: 1.5; margin: 0 0 16px; }
.pricecard .btn { margin-left: auto; margin-right: auto; }
.pricecard .btn + .btn { margin-top: 9px; }

.railcard { background: var(--band); border-radius: var(--radius); padding: 18px 20px; }
.railcard .stars { color: var(--amber); letter-spacing: 2px; font-size: 13px; margin-bottom: 8px; }
.railcard blockquote { margin: 0 0 10px; font-size: 14px; line-height: 1.55; color: var(--ink); }
.railcard cite { display: block; font-style: normal; font-family: 'Montserrat', sans-serif; font-weight: 700; font-size: 13px; color: var(--indigo); }

.ticks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.ticks li { display: flex; align-items: flex-start; gap: 10px; font-size: 13.5px; line-height: 1.45; }
.ticks svg { flex: none; margin-top: 2px; color: var(--amber); }

/* ---------- prose ---------- */
.prose h2 { margin-top: 0; }
.prose h3 { font-size: 1.25rem; margin: 38px 0 12px; }
.prose p { margin: 0 0 16px; }
.prose > *:last-child { margin-bottom: 0; }

/* ---------- included checklist ---------- */
.included { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin-top: 28px; padding: 0; list-style: none; }
.included li {
  position: relative;
  display: flex; align-items: flex-start; gap: 14px;
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
  padding: 20px 22px; font-size: 15px; line-height: 1.5; font-weight: 600; color: var(--indigo);
  box-shadow: var(--shadow-sm);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.included li:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: #d5d2e0; }
/* the tick gets its own amber disc so it reads as a mark, not punctuation */
.included svg {
  flex: none; width: 26px; height: 26px; padding: 5px; border-radius: 50%;
  background: rgba(223,134,74,.14); color: var(--amber);
}

/* ---------- interactive process ----------
   Four steps across a connecting rail. Selecting one opens a detail panel below,
   so the summary stays scannable and the depth is there for anyone who wants it. */
.steps { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-top: 38px; }
/* the rail sits behind the markers, trimmed to start and end under the first and last */
.steps::before {
  content: ''; position: absolute; top: 23px; left: 12.5%; right: 12.5%; height: 2px;
  background: rgba(255,255,255,.22); z-index: 0;
}
.step {
  position: relative; z-index: 1; background: none; border: 0; padding: 0; margin: 0;
  text-align: center; cursor: pointer; font: inherit; color: inherit;
  display: flex; flex-direction: column; align-items: center;
}
.step__n {
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--indigo); border: 2px solid rgba(255,255,255,.32); color: rgba(255,255,255,.75);
  display: grid; place-items: center;
  font-family: 'Montserrat', sans-serif; font-weight: 700; font-size: 15px;
  margin-bottom: 14px;
  transition: background .2s ease, border-color .2s ease, color .2s ease, transform .2s ease;
}
.step h3 { font-size: 1rem; margin-bottom: 5px; color: #fff; transition: color .2s ease; }
.step__hint { font-size: 12.5px; color: rgba(255,255,255,.6); }
.step:hover .step__n { border-color: var(--amber); color: var(--amber); transform: translateY(-2px); }
.step[aria-selected="true"] .step__n { background: var(--amber); border-color: var(--amber); color: #fff; }
.step[aria-selected="true"] h3 { color: var(--amber); }

/* the panel stays white so the detail copy reads as the answer, not more chrome */
.step-detail {
  margin-top: 34px; background: #fff; border-radius: var(--radius);
  padding: 28px 30px; box-shadow: var(--shadow-lg);
  display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 20px;
  /* centred so the marker sits against the middle of the copy regardless of how many
     lines it runs to, which keeps the padding even top and bottom */
  align-items: center;
}
.step-detail__icon {
  width: 44px; height: 44px; border-radius: 50%; background: var(--amber); color: #fff;
  display: grid; place-items: center; font-family: 'Montserrat', sans-serif; font-weight: 700;
}
.step-detail p { margin: 0; color: var(--muted); font-size: 15px; line-height: 1.65; }
@media (prefers-reduced-motion: no-preference) {
  .step-detail__body { animation: step-fade .28s ease; }
}
@keyframes step-fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------- recent work carousel ----------
   Continuously sliding, same approach as the client logo banner: the track holds
   the same group twice and translates -50%, so the loop is seamless. */
.slider {
  position: relative; margin-top: 34px; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}
.slider__track { display: flex; width: max-content; animation: work-marquee 56s linear infinite; }
.slider:hover .slider__track { animation-play-state: paused; }
/* With slider.js running the loop is driven by scrollLeft instead, so the reader can
   grab it. The CSS animation stays as the no-JS fallback and is switched off here. */
.slider--drag { overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; cursor: grab; }
.slider--drag::-webkit-scrollbar { display: none; }
.slider--drag .slider__track { animation: none; }
.slider--drag.is-dragging { cursor: grabbing; }
.slider--drag.is-dragging .slide { user-select: none; }
.slider--drag .slide img { -webkit-user-drag: none; user-drag: none; }
.slider__group { display: flex; gap: 22px; padding-right: 22px; flex: none; }
@keyframes work-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

.slide {
  flex: 0 0 340px;
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.slide img { width: 100%; height: 230px; object-fit: cover; }
.slide__cap { padding: 16px 18px 18px; }
.slide__cap h3 { font-size: 1rem; margin-bottom: 5px; }
.slide__cap p { margin: 0; font-size: 13.5px; color: var(--muted); line-height: 1.5; }

.slider__hint { margin-top: 16px; font-size: 13px; color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .slider { overflow-x: auto; }
  .slider__track { animation: none; }
}

/* ---------- locations ----------
   Pills pick an area, the panel below swaps the map and the detail. */
.areas-pills { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 28px; }
.areas-pills button {
  display: inline-flex; align-items: center; gap: 8px;
  background: #fff; border: 1px solid var(--border); border-radius: 99px;
  padding: 10px 20px; font-family: 'Open Sans', sans-serif; font-size: 14.5px; font-weight: 600;
  color: var(--indigo); cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.areas-pills button:hover { border-color: var(--amber); color: var(--amber); }
.areas-pills button[aria-selected="true"] { background: var(--indigo); border-color: var(--indigo); color: #fff; }
.areas-pills button:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }

.area-panel {
  display: grid; grid-template-columns: 1.15fr 1fr; margin-top: 26px;
  background: #fff; border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-lg);
}
.area-panel__map { position: relative; min-height: 360px; background: var(--band); }
.area-panel__map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; z-index: 1; }
/* the maps are kept and stacked rather than reloaded, so the inactive ones must stay
   hidden: this rule's display:block would otherwise beat the UA [hidden] rule */
.area-panel__map iframe[hidden] { display: none; }
/* behind the frame, so it only shows where the map cannot load */
.area-panel__fallback {
  position: absolute; inset: 0; z-index: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  padding: 24px; text-align: center; color: var(--muted);
}
.area-panel__fallback svg { color: var(--amber); }
.area-panel__fallback strong { font-family: 'Montserrat', sans-serif; font-size: 1.1rem; color: var(--indigo); }
.area-panel__fallback a { font-size: 14px; font-weight: 700; }
.area-panel__body { padding: 34px 36px; display: flex; flex-direction: column; }
.area-panel__body h3 { font-size: 1.5rem; margin-bottom: 12px; }
.area-panel__body > p { margin: 0 0 22px; color: var(--muted); font-size: 15px; line-height: 1.6; }

.area-facts { list-style: none; margin: 0 0 26px; padding: 0; display: flex; flex-direction: column; gap: 13px; }
.area-facts li { display: flex; align-items: center; gap: 12px; font-size: 14.5px; }
.area-facts svg { flex: none; color: var(--amber); }
.area-facts a { color: var(--indigo); font-weight: 600; }
.area-facts a:hover { color: var(--amber); text-decoration: none; }
.area-panel .btn { align-self: flex-start; margin-top: auto; }

@media (max-width: 900px) {
  .area-panel { grid-template-columns: 1fr; }
  .area-panel__map { min-height: 260px; }
  .area-panel__body { padding: 26px 24px 28px; }
}

/* ---------- closing CTA band ---------- */
.cta-band { display: flex; align-items: center; justify-content: space-between; gap: 40px; flex-wrap: wrap; }
.cta-band__actions { display: flex; gap: 14px; flex-wrap: wrap; }

@media (max-width: 1100px) {
  .layout { grid-template-columns: minmax(0, 1fr) 320px; gap: 40px; }
  .shero__inner { gap: 40px; }
}
@media (max-width: 980px) {
  .shero__inner { grid-template-columns: 1fr; gap: 38px; padding-top: 30px; padding-bottom: 56px; }
  .shero h1 { max-width: none; }
  .layout { grid-template-columns: minmax(0, 1fr); gap: 44px; }
  .rail { position: static; }
  .steps { grid-template-columns: repeat(2, 1fr); gap: 28px; }
  .steps::before { display: none; }
  .locations { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 660px) {
  .included, .steps { grid-template-columns: 1fr; }
  .locations { grid-template-columns: repeat(2, 1fr); }
  .slide { flex-basis: 260px; }
  .slide img { height: 180px; }
}

/* ---------- hero focal points ----------
   The hero crops hard and in different directions depending on the viewport: on a wide
   screen the box is ~2:1 so only about a third of a portrait photo's height survives
   (vertical position matters); on tablet and phone the box is taller than the photo, so
   the full height shows and it crops sideways instead (horizontal position matters).
   Because the two never apply at once, X and Y can be tuned independently per photo to
   keep the subject in frame at every width. ---------- */
.shero__bg--gutter   { object-position: 50% 42%; }
.shero__bg--wash     { object-position: 30% 22%; }  /* the spray arc, upper left */
.shero__bg--roof     { object-position: 25% 14%; }  /* operator on the roof, top left */
.shero__bg--driveway { object-position: 55% 42%; }  /* operator and the mist, centre right */
.shero__bg--solar    { object-position: 50% 45%; }  /* the basket, centre */
.shero__bg--bird     { object-position: 50% 42%; }
.shero__bg--commercial { object-position: 50% 35%; }  /* the basket and the building */

/* ---------- about page ----------
   The About hero carries no form, so the two-column grid collapses to a single
   readable column instead of leaving a hole where the card would sit. */
/* Without the form the hero is short, so the content has to be pushed clear of the
   absolutely positioned breadcrumb rather than sliding underneath it. */
.shero--solo .shero__inner {
  grid-template-columns: 1fr;
  padding-top: clamp(66px, 9vh, 104px);
  padding-bottom: clamp(54px, 7.5vh, 88px);
}
.shero--solo .shero__inner > div { max-width: 62ch; }
.shero--solo .shero__sub { margin-bottom: 28px; }
.shero__bg--about { object-position: 50% 52%; }

/* ---------- the three differentiators ----------
   On this page they run as a centred three up row with the icons sized up, rather than
   the icon-beside-text list the homepage uses. Everything is scoped to .usps--about and
   .about-apart so the homepage .usps list keeps its own layout. */
.about-apart { text-align: center; }
.about-apart .eyebrow { justify-content: center; }
.about-apart h2 { max-width: 20ch; margin-left: auto; margin-right: auto; }
.about-apart .lead { max-width: 62ch; margin-left: auto; margin-right: auto; }

.usps--about {
  margin-top: 52px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 44px 40px;
}
/* block, not the base 56px icon column grid, so the icon sits above the text */
.usps--about .usp { display: block; text-align: center; }
/* a fixed icon row height: the three PNGs differ in aspect ratio, and without it the
   headings below them sit at three different heights */
.usps--about .usp__icon { display: flex; align-items: center; justify-content: center; height: 96px; margin-bottom: 18px; }
.usps--about .usp__icon img { width: 88px; }
.usps--about .usp h3 { color: #fff; font-size: 1.15rem; margin-bottom: 10px; }
.usps--about .usp p { color: rgba(255,255,255,.78); max-width: 34ch; margin: 0 auto; }

@media (max-width: 900px) {
  .usps--about { gap: 38px 28px; }
  .usps--about .usp__icon { height: 80px; }
  .usps--about .usp__icon img { width: 72px; }
}
/* one per row on phones, where three columns leave the text too narrow to read */
@media (max-width: 620px) {
  .usps--about { grid-template-columns: minmax(0, 1fr); margin-top: 40px; }
}

/* service tiles: a plain, tappable index of everything we do */
.svc-tile {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius);
  padding: 20px 22px; color: var(--indigo); font-weight: 700; font-size: 15px;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.svc-tile svg { flex: none; color: var(--amber); }
.svc-tile:hover {
  text-decoration: none; border-color: var(--amber);
  box-shadow: var(--shadow-md); transform: translateY(-2px);
}

/* On narrow screens the breadcrumb rejoins the normal flow instead of floating over the
   hero. Absolutely positioned it was landing on top of the pill once the hero columns
   stacked, and in flow it also copes on its own with wrapping to a second line. */
@media (max-width: 980px) {
  /* relative, not static: it still needs to be a positioned element for its z-index to
     apply, otherwise the hero overlay paints straight over the breadcrumb */
  .shero__crumbs { position: relative; top: auto; left: auto; right: auto; padding-top: 18px; }
  .shero__inner,
  .shero--solo .shero__inner { padding-top: 22px; }
}

/* ---------- centred service/about hero on phones ----------
   Matches the homepage hero. The ticked USP list keeps its left alignment. */
@media (max-width: 720px) {
  .shero__inner { text-align: center; }
  .shero__crumbs .crumbs { justify-content: center; }
  .shero h1, .shero__sub { max-width: none; }
  .shero .pill { margin-left: auto; margin-right: auto; }
  .shero .hero__cta { justify-content: center; }
  .checks { text-align: left; max-width: 22em; margin-left: auto; margin-right: auto; }
}

/* ---------- legal pages ----------
   A single readable column. The hero drops the photo and gradient because a policy page
   does not need a banner, just a clear title. */
.shero--legal { background: var(--indigo); }
.shero--legal .shero__inner { padding-top: clamp(40px, 5vh, 62px); padding-bottom: clamp(34px, 4.5vh, 54px); }
.legal__updated { color: rgba(255,255,255,.6); font-size: 13px; margin: 0; }

.legal { max-width: 780px; }
.legal h2 {
  font-size: 1.32rem; margin: 44px 0 14px;
  padding-top: 26px; border-top: 1px solid var(--border);
}
.legal h2:first-of-type { margin-top: 8px; }
.legal p { margin: 0 0 16px; color: var(--ink); }
.legal__list { list-style: none; margin: 0 0 18px; padding: 0; }
.legal__list li {
  position: relative; padding-left: 20px; margin-bottom: 10px;
  color: var(--ink); line-height: 1.65;
}
.legal__list li::before {
  content: ''; position: absolute; left: 0; top: 11px;
  width: 7px; height: 7px; border-radius: 50%; background: var(--amber);
}
.legal a { font-weight: 600; }

/* ---------- 404 ----------
   Light page with the coloured whale, so it reads as a friendly dead end rather than
   another dark sales banner. */
.notfound {
  background: #fff;
  min-height: 78vh;
  display: flex; align-items: center;
  padding: 60px 0 72px;
  text-align: center;
}
.notfound__inner { display: flex; flex-direction: column; align-items: center; }
.notfound__whale {
  width: clamp(120px, 16vw, 176px); height: auto;
  margin-bottom: 18px;
}
.notfound__code {
  font-family: 'Montserrat', sans-serif; font-weight: 700;
  font-size: clamp(4.4rem, 15vw, 9rem); line-height: .9;
  color: var(--amber); margin: 0 0 10px; letter-spacing: -.03em;
}
.notfound h1 {
  color: var(--indigo); max-width: 18ch; margin: 0 0 16px;
  font-size: clamp(1.5rem, 3.4vw, 2.4rem);
}
.notfound__sub {
  color: var(--muted); max-width: 54ch;
  font-size: clamp(1rem, 1.3vw, 1.1rem); line-height: 1.6; margin: 0 0 30px;
}
.notfound .hero__cta { justify-content: center; }
.notfound__links {
  margin: 34px 0 0; font-size: 14px; line-height: 2;
  color: var(--muted); max-width: 60ch;
}
.notfound__links a { color: var(--indigo); font-weight: 600; }
.notfound__links a:hover { color: var(--amber); text-decoration: none; }
