@refrakt-md/lumina 0.16.0 → 0.17.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.
@@ -7,13 +7,18 @@
7
7
  }
8
8
  .rf-hint__header {
9
9
  margin-bottom: 0.375rem;
10
+ color: var(--hint-color);
10
11
  }
11
- .rf-hint__icon {
12
- display: flex;
12
+ /* The lone `hintType` field renders icon + label in one inline-flex span. */
13
+ .rf-hint__header > span {
14
+ display: inline-flex;
13
15
  align-items: center;
14
- color: var(--hint-color);
16
+ gap: 0.375rem;
15
17
  }
16
- .rf-hint__icon::before {
18
+ .rf-hint__header [data-icon-group="hint"] {
19
+ display: block;
20
+ }
21
+ .rf-hint__header [data-icon-group="hint"]::before {
17
22
  content: '';
18
23
  display: block;
19
24
  width: 1.25rem;
@@ -24,28 +29,27 @@
24
29
  -webkit-mask-repeat: no-repeat;
25
30
  mask-repeat: no-repeat;
26
31
  }
27
- .rf-hint--note .rf-hint__icon::before {
32
+ [data-icon-group="hint"][data-icon="note"]::before {
28
33
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='16' x2='12' y2='12'/%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'/%3E%3C/svg%3E");
29
34
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='16' x2='12' y2='12'/%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'/%3E%3C/svg%3E");
30
35
  }
31
- .rf-hint--warning .rf-hint__icon::before {
36
+ [data-icon-group="hint"][data-icon="warning"]::before {
32
37
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/%3E%3Cline x1='12' y1='9' x2='12' y2='13'/%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'/%3E%3C/svg%3E");
33
38
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/%3E%3Cline x1='12' y1='9' x2='12' y2='13'/%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'/%3E%3C/svg%3E");
34
39
  }
35
- .rf-hint--caution .rf-hint__icon::before {
40
+ [data-icon-group="hint"][data-icon="caution"]::before {
36
41
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='15' y1='9' x2='9' y2='15'/%3E%3Cline x1='9' y1='9' x2='15' y2='15'/%3E%3C/svg%3E");
37
42
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='15' y1='9' x2='9' y2='15'/%3E%3Cline x1='9' y1='9' x2='15' y2='15'/%3E%3C/svg%3E");
38
43
  }
39
- .rf-hint--check .rf-hint__icon::before {
44
+ [data-icon-group="hint"][data-icon="check"]::before {
40
45
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 11.08V12a10 10 0 1 1-5.93-9.14'/%3E%3Cpolyline points='22 4 12 14.01 9 11.01'/%3E%3C/svg%3E");
41
46
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 11.08V12a10 10 0 1 1-5.93-9.14'/%3E%3Cpolyline points='22 4 12 14.01 9 11.01'/%3E%3C/svg%3E");
42
47
  }
43
- .rf-hint__title {
48
+ .rf-hint__header [data-meta-value] {
44
49
  font-weight: 600;
45
50
  text-transform: capitalize;
46
51
  font-size: 0.8rem;
47
52
  letter-spacing: 0.03em;
48
- color: var(--hint-color);
49
53
  }
50
54
  .rf-hint__body {
51
55
  font-size: 0.925rem;
@@ -1,10 +1,5 @@
1
1
  /* HowTo — matches recipe design */
2
2
 
3
- /* Meta bar — extra bottom spacing beyond section header default */
4
- .rf-howto__meta {
5
- margin-bottom: 1.5rem;
6
- }
7
-
8
3
  /* Tools/materials list — surfaced zone with primary markers */
9
4
  .rf-howto__content ul {
10
5
  background: var(--rf-color-surface);
@@ -76,3 +71,23 @@
76
71
  .rf-howto__content blockquote p {
77
72
  margin: 0;
78
73
  }
74
+
75
+ /* Metadata — est. time / difficulty are short, symmetric facts, so keep the
76
+ * def-list a dense tile grid at every width (a smaller column min than the
77
+ * 8rem default) instead of the shared mobile label/value list. */
78
+ .rf-howto__metadata {
79
+ grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
80
+ }
81
+ @media (max-width: 48rem) {
82
+ .rf-howto__metadata {
83
+ grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
84
+ gap: 0.75rem;
85
+ align-items: normal;
86
+ padding: 0;
87
+ border: none;
88
+ }
89
+ .rf-howto__metadata > [data-name="row"] {
90
+ display: flex;
91
+ }
92
+ }
93
+
@@ -1,13 +1,9 @@
1
1
  /* Milestone */
2
2
 
3
- /* Primary badges: name left, status right */
4
- .rf-milestone__header-primary {
5
- justify-content: space-between;
6
- margin-bottom: 0.75rem;
7
- }
3
+ /* SPEC-079: eyebrow + metadata zone names replace header-primary /
4
+ * header-secondary. */
8
5
 
9
- /* Preamble: title + optional description between badge groups */
10
- .rf-milestone__preamble {
6
+ .rf-milestone__eyebrow {
11
7
  margin-bottom: 0.75rem;
12
8
  }
13
9
  .rf-milestone__title h1,
@@ -16,14 +12,9 @@
16
12
  margin-top: 0;
17
13
  }
18
14
 
19
- /* Secondary badges: pill row below preamble */
20
- .rf-milestone__header-secondary {
15
+ .rf-milestone__metadata {
21
16
  margin-bottom: 1.5rem;
22
17
  }
23
-
24
- .rf-milestone__target-badge {
25
- margin-left: auto;
26
- }
27
18
  .rf-milestone__body {
28
19
  font-size: 0.925rem;
29
20
  line-height: 1.65;
@@ -1,5 +1,11 @@
1
- /* Realm */
2
- .rf-realm {
1
+ /* Realm — split/stacked geometry, the title, and the metadata def-list all
2
+ * come from the shared layers: layouts/split.css ([data-layout] +
3
+ * [data-section="media"]), dimensions/sections.css ([data-section="title"] /
4
+ * "preamble"), and dimensions/metadata.css ([data-zone-layout]). This file
5
+ * only carries realm-specific chrome. */
6
+
7
+ /* Stacked layout — split / split-reverse are handled by shared split.css */
8
+ .rf-realm[data-layout="stacked"] {
3
9
  display: flex;
4
10
  flex-direction: column;
5
11
  }
@@ -19,13 +25,6 @@
19
25
  .rf-realm__content ol {
20
26
  padding-left: 1.5rem;
21
27
  }
22
- .rf-realm > span[property="name"] {
23
- display: block;
24
- font-size: 1.5rem;
25
- font-weight: 700;
26
- margin-bottom: 0.5rem;
27
- color: var(--rf-color-heading);
28
- }
29
28
 
30
29
  /* Realm Section */
31
30
  .rf-realm-section {
@@ -44,113 +43,3 @@
44
43
  .rf-realm-section__body ol {
45
44
  padding-left: 1.5rem;
46
45
  }
47
-
48
- /* Split layout — shared */
49
- .rf-realm[data-layout="split"],
50
- .rf-realm[data-layout="split-reverse"] {
51
- display: grid;
52
- grid-template-columns: var(--split-ratio, 1fr 1fr);
53
- column-gap: var(--split-gap, 2rem);
54
- align-items: var(--split-valign, start);
55
- }
56
- /* Split: badge + name + content left (col 1), scene right (col 2) */
57
- .rf-realm[data-layout="split"] > .rf-realm__badge {
58
- grid-column: 1;
59
- grid-row: 1;
60
- }
61
- .rf-realm[data-layout="split"] > span[property="name"] {
62
- grid-column: 1;
63
- grid-row: 2;
64
- }
65
- .rf-realm[data-layout="split"] > .rf-realm__content {
66
- grid-column: 1;
67
- grid-row: 3;
68
- }
69
- .rf-realm[data-layout="split"] > .rf-realm__scene {
70
- grid-column: 2;
71
- grid-row: 1 / 4;
72
- }
73
- /* Split-reverse: scene left (col 1), badge + name + content right (col 2) */
74
- .rf-realm[data-layout="split-reverse"] > .rf-realm__badge {
75
- grid-column: 2;
76
- grid-row: 1;
77
- }
78
- .rf-realm[data-layout="split-reverse"] > span[property="name"] {
79
- grid-column: 2;
80
- grid-row: 2;
81
- }
82
- .rf-realm[data-layout="split-reverse"] > .rf-realm__content {
83
- grid-column: 2;
84
- grid-row: 3;
85
- }
86
- .rf-realm[data-layout="split-reverse"] > .rf-realm__scene {
87
- grid-column: 1;
88
- grid-row: 1 / 4;
89
- margin: 0;
90
- }
91
- /* Collapse to single column on small screens */
92
- @media (max-width: 640px) {
93
- .rf-realm[data-layout="split"],
94
- .rf-realm[data-layout="split-reverse"] {
95
- grid-template-columns: 1fr;
96
- }
97
- .rf-realm[data-layout="split"] > .rf-realm__badge,
98
- .rf-realm[data-layout="split"] > span[property="name"],
99
- .rf-realm[data-layout="split"] > .rf-realm__content,
100
- .rf-realm[data-layout="split"] > .rf-realm__scene,
101
- .rf-realm[data-layout="split-reverse"] > .rf-realm__badge,
102
- .rf-realm[data-layout="split-reverse"] > span[property="name"],
103
- .rf-realm[data-layout="split-reverse"] > .rf-realm__content,
104
- .rf-realm[data-layout="split-reverse"] > .rf-realm__scene {
105
- grid-column: auto;
106
- grid-row: auto;
107
- }
108
- /* Only add margin when NOT in full-bleed media-position mode (shared split.css handles that) */
109
- .rf-realm[data-layout="split"]:not([data-media-position="top"]) > .rf-realm__scene,
110
- .rf-realm[data-layout="split-reverse"]:not([data-media-position="top"]) > .rf-realm__scene {
111
- margin-bottom: var(--rf-spacing-md);
112
- }
113
- }
114
- /* Reset grid placement when data-collapse triggers single-column from shared split.css */
115
- @media (max-width: 640px) {
116
- .rf-realm[data-collapse="sm"] > .rf-realm__badge,
117
- .rf-realm[data-collapse="sm"] > span[property="name"],
118
- .rf-realm[data-collapse="sm"] > .rf-realm__content,
119
- .rf-realm[data-collapse="sm"] > .rf-realm__scene {
120
- grid-column: auto;
121
- grid-row: auto;
122
- }
123
- .rf-realm[data-collapse="sm"]:not([data-media-position="top"]) > .rf-realm__scene {
124
- margin-bottom: var(--rf-spacing-md);
125
- }
126
- }
127
- @media (max-width: 768px) {
128
- .rf-realm[data-collapse="md"] > .rf-realm__badge,
129
- .rf-realm[data-collapse="md"] > span[property="name"],
130
- .rf-realm[data-collapse="md"] > .rf-realm__content,
131
- .rf-realm[data-collapse="md"] > .rf-realm__scene {
132
- grid-column: auto;
133
- grid-row: auto;
134
- }
135
- .rf-realm[data-collapse="md"]:not([data-media-position="top"]) > .rf-realm__scene {
136
- margin-bottom: var(--rf-spacing-md);
137
- }
138
- }
139
- @media (max-width: 1024px) {
140
- .rf-realm[data-collapse="lg"] > .rf-realm__badge,
141
- .rf-realm[data-collapse="lg"] > span[property="name"],
142
- .rf-realm[data-collapse="lg"] > .rf-realm__content,
143
- .rf-realm[data-collapse="lg"] > .rf-realm__scene {
144
- grid-column: auto;
145
- grid-row: auto;
146
- }
147
- .rf-realm[data-collapse="lg"]:not([data-media-position="top"]) > .rf-realm__scene {
148
- margin-bottom: var(--rf-spacing-md);
149
- }
150
- }
151
-
152
- /* Split layout scene gets subtle depth */
153
- .rf-realm[data-layout="split"] .rf-realm__scene img,
154
- .rf-realm[data-layout="split-reverse"] .rf-realm__scene img {
155
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
156
- }
@@ -104,3 +104,23 @@
104
104
  .rf-recipe__media img {
105
105
  border-radius: var(--rf-radius-lg);
106
106
  }
107
+
108
+ /* Metadata — prep / cook / serves / difficulty are short, symmetric facts,
109
+ * so keep the def-list a dense tile grid at every width (a smaller column
110
+ * min than the 8rem default) instead of the shared mobile label/value list. */
111
+ .rf-recipe__metadata {
112
+ grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
113
+ }
114
+ @media (max-width: 48rem) {
115
+ .rf-recipe__metadata {
116
+ grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
117
+ gap: 0.75rem;
118
+ align-items: normal;
119
+ padding: 0;
120
+ border: none;
121
+ }
122
+ .rf-recipe__metadata > [data-name="row"] {
123
+ display: flex;
124
+ }
125
+ }
126
+
@@ -1,13 +1,10 @@
1
1
  /* Spec */
2
2
 
3
- /* Primary badges: ID left, status right */
4
- .rf-spec__header-primary {
5
- justify-content: space-between;
6
- margin-bottom: 0.75rem;
7
- }
3
+ /* SPEC-079: eyebrow + metadata zone names replace header-primary /
4
+ * header-secondary. Layout-level geometry lives on [data-zone-layout]
5
+ * selectors. */
8
6
 
9
- /* Preamble: title + optional summary between badge groups */
10
- .rf-spec__preamble {
7
+ .rf-spec__eyebrow {
11
8
  margin-bottom: 0.75rem;
12
9
  }
13
10
  .rf-spec__title h1,
@@ -16,8 +13,7 @@
16
13
  margin-top: 0;
17
14
  }
18
15
 
19
- /* Secondary badges: pill row below preamble */
20
- .rf-spec__header-secondary {
16
+ .rf-spec__metadata {
21
17
  margin-bottom: 1.5rem;
22
18
  }
23
19
 
@@ -1,14 +1,17 @@
1
1
  /* Symbol */
2
- .rf-symbol__header {
2
+
3
+ /* SPEC-080: signature bar (kind/lang chips + source link). Geometry +
4
+ * the source link's right-push come from [data-zone-layout="bar"]; the
5
+ * source link is a `href` field (data-meta-type="link"). */
6
+ .rf-symbol__eyebrow {
3
7
  padding: 0.5rem 0;
4
8
  }
5
- .rf-symbol__source-link {
6
- margin-left: auto;
9
+ .rf-symbol__eyebrow [data-meta-type="link"] {
7
10
  font-size: 0.75rem;
8
11
  color: var(--rf-color-muted);
9
12
  text-decoration: none;
10
13
  }
11
- .rf-symbol__source-link:hover {
14
+ .rf-symbol__eyebrow [data-meta-type="link"]:hover {
12
15
  color: var(--rf-color-primary);
13
16
  }
14
17
  .rf-symbol__body {
@@ -4,24 +4,11 @@
4
4
  padding: 1.75rem 2rem;
5
5
  background: var(--rf-color-surface);
6
6
  }
7
+ /* Rating block — stars rendered by the shared `[data-meta-type=rating]`
8
+ * treatment; this rule only owns the spacing below the row. */
7
9
  .rf-testimonial__rating {
8
- display: flex;
9
- gap: 0.125rem;
10
10
  margin-bottom: 0.75rem;
11
- }
12
- .rf-testimonial__star {
13
11
  font-size: 1.1rem;
14
- color: var(--rf-color-border);
15
- line-height: 1;
16
- }
17
- .rf-testimonial__star::before {
18
- content: '★';
19
- }
20
- .rf-testimonial__star[data-filled="true"] {
21
- color: var(--rf-color-warning);
22
- }
23
- .rf-testimonial__content {
24
- display: contents;
25
12
  }
26
13
  .rf-testimonial blockquote {
27
14
  border: none;
@@ -1,30 +1,28 @@
1
1
  /* Work */
2
2
 
3
- /* Primary badges: ID left, status right */
4
- .rf-work__header-primary {
5
- justify-content: space-between;
6
- margin-bottom: 0.75rem;
7
- }
3
+ /* SPEC-080: eyebrow / metadata / tags are projected blocks placed at the
4
+ * rune root via `layout`. Geometry comes from the universal
5
+ * `[data-zone-layout]` selectors in dimensions/metadata.css; this file
6
+ * carries the work-specific spacing + complexity dots + assignee prefix. */
8
7
 
9
- /* Preamble: title + optional blurb between badge groups */
10
- .rf-work__preamble {
8
+ .rf-work__eyebrow {
11
9
  margin-bottom: 0.75rem;
12
10
  }
11
+
13
12
  .rf-work__title h1,
14
13
  .rf-work__title h2,
15
14
  .rf-work__title h3 {
16
15
  margin-top: 0;
17
16
  }
18
17
 
19
- /* Secondary badges: pill row below preamble */
20
- .rf-work__header-secondary {
18
+ .rf-work__metadata {
21
19
  margin-bottom: 1.5rem;
22
20
  }
23
21
 
24
- .rf-work__assignee-badge {
25
- margin-left: auto;
26
- }
27
- .rf-work__assignee-badge::before { content: '@'; }
22
+ /* Assignee — `@` prefix on the plain-text def-list value. Targets the
23
+ * row by field name so milestone / tags don't get the prefix too. */
24
+ .rf-work__metadata [data-field="assignee"] dd .rf-badge::before { content: '@'; }
25
+
28
26
  .rf-work__body {
29
27
  font-size: 0.925rem;
30
28
  line-height: 1.65;
@@ -38,12 +36,11 @@
38
36
  margin-top: 0.75rem;
39
37
  }
40
38
 
41
- /* Complexity dots */
42
- .rf-work__complexity-badge::after {
43
- margin-left: 0.25rem;
44
- }
45
- [data-complexity="trivial"] > .rf-work__header-secondary > .rf-work__complexity-badge::after { content: ''; }
46
- [data-complexity="simple"] > .rf-work__header-secondary > .rf-work__complexity-badge::after { content: '●●'; }
47
- [data-complexity="moderate"] > .rf-work__header-secondary > .rf-work__complexity-badge::after { content: '●●●'; }
48
- [data-complexity="complex"] > .rf-work__header-secondary > .rf-work__complexity-badge::after { content: '●●●●'; }
49
- [data-complexity="unknown"] > .rf-work__header-secondary > .rf-work__complexity-badge::after { content: '?'; }
39
+ /* Complexity dots — appended after the value cell in the def-list. The
40
+ * `data-complexity` attribute lives on the root work element (set by
41
+ * engine modifier processing). */
42
+ [data-complexity="trivial"] .rf-work__metadata [data-field="complexity"] dd::after { content: ' ●'; }
43
+ [data-complexity="simple"] .rf-work__metadata [data-field="complexity"] dd::after { content: ' ●●'; }
44
+ [data-complexity="moderate"] .rf-work__metadata [data-field="complexity"] dd::after { content: ' ●●●'; }
45
+ [data-complexity="complex"] .rf-work__metadata [data-field="complexity"] dd::after { content: ' ●●●●'; }
46
+ [data-complexity="unknown"] .rf-work__metadata [data-field="complexity"] dd::after { content: ' ?'; }
package/tokens/base.css CHANGED
@@ -52,6 +52,20 @@
52
52
  --rf-color-success-bg: #e0eee4;
53
53
  --rf-color-success-border: #b8d4be;
54
54
 
55
+ /* WORK-304 — neutral tint for line highlight (the third
56
+ * `[data-line-status]` value that snippet / codegroup / diff share).
57
+ * Subtle surface tint so highlighted rows read as emphasized but not
58
+ * status-coloured (which would compete with diff's add/remove channel
59
+ * and the semantic palette above). `*-rail` is the optional left-edge
60
+ * border colour; falls back to the primary accent via the consuming
61
+ * CSS for themes that don't override it. */
62
+ --rf-color-line-highlight: color-mix(in srgb, var(--rf-color-text) 6%, transparent);
63
+ --rf-color-line-highlight-rail: var(--rf-color-primary, var(--rf-color-text));
64
+ /* Gutter colour for `pre[data-linenumbers]` line counter. Defers to
65
+ * the existing muted text token by default; themes can pin a
66
+ * dedicated hue without overriding muted. */
67
+ --rf-color-line-number: var(--rf-color-muted);
68
+
55
69
  /* Radii */
56
70
  --rf-radius-sm: 6px;
57
71
  --rf-radius-md: 10px;