/* northstage.io — restyled 2026-10-06. Calm cool paper, Domine headings over Source Sans 3 text,
   and a single accent (teal on light, amber on dark) that appears as an EDGE (card left edges,
   outlines, focus rings, one filled button) and never as a coloured headline word. Mobile first,
   light and dark both mandatory, targets at least 44px. */

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--graphite);font-family:var(--body);
  font-size:clamp(1.06rem,1rem + .3vw,1.24rem);line-height:1.58;-webkit-font-smoothing:antialiased}
img{max-width:100%}
iframe{max-width:100%}
a{color:var(--plan)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
:focus-visible{outline:2px solid var(--plan);outline-offset:3px}
.mono{font-family:var(--mono);font-size:.84rem;letter-spacing:.02em}

/* Real bug, found live on an iPhone (Ivo's own screenshot, 2026-09-24): every card grid on this
   site is a <ul> with `list-style:none`, which suppresses the bullet in Chrome/Firefox but is
   NOT reliable in Safari once the <li> becomes a grid/flex item -- WebKit can still paint the
   marker box regardless of the ancestor's list-style. The other reason NOT to lean on
   `list-style:none` alone even where it visually works: Safari deliberately strips list
   semantics from the accessibility tree the moment list-style is none, which is a real a11y
   regression, not just a visual one. The correct fix targets the marker directly and works
   everywhere, keeping the list semantics intact for screen readers: */
.frames li::marker, .steps li::marker, .testi-grid li::marker{content:""}

/* ── header ─────────────────────────────────────────────────────────────────────────────────── */
.site{display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:20px clamp(20px,5vw,64px);border-bottom:1px solid var(--rule)}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none;color:var(--graphite)}
.brand svg{width:20px;height:20px;color:var(--plan)}
.brand span{font-family:var(--display);font-weight:600;font-size:1.12rem;letter-spacing:0}
.site nav{display:flex;gap:4px}
.site nav a{font-family:var(--mono);font-size:.84rem;font-weight:600;text-decoration:none;color:var(--mid);
  min-height:44px;min-width:44px;display:inline-grid;place-items:center;padding:0 10px;
  border:1px solid transparent;border-radius:9999px}
.site nav a[aria-current]{color:var(--graphite);border-color:var(--rule);background:var(--panel);border-radius:9999px}

/* ── hero ───────────────────────────────────────────────────────────────────────────────────── */
.hero{padding:clamp(40px,6vw,76px) clamp(20px,5vw,64px) clamp(30px,4vw,48px)}
.hero-in{max-width:1180px;margin:0 auto;display:grid;gap:clamp(28px,4vw,56px);
  grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr);align-items:center}
/* .solo: a page with no live "proof" tile to put beside the words — drop to one column instead of
   leaving an empty second cell. Used by the migration page; the homepage keeps the two-column grid. */
.hero-in.solo{grid-template-columns:1fr;max-width:760px}
.hero-words{min-width:0}
.hero-proof{margin:0;min-width:0}
.hero-proof .glass{aspect-ratio:1280/1000}
.hero-proof figcaption{margin-top:10px;color:var(--mid);font-family:var(--mono);font-size:.72rem}
.eyebrow{color:var(--accent-text);font-weight:600;text-transform:uppercase;letter-spacing:.12em;margin:0 0 22px}
h1{font-family:var(--display);font-weight:600;letter-spacing:-.012em;line-height:1.1;
  font-size:clamp(2.1rem,1.3rem + 2.7vw,3.5rem);margin:0 0 22px;max-width:15ch}
h1 em{font-style:normal;box-shadow:inset 0 -.14em 0 var(--plan)}
.lede{font-size:clamp(1.02rem,.98rem + .3vw,1.16rem);color:var(--lede);max-width:48ch;margin:0 0 28px}
.cta{display:inline-flex;align-items:center;min-height:48px;font-family:var(--body);font-weight:600;font-size:1.06rem;
  background:var(--plan);color:var(--paper);text-decoration:none;padding:0 30px;border-radius:12px;
  border:2px solid var(--plan)}
.cta:hover{background:transparent;color:var(--graphite)}
.cta:focus-visible{outline-offset:4px}
.cta-note{color:var(--mid);margin:14px 0 0}

