@karmo-co/drift-kit-reference 0.0.0-stage → 23.4.0

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.
Files changed (92) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +24 -2
  3. package/bin/drift-kit-ref.js +169 -0
  4. package/manifest/components/accordion.md +47 -0
  5. package/manifest/components/action-bar.md +51 -0
  6. package/manifest/components/alert.md +53 -0
  7. package/manifest/components/app-shell.md +43 -0
  8. package/manifest/components/avatar.md +42 -0
  9. package/manifest/components/body.md +48 -0
  10. package/manifest/components/box.md +58 -0
  11. package/manifest/components/breadcrumb.md +59 -0
  12. package/manifest/components/button.md +46 -0
  13. package/manifest/components/calendar.md +69 -0
  14. package/manifest/components/card.md +71 -0
  15. package/manifest/components/checkbox.md +43 -0
  16. package/manifest/components/choice-card.md +61 -0
  17. package/manifest/components/code-input.md +56 -0
  18. package/manifest/components/date-picker.md +66 -0
  19. package/manifest/components/day-of-month.md +54 -0
  20. package/manifest/components/detail-list.md +37 -0
  21. package/manifest/components/divider.md +33 -0
  22. package/manifest/components/dropdown.md +52 -0
  23. package/manifest/components/dropzone.md +56 -0
  24. package/manifest/components/eyebrow.md +45 -0
  25. package/manifest/components/feedback-badge.md +35 -0
  26. package/manifest/components/glider.md +34 -0
  27. package/manifest/components/heading.md +47 -0
  28. package/manifest/components/hero.md +46 -0
  29. package/manifest/components/icon-button.md +41 -0
  30. package/manifest/components/icon-tile.md +44 -0
  31. package/manifest/components/icon.md +30 -0
  32. package/manifest/components/input.md +63 -0
  33. package/manifest/components/link.md +42 -0
  34. package/manifest/components/loading-spinner.md +42 -0
  35. package/manifest/components/logo.md +38 -0
  36. package/manifest/components/modal.md +53 -0
  37. package/manifest/components/pagination.md +54 -0
  38. package/manifest/components/payment-form.md +29 -0
  39. package/manifest/components/price-summary.md +30 -0
  40. package/manifest/components/radio.md +42 -0
  41. package/manifest/components/section-heading.md +41 -0
  42. package/manifest/components/select.md +99 -0
  43. package/manifest/components/shield.md +34 -0
  44. package/manifest/components/sidebar.md +73 -0
  45. package/manifest/components/stepper.md +53 -0
  46. package/manifest/components/switch.md +45 -0
  47. package/manifest/components/table.md +77 -0
  48. package/manifest/components/tabs.md +43 -0
  49. package/manifest/components/tag.md +43 -0
  50. package/manifest/components/textarea.md +52 -0
  51. package/manifest/components/toast.md +52 -0
  52. package/manifest/components/tooltip.md +42 -0
  53. package/manifest/components/top-bar.md +60 -0
  54. package/manifest/components/vehicle.md +43 -0
  55. package/manifest/index.json +402 -0
  56. package/manifest/migrations/1.0.0.md +50 -0
  57. package/manifest/migrations/10.0.0.md +154 -0
  58. package/manifest/migrations/11.0.0.md +24 -0
  59. package/manifest/migrations/12.0.0.md +38 -0
  60. package/manifest/migrations/13.0.0.md +50 -0
  61. package/manifest/migrations/14.0.0.md +148 -0
  62. package/manifest/migrations/15.0.0.md +140 -0
  63. package/manifest/migrations/16.0.0.md +196 -0
  64. package/manifest/migrations/17.0.0.md +19 -0
  65. package/manifest/migrations/18.0.0.md +23 -0
  66. package/manifest/migrations/19.0.0.md +15 -0
  67. package/manifest/migrations/2.0.0.md +18 -0
  68. package/manifest/migrations/20.0.0.md +43 -0
  69. package/manifest/migrations/21.0.0.md +97 -0
  70. package/manifest/migrations/22.0.0.md +17 -0
  71. package/manifest/migrations/23.0.0.md +86 -0
  72. package/manifest/migrations/3.0.0.md +34 -0
  73. package/manifest/migrations/4.0.0.md +147 -0
  74. package/manifest/migrations/5.0.0.md +73 -0
  75. package/manifest/migrations/6.0.0.md +67 -0
  76. package/manifest/migrations/7.0.0.md +71 -0
  77. package/manifest/migrations/8.0.0.md +16 -0
  78. package/manifest/migrations/9.0.0.md +107 -0
  79. package/manifest/rules.md +37 -0
  80. package/manifest/setup.md +28 -0
  81. package/manifest/tokens/border-width.md +12 -0
  82. package/manifest/tokens/border.md +147 -0
  83. package/manifest/tokens/font.md +90 -0
  84. package/manifest/tokens/icon.md +84 -0
  85. package/manifest/tokens/interactive.md +37 -0
  86. package/manifest/tokens/motion.md +69 -0
  87. package/manifest/tokens/radius.md +20 -0
  88. package/manifest/tokens/shadow.md +28 -0
  89. package/manifest/tokens/spacing.md +35 -0
  90. package/manifest/tokens/surface.md +138 -0
  91. package/manifest/tokens/text.md +92 -0
  92. package/package.json +20 -4
