@techrox/page-studio-blocks 1.0.0 → 1.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techrox/page-studio-blocks",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "50 production-ready content blocks (Hero, Pricing, FAQ, Contact, …) plus the Puck config builder for @techrox/page-studio. SSR-safe, brand-themable via CSS variables, host-extensible.",
5
5
  "license": "MIT",
6
6
  "author": "techrox",
package/src/styles.css CHANGED
@@ -1,21 +1,275 @@
1
- /* @techrox/page-studio-blocks — minimal CSS the picker UI + reveal animations
2
- * need at runtime. Block typography classes (.tps-h1, .tps-section, etc.) are
3
- * NOT shipped here — host applications provide them via their own stylesheet.
4
- * See README "Required host CSS" for the list of classes blocks reference.
1
+ /* @techrox/page-studio-blocks — base styles for the block library.
5
2
  *
6
- * All CSS variables are defaulted to neutral values so the package looks
7
- * sane without theming. Override at :root in your host to rebrand. */
3
+ * Includes:
4
+ * - CSS variable defaults (override at :root in your host to theme)
5
+ * - Layout primitives (.tps-container, .tps-section, .tps-h1, …) that
6
+ * block render functions reference at runtime
7
+ * - Picker UI styles
8
+ * - Scroll-reveal animations */
8
9
 
