@kolkrabbi/kol-theme 0.11.7 → 0.11.9

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.
package/kol-theme.css CHANGED
@@ -37,6 +37,7 @@
37
37
  @import "./kol-typography.css" layer(components);
38
38
  @import "./kol-typography-mono.css" layer(components);
39
39
  @import "./kol-type-mono-classes.css" layer(components);
40
+ @import "./kol-type-roles.css" layer(components);
40
41
  @import "./kol-utilities.css" layer(components);
41
42
  @import "./kol-components-atoms.css" layer(components);
42
43
  @import "./kol-components-molecules.css" layer(components);
@@ -0,0 +1,248 @@
1
+ /**
2
+ * kol-type-roles.css — the DOC + CARD role sets (2026-07-28 epic).
3
+ *
4
+ * Two opt-in role families that end per-repo re-derivation of the same stacks:
5
+ *
6
+ * .kol-doc-* — content/doc chrome roles (eyebrow → footer). The docs-scale
7
+ * ramp: quieter than the editorial .kol-prose-* head family
8
+ * (label/display/title/lede), which stays the long-form voice.
9
+ * .kol-card-* — card text roles (title/kicker/meta/excerpt/value/tag),
10
+ * grounded in the shipped card families (ArticleCard et al).
11
+ *
12
+ * ONE RULE, TWO ENTRY POINTS (the epic's law): content-furniture roles carry a
13
+ * `.kol-prose <tag>` twin selector so generated markdown/CMS markup and
14
+ * authored divs resolve to the SAME rule. Head roles (eyebrow/heading/lede/…)
15
+ * are deliberately NOT twinned — prose's editorial head sizes differ by
16
+ * design, and prose h1-h6 stay pixel-frozen in kol-typography.css.
17
+ * Prose gains table/figure styling here for the first time (pure addition).
18
+ *
19
+ * Everything is opt-in: inert until markup references a class.
20
+ */
21
+
22
+ /* =============================================================================
23
+ * DOC SET — 11 roles
24
+ * ============================================================================= */
25
+
26
+ /* eyebrow — the overline label above a title ("KOL · ICONS"). Single-line
27
+ * chrome → helper ramp (line-height 1); never carries paragraphs. */
28
+ .kol-doc-eyebrow {
29
+ font-family: var(--kol-font-family-mono);
30
+ font-size: 10px;
31
+ line-height: 1;
32
+ font-weight: 500;
33
+ letter-spacing: 0.1em;
34
+ text-transform: uppercase;
35
+ color: var(--kol-fg-meta);
36
+ }
37
+
38
+ /* heading — the page H1 of doc chrome (matches the DocHeader contract). */
39
+ .kol-doc-heading {
40
+ font-family: var(--kol-font-family-sans-compact);
41
+ font-size: var(--kol-text-heading-03);
42
+ line-height: 120%;
43
+ font-weight: 500;
44
+ color: var(--kol-fg-emphasis);
45
+ }
46
+
47
+ /* section title — the anchored section H2 (DocSection contract). */
48
+ .kol-doc-section-title {
49
+ font-family: var(--kol-font-family-sans-compact);
50
+ font-size: var(--kol-text-heading-04);
51
+ line-height: 100%;
52
+ font-weight: 500;
53
+ color: var(--kol-fg-emphasis);
54
+ }
55
+
56
+ /* lede — the descriptive paragraph under a heading. */
57
+ .kol-doc-lede {
58
+ font-family: var(--kol-font-family-sans);
59
+ font-size: var(--kol-text-body-01);
60
+ line-height: 160%;
61
+ font-weight: 400;
62
+ color: var(--kol-fg-body);
63
+ max-width: 65ch;
64
+ }
65
+
66
+ /* body — doc running copy one rung under the lede. */
67
+ .kol-doc-body {
68
+ font-family: var(--kol-font-family-sans);
69
+ font-size: var(--kol-text-body-02);
70
+ line-height: 160%;
71
+ font-weight: 400;
72
+ color: var(--kol-fg-body);
73
+ }
74
+
75
+ /* ── Content furniture — twinned with prose (one rule, two entry points) ── */
76
+
77
+ /* code block */
78
+ .kol-prose pre,
79
+ .kol-doc-code {
80
+ font-family: var(--kol-font-family-mono);
81
+ font-size: 14px;
82
+ font-weight: 400;
83
+ line-height: 22px;
84
+ padding: 16px 20px;
85
+ background: var(--kol-fg-04);
86
+ border-radius: 6px;
87
+ overflow-x: auto;
88
+ }
89
+ .kol-doc-code { margin: 0; }
90
+ .kol-prose pre { margin: 24px 0; } /* prose keeps its editorial block rhythm */
91
+
92
+ /* inline code */
93
+ .kol-prose code,
94
+ .kol-doc-code-inline {
95
+ font-family: var(--kol-font-family-mono);
96
+ font-size: 0.875em;
97
+ font-weight: 400;
98
+ background: var(--kol-fg-04);
99
+ padding: 0.1em 0.35em;
100
+ border-radius: 3px;
101
+ }
102
+ /* code inside pre stays stripped (rule preserved from the prose sheet) */
103
+ .kol-prose pre code,
104
+ .kol-doc-code code {
105
+ background: none;
106
+ padding: 0;
107
+ font-size: inherit;
108
+ border-radius: 0;
109
+ }
110
+
111
+ /* table — the ApiTable contract generalised: body-02 cells, helper-10 header
112
+ * row, mono for value-ish cells via .kol-doc-table-value on the td. */
113
+ .kol-prose table,
114
+ .kol-doc-table {
115
+ width: 100%;
116
+ text-align: left;
117
+ border-collapse: collapse;
118
+ font-family: var(--kol-font-family-sans);
119
+ font-size: var(--kol-text-body-02);
120
+ line-height: 160%;
121
+ font-weight: 400;
122
+ }
123
+ .kol-prose thead tr,
124
+ .kol-doc-table thead tr {
125
+ border-bottom: 1px solid var(--kol-fg-12);
126
+ }
127
+ .kol-prose th,
128
+ .kol-doc-table th {
129
+ font-family: var(--kol-font-family-mono);
130
+ font-size: 10px;
131
+ line-height: 1;
132
+ font-weight: 400;
133
+ letter-spacing: 0.1em;
134
+ text-transform: uppercase;
135
+ color: var(--kol-fg-meta);
136
+ padding: 10px 16px;
137
+ }
138
+ .kol-prose td,
139
+ .kol-doc-table td {
140
+ padding: 12px 16px;
141
+ border-bottom: 1px solid var(--kol-fg-08);
142
+ vertical-align: top;
143
+ color: var(--kol-fg-body);
144
+ }
145
+ .kol-prose tbody tr:last-child td,
146
+ .kol-doc-table tbody tr:last-child td { border-bottom: 0; }
147
+ .kol-doc-table td.kol-doc-table-value {
148
+ font-family: var(--kol-font-family-mono);
149
+ font-size: 12px;
150
+ line-height: 16px;
151
+ white-space: nowrap;
152
+ }
153
+
154
+ /* figure — the framed content container (preview cards, embedded media). */
155
+ .kol-prose figure,
156
+ .kol-doc-figure {
157
+ margin: 0;
158
+ border: 1px solid var(--kol-fg-12);
159
+ border-radius: var(--kol-radius-md);
160
+ overflow: hidden;
161
+ }
162
+
163
+ /* caption */
164
+ .kol-prose figcaption,
165
+ .kol-doc-caption {
166
+ font-family: var(--kol-font-family-mono);
167
+ font-size: 12px;
168
+ line-height: 16px;
169
+ font-weight: 400;
170
+ letter-spacing: 0.02em;
171
+ color: var(--kol-fg-meta);
172
+ }
173
+
174
+ /* footer — wrappable closing chrome (attributions, notes, updated-lines).
175
+ * Mono ramp BY LAW: helper is line-height-1 single-line chrome and never
176
+ * carries wrapping text. */
177
+ .kol-prose footer,
178
+ .kol-doc-footer {
179
+ font-family: var(--kol-font-family-mono);
180
+ font-size: 12px;
181
+ line-height: 16px;
182
+ font-weight: 400;
183
+ letter-spacing: 0.02em;
184
+ color: var(--kol-fg-meta);
185
+ }
186
+
187
+ /* =============================================================================
188
+ * CARD SET — 6 roles. Grounded in the shipped card families: mono body voice,
189
+ * helper kickers/meta, compact sans titles.
190
+ * ============================================================================= */
191
+
192
+ .kol-card-title {
193
+ font-family: var(--kol-font-family-sans-compact);
194
+ font-size: var(--kol-text-heading-05);
195
+ line-height: 125%;
196
+ font-weight: 500;
197
+ color: var(--kol-fg-emphasis);
198
+ }
199
+
200
+ .kol-card-kicker {
201
+ font-family: var(--kol-font-family-mono);
202
+ font-size: 12px;
203
+ line-height: 1;
204
+ font-weight: 500;
205
+ letter-spacing: 0.06em;
206
+ text-transform: uppercase;
207
+ color: var(--kol-fg-64);
208
+ }
209
+
210
+ .kol-card-meta {
211
+ font-family: var(--kol-font-family-mono);
212
+ font-size: 12px;
213
+ line-height: 1;
214
+ font-weight: 500;
215
+ letter-spacing: 0.06em;
216
+ color: var(--kol-fg-48);
217
+ }
218
+
219
+ /* excerpt — clamped card copy; lines via --kol-card-excerpt-lines (default 3) */
220
+ .kol-card-excerpt {
221
+ font-family: var(--kol-font-family-mono);
222
+ font-size: 14px;
223
+ line-height: 18px;
224
+ font-weight: 400;
225
+ color: var(--kol-fg-48);
226
+ display: -webkit-box;
227
+ -webkit-box-orient: vertical;
228
+ -webkit-line-clamp: var(--kol-card-excerpt-lines, 3);
229
+ overflow: hidden;
230
+ }
231
+
232
+ .kol-card-value {
233
+ font-family: var(--kol-font-family-mono);
234
+ font-size: 16px;
235
+ line-height: 22px;
236
+ font-weight: 500;
237
+ color: var(--kol-fg-emphasis);
238
+ }
239
+
240
+ .kol-card-tag {
241
+ font-family: var(--kol-font-family-mono);
242
+ font-size: 10px;
243
+ line-height: 1;
244
+ font-weight: 500;
245
+ letter-spacing: 0.1em;
246
+ text-transform: uppercase;
247
+ color: var(--kol-fg-48);
248
+ }
@@ -744,12 +744,14 @@
744
744
  * ============================================================================= */
