Skip to content

Add stb — Stratos Theme Builder developer tool - #5503

Merged
norman-abramovitz merged 58 commits into
cloudfoundry:developfrom
nabramovitz:feat/stb-theme-builder
Jun 29, 2026
Merged

Add stb — Stratos Theme Builder developer tool#5503
norman-abramovitz merged 58 commits into
cloudfoundry:developfrom
nabramovitz:feat/stb-theme-builder

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

A self-contained developer tool under tools/stb/ for authoring Stratos theming/branding and exporting the company-config.json + theme.css the runtime already consumes.

  • Element-semantic model: harvests instrumented snapshot HTML → projects edits onto theme tokens → emits the bundle. OKLCH-canonical color.
  • UI: collapsing Miller-column navigator over the element hierarchy, live preview, token/element bidirectional editing.
  • Scope: entirely under tools/stb/ — no Stratos runtime changes in this PR; not wired into the main build. TypeScript + Vite + vitest.
  • Gates: 140 tests green, tsc --noEmit clean, prod build succeeds.

Shim marks lever elements (cursor + hover outline) and supports a
'show editable regions' toggle; parent hands the shim the lever id list
and exposes the toggle. Label the asset upload control.
Move the missing-token/color-format row above the editor and preview
panes and band it with a top and bottom rule so it reads as its own
area. Stop the page from scrolling the controls out of sight: add
min-height:0 to the flex middle row and zero the body padding that the
base stylesheet was adding.
Replace the raw --color-* token list as the sidebar's primary view with
an element tree built from the branding-model nodes: friendly names, the
AUTH > LOGIN hierarchy, a colour/value preview per row, and the node
description on hover. A Tree<->Tokens flip keeps the full token set one
click away, and hovering a tree row outlines its element in the preview
via a new STB_HIGHLIGHT_ELEMENT bridge message.

Add a durable token-meaning alias map (data/token-meanings.json) so the
Tokens view can lead with plain-language labels ("Primary action colour",
"Error / danger colour") and demote the raw id. The map is stb-only;
export still emits the real token ids and Stratos code is untouched.

Foundation for the navigator/preview prototype (Miller columns,
comparison tiles) per the 2026-06-28 UX design.
Add a distinct palette-swatch SVG favicon and reference it from the app
shell so stb is visually its own tool, not the Cloud Foundry mark. Also
clears the favicon.ico 404 in the console.
Add a third "Columns" sidebar view: Finder-style left->right drilldown
over the branding-model snapshotId hierarchy (area > page > element),
with collapse-to-rail for the left columns (the rail doubles as the
breadcrumb) and per-kind row glyphs (colour swatch / text / image).
Reuses the existing hover->highlight and select->lever-editor wiring.

Throwaway prototype to measure the R3 horizontal-column budget from the
2026-06-28 UX design. Finding: the login scene only reaches 3 levels, so
it can't stress the budget — needs multi-scene data to truly measure.
Lives beside the element tree; the Tree and Tokens views are unchanged.
Aggregate every scene's branding-model into one set (global-branding.ts:
loadGlobalModel reads the manifest, merges each scene's nodes tagged with
their scene id) and drive the Columns navigator from it instead of the
active-scene model. Selecting a node switches the preview to that node's
scene before opening the editor; hover only highlights when the node is in
the scene on screen.

This matches the design's "one navigator over the whole UI" intent and is
the prerequisite for actually stressing the R3 column budget: top-level
areas now merge across scenes by their shared snapshotId prefix. Only the
login scene is modelled today, so breadth appears once more scenes ship a
branding-model.json.
Add a branding-model.json for the already-instrumented app-list scene
(12 nodes under cf.applications: page, nav, heading, three app cards each
with a name + status colour matching Running/Stopped/Crashed). This gives
the global navigator a second top-level area ("cf") and four levels of
depth, so the R3 column budget is finally exercisable.

Result: collapse-to-rail holds the navigator to ~2 full columns plus thin
rails at any depth — the horizontal budget is not a problem.

Also guard the routing.json fetch so a scene without one (app-list) falls
back to empty routing instead of throwing a JSON parse error on the
dev-server HTML fallback.
Expose jumpTo(snapshotId) from the column navigator and call it when an
element is clicked in the preview, so clicking in the render selects the
node in the columns (the §2.6 bidirectional half, and a real stand-in for
the who-uses-me / chip-click "set full column path" action).

R1 finding: a path-set jump stays predictable to walk back from. The jump
lands on a real path (rails for the ancestors, leaf active), identical to a
manual drill; clicking the Auth rail returns to the root [Auth, Cf]. The
critic's "a jump breaks spatial memory" concern doesn't bite because the
rails ARE the visible breadcrumb — back-nav is seen, not remembered.
The editor anchored to a .stb-tree-row, but with the Columns view active
the tree is hidden and a hidden row reports a 0,0 rect — dumping the editor
in the top-left corner. Anchor to the deepest active column row instead
(skipping any zero-size/hidden candidate), and jump the columns before
opening the editor on a preview click so the active row exists to anchor to.
Add deriveAlertRoles(seed, {targetRatio, dark}): the principled .alert-danger
pattern. From one seed colour it derives a background/border/text trio that
stays on the seed hue but is pushed to divergent lightness, searching the text
lightness until text-on-background meets the contrast target; returns the
achieved ratio and meetsAA. Inverts for dark surfaces. Pure logic, TDD.

@norman-abramovitz norman-abramovitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - Still in POC mode.

@norman-abramovitz
norman-abramovitz merged commit 8ec81ae into cloudfoundry:develop Jun 29, 2026
12 checks passed
@nabramovitz
nabramovitz deleted the feat/stb-theme-builder branch June 29, 2026 07:23
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.

2 participants