Go to file
jamey b7ec41b0cf refactor admin CSS: replace utility classes with semantic styles
Replace Tailwind utility soup across admin templates with semantic
CSS classes. Add layout primitives (stack, row, cluster, grid),
extract JS transition helpers into transitions.css, and refactor
core_components, layouts, settings, newsletter, order_show, providers,
and theme editor templates.

Utility occurrences reduced from 290+ to 127 across admin files.
All 1679 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 17:15:25 +00:00
.gitea/workflows switch deploy workflow to local docker build 2026-02-20 18:58:14 +00:00
assets refactor admin CSS: replace utility classes with semantic styles 2026-03-01 17:15:25 +00:00
config add activity log with order timeline and global feed 2026-03-01 15:09:08 +00:00
docs tidy docs: condense progress, trim readme, mark plan statuses 2026-03-01 17:15:18 +00:00
lib refactor admin CSS: replace utility classes with semantic styles 2026-03-01 17:15:25 +00:00
priv add activity log with order timeline and global feed 2026-03-01 15:09:08 +00:00
rel rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
test add activity log with order timeline and global feed 2026-03-01 15:09:08 +00:00
.credo.exs add CI pipeline with credo and dialyzer 2026-02-08 15:19:42 +00:00
.dialyzer_ignore.exs rename project from SimpleshopTheme to Berrypod 2026-02-18 21:23:15 +00:00
.dockerignore fix production deployment: CSS, images and theme seeding 2026-02-08 23:42:56 +00:00
.formatter.exs mix phx.new simpleshop_theme --database sqlite3 --adapter bandit --binary-id 2025-12-30 12:26:26 +00:00
.gitignore remove accidentally tracked node_modules, update gitignore 2026-02-18 21:23:42 +00:00
.mcp.json chore: add MCP config for Claude Code + Tidewave integration 2026-01-31 13:49:07 +00:00
AGENTS.md docs: consolidate project tracking into PROGRESS.md 2026-01-31 14:06:07 +00:00
CLAUDE.md tidy docs: condense progress, trim readme, mark plan statuses 2026-03-01 17:15:18 +00:00
Dockerfile use Oban for startup variant processing, add vips-heif 2026-02-22 09:24:34 +00:00
fly.toml keep one machine always running on Fly 2026-02-22 09:24:38 +00:00
mise.toml feat: add cart page, cart drawer, and shared cart infrastructure 2026-02-06 19:39:37 +00:00
mix.exs add admin page editor with block reordering and management 2026-02-26 21:15:01 +00:00
mix.lock add admin page editor with block reordering and management 2026-02-26 21:15:01 +00:00
PROGRESS.md tidy docs: condense progress, trim readme, mark plan statuses 2026-03-01 17:15:18 +00:00
README.md tidy docs: condense progress, trim readme, mark plan statuses 2026-03-01 17:15:18 +00:00
ROADMAP.md tidy docs: condense progress, trim readme, mark plan statuses 2026-03-01 17:15:18 +00:00

Berrypod

A customisable e-commerce storefront for print-on-demand sellers, built with Phoenix LiveView. Professional shops without design expertise, privacy-respecting by default, fully self-hostable.

Features

Shop

Complete storefront with all the pages you need:

  • Home — hero banner, category navigation, featured products, newsletter
  • Products — grid layout with hover effects, sorting, filtering by collection
  • Product detail — image gallery with per-colour filtering, variant selector, related products
  • Cart — drawer + full page, quantity controls, shipping estimate, cross-tab sync
  • Checkout — Stripe-hosted checkout with shipping costs, order confirmation
  • Custom pages — CMS pages at any URL with 26 block types
  • Legal pages — auto-generated privacy, delivery, and terms from actual shop settings
  • Search — FTS5 full-text search with live modal, keyboard nav, ARIA
  • Contact — contact form with order status lookup

Admin

  • Theme editor — 8 presets, real-time preview, comprehensive customisation
  • Page builder — drag-free block editor with undo/redo, live editing on shop pages
  • Analytics — privacy-first, cookie-free, comparison mode, CSV export
  • Orders — status tracking, fulfilment timeline, provider submission
  • Media library — image management with alt text, usage tracking, orphan detection
  • Activity log — global event feed, "needs attention" tab, contextual retry
  • URL redirects — auto-redirect on slug change, 404 monitoring, dead link scanning
  • Email settings — 10 adapter options, test email, env var precedence
  • Print providers — Printify + Printful with sync, orders, shipping, webhooks

Technical highlights

  • Hand-written CSS with three-layer architecture (9.8 KB gzipped shop, 17.8 KB admin)
  • SQLite with BLOB storage, IMMEDIATE transactions, WAL, mmap
  • Image optimisation pipeline (AVIF/WebP/JPEG responsive variants via Oban)
  • ETS caching for CSS, pages, redirects, favicons
  • 99-100 PageSpeed mobile, no-JS support across all key flows
  • 1679+ tests, CI with credo + dialyzer

Getting started

Prerequisites

  • Elixir 1.19+
  • Erlang/OTP 28+
  • Node.js 20+ (for esbuild asset bundling)

Setup

git clone <repo-url>
cd berrypod
mix setup       # install deps, create DB, run migrations, build assets
mix phx.server  # start dev server at localhost:4000

Visit http://localhost:4000/setup to create your admin account and connect a print provider.

Running tests

mix test              # all tests
mix test path/to.exs  # specific file
mix precommit         # compile warnings + format + test (run before committing)

Project structure

lib/berrypod/                    # core business logic
├── accounts.ex                  # user accounts + auth
├── analytics.ex                 # privacy-first pageview tracking
├── activity_log.ex              # system event logging
├── cart.ex                      # session-based cart
├── media.ex                     # image uploads, optimisation, media library
├── newsletter.ex                # email list + campaigns
├── orders.ex                    # order lifecycle + fulfilment
├── pages.ex                     # page builder (blocks, cache, defaults)
├── products.ex                  # products, variants, categories
├── providers.ex                 # POD provider abstraction (Printify, Printful)
├── redirects.ex                 # URL redirects + dead link monitoring
├── search.ex                    # FTS5 full-text search
├── settings.ex                  # theme + shop settings
├── shipping.ex                  # shipping rates + country detection
├── theme/                       # CSS generation, presets, ETS cache
└── workers/                     # Oban background jobs

lib/berrypod_web/                # web layer
├── components/
│   ├── layouts/                 # app, admin, and shop layouts
│   ├── shop_components/         # shop UI (product cards, cart, gallery, etc.)
│   └── block_editor_components.ex
├── live/
│   ├── admin/                   # admin LiveViews (orders, pages, media, etc.)
│   ├── shop/                    # shop LiveViews (home, collection, product, etc.)
│   └── auth/                    # authentication
├── page_renderer.ex             # generic block-to-component dispatch
└── controllers/                 # Stripe webhooks, favicons, images, cart API

assets/css/
├── shop/                        # shop component styles
├── admin/                       # admin component styles
├── theme-layer1-primitives.css  # design tokens
├── theme-layer2-attributes.css  # theme-specific values
└── theme-layer3-semantic.css    # component styles

Stripe setup

  1. Create a Stripe account
  2. Navigate to Admin > Settings in your shop
  3. Paste your secret key and click "Connect Stripe"

For local webhook testing:

stripe listen --forward-to localhost:4000/webhooks/stripe

Test cards: 4242 4242 4242 4242 (success), 4000 0000 0000 0002 (declined).

Documentation

License

AGPL-3.0