Commit graph

726 commits

Author SHA1 Message Date
117227a901 Add setuptools to requirements for Python 3.12+ compatibility
Python 3.12 no longer bundles setuptools in virtual environments.
Pyramid imports pkg_resources from setuptools, causing CI to fail with
ModuleNotFoundError: No module named 'pkg_resources'.
2026-02-08 11:47:52 -05:00
c5f3b2915f Sticky ribbon + logo/nav on desktop scroll
Wraps ribbon and nav-grid in .sticky-header div inside section.main.
Desktop only (min-width: 800px) — sticks to top on scroll, eliminates
whitespace gap above sticky video. No change on mobile/tablet.
2026-02-08 11:47:15 -05:00
7becbb94a1 Always show queue add button, add mobile usability rule to CLAUDE.md
Hover-only controls are unreachable on touch devices. Removed opacity:0
hover-reveal pattern from queue add button. Added MOBILE USABILITY
guideline to CLAUDE.md: all interactive elements must be always visible.
2026-02-08 11:41:50 -05:00
d1fbcf53cf Add autoplay toggle switch inline with Up Next heading
iOS-style slider toggle, on by default, persisted in localStorage.
Moved from standalone checkbox into related-content header row.
Rebuilt on SPA navigation with rebindAutoplayToggle().
2026-02-08 11:41:01 -05:00
39b186d651 Prevent download/up-next from overlapping sticky video on mobile 2026-02-08 11:36:06 -05:00
8ad849cc72 Bump related content thumbnails from 56px to 58px 2026-02-08 11:35:08 -05:00
93152ab26d Left-align Up Next text, honor thumbnail aspect ratio 2026-02-08 11:34:13 -05:00
1ab8f6ff20 Reduce countdown from 14s to 7s, left-align countdown text 2026-02-08 11:32:26 -05:00
0a08b9b14e Add context-aware footer to base template
SaaS domain shows full MPS footer with navigation links, resources, and CTAs.
Shop domains show minimal footer with shop name and powered-by link.
2026-02-08 11:25:22 -05:00
52e2ffc06c Redesign countdown overlay as compact frosted-glass bottom bar
Countdown preview now anchors to bottom of media container instead of
covering the entire video. Uses backdrop-filter blur with theme-aware
semi-transparent background (light/dark). Compact single-row grid layout
with 60px thumb, title+number, and action buttons inline.

Also completes the stalled watch mode v2 changes: static content timer,
autoplay toggle persistence, audio container wrapping in hardSwap, and
watch_json endpoint accepting non-playable media types.
2026-02-08 10:36:03 -05:00
91fb6f7916 Bump product-main max-height from 33vh to 42vh 2026-02-08 10:17:30 -05:00
d03178b5b5 Redesign Up Next sidebar: compact rows, numbered index, hover-reveal queue button 2026-02-08 08:52:47 -05:00
cbeb873d14 Reduce h1 font size from 1.75em to 1.25em 2026-02-08 08:50:48 -05:00
04a4df4ccd Reduce subtitle text size in product/content headings 2026-02-08 08:49:43 -05:00
bc9b2fd954 Revert title above media in content, break subtitle to own line
Content template: video back on top, title below (as before).
Both templates: br before "uploaded to" / "sold by" so the
subtitle text wraps to its own line under the title.
2026-02-08 08:25:03 -05:00
12f738d480 Watch mode v2: continuous playback with crossfade and queue
Rewrite watch mode from basic autoplay into a full SPA media controller:

- Fix get_related_products() with 3-tier fallback (stem overlap, same
  media type, recency) so orphan products still show recommendations
- Add /watch/{id}/json endpoint for SPA navigation without page refresh
- Rewrite watch.js: SPA fetch+pushState, 14-second countdown timer,
  DJ crossfade with dual media elements, queue system with sessionStorage
