/* ============================================================
   Coverleo shared chrome stylesheet.
   Token system, base resets, animation primitives, nav, mega
   dropdown, contact modal, booking dialog, TBC placeholder, page
   transition, accessibility guard. Loaded by every page;
   page-specific component styles stay inline.
   ============================================================ */

/* ---- Token system (sage palette + hero-scoped vars) -------- */
:root {
  --hero-bg: #FAF7F1;
  --hero-text: #22211F;
  --hero-green: #243D34;
  --hero-green-hover: #1F342D;
  --hero-muted: #5F7467;
  --hero-sage-bg: #EEF2EA;
  --hero-border: #D8DED4;
  --hero-body: #56615B;
  --hero-micro: #747D76;
  --hero-card: #FFFFFB;

  /* Motion tokens (strong custom curves; weak built-ins lack the punch). */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --press-duration: 160ms;
  --dur-1: 150ms;
  --dur-2: 250ms;
  --dur-3: 350ms;

  /* Font tokens. Pages that have adopted the redesigned type system
     override these on <body>; pages not yet migrated keep the DM
     defaults below so nothing shifts until each page is propagated. */
  --font-display: 'DM Serif Display', Georgia, serif;
  --font-body: 'DM Sans', system-ui, sans-serif;
}

/* ---- Universal reset -------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* ---- Body base + paper-grain overlay ---------------------- */
body {
  font-family: var(--font-body);
  background-color: #F9F7F4;
  color: #262626;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body::after {
  content: '';
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
  pointer-events: none;
  z-index: 9999;
  opacity: 0.5;
}

/* ---- Sage shadow ladder (DESIGN.md tokens) ---------------- */
.shadow-sage-xs { box-shadow: 0 1px 2px rgba(80,101,90,0.05), 0 2px 6px rgba(80,101,90,0.07); }
.shadow-sage-sm { box-shadow: 0 1px 3px rgba(80,101,90,0.06), 0 3px 10px rgba(80,101,90,0.09), 0 6px 20px rgba(80,101,90,0.05); }
.shadow-sage-md { box-shadow: 0 2px 6px rgba(80,101,90,0.07), 0 6px 18px rgba(80,101,90,0.11), 0 14px 36px rgba(80,101,90,0.07); }
.shadow-sage-lg { box-shadow: 0 4px 12px rgba(80,101,90,0.08), 0 12px 32px rgba(80,101,90,0.12), 0 28px 60px rgba(80,101,90,0.08); }

/* ---- Reveal animation -------------------------------------- */
/* Strong ease-out per Emil: built-in `ease` is too weak for entry,
   the custom curve gives the punch that makes the section feel
   like it lands rather than drifts. */
.fade-up {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.55s var(--ease-out), transform 0.55s var(--ease-out);
}
.fade-up.visible {
  opacity: 1;
  transform: translateY(0);
}

/* ---- Anchor offset (fixed nav clearance) ------------------ */
section[id] { scroll-margin-top: 84px; }

/* ---- Overline / label typography -------------------------- */
.overline {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* ---- Named text-colour utilities (DESIGN.md neutral scale) --
   Replace opacity utilities (text-ink/55, text-white/22, etc.)
   which fail WCAG contrast. Solid colours keep contrast clean
   and stay semantic for assistive tech. Loaded once globally. */
.text-sage-headline { color: #22211F !important; }
.text-sage-ink      { color: #262626 !important; }
.text-sage-body     { color: #56615B !important; }
.text-sage-muted    { color: #5F7467 !important; }
.text-sage-micro    { color: #747D76 !important; }
.text-cream-soft    { color: #C1D1C9 !important; }
.text-cream-faint   { color: #96B0A5 !important; }

/* ---- Navigation chrome ------------------------------------ */
.nav-link {
  position: relative;
  transition: color 0.18s var(--ease-out);
}
/* Desktop navbar link typography; previously repeated as an inline
   style attribute on every nav link on every page. The aria-current
   and nav-on-dark rules below override colour/weight as before. */
nav#navbar .nav-link {
  font-size: 13.5px;
  font-weight: 500;
  color: #6B706A;
}
.nav-link:hover {
  color: #243D34 !important;
}
/* Hover is a plain colour shift; location is marked by the static
   aria-current underline. No animated underline-grow. */

/* Nav CTA: quiet bordered button, fills to dark on hover. */
.nav-cta {
  height: 38px;
  padding: 0 18px;
  border-radius: 8px;
  border: 1px solid #243D34;
  background: transparent;
  color: #243D34;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s var(--ease-out), color 0.2s var(--ease-out), border-color 0.2s var(--ease-out), transform var(--press-duration) var(--ease-out);
}
.nav-cta:hover {
  background-color: #243D34;
  color: #FFFFFB;
}
.nav-cta:active {
  transform: scale(0.97);
}

/* ---- Press feedback for every pressable surface ------------ */
/* Emil's "buttons must feel responsive" rule. Scale is subtle
   (0.97) so it reads as tactile, not animated. Applied to the
   most common button classes so every CTA gets the feel. */
.btn-primary,
.btn-outline,
.btn-outline-light,
.hero-cta-btn,
.hero-secondary-link {
  will-change: transform;
}
.btn-primary:active,
.btn-outline:active,
.btn-outline-light:active,
.hero-cta-btn:active,
.hero-secondary-link:active,
button[data-contact-trigger]:active {
  transform: scale(0.97);
}
/* Pair the press with a snappy retarget. The existing transitions
   already cover colour and box-shadow; add transform to that list. */
.btn-primary       { transition: background-color 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out), transform var(--press-duration) var(--ease-out); }
.btn-outline       { transition: border-color 0.2s var(--ease-out), background-color 0.2s var(--ease-out), transform var(--press-duration) var(--ease-out); }
.btn-outline-light { transition: border-color 0.2s var(--ease-out), background-color 0.2s var(--ease-out), transform var(--press-duration) var(--ease-out); }
nav#navbar .nav-link[aria-current="page"] {
  color: #243D34;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: rgba(36, 61, 52, 0.45);
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
}

/* Ruled document bar: flat surface, hairline structure, no blur,
   no shadow, ever. On scroll the bottom rule strengthens. */
nav#navbar {
  background-color: #FAF7F1 !important;
  border-bottom: 1px solid rgba(35, 55, 47, 0.14);
  transition: background-color 0.25s var(--ease-out), border-color 0.25s var(--ease-out);
}
nav#navbar.nav-scrolled {
  border-bottom-color: rgba(35, 55, 47, 0.28);
}

/* Brand logo treatment (every page).
   Single 200px-tall logo with the binocular figure intentionally
   overflowing the 76px nav into the section below. Click area is
   bound to the nav row via the anchor's explicit height; pointer-
   events are disabled on every descendant of the home link so the
   visually-overflowing portion of the image doesn't capture clicks
   intended for the area below the nav. flex/items-center handles
   the vertical centring automatically: a 200px child in a 76px
   flex container with align-items:center sits with its centre on
   the container's centre, overflowing equally above and below.
   Dark-section inversion is a CSS filter driven by .nav-on-dark,
   toggled by each page's scroll handler. */
nav#navbar a[href="/"] {
  height: 76px;
  display: inline-flex;
  align-items: center;
  overflow: visible;
  flex-shrink: 0;
}
nav#navbar a[href="/"] * { pointer-events: none; }
#logo-dark,
.nav-logo,
.home-nav-logo {
  height: 200px !important;
  max-height: 200px !important;
  width: auto !important;
  transition: filter 0.18s var(--ease-out);
}
@media (max-width: 479px) {
  #logo-dark,
  .nav-logo,
  .home-nav-logo {
    height: 160px !important;
    max-height: 160px !important;
  }
}
nav#navbar.nav-on-dark #logo-dark,
nav#navbar.nav-on-dark .nav-logo,
nav#navbar.nav-on-dark .home-nav-logo {
  filter: brightness(0) invert(1);
}

/* Dark-section nav inversion: same masthead, dark surface, white
   hairlines. Flat, no blur, no shadow. */
nav#navbar.nav-on-dark {
  background-color: #262626 !important;
  border-bottom-color: rgba(255, 255, 255, 0.18);
}
nav#navbar.nav-on-dark.nav-scrolled { border-bottom-color: rgba(255, 255, 255, 0.32); }
nav.nav-on-dark { background: #262626; }
nav.nav-on-dark .nav-link { color: rgba(255,255,255,0.6); }
nav.nav-on-dark .nav-link:hover { color: rgba(255,255,255,0.9); }
nav#navbar.nav-on-dark .nav-link[aria-current="page"] {
  color: rgba(255,255,255,0.92);
  text-decoration-color: rgba(255,255,255,0.5);
}
nav.nav-on-dark .nav-cta {
  border-color: rgba(255, 255, 255, 0.4);
  color: rgba(255, 255, 255, 0.92);
  background: transparent;
  box-shadow: none;
}
nav.nav-on-dark .nav-cta:hover {
  background-color: rgba(255, 255, 255, 0.14);
  color: #FFFFFB;
}
nav.nav-on-dark .mobile-toggle-icon { color: rgba(255,255,255,0.7); }

