/* Tramata Cloud — 10s brand video. Scene components.
   Editorial coastal-modernist: warm paper, brick, azulejo, Fraunces/Newsreader/
   Public Sans/JetBrains Mono. Composed of Sprites inside the Stage.
   Camera is always gently drifting; concrete hero moment first, then line-up,
   then the bundle math, then the sign-off.
*/

const C = {
  paper: "#faf6ee", paperDeep: "#f4ecdb", surface: "#fffdf8",
  ink: "#1a1614", inkSoft: "#4a423a", inkMuted: "#6b635a",
  hair: "#e3d9c9", hairStrong: "#d4c6ad",
  brick: "#b54a2a", brickDeep: "#8a3820", brickTint: "#f7e9e2",
  azulejo: "#2c5d8f", azulejoTint: "#e4ecf3",
  sage: "#5d7a4a", sageTint: "#ebf0e3", amber: "#b88b1f",
  wa: "#def7ec", waInk: "#102e23",
};
const DISPLAY = '"Fraunces", Georgia, serif';
const BODY = '"Newsreader", Georgia, serif';
const UI = '"Public Sans", system-ui, sans-serif';
const MONO = '"JetBrains Mono", ui-monospace, monospace';

const { Stage, Sprite, useTime, useSprite, Easing, interpolate, animate, clamp } = window;

/* ---------- helpers ---------- */
function Eyebrow({ children, color = C.brick, x, y, size = 15, align = "left" }) {
  return (
    <div style={{ position: "absolute", left: x, top: y, fontFamily: UI, fontWeight: 600,
      fontSize: size, letterSpacing: "0.22em", textTransform: "uppercase", color,
      transform: align === "center" ? "translateX(-50%)" : "none", whiteSpace: "nowrap" }}>
      {children}
    </div>
  );
}

/* paper grain + soft vignette, drawn once behind everything */
function Backdrop() {
  return (
    <div style={{ position: "absolute", inset: 0, background: C.paper }}>
      <div style={{ position: "absolute", inset: 0, background:
        "radial-gradient(120% 80% at 18% 12%, rgba(255,255,255,0.6), transparent 55%)," +
        "radial-gradient(120% 90% at 85% 95%, rgba(244,236,219,0.7), transparent 50%)" }} />
      <div style={{ position: "absolute", inset: 0, opacity: 0.5, mixBlendMode: "multiply",
        backgroundImage:
          "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/><feColorMatrix values='0 0 0 0 0.18 0 0 0 0 0.16 0 0 0 0 0.14 0 0 0 0.04 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>\")" }} />
    </div>
  );
}

