/* ===================================================================
   BONE VOYAGE — design system (cartoon)

   The hues still come from the studio photography (the source colours are
   in assets/img/manifest.json) — chocolate coat, Brisbane river, sage hedge,
   sunset cream — but saturated and brightened until they read as cartoon
   rather than editorial.

   The look is sticker-book: a heavy ink outline on everything, a hard
   offset shadow with no blur, wonky rotations, and motion that overshoots.
   =================================================================== */

/* ---------- 1. Tokens ---------------------------------------------- */
:root {
  /* A painted palette: gouache tones on warm paper. Nothing is pure black
     and nothing is fully saturated -- the look depends on every colour
     having some earth in it. */
  --paper:     #faf3e6;   /* the ground everything sits on      */
  --paper-up:  #fffdf8;   /* raised cards, a shade lighter      */
  --paper-dn:  #f1e5d1;   /* sunken wells                       */
  --umber:     #473627;   /* the darkest tone, a warm brown     */

  --terra:     #c87a56;
  --rust:      #b4503f;
  --mustard:   #dfa94f;
  --sage:      #93a37d;
  --dusty:     #93aabd;
  --clay:      #c08a74;
  --plum:      #a07f96;
  --bone:      #ffffff;

  /* Semantic roles (light) */
  --bg:          var(--paper);
  --bg-raised:   var(--paper-up);
  --bg-sunken:   var(--paper-dn);
  --ink:         var(--umber);
  --ink-soft:    #6a5540;
  /* Measured, not picked by eye: at #8a7560 this was 3.97:1 on the page
     ground, which fails AA for the small text it is used on (form hints,
     rate-row captions, the footer). #75634c clears 4.5:1 on all three
     grounds, the sunken wells included. */
  --ink-faint:   #75634c;
  --line:        #e3d6c0;
  --halo:        rgba(200, 122, 86, .32);

  /* Per-page accent. --theme is the painted fill, --theme-deep a ground dark
     enough to carry white text, --theme-ink a foreground legible on paper. */
  --theme:       var(--terra);
  --theme-soft:  #f5e5d9;
  --theme-deep:  #8a4b2e;
  --theme-ink:   #8a4b2e;

  /* Type. Lighter display weight than the sticker set used -- a painted
     page with 700-weight bubble headings still reads as a sticker book. */
  --font-display: "Fredoka", "Trebuchet MS", system-ui, sans-serif;
  --font-body:    "Nunito", ui-rounded, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono:    ui-monospace, "SF Mono", Menlo, monospace;

  /* Outlines are hairlines in a tonal colour now, not heavy ink. */
  --bw:    1.5px;
  --bw-lg: 2px;

  /* Shape stays soft and slightly irregular. */
  --r-sm: 12px;
  --r-md: 20px;
  --r-lg: 28px;
  --r-xl: 40px;
  --squircle: 42% 58% 55% 45% / 48% 44% 56% 52%;
  --blob:     58% 42% 38% 62% / 44% 58% 42% 56%;

  /* Motion settles rather than overshoots; paint does not boing. */
  --ease: cubic-bezier(.22, 1, .36, 1);
  --pop:  cubic-bezier(.33, 1.2, .5, 1);
  --boing: cubic-bezier(.3, 1.4, .45, 1);

  /* Soft shadows with blur, where the sticker set used hard offsets. */
  --shadow-sm: 0 2px 6px rgba(71, 54, 39, .07);
  --shadow-md: 0 7px 20px rgba(71, 54, 39, .10);
  --shadow-lg: 0 16px 40px rgba(71, 54, 39, .13);

  --page: 1240px;
  --gut:  clamp(1.15rem, 4vw, 3.5rem);
}

/* Dark mode. Three states: explicit dark, explicit light, and system default.
   The painted look goes to a dim lamplit room rather than to black: the
   grounds keep their brown, so the same gouache tones still sit on them. */
:root[data-theme="dark"],
:root:not([data-theme="light"]) {
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg:        #241c15;
    --bg-raised: #30261c;
    --bg-sunken: #1a140e;
    --ink:       #f3e7d4;
    --ink-soft:  #d7c5ab;
    --ink-faint: #b3a088;
    --line:      #4b3c2d;
    --halo:      rgba(200, 122, 86, .4);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg:        #241c15;
  --bg-raised: #30261c;
  --bg-sunken: #1a140e;
  --ink:       #f3e7d4;
  --ink-soft:  #d7c5ab;
  --ink-faint: #b3a088;
  --line:      #4b3c2d;
  --halo:      rgba(200, 122, 86, .4);
}