9
10
  :root {
10
- --tps-primary: #0b60d8;
11
- --tps-primary-dark: #0848a3;
12
- --tps-accent: #f59e0b;
13
- --tps-ink: #0f172a;
14
- --tps-muted: #64748b;
15
- --tps-line: #e2e8f0;
16
- --tps-bg: #fafaf7;
17
- --tps-bg-soft: #f8fafc;
18
- --tps-radius: 8px;
11
+ --tps-primary: #0b60d8;
12
+ --tps-primary-dark: #0848a3;
13
+ --tps-primary-light: #3b82f6;
14
+ --tps-primary-soft: #dbeafe;
15
+ --tps-accent: #f59e0b;
16
+ --tps-accent-dark: #d97706;
17
+ --tps-ink: #0f172a;
18
+ --tps-ink-2: #334155;
19
+ --tps-muted: #64748b;
20
+ --tps-hint: #94a3b8;
21
+ --tps-line: #e2e8f0;
22
+ --tps-bg: #ffffff;
23
+ --tps-bg-soft: #fafaf7;
24
+ --tps-bg-section: #f8fafc;
25
+ --tps-max: 1240px;
26
+ --tps-radius: 14px;
27
+ --tps-radius-lg: 20px;
28
+ }
29
+
30
+ /* -------------------------------------------------------------------------
31
+ Layout primitives — referenced by block render functions
32
+ ------------------------------------------------------------------------- */
33
+ .tps-container {
34
+ max-width: var(--tps-max);
35
+ margin: 0 auto;
36
+ padding: 0 24px;
37
+ }
38
+
39
+ .tps-section {
40
+ padding: clamp(64px, 8vw, 112px) 24px;
41
+ }
42
+
43
+ .tps-section-soft {
44
+ background: var(--tps-bg-soft);
45
+ }
46
+
47
+ /* -------------------------------------------------------------------------
48
+ Themes
49
+ -------------------------------------------------------------------------
50
+ A theme is nothing more than a re-scoped set of the *neutral* tokens
51
+ (ink / muted / line / bg / …). Brand tokens (--tps-primary, --tps-accent)
52
+ are deliberately left alone, so every vendor keeps its hue in every theme.
53
+
54
+ Apply a theme by setting `data-tps-theme="<name>"` on ANY container — the
55
+ renderer root, a page wrapper, a single section. Every descendant block
56
+ reads var(--tps-*) and re-paints automatically: no per-block code, no
57
+ re-render, just the CSS cascade. That's the whole mechanism, and it scales
58
+ — adding a new theme is one rule below, nothing else changes.
59
+
60
+ <div data-tps-theme="dark"> … blocks … </div>
61
+
62
+ The same token set also backs the per-section opt-in `background:'dark'`
63
+ (.tps-section-dark) so a single light page can drop one dark section.
64
+
65
+ To ADD a theme (e.g. "sepia"): copy the dark rule, rename the selector to
66
+ `[data-tps-theme="sepia"], .tps-section-sepia`, and change the values.
67
+ Nothing in the blocks needs to know the theme exists.
68
+ ------------------------------------------------------------------------- */
69
+
70
+ /* Explicit light = the :root defaults, restated so a light island can be
71
+ nested inside a dark container via data-tps-theme="light". */
72
+ [data-tps-theme="light"] {
73
+ --tps-ink: #0f172a;
74
+ --tps-ink-2: #334155;
75
+ --tps-muted: #64748b;
76
+ --tps-hint: #94a3b8;
77
+ --tps-line: #e2e8f0;
78
+ --tps-bg: #ffffff;
79
+ --tps-bg-soft: #fafaf7;
80
+ --tps-bg-section: #f8fafc;
81
+ }
82
+
83
+ /* Dark theme. Shared by the container scope and the per-section opt-in. */
84
+ [data-tps-theme="dark"],
85
+ .tps-section-dark {
86
+ --tps-ink: #f1f5f9;
87
+ --tps-ink-2: #cbd5e1;
88
+ --tps-muted: #94a3b8;
89
+ --tps-hint: #64748b;
90
+ --tps-line: #262626;
91
+ --tps-bg: #141414;
92
+ --tps-bg-soft: #1a1a1a;
93
+ --tps-bg-section: #0a0a0a;
94
+ --tps-primary-soft: #1a1a1a;
95
+ }
96
+ /* A container theme paints its own backdrop; the per-section variant paints
97
+ its surface (it's a section wrapper, not just a token scope). */
98
+ [data-tps-theme="dark"] {
99
+ background: var(--tps-bg-section);
100
+ color: var(--tps-ink);
101
+ }
102
+ .tps-section-dark {
103
+ background: #0a0a0a;
104
+ color: var(--tps-ink);
105
+ }
106
+ /* Eyebrows are primary by default — low contrast on dark, so flip to accent. */
107
+ [data-tps-theme="dark"] .tps-eyebrow,
108
+ .tps-section-dark .tps-eyebrow {
109
+ color: var(--tps-accent);
110
+ }
111
+ /* AntD form controls on a dark surface (form blocks). */
112
+ [data-tps-theme="dark"] .ant-input,
113
+ [data-tps-theme="dark"] .ant-input-number,
114
+ [data-tps-theme="dark"] .ant-input-affix-wrapper,
115
+ [data-tps-theme="dark"] .ant-picker,
116
+ [data-tps-theme="dark"] .ant-select-selector,
117
+ .tps-section-dark .ant-input,
118
+ .tps-section-dark .ant-input-number,
119
+ .tps-section-dark .ant-input-affix-wrapper,
120
+ .tps-section-dark .ant-picker,
121
+ .tps-section-dark .ant-select-selector {
122
+ background: #1a1a1a !important;
123
+ border-color: #2e2e2e !important;
124
+ color: #f1f5f9 !important;
125
+ }
126
+ [data-tps-theme="dark"] .ant-input::placeholder,
127
+ [data-tps-theme="dark"] .ant-select-selection-placeholder,
128
+ [data-tps-theme="dark"] .ant-picker-input > input::placeholder,
129
+ .tps-section-dark .ant-input::placeholder,
130
+ .tps-section-dark .ant-select-selection-placeholder,
131
+ .tps-section-dark .ant-picker-input > input::placeholder {
132
+ color: #64748b !important;
133
+ }
134
+ [data-tps-theme="dark"] .ant-form-item-label > label,
135
+ [data-tps-theme="dark"] .ant-checkbox-wrapper,
136
+ [data-tps-theme="dark"] .ant-radio-wrapper,
137
+ .tps-section-dark .ant-form-item-label > label,
138
+ .tps-section-dark .ant-checkbox-wrapper,
139
+ .tps-section-dark .ant-radio-wrapper {
140
+ color: #cbd5e1 !important;
141
+ }
142
+
143
+ .tps-eyebrow {
144
+ display: inline-block;
145
+ font-size: 12px;
146
+ font-weight: 700;
147
+ letter-spacing: 2px;
148
+ text-transform: uppercase;
149
+ color: var(--tps-primary);
150
+ margin-bottom: 16px;
151
+ }
152
+
153
+ .tps-h1 {
154
+ font-size: clamp(36px, 5.5vw, 60px);
155
+ letter-spacing: -0.02em;
156
+ color: var(--tps-ink);
157
+ margin: 0 0 16px;
158
+ font-weight: 800;
159
+ line-height: 1.15;
160
+ }
161
+
162
+ .tps-h2 {
163
+ font-size: clamp(28px, 4vw, 42px);
164
+ letter-spacing: -0.02em;
165
+ color: var(--tps-ink);
166
+ margin: 0 0 16px;
167
+ font-weight: 800;
168
+ line-height: 1.15;
169
+ }
170
+
171
+ .tps-h3 {
172
+ font-size: clamp(22px, 2.5vw, 28px);
173
+ letter-spacing: -0.02em;
174
+ color: var(--tps-ink);
175
+ margin: 0 0 16px;
176
+ font-weight: 800;
177
+ line-height: 1.15;
178
+ }
179
+
180
+ .tps-lede {
181
+ font-size: clamp(16px, 1.5vw, 19px);
182
+ line-height: 1.65;
183
+ color: var(--tps-muted);
184
+ max-width: 720px;
185
+ margin: 0 0 28px;
186
+ }
187
+
188
+ /* Hero — soft radial glow in primary + accent colours, dot-grid overlay */
189
+ .tps-hero {
190
+ position: relative;
191
+ padding: clamp(72px, 10vw, 128px) 24px clamp(64px, 8vw, 112px);
192
+ background:
193
+ radial-gradient(1100px 480px at 8% -10%, rgba(11, 96, 216, 0.06), transparent 60%),
194
+ radial-gradient(900px 420px at 100% 0%, rgba(245, 158, 11, 0.04), transparent 60%),
195
+ var(--tps-bg);
196
+ overflow: hidden;
197
+ }
198
+
199
+ .tps-hero::before {
200
+ content: '';
201
+ position: absolute;
202
+ inset: 0;
203
+ background-image: radial-gradient(
204
+ circle at 1px 1px,
205
+ rgba(15, 23, 42, 0.04) 1px,
206
+ transparent 0
207
+ );
208
+ background-size: 24px 24px;
209
+ mask-image: radial-gradient(ellipse 70% 50% at 50% 30%, #000 30%, transparent 70%);
210
+ -webkit-mask-image: radial-gradient(ellipse 70% 50% at 50% 30%, #000 30%, transparent 70%);
211
+ pointer-events: none;
212
+ }
213
+
214
+ .tps-hero-inner {
215
+ position: relative;
216
+ max-width: var(--tps-max);
217
+ margin: 0 auto;
218
+ }
219
+
220
+ /* <em> inside a hero heading renders as a gradient text fill */
221
+ .tps-hero h1 em {
222
+ font-style: normal;
223
+ background: linear-gradient(
224
+ 120deg,
225
+ var(--tps-primary) 0%,
226
+ var(--tps-primary-light) 100%
227
+ );
228
+ -webkit-background-clip: text;
229
+ background-clip: text;
230
+ -webkit-text-fill-color: transparent;
231
+ color: transparent;
232
+ }
233
+
234
+ .tps-service-icon {
235
+ display: inline-flex;
236
+ align-items: center;
237
+ justify-content: center;
238
+ width: 48px;
239
+ height: 48px;
240
+ border-radius: 12px;
241
+ background: var(--tps-primary-soft);
242
+ color: var(--tps-primary);
243
+ font-size: 22px;
244
+ margin-bottom: 18px;
245
+ }
246
+
247
+ .tps-service-hero {
248
+ background: linear-gradient(180deg, var(--tps-bg) 0%, var(--tps-bg-soft) 100%);
249
+ padding: clamp(60px, 8vw, 96px) 24px clamp(40px, 5vw, 64px);
250
+ border-bottom: 1px solid var(--tps-line);
251
+ }
252
+
253
+ .tps-form-card {
254
+ background: var(--tps-bg);
255
+ border: 1px solid var(--tps-line);
256
+ border-radius: var(--tps-radius);
257
+ padding: clamp(24px, 4vw, 40px);
258
+ }
259
+
260
+ .tps-overlay-card {
261
+ position: relative;
262
+ overflow: hidden;
263
+ border-radius: var(--tps-radius);
264
+ }
265
+
266
+ .tps-card-hover {
267
+ transition: transform 200ms ease, box-shadow 200ms ease;
268
+ }
269
+
270
+ .tps-card-hover:hover {
271
+ transform: translateY(-2px);
272
+ box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
19
273
  }
20
274
 
21
275
  /* --- Picker block-card (drawerItem override) ---------------------------- */
@@ -45,7 +299,7 @@
45
299
  padding: 0;
46
300
  border: 1px solid var(--tps-line);
47
301
  border-radius: var(--tps-radius);
48
- background: #fff;
302
+ background: var(--tps-bg);
49
303
  overflow: hidden;
50
304
  transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
51
305
  }