bsmnt 0.6.4 → 0.7.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.
Files changed (108) hide show
  1. package/dist/application/add-integration/index.d.ts.map +1 -1
  2. package/dist/application/add-integration/index.js +30 -4
  3. package/dist/application/add-integration/index.js.map +1 -1
  4. package/dist/application/shared/node-version.d.ts +8 -0
  5. package/dist/application/shared/node-version.d.ts.map +1 -0
  6. package/dist/application/shared/node-version.js +31 -0
  7. package/dist/application/shared/node-version.js.map +1 -0
  8. package/dist/application/shared/strip-ansi.d.ts +3 -0
  9. package/dist/application/shared/strip-ansi.d.ts.map +1 -0
  10. package/dist/application/shared/strip-ansi.js +7 -0
  11. package/dist/application/shared/strip-ansi.js.map +1 -0
  12. package/dist/core/create/execute-plan.d.ts +3 -0
  13. package/dist/core/create/execute-plan.d.ts.map +1 -1
  14. package/dist/core/create/execute-plan.js +3 -0
  15. package/dist/core/create/execute-plan.js.map +1 -1
  16. package/dist/domain/cms.d.ts +2 -0
  17. package/dist/domain/cms.d.ts.map +1 -1
  18. package/dist/domain/cms.js +1 -0
  19. package/dist/domain/cms.js.map +1 -1
  20. package/dist/domain/forms.d.ts +2 -2
  21. package/dist/domain/forms.js +1 -1
  22. package/dist/domain/forms.js.map +1 -1
  23. package/dist/domain/integration.d.ts +7 -3
  24. package/dist/domain/integration.d.ts.map +1 -1
  25. package/dist/domain/integration.js.map +1 -1
  26. package/dist/domain/skills.d.ts +26 -8
  27. package/dist/domain/skills.d.ts.map +1 -1
  28. package/dist/domain/skills.js +30 -9
  29. package/dist/domain/skills.js.map +1 -1
  30. package/dist/index.js +132 -16
  31. package/dist/index.js.map +1 -1
  32. package/dist/infrastructure/create/executor.d.ts.map +1 -1
  33. package/dist/infrastructure/create/executor.js +2 -1
  34. package/dist/infrastructure/create/executor.js.map +1 -1
  35. package/dist/infrastructure/create/init-git-repo.d.ts +11 -7
  36. package/dist/infrastructure/create/init-git-repo.d.ts.map +1 -1
  37. package/dist/infrastructure/create/init-git-repo.js +21 -18
  38. package/dist/infrastructure/create/init-git-repo.js.map +1 -1
  39. package/dist/infrastructure/create/sanity-auth.d.ts +11 -0
  40. package/dist/infrastructure/create/sanity-auth.d.ts.map +1 -0
  41. package/dist/infrastructure/create/sanity-auth.js +72 -0
  42. package/dist/infrastructure/create/sanity-auth.js.map +1 -0
  43. package/dist/infrastructure/create/setup-agent.d.ts +4 -3
  44. package/dist/infrastructure/create/setup-agent.d.ts.map +1 -1
  45. package/dist/infrastructure/create/setup-agent.js +51 -30
  46. package/dist/infrastructure/create/setup-agent.js.map +1 -1
  47. package/dist/infrastructure/create/setup-dotenvx.d.ts.map +1 -1
  48. package/dist/infrastructure/create/setup-dotenvx.js +9 -4
  49. package/dist/infrastructure/create/setup-dotenvx.js.map +1 -1
  50. package/dist/infrastructure/create/setup-remote.d.ts +14 -0
  51. package/dist/infrastructure/create/setup-remote.d.ts.map +1 -0
  52. package/dist/infrastructure/create/setup-remote.js +139 -0
  53. package/dist/infrastructure/create/setup-remote.js.map +1 -0
  54. package/dist/infrastructure/create/setup-sanity.d.ts +3 -2
  55. package/dist/infrastructure/create/setup-sanity.d.ts.map +1 -1
  56. package/dist/infrastructure/create/setup-sanity.js +34 -49
  57. package/dist/infrastructure/create/setup-sanity.js.map +1 -1
  58. package/dist/modules/features/env/dotenvx/config.d.ts.map +1 -1
  59. package/dist/modules/features/env/dotenvx/config.js +6 -0
  60. package/dist/modules/features/env/dotenvx/config.js.map +1 -1
  61. package/dist/paths.d.ts +0 -2
  62. package/dist/paths.d.ts.map +1 -1
  63. package/dist/paths.js +0 -2
  64. package/dist/paths.js.map +1 -1
  65. package/package.json +4 -3
  66. package/src/agent-skills/hubspot-pagebuilder-block/SKILL.md +160 -0
  67. package/src/agent-skills/manage-env/SKILL.md +5 -3
  68. package/src/agent-skills/rss-feed/SKILL.md +158 -0
  69. package/src/modules/features/cms/sanity/files/app/blog/[slug]/page.tsx +10 -9
  70. package/src/modules/features/cms/sanity/files/app/blog/page.tsx +5 -5
  71. package/src/modules/features/cms/sanity/files/lib/integrations/sanity/sanity.config.ts +3 -0
  72. package/src/modules/features/cms/sanity/files/lib/scripts/copy-sanity-mcp.ts +6 -6
  73. package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/page-tree-pane.tsx +4 -6
  74. package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/sanity.config.ts +3 -0
  75. package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/redirect.ts +5 -4
  76. package/src/modules/features/cms/sanity-pagebuilder/files/lib/scripts/sanity-typegen.ts +17 -26
  77. package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/json-ld.tsx +1 -0
  78. package/src/modules/features/env/dotenvx/files/decrypt-env.mjs +12 -12
  79. package/src/modules/features/env/dotenvx/files/push-keys.mjs +9 -9
  80. package/src/modules/features/env/dotenvx/files/save-key.mjs +3 -3
  81. package/src/modules/features/env/dotenvx/files/setup-remote.ts +182 -0
  82. package/src/modules/features/env/dotenvx/files/write-env.mjs +6 -6
  83. package/src/modules/features/forms/hubspot/files/_sanity-adapter/form-block.ts +60 -0
  84. package/src/modules/features/forms/hubspot/files/_sanity-adapter/form-field.ts +30 -0
  85. package/src/modules/features/forms/hubspot/files/_sanity-adapter/form-select-input.tsx +169 -0
  86. package/src/modules/features/forms/hubspot/files/lib/integrations/hubspot/README.md +114 -0
  87. package/src/modules/features/forms/hubspot/files/lib/integrations/hubspot/embed.tsx +165 -0
  88. package/src/modules/features/forms/hubspot/files/lib/integrations/hubspot/form-selection.ts +40 -0
  89. package/src/modules/features/forms/hubspot/files/lib/integrations/hubspot/form.tsx +29 -0
  90. package/src/modules/features/forms/hubspot/files/lib/integrations/hubspot/forms.ts +142 -0
  91. package/src/modules/features/forms/hubspot/files/lib/integrations/hubspot/hubspot-form.css +636 -0
  92. package/src/modules/features/forms/hubspot/files/lib/integrations/hubspot/skeleton.tsx +24 -0
  93. package/src/templates/next-default/README.md +1 -0
  94. package/src/templates/next-default/biome.json +1 -1
  95. package/src/templates/next-default/components/basement.svg +1 -1
  96. package/src/templates/next-default/knip.json +9 -1
  97. package/src/templates/next-experiments/README.md +1 -0
  98. package/src/templates/next-experiments/biome.json +1 -1
  99. package/src/templates/next-experiments/components/basement.svg +1 -1
  100. package/src/templates/next-experiments/knip.json +9 -1
  101. package/src/templates/next-pagebuilder/README.md +1 -0
  102. package/src/templates/next-pagebuilder/biome.json +1 -1
  103. package/src/templates/next-pagebuilder/knip.json +7 -2
  104. package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.types.ts +1197 -176
  105. package/src/templates/next-webgl/README.md +1 -0
  106. package/src/templates/next-webgl/biome.json +1 -1
  107. package/src/templates/next-webgl/components/basement.svg +1 -1
  108. package/src/templates/next-webgl/knip.json +9 -1
