Skip to main content

Semantic Layer

The Semantic Layer is also called the Intent Layer in public-facing communication — it is the layer that maps meaning and usage, and it is the canonical exposed boundary of the engine.

Documentation date: 2026-04-10 Focus: The primary purpose-based taxonomy of the Theme Engine for component creators.

1. Overview and Current Definition

The Semantic Layer is the canonical and exported Single Source of Truth of the Aplica Theme Engine. Unlike the Brand Layer (which carries only the hue) and the Mode/Surface Layers (which invert the pigmentation behind the scenes), the Semantic Layer expresses the complete and processed purpose of a token.

This is the layer where "pigments" gain clear functions such as: "Background of a primary button in the pressed state" or "Color of secondary text on top of a success color."

The Golden Rule (Exposure):

Semantic is strictly oriented toward Systems Engineering and Component Creators (Design System Team). Applications must not create invented "semantic exceptions." All styles of a base library component (a Button, Input, Modal, etc.) compulsorily reference the nominal paths from this layer for their internal CSS.

2. The Evolution of Nomenclature

In the earliest token iterations (Alpha / V1), there was significant semantic collision with component names (the "component-token syndrome" like btn-primary-bg). This inflated the code when the same button background needed to be used in a Notification. The taxonomy model adopted by V2 resolves modularity once and for all, following the unified pattern:

semantic.{category}.{subcategory}.{property}

Real examples extracted from the Semantic JSON:

  • semantic.color.interface.function.primary.normal.background
  • semantic.color.interface.feedback.info.default.normal.txtOn
  • semantic.color.brand.branding.first.lowest.border

Any of these prefixes is reserved and rigorously controlled by the central engine — there are no shortcuts or improvised paths, enabling very robust global scans across the generated code.

3. Consolidated Technical Decisions

From the operational standpoint of the Semantic layer's engine, the Theme Engine applies the following structure (based on its central schema):

  1. Brand (Branding & Ambient) Exposes the primitive tones first, second, and third (and Neutral/Gray colors), but already tied to the functional keys required to render any interface:

    • background
    • txtOn (perfectly contrasted text color to apply on top of the same string's background)
    • border
    • txt (since 3.6.0) — readable text in a content flow on the current canvas, referencing this color family (Example: semantic.color.brand.branding.first.default.txtOn)

    Four-part color contract (3.6.0): As of version 3.6.0, every color block exposes a fourth property txt alongside background, txtOn, and border. Unlike txtOn (text on a colored background), txt is text on canvas — a dark tone from the same palette family that is WCAG-accessible over the ambient background. See 07-txt-token.md for the full contract and configuration.

  2. Interface (Function & Feedback) Maps intentional use. The interaction functions (Primary, Secondary, Link, Disabled) now reside here in their complete behavioral variants:

    • normal
    • action (hover)
    • active (pressed — darker than action)
    • focus (keyboard focus indicator — lighter, uses the ring/outline appearance)

    Each of these states exposes the full color quartet: background, txtOn, border, and txt (since 3.6.0). Example: semantic.color.interface.function.primary.action.txt

    Breaking change (2.24.0): Before this version, active carried the keyboard focus appearance. As of 2.24.0, focus is a dedicated state for keyboard focus (uses the palette level that active previously mapped to), and active now maps to a darker palette step representing the pressed/selected state. Migrate: replace active usage in focus rings with focus; retain active for press/select visual feedback.

  3. Typography, Dimension, Opacity Following the same unique-name premises, the parameters for space, typography, and opacity take their final positions without improper ties to dark modes that do not affect these orthogonal fields.

  4. Product — Product Semantics

    The semantic.color.product.* subcategory is the most specific and most customizable area of the entire Semantic layer. It exists to solve a real problem: some products need colors that do not belong to the universal interface vocabulary — food temperature indicators, promotional badges, cashback signaling, subscription tiers, thematic areas of a website, and so on.

    [!IMPORTANT] Product is a completely open area. Unlike the interface.* and brand.* subcategories (which follow rigid schemas generated by the engine), Product items are defined manually by each product and can vary freely between different themes/brands.

    Structure of a Product item

    Each item is a color decomposed in the same pattern as the rest of Semantic — 5 intensity levels × 3 functional properties:

    semantic.color.product.<item>.<variant>.<intensity>.<property>
    SegmentPossible valuesDescription
    <item>promo, cashback, premium, or any free nameThe product concept
    <variant>default, secondaryVisual variant (primary and alternative color)
    <intensity>lowest, low, default, high, highestColor prominence level
    <property>background, txtOn, borderStandard functional trio

    Real example

    An e-commerce platform needing visual signaling for promotions and cashback would define:

    semantic.color.product.promo.default.default.background → background for promotional badges/banners
    semantic.color.product.promo.default.default.txtOn → readable text on that background
    semantic.color.product.promo.secondary.low.background → subtle promo variant for cards
    semantic.color.product.cashback.default.high.background → dense cashback badge background
    semantic.color.product.premium.default.default.background → premium tier indicator

    Product text tokens

    Beyond the background/txtOn/border trio, the system also supports dedicated text tokens for use in pure content contexts (where it is not a surface, but an isolated colored text):

    semantic.color.text.promo → standalone promotional text
    semantic.color.text.promo_secondary → secondary variant
    semantic.color.text.cashback → cashback text
    semantic.color.text.premium → premium tier text

    Why is Product open?

    Unlike Feedback (info, success, warning, danger), which is universal to every UI, product needs are unpredictable and potentially infinite. A delivery app needs temperature indicators. A marketplace needs seller badges. A financial app needs risk indicators. Cementing those categories in the engine schema would be restrictive and inflexible.

    [!CAUTION] Less is more. Always.

    Each new Product item generates at minimum 30 tokens (5 intensities × 3 properties × 2 variants) that propagate across all layers of the system (Brand → Mode → Surface → Semantic). This growth is exponential relative to the number of themes: if the system runs 4 themes, a single new item represents +120 tokens in total.

    More tokens mean:

    • Performance loss — larger files, more CSS/native variables, slower builds
    • Increased complexity — more decisions for designers, more properties for engineers
    • System entropy — underutilized tokens create confusion, inconsistency, and technical debt

    Before adding a new Product item, ask: "Can this need be solved with a Feedback token or an existing Brand variant?" If the answer is yes, do not create a Product item.

    [!TIP] If truly necessary, add with criteria: Define it in your theme's _brand.json with the base colors. The OKLCh pipeline automatically decomposes the palette. Then map it across the mode.*, surface.*, and finally semantic.color.product.* layers following the pattern of existing items. Document the justification.


4. Canonical Rules / Constraints

  • Forbidden to reference internal layers: It is strictly forbidden (Forbidden Pattern) to use theme.color.*, brand.*, or surface.* in Mobile SDKs and on the Web. Production environments only recognize the door that begins with semantic.* and was previously exposed through a build.
  • Avoid invented names: Never create a --semantic-color-invented inside a product's Styled Component. The Theme Engine taxonomy must not be violated, ensuring compatibility with any future global refactoring of generated themes. When there is a need to reduce cognitive load, use the Foundation layer.
  • Product is the controlled exception: Product items (semantic.color.product.*) are the only area where the consumer can freely add keys to the schema. But even here, the internal structure (variantintensityproperty) must be respected to maintain compatibility with the Mode and Surface layers.
  • Product must be minimal: Each item added generates dozens of tokens that propagate across all layers and all themes. Adding product colors without proven need is the fastest way to degrade Design System performance and coherence. The rule is: less is more.