@refrakt-md/lumina 0.21.0 → 0.23.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 (131) hide show
  1. package/base.css +2 -1
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +7 -0
  4. package/dist/config.js.map +1 -1
  5. package/dist/tokens.d.ts +5 -3
  6. package/dist/tokens.d.ts.map +1 -1
  7. package/dist/tokens.js +44 -3
  8. package/dist/tokens.js.map +1 -1
  9. package/index.css +11 -1
  10. package/package.json +7 -5
  11. package/styles/base/attributes.css +6 -7
  12. package/styles/dimensions/checklist.css +7 -36
  13. package/styles/dimensions/cover.css +13 -95
  14. package/styles/dimensions/density.css +6 -3
  15. package/styles/dimensions/frame.css +7 -4
  16. package/styles/dimensions/media.css +14 -61
  17. package/styles/dimensions/metadata.css +30 -80
  18. package/styles/dimensions/sections.css +16 -30
  19. package/styles/dimensions/sequence.css +17 -82
  20. package/styles/dimensions/state.css +39 -56
  21. package/styles/dimensions/substrate.css +3 -0
  22. package/styles/dimensions/surfaces.css +73 -113
  23. package/styles/elements/blockquote.css +3 -2
  24. package/styles/elements/code.css +3 -0
  25. package/styles/elements/table.css +3 -0
  26. package/styles/global.css +24 -63
  27. package/styles/layouts/blog.css +34 -95
  28. package/styles/layouts/default.css +12 -86
  29. package/styles/layouts/docs.css +9 -159
  30. package/styles/layouts/mobile.css +3 -52
  31. package/styles/layouts/on-this-page.css +8 -7
  32. package/styles/layouts/plan.css +27 -158
  33. package/styles/layouts/search.css +17 -82
  34. package/styles/layouts/split.css +24 -169
  35. package/styles/layouts/theme-toggle.css +3 -29
  36. package/styles/layouts/version-switcher.css +9 -10
  37. package/styles/runes/accordion.css +25 -68
  38. package/styles/runes/aggregate.css +4 -13
  39. package/styles/runes/annotate.css +11 -40
  40. package/styles/runes/api.css +4 -1
  41. package/styles/runes/audio.css +12 -50
  42. package/styles/runes/badge.css +5 -2
  43. package/styles/runes/bar.css +3 -0
  44. package/styles/runes/bento.css +18 -161
  45. package/styles/runes/bg.css +3 -37
  46. package/styles/runes/blog.css +18 -20
  47. package/styles/runes/bond.css +6 -26
  48. package/styles/runes/breadcrumb.css +7 -15
  49. package/styles/runes/budget.css +23 -45
  50. package/styles/runes/bug.css +5 -2
  51. package/styles/runes/card.css +27 -95
  52. package/styles/runes/cast.css +10 -27
  53. package/styles/runes/changelog.css +13 -17
  54. package/styles/runes/character.css +6 -20
  55. package/styles/runes/chart.css +15 -57
  56. package/styles/runes/codegroup.css +18 -26
  57. package/styles/runes/collection.css +8 -85
  58. package/styles/runes/compare.css +8 -19
  59. package/styles/runes/comparison.css +29 -56
  60. package/styles/runes/conversation.css +9 -31
  61. package/styles/runes/cta.css +17 -40
  62. package/styles/runes/datatable.css +33 -48
  63. package/styles/runes/decision.css +5 -2
  64. package/styles/runes/design-context.css +5 -4
  65. package/styles/runes/details.css +9 -17
  66. package/styles/runes/diagram.css +8 -16
  67. package/styles/runes/diff.css +11 -94
  68. package/styles/runes/drawer.css +9 -113
  69. package/styles/runes/embed.css +5 -13
  70. package/styles/runes/event.css +5 -3
  71. package/styles/runes/expand.css +10 -45
  72. package/styles/runes/faction.css +6 -12
  73. package/styles/runes/feature.css +15 -43
  74. package/styles/runes/figure.css +7 -26
  75. package/styles/runes/file-ref.css +3 -18
  76. package/styles/runes/form.css +19 -48
  77. package/styles/runes/gallery.css +8 -140
  78. package/styles/runes/grid.css +4 -56
  79. package/styles/runes/hero.css +28 -140
  80. package/styles/runes/hint.css +23 -48
  81. package/styles/runes/howto.css +9 -31
  82. package/styles/runes/itinerary.css +15 -44
  83. package/styles/runes/juxtapose.css +17 -92
  84. package/styles/runes/lore.css +7 -14
  85. package/styles/runes/map.css +9 -42
  86. package/styles/runes/mediatext.css +4 -45
  87. package/styles/runes/milestone.css +15 -28
  88. package/styles/runes/mockup.css +10 -115
  89. package/styles/runes/nav.css +37 -212
  90. package/styles/runes/organization.css +6 -5
  91. package/styles/runes/page-section.css +3 -4
  92. package/styles/runes/pagination.css +10 -42
  93. package/styles/runes/palette.css +16 -35
  94. package/styles/runes/placeholder.css +16 -0
  95. package/styles/runes/plan-history.css +23 -43
  96. package/styles/runes/plan-progress.css +6 -7
  97. package/styles/runes/plan-ref.css +4 -1
  98. package/styles/runes/playlist.css +10 -44
  99. package/styles/runes/plot.css +9 -25
  100. package/styles/runes/preview.css +9 -34
  101. package/styles/runes/pricing.css +23 -41
  102. package/styles/runes/progress.css +8 -27
  103. package/styles/runes/pullquote.css +9 -31
  104. package/styles/runes/realm.css +6 -12
  105. package/styles/runes/recipe.css +12 -36
  106. package/styles/runes/relationships.css +5 -36
  107. package/styles/runes/reveal.css +17 -22
  108. package/styles/runes/sandbox.css +9 -39
  109. package/styles/runes/section.css +10 -24
  110. package/styles/runes/showcase.css +3 -20
  111. package/styles/runes/sidenote.css +5 -4
  112. package/styles/runes/snippet.css +3 -0
  113. package/styles/runes/spacing.css +14 -33
  114. package/styles/runes/spec.css +5 -2
  115. package/styles/runes/steps.css +14 -46
  116. package/styles/runes/storyboard.css +4 -19
  117. package/styles/runes/swatch.css +4 -7
  118. package/styles/runes/symbol.css +16 -14
  119. package/styles/runes/tabs.css +15 -18
  120. package/styles/runes/testimonial.css +12 -13
  121. package/styles/runes/textblock.css +6 -24
  122. package/styles/runes/timeline.css +10 -28
  123. package/styles/runes/tint.css +3 -0
  124. package/styles/runes/toc.css +9 -7
  125. package/styles/runes/track.css +12 -41
  126. package/styles/runes/typography.css +15 -27
  127. package/styles/runes/work.css +5 -2
  128. package/styles/runes/xref.css +3 -1
  129. package/tokens/base.css +56 -66
  130. package/tokens/dark.css +79 -80
  131. package/styles/dimensions/guest-posture.css +0 -27
