import React from "react";
import {AbsoluteFill, useCurrentFrame, interpolate, useVideoConfig} from "remotion";
import {loadFont as loadBesley} from "@remotion/google-fonts/Besley";
import {loadFont as loadInter} from "@remotion/google-fonts/Inter";

const besley = loadBesley().fontFamily;
const inter = loadInter().fontFamily;

const PETROL = "#20383A", PETROL2 = "#0e1d1f", LIME = "#94c11f", LIME_D = "#6f9216";
const TEAL = "#298294", TEALL = "#9bd0d6", INK = "#20383A", RED = "#c0492f", AMBER = "#b07f1e", GREY = "#8a938f";

const reveal = (f: number, s: number) => ({
  opacity: interpolate(f, [s, s + 9], [0, 1], {extrapolateLeft: "clamp", extrapolateRight: "clamp"}),
  transform: `translateY(${interpolate(f, [s, s + 12], [16, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"})}px)`,
});
const fade = (f: number, s: number, e: number, d = 12) => interpolate(f, [s, s + d, e - d, e], [0, 1, 1, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
const win = (f: number, a: number, b: number) => interpolate(f, [a, a + 14, b - 14, b], [0, 1, 1, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
const app = (f: number, a: number) => interpolate(f, [a, a + 12], [0, 1], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});

// ---------- rail ----------
type ItemDef = {label: string; appear: number; green?: number; red?: number; detail?: string};
const Check: React.FC<{f: number; it: ItemDef}> = ({f, it}) => {
  if (f < it.appear) return null;
  let state: "pending" | "red" | "green" = "pending";
  if (it.red && f >= it.red && (!it.green || f < it.green)) state = "red";
  if (it.green && f >= it.green) state = "green";
  const change = state === "green" ? it.green! : state === "red" ? it.red! : it.appear;
  const pop = interpolate(f, [change, change + 7], [0.55, 1], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
  const box = state === "green" ? LIME_D : state === "red" ? RED : "transparent";
  const bord = state === "pending" ? "2px solid #b9c2bd" : "none";
  return (
    <div style={{display: "flex", alignItems: "flex-start", gap: 16, margin: "13px 0", ...reveal(f, it.appear)}}>
      <div style={{width: 36, height: 36, borderRadius: 9, background: box, border: bord, display: "flex", alignItems: "center", justifyContent: "center", color: "#fff", fontSize: 25, fontWeight: 700, transform: `scale(${pop})`, flex: "none", marginTop: 1, boxShadow: state === "red" ? `0 0 0 5px rgba(192,73,60,.18)` : "none"}}>{state === "green" ? "✓" : state === "red" ? "✕" : ""}</div>
      <div>
        <div style={{fontFamily: inter, fontSize: 26, color: state === "red" ? RED : state === "green" ? INK : "#65706b", fontWeight: state === "pending" ? 400 : 600}}>{it.label}{state === "red" && <span style={{color: RED, fontWeight: 700}}> - caught</span>}</div>
        {state === "red" && it.detail && <div style={{fontFamily: inter, fontSize: 20, color: RED, marginTop: 4, lineHeight: 1.28}}>{it.detail}</div>}
      </div>
    </div>
  );
};
const PRE: ItemDef[] = [
  {label: "Right tool for this data?", appear: 118, green: 240},
  {label: "Stripped the sensitive bits?", appear: 268, green: 390},
  {label: "Briefed it properly?", appear: 418, green: 505},
  {label: "Gave it the source?", appear: 532, green: 622},
];
const POST: ItemDef[] = [
  {label: "Facts verified?", appear: 962, green: 1004},
  {label: "Nothing invented?", appear: 1030, red: 1060, green: 1716, detail: "“4,200” isn’t in your notes"},
  {label: "Sounds like us?", appear: 1206, red: 1230, green: 1758, detail: "“transformational” - too promotional"},
  {label: "Would you sign it?", appear: 1786, green: 1810},
];

// ---------- primitives ----------
const card: React.CSSProperties = {background: "#fbfaf7", borderRadius: 16, padding: "26px 32px", boxShadow: "0 20px 60px rgba(0,0,0,.3)", width: 820};
const Caption: React.FC<{children: React.ReactNode}> = ({children}) => <div style={{fontFamily: besley, fontWeight: 700, fontSize: 38, color: "#f5f2ec", marginBottom: 24}}>{children}</div>;
const VisCard: React.FC<{caption: string; children: React.ReactNode}> = ({caption, children}) => <div><Caption>{caption}</Caption><div style={{...card, width: 760}}>{children}</div></div>;
const MiniDots: React.FC<{f: number}> = ({f}) => <span style={{display: "inline-flex", gap: 6}}>{[0, 1, 2].map((i) => {const o = 0.3 + 0.7 * (0.5 + 0.5 * Math.sin((f / 7 + i * 0.5) * Math.PI * 2)); return <span key={i} style={{width: 11, height: 11, borderRadius: 99, background: TEALL, opacity: o}} />;})}</span>;

// ---- chat bubbles ----
const aiCard: React.CSSProperties = {background: "#fbfaf7", borderRadius: "8px 22px 22px 22px", padding: "20px 28px", boxShadow: "0 16px 44px rgba(0,0,0,.26)", maxWidth: 770};
const userBubble: React.CSSProperties = {maxWidth: 600, color: "#eef5f2", fontFamily: inter, fontSize: 23, lineHeight: 1.42, padding: "14px 20px", borderRadius: "22px 22px 6px 22px", boxShadow: "0 12px 30px rgba(0,0,0,.22)"};
const Avatar: React.FC = () => <span style={{width: 28, height: 28, borderRadius: 99, background: PETROL, color: LIME, fontFamily: besley, fontWeight: 700, fontSize: 13, display: "flex", alignItems: "center", justifyContent: "center", flex: "none"}}>AI</span>;

// ---- highlighter piece: a lime marker sweeps left-to-right under a changed fragment ----
const Hi: React.FC<{f: number; at: number; children: React.ReactNode}> = ({f, at, children}) => {
  const sweep = interpolate(f, [at, at + 14], [0, 1], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
  const pop = interpolate(f, [at + 5, at + 17], [0, 1], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
  return (
    <span style={{position: "relative", display: "inline-block", padding: "0 2px"}}>
      <span style={{position: "absolute", left: -2, right: -2, top: 2, bottom: 1, background: "rgba(148,193,31,.34)", borderRadius: 5, transform: `scaleX(${sweep})`, transformOrigin: "left center", zIndex: 0}} />
      <span style={{position: "relative", zIndex: 1, color: INK, fontWeight: interpolate(pop, [0, 1], [400, 600]), boxShadow: pop > 0.6 ? `inset 0 -2px 0 ${LIME_D}` : "none"}}>{children}</span>
    </span>
  );
};

// ---- pre-flight visuals ----
const VTool: React.FC<{f: number}> = ({f}) => {
  const rows = [{t: "ChatGPT - free, personal login", ok: false, at: 130}, {t: "Your private Claude account", ok: false, at: 152}, {t: "Microsoft Copilot - company · EU-hosted", ok: true, at: 176}];
  return (<VisCard caption="1 · The right tool for this data?">{rows.map((r, i) => {const m = app(f, r.at + 40); return (
    <div key={i} style={{display: "flex", alignItems: "center", justifyContent: "space-between", gap: 18, padding: "14px 16px", margin: "8px 0", borderRadius: 10, border: r.ok ? `2px solid ${LIME_D}` : "2px solid #e6e1d6", background: r.ok ? `rgba(111,146,22,${0.08 * m})` : "#fff", ...reveal(f, r.at)}}>
      <span style={{fontFamily: inter, fontSize: 25, color: r.ok ? INK : "#9a9a90", textDecoration: !r.ok && m > 0.4 ? "line-through" : "none", fontWeight: r.ok ? 700 : 400}}>{r.t}</span>
      <span style={{width: 34, height: 34, borderRadius: 8, flex: "none", display: "flex", alignItems: "center", justifyContent: "center", color: "#fff", fontWeight: 700, fontSize: 21, background: r.ok ? LIME_D : RED, opacity: m}}>{r.ok ? "✓" : "✕"}</span>
    </div>);})}</VisCard>);
};
const FieldRow: React.FC<{f: number; label: string; value: string; maskAt?: number; keep?: boolean}> = ({f, label, value, maskAt, keep}) => {
  const m = maskAt ? app(f, maskAt) : 0;
  return (<div style={{display: "flex", alignItems: "center", gap: 20, padding: "13px 0", borderBottom: "1px solid #eee7da"}}>
    <span style={{fontFamily: inter, fontSize: 21, color: GREY, width: 180, textTransform: "uppercase", letterSpacing: 1, fontWeight: 600}}>{label}</span>
    <span style={{flex: 1, position: "relative", fontFamily: inter, fontSize: 26, color: INK, fontWeight: 600}}>
      <span style={{opacity: keep ? 1 : 1 - m}}>{value}</span>{!keep && <span style={{position: "absolute", left: 0, opacity: m, color: PETROL, letterSpacing: 3}}>•••••••••</span>}
    </span>
    {keep ? <span style={{fontSize: 20, color: LIME_D, fontWeight: 700}}>keep</span> : <span style={{fontSize: 19, color: LIME_D, fontWeight: 700, opacity: m, border: `1px solid ${LIME_D}`, borderRadius: 99, padding: "3px 12px"}}>anonymised</span>}
  </div>);
};
const VData: React.FC<{f: number}> = ({f}) => <VisCard caption="2 · Stripped the sensitive bits?"><FieldRow f={f} label="Beneficiary" value="Maria Schmidt" maskAt={322} /><FieldRow f={f} label="Budget" value="€480,000" maskAt={352} /><FieldRow f={f} label="Partner org" value="Caritas Berlin" keep /></VisCard>;
const VBrief: React.FC<{f: number}> = ({f}) => {
  const tags = [["Role", "a sceptical CFO", 430], ["Audience", "the board", 452], ["Format", "5 bullets", 474]] as const;
  return (<div><Caption>3 · Briefed it properly?</Caption><div style={{...card, width: 760, display: "flex", flexWrap: "wrap", gap: 14}}>{tags.map(([k, v, at], i) => (
    <span key={i} style={{display: "inline-flex", gap: 8, alignItems: "baseline", padding: "12px 18px", borderRadius: 10, background: "#eef3e6", ...reveal(f, at as number)}}><b style={{fontFamily: inter, fontSize: 19, color: TEAL, textTransform: "uppercase", letterSpacing: 1}}>{k}</b><span style={{fontFamily: inter, fontSize: 25, color: INK, fontWeight: 600}}>{v}</span></span>
  ))}<div style={{width: "100%", fontFamily: inter, fontSize: 22, color: GREY, marginTop: 6, ...reveal(f, 496)}}>A clear brief, not a vague ask.</div></div></div>);
};
const VSource: React.FC<{f: number}> = ({f}) => <div><Caption>4 · Gave it the source?</Caption><div style={{...card, width: 760, display: "flex", alignItems: "center", gap: 22}}>
  <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke={TEAL} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={{flex: "none"}}><path d="M21 11.5l-8.5 8.5a5 5 0 01-7-7l8.5-8.5a3.3 3.3 0 014.7 4.7L9 17.5a1.7 1.7 0 01-2.3-2.3L14 8" /></svg>
  <div style={{flex: 1}}><div style={{fontFamily: inter, fontSize: 26, color: INK, fontWeight: 700}}>Q3-impact-notes.pdf</div><div style={{fontFamily: inter, fontSize: 21, color: GREY, marginTop: 4}}>It reads your notes; it doesn't guess.</div></div>
  <span style={{fontFamily: inter, fontSize: 21, color: LIME_D, fontWeight: 700, border: `1px solid ${LIME_D}`, borderRadius: 99, padding: "6px 16px", opacity: app(f, 614)}}>attached ✓</span></div></div>;

// ---- feedback todo ----
const Todo: React.FC<{f: number; at: number; done: boolean; text: string}> = ({f, at, done, text}) => {
  if (f < at) return null;
  return (
    <div style={{display: "flex", gap: 14, alignItems: "flex-start", padding: "11px 0", ...reveal(f, at)}}>
      <span style={{width: 28, height: 28, borderRadius: 7, flex: "none", marginTop: 2, border: done ? "none" : "2px solid #c3ccc7", background: done ? LIME_D : "transparent", color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 17, fontWeight: 700}}>{done ? "✓" : ""}</span>
      <span style={{fontFamily: inter, fontSize: 24, lineHeight: 1.34, color: done ? GREY : INK, textDecoration: done ? "line-through" : "none"}}>{text}</span>
    </div>
  );
};

// ---- the workflow, as one chat thread: you -> AI draft -> your feedback (sends, slides up) -> AI revised ----
const Workflow: React.FC<{f: number}> = ({f}) => {
  const numFlag = f >= 1060;
  const toneFlag = f >= 1230;
  const factGreen = f >= 1004;
  const sent = f >= 1540;
  const revising = f >= 1620 && f < 1700;
  const revised = f >= 1700;
  // the thread auto-scrolls up as the conversation grows past the viewport
  const scrollY = interpolate(f, [1545, 1640, 1720, 1820], [0, 70, 134, 188], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
  const settle = sent ? interpolate(f, [1540, 1566], [12, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"}) : 0;
  return (
    <div style={{width: 880, height: 684, overflow: "hidden", position: "relative", WebkitMaskImage: "linear-gradient(to bottom, transparent 0, #000 38px, #000 100%)"}}>
      <div style={{position: "absolute", left: 0, right: 0, top: 0, paddingTop: 46, paddingBottom: 30, display: "flex", flexDirection: "column", gap: 18, transform: `translateY(${-scrollY}px)`}}>

        {/* M1 - you */}
        <div style={{display: "flex", justifyContent: "flex-end", ...reveal(f, 672)}}>
          <div style={{...userBubble, background: "#2f5d61"}}>Draft a CSRD impact paragraph from these notes - concise and factual.</div>
        </div>

        {/* M2 - AI first draft */}
        {f >= 712 && (
          <div style={{display: "flex", justifyContent: "flex-start", ...reveal(f, 720)}}>
            <div style={aiCard}>
              <div style={{display: "flex", alignItems: "center", gap: 10, marginBottom: 12}}><Avatar /><span style={{fontFamily: inter, fontSize: 18, letterSpacing: 2, textTransform: "uppercase", color: TEAL, fontWeight: 700}}>First draft</span></div>
              <div style={{fontFamily: inter, fontSize: 29, lineHeight: 1.55, color: INK}}>
                In 2025, our community programme reached <span style={{color: numFlag ? RED : INK, fontWeight: numFlag ? 700 : 400, textDecoration: numFlag ? "line-through" : "none"}}>4,200</span> beneficiaries across <span style={factGreen ? {color: INK, fontWeight: 600, background: "rgba(111,146,22,.18)", borderRadius: 4, padding: "1px 5px", boxShadow: `inset 0 -2px 0 ${LIME_D}`} : {}}>14 partner organisations</span>{factGreen && <span style={{color: LIME_D, fontWeight: 700}}> ✓</span>}, delivering <span style={{color: toneFlag ? AMBER : INK, fontWeight: toneFlag ? 700 : 400, textDecoration: toneFlag ? "line-through" : "none"}}>transformational</span> impact.
              </div>
            </div>
          </div>
        )}

        {/* M3 - your feedback: composes as you review, then sends & settles */}
        {f >= 1064 && (
          <div style={{display: "flex", justifyContent: "flex-end", ...reveal(f, 1064)}}>
            <div style={{...userBubble, maxWidth: 620, background: sent ? "#2f5d61" : "rgba(38,72,75,.62)", border: sent ? "1.5px solid transparent" : "1.5px dashed rgba(155,208,214,.55)", transform: `translateY(${settle}px)`}}>
              <div style={{fontSize: 16, letterSpacing: 1.5, textTransform: "uppercase", color: TEALL, fontWeight: 700, marginBottom: 9}}>{sent ? "You" : "You · drafting feedback"}</div>
              {f >= 1084 && <div style={{...reveal(f, 1084), marginBottom: 7}}>Remove “4,200” - it isn’t in my notes.</div>}
              {f >= 1250 && <div style={reveal(f, 1250)}>Cut “transformational” - keep our factual tone.</div>}
              {f >= 1440 && (
                <div style={{marginTop: 15, display: "flex", justifyContent: "flex-end"}}>
                  {sent ? (
                    <span style={{display: "inline-flex", gap: 8, alignItems: "center", background: LIME_D, color: "#fff", fontWeight: 700, fontSize: 18, padding: "7px 15px", borderRadius: 9, ...reveal(f, 1540)}}>Sent <span>✓</span></span>
                  ) : (
                    <span style={{display: "inline-flex", gap: 8, alignItems: "center", background: TEAL, color: "#fff", fontWeight: 700, fontSize: 18, padding: "7px 15px", borderRadius: 9, ...reveal(f, 1440)}}>Send <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 2L11 13" /><path d="M22 2l-7 20-4-9-9-4 20-7z" /></svg></span>
                  )}
                </div>
              )}
            </div>
          </div>
        )}

        {/* M4 - AI revised, with changed pieces highlighter-sweeping in one by one */}
        {f >= 1612 && (
          <div style={{display: "flex", justifyContent: "flex-start", ...reveal(f, 1620)}}>
            <div style={aiCard}>
              {revising ? (
                <div style={{display: "flex", gap: 12, alignItems: "center", color: TEAL, fontFamily: inter, fontSize: 23, padding: "4px 2px"}}>Applying your feedback <MiniDots f={f} /></div>
              ) : (
                <>
                  <div style={{display: "flex", alignItems: "center", gap: 10, marginBottom: 12, justifyContent: "space-between"}}>
                    <span style={{display: "flex", alignItems: "center", gap: 10}}><Avatar /><span style={{fontFamily: inter, fontSize: 18, letterSpacing: 2, textTransform: "uppercase", color: LIME_D, fontWeight: 700}}>Revised draft</span></span>
                    <span style={{fontSize: 18, color: LIME_D, fontWeight: 700, opacity: app(f, 1822)}}>your fixes applied ✓</span>
                  </div>
                  <div style={{fontFamily: inter, fontSize: 29, lineHeight: 1.6, color: INK}}>
                    In 2025, our community programme <Hi f={f} at={1714}>supported people</Hi> across 14 partner organisations, delivering <Hi f={f} at={1756}>measurable</Hi> impact. <Hi f={f} at={1794}>Final reach figures are pending verification.</Hi>
                  </div>
                </>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

export const Demo: React.FC = () => {
  const f = useCurrentFrame();
  const {fps} = useVideoConfig();
  const introO = fade(f, 0, 92, 14);
  const splitO = interpolate(f, [92, 112, 1834, 1860], [0, 1, 1, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
  const sigDraw = interpolate(f, [1995, 2070], [1400, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
  const sent = f >= 2190;
  const cardEnter = app(f, 1892);
  const cardOut = interpolate(f, [2256, 2326], [1, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
  // closing line stays hidden until the draft is sent, then fades in plainly (no zoom)
  const tagRise = interpolate(f, [2304, 2366], [12, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});
  const tagFade = interpolate(f, [2304, 2362, 2745, 2800], [0, 1, 1, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"});

  return (
    <AbsoluteFill style={{fontFamily: inter, background: `radial-gradient(130% 130% at 82% 8%, #2c5054 0%, ${PETROL} 48%, ${PETROL2} 100%)`}}>
      <div style={{position: "absolute", top: 42, left: 56, fontFamily: besley, fontWeight: 700, fontSize: 32, color: "#f5f2ec", opacity: 0.9, zIndex: 5}}>PHINEO<span style={{color: LIME}}>.</span></div>

      {f < 110 && (
        <AbsoluteFill style={{justifyContent: "center", alignItems: "flex-start", padding: "0 130px", opacity: introO}}>
          <div style={{fontWeight: 700, letterSpacing: 6, fontSize: 26, color: TEALL, textTransform: "uppercase"}}>Live demo</div>
          <div style={{fontFamily: besley, fontWeight: 700, fontSize: 100, color: "#f5f2ec", lineHeight: 1.04, marginTop: 18}}>The checklist<br />does the work.</div>
          <div style={{width: 150, height: 9, background: LIME, borderRadius: 3, margin: "32px 0 24px"}} />
          <div style={{fontFamily: besley, fontStyle: "italic", fontSize: 38, color: LIME}}>AI drafts. Your guardrails decide.</div>
        </AbsoluteFill>
      )}

      {f >= 92 && f < 1860 && (
        <AbsoluteFill style={{flexDirection: "row", opacity: splitO, padding: "100px 56px 56px"}}>
          <div style={{flex: 1, display: "flex", alignItems: "center", justifyContent: "center", paddingRight: 44}}>
            {f < 655 ? (
              <div style={{position: "relative", width: 800, height: 540}}>
                <div style={{position: "absolute", inset: 0, opacity: win(f, 112, 256)}}><VTool f={f} /></div>
                <div style={{position: "absolute", inset: 0, opacity: win(f, 268, 406)}}><VData f={f} /></div>
                <div style={{position: "absolute", inset: 0, opacity: win(f, 418, 520)}}><VBrief f={f} /></div>
                <div style={{position: "absolute", inset: 0, opacity: win(f, 532, 650)}}><VSource f={f} /></div>
              </div>
            ) : (
              <div style={{opacity: win(f, 655, 1858)}}><Workflow f={f} /></div>
            )}
          </div>
          <div style={{width: 640, background: "#fbfaf7", borderRadius: 20, padding: "30px 34px", boxShadow: "0 30px 70px rgba(0,0,0,.35)", alignSelf: "stretch", display: "flex", flexDirection: "column"}}>
            <div style={{fontFamily: besley, fontWeight: 700, fontSize: 36, color: PETROL}}>Your guardrails</div>
            <div style={{fontFamily: inter, fontSize: 22, color: LIME_D, fontWeight: 600, marginBottom: 8}}>the part WE bring, not the AI</div>
            <div style={{fontFamily: inter, fontSize: 20, letterSpacing: 2, color: TEAL, textTransform: "uppercase", fontWeight: 700, marginTop: 14}}>Pre-flight</div>
            {PRE.map((it, i) => <Check key={i} f={f} it={it} />)}
            <div style={{fontFamily: inter, fontSize: 20, letterSpacing: 2, color: TEAL, textTransform: "uppercase", fontWeight: 700, marginTop: 14}}>Post-flight</div>
            {POST.map((it, i) => <Check key={i} f={f} it={it} />)}
          </div>
        </AbsoluteFill>
      )}

      {/* SIGN & SEND -> the message box fades out, the line grows to centre */}
      {f >= 1857 && (
        <AbsoluteFill style={{justifyContent: "center", alignItems: "center"}}>
          <div style={{width: 1180, background: "#fbfaf7", borderRadius: 20, boxShadow: "0 40px 90px rgba(0,0,0,.42)", padding: "44px 56px", opacity: cardEnter * cardOut, transform: `translateY(${interpolate(f, [1857, 1892], [24, 0], {extrapolateLeft: "clamp", extrapolateRight: "clamp"})}px)`}}>
            <div style={{display: "flex", justifyContent: "space-between", alignItems: "center"}}>
              <div style={{fontFamily: inter, fontSize: 22, letterSpacing: 2, textTransform: "uppercase", color: TEAL, fontWeight: 700}}>Final draft</div>
              <div style={{fontFamily: inter, fontSize: 22, color: LIME_D, fontWeight: 700, display: "flex", alignItems: "center", gap: 12}}><span style={{width: 26, height: 26, borderRadius: 8, background: LIME_D, color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 17}}>✓</span>Cleared by every check</div>
            </div>
            <div style={{fontFamily: inter, fontSize: 32, lineHeight: 1.5, color: INK, marginTop: 26}}>In 2025, our community programme supported people across 14 partner organisations, delivering measurable impact. Final reach figures are pending verification.</div>
            <div style={{height: 1, background: "#e3ded3", margin: "34px 0 24px"}} />
            <div style={{display: "flex", justifyContent: "space-between", alignItems: "flex-end"}}>
              <div>
                <div style={{fontFamily: inter, fontSize: 19, color: GREY, textTransform: "uppercase", letterSpacing: 2, fontWeight: 700, marginBottom: 2}}>Signed</div>
                <svg width="340" height="84" viewBox="0 0 340 84" fill="none"><path d="M12,58 C44,10 78,8 96,50 C108,78 132,80 150,48 C168,14 206,10 236,54 C252,78 286,68 332,26" stroke={INK} strokeWidth="4.5" strokeLinecap="round" strokeLinejoin="round" strokeDasharray="1400" strokeDashoffset={sigDraw} /></svg>
                <div style={{fontFamily: inter, fontSize: 21, color: INK, fontWeight: 600, opacity: app(f, 2090)}}>K. Tesch · 11 Jun 2026</div>
              </div>
              {f >= 2128 && (
                <div style={reveal(f, 2128)}>
                  {!sent ? (
                    <div style={{display: "flex", alignItems: "center", gap: 14, background: TEAL, color: "#fff", fontFamily: inter, fontWeight: 700, fontSize: 28, padding: "16px 34px", borderRadius: 14}}>Send<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 2L11 13" /><path d="M22 2l-7 20-4-9-9-4 20-7z" /></svg></div>
                  ) : (
                    <div style={{display: "flex", alignItems: "center", gap: 14, background: LIME_D, color: "#fff", fontFamily: inter, fontWeight: 700, fontSize: 28, padding: "16px 34px", borderRadius: 14, ...reveal(f, 2190)}}>Sent<span style={{fontSize: 24}}>✓</span></div>
                  )}
                </div>
              )}
            </div>
          </div>
        </AbsoluteFill>
      )}

      {/* closing line - appears only after Sent, plain fade-in, centred */}
      {f >= 2300 && (
        <AbsoluteFill style={{justifyContent: "center", alignItems: "center"}}>
          <div style={{fontFamily: besley, fontStyle: "italic", fontSize: 62, color: "#f5f2ec", textAlign: "center", whiteSpace: "nowrap", opacity: tagFade, transform: `translateY(${tagRise}px)`}}>You decide. You sign. You <span style={{color: LIME}}>send.</span></div>
        </AbsoluteFill>
      )}
    </AbsoluteFill>
  );
};
