Initial commit: Interactives site

Astro-based site with 40+ interactive math games, puzzles, and explorations.
Includes admin dashboard, todo system, blog, theme/subcategory navigation,
and embed pages for iframe embedding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Neeldhara Misra 2026-04-17 03:09:40 +05:30
commit c5926b4213
265 changed files with 51899 additions and 0 deletions

View file

@ -0,0 +1,30 @@
---
import BaseHead from "@/components/BaseHead.astro";
import { Footer } from "@/components/sections/footer";
import Navbar from "@/components/sections/navbar";
const { title, description } = Astro.props;
---
<html lang="en">
<head>
<BaseHead title={title} description={description} />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
rel="stylesheet"
/>
</head>
<body class="h-screen antialiased">
<Navbar client:load />
<main>
<section class="mx-auto max-w-2xl px-4 py-16 md:py-28 lg:py-32">
<article class="prose prose-lg dark:prose-invert">
<slot />
</article>
</section>
</main>
<Footer />
</body>
</html>

View file

@ -0,0 +1,23 @@
---
import BaseHead from "@/components/BaseHead.astro";
import Banner from "@/components/sections/banner";
import { Footer } from "@/components/sections/footer";
import Navbar from "@/components/sections/navbar";
const { title, description } = Astro.props;
---
<html lang="en">
<head>
<BaseHead title={title} description={description} />
</head>
<body class="flex min-h-screen flex-col antialiased">
<Banner
client:load
url="https://www.shadcnblocks.com/template/hatch"
/>
<Navbar client:load />
<main class="w-full flex-1"><slot /></main>
<Footer />
</body>
</html>

View file

@ -0,0 +1,68 @@
---
import BaseHead from "@/components/BaseHead.astro";
interface Props {
title: string;
description: string;
}
const { title, description } = Astro.props;
---
<html lang="en">
<head>
<BaseHead title={title} description={description} />
<style>
.gs-lite {
background-color: #00ff00 !important;
}
.gs-lite * {
background-color: transparent !important;
border-color: #000000 !important;
color: #000000 !important;
}
.gs-lite button {
background-color: rgba(0, 0, 0, 0.1) !important;
border: 2px solid #000000 !important;
}
.gs-lite button:hover {
background-color: rgba(0, 0, 0, 0.2) !important;
}
.gs-lite input {
background-color: rgba(0, 0, 0, 0.05) !important;
border: 2px solid #000000 !important;
}
.gs-dark {
background-color: #00ff00 !important;
}
.gs-dark * {
background-color: transparent !important;
border-color: #ffffff !important;
color: #ffffff !important;
}
.gs-dark button {
background-color: rgba(255, 255, 255, 0.1) !important;
border: 2px solid #ffffff !important;
}
.gs-dark button:hover {
background-color: rgba(255, 255, 255, 0.2) !important;
}
.gs-dark input {
background-color: rgba(255, 255, 255, 0.05) !important;
border: 2px solid #ffffff !important;
}
</style>
</head>
<body class="min-h-screen bg-background antialiased">
<div id="embed-root" class="p-4 sm:p-8">
<slot />
</div>
<script is:inline>
const params = new URLSearchParams(window.location.search);
const mode = params.get('mode');
if (mode === 'gs-lite' || mode === 'gs-dark') {
document.getElementById('embed-root').classList.add(mode);
}
</script>
</body>
</html>

View file

@ -0,0 +1,61 @@
---
import BaseHead from "@/components/BaseHead.astro";
import { Footer } from "@/components/sections/footer";
import Navbar from "@/components/sections/navbar";
import SocialShare from "@/components/SocialShare";
import InteractiveBreadcrumb from "@/components/InteractiveBreadcrumb";
import AdminBar from "@/components/AdminBar";
import { Toaster } from "@/components/ui/toaster";
import type { InteractiveStatus } from "@/lib/interactives";
interface Props {
title: string;
description: string;
slug: string;
themes: string[];
subcategory?: string;
tags: string[];
status: InteractiveStatus;
}
const { title, description, slug, themes, subcategory, tags, status } = Astro.props;
const currentUrl = new URL(Astro.url.pathname, Astro.site).toString();
const embedUrl = new URL(`/embed/${slug}`, Astro.site).toString();
---
<html lang="en">
<head>
<BaseHead title={title} description={description} />
</head>
<body class="flex min-h-screen flex-col antialiased">
<Navbar client:load />
<main class="w-full flex-1">
<div class="container mx-auto px-4 py-6">
<InteractiveBreadcrumb
client:load
title={title}
themes={themes}
subcategory={subcategory}
/>
<AdminBar client:load slug={slug} currentStatus={status} />
<!-- Interactive content -->
<slot />
</div>
<!-- Share bar -->
<div class="container mx-auto px-4 pb-8">
<SocialShare
client:load
title={title}
description={description}
url={currentUrl}
embedUrl={embedUrl}
/>
</div>
</main>
<Toaster client:load />
<Footer />
</body>
</html>