diff --git a/index.html b/index.html
new file mode 100644
index 0000000..f01f050
--- /dev/null
+++ b/index.html
@@ -0,0 +1,448 @@
+import { useState, useRef, useCallback } from "react";
+
+const CARD_TYPES = ["Creature", "Instant", "Sorcery", "Enchantment", "Artifact", "Land", "Planeswalker", "Battle"];
+const COLORS = [
+ { id: "W", label: "White", symbol: "โ", bg: "#f9f6d5", border: "#c8b87a", text: "#333" },
+ { id: "U", label: "Blue", symbol: "๐ง", bg: "#c6d9e8", border: "#3a6b9c", text: "#fff" },
+ { id: "B", label: "Black", symbol: "๐", bg: "#1a1a1a", border: "#5a4a6e", text: "#d0c8e0" },
+ { id: "R", label: "Red", symbol: "๐ฅ", bg: "#e87040", border: "#8b2500", text: "#fff" },
+ { id: "G", label: "Green", symbol: "๐ฒ", bg: "#3a7a48", border: "#1a4025", text: "#d4f5d0" },
+ { id: "C", label: "Colorless", symbol: "โ", bg: "#c0bdb5", border: "#7a7068", text: "#333" },
+ { id: "M", label: "Multi", symbol: "โ
", bg: "linear-gradient(135deg,#f9f6d5,#c6d9e8,#1a1a1a,#e87040,#3a7a48)", border: "#b8960c", text: "#fff" },
+];
+
+const RARITY_COLORS = { Common: "#aaa", Uncommon: "#a0c0d0", Rare: "#d4af37", "Mythic Rare": "#e07020" };
+
+const DEFAULT_CARD = {
+ name: "Blazing Champion",
+ manaCost: "{2}{R}{R}",
+ type: "Creature",
+ subtype: "Human Warrior",
+ color: "R",
+ rarity: "Rare",
+ power: "4",
+ toughness: "3",
+ rulesText: "Haste\nWhen Blazing Champion enters the battlefield, it deals 2 damage to any target.",
+ flavorText: "\"No retreat. No mercy. Only fire.\"",
+ artist: "Proxy Artist",
+ setSymbol: "โ
",
+ loyalty: "",
+};
+
+function CardPreview({ card, imageUrl }) {
+ const colorObj = COLORS.find(c => c.id === card.color) || COLORS[5];
+ const isMulti = card.color === "M";
+ const isLand = card.type === "Land";
+ const isPW = card.type === "Planeswalker";
+
+ const frameBg = isMulti
+ ? "linear-gradient(160deg,#f9f6d5 0%,#c6d9e8 25%,#1a1a1a 50%,#e87040 75%,#3a7a48 100%)"
+ : colorObj.bg;
+
+ const rarityColor = RARITY_COLORS[card.rarity] || "#aaa";
+
+ return (
+
+ {/* Header */}
+
+
+ {card.name || "Card Name"}
+
+
+ {card.manaCost || ""}
+
+
+
+ {/* Art Frame */}
+
+ {imageUrl ? (
+

+ ) : (
+
+ {colorObj.symbol}
+
+ )}
+ {/* Set & rarity */}
+
+ {card.setSymbol || "โ
"} {card.rarity ? card.rarity[0] : ""}
+
+
+
+ {/* Type Line */}
+
+ {[card.type, card.subtype].filter(Boolean).join(" โ ") || "Type"}
+ {card.setSymbol || "โ
"}
+
+
+ {/* Text Box */}
+
+
+ {card.rulesText || ""}
+
+ {card.flavorText && (
+
+ {card.flavorText}
+
+ )}
+
+
+ {/* Footer */}
+
+
โฆ {card.artist || "Unknown"}
+ {(card.type === "Creature" || card.type === "Battle") && (
+
+ {card.power}/{card.toughness}
+
+ )}
+ {isPW && card.loyalty && (
+
+ {card.loyalty}
+
+ )}
+
+
+ );
+}
+
+function Field({ label, children }) {
+ return (
+
+
+ {children}
+
+ );
+}
+
+const inputStyle = {
+ background: "#1e1a14",
+ border: "1px solid #3a3020",
+ borderRadius: 6,
+ color: "#e8dfc8",
+ padding: "7px 10px",
+ fontSize: 13,
+ fontFamily: "inherit",
+ outline: "none",
+ width: "100%",
+ boxSizing: "border-box",
+ transition: "border-color 0.2s",
+};
+
+export default function App() {
+ const [card, setCard] = useState(DEFAULT_CARD);
+ const [imageUrl, setImageUrl] = useState("");
+ const [imageInput, setImageInput] = useState("");
+ const [tab, setTab] = useState("basic");
+ const previewRef = useRef();
+ const fileInputRef = useRef();
+
+ const update = useCallback((field, val) => setCard(c => ({ ...c, [field]: val })), []);
+
+ const handleImageFile = (e) => {
+ const file = e.target.files?.[0];
+ if (!file) return;
+ const reader = new FileReader();
+ reader.onload = (ev) => setImageUrl(ev.target.result);
+ reader.readAsDataURL(file);
+ };
+
+ const handleImageUrl = () => {
+ setImageUrl(imageInput.trim());
+ };
+
+ const handlePrint = () => window.print();
+
+ const isPW = card.type === "Planeswalker";
+ const isCreature = card.type === "Creature" || card.type === "Battle";
+
+ return (
+
+ {/* Header */}
+
+
๐
+
+
MTG Proxy Maker
+
Design ยท Print ยท Play
+
+
+
+
+
+ {/* Editor Panel */}
+
+ {/* Tabs */}
+
+ {["basic", "art", "stats"].map(t => (
+
+ ))}
+
+
+
+ {tab === "basic" && <>
+
+ update("name", e.target.value)} placeholder="e.g. Blazing Champion" />
+
+
+ update("manaCost", e.target.value)} placeholder="{2}{R}{R}" />
+
+
+
+
+
+
+ update("subtype", e.target.value)} placeholder="e.g. Wizard" />
+
+
+
+
+ {COLORS.map(c => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+ update("artist", e.target.value)} placeholder="Artist name" />
+
+ >}
+
+ {tab === "art" && <>
+
+
+
+
+
โ or paste an image URL โ
+
+
+ setImageInput(e.target.value)} placeholder="https://..." />
+
+
+
+ {imageUrl && (
+
+

+
+
+ )}
+
+ update("setSymbol", e.target.value)} placeholder="โ
or set code" maxLength={4} />
+
+ >}
+
+ {tab === "stats" && <>
+ {isCreature && <>
+
+
+ update("power", e.target.value)} placeholder="4" />
+
+
+ update("toughness", e.target.value)} placeholder="3" />
+
+
+ >}
+ {isPW && (
+
+ update("loyalty", e.target.value)} placeholder="4" />
+
+ )}
+ {!isCreature && !isPW && (
+
+ No stats for this card type. Switch to Creature or Planeswalker to edit stats.
+
+ )}
+
+
Quick Reset
+
+
+ >}
+
+
+
+ {/* Preview */}
+
+
Preview
+
+
+
+
+ Use the Print button to print on card stock.
+ Cut to 2.5" ร 3.5" for standard size.
+
+
+
+
+
+
+ );
+}