blade-ui
Grounded stack guidance: pull idiomatic Do/Don't + docs URLs from the
adopted stack corpus before improvising — ./scripts-run <skills-root>/corpus-grounding/scripts/ground search --manifest <skills-root>/design-intelligence/data/manifest.json --stack laravel "<topic>"
(the laravel stack file is Blade/UI-scoped, not general Laravel). See
design-intelligence.
Positioning — dispatched, not standalone
blade-ui is the apply-step executor for the Blade stack. It is
invoked by directives/ui/apply.ts
once the design brief is locked, and revisited by review.ts /
polish.ts during the design-review loop. It does not own the
flow, does not drive the audit, and does not lock the design.
When to use
Cite this skill when:
state.stack.frontend == "blade" (or the project is clearly Blade-only without Livewire / Flux) and directives/ui/apply.ts dispatches to this skill
- Editing or creating Blade views, components, partials, layouts, or forms
Do NOT use when:
- API-only endpoints (use
api-endpoint skill)
- Livewire components (use
livewire skill — it composes Blade views internally)
- Flux UI components (use
flux skill)
- Driving the full UI flow yourself — that is the
directives/ui/ orchestrator
Procedure: Create Blade view or component
Step 0: Inspect
- Confirm Blade is used — check
resources/views, components, layouts.
- Inspect existing UI patterns — layouts, partials, component naming, CSS conventions.
- Check form handling style — old input, validation errors, session flashes, reusable field partials.
- Inspect neighboring templates — match indentation, directives, slot usage, classes.
- Determine data flow — what belongs in controller/view model vs. template.
Step 1: Create the template
- Use the project's existing layout system.
- Keep template presentation-focused — no business logic, no DB queries.
- Extract repeated sections into partials or components.
Step 2: Handle forms (if applicable)
- Follow project's form style for labels, inputs, validation messages.
- Use CSRF protection correctly.
- Render validation errors consistently.
- Preserve user input with
old() or project conventions.
- Reuse existing field components — don't duplicate.
Step 3: Validate
- Check escaping —
{{ }} by default, {!! !!} only when explicitly safe.
- Check styling — Tailwind utility classes, not inline styles.
- Check accessibility — labels for form fields, semantic HTML.
Conventions
→ See guideline php/blade-ui.md for full conventions.
Output format
- Blade view or component file(s) following project conventions
- Component class (if applicable) with typed props
Review pass — a11y findings + preview envelope
When this skill is dispatched by directives/ui/review.ts (test slot)
or directives/ui/polish.ts (verify slot) — i.e. a review/polish run,
not the initial apply — it also emits:
state.ui_review.a11y — {violations: [{rule, selector, severity}, ...], severity_floor?, accepted_violations?}. Use the same (rule, selector)
shape as state.ui_audit.a11y_baseline so the engine's de-dup matches
pre-existing entries on replay. Omit the envelope on apply passes; the
engine's _apply_a11y_gate only fires when a baseline is present.
state.ui_review.preview — {render_ok: bool, screenshot_path?, dom_dump_path?, error?, skipped?, skip_reason?}. Render evidence is
required, not optional on a review/polish pass: you MUST drive the
headless browser (Playwright + axe-core) against the rendered output and
write render_ok. Omitting it now triggers the preview_render_required
halt — a render-capable stack can no longer claim success without
rendering. render_ok: false with error populated triggers the
preview_render_failed halt; render_ok: true with screenshot_path
threads the screenshot into the delivery report's artifacts list. The
only no-render path is an explicit, reasoned skip: set skipped: true
plus a skip_reason (e.g. no Playwright runner in this env). Browser
tooling (Playwright/Cypress/…) is a consumer-project dependency — this
package does not ship one.
Polish dispatch: when the dispatcher skips review because a previous
review pass already returned SUCCESS, this skill MUST itself
synthesise the updated state.ui_review.findings (including any
remaining a11y_violation entries) so the engine's gate sees the
current state on the next polish round.
Gotcha
@include shares parent scope — components don't. Know the difference.
- Always use Tailwind utility classes — not inline styles.
- Don't put business logic in templates — use view composers or Livewire.
Taste Dials
When DESIGN.md declares ## Taste Dials, honour them: Variance → layout-family spread + asymmetry tolerance; Motion → animation budget + reduced-motion posture; Density → spacing scale + information-per-viewport. Absent → follow the design brief's inferred dials.
Do NOT
- Do NOT use
{!! !!} with user input — XSS risk.
- Do NOT put business logic in Blade templates — use Livewire or view composers.
- Do NOT use inline styles — use Tailwind utility classes.
Anti-slop
Before shipping a Blade view, pull
docs/guidelines/design-antipatterns.md
and scan Visual / Typography / Layout — the Blade markup is where side-stripe
accents (V1), icon-tile feature cards (T3), and the centered-hero + 3-column
template (L1/L2) concretely land. Stack-specific Tailwind class/hex bans live in
tailwind-engineer.
Auto-trigger keywords
- Blade template
- Blade component
- Laravel view
- partial
- view logic
1---2name: blade-ui3description: Use when the project's frontend stack is Blade — dispatched by `directives/ui/{apply,review,polish}.ts`. Covers views, components, partials, layouts, and view logic.4---56# blade-ui78> **Grounded stack guidance:** pull idiomatic Do/Don't + docs URLs from the9> adopted stack corpus before improvising — `./scripts-run10> <skills-root>/corpus-grounding/scripts/ground search --manifest11> <skills-root>/design-intelligence/data/manifest.json --stack laravel "<topic>"`12> (the `laravel` stack file is Blade/UI-scoped, not general Laravel). See13> [`design-intelligence`](../design-intelligence/SKILL.md).1415## Positioning — dispatched, not standalone1617`blade-ui` is the **apply-step executor** for the Blade stack. It is18invoked by [`directives/ui/apply.ts`](../../templates/scripts/work_engine/directives/ui/apply.ts)19once the design brief is locked, and revisited by `review.ts` /20`polish.ts` during the design-review loop. It does **not** own the21flow, does **not** drive the audit, and does **not** lock the design.2223| Concern | Owner |24|---|---|25| Audit + token inventory (mandatory pre-step) | [`existing-ui-audit`](../existing-ui-audit/SKILL.md) |26| Design brief (layout / states / microcopy) | [`directives/ui/design.ts`](../../templates/scripts/work_engine/directives/ui/design.ts) |27| Universal design heuristics | [`fe-design`](../fe-design/SKILL.md) |28| Review + polish loop | [`directives/ui/review.ts`](../../templates/scripts/work_engine/directives/ui/review.ts) + [`polish.ts`](../../templates/scripts/work_engine/directives/ui/polish.ts) |2930## When to use3132Cite this skill when:3334- `state.stack.frontend == "blade"` (or the project is clearly Blade-only without Livewire / Flux) and `directives/ui/apply.ts` dispatches to this skill35- Editing or creating Blade views, components, partials, layouts, or forms3637Do NOT use when:3839- API-only endpoints (use `api-endpoint` skill)40- Livewire components (use `livewire` skill — it composes Blade views internally)41- Flux UI components (use `flux` skill)42- Driving the full UI flow yourself — that is the `directives/ui/` orchestrator4344## Procedure: Create Blade view or component4546### Step 0: Inspect47481. Confirm Blade is used — check `resources/views`, components, layouts.492. Inspect existing UI patterns — layouts, partials, component naming, CSS conventions.503. Check form handling style — old input, validation errors, session flashes, reusable field partials.514. Inspect neighboring templates — match indentation, directives, slot usage, classes.525. Determine data flow — what belongs in controller/view model vs. template.5354### Step 1: Create the template55561. Use the project's existing layout system.572. Keep template presentation-focused — no business logic, no DB queries.583. Extract repeated sections into partials or components.5960### Step 2: Handle forms (if applicable)61621. Follow project's form style for labels, inputs, validation messages.632. Use CSRF protection correctly.643. Render validation errors consistently.654. Preserve user input with `old()` or project conventions.665. Reuse existing field components — don't duplicate.6768### Step 3: Validate69701. Check escaping — `{{ }}` by default, `{!! !!}` only when explicitly safe.712. Check styling — Tailwind utility classes, not inline styles.723. Check accessibility — labels for form fields, semantic HTML.7374## Conventions7576→ See guideline `php/blade-ui.md` for full conventions.7778## Output format79801. Blade view or component file(s) following project conventions812. Component class (if applicable) with typed props8283### Review pass — a11y findings + preview envelope8485When this skill is dispatched by `directives/ui/review.ts` (test slot)86or `directives/ui/polish.ts` (verify slot) — i.e. a review/polish run,87not the initial apply — it also emits:8889- `state.ui_review.a11y` — `{violations: [{rule, selector, severity}, ...],90 severity_floor?, accepted_violations?}`. Use the same `(rule, selector)`91 shape as `state.ui_audit.a11y_baseline` so the engine's de-dup matches92 pre-existing entries on replay. Omit the envelope on apply passes; the93 engine's `_apply_a11y_gate` only fires when a baseline is present.94- `state.ui_review.preview` — `{render_ok: bool, screenshot_path?,95 dom_dump_path?, error?, skipped?, skip_reason?}`. **Render evidence is96 required, not optional** on a review/polish pass: you MUST drive the97 headless browser (Playwright + axe-core) against the rendered output and98 write `render_ok`. Omitting it now triggers the `preview_render_required`99 halt — a render-capable stack can no longer claim success without100 rendering. `render_ok: false` with `error` populated triggers the101 `preview_render_failed` halt; `render_ok: true` with `screenshot_path`102 threads the screenshot into the delivery report's `artifacts` list. The103 only no-render path is an **explicit, reasoned skip**: set `skipped: true`104 plus a `skip_reason` (e.g. no Playwright runner in this env). Browser105 tooling (Playwright/Cypress/…) is a consumer-project dependency — this106 package does not ship one.107108Polish dispatch: when the dispatcher skips `review` because a previous109review pass already returned `SUCCESS`, this skill MUST itself110synthesise the updated `state.ui_review.findings` (including any111remaining `a11y_violation` entries) so the engine's gate sees the112current state on the next polish round.113114## Gotcha115116- `@include` shares parent scope — components don't. Know the difference.117- Always use Tailwind utility classes — not inline styles.118- Don't put business logic in templates — use view composers or Livewire.119120## Taste Dials121122When `DESIGN.md` declares `## Taste Dials`, honour them: Variance → layout-family spread + asymmetry tolerance; Motion → animation budget + reduced-motion posture; Density → spacing scale + information-per-viewport. Absent → follow the design brief's inferred dials.123124## Do NOT125126- Do NOT use `{!! !!}` with user input — XSS risk.127- Do NOT put business logic in Blade templates — use Livewire or view composers.128- Do NOT use inline styles — use Tailwind utility classes.129130## Anti-slop131132Before shipping a Blade view, pull133[`docs/guidelines/design-antipatterns.md`](../../../docs/guidelines/design-antipatterns.md)134and scan Visual / Typography / Layout — the Blade markup is where side-stripe135accents (V1), icon-tile feature cards (T3), and the centered-hero + 3-column136template (L1/L2) concretely land. Stack-specific Tailwind class/hex bans live in137[`tailwind-engineer`](../tailwind-engineer/SKILL.md).138139## Auto-trigger keywords140141- Blade template142- Blade component143- Laravel view144- partial145- view logic