/* Self-hosted from Google Fonts, latin and latin-ext only: Caladea (Apache 2.0), IBM Plex Mono and Public Sans (SIL OFL 1.1). */
@font-face {
  font-family: 'Caladea';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/caladea-400-italic-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Caladea';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/caladea-400-italic-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Caladea';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/caladea-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Caladea';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/caladea-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Caladea';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/caladea-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Caladea';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/caladea-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/ibm-plex-mono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/ibm-plex-mono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/ibm-plex-mono-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/ibm-plex-mono-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/public-sans-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/public-sans-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/public-sans-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/public-sans-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Layout: a climbing topo. The red route line runs through the page; each section is a pitch, labelled in mono like topo notes. */
:root{
  --paper:#FFFFFF; --paper-2:#F2F3F1; --ink:#1B1F22; --ink-2:#4A5156; --ink-3:#646C71;
  --rule:#D6DAD5; --route:#C1281A; --route-soft:#F5DFDA; --on-route:#FFFFFF; --contour:#C7CDC6;
  --display:"Caladea",Georgia,"Times New Roman",serif;
  --body:"Public Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,"SFMono-Regular",Menlo,Consolas,monospace;
  --max:1120px;
  color-scheme:light;
}
/* White background in every theme (Mario, 28 Oct 2026), so there is no dark palette. */
*{box-sizing:border-box}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;background:var(--paper);color:var(--ink);font:400 17px/1.6 var(--body);-webkit-font-smoothing:antialiased;display:flex;flex-direction:column;min-height:100vh;min-height:100dvh}
body>main{flex:1 0 auto;width:100%}  /* a short page (404) keeps its footer at the bottom of the screen */
.w{max-width:var(--max);margin:0 auto;padding-left:max(20px,env(safe-area-inset-left,0px));padding-right:max(20px,env(safe-area-inset-right,0px))}
a{color:inherit;text-decoration-color:var(--route);text-decoration-thickness:1.5px;text-underline-offset:4px}
:focus-visible{outline:2px solid var(--route);outline-offset:3px}
h1,h2,h3{font-family:var(--display);font-weight:400;text-wrap:balance;margin:0}
main h3{color:var(--route)}  /* subheadings in route red (Mario, 29 Oct 2026) */
p{margin:0}
.note{font:500 12px/1.4 var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.note b{color:var(--route);font-weight:600}

/* header */
.top{border-bottom:1px solid var(--rule)}
.top .w{display:flex;align-items:center;gap:24px;padding-block:18px}
.mark{display:flex;flex-direction:column;line-height:1;text-decoration:none;position:relative;top:-2px}  /* lifted 2px so the lockup's ink sits centred in the header bar */
.mark b{font:700 34px/1 var(--display);letter-spacing:.06em;margin-right:-.06em}  /* tighter wordmark (Mario, 29 Oct 2026) */
.mark span{font:500 12px/1 var(--body);letter-spacing:.105em;margin-right:-.105em;color:var(--ink-2);margin-top:4px}  /* ACCOUNTING spans exactly the width of CRUX above it (Mario, 30 Oct 2026) */
.nav{margin-left:auto;display:flex;gap:22px;align-items:center;font-size:17px}  /* larger header text, same header size (Mario, 29 Oct 2026) */
.nav a{text-decoration:none;color:var(--ink-2)}
.nav a:hover{color:var(--ink)}
.btn{display:inline-flex;align-items:center;gap:8px;font:600 15px/1 var(--body);padding:13px 18px;border-radius:999px;text-decoration:none;border:1.5px solid var(--ink);color:var(--ink);background:transparent;cursor:pointer}
.btn:hover{background:var(--paper-2)}
.btn.go{background:var(--route);border-color:var(--route);color:var(--on-route)}
.btn.go:hover{filter:brightness(1.06)}
.nav .btn{padding:8px 14px;font-size:16px}
/* header in route red (Mario, 29 Oct 2026) */
.top .nav a{color:var(--route)}
.top .mark,.top .mark span{color:var(--ink)}  /* logo stays black (Mario, 29 Oct 2026) */
.top .nav a:hover{color:var(--ink)}
.top .nav .btn{border-color:var(--route);background:var(--route);color:var(--on-route)}  /* filled red, white text (Mario, 29 Oct 2026) */
.top .nav .btn:hover{background:var(--route);color:var(--on-route);filter:brightness(1.06)}

/* hero */
.hero .w{display:grid;grid-template-columns:minmax(0,1fr);gap:40px;align-items:center;padding-block:64px 72px}
.hero h1{font-size:clamp(42px,6.2vw,76px);line-height:1.02;letter-spacing:-.015em;margin:14px 0 22px}
.hero h1 em{font-style:italic;color:var(--route)}
.hero .lede{font-size:19px;color:var(--ink-2);max-width:34em}
.hero .cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:30px}
.map{position:relative;aspect-ratio:1/1;max-width:100%;border:1px solid var(--rule);border-radius:4px;background:var(--paper)}
.map canvas{position:absolute;inset:0;width:100%;height:100%}
.mapbox{margin:0;min-width:0}
.mapsec .mapbox{max-width:560px;margin-inline:auto}  /* map centred in its own band above How we work (Mario, 30 Oct 2026) */
.mapbox .legend{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-top:10px}

