/* ==========================================================================
   Joash Tay — personal site
   Dark theme, zero dependencies.
   Effects adapted from the Dev reference set (see README.md).
   ========================================================================== */

/* ---------- tokens ---------- */
:root{
  --void:#06070a;
  --surface:#0c0f15;
  --raised:#12161f;
  --raised-2:#171d28;

  --hair:rgba(255,255,255,.075);
  --hair-2:rgba(255,255,255,.14);

  --cyan:#4fd1ff;
  --cyan-20:rgba(79,209,255,.20);
  --cyan-35:rgba(79,209,255,.35);
  --rose:#ff4d6d;
  --mint:#5ef2c0;
  --amber:#ffb84d;
  --violet:#a78bfa;
  --lime:#b6f36a;

  --text:#e9eef6;
  --dim:#93a3b8;
  --faint:#5b6878;

  --ff-display:"Space Grotesk",ui-sans-serif,system-ui,sans-serif;
  --ff-body:"Inter",ui-sans-serif,system-ui,-apple-system,sans-serif;
  --ff-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  --maxw:1240px;
  --pad:clamp(1.15rem,4vw,3rem);
  --r:14px;
  --ease:cubic-bezier(.23,1,.32,1);
  --ease-snap:cubic-bezier(.4,0,.2,1);
}

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

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

body{
  background:var(--void);
  color:var(--text);
  font-family:var(--ff-body);
  font-size:clamp(.95rem,.9rem + .2vw,1.0625rem);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img{display:block;max-width:100%;height:auto;}
a{color:inherit;text-decoration:none;}
ul{list-style:none;}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;}

::selection{background:var(--cyan);color:var(--void);}

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

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

.skip{
  position:fixed;top:-100px;left:1rem;z-index:400;
  background:var(--cyan);color:var(--void);
  padding:.7rem 1.1rem;border-radius:8px;font-weight:600;
  transition:top .2s;
}
.skip:focus{top:1rem;}

.wrap{
  width:100%;
  max-width:var(--maxw);
  margin-inline:auto;
  padding-inline:var(--pad);
}

