import type { ReactNode } from 'react';
import { interpolate } from 'remotion';
import { C } from '../lib/colors';
import { springIn, softSpring, clampLerp } from '../lib/easings';

// FloatingChaos overlay — see definition at the bottom of this file. Adds
// real plumbing-pain to the tangle phase: code-snippet cards, an env file
// with a leaked-secret squiggle, and a 502 retry toast. Without it the
// "tangle" reads as four icons drifting; with it the tangle reads as a
// developer's actual desktop right before they give up. Fades out during
// the resolve phase so the clean row at the end isn't competing for eye.

// Phase 1 (frames 0–360 global → localFrame 0..360): the "problem" scene.
//
// Four floating mini-icons (hosting / OAuth / Docker / secrets) drift into the
// frame from corners and slowly tangle together with dotted lines forming
// a mess. A small "the plumbing" label fades in. In the last ~1.5s the mess
// RESOLVES: icons snap into a clean horizontal row and a fifth icon (the
// "prompt cursor") slides in from the right — foreshadowing PromptScene.
//
// Typography monospace, indigo + fg-muted. No flashy gradients.

interface Icon {
  id: string;
  label: string;
  start: { x: number; y: number };
  tangle: { x: number; y: number };
  resolved: { x: number; y: number };
  draw: (color: string) => ReactNode;
}

// Resolved row centered at y=540, evenly spaced.
const ROW_Y = 540;
const ROW_CENTER_X = 1920 / 2;
const RESOLVED_SPACING = 230;
const RESOLVED_OFFSETS = [-1.5, -0.5, 0.5, 1.5];

const ICONS: Icon[] = [
  {
    id: 'hosting',
    label: 'hosting',
    start: { x: 360, y: 220 },
    tangle: { x: 760, y: 420 },
    resolved: { x: ROW_CENTER_X + RESOLVED_OFFSETS[0] * RESOLVED_SPACING, y: ROW_Y },
    draw: (color) => <ServerStackIcon color={color} />,
  },
  {
    id: 'oauth',
    label: 'OAuth',
    start: { x: 1560, y: 240 },
    tangle: { x: 1100, y: 460 },
    resolved: { x: ROW_CENTER_X + RESOLVED_OFFSETS[1] * RESOLVED_SPACING, y: ROW_Y },
    draw: (color) => <KeyIcon color={color} />,
  },
  {
    id: 'docker',
    label: 'containers',
    start: { x: 380, y: 820 },
    tangle: { x: 840, y: 620 },
    resolved: { x: ROW_CENTER_X + RESOLVED_OFFSETS[2] * RESOLVED_SPACING, y: ROW_Y },
    draw: (color) => <ContainerIcon color={color} />,
  },
  {
    id: 'secrets',
    label: 'secrets',
    start: { x: 1540, y: 820 },
    tangle: { x: 1080, y: 660 },
    resolved: { x: ROW_CENTER_X + RESOLVED_OFFSETS[3] * RESOLVED_SPACING, y: ROW_Y },
    draw: (color) => <LockBigIcon color={color} />,
  },
];

const ICON_SIZE = 96;

// Resolve transition timings (in local frames):
const RESOLVE_START = 300; // 10s
const RESOLVE_END = 345;   // 11.5s — clean row landed
const HANDOFF_START = 330; // prompt-cursor icon slides in from the right
const HANDOFF_END = 358;

