Drops the npm run wrapper: this is a one-off tool reached for while picking role values for a new product skin, not part of the regular test/lint/build loop the other npm scripts cover. Makes the file executable and updates the doc to invoke it directly.
6.6 KiB
Creating a product skin
The Agama web UI can be restyled for a product without touching application code: colors, logo, and a handful of other roles are set in a single per-product file, loaded at runtime after Agama's own styles.
What a skin can change
- Colors and roles: a curated set of
--agm-t--*CSS custom properties (brand color, surface/text/border colors, status colors, focus ring, corner radius, product logo size/alignment, and a few typography/icon-size hooks).web/src/assets/products/example.cssis the basic reference (colors only, covers most products);example-advanced.cssdocuments every available role with a worked example.web/src/assets/styles/tokens/_semantic.scss's header comment is the authoritative, up-to-date index of every role. - Logo:
<product-id>.svg(light theme) and<product-id>-dark.svg(dark theme), transparent background. Match the square-ish aspect ratio of the existing logos in that folder:ProductLogorenders it at a small fixed width per usage context (masthead, next to the product name, ...), so a very wide or tall logo will look cramped or oversized.
Steps
- Copy
example.css(orexample-advanced.cssfor the full role set) toweb/src/assets/products/<product-id>.css. Set only the roles the brand actually needs; anything left unset keeps Agama's default look. - Add the logo files described above.
- Verify WCAG contrast for every color you set, in both light and dark
theme separately (a value that passes in one theme can fail in the
other, and dark-theme "elevated" surfaces like tooltips/popovers need to
read lighter than the page, not darker): run
web/scripts/check-contrast.js <foreground> <background> [--target=4.5](run from the repo root). Use--target=3for UI elements and focus rings, the default 4.5 for normal text. When a pair fails, the tool suggests a same-hue, same-saturation shade that passes. - If you hand-edit an SVG, validate it with
xmllint --noout <file>.svgbefore considering it done: a stray--inside an XML comment silently breaks rendering in browsers. - If the brand needs something the current roles don't cover, that's a gap
in the shared token layer (
_semantic.scss/_patternfly-overrides.scss), not something to work around per product. See "Extending the role API" below.
Extending the role API
Every role is documented and resolved in one place:
web/src/assets/styles/tokens/_semantic.scss maps each --agm-t--* role onto
the PatternFly tokens it affects, with the current Agama value as the
fallback default. A product file must only ever set --agm-t--* roles, never
a raw PatternFly or component-level variable directly.
Adding a role that's genuinely missing:
- Add the role to
_semantic.scss's role-index comment and resolve it at its real consumption point (a PF global token in_semantic.scss, or a component-level override in_patternfly-overrides.scss), with the current Agama value as the fallback so leaving it unset changes nothing. - Document it with a worked example in
example-advanced.css. - Before assuming one token covers a whole category (e.g. "corner radius"), check whether PatternFly actually splits that concern into several independent tiers under the hood; grep the component CSS for the relevant property and trace each occurrence back to its root token.
Prompting an AI to do this
Fill in the placeholders and paste:
Create a product skin for
<PRODUCT_ID>(an existing product id inweb/src/assets/products/) using this brand:<paste colors, and/or a link to the brand's site or guidelines>.First read
web/src/assets/products/example.css,example-advanced.css, and the role-index comment at the top ofweb/src/assets/styles/tokens/_semantic.scss, so you know the current--agm-t--*role set rather than assuming it. A product file only ever sets these roles; never a raw PatternFly or component-level variable directly.For every color you set: compute WCAG contrast explicitly with
web/scripts/check-contrast.js <foreground> <background> [--target=4.5](run from the repo root;--target=3for UI elements/focus rings), in both light and dark theme separately, rather than eyeballing. Where a brand color fails, use the tool's suggested same-hue/saturation shade rather than an unrelated substitute. Dark-theme elevated surfaces (tooltips, popovers) need to read lighter than the page, not darker.For the logo: read
ProductLogoand its callers first to find the actual rendered size/aspect ratio each usage needs, and match the square-ish shape of existing logos in that folder. Validate any hand-edited SVG withxmllint --nooutand a rendered preview at the real consuming size, in both themes, before calling it done.If something can't be done with the current
--agm-t--*role set, don't get creative. Do not set a raw PatternFly token or component-variable override from the product CSS file, and do not work around the "products only set--agm-t--*roles" contract. Stop and present a plan for extending the shared token API instead: the new role's name, where it gets documented (a role-index comment in_semantic.scss) and resolved (a PF global token in_semantic.scss, or a component-level override in_patternfly-overrides.scss, with the current Agama value as the fallback default so leaving it unset changes nothing), a worked example added toexample-advanced.css, and whether PatternFly actually splits the underlying concern into several independent tokens under the hood (check before assuming one override reaches everywhere it should). Get that plan approved before writing any code.
If you already know the API needs extending
When the brand needs something you already know isn't covered (not just an unexpected gap found mid-task), say so upfront in the same prompt so the AI plans for it from the start instead of discovering it partway through:
This brand also needs
<describe the missing capability, e.g. "square corners on every control, not just buttons">, which the current--agm-t--*role set doesn't cover. Present a plan for the new role before touching any file.
Important
No matter whether an AI or a human wrote it, every line (color values, contrast numbers, SVG content, any role-API change) must be reviewed and manually tested in the running app, in both light and dark mode, before asking for the color schema to be included in the project. A report of "done" or "verified" is not a substitute for someone actually looking at it.