/* ---------- scrollbar ---------- */
::-webkit-scrollbar{width:10px;height:10px;}
::-webkit-scrollbar-track{background:var(--void);}
::-webkit-scrollbar-thumb{background:#1c2432;border-radius:99px;border:2px solid var(--void);}
::-webkit-scrollbar-thumb:hover{background:#27334a;}

/* ==========================================================================
   BOOT SEQUENCE
   ========================================================================== */
.boot{
  position:fixed;inset:0;z-index:500;
  background:var(--void);
  display:grid;place-items:center;
  transition:opacity .6s var(--ease),visibility .6s;
}
.boot.is-done{opacity:0;visibility:hidden;}
.boot__inner{width:min(560px,86vw);}
.boot__log{
  font-family:var(--ff-mono);
  font-size:clamp(.7rem,.66rem + .25vw,.8rem);
  line-height:1.9;
  color:var(--dim);
  white-space:pre-wrap;
  min-height:11em;
}
.boot__log b{color:var(--cyan);font-weight:500;}
.boot__log i{color:var(--mint);font-style:normal;}
.boot__bar{
  margin-top:1.5rem;height:2px;background:var(--hair);overflow:hidden;
}
.boot__bar i{
  display:block;height:100%;width:0;background:var(--cyan);
  box-shadow:0 0 12px var(--cyan);
  transition:width .25s linear;
}

/* ==========================================================================
   CURSOR + PROGRESS
   ========================================================================== */
.cursor{position:fixed;top:0;left:0;z-index:700;pointer-events:none;display:none;}
.cursor__dot,.cursor__ring{
  position:absolute;top:0;left:0;border-radius:50%;
  transform:translate(-50%,-50%);
}
.cursor__dot{width:5px;height:5px;background:var(--cyan);}
.cursor__ring{
  width:34px;height:34px;border:1px solid var(--cyan-35);
  transition:width .25s var(--ease),height .25s var(--ease),border-color .25s,background-color .25s;
}
body.cursor-on .cursor{display:block;}
body.cursor-on{cursor:none;}
/* cursor:none on body alone is overridden by anything that sets its own,
   so buttons kept their pointer and the gallery kept its zoom-in glass */
body.cursor-on *{cursor:none !important;}
.cursor.is-hot .cursor__ring{
  width:56px;height:56px;
  border-color:var(--cyan);
  background:var(--cyan-20);
}

.progress{
  position:fixed;top:0;left:0;right:0;height:2px;z-index:120;
  background:transparent;pointer-events:none;
}
.progress i{
  display:block;height:100%;width:0;
  background:linear-gradient(90deg,var(--cyan),var(--mint));
  box-shadow:0 0 10px var(--cyan-35);
}

/* ==========================================================================
   NAV
   ========================================================================== */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:110;
  display:flex;align-items:center;justify-content:space-between;
  gap:1rem;
  padding:1.1rem var(--pad);
  transition:background-color .35s,backdrop-filter .35s,border-color .35s,padding .35s;
  border-bottom:1px solid transparent;
}
.nav.is-stuck{
  background:rgba(6,7,10,.72);
  backdrop-filter:blur(9px);
  -webkit-backdrop-filter:blur(9px);
  border-bottom-color:var(--hair);
  padding-block:.75rem;
}

.nav__brand{display:flex;align-items:center;gap:.6rem;}
.nav__brandMark{
  font-family:var(--ff-mono);font-weight:700;font-size:.8rem;letter-spacing:.06em;
  display:grid;place-items:center;width:32px;height:32px;
  border:1px solid var(--cyan-35);color:var(--cyan);border-radius:8px;
  transition:background-color .3s,box-shadow .3s;
}
.nav__brand:hover .nav__brandMark{background:var(--cyan-20);box-shadow:0 0 18px var(--cyan-20);}
.nav__brandName{
  font-family:var(--ff-display);font-weight:600;font-size:.95rem;letter-spacing:-.01em;
}

.nav__links{display:flex;align-items:center;gap:.35rem;}
.nav__links a{
  font-family:var(--ff-mono);
  font-size:.76rem;letter-spacing:.04em;
  color:var(--dim);
  padding:.5rem .75rem;border-radius:8px;
  transition:color .25s,background-color .25s;
}
.nav__links a:hover,.nav__links a.is-active{color:var(--text);}
.nav__links a.is-active{background:rgba(255,255,255,.05);}
.nav__cta{
  color:var(--cyan) !important;
  border:1px solid var(--cyan-35);
  margin-left:.4rem;
}
.nav__cta:hover{background:var(--cyan-20);}

.nav__burger{
  display:none;width:40px;height:40px;
  border:1px solid var(--hair);border-radius:10px;
  place-items:center;gap:5px;flex-direction:column;
}
.nav__burger span{
  display:block;width:17px;height:1.5px;background:var(--text);
  transition:transform .3s var(--ease),opacity .3s;
}
.nav__burger[aria-expanded="true"] span:first-child{transform:translateY(3.25px) rotate(45deg);}
.nav__burger[aria-expanded="true"] span:last-child{transform:translateY(-3.25px) rotate(-45deg);}

/* glitch — adapted from retro-glitchy-navigation-with-gsap */
.glitch{position:relative;}
.glitch::before,.glitch::after{
  content:attr(data-text);
  position:absolute;inset:0;
  display:grid;place-items:center;
  padding:inherit;
  opacity:0;pointer-events:none;
  font:inherit;letter-spacing:inherit;
}
.glitch::before{color:var(--rose);}
.glitch::after{color:var(--cyan);}
.glitch:hover::before{animation:glitch-a .4s steps(2,end) 2;opacity:.9;}
.glitch:hover::after{animation:glitch-b .4s steps(2,end) 2;opacity:.9;}
.glitch:hover > span{animation:glitch-jitter .4s steps(2,end) 2;}

@keyframes glitch-a{
  0%{transform:translate(0,0);clip-path:inset(0 0 62% 0);}
  25%{transform:translate(-2px,1px);clip-path:inset(48% 0 20% 0);}
  50%{transform:translate(2px,-1px);clip-path:inset(12% 0 70% 0);}
  75%{transform:translate(-1px,0);clip-path:inset(72% 0 6% 0);}
  100%{transform:translate(0,0);clip-path:inset(0 0 100% 0);}
}
@keyframes glitch-b{
  0%{transform:translate(0,0);clip-path:inset(70% 0 0 0);}
  25%{transform:translate(2px,-1px);clip-path:inset(18% 0 52% 0);}
  50%{transform:translate(-2px,1px);clip-path:inset(60% 0 14% 0);}
  75%{transform:translate(1px,0);clip-path:inset(4% 0 80% 0);}
  100%{transform:translate(0,0);clip-path:inset(100% 0 0 0);}
}
@keyframes glitch-jitter{
  0%,100%{transform:translate(0,0);}
  30%{transform:translate(1px,-1px);}
  60%{transform:translate(-1px,1px);}
}

/* ==========================================================================
   SHARED PIECES
   ========================================================================== */
.section{padding-block:clamp(5rem,11vw,9rem);position:relative;}
.section--tight{padding-block:clamp(3rem,7vw,5.5rem);}
.section--flush{padding-bottom:clamp(3rem,7vw,5rem);}

.secHead{margin-bottom:clamp(2.5rem,5vw,4rem);position:relative;}
.secHead--flush{margin-bottom:clamp(1.25rem,3vw,2rem);padding-inline:var(--pad);}
.secHead__num{
  font-family:var(--ff-mono);font-size:.72rem;letter-spacing:.28em;
  color:var(--cyan);display:block;margin-bottom:.9rem;
}
.secHead__num::before{content:"[ ";opacity:.5;}
.secHead__num::after{content:" ]";opacity:.5;}
.secHead__title{
  font-family:var(--ff-display);
  font-size:clamp(2rem,1.2rem + 4.2vw,4.25rem);
  font-weight:600;line-height:1.02;letter-spacing:-.035em;
}
.secHead__sub{
  margin-top:.85rem;color:var(--dim);
  font-family:var(--ff-mono);font-size:.78rem;letter-spacing:.03em;
}

.eyebrow{
  font-family:var(--ff-mono);font-size:.75rem;letter-spacing:.2em;
  color:var(--cyan);
}

/* buttons */
.btn{
  display:inline-flex;align-items:center;gap:.6rem;
  font-family:var(--ff-mono);font-size:.8rem;letter-spacing:.04em;
  padding:.85rem 1.4rem;border-radius:10px;
  border:1px solid var(--hair-2);color:var(--text);
  background:rgba(255,255,255,.03);
  transition:border-color .3s,background-color .3s,transform .3s var(--ease),box-shadow .3s;
}
.btn:hover{border-color:var(--cyan-35);background:rgba(79,209,255,.07);transform:translateY(-2px);}
.btn--primary{
  background:var(--cyan);color:var(--void);border-color:var(--cyan);font-weight:700;
}
.btn--primary:hover{
  background:#6fdcff;border-color:#6fdcff;
  box-shadow:0 12px 34px -12px var(--cyan);
}
.btn__arrow{width:14px;height:1.5px;background:currentColor;position:relative;transition:width .3s var(--ease);}
.btn__arrow::after{
  content:"";position:absolute;right:0;top:50%;
  width:6px;height:6px;border-top:1.5px solid currentColor;border-right:1.5px solid currentColor;
  transform:translateY(-50%) rotate(45deg);
}
.btn:hover .btn__arrow{width:22px;}

/* chips */
.chip{
  display:inline-block;
  font-family:var(--ff-mono);font-size:.64rem;letter-spacing:.16em;text-transform:uppercase;
  padding:.3rem .7rem;border-radius:999px;border:1px solid;
}
.chip--education{color:var(--cyan);border-color:var(--cyan-35);background:rgba(79,209,255,.09);}
.chip--career{color:var(--mint);border-color:rgba(94,242,192,.35);background:rgba(94,242,192,.09);}
.chip--service{color:var(--rose);border-color:rgba(255,77,109,.35);background:rgba(255,77,109,.09);}

/* cursor-tracking glow — adapted from glowing-corner-hover-effects */
.glow{position:relative;isolation:isolate;}
.glow::before{
  content:"";position:absolute;inset:0;border-radius:inherit;
  background:radial-gradient(420px circle at var(--mx,50%) var(--my,50%),rgba(79,209,255,.13),transparent 42%);
  opacity:0;transition:opacity .45s var(--ease);
  pointer-events:none;z-index:-1;
}
.glow:hover::before{opacity:1;}

/* scroll reveal */
.reveal{opacity:0;transform:translateY(28px);transition:opacity .8s var(--ease),transform .8s var(--ease);}
.reveal.is-in{opacity:1;transform:none;}

/* wind-blown text — adapted from gsap-wind-blown-text */
.fly{position:relative;}
.fly-char{will-change:transform,opacity;}

/* ==========================================================================
   HERO
   3D drifting columns adapted from vertical-auto-slider-up-down-3d-animate
   Typed heading adapted from typed-header
   ========================================================================== */
.hero{
  position:relative;
  min-height:100vh;
  min-height:100svh;
  display:grid;align-items:center;
  overflow:hidden;
  padding-block:clamp(7rem,14vh,10rem) clamp(5rem,10vh,7rem);
}

.hero__bg{position:absolute;inset:0;perspective:1100px;overflow:hidden;}
.hero__cols{
  --cols:5;
  position:absolute;
  top:-30%;left:-18%;
  width:140%;height:170%;
  display:grid;
  grid-template-columns:repeat(var(--cols),1fr);
  gap:.55rem;
  transform:rotateX(44deg) rotateY(15deg) rotate(-21deg) translate3d(-1em,3em,4em);
  transform-style:preserve-3d;
  transform-origin:50% 50%;
  opacity:.42;
  -webkit-mask-image:radial-gradient(120% 80% at 50% 40%,#000 20%,transparent 78%);
  mask-image:radial-gradient(120% 80% at 50% 40%,#000 20%,transparent 78%);
}
/* no flex gap here on purpose: the -50% loop keyframe is only seamless when
   every cell contributes an identical height + spacing, so spacing is margin */
.hero__col{display:flex;flex-direction:column;}
.hero__col > i{
  display:block;width:100%;aspect-ratio:1;margin-bottom:.55rem;
  background-size:cover;background-position:center;
  border-radius:10px;
  border:1px solid rgba(255,255,255,.06);
}
.hero__col--up{animation:colUp 44s linear infinite;}
.hero__col--down{animation:colDown 44s linear infinite;}
.hero__col:nth-child(2){padding-top:3.5rem;}
.hero__col:nth-child(4){padding-top:6rem;}
.hero__col:nth-child(5){padding-top:2rem;}
@keyframes colUp{from{transform:translateY(0);}to{transform:translateY(-50%);}}
@keyframes colDown{from{transform:translateY(-50%);}to{transform:translateY(0);}}
/* the hero keeps 50 image cells animating; parking them once the hero is off
   screen takes that work off every other section's frame budget */
.hero__cols.is-parked .hero__col{animation-play-state:paused;}

.hero__veil{
  position:absolute;inset:0;
  background:
    radial-gradient(85% 60% at 22% 45%,rgba(6,7,10,.94) 20%,rgba(6,7,10,.55) 60%,transparent 100%),
    linear-gradient(180deg,rgba(6,7,10,.85) 0%,transparent 22%,transparent 62%,var(--void) 100%);
}
.hero__grid{
  position:absolute;inset:0;
  background-image:
    linear-gradient(rgba(79,209,255,.045) 1px,transparent 1px),
    linear-gradient(90deg,rgba(79,209,255,.045) 1px,transparent 1px);
  background-size:64px 64px;
  -webkit-mask-image:radial-gradient(90% 70% at 30% 50%,#000,transparent 75%);
  mask-image:radial-gradient(90% 70% at 30% 50%,#000,transparent 75%);
}

.hero__inner{
  position:relative;z-index:2;
  width:100%;max-width:var(--maxw);
  margin-inline:auto;padding-inline:var(--pad);
}

.hero__name{
  font-family:var(--ff-display);
  font-size:clamp(2.9rem,1rem + 11.5vw,9.5rem);
  font-weight:700;line-height:.9;letter-spacing:-.045em;
  margin:.7rem 0 1.1rem;
  text-wrap:balance;
}

.hero__role{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.5ch;
  font-family:var(--ff-display);
  font-size:clamp(1.05rem,.85rem + 1.15vw,1.85rem);
  font-weight:500;letter-spacing:-.015em;
  color:var(--dim);
  margin-bottom:1.35rem;
}
.hero__roleSwap{
  color:var(--cyan);
  position:relative;
  font-family:var(--ff-mono);
  font-size:.86em;
}
.hero__roleSwap::after{
  content:"";display:inline-block;
  width:.55ch;height:1em;margin-left:.12ch;
  background:var(--cyan);vertical-align:-.12em;
  animation:caret .9s step-end infinite;
}
@keyframes caret{0%,100%{opacity:1;}50%{opacity:0;}}

.hero__blurb{
  max-width:46ch;color:var(--dim);
  margin-bottom:2.1rem;
  text-wrap:pretty;
}

.hero__actions{display:flex;flex-wrap:wrap;gap:.8rem;margin-bottom:clamp(2.5rem,5vw,3.5rem);}

.hero__meta{
  display:flex;flex-wrap:wrap;gap:clamp(1.1rem,3vw,2.75rem);
  padding-top:1.5rem;border-top:1px solid var(--hair);
  max-width:52rem;
}
.hero__meta li{display:flex;flex-direction:column;gap:.15rem;}
.hero__meta b{
  font-family:var(--ff-mono);font-size:.82rem;font-weight:500;
  color:var(--text);letter-spacing:.02em;
}
.hero__meta span{font-size:.76rem;color:var(--faint);}

.hero__cue{
  position:absolute;bottom:1.75rem;left:50%;transform:translateX(-50%);
  z-index:2;display:flex;flex-direction:column;align-items:center;gap:.5rem;
  font-family:var(--ff-mono);font-size:.64rem;letter-spacing:.28em;text-transform:uppercase;
  color:var(--faint);
  transition:color .3s;
}
.hero__cue:hover{color:var(--cyan);}
.hero__cue i{
  width:1px;height:38px;
  background:linear-gradient(180deg,var(--cyan),transparent);
  animation:cue 2s var(--ease) infinite;
}
@keyframes cue{0%{opacity:0;transform:scaleY(.2);transform-origin:top;}45%{opacity:1;}100%{opacity:0;transform:scaleY(1);transform-origin:bottom;}}

/* ==========================================================================
   ABOUT
   ========================================================================== */
.about{
  display:grid;
  grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:clamp(1.5rem,3.5vw,3.25rem);
  align-items:start;
}
.about__card{
  background:var(--raised);border:1px solid var(--hair);border-radius:var(--r);
  padding:clamp(1.4rem,3vw,2.6rem);
  transition:border-color .4s;
}
.about__card:hover{border-color:var(--hair-2);}
.about__lead{
  font-family:var(--ff-display);
  font-size:clamp(1.2rem,.95rem + 1.15vw,1.75rem);
  font-weight:500;line-height:1.35;letter-spacing:-.02em;
  color:var(--text);margin-bottom:1.35rem;text-wrap:balance;
}
.about__card p{color:var(--dim);margin-bottom:1.1rem;text-wrap:pretty;}
.about__facts{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:1.1rem;margin-top:1.9rem;padding-top:1.6rem;border-top:1px solid var(--hair);
}
.about__facts li{display:flex;flex-direction:column;gap:.2rem;}
.about__facts b{
  font-family:var(--ff-mono);font-size:.63rem;font-weight:500;
  letter-spacing:.2em;text-transform:uppercase;color:var(--cyan);
}
.about__facts span{font-size:.86rem;color:var(--text);}

.about__side{display:flex;flex-direction:column;gap:1rem;}
.portrait{
  position:relative;border-radius:var(--r);overflow:hidden;
  border:1px solid var(--hair);background:var(--raised);
}
.portrait img{width:100%;aspect-ratio:4/5;object-fit:cover;transition:transform .9s var(--ease);}
.portrait:hover img{transform:scale(1.04);}
.portrait figcaption{
  position:absolute;left:0;right:0;bottom:0;
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:1rem 1.1rem;
  background:linear-gradient(180deg,transparent,rgba(6,7,10,.92));
  font-family:var(--ff-mono);font-size:.66rem;letter-spacing:.16em;
}
.portrait figcaption span{color:var(--text);}
.portrait figcaption i{color:var(--cyan);font-style:normal;}

.counters{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.7rem;}
.counter{
  background:var(--raised);border:1px solid var(--hair);border-radius:12px;
  padding:1rem 1.05rem;transition:border-color .4s;
}
.counter:hover{border-color:var(--cyan-35);}
.counter b{
  display:block;font-family:var(--ff-display);
  font-size:clamp(1.35rem,1.1rem + .9vw,1.85rem);font-weight:600;letter-spacing:-.03em;
  color:var(--cyan);line-height:1.1;
}
.counter span{font-size:.7rem;color:var(--faint);letter-spacing:.02em;}

/* ==========================================================================
   HORIZONTAL TIMELINE — full-bleed stage panels
   Active/inactive language from the `timeline` reference, rotated 90 degrees.
   No blur filter anywhere in here on purpose: 12 simultaneously blurred
   elements were the whole reason the old version dropped frames.
   ========================================================================== */
.tl{position:relative;background:var(--surface);}
.tl::before,.tl::after{
  content:"";position:absolute;left:0;right:0;height:12rem;z-index:3;pointer-events:none;
}
.tl::before{top:0;background:linear-gradient(180deg,var(--void),transparent);}
.tl::after{bottom:0;background:linear-gradient(0deg,var(--void),transparent);}

/* Bounded by .tl__pin (100svh) rather than by .tl (6000px+). Blurring a
   6810px-tall layer meant ~10 megapixels through a 22px blur on every frame,
   against the 1 megapixel that is actually on screen. That was the Firefox
   stall: Gecko re-rasterises filtered surfaces far more eagerly than Blink. */
.tl__bg{position:absolute;inset:0;overflow:hidden;z-index:0;}
.tl__pin > .secHead,
.tl__pin > .tl__viewport,
.tl__pin > .tl__rail{position:relative;z-index:1;}
.tl__bgLayer{
  position:absolute;inset:-6%;
  background-size:cover;background-position:center;
  opacity:0;
  /* boosted, not muted: this reads as the active photo bled across the whole
     section. Blur is the single most expensive filter and Firefox is much more
     sensitive to the radius than Chrome, so this is as small as it can be and
     still look like a wash rather than a photograph. */
  filter:blur(22px) saturate(1.5) brightness(1.4);
  will-change:opacity;
  transition:opacity 1s var(--ease);
}
.tl__bgLayer.is-on{opacity:.58;}
.tl__bgVeil{
  position:absolute;inset:0;
  background:radial-gradient(70% 60% at 50% 46%,rgba(8,10,15,.42),rgba(6,7,10,.9) 78%);
}

.tl__pin{
  position:sticky;top:0;
  height:100vh;height:100svh;
  display:flex;flex-direction:column;
  overflow:hidden;
  padding-block:clamp(4.5rem,10vh,6.5rem) clamp(1.25rem,2.5vh,2rem);
  z-index:2;
}

.tl__hint{display:inline-flex;align-items:center;gap:.55rem;}
.tl__hint::after{
  content:"";width:26px;height:1px;background:var(--cyan);
  animation:hintSlide 1.9s var(--ease) infinite;
}
@keyframes hintSlide{0%{transform:translateX(-6px);opacity:.25;}50%{opacity:1;}100%{transform:translateX(8px);opacity:.25;}}

.tl__viewport{
  flex:1;min-height:0;
  display:flex;align-items:center;
  overflow:hidden;
}
.tl__track{
  --panel-w:min(1080px,84vw);
  /* top-aligned, not centred: panels differ in height, and centring them left
     each panel's image at a different y as you scrolled across */
  display:flex;align-items:flex-start;
  gap:clamp(1.5rem,4vw,4rem);
  padding-inline:calc(50vw - (var(--panel-w) / 2));
}

.tl__panel{
  flex:0 0 var(--panel-w);width:var(--panel-w);
  display:grid;
  grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
  gap:clamp(1.25rem,3vw,3rem);
  /* start, not center: centring let each panel's image float to a different
     height depending on how long its copy was */
  align-items:start;
  opacity:.16;
  transform:scale(.92);
  /* scale from the top edge, otherwise each depth state pulls its panel's
     image to a different height and the row of images looks ragged */
  transform-origin:top center;
  transition:opacity .55s var(--ease),transform .55s var(--ease);
}
.tl__panel.is-near{opacity:.34;transform:scale(.955);}
.tl__panel.is-active{opacity:1;transform:none;}

.tl__media{
  position:relative;
  border-radius:16px;overflow:hidden;
  border:1px solid var(--hair);
  background:var(--raised);
  aspect-ratio:4/3;
  transition:border-color .55s var(--ease),box-shadow .55s var(--ease);
}
.tl__media img{width:100%;height:100%;object-fit:cover;transform:scale(1.07);transition:transform 1.3s var(--ease);}
.tl__panel.is-active .tl__media{
  border-color:var(--cyan-35);
  box-shadow:0 40px 90px -40px rgba(0,0,0,.95),0 0 0 1px var(--cyan-20);
}
.tl__panel.is-active .tl__media img{transform:scale(1);}

.tl__body{position:relative;}
.tl__big{
  position:absolute;top:-.46em;left:-.05em;z-index:0;
  font-family:var(--ff-display);font-weight:700;
  font-size:clamp(5rem,13vw,12rem);line-height:.78;letter-spacing:-.06em;
  color:transparent;
  -webkit-text-stroke:1px rgba(79,209,255,.18);
  pointer-events:none;user-select:none;
  opacity:0;transform:translateY(20px);
  transition:opacity .7s var(--ease),transform .7s var(--ease);
}
.tl__panel.is-active .tl__big{opacity:1;transform:none;}

.tl__body > *:not(.tl__big){
  position:relative;z-index:1;
  opacity:0;transform:translateY(16px);
  transition:opacity .5s var(--ease),transform .5s var(--ease);
}
.tl__panel.is-active .tl__body > *:not(.tl__big){opacity:1;transform:none;}
.tl__panel.is-active .tl__era{transition-delay:.06s;}
.tl__panel.is-active .tl__title{transition-delay:.12s;}
.tl__panel.is-active .tl__org{transition-delay:.17s;}
.tl__panel.is-active .tl__desc{transition-delay:.22s;}
.tl__panel.is-active .chip{transition-delay:.27s;}

.tl__era{
  font-family:var(--ff-mono);font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--cyan);margin-bottom:.7rem;
  padding-left:.75rem;border-left:2px solid var(--cyan);
}
.tl__title{
  font-family:var(--ff-display);
  font-size:clamp(1.5rem,1.1rem + 1.7vw,2.7rem);
  font-weight:600;letter-spacing:-.032em;line-height:1.08;
  margin-bottom:.5rem;text-wrap:balance;
}
.tl__org{
  font-family:var(--ff-mono);font-size:.78rem;letter-spacing:.01em;
  color:var(--faint);margin-bottom:1.05rem;
}
.tl__desc{
  font-size:clamp(.88rem,.85rem + .18vw,1rem);line-height:1.65;color:var(--dim);
  margin-bottom:1.35rem;max-width:46ch;text-wrap:pretty;
}
.tl__panel .chip{display:inline-block;}

/* node rail */
.tl__rail{
  position:relative;
  padding-inline:var(--pad);
  max-width:var(--maxw);width:100%;margin-inline:auto;
  padding-top:clamp(1rem,2.4vh,1.75rem);
}
.tl__spine{
  position:absolute;
  left:var(--pad);top:calc(clamp(1rem,2.4vh,1.75rem) + 5px);
  height:1px;width:0;
  background:linear-gradient(90deg,var(--cyan),var(--mint));
  box-shadow:0 0 12px var(--cyan-35);
  z-index:1;
}
.tl__nodes{
  position:relative;z-index:2;
  display:flex;justify-content:space-between;align-items:flex-start;
  gap:.25rem;
}
.tl__nodes::before{
  content:"";position:absolute;
  left:0;right:0;top:5px;height:1px;
  background:var(--hair-2);z-index:-1;
}
.tl__node{
  display:flex;flex-direction:column;align-items:center;gap:.6rem;
  padding:0 .15rem;background:none;border:0;cursor:pointer;
}
.tl__node::before{
  content:"";
  width:11px;height:11px;border-radius:50%;
  background:var(--surface);
  border:1px solid var(--hair-2);
  transition:transform .45s var(--ease),background-color .45s,border-color .45s,box-shadow .45s;
}
/* passed years read as passed without competing with the glowing current one */
.tl__node.is-past::before{background:rgba(79,209,255,.32);border-color:rgba(79,209,255,.4);}
.tl__node.is-on::before{
  transform:scale(1.75);
  background:var(--cyan);border-color:var(--cyan);
  box-shadow:0 0 0 6px rgba(79,209,255,.13),0 0 20px var(--cyan);
}
.tl__node span{
  font-family:var(--ff-mono);font-size:.6rem;letter-spacing:.1em;
  color:var(--faint);opacity:.5;white-space:nowrap;
  transition:color .35s,opacity .35s,transform .35s var(--ease);
}
.tl__node.is-on span{color:var(--cyan);opacity:1;transform:translateY(2px);}
.tl__node:hover span{opacity:1;}

/* ==========================================================================
   IMAGE GALLERY (awards + certifications)
   Native scroll-snap underneath, so it swipes with JS off. JS layers the
   arrows, dots, counter, and the lightbox on top.
   ========================================================================== */
.gal{
  position:relative;
  border-radius:12px;overflow:hidden;
  border:1px solid var(--hair);
  background:var(--surface);
  margin-bottom:1.1rem;
}
.gal__track{
  display:flex;
  overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
}
.gal__track::-webkit-scrollbar{display:none;}
.gal__shot{
  flex:0 0 100%;scroll-snap-align:center;
  display:block;padding:0;border:0;background:none;
  line-height:0;cursor:zoom-in;
}
.gal__shot img{
  width:100%;aspect-ratio:4/3;object-fit:cover;
  transition:transform .8s var(--ease);
}
.gal__shot:hover img{transform:scale(1.035);}

.gal__arrow{
  position:absolute;top:50%;transform:translateY(-50%);
  width:32px;height:32px;border-radius:50%;
  display:grid;place-items:center;
  background:rgba(6,7,10,.74);
  border:1px solid var(--hair-2);
  color:var(--text);font-size:1.05rem;line-height:1;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  opacity:0;transition:opacity .3s,background-color .3s,border-color .3s,color .3s;
  z-index:3;
}
.gal:hover .gal__arrow,.gal__arrow:focus-visible{opacity:1;}
.gal__arrow--prev{left:8px;}
.gal__arrow--next{right:8px;}
.gal__arrow:hover{background:var(--cyan);color:var(--void);border-color:var(--cyan);}
.gal__arrow[disabled]{opacity:0 !important;pointer-events:none;}

.gal__dots{
  position:absolute;left:0;right:0;bottom:9px;z-index:3;
  display:flex;justify-content:center;gap:5px;pointer-events:none;
}
.gal__dot{
  width:5px;height:5px;border-radius:99px;
  background:rgba(255,255,255,.38);
  transition:background-color .3s,width .3s var(--ease);
}
.gal__dot.is-on{background:var(--cyan);width:15px;}

.gal__count{
  position:absolute;top:9px;right:9px;z-index:3;
  font-family:var(--ff-mono);font-size:.6rem;letter-spacing:.08em;
  color:var(--dim);
  background:rgba(6,7,10,.74);border:1px solid var(--hair);
  padding:2px 7px;border-radius:99px;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}

.gal--single .gal__arrow,
.gal--single .gal__dots,
.gal--single .gal__count{display:none;}

/* ==========================================================================
   LIGHTBOX
   ========================================================================== */
.lb{
  position:fixed;inset:0;z-index:600;
  background:rgba(4,5,8,.94);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  display:grid;place-items:center;
  padding:clamp(1rem,4vw,3rem);
  opacity:0;transition:opacity .3s var(--ease);
}
.lb[hidden]{display:none;}
.lb.is-open{opacity:1;}
.lb__stage{
  display:flex;flex-direction:column;align-items:center;gap:.9rem;
  max-width:min(1200px,92vw);
}
.lb__stage img{
  max-width:100%;max-height:76vh;object-fit:contain;
  border-radius:12px;border:1px solid var(--hair-2);
  background:var(--surface);
}
.lb__stage figcaption{
  font-family:var(--ff-mono);font-size:.7rem;letter-spacing:.06em;
  color:var(--dim);text-align:center;max-width:60ch;
}
.lb__close,.lb__arrow{
  position:absolute;
  border-radius:50%;
  border:1px solid var(--hair-2);
  background:rgba(255,255,255,.045);
  color:var(--text);
  display:grid;place-items:center;line-height:1;
  transition:background-color .3s,color .3s,border-color .3s;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
.lb__close:hover,.lb__arrow:hover{background:var(--cyan);color:var(--void);border-color:var(--cyan);}
.lb__close{
  top:clamp(.75rem,2vw,1.5rem);right:clamp(.75rem,2vw,1.5rem);
  width:44px;height:44px;font-size:1.5rem;
}
.lb__arrow{
  top:50%;transform:translateY(-50%);
  width:48px;height:48px;font-size:1.6rem;
}
.lb__arrow--prev{left:clamp(.5rem,2vw,1.75rem);}
.lb__arrow--next{right:clamp(.5rem,2vw,1.75rem);}
.lb__arrow[hidden]{display:none;}

/* ==========================================================================
   PROJECTS — parallax depth cards
   Adapted from parallax-depth-cards (Vue original ported to vanilla)
   ========================================================================== */
.tilts{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,290px),1fr));
  gap:clamp(.9rem,2vw,1.5rem);
}
.tilt{perspective:900px;}
.tilt__inner{
  position:relative;
  height:clamp(330px,38vw,420px);
  border-radius:var(--r);overflow:hidden;
  background:var(--raised);
  border:1px solid var(--hair);
  transform-style:preserve-3d;
  transition:transform .9s var(--ease),box-shadow .9s var(--ease),border-color .5s;
}
.tilt:hover .tilt__inner{
  transition:transform .12s linear,box-shadow .9s var(--ease),border-color .5s;
  border-color:var(--cyan-35);
  box-shadow:0 34px 74px -30px rgba(0,0,0,.95),0 0 0 1px var(--cyan-20);
}
.tilt__bg{
  position:absolute;top:-22px;left:-22px;
  width:calc(100% + 44px);height:calc(100% + 44px);
  background-size:cover;background-position:center;
  opacity:.34;
  transition:transform .9s var(--ease),opacity 1.4s var(--ease);
  pointer-events:none;
}
.tilt:hover .tilt__bg{opacity:.58;transition:transform .12s linear,opacity 1.4s var(--ease);}
.tilt__shine{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(420px circle at var(--mx,50%) var(--my,50%),rgba(255,255,255,.10),transparent 45%);
  opacity:0;transition:opacity .5s var(--ease);
}
.tilt:hover .tilt__shine{opacity:1;}
.tilt__body{
  position:absolute;left:0;right:0;bottom:0;
  padding:clamp(1.1rem,2vw,1.6rem);
}
.tilt__body::before{
  content:"";position:absolute;inset:-60% 0 0 0;z-index:-1;
  background:linear-gradient(180deg,transparent,rgba(6,7,10,.86) 45%,rgba(6,7,10,.97));
}
.tilt__tag{
  font-family:var(--ff-mono);font-size:.63rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--cyan);margin-bottom:.6rem;
}
.tilt__title{
  font-family:var(--ff-display);
  font-size:clamp(1.2rem,1rem + .8vw,1.6rem);
  font-weight:600;letter-spacing:-.025em;line-height:1.15;
  margin-bottom:.55rem;text-wrap:balance;
}
.tilt__desc{
  font-size:.84rem;line-height:1.55;color:var(--dim);
  opacity:0;max-height:0;overflow:hidden;
  transition:opacity .55s .1s var(--ease),max-height .55s var(--ease);
  text-wrap:pretty;
}
.tilt:hover .tilt__desc{opacity:1;max-height:11rem;}
.tilt__award{
  font-family:var(--ff-mono);font-size:.7rem;letter-spacing:.05em;
  color:var(--mint);
  /* collapsed by height, not pushed down by a percentage translate: a
     percentage of a short body is too small to clear the line */
  opacity:0;max-height:0;margin-top:0;overflow:hidden;
  transition:opacity .5s .05s var(--ease),max-height .5s var(--ease),margin-top .5s var(--ease);
}
.tilt:hover .tilt__award{opacity:1;max-height:4rem;margin-top:.85rem;}

/* ==========================================================================
   HONORS — shared spotlight grid
   Adapted from magical-hover-effect-w-tutorial. The 1px padding is what
   leaves the glowing rim once the content plate sits on top.
   ========================================================================== */
.spot{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,265px),1fr));
  gap:8px;
  align-items:stretch;
}
.spot:hover > .spot__card::after{opacity:1;}
.spot__card{
  position:relative;
  border-radius:12px;
  background:rgba(255,255,255,.085);
  padding:1px;
}
.spot__card::before,.spot__card::after{
  content:"";position:absolute;inset:0;border-radius:inherit;
  opacity:0;transition:opacity .5s;pointer-events:none;
}
.spot__card::before{
  background:radial-gradient(720px circle at var(--mx,50%) var(--my,50%),rgba(79,209,255,.08),transparent 40%);
  z-index:3;
}
.spot__card:hover::before{opacity:1;}
.spot__card::after{
  background:radial-gradient(480px circle at var(--mx,50%) var(--my,50%),rgba(79,209,255,.55),transparent 40%);
  z-index:1;
}
.spot__content{
  position:relative;z-index:2;
  border-radius:11px;background:var(--raised);
  display:flex;flex-direction:column;height:100%;
  padding:clamp(1rem,2vw,1.35rem);
  min-height:180px;
}
.spot__content .gal{margin-bottom:1rem;}
.spot__year{
  font-family:var(--ff-mono);font-size:.63rem;letter-spacing:.2em;
  color:var(--faint);margin-bottom:.6rem;
}
.spot__title{
  font-family:var(--ff-display);
  font-size:1.02rem;font-weight:600;letter-spacing:-.02em;line-height:1.25;
  margin-bottom:.4rem;text-wrap:balance;
}
.spot__desc{font-size:.79rem;color:var(--dim);line-height:1.5;flex:1;text-wrap:pretty;}
.spot__rank{
  margin-top:1rem;padding-top:.8rem;border-top:1px solid var(--hair);
  font-family:var(--ff-mono);font-size:.75rem;letter-spacing:.04em;
  color:var(--cyan);
}
.spot__card--quiet .spot__rank{color:var(--faint);}