/* sections */
section.pitch{border-top:1px solid var(--rule)}
section.pitch>.w{padding-block:72px}
.ph{display:grid;grid-template-columns:200px minmax(0,1fr);gap:32px;margin-bottom:40px}
.ph h2{font-size:clamp(32px,4vw,46px);line-height:1.08}
.ph>.note{font-size:18px;color:var(--ink-2)}  /* section labels sit larger than the labels inside cards */
.ph div>p{color:var(--ink-2);margin-top:14px;max-width:38em;font-size:18px}
.body{margin-left:232px}
.body h3{font-size:22px;line-height:1.2}  /* every card heading the same size (formatting sweep, Mario, 30 Oct 2026) */

.body.fit{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:28px}
.body.fit div{border-top:2px solid var(--ink);padding-top:14px}
.body.fit h3{margin-bottom:8px}
.body.fit p{color:var(--ink-2);font-size:16px}
.leaf{width:.8em;height:.8em;vertical-align:-.04em;fill:currentColor;color:var(--route)}  /* maple leaf after Canada (Mario, 29 Oct 2026), always route red */

.svc{list-style:none;margin:0;padding:0;border-top:1px solid var(--ink)}
.svc li{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.4fr) minmax(0,.7fr);gap:24px;padding:20px 0;border-bottom:1px solid var(--rule)}
/* service names in the label column, descriptions lined up with the intro paragraph (Mario, 29 Oct 2026) */
.body.svc{margin-left:0}
.body.svc li{grid-template-columns:200px minmax(0,1fr) minmax(0,.4fr);gap:32px;align-items:baseline}  /* name, description and timing start on one line */
.svc p{color:var(--ink-2);font-size:16px}
.svc .when{font:500 13px/1.5 var(--mono);color:var(--ink-3)}

