# blweb · Personal Blog > Still water runs deep — ink dissolves in silence. A personal blog built with React + Vite, combining Japanese minimalist aesthetics with glassmorphism design. No backend required, ready to deploy as static files. [中文版 →](./README.md) --- ## Features - **Japanese minimalist style** — sakura palette, kanji watermarks, manuscript grid backgrounds - **Glassmorphism cards** — rounded corners with `backdrop-filter` frosted glass effect - **Light / dark theme toggle** — persisted to `localStorage` - **Sakura petal animation** — Canvas petals drift on every route transition - **Admin panel** — PIN-protected; create, edit, and delete articles - **Rich text editor** — toolbar with bold, italic, headings, blockquotes, and image insertion (URL or local file → base64) - **Client-side search** — real-time filtering, no server needed - **No backend** — all data stored in `localStorage`; deploy anywhere as static files ## Tech Stack | Tech | Purpose | |------|---------| | React 18 | UI framework | | Vite | Build tool | | React Router v6 | Client-side routing | | CSS Modules + Custom Properties | Styling & theme system | | localStorage | Data persistence | ## Getting Started ```bash # Install dependencies npm install # Start development server npm run dev # Build for production npm run build ``` Open `http://localhost:5173` in your browser. ## Project Structure ``` src/ ├── components/ │ ├── admin/ # Admin panel (PIN gate, editor, toolbar) │ ├── article/ # Article components (card, grid, body) │ ├── layout/ # Layout (Header, Footer, AppShell) │ └── ui/ # Shared UI (theme toggle, search, tags, petal canvas) ├── contexts/ # React Contexts (theme, article data) ├── pages/ # Page components ├── styles/ # Global styles, design tokens, animations └── utils/ # Helpers (search, date formatting, slug generation) ``` ## Routes | Path | Page | |------|------| | `/` | Home (article list) | | `/article/:slug` | Article detail | | `/about` | About me | | `/admin` | Admin panel (PIN required) | | `/admin/new` | Create article | | `/admin/edit/:slug` | Edit article | ## Admin Panel Navigate to `/admin`. The default PIN is `2501`. To change it, update the `CORRECT_PIN` constant in [`src/components/admin/AdminGate.jsx`](src/components/admin/AdminGate.jsx). ## Deployment **Netlify**: `public/_redirects` is already configured for SPA routing. Drag and drop the `dist/` folder. **GitHub Pages / other static hosts**: After `npm run build`, copy `dist/index.html` to `dist/404.html`. ## License MIT