export function HookScene({ localFrame, fps }: { localFrame: number; fps: number }) {
  // Icons enter staggered over the first ~36 frames.
  const iconEntries = ICONS.map((_, i) => springIn(localFrame, fps, 6 + i * 8));

  // Tangle phase: drift from start position toward tangle position between
  // localFrame 60 and 240.
  const tangleProgress = clampLerp(localFrame, 60, 240);

  // Resolve phase: from tangled centroid to clean row.
  const resolveProgress = clampLerp(localFrame, RESOLVE_START, RESOLVE_END);

  // Sub-label "the plumbing nobody talks about" fades in at ~30, fades
  // out at the resolve.
  const labelIn = clampLerp(localFrame, 30, 60);
  const labelOut = 1 - clampLerp(localFrame, RESOLVE_START - 10, RESOLVE_START + 14);
  const labelOpacity = Math.min(labelIn, labelOut);

  // Resolved-row sub-label: monospace, fades in as row settles.
  const rowLabelIn = clampLerp(localFrame, RESOLVE_END - 6, RESOLVE_END + 14);

  // Handoff cursor icon — slides in from the right edge.
  const handoffProgress = clampLerp(localFrame, HANDOFF_START, HANDOFF_END);
  const handoffX = interpolate(handoffProgress, [0, 1], [1920 + 60, ROW_CENTER_X + 2.5 * RESOLVED_SPACING]);

  // Tangle SVG opacity: full while tangled, fades out as resolve happens.
  const tangleOpacity = Math.min(
    clampLerp(localFrame, 30, 90),
    1 - clampLerp(localFrame, RESOLVE_START - 6, RESOLVE_START + 18),
  );

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      {/* Top label */}
      <div
        style={{
          position: 'absolute',
          top: 140,
          left: 0,
          right: 0,
          textAlign: 'center',
          fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
          fontSize: 18,
          letterSpacing: 6,
          textTransform: 'uppercase',
          color: C.fgSubtle,
          opacity: labelOpacity,
        }}
      >
        the plumbing nobody talks about
      </div>

      {/* Resolved-row label, appears when icons land in clean row */}
      <div
        style={{
          position: 'absolute',
          top: ROW_Y - 110,
          left: 0,
          right: 0,
          textAlign: 'center',
          fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
          fontSize: 16,
          letterSpacing: 5,
          textTransform: 'uppercase',
          color: C.fgSubtle,
          opacity: rowLabelIn,
          transform: `translateY(${interpolate(rowLabelIn, [0, 1], [6, 0])}px)`,
        }}
      >
        what if one prompt handled all of it
      </div>

      {/* Floating chaos — code-snippet cards + 502 toast + env warning.
          Sits behind the icons, behind the tangle lines. Their entrance
          is staggered across frames 80–200 so the tangle grows in
          visible complexity rather than just sitting at peak. */}
      <FloatingChaos localFrame={localFrame} />

      {/* Tangle SVG (dotted lines between icons) */}
      <TangleLines
        icons={ICONS}
        tangleProgress={tangleProgress}
        opacity={tangleOpacity}
      />

      {/* Icons themselves */}
      {ICONS.map((icon, i) => {
        const entry = iconEntries[i];
        // Position interpolation: start → tangle → resolved.
        const sx = icon.start.x;
        const sy = icon.start.y;
        const tx = icon.tangle.x;
        const ty = icon.tangle.y;
        const rx = icon.resolved.x;
        const ry = icon.resolved.y;

        // Three-stage lerp.
        let x: number;
        let y: number;
        if (resolveProgress > 0) {
          x = interpolate(resolveProgress, [0, 1], [tx, rx]);
          y = interpolate(resolveProgress, [0, 1], [ty, ry]);
        } else {
          x = interpolate(tangleProgress, [0, 1], [sx, tx]);
          y = interpolate(tangleProgress, [0, 1], [sy, ty]);
        }

        // Subtle floating drift while tangled.
        const driftPhase = (localFrame + i * 12) / 30;
        const driftX = tangleProgress > 0.4 && resolveProgress < 0.1
          ? Math.sin(driftPhase * Math.PI) * 8
          : 0;
        const driftY = tangleProgress > 0.4 && resolveProgress < 0.1
          ? Math.cos(driftPhase * Math.PI * 0.8) * 8
          : 0;

        const scale = interpolate(entry, [0, 1], [0.6, 1]);
        const opacity = entry;

        // Icon color: muted during tangle, then accent on resolve.
        const iconColor =
          resolveProgress > 0.4 ? C.accent : C.fgMuted;

        return (
          <div
            key={icon.id}
            style={{
              position: 'absolute',
              left: x + driftX - ICON_SIZE / 2,
              top: y + driftY - ICON_SIZE / 2,
              width: ICON_SIZE,
              height: ICON_SIZE,
              opacity,
              transform: `scale(${scale})`,
              transformOrigin: 'center center',
              transition: 'none',
            }}
          >
            <IconCard color={iconColor}>
              {icon.draw(iconColor)}
            </IconCard>
            {/* Label below */}
            <div
              style={{
                position: 'absolute',
                top: ICON_SIZE + 8,
                left: 0,
                right: 0,
                textAlign: 'center',
                fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
                fontSize: 12,
                letterSpacing: 2,
                textTransform: 'uppercase',
                color: resolveProgress > 0.5 ? C.fgMuted : C.fgSubtle,
              }}
            >
              {icon.label}
            </div>
          </div>
        );
      })}

      {/* Hand-off cursor icon — slides in from the right at the end */}
      {handoffProgress > 0.02 && (
        <div
          style={{
            position: 'absolute',
            left: handoffX - ICON_SIZE / 2,
            top: ROW_Y - ICON_SIZE / 2,
            width: ICON_SIZE,
            height: ICON_SIZE,
            opacity: handoffProgress,
          }}
        >
          <IconCard color={C.accent} glow>
            <PromptCursorIcon color={C.accent} />
          </IconCard>
          <div
            style={{
              position: 'absolute',
              top: ICON_SIZE + 8,
              left: 0,
              right: 0,
              textAlign: 'center',
              fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
              fontSize: 12,
              letterSpacing: 2,
              textTransform: 'uppercase',
              color: C.accent,
            }}
          >
            one prompt
          </div>
        </div>
      )}
    </div>
  );
}

