/* =========================================================
   SEBENZA ONLINE — HOME 3 · "Type as the window"
   Reference lock: Exo Ape (type scale) + Locomotive (rhythm, text-only
   interaction). Paper canvas, amethyst ink, green only as a live dot.
   Media appears only in its native container: 9:16 reels, 16:10 browser.
   Glyphs (disc / half / quarter) are inline SVG — no GIFs on this page.
   ========================================================= */

:root{
  color-scheme:light;
  --paper:#F6F5F8;
  --ivory:#ECECEF;              /* the raised surface: a shade off the paper */
  --ink:#0A0A0C;                /* near-black, the dark ground inverted */
  --green:#00FF48;
  --purple:#7500F9;             /* the brand's main colour (the wordmark's dot); green is the accent */
  --paper-rgb:246,245,248;   /* for translucent paper (glass, sheets) */
  --ink-rgb:10,10,12;        /* for translucent ink (rules, tints) */
  --shadow-rgb:10,10,12;     /* shadows are ink-tinted in both themes */
  --highlight:rgba(255,255,255,.8);   /* the 1px light rim on glass */

  --line:rgba(var(--ink-rgb),.18);
  --line-strong:rgba(var(--ink-rgb),.32);
  --hair:1px solid var(--line);
  --hair-ink:1px solid var(--ink);

  --font:"Helvetica Neue Web","Helvetica Neue","HelveticaNeue",Helvetica,"HN Fallback",Arial,sans-serif;

  --fs-hero:clamp(88px,22vw,320px);
  --fs-display:clamp(48px,7vw,112px);
  --fs-h2:clamp(36px,4.6vw,72px);
  --fs-h3:clamp(22px,2vw,30px);
  --fs-row:clamp(22px,2.3vw,40px);
  --fs-num:clamp(40px,6vw,96px);
  --fs-lede:clamp(17px,1.3vw,20px);
  --fs-body:17px;
  --fs-label:11px;

  --track-hero:-.05em;
  --track-display:-.045em;
  --track-label:.1em;

  --pad:clamp(20px,5vw,64px);
  --maxw:clamp(1200px,1200px + (100vw - 1440px) * .92,1640px);
  --s-sec:clamp(120px,16vw,260px);   /* between sections: room enough that each one arrives (Aston, 2026-09-28: more white space, a dramatic entrance) */
  --s-block:clamp(56px,6vw,96px);
  --s-row:22px;
  --notch-room:clamp(18px,2.2vw,30px);   /* the logo notch hangs at the top: every page starts a little lower (Aston, 2026-09-28) */
  --nav-h:calc(24px + var(--notch-room));   /* how much room the top of the page keeps clear: the spine's, and the notch's */
  --gap:clamp(22px,2.6vw,40px);   /* the spine's step in from whichever edge it is on */

  --wall-h:62svh;
  --focus:1px solid var(--ink);

  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.25,1,.5,1);
  --t-fast:.25s;
  --t-med:.5s;
  --t-slow:.9s;
  --loop-a:2s;
  --loop-b:3.5s;

  /* written by js/home.js: hero scroll progress 0..1 */
  --p:0;
}

/* ---------- DARK MODE ----------
   Amethyst paper, paper ink. Follows the system by default; the toggle in
   the nav stamps data-theme on <html> (remembered in localStorage). */
:root[data-theme="dark"]{
  color-scheme:dark;
  --paper:#0A0A0C;
  --ivory:#151517;
  --ink:#F6F5F8;
  --paper-rgb:10,10,12;
  --ink-rgb:246,245,248;
  --shadow-rgb:0,0,0;
  --highlight:rgba(255,255,255,.08);
  --glass-bg:rgba(20,20,24,.44);
  --glass-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n' x='0' y='0' width='100%' height='100%'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='2' stitchTiles='stitch' seed='9'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeColorMatrix type='matrix' values='1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 0 .11'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");   /* finer grain on dark */
  --glass-line:rgba(255,255,255,.14);
  --glass-sheen:linear-gradient(135deg,rgba(255,255,255,.05) 0%,rgba(255,255,255,.015) 36%,rgba(255,255,255,0) 60%,rgba(255,255,255,0) 100%);
  --glass-sheen-band:linear-gradient(135deg,rgba(255,255,255,.03),rgba(255,255,255,0) 40%);
  --glass-shade:linear-gradient(to top,rgba(0,0,0,.22),rgba(0,0,0,0) 42%);
  --glass-blur:blur(24px) saturate(135%) brightness(.72);
  --glass-blur-band:blur(20px) saturate(130%) brightness(.78);
  --glass-rim:linear-gradient(150deg,rgba(255,255,255,.22) 0%,rgba(255,255,255,.07) 30%,rgba(255,255,255,.03) 55%,rgba(255,255,255,.1) 100%);
  --glass-rimline:linear-gradient(90deg,rgba(255,255,255,.18),rgba(255,255,255,.06) 26%,rgba(255,255,255,.04) 74%,rgba(255,255,255,.15));
  --glass-edge:rgba(0,0,0,.5);
  --glass-side:rgba(255,255,255,.045);
  --glass-shadow:0 0 0 1px var(--glass-edge),0 1px 2px rgba(0,0,0,.35),0 14px 34px -14px rgba(0,0,0,.6),0 36px 70px -30px rgba(0,0,0,.55);
  --glass-inset:inset 0 1px 0 rgba(255,255,255,.1),inset 0 -1px 0 rgba(255,255,255,.03),inset 1px 0 0 rgba(255,255,255,.04),inset -1px 0 0 rgba(255,255,255,.03);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --paper:#0A0A0C;
    --ivory:#151517;
    --ink:#F6F5F8;
    --paper-rgb:10,10,12;
    --ink-rgb:246,245,248;
    --shadow-rgb:0,0,0;
    --highlight:rgba(255,255,255,.08);
    --glass-bg:rgba(20,20,24,.44);
  --glass-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n' x='0' y='0' width='100%' height='100%'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='2' stitchTiles='stitch' seed='9'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeColorMatrix type='matrix' values='1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 0 .11'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");   /* finer grain on dark */
    --glass-line:rgba(255,255,255,.14);
    --glass-sheen:linear-gradient(135deg,rgba(255,255,255,.05) 0%,rgba(255,255,255,.015) 36%,rgba(255,255,255,0) 60%,rgba(255,255,255,0) 100%);
  --glass-sheen-band:linear-gradient(135deg,rgba(255,255,255,.03),rgba(255,255,255,0) 40%);
    --glass-shade:linear-gradient(to top,rgba(0,0,0,.22),rgba(0,0,0,0) 42%);
    --glass-blur:blur(24px) saturate(135%) brightness(.72);
    --glass-blur-band:blur(20px) saturate(130%) brightness(.78);
    --glass-rim:linear-gradient(150deg,rgba(255,255,255,.22) 0%,rgba(255,255,255,.07) 30%,rgba(255,255,255,.03) 55%,rgba(255,255,255,.1) 100%);
    --glass-rimline:linear-gradient(90deg,rgba(255,255,255,.18),rgba(255,255,255,.06) 26%,rgba(255,255,255,.04) 74%,rgba(255,255,255,.15));
    --glass-edge:rgba(0,0,0,.5);
    --glass-side:rgba(255,255,255,.045);
    --glass-shadow:0 0 0 1px var(--glass-edge),0 1px 2px rgba(0,0,0,.35),0 14px 34px -14px rgba(0,0,0,.6),0 36px 70px -30px rgba(0,0,0,.55);
    --glass-inset:inset 0 1px 0 rgba(255,255,255,.1),inset 0 -1px 0 rgba(255,255,255,.03),inset 1px 0 0 rgba(255,255,255,.04),inset -1px 0 0 rgba(255,255,255,.03);
  }
}
/* the wordmark is the traced SVG used as a mask, painted in the current ink,
   with the dot laid on top in true brand purple — so it reads in both themes */
.footer__mark{
  position:relative;display:block;
  width:min(100%,640px);aspect-ratio:2345/438;
  background:var(--ink);
  -webkit-mask:url("../assets/images/sebenza-wordmark.svg?v=65dd15e9") center/contain no-repeat;
  mask:url("../assets/images/sebenza-wordmark.svg?v=65dd15e9") center/contain no-repeat;
}
.footer__mark::after{content:"";position:absolute;left:94.07%;top:6.96%;width:4.99%;aspect-ratio:1;border-radius:50%;background:#7500F9}
/* client logos are dark marks: lift them on dark */
:root[data-theme="dark"] .clients__cell img{filter:grayscale(1) invert(1);opacity:.82}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .clients__cell img{filter:grayscale(1) invert(1);opacity:.82}}

/* ---------- FONTS ----------
   Self-hosted Helvetica Neue lands in assets/fonts/ when the licensed files
   arrive. local() lets macOS/iOS use the installed face without a request.
   "HN Fallback" is Arial with metric overrides so a swap does not shift layout. */
@font-face{font-family:"Helvetica Neue Web";font-weight:300;font-style:normal;font-display:swap;
  src:local("Helvetica Neue Light"),local("HelveticaNeue-Light"),url("../assets/fonts/HelveticaNeue-Light.woff2") format("woff2")}
@font-face{font-family:"Helvetica Neue Web";font-weight:400;font-style:normal;font-display:swap;
  src:local("Helvetica Neue"),local("HelveticaNeue"),url("../assets/fonts/HelveticaNeue-Regular.woff2") format("woff2")}
@font-face{font-family:"Helvetica Neue Web";font-weight:500;font-style:normal;font-display:swap;
  src:local("Helvetica Neue Medium"),local("HelveticaNeue-Medium"),url("../assets/fonts/HelveticaNeue-Medium.woff2") format("woff2")}
@font-face{font-family:"Helvetica Neue Web";font-weight:700;font-style:normal;font-display:swap;
  src:local("Helvetica Neue Bold"),local("HelveticaNeue-Bold"),url("../assets/fonts/HelveticaNeue-Bold.woff2") format("woff2")}
@font-face{font-family:"HN Fallback";src:local("Arial");size-adjust:97%;ascent-override:95%;descent-override:22%;line-gap-override:0%}

/* ---------- RESET ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* the root clips sideways overflow on every page (as the homepage always
   has): a hero's 3D sheet bled past the right edge at 1024-1280px and a
   trackpad could swipe the page sideways (2026-09-30). The body stays
   visible, or it would become its own scroller and swallow a swipe on iOS. */
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;overflow-x:clip}
body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font);
  font-weight:400;
  font-size:var(--fs-body);
  line-height:1.45;
  letter-spacing:-.012em;
  -webkit-font-smoothing:antialiased;
  overflow-x:visible;
}
img,video,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
ul,ol{list-style:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
:focus-visible{outline:var(--focus);outline-offset:3px}

.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--pad)}
.skip{position:absolute;left:var(--pad);top:-100px;z-index:200;padding:10px 14px;background:var(--ink);color:var(--paper);font-size:13px}
.skip:focus{top:12px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- TYPE ---------- */
h1,h2,.display{font-weight:300;letter-spacing:var(--track-display);line-height:.92;text-wrap:balance}
h2,.display{font-size:var(--fs-display)}
.h2{font-size:var(--fs-h2)}
h3{font-size:var(--fs-h3);font-weight:400;line-height:1.08;letter-spacing:-.03em}
.lede{font-size:var(--fs-lede);font-weight:300;line-height:1.4;letter-spacing:-.015em;max-width:44ch;text-wrap:pretty}
.label{
  display:inline-block;font-size:var(--fs-label);font-weight:500;
  letter-spacing:var(--track-label);text-transform:uppercase;line-height:1;
}
/* labels that can run to a second or third line get room between the lines
   (a line-height of 1 made them touch; review, 2026-09-30) */
.kind__src,.reel__cap .label,.results__item .label,.case__eyebrow,.serp__note,.work__foot .label{line-height:1.45}
.num{font-variant-numeric:tabular-nums}
[data-region-content][hidden]{display:none!important}   /* the other currency stays hidden, whatever the component styles its spans as */
.link{
  display:inline-block;position:relative;font-weight:400;
  padding-bottom:2px;
  background-image:linear-gradient(currentColor,currentColor);
  background-repeat:no-repeat;background-size:0 1px;background-position:0 100%;
  transition:background-size var(--t-med) var(--ease);
}
.link:hover,.link:focus-visible{background-size:100% 1px}
.link--on,.proof__item .label .link{background-size:100% 1px}   /* a link inside a figure's label reads as one */
.link--on:hover{background-size:0 1px;background-position:100% 100%}
/* small links reach at least 24px under a finger (review, 2026-09-30): an
   invisible hit area around each, so nothing on the page moves */
.fn a,.intro__fn,.kind__src .link,.case__facts dd a,.footer__col .link,.work__foot .link{position:relative}
.fn a::after,.intro__fn::after{content:"";position:absolute;left:50%;top:50%;width:28px;height:28px;transform:translate(-50%,-50%)}
.kind__src .link::after,.case__facts dd a::after{content:"";position:absolute;inset:-6px -2px}
.footer__col .link::after,.work__foot .link::after{content:"";position:absolute;inset:-5px -2px}

/* copy that differs by input: hover vs tap */
.on-touch{display:none}
@media (pointer:coarse){.on-mouse{display:none}.on-touch{display:inline}}

/* the live dot — the only place green is allowed */
.dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--green);vertical-align:middle;margin-right:10px;position:relative;top:-1px}

