/* Fonts follow Rachel Chen's system:
   body = TWK Lausanne (paid font — Inter is the free stand-in; swap --sans if you buy it),
   serif = Libre Baskerville. Logo keeps Happy Monkey from Alisha's Framer site. */
:root {
  --bg: #ffffff;
  --ink: #32404f;
  --ink-80: rgba(50, 64, 79, .88);
  --ink-55: rgba(50, 64, 79, .72);   /* muted text: dark enough to read comfortably (about 4.5:1 on white) */
  --ink-25: rgba(50, 64, 79, .36);
  --border: rgba(50, 64, 79, .12);
  --accent: #6d5bd0;
  --on-ink: #ffffff;          /* text on ink-coloured buttons/labels */
  --surface: #f3f4f6;         /* image placeholders */
  --nav-bg: rgba(255, 255, 255, .85);
  --logo: #2b2d5c;
  --wash: #ffffff;            /* hover wash on covers */
  --link-hover: #5b4fc4;
  --bubble-bg: #e9e9eb; --bubble-ink: #1a1a1a;
  --tip-bg: #e9e9eb; --tip-ink: #3b2a8a;   /* sticker notes: iOS-grey thought bubble, dark purple text */
  --cue-bg: rgba(0, 0, 0, .05); --cue-bg-hover: rgba(0, 0, 0, .1);
  --cat-ink: #2a2a2a; --cat-fill: #ffffff;
  --sweep-1: #6d5bd0; --sweep-2: #9b7cf0; --sweep-3: #c9b8ff; --sweep-4: #9fb6ff; --sweep-5: #5b7cf0;
  --sans: "Inter", "Helvetica Neue", Arial, sans-serif;
  --serif: "Libre Baskerville", Georgia, serif;
  --display: "Playfair Display", "Libre Baskerville", Georgia, serif;   /* headers */
  --ease: cubic-bezier(.22, 1, .36, 1);
  --page: 1080px;
}

:root[data-theme="dark"] {
  --accent: #a08bff;
  --bg: #121317;
  --ink: #e8eaf0;
  --ink-80: rgba(232, 234, 240, .9);
  --ink-55: rgba(232, 234, 240, .74);
  --ink-25: rgba(232, 234, 240, .4);
  --border: rgba(232, 234, 240, .12);
  --on-ink: #121317;
  --surface: #1c1e24;
  --nav-bg: rgba(18, 19, 23, .82);
  --logo: #c9c6ff;
  --wash: #000000;
  --link-hover: #b9a8ff;
  --bubble-bg: #2a2c33; --bubble-ink: #f2f3f6;
  --tip-bg: #2a2c33; --tip-ink: #d3c8ff;
  --cue-bg: rgba(255, 255, 255, .08); --cue-bg-hover: rgba(255, 255, 255, .14);
  --cat-ink: #26272e; --cat-fill: #f5f5f7;   /* night mode: a white cat with dark lines, same as by day */
  --sweep-1: #a08bff; --sweep-2: #c2b0ff; --sweep-3: #ece6ff; --sweep-4: #b9cbff; --sweep-5: #86a4ff;
  color-scheme: dark;
}

* { box-sizing: border-box; margin: 0; padding: 0; border-radius: 0; }
html { scroll-behavior: smooth; }
html.arriving-at-section { scroll-behavior: auto; }
body { background: var(--bg); color: var(--ink); font-family: var(--sans); font-size: 15px; line-height: 1.5; letter-spacing: -.01em; -webkit-font-smoothing: antialiased; overflow-x: hidden; transition: background-color .4s ease, color .4s ease; }
a { color: inherit; text-decoration: none; }
img, video { display: block; max-width: 100%; }
.label { color: var(--ink-55); font-size: 14px; }