package/base.css CHANGED
@@ -36,6 +36,7 @@
36
36
  @import './styles/dimensions/frame.css';
37
37
  @import './styles/dimensions/substrate.css';
38
38
  @import './styles/dimensions/cover.css';
39
- @import './styles/dimensions/guest-posture.css';
39
+ /* guest-posture is wholly structural → @refrakt-md/skeleton (loaded by the theme
40
+ * loader before base.css), so it has no skin remainder to import here (WORK-438). */
40
41
  @import './styles/dimensions/checklist.css';
41
42
  @import './styles/dimensions/sequence.css';
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,gFAAgF;AAChF,eAAO,MAAM,YAAY,6CAoFvB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,gFAAgF;AAChF,eAAO,MAAM,YAAY,6CA2FvB,CAAC"}
package/dist/config.js CHANGED
@@ -84,6 +84,13 @@ export const luminaConfig = mergeThemeConfig(baseConfig, {
84
84
  caution: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>',
85
85
  check: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>',
86
86
  },
87
+ // SPEC-094 §8 / WORK-437 (icon-from-config) — the accordion disclosure
88
+ // chevron lives in the icon registry, not embedded in accordion.css; the
89
+ // skeleton's `::before` reads the generated `--rf-icon-accordion-chevron`
90
+ // mask custom property, so a theme re-glyphs it without touching CSS.
91
+ accordion: {
92
+ chevron: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>',
93
+ },
87
94
  global: lucideIcons,
88
95
  },