/* ---------- GLYPH MARKS ---------- */
.mark{width:14px;height:14px;color:var(--ink);flex:none;transition:transform var(--t-slow) var(--ease)}
.mark--half.is-in{transform:rotate(180deg)}
.mark--quarter.is-in{transform:rotate(-90deg)}
.mark--tile.is-in{transform:rotate(90deg)}
.mark--disc{transform:scale(.4)}
.mark--disc.is-in{transform:scale(1)}
/* The animated brand glyphs, as small animated WebPs made from the source
   GIFs (assets/gifs, 2443px and 1 to 3 MB each: never link those from a page).
   They show at 18px, so assets/glyphs holds 72px copies, 5 to 23 KB each.
   Markup: <img class="mark mark--gif" loading="lazy" decoding="async"
   src="/assets/glyphs/black-N.webp" data-light="/assets/glyphs/black-N.webp"
   data-dark="/assets/glyphs/white-N.webp" alt="" aria-hidden="true">
   — the theme toggle in js/home.js swaps the two. The new pages use the
   static SVG marks (.mark--disc/half/quarter). Which N goes where:
     2  the service / section lead-in (Selected work, Web design, the case study service line)
     4  "what we do" headings (What we actually do, What we did)
     1  outcomes (Full service, Results)
     5  Paid media
     3  motion and the reel (Motion graphics, Showreel)
   The artwork carries its own padding, so a touch over 14px lands on size. */
.mark--gif{width:18px;height:18px;object-fit:contain;transform:none!important}

/* ---------- NAV — floating glass spine (desktop) / glass "+" (mobile) ----------
   Desktop: a vertical frosted pill anchored left-centre — brand dot, the
   links set vertically, "Let's talk" at the foot. The version switcher is
   Mobile: a frosted circle bottom-right;
   the "+" turns to "×" and opens a frosted overlay of large links. */
/* glass recipe — shared by the nav spine, the switcher pill, the mobile "+"
   and overlay, the sheet's frosted bands and the reel button. A tinted,
   saturated blur; a diagonal sheen and a bottom shade for thickness; fine
   grain; a 1px gradient rim that catches light top-left instead of a flat
   border; a hairline outside it so the edge reads on paper; layered shadows. */
:root{
  --glass-bg:rgba(var(--paper-rgb),.5);
  --glass-sheen:linear-gradient(135deg,rgba(255,255,255,.5) 0%,rgba(255,255,255,.14) 36%,rgba(255,255,255,0) 60%,rgba(255,255,255,.12) 100%);
  --glass-shade:linear-gradient(to top,rgba(var(--ink-rgb),.07),rgba(var(--ink-rgb),0) 38%);
  --glass-sheen-band:linear-gradient(135deg,rgba(255,255,255,.3),rgba(255,255,255,0) 40%);   /* bands: lit at the sheet's corner only, nothing at their inner end */
  --glass-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n' x='0' y='0' width='100%' height='100%'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='2' stitchTiles='stitch' seed='9'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeColorMatrix type='matrix' values='1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 0 .22'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  --glass-blur:blur(24px) saturate(170%) brightness(1.05);
  --glass-blur-band:blur(20px) saturate(160%);
  --glass-rim:linear-gradient(150deg,rgba(255,255,255,.95) 0%,rgba(255,255,255,.4) 30%,rgba(255,255,255,.12) 55%,rgba(255,255,255,.55) 100%);
  --glass-rimline:linear-gradient(90deg,rgba(255,255,255,.9),rgba(255,255,255,.3) 26%,rgba(255,255,255,.18) 74%,rgba(255,255,255,.8));
  --glass-edge:rgba(var(--ink-rgb),.07);
  --glass-side:rgba(255,255,255,.4);
  --glass-shadow:0 0 0 1px var(--glass-edge),0 1px 2px rgba(var(--shadow-rgb),.06),0 12px 30px -14px rgba(var(--shadow-rgb),.35),0 32px 64px -32px rgba(var(--shadow-rgb),.28);
  --glass-inset:inset 0 1px 0 rgba(255,255,255,.85),inset 0 -1px 0 rgba(255,255,255,.22),inset 1px 0 0 rgba(255,255,255,.35),inset -1px 0 0 rgba(255,255,255,.22);
  --glass-line:rgba(255,255,255,.7);     /* legacy: still used by a few hairlines */
}
/* ---------- THE TRAVELLING IMAGE ----------
   The phones show a tall crop of a wide photograph. Clicking a piece of work
   lifts that crop out of the ring and opens it out as it rises: the window
   widens from the phone's portrait slice to the whole landscape frame, so more
   of the picture appears the further it travels. It holds in the middle of the
   screen while the page steps back, then is handed to the case study. */
.transit{
  position:fixed;z-index:300;pointer-events:none;overflow:hidden;
  background:var(--ivory);
  box-shadow:0 40px 90px -50px rgba(var(--shadow-rgb),.5);
}
.transit img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* the page steps back so there is only one thing to watch. .fleet--bottom is
   named explicitly because it sits outside <main>, which is why clicking a
   phone down there used to leave the page standing. */
.is-transit main,.is-transit .fleet--bottom,.is-transit .footer,.is-transit .nav,.is-transit .beacon{
  opacity:0;transition:opacity .42s var(--ease);pointer-events:none;
}
@media (prefers-reduced-motion:reduce){
  .is-transit main,.is-transit .fleet--bottom,.is-transit .footer,.is-transit .nav,.is-transit .beacon{transition:none}
}

/* ---------- CROSS-DOCUMENT VIEW TRANSITIONS ----------
   Both the homepage and the case studies opt in, so a click on a phone morphs
   its screen into the case study's hero instead of cutting. Browsers without
   it simply navigate; the hero's zoom-out still plays on arrival. */
@view-transition{navigation:auto}
@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}
}
/* the morphing pair gets the whole stage to itself, and eases rather than cross-fades */
::view-transition-old(work-hero),::view-transition-new(work-hero){
  animation-duration:.6s;animation-timing-function:var(--ease-out);
  mix-blend-mode:normal;height:100%;overflow:clip;object-fit:cover;
}
::view-transition-group(work-hero){animation-duration:.6s;animation-timing-function:var(--ease-out);z-index:10}

.nav{
  --hide:translateX(calc(-100% - var(--gap) - 18px));   /* where the spine waits when it is out of the way */
  position:fixed;left:var(--gap);top:0;bottom:0;z-index:100;
  display:flex;align-items:center;
  pointer-events:none;
}
/* the spine docks to any edge; the grip drags it and it snaps to the nearest.
   Left and right stand it on end, top and bottom lay it flat. */
:root[data-nav-edge="right"] .nav{left:auto;right:var(--gap);--hide:translateX(calc(100% + var(--gap) + 18px))}
:root[data-nav-edge="top"] .nav{left:0;right:0;top:var(--gap);bottom:auto;justify-content:center;align-items:flex-start;--hide:translateY(calc(-100% - var(--gap) - 18px))}
:root[data-nav-edge="bottom"] .nav{left:0;right:0;top:auto;bottom:var(--gap);justify-content:center;align-items:flex-end;--hide:translateY(calc(100% + var(--gap) + 18px))}
/* A flat spine occupies real height, so the page has to make room for it. The
   bar is 58px; the rest is its step in from the edge plus air, so the first
   line of the hero clears it rather than hiding underneath. */
:root[data-nav-edge="top"]{--nav-h:calc(var(--gap) + 58px + 22px + 52px)}   /* the spine docked at the top sits below the notch */
:root[data-nav-edge="bottom"]{--nav-foot:calc(var(--gap) + 58px + 22px)}
:root[data-nav-edge="bottom"] body{padding-bottom:var(--nav-foot)}
.nav__inner{
  pointer-events:auto;position:relative;
  display:flex;flex-direction:column;align-items:center;gap:22px;
  width:58px;padding:16px 0 18px;
  border-radius:999px;
}
/* the glass itself: pills share one surface */
.nav__inner{
  background:var(--glass-noise),var(--glass-sheen),var(--glass-shade),var(--glass-bg);
  background-blend-mode:soft-light,normal,normal,normal;
  border:1px solid transparent;                       /* the rim ring paints over this */
  box-shadow:var(--glass-shadow),var(--glass-inset);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
}
/* the rim: a 1px gradient ring, lit top-left, kept off the content by a mask */
.nav__inner::before,.nav__burger::before,.beacon__plate::before{
  content:"";position:absolute;inset:-1px;border-radius:inherit;padding:1px;pointer-events:none;
  background:var(--glass-rim);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;
}
.nav__links{display:flex;flex-direction:column;align-items:center;gap:20px;margin:0}
.nav__link{
  writing-mode:vertical-rl;-webkit-text-orientation:sideways;text-orientation:sideways;transform:rotate(180deg);   /* sideways: no upright punctuation forms, the apostrophe stays an apostrophe */
  font-size:13px;font-weight:400;letter-spacing:.02em;line-height:1;
  padding:6px 4px;opacity:.78;
  transition:opacity var(--t-fast) var(--ease);
}
.nav__link:hover,.nav__link:focus-visible{opacity:1}
/* docked right: the text turns over so the feet of the letters face into the
   page, and the pill runs the other way — grip at the top, sun and moon at the
   foot — so it still reads from the outside in */
:root[data-nav-edge="right"] .nav__inner{flex-direction:column-reverse;padding:18px 0 16px}
:root[data-nav-edge="right"] .nav__links{flex-direction:column-reverse}
:root[data-nav-edge="right"] .nav__link{transform:none}   /* unrotated: the baseline now faces inward */
/* The links are written Home, About, Services, Work: the order the flat bar
   reads left to right (Aston, 2026-09-29: "home should come first"), and the
   order a keyboard and a screen reader meet them. Stood on end, the words are
   turned and read from the foot up, so the four are laid the other way round
   the pill, Home nearest the foot (docked right, where the column is reversed,
   nearest the top), as the spine has always read. */
@media (min-width:901px){
  :root:not([data-nav-edge="top"]):not([data-nav-edge="bottom"]) .nav__links > a:nth-of-type(1){order:4}
  :root:not([data-nav-edge="top"]):not([data-nav-edge="bottom"]) .nav__links > a:nth-of-type(2){order:3}
  :root:not([data-nav-edge="top"]):not([data-nav-edge="bottom"]) .nav__links > a:nth-of-type(3){order:2}
  :root:not([data-nav-edge="top"]):not([data-nav-edge="bottom"]) .nav__links > a:nth-of-type(4){order:1}
  :root:not([data-nav-edge="top"]):not([data-nav-edge="bottom"]) .nav__links > a.nav__cta{order:5}
}
/* laid flat: a row of upright links */
:root[data-nav-edge="top"] .nav__inner,:root[data-nav-edge="bottom"] .nav__inner{flex-direction:row;width:auto;height:58px;padding:0 20px;gap:20px}
:root[data-nav-edge="top"] .nav__links,:root[data-nav-edge="bottom"] .nav__links{flex-direction:row;align-items:center;gap:20px}
:root[data-nav-edge="top"] .nav__link,:root[data-nav-edge="bottom"] .nav__link{writing-mode:horizontal-tb;transform:none;padding:4px 2px}
:root[data-nav-edge="top"] .nav__cta,:root[data-nav-edge="bottom"] .nav__cta{
  margin:0 0 0 2px;padding:4px 0 4px 18px;border-bottom:0;border-left:var(--hair);
}
.nav__cta{opacity:1;font-weight:500;margin-bottom:2px;padding-bottom:18px;border-bottom:var(--hair)}   /* a hairline sets it apart; no dot. The link is rotated 180deg, so its physical bottom is the visual top */
.nav__cta .dot{display:none}
/* ---------- the services flyout ----------
   The spine docks to any edge, so the panel cannot have a fixed side: it
   always emerges perpendicular to whichever edge the spine is on, and slides
   out of that same edge. --fly-at is written by js/home.js and is the trigger's
   own position along the spine, so the panel arrives beside the word that
   opened it rather than at some fixed point.

   It is a sibling of the pill, not a child, because the pill is a rounded
   glass capsule with its own overflow and a panel growing out of it would be
   clipped by its own container. */
