@treeseed/core 0.8.8 → 0.8.9
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/dist/components/content/ContentStatusLegend.astro +4 -4
- package/dist/components/docs/BookFontControls.astro +9 -9
- package/dist/components/docs/DesktopSidebarToggle.astro +8 -8
- package/dist/components/docs/Footer.astro +6 -6
- package/dist/components/docs/PageTitle.astro +1 -1
- package/dist/components/docs/ThemeSelect.astro +3 -1
- package/dist/components/forms/ContactForm.astro +21 -21
- package/dist/components/forms/FooterSubscribeForm.astro +9 -9
- package/dist/components/site/BookList.astro +7 -7
- package/dist/components/site/CTASection.astro +4 -4
- package/dist/components/site/ChronicleList.astro +6 -6
- package/dist/components/site/Hero.astro +3 -3
- package/dist/components/site/PathCard.astro +5 -5
- package/dist/components/site/ProfileList.astro +5 -5
- package/dist/components/site/RouteNotFound.astro +5 -5
- package/dist/components/site/SectionIntro.astro +3 -3
- package/dist/components/site/StageBanner.astro +2 -2
- package/dist/components/site/TrustCallout.astro +3 -3
- package/dist/components/ui/data/ActionList.astro +51 -0
- package/dist/components/ui/data/Badge.astro +19 -0
- package/dist/components/ui/data/DataTable.astro +51 -0
- package/dist/components/ui/data/KeyValueList.astro +28 -0
- package/dist/components/ui/data/MetricCard.astro +25 -0
- package/dist/components/ui/data/MetricGrid.astro +27 -0
- package/dist/components/ui/data/StatusPill.astro +20 -0
- package/dist/components/ui/forms/Button.astro +52 -0
- package/dist/components/ui/forms/Field.astro +39 -0
- package/dist/components/ui/forms/FormActions.astro +12 -0
- package/dist/components/ui/forms/PasswordMeter.astro +80 -0
- package/dist/components/ui/forms/RadioGroup.astro +55 -0
- package/dist/components/ui/forms/Select.astro +44 -0
- package/dist/components/ui/forms/TextInput.astro +58 -0
- package/dist/components/ui/forms/Textarea.astro +45 -0
- package/dist/components/ui/layout/PageHeader.astro +45 -0
- package/dist/components/ui/shell/AppShell.astro +110 -0
- package/dist/components/ui/shell/BottomNav.astro +35 -0
- package/dist/components/ui/shell/ProjectHeader.astro +66 -0
- package/dist/components/ui/shell/PublicShell.astro +108 -0
- package/dist/components/ui/shell/RailNav.astro +35 -0
- package/dist/components/ui/shell/TopBar.astro +52 -0
- package/dist/components/ui/surface/Card.astro +46 -0
- package/dist/components/ui/surface/EmptyState.astro +45 -0
- package/dist/components/ui/surface/Panel.astro +54 -0
- package/dist/components/ui/theme/ThemeMenu.astro +32 -0
- package/dist/components/ui/theme/ThemePreviewSwatch.astro +18 -0
- package/dist/components/ui/theme/ThemeScript.astro +105 -0
- package/dist/components/ui/theme/ThemeSelector.astro +202 -0
- package/dist/components/ui/types.js +0 -0
- package/dist/dev.js +14 -2
- package/dist/layouts/AuthoredEntryLayout.astro +27 -27
- package/dist/layouts/BookLayout.astro +10 -10
- package/dist/layouts/ContentLayout.astro +4 -4
- package/dist/layouts/MainLayout.astro +27 -25
- package/dist/layouts/NoteLayout.astro +6 -6
- package/dist/layouts/ProfileLayout.astro +17 -17
- package/dist/pages/404.astro +6 -6
- package/dist/pages/contact.astro +4 -4
- package/dist/pages/docs-runtime/[...slug].astro +12 -12
- package/dist/pages/docs-runtime/index.astro +13 -13
- package/dist/pages/index.astro +28 -28
- package/dist/pages/ui/index.astro +216 -0
- package/dist/site.js +3 -2
- package/dist/styles/app-shell.css +398 -0
- package/dist/styles/forms.css +258 -0
- package/dist/styles/global.css +119 -119
- package/dist/styles/prose.css +11 -11
- package/dist/styles/theme.css +177 -0
- package/dist/styles/tokens.css +62 -22
- package/dist/styles/ui.css +551 -0
- package/dist/utils/content-status.js +5 -5
- package/dist/utils/site-config.js +2 -2
- package/dist/utils/theme.js +352 -40
- package/package.json +35 -2
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import { CONTENT_STATUSES, CONTENT_STATUS_META } from '../../utils/content-status';
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
<section class="border-t border-[color:var(--
|
|
6
|
-
<p class="text-sm font-semibold uppercase tracking-[0.18em] text-[color:var(--
|
|
5
|
+
<section class="border-t border-[color:var(--ts-color-border-strong)] pt-8">
|
|
6
|
+
<p class="text-sm font-semibold uppercase tracking-[0.18em] text-[color:var(--ts-color-accent-strong)]">Content status legend</p>
|
|
7
7
|
<div class="mt-5 grid gap-3 md:grid-cols-2 xl:grid-cols-5">
|
|
8
8
|
{CONTENT_STATUSES.map((status) => {
|
|
9
9
|
const meta = CONTENT_STATUS_META[status];
|
|
10
10
|
return (
|
|
11
|
-
<div class:list={['border-l-4 bg-[color:var(--
|
|
11
|
+
<div class:list={['border-l-4 bg-[color:var(--ts-color-canvas-subtle)] px-4 py-4', meta.tone]}>
|
|
12
12
|
<p class="font-semibold">{meta.label}</p>
|
|
13
|
-
<p class="mt-2 text-sm leading-7 text-[color:var(--
|
|
13
|
+
<p class="mt-2 text-sm leading-7 text-[color:var(--ts-color-text-muted)]">{meta.description}</p>
|
|
14
14
|
</div>
|
|
15
15
|
);
|
|
16
16
|
})}
|
|
@@ -113,9 +113,9 @@ const isBookPage = Boolean(getBookForPath(Astro.url.pathname));
|
|
|
113
113
|
.book-font-controls__buttons {
|
|
114
114
|
display: inline-flex;
|
|
115
115
|
align-items: center;
|
|
116
|
-
border: 1px solid var(--
|
|
116
|
+
border: 1px solid var(--ts-color-border-strong);
|
|
117
117
|
border-radius: 999px;
|
|
118
|
-
background: color-mix(in srgb, var(--
|
|
118
|
+
background: color-mix(in srgb, var(--ts-color-canvas-subtle) 78%, white 22%);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
.book-font-controls__button {
|
|
@@ -126,7 +126,7 @@ const isBookPage = Boolean(getBookForPath(Astro.url.pathname));
|
|
|
126
126
|
height: 2rem;
|
|
127
127
|
border: 0;
|
|
128
128
|
background: transparent;
|
|
129
|
-
color: var(--
|
|
129
|
+
color: var(--ts-color-text);
|
|
130
130
|
font-size: 1rem;
|
|
131
131
|
font-weight: 700;
|
|
132
132
|
line-height: 1;
|
|
@@ -135,13 +135,13 @@ const isBookPage = Boolean(getBookForPath(Astro.url.pathname));
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
.book-font-controls__button + .book-font-controls__button {
|
|
138
|
-
border-inline-start: 1px solid var(--
|
|
138
|
+
border-inline-start: 1px solid var(--ts-color-border-strong);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
.book-font-controls__button:hover,
|
|
142
142
|
.book-font-controls__button:focus-visible {
|
|
143
|
-
background: color-mix(in srgb, var(--
|
|
144
|
-
color: var(--
|
|
143
|
+
background: color-mix(in srgb, var(--ts-color-info-soft) 66%, white 34%);
|
|
144
|
+
color: var(--ts-color-info-text);
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
.book-font-controls__button::after {
|
|
@@ -151,10 +151,10 @@ const isBookPage = Boolean(getBookForPath(Astro.url.pathname));
|
|
|
151
151
|
inset-block-start: calc(100% + 0.45rem);
|
|
152
152
|
transform: translateX(-50%) translateY(-0.2rem);
|
|
153
153
|
padding: 0.3rem 0.5rem;
|
|
154
|
-
border: 1px solid var(--
|
|
154
|
+
border: 1px solid var(--ts-color-border-strong);
|
|
155
155
|
border-radius: 0.45rem;
|
|
156
|
-
background: color-mix(in srgb, var(--
|
|
157
|
-
color: var(--
|
|
156
|
+
background: color-mix(in srgb, var(--ts-color-canvas-subtle) 88%, white 12%);
|
|
157
|
+
color: var(--ts-color-text);
|
|
158
158
|
font-size: 0.76rem;
|
|
159
159
|
font-weight: 700;
|
|
160
160
|
letter-spacing: 0.04em;
|
|
@@ -43,8 +43,8 @@ const iconPath =
|
|
|
43
43
|
border: 1px solid var(--sl-color-hairline);
|
|
44
44
|
border-radius: 999px;
|
|
45
45
|
padding: 0.45rem 0.8rem;
|
|
46
|
-
background: color-mix(in srgb, var(--
|
|
47
|
-
color: var(--
|
|
46
|
+
background: color-mix(in srgb, var(--ts-color-canvas-subtle) 84%, white 16%);
|
|
47
|
+
color: var(--ts-color-text-muted);
|
|
48
48
|
font-size: 0.85rem;
|
|
49
49
|
line-height: 1;
|
|
50
50
|
transition:
|
|
@@ -55,15 +55,15 @@ const iconPath =
|
|
|
55
55
|
|
|
56
56
|
.desktop-sidebar-toggle:hover,
|
|
57
57
|
.desktop-sidebar-toggle:focus-visible {
|
|
58
|
-
background: color-mix(in srgb, var(--
|
|
59
|
-
border-color: var(--
|
|
60
|
-
color: var(--
|
|
58
|
+
background: color-mix(in srgb, var(--ts-color-info-soft) 52%, white 48%);
|
|
59
|
+
border-color: var(--ts-color-info);
|
|
60
|
+
color: var(--ts-color-text);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
.desktop-sidebar-toggle[aria-expanded='true'] {
|
|
64
|
-
background: color-mix(in srgb, var(--
|
|
65
|
-
border-color: var(--
|
|
66
|
-
color: var(--
|
|
64
|
+
background: color-mix(in srgb, var(--ts-color-info-soft) 68%, white 32%);
|
|
65
|
+
border-color: var(--ts-color-info);
|
|
66
|
+
color: var(--ts-color-text);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
.desktop-sidebar-toggle__icon {
|
|
@@ -66,7 +66,7 @@ import { SITE_FOOTER_MENU } from '../../utils/site-config';
|
|
|
66
66
|
|
|
67
67
|
.docs-footer-page-inner,
|
|
68
68
|
.docs-site-footer-inner {
|
|
69
|
-
width: min(100%, var(--
|
|
69
|
+
width: min(100%, var(--ts-content-width));
|
|
70
70
|
margin-inline: auto;
|
|
71
71
|
padding-inline: 1rem;
|
|
72
72
|
}
|
|
@@ -121,7 +121,7 @@ import { SITE_FOOTER_MENU } from '../../utils/site-config';
|
|
|
121
121
|
|
|
122
122
|
.docs-site-footer {
|
|
123
123
|
margin-top: 0;
|
|
124
|
-
border-top: 2px solid var(--
|
|
124
|
+
border-top: 2px solid var(--ts-color-border-strong);
|
|
125
125
|
padding-top: 2rem;
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -146,14 +146,14 @@ import { SITE_FOOTER_MENU } from '../../utils/site-config';
|
|
|
146
146
|
font-weight: 600;
|
|
147
147
|
letter-spacing: 0.16em;
|
|
148
148
|
text-transform: uppercase;
|
|
149
|
-
color: var(--
|
|
149
|
+
color: var(--ts-color-info-text);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
.docs-footer-title,
|
|
153
153
|
.docs-footer-column-title {
|
|
154
154
|
font-size: 1.25rem;
|
|
155
155
|
font-weight: 700;
|
|
156
|
-
color: var(--
|
|
156
|
+
color: var(--ts-color-text);
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
.docs-footer-copy,
|
|
@@ -161,7 +161,7 @@ import { SITE_FOOTER_MENU } from '../../utils/site-config';
|
|
|
161
161
|
margin-top: 0.75rem;
|
|
162
162
|
font-size: 1rem;
|
|
163
163
|
line-height: 2;
|
|
164
|
-
color: var(--
|
|
164
|
+
color: var(--ts-color-text-muted);
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
.docs-footer-links {
|
|
@@ -176,7 +176,7 @@ import { SITE_FOOTER_MENU } from '../../utils/site-config';
|
|
|
176
176
|
|
|
177
177
|
.docs-footer-links a:hover,
|
|
178
178
|
.docs-footer-links a:focus-visible {
|
|
179
|
-
color: var(--
|
|
179
|
+
color: var(--ts-color-text);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
@media (min-width: 40rem) {
|
|
@@ -33,8 +33,8 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
33
33
|
<div class:list={[
|
|
34
34
|
'rounded-lg border px-4 py-3 text-sm font-medium',
|
|
35
35
|
status === 'success'
|
|
36
|
-
? 'border-[color:var(--
|
|
37
|
-
: 'border-[color:var(--
|
|
36
|
+
? 'border-[color:var(--ts-color-info)] bg-[color:var(--ts-color-info-soft)] text-[color:var(--ts-color-text)]'
|
|
37
|
+
: 'border-[color:var(--ts-color-warning)] bg-[color:var(--ts-color-warning-soft)] text-[color:var(--ts-color-text)]',
|
|
38
38
|
]}>
|
|
39
39
|
{statusMessage}
|
|
40
40
|
</div>
|
|
@@ -47,8 +47,8 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
47
47
|
data-form-type="contact"
|
|
48
48
|
data-turnstile-action="contact_submit"
|
|
49
49
|
>
|
|
50
|
-
<p class="text-sm text-[color:var(--
|
|
51
|
-
Fields marked <span class="font-semibold text-[color:var(--
|
|
50
|
+
<p class="text-sm text-[color:var(--ts-color-text-subtle)]">
|
|
51
|
+
Fields marked <span class="font-semibold text-[color:var(--ts-color-warning)]">*</span> are required.
|
|
52
52
|
</p>
|
|
53
53
|
<input type="hidden" name="formType" value="contact" />
|
|
54
54
|
<input type="hidden" name="formToken" value="" />
|
|
@@ -63,9 +63,9 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
63
63
|
|
|
64
64
|
<div class="grid gap-5 md:grid-cols-2">
|
|
65
65
|
<label class="grid gap-2">
|
|
66
|
-
<span class="text-sm font-semibold text-[color:var(--
|
|
66
|
+
<span class="text-sm font-semibold text-[color:var(--ts-color-text)]">Name <span aria-hidden="true" class="text-[color:var(--ts-color-warning)]">*</span></span>
|
|
67
67
|
<input
|
|
68
|
-
class="min-h-12 rounded-md border border-[color:var(--
|
|
68
|
+
class="min-h-12 rounded-md border border-[color:var(--ts-color-border-strong)] bg-white/70 px-4 py-3"
|
|
69
69
|
type="text"
|
|
70
70
|
name="name"
|
|
71
71
|
autocomplete="name"
|
|
@@ -74,9 +74,9 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
74
74
|
/>
|
|
75
75
|
</label>
|
|
76
76
|
<label class="grid gap-2">
|
|
77
|
-
<span class="text-sm font-semibold text-[color:var(--
|
|
77
|
+
<span class="text-sm font-semibold text-[color:var(--ts-color-text)]">Email <span aria-hidden="true" class="text-[color:var(--ts-color-warning)]">*</span></span>
|
|
78
78
|
<input
|
|
79
|
-
class="min-h-12 rounded-md border border-[color:var(--
|
|
79
|
+
class="min-h-12 rounded-md border border-[color:var(--ts-color-border-strong)] bg-white/70 px-4 py-3"
|
|
80
80
|
type="email"
|
|
81
81
|
name="email"
|
|
82
82
|
autocomplete="email"
|
|
@@ -88,18 +88,18 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
88
88
|
|
|
89
89
|
<div class="grid gap-5 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)]">
|
|
90
90
|
<label class="grid gap-2">
|
|
91
|
-
<span class="text-sm font-semibold text-[color:var(--
|
|
91
|
+
<span class="text-sm font-semibold text-[color:var(--ts-color-text)]">Organization</span>
|
|
92
92
|
<input
|
|
93
|
-
class="min-h-12 rounded-md border border-[color:var(--
|
|
93
|
+
class="min-h-12 rounded-md border border-[color:var(--ts-color-border-strong)] bg-white/70 px-4 py-3"
|
|
94
94
|
type="text"
|
|
95
95
|
name="organization"
|
|
96
96
|
autocomplete="organization"
|
|
97
97
|
/>
|
|
98
98
|
</label>
|
|
99
99
|
<label class="grid gap-2">
|
|
100
|
-
<span class="text-sm font-semibold text-[color:var(--
|
|
100
|
+
<span class="text-sm font-semibold text-[color:var(--ts-color-text)]">Topic <span aria-hidden="true" class="text-[color:var(--ts-color-warning)]">*</span></span>
|
|
101
101
|
<select
|
|
102
|
-
class="min-h-12 rounded-md border border-[color:var(--
|
|
102
|
+
class="min-h-12 rounded-md border border-[color:var(--ts-color-border-strong)] bg-white/70 px-4 py-3"
|
|
103
103
|
name="contactType"
|
|
104
104
|
required
|
|
105
105
|
aria-required="true"
|
|
@@ -112,9 +112,9 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
112
112
|
</div>
|
|
113
113
|
|
|
114
114
|
<label class="grid gap-2">
|
|
115
|
-
<span class="text-sm font-semibold text-[color:var(--
|
|
115
|
+
<span class="text-sm font-semibold text-[color:var(--ts-color-text)]">Subject <span aria-hidden="true" class="text-[color:var(--ts-color-warning)]">*</span></span>
|
|
116
116
|
<input
|
|
117
|
-
class="min-h-12 rounded-md border border-[color:var(--
|
|
117
|
+
class="min-h-12 rounded-md border border-[color:var(--ts-color-border-strong)] bg-white/70 px-4 py-3"
|
|
118
118
|
type="text"
|
|
119
119
|
name="subject"
|
|
120
120
|
required
|
|
@@ -123,9 +123,9 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
123
123
|
</label>
|
|
124
124
|
|
|
125
125
|
<label class="grid gap-2">
|
|
126
|
-
<span class="text-sm font-semibold text-[color:var(--
|
|
126
|
+
<span class="text-sm font-semibold text-[color:var(--ts-color-text)]">Message <span aria-hidden="true" class="text-[color:var(--ts-color-warning)]">*</span></span>
|
|
127
127
|
<textarea
|
|
128
|
-
class="min-h-48 rounded-md border border-[color:var(--
|
|
128
|
+
class="min-h-48 rounded-md border border-[color:var(--ts-color-border-strong)] bg-white/70 px-4 py-3"
|
|
129
129
|
name="message"
|
|
130
130
|
required
|
|
131
131
|
aria-required="true"
|
|
@@ -133,24 +133,24 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
133
133
|
</label>
|
|
134
134
|
|
|
135
135
|
{TREESEED_PUBLIC_TURNSTILE_SITE_KEY && !shouldBypassTurnstile ? (
|
|
136
|
-
<div class="js-turnstile rounded-md border border-dashed border-[color:var(--
|
|
136
|
+
<div class="js-turnstile rounded-md border border-dashed border-[color:var(--ts-color-border-strong)] p-3"></div>
|
|
137
137
|
) : shouldBypassTurnstile ? (
|
|
138
|
-
<p class="rounded-md border border-[color:var(--
|
|
138
|
+
<p class="rounded-md border border-[color:var(--ts-color-info)] bg-[color:var(--ts-color-info-soft)] px-4 py-3 text-sm text-[color:var(--ts-color-text)]">
|
|
139
139
|
Local development mode is bypassing Turnstile so you can test the form workflow without Cloudflare captcha.
|
|
140
140
|
</p>
|
|
141
141
|
) : (
|
|
142
|
-
<p class="rounded-md border border-[color:var(--
|
|
142
|
+
<p class="rounded-md border border-[color:var(--ts-color-warning)] bg-[color:var(--ts-color-warning-soft)] px-4 py-3 text-sm text-[color:var(--ts-color-text)]">
|
|
143
143
|
Turnstile is not configured yet. Add `TREESEED_PUBLIC_TURNSTILE_SITE_KEY` before deploying forms.
|
|
144
144
|
</p>
|
|
145
145
|
)}
|
|
146
146
|
|
|
147
147
|
<div class="flex flex-wrap items-center justify-between gap-4">
|
|
148
|
-
<p class="text-sm leading-7 text-[color:var(--
|
|
148
|
+
<p class="text-sm leading-7 text-[color:var(--ts-color-text-subtle)]">
|
|
149
149
|
By sending this message, you agree that we may reply by email about this inquiry.
|
|
150
150
|
</p>
|
|
151
151
|
<button
|
|
152
152
|
type="submit"
|
|
153
|
-
class="js-submit inline-flex min-h-12 items-center justify-center border border-[color:var(--
|
|
153
|
+
class="js-submit inline-flex min-h-12 items-center justify-center border border-[color:var(--ts-color-accent)] bg-[color:var(--ts-color-accent)] px-6 py-3 text-base font-semibold text-[color:var(--ts-color-text)] transition hover:border-[color:var(--ts-color-info)] hover:bg-[color:var(--ts-color-info-soft)] disabled:cursor-not-allowed disabled:opacity-60"
|
|
154
154
|
disabled
|
|
155
155
|
>
|
|
156
156
|
Send message
|
|
@@ -11,11 +11,11 @@ const shouldBypassTurnstile = import.meta.env.DEV;
|
|
|
11
11
|
const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
<section id={SUBSCRIBE_ANCHOR_ID} class="mt-6 border-t border-[color:var(--
|
|
14
|
+
<section id={SUBSCRIBE_ANCHOR_ID} class="mt-6 border-t border-[color:var(--ts-color-border)] pt-4">
|
|
15
15
|
<div class="flex flex-col items-center gap-3 text-center">
|
|
16
16
|
<div class="flex flex-col gap-1">
|
|
17
|
-
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--
|
|
18
|
-
<p class="text-sm text-[color:var(--
|
|
17
|
+
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--ts-color-info-text)]">Subscribe for updates</p>
|
|
18
|
+
<p class="text-sm text-[color:var(--ts-color-text-muted)]">
|
|
19
19
|
Get occasional notes when new writing or project updates are published.
|
|
20
20
|
</p>
|
|
21
21
|
</div>
|
|
@@ -40,7 +40,7 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
40
40
|
<input type="hidden" name="name" value="" />
|
|
41
41
|
<div class="flex w-full flex-col items-center justify-center gap-3 md:flex-row md:flex-wrap">
|
|
42
42
|
<input
|
|
43
|
-
class="min-h-11 w-full rounded-md border border-[color:var(--
|
|
43
|
+
class="min-h-11 w-full rounded-md border border-[color:var(--ts-color-border-strong)] bg-white/80 px-4 py-2 md:w-auto md:min-w-[16rem] md:max-w-[18rem]"
|
|
44
44
|
type="email"
|
|
45
45
|
name="email"
|
|
46
46
|
placeholder="Email address"
|
|
@@ -50,13 +50,13 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
50
50
|
{TREESEED_PUBLIC_TURNSTILE_SITE_KEY && !shouldBypassTurnstile ? (
|
|
51
51
|
<div class="js-turnstile min-h-0"></div>
|
|
52
52
|
) : shouldBypassTurnstile ? (
|
|
53
|
-
<p class="text-xs text-[color:var(--
|
|
53
|
+
<p class="text-xs text-[color:var(--ts-color-text-subtle)]">Captcha bypassed locally.</p>
|
|
54
54
|
) : (
|
|
55
|
-
<p class="text-xs text-[color:var(--
|
|
55
|
+
<p class="text-xs text-[color:var(--ts-color-text-subtle)]">Turnstile not configured.</p>
|
|
56
56
|
)}
|
|
57
57
|
<button
|
|
58
58
|
type="submit"
|
|
59
|
-
class="js-submit inline-flex min-h-11 items-center justify-center whitespace-nowrap border border-[color:var(--
|
|
59
|
+
class="js-submit inline-flex min-h-11 items-center justify-center whitespace-nowrap border border-[color:var(--ts-color-accent)] bg-[color:var(--ts-color-accent)] px-4 py-2 text-sm font-semibold text-[color:var(--ts-color-text)] transition hover:border-[color:var(--ts-color-info)] hover:bg-[color:var(--ts-color-info-soft)] disabled:cursor-not-allowed disabled:opacity-60"
|
|
60
60
|
disabled
|
|
61
61
|
>
|
|
62
62
|
Subscribe
|
|
@@ -106,9 +106,9 @@ const formsApiBaseUrl = SITE_FORMS?.apiBaseUrl ?? '/api/form/submit';
|
|
|
106
106
|
statusNode.textContent = subscribeMessages[code] ?? (status === 'success' ? 'Subscription complete.' : 'We could not complete the signup.');
|
|
107
107
|
statusNode.classList.remove('hidden');
|
|
108
108
|
if (status === 'success') {
|
|
109
|
-
statusNode.className = 'js-subscribe-status rounded-md border border-[color:var(--
|
|
109
|
+
statusNode.className = 'js-subscribe-status rounded-md border border-[color:var(--ts-color-info)] bg-[color:var(--ts-color-info-soft)] px-4 py-2 text-sm font-medium text-[color:var(--ts-color-text)]';
|
|
110
110
|
} else {
|
|
111
|
-
statusNode.className = 'js-subscribe-status rounded-md border border-[color:var(--
|
|
111
|
+
statusNode.className = 'js-subscribe-status rounded-md border border-[color:var(--ts-color-warning)] bg-[color:var(--ts-color-warning-soft)] px-4 py-2 text-sm font-medium text-[color:var(--ts-color-text)]';
|
|
112
112
|
}
|
|
113
113
|
};
|
|
114
114
|
|
|
@@ -13,14 +13,14 @@ const { items } = Astro.props as { items: BookItem[] };
|
|
|
13
13
|
|
|
14
14
|
<div class="grid gap-6 md:grid-cols-2">
|
|
15
15
|
{items.map((item) => (
|
|
16
|
-
<div class="border border-[color:var(--
|
|
17
|
-
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--
|
|
18
|
-
<h3 class="mt-4 text-2xl font-bold text-[color:var(--
|
|
19
|
-
<p class="mt-3 text-base leading-8 text-[color:var(--
|
|
16
|
+
<div class="border border-[color:var(--ts-color-border)] bg-[color:var(--ts-color-surface)] p-6">
|
|
17
|
+
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--ts-color-info-text)]">{item.meta}</p>
|
|
18
|
+
<h3 class="mt-4 text-2xl font-bold text-[color:var(--ts-color-text)]">{item.title}</h3>
|
|
19
|
+
<p class="mt-3 text-base leading-8 text-[color:var(--ts-color-text-muted)]">{item.summary}</p>
|
|
20
20
|
<div class="mt-5 flex flex-wrap gap-3">
|
|
21
|
-
<a href={item.href} class="border border-[color:var(--
|
|
22
|
-
<a href={item.landingPath} class="border border-[color:var(--
|
|
23
|
-
<a href={item.downloadHref} class="border border-[color:var(--
|
|
21
|
+
<a href={item.href} class="border border-[color:var(--ts-color-border-strong)] px-4 py-2 text-sm font-semibold text-[color:var(--ts-color-text)] transition hover:border-[color:var(--ts-color-info)] hover:bg-[color:var(--ts-color-info-soft)]">Book page</a>
|
|
22
|
+
<a href={item.landingPath} class="border border-[color:var(--ts-color-border-strong)] px-4 py-2 text-sm font-semibold text-[color:var(--ts-color-text)] transition hover:border-[color:var(--ts-color-info)] hover:bg-[color:var(--ts-color-info-soft)]">Open knowledge</a>
|
|
23
|
+
<a href={item.downloadHref} class="border border-[color:var(--ts-color-accent)] bg-[color:var(--ts-color-accent)] px-4 py-2 text-sm font-semibold text-[color:var(--ts-color-text)] transition hover:border-[color:var(--ts-color-info)] hover:bg-[color:var(--ts-color-info-soft)]">Download</a>
|
|
24
24
|
</div>
|
|
25
25
|
</div>
|
|
26
26
|
))}
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
const { title, body, primaryHref, primaryLabel, secondaryHref, secondaryLabel } = Astro.props;
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
<section class="site-footer-cta px-0 py-0 text-[color:var(--
|
|
5
|
+
<section class="site-footer-cta px-0 py-0 text-[color:var(--ts-color-text)]">
|
|
6
6
|
<div class="site-footer-cta__inner">
|
|
7
7
|
<div class="mx-auto flex max-w-4xl flex-col items-center gap-6">
|
|
8
8
|
<div class="max-w-3xl">
|
|
9
9
|
<h2 class="font-serif text-3xl font-bold md:text-4xl">{title}</h2>
|
|
10
|
-
<p class="mt-4 text-lg leading-9 text-[color:var(--
|
|
10
|
+
<p class="mt-4 text-lg leading-9 text-[color:var(--ts-color-text-muted)]">{body}</p>
|
|
11
11
|
</div>
|
|
12
12
|
<div class="flex flex-wrap justify-center gap-3">
|
|
13
|
-
<a href={primaryHref} class="border border-[color:var(--
|
|
13
|
+
<a href={primaryHref} class="border border-[color:var(--ts-color-accent)] bg-[color:var(--ts-color-accent)] px-5 py-3 text-base font-semibold text-[color:var(--ts-color-text)] transition hover:border-[color:var(--ts-color-info)] hover:bg-[color:var(--ts-color-info-soft)]">{
|
|
14
14
|
primaryLabel
|
|
15
15
|
}</a>
|
|
16
16
|
{secondaryHref && secondaryLabel && (
|
|
17
|
-
<a href={secondaryHref} class="border border-[color:var(--
|
|
17
|
+
<a href={secondaryHref} class="border border-[color:var(--ts-color-border-strong)] bg-[color:var(--ts-color-surface-muted)] px-5 py-3 text-base font-semibold text-[color:var(--ts-color-text)] transition hover:border-[color:var(--ts-color-info)] hover:bg-[color:var(--ts-color-info-soft)]">
|
|
18
18
|
{secondaryLabel}
|
|
19
19
|
</a>
|
|
20
20
|
)}
|
|
@@ -17,16 +17,16 @@ const { items } = Astro.props as { items: ChronicleItem[] };
|
|
|
17
17
|
|
|
18
18
|
<div class="grid gap-1">
|
|
19
19
|
{items.map((item) => (
|
|
20
|
-
<a href={item.href} class="block border-t border-[color:var(--
|
|
20
|
+
<a href={item.href} class="block border-t border-[color:var(--ts-color-border)] py-7 transition hover:border-[color:var(--ts-color-border-strong)]">
|
|
21
21
|
<div class="flex flex-wrap items-center gap-4">
|
|
22
22
|
<StatusBadge status={item.status} />
|
|
23
|
-
<p class="text-sm font-medium text-[color:var(--
|
|
24
|
-
{item.meta && <p class="text-sm text-[color:var(--
|
|
23
|
+
<p class="text-sm font-medium text-[color:var(--ts-color-text-subtle)]">{item.date.toISOString().slice(0, 10)}</p>
|
|
24
|
+
{item.meta && <p class="text-sm text-[color:var(--ts-color-text-subtle)]">{item.meta}</p>}
|
|
25
25
|
</div>
|
|
26
|
-
<h3 class="mt-4 max-w-3xl text-2xl font-bold text-[color:var(--
|
|
27
|
-
<p class="mt-3 max-w-3xl text-lg leading-9 text-[color:var(--
|
|
26
|
+
<h3 class="mt-4 max-w-3xl text-2xl font-bold text-[color:var(--ts-color-text)] md:text-3xl">{item.title}</h3>
|
|
27
|
+
<p class="mt-3 max-w-3xl text-lg leading-9 text-[color:var(--ts-color-text-muted)]">{item.summary}</p>
|
|
28
28
|
{item.tags && item.tags.length > 0 && (
|
|
29
|
-
<p class="mt-4 text-sm uppercase tracking-[0.14em] text-[color:var(--
|
|
29
|
+
<p class="mt-4 text-sm uppercase tracking-[0.14em] text-[color:var(--ts-color-accent-strong)]">{item.tags.join(' / ')}</p>
|
|
30
30
|
)}
|
|
31
31
|
</a>
|
|
32
32
|
))}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<section class="relative overflow-hidden border-y border-[color:var(--
|
|
2
|
-
<div class="absolute inset-y-0 left-[68%] hidden w-px bg-[linear-gradient(180deg,transparent,var(--
|
|
1
|
+
<section class="relative overflow-hidden border-y border-[color:var(--ts-color-border-strong)] py-12 md:py-18">
|
|
2
|
+
<div class="absolute inset-y-0 left-[68%] hidden w-px bg-[linear-gradient(180deg,transparent,var(--ts-color-border-strong),transparent)] lg:block"></div>
|
|
3
3
|
<div class="grid gap-10 lg:grid-cols-[1.45fr_0.7fr] lg:items-start">
|
|
4
4
|
<div class="space-y-7 pr-0 lg:pr-10">
|
|
5
5
|
<slot name="eyebrow" />
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<slot name="actions" />
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
14
|
-
<div class="border-l border-[color:var(--
|
|
14
|
+
<div class="border-l border-[color:var(--ts-color-border)] pl-0 lg:pl-8">
|
|
15
15
|
<slot name="aside" />
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
const { href, title, description, meta } = Astro.props;
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
<a href={href} class="group block border-t border-[color:var(--
|
|
5
|
+
<a href={href} class="group block border-t border-[color:var(--ts-color-border)] py-6 transition hover:border-[color:var(--ts-color-border-strong)]">
|
|
6
6
|
<div class="grid gap-3 md:grid-cols-[0.42fr_1fr_auto] md:items-start md:gap-6">
|
|
7
7
|
<div>
|
|
8
|
-
{meta && <p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--
|
|
8
|
+
{meta && <p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--ts-color-accent-strong)]">{meta}</p>}
|
|
9
9
|
</div>
|
|
10
10
|
<div>
|
|
11
|
-
<h3 class="text-2xl font-bold text-[color:var(--
|
|
12
|
-
<p class="mt-3 max-w-2xl text-base leading-8 text-[color:var(--
|
|
11
|
+
<h3 class="text-2xl font-bold text-[color:var(--ts-color-text)]">{title}</h3>
|
|
12
|
+
<p class="mt-3 max-w-2xl text-base leading-8 text-[color:var(--ts-color-text-muted)]">{description}</p>
|
|
13
13
|
</div>
|
|
14
|
-
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--
|
|
14
|
+
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--ts-color-info-text)] group-hover:text-[color:var(--ts-color-accent-strong)]">Open path</p>
|
|
15
15
|
</div>
|
|
16
16
|
</a>
|
|
@@ -15,15 +15,15 @@ const { items } = Astro.props as { items: ProfileItem[] };
|
|
|
15
15
|
|
|
16
16
|
<div class="grid gap-6 md:grid-cols-2">
|
|
17
17
|
{items.map((item) => (
|
|
18
|
-
<a href={item.href} class="border border-[color:var(--
|
|
18
|
+
<a href={item.href} class="border border-[color:var(--ts-color-border)] bg-[color:var(--ts-color-surface)] p-6 transition hover:border-[color:var(--ts-color-border-strong)]">
|
|
19
19
|
<div class="flex flex-wrap items-center gap-3">
|
|
20
20
|
{item.status && <StatusBadge status={item.status} />}
|
|
21
|
-
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--
|
|
21
|
+
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--ts-color-info-text)]">{item.meta}</p>
|
|
22
22
|
</div>
|
|
23
|
-
<h3 class="mt-4 text-2xl font-bold text-[color:var(--
|
|
24
|
-
<p class="mt-3 text-base leading-8 text-[color:var(--
|
|
23
|
+
<h3 class="mt-4 text-2xl font-bold text-[color:var(--ts-color-text)]">{item.name}</h3>
|
|
24
|
+
<p class="mt-3 text-base leading-8 text-[color:var(--ts-color-text-muted)]">{item.summary}</p>
|
|
25
25
|
{item.tags && item.tags.length > 0 && (
|
|
26
|
-
<p class="mt-4 text-sm uppercase tracking-[0.14em] text-[color:var(--
|
|
26
|
+
<p class="mt-4 text-sm uppercase tracking-[0.14em] text-[color:var(--ts-color-accent-strong)]">{item.tags.join(' / ')}</p>
|
|
27
27
|
)}
|
|
28
28
|
</a>
|
|
29
29
|
))}
|
|
@@ -10,14 +10,14 @@ const {
|
|
|
10
10
|
|
|
11
11
|
<MainLayout title={title} description={description} currentPath={currentPath}>
|
|
12
12
|
<section class="mx-auto max-w-3xl space-y-6 py-20">
|
|
13
|
-
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--
|
|
14
|
-
<h1 class="font-serif text-5xl text-[color:var(--
|
|
15
|
-
<p class="text-lg leading-9 text-[color:var(--
|
|
13
|
+
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--ts-color-accent-strong)]">404</p>
|
|
14
|
+
<h1 class="font-serif text-5xl text-[color:var(--ts-color-text)]">{title}</h1>
|
|
15
|
+
<p class="text-lg leading-9 text-[color:var(--ts-color-text-muted)]">{description}</p>
|
|
16
16
|
<div class="flex flex-wrap gap-4">
|
|
17
|
-
<a href="/" class="border border-[color:var(--
|
|
17
|
+
<a href="/" class="border border-[color:var(--ts-color-accent)] bg-[color:var(--ts-color-accent)] px-5 py-3 text-base font-semibold text-[color:var(--ts-color-text)] transition hover:border-[color:var(--ts-color-info)] hover:bg-[color:var(--ts-color-info-soft)]">
|
|
18
18
|
Go home
|
|
19
19
|
</a>
|
|
20
|
-
<a href="/knowledge/" class="border border-[color:var(--
|
|
20
|
+
<a href="/knowledge/" class="border border-[color:var(--ts-color-border-strong)] px-5 py-3 text-base font-semibold text-[color:var(--ts-color-text)] transition hover:border-[color:var(--ts-color-info)] hover:bg-[color:var(--ts-color-info-soft)]">
|
|
21
21
|
Open knowledge
|
|
22
22
|
</a>
|
|
23
23
|
</div>
|
|
@@ -3,7 +3,7 @@ const { eyebrow, title, description } = Astro.props;
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
<header class="max-w-4xl space-y-4">
|
|
6
|
-
{eyebrow && <p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--
|
|
7
|
-
<h2 class="max-w-4xl font-serif text-4xl font-bold tracking-tight text-[color:var(--
|
|
8
|
-
<p class="max-w-3xl text-lg leading-9 text-[color:var(--
|
|
6
|
+
{eyebrow && <p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--ts-color-accent-strong)]">{eyebrow}</p>}
|
|
7
|
+
<h2 class="max-w-4xl font-serif text-4xl font-bold tracking-tight text-[color:var(--ts-color-text)] md:text-5xl">{title}</h2>
|
|
8
|
+
<p class="max-w-3xl text-lg leading-9 text-[color:var(--ts-color-text-muted)] md:text-xl">{description}</p>
|
|
9
9
|
</header>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { PROJECT_STAGE } from '../../utils/content-status';
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
<div class="inline-flex max-w-full flex-wrap items-center gap-x-3 gap-y-1 border-l-4 border-[color:var(--
|
|
5
|
+
<div class="inline-flex max-w-full flex-wrap items-center gap-x-3 gap-y-1 border-l-4 border-[color:var(--ts-color-accent)] bg-[color:var(--ts-color-accent-soft)] px-4 py-3 text-[color:var(--ts-color-text)]">
|
|
6
6
|
<span class="font-bold uppercase tracking-[0.16em] text-xs">{PROJECT_STAGE.label}</span>
|
|
7
|
-
<span class="text-[color:var(--
|
|
7
|
+
<span class="text-[color:var(--ts-color-text-muted)]">{PROJECT_STAGE.description}</span>
|
|
8
8
|
</div>
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
const { title, body } = Astro.props;
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
<aside class="border-l-4 border-[color:var(--
|
|
6
|
-
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--
|
|
5
|
+
<aside class="border-l-4 border-[color:var(--ts-color-warning)] bg-[color:var(--ts-color-warning-soft)] px-5 py-5 text-[color:var(--ts-color-text)]">
|
|
6
|
+
<p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--ts-color-warning-text)]">Trust note</p>
|
|
7
7
|
<h3 class="mt-2 text-2xl font-bold">{title}</h3>
|
|
8
|
-
<p class="mt-3 text-base leading-8 text-[color:var(--
|
|
8
|
+
<p class="mt-3 text-base leading-8 text-[color:var(--ts-color-text-muted)]">{body}</p>
|
|
9
9
|
</aside>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Badge from './Badge.astro';
|
|
3
|
+
import type { Tone } from '../types.js';
|
|
4
|
+
|
|
5
|
+
interface ActionListItem {
|
|
6
|
+
title: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
href?: string;
|
|
9
|
+
meta?: string;
|
|
10
|
+
tone?: Tone;
|
|
11
|
+
actionLabel?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
items?: ActionListItem[];
|
|
16
|
+
class?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
items = [],
|
|
21
|
+
class: className,
|
|
22
|
+
} = Astro.props as Props;
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
<div class:list={['ts-action-list', className]}>
|
|
26
|
+
{items.length > 0 ? (
|
|
27
|
+
<ul class="ts-action-list__items">
|
|
28
|
+
{items.map((item) => {
|
|
29
|
+
const Inner = (
|
|
30
|
+
<>
|
|
31
|
+
<span class="ts-action-list__content">
|
|
32
|
+
<span class="ts-action-list__title">{item.title}</span>
|
|
33
|
+
{item.description ? <span class="ts-action-list__description">{item.description}</span> : null}
|
|
34
|
+
</span>
|
|
35
|
+
<span class="ts-action-list__meta">
|
|
36
|
+
{item.meta ? <Badge tone={item.tone ?? 'muted'} size="sm">{item.meta}</Badge> : null}
|
|
37
|
+
{item.actionLabel ? <span class="ts-action-list__action">{item.actionLabel}</span> : null}
|
|
38
|
+
</span>
|
|
39
|
+
</>
|
|
40
|
+
);
|
|
41
|
+
return (
|
|
42
|
+
<li class="ts-action-list__item" data-tone={item.tone ?? 'default'}>
|
|
43
|
+
{item.href ? <a href={item.href} class="ts-action-list__link">{Inner}</a> : <div class="ts-action-list__row">{Inner}</div>}
|
|
44
|
+
</li>
|
|
45
|
+
);
|
|
46
|
+
})}
|
|
47
|
+
</ul>
|
|
48
|
+
) : (
|
|
49
|
+
<slot />
|
|
50
|
+
)}
|
|
51
|
+
</div>
|