/* ==========================================================================
   Modnyco Design System — editorial, all-white
   Tokens → base → layout → components → utilities → responsive

   White page, near-black ink, 1px hairlines, square corners, medium-weight
   neo-grotesk headlines. Brand cyan survives only as the focus ring and a
   link hover. Entrance / scroll motion lives in motion.css (separate owner).
   ========================================================================== */

/* --- Tokens ------------------------------------------------------------- */
:root{
  /* Kept for admin.css, which still reads them. The public site does not. */
  --navy:#0C1A32;      --navy-deep:#080F1D;  --navy-soft:#0F2547;

  --ink:#111111;       --ink-2:#3a3a3a;      --muted:#6b6b6b;
  --cream:#FAFAF9;     --cream-2:#F4F4F2;    --cream-3:#EFEFEC;
  --line:#e6e6e3;      --line-2:#e6e6e3;     --line-strong:#cfcfcb;
  --cyan:#0AAFE0;      --cyan-dark:#0891C0;  --cyan-light:#5EE3F8; --cyan-wash:#E4F7FD;
  --green:#1CD63C;
  --danger:#D32F2F;    --danger-wash:#FEE8E8;
  --ok:#1B8A3A;        --ok-wash:#E6F6EA;

  /* Public-site surface tokens */
  --paper:#ffffff;     --panel:#FAFAF9;      --hair:#e6e6e3;
  /* Text/icons sitting ON an ink fill (primary buttons, active chips), and
     the primary button's hover fill. Both flip in dark mode. */
  --on-ink:#ffffff;    --ink-hover:#2b2b2b;
  --radius:2px;
  --track:-0.03em;

  --font-display:'Geist',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-body:'Geist',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-mono:'Geist Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  --wrap:1440px;
  --gutter:48px;
  --nav-h:60px;
  --nav-top:16px;
  /* Admin still uses these radii; the public site uses --radius. */
  --r-sm:6px; --r-md:10px; --r-lg:14px; --r-xl:20px;
  --shadow-card:0 12px 40px rgba(17,17,17,.08);
  --shadow-cta:0 8px 24px rgba(17,17,17,.14);
  --ease:cubic-bezier(.4,0,.2,1);

  /* Diagonal notch cut out of the top-right corner of card images. */
  --notch:polygon(0 0,calc(100% - 128px) 0,calc(100% - 72px) 56px,100% 56px,100% 100%,0 100%);
}

/* --- Dark theme ----------------------------------------------------------
 * Set by the toggle in the nav (or the visitor's system setting) via
 * html[data-theme="dark"] — public pages only; the admin never gets it.
 * The ink/paper pair inverts, so primary buttons become light-on-dark.     */
html[data-theme="dark"]{
  color-scheme:dark;
  --ink:#f3f3f1;       --ink-2:#c8c8c4;      --muted:#94948f;
  --paper:#0f0f10;     --panel:#151517;      --hair:#2a2a2d;
  --cream:#151517;     --cream-2:#1b1b1d;    --cream-3:#202023;
  --line:#2a2a2d;      --line-2:#2a2a2d;     --line-strong:#3c3c40;
  --cyan-dark:#3cc8f0; --cyan-wash:#0c2a35;
  --danger:#ff6b6b;    --danger-wash:#3a1414;
  --ok:#4cd07a;        --ok-wash:#0f2e18;
  --on-ink:#0f0f10;    --ink-hover:#ffffff;
  --shadow-card:0 12px 40px rgba(0,0,0,.5);
  --shadow-cta:0 8px 24px rgba(0,0,0,.5);
}
/* Colours change with the theme, smoothly, but only while switching. */
html.theme-switching,html.theme-switching *{transition:background-color .35s ease,color .35s ease,
  border-color .35s ease,fill .35s ease,stroke .35s ease!important}

/* --- Base --------------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{background:var(--paper);color:var(--ink);font-family:var(--font-body);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden;
  font-feature-settings:"ss01","cv11"}

/* Hide the page scrollbar. Wheel, trackpad, keys, touch and the back-to-top
   button all still scroll — only the bar itself goes. Both html and body
   carry it: body sets overflow-x, so either box can own the viewport bar. */
html,body{scrollbar-width:none;-ms-overflow-style:none}
html::-webkit-scrollbar,body::-webkit-scrollbar{width:0;height:0;display:none}
img,svg,video{max-width:100%;display:block}
/* Components set their own display, which would otherwise beat the UA
   [hidden] rule and make the attribute a no-op (e.g. the project filters). */
[hidden]{display:none!important}
a{color:inherit;text-decoration:none}
button,input,textarea,select{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--cyan);outline-offset:3px;border-radius:var(--radius)}

h1,h2,h3,h4{font-family:var(--font-display);font-weight:500;line-height:1.08;letter-spacing:var(--track)}

