/* ==========================================================================
   site.css — the rebuilt index pages (client + hiring).
   The six linked case pages in work/ load this file plus work/case-page.css.
   The Garmin and Redline pages still run on style.css, so that file stays
   where it is until they are rewritten.
   ========================================================================== */

:root{
  --ink:#202020;
  --gray:#6b6b6b;
  --gray-2:#8a8a8a;
  --gray-3:#767676;
  --link:#0077b5;
  --paper:#fafafa;
  --white:#ffffff;
  --hair:rgba(0,0,0,.1);
  --hair-strong:#e0e0e0;
  --amber:#96591f;
  --cream:#fff8df;
  --live:#2f7d4f;
  --orange:#f2662a;
  --orange-deep:#de5520;
  --c-sage:#7f8f66;
  --c-clay:#b07555;
  --c-gold:#c2913f;
  --c-slate:#6d8199;
  --c-plum:#8d6f8a;
  --c-moss:#5f7a63;
  /* the dark band (Wayfarers) */
  --dark:#121212;
  --d-hair:rgba(255,255,255,.12);
  --d-text:rgba(255,255,255,.62);
  --d-label:rgba(255,255,255,.64);
  --ice:#bde9ff;
  --butter:#f7edb8;
  --sans:'Instrument Sans','Inter','Helvetica Neue',Arial,sans-serif;
  --mono:'Geist Mono','Fragment Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;
  --ease-spring:cubic-bezier(.22,1,.36,1);
  --noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
body{
  margin:0;
  font-family:var(--sans);
  font-size:16px;
  line-height:1.55;
  color:var(--ink);
  background:var(--white);
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:inherit}

.shell{max-width:1280px;margin:0 auto;padding-left:44px;padding-right:44px}
.prose{max-width:680px}

.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;
}
.skip-link{
  position:absolute;left:-9999px;top:0;z-index:99;
  background:var(--ink);color:#fff;padding:12px 18px;
  font-family:var(--mono);font-size:13px;
}
.skip-link:focus{left:0}

:focus-visible{outline:2px solid var(--amber);outline-offset:3px}

/* the grid the top of the page sits on, and the wash it fades into */
.dotted{
  background-color:var(--paper);
  background-image:radial-gradient(rgba(0,0,0,.08) 1px,transparent 1px);
  background-size:20px 20px;
}

/* ------------------------------------------------------------------- nav
   Restored from the original build, unchanged. */
