// social-posts.jsx — 6 animated Kin marketing posts.
// Each post is a self-contained scene rendered inside <PostCanvas> at
// design size (1080×1350 for 4:5 feed, 1080×1920 for 9:16 stories/TikTok).
// Posts auto-loop silently inside their canvas tile; focus mode shows the
// full Stage with playback controls.

const KIN = {
  paper: '#F6F2EB',
  paper2: '#EDE8DD',
  paper3: '#E3DDD0',
  ink:    '#2B2A28',
  ink2:   '#4A4845',
  ink3:   '#7A766F',
  ink4:   '#A8A39A',
  hairline: 'rgba(43,42,40,0.08)',
  raised: '#FBF8F2',
  coral:    '#D98667',
  coral500: '#B86A4D',
  coral50:  '#F5E5DC',
  green:    '#5F7A56',
  serif: '"Instrument Serif", "Playfair Display", Georgia, serif',
  sans:  '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif',
  mono:  '"JetBrains Mono", ui-monospace, monospace',
};

// ── Shared chrome ───────────────────────────────────────────────────────────

// A subtle Kin watermark / lockup placed bottom-corner of every post.
function KinLockup({ x = 56, y, color = KIN.ink, size = 28 }) {
  return (
    <div style={{
      position: 'absolute', left: x, bottom: y,
      display: 'flex', alignItems: 'center', gap: 10,
      fontFamily: KIN.serif, fontSize: size, color, letterSpacing: '-0.02em',
    }}>
      <svg width={size * 0.9} height={size * 0.9} viewBox="0 0 32 32" fill="none">
        <circle cx="16" cy="16" r="14" stroke={color} strokeWidth="1.5"/>
        <path d="M11 22V10M11 16l7-6M11 16l7 6" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
      <span>kin</span>
    </div>
  );
}

// Phone bezel for posts that show product. Designed to match Kin's iOS style.
function PhoneFrame({ x, y, width = 380, height = 800, children, scale = 1 }) {
  const w = width * scale, h = height * scale;
  return (
    <div style={{
      position: 'absolute', left: x, top: y,
      width: w, height: h,
      background: '#1a1a1a',
      borderRadius: 56 * scale,
      padding: 8 * scale,
      boxShadow: `0 ${30*scale}px ${80*scale}px rgba(40,30,20,0.18)`,
    }}>
      <div style={{
        width: '100%', height: '100%',
        background: KIN.raised,
        borderRadius: 48 * scale,
        overflow: 'hidden',
        position: 'relative',
      }}>
        {/* status bar */}
        <div style={{
          position: 'absolute', top: 0, left: 0, right: 0,
          height: 50 * scale,
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          padding: `${16*scale}px ${36*scale}px 0`,
          fontSize: 14 * scale, fontWeight: 600, color: KIN.ink,
          fontFamily: KIN.sans,
        }}>
          <span>9:41</span>
          <span style={{display:'flex', gap: 4*scale, alignItems:'center'}}>
            <span style={{width: 14*scale, height: 9*scale, border: `${1.5*scale}px solid ${KIN.ink}`, borderRadius: 2*scale, display:'inline-block', position:'relative'}}>
              <span style={{position:'absolute', inset: 1*scale, background: KIN.ink}}/>
            </span>
          </span>
        </div>
        {/* dynamic island */}
        <div style={{
          position: 'absolute', top: 12 * scale, left: '50%', transform: 'translateX(-50%)',
          width: 100 * scale, height: 30 * scale, background: '#000', borderRadius: 20 * scale,
        }}/>
        <div style={{position:'absolute', top: 50 * scale, left: 0, right: 0, bottom: 0}}>
          {children}
        </div>
      </div>
    </div>
  );
}

// ── POST 1 — "Just say it." (4:5 IG feed, voice logging) ────────────────────
//
// Beat 1 (0–1.0s): paper bg, big serif "Just say it." appears
// Beat 2 (1.0–2.5s): voice waveform animates at bottom of phone
// Beat 3 (2.5–4.0s): text bubble: "i did 4 sets of 5 deadlifts at 100"
// Beat 4 (4.0–6.0s): saved card slides in: "Deadlifts · 4×5 · 100 kg"
// Hold (6.0–7.0s): everything settles, lockup.