.skip-link{position:absolute;left:-9999px;top:0;z-index:999;background:var(--ink);
  color:#fff;padding:12px 20px;font-weight:500}
.skip-link:focus{left:0}

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* --- Layout ------------------------------------------------------------- */
.wrap{max-width:var(--wrap);margin:0 auto;padding-inline:var(--gutter)}
.section{padding-block:112px}
.section--tight{padding-block:64px}
.section--panel{background:var(--panel);border-block:1px solid var(--hair)}
/* One screen tall, content centred. The top padding clears the floating nav;
   taller content simply grows the section. */
.section--screen{min-height:100vh;min-height:100svh;display:flex;flex-direction:column;
  justify-content:center;padding-block:calc(var(--nav-top) + var(--nav-h) + 40px) 64px}
.section--screen>.wrap{width:100%}
main{min-height:60vh}

/* Small numbered label: "(01) What we do". */
.eyebrow{font-family:var(--font-mono);font-size:12px;letter-spacing:.02em;font-weight:400;
  color:var(--muted);text-transform:uppercase;margin-bottom:16px;
  display:flex;align-items:center;gap:10px}
.eyebrow::before{content:"";width:7px;height:7px;background:var(--ink);flex-shrink:0}
.eyebrow--light{color:var(--muted)}

.lede{font-size:18px;font-weight:400;color:var(--muted);line-height:1.6;letter-spacing:-.005em}

/* --- Nav (global) ------------------------------------------------------- */
/* A boxed white bar inset from the page edges and lined up with the content.
   It stays white on scroll; .is-stuck (site.js) only adds a soft shadow.
   No transform / backdrop-filter on .nav: either would trap the fixed
   mobile drawer inside the bar. */
.nav{position:fixed;z-index:200;top:var(--nav-top);height:var(--nav-h);
  left:max(10px,calc(max(0px,(100vw - var(--wrap)) / 2) + var(--gutter) - 14px));
  right:max(10px,calc(max(0px,(100vw - var(--wrap)) / 2) + var(--gutter) - 14px));
  display:flex;align-items:center;gap:40px;padding:0 8px 0 14px;
  background:var(--paper);border:1px solid var(--hair);
  transition:box-shadow .3s var(--ease),border-color .3s var(--ease)}
.nav.is-stuck{border-color:var(--line-strong);box-shadow:0 8px 28px rgba(17,17,17,.07)}
/* Scrolling down slides it up out of view (site.js). transform is none again
   whenever it shows, so it never traps the fixed mobile menu inside it. */
.nav{transition:box-shadow .3s var(--ease),border-color .3s var(--ease),transform .4s var(--ease)}
.nav.is-hidden{transform:translateY(calc(-100% - var(--nav-top) - 12px));box-shadow:none}

.nav__logo{display:flex;align-items:center;gap:10px;flex-shrink:0;position:relative;z-index:2}
.nav__logo img{height:30px;width:auto}
.nav__logo-text{font-family:var(--font-display);font-weight:600;font-size:19px;
  letter-spacing:-.02em;color:var(--ink)}
.nav__logo-text i{font-style:normal;color:var(--ink)}

.nav__links{display:flex;align-items:center;gap:30px;margin-right:auto}
.nav__link{font-size:15px;color:var(--ink-2);transition:color .2s var(--ease)}
.nav__link:hover{color:var(--ink)}
.nav__link[aria-current="page"]{color:var(--ink);font-weight:500}
.nav__links>.btn{display:none} /* mobile-drawer CTA; desktop uses .nav__cta-desktop */
.nav__cta-desktop{padding:11px 16px}

/* Legacy modifiers: the nav is white everywhere now. */
.nav--over .nav__link{color:var(--ink-2)}
.nav--over .nav__link[aria-current="page"],.nav--over .nav__logo-text{color:var(--ink)}

/* Light / dark toggle: shows the moon in light mode, the sun in dark. */
.theme-toggle{display:grid;place-items:center;width:40px;height:40px;flex-shrink:0;
  background:none;border:1px solid var(--hair);color:var(--ink);cursor:pointer;
  transition:border-color .2s var(--ease),background .2s var(--ease)}
.theme-toggle:hover{border-color:var(--ink)}
.theme-toggle svg{display:block}
.theme-toggle .i-sun{display:none}
html[data-theme="dark"] .theme-toggle .i-sun{display:block}
html[data-theme="dark"] .theme-toggle .i-moon{display:none}
.nav .theme-toggle + .nav__cta-desktop{margin-left:-28px}
.nav__burger{display:none;width:44px;height:44px;background:none;border:0;cursor:pointer;
  flex-direction:column;justify-content:center;gap:5px;padding:0 11px;margin-left:auto}
.nav__burger span{display:block;height:1.5px;width:100%;background:var(--ink);
  transition:transform .28s var(--ease),opacity .2s var(--ease)}
.nav.is-open .nav__burger span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
.nav.is-open .nav__burger span:nth-child(2){opacity:0}
.nav.is-open .nav__burger span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

/* --- Custom cursor ------------------------------------------------------ *
 * An ink dot and a trailing hairline ring. site.js still tags .is-light over
 * what used to be dark sections; on an all-white site that state is ignored. */
.has-cursor,.has-cursor a,.has-cursor button,.has-cursor [role="button"],
.has-cursor input,.has-cursor textarea,.has-cursor select,.has-cursor label{cursor:none}
.cursor-dot,.cursor-ring{position:fixed;top:0;left:0;z-index:9999;pointer-events:none;
  border-radius:50%;opacity:0;transition:opacity .25s var(--ease)}
.has-cursor .cursor-dot,.has-cursor .cursor-ring{opacity:1}
.cursor-dot{width:7px;height:7px;margin:-3.5px 0 0 -3.5px;background:var(--ink);
  transition:opacity .25s var(--ease),transform .18s var(--ease)}
.cursor-ring{width:36px;height:36px;margin:-18px 0 0 -18px;border:1px solid rgba(17,17,17,.55);
  transition:opacity .25s var(--ease),width .25s var(--ease),height .25s var(--ease),
             margin .25s var(--ease),background .25s var(--ease)}
.cursor-dot.is-light{background:var(--ink)}
.cursor-ring.is-light{border-color:rgba(17,17,17,.55)}
.cursor-ring.is-active{width:56px;height:56px;margin:-28px 0 0 -28px;background:rgba(17,17,17,.05)}
.cursor-ring.is-active.is-light{background:rgba(17,17,17,.05)}
.cursor-dot.is-active{transform:scale(.4)}
@media (hover:none),(pointer:coarse),print{.cursor-dot,.cursor-ring{display:none}}

/* --- Back to top -------------------------------------------------------- */
.to-top{position:fixed;right:24px;bottom:24px;z-index:190;width:44px;height:44px;
  display:grid;place-items:center;border:1px solid var(--hair);border-radius:var(--radius);
  background:var(--paper);color:var(--ink);cursor:pointer;box-shadow:0 6px 20px rgba(17,17,17,.08);
  opacity:0;transform:translateY(12px);pointer-events:none;
  transition:opacity .28s var(--ease),transform .28s var(--ease),background .2s var(--ease),
             color .2s var(--ease),border-color .2s var(--ease)}
.to-top.is-on{opacity:1;transform:none;pointer-events:auto}
.to-top:hover{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
.to-top svg{display:block}
@media (max-width:640px){.to-top{right:16px;bottom:16px;width:42px;height:42px}}

/* --- Buttons ------------------------------------------------------------ */
.btn{display:inline-flex;align-items:center;gap:8px;font-size:15px;font-weight:500;
  letter-spacing:-.005em;line-height:1.2;padding:14px 22px;border-radius:var(--radius);
  border:1px solid transparent;cursor:pointer;white-space:nowrap;
  transition:background .2s var(--ease),color .2s var(--ease),border-color .2s var(--ease)}
.btn--primary{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
.btn--primary:hover{background:var(--ink-hover);border-color:var(--ink-hover);color:var(--on-ink)}
.btn--sm{font-size:14px;padding:10px 16px}
.btn--ghost{border-color:var(--ink);color:var(--ink);background:transparent}
.btn--ghost:hover{background:var(--ink);color:var(--on-ink)}
.btn--quiet{background:var(--panel);border-color:var(--hair);color:var(--ink)}
.btn--quiet:hover{background:var(--cream-3)}
.btn--danger{background:var(--danger-wash);color:var(--danger)}
.btn--danger:hover{background:#fcd6d6}
.btn--link{font-size:15px;color:var(--muted);padding:14px 4px}
.btn--link:hover{color:var(--ink)}

/* "View all" — a hairline box with an arrow that steps on hover. */
.link-more{display:inline-flex;align-items:center;gap:10px;flex-shrink:0;
  padding:11px 16px;border:1px solid var(--ink);border-radius:var(--radius);
  font-size:14px;font-weight:500;color:var(--ink);background:transparent;
  transition:color .2s var(--ease),background .2s var(--ease)}
.link-more::after{content:"→";transition:transform .28s var(--ease)}
.link-more:hover{color:var(--on-ink);background:var(--ink)}
.link-more:hover::after{transform:translateX(3px)}

/* --- Reveal on scroll --------------------------------------------------- */
[data-reveal]{opacity:0;transform:translateY(36px);
  transition:opacity .7s var(--ease),transform .7s var(--ease)}
[data-reveal].is-in{opacity:1;transform:none}
@keyframes fadeUp{from{opacity:0;transform:translateY(28px)}to{opacity:1;transform:none}}
/* Held opaque for most of the cycle — the word is only in motion at the swap. */
@keyframes textCycle{0%{opacity:0;transform:translateY(10px)}8%,92%{opacity:1;transform:none}
  100%{opacity:0;transform:translateY(-8px)}}
@keyframes cookieIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
.anim-up{animation:fadeUp .72s var(--ease) both}

/* --- Loading screen (home) ---------------------------------------------- *
 * Only rendered on the home page and only when the inline script in
 * partials/loader.php arms it (html.is-loading). site.js fills the rule and
 * lifts the panel; if anything goes wrong the CSS timer below still clears
 * it, so it can never hold the page.                                      */
.loader{display:none}
html.is-loading .loader{display:flex;position:fixed;inset:0;z-index:1000;align-items:center;
  justify-content:center;background:var(--paper);
  animation:loaderBail .01s 4.5s forwards}
@keyframes loaderBail{to{visibility:hidden;opacity:0}}
.loader__inner{width:min(420px,calc(100vw - 48px));text-align:center}
.loader__chip{width:min(300px,62vw,46svh);margin:0 auto 18px}
.loader__chip .chip{width:100%;height:auto}
/* Loader traces start undrawn; site.js advances each one's dash offset. */
.trace--draw{stroke-dasharray:100 100;stroke-dashoffset:100;stroke-opacity:.35}
.chip--loader .pad{transition:fill .3s var(--ease),stroke .3s var(--ease)}
.chip--loader .pad.is-on{fill:var(--cyan);stroke:var(--cyan-dark);stroke-opacity:1}
.loader__word{font-family:'Clash Display',var(--font-display);font-weight:600;text-transform:uppercase;
  font-size:clamp(26px,4.2vw,40px);letter-spacing:-.01em;line-height:1;color:var(--ink);
  height:1em;overflow:hidden;margin-bottom:22px}
.loader__word span{display:inline-block;animation:loaderWord .35s var(--ease) both}
@keyframes loaderWord{from{opacity:0;transform:translateY(60%)}to{opacity:1;transform:none}}
.loader__bar{height:1px;background:var(--hair);overflow:hidden}
.loader__bar span{display:block;height:100%;width:100%;background:var(--ink);
  transform:scaleX(0);transform-origin:left}
.loader__meta{display:flex;justify-content:space-between;gap:16px;margin-top:12px;text-align:left;
  font-family:var(--font-mono);font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.loader__meta [data-loader-count]{color:var(--ink);font-variant-numeric:tabular-nums}
/* The lift: the panel wipes upward off the page. */
.loader.is-out{clip-path:inset(0 0 100% 0);transition:clip-path .8s cubic-bezier(.76,0,.24,1)}
.loader.is-out .loader__inner{opacity:0;transform:translateY(-16px);
  transition:opacity .35s var(--ease),transform .5s var(--ease)}

/* --- Hero (home) -------------------------------------------------------- */
/* Pure typography. A four-line uppercase statement set as large as the width
   allows, then one quiet row: the intro and the two actions. */
.hero{position:relative;background:var(--paper);min-height:100vh;min-height:100svh;
  display:flex;padding:132px 0 0}
.hero__inner{display:flex;flex-direction:column;flex:1;width:100%}
.hero__eyebrow{margin-bottom:28px}

/* The stage takes the spare height and centres the statement in it; the h1
   itself stays a plain block so its <br>s break lines normally. */
.hero__stage{flex:1 0 auto;display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,420px);
  align-items:center;gap:32px;padding-bottom:44px}
.hero__main{min-width:0}

/* --- Hero chip ------------------------------------------------------------
 * The die, its pins and the traces fanning out to pads (built in home.php).
 * Ink hairlines at low strength; cyan pulses travel out along each trace;
 * site.js tilts the whole drawing toward the pointer and marks the traces
 * nearest the cursor .is-hot.                                              */
.hero__art{position:relative;width:min(100%,calc(100svh - 430px));aspect-ratio:1;
  justify-self:end;perspective:1100px}
.chip{display:block;width:100%;height:100%;overflow:visible;transform-style:preserve-3d;
  will-change:transform}
.chip__dot{fill:var(--ink);fill-opacity:.09}
.trace{fill:none;stroke:var(--ink);stroke-opacity:.2;stroke-width:1.4;stroke-linejoin:round;
  transition:stroke .35s var(--ease),stroke-opacity .35s var(--ease),stroke-width .35s var(--ease)}
.trace.is-hot{stroke:var(--cyan-dark);stroke-opacity:.9;stroke-width:1.8}
.trace__pulse{fill:none;stroke:var(--cyan);stroke-width:2.4;stroke-linecap:round;
  stroke-dasharray:7 100;stroke-dashoffset:107;opacity:.75;
  animation:tracePulse var(--t,3s) linear var(--d,0s) infinite}
@keyframes tracePulse{to{stroke-dashoffset:0}}
.pad{fill:var(--paper);stroke:var(--ink);stroke-opacity:.45;stroke-width:1.4;
  transition:fill .35s var(--ease),stroke .35s var(--ease)}
.pad.is-hot{fill:var(--cyan);stroke:var(--cyan-dark);stroke-opacity:1}
.pin{fill:var(--ink);fill-opacity:.75}
.die{fill:var(--paper);stroke:var(--ink);stroke-width:1.6}
.die__inner{fill:var(--panel);stroke:var(--ink);stroke-opacity:.15}
.die__label{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.08em;fill:var(--muted)}
.die__mark{fill:none;stroke:var(--ink);stroke-opacity:.35}
@media (prefers-reduced-motion:reduce){.trace__pulse{animation:none;opacity:0}}

/* The one display face on the site: Clash Display, self-hosted. Its sharp
   cuts carry the statement on their own, so tracking stays near neutral. */
.hero__title{font-family:'Clash Display',var(--font-display);font-weight:600;
  font-size:clamp(50px,8.6vw,140px);line-height:.92;letter-spacing:-.02em;
  text-transform:uppercase;color:var(--ink)}
/* The hero is exactly one screen tall, so the title also answers to the
   screen height: four lines at .92 plus the nav, eyebrow and intro row must
   fit in 100svh. Whichever limit is tighter wins. */
.hero .hero__title{font-size:clamp(34px,min(8.6vw,calc((100svh - 420px) / 3.7)),140px)}
/* Beside the chip the width limit is its column, not the viewport: the
   longest line (ELECTRONICS) is ~7.2em wide in Clash Display. */
@media (min-width:1081px){
  .hero .hero__title{font-size:clamp(40px,min(calc((min(100vw, var(--wrap)) - var(--gutter) * 2 - 452px) / 7.2),calc((100svh - 420px) / 3.7)),128px)}
}
.hero h1{color:var(--ink)}
/* The rotating word: muted, on its own line. site.js swaps the text. */
.hero__word{display:inline-block;position:relative;max-width:100%}
/* The rotating word in brand cyan, darkened just enough to hold contrast on
   white at this size. */
.hero__word em{font-style:normal;color:var(--cyan-dark);display:inline-block;
  animation:textCycle 3.4s var(--ease) infinite}

/* One quiet row under the statement: intro and sectors left, actions right. */
.hero__foot{display:flex;align-items:flex-end;justify-content:space-between;gap:32px 48px;
  flex-wrap:wrap;padding:28px 0 48px;border-top:1px solid var(--hair)}
.hero__intro{flex:1 1 420px;min-width:0}
.hero__lede{font-size:18px;color:var(--ink-2);line-height:1.55;max-width:46ch;letter-spacing:-.01em}
.hero__sectors{margin-top:14px;font-family:var(--font-mono);font-size:11px;text-transform:uppercase;
  letter-spacing:.02em;color:var(--muted)}
.hero__actions{display:flex;gap:10px;flex-wrap:wrap;flex-shrink:0}

/* --- Page hero (inner pages) -------------------------------------------- */
.page-hero{padding:168px var(--gutter) 0}
.page-hero__row{display:flex;justify-content:space-between;align-items:flex-end;
  gap:60px;flex-wrap:wrap}
.page-hero__row>div:first-child{flex:1 1 480px;min-width:0}
.page-hero__row>p{flex:0 1 440px;min-width:0}
/* No lede beside it (detail pages): the title block is first AND last child,
   so it must not pick up the lede column's 440px basis — take the full row. */
.page-hero__row>div:only-child{flex:1 1 100%}
.page-hero h1{font-weight:500;font-size:clamp(40px,5.6vw,84px);letter-spacing:-.04em;
  line-height:1;color:var(--ink);overflow-wrap:break-word;hyphens:auto}
.page-hero p{max-width:440px}
/* Sentence-length titles (articles, case studies): smaller and wider, so they
   read as a headline in two or three lines rather than a tower of words. */
.page-hero--long h1{font-size:clamp(34px,4.4vw,64px);letter-spacing:-.035em;line-height:1.04;
  max-width:24ch}
.page-hero__rule{height:1px;background:var(--hair);margin-top:56px}

/* --- Section headers ---------------------------------------------------- */
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;
  margin-bottom:48px;gap:24px;flex-wrap:wrap}
.sec-head h2{font-size:clamp(32px,4vw,56px);color:var(--ink);letter-spacing:-.035em;line-height:1.02}
.sec-head--center{flex-direction:column;align-items:center;text-align:center}
.sec-head--center .eyebrow{justify-content:center}

/* --- Service tile grid (home) ------------------------------------------- */
.tiles{display:grid;grid-template-columns:repeat(4,1fr);
  border-left:1px solid var(--hair);border-top:1px solid var(--hair)}
.tile{background:var(--paper);padding:32px 28px 30px;display:flex;flex-direction:column;gap:28px;
  border-right:1px solid var(--hair);border-bottom:1px solid var(--hair);
  transition:background .22s var(--ease)}
.tile:hover{background:var(--panel)}
.tile__icon{width:44px;height:44px;border:1px solid var(--hair);border-radius:var(--radius);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--ink);background:var(--paper)}
.tile h3{font-size:22px;margin-bottom:12px;line-height:1.2;letter-spacing:-.02em}
.tile p{font-size:15px;color:var(--muted);line-height:1.6}
.tile__body{flex:1}
.tile__link{font-size:14px;color:var(--ink);font-weight:500;align-self:flex-start}
.tile__link:hover{color:var(--cyan-dark)}

/* --- Card grid (projects / services / 404) ------------------------------ *
 * Same language as the hero cards: shared hairlines, notched image, and a
 * CSS-counter number box over the image, so the markup stays as it was.   */
/* Always three columns, so a short or filtered set (two services in a
   category) keeps the same card size instead of stretching to fill the row.
   Each card carries its own full border and overlaps its neighbours by 1px,
   so shared edges stay hairline and an empty slot has no stray rule. */
.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0;
  padding:0 1px 1px 0;counter-reset:card}
.card{position:relative;display:flex;flex-direction:column;background:var(--paper);color:inherit;
  border:1px solid var(--hair);margin:0 -1px -1px 0;counter-increment:card;
  min-width:0;transition:background .25s var(--ease)}
.card:hover{background:var(--panel)}

.card__media{position:relative;aspect-ratio:16/11;overflow:hidden;background:var(--cream-3);
  clip-path:var(--notch)}
.card__media img{width:100%;height:100%;object-fit:cover}
.card__media::after{content:"";position:absolute;inset:0 0 auto 0;height:38%;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.45),rgba(0,0,0,0))}
.card__media::before{content:counter(card,decimal-leading-zero);position:absolute;z-index:1;
  top:18px;left:18px;font-family:var(--font-mono);font-size:11px;line-height:1;color:#fff;
  padding:4px 5px;border:1px solid rgba(255,255,255,.85);background:rgba(17,17,17,.28)}
