@mdxui/services 0.2.0 → 0.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.
@@ -0,0 +1,363 @@
1
+ /**
2
+ * @mdxui/services — carriage theme envelope
3
+ * ============================================================================
4
+ *
5
+ * The Services dialect's components (ServiceHero, Problem, WhatYouGet, …) were
6
+ * extracted from carriage's chassis and still reference carriage's design-token
7
+ * vocabulary: `text-display-hero`, `tracking-tighter2`, `text-ink`, `bg-cta`,
8
+ * `rounded-cta`, `max-w-container`, `oklch(var(--accent))` SVG strokes, and a
9
+ * Fraunces `--font-display`. The package ships JSX only, so in a consumer those
10
+ * tokens are UNDEFINED and every element falls back (16px headings, transparent
11
+ * CTAs, no teal accent). This file ships the token DEFINITIONS so the markup the
12
+ * package emits actually renders as designed.
13
+ *
14
+ * Consume it from your Tailwind v4 entry (e.g. app/globals.css):
15
+ *
16
+ * @import "@mdxui/services/styles.css";
17
+ *
18
+ * SCOPING (critical)
19
+ * ------------------
20
+ * Everything is scoped under `[data-dialect="services"]` — the wrapper
21
+ * `ServicesLandingView` renders around the whole Services arc. The host app
22
+ * pins SHARED token names globally for its OTHER dialects (e.g.
23
+ * `--font-display: instrument-serif`, its own `--color-accent`), and it uses
24
+ * `@theme inline`, which BAKES those values directly into the generated
25
+ * utilities (`.font-display { font-family: var(--font-instrument-serif) }`) —
26
+ * a CSS-var swap can't retarget them. So this envelope does NOT redefine shared
27
+ * Tailwind theme keys. Instead it ships the carriage utilities as explicit,
28
+ * SCOPED class rules (`[data-dialect="services"] .text-display-hero { … }`).
29
+ * They win inside the Services subtree by selector specificity, are completely
30
+ * host-agnostic, and leave every other archetype untouched. Carriage's
31
+ * exclusive token names (ink / surface / cta / display-hero …) never collide;
32
+ * the shared ones (font-display, accent) are handled here without touching the
33
+ * host's globals.
34
+ *
35
+ * This is shipped as raw CSS (not precompiled). The few `@font-face` rules and
36
+ * the plain class rules need no Tailwind processing; the consumer can `@import`
37
+ * it directly into its `@import "tailwindcss"` entry.
38
+ *
39
+ * Provenance: carriage src/app/globals.css + tailwind.config.ts on origin/master
40
+ * (commits 75c8952 landing token vocabulary, 1e1dcc5 theme catalogue + CTA/font
41
+ * indirection, f598b60 the 6 extended surface/sunk/ink2/ink3/line/line2 tokens).
42
+ */
43
+
44
+ /* ──────────────────────────────────────────────────────────────────
45
+ FONT — Fraunces, self-contained.
46
+ The host loads instrument-serif / inter / jetbrains via next/font but NOT
47
+ Fraunces, so the envelope ships it via @font-face (Google Fonts woff2).
48
+ @font-face has no ordering constraint (unlike @import url()), so it is safe
49
+ to drop anywhere in the consumer's entry. Variable axis covers the weights
50
+ carriage's display headings use.
51
+ ────────────────────────────────────────────────────────────────── */
52
+ @font-face {
53
+ font-family: 'Fraunces';
54
+ font-style: normal;
55
+ font-weight: 100 900;
56
+ font-display: swap;
57
+ src: url('https://fonts.gstatic.com/s/fraunces/v37/6NUu8FyLNQOQZAnv9bYEvDiIdE9Ea92uemAk_WBq8U_9thllg.woff2')
58
+ format('woff2');
59
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
60
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
61
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
62
+ }
63
+ @font-face {
64
+ font-family: 'Fraunces';
65
+ font-style: italic;
66
+ font-weight: 100 900;
67
+ font-display: swap;
68
+ src: url('https://fonts.gstatic.com/s/fraunces/v37/6NVf8FyLNQOQZAnv9ZwNjucMHVn85Ni7emA17F-_DPLm5Vnf_VkS.woff2')
69
+ format('woff2');
70
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
71
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
72
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
73
+ }
74
+
75
+ /* ──────────────────────────────────────────────────────────────────
76
+ SCOPE ROOT — carriage CSS vars, applied ONLY to the Services subtree.
77
+ `ServicesLandingView` renders `<div data-dialect="services">` around the
78
+ whole arc; these cascade to every section without touching the host page.
79
+ Faithful copy of carriage src/app/globals.css :root (sans the html/body
80
+ chrome — the host owns those). The class rules further down read these.
81
+ ────────────────────────────────────────────────────────────────── */
82
+ [data-dialect='services'] {
83
+ /* Warm-paper neutrals, ink-deep with cool tint. Strict OKLCH triples. */
84
+ --paper: 0.985 0.005 85;
85
+ --surface: 0.972 0.008 82;
86
+ --sunk: 0.955 0.01 80;
87
+ --ink: 0.205 0.018 252;
88
+ --ink2: 0.435 0.014 250;
89
+ --ink3: 0.625 0.012 248;
90
+ --line: 0.88 0.008 85;
91
+ --line2: 0.82 0.01 85;
92
+
93
+ /* One committed accent: petrol teal. Bare triples so the carriage inline
94
+ `oklch(var(--accent))` SVG strokes resolve. */
95
+ --accent: 0.52 0.092 198;
96
+ --accent-deep: 0.38 0.082 200;
97
+ --accent-mute: 0.76 0.04 198;
98
+
99
+ /* Earth-tone deal verdicts. */
100
+ --great: 0.56 0.09 158;
101
+ --fair: 0.685 0.082 78;
102
+ --over: 0.605 0.115 42;
103
+ --avoid: 0.46 0.13 28;
104
+
105
+ /* Fonts. Fraunces is the carriage display face; sans/mono reuse the host's
106
+ next/font handles when present. */
107
+ --font-fraunces: 'Fraunces', ui-serif, Georgia, serif;
108
+ --font-display: var(--font-fraunces);
109
+ --font-sans: var(--font-inter, ui-sans-serif, system-ui, sans-serif);
110
+ --font-mono: var(--font-jetbrains, ui-monospace, monospace);
111
+
112
+ /* CTA indirection — carriage default recipe: ink bg → accent-deep hover,
113
+ paper text. */
114
+ --cta-bg: var(--ink);
115
+ --cta-bg-hover: var(--accent-deep);
116
+ --cta-fg: var(--paper);
117
+
118
+ /* Type ramp — base (mobile) step; ≥640 / ≥1024 steps in the media queries. */
119
+ --text-display-hero: 40px;
120
+ --text-display-section: 32px;
121
+ --text-display-sub: 24px;
122
+
123
+ /* Container / radius. */
124
+ --container-max: 1100px;
125
+ --radius-cta: 9999px;
126
+ --radius-card: 0.5rem;
127
+ --radius-input: 0.375rem;
128
+
129
+ /* Motion — ScrollReveal reads these inline. */
130
+ --motion-fade-duration: 300ms;
131
+ --motion-fade-easing: cubic-bezier(0.2, 0.8, 0.2, 1);
132
+
133
+ /* Carriage paints the Services surface warm-paper + ink, independent of the
134
+ host's dark page, so the editorial sections read on paper. */
135
+ background: oklch(var(--paper));
136
+ color: oklch(var(--ink));
137
+ -webkit-font-smoothing: antialiased;
138
+ -moz-osx-font-smoothing: grayscale;
139
+ text-rendering: optimizeLegibility;
140
+ }
141
+
142
+ /* Display type ramp steps (carriage globals.css media queries, scoped). */
143
+ @media (min-width: 640px) {
144
+ [data-dialect='services'] {
145
+ --text-display-hero: 56px;
146
+ --text-display-section: 40px;
147
+ }
148
+ }
149
+ @media (min-width: 1024px) {
150
+ [data-dialect='services'] {
151
+ --text-display-hero: 60px;
152
+ }
153
+ }
154
+ @media (prefers-reduced-motion: reduce) {
155
+ [data-dialect='services'] {
156
+ --motion-fade-duration: 0ms;
157
+ }
158
+ }
159
+
160
+ /* ════════════════════════════════════════════════════════════════════
161
+ CARRIAGE UTILITIES — scoped class rules.
162
+ Every utility the Services markup references, defined under the subtree so
163
+ it wins by specificity and is host-agnostic. These are the v4-as-plain-CSS
164
+ translation of carriage's tailwind.config.ts theme.extend. Scoping each on
165
+ `.<utility>` also tree-shake-proofs them (no @source dependency).
166
+ ════════════════════════════════════════════════════════════════════ */
167
+
168
+ /* —— Fonts ——————————————————————————————————————————————————————— */
169
+ [data-dialect='services'] .font-display {
170
+ font-family: var(--font-fraunces), ui-serif, Georgia, serif;
171
+ }
172
+
173
+ /* —— Type ramp (font-size + line-height + tracking) ——————————————— */
174
+ [data-dialect='services'] .text-display-hero {
175
+ font-size: var(--text-display-hero);
176
+ line-height: 1.05;
177
+ }
178
+ [data-dialect='services'] .text-display-section {
179
+ font-size: var(--text-display-section);
180
+ line-height: 1.1;
181
+ }
182
+ [data-dialect='services'] .text-display-sub {
183
+ font-size: var(--text-display-sub);
184
+ line-height: 1.15;
185
+ }
186
+ [data-dialect='services'] .text-body {
187
+ font-size: 16px;
188
+ line-height: 1.5;
189
+ }
190
+ [data-dialect='services'] .text-body-sm {
191
+ font-size: 14px;
192
+ line-height: 1.5;
193
+ }
194
+ [data-dialect='services'] .text-body-xs {
195
+ font-size: 13px;
196
+ line-height: 1.5;
197
+ }
198
+ [data-dialect='services'] .text-eyebrow {
199
+ font-size: 11px;
200
+ line-height: 1.4;
201
+ letter-spacing: 0.04em;
202
+ }
203
+ [data-dialect='services'] .text-micro {
204
+ font-size: 12px;
205
+ line-height: 1.4;
206
+ }
207
+ [data-dialect='services'] .tracking-tightish {
208
+ letter-spacing: -0.011em;
209
+ }
210
+ [data-dialect='services'] .tracking-tighter2 {
211
+ letter-spacing: -0.02em;
212
+ }
213
+
214
+ /* —— Text colors ————————————————————————————————————————————————— */
215
+ [data-dialect='services'] .text-ink {
216
+ color: oklch(var(--ink));
217
+ }
218
+ [data-dialect='services'] .text-ink2 {
219
+ color: oklch(var(--ink2));
220
+ }
221
+ [data-dialect='services'] .text-ink3 {
222
+ color: oklch(var(--ink3));
223
+ }
224
+ [data-dialect='services'] .text-ink3\/60 {
225
+ color: oklch(var(--ink3) / 0.6);
226
+ }
227
+ [data-dialect='services'] .text-paper {
228
+ color: oklch(var(--paper));
229
+ }
230
+ [data-dialect='services'] .text-accent {
231
+ color: oklch(var(--accent));
232
+ }
233
+ [data-dialect='services'] .text-accentDeep {
234
+ color: oklch(var(--accent-deep));
235
+ }
236
+ [data-dialect='services'] .text-cta-fg {
237
+ color: oklch(var(--cta-fg));
238
+ }
239
+ [data-dialect='services'] .text-great {
240
+ color: oklch(var(--great));
241
+ }
242
+ [data-dialect='services'] .text-fair {
243
+ color: oklch(var(--fair));
244
+ }
245
+ [data-dialect='services'] .text-over {
246
+ color: oklch(var(--over));
247
+ }
248
+ [data-dialect='services'] .text-avoid {
249
+ color: oklch(var(--avoid));
250
+ }
251
+ [data-dialect='services'] .hover\:text-ink:hover {
252
+ color: oklch(var(--ink));
253
+ }
254
+ [data-dialect='services'] .hover\:text-accentDeep:hover {
255
+ color: oklch(var(--accent-deep));
256
+ }
257
+ [data-dialect='services'] .hover\:text-accent:hover {
258
+ color: oklch(var(--accent));
259
+ }
260
+
261
+ /* —— Background colors ——————————————————————————————————————————— */
262
+ [data-dialect='services'] .bg-paper {
263
+ background-color: oklch(var(--paper));
264
+ }
265
+ [data-dialect='services'] .bg-surface {
266
+ background-color: oklch(var(--surface));
267
+ }
268
+ [data-dialect='services'] .bg-sunk {
269
+ background-color: oklch(var(--sunk));
270
+ }
271
+ [data-dialect='services'] .bg-ink {
272
+ background-color: oklch(var(--ink));
273
+ }
274
+ [data-dialect='services'] .bg-ink\/40 {
275
+ background-color: oklch(var(--ink) / 0.4);
276
+ }
277
+ [data-dialect='services'] .bg-ink2 {
278
+ background-color: oklch(var(--ink2));
279
+ }
280
+ [data-dialect='services'] .bg-ink3 {
281
+ background-color: oklch(var(--ink3));
282
+ }
283
+ [data-dialect='services'] .bg-line {
284
+ background-color: oklch(var(--line));
285
+ }
286
+ [data-dialect='services'] .bg-line2 {
287
+ background-color: oklch(var(--line2));
288
+ }
289
+ [data-dialect='services'] .bg-accent {
290
+ background-color: oklch(var(--accent));
291
+ }
292
+ [data-dialect='services'] .bg-cta {
293
+ background-color: oklch(var(--cta-bg));
294
+ }
295
+ [data-dialect='services'] .hover\:bg-cta-hover:hover {
296
+ background-color: oklch(var(--cta-bg-hover));
297
+ }
298
+ [data-dialect='services'] .hover\:bg-surface:hover {
299
+ background-color: oklch(var(--surface));
300
+ }
301
+
302
+ /* —— Border colors ——————————————————————————————————————————————— */
303
+ [data-dialect='services'] .border-line {
304
+ border-color: oklch(var(--line));
305
+ }
306
+ [data-dialect='services'] .border-line2 {
307
+ border-color: oklch(var(--line2));
308
+ }
309
+ [data-dialect='services'] .border-accent {
310
+ border-color: oklch(var(--accent));
311
+ }
312
+ [data-dialect='services'] .border-ink {
313
+ border-color: oklch(var(--ink));
314
+ }
315
+ [data-dialect='services'] .hover\:border-ink:hover {
316
+ border-color: oklch(var(--ink));
317
+ }
318
+
319
+ /* —— Radius ——————————————————————————————————————————————————————— */
320
+ [data-dialect='services'] .rounded-cta {
321
+ border-radius: var(--radius-cta);
322
+ }
323
+ [data-dialect='services'] .rounded-card {
324
+ border-radius: var(--radius-card);
325
+ }
326
+ [data-dialect='services'] .rounded-input {
327
+ border-radius: var(--radius-input);
328
+ }
329
+
330
+ /* —— Container ———————————————————————————————————————————————————— */
331
+ [data-dialect='services'] .max-w-container {
332
+ max-width: var(--container-max);
333
+ }
334
+
335
+ /* —— Shadows —————————————————————————————————————————————————————— */
336
+ [data-dialect='services'] .shadow-sheet {
337
+ box-shadow: 0 1px 0 0 oklch(var(--line) / 0.6);
338
+ }
339
+ [data-dialect='services'] .shadow-lift {
340
+ box-shadow: 0 1px 2px 0 oklch(0.2 0.02 250 / 0.04),
341
+ 0 8px 24px -8px oklch(0.2 0.02 250 / 0.06);
342
+ }
343
+
344
+ /* —— Easing ——————————————————————————————————————————————————————— */
345
+ [data-dialect='services'] .ease-out-quart {
346
+ transition-timing-function: cubic-bezier(0.25, 1, 0.5, 1);
347
+ }
348
+ [data-dialect='services'] .ease-out-quint {
349
+ transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
350
+ }
351
+ [data-dialect='services'] .ease-out-expo {
352
+ transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
353
+ }
354
+
355
+ /* —— Number-friendly typography helper carriage markup uses ——————— */
356
+ [data-dialect='services'] .tabular {
357
+ font-variant-numeric: tabular-nums lining-nums;
358
+ }
359
+ [data-dialect='services'] .serif-num {
360
+ font-family: var(--font-fraunces), ui-serif, Georgia, serif;
361
+ font-feature-settings: 'ss01', 'cv11';
362
+ font-variant-numeric: lining-nums tabular-nums;
363
+ }
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@mdxui/services",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Services site template — the Services dialect of the @mdxui template family. Higher-order, outcome-led landing components (ServiceHero, Problem, WhatYouGet, HowItWorks, Defensibility, ReportPricing, Faq, FinalCta) that expose Services-semantic props and compose @mdxui/neo's design language. Extracted from carriage's chassis.",
5
5
  "type": "module",