/* ==========================================================================
   ARSENAL — skills tape + scroll-lit word list
   Tape is a marquee; word list adapted from css-scroll-timeline-word-highlight
   ========================================================================== */
.tape{
  overflow:hidden;
  border-block:1px solid var(--hair);
  padding-block:clamp(.9rem,2vw,1.3rem);
  margin-block:clamp(1.5rem,4vw,3rem) 0;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
}
.tape__row{display:flex;width:max-content;animation:tapeRun 52s linear infinite;}
.tape__set{display:flex;align-items:center;flex:0 0 auto;}
.tape__set span{
  font-family:var(--ff-display);
  font-size:clamp(1.05rem,.85rem + .8vw,1.75rem);
  font-weight:600;letter-spacing:-.022em;
  color:var(--dim);white-space:nowrap;
  padding-inline:clamp(.85rem,2vw,1.6rem);
  transition:color .3s;
}
.tape__set span:hover{color:var(--cyan);}
.tape__set i{
  width:5px;height:5px;border-radius:50%;
  background:var(--cyan);opacity:.45;flex:0 0 auto;
}
@keyframes tapeRun{from{transform:translate3d(0,0,0);}to{transform:translate3d(-50%,0,0);}}

/* Rebuilt to match css-scroll-timeline-word-highlight: the list is its own
   scroll container with proximity snap, which is what actually keeps the lead
   level with the lit term, and the brightening is a CSS view() timeline rather
   than a per-frame JS handler. */
