@domandigital/craft 0.1.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/css/craft.css ADDED
@@ -0,0 +1,145 @@
1
+ /*
2
+ * @domandigital/craft — base stylesheet.
3
+ *
4
+ * Works with or without Tailwind. Nothing here depends on a build step, a
5
+ * preprocessor, or a utility class layer; it is the typographic and interaction
6
+ * floor every Doman Digital surface stands on.
7
+ *
8
+ * Pair with the generated token block (see `craftTokens()`), which supplies the
9
+ * `--craft-*` custom properties this file references.
10
+ */
11
+
12
+ /* ---------------------------------------------------------------------------
13
+ * Typography floor
14
+ * ------------------------------------------------------------------------- */
15
+
16
+ html {
17
+ /* Kerning and ligatures are off by default in several engines at body sizes.
18
+ Turning them on is the single cheapest legibility win available. */
19
+ font-kerning: normal;
20
+ font-optical-sizing: auto;
21
+ text-rendering: optimizeLegibility;
22
+ }
23
+
24
+ /* A heading that wraps one word onto its own line looks like a mistake.
25
+ `balance` evens the lines; it is capped at ~6 lines by the spec, which is why
26
+ it is scoped to headings and not applied to body copy. */
27
+ h1,
28
+ h2,
29
+ h3,
30
+ h4,
31
+ h5,
32
+ h6,
33
+ .craft-balance {
34
+ text-wrap: balance;
35
+ }
36
+
37
+ /* `pretty` is the body-copy counterpart: it only prevents orphans, so it stays
38
+ cheap on long text where `balance` would not. */
39
+ p,
40
+ li,
41
+ figcaption,
42
+ blockquote {
43
+ text-wrap: pretty;
44
+ }
45
+
46
+ .craft-prose {
47
+ max-inline-size: var(--craft-measure-body, 65ch);
48
+ hanging-punctuation: first last;
49
+ }
50
+
51
+ .craft-measure-narrow {
52
+ max-inline-size: var(--craft-measure-narrow, 45ch);
53
+ }
54
+
55
+ .craft-measure-wide {
56
+ max-inline-size: var(--craft-measure-wide, 75ch);
57
+ }
58
+
59
+ /* Numbers in a column must line up. Proportional figures in a table are the
60
+ tell that nobody looked at the table. */
61
+ .craft-numeric,
62
+ [data-numeric] {
63
+ font-variant-numeric: lining-nums tabular-nums;
64
+ text-align: end;
65
+ }
66
+
67
+ /*
68
+ * Descender mask.
69
+ *
70
+ * A tight display line clipped by `overflow: hidden` (a reveal wrapper, a
71
+ * gradient text fill) loses the tails of g, j, p, q and y. Padding the box and
72
+ * pulling the same amount back off the margin gives the descenders room without
73
+ * moving anything on the page.
74
+ */
75
+ .craft-descender-mask {
76
+ padding-bottom: 0.16em;
77
+ margin-bottom: -0.16em;
78
+ }
79
+
80
+ /* ---------------------------------------------------------------------------
81
+ * Interaction
82
+ * ------------------------------------------------------------------------- */
83
+
84
+ .craft-press {
85
+ transition: transform var(--craft-duration-press, 120ms)
86
+ var(--craft-ease-out, cubic-bezier(0.23, 1, 0.32, 1));
87
+ }
88
+
89
+ .craft-press:active {
90
+ transform: scale(var(--craft-scale-press, 0.97));
91
+ }
92
+
93
+ /* Hover affordances only where hover exists. On touch, a hover-lift fires on tap
94
+ and sticks, which reads as a stuck element rather than feedback. */
95
+ @media (hover: hover) and (pointer: fine) {
96
+ .craft-hover-lift {
97
+ transition:
98
+ transform var(--craft-duration-dropdown, 200ms)
99
+ var(--craft-ease-out, cubic-bezier(0.23, 1, 0.32, 1)),
100
+ box-shadow var(--craft-duration-dropdown, 200ms)
101
+ var(--craft-ease-out, cubic-bezier(0.23, 1, 0.32, 1));
102
+ }
103
+
104
+ .craft-hover-lift:hover {
105
+ transform: translateY(-2px);
106
+ }
107
+ }
108
+
109
+ /* ---------------------------------------------------------------------------
110
+ * Motion budget, rule 1: the LCP element never animates.
111
+ *
112
+ * Whatever the largest contentful paint turns out to be, animating it delays the
113
+ * metric by exactly the animation's duration. Mark it and it is held still.
114
+ * ------------------------------------------------------------------------- */
115
+
116
+ [data-craft-lcp] {
117
+ animation: none !important;
118
+ transition: none !important;
119
+ }
120
+
121
+ /* ---------------------------------------------------------------------------
122
+ * Reduced motion.
123
+ *
124
+ * COLLAPSE durations. Never `animation: none`.
125
+ *
126
+ * This is not a style preference. A forwards-filled entrance keyframe starts at
127
+ * `opacity: 0` and ends at `opacity: 1`; `animation: none` removes the animation
128
+ * *and* its fill, so the element keeps the `opacity: 0` from its own base rule
129
+ * and the content is invisible — permanently, for exactly the users who asked
130
+ * for less motion. Collapsing the duration to 0.01ms runs the animation to
131
+ * completion within a frame, so the end state applies and nothing moves.
132
+ * ------------------------------------------------------------------------- */
133
+
134
+ @media (prefers-reduced-motion: reduce) {
135
+ *,
136
+ *::before,
137
+ *::after {
138
+ animation-duration: 0.01ms !important;
139
+ animation-delay: 0ms !important;
140
+ animation-iteration-count: 1 !important;
141
+ transition-duration: 0.01ms !important;
142
+ transition-delay: 0ms !important;
143
+ scroll-behavior: auto !important;
144
+ }
145
+ }
@@ -0,0 +1,97 @@
1
+ /*
2
+ * @domandigital/craft — Tailwind v4 theme bridge.
3
+ * Generated by `tailwindV4Theme()`. Import after craft.css and your token file.
4
+ *
5
+ * `@theme inline` is required rather than optional: without `inline`, Tailwind
6
+ * copies the value at build time and a runtime override of the underlying
7
+ * custom property never reaches the generated utility.
8
+ */
9
+
10
+ @theme inline {
11
+ --color-bg-canvas: var(--craft-bg-canvas);
12
+ --color-bg-base: var(--craft-bg-base);
13
+ --color-bg-surface: var(--craft-bg-surface);
14
+ --color-bg-elevated: var(--craft-bg-elevated);
15
+ --color-text-primary: var(--craft-text-primary);
16
+ --color-text-secondary: var(--craft-text-secondary);
17
+ --color-text-muted: var(--craft-text-muted);
18
+ --color-text-on-accent: var(--craft-text-on-accent);
19
+ --color-border-subtle: var(--craft-border-subtle);
20
+ --color-border-strong: var(--craft-border-strong);
21
+ --color-accent: var(--craft-accent);
22
+ --color-accent-hover: var(--craft-accent-hover);
23
+ --color-accent-soft: var(--craft-accent-soft);
24
+ --color-accent-text: var(--craft-accent-text);
25
+ --color-success: var(--craft-success);
26
+ --color-warning: var(--craft-warning);
27
+ --color-danger: var(--craft-danger);
28
+ --color-info: var(--craft-info);
29
+ --text-step--2: var(--craft-step--2);
30
+ --text-step--1: var(--craft-step--1);
31
+ --text-step-0: var(--craft-step-0);
32
+ --text-step-1: var(--craft-step-1);
33
+ --text-step-2: var(--craft-step-2);
34
+ --text-step-3: var(--craft-step-3);
35
+ --text-step-4: var(--craft-step-4);
36
+ --text-step-5: var(--craft-step-5);
37
+ --spacing-3xs: var(--craft-space-3xs);
38
+ --spacing-2xs: var(--craft-space-2xs);
39
+ --spacing-xs: var(--craft-space-xs);
40
+ --spacing-s: var(--craft-space-s);
41
+ --spacing-m: var(--craft-space-m);
42
+ --spacing-l: var(--craft-space-l);
43
+ --spacing-xl: var(--craft-space-xl);
44
+ --spacing-2xl: var(--craft-space-2xl);
45
+ --spacing-3xl: var(--craft-space-3xl);
46
+ --spacing-section-sm: var(--craft-section-sm);
47
+ --spacing-section-md: var(--craft-section-md);
48
+ --spacing-section-lg: var(--craft-section-lg);
49
+ --ease-out: var(--craft-ease-out);
50
+ --ease-in-out: var(--craft-ease-in-out);
51
+ --ease-drawer: var(--craft-ease-drawer);
52
+ --ease-reveal: var(--craft-ease-reveal);
53
+ --duration-press: var(--craft-duration-press);
54
+ --duration-tooltip: var(--craft-duration-tooltip);
55
+ --duration-dropdown: var(--craft-duration-dropdown);
56
+ --duration-modal: var(--craft-duration-modal);
57
+ --duration-drawer: var(--craft-duration-drawer);
58
+ --duration-reveal: var(--craft-duration-reveal);
59
+ --duration-stagger: var(--craft-duration-stagger);
60
+ --tracking-display: var(--craft-tracking-display);
61
+ --tracking-heading: var(--craft-tracking-heading);
62
+ --tracking-body: var(--craft-tracking-body);
63
+ --tracking-button: var(--craft-tracking-button);
64
+ --tracking-eyebrow: var(--craft-tracking-eyebrow);
65
+ --leading-display: var(--craft-leading-display);
66
+ --leading-heading: var(--craft-leading-heading);
67
+ --leading-subheading: var(--craft-leading-subheading);
68
+ --leading-body: var(--craft-leading-body);
69
+ }
70
+
71
+ :root {
72
+ --craft-density-row: 2.5rem;
73
+ --craft-density-pad-x: 0.75rem;
74
+ --craft-density-pad-y: 0.5rem;
75
+ --craft-density-font: 0.875rem;
76
+ }
77
+
78
+ [data-density="compact"] {
79
+ --craft-density-row: 2rem;
80
+ --craft-density-pad-x: 0.5rem;
81
+ --craft-density-pad-y: 0.25rem;
82
+ --craft-density-font: 0.8125rem;
83
+ }
84
+
85
+ [data-density="comfortable"] {
86
+ --craft-density-row: 2.5rem;
87
+ --craft-density-pad-x: 0.75rem;
88
+ --craft-density-pad-y: 0.5rem;
89
+ --craft-density-font: 0.875rem;
90
+ }
91
+
92
+ [data-density="spacious"] {
93
+ --craft-density-row: 3rem;
94
+ --craft-density-pad-x: 1rem;
95
+ --craft-density-pad-y: 0.75rem;
96
+ --craft-density-font: 0.9375rem;
97
+ }