// Scenes for the API Keys explainer animation.
// Total duration budget: 28 seconds
//   Scene 1: Intro / what are API keys          [0.0 – 4.0]   4s
//   Scene 2: Key types (api vs mcp)             [4.0 – 8.5]   4.5s
//   Scene 3: Generate a key (form)              [8.5 – 13.5]  5s
//   Scene 4: One-time copy + warning            [13.5 – 18.0] 4.5s
//   Scene 5: Use a key (curl + SDK)             [18.0 – 23.0] 5s
//   Scene 6: View usage + revoke                [23.0 – 28.0] 5s

// ─── Palette (Civo Design System) ─────────────────────────────────────────
const C = {
  bg:        '#111518',  // metal-1100 (canvas)
  panel:     '#192124',  // metal-900
  raised:    '#263237',  // metal-800
  pressed:   '#3B4954',  // metal-700
  border:    '#3B4954',
  fg1:       '#f3f5f7',  // metal-50
  fg2:       '#dbe1e6',  // metal-200
  fg3:       '#9fafbc',  // metal-400
  fg4:       '#758c9f',  // metal-500
  green:     '#00FF6F',
  greenInk:  '#05df72',
  success:   '#22c55e',
  danger:    '#fb2c37',
  warn:      '#fef9c2',
  info:      '#00bcff',
  violet:    '#a800b7',
  black:     '#000',
  white:     '#fff',
};

const FONT = "'Inter', system-ui, sans-serif";
const MONO = "'Reddit Mono', ui-monospace, 'JetBrains Mono', monospace";

// ─── Small utilities ──────────────────────────────────────────────────────
const lerp = (a, b, t) => a + (b - a) * t;
const easeOut = (t) => 1 - Math.pow(1 - t, 3);
const easeIn = (t) => t * t * t;
const easeInOut = (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;

// Fade + rise helper
function fadeRise(localTime, { inDur = 0.4, holdStart = 0.4, outStart, outDur = 0.3, rise = 12 } = {}) {
  let o = 1, ty = 0;
  if (localTime < inDur) {
    const t = easeOut(clamp(localTime / inDur, 0, 1));
    o = t;
    ty = (1 - t) * rise;
  }
  if (outStart != null && localTime > outStart) {
    const t = easeIn(clamp((localTime - outStart) / outDur, 0, 1));
    o *= (1 - t);
    ty -= t * 6;
  }
  return { opacity: o, translateY: ty };
}

// ─── Common chrome ────────────────────────────────────────────────────────

function SceneLabel({ number, title, subtitle }) {
  const { localTime, duration } = useSprite();
  const out = duration - 0.4;
  const { opacity, translateY } = fadeRise(localTime, { inDur: 0.5, outStart: out, outDur: 0.35 });
  return (
    <div style={{
      position: 'absolute',
      left: 80, bottom: 80,
      opacity, transform: `translateY(${translateY}px)`,
      maxWidth: 760,
    }}>
      <div style={{
        fontFamily: MONO,
        fontSize: 13, fontWeight: 600,
        letterSpacing: '0.3px',
        color: C.green,
        textTransform: 'uppercase',
        marginBottom: 14,
      }}>
        {number}
      </div>
      <div style={{
        fontFamily: FONT,
        fontSize: 44, fontWeight: 600,
        color: C.fg1,
        lineHeight: 1.1,
        letterSpacing: '-0.02em',
        marginBottom: 14,
      }}>
        {title}
      </div>
      {subtitle && (
        <div style={{
          fontFamily: FONT,
          fontSize: 18, fontWeight: 400,
          color: C.fg3,
          lineHeight: 1.45,
          maxWidth: 680,
        }}>
          {subtitle}
        </div>
      )}
    </div>
  );
}

// Top progress bar showing scene position
function ProgressChrome({ sceneIndex, sceneCount, sceneTitles }) {
  return (
    <div style={{
      position: 'absolute',
      top: 0, left: 0, right: 0,
      padding: '28px 80px 0',
      display: 'flex',
      alignItems: 'center',
      gap: 16,
      zIndex: 10,
    }}>
      {/* Civo mark */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <svg width="26" height="26" viewBox="0 0 100 100">
          <circle cx="50" cy="50" r="40" fill="none" stroke={C.green} strokeWidth="12"/>
          <circle cx="50" cy="50" r="10" fill={C.green}/>
        </svg>
        <div style={{
          fontFamily: "'Hanken Grotesk', Inter, sans-serif",
          fontSize: 15, fontWeight: 500,
          color: C.fg2,
          letterSpacing: '0.2px',
        }}>
          Konstruct · API Keys
        </div>
      </div>
      <div style={{ flex: 1 }}/>
      {/* Segmented progress */}
      <div style={{ display: 'flex', gap: 6 }}>
        {Array.from({ length: sceneCount }).map((_, i) => (
          <div key={i} style={{
            width: 28, height: 3,
            background: i <= sceneIndex ? C.green : C.pressed,
            opacity: i === sceneIndex ? 1 : (i < sceneIndex ? 0.55 : 0.35),
            borderRadius: 2,
            transition: 'background 200ms',
          }}/>
        ))}
      </div>
    </div>
  );
}

// Animated chrome: syncs the progress bar to current scene based on time
function Chrome() {
  const time = useTime();
  const SCENES = [
    { end: 5.5,  title: 'Intro' },
    { end: 10.0, title: 'Key types' },
    { end: 15.0, title: 'Generate' },
    { end: 19.5, title: 'Copy + warn' },
    { end: 27.5, title: 'Use' },
    { end: 32.5, title: 'Revoke' },
  ];
  let idx = 0;
  for (let i = 0; i < SCENES.length; i++) {
    if (time < SCENES[i].end) { idx = i; break; }
    idx = i;
  }
  return <ProgressChrome sceneIndex={idx} sceneCount={SCENES.length} sceneTitles={SCENES.map(s=>s.title)} />;
}

// ─── Scene 1: Intro ───────────────────────────────────────────────────────
// Concept: Big abstract "key" shape travels through a gateway. Text reveals
// the core pitch — auth without SSO, scoped to org, max 30 days.

function Scene1() {
  return (
    <Sprite start={0} end={5.5}>
      {({ localTime, duration }) => <Scene1Content localTime={localTime} duration={duration} />}
    </Sprite>
  );
}

function Scene1Content({ localTime, duration }) {
  // Key glides in, hits the gate, and turns green (authenticated)
  const keyX = interpolate([0, 1.2, 2.0, 3.6], [-200, 540, 540, 540], [easeOut, easeInOut, Easing.linear])(localTime);
  const keyRot = interpolate([0, 1.2, 2.0], [-18, 0, 0], [easeOut, easeInOut])(localTime);
  const authProgress = clamp((localTime - 1.2) / 0.5, 0, 1);
  const gateGlow = authProgress;

  const textFade = fadeRise(Math.max(0, localTime - 0.6), { inDur: 0.45, outStart: duration - 0.5, outDur: 0.4 });
  const subFade = fadeRise(Math.max(0, localTime - 1.4), { inDur: 0.5, outStart: duration - 0.5, outDur: 0.4 });

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      {/* Gate (right side) */}
      <div style={{
        position: 'absolute',
        left: 780, top: 260,
        width: 120, height: 260,
        border: `2px solid ${lerp(0.15, 1, gateGlow) > 0.5 ? C.green : C.pressed}`,
        borderRight: 'none',
        borderRadius: '8px 0 0 8px',
        boxShadow: gateGlow > 0.3 ? `0 0 ${40 * gateGlow}px rgba(0, 255, 111, ${0.4 * gateGlow})` : 'none',
        transition: 'border-color 200ms',
      }}/>
      <div style={{
        position: 'absolute',
        left: 900, top: 260,
        width: 120, height: 260,
        border: `2px solid ${gateGlow > 0.5 ? C.green : C.pressed}`,
        borderLeft: 'none',
        borderRadius: '0 8px 8px 0',
        boxShadow: gateGlow > 0.3 ? `0 0 ${40 * gateGlow}px rgba(0, 255, 111, ${0.4 * gateGlow})` : 'none',
      }}/>
      {/* Check mark pops when authenticated */}
      {authProgress > 0.5 && (
        <div style={{
          position: 'absolute',
          left: 906, top: 370,
          width: 48, height: 48,
          borderRadius: '50%',
          background: C.green,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          transform: `scale(${lerp(0, 1, easeOut(clamp((authProgress - 0.5) / 0.5, 0, 1)))})`,
        }}>
          <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
            <path d="M5 12l5 5 9-11" stroke={C.panel} strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </div>
      )}

      {/* The key */}
      <KeyShape x={keyX} y={350} rotation={keyRot} color={authProgress > 0.5 ? C.green : C.fg3} />

      {/* Headline */}
      <div style={{
        position: 'absolute',
        left: 80, top: 170,
        maxWidth: 900,
        opacity: textFade.opacity,
        transform: `translateY(${textFade.translateY}px)`,
      }}>
        <div style={{
          fontFamily: MONO,
          fontSize: 13, fontWeight: 600,
          color: C.green,
          letterSpacing: '0.3px',
          textTransform: 'uppercase',
          marginBottom: 20,
        }}>Admin · API keys</div>
        <div style={{
          fontFamily: FONT,
          fontSize: 64, fontWeight: 600,
          color: C.fg1,
          lineHeight: 1.0,
          letterSpacing: '-0.03em',
        }}>
          API keys
        </div>
        <div style={{
          fontFamily: FONT,
          fontSize: 22, fontWeight: 400,
          color: C.fg3,
          lineHeight: 1.4,
          marginTop: 20,
          maxWidth: 760,
          opacity: subFade.opacity,
          transform: `translateY(${subFade.translateY}px)`,
        }}>
          <span style={{ color: C.fg2 }}>Non-interactive credentials</span> for scripts, CI, and MCP.
        </div>
      </div>
    </div>
  );
}

function KeyShape({ x, y, rotation = 0, color = C.fg3 }) {
  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      transform: `rotate(${rotation}deg)`,
      transformOrigin: 'center',
    }}>
      <svg width="180" height="80" viewBox="0 0 180 80" fill="none">
        <circle cx="40" cy="40" r="28" stroke={color} strokeWidth="6" fill="none"/>
        <circle cx="40" cy="40" r="10" fill={color}/>
        <rect x="60" y="34" width="100" height="12" fill={color}/>
        <rect x="130" y="46" width="12" height="14" fill={color}/>
        <rect x="150" y="46" width="10" height="20" fill={color}/>
      </svg>
    </div>
  );
}

