/* janetlee.me — Sketchbook */

:root {
  --paper: #FAFAF7;
  --ink: #1B1B1B;
  --ink-soft: #4C4C48;
  --pen: #2442C9;
  --pen-dark: #16298A;
  --peach: #FFC2A3;
  --tape: color-mix(in srgb, var(--peach) 75%, transparent);
  --wash: #EEF0FA;
  --white: #FFFFFF;
  --on-pen: #FFFFFF;
  --link: var(--pen);

  --sans: 'Instrument Sans', system-ui, sans-serif;
  --hand: 'Reenie Beanie', cursive;

  --gutter: clamp(20px, 4vw, 48px);
  --max: 1240px;
  --section-gap: clamp(96px, 11vw, 168px);

  --lift: 0 2px 4px rgba(27, 27, 27, 0.08), 0 12px 28px rgba(27, 27, 27, 0.10);
}

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

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 19px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }

h1, h2, h3, p, figure, ul { margin: 0; }

a { color: var(--link); text-underline-offset: 4px; text-decoration-thickness: 2px; }
a:hover { color: var(--pen-dark); }
a:focus-visible, button:focus-visible { outline: 3px solid var(--pen); outline-offset: 3px; }

::selection { background: var(--peach); color: var(--ink); }

mark { background: var(--peach); color: inherit; padding: 0 4px; }

.page { overflow-x: clip; }

.wrap { max-width: var(--max); margin: 0 auto; padding-inline: var(--gutter); }

.hand { font-family: var(--hand); font-weight: 400; color: var(--pen); }

/* ---------- Header ---------- */
.site-header {
  padding-block: 28px;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 12px 24px;
}
.site-header .nav { margin-left: auto; }
@media (max-width: 600px) {
  .site-header .palette { order: 1; margin-left: auto; }
  .site-header .nav { order: 2; flex-basis: 100%; margin-left: 0; }
}
.wordmark { font-size: 40px; line-height: 1; text-decoration: none; }
.nav { display: flex; flex-wrap: wrap; gap: 8px 28px; font-weight: 600; font-size: 17px; }
.nav a { color: var(--ink); text-decoration: none; padding-block: 8px; }
.nav a:hover { color: var(--link); }

/* ---------- Hero ---------- */
.hero {
  padding-top: clamp(32px, 5vw, 72px);
  padding-bottom: var(--section-gap);
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 56px clamp(40px, 6vw, 96px);
}
.hero__text { flex: 1 1 400px; min-width: 0; }
.hero__title {
  font-size: clamp(88px, 12vw, 184px);
  line-height: 0.82;
  letter-spacing: -0.01em;
}
.hero__lede {
  margin-top: 32px;
  font-size: clamp(22px, 2.2vw, 30px);
  line-height: 1.3;
  max-width: 21em;
  font-weight: 500;
  letter-spacing: -0.01em;
}
.hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 36px; }

.button {
  display: inline-flex; align-items: center; min-height: 52px; padding: 0 26px;
  background: var(--pen); color: var(--on-pen); text-decoration: none; font-weight: 700;
  transition: background-color 160ms ease-out, transform 160ms ease-out;
}
.button:hover { background: var(--pen-dark); color: var(--on-pen); }
.button:active { transform: translateY(1px); }
.text-link { display: inline-flex; align-items: center; min-height: 52px; padding: 0 8px; font-weight: 700; }

/* Polaroid */
.polaroid { flex: 0 1 360px; min-width: 260px; position: relative; }
.polaroid__frame { background: none; padding: 0; }
.polaroid__frame img {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover; object-position: 50% 30%;
  border-radius: 999px 999px 14px 14px;
}
.polaroid__note { margin-top: 14px; font-size: 34px; line-height: 1; text-align: center; }
.polaroid__aside {
  position: absolute; left: -138px; bottom: 120px;
  display: flex; flex-direction: column; align-items: flex-end;
  font-size: 32px; line-height: 1;
}

.tape { position: absolute; height: 34px; width: 120px; background: var(--tape); }
.tape--photo { top: -14px; left: 38%; transform: rotate(4deg); }