/* ── the contact sheet: the signature element ───────────────────────────────────────────────── */
.sheet{padding:clamp(30px,4vw,54px) clamp(20px,5vw,64px) clamp(56px,8vw,96px);
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.sheet-head{max-width:1180px;margin:0 auto clamp(26px,4vw,40px);
  display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:12px}
h2{font-family:var(--display);font-weight:600;letter-spacing:-.008em;
  font-size:clamp(1.5rem,1.2rem + 1.1vw,2.15rem);margin:0;line-height:1.12}
.sheet-key{color:var(--mid);margin:0}
.frames{list-style:none;margin:0 auto;padding:0;max-width:1180px;
  display:grid;gap:clamp(20px,2.4vw,32px);
  /* auto-FILL leaves empty tracks when there are fewer items than columns — with two drafts that
     is a visible hole. auto-FIT collapses the empty tracks so the pair spans the row. */
  grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.frame{position:relative}
.frame-n{position:absolute;top:-9px;left:-9px;z-index:2;background:var(--paper);
  color:var(--mid);padding:0 6px}
/* the frame itself: a real page behind glass, scaled down. 1280px of site squeezed into the tile,
   which is why the transform and the fixed iframe width both have to be here. */
.glass{position:relative;aspect-ratio:1280/1000;overflow:hidden;background:#fff;border-radius:12px;
  border:1px solid var(--rule);box-shadow:0 1px 2px rgba(20,20,19,.05)}
/* A real page rendered at desktop width and scaled to fit its tile. The scale CANNOT be a fixed
   number: the hero frame and the sheet tiles are different widths and both change with the
   viewport, so one hard-coded factor leaves the page floating in a third of its box. --s is set
   per element by the scaler in baseof, and 1280 is the design width being scaled FROM. */
.glass iframe{position:absolute;top:0;left:0;
  /* max-width:none is LOAD-BEARING. The global img{max-width:100%}
iframe{max-width:100%} reset silently caps this
     at the tile width, so the iframe renders the site at ~370px — a MOBILE layout — and the scale
     then shrinks that to ~107px of unreadable content. The explicit width is overridden without
     any error and the frames simply come out blank. */
  max-width:none;width:1280px;height:1000px;border:0;
  transform:scale(var(--s,.2917));transform-origin:0 0;pointer-events:none;filter:saturate(.96)}
.frame-hit{position:absolute;inset:0;z-index:1}
.frame:hover .glass{border-color:var(--plan)}
.frame-what{margin:12px 0 0;font-size:1rem}
.frame-note{margin:0;color:var(--mid)}
/* the risk, and the reason it is worth taking: the misses are labelled. Red is reserved for it. */
.frame-note.miss{color:var(--mark)}

/* ── how it works ───────────────────────────────────────────────────────────────────────────── */
.how{padding:clamp(56px,8vw,104px) clamp(20px,5vw,64px)}
/* .how has no border by default because on the homepage it always follows .sheet, which already
   carries a border-bottom. The migration page stacks two .how-shaped sections back to back with
   nothing bordered between them; .rule-top draws the missing line rather than letting them blend. */
.how.rule-top{border-top:1px solid var(--rule)}
.how-in{max-width:1180px;margin:0 auto}
.how h2{margin-bottom:clamp(26px,4vw,44px)}
.steps{list-style:none;margin:0;padding:0;display:grid;gap:0;counter-reset:none}
/* Same open timeline as the homepage (Ivo, 2026-10-06: the edged cards on the subpages were the old look). */
.steps li{position:relative;background:none;border:0;border-radius:0;padding:0 0 34px 64px}
.steps li::before{content:"";position:absolute;left:21px;top:44px;bottom:0;width:1px;background:var(--rule)}
.steps li:last-child{padding-bottom:0}.steps li:last-child::before{display:none}
.step-n{position:absolute;left:0;top:0;width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
  background:var(--panel);border:1px solid var(--rule);color:var(--accent-text);font-size:.8rem;margin:0}
.steps h3{font-family:var(--display);font-weight:600;font-size:1.25rem;margin:0 0 6px;letter-spacing:-.008em;padding-top:8px}
.steps p{margin:0;color:var(--mid);font-size:.99rem;max-width:44ch}
@media (min-width:900px){
  .steps{grid-template-columns:repeat(3,1fr);gap:40px}
  .steps li{padding:64px 0 0}
  .steps li::before{left:44px;right:-40px;top:21px;bottom:auto;width:auto;height:1px}
  .steps h3{padding-top:0}
}

/* Homepage process as a timeline (Ivo, 2026-10-06): one line, numbered nodes. Vertical on phones,
   horizontal from 900px. The subpages' .steps use the same look. */
.timeline{list-style:none;margin:0;padding:0;display:grid;gap:0;position:relative}
.timeline li{position:relative;padding:0 0 34px 64px}
.timeline li::before{content:"";position:absolute;left:21px;top:44px;bottom:0;width:1px;background:var(--rule)}
.timeline li:last-child{padding-bottom:0}.timeline li:last-child::before{display:none}
.tl-dot{position:absolute;left:0;top:0;width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
  background:var(--panel);border:1px solid var(--rule);color:var(--accent-text);font-size:.8rem}
.tl-meta{display:block;color:var(--accent-text);font-size:.78rem;margin:2px 0 6px;text-transform:none}
.timeline h3{font-family:var(--display);font-weight:600;font-size:1.25rem;margin:0 0 6px;letter-spacing:-.008em}
.timeline p{margin:0;color:var(--mid);font-size:.99rem;max-width:44ch}
@media (min-width:900px){
  .timeline{grid-template-columns:repeat(5,1fr);gap:28px}
  .timeline li{padding:64px 0 0}
  .timeline li::before{left:44px;right:-28px;top:21px;bottom:auto;width:auto;height:1px}
}

/* ── services ───────────────────────────────────────────────────────────────────────────────── */
.offer{padding:clamp(46px,7vw,92px) clamp(20px,5vw,64px)}
.offer-in{max-width:1180px;margin:0 auto}
.offer h2{margin-bottom:clamp(20px,3vw,34px)}
/* Open list, not cards (Ivo, 2026-10-06): numbered rows split by hairlines, two columns on desktop. */
.services{margin:0;padding:0;display:grid;gap:0 clamp(32px,5vw,72px);grid-template-columns:repeat(auto-fit,minmax(min(100%,420px),1fr));counter-reset:svc}
.services div{counter-increment:svc;display:grid;grid-template-columns:2.4rem 1fr;column-gap:6px;
  padding:22px 0 26px;border-top:1px solid var(--rule);align-content:start}
.services div::before{content:counter(svc,decimal-leading-zero);grid-row:1/3;font-family:var(--mono);
  font-size:.8rem;letter-spacing:.06em;color:var(--accent-text);padding-top:.45rem}
.services dt{font-family:var(--display);font-weight:600;font-size:1.25rem;line-height:1.3;margin-bottom:6px}
.services dt a{text-decoration:none;color:var(--graphite);background:linear-gradient(var(--plan),var(--plan)) 0 100%/0 2px no-repeat;
  transition:background-size .2s}
.services dt a:hover,.services dt a:focus-visible{background-size:100% 2px}
.services dt a::after{content:" \2192";color:var(--accent-text)}
.services dd{margin:0;color:var(--mid);font-size:1rem;line-height:1.55;max-width:34rem}

/* ── testimonials ───────────────────────────────────────────────────────────────────────────────
   Renders only when data/testimonials.yaml holds a real, approved entry -- see that file and
   layouts/partials/testimonials.html for why. The avatar has three tiers, in order of what's
   actually been consented to: a personal photo (rare, needs explicit sign-off), a company logo
   (the safe default once that alone is OK'd), or a plain initials monogram (needs nobody's
   permission at all) -- never left blank, so a card is never missing its "who said this" anchor
   just because a photo wasn't consented to. */
.testi{padding:clamp(46px,7vw,92px) clamp(20px,5vw,64px);border-top:1px solid var(--rule)}
.testi-in{max-width:1180px;margin:0 auto}
.testi-in h2{margin-bottom:clamp(24px,3vw,38px)}
.testi-grid{list-style:none;margin:0;padding:0;display:grid;gap:20px;
  grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.testi-card{background:var(--panel);border-radius:14px;border:1px solid var(--rule);padding:26px 26px 22px}
.testi-quote{font-style:italic;font-size:1.05rem;line-height:1.5;margin:0 0 20px;color:var(--graphite)}
.testi-quote::before{content:"\201C";color:var(--plan);font-family:var(--display);
  font-style:normal;font-size:1.5em;line-height:0;vertical-align:-.14em;margin-right:1px}
.testi-who{display:flex;align-items:center;gap:12px}
.testi-avatar{width:44px;height:44px;border-radius:9999px;flex:none;object-fit:cover;background:var(--paper)}
.testi-avatar-logo{object-fit:contain;padding:7px;border:1px solid var(--rule)}
.testi-avatar-mono{display:grid;place-items:center;font-family:var(--display);font-weight:600;
  font-size:.9rem;color:var(--plan);background:var(--paper);border:1px solid var(--rule)}
.testi-name{margin:0;font-family:var(--display);font-weight:600;font-size:.96rem}
.testi-role{margin:2px 0 0;color:var(--mid)}

/* ── close ──────────────────────────────────────────────────────────────────────────────────── */
.close{padding:clamp(60px,9vw,112px) clamp(20px,5vw,64px);border-top:1px solid var(--rule)}
.close-in{max-width:760px;margin:0 auto;text-align:center}
.close h2{margin-bottom:18px}
.close .lede{margin-left:auto;margin-right:auto}

/* ── pages + footer ─────────────────────────────────────────────────────────────────────────── */
.page{padding:clamp(48px,7vw,92px) clamp(20px,5vw,64px)}
.page-in{max-width:660px;margin:0 auto}
.page h1{font-size:clamp(2rem,1.5rem + 2vw,3rem);max-width:none}
.page h2{margin:34px 0 12px}
.site-foot{border-top:1px solid var(--rule);padding:26px clamp(20px,5vw,64px)}
.foot-in{max-width:1180px;margin:0 auto;display:flex;justify-content:space-between;
  flex-wrap:wrap;gap:10px;color:var(--mid)}
.foot-in a{color:var(--mid)}

@media (max-width:900px){
  .hero-in{grid-template-columns:1fr}
  .hero-proof{order:-1}
}

@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}


/* ── light / dark / auto ──────────────────────────────────────────────────────────────────────
   Three states, not two. "auto" is the ABSENCE of data-theme, so the media query below stays in
   charge and anyone who never touches the control gets whatever their operating system already
   says. The tokens themselves are injected at :root from hugo params; both selectors here are
   more specific than a bare :root, so they win without !important. */
:root{color-scheme:light;--lede:#3a4647;--accent-text:#0b6b63}

@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --paper:#16191b; --panel:#1f2427; --graphite:#eef2f1;
    --mid:#a7b1b0; --rule:#2f3639; --plan:#f2b33d; --mark:#f2b33d; --lede:#c9d1d0; --accent-text:#f2b33d;
  }
}
:root[data-theme="dark"]{
  color-scheme:dark;
  --paper:#16191b; --panel:#1f2427; --graphite:#eef2f1;
    --mid:#a7b1b0; --rule:#2f3639; --plan:#f2b33d; --mark:#f2b33d; --lede:#c9d1d0; --accent-text:#f2b33d;
}

/* THE ONE REAL PROBLEM WITH DARK MODE HERE. The drafts are real client sites with white
   backgrounds, and they must NOT be inverted — that would misrepresent what the client's site
   actually looks like. Left alone on a dark page they read as holes punched in the layout.
   So each frame gets a paper matte: the bright page becomes a mounted print on a dark desk
   rather than a light leak. Dimmed slightly at rest, full brightness when you look at it. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .glass{background:#eef2f1;border-color:#3b4346;padding:6px}
  :root:not([data-theme="light"]) .glass iframe{border-radius:6px;filter:brightness(.9) saturate(.94)}
  :root:not([data-theme="light"]) .frame:hover .glass iframe,
  :root:not([data-theme="light"]) .glass:focus-within iframe{filter:none}
}
:root[data-theme="dark"] .glass{background:#eef2f1;border-color:#3b4346;padding:6px}
:root[data-theme="dark"] .glass iframe{border-radius:6px;filter:brightness(.9) saturate(.94)}
:root[data-theme="dark"] .frame:hover .glass iframe,
:root[data-theme="dark"] .glass:focus-within iframe{filter:none}

/* the control */
.head-right{display:flex;align-items:center;gap:10px}
.theme-btn{display:grid;place-items:center;width:32px;height:32px;padding:0;cursor:pointer;
  background:transparent;border:1px solid transparent;border-radius:9999px;color:var(--mid)}
.theme-btn:hover{color:var(--graphite);border-color:var(--rule);background:var(--panel)}
.theme-btn svg{width:16px;height:16px;grid-area:1/1;display:none}
:root[data-mode="auto"]  .theme-btn .i-auto,
:root[data-mode="light"] .theme-btn .i-light,
:root[data-mode="dark"]  .theme-btn .i-dark{display:block}
/* before the cycler runs, show the auto glyph rather than nothing */
:root:not([data-mode]) .theme-btn .i-auto{display:block}

/* the matte offsets the iframe by its padding, so the scaler must measure the inner box */
.glass{box-sizing:border-box}

/* Filled button keeps readable text on both accents: paper on teal, dark paper on amber. */
.cta{color:var(--paper)}
.cta:hover{color:var(--graphite)}

/* ── about page ─────────────────────────────────────────────────────────────────────────────── */
/* Restyled 2026-10-06 to match the rest of the site: calm panel and hairline, the accent used only
   as an edge (portrait frame, list rule), no hard offset shadow. */
.about{padding:clamp(40px,6vw,88px) clamp(20px,5vw,64px);overflow-x:clip}
.about-in{max-width:1040px;margin:0 auto;display:grid;gap:clamp(28px,5vw,64px);
  grid-template-columns:minmax(0,1fr) minmax(0,1.7fr);align-items:start}
.portrait{margin:0;width:min(100%,22rem);aspect-ratio:1;border-radius:14px;overflow:hidden;
  border:1px solid var(--rule);border-bottom:4px solid var(--plan);background:var(--panel);
  position:sticky;top:24px}
.portrait img{display:block;width:100%;height:100%;object-fit:cover}
.portrait .p-dark{display:none}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .portrait .p-light{display:none}
  :root:not([data-theme="light"]) .portrait .p-dark{display:block}
}
:root[data-theme="dark"] .portrait .p-light{display:none}
:root[data-theme="dark"] .portrait .p-dark{display:block}
:root[data-theme="light"] .portrait .p-light{display:block}
:root[data-theme="light"] .portrait .p-dark{display:none}
.about h1{max-width:none;margin-bottom:18px}
.about-body>p:first-of-type{font-size:1.2rem;line-height:1.5;margin:0 0 8px;max-width:38rem}
.about-body h2{font-size:clamp(1.25rem,2.4vw,1.55rem);margin:clamp(28px,4vw,40px) 0 12px}
.about-body ul{margin:0;padding:0;list-style:none;border-top:1px solid var(--rule)}
.about-body li{border-bottom:1px solid var(--rule);padding:14px 0 14px 16px;position:relative;max-width:42rem}
.about-body li::marker{content:""}
.about-body li::before{content:"";position:absolute;left:0;top:18px;bottom:18px;width:3px;border-radius:2px;background:var(--plan)}
.about-body li strong{font-family:var(--display);font-weight:600}
.about-cta{margin-top:clamp(28px,4vw,40px);display:flex;flex-wrap:wrap;gap:14px 22px;align-items:center}
.about-cta .alt{color:var(--graphite);font-weight:600}
@media (max-width:760px){.about-in{grid-template-columns:1fr}.portrait{width:min(100%,17rem);position:static}}
.foot-links{display:flex;gap:18px;flex-wrap:wrap}
.foot-links a{min-height:44px;display:inline-flex;align-items:center}