function Post1_VoiceLogging() {
  const t = useTime();

  // Voice waveform — 16 bars, sinusoidal heights driven by time
  const barHeights = Array.from({length: 24}, (_, i) => {
    const phase = i * 0.6 + t * 8;
    const amp = 6 + Math.sin(phase) * 4 + Math.sin(phase * 1.7 + 1) * 3;
    return Math.max(2, Math.abs(amp));
  });

  return (
    <div style={{position: 'absolute', inset: 0, background: KIN.paper, fontFamily: KIN.sans}}>
      {/* Serif headline at top */}
      <Sprite start={0} end={7}>
        {({ progress, localTime }) => {
          const op = Easing.easeOutCubic(clamp(localTime / 0.9, 0, 1));
          const ty = (1 - op) * 24;
          return (
            <div style={{
              position: 'absolute', top: 90, left: 56, right: 56,
              fontFamily: KIN.serif, fontSize: 132, lineHeight: 0.95, color: KIN.ink,
              letterSpacing: '-0.035em',
              opacity: op, transform: `translateY(${ty}px)`,
            }}>
              Just say it.
              <div style={{
                fontFamily: KIN.sans, fontSize: 28, color: KIN.ink3,
                marginTop: 28, fontWeight: 400, letterSpacing: '-0.005em',
                opacity: clamp((localTime - 0.5) / 0.6, 0, 1),
              }}>
                Kin logs your workout while you talk.
              </div>
            </div>
          );
        }}
      </Sprite>

      {/* Phone with chat */}
      <PhoneFrame x={350} y={500} width={380} height={780}>
        <div style={{padding: '20px 22px 0', height: '100%', position: 'relative'}}>
          <div style={{textAlign: 'center', fontSize: 16, color: KIN.ink3, marginBottom: 18}}>Kin ⌄</div>

          {/* User voice bubble (appears 1.0–) */}
          <Sprite start={1.0} end={7} keepMounted>
            {({ localTime }) => {
              if (localTime < 0) return null;
              const inT = Easing.easeOutBack(clamp(localTime / 0.5, 0, 1));
              const op = clamp(localTime / 0.4, 0, 1);
              return (
                <div style={{
                  marginLeft: 'auto',
                  width: 'fit-content', maxWidth: '80%',
                  background: KIN.coral, color: '#fff',
                  padding: '14px 16px', borderRadius: 22, borderBottomRightRadius: 6,
                  display: 'flex', alignItems: 'center', gap: 10,
                  opacity: op,
                  transform: `scale(${0.85 + inT * 0.15})`, transformOrigin: 'right',
                }}>
                  <div style={{display: 'flex', alignItems: 'center', gap: 2, height: 22}}>
                    {barHeights.slice(0, 14).map((h, i) => (
                      <span key={i} style={{
                        width: 2.5, height: h * 1.5,
                        background: 'rgba(255,255,255,0.85)', borderRadius: 2,
                      }}/>
                    ))}
                  </div>
                  <span style={{fontSize: 13, color: 'rgba(255,255,255,0.85)', fontFamily: KIN.mono}}>0:08</span>
                </div>
              );
            }}
          </Sprite>

          {/* Transcribed text bubble (appears 2.2–) */}
          <Sprite start={2.2} end={7} keepMounted>
            {({ localTime }) => {
              const op = Easing.easeOutCubic(clamp(localTime / 0.5, 0, 1));
              const ty = (1 - op) * 12;
              return (
                <div style={{
                  marginTop: 10, marginLeft: 'auto',
                  width: 'fit-content', maxWidth: '80%',
                  background: KIN.paper2, color: KIN.ink,
                  padding: '12px 16px', borderRadius: 22, borderBottomRightRadius: 6,
                  fontSize: 16,
                  opacity: op, transform: `translateY(${ty}px)`,
                }}>
                  did 4 sets of 5 deadlifts at 100
                </div>
              );
            }}
          </Sprite>

          {/* Kin's serif reply (appears 3.6–) */}
          <Sprite start={3.6} end={7} keepMounted>
            {({ localTime }) => {
              const op = Easing.easeOutCubic(clamp(localTime / 0.6, 0, 1));
              const chars = Math.floor(localTime * 26);
              const reply = "Saved. New PR — your last top set was 95.";
              return (
                <div style={{
                  marginTop: 18, opacity: op,
                  fontFamily: KIN.serif, fontSize: 22, lineHeight: 1.35, color: KIN.ink,
                }}>
                  {reply.slice(0, chars)}
                  {chars < reply.length && <span style={{opacity: 0.5}}>|</span>}
                </div>
              );
            }}
          </Sprite>

          {/* Saved workout card (appears 4.6–) */}
          <Sprite start={4.6} end={7} keepMounted>
            {({ localTime }) => {
              const op = Easing.easeOutCubic(clamp(localTime / 0.5, 0, 1));
              const ty = (1 - op) * 16;
              return (
                <div style={{
                  marginTop: 16, opacity: op, transform: `translateY(${ty}px)`,
                  position: 'relative',
                }}>
                  <div style={{position: 'absolute', left: 0, top: 0, bottom: 0, width: 3, background: KIN.green, borderRadius: 2}}/>
                  <div style={{
                    background: KIN.raised, border: `1px solid ${KIN.hairline}`, borderRadius: 14,
                    padding: '14px 16px', marginLeft: 8,
                  }}>
                    <div style={{fontSize: 10, letterSpacing: '.16em', color: KIN.green, fontWeight: 600, textTransform: 'uppercase'}}>Saved</div>
                    <div style={{fontSize: 16, color: KIN.ink, marginTop: 4, fontWeight: 500}}>Deadlifts · 4×5 · 100 kg</div>
                    <div style={{fontSize: 13, color: KIN.ink3, marginTop: 2}}>+5 kg from last week</div>
                  </div>
                </div>
              );
            }}
          </Sprite>
        </div>
      </PhoneFrame>

      <KinLockup y={56} />
    </div>
  );
}