/* ---------- Section basics ---------- */
.section-title {
  font-size: clamp(40px, 5vw, 72px);
  line-height: 1;
  letter-spacing: -0.035em;
  font-weight: 700;
}
.section-note { margin: 10px 0 clamp(48px, 6vw, 80px); font-size: 34px; line-height: 1.1; }
.item-title {
  font-size: clamp(26px, 2.6vw, 38px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 700;
}
.meta { margin: 6px 0 14px; color: var(--ink-soft); }
.measure { max-width: 36em; }
.measure-s { max-width: 30em; }

.margin-note { font-size: 32px; line-height: 1.05; }
.tilt-l { transform: rotate(-2deg); }
.tilt-r { transform: rotate(2deg); }
.tilt-l2 { transform: rotate(-1.5deg); }

/* ---------- Work ---------- */
.work { padding-bottom: var(--section-gap); }
.work__list { display: flex; flex-direction: column; gap: clamp(56px, 6vw, 88px); }
.job { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 24px clamp(32px, 5vw, 72px); }
.doodle { flex: 0 0 auto; color: var(--pen); }
.job__body { flex: 1 1 520px; min-width: 0; }
.job .margin-note { flex: 0 1 220px; }

/* ---------- Side projects ---------- */
.side { background: var(--wash); }
.side__inner { padding-block: clamp(88px, 10vw, 160px); }
.side__intro { margin: 18px 0 clamp(56px, 7vw, 96px); max-width: 32em; font-size: clamp(20px, 1.8vw, 24px); }

.taped { position: relative; }
.taped img, .taped video, .taped .pdemo {
  display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover;
  background: var(--white); padding: 12px;
  box-shadow: var(--lift);
}
.taped--passage .pdemo { display: flex; flex-direction: column; transform: rotate(-1deg); }
.taped--site video { transform: rotate(1.2deg); }

/* Passage live demo: a small re-creation of the app's screen, lines arriving in real time */
.pdemo { display: flex; flex-direction: column; }
.pdemo__bar, .pdemo__cols { background: #15161B; color: #F2F0EA; }
.pdemo__bar { display: flex; align-items: center; gap: 8px; padding: 12px 16px 4px; font: 600 13px/1 'Instrument Sans', sans-serif; }
.pdemo__dot { width: 8px; height: 8px; border-radius: 50%; background: #4FB286; }
.pdemo__status { margin-left: auto; font-weight: 500; color: #A9A79F; }
.pdemo.is-translating .pdemo__dot { background: #F7836E; }
.pdemo__cols { flex: 1 1 0; min-height: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; padding: 10px 16px 14px; }
.pdemo__col { display: flex; flex-direction: column; min-height: 0; }
.pdemo__panel {
  flex: 1 1 0; min-height: 0; overflow: hidden; border-radius: 8px; background: #000;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 8px; padding: 14px;
  font-family: Lora, Georgia, 'Songti SC', serif; font-size: clamp(12px, 1.05vw, 16px); line-height: 1.3;
}
.pdemo__col:nth-child(2) .pdemo__panel { box-shadow: inset 0 0 0 1.5px #F7836E; }
.pdemo__panel p { margin: 0; color: rgba(242, 240, 234, 0.5); transition: opacity 400ms ease-out, transform 400ms ease-out, color 400ms ease-out; }
.pdemo__panel p:last-child, .pdemo__panel p.is-current { color: #FFFFFF; font-weight: 600; }
.pdemo__label { margin: 8px 0 0; font: 600 12px/1 'Instrument Sans', sans-serif; color: #D8D6CE; }
.pdemo.is-live .pdemo__panel p { display: none; }
.pdemo.is-live .pdemo__panel p.is-shown { display: block; }
.pdemo.is-live .pdemo__panel p:last-child { color: rgba(242, 240, 234, 0.5); font-weight: 400; }
.pdemo.is-live .pdemo__panel p.is-current { color: #FFFFFF; font-weight: 600; }
.pdemo__panel p.is-entering { opacity: 0; transform: translateY(6px); }
.pdemo .w { opacity: 0; transition: opacity 160ms ease-out; }
.pdemo .w.is-on { opacity: 1; }
.pdemo.is-fading .pdemo__panel p { opacity: 0; }
@media (max-width: 640px) {
  .taped .pdemo { aspect-ratio: 4 / 5; }
}
.tape--a { top: -12px; left: 8%; width: 110px; height: 32px; transform: rotate(-6deg); }
.tape--b { top: -10px; right: 8%; width: 110px; height: 32px; transform: rotate(5deg); }
.tape--c { top: -12px; left: 44%; width: 110px; height: 32px; transform: rotate(-3deg); }

.passage { display: flex; flex-wrap: wrap; align-items: center; gap: 40px clamp(40px, 5vw, 72px); }
.taped--passage { flex: 3 1 560px; min-width: 0; }
.passage__text { flex: 2 1 340px; min-width: 0; }
.passage__text p { margin-top: 12px; }
.passage__text .quote-note { margin-top: 20px; font-size: 34px; line-height: 1.05; }

.side__pair {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: 56px clamp(40px, 5vw, 72px);
  margin-top: clamp(80px, 9vw, 136px);
}
.side__site { flex: 3 1 520px; min-width: 0; }
.side__site .item-title { margin-top: 32px; }
.side__site p { margin-top: 12px; }
.side__app { flex: 2 1 320px; min-width: 0; }
.side__app p { margin-top: 12px; }
.side__app .margin-note { margin-top: 20px; }

/* ---------- About ---------- */
.about { padding-block: var(--section-gap); }
.about__top { display: flex; flex-wrap: wrap; gap: 32px clamp(40px, 6vw, 96px); }
.about__top .section-title { flex: 1 1 320px; }
.about__text { flex: 2 1 520px; min-width: 0; max-width: 36em; display: flex; flex-direction: column; gap: 18px; }

.loves {
  list-style: none; padding: 0;
  margin-top: clamp(56px, 7vw, 96px);
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 40px 24px;
  color: var(--pen);
}
.loves li { display: flex; flex-direction: column; align-items: center; gap: 4px; width: 150px; text-align: center; }
.loves span { font-size: 34px; line-height: 1; }

/* ---------- Footer ---------- */
.site-footer { background: var(--pen); color: var(--on-pen); }
.site-footer__inner {
  padding-top: clamp(80px, 10vw, 150px); padding-bottom: 40px;
  display: flex; flex-direction: column; gap: clamp(40px, 5vw, 72px);
}
.site-footer__thanks { color: var(--on-pen); font-size: clamp(64px, 9vw, 140px); line-height: 0.85; }
.site-footer a { color: var(--on-pen); }
.site-footer a:hover { opacity: .75; }
.site-footer a:focus-visible { outline-color: var(--on-pen); }
.site-footer__email {
  font-size: clamp(24px, 3.4vw, 48px); font-weight: 700; letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}
.site-footer__links { display: flex; flex-wrap: wrap; gap: 8px 28px; font-weight: 600; }
.site-footer__links a { padding-block: 8px; }
.site-footer ::selection { background: var(--peach); color: var(--ink); }

/* ---------- Narrow screens ---------- */
@media (max-width: 900px) {
  .polaroid { flex-basis: 100%; max-width: 380px; margin-inline: auto; }
  .polaroid__aside {
    position: static; flex-direction: row-reverse; align-items: center; justify-content: center;
    gap: 8px; margin-top: 24px;
  }
  .polaroid__aside svg { display: none; }
  .job .margin-note { flex-basis: 100%; }
  .doodle { width: 110px; height: 110px; }
}

@media (max-width: 480px) {
  body { font-size: 18px; }
  .site-header { padding-block: 20px; }
  .nav { gap: 4px 20px; font-size: 16px; }
  .loves { justify-content: center; gap: 32px 8px; }
  .loves li { width: 45%; }
  .tape { width: 88px; height: 28px; }
}

/* ---------- Loader (hook) ----------
   Hidden unless <html> has .is-loading (set by the inline head script).
   The character SVG and its keyframes get dropped into #loader. */
.loader {
  position: fixed; inset: 0; z-index: 100;
  display: none; place-items: center;
  background: var(--paper);
  opacity: 1;
  transition: opacity 400ms ease-out, visibility 0s linear 400ms;
}
.is-loading .loader { display: grid; animation: loader-failsafe 0s linear 5.5s forwards; }
.loader:empty { display: none !important; }
.loader.is-done { opacity: 0; visibility: hidden; pointer-events: none; }
/* If site.js never runs, the overlay still gets out of the way. */
@keyframes loader-failsafe { to { opacity: 0; visibility: hidden; pointer-events: none; } }
@media (prefers-reduced-motion: reduce) { .loader { display: none !important; } }

/* ---------- Loader: mini-Janet shoots hoops (one 3s loop on first visit) ---------- */
.loader{color:var(--pen)}
.loader__inner{display:flex;flex-direction:column;align-items:center;gap:12px;width:min(728px,92vw)}
.loader__scene{width:100%;height:auto;overflow:visible}
.jl svg *{transform-box:view-box}
.jl{--ease:cubic-bezier(.45,.05,.35,1)}
.c-air{animation:c-air 3s linear infinite}
.c-turn{animation:c-turn 3s var(--ease) infinite}
.c-legs{transform-origin:0 0;animation:c-legs 3s var(--ease) infinite}
.c-upper{animation:c-upper 3s var(--ease) infinite}
.c-thighL{transform-origin:-8px -62px;animation:c-thighL 3s var(--ease) infinite}
.c-shinL{transform-origin:-8px -32px;animation:c-shinL 3s var(--ease) infinite}
.c-thighR{transform-origin:8px -62px;animation:c-thighR 3s var(--ease) infinite}
.c-shinR{transform-origin:8px -32px;animation:c-shinR 3s var(--ease) infinite}
.c-armL{transform-origin:-15px -100px;animation:c-armL 3s var(--ease) infinite}
.c-foreL{transform-origin:-15px -79px;animation:c-foreL 3s var(--ease) infinite}
.c-armR{transform-origin:15px -100px;animation:c-armR 3s var(--ease) infinite}
.c-foreR{transform-origin:15px -79px;animation:c-foreR 3s var(--ease) infinite}
.c-head{transform-origin:0 -108px;animation:c-head 3s var(--ease) infinite}
.c-sway{transform-origin:0 -160px;animation:c-sway 3s var(--ease) infinite}
.c-blink{transform-origin:0 -129px;animation:c-blink 3s linear infinite}
.c-grin{animation:c-grin 3s linear infinite}
.c-smile{animation:c-smile 3s linear infinite}
.c-shadow{transform-origin:150px 292px;animation:c-shadow 3s var(--ease) infinite}
.b-x{animation:b-x 3s linear infinite}
.b-y{animation:b-y 3s linear infinite}
.b-o{animation:b-o 3s linear infinite}
.b-s{transform-origin:0 0;animation:b-s .75s linear infinite}
.h-net{transform-origin:410px 132px;animation:h-net 3s ease-out infinite}
.h-swish{animation:h-swish 3s ease-out infinite}
.jl-cc{grid-area:1/1;animation:jl-cc 6s steps(1,end) infinite}

@keyframes c-air{
0%,47%{transform:translateY(0);animation-timing-function:cubic-bezier(.2,.7,.4,1)}
55%{transform:translateY(-48px);animation-timing-function:cubic-bezier(.5,0,.8,.4)}
65%{transform:translateY(0)}
76%{transform:translateY(0);animation-timing-function:cubic-bezier(.2,.7,.4,1)}
81%{transform:translateY(-22px);animation-timing-function:cubic-bezier(.5,0,.8,.4)}
86%,100%{transform:translateY(0)}}
@keyframes c-turn{0%,78%{transform:scaleX(1)}82%{transform:scaleX(-1)}86%,100%{transform:scaleX(1)}}
@keyframes c-legs{
0%,10%,20%,30%,40%{transform:scaleY(1)}
5%,15%,25%,35%{transform:scaleY(.96)}
47%{transform:scaleY(.85)}
53%{transform:scaleY(1.04)}
58%{transform:scaleY(.9)}
65%{transform:scaleY(.84)}
70%,76%{transform:scaleY(1)}
79%{transform:scaleY(.9)}
83%{transform:scaleY(.92)}
86%{transform:scaleY(.86)}
90%,100%{transform:scaleY(1)}}
@keyframes c-upper{
0%,10%,20%,30%,40%{transform:translateY(0) rotate(0)}
5%,15%,25%,35%{transform:translateY(3px) rotate(2deg)}
47%{transform:translateY(9px) rotate(0)}
53%{transform:translateY(-2px)}
58%{transform:translateY(6px)}
65%{transform:translateY(10px)}
70%,76%{transform:translateY(0)}
79%{transform:translateY(6px)}
83%{transform:translateY(5px)}
86%{transform:translateY(9px)}
90%,100%{transform:translateY(0)}}
@keyframes c-thighL{0%,40%{transform:rotate(0)}5%,15%,25%,35%{transform:rotate(4deg)}47%{transform:rotate(10deg)}55%{transform:rotate(-3deg)}60%{transform:rotate(16deg)}65%{transform:rotate(8deg)}70%,76%{transform:rotate(0)}82%{transform:rotate(18deg)}86%{transform:rotate(8deg)}90%,100%{transform:rotate(0)}}
@keyframes c-shinL{0%,40%{transform:rotate(0)}5%,15%,25%,35%{transform:rotate(-6deg)}47%{transform:rotate(-16deg)}55%{transform:rotate(0)}60%{transform:rotate(-34deg)}65%{transform:rotate(-14deg)}70%,76%{transform:rotate(0)}82%{transform:rotate(-38deg)}86%{transform:rotate(-12deg)}90%,100%{transform:rotate(0)}}
@keyframes c-thighR{0%,40%{transform:rotate(0)}5%,15%,25%,35%{transform:rotate(-4deg)}47%{transform:rotate(-10deg)}55%{transform:rotate(3deg)}60%{transform:rotate(-16deg)}65%{transform:rotate(-8deg)}70%,76%{transform:rotate(0)}82%{transform:rotate(-18deg)}86%{transform:rotate(-8deg)}90%,100%{transform:rotate(0)}}
@keyframes c-shinR{0%,40%{transform:rotate(0)}5%,15%,25%,35%{transform:rotate(6deg)}47%{transform:rotate(16deg)}55%{transform:rotate(0)}60%{transform:rotate(34deg)}65%{transform:rotate(14deg)}70%,76%{transform:rotate(0)}82%{transform:rotate(38deg)}86%{transform:rotate(12deg)}90%,100%{transform:rotate(0)}}
@keyframes c-armR{
0%,10%,20%,30%,40%{transform:rotate(-32deg)}
5%,15%,25%,35%{transform:rotate(-18deg)}
47%{transform:rotate(-140deg)}55%{transform:rotate(-172deg)}64%{transform:rotate(-160deg)}71%{transform:rotate(-120deg)}
77%{transform:rotate(-14deg)}81%{transform:rotate(-150deg)}86%{transform:rotate(-138deg)}93%{transform:rotate(-16deg)}100%{transform:rotate(-32deg)}}
@keyframes c-foreR{
0%,10%,20%,30%,40%{transform:rotate(30deg)}
5%,15%,25%,35%{transform:rotate(4deg)}
47%{transform:rotate(20deg)}55%{transform:rotate(4deg)}64%{transform:rotate(40deg)}71%{transform:rotate(30deg)}
77%{transform:rotate(14deg)}81%{transform:rotate(46deg)}86%{transform:rotate(56deg)}93%{transform:rotate(12deg)}100%{transform:rotate(30deg)}}
@keyframes c-armL{
0%,40%{transform:rotate(16deg)}
47%{transform:rotate(60deg)}55%{transform:rotate(150deg)}64%{transform:rotate(118deg)}71%{transform:rotate(40deg)}
77%{transform:rotate(10deg)}81%{transform:rotate(150deg)}86%{transform:rotate(138deg)}93%{transform:rotate(10deg)}100%{transform:rotate(16deg)}}
@keyframes c-foreL{
0%,40%{transform:rotate(-18deg)}
47%{transform:rotate(-110deg)}55%{transform:rotate(-20deg)}64%{transform:rotate(-24deg)}71%{transform:rotate(-14deg)}
77%{transform:rotate(-10deg)}81%{transform:rotate(-46deg)}86%{transform:rotate(-56deg)}93%{transform:rotate(-10deg)}100%{transform:rotate(-18deg)}}
@keyframes c-head{0%,5%,15%,25%,35%{transform:rotate(0)}10%,30%{transform:rotate(-3deg)}20%{transform:rotate(3deg)}40%{transform:rotate(0)}48%{transform:rotate(-4deg)}58%{transform:rotate(7deg)}72%{transform:rotate(9deg)}79%{transform:rotate(-7deg)}86%{transform:rotate(6deg)}93%,100%{transform:rotate(0)}}
@keyframes c-sway{0%,10%,20%,30%,40%{transform:rotate(0)}5%,25%{transform:rotate(1.5deg)}15%,35%{transform:rotate(-1.5deg)}47%{transform:translateY(-2px)}55%{transform:translateY(6px) rotate(-2deg)}61%{transform:translateY(-5px) rotate(2deg)}66%{transform:translateY(2px)}70%,77%{transform:translateY(0)}81%{transform:translateY(5px) rotate(4deg)}85%{transform:translateY(-3px) rotate(-3deg)}89%{transform:translateY(1px) rotate(1deg)}93%,100%{transform:translateY(0) rotate(0)}}
@keyframes c-blink{0%,30%,33%,88%,91%,100%{transform:scaleY(1)}31.5%,89.5%{transform:scaleY(.08)}}
@keyframes c-grin{0%,74%{opacity:0}76%,92%{opacity:1}94%,100%{opacity:0}}
@keyframes c-smile{0%,74%{opacity:1}76%,92%{opacity:0}94%,100%{opacity:1}}
@keyframes c-shadow{0%,47%{transform:scale(1);opacity:.18}55%{transform:scale(.55);opacity:.07}65%,76%{transform:scale(1);opacity:.18}81%{transform:scale(.75);opacity:.1}86%,100%{transform:scale(1);opacity:.18}}

@keyframes b-x{
0%,40%{transform:translateX(181px)}
47%{transform:translateX(186px)}
55%{transform:translateX(176px)}
72%,76%{transform:translateX(410px)}
82%{transform:translateX(414px)}
87%{transform:translateX(420px)}
91%{transform:translateX(426px)}
94%{transform:translateX(440px)}
94.5%,100%{transform:translateX(181px)}}
@keyframes b-y{
0%{transform:translateY(240px);animation-timing-function:cubic-bezier(.5,0,.9,.6)}
5%{transform:translateY(279px);animation-timing-function:cubic-bezier(.1,.4,.5,1)}
10%{transform:translateY(240px);animation-timing-function:cubic-bezier(.5,0,.9,.6)}
15%{transform:translateY(279px);animation-timing-function:cubic-bezier(.1,.4,.5,1)}
20%{transform:translateY(240px);animation-timing-function:cubic-bezier(.5,0,.9,.6)}
25%{transform:translateY(279px);animation-timing-function:cubic-bezier(.1,.4,.5,1)}
30%{transform:translateY(240px);animation-timing-function:cubic-bezier(.5,0,.9,.6)}
35%{transform:translateY(279px);animation-timing-function:cubic-bezier(.1,.4,.5,1)}
40%{transform:translateY(240px);animation-timing-function:ease-in-out}
47%{transform:translateY(178px);animation-timing-function:ease-out}
55%{transform:translateY(50px);animation-timing-function:cubic-bezier(.2,.6,.4,1)}
63%{transform:translateY(0px);animation-timing-function:cubic-bezier(.6,0,.8,.4)}
72%{transform:translateY(112px);animation-timing-function:linear}
76%{transform:translateY(152px);animation-timing-function:ease-in}
82%{transform:translateY(279px);animation-timing-function:ease-out}
87%{transform:translateY(248px);animation-timing-function:ease-in}
91%,94%{transform:translateY(279px)}
94.5%,100%{transform:translateY(240px)}}
@keyframes b-o{0%,91%{opacity:1}94%,96%{opacity:0}100%{opacity:1}}
@keyframes b-s{from{transform:rotate(0)}to{transform:rotate(360deg)}}
@keyframes h-net{0%,72%{transform:scale(1,1)}76%{transform:scale(.86,1.34)}80%{transform:scale(1.06,.9)}84%,100%{transform:scale(1,1)}}
@keyframes h-swish{0%,74%{opacity:0;transform:translateY(10px)}78%{opacity:1;transform:translateY(0)}90%{opacity:1;transform:translateY(-6px)}95%,100%{opacity:0;transform:translateY(-6px)}}
@keyframes jl-cc{0%{opacity:1}33.333%,100%{opacity:0}}
@media (prefers-reduced-motion: reduce){
.jl *{animation:none!important}
.jl-cc+.jl-cc,.h-swish,.c-grin{opacity:0}
}

/* ---------- Colour themes (picked in the top bar, remembered per visitor) ---------- */
:root[data-theme="cherry"] {
  --paper: #FFF8F8; --ink: #1F1415; --ink-soft: #5A4448;
  --pen: #D7263D; --pen-dark: #A81B2D; --peach: #FFC6D9; --wash: #FFEAF0;
  --on-pen: #FFFFFF; --link: #B81F33;
}
:root[data-theme="magenta"] {
  --paper: #FFF7FC; --ink: #1E0F1A; --ink-soft: #5A4552;
  --pen: #D1127A; --pen-dark: #A00C5C; --peach: #C8F53B; --wash: #F1FBD6;
  --on-pen: #FFFFFF; --link: #B30F69;
}
:root[data-theme="neon"] {
  --paper: #FFFEF5; --ink: #1F1A10; --ink-soft: #554C3A;
  --pen: #F25C05; --pen-dark: #C24700; --peach: #F3FF3D; --wash: #FFF6BF;
  --on-pen: #1F1A10; --link: #B34400;
}
body { transition: background-color 300ms ease-out, color 300ms ease-out; }

.palette {
  margin-left: 6px; padding: 2px 4px; border: 0; background: none; cursor: pointer;
  border-radius: 12px; line-height: 0; color: var(--ink);
}
.palette svg { width: 60px; height: 42px; overflow: visible; transition: transform 200ms ease-out; }
.palette:hover svg { transform: rotate(-6deg); }
.palette.is-dabbing svg { animation: palette-wiggle 420ms ease-out; }
.palette__board { fill: var(--white); stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }
.palette__hole { fill: var(--paper); stroke: currentColor; stroke-width: 1.6; }
.dab { transform-box: fill-box; transform-origin: center; transform: scale(1.18); transition: transform 240ms cubic-bezier(.3,1.6,.5,1); }
.dab.is-on { transform: scale(1.5); }
.palette:focus-visible { outline: 3px solid var(--pen); outline-offset: 2px; }
@keyframes palette-wiggle { 0% { transform: rotate(0); } 30% { transform: rotate(-10deg) scale(1.06); } 60% { transform: rotate(6deg); } 100% { transform: rotate(0); } }
@media (prefers-reduced-motion: reduce) { .palette svg, .dab { transition: none; } .palette.is-dabbing svg { animation: none; } }

.job__links { display: flex; flex-wrap: wrap; gap: 6px 24px; margin-top: 14px; font-weight: 600; font-size: 17px; }
.job__links a { padding-block: 6px; }

/* The alabaster.org clip keeps its 16:10 shape (the height attribute must not win) */
.taped video { height: auto; }


/* ---------- Project devices: straight laptops and a phone ---------- */
.device { position: relative; margin: 0; }
.laptop { filter: drop-shadow(0 14px 22px rgba(27, 27, 27, 0.14)); }
.laptop__screen { background: #1B1C22; padding: 2.4% 2.4% 2.8%; border-radius: 14px 14px 4px 4px; }
.laptop__screen > video, .laptop__screen > .pdemo {
  display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover;
  padding: 0; background: #15161B; box-shadow: none; transform: none; border-radius: 3px;
}
.laptop__screen > .pdemo { display: flex; flex-direction: column; overflow: hidden; }
.laptop__base {
  position: relative; height: 14px; margin: 0 -5%;
  background: #D6D5D0; border-radius: 2px 2px 12px 12px;
}
.laptop__base::after {
  content: ''; position: absolute; left: 50%; top: 0; width: 16%; height: 5px;
  transform: translateX(-50%); background: #BEBCB6; border-radius: 0 0 6px 6px;
}

.device--phone { width: min(240px, 60%); margin-bottom: 40px; }
.phone {
  overflow: hidden; padding: 9px; border-radius: 34px; background: #1B1C22;
  filter: drop-shadow(0 14px 22px rgba(27, 27, 27, 0.14));
}
.phone__track { display: flex; border-radius: 26px; overflow: hidden; }
.phone__screen { flex: 0 0 100%; width: 100%; height: auto; aspect-ratio: 506 / 1100; object-fit: cover; transition: transform 650ms cubic-bezier(.65,0,.35,1); }

.device--passage { flex: 3 1 560px; min-width: 0; }

.callout {
  position: absolute; z-index: 2; left: 50%; top: -60px; margin: 0;
  display: flex; align-items: flex-start; gap: 4px;
  font-size: 30px; line-height: 1; white-space: nowrap; transform: translateX(-34px) rotate(-1.5deg);
}
.callout svg { flex: 0 0 auto; margin-top: 12px; }
.device--passage { margin-top: 64px; }
@media (max-width: 640px) { .callout { display: none; } .device--passage { margin-top: 0; } }

/* ---------- Made at Princeton ---------- */
.school { padding-block: var(--section-gap) 0; }
.laptop__screen > img { display: block; width: 100%; height: auto; border-radius: 3px; }
.paths { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
.paths figure { margin: 0; }
.paths img { display: block; width: 100%; height: auto; border-radius: 6px; }
.paths figcaption { margin-top: 6px; font-size: 24px; line-height: 1.05; }
.device--dance { margin-top: 0; }
.laptop__screen > picture, .laptop__screen > picture img { display: block; width: 100%; height: auto; border-radius: 3px; }

/* ---------- Side projects: one consistent row per project ---------- */
.projects { display: flex; flex-direction: column; gap: clamp(96px, 10vw, 150px); }
.proj { display: flex; flex-wrap: wrap; align-items: center; gap: 40px clamp(40px, 5vw, 80px); }
.proj--flip { flex-direction: row-reverse; }
.proj__media { flex: 3 1 540px; min-width: 0; }
.proj__media--phone { display: flex; justify-content: center; }
.proj__media--phone .device--phone { margin-bottom: 0; }
.proj__text { flex: 2 1 320px; min-width: 0; }
.proj__text .meta { margin-top: 6px; }
.proj__text > p:not(.meta) { margin-top: 12px; }
.proj .device--passage, .proj .device--site { margin-top: 0; }
.proj .device--passage:has(.callout) { margin-top: 64px; }

/* Comfortable tap targets for text links on phones */
.job__links a { display: inline-flex; align-items: center; min-height: 44px; padding-block: 0; }
.site-footer a { display: inline-flex; align-items: center; min-height: 44px; }
@media (min-width: 901px) and (max-width: 1180px) { .hero__title { font-size: clamp(88px, 10vw, 120px); } }
.laptop__screen > picture img { aspect-ratio: 16 / 10; object-fit: cover; }

/* ---------- Passage: same laptop and three columns at every size; older lines fade out at the top instead of being cut ---------- */
.pdemo__panel { position: relative; }
.pdemo__panel::before {
  content: ""; position: absolute; z-index: 1; inset: 2px 2px auto; height: 38%;
  border-radius: 6px 6px 0 0; background: linear-gradient(#000 20%, rgba(0, 0, 0, 0)); pointer-events: none;
}
@media (max-width: 640px) {
  .laptop__screen > .pdemo { aspect-ratio: 16 / 10; }
  .pdemo__bar { padding: 7px 9px 2px; gap: 5px; font-size: 9px; }
  .pdemo__dot { width: 6px; height: 6px; }
  .pdemo__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 5px; padding: 6px 9px 8px; }
  .pdemo__panel { padding: 7px; gap: 4px; border-radius: 5px; font-size: 9.5px; line-height: 1.28; }
  .pdemo__label { margin-top: 4px; font-size: 8px; }
}

/* ---------- Phones and small tablets: work doodles sit centred above each job ---------- */
@media (max-width: 900px) {
  .job .doodle { margin-inline: auto; }
  .job .margin-note { text-wrap: balance; }
}
