🚀 Introduction
In Part 4, we introduced the DTCG three‑layer architecture for design tokens and the concept of industrial‑grade quality checks. This part will turn those concepts into runnable engineering code, presenting the complete industrial‑grade build script of Moongate v2.2.0.
If you have already completed the basic build script from Part 2 and want to upgrade to an industrial level – supporting color normalization, WCAG contrast checking, circular reference detection, and automatic generation of CSS variables and design system documentation – then this part is for you.
💡 Note: This part involves advanced engineering practices. It is recommended to read the first three parts (Basics, Engineering, Multi‑theme) first.
📁 Directory Structure
your-theme/
├── src/
│ ├── core/
│ │ ├── primitives/
│ │ │ └── colors.yaml # Raw color values
│ │ ├── semantics/
│ │ │ ├── dark.yaml # Dark semantic layer
│ │ │ └── light.yaml # Light semantic layer
│ │ └── layout.yaml # Layout tokens (spacing, typography, breakpoints, etc.)
│ ├── languages/ # Syntax rules per language
│ ├── workbench.yaml # UI colors
│ └── semantic.yaml # Semantic highlighting rules
├── scripts/
│ └── build.js # Industrial‑grade build script
├── themes/
│ ├── moongate-dark.json # Generated theme JSON
│ ├── moongate-light.json
│ ├── moongate-colors.css # Color tokens (auto‑generated)
│ └── moongate-layout.css # Layout tokens (auto‑generated)
├── docs/
│ └── DESIGN_SYSTEM.md # Auto‑generated design system documentation
└── package.json
🎨 Step 1: Primitives File
src/core/primitives/colors.yaml
🌙 Step 2: Semantic Layer Files
Dark Semantic Layer src/core/semantics/dark.yaml
Light Semantic Layer src/core/semantics/light.yaml
📐 Step 3: Layout Tokens File
src/core/layout.yaml
🛠️ Step 4: Industrial‑Grade Build Script
scripts/build.js
⚙️ Step 5: Configure package.json
{"name":"moongate-theme","version":"2.2.0","scripts":{"build":"node scripts/build.js","watch":"nodemon --watch src -e yaml --exec \"pnpm run build\"","prepublishOnly":"pnpm run build"},"devDependencies":{"js-yaml":"^4.1.1","nodemon":"^3.1.14","wcag-contrast":"^3.0.0"}}
⚠️ Note: Make sure to run
pnpm installornpm installto install all dependencies, otherwise the script will fail becausewcag-contrastis missing.
🚀 Step 6: Run the Build
pnpm run build
A successful build will produce output similar to:
🚀 Building theme (DTCG standard + industrial quality checks)...
📦 Loading primitives...
📦 Loading layout tokens...
✅ Layout tokens generated: themes/moongate-layout.css
📦 Loading shared rules...
📚 Loading language rules...
✅ Loaded: base.yaml
...
✨ Loading special rules...
✅ Loaded: better-comments.yaml
🎨 Scanning semantic files...
🔨 Building themes...
✅ Built: themes/moongate-dark.json
✅ dark · text: 14.48:1
✅ dark · textDim: 12.02:1
✅ dark · textMuted: 6.96:1
✅ Built: themes/moongate-light.json
✅ light · text: 17.08:1
✅ light · textDim: 7.25:1
✅ light · textMuted: 7.25:1
✅ Color tokens generated: themes/moongate-colors.css
✅ Design system documentation generated: docs/DESIGN_SYSTEM.md
🎉 All themes built successfully!
Generated files:
-
themes/moongate-dark.json,themes/moongate-light.json– VS Code themes -
themes/moongate-colors.css– Color tokens (light/dark) -
themes/moongate-layout.css– Layout tokens (spacing, typography, breakpoints, etc.) -
docs/DESIGN_SYSTEM.md– Complete design system documentation with variable selection protocol
📊 Step 7: Using the Generated Assets
CSS Variable Naming Rules
Generated CSS variables use the --ui- prefix, converting camelCase semantic variable names to kebab‑case. For example:
| Semantic Variable | Generated CSS Variable | Description |
|---|---|---|
bg |
--ui-bg |
Editor background |
surfaceRaised |
--ui-surface-raised |
Raised surface background |
textMuted |
--ui-text-muted |
Muted text color |
spacing.md |
--ui-spacing-md |
Medium spacing |
Using CSS Variables in a Blog
<link rel="stylesheet" href="/themes/moongate-colors.css">
<link rel="stylesheet" href="/themes/moongate-layout.css">
body {
background: var(--ui-bg);
color: var(--ui-text);
font-family: var(--ui-typography-family-sans);
font-size: var(--ui-typography-size-body);
}
.card {
background: var(--ui-surface-raised);
border: var(--ui-shadow-border) var(--ui-border);
padding: var(--ui-spacing-md);
border-radius: var(--ui-radius-none);
}
.button-primary:hover {
/* State composition: base + overlay */
background-image: linear-gradient(var(--ui-action-hover), var(--ui-action-hover));
background-color: var(--ui-primary);
}
@media (min-width: var(--ui-breakpoint-tablet)) {
.container {
padding: var(--ui-spacing-lg);
}
}
Switching Between Light and Dark Modes
Add or remove the .dark class on the root element:
document.documentElement.classList.toggle('dark');
📝 Summary
With this part, you have fully implemented an industrial‑grade build script:
- ✅ DTCG three‑layer architecture (primitives, semantics, components)
- ✅ Color normalization and circular reference detection
- ✅ WCAG contrast checking
- ✅ Automatic generation of CSS variables for colors
- ✅ Automatic generation of CSS variables for layout (spacing, typography, breakpoints, etc.)
- ✅ Automatic generation of design system documentation (including variable selection protocol)
This script not only serves the Moongate theme but can also be the engineering foundation for all your future design system projects. You now have a complete design system – from design philosophy to engineering code to cross‑platform assets.
Explore endlessly, code without limits.
This article is part of the **VS Code Theme Development Guide* series. The original Chinese version is available on my blog: moongate.top.*
© 2026 yuelinghuashu. This work is licensed under CC BY-NC 4.0.
For further actions, you may consider blocking this person and/or reporting abuse
