Get started

Brand guidelines to Tailwind CSS: map rules into code without losing context

Don't convert an entire brand guide into Tailwind theme variables. Classify each decision first. Reusable values that should create utilities may belong in Tailwind's namespaced theme variables, while runtime values can remain regular CSS variables. Put contextual behavior in CSS or components. Files remain assets, usage restrictions belong in guidance, and undecided rules stay unresolved until an owner decides them.

Updated September 24, 2026

Freeze the source contract before touching Tailwind

A brand guide can put approved rules, suggestions, examples, obsolete material, and open questions on the same page. Tailwind can't resolve those differences. Before translating any rule, write the contract that tells the implementation team what is authoritative.

  • Source identity and version: the exact guide, kit, decision record, or asset release being implemented.
  • Approval state: approved, conditional, or unresolved. A conditional rule must name its condition.
  • Scope: the products, surfaces, modes, locales, and platforms covered by the decision.
  • Decision owner: the person or role allowed to approve or change the brand decision.
  • Implementation owner: the person or role responsible for mapping it into project artifacts.
  • Acceptance owner: the person or role allowed to accept, revise, or block the implementation.
  • Exclusions: the surfaces, states, assets, or behaviors the decision does not govern.
  • Unresolved decisions: missing values, unclear behavior, absent assets, or conflicts that must not be filled by developer preference.

Set a conflict-precedence rule

When sources conflict, the current approved source contract takes precedence. Generated exports, existing components, screenshots, and local overrides are downstream evidence, not authority. A documented exception may override the source only within its named scope. If two approved sources conflict and no precedence exists, mark the row unresolved and block that part of the implementation.

Use /learn/brand-kit-for-web-developers for the broader handoff process. This page focuses on classifying approved rules before implementation. Once a rule has a destination, /learn/tailwind-css-v4-design-tokens covers the detailed framework mechanics and acceptance chain.

Use a decision-ready rule-placement matrix

Make one row for each source decision, not each file. Authority and version show where the decision came from. Portability asks whether its meaning should survive across products or frameworks. Placement criteria determine the destination. Ownership and evidence keep a plausible mapping from being mistaken for an accepted result.

Authority and portabilityPlacement criteria and destinationOwner and required evidenceDisposition
Tailwind theme variablesApproved source and version; a portable role or scale intended to expose a project-wide API.Use an @theme namespace when the decision should create Tailwind utilities or variants, such as a semantic color, font family, breakpoint, or recurring spacing value.The implementation owner supplies the theme mapping and generated-output evidence. The acceptance owner checks named consumers, modes, and states.Accept only within the tested scope; otherwise revise the mapping or block on a missing decision.
Regular CSS variables or custom CSSApproved source and version; a value or behavior needed at runtime but not intended to create a Tailwind API.Use regular CSS variables for runtime values. Use selectors, conditions, pseudo-elements, keyframes, or custom utilities for contextual behavior.The CSS owner supplies the rule, selector, cascade context, and representative rendered observation.Accept when context and reach match the contract; revise accidental global reach; block unresolved behavior.
ComponentsAn approved interaction or structural contract, usually portable in intent but specific to a named primitive or pattern.Place required structure, variants, state behavior, and composition constraints in the component contract.The component owner supplies supported variants and observations for required states, modes, content, and protected consumers.Accept, revise, or block the component within the named consumer scope.
Static assetsAn approved asset release and version; the file is authoritative while its placement rules may be portable guidance.Store logos, icons, illustrations, textures, and imagery as assets. Don't turn an image or logo lockup into a theme token.The asset owner supplies file identity, format, approved variants, usage restrictions, and a rendered instance where required.Accept the named asset, revise an incorrect file or placement, or block when the approved variant is missing.
DESIGN.md guidanceApproved portable intent, restrictions, and selection rules that a coding agent or contributor must read.Put usage prohibitions, motif rules, asset-selection criteria, and explanations of when to choose an existing role in machine-readable guidance.The guidance owner supplies the exact rule and governed scope. Acceptance checks implementation; the file alone isn't runtime proof.Accept documented intent, revise ambiguity, or block when the missing rule would require invention.
Approved local exceptionA named approval that differs from the general rule; deliberately non-portable and bounded.Record the surface, condition, reason, approver, expiry or review trigger, and the general rule it overrides.The local implementation owner supplies the override and proof that it doesn't leak into protected surfaces.Accept only for the recorded scope; revise leakage; block an undocumented override.
Unresolved workNo approved authority, conflicting sources, or a missing decision; portability may also be unknown.Don't encode a guess as a token, utility, component default, or agent instruction. Record the question and dependency.The decision owner supplies the missing decision. Implementation evidence can't substitute for it.Block the affected scope until resolved while unrelated approved rows proceed.
Apply these criteria to each approved brand decision.

