Skip to content

feat(landing): redesign default template + brand palette engine (Phase 1)#201

Merged
saltyskip merged 3 commits into
mainfrom
feat/landing-default-template-palette
Jun 15, 2026
Merged

feat(landing): redesign default template + brand palette engine (Phase 1)#201
saltyskip merged 3 commits into
mainfrom
feat/landing-default-template-palette

Conversation

@saltyskip

Copy link
Copy Markdown
Owner

What & why

The link landing page was hardcoded dark (#0a0a0a) with a single swapped accent, so every tenant got the same "dev-tool dark" canvas. The one piece of real visual content — social_preview.image_url — was never rendered (only emitted as an OG meta tag), and expires_at was never surfaced.

This is Phase 1 of brandable landing pages. End-state: a small library of first-party templates customers select (never author), fed by a LandingTheme config that cascades Link override → LandingTheme → Rift default. Phase 1 builds the foundation and the visual win, with no persistence yet.

Changes

  • services/landingLandingTheme brand config + a Default impl (Rift defaults), the renderer's sole branding input. Every knob is an enum or constrained string (template, color_scheme, font, corner_style, …) so a page can't render trash. Derives both ToSchema (REST) and JsonSchema (MCP) per CLAUDE.md.
  • api/links/palette — derivation engine turning one theme_color into a full, contrast-correct palette. Clamps saturation/lightness into a tasteful band, picks on-accent text color by WCAG luminance, falls back to the default accent on garbage input. Dark/Light/Auto (Auto emits a prefers-color-scheme override).
  • landing.rsDefault template redesign: palette expressed as CSS custom properties, preview image rendered as a hero, expiry surfaced, bigger icon/type, button depth; agent panel restyled to the shared tokens and gated on show_agent_panel. Platform-detection JS and JSON-LD unchanged.
  • routes.rs — stop consuming App branding (unused); render from LandingTheme::default(). Branding returns in Phase 2 via tenant config.
  • CLAUDE.md — push the PR before the final full test run so CI runs in parallel.

Tests

  • Palette unit tests: clamping bounds, contrast-text selection, garbage fallback, scheme selection, tinted-not-flat-black.
  • Resolve integration: hero preview image renders; :root / --accent CSS variables present.

Decisions / follow-ups

  • App branding is intentionally not consumed (it was unused). Its fields (App.{app_name, icon_url, theme_color}) are now orphaned — candidate for a cleanup issue.
  • Phase 2 (tracked separately): persist LandingTheme on TenantDoc + settings route + cascade + per-link content overrides; additional templates.

🤖 Generated with Claude Code

saltyskip and others added 2 commits June 15, 2026 14:21
…e 1)

The link landing page was hardcoded dark with a single swapped accent, so
every tenant got the same "dev-tool dark" canvas; the one piece of real
visual content (social_preview.image_url) was never rendered, and expires_at
was never surfaced.

Phase 1 of brandable landing pages (no persistence yet):

- services/landing: LandingTheme brand config with a Default impl (Rift
  defaults) — the renderer's sole branding input. Knobs are enums/constrained
  strings (template, color_scheme, font, corner_style, …) so a page can't
  render trash. Derives both REST (ToSchema) and MCP (JsonSchema) per CLAUDE.md.
- api/links/palette: derivation engine turning one theme_color into a full,
  contrast-correct palette. Clamps saturation/lightness into a tasteful band,
  picks on-accent text by WCAG luminance, falls back to the default accent on
  garbage input. Dark/Light/Auto (Auto emits a prefers-color-scheme override).
- landing.rs: Default template redesign — palette expressed as CSS custom
  properties, preview image rendered as a hero, expiry surfaced, bigger
  icon/type, button depth; agent panel restyled to the shared tokens and gated
  on show_agent_panel. Platform-detection JS and JSON-LD unchanged.
- routes.rs: stop consuming App branding (unused); render from
  LandingTheme::default(). Branding returns in Phase 2 via tenant config.

Tests: palette unit tests (clamping, contrast, fallback, scheme selection);
resolve integration assertions for the hero image, expiry, and CSS variables.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The full cargo test run is slow; pushing the branch/opening the PR first lets
remote CI run the suite in parallel with the local run instead of serializing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rift Ready Ready Preview, Comment Jun 15, 2026 7:46pm

Request Review

Adds a manual trigger so any branch can be deployed to sandbox from the
Actions UI or `gh workflow run server-ci.yml --ref <branch>`. deploy-sandbox
now also runs for workflow_dispatch events; deploy-prod stays gated to pushes
on main, so a manual dispatch never touches prod.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@saltyskip saltyskip merged commit 6abcbee into main Jun 15, 2026
6 checks passed
@saltyskip saltyskip deleted the feat/landing-default-template-palette branch June 15, 2026 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant