From c801fdc92911fc24e20f9de90d1aff4637963595 Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Fri, 28 Aug 2026 20:04:21 +0000 Subject: [PATCH] Make the page transition configurable, add crossfade/slide/reveal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cube view-transition block moves out of pagerite.css into transition designs (pagerite/themes/{name}/transition.css), handled like banner designs: served from disk at /_themes/..., injected by the backend as #pagerite-transition after the banner sheet, and picked site-wide in the site settings (Data.transition, default cube; GET/PUT /_api/settings carry transition + the designs found on disk). The site editor swaps the sheet in place on change; the dev-mode order fixup knows the new id. Designs: cube (unchanged), crossfade (all navigations), slide (sideways, both pages moving together) and reveal (clip-path wipe over the stationary old page) — the latter two mirrored on history-back and crossfading within a section like cube. Also compress the site settings form into a two-column grid: site name + favicon on one row, theme + transition on the next. --- docs/content-model.md | 2 + docs/design-principles.md | 4 +- docs/editing.md | 4 +- docs/frontend-runtime.md | 4 +- docs/themes-and-assets.md | 15 +- frontend/src/SiteEditor.vue | 171 ++++++++++++++++------- frontend/src/assets/pagerite.css | 97 +------------ frontend/src/pagerite.js | 5 +- pagerite/app.py | 12 +- pagerite/data.py | 4 + pagerite/themes/crossfade/transition.css | 20 +++ pagerite/themes/cube/transition.css | 98 +++++++++++++ pagerite/themes/reveal/transition.css | 52 +++++++ pagerite/themes/slide/transition.css | 74 ++++++++++ pagerite/views.py | 34 ++++- 15 files changed, 435 insertions(+), 161 deletions(-) create mode 100644 pagerite/themes/crossfade/transition.css create mode 100644 pagerite/themes/cube/transition.css create mode 100644 pagerite/themes/reveal/transition.css create mode 100644 pagerite/themes/slide/transition.css diff --git a/docs/content-model.md b/docs/content-model.md index fdd65f6..eab9c67 100644 --- a/docs/content-model.md +++ b/docs/content-model.md @@ -30,6 +30,8 @@ Files are content-addressed (blake3[:12] + extension) and stored **on disk** und `Data.theme` is the active theme name (empty = none/base only); themes are folders in `pagerite/themes/{name}` containing `theme.css` and/or `banner.css` (+ `banner.svg` artwork and any extra assets the CSS references, like summer's `grass.svg`), served by the backend at `/_themes/{name}/...` — read from disk per request (etag by mtime), never built, so on-disk edits show on the next page load even in prod. The theme selector and banner-design selector enumerate these folders via `GET /_api/settings`. +`Data.transition` is the page-transition design name (default `cube`): a theme folder shipping `transition.css`, injected as `#pagerite-transition` on every page and selected in the site editor (the selector enumerates `transition.css` folders via `GET /_api/settings`). See `docs/themes-and-assets.md`. + `Data.custom_css` is raw trusted CSS injected inline in every page `` (id `pagerite-user`) and swapped during fetch-navigation; editable in the site editor. Font picks (heading/body/brand) in the site editor are stored as plain `:root` rows in `custom_css` (`--font-body: var(--font-source-sans);` format — parsed out and rewritten on change, the `:root` block added/removed as needed), referencing the per-family variables (`--font-source-sans` etc.) from `pagerite.css`; the base stylesheet's `--font-brand` defaults to `var(--font-heading)`. `Data.favicon` names a file in the content-addressed store (on disk under `/files/`), uploaded/cleared in the site editor via `PUT`/`DELETE /_api/settings/favicon`; when set it is linked as `` on every page, otherwise browsers fall back to the build's `/favicon.ico` by convention. diff --git a/docs/design-principles.md b/docs/design-principles.md index 2a6fc80..901fcb5 100644 --- a/docs/design-principles.md +++ b/docs/design-principles.md @@ -26,7 +26,7 @@ Pagerite is a single-user CMS/blog. This document records the initial high-level - All pages share one static layout, defined once as an **html5tagger Template** with capitalized placeholders (`Title`, `Banner`, `Nav`, `Sidebar`, `Main`) filled per request. The dynamic regions carry stable ids (`#page-banner`, `#nav`, `#sidebar`, `#main`). - The page top is a **full-width banner header** with the site name and the navigation bar overlaid on it — no separate chrome header. The banner combines two layers, stacked in `#page-banner` (a grid, so they overlay): first the **banner design** — a named design living in a theme folder (`pagerite/themes/{name}/banner.css` plus artwork as `banner.html` — arbitrary markup like canvas + style + script — or `banner.svg`), chosen per page via `Node.banner_design` (a design name, "" for none, None to inherit from the nearest ancestor, then the front page, then the active theme's own design). The artwork is inlined into a `div[data-design]` wrapper: SVG artwork can be recolored from the theme stylesheet (corporate's single SVG serves both light and dark mode via `var()`-driven stops). Second, **per-page author code**: `Node.banner` holds an arbitrary trusted HTML snippet (an image, a styled div, canvas + script — anything), resolved by walking up the node's ancestors to the front page and rendered **after** the design artwork, so author styles always win over the design's own. The base stylesheet falls back to a plain gradient. There is deliberately no scrim fading the banner into the page background — any such fade would ruin user-supplied designs; themes that want one bake it into their SVG (purple does). -- **Fetch-navigation.** Links are plain ``; a small script (`frontend/src/pagerite.js`) intercepts same-origin clicks, fetches the page, and swaps the `#page-banner`, `#nav`, `#sidebar` and `#main` regions, the document title, and the site-wide custom CSS (`