/* ═══════════════════════════════════════════════════════════
   sanjay — personal site
   crimson / near-black. serif display against all-mono body.
   ═══════════════════════════════════════════════════════════ */

:root{
  --bg:#08080B;
  --bg2:#0D0D11;
  --panel:#121216;
  --panel2:#17171C;
  --line:#23232A;
  --line2:#31313B;

  --text:#EDEDF0;
  --dim:#8B8B96;
  --faint:#5A5A64;

  --crimson:#C41E3A;
  --crimson-lt:#F04256;
  --gain:#57BC74;
  --blue:#6BA8DE;
  --gold:#DFAE4C;

  --serif:'Instrument Serif',Georgia,'Times New Roman',serif;
  --mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  --col:52rem;
  --ease:cubic-bezier(.22,.61,.36,1);
}

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

html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:2rem;
}

body{
  background:var(--bg);
  color:var(--text);
  font-family:var(--mono);
  font-size:15px;
  font-weight:400;
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  text-rendering:optimizeLegibility;
}

::selection{background:var(--crimson);color:#fff}

:focus-visible{
  outline:2px solid var(--crimson-lt);
  outline-offset:3px;
  border-radius:2px;
}

.skip{
  position:absolute;left:-9999px;top:0;z-index:200;
  background:var(--crimson);color:#fff;padding:.6rem 1rem;font-size:.8rem;
}
.skip:focus{left:0}

/* ─────────── ambient background ─────────── */

#ambient{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;background:var(--bg)}
#stars,#lorenz{position:absolute;inset:0;width:100%;height:100%}

/* the attractor traces behind the entire page. it sits under the grain and
   the vignette, which is what keeps it from competing with body copy. */
#lorenz{opacity:.8;mix-blend-mode:screen}

.neb{position:absolute;border-radius:50%;filter:blur(130px);will-change:transform}
.n1{
  width:62vw;height:62vw;left:-20vw;top:-10vh;
  background:radial-gradient(circle,rgba(196,30,58,.30),transparent 68%);
  animation:n1 30s ease-in-out infinite;
}
.n2{
  width:50vw;height:50vw;right:-16vw;top:48vh;
  background:radial-gradient(circle,rgba(120,14,34,.36),transparent 70%);
  animation:n2 38s ease-in-out infinite;
}
@keyframes n1{50%{transform:translate(8vw,7vh) scale(1.14)}}
@keyframes n2{50%{transform:translate(-6vw,-8vh) scale(1.1)}}

/* film grain — inline feTurbulence, no network request */
#grain{
  position:absolute;inset:-50%;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  opacity:.05;
  animation:grain 6s steps(6) infinite;
}
@keyframes grain{
  0%,100%{transform:translate(0,0)}   17%{transform:translate(-4%,-3%)}
  33%{transform:translate(3%,-4%)}    50%{transform:translate(-3%,4%)}
  67%{transform:translate(4%,3%)}     83%{transform:translate(-4%,2%)}
}

#vig{
  position:absolute;inset:0;
  background:radial-gradient(ellipse at 50% 40%,transparent 24%,rgba(8,8,11,.92) 92%);
}

/* ─────────── hero collage ─────────── */

#hero{
  position:relative;z-index:10;
  height:100svh;min-height:34rem;
  overflow:hidden;
  isolation:isolate;
}

/* corner brackets */
.frame i{
  position:absolute;color:var(--line2);font-style:normal;
  font-size:1.5rem;line-height:1;user-select:none;
}
.br.tl{top:1rem;left:1rem}   .br.tr{top:1rem;right:1rem}
.br.bl{bottom:1rem;left:1rem} .br.br2{bottom:1rem;right:1rem}

/* every collage item positions from --x/--y and parallaxes by --d.
   --px/--py MUST carry units — they land inside calc() below, and a bare 0
   would invalidate the whole declaration on devices where the JS never runs. */
.f{
  --px:0px; --py:0px;
  position:absolute;
  left:var(--x);top:var(--y);
  transform:translate3d(var(--px),var(--py),0);
  will-change:transform;
}

.meta{max-width:15rem}
.meta h3{
  font-family:var(--mono);font-size:.68rem;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--crimson-lt);
  margin-bottom:.4rem;
}
.meta p{font-size:.76rem;color:var(--dim);line-height:1.55}

.pill{
  display:flex;align-items:center;gap:.45rem;
  font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);
  border:1px solid var(--line);background:rgba(13,13,17,.7);
  padding:.3rem .7rem;border-radius:99px;backdrop-filter:blur(6px);
}
.pill .dot{
  width:6px;height:6px;border-radius:50%;background:var(--gain);
  box-shadow:0 0 8px var(--gain);animation:pulse 2.4s ease-in-out infinite;
}
@keyframes pulse{50%{opacity:.35}}

