/* ══════════════════════════════════════════════════════════
   BRYAN HENRY — PORTFOLIO
   Vanilla CSS. No build step. Edit tokens below to reskin.
   ══════════════════════════════════════════════════════════ */

:root{
  /* core palette */
  --bg:        #05060A;
  --bg-2:      #0A0C13;
  --panel:     #0E1119;
  --line:      rgba(255,255,255,.09);
  --line-2:    rgba(255,255,255,.16);

  --ink:       #F2F5FA;
  --ink-2:     #99A2B5;
  --ink-3:     #5C6577;

  /* accents */
  --acc:       #4C8DFF;   /* electric blue (pulled from your resume) */
  --acc-2:     #22E0D6;   /* cyan */
  --acc-warm:  #FFAE5C;   /* archive / "the heart" */

  --glow:      0 0 0 1px rgba(76,141,255,.35), 0 0 40px -8px rgba(76,141,255,.45);

  /* type */
  --sans: "Space Grotesk", "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* metrics */
  --pad:  clamp(20px, 5vw, 80px);
  --rad:  14px;
  --ease: cubic-bezier(.22,1,.36,1);
}

*,*::before,*::after{ box-sizing:border-box; }

html{ scroll-behavior:smooth; -webkit-text-size-adjust:100%; }

body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--sans);
  font-size:16px;
  line-height:1.6;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
body.is-locked{ overflow:hidden; }