- Add audio support in watch mode (album art + audio player)
- Add queue "+" buttons to related content sidebar
- Add noscript/js-only progressive enhancement pattern
- Preload next media for instant transitions
2026-02-08 08:19:07 -05:00
fd33376cb7 Document CSS media sizing rule: never width 100% with max-height 2026-02-08 08:04:43 -05:00
7cd749cf5f Use width auto for watch-mode video to eliminate whitespace
width: 100% forced the video element wider than its rendered
content when max-height constrained the height. width: auto lets
the element shrink to match the actual video aspect ratio.
2026-02-08 08:01:40 -05:00
9ed4dd50e9 Move title above media in content template
Title should always appear before the image/video so the user
knows what they're looking at. product.j2 already had this order.
2026-02-08 07:48:00 -05:00
007a53f3df Left-align product images to match title text
With max-height constraining square media, images no longer fill
the container width and were centering via inherited text-align.
2026-02-08 07:07:01 -05:00
449542d3d8 Move None frequency option to leftmost position 2026-02-08 06:59:23 -05:00
1995b88615 Flash verification prompt for unauthenticated subscribe visitors 2026-02-08 06:49:06 -05:00
2235ea24a7 Move Subscribe link to left of username in nav 2026-02-08 06:48:32 -05:00
efc7ee9284 Use 33vh instead of 480px for product-main max-height
Scales with viewport so square media takes up at most 1/3 of the
screen on any device.
2026-02-08 06:39:22 -05:00
b76c0e0115 Add Subscribe nav link, None frequency option, improve form styling
- Subscribe link in nav bar on shop domains
- None option disables notifications for the subscriber
- Styled frequency as pill buttons, full-width submit, cleaner layout
2026-02-08 06:37:09 -05:00
0adc57c874 Add max-height 480px to all product-main selectors
The base .product-main rule was being overridden by more specific
selectors that set height: auto. Add max-height to each specific
rule so the constraint is respected. Also add production URL to
CLAUDE.md.
2026-02-08 06:26:03 -05:00
35819d0638 Cap product-main height at 480px to tame square media 2026-02-08 06:15:52 -05:00
d86167c00b Include GIT_HASH in package_data so it ships with pip install 2026-02-08 04:42:17 -05:00
ab8d07c04c Track GIT_HASH in repo so deploy always has it
Production installs from git clone without .git, so the
setup.py approach can't resolve the hash. Committing the
file ensures it's always present in the package.
2026-02-08 04:33:04 -05:00
1b704f545f Bake git hash at install time so /version works without .git
setup.py writes GIT_HASH file during install. The version view
reads it at runtime instead of shelling out to git.
2026-02-07 19:54:57 -05:00
1ebfb5a8aa Add /version endpoint with git hash for deploy verification 2026-02-07 19:38:01 -05:00
e9bef9982d Make subscription migration idempotent
Check for existing table/column before creating, so the migration
doesn't error when init-db has already created the schema.
2026-02-07 19:24:10 -05:00
8171960847 Add email digest subscriptions, @mentions, and RSS autodiscovery
Implement "Stay in the Loop" feature set:
- ShopSubscription model for daily/weekly email digest subscriptions
- Subscribe/verify/unsubscribe views with token-based email verification
- Digest sender console script for cron-based email delivery
- @mention parsing in comments with immediate email notifications
- RSS/Atom autodiscovery link tags in page head
- Shop settings toggle for enabling/disabling subscriptions
2026-02-07 19:04:13 -05:00
fe237ba350 Document capability-driven presentation practice in CLAUDE.md. 2026-02-07 16:40:04 -05:00
4b8d2aa4d3 Fix watch mode sticky video and media overflow
Change section.content overflow-x from auto to clip so position:sticky
works through it. Add min-width:0 on watch-left to prevent grid blowout.
Add overflow:hidden on sticky product-images to contain media.
2026-02-07 16:36:26 -05:00
819c0d630a Fix sticky video by wrapping left column in watch-left container
position: sticky only works within the containing block. In the grid
layout, each named area (images, description, comments) was its own
containing block, so the video had nowhere to stick. Wrapping all
left-column content in a single div gives the video a tall parent
to stick within while scrolling.
2026-02-07 15:24:06 -05:00
bc4858c58a Add YouTube-style watch mode with sticky video, autoplay, and related content
Shop owners can enable watch mode in settings to get: direct video autoplay
with muted fallback, sticky video player while scrolling, and a stemming-powered
"Up Next" related content sidebar. Degrades gracefully per capability.
2026-02-07 14:57:37 -05:00
68089dff5b Add AJAX comment submission to preserve media playback
Comments now submit via fetch() when JS is available, returning JSON
instead of triggering a full page reload that kills video/audio playback.
Falls back to the existing POST+redirect when JS is disabled.
2026-02-07 11:19:58 -05:00
timehexon
2ae2863a4c Replace "AI" with "machine learning" in CLAUDE.md
Machine learning is what we grow. "AI" is forbidden in all
permacomputer discourse, marketing, & documentation.
2026-02-02 19:55:59 +00:00
726cf6eebb Add shop setting to toggle product/content date visibility
Remove border-top from date metadata styling. Add show_dates boolean
to Shop model (default on) with radio buttons in Branding Settings
to show or hide created/updated dates on product and content pages.
2026-02-01 13:47:05 -05:00
875183d201 Add created/updated dates to product and content pages
Show subtle date metadata at the bottom of the description section
with muted text and a light border separator. Only shows "Updated"
when it differs from the created date.
2026-01-31 14:01:27 -05:00
1eca7a3145 Fix content.j2 thumbnail handling - remove play overlay from non-videos
- Fix broken image when content has no thumbnail1
- Remove play button overlay from images/GIFs (only videos get it)
- Non-video content now opens in new window on click
2026-01-25 10:25:55 -05:00
bbc03b0c6d Add template syntax validation tests
Validates all 51 Jinja2 templates can be parsed without syntax errors.
Includes specific tests for key templates: base, product, content, cart,
checkout, shop, invoice, billing, crypto_checkout, home, product_edit,
user_settings, and user_purchases.