function IconCard({ children, color, glow }: { children: React.ReactNode; color: string; glow?: boolean }) {
  return (
    <div
      style={{
        width: '100%',
        height: '100%',
        borderRadius: 18,
        backgroundColor: C.bgElevated,
        border: `1.5px solid ${color === C.accent ? C.accent : C.borderStrong}`,
        boxShadow: glow
          ? `0 0 0 4px ${C.accentGlow}, 0 14px 40px rgba(0,0,0,0.55)`
          : `0 10px 30px rgba(0,0,0,0.5)`,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
      }}
    >
      {children}
    </div>
  );
}

function TangleLines({
  icons,
  tangleProgress,
  opacity,
}: {
  icons: Icon[];
  tangleProgress: number;
  opacity: number;
}) {
  if (opacity < 0.01) return null;
  // Draw dotted lines between every pair of icons at their tangle positions.
  // Reveal via strokeDashoffset as tangleProgress grows.
  const pairs: Array<[Icon, Icon]> = [];
  for (let i = 0; i < icons.length; i++) {
    for (let j = i + 1; j < icons.length; j++) {
      pairs.push([icons[i], icons[j]]);
    }
  }
  return (
    <svg
      width={1920}
      height={1080}
      style={{ position: 'absolute', inset: 0, pointerEvents: 'none', opacity }}
    >
      {pairs.map(([a, b], i) => {
        // Interpolate endpoints between start and tangle positions.
        const ax = interpolate(tangleProgress, [0, 1], [a.start.x, a.tangle.x]);
        const ay = interpolate(tangleProgress, [0, 1], [a.start.y, a.tangle.y]);
        const bx = interpolate(tangleProgress, [0, 1], [b.start.x, b.tangle.x]);
        const by = interpolate(tangleProgress, [0, 1], [b.start.y, b.tangle.y]);
        const len = Math.hypot(bx - ax, by - ay);
        const reveal = clampLerp(tangleProgress, 0.2 + i * 0.05, 0.6 + i * 0.05);
        return (
          <line
            key={i}
            x1={ax}
            y1={ay}
            x2={bx}
            y2={by}
            stroke={C.fgSubtle}
            strokeWidth={1.5}
            strokeDasharray="4 7"
            strokeDashoffset={(1 - reveal) * len}
            opacity={0.55}
          />
        );
      })}
    </svg>
  );
}

// ---- Icons ----