/* ---- Ruled nav (opt in with .nav-ruled, homepage first) ----
   No bar of its own. Transparent over a dark hero, cream over light
   sections, deep green over dark ones, with a single hairline under
   the row in every state. Small-capital links sit centred on the
   page; the logo carries two local times beside it. The logo swaps
   between an ink and a cream file rather than being filtered, so on
   dark the lettering and the figure keep their two tones. Selectors
   start nav#navbar.nav-ruled to outrank the bar rules above, several
   of which are !important. */
nav#navbar.nav-ruled {
  /* The header is Hanken Grotesk on every page, including the older
     pages whose body is still DM Sans. Scoping the token here makes
     every font-body element inside the nav follow it. */
  --font-body: 'Hanken Grotesk', system-ui, sans-serif;
  background-color: #FAF7F1 !important;
  border-bottom: 1px solid rgba(35, 55, 47, 0.16);
  box-shadow: none;
  transition: none;
}
/* Transitions wait for site.js to add .nav-ready, once the scroll
   observers have reported. Otherwise a page that opens scrolled
   would visibly fade from the markup state to the real one. */
nav#navbar.nav-ruled.nav-ready {
  transition: background-color 0.25s var(--ease-out), border-color 0.25s var(--ease-out), transform 0.32s var(--ease-out);
}
/* Over a dark section the bar takes that section's own colour, which
   site.js passes in as --nav-dark (green bands on the homepage,
   charcoal sections and footers elsewhere). */
nav#navbar.nav-ruled.nav-on-dark {
  background-color: var(--nav-dark, #243D34) !important;
  border-bottom-color: rgba(243, 240, 232, 0.14);
}
/* At the top of a dark hero the bar disappears entirely. Once the
   page moves it fills in, so text scrolling underneath never shows
   through. */
nav#navbar.nav-ruled.nav-on-dark:not(.nav-scrolled) {
  background-color: transparent !important;
  border-bottom-color: rgba(243, 240, 232, 0.16);
}
nav#navbar.nav-ruled.nav-on-dark:has(#mobile-menu.open) { background-color: var(--nav-dark, #243D34) !important; }
nav#navbar.nav-ruled.nav-hidden { transform: translateY(-100%); }

.nav-ruled__row {
  height: 64px;
  padding: 0 32px;
  display: grid;
  /* The sides share the leftover space equally, which centres the
     links on the page, but never shrink below their content. The
     wide gap keeps the links clear of the clocks on any row too
     tight to centre exactly. */
  grid-template-columns: minmax(max-content, 1fr) auto minmax(max-content, 1fr);
  align-items: center;
  column-gap: 40px;
}
@media (max-width: 639px) { .nav-ruled__row { padding: 0 20px; } }
.nav-ruled__start { display: flex; align-items: center; gap: 18px; }
.nav-ruled__end {
  grid-column: 3;
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 12px;
}
nav#navbar.nav-ruled a.nav-ruled__home { height: 64px; }
/* The Coverleo wordmark (brand_assets/logo-coverleo-*.svg). The SVG is
   cropped to its ink, so this height is the l's ascender down to the
   baseline: about a 31px setting of the word. */
.nav-ruled__logo { display: block; height: 22px; width: auto; }
.nav-ruled__logo--cream { display: none; }
nav#navbar.nav-ruled.nav-on-dark .nav-ruled__logo--ink { display: none; }
nav#navbar.nav-ruled.nav-on-dark .nav-ruled__logo--cream { display: block; }

/* Link type, after Heirest: medium-weight capitals set slightly
   tight, so each label reads as one compact shape rather than a row
   of spaced letters. Tight capitals are a deliberate choice here, not
   an oversight; the links and the CTA share the treatment. */
.nav-ruled__links { display: none; align-items: center; gap: 26px; }
nav#navbar.nav-ruled .nav-link {
  font-size: 0.78125rem;   /* 12.5px */
  font-weight: 500;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: #3F4A43;
}
nav#navbar.nav-ruled.nav-on-dark .nav-link { color: rgba(243, 240, 232, 0.88); }
nav#navbar.nav-ruled.nav-on-dark .nav-link:hover { color: #FFFFFB !important; }
/* Current page: the strongest text colour for the state plus a fine
   underline. Weight stays at 500 so the row does not shift width from
   page to page. This one rule replaces the per-page copies. */