Data type alone doesn't determine the destination. A number may be a portable spacing step, a component-owned control height, a responsive layout threshold, or an approved one-page exception. Ask who owns the decision, where it may vary, and what evidence would show that it reached the intended consumers.

Draw the Tailwind v4 boundary precisely

The captured Tailwind CSS v4.3 documentation defines theme variables as special CSS variables declared with @theme. Their namespaces create framework APIs. A --color-* variable can create color utilities, and a --font-* variable can create font-family utilities. An ordinary CSS variable remains available to CSS, but its name alone doesn't create a Tailwind utility.

:root {
  --background: #f3f4ef;
}

.dark {
  --background: #1f211d;
}

@theme inline {
  --color-background: var(--background);
}

.page-shell {
  @apply bg-background;
}
Illustrative Tailwind CSS v4.3 mapping. The regular property holds the mode value; the namespaced theme variable exposes it to Tailwind's color utility API.

Here, --background is the semantic runtime property. The @theme mapping gives Tailwind a namespaced color role from which bg-background can be generated. This code doesn't prove that the source value is approved, the dark selector matches the project's mode policy, the built CSS contains the intended output, or a page consumes it. Each claim needs its own evidence.

Keep contextual behavior outside the theme. A decorative motif positioned differently inside a hero, a logo clear-space rule, or a dense-table exception doesn't become reusable when assigned a global token. Tailwind's custom-style route can express project CSS when utilities aren't the right contract. Components should own recurring structure and interaction behavior.

Dark mode contains two decisions

The semantic source decides the light and dark values. The application separately decides how to activate dark mode, such as with a selector or data attribute. Tailwind documents dark variants and selector customization, but it doesn't choose the product's theme policy.

Place colors, spacing, layout, motifs, and assets by behavior

Colors and interaction states

Start with a semantic role such as background, primary, destructive, or border, then record its light and dark values. Don't infer hover, focus, selected, disabled, or error behavior from a palette swatch. If the source defines a reusable state role, map it deliberately. If a button owns a state-specific decision, keep it in the Button contract. If the source is silent, mark the state unresolved instead of creating a darker shade by habit.

Spacing and responsive layout

A recurring spacing scale used across unrelated components can belong in the theme. A page grid, overlapping hero, or conditional sidebar may need custom CSS because its meaning depends on composition. Button padding belongs in the component contract when the component must change as a unit. A one-off reduction for a named narrow surface can be an approved exception. A breakpoint should enter the theme only when the source approves it as a shared responsive boundary, not because one mockup was drawn at that width.

Motifs, imagery, logos, and prohibitions

A motif may need an asset, placement CSS, and a written usage rule. Keep the image or SVG in the asset system. Put contextual placement in CSS or a component, and restrictions such as "never place behind body copy" in DESIGN.md. Logo files and approved variants remain assets. Minimum size, clear space, background restrictions, and prohibited alterations belong in guidance and may require component or CSS enforcement. Image subjects, crop direction, and selection criteria belong in guidance until the project has a named component contract. If no approved mobile crop or monochrome logo exists, record unresolved work instead of manufacturing one.

