@jirawatpyk/aura-tokens 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,34 @@
1
+ // eslint-plugin-aura.js — AURA 4.1
2
+ // Flags hard-coded colours in JS/TS: hex (#rgb, #rgba, #rrggbb, #rrggbbaa), rgb()/hsl() literals,
3
+ // and Tailwind arbitrary colour classes like bg-[#18181b]. Use semantic tokens instead.
4
+ const HEX = /#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})\b/i;
5
+ const FN = /\b(?:rgba?|hsla?)\(\s*\d/i;
6
+ const TW = /\b(?:bg|text|border|ring|fill|stroke|from|to|via|shadow)-\[(?:#|rgb|hsl)/i;
7
+
8
+ function check(context, node, value) {
9
+ if (typeof value !== 'string') return;
10
+ const hit = (TW.exec(value) || HEX.exec(value) || FN.exec(value) || [])[0];
11
+ if (hit) {
12
+ context.report({
13
+ node,
14
+ message: `Hard-coded colour "${hit}". Use a semantic token (bg-bg-surface, text-fg-primary, var(--aura-…)) instead.`,
15
+ });
16
+ }
17
+ }
18
+
19
+ module.exports = {
20
+ rules: {
21
+ 'no-hardcoded-color': {
22
+ meta: { type: 'problem', docs: { description: 'ห้ามใช้สี hardcode ให้ใช้ token — use AURA semantic tokens, never raw colours' } },
23
+ create(context) {
24
+ return {
25
+ Literal(node) { check(context, node, node.value); },
26
+ TemplateElement(node) { check(context, node, node.value && node.value.raw); },
27
+ };
28
+ },
29
+ },
30
+ },
31
+ configs: {
32
+ recommended: { plugins: ['aura'], rules: { 'aura/no-hardcoded-color': 'error' } },
33
+ },
34
+ };
@@ -0,0 +1,205 @@
1
+ name,type,mode,value,description,scope
2
+ primitive/violet/50,color,light,#f5f3ff,Primitive violet 50. Reference only — code uses semantic tokens (token-lint forbids raw hex).,
3
+ primitive/violet/100,color,light,#ede9fe,Primitive violet 100. Reference only — code uses semantic tokens (token-lint forbids raw hex).,
4
+ primitive/violet/200,color,light,#ddd6fe,Primitive violet 200. Reference only — code uses semantic tokens (token-lint forbids raw hex).,
5
+ primitive/violet/300,color,light,#c4b5fd,Primitive. Dark-theme aura-fg-accent (9.6:1 on dark aura-bg-surface).,
6
+ primitive/violet/400,color,light,#a78bfa,Primitive. Dark-theme aura-accent-violet (6.5:1 on dark aura-bg-surface).,
7
+ primitive/violet/500,color,light,#8b5cf6,Primitive violet 500. Reference only — code uses semantic tokens (token-lint forbids raw hex).,
8
+ primitive/violet/600,color,light,#7c3aed,Primitive. Primary brand violet (Figma: 'Primary brand'). Never in product code directly — reach it through a semantic token.,
9
+ primitive/violet/700,color,light,#6d28d9,Primitive. Light-theme accent: resolves aura-fg-accent and aura-accent-violet. 7.1:1 on aura-bg-surface.,
10
+ primitive/violet/800,color,light,#5b21b6,Primitive violet 800. Reference only — code uses semantic tokens (token-lint forbids raw hex).,
11
+ primitive/violet/900,color,light,#4c1d95,Primitive violet 900. Reference only — code uses semantic tokens (token-lint forbids raw hex).,
12
+ primitive/zinc/0,color,light,#ffffff,"Primitive white. Light aura-bg-surface, aura-fg-inverted; dark aura-fg-primary, aura-border-strong.",
13
+ primitive/zinc/50,color,light,#fafafa,Primitive. Light aura-bg-canvas and aura-bg-surface-hover.,
14
+ primitive/zinc/100,color,light,#f4f4f5,Primitive. Light aura-border-subtle.,
15
+ primitive/zinc/200,color,light,#e4e4e7,"Primitive. Light aura-border-default, card border.",
16
+ primitive/zinc/300,color,light,#d4d4d8,Primitive zinc 300. Reference only — code uses semantic tokens.,
17
+ primitive/zinc/400,color,light,#a1a1aa,Primitive. Light aura-fg-tertiary; dark aura-fg-secondary.,
18
+ primitive/zinc/450,color,light,#8e8e97,Primitive between zinc-400 and -500. Dark-theme aura-fg-tertiary (5.5:1 on dark surface). ADDED so tertiary text passes AA.,
19
+ primitive/zinc/500,color,light,#71717a,Primitive zinc 500. Reference only — code uses semantic tokens.,
20
+ primitive/zinc/600,color,light,#52525b,Primitive. Light aura-fg-secondary; dark aura-fg-tertiary.,
21
+ primitive/zinc/700,color,light,#3f3f46,Primitive zinc 700. Reference only — code uses semantic tokens.,
22
+ primitive/zinc/800,color,light,#27272a,Primitive. Dark aura-bg-surface-hover; primary button hover fill.,
23
+ primitive/zinc/900,color,light,#18181b,"Primitive 'Ink'. Light aura-fg-primary, aura-bg-surface-strong, aura-border-strong; dark aura-bg-surface; the brutal Creative shadow colour.",
24
+ primitive/zinc/950,color,light,#08080a,Primitive. Dark aura-bg-canvas.,
25
+ primitive/lime/50,color,light,#f7fee7,Primitive lime 50. Reference only.,
26
+ primitive/lime/100,color,light,#ecfccb,Primitive lime 100. Reference only.,
27
+ primitive/lime/200,color,light,#d9f99d,"Primitive 'Accent dot'. aura-accent-dot / aura-accent-lime and the Ready status fill. A fill only — 1.17:1 against white, so never text and never a mark that must be seen on a light surface.",
28
+ primitive/lime/300,color,light,#bef264,Primitive lime 300 (also exported in the Tailwind config).,
29
+ primitive/lime/400,color,light,#a3e635,Primitive lime 400. Reference only.,
30
+ primitive/lime/500,color,light,#84cc16,Primitive lime 500. Reference only.,
31
+ primitive/lime/600,color,light,#65a30d,Primitive lime 600. Reference only.,
32
+ primitive/lime/800,color,light,#3f6212,Primitive. Success alert text on aura-lime-50 (6.8:1). ADDED.,
33
+ primitive/red/50,color,light,#fef2f2,Primitive. Danger alert fill (light). ADDED.,
34
+ primitive/red/200,color,light,#fecaca,Primitive. Danger alert edge (light). ADDED.,
35
+ primitive/red/300,color,light,#fca5a5,"Primitive. Danger alert text (dark), 8.1:1. ADDED.",
36
+ primitive/red/400,color,light,#f87171,Primitive. Dark-theme aura-fg-danger: 6.4:1 on dark surface. ADDED.,
37
+ primitive/red/700,color,light,#b91c1c,"Primitive red 700 (Tailwind red, like the other scales). The Blocked status fill; white on it 6.5:1. ADDED — the source palette has no warm hue.",
38
+ primitive/amber/50,color,light,#fffbeb,Primitive. Warning alert fill (light). ADDED.,
39
+ primitive/amber/200,color,light,#fde68a,Primitive. Warning alert edge (light). ADDED.,
40
+ primitive/amber/300,color,light,#fcd34d,"Primitive. Warning alert text (dark), 9.6:1. ADDED.",
41
+ primitive/amber/800,color,light,#92400e,"Primitive. Warning alert text (light), 6.8:1 on amber-50. ADDED.",
42
+ primitive/ink,color,light,#08080a,Primitive ink (= zinc-950). Text on lime fills: the Ready status label (15:1 on aura-lime-200).,
43
+ primitive/white,color,light,#ffffff,Primitive white. The Creative button fill in every theme.,
44
+ semantic/bg-surface,color,light,{primitive/zinc/0},"Default surface: cards, tables, panels, page body. Grounds aura-fg-primary, -secondary and -accent.",FRAME_FILL
45
+ semantic/bg-surface-hover,color,light,{primitive/zinc/50},"Hover fill for rows, secondary buttons and list items. aura-fg-primary and -secondary still pass on it (≥5.8:1).",FRAME_FILL
46
+ semantic/bg-surface-strong,color,light,{primitive/zinc/900},"High-emphasis block (the wordmark tile, inverted callouts). Text on it: aura-fg-inverted.",FRAME_FILL
47
+ semantic/bg-canvas,color,light,{primitive/zinc/50},App background behind surfaces; the data-table header band.,FRAME_FILL
48
+ semantic/bg-inverted,color,light,{primitive/zinc/900},Inverted ground: tooltips. Text on it: aura-fg-inverted (17.7:1).,FRAME_FILL
49
+ semantic/fg-primary,color,light,{primitive/zinc/900},Body and heading text on aura-bg-surface and aura-bg-canvas (≥16.9:1 both themes).,TEXT_FILL
50
+ semantic/fg-secondary,color,light,{primitive/zinc/600},"Supporting text, labels, captions on aura-bg-surface / -canvas / -surface-hover (≥5.8:1 both themes).",TEXT_FILL
51
+ semantic/fg-tertiary,color,light,{primitive/zinc/500},"Placeholders, hints, timestamps, breadcrumb separators. Fixed in 4.1 to pass AA: 4.8:1 light / 5.5:1 dark on aura-bg-surface, ≥4.6:1 on -canvas and -surface-hover. Not for text on aura-bg-selected (4.4:1).",TEXT_FILL
52
+ semantic/fg-inverted,color,light,{primitive/zinc/0},Text on aura-bg-surface-strong and aura-bg-inverted (17.7:1).,TEXT_FILL
53
+ semantic/fg-accent,color,light,{primitive/violet/700},"Links and accent text on aura-bg-surface / -canvas (≥6.8:1 light, ≥9.6:1 dark).",TEXT_FILL
54
+ semantic/border-default,color,light,{primitive/zinc/200},"Hairline dividers and card/table outlines. Decorative only: ~1.3:1, below the 3:1 a control boundary needs.",STROKE_COLOR
55
+ semantic/border-strong,color,light,{primitive/zinc/900},Creative 2px borders and any boundary that must be seen (17.7:1).,STROKE_COLOR
56
+ semantic/border-subtle,color,light,{primitive/zinc/100},Faintest separators inside a surface (e.g. between grouped list items).,STROKE_COLOR
57
+ semantic/accent-dot,color,light,{primitive/lime/200},The lime signal dot beside the AURA wordmark and live/status dots. Visible on dark and strong grounds; invisible on white (1.17:1).,ALL_FILLS
58
+ semantic/accent-violet,color,light,{primitive/violet/700},"Violet accent fills and marks (selection, focus-adjacent emphasis, charts' first series).",ALL_FILLS
59
+ semantic/accent-lime,color,light,{primitive/lime/200},"Lime accent fill (highlights, the Ready status). Label on it in aura-ink.",ALL_FILLS
60
+ semantic/focus-ring,color,light,{primitive/violet/700},"Keyboard focus ring on every interactive element: 2px solid, 2px offset. Lands on aura-bg-surface / -canvas / -surface-hover at ≥6.8:1 light and ≥5.4:1 dark. On mesh and grain surfaces the ring switches to aura-on-texture (violet-700 on the violet-400 pool is only 2.6:1). ADDED — the source defines no focus style.",ALL_FILLS
61
+ semantic/mesh-from,color,light,{primitive/violet/400},Creative mesh: the violet pool (top-left). Same in both themes — mesh is a light-surface treatment. ADDED from the source's 'violet → lime gradient'.,ALL_FILLS
62
+ semantic/mesh-to,color,light,{primitive/lime/200},Creative mesh: the lime pool (bottom-right).,ALL_FILLS
63
+ semantic/mesh-ground,color,light,{primitive/white},Creative mesh: the ground between the pools.,ALL_FILLS
64
+ semantic/on-texture,color,light,{primitive/ink},"Text and icons on a mesh or grain surface in every theme: ≥7.3:1 on the darkest mesh point (violet-400), 15:1 on lime, 20:1 on white.",ALL_FILLS
65
+ semantic/grain,color,light,{primitive/ink},"Grain speckle colour, drawn at aura-grain-opacity. Visible only on light grounds.",ALL_FILLS
66
+ semantic/status-neutral-bg,color,light,{primitive/zinc/100},"Status pill fill for not-started / unknown states (To Do, Draft). Same in both themes. ADDED.",ALL_FILLS
67
+ semantic/status-neutral-fg,color,light,{primitive/zinc/700},Label and icon on aura-status-neutral-bg (9.5:1).,ALL_FILLS
68
+ semantic/status-progress-bg,color,light,{primitive/violet/100},"Status pill fill for work under way (In Progress, In Review). ADDED.",ALL_FILLS
69
+ semantic/status-progress-fg,color,light,{primitive/violet/800},Label and icon on aura-status-progress-bg (7.6:1).,ALL_FILLS
70
+ semantic/status-ready-bg,color,light,{primitive/lime/200},"Status pill fill for finished / good states (Ready, Done). The source's lime pill. ADDED as a named token.",ALL_FILLS
71
+ semantic/status-ready-fg,color,light,{primitive/ink},Label and icon on aura-status-ready-bg (15.2:1).,ALL_FILLS
72
+ semantic/status-blocked-bg,color,light,{primitive/red/700},"Status pill fill for stopped / failed states (Blocked, Failed). Dark on purpose: 5.5:1 lighter-to-darker against the lime Ready fill, so Ready and Blocked differ by lightness, not only red vs green. ADDED.",ALL_FILLS
73
+ semantic/status-blocked-fg,color,light,{primitive/white},Label and icon on aura-status-blocked-bg (6.5:1).,ALL_FILLS
74
+ semantic/bg-selected,color,light,{primitive/violet/50},"Selected table rows and list items. Opaque so pinned columns can sit on it (dark = a 14% violet-400 wash over zinc-900, flattened). aura-fg-primary on it ≥14.2:1, aura-fg-secondary ≥5.5:1, focus ring ≥5.2:1 in both themes. ADDED.",FRAME_FILL
75
+ semantic/border-control,color,light,{primitive/zinc/500},"Outline of unchecked checkboxes and other small controls that must be seen: ≥4.4:1 on aura-bg-surface, -canvas and aura-bg-selected (the 3:1 a control boundary needs). ADDED.",STROKE_COLOR
76
+ semantic/bg-skeleton,color,light,{primitive/zinc/100},Skeleton placeholder bars while a table or list loads. Decorative; the table carries aria-busy and a 'Loading rows' status for screen readers. ADDED.,FRAME_FILL
77
+ semantic/fg-danger,color,light,{primitive/red/700},"Error messages, destructive labels and invalid-field text on aura-bg-surface / -canvas: ≥6.2:1 light, ≥5.4:1 dark. ADDED.",TEXT_FILL
78
+ semantic/border-danger,color,light,{primitive/red/700},Outline of an invalid input (≥5.4:1 on its ground). ADDED.,STROKE_COLOR
79
+ semantic/bg-input,color,light,{primitive/zinc/0},"Text fields, selects, textareas. Always paired with a 1px aura-border-control outline. ADDED.",FRAME_FILL
80
+ semantic/bg-input-disabled,color,light,{primitive/zinc/50},Disabled and read-only inputs; text on it stays aura-fg-secondary. ADDED.,FRAME_FILL
81
+ semantic/bg-scrim,color,light,"rgba(8,8,10,0.48)",The dimmed layer behind a Dialog. ADDED.,FRAME_FILL
82
+ semantic/alert-info-bg,color,light,{primitive/violet/50},Info alert fill. ADDED.,ALL_FILLS
83
+ semantic/alert-info-fg,color,light,{primitive/violet/800},"Info alert title and icon: 8.2:1 light, 7.7:1 dark. Body text on the fill stays aura-fg-primary.",ALL_FILLS
84
+ semantic/alert-info-border,color,light,{primitive/violet/200},Info alert 1px edge (decorative).,ALL_FILLS
85
+ semantic/alert-success-bg,color,light,{primitive/lime/50},Success alert fill. ADDED.,ALL_FILLS
86
+ semantic/alert-success-fg,color,light,{primitive/lime/800},"Success alert title and icon: 6.8:1 light, 10.4:1 dark.",ALL_FILLS
87
+ semantic/alert-success-border,color,light,{primitive/lime/200},Success alert 1px edge (decorative).,ALL_FILLS
88
+ semantic/alert-warning-bg,color,light,{primitive/amber/50},Warning alert fill. ADDED.,ALL_FILLS
89
+ semantic/alert-warning-fg,color,light,{primitive/amber/800},"Warning alert title and icon: 6.8:1 light, 9.6:1 dark.",ALL_FILLS
90
+ semantic/alert-warning-border,color,light,{primitive/amber/200},Warning alert 1px edge (decorative).,ALL_FILLS
91
+ semantic/alert-danger-bg,color,light,{primitive/red/50},Danger alert fill. ADDED.,ALL_FILLS
92
+ semantic/alert-danger-fg,color,light,{primitive/red/700},"Danger alert title and icon: 5.9:1 light, 8.1:1 dark.",ALL_FILLS
93
+ semantic/alert-danger-border,color,light,{primitive/red/200},Danger alert 1px edge (decorative).,ALL_FILLS
94
+ semantic/fg-positive,color,light,{primitive/lime/800},"Rising-and-good numbers (Stat change, positive deltas) on aura-bg-surface / -canvas. Never on lime fills. ADDED 4.3.",TEXT_FILL
95
+ semantic/bg-surface,color,dark,{primitive/zinc/900},"Default surface: cards, tables, panels, page body. Grounds aura-fg-primary, -secondary and -accent.",FRAME_FILL
96
+ semantic/bg-surface-hover,color,dark,{primitive/zinc/800},"Hover fill for rows, secondary buttons and list items. aura-fg-primary and -secondary still pass on it (≥5.8:1).",FRAME_FILL
97
+ semantic/bg-surface-strong,color,dark,{primitive/zinc/0},"High-emphasis block (the wordmark tile, inverted callouts). Text on it: aura-fg-inverted.",FRAME_FILL
98
+ semantic/bg-canvas,color,dark,{primitive/zinc/950},App background behind surfaces; the data-table header band.,FRAME_FILL
99
+ semantic/bg-inverted,color,dark,{primitive/zinc/0},Inverted ground: tooltips. Text on it: aura-fg-inverted (17.7:1).,FRAME_FILL
100
+ semantic/fg-primary,color,dark,{primitive/zinc/0},Body and heading text on aura-bg-surface and aura-bg-canvas (≥16.9:1 both themes).,TEXT_FILL
101
+ semantic/fg-secondary,color,dark,{primitive/zinc/400},"Supporting text, labels, captions on aura-bg-surface / -canvas / -surface-hover (≥5.8:1 both themes).",TEXT_FILL
102
+ semantic/fg-tertiary,color,dark,{primitive/zinc/450},"Placeholders, hints, timestamps, breadcrumb separators. Fixed in 4.1 to pass AA: 4.8:1 light / 5.5:1 dark on aura-bg-surface, ≥4.6:1 on -canvas and -surface-hover. Not for text on aura-bg-selected (4.4:1).",TEXT_FILL
103
+ semantic/fg-inverted,color,dark,{primitive/zinc/900},Text on aura-bg-surface-strong and aura-bg-inverted (17.7:1).,TEXT_FILL
104
+ semantic/fg-accent,color,dark,{primitive/violet/300},"Links and accent text on aura-bg-surface / -canvas (≥6.8:1 light, ≥9.6:1 dark).",TEXT_FILL
105
+ semantic/border-default,color,dark,"rgba(255,255,255,0.1)","Hairline dividers and card/table outlines. Decorative only: ~1.3:1, below the 3:1 a control boundary needs.",STROKE_COLOR
106
+ semantic/border-strong,color,dark,{primitive/zinc/0},Creative 2px borders and any boundary that must be seen (17.7:1).,STROKE_COLOR
107
+ semantic/border-subtle,color,dark,"rgba(255,255,255,0.06)",Faintest separators inside a surface (e.g. between grouped list items).,STROKE_COLOR
108
+ semantic/accent-dot,color,dark,{primitive/lime/200},The lime signal dot beside the AURA wordmark and live/status dots. Visible on dark and strong grounds; invisible on white (1.17:1).,ALL_FILLS
109
+ semantic/accent-violet,color,dark,{primitive/violet/400},"Violet accent fills and marks (selection, focus-adjacent emphasis, charts' first series).",ALL_FILLS
110
+ semantic/accent-lime,color,dark,{primitive/lime/200},"Lime accent fill (highlights, the Ready status). Label on it in aura-ink.",ALL_FILLS
111
+ semantic/focus-ring,color,dark,{primitive/violet/400},"Keyboard focus ring on every interactive element: 2px solid, 2px offset. Lands on aura-bg-surface / -canvas / -surface-hover at ≥6.8:1 light and ≥5.4:1 dark. On mesh and grain surfaces the ring switches to aura-on-texture (violet-700 on the violet-400 pool is only 2.6:1). ADDED — the source defines no focus style.",ALL_FILLS
112
+ semantic/mesh-from,color,dark,{primitive/violet/400},Creative mesh: the violet pool (top-left). Same in both themes — mesh is a light-surface treatment. ADDED from the source's 'violet → lime gradient'.,ALL_FILLS
113
+ semantic/mesh-to,color,dark,{primitive/lime/200},Creative mesh: the lime pool (bottom-right).,ALL_FILLS
114
+ semantic/mesh-ground,color,dark,{primitive/white},Creative mesh: the ground between the pools.,ALL_FILLS
115
+ semantic/on-texture,color,dark,{primitive/ink},"Text and icons on a mesh or grain surface in every theme: ≥7.3:1 on the darkest mesh point (violet-400), 15:1 on lime, 20:1 on white.",ALL_FILLS
116
+ semantic/grain,color,dark,{primitive/ink},"Grain speckle colour, drawn at aura-grain-opacity. Visible only on light grounds.",ALL_FILLS
117
+ semantic/status-neutral-bg,color,dark,{primitive/zinc/100},"Status pill fill for not-started / unknown states (To Do, Draft). Same in both themes. ADDED.",ALL_FILLS
118
+ semantic/status-neutral-fg,color,dark,{primitive/zinc/700},Label and icon on aura-status-neutral-bg (9.5:1).,ALL_FILLS
119
+ semantic/status-progress-bg,color,dark,{primitive/violet/100},"Status pill fill for work under way (In Progress, In Review). ADDED.",ALL_FILLS
120
+ semantic/status-progress-fg,color,dark,{primitive/violet/800},Label and icon on aura-status-progress-bg (7.6:1).,ALL_FILLS
121
+ semantic/status-ready-bg,color,dark,{primitive/lime/200},"Status pill fill for finished / good states (Ready, Done). The source's lime pill. ADDED as a named token.",ALL_FILLS
122
+ semantic/status-ready-fg,color,dark,{primitive/ink},Label and icon on aura-status-ready-bg (15.2:1).,ALL_FILLS
123
+ semantic/status-blocked-bg,color,dark,{primitive/red/700},"Status pill fill for stopped / failed states (Blocked, Failed). Dark on purpose: 5.5:1 lighter-to-darker against the lime Ready fill, so Ready and Blocked differ by lightness, not only red vs green. ADDED.",ALL_FILLS
124
+ semantic/status-blocked-fg,color,dark,{primitive/white},Label and icon on aura-status-blocked-bg (6.5:1).,ALL_FILLS
125
+ semantic/bg-selected,color,dark,#2c283a,"Selected table rows and list items. Opaque so pinned columns can sit on it (dark = a 14% violet-400 wash over zinc-900, flattened). aura-fg-primary on it ≥14.2:1, aura-fg-secondary ≥5.5:1, focus ring ≥5.2:1 in both themes. ADDED.",FRAME_FILL
126
+ semantic/border-control,color,dark,{primitive/zinc/400},"Outline of unchecked checkboxes and other small controls that must be seen: ≥4.4:1 on aura-bg-surface, -canvas and aura-bg-selected (the 3:1 a control boundary needs). ADDED.",STROKE_COLOR
127
+ semantic/bg-skeleton,color,dark,{primitive/zinc/800},Skeleton placeholder bars while a table or list loads. Decorative; the table carries aria-busy and a 'Loading rows' status for screen readers. ADDED.,FRAME_FILL
128
+ semantic/fg-danger,color,dark,{primitive/red/400},"Error messages, destructive labels and invalid-field text on aura-bg-surface / -canvas: ≥6.2:1 light, ≥5.4:1 dark. ADDED.",TEXT_FILL
129
+ semantic/border-danger,color,dark,{primitive/red/400},Outline of an invalid input (≥5.4:1 on its ground). ADDED.,STROKE_COLOR
130
+ semantic/bg-input,color,dark,{primitive/zinc/900},"Text fields, selects, textareas. Always paired with a 1px aura-border-control outline. ADDED.",FRAME_FILL
131
+ semantic/bg-input-disabled,color,dark,{primitive/zinc/950},Disabled and read-only inputs; text on it stays aura-fg-secondary. ADDED.,FRAME_FILL
132
+ semantic/bg-scrim,color,dark,"rgba(0,0,0,0.64)",The dimmed layer behind a Dialog. ADDED.,FRAME_FILL
133
+ semantic/alert-info-bg,color,dark,#2c283a,Info alert fill. ADDED.,ALL_FILLS
134
+ semantic/alert-info-fg,color,dark,{primitive/violet/300},"Info alert title and icon: 8.2:1 light, 7.7:1 dark. Body text on the fill stays aura-fg-primary.",ALL_FILLS
135
+ semantic/alert-info-border,color,dark,#514674,Info alert 1px edge (decorative).,ALL_FILLS
136
+ semantic/alert-success-bg,color,dark,#27311a,Success alert fill. ADDED.,ALL_FILLS
137
+ semantic/alert-success-fg,color,dark,{primitive/lime/300},"Success alert title and icon: 6.8:1 light, 10.4:1 dark.",ALL_FILLS
138
+ semantic/alert-success-border,color,dark,#436019,Success alert 1px edge (decorative).,ALL_FILLS
139
+ semantic/alert-warning-bg,color,dark,#372b19,Warning alert fill. ADDED.,ALL_FILLS
140
+ semantic/alert-warning-fg,color,dark,{primitive/amber/300},"Warning alert title and icon: 6.8:1 light, 9.6:1 dark.",ALL_FILLS
141
+ semantic/alert-warning-border,color,dark,#704e15,Warning alert 1px edge (decorative).,ALL_FILLS
142
+ semantic/alert-danger-bg,color,dark,#361e21,Danger alert fill. ADDED.,ALL_FILLS
143
+ semantic/alert-danger-fg,color,dark,{primitive/red/300},"Danger alert title and icon: 5.9:1 light, 8.1:1 dark.",ALL_FILLS
144
+ semantic/alert-danger-border,color,dark,#6e2a2b,Danger alert 1px edge (decorative).,ALL_FILLS
145
+ semantic/fg-positive,color,dark,{primitive/lime/300},"Rising-and-good numbers (Stat change, positive deltas) on aura-bg-surface / -canvas. Never on lime fills. ADDED 4.3.",TEXT_FILL
146
+ component/button-primary-bg,color,light,{primitive/zinc/900},"Component: Enterprise (primary) button fill — ink in light, white in dark, as the Storybook story renders it (tokens.json pins it to the light value, which disappears on the dark surface).",ALL_FILLS
147
+ component/button-primary-fg,color,light,{primitive/zinc/0},Component: primary button label on aura-button-primary-bg (17.7:1 both themes).,ALL_FILLS
148
+ component/button-primary-bg-hover,color,light,{primitive/zinc/800},"Component: primary button hover. Light zinc-800 is the source value; dark zinc-200 is an ADDED value (the source has none — its zinc-800 hover hides the dark label at 1.19:1). Label 14.9:1 light, 14.0:1 dark.",ALL_FILLS
149
+ component/button-creative-bg,color,light,{primitive/white},Component: Creative button fill (white in every theme). Label in aura-ink.,ALL_FILLS
150
+ component/button-creative-border,color,light,{primitive/zinc/900},Component: Creative button 2px border.,ALL_FILLS
151
+ component/card-border,color,light,{primitive/zinc/200},Component: card outline (light value; use aura-border-default where the card must follow theme).,ALL_FILLS
152
+ component/button-primary-bg,color,dark,{primitive/zinc/0},"Component: Enterprise (primary) button fill — ink in light, white in dark, as the Storybook story renders it (tokens.json pins it to the light value, which disappears on the dark surface).",ALL_FILLS
153
+ component/button-primary-fg,color,dark,{primitive/zinc/900},Component: primary button label on aura-button-primary-bg (17.7:1 both themes).,ALL_FILLS
154
+ component/button-primary-bg-hover,color,dark,{primitive/zinc/200},"Component: primary button hover. Light zinc-800 is the source value; dark zinc-200 is an ADDED value (the source has none — its zinc-800 hover hides the dark label at 1.19:1). Label 14.9:1 light, 14.0:1 dark.",ALL_FILLS
155
+ component/button-creative-bg,color,dark,{primitive/white},Component: Creative button fill (white in every theme). Label in aura-ink.,ALL_FILLS
156
+ component/button-creative-border,color,dark,{primitive/zinc/900},Component: Creative button 2px border.,ALL_FILLS
157
+ component/card-border,color,dark,{primitive/zinc/200},Component: card outline (light value; use aura-border-default where the card must follow theme).,ALL_FILLS
158
+ spacing/space-0,number,light,0,,GAP
159
+ spacing/space-1,number,light,4,,GAP
160
+ spacing/space-2,number,light,8,,GAP
161
+ spacing/space-3,number,light,12,,GAP
162
+ spacing/space-4,number,light,16,,GAP
163
+ spacing/space-5,number,light,20,,GAP
164
+ spacing/space-6,number,light,24,,GAP
165
+ spacing/space-8,number,light,32,,GAP
166
+ spacing/space-10,number,light,40,,GAP
167
+ spacing/space-12,number,light,48,,GAP
168
+ spacing/space-16,number,light,64,,GAP
169
+ spacing/card-padding,number,light,24,,GAP
170
+ radius/radius-xs,number,light,4,,CORNER_RADIUS
171
+ radius/radius-sm,number,light,8,,CORNER_RADIUS
172
+ radius/radius-md,number,light,12,,CORNER_RADIUS
173
+ radius/radius-lg,number,light,16,,CORNER_RADIUS
174
+ radius/radius-xl,number,light,20,,CORNER_RADIUS
175
+ radius/radius-2xl,number,light,24,,CORNER_RADIUS
176
+ radius/radius-full,number,light,9999,,CORNER_RADIUS
177
+ radius/radius-squircle,number,light,20,,CORNER_RADIUS
178
+ radius/card-radius,number,light,20,,CORNER_RADIUS
179
+ radius/button-radius,number,light,9999,,CORNER_RADIUS
180
+ size/button-height,number,light,44,,GAP
181
+ size/icon-sm,number,light,16,,GAP
182
+ size/icon-md,number,light,20,,GAP
183
+ size/icon-lg,number,light,24,,GAP
184
+ size/focus-ring-width,number,light,2,,GAP
185
+ size/focus-ring-offset,number,light,2,,GAP
186
+ size/table-select-width,number,light,40,,GAP
187
+ size/control-sm,number,light,32,,GAP
188
+ size/input-height,number,light,44,,GAP
189
+ size/switch-width,number,light,36,,GAP
190
+ size/switch-height,number,light,20,,GAP
191
+ size/avatar-sm,number,light,24,,GAP
192
+ size/avatar-md,number,light,32,,GAP
193
+ size/avatar-lg,number,light,40,,GAP
194
+ size/dialog-sm,number,light,400,,GAP
195
+ size/dialog-md,number,light,560,,GAP
196
+ size/dialog-lg,number,light,720,,GAP
197
+ size/sidenav-width,number,light,240,,GAP
198
+ size/tooltip-max,number,light,240,,GAP
199
+ size/drawer-sm,number,light,360,"Drawer width, small (filters, quick detail). ADDED 4.2.",GAP
200
+ size/drawer-md,number,light,480,"Drawer width, default (record detail). ADDED 4.2.",GAP
201
+ size/drawer-lg,number,light,640,"Drawer width, large (edit forms). ADDED 4.2.",GAP
202
+ size/container-max,number,light,1280,Container max width — matches aura-bp-xl. ADDED 4.2.,GAP
203
+ size/container-narrow,number,light,720,Narrow container for forms and reading. ADDED 4.2.,GAP
204
+ size/cal-cell,number,light,36,Calendar day cell (DatePicker). 40px on touch screens via media query. ADDED 4.2.,GAP
205
+ size/popover-max-height,number,light,320,Max height of Combobox listbox and DatePicker popover lists. ADDED 4.2.,GAP
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@jirawatpyk/aura-tokens",
3
+ "version": "4.4.1",
4
+ "description": "AURA Design System — tokens (CSS variables, Tailwind preset, Figma variables), theme contrast checks and token lint.",
5
+ "main": "tailwind.tokens.cjs",
6
+ "types": "components/index.d.ts",
7
+ "files": [
8
+ "tokens.json",
9
+ "aura.css",
10
+ "aura-fonts.css",
11
+ "tailwind.config.ts",
12
+ "tailwind.tokens.cjs",
13
+ "figma-variables.csv",
14
+ "eslint-plugin-aura.js",
15
+ "components/aura.bundle.js",
16
+ "components/aura.components.css",
17
+ "components/index.d.ts",
18
+ "scripts/a11y-check.js",
19
+ "scripts/lint-tokens.js",
20
+ "GOVERNANCE.md",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "exports": {
25
+ "./aura.css": "./aura.css",
26
+ "./aura-fonts.css": "./aura-fonts.css",
27
+ "./tokens.json": "./tokens.json",
28
+ "./tailwind": "./tailwind.tokens.cjs",
29
+ "./components.js": "./components/aura.bundle.js",
30
+ "./components.css": "./components/aura.components.css",
31
+ "./eslint-plugin": "./eslint-plugin-aura.js"
32
+ },
33
+ "scripts": {
34
+ "build": "node scripts/build-tokens.js",
35
+ "a11y": "node scripts/a11y-check.js",
36
+ "lint:tokens": "node scripts/lint-tokens.js ../react/src && node scripts/lint-tokens.js ../react/styles",
37
+ "check:generated": "node scripts/build-tokens.js && git diff --exit-code -- aura.css aura-fonts.css tailwind.tokens.cjs figma-variables.csv",
38
+ "prepack": "npm run build"
39
+ },
40
+ "keywords": [
41
+ "design-system",
42
+ "tokens",
43
+ "enterprise",
44
+ "tailwind",
45
+ "figma",
46
+ "react"
47
+ ],
48
+ "license": "MIT",
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/Jirawatpyk/Aura-design.git",
52
+ "directory": "packages/tokens"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "homepage": "https://github.com/Jirawatpyk/Aura-design#readme",
58
+ "bugs": {
59
+ "url": "https://github.com/Jirawatpyk/Aura-design/issues"
60
+ }
61
+ }
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ /* AURA contrast check — resolves tokens.json and tests every documented text/ground pair in BOTH themes.
3
+ * Text needs 4.5:1, control edges and focus rings 3:1 (WCAG 2.1 AA). Writes a11y-report.json; exits 1 on any failure. */
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const TOKENS = path.join(__dirname, '..', 'tokens.json');
7
+ const T = JSON.parse(fs.readFileSync(TOKENS, 'utf8'));
8
+
9
+ function resolve(value, theme, depth = 0) {
10
+ if (depth > 16) throw new Error('alias loop at ' + value);
11
+ const m = /^\{(primitive|semantic|component)\.([a-z0-9-]+)(?:\.([a-z0-9]+))?\}$/.exec(String(value).trim());
12
+ if (!m) return String(value).trim();
13
+ const [, tier, a, b] = m;
14
+ if (tier === 'primitive') { const p = T.primitive[a]; return b ? p[b] : p; }
15
+ const v = T[tier][theme][a];
16
+ if (v === undefined) throw new Error(`missing ${tier}.${a} (${theme})`);
17
+ return resolve(v, theme, depth + 1);
18
+ }
19
+ const tok = (name, theme) => resolve(T.semantic[theme][name] ?? T.component[theme][name], theme);
20
+
21
+ function rgb(c, ground) {
22
+ let m = /^#([0-9a-f]{6})$/i.exec(c);
23
+ if (m) return [0, 2, 4].map((i) => parseInt(m[1].slice(i, i + 2), 16));
24
+ m = /^#([0-9a-f]{3})$/i.exec(c);
25
+ if (m) return m[1].split('').map((x) => parseInt(x + x, 16));
26
+ m = /^rgba?\(([^)]+)\)$/i.exec(c);
27
+ if (m) {
28
+ const [r, g, b, a = 1] = m[1].split(',').map(Number);
29
+ if (a >= 1 || !ground) return [r, g, b];
30
+ const G = rgb(ground);
31
+ return [r, g, b].map((v, i) => Math.round(a * v + (1 - a) * G[i]));
32
+ }
33
+ throw new Error('unsupported colour ' + c);
34
+ }
35
+ const lum = (c) => rgb(c).map((v) => v / 255).map((v) => (v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4))
36
+ .reduce((s, v, i) => s + v * [0.2126, 0.7152, 0.0722][i], 0);
37
+ function ratio(fg, bg) {
38
+ const B = '#' + rgb(bg).map((v) => v.toString(16).padStart(2, '0')).join('');
39
+ const F = '#' + rgb(fg, B).map((v) => v.toString(16).padStart(2, '0')).join('');
40
+ const a = lum(F), b = lum(B);
41
+ return (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05);
42
+ }
43
+
44
+ const TEXT = 4.5, UI = 3;
45
+ const grounds = ['bg-surface', 'bg-canvas', 'bg-surface-hover'];
46
+ const pairs = [];
47
+ for (const fg of ['fg-primary', 'fg-secondary', 'fg-tertiary', 'fg-accent', 'fg-danger', 'fg-positive']) for (const bg of grounds) pairs.push([fg, bg, TEXT]);
48
+ pairs.push(['fg-primary', 'bg-selected', TEXT], ['fg-secondary', 'bg-selected', TEXT]);
49
+ pairs.push(['fg-inverted', 'bg-surface-strong', TEXT], ['fg-inverted', 'bg-inverted', TEXT]);
50
+ pairs.push(['button-primary-fg', 'button-primary-bg', TEXT], ['button-primary-fg', 'button-primary-bg-hover', TEXT]);
51
+ for (const t of ['neutral', 'progress', 'ready', 'blocked']) pairs.push([`status-${t}-fg`, `status-${t}-bg`, TEXT]);
52
+ for (const t of ['info', 'success', 'warning', 'danger']) pairs.push([`alert-${t}-fg`, `alert-${t}-bg`, TEXT], ['fg-primary', `alert-${t}-bg`, TEXT]);
53
+ pairs.push(['on-texture', 'mesh-from', TEXT], ['on-texture', 'mesh-to', TEXT]);
54
+ for (const bg of ['bg-surface', 'bg-canvas', 'bg-input', 'bg-selected']) pairs.push(['border-control', bg, UI]);
55
+ for (const bg of ['bg-surface', 'bg-canvas', 'bg-surface-hover', 'bg-selected']) pairs.push(['focus-ring', bg, UI]);
56
+ pairs.push(['border-danger', 'bg-input', UI]);
57
+
58
+ const results = [], fails = [];
59
+ for (const theme of ['light', 'dark']) for (const [fg, bg, min] of pairs) {
60
+ const r = ratio(tok(fg, theme), tok(bg, theme));
61
+ const row = { theme, fg, bg, ratio: +r.toFixed(2), min, pass: r >= min };
62
+ results.push(row);
63
+ if (!row.pass) fails.push(`${theme}: ${fg} on ${bg} = ${row.ratio}:1 (needs ${min}:1)`);
64
+ }
65
+ fs.writeFileSync(path.join(process.cwd(), 'a11y-report.json'), JSON.stringify({ version: T.version, checked: results.length, fails, results }, null, 2));
66
+ if (fails.length) { console.error(`A11y FAIL — ${fails.length} of ${results.length} pairs:\n ` + fails.join('\n ')); process.exit(1); }
67
+ console.log(`A11y contrast OK — ${results.length} pairs pass in light and dark (AURA ${T.version}).`);
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ /* Token lint — fails when source files hard-code colours instead of AURA tokens.
3
+ * Usage: node scripts/lint-tokens.js [dir] (default: ./src) */
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const dir = path.resolve(process.argv[2] || path.join(process.cwd(), 'src'));
7
+ const ALLOW = /(aura\.css|aura\.components\.css|aura\.bundle\.js|tokens\.json|tailwind\.tokens\.cjs|figma-variables\.csv)$/;
8
+ const EXT = /\.(tsx?|jsx?|css|scss|mdx)$/;
9
+ const COLOUR = /#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3,4})\b|\b(?:rgba?|hsla?)\(\s*\d|\b(?:bg|text|border|ring|fill|stroke)-\[(?:#|rgb|hsl)/gi;
10
+ const violations = [];
11
+ function scan(d) {
12
+ if (!fs.existsSync(d)) return;
13
+ for (const f of fs.readdirSync(d)) {
14
+ const full = path.join(d, f);
15
+ if (f === 'node_modules' || f.startsWith('.')) continue;
16
+ if (fs.statSync(full).isDirectory()) { scan(full); continue; }
17
+ if (!EXT.test(f) || ALLOW.test(f)) continue;
18
+ const text = fs.readFileSync(full, 'utf8');
19
+ /* A file that must hold raw colours (the theme generator) says so, with a reason, in its first lines. */
20
+ if (/aura-lint:\s*allow-colours/.test(text.slice(0, 600))) continue;
21
+ text.split('\n').forEach((line, i) => {
22
+ const m = line.match(COLOUR);
23
+ if (m) violations.push(`${path.relative(process.cwd(), full)}:${i + 1} ${m.join(', ')}`);
24
+ });
25
+ }
26
+ }
27
+ scan(dir);
28
+ if (violations.length) {
29
+ console.error(`Token lint FAIL: ${violations.length} hard-coded colour(s) — use semantic tokens\n ` + violations.join('\n '));
30
+ process.exit(1);
31
+ }
32
+ console.log(`Token lint OK — no hard-coded colours in ${path.relative(process.cwd(), dir) || '.'}`);
@@ -0,0 +1,29 @@
1
+ import type { Config } from 'tailwindcss'
2
+ // Token maps are GENERATED from tokens.json — run `npm run build:tokens` after editing tokens.
3
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
4
+ const aura = require('./tailwind.tokens.cjs')
5
+
6
+ const config: Config = {
7
+ darkMode: 'class', // `.dark` on <html>; [data-theme="dark"] works too because aura.css declares both
8
+ content: [
9
+ './src/**/*.{js,ts,jsx,tsx,mdx}',
10
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
11
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
12
+ ],
13
+ theme: {
14
+ extend: {
15
+ // bg-bg-surface · text-fg-primary · border-border-strong · text-fg-danger · bg-alert-warning-bg …
16
+ colors: aura.colors,
17
+ // p-aura-6 · gap-aura-4 · rounded-aura-xl · shadow-aura-overlay · ease-aura-ease · duration-aura-fast · z-aura-dialog
18
+ spacing: aura.spacing,
19
+ borderRadius: aura.borderRadius,
20
+ boxShadow: aura.boxShadow,
21
+ transitionTimingFunction: aura.transitionTimingFunction,
22
+ transitionDuration: aura.transitionDuration,
23
+ zIndex: aura.zIndex,
24
+ fontFamily: aura.fontFamily, // font-display · font-sans · font-mono · font-thai
25
+ },
26
+ },
27
+ plugins: [],
28
+ }
29
+ export default config