// ─── Scene 2: Key types ───────────────────────────────────────────────────
function Scene2() {
  return (
    <Sprite start={5.5} end={10.0}>
      {({ localTime, duration }) => <Scene2Content localTime={localTime} duration={duration} />}
    </Sprite>
  );
}

function Scene2Content({ localTime, duration }) {
  const head = fadeRise(localTime, { inDur: 0.5, outStart: duration - 0.4, outDur: 0.35 });
  const card1 = fadeRise(Math.max(0, localTime - 0.5), { inDur: 0.5, outStart: duration - 0.4, outDur: 0.35 });
  const card2 = fadeRise(Math.max(0, localTime - 1.0), { inDur: 0.5, outStart: duration - 0.4, outDur: 0.35 });

  // Typing effect on prefixes
  const typeT1 = clamp((localTime - 1.4) / 0.8, 0, 1);
  const typeT2 = clamp((localTime - 2.2) / 0.8, 0, 1);
  const apiKey = 'konst_api_7f4a9c8e2b1d5a0f…';
  const mcpKey = 'konst_mcp_a3d8e1b6c9f2d0a7…';

  return (
    <div style={{ position: 'absolute', inset: 0, padding: '120px 80px 80px' }}>
      <div style={{
        opacity: head.opacity,
        transform: `translateY(${head.translateY}px)`,
        marginBottom: 48,
      }}>
        <div style={{
          fontFamily: MONO, fontSize: 13, fontWeight: 600,
          color: C.green, letterSpacing: '0.3px',
          textTransform: 'uppercase', marginBottom: 12,
        }}>Key types</div>
        <div style={{
          fontFamily: FONT, fontSize: 40, fontWeight: 600,
          color: C.fg1, letterSpacing: '-0.02em',
          lineHeight: 1.1,
        }}>
          Two types, identified by prefix.
        </div>
      </div>

      <div style={{ display: 'flex', gap: 24 }}>
        {/* API key card */}
        <KeyTypeCard
          style={{ opacity: card1.opacity, transform: `translateY(${card1.translateY}px)` }}
          badge="API key"
          prefix={apiKey.slice(0, Math.floor(typeT1 * apiKey.length))}
          accent={C.green}
          desc="Used to authenticate calls to the Konstruct API."
          iconKind="api"
        />
        <KeyTypeCard
          style={{ opacity: card2.opacity, transform: `translateY(${card2.translateY}px)` }}
          badge="MCP key"
          prefix={mcpKey.slice(0, Math.floor(typeT2 * mcpKey.length))}
          accent={C.info}
          desc="Used to authenticate with the Konstruct MCP server."
          iconKind="mcp"
        />
      </div>
    </div>
  );
}

