@font-face { font-family: "Archivo"; src: url(/assets/fonts/archivo.b7d651e8.woff2) format("woff2"); font-weight: 300 900; font-style: normal; font-display: swap; }
@font-face { font-family: "Archivo Fallback"; src: local("Arial"); size-adjust: 119.62%; ascent-override: 87.80%; descent-override: 21.00%; line-gap-override: 0.00%; }
    /* ---- Tokens: one source for the whole site. Swap here, never inline. ---- */
    body {
      /* colour: neutrals only. Brands keep their own; colour is spent on hover/scroll. */
      --ink: #111111; --paper: #f4f4f2; --body: #4a4a48; --muted: #7a7a78; --faint: #a0a09e; --rest: #b3b3b1; --sep: #dcdcda;
      --link: #0a66c2;
      /* type scale */
      /* fluid: the 1440 size as vw, floored for phones, capped at the desktop value */
      --t-mega: clamp(64px, 17.2vw, 232px); --t-h1: clamp(44px, 6.67vw, 96px); --t-h2: clamp(36px, 5.56vw, 80px); --t-h3: clamp(32px, 3.9vw, 56px); --t-h4: clamp(32px, 2.8vw, 40px); --t-h5: 24px;
      --t-lead: clamp(19px, 1.67vw, 24px); --t-body: 17px; --t-small: 15px; --t-meta: 13px;
      /* weights + tracking + leading */
      --w-display: 900; --w-medium: 500; --w-regular: 400; --w-light: 300;
      --track-display: -0.045em; --track-lead: -0.01em; --track-meta: 0.04em;
      --lh-mega: 0.84; --lh-display: 0.9; --lh-tight: 1; --lh-index: 1.06; --lh-lead: 1.4; --lh-body: 1.5;
      /* spacing */
      --sp-2: 10px; --sp-3: 16px; --sp-4: 24px; --sp-5: 32px; --sp-6: 40px; --sp-8: 80px; --sp-9: 96px;
      --gutter: clamp(16px, 1.67vw, 24px); --page-x: clamp(20px, 5vw, 72px); --section: clamp(112px, 16.7vw, 240px); --inset: clamp(12px, 2.23vw, 32px);
      --hero-top: clamp(72px, 8.9vw, 128px); --hero-gap: clamp(40px, 5vw, 72px); --now-gap: clamp(32px, 3.9vw, 56px); --work-gap: clamp(40px, 4.45vw, 64px);
      --foot-top: clamp(80px, 9.73vw, 140px); --foot-x: clamp(20px, 2.8vw, 40px); --foot-bottom: clamp(20px, 2.1vw, 30px);
      /* layout: every grid stays 12 columns; these placements are re-mapped per breakpoint below */
      --c-lead: 4 / span 6; --c-side: 1 / span 2; --c-role: 1 / span 6;
      --c-name: 1 / span 6; --c-title: 7 / span 4; --c-years: 11 / span 2; --years-self: end; --exp-gap: var(--gutter);
      --c-photo: 1 / span 3; --r-photo: auto; --c-ab1: 4 / span 3; --c-ab2: 7 / span 3; --c-ab3: 10 / span 3; --c-personal: 4 / span 7;
      --c-fmail: 1 / span 6; --c-flinks: 7 / span 4; --c-fcopy: 11 / span 2; --fcopy-align: right;
      --stats-cols: repeat(3, minmax(0, 1fr)); --stats-gap: var(--gutter);
      /* motion */
      --ease-out: cubic-bezier(.16,1,.3,1); --d-fast: .18s; --d-base: .35s; --d-slow: .5s; --d-reveal: 1.4s;
    }
    body.dark { --ink: #f4f4f2; --paper: #111111; --body: #c9c9c5; --muted: #8c8c88; --faint: #63635f; --rest: #4a4a47; --sep: #2e2e2c; }
    body, body :where(*:not(.ch, canvas, .sprite, .sprite *)) { transition-property: background-color, color, border-color; transition-duration: var(--d-base); }
    body.notrans, body.notrans * { transition: none !important; }
    /* semantics without style: landmarks, lists, headings and <address> carry the same classes as the old spans/divs */
    .vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
    .faint { color: var(--faint); }
    .glyphs { display: block; }
    ol, ul, dl, dd { margin: 0; padding: 0; list-style: none; } address { font-style: normal; } h1, h2, h3 { font-size: inherit; font-weight: inherit; }
    .sw { background: none; border: 0; padding: 0; margin: 0; font: inherit; cursor: pointer; line-height: 1; }
    .sw .orb { transition: transform var(--d-slow) var(--ease-out); }
    body.dark .sw .orb { transform: rotate(180deg); }
    body { margin: 0; background: var(--paper); color: var(--ink); font-family: "Archivo", "Archivo Fallback", "Helvetica Neue", Arial, sans-serif; -webkit-font-smoothing: antialiased; }
    a { color: var(--ink); text-decoration: none; } a:hover { color: var(--link); }
    /* type styles */
    .disp { font-weight: var(--w-display); letter-spacing: var(--track-display); }
    .t-mega { font-size: var(--t-mega); line-height: var(--lh-mega); text-transform: uppercase; }
    .t-h1 { font-size: var(--t-h1); line-height: var(--lh-display); text-transform: uppercase; }
    .t-h2 { font-size: var(--t-h2); line-height: var(--lh-index); }
    .t-h3 { font-size: var(--t-h3); line-height: var(--lh-display); }
    .t-h4 { font-size: var(--t-h4); line-height: var(--lh-display); }
    .t-h5 { font-size: var(--t-h5); line-height: var(--lh-tight); }
    .lead { font-size: var(--t-lead); line-height: var(--lh-lead); font-weight: var(--w-regular); letter-spacing: var(--track-lead); color: var(--ink); }
    .body { font-size: var(--t-body); line-height: var(--lh-body); font-weight: var(--w-regular); color: var(--body); }
    .small { font-size: var(--t-small); }
    .meta { font-size: var(--t-meta); line-height: var(--lh-body); font-weight: var(--w-medium); letter-spacing: var(--track-meta); text-transform: uppercase; color: var(--muted); }
    .ul { box-shadow: inset 0 -1px 0 currentColor; transition: color var(--d-base); }

    /* Mega title — liquid. Letters materialise out of a ripple on entry, then the
       cursor's speed stirs them: fast passes push the glyphs like water, they
       settle crisp again when the hand stops. */
    .mega { cursor: default; user-select: none; }
    .mega .line { display: block; padding: 0.06em 0.1em 0.06em 0; margin: -0.06em 0; }
    .mega .ch { display: inline-block; }
    .mega ::selection { color: var(--ink); background: rgba(128,128,128,0.25); }
    .mega.js .line { opacity: 0; }
    .mega.js.in.dom .line { animation: appear var(--d-reveal) var(--ease-out) both; }
    .mega.js.in.dom .line:nth-child(2) { animation-delay: .18s; }
    @keyframes appear { from { opacity: 0; } to { opacity: 1; } }
    @media (prefers-reduced-motion: reduce) {
      .mega .line { opacity: 1 !important; animation: none !important; filter: none !important; }
      .mega .ch { transition: none; }
    }

    /* Work: one sentence of wordmarks. Active = ink; others recede; hover = brand colour. */
    .index .proj { color: var(--rest); transition: color var(--d-base); }
    .index .proj.on { color: var(--ink); }
    .index .proj:hover { color: var(--brand); }
    .index .sep { color: var(--sep); font-weight: 300; }
    .index .brand { color: var(--ink); font-weight: 400; transition: color var(--d-base); }
    .index .brand:hover { color: var(--brand); }
    .role { transition: opacity var(--d-base); }
    .goo { filter: url(#goo); }
    .drop { border-radius: 46% 54% 52% 48% / 55% 44% 56% 45%; animation: morph 6s ease-in-out infinite; transform-origin: 50% 50%; }
    .drop-tail { animation-duration: 4.5s; animation-direction: reverse; }
    @keyframes morph {
      0%   { border-radius: 46% 54% 52% 48% / 55% 44% 56% 45%; }
      33%  { border-radius: 56% 44% 40% 60% / 46% 60% 40% 54%; }
      66%  { border-radius: 40% 60% 58% 42% / 60% 40% 56% 44%; }
      100% { border-radius: 46% 54% 52% 48% / 55% 44% 56% 45%; }
    }
    .goo.idle .drop { animation-play-state: paused; }
    @media (prefers-reduced-motion: reduce) { .drop { animation: none; } .goo { filter: none; } }
    .logo-mono { filter: grayscale(1) brightness(0.15); opacity: 0.6; }
    .photo { filter: grayscale(1); position: absolute; top: 0; left: 0; width: auto; height: 100%; aspect-ratio: 1; object-fit: cover; object-position: 50% 50%; }
    .mega .line { white-space: nowrap; }
    .nav-mail-short { display: none; }
    .f-links { flex-wrap: wrap; }

    /* Tablet: same grid, content columns widen; the portrait becomes a square beside the stacked bio beats. */
    @media (max-width: 1023px) {
      body { --c-lead: 4 / span 9; --c-side: 1 / span 3; --c-role: 1 / span 12;
             --c-photo: 1 / span 4; --r-photo: 1 / span 3; --c-ab1: 5 / span 8; --c-ab2: 5 / span 8; --c-ab3: 5 / span 8; --c-personal: 5 / span 8;
             --c-fmail: 1 / span 12; --c-flinks: 1 / span 8; --c-fcopy: 9 / span 4; }
      .photo { position: static; width: 100%; height: auto; }
    }
    /* Phone: one column. Rows stack, stats stack, the email in the nav shortens to a word. */
    @media (max-width: 767px) {
      body { --c-lead: 1 / span 12; --c-side: 1 / span 12; --c-name: 1 / span 12; --c-title: 1 / span 12; --c-years: 1 / span 12; --years-self: start; --exp-gap: 6px;
             --c-photo: 1 / span 12; --r-photo: auto; --c-ab1: 1 / span 12; --c-ab2: 1 / span 12; --c-ab3: 1 / span 12; --c-personal: 1 / span 12;
             --c-flinks: 1 / span 12; --c-fcopy: 1 / span 12; --fcopy-align: left;
             --stats-cols: minmax(0, 1fr); --stats-gap: var(--sp-5); }
      .nav-right { gap: 20px; }
      .nav-mail-full { display: none; } .nav-mail-short { display: inline; }
      .photo { width: 56%; max-width: 260px; }
    }
  