/* Mini-site themes. Each service page sets one of these on <body>. */
body.t-ember  { --theme: #c87a56; --theme-soft: #f5e5d9; --theme-deep: #8a4b2e; --theme-ink: #8a4b2e; --theme-lift: #dd9170; }
body.t-river  { --theme: #93aabd; --theme-soft: #e3edf3; --theme-deep: #3f6279; --theme-ink: #3f6279; --theme-lift: #a8bccd; }
body.t-sage   { --theme: #93a37d; --theme-soft: #e8ecdf; --theme-deep: #4e6039; --theme-ink: #4e6039; --theme-lift: #a9b793; }
body.t-lemon  { --theme: #dfa94f; --theme-soft: #faeed6; --theme-deep: #845d18; --theme-ink: #845d18; --theme-lift: #e8bc71; }
body.t-cocoa  { --theme: #c08a74; --theme-soft: #f3e6df; --theme-deep: #7d4a36; --theme-ink: #7d4a36; --theme-lift: #d4a28d; }
body.t-bubble { --theme: #a07f96; --theme-soft: #efe6ec; --theme-deep: #65435c; --theme-ink: #65435c; --theme-lift: #bb98b0; }

/* Kept so an older page class still themes rather than falling back to terra. */
body.t-apricot { --theme: #dfa94f; --theme-soft: #faeed6; --theme-deep: #845d18; --theme-ink: #845d18; --theme-lift: #e8bc71; }
body.t-plum    { --theme: #a07f96; --theme-soft: #efe6ec; --theme-deep: #65435c; --theme-ink: #65435c; --theme-lift: #bb98b0; }

/* On a dark ground the soft washes go muddy and the deep variants vanish, so
   the wash darkens and the painted tone itself becomes the legible ink. */
:root[data-theme="dark"] body[class*="t-"] { --theme-soft: #33261c; --theme-ink: var(--theme-lift, var(--theme)); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body[class*="t-"] { --theme-soft: #33261c; --theme-ink: var(--theme-lift, var(--theme)); }
}

/* ---------- 2. Reset + base ---------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: var(--font-body);
  font-size: clamp(1.02rem, .98rem + .2vw, 1.1rem);
  font-weight: 500;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Halftone dots — comic print rather than letterpress grain. A negative
   z-index keeps the layer above the page background but strictly behind every
   in-flow element, so it can never sit over text and cut contrast. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .5;
  /* Paper tooth. An inline turbulence filter rather than a tiled bitmap:
     it costs a few hundred bytes and never shows a repeat seam. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.22'/%3E%3C/svg%3E");
  mix-blend-mode: multiply;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body::before { opacity: .22; }
}
:root[data-theme="dark"] body::before { opacity: .22; }

img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: .98;
  letter-spacing: -.01em;
  text-wrap: balance;
}

h1 { font-size: clamp(2.6rem, 1.5rem + 5.4vw, 6.5rem); }
h2 { font-size: clamp(2rem, 1.3rem + 3.1vw, 3.9rem); }
h3 { font-size: clamp(1.25rem, 1.05rem + .9vw, 1.75rem); }

p { text-wrap: pretty; }
a { color: inherit; }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--bw-lg) solid var(--line);
  outline-offset: 3px;
  border-radius: 8px;
}

.skip-link {
  position: absolute;
  left: 50%;
  top: -100px;
  transform: translateX(-50%);
  z-index: 999;
  background: var(--ink);
  color: var(--bg);
  padding: .8rem 1.4rem;
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  font-weight: 800;
  text-decoration: none;
  transition: top .2s var(--ease);
}
.skip-link:focus { top: 0; }

.wrap { width: min(100% - (var(--gut) * 2), var(--page)); margin-inline: auto; }
.wrap-wide { width: min(100% - (var(--gut) * 2), 1500px); margin-inline: auto; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

section { padding-block: clamp(3.5rem, 8vw, 8rem); }


/* ---------- 3. Header / nav ---------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 90;
  padding: .8rem var(--gut);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(14px) saturate(1.5);
  -webkit-backdrop-filter: blur(14px) saturate(1.5);
  border-bottom: var(--bw) solid transparent;
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
.site-header.is-stuck { border-bottom-color: var(--ink); }

.logo {
  display: inline-flex;
  align-items: baseline;
  gap: .5ch;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: -.01em;
  text-decoration: none;
  color: var(--ink);
  white-space: nowrap;
}
.logo .mark {
  display: inline-block;
  color: var(--theme-ink);
  transform: rotate(-3deg);
  transition: transform .4s var(--boing);
}
.logo:hover .mark { transform: rotate(5deg) scale(1.08); }

/* Desktop nav — a floating pill */
nav#nav {
  display: flex;
  align-items: center;
  gap: .15rem;
  padding: .3rem;
  background: var(--bg-raised);
  border: var(--bw) solid var(--line);
  border-radius: 999px;
  box-shadow: var(--shadow-sm);
}
nav#nav a {
  padding: .55rem 1rem;
  border-radius: 999px;
  font-size: .9rem;
  font-weight: 700;
  text-decoration: none;
  color: var(--ink-soft);
  white-space: nowrap;
  transition: color .2s var(--ease), background .2s var(--ease);
}
nav#nav a:hover { color: var(--ink); background: var(--theme-soft); }
nav#nav a[aria-current="page"] { color: var(--ink); background: var(--theme-soft); }
nav#nav a.nav-cta {
  /* The deep tone, not the bright fill: nothing legible clears 4.5:1 on the
     bright one -- white reaches 3.29 and the umber 3.49. */
  background: var(--theme-deep);
  color: #fff;
  font-weight: 800;
  padding-inline: 1.25rem;
  border: var(--bw) solid var(--line);
}
nav#nav a.nav-cta:hover { background: var(--ink); color: var(--bg); }

.header-tools { display: flex; align-items: center; gap: .5rem; }

.theme-toggle {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border: var(--bw) solid var(--line);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--ink);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform .3s var(--boing), background .2s var(--ease);
}
.theme-toggle:hover { transform: rotate(25deg) scale(1.1); background: var(--theme); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-moon { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .icon-sun  { display: none; }
}

/* Burger */
.menu-toggle {
  display: none;
  width: 44px; height: 44px;
  border: var(--bw) solid var(--line);
  border-radius: 999px;
  background: var(--bg-raised);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  padding: 0;
  place-items: center;
  gap: 4px;
  flex-direction: column;
}
.menu-toggle span {
  display: block;
  width: 18px; height: 3px;
  border-radius: 3px;
  background: var(--ink);
  transition: transform .32s var(--pop), opacity .2s linear;
}
.menu-toggle.active span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.menu-toggle.active span:nth-child(2) { opacity: 0; }
.menu-toggle.active span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 900px) {
  .menu-toggle { display: flex; }
  nav#nav {
    position: fixed;
    inset: 64px .75rem auto .75rem;
    flex-direction: column;
    align-items: stretch;
    gap: .2rem;
    padding: .6rem;
    border-radius: var(--r-lg);
    border-width: var(--bw);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-12px) scale(.97);
    transition: opacity .28s var(--ease), transform .28s var(--ease), visibility .28s;
  }
  nav#nav.active, nav#nav.open {
    opacity: 1;
    visibility: visible;
    transform: none;
  }
  nav#nav a { padding: .85rem 1rem; font-size: 1rem; text-align: center; }
}


/* ---------- 4. Buttons + pills ------------------------------------- */
.btn {
  --btn-bg: var(--theme);
  /* Fixed dark, not --ink: --ink flips to cream in dark mode while --theme
     stays bright, which would put cream text on a yellow button. */
  --btn-fg: var(--umber);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .9rem 1.7rem;
  border: var(--bw) solid var(--line);
  border-radius: 999px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font: inherit;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.02rem;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--shadow-md);
  transition: transform .18s var(--ease), box-shadow .18s var(--ease), background .2s var(--ease);
}
/* Lift on hover, then physically press into the page on click — the shadow
   shrinks by exactly the distance the button travels, so it reads as a real
   object being pushed down. */
.btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.btn:active { transform: translateY(1px); box-shadow: var(--shadow-sm); }

.btn-accent { --btn-bg: var(--theme-deep); --btn-fg: #fff; }
.btn-accent:hover { background: var(--theme-ink); }

.btn-ghost { --btn-bg: var(--bg-raised); --btn-fg: var(--ink); }
.btn-ghost:hover { background: var(--theme); }

.btn .arrow { transition: transform .35s var(--boing); }
.btn:hover .arrow { transform: translateX(5px); }

@media (prefers-reduced-motion: reduce) {
  .btn, .btn:hover, .btn:active { transform: none; }
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .4rem .95rem;
  border-radius: 999px;
  border: var(--bw) solid var(--line);
  background: var(--theme-soft);
  color: var(--theme-ink);
  font-family: var(--font-display);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  transform: rotate(-1.5deg);
}

.pill .dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
}
.pill.live .dot { animation: pulse 2s var(--ease) infinite; }
@keyframes pulse {
  0%, 100% { opacity: 1;  transform: scale(1); }
  50%      { opacity: .4; transform: scale(.75); }
}


