/* --- Hero --------------------------------------------------------------- */

/* The band does not end on a straight line. A white wave is laid over its foot,
 * so the mint reads as flowing into the page below rather than stopping at a
 * ruled edge — which is the single thing that made this look like a boxed
 * banner bolted onto a document. The extra bottom padding is the room that wave
 * occupies; without it the wave would sit on top of the copy. */
.hero {
  position: relative;
  background: var(--mint);
  padding: var(--space-16) 0 calc(var(--space-12) + 60px);
  overflow: hidden;
}
.hero::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  /* -1px: at some zoom levels a 0 offset leaves a hairline of mint showing
     under the wave, which is exactly the hard edge this removes. */
  bottom: -1px;
  height: 76px;
  z-index: 3;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 76' preserveAspectRatio='none'%3E%3Cpath fill='%23ffffff' d='M0 76h1440V26c-150 26-300 34-470 20S650 4 500 12 160 48 0 30z'/%3E%3C/svg%3E")
    no-repeat center / 100% 100%;
}
/* The band does not START on a straight line either. The masthead is white and
 * the band is mint; without this they meet at a ruled edge across the full
 * width, which is the boundary the wireframe does not have. Same wave as the
 * foot, mirrored, in white so it reads as the header spilling into the band.
 *
 * (The decorative bubbles that used to live on this pseudo-element are now in
 * the hero SVG, where they scale with the blob instead of drifting away from
 * it at different window sizes.) */
.hero::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -1px;
  height: 44px;
  z-index: 3;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 44' preserveAspectRatio='none'%3E%3Cpath fill='%23ffffff' d='M0 0h1440v18c-140-16-286-20-448-8s-330 26-486 18S150 4 0 20z'/%3E%3C/svg%3E")
    no-repeat center / 100% 100%;
}
.hero .shell {
  position: relative;
}
/* One column. The artwork is positioned against `.hero`, not placed in a grid
 * cell, so the copy simply stops short of it rather than sharing a track with
 * something that extends past the container.
 *
 * The split only happens at 1024px. It used to start at 900, which squeezed the
 * copy into a 52% column barely 430px wide while the headline was still at its
 * large size — the "smooshed" state. Below 1024 the artwork goes underneath at
 * full width, which is what a phone and a portrait tablet both want. */
.hero-grid {
  display: grid;
  gap: var(--space-8);
}
@media (min-width: 1024px) {
  .hero-grid {
    min-height: 470px;
    align-content: center;
  }
  /* The COPY is constrained, not the grid. Narrowing `.hero-grid` looked right
   * but was wrong: `.shell` carries `margin: 0 auto`, so a max-width on that
   * same element CENTRES the narrowed column in the viewport instead of leaving
   * it at the shell's left edge — which walked the text rightwards until it sat
   * underneath the frame. */
  .hero-copy {
    max-width: 560px;
  }
}
.hero h1 {
  margin-bottom: var(--space-6);
}
.hero .lede {
  font-size: 1.125rem;
  color: var(--ink-soft);
  max-width: 46ch;
}
/* "on wheels." is the playful brush script from the style guide — Pacifico,
 * self-hosted. The previous version fell through to whatever cursive the OS
 * happened to have, which on this machine resolved to an italic serif: formal,
 * not whimsical, and the opposite of the brief.
 *
 * Pacifico carries a tall ascender and a deep descender, so it needs its own
 * line-height and a nudge down from the line above; at the shared 1.15 it
 * collided with the cap line of "Gentle grooming". */
.hero-script {
  display: block;
  margin-top: 0.12em;
  color: var(--teal-text);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.18em;
  line-height: 1.35;
  letter-spacing: 0;
}
.hero-heart {
  color: var(--pink);
  font-family: var(--font-body);
  font-size: 0.62em;
  vertical-align: 0.22em;
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-8);
}

/* --- The hero frame ----------------------------------------------------- */

/* On a phone the frame sits under the copy at full width. From the two-column
 * breakpoint it leaves the flow and pins to the RIGHT EDGE OF THE VIEWPORT,
 * which is what makes it run off the page. Absolute positioning against `.hero`
 * rather than a negative margin: the shell is a centred max-width box, so the
 * distance from its edge to the viewport edge changes with every window size
 * and no single margin value reaches it. */
.hero-art {
  margin-top: var(--space-8);
  height: clamp(240px, 62vw, 420px);
}
@media (min-width: 1024px) {
  .hero-art {
    /* Full band height, so the frame runs from under the masthead down to the
     * wave at the foot with no band of flat colour above or below it. */
    position: absolute;
    inset: 0 0 0 auto;
    width: 43vw;
    max-width: 660px;
    height: auto;
    margin-top: 0;
    z-index: 1;
  }
}