745
745
 
746
746
  :root {
747
- /* Sans family tokens — three cuts loaded. Editor convention used in prose:
747
+ /* Sans family tokens — four cuts loaded. Editor convention used in prose:
748
748
  * Narrow for top-of-scale (display, large headings), Compact for mid (smaller
749
- * headings, lede), base for body. Atomic classes follow the same convention. */
749
+ * headings, lede), base for body, Tight for the display-tight voice.
750
+ * Atomic classes follow the same convention. */
750
751
  --kol-font-family-sans: 'Right Grotesk', sans-serif;
751
752
  --kol-font-family-sans-narrow: 'Right Grotesk Narrow', 'Right Grotesk', sans-serif;
752
753
  --kol-font-family-sans-compact: 'Right Grotesk Compact', 'Right Grotesk', sans-serif;
754
+ --kol-font-family-sans-tight: 'Right Grotesk Tight', 'Right Grotesk', sans-serif;
753
755
 
754
756
  /* Type size tokens — numbered scale, 01 = largest, ascending = smaller.
755
757
  * Mobile-first; @media overrides below scale display + heading-01 up on
@@ -834,19 +836,21 @@
834
836
  * Add the class when a consumer needs it. */
835
837
 
836
838
  /* =============================================================================
837
- * DISPLAY TIGHT — the condensed-caps display voice: base sans + the variable
838
- * width axis (font-stretch), weight 470. Uppercase BY CONTRACT — display
839
- * classes are the one type family that carries text-transform; the display
840
- * voice is caps by design language.
839
+ * DISPLAY TIGHT — the condensed-caps display voice: the Tight cut by NAME
840
+ * (--kol-font-family-sans-tight), weight 500 (TightMedium). Never select the
841
+ * cut via font-stretch: the loaded faces are static, carry no stretch
842
+ * descriptors, so stretch-based selection silently renders the wide base cut
843
+ * (bug found 2026-07-28). Uppercase BY CONTRACT — display classes are the one
844
+ * type family that carries text-transform; the display voice is caps by
845
+ * design language.
841
846
  * Lobbied verbatim from the website's elder type system (2026-07-16) so call
842
847
  * sites migrate without renames. `kol-heading-display` was a byte-identical
843
848
  * duplicate of `kol-display-lg` and was not carried — map it to display-lg.
844
849
  * ============================================================================= */