function KeyTypeCard({ style, badge, prefix, accent, desc, iconKind }) {
  return (
    <div style={{
      ...style,
      flex: 1,
      background: C.panel,
      border: `1px solid ${C.border}`,
      borderRadius: 8,
      padding: '28px 28px 32px',
      position: 'relative',
      overflow: 'hidden',
    }}>
      <div style={{
        position: 'absolute', top: 0, left: 0, right: 0, height: 3,
        background: accent,
      }}/>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 24 }}>
        <div style={{
          width: 40, height: 40,
          background: 'rgba(255,255,255,0.04)',
          border: `1px solid ${C.border}`,
          borderRadius: 6,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: accent,
        }}>
          {iconKind === 'api' ? (
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8">
              <polyline points="16 18 22 12 16 6"/>
              <polyline points="8 6 2 12 8 18"/>
            </svg>
          ) : (
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8">
              <circle cx="12" cy="5" r="2"/>
              <circle cx="5" cy="19" r="2"/>
              <circle cx="19" cy="19" r="2"/>
              <path d="M12 7v4M10.3 13l-3.6 4M13.7 13l3.6 4"/>
            </svg>
          )}
        </div>
        <div style={{
          fontFamily: FONT, fontSize: 22, fontWeight: 600,
          color: C.fg1, letterSpacing: '-0.01em',
        }}>{badge}</div>
      </div>

      {/* Prefix code */}
      <div style={{
        fontFamily: MONO, fontSize: 17, fontWeight: 600,
        color: C.fg1,
        background: C.bg,
        border: `1px solid ${C.border}`,
        borderRadius: 4,
        padding: '14px 16px',
        marginBottom: 20,
        minHeight: 22,
        letterSpacing: '0.5px',
      }}>
        {prefix}
        <span style={{
          display: 'inline-block',
          width: 8, height: 17,
          background: accent,
          marginLeft: 2,
          verticalAlign: '-3px',
          animation: 'cursorBlink 1s steps(2) infinite',
        }}/>
      </div>

      <div style={{
        fontFamily: FONT, fontSize: 16, fontWeight: 400,
        color: C.fg3, lineHeight: 1.4,
      }}>{desc}</div>
    </div>
  );
}

// ─── Scene 3: Generate a key (form) ───────────────────────────────────────
function Scene3() {
  return (
    <Sprite start={10.0} end={15.0}>
      {({ localTime, duration }) => <Scene3Content localTime={localTime} duration={duration} />}
    </Sprite>
  );
}

