import React, { useState, useEffect } from "react";
import { motion } from "framer-motion";
// Snowy - Single-file React component
// Requirements: TailwindCSS configured in your project and framer-motion installed
// Save as SnowyPage.jsx and include in your app (e.g. App.jsx -> )
// Image used: https://cdn.discordapp.com/avatars/1308988260852437044/bb54beb3e09e6b2ea1274f8a7826d68e.png?size=1024
export default function SnowyPage() {
const defaultContent = {
name: "Snowy",
tagline: "Friendly furry adventurer & storyteller",
bio:
"Snowy is a playful, creative fursona who loves late-night stargazing, cozy cafés, and pixel art. This site showcases Snowy's art, stories, and links to socials.",
highlights: [
"Illustration",
"Short stories",
"Commissions open",
"Cosplay guides",
],
};
const [content, setContent] = useState(() => {
try {
const raw = localStorage.getItem("snowy_content");
return raw ? JSON.parse(raw) : defaultContent;
} catch (e) {
return defaultContent;
}
});
const [editing, setEditing] = useState(false);
const [dark, setDark] = useState(() => {
const cached = localStorage.getItem("snowy_theme");
return cached ? cached === "dark" : true;
});
useEffect(() => {
document.documentElement.classList.toggle("dark", dark);
localStorage.setItem("snowy_theme", dark ? "dark" : "light");
}, [dark]);
useEffect(() => {
localStorage.setItem("snowy_content", JSON.stringify(content));
}, [content]);
function onEditField(field, value) {
setContent((c) => ({ ...c, [field]: value }));
}
return (
{content.name}
{content.tagline}
About {content.name}
Last edited: auto
Gallery
A few example images and sketches.
{Array.from({ length: 8 }).map((_, i) => (
))}
Stories
Night Train (short)
Snowy took the midnight train and found a constellation only visible from the caboose...
Paper Crowns
A cozy story about rainy afternoons and secret maps drawn in the margins of library books.
);
}