/* ---------- 5. Hero ------------------------------------------------- */
.hero {
  position: relative;
  padding-block: clamp(2.5rem, 6vw, 5rem) clamp(3rem, 7vw, 6rem);
  overflow: hidden;
}

/* Soft colour wash behind the hero */
.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  width: 70vw; height: 70vw;
  max-width: 900px; max-height: 900px;
  top: -28%; right: -14%;
  border-radius: var(--blob);
  background: radial-gradient(circle at 35% 35%, var(--theme-soft), transparent 68%);
  filter: blur(24px);
  animation: drift 26s ease-in-out infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(0, 0, 0) rotate(0deg); }
  to   { transform: translate3d(-5%, 4%, 0) rotate(16deg); }
}

.hero-grid {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
@media (max-width: 940px) { .hero-grid { grid-template-columns: 1fr; } }

.hero h1 { margin-block: 1.1rem .9rem; }
/* Emphasis in any big heading: accent colour and a chunky underline, never
   italic — Fredoka has no italic, so the browser would synthesise a skew that
   reads as a rendering fault.

   The underline is text-decoration rather than an absolutely-positioned bar.
   A bar needs the em to be an inline-block to take a transform, which makes it
   an atomic box: on a heading that wraps ("A house, not a kennel.") the
   trailing full stop was orphaned onto its own line and the bar overshot the
   last word. text-decoration follows every line box on its own. */
.hero h1 em,
.page-hero h1 em {
  font-style: normal;
  color: var(--theme-ink);
  text-decoration: underline;
  text-decoration-thickness: .1em;
  text-underline-offset: .08em;
  text-decoration-skip-ink: none;
}

.hero-lede {
  font-size: clamp(1.05rem, 1rem + .45vw, 1.3rem);
  color: var(--ink-soft);
  max-width: 46ch;
  margin-bottom: 1.9rem;
}

.hero-actions { display: flex; flex-wrap: wrap; gap: .8rem; align-items: center; }

/* Photo stack — the signature shape */
.hero-media { position: relative; }
.hero-photo {
  border-radius: var(--squircle);
  overflow: hidden;
  border: var(--bw-lg) solid var(--line);
  box-shadow: var(--shadow-lg);
  aspect-ratio: 4 / 5;
  animation: morph 18s ease-in-out infinite;
}
.hero-photo img { width: 100%; height: 100%; object-fit: cover; }
@keyframes morph {
  0%, 100% { border-radius: 42% 58% 55% 45% / 48% 44% 56% 52%; }
  33%      { border-radius: 56% 44% 38% 62% / 42% 58% 42% 58%; }
  66%      { border-radius: 38% 62% 60% 40% / 58% 40% 60% 42%; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-photo { animation: none; border-radius: var(--r-xl); }
  .hero::before { animation: none; }
}

/* Floating stat sticker */
.sticker {
  position: absolute;
  display: grid;
  gap: .1rem;
  padding: .9rem 1.2rem;
  background: var(--mustard);
  color: var(--umber);
  border: var(--bw) solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  text-align: left;
  animation: bob 6s ease-in-out infinite;
}
.sticker b { font-family: var(--font-display); font-size: 1.7rem; line-height: 1; color: var(--umber); }
.sticker span { font-size: .74rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--umber); }
.sticker-tl { top: 4%;  left: -6%;  rotate: -8deg; }
.sticker-br { bottom: 6%; right: -4%; rotate: 7deg; animation-delay: -3s; background: var(--plum); }
@keyframes bob { 50% { translate: 0 -10px; } }
@media (prefers-reduced-motion: reduce) { .sticker { animation: none; } }
@media (max-width: 620px) {
  .sticker-tl { left: -2%; scale: .85; }
  .sticker-br { right: -2%; scale: .85; }
}


/* ---------- 6. Marquee ---------------------------------------------- */
.marquee {
  --speed: 34s;
  display: flex;
  overflow: hidden;
  gap: 0;
  padding-block: .85rem;
  background: var(--ink);
  color: var(--bg);
  border-block: var(--bw) solid var(--line);
  user-select: none;
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.marquee.marquee-accent .sep { color: var(--theme); opacity: 1; }
.marquee-track {
  display: flex;
  align-items: center;
  gap: 2.4rem;
  padding-right: 2.4rem;
  flex-shrink: 0;
  min-width: 100%;
  animation: slide var(--speed) linear infinite;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee-track > * {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, .95rem + .55vw, 1.6rem);
  font-weight: 700;
  letter-spacing: 0;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 2.4rem;
}
.marquee-track .sep { opacity: .5; }
@keyframes slide { to { transform: translateX(-100%); } }
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
  .marquee { overflow-x: auto; }
}


/* ---------- 7. Section headings ------------------------------------- */
.sec-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
  margin-bottom: clamp(1.8rem, 4vw, 3.2rem);
}
.sec-head h2 { max-width: 18ch; }
.sec-head p { color: var(--ink-soft); max-width: 40ch; }
.sec-head .pill { margin-bottom: .9rem; }