.nav__fly{
  position:absolute;z-index:2;pointer-events:auto;
  min-width:250px;padding:14px;
  border-radius:20px;
  background:var(--glass-noise),var(--glass-sheen),var(--glass-shade),var(--glass-bg);
  background-blend-mode:soft-light,normal,normal,normal;
  border:1px solid transparent;
  box-shadow:var(--glass-shadow),var(--glass-inset);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  display:flex;flex-direction:column;gap:2px;
  opacity:0;visibility:hidden;
  transition:opacity var(--t-fast) var(--ease),transform var(--t-fast) var(--ease),visibility 0s .2s;
}
.nav__fly::before{
  content:"";position:absolute;inset:-1px;border-radius:inherit;padding:1px;pointer-events:none;
  background:var(--glass-rim);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;
}
.nav.is-fly .nav__fly{opacity:1;visibility:visible;transform:none;transition-delay:0s}

/* where it comes from, per edge. The closed state is offset toward the spine,
   so it appears to slide out of it. */
.nav__fly{left:100%;top:var(--fly-at,50%);transform:translate(-10px,-50%);margin-left:14px}
.nav.is-fly .nav__fly{transform:translate(0,-50%)}
:root[data-nav-edge="right"] .nav__fly{
  left:auto;right:100%;margin-left:0;margin-right:14px;transform:translate(10px,-50%);
}
:root[data-nav-edge="right"] .nav.is-fly .nav__fly{transform:translate(0,-50%)}
:root[data-nav-edge="top"] .nav__fly{
  left:var(--fly-at,50%);top:100%;right:auto;margin:14px 0 0;transform:translate(-50%,-10px);
}
:root[data-nav-edge="top"] .nav.is-fly .nav__fly{transform:translate(-50%,0)}
:root[data-nav-edge="bottom"] .nav__fly{
  left:var(--fly-at,50%);top:auto;bottom:100%;right:auto;margin:0 0 14px;transform:translate(-50%,10px);
}
:root[data-nav-edge="bottom"] .nav.is-fly .nav__fly{transform:translate(-50%,0)}

/* a hairline bridge across the gap, so moving from the word to the panel does
   not pass over dead space and close it */
.nav__fly::after{
  content:"";position:absolute;top:0;bottom:0;left:-16px;width:16px;
}
:root[data-nav-edge="right"] .nav__fly::after{left:auto;right:-16px}
:root[data-nav-edge="top"] .nav__fly::after{left:0;right:0;top:-16px;bottom:auto;width:auto;height:16px}
:root[data-nav-edge="bottom"] .nav__fly::after{left:0;right:0;top:auto;bottom:-16px;width:auto;height:16px}

.nav__sub{
  display:grid;grid-template-columns:2.2em 1fr;align-items:baseline;gap:10px;
  padding:9px 10px;border-radius:12px;
  writing-mode:horizontal-tb;transform:none;   /* never sideways, whatever the spine is doing */
  font-size:13px;line-height:1.3;color:inherit;text-decoration:none;opacity:.8;
  transition:opacity var(--t-fast) var(--ease),background var(--t-fast) var(--ease);
}
.nav__sub .label{opacity:.62}
.nav__sub:hover,.nav__sub:focus-visible{opacity:1;background:rgba(var(--ink-rgb),.07);outline:none}
.nav__sub:focus-visible{box-shadow:inset 0 0 0 1px var(--line-strong)}
/* the trigger keeps its emphasis while its panel is open */
.nav.is-fly .nav__link[aria-expanded="true"]{opacity:1}

@media (max-width:900px){.nav__fly{display:none}}
.nav__subs{display:none}   /* the phone menu's copy of the services (js/home.js); the spine has the panel */

.nav__burger{display:none}
/* the grip: drag the spine to another edge, or move it with the arrow keys */
.nav__grip{
  display:none;pointer-events:auto;
  padding:6px;border-radius:8px;color:var(--ink);opacity:.3;cursor:grab;
  transition:opacity var(--t-fast) var(--ease),background var(--t-fast) var(--ease);
  touch-action:none;
}
.nav__grip span{
  display:block;width:14px;height:8px;
  background-image:radial-gradient(currentColor 1px,transparent 1.2px);
  background-size:4px 4px;background-position:1px 1px;
}
:root[data-nav-edge="top"] .nav__grip span,:root[data-nav-edge="bottom"] .nav__grip span{width:8px;height:14px}
.nav__grip:hover,.nav__grip:focus-visible{opacity:.75;background:rgba(var(--ink-rgb),.06)}
.nav.is-drag .nav__grip{cursor:grabbing;opacity:.85}
/* theme toggle: a moon to go dark, a sun to come back. It stands at the head of
   the spine, where the brand dot used to be. */
.nav__theme{
  display:grid;place-items:center;position:relative;
  width:36px;height:36px;border-radius:50%;color:var(--ink);opacity:.75;
  transition:opacity var(--t-fast) var(--ease),background var(--t-fast) var(--ease);
}
.nav__theme:hover,.nav__theme:focus-visible{opacity:1;background:rgba(var(--ink-rgb),.06)}
.nav__theme-i{
  grid-area:1/1;width:17px;height:17px;
  transition:opacity var(--t-med) var(--ease),transform var(--t-slow) var(--ease);
}
/* light: the moon is offered. dark: the sun is. The other one is turned away. */
.nav__theme-i--sun{opacity:0;transform:rotate(-90deg) scale(.5)}
.nav__theme-i--moon{opacity:1;transform:none}
:root[data-theme="dark"] .nav__theme-i--sun{opacity:1;transform:none}
:root[data-theme="dark"] .nav__theme-i--moon{opacity:0;transform:rotate(90deg) scale(.5)}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .nav__theme-i--sun{opacity:1;transform:none}
  :root:not([data-theme="light"]) .nav__theme-i--moon{opacity:0;transform:rotate(90deg) scale(.5)}
}

/* ---------- BEACON — "the menu lives here" ----------
   The favicon's mark (a half disc and two quarter discs, measured off
   assets/icons/sebenza-favicon.png) as three separate pieces of glass raised on
   a clear plate, pinned where the spine appears. It carries the inverse of the
   spine's state: visible while the spine is away, gone once it slides in.

   The plate is an unmasked circle and the only layer with a backdrop-filter —
   the shapes are masked but carry none, because a mask above a backdrop-filter
   can blind it to what is behind (see the note in css/fleet.css).

   js/home.js reads the bright, coloured things elsewhere on the page — the
   Bo-Kaap phones on the hero ring, the lit chip, the footer aurora — and writes
   the light's direction, colour and strength here, so the glass catches colour
   from across the page rather than only from what sits directly behind it. */
