Start the rebuild: note schema, vault kit and data migration

Phase 1 of the functional design plan.

- Move the old site into legacy/, unchanged, for reference. It still
  builds from there until cutover.
- Add packages/schema: the one definition of all 20 note types, with
  field titles and descriptions, note and vault checks, and JSON Schema
  export so later editing tools and the MCP server share it.
- Add vault-kit: Obsidian templates generated from the schema, and the
  Site guide for 24.01_PersonalWebsite.
- Add tools/migrate: turns the legacy JSON, collections, store data and
  page text into 545 Site folder notes and 84 images, and checks the
  result with the schema.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
This commit is contained in:
Claude
2026-10-11 18:40:55 +00:00
parent 4ded4b277b
commit a2f723ca2d
324 changed files with 11538 additions and 7556 deletions
+6 -15
View File
@@ -1,30 +1,21 @@
# build output
dist/
.output/
# dependencies
node_modules/
# generated types
.astro/
# migration output (it goes into the vault, not the repo)
out/
# generated from the schema
packages/schema/json/
# environment
.env
.env.*
!.env.example
# logs
# logs and editor files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# macOS / editor
.DS_Store
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea/
# misc
*.local
+28 -143
View File
@@ -1,156 +1,41 @@
# Greg Kilmer — Profile & Portfolio Site
# GregKilmer.com
A responsive, content-driven personal site for Greg Kilmer, built as **two wings
of the same house**: a polished professional resume/portfolio on one side, and a
warm, personality-driven interests hub on the other.
The site, rebuilt around Greg's Obsidian vault. Notes in the vault's Site
folder are the content; a content service checks every change and keeps the
last good version; the site serves pages from that service. The full plan,
with the decisions behind it, is the
[Functional Design Plan](https://claude.ai/code/artifact/2a4e8339-7887-4919-a51d-2c11547b80b3).
Built with **Astro 7 + React Islands + TypeScript**, served by a **Node server**
with API routes, ready to deploy as a container on a homelab Cosmos system.
## What is here
---
| Path | What it is |
| --- | --- |
| `packages/schema` | The one definition of every note type: fields, folders, file names, and the checks for one note and for the whole folder. The migration, the content service, the MCP server, the site and any later editing tool all use it. |
| `vault-kit` | What goes into the vault: the Obsidian templates (generated from the schema) and the Site guide. |
| `tools/migrate` | The one-time migration from the old site's data into Site folder notes. |
| `docs` | How the pieces fit. Start with [docs/content-model.md](docs/content-model.md). |
| `legacy` | The old site, kept for reference only. Nothing outside it imports from it except the migration. |
## Highlights
Coming in later phases: `services/content` (the content service and its MCP
server), the admin page, and the new site.
- **Astro 7** static-first core with React Islands for interactivity (mobile
menu, theme toggle, animated hero background, contact form).
- **Node backend** (`@astrojs/node`, standalone) with a typed `/api/contact`
endpoint (SMTP via nodemailer + webhook fallback, Zod validation, rate limit).
- **Section-aware theming**: the Professional wing reads dark/polished, the
Interests wing reads warm/inviting, plus a global light/dark toggle.
- **Rich motion**: animated mesh-gradient hero with an optional canvas particle
field, IntersectionObserver scroll reveals, View Transitions page swaps,
scroll-triggered nav blur. All `prefers-reduced-motion` aware.
- **Content Collections** (typed): add projects and experience by dropping
markdown/MDX files.
- **mdi icons everywhere** (no emojis, per the spec), inlined at build time from
`@iconify-json/mdi` for zero runtime cost.
- **Self-hosted variable fonts** (Inter, Plus Jakarta Sans, JetBrains Mono).
- **Accessible**: semantic landmarks, skip link, keyboard-operable menu,
focus-visible rings, ARIA on interactive bits, WCAG-AA contrast targets.
- **Deploy artifacts**: multi-stage `Dockerfile` + `docker-compose.yml`.
## Commands
---
Node 22 or newer.
## Quickstart
```bash
# 1. Install dependencies (Node 20+)
```sh
npm install
# 2. Start the dev server with hot reload
npm run dev
# -> http://localhost:4321
# 3. Production build (runs astro check + build)
npm run build
# 4. Run the built Node server
npm run serve
# -> http://localhost:4321
npm run check # typecheck and tests
npm run migrate # writes out/24.01_PersonalWebsite and out/MIGRATION-REPORT.md
npm run templates # regenerates vault-kit templates after a schema change
npm run schema:json # writes a JSON Schema per note type to packages/schema/json/
```
Environment is optional for local dev. To enable contact-form delivery, copy
`.env.example` to `.env` and fill in SMTP or webhook vars (see
[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)).
## The old site
---
## Project structure
The live site still runs from the old code until cutover. It builds the same
way as before, from inside `legacy/`:
```sh
cd legacy && docker compose up -d --build
```
src/
├── components/
│ ├── hero/ AnimatedBackground.tsx (gradient + canvas particles)
│ ├── motion/ Reveal.astro (IntersectionObserver scroll reveals)
│ ├── nav/ NavBar.astro, MobileMenu.tsx, ThemeToggle.tsx
│ ├── cards/ InterestCard.astro
│ ├── professional/ Timeline, SkillGrid, ProjectCard, SectionNav, ContactForm
│ ├── layout/ Footer, SectionHeader, SplitTransition, InterestHero,
│ │ RelatedInterests, Placeholder
│ └── Icon.astro Inline mdi icon renderer (build-time)
├── content/
│ ├── projects/ Project collection entries (markdown/MDX)
│ └── experience/ Experience collection entries
├── layouts/
│ └── BaseLayout.astro <html> shell, head, fonts, theme init, nav, footer
├── pages/
│ ├── index.astro Home (hero + snapshot grid)
│ ├── about.astro About + split transition fork
│ ├── professional/index.astro Single long page: Summary, Experience,
│ │ Skills, Projects, Education, Contact
│ ├── interests/ Hub + 5 sub-pages
│ │ ├── index.astro
│ │ ├── ttrpgs / gaming / reading / making / pokemon .astro
│ ├── contact.astro Two-column connect page + contact form
│ └── api/contact.ts POST endpoint -> SMTP / webhook
├── content.config.ts Collection schemas (projects, experience)
├── lib/ site.ts (nav/socials), motion.ts, content helpers
├── styles/ global.css, themes.css, animations.css
└── scripts/theme-init.ts No-FOUC theme boot (inlined in <head>)
```
---
## The two wings (theming model)
Theming has two independent axes (see [docs/THEMING.md](docs/THEMING.md)):
1. **Global light/dark** on `<html data-theme>`, set before paint by an inline
script, persisted to `localStorage`, toggleable via the nav button.
2. **Section tone** via `data-surface` on `<body>`:
- `neutral` (Home/About/Contact) — balanced middle ground
- `professional` — dark slate, polished
- `interest` — warm cream/amber, inviting
Components only reference semantic CSS variables (`--surface`, `--text`,
`--accent`...), so changing either axis restyles everything automatically.
---
## Adding content
- **Projects / Experience:** drop a markdown or MDX file in
`src/content/projects/` or `src/content/experience/`. Schemas and field
reference are in [docs/CONTENT.md](docs/CONTENT.md).
- **Interest pages:** hand-built `.astro` files under `src/pages/interests/`,
each following the spec's template (Header, Overview, Highlights, Currently,
Related). Edit copy in place.
- **Placeholders:** every `[Greg to fill]` gap from the spec is a styled
`Placeholder` slot with a TODO badge so you can find and replace them.
---
## Deployment (Cosmos homelab)
The site runs as a Node server inside a container. Full walkthrough in
[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md):
```bash
docker compose up -d --build
# Then point your reverse proxy at port 4321 with TLS for gregkilmer.com.
```
---
## Scripts
| Script | Description |
| ----------------- | ----------------------------------------------------- |
| `npm run dev` | Dev server with hot reload |
| `npm run build` | Type-check (`astro check`) then build the Node server |
| `npm run serve` | Run the built server (`dist/server/entry.mjs`) |
| `npm run preview` | Preview the build locally |
| `npm run check` | Type-check only |
---
## Tech stack
Astro 7, React 19, TypeScript 6, Tailwind CSS v4, Framer Motion, nodemailer,
Zod, `@iconify-json/mdi`, Fontsource variable fonts, `@astrojs/node` standalone.
---
## License
Personal site for Greg Kilmer. All rights reserved.
+48
View File
@@ -0,0 +1,48 @@
# Content model
Everything the site shows is a Markdown note with YAML frontmatter in the
vault at `20-29_Makerspace/24_Homelab_Infrastructure/24.01_PersonalWebsite/Site/`.
`24.02_PatiunWebsite` is reserved for the Patiun site later.
## Rules every note follows
- A note's `type` field says what it is. The types, their fields and their
folders are defined once, in `packages/schema/src/types.ts`.
- A note is live only when `publish: true`. Missing means false.
- Links between notes are Obsidian wikilinks, `[[Note name]]`, in frontmatter
or in the body. A link resolves by file name, so file names are unique across
the whole Site folder.
- Images live in `Site/_attachments/` and are linked the same way,
`[[galaxy-dice.jpg]]`, or are full https URLs.
- Folders starting with `_` hold templates and attachments, never notes.
Files starting with `_` are single settings notes: `_site.md`,
`Now/_kinds.md`, `Store/_settings.md`.
- Slugs come from the title unless a note sets `slug`. They are unique within
a type.
## Note types
| Type | Folder | Notes |
| --- | --- | --- |
| `post` | `Posts/` | Blog posts. `postType: case study` also appears on the Work page. |
| `library-item` | `Library/<Medium>/` | Books, light novels, webnovels, manga, manhwa, video games, anime, TV, movies. |
| `board-game` | `Shelf/` | The Shelf. Players and play time sync from BoardGameGeek by `bggId`. |
| `craft`, `station`, `tool`, `make` | `Workshop/…` | The Workshop. |
| `tabletop-system`, `campaign`, `card-game`, `deck` | `Tabletop/…` | Tabletop. Magic decks sync from Archidekt. |
| `experience`, `skills`, `education` | `Resume/…` | The resume page and its PDF. |
| `status`, `status-kinds` | `Now/` | The status log behind Now, the Landing strip and Now chips. |
| `product-line`, `store-settings` | `Store/…` | The Store. |
| `site-settings` | `_site.md` | Name, tagline, location and social links. |
| `page` | `Pages/` | The written introduction for a page. |
Each field's title and description live in the schema too, so the
JSON Schema export (`npm run schema:json`) can drive a form or explain a field
to an agent.
## Designed for editing tools
The content service will be the only writer apart from Obsidian. It will
expose one write API, built on the schema's `checkNote`, `writeNote` and
`checkVault`. The MCP server for agents is one client of that API; the admin
page is another; any editing tool built later is a third. None of them define
fields or rules of their own.
+30
View File
@@ -0,0 +1,30 @@
# build output
dist/
.output/
# dependencies
node_modules/
# generated types
.astro/
# environment
.env
.env.*
!.env.example
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# macOS / editor
.DS_Store
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea/
# misc
*.local
View File
+7
View File
@@ -0,0 +1,7 @@
# Legacy site
The GregKilmer.com site as it was before the 2026 rebuild, kept for reference.
It still runs the live site until cutover, built from this folder.
Do not add features here. Its data was migrated into vault notes by
`tools/migrate`; new content goes into the vault.
+156
View File
@@ -0,0 +1,156 @@
# Greg Kilmer — Profile & Portfolio Site
A responsive, content-driven personal site for Greg Kilmer, built as **two wings
of the same house**: a polished professional resume/portfolio on one side, and a
warm, personality-driven interests hub on the other.
Built with **Astro 7 + React Islands + TypeScript**, served by a **Node server**
with API routes, ready to deploy as a container on a homelab Cosmos system.
---
## Highlights
- **Astro 7** static-first core with React Islands for interactivity (mobile
menu, theme toggle, animated hero background, contact form).
- **Node backend** (`@astrojs/node`, standalone) with a typed `/api/contact`
endpoint (SMTP via nodemailer + webhook fallback, Zod validation, rate limit).
- **Section-aware theming**: the Professional wing reads dark/polished, the
Interests wing reads warm/inviting, plus a global light/dark toggle.
- **Rich motion**: animated mesh-gradient hero with an optional canvas particle
field, IntersectionObserver scroll reveals, View Transitions page swaps,
scroll-triggered nav blur. All `prefers-reduced-motion` aware.
- **Content Collections** (typed): add projects and experience by dropping
markdown/MDX files.
- **mdi icons everywhere** (no emojis, per the spec), inlined at build time from
`@iconify-json/mdi` for zero runtime cost.
- **Self-hosted variable fonts** (Inter, Plus Jakarta Sans, JetBrains Mono).
- **Accessible**: semantic landmarks, skip link, keyboard-operable menu,
focus-visible rings, ARIA on interactive bits, WCAG-AA contrast targets.
- **Deploy artifacts**: multi-stage `Dockerfile` + `docker-compose.yml`.
---
## Quickstart
```bash
# 1. Install dependencies (Node 20+)
npm install
# 2. Start the dev server with hot reload
npm run dev
# -> http://localhost:4321
# 3. Production build (runs astro check + build)
npm run build
# 4. Run the built Node server
npm run serve
# -> http://localhost:4321
```
Environment is optional for local dev. To enable contact-form delivery, copy
`.env.example` to `.env` and fill in SMTP or webhook vars (see
[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)).
---
## Project structure
```
src/
├── components/
│ ├── hero/ AnimatedBackground.tsx (gradient + canvas particles)
│ ├── motion/ Reveal.astro (IntersectionObserver scroll reveals)
│ ├── nav/ NavBar.astro, MobileMenu.tsx, ThemeToggle.tsx
│ ├── cards/ InterestCard.astro
│ ├── professional/ Timeline, SkillGrid, ProjectCard, SectionNav, ContactForm
│ ├── layout/ Footer, SectionHeader, SplitTransition, InterestHero,
│ │ RelatedInterests, Placeholder
│ └── Icon.astro Inline mdi icon renderer (build-time)
├── content/
│ ├── projects/ Project collection entries (markdown/MDX)
│ └── experience/ Experience collection entries
├── layouts/
│ └── BaseLayout.astro <html> shell, head, fonts, theme init, nav, footer
├── pages/
│ ├── index.astro Home (hero + snapshot grid)
│ ├── about.astro About + split transition fork
│ ├── professional/index.astro Single long page: Summary, Experience,
│ │ Skills, Projects, Education, Contact
│ ├── interests/ Hub + 5 sub-pages
│ │ ├── index.astro
│ │ ├── ttrpgs / gaming / reading / making / pokemon .astro
│ ├── contact.astro Two-column connect page + contact form
│ └── api/contact.ts POST endpoint -> SMTP / webhook
├── content.config.ts Collection schemas (projects, experience)
├── lib/ site.ts (nav/socials), motion.ts, content helpers
├── styles/ global.css, themes.css, animations.css
└── scripts/theme-init.ts No-FOUC theme boot (inlined in <head>)
```
---
## The two wings (theming model)
Theming has two independent axes (see [docs/THEMING.md](docs/THEMING.md)):
1. **Global light/dark** on `<html data-theme>`, set before paint by an inline
script, persisted to `localStorage`, toggleable via the nav button.
2. **Section tone** via `data-surface` on `<body>`:
- `neutral` (Home/About/Contact) — balanced middle ground
- `professional` — dark slate, polished
- `interest` — warm cream/amber, inviting
Components only reference semantic CSS variables (`--surface`, `--text`,
`--accent`...), so changing either axis restyles everything automatically.
---
## Adding content
- **Projects / Experience:** drop a markdown or MDX file in
`src/content/projects/` or `src/content/experience/`. Schemas and field
reference are in [docs/CONTENT.md](docs/CONTENT.md).
- **Interest pages:** hand-built `.astro` files under `src/pages/interests/`,
each following the spec's template (Header, Overview, Highlights, Currently,
Related). Edit copy in place.
- **Placeholders:** every `[Greg to fill]` gap from the spec is a styled
`Placeholder` slot with a TODO badge so you can find and replace them.
---
## Deployment (Cosmos homelab)
The site runs as a Node server inside a container. Full walkthrough in
[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md):
```bash
docker compose up -d --build
# Then point your reverse proxy at port 4321 with TLS for gregkilmer.com.
```
---
## Scripts
| Script | Description |
| ----------------- | ----------------------------------------------------- |
| `npm run dev` | Dev server with hot reload |
| `npm run build` | Type-check (`astro check`) then build the Node server |
| `npm run serve` | Run the built server (`dist/server/entry.mjs`) |
| `npm run preview` | Preview the build locally |
| `npm run check` | Type-check only |
---
## Tech stack
Astro 7, React 19, TypeScript 6, Tailwind CSS v4, Framer Motion, nodemailer,
Zod, `@iconify-json/mdi`, Fontsource variable fonts, `@astrojs/node` standalone.
---
## License
Personal site for Greg Kilmer. All rights reserved.
+8470
View File
File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
{
"name": "greg-kilmer-profile",
"version": "1.0.0",
"type": "module",
"private": true,
"description": "Personal profile / portfolio website for Greg Kilmer. Astro + React Islands + Node server.",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"serve": "node ./dist/server/entry.mjs",
"astro": "astro",
"check": "astro check",
"typecheck": "astro check && tsc --noEmit"
},
"dependencies": {
"@astrojs/check": "^0.9.9",
"@astrojs/mdx": "^7.0.2",
"@astrojs/node": "^11.0.2",
"@astrojs/react": "^6.0.2",
"@fontsource-variable/cinzel": "^5.3.0",
"@fontsource-variable/jetbrains-mono": "^5.2.8",
"@fontsource-variable/montserrat": "^5.3.0",
"@iconify-json/mdi": "^1.2.3",
"@tailwindcss/vite": "^4.3.2",
"@types/nodemailer": "^8.0.1",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"astro": "^7.2.0",
"framer-motion": "^12.42.2",
"nodemailer": "^9.0.3",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"tailwindcss": "^4.3.2",
"typescript": "^6.0.3",
"zod": "^4.4.3"
}
}

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 132 KiB