function ServerStackIcon({ color }: { color: string }) {
  return (
    <svg width="48" height="48" viewBox="0 0 48 48" fill="none">
      <rect x="8" y="10" width="32" height="9" rx="2" stroke={color} strokeWidth={2} fill="rgba(99,102,241,0.08)" />
      <rect x="8" y="22" width="32" height="9" rx="2" stroke={color} strokeWidth={2} fill="rgba(99,102,241,0.08)" />
      <rect x="8" y="34" width="32" height="9" rx="2" stroke={color} strokeWidth={2} fill="rgba(99,102,241,0.08)" />
      <circle cx="12" cy="14.5" r="1.2" fill={color} />
      <circle cx="12" cy="26.5" r="1.2" fill={color} />
      <circle cx="12" cy="38.5" r="1.2" fill={color} />
    </svg>
  );
}

function KeyIcon({ color }: { color: string }) {
  return (
    <svg width="48" height="48" viewBox="0 0 48 48" fill="none">
      <circle cx="17" cy="24" r="9" stroke={color} strokeWidth={2.2} fill="rgba(99,102,241,0.08)" />
      <circle cx="17" cy="24" r="3" fill={color} />
      <path d="M 26 24 L 42 24 M 38 24 L 38 31 M 34 24 L 34 29" stroke={color} strokeWidth={2.2} strokeLinecap="round" />
    </svg>
  );
}

function ContainerIcon({ color }: { color: string }) {
  return (
    <svg width="48" height="48" viewBox="0 0 48 48" fill="none">
      <rect x="6" y="22" width="9" height="9" rx="1" stroke={color} strokeWidth={2} fill="rgba(99,102,241,0.08)" />
      <rect x="17" y="22" width="9" height="9" rx="1" stroke={color} strokeWidth={2} fill="rgba(99,102,241,0.08)" />
      <rect x="28" y="22" width="9" height="9" rx="1" stroke={color} strokeWidth={2} fill="rgba(99,102,241,0.08)" />
      <rect x="17" y="11" width="9" height="9" rx="1" stroke={color} strokeWidth={2} fill="rgba(99,102,241,0.08)" />
      <path d="M 4 36 Q 24 42 44 36" stroke={color} strokeWidth={2} fill="none" strokeLinecap="round" />
    </svg>
  );
}

function LockBigIcon({ color }: { color: string }) {
  return (
    <svg width="48" height="48" viewBox="0 0 48 48" fill="none">
      <path d="M 15 22 L 15 15 A 9 9 0 0 1 33 15 L 33 22" stroke={color} strokeWidth={2.2} fill="none" />
      <rect x="11" y="22" width="26" height="18" rx="3" stroke={color} strokeWidth={2.2} fill="rgba(99,102,241,0.10)" />
      <circle cx="24" cy="30" r="2.2" fill={color} />
      <rect x="23" y="31" width="2" height="5" fill={color} />
    </svg>
  );
}

function PromptCursorIcon({ color }: { color: string }) {
  return (
    <svg width="48" height="48" viewBox="0 0 48 48" fill="none">
      <rect x="8" y="18" width="32" height="14" rx="3" stroke={color} strokeWidth={2} fill="rgba(99,102,241,0.10)" />
      <text x="13" y="29" fill={color} fontSize="11" fontFamily="ui-monospace, SF Mono, Menlo, monospace" letterSpacing="1">›</text>
      <rect x="20" y="22" width="2" height="6" fill={color} />
    </svg>
  );
}

// =============== FloatingChaos ====================================
// Renders four small "fragment" cards during the tangle phase. Each one
// makes the chaos concrete instead of abstract: real config snippets,
// a real-looking error toast, a real env file with a security squiggle.
// Together they sell the "tagelange Bastelei" reality the rest of the
// scene only gestures at.
//
// Timing:
//   Each card has a personal `appearAt` frame, spring-entrances with a
//   slight rotation. During the hold (frames 240–270) they jitter ±2px
//   so the layout doesn't feel frozen. From frame 280 they collapse —
//   scale to 0.85, translate inward toward the icon row, fade out, so
//   the resolve reads as "the chaos folds into the clean answer."
//
// Layout: four corners of the canvas, each card sized < 380px so they
// frame the centre tangle without crowding the icons.

interface ChaosCard {
  id: string;
  appearAt: number;
  x: number;
  y: number;
  rotate: number; // degrees
  render: () => ReactNode;
}