@@ -0,0 +1,43 @@
1
+ ## 20.0.0 - 2026-10-12
2
+
3
+ ### Migration
4
+
5
+ - **Tabs is now the underline tabs; the old Tabs is Segmented control.** The
6
+ sliding pill in a raised frame (`.dk-component-tabs` > `.dk-component-tab`
7
+ + `.dk-component-tab-indicator`) is `.dk-component-segmented` > `__option`
8
+ + `__indicator`, with radio semantics (`role="radiogroup"`, `role="radio"`,
9
+ `aria-checked`, written by the runtime); `.active` is no longer read. Its
10
+ tokens are `--dk-component-segmented-*`, its runtime
11
+ `dk.component.segmented`, its event `dk-component-segmented:change`
12
+ `{ value, values, option }`. The full map is
13
+ `migrations/20.0.0-tabs-to-segmented.json`. React `Tabs` keeps its name and
14
+ props but renders the new tabs; use `SegmentedControl` for the old look.
15
+
16
+ ### Rename map: `migrations/20.0.0-tabs-to-segmented.json`
17
+
18
+ ```json
19
+ {
20
+ "version": "20.0.0",
21
+ "summary": "Tabs is now the underline tabs Forge's design system pages use (with a pill variant); the old Tabs, a sliding pill in a raised frame, is now Segmented control, with radio semantics, and gains multiple selection, icon-only options and full width.",
22
+ "rename": {
23
+ ".dk-component-tabs (with .dk-component-tab children)": ".dk-component-segmented",
24
+ ".dk-component-tab": ".dk-component-segmented__option",
25
+ ".dk-component-tab-indicator": ".dk-component-segmented__indicator",
26
+ ".dk-component-tab-ico": ".dk-component-segmented__icon",
27
+ "--dk-component-tabs-*": "--dk-component-segmented-*",
28
+ "dk.component.tabs (the slider)": "dk.component.segmented",
29
+ "dk-component-tabs:change { index, tab }": "dk-component-segmented:change { value, values, option }"
30
+ },
31
+ "semantics": {
32
+ "role=\"tablist\" + role=\"tab\" + aria-selected": "role=\"radiogroup\" + role=\"radio\" + aria-checked (the runtime writes them). A strip that switched panels keeps doing so: aria-controls on an option shows its panel.",
33
+ ".active": "no longer read or written; aria-checked is the state"
34
+ },
35
+ "added": {
36
+ ".dk-component-tabs": "New: a tablist of .dk-component-tabs__tab (with __icon, __label, __count), an underline by default and data-variant=\"pill\", data-size, data-full-width, data-activation=\"manual\"; the runtime adds the __indicator.",
37
+ ".dk-component-segmented[data-multiple]": "Several chosen: a group of toggle buttons with aria-pressed, each pressed option on its own pill.",
38
+ "React": "Tabs keeps its name and props and renders the new tabs (adds variant, count, fullWidth, activation); SegmentedControl is new (options, multiple, value/defaultValue/onChange, size, fullWidth)."
39
+ },
40
+ "migrate": "Replace the classes as in rename. Leave role, aria-selected and tabindex to the runtime, or write role=\"radio\" with aria-checked yourself."
41
+ }
42
+ ```
43
+
@@ -0,0 +1,97 @@
1
+ ## 21.0.0 - 2026-10-14
2
+
3
+ ### Migration
4
+
5
+ - **Segmented control is now Glider.** `.dk-component-segmented` and its
6
+ parts are `.dk-component-glider`, `__option`, `__indicator`, `__icon` and
7
+ `__label`; its tokens are `--dk-component-glider-*`, its runtime
8
+ `dk.component.glider`, its event `dk-component-glider:change`, and React's
9
+ `SegmentedControl` is `Glider` (types `GliderProps`, `GliderOption` and so
10
+ on). Nothing else changes. The map is
11
+ `migrations/21.0.0-segmented-to-glider.json`.
12
+ - **Tabs has no pill variant.** Tabs is the underline alone:
13
+ `data-variant="pill"` and React's `variant` are gone, with the pill's
14
+ tokens (`--dk-component-tabs-pill-*`, `-count-on-pill-surface`); the
15
+ count's corner is `--dk-component-tabs-count-radius`. A pill look that
16
+ picks a value, one or several, is the Glider's. The map is
17
+ `migrations/21.0.0-tabs-pill-removed.json`.
18
+ - **Motion is a scale and patterns.** Seven durations became four (quick 120,
19
+ brisk 200, moderate 320, slow 480) and five easings four (standard,
20
+ emphasized, exit, spring). Components read patterns: state, press, travel,
21
+ enter, enter-large, exit, exit-large, expand, feedback, loop and cascade.
22
+ The old names are removed; the map is `migrations/21.0.0-motion-scale.json`.
23
+
24
+ ### Rename map: `migrations/21.0.0-motion-scale.json`
25
+
26
+ ```json
27
+ {
28
+ "version": "21.0.0",
29
+ "summary": "Motion is four durations, four easings and the patterns components read (13 Oct: snappy and fluid). Read a pattern by its job; the scale names below map to the nearest step, but a component should move to a pattern, not to the step.",
30
+ "rename": {
31
+ "--dk-motion-duration-snap": "--dk-motion-duration-quick (or --dk-motion-state-duration)",
32
+ "--dk-motion-duration-fast": "--dk-motion-duration-quick (or --dk-motion-state-duration)",
33
+ "--dk-motion-duration-default": "--dk-motion-duration-brisk (or --dk-motion-press-duration)",
34
+ "--dk-motion-duration-slower": "--dk-motion-duration-slow (or --dk-motion-enter-large-duration)",
35
+ "--dk-motion-duration-slowest": "--dk-motion-duration-slow (or --dk-motion-enter-large-duration)",
36
+ "--dk-motion-easing-in-out": "--dk-motion-easing-standard (or --dk-motion-state-easing)",
37
+ "--dk-motion-easing-out": "--dk-motion-easing-standard (or --dk-motion-state-easing)",
38
+ "--dk-motion-easing-ease": "--dk-motion-easing-standard (or --dk-motion-state-easing)",
39
+ "--dk-primitive-motion-duration-125": "--dk-primitive-motion-duration-120",
40
+ "--dk-primitive-motion-duration-150": "--dk-primitive-motion-duration-120",
41
+ "--dk-primitive-motion-duration-250": "--dk-primitive-motion-duration-200",
42
+ "--dk-primitive-motion-duration-300": "--dk-primitive-motion-duration-320",
43
+ "--dk-primitive-motion-duration-400": "--dk-primitive-motion-duration-480",
44
+ "--dk-primitive-motion-duration-500": "--dk-primitive-motion-duration-480",
45
+ "--dk-primitive-motion-easing-in-out": "--dk-primitive-motion-easing-standard",
46
+ "--dk-primitive-motion-easing-out": "--dk-primitive-motion-easing-standard",
47
+ "--dk-primitive-motion-easing-ease": "--dk-primitive-motion-easing-standard"
48
+ },
49
+ "changed": {
50
+ "--dk-motion-duration-moderate": "250ms -> 320ms",
51
+ "--dk-motion-duration-slow": "300ms -> 480ms",
52
+ "reduced motion": "fades at 120 to 160ms instead of cutting to 0.01ms"
53
+ },
54
+ "migrate": "Inside drift-kit every component already reads patterns."
55
+ }
56
+ ```
57
+
58
+ ### Rename map: `migrations/21.0.0-segmented-to-glider.json`
59
+
60
+ ```json
61
+ {
62
+ "version": "21.0.0",
63
+ "summary": "Segmented control is renamed Glider (13 Oct). Same markup, tokens, behaviour and semantics under the new name.",
64
+ "rename": {
65
+ ".dk-component-segmented": ".dk-component-glider",
66
+ ".dk-component-segmented__option": ".dk-component-glider__option",
67
+ ".dk-component-segmented__indicator": ".dk-component-glider__indicator",
68
+ ".dk-component-segmented__icon": ".dk-component-glider__icon",
69
+ ".dk-component-segmented__label": ".dk-component-glider__label",
70
+ "--dk-component-segmented-*": "--dk-component-glider-*",
71
+ "dk.component.segmented": "dk.component.glider",
72
+ "dk-component-segmented:change": "dk-component-glider:change",
73
+ "React SegmentedControl": "React Glider",
74
+ "React SegmentedControlProps, SegmentedSingleProps, SegmentedMultipleProps, SegmentedOption, SegmentedSize": "GliderProps, GliderSingleProps, GliderMultipleProps, GliderOption, GliderSize"
75
+ },
76
+ "migrate": "Replace the names as in rename; nothing else changes."
77
+ }
78
+ ```
79
+
80
+ ### Rename map: `migrations/21.0.0-tabs-pill-removed.json`
81
+
82
+ ```json
83
+ {
84
+ "version": "21.0.0",
85
+ "summary": "Tabs loses its pill variant (13 Oct): tabs are the underline alone, and a pill look that picks a value is the Glider's.",
86
+ "removed": {
87
+ "[data-variant=\"pill\"] on .dk-component-tabs": "Gone. Tabs that switch panels drop the attribute and become the underline; a pill strip that picks a value becomes a .dk-component-glider (data-multiple for several).",
88
+ "React Tabs variant, TabsVariant": "Gone; drop the prop.",
89
+ "--dk-component-tabs-pill-gap, -pill-height, -pill-small-height, -pill-large-height, -pill-padding-inline, -pill-small-padding-inline, -pill-large-padding-inline, -pill-surface, -pill-selected-color, -pill-surface-hover, -count-on-pill-surface": "Gone with the variant."
90
+ },
91
+ "rename": {
92
+ "--dk-component-tabs-pill-radius": "--dk-component-tabs-count-radius"
93
+ },
94
+ "migrate": ""
95
+ }
96
+ ```
97
+
@@ -0,0 +1,17 @@
1
+ ## 22.0.0 - 2026-10-15
2
+
3
+ ### Migration
4
+
5
+ - **Breadcrumb's separator is a slash, drawn as text.**
6
+ `--dk-component-breadcrumb-separator-icon` is gone; the separator's colour
7
+ is still `--dk-component-breadcrumb-separator-color`. Past pages are now
8
+ subtle neutral pills rather than primary links, and an item with a menu
9
+ wraps its link (or current page) and its `__more` in `span.__pill`. The
10
+ old markup still renders; it only lacks the joined pair.
11
+ - **Edged buttons are 2px smaller.** Plain, raised and outline Buttons and
12
+ Icon buttons now take their border out of their padding, so they are the
13
+ size borderless ones are (44px at medium, was 46). A layout that measured
14
+ around the old size moves by that much.
15
+ - **App shell sits on white.** `--dk-component-app-shell-surface` is the page
16
+ surface, not the grey canvas.
17
+
@@ -0,0 +1,86 @@
1
+ ## 23.0.0 - 2026-10-17
2
+
3
+ ### Breaking
4
+
5
+ - **Box has five sizes** (16 Oct): `xsmall` (12), `small` (18), `medium`
6
+ (24, the default), `large` (32) and `xlarge` (40). Past medium the corner
7
+ and the header grow too (radius 300 and 400, an h5 and an h4 title over a
8
+ body-md description). The tokens moved with the names:
9
+ `--dk-component-box-padding` is now 24, `-small-padding` 18 and
10
+ `-large-padding` 32; `-xsmall-*`, `-xlarge-*`, `-large-radius`,
11
+ `-xlarge-radius` and the large and xlarge title and description tokens are
12
+ new.
13
+
14
+ ### Migration
15
+
16
+ | Was | Now, for the same box |
17
+ |---|---|
18
+ | `data-size="small"` (`size="small"`) | `data-size="xsmall"` |
19
+ | no `data-size` (`size="medium"`) | `data-size="small"` |
20
+ | `data-size="large"` (`size="large"`) | no `data-size` (`size="medium"`) |
21
+
22
+ An override of `--dk-component-box-padding`, `-small-padding` or
23
+ `-large-padding` moves the same way.
24
+
25
+ ### Behaviour changes
26
+
27
+ - **Glider labels a rung smaller, with more air** (17 Oct): small, medium and
28
+ large labels are 10, 12 and 14px (were 12, 14, 16), the padding beside them
29
+ 12, 16 and 20px (were 8, 12, 16), and the icons 12, 14 and 16px (were 14,
30
+ 16, 20). Heights are unchanged (36, 44, 52). An option is wider than it was.
31
+
32
+ - **Card is rebuilt** (16 Oct). Same markup (`__media`, `__body`, `__title`,
33
+ `__subtitle` still render), new look and reach:
34
+ - `data-variant` raised (default), outline, flat; `data-size` small,
35
+ medium, large; `data-orientation="horizontal"`; `data-media="inset"`;
36
+ `__media` takes `data-ratio` (16/9 default, 1/1, 4/3, 3/2, 21/9) and
37
+ `data-fit="contain"`; new `__eyebrow`, `__meta`, one full-width `__cta`,
38
+ and `__corner[data-corner="start|end"]` for buttons over the top corners
39
+ (a heart toggle that fills when pressed, a Dropdown menu); with either,
40
+ a `__link` in the title stretches over the card. `data-corners="hover"`
41
+ fades the corners in under the pointer or the focus (a pressed toggle and
42
+ an open menu stay shown; a screen that cannot hover always shows them);
43
+ shown always on a card with no media, they take a row above the words,
44
+ and beside the body both sit on the media.
45
+ - It paints the kit surface, so `data-tone`, `data-tone-fill` and
46
+ `data-surface` drive it, and hover and press climb that surface's
47
+ control rungs. It is no longer a tone boundary: on a solid or tinted
48
+ panel it takes the panel's colours, as Box does. `data-surface="0"`
49
+ gives it the page back.
50
+ - Surface tier: grows on hover, presses on the surface rung. Only a link,
51
+ a button, a tab stop or a stretched card moves; a static card is still.
52
+ - The corner is radius 300 (was a literal 14px), the media is 16/9 (was
53
+ 132px), the title body-md (was 15px), and the subtitle wraps to two
54
+ lines (was one) through `--dk-component-card-subtitle-lines`.
55
+ - Selected (`aria-pressed`, `aria-current`) wears the primary edge;
56
+ `aria-disabled` stills it and dims it; the focus ring is an outline.
57
+ - React `Card` gains variant, size, orientation, tone, toneFill, surface,
58
+ eyebrow, meta, cta, cornerStart, cornerEnd, mediaRatio, mediaFit,
59
+ mediaInset, selected and disabled.
60
+ - **Two control press rungs** (16 Oct): text-width controls (Button, Glider,
61
+ Tabs, Breadcrumb and Top bar links, the phone sidebar tabs) press to 0.97;
62
+ small squares take the new compact rung, 0.93 (Icon button, Pagination
63
+ pages, Calendar days, Day of month cells), with `--dk-interactive-press-compact`
64
+ and `data-interactive="compact"`. Accordion headers press on the panel rung
65
+ (0.99): full width, they lurched at the item rung.
66
+ - **The quiet ramp follows the tone.** `--dk-interactive-surface-hover` and
67
+ `-active` and the nested fill read the control fills: the same greys on a
68
+ plain surface, the tone's and the level's next rung on a toned one.
69
+ - **Words step a rung per state** on Breadcrumb, Sidebar, Pagination, Glider,
70
+ Tabs and Top bar links (they rest a step lighter); Dropdown and Select menu
71
+ words stay full strength. On a solid tone the quiet word ramp steps to the
72
+ tone's white.
73
+ - **Presses:** Dropdown and Select options, Sidebar items and the Action bar
74
+ summary press on the item rung; Breadcrumb and Top bar links on the control
75
+ rung, Pagination, Calendar and Day of month cells on the compact rung (see
76
+ above); Choice card grows on hover.
77
+ - **Selected and highlighted:** the Sidebar's current item, Pagination's
78
+ current page and a picked day read the foundation's selected; a checked
79
+ Table row its highlighted tint.
80
+ - **Sidebar** items press a rung past hover and hover with the fill alone.
81
+ - **Accordion** sits on the surface it is on, and **Dropzone** on the control
82
+ fill, so both follow the tone, the level and the fill; Dropzone's hover,
83
+ press, chosen-file and focus states follow a status tone too.
84
+ - **Inset Glider** words go full strength inside a status tone, as inset
85
+ Breadcrumb's do; an inset Select chevron keeps its tone colour on hover.
86
+
@@ -0,0 +1,34 @@
1
+ ## 3.0.0 — 2026-09-09
2
+
3
+ ### Breaking
4
+
5
+ - `data-theme` values are lowercase: `data-theme="light"` / `data-theme="dark"`,
6
+ matching every other Drift attribute (`data-surface`, `data-tone`,
7
+ `data-density`, `data-border-radius`, `data-border-width`). `Light` / `Dark`
8
+ no longer match any selector. Kit selectors are normalised to the quoted form
9
+ `[data-theme="light"]` (238 selectors; the 3 unquoted `[data-alignment=…]`
10
+ selectors are quoted too). Token values are unchanged — 1,542 tokens across
11
+ six theme/surface/tone scopes compare equal between 2.0.0 with `Light`/`Dark`
12
+ and 3.0.0 with `light`/`dark`.
13
+ - Consumers: set `<body data-theme="light|dark">`, lowercase any stored theme
14
+ preference on read, and update your own `[data-theme=Light|Dark]` selectors
15
+ and `=== 'Light'` / `'Dark'` comparisons. Map in
16
+ `migrations/3.0.0-data-theme.json`.
17
+
18
+ ### Rename map: `migrations/3.0.0-data-theme.json`
19
+
20
+ ```json
21
+ {
22
+ "version": "3.0.0",
23
+ "date": "2026-09-09",
24
+ "summary": "data-theme values are lowercase like every other Drift attribute. Selectors in the kit are quoted [data-theme=\"light\"] / [data-theme=\"dark\"].",
25
+ "attributes": {
26
+ "data-theme": {
27
+ "Light": "light",
28
+ "Dark": "dark"
29
+ }
30
+ },
31
+ "consumers": "Set <body data-theme=\"light|dark\">; lowercase any stored preference on read; update your own [data-theme=Light|Dark] selectors and === 'Light'/'Dark' comparisons. Token values are unchanged (1,542 tokens x 6 scopes compared equal)."
32
+ }
33
+ ```
34
+
@@ -0,0 +1,147 @@
1
+ ## 4.0.0 — 2026-09-10
2
+
3
+ ### Breaking
4
+
5
+ - **The type scale is rebuilt, and sizes leave the h1…h6 vocabulary.** Hero,
6
+ Heading and Body now read one Karmo-owned scale
7
+ (`alias/karmo/font/type-scale.css`) and name their rungs from one shared
8
+ t-shirt vocabulary, `xxlarge` … `xxsmall` — the words Body and Eyebrow already
9
+ used. The audit that prompted this found three faults: Hero read the HEADING
10
+ ramp, so the display tier topped out at the same 48px as an H1 and ran down to
11
+ 24px; the heading ramp had a 36% gap at the top and three rungs inside 4px at
12
+ the bottom (28 · 26 · 24); and Body jumped 16 → 20 with no reading rung
13
+ between. Every value is now a `--dk-primitive-scale-*` step (one noted
14
+ exception, 26px) and every ramp is monotonic in size and in leading ratio.
15
+ - Hero — its own DISPLAY ramp, 72 · 64 · 56 · 48 · 40 desktop, scaling over
16
+ three breakpoints, never below 40px.
17
+ - Heading — seven rungs, 48 · 40 · 36 · 32 · 28 · 24 · 20 desktop, every step
18
+ at least 11%.
19
+ - Body — five rungs, 20 · 18 · 16 · 14 · 12, fixed at every breakpoint.
20
+ **`large` changed VALUE, not just name**: it was 20px, it is now the new
21
+ 18px rung, and the old 20px is `xlarge`. This is the only silent change in
22
+ the release — a stale `data-size="large"` still renders, 2px smaller.
23
+ - Eyebrow — unchanged.
24
+ Why not h1…h6: the size axis exists to decouple the visual size from the
25
+ element, and naming its values after the HTML outline invites exactly the
26
+ coupling it was built to break — an author who needs an `<h2>` reaches for
27
+ `data-size="h2"` and lets the look pick the semantics. The element is still
28
+ yours; the size is now named in a vocabulary that cannot be mistaken for it.
29
+ - **`disabled` is a state, not a colour.** `data-color="disabled"` is gone from
30
+ body, heading, hero, eyebrow and icon; the state is `[data-disabled]` or
31
+ `[aria-disabled="true"]`, the pair Button already accepts. It composes with
32
+ `data-color` instead of replacing it, so a disabled error label is finally
33
+ expressible. Not `data-status` — that axis is the five semantic statuses, and
34
+ disabled is an interaction state, which is how every other component models it.
35
+ - **`data-dc-tooltip` → `data-dk-tooltip`.** The last public name still carrying
36
+ the pre-2.0.0 prefix.
37
+
38
+ #### Added
39
+
40
+ - `data-style="italic"` on Heading. Inter ships a drawn italic at every weight,
41
+ so this selects a real face. Hero deliberately does NOT get one: Syne ships
42
+ `normal` only, and a browser-synthesised oblique is not a typeface decision.
43
+
44
+ ##### Fixed
45
+
46
+ - Stale `--dc-*` collection names and retired `window.dc*` globals in source
47
+ comments, which had named tokens and functions that no longer exist since
48
+ 2.0.0. Prose only.
49
+
50
+ Migration map: `migrations/4.0.0-type-scale.json`. Design note: forge
51
+ `docs/superpowers/specs/2026-09-10-drift-type-scale-design.md`.
52
+
53
+ ### Rename map: `migrations/4.0.0-type-scale.json`
54
+
55
+ ```json
56
+ {
57
+ "version": "4.0.0",
58
+ "date": "2026-09-10",
59
+ "note": "The type scale rebuild. Four breaking changes: (1) Hero and Heading size values move from the h1…h6 outline vocabulary to the shared t-shirt rungs, and Hero moves onto its own display ramp; (2) Body gains an 18px rung, which means `large` CHANGES VALUE — see sizes.body.warning; (3) disabled stops being a data-color value and becomes a state; (4) the tooltip markup attribute takes the dk prefix. Every entry below is a mechanical find-and-replace except the one flagged warning.",
60
+
61
+ "sizes": {
62
+ "note": "data-size values, per component. Old px are desktop values.",
63
+
64
+ "hero": {
65
+ "note": "Hero now reads the DISPLAY ramp (72 · 64 · 56 · 48 · 40 desktop) instead of the heading ramp, so it is bigger at every rung and stops below 40px on purpose. h1 keeps its exact size under a new name; h2 rounds up 2px. h3/h4/h5 have NO display equivalent — 28/26/24px in Syne was a heading wearing the display face, and the right migration is to change the element to a Heading, not to pick the nearest Hero rung.",
66
+ "h1": "medium",
67
+ "h2": "small",
68
+ "h3": "→ use .dk-component-heading[data-size=\"small\"]",
69
+ "h4": "→ use .dk-component-heading[data-size=\"xsmall\"]",
70
+ "h5": "→ use .dk-component-heading[data-size=\"xsmall\"]"
71
+ },
72
+
73
+ "heading": {
74
+ "note": "Seven rungs, 48 → 20 desktop. h1, h3, h5 and h6 keep their exact px; h2 rounds up 2px (38 → 40); h4 rounds down 2px (26 → 24) and lands on the same rung as h5, which is the point — 28/26/24 were three rungs inside 4px.",
75
+ "h1": "xxlarge",
76
+ "h2": "xlarge",
77
+ "h3": "small",
78
+ "h4": "xsmall",
79
+ "h5": "xsmall",
80
+ "h6": "xxsmall"
81
+ },
82
+
83
+ "body": {
84
+ "warning": "`large` is the one name in 4.0.0 whose VALUE changed rather than its name: it was 20px and is now 18px, the new reading rung. Anything that wants the old 20px must move to `xlarge`. A stale data-size=\"large\" keeps rendering — 2px smaller — so this one cannot be caught by a missing-token check. Search for it explicitly.",
85
+ "large": "xlarge",
86
+ "medium": "medium",
87
+ "small": "small",
88
+ "extra-small": "xsmall"
89
+ },
90
+
91
+ "eyebrow": {
92
+ "note": "Unchanged — large/medium/small at 12/11/10 were already on the shared vocabulary."
93
+ }
94
+ },
95
+
96
+ "states": {
97
+ "note": "disabled is a state now, not a palette value, so it composes with data-color instead of replacing it. Applies to body, heading, hero, eyebrow and icon. Use aria-disabled=\"true\" when the thing really is announced as disabled; data-disabled when it is purely presentational.",
98
+ "data-color=\"disabled\"": "data-disabled",
99
+ "data-color=\"disabled\" data-emphasis=\"subtle\"": "data-disabled data-emphasis=\"subtle\""
100
+ },
101
+
102
+ "attributes": {
103
+ "note": "The last public name still on the pre-2.0.0 prefix.",
104
+ "data-dc-tooltip": "data-dk-tooltip"
105
+ },
106
+
107
+ "tokens": {
108
+ "--dk-component-hero-h1-font-size": "--dk-component-hero-medium-font-size",
109
+ "--dk-component-hero-h1-line-height": "--dk-component-hero-medium-line-height",
110
+ "--dk-component-hero-h2-font-size": "--dk-component-hero-small-font-size",
111
+ "--dk-component-hero-h2-line-height": "--dk-component-hero-small-line-height",
112
+ "--dk-component-hero-h3-font-size": "--dk-component-heading-small-font-size",
113
+ "--dk-component-hero-h3-line-height": "--dk-component-heading-small-line-height",
114
+ "--dk-component-hero-h4-font-size": "--dk-component-heading-xsmall-font-size",
115
+ "--dk-component-hero-h4-line-height": "--dk-component-heading-xsmall-line-height",
116
+ "--dk-component-hero-h5-font-size": "--dk-component-heading-xsmall-font-size",
117
+ "--dk-component-hero-h5-line-height": "--dk-component-heading-xsmall-line-height",
118
+
119
+ "--dk-component-heading-h1-font-size": "--dk-component-heading-xxlarge-font-size",
120
+ "--dk-component-heading-h1-line-height": "--dk-component-heading-xxlarge-line-height",
121
+ "--dk-component-heading-h2-font-size": "--dk-component-heading-xlarge-font-size",
122
+ "--dk-component-heading-h2-line-height": "--dk-component-heading-xlarge-line-height",
123
+ "--dk-component-heading-h3-font-size": "--dk-component-heading-small-font-size",
124
+ "--dk-component-heading-h3-line-height": "--dk-component-heading-small-line-height",
125
+ "--dk-component-heading-h4-font-size": "--dk-component-heading-xsmall-font-size",
126
+ "--dk-component-heading-h4-line-height": "--dk-component-heading-xsmall-line-height",
127
+ "--dk-component-heading-h5-font-size": "--dk-component-heading-xsmall-font-size",
128
+ "--dk-component-heading-h5-line-height": "--dk-component-heading-xsmall-line-height",
129
+ "--dk-component-heading-h6-font-size": "--dk-component-heading-xxsmall-font-size",
130
+ "--dk-component-heading-h6-line-height": "--dk-component-heading-xxsmall-line-height",
131
+
132
+ "--dk-component-body-large-font-size": "--dk-component-body-xlarge-font-size",
133
+ "--dk-component-body-large-line-height": "--dk-component-body-xlarge-line-height",
134
+ "--dk-component-body-extra-small-font-size": "--dk-component-body-xsmall-font-size",
135
+ "--dk-component-body-extra-small-line-height": "--dk-component-body-xsmall-line-height"
136
+ },
137
+
138
+ "new-names": {
139
+ "note": "Added, with nothing to migrate from.",
140
+ "--dk-font-scale-display-{xxlarge|xlarge|large|medium|small}-{text-size|line-height}": "the display ramp, responsive",
141
+ "--dk-font-scale-heading-{xxlarge…xxsmall}-{text-size|line-height}": "the heading ramp, responsive",
142
+ "--dk-font-scale-body-{xlarge…xsmall}-{text-size|line-height}": "the body ramp, fixed",
143
+ "--dk-component-heading-italic-font-style": "data-style=\"italic\" on Heading — Inter has a drawn italic; Hero has no equivalent because Syne ships none"
144
+ }
145
+ }
146
+ ```
147
+
@@ -0,0 +1,73 @@
1
+ ## 5.0.0 — 2026-09-10
2
+
3
+ ### Breaking
4
+
5
+ - **Disabled loses its emphasis axis on the type primitives.** `data-emphasis="subtle"`
6
+ no longer does anything alongside the disabled state on body, heading, hero,
7
+ eyebrow or icon, and the five `--dk-component-{x}-disabled-subtle-color`
8
+ tokens are removed. The surviving token drops the segment it no longer varies
9
+ on: `--dk-component-{x}-disabled-default-color` → `--dk-component-{x}-disabled-color`.
10
+
11
+ The two rungs were never two strengths of one idea. Measured against the page
12
+ surface, `-default` is **2.88:1** in light and **5.57:1** in dark; `-subtle` is
13
+ **1.80:1** and **2.33:1**. Below 2:1 is not a quieter label, it is text nobody
14
+ can read — so on prose the axis offered a choice between "dim" and "invisible"
15
+ with no rule for picking one. The kit itself never had to pick: every disabled
16
+ CONTROL label (Button's six variants, Checkbox's description) takes `-subtle`,
17
+ and `-default` was referenced exactly once outside the type primitives, by the
18
+ accent Button's text-*shadow*. Prose keeps the readable rung; controls keep
19
+ theirs.
20
+
21
+ #### Unchanged, deliberately
22
+
23
+ - `--dk-text-disabled-subtle` / `--dk-icon-disabled-subtle` stay — Button and
24
+ Checkbox still read them, and a disabled control is conventionally near-
25
+ invisible in a way a paragraph is not.
26
+ - `data-emphasis="subtle"` still works with `data-color="neutral"`, whose subtle
27
+ rung is a real, legible de-emphasis.
28
+
29
+ Migration map: `migrations/5.0.0-disabled-one-rung.json`.
30
+
31
+ ### Rename map: `migrations/5.0.0-disabled-one-rung.json`
32
+
33
+ ```json
34
+ {
35
+ "version": "5.0.0",
36
+ "date": "2026-09-10",
37
+ "note": "Disabled loses its emphasis axis on the type primitives. One breaking change, and the mechanical part of it is a token rename; the behavioural part is that `data-emphasis=\"subtle\"` no longer does anything alongside the disabled state. Nothing else moves — data-emphasis still works for data-color=\"neutral\", and the Mapped --dk-text-disabled-subtle / --dk-icon-disabled-subtle tokens are untouched because Button and Checkbox still read them.",
38
+
39
+ "why": "The two rungs were never two strengths of one idea. Measured against the page surface: -default is 2.88:1 in light and 5.57:1 in dark; -subtle is 1.80:1 and 2.33:1. Below 2:1 is not a quieter label, it is text nobody can read, so on prose the axis offered a choice between 'dim' and 'invisible' with no rule for picking. The kit never had to pick either: every disabled CONTROL label (Button's six variants, Checkbox's description) takes -subtle, and -default was referenced exactly once outside the type primitives (the accent Button's text-shadow). Prose keeps the readable rung; controls keep theirs.",
40
+
41
+ "attributes": {
42
+ "note": "Applies to body, heading, hero, eyebrow and icon. Drop the emphasis attribute; the disabled state alone is now the whole answer. If it was the ONLY reason data-emphasis was on the element, remove the attribute entirely.",
43
+ "data-disabled data-emphasis=\"subtle\"": "data-disabled",
44
+ "aria-disabled=\"true\" data-emphasis=\"subtle\"": "aria-disabled=\"true\""
45
+ },
46
+
47
+ "tokens": {
48
+ "note": "The `-default` segment goes with the axis: the collection grammar omits any segment a token no longer varies on. The -subtle component tokens are REMOVED, not renamed — a var() to one now resolves to nothing, which is the intended loud failure.",
49
+ "--dk-component-body-disabled-default-color": "--dk-component-body-disabled-color",
50
+ "--dk-component-heading-disabled-default-color": "--dk-component-heading-disabled-color",
51
+ "--dk-component-hero-disabled-default-color": "--dk-component-hero-disabled-color",
52
+ "--dk-component-eyebrow-disabled-default-color": "--dk-component-eyebrow-disabled-color",
53
+ "--dk-component-icon-disabled-default-color": "--dk-component-icon-disabled-color"
54
+ },
55
+
56
+ "removed": {
57
+ "note": "No replacement. If a design genuinely needs 1.8:1 text, it is not a disabled label and should say what it actually is.",
58
+ "--dk-component-body-disabled-subtle-color": null,
59
+ "--dk-component-heading-disabled-subtle-color": null,
60
+ "--dk-component-hero-disabled-subtle-color": null,
61
+ "--dk-component-eyebrow-disabled-subtle-color": null,
62
+ "--dk-component-icon-disabled-subtle-color": null
63
+ },
64
+
65
+ "unchanged": {
66
+ "note": "Called out because they look like they should have moved and did not.",
67
+ "--dk-text-disabled-subtle": "still the Mapped token every disabled control label reads",
68
+ "--dk-icon-disabled-subtle": "same, for icons inside disabled controls",
69
+ "data-emphasis=\"subtle\" with data-color=\"neutral\"": "unaffected — neutral's subtle rung is a real, legible de-emphasis"
70
+ }
71
+ }
72
+ ```
73
+
@@ -0,0 +1,67 @@
1
+ ## 6.0.0 — 2026-09-11
2
+
3
+ - **BREAKING: icon sizes are the pixel number, not a t-shirt.** Five rungs become
4
+ nine: 12, 14, 16, 20, 24, 28, 32, 40, 48. Every old name maps to the pixel value
5
+ it already resolved to, so nothing renders differently:
6
+ `extra-small`→`12`, `small`→`16`, `medium`→`20`, `large`→`24`,
7
+ `extra-large`→`32`. Map in `migrations/6.0.0-icon-numeric-sizes.json`.
8
+ - **Why numbers.** Figma has always called these 12 and 24, so every handoff
9
+ carried a translation step that existed only because the kit disagreed with the
10
+ design tool. Numbers also let a rung slot in without renaming its neighbours:
11
+ adding 14 between 12 and 16 meant inventing a name between extra-small and
12
+ small, and 40 and 48 meant extra-extra-large and worse.
13
+ - **Four genuinely new rungs**: 14 for dense chrome, 28 between 24 and 32, and 40
14
+ and 48 for display sizes the old scale could not reach. Every value is an
15
+ existing scale primitive; nothing new was invented.
16
+ - **The old names are removed, not aliased.** A `var()` to one now resolves to
17
+ nothing, which is the loud failure this kit prefers over a silent fallback to
18
+ some default size.
19
+ - **data-weight is unchanged at three rungs**, and that is a decision rather than
20
+ an omission. The stroke scales with the icon, so `bold` at 12px already renders
21
+ around 1.25px; splitting that into five or seven steps would be differences
22
+ nobody can see at the sizes icons are actually used, and every extra rung is
23
+ another cell in the token matrix.
24
+
25
+ ### Rename map: `migrations/6.0.0-icon-numeric-sizes.json`
26
+
27
+ ```json
28
+ {
29
+ "version": "6.0.0",
30
+ "date": "2026-09-11",
31
+ "note": "Icon sizes stop being t-shirts and become the pixel number. Five rungs become nine: 12, 14, 16, 20, 24, 28, 32, 40, 48. The four existing values keep their pixel sizes exactly, so this is a rename and not a resize, except that `medium` was 20px and anyone who assumed it meant 24 will now have to say which they meant.",
32
+
33
+ "why": "Figma has always called these 12 and 24, so every handoff carried a translation step that existed only because the kit disagreed with the design tool. Numbers also let a rung slot in without renaming its neighbours: adding 14 between 12 and 16 under the old scheme meant inventing a name between extra-small and small, and adding 40 and 48 meant extra-extra-large and worse. More sizes were asked for because five did not cover the range; nine do, and the scheme no longer fights the next addition.",
34
+
35
+ "attributes": {
36
+ "note": "Applies to any element with class dk-component-icon. The pixel value each old name resolved to is the new name, so rendering is unchanged.",
37
+ "data-size=\"extra-small\"": "data-size=\"12\"",
38
+ "data-size=\"small\"": "data-size=\"16\"",
39
+ "data-size=\"medium\"": "data-size=\"20\"",
40
+ "data-size=\"large\"": "data-size=\"24\"",
41
+ "data-size=\"extra-large\"": "data-size=\"32\""
42
+ },
43
+
44
+ "tokens": {
45
+ "note": "Same mapping at the token level. The five old names are REMOVED, not aliased: a var() to one resolves to nothing, which is the loud failure this kit prefers over a silent fallback to some default size.",
46
+ "--dk-component-icon-extra-small-size": "--dk-component-icon-12-size",
47
+ "--dk-component-icon-small-size": "--dk-component-icon-16-size",
48
+ "--dk-component-icon-medium-size": "--dk-component-icon-20-size",
49
+ "--dk-component-icon-large-size": "--dk-component-icon-24-size",
50
+ "--dk-component-icon-extra-large-size": "--dk-component-icon-32-size"
51
+ },
52
+
53
+ "added": {
54
+ "note": "Four new rungs with no predecessor. 14 for dense table chrome, 28 between 24 and 32, and 40 and 48 for the display sizes the old scale simply could not reach.",
55
+ "--dk-component-icon-14-size": "var(--dk-primitive-scale-3-5)",
56
+ "--dk-component-icon-28-size": "var(--dk-primitive-scale-7)",
57
+ "--dk-component-icon-40-size": "var(--dk-primitive-scale-10)",
58
+ "--dk-component-icon-48-size": "var(--dk-primitive-scale-12)"
59
+ },
60
+
61
+ "unchanged": {
62
+ "note": "data-weight stays at three rungs. The stroke scales with the icon, so bold at 12px already renders around 1.25px; splitting that further would be differences nobody can see at the sizes icons are actually used.",
63
+ "data-weight": ["light", "regular", "bold"]
64
+ }
65
+ }
66
+ ```
67
+
@@ -0,0 +1,71 @@
1
+ ## 7.0.0 — 2026-09-12
2
+
3
+ - **Shadows are one ramp, named for the job.** `raised` (a thing resting on the
4
+ page), `lifted` (the same thing picked up), `floating` (a layer above the
5
+ page), `overlay` (a layer above everything), `on-color` (any of those on a
6
+ coloured fill). A token called `card` was already doing the work for toasts,
7
+ menus and a search field, which is the tell that it was named for the wrong
8
+ thing. Light values are unchanged, so the rename alone repaints nothing.
9
+ - **Thirteen of the nineteen shadow tokens had never been used anywhere.** The
10
+ upstream `drop-*` and `inner-*` families are COLOURS, not shadows:
11
+ `color-mix` with no offset or blur, unusable without writing the geometry
12
+ yourself, and only one thing in the kit ever did. They still resolve, since
13
+ upstream owns the block above the fence and a refresh would restore them, but
14
+ they are no longer part of the system and the Shadows page no longer presents
15
+ them as shadows. Markup composing them by hand keeps working.
16
+ - **The modal had no shadow token at all.** It hardcoded
17
+ `0 4px 8px -2px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.06)`, which never
18
+ themed and was lighter than a card on hover, leaving the most elevated thing
19
+ in the system with the least considered elevation. It uses `overlay` now.
20
+ - **Dark is not light with more alpha.** Black falling on a dark surface has
21
+ almost no range, which is why the old dark values read as nothing. Alpha
22
+ roughly doubles again (raised 0.16 to 0.36, lifted 0.20 to 0.44), and the two
23
+ genuinely floating rungs gain a hairline of light along the top edge, which is
24
+ how a raised surface catches light in a dark room. The lower rungs skip it: a
25
+ tab is not floating, and a bright line across its top reads as a seam.
26
+ - **`--dk-shadow-focus-ring`** for the `0 0 0 4px` primary ring that card,
27
+ checkbox, switch and select each wrote out raw. Button keeps its own, whose
28
+ width and colour are already component tokens that vary by variant.
29
+ - Migration map in `migrations/7.0.0-shadow-roles.json`.
30
+
31
+ ### Rename map: `migrations/7.0.0-shadow-roles.json`
32
+
33
+ ```json
34
+ {
35
+ "version": "7.0.0",
36
+ "summary": "Shadows become one ramp named for the job. Light values are unchanged; dark is deeper, and the two floating rungs gain a hairline top edge.",
37
+ "rename": {
38
+ "--dk-shadow-card-faint": "--dk-shadow-raised",
39
+ "--dk-shadow-card-subtle": "--dk-shadow-lifted",
40
+ "--dk-shadow-card-default": "--dk-shadow-floating",
41
+ "--dk-shadow-card-on-color": "--dk-shadow-on-color",
42
+ "--dk-shadow-popover": "--dk-shadow-overlay"
43
+ },
44
+ "added": {
45
+ "--dk-shadow-focus-ring": "The 0 0 0 4px primary-300 ring that card, checkbox, switch and select each wrote out raw. Button keeps its own, whose width and colour are already component tokens."
46
+ },
47
+ "removedFromTheSystem": {
48
+ "note": "The upstream drop-* and inner-* families are colours, not shadows: color-mix with no offset or blur, unusable without writing the geometry yourself. Thirteen of the fourteen had never been used anywhere, and the one that was (drop-lg, in the select menu) now uses --dk-shadow-floating. They still resolve, because upstream owns the block above the fence in tokens/mapped/shadow.css and a refresh would restore them, but they are no longer part of the shadow system and the Shadows page no longer lists them. Markup that composes them by hand keeps working.",
49
+ "tokens": [
50
+ "--dk-shadow-drop-xs",
51
+ "--dk-shadow-drop-sm-1",
52
+ "--dk-shadow-drop-sm-2",
53
+ "--dk-shadow-drop-md-1",
54
+ "--dk-shadow-drop-md-2",
55
+ "--dk-shadow-drop-lg-1",
56
+ "--dk-shadow-drop-lg-2",
57
+ "--dk-shadow-drop-xl-1",
58
+ "--dk-shadow-drop-xl-2",
59
+ "--dk-shadow-drop-2xl",
60
+ "--dk-shadow-drop-3xl",
61
+ "--dk-shadow-inner-sm",
62
+ "--dk-shadow-inner-md",
63
+ "--dk-shadow-inner-lg"
64
+ ]
65
+ },
66
+ "alsoFixed": {
67
+ "modal": "dk-component-modal hardcoded 0 4px 8px -2px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.06): it never themed, and it was lighter than a card on hover. It now uses --dk-shadow-overlay."
68
+ }
69
+ }
70
+ ```
71
+