/* the closing half-viewport belongs to the section, not the list, so the
   sticky lead lets go exactly as the last term passes the centre line */
.word{position:relative;margin-top:clamp(3rem,9vh,7rem);padding-bottom:calc(50vh - .65em);padding-bottom:calc(50vh - .5lh);}
.word__inner{
  display:flex;justify-content:center;
  gap:.4ch;
  padding-inline:var(--pad);
  font-family:var(--ff-display);
  font-size:clamp(1.15rem,.7rem + 2.4vw,2.9rem);
  font-weight:600;letter-spacing:-.03em;line-height:1.3;
}
.word__lead{
  position:sticky;
  top:calc(50vh - .65em);
  top:calc(50vh - .5lh);
  height:-moz-fit-content;height:fit-content;
  font:inherit;color:var(--faint);white-space:nowrap;
}
.word__list{padding-top:calc(50vh - .65em);padding-top:calc(50vh - .5lh);padding-bottom:0;}
.word__list li{
  scroll-snap-align:center;
  color:var(--text);opacity:.14;
  transition:opacity .4s var(--ease),color .4s var(--ease);
}

/* where the browser can drive this itself, it does, and the JS stays out */
@supports (animation-timeline:view()){
  .word__list li{
    animation:wordLit linear both;
    animation-timeline:view();
    animation-range:cover calc(50% - 1lh) calc(50% + 1lh);
    transition:none;
  }
  @keyframes wordLit{
    0%{opacity:.14;color:var(--text);}
    50%{opacity:1;color:var(--cyan);}
    100%{opacity:.14;color:var(--text);}
  }
}
.word__list li.is-lit{opacity:1;color:var(--cyan);}
.word__list li.is-near{opacity:.42;}