/* the name */
.wordmark{
  position:absolute;left:50%;top:46%;
  transform:translate(-50%,-50%);
  z-index:2;pointer-events:none;
}
.wordmark h1,.wordmark span{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(4.5rem,17vw,13rem);
  line-height:.9;letter-spacing:-.02em;
  text-transform:lowercase;white-space:nowrap;
  display:block;
}
.wordmark span{position:absolute;inset:0;color:var(--crimson)}
.wordmark span:nth-child(1){opacity:.07;transform:translate(15px,12px)}
.wordmark span:nth-child(2){opacity:.11;transform:translate(9px,7px)}
.wordmark span:nth-child(3){opacity:.20;transform:translate(4px,3px);color:var(--text)}
.wordmark h1{position:relative;color:var(--text)}

/* scattered annotations */
.tag{
  font-size:.8rem;color:var(--dim);line-height:1.45;
  max-width:16rem;letter-spacing:.01em;
}
.tag.lead{
  transform:translate3d(calc(-50% + var(--px)),var(--py),0);
  text-align:center;color:var(--text);font-size:.92rem;max-width:min(30rem,84vw);
  min-height:1.5rem;
}
.tag.rot-l{transform:translate3d(var(--px),var(--py),0) rotate(-4deg)}
.tag.rot-r{transform:translate3d(var(--px),var(--py),0) rotate(3.5deg)}
.tag.dimmed{color:var(--faint);font-size:.72rem}
.tag.route{color:var(--dim);font-size:.78rem;letter-spacing:.03em}
.sig{letter-spacing:.1em;font-size:.62rem;line-height:1.9}
.sig span{color:var(--crimson);letter-spacing:.16em;text-transform:uppercase;font-size:.56rem}

.cursor{
  display:inline-block;width:8px;height:1em;background:var(--crimson-lt);
  vertical-align:-.15em;margin-left:3px;animation:blink 1.1s step-end infinite;
}
@keyframes blink{50%{opacity:0}}

/* generative artifact cards */
.card{
  background:rgba(13,13,17,.66);border:1px solid var(--line);
  padding:.5rem;backdrop-filter:blur(4px);
}
.card svg,.card canvas{display:block;width:100%;height:auto}
.card figcaption{
  font-size:.56rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--faint);margin-top:.35rem;
}
.plot{width:11rem}
.plot .ax{stroke:var(--line2);stroke-width:.7;fill:none}
.plot .curve{stroke:var(--crimson-lt);stroke-width:1.4;fill:none;stroke-linejoin:round}
.plot .curve2{stroke:var(--faint);stroke-width:1;fill:none;stroke-dasharray:2 2}

.matrix{
  font-family:var(--mono);font-size:.42rem;line-height:.95;
  color:var(--crimson);opacity:.5;letter-spacing:.08em;user-select:none;
}

.coord{
  font-size:.56rem;letter-spacing:.1em;color:var(--faint);
}
.coord::before{
  content:'';position:absolute;left:-11px;top:50%;
  width:7px;height:1px;background:var(--line2);
}

