/* ==========================================================================
   LaundryMate — modern & friendly
   Soft rounded cards, warm tinted sections, generous colour and roomy type.
   Photography sits inset inside cards so everything feels contained and calm.
   ========================================================================== */

/* Metric-matched fallbacks. The browser paints text in these instantly, then
   swaps to the real font with no change in line height or width — which is what
   removes the layout shift a normal font swap causes. */
@font-face {
  font-family: 'Figtree Fallback';
  src: local('Arial'), local('Helvetica Neue'), local('Roboto');
  size-adjust: 98%;
  ascent-override: 94%;
  descent-override: 24%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'DM Mono Fallback';
  src: local('Courier New'), local('monospace');
  size-adjust: 108%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

:root {
  --ink: #14243A;
  --ink-2: #5A6B80;
  --ink-3: #8A99AC;

  --brand: #0A57A2;
  --brand-600: #1272CE;
  --brand-700: #084680;
  --sky-50: #EFF6FE;
  --sky-100: #DCEBFB;

  --mint: #0FA97F;  --mint-50: #E7F8F1;
  --sun:  #F0A828;  --sun-50:  #FEF5E4;  --sun-100: #FBE3B4;
  --coral:#F0674F;  --coral-50:#FEEDEA;
  --rose: #D4463A;  --rose-50: #FDEDEB;

  --cream: #FDF8F3;
  --line: #E7EDF4;
  --line-2: #F1F5F9;
  --paper: #FFFFFF;

  --r-sm: 10px;
  --r: 16px;
  --r-lg: 22px;
  --r-xl: 30px;

  --shadow-sm: 0 1px 2px rgba(20,36,58,.05), 0 2px 6px rgba(20,36,58,.04);
  --shadow: 0 2px 6px rgba(20,36,58,.05), 0 10px 26px rgba(20,36,58,.07);
  --shadow-lg: 0 4px 12px rgba(20,36,58,.06), 0 20px 48px rgba(20,36,58,.11);
  --shadow-brand: 0 8px 22px rgba(10,87,162,.26);

  --font-display: 'Figtree', 'Figtree Fallback', system-ui, -apple-system, sans-serif;
  --font-body: 'Figtree', 'Figtree Fallback', system-ui, -apple-system, sans-serif;
  --font-mono: 'DM Mono', 'DM Mono Fallback', ui-monospace, Menlo, monospace;

  --wrap: 1220px;
  --gut: clamp(20px, 5vw, 44px);
  --ease: cubic-bezier(.22,.61,.36,1);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; }
}
body {
  margin: 0; font-family: var(--font-body); font-size: 17px; line-height: 1.72;
  color: var(--ink-2); background: var(--paper);
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
img, svg, video { max-width: 100%; display: block; }
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-700); }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--brand-600); outline-offset: 3px; border-radius: 8px; }