nav#navbar.nav-ruled .nav-link[aria-current="page"] {
  color: #243D34;
  text-decoration: underline;
  text-decoration-color: rgba(36, 61, 52, 0.45);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 6px;
}
nav#navbar.nav-ruled.nav-on-dark .nav-link[aria-current="page"] {
  color: #FFFFFB;
  text-decoration-color: rgba(243, 240, 232, 0.5);
}
/* The dropdown trigger wraps its link in a block, whose line box sat
   the label about 2px below its neighbours. As a flex row it centres
   on the same line as the plain links. */
nav#navbar.nav-ruled .mega-trigger { display: flex; align-items: center; }

/* A nav item whose page does not exist yet: no link, and a visible
   TBC pill in place of one (the site's TBC rule). */
nav#navbar.nav-ruled .nav-link--tbc { display: inline-flex; align-items: center; gap: 7px; cursor: default; }
nav#navbar.nav-ruled .nav-link--tbc:hover { color: #3F4A43 !important; }
nav#navbar.nav-ruled.nav-on-dark .nav-link--tbc:hover { color: rgba(243, 240, 232, 0.88) !important; }
.nav-tbc {
  font-size: 0.59375rem;   /* 9.5px */
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 6px;
  border: 1px dashed currentColor;
  border-radius: 999px;
}

/* CTA: a quiet tinted block rather than an outlined button. */
nav#navbar.nav-ruled .nav-cta {
  display: none;
  height: 34px;
  padding: 0 16px;
  border: 0;
  border-radius: 4px;
  background: rgba(36, 61, 52, 0.08);
  color: #243D34;
  font-size: 0.78125rem;   /* 12.5px */
  font-weight: 500;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}
nav#navbar.nav-ruled .nav-cta:hover { background: #243D34; color: #FFFFFB; }
nav#navbar.nav-ruled.nav-on-dark .nav-cta { background: rgba(243, 240, 232, 0.11); color: #F3F0E8; }
nav#navbar.nav-ruled.nav-on-dark .nav-cta:hover { background: rgba(243, 240, 232, 0.2); color: #FFFFFB; }

.nav-ruled__toggle { color: #3F4A43; }
nav#navbar.nav-ruled.nav-on-dark .nav-ruled__toggle { color: rgba(243, 240, 232, 0.86); }

/* Melbourne and Manila times, filled in by site.js. Fixed width so
   the row does not shift when an hour gains a digit. */
.nav-clocks {
  display: none;
  flex-direction: column;
  gap: 6px;
  min-width: 132px;
  padding-left: 18px;
  border-left: 1px solid rgba(35, 55, 47, 0.18);
  font-size: 0.65625rem;   /* 10.5px */
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: #5F7467;
}
.nav-clocks b { font-weight: 600; color: #243D34; margin-left: 4px; }
nav#navbar.nav-ruled.nav-on-dark .nav-clocks { color: #A6B3A2; border-left-color: rgba(243, 240, 232, 0.2); }
nav#navbar.nav-ruled.nav-on-dark .nav-clocks b { color: #F3F0E8; }

nav#navbar.nav-ruled ~ .mega-scrim { top: 64px; }

/* Full row from 1024px; below that the hamburger takes over. The
   clocks join from 1100px, where the three links still sit centred
   beside them. */
@media (min-width: 1024px) {
  .nav-ruled__links { display: flex; }
  nav#navbar.nav-ruled .nav-cta { display: inline-flex; }
  .nav-ruled__toggle { display: none; }
  nav#navbar.nav-ruled #mobile-menu { display: none !important; }
}
@media (min-width: 1100px) {
  .nav-clocks { display: flex; }
}
@media (prefers-reduced-motion: reduce) {
  nav#navbar.nav-ruled { transition: none; }
}

/* Mobile menu toggle */
#mobile-menu { display: none; }
#mobile-menu.open { display: block; }

/* ---- Mega dropdown (Supported Roles) ---------------------- */
.mega-trigger { position: relative; }
.mega-dropdown {
  position: absolute;
  left: 0;
  top: 100%;
  z-index: 9000;
  padding-top: 8px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.22s var(--ease-out), transform 0.22s var(--ease-out), visibility 0.22s var(--ease-out);
  pointer-events: none;
}
.mega-trigger:hover .mega-dropdown,
.mega-trigger:focus-within .mega-dropdown,
.mega-dropdown.mega-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}
.mega-panel {
  background: #FFFFFB;
  border: 1px solid rgba(35, 55, 47, 0.10);
  border-radius: 12px;
  box-shadow: 0 12px 36px rgba(35, 55, 47, 0.18), 0 4px 12px rgba(35, 55, 47, 0.10);
  padding: 6px;
  min-width: 280px;
}
.mega-grid {
  display: grid;
  gap: 2px;
}
.mega-scrim {
  position: fixed;
  top: 76px;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  background: rgba(20, 28, 24, 0.40);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.2s var(--ease-out), visibility 0.2s var(--ease-out);
}
.mega-scrim.mega-open { opacity: 1; visibility: visible; }
@media (max-width: 1023px) { .mega-scrim { display: none; } }
.mega-link {
  display: block;
  padding: 9px 14px;
  border-radius: 8px;
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 500;
  color: #56615B;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.15s var(--ease-out), color 0.15s var(--ease-out);
}
.mega-link:hover {
  background: rgba(80, 101, 90, 0.07);
  color: #243D34;
}

/* ---- Pricing menu ------------------------------------------
   Pricing in the header opens one question and the two plans. site.js
   builds it from PRICING_MENU_COPY (see "Pricing menu" there): a popover
   from 1024px, and a fold under Pricing in the mobile menu below that.
   The colours are violet on every page, the sage pages included: a
   highlighted plan shows that plan's own ground. */

/* The header link. Styled by its href rather than by a class from
   site.js, because the script runs after first paint: the chevron's
   16px is held from the start, so the centred links do not shift when
   the menu arrives. The negative margin keeps the tinted block out of
   the row's spacing, and ::before lifts the 34px block to a 44px target. */
.nav-ruled__links a[href="/pricing/"] {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 34px;
  margin: 0 -8px;
  padding: 0 8px;
  border-radius: 4px;
  transition: color 0.18s var(--ease-out), background-color 0.18s var(--ease-out);
}
.nav-ruled__links a[href="/pricing/"]::before {
  content: '';
  position: absolute;
  inset: -5px 0;
}
.nav-ruled__links a[href="/pricing/"]::after,
.cl-pmenu__mtrigger::after {
  content: '';
  flex: none;
  width: 11px;
  height: 11px;
  background: currentColor;
  --clp-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9.5l6 6 6-6'/%3E%3C/svg%3E");
  -webkit-mask: var(--clp-chevron) center / contain no-repeat;
  mask: var(--clp-chevron) center / contain no-repeat;
  transition: transform 0.22s var(--ease-out);
}
/* With no script it is a plain link to the pricing page. */
@media (scripting: none) {
  .nav-ruled__links a[href="/pricing/"]::after { display: none; }
}
.nav-ruled__links a[href="/pricing/"][aria-expanded="true"]::after,
.cl-pmenu__mtrigger[aria-expanded="true"]::after { transform: rotate(180deg); }
nav#navbar.nav-ruled .nav-ruled__links a[aria-expanded="true"] {
  background: rgba(30, 22, 56, 0.08);
  color: #1E1638;
}
nav#navbar.nav-ruled.nav-on-dark .nav-ruled__links a[aria-expanded="true"] {
  background: rgba(242, 239, 250, 0.14);
  color: #FFFFFF;
}

