@mohammadhprp/system-prompt 0.12.1 → 0.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/framework/agents/README.md +0 -1
- package/framework/commands/README.md +1 -1
- package/framework/commands/mr.md +8 -9
- package/framework/commands/review.md +1 -1
- package/framework/mcps/README.md +0 -4
- package/framework/plugins/ponytail/README.md +0 -1
- package/framework/plugins/ponytail/capabilities.md +1 -1
- package/framework/references/standards/api.md +0 -1
- package/framework/references/standards/architecture.md +0 -1
- package/framework/references/standards/database.md +0 -1
- package/framework/references/standards/debugging.md +0 -1
- package/framework/references/standards/documentation.md +0 -1
- package/framework/references/standards/logging.md +0 -1
- package/framework/references/standards/naming.md +0 -1
- package/framework/references/standards/observability.md +0 -1
- package/framework/references/standards/performance.md +0 -1
- package/framework/references/standards/pull-requests.md +0 -1
- package/framework/references/standards/security.md +0 -1
- package/framework/references/standards/testing.md +0 -1
- package/framework/skills/README.md +4 -14
- package/framework/skills/glab/SKILL.md +222 -0
- package/framework/skills/glab/references/commands-detailed.md +616 -0
- package/framework/skills/glab/references/quick-reference.md +145 -0
- package/framework/skills/glab/references/troubleshooting.md +669 -0
- package/framework/skills/improve/SKILL.md +135 -0
- package/framework/skills/improve/examples.md +19 -0
- package/framework/skills/improve/references/audit-playbook.md +130 -0
- package/framework/skills/improve/references/closing-the-loop.md +96 -0
- package/framework/skills/improve/references/plan-template.md +197 -0
- package/framework/skills/jira-cli/SKILL.md +260 -0
- package/framework/skills/jira-cli/references/commands-detailed.md +268 -0
- package/framework/skills/jira-cli/references/quick-reference.md +111 -0
- package/framework/skills/jira-cli/references/troubleshooting.md +114 -0
- package/framework/skills/laravel-best-practices/SKILL.md +56 -216
- package/framework/skills/laravel-best-practices/references/architecture.md +1 -1
- package/framework/skills/laravel-best-practices/references/checklist.md +139 -0
- package/framework/skills/laravel-best-practices/references/eloquent.md +4 -2
- package/framework/skills/laravel-best-practices/references/infer-conventions.md +97 -0
- package/framework/skills/laravel-best-practices/references/pest-testing.md +47 -18
- package/framework/skills/laravel-best-practices/references/security.md +1 -1
- package/framework/skills/laravel-best-practices/references/style.md +1 -1
- package/framework/skills/laravel-best-practices/references/tailwindcss.md +0 -1
- package/framework/styles/README.md +9 -4
- package/framework/styles/factory/DESIGN.md +360 -0
- package/framework/styles/factory/README.md +32 -0
- package/framework/styles/factory/assets/preview.jpg +0 -0
- package/framework/styles/huly/DESIGN.md +449 -0
- package/framework/styles/huly/README.md +32 -0
- package/framework/styles/huly/assets/preview.jpg +0 -0
- package/framework/styles/notion/DESIGN.md +423 -0
- package/framework/styles/notion/README.md +32 -0
- package/framework/styles/notion/assets/preview.jpg +0 -0
- package/package.json +1 -1
- package/src/catalog.js +7 -19
- package/framework/agents/backend-architect.md +0 -146
- package/framework/mcps/github-mcp/README.md +0 -51
- package/framework/mcps/github-mcp/capabilities.md +0 -83
- package/framework/mcps/github-mcp/configs/.env.example +0 -1
- package/framework/mcps/github-mcp/configs/opencode.json +0 -13
- package/framework/mcps/github-mcp/install.md +0 -60
- package/framework/mcps/github-mcp/troubleshooting.md +0 -79
- package/framework/mcps/gitlab-mcp/README.md +0 -53
- package/framework/mcps/gitlab-mcp/capabilities.md +0 -216
- package/framework/mcps/gitlab-mcp/configs/.env.example +0 -2
- package/framework/mcps/gitlab-mcp/configs/opencode.json +0 -13
- package/framework/mcps/gitlab-mcp/install.md +0 -99
- package/framework/mcps/gitlab-mcp/troubleshooting.md +0 -116
- package/framework/mcps/jira-mcp/README.md +0 -52
- package/framework/mcps/jira-mcp/capabilities.md +0 -79
- package/framework/mcps/jira-mcp/configs/.env.example +0 -2
- package/framework/mcps/jira-mcp/configs/opencode.json +0 -13
- package/framework/mcps/jira-mcp/install.md +0 -94
- package/framework/mcps/jira-mcp/troubleshooting.md +0 -113
- package/framework/mcps/notion-mcp/README.md +0 -57
- package/framework/mcps/notion-mcp/capabilities.md +0 -118
- package/framework/mcps/notion-mcp/configs/opencode.json +0 -9
- package/framework/mcps/notion-mcp/install.md +0 -70
- package/framework/mcps/notion-mcp/troubleshooting.md +0 -95
- package/framework/skills/brainstorming/SKILL.md +0 -159
- package/framework/skills/brainstorming/examples.md +0 -49
- package/framework/skills/brainstorming/scripts/frame-template.html +0 -213
- package/framework/skills/brainstorming/scripts/helper.js +0 -167
- package/framework/skills/brainstorming/scripts/server.cjs +0 -723
- package/framework/skills/brainstorming/scripts/start-server.sh +0 -209
- package/framework/skills/brainstorming/scripts/stop-server.sh +0 -120
- package/framework/skills/brainstorming/visual-companion.md +0 -291
- package/framework/skills/code-review/SKILL.md +0 -72
- package/framework/skills/code-review/examples.md +0 -31
- package/framework/skills/codenavi/SKILL.md +0 -306
- package/framework/skills/codenavi/examples.md +0 -33
- package/framework/skills/codenavi/references/coding-principles.md +0 -143
- package/framework/skills/codenavi/references/notebook-spec.md +0 -171
- package/framework/skills/create-adr/SKILL.md +0 -429
- package/framework/skills/create-adr/examples.md +0 -35
- package/framework/skills/design/SKILL.md +0 -399
- package/framework/skills/design/examples.md +0 -34
- package/framework/skills/gitlab-mcp/SKILL.md +0 -83
- package/framework/skills/gitlab-mcp/examples.md +0 -31
- package/framework/skills/gitlab-mcp/references/code-review.md +0 -110
- package/framework/skills/gitlab-mcp/references/issues.md +0 -141
- package/framework/skills/gitlab-mcp/references/merge-requests.md +0 -120
- package/framework/skills/gitlab-mcp/references/pipelines.md +0 -67
- package/framework/skills/gitlab-mcp/references/search.md +0 -17
- package/framework/skills/gitlab-mcp/references/webhooks.md +0 -32
- package/framework/skills/gitlab-mcp/references/work-items.md +0 -50
- package/framework/skills/great-interface/SKILL.md +0 -43
- package/framework/skills/great-interface/references/animations.md +0 -205
- package/framework/skills/great-interface/references/better-accessibility.md +0 -106
- package/framework/skills/great-interface/references/better-colors.md +0 -100
- package/framework/skills/great-interface/references/better-interface.md +0 -132
- package/framework/skills/great-interface/references/better-layout.md +0 -76
- package/framework/skills/great-interface/references/better-typography.md +0 -157
- package/framework/skills/great-interface/references/better-ui.md +0 -107
- package/framework/skills/great-interface/references/better-writing.md +0 -109
- package/framework/skills/great-interface/references/choosing-fonts.md +0 -64
- package/framework/skills/great-interface/references/color-formats.md +0 -90
- package/framework/skills/great-interface/references/color-usage.md +0 -118
- package/framework/skills/great-interface/references/contrast.md +0 -79
- package/framework/skills/great-interface/references/css-cheat-sheet.md +0 -65
- package/framework/skills/great-interface/references/details-and-accessibility.md +0 -119
- package/framework/skills/great-interface/references/enter-exit.md +0 -147
- package/framework/skills/great-interface/references/explain-interface.md +0 -126
- package/framework/skills/great-interface/references/find-the-effect.md +0 -94
- package/framework/skills/great-interface/references/focus-and-keyboard.md +0 -131
- package/framework/skills/great-interface/references/forms.md +0 -84
- package/framework/skills/great-interface/references/from-an-image.md +0 -55
- package/framework/skills/great-interface/references/grouping-and-alignment.md +0 -123
- package/framework/skills/great-interface/references/hit-areas.md +0 -94
- package/framework/skills/great-interface/references/icon-transitions.md +0 -102
- package/framework/skills/great-interface/references/icons.md +0 -110
- package/framework/skills/great-interface/references/interface-review.md +0 -148
- package/framework/skills/great-interface/references/motion-and-zoom.md +0 -79
- package/framework/skills/great-interface/references/no-browser.md +0 -73
- package/framework/skills/great-interface/references/palette-generation.md +0 -104
- package/framework/skills/great-interface/references/palette-structure.md +0 -76
- package/framework/skills/great-interface/references/performance.md +0 -88
- package/framework/skills/great-interface/references/picker.md +0 -76
- package/framework/skills/great-interface/references/read-the-system.md +0 -178
- package/framework/skills/great-interface/references/removed-signals.md +0 -38
- package/framework/skills/great-interface/references/review-format.md +0 -46
- package/framework/skills/great-interface/references/scope-resolution.md +0 -88
- package/framework/skills/great-interface/references/screen-readers.md +0 -101
- package/framework/skills/great-interface/references/semantics-and-aria.md +0 -84
- package/framework/skills/great-interface/references/spacing-and-adaptivity.md +0 -159
- package/framework/skills/great-interface/references/spacing-and-sizing.md +0 -121
- package/framework/skills/great-interface/references/surfaces.md +0 -219
- package/framework/skills/great-interface/references/token-naming.md +0 -97
- package/framework/skills/great-interface/references/variable-fonts-and-opentype.md +0 -105
- package/framework/skills/great-interface/references/variant.md +0 -104
- package/framework/skills/great-interface/references/wrapping-and-punctuation.md +0 -55
- package/framework/skills/jira-mcp/SKILL.md +0 -57
- package/framework/skills/jira-mcp/examples.md +0 -31
- package/framework/skills/jira-mcp/references/comments.md +0 -27
- package/framework/skills/jira-mcp/references/issues.md +0 -97
- package/framework/skills/jira-mcp/references/projects.md +0 -39
- package/framework/skills/learning-opportunities/SKILL.md +0 -140
- package/framework/skills/learning-opportunities/examples.md +0 -34
- package/framework/skills/learning-opportunities/references/PRINCIPLES.md +0 -42
- package/framework/skills/notion-mcp/SKILL.md +0 -57
- package/framework/skills/notion-mcp/examples.md +0 -31
- package/framework/skills/notion-mcp/references/comments.md +0 -112
- package/framework/skills/notion-mcp/references/databases.md +0 -193
- package/framework/skills/notion-mcp/references/pages.md +0 -235
- package/framework/skills/spec-driven-eval/SKILL.md +0 -341
- package/framework/skills/spec-driven-eval/examples.md +0 -35
- package/framework/skills/spec-driven-eval/references/quickstart.md +0 -118
- package/framework/skills/spec-driven-eval/references/reference.md +0 -295
- package/framework/skills/technical-design-doc-creator/README.md +0 -411
- package/framework/skills/technical-design-doc-creator/SKILL.md +0 -1484
- package/framework/skills/technical-design-doc-creator/examples.md +0 -35
- package/framework/skills/web-design-guidelines/SKILL.md +0 -65
- package/framework/skills/web-design-guidelines/examples.md +0 -32
- package/framework/skills/web-design-guidelines/references/guideline.md +0 -174
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
|
|
2
|
+
# Infer Conventions
|
|
3
|
+
|
|
4
|
+
Learn how this application writes Laravel, then record what you learn as durable, path-scoped rules other agents will read. You are documenting reality, not improving it.
|
|
5
|
+
|
|
6
|
+
## Ground Rules (read before you start)
|
|
7
|
+
|
|
8
|
+
- Consistency first. The codebase's majority style is the convention. Never judge it, never propose a "better" pattern, never record what the code should do. If the app validates inline everywhere, that is the rule, even if Form Requests would be nicer.
|
|
9
|
+
- Skip what an active tool produces, keep what a tool would fight. Inspect the project's Pint and Rector configuration first; a Rector transformation is tooling-owned only when its package and relevant rule or set are installed and enabled. Active tools may rewrite code toward one canonical form: `$casts` to `casts()`, `$fillable` to attributes, magic accessors to the `Attribute` class, pipe-string rules to arrays, `$signature` to `#[Signature]`, named migrations to anonymous, and many more. When the app already sits at an active tool's target form, the tool owns it, so record nothing. But when the app deliberately holds a form an active tool would refactor away, such as legacy `getXxxAttribute()` accessors the `Attribute` class would replace, no tool can reproduce that choice and an agent defaults the other way. That against-the-grain hold is exactly what to record.
|
|
10
|
+
- Record decisions, not defaults. A consistent pattern earns a rule only when it reflects a choice: the app took one valid option where the framework or common practice offered others, or the pattern would surprise a competent agent. Framework defaults steer nothing, so skip them: anonymous migrations, `$signature` commands, `ShouldQueue` jobs, `casts()` on Laravel 11+, named routes, Rule objects in `app/Rules`, and `Mail::fake()` or `Bus::fake()` to isolate framework services. A real fork is not enough on its own. Weigh the side the app took, and record only the side an agent would not reach for by itself: inline closures everywhere, legacy accessors, a bespoke query layer. Watch for the false fork too. "No Mockery" next to facade fakes is not a choice against Mockery, because they double different things. The test for every candidate: without this rule, would the next agent plausibly write it differently? Only "yes" earns a rule.
|
|
11
|
+
- Architecture choices are the gold. Record presence and deliberate absence. The structural pattern the app commits to is the highest-signal convention and the one no tool can decide: Action classes and how they are invoked (`handle` / `execute` / `__invoke`), service objects, dedicated query objects exposing `builder()`, DTOs (spatie/laravel-data vs readonly classes), Form Request validation vs inline, an events and listeners spine vs direct calls, and domain or module folders. Also record a consistent non-pattern, such as "query Eloquent directly in controllers, no repository layer", so the next agent matches the app's altitude instead of over-engineering.
|
|
12
|
+
- Never duplicate `.ai/rules`. Read `.ai/rules/index.md` and the area files before the sweep. A dimension already covered there is marked done and skipped.
|
|
13
|
+
- Evidence or silence. A convention needs at least 3 consistent examples and no meaningful rival to become a candidate. Every Step 1 verdict applies this bar.
|
|
14
|
+
- The recorded rule states the convention, nothing else. One or two imperative lines: this project does X, so do X here. Keep detection evidence out. No counts, ratios, current usage, file lists, or example paths, because that is proof for the confirm step, not part of the rule. One short syntax fragment at most, and point to `search-docs` for API details.
|
|
15
|
+
|
|
16
|
+
## Process
|
|
17
|
+
|
|
18
|
+
Each step ends on a checkable completion criterion. Do not advance until it holds.
|
|
19
|
+
|
|
20
|
+
Fan out when you can. The sweep is embarrassingly parallel. If your environment can spawn subagents (a Task, dispatch, or equivalent tool), do Step 0 yourself, then hand each checklist group (A to J) and the architecture map to its own subagent. Each subagent runs the greps, reads a few representative files, and returns structured verdicts (dimension, verdict, evidence, proposed glob / title / note). You aggregate, dedupe, then run Steps 3 to 5. It is far faster on a real app. No subagents available? Run the steps in sequence, with the same bar and the same output.
|
|
21
|
+
|
|
22
|
+
### Step 0: Orient
|
|
23
|
+
|
|
24
|
+
Read `composer.json` (installed packages tell you which checklist groups apply), the `pint.json` / PHPStan / Rector config, `.ai/rules/index.md` if present, and most important, map the `app/` tree. List every directory under `app/` (and any `Modules/`, `src/`, `packages/`, or domain root). Every folder beyond Laravel's default skeleton (`Http`, `Models`, `Providers`, `Console`, `Exceptions`) is a structural pattern the app committed to and a high-value rule waiting to be written: `Actions`, `Services`, `Data` or DTOs, `Queries`, `Repositories`, `ViewModels`, `Pipelines`, `Support`, `Enums`, `Contracts`, `Observers`, or `Domain` and module roots. Note each one. You will confirm how it is used in Step 2.
|
|
25
|
+
|
|
26
|
+
This app ships a frontend stack, so the frontend checklist group applies. Sweep it.
|
|
27
|
+
|
|
28
|
+
Done when: you have the applicable checklist groups, the dimensions already recorded in `.ai/rules`, and a list of every non-default `app/` directory mapped to the pattern it represents.
|
|
29
|
+
|
|
30
|
+
### Step 1: Predefined sweep
|
|
31
|
+
|
|
32
|
+
Open `references/checklist.md` and work every applicable dimension using its search hints. Give each exactly one verdict:
|
|
33
|
+
|
|
34
|
+
- Pattern. Clears the bar, rival under ~20% of sites, and reflects a real choice (passes the decisions-not-defaults test). A recording candidate. Cite 2 to 3 example files.
|
|
35
|
+
- Conflict. Both styles present in meaningful numbers. Report the split with counts and example files. Never record a preferred winner while the code remains mixed, even in yolo, because that would describe an aspiration rather than reality. Record only if the user identifies a stable path or context boundary that explains both styles; otherwise defer until the code is reconciled.
|
|
36
|
+
- Default. Consistent, but a framework or common-practice default the agent already writes unprompted. Skip it as a no-op, not a convention.
|
|
37
|
+
- No signal. Under the bar: feature unused, or too few examples. Skip silently (one summary line at most).
|
|
38
|
+
- Tooling-owned or Already-recorded. Skip per the ground rules.
|
|
39
|
+
|
|
40
|
+
Done when: every applicable dimension carries exactly one of those verdicts.
|
|
41
|
+
|
|
42
|
+
### Step 2: Open-ended pass
|
|
43
|
+
|
|
44
|
+
First, close out the architecture map from Step 0. For every non-default `app/` directory you listed, confirm how the pattern is used and apply the same evidence and decisions-not-defaults tests as Step 1. Generator-standard or sparsely used directories such as `Rules`, `Observers`, `Mail`, and `Notifications` are signals to inspect, not automatic conventions. Make genuine structural patterns candidates: Action classes invoked via `handle` / `execute` / `__invoke`, Services constructor-injected, `Queries` objects exposing `builder(): Builder`, DTOs as readonly classes or spatie/laravel-data, module or domain folders as the unit of organization. Scope each qualifying pattern to its own directory glob. Also record a consistent deliberate absence, such as "no repository layer, controllers query Eloquent directly", so the next agent matches the app's altitude.
|
|
45
|
+
|
|
46
|
+
Then find what else makes this codebase itself: base or abstract classes most code extends, traits used everywhere, tenancy or authorization scoping woven through queries, naming schemes, and custom helpers. Same evidence bar, cite files. Record every genuine structural pattern, and cap the other house findings at ~5 so the pass stays high-signal.
|
|
47
|
+
|
|
48
|
+
Done when: every non-default `app/` directory from Step 0 has a verdict, and the pass has produced its cited house findings (or concluded there are none).
|
|
49
|
+
|
|
50
|
+
### Step 3: Confirm
|
|
51
|
+
|
|
52
|
+
Present every candidate in one batch. Per item: dimension, verdict, evidence (counts and files), and the exact proposed `glob` or `globs` / `title` / `note`. Conflicts are presented as questions about an existing context boundary or deferred cleanup, not as a choice of future style.
|
|
53
|
+
|
|
54
|
+
Default mode is confirm: record only what the user approves. Switch to yolo only when the invocation said so ("yolo", "don't ask", "just record them"), then record all pattern candidates without asking. Conflicts still go to the user in yolo.
|
|
55
|
+
|
|
56
|
+
Done when: every candidate is approved, rejected, or (conflicts) decided.
|
|
57
|
+
|
|
58
|
+
### Step 4: Record
|
|
59
|
+
|
|
60
|
+
Make one `record-rule` call for each glob an approved convention applies to. Choose the most specific globs that cover the cited evidence from the mapping table below; if a convention spans models and migrations, record it under both domains so agents discover it from either path. The `note` is the bare convention: strip every trace of detection (see the ground rule). If `record-rule` is unavailable (rules disabled), report the full rule text so the user can enable `BOOST_RULES_ENABLED` or add it by hand.
|
|
61
|
+
|
|
62
|
+
Record this:
|
|
63
|
+
|
|
64
|
+
> Accessors and mutators: use the legacy magic-method style (`getXxxAttribute()` / `setXxxAttribute()`), not the `Attribute` class. Match it in models.
|
|
65
|
+
|
|
66
|
+
Not this:
|
|
67
|
+
|
|
68
|
+
> Accessors/mutators use the legacy magic-method style; the `Attribute`-class style is not used anywhere (13 legacy, 0 Attribute-class), e.g. `app/Models/Post.php`. Match the legacy style in existing models.
|
|
69
|
+
|
|
70
|
+
Done when: every approved item has a successful tool response, and any failure is reported with its rule text.
|
|
71
|
+
|
|
72
|
+
### Step 5: Summarize
|
|
73
|
+
|
|
74
|
+
List recorded rules (file and title), conflicts the user deferred, notable no-signals, and remind the user to commit `.ai/rules` so their team and agents share the conventions.
|
|
75
|
+
|
|
76
|
+
## Glob mapping
|
|
77
|
+
|
|
78
|
+
Attach each rule to the most specific path that covers its evidence. Never a lazy `app/**` when a subtree fits. Match the glob to where the code actually lives, which is not the same in a default skeleton and in a modular or DDD layout. Use the Step 0 `app/` map to pick the real path.
|
|
79
|
+
|
|
80
|
+
Examples:
|
|
81
|
+
|
|
82
|
+
- Models: `app/Models/**` in a default app, or `app/Modules/Blog/Models/**` / `src/Domain/Blog/**` in a modular one.
|
|
83
|
+
- Controllers, routing, validation, responses: `app/Http/**`, or `app/Modules/*/Http/**` when each module owns its HTTP layer.
|
|
84
|
+
- Actions, Services, DTOs: `app/Actions/**`, `app/Services/**`, `app/Data/**`, or the module path the app actually uses.
|
|
85
|
+
- Tests: `tests/**`.
|
|
86
|
+
- Migrations and database: `database/migrations/**`.
|
|
87
|
+
- Truly app-wide (rare, e.g. auth retrieval): `app/**`.
|
|
88
|
+
|
|
89
|
+
`record-rule` takes one glob. When a convention genuinely spans two domains (e.g. UUID keys touch models and migrations), call it once per domain with the same title and note; mentioning another path in the note does not make the rule discoverable there.
|
|
90
|
+
|
|
91
|
+
## Edge cases
|
|
92
|
+
|
|
93
|
+
- Rules disabled or `record-rule` missing: detection is read-only, so Steps 0 to 3 still run, and recording falls back to the manual path in Step 4.
|
|
94
|
+
- Tiny or fresh app: most dimensions land on no-signal. Say so honestly ("not enough code to infer conventions yet") and record nothing.
|
|
95
|
+
- Huge app: each dimension is a bounded grep plus a handful of file reads. Sample representative files, do not read everything.
|
|
96
|
+
- Re-runs: reading `.ai/rules` in Step 0 makes re-runs incremental, so only new or undecided dimensions surface.
|
|
97
|
+
- Non-standard layout (modules, DDD): the open-ended pass catches the layout itself as convention #1. Adapt the globs in the mapping table to the observed paths.
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
name: pest-testing
|
|
3
|
-
description: "Use this skill for Pest PHP testing in Laravel projects only. Trigger whenever any test is being written, edited, fixed, or refactored — including fixing tests that broke after a code change, adding assertions, converting PHPUnit to Pest, adding datasets, and TDD workflows. Always activate when the user asks how to write something in Pest, mentions test files or directories (tests/Feature, tests/Unit, tests/Browser), or needs browser testing, smoke testing multiple pages for JS errors, or architecture tests. Covers: test()/it()/expect() syntax, datasets, mocking, browser testing (visit/click/fill), smoke testing, arch(), Livewire component tests, RefreshDatabase, and all Pest 4 features. Do not use for factories, seeders, migrations, controllers, models, or non-test PHP code."
|
|
4
|
-
license: MIT
|
|
5
|
-
metadata:
|
|
6
|
-
author: laravel
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Pest Testing 4
|
|
1
|
+
# Pest Testing 5
|
|
10
2
|
|
|
11
3
|
## Documentation
|
|
12
4
|
|
|
13
|
-
Use `search-docs` for detailed Pest
|
|
5
|
+
Use `search-docs` for detailed Pest 5 patterns and documentation.
|
|
14
6
|
|
|
15
7
|
## Basic Usage
|
|
16
8
|
|
|
@@ -46,6 +38,7 @@ it('is true', function () {
|
|
|
46
38
|
- Run minimal tests with filter before finalizing: `php artisan test --compact --filter=testName`.
|
|
47
39
|
- Run all tests: `php artisan test --compact`.
|
|
48
40
|
- Run file: `php artisan test --compact tests/Feature/ExampleTest.php`.
|
|
41
|
+
- Run only tests affected by recent changes (Tia): `./vendor/bin/pest --parallel --tia`.
|
|
49
42
|
|
|
50
43
|
## Assertions
|
|
51
44
|
|
|
@@ -82,16 +75,58 @@ it('has emails', function (string $email) {
|
|
|
82
75
|
]);
|
|
83
76
|
```
|
|
84
77
|
|
|
85
|
-
## Pest
|
|
78
|
+
## Pest 5 Features
|
|
86
79
|
|
|
87
80
|
| Feature | Purpose |
|
|
88
81
|
|---------|---------|
|
|
82
|
+
| Tia (Test Impact Analysis) | Rerun only tests affected by recent changes |
|
|
83
|
+
| Time-Balanced Sharding | Split tests across CI shards by execution time |
|
|
84
|
+
| New Validation Expectations | `toBeEmail()`, `toBeUlid()`, `toBeIpAddress()`, and more |
|
|
89
85
|
| Browser Testing | Full integration tests in real browsers |
|
|
90
86
|
| Smoke Testing | Validate multiple pages quickly |
|
|
91
87
|
| Visual Regression | Compare screenshots for visual changes |
|
|
92
|
-
| Test Sharding | Parallel CI runs |
|
|
93
88
|
| Architecture Testing | Enforce code conventions |
|
|
94
89
|
|
|
90
|
+
### Tia (Test Impact Analysis)
|
|
91
|
+
|
|
92
|
+
Tia reruns only tests affected by recent changes and replays cached results for the rest, dramatically reducing suite duration:
|
|
93
|
+
|
|
94
|
+
<!-- Tia Example -->
|
|
95
|
+
```shell
|
|
96
|
+
./vendor/bin/pest --parallel --tia
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- Replayed tests are not skipped — cached tests store everything they produced, including covered lines and branches.
|
|
100
|
+
- Detects Laravel, Symfony, Livewire, and Inertia automatically.
|
|
101
|
+
|
|
102
|
+
### New Validation Expectations
|
|
103
|
+
|
|
104
|
+
Pest 5 ships eight new validation matchers, all supporting `.not` negation:
|
|
105
|
+
|
|
106
|
+
<!-- Pest 5 Validation Expectations -->
|
|
107
|
+
```php
|
|
108
|
+
expect('nuno@pestphp.com')->toBeEmail();
|
|
109
|
+
expect('01ARZ3NDEKTSV4RRFFQ69G5FAV')->toBeUlid();
|
|
110
|
+
expect('192.168.1.1')->toBeIpAddress();
|
|
111
|
+
expect('00:1a:2b:3c:4d:5e')->toBeMacAddress();
|
|
112
|
+
expect('example.com')->toBeHostname();
|
|
113
|
+
expect('example.co.uk')->toBeDomain();
|
|
114
|
+
expect('Zm9vYmFy')->toBeBase64();
|
|
115
|
+
expect('deadbeef')->toBeHexadecimal();
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Time-Balanced Sharding
|
|
119
|
+
|
|
120
|
+
Distribute tests across CI shards by execution time rather than count:
|
|
121
|
+
|
|
122
|
+
<!-- Pest Sharding Example -->
|
|
123
|
+
```shell
|
|
124
|
+
./vendor/bin/pest --update-shards
|
|
125
|
+
./vendor/bin/pest --shard=1/4
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Commit `tests/.pest/shards.json` to the repository so CI shards stay consistent.
|
|
129
|
+
|
|
95
130
|
### Browser Test Example
|
|
96
131
|
|
|
97
132
|
Browser tests run in real browsers for full integration testing:
|
|
@@ -140,14 +175,8 @@ $pages->assertNoJavaScriptErrors()->assertNoConsoleLogs();
|
|
|
140
175
|
|
|
141
176
|
Capture and compare screenshots to detect visual changes.
|
|
142
177
|
|
|
143
|
-
### Test Sharding
|
|
144
|
-
|
|
145
|
-
Split tests across parallel processes for faster CI runs.
|
|
146
|
-
|
|
147
178
|
### Architecture Testing
|
|
148
179
|
|
|
149
|
-
Pest 4 includes architecture testing (from Pest 3):
|
|
150
|
-
|
|
151
180
|
<!-- Architecture Test Example -->
|
|
152
181
|
```php
|
|
153
182
|
arch('controllers')
|
|
@@ -90,7 +90,7 @@ Correct:
|
|
|
90
90
|
|
|
91
91
|
## CSRF Protection
|
|
92
92
|
|
|
93
|
-
Include `@csrf` in all POST/PUT/DELETE Blade forms.
|
|
93
|
+
Include `@csrf` in all POST/PUT/DELETE Blade forms. Inertia doesn't use `@csrf`; its HTTP client sends the `XSRF-TOKEN` cookie back as the `X-XSRF-TOKEN` header, which Laravel accepts in place of the `_token` field.
|
|
94
94
|
|
|
95
95
|
Incorrect:
|
|
96
96
|
```blade
|
|
@@ -44,7 +44,7 @@ Strings — use `Str` and fluent `Str::of()` over raw PHP:
|
|
|
44
44
|
// Incorrect
|
|
45
45
|
$slug = strtolower(str_replace(' ', '-', $title));
|
|
46
46
|
$short = substr($text, 0, 100) . '...';
|
|
47
|
-
$class = substr(strrchr('App\Models\User', '
|
|
47
|
+
$class = substr(strrchr('App\Models\User', '\\'), 1);
|
|
48
48
|
|
|
49
49
|
// Correct
|
|
50
50
|
$slug = Str::slug($title);
|
|
@@ -6,8 +6,11 @@ A curated catalog of design system references from [Refero Styles](https://style
|
|
|
6
6
|
|
|
7
7
|
| Style | Description | Preview |
|
|
8
8
|
| --- | --- | --- |
|
|
9
|
-
| [
|
|
10
|
-
| [
|
|
9
|
+
| [Factory](./factory/README.md) | Terminal war room — stark black canvas, light figure-ground cards, and restrained orange/green data signals. |  |
|
|
10
|
+
| [Huly](./huly/README.md) | Midnight observatory — violet-to-coral aurora hero, dark productivity surfaces, and pill-shaped controls. |  |
|
|
11
|
+
| [Linear](./linear/README.md) | Midnight precision instrument — near-black surfaces, acid-lime accent, tight Inter typography. |  |
|
|
12
|
+
| [Notion](./notion/README.md) | Warm paper notebook — off-white canvas, editorial typography, blue primary action, and playful accent panels. |  |
|
|
13
|
+
| [Raycast](./raycast/README.md) | Midnight command center, coral neon — almost-black canvas, warm coral brand accent, glass navigation. |  |
|
|
11
14
|
|
|
12
15
|
## How Styles Are Organized
|
|
13
16
|
|
|
@@ -15,7 +18,9 @@ Each style entry follows this structure:
|
|
|
15
18
|
|
|
16
19
|
```text
|
|
17
20
|
styles/<style-name>/
|
|
18
|
-
|
|
21
|
+
├── README.md # Concise style overview and implementation guidelines
|
|
22
|
+
├── DESIGN.md # Full design system reference: palette, typography, spacing, components, tokens
|
|
23
|
+
└── assets/ # Preview images and other style assets, when provided
|
|
19
24
|
```
|
|
20
25
|
|
|
21
26
|
## How to Use a Style
|
|
@@ -32,4 +37,4 @@ All styles are sourced from [Refero Styles](https://styles.refero.design/) — a
|
|
|
32
37
|
## Related Repository Areas
|
|
33
38
|
|
|
34
39
|
- [`skills/`](../skills/) contains task-specific procedures for AI coding agents.
|
|
35
|
-
- [`references/standards/`](../references/standards/) contains canonical engineering rules.
|
|
40
|
+
- [`references/standards/`](../references/standards/) contains canonical engineering rules.
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
# Factory — Style Reference
|
|
2
|
+
> Terminal war room at midnight. Factory is a stark black control surface where a single white card lands like a flashlit dispatch — the only object in the room is the work itself.
|
|
3
|
+
|
|
4
|
+
**Theme:** dark
|
|
5
|
+
|
|
6
|
+
Factory operates as a terminal war room: deep black canvas, weight-400 Geist type pressed tight with negative tracking, and generous negative space that lets two functional accents — signal orange and metric green — speak above the noise. The signature move is the light card floating on near-black ground (#eeeeee panels on #101010 canvas), creating stark figure/ground contrast rather than soft elevation. Almost all interaction is carried by monochrome surfaces; chromatic color is reserved for live data states and status pulses, never decoration. Components sit flat with minimal radii, thin 1px borders, and zero shadow dependency — the design earns its depth through contrast and spacing rhythm, not blur or glow.
|
|
7
|
+
|
|
8
|
+
## Tokens — Colors
|
|
9
|
+
|
|
10
|
+
| Name | Value | Token | Role |
|
|
11
|
+
|------|-------|-------|------|
|
|
12
|
+
| Obsidian Canvas | `#101010` | `--color-obsidian-canvas` | Page background, footer base — the void everything else is measured against |
|
|
13
|
+
| Carbon Lift | `#1d1a18` | `--color-carbon-lift` | Raised dark surfaces, nav wells, button fills — one step up from canvas for interactive depth |
|
|
14
|
+
| Ash Stroke | `#3d3a39` | `--color-ash-stroke` | Hairline borders, ghost button outlines, separator lines |
|
|
15
|
+
| Graphite Mid | `#4d4947` | `--color-graphite-mid` | Mid-tone fills for chart bodies, secondary surfaces, neutral data visualization |
|
|
16
|
+
| Warm Granite | `#8a8380` | `--color-warm-granite` | Muted body text, secondary copy, inactive labels — warm gray to soften the black |
|
|
17
|
+
| Pale Stone | `#b8b3b0` | `--color-pale-stone` | Tertiary text, section eyebrows, subdued supporting copy |
|
|
18
|
+
| Bone | `#eeeeee` | `--color-bone` | Primary text, light card surfaces, the single bright figure on dark ground |
|
|
19
|
+
| Chalk | `#fafafa` | `--color-chalk` | High-emphasis light button fill, log-in button, elevated neutral surface |
|
|
20
|
+
| Signal Orange | `#ee6018` | `--color-signal-orange` | Orange decorative accent for icons, marks, and small graphic details |
|
|
21
|
+
| Metric Green | `#a0ca92` | `--color-metric-green` | Green decorative accent for icons, marks, and small graphic details |
|
|
22
|
+
|
|
23
|
+
## Tokens — Typography
|
|
24
|
+
|
|
25
|
+
### Geist — All interface text — body, headings, buttons, nav, hero. Used at weight 400 almost universally; weight 500 is reserved for emphasis (e.g. footer heading). The flat 400-only treatment is a signature: authority is implied by size and tracking, not by bold weight. · `--font-geist`
|
|
26
|
+
- **Substitute:** Inter, system-ui
|
|
27
|
+
- **Weights:** 400, 500
|
|
28
|
+
- **Sizes:** 12, 14, 16, 36, 44, 72
|
|
29
|
+
- **Line height:** 1.0–1.5
|
|
30
|
+
- **Letter spacing:** -0.0400em, -0.0310em, -0.0250em
|
|
31
|
+
- **Role:** All interface text — body, headings, buttons, nav, hero. Used at weight 400 almost universally; weight 500 is reserved for emphasis (e.g. footer heading). The flat 400-only treatment is a signature: authority is implied by size and tracking, not by bold weight.
|
|
32
|
+
|
|
33
|
+
### Geist Mono — Captions, labels, status tags, metric units — always uppercase 12px with tight tracking. Carries the 'terminal' voice that distinguishes engineering surfaces from marketing surfaces. · `--font-geist-mono`
|
|
34
|
+
- **Substitute:** JetBrains Mono, IBM Plex Mono, ui-monospace
|
|
35
|
+
- **Weights:** 400
|
|
36
|
+
- **Sizes:** 12, 14, 16
|
|
37
|
+
- **Line height:** 1.0–1.2
|
|
38
|
+
- **Letter spacing:** -0.0200em
|
|
39
|
+
- **Role:** Captions, labels, status tags, metric units — always uppercase 12px with tight tracking. Carries the 'terminal' voice that distinguishes engineering surfaces from marketing surfaces.
|
|
40
|
+
|
|
41
|
+
### Type Scale
|
|
42
|
+
|
|
43
|
+
| Role | Size | Line Height | Letter Spacing | Token |
|
|
44
|
+
|------|------|-------------|----------------|-------|
|
|
45
|
+
| caption | 12px | 1 | -0.24px | `--text-caption` |
|
|
46
|
+
| body-sm | 14px | 1.43 | — | `--text-body-sm` |
|
|
47
|
+
| body | 16px | 1.5 | — | `--text-body` |
|
|
48
|
+
| heading | 36px | 1.1 | -1.12px | `--text-heading` |
|
|
49
|
+
| heading-lg | 44px | 1.12 | -1.1px | `--text-heading-lg` |
|
|
50
|
+
| display | 72px | 1 | -2.88px | `--text-display` |
|
|
51
|
+
|
|
52
|
+
## Tokens — Spacing & Shapes
|
|
53
|
+
|
|
54
|
+
**Base unit:** 8px
|
|
55
|
+
|
|
56
|
+
**Density:** comfortable
|
|
57
|
+
|
|
58
|
+
### Spacing Scale
|
|
59
|
+
|
|
60
|
+
| Name | Value | Token |
|
|
61
|
+
|------|-------|-------|
|
|
62
|
+
| 8 | 8px | `--spacing-8` |
|
|
63
|
+
| 16 | 16px | `--spacing-16` |
|
|
64
|
+
| 24 | 24px | `--spacing-24` |
|
|
65
|
+
| 32 | 32px | `--spacing-32` |
|
|
66
|
+
| 40 | 40px | `--spacing-40` |
|
|
67
|
+
| 56 | 56px | `--spacing-56` |
|
|
68
|
+
| 80 | 80px | `--spacing-80` |
|
|
69
|
+
| 96 | 96px | `--spacing-96` |
|
|
70
|
+
| 120 | 120px | `--spacing-120` |
|
|
71
|
+
|
|
72
|
+
### Border Radius
|
|
73
|
+
|
|
74
|
+
| Element | Value |
|
|
75
|
+
|---------|-------|
|
|
76
|
+
| nav | 3px |
|
|
77
|
+
| cards | 10px |
|
|
78
|
+
| buttons | 3px |
|
|
79
|
+
| largePanels | 20px |
|
|
80
|
+
|
|
81
|
+
### Layout
|
|
82
|
+
|
|
83
|
+
- **Page max-width:** 1200px
|
|
84
|
+
- **Section gap:** 96px
|
|
85
|
+
- **Card padding:** 24px
|
|
86
|
+
- **Element gap:** 24px
|
|
87
|
+
|
|
88
|
+
## Components
|
|
89
|
+
|
|
90
|
+
### Top Navigation Bar
|
|
91
|
+
**Role:** Persistent header across all pages
|
|
92
|
+
|
|
93
|
+
Transparent over #101010 canvas. Height ~64px. Left-aligned wordmark 'FACTORY' in #eeeeee, 12px Geist Mono uppercase, letter-spacing wide. Nav links (Product, Enterprise, Pricing, News, Company, Careers) in #eeeeee at 14px Geist weight 400, uppercase. Log In = #fafafa fill, 3px radius, #101010 text, 0 14px padding. Contact Sales = ghost text link with arrow, transparent fill, 1px #3d3a39 border, 0px radius, 24px vertical padding.
|
|
94
|
+
|
|
95
|
+
### Dark Filled Button
|
|
96
|
+
**Role:** Primary interactive control in dark contexts
|
|
97
|
+
|
|
98
|
+
Background #1f1d1c, text #eeeeee, 3px border-radius, 0 14px padding, Geist 14px weight 400. No border. Used for actions that commit within a dark surface.
|
|
99
|
+
|
|
100
|
+
### Light Filled Button (Log In)
|
|
101
|
+
**Role:** High-emphasis auth trigger
|
|
102
|
+
|
|
103
|
+
Background #fafafa, text #eeeeee (note: on the light fill, text is inverted to dark in practice — #101010), 3px border-radius, 0 14px padding. The only chromatic-contrast button in the system; appears once in the nav.
|
|
104
|
+
|
|
105
|
+
### Ghost Text Link
|
|
106
|
+
**Role:** Secondary navigation, in-text links, 'Read More' affordances
|
|
107
|
+
|
|
108
|
+
Transparent background, 1px #3d3a39 border, 0px radius (flat), 24px vertical padding, #eeeeee text. Behaves like a typographic button — no fill ever appears on hover, only text/border color shift to #fafafa.
|
|
109
|
+
|
|
110
|
+
### Light Surface Card
|
|
111
|
+
**Role:** Featured content panels, CTAs, case studies — the figure on dark ground
|
|
112
|
+
|
|
113
|
+
Background #eeeeee, 10px border-radius, 24px padding all sides, no shadow. Contains dark text (#101010 or #060505) inside. Often carries a subtle grain/noise texture overlay. This is the system's primary way to create visual hierarchy on dark pages.
|
|
114
|
+
|
|
115
|
+
### Dashboard Frame
|
|
116
|
+
**Role:** Product hero — the live software factory preview
|
|
117
|
+
|
|
118
|
+
macOS window chrome (traffic-light dots) on a #0d0d0d panel with 10px radius. Internal content is a dark grid of metric tiles with 1px #1d1a18 dividers. Header bar: dark fill, Geist Mono 12px uppercase for window title, status dot in #ee6018.
|
|
119
|
+
|
|
120
|
+
### Metric Tile
|
|
121
|
+
**Role:** Individual data cell inside the dashboard
|
|
122
|
+
|
|
123
|
+
No background, 1px #1d1a18 hairline divider, 20px padding. Label: Geist Mono 12px uppercase #b8b3b0, tracking -0.24px. Value: Geist 36px weight 400, #eeeeee, tracking -1.12px. Sparkline below: 40px tall, 1px stroke in #ee6018 or #a0ca92.
|
|
124
|
+
|
|
125
|
+
### CTA Section Card
|
|
126
|
+
**Role:** Conversion closer at page bottom
|
|
127
|
+
|
|
128
|
+
Light card (#eeeeee) ~480px wide, 10px radius, 24px padding, optional grain texture. Eyebrow: Geist Mono 12px uppercase, #ee6018 dot + #101010 text. Headline: Geist 36px weight 400, #101010. CTA: dark filled button using #101010 fill, #eeeeee text, 3px radius.
|
|
129
|
+
|
|
130
|
+
### Status Pulse
|
|
131
|
+
**Role:** Inline 'live' indicator on logos, avatars, section headers
|
|
132
|
+
|
|
133
|
+
6px filled circle in #ee6018 with optional 1px stroke. Sits immediately before label text. No animation required, but pairs with marquee/animation in the marquee logo strip.
|
|
134
|
+
|
|
135
|
+
### Logo Strip (Trust Bar)
|
|
136
|
+
**Role:** Social proof band beneath hero
|
|
137
|
+
|
|
138
|
+
Single row of partner wordmarks on #101010 canvas, all rendered in #8a8380 at consistent visual weight. No card backgrounds, no dividers — just the wordmarks floating in negative space. Separated from surrounding sections by 96px vertical breathing room.
|
|
139
|
+
|
|
140
|
+
### Feature Card Row
|
|
141
|
+
**Role:** Multi-card sections explaining product capabilities
|
|
142
|
+
|
|
143
|
+
Dark cards (transparent on #101010) with 1px #1d1a18 hairline border, 10px radius, 20px padding. 'Read More →' ghost link in footer. No card background fill — the card is implied by the border, not the surface.
|
|
144
|
+
|
|
145
|
+
### Footer
|
|
146
|
+
**Role:** Site footer with link columns and brand mark
|
|
147
|
+
|
|
148
|
+
Background #101010, 96px+ vertical padding. Headings: Geist Mono 12px uppercase #eeeeee. Links: 14px Geist weight 400 #8a8380. No dividers between columns — generous column gap (24–36px) does the separation.
|
|
149
|
+
|
|
150
|
+
## Do's and Don'ts
|
|
151
|
+
|
|
152
|
+
### Do
|
|
153
|
+
- Keep the canvas #101010 on every section. Light cards (#eeeeee) are the only objects allowed to be bright.
|
|
154
|
+
- Use Geist 400 for everything. Reach for weight 500 only when a label must dominate a dense surface (footer headings, key CTAs).
|
|
155
|
+
- Apply negative letter-spacing proportionally to size: -0.04em at 72px, -0.025em at 44px, -0.02em at 12px. Display type earns its weight through tightness, not boldness.
|
|
156
|
+
- Reserve #ee6018 for live status, build-state indicators, and accent strokes in data charts. Never use it as a button fill.
|
|
157
|
+
- Set border-radius to 3px on buttons and nav elements, 10px on cards, 20px on the largest panels. Do not round corners more than this — the system is not soft.
|
|
158
|
+
- Build depth through #eeeeee-on-#101010 contrast and 96px+ section gaps. Do not introduce drop shadows or blur to fake elevation.
|
|
159
|
+
- Use Geist Mono 12px uppercase for eyebrows, status labels, and column headers. This is the system's secondary voice and the fastest way to signal 'instrument, not marketing'.
|
|
160
|
+
|
|
161
|
+
### Don't
|
|
162
|
+
- Do not introduce additional accent colors. The palette is two neutrals (#101010, #eeeeee), one warm gray for muted text (#8a8380), and two functional accents (#ee6018, #a0ca92). Anything else is noise.
|
|
163
|
+
- Do not use weight 600+ or bold for headings. The system speaks at weight 400 with tight tracking — bolding breaks the voice.
|
|
164
|
+
- Do not put #ee6018 or #a0ca92 on button backgrounds, card surfaces, or large text fills. They are data-voice colors, not chrome colors.
|
|
165
|
+
- Do not use line-height above 1.5. Display sizes use lh=1; body sits at 1.5. Anything looser makes the page feel editorial rather than technical.
|
|
166
|
+
- Do not add drop shadows, glows, or blurs to cards, buttons, or modals. The system's elevation is contrast, not depth-of-field.
|
|
167
|
+
- Do not mix in serif typefaces or display fonts. Geist and Geist Mono only.
|
|
168
|
+
- Do not fill buttons with brand color. The primary action is a neutral dark fill (#1f1d1c) or a neutral light fill (#fafafa) — chromatic CTAs would break the monochrome chrome.
|
|
169
|
+
|
|
170
|
+
## Surfaces
|
|
171
|
+
|
|
172
|
+
| Level | Name | Value | Purpose |
|
|
173
|
+
|-------|------|-------|---------|
|
|
174
|
+
| 0 | Obsidian Canvas | `#101010` | Page base, hero, all non-card sections |
|
|
175
|
+
| 1 | Carbon Lift | `#1d1a18` | Nav well, inline buttons, subtle panel elevation |
|
|
176
|
+
| 2 | Bone Card | `#eeeeee` | Light cards on dark ground — the signature figure/ground move |
|
|
177
|
+
| 3 | Chalk Elevated | `#fafafa` | Light button fill, top of the light surface stack |
|
|
178
|
+
|
|
179
|
+
## Elevation
|
|
180
|
+
|
|
181
|
+
No shadows. Depth is built through figure/ground contrast — a #eeeeee card landing on a #101010 canvas does the work a drop shadow would do in other systems. The only box-shadow token observed is a 1px hairline at near-black, never a diffuse glow. This keeps the interface flat and instrument-like.
|
|
182
|
+
|
|
183
|
+
## Imagery
|
|
184
|
+
|
|
185
|
+
Imagery is minimal and product-led. The dominant visual is a photorealistic macOS dashboard screenshot serving as the hero — a real-feeling terminal panel with traffic-light chrome, monospaced column headers, and live sparklines in orange and green. There is no lifestyle photography, no people, no abstract gradients. Decorative texture on light cards is a subtle film-grain noise overlay, not an illustration. Logos in the trust bar are rendered as monochrome wordmarks, not as color photos. The brand relies on UI-in-UI: showing the product is the imagery.
|
|
186
|
+
|
|
187
|
+
## Layout
|
|
188
|
+
|
|
189
|
+
Full-bleed #101010 canvas at all times — no light body background. Max content width ~1200px, centered. Hero is a 2-column split: left third holds the headline + supporting copy + button row, right two-thirds holds the dashboard screenshot at near-1:1 scale. Section rhythm: dark band → logo strip → dark band with feature cards → dark band with CTA card. Vertical spacing between sections is 96px+ — the page breathes. Cards in grid layouts are separated by 24px gaps, never touching. Navigation is a single sticky top bar, no sidebar, no mega-menu — the surface stays uncluttered.
|
|
190
|
+
|
|
191
|
+
## Agent Prompt Guide
|
|
192
|
+
|
|
193
|
+
**Quick Color Reference**
|
|
194
|
+
- canvas: #101010
|
|
195
|
+
- text: #eeeeee
|
|
196
|
+
- muted text: #8a8380
|
|
197
|
+
- card surface: #eeeeee
|
|
198
|
+
- accent (live status / data signal): #ee6018
|
|
199
|
+
- accent (positive metric / trend): #a0ca92
|
|
200
|
+
- primary action: #1d1a18 (filled action)
|
|
201
|
+
|
|
202
|
+
**Example Component Prompts**
|
|
203
|
+
1. *Hero section*: Full-bleed #101010 background, max-width 1200px centered. Headline at 72px Geist weight 400, #eeeeee, letter-spacing -2.88px, line-height 1. Supporting copy at 16px Geist weight 400, #8a8380. Two buttons inline: a dark filled button (#1f1d1c, #eeeeee text, 3px radius, 0 14px padding) followed by a ghost link with arrow (transparent, 1px #3d3a39 border, 0px radius, 24px vertical padding).
|
|
204
|
+
2. Create a Primary Action Button: #1d1a18 background, #eeeeee text, 9999px radius, compact pill padding. Use this filled treatment for the main CTA.
|
|
205
|
+
3. *Dashboard metric tile*: no background, 1px #1d1a18 bottom border, 20px padding. Label: Geist Mono 12px uppercase #b8b3b0. Value: Geist 36px weight 400, #eeeeee, letter-spacing -1.12px. Sparkline: 40px tall, 1px stroke, color #ee6018 (negative trend) or #a0ca92 (positive trend).
|
|
206
|
+
4. *Trust logo strip*: full-width #101010 band, 96px vertical padding, single row of 8 partner wordmarks rendered in #8a8380, evenly distributed with 24px+ gaps. No card backgrounds, no dividers.
|
|
207
|
+
5. *Top nav bar*: transparent on #101010, ~64px tall. Wordmark left: 'FACTORY' Geist Mono 12px uppercase #eeeeee. Nav center/right: Product, Enterprise, Pricing, News, Company, Careers in Geist 14px weight 400 #eeeeee uppercase. Log In button: #fafafa fill, #101010 text, 3px radius. Contact Sales: ghost text link with arrow.
|
|
208
|
+
|
|
209
|
+
## Motion Philosophy
|
|
210
|
+
|
|
211
|
+
Transitions are short and mechanical: 0.15s–0.2s with cubic-bezier(0.4, 0, 0.2, 1) easing — the feel of a CLI tool, not a marketing site. Color, background-color, border-color, and stroke all transition together so state changes feel like a single switch flipping, not a layered animation. Named motion (marquee-scroll, sfDashboardFrameIn) appears sparingly: a slow logo marquee and a single dashboard entrance. Avoid spring physics, parallax, or scroll-driven effects — the surface should feel still and precise.
|
|
212
|
+
|
|
213
|
+
## Voice & Type Treatment
|
|
214
|
+
|
|
215
|
+
Two voices, one family. Geist 400 carries all marketing and body copy — flat, calm, undecorated. Geist Mono 12px uppercase carries all instrument labels: column headers, status tags, 'BUILD WITH US', nav items. This split is structural: when a user sees Mono, they know they are looking at a system surface, not a page surface. Maintain this discipline even when extending the product.
|
|
216
|
+
|
|
217
|
+
## Similar Brands
|
|
218
|
+
|
|
219
|
+
- **Linear** — Same monochrome-dark canvas, weight-400 display type with tight negative tracking, and one restrained accent (Linear's purple vs Factory's orange) reserved for state and status, never decoration.
|
|
220
|
+
- **Vercel** — Identical figure/ground strategy: pitch-black canvas, one bright card or screenshot as hero, Geist-family type at flat weight, no drop shadows — depth earned through contrast.
|
|
221
|
+
- **Resend** — Shares the terminal-warm aesthetic — warm grays (#8a8380 class) instead of cold, Geist Mono labels, minimal radii (3–10px), and chromatic accents used only as functional signal in product UI.
|
|
222
|
+
- **Cursor** — Developer-tool dark surface with Geist-weight typography, dashboard hero pattern showing the product in a windowed UI, and a single warm accent for active states.
|
|
223
|
+
- **Railway** — Same instrument-panel sensibility — dark canvas, monospaced eyebrows, metric tiles with live data, and an anti-decorative stance that treats color as data not chrome.
|
|
224
|
+
|
|
225
|
+
## Quick Start
|
|
226
|
+
|
|
227
|
+
### CSS Custom Properties
|
|
228
|
+
|
|
229
|
+
```css
|
|
230
|
+
:root {
|
|
231
|
+
/* Colors */
|
|
232
|
+
--color-obsidian-canvas: #101010;
|
|
233
|
+
--color-carbon-lift: #1d1a18;
|
|
234
|
+
--color-ash-stroke: #3d3a39;
|
|
235
|
+
--color-graphite-mid: #4d4947;
|
|
236
|
+
--color-warm-granite: #8a8380;
|
|
237
|
+
--color-pale-stone: #b8b3b0;
|
|
238
|
+
--color-bone: #eeeeee;
|
|
239
|
+
--color-chalk: #fafafa;
|
|
240
|
+
--color-signal-orange: #ee6018;
|
|
241
|
+
--color-metric-green: #a0ca92;
|
|
242
|
+
|
|
243
|
+
/* Typography — Font Families */
|
|
244
|
+
--font-geist: 'Geist', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
245
|
+
--font-geist-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
246
|
+
|
|
247
|
+
/* Typography — Scale */
|
|
248
|
+
--text-caption: 12px;
|
|
249
|
+
--leading-caption: 1;
|
|
250
|
+
--tracking-caption: -0.24px;
|
|
251
|
+
--text-body-sm: 14px;
|
|
252
|
+
--leading-body-sm: 1.43;
|
|
253
|
+
--text-body: 16px;
|
|
254
|
+
--leading-body: 1.5;
|
|
255
|
+
--text-heading: 36px;
|
|
256
|
+
--leading-heading: 1.1;
|
|
257
|
+
--tracking-heading: -1.12px;
|
|
258
|
+
--text-heading-lg: 44px;
|
|
259
|
+
--leading-heading-lg: 1.12;
|
|
260
|
+
--tracking-heading-lg: -1.1px;
|
|
261
|
+
--text-display: 72px;
|
|
262
|
+
--leading-display: 1;
|
|
263
|
+
--tracking-display: -2.88px;
|
|
264
|
+
|
|
265
|
+
/* Typography — Weights */
|
|
266
|
+
--font-weight-regular: 400;
|
|
267
|
+
--font-weight-medium: 500;
|
|
268
|
+
|
|
269
|
+
/* Spacing */
|
|
270
|
+
--spacing-unit: 8px;
|
|
271
|
+
--spacing-8: 8px;
|
|
272
|
+
--spacing-16: 16px;
|
|
273
|
+
--spacing-24: 24px;
|
|
274
|
+
--spacing-32: 32px;
|
|
275
|
+
--spacing-40: 40px;
|
|
276
|
+
--spacing-56: 56px;
|
|
277
|
+
--spacing-80: 80px;
|
|
278
|
+
--spacing-96: 96px;
|
|
279
|
+
--spacing-120: 120px;
|
|
280
|
+
|
|
281
|
+
/* Layout */
|
|
282
|
+
--page-max-width: 1200px;
|
|
283
|
+
--section-gap: 96px;
|
|
284
|
+
--card-padding: 24px;
|
|
285
|
+
--element-gap: 24px;
|
|
286
|
+
|
|
287
|
+
/* Border Radius */
|
|
288
|
+
--radius-sm: 3px;
|
|
289
|
+
--radius-lg: 10px;
|
|
290
|
+
--radius-2xl: 20px;
|
|
291
|
+
|
|
292
|
+
/* Named Radii */
|
|
293
|
+
--radius-nav: 3px;
|
|
294
|
+
--radius-cards: 10px;
|
|
295
|
+
--radius-buttons: 3px;
|
|
296
|
+
--radius-largepanels: 20px;
|
|
297
|
+
|
|
298
|
+
/* Surfaces */
|
|
299
|
+
--surface-obsidian-canvas: #101010;
|
|
300
|
+
--surface-carbon-lift: #1d1a18;
|
|
301
|
+
--surface-bone-card: #eeeeee;
|
|
302
|
+
--surface-chalk-elevated: #fafafa;
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Tailwind v4
|
|
307
|
+
|
|
308
|
+
```css
|
|
309
|
+
@theme {
|
|
310
|
+
/* Colors */
|
|
311
|
+
--color-obsidian-canvas: #101010;
|
|
312
|
+
--color-carbon-lift: #1d1a18;
|
|
313
|
+
--color-ash-stroke: #3d3a39;
|
|
314
|
+
--color-graphite-mid: #4d4947;
|
|
315
|
+
--color-warm-granite: #8a8380;
|
|
316
|
+
--color-pale-stone: #b8b3b0;
|
|
317
|
+
--color-bone: #eeeeee;
|
|
318
|
+
--color-chalk: #fafafa;
|
|
319
|
+
--color-signal-orange: #ee6018;
|
|
320
|
+
--color-metric-green: #a0ca92;
|
|
321
|
+
|
|
322
|
+
/* Typography */
|
|
323
|
+
--font-geist: 'Geist', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
324
|
+
--font-geist-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
325
|
+
|
|
326
|
+
/* Typography — Scale */
|
|
327
|
+
--text-caption: 12px;
|
|
328
|
+
--leading-caption: 1;
|
|
329
|
+
--tracking-caption: -0.24px;
|
|
330
|
+
--text-body-sm: 14px;
|
|
331
|
+
--leading-body-sm: 1.43;
|
|
332
|
+
--text-body: 16px;
|
|
333
|
+
--leading-body: 1.5;
|
|
334
|
+
--text-heading: 36px;
|
|
335
|
+
--leading-heading: 1.1;
|
|
336
|
+
--tracking-heading: -1.12px;
|
|
337
|
+
--text-heading-lg: 44px;
|
|
338
|
+
--leading-heading-lg: 1.12;
|
|
339
|
+
--tracking-heading-lg: -1.1px;
|
|
340
|
+
--text-display: 72px;
|
|
341
|
+
--leading-display: 1;
|
|
342
|
+
--tracking-display: -2.88px;
|
|
343
|
+
|
|
344
|
+
/* Spacing */
|
|
345
|
+
--spacing-8: 8px;
|
|
346
|
+
--spacing-16: 16px;
|
|
347
|
+
--spacing-24: 24px;
|
|
348
|
+
--spacing-32: 32px;
|
|
349
|
+
--spacing-40: 40px;
|
|
350
|
+
--spacing-56: 56px;
|
|
351
|
+
--spacing-80: 80px;
|
|
352
|
+
--spacing-96: 96px;
|
|
353
|
+
--spacing-120: 120px;
|
|
354
|
+
|
|
355
|
+
/* Border Radius */
|
|
356
|
+
--radius-sm: 3px;
|
|
357
|
+
--radius-lg: 10px;
|
|
358
|
+
--radius-2xl: 20px;
|
|
359
|
+
}
|
|
360
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Factory — Style Reference
|
|
2
|
+
|
|
3
|
+
> terminal war room at midnight
|
|
4
|
+
|
|
5
|
+
**Theme:** dark
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
Factory is a stark black control surface: an Obsidian canvas, warm-gray supporting text, and a single light card that lands like a dispatch in the dark. Geist and Geist Mono typography, tight tracking, hairline borders, minimal radii, and generous spacing create an instrument-like interface. Signal orange and metric green are reserved for live status and data visualization rather than decorative chrome.
|
|
10
|
+
|
|
11
|
+
## Guidelines
|
|
12
|
+
|
|
13
|
+
### Do
|
|
14
|
+
|
|
15
|
+
- Use #101010 as the page canvas and #eeeeee for the primary light-card surface
|
|
16
|
+
- Use Geist at weight 400 for interface text; reserve weight 500 for focused emphasis
|
|
17
|
+
- Use Geist Mono in uppercase for labels, status tags, and metric units
|
|
18
|
+
- Reserve #ee6018 and #a0ca92 for live status, data signals, and chart strokes
|
|
19
|
+
- Build depth through contrast, spacing, and 1px borders instead of shadows
|
|
20
|
+
- Keep section gaps near 96px, card padding near 24px, and cards near 10px radius
|
|
21
|
+
|
|
22
|
+
### Don't
|
|
23
|
+
|
|
24
|
+
- Do not introduce additional accent colors
|
|
25
|
+
- Do not use bold heading weights or loose editorial typography
|
|
26
|
+
- Do not use orange or green as button, card, or large text fills
|
|
27
|
+
- Do not add drop shadows, glows, or blur to create elevation
|
|
28
|
+
- Do not use lifestyle photography or decorative gradients
|
|
29
|
+
|
|
30
|
+
## Similar Brands
|
|
31
|
+
|
|
32
|
+
Linear, Vercel, Resend, Cursor, Railway
|