/* ---------- 8. Bento grid ------------------------------------------- */
.bento {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(.75rem, 1.5vw, 1.15rem);
}
@media (max-width: 900px) { .bento { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .bento { grid-template-columns: 1fr; } }

.cell {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .55rem;
  padding: clamp(1.3rem, 2.6vw, 2.1rem);
  background: var(--bg-raised);
  border: var(--bw) solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: transform .3s var(--boing), box-shadow .3s var(--ease);
}
.cell:hover { transform: translate(-3px, -3px) rotate(-.6deg); box-shadow: var(--shadow-md); }
/* Alternate the tilt so a grid of cells looks hand-placed, not stamped. */
.cell:nth-child(even):hover { transform: translate(-3px, -3px) rotate(.6deg); }

.cell-3 { grid-column: span 3; }
.cell-2 { grid-column: span 2; }
.cell-4 { grid-column: span 4; }
.cell-6 { grid-column: span 6; }
@media (max-width: 900px) {
  .cell-3, .cell-4, .cell-6 { grid-column: span 2; }
  .cell-2 { grid-column: span 1; }
}
@media (max-width: 560px) { .cell, .cell-2 { grid-column: 1 / -1; } }

.cell.is-accent { background: var(--theme-deep); color: #fff; border-color: var(--theme-deep); }
.cell.is-accent .cell-kicker, .cell.is-accent p { color: rgba(255, 255, 255, .92); }
.cell.is-ink { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.cell.is-ink p, .cell.is-ink .cell-kicker { color: color-mix(in srgb, var(--bg) 76%, transparent); }

.cell-kicker {
  font-family: var(--font-display);
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.cell p { color: var(--ink-soft); font-size: .965rem; }
.cell .price {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.8rem, 1.35rem + 1.7vw, 2.8rem);
  line-height: 1;
  letter-spacing: -.01em;
}
.cell .price small { font-size: .42em; font-weight: 500; color: var(--ink-faint); letter-spacing: 0; }
.cell.is-accent .price small { color: rgba(255, 255, 255, .8); }

/* Photo cells */
.cell-photo { padding: 0; min-height: 200px; }
.cell-photo img { width: 100%; height: 100%; object-fit: cover; }
.cell-photo figcaption {
  position: absolute;
  left: .8rem; bottom: .8rem;
  padding: .35rem .9rem;
  border-radius: 999px;
  border: var(--bw) solid var(--line);
  background: var(--mustard);
  color: var(--umber);
  font-family: var(--font-display);
  font-size: .78rem;
  font-weight: 700;
  transform: rotate(-2deg);
}

/* Big numeral watermark in a corner */
.cell .numeral {
  position: absolute;
  right: -.1em; bottom: -.34em;
  font-family: var(--font-display);
  font-size: 9rem;
  font-weight: 700;
  line-height: 1;
  color: var(--theme);
  opacity: .16;
  pointer-events: none;
}


/* ---------- 9. Services ---------------------------------------------- */
.services-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr));
  gap: clamp(.9rem, 2vw, 1.4rem);
}

.service-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 0;
  background: var(--bg-raised);
  border: var(--bw) solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: transform .35s var(--boing), box-shadow .35s var(--ease);
}
.service-card:hover { transform: translate(-4px, -5px) rotate(-1deg); box-shadow: var(--shadow-lg); }
.service-card:nth-child(even):hover { transform: translate(-4px, -5px) rotate(1deg); }
.service-card .card-img { aspect-ratio: 16 / 11; overflow: hidden; border-bottom: var(--bw) solid var(--line); }
.service-card .card-img img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .7s var(--ease);
}
.service-card:hover .card-img img { transform: scale(1.06); }
.service-card .card-body { padding: clamp(1.2rem, 2.4vw, 1.8rem); display: grid; gap: .5rem; }
.service-card .card-body p { color: var(--ink-soft); font-size: .95rem; }
.service-card .card-foot {
  margin-top: auto;
  padding: 0 clamp(1.2rem, 2.4vw, 1.8rem) clamp(1.2rem, 2.4vw, 1.8rem);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-weight: 600;
}
.service-card .from { color: var(--theme-ink); font-family: var(--font-display); font-weight: 700; font-size: 1.2rem; }
.service-card .go {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 999px;
  border: var(--bw) solid var(--line);
  background: var(--theme-soft);
  color: var(--theme-ink);
  transition: transform .35s var(--boing), background .25s var(--ease), color .25s var(--ease);
}
.service-card:hover .go { background: var(--theme-deep); color: #fff; transform: rotate(-45deg) scale(1.12); }


/* ---------- 10. Gallery ---------------------------------------------- */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: clamp(.6rem, 1.4vw, 1rem);
}
.gallery-item {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: var(--r-md);
  border: var(--bw) solid var(--line);
  background: var(--bg-sunken);
  box-shadow: var(--shadow-sm);
  transition: transform .4s var(--boing), border-radius .4s var(--ease), box-shadow .3s var(--ease);
}
/* A photo wall of identically-square tiles looks like a spreadsheet; nudging
   alternate tiles off-axis makes it read as pinned-up snapshots. */
.gallery-item:nth-child(3n)   { transform: rotate(-1.4deg); }
.gallery-item:nth-child(3n+1) { transform: rotate(1.1deg); }
.gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease); }

.gallery-masonry {
  columns: 4 240px;
  column-gap: clamp(.6rem, 1.4vw, 1rem);
}
.gallery-masonry .gallery-item {
  aspect-ratio: auto;
  break-inside: avoid;
  margin-bottom: clamp(.6rem, 1.4vw, 1rem);
  display: block;
}
.gallery-masonry .gallery-item img { height: auto; }
.gallery-item:hover { transform: scale(1.06) rotate(-2.5deg); border-radius: var(--r-lg); box-shadow: var(--shadow-md); z-index: 2; }
.gallery-item:hover img { transform: scale(1.08); }


/* ---------- 11. Testimonials ----------------------------------------- */
.testimonial-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(.9rem, 2vw, 1.4rem);
}
.quote {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: clamp(1.5rem, 3vw, 2.2rem);
  background: var(--bg-raised);
  border: var(--bw) solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  margin-bottom: 14px;
  transition: transform .35s var(--boing), box-shadow .3s var(--ease);
}
.quote:hover { transform: translate(-3px, -3px) rotate(-1deg); box-shadow: var(--shadow-md); }

/* Speech-bubble tail, drawn as two stacked triangles: the outer one is the
   ink outline, the inner one punches the card colour back through it. */
.quote::after,
.quote .tail {
  content: "";
  position: absolute;
  left: 2.4rem;
  bottom: calc(-1 * (14px + var(--bw)));
  width: 0; height: 0;
  border-left: 18px solid transparent;
  border-right: 10px solid transparent;
  border-top: calc(14px + var(--bw)) solid var(--line);
}
.quote .tail {
  bottom: -14px;
  border-left-width: 15px;
  border-right-width: 8px;
  border-top: 14px solid var(--bg-raised);
  z-index: 1;
}
.quote::before {
  content: "\201C";
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 5rem;
  line-height: .7;
  color: var(--theme);
  opacity: .5;
}
.quote blockquote { font-size: 1.03rem; color: var(--ink); }
.quote figcaption { display: flex; align-items: center; gap: .7rem; margin-top: auto; }
.quote .avatar {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: var(--bw) solid var(--line);
  background: var(--theme);
  color: var(--umber);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: .9rem;
  flex: none;
}
.quote .who { font-weight: 600; font-size: .92rem; }
.quote .where { color: var(--ink-faint); font-size: .82rem; }
.stars { color: var(--theme-ink); letter-spacing: .08em; font-size: 1rem; }