// ── POST 2 — "Text it like a friend." (9:16 Stories/Reels, text logging) ────

function Post2_TextLogging() {
  return (
    <div style={{position: 'absolute', inset: 0, background: KIN.paper, fontFamily: KIN.sans}}>
      {/* Eyebrow */}
      <Sprite start={0} end={7} keepMounted>
        {({ localTime }) => {
          const op = clamp(localTime / 0.5, 0, 1);
          return (
            <div style={{
              position: 'absolute', top: 110, left: 56,
              fontSize: 24, color: KIN.coral500, fontWeight: 600,
              letterSpacing: '.18em', textTransform: 'uppercase',
              opacity: op,
            }}>Text it like a friend</div>
          );
        }}
      </Sprite>

      {/* Big headline */}
      <Sprite start={0.4} end={7} keepMounted>
        {({ localTime }) => {
          const op = Easing.easeOutCubic(clamp(localTime / 0.7, 0, 1));
          const ty = (1 - op) * 32;
          return (
            <div style={{
              position: 'absolute', top: 170, left: 56, right: 56,
              fontFamily: KIN.serif, fontSize: 116, lineHeight: 0.95, color: KIN.ink,
              letterSpacing: '-0.035em',
              opacity: op, transform: `translateY(${ty}px)`,
            }}>
              No forms.<br/>
              No reps to<br/>
              <em style={{color: KIN.coral500, fontStyle: 'italic'}}>tap in.</em>
            </div>
          );
        }}
      </Sprite>

      {/* Phone frame, large, centered low */}
      <PhoneFrame x={150} y={780} width={780} height={1100} scale={1}>
        <div style={{padding: '24px 26px 0', height: '100%', position: 'relative'}}>
          <div style={{textAlign: 'center', fontSize: 22, color: KIN.ink3, marginBottom: 24}}>Kin ⌄</div>

          {/* User text bubble — types in */}
          <Sprite start={1.0} end={7} keepMounted>
            {({ localTime }) => {
              const full = "did chest and triceps. felt strong. 4×8 bench at 80, 3×10 dips, 3×12 pushdowns";
              const chars = Math.floor(clamp(localTime / 1.6, 0, 1) * full.length);
              const op = clamp(localTime / 0.3, 0, 1);
              return (
                <div style={{
                  marginLeft: 'auto', maxWidth: '85%', width: 'fit-content',
                  background: KIN.coral, color: '#fff',
                  padding: '18px 22px', borderRadius: 28, borderBottomRightRadius: 8,
                  fontSize: 24, lineHeight: 1.3, opacity: op,
                }}>
                  {full.slice(0, chars)}
                  {chars < full.length && <span style={{opacity: 0.6}}>|</span>}
                </div>
              );
            }}
          </Sprite>

          {/* Kin reply — serif */}
          <Sprite start={3.0} end={7} keepMounted>
            {({ localTime }) => {
              const op = Easing.easeOutCubic(clamp(localTime / 0.6, 0, 1));
              const ty = (1 - op) * 16;
              return (
                <div style={{
                  marginTop: 28, opacity: op, transform: `translateY(${ty}px)`,
                  fontFamily: KIN.serif, fontSize: 30, lineHeight: 1.35, color: KIN.ink,
                }}>
                  Got it — push session logged. Volume is up 12% from last week.
                </div>
              );
            }}
          </Sprite>

          {/* 3 exercise rows materialize in sequence */}
          {[
            {name: 'Bench Press', sets: '4 × 8', load: '80 kg', start: 4.1},
            {name: 'Dips',        sets: '3 × 10', load: 'BW',    start: 4.5},
            {name: 'Pushdowns',   sets: '3 × 12', load: '32 kg', start: 4.9},
          ].map((ex, i) => (
            <Sprite key={ex.name} start={ex.start} end={7} keepMounted>
              {({ localTime }) => {
                const op = Easing.easeOutCubic(clamp(localTime / 0.4, 0, 1));
                const ty = (1 - op) * 12;
                return (
                  <div style={{
                    marginTop: i === 0 ? 28 : 12,
                    opacity: op, transform: `translateY(${ty}px)`,
                    background: KIN.raised, border: `1px solid ${KIN.hairline}`, borderRadius: 16,
                    padding: '20px 22px',
                    display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
                  }}>
                    <span style={{fontSize: 22, fontWeight: 500, color: KIN.ink, flex: 1}}>{ex.name}</span>
                    <span style={{fontFamily: KIN.mono, fontSize: 18, color: KIN.ink3, width: 90, textAlign: 'right'}}>{ex.sets}</span>
                    <span style={{fontFamily: KIN.mono, fontSize: 18, color: KIN.ink, width: 80, textAlign: 'right', fontWeight: 500}}>{ex.load}</span>
                  </div>
                );
              }}
            </Sprite>
          ))}
        </div>
      </PhoneFrame>

      <KinLockup y={56} size={36} />
    </div>
  );
}