.card__body{padding:26px 26px 28px;display:flex;flex-direction:column;flex:1}
.card h3{font-size:21px;letter-spacing:-.02em;line-height:1.22;color:var(--ink);margin-bottom:10px}
.card p{font-size:15px;color:var(--muted);line-height:1.6;flex:1}
/* Tags sit under the description, as in the hero cards. */
.card .chips{order:3;margin:18px 0 0}
.card__cta{order:4;display:flex;align-items:center;gap:6px;margin-top:20px;font-size:14px;
  color:var(--ink);font-weight:500;transition:gap .3s var(--ease)}
.card__cta span{transition:transform .3s var(--ease)}
.card:hover .card__cta span{transform:translateX(4px)}
.chips{display:flex;gap:6px;margin-bottom:12px;flex-wrap:wrap}

/* --- Project sorting cards ---------------------------------------------- */
.filters{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  margin-bottom:48px;border-left:1px solid var(--hair);border-top:1px solid var(--hair)}
.filter{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:6px;
  text-align:left;padding:20px 22px 22px;min-height:150px;background:var(--paper);
  border:0;border-right:1px solid var(--hair);border-bottom:1px solid var(--hair);
  border-radius:0;cursor:pointer;transition:background .2s var(--ease)}
.filter__count{font-family:var(--font-mono);font-size:12px;line-height:1;color:var(--muted);
  padding:4px 5px;border:1px solid var(--hair);transition:color .2s var(--ease),border-color .2s var(--ease)}
