/* profile-card.jsx — GitHub Profile Card demo + theme picker */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "blue",
  "mode": "dark",
  "direction": "original",
  "tagline": "v1"
}/*EDITMODE-END*/;

const PROFILE_TWEAKS_STORAGE_KEY = "devis-lab:profile-card:tweaks";
const PROFILE_SITE_URL = "https://devis-lab.pages.dev";

/* Tagline options — tweakable */
const TAGLINES = [
  {
    id: "v1",
    title: "Hi, I’m Devis",
    eyebrow: "DEVIS LAB • OPEN FOR PROJECTS",
    headlineLines: [
      [{ text: "Hi, I’m Devis." }],
      [{ text: "Vibe-coding", accent: true }],
      [{ text: "daily." }],
    ],
    sub: "Building apps, automations and AI-powered tools — weekend by weekend, refined daily.",
  },
  {
    id: "v2",
    title: "My Lab",
    eyebrow: "DEVIS LAB • SMALL LAB",
    headlineLines: [
      [{ text: "Small lab." }],
      [{ text: "Big projects." }],
      [{ text: "Clear signal.", accent: true }],
    ],
    sub: "A compact digital lab for product ideas, brand systems and useful experiments.",
  },
  {
    id: "v3",
    title: "AI Tools",
    eyebrow: "DEVIS LAB • AI TOOLS",
    headlineLines: [
      [{ text: "AI tools.", accent: true }],
      [{ text: "Useful systems." }],
      [{ text: "Less busywork." }],
    ],
    sub: "Assistants, automations and workflows designed to save time and sharpen work.",
  },
  {
    id: "v4",
    title: "Build Loop",
    eyebrow: "DEVIS LAB • BUILD LOOP",
    headlineLines: [
      [{ text: "Build fast." }],
      [{ text: "Test clearly." }],
      [{ text: "Refine daily.", accent: true }],
    ],
    sub: "Small ideas move through a simple loop: prototype, test, polish and ship.",
  },
];

const MOOD_TILES = {
  v1: { label: "Hi, I’m Devis", glyph: "hello" },
  v2: { label: "My Lab", glyph: "lab" },
  v3: { label: "AI Tools", glyph: "power" },
  v4: { label: "Build Loop", glyph: "loop" },
};

/* ──────────────────────────────────────────────────────────────────────
   The Banner Card — the artifact users put on their GitHub README
   ────────────────────────────────────────────────────────────────────── */

const MOBILE_TAGLINES = {
  v1: {
    headlineLines: [
      [{ text: "Hi, I\u2019m Devis." }],
      [{ text: "Vibe-coding daily.", accent: true }],
    ],
    sub: "Apps, automations and AI tools \u2014 refined daily.",
  },
  v2: {
    headlineLines: [
      [{ text: "Small lab." }],
      [{ text: "Big projects.", accent: true }],
    ],
    sub: "A compact lab for product ideas and useful systems.",
  },
  v3: {
    headlineLines: [
      [{ text: "AI tools.", accent: true }],
      [{ text: "Less busywork." }],
    ],
    sub: "Assistants and automations that save time.",
  },
  v4: {
    headlineLines: [
      [{ text: "Build fast." }],
      [{ text: "Refine daily.", accent: true }],
    ],
    sub: "Prototype, test, polish and ship.",
  },
};

function renderStageHeadline(lines) {
  return lines.map((line, lineIndex) => (
    <React.Fragment key={`line-${lineIndex}`}>
      {lineIndex > 0 && <br />}
      {line.map((segment, segmentIndex) => {
        if (segment.accent) {
          return <span className="banner-title-accent" key={`segment-${lineIndex}-${segmentIndex}`}>{segment.text}</span>;
        }
        return <React.Fragment key={`segment-${lineIndex}-${segmentIndex}`}>{segment.text}</React.Fragment>;
      })}
    </React.Fragment>
  ));
}