/* terminal */
.term{
  margin-top:clamp(2.5rem,6vw,4.5rem);
  background:#080b10;
  border:1px solid var(--hair);border-radius:var(--r);
  overflow:hidden;font-family:var(--ff-mono);
  transition:border-color .4s;
}
.term:hover{border-color:var(--hair-2);}
.term__bar{
  display:flex;align-items:center;gap:.42rem;
  padding:.75rem 1rem;border-bottom:1px solid var(--hair);
  background:rgba(255,255,255,.022);
}
.term__bar i{width:9px;height:9px;border-radius:50%;background:#28313f;}
.term__bar i:nth-child(1){background:#3a2029;}
.term__bar i:nth-child(2){background:#3a3320;}
.term__bar i:nth-child(3){background:#1e3630;}
.term__bar span{margin-left:.7rem;font-size:.68rem;color:var(--faint);letter-spacing:.02em;}
.term__body{padding:clamp(1.1rem,2.2vw,1.6rem);display:grid;gap:.85rem;}
.term__body p{
  display:grid;grid-template-columns:8rem minmax(0,1fr);
  gap:1rem;align-items:baseline;
  font-size:.775rem;line-height:1.65;
}
.term__body b{color:var(--cyan);font-weight:500;letter-spacing:.02em;}
.term__body b::before{content:"$ ";opacity:.45;}
.term__body span{color:var(--dim);}

/* ==========================================================================
   CERTIFICATIONS
   The 3D turn-in reveal is what survives from css-only-image-cube-grid-gallery;
   the faces became flat cards because a rotating face cannot hold a carousel.
   ========================================================================== */
.certs{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,285px),1fr));
  gap:clamp(.8rem,1.6vw,1.15rem);
  perspective:1400px;
}
.cert{
  background:var(--raised);
  border:1px solid var(--hair);
  border-radius:14px;overflow:hidden;
  transform-origin:center bottom;
  transition:border-color .4s,transform .5s var(--ease),box-shadow .5s var(--ease);
}
.cert:hover{
  border-color:var(--cyan-35);
  transform:translateY(-4px);
  box-shadow:0 28px 60px -30px rgba(0,0,0,.92);
}
.cert .gal{
  margin:0;border:0;border-bottom:1px solid var(--hair);
  border-radius:0;background:var(--surface);
}
.cert__body{padding:clamp(1rem,2vw,1.3rem);}
.cert__title{
  font-family:var(--ff-display);
  font-size:1rem;font-weight:600;letter-spacing:-.015em;line-height:1.25;
  margin-bottom:.3rem;text-wrap:balance;
}
.cert__issuer{font-size:.82rem;color:var(--dim);}
.cert__meta{
  font-family:var(--ff-mono);font-size:.65rem;letter-spacing:.12em;
  color:var(--cyan);margin-top:.7rem;text-transform:uppercase;
}
.cert.turnIn{opacity:0;transform:rotateX(-72deg);}
.cert.turnIn.is-in{
  opacity:1;transform:none;
  transition:opacity .7s var(--ease),transform .7s var(--ease);
}

/* ==========================================================================
   CONTACT + FOOTER
   ========================================================================== */
.contact{background:var(--surface);border-top:1px solid var(--hair);}
.contact__big{
  font-family:var(--ff-display);
  font-size:clamp(1.7rem,.9rem + 4.6vw,4.25rem);
  font-weight:600;letter-spacing:-.04em;line-height:1.04;
  max-width:17ch;
  margin-bottom:clamp(2rem,4.5vw,3.25rem);
  text-wrap:balance;
}
.contact__grid{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,245px),1fr));
  gap:.7rem;
}
.contact__card{
  display:flex;flex-direction:column;gap:.45rem;
  padding:1.25rem 1.35rem;
  background:var(--raised);border:1px solid var(--hair);border-radius:12px;
  transition:border-color .4s,transform .4s var(--ease),background-color .4s;
}
a.contact__card:hover{border-color:var(--cyan-35);transform:translateY(-3px);}
.contact__k{
  font-family:var(--ff-mono);font-size:.62rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--faint);
}
.contact__v{font-size:.92rem;color:var(--text);word-break:break-word;}
a.contact__card:hover .contact__v{color:var(--cyan);}
.contact__card--cta{background:rgba(79,209,255,.07);border-color:var(--cyan-35);}
.contact__card--cta .contact__v{color:var(--cyan);}

