/* ============================================================
   SAMAY RAINA — fan site  (MOBILE-FIRST)
   Base styles target ~375px phones; @media (min-width: 700px)
   and (min-width: 1000px) layer up tablet/desktop.
   Theme: "IGL stage" — blood red, blackout, gold latent accents
   ============================================================ */

:root {
  --bg: #0b0407;
  --bg-2: #140a0c;
  --panel: #170b0e;
  --line: #3a1418;
  --crimson: #e62329;
  --crimson-hot: #ff3b41;
  --maroon: #8f1116;
  --gold: #f2b90d;
  --cream: #f6eedd;
  --cream-dim: #cbb9a4;
  --ink: #17100c;
  --font-display: "Anton", "Arial Narrow", Impact, sans-serif;
  --font-body: "Archivo", "Helvetica Neue", sans-serif;
  --font-scribble: "Kalam", "Comic Sans MS", cursive;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  background: var(--bg);
  color: var(--cream);
  font-family: var(--font-body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--crimson); color: var(--cream); }
a { color: inherit; text-decoration: none; }
img, svg { max-width: 100%; }
button { -webkit-tap-highlight-color: transparent; }

.grain {
  position: fixed; inset: 0; z-index: 50; pointer-events: none; opacity: .07;
  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='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
}

/* ============ NAV ============ */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: calc(10px + env(safe-area-inset-top)) 16px 10px;
  background: rgba(11, 4, 7, .85);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(230, 35, 41, .25);
}
.nav-logo { font-family: var(--font-display); font-size: 1.35rem; letter-spacing: .06em; color: var(--cream); }
.nav-logo .knight { color: var(--crimson); margin-left: 2px; }
.nav-links { display: none; }
.nav-links a {
  font-weight: 700; font-size: .82rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--cream-dim); transition: color .2s;
}
.nav-links a:hover { color: var(--crimson-hot); }
.nav-cta {
  font-family: var(--font-display); font-size: .82rem; letter-spacing: .08em;
  background: var(--crimson); color: var(--cream);
  padding: 8px 12px; border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 rgba(0,0,0,.55);
  transition: transform .15s, box-shadow .15s;
  white-space: nowrap;
}
.nav-cta:hover { transform: translate(-2px,-2px); box-shadow: 5px 5px 0 rgba(0,0,0,.55); }

/* ============ HERO ============ */
.hero {
  position: relative; min-height: 100svh;
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  padding: calc(90px + env(safe-area-inset-top)) 18px 84px;
  background:
    radial-gradient(85% 70% at 50% 0%, rgba(143, 17, 22, .5), transparent 60%),
    var(--bg);
  overflow: hidden;
}
.hero-spot {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(52% 38% at 50% 32%, rgba(230, 35, 41, .35), transparent 70%);
  animation: spotBreathe 6s ease-in-out infinite;
}
@keyframes spotBreathe { 50% { opacity: .65; } }
.hero-chess {
  position: absolute; left: 0; right: 0; bottom: 38px; height: 170px; pointer-events: none;
  background: repeating-conic-gradient(rgba(246,238,221,.05) 0% 25%, transparent 0% 50%) 0 0 / 56px 56px;
  -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,.9), transparent);
          mask-image: linear-gradient(to top, rgba(0,0,0,.9), transparent);
  transform: perspective(500px) rotateX(48deg) scale(1.35);
  transform-origin: bottom;
}
.hero-inner { position: relative; z-index: 2; max-width: 980px; }
.hero-kicker {
  display: inline-flex; align-items: center; gap: 9px;
  font-weight: 700; font-size: .68rem; letter-spacing: .28em; text-transform: uppercase;
  color: var(--crimson-hot); margin-bottom: 16px;
}
.hero-title { font-family: var(--font-display); line-height: .88; animation: heroRise .9s cubic-bezier(.2,.9,.25,1) both; }
.hero-title .line-1 {
  display: block; font-size: clamp(4.4rem, 22vw, 11.5rem);
  color: var(--cream); letter-spacing: .01em;
  text-shadow: 0 0 60px rgba(230,35,41,.35);
}
.hero-title .line-2 {
  display: block; font-size: clamp(4.4rem, 22vw, 11.5rem);
  color: transparent; -webkit-text-stroke: 2.5px var(--crimson);
  letter-spacing: .01em; margin-top: -.08em;
}
@keyframes heroRise { from { transform: translateY(40px); opacity: 0; } }
.hero-scribble {
  font-family: var(--font-scribble); font-weight: 700;
  color: var(--gold); font-size: clamp(1.05rem, 4.5vw, 1.6rem);
  transform: rotate(-2deg); margin: 14px 0 10px;
}
.hero-sub {
  color: var(--cream-dim); font-size: clamp(.9rem, 3.6vw, 1.12rem);
  line-height: 1.6; max-width: 620px; margin: 0 auto 26px;
}
.hero-sub em { color: var(--cream); font-style: normal; font-weight: 700; }
.hero-ctas { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

.btn {
  display: inline-block;
  font-family: var(--font-display); font-size: 1rem; letter-spacing: .1em;
  padding: 14px 24px; border: 2px solid var(--ink); cursor: pointer;
  transition: transform .15s, box-shadow .15s, background .2s, color .2s;
  min-height: 48px;
}
.btn-solid { background: var(--crimson); color: var(--cream); box-shadow: 5px 5px 0 rgba(0,0,0,.6); }
.btn-solid:hover { transform: translate(-2px,-2px); box-shadow: 8px 8px 0 rgba(0,0,0,.6); background: var(--crimson-hot); }
.btn-ghost { background: transparent; color: var(--cream); border-color: var(--cream); box-shadow: 5px 5px 0 rgba(230,35,41,.35); }
.btn-ghost:hover { background: var(--cream); color: var(--ink); transform: translate(-2px,-2px); }
.btn-knight { color: var(--gold); }

/* stickers */
.sticker {
  position: absolute; z-index: 3;
  font-family: var(--font-display); font-size: .72rem; line-height: 1.15;
  letter-spacing: .08em; text-align: center;
  padding: 8px 11px; border: 3px solid var(--ink);
  box-shadow: 4px 4px 0 rgba(0,0,0,.5);
  animation: stickerIn .7s cubic-bezier(.2,1.4,.4,1) both;
}
.sticker-1 { top: calc(13% + env(safe-area-inset-top)); left: 4%; background: var(--crimson); color: var(--cream); transform: rotate(-9deg); animation-delay: .5s; }
.sticker-2 { top: calc(14% + env(safe-area-inset-top)); right: 4%; background: var(--cream); color: var(--ink); transform: rotate(6deg); animation-delay: .7s; }
.sticker-3 { display: none; bottom: 24%; right: 12%; background: var(--ink); color: var(--gold); border-color: var(--crimson); transform: rotate(-5deg); animation-delay: .9s; }
@keyframes stickerIn { from { opacity: 0; scale: .4; } }

/* ticker */
.ticker {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 4;
  background: #0d0508; border-top: 2px solid var(--crimson); border-bottom: 2px solid var(--crimson);
  overflow: hidden; padding: 8px 0;
}
.ticker-track {
  display: inline-flex; align-items: center; gap: 1.8rem; white-space: nowrap;
  font-family: var(--font-display); font-size: .92rem; letter-spacing: .14em; color: var(--cream);
  animation: tick 30s linear infinite;
}
.ticker-track i { font-style: normal; color: var(--crimson); }
@keyframes tick { to { transform: translateX(-50%); } }

.live-dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--crimson-hot);
  box-shadow: 0 0 0 0 rgba(230,35,41,.7); animation: livePulse 1.6s infinite;
  display: inline-block; flex: none;
}
@keyframes livePulse { 70% { box-shadow: 0 0 0 9px rgba(230,35,41,0); } }

/* ============ SECTION HEADERS ============ */
.section-title {
  position: relative; text-align: center;
  font-family: var(--font-display); font-size: clamp(2.1rem, 8vw, 4rem);
  letter-spacing: .04em; color: var(--cream); z-index: 1;
}
.section-title span { color: var(--crimson); }
.section-title::before {
  content: attr(data-bg);
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-52%);
  /* Sized to stay inside the title band — at 26vw/14rem the word spilled under
     the content below and read as "cut off". */
  font-size: clamp(4rem, 14vw, 8.5rem); color: transparent;
  -webkit-text-stroke: 2px rgba(246,238,221,.07);
  z-index: -1; white-space: nowrap;
}
.section-sub {
  text-align: center; color: var(--cream-dim); margin-top: 8px;
  font-family: var(--font-scribble); font-size: 1.05rem; transform: rotate(-1deg);
  padding: 0 18px;
}

/* ============ CHAT STAGE (mobile: buddy stacked over chat) ============ */
.stage { padding: 86px 14px 60px; position: relative; }
.stage-grid {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  max-width: 1080px; margin: 30px auto 0;
}