.hero-frame {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* The pale line running outside the frame. Her mint at full strength vanishes
 * against the hero background, so this is one step darker: same hue, enough
 * separation to read as a drawn line. */
.hero-frame-rule {
  fill: none;
  stroke: #bfe4ec;
  stroke-width: 2.6;
}

/* The white ring. A CENTRED stroke on the aperture path — half of it falls
 * outside the window and half inside, and the image drawn afterwards covers the
 * inside half exactly. One stroke rather than two shapes means the ring cannot
 * develop a seam or vary in width at any size. */
.hero-frame-border {
  fill: none;
  stroke: var(--white);
  stroke-width: 22;
  stroke-linejoin: round;
}

.hero-frame-bubbles circle {
  fill: rgba(255, 255, 255, 0.55);
  stroke: #bfe4ec;
  stroke-width: 2;
}

/* The four reassurance points under the hero copy. One row on a desktop, as the
 * wireframe has them; `auto-fit` alone let them wrap to two ragged rows. */
.hero-features {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4) var(--space-5);
}
/* Four across only once the copy column is wide enough to hold them without the
 * labels wrapping to three lines each. Below that, two-by-two reads far better
 * than four squeezed columns. */
@media (min-width: 1320px) {
  .hero-features {
    grid-template-columns: repeat(4, 1fr);
  }
}
.hero-feature {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.3;
}
.hero-feature .icon {
  flex: none;
  color: var(--pink);
}
/* Four narrow columns break badly on their own — "Clean, Safe &" / "Comfortable"
 * strands the ampersand. `balance` lets the browser even the line lengths. */
.hero-feature span {
  text-wrap: balance;
}

/* --- Bands -------------------------------------------------------------- */

.band {
  background: var(--teal);
  color: var(--white);
  padding: var(--space-12) 0;
}
.band h2 {
  color: var(--white);
}
.band a {
  color: var(--white);
}
.band-split {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 900px) {
  .band-split {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-12);
  }
}

.checklist {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--space-4);
}
.checklist li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-weight: 500;
}
.checklist .icon {
  flex: none;
  margin-top: 2px;
}

/* --- Service cards ------------------------------------------------------ */

.cards {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}
@media (min-width: 620px) {
  .cards {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 1040px) {
  .cards {
    grid-template-columns: repeat(4, 1fr);
  }
}
.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow);
}
.card h3 {
  color: var(--pink-text);
}

.service-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.service-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lifted);
}
.service-card-art {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--mint);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
/* The asset is already cropped to 16:10, so `cover` here only absorbs sub-pixel
 * rounding — it is not doing the framing. */
.service-card-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.service-card-badge {
  position: absolute;
  left: 50%;
  bottom: calc(var(--space-6) * -1);
  transform: translateX(-50%);
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--pink);
  color: var(--pink);
  box-shadow: var(--shadow);
}
.service-card-body {
  padding: var(--space-8) var(--space-6) var(--space-6);
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex: 1;
}
.service-card-body h3 {
  margin: 0;
  color: var(--ink);
  font-size: 1.125rem;
}
.service-card-body p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.9375rem;
}
.service-card-body .more {
  margin-top: auto;
  padding-top: var(--space-4);
  color: var(--teal-text);
  font-weight: 600;
  text-decoration: none;
}
.service-card-body .more:hover {
  text-decoration: underline;
}

/* --- How it works ------------------------------------------------------- */

.steps {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: 1fr;
  text-align: center;
}
@media (min-width: 560px) {
  .steps {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 940px) {
  .steps {
    grid-template-columns: repeat(4, 1fr);
  }
}
.step-icon {
  width: 84px;
  height: 84px;
  margin: 0 auto var(--space-4);
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--teal);
  color: var(--teal-text);
}
.step h3 {
  font-size: 1rem;
  margin-bottom: var(--space-2);
}
.step p {
  color: var(--ink-soft);
  font-size: 0.9375rem;
  margin: 0;
}

/* --- Closing call to action --------------------------------------------- */

.cta-split {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 900px) {
  .cta-split {
    grid-template-columns: 1fr 1fr;
  }
}
.cta-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}
/* White-on-teal outline, the style guide's secondary treatment inverted for a
 * coloured band — a white-background button here would read as a hole. */
.btn-on-band {
  background: transparent;
  color: var(--white);
  border-color: var(--white);
}
.btn-on-band:hover {
  background: rgba(255, 255, 255, 0.14);
}
/* The van illustration, from the client's own 1024x447 artwork. `height: auto`
 * with the intrinsic width/height on the element keeps its aspect ratio — it was
 * being squashed by a grid track stretching it to the row height.
 *
 * The cap was 420px when this came off the wireframe at 283px native and
 * anything wider was visible upscaling. The supplied file is 1009px after
 * trimming, so 500px still lands at 2x on a HiDPI screen. */
.cta-van {
  width: 100%;
  max-width: 500px;
  height: auto;
  display: block;
  justify-self: center;
  align-self: center;
}

/* Photographs sitting inside a coloured band. Rounded and framed so the picture
 * reads as placed on the band rather than punched through it. */
.band-photo {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius-lg);
  border: 5px solid var(--white);
  box-shadow: var(--shadow-lifted);
}
