The shop.html.heex and shop_root.html.heex were both full HTML documents.
When nested (root layout + live layout), this created invalid HTML with
duplicate <!DOCTYPE>, <html>, <head>, and <body> tags.
This caused:
- "Cannot bind multiple views to the same DOM element" console errors
- Failed Lighthouse audits
- Potential rendering issues
Fix:
- shop_root.html.heex: Now contains the full HTML document with theme
settings, CSS variables, and data attributes
- shop.html.heex: Now just passes through @inner_content
Results:
- Console errors: Gone
- Best Practices: 96 → 100
- Total Blocking Time: 140ms → 30ms
- HTML validation: Passes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Self-hosted fonts:
- Download all 10 typefaces (35 font files, 728KB) from Google Fonts
- Create @font-face declarations in assets/css/fonts.css
- Remove Google Fonts external dependency from layouts
- Privacy improvement (no Google tracking)
- Performance improvement (no DNS lookup to fonts.googleapis.com)
- GDPR compliant (no third-party requests)
Admin access:
- Add /admin route that redirects to /admin/theme (requires auth)
- Remove Admin link from footer (too visible for visitors)
- Shop owners can bookmark or type /admin directly
Layout improvements:
- Create shop_root.html.heex as minimal root for shop pages
- Shop pages no longer show admin nav bar
Other:
- Update .gitignore to exclude digested static files
- Add PageSpeed 100% task to ROADMAP.md
- Fix test to check /users/settings instead of shop homepage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Mobile Bottom Navigation section to ROADMAP
- Update routes table in README (collections routes)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace cramped horizontal nav on mobile with a fixed bottom tab bar
for thumb-friendly navigation. The header nav is now hidden on mobile
(<768px) and the bottom nav provides Home, Shop, About, and Contact
links with icons.
- Add mobile_bottom_nav component with icon + label nav items
- Active page has accent-colored background highlight and larger icon
- Add shadow to lift nav visually off the page
- Update all page templates with bottom padding and bottom nav
- Remove CSS rule that was overriding Tailwind's hidden class
- Responsive header padding (tighter on mobile)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove marketing fluff "Be the first" - everyone on the list gets
emails at the same time. Just describe what they'll receive.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
More personal and authentic for a solo POD seller:
- "Get in touch" instead of "Contact Us"
- "Drop me a message" instead of "Drop us"
- "I'll get back to you" instead of "we'll"
- "Send a message" instead of "Send us a message"
- "How can I help?" instead of "How can we help?"
- "I'll send you a link" instead of "we'll send"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
More accurate than "Stay in touch" - newsletters are one-way communication.
Also updated description slightly: "news" instead of "updates" to avoid
repetition with the title.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
More neutral and personal than "Follow us":
- Works for all platform types (GitHub, Ko-fi, etc., not just social follows)
- "me" fits a solo POD seller better than corporate "us"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Select platforms typical for a quirky, nerdy POD seller:
- Instagram: primary visual portfolio
- Bluesky: nerdy Twitter alternative
- Mastodon: federated/open web presence
- Ko-fi: indie tips and commissions
- GitHub: open source projects
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add newsletter_card component with :card and :inline variants to share
between footer and contact page. Add social_links_card component with
full-width icon+text cards for better discoverability.
Improve contact_form with optional email link and response time display,
keeping important contact info above the fold. Reorganize contact page
layout with form on left, info cards on right.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Mark as completed:
- Navigation links between admin and shop
- Collection routes with filtering and sorting
- Header navigation accessibility improvements
Update Phase 9 routes to reflect current implementation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Current page in nav is now a span instead of a link (no self-links)
- Logo links to home page, except when already on home
- Use aria-current="page" with accent underline for current page indicator
- Extract logo_content, logo_inner, and nav_item helper components
- Update CSS to target both a and span elements in .shop-nav
This follows WCAG accessibility guidelines - links that point to
the current page are confusing for screen reader users.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add sort functionality to /collections/:slug pages with 6 sort options
(featured, newest, price ascending/descending, name A-Z/Z-A). Sort
selection persists across category navigation via URL query params.
Refactor handle_params to be DRY using load_collection/1 helper.
Add comprehensive unit tests for PreviewData category functions and
LiveView tests for the Collection page sorting and navigation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add ShopLive.Collection LiveView for collection pages
- Add products_by_category/1 and category_by_slug/1 to PreviewData
- Support /collections/all for all products view
- Remove /products route and ShopLive.Products (replaced by collections)
- Update all links to use /collections/all instead of /products
- Update category nav to link to /collections/:slug
- Update PDP breadcrumb to link to specific collection
URL structure now follows Shopify convention:
- /collections/all - All products
- /collections/art-prints - Art Prints collection
- /collections/apparel - Apparel collection
- etc.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add "← View Shop" link on admin/theme page for easy navigation
- Add collapsible sidebar with chevron toggle button
- Include proper ARIA attributes for accessibility (aria-label,
aria-expanded, aria-controls)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Verifies that updating theme settings regenerates the CSS cache
with the new values. Tests accent color changes from red to blue
and confirms the correct HSL hue values appear in cached CSS.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests cover:
- get/0, put/1, invalidate/0, warm/0 functions
- Performance benchmark comparing cache hit vs CSS generation
- 100 cache hit consistency test
Run with: mix test test/simpleshop_theme/theme/css_cache_test.exs --include benchmark
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The CSSCache.init/1 already calls warm() on startup.
Remove from Quick Wins, add to Completed section.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update README title to "SimpleShop"
- Update ROADMAP title to "SimpleShop Roadmap"
- Add "Rename Project to SimpleShop" to Technical Debt section
with list of files that would need updating
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The shop is the product; the theme editor is a feature.
Reorder features section to lead with "The Shop" before
"Theme Editor".
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Newsletter signup card for prominent subscription CTA
- Social media links card with icons and text labels
- Makes social links more discoverable than small footer icons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove reference to deleted sample-content.md
- Move Sample Content to Completed section (it's implemented)
- Note Printify integration in completed features
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add ShopLive.Cart at /cart using shared PageTemplates
- Update ErrorHTML to render fully themed 404/500 pages
- Add dev-only error preview routes at /dev/errors/404 and /dev/errors/500
- Update error page tests for themed output
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document the architecture and implementation phases for transforming
static page templates into a database-driven, customizable page builder
with visual editing capabilities.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add PDP (Product Detail Page) at /products/:id with full e-commerce
functionality including product gallery, variant selector, quantity
controls, reviews section, and related products.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create ShopLive.Products module and template
- Add /products route to public shop live session
- Shows product grid with category filters and sort dropdown
- Displays all 16 preview products with categories
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create ShopLive.Contact module and template
- Add /contact route to public shop live session
- Includes contact form, order tracking, info cards, social links
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create ShopLive.About module and template
- Add /about route to public shop live session
- Reuse shop_components for header, footer, hero, rich text
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add .themed class as shared selector for both shop and preview
- Move visual/behavioral styles from .preview-frame to .themed
- Keep .preview-frame only for CSS variable switching (editor live preview)
- Update CSSGenerator to target .themed instead of .shop-root
- Refactor CSS files to use native CSS nesting syntax
- Update tests to reflect new class structure
This improves maintainability by:
- Eliminating duplicate selectors (.shop-root + .preview-frame)
- Using modern CSS nesting (94%+ browser support)
- Clear separation: .preview-frame = vars, .themed = styles
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add tests to verify that:
- Both .shop-root and .preview-frame have theme data attributes
- Theme settings changes are reflected on shop pages
- CSS file has correct selectors for both contexts
- Generated CSS cache includes all theme variables
These tests catch regressions like the selector issue where
.preview-frame[data-mood="warm"] was incorrectly transformed to
.preview-frame, .shop-root[data-mood="warm"] instead of
.preview-frame[data-mood="warm"], .shop-root[data-mood="warm"]
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix asset paths in shop layout (css/app.css, js/app.js)
- Add Google Fonts preconnect and stylesheet link
- Update theme-layer2-attributes.css to target both .preview-frame
and .shop-root so theme styles apply to real shop pages
- Properly duplicate attribute selectors (e.g., [data-mood="warm"])
for both .preview-frame and .shop-root
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create LoadTheme plug for loading theme settings
- Add shop layout with inline CSS injection (~400 bytes vs 17KB full)
- Create ShopLive.Home at / using shared ShopComponents
- Wire up CSS cache invalidation when theme settings change
- Replace Phoenix welcome page with themed shop home page
The shop layout injects only the active theme CSS variables inline,
achieving a 97% reduction compared to the full variants file used
by the theme editor.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add reusable components for all page sections:
- category_nav: Category circles for homepage navigation
- featured_products_section: Product grid with title and view-all CTA
- image_text_section: Two-column image + text layout
- collection_header: Page header with title and product count
- filter_bar: Category pills and sort dropdown
- content_body: Long-form content wrapper for about page
- contact_form: Contact form card
- order_tracking_card: Order tracking input card
- info_card: Bullet-point info card
- contact_info_card: Email contact card with icon
- social_links: Social media icon links
- cart_item: Cart item row with quantity controls
- order_summary: Order totals and checkout card
- breadcrumb: Navigation breadcrumb trail
- related_products_section: Related products grid
All preview pages now compose entirely of reusable components,
making them easier to maintain and enabling future section-based
theme customization.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add variant support to hero_section component:
- :default - Standard hero with section wrapper (home, about)
- :page - Page header style with larger title, more spacing (contact)
- :error - Error page with pre-title (404), dual buttons (error)
Now used in: home, about, contact, error pages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create a centered hero section component with:
- Title (h1) and description (p)
- Optional CTA button with preview/live mode support
- Configurable background (:base or :sunken)
Used in: home page (with CTA), about page (without CTA)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>