/* ============================================================
   Andrew Parton — shared theme
   Palette 204 (cool-blue) re-skin of the Doubleslash tokens,
   plus the site's utility classes and cross-document
   View Transitions. Linked from every page after the DS tokens.
   ============================================================ */

/* ---- Theme tokens ----------------------------------------
   Four selectable colour modes, cycled by the header button
   (apw-theme-toggle.js sets data-theme on <html>; the choice is
   saved in localStorage). :root is the default "Light" palette,
   identical to the original site. The three dark modes override
   only the flipping tokens below. Showcase panels that are meant
   to stay dark in every mode (hero, .apw-lamp band, portrait,
   demo cards, footer) keep their literal dark colours.

   Flipping tokens: surfaces, text, borders, header + mobile-nav
   backgrounds, and the accent (brightened on dark so it clears
   WCAG AA over the darker surfaces). Everything else is derived. */
:root {
  /* Surfaces */
  --canvas: #f7f5fb;                    /* page background */
  --surface: #ffffff;                   /* raised cards */
  --surface-tint: #e8edf7;              /* banded-chapter tint */
  --header-bg: rgba(247,245,251,.82);   /* sticky header (over inline) */
  --mnav-bg: rgba(247,245,251,.98);     /* mobile slide-down panel */

  /* Text */
  --ink: #303f5c;                       /* headings / strong foreground */
  --body-ink: #1c2230;                  /* body copy */
  --muted: rgba(28,34,48,.55);          /* roles, dates */
  --muted-soft: rgba(28,34,48,.5);      /* captions */

  /* Accent */
  --accent: #4568bc;                    /* links, labels, focus, hairlines */
  --accent-solid: #4568bc;              /* filled controls (light text on top) */
  --accent-ink: #3a5296;                /* text on the pale accent wash */
  --accent-light: #799ae1;              /* cornflower — light accent */
  --on-light-accent: #101827;           /* dark text on a light accent pill (all modes) */
  --accent-weak: rgba(69,104,188,.09);  /* tag / accordion wash */
  --accent-weak-2: rgba(69,104,188,.16);/* hover / open wash */

  /* Borders */
  --border: rgba(48,63,92,.14);
  --border-strong: rgba(48,63,92,.28);

  /* Legacy aliases (still referenced in places) */
  --electric: var(--accent);
  --magenta: var(--accent-solid);
  --orchid: var(--accent-light);
  --burgundy: #2a3550;
  --footer: #0e1420;                    /* footer stays dark in every mode */
  --white: #ffffff;
  --soft: #b8d1e7;
  --grad-mark: linear-gradient(135deg, #303f5c, #4568bc);
  --grad-mark-tri: linear-gradient(135deg, #303f5c, #4568bc 60%, #799ae1);
}

/* ---- A · Deep Navy — extends the existing dark surface ----- */
:root[data-theme="navy"] {
  --canvas: #0b1018;
  --surface: #131c2e;
  --surface-tint: #0f1727;
  --header-bg: rgba(11,16,24,.82);
  --mnav-bg: rgba(11,16,24,.98);
  --ink: #e8edf7;
  --body-ink: #c5cede;
  --muted: rgba(205,216,236,.62);
  --muted-soft: rgba(205,216,236,.48);
  --accent: #9db8ee;
  --accent-solid: #4568bc;
  --accent-ink: #cdddf8;
  --accent-light: #9db8ee;
  --accent-weak: rgba(120,150,220,.14);
  --accent-weak-2: rgba(120,150,220,.22);
  --border: rgba(160,180,220,.16);
  --border-strong: rgba(160,180,220,.32);
}

body { margin: 0; background: var(--canvas); color: var(--body-ink); font-family: "Libre Franklin", system-ui, sans-serif; }
html { scroll-behavior: smooth; }
/* Lenis takes over scrolling when active — native smooth-scroll fights it
   (causes sluggish, catch-up scrolling), so disable it. Lenis adds .lenis. */
html.lenis { scroll-behavior: auto; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
::selection { background: var(--accent-solid); color: #fff; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

/* ---- Lava-lamp WebGL background (reusable) ----------------
   Calming, slow-drifting "//" marks rendered via WebGL (apw-lamp.js),
   meant for CTA-style dark panels. Apply .apw-lamp to the panel and
   give it a <canvas class="apw-lamp__canvas" aria-hidden="true">
   as a child; the script finds and animates it. If WebGL is
   unavailable the script adds .apw-lamp--fallback, which hides the
   canvas so the panel's own inline background shows through. */
.apw-lamp { position:relative; }
.apw-lamp__canvas { position:absolute; inset:0; width:100%; height:100%; display:block; pointer-events:none; }
.apw-lamp--fallback .apw-lamp__canvas { display:none; }

/* ---- Nav links -------------------------------------------- */
a.apw-nav { position: relative; text-decoration: none; }
a.apw-nav::after { content:""; position:absolute; left:0; right:0; bottom:-6px; height:2px; background:var(--accent); transform:scaleX(0); transform-origin:left; transition:transform .28s cubic-bezier(.2,.7,.2,1); }
a.apw-nav:hover::after, a.apw-nav[aria-current="page"]::after { transform:scaleX(1); }

/* ---- Buttons / links -------------------------------------- */
.apw-cta { display:inline-flex; align-items:center; gap:9px; text-decoration:none; cursor:pointer; border:none;
  font:600 19px/1 "Titillium Web",system-ui,sans-serif; color:#fff; background:var(--accent-solid); padding:16px 30px; border-radius:9px;
  transition:transform .2s ease, box-shadow .2s ease; }
.apw-cta:hover { transform:translateY(-2px); box-shadow:0 12px 26px -12px rgba(69,104,188,.75); }
.apw-cta--sm { font-size:16px; padding:11px 20px; border-radius:8px; }
.apw-cta--ghost { background:transparent; color:var(--ink); border:1.5px solid var(--border-strong); }
.apw-cta--ghost:hover { box-shadow:none; border-color:var(--accent); color:var(--accent); }
.apw-link { font:600 17px "Titillium Web",system-ui,sans-serif; color:var(--accent); text-decoration:none; border-bottom:2px solid rgba(69,104,188,.32); padding-bottom:2px; }

/* ---- Tags / chips / cards --------------------------------- */
.apw-tag { font:600 13px "Titillium Web",system-ui,sans-serif; padding:5px 11px; border-radius:6px; background:var(--accent-weak); color:var(--accent-ink); letter-spacing:.02em; }
.apw-chip { font:600 15px "Titillium Web",system-ui,sans-serif; padding:9px 18px; border-radius:8px; border:1.5px solid var(--border-strong); background:transparent; color:var(--ink); cursor:pointer; transition:border-color .2s ease, color .2s ease, background .2s ease; }
.apw-chip:hover { border-color:var(--accent); color:var(--accent); }
.apw-chip.is-active { background:var(--accent-solid); color:#fff; border-color:var(--accent-solid); }
.apw-proj, .apw-xcard { transition:transform .3s ease, box-shadow .3s ease; }
.apw-proj:hover, .apw-xcard:hover { transform:translateY(-4px); box-shadow:0 22px 50px -26px rgba(48,63,92,.4); }

/* ---- Full-bleed photo hero (index) ------------------------ */
.apw-hero { position:relative; overflow:hidden; background:#0e1420; min-height:88vh; display:flex; align-items:center; }
.apw-hero__media { position:absolute; inset:0; z-index:0; background:#0e1420 center/cover no-repeat; }
/* Scrims: dark on the right (behind copy) + a floor gradient for depth.
   Left stays image-forward so the portrait + screens read. */
.apw-hero__scrim { position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    linear-gradient(100deg, rgba(14,20,32,0) 34%, rgba(14,20,32,.62) 58%, rgba(14,20,32,.90) 82%),
    linear-gradient(0deg, rgba(14,20,32,.55) 0%, rgba(14,20,32,0) 30%); }
.apw-hero__inner { position:relative; z-index:2; width:100%; max-width:1360px; margin:0 auto;
  padding:96px 48px; display:grid; grid-template-columns:1fr; }
.apw-hero__copy { justify-self:end; max-width:47ch; text-align:left; }
/* Liquid Glass panel for the hero copy: a web approximation
   (backdrop-filter + layered translucency + inner highlight/shadow)
   of Apple's Liquid Glass material, floating the copy over the photo.
   Trialled across the whole home page; kept here only — the rest of
   the page reverted to flat cool-blue cards. */
.apw-hero__copy.apw-glass-hero {
  background: linear-gradient(135deg, rgba(20,28,46,.58) 0%, rgba(20,28,46,.30) 100%);
  backdrop-filter: blur(22px) saturate(150%) contrast(1.05);
  -webkit-backdrop-filter: blur(22px) saturate(150%) contrast(1.05);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 22px;
  padding: 40px 44px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.16),
    inset 0 -1px 0 rgba(0,0,0,.25),
    0 30px 70px -34px rgba(0,0,0,.55); }
@media (prefers-reduced-transparency: reduce) {
  .apw-hero__copy.apw-glass-hero {
    background:var(--ink) !important; backdrop-filter:none !important; -webkit-backdrop-filter:none !important; }
}
.apw-hero__mark { position:absolute; z-index:1; right:18px; top:6%; font:900 300px/1 "Heebo",system-ui,sans-serif;
  letter-spacing:-.06em; background:var(--grad-mark-tri); -webkit-background-clip:text; background-clip:text;
  color:transparent; opacity:.14; pointer-events:none; user-select:none; }
.apw-hero__eyebrow { font:500 15px "Libre Franklin",system-ui,sans-serif; text-transform:uppercase;
  letter-spacing:.22em; color:#9db8ee; margin:0 0 22px; }
.apw-hero__title { font:800 clamp(46px,5.4vw,76px)/1.03 "Heebo",system-ui,sans-serif; color:#fff;
  letter-spacing:-.03em; margin:0 0 22px; text-wrap:balance; }
.apw-hero__lead { font:400 20px/1.6 "Libre Franklin",system-ui,sans-serif; color:rgba(255,255,255,.86);
  margin:0 0 30px; }
.apw-hero__foot { font:500 16px/1.6 "Libre Franklin",system-ui,sans-serif; color:rgba(255,255,255,.62);
  margin:26px 0 0; }
.apw-hero .apw-link { color:#9db8ee; border-bottom-color:rgba(157,184,238,.4); }
.apw-hero .apw-link:hover { color:#fff; }

@media (max-width: 900px) {
  .apw-hero { min-height:0; }
  /* Portrait sits at the top, copy drops below over a near-solid floor. */
  .apw-hero__media { background-position:22% top; }
  .apw-hero__scrim {
    background:
      linear-gradient(180deg, rgba(14,20,32,.15) 0%, rgba(14,20,32,.30) 34%, rgba(14,20,32,.92) 60%, #0e1420 100%); }
  .apw-hero__inner { padding:230px 24px 64px; }
  .apw-hero__copy { justify-self:stretch; max-width:none; }
  .apw-hero__copy.apw-glass-hero { padding:28px 26px; border-radius:18px; }
  .apw-hero__mark { font-size:140px; top:2%; right:8px; opacity:.12; }
}

/* ---- Credits timeline ------------------------------------- */
.apw-timeline { position:relative; max-width:1360px; margin:0 auto; padding:20px 0 40px; }
/* Central vertical spine. */
.apw-timeline::before { content:""; position:absolute; left:50%; top:0; bottom:0; width:2px;
  transform:translateX(-50%);
  background:linear-gradient(180deg, transparent 0, rgba(69,104,188,.32) 6%, rgba(69,104,188,.32) 94%, transparent 100%); }

/* Era heading, centred on the spine. */
.apw-tl-era { position:relative; text-align:center; padding:52px 0 40px; }
.apw-tl-era-line { display:block; width:2px; height:0; }
.apw-tl-era-head { position:relative; display:inline-block; background:var(--canvas); padding:0 22px; }
.apw-tl-era-title { font:800 34px/1 'Heebo',system-ui,sans-serif; color:var(--ink); letter-spacing:-.03em; margin:0 0 8px; }
.apw-tl-era-sub { font:500 14px 'Titillium Web',system-ui,sans-serif; letter-spacing:.14em; text-transform:uppercase; color:var(--accent); margin:0; }

/* Each job. Cards alternate sides of the spine on desktop. */
.apw-tl-item { position:relative; width:50%; box-sizing:border-box; padding:14px 48px; }
.apw-tl-item:nth-child(odd)  { left:0; }
.apw-tl-item:nth-child(even) { left:50%; }
/* Dot on the spine. */
.apw-tl-dot { position:absolute; top:34px; width:15px; height:15px; border-radius:50%;
  background:var(--accent-solid); border:3px solid var(--canvas); box-shadow:0 0 0 2px rgba(69,104,188,.35); z-index:2; }
.apw-tl-item:nth-child(odd)  .apw-tl-dot { right:-8px; }
.apw-tl-item:nth-child(even) .apw-tl-dot { left:-8px; }

.apw-tl-card { position:relative; background:var(--surface); border:1px solid var(--border); border-radius:16px;
  padding:24px 26px; box-shadow:0 18px 44px -30px rgba(20,30,55,.5);
  transition:transform .35s cubic-bezier(.34,1.4,.4,1), box-shadow .35s ease, border-color .35s ease; }
.apw-tl-card:hover { transform:translateY(-4px); box-shadow:0 30px 60px -30px rgba(20,30,55,.6); border-color:rgba(69,104,188,.4); }
.apw-tl-dates { font:600 14px 'Titillium Web',system-ui,sans-serif; letter-spacing:.1em; text-transform:uppercase; color:var(--accent); margin:0 0 8px; }
.apw-tl-company { font:700 22px 'Heebo',system-ui,sans-serif; color:var(--ink); letter-spacing:-.02em; margin:0 0 3px; }
.apw-tl-role { font:500 14px 'Libre Franklin',system-ui,sans-serif; color:var(--muted); margin:0 0 12px; }
.apw-tl-desc { font:400 16px/1.62 'Libre Franklin',system-ui,sans-serif; color:var(--body-ink); margin:0 0 14px; }
.apw-tl-tags { display:flex; flex-wrap:wrap; gap:8px; }

/* Pre-animation state when the motion layer is active: items hidden and
   parked off to the left; JS drives them in/out with scroll. */
html.apw-motion .apw-tl-item { opacity:0; }

@media (max-width: 860px) {
  .apw-timeline::before { left:22px; }
  .apw-tl-era { text-align:left; padding:40px 0 28px 0; }
  .apw-tl-era-head { padding:0 14px 0 44px; }
  .apw-tl-era-title { font-size:27px; }
  .apw-tl-item, .apw-tl-item:nth-child(odd), .apw-tl-item:nth-child(even) { width:100%; left:0; padding:12px 0 12px 44px; }
  .apw-tl-item:nth-child(odd) .apw-tl-dot, .apw-tl-item:nth-child(even) .apw-tl-dot { left:15px; right:auto; }
}

/* ---- Biography portrait ----------------------------------- */
.apw-portrait { position:relative; overflow:hidden; border-radius:18px; aspect-ratio:1/1;
  border:1px solid var(--border); background:#0e1420;
  box-shadow:0 24px 60px -34px rgba(20,30,55,.6);
  transition:transform .5s cubic-bezier(.34,1.4,.4,1), box-shadow .5s cubic-bezier(.34,1.4,.4,1); }
.apw-portrait:hover { transform:translateY(-4px); box-shadow:0 34px 74px -34px rgba(20,30,55,.72); }
.apw-portrait__img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  object-position:60% 30%; transition:transform 1.1s cubic-bezier(.2,.7,.2,1); }
.apw-portrait:hover .apw-portrait__img { transform:scale(1.05); }
/* Cool-blue floor so the caption + marks read and it locks to the palette. */
.apw-portrait__scrim { position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(0deg, rgba(11,16,26,.82) 0%, rgba(11,16,26,.28) 34%, rgba(11,16,26,0) 60%),
             linear-gradient(120deg, rgba(69,104,188,.20) 0%, rgba(11,16,26,0) 50%); }
.apw-portrait__mark { position:absolute; right:12px; top:6px; z-index:2;
  font:900 132px/1 'Heebo',system-ui,sans-serif; letter-spacing:-.06em;
  color:#fff; opacity:.12; pointer-events:none; user-select:none; }
.apw-portrait__mono { position:absolute; left:18px; bottom:16px; z-index:2;
  font:900 34px/1 'Heebo',system-ui,sans-serif; letter-spacing:-.04em;
  background:var(--grad-mark-tri); -webkit-background-clip:text; background-clip:text; color:transparent;
  opacity:.95; }
@media (prefers-reduced-motion: reduce) {
  .apw-portrait, .apw-portrait__img { transition:none !important; }
}

/* ---- Biography: intro band + chapter sections ------------- */
/* Intro: portrait beside a short lead-in. */
.apw-bio-intro { display:grid; grid-template-columns:340px 1fr; gap:60px; align-items:start;
  max-width:1180px; margin:0 auto; }

/* Alternating shaded / plain full-bleed bands. One accent-tinted wash,
   used consistently, so the page reads as banded chapters. */
.apw-bio-band { padding:74px 0; }
.apw-bio-band--tint { background:var(--surface-tint); }

/* Each chapter: story text beside its contextual photo. */
.apw-chapter { display:grid; grid-template-columns:1fr 1fr; gap:64px; align-items:center;
  max-width:1180px; margin:0 auto; }
.apw-chapter__meta { font:600 14px/1 'Titillium Web',system-ui,sans-serif; letter-spacing:.14em;
  text-transform:uppercase; color:var(--accent); margin:0 0 14px; }
.apw-chapter__title { font:800 34px/1.12 'Heebo',system-ui,sans-serif; color:var(--ink);
  letter-spacing:-.025em; margin:0 0 18px; text-wrap:balance; }
.apw-chapter__text p { font:400 18px/1.72 'Libre Franklin',system-ui,sans-serif; color:var(--body-ink);
  margin:0 0 16px; max-width:58ch; }
.apw-chapter__text p:last-child { margin-bottom:0; }

.apw-chapter__media { justify-self:center; width:100%; max-width:420px; margin:0; }
.apw-chapter__media--wide { max-width:560px; }
.apw-chapter__media img { display:block; width:100%; height:auto; border-radius:14px;
  border:1px solid var(--border); box-shadow:0 26px 56px -30px rgba(20,30,55,.55); }
.apw-chapter__media figcaption { font:400 13px/1.5 'Libre Franklin',system-ui,sans-serif;
  color:var(--muted-soft); margin-top:11px; }
/* Real-photo chapters: a shorter landscape frame that crops the picture, so
   there is more image than shows, room for the scroll-parallax (apw-motion.js)
   to drift it behind the frame edge. Wraps only the <img>, so the caption
   stays below. Brand logos below the 'I was out' beat keep their natural size. */
.apw-chapter__frame { position:relative; overflow:hidden; border-radius:14px; aspect-ratio:3/2;
  border:1px solid var(--border); box-shadow:0 26px 56px -30px rgba(20,30,55,.55); background:#0e1420; }
.apw-chapter__frame img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  border:0; border-radius:0; box-shadow:none; }

/* Flip: photo on the left, text on the right. */
.apw-chapter--flip .apw-chapter__text  { order:2; }
.apw-chapter--flip .apw-chapter__media { order:1; }

/* Text-only chapters: a single readable measure, centred in the band. */
.apw-chapter--solo { display:block; max-width:760px; }
.apw-chapter--solo .apw-chapter__text p { max-width:none; }

/* Full-bleed emphatic beat between chapters (e.g. "I was out."). */
.apw-bio-beat { max-width:1180px; margin:0 auto; text-align:center; }
.apw-bio-beat p { font:800 clamp(40px,6vw,72px)/1.02 'Heebo',system-ui,sans-serif; color:var(--ink);
  letter-spacing:-.035em; margin:0; }
.apw-bio-beat span { background:var(--grad-mark); -webkit-background-clip:text; background-clip:text;
  color:transparent; }

@media (max-width:860px){
  .apw-bio-intro { grid-template-columns:1fr; gap:30px; }
  .apw-bio-band { padding:52px 0; }
  .apw-chapter, .apw-chapter--flip { grid-template-columns:1fr; gap:26px; }
  /* Always photo above its text on narrow screens. */
  .apw-chapter__media, .apw-chapter--flip .apw-chapter__media { order:1; }
  .apw-chapter__text,  .apw-chapter--flip .apw-chapter__text  { order:2; }
  .apw-chapter__media { max-width:420px; justify-self:start; }
}

/* ---- Demo cards + expand-to-play game frame --------------- */
.apw-demo { position:relative; display:block; border-radius:16px; overflow:hidden;
  border:1px solid var(--border); background:#0e1420; text-decoration:none; aspect-ratio:16/10;
  box-shadow:0 10px 30px -20px rgba(20,30,55,.5);
  /* Spring: overshoot cubic-bezier gives a bouncy lift on hover in/out. */
  transition:transform .5s cubic-bezier(.34,1.56,.4,1), box-shadow .5s cubic-bezier(.34,1.56,.4,1);
  will-change:transform; }
.apw-demo:hover, .apw-demo:focus-visible {
  transform:translateY(-12px) scale(1.035);
  box-shadow:0 40px 80px -32px rgba(20,30,55,.72), 0 12px 28px -18px rgba(20,30,55,.5);
  z-index:3; }
.apw-demo__img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  transition:transform .6s cubic-bezier(.2,.7,.2,1); }
.apw-demo:hover .apw-demo__img { transform:scale(1.07); }
/* Stronger scrim: near-solid where the text sits, fading up the card, so
   copy stays readable over busy game art. Two layers: a tall bottom
   gradient plus a slight overall darken. */
.apw-demo__scrim { position:absolute; inset:0;
  background:
    linear-gradient(0deg, rgba(11,16,26,.97) 0%, rgba(11,16,26,.9) 24%, rgba(11,16,26,.6) 50%, rgba(11,16,26,.12) 78%, rgba(11,16,26,0) 100%),
    linear-gradient(0deg, rgba(11,16,26,.22), rgba(11,16,26,.22)); }
.apw-demo__tag { position:absolute; right:14px; top:14px; z-index:2;
  font:600 12px 'Titillium Web',system-ui,sans-serif; letter-spacing:.14em; text-transform:uppercase;
  color:#e6edfb; background:rgba(11,16,26,.66); padding:5px 10px; border-radius:6px;
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
.apw-demo__body { position:absolute; left:0; right:0; bottom:0; z-index:2; padding:22px 24px 24px; }
.apw-demo__title { font:700 24px 'Heebo',system-ui,sans-serif; color:#fff; letter-spacing:-.02em; margin:0 0 6px;
  text-shadow:0 1px 12px rgba(0,0,0,.55), 0 1px 2px rgba(0,0,0,.6); }
.apw-demo__desc { font:400 15px/1.55 'Libre Franklin',system-ui,sans-serif; color:rgba(255,255,255,.92); margin:0 0 16px; max-width:44ch;
  text-shadow:0 1px 8px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.55); }
.apw-play { display:inline-flex; align-items:center; gap:9px; cursor:pointer;
  font:600 16px/1 'Titillium Web',system-ui,sans-serif; color:#0e1420; background:#fff;
  border:none; padding:12px 22px; border-radius:9px; text-decoration:none;
  transition:transform .2s ease, box-shadow .2s ease, background .2s ease; }
.apw-play::after { content:"\25B6"; font-size:11px; }
.apw-play:hover { transform:translateY(-2px); background:var(--orchid); color:#0e1420;
  box-shadow:0 12px 26px -12px rgba(0,0,0,.6); }
.apw-play--soon { background:rgba(255,255,255,.14); color:rgba(255,255,255,.72); cursor:default; }
.apw-play--soon::after { content:none; }
.apw-play--soon:hover { transform:none; background:rgba(255,255,255,.14); color:rgba(255,255,255,.72); box-shadow:none; }

/* Whole card is the play target: stretch the link over the card and drop the
   pill styling, so a click anywhere on the card launches the game. */
.apw-play--cover { position:absolute; inset:0; z-index:4; display:block;
  padding:0; background:none; font-size:0; color:transparent; box-shadow:none; }
.apw-play--cover::after { content:none; }
.apw-play--cover:hover { transform:none; background:none; box-shadow:none; }
.apw-play--cover:focus-visible { outline:2px solid var(--orchid); outline-offset:-4px; }

/* Overlay + expanding frame */
.apw-gf-overlay { position:fixed; inset:0; z-index:2000; background:rgba(8,12,20,0);
  transition:background .45s ease; }
.apw-gf-overlay.is-in { background:rgba(8,12,20,.78); }
.apw-gf-frame { position:fixed; z-index:2001; overflow:hidden; background:#0e1420;
  box-shadow:0 40px 120px -30px rgba(0,0,0,.7); will-change:top,left,width,height; }
.apw-gf-iframe { position:absolute; inset:0; width:100%; height:100%; border:0; display:block;
  background:#0e1420; }
.apw-gf-frame.is-loading .apw-gf-iframe { opacity:0; }
.apw-gf-iframe { transition:opacity .3s ease .1s; }
.apw-gf-spinner { position:absolute; left:50%; top:50%; width:44px; height:44px; margin:-22px 0 0 -22px;
  border:3px solid rgba(255,255,255,.18); border-top-color:#799ae1; border-radius:50%;
  animation:apw-gf-spin .8s linear infinite; z-index:1; }
.apw-gf-frame:not(.is-loading) .apw-gf-spinner { display:none; }
@keyframes apw-gf-spin { to { transform:rotate(360deg); } }
.apw-gf-close { position:absolute; left:50%; bottom:20px; transform:translateX(-50%); z-index:3;
  font:600 15px/1 'Titillium Web',system-ui,sans-serif; color:#fff; cursor:pointer;
  background:rgba(14,20,32,.72); border:1px solid rgba(255,255,255,.22); padding:11px 26px;
  border-radius:999px; backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  opacity:0; transition:opacity .3s ease, transform .2s ease, background .2s ease; }
.apw-gf-frame.is-open .apw-gf-close { opacity:1; }
.apw-gf-close:hover { background:rgba(69,104,188,.9); transform:translateX(-50%) translateY(-2px); }

@media (prefers-reduced-motion: reduce) {
  .apw-gf-overlay, .apw-gf-frame, .apw-gf-close, .apw-demo__img { transition:none !important; }
  .apw-gf-spinner { animation:none; }
}

/* ---- Reveal on scroll ------------------------------------- */
.apw-reveal { opacity:0; transform:translateY(26px); }
.apw-reveal.is-in { opacity:1; transform:none; transition:opacity .8s cubic-bezier(.2,.7,.2,1), transform .8s cubic-bezier(.2,.7,.2,1); }

/* ---- GSAP motion layer (apw-motion.js) -------------------- */
/* When the motion script is active it hides these until it takes
   control, preventing a flash of visible-then-hidden content.
   Header is never hidden. Under prefers-reduced-motion the class is
   never added, so nothing here applies. */
/* First section = hero: its text children are staggered in, so hide
   those specifically. On the photo hero the copy is nested in
   .apw-hero__copy (media/scrim/mark layers must stay visible). */
html.apw-motion main > section:first-of-type:not(.apw-hero) > :is(h1, h2, p, div),
html.apw-motion .apw-hero__copy > :is(h1, h2, p, div) { opacity:0; }
/* Every later section reveals as a whole block. */
html.apw-motion main > section:not(:first-of-type),
html.apw-motion .apw-proj,
html.apw-motion .apw-xcard,
html.apw-motion .apw-demo,
html.apw-motion article.apw-job,
html.apw-motion main figure { opacity:0; }
html.apw-motion .apw-header,
html.apw-motion .apw-header * { opacity:1; }

/* ---- Career accordion (concertina, built by apw-accordion.js) ----
   The article keeps its .apw-job class, so the reveal rule above would
   hide the header; force accordion items (and open-panel figures) visible
   with !important, and let the open/close animation be the motion. */
.apw-acc { opacity:1 !important; transform:none !important;
  border-top:1px solid var(--border); scroll-margin-top:78px;
  /* Keep browser scroll-anchoring from nudging the view as a panel expands —
     the accordion's own close→scroll→open choreography owns the scroll. */
  overflow-anchor:none; }
.apw-acc:last-of-type { border-bottom:1px solid var(--border); }

.apw-acc__head {
  width:100%; display:flex; align-items:center; gap:28px;
  padding:26px 12px; background:var(--accent-weak); border:0; cursor:pointer;
  text-align:left; color:var(--ink); font-family:inherit;
  border-radius:12px; transition:background .25s ease;
  scroll-margin-top:74px; /* clear the sticky nav when scrolled to */
  -webkit-tap-highlight-color:transparent;
}
.apw-acc__head:hover { background:var(--accent-weak-2); }
.apw-acc.is-open .apw-acc__head { background:var(--accent-weak-2); }
.apw-acc__head:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }

.apw-acc__lead { display:flex; flex-direction:column; gap:5px; flex:1 1 auto; min-width:0; }
.apw-acc__co { font:700 24px 'Heebo',system-ui,sans-serif; letter-spacing:-.02em;
  color:var(--ink); transition:color .25s ease; }
.apw-acc__role { font:600 13px 'Titillium Web',system-ui,sans-serif;
  text-transform:uppercase; letter-spacing:.1em; color:var(--accent); }

.apw-acc__aside { display:flex; flex-direction:column; align-items:flex-end; gap:9px; flex:0 0 auto; }
.apw-acc__dates { font:500 14px 'Libre Franklin',system-ui,sans-serif;
  color:var(--muted-soft); white-space:nowrap; }
.apw-acc__tags { display:flex; flex-wrap:wrap; gap:7px; justify-content:flex-end; margin:0; }

.apw-acc__chev { flex:0 0 auto; display:flex; color:rgba(28,34,48,.38);
  transition:transform .42s cubic-bezier(.34,1.3,.5,1), color .25s ease; }

/* Open state: company + chevron pick up the accent, chevron flips up. */
.apw-acc.is-open .apw-acc__co { color:var(--accent); }
.apw-acc.is-open .apw-acc__chev { transform:rotate(180deg); color:var(--accent); }

/* Panel: animate to the content's natural height (grid-template-rows trick). */
.apw-acc__panel { display:grid; grid-template-rows:0fr;
  transition:grid-template-rows .5s cubic-bezier(.4,0,.2,1); }
/* Suppress the animation when a section is force-closed during a switch, so
   the layout settles instantly before the scroll target is measured. */
.apw-acc--noanim .apw-acc__panel, .apw-acc--noanim .apw-acc__body { transition:none !important; }
.apw-acc.is-open .apw-acc__panel { grid-template-rows:1fr; }
.apw-acc__inner { overflow:hidden; min-height:0; }
.apw-acc__body { max-width:none; padding:6px 12px 44px;
  opacity:0; transition:opacity .4s ease .06s; }
.apw-acc.is-open .apw-acc__body { opacity:1; }
/* Figures inside an open panel: beat the reveal's opacity:0 hold. */
.apw-acc.is-open .apw-acc__body figure { opacity:1 !important; transform:none !important; }

@media (max-width: 860px) {
  .apw-acc__head { flex-wrap:wrap; gap:10px 16px; padding:20px 34px 20px 6px; position:relative; }
  .apw-acc__lead { flex-basis:100%; }
  .apw-acc__co { font-size:21px; }
  .apw-acc__aside { flex-basis:100%; align-items:flex-start; gap:8px; }
  .apw-acc__tags { justify-content:flex-start; }
  .apw-acc__chev { position:absolute; top:18px; right:4px; }
  .apw-acc__body { padding:4px 6px 32px; }
}

@media (prefers-reduced-motion: reduce) {
  .apw-acc__panel, .apw-acc__body, .apw-acc__chev, .apw-acc__head, .apw-acc__co { transition:none !important; }
}

/* ---- Page entrance (replaces cross-document View Transitions) ---
   Cross-document view transitions were unreliable here: the pages ship
   nearly empty and the DC runtime renders content into #dc-root>.sc-host
   asynchronously (React commit after DOMContentLoaded), so the browser
   frequently snapshotted the new page before its content existed and the
   transition was skipped. Instead, animate .sc-host itself: the browser
   starts this animation the moment the element is inserted, which is
   exactly when the page's content commits, on every navigation, with no
   snapshot-timing race. Opacity only, so the sticky header, transforms
   and per-section scroll reveals are left untouched. */
@media (prefers-reduced-motion: no-preference) {
  #dc-root > .sc-host { animation: apw-page-in .5s cubic-bezier(.2,.7,.2,1) both; }
}
@keyframes apw-page-in { from { opacity: 0; } to { opacity: 1; } }

/* ---- Mobile nav (hamburger, injected by apw-nav.js) ------- */
/* Hidden on desktop; the .apw-nav-wrap links show instead. */
.apw-menu-btn, .apw-mobile-nav { display:none; }

@media (max-width: 860px) {
  .apw-menu-btn {
    display:inline-flex; flex-direction:column; justify-content:center; gap:5px;
    width:44px; height:44px; padding:10px; margin:-6px -8px -6px 0;
    background:transparent; border:0; cursor:pointer; border-radius:10px;
  }
  .apw-menu-btn span {
    display:block; width:100%; height:2px; border-radius:2px; background:var(--ink);
    transition:transform .28s cubic-bezier(.2,.7,.2,1), opacity .18s ease;
  }
  .apw-menu-open .apw-menu-btn span:nth-child(1) { transform:translateY(7px) rotate(45deg); }
  /* !important: beats html.apw-motion .apw-header * { opacity:1 } (the reveal
     rule), which is more specific and would otherwise stop the bar hiding. */
  .apw-menu-open .apw-menu-btn span:nth-child(2) { opacity:0 !important; }
  .apw-menu-open .apw-menu-btn span:nth-child(3) { transform:translateY(-7px) rotate(-45deg); }

  .apw-mobile-nav {
    display:flex; flex-direction:column;
    position:absolute; left:0; right:0; top:100%;
    background:var(--mnav-bg);
    -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
    border-bottom:1px solid var(--border);
    box-shadow:0 22px 44px -26px rgba(20,30,55,.55);
    padding:6px 24px 14px;
    /* !important on visibility: the panel lives inside .apw-header, so the
       reveal rule html.apw-motion .apw-header * { opacity:1 } (specificity
       0,2,1) outranks this and would pin it permanently visible — i.e. the
       menu looking "always open". These win regardless. */
    transform:translateY(-8px); opacity:0 !important; pointer-events:none !important;
    transition:opacity .22s ease, transform .22s cubic-bezier(.2,.7,.2,1);
  }
  .apw-menu-open .apw-mobile-nav { transform:translateY(0); opacity:1 !important; pointer-events:auto !important; }
  .apw-mnav-link {
    font:600 18px 'Titillium Web',system-ui,sans-serif; color:var(--ink);
    text-decoration:none; padding:14px 6px; border-top:1px solid rgba(28,34,48,.09);
  }
  .apw-mnav-link:first-child { border-top:0; }
  .apw-mnav-link.is-current { color:var(--accent); }
}

/* ---- Responsive ------------------------------------------- */
@media (max-width: 1080px) { .apw-proj-grid, .apw-demos-grid { grid-template-columns:1fr 1fr !important; } }
@media (max-width: 860px) {
  .apw-nav-wrap { display:none !important; }
  .apw-hero-title { font-size: clamp(40px, 10vw, 78px) !important; }
  .apw-page-title { font-size: clamp(38px, 9vw, 66px) !important; }
  .apw-bio-grid { grid-template-columns: 1fr !important; }
  .apw-job { grid-template-columns: 1fr !important; gap:14px !important; }
  .apw-contact-grid { grid-template-columns: 1fr !important; }
  .apw-proj-grid { grid-template-columns:1fr !important; }
  .apw-analysis-grid { grid-template-columns:1fr !important; }
  .apw-demos-grid { grid-template-columns:1fr !important; }
  .apw-xcard-grid { grid-template-columns:1fr 1fr !important; }
  .apw-pad { padding-left:24px !important; padding-right:24px !important; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior:auto; }
  .apw-reveal { opacity:1; transform:none; transition:none; }
}

/* ---- Theme plumbing --------------------------------------- */
/* These surfaces are set with inline styles on every page, so the
   token swap needs !important to reach them. On Light they resolve
   to the original colours, so the default look is unchanged. */
.apw-header { background:var(--header-bg) !important; }
.apw-proj, .apw-xcard { background:var(--surface) !important; }

/* Panels that use inline background:var(--ink) as a dark surface
   (the .apw-lamp page-title bands and the Contact "needs building"
   card) must stay dark in Navy — --ink flips to a light text tone
   there, which would leave white text on a light panel. Light mode
   is untouched, keeping its original slate panels. */
:root[data-theme="navy"] .apw-lamp,
:root[data-theme="navy"] [style*="background:var(--ink)"],
:root[data-theme="navy"] [style*="background: var(--ink)"] { background:#0e1420 !important; }

/* ---- Header theme toggle (injected by apw-theme-toggle.js) -
   Icon-only button: a moon in Light (switch to dark), a sun in Navy. */
.apw-theme-btn { display:inline-flex; align-items:center; justify-content:center;
  width:40px; height:40px; padding:0;
  background:transparent; border:1.5px solid var(--border-strong); border-radius:10px;
  color:var(--ink); cursor:pointer;
  transition:border-color .2s ease, color .2s ease; -webkit-tap-highlight-color:transparent; }
.apw-theme-btn:hover { border-color:var(--accent); color:var(--accent); }
.apw-theme-btn:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.apw-theme-btn svg { display:block; width:19px; height:19px; pointer-events:none; }

/* Desktop: the button rides at the end of the primary nav. */
.apw-nav-wrap .apw-theme-btn { margin-left:2px; }

/* Mobile: a left-aligned row at the foot of the slide-down panel. */
.apw-mobile-nav .apw-theme-btn { justify-content:flex-start; width:auto; height:auto;
  padding:14px 6px; border:0; border-top:1px solid var(--border); border-radius:0;
  color:var(--ink); }
.apw-mobile-nav .apw-theme-btn:hover { color:var(--accent); }