const CHAOS_HOLD_START = 240;
const CHAOS_RESOLVE_START = 280;
const CHAOS_RESOLVE_END = 315;

function FloatingChaos({ localFrame }: { localFrame: number }) {
  // Collapse alpha + collapse-toward-centre during resolve.
  const collapse = clampLerp(localFrame, CHAOS_RESOLVE_START, CHAOS_RESOLVE_END);
  if (collapse >= 0.99) return null;

  const cards: ChaosCard[] = [
    {
      id: 'docker',
      appearAt: 70,
      x: 130,
      y: 360,
      rotate: -3.5,
      render: () => <ConfigCard />,
    },
    {
      id: 'oauth',
      appearAt: 100,
      x: 1450,
      y: 220,
      rotate: 2.4,
      render: () => <OAuthCodeCard />,
    },
    {
      id: 'env',
      appearAt: 135,
      x: 1330,
      y: 740,
      rotate: -2.6,
      render: () => <EnvLeakCard />,
    },
    {
      id: 'error',
      appearAt: 175,
      x: 170,
      y: 750,
      rotate: 3.2,
      render: () => <ErrorToastCard localFrame={localFrame} />,
    },
  ];

  return (
    <div
      style={{
        position: 'absolute',
        inset: 0,
        pointerEvents: 'none',
        opacity: 1 - collapse,
      }}
    >
      {cards.map((card) => {
        // Entrance: scale + opacity ramp over 14 frames.
        const entrance = clampLerp(localFrame, card.appearAt, card.appearAt + 14);
        if (entrance < 0.01) return null;
        const entryScale = interpolate(entrance, [0, 1], [0.85, 1]);
        const entryY = interpolate(entrance, [0, 1], [14, 0]);

        // Hold jitter — keeps the cards alive during the centre tangle
        // hold without making them feel busy. Different phase per card.
        const jitterPhase = (localFrame + card.appearAt * 1.7) / 22;
        const jitterX = Math.sin(jitterPhase * Math.PI) * 1.6;
        const jitterY = Math.cos(jitterPhase * Math.PI * 0.7) * 1.4;

        // Resolve: cards collapse inward toward canvas centre (960, 540)
        // and scale down. By the time the icons settle into their row,
        // the chaos has folded away.
        const collapseScale = interpolate(collapse, [0, 1], [1, 0.7]);
        const collapseDx = interpolate(collapse, [0, 1], [0, (960 - card.x) * 0.35]);
        const collapseDy = interpolate(collapse, [0, 1], [0, (540 - card.y) * 0.35]);

        return (
          <div
            key={card.id}
            style={{
              position: 'absolute',
              left: card.x,
              top: card.y,
              opacity: entrance * (1 - collapse * 0.4),
              transform: `translate(${jitterX + collapseDx}px, ${jitterY + collapseDy + entryY}px) rotate(${card.rotate}deg) scale(${entryScale * collapseScale})`,
              transformOrigin: 'center center',
              filter: collapse > 0.4 ? `blur(${collapse * 1.5}px)` : 'none',
            }}
          >
            {card.render()}
          </div>
        );
      })}
    </div>
  );
}

// ---- Chaos card variants ----

function CardFrame({
  children,
  width,
  label,
  intent = 'neutral',
}: {
  children: ReactNode;
  width: number;
  label?: string;
  intent?: 'neutral' | 'warn' | 'error';
}) {
  const borderColor =
    intent === 'error' ? '#dc2626' : intent === 'warn' ? '#f59e0b' : C.borderStrong;
  return (
    <div
      style={{
        width,
        backgroundColor: C.bgElevated,
        border: `1px solid ${borderColor}`,
        borderRadius: 10,
        boxShadow: '0 16px 36px rgba(0,0,0,0.55)',
        overflow: 'hidden',
      }}
    >
      {label && (
        <div
          style={{
            padding: '8px 14px',
            borderBottom: `1px solid ${C.border}`,
            fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
            fontSize: 10,
            letterSpacing: 2,
            textTransform: 'uppercase',
            color: intent === 'error' ? '#dc2626' : intent === 'warn' ? '#f59e0b' : C.fgSubtle,
          }}
        >
          {label}
        </div>
      )}
      <div style={{ padding: '12px 14px' }}>{children}</div>
    </div>
  );
}

