brand
無料Apply this site's visual identity — colours, type, logo files and fixed brand strings. Use for any page, component, social asset or document that should look like the site.
日本語の概要は準備中です。原文の説明を表示しています。
Use when wiring shadcn/ui primitives, forms or admin UI in site-os — the component mechanics, the VBField validation layer, and the UI bugs that have actually shipped here. For brand identity (colour, type, logo, voice) load brand instead; that skill wins on any disagreement.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Scope: how components are wired. For the brand itself — colour, type,
logo usage, the fixed strings, copy voice — the authority is the
brand skill (docs/brand/SKILL.md, revision 4). Where this file
and that one disagree, the brand skill wins; tell the operator so this one
can be corrected rather than quietly working around it.
Brand revision 4 superseded parts of this file. Corrections already applied:
body type is Public Sans (not Inter) with Newsreader for display, the
deep-surface class is .vb-deep (.vb-dark is a deprecated alias), and
docs/brand/tokens.css — not this repo's own :root — is the single source
for brand colour.
shadcn components are not themed from the outside. Each reads a fixed set of
CSS variables (--primary, --border, --ring, --radius…). Those variables
are re-pointed at brand values in src/app/globals.css, so all 40+ primitives —
including ones added next year — render in brand with zero forked files.
Never hard-code a colour in a component. If something looks wrong, the fix is
almost always a token, not a className.
| What | Where |
|---|---|
| Brand tokens (source of truth) | docs/brand/tokens.css, imported once at the top of src/app/globals.css |
| App-only tokens + the shadcn bridge | src/app/globals.css (:root and .dark, .vb-deep) |
| Logo/mark components | src/components/brand/{BrandLogo,BrandMark}.tsx — never hand-assemble a lockup |
| Fixed brand strings | src/lib/brand.ts |
| Tailwind colour/radius mapping | tailwind.config.ts |
| shadcn primitives | src/components/ui/ |
| Validation layer | src/components/ui/vb-field.tsx |
Do NOT add a second theme file. The brief ships a standalone
yoursite-shadcn-theme.css; its contents are already merged into
globals.css. Adding it back creates the exact two-sources-of-truth breakage
the brief itself warns about.
Tailwind is v3 here (@tailwind base/components/utilities, tailwind.config.ts).
Ignore v4 instructions: no @theme inline, no @import "tailwindcss".
Hex, not HSL channels. Config references variables directly —
primary: 'var(--primary)', never hsl(var(--primary)). Wrapping them in
hsl() makes every colour resolve to nothing.
Moved. The colour table, the type roles and the fixed strings are in the
brand skill and in docs/brand/DESIGN-SYSTEM.md §4-5.
Duplicating them here is what let this file go stale against revision 4.
One repo-specific gotcha that is NOT in the brand pack and still applies:
muted in this repo is a text colour (text-muted is used site-wide),
whereas shadcn means it as a surface. Use bg-sand for that surface and
text-muted-foreground for shadcn's text meaning. Don't "fix" this by
redefining muted — it silently wrecks every text-muted on the public site.
A second one, load-bearing for the build: the saffron and green scales in
tailwind.config.ts are hex literals, not var(). Tailwind v3 rewrites
opacity modifiers (bg-saffron-500/10) into rgb(... / <alpha-value>) and
cannot do that arithmetic on a var() holding a hex, so switching them breaks
every alpha class at build time. pnpm brand:check asserts they stay equal to
docs/brand/tokens.css.
Anything not listed needs no change — tokens cover it.
| Component | Rule |
|---|---|
button | default = saffron with ink text. Never text-white. secondary = transparent + 1.5px border-input, hover warms to saffron. Hover lifts 1px. |
toggle / toggle-group | Pressed = saffron tint at 14% behind a saffron hairline (edit the cva variant). shadcn's default bg-accent solid fill reads as a primary button — wrong by default. |
card | Opt in to className="vb-card-accent" for the 3px saffron top rule that grows on hover. Not automatic. |
input / textarea | Prefer VBField (§4) in any validating form. Border: border-input → border-destructive on error → border-accent when valid. |
badge | Four variants: saffron tint (default), green tint (success), outline, red tint (destructive). Mono, uppercase, 0.12em tracking, pill radius. |
alert | Tinted bg at ~8% of its semantic colour + matching 30% border. Left-border accent stripes are banned. |
dialog/alert-dialog/sheet/drawer | Overlay var(--overlay) (warm), never neutral black. Panel radius 28px. No glassmorphism on light. |
tooltip | Dark ink panel (#1c1814) with paper text, even in light mode. |
tabs | Underline: 2px saffron bottom border on active trigger. Not pill/segmented. |
accordion | Chevron → + rotating 45° to ×. Open panel gets sand background. |
sidebar | Ground is sand, not white. Active item = white surface + shadow-xs. |
chart | Use --chart-1…5. Grid at 6% ink; axis labels mono 9–10px. |
calendar | Selected day = saffron tint + saffron hairline + ink text. Never solid saffron fill. |
skeleton | Solid #ece2cf. No shimmer animation. |
globals.css — don't re-add per component):focus-visible.
Do not add per-component focus:ring-2.var(--ease-out) = cubic-bezier(0.16,1,0.3,1), 120–220ms.
Confident settle, never a bounce. prefers-reduced-motion handled globally.✓ in a tinted green circle.currentColor, no fill.VBFieldRules are data, not code. A field carries its own contract, runs it on blur and submit, owns its error slot, reports validity upward.
<VBField
name="key" label="Deployment key" hint="required · min 12" secret
value={v.key} values={v} submitted={submitted}
rules={[{ kind: 'required' }, { kind: 'min', value: 12 }]}
onChange={(key) => setV({ ...v, key })}
/>
Rule kinds: required · email · min · max · pattern · match · custom.
secret adds the eye reveal toggle.
Server-side: import runRules from the same module and re-run the identical
rule array in the route handler. One contract, both sides — never write a
second set of checks.
Use VBField for contact/onboarding/settings forms. Raw Input is fine for
search boxes and other non-validating inputs.
Every item below is a real bug caught on this site, not theory. Check these explicitly — they all passed typecheck and build.
.cta-band p with no explicit
color rendered near-invisible on its dark band. Any element on a coloured
or dark ground needs its colour stated.#f59e0b fails contrast. This is
what --primary-foreground: #1c1814 is for..vb-dark, which sets both background and foreground.
Setting only the background leaves inherited light-mode text on it.absolute child needs BOTH axes anchored. A toggle knob with
absolute top-0.5 but no left-0.5 fell back to a static horizontal
position (left: 22px), so the on/off translate-x shifted from the wrong
origin and every switch looked broken. Verify with getComputedStyle, not
by eye.fixed header needs top clearance on centered pages. min-h-[80vh] flex items-center wrappers rendered their top content under the 72px
fixed header. Add pt-24 on such pages..hero { padding: … }
silently killed .wrap { padding: 0 28px } on the same element (source
order). Use longhand (padding-top/padding-bottom) when two classes share
an element.onClick/onSubmit/action is worse than
no form — it implies a working feature. Either wire it or delete it.Any input that can be wrong gets a rule. No exceptions, no bespoke per-form validation logic.
| Input | Minimum rules |
|---|---|
required + email | |
| Password | required + min (8+) |
| Confirm password | required + match |
| Phone / WhatsApp | required + pattern (digits, country code) |
| Name fields | required + max |
| URL | required (if mandatory) + pattern |
| Numeric config | required + min/max bounds |
| Search / filter | none — non-validating, raw Input is fine |
Rules live in one array, used by both the client field and the server route
(runRules). If a route handler re-implements a check the field already
declares, that's a bug — they will drift.
Feedback states are token-driven, never ad-hoc colours: error =
border-destructive + text-destructive, valid = border-accent +
text-accent, neutral = border-input. Error text goes in the field's own
slot with role="alert", and the slot keeps its height when empty
(min-h-4) so the layout doesn't jump.
Moved to the brand skill (and docs/brand/DESIGN-SYSTEM.md
§3), which also carries the three fixed strings and the banned-word list.
src/lib/brand.ts exports those strings as constants — use them rather than
retyping.
bg-primary renders saffron; text-primary-foreground renders ink, not white.VBField; the route handler imports runRules from it.slate-*, gray-*, blue-*, zinc-*) are not used —
they read cold against the warm ground. Use ink/hairline/sand/muted.pnpm dev —
dynamic/prerender bugs and stale .next-stable type caches don't show up in dev.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Apply this site's visual identity — colours, type, logo files and fixed brand strings. Use for any page, component, social asset or document that should look like the site.
日本語の概要は準備中です。原文の説明を表示しています。
Use FIRST when someone asks for a new feature or a change to an existing one — before any schema, code or test. Works out what is actually being asked for, whether to build it or integrate a third party (Trustpilot, Stripe, Calendly and the like), where the data lives, who may do what, and what happens when the vendor is down. Produces a decision, then hands to feature-schema.
日本語の概要は準備中です。原文の説明を表示しています。
Use when a new feature needs a table, column or capability — evolving the schema so the new thing joins the permission, audit and RLS contract instead of sitting outside it. Covers the DDL/DML split, the resource/capability wiring, and the self-verifying migration.
日本語の概要は準備中です。原文の説明を表示しています。
Use after building a feature — explore it in a real browser to find what nobody predicted, then turn each finding into a deterministic test that guards it forever. Covers the agentic pass, what to generate vs hand-write, and how to skip honestly when a capability is missing.
日本語の概要は準備中です。原文の説明を表示しています。
Publishing content or deploying site-os — what caches exist, what refreshes them, and how to prove a change is actually live. Use when publishing a post or product, launching a page, deploying, or when someone says a change "isn't showing".
日本語の概要は準備中です。原文の説明を表示しています。
Handling secrets, keys and credentials for site-os — reading vigyan-secrets.md safely, moving keys into app_secrets, rotating, and responding to an exposure. Use whenever a task touches a key, token, password, .env file, app_secrets, encryption, or the secrets document.
日本語の概要は準備中です。原文の説明を表示しています。