@@ -0,0 +1,636 @@
1
+ /* biome-ignore-all lint/style/noDescendingSpecificity: selector order follows HubSpot's DOM, not specificity. */
2
+
3
+ /* Styles HubSpot's injected DOM, scoped under `.hubspot-form-wrapper`.
4
+ *
5
+ * Tokens map onto the basement starter design system — `--color-primary`
6
+ * (surface), `--color-secondary` (text), `--color-contrast` (accent) and
7
+ * `--font-mono` — so the form inherits the project's palette and light/dark
8
+ * theme (`[data-theme]`) automatically. Each maps with a standalone fallback
9
+ * for use outside the starter. Override any `--hs-*` from a parent scope to
10
+ * customize. */
11
+
12
+ .hubspot-form-wrapper,
13
+ .hubspot-form-card {
14
+ --hs-surface: var(--color-primary, #ffffff);
15
+ --hs-surface-focus: color-mix(
16
+ in srgb,
17
+ var(--color-secondary, #000000) 8%,
18
+ var(--color-primary, #ffffff)
19
+ );
20
+ --hs-border: color-mix(
21
+ in srgb,
22
+ var(--color-secondary, #000000) 28%,
23
+ transparent
24
+ );
25
+ --hs-card-border: color-mix(
26
+ in srgb,
27
+ var(--color-secondary, #000000) 16%,
28
+ transparent
29
+ );
30
+ --hs-muted: var(--color-gray-400, #858585);
31
+ --hs-text: var(--color-secondary, #18181b);
32
+ --hs-text-strong: var(--color-secondary, #18181b);
33
+ --hs-accent: var(--color-contrast, #ff4d00);
34
+ --hs-accent-contrast: var(--color-primary, #ffffff);
35
+ --hs-error: #ff5c5c;
36
+
37
+ /* Prefer the host's sans font, then its mono (the starter ships mono only),
38
+ * then a system stack. */
39
+ --hs-font-sans: var(
40
+ --font-sans,
41
+ var(--font-mono, ui-sans-serif, system-ui, sans-serif)
42
+ );
43
+ --hs-font-mono: var(--font-mono, ui-monospace, monospace);
44
+ --hs-radius: 4px;
45
+
46
+ /* Grid rhythm: column gap, row gap, inline-error gutter. */
47
+ --hs-col-gap: 1.125rem;
48
+ --hs-row-gap: 0.5rem;
49
+ --hs-error-gutter: 18px;
50
+
51
+ --hs-select-arrow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%23858585'><path d='M5.23 7.21a.75.75 0 011.06.02L10 11.06l3.71-3.83a.75.75 0 111.08 1.04l-4.25 4.39a.75.75 0 01-1.08 0L5.21 8.27a.75.75 0 01.02-1.06z'/></svg>");
52
+ }
53
+
54
+ /* ---------- Card (optional wrapper from <HubSpotForm />) ---------- */
55
+ .hubspot-form-card {
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: 1.5rem;
59
+ width: 100%;
60
+ padding: 1.5rem;
61
+ border: 1px solid var(--hs-card-border);
62
+ border-radius: calc(var(--hs-radius) * 2);
63
+ background: var(--hs-surface);
64
+ }
65
+
66
+ /* ---------- Wrapper ---------- */
67
+ .hubspot-form-wrapper {
68
+ position: relative;
69
+ display: flex;
70
+ flex-direction: column;
71
+ /* Reserve space so remote forms (unmeasurable at SSR) shift the page less. */
72
+ min-height: 400px;
73
+ }
74
+
75
+ .hubspot-form-error {
76
+ text-align: center;
77
+ font-family: var(--hs-font-sans);
78
+ font-size: 0.875rem;
79
+ color: var(--hs-error);
80
+ }
81
+
82
+ /* ---------- Loading skeleton ----------
83
+ * In-flow (flex: 1) so it fills the reserved min-height on desktop and grows
84
+ * the card on mobile, where stacked fields exceed 400px. */
85
+ .hubspot-form-skeleton {
86
+ flex: 1;
87
+ display: flex;
88
+ flex-direction: column;
89
+ gap: 1.5rem;
90
+ pointer-events: none;
91
+ animation: hubspot-form-skeleton-pulse 1.4s ease-in-out infinite;
92
+ }
93
+
94
+ .hubspot-form-skeleton-row {
95
+ display: grid;
96
+ grid-template-columns: 1fr 1fr;
97
+ gap: var(--hs-col-gap);
98
+ }
99
+
100
+ @media (max-width: 767px) {
101
+ .hubspot-form-skeleton-row {
102
+ grid-template-columns: 1fr;
103
+ }
104
+ }
105
+
106
+ /* Label bar (::before) above an input bar (::after), mirroring a real field. */
107
+ .hubspot-form-skeleton-field {
108
+ display: flex;
109
+ flex-direction: column;
110
+ gap: 0.5rem;
111
+ }
112
+
113
+ .hubspot-form-skeleton-field::before {
114
+ content: "";
115
+ width: 40%;
116
+ height: 12px;
117
+ border-radius: var(--hs-radius);
118
+ background: var(--hs-surface-focus);
119
+ }
120
+
121
+ .hubspot-form-skeleton-field::after {
122
+ content: "";
123
+ height: 42px;
124
+ border-radius: var(--hs-radius);
125
+ background: var(--hs-surface-focus);
126
+ }
127
+
128
+ .hubspot-form-skeleton-field--textarea::after {
129
+ height: 118px;
130
+ }
131
+
132
+ /* Sits at the bottom of the reserved area, like the real submit button. */
133
+ .hubspot-form-skeleton-button {
134
+ margin-top: auto;
135
+ height: 32px;
136
+ border-radius: var(--hs-radius);
137
+ background: var(--hs-surface-focus);
138
+ }
139
+
140
+ @keyframes hubspot-form-skeleton-pulse {
141
+ 0%,
142
+ 100% {
143
+ opacity: 1;
144
+ }
145
+ 50% {
146
+ opacity: 0.55;
147
+ }
148
+ }
149
+
150
+ @media (prefers-reduced-motion: reduce) {
151
+ .hubspot-form-skeleton {
152
+ animation: none;
153
+ }
154
+ }
155
+
156
+ /* ---------- Iframe fallback (HubSpot Free portals) ---------- */
157
+ .hubspot-form-embed .hs-form-iframe {
158
+ display: block;
159
+ width: 100%;
160
+ border: 0;
161
+ }
162
+
163
+ /* ---------- Form grid ----------
164
+ * Text fields pair into a 2-col grid; full-width types span both columns. */
165
+ .hubspot-form-embed .hs-form-private {
166
+ position: relative;
167
+ display: grid;
168
+ grid-template-columns: repeat(2, minmax(0, 1fr));
169
+ column-gap: var(--hs-col-gap);
170
+ /* Each field reserves --hs-error-gutter below, so input-to-input spacing is
171
+ * row-gap + gutter. */
172
+ row-gap: var(--hs-row-gap);
173
+ }
174
+
175
+ @media (max-width: 767px) {
176
+ .hubspot-form-embed .hs-form-private {
177
+ grid-template-columns: 1fr;
178
+ }
179
+ }
180
+
181
+ .hubspot-form-embed .hs-form-private > .hs-fieldtype-textarea,
182
+ .hubspot-form-embed .hs-form-private > .hs-fieldtype-booleancheckbox,
183
+ .hubspot-form-embed .hs-form-private > .hs-fieldtype-radio,
184
+ .hubspot-form-embed .hs-form-private > .hs-fieldtype-select,
185
+ .hubspot-form-embed .hs-form-private > .hs-richtext,
186
+ .hubspot-form-embed .hs-form-private > .legal-consent-container,
187
+ .hubspot-form-embed .hs-form-private > .hs_submit,
188
+ /* HubSpot sometimes wraps section-heading rich text in an unnamed <div> that
189
+ * becomes the grid child — span it full width too. */
190
+ .hubspot-form-embed .hs-form-private
191
+ > div:has(> .hs-richtext.hs-main-font-element) {
192
+ grid-column: 1 / -1;
193
+ }
194
+
195
+ /* HubSpot's legacy fieldset layout (fallback). */
196
+ .hubspot-form-embed .hs-form-private fieldset {
197
+ max-width: none;
198
+ border: 0;
199
+ margin: 0;
200
+ padding: 0;
201
+ grid-column: 1 / -1;
202
+ }
203
+
204
+ /* HubSpot V3 wraps fields in `<fieldset>`s; keep the same grid rhythm. */
205
+ .hubspot-form-embed .hs-form-private fieldset.form-columns-1 {
206
+ display: grid;
207
+ grid-template-columns: 1fr;
208
+ row-gap: var(--hs-row-gap);
209
+ }
210
+
211
+ .hubspot-form-embed .hs-form-private fieldset.form-columns-2 {
212
+ display: grid;
213
+ grid-template-columns: 1fr 1fr;
214
+ column-gap: var(--hs-col-gap);
215
+ row-gap: var(--hs-row-gap);
216
+ }
217
+
218
+ .hubspot-form-embed .hs-form-private fieldset > .hs-richtext {
219
+ grid-column: 1 / -1;
220
+ }
221
+
222
+ /* Extra top space above section headings (skip the first child). */
223
+ .hubspot-form-embed .hs-form-private
224
+ > fieldset:has(> .hs-richtext.hs-main-font-element):not(:first-child),
225
+ .hubspot-form-embed
226
+ .hs-form-private
227
+ > div:has(> .hs-richtext.hs-main-font-element):not(:first-child) {
228
+ margin-top: 0.5rem;
229
+ }
230
+
231
+ .hubspot-form-embed .hs-form-private fieldset.form-columns-3 {
232
+ display: grid;
233
+ grid-template-columns: 1fr 1fr 1fr;
234
+ gap: 1.125rem;
235
+ }
236
+
237
+ @media (max-width: 767px) {
238
+ .hubspot-form-embed .hs-form-private fieldset.form-columns-2,
239
+ .hubspot-form-embed .hs-form-private fieldset.form-columns-3 {
240
+ grid-template-columns: 1fr;
241
+ gap: var(--hs-row-gap);
242
+ }
243
+ }
244
+
245
+ .hubspot-form-embed .hs-form-private fieldset .hs-form-field {
246
+ width: 100%;
247
+ float: none;
248
+ /* Keep the bottom error gutter; zero the other sides. */
249
+ padding-left: 0;
250
+ padding-right: 0;
251
+ padding-top: 0;
252
+ padding-bottom: var(--hs-error-gutter);
253
+ }
254
+
255
+ /* Pull HubSpot's tracking inputs/iframes out of the grid so they don't claim
256
+ * cells. */
257
+ .hubspot-form-embed .hs-form-private > input[type="hidden"],
258
+ .hubspot-form-embed .hs-form-private > iframe {
259
+ position: absolute;
260
+ width: 0;
261
+ height: 0;
262
+ pointer-events: none;
263
+ visibility: hidden;
264
+ }
265
+
266
+ /* ---------- Field ----------
267
+ * padding-bottom reserves the error gutter so toggling an error never shifts. */
268
+ .hubspot-form-embed .hs-form-field {
269
+ position: relative;
270
+ display: flex;
271
+ flex-direction: column;
272
+ gap: 0.5rem;
273
+ padding-bottom: var(--hs-error-gutter);
274
+ }
275
+
276
+ .hubspot-form-embed .hs-form-field > .input {
277
+ width: 100%;
278
+ margin: 0;
279
+ }
280
+
281
+ /* ---------- Label ---------- */
282
+ .hubspot-form-embed .hs-form-field > label {
283
+ margin: 0;
284
+ font-family: var(--hs-font-sans);
285
+ font-size: 0.875rem;
286
+ font-weight: 400;
287
+ line-height: 1.2;
288
+ letter-spacing: -0.01em;
289
+ color: var(--hs-text);
290
+ }
291
+
292
+ .hubspot-form-embed .hs-form-required {
293
+ margin-left: 2px;
294
+ color: var(--hs-text);
295
+ }
296
+
297
+ .hubspot-form-embed .hs-field-desc {
298
+ margin: 0;
299
+ font-family: var(--hs-font-sans);
300
+ font-size: 0.75rem;
301
+ line-height: 1.2;
302
+ color: var(--hs-muted);
303
+ }
304
+
305
+ /* ---------- Inputs ---------- */
306
+ .hubspot-form-embed .hs-input {
307
+ display: block;
308
+ box-sizing: border-box;
309
+ width: 100%;
310
+ height: 42px;
311
+ padding: 10px 12px;
312
+ border: 1px solid var(--hs-border);
313
+ border-radius: var(--hs-radius);
314
+ background: var(--hs-surface);
315
+ font-family: var(--hs-font-sans);
316
+ font-size: 0.875rem;
317
+ font-weight: 400;
318
+ line-height: 1.2;
319
+ letter-spacing: -0.01em;
320
+ color: var(--hs-text);
321
+ transition:
322
+ border-color 150ms ease,
323
+ background-color 150ms ease;
324
+ }
325
+
326
+ .hubspot-form-embed .hs-input::placeholder {
327
+ color: var(--hs-muted);
328
+ opacity: 1;
329
+ }
330
+
331
+ .hubspot-form-embed
332
+ .hs-input:hover:not(:disabled):not(.invalid):not(.error):not(:focus) {
333
+ border-color: var(--hs-muted);
334
+ }
335
+
336
+ .hubspot-form-embed .hs-input:focus,
337
+ .hubspot-form-embed .hs-input:focus-visible {
338
+ background: var(--hs-surface-focus);
339
+ border-color: var(--hs-accent);
340
+ outline: none;
341
+ }
342
+
343
+ /* Override autofill's background with an inset shadow to match the focus fill. */
344
+ .hubspot-form-embed .hs-input:-webkit-autofill,
345
+ .hubspot-form-embed .hs-input:-webkit-autofill:hover,
346
+ .hubspot-form-embed .hs-input:-webkit-autofill:focus {
347
+ -webkit-box-shadow: 0 0 0 1000px var(--hs-surface-focus) inset;
348
+ box-shadow: 0 0 0 1000px var(--hs-surface-focus) inset;
349
+ -webkit-text-fill-color: var(--hs-text);
350
+ caret-color: var(--hs-text);
351
+ }
352
+
353
+ .hubspot-form-embed textarea.hs-input {
354
+ min-height: 118px;
355
+ height: 118px;
356
+ padding: 10px 12px;
357
+ resize: none;
358
+ font-family: var(--hs-font-sans);
359
+ }
360
+
361
+ .hubspot-form-embed select.hs-input {
362
+ appearance: none;
363
+ -webkit-appearance: none;
364
+ padding-right: 36px;
365
+ background-image: var(--hs-select-arrow);
366
+ background-repeat: no-repeat;
367
+ background-position: right 10px center;
368
+ background-size: 16px;
369
+ }
370
+
371
+ /* ---------- Checkbox + Radio ---------- */
372
+ .hubspot-form-embed input[type="checkbox"],
373
+ .hubspot-form-embed input[type="radio"] {
374
+ appearance: none;
375
+ -webkit-appearance: none;
376
+ position: relative;
377
+ flex-shrink: 0;
378
+ box-sizing: border-box;
379
+ width: 20px;
380
+ height: 20px;
381
+ margin: 0;
382
+ border: 1.5px solid var(--hs-border);
383
+ background: var(--hs-surface);
384
+ cursor: pointer;
385
+ transition:
386
+ border-color 150ms ease,
387
+ background-color 150ms ease;
388
+ }
389
+
390
+ .hubspot-form-embed input[type="checkbox"] {
391
+ border-radius: var(--hs-radius);
392
+ }
393
+
394
+ .hubspot-form-embed input[type="radio"] {
395
+ border-radius: 50%;
396
+ }
397
+
398
+ .hubspot-form-embed input[type="checkbox"]:hover:not(:disabled),
399
+ .hubspot-form-embed input[type="radio"]:hover:not(:disabled) {
400
+ border-color: var(--hs-muted);
401
+ }
402
+
403
+ .hubspot-form-embed input[type="checkbox"]:focus-visible,
404
+ .hubspot-form-embed input[type="radio"]:focus-visible {
405
+ outline: 2px solid var(--hs-accent);
406
+ outline-offset: 2px;
407
+ }
408
+
409
+ .hubspot-form-embed input[type="checkbox"]:checked,
410
+ .hubspot-form-embed input[type="radio"]:checked {
411
+ border-color: var(--hs-accent);
412
+ background: var(--hs-accent);
413
+ }
414
+
415
+ /* Checkmark glyph (two borders rotated into a tick) */
416
+ .hubspot-form-embed input[type="checkbox"]:checked::after {
417
+ content: "";
418
+ position: absolute;
419
+ top: 50%;
420
+ left: 50%;
421
+ width: 10px;
422
+ height: 5px;
423
+ border-left: 2px solid var(--hs-accent-contrast);
424
+ border-bottom: 2px solid var(--hs-accent-contrast);
425
+ transform: translate(-50%, -65%) rotate(-45deg);
426
+ }
427
+
428
+ /* Radio inner dot */
429
+ .hubspot-form-embed input[type="radio"]:checked::after {
430
+ content: "";
431
+ position: absolute;
432
+ top: 50%;
433
+ left: 50%;
434
+ width: 8px;
435
+ height: 8px;
436
+ border-radius: 50%;
437
+ background: var(--hs-accent-contrast);
438
+ transform: translate(-50%, -50%);
439
+ }
440
+
441
+ .hubspot-form-embed input[type="checkbox"]:disabled,
442
+ .hubspot-form-embed input[type="radio"]:disabled {
443
+ cursor: not-allowed;
444
+ opacity: 0.55;
445
+ }
446
+
447
+ /* Multi-option lists as a 2-col grid; `.input >` avoids matching
448
+ * .hs-error-msgs (also an .inputs-list). */
449
+ .hubspot-form-embed .input > .inputs-list {
450
+ display: grid;
451
+ grid-template-columns: repeat(2, minmax(0, 1fr));
452
+ gap: 0.75rem 1.125rem;
453
+ margin: 0;
454
+ padding: 0;
455
+ list-style: none;
456
+ }
457
+
458
+ .hubspot-form-embed .hs-form-booleancheckbox .input > .inputs-list {
459
+ grid-template-columns: 1fr;
460
+ }
461
+
462
+ @media (max-width: 767px) {
463
+ .hubspot-form-embed .input > .inputs-list {
464
+ grid-template-columns: 1fr;
465
+ }
466
+ }
467
+
468
+ .hubspot-form-embed .input > .inputs-list > li {
469
+ margin: 0;
470
+ padding: 0;
471
+ list-style: none;
472
+ }
473
+
474
+ .hubspot-form-embed .input > .inputs-list label {
475
+ display: inline-flex;
476
+ align-items: center;
477
+ gap: 0.5rem;
478
+ margin: 0;
479
+ font-family: var(--hs-font-sans);
480
+ font-size: 0.875rem;
481
+ line-height: 1.2;
482
+ letter-spacing: -0.01em;
483
+ color: var(--hs-text);
484
+ cursor: pointer;
485
+ }
486
+
487
+ .hubspot-form-embed .input > .inputs-list label > span {
488
+ user-select: none;
489
+ }
490
+
491
+ /* ---------- Errors ---------- */
492
+ /* Collapse HubSpot's empty `.hs_error_rollup`; errors show per-field instead. */
493
+ .hubspot-form-embed .hs_error_rollup {
494
+ display: none;
495
+ }
496
+
497
+ .hubspot-form-embed .hs-input.invalid,
498
+ .hubspot-form-embed .hs-input.error,
499
+ .hubspot-form-embed .hs-form-field.invalid .hs-input {
500
+ border-color: var(--hs-error);
501
+ }
502
+
503
+ /* Absolutely position the error list into the field's reserved gutter. */
504
+ .hubspot-form-embed .hs-error-msgs {
505
+ position: absolute;
506
+ bottom: 0;
507
+ left: 0;
508
+ right: 0;
509
+ margin: 0;
510
+ padding: 0;
511
+ list-style: none;
512
+ line-height: 1.2;
513
+ }
514
+
515
+ .hubspot-form-embed .hs-error-msgs li {
516
+ margin: 0;
517
+ padding: 0;
518
+ list-style: none;
519
+ line-height: 1.2;
520
+ }
521
+
522
+ .hubspot-form-embed .hs-error-msg {
523
+ display: block;
524
+ margin: 0;
525
+ padding: 0;
526
+ font-family: var(--hs-font-sans);
527
+ font-size: 0.75rem;
528
+ font-weight: 400;
529
+ line-height: 1.2;
530
+ letter-spacing: -0.01em;
531
+ color: var(--hs-error);
532
+ }
533
+
534
+ /* ---------- Submit button ---------- */
535
+ .hubspot-form-embed .hs_submit {
536
+ margin: 0;
537
+ }
538
+
539
+ .hubspot-form-embed .hs_submit .actions {
540
+ display: flex;
541
+ width: 100%;
542
+ margin: 0;
543
+ padding: 0;
544
+ }
545
+
546
+ .hubspot-form-embed .hs-button {
547
+ appearance: none;
548
+ -webkit-appearance: none;
549
+ display: inline-flex;
550
+ align-items: center;
551
+ justify-content: center;
552
+ width: 100%;
553
+ height: 40px;
554
+ padding: 8px 16px;
555
+ border: 1px solid var(--hs-accent);
556
+ border-radius: var(--hs-radius);
557
+ background: var(--hs-accent);
558
+ color: var(--hs-accent-contrast);
559
+ font-family: var(--hs-font-mono);
560
+ font-size: 0.875rem;
561
+ font-weight: 400;
562
+ line-height: 1.2;
563
+ letter-spacing: 0;
564
+ text-transform: uppercase;
565
+ cursor: pointer;
566
+ transition: filter 200ms ease;
567
+ }
568
+
569
+ .hubspot-form-embed .hs-button:hover:not(:disabled) {
570
+ filter: brightness(1.1);
571
+ }
572
+
573
+ .hubspot-form-embed .hs-button:focus-visible {
574
+ outline: 2px solid var(--hs-text-strong);
575
+ outline-offset: 2px;
576
+ }
577
+
578
+ .hubspot-form-embed .hs-button:disabled {
579
+ background: var(--hs-surface-focus);
580
+ border-color: var(--hs-border);
581
+ color: var(--hs-muted);
582
+ cursor: not-allowed;
583
+ }
584
+
585
+ /* ---------- Legal consent (centered) ---------- */
586
+ .hubspot-form-embed .legal-consent-container {
587
+ font-family: var(--hs-font-sans);
588
+ font-size: 0.875rem;
589
+ line-height: 1.2;
590
+ letter-spacing: -0.01em;
591
+ color: var(--hs-muted);
592
+ text-align: center;
593
+ }
594
+
595
+ .hubspot-form-embed .legal-consent-container p {
596
+ margin: 0;
597
+ }
598
+
599
+ /* ---------- Rich text (section headings / help copy, left-aligned) ---------- */
600
+ .hubspot-form-embed .hs-richtext {
601
+ margin-bottom: 1rem;
602
+ font-family: var(--hs-font-sans);
603
+ font-size: 0.875rem;
604
+ line-height: 1.4;
605
+ letter-spacing: -0.01em;
606
+ color: var(--hs-muted);
607
+ }
608
+
609
+ .hubspot-form-embed .hs-richtext > * + * {
610
+ margin-top: 0.5rem;
611
+ }
612
+
613
+ .hubspot-form-embed .hs-richtext h1,
614
+ .hubspot-form-embed .hs-richtext h2,
615
+ .hubspot-form-embed .hs-richtext h3,
616
+ .hubspot-form-embed .hs-richtext h4 {
617
+ margin: 0;
618
+ font-family: var(--hs-font-sans);
619
+ font-size: 1.125rem;
620
+ font-weight: 400;
621
+ line-height: 1.2;
622
+ letter-spacing: -0.01em;
623
+ color: var(--hs-muted);
624
+ }
625
+
626
+ .hubspot-form-embed .hs-richtext p {
627
+ margin: 0;
628
+ }
629
+
630
+ .hubspot-form-embed .legal-consent-container a,
631
+ .hubspot-form-embed .hs-richtext a {
632
+ font-weight: 500;
633
+ color: var(--hs-accent);
634
+ text-decoration: underline;
635
+ text-underline-offset: 2px;
636
+ }
@@ -0,0 +1,24 @@
1
+ export function HubSpotFormSkeleton() {
2
+ return (
3
+ <div
4
+ aria-busy="true"
5
+ aria-label="Loading form"
6
+ className="hubspot-form-skeleton"
7
+ role="status"
8
+ >
9
+ <div className="hubspot-form-skeleton-row" aria-hidden="true">
10
+ <span className="hubspot-form-skeleton-field" />
11
+ <span className="hubspot-form-skeleton-field" />
12
+ </div>
13
+ <div className="hubspot-form-skeleton-row" aria-hidden="true">
14
+ <span className="hubspot-form-skeleton-field" />
15
+ <span className="hubspot-form-skeleton-field" />
16
+ </div>
17
+ <span
18
+ aria-hidden="true"
19
+ className="hubspot-form-skeleton-field hubspot-form-skeleton-field--textarea"
20
+ />
21
+ <span aria-hidden="true" className="hubspot-form-skeleton-button" />
22
+ </div>
23
+ )
24
+ }
@@ -27,6 +27,7 @@ bun dev
27
27
  | `bun env:setup` | Restore `.env.keys` from 1Password |
28
28
  | `bun env:view` | Print the decrypted `.env` (`--preview` / `--prod`) |
29
29
  | `bun env:setup-remote` | Push private keys to GitHub / Vercel (`github`/`vercel`, or pick) |
30
+ | `bun setup-remote` | Create the GitHub repo, link a Vercel project, and push the key to Vercel env |
30
31
  | `bun env:save` | Save the private key to 1Password (Development vault) |
31
32
 
32
33
  ## Environment variables
@@ -83,7 +83,7 @@
83
83
  "complexity": {
84
84
  "noForEach": "off",
85
85
  "useFlatMap": "warn",
86
- "useSimplifiedLogicExpression": "warn"
86
+ "useSimplifiedLogicExpression": "off"
87
87
  },
88
88
  "correctness": {
89
89
  "noInvalidUseBeforeDeclaration": "error",
@@ -1 +1 @@
1
- <svg width="123" height="18" viewBox="0 0 123 18" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4.43626 6.76458V.252441H.381348V17.1671H4.33011v-3.0447c.40337 2.1989 1.78331 3.2984 4.13983 3.2984 3.96996 0 4.86166-.9515 4.86166-5.6664V9.91493c0-4.7361-.8704-5.66641-4.64937-5.66641-2.54758 0-3.77892.54973-4.24597 2.51606Zm.02123 5.94122V9.42863c.10615-1.14174.84919-1.69146 2.29282-1.69146 1.95315 0 2.31406.42286 2.31406 2.30463v1.628c0 1.8395-.36091 2.2623-2.31406 2.2623-1.4224 0-2.16544-.4228-2.29282-1.2263Zm10.23281.8035c0 3.4252.7643 4.0384 4.9253 3.9115 1.9956-.0211 3.418-.8035 3.97-2.4949v2.2412h4.0337V8.62519c0-3.70008-.8917-4.37667-5.6259-4.37667h-.9766c-4.9678 0-5.9019.65544-5.9019 4.14409v.50744h4.0337c-.0425-1.45889.3184-1.71261 2.314-1.71261 1.7833 0 2.123.25372 2.123 1.71261v.71887l-4.0337.02114c-4.0973 0-4.8616.61314-4.8616 3.86924Zm4.246.0423c0-.7823.2123-.9303 1.3162-.9303l3.3331-.0212v.5497c0 .9938-.6793 1.3744-2.4627 1.4166h-.2122c-1.656 0-1.9744-.1691-1.9744-1.0148Zm10.0417-.3383c0 3.5309.8917 4.2075 5.5622 4.2075h.9766c5.3499 0 6.3265-.592 6.3265-3.6367 0-1.9451-.4883-3.108-2.5051-3.7-1.104-.31718-2.0805-.5709-4.1611-.90919-1.3799-.21143-1.762-.46515-1.762-.99373 0-.78231.4246-.99374 1.9956-.99374 1.6347 0 2.0805.29601 2.0805 1.33203v.38058h4.0337v-.38058c0-3.61551-.8917-4.27095-5.6259-4.27095h-.9766c-4.8192 0-5.7533.57087-5.7533 3.8058 0 1.69146.4458 2.64288 2.1867 3.31948 1.2738.4863 3.2057.7823 3.9487.9303 1.8682.3383 2.3141.6766 2.3141 1.184 0 .7612-.4883.9726-2.3141.9726-1.9744 0-2.5051-.2748-2.5051-1.2474v-.2749H28.978v.2749Zm14.0967-2.3681c0 5.5396.9765 6.5756 6.1779 6.5756h.9765c5.1589 0 6.1142-.6766 6.1142-4.271h-4.2459c0 1.0784-.3609 1.3109-2.3353 1.3109-2.0593 0-2.4415-.3594-2.4415-2.1989v-.0634h9.1289v-1.9875c0-5.03207-.9766-5.96238-6.2204-5.96238h-.9765c-5.2014 0-6.1779 1.01488-6.1779 6.59668Zm4.2459-1.628v-.06343c0-1.64918.3822-1.96633 2.4415-1.96633 1.9956 0 2.4202.31715 2.4414 2.02976h-4.8829Zm10.9122 7.9499h4.0337V9.83035c0-1.48003.7006-2.22004 2.1017-2.22004 1.6135 0 1.932.31715 1.932 1.96632v7.59047h4.0124l-.0212-7.46361c.0424-1.39546.743-2.09318 2.1017-2.09318 1.6135 0 1.8895.31715 1.8895 1.96632v7.59047h4.0337l-.0212-8.20362c0-3.97494-.7219-4.71496-4.6069-4.71496-2.1443 0-3.4393.90916-3.9063 2.91778-.1699-2.41034-.8705-2.91778-4.0974-2.91778-1.8895 0-2.9722.76116-3.418 2.66406V4.50224h-4.0337V17.1671Zm21.6545-6.3219c0 5.5396.9766 6.5756 6.1991 6.5756h.9766c5.1164 0 6.0717-.6766 6.0717-4.271H88.91c0 1.0784-.3609 1.3109-2.3141 1.3109-2.1017 0-2.4839-.3594-2.4839-2.1989v-.0634h9.1289v-1.9875c0-5.03207-.9766-5.96238-6.1779-5.96238h-.9766c-5.2225 0-6.1991 1.01488-6.1991 6.59668Zm4.2247-1.628v-.06343c0-1.64918.3822-1.96633 2.4839-1.96633 1.9744 0 2.399.31715 2.4202 2.02976H84.112Zm10.891 7.9499h4.0337V9.61892c.0212-1.35317.7642-2.00861 2.2293-2.00861 1.868 0 2.208.35943 2.208 2.30462v7.25217h4.033l-.021-8.20362c0-3.97494-.7-4.71496-4.394-4.71496-2.336 0-3.5671.76116-4.0553 2.81206V4.50224H95.003V17.1671Zm13.545-9.30307h1.252v5.05327c0 3.5732.828 4.2498 5.095 4.2498h2.76v-3.5944h-2.335c-1.253 0-1.486-.2114-1.486-1.2686V7.86403h3.63V4.50224h-3.63V1.77476h-3.821v2.72748h-1.465v3.36179Zm10.636 9.30307h3.63v-3.5944h-3.63v3.5944Z" fill="#EFEFEF"/></svg>
1
+ <svg width="123" height="18" viewBox="0 0 123 18" fill="none" xmlns="http://www.w3.org/2000/svg"><title>basement</title><path d="M4.43626 6.76458V.252441H.381348V17.1671H4.33011v-3.0447c.40337 2.1989 1.78331 3.2984 4.13983 3.2984 3.96996 0 4.86166-.9515 4.86166-5.6664V9.91493c0-4.7361-.8704-5.66641-4.64937-5.66641-2.54758 0-3.77892.54973-4.24597 2.51606Zm.02123 5.94122V9.42863c.10615-1.14174.84919-1.69146 2.29282-1.69146 1.95315 0 2.31406.42286 2.31406 2.30463v1.628c0 1.8395-.36091 2.2623-2.31406 2.2623-1.4224 0-2.16544-.4228-2.29282-1.2263Zm10.23281.8035c0 3.4252.7643 4.0384 4.9253 3.9115 1.9956-.0211 3.418-.8035 3.97-2.4949v2.2412h4.0337V8.62519c0-3.70008-.8917-4.37667-5.6259-4.37667h-.9766c-4.9678 0-5.9019.65544-5.9019 4.14409v.50744h4.0337c-.0425-1.45889.3184-1.71261 2.314-1.71261 1.7833 0 2.123.25372 2.123 1.71261v.71887l-4.0337.02114c-4.0973 0-4.8616.61314-4.8616 3.86924Zm4.246.0423c0-.7823.2123-.9303 1.3162-.9303l3.3331-.0212v.5497c0 .9938-.6793 1.3744-2.4627 1.4166h-.2122c-1.656 0-1.9744-.1691-1.9744-1.0148Zm10.0417-.3383c0 3.5309.8917 4.2075 5.5622 4.2075h.9766c5.3499 0 6.3265-.592 6.3265-3.6367 0-1.9451-.4883-3.108-2.5051-3.7-1.104-.31718-2.0805-.5709-4.1611-.90919-1.3799-.21143-1.762-.46515-1.762-.99373 0-.78231.4246-.99374 1.9956-.99374 1.6347 0 2.0805.29601 2.0805 1.33203v.38058h4.0337v-.38058c0-3.61551-.8917-4.27095-5.6259-4.27095h-.9766c-4.8192 0-5.7533.57087-5.7533 3.8058 0 1.69146.4458 2.64288 2.1867 3.31948 1.2738.4863 3.2057.7823 3.9487.9303 1.8682.3383 2.3141.6766 2.3141 1.184 0 .7612-.4883.9726-2.3141.9726-1.9744 0-2.5051-.2748-2.5051-1.2474v-.2749H28.978v.2749Zm14.0967-2.3681c0 5.5396.9765 6.5756 6.1779 6.5756h.9765c5.1589 0 6.1142-.6766 6.1142-4.271h-4.2459c0 1.0784-.3609 1.3109-2.3353 1.3109-2.0593 0-2.4415-.3594-2.4415-2.1989v-.0634h9.1289v-1.9875c0-5.03207-.9766-5.96238-6.2204-5.96238h-.9765c-5.2014 0-6.1779 1.01488-6.1779 6.59668Zm4.2459-1.628v-.06343c0-1.64918.3822-1.96633 2.4415-1.96633 1.9956 0 2.4202.31715 2.4414 2.02976h-4.8829Zm10.9122 7.9499h4.0337V9.83035c0-1.48003.7006-2.22004 2.1017-2.22004 1.6135 0 1.932.31715 1.932 1.96632v7.59047h4.0124l-.0212-7.46361c.0424-1.39546.743-2.09318 2.1017-2.09318 1.6135 0 1.8895.31715 1.8895 1.96632v7.59047h4.0337l-.0212-8.20362c0-3.97494-.7219-4.71496-4.6069-4.71496-2.1443 0-3.4393.90916-3.9063 2.91778-.1699-2.41034-.8705-2.91778-4.0974-2.91778-1.8895 0-2.9722.76116-3.418 2.66406V4.50224h-4.0337V17.1671Zm21.6545-6.3219c0 5.5396.9766 6.5756 6.1991 6.5756h.9766c5.1164 0 6.0717-.6766 6.0717-4.271H88.91c0 1.0784-.3609 1.3109-2.3141 1.3109-2.1017 0-2.4839-.3594-2.4839-2.1989v-.0634h9.1289v-1.9875c0-5.03207-.9766-5.96238-6.1779-5.96238h-.9766c-5.2225 0-6.1991 1.01488-6.1991 6.59668Zm4.2247-1.628v-.06343c0-1.64918.3822-1.96633 2.4839-1.96633 1.9744 0 2.399.31715 2.4202 2.02976H84.112Zm10.891 7.9499h4.0337V9.61892c.0212-1.35317.7642-2.00861 2.2293-2.00861 1.868 0 2.208.35943 2.208 2.30462v7.25217h4.033l-.021-8.20362c0-3.97494-.7-4.71496-4.394-4.71496-2.336 0-3.5671.76116-4.0553 2.81206V4.50224H95.003V17.1671Zm13.545-9.30307h1.252v5.05327c0 3.5732.828 4.2498 5.095 4.2498h2.76v-3.5944h-2.335c-1.253 0-1.486-.2114-1.486-1.2686V7.86403h3.63V4.50224h-3.63V1.77476h-3.821v2.72748h-1.465v3.36179Zm10.636 9.30307h3.63v-3.5944h-3.63v3.5944Z" fill="#EFEFEF"/></svg>
@@ -9,6 +9,14 @@
9
9
  ],
10
10
  "ignoreDependencies": [
11
11
  "zod",
12
- "@svgr/webpack"
12
+ "@svgr/webpack",
13
+ "gsap",
14
+ "@gsap/react",
15
+ "motion"
16
+ ],
17
+ "ignoreBinaries": [
18
+ "op",
19
+ "gh",
20
+ "vercel"
13
21
  ]
14
22
  }