function ConfigCard() {
  return (
    <CardFrame width={340} label="docker-compose.yml">
      <pre
        style={{
          margin: 0,
          fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
          fontSize: 11.5,
          lineHeight: 1.5,
          color: C.fgMuted,
          letterSpacing: 0.1,
        }}
      >
{`services:
  nginx:
    image: nginx:alpine
    ports: ["443:443"]
    volumes:
      - ./certs:/etc/ssl
      - ./conf.d:/etc/nginx`}
      </pre>
    </CardFrame>
  );
}

function OAuthCodeCard() {
  return (
    <CardFrame width={360} label="oauth_callback.ts">
      <pre
        style={{
          margin: 0,
          fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
          fontSize: 11.5,
          lineHeight: 1.5,
          color: C.fgMuted,
          letterSpacing: 0.1,
        }}
      >
{`app.use(passport.authenticate(
  'oauth2', {
    clientID: process.env.CID,
    clientSecret: process.env.CS,
    callbackURL: '/cb',
  }
));`}
      </pre>
    </CardFrame>
  );
}

function EnvLeakCard() {
  // The squiggle hints at "this got committed to git by accident" —
  // a recognisable plumbing failure mode.
  return (
    <CardFrame width={320} label="// .env" intent="warn">
      <div
        style={{
          fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
          fontSize: 12,
          lineHeight: 1.55,
          color: C.fgMuted,
        }}
      >
        <div>STRIPE_KEY=sk_live_•••</div>
        <div style={{ position: 'relative', display: 'inline-block' }}>
          NOTION_API_KEY=secret_3a8f
          <svg
            width="170"
            height="6"
            viewBox="0 0 170 6"
            style={{ position: 'absolute', left: 0, bottom: -3, pointerEvents: 'none' }}
          >
            <path
              d="M 0 3 Q 4 0 8 3 T 16 3 T 24 3 T 32 3 T 40 3 T 48 3 T 56 3 T 64 3 T 72 3 T 80 3 T 88 3 T 96 3 T 104 3 T 112 3 T 120 3 T 128 3 T 136 3 T 144 3 T 152 3 T 160 3 T 168 3"
              stroke="#f59e0b"
              strokeWidth="1.2"
              fill="none"
            />
          </svg>
        </div>
        <div style={{ color: '#f59e0b', fontSize: 10.5, marginTop: 8, letterSpacing: 0.4 }}>
          ⚠  in git history since v0.3.1
        </div>
      </div>
    </CardFrame>
  );
}

function ErrorToastCard({ localFrame }: { localFrame: number }) {
  // The retry counter ticks while the card is visible — keeps the
  // "still broken" feeling alive across the hold without changing the
  // overall composition.
  const elapsedSecs = Math.floor((localFrame - 175) / 30);
  const retries = Math.max(1, Math.min(8, Math.floor(elapsedSecs / 1) + 1));

  return (
    <CardFrame width={320} intent="error">
      <div
        style={{
          display: 'flex',
          alignItems: 'flex-start',
          gap: 10,
        }}
      >
        <div
          style={{
            width: 22,
            height: 22,
            borderRadius: 11,
            backgroundColor: 'rgba(220,38,38,0.16)',
            border: '1.5px solid #dc2626',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            flexShrink: 0,
          }}
        >
          <div
            style={{
              fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
              color: '#dc2626',
              fontSize: 14,
              fontWeight: 700,
              lineHeight: 1,
            }}
          >
            !
          </div>
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div
            style={{
              fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
              fontSize: 12.5,
              color: '#dc2626',
              fontWeight: 600,
              letterSpacing: 0.2,
            }}
          >
            502 Bad Gateway
          </div>
          <div
            style={{
              fontFamily: 'ui-monospace, SF Mono, Menlo, monospace',
              fontSize: 11,
              color: C.fgMuted,
              marginTop: 4,
              letterSpacing: 0.2,
            }}
          >
            upstream timed out · retrying ({retries}/8)
          </div>
        </div>
      </div>
    </CardFrame>
  );
}