.foot{border-top:1px solid var(--hair);padding-block:2.25rem;background:var(--void);}
.foot__inner{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:.75rem 1.5rem;
}
.foot__name{
  font-family:var(--ff-display);font-weight:600;letter-spacing:.14em;font-size:.85rem;
}
.foot__meta,.foot__year{
  font-family:var(--ff-mono);font-size:.68rem;letter-spacing:.06em;color:var(--faint);
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

/* --- pointer capability gates ------------------------------------------- */
@media (hover:none),(pointer:coarse){
  .glow::before,.tilt__shine,.spot__card::before,.spot__card::after{display:none;}
  .tilt__desc{opacity:1;max-height:11rem;}
  .tilt__award{opacity:1;max-height:4rem;margin-top:.85rem;}
  .tilt__bg{opacity:.5;}
  .gal__arrow{opacity:1;}
  body.cursor-on{cursor:auto;}
  body.cursor-on .cursor{display:none;}
}

/* --- <= 1180px ----------------------------------------------------------- */
@media (max-width:1180px){
  .hero__cols{--cols:4;}
  .tl__track{--panel-w:min(920px,88vw);}
}

/* --- <= 1024px ----------------------------------------------------------- */
@media (max-width:1024px){
  .about{grid-template-columns:minmax(0,1fr);}
  .about__side{
    display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
    gap:1rem;align-items:start;
  }
  .counters{grid-template-columns:repeat(2,minmax(0,1fr));align-content:start;}
}

/* --- <= 900px : timeline panel stacks ------------------------------------ */
@media (max-width:900px){
  .tl__panel{
    grid-template-columns:minmax(0,1fr);
    gap:clamp(1rem,2.5vw,1.5rem);
    align-content:center;
  }
  .tl__media{aspect-ratio:16/9;}
  .tl__big{font-size:clamp(4rem,16vw,7rem);top:-.4em;}
}

/* --- <= 860px ------------------------------------------------------------ */
@media (max-width:860px){
  .hero__cols{--cols:3;transform:rotateX(38deg) rotateY(12deg) rotate(-17deg) translate3d(0,2em,2em);}
  .term__body p{grid-template-columns:minmax(0,1fr);gap:.15rem;}
}

/* --- <= 767px : nav drawer + timeline becomes a swipe carousel ----------- */
@media (max-width:767px){
  .nav__burger{display:flex;}
  .nav__links{
    position:fixed;top:0;right:0;
    width:min(320px,84vw);height:100vh;height:100svh;
    flex-direction:column;align-items:stretch;justify-content:center;
    gap:.35rem;padding:2rem 1.5rem;
    background:rgba(8,10,15,.96);
    backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
    border-left:1px solid var(--hair);
    transform:translateX(100%);
    transition:transform .45s var(--ease);
    z-index:-1;
  }
  .nav__links.is-open{transform:none;}
  .nav__links a{
    font-size:1rem;padding:.9rem 1rem;border-radius:10px;
    border-bottom:1px solid var(--hair);
  }
  .nav__cta{margin-left:0;margin-top:.75rem;border-bottom-color:var(--cyan-35);}
  .glitch::before,.glitch::after{display:none;}

  .hero__cols{--cols:2;opacity:.3;}
  .hero__meta{gap:1rem 1.75rem;}
  .hero__cue{display:none;}

  /* the pinned track is unreliable against a collapsing mobile toolbar,
     so below this width the same panels become a native swipe carousel */
  .tl__pin{position:static;height:auto;padding-block:clamp(3.5rem,9vw,5rem) 1.25rem;}
  .tl__viewport{
    overflow-x:auto;overflow-y:hidden;
    scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
  }
  .tl__viewport::-webkit-scrollbar{display:none;}
  .tl__track{
    transform:none !important;
    padding-inline:var(--pad);
    --panel-w:min(80vw,360px);
    gap:1rem;
  }
  .tl__panel{scroll-snap-align:center;opacity:.4;transform:none;}
  .tl__panel.is-near{opacity:.7;transform:none;}
  .tl__panel.is-active{transform:none;}
  .tl__big{display:none;}
  .tl__desc{font-size:.86rem;}
  .tl::before,.tl::after{height:5rem;}

  .about__side{grid-template-columns:minmax(0,1fr);}
}

/* --- <= 640px ------------------------------------------------------------ */
@media (max-width:640px){
  .word__inner{display:block;text-align:center;}
  .word__lead{
    position:static;white-space:normal;display:block;margin-bottom:.4em;
  }
  .word__list{padding-block:calc(50vh - .5lh);}
  .word__list li{scroll-snap-align:none;}


  /* twelve year labels will not fit across a phone, so the dots carry it */
  .tl__node span{display:none;}
  .tl__node{gap:0;}

  .counters{grid-template-columns:repeat(2,minmax(0,1fr));}
  .foot__inner{flex-direction:column;align-items:flex-start;}
  .lb__arrow{width:40px;height:40px;font-size:1.3rem;}
}

/* --- <= 420px ------------------------------------------------------------ */
@media (max-width:420px){
  .hero__cols{--cols:2;}
  .hero__actions{flex-direction:column;align-items:stretch;}
  .btn{justify-content:center;}
  .hero__meta{flex-direction:column;gap:.9rem;}
  .counters{grid-template-columns:minmax(0,1fr);}
  /* the gallery stays two-up here on purpose: nine full-width tiles turn this
     section into ~3000px of scrolling on a phone */
}

/* --- short viewports ----------------------------------------------------- */
@media (max-height:700px) and (min-width:768px){
  .tl__pin{padding-block:4rem .75rem;}
  .secHead--flush .secHead__sub{display:none;}
  .tl__media{aspect-ratio:16/10;}
  .tl__desc{display:none;}
}

/* ==========================================================================
   REDUCED MOTION
   Nothing is removed — motion collapses into an instant state change.
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .hero__col--up,.hero__col--down{animation:none;}
  .hero__cols{transform:none;opacity:.16;top:0;left:0;width:100%;height:100%;}
  .tape__row{animation:none;}
  .tl__panel{opacity:1;transform:none;}
  .tl__body > *:not(.tl__big){opacity:1;transform:none;}
  .tl__big{opacity:1;transform:none;}
  .tilt__desc{opacity:1;max-height:11rem;}
  .tilt__award{opacity:1;max-height:4rem;margin-top:.85rem;}
  .word__list li{opacity:1;}
  .word__list li.is-lit{color:var(--cyan);}
  .cert.turnIn{opacity:1;transform:none;}
  .reveal{opacity:1;transform:none;}
  .cursor{display:none !important;}
  body.cursor-on{cursor:auto;}
  .hero__roleSwap::after{animation:none;}
}

/* ==========================================================================
   PRINT
   ========================================================================== */
@media print{
  .boot,.cursor,.progress,.nav,.hero__bg,.hero__veil,.hero__grid,.hero__cue,
  body{background:#fff;color:#000;}
  .section{padding-block:1.5rem;}
  .tl__pin{position:static;height:auto;}
  .tl__viewport{overflow:visible;}
  .tl__track{display:block;transform:none !important;padding:0;}
  .tl__panel{
    width:100%;display:block;opacity:1;transform:none;
    page-break-inside:avoid;margin-bottom:1rem;
  }
  .tl__body > *:not(.tl__big){opacity:1;transform:none;}
  .tl__big,.tl__media,.portrait,.tilt__bg,.gal{display:none;}
  a{text-decoration:underline;}
}

/* ==========================================================================
   REVISIONS
   ========================================================================== */

/* ---------- skills ticker, now its own band between profile and timeline -- */
.tapeBand{
  position:relative;
  background:var(--surface);
  border-block:1px solid var(--hair);
}
.tapeBand .tape{margin-block:0;border-block:0;}

/* ---------- more colour across the page ---------------------------------- */
#about    .secHead__num{color:var(--cyan);}
#timeline .secHead__num{color:var(--mint);}
#work     .secHead__num{color:var(--amber);}
#life     .secHead__num{color:var(--violet);}
#honors   .secHead__num{color:var(--rose);}
#arsenal  .secHead__num{color:var(--lime);}
#certs    .secHead__num{color:var(--cyan);}
#contact  .secHead__num{color:var(--mint);}

.progress i{background:linear-gradient(90deg,var(--cyan),var(--violet) 45%,var(--mint));}

.counters .counter:nth-child(1) b{color:var(--cyan);}
.counters .counter:nth-child(2) b{color:var(--mint);}
.counters .counter:nth-child(3) b{color:var(--amber);}
.counters .counter:nth-child(4) b{color:var(--violet);}

.about__facts li:nth-child(1) b{color:var(--cyan);}
.about__facts li:nth-child(2) b{color:var(--mint);}
.about__facts li:nth-child(3) b{color:var(--amber);}
.about__facts li:nth-child(4) b{color:var(--violet);}

.term__body p:nth-child(1) b{color:var(--cyan);}
.term__body p:nth-child(2) b{color:var(--mint);}
.term__body p:nth-child(3) b{color:var(--amber);}
.term__body p:nth-child(4) b{color:var(--violet);}
.term__body p:nth-child(5) b{color:var(--rose);}
.term__body p:nth-child(6) b{color:var(--lime);}

.spot__card:nth-child(6n+1) .spot__rank{color:var(--cyan);}
.spot__card:nth-child(6n+2) .spot__rank{color:var(--mint);}
.spot__card:nth-child(6n+3) .spot__rank{color:var(--amber);}
.spot__card:nth-child(6n+4) .spot__rank{color:var(--violet);}
.spot__card:nth-child(6n+5) .spot__rank{color:var(--rose);}
.spot__card:nth-child(6n+6) .spot__rank{color:var(--lime);}

.certs .cert:nth-child(6n+1) .cert__meta{color:var(--cyan);}
.certs .cert:nth-child(6n+2) .cert__meta{color:var(--mint);}
.certs .cert:nth-child(6n+3) .cert__meta{color:var(--amber);}
.certs .cert:nth-child(6n+4) .cert__meta{color:var(--violet);}
.certs .cert:nth-child(6n+5) .cert__meta{color:var(--rose);}
.certs .cert:nth-child(6n+6) .cert__meta{color:var(--lime);}

.tape__set i:nth-of-type(6n+1){background:var(--cyan);}
.tape__set i:nth-of-type(6n+2){background:var(--mint);}
.tape__set i:nth-of-type(6n+3){background:var(--amber);}
.tape__set i:nth-of-type(6n+4){background:var(--violet);}
.tape__set i:nth-of-type(6n+5){background:var(--rose);}
.tape__set i:nth-of-type(6n+6){background:var(--lime);}
.tape__set span:nth-of-type(6n+1):hover{color:var(--cyan);}
.tape__set span:nth-of-type(6n+2):hover{color:var(--mint);}
.tape__set span:nth-of-type(6n+3):hover{color:var(--amber);}
.tape__set span:nth-of-type(6n+4):hover{color:var(--violet);}
.tape__set span:nth-of-type(6n+5):hover{color:var(--rose);}
.tape__set span:nth-of-type(6n+6):hover{color:var(--lime);}

/* ---------- timeline panels take their category colour ------------------- */
.tl__panel{--cat:#4fd1ff;--cat-a:rgba(79,209,255,.38);--cat-b:rgba(79,209,255,.20);}

.tl__era{color:var(--cat);border-left-color:var(--cat);}
.tl__big{-webkit-text-stroke:1px var(--cat-b);}
.tl__panel.is-active .tl__media{
  border-color:var(--cat-a);
  box-shadow:0 40px 90px -40px rgba(0,0,0,.95),0 0 0 1px var(--cat-b);
}

/* ---------- node rail: one node per year, plus the travelling pip -------- */
.tl__pip{
  position:absolute;
  top:calc(clamp(1rem,2.4vh,1.75rem) + 5.5px);
  left:0;
  width:13px;height:13px;
  margin-left:-6.5px;margin-top:-6.5px;
  border-radius:50%;
  background:var(--pip,var(--cyan));
  box-shadow:0 0 0 5px rgba(255,255,255,.05),0 0 22px var(--pip,var(--cyan));
  z-index:4;pointer-events:none;
  will-change:transform;
}
.tl__node.is-on::before{
  /* the pip IS the current node, so the dot beneath it gets out of the way
     rather than peeking out from under one edge */
  opacity:0;
}
.tl__node.is-on span{color:var(--pip,var(--cyan));}



/* ==========================================================================
   BENTO
   Adapted from flilp-bento-hover-effect (GSAP Flip replaced by
   native grid-template interpolation)
   ========================================================================== */
.bento{
  display:grid;gap:clamp(.5rem,1vw,.85rem);
  /* width:100% matters: with aspect-ratio and a binding max-height, a block
     box with auto width derives its WIDTH from the capped height, which made
     this grid 282px narrower than every other section on the page */
  width:100%;
  aspect-ratio:16/11;max-height:min(76vh,720px);
  transition:grid-template-columns .5s var(--ease),grid-template-rows .5s var(--ease);
}
.bento.cols-3-1-1{grid-template-columns:3fr 1fr 1fr;}
.bento.cols-1-3-1{grid-template-columns:1fr 3fr 1fr;}
.bento.cols-1-1-3{grid-template-columns:1fr 1fr 3fr;}
.bento.rows-3-1-1{grid-template-rows:3fr 1fr 1fr;}
.bento.rows-1-3-1{grid-template-rows:1fr 3fr 1fr;}
.bento.rows-1-1-3{grid-template-rows:1fr 1fr 3fr;}

.bento__item{
  position:relative;overflow:hidden;
  border-radius:12px;border:1px solid var(--hair);
  background:var(--raised);
  transition:border-color .45s;
}
.bento__item img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;opacity:.72;
  transition:opacity .5s var(--ease),transform 1.1s var(--ease);
}
.bento__item::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 45%,rgba(6,7,10,.9));
  opacity:.75;transition:opacity .45s;
}
.bento__item:hover{border-color:var(--cyan-35);z-index:5;}
.bento__item:hover img{opacity:1;transform:scale(1.04);}
.bento__label{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  padding:.75rem .9rem;
  font-family:var(--ff-mono);font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text);
  opacity:0;transform:translateY(6px);
  transition:opacity .4s var(--ease),transform .4s var(--ease);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.bento__item:hover .bento__label{opacity:1;transform:none;}