/* ---- buddy ---- */
.buddy-zone { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.buddy { position: relative; width: 172px; }
.buddy-svg { width: 100%; display: block; position: relative; z-index: 2; }
.buddy-spot {
  position: absolute; left: 50%; bottom: -4px; transform: translateX(-50%);
  width: 185px; height: 215px; z-index: 1; pointer-events: none;
  background: linear-gradient(to bottom, transparent 0%, rgba(230,35,41,.13) 55%, rgba(230,35,41,.28) 100%);
  clip-path: polygon(38% 0, 62% 0, 100% 100%, 0 100%);
  filter: blur(2px);
}
.buddy-caption {
  font-weight: 700; letter-spacing: .2em; font-size: .62rem; text-transform: uppercase;
  color: var(--cream-dim); text-align: center;
}
.buddy-caption span { color: var(--crimson); }

.buddy-bubble {
  position: absolute; z-index: 5; left: 50%; top: -8px;
  max-width: min(240px, 72vw); width: max-content;
  font-family: var(--font-scribble); font-weight: 700; font-size: .95rem; line-height: 1.3;
  background: var(--cream); color: var(--ink);
  border: 3px solid var(--ink); border-radius: 14px; padding: 9px 13px;
  box-shadow: 5px 5px 0 rgba(0,0,0,.45);
  opacity: 0; transform: translate(-50%,-88%) scale(.7); transform-origin: bottom center;
  transition: opacity .25s, transform .25s cubic-bezier(.2,1.4,.4,1);
  pointer-events: none;
}
.buddy-bubble::after {
  content: ""; position: absolute; left: 50%; bottom: -9px; margin-left: -7px;
  width: 14px; height: 14px; background: var(--cream);
  border-right: 3px solid var(--ink); border-bottom: 3px solid var(--ink);
  transform: rotate(45deg);
}
.buddy-bubble.show { opacity: 1; transform: translate(-50%,-100%) scale(1); }

/* hanging Edison bulbs (his stage look) */
.stage-bulbs { position: absolute; left: 0; right: 0; top: -34px; height: 0; z-index: 1; pointer-events: none; }
.bulb {
  position: absolute; top: 0; width: 2px;
  background: linear-gradient(#3a2517, #1a0f0a);
  transform-origin: top center;
  animation: bulbSway 5.5s ease-in-out infinite;
}
.bulb i {
  position: absolute; bottom: -14px; left: 50%; transform: translateX(-50%);
  width: 14px; height: 18px; border-radius: 50% 50% 46% 46%;
  background: radial-gradient(circle at 50% 62%, #ffd98a 0%, #f2b90d 45%, #8a5a06 100%);
  box-shadow: 0 0 16px 4px rgba(242, 185, 13, .35), 0 0 40px 10px rgba(242, 185, 13, .12);
  animation: bulbFlicker 4s steps(1) infinite;
}
.bulb-1 { left: 14%; height: 52px; animation-delay: .4s; }
.bulb-2 { left: 50%; height: 30px; }
.bulb-3 { left: 84%; height: 64px; animation-delay: 1.1s; }
.bulb-2 i { animation-delay: 1.6s; }
.bulb-3 i { animation-delay: .7s; }
@keyframes bulbSway { 0%, 100% { transform: rotate(2.5deg); } 50% { transform: rotate(-2.5deg); } }
@keyframes bulbFlicker { 0%, 91%, 95%, 100% { opacity: 1; } 92%, 94% { opacity: .55; } }

/* confetti */
.buddy-fx { position: absolute; inset: 0; z-index: 6; pointer-events: none; }
.buddy-fx span { position: absolute; left: 50%; top: 40%; width: 8px; height: 13px; opacity: 0; background: var(--gold); }
.buddy-fx span:nth-child(3n) { background: var(--crimson); }
.buddy-fx span:nth-child(3n+1) { background: var(--cream); }
.buddy.is-party .buddy-fx span { animation: confetti 1.15s ease-out forwards; }
@keyframes confetti {
  0% { opacity: 1; transform: translate(0,0) rotate(0); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--rot)); }
}

/* ---- buddy rig defaults ---- */
.b-all { animation: buddyBob 3.4s ease-in-out infinite; }
@keyframes buddyBob { 50% { transform: translateY(-4px); } }
.b-all, .b-head, .b-arm, .b-leg, .b-eyes, .b-brow, .b-pupil, .m, .h,
.p-mic, .p-crown, .p-knight, .p-zzz, .p-shades, .p-sweat, .p-fire, .p-tear, .p-hearts, .z {
  transform-box: fill-box;
}
.b-head { transform-origin: 50% 88%; transition: transform .3s; }
.b-arm { transform-origin: 50% 8%; transition: transform .35s cubic-bezier(.3,1.3,.4,1); }
.b-leg { transform-origin: 50% 6%; transition: transform .3s; }
.b-eyes { transform-origin: center; transition: transform .12s; }
.b-brow { transform-origin: center; transition: transform .25s; }
.b-pupil { transition: transform .25s; }

.m { opacity: 0; transition: opacity .12s; }
.m-smile { opacity: 1; }
.p-mic, .p-crown, .p-knight, .p-zzz, .p-shades, .p-sweat, .p-fire, .p-tear, .p-hearts { opacity: 0; transition: opacity .25s, transform .3s; }
.e-happy, .e-closed, .e-shock { opacity: 0; }
.e-open { opacity: 1; }

.buddy.is-blink .e-open { transform: scaleY(.1); }
.buddy.is-tilt .b-head { transform: rotate(7deg); }
.buddy.is-look .b-pupil { transform: translateX(-3.5px); }

/* ---- MOOD: talk ---- */
[data-mood="talk"] .m-smile { opacity: 0; }
[data-mood="talk"] .m-talk { opacity: 1; animation: chatter .28s ease-in-out infinite; transform-origin: center; }
@keyframes chatter { 50% { transform: scaleY(.35); } }
[data-mood="talk"] .b-arm-r { transform: rotate(112deg); }
[data-mood="talk"] .p-mic { opacity: 1; }

/* ---- MOOD: think ---- */
[data-mood="think"] .m-smile { opacity: 0; }
[data-mood="think"] .m-flat { opacity: 1; }
[data-mood="think"] .b-pupil { transform: translate(-3px,-3px); }
[data-mood="think"] .b-brow-l { transform: rotate(-12deg) translateY(-2px); }
[data-mood="think"] .b-brow-r { transform: rotate(7deg); }
[data-mood="think"] .b-arm-l { transform: rotate(-118deg); }
[data-mood="think"] .b-head { transform: rotate(-4deg); }
[data-mood="think"] .p-knight { opacity: 1; animation: knightFloat 2.2s ease-in-out infinite; }
@keyframes knightFloat { 50% { transform: translateY(-7px) rotate(-8deg); } }

/* ---- MOOD: laugh ---- */
[data-mood="laugh"] .m-smile { opacity: 0; }
[data-mood="laugh"] .m-open { opacity: 1; }
[data-mood="laugh"] .e-open { opacity: 0; }
[data-mood="laugh"] .e-happy { opacity: 1; }
[data-mood="laugh"] .b-all { animation: laughShake .5s ease-in-out infinite; }
@keyframes laughShake {
  0%, 100% { transform: rotate(-2.5deg) translateY(0); }
  50% { transform: rotate(2.5deg) translateY(-6px); }
}

/* ---- MOOD: roast ---- */
[data-mood="roast"] .m-smile { opacity: 0; }
[data-mood="roast"] .m-smirk { opacity: 1; }
[data-mood="roast"] .p-shades { opacity: 1; animation: shadesDrop .45s cubic-bezier(.2,1.2,.4,1) both; }
@keyframes shadesDrop { from { transform: translateY(-46px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
[data-mood="roast"] .p-fire { opacity: 1; animation: firePulse 1.1s ease-in-out infinite; }
@keyframes firePulse { 50% { transform: scale(1.12); opacity: .7; } }
[data-mood="roast"] .b-arm-r { transform: rotate(-32deg); }
[data-mood="roast"] .p-mic { opacity: 1; }
[data-mood="roast"] .b-head { transform: rotate(3deg); }

/* ---- MOOD: shock ---- */
[data-mood="shock"] .m-smile { opacity: 0; }
[data-mood="shock"] .m-oh { opacity: 1; }
[data-mood="shock"] .e-open { opacity: 0; }
[data-mood="shock"] .e-shock { opacity: 1; }
[data-mood="shock"] .p-sweat { opacity: 1; animation: sweatDrip 1s ease-in infinite; }
@keyframes sweatDrip { 0% { transform: translateY(0); opacity: 1; } 100% { transform: translateY(10px); opacity: 0; } }
[data-mood="shock"] .b-all { animation: shockJump .45s cubic-bezier(.3,1.6,.4,1) 2; }
@keyframes shockJump { 30% { transform: translateY(-14px); } }
[data-mood="shock"] .b-brow-l, [data-mood="shock"] .b-brow-r { transform: translateY(-5px); }

/* ---- MOOD: gg ---- */
[data-mood="gg"] .m-smile { opacity: 0; }
[data-mood="gg"] .m-open { opacity: 1; }
[data-mood="gg"] .e-open { opacity: 0; }
[data-mood="gg"] .e-happy { opacity: 1; }
[data-mood="gg"] .p-crown { opacity: 1; animation: crownDrop .5s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes crownDrop { from { transform: translateY(-36px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
[data-mood="gg"] .b-arm-l { transform: rotate(162deg); }
[data-mood="gg"] .b-arm-r { transform: rotate(-162deg); }
[data-mood="gg"] .b-all { animation: ggBounce .6s ease-in-out infinite; }
@keyframes ggBounce { 50% { transform: translateY(-8px); } }

/* ---- MOOD: sleep ---- */
[data-mood="sleep"] .m-smile { opacity: 0; }
[data-mood="sleep"] .m-flat { opacity: 1; }
[data-mood="sleep"] .e-open { opacity: 0; }
[data-mood="sleep"] .e-closed { opacity: 1; }
[data-mood="sleep"] .b-head { transform: rotate(9deg) translateY(3px); }
[data-mood="sleep"] .b-all { animation: buddyBob 5.5s ease-in-out infinite; }
[data-mood="sleep"] .p-zzz { opacity: 1; }
[data-mood="sleep"] .z { animation: zFloat 2.4s ease-in-out infinite; opacity: 0; }
[data-mood="sleep"] .z2 { animation-delay: .5s; }
[data-mood="sleep"] .z3 { animation-delay: 1s; }
@keyframes zFloat {
  0% { opacity: 0; transform: translate(0,6px); }
  40% { opacity: 1; }
  100% { opacity: 0; transform: translate(6px,-12px); }
}

/* ---- MOOD: wave (greeting) ---- */
[data-mood="wave"] .e-open { opacity: 0; }
[data-mood="wave"] .e-happy { opacity: 1; }
[data-mood="wave"] .b-arm-r { animation: waveArm .8s ease-in-out infinite; }
@keyframes waveArm { 0%, 100% { transform: rotate(-135deg); } 50% { transform: rotate(-168deg); } }
[data-mood="wave"] .b-head { transform: rotate(-5deg); }

/* ---- MOOD: dance (groove) + variant .dance-b (bhangra hop) ---- */
[data-mood="dance"] .m-smile { opacity: 0; }
[data-mood="dance"] .m-open { opacity: 1; }
[data-mood="dance"] .e-open { opacity: 0; }
[data-mood="dance"] .e-happy { opacity: 1; }
[data-mood="dance"] .b-all { animation: danceSway .64s ease-in-out infinite alternate; }
@keyframes danceSway {
  0% { transform: rotate(-5deg) translateY(0); }
  50% { transform: rotate(0deg) translateY(-7px); }
  100% { transform: rotate(5deg) translateY(0); }
}
[data-mood="dance"] .b-head { animation: danceHead .32s ease-in-out infinite alternate; }
@keyframes danceHead { from { transform: rotate(-7deg); } to { transform: rotate(7deg); } }
[data-mood="dance"] .b-arm-l { animation: dancePump .64s ease-in-out infinite; }
[data-mood="dance"] .b-arm-r { animation: dancePumpR .64s ease-in-out infinite; }
@keyframes dancePump { 0%, 100% { transform: rotate(18deg); } 50% { transform: rotate(95deg); } }
@keyframes dancePumpR { 0%, 100% { transform: rotate(-95deg); } 50% { transform: rotate(-18deg); } }
[data-mood="dance"] .b-leg-l { animation: kick .64s ease-in-out infinite; }
[data-mood="dance"] .b-leg-r { animation: kick .64s ease-in-out infinite; animation-delay: .32s; }
@keyframes kick { 0%, 100% { transform: rotate(0); } 50% { transform: rotate(12deg) translateY(-3px); } }

.buddy.dance-b[data-mood="dance"] .b-all { animation: bhangraHop .5s ease-in-out infinite; }
@keyframes bhangraHop { 0%, 100% { transform: translateY(0) rotate(-3deg); } 50% { transform: translateY(-13px) rotate(3deg); } }
.buddy.dance-b[data-mood="dance"] .b-arm-l { animation: bhangraArmL .5s ease-in-out infinite; }
.buddy.dance-b[data-mood="dance"] .b-arm-r { animation: bhangraArmR .5s ease-in-out infinite; }
@keyframes bhangraArmL { 0%, 100% { transform: rotate(115deg); } 50% { transform: rotate(155deg); } }
@keyframes bhangraArmR { 0%, 100% { transform: rotate(-155deg); } 50% { transform: rotate(-115deg); } }
.buddy.dance-b[data-mood="dance"] .b-leg-l { animation: bhangraLegL .5s ease-in-out infinite; }
.buddy.dance-b[data-mood="dance"] .b-leg-r { animation: bhangraLegR .5s ease-in-out infinite; }
@keyframes bhangraLegL { 0%, 100% { transform: rotate(0); } 50% { transform: rotate(-16deg) translateY(-5px); } }
@keyframes bhangraLegR { 0%, 100% { transform: rotate(16deg) translateY(-5px); } 50% { transform: rotate(0); } }

/* ---- MOOD: cry ---- */
[data-mood="cry"] .m-smile { opacity: 0; }
[data-mood="cry"] .m-sad { opacity: 1; }
[data-mood="cry"] .e-open { opacity: 0; }
[data-mood="cry"] .e-closed { opacity: 1; }
[data-mood="cry"] .b-brow-l { transform: rotate(-14deg) translateY(1px); }
[data-mood="cry"] .b-brow-r { transform: rotate(14deg) translateY(1px); }
[data-mood="cry"] .p-tear { opacity: 1; }
[data-mood="cry"] .p-tear-l { animation: tearDrip 1.1s ease-in infinite; }
[data-mood="cry"] .p-tear-r { animation: tearDrip 1.1s ease-in infinite .5s; }
@keyframes tearDrip { 0% { transform: translateY(0); opacity: 1; } 100% { transform: translateY(14px); opacity: 0; } }
[data-mood="cry"] .b-all { animation: sob .55s ease-in-out infinite; }
@keyframes sob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(2.5px); } }

/* ---- MOOD: love ---- */
[data-mood="love"] .e-open { opacity: 0; }
[data-mood="love"] .e-happy { opacity: 1; }
[data-mood="love"] .p-hearts { opacity: 1; }
[data-mood="love"] .h { animation: heartFloat 1.7s ease-out infinite; opacity: 0; }
[data-mood="love"] .h2 { animation-delay: .4s; }
[data-mood="love"] .h3 { animation-delay: .8s; }
@keyframes heartFloat {
  0% { opacity: 0; transform: translateY(8px) scale(.5); }
  30% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-22px) scale(1.1); }
}
[data-mood="love"] .b-head { transform: rotate(5deg); }
[data-mood="love"] .b-arm-l { transform: rotate(24deg); }
[data-mood="love"] .b-arm-r { transform: rotate(-24deg); }

/* ---- MOOD: facepalm ---- */
[data-mood="facepalm"] .m-smile { opacity: 0; }
[data-mood="facepalm"] .m-flat { opacity: 1; }
[data-mood="facepalm"] .e-open { opacity: 0; }
[data-mood="facepalm"] .e-closed { opacity: 1; }
[data-mood="facepalm"] .b-arm-r { transform: rotate(122deg) translateY(-3px); }
[data-mood="facepalm"] .b-head { transform: rotate(6deg) translateY(3px); }
[data-mood="facepalm"] .b-brow-l { transform: rotate(-10deg); }
[data-mood="facepalm"] .b-brow-r { transform: rotate(10deg); }

/* ---- MOOD: hype (clap) ---- */
[data-mood="hype"] .m-smile { opacity: 0; }
[data-mood="hype"] .m-open { opacity: 1; }
[data-mood="hype"] .e-open { opacity: 0; }
[data-mood="hype"] .e-happy { opacity: 1; }
[data-mood="hype"] .b-arm-l { animation: clapL .3s ease-in-out infinite; }
[data-mood="hype"] .b-arm-r { animation: clapR .3s ease-in-out infinite; }
@keyframes clapL { 0%, 100% { transform: rotate(-40deg); } 50% { transform: rotate(-64deg); } }
@keyframes clapR { 0%, 100% { transform: rotate(40deg); } 50% { transform: rotate(64deg); } }
[data-mood="hype"] .b-all { animation: ggBounce .55s ease-in-out infinite; }

/* ============ CHAT WINDOW ============ */
.chat {
  width: 100%;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 18px;
  display: flex; flex-direction: column;
  height: min(56dvh, 620px);
  min-height: 400px;
  overflow: hidden;
  box-shadow: 0 30px 80px rgba(0,0,0,.55), 0 0 0 1px rgba(230,35,41,.08), 0 0 90px rgba(230,35,41,.07);
}
.chat-head {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  background: linear-gradient(#200e12, #170b0e);
  border-bottom: 2px solid var(--crimson);
}
.chat-head-txt { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.chat-head-txt strong { font-size: .95rem; letter-spacing: .04em; }
.chat-head-txt small { color: var(--cream-dim); font-size: .66rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-head-txt code { color: var(--gold); font-size: .66rem; }
.chat-elo {
  margin-left: auto; font-family: var(--font-display); font-size: .74rem;
  color: var(--gold); border: 1px solid rgba(242,185,13,.4);
  padding: 4px 9px; border-radius: 999px; letter-spacing: .1em; flex: none;
}

.chat-log { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 14px; display: flex; flex-direction: column; gap: 13px; overscroll-behavior: contain; }
.chat-log::-webkit-scrollbar { width: 6px; }
.chat-log::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }

.msg { max-width: 86%; padding: 10px 14px; border-radius: 16px; font-size: .93rem; line-height: 1.5; animation: msgIn .3s cubic-bezier(.2,1.2,.4,1) both; overflow-wrap: break-word; }
@keyframes msgIn { from { opacity: 0; transform: translateY(10px) scale(.96); } }
.msg-user { align-self: flex-end; background: linear-gradient(135deg, var(--crimson), var(--maroon)); color: #fff; border-bottom-right-radius: 4px; }
.msg-bot { align-self: flex-start; background: #241014; border: 1px solid #45181d; border-bottom-left-radius: 4px; }
.msg-name { display: block; font-size: .6rem; font-weight: 900; letter-spacing: .24em; color: var(--crimson-hot); margin-bottom: 4px; text-transform: uppercase; }
.msg-bot .cursor { display: inline-block; width: 8px; background: var(--crimson); animation: blinkCursor .7s steps(1) infinite; }
@keyframes blinkCursor { 50% { opacity: 0; } }

.typing { display: flex; align-items: center; gap: 10px; align-self: flex-start; color: var(--cream-dim); }
.typing .dots { display: flex; gap: 4px; }
.typing .dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--crimson); animation: dotHop 1s ease-in-out infinite; }
.typing .dots i:nth-child(2) { animation-delay: .15s; }
.typing .dots i:nth-child(3) { animation-delay: .3s; }
@keyframes dotHop { 40% { transform: translateY(-6px); } }
.typing .status { font-family: var(--font-scribble); font-size: .92rem; }

.latent-card {
  align-self: center; text-align: center;
  border: 3px double var(--gold); border-radius: 12px;
  background: #1a1006; color: var(--gold);
  padding: 12px 22px; margin: 6px 0; transform: rotate(-1.5deg);
  animation: msgIn .4s both;
}
.latent-card .lt-label { font-size: .6rem; font-weight: 900; letter-spacing: .3em; }
.latent-card .lt-score { font-family: var(--font-display); font-size: 2.2rem; line-height: 1.1; }
.latent-card .lt-remark { font-family: var(--font-scribble); font-size: .92rem; color: var(--cream); }

.chat-chips {
  display: flex; gap: 8px; padding: 10px 12px;
  border-top: 1px solid var(--line);
  overflow-x: auto; flex-wrap: nowrap;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.chat-chips::-webkit-scrollbar { display: none; }
.chat-chips button {
  font-family: var(--font-body); font-weight: 700; font-size: .8rem;
  color: var(--cream-dim); background: transparent;
  border: 1px solid var(--line); border-radius: 999px;
  padding: 9px 15px; cursor: pointer; transition: all .2s;
  white-space: nowrap; flex: none; min-height: 38px;
}
.chat-chips button:hover, .chat-chips button:focus-visible { border-color: var(--crimson); color: #fff; background: rgba(230,35,41,.14); }

.chat-input { display: flex; gap: 9px; padding: 12px; border-top: 1px solid var(--line); background: #10070a; }
.chat-input input {
  flex: 1; min-width: 0; background: #0c0508; color: var(--cream);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 14px; font-family: var(--font-body);
  font-size: 16px; /* 16px+ prevents iOS zoom-on-focus */
  outline: none; transition: border-color .2s, box-shadow .2s;
}
.chat-input input:focus { border-color: var(--crimson); box-shadow: 0 0 0 3px rgba(230,35,41,.15); }
.chat-input input::placeholder { color: #7a5f58; }
.chat-input button {
  width: 50px; min-height: 48px; border: 2px solid var(--ink); border-radius: 10px;
  background: var(--crimson); color: var(--cream); font-size: 1rem; cursor: pointer;
  box-shadow: 3px 3px 0 rgba(0,0,0,.5); transition: transform .12s, box-shadow .12s, background .2s;
  flex: none;
}
.chat-input button:hover { transform: translate(-1px,-1px); box-shadow: 4px 4px 0 rgba(0,0,0,.5); background: var(--crimson-hot); }
.chat-input button:active { transform: translate(2px,2px); box-shadow: 0 0 0 rgba(0,0,0,.5); }

.stage-disclaimer { text-align: center; margin-top: 22px; font-family: var(--font-scribble); color: #8a6f60; font-size: .92rem; }
.stage-disclaimer strong { display: block; font-family: var(--font-display); letter-spacing: .09em; font-size: .72rem; color: var(--cream-dim); }
.stage-disclaimer span { display: block; margin-top: 3px; }

/* ============ LORE (mobile: swipe carousel) ============ */
.lore { padding: 70px 0; background: linear-gradient(var(--bg), #100609 50%, var(--bg)); }
.lore-grid {
  display: flex; gap: 14px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: 40px 20px 10px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  max-width: 1150px; margin: 0 auto;
}
.lore-grid::-webkit-scrollbar { display: none; }
.card {
  position: relative; background: var(--bg-2);
  border: 1px solid var(--line); border-radius: 14px;
  padding: 26px 20px 54px;
  flex: 0 0 76%;
  scroll-snap-align: center;
  transition: transform .25s, border-color .25s, box-shadow .25s;
}
.card:nth-child(odd) { transform: rotate(-1.1deg); }
.card:nth-child(even) { transform: rotate(1.1deg); }
.card:hover {
  transform: rotate(0) translateY(-8px);
  border-color: var(--crimson);
  box-shadow: 0 24px 50px rgba(0,0,0,.5), 0 0 40px rgba(230,35,41,.12);
}
.card-icon { font-size: 2.1rem; margin-bottom: 12px; }
.card h3 { font-family: var(--font-display); font-size: 1.3rem; letter-spacing: .04em; margin-bottom: 9px; color: var(--cream); }
.card p { color: var(--cream-dim); font-size: .88rem; line-height: 1.6; }
.card-tag {
  position: absolute; left: 20px; bottom: 16px;
  font-family: var(--font-display); font-size: .7rem; letter-spacing: .16em;
  color: var(--crimson-hot); border: 1px solid rgba(230,35,41,.4);
  padding: 4px 10px; border-radius: 999px;
}

/* ============ TOUR ============ */
.tour { padding: 30px 0 0; }
.tour-inner { background: var(--crimson); color: var(--ink); text-align: center; padding: 56px 20px 64px; position: relative; overflow: hidden; }
.tour-inner::before {
  content: "STILL ALIVE STILL ALIVE STILL ALIVE STILL ALIVE";
  position: absolute; inset: -14px 0 auto; white-space: nowrap;
  font-family: var(--font-display); font-size: 6.5rem; line-height: 1;
  color: transparent; -webkit-text-stroke: 2px rgba(11,4,7,.16);
  pointer-events: none;
}
.tour-kicker { font-weight: 900; letter-spacing: .34em; font-size: .72rem; position: relative; }
.tour-title { font-family: var(--font-display); font-size: clamp(3rem, 14vw, 7rem); line-height: .95; margin: 10px 0 12px; position: relative; color: var(--ink); }
.tour-title em { font-style: normal; color: var(--cream); text-shadow: 4px 4px 0 rgba(11,4,7,.35); }
.tour-sub { max-width: 480px; margin: 0 auto 26px; font-weight: 500; position: relative; font-size: .95rem; }
.tour .btn-solid { background: var(--ink); color: var(--cream); border-color: var(--ink); box-shadow: 5px 5px 0 rgba(11,4,7,.3); position: relative; }
.tour .btn-solid:hover { background: #000; }

/* ============ FOOTER ============ */
.footer { text-align: center; padding: 50px 20px calc(34px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
.footer-logo { font-family: var(--font-display); font-size: 1.7rem; letter-spacing: .06em; }
.footer-logo span { color: var(--crimson); }
.footer-links { display: flex; gap: 22px; justify-content: center; margin: 16px 0; flex-wrap: wrap; }
.footer-links a { color: var(--cream-dim); font-weight: 700; font-size: .8rem; letter-spacing: .14em; text-transform: uppercase; transition: color .2s; padding: 8px 4px; }
.footer-links a:hover { color: var(--crimson-hot); }
.footer-note { color: #7a5f58; font-size: .76rem; line-height: 1.5; }
.footer-note a { text-decoration: underline; text-underline-offset: 2px; }
.footer-note a:hover { color: var(--crimson-hot); }

/* ============================================================
   TABLET & UP  (min-width: 700px)
   ============================================================ */
@media (min-width: 700px) {
  .nav { padding-left: 24px; padding-right: 24px; }
  .nav-logo { font-size: 1.5rem; }
  .nav-cta { font-size: .95rem; padding: 8px 16px; }
  .hero { padding-bottom: 90px; }
  .hero-kicker { font-size: .8rem; letter-spacing: .32em; }
  .hero-title .line-1, .hero-title .line-2 { font-size: clamp(4.2rem, 15vw, 11.5rem); }
  .hero-title .line-2 { -webkit-text-stroke-width: 3px; }
  .sticker { font-size: .95rem; padding: 12px 16px; }
  .sticker-1 { top: 20%; left: 6%; }
  .sticker-2 { top: 26%; right: 7%; }
  .sticker-3 { display: block; }
  .ticker-track { font-size: 1.05rem; gap: 2.2rem; }
  .hero-chess { height: 220px; background-size: 72px 72px; }

  .stage { padding: 100px 24px 70px; }
  .buddy { width: 240px; }
  .buddy-spot { width: 230px; height: 290px; }
  .buddy-caption { font-size: .72rem; }

  .chat { height: 580px; }
  .chat-chips { flex-wrap: wrap; }

  .lore { padding: 90px 24px; }
  .lore-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; overflow: visible; padding: 54px 0 0; }
  .card { flex: none; }

  .tour-inner { padding: 70px 24px 80px; }
  .tour-inner::before { font-size: 9rem; }
}

/* ============================================================
   DESKTOP  (min-width: 1000px)
   ============================================================ */
@media (min-width: 1000px) {
  .nav-links { display: flex; gap: 26px; }
  /* One-screen stage: title + buddy + FULL chat (log, chips, input) must all fit
     inside the viewport with no scrolling — the section is a 100dvh flex column
     and the chat stretches to whatever height remains. */
  .stage {
    height: 100dvh; min-height: 100dvh; max-height: 100dvh;
    padding: 84px 24px 20px;
    display: flex; flex-direction: column; overflow: hidden;
  }
  .stage-grid {
    display: grid; grid-template-columns: 360px 1fr; gap: 40px;
    align-items: stretch; flex: 1; min-height: 0; margin-top: 14px;
  }
  .section-title { font-size: clamp(2.1rem, 4.5vw, 3.2rem); }
  .buddy-zone { justify-content: flex-end; }
  .buddy { width: 300px; }
  .buddy-spot { width: 260px; height: 330px; }
  .buddy-bubble { left: 58%; transform-origin: bottom left; transform: translate(0,-88%) scale(.7); }
  .buddy-bubble.show { transform: translate(0,-100%) scale(1); }
  .buddy-bubble::after { left: 18px; margin-left: 0; }
  .chat { height: auto; min-height: 0; }
  .stage-disclaimer { margin-top: 12px; }
  .lore-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ============================================================
   LANDSCAPE PHONES / SHORT SCREENS
   ============================================================ */
@media (max-height: 520px) {
  .chat { height: 82dvh; min-height: 320px; }
}
@media (min-width: 700px) and (max-height: 520px) {
  .stage { padding-top: 76px; }
  .stage-grid { display: grid; grid-template-columns: 250px 1fr; gap: 24px; align-items: end; }
  .buddy { width: 185px; }
  .buddy-spot { width: 195px; height: 235px; }
  .stage-bulbs { top: -20px; }
  .bulb-1 { height: 34px; } .bulb-2 { height: 18px; } .bulb-3 { height: 42px; }
}

/* ============ REDUCED MOTION ============ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  .ticker-track { animation: none; }
  html { scroll-behavior: auto; }
}

/* ============================================================
   SHARE LAYER — panel, QR, nudges (appended by talktosamay)
   ============================================================ */
.chat-share {
  margin-left: 8px; padding: 7px 10px;
  font-family: var(--font-display); font-size: .72rem; letter-spacing: .08em;
  background: var(--gold); color: var(--ink);
  border: 2px solid var(--ink); border-radius: 6px;
  box-shadow: 2px 2px 0 var(--ink); cursor: pointer;
  transition: transform .12s;
}
.chat-share:active { transform: translate(2px, 2px); box-shadow: none; }
.chat-share.pulse { animation: sharePulse 1s ease-in-out 5; }
@keyframes sharePulse {
  0%, 100% { transform: scale(1); box-shadow: 2px 2px 0 var(--ink); }
  50% { transform: scale(1.12); box-shadow: 0 0 18px var(--gold); }
}

#sharePanel { position: fixed; inset: 0; z-index: 90; display: none; }
#sharePanel.open { display: block; }
body.sp-lock { overflow: hidden; }
.sp-backdrop { position: absolute; inset: 0; background: rgba(4, 1, 2, .72); backdrop-filter: blur(3px); }
.sp-sheet {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: var(--panel); border-top: 3px solid var(--crimson);
  border-radius: 18px 18px 0 0; padding: 14px 18px calc(20px + env(safe-area-inset-bottom));
  animation: spUp .28s cubic-bezier(.2, .9, .3, 1.1);
  max-height: 82vh; overflow-y: auto;
}
@keyframes spUp { from { transform: translateY(60%); opacity: .4; } to { transform: none; opacity: 1; } }
.sp-grab { width: 44px; height: 4px; border-radius: 4px; background: var(--line); margin: 0 auto 12px; }
.sp-title { font-family: var(--font-display); font-size: 1.3rem; letter-spacing: .05em; color: var(--cream); }
.sp-title span { color: var(--crimson-hot); }
.sp-sub {
  margin: 8px 0 14px; padding: 10px 12px; font-size: .82rem; color: var(--cream-dim);
  background: var(--bg-2); border-left: 3px solid var(--gold); border-radius: 6px;
  white-space: pre-line; word-break: break-word;
}
.sp-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sp-btn {
  display: flex; align-items: center; gap: 9px; padding: 13px 14px;
  font-family: var(--font-display); font-size: .86rem; letter-spacing: .06em;
  color: var(--cream); background: var(--bg-2);
  border: 2px solid var(--line); border-radius: 10px; cursor: pointer;
  transition: border-color .15s, transform .12s;
}
.sp-btn:hover { border-color: var(--crimson); }
.sp-btn:active { transform: scale(.97); }
.sp-ic { font-size: 1.15rem; }
.sp-wa { border-color: #1da851; }
.sp-linkrow { display: flex; gap: 14px; align-items: center; margin-top: 16px; }
.sp-qr {
  width: 96px; height: 96px; flex: 0 0 96px;
  border: 2px solid var(--line); border-radius: 10px; background: var(--bg-2);
}
.sp-linkcol { min-width: 0; }
.sp-linklabel { font-size: .78rem; color: var(--cream-dim); margin-bottom: 6px; }
.sp-url {
  display: block; font-size: .78rem; color: var(--gold);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 8px;
}
.sp-copy {
  padding: 8px 12px; font-family: var(--font-display); font-size: .72rem; letter-spacing: .08em;
  background: var(--crimson); color: var(--cream);
  border: 2px solid var(--ink); border-radius: 6px; box-shadow: 2px 2px 0 var(--ink); cursor: pointer;
}
.sp-copy:active { transform: translate(2px, 2px); box-shadow: none; }

#shareToast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%) translateY(20px);
  z-index: 99; padding: 11px 18px; max-width: 88vw;
  font-size: .85rem; color: var(--cream); background: var(--maroon);
  border: 2px solid var(--crimson); border-radius: 10px;
  opacity: 0; pointer-events: none; transition: opacity .25s, transform .25s;
}
#shareToast.on { opacity: 1; transform: translateX(-50%) translateY(0); }

.lt-share {
  margin-top: 10px; padding: 9px 14px; width: 100%;
  font-family: var(--font-display); font-size: .8rem; letter-spacing: .07em;
  background: var(--gold); color: var(--ink);
  border: 2px solid var(--ink); border-radius: 8px;
  box-shadow: 2px 2px 0 var(--ink); cursor: pointer;
}
.lt-share:active { transform: translate(2px, 2px); box-shadow: none; }

@media (min-width: 700px) {
  .sp-sheet { left: 50%; right: auto; bottom: 50%; transform: translate(-50%, 50%); width: 460px; border-radius: 18px; border: 2px solid var(--line); border-top: 3px solid var(--crimson); }
  @keyframes spUp { from { transform: translate(-50%, 54%); opacity: .4; } to { transform: translate(-50%, 50%); opacity: 1; } }
}
@media (prefers-reduced-motion: reduce) {
  .sp-sheet, .chat-share.pulse { animation: none; }
}

/* ---- audit P0/P1 additions ---- */
.lt-url {
  margin-top: 8px; font-size: .68rem; letter-spacing: .12em;
  color: var(--cream-dim); text-transform: uppercase; opacity: .85;
}
.nav-cta-chat { display: none; }
@media (max-width: 999px) {
  .nav-cta:not(.nav-cta-chat) { display: none; }
  .nav-cta-chat { display: inline-block; }
}
#chatFab {
  position: fixed; right: 16px; bottom: calc(18px + env(safe-area-inset-bottom));
  z-index: 80; padding: 12px 16px;
  font-family: var(--font-display); font-size: .85rem; letter-spacing: .07em;
  background: var(--crimson); color: var(--cream);
  border: 2px solid var(--ink); border-radius: 999px;
  box-shadow: 3px 3px 0 var(--ink), 0 6px 22px rgba(230, 35, 41, .45);
  cursor: pointer; opacity: 0; pointer-events: none;
  transform: translateY(12px); transition: opacity .2s, transform .2s;
}
#chatFab.on { opacity: 1; pointer-events: auto; transform: none; }

/* ---- nimbu-mirchi mark (replaces the old chess knight everywhere) ---- */
.nimbu {
  display: inline-block; vertical-align: -.18em;
  width: 1em; height: 1.15em; margin-left: .12em;
  background: url("nimbu.svg") center/contain no-repeat;
}
.ticker-track i.nimbu { width: 1.1em; height: 1.25em; margin: 0; }

/* ============================================================
   MOBILE CHAT LAYOUT (< 700px)
   The stacked layout (title -> big buddy -> chat) pushed half the
   chat below the fold. On phones the chat IS the product, so it
   fills the viewport like a messaging app and the buddy shrinks to
   a floating avatar in the title band, at the chat's top-right.
   ============================================================ */
@media (max-width: 699px) {
  /* height, not min-height: with min-height the section grows as messages are
     added, which pushed the input off-screen and stopped the log from ever
     scrolling. Fixed height + min-height:0 down the chain = internal scroll. */
  /* --vvh is the visual viewport in pixels, set by chat.js only while a
     keyboard is actually up. Browsers that honour interactive-widget already
     shrink 100dvh themselves and never see the variable; iOS does not, and
     without it 100dvh keeps counting the strip the keyboard is sitting on,
     so the input the user just tapped ends up underneath it. */
  .stage {
    height: var(--vvh, 100dvh);
    min-height: var(--vvh, 100dvh);
    max-height: var(--vvh, 100dvh);
    display: flex; flex-direction: column;
    padding: 62px 11px calc(10px + env(safe-area-inset-bottom));
    position: relative; overflow: hidden;
  }
  /* Title moves left so the floating buddy owns the right of the band. */
  .section-title {
    text-align: left; font-size: clamp(1.55rem, 7vw, 2.1rem);
    padding-right: 96px; line-height: 1.05;
  }
  .section-title::before { display: none; }   /* watermark has no room here */
  .section-sub { display: none; }

  /* flex column, not block: .chat can then use flex:1 to claim the leftover
     height. A percentage height on a block flex-item child doesn't resolve. */
  .stage-grid {
    display: flex; flex-direction: column; position: relative;
    flex: 1; min-height: 0; margin: 8px 0 0;
  }

  /* Floating avatar — pulled up into the title band, out of the chat's flow. */
  /* Sits in the chat's top-right corner, tucked just under the fixed nav.
     .chat-head reserves matching right padding so SHARE never lands beneath it. */
  /* -48px predates .buddy-svg going overflow:visible (4.1). Props that paint
     ABOVE the head — the gg crown most of all — then landed entirely behind
     the fixed nav, so gg lost its single clearest signal on mobile. -30px
     clears the nav with the crown on. */
  .buddy-zone {
    position: absolute; top: -30px; right: -2px;
    width: 84px; z-index: 6; gap: 0;
    filter: drop-shadow(0 6px 14px rgba(0,0,0,.65));
  }
  .buddy { width: 84px; }
  .buddy-caption, .stage-bulbs { display: none; }
  .buddy-bubble { left: auto; right: 0; transform: translate(0, -86%) scale(.7); }
  .buddy-bubble.show { transform: translate(0, -100%) scale(1); }
  .buddy-bubble::after { left: auto; right: 22px; margin-left: 0; }

  .chat { flex: 1; height: auto; min-height: 0; border-radius: 14px; }
  .chat-elo { display: none; }               /* frees the header for SHARE */
  .chat-head { padding-right: 88px; }        /* keeps SHARE clear of the buddy */
  .stage-disclaimer { margin-top: 10px; font-size: .8rem; }
  .stage-disclaimer strong { font-size: .64rem; }
  .stage-disclaimer span { display: none; }   /* the joke goes; the disclosure stays */
}

/* ---- share panel: card preview + format switch ---- */
.sp-formats { display: flex; gap: 8px; margin: 12px 0 10px; }
.sp-fmt {
  flex: 1; padding: 9px 10px; cursor: pointer;
  font-family: var(--font-display); font-size: .78rem; letter-spacing: .07em;
  color: var(--cream-dim); background: var(--bg-2);
  border: 2px solid var(--line); border-radius: 9px;
}
.sp-fmt.on { color: var(--ink); background: var(--gold); border-color: var(--ink); }
.sp-cardwrap {
  position: relative; border: 2px solid var(--line); border-radius: 12px;
  background: var(--bg-2); overflow: hidden; margin-bottom: 14px;
  min-height: 190px; display: grid; place-items: center;
}
#spCardImg { display: none; width: 100%; max-height: 46vh; object-fit: contain; }
.sp-spin {
  position: absolute; inset: 0; display: grid; place-items: center; gap: 10px;
  font-size: .84rem; color: var(--cream-dim); background: var(--bg-2);
}
.sp-spin span {
  width: 26px; height: 26px; border-radius: 50%;
  border: 3px solid var(--line); border-top-color: var(--crimson);
  animation: spSpin .8s linear infinite;
}
@keyframes spSpin { to { transform: rotate(360deg); } }
.sp-linkrow { display: flex; gap: 10px; margin-top: 14px; align-items: stretch; }
.sp-linkrow .sp-copy { flex: 1; }
.sp-copy-ghost { background: transparent; color: var(--cream); border-color: var(--line); box-shadow: none; }
.sp-note { margin-top: 12px; font-size: .76rem; color: var(--cream-dim); line-height: 1.45; }

/* ============================================================
   RIG FIXES (tasks 2.2 / 2.3)
   ============================================================ */
/* LOAD-BEARING. .b-arm is in the `transform-box: fill-box` list above, where
   `transform-origin: 50% 8%` resolves against the arm's own bbox — which, once
   the arms were lengthened, sat up in the HAIR and visibly DETACHED the limb on
   gg / wave / think / facepalm. Pin each arm to its own shoulder in user units. */
.b-arm-l { transform-box: view-box; transform-origin: 70px 165px; }
.b-arm-r { transform-box: view-box; transform-origin: 150px 165px; }

/* Edison bulbs: filament core + brass cap, so they read as bulbs not dots. */
.bulb i::before {
  content: ""; position: absolute; left: 50%; top: 46%;
  width: 5px; height: 5px; margin-left: -2.5px; border-radius: 1px;
  border: 1px solid rgba(255, 236, 179, .9); border-top: 0; border-bottom: 0;
}
.bulb i::after {
  content: ""; position: absolute; left: 50%; top: -4px;
  width: 7px; height: 5px; margin-left: -3.5px; border-radius: 1px 1px 0 0;
  background: linear-gradient(#c9a05a, #8a6a2b);
}

/* ============================================================
   PHASE 3.1 — core expressions: idle / talk / laugh
   ============================================================
   The old versions moved as ONE rigid block on one clock, which is exactly
   the robotic read BUDDY_REF calls out. Everything below runs on its own
   timing and offset so no two parts share a keyframe.
   ============================================================ */

/* ---- IDLE: breathe, don't bob ---- */
.b-all { animation: buddyBob 4.2s cubic-bezier(.45,0,.55,1) infinite; }
@keyframes buddyBob { 50% { transform: translateY(-3px); } }

.b-body {
  transform-box: view-box; transform-origin: 110px 228px;   /* pivot at the hem */
  animation: breathe 4.2s cubic-bezier(.45,0,.55,1) infinite;
}
@keyframes breathe {
  0%, 100% { transform: scale(1, 1); }
  45%      { transform: scale(.988, 1.022); }   /* inhale: chest up, narrows */
  72%      { transform: scale(1.008, .994); }   /* exhale overshoot, then settle */
}

/* Hair + curls lag the head and settle after it. */
.b-hair, .b-curls {
  transform-box: view-box; transform-origin: 110px 92px;
  animation: hairLag 4.2s ease-in-out infinite; animation-delay: .09s;
}
@keyframes hairLag {
  0%, 100% { transform: rotate(0deg) translateY(0); }
  40%      { transform: rotate(-.9deg) translateY(-1.1px); }
  76%      { transform: rotate(.7deg) translateY(.5px); }
}

/* Blink: snaps shut fast, opens slower, closes onto the LOWER lid. */
.b-eyes { transition: transform .17s cubic-bezier(.2,.9,.3,1); }
.buddy.is-blink .e-open { transform: translateY(3.4px) scaleY(.07); transition-duration: .07s; }

/* ---- TALK ---- */
[data-mood="talk"] .m-talk {
  opacity: 1; transform-origin: center;
  animation: chatter .92s steps(1, end) infinite;
}
@keyframes chatter {
  0%   { transform: scale(1,    1);    }
  11%  { transform: scale(1.06, .42);  }
  22%  { transform: scale(.95,  1.08); }
  31%  { transform: scale(1.07, .34);  }
  45%  { transform: scale(.97,  .92);  }
  56%  { transform: scale(1.04, .5);   }
  68%  { transform: scale(.96,  1.1);  }
  79%  { transform: scale(1.05, .38);  }
  90%  { transform: scale(1,    .86);  }
}
[data-mood="talk"] .b-head { animation: talkNod .83s ease-in-out infinite; }
@keyframes talkNod {
  0%, 100% { transform: rotate(-1.7deg) translateY(0); }
  32%      { transform: rotate(1.5deg) translateY(-1.7px); }
  64%      { transform: rotate(-.5deg) translateY(.8px); }
}
/* The mic pivots about the FIST — not its own bbox centre, and not the
   viewBox centre, which is what transform-origin defaults to here. */
.p-microt {
  transform-box: view-box; transform-origin: 167px 246px;
  transition: transform .35s cubic-bezier(.3,1.3,.4,1);
}
[data-mood="talk"] .b-arm-r { transform: rotate(120deg); }
[data-mood="talk"] .p-microt { transform: rotate(-75deg); }

/* ---- LAUGH ---- */
[data-mood="laugh"] .b-all { animation: laughShake .46s cubic-bezier(.3,0,.4,1) infinite; }
@keyframes laughShake {
  0%, 100% { transform: translateY(0) rotate(-1.2deg); }
  38%      { transform: translateY(-7px) rotate(1.6deg); }
  72%      { transform: translateY(1.5px) rotate(-.4deg); }
}
[data-mood="laugh"] .b-body { animation: laughSquash .46s cubic-bezier(.3,0,.4,1) infinite; }
@keyframes laughSquash {
  0%, 100% { transform: scale(1.035, .962); }
  40%      { transform: scale(.962, 1.05); }
}
[data-mood="laugh"] .b-head {
  animation: laughThrow .46s cubic-bezier(.3,0,.4,1) infinite; animation-delay: .04s;
}
@keyframes laughThrow {
  0%, 100% { transform: rotate(-3.5deg) translateY(0); }
  45%      { transform: rotate(-12deg) translateY(-2px); }   /* head back */
}
[data-mood="laugh"] .b-arm-l { animation: laughArmL .46s ease-in-out infinite; animation-delay: .08s; }
[data-mood="laugh"] .b-arm-r { animation: laughArmR .46s ease-in-out infinite; animation-delay: .08s; }
@keyframes laughArmL { 0%, 100% { transform: rotate(7deg); }  45% { transform: rotate(-10deg); } }
@keyframes laughArmR { 0%, 100% { transform: rotate(-7deg); } 45% { transform: rotate(10deg); } }
[data-mood="laugh"] .b-hair, [data-mood="laugh"] .b-curls {
  animation: laughHair .46s ease-in-out infinite; animation-delay: .11s;
}
@keyframes laughHair {
  0%, 100% { transform: rotate(1.6deg) translateY(.7px); }
  45%      { transform: rotate(-2.2deg) translateY(-1.6px); }
}
/* swap the shared .m-open for a purpose-drawn dropped jaw */
[data-mood="laugh"] .m-open  { opacity: 0; }
[data-mood="laugh"] .m-laugh { opacity: 1; }
[data-mood="laugh"] .b-brow-l { transform: translateY(-1.8px) rotate(-5deg); }
[data-mood="laugh"] .b-brow-r { transform: translateY(-1.8px) rotate(5deg); }

@media (prefers-reduced-motion: reduce) {
  [data-mood="laugh"] .b-head { transform: rotate(-9deg) translateY(-2px); }
  [data-mood="talk"]  .b-arm-r { transform: rotate(120deg); }
  [data-mood="talk"]  .p-microt { transform: rotate(-75deg); }
}

/* ============================================================
   PHASE 3.2 — comedy expressions: roast / facepalm / think
   ============================================================
   All three are "hand" poses and all three broke the same way: the arm is
   ~83 units shoulder-to-hand but the shoulder sits only ~48-81 from the
   chin/forehead, so a pure rotation parks the hand at the NECK. Facepalm
   read as scratching his neck, think as a shrug. think has to foreshorten
   with scale(1,S) — shortening along the arm's own length, which is what
   bending an elbow looks like — before rotating.
   ============================================================ */

/* ---- ROAST ---- */
[data-mood="roast"] .b-all { animation: roastLean 3.6s ease-in-out infinite; }
@keyframes roastLean {
  0%, 100% { transform: rotate(-3.4deg) translate(3px, 0); }
  50%      { transform: rotate(-2.2deg) translate(3px, -2.5px); }
}
[data-mood="roast"] .b-leg-l { transform: rotate(4deg); }
[data-mood="roast"] .b-leg-r { transform: rotate(-2deg) translateY(1px); }
[data-mood="roast"] .b-brow-r { transform: translateY(-4.5px) rotate(-7deg); }
[data-mood="roast"] .b-brow-l { transform: translateY(1px) rotate(3deg); }
[data-mood="roast"] .b-head { transform: rotate(4.5deg) translateY(-1px); }
[data-mood="roast"] .b-arm-r { transform: rotate(-26deg); }
[data-mood="roast"] .p-microt { transform: rotate(18deg); }
[data-mood="roast"] .p-fire { opacity: 1; animation: firePulse 1.1s ease-in-out infinite; }
.fl { transform-box: view-box; transform-origin: 110px 292px; }
[data-mood="roast"] .fl1 { animation: flicker1 .52s ease-in-out infinite; }
[data-mood="roast"] .fl2 { animation: flicker2 .43s ease-in-out infinite; }
[data-mood="roast"] .fl3 { animation: flicker3 .61s ease-in-out infinite; }
@keyframes flicker1 { 0%,100% { transform: scaleY(1) scaleX(1); }     50% { transform: scaleY(1.28) scaleX(.9); } }
@keyframes flicker2 { 0%,100% { transform: scaleY(1.15) scaleX(.94); } 50% { transform: scaleY(.86) scaleX(1.06); } }
@keyframes flicker3 { 0%,100% { transform: scaleY(.9) scaleX(1.05); }  50% { transform: scaleY(1.22) scaleX(.93); } }

.b-hand { transform-box: view-box; transition: transform .35s cubic-bezier(.3,1.3,.4,1); }
.b-hand-l { transform-origin: 50px 245px; }
.b-hand-r { transform-origin: 170px 245px; }

/* ---- FACEPALM ---- */
/* Palm over the EYES, and enlarged. At mitten size the hand read as a poke:
   a face is 84 units wide and the hand only 20. */
[data-mood="facepalm"] .b-arm-r  { transform: rotate(158deg); }
[data-mood="facepalm"] .b-hand-r { transform: scale(1.6); }
/* The hand is the SAME flat skin colour as the face, so a palm laid on it
   disappears and only the dark cuff shows. A cast shadow is the only thing
   that separates two identical flat fills. */
[data-mood="facepalm"] .b-arm-r,
[data-mood="shock"] .b-arm-l,
[data-mood="shock"] .b-arm-r,
[data-mood="think"] .b-arm-l { filter: drop-shadow(-1.5px 2.5px 1.8px rgba(0,0,0,.55)); }
[data-mood="facepalm"] .b-head { transform: rotate(8deg) translateY(5px); }
[data-mood="facepalm"] .b-body { animation: sighSlump 2.6s ease-in-out infinite; }
@keyframes sighSlump {
  0%, 100% { transform: translateY(2.5px) scale(1.012, .984); }
  38%      { transform: translateY(0) scale(.994, 1.008); }
}
[data-mood="facepalm"] .b-brow-l { transform: translate(2px, 3px) rotate(-15deg); }
[data-mood="facepalm"] .b-brow-r { transform: translate(-2px, 3px) rotate(15deg); }
[data-mood="facepalm"] .m-flat { opacity: 0; }
[data-mood="facepalm"] .m-sad  { opacity: 1; }

/* ---- THINK ---- */
[data-mood="think"] .b-arm-l { transform: rotate(-142deg) scale(1, .57); }
[data-mood="think"] .b-head { transform: rotate(-6deg) translateY(1px); }
[data-mood="think"] .b-pupil { transform: translate(-3.2px, -3.8px); }
[data-mood="think"] .b-brow-l { transform: translateY(-3.5px) rotate(-15deg); }
[data-mood="think"] .b-brow-r { transform: translateY(1.5px) rotate(9deg); }
[data-mood="think"] .m-flat { opacity: 0; }
[data-mood="think"] .m-smirk { opacity: 1; transform: translate(-7px, 1px) scale(.8, .78); }
[data-mood="think"] .b-all { animation: ponder 4.4s ease-in-out infinite; }
@keyframes ponder {
  0%, 100% { transform: rotate(-1.4deg) translateY(0); }
  50%      { transform: rotate(1.1deg) translateY(-2.5px); }
}

@media (prefers-reduced-motion: reduce) {
  [data-mood="roast"] .b-all { transform: rotate(-3.4deg) translate(3px, 0); }
  [data-mood="think"] .b-all { transform: rotate(-1.4deg); }
  [data-mood="facepalm"] .b-body { transform: translateY(2.5px) scale(1.012, .984); }
}

/* ============================================================
   PHASE 3.3 — warm expressions: love / wave / gg / hype
   ============================================================
   All four read as "positive" and that was the problem: same e-happy
   crescents over the same grin, so they were interchangeable.
   ============================================================ */

/* ---- LOVE ---- */
[data-mood="love"] .b-head { transform: rotate(9deg) translateY(1px); }
[data-mood="love"] .m-smile { opacity: 1; }
[data-mood="love"] .b-blush { opacity: .72; r: 8.5; }
[data-mood="love"] .b-brow-l { transform: translate(3px,-1.5px) rotate(9deg); }
[data-mood="love"] .b-brow-r { transform: translate(-3px,-1.5px) rotate(-9deg); }
/* A hand-to-cheek swoon was tried and REJECTED: at mitten size against a full
   beard it read as a lump on his jaw. The tenderness is carried by the hearts,
   the blush, the tilt and the brows — the arms only have to not fight it. */
[data-mood="love"] .b-arm-l { animation: swoonArmL 3.1s ease-in-out infinite; animation-delay: .16s; }
[data-mood="love"] .b-arm-r { animation: swoonArmR 3.1s ease-in-out infinite; animation-delay: .16s; }
@keyframes swoonArmL { 0%, 100% { transform: rotate(22deg); } 50% { transform: rotate(31deg); } }
@keyframes swoonArmR { 0%, 100% { transform: rotate(-29deg); } 50% { transform: rotate(-20deg); } }
[data-mood="love"] .b-all { animation: swoon 3.1s ease-in-out infinite; }
@keyframes swoon {
  0%, 100% { transform: rotate(2.2deg) translateY(0); }
  50%      { transform: rotate(-1deg) translateY(-3.5px); }
}
[data-mood="love"] .h  { animation: heartFloat 2.1s ease-out infinite; opacity: 0; }
[data-mood="love"] .h2 { animation-delay: .42s; }
[data-mood="love"] .h3 { animation-delay: .84s; }
[data-mood="love"] .h4 { animation-delay: 1.26s; }
[data-mood="love"] .h5 { animation-delay: 1.68s; }
@keyframes heartFloat {
  0%   { opacity: 0; transform: translateY(10px) scale(.45); }
  18%  { opacity: 1; transform: translateY(4px) scale(1.08); }
  72%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-26px) scale(1.15); }
}

/* ---- WAVE ---- */
[data-mood="wave"] .b-arm-r { animation: waveArm .78s ease-in-out infinite; }
@keyframes waveArm { 0%, 100% { transform: rotate(-126deg); } 50% { transform: rotate(-174deg); } }
[data-mood="wave"] .b-arm-l { transform: rotate(-13deg); }
[data-mood="wave"] .m-smile { opacity: 1; }
[data-mood="wave"] .b-head { animation: waveNod 1.56s ease-in-out infinite; }
@keyframes waveNod {
  0%, 100% { transform: rotate(-7deg) translateY(0); }
  50%      { transform: rotate(-2.5deg) translateY(-1.5px); }
}
[data-mood="wave"] .b-all { animation: waveLean 1.56s ease-in-out infinite; }
@keyframes waveLean {
  0%, 100% { transform: rotate(1.8deg) translateY(0); }
  50%      { transform: rotate(-1.2deg) translateY(-2.5px); }
}

/* ---- GG ---- */
/* 168deg folded the arm back ONTO the head (plaid on dark hair = invisible). */
[data-mood="gg"] .b-arm-l { transform: rotate(150deg); }
[data-mood="gg"] .b-arm-r { transform: rotate(-154deg); }
[data-mood="gg"] .m-open  { opacity: 0; }
[data-mood="gg"] .m-laugh { opacity: 1; }
[data-mood="gg"] .b-brow-l { transform: translateY(-3px) rotate(-5deg); }
[data-mood="gg"] .b-brow-r { transform: translateY(-3px) rotate(5deg); }
[data-mood="gg"] .b-all { animation: ggBounce .6s cubic-bezier(.3,0,.35,1) infinite; }
@keyframes ggBounce { 0%, 100% { transform: translateY(0); } 45% { transform: translateY(-11px); } }
[data-mood="gg"] .b-body { animation: ggSquash .6s cubic-bezier(.3,0,.35,1) infinite; }
@keyframes ggSquash {
  0%, 100% { transform: scale(1.032, .966); }
  45%      { transform: scale(.966, 1.046); }
}
[data-mood="gg"] .b-head { animation: ggHead .6s ease-in-out infinite; animation-delay: .05s; }
@keyframes ggHead {
  0%, 100% { transform: rotate(-2deg) translateY(0); }
  50%      { transform: rotate(-7deg) translateY(-1.5px); }
}
[data-mood="gg"] .p-crown {
  animation: crownDrop .5s cubic-bezier(.2,1.4,.4,1) both,
             crownWobble .6s ease-in-out .5s infinite;
}
@keyframes crownWobble {
  0%, 100% { transform: rotate(-4deg) translateY(0); }
  50%      { transform: rotate(4deg) translateY(-2px); }
}

/* ---- HYPE ---- */
/* Mirrored arms on one keyframe read as praying hands. */
@keyframes clapL { 0%, 100% { transform: rotate(-36deg); } 50% { transform: rotate(-68deg); } }
@keyframes clapR { 0%, 100% { transform: rotate(46deg); }  50% { transform: rotate(64deg); } }
[data-mood="hype"] .b-arm-r { animation: clapR .3s ease-in-out infinite; animation-delay: .03s; }
[data-mood="hype"] .b-all { animation: hypeBounce .6s cubic-bezier(.3,0,.35,1) infinite; }
@keyframes hypeBounce {
  0%, 100% { transform: translateY(0) rotate(-1deg); }
  50%      { transform: translateY(-7px) rotate(1deg); }
}
[data-mood="hype"] .b-head { animation: hypeNod .6s ease-in-out infinite; animation-delay: .07s; }
@keyframes hypeNod {
  0%, 100% { transform: rotate(2deg) translateY(0); }
  50%      { transform: rotate(-2.5deg) translateY(-1.5px); }
}

@media (prefers-reduced-motion: reduce) {
  [data-mood="love"] .b-all { transform: rotate(2.2deg); }
  [data-mood="love"] .b-arm-l { transform: rotate(22deg); }
  [data-mood="love"] .b-arm-r { transform: rotate(-29deg); }
  [data-mood="wave"] .b-arm-r { transform: rotate(-150deg); }
  [data-mood="wave"] .b-head { transform: rotate(-7deg); }
  [data-mood="gg"] .p-crown { transform: none; opacity: 1; }
  [data-mood="hype"] .b-arm-l { transform: rotate(-52deg); }
  [data-mood="hype"] .b-arm-r { transform: rotate(55deg); }
  [data-mood="love"] .h { opacity: 1; }
}

/* ============================================================
   PHASE 3.4 — big reactions: shock / cry / sleep
   ============================================================
   cry and sleep were near-duplicates: both e-closed over a hairline mouth
   with the head tilted, so the only difference was a tear.
   ============================================================ */

/* ---- SHOCK ---- */
/* shockJump runs twice and stops, so the POSE has to carry it afterwards. */
[data-mood="shock"] .b-all { animation: shockJump .42s cubic-bezier(.3,1.7,.4,1) 2; }
@keyframes shockJump {
  0%   { transform: translateY(0) scale(1, 1); }
  18%  { transform: translateY(-4px) scale(.94, 1.08); }
  45%  { transform: translateY(-16px) scale(1, 1); }
  78%  { transform: translateY(0) scale(1.06, .93); }
  100% { transform: translateY(0) scale(1, 1); }
}
/* hands up BESIDE the head, kept outside the face silhouette */
[data-mood="shock"] .b-arm-l { transform: rotate(158deg) scale(1, .85); }
[data-mood="shock"] .b-arm-r { transform: rotate(-158deg) scale(1, .85); }
/* -9px floated the brows into the hairline where they read as hair. Raised
   brows only say "shocked" relative to the EYES. */
[data-mood="shock"] .b-brow-l, [data-mood="shock"] .b-brow-r { transform: translateY(-5.5px); }
[data-mood="shock"] .m-oh { transform: scale(1.5, 1.8) translateY(6px); }
[data-mood="shock"] .b-head { animation: shockRecoil .42s cubic-bezier(.3,1.7,.4,1) 2; }
@keyframes shockRecoil {
  0%, 100% { transform: rotate(0) translateY(0); }
  40%      { transform: rotate(-3deg) translateY(-3px); }
}
[data-mood="shock"] .p-sweat { opacity: 1; animation: sweatDrip .9s ease-in infinite; }

/* ---- CRY ---- */
[data-mood="cry"] .m-sad  { opacity: 0; }
[data-mood="cry"] .m-wail { opacity: 1; }
[data-mood="cry"] .b-brow-l { transform: rotate(-21deg) translate(2px, 2.5px); }
[data-mood="cry"] .b-brow-r { transform: rotate(21deg) translate(-2px, 2.5px); }
[data-mood="cry"] .b-all { animation: sob .55s ease-in-out infinite; }
@keyframes sob {
  0%, 100% { transform: translateY(0) rotate(-.8deg); }
  50%      { transform: translateY(3px) rotate(.5deg); }
}
[data-mood="cry"] .b-body { animation: sobShoulders .55s ease-in-out infinite; animation-delay: .05s; }
@keyframes sobShoulders {
  0%, 100% { transform: translateY(0) scale(1.014, .988); }
  50%      { transform: translateY(2.5px) scale(.998, 1.01); }
}
[data-mood="cry"] .b-head { animation: sobHead .55s ease-in-out infinite; animation-delay: .09s; }
@keyframes sobHead {
  0%, 100% { transform: rotate(-2deg) translateY(5px); }
  50%      { transform: rotate(-3.5deg) translateY(7.5px); }
}
[data-mood="cry"] .b-arm-l { animation: sobArmL .55s ease-in-out infinite; animation-delay: .13s; }
[data-mood="cry"] .b-arm-r { animation: sobArmR .55s ease-in-out infinite; animation-delay: .13s; }
@keyframes sobArmL { 0%, 100% { transform: rotate(6deg); }  50% { transform: rotate(2deg); } }
@keyframes sobArmR { 0%, 100% { transform: rotate(-6deg); } 50% { transform: rotate(-2deg); } }
[data-mood="cry"] .p-tear-l { animation: tearDrip 1s ease-in infinite; }
[data-mood="cry"] .p-tear-r { animation: tearDrip 1s ease-in infinite .42s; }
@keyframes tearDrip {
  0%   { transform: translateY(0) scale(.85); opacity: 0; }
  15%  { opacity: 1; }
  100% { transform: translateY(27px) scale(1.2); opacity: 0; }
}

/* ---- SLEEP ---- */
[data-mood="sleep"] .m-flat { opacity: 0; }
[data-mood="sleep"] .m-oh { opacity: 1; transform: scale(.8, .6) translateY(4px); }
[data-mood="sleep"] .b-body { animation: sleepBreathe 5.5s ease-in-out infinite; }
@keyframes sleepBreathe {
  0%, 100% { transform: scale(1, 1); }
  45%      { transform: scale(.98, 1.032); }
}
[data-mood="sleep"] .b-head { animation: sleepNod 5.5s ease-in-out infinite; animation-delay: .35s; }
@keyframes sleepNod {
  0%, 100% { transform: rotate(10deg) translateY(4.5px); }
  45%      { transform: rotate(8deg) translateY(1.5px); }
}
[data-mood="sleep"] .b-arm-l { transform: rotate(5deg); }
[data-mood="sleep"] .b-arm-r { transform: rotate(-5deg); }
[data-mood="sleep"] .b-brow-l { transform: translateY(2px) rotate(4deg); }
[data-mood="sleep"] .b-brow-r { transform: translateY(2px) rotate(-4deg); }

@media (prefers-reduced-motion: reduce) {
  [data-mood="cry"] .b-head { transform: rotate(-2deg) translateY(5px); }
  [data-mood="cry"] .p-tear { opacity: 1; }
  [data-mood="sleep"] .b-head { transform: rotate(10deg) translateY(4.5px); }
  [data-mood="sleep"] .z { opacity: 1; }
}

/* ============================================================
   PHASE 4.1 — weight + follow-through on the loops
   ============================================================
   Everything ran on ONE clock or an exact harmonic of it (body .64s, head
   .32s = perfectly synced, which is what reads as clockwork). And the groove
   arms swung through horizontal, where a hand 83 units from a shoulder at
   x=70 lands OUTSIDE the 0-220 viewBox and gets sliced flat. Arms now pump
   UP past horizontal, foreshortened hardest at the crossing.
   ============================================================ */
.b-beard { transform-box: view-box; transform-origin: 110px 100px; }

/* ---- GROOVE ---- */
[data-mood="dance"] .b-all { animation: danceSway .66s ease-in-out infinite alternate; }
@keyframes danceSway {
  0%   { transform: rotate(-3.5deg) translateY(0) scale(1.02, .975); }
  55%  { transform: rotate(0deg) translateY(-8px) scale(.975, 1.03); }
  100% { transform: rotate(3.5deg) translateY(-1px) scale(1.015, .985); }
}
[data-mood="dance"] .b-body { animation: danceBody .66s ease-in-out infinite alternate; animation-delay: .06s; }
@keyframes danceBody {
  0%   { transform: scale(1.03, .966) skewX(1.4deg); }
  100% { transform: scale(.972, 1.036) skewX(-1.4deg); }
}
[data-mood="dance"] .b-head { animation: danceHead .35s ease-in-out infinite alternate; animation-delay: .04s; }
@keyframes danceHead {
  from { transform: rotate(-8deg) translateY(1px); }
  to   { transform: rotate(7deg) translateY(-1.5px); }
}
[data-mood="dance"] .b-arm-l { animation: dancePump .66s ease-in-out infinite; }
[data-mood="dance"] .b-arm-r { animation: dancePumpR .66s ease-in-out infinite; animation-delay: .05s; }
/* 5.1: the foreshortening here was originally cranked to .42 purely to keep
   the hands inside the 0-220 viewBox — but the same task made .buddy-svg
   overflow:visible, so that constraint no longer exists and the extreme
   values were left doing nothing but turning his forearms into stumps.
   Relaxed to a real elbow bend. */
@keyframes dancePump {
  0%, 100% { transform: rotate(12deg) scale(1, .84); }
  28%      { transform: rotate(70deg) scale(1, .62); }
  50%      { transform: rotate(128deg) scale(1, .72); }
  72%      { transform: rotate(70deg) scale(1, .62); }
}
@keyframes dancePumpR {
  0%, 100% { transform: rotate(-128deg) scale(1, .72); }
  28%      { transform: rotate(-70deg) scale(1, .62); }
  50%      { transform: rotate(-12deg) scale(1, .84); }
  72%      { transform: rotate(-70deg) scale(1, .62); }
}
[data-mood="dance"] .b-leg-l { animation: kick .66s ease-in-out infinite; }
[data-mood="dance"] .b-leg-r { animation: kick .66s ease-in-out infinite; animation-delay: .33s; }
[data-mood="dance"] .b-hair, [data-mood="dance"] .b-curls {
  animation: danceHair .35s ease-in-out infinite alternate; animation-delay: .12s;
}
@keyframes danceHair {
  from { transform: rotate(2.6deg) translateY(.8px); }
  to   { transform: rotate(-2.4deg) translateY(-1.4px); }
}
[data-mood="dance"] .b-beard {
  animation: danceBeard .35s ease-in-out infinite alternate; animation-delay: .16s;
}
@keyframes danceBeard {
  from { transform: rotate(2deg) translateY(.5px); }
  to   { transform: rotate(-1.8deg) translateY(-.6px); }
}
/* ---- BHANGRA HOP ----------------------------------------------------- */
.buddy.dance-b[data-mood="dance"] .b-all { animation: bhangraHop .5s cubic-bezier(.34,0,.36,1) infinite; }
@keyframes bhangraHop {
  0%, 100% { transform: translateY(0) rotate(-3deg) scale(1.05, .93); }   /* squashed, loaded */
  22%      { transform: translateY(-9px) rotate(-1deg) scale(.95, 1.06); } /* stretch off the floor */
  50%      { transform: translateY(-15px) rotate(3deg) scale(1, 1); }      /* airborne, neutral */
  78%      { transform: translateY(-6px) rotate(1deg) scale(.97, 1.04); }
}
.buddy.dance-b[data-mood="dance"] .b-body { animation: bhangraBody .5s ease-in-out infinite; animation-delay: .05s; }
@keyframes bhangraBody {
  0%, 100% { transform: scale(1.035, .962); }
  50%      { transform: scale(.968, 1.042); }
}
/* uneven arms — a perfectly mirrored pair is the giveaway (BUDDY_REF) */
.buddy.dance-b[data-mood="dance"] .b-arm-l { animation: bhangraArmL .5s ease-in-out infinite; animation-delay: .04s; }
.buddy.dance-b[data-mood="dance"] .b-arm-r { animation: bhangraArmR .5s ease-in-out infinite; }
@keyframes bhangraArmL {
  0%, 100% { transform: rotate(133deg) scale(1, .76); }
  50%      { transform: rotate(154deg) scale(1, .90); }
}
@keyframes bhangraArmR {
  0%, 100% { transform: rotate(-150deg) scale(1, .86); }
  50%      { transform: rotate(-135deg) scale(1, .76); }
}
.buddy.dance-b[data-mood="dance"] .b-head { animation: bhangraHead .5s ease-in-out infinite; animation-delay: .07s; }
@keyframes bhangraHead {
  0%, 100% { transform: rotate(3deg) translateY(1.5px); }
  50%      { transform: rotate(-4deg) translateY(-2px); }
}
.buddy.dance-b[data-mood="dance"] .b-hair,
.buddy.dance-b[data-mood="dance"] .b-curls {
  animation: bhangraHair .5s ease-in-out infinite; animation-delay: .13s;
}
@keyframes bhangraHair {
  0%, 100% { transform: rotate(-2.8deg) translateY(1.6px); }   /* hair packs DOWN on landing */
  50%      { transform: rotate(2.4deg) translateY(-2.2px); }   /* and floats up at the apex */
}
.buddy.dance-b[data-mood="dance"] .b-beard {
  animation: bhangraBeard .5s ease-in-out infinite; animation-delay: .17s;
}
@keyframes bhangraBeard {
  0%, 100% { transform: translateY(1.2px) scaleY(.97); }
  50%      { transform: translateY(-1.4px) scaleY(1.03); }
}

/* Idle breath gets the beard too, so it is never the one welded part. */
.b-beard { animation: beardLag 4.2s ease-in-out infinite; animation-delay: .14s; }
@keyframes beardLag {
  0%, 100% { transform: translateY(0) scaleY(1); }
  42%      { transform: translateY(-.7px) scaleY(1.012); }
  78%      { transform: translateY(.35px) scaleY(.995); }
}

/* An SVG viewport clips at its viewBox, so on the dance peaks the hands were
   sliced flat against an invisible wall at x=0 / x=220. The poses are right —
   the box is just tight — and widening the viewBox would force a re-check of
   the 84px mobile avatar, the desktop stage and the share-card placement
   (BUDDY_REF). Letting the rig overspill a few units costs nothing on a dark
   stage, and it lets the gg crown fly IN from above instead of popping in at
   the frame edge. The serialized share card carries no stylesheet, so it is
   unaffected. */
.buddy-svg { overflow: visible; }

/* ============================================================
   PHASE 4.2 — anticipation + settle on mood transitions
   ============================================================
   Poses used to appear the instant data-mood flipped: the rig animation
   started at its 0% keyframe and the transitioned parts eased in linearly.
   Nothing wound up first, and nothing overshot, so every reaction arrived
   flat. A pose that lands without a counter-move reads as a slide swap.

   The arrival rides .buddy-svg — nothing else animates that element, so it
   composes with whatever the mood is doing to .b-all rather than fighting
   it — and pivots at the FLOOR, so he compresses into the ground and pushes
   off it rather than scaling about his own middle.
   ============================================================ */
.buddy-svg { transform-origin: 50% 96%; }

.buddy.is-arriving .buddy-svg { animation: moodArrive .44s cubic-bezier(.2,1.5,.35,1); }
@keyframes moodArrive {
  0%   { transform: scale(1, 1) translateY(0); }
  15%  { transform: scale(1.05, .93) translateY(2px); }    /* anticipate: crouch DOWN first */
  44%  { transform: scale(.955, 1.07) translateY(-4px); }  /* drive up, overshoot past the pose */
  70%  { transform: scale(1.018, .982) translateY(1px); }  /* rebound under */
  100% { transform: scale(1, 1) translateY(0); }           /* settle */
}

/* Quiet moods get a slower, shallower arrival. A sob or a yawn that pops in
   with the same snap as a gg is the joke landing on the wrong beat. */
.buddy.is-arriving[data-mood="sleep"] .buddy-svg,
.buddy.is-arriving[data-mood="cry"] .buddy-svg,
.buddy.is-arriving[data-mood="think"] .buddy-svg,
.buddy.is-arriving[data-mood="love"] .buddy-svg {
  animation: moodArriveSoft .66s cubic-bezier(.25,.9,.3,1);
}
@keyframes moodArriveSoft {
  0%   { transform: scale(1, 1) translateY(0); }
  22%  { transform: scale(1.022, .97) translateY(1.5px); }
  60%  { transform: scale(.99, 1.016) translateY(-1.5px); }
  100% { transform: scale(1, 1) translateY(0); }
}

/* The transitioned parts settle too. .b-arm was already springy; the head,
   brows, legs and pupils were on plain ease, which is what made a pose look
   like it slid into place instead of arriving. */
.b-head  { transition: transform .34s cubic-bezier(.25,1.5,.4,1); }
.b-brow  { transition: transform .28s cubic-bezier(.25,1.6,.4,1); }
.b-leg   { transition: transform .32s cubic-bezier(.25,1.4,.4,1); }
.b-pupil { transition: transform .28s cubic-bezier(.25,1.4,.4,1); }

/* ============================================================
   PHASE 4.3 — idle quirks
   ============================================================
   Each quirk is a transient class on #buddy, added and removed by the quirk
   loop in buddy.js. They are POSES, not moods: they never touch data-mood,
   so the 14-mood contract is untouched and chat.js can interrupt at any
   point (Buddy.set clears them all).
   ============================================================ */
.p-phone, .p-chai { opacity: 0; transition: opacity .22s; }
.buddy.is-phone .p-phone { opacity: 1; }
.buddy.is-chai  .p-chai  { opacity: 1; }

/* --- checking the phone: held low at the belly, head and eyes down --- */
.buddy.is-phone .b-arm-l { transform: rotate(-42deg) scale(1, .8); }
.buddy.is-phone .b-head  { transform: rotate(-3deg) translateY(2.5px); }
.buddy.is-phone .b-pupil { transform: translate(-2px, 3.5px); }
.buddy.is-phone .m-smile { opacity: 0; }
.buddy.is-phone .m-smirk { opacity: 1; }

/* --- sipping chai: cup up to the chin, eyes closed on the sip --- */
.buddy.is-chai .b-arm-l { transform: rotate(-148deg) scale(1, .62);
                          filter: drop-shadow(-1.5px 2.5px 1.8px rgba(0,0,0,.55)); }
.buddy.is-chai .b-head  { transform: rotate(5deg) translateY(1px); }
.buddy.is-chai .e-open  { opacity: 0; }
.buddy.is-chai .e-closed{ opacity: 1; }
.buddy.is-chai .chai-steam { animation: steamRise 1.8s ease-out infinite; }
@keyframes steamRise {
  0%   { opacity: 0; transform: translateY(3px) scaleY(.7); }
  35%  { opacity: .55; }
  100% { opacity: 0; transform: translateY(-7px) scaleY(1.2); }
}

/* --- tap-tap on the mic: "is this thing on" --- */
.buddy.is-mictap .p-mic { opacity: 1; }
.buddy.is-mictap .p-microt { transform: rotate(-80deg); }
.buddy.is-mictap .b-arm-r { animation: micTap .46s ease-in-out 3; }
/* NO scale on this arm. .p-microt pivots about a FIXED view-box origin of
   167,246 — the fist's unscaled position — so any scale(1,S) on .b-arm-r
   moves the fist out from under that pivot and the mic swings off into
   space. Same reason `talk` rotates without scaling. */
@keyframes micTap {
  0%, 100% { transform: rotate(114deg); }
  50%      { transform: rotate(123deg); }
}

/* --- scratching the beard, mid-thought --- */
.buddy.is-scratch .b-arm-l {
  animation: beardScratch .44s ease-in-out 3;
  filter: drop-shadow(-1.5px 2.5px 1.8px rgba(0,0,0,.55));
}
@keyframes beardScratch {
  0%, 100% { transform: rotate(-139deg) scale(1, .58); }
  50%      { transform: rotate(-148deg) scale(1, .55); }
}

/* Reduced motion: the poses still read, the repeated taps/scratches do not. */
@media (prefers-reduced-motion: reduce) {
  .buddy.is-mictap .b-arm-r  { transform: rotate(118deg); }
  .buddy.is-scratch .b-arm-l { transform: rotate(-143deg) scale(1, .57); }
  .buddy.is-chai .chai-steam { opacity: .45; }
}

/* ============================================================
   PHASE 4.4 — poke interaction
   ============================================================
   Nothing signalled the buddy was clickable, which is most of why the poke
   went unnoticed. The recoil upgrades 4.2's arrival rather than competing
   with it: .is-poked is added BEFORE Buddy.set(), and set() is what restarts
   .is-arriving, so the poke simply arrives harder.
   ============================================================ */
.buddy { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.buddy-svg, .buddy-caption { user-select: none; -webkit-user-select: none; }

.buddy.is-arriving.is-poked .buddy-svg { animation: pokeSquish .52s cubic-bezier(.2,1.7,.3,1); }
@keyframes pokeSquish {
  0%   { transform: scale(1, 1) rotate(0); }
  12%  { transform: scale(1.13, .85) translateY(6px) rotate(-1.6deg); }  /* jabbed down */
  40%  { transform: scale(.91, 1.12) translateY(-8px) rotate(1.6deg); }  /* springs back up */
  66%  { transform: scale(1.05, .96) translateY(1px) rotate(-.7deg); }
  100% { transform: scale(1, 1) rotate(0); }
}

/* ============================================================
   PHASE 5.2 — reduced-motion gap: dance had no pinned pose
   ============================================================
   Every other mood got a static pin as it was built, but dance is carried
   ENTIRELY by keyframes — so with animation off it collapsed to idle with an
   open mouth. Pin a readable mid-groove: one arm up, one down, weight on one
   leg. Values lifted straight from the 50% keyframes so the still matches a
   frame the animation actually passes through.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  [data-mood="dance"] .b-all   { transform: rotate(-3.5deg) scale(1.02, .975); }
  [data-mood="dance"] .b-head  { transform: rotate(-8deg) translateY(1px); }
  [data-mood="dance"] .b-arm-l { transform: rotate(128deg) scale(1, .72); }
  [data-mood="dance"] .b-arm-r { transform: rotate(-12deg) scale(1, .84); }
  [data-mood="dance"] .b-leg-l { transform: rotate(12deg) translateY(-3px); }

  /* the bhangra variant is a different silhouette — both arms up */
  .buddy.dance-b[data-mood="dance"] .b-all   { transform: translateY(-9px) rotate(-1deg) scale(.95, 1.06); }
  .buddy.dance-b[data-mood="dance"] .b-head  { transform: rotate(-4deg) translateY(-2px); }
  .buddy.dance-b[data-mood="dance"] .b-arm-l { transform: rotate(154deg) scale(1, .90); }
  .buddy.dance-b[data-mood="dance"] .b-arm-r { transform: rotate(-150deg) scale(1, .86); }
  .buddy.dance-b[data-mood="dance"] .b-leg-l { transform: rotate(-16deg) translateY(-5px); }
  .buddy.dance-b[data-mood="dance"] .b-leg-r { transform: rotate(16deg) translateY(-5px); }
}

/* ============================================================
   BUDDY v3 — painterly canvas mount (replaces the inline SVG rig)
   ============================================================
   Engine fit: scale = min(W*0.94/560, H*0.96/740), bottom-anchored at H*0.99.

   SIZING, and the mistake worth not repeating: the manifest's `anchor.top`
   is 40, but that is frame padding, NOT the head. The character actually
   spans y 237 (head) -> 711 (feet) = 474 units. Sizing the mount against
   678 units instead of 474 rendered him 31% too small.
   Mounts below make 474 units land at 375px desktop / 105px mobile, which
   is exactly what the old SVG rig measured head-top to shoe-bottom.
   Negative margins re-seat him on the old feet line so nothing shifts.
   ============================================================ */
.buddy-canvas {
  position: relative; z-index: 2;
  width: 471px; height: 610px; margin: -195px -85.5px 0;
  pointer-events: none;             /* the click handler lives on .buddy */
}
.buddy-canvas canvas { display: block; }

@media (max-width: 999px) { .buddy-canvas { width: 377px; height: 488px; margin: -156px -68.5px 0; } }
@media (max-width: 700px) { .buddy-canvas { width: 290px; height: 376px; margin: -120px -52.5px 0; } }
@media (max-width: 560px) { .buddy-canvas { width: 132px; height: 171px; margin: -55px -24px 0; } }

/* ============================================================
   AUTH LAYER — login card, password card, account menu (F20)
   ============================================================
   Cards live inside #chatLog so they inherit its scroll and its
   width, and so the composer being hidden leaves no empty gap. */
.login-card, .pw-card {
  display: block;
  margin: 10px 0 4px;
  padding: 16px 16px 14px;
  background: var(--panel);
  border: 2px solid var(--crimson);
  border-radius: 12px;
  box-shadow: 3px 3px 0 rgba(0, 0, 0, .45);
  color: var(--cream);
}
.login-card h4, .pw-card h4 {
  margin: 0 0 12px;
  font-family: var(--font-display);
  font-size: 1.02rem;
  letter-spacing: .06em;
  color: var(--cream);
}
.login-card label, .pw-card label {
  display: block;
  margin: 0 0 4px;
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--cream-dim);
}
.login-card input, .pw-card input {
  width: 100%;
  margin: 0 0 10px;
  padding: 10px 12px;
  font: inherit;
  font-size: 16px;            /* 16px or iOS zooms the page on focus */
  color: var(--cream);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 8px;
}
.login-card input:focus-visible, .pw-card input:focus-visible {
  outline: 2px solid var(--crimson-hot);
  outline-offset: 1px;
  border-color: var(--crimson-hot);
}
.login-card button[type="submit"], .pw-card button[type="submit"] {
  width: 100%;
  margin-top: 2px;
  padding: 11px 14px;
  font-family: var(--font-display);
  font-size: .86rem;
  letter-spacing: .1em;
  color: var(--cream);
  background: var(--crimson);
  border: 2px solid var(--ink);
  border-radius: 8px;
  box-shadow: 2px 2px 0 var(--ink);
  cursor: pointer;
  transition: transform .12s;
}
.login-card button[type="submit"]:active,
.pw-card button[type="submit"]:active { transform: translate(2px, 2px); box-shadow: none; }
.login-card button[disabled], .pw-card button[disabled] { opacity: .6; cursor: default; }
.pw-cancel {
  width: 100%;
  margin-top: 8px;
  padding: 8px;
  font: inherit;
  font-size: .82rem;
  color: var(--cream-dim);
  background: none;
  border: 0;
  cursor: pointer;
  text-decoration: underline;
}
/* The error line is a live region, so it must hold its place in the layout —
   growing the card under the user's thumb as they read it is worse than a gap. */
.auth-err {
  min-height: 1.1em;
  margin: 8px 0 0;
  font-size: .8rem;
  color: var(--crimson-hot);
}
.auth-foot {
  margin: 6px 0 0;
  font-size: .74rem;
  color: var(--cream-dim);
}
.auth-foot a { color: var(--gold); }

/* Account button: a ghost clone of .chat-share, round, one letter. */
.chat-acct {
  margin-left: 8px;
  width: 30px; height: 30px;
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-size: .8rem; line-height: 1;
  color: var(--cream);
  background: transparent;
  border: 2px solid var(--cream-dim);
  border-radius: 50%;
  cursor: pointer;
  transition: transform .12s, border-color .12s;
}
.chat-acct:hover { border-color: var(--crimson-hot); }
.chat-acct:active { transform: translate(1px, 1px); }
.chat-acct[hidden] { display: none; }

#acctMenu {
  position: absolute;
  top: 100%; right: 10px;
  z-index: 40;
  min-width: 190px;
  margin-top: 6px;
  padding: 8px;
  background: var(--panel);
  border: 2px solid var(--crimson);
  border-radius: 10px;
  box-shadow: 3px 3px 0 rgba(0, 0, 0, .5);
}
#acctMenu .acct-email {
  margin: 2px 6px 8px;
  font-size: .74rem;
  color: var(--cream-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#acctMenu button {
  display: block;
  width: 100%;
  padding: 8px 6px;
  font: inherit;
  font-size: .84rem;
  text-align: left;
  color: var(--cream);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}
#acctMenu button:hover, #acctMenu button:focus-visible { background: var(--bg-2); }
/* The popover is positioned against the chat header. */
.chat-head { position: relative; }

@media (max-width: 420px) {
  .login-card, .pw-card { padding: 13px 12px 12px; }
  .login-card h4, .pw-card h4 { font-size: .94rem; }
  #acctMenu { right: 6px; min-width: 170px; }
}

/* `hidden` is only `display:none` in the UA stylesheet, so any author rule with
   a display wins — .chat-chips and .chat-input are both flex, which is exactly
   how a signed-out visitor ended up looking at a composer they cannot use.
   State beats layout here, so this rule has to be the loud one. */
.chat-chips[hidden], .chat-input[hidden], .chat-acct[hidden] { display: none !important; }

/* ============================================================
   RESTORE — old transcript, divider, pin-to-bottom (F9)
   ============================================================ */
/* A conversation from two days ago must not animate in as though it just
   arrived. `.restored` is set on every row painted from the server. */
.msg.restored, .latent-card.restored { animation: none; }

.chat-divider {
  align-self: stretch;
  display: flex; align-items: center; gap: 10px;
  margin: 4px 0 2px;
  font-family: var(--font-scribble);
  font-size: .78rem;
  color: var(--cream-dim);
  text-align: center;
}
.chat-divider::before, .chat-divider::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--line);
}

/* Scroll anchoring: the browser holds ONE element still when content changes.
   Left to itself it picks a bubble in the middle of the view, which freezes the
   reader in place while a reply grows below them. Opting every row out and
   leaving this 1px last child as the only candidate makes "hold still" mean
   "hold the bottom". The negative margin eats the flex gap so the anchor costs
   no visible space. */
.chat-log > * { overflow-anchor: none; }
.log-anchor {
  overflow-anchor: auto;
  flex: 0 0 1px;
  height: 1px;
  margin-top: -13px;
  pointer-events: none;
}
/* Being off screen does NOT retire an anchor — measured in the pane, a reply
   growing while the reader sat 700px up still dragged the view down one pixel
   per pixel, because the anchor stayed the only eligible node. So chat.js puts
   .unpinned on the log the moment they scroll away from the bottom, which
   leaves the browser no anchor at all, and takes it off when they come back. */
.chat-log.unpinned .log-anchor { overflow-anchor: none; }

/* ============================================================
   NEW CHAT — header button, two-tap confirm (D7)
   ============================================================ */

/* A ghost clone of .chat-share: same box, no gold fill, so SHARE stays the
   one loud thing in the header and "new chat" reads as the quieter action. */
.chat-new {
  margin-left: auto; padding: 7px 10px;
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--font-display); font-size: .72rem; letter-spacing: .08em;
  color: var(--cream-dim);
  background: transparent;
  border: 2px solid var(--cream-dim); border-radius: 6px;
  cursor: pointer;
  transition: transform .12s, border-color .12s, background .12s, color .12s;
}
.chat-new:hover { color: var(--cream); border-color: var(--crimson-hot); }
.chat-new:active { transform: translate(1px, 1px); }
.chat-new[hidden] { display: none !important; }

/* .chat-elo also claims margin-left:auto. Whichever of the two is present
   first takes the gap; when ELO is showing, NEW must not claim it again or
   the two split the header and the buttons drift apart. */
.chat-elo ~ .chat-new { margin-left: 8px; }

/* Armed: crimson fill is the whole point — the second tap is destructive to
   the on-screen conversation, so the button must stop looking like the first. */
.chat-new[data-state="armed"] {
  color: var(--cream);
  background: var(--crimson);
  border-color: var(--crimson);
}
.chat-new[data-state="armed"] .chat-new-sign,
.chat-new[data-state="busy"] .chat-new-sign { display: none; }
.chat-new[data-state="busy"] { opacity: .6; cursor: default; }

/* The armed prompt is an announcement, not a label — screen readers get it
   from a live region instead of a button whose name changes under them. */
.chat-new-status {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

@media (max-width: 699px) {
  /* ELO is already gone here and the buddy takes the top-right corner, so the
     header has room for one word at most. "+" alone still reads as "new", and
     PAKKA? comes back for the armed state because that one cannot be guessed. */
  /* Every pixel this button takes comes out of #botModeTag, which is the
     AI-parody line and already ellipsises at this width. Tighter padding and
     a tighter header gap hand most of it back. */
  .chat-new { padding: 6px 7px; margin-left: 6px; }
  .chat-head { gap: 8px; }
  .chat-new[data-state="idle"] .chat-new-txt { display: none; }
  .chat-new[data-state="idle"] { margin-left: auto; }
}

/* ============================================================
   RETURNING USER — chat-first landing (D8)
   ============================================================ */

/* Someone who has already talked to the bot does not need the pitch again;
   they need the conversation. The hero goes entirely rather than shrinking,
   because a half hero is still a scroll between them and the input. */
html.returning .hero { display: none; }

/* Tablet is the only breakpoint that needs re-proportioning: mobile already
   gives the chat the whole viewport, and desktop's stage is a 100dvh grid.
   Here the buddy and the chat are both sized for a page that scrolls, so with
   the hero gone they still add up to more than 1024px of iPad. */
@media (min-width: 700px) and (max-width: 999px) {
  html.returning .buddy { width: 160px; }
  html.returning .buddy-spot { width: 170px; height: 200px; }
  html.returning .chat { height: min(62dvh, 620px); }

  /* Measured at 768x1024: stacked, the chrome above the chat is 648px — 100
     padding, 92 title, 74 resume line, 30 grid margin and a 352px buddy column
     (the rig is roughly 1:2, so 160px wide is still 332px tall). The chat's own
     620px then puts the input 223px below the fold. Shrinking the buddy is what
     D8 asks for, but stacked it cannot pay for itself; beside the chat it does,
     and 160px is exactly a side-column width. Desktop already does this at
     1000px — returning just brings the same grid down one breakpoint. */
  html.returning .stage-grid {
    display: grid; grid-template-columns: 180px 1fr; gap: 20px;
    align-items: stretch; margin-top: 14px;
  }
  html.returning .buddy-zone { justify-content: flex-end; }
  html.returning .stage { padding-top: 88px; }
}

/* The way back to the hero, in the resume line. Quiet on purpose: it is an
   escape hatch, not an invitation to leave the chat. */
.intro-link {
  color: var(--gold);
  text-decoration: none;
  border-bottom: 1px dashed rgba(242, 185, 13, .5);
  white-space: nowrap;
}
.intro-link:hover { color: var(--cream); border-bottom-color: var(--cream); }
