const { useState, useEffect, useMemo, useRef } = React;

// Data loaded from data.js (window.FILTERS, window.CONFLICTS, window.PRODUCTS)
const FILTERS   = window.FILTERS;
const CONFLICTS = window.CONFLICTS;
const PRODUCTS  = window.PRODUCTS;

const conflictMap = {};
FILTERS.forEach(f => conflictMap[f.id] = new Set());
CONFLICTS.forEach(([a,b]) => { conflictMap[a].add(b); conflictMap[b].add(a); });

// Localized filter labels
function flabel(id) { return t(`f.${id}.label`); }
function fsub(id)   { return t(`f.${id}.sub`); }

// ============ PRODUCT CATALOG ============
// Loaded from data.js (window.PRODUCTS) so product.html can share it.

// ============ GAMIFICATION ============
// Score = sum over active filters of how well a product matches that filter
function scoreProduct(p, active) {
  if (active.size === 0) return 0;
  let s = 0;
  active.forEach(tag => { if (p.tags.includes(tag)) s += 1; });
  return s / active.size; // 0..1
}

function comboName(active) {
  if (active.size === 0) return { name: t("combo.empty"), flavor: t("combo.empty.flav"), tier: 0 };
  const has = (...tags) => tags.every(x => active.has(x));
  if (has("pahali","super","iyi")) return { name:t("combo.endgame"), flavor:t("combo.endgame.flav"), tier:5 };
  if (has("ucuz","iyi"))           return { name:t("combo.value"),   flavor:t("combo.value.flav"),   tier:4 };
  if (has("super","iyi"))          return { name:t("combo.main"),    flavor:t("combo.main.flav"),    tier:4 };
  if (has("pahali","iyi"))         return { name:t("combo.premium"), flavor:t("combo.premium.flav"), tier:3 };
  if (has("ucuz","kotu"))          return { name:t("combo.trap"),    flavor:t("combo.trap.flav"),    tier:1 };
  if (has("pahali"))               return { name:t("combo.big"),     flavor:t("combo.big.flav"),     tier:3 };
  if (has("super"))                return { name:t("combo.top"),     flavor:t("combo.top.flav"),     tier:4 };
  if (has("iyi"))                  return { name:t("combo.safe"),    flavor:t("combo.safe.flav"),    tier:3 };
  if (has("ucuz"))                 return { name:t("combo.bargain"), flavor:t("combo.bargain.flav"), tier:2 };
  if (has("kotu"))                 return { name:t("combo.regret"),  flavor:t("combo.regret.flav"),  tier:1 };
  return { name:t("combo.generic"), flavor:"", tier:2 };
}

// ============ UI ============
function App() {
  const [active, setActive]   = useState(new Set());
  const [shake,  setShake]    = useState(null);
  const [types,  setTypes]    = useState(new Set()); // empty = all; "kulaklık" / "klavye"
  const [xp,     setXp]       = useState(0);
  const [flash,  setFlash]    = useState(null);
  const [sort,   setSort]     = useState("match"); // match | ucuz | pahali
  const [bumpedProducts, setBumpedProducts] = useState(new Set());

  function toggleType(typeId) {
    setTypes(prev => {
      const next = new Set(prev);
      if (next.has(typeId)) next.delete(typeId); else { next.add(typeId); setXp(x => x + 5); }
      return next;
    });
  }

  function toggle(id) {
    setActive(prev => {
      const next = new Set(prev);
      if (next.has(id)) {
        next.delete(id);
        return next;
      }
      // check conflicts
      const enemies = conflictMap[id];
      const blocked = [...enemies].filter(e => next.has(e));
      if (blocked.length > 0) {
        setShake({ id, enemies: blocked });
        setTimeout(() => setShake(null), 600);
        setFlash({ msg: `⚠ ${flabel(id)} ${t("flash.conflict")} ${blocked.map(e=>flabel(e)).join(" + ")} ${t("flash.conflict.end")}`, type:"err" });
        setTimeout(() => setFlash(null), 1800);
        return prev;
      }
      next.add(id);
      setXp(x => x + 10);
      setFlash({ msg:t("flash.xp"), type:"ok" });
      setTimeout(() => setFlash(null), 900);
      // bump products that match this new tag
      const matches = PRODUCTS.filter(p => p.tags.includes(id)).map(p=>p.id);
      setBumpedProducts(new Set(matches));
      setTimeout(() => setBumpedProducts(new Set()), 700);
      return next;
    });
  }

  function clearAll() {
    setActive(new Set());
  }

  const combo = comboName(active);

  const visible = useMemo(() => {
    let list = PRODUCTS.filter(p => types.size === 0 ? true : types.has(p.type));
    // attach score
    list = list.map(p => ({ ...p, _score: scoreProduct(p, active) }));
    // when filters are active, hide products with zero match
    if (active.size > 0) {
      list = list.filter(p => p._score > 0);
    }
    if (sort === "ucuz")   list.sort((a,b) => a.price - b.price);
    else if (sort === "pahali") list.sort((a,b) => b.price - a.price);
    else list.sort((a,b) => b._score - a._score || a.price - b.price);
    return list;
  }, [types, active, sort]);

  const cheapest = visible[0] && [...visible].sort((a,b)=>{
    const ap = window.displayPrice(a).amount, bp = window.displayPrice(b).amount;
    return ap - bp;
  })[0];

  // ===== render =====
  return (
    <div className="app">
      <Stickers/>
      <Header xp={xp} combo={combo} flash={flash} />
      {active.size === 0 && types.size === 0 && <FeaturedHero />}
      <FilterBoard
        active={active}
        toggle={toggle}
        shake={shake}
        onClear={clearAll}
        types={types}
        toggleType={toggleType}
      />
      <ResultsBar
        sort={sort} setSort={setSort}
        count={visible.length}
        cheapest={cheapest}
      />
      <Grid items={visible} active={active} bumped={bumpedProducts} />
      <Legend />
    </div>
  );
}