89
96
  });
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,YAAY,CAAC;AAElD,gFAAgF;AAChF,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC,UAAU,EAAE;IACxD,KAAK,EAAE;QACN,IAAI,EAAE;YACL,KAAK,EAAE;gBACN,EAAE,EAAE,oBAAoB;gBACxB,OAAO,EAAE,yBAAyB;gBAClC,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;YACD,IAAI,EAAE;gBACL,EAAE,EAAE,oBAAoB;gBACxB,OAAO,EAAE,yBAAyB;gBAClC,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;SACD;QACD,MAAM,EAAE;YACP,KAAK,EAAE;gBACN,EAAE,EAAE,yBAAyB;gBAC7B,OAAO,EAAE,+BAA+B;gBACxC,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;YACD,IAAI,EAAE;gBACL,EAAE,EAAE,yBAAyB;gBAC7B,OAAO,EAAE,+BAA+B;gBACxC,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;SACD;QACD,IAAI,EAAE;YACL,KAAK,EAAE;gBACN,EAAE,EAAE,gCAAgC;gBACpC,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;YACD,IAAI,EAAE;gBACL,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,SAAS;aACjB;SACD;QACD,IAAI,EAAE;YACL,KAAK,EAAE;gBACN,EAAE,EAAE,yBAAyB;gBAC7B,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,6BAA6B;aACrC;YACD,IAAI,EAAE;gBACL,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,SAAS;aACjB;SACD;QACD,IAAI,EAAE;YACL,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE;gBACL,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,wBAAwB;aACjC;SACD;KACD;IACD,KAAK,EAAE;QACN,IAAI,EAAE;YACL,IAAI,EAAE,4SAA4S;YAClT,OAAO,EAAE,iXAAiX;YAC1X,OAAO,EAAE,uSAAuS;YAChT,KAAK,EAAE,qRAAqR;SAC5R;QACD,MAAM,EAAE,WAAW;KACnB;CACD,CAAC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,YAAY,CAAC;AAElD,gFAAgF;AAChF,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC,UAAU,EAAE;IACxD,KAAK,EAAE;QACN,IAAI,EAAE;YACL,KAAK,EAAE;gBACN,EAAE,EAAE,oBAAoB;gBACxB,OAAO,EAAE,yBAAyB;gBAClC,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;YACD,IAAI,EAAE;gBACL,EAAE,EAAE,oBAAoB;gBACxB,OAAO,EAAE,yBAAyB;gBAClC,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;SACD;QACD,MAAM,EAAE;YACP,KAAK,EAAE;gBACN,EAAE,EAAE,yBAAyB;gBAC7B,OAAO,EAAE,+BAA+B;gBACxC,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;YACD,IAAI,EAAE;gBACL,EAAE,EAAE,yBAAyB;gBAC7B,OAAO,EAAE,+BAA+B;gBACxC,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;SACD;QACD,IAAI,EAAE;YACL,KAAK,EAAE;gBACN,EAAE,EAAE,gCAAgC;gBACpC,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,wBAAwB;aAChC;YACD,IAAI,EAAE;gBACL,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,SAAS;aACjB;SACD;QACD,IAAI,EAAE;YACL,KAAK,EAAE;gBACN,EAAE,EAAE,yBAAyB;gBAC7B,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,6BAA6B;aACrC;YACD,IAAI,EAAE;gBACL,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,yBAAyB;gBAClC,MAAM,EAAE,SAAS;aACjB;SACD;QACD,IAAI,EAAE;YACL,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE;gBACL,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,wBAAwB;aACjC;SACD;KACD;IACD,KAAK,EAAE;QACN,IAAI,EAAE;YACL,IAAI,EAAE,4SAA4S;YAClT,OAAO,EAAE,iXAAiX;YAC1X,OAAO,EAAE,uSAAuS;YAChT,KAAK,EAAE,qRAAqR;SAC5R;QACD,uEAAuE;QACvE,yEAAyE;QACzE,0EAA0E;QAC1E,sEAAsE;QACtE,SAAS,EAAE;YACV,OAAO,EAAE,2MAA2M;SACpN;QACD,MAAM,EAAE,WAAW;KACnB;CACD,CAAC,CAAC"}
package/dist/tokens.d.ts CHANGED
@@ -5,9 +5,11 @@ import type { ThemeTokensConfig } from '@refrakt-md/types';
5
5
  * "quiet spectrum walk" syntax palette (teal / violet / rust / ochre /
6
6
  * sage), and the four muted-earthy status colours.
7
7
  *
8
- * This is the *source of truth* for Lumina's runtime CSS values; the
9
- * hand-authored `tokens/base.css` and `tokens/dark.css` mirror it
10
- * verbatim and a coverage test keeps the two in lockstep.
8
+ * This is the *source of truth* for Lumina's runtime CSS values. The
9
+ * `tokens/base.css` and `tokens/dark.css` files are **generated** from this
10
+ * export by `scripts/generate-tokens.mjs` (run as part of the package build via
11
+ * `generateThemeStylesheet`); a drift test (`test/token-generation.test.ts`)
12
+ * fails CI if the committed CSS diverges. Edit this file, never the CSS.
11
13
  *
12
14
  * Sites that want the previous cream-and-navy appearance opt into the
13
15
  * `tideline` preset shipping alongside this default (see
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY,EAAE,iBAyL1B,CAAC"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY,EAAE,iBAoO1B,CAAC"}
package/dist/tokens.js CHANGED
@@ -4,9 +4,11 @@
4
4
  * "quiet spectrum walk" syntax palette (teal / violet / rust / ochre /
5
5
  * sage), and the four muted-earthy status colours.
6
6
  *
