diff --git a/Chrono/Chrono.sln b/Chrono/Chrono.sln
index e5463fe..91001c9 100644
--- a/Chrono/Chrono.sln
+++ b/Chrono/Chrono.sln
@@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build", "Build\Build.csproj
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "Model\Model.csproj", "{3358AF7A-603B-4BAC-A7F5-07978FB87843}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deploy", "Deploy\Deploy.csproj", "{E5E9A799-76C8-43B3-B9C2-3CAEC2B5E1DD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -24,5 +26,9 @@ Global
{3358AF7A-603B-4BAC-A7F5-07978FB87843}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3358AF7A-603B-4BAC-A7F5-07978FB87843}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3358AF7A-603B-4BAC-A7F5-07978FB87843}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E5E9A799-76C8-43B3-B9C2-3CAEC2B5E1DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E5E9A799-76C8-43B3-B9C2-3CAEC2B5E1DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E5E9A799-76C8-43B3-B9C2-3CAEC2B5E1DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E5E9A799-76C8-43B3-B9C2-3CAEC2B5E1DD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/Chrono/Deploy/Deploy.csproj b/Chrono/Deploy/Deploy.csproj
new file mode 100644
index 0000000..6c1dc92
--- /dev/null
+++ b/Chrono/Deploy/Deploy.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/Chrono/Deploy/Program.cs b/Chrono/Deploy/Program.cs
new file mode 100644
index 0000000..9eb0877
--- /dev/null
+++ b/Chrono/Deploy/Program.cs
@@ -0,0 +1,33 @@
+using System.Diagnostics;
+
+var deployDir = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", ".."));
+var webDir = Path.GetFullPath(Path.Combine(deployDir, "..", "Web"));
+var webProject = Path.Combine(webDir, "Web.csproj");
+var publishDir = Path.Combine(Path.GetTempPath(), "chrono-deploy", Guid.NewGuid().ToString());
+var deploymentToken = Environment.GetEnvironmentVariable("Chrono_DeployToken") ?? throw new InvalidOperationException("Chrono_DeployToken environment variable not set.");
+var deployEnv = Environment.GetEnvironmentVariable("Chrono_DeployEnv") ?? "preview";
+
+// 1. Publish
+Console.WriteLine("Publishing Web project...");
+Run("dotnet", $"publish \"{webProject}\" -c Release -o \"{publishDir}\"");
+
+var wwwroot = Path.Combine(publishDir, "wwwroot");
+if (!Directory.Exists(wwwroot))
+{
+ Console.Error.WriteLine("wwwroot not found in publish output.");
+ return 1;
+}
+
+// 2. Deploy
+Console.WriteLine("Deploying to Azure Static Web Apps...");
+Run("swa.cmd", $"deploy \"{wwwroot}\" --deployment-token \"{deploymentToken}\" --app-location \"{webDir}\" --env \"{deployEnv}\"");
+
+Console.WriteLine("Deploy successful!");
+return 0;
+
+static void Run(string fileName, string arguments)
+{
+ var process = Process.Start(new ProcessStartInfo(fileName, arguments) { UseShellExecute = false })!;
+ process.WaitForExit();
+ if (process.ExitCode != 0) { Environment.Exit(process.ExitCode); }
+}
\ No newline at end of file
diff --git a/Chrono/Web/Pages/Home.razor b/Chrono/Web/Pages/Home.razor
index dfcdf75..99b1f0a 100644
--- a/Chrono/Web/Pages/Home.razor
+++ b/Chrono/Web/Pages/Home.razor
@@ -1,7 +1,123 @@
@page "/"
-Home
+Slop Game Reference - Chrono CCG
-
Hello, world!
+
+
+
+
Collectible Card Game
+
Slop Game Reference - Chrono CCG
+
+ AI generated website for reference notes on playing Chrono CCG.
+
+
+
+
-Welcome to your new app.
\ No newline at end of file
+
+
+
+
+
+
+ @agentsCount
+ Agents
+
+
+
+
+
+
+
+ @spellsCount
+ Spells
+
+
+
+
+
+
+
+ @tokensCount
+ Tokens
+
+
+
+
+
+
+
+ @visibleDecks
+ Decks
+
+
+
+
+
+
+
+ @factionCount
+ Factions
+
+
+
+
+
+
+
+ @totalCount
+ Total Cards
+
+
+
+
+
+
+
+
Explore Cards
+
Browse the full gallery of @totalCount cards. Filter by faction, cost, or category, and dive into detailed stats, archetypes, and immortalize chains.
+
Browse Gallery
+
+
+
+
View Agents
+
All @agentsCount agents in a sortable data grid with filtering, paging, and detailed stats at a glance.
+
View Agents
+
+
+
+
Browse Decks
+
Check out @visibleDecks curated deck lists. See key cards, divers, and full card breakdowns with interactive previews.
+
Browse Decks
+
+
+
+@code {
+ private int totalCount;
+ private int agentsCount;
+ private int spellsCount;
+ private int tokensCount;
+ private int visibleDecks;
+ private int factionCount;
+
+ protected override void OnInitialized()
+ {
+ var cards = CardDatabase.Cards;
+ totalCount = cards.Count;
+ agentsCount = cards.Count(c => c.IsAgent);
+ spellsCount = cards.Count(c => c.IsSpell);
+ tokensCount = cards.Count(c => c.IsToken);
+ visibleDecks = DeckDatabase.Decks.Count(d => d.IsVisible);
+ factionCount = cards.Where(c => c.Faction != null).Select(c => c.Faction).Distinct().Count();
+ }
+}
\ No newline at end of file
diff --git a/Chrono/Web/Pages/Home.razor.css b/Chrono/Web/Pages/Home.razor.css
new file mode 100644
index 0000000..d045e31
--- /dev/null
+++ b/Chrono/Web/Pages/Home.razor.css
@@ -0,0 +1,248 @@
+/* ── Hero ── */
+.home-hero {
+ position: relative;
+ text-align: center;
+ padding: 4rem 1rem 3rem;
+ margin-bottom: 2.5rem;
+ overflow: hidden;
+}
+
+.hero-glow {
+ position: absolute;
+ top: -30%;
+ left: 50%;
+ width: 60rem;
+ height: 30rem;
+ transform: translateX(-50%);
+ background: radial-gradient(ellipse at center, rgba(108, 99, 255, 0.15) 0%, transparent 70%);
+ pointer-events: none;
+}
+
+.hero-content {
+ position: relative;
+ z-index: 1;
+ max-width: 42rem;
+ margin: 0 auto;
+}
+
+.hero-badge {
+ display: inline-block;
+ font-size: 0.75rem;
+ font-weight: 600;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--gold);
+ border: 1px solid rgba(255, 215, 0, 0.3);
+ background: rgba(255, 215, 0, 0.06);
+ padding: 0.3rem 0.9rem;
+ border-radius: 999px;
+ margin-bottom: 1.25rem;
+}
+
+.hero-title {
+ font-size: 3.5rem;
+ font-weight: 800;
+ margin: 0 0 1rem;
+ line-height: 1.1;
+ background: linear-gradient(135deg, #e8e8f0 0%, #6c63ff 50%, #ffd700 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.hero-subtitle {
+ font-size: 1.05rem;
+ line-height: 1.65;
+ color: var(--text-secondary);
+ margin: 0 0 2rem;
+ max-width: 34rem;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.hero-actions {
+ display: flex;
+ gap: 0.75rem;
+ justify-content: center;
+ flex-wrap: wrap;
+}
+
+.cta-button {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.45rem;
+ padding: 0.7rem 1.5rem;
+ border-radius: var(--radius-sm);
+ font-size: 0.9rem;
+ font-weight: 600;
+ text-decoration: none;
+ transition: all var(--transition);
+}
+
+.cta-button.primary {
+ background: var(--accent);
+ color: #fff;
+ box-shadow: 0 0 20px var(--accent-glow);
+}
+
+.cta-button.primary:hover {
+ background: #7b73ff;
+ box-shadow: 0 0 30px var(--accent-glow);
+ transform: translateY(-1px);
+}
+
+.cta-button.secondary {
+ background: var(--bg-elevated);
+ color: var(--text-primary);
+ border: 1px solid var(--border);
+}
+
+.cta-button.secondary:hover {
+ background: var(--bg-hover);
+ border-color: var(--accent);
+ transform: translateY(-1px);
+}
+
+/* ── Stats ── */
+.home-stats {
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 0.75rem;
+ max-width: 56rem;
+ margin: 0 auto 3rem;
+}
+
+.stat-card {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ background: var(--bg-surface);
+ border: 1px solid var(--border);
+ border-radius: var(--radius);
+ padding: 1rem;
+ transition: all var(--transition);
+}
+
+.stat-card:hover {
+ background: var(--bg-elevated);
+ border-color: var(--accent);
+ transform: translateY(-2px);
+ box-shadow: var(--shadow);
+}
+
+.stat-icon {
+ width: 2.5rem;
+ height: 2.5rem;
+ border-radius: var(--radius-sm);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.1rem;
+ flex-shrink: 0;
+}
+
+.stat-icon.agents { background: rgba(108, 99, 255, 0.15); color: var(--accent); }
+.stat-icon.spells { background: rgba(255, 215, 0, 0.12); color: var(--gold); }
+.stat-icon.tokens { background: rgba(0, 200, 150, 0.15); color: #00c896; }
+.stat-icon.decks { background: rgba(255, 120, 80, 0.15); color: #ff7850; }
+.stat-icon.factions { background: rgba(100, 200, 255, 0.15); color: #64c8ff; }
+.stat-icon.total { background: rgba(200, 150, 255, 0.15); color: #c896ff; }
+
+.stat-body {
+ display: flex;
+ flex-direction: column;
+}
+
+.stat-value {
+ font-size: 1.3rem;
+ font-weight: 700;
+ line-height: 1.2;
+ color: var(--text-primary);
+}
+
+.stat-label {
+ font-size: 0.72rem;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+ color: var(--text-muted);
+}
+
+/* ── Section Cards ── */
+.home-sections {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 1.25rem;
+ max-width: 56rem;
+ margin: 0 auto;
+}
+
+.section-card {
+ background: var(--bg-surface);
+ border: 1px solid var(--border);
+ border-radius: var(--radius);
+ padding: 2rem 1.5rem;
+ transition: all var(--transition);
+}
+
+.section-card:hover {
+ background: var(--bg-elevated);
+ border-color: var(--accent);
+ transform: translateY(-3px);
+ box-shadow: var(--shadow);
+}
+
+.section-icon {
+ width: 3rem;
+ height: 3rem;
+ border-radius: var(--radius);
+ background: rgba(108, 99, 255, 0.1);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.3rem;
+ color: var(--accent);
+ margin-bottom: 1rem;
+}
+
+.section-card h2 {
+ font-size: 1.15rem;
+ margin: 0 0 0.5rem;
+ color: var(--text-primary);
+}
+
+.section-card p {
+ font-size: 0.85rem;
+ line-height: 1.55;
+ color: var(--text-secondary);
+ margin: 0 0 1.25rem;
+}
+
+.section-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ font-size: 0.85rem;
+ font-weight: 600;
+ color: var(--accent);
+ text-decoration: none;
+ transition: gap var(--transition);
+}
+
+.section-link:hover {
+ gap: 0.6rem;
+ color: #7b73ff;
+}
+
+/* ── Responsive ── */
+@@media (max-width: 900px) {
+ .home-stats { grid-template-columns: repeat(3, 1fr); }
+ .home-sections { grid-template-columns: 1fr; }
+}
+
+@@media (max-width: 600px) {
+ .hero-title { font-size: 2.2rem; }
+ .hero-subtitle { font-size: 0.95rem; }
+ .hero-actions { flex-direction: column; align-items: center; }
+ .cta-button { width: 100%; justify-content: center; }
+ .home-stats { grid-template-columns: repeat(2, 1fr); }
+}
\ No newline at end of file