function Scene3Content({ localTime, duration }) {
  const dialog = fadeRise(localTime, { inDur: 0.45, outStart: duration - 0.4, outDur: 0.35 });

  // Sequentially fill fields: name → type → role → expiry → button
  // Name: 0.3–1.2 (typing)
  const name = 'pipeline-api-key';
  const nameT = clamp((localTime - 0.3) / 0.9, 0, 1);
  const nameText = name.slice(0, Math.floor(nameT * name.length));

  // Type select at 1.3, selection lands at 1.8
  const typeOpen = localTime > 1.3 && localTime < 2.2;
  const typeSelected = localTime > 2.0;

  // Role select 2.3, selection 2.8
  const roleOpen = localTime > 2.3 && localTime < 3.2;
  const roleSelected = localTime > 3.0;

  // Expiry 3.3, selection 3.7
  const expirySelected = localTime > 3.5;

  // Button click 4.0
  const btnPress = localTime > 4.0 && localTime < 4.3;
  const btnHover = localTime > 3.9;

  const cursorPos = (() => {
    // interp cursor path: start → name → type → role → expiry → button
    const points = [
      { t: 0.0, x: 1100, y: 700 },
      { t: 0.5, x: 760, y: 300 },  // name field
      { t: 1.5, x: 760, y: 390 },  // type select
      { t: 2.5, x: 760, y: 480 },  // role select
      { t: 3.4, x: 760, y: 570 },  // expiry
      { t: 4.0, x: 900, y: 660 },  // button
    ];
    for (let i = 0; i < points.length - 1; i++) {
      if (localTime >= points[i].t && localTime <= points[i + 1].t) {
        const t = (localTime - points[i].t) / (points[i + 1].t - points[i].t);
        const eased = easeInOut(t);
        return {
          x: lerp(points[i].x, points[i + 1].x, eased),
          y: lerp(points[i].y, points[i + 1].y, eased),
        };
      }
    }
    return points[points.length - 1];
  })();

  return (
    <div style={{ position: 'absolute', inset: 0, padding: '120px 80px 80px' }}>
      {/* Left side: label */}
      <div style={{
        position: 'absolute',
        left: 80, top: 170,
        maxWidth: 380,
        opacity: dialog.opacity,
      }}>
        <div style={{
          fontFamily: MONO, fontSize: 13, fontWeight: 600,
          color: C.green, letterSpacing: '0.3px',
          textTransform: 'uppercase', marginBottom: 12,
        }}>Step 1 · Generate</div>
        <div style={{
          fontFamily: FONT, fontSize: 36, fontWeight: 600,
          color: C.fg1, letterSpacing: '-0.02em',
          lineHeight: 1.1, marginBottom: 18,
        }}>
          Create a key.
        </div>
        <div style={{
          fontFamily: FONT, fontSize: 16, fontWeight: 400,
          color: C.fg3, lineHeight: 1.5,
        }}>
          Required fields: name, type, role, and expiry. The role cannot exceed the creator's role. Maximum expiry is 30 days.
        </div>
      </div>

      {/* Dialog (right side) */}
      <div style={{
        position: 'absolute',
        left: 540, top: 140,
        width: 600,
        background: C.panel,
        border: `1px solid ${C.border}`,
        borderRadius: 8,
        boxShadow: '0 20px 60px rgba(0,0,0,0.5)',
        opacity: dialog.opacity,
        transform: `translateY(${dialog.translateY}px) scale(${lerp(0.96, 1, dialog.opacity)})`,
        overflow: 'visible',
      }}>
        {/* Dialog header */}
        <div style={{
          padding: '20px 24px 16px',
          borderBottom: `1px solid ${C.border}`,
          fontFamily: FONT, fontSize: 18, fontWeight: 600,
          color: C.fg1,
        }}>
          Generate API key
        </div>

        <div style={{ padding: 24 }}>
          <FormField label="Name">
            <div style={{
              background: C.bg, border: `1px solid ${C.border}`,
              borderRadius: 4, padding: '10px 12px',
              fontFamily: MONO, fontSize: 14, color: C.fg1,
              minHeight: 20,
            }}>
              {nameText}
              {nameT < 1 && nameT > 0 && (
                <span style={{
                  display: 'inline-block', width: 2, height: 16,
                  background: C.green, marginLeft: 1, verticalAlign: '-2px',
                  animation: 'cursorBlink 1s steps(2) infinite',
                }}/>
              )}
            </div>
          </FormField>

          <FormField label="Type">
            <Select
              value={typeSelected ? 'API key' : (typeOpen ? '' : '')}
              placeholder="Select type"
              open={typeOpen}
              options={['API key', 'MCP key']}
              highlightIndex={typeOpen ? (localTime > 1.7 ? 0 : -1) : -1}
            />
          </FormField>

          <FormField label="Role">
            <Select
              value={roleSelected ? 'Developer' : ''}
              placeholder="Select role"
              open={roleOpen}
              options={['Developer', 'Team Admin']}
              highlightIndex={roleOpen ? (localTime > 2.7 ? 0 : -1) : -1}
            />
          </FormField>

          <FormField label="Expires in">
            <div style={{ display: 'flex', gap: 8 }}>
              {['7 days', '14 days', '30 days'].map((label, i) => {
                const selected = expirySelected && i === 2;
                return (
                  <div key={label} style={{
                    flex: 1,
                    padding: '10px 0', textAlign: 'center',
                    border: `1px solid ${selected ? C.green : C.border}`,
                    background: selected ? 'rgba(0,255,111,0.08)' : C.bg,
                    color: selected ? C.green : C.fg2,
                    borderRadius: 4,
                    fontFamily: FONT, fontSize: 14, fontWeight: selected ? 600 : 400,
                    transition: 'all 150ms',
                  }}>
                    {label}
                  </div>
                );
              })}
            </div>
          </FormField>

          {/* Buttons */}
          <div style={{
            display: 'flex', gap: 12, marginTop: 28,
            justifyContent: 'flex-end',
          }}>
            <div style={{
              padding: '10px 20px',
              border: `1px solid ${C.border}`,
              borderRadius: 4,
              fontFamily: FONT, fontSize: 14, fontWeight: 600,
              color: C.fg2, background: 'transparent',
            }}>Cancel</div>
            <div style={{
              padding: '10px 20px',
              background: btnPress ? C.greenInk : C.green,
              borderRadius: 4,
              fontFamily: FONT, fontSize: 14, fontWeight: 700,
              color: C.panel,
              transform: btnPress ? 'scale(0.97)' : 'scale(1)',
              boxShadow: btnHover && !btnPress ? '0 0 0 3px rgba(0,255,111,0.25)' : 'none',
              transition: 'all 100ms',
            }}>Generate key</div>
          </div>
        </div>
      </div>

      {/* Cursor */}
      {localTime > 0.2 && localTime < 4.5 && (
        <Cursor x={cursorPos.x} y={cursorPos.y} clicking={btnPress} />
      )}
    </div>
  );
}

function FormField({ label, children }) {
  return (
    <div style={{ marginBottom: 16 }}>
      <div style={{
        fontFamily: FONT, fontSize: 13, fontWeight: 500,
        color: C.fg2, marginBottom: 6,
      }}>{label}</div>
      {children}
    </div>
  );
}