.nav{position:sticky;top:0;z-index:100;background:var(--white);border-bottom:1px solid var(--hair)}
.nav-row{height:80px;display:flex;align-items:center;gap:32px}
.brand{display:flex;align-items:center;gap:12px;flex:none;text-decoration:none;color:inherit}
.brand-mark{width:49px;height:18px;color:#000;fill:currentColor}
.brand-name{font-size:20px;font-weight:500;letter-spacing:-.01em}
.nav-links{display:flex;gap:32px;margin:0 auto}
.nav-links a{font-size:15px;white-space:nowrap;color:var(--ink);text-decoration:none;transition:opacity .15s ease-out}
.nav-links a:hover{opacity:.55}
.nav-cta{display:flex;align-items:center;gap:24px;flex:none;margin-left:auto;white-space:nowrap}
.nav .btn{padding:12px 20px}
.nav-toggle{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
  clip-path:inset(50%);overflow:hidden;white-space:nowrap;appearance:none;
}
.nav-toggle:focus-visible ~ .nav-burger,
.nav-burger:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
@media (min-width:961px){.nav-toggle{display:none}}
.nav-burger{display:none}
.nav-drawer{display:none}
/* the bar goes dark while the Wayfarers band is under it (site.js sets
   .is-dark), so it reads as part of the band instead of a white lid on it */
.nav{transition:background-color .25s ease-out,border-color .25s ease-out}
.nav .brand,.nav .brand-mark,.nav-links a{transition:color .25s ease-out,opacity .15s ease-out}
.nav.is-dark{background:var(--dark);border-bottom-color:var(--d-hair)}
.nav.is-dark .brand,.nav.is-dark .brand-mark,.nav.is-dark .nav-links a{color:#fff}
.nav.is-dark .dashed-link{color:var(--ice)}
.nav.is-dark .btn--primary{background:#fff;color:#000}
.nav.is-dark .btn--primary:hover{background:var(--ice)}
.nav.is-dark :focus-visible{outline-color:var(--ice)}

.btn{
  display:inline-flex;align-items:center;gap:10px;
  padding:14px 24px;border-radius:2px;text-decoration:none;
  font-size:15px;font-weight:500;line-height:1;
  transition:background-color .15s ease-out,border-color .15s ease-out,color .15s ease-out;
}
.btn .arr{display:inline-block;transition:transform .15s ease-out}
.btn:hover .arr{transform:translateX(4px)}
.btn--primary{background:#000;color:#fff}
.btn--primary:hover{background:var(--ink)}
.btn--ghost{background:var(--white);color:var(--ink);border:1px solid rgba(0,0,0,.15)}
.btn--ghost:hover{border-color:rgba(0,0,0,.4)}
.dashed-link{
  color:var(--link);font-size:15px;text-decoration:underline;
  text-decoration-style:dashed;text-underline-offset:4px;text-decoration-thickness:1px;
  transition:opacity .15s ease-out;
}
.dashed-link:hover{opacity:.7}

/* ------------------------------------------------------------------ hero
   Restored from the original build. Only the words changed. */
.hero{position:relative;overflow:hidden}
.hero-inner{
  position:relative;z-index:2;padding-top:96px;
  display:flex;flex-direction:column;align-items:center;text-align:center;
}
.hero-inner .h1{
  margin:0;max-width:900px;
  font-size:clamp(40px,5.6vw,72px);line-height:1.08;
  letter-spacing:-.02em;text-wrap:balance;font-weight:600;
}
.hero-sub{
  margin:24px 0 0;max-width:660px;
  font-size:clamp(17px,1.7vw,22px);line-height:1.42;color:var(--gray);
}
.hero-sub b{color:var(--ink);font-weight:500}
.hero-actions{display:flex;gap:12px;margin-top:36px;flex-wrap:wrap;justify-content:center}

/* trusted-by band: a contained strip, never edge to edge, names looping left
   to right. Restored as-is. */
.trustband{
  margin-top:44px;width:100%;max-width:880px;
  background:var(--white);border:1px solid var(--hair);border-radius:2px;
  padding:16px 0 18px;overflow:hidden;
  display:flex;flex-direction:column;align-items:center;gap:12px;
}
.trustband-label{
  font-family:var(--mono);font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--gray-3);line-height:1;flex:none;
}
.trustband-lane{
  width:100%;overflow:hidden;
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 7%,#000 93%,transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,#000 7%,#000 93%,transparent 100%);
}
.trustband-track{display:flex;width:max-content;animation:trustband-run 30s linear infinite}
.trustband:hover .trustband-track{animation-play-state:paused}
.trustband-seq{display:flex;align-items:center;flex:none;list-style:none;margin:0;padding:0}
/* every item carries its own trailing separator, so the rhythm holds across
   the seam between sequences too */
.trustband-seq li{
  display:flex;align-items:center;gap:24px;padding-right:24px;
  font-size:15px;font-weight:500;letter-spacing:-.01em;
  color:var(--ink);white-space:nowrap;
}
.trustband-seq li::after{content:"";width:4px;height:4px;flex:none;background:rgba(0,0,0,.25)}
/* negative start to positive end: content travels left to right. one third of
   the track is exactly one sequence, so the reset is invisible */
@keyframes trustband-run{
  from{transform:translateX(calc(-100% / 3))}
  to{transform:translateX(0)}
}

/* ------------------------------------------------------------------ fan
   Geometry is lifted from the original hero: rays run from 50,82 out to
   16,60 / 28,34 / 50,22 / 72,34 / 84,60, and each chip sits on the end of
   one. The nodes are links into the case pages, so the fan is the page's
   table of contents rather than a diagram of nothing. */
.canvas{position:relative;height:560px;margin-top:16px}
.land{
  position:absolute;inset:0;
  background-image:url("assets/hero-valley.jpg");
  background-size:cover;background-position:50% 58%;background-repeat:no-repeat;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 20%,#000 84%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 20%,#000 84%,transparent 100%);
}
.land::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:var(--noise);opacity:.07;mix-blend-mode:multiply;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 34%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 34%);
}
/* each ray is drawn twice, a pale halo under a hairline, so it stays legible
   over both the dark hills and the bright sky */
.wires{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.wires line{stroke-width:1;fill:none;vector-effect:non-scaling-stroke;transition:stroke .22s,stroke-width .22s}
.wires .halo line{stroke:rgba(255,255,255,.7);stroke-width:3.5}
.wires .ink line{stroke:rgba(28,34,28,.5)}
.wires .ink line.is-hot{stroke:var(--amber);stroke-width:1.7}

.node{
  position:absolute;transform:translate(-50%,-50%);
  display:block;text-decoration:none;text-align:left;white-space:nowrap;
  min-width:186px;padding:9px 13px 10px;border-radius:2px;
  background:rgba(255,255,255,.95);border:1px solid rgba(0,0,0,.15);
  box-shadow:0 6px 16px rgba(45,45,35,.16);
  transition:transform .26s var(--ease-spring),box-shadow .26s var(--ease-spring),border-color .22s;
}
.node .k{
  display:flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:11.5px;letter-spacing:.055em;
  text-transform:uppercase;color:var(--ink);transition:color .22s;
}
.node .k::before{content:"";width:5px;height:5px;background:var(--ink);flex:none;transition:background .22s}
.node .v{display:block;font-size:13px;line-height:1.35;color:var(--gray);margin-top:4px}
.node .dot{width:6px;height:6px;border-radius:50%;background:var(--live);margin-left:2px;flex:none}
.node .dot--off{background:none;border:1.5px solid var(--gray-2)}
.node:hover,.node:focus-visible,.node.is-hot{
  transform:translate(-50%,calc(-50% - 4px));
  box-shadow:0 13px 28px rgba(45,45,35,.24);
  border-color:rgba(150,89,31,.55);
}
.node:hover .k,.node:focus-visible .k,.node.is-hot .k{color:var(--amber)}
.node:hover .k::before,.node:focus-visible .k::before,.node.is-hot .k::before{background:var(--amber)}

.monotile{
  position:absolute;left:50%;bottom:48px;transform:translateX(-50%);
  width:104px;height:104px;border-radius:24px;background:var(--ink);
  /* the soft white ring lifts the tile off the painted hills and covers the
     ray ends passing beneath it */
  box-shadow:0 0 0 7px rgba(255,255,255,.45),0 12px 30px rgba(45,45,35,.28);
  display:grid;place-items:center;color:#fff;
}
.monotile svg{width:62px;height:23px;fill:currentColor}

/* ray draw-in, only when motion is welcome */
html.anim .wires line{stroke-dasharray:1200;stroke-dashoffset:1200;animation:draw .9s var(--ease-spring) .15s forwards}
html.anim .node{opacity:0;animation:rise .6s var(--ease-spring) var(--d,0s) forwards}
@keyframes draw{to{stroke-dashoffset:0}}
@keyframes rise{from{opacity:0;transform:translate(-50%,calc(-50% + 10px))}to{opacity:1;transform:translate(-50%,-50%)}}

/* Reveal on scroll. Only armed once JS confirms it can unarm each one, so the
   page renders complete for a reader with no JS and for a headless screenshot. */
html.anim.reveal-armed .reveal{opacity:0;transform:translateY(16px)}
html.anim.reveal-armed .reveal.in{
  opacity:1;transform:none;
  transition:opacity .55s var(--ease-spring),transform .55s var(--ease-spring);
}

/* --------------------------------------------------------------- section */
.sec{padding:52px 0 0}
.sec:last-of-type{padding-bottom:20px}
.sec-h{
  display:flex;align-items:baseline;justify-content:space-between;gap:20px;
  margin:0 0 4px;padding-bottom:12px;border-bottom:1px solid var(--hair-strong);
}
.sec-h h2{
  margin:0;font-family:var(--mono);font-size:12px;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;color:var(--gray);
}
.sec-h .aside{font-size:14px;color:var(--gray-2)}

/* ----------------------------------------------------------------- work
   Sized by weight, not by wordcount. SST is the retainer everything else
   hangs off, so it gets the full row; Lilo is a good small build and reads
   like one. Twelve columns, each card declares how many it takes. */
.work-grid{
  display:grid;grid-template-columns:repeat(12,minmax(0,1fr));
  gap:18px;margin-top:18px;
}
.e--xl{grid-column:span 12}
.e--lg{grid-column:span 7}
.e--md{grid-column:span 5}
.e--sm{grid-column:span 4}
.e--xs{grid-column:span 3}

/* Each card is the client's card. Everything tinted on it derives from two
   declared values, --b1 and --b2, so a brand correction is two hex codes in
   the markup and nothing else. --bi is the same hue pushed dark enough to set
   type in; the raw brand colour is usually too light to read at body weight. */
.entry{
  --bi:color-mix(in srgb,var(--b1) 70%,#141414);
  --b2i:color-mix(in srgb,var(--b2) 70%,#141414);
  --bface:color-mix(in srgb,var(--b1) 4%,#fff);
  --bedge:color-mix(in srgb,var(--b1) 26%,#fff);
  /* how hard the two corner washes read. A percentage of the brand colour is
     not a percentage of how loud it looks, so a vivid brand needs a smaller
     number to land at the same weight as a muted one. */
  --wash1:10%;
  --wash2:7%;

  position:relative;
  display:flex;flex-direction:column;
  border:1px solid var(--bedge);
  border-radius:10px;padding:0;
  background:
    radial-gradient(86% 64% at 100% 0%,color-mix(in srgb,var(--b1) var(--wash1),transparent) 0%,transparent 72%),
    radial-gradient(70% 58% at 0% 100%,color-mix(in srgb,var(--b2) var(--wash2),transparent) 0%,transparent 70%),
    var(--bface);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.75),
    0 1px 2px rgba(45,45,35,.05),
    0 10px 24px -10px color-mix(in srgb,var(--b1) 30%,rgba(45,45,35,.4));
  transition:box-shadow .35s var(--ease-spring),border-color .22s,translate .3s var(--ease-spring);
}
.entry:hover{
  border-color:color-mix(in srgb,var(--b1) 42%,#fff);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.75),
    0 2px 4px rgba(45,45,35,.06),
    0 26px 48px -16px color-mix(in srgb,var(--b1) 40%,rgba(45,45,35,.5));
}
/* The card lifts rather than leans. Any 3D rotation makes the browser paint
   the card flat and then resample it, which softens every line of text on it.
   A whole-pixel lift stays sharp. It goes on `translate`, not `transform`, so
   the reveal's transform:none cannot cancel it. */
@media (hover:hover) and (pointer:fine){
  .entry:hover{translate:0 -3px}
}
/* the reveal sets its own transition list once a card is in, which would drop
   the hover transitions above */
html.anim.reveal-armed .entry.reveal.in{
  transition:opacity .55s var(--ease-spring),transform .55s var(--ease-spring),
    box-shadow .35s var(--ease-spring),border-color .22s,translate .3s var(--ease-spring);
}
.entry.is-hot{border-color:color-mix(in srgb,var(--b1) 55%,#fff)}

.entry-inner{
  display:grid;grid-template-columns:262px minmax(0,1fr);gap:0 40px;
  align-items:start;padding:28px 30px 28px;flex:1;
}
/* below full width there is no room for a rail beside the prose */
.e--lg .entry-inner,.e--md .entry-inner,
.e--sm .entry-inner,.e--xs .entry-inner{display:flex;flex-direction:column;gap:14px}
.e--lg .entry-rail,.e--md .entry-rail,
.e--sm .entry-rail,.e--xs .entry-rail{display:contents}
.e--lg .entry-head,.e--md .entry-head,.e--sm .entry-head,.e--xs .entry-head{order:1}
.e--lg .entry-sub,.e--md .entry-sub,.e--sm .entry-sub,.e--xs .entry-sub{order:2;margin:0}
.e--lg .entry-body,.e--md .entry-body,.e--sm .entry-body,.e--xs .entry-body{order:3}
.e--lg .entry-links,.e--md .entry-links,
.e--sm .entry-links,.e--xs .entry-links{order:4;margin:auto 0 0}

.entry-head{display:flex;flex-direction:column;align-items:flex-start;gap:12px}
/* the client's name is set in their colour; it is the one place the brand
   speaks at full strength */
.entry-head h3{
  margin:0;font-weight:600;letter-spacing:-.018em;line-height:1.14;
  color:var(--bi);
}
.e--xl .entry-head h3{font-size:34px}
.e--lg .entry-head h3{font-size:27px}
.e--md .entry-head h3{font-size:23px}
.e--sm .entry-head h3{font-size:21px}
.e--xs .entry-head h3{font-size:20px}

.entry-sub{
  margin:10px 0 0;font-family:var(--mono);font-size:11.5px;
  letter-spacing:.05em;text-transform:uppercase;
  color:color-mix(in srgb,var(--b1) 45%,#555);
}
.entry-body > p{margin:0 0 14px;color:#39393a}
.entry-body > p:last-of-type{margin-bottom:0}
.entry-body > p strong{color:var(--bi);font-weight:600}

.card-live{
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.055em;
  text-transform:uppercase;line-height:1;
  color:var(--bi);
  background:color-mix(in srgb,var(--b1) 11%,#fff);
  border:1px solid color-mix(in srgb,var(--b1) 26%,#fff);
  padding:7px 11px;border-radius:2px;
}
.card-live::before{
  content:"";width:6px;height:6px;flex:none;border-radius:50%;
  background:var(--live);box-shadow:0 0 0 3px color-mix(in srgb,var(--live) 18%,transparent);
}
.card-live--wip::before{background:#b8860b;box-shadow:0 0 0 3px rgba(184,134,11,.18)}

/* The first link is the way in, so it carries the brand solid; the rest are
   outlined in it and pick up the secondary colour on hover. */
.entry-links{list-style:none;margin:22px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.entry-links a{
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:11.5px;letter-spacing:.05em;
  text-transform:uppercase;text-decoration:none;
  border-radius:2px;padding:7px 12px;
  color:var(--bi);
  background:color-mix(in srgb,var(--b1) 7%,#fff);
  border:1px solid color-mix(in srgb,var(--b1) 30%,#fff);
  transition:background .18s,border-color .18s,color .18s,transform .18s var(--ease-spring);
}
.entry-links li:first-child a{
  color:#fff;background:var(--bi);
  border-color:color-mix(in srgb,var(--bi) 80%,#000);
}
.entry-links a:hover{transform:translateY(-1px)}
.entry-links li:first-child a:hover{background:var(--b2i);border-color:var(--b2i)}
.entry-links li + li a:hover{
  color:var(--b2i);
  border-color:color-mix(in srgb,var(--b2) 55%,#fff);
  background:color-mix(in srgb,var(--b2) 13%,#fff);
}
.entry-links a.is-live{border-color:rgba(47,125,79,.4)}
.entry-links a.is-live::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--live);flex:none}
/* Links out to the live site. Lowercase so a domain reads as a domain, and the
   diagonal arrow says it leaves the page where the case-study links do not. */
.entry-links a.is-ext{text-transform:none;letter-spacing:.02em}
.entry-links a.is-ext::after,.minis a.is-ext::after{content:"\2197";font-size:12px;line-height:1}

@media (max-width:1080px){
  .e--lg,.e--sm{grid-column:span 12}
  .e--md,.e--xs{grid-column:span 6}
}
@media (max-width:760px){
  .work-grid{gap:14px}
  .e--xl,.e--lg,.e--md,.e--sm,.e--xs{grid-column:span 12}
  .entry{transform:none !important}
  .e--xl .entry-head h3{font-size:26px}
  .entry-inner{display:flex;flex-direction:column;gap:14px;padding:22px 20px 22px}
  .entry-rail{display:contents}
  .entry-head{order:1}
  .entry-sub{order:2;margin:0}
  .entry-body{order:3}
  .entry-links{order:4;margin:0}
}

/* ------------------------------------------------------- currently building
   Prose and not cards on purpose. The disclosure risk on live client work only
   exists when a name, a status and a date appear together; strip all three and
   what is left describes the kind of problem, which is the part worth showing. */
.flight{
  margin-top:16px;border:1px solid var(--hair-strong);border-radius:2px;
  background:var(--white);padding:24px 28px;
  box-shadow:0 1px 2px rgba(45,45,35,.05);
}
.flight p{margin:0;max-width:760px;color:#3b3b3b}
.flight p + p{margin-top:14px;padding-top:14px;border-top:1px solid var(--hair)}

/* ------------------------------------------------------------ principles */
.prins{
  margin:16px 0 0;padding:0;list-style:none;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;
}
.prins li{
  background:var(--white);border:1px solid var(--hair);border-radius:2px;
  padding:22px 24px;
  transition:transform .28s var(--ease-spring),box-shadow .28s var(--ease-spring);
}
.prins li:hover{transform:translateY(-3px);box-shadow:0 12px 26px rgba(45,45,35,.09)}
.prins h3{
  margin:0 0 7px;font-size:16px;font-weight:600;letter-spacing:-.005em;
}
.prins p{margin:0;color:#3b3b3b;font-size:15.5px}

/* ------------------------------------------------------------- wayfarers
   The daydream, and the one place the page goes dark. Restored from the
   original build with its look intact. Everything is scoped under .way
   because the old markup leans on generic names (.mono, .eyebrow)
   that would otherwise leak into the rest of the page. */
.way{
  position:relative;margin-top:72px;padding:120px 0;
  background:var(--dark);color:#fff;line-height:1.35;
}
.way::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:var(--noise);opacity:.05;
}
.way > *{position:relative}
/* site.css never zeroes the UA margins the way the old reset did */
.way :where(h2,h3,h4,p,figure,blockquote){margin:0}
.way :focus-visible{outline-color:var(--ice)}
.way + .shell > .sec:first-child{padding-top:88px}

.way .h2{
  font-size:clamp(32px,3.6vw,50px);line-height:1.1;
  letter-spacing:-.02em;text-wrap:balance;font-weight:500;color:#fff;
}
.way .h3{font-size:24px;line-height:1.2;letter-spacing:-.01em;font-weight:500;color:#fff}
.way .mono{
  font-family:var(--mono);font-size:13px;letter-spacing:.04em;
  text-transform:uppercase;line-height:1.2;
}
.way .tint{color:var(--ice)}
.way .eyebrow{
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--mono);font-size:13px;letter-spacing:.05em;
  text-transform:uppercase;line-height:1;
  padding:9px 14px;border-radius:2px;
  color:var(--butter);background:rgba(255,255,255,.04);border:1px solid var(--d-hair);
}
.way .eyebrow::before{content:"";width:5px;height:5px;flex:none;background:currentColor}
.way .section-head{max-width:820px;margin-bottom:56px}
.way .section-head .eyebrow{margin-bottom:24px}

.way .way-lede{
  margin-top:18px;
  font-family:var(--mono);font-size:13px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--d-text);
}
/* the origin, in first person, ahead of the quotes */
.way-intro{max-width:780px;margin-bottom:72px}
.way-intro p{font-size:clamp(17px,1.5vw,20px);line-height:1.6;color:var(--d-text)}
.way-intro p + p{margin-top:20px}
.way-intro b{color:#fff;font-weight:500}
.quote-panel{
  position:relative;overflow:hidden;
  border:1px solid rgba(255,255,255,.18);
  border-radius:8px;
  padding:72px 64px 56px;
  background:
    radial-gradient(120% 100% at 85% 0%,rgba(63,93,94,.9) 0%,rgba(63,93,94,0) 60%),
    radial-gradient(100% 90% at 10% 100%,rgba(92,122,82,.55) 0%,rgba(92,122,82,0) 60%),
    linear-gradient(135deg,#16232e 0%,#1e3438 55%,#2b4a44 100%);
}
.quote-panel::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:var(--noise);opacity:.07;
}
.quote-glyph{
  font-size:120px;line-height:.6;font-weight:500;color:#fff;
  opacity:.9;margin-bottom:8px;font-family:Georgia,serif;
}
.quote-text{
  font-size:clamp(22px,2.6vw,36px);
  font-weight:500;line-height:1.24;letter-spacing:-.015em;
  color:#fff;max-width:900px;
}
.quote-text em{font-style:normal}
/* site.js wraps each word in a .w and lights them in reading order once the
   quote is in frame. Without JS the words are never wrapped, so it reads lit. */
.quote-text .w{transition:color .4s ease-out}
html.anim .quote-text .w{color:rgba(255,255,255,.35)}
html.anim .quote-text.lit .w,
html.anim .quote-text .w.w-in{color:#fff}
.quote-text .tint,
html.anim .quote-text .w.tint.w-in{color:var(--ice)}
html.anim .quote-text .w.tint{color:rgba(189,233,255,.4)}
html.anim .quote-text.lit .w.tint{color:var(--ice)}
/* two quotes, one panel. A step smaller than the single quote it replaced,
   and a hairline between them so each keeps its own attribution */
.quote + .quote{margin-top:40px;padding-top:40px;border-top:1px solid rgba(255,255,255,.14)}
.way .quote-attrib{
  margin-top:24px;
  font-family:var(--mono);font-size:12px;letter-spacing:.05em;
  text-transform:uppercase;color:rgba(255,255,255,.6);
}

.way-cols{
  display:grid;grid-template-columns:1.25fr 1fr;gap:64px;
  margin-top:88px;
}
.way-story p{font-size:17px;line-height:1.6;color:var(--d-text)}
.way-story p + p{margin-top:20px}
.way-story b{color:#fff;font-weight:500}
.way-spine{
  margin-top:28px;padding:20px 24px;
  border:1px solid var(--d-hair);border-radius:2px;
  background:rgba(255,255,255,.03);
  font-size:16px;line-height:1.5;color:#fff;
}
.way-spine .mono{color:var(--butter);display:block;margin-bottom:10px}
.way .way-spine-quote{
  margin-top:16px;padding-top:14px;border-top:1px solid var(--d-hair);
  font-size:14.5px;line-height:1.55;color:var(--d-text);
}
.way-spine-quote cite{
  display:block;margin-top:10px;font-style:normal;
  font-family:var(--mono);font-size:11px;letter-spacing:.05em;
  text-transform:uppercase;color:var(--d-label);
}
/* the 67-color palette sheet, a shipped artifact, shown pixel-perfect */
.way .way-palette{
  margin-top:24px;
  border:1px solid var(--d-hair);border-radius:2px;
  background:rgba(255,255,255,.03);overflow:hidden;
}
.way-palette figcaption{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:14px 18px;
  font-size:13.5px;color:var(--d-text);
}
.way-palette .mono{color:var(--butter)}
.way-palette img{
  width:100%;height:auto;
  image-rendering:pixelated;
  border-top:1px solid var(--d-hair);
}
/* sized to its own two rows. Stretched to the story column beside it, the
   rows were mostly air */
.way-facts{align-self:start;border:1px solid var(--d-hair)}
.way-fact{padding:24px 26px;border-bottom:1px solid var(--d-hair)}
.way-fact:last-child{border-bottom:0}
.way-fact .mono{color:var(--d-label);display:block;margin-bottom:12px}
.way-fact p{font-size:15px;line-height:1.55;color:var(--d-text)}
.way-fact p b{color:#fff;font-weight:500}
/* the core loop as three numbered legs. The last one ends on heading out
   again, so the list reads as a circle without needing an arrow drawn back */
.loop{list-style:none;margin:0;padding:0;counter-reset:leg}
.loop li{
  counter-increment:leg;position:relative;
  padding:11px 0 11px 28px;border-top:1px solid var(--d-hair);
  font-size:15px;line-height:1.55;color:var(--d-text);
}
.loop li:first-child{padding-top:0;border-top:0}
.loop li:last-child{padding-bottom:0}
.loop li::before{
  content:counter(leg,decimal-leading-zero);
  position:absolute;left:0;top:11px;
  font-family:var(--mono);font-size:11px;letter-spacing:.04em;
  line-height:23px;color:var(--butter);
}
.loop li:first-child::before{top:0}
.loop b{color:#fff;font-weight:500}
/* slice-moment strip: real WIP game art, framed as devlog */
.way-slice{margin-top:88px}
.way-slice-head{margin-bottom:28px}
.slice-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.slice{
  display:flex;flex-direction:column;
  border:1px solid rgba(255,255,255,.16);border-radius:8px;
  overflow:hidden;background:rgba(255,255,255,.03);
  transition:translate .15s ease-out,border-color .15s ease-out;
}
/* on `translate`, like the work cards, so the reveal's transform:none cannot
   cancel the lift */
.slice:hover{translate:0 -3px;border-color:rgba(255,255,255,.32)}
html.anim.reveal-armed .slice.reveal.in{
  transition:opacity .55s var(--ease-spring),transform .55s var(--ease-spring),
    translate .15s ease-out,border-color .15s ease-out;
}
.slice img{width:100%;height:auto}
.slice figcaption{
  padding:16px 18px 18px;
  font-size:13.5px;line-height:1.5;color:var(--d-text);
  border-top:1px solid var(--d-hair);flex:1;
}
.slice figcaption b{color:#fff;font-weight:500}
.way .slice-note{
  margin-top:18px;
  font-family:var(--mono);font-size:12px;letter-spacing:.04em;
  line-height:1.6;color:var(--d-label);
}
.slice-note::before{
  content:"";display:inline-block;width:5px;height:5px;
  background:var(--butter);margin-right:10px;vertical-align:2px;
}
.way .slice-log{
  margin-top:20px;padding:18px 22px;
  border:1px solid var(--d-hair);border-radius:2px;
  background:rgba(255,255,255,.03);
  font-size:14.5px;line-height:1.55;color:var(--d-text);
}
.slice-log .mono{color:var(--butter);display:block;margin-bottom:10px}
.slice-log p + p{margin-top:8px}

@media (max-width:960px){
  .way-cols{grid-template-columns:1fr;gap:40px;margin-top:64px}
  .quote-panel{padding:48px 32px 40px}
  .quote-glyph{font-size:84px}
  .slice-grid{grid-template-columns:1fr;gap:16px}
  .way-slice{margin-top:64px}
}
@media (max-width:680px){
  .way{margin-top:56px;padding:72px 0}
  .way + .shell > .sec:first-child{padding-top:64px}
  .way .section-head{margin-bottom:40px}
  .way-intro{margin-bottom:48px}
  .quote-panel{padding:40px 24px 32px}
  .quote-glyph{font-size:64px}
  .way-fact{padding:22px 20px}
}

/* ----------------------------------------------------------------- about */
.about{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:48px;margin-top:26px;align-items:start}
.about p{margin:0 0 14px;color:#3b3b3b}
.about p:last-child{margin-bottom:0}
.contact{list-style:none;margin:0;padding:0;font-family:var(--mono);font-size:13px;min-width:250px}
.contact li{padding:11px 0;border-bottom:1px solid var(--hair);display:flex;gap:16px;justify-content:space-between}
.contact li:first-child{padding-top:0}
.contact dt,.contact .lab{color:var(--gray-2);text-transform:uppercase;font-size:11px;letter-spacing:.09em}
.contact a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--hair-strong)}
.contact a:hover{border-bottom-color:var(--ink)}
/* Get in touch lands here (#contact) instead of opening a mail client, so the
   address gets a highlighter pass to show where to look. It stays marked for
   as long as the hash does. */
.contact{scroll-margin-top:120px}
.contact-email{
  background:linear-gradient(var(--butter),var(--butter)) no-repeat left center / 0% 100%;
  padding:2px 0 2px 4px;margin:-2px 0 -2px -4px;
}
#contact:target .contact-email{background-size:100% 100%;transition:background-size .6s var(--ease-spring) .15s}
.contact-val{display:inline-flex;align-items:center;gap:10px}
.copy-btn{
  font:inherit;font-size:10px;letter-spacing:.09em;text-transform:uppercase;line-height:1;
  color:var(--gray);background:var(--white);border:1px solid var(--hair-strong);border-radius:4px;
  padding:4px 7px;cursor:pointer;transition:color .15s,border-color .15s;
}
.copy-btn:hover{color:var(--ink);border-color:var(--ink)}
.copy-btn.is-done{color:var(--live);border-color:var(--live)}

/* ---------------------------------------------------------------- footer */
/* one orange block, full bleed. Ink on this orange clears 4.5:1; white does
   not, which is why the type is dark. The name underneath is decoration, a
   shade down from the block, and is cropped by the bottom edge on purpose. */
.foot{margin-top:74px}
.foot-in{
  background:var(--orange);color:var(--ink);
  overflow:hidden;
}
.foot-row{
  display:flex;justify-content:space-between;gap:24px;flex-wrap:wrap;
  padding-top:28px;padding-bottom:28px;
  font-family:var(--mono);font-size:12.5px;letter-spacing:.04em;
}
.foot a{color:var(--ink);text-decoration:none;border-bottom:1px solid rgba(32,32,32,.35)}
.foot a:hover{border-bottom-color:var(--ink)}
.foot :focus-visible{outline-color:var(--ink)}
/* sized off the shell's content box, so the name runs exactly gutter to
   gutter at any width; the vw line is for browsers without container units */
.foot-name{container-type:inline-size;user-select:none}
.foot-name span{
  display:block;
  font-size:14.6vw;font-size:16.9cqw;font-weight:600;letter-spacing:-.045em;
  line-height:.74;white-space:nowrap;
  color:var(--orange-deep);
  margin-bottom:-.06em;
}
/* the block wipes in from the left, and the name rides in a beat behind it.
   The clip goes on .foot-in, never on .foot: Chrome's IntersectionObserver
   counts the target's own clip-path, so a clipped footer never reports in
   and would stay hidden for good */
html.anim .foot.armed .foot-in{clip-path:inset(0 100% 0 0)}
html.anim .foot.armed .foot-name span{transform:translateX(-10%)}
html.anim .foot.armed.in .foot-in{clip-path:inset(0 0 0 0);transition:clip-path .9s cubic-bezier(.19,1,.22,1)}
html.anim .foot.armed.in .foot-name span{transform:none;transition:transform 1.4s cubic-bezier(.19,1,.22,1) .06s}

/* ------------------------------------------------------------ responsive */
@media (max-width:960px){
  .nav-links,.nav-cta .dashed-link{display:none}
  .nav-row{gap:14px}
  .brand-name{font-size:18px}
  .nav .btn{padding:11px 14px;font-size:14px}
  .nav-burger{
    display:flex;flex-direction:column;justify-content:center;gap:5px;
    width:40px;height:40px;padding:8px;border:1px solid var(--hair);border-radius:2px;cursor:pointer;
  }
  .nav-burger span{display:block;height:1.5px;background:#000;transition:transform .15s ease-out,opacity .15s ease-out}
  .nav-toggle:checked ~ .nav-burger span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
  .nav-toggle:checked ~ .nav-burger span:nth-child(2){opacity:0}
  .nav-toggle:checked ~ .nav-burger span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}
  /* escape the flex row: pin the drawer full-width below the sticky bar */
  .nav-drawer{
    display:none;position:absolute;top:100%;left:0;right:0;background:var(--white);
    border-top:1px solid var(--hair);border-bottom:1px solid var(--hair);
    max-height:calc(100vh - 80px);overflow-y:auto;box-shadow:0 20px 32px rgba(0,0,0,.07);
  }
  .nav-toggle:checked ~ .nav-drawer{display:block}
  .nav-drawer a{display:block;padding:16px 40px;font-size:16px;color:var(--ink);text-decoration:none;border-bottom:1px solid var(--hair)}
  .nav-drawer a:last-child{border-bottom:0}
  .nav.is-dark .nav-burger{border-color:var(--d-hair)}
  .nav.is-dark .nav-burger span{background:#fff}
  .nav.is-dark .nav-toggle:focus-visible ~ .nav-burger,
  .nav.is-dark .nav-burger:focus-visible{outline-color:var(--ice)}
  .nav.is-dark .nav-drawer{background:var(--dark);border-color:var(--d-hair)}
  .nav.is-dark .nav-drawer a{color:#fff;border-bottom-color:var(--d-hair)}
}
@media (max-width:900px){
  .hero-inner{padding-top:56px}
  .shell{padding-left:22px;padding-right:22px}
  .masthead{padding-top:44px}
  .prins{grid-template-columns:1fr;gap:22px}
  .about{grid-template-columns:1fr;gap:28px}
}
@media (max-width:820px){
  /* the fan cannot hold its geometry at this width, so the rays go and the
     nodes reflow into a wrapped row above the mark */
  .canvas{height:auto;padding:26px 0 150px;margin-top:0}
  .land{height:100%}
  .wires{display:none}
  .node{
    position:static;transform:none;min-width:0;
    box-shadow:0 4px 12px rgba(45,45,35,.14);
  }
  .node:hover,.node:focus-visible,.node.is-hot{transform:none}
  .nodes{
    position:relative;z-index:3;display:flex;flex-wrap:wrap;
    gap:9px;justify-content:center;padding:0 18px;
  }
  html.anim .node{opacity:1;animation:none}
  .monotile{width:84px;height:84px;border-radius:20px;bottom:36px}
  .monotile svg{width:50px;height:18.5px}
  .topnav{gap:14px;font-size:11px;flex-wrap:wrap;justify-content:flex-end}
  .entry-head{gap:7px}
}
@media (prefers-reduced-motion:reduce){
  html.anim .wires line,html.anim .node{animation:none;stroke-dashoffset:0;opacity:1}
  *{transition-duration:.01ms !important}
}

/* Glowlight's raspberry (#E30B5D) is the most saturated brand on the page by
   a wide margin, so it takes the washes down rather than reading as a pink
   card beside five muted ones. Nothing else about it changes. */
#glowlight{--bface:color-mix(in srgb,var(--b1) 2%,#fff);--wash1:4.5%;--wash2:4%}

/* --------------------------------------------------------- the lead card
   SST is the retainer everything else hangs off, so it takes the full row.
   It stays a pale card like the rest of the grid: the brand speaks through
   --b1 on the title and through one contained plate, not by flooding the
   card. An azure field behind a page made of paper and hairlines only ever
   reads as a different website.

   The plate is the rewards app's shipped icon, the same art that sits on a
   customer's home screen (sst-apps/apps/rewards/assets/icon.png, the `sst`
   brand in app.config.ts), exported at 192px for a plate that renders at 60.
   Rounded square because that is how the icon is actually seen, and because
   the page already speaks that shape in the hero mark.

   --b1/--b2 are read off that icon, whose field runs teal #087068 to gold
   #B8863C; the card carries #14857C/#C78A33, the same pair a shade deeper so
   it still sets type. packages/tokens calls teal + gold SST's real brand
   pair too. The azure this card used to carry is the app's in-UI "spa"
   palette: correct for the product, wrong beside the logo. */
.entry--lead{
  /* a touch more face and edge than the pale cards, since it leads the grid */
  --bface:color-mix(in srgb,var(--b1) 6%,#fff);
  --bedge:color-mix(in srgb,var(--b1) 32%,#fff);
}
/* 34px does not clear the plate beside it in a rail this wide */
.entry--lead .entry-head h3{font-size:30px}

/* a hairline between the rail and the prose, the same move the rest of the
   page makes with its rules. It is what stops the two columns reading as a
   block of text that happens to have a heading beside it. */
.entry--lead .entry-inner{grid-template-columns:348px minmax(0,1fr);gap:0}
.entry--lead .entry-rail{padding-right:32px;border-right:1px solid var(--hair)}
.entry--lead .entry-body{padding-left:34px;max-width:62ch}

/* Three chips wrapped two-then-one in the rail, which is the ragged part you
   see before anything else. As a hairline list they never wrap, they fill the
   column the prose already made tall, and they read as an index into the case
   studies. Orange is the app's action colour, so it lands on the arrow. */
.entry--lead .entry-links{
  display:block;margin:24px 0 0;
  border-top:1px solid var(--hair);
}
.entry--lead .entry-links li{border-bottom:1px solid var(--hair)}
.entry--lead .entry-links a,
.entry--lead .entry-links li:first-child a{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:11px 1px;border:0;border-radius:0;background:none;font-weight:400;
  color:var(--bi);
  transition:color .18s;
}
.entry--lead .entry-links a::after{
  content:"\2192";font-size:13px;line-height:1;
  color:color-mix(in srgb,var(--b1) 66%,#fff);
  transition:transform .22s var(--ease-spring),color .18s;
}
.entry--lead .entry-links a:hover,
.entry--lead .entry-links li:first-child a:hover,
.entry--lead .entry-links li + li a:hover{
  transform:none;background:none;border-color:transparent;color:var(--b2i);
}
.entry--lead .entry-links a:hover::after{transform:translateX(3px);color:var(--b2i)}
.entry--lead .entry-sites{margin-top:18px}
.entry--lead .entry-links a.is-ext::after{content:"\2197"}
.entry--lead .entry-links a.is-ext:hover::after{transform:translate(2px,-2px)}

@media (max-width:1080px){
  /* no room for the lockup in a narrower rail, so the plate goes back to
     sitting above the name */
  .entry--lead .entry-inner{grid-template-columns:268px minmax(0,1fr)}
  .entry--lead .entry-rail{padding-right:26px}
  .entry--lead .entry-body{padding-left:28px;max-width:none}
  /* .entry--plated sets the lockup and is declared later at equal weight, so
     this has to out-specify it rather than just follow it */
  .entry--lead.entry--plated .entry-head{
    display:flex;flex-direction:column;align-items:flex-start;gap:12px;
  }
  .entry--lead.entry--plated{--plate-size:56px}
  /* align-self is the cross axis once this is a flex column, so the lockup's
     centring would indent the name away from everything stacked under it */
  .entry--lead.entry--plated .entry-head h3{align-self:flex-start}
  .entry--lead .entry-head h3{font-size:27px}
}
@media (max-width:760px){
  /* the rail collapses into the single column here, so the divider goes with
     it. .entry-inner carries align-items:start, which shrink-wraps every flex
     child, so the list has to ask for the full width back. */
  .entry--lead .entry-rail{padding-right:0;border-right:0}
  .entry--lead .entry-body{padding-left:0;max-width:none}
  .entry--lead .entry-links{margin-top:4px;align-self:stretch}
}

/* ------------------------------------------------------------- the plates
   Three clients own a mark worth showing, so each of those cards carries it
   as a rounded square beside the name. Rounded square because that is how
   two of the three are actually seen, and because the page already speaks
   that shape in the hero mark. Everything else about the card is unchanged.

   Sources, in order of how much was ours to invent:
     SST         the rewards app's shipped icon, untouched
                 (sst-apps/apps/rewards/assets/icon.png, `sst` in app.config.ts)
     ChapterMade their own icon.svg (chaptermade/public), same geometry,
                 refilled from flat charcoal into their charcoal -> sunset so
                 it reads as their brand and not as a third black app icon
     Glowlight   built here. Their app has no icon (assets/README.md says so)
                 and a 3.6:1 wordmark will not sit in a square, so the plate
                 is the "g" lifted from that wordmark, set white on their
                 midnight ink over a raspberry bloom. Glow, and light. */
.entry--plated .entry-head{
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:13px 14px;
}
.entry--plated .entry-head::before{
  content:"";grid-column:1;grid-row:2;
  width:var(--plate-size,52px);height:var(--plate-size,52px);
  border-radius:calc(var(--plate-size,52px) * .234);
  background:var(--plate) center / cover no-repeat,var(--bi);
  box-shadow:
    inset 0 0 0 1px rgba(0,0,0,.07),
    0 1px 2px rgba(30,25,20,.16),
    0 8px 16px -8px color-mix(in srgb,var(--b1) 40%,rgba(30,25,20,.5));
}
.entry--plated .card-live{grid-column:1/-1;grid-row:1;justify-self:start}
.entry--plated .entry-head h3{grid-column:2;grid-row:2;align-self:center}

#sst{--plate:url("assets/sst-app-icon.png");--plate-size:60px}
#glowlight{--plate:url("assets/glowlight-plate.png")}
#chaptermade{--plate:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%231c1c1c'/%3E%3Cstop offset='.55' stop-color='%23c45f32'/%3E%3Cstop offset='1' stop-color='%23d9894a'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='64' height='64' rx='14' fill='url(%23g)'/%3E%3Cpath d='M44 22.5a14 14 0 1 0 0 19' fill='none' stroke='%23fff' stroke-width='6' stroke-linecap='round'/%3E%3C/svg%3E")}

@media (max-width:760px){
  /* the lockup survives here only if the plate gives the name room back */
  .entry--plated{--plate-size:46px}
  #sst{--plate-size:48px}
}

/* ---------------------------------------------- the condensed card
   Three small engagements that each want a sentence rather than a card of
   their own. Same voice as the full entries, just shorter: the constraint,
   then what it forced. New contract work lands here until it earns its own
   card. */
.minis{list-style:none;margin:0;padding:0;display:grid;gap:26px 34px;grid-template-columns:repeat(2,minmax(0,1fr))}
.minis li{display:flex;flex-direction:column;align-items:flex-start}
.minis h4{
  margin:0 0 9px;font-size:16px;font-weight:600;letter-spacing:-.008em;
  color:var(--bi);line-height:1.25;
}
.minis .mini-when{
  display:block;margin-top:5px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;
  text-transform:uppercase;font-weight:400;
  color:color-mix(in srgb,var(--b1) 45%,#555);
}
.minis p{margin:0 0 14px;font-size:14.5px;line-height:1.5;color:#44444a}
.minis p strong{color:var(--bi);font-weight:600}
.minis a{
  margin-top:auto;
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:11px;letter-spacing:.05em;
  text-transform:uppercase;text-decoration:none;
  color:var(--bi);
  background:color-mix(in srgb,var(--b1) 7%,#fff);
  border:1px solid color-mix(in srgb,var(--b1) 30%,#fff);
  border-radius:2px;padding:6px 11px;
  transition:background .18s,border-color .18s,color .18s,transform .18s var(--ease-spring);
}
.mini-links{margin-top:auto;display:flex;flex-wrap:wrap;gap:8px}
.mini-links a{margin-top:0}
.minis a:hover{
  transform:translateY(-1px);
  color:var(--b2i);
  border-color:color-mix(in srgb,var(--b2) 55%,#fff);
  background:color-mix(in srgb,var(--b2) 13%,#fff);
}
/* a divider between columns, so three snippets do not read as one paragraph
   that happens to have been poured into three buckets */
.minis li + li{
  padding-left:34px;margin-left:-34px;
  border-left:1px solid color-mix(in srgb,var(--b1) 16%,#fff);
}
@media (max-width:1080px){
  .minis{grid-template-columns:repeat(2,minmax(0,1fr))}
  .minis li + li{padding-left:0;margin-left:0;border-left:0}
  .minis li:nth-child(2n){padding-left:34px;margin-left:-34px;border-left:1px solid color-mix(in srgb,var(--b1) 16%,#fff)}
}
@media (max-width:760px){
  .minis{grid-template-columns:1fr;gap:22px}
  .minis li:nth-child(n){padding-left:0;margin-left:0;border-left:0}
  .minis li + li{padding-top:22px;border-top:1px solid color-mix(in srgb,var(--b1) 16%,#fff)}
}

/* A grouping card, not a client card. It takes the full row because it holds
   three things, but it is the least important card on the page, so it does not
   get to borrow the lead card's type scale. */
.entry--group.e--xl .entry-head h3{font-size:24px}
.entry--group .entry-rail{align-self:start}

/* --------------------------------------------------------- phone layout
   On a phone the top of the page was five things at once: the bar button,
   two hero buttons, the moving trust band, and five chips piled on the
   landscape. Here the first screen is the headline, the line under it and
   one button. The chips keep their look but line up as one column on the
   landscape, each with an arrow, so the fan still works as the page's
   table of contents. Everything below gets more air between sections and
   cards. "Get in touch" and "Start a project" both stay reachable, from the
   menu and from the About section. */
@media (max-width:760px){
  .nav-row{height:64px}
  .nav .nav-cta{display:none}
  .nav-burger{margin-left:auto}
  .nav-drawer{max-height:calc(100vh - 64px)}
  .shell{padding-left:24px;padding-right:24px}

  .hero-inner{padding-top:88px}
  .hero-inner .h1{font-size:44px}
  .hero-sub{margin-top:20px;font-size:18px;line-height:1.5}
  .hero-actions{margin-top:36px}
  .hero-actions .btn--ghost,.trustband{display:none}

  .canvas{padding:56px 24px 168px;margin-top:40px}
  .nodes{flex-direction:column;flex-wrap:nowrap;gap:10px;padding:0;max-width:360px;margin:0 auto}
  /* the inline left/top are the fan's desktop geometry */
  .node{position:relative;left:0 !important;top:0 !important;
    width:100%;white-space:normal;padding:12px 40px 13px 15px}
  .node::after{
    content:"\2192";position:absolute;right:15px;top:50%;transform:translateY(-50%);
    color:var(--gray-2);transition:transform .2s var(--ease-spring),color .2s;
  }
  .node:hover::after,.node:focus-visible::after{color:var(--amber);transform:translate(3px,-50%)}

  .sec{padding-top:80px}
  .sec-h{flex-direction:column;align-items:flex-start;gap:8px;padding-bottom:14px}
  .work-grid{gap:28px;margin-top:24px}
  .entry .entry-inner{gap:18px;padding:26px 22px}
  .entry-body > p{margin-bottom:18px}
  .flight{padding:24px 22px}

  /* the plate sits beside the name again, and the role line drops its box
     and reads as a caption under them */
  .entry.entry--plated .entry-head{
    display:grid;grid-template-columns:auto minmax(0,1fr);gap:0 14px;align-items:center;
  }
  .entry.entry--plated .entry-head::before{grid-row:1}
  .entry.entry--plated .entry-head h3{grid-row:1;align-self:center}
  .entry.entry--plated .card-live{grid-row:2;grid-column:1/-1;margin-top:14px}
  .entry .card-live{background:none;border:0;padding:0;line-height:1.5}
}