/* ---------- 12. Suburb cloud ----------------------------------------- */
.suburb-cloud { display: flex; flex-wrap: wrap; gap: .4rem; }
.suburb-cloud a, .suburb-cloud span {
  padding: .4rem .9rem;
  border: var(--bw) solid var(--line);
  border-radius: 999px;
  background: var(--bg-raised);
  font-size: .85rem;
  font-weight: 700;
  color: var(--ink-soft);
  text-decoration: none;
  transition: transform .25s var(--boing), background .2s var(--ease), color .2s var(--ease);
}
.suburb-cloud a:hover, .suburb-cloud span:hover {
  background: var(--theme);
  color: var(--umber);
  transform: translateY(-3px) rotate(-3deg) scale(1.05);
}


/* ---------- 13. Accordion / FAQ --------------------------------------- */
.faq { display: grid; gap: .6rem; }
.faq details {
  border: var(--bw) solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg-raised);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: box-shadow .25s var(--ease), background .25s var(--ease);
}
.faq details[open] { background: var(--theme-soft); box-shadow: var(--shadow-md); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.05rem 1.3rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  display: grid;
  place-items: center;
  width: 30px; height: 30px;
  border: var(--bw) solid var(--line);
  border-radius: 999px;
  background: var(--theme);
  color: var(--umber);
  font-family: var(--font-display);
  font-size: 1.3rem;
  line-height: 1;
  transition: transform .3s var(--boing);
  flex: none;
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq .answer { padding: 0 1.3rem 1.2rem; color: var(--ink-soft); }


/* ---------- 14. Rate table -------------------------------------------- */
.rate-block { display: grid; gap: .55rem; }
.rate-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1rem;
  align-items: baseline;
  padding: .95rem 1.2rem;
  background: var(--bg-raised);
  border: var(--bw) solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  transition: transform .25s var(--boing), box-shadow .25s var(--ease), background .2s var(--ease);
}
.rate-row:hover { transform: translate(-3px, -3px); box-shadow: var(--shadow-md); background: var(--theme-soft); }
.rate-row dt { font-weight: 600; }
.rate-row dt small { display: block; font-weight: 400; font-size: .85rem; color: var(--ink-faint); }
.rate-row dd {
  font-family: var(--font-display);
  font-size: 1.45rem;
  font-weight: 700;
  color: var(--theme-ink);
  white-space: nowrap;
}
.rate-row dd small { font-family: var(--font-body); font-size: .62rem; color: var(--ink-faint); }


/* ---------- 15. Steps ------------------------------------------------- */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: clamp(1rem, 2vw, 1.6rem); }
.step { position: relative; display: grid; gap: .5rem; padding-top: 3rem; }
.step .n {
  position: absolute;
  top: 0; left: 0;
  width: 48px; height: 48px;
  display: grid; place-items: center;
  border-radius: 999px;
  border: var(--bw) solid var(--line);
  background: var(--theme);
  color: var(--umber);
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  box-shadow: var(--shadow-sm);
  transform: rotate(-4deg);
}
.step p { color: var(--ink-soft); font-size: .95rem; }


/* ---------- 16. CTA band ---------------------------------------------- */
.cta-band {
  position: relative;
  padding: clamp(2.5rem, 6vw, 5rem);
  border-radius: var(--r-xl);
  border: var(--bw-lg) solid var(--line);
  background: var(--ink);
  color: var(--bg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  text-align: center;
  display: grid;
  gap: 1.2rem;
  justify-items: center;
}
.cta-band::before {
  content: "";
  position: absolute;
  inset: auto -10% -60% -10%;
  height: 120%;
  border-radius: var(--blob);
  background: radial-gradient(circle at 50% 20%, var(--theme), transparent 62%);
  opacity: .5;
}
.cta-band > * { position: relative; }
.cta-band p { color: color-mix(in srgb, var(--bg) 78%, transparent); max-width: 46ch; }
.cta-band .btn { --btn-bg: var(--bg-raised); --btn-fg: var(--ink); border-color: var(--line); }
.cta-band .btn:hover { background: var(--mustard); }
.cta-band .btn { box-shadow: 6px 6px 0 var(--bg); }
.cta-band .btn:hover { box-shadow: 9px 9px 0 var(--bg); }
.cta-band .btn:active { box-shadow: 1px 1px 0 var(--bg); }
.cta-band .pill { border-color: var(--bg); background: var(--bg); color: var(--umber); }
.cta-band .btn::after { background: var(--theme-deep); }


/* ---------- 17. Footer ------------------------------------------------- */
.site-footer {
  margin-top: clamp(3rem, 7vw, 6rem);
  padding: clamp(2.5rem, 5vw, 4rem) var(--gut) 2rem;
  background: var(--bg-sunken);
  border-top: var(--bw-lg) solid var(--line);
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: 2rem;
  margin-bottom: 2.5rem;
}
@media (max-width: 800px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .footer-grid { grid-template-columns: 1fr; } }
.footer-grid h4 {
  font-family: var(--font-display);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .9rem;
}
.footer-grid ul { list-style: none; display: grid; gap: .5rem; }
.footer-grid a { color: var(--ink-soft); text-decoration: none; font-size: .95rem; font-weight: 600; transition: color .2s var(--ease); }
.footer-grid a:hover { color: var(--theme-ink); }
.footer-blurb { color: var(--ink-soft); font-size: .93rem; max-width: 34ch; margin-top: .8rem; }
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  align-items: center;
  padding-top: 1.6rem;
  border-top: var(--bw) solid var(--line);
  font-size: .85rem;
  color: var(--ink-faint);
}
.footer-bottom a { color: var(--ink-faint); }


