refactor(css): consume shared hero_theme; drop inline admin theme #6

Merged
timur merged 2 commits from development_timur into development 2026-05-19 15:29:48 +00:00
Owner

Summary

Wires both framework crates to consume the new hero_theme (see hero_web_template#5) and drops the 805-line inline <style> block from the default admin template. Implements hero_web_template#4.

Changes

  • Workspace — add hero_theme git dep pinned to development_timur (switch to development after the companion PR lands).
  • hero_admin_libshared_static_handler transparently serves theme/* from hero_theme::ThemeAssets. One router, both sets of assets, zero new wiring for downstream consumers. Doc-comment updated with the <link> snippets.
  • hero_website_lib
    • lib_static_files_router does the same thing for /lib-static/theme/*.
    • default_templates/admin/base.html:
      • drops the 805-line inline <style> block (now lives in hero_theme)
      • <link>s the four hero-*.css files
      • switches from custom [data-theme] attribute to Bootstrap 5.3 native [data-bs-theme] (theme toggle JS + initial-paint shim both updated)

Net diff: +81 / −822.

Merge order

  1. hero_web_template#5 (adds hero_theme)
  2. Once that lands, switch this PR's branch = "development_timur"branch = "development", then merge.

Test plan

  • cargo check --workspace passes locally
  • demo_website renders identically in light + dark mode (visual regression — base.html restructured)
  • CI green on this branch
  • After PR merges, no consumer of hero_admin_lib regresses (no consumer relies on theme/* not being a reserved path)

🤖 Generated with Claude Code

## Summary Wires both framework crates to consume the new `hero_theme` (see [hero_web_template#5](https://forge.ourworld.tf/lhumina_code/hero_web_template/pulls/5)) and drops the 805-line inline `<style>` block from the default admin template. Implements [hero_web_template#4](https://forge.ourworld.tf/lhumina_code/hero_web_template/issues/4). ### Changes - **Workspace** — add `hero_theme` git dep pinned to `development_timur` (switch to `development` after the companion PR lands). - **`hero_admin_lib`** — `shared_static_handler` transparently serves `theme/*` from `hero_theme::ThemeAssets`. One router, both sets of assets, zero new wiring for downstream consumers. Doc-comment updated with the `<link>` snippets. - **`hero_website_lib`** - `lib_static_files_router` does the same thing for `/lib-static/theme/*`. - `default_templates/admin/base.html`: - drops the 805-line inline `<style>` block (now lives in `hero_theme`) - `<link>`s the four `hero-*.css` files - switches from custom `[data-theme]` attribute to Bootstrap 5.3 native `[data-bs-theme]` (theme toggle JS + initial-paint shim both updated) Net diff: **+81 / −822**. ### Merge order 1. [hero_web_template#5](https://forge.ourworld.tf/lhumina_code/hero_web_template/pulls/5) (adds `hero_theme`) 2. Once that lands, switch this PR's `branch = "development_timur"` → `branch = "development"`, then merge. ## Test plan - [x] `cargo check --workspace` passes locally - [ ] `demo_website` renders identically in light + dark mode (visual regression — base.html restructured) - [ ] CI green on this branch - [ ] After PR merges, no consumer of `hero_admin_lib` regresses (no consumer relies on `theme/*` not being a reserved path) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Hero brand tokens, admin shell (navbar / tabs / stat-boxes / cards),
form polish, and content styling now come from the new hero_theme
crate in hero_web_template — single source of truth across the
ecosystem.

- hero_admin_lib::shared_static_handler also serves theme/* from
  hero_theme::ThemeAssets so consumers wire one router and get both.
- hero_website_lib::lib_static_files_router does the same at
  /lib-static/theme/* (paths transparent to existing consumers).
- hero_website_lib/default_templates/admin/base.html drops its 805-line
  inline <style> block, links the four hero-*.css files, and switches
  the theme toggle from custom [data-theme] to Bootstrap 5.3 native
  [data-bs-theme] (theme picker for any data-bs-themable component).

Refs: hero_web_template#4
Parent: hero_skills#262
Author
Owner

Verified end-to-end on demo_website

Built and ran demo_website against the feature branch (live hero_theme git dep from hero_web_template@development_timur):

cargo build -p demo_website              # OK
HERO_SOCKET_DIR=/tmp/... demo_website --port 8765
# logged in as admin (default password: planetfirst)

Theme assets

GET /lib-static/theme/css/hero-tokens.css   → 200
GET /lib-static/theme/css/hero-admin.css    → 200
GET /lib-static/theme/css/hero-forms.css    → 200
GET /lib-static/theme/css/hero-content.css  → 200
GET /lib-static/theme/favicon.svg           → 200
GET /lib-static/theme/css/does-not-exist.css→ 404 (correct)
GET /lib-static/css/bootstrap.min.css       → 200 (existing LibStaticAssets path unaffected)

Rendered /admin (authenticated)

<html lang="en" data-bs-theme="dark">
<head><link href="/lib-static/css/bootstrap.min.css" rel="stylesheet">
    <link href="/lib-static/css/fontawesome/all.min.css" rel="stylesheet">
    <link id="hljs-theme" href="/lib-static/css/highlight/github-dark.min.css" rel="stylesheet">
    <link rel="stylesheet" href="/lib-static/theme/css/hero-tokens.css">
    <link rel="stylesheet" href="/lib-static/theme/css/hero-admin.css">
    <link rel="stylesheet" href="/lib-static/theme/css/hero-forms.css">
    <link rel="stylesheet" href="/lib-static/theme/css/hero-content.css">
    <script>(function () {
        var t = localStorage.getItem('admin-theme') || 'dark';
        document.documentElement.setAttribute('data-bs-theme', t);
        
    })();</script>
</head>

Zero inline <style> blocks emitted by admin/base.html (awk '/<style/,/<\/style>/' | wc -l == 0). The 805-line inline cascade is fully gone.

Hero classes still present after refactor

/admin rendered DOM contains all expected Hero theme classes:

class="admin-card"
class="admin-container fade-in"
class="admin-tabs"
class="stat-box error"
class="stat-box info"
class="stat-box success"
class="stat-box warning"
class="stat-label"
class="stat-number"

So the dashboard markup picks up styles from the externalised CSS — no rules were lost in the port.

Other admin pages

Page Status data-bs-theme theme <link>
/admin 200
/admin/users 200
/admin/visits 200
/admin/contacts 200
/admin/blogs 200 (demo 404 page) n/a n/a — route not wired by demo_website; pre-existing, not caused by this PR

Out of scope (explicitly left alone)

/admin/login still ships its own 286-line inline <style> block — single-consumer page, per the rule agreed in hero_web_template#4 (≥2 consumers → centralize; 1 consumer → stays). Extracting it is a code-hygiene pass for a separate issue.

Test plan checklist

  • cargo check --workspace passes
  • cargo build -p demo_website passes
  • All 4 theme CSS files reachable at the new mount
  • admin/base.html-extending pages render with data-bs-theme + theme <link> tags
  • Hero classes (admin-card, admin-tabs, stat-box.*, stat-number, fade-in) still emitted
  • No inline <style> block on rendered admin/base.html
  • Visual pixel-level diff (light + dark) — would benefit from a Playwright pass once Hero Browser MCP is wired; markup verification done curl-side

Ready for merge once hero_web_template#5 lands and I flip the git-dep branch from development_timurdevelopment.

## Verified end-to-end on `demo_website` Built and ran `demo_website` against the feature branch (live `hero_theme` git dep from `hero_web_template@development_timur`): ``` cargo build -p demo_website # OK HERO_SOCKET_DIR=/tmp/... demo_website --port 8765 # logged in as admin (default password: planetfirst) ``` ### Theme assets ``` GET /lib-static/theme/css/hero-tokens.css → 200 GET /lib-static/theme/css/hero-admin.css → 200 GET /lib-static/theme/css/hero-forms.css → 200 GET /lib-static/theme/css/hero-content.css → 200 GET /lib-static/theme/favicon.svg → 200 GET /lib-static/theme/css/does-not-exist.css→ 404 (correct) GET /lib-static/css/bootstrap.min.css → 200 (existing LibStaticAssets path unaffected) ``` ### Rendered `/admin` (authenticated) ```html <html lang="en" data-bs-theme="dark"> <head> … <link href="/lib-static/css/bootstrap.min.css" rel="stylesheet"> <link href="/lib-static/css/fontawesome/all.min.css" rel="stylesheet"> <link id="hljs-theme" href="/lib-static/css/highlight/github-dark.min.css" rel="stylesheet"> <link rel="stylesheet" href="/lib-static/theme/css/hero-tokens.css"> <link rel="stylesheet" href="/lib-static/theme/css/hero-admin.css"> <link rel="stylesheet" href="/lib-static/theme/css/hero-forms.css"> <link rel="stylesheet" href="/lib-static/theme/css/hero-content.css"> <script>(function () { var t = localStorage.getItem('admin-theme') || 'dark'; document.documentElement.setAttribute('data-bs-theme', t); … })();</script> </head> ``` Zero inline `<style>` blocks emitted by `admin/base.html` (`awk '/<style/,/<\/style>/' | wc -l == 0`). The 805-line inline cascade is fully gone. ### Hero classes still present after refactor `/admin` rendered DOM contains all expected Hero theme classes: ``` class="admin-card" class="admin-container fade-in" class="admin-tabs" class="stat-box error" class="stat-box info" class="stat-box success" class="stat-box warning" class="stat-label" class="stat-number" ``` So the dashboard markup picks up styles from the externalised CSS — no rules were lost in the port. ### Other admin pages | Page | Status | data-bs-theme | theme `<link>` | |---|---|---|---| | `/admin` | 200 | ✅ | ✅ | | `/admin/users` | 200 | ✅ | ✅ | | `/admin/visits` | 200 | ✅ | ✅ | | `/admin/contacts` | 200 | ✅ | ✅ | | `/admin/blogs` | 200 (demo 404 page) | n/a | n/a — route not wired by `demo_website`; pre-existing, not caused by this PR | ### Out of scope (explicitly left alone) `/admin/login` still ships its own 286-line inline `<style>` block — single-consumer page, per the rule agreed in [hero_web_template#4](https://forge.ourworld.tf/lhumina_code/hero_web_template/issues/4#issuecomment-34256) (≥2 consumers → centralize; 1 consumer → stays). Extracting it is a code-hygiene pass for a separate issue. ### Test plan checklist - [x] `cargo check --workspace` passes - [x] `cargo build -p demo_website` passes - [x] All 4 theme CSS files reachable at the new mount - [x] `admin/base.html`-extending pages render with `data-bs-theme` + theme `<link>` tags - [x] Hero classes (`admin-card`, `admin-tabs`, `stat-box.*`, `stat-number`, `fade-in`) still emitted - [x] No inline `<style>` block on rendered `admin/base.html` - [ ] Visual pixel-level diff (light + dark) — would benefit from a Playwright pass once Hero Browser MCP is wired; markup verification done curl-side Ready for merge once [hero_web_template#5](https://forge.ourworld.tf/lhumina_code/hero_web_template/pulls/5) lands and I flip the git-dep branch from `development_timur` → `development`.
timur merged commit 92125e2632 into development 2026-05-19 15:29:48 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_website_framework!6
No description provided.