/* ticker */
.tape{
  position:absolute;left:0;right:0;bottom:4.6rem;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  background:rgba(8,8,11,.6);backdrop-filter:blur(6px);
  height:32px;display:flex;align-items:center;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.tape-track{display:flex;white-space:nowrap;animation:roll 46s linear infinite}
@keyframes roll{to{transform:translateX(-50%)}}
.tick{
  font-size:.68rem;letter-spacing:.06em;padding:0 1.4rem;color:var(--dim);
  display:inline-flex;gap:.45rem;align-items:center;
}
.tick b{color:var(--text);font-weight:500}
.tick i{font-style:normal}
.up{color:var(--gain)} .dn{color:var(--crimson-lt)} .flat{color:var(--faint)}

.scrollhint{
  position:absolute;left:50%;bottom:1.6rem;transform:translateX(-50%);
  font-size:.64rem;letter-spacing:.22em;text-transform:uppercase;
  color:var(--faint);text-decoration:none;text-align:center;
  transition:color .2s var(--ease);
}
.scrollhint:hover{color:var(--crimson-lt)}
.scrollhint span{display:block;font-size:.9rem;margin-top:.15rem;animation:bob 1.8s ease-in-out infinite}
@keyframes bob{50%{transform:translateY(5px)}}

/* ─────────── content ─────────── */

/* the attractor runs behind everything, so the reading half of the page gets a
   scrim that fades in just past the hero. it stays visible, it stops competing. */
main{
  position:relative;z-index:10;
  background:linear-gradient(rgba(8,8,11,0),rgba(8,8,11,.85) 7rem);
}
.wrap{max-width:var(--col);margin:0 auto;padding:0 1.5rem 7rem}
.sec{margin-top:5.5rem}
.sec:first-child{margin-top:4rem}

.hd{
  display:flex;align-items:baseline;gap:.8rem;
  border-bottom:1px solid var(--line);
  padding-bottom:.55rem;margin-bottom:1.5rem;
}
.hd h2{
  font-family:var(--serif);font-weight:400;font-size:1.7rem;
  letter-spacing:0;text-transform:lowercase;line-height:1;
}
.hd small{
  font-size:.6rem;color:var(--crimson-lt);letter-spacing:.18em;
  margin-left:auto;text-transform:uppercase;
}

/* key/value rows */
.rows{display:block}
.row{
  display:grid;grid-template-columns:1fr auto;gap:1rem;
  padding:.6rem 0;border-bottom:1px dotted var(--line);
  font-size:.86rem;
}
.row:last-child{border-bottom:none}
.row dt{color:var(--dim)}
.row dd{font-weight:500;text-align:right}

/* ─────────── loadout ─────────── */

/* fixed 5 wide so the 10 tiles land as an even 5 + 5 at every width */
.grid{display:grid;grid-template-columns:repeat(5,1fr);gap:.55rem}
.slot{
  aspect-ratio:1;background:var(--panel2);border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;
  font:inherit;font-size:.64rem;font-weight:500;text-align:center;color:var(--text);
  cursor:crosshair;padding:2px;line-height:1.15;
  transition:border-color .14s var(--ease),transform .14s var(--ease),background .14s var(--ease);
}
.slot:hover,.slot:focus-visible,.slot[aria-expanded="true"]{
  border-color:var(--crimson);transform:translateY(-2px);background:var(--panel);
}
.slot[data-tier="2"]{color:var(--blue)}
.slot[data-tier="3"]{color:var(--gold)}
/* dashed + faint, never transparent — opacity here would let the attractor
   show through and the tile would read as a hole in the grid */
.slot.empty{
  cursor:default;color:var(--faint);
  background:var(--bg2);border-style:dashed;
}
.slot.empty:hover{border-color:var(--line);transform:none;background:var(--bg2)}

.slotinfo{
  margin-top:.9rem;font-size:.74rem;color:var(--dim);min-height:2.6rem;line-height:1.6;
}
.slotinfo b{color:var(--text);font-weight:500}
.slotinfo i{color:var(--crimson-lt)}

/* ─────────── ambient jazz toggle ─────────── */

.audio{
  position:fixed;right:1.1rem;bottom:1.1rem;z-index:80;
  display:flex;align-items:center;gap:.55rem;
  font:inherit;font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim);background:rgba(8,8,11,.8);
  border:1px solid var(--line);border-radius:99px;
  padding:.42rem .8rem .42rem .7rem;cursor:pointer;
  backdrop-filter:blur(8px);
  transition:color .18s var(--ease),border-color .18s var(--ease);
}
.audio:hover{color:var(--text);border-color:var(--line2)}
.audio[aria-pressed="true"]{color:var(--crimson-lt);border-color:var(--crimson)}

.eq{display:flex;align-items:flex-end;gap:2px;height:10px}
.eq i{width:2px;height:2px;background:currentColor;display:block;transition:height .2s var(--ease)}
.audio[aria-pressed="true"] .eq i{animation:eq 1.1s ease-in-out infinite}
.eq i:nth-child(2){animation-delay:.18s}
.eq i:nth-child(3){animation-delay:.36s}
.eq i:nth-child(4){animation-delay:.54s}
@keyframes eq{0%,100%{height:2px}50%{height:10px}}

/* the bars are the state indicator, so pin them open when animation is off */
@media (prefers-reduced-motion:reduce){
  .audio[aria-pressed="true"] .eq i{height:10px}
}

#tip{
  position:fixed;z-index:90;pointer-events:none;
  background:#08080A;border:1px solid var(--line2);
  padding:.6rem .75rem;max-width:15rem;font-size:.72rem;line-height:1.45;
  opacity:0;transition:opacity .12s var(--ease);
  box-shadow:0 8px 24px rgba(0,0,0,.6);
}
#tip .t{font-weight:600;display:block;margin-bottom:.15rem}
#tip .ty{color:var(--dim);display:block;margin-bottom:.3rem;font-size:.66rem}
#tip .fl{color:var(--crimson-lt);font-style:italic;display:block;margin-top:.35rem}

/* ─────────── github output ─────────── */

#output.is-loading .gcell .n,#output.is-loading .barlbl [data-live]{opacity:.4}
#output.is-error{display:none}