.beacon{
  --lx:0;                          /* light direction, roughly -1..1 */
  --ly:-1;
  --lc:255,255,255;                /* light colour, an rgb triplet */
  --li:0;                          /* light strength, 0..1 */
  --lr:150;                        /* the raking angle, degrees, following the light */
  --la:var(--lr);
  --d:54px;                        /* the plate */
  --mk:31px;                       /* the mark inside it */
  display:none;
  position:absolute;left:calc((58px - var(--d)) / 2);top:50%;
  width:var(--d);height:var(--d);margin-top:calc(var(--d) / -2);
  pointer-events:none;
  perspective:220px;
  transition:opacity .35s var(--ease),transform .55s var(--ease);
}
.beacon__plate{
  position:absolute;inset:0;border-radius:50%;
  background:var(--glass-noise),var(--glass-sheen),var(--glass-shade),var(--glass-bg);
  background-blend-mode:soft-light,normal,normal,normal;
  border:1px solid transparent;
  box-shadow:var(--glass-shadow),inset 0 1px 0 rgba(255,255,255,.55),inset 0 -1px 0 rgba(255,255,255,.14);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
}
.beacon__mark{
  position:absolute;left:50%;top:50%;
  width:var(--mk);height:var(--mk);margin:calc(var(--mk) / -2) 0 0 calc(var(--mk) / -2);
  transform-style:preserve-3d;
  transform:rotateY(calc(var(--lx) * -8deg)) rotateX(calc(var(--ly) * 8deg));
  transition:transform .5s var(--ease);
}
/* three pieces, each at its own depth so they read as separate glass */
.beacon__shape{position:absolute;inset:0;transform-style:preserve-3d}
.beacon__shape--dome{transform:translateZ(3.5px)}
.beacon__shape--ql{transform:translateZ(1px)}
.beacon__shape--qr{transform:translateZ(2.2px)}
/* the three pieces sit at different angles to the light, so they never read as one engraved plate */
.beacon__shape--ql .beacon__face{--la:calc(var(--lr) + 40)}
.beacon__shape--qr .beacon__face{--la:calc(var(--lr) - 34)}
.beacon__shape--dome{--m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M0 50A50 50 0 0 1 100 50Z' fill='%23000'/%3E%3C/svg%3E")}
.beacon__shape--ql{--m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M0 60A40 40 0 0 1 40 100H0Z' fill='%23000'/%3E%3C/svg%3E")}
.beacon__shape--qr{--m:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 60H99.1A50 50 0 0 1 50 100Z' fill='%23000'/%3E%3C/svg%3E")}
.beacon__face,.beacon__side{
  position:absolute;inset:0;display:block;
  -webkit-mask:var(--m) center/contain no-repeat;mask:var(--m) center/contain no-repeat;
}
/* the shapes themselves are solid: black over a light part of the page,
   white over a dark one (Aston, 2026-09-30). js/home.js reads what is behind
   the beacon as the page scrolls and sets .is-on-dark or .is-on-light; before
   it does, the theme decides. The thickness behind each face is a shade of
   the same colour, so the pieces still read as separate. */
.beacon{--beacon-ink:#0A0A0C;--beacon-edge-ink:#3a3a42;--beacon-edge-deep-ink:#1c1c21}
:root[data-theme="dark"] .beacon{--beacon-ink:#fff;--beacon-edge-ink:rgba(255,255,255,.62);--beacon-edge-deep-ink:rgba(255,255,255,.4)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .beacon{--beacon-ink:#fff;--beacon-edge-ink:rgba(255,255,255,.62);--beacon-edge-deep-ink:rgba(255,255,255,.4)}}
.beacon.is-on-light{--beacon-ink:#0A0A0C;--beacon-edge-ink:#3a3a42;--beacon-edge-deep-ink:#1c1c21}
.beacon.is-on-dark{--beacon-ink:#fff;--beacon-edge-ink:rgba(255,255,255,.62);--beacon-edge-deep-ink:rgba(255,255,255,.4)}
.beacon__face{background:var(--beacon-ink);transition:background-color .3s var(--ease)}
/* over a dark part of the page the glass itself smokes over, so the white
   shapes stand on dark glass as the black ones stand on clear */
.beacon__plate{transition:background .3s var(--ease)}
.beacon.is-on-dark .beacon__plate{background:var(--glass-noise),linear-gradient(180deg,rgba(255,255,255,.1),rgba(255,255,255,.02)),rgba(18,18,22,.58);background-blend-mode:soft-light,normal,normal}
/* the thickness: layers stacked behind the face */
.beacon__side{
  transform:translateZ(calc(var(--z) * -1px)) scale(calc(1 - var(--z) * .008));
  background:var(--beacon-edge-ink);transition:background-color .3s var(--ease);
}
.beacon__side:last-of-type{background:var(--beacon-edge-deep-ink)}
/* the beacon sits on the rail wherever the spine is docked */
:root[data-nav-edge="right"] .beacon{left:auto;right:calc((58px - var(--d)) / 2)}
:root[data-nav-edge="top"] .beacon,:root[data-nav-edge="bottom"] .beacon{
  left:50%;right:auto;margin:0 0 0 calc(var(--d) / -2);
}
:root[data-nav-edge="top"] .beacon{top:calc((58px - var(--d)) / 2);bottom:auto}
:root[data-nav-edge="bottom"] .beacon{top:auto;bottom:calc((58px - var(--d)) / 2)}
@media (hover:hover) and (pointer:fine) and (min-width:901px){
  .beacon{display:block}
  .nav.is-peek .beacon,.nav:focus-within .beacon{opacity:0;transform:translateX(-8px)}   /* the spine takes over */
}
@media (prefers-reduced-motion:reduce){
  .beacon,.beacon__mark{transition:none}
}

/* "Let's talk", kept on screen beside the beacon while the spine is away
   (js/home.js; Aston, 2026-09-30): the same glass, the same rail */
.nav__stay{display:none}
@media (hover:hover) and (pointer:fine) and (min-width:901px){
  .nav__stay{
    position:absolute;left:calc((58px - 44px) / 2);top:calc(50% + 27px + 14px);
    display:inline-flex;align-items:center;height:44px;padding:0 18px 0 16px;border-radius:999px;
    font-size:13px;font-weight:500;letter-spacing:.01em;white-space:nowrap;color:var(--ink);
    pointer-events:auto;
    background:var(--glass-noise),var(--glass-sheen),var(--glass-shade),var(--glass-bg);
    background-blend-mode:soft-light,normal,normal,normal;
    box-shadow:var(--glass-shadow),var(--glass-inset);
    -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
    transition:opacity .35s var(--ease) .35s,transform .55s var(--ease) .35s,visibility 0s linear .35s;   /* after the spine has gone */
  }
  .nav__stay .dot{margin-right:9px}
  .nav__stay:hover{transform:translateY(-1px)}
  .nav.is-peek .nav__stay,.nav:focus-within .nav__stay,.nav.is-drag .nav__stay,.nav.is-fly .nav__stay{
    opacity:0;visibility:hidden;transform:scale(.9);transition:opacity .2s var(--ease),transform .3s var(--ease),visibility 0s linear .3s;
  }
  :root[data-nav-edge="right"] .nav__stay{left:auto;right:calc((58px - 44px) / 2)}
  :root[data-nav-edge="top"] .nav__stay,:root[data-nav-edge="bottom"] .nav__stay{left:calc(50% + 27px + 14px)}
  :root[data-nav-edge="top"] .nav__stay{top:calc((58px - 44px) / 2);bottom:auto}
  :root[data-nav-edge="bottom"] .nav__stay{top:auto;bottom:calc((58px - 44px) / 2)}
}
@media (prefers-reduced-motion:reduce){.nav__stay{transition:none}}

/* desktop: the spine slides out of the way and returns when the pointer nears the edge (js adds .is-peek) */
@media (hover:hover) and (pointer:fine) and (min-width:901px){
  .nav__grip{display:block}
  .nav__inner{transition:transform .55s var(--ease),opacity .35s var(--ease),visibility 0s linear .55s;transform:var(--hide);opacity:0;visibility:hidden}
  .nav.is-peek .nav__inner,.nav:focus-within .nav__inner{transform:none;opacity:1;visibility:visible;transition-delay:0s}
  /* dragging: the pill retracts into the glass icon — both are centred on the
     rail, so it shrinks straight into it — and the icon then follows the
     pointer, so there is one small thing to place instead of a long bar */
  .nav.is-drag .nav__inner{
    opacity:0;transform:scale(.28);visibility:visible;
    transition:opacity .2s var(--ease),transform .26s var(--ease);
  }
  .nav.is-drag .beacon{
    opacity:1;transform:translate(var(--bx,0px),var(--by,0px)) scale(1.14);
    transition:transform .18s var(--ease),opacity .18s var(--ease);
  }
  /* let go: the icon stays exactly where it was dropped and fades out there,
     while the pill unfolds at its new edge. Nothing travels across the screen. */
  .nav.is-dropping .beacon{
    opacity:0;transform:translate(var(--bx,0px),var(--by,0px)) scale(1.14);
    transition:opacity .3s var(--ease);
  }
}

/* ---------- FRAMES (the only media containers on the page) ----------
   No border: a picture's own edge is the frame (Aston, 2026-09-29: "I
   don't like borders"). */
.frame{
  position:relative;overflow:hidden;
  border:0;border-radius:0;
  background:var(--ivory);
  flex:none;
}
.frame--9x16{aspect-ratio:9/16}
.frame--16x10{aspect-ratio:16/10}
.frame--16x9{aspect-ratio:16/9}
.frame__poster,.frame__video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.frame__poster{z-index:1;transition:opacity var(--t-slow) var(--ease)}
/* the stage between two rows on a phone: empty until the new picture has
   arrived (js/home.js), never the last one under the new row's name */
.frame.is-swapping .frame__poster{opacity:0;transition:none}
.frame.is-live .frame__poster{opacity:0}
.frame__video{z-index:0}
/* intentional placeholder — clip in production, slot keeps its geometry */
.frame--empty{display:grid;place-items:center;padding:14px;text-align:center}

/* ---------- reels ----------
   The social reels, on the case studies and the organic social page: a grid
   of 9:16 frames, each paused on its poster until hovered, when its loop
   plays muted and the poster gives way; leaving it brings the poster back.
   The pill in the corner is only the sound switch: "Sound off" or "Sound
   on", no player controls. A double tap drops a heart, the way the apps do
   (js/social-reels.js). */
.reels{display:grid;gap:clamp(12px,1.6vw,24px)}
.reels--hero{grid-template-columns:repeat(3,minmax(0,1fr))}
.reels--grid{grid-template-columns:repeat(3,minmax(0,1fr));margin-top:var(--s-block)}
.reels--wall{grid-template-columns:repeat(4,minmax(0,1fr));margin-top:var(--s-block)}
.reels__cap{display:flex;justify-content:space-between;gap:12px;padding-top:12px;font-size:12px;opacity:.6}
.reel__sound{
  position:absolute;z-index:3;left:10px;bottom:10px;
  display:inline-flex;align-items:center;gap:8px;
  padding:7px 12px 7px 10px;border:0;border-radius:999px;
  background:rgba(10,10,12,.55);color:#fff;
  font:inherit;font-size:11px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;line-height:1;
  cursor:pointer;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  transition:opacity var(--t-fast) var(--ease),background var(--t-fast) var(--ease);
}
/* the dot is the state: grey off, green on */
.reel__sound::before{content:"";width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.5);flex:none;transition:background var(--t-fast) var(--ease)}
.reel__sound:hover,.reel__sound:focus-visible{background:rgba(10,10,12,.78)}
.frame.is-sound .reel__sound::before{background:var(--green)}
/* the heart: pops where the double tap landed, then lifts off and fades */
.reel__heart{
  position:absolute;z-index:4;width:64px;height:64px;margin:-32px 0 0 -32px;
  pointer-events:none;color:#fff;
  filter:drop-shadow(0 4px 14px rgba(0,0,0,.35));
  animation:reel-heart 1.1s cubic-bezier(.2,.8,.3,1) forwards;
}
.reel__heart svg{display:block;width:100%;height:100%}
@keyframes reel-heart{
  0%{transform:scale(.2) rotate(-8deg);opacity:0}
  18%{transform:scale(1.15) rotate(3deg);opacity:1}
  40%{transform:scale(1) rotate(0)}
  100%{transform:translateY(-90px) scale(.85);opacity:0}
}
@media (max-width:900px){
  .reels--grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .reels--wall{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:620px){
  .reels--hero{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
  .reels--grid,.reels--wall{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  /* three across, the frames are a third of the screen: the pill keeps its
     dot and drops its words */
  .reels--hero .reel__sound{left:6px;bottom:6px;padding:7px;font-size:0;gap:0}
  .reels--grid .reel__sound,.reels--wall .reel__sound{left:6px;bottom:6px;padding:6px 9px 6px 8px;font-size:10px}
}
@media (prefers-reduced-motion:reduce){
  .reel__heart{animation-duration:.4s}
}
.frame--empty .label{opacity:.55;line-height:1.5}
.frame--empty::before{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(var(--line) 1px,transparent 1px) 0 0/100% 25%,
    linear-gradient(90deg,var(--line) 1px,transparent 1px) 0 0/25% 100%;
  opacity:.6;
}
.frame--empty .label{position:relative;background:var(--ivory);padding:6px 8px}

/* ---------- HERO — type as the window ----------
   .hero is two viewports tall; the stage sticks for the first one. The wall
   of 9:16 reels is clipped to the letterforms of the h1 (SVG clipPath built
   from the h1's box by js/home.js). As --p climbs, the clip opens into a
   full-width strip and the copy fades. The strip is the hero's end state. */
.hero{position:relative;height:200svh;min-height:200svh}
.hero__stage{
  position:sticky;top:0;height:100svh;
  overflow:hidden;
  display:grid;place-items:center;
}
.hero__title{
  position:relative;z-index:1;
  font-size:var(--fs-hero);font-weight:700;   /* matches the wordmark's weight */
  letter-spacing:-.045em;line-height:.85;
  white-space:nowrap;text-wrap:nowrap;
  padding-inline:.02em;               /* room for the S overshoot */
}
.hero__wall{
  position:absolute;left:0;right:0;top:50%;z-index:2;
  height:var(--wall-h);
  transform:translateY(-50%);
  display:flex;align-items:flex-start;
  overflow:hidden;
  pointer-events:none;
  clip-path:url(#heroClip);
  -webkit-clip-path:url(#heroClip);
}
.hero.is-open .hero__wall{clip-path:none;-webkit-clip-path:none;pointer-events:auto;overflow-x:auto;overflow-y:visible;scrollbar-width:none}
.hero.is-open .hero__wall::-webkit-scrollbar{display:none}
.reel-item{flex:none;display:flex;flex-direction:column;width:calc(var(--wall-h) * 9 / 16)}
.reel-item .frame{height:var(--wall-h);width:100%}
.reel-item__cap{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:12px;align-items:baseline;
  padding:12px 12px 0;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-size:12px;letter-spacing:-.01em;
  opacity:0;transform:translateY(6px);
  transition:opacity var(--t-slow) var(--ease),transform var(--t-slow) var(--ease);
}
.reel-item__cap .label{opacity:.62}
.hero.is-open .reel-item__cap{opacity:1;transform:none}
.hero.is-open .hero__wall{height:auto}
.hero.is-open .hero__stage{align-content:center}

.hero__copy{
  position:absolute;left:0;right:0;z-index:3;
  padding-inline:var(--pad);
  pointer-events:none;
  opacity:calc(1 - clamp(0, (var(--p) - .3) / .3, 1));
  transform:translateY(calc(clamp(0, (var(--p) - .3) / .3, 1) * -24px));
}
.hero__copy > *{pointer-events:auto}
.hero__copy--top{top:calc(var(--nav-h) + 6vh)}
.hero__copy--bottom{bottom:6vh;display:flex;justify-content:space-between;align-items:flex-end;gap:32px;flex-wrap:wrap}
.hero__sub{font-size:var(--fs-lede);font-weight:300;letter-spacing:-.015em;line-height:1.35;max-width:34ch}
.hero__sub b{font-weight:500}
.hero__links{display:flex;gap:28px;font-size:15px}
.hero.is-open .hero__copy{visibility:hidden}

/* static fallback: no clip support or reduced motion */
.hero--static{height:auto;min-height:0;padding-top:calc(var(--nav-h) + 8vh)}
.hero--static .hero__stage{position:static;height:auto;display:block;overflow:visible}
.hero--static .hero__title{text-align:center;padding-block:10vh 6vh}
.hero--static .hero__wall{position:static;transform:none;height:auto;clip-path:none;-webkit-clip-path:none;pointer-events:auto;overflow-x:auto;scrollbar-width:none}
.hero--static .hero__copy{position:static;opacity:1;transform:none;visibility:visible;padding-bottom:5vh}
.hero--static .hero__copy--bottom{padding-top:24px}
.hero--static .reel-item__cap{opacity:1;transform:none}

/* ---------- CLIENTS ---------- */
.clients{margin-top:var(--s-sec)}
/* twelve hairline cells: eleven marks and a count. The 1px grid gap over a
   line-coloured background draws every rule at once, corners included. */
/* an open field of marks: no cell backgrounds, no rules — the logos sit
   straight on the sheet, spaced by the grid alone */
.clients__grid{
  display:grid;grid-template-columns:repeat(6,minmax(0,1fr));
  gap:0 clamp(16px,2vw,32px);
}
.clients__cell{
  display:flex;align-items:center;justify-content:center;   /* flex, not grid: gives the image a definite box for max-width */
  height:clamp(72px,6.4vw,92px);min-width:0;               /* no aspect-ratio here: with a min-height it forced 220px cells that overlapped */
  padding:12px 0;
  overflow:hidden;
}
/* the mark fills the cell's width, or reaches the height cap — whichever comes first */
.clients__cell img{
  width:auto;max-width:78%;min-width:0;flex:0 1 auto;height:clamp(26px,2.5vw,38px);   /* air on every side; the file itself carries ~8% padding */
  object-fit:contain;
  filter:grayscale(1);opacity:.85;
  transition:opacity var(--t-fast) var(--ease),filter var(--t-fast) var(--ease),transform var(--t-med) var(--ease);
}
.clients__cell:hover img{opacity:1;filter:none;transform:scale(1.04)}
.clients__cell--more{flex-direction:column;gap:8px;text-align:center}
.clients__cell--more .num{font-size:clamp(26px,2.4vw,36px);font-weight:300;letter-spacing:-.04em;line-height:1}
.clients__cell--more .label{opacity:.62;line-height:1.5}
.clients__head{display:flex;align-items:center;gap:12px;margin-bottom:10px}

/* ---------- SECTION HEAD ---------- */
.sec{padding-top:var(--s-sec)}
.sec__head{
  display:grid;grid-template-columns:auto 1fr;gap:16px 24px;align-items:center;
  padding-bottom:18px;border-bottom:var(--hair);margin-bottom:var(--s-block);
}
.sec__head .label{display:inline-flex;align-items:center;gap:12px}
.sec__head .h2{grid-column:1 / -1}
.sec__head .lede{grid-column:1 / -1;max-width:52ch}

/* ---------- WORK INDEX ---------- */
/* A section header ends in a rule and the ruled block beneath it starts with
   one, so a section opened with two lines and a band of trapped space between
   them. Where the block draws its own rule the header gives up its, and a
   section break is a single line again. The padding stays, so only the line
   goes. */
.sec__head:has(+ .work__grid),
.sec__head:has(+ .frame){border-bottom:0}

.work__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,36%);gap:clamp(32px,5vw,80px);align-items:start}
.work__rows{display:flex;flex-direction:column}
.work__row{
  display:grid;grid-template-columns:2.2em minmax(0,1fr) auto 1.2em;align-items:baseline;   /* no year column: no years anywhere (Aston, 2026-10-01) */
  gap:clamp(14px,2vw,28px);
  padding-block:var(--s-row);
  border-top:var(--hair);
  transition:padding var(--t-med) var(--ease);
}
.work__row:last-child{border-bottom:var(--hair)}
.work__row .label{opacity:.62;line-height:inherit}
.work__client{font-size:var(--fs-row);font-weight:300;letter-spacing:-.035em;line-height:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:transform var(--t-med) var(--ease)}
.work__service{font-size:13px;letter-spacing:-.01em;white-space:nowrap}
/* desktop: long names fit (Aston, 2026-09-30: "Albin Hagström & Son" and
   "Psycho Bunny South Africa" were cut off) — the names a size down, and a
   long service allowed onto two short lines; phones are unchanged */
@media (min-width:901px){
  .work__client{font-size:clamp(20px,1.75vw,28px)}
  .work__service{white-space:normal;max-width:11.5em;line-height:1.3;text-align:right}
}
.work__ind{display:none}
.work__arrow{font-size:18px;line-height:1;opacity:.35;transition:transform var(--t-med) var(--ease),opacity var(--t-med) var(--ease);justify-self:end}
.work__row.is-on .work__client,.work__row:hover .work__client{transform:translateX(8px)}
.work__row.is-on .work__arrow,.work__row:hover .work__arrow{opacity:1;transform:translateX(4px)}
.work__row.is-on{border-top-color:var(--ink)}
.work__row.is-on + .work__row{border-top-color:var(--ink)}
.work__row.is-on:last-child{border-bottom-color:var(--ink)}
.work__foot{display:flex;justify-content:space-between;align-items:center;gap:20px;padding-top:22px;font-size:14px}

.stage{position:sticky;top:calc(var(--nav-h) + 24px)}
.stage__frame{margin-inline:auto;display:none}
.stage__frame.is-shown{display:block}
.stage__frame--9x16{width:min(100%,calc((100svh - var(--nav-h) - 96px) * 9 / 16))}
.stage__frame--16x10{width:100%}
/* one frame for every piece: reels and browser captures are cropped to the
   same square so the index reads as a set rather than two formats trading
   places. */
.stage .frame{
  aspect-ratio:1/1;
  width:min(100%,calc(100svh - var(--nav-h) - 96px));
}
.stage__frame .frame__poster{opacity:1}
.stage__frame.is-live .frame__poster{opacity:0}
.stage__cap{display:flex;justify-content:space-between;gap:12px;padding-top:12px;font-size:12px;opacity:.6}
.stage.is-link{cursor:pointer}
@media (hover:hover){.stage.is-link:hover .stage__cap{opacity:.9}}

/* ---------- GLYPH WALL ---------- */
.glyphs{margin-top:var(--s-sec);border-top:var(--hair);border-bottom:var(--hair);overflow:hidden;position:relative}
.glyphs__grid{display:grid;grid-auto-rows:1fr;gap:0}
.glyphs__cell{
  aspect-ratio:1;color:var(--ink);
  transform:translate(var(--tx,0px),var(--ty,0px)) rotate(var(--rot,0deg));
  will-change:transform;
}
/* one cyber-green quarter loose in the wall: trails the mouse (or is dragged)
   and shoves the amethyst quarters aside as it passes */
.glyphs__q{
  position:absolute;left:0;top:0;z-index:2;
  width:var(--cell,72px);height:var(--cell,72px);
  margin:calc(var(--cell,72px) / -2) 0 0 calc(var(--cell,72px) / -2);
  color:var(--green);
  cursor:grab;touch-action:none;
  will-change:transform;
  filter:drop-shadow(0 10px 18px rgba(var(--shadow-rgb),.22));
}
.glyphs__q.is-held{cursor:grabbing}
.glyphs__q svg{width:100%;height:100%;display:block}
.glyphs__cell svg{width:100%;height:100%;transform:scale(.9);transform-origin:0 100%}

/* ---------- SERVICES ---------- */
.services__grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr))}
.svc{
  display:flex;flex-direction:column;gap:18px;
  padding:6px clamp(18px,2vw,32px) 8px 0;
  border-left:var(--hair);padding-left:clamp(18px,2vw,32px);
  min-height:280px;
}
.svc:first-child{border-left:0;padding-left:0}
.svc__top{display:flex;align-items:center;justify-content:space-between;gap:12px}
.svc__top .label{opacity:.62}
.svc h3{margin-top:auto;font-weight:300;font-size:var(--fs-h3)}
.svc p{font-size:15px;font-weight:300;line-height:1.45;letter-spacing:-.012em;max-width:30ch}
.svc__meta{font-size:11px;letter-spacing:.08em;text-transform:uppercase;opacity:.62;padding-top:14px;border-top:var(--hair)}
/* the four cards now lead to their service pages. The heading carries the
   link and a stretched pseudo-element makes the whole tile the target, so
   the tab order stays one stop per service rather than one per card part. */
.svc{position:relative}
.svc__link{color:inherit;text-decoration:none}
.svc__link::after{content:"";position:absolute;inset:0;z-index:1}
.svc__link:focus-visible{outline:none}
.svc:has(.svc__link:focus-visible){outline:2px solid var(--ink);outline-offset:8px}
.svc__link,.svc .mark,.svc__meta{transition:opacity var(--t-fast) var(--ease),transform var(--t-slow) var(--ease)}
.svc:hover .svc__meta{opacity:.85}
.svc:hover .mark--disc{transform:scale(1)}
.svc:hover .mark--half{transform:rotate(180deg)}
.svc:hover .mark--quarter{transform:rotate(-90deg)}
.svc:hover .mark--tile{transform:rotate(90deg)}

/* ---------- PROOF ---------- */
.proof{margin-top:var(--s-sec)}
.proof__row{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  border-top:var(--hair);border-bottom:var(--hair);
}
.proof__item{padding:28px clamp(16px,2vw,32px) 30px 0;border-left:var(--hair);padding-left:clamp(16px,2vw,32px);display:flex;flex-direction:column;gap:12px;container-type:inline-size}
.proof__item:first-child{border-left:0;padding-left:0}
.proof__n{font-size:var(--fs-num);font-size:min(var(--fs-num),27cqw);font-weight:300;letter-spacing:-.05em;line-height:.9;white-space:nowrap}   /* a six-figure visitor count must fit its column */
.proof__item .label{opacity:.62;line-height:1.5;max-width:22ch}
/* Three figures instead of four (the hosting page): three columns, so the row
   spans the page instead of stopping at three quarters with an empty fourth.
   It stays three across until the phone layout: a third figure alone on a
   second row reads as a leftover. */
@media (min-width:621px){
  .proof__row.proof__row--3{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (min-width:621px) and (max-width:1024px){
  .proof__row--3 > .proof__item.proof__item{border-bottom:0}
  .proof__row--3 > .proof__item:nth-child(3){border-left:var(--hair);padding-left:clamp(16px,2vw,32px)}
}

/* ---------- KIND WORDS ----------
   What clients say (scripts/kind-words.js), on the homepage and About: one
   quote set large in the story voice, then the rest three across, each with
   its source (the stars and "Google review", or the client and their
   interview). The featured one with a video has its own dark container; the
   rest have no cards and no borders, just a hairline over each, as the rows. */
.kind__lead{margin:0;padding-top:clamp(8px,1vw,16px)}
/* the lead with its picture (a still from the client's interview) is the
   featured testimonial, in a container of its own (Aston, 2026-09-29): a
   dark panel, the quote on the left and the still filling the right half to
   the panel's edges. In the dark theme the panel is a shade raised off the
   page, so it still reads as its own thing. */
.kind__lead--pic{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:stretch;
  padding-top:0;background:#0A0A0C;color:#F6F5F8;overflow:hidden;
}
:root[data-theme="dark"] .kind__lead--pic{background:#17171A}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .kind__lead--pic{background:#17171A}}
.kind__lead--pic .kind__quote{max-width:none;font-size:clamp(26px,2.5vw,42px)}
.kind__lead--pic .kind__body{grid-row:1;grid-column:1;align-self:center;padding:clamp(32px,4.4vw,80px)}
.kind__lead--pic .link{color:inherit}
.kind__lead--pic .kind__src{color:rgba(246,245,248,.66)}
.kind__lead--pic .kind__stars{color:#b985ff}
.kind__case{flex-basis:100%}   /* the brand purple is too dark on the black card */   /* the dark card in both themes */
.kind__pic{grid-row:1;grid-column:2;position:relative;display:block}
.kind__pic .frame{display:block;height:100%;background:#0A0A0C}
.kind__pic img{display:block;width:100%;height:100%;object-fit:cover;object-position:62% 50%;transition:transform .9s var(--ease-out)}
/* the play button: green, the accent, so it is the first thing found
   (Aston, 2026-09-29); the interview then plays right there (js/home.js) */
.kind__play{
  position:absolute;left:clamp(14px,1.6vw,24px);bottom:clamp(14px,1.6vw,24px);
  display:inline-flex;align-items:center;gap:10px;height:52px;padding:0 22px 0 18px;border-radius:999px;
  background:var(--green);color:#0A0A0C;font-size:14px;font-weight:600;letter-spacing:-.01em;
  box-shadow:0 12px 30px -12px rgba(0,255,72,.75);
  transition:transform .25s var(--ease-out),background-color .2s;
}
.kind__play svg{width:18px;height:18px;fill:currentColor;flex:none}
@media (hover:hover){
  .kind__pic:hover img{transform:scale(1.03)}
  .kind__pic:hover .kind__play{background:#3dff72;transform:scale(1.04)}
}
.kind__pic:focus-visible{outline:none}
.kind__pic:focus-visible .kind__play{outline:2px solid #fff;outline-offset:3px}
/* playing: the film plays where the still was, beside the quote, at its
   own 16:9 on the dark panel (Aston, 2026-09-29: no bigger box) */
.kind__pic .frame > .kind__video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;background:#0A0A0C;z-index:2;cursor:pointer}
/* its own two controls, bottom left, once it is playing: play or pause, and
   the sound (green while it is off, as the reel's is) */
.kind__ctl{position:absolute;left:clamp(14px,1.6vw,24px);bottom:clamp(14px,1.6vw,24px);z-index:3;display:flex;gap:10px}
.kind__btn{
  width:46px;height:46px;border-radius:50%;display:grid;place-items:center;margin:0;padding:0;border:0;cursor:pointer;
  color:#fff;background:rgba(10,10,12,.55);-webkit-backdrop-filter:blur(14px) saturate(160%);backdrop-filter:blur(14px) saturate(160%);
  transition:background-color .2s,color .2s,transform .2s var(--ease-out);
}
.kind__btn:active{transform:scale(.94)}
.kind__btn:focus-visible{outline:2px solid #fff;outline-offset:3px}
.kind__btn svg{width:19px;height:19px;fill:currentColor;flex:none}
.kind__btn .i-play,.kind__btn .i-x{display:none}
:is(.kind__pic,.reel__frame).is-paused .kind__btn .i-play{display:block}
:is(.kind__pic,.reel__frame).is-paused .kind__btn .i-pause{display:none}
:is(.kind__pic,.reel__frame).is-muted .kind__btn .i-x{display:inline}
:is(.kind__pic,.reel__frame).is-muted .kind__btn .i-waves{display:none}
:is(.kind__pic,.reel__frame).is-muted :is(.kind__mute,.reel__mute){background:var(--green);color:#0A0A0C}
@media (hover:hover){.kind__btn:hover{background:rgba(10,10,12,.72)}:is(.kind__pic,.reel__frame).is-muted :is(.kind__mute,.reel__mute):hover{background:#3dff72}}
.kind__pic.is-playing img{opacity:0}
.kind__pic.is-playing .kind__play{display:none}
.kind__pic.is-playing img{transform:none}
@media (max-width:620px){.kind__play{height:44px;padding:0 16px 0 13px;font-size:13px}}
@media (max-width:900px){
  .kind__lead--pic{grid-template-columns:1fr}
  .kind__pic{grid-row:1;grid-column:1}
  .kind__pic .frame{height:auto;aspect-ratio:16/9}
  .kind__lead--pic .kind__body{grid-row:2;padding:clamp(24px,6vw,40px)}
}
.kind__lead .kind__quote{margin:0;max-width:26ch;font-size:clamp(30px,3.6vw,58px);font-weight:300;letter-spacing:-.035em;line-height:1.08;text-wrap:balance}
.kind__grid{margin-top:var(--s-block);display:grid;grid-template-columns:repeat(3,minmax(0,1fr));column-gap:clamp(24px,3vw,48px)}
.kind__item{margin:0;padding:22px 0 clamp(28px,3vw,44px);border-top:var(--hair)}
.kind__more{margin-top:clamp(8px,1.4vw,20px)}   /* the homepage's way to the rest, on About */
.kind__item .kind__quote{margin:0;font-size:clamp(19px,1.45vw,23px);font-weight:300;letter-spacing:-.02em;line-height:1.38;text-wrap:pretty}
.kind__who{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;margin-top:18px}
.kind__lead .kind__who{margin-top:clamp(20px,2.4vw,32px)}
.kind__name{font-size:var(--fs-body);font-weight:500;letter-spacing:-.01em}
/* the credit line is quieted with its colour, not opacity, so the stars in
   it stay solid (they measured 3.5:1 at .62; review, 2026-09-30); in dark
   the stars take a lighter purple that holds 7:1 on the dark ground */
.kind__src{display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px 10px;color:rgba(var(--ink-rgb),.62)}
.kind__stars{color:var(--purple);letter-spacing:2px;font-size:13px}
:root[data-theme="dark"] .kind__stars{color:#b985ff}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .kind__stars{color:#b985ff}}
/* the services, said as one story with the five as chips (index.html;
   Aston, 2026-09-30) */
.services__say{
  margin-top:clamp(40px,4.4vw,72px);max-width:42ch;
  font-size:clamp(22px,2.4vw,36px);font-weight:300;letter-spacing:-.025em;line-height:1.95;text-wrap:pretty;
}
.services__say mark{background:var(--green);color:#0A0A0C;padding:0 .06em;margin:0 -.02em;-webkit-box-decoration-break:clone;box-decoration-break:clone}
/* the chips a size down from the words, with air round them: the line is
   tall enough that two rows of chips never meet (Aston, 2026-09-30: "all the
   lines are touching, all the buttons are touching") */
.services__say .chip{
  font-size:.82em;font-weight:400;letter-spacing:-.015em;line-height:1.25;
  padding:.16em .62em .2em;margin:0 .12em;border-radius:10px;white-space:nowrap;
}
.services__say .chip:first-child{margin-left:0}
.services__nw{white-space:nowrap}   /* a comma never starts a line, */
.services__nw .chip{margin-right:0}   /* and sits against its chip */
.kind__quote mark{background:var(--green);color:#0A0A0C;padding:0 .06em;margin:0 -.02em;-webkit-box-decoration-break:clone;box-decoration-break:clone}
.kind__quote mark.purple{background:var(--purple);color:#fff}
/* the grid never ends on a gap: a last row of one takes the whole row, a
   last row of two lets the second take two columns */
@media (min-width:981px){
  .kind__item:last-child:nth-child(3n+1){grid-column:1/-1}
  .kind__item:last-child:nth-child(3n+2){grid-column:span 2}
}
@media (max-width:980px){.kind__grid{grid-template-columns:repeat(2,minmax(0,1fr))}.kind__item:last-child:nth-child(odd){grid-column:1/-1}}
@media (max-width:620px){.kind__grid{grid-template-columns:1fr}}
/* straight under the heading (the services page, no interview between):
   the heading's rule is the only line, so the first row draws none of its
   own and the grid adds no gap of its own (Aston, 2026-09-30: two lines and
   a band of space between them) */
.sec__head + .kind__grid{margin-top:0}
.sec__head:has(+ .kind__grid){margin-bottom:clamp(10px,1.4vw,20px)}
.sec__head + .kind__grid > .kind__item:nth-child(-n+3){border-top:0}
@media (max-width:980px){.sec__head + .kind__grid > .kind__item:nth-child(3){border-top:var(--hair)}}
@media (max-width:620px){.sec__head + .kind__grid > .kind__item:nth-child(2){border-top:var(--hair)}}
.kind__item:last-child .kind__quote{max-width:44ch}

/* ---------- SHOWREEL ---------- */
.reel .frame--16x9{width:100%}
/* the showreel's controls are the interview's (.kind__ctl), bottom left; the
   picture itself plays and pauses it too (js/home.js) */
.reel__frame .frame__poster{cursor:pointer}
.reel__frame .kind__ctl{z-index:4}
.reel .frame video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;background:#0A0A0C;z-index:3;cursor:pointer}
.reel__cap{display:flex;justify-content:space-between;gap:12px;padding-top:12px;font-size:12px}
.reel__cap .label{opacity:.62}

/* ---------- CONTACT ---------- */
.contact{margin-top:var(--s-sec);padding-top:var(--s-block);border-top:var(--hair)}
.contact__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(24px,4vw,64px);align-items:end}
.contact__mail{display:inline-block;margin-top:var(--s-block);font-size:min(var(--fs-h2),7.4vw);font-weight:300;letter-spacing:-.04em;line-height:1;white-space:nowrap}
/* the quiet line under the question on the service pages: the gold standard,
   beside the gold. Muted through its colour, not opacity: it is also a
   .reveal, whose opacity is the fade-in's. */
.contact__sub{margin-top:clamp(16px,1.6vw,24px);font-size:var(--fs-lede);font-weight:300;line-height:1.4;letter-spacing:-.015em;max-width:40ch;color:color-mix(in srgb,var(--ink) 62%,transparent);text-wrap:pretty}
/* "gold standard" in every page's close, in metallic gold (Aston,
   2026-09-30). Not a highlighter box (he found that cheap): the words
   themselves are gold, shaded top to bottom like the gold pieces, a bright
   line above the middle and a deeper foot, set a weight up so the metal
   has room to show. Deep gold on the light page, where pale gold would not
   be read; bright gold on the dark one. */
mark.gold{
  --gold-ink:linear-gradient(180deg,#9A7428 0%,#6F4F12 34%,#B08433 52%,#7A5716 70%,#5A3E0C 100%);
  background:var(--gold-ink);
  -webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent;
  font-weight:500;padding:0;margin:0;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
}
:root[data-theme="dark"] mark.gold{--gold-ink:linear-gradient(180deg,#FBE9B0 0%,#E6BE5E 32%,#B8892F 52%,#EDCB76 68%,#A5772A 100%)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) mark.gold{--gold-ink:linear-gradient(180deg,#FBE9B0 0%,#E6BE5E 32%,#B8892F 52%,#EDCB76 68%,#A5772A 100%)}}
@media (forced-colors:active){mark.gold{background:none;color:CanvasText;-webkit-text-fill-color:CanvasText}}
.contact__meta{display:flex;flex-direction:column;gap:10px;font-size:14px;text-align:right}
.contact__meta .label{opacity:.62}

/* ---------- FOOTER ----------
   Map on top, then the wordmark set large against three compact columns. */
.footer{margin-top:var(--s-sec)}
.footer__map{padding-block:clamp(40px,5vw,72px) clamp(32px,4vw,56px)}
.footer__map-frame{position:relative;max-width:1100px;margin-inline:auto}   /* no padding here: the pins are placed in % of this box */
.footer__map-frame img{width:100%;height:auto;display:block}
.footer__pin{
  position:absolute;left:var(--x);top:var(--y);
  transform:translate(-50%,-50%);
  width:0;height:0;pointer-events:none;
}
.footer__pin .label{
  position:absolute;left:12px;top:-20px;
  white-space:nowrap;color:var(--ink);opacity:.7;
}
.footer__pin--below .label{top:6px}
.footer__pin--right .label{left:auto;right:12px;text-align:right}

.footer__grid{
  display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);
  gap:clamp(32px,5vw,96px);align-items:end;
  padding-block:clamp(24px,3vw,48px) clamp(40px,5vw,72px);
}
.footer__brand{display:flex;flex-direction:column;align-items:flex-end;min-width:0}   /* the wordmark, right-aligned */
.footer__cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px 20px;align-self:end}
.footer__col{display:flex;flex-direction:column;gap:10px;font-size:14px;min-width:0}
.footer__col .label{opacity:.62;margin-bottom:6px}
.footer__col .link{align-self:flex-start}
.footer__base{display:grid;grid-template-columns:1fr auto 1fr;gap:16px;align-items:center;padding-block:18px 72px;border-top:var(--hair)}   /* bottom clears the fixed version switcher */
.footer__base .label{opacity:.62}
.footer__base .footer__base-tag{opacity:.75;text-align:center}
.footer__base > :last-child{text-align:right}
/* the currency toggle, at the end of the footer's last line */
.footer__end{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:12px 16px}
.footer__region{display:inline-flex;gap:2px;padding:3px;border-radius:999px;border:var(--hair)}
.footer__region-btn{
  min-height:28px;padding:0 12px;border:0;border-radius:999px;background:none;color:inherit;cursor:pointer;
  font:inherit;font-size:var(--fs-label);font-weight:500;letter-spacing:var(--track-label);text-transform:uppercase;line-height:1;
  opacity:.62;transition:background-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease),opacity var(--t-fast) var(--ease);
}
.footer__region-btn:hover{opacity:1}
.footer__region-btn[aria-pressed="true"]{background:var(--ink);color:var(--paper);opacity:1}
.footer__region-btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* ---------- REVEAL ---------- */
/* the entrance: a longer rise, slower, easing out hard, so a section is seen
   arriving rather than blinking in; its parts follow one another */
.reveal{opacity:0;transform:translate3d(0,56px,0);transition:transform 1.25s cubic-bezier(.16,1,.3,1),opacity 1s cubic-bezier(.33,1,.68,1)}
.reveal.in{opacity:1;transform:none}
.reveal[data-delay="1"]{transition-delay:.12s}
.reveal[data-delay="2"]{transition-delay:.24s}
.reveal[data-delay="3"]{transition-delay:.36s}
@media (max-width:640px){.reveal{transform:translate3d(0,36px,0)}}

/* ---------- RESPONSIVE ---------- */
@media (max-width:1180px){
  .work__grid{grid-template-columns:minmax(0,1fr) minmax(0,40%)}
}
@media (max-width:1024px){
  .clients__grid{grid-template-columns:repeat(4,minmax(0,1fr))}
  .services__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .svc{min-height:0;padding-block:22px;border-top:var(--hair)}
  .svc:nth-child(-n+2){border-top:0;padding-top:6px}
  .svc:nth-child(odd){border-left:0;padding-left:0}
  .svc:nth-child(even){padding-right:0}
  .proof__row{grid-template-columns:repeat(2,minmax(0,1fr))}
  .proof__item:nth-child(odd){border-left:0;padding-left:0}
  .proof__item:nth-child(-n+2){border-bottom:var(--hair)}
  .footer__grid{grid-template-columns:1fr;gap:40px}
  .footer__brand{align-items:flex-start}
  .footer__mark{width:min(100%,520px)}
}
@media (max-width:900px){
  .nav{inset:auto clamp(14px,4vw,22px) clamp(14px,4vw,22px) auto;display:block}
  .nav__inner{width:auto;padding:0;gap:0;background:none;border:0;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;align-items:flex-end}
  .nav__inner::before{display:none}
  /* the glass "+" */
  .nav__burger{
    display:grid;place-items:center;position:relative;z-index:2;
    width:58px;height:58px;border-radius:50%;padding:0;margin:0;
    background:var(--glass-noise),var(--glass-sheen),var(--glass-shade),var(--glass-bg);
    background-blend-mode:soft-light,normal,normal,normal;
    border:1px solid transparent;
    box-shadow:var(--glass-shadow),var(--glass-inset);
    -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
    transition:transform var(--t-med) var(--ease);
  }
  .nav__burger span{position:absolute;left:50%;top:50%;width:20px;height:1.5px;margin:-.75px 0 0 -10px;background:var(--ink);transition:transform var(--t-med) var(--ease)}
  .nav__burger span:last-child{transform:rotate(90deg)}
  .nav__burger[aria-expanded="true"]{transform:rotate(45deg)}
  .nav__burger[aria-expanded="true"] span:first-child{transform:none}
  .nav__burger[aria-expanded="true"] span:last-child{transform:rotate(90deg)}
  /* the overlay */
  .nav__links{
    position:fixed;inset:0;z-index:1;
    display:flex;flex-direction:column;justify-content:flex-end;align-items:flex-end;gap:14px;
    padding:0 clamp(22px,6vw,34px) 104px;
    background:var(--glass-noise),linear-gradient(to bottom,rgba(var(--paper-rgb),.66),rgba(var(--paper-rgb),.86));
    background-blend-mode:soft-light,normal;
    -webkit-backdrop-filter:blur(30px) saturate(170%);backdrop-filter:blur(30px) saturate(170%);
    opacity:0;pointer-events:none;transform:translateY(14px);
    transition:opacity var(--t-med) var(--ease),transform var(--t-med) var(--ease);
  }
  .nav__links.is-open{opacity:1;pointer-events:auto;transform:none}
  /* With the services open the menu can be taller than a short phone, so it
     scrolls: the first item's auto margin keeps the menu at the foot when it
     fits (flex-end would push the overflow off the top, out of reach). The
     top padding is the room it keeps above itself when it scrolls. */
  .nav__links{justify-content:flex-start;overflow-y:auto;overscroll-behavior:contain;padding-top:40px}
  .nav__links > *{flex-shrink:0}   /* a scrolling column would otherwise squash its items to fit */
  .nav__links > :first-child{margin-top:auto}
  .nav__link{writing-mode:horizontal-tb;transform:none;font-size:30px;font-weight:300;letter-spacing:-.03em;padding:4px 0;opacity:1;text-align:right}

  /* ---------- the services, under Services ----------
     Services opens its list in place. A plus before the word turns into a
     minus while it is open; the list folds open by its own height, and while
     it is shut it takes back the column gap it would otherwise add. */
  .nav__link[data-fly]{display:flex;align-items:center;gap:14px}
  .nav__link[data-fly]::before{
    content:"";flex:none;width:13px;height:13px;opacity:.55;
    background:
      linear-gradient(currentColor,currentColor) center/100% 1.5px no-repeat,
      linear-gradient(currentColor,currentColor) center/1.5px 100% no-repeat;
    transition:background-size var(--t-med) var(--ease);
  }
  .nav__links.is-subs .nav__link[data-fly]::before{background-size:100% 1.5px,1.5px 0}
  .nav__subs{
    display:grid;grid-template-rows:0fr;margin-top:-14px;
    opacity:0;visibility:hidden;
    transition:grid-template-rows var(--t-med) var(--ease),margin var(--t-med) var(--ease),opacity var(--t-fast) var(--ease),visibility 0s linear var(--t-med);
  }
  .nav__subs > div{min-height:0;overflow:hidden;display:flex;flex-direction:column;align-items:flex-end}
  .nav__links.is-subs .nav__subs{grid-template-rows:1fr;margin-top:-6px;opacity:1;visibility:visible;transition-delay:0s}
  .nav__subs .nav__sub{
    display:flex;align-items:baseline;justify-content:flex-end;gap:12px;
    padding:5px 0;border-radius:0;background:none;text-align:right;
    font-size:17px;font-weight:300;letter-spacing:-.015em;opacity:.72;
  }
  .nav__subs .nav__sub .label{font-size:11px}
  .nav__subs .nav__sub:focus-visible{opacity:1;background:none;box-shadow:none;text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
  .nav__subs .nav__sub:hover{background:none}
  @media (hover:hover){.nav__subs .nav__sub:hover{opacity:1;text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}}   /* not on touch, where a hover sticks to whatever ends up under the last tap */
  .nav__subs .nav__sub--all{margin-top:4px;opacity:1}
  .nav__theme{width:44px;height:44px;margin-bottom:6px;border:var(--hair)}
  .nav__theme-i{width:19px;height:19px}
  .nav__cta{font-weight:300;font-size:30px;letter-spacing:-.03em;margin-top:22px;padding:4px 0;border:0;display:block}   /* same voice as the other links, set apart by space */
  .nav__cta .dot{display:none}

  .work__grid{grid-template-columns:1fr}
  .stage{position:static;order:-1;max-width:560px;margin-inline:auto;width:100%}
  .stage.is-docked{order:0;margin:0;max-width:none;padding:18px 0 26px}
  .stage__frame--9x16{width:min(100%,60vw,300px)}
  /* A stacked list (phones) has no picture: a tap goes straight into the
     case study, and each row says what the client does instead (Aston,
     2026-09-30). So no stage, and no row marked as the one showing. */
  .stage{display:none}
  .work__row{row-gap:0}
  .work__ind{display:block;grid-column:2;grid-row:2;margin-top:7px;font-size:13px;letter-spacing:-.01em;line-height:1.35;opacity:.62;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .work__row.is-on,.work__row.is-on + .work__row{border-top-color:var(--line)}
  .work__row.is-on:last-child{border-bottom-color:var(--line)}
  .work__row.is-on .work__client{transform:none}
  .work__row.is-on .work__arrow{opacity:.35;transform:none}
  .contact__grid{grid-template-columns:1fr}
  .contact__meta{text-align:left}
}
@media (max-width:820px){
  :root{--wall-h:59vw}
  .reel-item__cap{grid-template-columns:auto minmax(0,1fr);gap:8px;padding:10px 8px 0;font-size:11px}
  .reel-item__cap .label:last-child{display:none}
  .hero__copy--bottom{flex-direction:column;align-items:flex-start;gap:18px}
  .reel-item .frame{height:var(--wall-h)}
  .hero.is-open .hero__wall{height:auto}
}
@media (max-width:620px){
  body{font-size:16px}
  .services__grid,.proof__row{grid-template-columns:1fr}
  .svc,.proof__item{border-left:0;padding-left:0;padding-right:0;border-top:var(--hair)}
  .svc:first-child,.proof__item:first-child{border-top:0}
  .proof__item:nth-child(-n+2){border-bottom:0}
  .footer__cols{grid-template-columns:1fr 1fr;gap:28px 16px}          /* Services and Connect side by side */
  .footer__base{grid-template-columns:1fr;gap:18px;padding-block:26px 96px;justify-items:center}   /* the bottom clears the floating menu button */
  .footer__base > *{text-align:center!important}
  .footer__end{flex-direction:column;justify-content:center}   /* the toggle under the places, clear of the menu button */
  .footer__pin .label{display:none}       /* pins alone on phones; the Locations column names them */
  .work__service{display:none}
  .clients__grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .clients__cell{height:64px;padding:10px 0}
  .clients__cell img{height:26px;max-width:82%}
  .clients__cell--more .label{font-size:9px}
}

/* ---------- REDUCED MOTION ---------- */
@media (prefers-reduced-motion:reduce){
  :root{--t-fast:0s;--t-med:0s;--t-slow:0s}
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
  .reveal{opacity:1;transform:none}
  .mark{transform:none!important}
}

/* ---------- a section's head, split ----------
   Where a heading has a line under it, the line moves to the right on a wide
   screen and sits level with the heading's foot, so the head uses the width
   instead of stacking down the left (Aston, 2026-09-28). */
@media (min-width:900px){
  .sec__head:has(> .lede){grid-template-columns:minmax(0,7fr) minmax(0,5fr);column-gap:clamp(48px,6vw,120px);align-items:end}
  .sec__head:has(> .lede) > .label{grid-column:1 / -1;justify-self:start}
  .sec__head:has(> .lede) > .h2{grid-column:1}
  .sec__head:has(> .lede) > .lede{grid-column:2;max-width:46ch}
}

/* ---------- one line per break ----------
   A ruled list that ends its section does not close with a rule of its own:
   the space ends it, and the next section's rule (if it has one) is the only
   line at the join. Two parallel rules with nothing between them looked
   unfinished (Aston, 2026-09-28). The same for a ticker straight above a
   ruled list: its bottom rule is the list's top one. */
.work__row:last-child,.hub__row:last-child,.plan:last-child,.step:last-child,.did__row:last-child,.faq__item:last-child{border-bottom:0}
.rail:has(+ .steps){margin-bottom:0}
.rail + .steps{border-top:0}

/* ---------- a lone figure, split ----------
   One number with nothing beside it left the right of the page empty: it is
   set big on the left, its label on the right at the foot of it. */
.proof__row:has(> .proof__item:only-child){grid-template-columns:minmax(0,1fr)}
@media (min-width:900px){
  .proof__row:has(> .proof__item:only-child) > .proof__item,
  .results__row--1 > .results__item{
    display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);column-gap:clamp(48px,6vw,120px);align-items:end;
  }
  .proof__row:has(> .proof__item:only-child) .proof__n,
  .results__row--1 .results__n{font-size:min(clamp(88px,11vw,190px),58cqw)}
  .proof__row:has(> .proof__item:only-child) .proof__item > .label,
  .results__row--1 .results__item > .label{max-width:26ch;font-size:14px;padding-bottom:.6em}
}

/* ---------- the notch ----------
   The old site's logo notch, back (Aston, 2026-09-28): the Sebenza logo in a
   tab hanging from the top of the screen, like a phone's notch, and a link
   home. The tab is the page's ink: dark on the light theme with the logo
   turned white, light on the dark theme with the logo as it is. The wings
   are the two concave corners that join it to the top edge. */
.notch{
  --notch-bg:var(--ink);--curve:18px;
  position:fixed;top:0;left:50%;z-index:95;transform:translateX(-50%);
  display:flex;align-items:center;justify-content:center;
  padding:calc(env(safe-area-inset-top,0px) + 7px) 20px 10px;
  background:var(--notch-bg);border-radius:0 0 18px 18px;
  box-shadow:0 6px 28px rgba(0,0,0,.26),0 2px 8px rgba(0,0,0,.14);
  transition:box-shadow .2s ease;
}
.notch:hover{box-shadow:0 8px 36px rgba(0,0,0,.34),0 2px 10px rgba(0,0,0,.18)}
.notch:focus-visible{outline:2px solid var(--green);outline-offset:3px}
.notch__wing{position:absolute;top:0;width:var(--curve);height:var(--curve);fill:var(--notch-bg);transform:rotate(180deg);pointer-events:none}
.notch__wing--l{right:100%}
.notch__wing--r{left:100%}
.notch__logo{display:block;height:28px;width:auto;filter:brightness(0) invert(1)}
:root[data-theme="dark"] .notch__logo{filter:none}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .notch__logo{filter:none}}
@media (max-width:640px){.notch{padding:calc(env(safe-area-inset-top,0px) + 6px) 16px 8px}.notch__logo{height:22px}}
/* the spine docked at the top sits below the notch rather than over it */
:root[data-nav-edge="top"] .nav{top:calc(var(--gap) + 52px)}
@media print{.notch{display:none}}

/* ---------- the gold pieces (the service pages, and the paid media case studies) ----------
   The ROI OR DIE coin, the </> and the @: solid gold from the monument's
   studio (docs/gold/pieces.py), floating beside the closing question. The
   still is the object alone on transparency. The page draws the shadow, a
   soft pool beneath it, and floats the piece: the picture drifts up as the
   pool shrinks and pales under it, and settles as the pool spreads. The two
   animations share one clock, so they never part. The live version
   (js/gold3d.js) reads that same clock, and the pool stays under it too. */
.contact--gold .contact__grid{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);align-items:center}
.contact__gold{position:relative;margin:0;justify-self:end;width:min(100%,var(--gold-w));perspective:1100px}
.contact__gold--coin{--gold-w:440px}
.contact__gold--code{--gold-w:540px}
.contact__gold--at{--gold-w:400px}
.contact__gold-float{position:relative;z-index:1;animation:gold-float 5.2s ease-in-out infinite}
.contact__gold img{
  display:block;width:100%;height:auto;
  transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
}
.contact__gold::before{
  content:"";position:absolute;z-index:0;pointer-events:none;
  left:10%;right:10%;top:calc(100% - 5%);height:11%;border-radius:50%;
  background:radial-gradient(ellipse at 50% 50%,rgba(var(--shadow-rgb),.42),rgba(var(--shadow-rgb),.16) 45%,rgba(var(--shadow-rgb),0) 72%);
  animation:gold-shadow 5.2s ease-in-out infinite;
  transform:translate(calc(var(--tilt-y,0) * -1.2px),0) scale(1);
}
@keyframes gold-float{0%,100%{transform:translateY(3%)}50%{transform:translateY(-3%)}}
@keyframes gold-shadow{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(.82);opacity:.66}}
@media (prefers-reduced-motion:reduce){
  .contact__gold-float,.contact__gold::before{animation:none}
}
/* The live piece (js/gold3d.js) draws over the still once its first frame is
   ready, and the still fades out beneath it; the pool stays, since the live
   piece floats on the still's clock. The canvas reaches past the still on
   every side, by BLEED in js/gold3d-scene.js, to hold the float and the turn. */
.contact__gold canvas{
  position:absolute;z-index:2;pointer-events:none;
  left:-12%;top:-16%;width:124%;height:132%;
  opacity:0;transition:opacity .8s ease;
}
.contact__gold img{transition:opacity .8s ease}
.contact__gold.is-3d canvas{opacity:1}
.contact__gold.is-3d img{opacity:0}
@media (max-width:820px){
  .contact--gold .contact__grid{grid-template-columns:1fr}
  .contact__gold{justify-self:start;width:min(82vw,var(--gold-w))}
  .contact__gold--coin{--gold-w:340px}
  .contact__gold--code{--gold-w:400px}
  .contact__gold--at{--gold-w:300px}
}

/* ---------- the free consult: its button and the calendar dialog ----------
   Used by the case studies' consult band and the homepage's close (moved
   here from work.css, 2026-09-30). */
.consult__btn,.explore__btn{
  display:inline-flex;align-items:center;gap:0;margin-top:clamp(26px,3vw,40px);
  padding:16px 26px;border-radius:999px;
  background:var(--ink);color:var(--paper);
  font-size:var(--fs-body);font-weight:500;letter-spacing:-.01em;
  transition:transform var(--t-fast) var(--ease),opacity var(--t-fast) var(--ease);
}
.consult__btn:hover,.consult__btn:focus-visible,.explore__btn:hover,.explore__btn:focus-visible{transform:translateY(-2px)}
.consult__btn:focus-visible,.explore__btn:focus-visible{outline:2px solid var(--ink);outline-offset:4px}
.services__team span{margin-left:.45em}
/* the homepage's way on to the people (Aston, 2026-10-01): /about#team lands
   on the photographs, clear of the nav */
.team__row{scroll-margin-top:calc(var(--nav-h) + 32px)}
/* the calendar, in a dialog over the page (js/consult.js) */
.consult__dialog{
  margin:auto;inset:0;   /* the page's reset takes a dialog's own centring away */
  width:min(760px,calc(100vw - 32px));max-height:calc(100dvh - 32px);
  padding:0;border:var(--hair);border-radius:18px;
  background:var(--paper);color:var(--ink);
  box-shadow:0 30px 80px rgba(var(--shadow-rgb,0,0,0),.35);
  overflow:auto;overscroll-behavior:contain;
}
.consult__dialog::backdrop{background:rgba(10,10,12,.55);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.consult__head{
  position:sticky;top:0;z-index:1;display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:14px 18px;border-bottom:var(--hair);background:var(--paper);
}
.consult__close{
  width:40px;height:40px;border:var(--hair);border-radius:50%;background:none;color:inherit;
  font-size:24px;line-height:1;cursor:pointer;
}
.consult__close:hover,.consult__close:focus-visible{background:rgba(var(--ink-rgb),.06)}
.consult__cal{position:relative;min-height:560px}
.consult__cal iframe{display:block;width:100%;height:672px;background:transparent}
.consult__loading{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:12px;
  font-size:14px;opacity:.7;pointer-events:none;
}
.consult__dialog.is-loaded .consult__loading{display:none}
.consult__spin{width:18px;height:18px;border:2px solid rgba(var(--ink-rgb),.2);border-top-color:var(--ink);border-radius:50%;animation:consult-spin .8s linear infinite}
@keyframes consult-spin{to{transform:rotate(360deg)}}
:root.has-dialog{overflow:hidden}
.consult__title{display:flex;flex-direction:column;gap:4px;min-width:0}
.consult__alt{font-size:13px;line-height:1.4;color:rgba(var(--ink-rgb),.7)}

/* ---------- the word by the cursor, on a mouse ----------
   A small ink pill that follows the pointer and says what can be done: over
   the homepage's phones (js/fleet.js) and over the social page's falling
   tiles (js/drop.js, .drop__tag). */
.cursor-tag,.drop__tag{
  position:fixed;left:0;top:0;z-index:200;pointer-events:none;
  padding:8px 13px;border-radius:999px;
  background:var(--ink);color:var(--paper);
  font-size:13px;font-weight:500;letter-spacing:-.005em;line-height:1;white-space:nowrap;
  box-shadow:0 8px 20px -10px rgba(var(--shadow-rgb),.5);
  opacity:0;scale:.86;transform-origin:0 0;
  transition:opacity .16s var(--ease),scale .2s var(--ease-out);
}
.cursor-tag.is-on,.drop__tag.is-on{opacity:1;scale:1}

/* ---------- the ways in: the call, or a message (Aston, 2026-10-01) ----------
   Where the email address used to close a page: two buttons, the call in
   ink and the message as its outline. Both open one dialog with a switch at
   the top (js/consult.js); /contact has the same two sides in the page. */
.contact__ways{display:flex;flex-wrap:wrap;align-items:center;gap:14px 16px;margin-top:var(--s-block)}
.contact__ways .consult__btn{margin-top:0}
.consult__btn--ghost{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 1px rgba(var(--ink-rgb),.3)}
.consult__btn--ghost:hover,.consult__btn--ghost:focus-visible{box-shadow:inset 0 0 0 1px var(--ink)}

.talk__switch{display:inline-flex;gap:2px;padding:4px;border-radius:999px;background:rgba(var(--ink-rgb),.06)}
.talk__tab{
  appearance:none;border:0;border-radius:999px;padding:10px 18px;background:none;color:inherit;
  font:inherit;font-size:15px;font-weight:500;letter-spacing:-.01em;line-height:1.2;white-space:nowrap;
  cursor:pointer;opacity:.62;transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),opacity var(--t-fast) var(--ease);
}
.talk__tab:hover{opacity:1}
.talk__tab[aria-selected="true"]{background:var(--ink);color:var(--paper);opacity:1}
.talk__tab:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.talk__panel[hidden]{display:none}
.talk .consult__alt{margin:0;padding:12px 18px;border-top:var(--hair)}
.talk__to{appearance:none;border:0;padding:0;background:none;color:inherit;font:inherit;text-decoration:underline;text-underline-offset:.16em;cursor:pointer}
.talk__panel--message{padding:clamp(20px,3vw,32px)}
@media (max-width:480px){
  .talk__tab{padding:9px 13px;font-size:14px}
  .consult__head{padding:12px}
}

/* the message form: the site's hairlines, labels in its label face, and
   the ticks as pills that fill with ink */
.lead{--bad:#C8323A;position:relative;display:grid;gap:22px}
:root[data-theme="dark"] .lead{--bad:#FF7A7A}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .lead{--bad:#FF7A7A}}
.lead__row{display:grid;gap:22px}
@media (min-width:640px){.lead__row{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.lead__field{display:grid;gap:6px;min-width:0}
.lead__need{margin:0;padding:0;border:0;min-width:0}
.lead__label{
  display:block;padding:0;font-size:var(--fs-label);font-weight:500;
  letter-spacing:var(--track-label);text-transform:uppercase;line-height:1.2;opacity:.72;
}
.lead__need .lead__label{margin-bottom:12px}
.lead__opt{margin-left:4px;font-weight:400;letter-spacing:0;text-transform:none;opacity:.7}
.lead input:not([type="checkbox"]),.lead textarea{
  width:100%;padding:10px 0 12px;border:0;border-bottom:var(--hair);border-radius:0;
  background:transparent;color:var(--ink);font:inherit;font-size:18px;line-height:1.4;letter-spacing:-.01em;
  transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease);
}
.lead textarea{min-height:110px;resize:vertical}
.lead input::placeholder,.lead textarea::placeholder{color:rgba(var(--ink-rgb),.38)}
.lead input:not([type="checkbox"]):focus,.lead textarea:focus{outline:none;border-bottom-color:var(--ink);box-shadow:0 1px 0 var(--ink)}
.lead [aria-invalid="true"]{border-bottom-color:var(--bad)!important;box-shadow:0 1px 0 var(--bad)!important}
.lead__err{margin:0;font-size:13px;line-height:1.4;color:var(--bad)}
.lead__err:empty{display:none}
.lead__chips{display:flex;flex-wrap:wrap;gap:8px}
.lead__chip{position:relative;display:inline-flex;cursor:pointer}
.lead__chip input{position:absolute;opacity:0;inset:0;margin:0;cursor:pointer}
.lead__chip span{
  display:inline-block;padding:9px 15px;border-radius:999px;
  box-shadow:inset 0 0 0 1px rgba(var(--ink-rgb),.24);
  font-size:15px;line-height:1.2;letter-spacing:-.01em;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease);
}
.lead__chip:hover span{box-shadow:inset 0 0 0 1px var(--ink)}
.lead__chip input:checked + span{background:var(--ink);color:var(--paper);box-shadow:inset 0 0 0 1px var(--ink)}
.lead__chip input:focus-visible + span{outline:2px solid var(--ink);outline-offset:2px}
.lead__hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;overflow:hidden}
/* the three steps (js/consult.js adds .is-steps; without it the form is one
   page): the count and a bar, the question in the type of a lede, and Back
   and Next at the foot of each */
.lead__steps{display:flex;align-items:center;gap:14px}
.lead:not(.is-steps) .lead__steps,.lead:not(.is-steps) .lead__next,.lead:not(.is-steps) .lead__back{display:none}
.lead__count{font-size:var(--fs-label);font-weight:500;letter-spacing:var(--track-label);text-transform:uppercase;white-space:nowrap;opacity:.62}
.lead__count b{font-weight:500}
.lead__bar{flex:1;height:2px;border-radius:2px;background:rgba(var(--ink-rgb),.12);overflow:hidden}
.lead__bar span{display:block;width:33.34%;height:100%;background:var(--ink);transition:width .35s var(--ease)}
.lead__step{margin:0;padding:0;border:0;min-width:0}
.lead__step > * + *{margin-top:20px}
.lead.is-steps .lead__step:not(.is-on){display:none}
.lead.is-steps .lead__step.is-on{animation:lead-in .32s var(--ease) both}
@keyframes lead-in{from{opacity:0;transform:translateY(6px)}}
@media (prefers-reduced-motion:reduce){.lead.is-steps .lead__step.is-on{animation:none}.lead__bar span{transition:none}}
.lead__q{float:left;width:100%;padding:0;font-size:clamp(24px,2.4vw,32px);font-weight:400;line-height:1.15;letter-spacing:-.03em;text-wrap:balance}
.lead__q + *{clear:both;padding-top:16px;margin-top:0}
.lead__hint{margin:0;font-size:var(--fs-body);opacity:.62}
.lead__hint + .lead__chips{margin-top:14px}
.lead__nav{display:flex;flex-wrap:wrap;align-items:center;gap:12px 22px;margin-top:28px}
.lead__nav .consult__btn{margin-top:0;border:0;cursor:pointer;font-family:inherit}
.lead__back{appearance:none;border:0;padding:12px 2px;background:none;color:inherit;font:inherit;font-size:var(--fs-body);cursor:pointer;opacity:.62;transition:opacity var(--t-fast) var(--ease)}
.lead__back::before{content:"\2190\00a0"}
.lead__back:hover,.lead__back:focus-visible{opacity:1}
.lead__step .lead__status{margin-top:14px}
.lead__next span{margin-left:.45em}
/* short screens (the smallest phones, a laptop with the browser's chrome
   open): the same steps, set tighter, so each still fits without scrolling */
@media (max-height:720px){
  .consult__head{padding:10px 14px}
  .talk__panel--message{padding:18px 20px 20px}
  .lead{gap:14px}
  .lead__q{font-size:22px}
  .lead__q + *{padding-top:10px}
  .lead__step > * + *{margin-top:14px}
  .lead__hint + .lead__chips{margin-top:10px}
  .lead input:not([type="checkbox"]),.lead textarea{padding:7px 0 8px;font-size:17px}
  .lead textarea{min-height:72px}
  .lead__chip span{padding:8px 13px;font-size:14px}
  .lead__nav{margin-top:18px}
  .lead__nav .consult__btn{padding:13px 22px}
}
.lead__check:empty{display:none}
.lead__send{margin-top:0;border:0;cursor:pointer;font-family:inherit}
.lead__send:disabled{opacity:.55;cursor:default;transform:none}
.lead__status{margin:0;font-size:14px;line-height:1.4;opacity:.78}
.lead__status:empty{display:none}
.lead__status.is-bad{color:var(--bad);opacity:1}

/* the thank-you page: the words, and the handshake in gold beside them */
.thanks{
  display:grid;gap:clamp(36px,5vw,80px);align-items:center;
  min-height:min(100svh,980px);
  padding-top:calc(var(--nav-h) + clamp(30px,6vh,80px));padding-bottom:var(--s-block);
}
.thanks__title{font-size:clamp(46px,7.4vw,112px);font-weight:700;letter-spacing:-.045em;line-height:.95;margin-top:22px}
.thanks__say{margin-top:clamp(22px,2.6vw,34px);max-width:26ch;font-size:clamp(24px,2.5vw,38px);font-weight:300;line-height:1.24;letter-spacing:-.03em;text-wrap:pretty}
.thanks__home{display:inline-block;margin-top:clamp(28px,3vw,44px);font-size:var(--fs-body)}
.contact__gold--hand{--gold-w:560px}
.thanks__gold{justify-self:center}
@media (min-width:901px){.thanks{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
@media (max-width:900px){.contact__gold--hand{--gold-w:420px}.thanks__gold{justify-self:start;width:min(86vw,var(--gold-w))}}