img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
h1,h2,h3{ margin:0; font-weight:600; letter-spacing:-.03em; line-height:1.02; }
::selection{ background:var(--acc); color:#000; }

/* ═══ BOOT SEQUENCE ═══════════════════════════════════════ */
.boot{
  position:fixed; inset:0; z-index:9999;
  background:var(--bg);
  display:grid; place-items:center;
  transition:opacity .7s var(--ease), visibility .7s;
}
.boot.is-done{ opacity:0; visibility:hidden; }
.boot__inner{ width:min(420px,80vw); font-family:var(--mono); font-size:11px; }
.boot__mark{
  font-family:var(--sans); font-size:64px; font-weight:700; letter-spacing:-.05em;
  color:var(--ink); margin-bottom:24px;
  animation:bootPulse 1.6s var(--ease) infinite;
}
@keyframes bootPulse{ 0%,100%{opacity:1} 50%{opacity:.35} }
.boot__log{ height:76px; color:var(--ink-3); line-height:1.9; overflow:hidden; }
.boot__log b{ color:var(--acc-2); font-weight:400; }
.boot__bar{ height:2px; background:var(--line); margin:16px 0 8px; overflow:hidden; }
.boot__bar span{ display:block; height:100%; width:0; background:var(--acc); transition:width .2s linear; }
.boot__pct{ color:var(--ink-3); text-align:right; }

/* ═══ AMBIENT FX ══════════════════════════════════════════ */
/* circuit traces sit beneath the dot field — both z-index 0, DOM order wins */
.fx-circuit{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  opacity:1;   /* the layer's own alphas do the dimming — see circuit() */
}
.fx-grid{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  opacity:.55;
}
.fx-noise{
  position:fixed; inset:0; z-index:1; pointer-events:none; opacity:.035;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  mix-blend-mode:overlay;
}
.fx-scan{
  position:fixed; inset:0; z-index:1; pointer-events:none; opacity:.5;
  background:repeating-linear-gradient(180deg,transparent 0 3px,rgba(255,255,255,.012) 3px 4px);
}
main{ position:relative; z-index:2; }

/* ═══ CURSOR ══════════════════════════════════════════════ */
.cursor{ position:fixed; top:0; left:0; z-index:9998; pointer-events:none; mix-blend-mode:difference; }
.cursor__dot,.cursor__ring{ position:absolute; border-radius:50%; transform:translate(-50%,-50%); }
.cursor__dot{ width:5px; height:5px; background:#fff; }
.cursor__ring{
  width:34px; height:34px; border:1px solid rgba(255,255,255,.5);
  transition:width .3s var(--ease), height .3s var(--ease), border-color .3s;
}
.cursor.is-hot .cursor__ring{ width:60px; height:60px; border-color:#fff; }
.cursor.is-hot .cursor__dot{ opacity:0; }
@media (hover:none),(max-width:900px){ .cursor{ display:none; } }

/* ═══ SCROLL RAIL ═════════════════════════════════════════ */
.scroll-rail{
  position:fixed; top:0; left:0; right:0; height:2px; z-index:900;
  background:rgba(255,255,255,.05);
}
.scroll-rail span{
  display:block; height:100%; width:0;
  background:linear-gradient(90deg,var(--acc),var(--acc-2));
}

/* ═══ NAV ═════════════════════════════════════════════════ */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:800;
  display:flex; align-items:center; justify-content:space-between;
  padding:18px var(--pad);
  transition:background .4s var(--ease), backdrop-filter .4s, border-color .4s, padding .4s var(--ease);
  border-bottom:1px solid transparent;
}
.nav.is-stuck{
  background:rgba(5,6,10,.72); backdrop-filter:blur(16px) saturate(150%);
  border-bottom-color:var(--line); padding:12px var(--pad);
}
.nav__brand{ display:flex; align-items:center; gap:12px; }
.nav__glyph{
  display:grid; place-items:center; width:32px; height:32px;
  border:1px solid var(--line-2); border-radius:8px;
  font-family:var(--mono); font-size:11px; font-weight:700; letter-spacing:.05em;
  transition:border-color .3s, color .3s, box-shadow .3s;
}
.nav__brand:hover .nav__glyph{ border-color:var(--acc); color:var(--acc); box-shadow:var(--glow); }
.nav__name{ font-size:14px; font-weight:500; letter-spacing:-.01em; }
.nav__links{ display:flex; gap:26px; font-family:var(--mono); font-size:11px; letter-spacing:.06em; text-transform:uppercase; }
.nav__links a{ color:var(--ink-2); display:flex; gap:6px; align-items:baseline; transition:color .25s; }
.nav__links a i{ font-style:normal; color:var(--ink-3); font-size:9px; }
.nav__links a:hover{ color:var(--ink); }
.nav__links a:hover i{ color:var(--acc); }
.nav__toggle{ display:none; background:none; border:0; padding:8px; cursor:pointer; }
.nav__toggle span{ display:block; width:22px; height:1.5px; background:var(--ink); margin:5px 0; transition:transform .3s var(--ease), opacity .3s; }
.nav__toggle[aria-expanded="true"] span:first-child{ transform:translateY(6.5px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:last-child{ transform:translateY(-6.5px) rotate(-45deg); }

.drawer{
  position:fixed; inset:0; z-index:790;
  background:rgba(5,6,10,.97); backdrop-filter:blur(20px);
  display:flex; flex-direction:column; justify-content:center; gap:8px;
  padding:0 var(--pad);
  opacity:0; visibility:hidden; transition:opacity .4s var(--ease), visibility .4s;
}
.drawer.is-open{ opacity:1; visibility:visible; }
.drawer a{ font-size:clamp(32px,9vw,56px); font-weight:600; letter-spacing:-.04em; color:var(--ink-2); transition:color .25s, transform .25s var(--ease); }
.drawer a:hover{ color:var(--acc); transform:translateX(10px); }

@media(max-width:900px){
  .nav__links{ display:none; }
  .nav__toggle{ display:block; }
}

/* ═══ HERO ════════════════════════════════════════════════ */
.hero{ padding:clamp(140px,20vh,220px) var(--pad) clamp(60px,10vh,110px); }
.hero__meta{ display:flex; flex-wrap:wrap; gap:10px; margin-bottom:34px; }
.tag{
  display:inline-flex; align-items:center; gap:7px;
  font-family:var(--mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-2); border:1px solid var(--line); border-radius:100px; padding:6px 13px;
  background:rgba(255,255,255,.02);
}
.tag b{ width:6px; height:6px; border-radius:50%; background:var(--acc-2); box-shadow:0 0 10px var(--acc-2); animation:blip 2s infinite; }
@keyframes blip{ 0%,100%{opacity:1} 50%{opacity:.25} }

.hero__title{ font-size:clamp(44px,9.5vw,148px); font-weight:700; letter-spacing:-.055em; }
.hero__title .line{ display:block; overflow:hidden; padding-bottom:.06em; }
.hero__title em{
  font-style:normal;
  background:linear-gradient(100deg,var(--acc) 0%,var(--acc-2) 55%,var(--acc) 100%);
  background-size:220% 100%;
  -webkit-background-clip:text; background-clip:text; color:transparent;
  animation:sheen 7s linear infinite;
}
@keyframes sheen{ to{ background-position:220% 0; } }
[data-split]{ display:inline-block; }
.char{ display:inline-block; transform:translateY(110%); }
.char.in{ transform:translateY(0); transition:transform .9s var(--ease); }

/* The <em> sheen above is background-clip:text, which does NOT paint through
   descendants that create their own stacking context — and every .char does,
   via its transform. Left per-char, the gradient line renders fully
   transparent. So the highlighted line rises as one block and its chars stay
   untransformed, which lets the clip resolve. */
.hero__title em{ display:inline-block; transform:translateY(110%); }
.hero__title em .char{ transform:none; }
.hero__title em.in{ transform:translateY(0); transition:transform .9s var(--ease); }

.hero__sub{ max-width:56ch; margin:30px 0 0; color:var(--ink-2); font-size:clamp(15px,1.6vw,19px); }
.hero__cta{ display:flex; flex-wrap:wrap; gap:12px; margin-top:34px; }
.btn{
  display:inline-flex; align-items:center; gap:10px;
  font-family:var(--mono); font-size:12px; letter-spacing:.05em;
  padding:14px 24px; border:1px solid var(--line-2); border-radius:100px;
  color:var(--ink); transition:all .3s var(--ease); position:relative; overflow:hidden;
}
.btn:hover{ border-color:var(--acc); color:var(--acc); box-shadow:var(--glow); transform:translateY(-2px); }
.btn--solid{ background:var(--ink); color:var(--bg); border-color:var(--ink); }
.btn--solid:hover{ background:var(--acc); border-color:var(--acc); color:#000; }
.btn span{ transition:transform .3s var(--ease); }
.btn:hover span{ transform:translateY(3px); }

/* A single bright arc orbiting the edge. ::before is an oversized SQUARE
   carrying a conic-gradient — square so the arc travels at an even speed
   rather than lurching at the pill's ends — and it spins. ::after paints the
   background back over the middle, so all that survives is a 1px ring with a
   moving highlight in it. .btn's own overflow:hidden clips it to the pill. */
.btn--beam::before{
  content:""; position:absolute; z-index:0;
  top:50%; left:50%; width:180%; aspect-ratio:1; translate:-50% -50%;
  background:conic-gradient(from 0turn,
    transparent 0 60%, var(--acc-2) 76%, var(--acc) 90%, transparent 98%);
  animation:beam 3.6s linear infinite;
}
.btn--beam::after{
  content:""; position:absolute; z-index:1; inset:1px;
  background:var(--bg); border-radius:inherit;
}
/* the label has to sit above both pseudo-elements */
.btn__label{ position:relative; z-index:2; }
.btn:hover .btn__label{ transform:none; }   /* not the .btn span nudge */
@keyframes beam{ to{ rotate:1turn; } }

.stats{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:1px; margin-top:clamp(50px,9vh,96px);
  background:var(--line); border:1px solid var(--line); border-radius:var(--rad); overflow:hidden;
}
.stat{ background:var(--bg); padding:22px 20px; }
.stat b{ display:block; font-size:clamp(28px,3.6vw,44px); font-weight:700; letter-spacing:-.04em; color:var(--acc); font-variant-numeric:tabular-nums; }
.stat span{ font-family:var(--mono); font-size:10px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3); }

/* ═══ MARQUEE ═════════════════════════════════════════════ */
.marquee{
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  overflow:hidden; padding:15px 0; background:var(--bg-2);
}
.marquee__track{
  display:flex; gap:34px; align-items:center; white-space:nowrap; width:max-content;
  animation:slide 42s linear infinite;
  font-family:var(--mono); font-size:12px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-2);
}
.marquee__track i{ color:var(--acc); font-style:normal; font-size:8px; }
@keyframes slide{ to{ transform:translateX(-50%); } }
.marquee:hover .marquee__track{ animation-play-state:paused; }

/* ═══ SECTIONS ════════════════════════════════════════════ */
.sec{ padding:clamp(80px,13vh,150px) var(--pad); }
.sec--warm{ --acc:var(--acc-warm); background:
  radial-gradient(120% 70% at 50% 0%, rgba(255,174,92,.055), transparent 65%); }
.sec__head{ margin-bottom:clamp(38px,6vh,64px); }
.sec__idx{ display:block; font-family:var(--mono); font-size:11px; letter-spacing:.16em; color:var(--acc); margin-bottom:14px; }
.sec__title{ font-size:clamp(34px,5.6vw,76px); font-weight:700; letter-spacing:-.045em; }
.sec__title em{ font-style:normal; color:var(--ink-3); font-weight:400; }
.sec__note{ max-width:58ch; margin:18px 0 0; color:var(--ink-2); font-size:clamp(14px,1.4vw,17px); }

[data-reveal]{ opacity:0; transform:translateY(26px); }
[data-reveal].in{ opacity:1; transform:none; transition:opacity .9s var(--ease), transform .9s var(--ease); }

/* ═══ WORK GRID ═══════════════════════════════════════════ */
.grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(290px,1fr)); gap:22px; }
.grid--dense{ grid-template-columns:repeat(auto-fill,minmax(225px,1fr)); gap:18px; }
/* Systems used to be a fixed 2-up, which made 4 projects fill the screen
   before you'd scrolled anywhere. Same responsive track as .grid now —
   auto-fill handles narrow viewports without a breakpoint. */
.grid--feature{ grid-template-columns:repeat(auto-fill,minmax(290px,1fr)); gap:22px; }

.card{
  position:relative; border:1px solid var(--line); border-radius:var(--rad);
  background:var(--panel); overflow:hidden; cursor:pointer;
  opacity:0; transform:translateY(30px);
  transition:opacity .8s var(--ease), transform .55s var(--ease), border-color .4s, box-shadow .4s;
  will-change:transform;
}
.card.in{ opacity:1; transform:none; }
.card:hover{ border-color:var(--line-2); box-shadow:0 24px 60px -30px rgba(0,0,0,.9); }
.card.is-feature{ grid-column:span 1; }

/* 3:2 not 4:3 — a shorter card puts a second row in view instead of
   forcing the visitor through the grid one project at a time. */
.card__media{
  position:relative; aspect-ratio:3/2; overflow:hidden; background:var(--bg-2);
}
.card__media img{
  position:absolute; inset:0; z-index:1;
  width:100%; height:100%; object-fit:cover;
  opacity:0;
  transition:transform 1s var(--ease), filter .6s, opacity .6s var(--ease);
  filter:grayscale(.5) contrast(1.03);
}
.card__media img.is-loaded{ opacity:1; }
.card:hover .card__media img{ transform:scale(1.06); filter:none; }
.card__media canvas{ position:absolute; inset:0; width:100%; height:100%; }
.card__scan{
  position:absolute; inset:0; z-index:2; pointer-events:none; opacity:0;
  background:linear-gradient(180deg,transparent 45%,rgba(76,141,255,.14) 50%,transparent 55%);
  transition:opacity .4s;
}
.card:hover .card__scan{ opacity:1; animation:sweep 1.6s linear infinite; }
@keyframes sweep{ from{ transform:translateY(-100%); } to{ transform:translateY(100%); } }

.card__year{
  position:absolute; top:12px; right:12px; z-index:3;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.08em;
  padding:5px 10px; border-radius:100px;
  background:rgba(5,6,10,.75); backdrop-filter:blur(8px);
  border:1px solid var(--line); color:var(--ink-2);
}
/* confidential work — reads as deliberate, not as a missing asset */
.card__lock{
  position:absolute; top:12px; left:12px; z-index:3;
  font-family:var(--mono); font-size:9px; letter-spacing:.12em;
  padding:5px 10px; border-radius:100px;
  background:rgba(5,6,10,.75); backdrop-filter:blur(8px);
  border:1px solid rgba(255,174,92,.35); color:var(--acc-warm);
}
.modal__hint--nda{ border-left-color:var(--acc-warm); color:var(--acc-warm); }

/* The face carries only what you need to decide whether to click.
   Brief and tags live in the modal — see .modal__brief / .modal__tags. */
.card__body{ padding:15px 17px 17px; }
.card__title{ font-size:16.5px; font-weight:600; letter-spacing:-.025em; display:flex; align-items:center; gap:8px; }
.card__title u{ text-decoration:none; color:var(--acc); opacity:0; transform:translate(-6px,6px); transition:all .35s var(--ease); }
.card:hover .card__title u{ opacity:1; transform:none; }
.card__role{ font-family:var(--mono); font-size:10.5px; letter-spacing:.03em; color:var(--ink-3); margin-top:6px; }
.card.is-feature .card__title{ font-size:17.5px; }

/* ═══ ARCHIVE ═════════════════════════════════════════════ */
.archive{ border-top:1px solid var(--line); }
.arc{
  display:grid; grid-template-columns:60px 1.1fr 1.4fr auto; gap:24px; align-items:center;
  padding:24px 8px; border-bottom:1px solid var(--line);
  position:relative; transition:padding .4s var(--ease), background .4s;
  opacity:0; transform:translateY(18px);
  width:100%; text-align:left; background:none; border-left:0; border-right:0;
  border-top:0; color:inherit; font:inherit; cursor:pointer;
}
.arc.in{ opacity:1; transform:none; transition:opacity .7s var(--ease), transform .7s var(--ease), padding .4s var(--ease), background .4s; }
.arc:hover{ padding-left:22px; background:rgba(255,174,92,.04); }
.arc__idx{ font-family:var(--mono); font-size:11px; color:var(--ink-3); }
.arc__title{ font-size:clamp(20px,2.6vw,32px); font-weight:600; letter-spacing:-.035em; transition:color .3s; }
.arc:hover .arc__title{ color:var(--acc-warm); }
.arc__note{ color:var(--ink-2); font-size:14px; }
.arc__go{
  font-family:var(--mono); font-size:11px; color:var(--ink-3);
  display:inline-flex; align-items:center; gap:8px;
  transition:color .3s, transform .3s var(--ease);
}
.arc__go i{
  font-style:normal; font-size:9.5px; letter-spacing:.06em;
  border:1px solid var(--line); border-radius:100px; padding:3px 8px;
}
.arc:hover .arc__go{ color:var(--acc-warm); }
.arc-item.is-open .arc__go{ color:var(--acc-warm); transform:rotate(45deg); }
.arc-item.is-open .arc__title{ color:var(--acc-warm); }
.arc-item.is-open .arc{ background:rgba(255,174,92,.05); }

/* expanding gallery */
.arc-gallery{
  max-height:0; overflow:hidden;
  transition:max-height .7s var(--ease);
  border-bottom:1px solid var(--line);
}
.arc-gallery__grid{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
  gap:10px; padding:20px 8px 24px;
}
.arc-gallery__grid figure{ margin:0; position:relative; overflow:hidden; border-radius:8px; background:var(--bg-2); }
.arc-gallery__grid img{
  width:100%; height:100%; object-fit:cover; aspect-ratio:1/1;
  transition:transform .8s var(--ease), filter .5s;
  filter:grayscale(.35);
}
.arc-gallery__grid figure:hover img{ transform:scale(1.07); filter:none; }
.arc-gallery__grid figcaption{
  position:absolute; left:0; right:0; bottom:0; padding:22px 10px 9px;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.05em; color:#fff;
  background:linear-gradient(transparent, rgba(0,0,0,.85));
  opacity:0; transform:translateY(6px);
  transition:opacity .35s var(--ease), transform .35s var(--ease);
}
.arc-gallery__grid figure:hover figcaption{ opacity:1; transform:none; }
@media(max-width:600px){
  .arc-gallery__grid{ grid-template-columns:repeat(auto-fill,minmax(130px,1fr)); }
}
@media(max-width:820px){
  .arc{ grid-template-columns:40px 1fr auto; }
  .arc__note{ display:none; }
}
.archive__link{ margin-top:30px; font-family:var(--mono); font-size:12px; color:var(--ink-3); }
.archive__link a{ color:var(--acc-warm); border-bottom:1px solid rgba(255,174,92,.3); }

/* ═══ ABOUT ═══════════════════════════════════════════════ */
.about{
  display:grid; grid-template-columns:minmax(180px,1fr) 2.2fr; gap:clamp(24px,5vw,80px);
  padding:clamp(80px,13vh,150px) var(--pad);
  border-top:1px solid var(--line);
}
.about h2{ font-size:clamp(30px,4.4vw,58px); }
.about__body p{ color:var(--ink-2); font-size:clamp(15px,1.5vw,18px); max-width:64ch; margin:0 0 20px; }
.about__body p:first-child{ color:var(--ink); }
/* Capped at 280px on purpose — the source file is 500px wide, so this keeps
   it downscaling (sharp) instead of stretching to fill the column. Same
   grayscale-until-hover treatment the project cards use. */
.about__portrait{
  margin:30px 0 0; max-width:280px; overflow:hidden;
  border:1px solid var(--line); border-radius:var(--rad); background:var(--bg-2);
}
.about__portrait img{
  width:100%; height:auto; display:block;
  filter:grayscale(.4) contrast(1.03);
  transition:filter .6s var(--ease), transform 1s var(--ease);
}
.about__portrait:hover img{ filter:none; transform:scale(1.04); }
.about__cta{ margin:28px 0 0; }
.chips{ display:flex; flex-wrap:wrap; gap:8px; list-style:none; padding:0; margin:30px 0 0; }
.chips li{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.06em;
  padding:7px 13px; border:1px solid var(--line); border-radius:100px; color:var(--ink-2);
  transition:border-color .3s, color .3s, transform .3s var(--ease);
}
.chips li:hover{ border-color:var(--acc); color:var(--acc); transform:translateY(-2px); }
@media(max-width:820px){ .about{ grid-template-columns:1fr; } }

/* ═══ CONTACT ═════════════════════════════════════════════ */
.contact{ padding:clamp(80px,15vh,170px) var(--pad); border-top:1px solid var(--line); }
.contact__big{ font-size:clamp(48px,11vw,150px); font-weight:700; letter-spacing:-.055em; }
.contact__big em{
  font-style:normal;
  background:linear-gradient(100deg,var(--acc),var(--acc-2));
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
.contact__links{ display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:1px; margin-top:clamp(40px,7vh,70px); background:var(--line); border:1px solid var(--line); border-radius:var(--rad); overflow:hidden; }
.contact__links a{ background:var(--bg); padding:22px; display:block; transition:background .35s, color .35s; }
.contact__links a i{ display:block; font-style:normal; font-family:var(--mono); font-size:10px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink-3); margin-bottom:8px; }
.contact__links a:hover{ background:var(--acc); color:#000; }
.contact__links a:hover i{ color:rgba(0,0,0,.6); }

/* ═══ FOOTER ══════════════════════════════════════════════ */
.foot{
  display:flex; flex-wrap:wrap; gap:16px; justify-content:space-between;
  padding:26px var(--pad); border-top:1px solid var(--line);
  font-family:var(--mono); font-size:10.5px; letter-spacing:.06em; color:var(--ink-3);
  position:relative; z-index:2;
}
.foot__status{ display:inline-flex; align-items:center; gap:7px; }
.foot__status b{ width:6px; height:6px; border-radius:50%; background:var(--acc-2); animation:blip 2s infinite; }
/* build stamp — if this shows an older number than the ?v= in index.html,
   the browser is serving a cached main.js */
.foot__status i{ font-style:normal; color:var(--ink-3); opacity:.65; margin-left:4px; }

/* ═══ MODAL ═══════════════════════════════════════════════ */
.modal{ position:fixed; inset:0; z-index:950; opacity:0; visibility:hidden; transition:opacity .45s var(--ease), visibility .45s; }
.modal.is-open{ opacity:1; visibility:visible; }
.modal__scrim{ position:absolute; inset:0; background:rgba(3,4,7,.88); backdrop-filter:blur(10px); }
.modal__panel{
  position:absolute; inset:auto 0 0 0; margin:0 auto; max-width:1000px; height:92vh;
  background:var(--bg-2); border:1px solid var(--line); border-radius:18px 18px 0 0;
  overflow-y:auto; transform:translateY(40px); transition:transform .55s var(--ease);
}
.modal.is-open .modal__panel{ transform:none; }
.modal__x{
  position:sticky; top:16px; float:right; margin:16px 16px 0 0; z-index:5;
  width:40px; height:40px; border-radius:50%; cursor:pointer;
  background:rgba(5,6,10,.8); backdrop-filter:blur(10px);
  border:1px solid var(--line-2); color:var(--ink); font-size:14px;
  transition:border-color .3s, color .3s, transform .3s var(--ease);
}
.modal__x:hover{ border-color:var(--acc); color:var(--acc); transform:rotate(90deg); }
.modal__body{ padding:clamp(28px,5vw,64px); }
.modal__body h3{ font-size:clamp(30px,5vw,60px); letter-spacing:-.045em; margin-bottom:14px; }
.modal__meta{ font-family:var(--mono); font-size:11px; letter-spacing:.05em; color:var(--acc); margin-bottom:6px; }
.modal__role{ font-family:var(--mono); font-size:12px; color:var(--ink-3); margin-bottom:28px; }
.modal__body p{ color:var(--ink-2); font-size:clamp(15px,1.5vw,18px); max-width:68ch; margin:0 0 20px; }
/* the one-line pitch that used to sit on the card face */
.modal__body .modal__brief{
  color:var(--ink); font-size:clamp(16px,1.7vw,20px); line-height:1.5;
  max-width:60ch; margin:0 0 26px; padding-left:16px;
  border-left:2px solid var(--acc);
}
.modal__tags{ display:flex; flex-wrap:wrap; gap:7px; margin:0 0 34px; padding:0; list-style:none; }
.modal__tags li{
  font-family:var(--mono); font-size:10px; letter-spacing:.07em; text-transform:uppercase;
  padding:5px 11px; border:1px solid var(--line); border-radius:100px; color:var(--ink-3);
}
/* Contact sheet, not a stack. Was a single-column grid, so every shot was
   full-bleed and you scrolled them one at a time. Thumbnails let you take the
   whole case study in at a glance and click into whichever one you want. */
.modal__shots{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(210px,1fr));
  gap:12px; margin:34px 0 0;
}
.modal__shots figure{
  margin:0; position:relative; overflow:hidden; border-radius:10px;
  border:1px solid var(--line); background:var(--bg-2); cursor:zoom-in;
}
.modal__shots img{
  width:100%; height:100%; object-fit:cover; aspect-ratio:4/3; display:block;
  transition:transform .8s var(--ease), filter .5s;
  filter:grayscale(.3);
}
.modal__shots figure:hover img{ transform:scale(1.06); filter:none; }
.modal__shots figcaption{
  position:absolute; left:0; right:0; bottom:0; padding:24px 11px 10px;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.05em; color:#fff;
  background:linear-gradient(transparent, rgba(0,0,0,.86));
  opacity:0; transform:translateY(6px);
  transition:opacity .35s var(--ease), transform .35s var(--ease);
}
.modal__shots figure:hover figcaption{ opacity:1; transform:none; }
@media(max-width:600px){
  .modal__shots{ grid-template-columns:repeat(auto-fill,minmax(140px,1fr)); }
}

/* ═══ LIGHTBOX ════════════════════════════════════════════ */
.lb{
  position:fixed; inset:0; z-index:980; display:grid; place-items:center;
  background:rgba(3,4,7,.94); backdrop-filter:blur(14px);
  opacity:0; visibility:hidden; transition:opacity .35s var(--ease), visibility .35s;
}
.lb.is-open{ opacity:1; visibility:visible; }
.lb__stage{ margin:0; max-width:92vw; max-height:88vh; display:flex; flex-direction:column; gap:12px; }
.lb__stage img{
  max-width:92vw; max-height:80vh; width:auto; height:auto;
  object-fit:contain; border-radius:10px; border:1px solid var(--line-2);
  transform:scale(.97); transition:transform .4s var(--ease);
}
.lb.is-open .lb__stage img{ transform:none; }
.lb__stage figcaption{
  font-family:var(--mono); font-size:11px; letter-spacing:.06em;
  color:var(--ink-2); text-align:center;
}
.lb__x,.lb__nav{
  position:absolute; z-index:2; cursor:pointer;
  background:rgba(5,6,10,.8); backdrop-filter:blur(10px);
  border:1px solid var(--line-2); color:var(--ink);
  transition:border-color .3s, color .3s, transform .3s var(--ease);
}
.lb__x{ top:24px; right:24px; width:44px; height:44px; border-radius:50%; font-size:15px; }
.lb__x:hover{ border-color:var(--acc); color:var(--acc); transform:rotate(90deg); }
.lb__nav{
  top:50%; margin-top:-26px; width:52px; height:52px; border-radius:50%;
  font-size:26px; line-height:1; padding:0 0 4px;
}
.lb__nav:hover{ border-color:var(--acc); color:var(--acc); }
.lb__nav--prev{ left:24px; }
.lb__nav--next{ right:24px; }
.lb__count{
  position:absolute; bottom:26px; left:50%; transform:translateX(-50%);
  font-family:var(--mono); font-size:11px; letter-spacing:.1em; color:var(--ink-3);
}
/* Phone: the arrows used to sit at left/right:10px, vertically centred. The
   stage is 92vw, so on a 390px screen they landed on top of the shot and
   covered ~27px of each edge — you were navigating over the thing you came to
   look at. Park them under the image with the counter between them, and give
   the shot back the width they were taking. Unchanged from 601px up, where
   there is real margin either side of the stage. */
@media(max-width:600px){
  .lb__nav{
    width:44px; height:44px; font-size:21px;
    top:auto; bottom:16px; margin-top:0;
  }
  .lb__nav--prev{ left:50%; right:auto; margin-left:-98px; }
  .lb__nav--next{ right:50%; left:auto; margin-right:-98px; }
  .lb__count{ bottom:32px; }
  .lb__x{ top:14px; right:14px; }
  /* Give the stage a DEFINITE width. It is a centred grid item, so it was
     shrink-to-fit, and the image inside was width:auto — that left the used
     width to be derived from intrinsic size and the max-height constraint,
     which iOS Safari resolved far smaller than the space available. A 1200px
     screenshot came out roughly 100px wide. Nothing here may depend on the
     browser guessing: the stage is 98vw and the image fills it. */
  .lb__stage{ width:94vw; max-width:94vw; max-height:none; gap:10px; }
  .lb__stage img{
    width:100%; max-width:100%; height:auto;
    /* dvh keeps the shot clear of the control row when the URL bar
       collapses; the vh line above it is the fallback.
       The 210px reserved here is not only the control row: the stage is
       vertically centred, so every pixel taken off the image height puts
       ~half of it back as clear space at the top — which is what keeps the
       close button off the picture rather than sitting on its corner. */
    max-height:calc(100vh - 210px);
    max-height:calc(100dvh - 210px);
    /* a tall shot is letterboxed inside that box by object-fit; without this
       the border would draw around the empty space instead of the picture */
    object-fit:contain; border:0; border-radius:0;
  }
  .lb__stage figcaption{ padding:0 12px; }
}
.modal__ext{
  display:inline-flex; gap:9px; align-items:center; margin-top:10px;
  font-family:var(--mono); font-size:12px; padding:13px 22px;
  border:1px solid var(--line-2); border-radius:100px; transition:all .3s var(--ease);
}
.modal__ext:hover{ border-color:var(--acc); color:var(--acc); box-shadow:var(--glow); }
.modal__hint{
  font-family:var(--mono); font-size:11px; color:var(--ink-3);
  border-left:2px solid var(--line-2); padding:10px 0 10px 16px; margin:28px 0 0;
}

/* ═══ MOTION PREFERENCES ══════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
  html{ scroll-behavior:auto; }
  [data-reveal],.card,.arc{ opacity:1 !important; transform:none !important; }
  .char,.hero__title em{ transform:none !important; }
  .fx-grid,.fx-scan,.fx-circuit{ display:none; }
  /* the rule above would park the orbiting arc mid-lap as a bright blob on one
     edge — drop it and leave the button its plain border */
  .btn--beam::before,.btn--beam::after{ display:none; }
}