.filter__name{font-family:var(--font-display);font-size:19px;font-weight:500;
  letter-spacing:-.02em;color:var(--ink);margin-top:auto}
.filter__hint{font-size:13px;line-height:1.5;color:var(--muted)}
/* Ink rule along the top of the chosen card. */
.filter::after{content:"";position:absolute;left:-1px;right:-1px;top:-1px;height:2px;
  background:var(--ink);transform:scaleX(0);transform-origin:left;transition:transform .3s var(--ease)}
.filter:hover{background:var(--panel)}
.filter[aria-current="true"]{background:var(--panel)}
.filter[aria-current="true"]::after{transform:scaleX(1)}
.filter[aria-current="true"] .filter__count{color:var(--on-ink);background:var(--ink);border-color:var(--ink)}

@media (max-width:560px){
  .filters{grid-template-columns:repeat(2,1fr)}
  .filter{min-height:112px;padding:16px}
  .filter__name{font-size:16px}
  .filter__hint{display:none}
}

/* Category pages and the noscript fallback keep a chip row. */
.filters--chips{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:36px;border:0}
.filter--chip{min-height:0;flex-direction:row;font-size:14px;font-weight:400;padding:8px 14px;
  border:1px solid var(--hair);border-radius:var(--radius);color:var(--ink-2);background:var(--paper)}
.filter--chip:hover{border-color:var(--ink);color:var(--ink);background:var(--paper)}
.filter--chip::after{display:none}
.filter--chip[aria-current="true"]{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}

/* --- Portfolio cards (home) -------------------------------------------- *
 * The zaro.ai card: image with the top-right corner cut, a mono number box
 * and kicker over it, then title, text and tags. A sideways row that starts
 * on the content edge and runs off the right of the screen.               */
.pf .sec-head{margin-bottom:40px}
.pf__nav{display:flex;align-items:center;gap:8px}
.pf__btn{display:grid;place-items:center;width:46px;height:46px;background:var(--paper);
  border:1px solid var(--ink);color:var(--ink);cursor:pointer;
  transition:background .2s var(--ease),color .2s var(--ease),opacity .2s var(--ease)}
.pf__btn:hover:not(:disabled){background:var(--ink);color:var(--on-ink)}
.pf__btn:disabled{opacity:.25;cursor:default}
.pf__nav .link-more{margin-left:8px}

/* Left padding lines the first card up with the content column. */
.pf__track{--pf-edge:max(var(--gutter),calc((100vw - var(--wrap)) / 2 + var(--gutter)));
  display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
  padding:0 var(--pf-edge) 1px;scroll-padding-inline:var(--pf-edge);
  scrollbar-width:none;outline:none}
.pf__track::-webkit-scrollbar{display:none}
.pf__track:focus-visible{outline:2px solid var(--ink);outline-offset:4px}
.zc{flex:0 0 calc((min(100vw, var(--wrap)) - var(--gutter) * 2) / 3);min-width:0;
  scroll-snap-align:start;display:flex;flex-direction:column;color:inherit;
  background:var(--paper);border:1px solid var(--hair);margin-right:-1px;
  transition:background .25s var(--ease)}
.zc:hover{background:var(--panel)}
.zc__media{position:relative;aspect-ratio:4/3;overflow:hidden;background:var(--cream-3);
  clip-path:var(--notch)}