/* ============================================================ SCENE 1
   0–4s — CallBack, live. A phone: missed-call banner drops, then an
   auto-sent WhatsApp reply. Camera slowly pushes in.
*/
function PhoneScene() {
  const t = useTime();                       // global time
  // camera: slow push-in across the scene
  const camScale = interpolate([0, 4], [1.0, 1.16], Easing.easeInOutSine)(t);
  const camY = interpolate([0, 4], [0, -26], Easing.easeInOutSine)(t);

  return (
    <Sprite start={0} end={4.15}>
      {({ localTime: lt }) => {
        const exit = clamp((lt - 3.85) / 0.3, 0, 1);
        const phoneIn = Easing.easeOutCubic(clamp(lt / 0.6, 0, 1));
        const bannerIn = Easing.easeOutBack(clamp((lt - 0.7) / 0.5, 0, 1));
        const bubbleIn = Easing.easeOutCubic(clamp((lt - 1.9) / 0.5, 0, 1));
        const sentIn = clamp((lt - 2.7) / 0.4, 0, 1);
        return (
          <div style={{ position: "absolute", inset: 0,
            transform: `scale(${camScale}) translateY(${camY}px)`, transformOrigin: "50% 46%",
            opacity: 1 - exit }}>
            <Eyebrow x={640} y={150} align="center" color={C.brick}>Tramata Cloud · CallBack</Eyebrow>
            {/* phone */}
            <div style={{ position: "absolute", left: 640, top: 250, transform:
              `translateX(-50%) translateY(${(1 - phoneIn) * 40}px)`, opacity: phoneIn }}>
              <div style={{ width: 360, height: 540, background: C.surface,
                border: `1px solid ${C.hairStrong}`, borderRadius: 42, padding: 14,
                boxShadow: "0 40px 90px -30px rgba(26,22,20,0.5)", position: "relative" }}>
                {/* notch */}
                <div style={{ position: "absolute", top: 22, left: "50%", transform: "translateX(-50%)",
                  width: 110, height: 26, background: C.ink, borderRadius: 14 }} />
                <div style={{ position: "absolute", inset: 14, borderRadius: 30, background: C.paperDeep,
                  overflow: "hidden" }}>
                  {/* status bar */}
                  <div style={{ position: "absolute", top: 0, left: 0, right: 0, height: 56,
                    display: "flex", alignItems: "flex-end", justifyContent: "space-between",
                    padding: "0 22px 8px", fontFamily: UI, fontSize: 13, color: C.inkSoft, fontWeight: 600 }}>
                    <span>9:41</span><span style={{ letterSpacing: "0.1em" }}>WhatsApp</span>
                  </div>

                  {/* missed call banner */}
                  <div style={{ position: "absolute", top: 74, left: 16, right: 16,
                    transform: `translateY(${(1 - bannerIn) * -30}px)`, opacity: clamp(bannerIn, 0, 1) }}>
                    <div style={{ background: C.brickTint, border: `1px solid ${C.brick}`,
                      borderRadius: 14, padding: "12px 14px", display: "flex", alignItems: "center", gap: 11 }}>
                      <div style={{ width: 34, height: 34, borderRadius: 17, background: C.brick,
                        display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
                        <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.2"
                          strokeLinecap="round" strokeLinejoin="round">
                          <path d="M3 5l4-1 2 5-3 2a14 14 0 007 7l2-3 5 2-1 4a2 2 0 01-2 1A17 17 0 013 7a2 2 0 010-2z"/>
                          <line x1="22" y1="2" x2="16" y2="8"/><line x1="16" y1="2" x2="22" y2="8"/>
                        </svg>
                      </div>
                      <div>
                        <div style={{ fontFamily: UI, fontWeight: 700, fontSize: 14.5, color: C.brickDeep }}>Missed call</div>
                        <div style={{ fontFamily: UI, fontSize: 12.5, color: C.inkMuted }}>+351 919 ··· 204 · just now</div>
                      </div>
                    </div>
                  </div>

                  {/* auto-reply bubble */}
                  <div style={{ position: "absolute", top: 178, left: 16, right: 60,
                    opacity: clamp(bubbleIn, 0, 1), transform: `translateY(${(1 - bubbleIn) * 16}px)` }}>
                    <div style={{ background: C.wa, color: C.waInk, borderRadius: "14px 14px 14px 4px",
                      padding: "11px 13px", fontFamily: BODY, fontSize: 15, lineHeight: 1.4,
                      boxShadow: "0 6px 16px -8px rgba(16,46,35,0.4)" }}>
                      Olá! Desculpe não termos atendido — como podemos ajudar? 🌊
                      <div style={{ fontFamily: MONO, fontSize: 10.5, color: C.sage, marginTop: 6,
                        opacity: sentIn, letterSpacing: "0.02em" }}>
                        ✓ auto-sent by CallBack · 4s
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        );
      }}
    </Sprite>
  );
}

/* ============================================================ SCENE 2
   4–6.9s — The line-up. Three product cards rise in sequence.
*/
function Card({ name, price, sub, accent, delay, lt, glyph }) {
  const inP = Easing.easeOutBack(clamp((lt - delay) / 0.55, 0, 1));
  const op = clamp((lt - delay) / 0.4, 0, 1);
  return (
    <div style={{ width: 280, background: C.surface, border: `1px solid ${C.hair}`,
      borderRadius: 8, padding: "26px 26px 24px", position: "relative",
      boxShadow: "0 30px 60px -34px rgba(26,22,20,0.28)",
      transform: `translateY(${(1 - inP) * 60}px) scale(${0.92 + 0.08 * inP})`, opacity: op }}>
      <div style={{ position: "absolute", top: -1, left: -1, width: 56, height: 4, background: accent }} />
      <div style={{ height: 46, display: "flex", alignItems: "center", color: accent }}>{glyph}</div>
      <div style={{ fontFamily: DISPLAY, fontWeight: 500, fontSize: 30, color: C.ink, marginTop: 8 }}>{name}</div>
      <div style={{ fontFamily: BODY, fontSize: 16.5, color: C.inkMuted, marginTop: 6, lineHeight: 1.35 }}>{sub}</div>
      <div style={{ fontFamily: MONO, fontSize: 17, color: accent, marginTop: 18, fontWeight: 500 }}>{price}</div>
    </div>
  );
}

function LineupScene() {
  return (
    <Sprite start={4} end={7}>
      {({ localTime: lt }) => {
        const inAll = clamp(lt / 0.3, 0, 1);
        const exit = clamp((lt - 2.7) / 0.3, 0, 1);
        const drift = interpolate([0, 3], [18, -18], Easing.easeInOutSine)(lt);
        return (
          <div style={{ position: "absolute", inset: 0, opacity: (1 - exit),
            transform: `translateY(${drift}px)` }}>
            <Eyebrow x={640} y={150} align="center">Four tools · one job each</Eyebrow>
            <div style={{ position: "absolute", left: 640, top: 196, transform: "translateX(-50%)",
              fontFamily: DISPLAY, fontWeight: 400, fontSize: 40, color: C.ink, whiteSpace: "nowrap",
              opacity: inAll, fontVariationSettings: '"opsz" 144, "SOFT" 30' }}>
              Small tools that pay for themselves.
            </div>
            <div style={{ position: "absolute", left: 640, top: 320, transform: "translateX(-50%)",
              display: "flex", gap: 26 }}>
              <Card name="CallBack" price="€19/mo" sub="Texts back every missed call." accent={C.brick} delay={0.25} lt={lt}
                glyph={<svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><path d="M3 5l4-1 2 5-3 2a14 14 0 007 7l2-3 5 2-1 4a2 2 0 01-2 1A17 17 0 013 7a2 2 0 010-2z"/></svg>} />
              <Card name="ReviewBoost" price="€29/mo" sub="Asks happy clients for reviews." accent={C.amber} delay={0.5} lt={lt}
                glyph={<svg width="30" height="30" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.9 6.3 6.9.7-5.1 4.6 1.4 6.8L12 17.8 5.9 20.4l1.4-6.8L2.2 9l6.9-.7z"/></svg>} />
              <Card name="Reminder" price="€39/mo" sub="Cuts no-shows in half." accent={C.azulejo} delay={0.75} lt={lt}
                glyph={<svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="18" height="16" rx="2"/><line x1="3" y1="10" x2="21" y2="10"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="16" y1="2" x2="16" y2="6"/></svg>} />
            </div>
          </div>
        );
      }}
    </Sprite>
  );
}

/* ============================================================ SCENE 3
   6.9–8.4s — The bundle math. €19 + €29 + €39 = €87 → €69/mo.
*/
function MathScene() {
  return (
    <Sprite start={6.9} end={8.5}>
      {({ localTime: lt }) => {
        const inA = Easing.easeOutCubic(clamp(lt / 0.4, 0, 1));
        const strike = clamp((lt - 0.55) / 0.35, 0, 1);
        const swap = Easing.easeOutBack(clamp((lt - 0.95) / 0.45, 0, 1));
        const swapOp = clamp((lt - 0.95) / 0.3, 0, 1);
        const exit = clamp((lt - 1.35) / 0.25, 0, 1);
        return (
          <div style={{ position: "absolute", inset: 0, opacity: 1 - exit }}>
            <Eyebrow x={640} y={250} align="center">Bundle all three</Eyebrow>
            {/* sum line */}
            <div style={{ position: "absolute", left: 640, top: 300, transform: "translateX(-50%)",
              fontFamily: MONO, fontSize: 34, color: C.inkMuted, opacity: inA, whiteSpace: "nowrap" }}>
              <span style={{ position: "relative" }}>
                €19 + €29 + €39 = €87
                <span style={{ position: "absolute", left: -6, right: -6, top: "52%", height: 3,
                  background: C.brick, transformOrigin: "left", transform: `scaleX(${strike})` }} />
              </span>
            </div>
            {/* bundle price */}
            <div style={{ position: "absolute", left: 640, top: 372, transform:
              `translateX(-50%) scale(${0.6 + 0.4 * swap})`, opacity: swapOp,
              display: "flex", alignItems: "baseline", gap: 16, whiteSpace: "nowrap" }}>
              <span style={{ fontFamily: DISPLAY, fontWeight: 600, fontSize: 116, color: C.brick,
                lineHeight: 1, fontVariationSettings: '"opsz" 144' }}>€69</span>
              <span style={{ fontFamily: UI, fontWeight: 600, fontSize: 26, color: C.inkSoft }}>/mo</span>
              <span style={{ fontFamily: UI, fontWeight: 600, fontSize: 16, letterSpacing: "0.04em",
                color: C.brickDeep, background: C.brickTint, padding: "7px 12px", borderRadius: 4,
                alignSelf: "center" }}>save €18</span>
            </div>
          </div>
        );
      }}
    </Sprite>
  );
}

/* ============================================================ SCENE 4
   8.4–10s — Sign-off. TRAMATA CLOUD wordmark + tagline.
*/
function SignoffScene() {
  return (
    <Sprite start={8.4} end={10}>
      {({ localTime: lt }) => {
        const tabIn = Easing.easeOutCubic(clamp(lt / 0.4, 0, 1));
        const markIn = clamp((lt - 0.2) / 0.5, 0, 1);
        const lineIn = clamp((lt - 0.7) / 0.5, 0, 1);
        const drift = interpolate([0, 1.6], [1.0, 1.05], Easing.easeOutSine)(lt);
        return (
          <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column",
            alignItems: "center", justifyContent: "center", transform: `scale(${drift})` }}>
            <div style={{ width: 70, height: 4, background: C.brick, transform: `scaleX(${tabIn})`,
              marginBottom: 26 }} />
            <div style={{ fontFamily: DISPLAY, fontWeight: 600, fontSize: 82, letterSpacing: "0.1em",
              color: C.ink, opacity: markIn, transform: `translateY(${(1 - markIn) * 14}px)`,
              whiteSpace: "nowrap", fontVariationSettings: '"opsz" 144, "SOFT" 50' }}>
              TRAMATA<span style={{ color: C.brick, letterSpacing: "0.04em" }}> CLOUD</span>
            </div>
            <div style={{ fontFamily: BODY, fontStyle: "italic", fontSize: 29, color: C.inkMuted,
              marginTop: 22, opacity: lineIn, transform: `translateY(${(1 - lineIn) * 10}px)`,
              whiteSpace: "nowrap" }}>
              Tools that pay for themselves in a month.
            </div>
          </div>
        );
      }}
    </Sprite>
  );
}

/* ---------- timestamp label for review ---------- */
function ClockLabel() {
  const t = useTime();
  const root = React.useRef(null);
  React.useEffect(() => {
    const host = document.getElementById("video-root");
    if (host) host.setAttribute("data-screen-label", "t=" + t.toFixed(1) + "s");
  }, [Math.floor(t)]);
  return null;
}

function Video() {
  const EMBED = /embed/.test(typeof location !== "undefined" ? location.hash : "");
  return (
    <Stage width={1280} height={720} duration={10} background={C.paper}
      controls={!EMBED} persistKey="tramata_cloud_vid">
      <Backdrop />
      <PhoneScene />
      <LineupScene />
      <MathScene />
      <SignoffScene />
      <ClockLabel />
    </Stage>
  );
}

ReactDOM.createRoot(document.getElementById("video-root")).render(<Video />);