/* Header fits a 390px phone: targets stay at 40px or more (WCAG 2.2 minimum is 24px). */
.site nav{gap:0}
.site nav a{min-width:40px;min-height:40px;padding:0 8px}
.theme-btn{width:40px;height:40px}
@media (max-width:480px){.site{padding-left:16px;padding-right:16px;gap:8px}.head-right{gap:2px}}

/* Centred hero: landscape backdrop in the brand colours, the real draft floating on it. */
.hero-c{position:relative;isolation:isolate;overflow:hidden;padding-bottom:clamp(20px,4vw,56px)}
.hero-bg{position:absolute;inset:0 0 auto 0;z-index:-1;display:block;height:min(100%,980px)}
.hero-bg img{width:100%;height:100%;object-fit:cover;object-position:50% 100%}
.hero-bg .bg-dark{display:none}
.hero-c .hero-in{grid-template-columns:1fr;max-width:1000px;text-align:center;gap:clamp(32px,5vw,64px)}
.hero-c .hero-words{display:flex;flex-direction:column;align-items:center;padding-top:clamp(8px,3vw,40px)}
.hero-c h1{font-size:clamp(2.25rem,1.2rem + 4.4vw,4.4rem);max-width:15ch}
.hero-c .lede{max-width:40rem}
.hero-mac{margin:0 auto;width:min(100%,920px)}
.hero-mac .lid{background:#0c0e0f;border-radius:18px 18px 4px 4px;padding:clamp(6px,1.2vw,14px) clamp(6px,1.2vw,14px) clamp(8px,1.5vw,18px);
  box-shadow:0 0 0 1.5px #3a4144 inset,0 40px 90px -25px rgba(0,0,0,.55);position:relative}
.hero-mac .lid::before{content:"";position:absolute;top:clamp(2px,.5vw,6px);left:50%;width:5px;height:5px;margin-left:-2.5px;border-radius:50%;background:#2a3033}
.hero-mac .lid img{display:block;width:100%;height:auto;aspect-ratio:1440/900;border-radius:5px;background:#f3ece2}
.hero-mac .base{height:clamp(8px,1.6vw,16px);margin:0 -4%;border-radius:0 0 22px 22px;
  background:linear-gradient(#cfd5d6,#9aa2a4);box-shadow:0 18px 30px -12px rgba(0,0,0,.5);position:relative}
.hero-mac .base::before{content:"";position:absolute;top:0;left:50%;width:16%;height:55%;transform:translateX(-50%);border-radius:0 0 10px 10px;background:#7d8587}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .hero-bg .bg-light{display:none}
  :root:not([data-theme="light"]) .hero-bg .bg-dark{display:block}
}
:root[data-theme="dark"] .hero-bg .bg-light{display:none}
:root[data-theme="dark"] .hero-bg .bg-dark{display:block}
:root[data-theme="light"] .hero-bg .bg-light{display:block}
:root[data-theme="light"] .hero-bg .bg-dark{display:none}


.hero-c .cta-note{color:var(--lede)}

.shot{margin:0;border-radius:14px;overflow:hidden;border:1px solid var(--rule);background:var(--panel)}
.shot img{display:block;width:100%;height:auto;aspect-ratio:1440/900}
.frames{grid-template-columns:repeat(auto-fit,minmax(min(100%,400px),1fr))}
.frame-note{text-transform:none}

/* ── booking page (client of the booking API) ───────────────────────────────────────────────── */
.book .lede{margin-bottom:28px}
.book-form{display:grid;gap:22px;max-width:640px}
.bk-block{border:0;padding:0;margin:0}.bk-block legend{font-family:var(--display);font-size:1.1rem;margin-bottom:10px;padding:0}
.bk-chips{display:flex;flex-wrap:wrap;gap:8px}
.bk-chip{font:inherit;color:var(--graphite);background:transparent;border:1px solid var(--rule);border-radius:999px;padding:9px 16px;cursor:pointer}
.bk-chip:hover{border-color:var(--accent-text)}
.bk-chip[aria-checked=true]{background:var(--plan);border-color:var(--plan);color:var(--paper)}
.bk-chip:focus-visible,.bk-fields input:focus-visible,.bk-fields textarea:focus-visible{outline:2px solid var(--plan);outline-offset:2px}
.bk-fields{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr))}
.bk-fields label{display:grid;gap:6px;font-size:.92rem;color:var(--mid)}
.bk-fields input,.bk-fields textarea{font:inherit;color:var(--graphite);background:var(--panel);border:1px solid var(--rule);border-radius:10px;padding:11px 13px}
.bk-wide{grid-column:1/-1}.bk-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.bk-check{display:flex;gap:10px;align-items:flex-start;font-size:.93rem;color:var(--mid)}.bk-check input{margin-top:4px}
.bk-hint{color:var(--mid);font-size:.8rem;text-transform:none;margin:8px 0 0}
.bk-msg{min-height:1.4em;color:var(--accent-text);margin:0}
.bk-done dl{display:grid;grid-template-columns:auto 1fr;gap:6px 18px;margin:18px 0}.bk-done dt{color:var(--mid)}.bk-done dd{margin:0}

/* ── contact page: hero, then the About list ──────────────────────────────────────────────── */
.contact-more{padding:clamp(40px,6vw,80px) clamp(20px,5vw,64px)}
.contact-in{max-width:760px;margin:0 auto}
.contact-in h2:first-child{margin-top:0}

/* example cards: image plus one quiet caption link (IVO-42) */
.frame-what a{color:var(--graphite);text-decoration:none;font-weight:600}
.frame-what a span{color:var(--accent-text)}.frame-what a:hover,.frame-what a:focus-visible{text-decoration:underline;text-underline-offset:4px}
.shot a{display:block}

/* ── contact: call or message (IVO-43) ─────────────────────────────────────────────────────────── */
.ct-choose,.ct-msg{padding:clamp(34px,5vw,64px) clamp(20px,5vw,64px)}
.ct-in{max-width:880px;margin:0 auto}
.ct-h{font-family:var(--display);font-weight:400;font-size:clamp(1.5rem,1.2rem + 1.4vw,2.1rem);margin:0 0 20px}
.ct-routes{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
.ct-route{display:grid;gap:8px;align-content:start;text-decoration:none;color:var(--graphite);background:var(--panel);
  border:1px solid var(--rule);border-radius:16px;padding:24px 24px 20px;min-height:44px}
.ct-route strong{font-family:var(--display);font-weight:600;font-size:1.25rem}
.ct-route span{color:var(--mid);font-size:1rem}
.ct-go{font-style:normal;font-weight:600;color:var(--accent-text);margin-top:6px}
.ct-route:hover,.ct-route:focus-visible{border-color:var(--plan)}
.ct-form{display:grid;gap:24px;max-width:760px}
.ct-types{border:0;padding:0;margin:0}.ct-types legend{font-family:var(--display);font-size:1.15rem;margin:0 0 12px;padding:0}
.ct-grid{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr))}
.ct-type{position:relative;display:block;cursor:pointer}
.ct-type input{position:absolute;opacity:0;inset:0;width:100%;height:100%;margin:0;cursor:pointer}
.ct-card{display:grid;gap:2px;min-height:64px;padding:14px 16px;background:var(--panel);border:1px solid var(--rule);border-radius:12px}
.ct-card strong{font-weight:600}.ct-card small{color:var(--mid);font-size:.88rem}
.ct-type:hover .ct-card{border-color:var(--plan)}
.ct-type input:checked+.ct-card{border-color:var(--plan);box-shadow:inset 4px 0 0 var(--plan);background:var(--paper)}
.ct-type input:focus-visible+.ct-card{outline:2px solid var(--plan);outline-offset:2px}
.ct-fields{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
.ct-fields label{display:grid;gap:6px;font-size:.96rem;color:var(--graphite)}
.ct-fields input,.ct-fields textarea{font:inherit;color:var(--graphite);background:var(--panel);border:1px solid var(--rule);border-radius:10px;padding:12px 14px;min-height:48px;width:100%}
.ct-fields input:focus-visible,.ct-fields textarea:focus-visible{outline:2px solid var(--plan);outline-offset:2px}
.ct-fields [aria-invalid=true]{border-color:var(--err,#b3261e)}
.ct-wide{grid-column:1/-1}.ct-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.ct-check{display:flex;gap:12px;align-items:flex-start;font-size:.98rem;min-height:44px}
.ct-check input{margin-top:5px;width:20px;height:20px;flex:none}
.ct-hint{color:var(--mid);font-size:.88rem;margin:6px 0 0;display:block}
.ct-err{color:var(--err,#b3261e);font-size:.9rem;margin:6px 0 0;display:block}
.ct-status{min-height:1.4em;margin:0;color:var(--err,#b3261e);font-weight:600}
.ct-done{max-width:640px;padding:26px 28px;border:1px solid var(--rule);border-radius:16px;background:var(--panel);box-shadow:inset 4px 0 0 var(--plan)}
.ct-done h3{font-family:var(--display);font-weight:400;font-size:1.6rem;margin:0 0 10px}
.ct-done:focus-visible{outline:2px solid var(--plan);outline-offset:3px}
.ct-more{margin-top:clamp(36px,5vw,56px)}
.ct-alt{margin:26px 0 0;color:var(--mid)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--err:#ff8a80}}
:root[data-theme="dark"]{--err:#ff8a80}
.ct-form[hidden],.ct-err[hidden],.ct-done[hidden]{display:none}

/* FAQ (IVO-44): one answer per block, each with its own anchor */
.faq-item{padding:20px 0;border-top:1px solid var(--rule);scroll-margin-top:24px}
.faq-item:first-child{border-top:0}
.faq-item h2{font-family:var(--display);font-weight:400;font-size:clamp(1.25rem,1.1rem + .7vw,1.6rem);margin:0 0 8px}
.faq-item h2 a{color:inherit;text-decoration:none}
.faq-item h2 a:hover,.faq-item h2 a:focus-visible{text-decoration:underline;text-underline-offset:4px}
.faq-item p{margin:0;max-width:62ch}
.faq-item:target{background:var(--panel);border-radius:12px;padding-left:16px;padding-right:16px}
.faq-list .how-in{max-width:760px;margin-inline:auto}

/* Two equal ways in: call or message (Perplexity 2026-10-06: equal weight, stacked on phones, 48px targets) */
.cta-row{display:flex;flex-wrap:wrap;gap:12px;align-items:stretch}
.cta-row .cta{justify-content:center;flex:1 1 220px}
.hero-c .cta-row{justify-content:center;width:100%;max-width:520px}
.close-in .cta-row{justify-content:center;max-width:520px;margin:0 auto}

/* ── IVO-45 usability pass (2026-10-06) ─────────────────────────────────────────────────────────
   Perplexity research (Material, Apple HIG, NN/g via service-site guides): one filled primary
   button per view with the alternative outlined; 4 to 6 plain menu items with the contact action
   set apart; numbers only for real sequences; whole rows as tap targets (44px or more). Pills
   follow the style references (cohere, duna, useportal). */
.cta{border-radius:9999px}
.cta.alt{background:transparent;color:var(--graphite);border-color:var(--plan)}
.cta.alt:hover{background:var(--panel);color:var(--graphite)}
.cta:not(.alt):hover{background:transparent;color:var(--graphite)}

/* balanced line breaks: no single orphan word on a heading or the eyebrow */
h1,h2,h3,.eyebrow{text-wrap:balance}

/* main menu: desktop only */
.site .main-nav{display:none}
@media (min-width:1120px){
  .site{gap:28px}
  .site .main-nav{display:flex;align-items:center;gap:2px;margin-left:auto}
  .site .main-nav a{white-space:nowrap;font-family:var(--body);font-size:.98rem;font-weight:500;color:var(--mid);text-decoration:none;
    min-height:44px;display:inline-flex;align-items:center;padding:0 12px;border-radius:9999px}
  .site .main-nav a:hover{color:var(--graphite);background:var(--panel)}
  .site .main-nav .nav-cta{margin-left:10px;color:var(--graphite);font-weight:600;border:1.5px solid var(--plan);padding:0 18px}
  .site .main-nav .nav-cta:hover{background:var(--panel)}
  .head-right{border-left:1px solid var(--rule);padding-left:12px}
}

/* services: not a sequence, so no 01..07; a linked row is one big tap target */
.services div{grid-template-columns:1fr;position:relative}
.services div::before{content:none}
.services dt a::before{content:"";position:absolute;inset:0}
.services div:has(dt a):hover dt a{background-size:100% 2px}
.services div:has(dt a:focus-visible){outline:2px solid var(--plan);outline-offset:4px;border-radius:6px}
.services dt a:focus-visible{outline:none}

/* FAQ: the list follows the intro directly */
.faq-list{padding-top:0}

/* footer: the map of every page */
.foot-in{align-items:flex-start;gap:14px 40px}
.foot-brand{margin:12px 0 0;font-family:var(--display);font-weight:600;color:var(--graphite)}
.foot-links{gap:0 20px;max-width:760px;justify-content:flex-end;font-size:.95rem}
@media (max-width:700px){.foot-in{flex-direction:column}.foot-links{justify-content:flex-start;gap:0 18px}}

/* ── guides (how-to articles, 2026-10-08) ──────────────────────────────────────────────────────
   Only existing tokens (paper, graphite, mid, rule, panel, plan, accent-text), so light and dark
   follow the rest of the site. Prose column of about 65 characters; the numbered steps reuse the
   round number node of the process timeline; code blocks wrap instead of scrolling so nothing
   can push the page wider on a phone. */
.guide h1{max-width:none}
.guide-back{margin:0 0 18px}
.guide-back a{display:inline-flex;align-items:center;min-height:44px;color:var(--mid);font-family:var(--mono);font-size:.84rem;text-decoration:none}
.guide-back a:hover,.guide-back a:focus-visible{color:var(--graphite);text-decoration:underline;text-underline-offset:4px}
.guide-meta{color:var(--mid);margin:14px 0 0}
.services dd.guide-meta{margin-top:8px;font-size:.84rem}
.offer.rule-top{border-top:1px solid var(--rule)}
.guide-wrap{padding:0 clamp(20px,5vw,64px) clamp(56px,8vw,96px)}
.guide-in{max-width:760px;margin:0 auto}
.guide-short{background:var(--panel);border:1px solid var(--rule);border-radius:12px;padding:22px clamp(18px,3vw,28px) 24px}
.guide-short h2{font-size:1.25rem;margin:0 0 10px}
.guide-short p{margin:0}
.guide-video{display:flex;align-items:center;gap:clamp(18px,4vw,36px);margin-top:20px;padding:22px clamp(18px,3vw,28px);background:var(--panel);border:1px solid var(--rule);border-radius:12px}
.guide-video-text{flex:1 1 0;min-width:0}
.guide-video h2{font-size:1.25rem;margin:0 0 10px}
.guide-video p{margin:0}
.guide-video video{flex:0 0 auto;display:block;width:min(100%,240px);max-width:100%;aspect-ratio:9/16;height:auto;border-radius:10px;background:var(--graphite)}
@media (max-width:640px){.guide-video{flex-direction:column;align-items:stretch}.guide-video video{align-self:center}}
.story-demo{margin:clamp(32px,5vw,48px) 0 0}
.story-demo-cta{margin-top:16px}
.story-transcript{margin:24px 0 0;border-top:1px solid var(--rule);padding-top:8px}
.story-transcript summary{display:flex;align-items:center;min-height:44px;cursor:pointer;font-weight:600;color:var(--graphite)}
.story-transcript summary:focus-visible{outline:2px solid var(--plan);outline-offset:4px;border-radius:6px}
.story-transcript p{max-width:65ch;margin:0 0 1em}
.guide-toc{margin:34px 0 0}
.guide-toc p{margin:0 0 6px;color:var(--mid);text-transform:uppercase;letter-spacing:.1em}
.guide-toc ul{list-style:none;margin:0;padding:0}
.guide-toc li::marker{content:""}
.guide-toc a{display:flex;align-items:center;min-height:40px;color:var(--graphite);text-decoration:none;border-top:1px solid var(--rule)}
.guide-toc li:last-child a{border-bottom:1px solid var(--rule)}
.guide-toc a:hover,.guide-toc a:focus-visible{color:var(--accent-text);text-decoration:underline;text-underline-offset:4px}

.guide-body{margin-top:clamp(8px,2vw,16px)}
.guide-body h2{margin:clamp(40px,6vw,60px) 0 14px;scroll-margin-top:24px;font-size:clamp(1.45rem,1.2rem + 1vw,1.9rem)}
.guide-body p,.guide-body li{max-width:65ch;overflow-wrap:break-word}
.guide-body p{margin:0 0 1em}
.guide-body a{color:var(--plan);text-underline-offset:3px;overflow-wrap:anywhere}
.guide-body a:hover{color:var(--graphite)}
.guide-body strong{font-weight:600}
.guide-body ul{margin:0 0 1.2em;padding-left:1.25em}
.guide-body ul li{margin:0 0 .5em}
.guide-body ol{list-style:none;margin:0 0 1.4em;padding:0}
.guide-body ol>li{position:relative;padding:0 0 28px 56px;margin:0}
.guide-body ol>li::marker{content:""}
.guide-body ol>li::before{counter-increment:gstep;content:counter(gstep);position:absolute;left:0;top:-2px;width:40px;height:40px;
  border-radius:50%;display:grid;place-items:center;background:var(--panel);border:1px solid var(--rule);
  color:var(--accent-text);font-family:var(--body);font-weight:600;font-size:1rem}
.guide-body ol>li::after{content:"";position:absolute;left:19.5px;top:44px;bottom:6px;width:1px;background:var(--rule)}
.guide-body ol>li:last-child{padding-bottom:0}.guide-body ol>li:last-child::after{display:none}
.guide-body ol{counter-reset:gstep}
.guide-body ol>li>p:first-child{margin-top:6px}
.guide-body ol>li>ul{margin-top:.6em}
.guide-body code,.guide-body pre{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em}
.guide-body code{background:var(--panel);border:1px solid var(--rule);border-radius:5px;padding:1px 5px;overflow-wrap:anywhere}
.guide-body pre{background:var(--panel);border:1px solid var(--rule);border-radius:10px;padding:14px 16px;margin:0 0 1.2em;
  white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.5;max-width:100%}
.guide-body pre code{background:none;border:0;padding:0;font-size:1em}
/* guide index: same 760px column as the hero above it, one hairline under the hero (not two) */
.guide-list .offer-in{max-width:760px}
.guide-list{padding-top:clamp(20px,3vw,36px)}
.guide-list .services{grid-template-columns:1fr}
.guide-list .services div:first-child{border-top:0}
.guide-list .services dt a::after{content:"\00a0\2192"}
/* hosting partner strip (Ivo, 2026-10-08): the partner's own wordmark in one colour, text colour in both themes */
.partner{padding:clamp(28px,4vw,48px) clamp(20px,5vw,64px);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.partner-in{max-width:1180px;margin:0 auto;display:flex;flex-wrap:wrap;align-items:center;gap:16px clamp(24px,4vw,56px)}
.partner-in p{margin:0}.partner-in p:last-child{color:var(--mid);max-width:34rem;min-width:0}
.partner-link{display:inline-flex;color:var(--graphite);padding:6px 0}
.partner-logo{display:block;height:30px;width:auto;max-width:100%}
.partner-link:focus-visible{outline:2px solid var(--plan);outline-offset:6px}
.partner-ik img{display:block;height:48px;width:auto;max-width:100%}
.partner-ik .ik-dark{display:none}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .partner-ik .ik-light{display:none}:root:not([data-theme="light"]) .partner-ik .ik-dark{display:block}}
:root[data-theme="dark"] .partner-ik .ik-light{display:none}:root[data-theme="dark"] .partner-ik .ik-dark{display:block}

/* ── hosting vs maintenance (maintenance page) ──────────────────────────────────────────────── */
.vs{padding:clamp(46px,7vw,92px) clamp(20px,5vw,64px);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.vs-in{max-width:1180px;margin:0 auto}
.vs h2{margin-bottom:14px}
.vs .lede{max-width:60ch}
.vs-grid{display:grid;gap:clamp(16px,2.4vw,28px);grid-template-columns:repeat(auto-fit,minmax(min(100%,340px),1fr));margin-top:clamp(18px,3vw,32px)}
.vs-card{background:var(--panel);border:1px solid var(--rule);border-radius:14px;padding:clamp(22px,3vw,34px)}
.vs-card .eyebrow{margin:0 0 10px}
.vs-card h3{font-family:var(--display);font-weight:600;font-size:clamp(1.3rem,1.1rem + .8vw,1.7rem);line-height:1.25;margin:0 0 10px}
.vs-card p{margin:0 0 12px;color:var(--mid);max-width:34rem}
.vs-card p:last-child{margin-bottom:0}
.vs-card a{color:var(--accent-text);text-underline-offset:3px}
.vs-card a:focus-visible{outline:2px solid var(--plan);outline-offset:3px;border-radius:4px}
.vs-care{border-color:var(--plan)}