.zc__media img{width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease)}
.zc:hover .zc__media img{transform:scale(1.04)}
/* A light scrim at the top only, so the white label always reads. */
.zc__media::after{content:"";position:absolute;inset:0 0 auto 0;height:45%;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.45),rgba(0,0,0,0))}
.zc__label{position:absolute;top:20px;left:20px;right:96px;z-index:1;display:flex;
  align-items:flex-start;gap:12px;color:#fff}
.zc__num{flex-shrink:0;font-family:var(--font-mono);font-size:11px;line-height:1;margin-top:5px;
  padding:4px 5px;border:1px solid rgba(255,255,255,.85);background:rgba(17,17,17,.25)}
.zc__kicker{font-size:20px;font-weight:500;letter-spacing:-.02em;line-height:1.2}
.zc__body{display:flex;flex-direction:column;flex:1;padding:28px 28px 30px}
.zc__title{font-size:21px;font-weight:500;letter-spacing:-.02em;line-height:1.22;color:var(--ink);
  min-height:2.44em;margin-bottom:12px;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden}
.zc__text{font-size:15px;color:var(--muted);line-height:1.6;flex:1}
.zc__tags{display:flex;gap:6px;flex-wrap:wrap;margin-top:18px}

/* --- Home film (YouTube) ----------------------------------------------- *
 * A local poster and a Play plate until the visitor presses Play; only then
 * does site.js load YouTube's privacy-enhanced player in its place.       */
.video-wrap{overflow:hidden;border:1px solid var(--hair);position:relative;
  aspect-ratio:16/9;background:#000}
.section--screen .video-wrap{height:min(calc(100svh - 330px),calc((100vw - var(--gutter) * 2) * 9 / 16));
  width:auto;max-width:100%;margin-inline:auto;aspect-ratio:16/9}
.yt__poster{width:100%;height:100%;object-fit:cover;display:block;transition:transform .7s var(--ease)}
.yt::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(0deg,rgba(0,0,0,.35),rgba(0,0,0,0) 45%)}
.yt:hover .yt__poster{transform:scale(1.02)}
.yt__play{position:absolute;left:24px;bottom:24px;z-index:2;display:flex;align-items:center;gap:14px;
  padding:8px 20px 8px 8px;background:var(--paper);color:var(--ink);font-size:15px;font-weight:500;
  transition:transform .25s var(--ease)}
.yt__play:hover{transform:translateY(-2px)}
.yt__icon{display:grid;place-items:center;width:44px;height:44px;background:var(--ink);color:var(--on-ink)}
.yt__label{display:flex;flex-direction:column;line-height:1.25}
.yt__label small{font-family:var(--font-mono);font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.yt.is-playing::before{display:none}
.yt iframe{position:absolute;inset:0;width:100%;height:100%;border:0;z-index:3}
@media (max-width:640px){.yt__play{left:14px;bottom:14px}}

/* --- Formerly dark sections — now a quiet off-white panel ---------------- */
.dark{background:var(--panel);color:var(--ink);position:relative;overflow:hidden;
  border-block:1px solid var(--hair)}
.dark h2,.dark h3{color:var(--ink)}
.dark .lede{color:var(--muted)}

/* Decorative layers from the old dark hero; kept inert in case of stray markup. */
.grid-dots,.glow,.aurora,.bracket{display:none}

/* --- Morph (scroll-pinned capabilities) --------------------------------- */
.morph{height:220vh;background:var(--paper);position:relative;border-top:1px solid var(--hair)}
.morph__sticky{position:sticky;top:0;height:100vh;overflow:hidden;display:flex;align-items:center}
.morph__inner{position:relative;z-index:1;width:100%;max-width:var(--wrap);margin:0 auto;
  padding-inline:var(--gutter);display:grid;grid-template-columns:56px 1fr 1fr;gap:56px;align-items:center}
.rail{display:flex;flex-direction:column;align-items:center;height:260px;justify-content:center;position:relative}
.rail__track{position:absolute;left:50%;width:1px;transform:translateX(-50%);
  top:0;bottom:0;background:var(--hair)}
.rail__nums{display:flex;flex-direction:column;justify-content:space-between;height:100%;position:relative}
.rail__nums b{font-family:var(--font-mono);font-size:12px;font-weight:400;line-height:1;
  color:var(--muted);background:var(--paper);padding:5px 6px;border:1px solid var(--hair);
  transition:color .3s var(--ease),background .3s var(--ease),border-color .3s var(--ease)}
.rail__nums b.is-on{color:var(--on-ink);background:var(--ink);border-color:var(--ink)}
.morph__texts{position:relative;min-height:440px}
/* Unpinned (reduced motion, or set by site.js on narrow screens): the steps
   stack in normal flow and the image column and rail step aside. */
.morph--static{height:auto}
.morph--static .morph__sticky{position:static;height:auto;padding-block:96px}
.morph--static .morph__inner{grid-template-columns:minmax(0,1fr)}
.morph--static .rail,.morph--static .morph__imgs{display:none}
.morph--static .morph__texts{min-height:0;display:flex;flex-direction:column;gap:72px}
.morph--static .mstep{position:static;opacity:1;transform:none;pointer-events:auto}
/* Per-step picture: hidden while pinned (the image column shows it), shown on
   top of each step once the section stacks — same order as desktop reads. */
.mstep__img{display:none;margin:0 0 24px;aspect-ratio:16/10;overflow:hidden;
  background:var(--cream-3);clip-path:var(--notch)}
.mstep__img img{width:100%;height:100%;object-fit:cover}
.morph--static .mstep__img{display:block}
.mstep{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;
  opacity:0;transform:translateY(24px);pointer-events:none;
  transition:opacity .55s var(--ease),transform .55s var(--ease)}
.mstep.is-on{opacity:1;transform:none;pointer-events:auto}
.mstep h2{font-size:clamp(32px,3.6vw,54px);color:var(--ink);margin-bottom:22px;letter-spacing:-.035em;line-height:1.02}
.mstep>p{font-size:16px;color:var(--muted);line-height:1.65;margin-bottom:26px;max-width:480px}
.ticks{display:flex;flex-direction:column;gap:0;margin-bottom:32px;list-style:none;
  border-top:1px solid var(--hair);max-width:520px}
.ticks li{display:flex;gap:14px;align-items:flex-start;font-size:14.5px;color:var(--ink-2);
  line-height:1.55;padding:12px 0;border-bottom:1px solid var(--hair)}
.ticks li::before{content:"";width:6px;height:6px;background:var(--ink);flex-shrink:0;margin-top:.55em}
.mstep .btn{align-self:flex-start}
.morph__imgs{position:relative;aspect-ratio:1;overflow:hidden;background:var(--cream-3);
  clip-path:var(--notch)}
.mimg{position:absolute;inset:0;opacity:0;transform:scale(1.06);
  transition:opacity .6s var(--ease),transform .6s var(--ease)}
.mimg.is-on{opacity:1;transform:none}
.mimg img{width:100%;height:100%;object-fit:cover}

/* --- Approach cards ----------------------------------------------------- */
.approach{display:grid;grid-template-columns:repeat(3,1fr);
  border-left:1px solid var(--hair);border-top:1px solid var(--hair)}
.approach__card{padding:32px 30px 40px;background:var(--paper);
  border-right:1px solid var(--hair);border-bottom:1px solid var(--hair);
  transition:background .22s var(--ease)}
.approach__card:hover{background:var(--panel)}
.approach__card b{display:inline-block;font-family:var(--font-mono);font-size:11px;font-weight:400;
  line-height:1;color:var(--ink);padding:4px 5px;border:1px solid var(--ink);margin-bottom:56px}
.approach__card h3{font-size:22px;margin-bottom:14px;line-height:1.22;letter-spacing:-.02em}
.approach__card p{font-size:15px;color:var(--muted);line-height:1.65}

/* --- CTA band ----------------------------------------------------------- */
.cta{padding:56px 56px;position:relative;overflow:hidden;background:var(--panel);
  border:1px solid var(--hair)}
.cta__inner{position:relative;z-index:1;display:flex;align-items:flex-end;
  justify-content:space-between;gap:44px;flex-wrap:wrap;text-align:left}
.cta__copy{flex:1 1 420px;min-width:0}
.cta__inner>.btn{flex-shrink:0}
.cta h2{font-weight:500;font-size:clamp(32px,4.2vw,60px);letter-spacing:-.04em;line-height:1;
  color:var(--ink);margin-bottom:16px}
.cta p{font-size:17px;color:var(--muted);max-width:52ch;margin:0;line-height:1.6}
.cta .eyebrow{margin-bottom:18px}

/* --- Detail pages ------------------------------------------------------- */
.detail{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:64px;align-items:start}
.prose h2{font-size:30px;margin:44px 0 14px;color:var(--ink)}
.prose h3{font-size:22px;margin:32px 0 12px;color:var(--ink);letter-spacing:-.02em}
.prose p{font-size:17px;color:var(--ink-2);line-height:1.75;margin-bottom:18px}
.prose ul{margin:0 0 22px 0;list-style:none}
.prose li{position:relative;padding-left:24px;font-size:17px;color:var(--ink-2);
  line-height:1.7;margin-bottom:10px}
.prose li::before{content:"";position:absolute;left:0;top:.68em;width:6px;height:6px;background:var(--ink)}
.prose a{text-decoration:underline;text-underline-offset:3px}
.prose a:hover{color:var(--cyan-dark)}
.prose>*:first-child{margin-top:0}

.detail__hero{overflow:hidden;margin-bottom:48px;aspect-ratio:16/8;background:var(--cream-3);
  clip-path:var(--notch)}
.detail__hero img{width:100%;height:100%;object-fit:cover}

.aside{position:sticky;top:calc(var(--nav-top) + var(--nav-h) + 24px);display:flex;flex-direction:column;
  border:1px solid var(--hair)}
.panel{background:var(--paper);padding:24px 24px 26px;border-bottom:1px solid var(--hair)}
.panel:last-child{border-bottom:0}
.panel h4{font-size:12px;font-family:var(--font-mono);font-weight:400;letter-spacing:.02em;
  text-transform:uppercase;color:var(--muted);margin-bottom:14px}
.panel ul{list-style:none;display:flex;flex-direction:column;gap:10px}
.panel li a{font-size:15px;color:var(--ink-2);transition:color .2s}
.panel li a:hover{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
.panel li a[aria-current="page"]{color:var(--ink);font-weight:500}
.panel--cta{background:var(--panel)}
.panel--cta p{font-size:15px;color:var(--ink-2);line-height:1.6;margin-bottom:18px}

.breadcrumb{display:flex;gap:8px;flex-wrap:wrap;font-family:var(--font-mono);font-size:11.5px;
  letter-spacing:.02em;text-transform:uppercase;color:var(--muted);margin-bottom:28px;list-style:none}
.breadcrumb li+li::before{content:"/";margin-right:8px;color:var(--line-strong)}
.breadcrumb a:hover{color:var(--ink)}
.breadcrumb [aria-current]{color:var(--ink)}

.pager{display:flex;justify-content:space-between;gap:20px;margin-top:64px;
  padding-top:28px;border-top:1px solid var(--hair);flex-wrap:wrap}
.pager a{font-size:16px;color:var(--ink);font-weight:500;letter-spacing:-.01em}
.pager a:hover{text-decoration:underline;text-underline-offset:3px}
.pager small{display:block;font-family:var(--font-mono);font-size:11px;font-weight:400;
  text-transform:uppercase;color:var(--muted);margin-bottom:6px}

/* --- Policy pages ------------------------------------------------------ */
.policy{max-width:820px}
.policy__table{overflow-x:auto;margin:0 0 22px;border:1px solid var(--hair)}
.policy table{width:100%;border-collapse:collapse;font-size:14px;min-width:560px}
.policy th,.policy td{text-align:left;vertical-align:top;padding:12px 14px;border-bottom:1px solid var(--hair);
  line-height:1.5;color:var(--ink-2)}
.policy th{font-family:var(--font-mono);font-size:11px;font-weight:400;text-transform:uppercase;
  letter-spacing:.02em;color:var(--muted);background:var(--panel)}
.policy tr:last-child td{border-bottom:0}
.policy code{font-family:var(--font-mono);font-size:12.5px;color:var(--ink)}
.policy td small{color:var(--muted)}

/* --- Contact ------------------------------------------------------------ */
/* Two hairline boxes sharing a border; stretch keeps them level. */
.contact-grid{display:grid;grid-template-columns:420px 1fr;gap:0;align-items:stretch}
.contact-info,.contact-grid>div,.contact-grid>form{display:flex;flex-direction:column}
.contact-grid .form{flex:1}
.contact-info{background:var(--panel);color:var(--ink);border:1px solid var(--hair);
  padding:44px 40px;position:relative;overflow:hidden}
.contact-info__inner{position:relative;z-index:1}
.contact-info h2{color:var(--ink);font-size:30px;margin-bottom:12px}
.contact-info>.contact-info__inner>p{color:var(--muted);font-size:16px;line-height:1.6;margin-bottom:36px}
.contact-info ul{list-style:none;display:flex;flex-direction:column;border-top:1px solid var(--hair)}
.contact-info li{display:flex;gap:16px;align-items:flex-start;padding:20px 0;border-bottom:1px solid var(--hair)}
.contact-info li svg{flex-shrink:0;margin-top:2px;color:var(--ink)}
.contact-info li span{font-size:11px;font-family:var(--font-mono);letter-spacing:.02em;
  text-transform:uppercase;color:var(--muted);display:block;margin-bottom:5px}
.contact-info li a,.contact-info li address{font-size:16px;color:var(--ink);font-style:normal;line-height:1.55}
.contact-info li a:hover{text-decoration:underline;text-underline-offset:3px}
.contact-socials{display:flex;gap:8px;margin-top:32px}
.contact-socials a{width:40px;height:40px;border:1px solid var(--hair);border-radius:var(--radius);
  display:flex;align-items:center;justify-content:center;background:var(--paper);
  color:var(--ink);transition:all .2s var(--ease)}
.contact-socials a:hover{border-color:var(--ink);background:var(--ink);color:var(--on-ink)}

.form{background:var(--paper);border:1px solid var(--hair);padding:44px 40px}
.contact-grid .form{border-left:0}
.field textarea.fixed-h{resize:none;height:150px;min-height:0}
.form__grid{display:grid;grid-template-columns:1fr 1fr;gap:22px}
.field{display:flex;flex-direction:column;gap:8px}
.field--full{grid-column:1/-1}
.field label{font-size:11.5px;font-family:var(--font-mono);letter-spacing:.02em;
  text-transform:uppercase;color:var(--muted)}
.field label .req{color:var(--ink)}
.field input,.field textarea,.field select{padding:13px 14px;border:1px solid var(--hair);
  border-radius:var(--radius);font-size:15px;background:var(--paper);
  transition:border-color .2s var(--ease),background .2s var(--ease)}
.field input:hover,.field textarea:hover{border-color:var(--line-strong)}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--ink);outline:none}
.field textarea{resize:vertical;min-height:130px}
.form__note{margin-top:4px;font-size:13px;color:var(--muted);line-height:1.55}
.form__note a{color:var(--ink-2);text-decoration:underline;text-underline-offset:3px}
.field__err{font-size:12px;color:var(--danger)}
.field.has-err input,.field.has-err textarea{border-color:var(--danger)}
/* Passed the live check: a quiet tick at the right edge of the input. */
.field.is-ok input,.field.is-ok textarea{border-color:var(--ok);padding-right:40px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%231B8A3A' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 14px center;background-size:16px 16px}
.field.is-ok textarea{background-position:right 14px top 14px}

.alert{padding:14px 16px;border-radius:var(--radius);font-size:14px;margin-bottom:24px;line-height:1.6}
.alert--ok{background:var(--ok-wash);color:var(--ok);border:1px solid rgba(27,138,58,.2)}
.alert--err{background:var(--danger-wash);color:var(--danger);border:1px solid rgba(211,47,47,.2)}

/* --- Article cards ------------------------------------------------------ *
 * Hairline columns like the project cards; the image carries the notch and
 * a tag box, and a byline footer sits under the excerpt.                   */
.acards{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:0;
  border-left:1px solid var(--hair);border-top:1px solid var(--hair)}
.acard{position:relative;display:flex;flex-direction:column;background:var(--paper);
  border-right:1px solid var(--hair);border-bottom:1px solid var(--hair);min-width:0;
  transition:background .25s var(--ease)}
.acard:hover{background:var(--panel)}
/* One stretched link keeps the whole card clickable without nesting anchors. */
.acard__hit{position:absolute;inset:0;z-index:2}

.acard__media{position:relative;overflow:hidden;background:var(--cream-3);aspect-ratio:16/11;
  clip-path:var(--notch)}
.acard__media img{width:100%;height:100%;object-fit:cover}
.acard__media::after{content:"";position:absolute;inset:0 0 auto 0;height:38%;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.45),rgba(0,0,0,0))}
.acard__tag{position:absolute;left:18px;top:18px;z-index:1;font-family:var(--font-mono);
  font-size:11px;line-height:1;color:#fff;padding:4px 5px;border:1px solid rgba(255,255,255,.85);background:rgba(17,17,17,.28)}

.acard__body{padding:26px 26px 0;flex:1}
.acard__title{font-size:21px;font-weight:500;line-height:1.22;letter-spacing:-.02em;
  color:var(--ink);margin-bottom:12px}
.acard:hover .acard__title{text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
.acard__excerpt{font-size:15px;line-height:1.6;color:var(--muted)}

.acard__foot{display:flex;align-items:center;gap:12px;padding:18px 26px 22px;margin-top:22px;
  border-top:1px solid var(--hair)}
.acard__avatar{display:grid;place-items:center;width:34px;height:34px;border-radius:var(--radius);
  background:var(--panel);border:1px solid var(--hair);color:var(--ink);
  font-family:var(--font-mono);font-size:13px;flex-shrink:0}
.acard__by{display:flex;flex-direction:column;gap:1px;min-width:0}
.acard__by b{font-size:13.5px;font-weight:500;color:var(--ink)}
.acard__by span{font-size:12.5px;color:var(--muted)}
.acard__go{display:grid;place-items:center;width:36px;height:36px;border-radius:var(--radius);
  border:1px solid var(--ink);color:var(--ink);margin-left:auto;flex-shrink:0;
  transition:background .2s var(--ease),color .2s var(--ease)}
.acard:hover .acard__go{background:var(--ink);color:var(--on-ink)}

@media (max-width:640px){
  .cards{grid-template-columns:1fr}
  .card__body{padding:20px 18px 22px}
  .card h3{font-size:19px}
  .card p{font-size:14.5px}
  .acards{grid-template-columns:1fr}
  .acard__body{padding:20px 18px 0}
  .acard__title{font-size:19px;margin-bottom:8px}
  .acard__excerpt{font-size:14.5px}
  .acard__foot{padding:14px 18px 18px;margin-top:16px;gap:10px}
}

/* --- Article ------------------------------------------------------------ */
.article-meta{display:flex;gap:16px;align-items:center;flex-wrap:wrap;
  font-family:var(--font-mono);font-size:11.5px;letter-spacing:.02em;text-transform:uppercase;
  color:var(--muted);margin-bottom:28px}

/* --- Footer (global) ---------------------------------------------------- */
.footer{padding:72px var(--gutter) 36px;background:var(--paper);border-top:1px solid var(--hair)}
.footer__top{display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;
  gap:40px;margin-bottom:32px;padding-bottom:56px;border-bottom:1px solid var(--hair)}
.footer__brand{max-width:300px}
.footer__brand .nav__logo{margin-bottom:18px}
.footer__brand .nav__logo-text{color:var(--ink)}
.footer__brand p{font-size:14px;color:var(--muted);line-height:1.6}
.footer__cols{display:flex;gap:72px;flex-wrap:wrap}
.footer__col h4{font-family:var(--font-mono);font-size:11px;font-weight:400;letter-spacing:.02em;
  text-transform:uppercase;color:var(--muted);margin-bottom:16px}
.footer__col ul{list-style:none;display:flex;flex-direction:column;gap:10px}
.footer__col a{font-size:14.5px;color:var(--ink);transition:color .2s}
.footer__col a:hover{color:var(--muted)}
.footer__social{display:flex;gap:8px}
.footer__social a{width:40px;height:40px;border:1px solid var(--hair);border-radius:var(--radius);
  display:flex;align-items:center;justify-content:center;color:var(--ink);
  font-family:var(--font-display);font-weight:600;font-size:14px;transition:all .2s var(--ease)}
.footer__social a:hover{border-color:var(--ink);background:var(--ink);color:var(--on-ink)}
.footer__bottom{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:12px}
.footer__bottom p,.footer__bottom a,.footer__bottom address{font-family:var(--font-mono);font-size:11.5px;color:var(--muted)}
.footer__legal{display:flex;gap:18px}
.footer__bottom a:hover{color:var(--ink)}

/* --- 404 ---------------------------------------------------------------- */
.nf-hero{background:var(--paper);position:relative;overflow:hidden;
  padding:184px var(--gutter) 112px;text-align:left}
.nf-hero__inner{position:relative;z-index:1;max-width:calc(var(--wrap) - var(--gutter) * 2);margin:0 auto}
.nf-hero .eyebrow{margin-bottom:28px}

.nf-code{display:flex;align-items:center;justify-content:flex-start;gap:10px;margin-bottom:32px}
/* :not() keeps the chip out so its SVG keeps its currentColor stroke. */
.nf-code>span:not(.nf-code__chip){font-family:var(--font-display);font-weight:500;
  font-size:clamp(96px,15vw,200px);line-height:.82;letter-spacing:-.06em;color:var(--ink);
  animation:fadeUp .7s var(--ease) both}
.nf-code>span:last-child{animation-delay:.14s}
.nf-code__chip{width:clamp(74px,11vw,150px);height:clamp(74px,11vw,150px);flex-shrink:0;
  color:var(--ink);animation:nfSpin 14s linear infinite,fadeUp .7s .07s var(--ease) both}
.nf-code__chip svg{width:100%;height:100%}
@keyframes nfSpin{to{transform:rotate(360deg)}}

.nf-hero h1{font-weight:500;font-size:clamp(34px,4.6vw,64px);letter-spacing:-.04em;
  line-height:1.02;color:var(--ink);margin-bottom:18px;max-width:16ch;
  animation:fadeUp .7s .18s var(--ease) both}
.nf-lede{font-size:18px;color:var(--muted);line-height:1.6;
  max-width:520px;margin:0 0 36px;animation:fadeUp .7s .26s var(--ease) both}
.nf-actions{display:flex;gap:10px;justify-content:flex-start;flex-wrap:wrap;margin-bottom:72px;
  animation:fadeUp .7s .34s var(--ease) both}

.nf-routes{display:grid;grid-template-columns:repeat(3,1fr);text-align:left;
  border-left:1px solid var(--hair);border-top:1px solid var(--hair);
  animation:fadeUp .7s .42s var(--ease) both}
.nf-routes a{display:block;padding:24px 26px 30px;background:var(--paper);
  border-right:1px solid var(--hair);border-bottom:1px solid var(--hair);
  transition:background .2s var(--ease)}
.nf-routes a:hover{background:var(--panel)}
.nf-routes__n{display:inline-block;font-family:var(--font-mono);font-size:11px;line-height:1;
  color:var(--ink);padding:4px 5px;border:1px solid var(--ink);margin-bottom:36px}
.nf-routes b{font-family:var(--font-display);font-weight:500;font-size:22px;letter-spacing:-.02em;
  color:var(--ink);display:block;margin-bottom:8px}
.nf-routes small{font-size:14.5px;color:var(--muted);line-height:1.6;display:block}

.nf-tags{display:flex;align-items:center;gap:6px;flex-wrap:wrap;justify-content:flex-start;
  margin-top:40px;animation:fadeUp .7s .5s var(--ease) both}
.nf-tags>span{font-family:var(--font-mono);font-size:11px;text-transform:uppercase;
  color:var(--muted);width:100%;margin-bottom:6px}
.nf-tags a{font-size:14px;padding:7px 12px;border-radius:var(--radius);color:var(--ink-2);
  border:1px solid var(--hair);transition:all .2s var(--ease)}
.nf-tags a:hover{border-color:var(--ink);color:var(--ink)}

/* --- Responsive --------------------------------------------------------- */
@media (max-width:1080px){
  /* The chip steps aside so the headline keeps the width. */
  .hero__stage{display:flex;flex-direction:column;justify-content:center;align-items:stretch}
  .hero__art{display:none}
  .cards{grid-template-columns:repeat(2,minmax(0,1fr))}
  .zc{flex-basis:calc((100vw - var(--gutter) * 2) / 2)}
  :root{--gutter:32px}
  .tiles{grid-template-columns:repeat(2,1fr)}
  .approach{grid-template-columns:1fr}
  .approach__card b{margin-bottom:28px}
  .detail{grid-template-columns:1fr;gap:44px}
  .aside{position:static}
  .contact-grid{grid-template-columns:1fr}
  /* Stacked: the form comes first, the details card follows under it. */
  .contact-grid>.contact-info{order:2;border-top:0}
  .contact-grid .form{border-left:1px solid var(--hair)}
  .morph__inner{grid-template-columns:40px 1fr;gap:32px}
  .morph__imgs{display:none}
}
@media (max-width:860px){
  :root{--nav-top:10px;--nav-h:56px}
  /* Half-width white panel sliding in from the right; the page stays
     visible behind a dim layer, and tapping that layer closes it (site.js). */
  .nav__links{position:fixed;inset:0 0 0 auto;width:max(50vw,250px);z-index:1;
    flex-direction:column;justify-content:flex-start;
    align-items:stretch;gap:0;margin:0;padding:calc(var(--nav-top) + var(--nav-h) + 40px) 0 40px;
    background:var(--paper);overflow-y:auto;border-left:1px solid var(--hair);
    box-shadow:-24px 0 60px rgba(17,17,17,.08);
    transform:translateX(100%);visibility:hidden;
    transition:transform .42s var(--ease),visibility 0s linear .42s}
  .nav.is-open .nav__links{transform:none;visibility:visible;transition-delay:0s}
  .nav.is-open{box-shadow:none}
  .nav::before{content:"";position:fixed;inset:0;z-index:0;background:rgba(17,17,17,.3);
    opacity:0;visibility:hidden;transition:opacity .35s var(--ease),visibility 0s linear .35s}
  .nav.is-open::before{opacity:1;visibility:visible;transition-delay:0s}
  /* The burger has to stay above the panel it opens. */
  .nav__burger{position:relative;z-index:2;display:flex;margin-left:8px;order:3}
  /* Phones: the toggle sits just left of the menu button. */
  .theme-toggle{order:2;margin-left:auto;position:relative;z-index:2;width:38px;height:38px}
  .nav__links .nav__link{
    padding:16px 24px;color:var(--ink);font-size:26px;font-weight:500;
    font-family:var(--font-display);letter-spacing:-.03em;line-height:1.1;
    border-bottom:1px solid var(--hair);
    opacity:0;transform:translateX(24px);
    transition:opacity .3s var(--ease),transform .3s var(--ease)}
  .nav__links .nav__link:first-child{border-top:1px solid var(--hair)}
  .nav.is-open .nav__links .nav__link{opacity:1;transform:none}
  .nav.is-open .nav__links .nav__link:nth-child(2){transition-delay:.10s}
  .nav.is-open .nav__links .nav__link:nth-child(3){transition-delay:.15s}
  .nav.is-open .nav__links .nav__link:nth-child(4){transition-delay:.20s}
  .nav.is-open .nav__links .nav__link:nth-child(5){transition-delay:.25s}
  .nav__links>.btn{display:inline-flex;margin:32px 24px 0;justify-content:center;
    padding:16px 22px;font-size:16px;
    opacity:0;transform:translateX(24px);
    transition:opacity .3s var(--ease) .3s,transform .3s var(--ease) .3s}
  .nav.is-open .nav__links>.btn{opacity:1;transform:none}
  html.nav-open,html.nav-open body{overflow:hidden}
  .nav__cta-desktop{display:none}

  .hero{padding-top:112px}
  /* Sized so the longest line ("We engineer") fits a phone in one line. */
  /* Clash Display runs wide: sized so ELECTRONICS (the longest line) fits. */
  .hero .hero__title{font-size:clamp(30px,min(10.2vw,calc((100svh - 490px) / 3.7)),80px)}
  .hero__stage{padding-bottom:32px}
  .hero__foot{padding-bottom:36px}
  .hero__lede{font-size:16px}
  .hero__actions,.hero__actions .btn{flex:1 1 auto;justify-content:center}

  /* One card and a peek; the arrows give way to swiping. */
  .zc{flex-basis:82vw}
  .pf__btn{display:none}
  .pf__nav .link-more{margin-left:0}
  .zc__body{padding:22px 20px 24px}
  .zc__kicker{font-size:17px}
  .morph{height:auto}
  .morph__sticky{position:static;height:auto;padding-block:80px}
  .morph__inner{grid-template-columns:1fr}
  .rail{display:none}
  .morph__texts{min-height:0;display:flex;flex-direction:column;gap:64px}
  .mstep{position:static;opacity:1;transform:none;pointer-events:auto}
  .form,.contact-info{padding:32px 22px}
  .form__grid{grid-template-columns:1fr}
  /* Compact on phones: a band, not a poster. */
  .cta{padding:28px 22px}
  .cta__inner{flex-direction:column;align-items:stretch;gap:20px}
  /* Its desktop flex-basis is a 420px width; stacked, that would become a
     420px height — the cause of the oversized band on phones. */
  .cta__copy{flex:0 0 auto}
  .cta .eyebrow{margin-bottom:10px}
  .cta h2{font-size:26px;letter-spacing:-.03em;margin-bottom:8px}
  .cta p{font-size:15px;line-height:1.55}
  .cta__inner>.btn{justify-content:center}
  .mstep__img{display:block}
  .section{padding-block:72px}
  .page-hero{padding:124px var(--gutter) 0}
  .page-hero__rule{margin-top:40px}
  .cards{grid-template-columns:1fr}
  .footer__top{flex-direction:column;gap:36px}
  .nf-hero{padding:132px var(--gutter) 72px}
  .nf-routes{grid-template-columns:1fr}
  .nf-code{gap:4px}
}
@media (max-width:520px){
  :root{--gutter:20px}
  .tiles{grid-template-columns:1fr}
  .footer__cols{gap:36px}
  :root{--notch:polygon(0 0,calc(100% - 96px) 0,calc(100% - 56px) 40px,100% 40px,100% 100%,0 100%)}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
  [data-reveal]{opacity:1;transform:none}
}
@media print{.nav,.footer{display:none}}