.profile{width:100%;height:auto;display:block;margin:0 0 8px}
/* one vertical band per pitch: alternating greys, Crux-led pitches (P4, P6, P7) in soft route red (Mario, 29 Oct 2026) */
.profile .bands polygon{stroke:var(--paper);stroke-width:1.5}
.profile .far{fill:#F7F8F6}  /* faint distant range behind the route (Mario, 29 Oct 2026) */
.profile .line,.profile .crux{stroke-linejoin:round}
.profile .b1{fill:#F2F3F1} .profile .b2{fill:#E8EAE6}
.profile .bm1{fill:#F5DFDA}
.profile .line{fill:none;stroke:var(--ink);stroke-width:2}
.profile .crux{fill:none;stroke:var(--route);stroke-width:4;stroke-linecap:round}
.profile .anc{fill:var(--paper);stroke:var(--ink);stroke-width:2}
.profile .anc.m{fill:var(--route);stroke:var(--route)}
.profile text{font:500 12px var(--mono);fill:var(--ink-2)}
.profile text.m{fill:var(--route);font-weight:600}
.steps{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:28px;counter-reset:p}
.steps li{padding-top:12px;border-top:1px solid var(--rule)}
.steps li.m{border-top:3px solid var(--route)}
#route .steps>li{border-top:2px solid var(--route)} #route .steps>li.m{border-top-width:3px;padding-top:11px}  /* red line above each stage card so the stages read as separate sections (Mario, 29 Oct 2026); 1px less padding under the thicker rule keeps the Stage labels level */
#route .steps .note b{color:var(--ink-3)}  /* Stage 2 label in the same grey as Stages 1 and 3 (Mario, 29 Oct 2026) */
.steps .note{display:block;margin-bottom:6px}
.steps h3{margin-bottom:8px}
.steps p{font-size:16px;color:var(--ink-2)}
.steps .you{margin-top:14px;padding-top:10px;border-top:1px dashed var(--rule);color:var(--ink);font-weight:600}  /* what the client does in each stage */
.steps .you .note{margin-bottom:2px;font-weight:500}
.profile .peak{fill:var(--ink)}
/* the eight working steps, split under their stage and folded away until clicked (Mario, 29 Oct 2026) */
.steps8{margin-top:14px;border-top:1px dashed var(--rule);padding-top:10px}
.steps8 summary{cursor:pointer;font:500 12px/1.4 var(--mono);letter-spacing:.06em;text-transform:uppercase;color:var(--route)}
.steps8 summary:hover{color:var(--ink)}
.steps .steps8 ol{list-style:none;margin:10px 0 0;padding:0;display:grid;gap:10px}
.steps .steps8 li{border:0;padding:0;font-size:15px;line-height:1.5;color:var(--ink-3)}  /* lighter text for the expanded steps (Mario, 29 Oct 2026) */
.steps .steps8 li .sn{display:block;font-weight:600;color:var(--ink-2);margin-bottom:2px}  /* step number and name on its own line above the text */
/* the steps on the profile: small anchors between steps, numbers mid-pitch, each a link to its step in the cards (Mario, 29 Oct 2026) */
.profile .pa{fill:var(--paper);stroke:var(--ink-2);stroke-width:1.5}
.profile .pa.m{stroke:var(--route)}
.profile .pitches text{font:600 11px var(--mono);fill:var(--ink-3)}
.profile .pitches .m text{fill:var(--route)}
.profile .pitches .hit{fill:transparent}
.profile .pitches a{cursor:pointer}
.profile .pitches a:hover text,.profile .pitches a:focus-visible text{fill:var(--ink);text-decoration:underline}
.steps8 li{scroll-margin:120px;border-radius:2px;transition:background-color .6s,box-shadow .6s}
.steps .steps8 li.hl{background:var(--route-soft);box-shadow:0 0 0 6px var(--route-soft)}

.roles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0;border:1px solid var(--rule);border-radius:4px}
.roles div{padding:24px}
.roles div+div{border-left:1px solid var(--rule)}
.roles h3{margin:6px 0 8px}
.roles ul{margin:0;padding-left:18px;color:var(--ink-2);font-size:16px}
.roles li+li{margin-top:6px}
.roles .lead{background:var(--route-soft)}
.roles .lead .note b{color:var(--ink)}  /* lead card label in black (Mario, 29 Oct 2026) */

.fees{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:28px}
.fees>div{border-top:2px solid var(--ink);padding-top:14px}  /* same top rule as the cards in Who we work with */
.fees h3{margin-bottom:8px}
.fees p{color:var(--ink-2);font-size:16px}

/* bio on the left; At a glance, headshot and LinkedIn stacked in a sidebar on the right (Mario, 29 Oct 2026) */
.about{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:24px 56px;align-items:start}
@media (min-width:901px) and (max-width:979px){.about{grid-template-columns:minmax(0,1fr) 280px;column-gap:40px}}
.about .bio{max-width:44em}
.about p+p{margin-top:16px}
.about .lede{font:400 26px/1.35 var(--display)}
.portrait{display:block;width:100%;max-width:220px;height:auto;aspect-ratio:1/1;object-fit:cover;object-position:50% 25%;border-radius:50%;background:var(--paper-2)}
.about .meta{display:grid;grid-template-columns:1fr;gap:28px;align-items:start}
.about .meta .portrait{max-width:200px;margin:0 auto}
.about .meta .cv{text-align:center}  /* LinkedIn note and button centred under the headshot (Mario, 29 Oct 2026) */
@media (min-width:1050px){.about .meta{margin-top:calc(-40px - .906 * clamp(32px,4vw,46px))}}  /* sidebar starts level with the About heading, not below it; narrower screens would collide with the heading (Mario, 30 Oct 2026) */
.glance{border-top:2px solid var(--ink);padding-top:14px}
.about dl{margin:10px 0 0;display:grid;grid-template-columns:auto 1fr;gap:6px 16px;font-size:15px}
.about dt{color:var(--route)} .about dd{margin:0}
.cv{border-top:2px solid var(--ink);padding-top:14px}  /* work experience beside the bio, education beside the glance (Mario, 29 Oct 2026) */
.cv .cvlink{font-size:16px;color:var(--ink-2);margin:0 0 16px}  /* work history lives on LinkedIn (Mario, 29 Oct 2026) */

.book{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:48px;align-items:center}  /* fit check card centred against What happens next; Mario kept both (30 Oct 2026) */
.fitcta{border-top:2px solid var(--ink);padding-top:14px}
.fitcta h3{margin:6px 0 8px}
.fitcta p:not(.note){color:var(--ink-2);font-size:16px}
.fitcta p+p{margin-top:18px}
.reviews{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:48px;align-items:start}
.reviews.empty{grid-template-columns:minmax(0,640px)}
.quote{margin:0;border-top:2px solid var(--ink);padding-top:14px}
.quote+.quote{margin-top:32px}
.quote blockquote{margin:10px 0 0;font:400 22px/1.4 var(--display)}
.quote figcaption{margin-top:12px;font-size:15px}
.quote figcaption .note{display:block;margin-top:4px}
.quote.placeholder{border:1.5px dashed var(--ink-3);border-radius:6px;padding:18px}
.quote.placeholder blockquote{font:400 16px/1.55 var(--body);color:var(--ink-2)}
.opt{font-weight:400;color:var(--ink-3)}
label.consent{display:flex;gap:10px;align-items:flex-start;font-weight:400;font-size:15px;margin:0;cursor:pointer}
label.consent input{width:auto;margin:5.5px 0 0;accent-color:var(--route);flex:none}
form{display:grid;gap:16px}
.row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
label{display:block;font-size:14px;font-weight:600;margin-bottom:6px}
input,select,textarea{width:100%;font:inherit;font-size:16px;color:var(--ink);background:var(--paper);border:1.5px solid var(--rule);border-radius:6px;padding:11px 12px}
input:focus,select:focus,textarea:focus{border-color:var(--ink);outline:none}
textarea{display:block;min-height:110px;resize:vertical}
select{height:calc(1.6em + 24px)}  /* same height as the text fields */
.checks{display:flex;flex-wrap:wrap;gap:8px}
.checks label{font-weight:500;font-size:15px;display:inline-flex;gap:8px;align-items:center;border:1.5px solid var(--rule);border-radius:999px;padding:7px 12px;margin:0;cursor:pointer}
.checks input{width:auto;accent-color:var(--route);margin:0}
.checks label:has(input:focus-visible),label.consent:has(input:focus-visible){outline:2px solid var(--route);outline-offset:2px}
.formmsg{font-size:15px;color:var(--ink-2)}
form>.formmsg:empty{position:absolute}  /* an empty status line takes no row, so a form ends at its button */
.formmsg.ok{color:var(--ink);border-left:3px solid var(--route);padding-left:12px}
.small{font-size:14px;color:var(--ink-3)}
.steps.next{grid-template-columns:1fr;margin-top:12px}  /* What happens next, one step per row */
form .note+.small{margin-top:6px}

footer{border-top:1px solid var(--ink);margin-top:0}
footer .w{display:flex;gap:8px 24px;flex-wrap:wrap;align-items:baseline;justify-content:center;text-align:center;padding-block:28px 40px;font-size:14px;color:var(--ink-3)}  /* centred (Mario, 30 Oct 2026) */
footer a{color:var(--ink-2)}

/* privacy page */
.doc{max-width:720px;padding-block:56px 72px}
.doc h1{font-size:clamp(36px,5vw,52px);line-height:1.05;margin:14px 0 22px}  /* same spacing as the home page heading */
.doc h2{font-size:26px;line-height:1.2;margin:44px 0 12px;color:var(--route)}
.doc p:not(.note),.doc li{color:var(--ink-2)}
.doc .back{margin-top:24px}
.addr{user-select:all}
.doc :is(p,ul)+:is(p,ul){margin-top:12px}
.doc ul{margin:0;padding-left:20px}
.doc li+li{margin-top:6px}

/* Vertical alignment pass (Mario, 30 Oct 2026). Each section label sits on the baseline of its heading, and cards
   in a row share their inner rows, so headings, text and "What you do" line up across the row even when one wraps. */
.ph{align-items:baseline}
.body.fit>div,.fees>div{display:grid;grid-row:span 2;grid-template-rows:subgrid;row-gap:0}
.body.fit,.fees{grid-auto-rows:auto}
#route .steps>li{display:grid;grid-row:span 5;grid-template-rows:subgrid;row-gap:0;align-content:start}
.roles>div{display:grid;grid-row:span 3;grid-template-rows:subgrid;row-gap:0}

/* Motion (Mario approved all six, 30 Oct 2026). One orchestrated moment, the route drawing itself on the map and the
   elevation profile, plus quiet supporting touches. Nothing hides content in the first screen, and all of it switches off
   under reduced motion. */
:root{--ease:cubic-bezier(.2,.7,.2,1)}
@media (prefers-reduced-motion:no-preference){
  /* 1. hero: a red underline sweeps under "past the crux." once on load. It runs freely under "past", then from the start of
     "the" to the end of the "x" it struggles: letter by letter, slower each time, pausing and twice slipping back a little,
     before topping out on the full stop (Mario, 30 Oct 2026). Stops sit at the letter edges in Caladea italic (measured). */
  .hero h1 em{background:linear-gradient(var(--route),var(--route)) 0 92%/0 2px no-repeat;animation:sweep 5.4s .5s both}
  @keyframes sweep{
    0%{background-size:0 2px;animation-timing-function:cubic-bezier(.3,.1,.4,1)}
    10%{background-size:35.8% 2px;animation-timing-function:cubic-bezier(.5,0,.3,1)}
    16%,19%{background-size:41.9% 2px;animation-timing-function:cubic-bezier(.5,0,.3,1)}
    26%,29%{background-size:51.7% 2px;animation-timing-function:cubic-bezier(.5,0,.3,1)}
    36%{background-size:59.8% 2px;animation-timing-function:cubic-bezier(.5,0,.3,1)}
    40%,44%{background-size:63.7% 2px;animation-timing-function:cubic-bezier(.5,0,.3,1)}
    51%,55%{background-size:71.7% 2px;animation-timing-function:cubic-bezier(.4,0,.6,1)}
    59%{background-size:70.4% 2px;animation-timing-function:cubic-bezier(.5,0,.3,1)}
    66%,71%{background-size:78.7% 2px;animation-timing-function:cubic-bezier(.5,0,.3,1)}
    79%,83%{background-size:88.5% 2px;animation-timing-function:cubic-bezier(.4,0,.6,1)}
    86%{background-size:87.3% 2px;animation-timing-function:cubic-bezier(.5,0,.3,1)}
    94%,96%{background-size:96.8% 2px;animation-timing-function:cubic-bezier(.2,.7,.2,1)}
    100%{background-size:100% 2px}
  }
  /* 2. sections below the first screen rise in gently as they arrive, siblings a beat apart */
  .mo .rv{transition:opacity .7s var(--ease),transform .7s var(--ease)}
  .mo .rv.pre{opacity:0;transform:translateY(14px)}
  /* 3. the red rule over each stage card draws left to right */
  .mo #route .steps>li{position:relative;border-top-color:transparent}
  .mo #route .steps>li::before{content:"";position:absolute;left:0;right:0;top:-2px;height:2px;background:var(--route);transform-origin:left;transition:transform .9s .25s var(--ease)}
  .mo #route .steps>li.m::before{top:-3px;height:3px}
  .mo #route .steps>li.pre::before{transform:scaleX(0)}
  /* 4. the elevation profile: the line climbs, then the step markers come up in order */
  /* (the line, the red Stage 2 section and the markers are driven together by the script, so the red never runs ahead of the black) */
  .mo .profile .bands polygon{transition:opacity 1s .2s ease}
  .mo .profile.pre .bands polygon{opacity:0}
  /* 5. "How it works" opens with a short fade instead of a jump */
  .steps8[open] ol{animation:unfold .35s var(--ease)}
  @keyframes unfold{from{opacity:0;transform:translateY(-4px)}}
  /* 6. hover: buttons lift a pixel, header links get a red rule that grows from the left */
  .btn{transition:transform .2s var(--ease),box-shadow .2s var(--ease),background-color .2s,filter .2s}
  .btn:hover{transform:translateY(-1px);box-shadow:0 4px 12px -6px rgba(27,31,34,.35)}
  .btn:active{transform:none;box-shadow:none}
  .top .nav a:not(.btn){background:linear-gradient(var(--route),var(--route)) 0 100%/0 1.5px no-repeat;transition:background-size .3s var(--ease),color .2s;padding-bottom:2px;margin-bottom:-2px}
  .top .nav a:not(.btn):hover{background-size:100% 1.5px}
  /* 7. the hero intro and every section intro stream in like an AI answer; the untyped rest holds its place so nothing moves (Mario, 30 Oct 2026).
     The caret is a zero-width mark, so it never pushes a word onto the next line as it travels. */
  .tw-rest{color:transparent}
  .tw-caret{position:relative}
  .tw-caret::after{content:"";position:absolute;left:-1px;top:.12em;width:2px;height:1.05em;background:var(--route);animation:caret 1s steps(1) infinite}
  .tw-caret.done::after{animation:caret 1s steps(1) 3 forwards,fade .4s 3s forwards}
  @keyframes caret{50%{opacity:0}}
  @keyframes fade{to{opacity:0}}
}
/* until the script takes the intro over, keep it blank so it doesn't flash in full first; if the script never arrives it shows after 2.5 s */
@media (prefers-reduced-motion:no-preference) and (scripting:enabled){
  .hero .lede:not(.tw){animation:twwait 0s 2.5s backwards}
  @keyframes twwait{from{color:transparent}}
}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media print{.tw-rest{color:inherit!important}.tw-caret,.tw-tail{visibility:visible!important}.tw-caret{display:none}}  /* a printed page shows every intro in full */

@media (max-width:900px){
  .hero .w{grid-template-columns:1fr;padding-block:40px}
  .mapbox{max-width:560px;width:100%;margin-inline:auto}
  .ph{grid-template-columns:1fr;gap:10px}
  .body{margin-left:0}
  .body.fit,.fees{grid-template-columns:1fr}
  .svc li,.body.svc li{grid-template-columns:1fr;gap:6px}
  .steps{grid-template-columns:1fr}
  .roles{grid-template-columns:1fr}
  .roles div+div{border-left:0;border-top:1px solid var(--rule)}
  .about,.about .meta,.book,.cv,.reviews{grid-template-columns:1fr;gap:28px}
  .book{gap:40px}
  .doc{padding-top:40px}
  .portrait{max-width:180px}
  .nav a:not(.btn){display:none}
}
@media (max-width:520px){
  body{font-size:16px}
  .profile .pitches text{font-size:24px}  /* the profile scales down a lot on phones */
  .steps{grid-template-columns:1fr}
  .row{grid-template-columns:1fr}
  section.pitch>.w{padding-block:52px}
  .doc{padding-bottom:52px}
}
