/* goujan.dev — deep field.
   Bricolage Grotesque, Space Grotesk and Instrument Serif are self-hosted and
   licensed under the SIL OFL; the licences sit beside them in assets/fonts/. */

@font-face{font-family:'Bricolage Grotesque';src:url('assets/fonts/BricolageGrotesque-Variable.woff2') format('woff2');font-weight:200 800;font-stretch:75% 100%;font-style:normal;font-display:swap}
@font-face{font-family:'Space Grotesk';src:url('assets/fonts/SpaceGrotesk-Variable.woff2') format('woff2');font-weight:300 700;font-style:normal;font-display:swap}
@font-face{font-family:'Instrument Serif';src:url('assets/fonts/InstrumentSerif-Italic.woff2') format('woff2');font-weight:400;font-style:italic;font-display:swap}

/* ------------------------------------------------------------------ tokens */
:root{
  color-scheme:dark;

  --void:#05060a;
  --void-2:#0a0c13;
  --bone:#eceae4;
  --dim:#8d92a0;
  --faint:#5b6070;
  --line:#ffffff16;
  --line-strong:#ffffff2e;

  --lime:#c9f74f;
  --cyan:#59e2e8;
  --violet:#9c7dff;
  /* Travels lime -> cyan -> violet as the page is scrolled. site.js writes it. */
  --accent:#c9f74f;
  --accent-rgb:201 247 79;

  --display:'Bricolage Grotesque','Arial Narrow',system-ui,sans-serif;
  --sans:'Space Grotesk',ui-sans-serif,system-ui,'Segoe UI',sans-serif;
  --serif:'Instrument Serif',Georgia,'Times New Roman',serif;
  --mono:ui-monospace,'SF Mono',Consolas,'Courier New',monospace;

  --gutter:clamp(20px,5vw,76px);
  --shell:1560px;
  --band:clamp(84px,11vw,170px);

  --progress:0;
  --px:0;  /* pointer, -1..1 */
  --py:0;

  --ease:cubic-bezier(.22,.61,.24,1);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
html:not(.lenis) {scroll-behavior:smooth}
body{
  margin:0;
  background:var(--void);
  color:var(--bone);
  font:400 16px/1.6 var(--sans);
  font-synthesis-weight:none;
  overflow-x:clip;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,p,dl,dd,figure,ul{margin:0}
ul{padding:0;list-style:none}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
[hidden]{display:none!important}
::selection{background:var(--accent);color:var(--void)}
:focus-visible{outline:2px solid var(--accent);outline-offset:6px;border-radius:2px}

.shell{width:100%;max-width:var(--shell);margin-inline:auto;padding-inline:var(--gutter)}
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip-link{position:fixed;z-index:120;top:14px;left:14px;padding:11px 20px;background:var(--bone);color:var(--void);font:500 13px var(--sans);border-radius:99px;transform:translateY(-220%)}
.skip-link:focus{transform:none}

.tag{font:400 11px/1.5 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.dot{display:inline-block;width:5px;height:5px;margin-right:9px;border-radius:50%;background:var(--accent);vertical-align:middle;box-shadow:0 0 12px rgb(var(--accent-rgb)/.85)}

.link{position:relative;display:inline-block;color:var(--bone)}
.link::after{content:'';position:absolute;left:0;right:0;bottom:-3px;height:1px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .5s var(--ease)}
.link:hover::after,.link:focus-visible::after{transform:scaleX(1);transform-origin:left}

/* --------------------------------------------------------------- backdrop */
/* Three fixed decorative layers: a real deep-field photograph, an original
   WebGL nebula drawn over it, and film grain. All of it is aria-hidden and
   none of the page depends on it. */
.backdrop{position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden}
.backdrop__field{
  position:absolute;inset:-6%;
  background:url('assets/space-deepfield.jpg') center/cover no-repeat;
  opacity:.34;
  filter:saturate(.6) contrast(1.12);
  transform:translate3d(calc(var(--px) * -14px),calc(var(--py) * -14px),0) scale(1.06);
  transition:transform .8s var(--ease);
}
.backdrop::after{
  content:'';position:absolute;inset:0;
  background:
    radial-gradient(120% 78% at 50% 0%,#05060a00 12%,#05060ac2 68%,#05060a 100%),
    linear-gradient(180deg,#05060a99 0%,#05060a33 24%,#05060abb 100%);
}
.backdrop__gl{position:absolute;inset:0;width:100%;height:100%;display:block;mix-blend-mode:screen;opacity:0;transition:opacity 1.2s ease}
.backdrop__gl.is-live{opacity:.95}
.backdrop__grain{
  position:absolute;inset:-200px;opacity:.05;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='220' height='220' filter='url(%23n)'/></svg>");
  animation:grain 6s steps(6) infinite;
}
@keyframes grain{
  0%{transform:translate(0,0)}      20%{transform:translate(-12px,7px)}
  40%{transform:translate(9px,-11px)} 60%{transform:translate(-7px,-6px)}
  80%{transform:translate(11px,9px)}  100%{transform:translate(0,0)}
}

/* If WebGL never starts, a static CSS aurora keeps the page from going flat. */
.backdrop__gl:not(.is-live) + .backdrop__grain::before{
  content:'';position:absolute;inset:200px;
  background:
    radial-gradient(62% 48% at 74% 22%,rgb(var(--accent-rgb)/.10) 0%,transparent 66%),
    radial-gradient(52% 44% at 18% 70%,#9c7dff1f 0%,transparent 70%);
}

/* ---------------------------------------------------------------- chrome */
.progress{position:fixed;z-index:60;inset:0 0 auto 0;height:2px;background:#ffffff0d;pointer-events:none}
.progress>i{display:block;height:100%;background:var(--accent);transform:scaleX(var(--progress));transform-origin:left;box-shadow:0 0 16px rgb(var(--accent-rgb)/.6)}

.cursor{position:fixed;z-index:110;top:0;left:0;pointer-events:none;mix-blend-mode:difference}
.cursor__dot,.cursor__ring{position:absolute;top:0;left:0;border-radius:50%;translate:-50% -50%}
.cursor__dot{width:6px;height:6px;background:#fff}
.cursor__ring{width:38px;height:38px;border:1px solid #ffffff99;transition:width .35s var(--ease),height .35s var(--ease),border-color .35s}
.cursor.is-active .cursor__ring{width:70px;height:70px;border-color:#fff}
body.has-cursor{cursor:none}
body.has-cursor a,body.has-cursor button{cursor:none}

.masthead{
  position:fixed;z-index:70;inset:0 0 auto 0;
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  height:76px;padding-inline:var(--gutter);
  transition:background .4s ease,backdrop-filter .4s ease,border-color .4s ease;
  border-bottom:1px solid transparent;
}
.masthead.is-stuck{background:#05060abb;backdrop-filter:blur(14px) saturate(1.2);border-bottom-color:var(--line)}
.wordmark{display:inline-flex;align-items:center;gap:11px;font:500 15px var(--sans);letter-spacing:-.02em}
.wordmark b{font-weight:500;color:var(--dim)}
.wordmark__mark{width:22px;height:22px;fill:none;stroke:var(--accent);stroke-width:2.6}
.wordmark__pupil{fill:var(--accent);stroke:none}
.wordmark:hover .wordmark__mark{animation:pulse 1.6s ease-in-out infinite}
@keyframes pulse{50%{opacity:.45}}

.masthead__nav{display:flex;gap:6px}
.masthead__nav a{position:relative;display:inline-flex;align-items:center;height:44px;padding-inline:15px;font-size:14px;color:var(--dim);border-radius:99px;transition:color .3s}
.masthead__nav a::before{content:'';position:absolute;inset:6px 0;border-radius:99px;background:#ffffff0f;opacity:0;transform:scale(.82);transition:opacity .35s var(--ease),transform .35s var(--ease)}
.masthead__nav a:hover{color:var(--bone)}
.masthead__nav a:hover::before{opacity:1;transform:scale(1)}
.masthead__nav a>span{position:relative}

.motion{display:inline-flex;align-items:center;gap:9px;height:44px;font:400 10px var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.motion__led{width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 10px rgb(var(--accent-rgb)/.8)}
.motion[aria-pressed=true] .motion__led{background:var(--faint);box-shadow:none}
.motion:hover{color:var(--bone)}

/* ------------------------------------------------------------------- hero */
.hero{position:relative;min-height:100svh;display:flex;align-items:flex-end;padding-block:150px 46px}
.hero__inner{width:100%}
.hero__where{display:flex;align-items:center;margin-bottom:clamp(18px,3vw,34px)}
.hero__name{
  font-family:var(--display);
  font-weight:700;font-stretch:86%;
  font-size:clamp(96px,20.5vw,330px);
  line-height:.8;letter-spacing:-.05em;
  margin-left:-.035em;
}
.hero__name::after{content:'.';color:var(--accent)}
.hero__name .glyph{display:inline-block;will-change:transform}

.hero__row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:clamp(24px,4vw,64px);align-items:flex-end;margin-top:clamp(26px,4vw,54px)}
.hero__role{max-width:34ch;font-size:clamp(17px,1.5vw,22px);line-height:1.5;color:#c3c6cf;letter-spacing:-.01em}
.hero__role em{font-family:var(--serif);font-style:italic;color:var(--accent);font-size:1.12em}

.stamp{position:relative;width:clamp(86px,9vw,124px);flex:none;rotate:-4deg;transition:rotate .5s var(--ease),translate .5s var(--ease)}
.stamp img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:4px;filter:saturate(.92) contrast(1.05)}
.stamp::before{content:'';position:absolute;inset:-1px;border:1px solid var(--line-strong);border-radius:5px;pointer-events:none}
.stamp figcaption{position:absolute;left:6px;bottom:6px;padding:3px 6px;font:400 8px var(--mono);letter-spacing:.1em;background:#05060ae0;border-radius:3px;color:var(--bone)}
.stamp:hover{rotate:0deg;translate:0 -6px}

.hero__cue{margin-top:clamp(34px,6vw,76px)}
.hero__cue a{display:inline-flex;align-items:center;gap:14px;font:400 11px var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--dim)}
.hero__cue-line{display:block;width:54px;height:1px;background:linear-gradient(90deg,var(--accent),transparent);position:relative;overflow:hidden}
.hero__cue-line::after{content:'';position:absolute;inset:0;width:18px;background:var(--accent);animation:trace 2.4s var(--ease) infinite}
@keyframes trace{0%{transform:translateX(-20px)}70%,100%{transform:translateX(58px)}}
.hero__cue a:hover{color:var(--bone)}

/* ---------------------------------------------------------------- marquee */
.marquee{position:relative;padding-block:26px;border-block:1px solid var(--line);overflow:hidden;background:#05060a66;backdrop-filter:blur(3px)}
.marquee__track{display:flex;width:max-content;white-space:nowrap;will-change:transform}
.marquee__set{display:inline-block;padding-right:0;font-family:var(--display);font-weight:500;font-stretch:90%;font-size:clamp(26px,3.6vw,54px);letter-spacing:-.03em;color:#ffffff1f}
.marquee__set i{font-style:normal;color:var(--accent);font-size:.44em;vertical-align:middle;padding-inline:.22em}

/* -------------------------------------------------------------- statement */
.statement{padding-block:var(--band)}
.statement__text{
  font-family:var(--display);font-weight:500;font-stretch:88%;
  font-size:clamp(30px,5vw,80px);line-height:1.08;letter-spacing:-.04em;
  max-width:19ch;
}
.statement__text .word{color:#ffffff1c;transition:color .45s ease}
.statement__text .word.is-lit{color:var(--bone)}

/* ------------------------------------------------------------------- work */
.rule{display:flex;justify-content:space-between;align-items:baseline;gap:20px;padding-bottom:20px;border-bottom:1px solid var(--line)}
.h-display{
  font-family:var(--display);font-weight:600;font-stretch:84%;
  font-size:clamp(42px,7.4vw,124px);line-height:.95;letter-spacing:-.045em;
  margin-top:clamp(26px,4vw,52px);
}
.h-display em{font-family:var(--serif);font-style:italic;font-weight:400;font-stretch:normal;letter-spacing:-.02em;color:var(--accent)}

.work{padding-block:0 var(--band)}
.piece{display:block;margin-top:clamp(34px,5vw,72px)}
.piece__frame{
  position:relative;overflow:hidden;
  background:#0d1016;border:1px solid var(--line);
  aspect-ratio:1896/561;
}
.piece__frame img{width:100%;height:100%;object-fit:cover;transition:transform 1.1s var(--ease),opacity .6s ease}
.piece__gl{position:absolute;inset:0;width:100%;height:100%;display:block;opacity:0;transition:opacity .5s ease}
.piece__frame.fx-live .piece__gl{opacity:1}
.piece__frame.fx-live img{opacity:0}
.piece:hover .piece__frame:not(.fx-live) img{transform:scale(1.04)}
.piece__frame::after{content:'';position:absolute;inset:0;pointer-events:none;box-shadow:inset 0 0 120px #05060a88}

.piece__open{
  position:absolute;right:clamp(14px,2vw,28px);bottom:clamp(14px,2vw,28px);
  display:grid;place-items:center;width:62px;height:62px;border-radius:50%;
  background:var(--bone);color:var(--void);
  transition:transform .45s var(--ease),background .45s var(--ease);
}
.piece__open svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.piece:hover .piece__open,.piece:focus-visible .piece__open{transform:scale(1.12) rotate(45deg);background:var(--accent)}

.piece__meta{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr) auto;gap:clamp(20px,4vw,64px);align-items:end;margin-top:clamp(22px,3vw,40px)}
.piece__meta h3{font-family:var(--display);font-weight:600;font-stretch:86%;font-size:clamp(26px,3.4vw,50px);letter-spacing:-.04em;line-height:1.05;margin-top:12px}
.piece__note{color:var(--dim);max-width:34ch;font-size:15px}
.piece__cta{display:inline-flex;align-items:center;gap:10px;font:400 13px var(--sans);color:var(--accent);white-space:nowrap}
.piece:hover ~ .piece__meta .piece__cta span{transform:translateX(6px)}
.piece__cta span{display:inline-block;transition:transform .4s var(--ease)}

/* ------------------------------------------------------------------ about */
.about{padding-block:var(--band);border-top:1px solid var(--line)}
.about__grid{display:grid;grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);gap:clamp(34px,6vw,110px)}
.about__aside{position:sticky;top:120px;align-self:start}
.portrait{margin-top:clamp(28px,4vw,54px);max-width:290px;position:relative;overflow:hidden;border-radius:6px;border:1px solid var(--line)}
.portrait img{width:100%;aspect-ratio:1;object-fit:cover}
.portrait::after{content:'';position:absolute;inset:0;background:linear-gradient(180deg,transparent 40%,#05060acc);mix-blend-mode:multiply}

.lede{font-size:clamp(20px,2.1vw,30px);line-height:1.38;letter-spacing:-.02em;color:#d3d6dd;max-width:26ch}
.stack{margin-top:clamp(40px,6vw,80px);border-top:1px solid var(--line)}
.stack>div{display:grid;grid-template-columns:150px minmax(0,1fr);gap:16px;align-items:baseline;padding-block:22px;border-bottom:1px solid var(--line);transition:background .4s ease,padding-inline .4s var(--ease)}
.stack>div:hover{background:#ffffff07;padding-inline:14px}
.stack dt{font:400 11px var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.stack dd{display:inline}
.stack dd+dd::before{content:'\00a0\00b7\00a0';color:var(--faint)}
.about__body .link{margin-top:clamp(34px,4vw,54px);font-size:15px}

/* --------------------------------------------------------------- activity */
.activity{padding-block:var(--band);border-top:1px solid var(--line)}
.activity-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 20px;margin-top:clamp(34px,5vw,64px)}
.activity-total{font-family:var(--display);font-weight:600;font-stretch:86%;font-size:clamp(24px,2.6vw,38px);letter-spacing:-.03em}
#heat-range{margin-top:6px}

.heat{margin-top:26px;overflow-x:auto;overscroll-behavior-x:contain;padding-bottom:6px}
.heat__grid{display:grid;grid-auto-flow:column;grid-template-columns:repeat(var(--weeks,26),minmax(9px,1fr));gap:4px;min-width:min(100%,560px)}
.heat__col{display:grid;grid-template-rows:repeat(7,1fr);gap:4px}
.heat__cell{aspect-ratio:1;border-radius:2px;background:#ffffff0d;transition:background .4s ease,box-shadow .4s ease}
.heat__cell[data-l="1"]{background:rgb(var(--accent-rgb)/.24)}
.heat__cell[data-l="2"]{background:rgb(var(--accent-rgb)/.46)}
.heat__cell[data-l="3"]{background:rgb(var(--accent-rgb)/.72)}
.heat__cell[data-l="4"]{background:rgb(var(--accent-rgb)/1);box-shadow:0 0 12px rgb(var(--accent-rgb)/.5)}
.heat__foot{display:flex;flex-wrap:wrap;justify-content:space-between;gap:12px;margin-top:16px}
.heat__key{display:inline-flex;align-items:center;gap:5px}
.heat__key .heat__cell{width:11px;height:11px;aspect-ratio:auto}
.activity-fallback{margin-top:clamp(34px,5vw,64px);color:var(--dim)}

/* ---------------------------------------------------------------- contact */
.contact{position:relative;padding-block:calc(var(--band) * 1.15);border-top:1px solid var(--line);overflow:hidden;isolation:isolate}
.contact__sky{
  position:absolute;z-index:-1;inset:0;
  background:url('assets/space-andromeda.jpg') center/cover no-repeat;
  opacity:.5;
  /* The source mosaic has ragged edges; fade them out rather than crop the sweep. */
  -webkit-mask-image:radial-gradient(76% 88% at 50% 50%,#000 24%,transparent 78%);
  mask-image:radial-gradient(76% 88% at 50% 50%,#000 24%,transparent 78%);
}
.contact__inner{position:relative}
.contact__title{
  font-family:var(--display);font-weight:700;font-stretch:84%;
  font-size:clamp(58px,13vw,220px);line-height:.86;letter-spacing:-.05em;
  margin-block:clamp(18px,3vw,36px) clamp(34px,5vw,70px);
}
.contact__title::after{content:'.';color:var(--accent)}
.contact__title .glyph{display:inline-block}
.contact__links{display:grid;gap:0;border-top:1px solid var(--line-strong);max-width:900px}
.big-link{
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding-block:clamp(18px,2.4vw,30px);border-bottom:1px solid var(--line-strong);
  font-family:var(--display);font-weight:500;font-stretch:90%;
  font-size:clamp(20px,2.6vw,38px);letter-spacing:-.03em;
  transition:padding-inline .5s var(--ease),color .4s ease;
}
a.big-link:hover{padding-inline:20px;color:var(--accent)}
.big-link__arrow{transition:transform .5s var(--ease)}
a.big-link:hover .big-link__arrow{transform:translate(6px,-6px)}
.big-link--pending{color:var(--faint)}

/* ----------------------------------------------------------------- footer */
.footer{border-top:1px solid var(--line);padding-block:34px}
.footer__inner{display:flex;flex-wrap:wrap;align-items:center;gap:14px 34px}
.footer__name{font:500 15px var(--sans);letter-spacing:-.02em}
.footer__name b{font-weight:500;color:var(--dim)}
.footer__credit{flex:1 1 320px;color:var(--faint)}

/* ------------------------------------------------------------ enhancement */
/* Reveal state. Without JavaScript the .is-ready class never lands and every
   one of these stays at its final value, so the page simply renders. */
.js [data-split]{opacity:0}
.js [data-split].is-ready{opacity:1}
/* SplitText's masks need the pieces to be block-level to clip cleanly. */
.js .line{display:block}
.js .glyph{display:inline-block}

/* ------------------------------------------------------------ narrow view */
@media (max-width:1080px){
  .about__grid{grid-template-columns:1fr}
  .about__aside{position:static}
  .portrait{max-width:220px}
  .piece__meta{grid-template-columns:1fr 1fr;row-gap:26px}
  .piece__cta{grid-column:1/-1}
}
@media (max-width:780px){
  .masthead{height:64px}
  .masthead__nav{display:none}
  .hero{padding-block:120px 40px;min-height:94svh}
  .hero__row{grid-template-columns:1fr;align-items:flex-start}
  .stamp{order:-1;margin-bottom:8px}
  .piece__meta{grid-template-columns:1fr}
  .stack>div{grid-template-columns:1fr;gap:6px;padding-block:18px}
  .piece__open{width:48px;height:48px}
  .piece__open svg{width:18px;height:18px}
  .footer__credit{flex-basis:100%}
}
@media (max-width:480px){
  .hero__name{font-size:clamp(76px,23vw,150px)}
  .heat__grid{min-width:520px}
}

/* ----------------------------------------------------------- less motion */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  .backdrop__grain{animation:none}
  .js [data-split]{opacity:1}
}
/* The pause control mirrors the same state for people who switch motion off. */
html.motion-off .backdrop__grain,
html.motion-off .hero__cue-line::after,
html.motion-off .wordmark__mark{animation:none!important}
html.motion-off .backdrop__gl{opacity:.6}
