Yoizen UI design system. Trigger: Yoizen UI components, styling, colors, typography, Angular frontend polish.
64
80%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./ywai/skills/yz-ui/SKILL.mdThese are the mandatory UI norms for every Yoizen frontend — existing repos and new ones alike. The skill is self-contained: tokens, themes, patterns, and copyable artifacts live in assets/. If a project's visuals deviate, the project is wrong, not the norm — correct it with the checklist. Never imitate a legacy project's existing look.
How to apply it to any project: copy the canonical artifacts from assets/. palette.css (tokens, dark + light) and base.css go in verbatim (brand truth). The component CSS (buttons/forms/table/modal/components/shell) and the behavioral primitives (modal/anchored directives, yd-select, yd-date calendar, toasts) are copied and wired/renamed to the project's components. A brand-new app comes out identical — colors, dark/light, animations, tooltips, calendar, responsive — without re-deriving the design.
| File | Read it when |
|---|---|
| references/patterns.md | Building or correcting a specific element. The 14 signature patterns (background, buttons, alerts, toasts, loading, modals, rail, tooltips, selects/date, shell, tables, diff) with their hard-won gotchas. The checklist below points here by number. |
| references/theming.md | Touching the palette, adding a semantic color, or a role that looks wrong in one theme. Token families, the hue/luminosity rule, glass hierarchy, colored shadows. |
| references/assets.md | You need the file on disk: brand logos, the CSS bundle, the TypeScript primitives. |
Yoizen frontends are Angular (standalone components) — never React/JSX.
MANDATORY: latest stable Angular major. Check ng version / package.json; if behind, upgrading is part of the work — one major at a time, per https://angular.dev/update-guide. Run bare ng update first to see everything updatable, and bump the Angular packages together with their peers (@angular/cdk/Material, lucide-angular, …) in the same major step — ng update @angular/core @angular/cli alone leaves peers on the old major (peer-dep conflicts). Never --force (it installs incompatible peers). Commit before each major; ng update runs migration schematics, so review the diff and run the app after each step. New code uses zoneless change detection, signals (input()/output()/computed()), and native control flow (@if/@for/@defer). Never *ngIf/*ngFor, @Input()/@Output() decorators, or NgModules.
Detect the styling approach before writing styles:
| Approach | Detection |
|---|---|
| Pure CSS + design tokens (default) | :root custom properties in palette.css, modular CSS per feature |
| Tailwind CSS 4 | @import "tailwindcss" in styles.css (CSS-first) — never a tailwind.config.js (configure via @theme; see assets/tailwind-theme-schema.json) |
Source of truth: assets/paleta-institucional.png. Exact hexes:
| Color | Hex | Usage |
|---|---|---|
| Primary Blue | #1A66FF | Buttons, links, primary actions |
| Secondary Purple | #4A3ABF | Supportive emphasis, gradients |
| Accent Orange | #FD6421 | Critical CTAs, urgent attention |
| Yellow | #FDBD27 | Auxiliary highlights |
| Dark | #272A35 | Text, dark surfaces |
| Dark Navy / Darker Navy | #00183F / #00122D | Deep dark bg alternatives |
Brand gradients are tokens in palette.css: --grad-full (blue→purple→orange), --grad-brand (blue→purple, for buttons/highlights), --grad-accent, --grad-text (wordmark). Reserve the full gradient for highlights/CTAs — never large surfaces. Never use #000 as a background (use --yz-dark/--yz-dark-soft on dark, or the light ambient gradient). Realign any off-brand blues / muddy grays to these hexes — it's part of any UI work.
The system is one set of CSS custom properties in :root (dark = default) re-themed by a single :root[data-theme="light"] block. Components consume var(--*) and never raw hex. Non-negotiables:
assets/palette.css and assets/base.css verbatim. Tokens live only in palette.css. Never build a second, parallel token system for light.base.css carries the mandatory ambient glow. Always ship backdrop-filter with its -webkit- prefix.-soft + -border pair, defined in both theme blocks.The reasoning behind each of these, the full token family list, and the glass-hierarchy rules are in references/theming.md — read it before touching the palette.
Audit a screen against this. Each item names the pattern in references/patterns.md that carries the fix.
1px solid #ccc + flat 0 1px 2px shadow → --panel-border/-strong + --shadow-glass / .glass. A colour-tinted shadow that leaves a halo over white → token that goes neutral in light (theming).--space-* tokens.--text/--text-soft/--text-muted/--text-faint + type scale.--radius-sm/md/lg; pills for badges and (dark) buttons.transition: all / keyframes without a prefers-reduced-motion guard → 140–150ms ease, named properties, guard every keyframe (#2).currentColor (Iconography).backdrop-filter without -webkit-, or dark theme missing color-scheme: dark → add both.role=dialog/focus-trap/scroll-lock/Escape) → [yzModal] + .overlay/.modal (#8).title, icon-only control with no hover hint, a tooltip that's the only carrier of an error, or a tip echoing already-visible text → [data-tip] + aria-label (#10).<select>/<input type=date> OS chrome → themed yd-select/yd-date (#11).Correct at the token level first (palette/base), then per-component — a fixed palette improves every screen at once. The audit is done only when all 18 items have been checked against the screen — not the first few that obviously match.
Copy the canonical files from assets/ and import them once from styles.css, in this order (later files consume the tokens):
@import "./styles/palette.css"; /* tokens only — dark + light */
@import "./styles/base.css"; /* reset, ambient bg, scrollbar, focus, glass, theme reveal */
@import "./app/shared/styles/buttons.css";
@import "./app/shared/styles/forms.css"; /* inputs, fields, yd-select, yd-cal */
@import "./app/shared/styles/table.css"; /* data-table + col-hide-* responsive */
@import "./app/shared/styles/modal.css";
@import "./app/shared/styles/components.css"; /* pills, tags, cards, headers, KPI, alerts, spinner, skeleton, empty, toasts, tooltips, diff, kv */
@import "./app/layout/shell.css"; /* reference shell — swap per app */
/* feature-specific styles stay under ./app/features/<feature>/ */Mandatory icon set: Lucide (lucide-angular) — uniform 2px-stroke outline icons. One set per app; never mix libraries or use emojis/ad-hoc SVGs when a Lucide icon exists.
import { LucideAngularModule, Search } from 'lucide-angular';
@Component({ imports: [LucideAngularModule], template: `<lucide-icon [img]="SearchIcon" [size]="20" />` })
export class MyComponent { protected readonly SearchIcon = Search; }stroke-width: 2; never mix widths or outline/filled.currentColor — never hardcode. Semantic icons take the semantic token; interactive icons follow their button/link color..btn-icon in buttons.css, or .icon-act for inline row actions in components.css) + an aria-label.ChangeDetectionStrategy.OnPush on every component, zoneless app. Derive view state with computed(); don't recompute in the template.@for must declare track (stable id) so rows aren't re-created.loadComponent; defer heavy/below-the-fold blocks with @defer.transform/opacity (compositor-only); keep the ambient glow a fixed body::before (not background-attachment: fixed) to avoid full repaints on scroll.YoizenSA/dev-ai-workflow
36f5af5
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.