// ── POST 3 — "Plans that flex." (4:5 IG feed, AI plan adapts) ───────────────

function Post3_AdaptivePlan() {
  return (
    <div style={{position: 'absolute', inset: 0, background: KIN.paper, fontFamily: KIN.sans}}>
      {/* Headline */}
      <Sprite start={0} end={8} keepMounted>
        {({ localTime }) => {
          const op = Easing.easeOutCubic(clamp(localTime / 0.7, 0, 1));
          const ty = (1 - op) * 24;
          return (
            <div style={{
              position: 'absolute', top: 84, left: 56, right: 56,
              fontFamily: KIN.serif, fontSize: 116, lineHeight: 0.95, color: KIN.ink,
              letterSpacing: '-0.035em',
              opacity: op, transform: `translateY(${ty}px)`,
            }}>
              Plans that<br/>
              <em style={{color: KIN.coral500, fontStyle: 'italic'}}>flex with you.</em>
            </div>
          );
        }}
      </Sprite>

      <Sprite start={0.6} end={8} keepMounted>
        {({ localTime }) => {
          const op = clamp(localTime / 0.5, 0, 1);
          return (
            <div style={{
              position: 'absolute', top: 358, left: 56, right: 56,
              fontFamily: KIN.sans, fontSize: 26, color: KIN.ink3,
              lineHeight: 1.4, opacity: op,
            }}>
              Tell Kin how you feel — your week rebuilds itself.
            </div>
          );
        }}
      </Sprite>

      {/* Phone */}
      <PhoneFrame x={350} y={500} width={380} height={780}>
        <div style={{padding: '20px 22px 0', height: '100%', position: 'relative'}}>
          <div style={{textAlign: 'center', fontSize: 16, color: KIN.ink3, marginBottom: 14}}>Your Week ⌄</div>

          {/* Day pills row — Monday goes from "PUSH" to "REST" */}
          <Sprite start={0.4} end={8} keepMounted>
            {({ localTime }) => {
              // Days, with Monday flipping at t=2.8
              const flipped = localTime > 2.8;
              const days = [
                {d: 'M', kind: flipped ? 'rest' : 'push'},
                {d: 'T', kind: 'done'},
                {d: 'W', kind: 'pull'},
                {d: 'T', kind: 'rest'},
                {d: 'F', kind: 'push'},
                {d: 'S', kind: 'cardio'},
                {d: 'S', kind: 'rest'},
              ];
              const flipT = clamp((localTime - 2.8) / 0.5, 0, 1);
              const flipScale = flipped ? (0.7 + Easing.easeOutBack(flipT) * 0.3) : 1;
              return (
                <div style={{display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 4}}>
                  {days.map((day, i) => {
                    const isMonday = i === 0;
                    const isDone = day.kind === 'done';
                    const isRest = day.kind === 'rest';
                    const bg = isDone ? KIN.green
                             : isRest ? KIN.coral50
                             : KIN.coral;
                    const fg = isDone || !isRest ? '#fff' : KIN.coral500;
                    return (
                      <div key={i} style={{display:'flex', flexDirection:'column', alignItems:'center', gap: 4}}>
                        <div style={{fontSize: 10, color: KIN.ink3}}>{day.d}</div>
                        <div style={{
                          width: 32, height: 32, borderRadius: 999,
                          background: bg, color: fg,
                          display: 'flex', alignItems: 'center', justifyContent: 'center',
                          fontSize: 11, fontWeight: 600,
                          transform: isMonday ? `scale(${flipScale})` : 'scale(1)',
                          transition: 'background 200ms',
                        }}>
                          {isDone ? '✓' : isRest ? 'R' : (day.kind[0].toUpperCase())}
                        </div>
                      </div>
                    );
                  })}
                </div>
              );
            }}
          </Sprite>

          {/* User says "I'm beat today" — appears at 1.4 */}
          <Sprite start={1.4} end={8} keepMounted>
            {({ localTime }) => {
              const op = Easing.easeOutCubic(clamp(localTime / 0.5, 0, 1));
              const fadeOut = clamp((localTime - 4.5) / 0.5, 0, 1);
              const ty = (1 - op) * 12;
              return (
                <div style={{
                  marginTop: 28, marginLeft: 'auto',
                  width: 'fit-content', maxWidth: '78%',
                  background: KIN.coral, color: '#fff',
                  padding: '12px 16px', borderRadius: 20, borderBottomRightRadius: 6,
                  fontSize: 15,
                  opacity: op * (1 - fadeOut * 0.5), transform: `translateY(${ty}px)`,
                }}>
                  i'm beat today, didn't sleep
                </div>
              );
            }}
          </Sprite>

          {/* Kin's serif reply at 2.2 */}
          <Sprite start={2.2} end={8} keepMounted>
            {({ localTime }) => {
              const op = Easing.easeOutCubic(clamp(localTime / 0.5, 0, 1));
              const ty = (1 - op) * 12;
              return (
                <div style={{
                  marginTop: 14, opacity: op, transform: `translateY(${ty}px)`,
                  fontFamily: KIN.serif, fontSize: 18, lineHeight: 1.35, color: KIN.ink,
                }}>
                  Heard. Swapping push for an easy mobility day, pulling Friday's volume up to compensate.
                </div>
              );
            }}
          </Sprite>

          {/* Adjustment chip slides in at 3.8 */}
          <Sprite start={3.8} end={8} keepMounted>
            {({ localTime }) => {
              const op = Easing.easeOutCubic(clamp(localTime / 0.5, 0, 1));
              const ty = (1 - op) * 16;
              return (
                <div style={{
                  marginTop: 18, opacity: op, transform: `translateY(${ty}px)`,
                  background: KIN.coral50, borderLeft: `3px solid ${KIN.coral}`,
                  padding: '12px 14px', borderRadius: 10,
                }}>
                  <div style={{fontSize: 10, letterSpacing: '.14em', color: KIN.coral500, fontWeight: 600, textTransform: 'uppercase', marginBottom: 4}}>Adjusted</div>
                  <div style={{fontFamily: KIN.serif, fontSize: 14, color: KIN.ink, fontStyle: 'italic'}}>
                    Mon: Push → Mobility · Fri: +20 min
                  </div>
                </div>
              );
            }}
          </Sprite>
        </div>
      </PhoneFrame>

      <KinLockup y={56} />
    </div>
  );
}