// ====== ENTRANCE SHOWCASE — picks computed live from PRODUCTS ======
function pickFeatured() {
  const all = PRODUCTS;
  const hp = all.filter(p => p.type === "kulaklık");
  const kb = all.filter(p => p.type === "klavye");
  const has = (p, t) => p.tags.includes(t);
  const byPrice = arr => [...arr].sort((a,b)=>a.price-b.price);
  const used = new Set();
  const take = (p) => { if (p) used.add(p.id); return p; };
  const not = arr => arr.filter(p => !used.has(p.id));

  // 1) PREMIUM — en pahalı 'super' ürün
  const premium = take(
    [...all].filter(p => has(p,"super")).sort((a,b)=>b.price-a.price)[0]
    || [...all].sort((a,b)=>b.price-a.price)[0]
  );
  // 2) EN İYİ SES — sound skoru en yüksek kulaklık
  const bestSound = take(
    not(hp).sort((a,b)=>(b.sound||0)-(a.sound||0))[0] || not(hp)[0]
  );
  // 3) VALUE — en ucuz 'ucuz'+'iyi'
  const value = take(
    byPrice(not(all).filter(p => has(p,"ucuz") && has(p,"iyi")))[0]
    || byPrice(not(all).filter(p => has(p,"iyi")))[0]
  );
  // 4) EN İYİ KLAVYE — 'super' > 'iyi', hotswap, sonra fiyat
  const bestKb = take(
    not(kb).sort((a,b)=>{
      const q = x => (has(x,"super")?2:0)+(has(x,"iyi")?1:0)+(x.hotswap?0.5:0);
      return q(b)-q(a) || b.price-a.price;
    })[0] || not(kb)[0]
  );

  return [
    premium  && { p: premium,  kind: "premium", badge: "b-premium" },
    bestSound&& { p: bestSound,kind: "best",    badge: "b-best" },
    value    && { p: value,    kind: "value",   badge: "b-value" },
    bestKb   && { p: bestKb,   kind: "budget",  badge: "b-budget" },
  ].filter(Boolean);
}