/* The same link in the mobile menu. Its colours are inline on each page,
   so the open state has to be !important to change them. */
.cl-pmenu__mtrigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 44px;
}
.cl-pmenu__mtrigger::after { width: 16px; height: 16px; }
.cl-pmenu__mtrigger[aria-expanded="true"] {
  color: #1E1638 !important;
  font-weight: 700 !important;
  border-bottom-color: transparent !important;
}
/* The nav is fixed, so a menu taller than a small phone could never be
   reached by scrolling the page. It scrolls inside itself instead. */
#mobile-menu.open {
  max-height: calc(100vh - 65px);
  max-height: calc(100dvh - 65px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Popover. Pricing is the first link, so it opens to the right, and the
   arrow's centre lines up with the middle of the link. */
.cl-pmenu { position: relative; display: flex; align-items: center; }
.cl-pmenu__pop,
.cl-pmenu__fold {
  --clp-ink: #1E1638;
  --clp-surface: #FDFCFF;
  --clp-ask: #EDEAF5;
  --clp-muted: #5E5C6C;
  --clp-accent: #6A4FD8;
  --clp-lav: #E3DBF8;
  --clp-ring: rgba(30, 22, 56, 0.08);
}
.cl-pmenu__pop {
  position: absolute;
  z-index: 10;
  top: calc(100% + 20px);
  left: -20px;
  width: 468px;
  max-width: calc(100vw - 32px);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity 0.22s var(--ease-out), transform 0.22s var(--ease-out), visibility 0.22s var(--ease-out);
}
.cl-pmenu__pop.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
}
.cl-pmenu__arrow {
  position: absolute;
  z-index: 1;
  top: -6px;
  left: 44px;
  width: 14px;
  height: 14px;
  background: var(--clp-ask);
  border-radius: 3px;
  box-shadow: -1px -1px 0 var(--clp-ring);
  transform: rotate(45deg);
}

/* Fold, in the mobile menu. Only the rows track animates, and it closes
   to nothing, so the card's margin sits inside the clipped part. */
.cl-pmenu__fold {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows 0.26s var(--ease-out), visibility 0.26s var(--ease-out);
}
.cl-pmenu__fold.is-open { grid-template-rows: 1fr; visibility: visible; }
.cl-pmenu__fold-in { min-height: 0; overflow: hidden; }

/* The card. The family is set here rather than from --font-display,
   which is still DM Serif on the pages not yet moved to the new type.
   Those pages load no Bricolage, so they fall through to Hanken. */
.cl-pmenu__card {
  --pm-display: 'Bricolage Grotesque', 'Bricolage Fallback', 'Hanken Grotesk', system-ui, sans-serif;
  position: relative;
  color: var(--clp-ink);
  background: var(--clp-surface);
  font-family: var(--font-body);
  text-align: left;
}
.cl-pmenu__pop .cl-pmenu__card {
  border-radius: 14px;
  /* The ring keeps the edge on the lavender grounds, where the question
     band is almost the page's own colour. */
  box-shadow: 0 0 0 1px var(--clp-ring), 0 12px 36px rgba(30, 22, 56, 0.18), 0 4px 12px rgba(30, 22, 56, 0.10);
}
.cl-pmenu__fold .cl-pmenu__card {
  max-width: 468px;
  margin: 4px 0 10px;
  border: 1px solid rgba(30, 22, 56, 0.10);
  border-radius: 12px;
}