Before

Width:  |  Height:  |  Size: 434 KiB

After

Width:  |  Height:  |  Size: 434 KiB

Before

Width:  |  Height:  |  Size: 874 KiB

After

Width:  |  Height:  |  Size: 874 KiB

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Before

Width:  |  Height:  |  Size: 516 KiB

After

Width:  |  Height:  |  Size: 516 KiB

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Before

Width:  |  Height:  |  Size: 669 KiB

After

Width:  |  Height:  |  Size: 669 KiB

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Before

Width:  |  Height:  |  Size: 225 KiB

After

Width:  |  Height:  |  Size: 225 KiB

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Before

Width:  |  Height:  |  Size: 171 KiB

After

Width:  |  Height:  |  Size: 171 KiB

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Before

Width:  |  Height:  |  Size: 512 KiB

After

Width:  |  Height:  |  Size: 512 KiB

Before

Width:  |  Height:  |  Size: 615 KiB

After

Width:  |  Height:  |  Size: 615 KiB

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Before

Width:  |  Height:  |  Size: 207 KiB

After

Width:  |  Height:  |  Size: 207 KiB

Before

Width:  |  Height:  |  Size: 290 KiB

After

Width:  |  Height:  |  Size: 290 KiB

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 204 KiB

Before

Width:  |  Height:  |  Size: 277 KiB