7
- * This is the *source of truth* for Lumina's runtime CSS values; the
8
- * hand-authored `tokens/base.css` and `tokens/dark.css` mirror it
9
- * verbatim and a coverage test keeps the two in lockstep.
7
+ * This is the *source of truth* for Lumina's runtime CSS values. The
8
+ * `tokens/base.css` and `tokens/dark.css` files are **generated** from this
9
+ * export by `scripts/generate-tokens.mjs` (run as part of the package build via
10
+ * `generateThemeStylesheet`); a drift test (`test/token-generation.test.ts`)
11
+ * fails CI if the committed CSS diverges. Edit this file, never the CSS.
10
12
  *
11
13
  * Sites that want the previous cream-and-navy appearance opt into the
12
14
  * `tideline` preset shipping alongside this default (see
@@ -19,6 +21,43 @@ export const luminaTokens = {
19
21
  font: {
20
22
  sans: "'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
21
23
  mono: "'JetBrains Mono', 'Fira Code', ui-monospace, 'Cascadia Code', monospace",
24
+ // Lumina is a unified-neutral theme: its headings use the same sans as
25
+ // body. The slot exists so an editorial theme can swap in a serif/display
26
+ // family without touching rune CSS.
27
+ display: "'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
28
+ },
29
+ // SPEC-094 — typographic scale. A roughly-1.2 modular scale anchored at a
30
+ // 1rem body. Nothing consumes these yet (WORK-405 migrates Lumina's
31
+ // hardcoded sizes onto them); values match Lumina's current type feel.
32
+ text: {
33
+ xs: '0.75rem',
34
+ sm: '0.875rem',
35
+ base: '1rem',
36
+ lg: '1.125rem',
37
+ xl: '1.25rem',
38
+ '2xl': '1.5rem',
39
+ '3xl': '1.875rem',
40
+ '4xl': '2.5rem',
41
+ },
42
+ weight: {
43
+ light: '300',
44
+ normal: '400',
45
+ medium: '500',
46
+ semibold: '600',
47
+ bold: '700',
48
+ },
49
+ leading: {
50
+ tight: '1.2',
51
+ snug: '1.35',
52
+ normal: '1.5',
53
+ relaxed: '1.65',
54
+ loose: '2',
55
+ },
56
+ tracking: {
57
+ tight: '-0.01em',
58
+ normal: '0',
59
+ wide: '0.03em',
60
+ wider: '0.06em',
22
61
  },
23
62
  color: {
24
63
  text: '#1c1a17',
@@ -75,6 +114,8 @@ export const luminaTokens = {
75
114
  spacing: {
76
115
  xs: '0.25rem',
77
116
  sm: '0.5rem',
117
+ snug: '0.75rem',
118
+ cozy: '1rem',
78
119
  md: '1.5rem',
79
120
  lg: '2rem',
80
121
  xl: '3rem',
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
package/index.css CHANGED
@@ -1,5 +1,12 @@
1
1
  /* Lumina Theme Identity — CSS Barrel */
2
2
 
3
+ /* Cascade-layer contract — must load first so the `@layer skeleton, skin;` order
4
+ * declaration is emitted before any layer content (SPEC-094 §3 / WORK-436).
5
+ * Lumina's own CSS below is currently unlayered, which keeps it winning over the
6
+ * (empty) skeleton layer — the per-file `@layer skin` re-bucketing lands in
7
+ * WORK-438. */
8
+ @import '@refrakt-md/skeleton';
9
+
3
10
  /* Design Tokens */
4
11
  @import './tokens/base.css';
5
12
  @import './tokens/dark.css';
@@ -37,7 +44,9 @@
37
44
  @import './styles/dimensions/frame.css';
38
45
  @import './styles/dimensions/substrate.css';
39
46
  @import './styles/dimensions/cover.css';
40
- @import './styles/dimensions/guest-posture.css';
47
+ /* guest-posture is wholly structural (pointer-events + a tab-strip display reset)
48
+ * → @refrakt-md/skeleton (dimensions/guest-posture.css), promoted with the
49
+ * tabs/codegroup structure it depends on (WORK-438). */
41
50
  @import './styles/dimensions/checklist.css';
42
51
  @import './styles/dimensions/sequence.css';
43
52
 
@@ -80,6 +89,7 @@
80
89
  @import './styles/runes/faction.css';
81
90
  @import './styles/runes/feature.css';
82
91
  @import './styles/runes/figure.css';
92
+ @import './styles/runes/placeholder.css';
83
93
  @import './styles/runes/gallery.css';
84
94
  @import './styles/runes/form.css';
85
95
  @import './styles/runes/grid.css';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@refrakt-md/lumina",
3
3
  "description": "Lumina theme for refrakt.md — design tokens, CSS, identity transform, and layout configs",
4
- "version": "0.21.0",
4
+ "version": "0.23.0",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -80,12 +80,14 @@
80
80
  "assets"
81
81
  ],
82
82
  "scripts": {
83
- "build": "tsc"
83
+ "build": "tsc && node scripts/generate-tokens.mjs",
84
+ "generate-tokens": "node scripts/generate-tokens.mjs"
84
85
  },
85
86
  "dependencies": {
86
- "@refrakt-md/runes": "0.21.0",
87
- "@refrakt-md/transform": "0.21.0",
88
- "@refrakt-md/types": "0.21.0"
87
+ "@refrakt-md/runes": "0.23.0",
88
+ "@refrakt-md/skeleton": "0.23.0",
89
+ "@refrakt-md/transform": "0.23.0",
90
+ "@refrakt-md/types": "0.23.0"
89
91
  },
90
92
  "devDependencies": {
91
93
  "postcss": "^8.4.0"
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Universal Rune Attributes — spacing & inset
2
3
  *
3
4
  * Compound attribute selectors [data-rune][data-*] give specificity (0,2,0):
@@ -19,11 +20,9 @@
19
20
  [data-rune][data-inset="loose"] { padding-inline: var(--rf-inset-loose, 4rem); }
20
21
  [data-rune][data-inset="breathe"] { padding-inline: var(--rf-inset-breathe, 8rem); }
21
22
 
22
- /* ── Elevationdrop shadow (box-shadow) ──────────────────────────────
23
- * Universal `elevation` attribute (SPEC-086). Maps to the shared --rf-shadow-*
24
- * token scale; `none` explicitly flattens a rune's default shadow. */
23
+ /* The `elevation` axis (SPEC-107) depth-ladder chrome (fill / border / radius
24
+ * / resting shadow) is mapped by value in dimensions/surfaces.css. The old
25
+ * SPEC-086 shadow scale (none/sm/md/lg) is superseded; the engine maps those
26
+ * deprecated aliases onto the ladder before they reach the DOM. */
25
27
 
26
- [data-rune][data-elevation="none"] { box-shadow: var(--rf-shadow-none); }
27
- [data-rune][data-elevation="sm"] { box-shadow: var(--rf-shadow-sm); }
28
- [data-rune][data-elevation="md"] { box-shadow: var(--rf-shadow-md); }
29
- [data-rune][data-elevation="lg"] { box-shadow: var(--rf-shadow-lg); }
28
+ }
@@ -1,21 +1,11 @@
1
- /* === Checklist: universal checkbox item styling === */
1
+ @layer skin {
2
+ /* === Checklist — skin ===
3
+ * The indicator chrome (fill, border, radius, box-shadow) and the item text
4
+ * treatment per state. The indicator gutter + box placement/size live in
5
+ * @refrakt-md/skeleton (dimensions/checklist.css). */
2
6
 
3
- /* All checklist items get left padding for the indicator */
4
- [data-checked] {
5
- position: relative;
6
- padding-left: 1.75rem;
7
- list-style: none;
8
- margin-left: -1.5rem;
9
- }
10
-
11
- /* Indicator base — positioned left of text */
7
+ /* Indicator base chrome. */
12
8
  [data-checked]::before {
13
- content: '';
14
- position: absolute;
15
- left: 0.125rem;
16
- top: 0.5em;
17
- width: 1rem;
18
- height: 1rem;
19
9
  border-radius: var(--rf-radius-sm, 0.25rem);
20
10
  border: 2px solid var(--rf-color-border);
21
11
  background: transparent;
@@ -40,7 +30,7 @@
40
30
 
41
31
  [data-checked="active"] {
42
32
  color: var(--rf-color-primary);
43
- font-weight: 600;
33
+ font-weight: var(--rf-weight-semibold);
44
34
  }
45
35
 
46
36
  /* Skipped — muted with strikethrough */
@@ -59,23 +49,4 @@
59
49
  background: transparent;
60
50
  }
61
51
 
62
- /* === Density interaction === */
63
-
64
- /* Compact: tighter spacing */
65
- [data-density="compact"] [data-checked] {
66
- padding-left: 1.5rem;
67
- }
68
-
69
- [data-density="compact"] [data-checked]::before {
70
- width: 0.75rem;
71
- height: 0.75rem;
72
- }
73
-
74
- /* Minimal: indicators only, no text */
75
- [data-density="minimal"] [data-checked] {
76
- font-size: 0;
77
- padding-left: 0;
78
- display: inline-block;
79
- width: 1rem;
80
- height: 1rem;
81
52
  }
@@ -1,116 +1,32 @@
1
- /* Cover layout (SPEC-089) — `media-position="cover"`.
1
+ @layer skin {
2
+ /* Cover layout (SPEC-089) — skin.
2
3
  *
3
- * The media well fills the rune interior and the content overlays it (the poster
4
- * / cover card). The media stays a media guest — the thin-edge frame and
5
- * `--rf-radius-media` are preserved with content floated on top via grid
6
- * stacking (media + content share one grid cell). No overlay primitive in the
7
- * layout config; the variant supplies the structure (SPEC-091), CSS positions.
8
- *
9
- * Height authority: an external grid track (bento) wins; else the media aspect
10
- * (`frame-aspect`, default portrait); a card height/aspect knob overrides via the
11
- * cascade. Cover supersedes the media-vs-content split knobs (content-height /
12
- * media-ratio), which have no meaning when there is no split. */
4
+ * The grid-overlay *structure* (media well + content share one grid cell, the
5
+ * well fills/crops its guest, the overlay positions via content-place) lives in
6
+ * @refrakt-md/skeleton (dimensions/cover.css). What remains here is skin: the
7
+ * media radii, the overlay's surface padding, and the legibility scrim
8
+ * (gradient / frost) painted over the media. */
13
9
 
14
- /* ── full scope — the whole content overlays the media well ──────────── */
15
- [data-media-position="cover"]:not([data-cover-scope="header"]) {
16
- display: grid;
17
- grid-template: minmax(0, 1fr) / minmax(0, 1fr);
18
- aspect-ratio: var(--frame-aspect, var(--cover-aspect, 3 / 4));
19
- container-type: size;
20
- overflow: hidden;
21
- isolation: isolate;
22
- }
23
- [data-media-position="cover"]:not([data-cover-scope="header"]) > [data-section="media"],
24
- [data-media-position="cover"]:not([data-cover-scope="header"]) > [data-name="content"] {
25
- grid-area: 1 / 1;
26
- margin: 0;
27
- min-width: 0;
28
- }
29
-
30
- /* ── header scope — only the cover-band overlays; body flows below ────── */
31
10
  [data-cover-scope="header"] > [data-name="cover-band"] {
32
- display: grid;
33
- grid-template: minmax(0, 1fr) / minmax(0, 1fr);
34
- aspect-ratio: var(--frame-aspect, 16 / 9);
35
11
  border-radius: var(--rf-radius-media);
36
- overflow: hidden;
37
- isolation: isolate;
38
- container-type: size;
39
- }
40
- /* On narrow screens a 16/9 band is too short to seat the preamble over the
41
- * scrim, so default it to a taller (≥1:1) poster shape. An explicit
42
- * `frame-aspect` still wins. */
43
- @media (max-width: 40rem) {
44
- [data-cover-scope="header"] > [data-name="cover-band"] {
45
- aspect-ratio: var(--frame-aspect, 4 / 5);
46
- }
47
- }
48
- [data-cover-scope="header"] > [data-name="cover-band"] > [data-section="media"],
49
- [data-cover-scope="header"] > [data-name="cover-band"] > [data-name="preamble"] {
50
- grid-area: 1 / 1;
51
- margin: 0;
52
12
  }
53
13
 
54
- /* ── shared: the media well fills, the overlaid box positions ─────────── */
55
14
  [data-media-position="cover"] [data-section="media"] {
56
- position: relative;
57
- height: 100%;
58
15
  border-radius: var(--rf-radius-media);
59
- overflow: hidden;
60
- }
61
- [data-media-position="cover"] [data-section="media"] > :is(img, video) {
62
- width: 100%;
63
- height: 100%;
64
- object-fit: cover;
65
- }
66
- /* SPEC-101 — non-img/video guests (a sandbox, an embed) fill the well too.
67
- * They can't be object-fit-cropped, so they get the well's box outright;
68
- * display:block covers undefined custom elements (inline by default). */
69
- [data-media-position="cover"] [data-section="media"] > :not(img, video) {
70
- display: block;
71
- width: 100%;
72
- height: 100%;
73
16
  }
17
+
74
18
  /* A backdrop sandbox sits flush in the well — the well's own radius/overflow
75
- * does the clipping. The iframe height is pinned inline by the element in
76
- * `fill` mode; this carries the fixed-height case visually until then. */
19
+ * does the clipping. */
77
20
  [data-media-position="cover"] [data-section="media"] .rf-sandbox {
78
- margin: 0;
79
21
  border-radius: 0;
80
22
  }
81
- [data-media-position="cover"] [data-section="media"] .rf-sandbox iframe {
82
- height: 100%;
83
- }
84
- /* The overlaid box (full: content; header: preamble) anchors via content-place. */
23
+
24
+ /* The overlaid box carries the surface padding (density-aware via --rune-padding). */
85
25
  [data-media-position="cover"]:not([data-cover-scope="header"]) > [data-name="content"],
86
26
  [data-cover-scope="header"] > [data-name="cover-band"] > [data-name="preamble"] {
87
- position: relative;
88
- z-index: 1;
89
- align-self: var(--cover-place-block, end);
90
- justify-self: var(--cover-place-inline, stretch);
91
27
  padding: var(--rune-padding, var(--rf-spacing-md));
92
28
  }
93
29
 
94
- /* ── auto / unset placement ───────────────────────────────────────────
95
- * `auto` is the cover default, so an unset content-place behaves the same as an
96
- * explicit `auto`. A header band is always a caption strip — the preamble sits at
97
- * the block-end over the scrim regardless of the band's orientation. A full-scope
98
- * overlay adapts to the cover region's orientation (portrait → block-end caption;
99
- * landscape → inline-start side panel). An explicit value (e.g. "center center")
100
- * sets the `--cover-place-*` vars on the base rule above and does NOT match here,
101
- * so it pins regardless of orientation. */
102
- [data-media-position="cover"]:not([data-cover-scope="header"]):is([data-content-place="auto"], :not([data-content-place])) > [data-name="content"],
103
- [data-cover-scope="header"]:is([data-content-place="auto"], :not([data-content-place])) > [data-name="cover-band"] > [data-name="preamble"] {
104
- align-self: end;
105
- justify-self: stretch;
106
- }
107
- @container (min-aspect-ratio: 1 / 1) {
108
- [data-media-position="cover"]:not([data-cover-scope="header"]):is([data-content-place="auto"], :not([data-content-place])) > [data-name="content"] {
109
- align-self: center;
110
- justify-self: start;
111
- }
112
- }
113
-
114
30
  /* ── default cover scrim (SPEC-088 scrim, on the media surface) ────────
115
31
  * Overlaying text on an arbitrary image without a scrim is a legibility footgun,
116
32
  * so cover applies a default gradient scrim weighted toward the content edge.
@@ -169,3 +85,5 @@
169
85
  * reads at full foreground strength — the same colour as the headline. */
170
86
  --rf-color-muted: var(--rf-color-text);
171
87
  }
88
+
89
+ }
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* ─── Density Dimension ─────────────────────────────────────────────────
2
3
  * Controls spacing, visibility, and detail level across all runes.
3
4
  * Three levels: full (dedicated page), compact (grid/card), minimal (list).
@@ -9,14 +10,14 @@
9
10
 
10
11
  [data-density="full"] {
11
12
  --rune-padding: var(--rf-spacing-md);
12
- --rf-title-size: 1.5rem;
13
+ --rf-title-size: var(--rf-text-2xl);
13
14
  }
14
15
 
15
16
  /* ─── Compact: truncated descriptions, tight spacing ──────────────── */
16
17
 
17
18
  [data-density="compact"] {
18
19
  --rune-padding: var(--rf-spacing-sm);
19
- --rf-title-size: 1.25rem;
20
+ --rf-title-size: var(--rf-text-xl);
20
21
  }
21
22
 
22
23
  [data-density="compact"] [data-section="description"] {
@@ -34,7 +35,7 @@
34
35
 
35
36
  [data-density="minimal"] {
36
37
  --rune-padding: var(--rf-spacing-xs);
37
- --rf-title-size: 1rem;
38
+ --rf-title-size: var(--rf-text);
38
39
  }
39
40
 
40
41
  [data-density="minimal"] [data-section="description"] {
@@ -74,3 +75,5 @@
74
75
  [data-density="minimal"] [data-density="full"] [data-meta-rank="secondary"] {
75
76
  display: revert;
76
77
  }
78
+
79
+ }
@@ -1,3 +1,4 @@
1
+ @layer skin {
1
2
  /* Frame chrome (SPEC-086) — media-surface presentation.
2
3
  *
3
4
  * The engine lands the frame contract on the frame-target element: a rune's
@@ -42,7 +43,7 @@
42
43
  * guest so a displaced image's shadow falls into the slot's exposed
43
44
  * interior (clipped at the slot's `overflow: hidden` boundary like any
44
45
  * other in-slot content). */
45
- [data-section="media"][data-frame-shadow] > :is(img, video, [data-rune]) {
46
+ [data-section="media"][data-frame-shadow] > :is(img, video, .rf-placeholder, [data-rune]) {
46
47
  filter: var(--frame-shadow);
47
48
  }
48
49
 
@@ -50,7 +51,7 @@
50
51
  [style*="--frame-aspect"] { aspect-ratio: var(--frame-aspect); }
51
52
 
52
53
  /* ── Crop anchor — focal point when the guest is cut ─────────────────── */
53
- [style*="--frame-anchor"] > :is(img, video) { object-position: var(--frame-anchor); }
54
+ [style*="--frame-anchor"] > :is(img, video, .rf-placeholder) { object-position: var(--frame-anchor); }
54
55
 
55
56
  /* ── Placement of the framed box within its slot ─────────────────────── */
56
57
  [style*="--frame-place-x"] { justify-self: var(--frame-place-x, auto); align-self: var(--frame-place-y, auto); }
@@ -59,7 +60,7 @@
59
60
  /* `[data-rune]` extends the rule to nested rune guests (codegroup, mockup,
60
61
  * chart, etc.), so frame chrome stays guest-agnostic — the same selector
61
62
  * pattern the displace rule uses. */
62
- [style*="--frame-oversize"] > :is(img, video, [data-rune]) { width: calc(100% * var(--frame-oversize, 1)); max-width: none; }
63
+ [style*="--frame-oversize"] > :is(img, video, .rf-placeholder, [data-rune]) { width: calc(100% * var(--frame-oversize, 1)); max-width: none; }
63
64
 
64
65
  /* ── Displacement (peek / spill) — move the guest toward an edge/corner.
65
66
  * The host decides whether the guest is cropped or spills; this only moves it.
@@ -80,7 +81,7 @@
80
81
  * parent's edge for a true breakout. */
81
82
 
82
83
  /* — Case 1: media-zone displace → translate the inner guest, zone clips. */
83
- [data-section="media"][data-displace] > :is(img, video, [data-rune]) {
84
+ [data-section="media"][data-displace] > :is(img, video, .rf-placeholder, [data-rune]) {
84
85
  transform: translate(var(--displace-x, 0), var(--displace-y, 0));
85
86
  }
86
87
  [data-section="media"][data-displace="top"] { --displace-y: calc(-1 * var(--frame-offset, var(--rf-spacing-lg))); }
@@ -102,3 +103,5 @@
102
103
  * clipped by the zone's `overflow: hidden` regardless of width, so the peek
103
104
  * reads consistently from desktop to mobile. For self-target (showcase) the
104
105
  * negative-margin spill stays on too — that's the intended breakout. */
106
+
107
+ }
@@ -1,62 +1,15 @@
1
- /* ─── Media Slots Dimension ─────────────────────────────────────────────
2
- * Generic treatment for 5 media slot types: portrait, cover, thumbnail,
3
- * hero, icon. Applied via data-media attribute on image/media elements.
4
- *
5
- * Includes density × media interactions (compact shrinks, minimal hides).
6
- * ────────────────────────────────────────────────────────────────────── */
7
-
8
- /* ─── Portrait: circular crop ─────────────────────────────────────── */
9
-
10
- [data-media="portrait"] {
11
- border-radius: var(--rf-radius-full);
12
- aspect-ratio: 1 / 1;
13
- object-fit: cover;
14
- width: var(--media-portrait-size, 5rem);
15
- height: var(--media-portrait-size, 5rem);
16
- }
17
-
18
- /* ─── Cover: full-width banner image ──────────────────────────────── */
19
-
20
- [data-media="cover"] {
21
- width: 100%;
22
- object-fit: cover;
23
- border-radius: var(--rf-radius-md);
24
- }
25
-
26
- /* ─── Thumbnail: small fixed preview ──────────────────────────────── */
27
-
28
- [data-media="thumbnail"] {
29
- width: var(--media-thumbnail-size, 3rem);
30
- height: var(--media-thumbnail-size, 3rem);
31
- border-radius: var(--rf-radius-sm);
32
- object-fit: cover;
33
- flex-shrink: 0;
34
- }
35
-
36
- /* ─── Hero: large responsive image ────────────────────────────────── */
37
-
38
- [data-media="hero"] {
39
- width: 100%;
40
- object-fit: cover;
41
- }
42
-
43
- /* ─── Icon: small square, no crop ─────────────────────────────────── */
44
-
45
- [data-media="icon"] {
46
- width: var(--media-icon-size, 2rem);
47
- height: var(--media-icon-size, 2rem);
48
- object-fit: contain;
49
- flex-shrink: 0;
50
- }
51
-
52
- /* ─── Density × Media ─────────────────────────────────────────────── */
53
-
54
- /* Compact: smaller portraits */
55
- [data-density="compact"] [data-media="portrait"] {
56
- --media-portrait-size: 3rem;
57
- }
58
-
59
- /* Minimal: hide all media */
60
- [data-density="minimal"] [data-media] {
61
- display: none;
1
+ /* ─── Media Slots Dimension — skin ──────────────────────────────────────
2
+ * The rounded corners of each slot type. Slot sizing/fit (the geometry) is
3
+ * structure and lives in `@refrakt-md/skeleton` (styles/dimensions/media.css). */
4
+
5
+ @layer skin {
6
+ [data-media="portrait"] {
7
+ border-radius: var(--rf-radius-full);
8
+ }
9
+ [data-media="cover"] {
10
+ border-radius: var(--rf-radius-md);
11
+ }
12
+ [data-media="thumbnail"] {
13
+ border-radius: var(--rf-radius-sm);
14
+ }
62
15
  }