function Select({ value, placeholder, open, options, highlightIndex = -1 }) {
  return (
    <div style={{ position: 'relative' }}>
      <div style={{
        background: C.bg,
        border: `1px solid ${open ? C.green : C.border}`,
        borderRadius: 4,
        padding: '10px 12px',
        fontFamily: FONT, fontSize: 14,
        color: value ? C.fg1 : C.fg4,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      }}>
        <span>{value || placeholder}</span>
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <path d="M3 5l4 4 4-4" stroke={C.fg3} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </div>
      {open && (
        <div style={{
          position: 'absolute', top: '100%', left: 0, right: 0,
          marginTop: 4,
          background: C.panel,
          border: `1px solid ${C.border}`,
          borderRadius: 4,
          boxShadow: '0 8px 24px rgba(0,0,0,0.5)',
          zIndex: 20,
          overflow: 'hidden',
        }}>
          {options.map((opt, i) => (
            <div key={opt} style={{
              padding: '10px 12px',
              background: i === highlightIndex ? C.raised : 'transparent',
              fontFamily: FONT, fontSize: 14,
              color: C.fg1,
            }}>
              {opt}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function Cursor({ x, y, clicking }) {
  return (
    <div style={{
      position: 'absolute',
      left: x, top: y,
      transform: `translate(-2px, -2px) scale(${clicking ? 0.85 : 1})`,
      transition: 'transform 80ms',
      pointerEvents: 'none',
      zIndex: 100,
    }}>
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none">
        <path d="M2 2l7 20 3.5-8.5L21 10 2 2z" fill={C.white} stroke={C.black} strokeWidth="1.2" strokeLinejoin="round"/>
      </svg>
      {clicking && (
        <div style={{
          position: 'absolute',
          left: -14, top: -14,
          width: 30, height: 30,
          borderRadius: '50%',
          border: `2px solid ${C.green}`,
          opacity: 0.6,
        }}/>
      )}
    </div>
  );
}

// ─── Scene 4: Copy the key (ONE TIME) ─────────────────────────────────────
function Scene4() {
  return (
    <Sprite start={15.0} end={19.5}>
      {({ localTime, duration }) => <Scene4Content localTime={localTime} duration={duration} />}
    </Sprite>
  );
}

function Scene4Content({ localTime, duration }) {
  const dialog = fadeRise(localTime, { inDur: 0.45, outStart: duration - 0.4, outDur: 0.35 });

  // Key string + copy button interaction
  const key = 'konst_api_7f4a9c8e2b1d5a0f3e6c4b8d1a2e5f9c';
  const copied = localTime > 2.2;
  const btnHover = localTime > 1.8 && localTime < 2.2;

  // Warning text pulse after copy
  const warnPulse = copied ? (Math.sin((localTime - 2.2) * 4) * 0.5 + 0.5) : 0;

  // Cursor targets copy button
  const cursorPos = (() => {
    if (localTime < 0.6) return { x: 1100, y: 700, show: false };
    if (localTime < 2.0) {
      const t = clamp((localTime - 0.6) / 1.4, 0, 1);
      return {
        x: lerp(1100, 920, easeInOut(t)),
        y: lerp(700, 340, easeInOut(t)),
        show: true,
      };
    }
    return { x: 920, y: 340, show: true };
  })();
  const clicking = localTime > 2.0 && localTime < 2.3;

  return (
    <div style={{ position: 'absolute', inset: 0, padding: '120px 80px 80px' }}>
      {/* Left label */}
      <div style={{
        position: 'absolute',
        left: 80, top: 170,
        maxWidth: 380,
        opacity: dialog.opacity,
      }}>
        <div style={{
          fontFamily: MONO, fontSize: 13, fontWeight: 600,
          color: C.danger, letterSpacing: '0.3px',
          textTransform: 'uppercase', marginBottom: 12,
        }}>Step 2 · Copy the key</div>
        <div style={{
          fontFamily: FONT, fontSize: 36, fontWeight: 600,
          color: C.fg1, letterSpacing: '-0.02em',
          lineHeight: 1.1, marginBottom: 18,
        }}>
          Shown once.
        </div>
        <div style={{
          fontFamily: FONT, fontSize: 16, fontWeight: 400,
          color: C.fg3, lineHeight: 1.5,
        }}>
          The plaintext key is displayed only at creation. Copy it to a secret store. To recover from a missed copy, delete the key and create a new one.
        </div>
      </div>

      {/* Dialog */}
      <div style={{
        position: 'absolute',
        left: 540, top: 140,
        width: 620,
        background: C.panel,
        border: `1px solid ${C.border}`,
        borderRadius: 8,
        boxShadow: '0 20px 60px rgba(0,0,0,0.5)',
        opacity: dialog.opacity,
        transform: `translateY(${dialog.translateY}px) scale(${lerp(0.96, 1, dialog.opacity)})`,
      }}>
        <div style={{
          padding: '20px 24px 16px',
          borderBottom: `1px solid ${C.border}`,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke={C.success} strokeWidth="2">
            <circle cx="12" cy="12" r="10"/>
            <path d="M8 12l3 3 5-6"/>
          </svg>
          <span style={{ fontFamily: FONT, fontSize: 18, fontWeight: 600, color: C.fg1 }}>
            Copy your new API key
          </span>
        </div>

        <div style={{ padding: 24 }}>
          {/* Key field with copy button */}
          <div style={{
            display: 'flex', gap: 0,
            background: C.bg,
            border: `1px solid ${copied ? C.success : C.border}`,
            borderRadius: 4,
            overflow: 'hidden',
            marginBottom: 20,
            transition: 'border-color 200ms',
          }}>
            <div style={{
              flex: 1,
              padding: '12px 14px',
              fontFamily: MONO, fontSize: 13,
              color: C.fg1, letterSpacing: '0.4px',
              overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
            }}>
              {key}
            </div>
            <div style={{
              padding: '10px 14px',
              background: copied ? C.success : (btnHover ? C.raised : 'transparent'),
              borderLeft: `1px solid ${C.border}`,
              display: 'flex', alignItems: 'center', gap: 8,
              fontFamily: FONT, fontSize: 13, fontWeight: 600,
              color: copied ? C.panel : C.fg1,
              transition: 'all 150ms',
            }}>
              {copied ? (
                <>
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
                    <path d="M5 12l5 5 9-11" strokeLinecap="round" strokeLinejoin="round"/>
                  </svg>
                  Copied
                </>
              ) : (
                <>
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <rect x="9" y="9" width="13" height="13" rx="2"/>
                    <path d="M5 15V5a2 2 0 0 1 2-2h10"/>
                  </svg>
                  Copy
                </>
              )}
            </div>
          </div>

          {/* Shell snippet */}
          <div style={{
            background: C.bg,
            border: `1px solid ${C.border}`,
            borderRadius: 4,
            padding: '14px 16px',
            fontFamily: MONO, fontSize: 13,
            lineHeight: 1.6,
          }}>
            <div style={{ color: C.fg4 }}><span style={{ color: C.info }}>export</span> KONSTRUCT_API_KEY=<span style={{ color: C.green }}>"konst_api_…"</span></div>
          </div>

          {/* Warning box */}
          <div style={{
            marginTop: 18,
            padding: '12px 14px',
            background: copied ? `rgba(251, 44, 55, ${0.08 + warnPulse * 0.08})` : 'rgba(251, 44, 55, 0.08)',
            border: `1px solid rgba(251, 44, 55, ${copied ? 0.5 : 0.3})`,
            borderRadius: 4,
            display: 'flex', gap: 10,
            fontFamily: FONT, fontSize: 13,
            color: C.fg2, lineHeight: 1.45,
            transition: 'all 200ms',
          }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={C.danger} strokeWidth="2" style={{ flexShrink: 0, marginTop: 1 }}>
              <path d="M10.3 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.7 3.86a2 2 0 00-3.4 0z"/>
              <path d="M12 9v4M12 17h.01"/>
            </svg>
            <span>
              <span style={{ color: C.danger, fontWeight: 600 }}>Warning —</span> Konstruct does not store or display the plaintext key after this dialog closes.
            </span>
          </div>
        </div>
      </div>

      {cursorPos.show && <Cursor x={cursorPos.x} y={cursorPos.y} clicking={clicking} />}
    </div>
  );
}

// ─── Scene 5: Use the key (curl + SDK) ────────────────────────────────────
function Scene5() {
  return (
    <Sprite start={19.5} end={27.5}>
      {({ localTime, duration }) => <Scene5Content localTime={localTime} duration={duration} />}
    </Sprite>
  );
}

function Scene5Content({ localTime, duration }) {
  const head = fadeRise(localTime, { inDur: 0.4, outStart: duration - 0.35, outDur: 0.3 });

  // Phase A (0–3.2s): curl
  // Phase B (3.2–8.0s): Backstage SDK integration
  const curlVisible = localTime < 3.4;
  const sdkVisible = localTime >= 3.0;

  const curlIn = fadeRise(Math.max(0, localTime - 0.4), { inDur: 0.5, outStart: 3.0, outDur: 0.4, rise: 10 });
  const sdkIn = fadeRise(Math.max(0, localTime - 3.0), { inDur: 0.5, outStart: duration - 0.4, outDur: 0.35, rise: 14 });

  // curl response type
  const curlT = clamp((localTime - 1.8) / 0.9, 0, 1);

  // SDK code lines reveal progressively
  const sdkStart = 3.4;
  const sdkLine = (n) => clamp((localTime - sdkStart - n * 0.28) / 0.3, 0, 1);

  // Backstage "Catalog" panel renders after SDK call at ~7.0s
  const catalogIn = fadeRise(Math.max(0, localTime - 6.4), { inDur: 0.55, outStart: duration - 0.4, outDur: 0.35, rise: 18 });

  // Headline swaps between phases
  const showCurlHead = localTime < 3.2;

  return (
    <div style={{ position: 'absolute', inset: 0, padding: '120px 80px 70px' }}>
      <div style={{
        opacity: head.opacity,
        transform: `translateY(${head.translateY}px)`,
        marginBottom: 28,
      }}>
        <div style={{
          fontFamily: MONO, fontSize: 13, fontWeight: 600,
          color: C.green, letterSpacing: '0.3px',
          textTransform: 'uppercase', marginBottom: 12,
        }}>Step 3 · Authenticate requests</div>
        <div style={{
          fontFamily: FONT, fontSize: 34, fontWeight: 600,
          color: C.fg1, letterSpacing: '-0.02em',
          lineHeight: 1.15,
          minHeight: 44,
        }}>
          {showCurlHead ? (
            <>Direct HTTP, or use the <span style={{ fontFamily: MONO, color: C.green }}>@konstructio/konstruct-sdk</span>.</>
          ) : (
            <>The SDK plugs straight into a Backstage backend.</>
          )}
        </div>
      </div>

      {/* Phase A: curl — centered, single card */}
      {curlVisible && (
        <div style={{
          maxWidth: 860,
          margin: '0 auto',
          background: C.panel,
          border: `1px solid ${C.border}`,
          borderRadius: 8,
          overflow: 'hidden',
          opacity: curlIn.opacity,
          transform: `translateY(${curlIn.translateY}px)`,
        }}>
          <TerminalHeader label="$ curl" accent={C.green}/>
          <div style={{ padding: '18px 20px', fontFamily: MONO, fontSize: 14, lineHeight: 1.7 }}>
            <Line>
              <TokKw>export</TokKw> KONSTRUCT_API_KEY=<TokStr>"konst_api_…"</TokStr>
            </Line>
            <Line>&nbsp;</Line>
            <Line>
              <span style={{ color: C.green }}>curl</span> -H <TokStr>"Authorization: Bearer $KONSTRUCT_API_KEY"</TokStr> \
            </Line>
            <Line indent>
              https://&lt;your-konstruct-host&gt;/api/v1/<TokProp>health</TokProp>
            </Line>
            {curlT > 0 && (
              <>
                <Line>&nbsp;</Line>
                <Line>
                  <span style={{ color: C.fg4 }}>↳ </span>
                  <TokStr style={{ color: C.success }}>{'{"status":"ok"}'.slice(0, Math.floor(curlT * 15))}</TokStr>
                </Line>
              </>
            )}
          </div>
        </div>
      )}

      {/* Phase B: Backstage SDK integration */}
      {sdkVisible && (
        <div style={{
          display: 'grid',
          gridTemplateColumns: '1.25fr 1fr',
          gap: 20,
          alignItems: 'stretch',
          opacity: sdkIn.opacity,
          transform: `translateY(${sdkIn.translateY}px)`,
        }}>
          {/* Code: Backstage backend plugin */}
          <div style={{
            background: C.panel,
            border: `1px solid ${C.border}`,
            borderRadius: 8,
            overflow: 'hidden',
          }}>
            <TerminalHeader label="plugins/konstruct-backend/src/service/router.ts" accent={C.info}/>
            <div style={{ padding: '16px 20px 18px', fontFamily: MONO, fontSize: 13, lineHeight: 1.65 }}>
              {sdkLine(0) > 0 && <Line>
                <TokKw>import</TokKw> {'{ '}<TokProp>KonstructClient</TokProp>{' }'} <TokKw>from</TokKw> <TokStr>'@konstructio/konstruct-sdk'</TokStr>;
              </Line>}
              {sdkLine(1) > 0 && <Line>
                <TokKw>import</TokKw> {'{ '}<TokProp>createRouter</TokProp>{' }'} <TokKw>from</TokKw> <TokStr>'@backstage/backend-plugin-api'</TokStr>;
              </Line>}
              {sdkLine(2) > 0 && <Line>&nbsp;</Line>}
              {sdkLine(2) > 0 && <Line>
                <TokKw>export async function</TokKw> <span style={{ color: C.green }}>createKonstructRouter</span>({'{ '}<TokProp>config</TokProp>, <TokProp>logger</TokProp>{' }'}) {'{'}
              </Line>}
              {sdkLine(3) > 0 && <Line indent>
                <TokKw>const</TokKw> client = <TokKw>new</TokKw> <span style={{ color: C.fg1 }}>KonstructClient</span>({'{'}
              </Line>}
              {sdkLine(4) > 0 && <Line indent>
                &nbsp;&nbsp;<TokProp>apiUrl</TokProp>: config.<span style={{ color: C.green }}>getString</span>(<TokStr>'konstruct.apiUrl'</TokStr>),
              </Line>}
              {sdkLine(5) > 0 && <Line indent>
                &nbsp;&nbsp;<TokProp>apiToken</TokProp>: config.<span style={{ color: C.green }}>getString</span>(<TokStr>'konstruct.apiToken'</TokStr>),
              </Line>}
              {sdkLine(6) > 0 && <Line indent>{'});'}</Line>}
              {sdkLine(7) > 0 && <Line>&nbsp;</Line>}
              {sdkLine(7) > 0 && <Line indent>
                <TokKw>const</TokKw> router = <span style={{ color: C.green }}>createRouter</span>();
              </Line>}
              {sdkLine(8) > 0 && <Line indent>
                router.<span style={{ color: C.green }}>get</span>(<TokStr>'/clusters'</TokStr>, <TokKw>async</TokKw> (_req, res) {'=> {'}
              </Line>}
              {sdkLine(9) > 0 && <Line indent>
                &nbsp;&nbsp;<TokKw>const</TokKw> clusters = <TokKw>await</TokKw> client.<TokProp>clusters</TokProp>.<span style={{ color: C.green }}>list</span>();
              </Line>}
              {sdkLine(10) > 0 && <Line indent>
                &nbsp;&nbsp;res.<span style={{ color: C.green }}>json</span>(clusters);
              </Line>}
              {sdkLine(11) > 0 && <Line indent>{'});'}</Line>}
              {sdkLine(12) > 0 && <Line indent>
                <TokKw>return</TokKw> router;
              </Line>}
              {sdkLine(13) > 0 && <Line>{'}'}</Line>}
            </div>
          </div>

          {/* Right column: app-config + Backstage catalog card */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            {/* app-config */}
            <div style={{
              background: C.panel,
              border: `1px solid ${C.border}`,
              borderRadius: 8,
              overflow: 'hidden',
            }}>
              <TerminalHeader label="app-config.yaml" accent={C.fg3}/>
              <div style={{ padding: '14px 18px', fontFamily: MONO, fontSize: 12.5, lineHeight: 1.7 }}>
                <Line><TokProp>konstruct</TokProp>:</Line>
                <Line>&nbsp;&nbsp;<TokProp>apiUrl</TokProp>: <TokStr>https://konstruct.example.io</TokStr></Line>
                <Line>&nbsp;&nbsp;<TokProp>apiToken</TokProp>: <TokStr>${'{KONSTRUCT_API_KEY}'}</TokStr></Line>
              </div>
            </div>

            {/* Backstage catalog card result */}
            <div style={{
              flex: 1,
              background: '#fff',
              borderRadius: 8,
              overflow: 'hidden',
              position: 'relative',
              border: '1px solid #e5e7eb',
              opacity: catalogIn.opacity,
              transform: `translateY(${catalogIn.translateY}px)`,
            }}>
              {/* Backstage-style top bar */}
              <div style={{
                display: 'flex', alignItems: 'center', gap: 10,
                padding: '10px 16px',
                background: '#171D24',
                color: '#fff',
                fontFamily: FONT, fontSize: 12, fontWeight: 500,
                letterSpacing: '0.3px',
              }}>
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9BF0E1" strokeWidth="2">
                  <path d="M3 9l9-6 9 6v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/>
                </svg>
                Backstage · Software Catalog
              </div>
              <div style={{ padding: '14px 16px' }}>
                <div style={{
                  fontFamily: FONT, fontSize: 11, fontWeight: 600,
                  color: '#6a7282', letterSpacing: '0.3px',
                  textTransform: 'uppercase', marginBottom: 6,
                }}>Konstruct clusters</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                  {[
                    { name: 'prod-eu-west-1', status: 'Healthy', color: '#00a63e' },
                    { name: 'prod-us-east-2', status: 'Healthy', color: '#00a63e' },
                    { name: 'staging-eu', status: 'Degraded', color: '#e17100' },
                  ].map((c, i) => (
                    <div key={c.name} style={{
                      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                      padding: '8px 10px',
                      background: '#f8fafc',
                      border: '1px solid #e5e7eb',
                      borderRadius: 4,
                      fontFamily: FONT, fontSize: 13, color: '#101828',
                    }}>
                      <span style={{ fontFamily: MONO, fontWeight: 500 }}>{c.name}</span>
                      <span style={{
                        display: 'inline-flex', alignItems: 'center', gap: 6,
                        fontSize: 12, fontWeight: 600, color: c.color,
                      }}>
                        <span style={{ width: 6, height: 6, borderRadius: '50%', background: c.color }}/>
                        {c.status}
                      </span>
                    </div>
                  ))}
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function TerminalHeader({ label, accent }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 8,
      padding: '10px 16px',
      background: C.raised,
      borderBottom: `1px solid ${C.border}`,
      fontFamily: MONO, fontSize: 12, fontWeight: 500,
      color: C.fg2, letterSpacing: '0.3px',
    }}>
      <div style={{ width: 8, height: 8, borderRadius: '50%', background: accent }}/>
      {label}
    </div>
  );
}
function Line({ children, indent }) {
  return (
    <div style={{ paddingLeft: indent ? 24 : 0, color: C.fg1, whiteSpace: 'nowrap', overflow: 'hidden' }}>
      {children}
    </div>
  );
}
const TokKw = ({ children }) => <span style={{ color: '#c27aff' }}>{children}</span>;
const TokStr = ({ children, style }) => <span style={{ color: C.green, ...style }}>{children}</span>;
const TokProp = ({ children }) => <span style={{ color: C.info }}>{children}</span>;

// ─── Scene 6: Usage + revoke ──────────────────────────────────────────────
function Scene6() {
  return (
    <Sprite start={27.5} end={32.5}>
      {({ localTime, duration }) => <Scene6Content localTime={localTime} duration={duration} />}
    </Sprite>
  );
}

function Scene6Content({ localTime, duration }) {
  const head = fadeRise(localTime, { inDur: 0.4, outStart: duration - 0.35, outDur: 0.3 });
  const list = fadeRise(Math.max(0, localTime - 0.4), { inDur: 0.5, outStart: duration - 0.35, outDur: 0.3 });

  // Rows pulse as activity; then delete click at ~3.0s → row flashes red → disappears
  const deleting = localTime > 3.0 && localTime < 3.5;
  const deleted = localTime > 3.5;

  // "401 Unauthorized" toast after delete
  const toast = fadeRise(Math.max(0, localTime - 3.7), { inDur: 0.4, outStart: duration - 0.4, outDur: 0.3, rise: 20 });

  return (
    <div style={{ position: 'absolute', inset: 0, padding: '120px 80px 80px' }}>
      <div style={{
        opacity: head.opacity,
        transform: `translateY(${head.translateY}px)`,
        marginBottom: 28,
        display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between',
      }}>
        <div>
          <div style={{
            fontFamily: MONO, fontSize: 13, fontWeight: 600,
            color: C.green, letterSpacing: '0.3px',
            textTransform: 'uppercase', marginBottom: 12,
          }}>Manage keys</div>
          <div style={{
            fontFamily: FONT, fontSize: 36, fontWeight: 600,
            color: C.fg1, letterSpacing: '-0.02em',
            lineHeight: 1.1,
          }}>
            Review activity. Delete to revoke.
          </div>
        </div>
        <div style={{
          fontFamily: FONT, fontSize: 14, color: C.fg3,
          textAlign: 'right', maxWidth: 340,
        }}>
          The key list shows type, role, expiry, and recent usage.<br/>Deletion revokes the key immediately.
        </div>
      </div>

      {/* Table */}
      <div style={{
        background: C.panel,
        border: `1px solid ${C.border}`,
        borderRadius: 8,
        overflow: 'hidden',
        opacity: list.opacity,
        transform: `translateY(${list.translateY}px)`,
      }}>
        {/* Header row */}
        <div style={{
          display: 'grid',
          gridTemplateColumns: '1.6fr 1fr 0.7fr 1fr 100px',
          gap: 16,
          padding: '14px 20px',
          background: C.raised,
          borderBottom: `1px solid ${C.border}`,
          fontFamily: FONT, fontSize: 11, fontWeight: 600,
          color: C.fg3, letterSpacing: '0.4px',
          textTransform: 'uppercase',
        }}>
          <div>Name</div>
          <div>Type</div>
          <div>Role</div>
          <div>Expires</div>
          <div style={{ textAlign: 'right' }}>Actions</div>
        </div>

        <KeyRow
          name="pipeline-api-key"
          type="API key"
          role="Developer"
          expires="in 30 days"
          active={localTime > 0.8 && localTime < 2.5}
          deleting={deleting}
          deleted={deleted}
          highlighted
        />
        <KeyRow name="ci-deploy-bot" type="API key" role="Developer" expires="in 12 days" active={localTime > 1.1 && localTime < 1.8} />
        <KeyRow name="claude-code-mcp" type="MCP key" role="Team Admin" expires="in 7 days" active={localTime > 1.5 && localTime < 2.2} accent={C.info} />
        <KeyRow name="nightly-backup" type="API key" role="Developer" expires="in 21 days" />
      </div>

      {/* 401 Toast */}
      {localTime > 3.7 && (
        <div style={{
          position: 'absolute',
          right: 80, bottom: 80,
          width: 320,
          background: C.panel,
          border: `1px solid ${C.danger}`,
          borderRadius: 6,
          padding: '14px 16px',
          display: 'flex', gap: 12,
          alignItems: 'flex-start',
          boxShadow: '0 12px 32px rgba(0,0,0,0.5)',
          opacity: toast.opacity,
          transform: `translateY(${toast.translateY}px)`,
        }}>
          <div style={{
            width: 28, height: 28, borderRadius: 4,
            background: 'rgba(251,44,55,0.15)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            flexShrink: 0,
          }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={C.danger} strokeWidth="2.5">
              <path d="M18 6L6 18M6 6l12 12" strokeLinecap="round"/>
            </svg>
          </div>
          <div>
            <div style={{
              fontFamily: MONO, fontSize: 13, fontWeight: 600,
              color: C.danger, marginBottom: 4,
            }}>401 Unauthorized</div>
            <div style={{
              fontFamily: FONT, fontSize: 13, color: C.fg3, lineHeight: 1.4,
            }}>
              Subsequent requests using the deleted key are rejected.
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function KeyRow({ name, type, role, expires, active, deleting, deleted, highlighted, accent }) {
  const typeAccent = accent || (type === 'MCP key' ? C.info : C.green);
  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: '1.6fr 1fr 0.7fr 1fr 100px',
      gap: 16,
      padding: '16px 20px',
      borderBottom: `1px solid ${C.border}`,
      background: deleting ? 'rgba(251,44,55,0.12)' : 'transparent',
      alignItems: 'center',
      fontFamily: FONT, fontSize: 14, color: C.fg2,
      opacity: deleted ? 0.15 : 1,
      transform: deleted ? 'translateX(-8px)' : 'translateX(0)',
      textDecoration: deleted ? 'line-through' : 'none',
      transition: 'all 300ms',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 8, height: 8, borderRadius: '50%',
          background: active ? C.success : C.fg4,
          boxShadow: active ? `0 0 8px ${C.success}` : 'none',
          transition: 'all 150ms',
        }}/>
        <span style={{ fontFamily: MONO, color: C.fg1, fontWeight: 500 }}>{name}</span>
      </div>
      <div>
        <span style={{
          display: 'inline-block',
          padding: '3px 10px',
          background: `${typeAccent}20`,
          border: `1px solid ${typeAccent}`,
          borderRadius: 4,
          color: typeAccent,
          fontFamily: FONT, fontSize: 12, fontWeight: 600,
        }}>{type}</span>
      </div>
      <div style={{ fontSize: 13, color: C.fg3 }}>{role}</div>
      <div style={{ fontSize: 13, color: C.fg3, fontFamily: MONO }}>{expires}</div>
      <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
        <IconBtn active={active} color={C.fg3}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M22 12h-4l-3 9L9 3l-3 9H2"/>
          </svg>
        </IconBtn>
        <IconBtn active={highlighted && deleting} color={highlighted ? C.danger : C.fg3}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6"/>
          </svg>
        </IconBtn>
      </div>
    </div>
  );
}

function IconBtn({ children, active, color }) {
  return (
    <div style={{
      width: 28, height: 28,
      border: `1px solid ${active ? color : C.border}`,
      background: active ? `${color}20` : 'transparent',
      borderRadius: 4,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      color,
      transition: 'all 150ms',
    }}>{children}</div>
  );
}

// ─── Root scene ───────────────────────────────────────────────────────────
function App() {
  return (
    <>
      <Chrome />
      <Scene1 />
      <Scene2 />
      <Scene3 />
      <Scene4 />
      <Scene5 />
      <Scene6 />
    </>
  );
}

window.App = App;