.bento__item:nth-child(6n+1):hover{border-color:var(--cyan);}
.bento__item:nth-child(6n+2):hover{border-color:var(--mint);}
.bento__item:nth-child(6n+3):hover{border-color:var(--amber);}
.bento__item:nth-child(6n+4):hover{border-color:var(--violet);}
.bento__item:nth-child(6n+5):hover{border-color:var(--rose);}
.bento__item:nth-child(6n+6):hover{border-color:var(--lime);}

/* ==========================================================================
   FIREFOX SCROLL COST
   Only a handful of panels can ever be on screen, but all twelve were being
   painted on every frame of horizontal travel. Hiding the far ones takes them
   out of paint entirely while leaving the layout (and therefore the measured
   panel centres) exactly as it was.
   ========================================================================== */
.tl__panel.is-far{visibility:hidden;}

/* the ticker keeps animating a 7000px row even when it is nowhere near the
   viewport, which costs a composite every frame all the way down the page */
.tape__row.is-parked{animation-play-state:paused;}

@media (max-width:1024px){
  .bento{aspect-ratio:4/3;}
}
@media (max-width:640px){
  .bento{aspect-ratio:auto;max-height:none;grid-template-columns:repeat(2,minmax(0,1fr)) !important;grid-template-rows:none !important;}
  .bento__item{aspect-ratio:1;}
  .bento__item--center{grid-column:span 2;aspect-ratio:16/10;}
}
@media (hover:none),(pointer:coarse){
  .bento__label{opacity:1;transform:none;}
  .bento__item::after{opacity:.85;}
}
@media (prefers-reduced-motion:reduce){
  .bento__label{opacity:1;transform:none;}
}
@media print{
  .bento{display:none !important;}
}

/* ==========================================================================
   TIMELINE CATEGORIES (professional set)
   ========================================================================== */
.chip--security{color:var(--mint);border-color:rgba(94,242,192,.35);background:rgba(94,242,192,.09);}
.chip--competition{color:var(--amber);border-color:rgba(255,184,77,.35);background:rgba(255,184,77,.09);}
.chip--leadership{color:var(--violet);border-color:rgba(167,139,250,.35);background:rgba(167,139,250,.09);}

.tl__panel[data-cat="security"]   {--cat:#5ef2c0;--cat-a:rgba(94,242,192,.38);--cat-b:rgba(94,242,192,.20);}
.tl__panel[data-cat="competition"]{--cat:#ffb84d;--cat-a:rgba(255,184,77,.38);--cat-b:rgba(255,184,77,.20);}
.tl__panel[data-cat="leadership"] {--cat:#a78bfa;--cat-a:rgba(167,139,250,.38);--cat-b:rgba(167,139,250,.20);}

/* ==========================================================================
   STYLE SWITCH
   ========================================================================== */
.secHead--flush{position:relative;}
.tl__switch{
  display:inline-flex;gap:2px;padding:3px;margin-top:1rem;
  border:1px solid var(--hair);border-radius:99px;
  background:rgba(255,255,255,.03);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
.tl__switch[hidden]{display:none;}
.tl__switch button{
  font-family:var(--ff-mono);font-size:.64rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--faint);padding:.42rem 1rem;border-radius:99px;
  transition:color .3s,background-color .3s;
}
.tl__switch button.is-on{color:var(--void);background:var(--cyan);font-weight:700;}
.tl__switch button:not(.is-on):hover{color:var(--text);background:rgba(255,255,255,.05);}
@media (min-width:900px){
  .tl__switch{position:absolute;right:var(--pad);top:.25rem;margin-top:0;}
}

.tl[data-mode="panels"] #tlCards{display:none;}
.tl[data-mode="cards"] #tlPanels{display:none;}

/* ==========================================================================
   TIMED CARDS
   Adapted from timed-cards-opening. GSAP is gone, and the timer no longer
   owns the sequence: scroll position does, so the two can never disagree.
   The timer advances by scrolling, and any manual scroll cancels it.
   ========================================================================== */
/* The sticky pin's containing block is this wrapper, not the section, so it
   has to inherit the section's reserved height or the pin unsticks after one
   viewport. The panels version has no wrapper, which is why it never hit this. */
.tlc{height:100%;}

.tlc__pin{
  position:sticky;top:0;
  height:100vh;height:100svh;
  overflow:hidden;
  display:flex;flex-direction:column;
  padding-block:clamp(4.5rem,10vh,6.5rem) clamp(1.25rem,2.5vh,2rem);
}

/* one card per entry, absolutely placed; JS moves them between the deck slot
   and full-bleed. Size is animated rather than faked with a scale because a
   2:3 card scaled to a 16:9 screen would stretch the photo. */
.tlc__cards{position:absolute;inset:0;overflow:hidden;}
.tlc__card{
  position:absolute;left:0;top:0;
  overflow:hidden;padding:0;
  border:1px solid var(--hair);
  background:var(--raised);
  cursor:pointer;
  --tlc-ease:cubic-bezier(.37,0,.63,1);   /* sine.inOut, as the original uses */
  transition:
    left .62s var(--tlc-ease),
    top .62s var(--tlc-ease),
    width .62s var(--tlc-ease),
    height .62s var(--tlc-ease),
    border-radius .62s var(--tlc-ease),
    border-color .5s var(--ease),
    opacity .45s var(--ease);
}
.tlc__card.is-instant{transition:none !important;}
.tlc__card img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;opacity:.8;
  transition:opacity .8s var(--ease);
}
.tlc__card::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 42%,rgba(6,7,10,.94));
  transition:opacity .7s var(--ease);
}
.tlc__card__meta{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  display:block;padding:.7rem .75rem;text-align:left;
  transition:opacity .45s var(--ease);
}
.tlc__card__meta i{
  display:block;font-style:normal;
  font-family:var(--ff-mono);font-size:.55rem;letter-spacing:.12em;
  color:var(--ccat,var(--cyan));margin-bottom:.22rem;
}
.tlc__card__meta b{
  display:block;font-weight:500;
  font-family:var(--ff-mono);font-size:.57rem;letter-spacing:.09em;text-transform:uppercase;
  color:var(--text);line-height:1.35;
}
.tlc__card:not(.is-open):hover{border-color:var(--ccat,var(--cyan));}
.tlc__card:not(.is-open):hover img{opacity:1;}

/* the open card is the backdrop now, so it drops its card chrome */
.tlc__card.is-open{border-color:transparent;cursor:default;}
.tlc__card.is-open::after{opacity:0;}
.tlc__card.is-open .tlc__card__meta{opacity:0;}
.tlc__card.is-open img{opacity:1;}

/* legibility wash for the open card, inside the card so it scales with it */
.tlc__card::before{
  content:"";position:absolute;inset:0;z-index:1;
  opacity:0;transition:opacity .55s var(--ease);
  background:
    linear-gradient(90deg,rgba(6,7,10,.94) 0%,rgba(6,7,10,.76) 46%,rgba(6,7,10,.28) 100%),
    linear-gradient(180deg,rgba(6,7,10,.88) 0%,transparent 26%,transparent 58%,rgba(6,7,10,.9) 100%);
}
.tlc__card.is-open::before{opacity:1;}

.tlc__timer{
  position:absolute;top:0;left:0;right:0;height:3px;z-index:50;
  background:rgba(255,255,255,.07);
}
.tlc__timer i{
  display:block;height:100%;width:0;
  background:var(--cat,var(--cyan));
  box-shadow:0 0 14px var(--cat,var(--cyan));
}