Catches issues like mismatched {% if %}/{% endif %} blocks before deployment.
2026-01-22 12:48:50 -05:00
4f43aa7104 Fix content.j2 template - remove extra endif causing syntax error 2026-01-22 12:24:12 -05:00
ded0941839 Fix video thumbnail container CSS - support div element not just a 2026-01-22 12:04:43 -05:00
d254147362 Simplify inline video - use direct URLs, no /player/ endpoint
- Pass video URL directly to playInline() function
- No more fetching from JSON endpoint
- No-JS fallback opens video URL directly in new tab
- Play Preview button links directly to video file
- Removed all /player/ route dependencies from templates

Much simpler: click thumbnail → swap to video element with that URL

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-22 12:02:55 -05:00
57a5f83b73 Replace pop-up player with inline video on thumbnail click
Simple approach:
- Click thumbnail → swap it for an inline video element
- Video has native browser controls (including PiP button)
- No JavaScript fallback → opens /player/{id} in new tab
- Removed all pop-up window code

The native browser video controls already have a PiP button,
so no need for custom PiP implementation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-22 11:32:17 -05:00
34ee5a9eeb Replace broken PiP API with small floating pop-out window
Native PiP API (requestPictureInPicture) not available in user's browser.
Instead, open a small pop-out window (480x320) that:
- Is movable (drag the window)
- Is resizable (resize=yes)
- Stays open when browsing main site
- Has prev/next controls (from player.j2)
- Auto-advances when video ends (from player.js)
- Positioned in bottom-right corner of screen

This is more reliable than trying to use browser APIs that may not
be available or work differently across browsers.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-22 11:24:28 -05:00
6ec2a97f34 Add PiP support to content.j2 template (was only in product.j2) 2026-01-22 10:09:12 -05:00
453334f3e4 Change thumbnail click to open PiP directly instead of pop-up 2026-01-22 09:35:56 -05:00