/* ============ tokens ============ */
:root{
  --bg:#f7f7f5;
  --bg-alt:#f1f1ee;
  --ink:#111112;
  --ink-soft:#4a4a4e;
  --ink-faint:#9a9a9f;
  --line:rgba(17,17,18,.14);
  --accent:#223fff;
  --max:1280px;
  --pad:clamp(20px,5vw,72px);
  --font:"Lato",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
}
html[data-theme="dark"]{
  --bg:#0b0b0c;
  --bg-alt:#111113;
  --ink:#f4f4f2;
  --ink-soft:#b6b6b3;
  --ink-faint:#6c6c70;
  --line:rgba(244,244,242,.16);
  --accent:#223fff;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
/* the particle field sits behind the whole site, fixed to the viewport */
.site__canvas{position:fixed;inset:0;width:100%;height:100%;z-index:-2;pointer-events:none}
/* light mode lays a half-opaque white sheet over the field so it reads as
   texture rather than competing with the content. It sits above the canvas
   (-2) and below everything in the flow. */
html:not([data-theme="dark"]) body::before{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:rgba(255,255,255,.5);
}
/* The header is a floating pill, so copy scrolls past in the gap beside it and
   reads as clutter behind the bar. This fades the top of the viewport out to
   the page colour: opaque for the height of the pill, then gone by 130px.
   z-index 30 keeps it above the content but under the menu scrim (40), the
   bar (50) and the scroll progress (60). The stops are written as rgba of the
   page colour rather than `transparent`, which some engines interpolate
   through transparent *black* and leave a grey smear. */
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
body{
  margin:0;
  /* --page-bg is what actually gets painted. It defaults to --bg and is the
     only thing the scroll shift touches, so form fields and panels that also
     read --bg are left alone. */
  background:var(--page-bg,var(--bg));
  transition:background-color .55s var(--ease);
  color:var(--ink);
  font-family:var(--font);
  font-weight:400;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  transition:background-color .6s var(--ease),color .6s var(--ease);
}
img,canvas,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
h1,h2,h3{font-weight:400;letter-spacing:-.03em;line-height:1.02;margin:0}
p{margin:0 0 1.1em}
ul,ol{margin:0;padding:0;list-style:none}

/* clip-based hiding: -9999px would widen the root scroll area */
.skip{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip:focus{
  position:fixed;left:12px;top:12px;width:auto;height:auto;margin:0;padding:12px 18px;
  clip-path:none;background:var(--ink);color:var(--bg);z-index:99;
}
:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:2px}

/* ============ scroll progress ============ */
.progress{position:fixed;inset:0 0 auto 0;height:2px;z-index:60;pointer-events:none}
.progress span{display:block;height:100%;width:100%;background:var(--accent);transform:scaleX(0);transform-origin:0 50%}

/* ============ nav: floating card that expands into a menu ============
   Geometry matched to the reference: 20px inset, 10px radius, 56px bar row,
   24px inner padding, 40px links on a 57px rhythm, blur(24px) overlay.      */
:root{ --menu-ease:cubic-bezier(.15,.9,.34,.95); --card:#f7f7f7; --svc-card:#ffffff; --svc-pill:#f1f1ee;
  --svc-hover-bg:#ffffff; --svc-hover-ink:#141414;
  --svc-hover-soft:rgba(20,20,20,.72); --svc-hover-pill:rgba(0,0,0,.065);
  --svc-pill-on-card:rgba(0,0,0,.065);
  --svc-ink:#141414; --svc-ink-soft:rgba(20,20,20,.72); --svc-ink-faint:rgba(20,20,20,.45); }
html[data-theme="dark"]{ --card:#141416; --svc-card:#ffffff; --svc-pill:#191919;
  --svc-hover-bg:#ffffff; --svc-hover-ink:#141414;
  --svc-hover-soft:rgba(20,20,20,.72); --svc-hover-pill:rgba(0,0,0,.065);
  --svc-pill-on-card:rgba(0,0,0,.065); }

.nav{
  position:fixed;top:20px;left:20px;right:20px;z-index:50;
  max-width:calc(var(--max) + 80px);margin-inline:auto;
  padding:0 24px;
  border-radius:10px;overflow:hidden;
  background:var(--card);
  border:0;
  transition:transform .5s var(--menu-ease),background-color .4s var(--menu-ease);
}
@media (max-width:899px){
  /* closed, the bar hugs its contents on the left, as it does on desktop;
     open, it spans the full width */
  .nav{right:auto;width:max-content;max-width:calc(100vw - 40px);margin-inline:0}
  .nav.is-open{right:20px;width:auto;max-width:none}
  /* a collapsed row still contributes its content's width, which would stretch
     the closed bar to the width of the menu links — zero it out until open */
  .menu{width:0}
  .nav.is-open .menu{width:auto}
  /* the tray now holds the languages alone */
  .menu__utils{
    display:flex;align-items:center;gap:12px;
    /* the languages are the last thing in the panel, so the bottom padding
       here is what keeps them off the panel's edge */
    padding:14px 0 22px;border-top:1px solid var(--line);
  }
  /* the phone and the theme switch ride in the bar but stay out of sight
     while it is closed, so the closed bar keeps its width */
  .nav:not(.is-open) .bar__contact,
  .nav:not(.is-open) .bar__theme{display:none}
  .bar{justify-content:flex-start}
  .bar__actions{margin-left:auto}
  /* open: logo and number on the left, switch and close on the right */
  .nav.is-open .bar__sep{display:none}
  .nav.is-open .bar__contact--phone{
    width:auto;height:auto;padding:0 0 0 16px;border-radius:0;
    font-size:14px;color:var(--ink-soft);background:none;
  }
  .nav.is-open .bar__contact--phone:hover{color:var(--ink);background:none}
  .nav.is-open .bar__contact--phone svg{display:none}
  .nav.is-open .bar__contact-num{display:inline}
  .nav.is-open .bar__theme{margin-right:10px}
  /* the cross alone is clear enough; the word would push the row past the
     panel's width once the number and the switch are in it */
  .nav.is-open .bar__label{display:none}
}

.bar{display:flex;align-items:center;justify-content:space-between;gap:20px;height:56px}
.bar__brand{display:inline-flex;align-items:center;height:56px}
.nav__mark{width:72px;height:40px;flex:none;overflow:visible;transition:opacity .4s var(--menu-ease)}
.bar__brand:hover .nav__mark{opacity:.6}

.bar__actions{display:flex;align-items:center;gap:0}
/* language + theme sit in their own pill, clear of the menu */
.utils{
  position:fixed;top:20px;right:20px;z-index:51;
  display:flex;align-items:center;gap:4px;height:56px;padding:0 12px;
  border-radius:10px;background:var(--card);
  transition:transform .5s var(--menu-ease),opacity .35s var(--menu-ease);
}
.menu-open .utils{opacity:0;pointer-events:none}
.bar__contact{
  display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;flex:none;
  border-radius:50%;color:var(--ink-soft);
  transition:color .3s var(--ease),background-color .3s var(--ease);
}
.bar__contact svg{width:16px;height:16px}
.bar__contact:hover{color:var(--ink);background:var(--svc-pill)}
/* the call button carries the number itself, so it is a pill not a circle */
.bar__contact--phone{
  width:auto;gap:8px;padding:0 13px;border-radius:20px;
  font-size:13px;letter-spacing:.01em;white-space:nowrap;
}
/* inside the top-right pill it sits ahead of the divider and the languages */
.utils .bar__contact{height:30px}
.utils .bar__contact:not(.bar__contact--phone){width:30px}
.utils .bar__theme{width:30px;height:30px;margin-right:0;margin-left:2px}
@media (max-width:899px){
  /* the bar is tight on a phone, so the icon alone has to do the work */
  .bar__contact-num{display:none}
  .bar__contact--phone{width:32px;padding:0;gap:0;border-radius:50%}
}
.utils__sep{width:1px;height:20px;flex:none;margin:0 10px;background:var(--line)}
.utils__sep[hidden]{display:none}
/* on mobile the pill is empty — its controls live in the menu */
@media (max-width:899px){.utils{display:none}}
.lang{display:inline-flex;align-items:center;gap:2px}
.lang__full{display:none}
.lang__item{
  padding:5px 7px;border-radius:20px;font-size:12px;letter-spacing:.06em;
  color:var(--ink-faint);transition:color .3s var(--ease),background-color .3s var(--ease);
}
.lang__item:hover{color:var(--ink)}
.lang__item.is-current{color:var(--ink);background:var(--svc-pill)}
/* on mobile each language gets its own row, spelled out in full */
@media (max-width:899px){
  .lang{flex-direction:column;align-items:flex-start;gap:2px}
  .lang__short{display:none}
  .lang__full{display:inline}
  .lang__item{padding:7px 10px;font-size:16px;letter-spacing:.02em}
}
.bar__theme{
  display:grid;place-items:center;width:34px;height:34px;padding:0;margin-right:14px;
  border:0;border-radius:50%;background:transparent;color:var(--ink-soft);
  transition:color .3s,transform .5s var(--menu-ease);
}
.bar__theme:hover{color:var(--ink)}
/* sun and moon stacked in one cell, cross-faded on theme change */
.bar__theme svg{grid-area:1/1;transition:opacity .35s var(--menu-ease),transform .5s var(--menu-ease)}
/* the icon shows the mode you'd switch to, not the one you're in */
.icon-sun{opacity:0;transform:rotate(55deg) scale(.6)}
.icon-moon{opacity:1;transform:none}
html[data-theme="dark"] .icon-sun{opacity:1;transform:none}
html[data-theme="dark"] .icon-moon{opacity:0;transform:rotate(-55deg) scale(.6)}
/* the moon's stars twinkle out of step with each other */
.icon-moon__stars circle{animation:star-blink 2.6s var(--ease) infinite}
.icon-moon__stars circle:nth-child(2){animation-delay:.85s}
.icon-moon__stars circle:nth-child(3){animation-delay:1.7s}
@keyframes star-blink{0%,100%{opacity:.2}45%,55%{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .icon-moon__stars circle{animation:none;opacity:.75}
}
/* slow continuous loop on the rays */
.icon-sun__rays{transform-origin:12px 12px;animation:sun-loop 12s linear infinite}
@keyframes sun-loop{to{transform:rotate(360deg)}}

/* 1px × 36px rule, exactly as the reference separates logo from toggle */
.bar__sep{width:1px;height:36px;background:var(--line);flex:none;margin:0 20px}
.bar__sep--nav{display:none}

.bar__toggle{
  display:inline-flex;align-items:center;gap:10px;height:56px;
  padding:0 0 0 20px;border:0;background:transparent;
  color:var(--ink);font:inherit;font-size:15px;
  transition:opacity .3s var(--menu-ease);
}
.bar__toggle:hover{opacity:.6}
/* below the breakpoint the bar must hold its width: the same gaps and the same
   toggle padding as the desktop bar, declared after the base rules so they win */
@media (max-width:899px){
  .bar{gap:0}
  .bar__toggle{padding-left:0}
}
.bar__icon{position:relative;display:grid;place-items:center;width:18px;height:18px}
.dots{display:grid;grid-template-columns:repeat(3,3px);gap:2.6px;transition:opacity .3s var(--menu-ease),transform .45s var(--menu-ease)}
.dots i{width:3px;height:3px;border-radius:50%;background:currentColor}
.cross{position:absolute;inset:0;width:18px;height:18px;opacity:0;transform:rotate(-45deg) scale(.7);transition:opacity .3s var(--menu-ease),transform .45s var(--menu-ease)}
.nav.is-open .dots{opacity:0;transform:rotate(45deg) scale(.7)}
.nav.is-open .cross{opacity:1;transform:none}
.bar__label{white-space:nowrap}

/* the panel grows straight out of the bar */
.menu{display:grid;grid-template-rows:0fr;transition:grid-template-rows .55s var(--menu-ease)}
.nav.is-open .menu{grid-template-rows:1fr}
.menu__inner{overflow:hidden;min-height:0}
.menu__nav{display:flex;flex-direction:column;align-items:flex-start;gap:14px;padding:22px 0 18px}
.menu__nav a{
  display:block;font-size:40px;line-height:1.12;letter-spacing:-.02em;padding:9px 0;margin-bottom:0;
  opacity:0;transform:translate3d(0,20px,0);
  transition:opacity .45s var(--menu-ease),transform .5s var(--menu-ease);
}
.menu__nav a:last-child{margin-bottom:0}
.nav.is-open .menu__nav a{opacity:1;transform:none}
.nav.is-open .menu__nav a:nth-child(1){transition-delay:.08s}
.nav.is-open .menu__nav a:nth-child(2){transition-delay:.13s}
.nav.is-open .menu__nav a:nth-child(3){transition-delay:.18s}
.nav.is-open .menu__nav a:nth-child(4){transition-delay:.23s}
.nav.is-open .menu__nav a:nth-child(5){transition-delay:.28s}
.menu__nav span{position:relative;display:inline-block;transition:opacity .3s var(--menu-ease)}
.menu__nav a:hover span,.menu__nav a:focus-visible span{opacity:.55}

/* --- desktop: a compact pill that grows sideways, links inline (reference behavior) --- */
@media (min-width:900px){
  .nav{
    right:auto;width:max-content;max-width:calc(100vw - 40px);margin-inline:0;
    display:flex;align-items:center;height:56px;
  }
  .bar{display:contents}
  .bar__brand{order:1}
  .bar__sep{order:2}
  .menu{order:3;height:56px;grid-template-rows:1fr;grid-template-columns:0fr;
        transition:grid-template-columns .55s var(--menu-ease)}
  .nav.is-open .menu{grid-template-columns:1fr}
  .bar__sep--nav{order:4}
  .nav.is-open .bar__sep--nav{display:block}
  .bar__actions{order:5}
  .menu__inner{min-width:0;overflow:hidden}
  .menu__nav{flex-direction:row;align-items:center;gap:28px;padding:0;border-top:0;white-space:nowrap}
  .menu__nav a{
    font-size:15px;line-height:56px;letter-spacing:0;padding:0;margin:0;
    transform:translate3d(0,6px,0);
  }
  .nav.is-open .menu__nav a{transform:none}
  .bar__toggle{padding-left:0}
  /* no blur overlay on desktop — the pill just widens */
  .scrim{display:none}
}

/* full-viewport blur behind the open card */
.scrim{
  position:fixed;inset:0;z-index:40;
  background:rgba(0,0,0,.06);
  backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);
  opacity:0;pointer-events:none;transition:opacity .45s var(--menu-ease);
}
.scrim.is-on{opacity:1;pointer-events:auto}

/* ============ hero ============ */
.hero{position:relative;min-height:100svh;display:flex;align-items:center;padding:clamp(90px,14vh,150px) var(--pad) clamp(40px,8vh,90px)}
/* single words in the hero carry their own weight, slant and color */
/* a serif against the sans, so the middle line reads as an aside.
   Serifs sit optically smaller at the same size, hence the nudge up. */
.hero__title .t-soft{
  font-family:"Playfair Display",Georgia,"Times New Roman",serif;
  font-style:italic;font-weight:400;font-size:1.08em;letter-spacing:-.02em;
  color:var(--ink-soft);
}
.hero__title .t-pop{
  /* a marker-pen highlight rather than colored type. The block is held back
     until the characters reveal, or it flashes as an empty blue bar first. */
  font-weight:700;color:#fff;background:transparent;
  padding:.02em .12em .08em;border-radius:.08em;
  box-decoration-break:clone;-webkit-box-decoration-break:clone;
  transition:background-color .5s var(--ease);
}
.hero__title.is-in .t-pop{background:var(--accent)}
@media (prefers-reduced-motion:reduce){ .hero__title .t-pop{transition:none} }
.hero__inner{position:relative;z-index:1;width:100%;max-width:var(--max);margin:0 auto}
.hero__title{font-size:clamp(1.755rem,6.075vw,5.76rem);letter-spacing:-.045em}
.hero__sub{margin-top:clamp(18px,3vw,30px);font-size:clamp(.95rem,1.35vw,1.15rem);line-height:1.6;color:var(--ink-soft);max-width:60ch}
.hero__actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:clamp(24px,3.4vw,38px)}
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  height:50px;padding:0 28px;border-radius:999px;
  border:1px solid var(--line);background:transparent;color:var(--ink);
  font-size:14px;letter-spacing:.01em;white-space:nowrap;
  transition:background-color .45s var(--ease),color .45s var(--ease),
             border-color .45s var(--ease),transform .45s var(--ease-out);
}
.btn:hover{transform:translateY(-2px);background:var(--accent);color:#fff;border-color:var(--accent)}
.btn--solid{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.btn--solid:hover{background:var(--accent);color:#fff;border-color:var(--accent)}

/* ============ reveal primitives ============ */
[data-split]{overflow:hidden}
.line{display:block}
.word{display:inline-block;white-space:nowrap;overflow:hidden;vertical-align:top;padding-bottom:.08em}
.char{display:inline-block;will-change:transform;transform:translate3d(0,110%,0)}
.is-in .char{transform:none;transition:transform .95s var(--ease-out)}
[data-reveal]{opacity:0;transform:translate3d(0,26px,0)}
[data-reveal].is-in{opacity:1;transform:none;transition:opacity .9s var(--ease-out),transform .9s var(--ease-out)}

/* ============ work: three projects in one row ============ */
/* dark mode veils the particle field behind the projects block */
html[data-theme="dark"] .work{background:rgba(0,0,0,.25)}
html:not([data-theme="dark"]) .work{background:rgba(255,255,255,.25)}
.work{max-width:none;margin:0;padding:clamp(24px,5vh,60px) var(--pad) clamp(80px,16vh,180px)}
/* the band runs edge to edge; its contents sit on the hero's measure */
.work__title,.work__list{width:100%;max-width:var(--max);margin-inline:auto}
.work__title{margin-bottom:clamp(30px,6vh,70px)}
.work__list{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(12px,1.6vw,22px);align-items:start}
.project__link{display:block;width:100%}
/* The grid gives this box fractional bounds (top 151.91, width 300.05 at
   1440), so on a 2x display the clip edge lands mid device-pixel and the
   zoomed image leaves a half-covered row over the top and bottom borders.
   Hit-testing proves it is not geometric overflow, it is rasterisation, so
   pulling the clip half a pixel inside is the fix: the outermost row is then
   never painted by the image. The crop is half a pixel and invisible. */
.project__media{
  position:relative;margin:0;overflow:hidden;background:var(--bg-alt);contain:paint;
  clip-path:inset(0.5px);
}
.thumb{
  /* square crop sitting 18% of the way in from the left of the
     1600x858 source, rather than hard against the left edge */
  display:block;width:100%;height:auto;aspect-ratio:1/1;
  object-fit:cover;object-position:18% center;
  /* full color */
  transition:transform 1.1s var(--ease-out);
  backface-visibility:hidden;
  /* a hair wider than the frame at rest, so the scale grows from inside it */
  transform:scale(1.001);
}
.project__link:hover .thumb,
.project__link:focus-visible .thumb{transform:scale(1.05)}

/* hover fills the frame with the project write-up on a flat panel: white on
   the light theme, near-black on the dark one. The three text colours below
   key off --prj-ink so they follow the panel. */
.project__reveal{
  /* off-white rather than #fff: pure white against the #f7f7f5 page reads as a
     hard seam along the top edge with nothing to balance it on the other three.
     A hair of warmth plus a border on all four sides makes the edge deliberate. */
  --prj-bg:#fcfcfb;
  --prj-ink:#141416;
  --prj-soft:rgba(20,20,22,.74);
  --prj-rule:rgba(20,20,22,.34);
  --prj-edge:rgba(20,20,22,.09);
  position:absolute;inset:0;z-index:2;
  display:flex;flex-direction:column;justify-content:center;gap:10px;
  padding:clamp(18px,2vw,28px);
  background:var(--prj-bg);color:var(--prj-ink);
  border:1px solid var(--prj-edge);
  opacity:0;transition:opacity .5s var(--ease);
}
html[data-theme="dark"] .project__reveal{
  --prj-bg:#121214;
  --prj-ink:#f4f4f2;
  --prj-soft:rgba(244,244,242,.76);
  --prj-rule:rgba(244,244,242,.4);
  --prj-edge:rgba(244,244,242,.1);
}
.project__link:hover .project__reveal,
.project__link:focus-visible .project__reveal{opacity:1}
.project__reveal-title{font-size:clamp(1rem,1.5vw,1.3rem);letter-spacing:-.02em}
.project__reveal-desc{
  margin:0;font-size:clamp(.78rem,.85vw,.9rem);line-height:1.55;color:var(--prj-soft);
}
.project__visit{
  display:inline-flex;align-items:center;gap:7px;margin-top:4px;
  font-size:clamp(.78rem,.85vw,.9rem);color:var(--prj-ink);
  border-bottom:1px solid var(--prj-rule);padding-bottom:2px;align-self:flex-start;
  transition:border-color .35s var(--ease),gap .35s var(--ease-out);
}
.project__link:hover .project__visit{border-color:var(--prj-ink);gap:11px}
.project__meta{
  display:flex;gap:16px;margin-top:12px;
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint);
  transition:color .4s var(--ease);
}
.project__link:hover .project__meta{color:var(--ink)}

@media (max-width:860px){
  .work__list{grid-template-columns:1fr;gap:clamp(30px,6vw,48px)}
  .project__reveal-title{font-size:clamp(1.2rem,3vw,1.6rem)}
  .project__reveal-desc{font-size:.9rem}
}

/* ============ services ============
   Card metrics taken from the reference at both widths:
   mobile  = full width, 14px radius, 20px padding, 14/20 body
   desktop = 3-up grid, 10px gap, 30px radius, 40px padding, 28/32 title, 16/24 body */
/* same wrapper as the footer: the section is full width with a --pad gutter,
   its inner row capped at --max and centered */
.services{position:relative;max-width:none;margin:0;padding:0 var(--pad) clamp(80px,16vh,180px)}
.services__inner{max-width:var(--max);margin:0 auto}
.services__title{position:relative;z-index:1;margin-bottom:clamp(18px,3vh,26px)}
.services__list{position:relative;z-index:1;display:grid;gap:26px;grid-auto-rows:1fr}

.services__intro{
  margin:0 0 clamp(18px,3vh,26px);max-width:52ch;
  font-size:clamp(.95rem,1.3vw,1.1rem);line-height:1.7;color:var(--ink-soft);
}
@media (min-width:900px){
}

/* ---- pricing ---- */
/* the tinted band runs edge to edge; its contents stay on the shared measure */
.pack{max-width:none;margin:0;padding:clamp(50px,9vh,110px) var(--pad)}
/* 80%, and following the theme: a fixed black band would put dark text
   on black in light mode */
html[data-theme="dark"] .pack{background:rgba(0,0,0,.8)}
html:not([data-theme="dark"]) .pack{background:rgba(255,255,255,.8)}
.pack__inner{width:100%;max-width:var(--max);margin-inline:auto;text-align:left}
/* pricing and the reviews share one row */
.pack__row{display:grid;gap:clamp(24px,3vw,44px);align-items:center}
@media (min-width:900px){ .pack__row{grid-template-columns:1fr 1fr} }
.pack__col{min-width:0}
.pack__title{margin-bottom:clamp(16px,2.6vh,24px)}
.pack__headline{
  /* one line, so the size is capped rather than filling the measure */
  margin:0 0 16px;max-width:none;white-space:nowrap;
  font-size:clamp(1.3rem,3.2vw,2.6rem);line-height:1.15;letter-spacing:-.03em;color:var(--ink);
}
.pack__headline strong{font-weight:400;color:inherit}
.pack__body{margin:0 0 clamp(22px,3.4vh,32px);max-width:56ch;font-size:15px;line-height:1.75;color:var(--ink-soft)}
.pack__actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:flex-start}
.pack__note{margin:clamp(18px,2.6vh,26px) 0 0;font-size:13px;line-height:1.7;color:var(--ink-faint)}
.pack__link{
  padding:0;border:0;background:transparent;color:var(--ink-soft);font:inherit;font-size:13px;
  border-bottom:1px solid var(--line);cursor:pointer;transition:color .25s var(--ease);
}
.pack__link:hover{color:var(--accent)}

/* ---- testimonials: one at a time, centered, self-advancing ---- */
.says{min-width:0;margin:0;padding:0}
.says__slider{max-width:none;margin-inline:auto}
.says__viewport{overflow:hidden;border-radius:18px}
.says__track{
  display:flex;margin:0;padding:0;list-style:none;
  transition:transform .55s var(--ease-out);
}
.says__item{
  flex:0 0 100%;min-width:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:9px;text-align:center;
  padding:0;
  background:transparent;color:var(--ink);border:0;border-radius:0;
}
.says__stars{display:flex;align-items:center;gap:4px;margin:0;color:#e0a92b}
.says__stars svg{fill:currentColor;width:17px;height:17px}
.says__score{margin-left:9px;font-size:12px;letter-spacing:.08em;color:var(--ink-faint)}
.says__head{margin:0;font-size:1rem;letter-spacing:-.01em;color:var(--ink)}
.says__quote{margin:0}
.says__quote p{margin:0;font-size:13.5px;line-height:1.7;color:var(--ink-soft);max-width:58ch}
.says__quote p + p{margin-top:.85em}
.says__who{margin:0;padding-top:2px;font-size:12.5px;line-height:1.55;color:var(--ink-faint)}
.says__name{display:block;color:var(--ink)}
@media (prefers-reduced-motion:reduce){ .says__track{transition:none} }

/* ---- questions ---- */
.faq{max-width:none;margin:0;padding:clamp(40px,7vh,90px) var(--pad)}
html[data-theme="dark"] .faq{background:rgba(0,0,0,.25)}
html:not([data-theme="dark"]) .faq{background:rgba(255,255,255,.25)}
.faq__inner{max-width:var(--max);margin:0 auto}
.faq__title{margin-bottom:clamp(20px,3.4vh,30px)}
.faq__list{display:grid;gap:10px;max-width:none}
.faq__item{
  border:0;border-radius:20px;
  padding:4px 30px;
  transition:background .25s var(--ease);
}
html[data-theme="dark"] .faq__item{background:rgba(0,0,0,.5);border:1px solid rgba(255,255,255,.07)}
html:not([data-theme="dark"]) .faq__item{background:rgba(255,255,255,.5);border:1px solid rgba(0,0,0,.07)}
.faq__q{
  list-style:none;cursor:pointer;
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:24px 0;font-size:clamp(1.1rem,1.75vw,1.35rem);line-height:1.4;color:var(--ink);
}
.faq__q::-webkit-details-marker{display:none}
.faq__q::after{
  content:"";flex:none;width:11px;height:11px;margin-right:2px;
  border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);
  transition:transform .3s var(--ease-out);
}
.faq__item[open] .faq__q::after{transform:rotate(-135deg) translate(-3px,-3px)}
.faq__a{padding:0 0 26px}
.faq__a p{margin:0 0 12px;max-width:none;font-size:16px;line-height:1.8;color:var(--ink-soft)}
.faq__a p:last-child{margin-bottom:0}
@media (prefers-reduced-motion:reduce){ .faq__q::after{transition:none} }

/* ---- free website analysis: the odd card out ---- */
.svc.svc--audit{
  /* white at rest like every other card; it is the amber rule that marks it.
     `.svc` is defined further down, so this needs the extra class to win. */
  background:var(--svc-card);color:var(--svc-ink);
  border:3px solid rgb(174,187,255);
  box-shadow:none;
  /* the whole card is the button, so reset what the element brings with it */
  font:inherit;text-align:left;cursor:pointer;
}
/* decorative: the card around it takes the click */
.svc__cta{
  display:inline-flex;align-items:center;gap:9px;align-self:flex-start;
  margin-top:20px;padding:13px 22px;border-radius:40px;
  background:var(--accent);color:#fff;
  font-size:14px;line-height:1;font-weight:600;
  transition:transform .3s var(--ease-out);
}
.svc__cta svg{transition:transform .35s var(--ease-out)}
.svc--audit:hover .svc__cta,.svc--audit:focus-visible .svc__cta{
  transform:translateY(-2px);
}
.svc--audit:hover .svc__cta svg,.svc--audit:focus-visible .svc__cta svg{transform:translateX(3px)}
.audit-dlg .bk-group--fields:first-of-type{border-top:0;padding-top:0}


/* ---- technology strip: logo and name share one tile ---- */
.tech{overflow:hidden;padding:clamp(30px,5vh,52px) var(--pad);border-top:1px solid var(--line)}
.tech__inner{max-width:var(--max);margin:0 auto}
.tech__marquee{
  /* the strip is exactly as wide as the wrapper: no bleed past it, so a tile
     is never clipped by the section edge */
  --tech-cols:1;
  --tech-gap:16px;
  /* no fade mask: the tiles now land exactly on the wrapper edges, and a
     mask would dim the last one instead of hinting at more */
  overflow:hidden;
}
.tech__track{
  display:flex;align-items:stretch;gap:var(--tech-gap);
  margin:0;padding:0;width:max-content;
}
.tech__item{
  /* --tech-w is set in js from the wrapper width, so a whole number of tiles
     fills the visible area; the fallback keeps them sane before that runs */
  width:var(--tech-w,220px);
  display:flex;align-items:center;justify-content:center;gap:12px;flex:none;
  white-space:nowrap;overflow:hidden;
  padding:25px 15px;border-radius:10px;
  /* dark tile on the dark theme, light tile on the light one */
  background:#141416;color:#fff;
  border:1px solid rgba(255,255,255,.12);
}
html:not([data-theme="dark"]) .tech__item{
  background:#ffffff;color:var(--ink);
  border-color:rgba(0,0,0,.1);
}
/* the brand files are black artwork: knocked out to white on the dark tile,
   left as they are on the light one */
.tech__icon img{filter:invert(1)}
html:not([data-theme="dark"]) .tech__icon img{filter:none}
.tech__icon{display:grid;place-items:center;width:34px;height:34px;flex:none}
.tech__icon img,.tech__icon svg{width:34px;height:34px;display:block}
.tech__name{font-size:16px;letter-spacing:.01em;overflow:hidden;text-overflow:ellipsis}
/* the widest name needs roughly 210px of tile, so the column count climbs
   with the wrapper rather than leaving four over-wide tiles on a desktop */
@media (min-width:520px){ .tech__marquee{--tech-cols:2} }
@media (min-width:760px){ .tech__marquee{--tech-cols:3} }
@media (min-width:1040px){ .tech__marquee{--tech-cols:4} }
@media (min-width:1300px){
  /* six across leaves each tile around 195px: enough for the longest name
     (Google Analytics) once the icon and type step down a little, and the
     wider gap does the separating that the extra tile used to */
  .tech__marquee{--tech-cols:6;--tech-gap:20px}
  .tech__item{gap:10px}
  .tech__icon,.tech__icon img,.tech__icon svg{width:30px;height:30px}
  .tech__name{font-size:15px}
}


.svc{
  display:flex;flex-direction:column;background:var(--svc-card);color:var(--svc-ink);
  border-radius:14px;padding:20px;min-height:270px;
  transition:background-color .4s var(--ease),color .4s var(--ease);
}
/* On the light theme the cards are white on a near-white page, so they need an
   edge to read as cards at all. `.svc--audit` is excluded: this selector scores
   higher than the `.svc.svc--audit` rule above and would replace its amber rule. */
html:not([data-theme="dark"]) .svc:not(.svc--audit){
  border:1px solid rgba(0,0,0,.08);
}
.svc[role="button"]{cursor:pointer}
.svc:hover,.svc:focus-visible{background:var(--svc-hover-bg);color:var(--svc-hover-ink)}
.svc[role="button"]:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.svc__head{display:flex;align-items:flex-start;justify-content:space-between;gap:20px}
.svc__title{
  font-size:20px;line-height:26px;letter-spacing:-.02em;
}
.svc__arrow{
  flex:none;display:grid;place-items:center;width:30px;height:30px;
  color:var(--svc-ink-faint);transition:color .35s var(--ease),transform .45s var(--ease-out);
}
.svc:hover .svc__arrow,.svc:focus-visible .svc__arrow{
  color:var(--svc-hover-ink);transform:translate(3px,-3px);
}
.svc__desc{
  display:block;margin:26px 0 16px;max-width:62ch;
  margin-top:auto;
  font-size:14px;line-height:20px;color:var(--svc-ink-soft);
  transition:color .4s var(--ease);
}
.svc:hover .svc__desc,.svc:focus-visible .svc__desc{color:var(--svc-hover-soft)}
.svc__tags{display:flex;flex-wrap:wrap;gap:6px}
.svc__tags li{
  display:inline-flex;align-items:center;height:28px;padding:0 16px;
  background:var(--svc-pill-on-card);border-radius:26px;
  font-size:12px;line-height:12px;color:var(--svc-ink);
  transition:background-color .4s var(--ease),color .4s var(--ease);
}
.svc:hover .svc__tags li,.svc:focus-visible .svc__tags li{
  background:var(--svc-hover-pill);color:var(--svc-hover-ink);
}

/* cards rest on white; each reveals its own pale tint on hover.
   The two lists restart the count, so tints repeat between them. */
.svc:nth-child(1){--svc-hover-bg:#e7ecfb}  /* pale blue    */
.svc:nth-child(2){--svc-hover-bg:#fdeadf}  /* pale peach   */
.svc:nth-child(3){--svc-hover-bg:#e6f2ea}  /* pale green   */
.svc:nth-child(4){--svc-hover-bg:#f6e7f0}  /* pale mauve   */
.svc:nth-child(5){--svc-hover-bg:#fbf3da}  /* pale butter  */
.svc:nth-child(6){--svc-hover-bg:#e3eff4}  /* pale cyan    */
.svc:nth-child(7){--svc-hover-bg:#eee9f8}  /* pale lilac   */
.svc:nth-child(8){--svc-hover-bg:#fae6e6}  /* pale rose    */
/* the analysis card keeps its own warm tint: two classes to match the
   specificity of the positional rules above, and placed after them */
.svc.svc--audit{--svc-hover-bg:#e7ebff}


@media (min-width:900px){
  .services__list{grid-template-columns:repeat(3,1fr)}
  /* Three tracks, no gaps. Websites (1) and Practical AI (6) take two tracks
     each: 2 + 1 + 1 + 1 + 1 + 2 + 1 = 9 units, which is exactly three full rows. */
  .svc:nth-child(1){grid-row:1;grid-column:1 / span 2}   /* Business Websites */
  .svc:nth-child(2){grid-row:1;grid-column:3}
  .svc:nth-child(3){grid-row:2;grid-column:1}
  .svc:nth-child(4){grid-row:2;grid-column:2}
  .svc:nth-child(5){grid-row:2;grid-column:3}
  .svc:nth-child(7){grid-row:3;grid-column:1}            /* Free analysis */
  .svc:nth-child(6){grid-row:3;grid-column:2 / span 2}   /* Practical AI */
  .svc{border-radius:30px;padding:40px;min-height:400px}
  .svc__title{font-size:28px;line-height:32px}
  .svc__arrow{width:37px;height:37px}
    .svc__desc{margin:48px 0 18px;margin-top:auto;font-size:16px;line-height:24px}
}

/* ============ service detail pages ============ */
/* the service detail pages sit over the particle field, so the reading
   column gets a veil of its own — mirroring the sections on the homepage */
html[data-theme="dark"] .svc-page{background:rgba(0,0,0,.5)}
html:not([data-theme="dark"]) .svc-page{background:rgba(255,255,255,.5)}
.svc-page{max-width:var(--max);margin:0 auto;padding:clamp(110px,16vh,180px) var(--pad) clamp(60px,10vh,110px)}
.crumbs{
  display:flex;flex-wrap:wrap;gap:8px;margin-bottom:clamp(28px,5vh,56px);
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint);
}
.crumbs a{transition:color .3s var(--ease)}
.crumbs a:hover{color:var(--accent)}
.svc-hero{max-width:62ch;margin-bottom:clamp(40px,7vh,80px)}
.svc-hero__num{margin:0 0 12px;font-size:12px;letter-spacing:.2em;color:var(--ink-faint)}
.svc-hero__title{font-size:clamp(2rem,6vw,4.2rem);letter-spacing:-.035em;margin-bottom:18px}
.svc-hero__lead{margin:0;font-size:clamp(1rem,1.6vw,1.3rem);line-height:1.6;color:var(--ink-soft)}
.svc-body{
  display:grid;gap:16px;border-top:1px solid var(--line);
  padding-top:clamp(20px,3vh,28px);margin-bottom:clamp(34px,6vh,58px);
}
.svc-body__text{margin:0;max-width:64ch;font-size:clamp(.95rem,1.2vw,1.05rem);line-height:1.75;color:var(--ink-soft)}

/* ---- guided question panel (Websites) ---- */
/* the form leads the page; the hero title follows it visually but still comes
   first in the document, so the h1 stays ahead of the form's h2 */
.svc-top{display:flex;flex-direction:column}
.svc-top .quiz{order:1}
.svc-top .svc-hero{order:2}

.quiz{
  margin:0 0 clamp(30px,5vh,48px);padding:clamp(22px,3vw,30px);
  border-radius:16px;color:var(--ink);
}
html[data-theme="dark"] .quiz{background:rgba(0,0,0,.5)}
html:not([data-theme="dark"]) .quiz{background:rgba(255,255,255,.5)}
.quiz__head{margin-bottom:24px}
.quiz__title{font-size:clamp(1.35rem,2.6vw,2rem);letter-spacing:-.03em;margin:0 0 8px}
.quiz__lead{margin:0;font-size:14px;line-height:1.6;color:var(--ink-soft)}

/* steps run down the left, the question sits beside them */
.quiz__body{display:grid;gap:26px}
@media (min-width:820px){ .quiz__body{grid-template-columns:200px minmax(0,1fr);gap:48px} }

.quiz__meter{margin:0}
.quiz__rails{position:relative}
.quiz__dots{display:grid;gap:22px;margin:0;position:relative}
/* the rail runs centre-to-centre: from the first marker to RESULT, no further.
   24px markers, so half of one at each end. */
.quiz__rail{
  position:absolute;left:11px;top:12px;bottom:12px;width:2px;
  background:var(--line);border-radius:2px;overflow:hidden;
}
.quiz__fill{
  display:block;width:100%;height:0;background:var(--accent);
  transition:height .5s var(--ease-out);
}
.quiz__dot{
  position:relative;z-index:1;display:flex;align-items:center;gap:12px;min-width:0;
  color:var(--ink-faint);transition:color .35s var(--ease);
}
.quiz__dot-n{
  flex:none;display:grid;place-items:center;width:24px;height:24px;border-radius:50%;
  /* opaque so the rail does not show through an upcoming step */
  border:1px solid var(--line);background:var(--bg);
  font-size:11px;line-height:1;
  transition:background-color .35s var(--ease),border-color .35s var(--ease),
             color .35s var(--ease),transform .35s var(--ease-out);
}
.quiz__dot-t{font-size:12px;letter-spacing:.1em;text-transform:uppercase;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.quiz__dot.is-done{color:var(--ink-soft)}
.quiz__dot.is-done .quiz__dot-n{background:var(--accent);border-color:var(--accent);color:#fff}
.quiz__dot.is-on{color:var(--ink)}
.quiz__dot.is-on .quiz__dot-n{
  background:var(--accent);border-color:var(--accent);color:#fff;transform:scale(1.12);
}
/* reads as part of the sentence: "1. What do you most want it to bring in?" */
.quiz__q-num{flex:none}

/* on narrow screens the rail lies flat above the question */
@media (max-width:819px){
  .quiz__dots{grid-auto-flow:column;grid-auto-columns:1fr;gap:6px}
  /* four equal columns with the marker at the left of each, so the last
     centre sits a quarter-width in from the right edge */
  .quiz__rail{left:12px;right:calc(25% - 16.5px);top:11px;bottom:auto;width:auto;height:2px}
  .quiz__fill{width:0;height:100%;transition:width .5s var(--ease-out)}
  .quiz__dot{flex-direction:column;align-items:flex-start;gap:8px}
  .quiz__dot-t{display:none}
}

.quiz__step{border:0;padding:0;margin:0;min-width:0}
.quiz__step[hidden]{display:none}
.quiz__step:not([hidden]){animation:quiz-in .38s var(--ease-out) both}
@keyframes quiz-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.quiz__q{
  display:flex;align-items:baseline;gap:10px;
  padding:0;margin:0 0 20px;font-size:clamp(1.3rem,2.4vw,1.9rem);
  line-height:1.25;letter-spacing:-.02em;color:var(--ink);
}
.quiz__opts{display:grid;gap:8px}
.quiz__opt{
  position:relative;display:flex;align-items:center;gap:12px;width:100%;text-align:left;
  padding:14px 18px;border:1px solid var(--line);border-radius:12px;
  background:transparent;color:var(--ink);
  font:inherit;font-size:15px;line-height:1.4;cursor:pointer;
  transition:background-color .25s var(--ease),border-color .25s var(--ease),transform .25s var(--ease-out);
}
.quiz__opt:hover,.quiz__opt:focus-visible{background:var(--bg-alt);border-color:var(--ink-faint);transform:translateX(3px)}
.quiz__opt.is-chosen{border-color:var(--accent);background:var(--bg-alt)}
@media (min-width:700px){ .quiz__opts{grid-template-columns:1fr 1fr} }

.quiz__summary{margin:0 0 12px;font-size:clamp(1rem,1.6vw,1.2rem);line-height:1.5;color:var(--ink)}
.quiz__summary b{font-weight:700}
.quiz__advice{margin:0 0 20px;font-size:14px;line-height:1.7;color:var(--ink-soft);max-width:60ch}
.quiz__actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.quiz__result .btn{cursor:pointer}
/* a tick box, since several answers can be on at once */
.quiz__opt::before{
  content:"";flex:none;width:18px;height:18px;border:1px solid var(--line);border-radius:5px;
  transition:background-color .2s var(--ease),border-color .2s var(--ease);
}
.quiz__opt[aria-pressed="true"]::before{background:var(--accent);border-color:var(--accent)}
.quiz__opt::after{
  content:"\2713";position:absolute;left:23px;top:50%;transform:translateY(-50%);
  color:#fff;font-size:11px;line-height:1;opacity:0;transition:opacity .2s var(--ease);
}
.quiz__opt[aria-pressed="true"]::after{opacity:1}

.quiz__nav{display:flex;align-items:center;gap:16px;margin-top:24px}
.quiz__next{cursor:pointer;margin-left:auto}
.quiz__next:disabled{opacity:.4;cursor:not-allowed}
.quiz__next[hidden]{display:none}
.quiz__restart,.quiz__back{
  padding:0;border:0;background:transparent;cursor:pointer;
  color:var(--ink-faint);font:inherit;font-size:13px;
  transition:color .25s var(--ease);
}
.quiz__restart{margin-top:16px}
.quiz__restart:hover,.quiz__back:hover{color:var(--ink)}
.quiz__back[hidden]{display:none}
@media (prefers-reduced-motion:reduce){
  .quiz__opt,.quiz__fill,.quiz__dot,.quiz__dot-n{transition:none}
  .quiz__step:not([hidden]){animation:none}
}

/* ---- comparison chart (Websites) ---- */
.cmp{margin:0 0 clamp(34px,6vh,58px);padding-top:clamp(20px,3vh,28px);border-top:1px solid var(--line)}
.cmp__title{font-size:clamp(1.3rem,2.4vw,1.9rem);letter-spacing:-.02em;margin:0 0 8px}
.cmp__lead{margin:0 0 22px;max-width:56ch;font-size:14px;line-height:1.7;color:var(--ink-soft)}
.cmp__scroll{overflow-x:auto;overscroll-behavior-x:contain}
.cmp__table{width:100%;border-collapse:collapse;min-width:560px;text-align:left}
.cmp__table th,.cmp__table td{padding:14px 16px;vertical-align:top}
.cmp__table thead th{
  font-size:11px;font-weight:400;letter-spacing:.18em;text-transform:uppercase;
  border-bottom:1px solid var(--line);
}
.cmp__table tbody th{
  width:30%;font-weight:400;font-size:14px;line-height:1.5;color:var(--ink);
}
.cmp__table tbody tr + tr th,.cmp__table tbody tr + tr td{border-top:1px solid var(--line)}
.cmp__table tbody td{font-size:14px;line-height:1.5;color:var(--ink-soft)}
/* our column is the one being argued for, so it carries the weight */
.cmp__table .cmp__us{background:var(--bg-alt)}
.cmp__table thead .cmp__us{color:var(--ink)}
.cmp__table tbody .cmp__us .cmp__txt{color:var(--ink)}
.cmp__mark{
  display:inline-grid;place-items:center;width:18px;height:18px;margin-right:10px;
  border-radius:50%;font-size:11px;line-height:1;vertical-align:-3px;
}
.cmp__mark--yes{background:var(--accent);color:#fff}
.cmp__mark--no{background:transparent;border:1px solid var(--line);color:var(--ink-faint)}
.cmp__txt{display:inline}
@media (max-width:700px){
  .cmp__table th,.cmp__table td{padding:12px}
  .cmp__table tbody th{width:34%}
}

/* ---- inline data chart (AI Solutions) ---- */
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.chart{margin:clamp(26px,4vh,38px) 0 0;max-width:620px}
@media (min-width:900px){.svc-body--chart .chart{margin-top:4px;max-width:none}}
.chart__cap{
  margin:0 0 14px;font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-faint);
}
.chart__plot{position:relative}
.chart__svg{width:100%;height:auto;overflow:visible}
.chart__grid{stroke:var(--line);stroke-width:1}
.chart__ytick,.chart__xtick{
  fill:var(--ink-faint);font-family:var(--font);font-size:11px;letter-spacing:.04em;
}
.chart__area{fill:var(--accent);opacity:.08}
.chart__line{fill:none;stroke:var(--accent);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.chart__dot{
  fill:var(--bg);stroke:var(--accent);stroke-width:2;
  transition:r .25s var(--ease-out),fill .25s var(--ease);
}
.chart__stem{stroke:var(--accent);stroke-width:1;opacity:0;transition:opacity .25s var(--ease)}
.chart__hit{fill:transparent;cursor:pointer}
.chart__pt{outline:none}
.chart__pt:hover .chart__dot,
.chart__pt:focus-visible .chart__dot{r:6.5;fill:var(--accent)}
.chart__pt:hover .chart__stem,
.chart__pt:focus-visible .chart__stem{opacity:.32}
.chart__pt:focus-visible .chart__dot{stroke-width:3}
.chart__tip{
  position:absolute;z-index:2;transform:translate(-50%,-140%);
  padding:7px 11px;border-radius:8px;pointer-events:none;white-space:nowrap;
  background:var(--ink);color:var(--bg);
  font-size:12px;line-height:1.35;letter-spacing:.01em;
}
.chart__tip b{font-weight:700}
.chart__note{margin:14px 0 0;font-size:12px;line-height:1.6;color:var(--ink-faint)}
.chart__note a{border-bottom:1px solid var(--line);transition:color .3s var(--ease)}
.chart__note a:hover{color:var(--accent)}
@media (prefers-reduced-motion:reduce){
  .chart__dot,.chart__stem{transition:none}
}
@media (min-width:900px){
  .svc-body{gap:28px}
  /* prose left, chart right */
  .svc-body--chart{grid-template-columns:minmax(0,1fr) minmax(300px,400px);gap:48px;align-items:start}
}
.svc-cta{border-top:1px solid var(--line);padding-top:clamp(30px,5vh,50px)}
.svc-cta__title{font-size:clamp(1.6rem,3.5vw,2.6rem);margin-bottom:10px}
.svc-cta__text{max-width:50ch;color:var(--ink-soft)}
.svc-nav{
  display:flex;justify-content:space-between;gap:16px;
  margin-top:clamp(40px,7vh,70px);padding-top:22px;border-top:1px solid var(--line);font-size:14px;
}
.svc-nav__link{color:var(--ink-soft);transition:color .3s var(--ease)}
.svc-nav__link:hover{color:var(--accent)}

/* ============ contact ============ */
/* dark mode veils the particle field behind the contact block */
html[data-theme="dark"] .contact{background:rgba(0,0,0,.5)}
html:not([data-theme="dark"]) .contact{background:rgba(255,255,255,.5)}
.contact{padding:clamp(70px,12vh,140px) var(--pad);border-top:1px solid var(--line)}
.contact__inner{position:relative;max-width:var(--max);margin:0 auto}
.contact__head{align-self:center}
.contact__title{font-size:clamp(1.75rem,3.2vw,2.9rem);letter-spacing:-.03em;margin-bottom:16px;text-wrap:balance}
.contact__lead{margin:0;font-size:clamp(.95rem,1.4vw,1.15rem);line-height:1.6;color:var(--ink-soft)}

.contact__grid{display:grid;grid-template-columns:1fr;gap:clamp(24px,4vw,48px);align-items:start}
@media (min-width:900px){ .contact__grid{grid-template-columns:1fr 1fr} }

.contact__details{display:flex;flex-wrap:wrap;gap:clamp(18px,2.6vw,34px);margin-top:clamp(20px,3vw,28px)}
.contact__details li{display:grid;gap:3px;min-width:0}
.contact__label{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-faint)}
.contact__details a{font-size:clamp(1rem,1.5vw,1.15rem);transition:color .3s var(--ease)}
.contact__details a:hover{color:var(--accent)}

/* map desaturated to a near-white plan view */
.contact__map{margin:0}
.contact__map-frame{
  position:relative;border-radius:20px;overflow:hidden;
  background:var(--svc-card);aspect-ratio:4/3;
}
.contact__map-frame iframe{
  position:absolute;left:0;top:0;width:100%;height:100%;border:0;
  /* a pale plan view: land clamps to white and labels darken, while the
     water keeps its blue. contrast runs before brightness so the light
     fills push past 1.0 instead of being pulled back toward mid-grey. */
  filter:saturate(.55) contrast(1.28) brightness(1.1);
}

.field{display:grid;gap:6px}
.field label{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-faint)}
.field input,.field textarea,.field select{
  width:100%;font:inherit;font-size:15px;color:var(--ink);
  background:var(--bg);border:1px solid var(--line);border-radius:12px;
  padding:12px 14px;resize:vertical;
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(34,63,255,.14);
}
/* the native arrow is drawn in the OS color, which reads as a light-mode
   artefact on the dark dialog, so it is replaced with our own chevron */
.field select{
  appearance:none;cursor:pointer;padding-right:38px;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),
                   linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-size:6px 6px,6px 6px;
  background-position:calc(100% - 20px) 55%,calc(100% - 14px) 55%;
  background-repeat:no-repeat;
}
.field textarea{min-height:82px;line-height:1.6}
/* honeypot: off-screen rather than display:none, which bots skip */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
/* the note only exists once a need has been chosen */
.field[hidden]{display:none}

/* ============ footer ============ */
/* ============ footer ============
   Structure follows the reference: a narrow intro column, an empty gutter,
   then a half-width block of three stacked link/detail columns.          */
/* dark mode veils the particle field behind the footer */
html[data-theme="dark"] .foot{background:rgba(0,0,0,.75)}
html:not([data-theme="dark"]) .foot{background:rgba(255,255,255,.75)}
.foot{
  color:var(--ink);
  padding:clamp(60px,10vw,140px) var(--pad) clamp(40px,8vw,155px);
  border-top:1px solid var(--line);
}
.foot__row{
  max-width:var(--max);margin:0 auto;
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(30px,5vw,60px);
}
.foot__intro{grid-column:1 / 2}
.foot__mark{display:block;margin-bottom:16px;color:var(--ink)}
.foot__logo{width:86px;height:48px;overflow:visible}
.foot__crafted{font-size:1.05rem;letter-spacing:-.01em;margin:0 0 6px}
.foot__by{font-size:.86rem;color:var(--ink-soft);margin:0 0 14px}
.foot__blurb{font-size:.86rem;line-height:1.65;color:var(--ink-soft);margin:0;max-width:34ch}
.foot__cols{
  /* as many equal columns as there are children: the english footer carries a
     services list that the translated ones do not, so a fixed count would
     leave a hole on /fr/ and /es/ */
  grid-column:2 / 5;
  display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:clamp(20px,3vw,40px);
}
.foot__col p{margin:0 0 4px;font-size:.86rem;color:var(--ink-soft)}
.foot__col ul{display:grid;gap:4px}
.foot__col li a{font-size:.86rem;color:var(--ink-soft);transition:color .3s var(--ease)}
.foot__col li a:hover{color:var(--ink)}
.foot__label{
  margin:0 0 14px;
  font-family:var(--font);font-size:11px;font-weight:400;
  letter-spacing:.18em;text-transform:uppercase;color:var(--ink-faint);
}
.foot__muted{color:var(--ink-faint)!important}
/* the google profile link is an icon: the name lives in the tooltip and the
   accessible name, so nothing is lost for a screen reader */
.foot__gmb{
  display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;margin-top:10px;border-radius:9px;
  color:var(--ink-soft);border:1px solid var(--line);
  transition:color .3s var(--ease),border-color .3s var(--ease),background-color .3s var(--ease);
}
.foot__gmb svg{width:17px;height:17px;display:block}
.foot__gmb:hover,.foot__gmb:focus-visible{color:var(--ink);border-color:var(--ink)}
.foot__mail{
  display:inline-block;margin-top:8px;font-size:.86rem;
  background-image:linear-gradient(currentColor,currentColor);
  background-size:100% 1px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size .5s var(--ease-out);
}
.foot__mail:hover{background-size:0% 1px}
.foot__base{
  max-width:var(--max);margin:clamp(50px,8vw,100px) auto 0;
  display:flex;flex-wrap:wrap;justify-content:space-between;gap:12px;
  font-family:var(--font);
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint);
}

/* ============ responsive ============ */
@media (max-width:860px){
  .foot__row{grid-template-columns:1fr;gap:clamp(30px,6vw,44px)}
  .foot__intro,.foot__cols{grid-column:1 / -1}
  .foot__cols{grid-auto-flow:row;grid-template-columns:repeat(2,1fr);gap:28px}
}
@media (max-width:520px){
  .foot__cols{grid-auto-flow:row;grid-template-columns:1fr;gap:26px}
  .utils{top:14px;right:14px;padding:0 8px;gap:2px}
  .nav{top:14px;left:14px;right:auto;max-width:calc(100vw - 28px)}
  .nav.is-open{right:14px}
  .menu__nav{gap:10px;padding:30px 0 14px}
  .menu__nav a{font-size:30px;line-height:30px}
}

/* ============ motion prefs ============ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .char{transform:none}
  [data-reveal]{opacity:1;transform:none}
  .thumb{transform:none}
  .project__link:hover .thumb{transform:none}
}

/* ============ booking dialog ============ */
.booking{
  width:min(760px,calc(100vw - 32px));max-width:none;padding:clamp(22px,3vw,34px);
  /* the calendar makes this tall — keep it inside the viewport and scroll */
  max-height:calc(100dvh - 32px);overflow:auto;overscroll-behavior:contain;
  border:0;border-radius:20px;background:var(--card);color:var(--ink);
  font-family:var(--font);
}
.booking::backdrop{background:rgba(0,0,0,.55);backdrop-filter:blur(6px)}
.booking__close{
  position:absolute;top:14px;right:14px;display:grid;place-items:center;
  width:32px;height:32px;border:0;border-radius:50%;background:transparent;
  color:var(--ink-faint);cursor:pointer;transition:color .3s var(--ease)
}
.booking__close:hover{color:var(--ink)}
.booking__title{font-size:clamp(1.2rem,2.4vw,1.6rem);letter-spacing:-.02em;margin-bottom:8px;padding-right:40px}
.booking__lead{margin:0 0 clamp(18px,2.4vw,26px);font-size:14px;line-height:20px;color:var(--ink-soft)}
.booking__grid{display:grid;gap:clamp(14px,1.8vw,20px)}
@media (min-width:640px){ .booking__grid{grid-template-columns:1fr 1fr} }

.booking__cal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.booking__month{font-size:13px;letter-spacing:.02em}
.booking__nav{
  width:24px;height:24px;border:1px solid var(--line);border-radius:50%;
  background:transparent;color:var(--ink);cursor:pointer;font-size:13px;line-height:1;
  transition:background-color .3s var(--ease),color .3s var(--ease)
}
.booking__nav:hover:not(:disabled){background:var(--accent);color:#fff;border-color:var(--accent)}
.booking__nav:disabled{opacity:.3;cursor:default}
.booking__dow,.booking__days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.booking__dow{margin-bottom:4px}
.booking__dow span{text-align:center;font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint)}
.booking__day{
  height:30px;display:grid;place-items:center;
  border:0;border-radius:6px;background:var(--svc-pill);color:var(--ink);
  font:inherit;font-size:12px;cursor:pointer;
  transition:background-color .25s var(--ease),color .25s var(--ease)
}
.booking__day:hover:not(:disabled){background:var(--accent);color:#fff}
.booking__day:disabled{background:transparent;color:var(--ink-faint);opacity:.45;cursor:default}
.booking__day.is-chosen{background:var(--accent);color:#fff}
.booking__day--pad{background:transparent;pointer-events:none}

.booking__slots-label{margin:0 0 8px;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-faint)}
.booking__slot-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(64px,1fr));gap:5px;max-height:214px;overflow:auto}
.booking__hint{grid-column:1/-1;margin:0;font-size:12px;line-height:1.5;color:var(--ink-faint)}
.booking__slot{
  padding:6px 8px;border:1px solid var(--line);border-radius:7px;
  background:transparent;color:var(--ink);font:inherit;font-size:12px;cursor:pointer;text-align:center;
  transition:background-color .25s var(--ease),color .25s var(--ease),border-color .25s var(--ease)
}
.booking__slot:hover{border-color:var(--accent)}
.booking__slot.is-chosen{background:var(--accent);color:#fff;border-color:var(--accent)}

/* ---- booking: call preferences, shown before the calendar ---- */
.booking__prefs{display:grid;gap:0;margin:0}
.bk-group{
  border:0;padding:clamp(16px,2vw,20px) 0;margin:0;min-width:0;
  border-top:1px solid var(--line);
}
.booking__prefs .bk-group:first-child{padding-top:0;border-top:0}
.bk-legend{
  display:flex;align-items:center;gap:10px;
  padding:0;margin:0 0 12px;font-size:11px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-faint);
}
.bk-num{
  flex:none;display:grid;place-items:center;width:20px;height:20px;border-radius:50%;
  border:1px solid var(--line);
  font-size:10px;letter-spacing:0;color:var(--ink-soft);
}
.bk-chips{display:flex;flex-wrap:wrap;gap:8px}
.bk-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.bk-sep{flex:none;width:1px;height:22px;background:var(--line)}
.bk-sep[hidden],.bk-chips--part[hidden]{display:none}
.bk-chip{
  padding:9px 16px;border:1px solid var(--line);border-radius:26px;
  background:transparent;color:var(--ink);font:inherit;font-size:13px;line-height:1.2;
  cursor:pointer;
  transition:background-color .25s var(--ease),border-color .25s var(--ease),color .25s var(--ease);
}
.bk-chip:hover{border-color:var(--ink-faint)}
.bk-chip[aria-checked="true"]{background:var(--accent);border-color:var(--accent);color:#fff}
/* the exact-slot chip reads as the odd one out, since it opens the calendar */
.bk-chip--exact{border-style:dashed}
.bk-chip--exact[aria-checked="true"]{border-style:solid}
.booking__grid[hidden]{display:none}
.booking__grid{margin-top:14px}
/* the calendar slides in when an exact time is asked for */
.booking__grid:not([hidden]){animation:bk-reveal .35s var(--ease-out) both}
@keyframes bk-reveal{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .booking__grid:not([hidden]){animation:none}
  .bk-chip{transition:none}
}

.bk-group--fields{border-top:1px solid var(--line);padding:clamp(16px,2vw,20px) 0}
.booking__fields{display:grid;gap:12px;margin:0}
.field__opt{text-transform:none;letter-spacing:.02em;opacity:.65}
@media (min-width:640px){ .booking__fields{grid-template-columns:repeat(3,1fr)} }
.booking__foot{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;
  margin-top:clamp(16px,2vw,22px)
}
.booking__summary{margin:0;font-size:13px;color:var(--ink-soft);flex:1 1 220px}
.booking__summary[data-state="error"]{color:#d23b3b}
.booking__foot .btn{cursor:pointer}
.contact__book{margin-top:20px;cursor:pointer}


/* ============ 404 ============ */
.nf{
  min-height:100vh;min-height:100svh;
  display:flex;flex-direction:column;align-items:flex-start;justify-content:center;
  gap:14px;padding:0 var(--pad);max-width:var(--max);margin:0 auto;
}
.nf__code{margin:0;font-size:13px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint)}
.nf__title{margin:0;font-size:clamp(2rem,6vw,3.6rem);line-height:1.05;letter-spacing:-.03em}
.nf__text{margin:0 0 10px;max-width:52ch;font-size:1rem;line-height:1.7;color:var(--ink-soft)}
