clampography 0.9.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.
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Dawid Wąsowski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # 🙌 Clampography
2
+
3
+ **Clampography** is a CSS-only alternative to the official
4
+ [Tailwind CSS Typography plugin](https://github.com/tailwindlabs/tailwindcss-typography).
5
+ Instead of fixed sizes, it uses the CSS
6
+ [clamp()](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/clamp)
7
+ function to create fluid typography that adapts to any screen. With
8
+ [94%+ global browser support](https://caniuse.com/css-math-functions), it works
9
+ on nearly all devices.
10
+
11
+ Designed for [Tailwind v4's](https://tailwindcss.com/blog/tailwindcss-v4)
12
+ CSS-first system, no JavaScript configuration needed. Best suited for simple
13
+ websites like blogs and articles.
14
+
15
+ ## Philosophy
16
+
17
+ **Clampography** is built on three core principles to match
18
+ `@tailwindcss/typography` quality standards while remaining pure CSS:
19
+
20
+ - **No default styling:** No colors, borders, transforms, or decorations.
21
+ - **Structure only:** Manages size, spacing, weight, and font-family.
22
+ - **Smart scaling:** Contextual elements use `em` (relative), blocks use
23
+ `clamp()` (fluid).
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ # Install with NPM
29
+ npm install clampography
30
+
31
+ # Install with PNPM
32
+ pnpm add clampography
33
+
34
+ # Install with Deno
35
+ deno install npm:clampography
36
+
37
+ # Install with Bun
38
+ bun install clampography
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ ```css
44
+ /* First import Tailwind CSS */
45
+ @import "tailwindcss";
46
+
47
+ /* Then import Clampography */
48
+ @import "clampography";
49
+
50
+ /* Override default heading styles */
51
+ @layer base {
52
+ h1 {
53
+ letter-spacing: 0.05em;
54
+ }
55
+ }
56
+ ```
@@ -0,0 +1,519 @@
1
+ @layer base {
2
+ /* ==========================================================================
3
+
4
+ CLAMPOGRAPHY
5
+
6
+ A fluid typography system matching @tailwindcss/typography standards.
7
+
8
+ PHILOSOPHY:
9
+ - No default styling (no colors, borders, transforms, decorations)
10
+ - Structure only: size, spacing, weight, font-family
11
+ - Contextual elements use 'em' (relative), blocks use 'clamp' (fluid)
12
+
13
+ ========================================================================== */
14
+
15
+ /* --------------------------------------------------------------------------
16
+ ROOT CONFIGURATION
17
+ -------------------------------------------------------------------------- */
18
+
19
+ :root {
20
+ /* Fluid spacing scale */
21
+ --spacing-xs: clamp(0.5rem, 0.375rem + 0.625vw, 0.75rem);
22
+ --spacing-sm: clamp(0.75rem, 0.5625rem + 0.9375vw, 1.25rem);
23
+ --spacing-md: clamp(1rem, 0.75rem + 1.25vw, 1.5rem);
24
+ --spacing-lg: clamp(1.5rem, 1.125rem + 1.875vw, 2.5rem);
25
+ --spacing-xl: clamp(2rem, 1.5rem + 2.5vw, 3rem);
26
+
27
+ /* Utility variables */
28
+ --scroll-offset: 5rem;
29
+
30
+ /* System font stacks - optimal performance & consistency */
31
+ --font-family-base: system-ui, -apple-system, 'Segoe UI', Roboto,
32
+ 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
33
+ --font-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
34
+ 'Liberation Mono', 'Courier New', monospace;
35
+ }
36
+
37
+ /* --------------------------------------------------------------------------
38
+ BODY - Global Typography Settings
39
+ -------------------------------------------------------------------------- */
40
+
41
+ body {
42
+ font-family: var(--font-family-base);
43
+ /* Typography standard: 16px → 18px (not 14px) for optimal readability */
44
+ font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
45
+ line-height: 1.75;
46
+
47
+ /* Rendering optimizations */
48
+ text-rendering: optimizeLegibility;
49
+ -webkit-font-smoothing: antialiased;
50
+ -moz-osx-font-smoothing: grayscale;
51
+
52
+ /* Progressive enhancement - better line breaks (Chrome 117+, Safari 16.4+) */
53
+ text-wrap: pretty;
54
+ }
55
+
56
+ /* --------------------------------------------------------------------------
57
+ HEADINGS (H1-H6) - Structural Hierarchy
58
+ -------------------------------------------------------------------------- */
59
+
60
+ :where(h1, h2, h3, h4, h5, h6) {
61
+ font-weight: 600; /* Default weight, individual headings override */
62
+ scroll-margin-top: var(--scroll-offset);
63
+ }
64
+
65
+ h1 {
66
+ /* Typography standard: 36px → 48px (matches prose-base → prose-lg) */
67
+ font-size: clamp(2.25rem, 1.95rem + 1.5vw, 3rem);
68
+ line-height: 1.1111; /* Tailwind Typography uses tighter line-height for h1 */
69
+ font-weight: 800; /* Typography uses heavier weight for h1 */
70
+ margin-top: 0;
71
+ margin-bottom: var(--spacing-xl);
72
+ }
73
+
74
+ h2 {
75
+ /* Typography standard: 24px → 30px */
76
+ font-size: clamp(1.5rem, 1.35rem + 0.75vw, 1.875rem);
77
+ line-height: 1.3333;
78
+ font-weight: 700;
79
+ margin-top: var(--spacing-xl);
80
+ margin-bottom: var(--spacing-md);
81
+ }
82
+
83
+ h3 {
84
+ /* Typography standard: 20px → 24px */
85
+ font-size: clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
86
+ line-height: 1.6;
87
+ margin-top: var(--spacing-lg);
88
+ margin-bottom: var(--spacing-sm);
89
+ }
90
+
91
+ h4 {
92
+ /* Typography standard: stays at body size (16px → 18px) */
93
+ font-size: clamp(1rem, 0.975rem + 0.125vw, 1.125rem);
94
+ line-height: 1.5;
95
+ margin-top: var(--spacing-lg);
96
+ margin-bottom: var(--spacing-sm);
97
+ }
98
+
99
+ h5 {
100
+ /* H5/H6 rarely used in prose, but keep them proportional */
101
+ font-size: 1rem; /* Fixed at body size, distinguished by weight */
102
+ line-height: 1.5;
103
+ margin-top: var(--spacing-md);
104
+ margin-bottom: var(--spacing-xs);
105
+ }
106
+
107
+ h6 {
108
+ font-size: 0.875rem; /* Slightly smaller for hierarchy */
109
+ line-height: 1.5;
110
+ margin-top: var(--spacing-md);
111
+ margin-bottom: var(--spacing-xs);
112
+ }
113
+
114
+ /* --------------------------------------------------------------------------
115
+ TEXT CONTENT - Paragraphs & Inline Elements
116
+ -------------------------------------------------------------------------- */
117
+
118
+ /* Paragraphs */
119
+ p {
120
+ line-height: 1.75;
121
+ margin-bottom: var(--spacing-md);
122
+ }
123
+
124
+ /* Text modifiers - semantic emphasis */
125
+ :where(strong, b) {
126
+ font-weight: 700;
127
+ }
128
+
129
+ :where(em, i, cite, var) {
130
+ font-style: italic;
131
+ }
132
+
133
+ /* Definition term - structural emphasis without forcing italic */
134
+ dfn {
135
+ font-style: normal;
136
+ font-weight: 600;
137
+ }
138
+
139
+ /* Contextual sizing - uses 'em' to scale with parent */
140
+ small {
141
+ font-size: 0.875em; /* 87.5% of parent */
142
+ line-height: 1.5;
143
+ }
144
+
145
+ /* Code-related elements */
146
+ :where(code, kbd, samp) {
147
+ font-family: var(--font-family-mono);
148
+ font-size: 0.875em; /* Relative to context */
149
+ }
150
+
151
+ /* Superscript & subscript - essential for scientific notation */
152
+ :where(sub, sup) {
153
+ font-size: 0.75em;
154
+ line-height: 0;
155
+ position: relative;
156
+ vertical-align: baseline;
157
+ }
158
+ sup {
159
+ top: -0.5em;
160
+ }
161
+ sub {
162
+ bottom: -0.25em;
163
+ }
164
+
165
+ /* Abbreviations with titles */
166
+ abbr[title] {
167
+ text-decoration: underline dotted;
168
+ cursor: help;
169
+ }
170
+
171
+ /* Editorial marks - semantic text changes */
172
+ del {
173
+ text-decoration: line-through;
174
+ }
175
+
176
+ ins {
177
+ text-decoration: underline;
178
+ }
179
+
180
+ /* Strikethrough - presentational (not semantic like del) */
181
+ s {
182
+ text-decoration: line-through;
183
+ }
184
+
185
+ /* Underline - presentational (not semantic like ins) */
186
+ u {
187
+ text-decoration: underline;
188
+ }
189
+
190
+ /* Mark/Highlight element */
191
+ mark {
192
+ font-style: normal;
193
+ font-weight: inherit;
194
+ }
195
+
196
+ /* Address element */
197
+ address {
198
+ font-style: normal; /* Reset browser default italic */
199
+ margin-top: var(--spacing-md);
200
+ margin-bottom: var(--spacing-md);
201
+ }
202
+
203
+ /* Time element */
204
+ time {
205
+ font-style: normal;
206
+ font-variant-numeric: tabular-nums; /* Monospace numbers for alignment */
207
+ }
208
+
209
+ /* --------------------------------------------------------------------------
210
+ BLOCKQUOTES - Structural Spacing Only
211
+ -------------------------------------------------------------------------- */
212
+
213
+ blockquote {
214
+ margin-top: var(--spacing-lg);
215
+ margin-bottom: var(--spacing-lg);
216
+ padding-left: var(--spacing-md);
217
+ /* No font-style - let users decide visual treatment */
218
+ }
219
+
220
+ /* Nested blockquotes - reduced spacing for hierarchy */
221
+ blockquote blockquote {
222
+ margin-top: var(--spacing-sm);
223
+ margin-bottom: var(--spacing-sm);
224
+ padding-left: var(--spacing-sm);
225
+ }
226
+
227
+ /* Inline quotes */
228
+ q {
229
+ font-style: inherit;
230
+ /* Browser adds quotation marks automatically */
231
+ }
232
+
233
+ /* --------------------------------------------------------------------------
234
+ LISTS - Custom Structured Markers (Prose-like)
235
+ -------------------------------------------------------------------------- */
236
+
237
+ /* Reset default list styles to build custom ones */
238
+ :where(ul, ol) {
239
+ list-style: none;
240
+ margin-bottom: var(--spacing-md);
241
+ padding-left: clamp(1.5rem, 1.25rem + 1.25vw, 2rem);
242
+ }
243
+
244
+ li {
245
+ position: relative;
246
+ margin-bottom: var(--spacing-xs);
247
+ padding-left: 0.375em; /* Space between marker and text */
248
+ }
249
+
250
+ /*
251
+ * CUSTOM BULLETS (UL)
252
+ * Perfectly centered dot relative to the first line of text.
253
+ */
254
+ ul > li::before {
255
+ content: '';
256
+ position: absolute;
257
+ /* Positioning relative to the li padding */
258
+ left: -1.125em;
259
+ /* Vertically aligns with the first line (assuming line-height 1.75) */
260
+ top: calc(0.875em - 0.1875em);
261
+ width: 0.375em;
262
+ height: 0.375em;
263
+ background-color: currentColor;
264
+ border-radius: 50%;
265
+ opacity: 0.4; /* Subtle visual weight */
266
+ }
267
+
268
+ /*
269
+ * CUSTOM NUMBERS (OL)
270
+ * Right-aligned numbers for professional look (e.g. "9." aligns with "10.")
271
+ */
272
+ ol {
273
+ counter-reset: list-counter;
274
+ }
275
+
276
+ ol > li {
277
+ counter-increment: list-counter;
278
+ }
279
+
280
+ ol > li::before {
281
+ content: counter(list-counter) '.';
282
+ position: absolute;
283
+ left: -2.5em; /* More space for numbers */
284
+ width: 1.75em; /* Fixed width container for alignment */
285
+ text-align: right;
286
+ font-weight: 600; /* Make numbers stand out structurally */
287
+ color: currentColor;
288
+ opacity: 0.6; /* Slightly lighter than text */
289
+ }
290
+
291
+ /* Nested lists spacing */
292
+ :where(ul, ol) :where(ul, ol) {
293
+ margin-top: 0.5rem;
294
+ margin-bottom: 0.5rem;
295
+ padding-left: var(--spacing-md);
296
+ }
297
+
298
+ /* --------------------------------------------------------------------------
299
+ DEFINITION LISTS - Glossaries & Key-Value Pairs
300
+ -------------------------------------------------------------------------- */
301
+
302
+ dl {
303
+ margin-top: var(--spacing-md);
304
+ margin-bottom: var(--spacing-md);
305
+ }
306
+
307
+ dt {
308
+ font-weight: 600;
309
+ margin-top: var(--spacing-sm);
310
+ }
311
+
312
+ /* First dt shouldn't have top margin */
313
+ dt:first-child {
314
+ margin-top: 0;
315
+ }
316
+
317
+ dd {
318
+ margin-left: var(--spacing-md);
319
+ margin-bottom: var(--spacing-xs);
320
+ }
321
+
322
+ /* Last dd shouldn't have bottom margin */
323
+ dd:last-child {
324
+ margin-bottom: 0;
325
+ }
326
+
327
+ /* --------------------------------------------------------------------------
328
+ CODE BLOCKS - Monospace Typography
329
+ -------------------------------------------------------------------------- */
330
+
331
+ pre {
332
+ margin-top: var(--spacing-md);
333
+ margin-bottom: var(--spacing-md);
334
+ font-family: var(--font-family-mono);
335
+ font-size: 0.875em;
336
+ line-height: 1.6;
337
+ overflow-x: auto;
338
+ /* Padding & background moved to global.css */
339
+ }
340
+
341
+ /* Code inside pre blocks */
342
+ pre code {
343
+ font-size: inherit;
344
+ /* Reset inline code styles if any user CSS exists */
345
+ padding: 0;
346
+ background: none;
347
+ border-radius: 0;
348
+ }
349
+
350
+ /* --------------------------------------------------------------------------
351
+ FORMS - Basic Structure
352
+ -------------------------------------------------------------------------- */
353
+
354
+ fieldset {
355
+ margin-top: var(--spacing-md);
356
+ margin-bottom: var(--spacing-md);
357
+ padding: var(--spacing-md);
358
+ border: 0; /* Remove default border - user adds styling */
359
+ }
360
+
361
+ legend {
362
+ font-weight: 600;
363
+ padding: 0 var(--spacing-xs);
364
+ }
365
+
366
+ /* Form output element - typically displays calculation results */
367
+ output {
368
+ display: inline-block;
369
+ font-variant-numeric: tabular-nums;
370
+ }
371
+
372
+ /* Visual indicator elements - structural spacing only */
373
+ :where(meter, progress) {
374
+ display: inline-block;
375
+ vertical-align: middle;
376
+ }
377
+
378
+ /* --------------------------------------------------------------------------
379
+ MEDIA - Images, Videos, Figures
380
+ -------------------------------------------------------------------------- */
381
+
382
+ :where(img, video) {
383
+ max-width: 100%;
384
+ height: auto;
385
+ }
386
+
387
+ figure {
388
+ margin-top: var(--spacing-lg);
389
+ margin-bottom: var(--spacing-lg);
390
+ }
391
+
392
+ figcaption {
393
+ margin-top: var(--spacing-xs);
394
+ font-size: 0.875em;
395
+ line-height: 1.5;
396
+ }
397
+
398
+ /* --------------------------------------------------------------------------
399
+ TABLES - Structural Layout
400
+ -------------------------------------------------------------------------- */
401
+
402
+ table {
403
+ width: 100%;
404
+ margin-top: var(--spacing-md);
405
+ margin-bottom: var(--spacing-md);
406
+ border-collapse: collapse;
407
+ font-size: 0.9375em;
408
+ line-height: 1.6;
409
+ }
410
+
411
+ caption {
412
+ margin-bottom: var(--spacing-xs);
413
+ font-size: 0.875em;
414
+ font-weight: 600;
415
+ text-align: left;
416
+ }
417
+
418
+ th,
419
+ td {
420
+ padding: var(--spacing-xs) var(--spacing-sm);
421
+ text-align: left;
422
+ }
423
+
424
+ th {
425
+ font-weight: 600;
426
+ }
427
+
428
+ /* Table sections - structural differentiation */
429
+ thead th {
430
+ vertical-align: bottom;
431
+ }
432
+
433
+ tbody th,
434
+ tbody td {
435
+ vertical-align: top;
436
+ }
437
+
438
+ tfoot th,
439
+ tfoot td {
440
+ vertical-align: top;
441
+ }
442
+
443
+ /* Add spacing between tbody sections if multiple exist */
444
+ tbody + tbody {
445
+ border-top-width: 2px;
446
+ }
447
+
448
+ /* --------------------------------------------------------------------------
449
+ SEPARATORS - Spacing Only
450
+ -------------------------------------------------------------------------- */
451
+
452
+ hr {
453
+ margin-top: var(--spacing-xl);
454
+ margin-bottom: var(--spacing-xl);
455
+ border: 0;
456
+ /* Border style moved to global.css */
457
+ }
458
+
459
+ /* --------------------------------------------------------------------------
460
+ INTERACTIVE ELEMENTS - Accessibility
461
+ -------------------------------------------------------------------------- */
462
+
463
+ :where(:focus, :focus-visible) {
464
+ outline-offset: 2px;
465
+ }
466
+
467
+ details {
468
+ margin-top: var(--spacing-md);
469
+ margin-bottom: var(--spacing-md);
470
+ }
471
+
472
+ summary {
473
+ cursor: pointer;
474
+ font-weight: 600;
475
+ margin-bottom: var(--spacing-xs);
476
+ }
477
+
478
+ /* Dialog element - semantic modal */
479
+ dialog {
480
+ font-size: inherit;
481
+ line-height: inherit;
482
+ }
483
+
484
+ /* --------------------------------------------------------------------------
485
+ UTILITIES - Margin Cleanup
486
+ -------------------------------------------------------------------------- */
487
+
488
+ :where(h1, h2, h3, h4, h5, h6, p, ul, ol, dl, blockquote, figure, table, pre):first-child {
489
+ margin-top: 0;
490
+ }
491
+
492
+ :where(p, ul, ol, dl, blockquote, figure, table, pre):last-child {
493
+ margin-bottom: 0;
494
+ }
495
+
496
+ /* --------------------------------------------------------------------------
497
+ PRINT STYLES - Optimized for Paper
498
+ -------------------------------------------------------------------------- */
499
+
500
+ @media print {
501
+ body {
502
+ font-size: 12pt;
503
+ line-height: 1.5;
504
+ color: #000;
505
+ }
506
+
507
+ :where(h1, h2, h3, h4, h5, h6) {
508
+ break-after: avoid;
509
+ }
510
+
511
+ :where(img, figure, pre, table) {
512
+ break-inside: avoid;
513
+ }
514
+
515
+ a {
516
+ text-decoration: underline;
517
+ }
518
+ }
519
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "clampography",
3
+ "version": "0.9.0",
4
+ "description": "Fluid typography system based on CSS clamp() for Tailwind CSS v4",
5
+ "main": "clampography.css",
6
+ "style": "clampography.css",
7
+ "files": [
8
+ "clampography.css"
9
+ ],
10
+ "keywords": [
11
+ "alternative",
12
+ "blog",
13
+ "clamp",
14
+ "content",
15
+ "css",
16
+ "fluid",
17
+ "fluid-typography",
18
+ "font",
19
+ "font-size",
20
+ "markdown",
21
+ "style",
22
+ "tailwind",
23
+ "tailwind-css",
24
+ "tailwindcss",
25
+ "text",
26
+ "typography"
27
+ ],
28
+ "author": "Dawid Wąsowski",
29
+ "license": "MIT"
30
+ }