function BannerCard({ direction, tagline, compact = false, surface = "dark", themeId = "blue", onMood = null, pulseToken = null }) {
  const t = TAGLINES.find(x => x.id === tagline) || TAGLINES[0];
  const headlineLines = t.headlineLines || TAGLINES[0].headlineLines;
  const bodyCopy = t.sub;
  const mobileCopy = MOBILE_TAGLINES[t.id] || MOBILE_TAGLINES.v1;

  return (
    <div className={"banner " + surface + (compact ? " compact" : "")} data-direction={direction}>
      <div className="banner-inner">
        <div className="banner-left">
          <div className="banner-mark stable-preview">
            {compact
              ? (() => {
                  const Logo = LOGO_DIRECTIONS.find(d => d.id === direction)?.Component || LogoOriginal;
                  return (
                    <Logo
                      size={120}
                      context="asset"
                      displayMode="clean"
                      surface={surface}
                      signalCore={direction === "pixel" ? "pixel" : direction === "monochrome" ? "mono" : "default"}
                    />
                  );
                })()
              : <AnimatedLogoSwitch direction={direction} themeId={themeId} surface={surface} sizeVar="100%" className="banner-logo-switch" pulseToken={pulseToken} context="asset" displayMode="clean" signalCore="default" />}
          </div>
        </div>

        <div className="banner-right">
          <div className="banner-eyebrow stable-eyebrow">
            <span className="pulse" />
            {t.eyebrow}
          </div>

          <AnimatedTextSlot
            as="h1"
            tokenKey={t.id}
            className="banner-title stable-headline"
            variant="headline"
          >
            {renderStageHeadline(headlineLines)}
          </AnimatedTextSlot>

          <AnimatedTextSlot
            as="p"
            tokenKey={t.id}
            className="banner-sub stable-body"
            variant="body"
            value={bodyCopy}
          />
          <h1 className="banner-title banner-title-mobile">
            {renderStageHeadline(mobileCopy.headlineLines)}
          </h1>
          <p className="banner-sub banner-sub-mobile">{mobileCopy.sub}</p>

          <div className="banner-chips stable-controls identity-stage__mood-dock" role="radiogroup" aria-label="Banner mood">
            {TAGLINES.map((tl) => {
              const mood = MOOD_TILES[tl.id] || { label: tl.id.toUpperCase() };
              const active = tl.id === t.id;
              return (
                <button
                  key={tl.id}
                  type="button"
                  className={"banner-chip" + (active ? " active" : "")}
                  aria-pressed={active}
                  aria-label={`Use ${mood.label} mood`}
                  onClick={() => onMood?.(tl.id)}
                  disabled={!onMood}
                >
                  {mood.label}
                </button>
              );
            })}
          </div>

          <div className="banner-foot stable-meta">
            <div className="now">
              <Sparkle size={11} color="var(--accent-1)" />
              Status: <b>Open for projects</b>
            </div>
            <a href="#">github.com/Devis-Lab</a>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ──────────────────────────────────────────────────────────────────────
   Standalone theme application — for the variant gallery cards where
   each card has its own theme regardless of global setting.
   ────────────────────────────────────────────────────────────────────── */

function ThemedBanner({ themeId, direction, tagline, compact = false, dark = true }) {
  const theme = getTheme(themeId);
  const style = {
    "--accent-1": theme.c1,
    "--accent-2": theme.c2,
    "--accent-3": theme.c3,
    "--logo-cyan": theme.logoCyan,
    "--logo-accent": theme.logoAccent,
    "--logo-end": theme.logoEnd,
    "--logo-sparkle": theme.logoSparkle,
    "--wordmark-dot": theme.logoSparkleStrong,
    "--wordmark-lab-start": theme.logoCyan,
    "--wordmark-lab-mid": theme.logoAccent,
    "--wordmark-lab-end": theme.logoEnd,
    "--pixel-theme-tint": theme.logoSparkleStrong,
    "--pixel-base-1": theme.pixelBase1 || theme.logoCyan,
    "--pixel-base-2": theme.pixelBase2 || theme.logoAccent,
    "--pixel-base-3": theme.pixelBase3 || theme.logoEnd,
    "--pixel-signal": theme.pixelSignal || "#00F0C8",
    "--pixel-signal-soft": `color-mix(in oklab, ${theme.pixelSignal || "#00F0C8"}, transparent 74%)`,
    "--signal-dot": theme.logoSparkleStrong,
    "--signal-core": theme.logoSparkleStrong,
    "--signal-core-glow": `color-mix(in oklab, ${theme.logoSparkleStrong}, transparent 70%)`,
    "--accent-soft": theme.soft,
    "--accent-ring": theme.ring,
  };
  return (
    <div style={style}>
      <BannerCard direction={direction} tagline={tagline} compact={compact} surface={dark ? "dark" : "light"} themeId={theme.id} pulseToken={theme.id} />
    </div>
  );
}

/* ──────────────────────────────────────────────────────────────────────
   Theme picker bar — visual theme buttons row
   ────────────────────────────────────────────────────────────────────── */

function ThemePickerBar({ themeId, onPick }) {
  return (
    <div className="pc-controls-group accent-control-block">
      <span className="pc-controls-label">Accent color</span>
      {THEMES.map(th => (
        <button
          key={th.id}
          className={"pc-theme-btn" + (themeId === th.id ? " on" : "")}
          aria-label={`Choose ${th.name} theme`}
          aria-pressed={themeId === th.id}
          onClick={() => onPick(th.id)}
        >
          <span
            className="pc-theme-swatch"
            style={{ background: `linear-gradient(135deg, ${th.c1}, ${th.c2} 50%, ${th.c3})` }}
          />
          {th.short}
        </button>
      ))}
    </div>
  );
}

function LogoPickerBar({ direction, onPick }) {
  return (
    <div className="pc-controls-group logo-controls-wide">
      <span className="pc-controls-label">Logo variant</span>
      <div className="logo-mode-row profile-logo-row">
        {LOGO_DIRECTIONS.map(d => {
          const Logo = d.Component;
          const active = direction === d.id;
          return (
            <button
              key={d.id}
              className={"logo-mode-btn" + (active ? " active" : "")}
              aria-label={`Choose ${d.label} logo variant`}
              aria-pressed={active}
              onClick={() => onPick(d.id)}
            >
              <Logo size={28} variant={d.id === "monochrome" ? "mono-current" : "color"} />
              <b>{d.label}</b>
            </button>
          );
        })}
      </div>
    </div>
  );
}

function SurfaceModeBar({ mode, onPick }) {
  return (
    <div className="pc-controls-group surface-control-block">
      <span className="pc-controls-label">Surface / finish</span>
      <div className="profile-surface-row" role="radiogroup" aria-label="Banner surface">
        {[
          { id: "dark", label: "Dark" },
          { id: "light", label: "Light" },
        ].map(surface => (
          <button
            key={surface.id}
            className={"surface-choice " + surface.id + (mode === surface.id ? " on" : "")}
            aria-pressed={mode === surface.id}
            onClick={() => onPick(surface.id)}
          >
            <span />
            {surface.label}
          </button>
        ))}
      </div>
    </div>
  );
}

function IdentityStageSignature({ direction, themeId, mode }) {
  const identity = getIdentityMode(direction);

  return (
    <div className="identity-stage__signature" aria-hidden="true">
      <DevisWordmark
        direction={direction}
        size="lg"
        pulseToken={`${themeId}|${direction}|${mode}`}
      />
      <span>{identity.label}</span>
    </div>
  );
}

function InteractiveIdentityStage({ themeId, direction, mode, tagline, onTheme, onDirection, onMode, onMood }) {
  const theme = getTheme(themeId);

  return (
    <section className="identity-stage" data-surface={mode} aria-label="Interactive Identity Stage">
      <div className="identity-stage__ambient" aria-hidden="true" />
      <div className="identity-stage__chrome">
        <div className="identity-stage__chrome-bar">
          <span>
            <span className="dot-row"><i /><i /><i /></span>
            github.com/Devis-Lab
          </span>
          <span>{theme.short} / {mode}</span>
        </div>

        <div className="identity-stage__preview">
          <BannerCard
            direction={direction}
            tagline={tagline}
            surface={mode}
            themeId={themeId}
            pulseToken={themeId}
            onMood={onMood}
          />
          <IdentityStageSignature direction={direction} themeId={themeId} mode={mode} />
          <div className="identity-stage__overlay" aria-hidden="true">
            <span><i /><i /><i /></span>
          </div>

          <div className="identity-stage__dock" aria-label="Identity controls">
            <div className="identity-stage__logo-dock">
              <LogoPickerBar direction={direction} onPick={onDirection} />
            </div>
            <div className="identity-stage__accent-dock">
              <ThemePickerBar themeId={themeId} onPick={onTheme} />
            </div>
            <div className="identity-stage__surface-dock">
              <SurfaceModeBar mode={mode} onPick={onMode} />
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

function HeaderBrand({ pulseToken }) {
  return (
    <div className="pc-brand-title single">
      <DevisWordmark direction="original" className="pc-brand-text" size="sm" pulseToken={pulseToken} />
    </div>
  );
}

function ThemeSurfaceGallery({ direction, tagline }) {
  return (
    <div className="surface-gallery">
      {THEMES.map(th => (
        <div key={th.id} className="surface-theme-card">
          <div className="surface-theme-head">
            <b>{th.name}</b>
            <span>{th.sub}</span>
          </div>
          <div className="surface-pair">
            <div>
              <span>Dark</span>
              <ThemedBanner themeId={th.id} direction={direction} tagline={tagline} compact dark />
            </div>
            <div>
              <span>Light</span>
              <ThemedBanner themeId={th.id} direction={direction} tagline={tagline} compact dark={false} />
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

/* ──────────────────────────────────────────────────────────────────────
   Markdown / install block
   ────────────────────────────────────────────────────────────────────── */

function ReadmeCode({ themeId, direction }) {
  const theme = getTheme(themeId);
  const md =
`<!-- Devis Lab GitHub profile README -->

[![Devis Lab - digital products, automation and AI-powered tools](./assets/github-banner-${theme.asset}.svg)](${PROFILE_SITE_URL})

<!-- Optional theme tabs -->
<details>
  <summary><b>Switch theme</b> · Blue · Magenta · Green · Sunset · Violet</summary>

  | Blue | Magenta | Green | Sunset | Violet |
  |---|---|---|---|---|
  | ![](./assets/github-banner-blue.svg) | ![](./assets/github-banner-magenta.svg) | ![](./assets/github-banner-green.svg) | ![](./assets/github-banner-sunset.svg) | ![](./assets/github-banner-violet.svg) |

</details>`;

  const [copied, setCopied] = React.useState(false);
  const onCopy = () => {
    navigator.clipboard?.writeText(md);
    setCopied(true);
    setTimeout(() => setCopied(false), 1400);
  };

  /* Lightweight highlight — markdown + HTML mix */
  const lines = md.split("\n").map((line, i) => {
    if (line.trim().startsWith("<!--")) {
      return <div key={i}><span className="tk-cmt">{line}</span></div>;
    }
    /* tag detection */
    const tagged = line
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;");
    return (
      <div key={i}
        dangerouslySetInnerHTML={{ __html: tagged
          .replace(/(&lt;\/?[a-zA-Z][^&]*?&gt;)/g, '<span class="tk-tag">$1</span>')
          .replace(/(\w+)=(&quot;|")/g, '<span class="tk-attr">$1</span>=$2')
          .replace(/("[^"]*")/g, '<span class="tk-str">$1</span>')
        }}
      />
    );
  });

  return (
    <div className="pc-code">
      <button className="pc-code-copy" onClick={onCopy} aria-label="Copy GitHub README Markdown">
        <IconCopy /> {copied ? "Copied" : "Copy Markdown"}
      </button>
      {lines}
    </div>
  );
}

/* Animated banner preview kept for standalone experiments. The shipped README
   assets are static SVG files generated in assets/ and use the clean logo. */

const BANNER_PREVIEW_STYLE = `
@keyframes accent1 {
  0%, 4%   { background-color: #00D4CB; }
  20%, 24% { background-color: #A78BFA; }
  40%, 44% { background-color: #F472B6; }
  60%, 64% { background-color: #FBBF24; }
  80%, 84% { background-color: #34D399; }
  100%     { background-color: #00D4CB; }
}
@keyframes accent2 {
  0%, 4%   { background-color: #2563EB; }
  20%, 24% { background-color: #7C3AED; }
  40%, 44% { background-color: #DB2777; }
  60%, 64% { background-color: #F97316; }
  80%, 84% { background-color: #10B981; }
  100%     { background-color: #2563EB; }
}
@keyframes accent3 {
  0%, 4%   { background-color: #7C3AED; }
  20%, 24% { background-color: #5B21B6; }
  40%, 44% { background-color: #9D174D; }
  60%, 64% { background-color: #DC2626; }
  80%, 84% { background-color: #047857; }
  100%     { background-color: #7C3AED; }
}
@keyframes accentGrad {
  0%, 4%   { background: linear-gradient(120deg, #00D4CB, #2563EB 50%, #7C3AED); }
  20%, 24% { background: linear-gradient(120deg, #A78BFA, #7C3AED 50%, #5B21B6); }
  40%, 44% { background: linear-gradient(120deg, #F472B6, #DB2777 50%, #9D174D); }
  60%, 64% { background: linear-gradient(120deg, #FBBF24, #F97316 50%, #DC2626); }
  80%, 84% { background: linear-gradient(120deg, #34D399, #10B981 50%, #047857); }
  100%     { background: linear-gradient(120deg, #00D4CB, #2563EB 50%, #7C3AED); }
}
@keyframes accentTextGrad {
  0%, 4%   { color: #6DB7E2; }
  20%, 24% { color: #9B7BE0; }
  40%, 44% { color: #DB5D8E; }
  60%, 64% { color: #F08043; }
  80%, 84% { color: #1FAB85; }
  100%     { color: #6DB7E2; }
}
@keyframes pulse10 {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.5); opacity: 0.65; }
}

.bnr-preview {
  position: relative;
  aspect-ratio: 3 / 1;
  background-color: #07091A;
  color: #fff;
  overflow: hidden;
  border-radius: 14px;
  font-family: var(--font-display);
}
.bnr-glow {
  position: absolute;
  border-radius: 50%;
  opacity: 0.65;
}
.bnr-glow.a { top: -10%; left: 0%;   width: 60%; height: 100%; background: #2563EB; }
.bnr-glow.b { bottom: -20%; right: 0%; width: 60%; height: 110%; background: #7C3AED; opacity: 0.55; }
.bnr-glow.c { top: -10%; left: 40%; width: 30%; height: 50%; background: #00D4CB; opacity: 0.35; }

.bnr-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255,255,255,0.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.035) 1px, transparent 1px);
  background-size: 28px 28px;
  mask-image: radial-gradient(80% 80% at 50% 50%, #000 30%, transparent 95%);
  pointer-events: none;
}

.bnr-content {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 64px;
  padding: 56px 64px;
  align-items: center;
  height: 100%;
  box-sizing: border-box;
}
.bnr-logo {
  width: 240px; height: 240px;
  display: flex; align-items: center; justify-content: center;
}
.bnr-logo img, .bnr-logo svg { width: 100%; height: 100%; object-fit: contain; }

.bnr-text { display: flex; flex-direction: column; gap: 16px; }

.bnr-pill {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 12px 5px 8px;
  border-radius: 999px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.1);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 1.6px;
  color: rgba(255,255,255,0.72);
}
.bnr-pill-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #00D4CB;
}

.bnr-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 52px;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.05;
  color: #fff;
}
.bnr-title-accent {
  display: block;
  background: linear-gradient(120deg, #00D4CB, #2563EB 50%, #7C3AED);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.bnr-sub {
  margin: 6px 0 0;
  font-size: 17px;
  line-height: 1.5;
  color: rgba(255,255,255,0.7);
  font-family: var(--font-display);
}

.bnr-chips-row {
  display: flex;
  gap: 10px;
  margin-top: 10px;
  font-family: var(--font-mono);
  font-size: 10.5px;
}
.bnr-chip {
  padding: 4px 10px;
  border-radius: 6px;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.08);
  color: rgba(255,255,255,0.85);
}
.bnr-chip.brand {
  background: linear-gradient(120deg, #00D4CB, #2563EB 50%, #7C3AED);
  border: 0;
  color: #fff;
  opacity: 0.85;
}

.bnr-footrow {
  position: absolute;
  left: 484px;
  right: 60px;
  bottom: 28px;
  display: flex; justify-content: space-between;
  font-family: var(--font-mono);
  font-size: 11px;
  color: rgba(255,255,255,0.55);
  border-top: 1px solid rgba(255,255,255,0.08);
  padding-top: 14px;
  z-index: 2;
}
.bnr-footrow .accdot {
  display: inline-block;
  width: 6px; height: 6px; border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
  background: #00D4CB;
}
.bnr-footrow b {
  font-family: var(--font-display); font-weight: 500;
  color: rgba(255,255,255,0.92);
}
.bnr-footrow .sep { color: rgba(255,255,255,0.4); margin: 0 6px; }
`;

function BannerSvgPreview() {
  return (
    <div className="bnr-preview">
      <style>{BANNER_PREVIEW_STYLE}</style>
      <div className="bnr-glow a" />
      <div className="bnr-glow b" />
      <div className="bnr-glow c" />
      <div className="bnr-grid" />

      <div className="bnr-content">
        <div className="bnr-logo">
          <LogoOriginalClean size={240} />
        </div>
        <div className="bnr-text">
          <div className="bnr-pill">
            <span className="bnr-pill-dot" />
            DEVIS LAB · OPEN FOR PROJECTS
          </div>
          <h2 className="bnr-title">
            Hi, I'm Devis
            <span className="bnr-title-accent">vibe-coding daily</span>
          </h2>
          <p className="bnr-sub">
            Brand lab for digital products.<br/>
            Creative systems for playful AI tools.
          </p>
          <div className="bnr-chips-row">
            <span className="bnr-chip brand">Vibe coding</span>
            <span className="bnr-chip">Hand-crafted</span>
            <span className="bnr-chip">AI-curious</span>
            <span className="bnr-chip">Open source</span>
            <span className="bnr-chip">Indie</span>
          </div>
        </div>
      </div>

      <div className="bnr-footrow">
        <span><span className="accdot" />Devis Lab <span className="sep">·</span> vibe coding <span className="sep">·</span> 2026</span>
        <a href="#" style={{ color: "inherit", textDecoration: "none" }}>github.com/Devis-Lab</a>
      </div>
    </div>
  );
}

/* ──────────────────────────────────────────────────────────────────────
   Client-side SVG generator + download — bypasses server sanitizer
   ────────────────────────────────────────────────────────────────────── */

const THEMES_FOR_SVG = [
  { c1: '#00D4CB', c2: '#2563EB', c3: '#7C3AED' },
  { c1: '#A78BFA', c2: '#7C3AED', c3: '#5B21B6' },
  { c1: '#F472B6', c2: '#DB2777', c3: '#9D174D' },
  { c1: '#FBBF24', c2: '#F97316', c3: '#DC2626' },
  { c1: '#34D399', c2: '#10B981', c3: '#047857' },
];

async function buildBannerSvg(themeId = "blue") {
  const theme = getTheme(themeId);
  const resp = await fetch(`assets/github-banner-${theme.asset}.svg`);
  if (!resp.ok) throw new Error('Could not load generated SVG asset');
  return await resp.text();
}

function DownloadSvgButton({ themeId = "blue" }) {
  const theme = getTheme(themeId);
  const [busy, setBusy] = React.useState(false);
  const [done, setDone] = React.useState(false);
  const onClick = async () => {
    setBusy(true);
    try {
      const svg = await buildBannerSvg(theme.id);
      const blob = new Blob([svg], { type: 'image/svg+xml' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `github-banner-${theme.asset}.svg`;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(url);
      setDone(true);
      setTimeout(() => setDone(false), 2500);
    } catch (e) {
      console.error(e);
      alert('Failed to build SVG: ' + e.message);
    } finally {
      setBusy(false);
    }
  };
  return (
    <button
      onClick={onClick}
      disabled={busy}
      style={{
        appearance: 'none',
        border: 0,
        cursor: busy ? 'wait' : 'pointer',
        padding: '12px 22px',
        borderRadius: 10,
        background: 'linear-gradient(120deg, var(--accent-2), var(--accent-3))',
        color: '#fff',
        font: 'inherit',
        fontFamily: 'var(--font-display)',
        fontWeight: 500,
        fontSize: 14,
        letterSpacing: 0,
        boxShadow: '0 6px 16px -6px color-mix(in oklab, var(--accent-3), transparent 50%)',
        display: 'inline-flex',
        alignItems: 'center',
        gap: 8,
      }}
    >
      {busy ? 'Building...' : done ? 'Downloaded' : `Download github-banner-${theme.asset}.svg`}
    </button>
  );
}

Object.assign(window, { BannerSvgPreview, DownloadSvgButton });

function ProfileCardPage() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS, { migrateFrom: [PROFILE_TWEAKS_STORAGE_KEY] });
  const theme = getTheme(t.theme);
  const topbarCompact = useScrollCompact(28);
  const [soundEnabled, toggleSound] = useInteractionSoundToggle();

  useApplyTheme(theme.id);
  useApplyMode(t.mode);
  useApplyFavicon(theme.id, t.direction, t.mode);

  const TopbarLogo = LogoOriginal;
  const setDirection = React.useCallback((direction) => {
    setTweak("direction", direction);
    playLogoModeSound(direction);
  }, [setTweak]);
  const setTheme = React.useCallback((themeId) => {
    setTweak("theme", themeId);
    playAccentSound(themeId);
  }, [setTweak]);
  const setMode = React.useCallback((mode) => {
    setTweak("mode", mode);
    playSurfaceSound(mode);
  }, [setTweak]);
  const setMood = React.useCallback((mood) => {
    setTweak("tagline", mood);
    playMoodSound(mood);
  }, [setTweak]);

  return (
    <div className="pc-shell">
      {/* Page header */}
      <div className={"pc-hdr pc-home-hdr topbar" + (topbarCompact ? " is-compact" : "")}>
        <div className="pc-hdr-l topbar-brand">
          <span className="brand-mark">
            <TopbarLogo size={28} />
          </span>
          <HeaderBrand pulseToken={t.theme} />
        </div>
        <div className="pc-hdr-r">
          <span className="active-theme-signal" aria-label={`Active theme ${theme.short} ${t.mode}`}>
            <i aria-hidden="true" />
            {theme.short} / {t.mode}
          </span>
          <a className="pc-nav-link" href="brand-lab.html">Brand Lab</a>
          <div className="mode-tog" role="radiogroup" aria-label="Banner and page surface">
            <button aria-pressed={t.mode === "light"} className={t.mode === "light" ? "on" : ""} onClick={() => setMode("light")}>Light</button>
            <button aria-pressed={t.mode === "dark"} className={t.mode === "dark" ? "on" : ""} onClick={() => setMode("dark")}>Dark</button>
          </div>
          <SoundToggleButton enabled={soundEnabled} onToggle={toggleSound} />
        </div>
      </div>

      <InteractiveIdentityStage
        themeId={t.theme}
        direction={t.direction}
        tagline={t.tagline}
        mode={t.mode}
        onTheme={setTheme}
        onDirection={setDirection}
        onMode={setMode}
        onMood={setMood}
      />

      {false && (
        <React.Fragment>
      {/* All themes at once */}
      <h3 className="pc-section-title">Motywy dark i light</h3>
      <p className="pc-section-sub">
        Ten sam banner w pięciu kolorach i dwóch powierzchniach. Dark jest domyślny,
        ale light ma własny kontrast, tło i ringi.
      </p>
      <ThemeSurfaceGallery direction={t.direction} tagline={t.tagline} />

      {/* Ready-to-use README artifact */}
      <h3 className="pc-section-title">SVG do README</h3>
      <p className="pc-section-sub">
        Podglad i snippet korzystaja z aktywnego motywu: <code style={{ fontFamily: "var(--font-mono)", background: "var(--surface-2)", padding: "2px 6px", borderRadius: 4, fontSize: 12.5 }}>{`assets/github-banner-${theme.asset}.svg`}</code>.
      </p>

      <div className="banner-frame" style={{ marginBottom: 18 }}>
        <div className="banner-frame-cap">
          <span>
            <span className="dot-row"><i /><i /><i /></span>
            {`assets/github-banner-${theme.asset}.svg`}
          </span>
          <span>{theme.name}</span>
        </div>
        <div className="readme-svg-preview">
          <img src={`assets/github-banner-${theme.asset}.svg`} alt={`Devis Lab GitHub banner - ${theme.name}`} />
        </div>
      </div>

      <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap', marginBottom: 28 }}>
        <DownloadSvgButton themeId={theme.id} />
        <p style={{ margin: 0, fontSize: 13, color: 'var(--text-dim)', maxWidth: '52ch', lineHeight: 1.5 }}>
          Klik pobiera dokładnie ten wariant SVG, który widzisz w podglądzie.
        </p>
      </div>

      <div className="steps" style={{ marginBottom: 18 }}>
        <div className="step">
          <span className="num">1</span>
          <h4>Dodaj asset do repo profilu</h4>
          <p>
            Wrzuć <code>{`assets/github-banner-${theme.asset}.svg`}</code> do repo <code>Devis-Lab/Devis-Lab</code>.
          </p>
        </div>
        <div className="step">
          <span className="num">2</span>
          <h4>Wklej klikany Markdown</h4>
          <p>
            Uzyj snippetu ponizej. Link prowadzi do <code>{PROFILE_SITE_URL}</code>, a obraz ma aktualny odcien.
          </p>
        </div>
        <div className="step">
          <span className="num">3</span>
          <h4>Zmien motyw jednym kliknieciem</h4>
          <p>
            Przelacz akcent w bannerze, pobierz SVG i README od razu wskaze wlasciwy plik.
          </p>
        </div>
      </div>

      <h3 className="pc-section-title">Gotowy snippet</h3>
      <p className="pc-section-sub">
        Wklej do README.md. Zmienisz akcent, a nazwa pliku w markdownie zmieni sie razem z podgladem.
      </p>
      <ReadmeCode themeId={t.theme} direction={t.direction} />

        </React.Fragment>
      )}

      <div className="foot-line">
        <span>Devis Lab · 2026</span>
        <a href="brand-lab.html" style={{ color: "inherit", textDecoration: "none" }}>Brand Lab</a>
      </div>

      <TweaksPanel title="Devis Lab">
        <TweakSection label="Theme" />
        <TweakColor
          label="Accent"
          value={[theme.c1, theme.c2, theme.c3]}
          options={THEMES.map(th => [th.c1, th.c2, th.c3])}
          onChange={(palette) => {
            const th = THEMES.find(x => x.c1 === palette[0] && x.c2 === palette[1]);
            if (th) setTweak("theme", th.id);
          }}
        />
        <TweakSection label="Identity" />
        <TweakSelect
          label="Logo"
          value={t.direction}
          options={LOGO_DIRECTIONS.map(d => ({ value: d.id, label: d.label }))}
          onChange={(v) => setTweak("direction", v)}
        />
        <TweakSelect
          label="Copy"
          value={t.tagline}
          options={TAGLINES.map(tl => ({ value: tl.id, label: tl.id.toUpperCase() + " — " + tl.title }))}
          onChange={(v) => setTweak("tagline", v)}
        />
        <TweakSection label="Surface" />
        <TweakRadio
          label="Page"
          value={t.mode}
          options={[{ value: "light", label: "Light" }, { value: "dark", label: "Dark" }]}
          onChange={(v) => setTweak("mode", v)}
        />
      </TweaksPanel>
    </div>
  );
}

/* SegControl — re-declared here since sections.jsx isn't loaded on this page */
function SegControl({ value, onChange, options }) {
  const idx = Math.max(0, options.findIndex(o => o.id === value));
  return (
    <div style={{
      position: "relative",
      display: "inline-flex",
      padding: 3,
      borderRadius: 10,
      background: "var(--surface-2)",
      border: "1px solid var(--line)",
    }}>
      <div style={{
        position: "absolute",
        top: 3, bottom: 3,
        width: `calc((100% - 6px) / ${options.length})`,
        left: `calc(3px + ${idx} * (100% - 6px) / ${options.length})`,
        background: "var(--surface)",
        borderRadius: 7,
        boxShadow: "0 1px 3px rgba(13,19,43,.08)",
        transition: "left .18s cubic-bezier(.3,.7,.4,1)",
      }} />
      {options.map(o => (
        <button key={o.id}
          onClick={() => onChange(o.id)}
          style={{
            position: "relative",
            background: "transparent",
            border: 0,
            padding: "7px 14px",
            fontFamily: "var(--font-display)",
            fontWeight: 500,
            fontSize: 12.5,
            color: o.id === value ? "var(--text)" : "var(--text-dim)",
            cursor: "pointer",
            borderRadius: 7,
          }}
        >{o.label}</button>
      ))}
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<ProfileCardPage />);