/* text and controls sit above every card */
.tlc__pin > .secHead{position:relative;z-index:40;}
.tlc__stage{
  position:relative;z-index:40;
  flex:1;min-height:0;
  display:flex;align-items:flex-end;
  width:100%;max-width:var(--maxw);margin-inline:auto;
  padding-inline:var(--pad);padding-bottom:clamp(1rem,3vh,2.25rem);
  pointer-events:none;
}
.tlc__details{--tlc-fs:1;max-width:44ch;pointer-events:auto;}
.tlc__details > *{
  opacity:0;transform:translateY(24px);
  transition:opacity .55s var(--ease),transform .55s var(--ease);
}
.tlc__details.is-in > *{opacity:1;transform:none;}
.tlc__details.is-in .tlc__title{transition-delay:.07s;}
.tlc__details.is-in .tlc__org{transition-delay:.12s;}
.tlc__details.is-in .tlc__desc{transition-delay:.17s;}
.tlc__details.is-in .chip{transition-delay:.22s;}

.tlc__era{
  font-family:var(--ff-mono);font-size:calc(.7rem * var(--tlc-fs,1));letter-spacing:.2em;text-transform:uppercase;
  color:var(--cat,var(--cyan));margin-bottom:.7rem;
  padding-left:.75rem;border-left:2px solid var(--cat,var(--cyan));
}
.tlc__title{
  font-family:var(--ff-display);
  font-size:calc(clamp(1.55rem,1rem + 2.2vw,3.3rem) * var(--tlc-fs,1));
  font-weight:600;letter-spacing:-.035em;line-height:1.04;
  margin-bottom:.5rem;text-wrap:balance;
}
.tlc__org{
  font-family:var(--ff-mono);font-size:calc(.76rem * var(--tlc-fs,1));color:var(--faint);margin-bottom:1rem;
}
.tlc__desc{
  font-size:calc(clamp(.86rem,.84rem + .16vw,.98rem) * var(--tlc-fs,1));line-height:1.6;color:var(--dim);
  margin-bottom:1.2rem;text-wrap:pretty;
  /* line count is set by JS from the room actually available, so a long entry
     on a short screen shortens instead of running up behind the heading */
  display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;
}
.tlc__details .chip{display:inline-block;}

.tlc__rail{
  position:absolute;z-index:40;
  display:flex;align-items:center;gap:clamp(.75rem,1.6vw,1.25rem);
  padding:0;
}
.tlc__count{
  display:flex;align-items:baseline;gap:.15rem;
  font-family:var(--ff-mono);flex:0 0 auto;
}
.tlc__count b{font-size:1.5rem;font-weight:700;color:var(--text);letter-spacing:-.02em;}
.tlc__count i{font-style:normal;color:var(--faint);}
.tlc__count span{font-size:.75rem;color:var(--faint);}

.tlc__arrows{display:flex;gap:.45rem;flex:0 0 auto;}
.tlc__arrows button{
  width:38px;height:38px;border-radius:50%;
  border:1px solid var(--hair-2);color:var(--dim);
  display:grid;place-items:center;font-size:1.1rem;line-height:1;
  transition:color .3s,border-color .3s,background-color .3s;
}
.tlc__arrows button:hover:not([disabled]){color:var(--void);background:var(--cyan);border-color:var(--cyan);}
.tlc__arrows button[disabled]{opacity:.3;cursor:default;}

.tlc__railInner{flex:1;min-width:0;padding:0 !important;max-width:none;margin:0;}
/* when the rail gets tight the year labels are the first thing to go */
.tlc__railInner.is-tight .tl__node span{display:none;}
.tlc__railInner.is-tight .tl__node{gap:0;}
.tlc__railInner .tl__spine{top:5px;left:0;}
.tlc__railInner .tl__pip{top:5.5px;}

/* ==========================================================================
   TIMED CARDS — responsive
   ========================================================================== */
@media (max-width:900px){
  .tlc__stage{align-items:flex-end;}
}
@media (max-width:767px){
  .tlc__pin{position:static;height:auto;padding-block:clamp(3.5rem,9vw,5rem) 1.25rem;}
  .tlc__cards{display:none;}
  .tlc__veil{display:none;}
  .tlc__timer{display:none;}
  .tlc__details > *{opacity:1;transform:none;}
  .tlc__rail{flex-wrap:wrap;gap:1rem;}
  .tlc__railInner{order:3;flex-basis:100%;}
}
@media (prefers-reduced-motion:reduce){
  .tlc__details > *{opacity:1;transform:none;}
  .tlc__timer{display:none;}
}
@media print{
  .tl__switch,.tlc{display:none !important;}
}

/* ==========================================================================
   MOBILE COST
   Firefox on Android is far more sensitive to filters and backdrop blur than
   desktop Chrome, and none of these effects earn their keep on a phone.
   ========================================================================== */
@media (max-width:767px){
  /* a full-viewport 22px blur, repainted while the section scrolls */
  .tl__bgLayer{display:none;}
  /* backdrop-filter re-renders the strip under the bar on every frame */
  .nav.is-stuck{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(6,7,10,.94);}
  .nav__links{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(8,10,15,.985);}
  .tl__switch{backdrop-filter:none;-webkit-backdrop-filter:none;}
  .gal__arrow,.gal__count{backdrop-filter:none;-webkit-backdrop-filter:none;}
  .lb{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(4,5,8,.985);}
  /* the outlined year numeral costs a text-stroke paint per panel */
  .tl__big{display:none;}
  /* headings render plainly; the character reveal is disabled in JS here */
  .fly{opacity:1;}
}

/* ==========================================================================
   MOBILE TOUCH TARGETS AND LEGIBILITY
   Measured on a 412px viewport: 33 controls came in under the 44px guideline,
   the worst being the timeline year nodes at 16x11, and 102 elements sat below
   11px. Padding grows the hit area without moving anything visually; the node
   centres are unchanged because the padding is symmetric.
   ========================================================================== */
@media (max-width:767px){
  .tl__node{padding:14px 10px;}
  .tl__nodes{gap:0;}

  .gal__arrow{width:40px;height:40px;font-size:1.2rem;}
  .gal__arrow--prev{left:6px;}
  .gal__arrow--next{right:6px;}

  .tl__switch button{padding:.7rem 1.15rem;}
  .nav__burger{width:44px;height:44px;}
  .tlc__arrows button{width:44px;height:44px;}

  .hero__cue,.foot__meta{min-height:auto;}

  /* nothing below 11px on a phone */
  .gal__count{font-size:.7rem;}
  .chip{font-size:.7rem;padding:.34rem .78rem;}
  .tilt__tag,.spot__year,.cert__meta,.bento__label,.tlc__card__meta b,.tlc__card__meta i{font-size:.7rem;}
  .secHead__num{font-size:.78rem;}
  .tl__era,.tlc__era{font-size:.74rem;}
  .term__body{font-size:.82rem;}
  .hero__meta span,.about__facts b,.contact__k{font-size:.7rem;}
}

/* ==========================================================================
   MOBILE LAYOUT CORRECTIONS
   ========================================================================== */
@media (max-width:767px){
  /* The half-viewport padding exists so a term can reach the centre line under
     the sticky heading. The heading is static here, so all it did was strand
     "I work in" above ~400px of nothing. */
  .word{padding-bottom:0;}
  .word__list{padding-block:0;}
  .word__lead{margin-bottom:.5em;}

  /* cards mode: the rail returns to normal flow under the copy */
  .tlc__rail{
    position:static;
    width:auto !important;height:auto !important;
    left:auto !important;top:auto !important;
    /* the rail is out of the pin's absolute frame here, so it needs the page
       gutter back or the counter and the last node sit on the screen edge */
    padding-inline:var(--pad) !important;
    margin-top:1.75rem;flex-wrap:wrap;row-gap:1rem;
  }
  .tlc__railInner{flex:1 1 100%;order:3;}
  .tlc__count{order:2;margin-left:auto;}
  .tlc__arrows{order:1;}
  .tlc__pin{padding-bottom:2rem;}
}

/* ==========================================================================
   ROUND OF FIXES
   ========================================================================== */
.btn__dl{width:16px;height:16px;flex:0 0 auto;transition:transform .3s var(--ease);}
.btn--primary:hover .btn__dl{transform:translateY(2px);}

@media (max-width:767px){
  /* The 44px tap padding pushed the dots 14px down while the connecting line
     stayed at 5px, so the nodes floated off their own rail. Dot centre is
     padding-top + half the dot: 14 + 5.5. */
  .tl__nodes::before{top:19.5px;}
  .tl__rail .tl__pip{top:calc(clamp(1rem,2.4vh,1.75rem) + 19.5px);}
  .tlc__railInner .tl__spine,.tlc__railInner .tl__pip{top:19.5px;}
  .tl__rail .tl__spine{top:calc(clamp(1rem,2.4vh,1.75rem) + 19.5px);}

  /* cards mode: bring the entry's photo back as a band above the copy, and
     order the pin so it reads heading, image, copy, controls */
  .tlc__pin{display:flex;flex-direction:column;}
  .tlc__pin > .secHead{order:1;}
  .tlc__cards{
    display:block;order:2;
    position:relative;inset:auto;
    height:190px;margin:0 var(--pad) 1.35rem;
    border-radius:14px;overflow:hidden;border:1px solid var(--hair);
  }
  .tlc__card{display:none;}
  .tlc__card.is-open{
    display:block;
    left:0 !important;top:0 !important;
    width:100% !important;height:100% !important;
    border-radius:14px !important;
    transition:opacity .45s var(--ease);
  }
  .tlc__card.is-open::before{opacity:.3;}
  .tlc__card.is-open img{opacity:.9;}
  .tlc__stage{order:3;}
  .tlc__rail{order:4;}

  /* fade the copy in when the arrows change entry */
  .tlc__details > *{
    opacity:0;transform:translateY(10px);
    transition:opacity .4s var(--ease),transform .4s var(--ease);
  }
  .tlc__details.is-in > *{opacity:1;transform:none;}

  /* the counter was running past the right edge */
  .tlc__count{margin-left:auto;padding-right:2px;}
  .tlc__count b{font-size:1.25rem;}
}