// ── POST 4 — "What you ate, in one line." (9:16 TikTok, nutrition) ──────────

function Post4_NutritionChat() {
  return (
    <div style={{position: 'absolute', inset: 0, background: KIN.paper, fontFamily: KIN.sans}}>
      {/* Eyebrow */}
      <Sprite start={0} end={7} keepMounted>
        {({ localTime }) => {
          const op = clamp(localTime / 0.5, 0, 1);
          return (
            <div style={{
              position: 'absolute', top: 110, left: 56,
              fontSize: 24, color: KIN.coral500, fontWeight: 600,
              letterSpacing: '.18em', textTransform: 'uppercase',
              opacity: op,
            }}>Nutrition, simplified</div>
          );
        }}
      </Sprite>

      {/* Big headline */}
      <Sprite start={0.3} end={7} keepMounted>
        {({ localTime }) => {
          const op = Easing.easeOutCubic(clamp(localTime / 0.7, 0, 1));
          const ty = (1 - op) * 32;
          return (
            <div style={{
              position: 'absolute', top: 170, left: 56, right: 56,
              fontFamily: KIN.serif, fontSize: 116, lineHeight: 0.95, color: KIN.ink,
              letterSpacing: '-0.035em',
              opacity: op, transform: `translateY(${ty}px)`,
            }}>
              One line.<br/>
              That's the whole<br/>
              <em style={{color: KIN.coral500, fontStyle: 'italic'}}>food log.</em>
            </div>
          );
        }}
      </Sprite>

      {/* Phone */}
      <PhoneFrame x={150} y={780} width={780} height={1100}>
        <div style={{padding: '24px 26px 0', height: '100%', position: 'relative'}}>
          <div style={{textAlign: 'center', fontSize: 22, color: KIN.ink3, marginBottom: 28}}>Kin ⌄</div>

          {/* User text */}
          <Sprite start={0.8} end={7} keepMounted>
            {({ localTime }) => {
              const full = "chili and a beer for dinner, scoop of greek yogurt for dessert";
              const chars = Math.floor(clamp(localTime / 1.4, 0, 1) * full.length);
              const op = clamp(localTime / 0.3, 0, 1);
              return (
                <div style={{
                  marginLeft: 'auto', maxWidth: '85%', width: 'fit-content',
                  background: KIN.coral, color: '#fff',
                  padding: '18px 22px', borderRadius: 28, borderBottomRightRadius: 8,
                  fontSize: 26, lineHeight: 1.3, opacity: op,
                }}>
                  {full.slice(0, chars)}
                  {chars < full.length && <span style={{opacity: 0.6}}>|</span>}
                </div>
              );
            }}
          </Sprite>

          {/* Kin reply */}
          <Sprite start={2.5} end={7} keepMounted>
            {({ localTime }) => {
              const op = Easing.easeOutCubic(clamp(localTime / 0.5, 0, 1));
              const ty = (1 - op) * 14;
              return (
                <div style={{
                  marginTop: 28, opacity: op, transform: `translateY(${ty}px)`,
                  fontFamily: KIN.serif, fontSize: 30, lineHeight: 1.35, color: KIN.ink,
                }}>
                  Logged. About 940 kcal — 38 g protein.
                </div>
              );
            }}
          </Sprite>

          {/* Big nutrition card */}
          <Sprite start={3.4} end={7} keepMounted>
            {({ localTime }) => {
              const op = Easing.easeOutCubic(clamp(localTime / 0.6, 0, 1));
              const ty = (1 - op) * 20;
              const ringT = Easing.easeOutCubic(clamp(localTime / 1.2, 0, 1));
              const r = 80, c = 2 * Math.PI * r;
              return (
                <div style={{
                  marginTop: 28, opacity: op, transform: `translateY(${ty}px)`,
                  background: KIN.raised, border: `1px solid ${KIN.hairline}`, borderRadius: 22,
                  padding: 26, display: 'flex', alignItems: 'center', gap: 26,
                }}>
                  <div style={{position: 'relative', width: 180, height: 180, flexShrink: 0}}>
                    <svg width="180" height="180" viewBox="0 0 180 180" style={{transform: 'rotate(-90deg)'}}>
                      <circle cx="90" cy="90" r={r} fill="none" stroke={KIN.paper2} strokeWidth="8"/>
                      <circle cx="90" cy="90" r={r} fill="none" stroke={KIN.green} strokeWidth="8" strokeLinecap="round"
                        strokeDasharray={c} strokeDashoffset={c * (1 - 0.59 * ringT)}/>
                    </svg>
                    <div style={{position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center'}}>
                      <div style={{fontFamily: KIN.serif, fontSize: 48, color: KIN.ink, letterSpacing: '-0.02em'}}>
                        {Math.floor(940 * ringT)}
                      </div>
                      <div style={{fontSize: 14, color: KIN.ink3, letterSpacing: '.14em', textTransform: 'uppercase', marginTop: 4}}>kcal</div>
                    </div>
                  </div>
                  <div style={{flex: 1}}>
                    {[
                      {label: 'Protein', val: 38, target: 160, color: KIN.green},
                      {label: 'Carbs',   val: 92, target: 220, color: KIN.coral},
                      {label: 'Fat',     val: 32, target: 70,  color: '#C79A7A'},
                    ].map((m) => (
                      <div key={m.label} style={{marginBottom: 14}}>
                        <div style={{display: 'flex', justifyContent: 'space-between', fontSize: 16, marginBottom: 6}}>
                          <span style={{color: KIN.ink, fontWeight: 500}}>{m.label}</span>
                          <span style={{color: KIN.ink3, fontFamily: KIN.mono}}>
                            {Math.floor(m.val * ringT)}/{m.target}g
                          </span>
                        </div>
                        <div style={{height: 6, background: KIN.paper2, borderRadius: 3, overflow: 'hidden'}}>
                          <div style={{width: `${(m.val/m.target) * 100 * ringT}%`, height: '100%', background: m.color, borderRadius: 3}}/>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              );
            }}
          </Sprite>
        </div>
      </PhoneFrame>

      <KinLockup y={56} size={36} />
    </div>
  );
}

// ── POST 5 — "A coach that listens." (4:5 IG feed, brand mood, type-only) ───

function Post5_BrandQuote() {
  const t = useTime();
  return (
    <div style={{position: 'absolute', inset: 0, background: KIN.paper, fontFamily: KIN.sans, overflow: 'hidden'}}>
      {/* Subtle grain via dots */}
      <div style={{
        position: 'absolute', inset: 0,
        backgroundImage: `radial-gradient(${KIN.paper3} 1px, transparent 1px)`,
        backgroundSize: '8px 8px',
        opacity: 0.4,
      }}/>

      {/* Hairline frame */}
      <div style={{
        position: 'absolute', inset: 56,
        border: `1px solid ${KIN.hairline}`,
        borderRadius: 4,
      }}/>

      {/* Eyebrow */}
      <Sprite start={0} end={6} keepMounted>
        {({ localTime }) => {
          const op = clamp(localTime / 0.5, 0, 1);
          return (
            <div style={{
              position: 'absolute', top: 110, left: '50%', transform: 'translateX(-50%)',
              fontSize: 18, color: KIN.coral500, fontWeight: 600,
              letterSpacing: '.32em', textTransform: 'uppercase',
              opacity: op, textAlign: 'center',
            }}>— Meet Kin —</div>
          );
        }}
      </Sprite>

      {/* Words appear one at a time */}
      {[
        {text: 'A',         x: 0,  delay: 0.3},
        {text: 'coach',     x: 0,  delay: 0.55},
        {text: 'that',      x: 0,  delay: 0.85},
        {text: 'listens.',  x: 0,  delay: 1.1, italic: true, color: KIN.coral500},
      ].map((w, i) => null)}

      <Sprite start={0.3} end={6} keepMounted>
        {({ localTime }) => {
          const wordT = (delay) => Easing.easeOutCubic(clamp((localTime - delay) / 0.5, 0, 1));
          return (
            <div style={{
              position: 'absolute', top: '40%', left: 0, right: 0, transform: 'translateY(-50%)',
              fontFamily: KIN.serif, fontSize: 188, lineHeight: 1.0, color: KIN.ink,
              letterSpacing: '-0.04em', textAlign: 'center',
            }}>
              <div style={{opacity: wordT(0), transform: `translateY(${(1-wordT(0))*20}px)`}}>A coach</div>
              <div style={{opacity: wordT(0.4), transform: `translateY(${(1-wordT(0.4))*20}px)`}}>that</div>
              <div style={{opacity: wordT(0.8), transform: `translateY(${(1-wordT(0.8))*20}px)`, fontStyle: 'italic', color: KIN.coral500}}>listens.</div>
            </div>
          );
        }}
      </Sprite>

      {/* Subhead */}
      <Sprite start={2.0} end={6} keepMounted>
        {({ localTime }) => {
          const op = Easing.easeOutCubic(clamp(localTime / 0.7, 0, 1));
          return (
            <div style={{
              position: 'absolute', bottom: 200, left: 80, right: 80,
              fontFamily: KIN.sans, fontSize: 26, color: KIN.ink3, lineHeight: 1.45,
              textAlign: 'center', opacity: op,
            }}>
              No reps to count, no forms to fill.<br/>
              Just talk to Kin like you'd talk to a friend.
            </div>
          );
        }}
      </Sprite>

      <KinLockup y={56} x={undefined} />
      <div style={{position: 'absolute', bottom: 56, right: 56,
        fontFamily: KIN.sans, fontSize: 18, color: KIN.ink3, letterSpacing: '.16em', textTransform: 'uppercase'}}>
        On the App Store
      </div>
    </div>
  );
}

// ── POST 6 — "12 weeks." (9:16 Stories, progress chart) ─────────────────────

function Post6_Progress() {
  return (
    <div style={{position: 'absolute', inset: 0, background: KIN.paper, fontFamily: KIN.sans}}>
      {/* Eyebrow */}
      <Sprite start={0} end={8} keepMounted>
        {({ localTime }) => {
          const op = clamp(localTime / 0.5, 0, 1);
          return (
            <div style={{
              position: 'absolute', top: 110, left: 56,
              fontSize: 24, color: KIN.coral500, fontWeight: 600,
              letterSpacing: '.18em', textTransform: 'uppercase',
              opacity: op,
            }}>12 weeks with Kin</div>
          );
        }}
      </Sprite>

      {/* Headline */}
      <Sprite start={0.3} end={8} keepMounted>
        {({ localTime }) => {
          const op = Easing.easeOutCubic(clamp(localTime / 0.7, 0, 1));
          const ty = (1 - op) * 32;
          return (
            <div style={{
              position: 'absolute', top: 170, left: 56, right: 56,
              fontFamily: KIN.serif, fontSize: 124, lineHeight: 0.95, color: KIN.ink,
              letterSpacing: '-0.035em',
              opacity: op, transform: `translateY(${ty}px)`,
            }}>
              Progress<br/>
              you can<br/>
              <em style={{color: KIN.coral500, fontStyle: 'italic'}}>see.</em>
            </div>
          );
        }}
      </Sprite>

      {/* Chart card — fills bottom half */}
      <Sprite start={1.0} end={8} keepMounted>
        {({ localTime }) => {
          const op = Easing.easeOutCubic(clamp(localTime / 0.6, 0, 1));
          const ty = (1 - op) * 30;
          // Line draws over 1.2s starting at +0.6s into sprite
          const drawT = Easing.easeOutCubic(clamp((localTime - 0.6) / 1.4, 0, 1));
          const valueT = Easing.easeOutCubic(clamp((localTime - 0.6) / 1.4, 0, 1));

          // 12 weekly data points: 1RM bench from 70 → 102.5
          const points = [
            70, 71.5, 73, 73, 75, 76.5, 78, 80, 84, 88, 95, 102.5
          ];
          const w = 760, h = 420, padX = 30, padY = 30;
          const xStep = (w - padX * 2) / (points.length - 1);
          const minV = 65, maxV = 110;
          const xy = points.map((v, i) => [
            padX + i * xStep,
            padY + (h - padY * 2) * (1 - (v - minV) / (maxV - minV)),
          ]);
          const path = xy.map((p, i) => (i === 0 ? `M ${p[0]} ${p[1]}` : `L ${p[0]} ${p[1]}`)).join(' ');
          const area = path + ` L ${xy[xy.length-1][0]} ${h - padY} L ${xy[0][0]} ${h - padY} Z`;

          // Visible portion of the line
          const visibleCount = Math.ceil(drawT * (points.length - 1)) + 1;
          const visibleXY = xy.slice(0, visibleCount);
          // Last point clipped to drawT
          if (visibleCount > 1 && drawT < 1) {
            const segT = drawT * (points.length - 1) - (visibleCount - 2);
            const a = xy[visibleCount - 2], b = xy[visibleCount - 1];
            visibleXY[visibleCount - 1] = [
              a[0] + (b[0] - a[0]) * segT,
              a[1] + (b[1] - a[1]) * segT,
            ];
          }
          const visiblePath = visibleXY.map((p, i) => (i === 0 ? `M ${p[0]} ${p[1]}` : `L ${p[0]} ${p[1]}`)).join(' ');
          const head = visibleXY[visibleXY.length - 1];

          const currentVal = points[0] + (points[points.length-1] - points[0]) * valueT;

          return (
            <div style={{
              position: 'absolute', bottom: 220, left: 56, right: 56,
              opacity: op, transform: `translateY(${ty}px)`,
              background: KIN.raised, border: `1px solid ${KIN.hairline}`, borderRadius: 28,
              padding: 36,
            }}>
              <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 18}}>
                <div>
                  <div style={{fontSize: 14, letterSpacing: '.16em', color: KIN.ink3, fontWeight: 600, textTransform: 'uppercase'}}>Bench Press · 1RM</div>
                  <div style={{display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 8}}>
                    <span style={{fontFamily: KIN.serif, fontSize: 84, color: KIN.ink, lineHeight: 1, letterSpacing: '-0.025em'}}>
                      {currentVal.toFixed(1)}
                    </span>
                    <span style={{fontFamily: KIN.serif, fontSize: 28, color: KIN.ink3}}>kg</span>
                  </div>
                </div>
                <div style={{
                  display: 'flex', alignItems: 'center', gap: 6,
                  background: '#EAEFE3', color: '#5F7A56',
                  padding: '8px 14px', borderRadius: 999, fontSize: 18, fontWeight: 600,
                  opacity: clamp((localTime - 1.6) / 0.4, 0, 1),
                }}>
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M7 17l10-10"/><path d="M8 7h9v9"/></svg>
                  +32.5 kg
                </div>
              </div>

              <svg viewBox={`0 0 ${w} ${h}`} width="100%" style={{display: 'block', overflow: 'visible'}}>
                <defs>
                  <linearGradient id="benchG" x1="0" x2="0" y1="0" y2="1">
                    <stop offset="0%" stopColor={KIN.coral} stopOpacity="0.22"/>
                    <stop offset="100%" stopColor={KIN.coral} stopOpacity="0"/>
                  </linearGradient>
                </defs>
                {[0, 1, 2, 3].map(i => (
                  <line key={i} x1={padX} x2={w - padX}
                    y1={padY + ((h - padY * 2) / 3) * i} y2={padY + ((h - padY * 2) / 3) * i}
                    stroke={KIN.hairline} strokeDasharray="3 6"/>
                ))}
                {drawT === 1 && <path d={area} fill="url(#benchG)"/>}
                {drawT > 0 && (
                  <>
                    <path d={visiblePath} fill="none" stroke={KIN.coral} strokeWidth="4" strokeLinecap="round" strokeLinejoin="round"/>
                    <circle cx={head[0]} cy={head[1]} r="9" fill="#fff" stroke={KIN.coral} strokeWidth="3"/>
                  </>
                )}
                {/* Week labels */}
                {[0, 3, 6, 9, 11].map(i => (
                  <text key={i} x={xy[i][0]} y={h - 4}
                    fontSize="14" fill={KIN.ink3} textAnchor="middle"
                    fontFamily={KIN.sans} letterSpacing="0.04em">
                    Wk {i + 1}
                  </text>
                ))}
              </svg>

              {/* Caption */}
              <div style={{
                fontFamily: KIN.serif, fontStyle: 'italic', fontSize: 24, color: KIN.ink3,
                marginTop: 16, textAlign: 'center',
                opacity: clamp((localTime - 2.2) / 0.5, 0, 1),
              }}>
                3 sessions a week. Kin handled the rest.
              </div>
            </div>
          );
        }}
      </Sprite>

      <KinLockup y={56} size={36} />
    </div>
  );
}

// ── Post registry ───────────────────────────────────────────────────────────

const POSTS = [
  {id: 'p1', title: 'Voice logging',     ratio: '4:5',  size: 'IG feed',    audience: 'Busy pro',     w: 1080, h: 1350, dur: 7,   render: Post1_VoiceLogging},
  {id: 'p2', title: 'Text logging',      ratio: '9:16', size: 'Story/Reel', audience: 'Lifters',       w: 1080, h: 1920, dur: 7,   render: Post2_TextLogging},
  {id: 'p3', title: 'Adaptive plan',     ratio: '4:5',  size: 'IG feed',    audience: 'Busy pro',     w: 1080, h: 1350, dur: 8,   render: Post3_AdaptivePlan},
  {id: 'p4', title: 'Nutrition chat',    ratio: '9:16', size: 'TikTok',     audience: 'General',       w: 1080, h: 1920, dur: 7,   render: Post4_NutritionChat},
  {id: 'p5', title: 'Brand quote',       ratio: '4:5',  size: 'IG feed',    audience: 'Brand mood',    w: 1080, h: 1350, dur: 6,   render: Post5_BrandQuote},
  {id: 'p6', title: 'Progress',          ratio: '9:16', size: 'Story/Reel', audience: 'Lifters',       w: 1080, h: 1920, dur: 8,   render: Post6_Progress},
];

Object.assign(window, {
  POSTS,
  Post1_VoiceLogging, Post2_TextLogging, Post3_AdaptivePlan,
  Post4_NutritionChat, Post5_BrandQuote, Post6_Progress,
  KIN, PhoneFrame, KinLockup,
});