.cl-pmenu__ask { background: var(--clp-ask); }
.cl-pmenu__pop .cl-pmenu__ask { padding: 18px 20px 20px; border-radius: 14px 14px 0 0; }
.cl-pmenu__fold .cl-pmenu__ask { padding: 14px 14px 16px; border-radius: 11px 11px 0 0; }
.cl-pmenu__q {
  margin: 0 0 14px;
  font-family: var(--pm-display);
  font-size: 20px;
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -0.016em;
  text-wrap: balance;
  color: var(--clp-ink);
}
.cl-pmenu__fold .cl-pmenu__q { margin-bottom: 12px; font-size: 18px; letter-spacing: -0.014em; }
.cl-pmenu__answers {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.cl-pmenu__ans {
  appearance: none;
  height: 44px;
  padding: 0 16px;
  border: 1px solid rgba(30, 22, 56, 0.28);
  border-radius: 8px;
  background: var(--clp-surface);
  color: var(--clp-ink);
  font-family: inherit;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.18s var(--ease-out), border-color 0.18s var(--ease-out), color 0.18s var(--ease-out);
}
.cl-pmenu__ans:active { background: #F7F6FB; }
.cl-pmenu__ans[aria-pressed="true"] { background: var(--clp-ink); border-color: var(--clp-ink); color: #FFFFFF; }

.cl-pmenu__rows { display: grid; gap: 2px; padding: 6px; }
.cl-pmenu__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 20px;
  align-items: start;
  padding: 13px 14px;
  border-radius: 10px;
  text-decoration: none;
  transition: background-color 0.24s var(--ease-out);
}
.cl-pmenu__row:active { background: rgba(106, 79, 216, 0.12); }
.cl-pmenu__main { display: grid; gap: 3px; min-width: 0; }
.cl-pmenu__head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.cl-pmenu__name {
  font-family: var(--pm-display);
  font-size: 16px;
  font-weight: 650;
  line-height: 22px;
  letter-spacing: -0.012em;
  white-space: nowrap;
}
.cl-pmenu__line { font-size: 13.5px; line-height: 1.4; }
.cl-pmenu__price {
  display: grid;
  gap: 3px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cl-pmenu__from { font-size: 14.5px; font-weight: 650; line-height: 22px; }
.cl-pmenu__unit { font-size: 12.5px; line-height: 1.5; }
.cl-pmenu__name,
.cl-pmenu__from { color: var(--clp-ink); transition: color 0.24s var(--ease-out); }
.cl-pmenu__line,
.cl-pmenu__unit { color: var(--clp-muted); transition: color 0.24s var(--ease-out); }
/* Held in place while hidden, so answering never moves a row. */
.cl-pmenu__tag {
  flex: none;
  padding: 4px 8px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 650;
  line-height: 1;
  visibility: hidden;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.24s var(--ease-out), transform 0.24s var(--ease-out), visibility 0.24s var(--ease-out);
}
.cl-pmenu__row.is-on .cl-pmenu__tag { visibility: visible; opacity: 1; transform: none; }

/* Each plan highlights on its own ground, as on the pricing page. */
.cl-pmenu__row--ink .cl-pmenu__tag { background: #B4A3FF; color: var(--clp-ink); }
.cl-pmenu__row--ink.is-on { background: var(--clp-ink); }
.cl-pmenu__row--ink.is-on .cl-pmenu__name,
.cl-pmenu__row--ink.is-on .cl-pmenu__from,
.cl-pmenu__row--ink.is-on .cl-pmenu__line,
.cl-pmenu__row--ink.is-on .cl-pmenu__unit { color: #FFFFFF; }
.cl-pmenu__row--lav .cl-pmenu__tag { background: #5F44CF; color: #FFFFFF; }
.cl-pmenu__row--lav.is-on { background: var(--clp-lav); }
.cl-pmenu__row--lav.is-on .cl-pmenu__line,
.cl-pmenu__row--lav.is-on .cl-pmenu__unit { color: #3C3854; }

/* Hover only where it is real, so a tap does not leave a tint behind. */
@media (hover: hover) {
  .cl-pmenu__ans:hover { border-color: var(--clp-accent); }
  .cl-pmenu__ans[aria-pressed="true"]:hover { background: #2B214B; border-color: #2B214B; }
  .cl-pmenu__row:hover { background: rgba(106, 79, 216, 0.07); }
  .cl-pmenu__row--ink.is-on:hover { background: #2B214B; }
  .cl-pmenu__row--lav.is-on:hover { background: #D9CFF6; }
}

/* Focus. The two rules that start nav#navbar outrank the pale ring the
   Split-hero pages give everything in the row over a dark bar: this
   card stays light whatever the bar is doing. */
.cl-pmenu__card :focus-visible {
  outline: 2px solid var(--clp-accent);
  outline-offset: 2px;
  box-shadow: none;
}
.cl-pmenu__row:focus-visible { outline-offset: -2px; }
.cl-pmenu__row--ink.is-on:focus-visible { outline-color: #B4A3FF; }
nav#navbar.nav-ruled.nav-on-dark .nav-ruled__row .cl-pmenu__card :focus-visible { outline-color: var(--clp-accent); }
nav#navbar.nav-ruled.nav-on-dark .nav-ruled__row .cl-pmenu__row--ink.is-on:focus-visible { outline-color: #B4A3FF; }

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

/* Phones and tablets: one column, with the price on a single line and
   the tag out at the far edge. */
.cl-pmenu__fold .cl-pmenu__row {
  grid-template-columns: minmax(0, 1fr);
  row-gap: 3px;
  padding: 11px 12px;
  border-radius: 9px;
}
.cl-pmenu__fold .cl-pmenu__head { justify-content: space-between; }
.cl-pmenu__fold .cl-pmenu__name { font-size: 15.5px; line-height: 21px; }
.cl-pmenu__fold .cl-pmenu__line { font-size: 13px; }
.cl-pmenu__fold .cl-pmenu__price { display: block; text-align: left; white-space: normal; }
.cl-pmenu__fold .cl-pmenu__from,
.cl-pmenu__fold .cl-pmenu__unit { font-size: 13.5px; font-weight: 650; line-height: 1.4; color: var(--clp-ink); }
.cl-pmenu__fold .cl-pmenu__row--ink.is-on .cl-pmenu__from,
.cl-pmenu__fold .cl-pmenu__row--ink.is-on .cl-pmenu__unit { color: #FFFFFF; }
.cl-pmenu__fold .cl-pmenu__row--lav.is-on .cl-pmenu__unit { color: var(--clp-ink); }
/* Under about 330px the name and the tag no longer fit side by side. */
@media (max-width: 339px) {
  .cl-pmenu__fold .cl-pmenu__name { font-size: 14.5px; }
  .cl-pmenu__fold .cl-pmenu__tag { padding: 4px 6px; }
}

@media (prefers-reduced-motion: reduce) {
  .cl-pmenu__pop,
  .cl-pmenu__fold,
  .cl-pmenu__tag { transition: none; transform: none; }
}

/* ---- Contact modal ---------------------------------------- */
.contact-backdrop {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(20, 28, 24, 0.65);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.32s var(--ease-out), visibility 0.32s var(--ease-out);
}
.contact-backdrop.open { opacity: 1; visibility: visible; }

.contact-panel {
  position: fixed;
  z-index: 10001;
  bottom: 0;
  left: 0;
  right: 0;
  max-height: 94vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: #F9F7F4;
  border-radius: 20px 20px 0 0;
  transform: translateY(100%);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: transform 0.38s cubic-bezier(0.22,1,0.36,1), opacity 0.3s var(--ease-out), visibility 0.38s var(--ease-out);
}
.contact-panel.open {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}
@media (min-width: 640px) {
  .contact-panel {
    bottom: auto;
    top: 50%;
    left: 50%;
    right: auto;
    width: 100%;
    max-width: 520px;
    max-height: 90vh;
    border-radius: 16px;
    transform: translate(-50%, -46%) scale(0.97);
    opacity: 0;
  }
  .contact-panel.open {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
}

.contact-panel .form-field {
  width: 100%;
  font-family: var(--font-body);
  font-size: 14px;
  color: #262626;
  background: #FFFFFB;
  border: 1px solid rgba(80, 101, 90, 0.18);
  border-radius: 8px;
  padding: 11px 14px;
  outline: none;
  transition: border-color 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out);
}
.contact-panel .form-field::placeholder { color: rgba(38, 38, 38, 0.32); }
.contact-panel .form-field:focus {
  border-color: #50655A;
  box-shadow: 0 0 0 3px rgba(80, 101, 90, 0.10);
}
.contact-panel textarea.form-field { resize: vertical; min-height: 72px; }

/* ---- Booking dialog (contact choices, details form, Calendly) -
   Built and opened by site.js when any [data-contact-trigger] is
   pressed. Three steps share one panel, named by data-step on the
   dialog: "choose" (two large choices), "details" (the short form)
   and "book" (Calendly inline). A native <dialog> opened with showModal(), so it sits in
   the top layer above the nav and the paper-grain overlay and leaves
   the page inert behind it. Neutral product chrome that has to sit on
   both the violet pages and the older ones: one sans, ink text and a
   single accent kept to focus and loading. Most pages scope --ink and
   --accent to a section, so the fallbacks are what usually shows.
   The body is plain white on purpose: it meets Calendly's own white
   page without a visible seam. Motion is opacity on the dialog and
   transform on the panel and the progress line only; closing is
   quicker than opening. */
.cl-book {
  --clb-ink: var(--ink, #1E1638);
  --clb-accent: var(--accent, var(--violet, #6A4FD8));
  --clb-muted: #5E5C6C;
  --clb-line: rgba(30, 22, 56, 0.10);
  --clb-bar: #FBFAFE;
  --clb-err: #B42318;
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 24px;
  border: 0;
  overflow: hidden;
  overscroll-behavior: contain;
  background: rgba(21, 13, 44, 0.56);
  color: var(--clb-ink);
  font-family: var(--font-body, 'Hanken Grotesk', system-ui, sans-serif);
  opacity: 0;
  transition: opacity 160ms var(--ease-out);
}
/* Only while open: a bare display rule would override the browser's
   own dialog:not([open]) { display: none }. */
.cl-book[open] { display: grid; place-items: center; }
.cl-book::backdrop { background: transparent; }
.cl-book.is-open {
  opacity: 1;
  transition: opacity 220ms var(--ease-out);
}

/* The choices and the form sit in a compact panel that grows with its
   content. The booking step widens it to 1160px because Calendly only
   switches to its two-column layout (details beside the calendar) once
   its frame is about 1130px wide; at 1000px it stacks. Narrower
   screens get the stacked layout. */
.cl-book__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(480px, 100%);
  max-height: calc(100vh - 48px);
  max-height: calc(100dvh - 48px);
  background: #FFFFFF;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(21, 13, 44, 0.12), 0 24px 64px rgba(21, 13, 44, 0.30);
  transform: translateY(8px) scale(0.985);
  transition: transform 160ms var(--ease-out);
}
.cl-book.is-open .cl-book__panel {
  transform: none;
  transition: transform 260ms var(--ease-out);
}
.cl-book[data-step="book"] .cl-book__panel {
  width: min(1160px, 100%);
  height: min(720px, calc(100vh - 48px));
  height: min(720px, calc(100dvh - 48px));
}
/* Steps, the Back button and the fallback link are switched with the
   hidden attribute; this keeps it winning over their display rules. */
.cl-book [hidden] { display: none !important; }

.cl-book__bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  min-height: 60px;
  padding: 8px 8px 8px 20px;
  background: var(--clb-bar);
  border-bottom: 1px solid var(--clb-line);
}
/* With Back in front, the bar starts at the button instead. */
.cl-book:not([data-step="choose"]) .cl-book__bar { padding-left: 8px; }
.cl-book__title {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-family: inherit;
  font-size: 15.5px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.005em;
  color: var(--clb-ink);
  text-wrap: balance;
}
/* Focus lands on the heading when a step changes, so the change is
   read out. It is not a control, so it shows no ring. */
.cl-book__title:focus { outline: none; box-shadow: none; }
.cl-book__alt,
.cl-book__slow a {
  color: var(--clb-muted);
  text-decoration: underline;
  text-decoration-color: rgba(30, 22, 56, 0.28);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  border-radius: 8px;
  transition: color 150ms var(--ease-out), text-decoration-color 150ms var(--ease-out);
}
/* 44px tall: 13px padding above and below an 18px line. */
.cl-book__alt {
  flex: none;
  display: inline-block;
  padding: 13px 8px;
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
  white-space: nowrap;
}
@media (hover: hover) {
  .cl-book__alt:hover,
  .cl-book__slow a:hover {
    color: var(--clb-ink);
    text-decoration-color: currentColor;
  }
  .cl-book__icon-btn:hover { background: rgba(30, 22, 56, 0.06); }
}
/* Back and Close: 44px square. */
.cl-book__icon-btn {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--clb-ink);
  cursor: pointer;
  transition: background-color 150ms var(--ease-out), transform var(--press-duration) var(--ease-out);
}
.cl-book__icon-btn:active { transform: scale(0.94); }
.cl-book__icon-btn svg { display: block; width: 18px; height: 18px; }
/* Outranks the shared sage focus halo further down this file. */
.cl-book__icon-btn:focus-visible,
.cl-book__alt:focus-visible,
.cl-book__slow a:focus-visible,
.cl-book__send:focus-visible,
.cl-book__done:focus-visible,
.cl-book__privacy a:focus-visible,
.cl-book__failed a:focus-visible {
  outline: 2px solid var(--clb-accent);
  outline-offset: 2px;
  box-shadow: none;
}

/* ---- Choose and details steps ----
   Each scrolls on its own under the bar when the screen is short. A
   step that appears fades up a few pixels, so the change reads as a
   change and not a jump. */
.cl-book__pane {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.cl-book.is-open .cl-book__pane { animation: clb-step-in 220ms var(--ease-out) both; }
@keyframes clb-step-in { from { opacity: 0; transform: translateY(6px); } }

/* The two choices: full-width rows, edge to edge in the panel, with a
   hairline between. Each is one large button. */
.cl-book__choice {
  appearance: none;
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) 20px;
  align-items: start;
  column-gap: 16px;
  width: 100%;
  min-height: 88px;
  margin: 0;
  padding: 22px 20px 22px 24px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--clb-ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 150ms var(--ease-out);
}
.cl-book__choice + .cl-book__choice { border-top: 1px solid var(--clb-line); }
.cl-book__choice-i { display: block; width: 24px; height: 24px; color: var(--clb-accent); }
.cl-book__choice-text { display: grid; gap: 4px; }
.cl-book__choice-t {
  display: block;
  font-size: 17px;
  font-weight: 600;
  line-height: 24px;
  letter-spacing: -0.012em;
}
.cl-book__choice-s {
  display: block;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--clb-muted);
  text-wrap: pretty;
}
.cl-book__chev {
  display: block;
  align-self: center;
  width: 20px;
  height: 20px;
  color: var(--clb-muted);
  transition: transform 200ms var(--ease-out), color 150ms var(--ease-out);
}
@media (hover: hover) {
  .cl-book__choice:hover { background: rgba(106, 79, 216, 0.05); }
  .cl-book__choice:hover .cl-book__chev { color: var(--clb-ink); transform: translateX(3px); }
}
.cl-book__choice:active { background: rgba(106, 79, 216, 0.09); }
.cl-book__choice:focus-visible {
  outline: 2px solid var(--clb-accent);
  outline-offset: -4px;
  border-radius: 12px;
  box-shadow: none;
}

/* The form. 16px inputs so phones do not zoom in on focus. */
.cl-book__form {
  display: grid;
  gap: 18px;
  padding: 22px 24px 24px;
}
.cl-book__field { display: grid; gap: 6px; min-width: 0; }
.cl-book__field label {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--clb-ink);
}
.cl-book__opt { font-weight: 400; color: var(--clb-muted); }
.cl-book__input {
  display: block;
  width: 100%;
  min-height: 48px;
  margin: 0;
  padding: 12px 14px;
  border: 1px solid rgba(30, 22, 56, 0.26);
  border-radius: 10px;
  background: #FFFFFF;
  font: inherit;
  font-size: 16px;
  line-height: 22px;
  color: var(--clb-ink);
  transition: border-color 150ms var(--ease-out), box-shadow 150ms var(--ease-out);
}
textarea.cl-book__input { resize: vertical; }
.cl-book__input:focus,
.cl-book__input:focus-visible {
  outline: none;
  border-color: var(--clb-accent);
  box-shadow: 0 0 0 3px rgba(106, 79, 216, 0.22);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--clb-accent) 22%, transparent);
}
.cl-book__input[aria-invalid="true"] { border-color: var(--clb-err); }
.cl-book__input[aria-invalid="true"]:focus { border-color: var(--clb-err); box-shadow: 0 0 0 3px rgba(180, 35, 24, 0.16); }
.cl-book__err {
  margin: 0;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--clb-err);
}

.cl-book__actions { display: grid; gap: 14px; margin-top: 4px; }
.cl-book__send,
.cl-book__done {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  border-radius: 10px;
  font: inherit;
  font-weight: 700;
  letter-spacing: -0.005em;
  cursor: pointer;
  transition: background-color 150ms var(--ease-out), border-color 150ms var(--ease-out), transform var(--press-duration) var(--ease-out);
}
.cl-book__send {
  width: 100%;
  min-height: 52px;
  padding: 0 24px;
  border: 0;
  background: var(--clb-ink);
  color: #FFFFFF;
  font-size: 15.5px;
}
.cl-book__send:active,
.cl-book__done:active { transform: scale(0.98); }
.cl-book__send[aria-disabled="true"] { cursor: progress; transform: none; background: #3A3157; }
@media (hover: hover) {
  .cl-book__send:hover { background: #2E2452; }
  .cl-book__done:hover { background: rgba(30, 22, 56, 0.05); border-color: rgba(30, 22, 56, 0.4); }
}
.cl-book__failed {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--clb-err);
}
.cl-book__failed:empty { display: none; }
.cl-book__privacy {
  margin: 0;
  font-size: 13px;
  line-height: 18px;
  color: var(--clb-muted);
}
/* Inline links, padded to a 44px hit area without moving the line. */
.cl-book__privacy a,
.cl-book__failed a {
  padding: 13px 0;
  border-radius: 4px;
  color: var(--clb-ink);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: rgba(30, 22, 56, 0.35);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.cl-book__failed a { color: inherit; text-decoration-color: currentColor; }
.cl-book__privacy a:hover { text-decoration-color: currentColor; }

/* Bot trap: off screen and out of the accessibility tree. */
.cl-book__hp {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.cl-book__thanks {
  display: grid;
  justify-items: start;
  gap: 14px;
  padding: 28px 24px 24px;
}
.cl-book__tick { display: block; width: 32px; height: 32px; color: var(--clb-accent); }
.cl-book__thanks-t {
  max-width: 30ch;
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: -0.012em;
  color: var(--clb-ink);
  text-wrap: pretty;
}
.cl-book__thanks-t:focus { outline: none; box-shadow: none; }
.cl-book__done {
  min-height: 48px;
  margin-top: 6px;
  padding: 0 24px;
  border: 1px solid rgba(30, 22, 56, 0.26);
  background: transparent;
  color: var(--clb-ink);
  font-size: 15px;
}

.cl-book__body {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  background: #FFFFFF;
}
.cl-book__frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: #FFFFFF;
}

/* Quiet loading state until Calendly has drawn its page: a muted line
   on a white cover, with the progress line below sitting on top.
   Fades away, never jumps. */
.cl-book__loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 24px;
  background: #FFFFFF;
  text-align: center;
  transition: opacity 200ms var(--ease-out), visibility 200ms var(--ease-out);
}
.cl-book__loading p {
  margin: 0;
  max-width: 36ch;
  font-size: 14px;
  line-height: 1.5;
  color: var(--clb-muted);
}
.cl-book__slow { display: none; }
.cl-book__body.is-slow .cl-book__slow { display: block; }
.cl-book__body.is-loaded .cl-book__loading {
  opacity: 0;
  visibility: hidden;
}

/* Progress line under the header bar. Calendly reports no real progress, so
   this is paced, not measured, to show the wait is moving. Two
   transitions on one line multiply: `scale` makes the quick opening
   jump to about 30%, `transform` then crawls on toward 90% over
   8s, slowing as it goes. It never fills on its own. site.js adds
   is-loading once the dialog is on screen and is-loaded when Calendly
   has drawn its page; then it fills in 200ms and fades. Nothing waits
   for it: the white cover starts fading at that same moment. */
.cl-book__progress {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: 100%;
  height: 2px;
  background: var(--clb-accent);
  transform-origin: left center;
  scale: 0 1;
  transform: scaleX(0.27);
  pointer-events: none;
}
.cl-book__body.is-loading .cl-book__progress {
  scale: 1 1;
  transform: scaleX(0.9);
  transition: scale 450ms var(--ease-out), transform 8s cubic-bezier(0, 0, 0.58, 1);
}
/* Kept after is-loading so it wins while both are set. A reopen after
   loading starts here, so no line shows at all. */
.cl-book__body.is-loaded .cl-book__progress {
  scale: 1 1;
  transform: scaleX(1);
  opacity: 0;
  transition: scale 200ms var(--ease-out), transform 200ms var(--ease-out), opacity 160ms var(--ease-out) 160ms;
}

/* Focus wraps (site.js): Tab past the last control of the step on
   show lands on the first, Shift+Tab before the first on the last. */
.cl-book__edge {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
}
.cl-book__sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Phone: a full-width sheet with a slimmer bar. The choices and the
   form rise from the bottom edge and grow with their content; the
   booking step fills the screen. The dialog follows the visible area
   (--clb-vh and --clb-vt, set by site.js from visualViewport), so with
   the keyboard up the sheet sits above it and the Send row, stuck to
   the foot of the form, stays in view. The fallback link keeps its
   full accessible name; only "Trouble loading?" is hidden visually so
   the bar fits on one line. */
@media (max-width: 639px) {
  .cl-book {
    padding: 0;
    inset: var(--clb-vt, 0px) 0 auto 0;
    height: var(--clb-vh, 100%);
  }
  .cl-book[open] { place-items: end stretch; }
  .cl-book__panel {
    width: 100%;
    max-height: 100%;
    border-radius: 16px 16px 0 0;
    box-shadow: none;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    transform: translateY(16px);
  }
  .cl-book[data-step="book"] .cl-book__panel {
    width: 100%;
    height: 100%;
    border-radius: 0;
    padding-top: env(safe-area-inset-top, 0px);
  }
  .cl-book__bar {
    min-height: 56px;
    gap: 4px;
    padding: 6px 6px 6px 16px;
  }
  .cl-book:not([data-step="choose"]) .cl-book__bar { padding-left: 6px; }
  .cl-book__choice { padding: 20px 16px 20px 20px; column-gap: 14px; }
  .cl-book__form { gap: 16px; padding: 20px 16px 0; }
  .cl-book__details { scroll-padding-bottom: 150px; }
  .cl-book__actions {
    position: sticky;
    bottom: 0;
    z-index: 1;
    margin: 0 -16px;
    padding: 12px 16px 16px;
    background: #FFFFFF;
    border-top: 1px solid var(--clb-line);
  }
  .cl-book__thanks { padding: 24px 16px 20px; }
  .cl-book__done { width: 100%; }
  /* Touch targets: 44px tall for the link. */
  .cl-book__alt { padding: 13px 4px; }
  .cl-book__alt-lead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cl-book,
  .cl-book.is-open,
  .cl-book__panel,
  .cl-book.is-open .cl-book__panel,
  .cl-book__loading { transition: none; }
  .cl-book__panel { transform: none; }
  .cl-book__progress { display: none; }
  .cl-book.is-open .cl-book__pane { animation: none; }
  .cl-book__chev { transition: none; }
}

/* ---- TBC placeholder (visible "needs founder input") ------ */
.tbc-placeholder {
  position: relative;
  border: 1.5px dashed #A6B3A2;
  background: #F4F1E8;
  border-radius: 12px;
  padding: 18px 16px 14px;
  display: block;
}
.tbc-placeholder--inline {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 5px 10px 5px 6px;
  border-radius: 999px;
  border-width: 1px;
}
.tbc-badge {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #FFFFFB;
  background: #50655A;
  padding: 3px 7px;
  border-radius: 4px;
  line-height: 1;
  white-space: nowrap;
}
.tbc-needs {
  font-family: var(--font-body);
  font-size: 13.5px;
  color: #56615B;
  line-height: 1.45;
}

/* ---- Universal focus halo (DESIGN.md focus-halo token) ----
   Stacked halo: thin warm-cream inner band keeps the dark-green
   outer ring separated from sage/dark backgrounds where a single
   solid outline could disappear into the button colour. Works on
   cream, sage, parchment and dark sections without per-context rules. */
:focus-visible {
  outline: 2px solid #243D34;
  outline-offset: 3px;
  box-shadow: 0 0 0 1px rgba(250, 247, 241, 0.85);
}
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid #243D34;
  outline-offset: 3px;
  box-shadow: 0 0 0 1px rgba(250, 247, 241, 0.85);
}

/* ---- Skip link (a11y; visible on focus) ------------------- */
.skip-link {
  position: absolute;
  top: 16px;
  left: 16px;
  transform: translateY(-148px);
  z-index: 99999;
  padding: 10px 16px;
  background: #243D34;
  color: #FFFFFB;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  border-radius: 8px;
  text-decoration: none;
  box-shadow: 0 4px 12px rgba(36, 61, 52, 0.24);
  transition: transform 0.18s ease;
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  outline: 2px solid #FFFFFB;
  outline-offset: 2px;
}

/* ---- Page transition (every page) -------------------------
   Every page opts in to the browser's cross-page animation, so a
   click to another page eases across instead of cutting. Chrome,
   Edge and Safari animate; other browsers load the page as normal.
   Reduced motion turns it off.

   The nav is named so it holds still while the page under it
   changes (or slides back in, if it was tucked away on scroll). A
   view-transition-name must be unique on a page or the browser skips
   the whole transition, so every page has exactly one nav#navbar.

   The default: the new page fades in over the old one in about a
   fifth of a second and settles up 8px. The old page stays solid
   underneath instead of fading too, because whatever shows through
   a gap is the new page's background: two dark sections would flash
   light between them.

   The homepage, AI Business Specialist + and AI Expert Plan share
   the Split hero (.ph-hero). Between those three the hero morphs,
   set in each page's own styles, so this default steps aside on
   them. On a trip between one of them and any other page, their
   head script adds .vt-plain, which drops the hero's names and
   brings this default back. The animation runs on the page being
   opened, so these rules decide how a page arrives. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
nav#navbar { view-transition-name: site-nav; }
:root:is(.vt-plain, :not(:has(.ph-hero)))::view-transition-group(*) {
  animation-duration: 420ms;
  animation-timing-function: var(--ease-out);
}
:root:is(.vt-plain, :not(:has(.ph-hero)))::view-transition-old(*),
:root:is(.vt-plain, :not(:has(.ph-hero)))::view-transition-new(*) {
  animation-duration: 220ms;
  animation-timing-function: var(--ease-out);
}
:root:is(.vt-plain, :not(:has(.ph-hero)))::view-transition-old(root) {
  animation: none;
  mix-blend-mode: normal;
}
:root:is(.vt-plain, :not(:has(.ph-hero)))::view-transition-new(root) {
  animation: vt-page-fade 220ms var(--ease-out) both, vt-page-rise 420ms var(--ease-out) both;
  mix-blend-mode: normal;
}
@keyframes vt-page-fade { from { opacity: 0; } }
@keyframes vt-page-rise { from { transform: translateY(8px); } }

/* ---- Reduced motion (WCAG 2.3.3) -------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .fade-up {
    opacity: 1 !important;
    transform: none !important;
  }
}