After

Width:  |  Height:  |  Size: 277 KiB

Before

Width:  |  Height:  |  Size: 937 KiB

After

Width:  |  Height:  |  Size: 937 KiB

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Before

Width:  |  Height:  |  Size: 401 KiB

After

Width:  |  Height:  |  Size: 401 KiB

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Before

Width:  |  Height:  |  Size: 169 KiB

After

Width:  |  Height:  |  Size: 169 KiB

Before

Width:  |  Height:  |  Size: 211 KiB

After

Width:  |  Height:  |  Size: 211 KiB

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before

Width:  |  Height:  |  Size: 658 KiB

After

Width:  |  Height:  |  Size: 658 KiB

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 248 KiB

Before

Width:  |  Height:  |  Size: 625 KiB

After

Width:  |  Height:  |  Size: 625 KiB

Before

Width:  |  Height:  |  Size: 874 KiB

After

Width:  |  Height:  |  Size: 874 KiB

Before

Width:  |  Height:  |  Size: 315 KiB

After

Width:  |  Height:  |  Size: 315 KiB

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Before

Width:  |  Height:  |  Size: 665 KiB

After

Width:  |  Height:  |  Size: 665 KiB

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 262 KiB

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Before

Width:  |  Height:  |  Size: 336 KiB

After

Width:  |  Height:  |  Size: 336 KiB

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 181 KiB

Before

Width:  |  Height:  |  Size: 909 KiB

After

Width:  |  Height:  |  Size: 909 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 217 KiB

After

Width:  |  Height:  |  Size: 217 KiB

Some files were not shown because too many files have changed in this diff Show More