845
850
 
846
851
  .kol-display-lg {
847
- font-family: var(--kol-font-family-sans);
848
- font-stretch: extra-condensed;
849
- font-weight: 470;
852
+ font-family: var(--kol-font-family-sans-tight);
853
+ font-weight: 500;
850
854
  font-size: var(--kol-text-display-tight-01);
851
855
  line-height: 100%;
852
856
  text-transform: uppercase;
@@ -854,18 +858,16 @@
854
858
  }
855
859
 
856
860
  .kol-display-section {
857
- font-family: var(--kol-font-family-sans);
858
- font-stretch: extra-condensed;
859
- font-weight: 470;
861
+ font-family: var(--kol-font-family-sans-tight);
862
+ font-weight: 500;
860
863
  font-size: var(--kol-text-display-tight-02);
861
864
  line-height: 100%;
862
865
  text-transform: uppercase;
863
866
  }
864
867
 
865
868
  .kol-display-section-sm {
866
- font-family: var(--kol-font-family-sans);
867
- font-stretch: extra-condensed;
868
- font-weight: 470;
869
+ font-family: var(--kol-font-family-sans-tight);
870
+ font-weight: 500;
869
871
  font-size: var(--kol-text-display-tight-03);
870
872
  line-height: 100%;
871
873
  text-transform: uppercase;
@@ -1084,37 +1086,10 @@
1084
1086
  .kol-prose em { font-style: italic; color: var(--kol-fg-strong); }
1085
1087
  .kol-prose strong { font-weight: 700; color: var(--kol-fg-emphasis); }
1086
1088
 
1087
- /* ─── Code (inline + block) — JetBrains Mono via the mono token. Same family
1088
- * as `.kol-mono-N` so a future swap cascades. Body weight 400. ─── */
1089
-
1090
- .kol-prose code {
1091
- font-family: var(--kol-font-family-mono);
1092
- font-size: 0.875em; /* ~14px when prose body is 16px — proportional */
1093
- font-weight: 400;
1094
- background: var(--kol-fg-04);
1095
- padding: 0.1em 0.35em;
1096
- border-radius: 3px;
1097
- }
1098
-
1099
- .kol-prose pre {
1100
- font-family: var(--kol-font-family-mono);
1101
- font-size: 14px;
1102
- font-weight: 400;
1103
- line-height: 22px;
1104
- margin: 24px 0;
1105
- padding: 16px 20px;
1106
- background: var(--kol-fg-04);
1107
- border-radius: 6px;
1108
- overflow-x: auto;
1109
- }
1110
-
1111
- /* Code inside pre — strip inline-code styles to avoid double background / padding. */
1112
- .kol-prose pre code {
1113
- background: none;
1114
- padding: 0;
1115
- font-size: inherit;
1116
- border-radius: 0;
1117
- }
1089
+ /* ─── Code (inline + block) — rules live in kol-type-roles.css as the
1090
+ * prose/doc twin selectors (.kol-prose pre, .kol-doc-code etc.), one
1091
+ * definition for both entry points. Only prose's block margin stays
1092
+ * prose-specific, declared there. ─── */
1118
1093
 
1119
1094
  /* ─── Blockquote ─── */
1120
1095
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolkrabbi/kol-theme",
3
- "version": "0.11.7",
3
+ "version": "0.11.9",
4
4
  "description": "KOL (Kolkrabbi) design-system tokens + base CSS — brand-neutral. The canonical token/cascade layer every other KOL package and consumer builds on.",
5
5
  "license": "MIT",
6
6
  "type": "module",