@v4/tokens

The generated Ghost 2.0 default tokens, the per-component contract slices and the generated icon set.

2026-11-07

Overview

@v4/tokens is the Ghost 2.0 default token set — the generated source of truth the theme contract derives from. It sits between the raw Token Studio export and every component theme: tokens.json in, typed TypeScript and icons out.

Nothing here is hand-written. tokens.json is a vendored Token Studio export from stadionHQ/ghost-web-tokens-v2, and everything under src/__generated__/ is produced by the @v4/token-parser CLI. The generated files are never edited by hand — to change a value you re-fetch the export and commit, and the generated diff is the review surface. How the pipeline works is on Token pipeline; the steps to regenerate are on Generating tokens; the generator catalogue is Code generation.

What it contains

packages/tokens/
├── tokens.json                       vendored Token Studio export (input)
└── src/
    ├── __generated__/
    │   ├── tokens.ts                  the typed defaults — the token source of truth
    │   ├── tokens.css                 the emitted --ph__* CSS variable layer
    │   ├── tokens.flat.json           flattened view
    │   └── components/                per-component contract slices
    └── icons/                         129 generated SVG icon components

The Token Studio sets it covers: Primitive · Semantic · Colour-Sets · Component/{Core, Content, Football, Video, Gamification, Hospitality}. Component/Hospitality is an empty set in the export, so it emits no contract module — the five slices below are the whole output.

Entry points

Import Contents
@v4/tokens tokens (the full generated defaults object) and its Tokens type
@v4/tokens/icons The 129 generated icon components (IconArrowRight, …) and the shared IconProps type
@v4/tokens/components/<name> A per-component contract slice — core, content, football, video, gamification

How it is consumed

  • @v4/ghost-core imports the raw tokens object in exactly one file, default.theme.ts, to build the global contract; every component then binds contract paths (g.components.*, colour-set paths) so Euro League's overrides flow through. No component imports @v4/tokens directly for theming.
  • Icons are imported from @v4/tokens/icons by components and stories — never re-drawn as inline SVG. See Icons.
  • Euro League's look comes from its own token layer, @v4/tokens-euro-league, applied over these defaults — not from editing this package, which the template owns. (sync-tokens below refreshes THIS package's Ghost baseline; it is not how Euro League's tokens update — Token Studio pushes those straight into the repo.)

Commands

Command Purpose
pnpm --filter @v4/tokens generate Regenerate src/__generated__/ from tokens.json
pnpm --filter @v4/tokens check Validate the export without writing (CI gate)
pnpm --filter @v4/tokens sync-tokens Re-fetch tokens.json from the upstream repo, then regenerate
pnpm --filter @v4/tokens sync-icons Re-generate the icon set from Ghost – Core 2.0 and the ELB files (below)
pnpm --filter @v4/tokens drift Design-drift report: Ghost – Core 2.0 against ghost-core/figma.json
pnpm --filter @v4/tokens build generate, then compile dist/

sync-icons makes six v4-tokens icons runs into src/icons/, in order:

  1. Ghost – Core 2.0 (67J5FrDZn5HzYzf5hJgoNA) — every icon master on its icons page.
  2. ELB – Web – Core (HIjezWNeRQSBGkxx8VqmjA) — every icon master on its icons page.
  3. ELB – Web – Core, by node — the six plain social-media glyphs (Facebook, YouTube, X, Instagram, TikTok, WhatsApp), which are variants and so invisible to page discovery.
  4. ELB – Web – Content (9iz5GeR9syO68cmPr1ppE1), by node — Feature and Share-Plain.
  5. Ghost – Core 2.0, by node — Chevron-Down and Chevron-Up.
  6. ELB – Web – Content, by node — the three competition marks: EuroLeague, EuroCup and NextGen.

A later run writes over an earlier one's file of the same name.

Icons and component contracts

Beyond the defaults object, @v4/tokens ships two generated surfaces that the component packages consume directly.

Icons — @v4/tokens/icons

The package generates 129 icon components from three Figma files: Ghost – Core 2.0 (67J5FrDZn5HzYzf5hJgoNA), ELB – Web – Core (HIjezWNeRQSBGkxx8VqmjA) and ELB – Web – Content (9iz5GeR9syO68cmPr1ppE1, which supplies Feature, Share-Plain and the EuroLeague, EuroCup and NextGen competition marks). Each is an SVG functional component with fill="currentColor", so it inherits its colour from the text context it sits in. Most are drawn in a 24×24 viewBox; a handful keep their own (12, 16, 20 or 25–26 units wide):

import { IconArrowRight, type IconProps } from "@v4/tokens/icons";

<IconArrowRight />;

Import the real icon — never hand-draw inline SVG demo shapes in stories or slot demo content. How to consume one (colour inheritance, color: inherit on anchor-rooted components) and how directional glyphs mirror under RTL through the opt-in directionalIcon mechanism are on Icons and the icon catalogue.

Regenerate with pnpm --filter @v4/tokens sync-icons. The output is generated — do not hand-edit src/icons/.

Per-component contracts — @v4/tokens/components/*

The parser slices the Token Studio Component/* sets into per-namespace contract modules, exposed at @v4/tokens/components/<name>:

Subpath Namespace
@v4/tokens/components/core Component/Core
@v4/tokens/components/content Component/Content
@v4/tokens/components/football Component/Football
@v4/tokens/components/video Component/Video
@v4/tokens/components/gamification Component/Gamification

These feed the global contract (components.core, components.content, …) that @v4/ghost-core's default.theme.ts assembles. A component theme binds those namespaces through the global-contract path (g.components.core.*), never by importing a @v4/tokens/components/* module and freezing its literals — a raw import puts the value beyond Euro League's overrides. Why is on Binding through the global contract.