/* ---------- 18. Forms --------------------------------------------------- */
.form-container { display: grid; gap: 1.1rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
@media (max-width: 640px) { .form-row { grid-template-columns: 1fr; } }

.field { display: grid; gap: .45rem; }
.field label {
  font-family: var(--font-display);
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.field label .req { color: var(--theme); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: .9rem 1.05rem;
  font: inherit;
  font-size: .98rem;
  color: var(--ink);
  background: var(--bg-raised);
  border: var(--bw) solid var(--line);
  border-radius: var(--r-sm);
  transition: box-shadow .2s var(--ease);
}
.field textarea { min-height: 130px; resize: vertical; }
.field select { cursor: pointer; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' stroke='%239a8574' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.05rem center;
  padding-right: 2.6rem;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  box-shadow: var(--shadow-sm), 0 0 0 4px var(--halo);
}
.field .hint { font-size: .82rem; color: var(--ink-faint); }

.form-status {
  display: none;
  padding: 1.2rem 1.4rem;
  border-radius: var(--r-md);
  border: var(--bw) solid;
}
.form-status.success { border-color: #4b7d3f; background: #eaf4e6; color: #2c4d24; }
.form-status.error   { border-color: #b0402a; background: #fbe8e3; color: #7d2716; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .form-status.success { background: #1b2a17; color: #b5d8a9; }
  :root:not([data-theme="light"]) .form-status.error   { background: #2c1410; color: #f0b4a3; }
}
:root[data-theme="dark"] .form-status.success { background: #1b2a17; color: #b5d8a9; }
:root[data-theme="dark"] .form-status.error   { background: #2c1410; color: #f0b4a3; }

.submit-btn { justify-content: center; width: 100%; padding-block: 1.1rem; }


/* ---------- 19. Scroll reveal ------------------------------------------ */
/* Only hide the starting state when scripting is available to reveal it —
   otherwise a blocked or failed script would leave the page blank. */
.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
  transition-delay: var(--d, 0ms);
}
.js .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
}

/* Reading-progress bar */
.progress {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  width: 100%;
  transform: scaleX(var(--p, 0));
  transform-origin: left;
  background: var(--theme);
  z-index: 200;
  pointer-events: none;
}


/* ---------- 20. Misc ---------------------------------------------------- */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: .93rem;
  text-decoration: none;
  color: var(--ink-soft);
  transition: gap .25s var(--ease), color .2s var(--ease);
}
.back-link:hover { gap: .85rem; color: var(--theme-ink); }

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }
.split .media { border-radius: var(--r-xl); overflow: hidden; border: var(--bw-lg) solid var(--line); box-shadow: var(--shadow-md); }
.split .media img { width: 100%; aspect-ratio: 4/5; object-fit: cover; }
.split .media.wide img { aspect-ratio: 3/2; }

.prose { display: grid; gap: 1.05rem; }
.prose p { color: var(--ink-soft); }
.prose h2 + p, .prose h3 + p { margin-top: -.3rem; }

.tick-list { list-style: none; display: grid; gap: .7rem; }
.tick-list li { display: grid; grid-template-columns: 22px 1fr; gap: .7rem; align-items: start; color: var(--ink-soft); }
.tick-list li::before {
  content: "";
  width: 20px; height: 20px;
  margin-top: .18rem;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: var(--theme)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10'%3E%3Cpath d='M1 5l3.2 3.2L11 1.4' stroke='%2324130a' stroke-width='2.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    center / 11px no-repeat;
}

.note {
  padding: 1.1rem 1.3rem;
  border: var(--bw) solid var(--line);
  border-left-width: 10px;
  border-radius: var(--r-sm);
  background: var(--theme-soft);
  box-shadow: var(--shadow-sm);
  font-size: .95rem;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .note { color: var(--ink); }
}

.page-hero {
  padding-block: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 4vw, 3rem);
}
.page-hero > .wrap { display: grid; gap: 1.1rem; justify-items: start; }
.page-hero p { color: var(--ink-soft); font-size: clamp(1rem, .96rem + .35vw, 1.2rem); max-width: 55ch; }


/* ---------- 21. Re-skinned long-form pages ------------------------------
   Journal posts, terms, privacy and the intake form keep their original copy
   and land inside this wrapper, so the styling has to cover whatever markup
   those pages already used. */
.reskin {
  max-width: 760px;
  padding-block: clamp(2rem, 5vw, 3.5rem) clamp(3rem, 7vw, 5rem);
  display: block;
}
.reskin > * + * { margin-top: 1.1rem; }

.reskin h1 { font-size: clamp(2.1rem, 1.4rem + 3.2vw, 3.6rem); margin-top: 1.2rem; }
.reskin h2 { font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2.2rem); margin-top: 2.6rem; }
.reskin h3 { font-size: clamp(1.15rem, 1.05rem + .6vw, 1.45rem); margin-top: 1.9rem; }
.reskin h2 + p, .reskin h3 + p, .reskin h1 + p { margin-top: .7rem; }

.reskin p, .reskin li { color: var(--ink-soft); }
.reskin strong { color: var(--ink); }
.reskin a { color: var(--theme-ink); text-underline-offset: 3px; }

.reskin ul, .reskin ol { padding-left: 1.3rem; display: grid; gap: .5rem; }
.reskin li::marker { color: var(--theme); }

.reskin blockquote {
  margin-inline: 0;
  padding: 1.1rem 1.4rem;
  border-left: 3px solid var(--theme);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: var(--theme-soft);
  font-style: italic;
}
.reskin blockquote p { color: var(--ink); }

.reskin img { border-radius: var(--r-md); margin-block: 1.6rem; }
.reskin hr { border: 0; border-top: 1px solid var(--line); margin-block: 2.4rem; }

.reskin table {
  width: 100%;
  border-collapse: collapse;
  font-size: .94rem;
}
.reskin .table-scroll, .reskin table { display: block; overflow-x: auto; }
.reskin th, .reskin td {
  padding: .7rem .9rem;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
.reskin th { font-weight: 700; color: var(--ink); white-space: nowrap; }

/* The old pages carried their own utility classes; neutralise the ones that
   fought the new layout rather than trying to enumerate every variant. */
.reskin [class*="hero"],
.reskin [class*="container"],
.reskin [class*="content"],
.reskin [class*="wrapper"],
.reskin [class*="section"] {
  max-width: 100%;
  padding: 0;
  margin-inline: 0;
  background: none;
  text-align: left;
}

/* Forms inside re-skinned pages (the client intake form). */
.reskin label {
  display: block;
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: .4rem;
}
.reskin input, .reskin select, .reskin textarea {
  width: 100%;
  padding: .85rem 1rem;
  font: inherit;
  color: var(--ink);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.reskin input:focus, .reskin select:focus, .reskin textarea:focus {
  outline: none;
  border-color: var(--theme);
  box-shadow: 0 0 0 4px var(--halo);
}
.reskin button, .reskin input[type="submit"] {
  width: auto;
  padding: .95rem 1.7rem;
  border: 0;
  border-radius: 999px;
  background: var(--theme-deep);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
}


/* ---------- 22. Enquiry layout ------------------------------------------ */
.enquiry-split { align-items: start; gap: clamp(2rem, 4vw, 3.5rem); }
.enquiry-aside { display: grid; gap: 1rem; position: sticky; top: 90px; }
.enquiry-aside .cell-photo { min-height: 0; aspect-ratio: 4 / 3; }
.enquiry-aside .cell-photo img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 900px) {
  .enquiry-aside { position: static; }
}


/* ---------- 23. Photo credits -------------------------------------------
   Rendered only when a photo's licence asks for attribution. */
.photo-credits {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1.2rem;
  font-size: .84rem;
  color: var(--ink-faint);
}
.photo-credits a { color: var(--ink-soft); text-underline-offset: 3px; }
.photo-credits a:hover { color: var(--theme-ink); }


/* ---------- 24. Cartoon flourishes ---------------------------------------
   Decoration only: every rule here is aria-hidden or a background, so a
   screen reader never meets any of it. */

/* A scatter of paw prints behind a section. Two offset layers at different
   sizes so the repeat is not obvious. */
.pawed { position: relative; }
.pawed::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .5;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cg fill='%23ff5a2b' opacity='.45' transform='rotate(-18 60 60)'%3E%3Cellipse cx='60' cy='72' rx='15' ry='12'/%3E%3Cellipse cx='44' cy='54' rx='6' ry='8'/%3E%3Cellipse cx='56' cy='48' rx='6' ry='8.5'/%3E%3Cellipse cx='68' cy='49' rx='6' ry='8.5'/%3E%3Cellipse cx='79' cy='57' rx='6' ry='8'/%3E%3C/g%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='170' height='170' viewBox='0 0 120 120'%3E%3Cg fill='%232e9bc9' opacity='.3' transform='rotate(24 60 60)'%3E%3Cellipse cx='60' cy='72' rx='15' ry='12'/%3E%3Cellipse cx='44' cy='54' rx='6' ry='8'/%3E%3Cellipse cx='56' cy='48' rx='6' ry='8.5'/%3E%3Cellipse cx='68' cy='49' rx='6' ry='8.5'/%3E%3Cellipse cx='79' cy='57' rx='6' ry='8'/%3E%3C/g%3E%3C/svg%3E");
  background-position: 0 0, 70px 40px;
}