One decision can produce several artifacts

A rule can span an asset, CSS, a component, and DESIGN.md when each artifact carries a different responsibility. The acceptance record should connect all of them to the same source decision.

Keep typography as a chain of separate decisions

Typography isn't a single Tailwind setting. First record the upstream role, family, available weights, and scale direction. Then decide the Tailwind namespace mapping, font-file delivery, fallback stack, loading policy, named consumers, and required rendered evidence separately.

RecordDo not infer
Upstream contractFamily by role, available weights, scale direction, approval state, and source version.That files are present, licensed for the project, or successfully delivered.
Tailwind mappingFor v4.3, the selected --font-* and any --text-* mappings intended to create utilities.That declaring a family loads its files or makes every requested weight available.
Font deliveryFile or package identity, @font-face declarations, formats, weight ranges, fallback stack, and font-display value.That a valid declaration produces the intended face under every network and glyph condition.
Consumers and evidenceNamed headings, body text, controls, data, and code samples; test strings; expected and observed faces, weights, wrapping, and fallback behavior.That a theme preview proves the consuming application behaves the same way.
Each typography layer answers a different question.

The font-display values aren't a simple choice between unstyled text and blank space. MDN describes swap as an extremely small block period followed by an infinite swap period. fallback uses an extremely small block period and a short swap period. optional uses an extremely small block period and no swap period. The exact durations depend on the user agent. Record the chosen policy, then observe the project under the loading conditions required by its scope.

Record Ambient Sage as upstream intake only

Ambient Sage v1 shows what an upstream intake record can contain. Its frozen evidence identifies Plus Jakarta Sans for heading and body roles at weights 400, 500, 600, and 700. The kit assigns JetBrains Mono to the mono role at weights 400, 500, and 700. Its published scale direction is compact-product. The public kit also supplies semantic light and dark tokens and implementation artifacts.

Token specimen · real values

Ambient Sage

Live render

Ambient Sage's actual tokens — the same values its exports use.

Color tokensSemantic roles with HEX / HSL / CMYK

Color tokens

Ambient Sage
light · HEX · HSL · CMYK

Core

#F3F4EF

background

H 72 · C0, 0, 2, 4

#1A1C17

foreground

H 84 · C7, 0, 18, 89

#E5E6E0

card

H 70 · C0, 0, 3, 10

#ECEEE8

muted

H 80 · C1, 0, 3, 7

#D8D9D2

border

H 68.57 · C0, 0, 3, 15

Brand

#FEE951

primary

H 52.72 · C0, 8, 68, 0

#1A1C17

primary-fg

H 84 · C7, 0, 18, 89

#E5E6E0

secondary

H 70 · C0, 0, 3, 10

#F7E464

accent

H 52.24 · C0, 8, 60, 3

#FEE951

ring

H 52.72 · C0, 8, 68, 0

Semantic

#C0392B

destructive

H 5.64 · C0, 70, 78, 25

#FFFFFF

destructive-fg

H 0 · C0, 0, 0, 0

#2D7238

success

H 129.57 · C61, 0, 51, 55

#C97D12

warning

H 35.08 · C0, 38, 91, 21

#545651

muted-fg

H 84 · C2, 0, 6, 66

Charts

#FEE951

chart-1

H 52.72 · C0, 8, 68, 0

#4A8FD4

chart-2

H 210 · C65, 33, 0, 17

#6BBF8A

chart-3

H 142.14 · C44, 0, 28, 25

#E07498

chart-4

H 340 · C0, 48, 32, 12

#E8A24B

chart-5

H 33.25 · C0, 30, 68, 9

Type scaleHeading, body, and mono in the kit's fonts

Typography

Ambient Sage

Scale: compact-product

Density: balanced