/* ---------- NAV ---------- */
.nav { position: fixed; inset: 0 0 auto 0; z-index: 60; display: flex; justify-content: space-between; align-items: center; padding: 18px 32px; background: var(--nav-bg); backdrop-filter: blur(10px); transition: background-color .4s ease; }
.nav-logo { font-family: "Happy Monkey", var(--sans); font-size: 25px; line-height: 1; letter-spacing: .01em; color: var(--logo); }
@media (max-width: 768px) { .nav-logo { font-size: 21px; } }
/* clicking the name: letters hop up one after another */
.nav-logo .ch, .nav-links a .ch { display: inline-block; white-space: pre; }
.nav-logo.hop .ch, .nav-links a.hop .ch { animation: hop .55s cubic-bezier(.3, 1.6, .5, 1) both; animation-delay: calc(var(--i) * 28ms); }
.nav-logo:active, .nav-links a:active { scale: .97; }
@keyframes hop { 0% { translate: 0 0; } 35% { translate: 0 -9px; rotate: -4deg; } 70% { translate: 0 1px; } 100% { translate: 0 0; } }
.nav-links { display: flex; gap: 32px; font-size: 18px; color: var(--ink-80); }
@media (max-width: 768px) { .nav-links { gap: 20px; font-size: 16px; } }
.nav-links a { transition: color .2s; }
.nav-links { align-items: center; }
/* Night-mode switch, styled like Figma's Dev Mode toggle: pill track, oval knob holding  < icon >  */
.theme-switch { position: relative; width: 70px; height: 32px; padding: 0; border: 1px solid #e0b43a; border-radius: 999px; background: #f6c945; cursor: pointer; transition: background-color .35s ease, border-color .35s ease; }
.theme-switch:hover { filter: brightness(1.03); }
.theme-switch:focus-visible { outline: 2px solid var(--link-hover); outline-offset: 3px; }
.theme-switch .knob { position: absolute; top: 3px; left: 3px; width: 38px; height: 24px; border-radius: 999px; display: grid; place-items: center; background: #ffffff; color: #8a5a00; box-shadow: 0 1px 3px rgba(0,0,0,.18); transition: translate .4s cubic-bezier(.34, 1.3, .64, 1), background-color .35s ease, color .35s ease; }
.theme-switch .knob svg { display: block; width: 28px; height: 15px; }
.theme-switch .knob .moon { display: none; }
.theme-switch:active .knob { scale: .94; }
:root[data-theme="dark"] .theme-switch { background: #7b6cf0; border-color: #6a5be0; }
:root[data-theme="dark"] .theme-switch .knob { translate: 26px 0; background: #f2f3f6; color: #3b2f9e; }
:root[data-theme="dark"] .theme-switch .knob .sun { display: none; }
:root[data-theme="dark"] .theme-switch .knob .moon { display: block; }
.nav-links a:hover { color: var(--ink); }
/* "play" is handwritten in the same purple as the hello, and opens the kitty game page */
.nav-links a.nav-play { font-family: "Sacramento", cursive; font-size: 2.05em; line-height: 1; color: var(--accent); rotate: -8deg; }
.nav-links a.nav-play:hover { color: var(--accent); }

/* =========================================================
   HERO — sticker pile
   ========================================================= */
.hero { height: 180vh; position: relative; }
.hero-pin { contain: layout style; position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; --burst: 0; }

.stickers { position: absolute; inset: 0; z-index: 2; pointer-events: none; --size: clamp(96px, 20.5vmin, 200px); }
.stickers:has(.sticker:hover), .stickers:has(.sticker.is-open) { z-index: 5; }   /* a hovered note sits above the cat too */
.sticker {
  will-change: transform, opacity;
  position: absolute; left: 50%; top: 50%;
  height: calc(var(--size) * var(--k, 1));
  transform: translate(-50%, -50%)
    translate(calc(var(--x, 0px) * (1 + var(--burst) * 1.6) + var(--drag-x, 0px)),
              calc(var(--y, 0px) * (1 + var(--burst) * 1.6) + var(--drag-y, 0px)));
  translate: var(--jx, 0px) var(--jy, 0px);
  opacity: calc(1 - var(--burst) * 1.3);
  pointer-events: auto; cursor: grab; touch-action: none; user-select: none;
  --shadow: drop-shadow(1px 2px 3px rgba(0,0,0,.10)) drop-shadow(var(--sx, 0px) var(--sy, 6px) calc(var(--size) * .16) rgba(0,0,0,.09));
}
.stickers.is-dealing .sticker:not(.is-dealt) { visibility: hidden; }
.sticker.is-applied { animation: apply .34s cubic-bezier(.3, .9, .4, 1); }
.sticker.is-placing { animation: place .7s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes place { from { opacity: 0; filter: blur(4px); } to { opacity: 1; filter: none; } }
.sticker.is-dragging { scale: 1.12; cursor: grabbing; z-index: 20; --shadow: drop-shadow(2px 4px 4px rgba(0,0,0,.16)) drop-shadow(calc(var(--sx, 0px) * 2) calc(var(--sy, 6px) * 2 + 8px) calc(var(--size) * .26) rgba(0,0,0,.22)); }
.sticker:hover, .sticker.is-open { z-index: 40; }
@keyframes apply { 0% { scale: 1.14; } 45% { scale: .94; } 100% { scale: 1; } }

.sticker-art { display: block; height: 100%; width: auto; pointer-events: none; transform: rotate(calc(var(--tilt, 0deg) + var(--jr, 0deg))); filter: var(--shadow); transition: filter .16s ease-out; -webkit-user-drag: none; }
/* Placeholder SVG stickers get a white die-cut edge. Your real sticker PNGs should already have one. */
.sticker-art svg { display: block; height: 100%; width: auto; }
/* drawn stickers get the same die-cut look as the photo ones: white border, then a thin light-grey edge */
.sticker-art.placeholder { filter: drop-shadow(5px 0 0 #fff) drop-shadow(-5px 0 0 #fff) drop-shadow(0 5px 0 #fff) drop-shadow(0 -5px 0 #fff) drop-shadow(1px 0 0 #d6d6d6) drop-shadow(-1px 0 0 #d6d6d6) drop-shadow(0 1px 0 #d6d6d6) drop-shadow(0 -1px 0 #d6d6d6) var(--shadow); }
@media (hover: hover) { .sticker:not(.sticker-still):hover .sticker-art { animation: wiggle 1.4s ease-in-out infinite; } }
.sticker.is-dragging .sticker-art { animation: none; }
@keyframes wiggle { 0%, 100% { rotate: -2.5deg; } 50% { rotate: 2.5deg; } }

.sticker-note { height: auto; }
/* the note is a thought bubble: iOS grey cloud, dark purple text, two little dots trailing toward the cat */
/* the welcome note is a cloud-shaped thought bubble: scalloped edge, soft gradient, text sitting inside,
   two little bubbles trailing down toward the cat */
.sticker-note .sticker-art { position: relative; width: 18em; height: auto; padding: 2.6em 2.9em 2.7em; color: var(--tip-ink);
  font-size: min(calc(var(--size) * .1), 15px); font-weight: 500; line-height: 1.45; text-align: center; }
.sticker-note .sticker-art p { position: relative; z-index: 1; }
.sticker-note .cloud { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; z-index: 0; }
.sticker-note .dot { position: absolute; z-index: 0; border-radius: 50%; background: var(--tip-bg); box-shadow: inset 0 0 0 1.4px var(--cloud-line); }
.sticker-note .sticker-art { filter: drop-shadow(0 6px 14px rgba(40, 30, 90, .08)); }
.sticker-note .d1 { width: 1.35em; height: 1.35em; right: 13%; bottom: -.9em; }
.sticker-note .d2 { width: .75em; height: .75em; right: 6%; bottom: -2em; }
:root { --cloud-top: #ffffff; --cloud-line: rgba(109, 91, 208, .28); }
:root[data-theme="dark"] { --cloud-top: #383a42; --cloud-line: rgba(185, 168, 255, .3); }

.tip { position: absolute; top: calc(100% + 22px); left: 50%; translate: var(--tip-nudge, 0px) 0; transform: translate(-50%, 4px); width: max-content; max-width: min(16rem, 60vw); padding: 10px 14px; border-radius: 18px; background: var(--tip-bg); color: var(--tip-ink); box-shadow: 0 6px 18px rgba(0,0,0,.08); font-size: 13.5px; font-weight: 500; line-height: 1.4; text-align: center; opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .16s ease-out, transform .16s ease-out, visibility 0s linear .16s; z-index: 30; }
.tip.up { top: auto; bottom: calc(100% + 22px); transform: translate(-50%, -4px); }
/* the little thought-bubble dots between the sticker and the note */
.tip::before, .tip::after { content: ""; position: absolute; left: 50%; border-radius: 50%; background: var(--tip-bg); }
.tip::before { width: 10px; height: 10px; top: -13px; margin-left: -12px; }
.tip::after { width: 6px; height: 6px; top: -22px; margin-left: -17px; }
.tip.up::before { top: auto; bottom: -13px; }
.tip.up::after { top: auto; bottom: -22px; }
.sticker.is-open .tip { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition-delay: 0s; }
@media (hover: hover) { .sticker:not(.is-dragging):hover .tip { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition-delay: 0s; } }

/* Center lockup (placed like Gyan's): the cat, with a chat bubble beside her that does the talking */
.lockup { will-change: transform, opacity; position: absolute; left: 50%; top: 50%; z-index: 3; pointer-events: none; display: flex; flex-direction: column; align-items: center; transform: translate(-50%, -50%) scale(calc(1 - var(--burst) * .15)); opacity: calc(1 - var(--burst) * 1.6); }
.greet { position: relative; }
.cat { width: clamp(170px, 24vmin, 240px); position: relative; animation: breathe 3.4s ease-in-out infinite; }
.cat svg { display: block; width: 100%; overflow: visible; stroke: var(--cat-ink); }
.cat .cat-ground { position: absolute; inset: 0; height: 100%; stroke: var(--ink); stroke-width: 2; opacity: .45; }
.cat .cat-art { position: relative; }
.cat [fill="#fff"]:not([stroke="none"]) { fill: var(--cat-fill); }
.cat [fill="#2a2a2a"] { fill: var(--cat-ink); }
/* night mode: a white die-cut edge (like the stickers) keeps the dark tail and lines visible on the dark page */
:root[data-theme="dark"] .cat .cat-art { filter: drop-shadow(2px 0 0 var(--cat-fill)) drop-shadow(-2px 0 0 var(--cat-fill)) drop-shadow(0 2px 0 var(--cat-fill)) drop-shadow(0 -2px 0 var(--cat-fill)) drop-shadow(0 6px 12px rgba(0,0,0,.35)); }
.cat svg g { transform-box: view-box; transform-origin: 0 0; }
.cat svg g.eye-l, .cat svg g.eye-r { transform-box: fill-box; transform-origin: center; transition: scale .35s cubic-bezier(.34, 1.4, .64, 1), opacity .16s; }
.eye-wink { opacity: 0; transition: opacity .16s; }
@keyframes breathe { 50% { translate: 0 -2px; } }

/* waking up: sleepy → squint → open → big eyes, then a smile */
.eyes { opacity: 0; transition: opacity .16s ease; }
.cat.state-sleepy .eyes-sleepy, .cat.state-half .eyes-half,
.cat.state-open .eyes-round, .cat.state-big .eyes-big { opacity: 1; }
.cat svg g.eyes-big { transform-box: fill-box; transform-origin: center; }
.cat.state-big .eyes-big { animation: blink 4.6s 1.8s infinite; }
@keyframes blink { 0%, 93%, 100% { scale: 1 1; } 96% { scale: 1 .08; } }
.mouth-smile { opacity: 0; transition: opacity .2s; }
.cat.state-big .mouth-flat { opacity: 0; }
.cat.state-big .mouth-smile { opacity: 1; }
.head { transition: rotate .6s cubic-bezier(.34, 1.4, .64, 1), translate .6s cubic-bezier(.34, 1.4, .64, 1); }
.eyes-big { transition: opacity .16s ease, translate .45s cubic-bezier(.34, 1.3, .64, 1); }
.mouth-o { opacity: 0; transition: opacity .2s; }

/* ---- expressions: she reacts to what the bubble says ---- */
/* thinking: eyes drift up toward the bubble, little "o" mouth, head tilts */
.cat.state-big.expr-think .eyes-big { translate: 3px -3px; }
.cat.state-big.expr-think .head { rotate: 6deg; }
.cat.state-big.expr-think .mouth-smile { opacity: 0; }
.cat.state-big.expr-think .mouth-o { opacity: 1; }
/* focused: looking across at the work, flat mouth */
.cat.state-big.expr-focus .eyes-big { translate: 3px 1px; }
.cat.state-big.expr-focus .head { rotate: 3deg; }
.cat.state-big.expr-focus .mouth-smile { opacity: 0; }
.cat.state-big.expr-focus .mouth-flat { opacity: 1; }
/* looking down at something in her paws */
.cat.state-big.expr-down .eyes-big { translate: 0 3px; }
.cat.state-big.expr-down .head { rotate: -2deg; translate: 0 2px; }
/* happy: eyes squeeze shut into smiles */
.cat.state-big.expr-happy .eyes-big { opacity: 0; animation: none; }
.cat.state-big.expr-happy .eyes-happy { opacity: 1; }
.cat.state-big.expr-happy .head { rotate: -6deg; }
/* dreamy: heavy lids, gazing up and away */
.cat.state-big.expr-dreamy .eyes-big { opacity: 0; animation: none; }
.cat.state-big.expr-dreamy .eyes-half { opacity: 1; translate: 2px -2px; }
.cat.state-big.expr-dreamy .head { rotate: 8deg; }
.cat.state-big.expr-dreamy .mouth-smile { opacity: 0; }
.cat.state-big.expr-dreamy .mouth-flat { opacity: 1; }
.eyes-half { transition: opacity .16s ease, translate .45s ease; }
/* wink: one eye closes into a smile */
.cat.state-big.expr-wink .eye-r { opacity: 0; }
.cat.state-big.expr-wink .eye-wink { opacity: 1; }
.cat.state-big.expr-wink .head { rotate: -5deg; }
/* surprised: eyes go wide, little "o" */
.cat.state-big.expr-surprised .eye-l, .cat.state-big.expr-surprised .eye-r { scale: 1.2; }
.cat.state-big.expr-surprised .mouth-smile { opacity: 0; }
.cat.state-big.expr-surprised .mouth-o { opacity: 1; }
/* smug: half-closed eyes, small smile */
.cat.state-big.expr-smug .eyes-big { opacity: 0; animation: none; }
.cat.state-big.expr-smug .eyes-half { opacity: 1; }
.cat.state-big.expr-smug .head { rotate: -3deg; }
/* distracted by the butterfly: wide eyes that follow it (moved from script), mouth open */
.cat.state-big.expr-distracted .eye-l, .cat.state-big.expr-distracted .eye-r { scale: 1.12; }
.cat.state-big.expr-distracted .mouth-smile { opacity: 0; }
.cat.state-big.expr-distracted .mouth-o { opacity: 1; }
.cat.tracking .eyes-big { transition: opacity .16s ease; }
.cat.tracking .head { transition: none; }

/* the butterfly */
.butterfly { position: absolute; left: 0; top: 0; z-index: 4; width: 34px; height: 30px; pointer-events: none; opacity: 0; will-change: transform, opacity; }
.butterfly svg { width: 100%; height: 100%; overflow: visible; }
.butterfly .wing { transform-box: view-box; transform-origin: 0 0; animation: flap .17s ease-in-out infinite alternate; }
@keyframes flap { from { scale: 1 1; } to { scale: .22 1; } }
:root[data-theme="dark"] .butterfly svg { stroke: #e8eaf0; }
.cat.state-half .head { rotate: 2deg; }
.cat.state-big .head { rotate: -4deg; }

/* tail: the wag travels base → tip (each joint lags the one before) */
.t1 { animation: wag1 1.8s ease-in-out infinite; }
.t2 { animation: wag2 1.8s .14s ease-in-out infinite; }
.t3 { animation: wag3 1.8s .28s ease-in-out infinite; }
.cat.happy .t1, .cat.happy .t2, .cat.happy .t3 { animation-duration: .9s; }
@keyframes wag1 { 0%, 100% { rotate: -8deg; } 50% { rotate: 10deg; } }
@keyframes wag2 { 0%, 100% { rotate: -16deg; } 50% { rotate: 18deg; } }
@keyframes wag3 { 0%, 100% { rotate: -24deg; } 50% { rotate: 26deg; } }

/* chat bubble: typing dots, then the message */
.chat-bubble { position: absolute; left: calc(100% - 26px); top: 6%; min-height: 42px; display: flex; align-items: center; background: var(--bubble-bg); color: var(--bubble-ink); padding: 10px 16px; border-radius: 20px; font-size: 15px; font-weight: 500; white-space: nowrap; box-sizing: border-box; overflow: clip; overflow-clip-margin: 8px; transform-origin: 0 100%; opacity: 0; scale: .5; transition: opacity .25s, scale .45s cubic-bezier(.34, 1.56, .64, 1), background-color .4s, width .38s cubic-bezier(.22, 1, .36, 1); }
.chat-bubble > * { flex: none; }   /* the text keeps its natural width so the bubble can measure and ease to it */
.chat-bubble::before { content: ""; position: absolute; left: -5px; bottom: 0; width: 18px; height: 16px; background: var(--bubble-bg); border-bottom-right-radius: 14px; clip-path: polygon(0 100%, 100% 0, 100% 100%); transition: background-color .4s; }
.chat-bubble.on { opacity: 1; scale: 1; }
.chat-bubble .msg { display: none; }
.chat-bubble.said .typing { display: none; }
.chat-bubble.said .msg { display: inline; animation: msg-in .35s ease-out; }
@keyframes msg-in { from { opacity: 0; translate: 0 3px; } }
.typing { display: inline-flex; gap: 5px; padding: 3px 0; }
.typing i { width: 8px; height: 8px; border-radius: 50%; background: var(--ink-55); animation: dot 1.3s infinite; }
.typing i:nth-child(2) { animation-delay: .16s; } .typing i:nth-child(3) { animation-delay: .32s; }
@keyframes dot { 0%, 60%, 100% { opacity: .35; translate: 0 0; } 30% { opacity: 1; translate: 0 -3px; } }

/* the changing word: backspaced, then the next one washes in with colour */
@property --wpos { syntax: "<percentage>"; inherits: false; initial-value: 2%; }
.chat-bubble .word {
  color: transparent;
  background-image: linear-gradient(100deg, var(--bubble-ink) 0%, var(--bubble-ink) 34%, var(--sweep-1) 41%, var(--sweep-2) 46%, var(--sweep-4) 51%, var(--sweep-5) 56%, var(--bubble-ink) 64%, var(--bubble-ink) 100%);
  background-size: 300% 100%; background-position: var(--wpos) 0;
  -webkit-background-clip: text; background-clip: text;
}
/* the new word fades up into place, then a purple light glides across it */
.chat-bubble .word.washing { animation: word-in .3s cubic-bezier(.2, .7, .3, 1) both, word-sweep 1.4s .08s cubic-bezier(.45, 0, .25, 1) both; }
@keyframes word-in { from { opacity: 0; filter: blur(3px); translate: 0 4px; } }
@keyframes word-sweep { from { --wpos: 92%; } to { --wpos: 2%; } }


.scroll-cue { position: absolute; left: 50%; bottom: 28px; z-index: 3; width: 44px; height: 44px; margin-left: -22px; display: grid; place-items: center; border-radius: 50%; background: var(--cue-bg); color: var(--ink); animation: bob 2.2s ease-in-out infinite; opacity: calc(1 - var(--burst) * 6); }
.scroll-cue svg { width: 18px; }
.scroll-cue:hover { background: var(--cue-bg-hover); }
@keyframes bob { 50% { transform: translateY(5px); } }

/* =========================================================
   PAGE — Rachel-style intro + 2-column work grid
   ========================================================= */
.page { position: relative; z-index: 5; background: var(--bg); margin-top: -60vh; padding: 0 max(32px, (100vw - var(--page)) / 2); }
.intro { padding: 72px 0 0; scroll-margin-top: 40px; }
.headline { font-weight: 400; font-size: clamp(28px, 4vw, 40px); line-height: 1.25; letter-spacing: -.03em; color: var(--ink); }
/* Gradient light sweep across the work headline (left → right), then settles to ink */
@property --sweep { syntax: "<percentage>"; inherits: false; initial-value: 100%; }
.headline.sweep {
  display: inline-block;
  background-image: linear-gradient(105deg,
    var(--ink) 0%, var(--ink) 32%,
    var(--sweep-1) 39%, var(--sweep-2) 44%, var(--sweep-3) 48%, var(--sweep-4) 52%, var(--sweep-5) 57%,
    var(--ink) 65%, var(--ink) 100%);
  background-size: 320% 100%;
  background-position: var(--sweep) 0;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  opacity: 0; filter: blur(8px); translate: 0 10px;
  transition: opacity .9s var(--ease), filter .9s var(--ease), translate .9s var(--ease);
}
.headline.sweep.lit { opacity: 1; filter: none; translate: 0 0; }
/* starts moving the moment the headline is seen, then glides slowly across */
.headline.sweep.play { animation: sweep 3.8s cubic-bezier(.25, .55, .35, 1) both; }
@keyframes sweep { from { --sweep: 86%; } to { --sweep: 4%; } }
@media (prefers-reduced-motion: reduce) { .headline.sweep { opacity: 1; filter: none; translate: none; --sweep: 0%; } }
.headline.small { font-size: 28px; margin-bottom: 32px; }
.intro-cols { display: grid; grid-template-columns: auto auto; justify-content: start; gap: 12px 80px; padding: 52px 0 56px; max-width: 900px; }   /* each column as wide as its text, with a clear gap between them */
.intro-cols p:not(.label) { color: var(--ink-80); }

.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 32px 24px; }
.card { display: flex; flex-direction: column; gap: 8px; }
.thumb { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: var(--c); }
.thumb::after { content: ""; position: absolute; inset: 0; box-shadow: inset 0 0 0 1px var(--border); pointer-events: none; z-index: 2; }
.thumb::before { content: ""; position: absolute; inset: 0; background: var(--wash); opacity: 0; transition: opacity .3s ease-in-out; z-index: 1; }
.card:hover .thumb::before { opacity: .22; }
.thumb img, .thumb video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* media fades in from a blur once loaded; a tinted block pulses while it loads */
.media-fade { opacity: 0; filter: blur(6px); transition: opacity .5s ease-in-out, filter .5s ease-in-out; }
.media-fade.loaded { opacity: 1; filter: none; }
.thumb .pulse { position: absolute; inset: 0; background: var(--c); animation: pulse 2s cubic-bezier(.4, 0, .6, 1) infinite; }
.thumb.ready .pulse { display: none; }
@keyframes pulse { 50% { opacity: .5; } }
.thumb .ph { position: absolute; inset: 0; display: grid; place-items: center; font-size: 15px; font-weight: 500; color: rgba(255,255,255,.75); text-shadow: 0 1px 2px rgba(0,0,0,.08); }
.card.soon .thumb::before { display: none; }
.caption { display: flex; flex-wrap: wrap; gap: 6px; font-size: 15.5px; }
.caption .t { color: var(--ink); }
.caption .s { color: var(--ink-25); }
.caption .m { color: var(--ink-55); }

/* Reveal: Rachel fades content in from a blur */
.reveal { opacity: 0; filter: blur(6px); transform: translateY(8px); transition: opacity .7s var(--ease), filter .7s var(--ease), transform .7s var(--ease); }
.reveal.shown { opacity: 1; filter: none; transform: none; }

/* Homepage entrance, one smooth sequence as the work section scrolls in (js/main.js → introGate):
   the intro headline rises in word by word (the handwritten hello first), the Currently / Focus line follows,
   and only then do the project cards glide up. Only opacity and position animate, so it stays on the GPU.
   The hidden starting state applies only once the script has added .js-intro (and never with reduced motion). */
:root { --ease-glide: cubic-bezier(.16, 1, .3, 1); }
.js-intro .intro .hop-text .word { opacity: 0; translate: 0 .5em; transition: opacity .9s var(--ease-glide), translate 1.2s var(--ease-glide); transition-delay: calc(var(--w, 0) * 45ms); }
.js-intro .intro .intro-cols > div { opacity: 0; translate: 0 16px; transition: opacity .9s var(--ease-glide), translate 1.2s var(--ease-glide); transition-delay: calc(var(--after, 0ms) + var(--k, 0) * 110ms); }
.js-intro .intro.entered .hop-text .word, .js-intro .intro.entered .intro-cols > div { opacity: 1; translate: 0 0; }
/* the project cards: no blur (blurring big video thumbnails is what makes scrolling stutter), a longer, softer rise */
.grid .card.reveal { filter: none; transform: none; translate: 0 32px; transition: opacity 1s var(--ease-glide), translate 1.3s var(--ease-glide); }
.grid .card.reveal.shown { translate: 0 0; }

/* Custom cursor over cards (Rachel-style): a dot that opens into a typed label */
.card { cursor: none; }
.cursor-label { position: fixed; left: 0; top: 0; z-index: 100; pointer-events: none; display: flex; align-items: center; height: 26px; padding: 0 9px; background: var(--ink); color: var(--on-ink); font-size: 12.5px; font-weight: 500; white-space: nowrap; opacity: 0; scale: .4; transform-origin: 0 0; transition: opacity .18s, scale .25s cubic-bezier(.34, 1.56, .64, 1); }
.cursor-label.on { opacity: 1; scale: 1; }
.cursor-label:empty { padding: 0; width: 10px; height: 10px; }
@media (hover: none) { .cursor-label { display: none; } .card { cursor: pointer; } }

/* About */
.about { padding: 120px 0 0; }
.about-grid { display: grid; grid-template-columns: 1fr 2fr; gap: 40px; }
.about-body > p { color: var(--ink-80); margin-bottom: 14px; max-width: 520px; }
.skills { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 32px; }
.skills p:not(.label) { color: var(--ink-80); margin-top: 4px; }

/* Contact */
.contact { padding: 140px 0 40px; }
.contact-head { display: grid; gap: 14px; margin-bottom: 40px; }
.contact-head .headline { font-size: clamp(25px, 3.5vw, 35px); font-weight: 350; line-height: 1.25; }   /* same size and weight as the intro line ("hello I'm Alisha…") */
.contact-head .label { max-width: 420px; font-size: 15px; }
.contact-list { border-top: 1px solid var(--border); }
.contact-row { position: relative; display: grid; grid-template-columns: 140px 1fr auto; align-items: baseline; gap: 16px; padding: 18px 0; font-size: 18px; letter-spacing: -.01em; border-bottom: 1px solid var(--border); cursor: none; overflow: hidden; }
/* label and value are the same size — the label is just fainter */
.contact-row .label { font-size: inherit; color: var(--ink); opacity: .45; }
.contact-row .value { color: var(--ink); transition: translate .45s var(--ease), color .3s; }
.contact-row .arrow { font-size: 16px; color: var(--ink-55); transition: translate .45s var(--ease), color .3s; }
/* hover: a tint slides in from the left, the text nudges right */
.contact-row::before { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(155, 124, 240, .08), rgba(91, 124, 240, .04)); transform: scaleX(0); transform-origin: left; transition: transform .5s var(--ease); z-index: -1; }
.contact-row:hover::before { transform: scaleX(1); }
.contact-row:hover .value { translate: 10px 0; color: var(--link-hover); }
.contact-row:hover .arrow { translate: 4px -4px; color: var(--link-hover); }
.contact-foot { display: flex; justify-content: space-between; margin-top: 64px; }
.contact-foot a:hover { color: var(--ink); }
@media (max-width: 768px) {
  .contact-row { grid-template-columns: 1fr auto; padding: 18px 0; cursor: pointer; }
  .contact-row { font-size: 16px; }
  .contact-row .label { grid-column: 1 / -1; margin-bottom: -10px; }
}

/* =========================================================
   CASE STUDY — centered column
   ========================================================= */
.cs { --cs-w: 1120px; max-width: calc(var(--cs-w) + 80px); margin: 0 auto; padding: 120px 40px 40px; }
.back { display: inline-flex; align-items: center; gap: 8px; margin-bottom: 44px; font-size: 15px; color: var(--ink-55); transition: color .2s; }
.back svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; transition: translate .35s cubic-bezier(.22, 1, .36, 1); }
.back:hover { color: var(--ink); }
.back:hover svg { translate: -4px 0; }
.cs-title { font-weight: 400; font-size: clamp(36px, 5vw, 56px); letter-spacing: -.03em; line-height: 1.1; margin: 0 0 12px; }
.cs-tagline { font-size: 19px; line-height: 1.5; color: var(--ink-80); max-width: 680px; }
.cs-caption { margin-top: 14px; }
.live-btn { display: inline-flex; align-items: center; gap: 8px; margin-top: 20px; padding: 9px 14px; background: var(--ink); color: var(--on-ink); font-size: 14px; transition: background .2s; }
.live-btn:hover { background: var(--accent); }
.live-btn .dot { width: 7px; height: 7px; border-radius: 50%; background: #5ee08a; }
.cs-cover { margin: 40px 0; }
.cs-meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 28px 48px; padding: 28px 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); margin-bottom: 72px; }
.cs-meta dt { font-size: 13px; color: var(--ink-55); }
.cs-meta dd { font-size: 15px; margin-top: 3px; max-width: 250px; }
/* body: section list on the left (sticky, highlights where you are), content on the right */
.cs-layout { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 72px; align-items: start; }
.toc { position: sticky; top: 104px; display: grid; gap: 2px; transition: opacity .45s ease, translate .45s ease; }
.toc.away { opacity: 0; translate: 0 -8px; pointer-events: none; }
/* "On this page": purple, with a slow purple light passing through it every few seconds */
.toc .label { margin-bottom: 10px; font-size: 16px; font-weight: 600; letter-spacing: -.01em; color: transparent;
  background-image: linear-gradient(100deg, var(--accent) 0%, var(--accent) 36%, var(--sweep-2) 44%, var(--sweep-3) 50%, var(--sweep-4) 56%, var(--accent) 64%, var(--accent) 100%);
  background-size: 300% 100%; background-position: 2% 0; -webkit-background-clip: text; background-clip: text;
  animation: toc-flash 5.5s cubic-bezier(.45, 0, .25, 1) .4s infinite; }
@keyframes toc-flash { 0% { background-position: 92% 0; } 45%, 100% { background-position: 2% 0; } }
/* section markers are little cat paws: faint by default, purple (with a tiny hop) for the section you are reading */
.toc a { position: relative; padding: 5px 0 5px 24px; font-size: 14.5px; color: var(--ink-55); transition: color .25s; }
.toc a::before { content: ""; position: absolute; left: 0; top: 50%; width: 14px; height: 14px; margin-top: -7px;
  background: var(--ink-25); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 24 24%27%3E%3Cellipse cx=%2712%27 cy=%2716%27 rx=%275.2%27 ry=%274.4%27/%3E%3Cellipse cx=%275.2%27 cy=%2710.2%27 rx=%272.1%27 ry=%272.7%27/%3E%3Cellipse cx=%279.4%27 cy=%276.4%27 rx=%272.1%27 ry=%272.8%27/%3E%3Cellipse cx=%2714.6%27 cy=%276.4%27 rx=%272.1%27 ry=%272.8%27/%3E%3Cellipse cx=%2718.8%27 cy=%2710.2%27 rx=%272.1%27 ry=%272.7%27/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 24 24%27%3E%3Cellipse cx=%2712%27 cy=%2716%27 rx=%275.2%27 ry=%274.4%27/%3E%3Cellipse cx=%275.2%27 cy=%2710.2%27 rx=%272.1%27 ry=%272.7%27/%3E%3Cellipse cx=%279.4%27 cy=%276.4%27 rx=%272.1%27 ry=%272.8%27/%3E%3Cellipse cx=%2714.6%27 cy=%276.4%27 rx=%272.1%27 ry=%272.8%27/%3E%3Cellipse cx=%2718.8%27 cy=%2710.2%27 rx=%272.1%27 ry=%272.7%27/%3E%3C/svg%3E") center / contain no-repeat;
  rotate: -14deg; transition: background-color .25s, scale .35s cubic-bezier(.34, 1.56, .64, 1), rotate .35s; }
.toc a:hover { color: var(--ink); }
.toc a:hover::before { background: var(--ink-55); }
.toc a.active { color: var(--ink); }
.toc a.active::before { background: var(--accent); scale: 1.18; rotate: 0deg; animation: paw-step .45s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes paw-step { 0% { scale: .6; translate: 0 4px; } 60% { scale: 1.3; translate: 0 -2px; } 100% { scale: 1.18; translate: 0 0; } }
.cs-section { margin-bottom: 88px; scroll-margin-top: 100px; }
.cs-section h2 { font-weight: 600; font-size: 30px; letter-spacing: -.025em; line-height: 1.2; margin-bottom: 14px; color: var(--ink); }
.cs-body { display: grid; gap: 14px; max-width: 720px; }
.cs-body p { color: var(--ink-80); font-size: 16.5px; line-height: 1.65; }
.cs-gallery { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 28px; }
.cs-gallery .one { grid-column: 1 / -1; }
.cs-gallery figure { display: grid; gap: 8px; }
.cs-gallery figcaption { font-size: 13.5px; color: var(--ink-55); }
.cs-img { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--surface); box-shadow: inset 0 0 0 1px var(--border); display: grid; place-items: center; font-family: var(--sans); font-size: 12px; color: var(--ink-55); }
.cs-gallery .one .cs-img { aspect-ratio: 16 / 9; }
.cs-img img, .cs-img video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.others { max-width: calc(1120px + 80px); margin: 0 auto; padding: 40px 40px 100px; }
.others h2 { font-weight: 400; font-size: 24px; letter-spacing: -.02em; margin-bottom: 24px; padding-top: 28px; border-top: 1px solid var(--border); }
.others .grid { gap: 32px 24px; }
@media (max-width: 900px) {
  .cs, .others { padding-left: 20px; padding-right: 20px; }
  .cs-layout { grid-template-columns: minmax(0, 1fr); gap: 0; }   /* minmax: the screen rail scrolls instead of widening the page */
  .toc { display: none; }
  .cs-section { margin-bottom: 60px; }
  .cs-gallery { grid-template-columns: 1fr; }
}

/* ---------- RESPONSIVE ---------- */
@media (max-width: 768px) {
  .nav { padding: 16px 20px; }
  .page { padding: 0 20px; }
  .br-lg { display: none; }
  .grid, .about-grid, .intro-cols { grid-template-columns: 1fr; }
  .intro-cols { row-gap: 20px; }
  .skills { grid-template-columns: 1fr 1fr; }
  .cs-meta { display: grid; grid-template-columns: 1fr 1fr; gap: 24px 20px; }
  .stickers { --size: clamp(70px, 24vmin, 120px); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* =========================================================
   FLIPBOOK (case study) — a real page-turning book
   ========================================================= */
/* the book breaks out of the text column to use the whole page width (the column sits 131px right of centre) */
.cs-flip { margin-top: 28px; width: min(1360px, 100vw - 48px); margin-left: calc((100% - min(1360px, 100vw - 48px)) / 2 - 131px); }
@media (max-width: 900px) { .cs-flip { width: auto; margin-left: 0; } }
.flipbook { position: relative; background: linear-gradient(180deg, #f1f1f3, #e7e7ea); padding: 44px 64px 18px; }
:root[data-theme="dark"] .flipbook { background: linear-gradient(180deg, #1d1f25, #17181d); }
.fb-stage { position: relative; display: flex; align-items: center; justify-content: center; }
.fb-book { width: 100%; max-width: 100%; margin: 0 auto; }
.fb-book .stf__parent { margin: 0 auto; }
/* closed, the book sits centred on its cover (like a real book on a table); it slides over as it opens */
.flipbook.animated .fb-book { transition: translate .9s cubic-bezier(.45, 0, .25, 1); }
.flipbook.at-start:not(.is-portrait) .fb-book { translate: -25% 0; }
.flipbook.at-end:not(.is-portrait) .fb-book { translate: 25% 0; }
.fb-page { background: #fff; overflow: hidden; }
.fb-page img { display: block; width: 100%; height: 100%; object-fit: cover; user-select: none; -webkit-user-drag: none; background: #f4f1ec; }
/* the inner gutter: a soft fold shadow on each page, like a bound book */
.fb-page:not(.fb-hard)::after { content: ""; position: absolute; inset: 0; pointer-events: none; }
.fb-page.--left:not(.fb-hard)::after { background: linear-gradient(270deg, rgba(0,0,0,.16), rgba(0,0,0,0) 7%); }
.fb-page.--right:not(.fb-hard)::after { background: linear-gradient(90deg, rgba(0,0,0,.16), rgba(0,0,0,0) 7%); }
.fb-hard { background: #4a1f2b; }
.fb-book .stf__block { box-shadow: 0 18px 40px -18px rgba(0,0,0,.45); }
/* closed book: centred on its cover, a little lift */
.flipbook.at-start .fb-book .stf__block { box-shadow: none; }
.flipbook.at-start .fb-book .stf__item.--right, .flipbook.at-end .fb-book .stf__item.--left { box-shadow: 0 22px 44px -16px rgba(0,0,0,.5); }

.fb-nav { position: absolute; top: 50%; z-index: 5; width: 42px; height: 42px; margin-top: -21px; display: grid; place-items: center; border: 0; border-radius: 50%; background: rgba(255,255,255,.92); color: #2a2a2a; box-shadow: 0 2px 10px rgba(0,0,0,.12); cursor: pointer; transition: opacity .25s, scale .25s, background-color .2s; }
.fb-nav svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.fb-nav:hover { scale: 1.08; }
.fb-prev { left: -54px; } .fb-next { right: -54px; }
.flipbook.at-start .fb-prev, .flipbook.at-end .fb-next { opacity: 0; pointer-events: none; }
.flipbook:not(.animated) .fb-nav { transition: none; }

.fb-bar { display: flex; align-items: center; gap: 16px; margin-top: 22px; font-size: 13px; color: var(--ink-55); }
.fb-count { min-width: 92px; font-variant-numeric: tabular-nums; }
.fb-progress { flex: 1; height: 3px; background: var(--border); border-radius: 3px; cursor: pointer; position: relative; }
.fb-progress::before { content: ""; position: absolute; inset: -8px 0; }
.fb-progress span { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 3px; transition: width .6s cubic-bezier(.22, 1, .36, 1); }
.fb-full { width: 32px; height: 32px; display: grid; place-items: center; border: 0; background: none; color: var(--ink-55); cursor: pointer; }
.fb-full svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.fb-full:hover { color: var(--ink); }
.flipbook:fullscreen { display: flex; flex-direction: column; justify-content: center; padding: 4vh 8vw; }
.flipbook:fullscreen .fb-book { max-width: min(100%, calc(84vh * var(--fb-ratio) * 2)); }

/* Behance-style photo grid at the top of a case study */
.cs-photos { display: grid; grid-template-columns: repeat(6, 1fr); gap: 0; margin: 36px 0 12px; }
.cs-photos figure { position: relative; overflow: hidden; background: var(--surface); }
.cs-photos img { width: 100%; height: 100%; object-fit: cover; display: block; transition: scale .8s cubic-bezier(.22, 1, .36, 1); }
.cs-photos figure:hover img { scale: 1.03; }
.cs-photos .w6 { grid-column: span 6; } .cs-photos .w4 { grid-column: span 4; } .cs-photos .w3 { grid-column: span 3; } .cs-photos .w2 { grid-column: span 2; }

@media (max-width: 900px) {
  .flipbook { padding: 24px 12px 14px; }
  .fb-prev { left: 4px; } .fb-next { right: 4px; }
  .fb-nav { width: 36px; height: 36px; margin-top: -18px; }
  .cs-photos { grid-template-columns: 1fr 1fr; }
  .cs-photos .w6, .cs-photos .w4 { grid-column: span 2; } .cs-photos .w3, .cs-photos .w2 { grid-column: span 1; }
}


/* Page and case study titles: the same Inter as the intro headline, in plain ink (no colour sweep) */
.cs-title, .page-title {
  font-family: var(--sans); font-weight: 400; letter-spacing: -.035em;
  font-size: clamp(40px, 5.4vw, 62px); line-height: 1.1; padding-bottom: .06em;
  display: block; width: fit-content; color: var(--ink);
}


/* contact: Behance + LinkedIn as icons */
.contact-icons { display: flex; gap: 12px; margin-top: 28px; }
.contact-icons a { width: 46px; height: 46px; display: grid; place-items: center; border: 1px solid var(--border); color: var(--ink); cursor: none; transition: background-color .25s, color .25s, border-color .25s, translate .3s cubic-bezier(.22, 1, .36, 1); }
.contact-icons svg { width: 20px; height: 20px; fill: currentColor; }
.contact-icons a:hover { background: var(--accent); border-color: var(--accent); color: #fff; translate: 0 -2px; }
@media (hover: none) { .contact-icons a { cursor: pointer; } }

/* =========================================================
   STANDALONE PAGES (about, contact)
   ========================================================= */
.subpage { max-width: calc(1120px + 80px); margin: 0 auto; padding: 130px 40px 0; }
.subpage .page-title { margin-bottom: 18px; }
.subpage .lede { font-size: 19px; line-height: 1.55; color: var(--ink-80); max-width: 640px; }
.subpage .contact { padding-top: 48px; }

/* about */
/* the top of the about page: a centred intro and two facts, with chips that hop on hover */
.about-bento { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 16px; }
.tile { border-radius: 0; padding: 28px; background: none; }
.tile .label { margin-bottom: 10px; }
.tile-intro, .tile-now, .tile-tools { text-align: center; }
.tile-intro .chips, .tile-tools .chips { justify-content: center; }
.tile-intro { grid-column: 1 / -1; }
.tile-intro .hi { font-family: "Happy Monkey", cursive; font-size: 32px; color: var(--accent); margin-bottom: 10px; }
.tile-intro p:not(.hi, .label) { color: var(--ink-80); font-size: 17px; line-height: 1.7; margin-bottom: 14px; max-width: 660px; margin-inline: auto; }
.tile-intro .label { margin-top: 22px; }
.chips { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; }
.chips li { padding: 7px 14px; border-radius: 999px; background: var(--bg); box-shadow: inset 0 0 0 1px var(--border); font-size: 14.5px; color: var(--ink); cursor: default; transition: translate .3s cubic-bezier(.34, 1.56, .64, 1), rotate .3s ease; }
.chips li:hover { translate: 0 -3px; rotate: -3deg; }
.tile-now { grid-column: 1 / 7; }
.tile-now .big { font-size: 26px; line-height: 1.2; letter-spacing: -.02em; color: var(--ink); margin-bottom: 4px; }
.tile-now p:not(.label, .big) { color: var(--ink-80); }
.tile-tools { grid-column: 7 / 13; }
.chips.tools { gap: 14px; }
.chips.tools li { padding: 0; background: none; box-shadow: none; }
.chips.tools img { display: block; width: 40px; height: 40px; }
/* =========================================================
   PLAY PAGE — Leo's mouse chase (js/game.js draws into the canvas)
   Exactly one screen tall and never scrolls: the heading and the game (a strip a little
   taller than it was on the about page, edge to edge) sit together in the middle of the screen.
   ========================================================= */
html:has(body.play-page), body.play-page { height: 100%; overflow: hidden; overscroll-behavior: none; }
/* fast taps anywhere jump: no double-tap zoom, no text selection, no grey tap flash */
body.play-page { touch-action: manipulation; -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
.play-stage { height: 100vh; height: 100dvh; display: flex; flex-direction: column; max-width: calc(1120px + 80px); margin: 0 auto; padding: 76px 40px 0; }
.play-field { position: relative; height: 360px; flex-shrink: 1; min-height: 200px; }
/* the heading takes the space between the nav and the game and sits in the middle of it; the ground below the game takes a bit less, so the game sits just below the middle of the screen */
.play-stage .game-head { flex: 1 1 0; margin-bottom: 0; align-content: center; }
.play-stage::after { content: ""; flex: .8 1 0; }
/* the ground carries on below the game, all the way to the bottom of the screen (same greens game.js draws) */
:root { --game-ground: #a8d5b8; }
:root[data-theme="dark"] { --game-ground: #4f9670; }
.play-field::after { content: ""; position: absolute; top: calc(100% - 1px); left: calc(50% - 50vw); width: 100vw; height: 100vh; background: var(--game-ground); }
/* the canvas is pinned to the field (not sized by it) so resizing it can't feed back into the layout */
.play-field .game { position: absolute; top: 0; left: calc(50% - 50vw); width: 100vw; height: 100%; margin: 0; }
.game-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 14px 24px; margin-bottom: 24px; }
.game-head h1 { font-weight: 400; font-size: 30px; letter-spacing: -.02em; margin-bottom: 4px; }
.game-head p { color: var(--ink-55); font-size: 14.5px; max-width: 560px; }
.game-play { display: inline-flex; align-items: center; gap: 8px; padding: 12px 20px 12px 16px; border: 0; border-radius: 999px; background: var(--ink); color: var(--on-ink); font: 500 15px var(--sans); cursor: pointer; transition: translate .3s cubic-bezier(.34, 1.56, .64, 1), background-color .25s; }
.game-play svg { width: 16px; height: 16px; }
.game-play:hover { translate: 0 -2px; }
.game-play .icon-retry, .game-play.retry .icon-play { display: none; }
.game-play.retry .icon-retry { display: block; }
/* the sky behind the game; clouds, hills and grass are drawn on top by game.js */
:root { --game-bg: linear-gradient(180deg, #e6f4f1 0%, #cfe8e4 100%); }
:root[data-theme="dark"] { --game-bg: linear-gradient(180deg, #221d4a 0%, #3a3373 60%, #5a4c8c 100%); }
.game, .game:focus, .game:focus-visible { outline: none; box-shadow: none; }
/* full-bleed: the game runs edge to edge across the window, past the centred page column */
.game { display: block; width: 100vw; margin-left: calc(50% - 50vw); height: 220px; background: var(--game-bg); cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.about-block { margin-top: 110px; }
.about-block > h2 { font-weight: 400; font-size: 30px; letter-spacing: -.02em; margin-bottom: 24px; }
.exp { border-top: 1px solid var(--border); }
.exp-row { display: grid; grid-template-columns: 180px minmax(0, 1fr) minmax(0, 1.4fr); gap: 24px; padding: 18px 0; border-bottom: 1px solid var(--border); }
.exp-row .when { color: var(--ink-55); font-size: 13.5px; }
.exp-row .role { font-size: 15.5px; color: var(--ink); }
.exp-row .role span { display: block; font-size: 13.5px; color: var(--ink-55); margin-top: 2px; }
.exp-row .what { color: var(--ink-80); font-size: 14px; line-height: 1.6; }
.tool-row { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: 22px; padding-top: 6px; }
.tool-row img { display: block; width: 44px; height: 44px; transition: translate .3s cubic-bezier(.34, 1.56, .64, 1); }
.tool-row li:hover img { translate: 0 -4px; }
/* FUN: a four-column photo grid. Every cell has a label slot (empty for photos that carry a group on), so photos in a row
   line up along the top; each photo keeps its own shape, so heights vary like a contact sheet */
.fun-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 44px 22px; align-items: start; }
.fun-item { margin: 0; }
.fun-label { min-height: 1.5em; margin-bottom: 10px; font-size: 16px; line-height: 1.5; color: var(--ink-55); white-space: nowrap; }
.fun-label span { color: var(--ink-55); opacity: .8; margin-right: 1px; }
.fun-photo { display: grid; place-items: center; width: 100%; height: auto; background: var(--surface); box-shadow: inset 0 0 0 1px var(--border); font-size: 12px; color: var(--ink-55); overflow: hidden; transition: scale .6s cubic-bezier(.22, 1, .36, 1); }
img.fun-photo { display: block; object-fit: cover; box-shadow: none; }
.fun-item:hover .fun-photo { scale: 1.02; }
@media (max-width: 900px) {
  .subpage { padding: 110px 20px 0; }
  .about-bento { grid-template-columns: 1fr; }
  .about-bento .tile { grid-column: 1 / -1; grid-row: auto; padding: 22px; }
  .play-stage { padding: 70px 20px 0; }
  .play-field { height: 290px; }
  .play-stage .game-head { margin-bottom: 0; }
  .game-head { margin-bottom: 18px; }
  .game-head h1 { font-size: 26px; }
  .exp-row { grid-template-columns: 1fr; gap: 6px; }
  .fun-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px 14px; }
  .fun-label { font-size: 14.5px; }
}


/* contact heading: letters hop on hover (same bounce as the nav) and blush into a light pink gradient */
.contact-head .headline, .hop-text { cursor: default; }
.contact-head .headline .word, .hop-text .word { display: inline-block; white-space: nowrap; }
/* "Hellooo!": the handwritten hello, traced from Alisha's sample; its SVG fills with the text colour */
.hop-text .word.script { margin-right: .15em; vertical-align: -.12em; color: var(--accent); }   /* the same purple as "hi there!" */
/* the intro sentence is a touch smaller and lighter than other headlines; the hello is scaled up by the same amount so it keeps its size */
.headline.hop-text { font-size: clamp(25px, 3.5vw, 35px); font-weight: 350; }
.hop-text .hello-mark { display: block; width: calc(3.2em * 40 / 35); height: auto; aspect-ratio: 1846 / 804; overflow: visible; rotate: -7deg; transform-origin: 40% 70%; }   /* tilted up a little, like the handwritten "play" in the nav */
.contact-head .headline .ch, .hop-text .ch { display: inline-block; transition: color .45s ease; transition-delay: calc(var(--i) * 14ms); }
.contact-head .headline.hop .ch { animation: hop .55s cubic-bezier(.3, 1.6, .5, 1) both; animation-delay: calc(var(--i) * 22ms); }
.contact-head .headline.blush .ch { color: color-mix(in oklab, var(--blush-a) calc((1 - var(--p)) * 100%), var(--blush-b)); }
:root { --blush-a: #ef8fb2; --blush-b: #d9709c; }
:root[data-theme="dark"] { --blush-a: #ffdbe7; --blush-b: #f6b3cb; }

/* =========================================================
   MOTION COVERS — close-up UI moments (see COVERS in js/main.js)
   Each .cv-scene zooms in, drifts closer, then zooms out into the next.
   Base styles are each scene's finished look (the resting frame);
   the animations only run on the scene that is .on.
   ========================================================= */
.cv { position: absolute; inset: 0; container-type: size; overflow: hidden; font-family: var(--sans); letter-spacing: -.01em; }
.cv::before { content: ""; position: absolute; inset: 0; background-image: radial-gradient(rgba(10, 77, 151, .2) 1px, transparent 1.4px); background-size: 2.4cqw 2.4cqw; }
.cv-scene { position: absolute; inset: 0; display: grid; place-items: center; opacity: 0; }
.cv-scene.rest { opacity: 1; }
.cv-scene.on { animation: cv-shot var(--ms) linear both; will-change: transform, opacity; }
@keyframes cv-shot {
  0% { opacity: 0; scale: 1.22; animation-timing-function: cubic-bezier(.16, .9, .3, 1); }
  15% { opacity: 1; scale: 1; animation-timing-function: cubic-bezier(.4, 0, .6, 1); }
  86% { opacity: 1; scale: 1.07; animation-timing-function: cubic-bezier(.5, 0, .9, .4); }
  100% { opacity: 0; scale: .86; }
}
.cv-cam { display: grid; place-items: center; }
.cv-hdfc .cv-cam { scale: 1.25; }   /* close-up: the component fills the frame, like a zoomed-in shot */
.cv-hdfc .cv-cam:has(.cv-field) { scale: 1.05; }   /* the field + its nudge need more room */
.cv-cursor { position: absolute; z-index: 3; width: 4.4cqw; left: 52%; top: 52%; fill: #14161c; stroke: #fff; stroke-width: 1.5; stroke-linejoin: round; filter: drop-shadow(0 .5cqw .7cqw rgba(0, 0, 0, .3)); transform-origin: 15% 10%; }
@keyframes cv-press { 0%, 100% { scale: 1; } 40% { scale: .88; } }
@keyframes cv-appear { from { opacity: 0; translate: 0 1.4cqw; } }
@keyframes cv-pop { 0% { opacity: 0; scale: .7; } 70% { scale: 1.04; } 100% { opacity: 1; scale: 1; } }
@keyframes cv-blink { 50% { opacity: 0; } }

/* HDFC: soft bank blue with a dot grid */
.cv-hdfc { background: radial-gradient(120% 90% at 25% 15%, #eef2fa 0%, #d3ddf0 55%, #c2cfea 100%); color: #1d2433; }
.cv-hdfc em { font-style: normal; color: #0a4d97; background: rgba(10, 77, 151, .1); border-radius: .2em; padding: 0 .08em; }
.cv-bars { display: inline-flex; align-items: center; gap: .2em; height: 1em; }
.cv-bars i { width: .2em; height: .55em; border-radius: 99px; background: currentColor; }
.cv-bars i:nth-child(2) { height: 1em; }
.cv-caret { display: inline-block; width: .07em; height: 1.05em; margin-left: .06em; vertical-align: -.18em; background: #0a4d97; }
.cv-scene.on .cv-caret { animation: cv-blink 1s steps(1) infinite; }
.cv-card { position: relative; background: #fff; border-radius: 2.4cqw; padding: 3cqw 3.4cqw; font-size: 2.6cqw; box-shadow: 0 0 0 .25cqw rgba(10, 77, 151, .28), 0 3cqw 6cqw -2.5cqw rgba(10, 40, 100, .45); }

/* 1 · the AI orb: tapped, it starts listening */
.cv-orb { position: relative; width: 21cqw; aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center; color: #fff; font-size: 9cqw;
  background: radial-gradient(circle, #e0262d 0%, #8a3577 30%, #0a4d97 68%); box-shadow: 0 3cqw 6cqw -2cqw rgba(10, 40, 100, .5); }
.cv-orb .cv-bars i { width: .15em; }
.cv-ripple { position: absolute; inset: 0; border-radius: 50%; border: .35cqw solid rgba(10, 77, 151, .4); opacity: 0; }
.cv-scene.on .cv-orb { animation: cv-press .38s 1260ms ease-out both; }
.cv-scene.on .cv-ripple { animation: cv-ripple 1.3s 1320ms ease-out infinite; }
.cv-scene.on .cv-ripple.r2 { animation-delay: 1750ms; }
@keyframes cv-ripple { 0% { opacity: .9; scale: 1; } 100% { opacity: 0; scale: 1.9; } }
.cv-scene.on .cv-orb .cv-bars i { animation: cv-bar .42s 1400ms ease-in-out infinite alternate; }
.cv-scene.on .cv-orb .cv-bars i:nth-child(2) { animation-delay: 1520ms; }
.cv-scene.on .cv-orb .cv-bars i:nth-child(3) { animation-delay: 1610ms; }
@keyframes cv-bar { from { scale: 1 .55; } to { scale: 1 1.2; } }
.cv-scene.on .cv-orb ~ .cv-cursor { animation: cv-c1 var(--ms) both; }
@keyframes cv-c1 { 0%, 16% { left: 80%; top: 90%; opacity: 0; } 22% { opacity: 1; animation-timing-function: cubic-bezier(.3, .1, .2, 1); } 45% { left: 52%; top: 53%; scale: 1; } 48% { scale: .82; } 54%, 100% { left: 52%; top: 53%; scale: 1; opacity: 1; } }

/* 2 · asking in your own words */
.cv-input { display: flex; align-items: center; gap: 2cqw; width: 68cqw; padding: 2cqw 2cqw 2cqw 3cqw; border-radius: 99px; background: #fff; font-size: 3.6cqw;
  box-shadow: 0 0 0 .25cqw rgba(10, 77, 151, .28), 0 2.6cqw 5cqw -2cqw rgba(10, 40, 100, .4); }
.cv-input > .cv-bars { color: #9aa6bb; flex: none; }
.cv-input p { flex: 1; white-space: nowrap; overflow: hidden; }
.cv-send { flex: none; width: 6.6cqw; aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center; background: #0a4d97; }
.cv-send svg { width: 50%; fill: none; stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.cv-scene.on .cv-send { animation: cv-press .36s 2650ms ease-out both; }

/* 3 · the coach thinks, answers, offers a guide */
.cv-answer { width: 58cqw; }
.cv-answer h4 { font-size: 3.2cqw; font-weight: 600; padding-bottom: 1.3cqw; margin-bottom: 1.8cqw; border-bottom: .3cqw solid #0a4d97; }
.cv-row { position: relative; display: flex; gap: 2cqw; align-items: flex-start; }
.cv-row > .cv-bars { flex: none; color: #0a4d97; font-size: 3.2cqw; margin-top: .3cqw; }
.cv-row p { line-height: 1.45; }
.cv-dots { position: absolute; left: 5.4cqw; top: 1.2cqw; display: flex; gap: .8cqw; opacity: 0; }
.cv-dots i { width: 1.2cqw; aspect-ratio: 1; border-radius: 50%; background: #9aa6bb; }
.cv-btn { display: block; margin-top: 2.4cqw; padding: 1.3cqw; border-radius: 1cqw; background: #0a4d97; color: #fff; font-weight: 500; text-align: center; }
.cv-scene.on .cv-dots { animation: cv-think 1.15s 250ms both; }
.cv-scene.on .cv-dots i { animation: cv-hop .5s ease-in-out infinite alternate; }
.cv-scene.on .cv-dots i:nth-child(2) { animation-delay: .15s; } .cv-scene.on .cv-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes cv-think { 0%, 90% { opacity: 1; } 100% { opacity: 0; } }
@keyframes cv-hop { to { translate: 0 -.8cqw; background: #0a4d97; } }
.cv-scene.on .cv-row p { animation: cv-appear .5s 1350ms cubic-bezier(.2, .8, .2, 1) both; }
.cv-scene.on .cv-btn { animation: cv-appear .5s 1550ms cubic-bezier(.2, .8, .2, 1) both, cv-press .36s 2560ms ease-out; }
.cv-scene.on .cv-answer ~ .cv-cursor { animation: cv-c3 var(--ms) both; }
@keyframes cv-c3 { 0%, 42% { left: 84%; top: 94%; opacity: 0; } 47% { opacity: 1; animation-timing-function: cubic-bezier(.3, .1, .2, 1); } 66% { left: 53%; top: 65%; scale: 1; } 69% { scale: .82; } 74%, 100% { left: 53%; top: 65%; scale: 1; opacity: 1; } }

/* 4 · a mistake caught before you continue */
.cv-field { width: 54cqw; margin-top: -15cqw; }
.cv-field label { display: block; font-size: 2.2cqw; color: #3b7be0; }
.cv-field p { font-size: 3.8cqw; letter-spacing: .1em; margin: .6cqw 0 1cqw; }
.cv-line { position: relative; display: block; height: .3cqw; background: #c9d2e2; }
.cv-line::after { content: ""; position: absolute; inset: 0; background: #e0262d; transform-origin: left; }
.cv-nudge { position: absolute; right: 3cqw; top: calc(100% + 2.4cqw); width: 36cqw; padding: 1.8cqw 2.2cqw; border-radius: 1.8cqw; background: #fff; font-size: 2.2cqw; line-height: 1.4;
  box-shadow: 0 0 0 .25cqw #0a4d97, 0 2.4cqw 4.5cqw -2cqw rgba(10, 40, 100, .45); transform-origin: 90% 0; }
.cv-nudge b { color: #e0262d; font-weight: 600; }
.cv-mini { position: absolute; right: -3.4cqw; bottom: -3.4cqw; width: 6.8cqw; aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center; color: #fff; font-size: 2.8cqw;
  background: radial-gradient(circle, #e0262d 0%, #8a3577 32%, #0a4d97 70%); box-shadow: 0 1cqw 2cqw rgba(10, 40, 100, .4); }
.cv-scene.on .cv-line::after { animation: cv-grow .45s 1650ms cubic-bezier(.2, .8, .2, 1) both; }
@keyframes cv-grow { from { scale: 0 1; } }
.cv-scene.on .cv-nudge { animation: cv-pop .55s 1950ms cubic-bezier(.2, .8, .2, 1) both; }

/* 5 · done */
.cv-done { display: flex; align-items: center; gap: 2.6cqw; padding: 3cqw 4.4cqw 3cqw 3.4cqw; }
.cv-check { width: 9cqw; fill: none; stroke: #1f9d55; stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; }
.cv-check circle { stroke-dasharray: 145; } .cv-check path { stroke-dasharray: 40; stroke-width: 3.8; }
.cv-done h4 { font-size: 3.8cqw; font-weight: 600; }
.cv-done p { font-size: 2.4cqw; color: #5b6478; margin-top: .4cqw; }
.cv-scene.on .cv-check circle { animation: cv-draw .7s 350ms cubic-bezier(.6, 0, .2, 1) both; --len: 145; }
.cv-scene.on .cv-check path { animation: cv-draw .45s 900ms cubic-bezier(.6, 0, .2, 1) both; --len: 40; }
@keyframes cv-draw { from { stroke-dashoffset: var(--len); } to { stroke-dashoffset: 0; } }
.cv-scene.on .cv-done > div { animation: cv-appear .5s 800ms cubic-bezier(.2, .8, .2, 1) both; }

/* =========================================================
   CASE STUDY: screen rail + kicker
   ========================================================= */
.cs-kicker { font-family: var(--sans); font-size: 13px; font-weight: 500; letter-spacing: .04em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
.cs-body b { font-weight: 600; color: var(--ink); }
.cs-rail { display: flex; gap: 20px; overflow-x: auto; scroll-snap-type: x mandatory; padding: 28px 2px 14px; margin-top: 8px; scrollbar-width: thin; }
.cs-rail figure { flex: 0 0 auto; width: 186px; scroll-snap-align: start; display: grid; gap: 12px; align-content: start; }
.rail-phone { aspect-ratio: 402 / 874; padding: 5px; border-radius: 26px; background: #121318; box-shadow: 0 0 0 1px #33363f, 0 14px 30px -14px rgba(10, 30, 70, .45); transition: translate .35s var(--ease); }
.rail-phone img { width: 100%; height: 100%; object-fit: cover; border-radius: 21px; display: block; }
@media (hover: hover) { .cs-rail figure:hover .rail-phone { translate: 0 -6px; } }
.cs-rail figcaption { font-size: 13.5px; line-height: 1.4; color: var(--ink-55); }
@media (max-width: 768px) { .cs-rail { gap: 14px; } .cs-rail figure { width: 148px; } .rail-phone { border-radius: 21px; } .rail-phone img { border-radius: 17px; } }
.cs-img:has(img) { box-shadow: none; }
.cs-img[style] img { object-fit: contain; }

/* phones: the nav fits on one line (logo, three links, switch) */
@media (max-width: 520px) {
  .nav { padding: 14px 16px; gap: 10px; }
  .nav-logo { font-size: 19px; white-space: nowrap; }
  .nav-links { gap: 14px; font-size: 14.5px; }
  .nav-links a { white-space: nowrap; }
}

/* ---------- phone nav: logo on the left; the theme switch and a three-line menu button on the right ----------
   (js/main.js wraps the links in .nav-menu and adds .nav-burger; tapping it toggles .menu-open on the nav) */
.nav-menu { display: contents; }
.nav-burger { display: none; }
@media (max-width: 768px) {
  .nav-links { gap: 6px; }
  /* a bigger, easier-to-tap day / night switch on phones */
  .theme-switch { width: 76px; height: 38px; margin: 0; }
  .theme-switch .knob { top: 3px; left: 3px; width: 42px; height: 30px; }
  .theme-switch .knob svg { width: 30px; height: 17px; }
  :root[data-theme="dark"] .theme-switch .knob { translate: 28px 0; }
  .nav-burger { display: grid; place-content: center; gap: 5px; width: 42px; height: 42px; margin-right: -9px; padding: 0; border: 0; background: none; color: var(--ink); cursor: pointer; -webkit-tap-highlight-color: transparent; }
  .nav-burger span { display: block; width: 22px; height: 2px; border-radius: 2px; background: currentColor; transition: translate .4s var(--ease), rotate .4s var(--ease), opacity .2s ease; }
  /* open: the three lines fold into a cross */
  .nav.menu-open .nav-burger span:nth-child(1) { translate: 0 7px; rotate: 45deg; }
  .nav.menu-open .nav-burger span:nth-child(2) { opacity: 0; }
  .nav.menu-open .nav-burger span:nth-child(3) { translate: 0 -7px; rotate: -45deg; }
  /* the menu drops down under the bar */
  .nav-menu { display: flex; flex-direction: column; position: absolute; top: 100%; left: 0; right: 0; padding: 4px 20px 18px; background: var(--bg); border-bottom: 1px solid var(--border); box-shadow: 0 22px 32px -24px rgba(0, 0, 0, .3);
    opacity: 0; translate: 0 -10px; visibility: hidden; pointer-events: none; transition: opacity .3s var(--ease), translate .4s var(--ease), visibility 0s linear .4s; }
  .nav.menu-open .nav-menu { opacity: 1; translate: 0 0; visibility: visible; pointer-events: auto; transition: opacity .3s var(--ease), translate .4s var(--ease); }
  /* the dividers are the bottom edges of Work, About and Contact, so they stay straight; play sits under them, tilted and purple */
  .nav-menu a { padding: 15px 0; font-size: 19px; white-space: nowrap; border-bottom: 1px solid var(--border); }
  .nav-menu a.nav-play { align-self: flex-start; padding: 10px 4px 2px; font-size: 38px; border-bottom: 0; color: var(--accent); }
  .nav-menu a[aria-current="page"]:not(.nav-play) { color: var(--ink); }
  /* the hero on phones: just the cat (no sticker pile), a bit bigger, with her speech bubble centred above her
     (beside her it ran off the right edge and pushed the group off-centre) */
  .stickers { display: none; }
  .cat { width: min(60vw, 250px); }
  .chat-bubble { left: 50%; top: auto; bottom: calc(100% + 16px); translate: -50% 0; transform-origin: 50% 100%; max-width: calc(100vw - 32px); }
  .chat-bubble::before { left: 50%; bottom: -7px; width: 16px; height: 9px; translate: -50% 0; border-radius: 0; clip-path: polygon(0 0, 100% 0, 50% 100%); }
}

/* the brief, quoted */
.cs-body q { display: block; quotes: none; padding: 4px 0 4px 18px; border-left: 2px solid var(--accent); font-size: 1.12em; line-height: 1.6; color: var(--ink); }
/* a part of the section above it (e.g. the steps of a solution): tighter, smaller heading */
.cs-section.cs-sub { margin-bottom: 72px; }
.cs-section.cs-sub h3 { font-weight: 600; font-size: 23px; color: var(--ink); letter-spacing: -.01em; line-height: 1.25; margin-bottom: 12px; }

/* ---------- petting the cat (hover with a mouse) ----------
   #cat so it wins over every expression; removing .petted hands her straight back to what she was doing */
.cat .blush ellipse { fill: #f4a6ba; stroke: none; opacity: 0; transition: opacity .35s ease; }
#cat { pointer-events: auto; }   /* the lockup lets clicks through; the cat itself can be petted */
@media (hover: hover) { #cat { cursor: grab; } }
#cat.petted .eyes, #cat.petted .eye-wink { opacity: 0; animation: none; }
#cat.petted .eyes-happy { opacity: 1; }
#cat.petted .mouth-flat, #cat.petted .mouth-o { opacity: 0; }
#cat.petted .mouth-smile { opacity: 1; }
#cat.petted .blush ellipse { opacity: .8; }
#cat.petted .head { rotate: var(--pet-tilt, 4deg); translate: 0 1.5px; transition: rotate .4s cubic-bezier(.34, 1.4, .64, 1), translate .4s ease; }
#cat.petted .t1, #cat.petted .t2, #cat.petted .t3 { animation-duration: .8s; }
.pet-heart { position: absolute; z-index: 3; width: 16px; pointer-events: none; translate: -50% -50%; animation: pet-heart 1.1s ease-out forwards; }
.pet-heart svg { display: block; width: 100%; fill: #f08aa8; }
@keyframes pet-heart { 0% { opacity: 0; scale: .4; } 20% { opacity: 1; scale: 1; } 100% { opacity: 0; scale: .8; transform: translate(var(--drift), -46px); } }
/* while she's petted the bubble reads "Please be kind to animals", then hands back to its usual line */
.chat-bubble .pet-msg { display: none; }
.chat-bubble.petting .typing, .chat-bubble.petting #lead, .chat-bubble.petting #word { display: none; }
.chat-bubble.petting .msg, .chat-bubble.petting .pet-msg { display: inline; }
.chat-bubble.petting .pet-msg { animation: msg-in .3s ease-out; }
.chat-bubble .msg.msg-back { animation: msg-in .3s ease-out; }

/* ---------- Got Tea cover: a slow green vortex (Got green, shadow green, breaker bay, a touch of cream) + grain ----------
   The swirl turns and two soft lights drift while it's on screen; the centre stays darker so the title always reads. */
.cvm { background: #1f4d45; }
.cvm::before { display: none; }
.cvm-silk { position: absolute; inset: 0; overflow: hidden; }
.cvm-silk .vx { position: absolute; left: 50%; top: 50%; width: 170cqw; aspect-ratio: 1; translate: -50% -50%; filter: blur(4.5cqw);
  background: conic-gradient(from 20deg at 50% 50%, #1f4d45, #2f6f64 12%, #4a9184 24%, #a8d2c6 33%, #eef3ea 38%, #6fae9f 46%, #24584f 58%, #4a9184 70%, #cfe3dc 77%, #3c8174 86%, #1f4d45);
  animation: cvm-spin 22s linear infinite, cvm-sway 6s ease-in-out infinite alternate; animation-play-state: paused; }
.cvm-silk i { position: absolute; border-radius: 50%; filter: blur(4cqw); animation: cvm-drift 7s ease-in-out infinite alternate; animation-play-state: paused; }
.cvm-silk .l1 { width: 46cqw; height: 34cqw; left: 4%; top: -6%; background: radial-gradient(closest-side, rgba(240, 246, 238, .55), transparent); }
.cvm-silk .l2 { width: 54cqw; height: 40cqw; right: -6%; bottom: -14%; background: radial-gradient(closest-side, rgba(16, 48, 42, .8), transparent); animation-duration: 8s; animation-delay: -3s; }
.cvm.playing .cvm-silk .vx, .cvm.playing .cvm-silk i { animation-play-state: running; }
.cvm-silk .vx, .cvm-silk i, .cvm-silk .rb { will-change: transform; }
@keyframes cvm-spin { to { rotate: 360deg; } }
@keyframes cvm-sway { 0% { scale: 1 1; } 50% { scale: 1.12 .9; } 100% { scale: .94 1.08; } }
/* soft ribbons of light that ripple across, like silk */
.cvm-silk .rb { position: absolute; left: -30%; width: 160%; height: 26cqh; border-radius: 50%; filter: blur(3.2cqw); opacity: .75;
  background: linear-gradient(90deg, transparent, rgba(207, 227, 220, .0) 10%, rgba(220, 236, 229, .7) 35%, rgba(255, 255, 255, .55) 50%, rgba(168, 210, 198, .6) 65%, transparent 90%);
  animation: cvm-wave 5s ease-in-out infinite alternate; animation-play-state: paused; }
.cvm-silk .r1 { top: 8%; rotate: -14deg; }
.cvm-silk .r2 { top: 52%; rotate: -8deg; height: 20cqh; opacity: .5; animation-duration: 6s; animation-delay: -2s; background: linear-gradient(90deg, transparent, rgba(111, 174, 159, .7) 30%, rgba(238, 243, 234, .55) 52%, rgba(74, 145, 132, .6) 72%, transparent); }
.cvm-silk .r3 { top: 74%; rotate: -18deg; height: 18cqh; opacity: .45; animation-duration: 4.4s; animation-delay: -3s; }
.cvm.playing .cvm-silk .rb { animation-play-state: running; }
@keyframes cvm-wave {
  0% { translate: -6% 0; scale: 1 1; skew: 0deg 0deg; }
  33% { translate: 4% -7cqh; scale: 1.05 1.35; skew: 8deg -3deg; }
  66% { translate: -2% 5cqh; scale: .96 .8; skew: -6deg 2deg; }
  100% { translate: 6% -2cqh; scale: 1.02 1.2; skew: 4deg 3deg; }
}
@keyframes cvm-drift { 0% { translate: 0 0; scale: 1; } 50% { translate: 10cqw 6cqh; scale: 1.15; } 100% { translate: -8cqw -4cqh; scale: .92; } }
/* a soft, darker pool behind the title so it always reads */
.cvm-silk::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse 46% 40% at 50% 50%, rgba(14, 44, 38, .55), rgba(14, 44, 38, 0) 72%); }
/* film grain, like printed paper */
.cvm::after { content: ""; position: absolute; inset: 0; opacity: .18; mix-blend-mode: overlay; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.cvm-title { position: absolute; inset: 0; display: grid; place-items: center; align-content: center; gap: 2.6cqh; z-index: 1; color: #ffffff; text-align: center; }
.cvm-title p { font-family: "Inter Tight", var(--sans); font-size: max(17px, 4.6cqw); font-weight: 500; letter-spacing: -.025em; text-shadow: 0 .15cqw 1.2cqw rgba(8, 30, 26, .45); }
.cvm-title p span { font-weight: 400; opacity: .8; margin: 0 .12em; }
.cvm-logo { width: max(40px, 11cqw); aspect-ratio: 1; background: #ffffff; filter: drop-shadow(0 .3cqw 1.2cqw rgba(8, 30, 26, .4));
  -webkit-mask: url("../assets/gottea/logo.png") center / contain no-repeat; mask: url("../assets/gottea/logo.png") center / contain no-repeat; }

/* ---------- Kitabwalah cover: the sign-in card is the hero; behind it the Got Tea vortex, re-tinted in very pale
   butter, cream and a breath of apricot, so it only adds a slow, quiet movement + grain ---------- */
.cvk { background: #fbf3dc; }
.cvk .cvm-silk .vx { background: conic-gradient(from 20deg at 50% 50%, #fbf3dc, #f8e9bf 12%, #fdf8ea 24%, #f6e2b0 33%, #fffdf6 40%, #f9ecd0 48%, #f5dfae 58%, #fcf5e2 70%, #f7e6c4 78%, #fefaf0 86%, #fbf3dc); }
.cvk .cvm-silk .l1 { background: radial-gradient(closest-side, rgba(255, 255, 255, .7), transparent); }
.cvk .cvm-silk .l2 { background: radial-gradient(closest-side, rgba(242, 205, 140, .45), transparent); }
.cvk .cvm-silk .rb { opacity: .55; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .7) 35%, rgba(255, 250, 235, .6) 50%, rgba(246, 222, 168, .5) 65%, transparent 90%); }
.cvk .cvm-silk .r2 { opacity: .4; background: linear-gradient(90deg, transparent, rgba(245, 214, 150, .5) 30%, rgba(255, 253, 245, .6) 52%, rgba(240, 210, 150, .4) 72%, transparent); }
.cvk .cvm-silk::after { display: none; }
.cvk::after { opacity: .22; }
.thumb .cvk-card { position: absolute; inset: auto; left: 50%; top: 50%; z-index: 1; height: 90cqh; width: auto; object-fit: contain; translate: -50% -50%; pointer-events: none; }

/* ---------- case study: a tablet playing the real prototype, and the design decisions beside it ---------- */
.flow { margin-top: 26px; display: grid; gap: 12px; }
.flow-tab { padding: 1.6%; border-radius: 18px; background: #15171b; box-shadow: 0 0 0 1px #34373f, 0 24px 48px -22px rgba(20, 40, 35, .5); }
.flow-scr { position: relative; aspect-ratio: 1194 / 834; overflow: hidden; border-radius: 10px; background: #fffdee; }
.flow-scr img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .3s ease; }
.flow-scr img.on { opacity: 1; }
.flow .tap { position: absolute; z-index: 2; width: 5.5%; aspect-ratio: 1; border-radius: 50%; translate: -50% -50%; background: rgba(74, 145, 132, .45); box-shadow: 0 0 0 4px rgba(74, 145, 132, .25); opacity: 0; pointer-events: none; }
.flow .tap.go { animation: flow-tap .5s ease-out; }
@keyframes flow-tap { 0% { opacity: 0; scale: 1.4; } 35% { opacity: 1; scale: .8; } 100% { opacity: 0; scale: 1.5; } }
.flow-cap { font-size: 13.5px; color: var(--ink-55); }
.cs-duo { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 32px; align-items: center; margin-top: 26px; }
.cs-duo .flow { margin-top: 0; }
.cs-notes { list-style: none; display: grid; gap: 18px; }
@media (max-width: 768px) { .cs-duo { grid-template-columns: 1fr; gap: 20px; } }
.cs-notes li { font-size: 14.5px; line-height: 1.55; color: var(--ink-80); padding-top: 12px; border-top: 2px solid var(--accent); }
.cs-notes b { display: block; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
@media (max-width: 768px) { .flow-tab { border-radius: 16px; } .flow-scr { border-radius: 10px; } }

/* research numbers: an editorial row, each figure with a thin bar filled to its value (in the project's colour) */
.cs-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 34px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.cs-stats > div { display: flex; flex-direction: column; padding: 22px 22px 20px; }
.cs-stats > div + div { border-left: 1px solid var(--border); }
.cs-stats > div:first-child { padding-left: 0; }
.cs-stats dt { font-family: var(--sans); font-weight: 300; font-size: clamp(38px, 4.2vw, 52px); line-height: .95; letter-spacing: -.05em; color: var(--ink); font-variant-numeric: tabular-nums; }
.cs-stats dt small { font-size: .42em; font-weight: 400; letter-spacing: 0; margin-left: .08em; vertical-align: .95em; color: var(--ink-55); }
.cs-stats dd { margin-top: 12px; font-size: 13.5px; line-height: 1.5; color: var(--ink-55); }
.cs-stats .bar { display: block; height: 3px; margin-top: auto; padding-top: 0; background: var(--border); border-radius: 2px; overflow: hidden; translate: 0 6px; }
.cs-stats dd { margin-bottom: 18px; }
.cs-stats .bar i { display: block; height: 100%; width: var(--v); background: var(--proj, var(--ink)); border-radius: inherit; transform-origin: left; scale: 0 1; transition: scale 1.1s cubic-bezier(.22, 1, .36, 1); }
.cs-section.shown .cs-stats .bar i { scale: 1 1; }
.cs-stats > div:nth-child(2) .bar i { transition-delay: .1s; } .cs-stats > div:nth-child(3) .bar i { transition-delay: .2s; } .cs-stats > div:nth-child(4) .bar i { transition-delay: .3s; }
@media (prefers-reduced-motion: reduce) { .cs-stats .bar i { scale: 1 1; transition: none; } }
.cs-notes-row { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px 28px; margin-top: 30px; }
@media (max-width: 768px) {
  .cs-stats { grid-template-columns: 1fr 1fr; }
  .cs-stats > div:nth-child(3) { border-left: 0; padding-left: 0; }
  .cs-stats > div:nth-child(n+3) { border-top: 1px solid var(--border); }
  .cs-notes-row { grid-template-columns: 1fr; }
}

/* ---------- case study clips: whole screens in a phone frame, or a cropped close-up of one detail ---------- */
.cs-clips { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; margin-top: 26px; align-items: start; }
.cs-clips.phones { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cs-clips .wide { grid-column: 1 / -1; }
.cs-clips figure { display: grid; gap: 10px; }
.cs-clips figcaption { font-size: 13.5px; color: var(--ink-55); }
.cs-clips video { display: block; width: 100%; height: 100%; object-fit: cover; }
.clip-detail { border-radius: 16px; overflow: hidden; background: #fff6d1; box-shadow: inset 0 0 0 1px var(--border); }
.clip-phone { width: min(100%, 230px); margin: 0 auto; aspect-ratio: 480 / 1040; padding: 6px; border-radius: 30px; background: #15161a; box-shadow: 0 0 0 1px #33363f, 0 18px 36px -18px rgba(60, 40, 0, .45); }
.clip-phone video { border-radius: 24px; }
@media (max-width: 768px) { .cs-clips, .cs-clips.phones { grid-template-columns: 1fr 1fr; gap: 14px; } .clip-phone { border-radius: 22px; padding: 4px; } .clip-phone video { border-radius: 18px; } }
.cs-clips.three { grid-template-columns: 1.1fr 1fr 1fr; align-items: center; }
.cs-clips .wide .clip-detail { max-width: 720px; }
@media (max-width: 768px) { .cs-clips.three { grid-template-columns: 1fr 1fr; } .cs-clips.three figure:first-child { grid-column: 1 / -1; } }

/* ---------- vector demos (Kitabwalah loader + bottom navigation), redrawn so they stay sharp and run slowly ---------- */
.cs-demo { display: grid; gap: 10px; margin-top: 26px; }
.cs-demo figcaption { font-size: 13.5px; color: var(--ink-55); }
.demo { position: relative; border-radius: 16px; background: #fffaf0; box-shadow: inset 0 0 0 1px var(--border); overflow: hidden; }
:root[data-theme="dark"] .demo { background: #fbf6ea; }
.kw-loader { display: grid; justify-items: center; padding: 18px 16px 26px; }
.kw-loader svg { width: min(100%, 420px); overflow: visible; }
.kw-bag { transform-box: fill-box; transform-origin: 50% 100%; }
.kw-loader .it { transform-box: fill-box; transform-origin: center; translate: 200px 150px; opacity: 0; }
.kw-loader.playing .kw-bag { animation: kw-bag 3.6s cubic-bezier(.4, 0, .3, 1) infinite; }
.kw-loader.playing .it { animation: kw-burst 3.6s cubic-bezier(.2, .9, .3, 1) infinite; animation-delay: var(--d); }
.kw-loader:not(.playing) .it { translate: calc(200px + var(--x)) calc(150px + var(--y)); rotate: var(--r); opacity: 1; }
@keyframes kw-bag { 0%, 100% { scale: 1 1; } 10% { scale: 1.06 .9; } 20% { scale: .95 1.07; } 30% { scale: 1.02 .98; } 38%, 92% { scale: 1 1; } }
@keyframes kw-burst {
  0%, 12% { translate: 200px 150px; rotate: 0deg; scale: .3; opacity: 0; }
  16% { opacity: 1; }
  40% { translate: calc(200px + var(--x)) calc(150px + var(--y)); rotate: var(--r); scale: 1; }
  70% { translate: calc(200px + var(--x)) calc(146px + var(--y)); rotate: calc(var(--r) * 1.3); scale: 1; opacity: 1; }
  86%, 100% { translate: 200px 160px; rotate: 0deg; scale: .3; opacity: 0; }
}
.kw-loader-text { margin-top: 6px; font-size: 15px; color: #4a4a4a; }
.kw-loader-text span { animation: kw-dot 1.4s infinite; } .kw-loader-text span:nth-child(2) { animation-delay: .2s; } .kw-loader-text span:nth-child(3) { animation-delay: .4s; }
@keyframes kw-dot { 0%, 60%, 100% { opacity: .2; } 30% { opacity: 1; } }
.kw-nav { padding: 34px 18px; display: grid; place-items: center; }
.kw-bar { display: grid; grid-template-columns: repeat(4, 1fr); width: min(100%, 560px); padding: 10px 6px 12px; border-radius: 14px; background: #fff; box-shadow: 0 10px 30px -14px rgba(80, 60, 0, .3), 0 0 0 1px rgba(0, 0, 0, .05); }
.kw-tab { position: relative; display: grid; justify-items: center; gap: 6px; padding-top: 10px; color: #8d8f96; font-family: Inter, sans-serif; }
.kw-tab svg { width: 30px; height: 30px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: color .3s; }
.kw-tab b { font-size: 13px; font-weight: 500; transition: color .3s, font-weight .3s; }
.kw-tab .mark { position: absolute; top: -6px; width: 26px; height: 4px; border-radius: 3px; background: #f9c51b; scale: 0 1; transition: scale .45s cubic-bezier(.3, 1.4, .5, 1); }
.kw-tab.on { color: #1c1d21; } .kw-tab.on b { font-weight: 700; }
.kw-tab.on .mark { scale: 1 1; }
.kw-nav.playing .kw-tab.on svg { animation: kw-tap .7s cubic-bezier(.3, 1.5, .5, 1); }
.kw-nav.playing .kw-tab.on .spin { transform-box: fill-box; transform-origin: center; animation: kw-spin .9s ease-in-out; }
@keyframes kw-tap { 0% { scale: 1; } 25% { scale: .78; } 60% { scale: 1.18; translate: 0 -3px; } 100% { scale: 1; translate: 0 0; } }
@keyframes kw-spin { to { rotate: 360deg; } }
@media (prefers-reduced-motion: reduce) { .kw-loader .it { translate: calc(200px + var(--x)) calc(150px + var(--y)); rotate: var(--r); opacity: 1; animation: none !important; } }