/* A bone rule, for breaking up long pages. */
.bone-rule {
  display: block;
  width: 100%;
  max-width: 220px;
  margin: clamp(1.6rem, 4vw, 2.6rem) auto;
  height: 26px;
  border: 0;
  background: center / contain no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='26' viewBox='0 0 220 26'%3E%3Cg fill='none' stroke='%2324130a' stroke-width='3' stroke-linejoin='round'%3E%3Cpath d='M26 6a7 7 0 1 0-6 7 7 7 0 1 0 6 7l168 0a7 7 0 1 0 6-7 7 7 0 1 0-6-7z' fill='%23ffc247'/%3E%3C/g%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .bone-rule { filter: invert(1) hue-rotate(180deg); }
}
:root[data-theme="dark"] .bone-rule { filter: invert(1) hue-rotate(180deg); }

/* A wobble for anything that should feel alive on hover. */
@keyframes wobble {
  0%, 100% { transform: rotate(0deg); }
  25%      { transform: rotate(-4deg); }
  75%      { transform: rotate(4deg); }
}
.wobble:hover { animation: wobble .5s var(--ease); }

/* Section headings get a chunky highlighter swipe behind the first word. */
.sec-head h2 mark,
.hero h1 mark {
  background: var(--theme);
  color: var(--umber);
  padding: 0 .18em;
  border-radius: 8px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

@media (prefers-reduced-motion: reduce) {
  .wobble:hover { animation: none; }
  .gallery-item, .gallery-item:hover,
  .cell:hover, .service-card:hover, .quote:hover, .rate-row:hover { transform: none; }
}


/* ---------- 25. Quote estimator ------------------------------------------
   The form and its output sit side by side on a wide screen and stack on a
   narrow one. Colour comes only from the theme tokens, so the block follows
   the page accent and both colour schemes without a second rule set: the
   total sits on --theme-deep, which is defined as a ground dark enough to
   carry white text. */
.estimator {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(1.2rem, 2.5vw, 2rem);
  align-items: start;
}
@media (max-width: 860px) {
  .estimator { grid-template-columns: 1fr; }
}

.estimator-form {
  display: grid;
  gap: 1rem;
  padding: clamp(1.2rem, 2.5vw, 1.8rem);
  background: var(--bg-raised);
  border: var(--bw-lg) solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
}
.estimator-form .form-row { gap: 1rem; align-items: start; }
/* A field with a hint is taller than one without, and a stretched grid item
   spreads that extra height across its own rows -- which drops the shorter
   field's control below its neighbour's. Pin the rows to the top instead. */
.estimator-form .field { align-content: start; }
.estimator-form .field.check label {
  display: flex;
  gap: .6rem;
  align-items: center;
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--font-body);
  font-size: .92rem;
  font-weight: 600;
  color: var(--ink);
}
.estimator-form .field.check input { width: auto; }
.estimator-form [hidden] { display: none; }
.estimator-form button { justify-self: start; }

.estimator-out {
  display: grid;
  gap: .8rem;
  align-content: start;
}
.estimator-empty {
  padding: clamp(1.2rem, 2.5vw, 1.8rem);
  background: var(--bg-sunken);
  border: var(--bw) dashed var(--ink);
  border-radius: var(--r-lg);
  font-size: .95rem;
  color: var(--ink-soft);
  display: grid;
  gap: .5rem;
}
.estimator-empty strong { color: var(--ink); }
/* The status line is for screen readers; the figure itself is right below it
   in the rendered estimate, so showing both would just say it twice. */