.gh{display:grid;grid-template-columns:repeat(3,1fr);gap:.6rem;margin-bottom:1rem}
.gcell{background:var(--panel2);border:1px solid var(--line);padding:.85rem .7rem;text-align:center}
.gcell .n{
  font-family:var(--serif);font-size:1.9rem;line-height:1;
  display:block;margin-bottom:.3rem;transition:opacity .3s var(--ease);
}
.gcell .l{font-size:.58rem;color:var(--faint);letter-spacing:.13em}

.bars{
  display:flex;gap:3px;align-items:flex-end;height:46px;
  background:var(--panel2);border:1px solid var(--line);padding:.5rem;
}
.bar{flex:1;background:var(--line);min-height:2px;border-radius:1px;transition:height .5s var(--ease)}
.bar.on{background:var(--crimson)}
.barlbl{
  font-size:.6rem;color:var(--faint);letter-spacing:.08em;margin-top:.45rem;
  display:flex;justify-content:space-between;
}

/* ─────────── rotation ─────────── */

.rot{display:grid;grid-template-columns:repeat(12,1fr);gap:4px}
.art{
  background:var(--panel2);border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;text-align:center;
  padding:.5rem .3rem;font-weight:500;line-height:1.15;
  position:relative;overflow:hidden;
  transition:border-color .16s var(--ease),color .16s var(--ease);
}
.art:hover{border-color:var(--crimson);color:var(--crimson-lt)}
.art::before{
  content:attr(data-n);position:absolute;top:3px;left:4px;
  font-size:.5rem;color:var(--faint);letter-spacing:.06em;
}
.a1{
  grid-column:span 6;grid-row:span 2;font-size:1.5rem;min-height:96px;
  background:linear-gradient(140deg,rgba(196,30,58,.22),var(--panel2));
}
.a2{grid-column:span 6;font-size:1rem;min-height:46px;background:linear-gradient(140deg,rgba(196,30,58,.14),var(--panel2))}
.a3{grid-column:span 6;font-size:1rem;min-height:46px;background:linear-gradient(140deg,rgba(196,30,58,.08),var(--panel2))}
.a4,.a5,.a6{grid-column:span 4;font-size:.78rem;min-height:52px}
.sm{grid-column:span 3;font-size:.64rem;color:var(--dim);min-height:48px}

/* ─────────── links + footer ─────────── */

.links{display:flex;flex-wrap:wrap;gap:1.7rem;align-items:baseline}
.links a{
  color:var(--dim);text-decoration:none;font-size:.84rem;
  position:relative;transition:color .18s var(--ease);
}
.links a::after{
  content:'';position:absolute;left:0;bottom:-3px;width:100%;height:1px;
  background:var(--crimson);transform:scaleX(0);transform-origin:left;
  transition:transform .22s var(--ease);
}
.links a:hover,.links a:focus-visible{color:var(--text)}
.links a:hover::after,.links a:focus-visible::after{transform:scaleX(1)}

footer{
  margin-top:5rem;padding-top:1.2rem;border-top:1px solid var(--line);
  font-size:.64rem;color:var(--faint);letter-spacing:.08em;
  display:flex;justify-content:space-between;flex-wrap:wrap;gap:1rem;
}

/* ─────────── responsive ─────────── */

@media (max-width:1040px){ .t3{display:none} }

/* --x/--y are set inline on each floater, so overriding them from a media
   query needs !important — inline custom properties otherwise win. */
@media (max-width:760px){
  .t2{display:none}
  .wordmark{top:34%}
  .wordmark h1,.wordmark span{font-size:clamp(5.5rem,20vw,13rem)}
  .tag.lead{--y:47% !important}

  /* the collage can't survive at this width, so bring the stats block back
     as a centred block and let it carry the space under the name */
  #heroStats{
    display:block;
    --x:50% !important; --y:61% !important;
    transform:translateX(-50%);
    text-align:center;
    max-width:min(21rem,86vw);
  }
  #heroStats h3{margin-bottom:.5rem}
  #heroStats p{font-size:.74rem}
}

@media (max-width:640px){
  body{font-size:14px}
  .wrap{padding:0 1.15rem 5rem}
  .sec{margin-top:4.2rem}
  .hd h2{font-size:1.45rem}
  .row{grid-template-columns:1fr;gap:.1rem}
  .row dd{text-align:left}
  .gh{grid-template-columns:1fr;gap:.4rem}
  .gcell{display:flex;align-items:baseline;justify-content:space-between;text-align:left}
  .gcell .n{margin-bottom:0;font-size:1.5rem}
  .grid{gap:.4rem}
  .slot{font-size:.56rem}
  .a1,.a2,.a3{grid-column:span 12}
  .a4,.a5,.a6{grid-column:span 6}
  .sm{grid-column:span 6}
  .frame i{font-size:1.1rem}
}

@media (hover:none){
  #tip{display:none}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .f{transform:none !important}
  .tag.lead{transform:translateX(-50%) !important}
}