Heading · Plus Jakarta Sans · 1.875rem

Ship beautiful product faster

Subheading · Plus Jakarta Sans · 1.375rem

A warm-sage neutral-surface mobile kit with a single vivid yellow accent, flat tonal cards, and oversized display numerals.

Body · Plus Jakarta Sans · 1rem

Ambient Sage uses a near-white warm-sage canvas (#f3f4ef) with card panels distinguished only by a tonal shift to #e5e6e0, never by shadows or borders. A single vivid yellow (#fee951) is the only saturated color and appears sparingly at component scale as orbs, button fills, and focus rings. Primary data values render as oversized bold hero numerals with a small superscript unit. Typography is a friendly rounded geometric (Plus Jakarta Sans) with no uppercase and no tight tracking, while JetBrains Mono is reserved for hex codes and technical strings. Generous rounding and luminance-only contrast give the whole system a calm, minimal feel.

Mono · JetBrains Mono · 0.8125rem

npx shadcn add ambientsage.json

Aa

Plus Jakarta Sans · Heading

400500600700

Aa

Plus Jakarta Sans · Body

400500600700

ABCDEFGHIJKLM NOPQRSTUVWXYZ

abcdefghijklmnopqrstuvwxyz

0123456789 & @ # % →

Radius & spacingCorner radius, elevation, and spacing steps

Tokens

Ambient Sage primitives
density: balanced

Radius scale

sm · 0.375rem
md · 0.75rem
lg · 1.25rem
xl · 1.75rem

Component radius

button
card
input

Elevation

level 1
level 2
level 3
level 4

Spacing · base 4px

1x
2x
3x
4x
6x
8x
This specimen shows published upstream kit data. It doesn't show that a reader's project mapped the roles, loaded the fonts, or passed runtime or accessibility checks.

For a consuming project, leave these fields unresolved until someone inspects them: the exact artifact identity, Tailwind namespace mappings, font-file source, fallback stack, font-display policy, component assignments, protected surfaces, rendered observations, and accessibility results. Export availability proves that an artifact exists, not that a project consumed it correctly.

Copy the complete source-to-consumer record

Use one record for one decision and one bounded acceptance scope. "Required" means evidence must exist before acceptance. "Conditional" means the field becomes required under a named condition. "Unresolved" means a decision or observation is missing. "Not applicable" requires a reason.

RECORD ID [required]:
SOURCE DECISION [required]:
SOURCE IDENTITY + VERSION [required]:
APPROVAL STATE [required: approved | conditional | unresolved]:
SCOPE [required]:
DECISION OWNER [required]:
IMPLEMENTATION OWNER [required]:
ACCEPTANCE OWNER [required]:
EXCLUSIONS [required; "none recorded" is explicit]:
UNRESOLVED DECISIONS [required; "none" is explicit]:

SEMANTIC ROLE [conditional: required for token mappings]:
MODE VALUES [conditional: required when the role varies by mode]:
STATE VALUES OR BEHAVIOR [conditional: required for stateful consumers]:
EMITTED ARTIFACT IDENTITY [conditional: required when an artifact exists]:
PROJECT MAPPING [required]:
COMPONENT CONTRACT [conditional: required when a component owns behavior]:
NAMED CONSUMERS [required]:
PROTECTED SURFACES [required]:
APPROVED EXCEPTIONS [required; not applicable with reason is allowed]:

EXPECTED RESULT [required]:
OBSERVED RESULT [required for acceptance; unresolved until inspected]:
EVIDENCE STATUS [required: documented | emitted | mapped | observed | missing]:
EVIDENCE REFERENCE [conditional: required for every claimed observation]:
FIRST DIVERGENT LAYER [conditional: required after a mismatch]:
CORRECTION OWNER [conditional: required after a mismatch]:
RETEST TRIGGER [required]:
FINAL DISPOSITION [required: accept | revise | block]:
DISPOSITION SCOPE + REASON [required]:
Copyable classification and acceptance record. Don't replace unresolved or not-applicable labels with empty fields.

Artifact identity and project mapping are separate. An export can contain the correct role while the project points to an older file, renames the role incorrectly, or never imports it. A component can reference the intended utility while a local selector overrides the result. The record keeps those failures distinct.

Run one illustrative controlled change

The following row is illustrative and hasn't been executed. It defines a check without claiming that Ambient Sage or a consuming application was benchmarked. The proposed decision is a semantic page-background role derived from the public kit's warm-sage direction. Project approval, mapping, and observations remain pending.

Illustrative entryEvidence state
Source and authorityAmbient Sage v1 public kit; proposed decision: the page background uses the approved semantic background role. The decision owner must confirm scope before implementation.Documented upstream; project approval unresolved.
Artifact and project mappingExpected emitted role: --background with light and dark values. Proposed Tailwind v4.3 mapping: --color-background: var(--background). Exact export identity, imported file, and built output are pending.Artifact available upstream; project mapping pending.
Component and exceptionPageShell contract consumes bg-background. A marketing-campaign exception may override it only on a named route with an owner, reason, approval, and review trigger. No exception is assumed.Illustrative contract; exception not applicable unless approved.
Consumers and protected surfacesNamed consumers: dashboard shell and settings shell. Modes: light and dark. State: default; interaction states aren't applicable to the shell background. Protected surfaces: dialog and destructive-action colors must remain unchanged.Inspection pending.
Expectation and observationExpected: both shells resolve the approved background in each mode while protected surfaces remain unchanged. Observed: unresolved until the source, built CSS, computed styles, and representative renders are inspected.Expectation recorded; observation missing.
Routing and ownershipSource ambiguity returns to the decision owner. Export divergence goes to the artifact owner. Namespace divergence goes to the Tailwind implementation owner. Component or local-override divergence goes to that code's owner.Routing planned; no failure observed.
Retest and dispositionRetest after source-version, export, theme-mapping, mode-policy, component-contract, or approved-exception changes. Current disposition: block acceptance because project observations are missing.Blocked within this illustrative row's acceptance scope.
Illustrative mapping row. Pending fields aren't presented as results.
  1. 1

    Write the expectation first

    Before changing code, name the approved source version, semantic role, modes, states, named consumers, protected surfaces, test content, and exact expected result.

  2. 2

    Inspect the emitted artifact

    Confirm that the intended role and mode values exist in the exact artifact selected for the project. Record its identity. A public preview or another export isn't equivalent evidence.

  3. 3

    Inspect the project mapping

    Confirm that the project imports that artifact and maps the regular semantic property into the intended Tailwind namespace. Inspect generated output separately from authored CSS.

  4. 4

    Inspect the component contract and exceptions

    Confirm that named components consume the intended utility or property. Classify local overrides as approved, accidental, or unresolved.

  5. 5

    Observe representative consumers

    Check every required mode and state with the content named in the record. Inspect protected surfaces that should remain unchanged. Record specific observations, not a general pass.

  6. 6

    Route the first divergence

    Stop at the earliest layer that differs from the expectation. Assign that layer's correction owner and set the retest trigger without making a broader acceptance claim.

  7. 7

    Choose a bounded disposition

    Accept only when the required evidence exists for the stated scope. Choose revise when a known mapping or implementation must change. Choose block when authority, artifacts, or observations are missing.

Complete one real row before expanding adoption

Start with one approved semantic role used by two named consumers. Record its source version, three owners, destination, Tailwind mapping, modes, states, protected surfaces, test content, and expected result. Inspect the emitted artifact, project mapping, component contract, exceptions, built output, and rendered consumers. If a required field remains unresolved, block that row instead of filling the gap with a plausible default. Move to the next brand rule only after the first row has a defensible accept, revise, or block decision.

Sources