h1,h2,h3,h4 { font-family: var(--font-display); color: var(--ink); margin: 0 0 .5em; font-weight: 700; }
h1 { font-size: clamp(2.4rem, 5vw, 3.9rem); line-height: 1.08; letter-spacing: -.028em; }
h2 { font-size: clamp(1.85rem, 3.4vw, 2.7rem); line-height: 1.14; letter-spacing: -.022em; }
h3 { font-size: clamp(1.1rem, 1.7vw, 1.3rem); line-height: 1.35; letter-spacing: -.012em; }
p { margin: 0 0 1.15em; } p:last-child { margin-bottom: 0; }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gut); }
.section { padding-block: clamp(68px, 9vw, 128px); position: relative; }
.section--foam { background: var(--sky-50); }
.section--tight { padding-block: clamp(48px, 6vw, 80px); }
.section--ink { background: var(--ink); color: #A9BACD; }
.section--ink h2, .section--ink h3 { color: #fff; }
.center { text-align: center; }
.stack > * + * { margin-top: 1rem; }

.eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  background: var(--sky-100); color: var(--brand);
  padding: .38rem .9rem; border-radius: 999px;
  font-size: .78rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  margin-bottom: 1.3rem;
}
.eyebrow::before { content:''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.section--ink .eyebrow { background: rgba(255,255,255,.12); color: #A8D0F5; }
.sec-head { max-width: 680px; margin-bottom: clamp(40px, 5vw, 68px); }
.sec-head.center { margin-inline: auto; }
.sec-head p { font-size: 1.08rem; color: var(--ink-2); margin-bottom: 0; }
.sec-head p + p { margin-top: .8rem; }

/* buttons — full pill, friendly */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  padding: .92rem 1.7rem; border-radius: 999px; border: 2px solid transparent;
  font-weight: 700; font-size: .97rem; letter-spacing: -.008em; cursor: pointer; text-align: center;
  transition: transform .2s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn svg { width: 18px; height: 18px; flex: none; }
.btn--primary { background: var(--brand); color: #fff; box-shadow: var(--shadow-brand); }
.btn--primary:hover { background: var(--brand-600); color: #fff; box-shadow: 0 12px 30px rgba(10,87,162,.34); }
.btn--ghost { background: #fff; color: var(--ink); border-color: var(--line); box-shadow: var(--shadow-sm); }
.btn--ghost:hover { border-color: var(--brand); color: var(--brand); }
.btn--danger { background: var(--rose); color: #fff; box-shadow: 0 8px 22px rgba(212,70,58,.28); }
.btn--danger:hover { background: #B23A2F; color: #fff; }
.btn--wa { background: #1FAF54; color: #fff; box-shadow: 0 8px 22px rgba(31,175,84,.28); }
.btn--wa:hover { background: #1A9749; color: #fff; }
.btn--light { background: #fff; color: var(--brand); }
.btn--light:hover { background: var(--sky-50); color: var(--brand-700); }
.btn--outline-light { background: transparent; color: #fff; border-color: rgba(255,255,255,.36); }
.btn--outline-light:hover { border-color: #fff; background: rgba(255,255,255,.1); color: #fff; }
.btn--sm { padding: .6rem 1.2rem; font-size: .88rem; border-width: 2px; }
.btn--block { width: 100%; }
.btn[disabled] { opacity: .45; pointer-events: none; }

/* "See more" style links. The arrow slides instead of the whole button lifting,
   which reads as a quieter, forward motion — right for a secondary link that
   sits under a grid rather than competing with the primary call to action. */
.btn--arrow svg { transition: transform .25s var(--ease); }
.btn--arrow:hover { transform: none; box-shadow: var(--shadow); }
.btn--arrow:hover svg { transform: translateX(4px); }

/* Section footer: the fading hairlines either side stop a lone centred button
   from floating in the whitespace and close the section off deliberately. */
.more-row {
  display: flex; align-items: center; gap: clamp(1rem, 3vw, 1.9rem);
  max-width: 760px; margin: clamp(2.4rem, 5vw, 3.4rem) auto 0;
}
.more-row::before,
.more-row::after { content: ''; flex: 1; height: 1px; }
.more-row::before { background: linear-gradient(to right, transparent, rgba(20,36,58,.14)); }
.more-row::after  { background: linear-gradient(to left,  transparent, rgba(20,36,58,.14)); }
.more-row .btn { flex: none; padding-inline: 1.9rem; }

@media (max-width: 560px) {
  .more-row { max-width: none; }
  .more-row::before, .more-row::after { display: none; }
  .more-row .btn { flex: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .btn--arrow:hover svg { transform: none; }
}
/* A wizard step button that is waiting on valid input reads better as a
   flat grey block than a faded blue one — it looks unavailable, not broken. */
.wiz-actions .btn--primary[disabled] {
  opacity: 1; background: #D8DEE6; border-color: #D8DEE6;
  color: #FFFFFF; box-shadow: none;
}
.btn-row { display: flex; flex-wrap: wrap; gap: .7rem; }
.btn-row--tight { margin-top: 1.8rem; }

/* On a phone these wrap onto separate lines but keep their content width, so
   a pair of CTAs ends up as two ragged half-width pills. Stacked and full
   width reads as a deliberate choice and gives a bigger tap target. */
@media (max-width: 560px) {
  .btn-row { flex-direction: column; align-items: stretch; gap: .6rem; }
  .btn-row > .btn { width: 100%; }
}

/* header */
.topbar { background: var(--ink); color: #A9BACD; font-size: .82rem; padding: .55rem 0; }
.topbar .wrap { display: flex; gap: 1.8rem; align-items: center; justify-content: center; flex-wrap: wrap; }
.topbar a { color: #CFDCEA; } .topbar a:hover { color: #fff; }
.topbar span { display: inline-flex; align-items: center; gap: .45rem; }
.topbar svg { width: 14px; height: 14px; opacity: .65; }
@media (max-width: 860px) { .topbar .wrap > :nth-child(n+3) { display: none; } }
@media (max-width: 560px) { .topbar .wrap > :nth-child(n+2) { display: none; } .topbar { font-size: .77rem; } }

.site-header {
  position: sticky; top: 0; z-index: 90; background: rgba(255,255,255,.9);
  backdrop-filter: saturate(180%) blur(16px); -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid transparent; transition: border-color .25s, box-shadow .25s;
}
.site-header.is-stuck { border-bottom-color: var(--line-2); box-shadow: 0 4px 22px rgba(20,36,58,.06); }
.site-header .wrap { display: flex; align-items: center; gap: 1.2rem; height: 116px; }
.brand { flex: none; } .brand img { height: 88px; width: auto; }

.nav { margin-left: auto; display: flex; align-items: center; gap: .2rem; }
.nav a { padding: .58rem .9rem; border-radius: 999px; color: var(--ink-2); font-weight: 600; font-size: .94rem; transition: background .16s, color .16s; }
.nav a:hover { background: var(--sky-50); color: var(--brand); }
.nav a.is-active { background: var(--sky-100); color: var(--brand); }
.header-cta { display: flex; align-items: center; gap: .55rem; margin-left: .8rem; }
.nav .header-cta a.btn--primary { color: #fff; background: var(--brand); }
.nav .header-cta a.btn--primary:hover { color: #fff; background: var(--brand-600); }
.nav .header-cta a.btn--ghost { color: var(--ink); background: #fff; }
.nav .header-cta a.btn--ghost:hover { color: var(--brand); background: #fff; }

.nav-toggle { display: none; margin-left: auto; width: 46px; height: 46px; border-radius: 14px; border: 1px solid var(--line); background: #fff; align-items: center; justify-content: center; cursor: pointer; box-shadow: var(--shadow-sm); }
.nav-toggle span { display: block; width: 19px; height: 2px; background: var(--ink); border-radius: 2px; position: relative; transition: .2s; }
.nav-toggle span::before, .nav-toggle span::after { content:''; position:absolute; left:0; width:19px; height:2px; background: var(--ink); border-radius: 2px; transition:.2s; }
.nav-toggle span::before { top: -6px; } .nav-toggle span::after { top: 6px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { top:0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after { top:0; transform: rotate(-45deg); }
@media (max-width: 980px) {
  .nav-toggle { display: flex; }
  /* Anchored to the header itself rather than a fixed viewport offset, so it
     always sits directly under the bar no matter how tall the top strip is. */
  .nav { position: absolute; top: 100%; left: 0; right: 0; margin: 0;
         flex-direction: column; align-items: stretch; gap: .2rem;
         background: #fff; padding: 1rem var(--gut) 1.8rem; box-shadow: var(--shadow-lg);
         border-bottom-left-radius: var(--r-lg); border-bottom-right-radius: var(--r-lg);
         transform: translateY(-12px); opacity: 0; pointer-events: none; transition: .22s var(--ease);
         max-height: calc(100dvh - 120px); overflow-y: auto; }
  .nav.is-open { transform: none; opacity: 1; pointer-events: auto; }
  .nav a { padding: .85rem 1rem; font-size: 1rem; border-radius: 14px; }
  .header-cta { margin: .8rem 0 0; flex-direction: column; align-items: stretch; }
  .header-cta .btn { width: 100%; }
}

/* hero */
.hero {
  position: relative;
  background: radial-gradient(1000px 560px at 88% -12%, var(--sky-100) 0%, transparent 62%), var(--paper);
  padding-block: clamp(48px,7vw,96px) clamp(68px,9vw,120px);
}
.hero-grid { display: grid; gap: clamp(36px,5vw,68px); grid-template-columns: 1.03fr .97fr; align-items: center; }
@media (max-width: 940px) { .hero-grid { grid-template-columns: 1fr; } }
.hero h1 { margin-bottom: .4em; max-width: 15ch; }
.hero h1 .accent { display: block; color: var(--brand); }
.hero-lead { font-size: 1.12rem; color: var(--ink-2); max-width: 48ch; }
.pill { display: inline-flex; align-items: center; gap: .55rem; padding: .42rem 1rem .42rem .45rem;
        background: #fff; border: 1px solid var(--line); border-radius: 999px; box-shadow: var(--shadow-sm);
        font-size: .84rem; font-weight: 600; color: var(--ink-2); margin-bottom: 1.6rem; }
.pill b { display: inline-flex; align-items: center; gap: .32rem; background: var(--mint-50); color: #077A5C;
          padding: .2rem .62rem; border-radius: 999px; font-size: .74rem; font-weight: 800; }
.pill b::before { content:''; width:6px; height:6px; border-radius:50%; background: var(--mint); }
.hero-trust { display: flex; align-items: center; gap: .7rem 1.7rem; margin-top: 2.2rem; flex-wrap: wrap; }
.hero-trust > div { display: flex; align-items: center; gap: .5rem; font-size: .89rem; font-weight: 600; color: var(--ink-2); }
.hero-trust svg { width: 19px; height: 19px; color: var(--mint); flex: none; }
.hero-media { position: relative; }
.hero-media__frame { position: relative; border-radius: var(--r-xl); overflow: hidden; background: var(--sky-50); aspect-ratio: 4/4.4; box-shadow: var(--shadow-lg); }
.hero-media__frame img, .hero-media__frame svg { width: 100%; height: 100%; object-fit: cover; }
.float-card { position: absolute; background: rgba(255,255,255,.95); backdrop-filter: blur(10px);
              border-radius: var(--r); padding: .8rem 1rem; box-shadow: var(--shadow-lg);
              display: flex; align-items: center; gap: .7rem; animation: bob 6s ease-in-out infinite; }
.float-card__icon { width: 36px; height: 36px; border-radius: 12px; flex: none; display: grid; place-items: center; background: var(--sky-100); color: var(--brand); }
.float-card__icon svg { width: 18px; height: 18px; }
.float-card strong { display: block; font-size: .89rem; color: var(--ink); line-height: 1.3; font-weight: 700; }
.float-card small { font-size: .76rem; color: var(--ink-3); }
.float-card--tl { top: 6%; left: -5%; animation-delay: -1.5s; }
.float-card--br { bottom: 7%; right: -5%; }
.float-card--mint .float-card__icon { background: var(--mint-50); color: #077A5C; }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
/* On a phone the cards get a tighter scale rather than losing their second
   line — the supporting text is the part that actually sells the offer. */
@media (max-width: 600px) {
  .float-card {
    padding: .6rem .75rem; gap: .55rem; border-radius: var(--r-sm);
    max-width: 63%;
  }
  .float-card--tl { left: 2%; top: 3%; }
  .float-card--br { right: 2%; bottom: 3%; }
  .float-card__icon { width: 30px; height: 30px; border-radius: 10px; }
  .float-card__icon svg { width: 15px; height: 15px; }
  .float-card strong { font-size: .8rem; }
  .float-card small { font-size: .7rem; line-height: 1.35; display: block; }
}

/* stats */
.stats { display: grid; grid-template-columns: repeat(4,1fr); background: #fff; border-radius: var(--r-lg); box-shadow: var(--shadow); overflow: hidden; }
.stats > div { padding: 1.9rem 1.4rem; text-align: center; border-right: 1px solid var(--line-2); }
.stats > div:last-child { border-right: 0; }
.stats dt {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.9rem,3.4vw,2.6rem); color: var(--brand);
  line-height: 1; letter-spacing: -.03em;
  /* equal-width digits so the number does not jiggle while counting */
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}
.stats dd { margin: .55rem 0 0; font-size: .86rem; color: var(--ink-3); font-weight: 600; }
@media (max-width: 760px) {
  .stats { grid-template-columns: repeat(2,1fr); }
  .stats > div:nth-child(2n) { border-right: 0; }
  .stats > div:nth-child(-n+2) { border-bottom: 1px solid var(--line-2); }
}

/* estimator */
.quote { background: #fff; border-radius: var(--r-lg); box-shadow: var(--shadow-lg); overflow: hidden; border: 0; }
.quote__head { padding: 1.5rem 1.6rem; background: linear-gradient(135deg, var(--brand-700), var(--brand) 62%, var(--brand-600)); color: #fff; }
.quote__head h3 { color: #fff; margin-bottom: .28rem; font-size: 1.2rem; }
.quote__head p { margin: 0; font-size: .88rem; color: #C9DFF6; }
.quote__body { padding: 1.5rem 1.6rem 1.7rem; }
.quote__row { display: grid; grid-template-columns: 1fr auto; gap: .7rem; align-items: end; margin-bottom: 1rem; }
.quote__list { border-top: 1px solid var(--line-2); margin-top: 1.2rem; padding-top: .5rem; }
.quote__line { display: flex; align-items: center; gap: .8rem; padding: .7rem 0; border-bottom: 1px solid var(--line-2); font-size: .91rem; }
.quote__line:last-child { border-bottom: 0; }
.quote__line span:first-child { flex: 1; color: var(--ink); font-weight: 600; }
.quote__line .amt { font-family: var(--font-mono); color: var(--ink); }
.quote__line button { border: 0; background: none; cursor: pointer; color: var(--ink-3); width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center; }
.quote__line button:hover { background: var(--rose-50); color: var(--rose); }
.quote__empty { text-align: center; padding: 1.8rem 0; color: var(--ink-3); font-size: .9rem; }
.quote__total { display: flex; justify-content: space-between; align-items: baseline; padding-top: 1.1rem; margin-top: .3rem; border-top: 2px solid var(--line); }
.quote__total span { color: var(--ink-2); font-weight: 700; font-size: .96rem; }
.quote__total strong { font-family: var(--font-display); font-size: 1.9rem; color: var(--brand); letter-spacing: -.03em; font-weight: 800; }
.quote__note { font-size: .8rem; color: var(--ink-3); margin-top: .8rem; line-height: 1.6; }
.quote__note b { color: var(--mint); font-weight: 700; }

/* forms */
.field { margin-bottom: 1.1rem; }
.field > label, .label { display: block; font-size: .85rem; font-weight: 700; color: var(--ink); margin-bottom: .45rem; }
.input, .select, .textarea { width: 100%; padding: .82rem 1rem; border: 2px solid var(--line); border-radius: 14px; background: #fff; color: var(--ink); font-size: .95rem; transition: border-color .16s, box-shadow .16s; }
.input::placeholder, .textarea::placeholder { color: #A9B6C6; }
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 4px rgba(10,87,162,.1); }
.textarea { min-height: 118px; resize: vertical; line-height: 1.6; }
.select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238A99AC' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 1rem center; padding-right: 2.5rem; }
.hint { font-size: .8rem; color: var(--ink-3); margin-top: .4rem; line-height: 1.55; }
.field-error { font-size: .8rem; color: var(--rose); margin-top: .4rem; font-weight: 600; }
.input.has-error, .select.has-error, .textarea.has-error { border-color: var(--rose); }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
@media (max-width: 620px) { .grid-2 { grid-template-columns: 1fr; } }
.check { display: flex; gap: .65rem; align-items: flex-start; font-size: .9rem; cursor: pointer; }
.check input { margin-top: .3rem; width: 17px; height: 17px; accent-color: var(--brand); flex: none; }
.radio-cards { display: grid; gap: .7rem; }
.radio-cards--2 { grid-template-columns: 1fr 1fr; }
@media (max-width: 620px) { .radio-cards--2 { grid-template-columns: 1fr; } }
.radio-card { position: relative; display: flex; gap: .8rem; align-items: flex-start; padding: 1rem 1.1rem; border: 2px solid var(--line); border-radius: var(--r); cursor: pointer; background: #fff; transition: border-color .16s, background .16s, box-shadow .16s; }
.radio-card:hover { border-color: var(--sky-100); background: var(--sky-50); }
.radio-card input { position: absolute; opacity: 0; pointer-events: none; }
.radio-card__dot { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line); flex: none; margin-top: .18rem; display: grid; place-items: center; transition: .16s; }
.radio-card__dot::after { content:''; width: 10px; height: 10px; border-radius: 50%; background: transparent; transition: .16s; }
.radio-card input:checked ~ .radio-card__dot { border-color: var(--brand); }
.radio-card input:checked ~ .radio-card__dot::after { background: var(--brand); }
.radio-card:has(input:checked) { border-color: var(--brand); background: var(--sky-50); }
.radio-card input:focus-visible ~ .radio-card__dot { outline: 3px solid var(--brand-600); outline-offset: 2px; }
.radio-card strong { display: block; color: var(--ink); font-size: .95rem; font-weight: 700; }
.radio-card small { color: var(--ink-3); font-size: .83rem; }

/* alerts */
.alert { padding: .95rem 1.2rem; border-radius: var(--r); font-size: .91rem; font-weight: 600; margin-bottom: 1rem; border: 0; transition: opacity .35s ease, transform .35s ease, max-height .35s ease, margin .35s ease, padding .35s ease; max-height: 200px; overflow: hidden; }
.alert.is-hiding { opacity: 0; transform: translateY(-6px); max-height: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; }
.alert--success { background: var(--mint-50); color: #066B4F; }
.alert--error { background: var(--rose-50); color: #A32F24; }
.alert--info { background: var(--sky-50); color: var(--brand-700); }
.alert--warning { background: var(--sun-50); color: #8C6210; }

/* grids + cards */
.grid { display: grid; gap: clamp(1.4rem, 2.4vw, 2rem); }
.grid--3 { grid-template-columns: repeat(3,1fr); }
.grid--4 { grid-template-columns: repeat(4,1fr); }
@media (max-width: 980px) { .grid--4 { grid-template-columns: repeat(2,1fr); } .grid--3 { grid-template-columns: repeat(2,1fr); } }
@media (max-width: 620px) { .grid--3, .grid--4 { grid-template-columns: 1fr; } .grid { gap: 1.5rem; } }
.card { background: #fff; border: 0; border-radius: var(--r-lg); padding: 1.8rem; box-shadow: var(--shadow); transition: transform .22s var(--ease), box-shadow .22s var(--ease); }
.card--pad-lg { padding: clamp(1.7rem, 3vw, 2.4rem); }

/* service cards — soft, rounded, photo inset in a white frame */
.svc { display: flex; flex-direction: column; height: 100%; background: #fff; border: 0; border-radius: var(--r-lg); padding: 1.8rem 1.7rem; position: relative; box-shadow: var(--shadow); }
.svc__icon { width: 52px; height: 52px; border-radius: 16px; margin-bottom: 1.2rem; display: grid; place-items: center; background: var(--sky-100); color: var(--brand); flex: none; }
.svc__icon svg { width: 25px; height: 25px; }
.svc h3 { font-size: 1.16rem; margin-bottom: .45rem; }
.svc p { font-size: .93rem; color: var(--ink-2); margin-bottom: 1.2rem; line-height: 1.68; }
/* Holds just the button now that the price has gone, so it needs less room
   above it than it did when it carried two lines of type. */
.svc__foot { margin-top: auto; padding-top: 1rem; border-top: 1px solid var(--line-2); display: flex; flex-direction: column; align-items: center; gap: .95rem; text-align: center; }
/* the only clickable target on the card */
.svc__book { width: 100%; max-width: 210px; }
.svc__more { display: inline-flex; align-items: center; gap: .3rem; font-size: .86rem; font-weight: 700; color: var(--brand); background: var(--sky-50); padding: .45rem .95rem; border-radius: 999px; transition: background .18s, color .18s; }
.svc__more:hover { background: var(--brand); color: #fff; }

.svc--photo { padding: 0; overflow: hidden; }
/* image runs to the very edge of the card — no white margin on top or sides */
.svc--photo .svc__media { display: block; position: relative; aspect-ratio: 4/3; background: var(--sky-50); overflow: hidden; border-radius: 0; margin-bottom: 0; }
.svc--photo .svc__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.svc--photo .svc__media::after { display: none; }
.svc--photo .svc__icon { display: none; }
.svc--photo .svc__body { display: flex; flex-direction: column; flex: 1; padding: 1.6rem 1.6rem 1.7rem; }
.svc--photo h3 { margin-top: 0; margin-bottom: .5rem; }
.svc--photo .svc__foot { margin-top: auto; }

/* steps */
.steps { display: grid; grid-template-columns: repeat(4,1fr); gap: 1.2rem; counter-reset: s; }
@media (max-width: 980px) { .steps { grid-template-columns: repeat(2,1fr); } }
@media (max-width: 560px) { .steps { grid-template-columns: 1fr; } }
.step { counter-increment: s; position: relative; padding: 1.8rem 1.6rem; background: #fff; border: 0; border-radius: var(--r-lg); box-shadow: var(--shadow); }
.step__n { width: 46px; height: 46px; border-radius: 16px; margin-bottom: 1.1rem; display: grid; place-items: center;
           background: var(--brand); color: #fff; font-family: var(--font-display); font-size: 1rem; font-weight: 800;
           box-shadow: 0 6px 16px rgba(10,87,162,.28); }
.step__n::after { content: counter(s, decimal-leading-zero); }
.step h3 { font-size: 1.1rem; margin-bottom: .4rem; }
.step p { font-size: .92rem; color: var(--ink-2); margin: 0; line-height: 1.68; }
.step::after { display: none; }
.step + .step { border-left: 0; padding-left: 1.6rem; }

/* pricing */
.price-tabs { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: 1.8rem; border: 0; }
.price-tabs button { padding: .6rem 1.15rem; border-radius: 999px; border: 2px solid var(--line); background: #fff; font-size: .88rem; font-weight: 700; color: var(--ink-2); cursor: pointer; margin: 0; transition: .16s; }
.price-tabs button:hover { border-color: var(--sky-100); color: var(--brand); }
.price-tabs button[aria-selected="true"] { background: var(--brand); border-color: var(--brand); color: #fff; }
.table-wrap { overflow-x: auto; border: 0; border-radius: var(--r-lg); background: #fff; box-shadow: var(--shadow); }
table.rate { width: 100%; border-collapse: collapse; font-size: .93rem; min-width: 560px; }
table.rate thead th { text-align: left; padding: 1rem 1.3rem; background: var(--sky-50); color: var(--brand-700); font-size: .76rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; border-bottom: 0; white-space: nowrap; }
table.rate tbody td { padding: .95rem 1.3rem; border-bottom: 1px solid var(--line-2); vertical-align: top; }
table.rate tbody tr:last-child td { border-bottom: 0; }
table.rate tbody tr:hover { background: var(--sky-50); }
table.rate td:first-child { color: var(--ink); font-weight: 600; }
table.rate .num { font-family: var(--font-mono); color: var(--ink); white-space: nowrap; }
table.rate .dash { color: #C9D5E2; }
table.rate .note { display: block; font-size: .79rem; color: var(--ink-3); font-weight: 400; margin-top: .2rem; }
.rate-panel[hidden] { display: none; }

/* ---------- the mobile face of the tablist above ----------
   A bordered box with text in it is indistinguishable from a filled-in form
   field, so this one carries a solid brand chevron chip on the right. Nobody
   mistakes that for something they have already answered. */
.price-picker { display: none; margin-bottom: 1.4rem; }
.price-picker label {
  display: block; margin-bottom: .4rem;
  font-size: .78rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-3);
}
.price-picker .optsel__trigger {
  padding: .6rem .6rem .6rem 1.1rem;
  border-color: var(--sky-100); box-shadow: var(--shadow-sm);
}
.price-picker .optsel__label { font-size: 1rem; font-weight: 800; }
.price-picker .optsel__chev {
  width: 34px; height: 34px; border-radius: 50%;
  align-items: center; justify-content: center;
  background: var(--brand); color: #fff;
}
.price-picker .optsel__chev svg { width: 17px; height: 17px; stroke-width: 2.4; }
.price-picker .optsel.is-open .optsel__trigger { border-color: var(--brand); }

/* ---------- rate card on a phone ----------
   A four-column table cannot fit, so it used to scroll sideways — prices out
   of view until you swiped, with no hint they were there. Each row becomes a
   card instead: item on top, then only the services actually offered. */
@media (max-width: 720px) {
  .price-picker { display: block; }
  .price-tabs { display: none; }

  .rate-panel .table-wrap {
    overflow: visible; background: transparent; box-shadow: none; border-radius: 0;
  }
  .rate-panel table.rate { display: block; min-width: 0; font-size: .95rem; }
  .rate-panel table.rate thead { display: none; }
  .rate-panel table.rate tbody { display: grid; gap: .75rem; }

  .rate-panel table.rate tr {
    display: block; padding: 1rem 1.1rem;
    background: #fff; border-radius: var(--r); box-shadow: var(--shadow-sm);
  }
  .rate-panel table.rate tr:hover { background: #fff; }

  .rate-panel table.rate td {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 1rem; padding: .42rem 0; border-bottom: 0;
  }
  .rate-panel table.rate td::before {
    content: attr(data-label);
    font-size: .84rem; font-weight: 600; color: var(--ink-3);
  }
  .rate-panel table.rate td:first-child {
    display: block; padding: 0 0 .6rem;
    margin-bottom: .35rem; border-bottom: 1px solid var(--line-2);
    font-size: 1rem; font-weight: 700;
  }
  /* a column of dashes says nothing useful in a card */
  .rate-panel table.rate td.is-empty { display: none; }
}

/* testimonials */
.quotes { display: grid; grid-template-columns: repeat(3,1fr); gap: 1.4rem; }
@media (max-width: 980px) { .quotes { grid-template-columns: repeat(2,1fr); } }
@media (max-width: 640px) { .quotes { grid-template-columns: 1fr; } }
.quote-card { background: #fff; border: 0; border-radius: var(--r-lg); padding: 1.8rem 1.7rem; display: flex; flex-direction: column; box-shadow: var(--shadow); }
.quote-card + .quote-card { padding-left: 1.7rem; border-left: 0; }
.stars { display: flex; gap: 2px; margin-bottom: 1rem; color: var(--sun); }
.stars svg { width: 16px; height: 16px; }
.quote-card blockquote { margin: 0 0 1.3rem; font-size: .97rem; color: var(--ink-2); line-height: 1.72; }
.quote-card figcaption { margin-top: auto; display: flex; align-items: center; gap: .75rem; }
.avatar { width: 42px; height: 42px; border-radius: 50%; flex: none; display: grid; place-items: center; background: linear-gradient(140deg, var(--brand), var(--brand-600)); border: 0; color: #fff; font-weight: 800; font-size: .95rem; font-family: var(--font-display); }
.quote-card figcaption strong { display: block; color: var(--ink); font-size: .92rem; font-weight: 700; }
.quote-card figcaption small { color: var(--ink-3); font-size: .82rem; }

/* FAQ */
.faq { max-width: 820px; margin-inline: auto; border-top: 0; }
.faq-split .faq { max-width: none; margin-inline: 0; }
.faq-split .sec-head { margin-bottom: 1.6rem; max-width: none; }
@media (max-width: 900px) { .faq-split .sec-head { text-align: left; } }
.faq details { background: #fff; border: 0; border-radius: var(--r); margin-bottom: .8rem; box-shadow: var(--shadow-sm); overflow: hidden; transition: box-shadow .2s; }
.faq details[open] { box-shadow: var(--shadow); }
.faq summary { padding: 1.2rem 1.4rem; cursor: pointer; list-style: none; font-weight: 700; color: var(--ink); font-size: 1.02rem; display: flex; align-items: center; justify-content: space-between; gap: 1.2rem; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content:''; flex: none; width: 26px; height: 26px; border-radius: 50%; background: var(--sky-50) no-repeat center;
  background-image: linear-gradient(var(--brand),var(--brand)), linear-gradient(var(--brand),var(--brand));
  background-size: 11px 2px, 2px 11px; background-position: center, center; transition: transform .24s var(--ease), background-size .24s var(--ease); }
.faq details[open] summary::after { background-size: 11px 2px, 0 11px; transform: rotate(180deg); }
.faq .faq__a { padding: 0 1.4rem 1.3rem; color: var(--ink-2); font-size: .95rem; line-height: 1.75; }
.faq .faq__a p:last-child { margin-bottom: 0; }

/* coverage */
.zone { margin-bottom: 2.2rem; }
.zone h3 { font-size: 1rem; margin-bottom: 1rem; display: flex; align-items: center; gap: .8rem; font-family: var(--font-display); font-weight: 700; letter-spacing: -.01em; text-transform: none; color: var(--ink); }
.zone h3::after { content:''; flex: 1; height: 1px; background: var(--line); }
.chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip { display: inline-flex; align-items: center; gap: .45rem; padding: .5rem .95rem; border-radius: 999px; background: #fff; border: 1px solid var(--line); font-size: .87rem; font-weight: 600; color: var(--ink-2); box-shadow: var(--shadow-sm); transition: .16s; }
.chip:hover { border-color: var(--brand); color: var(--brand); transform: translateY(-2px); }
.chip::before { content:''; width: 6px; height: 6px; border-radius: 50%; background: var(--mint); flex: none; }

/* ---------- coverage page: area photo tiles ---------- */
.area-tiles {
  display: flex; flex-wrap: wrap; gap: 1.3rem;
  justify-content: center;
}
/* fixed basis, no grow — so a short last row centres instead of stretching */
.area-tile-w { flex: 0 1 calc((100% - 2.6rem) / 3); }
@media (max-width: 1080px) { .area-tile-w { flex-basis: calc((100% - 1.3rem) / 2); } }
.area-tile {
  position: relative; display: block; overflow: hidden;
  border-radius: var(--r-lg); aspect-ratio: 4/3;
  background: var(--sky-100); box-shadow: var(--shadow);
  text-decoration: none; isolation: isolate;
  transition: transform .3s var(--ease-float), box-shadow .3s var(--ease-float);
}
.area-tile:hover { transform: translateY(-5px); box-shadow: var(--shadow-lg); }
.area-tile:focus-visible { outline: 3px solid var(--brand-600); outline-offset: 3px; }
.area-tile img {
  width: 100%; height: 100%; object-fit: cover; object-position: center 28%; display: block;
  transition: transform .55s var(--ease-float);
}
.area-tile:hover img { transform: scale(1.07); }

/* scrim keeps the label readable over any photo */
.area-tile::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top,
    rgba(8, 26, 48, .88) 0%,
    rgba(8, 26, 48, .55) 34%,
    rgba(8, 26, 48, .08) 62%,
    rgba(8, 26, 48, 0) 100%);
  transition: opacity .3s;
}
.area-tile:hover::after { opacity: .92; }

.area-tile__zone {
  position: absolute; top: .95rem; left: .95rem; z-index: 2;
  padding: .32rem .7rem; border-radius: 999px;
  background: rgba(255,255,255,.9); backdrop-filter: blur(6px);
  font-size: .72rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--brand-700);
}
.area-tile__body {
  position: absolute; inset: auto 0 0 0; z-index: 2;
  padding: 1.15rem 1.25rem 1.2rem;
  display: flex; align-items: flex-end; justify-content: space-between; gap: .7rem;
}
.area-tile__name {
  font-family: var(--font-display); font-weight: 800; color: #fff;
  font-size: 1.35rem; line-height: 1.18; letter-spacing: -.018em;
  text-shadow: 0 1px 12px rgba(8,26,48,.5);
}
.area-tile__go {
  flex: none; width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.34);
  color: #fff; transition: background .2s, transform .2s;
}
.area-tile__go svg { width: 17px; height: 17px; }
.area-tile:hover .area-tile__go { background: var(--brand-600); border-color: var(--brand-600); transform: translateX(3px); }

@media (max-width: 560px) {
  .area-tiles { gap: .8rem; }
  .area-tile-w { flex-basis: calc((100% - .8rem) / 2); }
  .area-tile { aspect-ratio: 1/1; border-radius: var(--r); }
  .area-tile__name { font-size: .92rem; }
  .area-tile__go { display: none; }
  .area-tile__zone { font-size: .6rem; top: .55rem; left: .55rem; }
}
@media (prefers-reduced-motion: reduce) {
  .area-tile, .area-tile img, .area-tile__go { transition: none; }
  .area-tile:hover { transform: none; }
  .area-tile:hover img { transform: none; }
}

/* ---------- homepage: coverage area list ---------- */
.cov-intro { text-align: justify; text-align-last: center; }
.cov-intro strong { color: var(--ink); font-weight: 700; }
.cov-intro--left { text-align-last: left; }
@media (max-width: 640px) { .cov-intro { text-align: left; text-align-last: left; } }
.sec-head--wide { max-width: 1080px; }
.area-body { font-size: 1.05rem; line-height: 1.85; color: var(--ink-2); }
.area-body p { text-align: justify; margin-bottom: 1.3rem; }
.area-body p:last-child { margin-bottom: 0; }
.area-body strong { color: var(--ink); font-weight: 700; }
.area-landmark {
  margin: 2.4rem 0 1.6rem; border-radius: var(--r-xl, 24px); overflow: hidden;
  box-shadow: var(--shadow-lg);
}
.area-landmark img {
  width: 100%; height: auto; aspect-ratio: 16 / 9; max-height: 460px;
  object-fit: cover; object-position: center 28%; display: block;
}

/* ---------- area page: services sidebar ---------- */
.area-services {
  margin-top: 1.6rem; background: var(--sky-50); border-radius: var(--r);
  padding: 1.4rem;
}
.area-services h3 { font-size: 1.15rem; text-align: center; margin-bottom: 1rem; }
.area-services__list { display: grid; gap: .7rem; }
.area-services__item {
  display: block; text-align: center; padding: .8rem 1rem;
  border-radius: 999px; border: 2px solid var(--line); background: #fff;
  color: var(--ink); font-weight: 700; font-size: .92rem; text-decoration: none;
  transition: border-color .16s, background .16s, color .16s;
}
.area-services__item:hover { border-color: var(--brand); color: var(--brand); }
.area-services__item:first-child { background: var(--brand); border-color: var(--brand); color: #fff; }
.area-services__item:first-child:hover { color: #fff; }
.split.area-split { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 2.2rem; }
.area-sidebar { width: 100%; max-width: none; margin-left: auto; }
/* The shared side photo is the 3:4 brand portrait, so the frame is portrait too.
   object-position keeps the subject's head in frame if a wider photo is swapped in. */
.area-sidebar .split__media { aspect-ratio: 3 / 4; }
.area-sidebar .split__media img { object-position: center 20%; }
@media (max-width: 900px) {
  .split.area-split { grid-template-columns: 1fr; }
  .area-sidebar { max-width: 420px; margin-inline: auto; }
}
.area-cols {
  display: grid; grid-template-columns: repeat(4, minmax(150px, auto)); gap: 1.6rem 4.5rem;
  width: fit-content; max-width: 100%; margin-inline: auto;
}
.area-cols__list { list-style: none; margin: 0; padding: 0; display: grid; gap: .9rem; }
.area-cols__list li { position: relative; padding-left: 1.1rem; }
.area-cols__list li::before {
  content: ''; position: absolute; left: 0; top: .55em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--brand);
}
.area-cols__list a { font-weight: 700; color: var(--brand); text-decoration: none; }
.area-cols__list a:hover { color: var(--brand-700); text-decoration: underline; }
@media (max-width: 860px) { .area-cols { grid-template-columns: repeat(2, 1fr); width: 100%; max-width: 480px; } }
@media (max-width: 520px) { .area-cols { grid-template-columns: 1fr; width: 100%; max-width: 320px; } }

/* split */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px,5vw,68px); align-items: center; }
.split--flip > :first-child { order: 2; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } .split--flip > :first-child { order: 0; } }
.split__media { border-radius: var(--r-xl); overflow: hidden; background: var(--sky-50); aspect-ratio: 4/3; box-shadow: var(--shadow-lg); }
.split__media img, .split__media svg { width: 100%; height: 100%; object-fit: cover; }
.ticks { list-style: none; padding: 0; margin: 1.6rem 0 0; display: grid; gap: .9rem; }
.ticks li { display: flex; gap: .8rem; align-items: flex-start; font-size: .96rem; padding: 0; border: 0; }
.ticks li:first-child { border-top: 0; }
.ticks svg { width: 21px; height: 21px; color: var(--mint); flex: none; margin-top: .18rem; }

/* ---------- homepage: "talk to our team" contact panel ---------- */
.contact-panel {
  background: var(--sky-50); border-radius: var(--r-xl);
  padding: clamp(1.6rem, 3vw, 2.4rem);
}
.contact-panel__map {
  border-radius: var(--r); overflow: hidden; height: 220px;
  margin-bottom: 1.6rem; box-shadow: var(--shadow-sm);
}

/* ---------- embedded map, with something to show when it will not load ----
   Ad blockers, privacy extensions and strict corporate networks all block
   Google's embed. The iframe sits on top; when it fails to render, the
   address underneath shows through instead of an empty grey box. */
.map-embed { position: relative; }
.map-embed iframe { position: relative; z-index: 1; }
.map-embed__fallback {
  position: absolute; inset: 0; z-index: 0;
  display: grid; align-content: center; justify-items: center; gap: .5rem;
  padding: 1.5rem; text-align: center; text-decoration: none;
  background: var(--foam); color: var(--ink-2); font-size: .88rem; line-height: 1.5;
}
.map-embed__fallback svg { width: 26px; height: 26px; color: var(--brand); }
.map-embed__cta { font-weight: 700; color: var(--brand-600); text-decoration: underline; }
.contact-panel__grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem 1.2rem;
}
@media (max-width: 560px) { .contact-panel__grid { grid-template-columns: 1fr; } }
.contact-panel__item { display: flex; gap: .8rem; align-items: flex-start; }
.contact-panel__icon {
  width: 42px; height: 42px; border-radius: 12px; flex: none;
  background: #fff; color: var(--brand);
  display: grid; place-items: center; box-shadow: var(--shadow-sm);
}
.contact-panel__icon svg { width: 19px; height: 19px; }
.contact-panel__item strong { display: block; color: var(--ink); font-size: .92rem; margin-bottom: .18rem; }
.contact-panel__item small { display: block; color: var(--ink-2); font-size: .85rem; line-height: 1.5; }
.contact-panel__item small a { color: var(--ink-2); text-decoration: none; }
.contact-panel__item small a:hover { color: var(--brand); }
.ticks strong { color: var(--ink); display: block; font-weight: 700; }
.ticks span { color: var(--ink-2); font-size: .92rem; line-height: 1.68; }

/* CTA band */
.cta-band { position: relative; overflow: hidden; background: linear-gradient(135deg, var(--brand-700) 0%, var(--brand) 55%, #1479D6 100%); color: #fff; border-radius: var(--r-xl); padding: clamp(2.6rem,5vw,4.2rem) clamp(1.6rem,4vw,3rem); text-align: center; }
.cta-band::before { content:''; position:absolute; width: 380px; height: 380px; border-radius: 50%; top: -170px; right: -110px; background: radial-gradient(circle, rgba(255,255,255,.14), transparent 70%); display: block; }
.cta-band::after { content:''; position:absolute; width: 280px; height: 280px; border-radius: 50%; bottom: -140px; left: -80px; background: radial-gradient(circle, rgba(255,255,255,.12), transparent 70%); display: block; }
.cta-band > * { position: relative; }
.cta-band h2 { color: #fff; margin-bottom: .55rem; }
.cta-band p { color: #CFE3F7; max-width: 52ch; margin-inline: auto; margin-bottom: 1.8rem; font-size: 1.04rem; }
.cta-band .btn-row { justify-content: center; }

/* ---------- inner page banner ----------
   Every inner page gets the same height so the site feels consistent. The
   image sits behind a dark gradient so white text stays readable no matter
   what photograph is dropped in. */
.page-banner {
  position: relative;
  display: flex; align-items: center;
  /* The banner takes the shape of its image (3:1) rather than a fixed height,
     so nothing is cropped. A fixed 380px height against a full-width element
     meant the banner was 4:1 or wider and had to throw most of the picture
     away. 17/5 (3.4:1) is slightly wider than the 3:1 images, so a thin band
     goes from top and bottom — composed as headroom and foreground, nothing
     that matters. The max-height keeps it sane on a wide monitor. */
  /* width must be stated explicitly: with aspect-ratio set, a clamped
     max-height lets the browser resolve the width FROM the ratio instead of
     filling the viewport, which left a gap down the right-hand side. */
  width: 100%;
  aspect-ratio: 17 / 5;
  min-height: 260px;
  max-height: 440px;
  background: var(--ink);
  overflow: hidden;
  isolation: isolate;
}
.page-banner__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  /* The banner is around 4:1 on a wide screen while the source images are
     21:9, so cover trims a lot off the top and bottom. Centring the crop cut
     heads off; biasing it upward keeps faces and hanging garments in frame.
     Pages can override with --banner-focus when their image needs it. */
  object-position: var(--banner-focus, 50% 22%);
  z-index: -2;
}
/* gradient scrim: heaviest on the left where the text sits */
.page-banner::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg,
    rgba(8,20,38,.90) 0%,
    rgba(8,20,38,.74) 42%,
    rgba(8,26,52,.48) 72%,
    rgba(10,87,162,.36) 100%);
}
.page-banner .wrap { position: relative; width: 100%; }
.page-banner__inner { max-width: 660px; padding-block: clamp(2.4rem, 5vw, 3.6rem); }
.page-banner h1 {
  color: #fff; font-size: clamp(2.1rem, 4.4vw, 3.4rem); margin-bottom: .5rem;
  text-wrap: balance;
}
.page-banner p { font-size: 1.06rem; color: #CBDCEE; margin-bottom: 0; max-width: 54ch; }

/* a slow settle so the banner has life without being distracting */
@media (prefers-reduced-motion: no-preference) {
  .page-banner__img { animation: bannerSettle 14s var(--ease) forwards; }
}
@keyframes bannerSettle {
  from { transform: scale(1.09); }
  to   { transform: scale(1); }
}

@media (max-width: 640px) {
  .page-banner { min-height: 220px; }
  .page-banner p { font-size: .99rem; }
}

/* footer */
.site-footer { background: var(--ink); color: #94A7BC; padding-block: clamp(56px,7vw,86px) 0; }
.footer-grid { display: grid; grid-template-columns: 1.8fr 1fr 1fr 1.3fr; gap: 2.4rem; }
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: 2.2rem; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } }
.site-footer img.flogo { height: 96px; width: auto; margin-bottom: 1.5rem; }
@media (max-width: 640px) { .site-footer img.flogo { height: 76px; } }
.site-footer p { font-size: .92rem; line-height: 1.7; max-width: 34ch; }
.site-footer h4 { color: #fff; font-size: .8rem; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 1.1rem; font-family: var(--font-display); font-weight: 800; }
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: .6rem; }
.site-footer ul a { color: #94A7BC; font-size: .92rem; }
.site-footer ul a:hover { color: #fff; }
.fcontact { display: grid; gap: .85rem; font-size: .92rem; }
.fcontact div { display: flex; gap: .6rem; align-items: flex-start; }
.fcontact svg { width: 17px; height: 17px; color: #5E7591; flex: none; margin-top: .22rem; }
.fcontact a { color: #C0D0E1; } .fcontact a:hover { color: #fff; }
.socials { display: flex; gap: .5rem; margin-top: 1.4rem; }
.socials a { width: 40px; height: 40px; border-radius: 14px; display: grid; place-items: center; background: rgba(255,255,255,.08); border: 0; color: #B6C6D6; transition: .16s; }
.socials a:hover { background: var(--brand); color: #fff; transform: translateY(-2px); }
.socials svg { width: 17px; height: 17px; }
.footer-base { margin-top: clamp(40px,5vw,62px); padding-block: 1.5rem; border-top: 1px solid rgba(255,255,255,.1); display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; font-size: .86rem; }
.footer-base a { color: #94A7BC; } .footer-base a:hover { color: #fff; }
.footer-base nav { display: flex; gap: 1.3rem; }

/* Three-column footer body: brand, policies, contact details. Cards,
   e-wallets and BNPL all require the policy pages to be reachable from every
   page, so they get a column of their own rather than sitting among the
   site navigation links. */
.footer-grid--trio { grid-template-columns: minmax(0,1.5fr) minmax(0,1fr) minmax(0,1.25fr); gap: clamp(2rem,4vw,3.4rem); }
@media (max-width: 900px) { .footer-grid--trio { grid-template-columns: 1fr 1fr; gap: 2.4rem; } }
@media (max-width: 560px) { .footer-grid--trio { grid-template-columns: 1fr; gap: 2.2rem; } }

.footer-base--center { justify-content: center; text-align: center; }

/* WhatsApp FAB */
.wa-fab { position: fixed; right: 22px; bottom: 22px; z-index: 80; width: 56px; height: 56px; border-radius: 50%; background: #1FAF54; color: #fff; display: grid; place-items: center; box-shadow: 0 10px 28px rgba(31,175,84,.4); transition: transform .2s var(--ease); }
.wa-fab:hover { transform: scale(1.08); background: #1FAF54; color: #fff; }
.wa-fab svg { width: 27px; height: 27px; }
@media (max-width: 560px) { .wa-fab { right: 14px; bottom: 14px; width: 52px; height: 52px; } }

/* auth */
.auth { min-height: 100dvh; display: grid; grid-template-columns: 1.05fr .95fr; }
@media (max-width: 900px) { .auth { grid-template-columns: 1fr; } }
.auth__aside { background: linear-gradient(150deg, var(--brand-700), var(--brand) 60%, #1479D6); color: #fff; padding: clamp(2rem,5vw,3.8rem); display: flex; flex-direction: column; position: relative; overflow: hidden; }
.auth__aside::after { content:''; position:absolute; width: 460px; height: 460px; border-radius: 50%; right: -180px; bottom: -200px; background: radial-gradient(circle, rgba(255,255,255,.13), transparent 70%); display: block; }
.auth__aside > * { position: relative; }
.auth__aside h2 { color: #fff; font-size: clamp(1.7rem,3vw,2.3rem); }
.auth__aside p { color: #CFE3F7; }
.auth__aside img { height: clamp(84px, 7vw, 104px); width: auto; margin-bottom: auto; }
.auth__aside .ticks svg { color: #8FD8C2; }
@media (max-width: 900px) { .auth__aside { display: none; } }
.auth__main { display: grid; place-items: center; padding: clamp(1.6rem,5vw,3rem); }
.auth__form { width: 100%; max-width: 420px; }
.auth__form h1 { font-size: clamp(1.7rem,3.4vw,2.2rem); margin-bottom: .35em; }
.auth__form .lead { color: var(--ink-3); font-size: .97rem; margin-bottom: 1.8rem; }
/* On desktop the blue panel carries the branding, so the form column starts
   straight on the greeting — a second logo alongside it reads as a duplicate. */
.auth__logo { display: none; }

@media (max-width: 900px) {
  /* The blue panel is hidden at this width, so the logo moves across and
     becomes the masthead for the form. */
  .auth__main { padding-top: clamp(2rem, 8vw, 3.5rem); }
  .auth__form { text-align: center; }
  .auth__logo {
    display: inline-block; width: auto;
    height: clamp(96px, 27vw, 136px);
    margin-bottom: 1.6rem;
  }
  .auth__form h1 { font-size: clamp(1.8rem, 6vw, 2.2rem); }
  .auth__form .lead { margin-bottom: 2.2rem; }

  /* Labels and inputs stay left-aligned — a centred field label floats away
     from the box it belongs to and is harder to scan down a column. */
  .auth__form form,
  .auth__form .alert { text-align: left; }
}

/* badges */
.badge { display: inline-flex; align-items: center; gap: .38rem; padding: .28rem .72rem; border-radius: 999px; font-size: .78rem; font-weight: 700; white-space: nowrap; font-family: var(--font-body); border: 0; }
.badge::before { content:''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge--mint { background: var(--mint-50); color: #066B4F; }
.badge--blue { background: var(--sky-100); color: var(--brand-700); }
.badge--amber { background: var(--sun-50); color: #8C6210; }
.badge--red { background: var(--rose-50); color: #A32F24; }
.badge--grey { background: var(--line-2); color: #62748A; }

/* utilities */
.muted { color: var(--ink-3); }
.mono { font-family: var(--font-mono); }
.mb-0 { margin-bottom: 0; }
.mt-2 { margin-top: 2rem; }
.hide { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: -9999px; top: 0; z-index: 200; background: var(--brand); color: #fff; padding: .8rem 1.2rem; border-radius: 0 0 12px 0; }
.skip-link:focus { left: 0; color: #fff; }

/* ---------- scroll reveal: float up ----------
   An expo-out curve so elements decelerate into place rather than easing
   linearly — that overshoot-free settle is what reads as "floating". */
:root { --ease-float: cubic-bezier(.16, 1, .3, 1); }

.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease-float), transform .7s var(--ease-float);
}
.reveal.is-in { opacity: 1; transform: none; }

/* cards travel further and scale up very slightly, so a grid of them
   reads as a wave rather than a single block appearing */
.svc.reveal, .card.reveal, .step.reveal, .quote-card.reveal {
  transform: translateY(64px);
  transition: opacity .85s var(--ease-float), transform .85s var(--ease-float);
}
.svc.reveal.is-in, .card.reveal.is-in, .step.reveal.is-in, .quote-card.reveal.is-in {
  transform: translateY(0);
}

/* the photo itself never animates — only the card floats */
.svc--photo .svc__media img { transform: none !important; transition: none !important; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .svc.reveal, .card.reveal, .step.reveal, .quote-card.reveal { opacity: 1; transform: none; }
  .svc--photo .svc__media img { transform: none !important; }
}

/* ---------- mobile performance ---------- */
@media (max-width: 780px) {
  /* backdrop blur is expensive to composite on phones */
  .site-header { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(255,255,255,.97); }
  /* The bob itself is a transform, which the GPU handles cheaply. What made
     this costly on a phone was compositing it against a live backdrop blur
     every frame — so drop the blur and keep the movement. */
  .float-card { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(255,255,255,.97); }
}

/* Anyone who has asked their device to calm down still gets a static card. */
@media (prefers-reduced-motion: reduce) {
  .float-card { animation: none; }
}

/* ---------- stats: each column arrives on its own ---------- */
.stats > div.reveal {
  transform: translateY(30px);
  transition: opacity .75s var(--ease-float), transform .75s var(--ease-float);
}
.stats > div.reveal.is-in { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .stats > div.reveal { opacity: 1; transform: none; }
}

/* ---------- header sizing on small screens ----------
   The logo stays prominent but the bar is trimmed so it does not take too
   much vertical space on a phone. The drawer offset tracks the bar height. */
@media (max-width: 640px) {
  .site-header .wrap { height: 92px; }
  .brand img { height: 68px; }
}

/* Anchor targets sit below the sticky header rather than under it. */
#booking, #estimator, #contact-form { scroll-margin-top: 136px; }
@media (max-width: 640px) { #booking, #estimator, #contact-form { scroll-margin-top: 106px; } }

/* ==========================================================================
   Booking wizard — one step at a time
   ========================================================================== */
.wizard { position: relative; }

/* ---------- progress rail ----------
   One component for every screen size: a connected rail with a dot per step.
   Finished steps are buttons, so people can jump back and change something
   instead of stepping backwards one panel at a time. */
.wiz-nav-wrap {
  margin: 0 0 1.7rem;
  padding: 1.4rem 1.45rem 1rem;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}

.wiz-nav {
  /* --inset is half a column, so the rail starts and ends at the outer dot
     centres. JS recalculates it if the number of steps ever changes. */
  --dot: 34px;
  --inset: 10%;
  --fill: 0%;
  position: relative;
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  list-style: none; margin: 0; padding: 0;
}

/* the rail, then the coloured part showing how far along you are */
.wiz-nav::before,
.wiz-nav::after {
  content: ''; position: absolute; z-index: 0;
  top: calc(var(--dot) / 2); margin-top: -2px; height: 4px;
  left: var(--inset); border-radius: 999px;
}
.wiz-nav::before { right: var(--inset); background: var(--line); }
.wiz-nav::after  { width: var(--fill); background: var(--mint); transition: width .4s var(--ease-float); }

.wiz-nav__item { position: relative; z-index: 1; min-width: 0; }

.wiz-nav__btn {
  display: flex; flex-direction: column; align-items: center; gap: .55rem;
  width: 100%; padding: 0 .2rem;
  border: 0; background: none; font: inherit; text-align: center;
  color: var(--ink-3); cursor: default;
  -webkit-tap-highlight-color: transparent;
}

.wiz-nav__num {
  position: relative;
  width: var(--dot); height: var(--dot); border-radius: 50%;
  display: grid; place-items: center;
  background: var(--line-2); color: var(--ink-3);
  font-size: .84rem; font-weight: 800;
  box-shadow: 0 0 0 5px #fff;                 /* keeps the rail off the dot */
  transition: background .25s, color .25s, transform .2s, box-shadow .25s;
}
.wiz-nav__digit,
.wiz-nav__check {
  grid-area: 1 / 1; display: grid; place-items: center;
  transition: opacity .2s, transform .2s;
}
.wiz-nav__check { opacity: 0; transform: scale(.5); }
.wiz-nav__check svg { width: 15px; height: 15px; stroke-width: 3; }

.wiz-nav__label {
  font-size: .84rem; font-weight: 700; line-height: 1.25;
  transition: color .2s;
}

/* Height is reserved even when invisible, so the row does not jump on hover. */
.wiz-nav__edit {
  display: inline-flex; align-items: center; gap: .22rem;
  height: 14px; font-size: .68rem; font-weight: 700;
  color: var(--brand-600); opacity: 0; transition: opacity .2s;
}
.wiz-nav__edit svg { width: 11px; height: 11px; }

/* --- states --- */
.wiz-nav__item.is-done .wiz-nav__num { background: var(--mint); color: #fff; }
.wiz-nav__item.is-done .wiz-nav__digit { opacity: 0; transform: scale(.5); }
.wiz-nav__item.is-done .wiz-nav__check { opacity: 1; transform: none; }
.wiz-nav__item.is-done .wiz-nav__label { color: var(--ink-2); }

.wiz-nav__item.is-active .wiz-nav__num {
  background: var(--brand); color: #fff;
  box-shadow: 0 0 0 5px #fff, 0 0 0 9px var(--sky-100);
}
.wiz-nav__item.is-active .wiz-nav__label { color: var(--ink); }

.wiz-nav__item.is-clickable .wiz-nav__btn { cursor: pointer; }
.wiz-nav__item.is-clickable .wiz-nav__btn:hover .wiz-nav__num,
.wiz-nav__item.is-clickable .wiz-nav__btn:focus-visible .wiz-nav__num { transform: translateY(-2px); }
.wiz-nav__item.is-clickable .wiz-nav__btn:hover .wiz-nav__label,
.wiz-nav__item.is-clickable .wiz-nav__btn:focus-visible .wiz-nav__label { color: var(--brand-600); }
.wiz-nav__item.is-clickable .wiz-nav__btn:hover .wiz-nav__edit,
.wiz-nav__item.is-clickable .wiz-nav__btn:focus-visible .wiz-nav__edit { opacity: 1; }

.wiz-nav__btn:focus-visible { outline: none; }
.wiz-nav__btn:focus-visible .wiz-nav__num { box-shadow: 0 0 0 5px #fff, 0 0 0 9px var(--sky-100); }

@media (prefers-reduced-motion: reduce) {
  .wiz-nav::after, .wiz-nav__num, .wiz-nav__digit, .wiz-nav__check { transition: none; }
}

/* --- the line under the rail --- */
.wiz-nav__meta {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: .35rem .9rem;
  margin: 1.15rem 0 0; padding-top: .85rem;
  border-top: 1px dashed var(--line);
  font-size: .78rem; font-weight: 600; color: var(--ink-3);
}
.wiz-nav__meta strong { color: var(--ink-2); }
.wiz-nav__hint { display: inline-flex; align-items: center; gap: .3rem; color: var(--brand-600); }
.wiz-nav__hint svg { width: 12px; height: 12px; }
.wiz-nav__hint[hidden] { display: none; }

@media (max-width: 620px) {
  .wiz-nav-wrap { padding: 1.1rem .75rem .8rem; border-radius: var(--r); }
  .wiz-nav { --dot: 30px; }
  .wiz-nav__btn { gap: .45rem; padding: 0 .1rem; }
  .wiz-nav__label { font-size: .64rem; letter-spacing: -.01em; }
  .wiz-nav__edit { display: none; }
  .wiz-nav__meta { justify-content: center; text-align: center; font-size: .74rem; }
}
@media (max-width: 360px) {
  .wiz-nav { --dot: 27px; }
  .wiz-nav__label { font-size: .6rem; }
}

/* ---------- panels ---------- */
.wiz-panel[hidden] { display: none; }
.wiz-panel { animation: wizIn .32s var(--ease-float); }
@keyframes wizIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .wiz-panel { animation: none; } }

.wiz-actions {
  display: flex; justify-content: center; align-items: center;
  gap: .8rem; margin-top: 1.6rem;
}
.wiz-actions .btn { min-width: 150px; }
@media (max-width: 520px) {
  .wiz-actions .btn { min-width: 0; flex: 1; }
}

/* ---------- running total ---------- */
.wiz-total {
  position: sticky; bottom: 0; z-index: 20;
  margin-top: 1.4rem;
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  background: var(--ink); color: #C6D4E4;
  padding: .95rem 1.3rem; border-radius: var(--r);
  font-size: .92rem; box-shadow: var(--shadow-lg);
}
.wiz-total strong { color: #fff; }
.wiz-total [data-quote-mini] { font-family: var(--font-display); font-size: 1.25rem; letter-spacing: -.02em; }
.wiz-total[hidden] { display: none; }

/* ---------- summary on the payment step ----------
   Every row carries its own Edit button, so nothing has to be unwound step by
   step to fix one wrong detail. */
.wiz-review {
  margin-top: 1.5rem; padding: 1.1rem 1.15rem .9rem;
  background: var(--sky-50); border: 1px solid var(--sky-100);
  border-radius: var(--r);
}
.wiz-review__head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: .2rem .8rem; margin: 0 0 .6rem;
}
.wiz-review h4 { font-size: .78rem; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-2); margin: 0; }
.wiz-review__note { margin: 0; font-size: .76rem; font-weight: 600; color: var(--ink-3); }
.wiz-review__row {
  display: flex; align-items: baseline; gap: .5rem .9rem;
  padding: .55rem 0; border-bottom: 1px dashed var(--sky-100); font-size: .9rem;
}
.wiz-review__edit {
  flex: none; margin: -.3rem -.4rem -.3rem 0; padding: .3rem .4rem;
  border: 0; background: none; border-radius: var(--r-sm);
  font: inherit; font-size: .78rem; font-weight: 700; color: var(--brand-600);
  cursor: pointer; transition: background .18s, color .18s;
}
.wiz-review__edit:hover { background: #fff; color: var(--brand); }
.wiz-review__edit:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 1px; }

/* ---------- payment step: price estimate ---------- */
.price-estimate { margin-bottom: 1.6rem; padding-bottom: 1.4rem; border-bottom: 1px solid var(--line-2); }
.price-estimate h3 { font-size: 1.05rem; font-weight: 800; color: var(--ink); margin: 0 0 .7rem; }
.price-estimate__row {
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: .25rem .9rem;
  padding: .6rem 0; border-bottom: 1px dashed var(--line-2); font-size: .92rem;
}
.price-estimate__row .badge { flex: none; }
.price-estimate__row:last-child { border-bottom: 0; }
.price-estimate__label { color: var(--brand); font-weight: 600; }

/* Right-hand group: the condition and the badge travel together, so a
   qualified "Free" never reads as an unqualified one. */
.price-estimate__value {
  display: inline-flex; align-items: center; gap: .55rem;
  margin-left: auto; font-weight: 700; color: var(--ink);
}
.price-estimate__value small {
  font-size: .78rem; font-weight: 600; color: var(--ink-3); white-space: nowrap;
}
.wiz-review__row:last-child { border-bottom: 0; }
.wiz-review__row > span { color: var(--ink-3); flex: none; }
.wiz-review__row strong {
  flex: 1 1 auto; min-width: 0; text-align: right;
  color: var(--ink); font-weight: 600; overflow-wrap: anywhere;
}

/* ---------- payment method picker ----------
   Two big targets rather than a dropdown: the choice changes what happens
   after Confirm, so it should be impossible to pick by accident. */
.pay-head {
  margin: 1.7rem 0 .85rem; font-size: 1.02rem; font-weight: 800; color: var(--ink);
}

.pay-methods { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }

.pay-opt {
  position: relative; display: flex; align-items: flex-start; gap: .85rem;
  padding: 1.05rem 1.1rem;
  border: 1.5px solid var(--line); border-radius: var(--r);
  background: #fff; cursor: pointer;
  transition: border-color .18s, background .18s, box-shadow .18s;
}
.pay-opt:hover { border-color: var(--sky-100); background: var(--sky-50); }
.pay-opt input { position: absolute; opacity: 0; pointer-events: none; }

/* the radio itself */
.pay-opt__dot {
  flex: none; width: 20px; height: 20px; margin-top: .15rem; border-radius: 50%;
  border: 2px solid var(--line); background: #fff;
  display: grid; place-items: center; transition: border-color .18s;
}
.pay-opt__dot::after {
  content: ''; width: 10px; height: 10px; border-radius: 50%;
  background: var(--brand); transform: scale(0); transition: transform .18s var(--ease-float);
}

.pay-opt__icon {
  flex: none; width: 38px; height: 38px; border-radius: 11px;
  display: grid; place-items: center;
  background: var(--sky-50); color: var(--brand);
}
.pay-opt__icon svg { width: 20px; height: 20px; }
.pay-opt__icon--wa { background: #E6F7EE; color: #17A64A; }

.pay-opt__text { display: block; min-width: 0; }
.pay-opt__text strong { display: block; font-size: .98rem; color: var(--ink); margin-bottom: .18rem; }
.pay-opt__text small { display: block; font-size: .85rem; line-height: 1.5; color: var(--ink-2); }
.pay-opt__marks {
  display: inline-block; margin-top: .5rem; padding: .2rem .5rem;
  border-radius: 999px; background: var(--line-2);
  font-size: .7rem; font-weight: 700; letter-spacing: .01em; color: var(--ink-3);
}

/* --- selected --- */
.pay-opt:has(input:checked) {
  border-color: var(--brand); background: var(--sky-50);
  box-shadow: 0 0 0 3px rgba(10, 87, 162, .09);
}
.pay-opt:has(input:checked) .pay-opt__dot { border-color: var(--brand); }
.pay-opt:has(input:checked) .pay-opt__dot::after { transform: scale(1); }
.pay-opt:has(input:focus-visible) { border-color: var(--brand-600); box-shadow: 0 0 0 3px var(--sky-100); }

/* Older browsers without :has still need the checked state to read clearly. */
@supports not selector(:has(*)) {
  .pay-opt input:checked ~ .pay-opt__dot { border-color: var(--brand); }
  .pay-opt input:checked ~ .pay-opt__dot::after { transform: scale(1); }
}

/* --- card switched off in the dashboard: shown, but clearly not pickable --- */
.pay-opt--soon { cursor: default; background: linear-gradient(180deg, #fff 0%, var(--line-2) 160%); border-style: dashed; }
.pay-opt--soon:hover { border-color: var(--line); background: linear-gradient(180deg, #fff 0%, var(--line-2) 160%); }
.pay-opt--soon .pay-opt__dot { border-color: var(--line); background: var(--line-2); }
.pay-opt--soon .pay-opt__icon { background: var(--line-2); color: var(--ink-3); }
.pay-opt--soon .pay-opt__text strong { color: var(--ink-2); display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; }
.pay-opt--soon .pay-opt__text small,
.pay-opt--soon .pay-opt__marks { opacity: .8; }
.pay-opt__soon {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .2rem .6rem .2rem .5rem; border-radius: 999px;
  background: linear-gradient(135deg, #FFF6E0, #FDEBC4);
  border: 1px solid #F3D99A; color: #8A5A00;
  font-size: .68rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
}
.pay-opt__soon::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%; background: #E0A21B;
  box-shadow: 0 0 0 3px rgba(224, 162, 27, .18);
}

.pay-note {
  display: flex; align-items: flex-start; gap: .55rem;
  margin: .8rem 0 0; padding: .75rem .9rem;
  background: var(--mint-50); border-radius: var(--r-sm);
  font-size: .82rem; line-height: 1.55; color: var(--ink-2);
}
.pay-note svg { flex: none; width: 15px; height: 15px; margin-top: .12rem; color: #0B8A68; }
.pay-note[hidden] { display: none; }

@media (max-width: 480px) {
  .pay-opt { padding: .9rem .85rem; gap: .65rem; }
  .pay-opt__icon { width: 34px; height: 34px; border-radius: 10px; }
}

/* the estimator is the whole step now, so drop the sticky offset */
.wiz-panel .quote { position: static; }

/* On phones the sticky total shares the bottom edge with the WhatsApp button,
   so keep the amount clear of it. */
@media (max-width: 640px) {
  .wiz-total { padding-right: 4.9rem; font-size: .86rem; }
  .wiz-total [data-quote-mini] { font-size: 1.1rem; }
}

/* ==========================================================================
   Promises — one white panel, three columns with hairline dividers.
   Stays three across as the window narrows; only stacks on real phones.
   ========================================================================== */
.promises {
  background: #fff;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
.promise {
  position: relative;
  padding: clamp(1.4rem, 2.6vw, 2.4rem);
}
/* inset divider rather than a full-height border, so it floats like the panel */
.promise + .promise::before {
  content: '';
  position: absolute; left: 0; top: 12%; bottom: 12%;
  width: 1px; background: var(--line);
}
.promise__icon {
  display: block; color: var(--brand);
  margin-bottom: clamp(.9rem, 1.6vw, 1.3rem);
}
.promise__icon svg {
  width: clamp(38px, 4.2vw, 54px);
  height: clamp(38px, 4.2vw, 54px);
  stroke-width: 1.25;      /* fine detail needs a thinner stroke to stay legible */
}
.promise h3 {
  font-size: clamp(.98rem, 1.5vw, 1.2rem);
  margin-bottom: .5rem; line-height: 1.28;
}
.promise p {
  font-size: clamp(.82rem, 1.05vw, .93rem);
  color: var(--ink-2); line-height: 1.6; margin: 0;
}

/* below this the columns get too narrow to read, so stack with a rule between */
@media (max-width: 560px) {
  .promises { grid-template-columns: 1fr; }
  .promise + .promise::before {
    left: clamp(1.4rem, 2.6vw, 2.4rem); right: clamp(1.4rem, 2.6vw, 2.4rem);
    top: 0; bottom: auto; width: auto; height: 1px;
  }
}

/* ==========================================================================
   Service picker on the booking form
   ========================================================================== */
.svc-picker { list-style: none; margin: 0 0 1.6rem; padding: 0; display: grid; gap: .6rem; }

.svc-opt {
  position: relative; display: flex; align-items: flex-start; gap: .9rem;
  padding: 1rem 1.1rem; background: #fff;
  border: 2px solid var(--line); border-radius: var(--r);
  cursor: pointer; transition: border-color .16s, background .16s;
}
.svc-opt:hover { border-color: var(--sky-100); background: var(--sky-50); }
.svc-opt input { position: absolute; opacity: 0; pointer-events: none; }

.svc-opt__icon {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--sky-100); color: var(--brand);
  transition: background .16s, color .16s;
}
.svc-opt__icon svg { width: 22px; height: 22px; }

.svc-opt__text { flex: 1; min-width: 0; }
.svc-opt__text strong { display: block; color: var(--ink); font-size: .98rem; line-height: 1.3; }
.svc-opt__text small { display: block; color: var(--ink-2); font-size: .85rem; line-height: 1.5; margin-top: .12rem; }
.svc-opt__note {
  display: inline-flex; align-items: center; gap: .3rem; margin-top: .45rem;
  background: var(--sun-50); color: #8C6210;
  padding: .18rem .55rem; border-radius: 999px;
  font-size: .74rem; font-weight: 700;
}
.svc-opt__note svg { width: 12px; height: 12px; }

.svc-opt__dot {
  width: 22px; height: 22px; border-radius: 50%; flex: none; align-self: center;
  border: 2px solid var(--line); display: grid; place-items: center; transition: .16s;
}
.svc-opt__dot::after { content: ''; width: 10px; height: 10px; border-radius: 50%; background: transparent; transition: .16s; }

.svc-opt:has(input:checked) { border-color: var(--brand); background: var(--sky-50); }
.svc-opt:has(input:checked) .svc-opt__icon { background: var(--brand); color: #fff; }
.svc-opt:has(input:checked) .svc-opt__dot { border-color: var(--brand); }
.svc-opt:has(input:checked) .svc-opt__dot::after { background: var(--brand); }
.svc-opt input:focus-visible ~ .svc-opt__dot { outline: 3px solid var(--brand-600); outline-offset: 2px; }

.svc-add {
  border-top: 1px solid var(--line-2); padding-top: 1.3rem;
}

@media (max-width: 520px) {
  .svc-opt { padding: .85rem .9rem; gap: .7rem; }
  .svc-opt__icon { width: 38px; height: 38px; }
  .svc-opt__icon svg { width: 19px; height: 19px; }
  .svc-opt__text strong { font-size: .92rem; }
  .svc-opt__text small { font-size: .8rem; }
}

/* ---------- address autocomplete ---------- */
.addr-wrap { position: relative; }

.addr-results {
  position: absolute; left: 0; right: 0; top: calc(100% - 1.2rem); z-index: 40;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow-lg); overflow: hidden auto; max-height: 320px;
}
.addr-item {
  display: flex; gap: .75rem; align-items: flex-start; width: 100%;
  padding: .8rem 1rem; border: 0; border-bottom: 1px solid var(--line-2);
  background: #fff; text-align: left; cursor: pointer; font: inherit;
}
.addr-item:last-child { border-bottom: 0; }
.addr-item:hover, .addr-item.is-active { background: var(--sky-50); }
.addr-item__pin {
  width: 18px; height: 18px; flex: none; margin-top: .15rem; border-radius: 50%;
  background: var(--sky-100); position: relative;
}
.addr-item__pin::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  width: 6px; height: 6px; border-radius: 50%; background: var(--brand);
}
.addr-item strong { display: block; color: var(--ink); font-size: .92rem; font-weight: 600; line-height: 1.35; }
.addr-item small { display: block; color: var(--ink-3); font-size: .8rem; margin-top: .1rem; }
.addr-empty { padding: 1rem; color: var(--ink-3); font-size: .88rem; }

.addr-status { font-size: .8rem; color: var(--ink-3); margin-top: .35rem; min-height: 1.1em; }
.addr-status--ok { color: #077A5C; font-weight: 600; }
.addr-status--warn { color: #8C6210; }

/* ---------- contact step: individual / company toggle ---------- */
.contact-type { display: flex; gap: 1.6rem; margin-bottom: 1.3rem; }
.contact-type__opt { display: flex; align-items: center; gap: .55rem; font-size: .93rem; font-weight: 600; color: var(--ink); cursor: pointer; }
.contact-type__opt input { position: absolute; opacity: 0; pointer-events: none; }
.contact-type__dot { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line); flex: none; display: grid; place-items: center; transition: .16s; }
.contact-type__dot::after { content: ''; width: 10px; height: 10px; border-radius: 50%; background: transparent; transition: .16s; }
.contact-type__opt input:checked ~ .contact-type__dot { border-color: var(--brand); }
.contact-type__opt input:checked ~ .contact-type__dot::after { background: var(--brand); }
.contact-type__opt input:focus-visible ~ .contact-type__dot { outline: 3px solid var(--brand-600); outline-offset: 2px; }

/* ---------- contact step: phone with country-code picker ---------- */
.phone-group { display: flex; flex-wrap: wrap; gap: .6rem; position: relative; }
/* min-width:0 lets the input shrink to the row rather than forcing overflow;
   an error inside the row drops onto its own line instead of stealing width. */
.phone-group .field-error { flex: 0 0 100%; width: 100%; margin-top: 0; }
.phone-code {
  flex: none; display: flex; align-items: center; gap: .4rem;
  min-width: 84px; padding: 0 .7rem; border: 2px solid var(--line); border-radius: 14px;
  background: var(--line-2); color: var(--ink); font-weight: 700; font-size: .95rem;
  cursor: pointer; transition: border-color .16s, background .16s;
}
.phone-code svg { width: 14px; height: 14px; color: var(--ink-3); }
.phone-code:hover { border-color: var(--sky-100); }
.phone-code[aria-expanded="true"] { border-color: var(--brand); background: #fff; }
.phone-group .input { flex: 1; min-width: 0; }

.phone-code-list {
  position: absolute; z-index: 30; top: calc(100% + .4rem); left: 0;
  width: 280px; max-width: calc(100vw - 3rem);
  background: #fff; border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow-lg); overflow: hidden;
}
.phone-code-search {
  width: 100%; padding: .7rem .9rem; border: 0; border-bottom: 1px solid var(--line-2);
  font-size: .88rem; color: var(--ink); outline: none;
}
.phone-code-items { max-height: 260px; overflow-y: auto; }
.phone-code-item {
  width: 100%; display: flex; justify-content: space-between; align-items: center; gap: .8rem;
  padding: .6rem .9rem; border: 0; border-bottom: 1px solid var(--line-2);
  background: #fff; color: var(--ink); font-size: .85rem; text-align: left; cursor: pointer;
}
.phone-code-item:last-child { border-bottom: 0; }
.phone-code-item:hover { background: var(--sky-50); }
.phone-code-item strong { color: var(--ink-3); font-weight: 700; flex: none; }
.phone-code-empty { padding: 1rem; color: var(--ink-3); font-size: .85rem; }

/* ---------- address step ---------- */
.addr-clear {
  position: absolute; right: .6rem; top: 2.55rem;
  width: 30px; height: 30px; display: grid; place-items: center;
  border: 0; border-radius: 50%; background: var(--line-2); color: var(--ink-3);
  cursor: pointer; transition: background .16s, color .16s;
}
.addr-clear svg { width: 14px; height: 14px; }
.addr-clear:hover { background: var(--line); color: var(--ink); }
.addr-clear[hidden] { display: none; }

.addr-locate {
  display: inline-flex; align-items: center; gap: .5rem;
  border: 0; background: none; padding: .7rem 0 .2rem; margin-bottom: .6rem;
  color: var(--brand); font-weight: 700; font-size: .88rem; cursor: pointer;
}
.addr-locate svg { width: 16px; height: 16px; }
.addr-locate:hover { color: var(--brand-700); }
.addr-locate:disabled { opacity: .5; cursor: default; }

.addr-type-group { display: grid; grid-template-columns: repeat(3, 1fr); gap: .7rem; }
.addr-type-opt {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: .4rem;
  padding: .9rem .6rem; border: 2px solid var(--line); border-radius: var(--r);
  font-size: .85rem; font-weight: 700; color: var(--ink-2); cursor: pointer;
  transition: border-color .16s, background .16s, color .16s;
}
.addr-type-opt input { position: absolute; opacity: 0; pointer-events: none; }
.addr-type-opt svg { width: 20px; height: 20px; }
.addr-type-opt:hover { border-color: var(--sky-100); background: var(--sky-50); }
.addr-type-opt:has(input:checked) { border-color: var(--brand); background: var(--sky-50); color: var(--brand); }

.addr-map-wrap { position: relative; border-radius: var(--r); overflow: hidden; box-shadow: var(--shadow-sm); }
.addr-map { width: 100%; height: 300px; background: linear-gradient(135deg,#EEF4FA,#E3ECF5); }
.addr-map-wrap .map-pin { z-index: 2; }
.addr-map-field { margin-top: 1.1rem; }
.addr-map-field[hidden] { display: none; }
.addr-map-tip { z-index: 3; }
.addr-powered { padding: .45rem .9rem; font-size: .7rem; font-weight: 600; letter-spacing: .02em; color: var(--ink-3); text-align: right; border-top: 1px solid var(--line); background: #FBFCFE; }
@media (max-width: 640px) {
  .addr-map { height: 280px; }
  .addr-map-wrap .addr-map-tip { left: .5rem; right: .5rem; top: .5rem; font-size: .72rem; padding: .45rem .6rem; }
}
.addr-map-tip {
  position: absolute; left: .7rem; right: .7rem; top: .7rem;
  display: flex; align-items: center; gap: .5rem;
  background: rgba(20,36,58,.88); color: #fff; font-size: .78rem; font-weight: 600;
  padding: .6rem .8rem; border-radius: 10px; line-height: 1.35; pointer-events: none;
}
.addr-map-tip svg { width: 16px; height: 16px; flex: none; }
#addrDetails .field { margin-top: 1.3rem; }

/* homepage variant: the rows are links rather than radio options */
.svc-picker--static .svc-opt { cursor: pointer; }
.svc-picker--static .svc-opt:hover { border-color: var(--brand); background: var(--sky-50); }
.svc-opt__go {
  width: 30px; height: 30px; border-radius: 50%; flex: none; align-self: center;
  display: grid; place-items: center; color: var(--brand);
  background: var(--sky-100); transition: background .16s, color .16s, transform .16s;
}
.svc-opt__go svg { width: 15px; height: 15px; }
.svc-picker--static .svc-opt:hover .svc-opt__go { background: var(--brand); color: #fff; transform: translateX(2px); }

/* ---------- time slot step ---------- */
.slot-head {
  font-size: .95rem; margin-bottom: 1rem; color: var(--ink);
  display: flex; align-items: center; gap: .7rem;
}
.slot-head::after { content: ''; flex: 1; height: 1px; background: var(--line-2); }

/* a select with a leading icon, matching the day picker beside it */
.select-lead { position: relative; }
.select-lead__icon {
  position: absolute; left: .95rem; top: 50%; transform: translateY(-50%);
  color: var(--brand); pointer-events: none; display: grid; place-items: center;
}
.select-lead__icon svg { width: 18px; height: 18px; }
.select-lead .select { padding-left: 2.9rem; }

/* ---------- driver note ---------- */
.note-add {
  display: flex; align-items: center; justify-content: center; gap: .55rem;
  width: 100%; padding: .95rem 1rem; font: inherit; font-weight: 700;
  font-size: .95rem; cursor: pointer;
  border: 2px dashed var(--sky-200, #C9DFF8); border-radius: 14px;
  background: var(--sky-50); color: var(--brand);
  transition: background .16s, border-color .16s;
}
.note-add:hover { background: #E4F0FE; border-color: var(--brand); }
.note-add:focus-visible { outline: 3px solid var(--brand-600); outline-offset: 2px; }
.note-add svg { width: 18px; height: 18px; }

/* the saved note, shown above the button — click it to edit */
.note-preview {
  margin: 0 0 .7rem; padding: .9rem 1rem; cursor: pointer;
  border-radius: 14px; border: 2px solid var(--line);
  background: #fff; color: var(--ink-2);
  font-size: .93rem; line-height: 1.55; white-space: pre-wrap;
  transition: border-color .16s;
}
.note-preview:hover { border-color: #C9D6E4; }
.note-preview[hidden] { display: none; }

.note-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center; padding: 1.2rem;
  background: rgba(20, 28, 40, .55); backdrop-filter: blur(2px);
  animation: noteFade .18s ease;
}
.note-modal[hidden] { display: none; }
.note-modal__card {
  width: 100%; max-width: 460px; background: #fff;
  border-radius: var(--r-lg, 22px); padding: 1.5rem;
  box-shadow: 0 20px 60px rgba(15,25,40,.28);
  animation: noteRise .2s var(--ease-float);
}
@keyframes noteFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes noteRise {
  from { opacity: 0; transform: translateY(10px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .note-modal, .note-modal__card { animation: none; }
}

.note-modal__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: 1rem;
}
.note-modal__head h3 { margin: 0; font-size: 1.15rem; color: var(--ink); }
.note-modal__close {
  flex: none; display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0; cursor: pointer;
  border: 0; border-radius: 50%; background: var(--sky-50); color: var(--ink-2);
  transition: background .16s, color .16s;
}
.note-modal__close:hover { background: var(--line-2); color: var(--ink); }
.note-modal__close svg { width: 16px; height: 16px; }

.note-modal__card .textarea { width: 100%; min-height: 118px; resize: vertical; }
.note-modal__count {
  margin-top: .4rem; text-align: right; font-size: .8rem; color: var(--ink-3);
}
.note-modal__actions {
  display: flex; justify-content: flex-end; gap: .6rem; margin-top: 1.2rem;
}
@media (max-width: 480px) {
  .note-modal__actions { flex-direction: column-reverse; }
  .note-modal__actions .btn { width: 100%; }
}

/* stop the page scrolling behind the open modal */
body.has-modal { overflow: hidden; }

/* ---------- icon dropdown (driver instructions) ---------- */
.optsel { position: relative; }

.optsel__trigger {
  display: flex; align-items: center; gap: .7rem; width: 100%;
  padding: .82rem 1rem; font: inherit; text-align: left; cursor: pointer;
  border: 2px solid var(--line); border-radius: 14px; background: #fff;
  color: var(--ink); transition: border-color .16s, box-shadow .16s;
}
.optsel__trigger:hover { border-color: #C9D6E4; }
.optsel.is-open .optsel__trigger {
  border-color: var(--brand); box-shadow: 0 0 0 4px rgba(10,87,162,.1);
}
.optsel__trigger:focus-visible { outline: 3px solid var(--brand-600); outline-offset: 2px; }

.optsel__icon { color: var(--brand); flex: none; display: flex; }
.optsel__icon svg { width: 20px; height: 20px; }
.optsel__label { flex: 1; font-size: .95rem; font-weight: 600; }
.optsel__chev { color: var(--ink-3); flex: none; display: flex; transition: transform .2s var(--ease); }
/* icon() emits an SVG with no width or height, so without this the chevron
   collapses to nothing and the control reads as a plain text box. */
.optsel__chev svg { width: 18px; height: 18px; }
.optsel.is-open .optsel__chev { transform: rotate(180deg); }

/* Floats over the form, like the calendar, so opening it does not push the
   fields below it down the page. */
.optsel__pop {
  position: absolute; top: calc(100% + .5rem); left: 0; z-index: 30;
  width: 100%;
  /* A long list used to run past the bottom of the window, so choosing the
     last option meant scrolling the page. It scrolls inside itself now and
     never grows taller than the viewport can hold. */
  max-height: min(48vh, 340px);
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
  border: 2px solid var(--line); border-radius: var(--r);
  background: #fff; box-shadow: var(--shadow-lg);
  animation: calOpen .2s var(--ease-float);
}

/* Opens upward when the trigger sits low on the screen. */
.optsel__pop--up { top: auto; bottom: calc(100% + .5rem); }
.optsel__pop[hidden] { display: none; }
.optsel.is-open { z-index: 30; }
@media (prefers-reduced-motion: reduce) { .optsel__pop { animation: none; } }

.optsel__opt {
  display: flex; align-items: center; gap: .7rem; width: 100%;
  padding: .85rem 1rem; font: inherit; text-align: left; cursor: pointer;
  border: 0; border-bottom: 1px solid var(--line-2); background: transparent;
  color: var(--ink); transition: background .14s;
}
.optsel__opt:last-child { border-bottom: 0; }
.optsel__opt:hover { background: var(--sky-50); }
.optsel__opt:focus-visible { outline: 3px solid var(--brand-600); outline-offset: -3px; }
.optsel__opt .optsel__label { font-weight: 600; }
.optsel__opt.is-selected { background: var(--sky-50); }

/* An option that exists but is not offered for the item currently chosen.
   Left visible on purpose — a service quietly vanishing from the list looks
   like a bug. Greyed and unclickable reads as unavailable without needing a
   label to say so. */
/* Muted, not faded. Dimming the whole row with opacity took the text below
   readable contrast — the name still has to be legible so it is obvious which
   service is unavailable. The greyed dot and the flat background carry the
   "you cannot pick this" message instead. */
.optsel__opt.is-off { cursor: not-allowed; background: var(--foam-2, #F7FAFD); }
.optsel__opt.is-off .optsel__label { color: var(--ink-2); font-weight: 500; }
.optsel__opt.is-off:hover { background: var(--foam-2, #F7FAFD); }
.optsel__opt.is-off .optsel__dot { border-color: var(--line); background: var(--line-2); }
/* the trigger carries an icon but the rows do not, so indent them to match */
.optsel__pop--noicon .optsel__opt .optsel__label { padding-left: calc(20px + .7rem); }

/* the radio marker on the right, filled on the chosen row */
.optsel__dot {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--line); background: #fff; position: relative;
}
.optsel__opt.is-selected .optsel__dot { border-color: var(--brand); }
.optsel__opt.is-selected .optsel__dot::after {
  content: ''; position: absolute; inset: 2px;
  border-radius: 50%; background: var(--brand);
}

/* ---------- booking calendar ---------- */
.cal-field { position: relative; }

.cal-trigger {
  display: flex; align-items: center; gap: .65rem; width: 100%;
  padding: .82rem 1rem; font: inherit; text-align: left; cursor: pointer;
  border: 2px solid var(--line); border-radius: 14px; background: #fff;
  color: var(--ink); transition: border-color .16s, box-shadow .16s;
}
.cal-trigger:hover { border-color: #C9D6E4; }
.cal-field.is-open .cal-trigger {
  border-color: var(--brand); box-shadow: 0 0 0 4px rgba(10,87,162,.1);
}
.cal-trigger__icon { color: var(--brand); flex: none; }
.cal-trigger__label { flex: 1; font-size: .95rem; font-weight: 600; }
.cal-trigger__chev { color: var(--ink-3); flex: none; transition: transform .2s var(--ease); }
.cal-field.is-open .cal-trigger__chev { transform: rotate(180deg); }
.cal-trigger:focus-visible { outline: 3px solid var(--brand-600); outline-offset: 2px; }

/* Floats over the form rather than pushing it down. .cal-field is the
   positioning context, so the grid stays pinned to its own trigger and cannot
   drift. It opens downward, so it never lands behind the sticky header. */
.cal-pop {
  position: absolute;
  top: calc(100% + .5rem);
  left: 0;
  z-index: 30;
  /* Days are square, so the grid grows with the field. In a narrow booking
     column that is fine; in a full-width dashboard field it turns into
     125px circles. Cap it — a calendar has a natural size. */
  width: 100%;
  min-width: 288px;
  max-width: min(360px, calc(100vw - 2.5rem));
  box-shadow: var(--shadow-lg);
  animation: calOpen .2s var(--ease-float);
}
.cal-pop[hidden] { display: none; }
/* raise the whole field while open so the grid sits above the fields below */
.cal-field.is-open { z-index: 30; }
@keyframes calOpen {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .cal-pop { animation: none; } }

.cal {
  border: 2px solid var(--line); border-radius: var(--r);
  background: #fff; padding: .9rem;
}
.cal__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-bottom: .7rem;
}
.cal__head strong { font-size: .95rem; color: var(--ink); }
.cal__nav {
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--line); background: #fff; color: var(--ink);
  display: grid; place-items: center; cursor: pointer; transition: .16s;
}
.cal__nav:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.cal__nav:disabled { opacity: .3; cursor: not-allowed; }

.cal__dow, .cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal__dow span {
  text-align: center; font-size: .7rem; font-weight: 700;
  color: var(--ink-3); padding-bottom: .35rem;
}
.cal__pad { aspect-ratio: 1; }

.cal__day {
  aspect-ratio: 1; display: grid; place-items: center;
  border: 0; background: transparent; border-radius: 50%;
  font: inherit; font-size: .87rem; font-weight: 600; color: var(--ink);
  cursor: pointer; transition: background .14s, color .14s;
}
.cal__day:hover:not(.is-off):not(.is-selected) { background: var(--sky-100); }
.cal__day.is-off { color: #C4CFDC; cursor: not-allowed; font-weight: 400; }

/* Only shown on free date fields (the dashboard), where the native picker
   used to offer these two. */
.cal__foot {
  display: flex; justify-content: space-between; gap: .5rem;
  margin-top: .7rem; padding-top: .7rem; border-top: 1px solid var(--line-2);
}
.cal__foot-btn {
  padding: .35rem .6rem; border: 0; border-radius: var(--r-sm);
  background: none; font: inherit; font-size: .82rem; font-weight: 700;
  color: var(--brand-600); cursor: pointer; transition: background .16s;
}
.cal__foot-btn:hover { background: var(--sky-50); }
.cal__day.is-selected { background: var(--brand); color: #fff; }
.cal__day.is-today:not(.is-selected) { box-shadow: inset 0 0 0 1.5px var(--brand); }
.cal__day:focus-visible { outline: 3px solid var(--brand-600); outline-offset: 1px; }

.cal__chosen {
  margin: .8rem 0 0; padding-top: .7rem; border-top: 1px solid var(--line-2);
  font-size: .84rem; color: var(--ink-3); text-align: center;
}
.cal__chosen strong { color: var(--ink); }

@media (max-width: 420px) {
  .cal { padding: .7rem; }
  .cal__day { font-size: .82rem; }
}

/* ---------- pages that are just a form, with no banner above ---------- */
.section--form-top { padding-top: clamp(32px, 4vw, 52px); }

/* fallback route when address lookup is down or has nothing useful */
.addr-manual {
  margin-top: .5rem; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: .85rem; font-weight: 600; color: var(--brand);
  text-decoration: underline; text-underline-offset: 3px;
}
.addr-manual:hover { color: var(--brand-700); }
.addr-manual:focus-visible { outline: 3px solid var(--brand-600); outline-offset: 3px; border-radius: 4px; }

/* ==========================================================================
   Quality assurance — photo with a floating stat, and animated meters
   The bars fill from zero when the row scrolls into view. .reveal already
   does that work elsewhere on the page, so this hooks into the same class
   rather than adding a second observer.
   ========================================================================== */
.quality__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
}

/* The badge now hangs mostly below the photo, so the media column reserves
   room for the part that overhangs rather than letting it cover the subject. */
.quality__media { position: relative; padding-bottom: 4.5rem; }
.quality__photo {
  border-radius: var(--r-xl); overflow: hidden;
  aspect-ratio: 4/4.7; box-shadow: var(--shadow-lg);
}
/* The source photo is a 3:4 portrait in a slightly wider frame, so the crop
   eats the top and bottom. Biasing upward keeps the face intact. */
.quality__photo img {
  width: 100%; height: 100%; object-fit: cover;
  object-position: 50% 18%; display: block;
}

/* Sits across the bottom-left corner of the photo, overlapping it — the same
   trick as the hero badges, so the section belongs to the rest of the page. */
.quality__badge {
  position: absolute; left: clamp(-1.75rem, -3vw, -.5rem); bottom: 0;
  width: min(268px, 74%); padding: 1.15rem 1.3rem 1.25rem;
  border-radius: var(--r-lg); color: #fff;
  background: linear-gradient(150deg, var(--brand) 0%, var(--brand-700, #073F76) 100%);
  box-shadow: 0 22px 46px rgba(10, 87, 162, .34);
}
.quality__badge-top { display: flex; align-items: center; gap: .8rem; }
.quality__badge-num {
  font-size: clamp(1.9rem, 3.4vw, 2.5rem); font-weight: 800;
  line-height: 1; letter-spacing: -.03em;
}
.quality__badge-label {
  font-size: .87rem; font-weight: 700; line-height: 1.25;
  color: rgba(255, 255, 255, .92);
}
.quality__badge p {
  margin: .7rem 0 0; font-size: .85rem; line-height: 1.5;
  color: rgba(255, 255, 255, .8);
}
/* A solid white pill, so the booking action reads as a button rather than an
   underlined aside — it is the only call to action in this section. */
.quality__badge-cta {
  display: inline-flex; align-items: center; gap: .45rem; margin-top: 1rem;
  padding: .6rem 1.1rem; border-radius: 999px;
  background: #fff; color: var(--brand); text-decoration: none;
  font-size: .87rem; font-weight: 700; letter-spacing: -.008em;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.quality__badge-cta svg { width: 16px; height: 16px; flex: none; transition: transform .25s var(--ease); }
.quality__badge-cta:hover { background: var(--sky-50); color: var(--brand-700); }
.quality__badge-cta:hover svg { transform: translateX(3px); }
.quality__badge-cta:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .quality__badge-cta:hover svg { transform: none; }
}

/* --- meters --- */
.meters { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.35rem; }

.meter__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; margin-bottom: .5rem;
}
.meter__label { font-size: .98rem; font-weight: 700; color: var(--ink); }
.meter__pct {
  font-family: var(--font-mono); font-size: .88rem; font-weight: 500;
  color: var(--brand); flex: none;
}

.meter__track {
  height: 9px; border-radius: 999px; background: var(--line-2); overflow: hidden;
}
.meter__fill {
  display: block; height: 100%; width: 0; border-radius: 999px;
  background: linear-gradient(90deg, var(--brand) 0%, var(--mint) 100%);
  transition: width 1.1s var(--ease-float);
}
.meter.is-in .meter__fill { width: var(--pct); }

/* Nothing should animate for someone who has asked it not to. */
@media (prefers-reduced-motion: reduce) {
  .meter__fill { transition: none; width: var(--pct); }
}

@media (max-width: 900px) {
  .quality__grid { grid-template-columns: 1fr; gap: 2.6rem; }

  /* On one column the overlap has nowhere to go — it landed on her hands and
     the laundry, which is the subject. Photo and badge instead become a single
     card: the wrapper owns the radius and the shadow, and the two children sit
     flush inside it, so the join reads as deliberate rather than as a panel
     that slipped. */
  .quality__media {
    padding-bottom: 0; max-width: 460px; margin-inline: auto;
    border-radius: var(--r-xl); overflow: hidden;
    box-shadow: var(--shadow-lg);
  }
  .quality__photo { aspect-ratio: 4/4; border-radius: 0; box-shadow: none; }
  .quality__badge {
    position: static; width: 100%; margin-top: 0;
    border-radius: 0; box-shadow: none;
    padding: 1.35rem 1.4rem 1.5rem;
  }

  /* Room to breathe now the card is not fighting the photo for space. */
  .quality__badge-top { gap: .7rem; }
  .quality__badge-num { font-size: 2.3rem; }
  .quality__badge-label { font-size: .95rem; }
  .quality__badge p { font-size: .92rem; margin-top: .8rem; }

  /* Full width so it is an unmissable tap target, not a link tucked in a
     corner next to the floating WhatsApp button. */
  .quality__badge-cta {
    width: 100%; justify-content: center;
    margin-top: 1.2rem; padding: .85rem 1.1rem; font-size: .95rem;
  }
}

/* ==========================================================================
   Track an order — homepage
   No panel, no badge, no background: the same centred section head the rest
   of the page uses. The entrance is the only thing added — the lines arrive
   one behind the other rather than all at once.
   ========================================================================== */
.track-cta { max-width: 680px; margin-inline: auto; text-align: center; }
.track-cta h2 { margin: .9rem 0 .6rem; }
.track-cta p { margin: 0 auto 1.9rem; max-width: 32em; color: var(--ink-2); font-size: 1.08rem; }

/* .reveal on the wrapper brings .is-in from the observer already running on
   this page; the children ride in behind it on a short stagger. */
.track-cta > * {
  opacity: 0; transform: translateY(14px);
  transition: opacity .5s var(--ease-float), transform .5s var(--ease-float);
}
.track-cta.is-in > * { opacity: 1; transform: none; }

.track-cta.is-in .eyebrow { transition-delay: .06s; }
.track-cta.is-in h2       { transition-delay: .16s; }
.track-cta.is-in p        { transition-delay: .26s; }
.track-cta.is-in .btn     { transition-delay: .36s; }

/* The button lands with a little more life than the text above it. */
.track-cta > .btn { transform: translateY(14px) scale(.94); }
.track-cta.is-in > .btn { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .track-cta > * { transition: none; opacity: 1; transform: none; }
}

/* ==========================================================================
   Track an order — the detail panels
   Two panels with the same shell: what is happening, then what it costs.
   Before this it was a bare list followed by a shaded box, which read as two
   unrelated fragments instead of one summary.
   ========================================================================== */
.track-block {
  padding: 1.2rem 1.3rem;
  border: 1px solid var(--line-2); border-radius: var(--r);
  background: var(--foam);
}

/* Progress on the left, detail on the right. Stacked on a phone, where the
   only sensible order is: where is it, then when, then what it costs. */
.track-result { display: grid; gap: 1.6rem; align-items: start; }
@media (min-width: 820px) {
  .track-result { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr); gap: 2rem; }
}
.track-result__main { min-width: 0; }

.track-blocks { display: grid; gap: .9rem; align-items: start; }
.track-block h3 {
  margin: 0 0 .9rem; font-size: .74rem; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
}
.track-block__empty { margin: 0; font-size: .92rem; color: var(--ink-2); line-height: 1.6; }

/* --- label / value rows --- */
.track-rows { margin: 0; }
.track-rows > div {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; padding: .42rem 0;
}
.track-rows dt { font-size: .88rem; color: var(--ink-3); }
.track-rows dd {
  margin: 0; text-align: right; font-weight: 700; color: var(--ink); font-size: .95rem;
}
/* the time slot belongs with its date, not on a row of its own */
.track-rows dd span {
  display: block; font-size: .82rem; font-weight: 600; color: var(--ink-2);
}

.track-rows--money { margin-top: .9rem; padding-top: .3rem; border-top: 1px solid var(--line-2); }
.track-rows__total { padding-top: .6rem !important; border-top: 1px solid var(--line-2); }
.track-rows__total dt { font-weight: 700; color: var(--ink-2); }
.track-rows__total dd { color: var(--brand); font-size: 1.1rem; }

/* --- the priced lines --- */
.track-lines { list-style: none; margin: 0; padding: 0; }
.track-lines li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  padding: .62rem 0; border-bottom: 1px dashed var(--line-2);
}
.track-lines li:first-child { padding-top: 0; }
.track-lines li:last-child { border-bottom: 0; }
.track-lines strong { display: block; font-size: .95rem; color: var(--ink); }
.track-lines span {
  display: block; margin-top: .12rem;
  font-size: .82rem; font-weight: 500; color: var(--ink-3);
}
.track-lines b { flex: none; font-size: .95rem; white-space: nowrap; }

/* ============================================================
   Blog
   ============================================================ */

.wrap--narrow { max-width: 760px; }

/* Builds on the existing .chip rather than redefining it. The base chip has a
   decorative mint dot, which reads as a status marker — wrong for a filter, so
   it is dropped here. */
.blog-filters { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: 2rem; }
.blog-filters .chip,
.post__head .chip { text-decoration: none; }
.blog-filters .chip::before,
.post__head .chip::before { display: none; }
.chip.is-on { background: var(--brand); border-color: var(--brand); color: #fff; }
.chip.is-on:hover { color: #fff; border-color: var(--brand); }

/* ---------- lead story ---------- */
/* A grid of equal cards gives the eye nowhere to land, so the newest post runs
   full width with the image beside the words. */
.post-feature {
  display: grid; grid-template-columns: 1.15fr 1fr; gap: 0;
  background: #fff; border-radius: var(--r-xl); overflow: hidden;
  box-shadow: var(--shadow); margin-bottom: 2.2rem; text-decoration: none;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease);
}
.post-feature:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.post-feature__media { aspect-ratio: 16/10; position: relative; overflow: hidden; }
.post-feature__media img {
  /* Taken out of flow so the photo's own shape can never stretch the box:
     the aspect-ratio above decides the size, the image just fills it. */
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.post-feature__body { padding: clamp(1.6rem, 3vw, 2.4rem); align-self: center; }
.post-feature__body h2 { font-size: clamp(1.4rem, 2.6vw, 1.95rem); margin: .6rem 0 .6rem; color: var(--ink); }
.post-feature__body p { color: var(--ink-2); margin: 0 0 1rem; }

/* ---------- card grid ---------- */
/* Fixed at three across rather than auto-fill. Auto-fill fits as many 290px
   columns as the width allows, so a wide monitor quietly turned this into four
   and the last row was left short again. The page size is set to match three,
   so the two have to agree. */
.post-grid {
  display: grid; gap: 1.4rem;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 980px) { .post-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .post-grid { grid-template-columns: 1fr; } }
.post-card {
  background: #fff; border-radius: var(--r-lg); overflow: hidden;
  box-shadow: var(--shadow); height: 100%;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease);
}
.post-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.post-card__link { display: flex; flex-direction: column; height: 100%; text-decoration: none; }
.post-card__media { aspect-ratio: 16/9; background: var(--sky-50); position: relative; overflow: hidden; flex: none; }
.post-card__media img {
  /* Out of flow for the same reason as .post-feature__media: a squarer or
     taller upload would otherwise grow the box past 16:9. */
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.post-card__body { padding: 1.3rem 1.35rem 1.4rem; display: flex; flex-direction: column; flex: 1; }
.post-card__body h3 { font-size: 1.08rem; line-height: 1.35; margin: .55rem 0 .5rem; color: var(--ink); }
.post-card__body p {
  font-size: .92rem; color: var(--ink-2); margin: 0 0 1rem;
  /* Three lines keeps every card the same shape however long the summary. */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.post-card__cat {
  align-self: flex-start; font-size: .72rem; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase; color: var(--brand);
}
.post-card__meta {
  margin-top: auto; display: flex; align-items: center; justify-content: space-between;
  gap: .8rem; font-size: .84rem; color: var(--ink-3);
}
.post-card__more { display: inline-flex; align-items: center; gap: .35rem; color: var(--brand); font-weight: 700; }
.post-card__more svg { width: 15px; height: 15px; transition: transform .2s var(--ease); }
.post-card:hover .post-card__more svg,
.post-feature:hover .post-card__more svg { transform: translateX(4px); }

.pager { display: flex; align-items: center; justify-content: center; gap: .8rem; margin-top: 2.8rem; }

/* ---------- single post ---------- */
/* Article and sidebar in one grid. The main column is capped near 760px
   because reading speed peaks around 70 characters a line — the sidebar is
   what uses the width a wide screen has spare, not the prose. */
.post-layout {
  display: grid; gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: minmax(0, 760px) 330px;
  justify-content: space-between;
  align-items: start;
  padding-block: clamp(1.5rem, 4vw, 2.6rem) clamp(2rem, 5vw, 3.5rem);
}
.post-layout__main { min-width: 0; }

/* Sticky so it stays useful through a long guide. The offset clears the fixed
   header; the height cap lets a tall card scroll on a short screen instead of
   running off the bottom where it cannot be reached. */
.post-side {
  position: sticky; top: 96px;
  max-height: calc(100vh - 120px); overflow-y: auto;
}
.post-side::-webkit-scrollbar { width: 6px; }
.post-side::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }

.side-card {
  background: var(--sky-50); border-radius: var(--r-lg);
  padding: 1.4rem 1.3rem;
}
.side-card__title {
  margin: 0 0 1rem; font-size: 1.05rem; font-weight: 800;
  letter-spacing: -.01em; color: var(--ink);
}
.side-card__all { margin-top: 1.1rem; }

.side-posts { list-style: none; margin: 0; padding: 0; display: grid; gap: .9rem; }
.side-posts li + li { border-top: 1px solid var(--line); padding-top: .9rem; }

.side-post { display: flex; gap: .8rem; align-items: flex-start; color: inherit; }
.side-post__media {
  flex: none; width: 68px; height: 68px; border-radius: 10px;
  overflow: hidden; background: #fff;
}
.side-post__media img { width: 100%; height: 100%; object-fit: cover; }
.side-post__text { min-width: 0; }
.side-post__title {
  display: block; font-weight: 700; font-size: .92rem; line-height: 1.35;
  color: var(--ink); letter-spacing: -.008em;
}
.side-post:hover .side-post__title { color: var(--brand); }
.side-post__date { display: block; margin-top: .3rem; font-size: .78rem; color: var(--ink-3); }

/* Below this the sidebar has nowhere useful to sit, so it drops under the
   article and stops being sticky. */
@media (max-width: 1040px) {
  .post-layout { grid-template-columns: minmax(0, 1fr); }
  .post-side { position: static; max-height: none; overflow: visible; }
  .side-card { max-width: 640px; }
}

.post__head { padding: 0 0 1.4rem; }
.post__head h1 {
  font-size: clamp(1.9rem, 4.4vw, 3rem); line-height: 1.14;
  letter-spacing: -.02em; margin: .8rem 0 .7rem;
}
.post__standfirst { font-size: clamp(1.05rem, 2vw, 1.2rem); color: var(--ink-2); margin: 0 0 1rem; }
.post__meta { display: flex; flex-wrap: wrap; gap: .5rem; font-size: .88rem; color: var(--ink-3); }

.post__cover { margin: 0 0 2.2rem; border-radius: var(--r-xl); overflow: hidden; box-shadow: var(--shadow-lg); }
.post__cover img { width: 100%; height: auto; display: block; }

/* Long-form measure: around 70 characters a line, which is where reading speed
   peaks — wider and the eye loses its place returning to the next line. */
.post__body { font-size: 1.05rem; line-height: 1.72; color: var(--ink-2); }

/* Spacing follows the source. A blank line in the editor puts space above the
   next block; two lines typed one under the other stay welded, which is what
   "wash clothes when they:" followed by its ticks needs to look right. */
.post__body > * + *        { margin-top: 1.15rem; }
.post__body > .is-tight    { margin-top: 0; }

/* Section titles carry the page. They are set heavier and tighter than the
   body headings elsewhere on the site, because in a long article the heading
   is the thing a scanning reader is looking for. */
.post__body h2 {
  font-family: var(--font-display); font-weight: 800; color: var(--ink);
  font-size: clamp(1.75rem, 3.6vw, 2.35rem); line-height: 1.14;
  letter-spacing: -.028em; margin: 2.1rem 0 0; text-wrap: balance;
}
.post__body h3 {
  font-family: var(--font-display); font-weight: 800; color: var(--ink);
  font-size: clamp(1.2rem, 2.1vw, 1.45rem); line-height: 1.25;
  letter-spacing: -.018em; margin: 1.7rem 0 0;
}
.post__body h4 {
  font-family: var(--font-display); font-weight: 700; color: var(--ink);
  font-size: 1.06rem; line-height: 1.35; letter-spacing: -.01em; margin: 1.4rem 0 0;
}
.post__body h2:first-child,
.post__body h3:first-child { margin-top: 0; }
/* A rule already supplies the gap above the title that follows it. */
.post__body hr + h2 { margin-top: .9rem; }
.post__body hr + h3 { margin-top: .8rem; }
.post__body h2 + *  { margin-top: .85rem; }
.post__body h3 + *  { margin-top: .65rem; }
.post__body h4 + *  { margin-top: .5rem; }

/* A section divider sits on plain white, so it needs a darker line than
   --line, which is tuned for card edges against a tinted background and
   effectively disappears here. */
.post__body hr {
  border: 0; border-top: 1px solid #C3CEDB;
  margin: 2.3rem 0 0; height: 0;
}

.post__body p { margin-bottom: 0; }
.post__body ul, .post__body ol { padding-left: 1.35rem; margin-bottom: 0; }
.post__body li + li { margin-top: .3rem; }
.post__body li { padding-left: .2rem; }
.post__body li::marker { color: var(--ink-3); }
.post__body ol > li::marker { color: var(--brand); font-weight: 700; }
.post__body li > ul, .post__body li > ol { margin-top: .3rem; }

/* Tick lines carry their own marker, so the list drops the bullet it would
   otherwise add — a dot in front of a tick reads as two markers. The rows sit
   tighter than a bullet list because a tick list is scanned, not read. */
.post__body .post__checks { list-style: none; padding-left: 0; }
.post__body .post__checks li {
  padding-left: 0; display: flex; align-items: baseline;
}
.post__body .post__checks li + li { margin-top: .12rem; }
/* A right margin rather than a flex gap: gap on a flex row is the newer of the
   two and this needs to hold up in whatever browser the shop is on. */
.post__body .post__checks .tick {
  flex: none; margin-right: .55rem; color: var(--brand); font-weight: 700;
}

.post__body a { color: var(--brand); text-decoration: underline; text-underline-offset: 3px;
                text-decoration-thickness: 1px; overflow-wrap: anywhere; }
.post__body a:hover { color: var(--brand-700); }

.post__body blockquote {
  margin: 1.5rem 0 0; padding: .1rem 0 .1rem 1.15rem;
  border-left: 3px solid var(--brand); color: var(--ink);
  font-size: 1.08rem;
}
.post__body blockquote p { margin: 0; }
.post__body blockquote.is-tight { margin-top: .4rem; }

.post__body strong { color: var(--ink); font-weight: 700; }
.post__body em { font-style: italic; }
.post__body del { color: var(--ink-3); }
.post__body code {
  font-family: var(--font-mono); font-size: .88em;
  background: var(--sky-50); padding: .12rem .34rem; border-radius: 5px; color: var(--ink);
}

.post__figure { margin: 1.6rem 0 0; }
.post__figure img { width: 100%; height: auto; border-radius: var(--r); }
.post__figure figcaption { margin-top: .5rem; font-size: .85rem; color: var(--ink-3); }

.post__tablewrap { margin-top: 1.4rem; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.post__tablewrap table { width: 100%; border-collapse: collapse; font-size: .96rem; }
.post__tablewrap th, .post__tablewrap td {
  text-align: left; padding: .6rem .8rem; border-bottom: 1px solid var(--line);
}
.post__tablewrap th { font-weight: 800; color: var(--ink); background: var(--sky-50); white-space: nowrap; }

/* Anchored headings should not land under the sticky header. */
.post__body :is(h2, h3, h4)[id] { scroll-margin-top: 96px; }

.post__cta {
  margin: 2.8rem 0 3.2rem; padding: clamp(1.5rem, 3vw, 2.2rem);
  border-radius: var(--r-xl); background: var(--sky-50);
  display: flex; flex-wrap: wrap; align-items: center; gap: .7rem;
}
.post__cta h2 { flex: 1 1 100%; margin: 0; font-size: 1.25rem; }
.post__cta p  { flex: 1 1 100%; margin: 0 0 .5rem; color: var(--ink-2); }

@media (max-width: 820px) {
  .post-feature { grid-template-columns: 1fr; }
  .post-feature__media { aspect-ratio: 16/9; }
}
@media (max-width: 560px) {
  .pager .btn { flex: 1 1 auto; justify-content: center; }
  .post__cta .btn { width: 100%; justify-content: center; }
}

/* Public-side empty state — the admin stylesheet has one, but this is a
   visitor-facing page and cannot borrow it. */
.blog-empty { text-align: center; padding: clamp(2.5rem, 6vw, 4rem) 1rem; }
.blog-empty h3 { margin: 0 0 .5rem; font-size: 1.25rem; }
.blog-empty p { margin: 0; color: var(--ink-3); }
.blog-next__title { margin: 0 0 1.4rem; font-size: clamp(1.3rem, 2.6vw, 1.7rem); }

/* Small screens: the big section titles need a touch less air. */
@media (max-width: 560px) {
  .post__body { font-size: 1.02rem; }
  .post__body h2 { margin-top: 1.7rem; }
  .post__body hr { margin-top: 1.9rem; }
}

/* ---------- full-screen handoff loader ----------
   Shown while the booking is being saved and the card page is being opened.
   The browser keeps displaying the form until the gateway answers, which can
   take a couple of seconds, and a page that looks unchanged after a click
   reads as a click that did not register. This covers the gap.

   The logo carries it alone, with no wording: this is on screen for about a
   second, and a sentence nobody has time to read is just clutter. */
.lm-loader {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  background: #fff;
  opacity: 0; visibility: hidden;
  transition: opacity .25s ease, visibility .25s ease;
}
.lm-loader.is-on { opacity: 1; visibility: visible; }

.lm-loader__logo {
  width: 210px; max-width: 58vw; height: auto;
  animation: lm-breathe 3.2s cubic-bezier(.45, 0, .55, 1) infinite;
}

/* Slow and shallow on purpose. A brand mark that flashes reads as a page
   failing to load; this should only suggest that something is still working. */
@keyframes lm-breathe {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .82; transform: scale(.99); }
}

@media (prefers-reduced-motion: reduce) {
  .lm-loader__logo { animation: none; }
}

/* ---------- notice ----------
   A step up from .alert for messages that carry consequence. The icon gives it
   a shape people recognise before reading, the title answers "what happened",
   and the line under it answers "what now". Dismissable, because once it has
   been read it is only taking up the space the form needs. */
.notice {
  display: flex; align-items: flex-start; gap: .9rem;
  padding: 1rem 1.1rem; border-radius: var(--r, 14px);
  margin-bottom: 1rem; border: 1px solid transparent;
  max-height: 500px; overflow: hidden;

  /* Declared here, not on .is-going. A transition has to already be on the
     element when its values change, or the browser has nothing to interpolate
     from on the very first change. */
  transition: opacity .35s ease, transform .35s ease, max-height .35s ease,
              margin .35s ease, padding .35s ease, border-width .35s ease;

  /* "backwards", never "both". A filled animation keeps its last keyframe
     applied for good, and animations outrank normal declarations — so with
     "both" the to-frame's opacity:1 was quietly overriding .is-going and the
     fade never ran. "backwards" covers the entry and then gets out of the way. */
  animation: notice-in .4s cubic-bezier(.22, 1, .36, 1) backwards;
}

/* Slides down from under the header rather than fading in place: the movement
   is what catches the eye of someone who has just been redirected here and is
   not yet looking at this part of the page. */
@keyframes notice-in {
  from { opacity: 0; transform: translateY(-9px); }
  to   { opacity: 1; transform: translateY(0); }
}

.notice__icon {
  flex: none; width: 38px; height: 38px; border-radius: 11px;
  display: grid; place-items: center;
}
.notice__icon svg { width: 19px; height: 19px; }

.notice__body { flex: 1 1 auto; min-width: 0; }
.notice__title {
  display: block; font-size: .95rem; font-weight: 800;
  letter-spacing: -.01em; line-height: 1.35;
}
.notice__text {
  margin: .3rem 0 0; font-size: .89rem; line-height: 1.55; opacity: .85;
}

/* Leaving: collapses its own height so the form below rises to meet it
   instead of the page jumping. Border width is in the transition too — left
   out, it snaps from 1px to nothing and shows up as a small jolt at the end. */
.notice.is-going {
  opacity: 0; transform: translateY(-6px);
  max-height: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0;
  border-width: 0;
}

.notice--warn {
  background: var(--sun-50, #FFF8E8); border-color: var(--sun-100, #FDEBC4);
  color: #7A5300;
}
.notice--warn .notice__icon { background: var(--sun-100, #FDEBC4); color: #8A5A00; }

@media (max-width: 520px) {
  .notice { padding: .9rem; gap: .7rem; }
  .notice__icon { width: 32px; height: 32px; border-radius: 9px; }
  .notice__icon svg { width: 16px; height: 16px; }
}


/* ---------- booking: Confirm button sized to its label, not the card ---------- */
.wiz-submit { display: flex; justify-content: center; margin-top: 1.5rem; }
.wiz-submit .btn { min-width: 260px; padding: .95rem 2.4rem; justify-content: center; }
@media (max-width: 520px) {
  .wiz-submit .btn { width: 100%; min-width: 0; }   /* a full-width target is easier on a phone */
}

/* ---------- public pages: messages as a neat centred notice ---------- */
.flash-wrap { padding-top: 1.4rem; display: grid; justify-items: center; }
.flash-wrap .alert {
  display: inline-flex; align-items: center; gap: .65rem; width: auto; max-width: 680px;
  padding: .75rem 1.25rem .75rem .8rem; border-radius: 999px; margin-bottom: 0;
  box-shadow: var(--shadow-sm); font-size: .9rem; line-height: 1.45;
}
.flash-wrap .alert::before {
  content: ''; flex: none; width: 24px; height: 24px; border-radius: 50%;
  background: currentColor no-repeat center / 14px;
}
.flash-wrap .alert--success { border: 1px solid #BDEBD9; }
.flash-wrap .alert--success::before {
  background-color: #0FA97F;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E");
}
.flash-wrap .alert--error { border: 1px solid #F5C2BC; }
.flash-wrap .alert--error::before {
  background-color: #D4463A;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M12 7v6M12 17h.01'/%3E%3C/svg%3E");
}
.flash-wrap .alert--info::before, .flash-wrap .alert--warning::before {
  background-color: currentColor;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M12 11v6M12 7h.01'/%3E%3C/svg%3E");
}
.flash-wrap .alert.is-hiding { margin-bottom: 0; }
@media (max-width: 520px) {
  .flash-wrap .alert { border-radius: 16px; }
}

/* the page right under a notice does not need its full top spacing */
.flash-wrap + .section { padding-top: clamp(1.6rem, 3vw, 2.4rem); }

/* Policy pages (refund, privacy, delivery, terms): justified body text.
   Whole words only, never split across lines with a hyphen. */
.legal p,
.legal li {
  text-align: justify;
  text-justify: inter-word;
  hyphens: none;
  -webkit-hyphens: none;
  word-break: normal;
  overflow-wrap: normal;
}

/* ==========================================================================
   Address step, organised layout (2026-10)
   1 Find your address: search bar with Locate me, map, "Collect from" card
   2 Address details: type + unit side by side
   ========================================================================== */
.addr-sec + .addr-sec { margin-top: 1.6rem; padding-top: 1.5rem; border-top: 1px dashed var(--line); }
.addr-sec__head { display: flex; align-items: center; gap: .6rem; margin-bottom: .9rem; font-size: .95rem; font-weight: 800; color: var(--ink); }
.addr-sec__num { width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center; flex: none; background: var(--brand); color: #fff; font-size: .8rem; font-weight: 800; box-shadow: var(--shadow-brand); }

/* search bar: icon, input, clear, Locate me, all in one rounded field */
.addr-wrap { position: relative; }
.addr-bar {
  position: relative; display: flex; align-items: center; gap: .35rem;
  padding: .3rem .35rem .3rem .95rem; border: 2px solid var(--line); border-radius: 16px; background: #fff;
  transition: border-color .16s, box-shadow .16s;
}
.addr-bar:focus-within { border-color: var(--brand); box-shadow: 0 0 0 4px rgba(10,87,162,.1); }
.addr-bar__ico { flex: none; display: grid; color: var(--ink-3); }
.addr-bar__ico svg { width: 18px; height: 18px; }
.addr-bar__input {
  flex: 1; min-width: 0; border: 0; outline: 0; background: transparent;
  padding: .62rem .2rem; font: inherit; font-size: .95rem; color: var(--ink);
  text-overflow: ellipsis;
}
.addr-bar__input::placeholder { color: #A9B6C6; }
.addr-bar__input::-webkit-search-cancel-button { -webkit-appearance: none; display: none; }
.addr-bar .addr-clear { position: static; flex: none; width: 30px; height: 30px; }
.addr-bar .addr-locate {
  flex: none; display: inline-flex; align-items: center; gap: .4rem; margin: 0;
  padding: .55rem .85rem; border: 0; border-radius: 12px;
  background: var(--sky-50); color: var(--brand); font: inherit; font-size: .84rem; font-weight: 700; cursor: pointer;
  transition: background .16s, color .16s;
}
.addr-bar .addr-locate:hover { background: var(--sky-100); color: var(--brand-700); }
.addr-bar .addr-locate svg { width: 16px; height: 16px; }
.addr-bar .addr-locate:disabled { opacity: .6; cursor: wait; }
.addr-bar .addr-results { top: calc(100% + 6px); left: -2px; right: -2px; }

/* status on the left, manual entry on the right, one tidy line */
.addr-meta { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-top: .5rem; min-height: 1.3em; }
.addr-meta .addr-status { margin: 0; flex: 1; min-width: 0; line-height: 1.45; }
.addr-meta .addr-manual { margin: 0; flex: none; font-size: .8rem; color: var(--ink-3); text-decoration-color: var(--line); }
.addr-meta .addr-manual:hover { color: var(--brand); }

/* map */
.addr-map-field { margin-top: .9rem; }
.addr-map-field[hidden] { display: none; }
.addr-map-wrap { border-radius: 18px; border: 1px solid var(--line); box-shadow: var(--shadow-sm); }
.addr-map { height: 360px; }
.addr-map-wrap .addr-map-tip {
  left: 50%; right: auto; top: auto; bottom: 2.1rem; transform: translateX(-50%);
  width: max-content; max-width: calc(100% - 7rem);
  padding: .5rem .85rem; border-radius: 999px; font-size: .78rem;
  background: rgba(11,37,69,.86); box-shadow: 0 6px 16px rgba(11,37,69,.2);
  transition: opacity .2s;
}
.addr-map-wrap .addr-map-tip svg { width: 15px; height: 15px; }
.addr-map-wrap.is-moving .addr-map-tip { opacity: 0; }

/* "Collect from" card */
.addr-picked {
  display: flex; align-items: center; gap: .85rem; margin-top: .9rem;
  padding: .9rem 1rem; border-radius: 16px; border: 1.5px solid var(--sky-100);
  background: linear-gradient(120deg, var(--sky-50), #fff 70%);
}
.addr-picked[hidden] { display: none; }
.addr-picked__ico { flex: none; width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; background: var(--brand); color: #fff; box-shadow: var(--shadow-brand); }
.addr-picked__ico svg { width: 20px; height: 20px; }
.addr-picked__text { flex: 1; min-width: 0; display: grid; gap: .1rem; }
.addr-picked__k { font-size: .68rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--brand); }
.addr-picked__text strong { font-size: .95rem; color: var(--ink); line-height: 1.35; overflow-wrap: anywhere; }
.addr-picked__text small { font-size: .82rem; color: var(--ink-2); line-height: 1.45; }
.addr-picked__edit {
  flex: none; padding: .45rem .85rem; border-radius: 999px; border: 1px solid var(--line); background: #fff;
  font: inherit; font-size: .8rem; font-weight: 700; color: var(--ink-2); cursor: pointer;
}
.addr-picked__edit:hover { border-color: var(--brand); color: var(--brand); }

/* details: type and unit side by side */
#addrDetails[hidden] { display: none; }
.addr-details-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1rem; align-items: start; }
.addr-details-grid .field { margin: 0; }
#addrDetails .addr-details-grid .field { margin-top: 0; }
.addr-type-group { gap: .45rem; }
.addr-type-opt { flex-direction: row; justify-content: center; gap: .4rem; padding: .78rem .4rem; border-radius: 14px; font-size: .84rem; }
.addr-type-opt svg { width: 17px; height: 17px; }

@media (max-width: 640px) {
  .addr-bar { padding-left: .75rem; }
  .addr-bar .addr-locate { padding: .55rem .6rem; }
  .addr-bar .addr-locate span { display: none; }
  .addr-map { height: 280px; }
  .addr-map-wrap .addr-map-tip { max-width: calc(100% - 5.5rem); font-size: .72rem; white-space: normal; text-align: left; }
  .addr-details-grid { grid-template-columns: 1fr; }
  .addr-meta { flex-direction: column; gap: .35rem; }
  .addr-picked { position: relative; align-items: flex-start; padding: .8rem .85rem; }
  .addr-picked__ico { width: 36px; height: 36px; }
  .addr-picked__k { min-height: 26px; display: flex; align-items: center; }
  .addr-picked__edit { position: absolute; top: .7rem; right: .7rem; padding: .3rem .7rem; font-size: .76rem; }
}

.req-mark { color: #D14343; font-weight: 800; }


/* ==========================================================================
   Sign in / Create account on phones: a white card floating on the night-blue
   background, with a close button to go back to the website.
   ========================================================================== */
.auth__close { display: none; }
@media (max-width: 900px) {
  .auth {
    background:
      radial-gradient(70% 42% at 50% 0%, rgba(44,131,219,.42), transparent 70%),
      radial-gradient(60% 30% at 50% 100%, rgba(127,231,245,.10), transparent 70%),
      #04111F;
  }
  .auth__main { min-height: 100dvh; padding: 28px 16px calc(28px + env(safe-area-inset-bottom, 0px)); place-items: center; }
  .auth__form {
    position: relative; max-width: 400px;
    padding: 40px 24px 26px; border-radius: 22px; background: #fff;
    box-shadow: 0 40px 80px -30px rgba(0,0,0,.65), 0 0 0 1px rgba(255,255,255,.04);
  }
  .auth__close {
    position: absolute; top: 14px; right: 14px; z-index: 1;
    display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
    border: 1px solid var(--line); background: #fff; color: var(--ink-3);
    transition: color .3s, border-color .3s, background .3s, transform .45s cubic-bezier(.22,.8,.2,1);
  }
  .auth__close svg { width: 16px; height: 16px; }
  .auth__close:hover, .auth__close:focus-visible {
    color: var(--brand); border-color: var(--brand); background: var(--sky-50); transform: rotate(90deg); outline: none;
  }
  .auth__logo { height: 84px; width: auto; margin: -4px auto 14px; }
  .auth__form h1 { font-size: 1.55rem; margin-bottom: .3em; }
  .auth__form .lead {
    margin: 0 0 24px; font-size: .72rem; font-weight: 600;
    letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3);
  }
  .auth__form .field { margin-bottom: 14px; }
  .auth__form .field label { font-size: .84rem; margin-bottom: 6px; }
  .auth__form .input {
    height: 48px; padding: 0 14px; border: 1.5px solid var(--line); border-radius: 12px;
    background: #fff; font-size: .95rem;
  }
  .auth__form .input:focus { border-color: var(--brand); box-shadow: 0 0 0 4px rgba(10,87,162,.12); }
  .auth__form .btn--block { height: 50px; margin-top: 8px; border-radius: 12px; }
  .auth__form .hint.center { font-size: .84rem; }
  .auth__back { display: none; }
}