.estimator-status {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.estimate {
  display: grid;
  gap: .9rem;
  padding: clamp(1.2rem, 2.5vw, 1.8rem);
  background: var(--theme-soft);
  border: var(--bw-lg) solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
}
.estimate-top { display: grid; gap: .1rem; }
.estimate-kicker {
  font-family: var(--font-display);
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.estimate-total {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 2rem + 3vw, 3.4rem);
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
}
.estimate-sub { font-size: .92rem; color: var(--ink-soft); }

.estimate-lines { display: grid; gap: .4rem; }
.estimate-line {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: .8rem;
  align-items: baseline;
  padding: .6rem .85rem;
  background: var(--bg-raised);
  border: var(--bw) solid var(--line);
  border-radius: var(--r-sm);
  font-size: .94rem;
}
.estimate-line dt { font-weight: 700; }
.estimate-line dt small {
  display: block;
  font-weight: 400;
  font-size: .8rem;
  color: var(--ink-faint);
}
.estimate-line dd { font-family: var(--font-display); font-weight: 700; white-space: nowrap; }
.estimate-line.is-total {
  background: var(--theme-deep);
  color: var(--bone);
  border-color: var(--ink);
}
.estimate-line.is-total dd { font-size: 1.2rem; }

.estimate-chips-label {
  font-family: var(--font-display);
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.estimate-chips { display: flex; flex-wrap: wrap; gap: .4rem; list-style: none; }
.estimate-chips .chip {
  display: inline-flex;
  gap: .35rem;
  align-items: baseline;
  padding: .3rem .7rem;
  font-size: .82rem;
  font-weight: 700;
  background: var(--bg-raised);
  border: var(--bw) solid var(--line);
  border-radius: 999px;
}
.estimate-chips .chip small { font-weight: 400; color: var(--ink-faint); }
.estimate-chips .chip.is-peak { background: var(--theme); color: var(--umber); }
.estimate-chips .chip.is-peak small { color: var(--umber); }

.estimate-notes {
  display: grid;
  gap: .5rem;
  list-style: none;
  font-size: .88rem;
  color: var(--ink-soft);
}
.estimate-notes li {
  padding-left: 1.5rem;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='7' fill='none' stroke='%2324130a' stroke-width='2'/%3E%3Cpath d='M8 4.4v5M8 11.6v.4' stroke='%2324130a' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E")
    left .1rem / 15px no-repeat;
}

/* The estimate carried over to the enquiry page. */
.estimate-carry { display: grid; gap: .7rem; margin-bottom: 1.2rem; justify-items: start; }
.estimate-carry .estimate { width: 100%; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .estimate,
  :root:not([data-theme="light"]) .estimator-empty { color: var(--ink); }
  /* The note bullet is drawn in the light ink; redraw it in the dark one. */
  :root:not([data-theme="light"]) .estimate-notes li {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='7' fill='none' stroke='%23ffeccd' stroke-width='2'/%3E%3Cpath d='M8 4.4v5M8 11.6v.4' stroke='%23ffeccd' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  }
}
:root[data-theme="dark"] .estimate-notes li {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='7' fill='none' stroke='%23ffeccd' stroke-width='2'/%3E%3Cpath d='M8 4.4v5M8 11.6v.4' stroke='%23ffeccd' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}


/* ---------- 26. Cartoon dogs ---------------------------------------------
   Drawn in tools/dogs.py and inlined, so they are part of the document rather
   than five more image requests. They are stickers: fixed espresso outlines
   that do not flip with the colour scheme, same as the accent buttons.

   Everything here moves gently and stops entirely under reduced motion. A dog
   that jiggles forever is charming for about four seconds. */
.dog { display: block; width: 100%; height: auto; }

/* A dog peeking over the corner of a hero photo. */
.dog-peek {
  position: absolute;
  z-index: 3;
  width: clamp(92px, 13vw, 150px);
  bottom: -10px;
  left: -18px;
  filter: drop-shadow(0 6px 10px rgba(71, 54, 39, .16));
  animation: dog-bob 4.5s var(--ease) infinite;
  pointer-events: none;
}
.dog-peek-hero { bottom: -16px; left: -26px; }
@keyframes dog-bob {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50%      { transform: translateY(-9px) rotate(3deg); }
}

/* The ears swing a beat behind the body, which is most of the charm. */
.dog-ear   { transform-origin: 50% 20%; animation: ear-flop 4.5s var(--ease) infinite; }
.dog-ear-r { animation-delay: -.22s; }
@keyframes ear-flop {
  0%, 100% { transform: rotate(-4deg); }
  50%      { transform: rotate(5deg); }
}

.dog-tail { transform-origin: 0% 100%; animation: tail-wag .9s var(--boing) infinite; }
@keyframes tail-wag {
  0%, 100% { transform: rotate(-11deg); }
  50%      { transform: rotate(11deg); }
}

.dog-zzz { animation: zzz 3.4s var(--ease) infinite; }
@keyframes zzz {
  0%, 100% { opacity: .25; transform: translateY(3px); }
  50%      { opacity: 1;   transform: translateY(-3px); }
}

/* A ball tucked into the hero. */
.toy-ball {
  position: absolute;
  z-index: 3;
  width: clamp(38px, 5vw, 58px);
  top: 8%;
  right: -16px;
  animation: toy-roll 5.5s var(--ease) infinite;
  pointer-events: none;
}
@keyframes toy-roll {
  0%, 100% { transform: translateY(0) rotate(0); }
  50%      { transform: translateY(-14px) rotate(160deg); }
}

/* A dog badge in the corner of each service card's photo. */
/* .card-img clips its contents so the photo can zoom on hover, so the dog has
   to sit inside it rather than hang off the edge. */
.service-card .card-img { position: relative; }
.card-dog {
  position: absolute;
  right: 14px;
  bottom: 8px;
  width: 84px;
  z-index: 2;
  filter: drop-shadow(0 4px 8px rgba(71, 54, 39, .14));
  transition: transform .4s var(--boing);
}
.service-card:hover .card-dog,
.service-card:focus-visible .card-dog { transform: translateY(-8px) rotate(-7deg) scale(1.06); }

/* A dog sitting on top of the estimate. */
.estimator-dog {
  position: absolute;
  top: -58px;
  right: 6px;
  width: 92px;
  z-index: 2;
  filter: drop-shadow(0 4px 8px rgba(71, 54, 39, .14));
  animation: dog-bob 5s var(--ease) infinite;
  pointer-events: none;
}
.estimator { position: relative; }
@media (max-width: 860px) { .estimator-dog { display: none; } }

/* Paw prints wandering between sections. */
.paw-trail {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: clamp(1.2rem, 4vw, 3rem);
  padding: clamp(.6rem, 2vw, 1.4rem) 1rem;
  overflow: hidden;
}
.paw-step {
  width: clamp(20px, 2.6vw, 30px);
  opacity: .5;
  transform: rotate(calc(var(--i) * 9deg - 18deg)) translateY(calc(var(--i) * -5px));
  animation: paw-pad 3.6s var(--ease) infinite;
  animation-delay: calc(var(--i) * .22s);
}
.paw-step svg { display: block; width: 100%; height: auto; }
@keyframes paw-pad {
  0%, 70%, 100% { opacity: .32; }
  35%           { opacity: .9; }
}

/* A dog asleep at the foot of every page. */
.footer-dog {
  width: clamp(120px, 18vw, 190px);
  margin: 0 auto -8px;
  opacity: .92;
}
.footer-dog svg { display: block; width: 100%; height: auto; }

@media (prefers-reduced-motion: reduce) {
  .dog-peek, .dog-ear, .dog-tail, .dog-zzz, .toy-ball, .paw-step, .estimator-dog {
    animation: none;
  }
  .service-card:hover .card-dog { transform: none; }
}


/* The homepage hero is an illustration rather than a photograph, so the frame
   drops the photo-specific rules: no object-fit crop, and the drawing fills
   the squircle edge to edge. */
/* The frame is a fixed 4:5 box. The drawing is cut to the same ratio, so it
   fills the squircle rather than letterboxing inside it. */
.hero-illustration .dog-scene { display: block; width: 100%; height: 100%; }