6
- "sideEffects": false,
6
+ "sideEffects": [
7
+ "**/*.css"
8
+ ],
7
9
  "license": "MIT",
8
10
  "author": "dot.do",
9
11
  "repository": {
@@ -44,14 +46,15 @@
44
46
  "./schemas": {
45
47
  "types": "./dist/schemas/index.d.ts",
46
48
  "import": "./dist/schemas/index.js"
47
- }
49
+ },
50
+ "./styles.css": "./dist/styles.css"
48
51
  },
49
52
  "files": [
50
53
  "dist",
51
54
  "README.md"
52
55
  ],
53
56
  "scripts": {
54
- "build": "NODE_OPTIONS=--max-old-space-size=4096 tsup",
57
+ "build": "NODE_OPTIONS=--max-old-space-size=8192 tsup",
55
58
  "typecheck": "tsc --noEmit",
56
59
  "test": "vitest run",
57
60
  "clean": "rm -rf dist .turbo node_modules",
@@ -59,7 +62,7 @@
59
62
  },
60
63
  "devDependencies": {
61
64
  "@mdxui/dialect": "0.1.0",
62
- "@mdxui/neo": "0.1.0",
65
+ "@mdxui/neo": "0.1.2",
63
66
  "@mdxui/primitives": "^6.0.0",
64
67
  "@mdxui/themes": "^6.0.0",
65
68
  "@mdxui/typescript-config": "6.0.0",