function FeaturedHero() {
  const picks = useMemo(pickFeatured, []);
  if (!picks.length) return null;
  return (
    <section className="hero-show">
      <div className="hero-show-head">
        <div className="hero-show-title">
          {window.LANG==="tr" ? <>EDİTÖR <span className="hl">SEÇİMLERİ</span></> : <>EDITOR'S <span className="hl">PICKS</span></>}
        </div>
        <div className="hero-show-sub">{t("hero.sub")}</div>
      </div>
      <div className="hero-grid">
        {picks.map(({p, kind, badge}) => {
          const dp = window.displayPrice(p);
          const st = window.displayStores(p).stores[0]?.name || p.store;
          return (
            <a key={p.id} className="hero-card" href={`product.html?id=${p.id}`} target="_blank" rel="noopener">
              <span className={`hero-card-badge ${badge}`}>{t(`hero.${kind}`)}</span>
              <div className="hero-card-img">
                {p.image
                  ? <img src={p.image} alt={`${p.brand} ${p.model}`} loading="lazy"/>
                  : p.type==="klavye" ? <KbMock seed={p.id}/> : <HpMock seed={p.id}/>}
              </div>
              <div className="hero-card-body">
                <div className="hero-card-brand">{p.brand}</div>
                <div className="hero-card-model">{p.model}</div>
                <div className="hero-card-why">{t(`hero.${kind}.why`)}</div>
                <div className="hero-card-foot">
                  <div className="hero-card-price"><span className="cur">{dp.symbol}</span>{dp.amount.toLocaleString(dp.locale)}</div>
                  <div className="hero-card-store">@ {st}</div>
                </div>
                <div className="hero-card-cta">{t("cat.details")}</div>
              </div>
            </a>
          );
        })}
      </div>
    </section>
  );
}

function Marquee({ combo, count, active }) {
  const items = [
    `KOMBO: ${combo.name}`,
    `${active} FİLTRE AKTİF`,
    `${count} ÜRÜN GÖSTERİLİYOR`,
    "EN POPÜLER: 75% KLAVYE",
    "TREND: TACTILE SWITCH",
    "EN ÇOK ARANAN: HOT-SWAP",
    "ANC > 90 = PREMIUM",
    "KOMBO: ${combo.name}".replace("${combo.name}", combo.name),
    "PİL > 30sa = LONG-HAUL",
    "SWITCH'LERİ DENE ↓",
  ];
  return (
    <div className="marquee">
      <div className="marquee-inner">
        {[...items, ...items].map((t,i) => (
          <span key={i} className="marquee-item">
            <span className="marquee-bullet">●</span>{t}
          </span>
        ))}
      </div>
    </div>
  );
}

function Stickers() {
  const TR = window.LANG === "tr";
  return (
    <div className="stickers" aria-hidden="true">
      <svg className="sticker sticker-burst" viewBox="0 0 60 60">
        <g transform="translate(30 30)">
          {[...Array(16)].map((_,i) => (
            <line key={i} x1="0" y1="0" x2="0" y2="-26"
                  stroke="currentColor" strokeWidth="3" strokeLinecap="round"
                  transform={`rotate(${i*22.5})`}/>
          ))}
          <circle r="8" fill="currentColor"/>
        </g>
      </svg>
      <div className="sticker sticker-new">
        <span className="sticker-new-l1">{TR ? "YENİ" : "NEW"}</span>
        <span className="sticker-new-l2">{TR ? "2026" : "2026"}</span>
        <span className="sticker-new-stars">★★★</span>
      </div>
      <svg className="sticker sticker-asterisk" viewBox="0 0 40 40">
        <g transform="translate(20 20)" stroke="currentColor" strokeWidth="3" strokeLinecap="round">
          <line x1="0" y1="-15" x2="0" y2="15"/>
          <line x1="-15" y1="0" x2="15" y2="0"/>
          <line x1="-11" y1="-11" x2="11" y2="11"/>
          <line x1="-11" y1="11" x2="11" y2="-11"/>
        </g>
      </svg>
      <div className="sticker sticker-stamp">
        <span>★</span> <span>{TR ? "İNDİRİM" : "DEAL"}</span> <span>★</span>
        <small>{TR ? "BU HAFTA" : "THIS WEEK"}</small>
      </div>
      <svg className="sticker sticker-arrow" viewBox="0 0 80 40">
        <path d="M 5 20 Q 30 5 55 20 L 50 15 M 55 20 L 50 25"
              stroke="currentColor" strokeWidth="2.5" fill="none"
              strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
      <div className="sticker sticker-tape">
        <span>★ {TR ? "ARŞİV" : "ARCHIVE"} ★ {TR ? "KATALOG" : "CATALOG"} ★ 2026 ★</span>
      </div>
    </div>
  );
}

function Header({ xp, combo, flash }) {
  const level = Math.floor(xp / 50) + 1;
  const xpInLvl = xp % 50;
  return (
    <header className="hdr">
      <div className="hdr-l">
        <div className="logo">
          <span className="logo-a">Klavye</span>
          <span className="logo-b">× Kulaklık</span>
        </div>
        <div className="tagline">{t("cat.tagline")}</div>
      </div>
      <div className="hdr-r">
        <div className="combo">
          <div key={combo.name} className={`combo-name tier-${combo.tier}`}>{combo.name}</div>
          <div className="combo-flavor">{combo.flavor}</div>
        </div>
        <div className="xp">
          <div className="xp-label">{t("cat.lv")} {level}</div>
          <div className="xp-bar"><div className="xp-fill" style={{width: `${(xpInLvl/50)*100}%`}}/></div>
          <div className="xp-num">{xp} {t("cat.xp")}</div>
        </div>
      </div>
      {flash && <div className={`flash flash-${flash.type}`}>{flash.msg}</div>}
    </header>
  );
}

function FilterBoard({ active, toggle, shake, onClear, types, toggleType }) {
  const TYPE_SWITCHES = [
    { id:"kulaklık", label:t("t.kulaklık"), sub:t("t.kulaklık.sub"), hue:200, icon:"🎧" },
    { id:"klavye",   label:t("t.klavye"),   sub:t("t.klavye.sub"),   hue:120, icon:"⌨"  },
  ];
  return (
    <section className="board">
      <div className="board-head">
        <div className="board-title">
          <span className="dot dot-live"/> {t("cat.panel")}
        </div>
        <div className="board-meta">
          <span className="meta-on">{active.size + types.size} {t("cat.active")}</span>
          <button className="clear-btn" onClick={onClear} disabled={active.size===0}>{t("cat.reset")}</button>
        </div>
      </div>

      <div className="sw-group-label">{t("cat.group.type")}</div>
      <div className="switches switches-type">
        {TYPE_SWITCHES.map(f => (
          <Switch
            key={f.id}
            f={f}
            on={types.has(f.id)}
            onClick={() => toggleType(f.id)}
            isShaking={false}
            isEnemy={false}
            blocked={false}
            enemies={[]}
          />
        ))}
      </div>

      <div className="sw-group-label">{t("cat.group.q")}</div>
      <div className="switches">
        {FILTERS.map(f => {
          const localized = { ...f, label: flabel(f.id), sub: fsub(f.id) };
          const on = active.has(f.id);
          const isShaking = shake?.id === f.id;
          const isEnemy   = shake?.enemies.includes(f.id);
          const enemies   = [...conflictMap[f.id]];
          const blockedByActive = enemies.some(e => active.has(e)) && !on;
          return (
            <Switch
              key={f.id}
              f={localized}
              on={on}
              onClick={() => toggle(f.id)}
              isShaking={isShaking}
              isEnemy={isEnemy}
              blocked={blockedByActive}
              enemies={enemies}
            />
          );
        })}
      </div>

      <ConflictMatrix active={active} />
    </section>
  );
}

function Switch({ f, on, onClick, isShaking, isEnemy, blocked, enemies }) {
  const cls = [
    "sw",
    on && "sw-on",
    blocked && "sw-blocked",
    isShaking && "sw-shake",
    isEnemy && "sw-enemy",
  ].filter(Boolean).join(" ");
  return (
    <button
      className={cls}
      onClick={onClick}
      style={{ "--hue": f.hue }}
      title={blocked ? `Çakışıyor: ${enemies.join(", ")}` : f.label}
    >
      <div className="sw-icon">{f.icon}</div>
      <div className="sw-track">
        <div className="sw-knob"/>
        <div className="sw-track-off">{t("cat.off")}</div>
        <div className="sw-track-on">{t("cat.on")}</div>
      </div>
      <div className="sw-meta">
        <div className="sw-label">{f.label}</div>
        <div className="sw-sub">{f.sub}</div>
      </div>
      {blocked && <div className="sw-lock">{t("cat.lock")}</div>}
    </button>
  );
}

function ConflictMatrix({ active }) {
  return (
    <div className="matrix">
      <div className="matrix-title">{t("cat.conflict")}</div>
      <div className="matrix-rules">
        {CONFLICTS.map(([a,b], i) => {
          const fa = FILTERS.find(x=>x.id===a);
          const fb = FILTERS.find(x=>x.id===b);
          const aActive = active.has(a);
          const bActive = active.has(b);
          const live = aActive || bActive;
          return (
            <div key={i} className={`rule ${live ? "rule-live" : ""}`}>
              <span className={`rule-tag ${aActive ? "rule-tag-on" : ""}`} style={{"--hue": fa.hue}}>{flabel(a)}</span>
              <span className="rule-x">⊥</span>
              <span className={`rule-tag ${bActive ? "rule-tag-on" : ""}`} style={{"--hue": fb.hue}}>{flabel(b)}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function ResultsBar({ sort, setSort, count, cheapest }) {
  return (
    <div className="rbar">
      <div className="rbar-l">
        <span className="count-big">{count}</span>
        <span className="count-label">{t("cat.matching")}</span>
      </div>
      <div className="rbar-r">
        {cheapest && (() => {
          const dp = window.displayPrice(cheapest);
          const st = window.displayStores(cheapest).stores[0]?.name || cheapest.store;
          return (
            <a className="bestprice" href={`product.html?id=${cheapest.id}`} target="_blank" rel="noopener">
              <span className="bp-label">{t("cat.cheapest")}</span>
              <span className="bp-val">{dp.symbol}{dp.amount.toLocaleString(dp.locale)}</span>
              <span className="bp-store">@ {st}</span>
              <span className="bp-arrow">↗</span>
            </a>
          );
        })()}
        <div className="sort">
          <span className="sort-label">{t("cat.sort")}</span>
          {[["match",t("cat.match")],["ucuz","₺ ↑"],["pahali","₺ ↓"]].map(([k,l]) => (
            <button key={k} className={`sort-btn ${sort===k?"sort-on":""}`} onClick={()=>setSort(k)}>{l}</button>
          ))}
        </div>
      </div>
    </div>
  );
}

function Grid({ items, active, bumped }) {
  if (items.length === 0) {
    return (
      <div className="empty">
        <div className="empty-icon">⊘</div>
        <div className="empty-title">{t("cat.empty.title")}</div>
        <div className="empty-sub">{t("cat.empty.sub")}</div>
      </div>
    );
  }
  return (
    <div className="grid">
      {items.map((p,i) => (
        <Card key={p.id} p={p} active={active} bumped={bumped.has(p.id)} idx={i} />
      ))}
    </div>
  );
}

function Card({ p, active, bumped, idx }) {
  const matchPct = active.size === 0 ? null : Math.round(p._score * 100);
  const isFullMatch = active.size > 0 && p._score === 1;
  return (
    <a
      className={`card ${bumped?"card-bump":""} ${isFullMatch?"card-full":""}`}
      style={{ "--i": idx }}
      href={`product.html?id=${p.id}`}
      target="_blank"
      rel="noopener"
    >
      {isFullMatch && <div className="card-badge">{t("cat.perfect")}</div>}
      <div className="card-type">{p.type === "klavye" ? `⌨ ${t("t.klavye")}` : `🎧 ${t("t.kulaklık")}`}</div>
      <div className="card-mock" style={{"--seed": p.id*37 % 360}}>
        {p.image
          ? <img className="card-product-img" src={p.image} alt={`${p.brand} ${p.model}`} loading="lazy" />
          : p.type==="klavye"
            ? <KbMock seed={p.id} />
            : <HpMock seed={p.id} />}
      </div>
      <div className="card-brand">{p.brand}</div>
      <div className="card-model">{p.model}</div>

      {p.type=="klavye" && (
        <div className="kb-specs">
          <span className="kb-chip kb-chip-form">{p.form}</span>
          <span className={`kb-chip kb-chip-sw kb-sw-${p.sw.toLowerCase()}`}>{LV(p.sw, "sw")}</span>
          <span className="kb-chip kb-chip-conn">{LV(p.conn, "conn")}</span>
          {p.hotswap && <span className="kb-chip kb-chip-hot">HOT-SWAP</span>}
        </div>
      )}
      {p.type=="klavye" && p.build && <div className="card-spec">{L(p.build)}</div>}

      {p.type=="kulaklık" && (
        <div className="card-stats">
          <Stat label={t("pd.spec.anc")}  v={p.anc} />
          <Stat label={t("pd.spec.sound")}  v={p.sound} />
          <Stat label={t("pd.spec.battery")}  v={Math.min(100, Math.round(p.battery/70*100))} suffix={`${p.battery}${window.LANG==="tr"?"sa":"h"}`} />
        </div>
      )}
      {p.type=="kulaklık" && p.codec && <div className="card-spec">Codec: {p.codec}</div>}

      <div className="card-tags">
        {p.tags.map(tagId => {
          const f = FILTERS.find(x=>x.id===tagId);
          const on = active.has(tagId);
          return <span key={tagId} className={`ctag ${on?"ctag-on":""}`} style={{"--hue":f.hue}}>{flabel(tagId)}</span>;
        })}
      </div>

      <div className="card-foot">
        {(() => {
          const dp = window.displayPrice(p);
          return (
            <div className="card-price">
              <span className="price-cur">{dp.symbol}</span>
              <span className="price-num">{dp.amount.toLocaleString(dp.locale)}</span>
            </div>
          );
        })()}
        <div className="card-store">@ {window.displayStores(p).stores[0]?.name || p.store}</div>
      </div>

      {matchPct !== null && (
        <div className="card-match">
          <div className="match-bar"><div className="match-fill" style={{width:`${matchPct}%`}}/></div>
          <div className="match-num">{matchPct}%</div>
        </div>
      )}
      <div className="card-cta">{t("cat.details")}</div>
    </a>
  );
}

function Stat({ label, v, suffix }) {
  return (
    <div className="stat">
      <div className="stat-label">{label}</div>
      <div className="stat-bar"><div className="stat-fill" style={{width:`${v}%`}}/></div>
      <div className="stat-v">{suffix || v}</div>
    </div>
  );
}

// ===== Procedural visual mocks for products (placeholders, no real images) =====
function HpMock({ seed }) {
  const h = (seed * 47) % 360;
  const accent = `hsl(${h} 75% 55%)`;
  const dark   = `hsl(${h} 35% 22%)`;
  const mid    = `hsl(${h} 45% 38%)`;
  const cushion = `hsl(${h} 25% 18%)`;
  return (
    <svg viewBox="0 0 120 90" className="mock-svg" preserveAspectRatio="xMidYMid meet">
      <defs>
        <linearGradient id={`hpg${seed}`} x1="0" x2="0" y1="0" y2="1">
          <stop offset="0" stopColor={accent}/>
          <stop offset="1" stopColor={mid}/>
        </linearGradient>
        <linearGradient id={`hph${seed}`} x1="0" x2="0" y1="0" y2="1">
          <stop offset="0" stopColor={mid}/>
          <stop offset="1" stopColor={dark}/>
        </linearGradient>
      </defs>
      {/* Headband — outer */}
      <path d="M 18 56 Q 60 -2 102 56" stroke="#0d0d0e" strokeWidth="8" fill="none" strokeLinecap="round"/>
      <path d="M 18 56 Q 60 -2 102 56" stroke={`url(#hph${seed})`} strokeWidth="6" fill="none" strokeLinecap="round"/>
      {/* Headband stitching */}
      <path d="M 24 50 Q 60 4 96 50" stroke="rgba(255,255,255,0.25)" strokeWidth="0.8" fill="none" strokeDasharray="2 3" strokeLinecap="round"/>

      {/* Earcup connectors */}
      <rect x="20" y="44" width="5" height="14" rx="1" fill="#0d0d0e"/>
      <rect x="95" y="44" width="5" height="14" rx="1" fill="#0d0d0e"/>

      {/* LEFT earcup — outer ring */}
      <rect x="6" y="48" width="28" height="36" rx="10" fill="#0d0d0e"/>
      <rect x="8" y="50" width="24" height="32" rx="8" fill={`url(#hpg${seed})`}/>
      {/* cushion */}
      <ellipse cx="20" cy="66" rx="9" ry="11" fill={cushion}/>
      <ellipse cx="20" cy="66" rx="6.5" ry="8.5" fill="rgba(0,0,0,0.5)"/>
      {/* brand dot */}
      <circle cx="13" cy="55" r="1.2" fill={accent}/>

      {/* RIGHT earcup */}
      <rect x="86" y="48" width="28" height="36" rx="10" fill="#0d0d0e"/>
      <rect x="88" y="50" width="24" height="32" rx="8" fill={`url(#hpg${seed})`}/>
      <ellipse cx="100" cy="66" rx="9" ry="11" fill={cushion}/>
      <ellipse cx="100" cy="66" rx="6.5" ry="8.5" fill="rgba(0,0,0,0.5)"/>
      {/* L/R indicator */}
      <text x="100" y="56" textAnchor="middle" fill="rgba(255,255,255,0.4)" fontSize="3.5" fontWeight="800" fontFamily="monospace">R</text>
      <text x="20" y="56" textAnchor="middle" fill="rgba(255,255,255,0.4)" fontSize="3.5" fontWeight="800" fontFamily="monospace">L</text>
    </svg>
  );
}

function KbMock({ seed }) {
  const h = (seed * 53) % 360;
  const isLight = seed % 3 === 0;
  const base  = isLight ? `hsl(${h} 18% 78%)` : `hsl(${h} 32% 22%)`;
  const plate = isLight ? `hsl(${h} 30% 60%)` : `hsl(${h} 60% 45%)`;
  const cap   = isLight ? "#f1ebdc" : "#3a3a3f";
  const capDark = isLight ? "#d6d0bd" : "#2a2a2f";
  const text  = isLight ? "rgba(0,0,0,0.6)" : "rgba(255,255,255,0.55)";
  const accent = `hsl(${h} 80% 55%)`;

  // 4 rows × 14 cols of keys, last row has wider modifiers
  const keys = [];
  const layout = [
    [1,1,1,1,1,1,1,1,1,1,1,1,1,2],     // numbers + backspace
    [1.5,1,1,1,1,1,1,1,1,1,1,1,1,1.5], // QWERTY
    [1.8,1,1,1,1,1,1,1,1,1,1,1,2.2],   // ASDF
    [2.2,1,1,1,1,1,1,1,1,1,1,2.8],     // ZXCV
  ];
  const totalW = 110, startX = 5;
  layout.forEach((row, r) => {
    let x = startX;
    const totalUnits = row.reduce((a,b) => a + b, 0);
    const unit = totalW / totalUnits;
    row.forEach((u, c) => {
      const w = unit * u - 0.6;
      const isAccent = (r === 0 && c === row.length - 1) || (r === 3 && c === Math.floor(row.length / 2));
      keys.push(
        <g key={`${r}-${c}`}>
          {/* Key shadow / side */}
          <rect x={x} y={20 + r*13.5 + 1} width={w} height="11" rx="1.5" fill={capDark}/>
          {/* Key top */}
          <rect x={x} y={20 + r*13.5} width={w} height="10" rx="1.5"
                fill={isAccent ? accent : cap}
                stroke="rgba(0,0,0,0.18)" strokeWidth="0.3"/>
          {/* Tiny letter on alpha row */}
          {u === 1 && r === 1 && c < 10 && (
            <text x={x + w/2} y={28} textAnchor="middle" fill={text} fontSize="3.2" fontWeight="800" fontFamily="monospace">
              {"QWERTYUIOP".charAt(c)}
            </text>
          )}
          {u === 1 && r === 2 && c < 9 && c > 0 && (
            <text x={x + w/2} y={41.5} textAnchor="middle" fill={text} fontSize="3.2" fontWeight="800" fontFamily="monospace">
              {"ASDFGHJKL".charAt(c - 1)}
            </text>
          )}
        </g>
      );
      x += unit * u;
    });
  });

  return (
    <svg viewBox="0 0 120 90" className="mock-svg" preserveAspectRatio="xMidYMid meet">
      {/* Body shadow */}
      <rect x="2" y="14" width="116" height="68" rx="5" fill="#0d0d0e"/>
      {/* Body */}
      <rect x="2" y="14" width="116" height="64" rx="5" fill={base} stroke="#0d0d0e" strokeWidth="0.8"/>
      {/* Plate accent line */}
      <rect x="2" y="14" width="116" height="3" fill={plate}/>
      {/* USB-C port */}
      <rect x="56" y="14" width="8" height="2" rx="0.5" fill="#0d0d0e"/>
      {/* Keys */}
      {keys}
      {/* Brand mark bottom-left */}
      <circle cx="8" cy="74" r="1.5" fill={accent}/>
      <text x="13" y="76" fill={text} fontSize="3" fontWeight="800" fontFamily="monospace" letterSpacing="0.5">{`MX-${(seed*7)%100}`}</text>
    </svg>
  );
}

function Legend() {
  return (
    <footer className="legend">
      <div>{t("cat.howto")}</div>
      <div className="legend-r">{t("cat.version")}</div>
    </footer>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
