@contentrain/astro-kit 0.44.1 → 0.45.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/catalog.json +49 -0
- package/components/band/Band.astro +17 -4
- package/components/band/fixtures.json +125 -1
- package/components/band/meta.json +11 -0
- package/components/header/Header.astro +5 -5
- package/components/header/fixtures.json +27 -1
- package/components/hero/Hero.astro +29 -5
- package/components/hero/fixtures.json +118 -1
- package/components/hero/meta.json +27 -0
- package/components/prose/Prose.astro +8 -3
- package/components/prose/fixtures.json +5 -1
- package/components/prose/meta.json +11 -0
- package/package.json +1 -1
package/catalog.json
CHANGED
|
@@ -148,6 +148,17 @@
|
|
|
148
148
|
"default": "default",
|
|
149
149
|
"description": "Section background when nothing is measured."
|
|
150
150
|
},
|
|
151
|
+
"inset": {
|
|
152
|
+
"options": [
|
|
153
|
+
"none",
|
|
154
|
+
"15",
|
|
155
|
+
"27",
|
|
156
|
+
"34",
|
|
157
|
+
"42"
|
|
158
|
+
],
|
|
159
|
+
"default": "none",
|
|
160
|
+
"description": "Layout stack only (split ignores it). From md (768px) up, the band's content (copy, image and items) starts at this share of the frame's width and runs to its end, its text at that edge (a centred band's too): a narrow talk beside a wide margin. Below md it is the full column. none: as before."
|
|
161
|
+
},
|
|
151
162
|
"headingLines": {
|
|
152
163
|
"options": [
|
|
153
164
|
"flow",
|
|
@@ -3822,6 +3833,33 @@
|
|
|
3822
3833
|
],
|
|
3823
3834
|
"default": "none",
|
|
3824
3835
|
"description": "Split and centered: edge runs the image on to the window's edge on its side (both sides when centered); overlap also lets it cross the section's bottom edge by --hero-overlap (3rem), over the next section's top padding, when the image comes last: with stackOrder media-first it draws as edge, so it never covers the text. A cover ignores it."
|
|
3836
|
+
},
|
|
3837
|
+
"inset": {
|
|
3838
|
+
"options": [
|
|
3839
|
+
"none",
|
|
3840
|
+
"15",
|
|
3841
|
+
"27",
|
|
3842
|
+
"34",
|
|
3843
|
+
"42"
|
|
3844
|
+
],
|
|
3845
|
+
"default": "none",
|
|
3846
|
+
"description": "Layout centered only (split and cover ignore it). From md (768px) up, the copy's start edge sits at this share of the frame's width and its text is set at that edge, not centred: a statement on an axis, the void before it part of the page. Below md the hero is centred as without it. none: as before."
|
|
3847
|
+
},
|
|
3848
|
+
"height": {
|
|
3849
|
+
"options": [
|
|
3850
|
+
"auto",
|
|
3851
|
+
"screen"
|
|
3852
|
+
],
|
|
3853
|
+
"default": "auto",
|
|
3854
|
+
"description": "The hero's height. screen: from sm (640px) up, at least the window's height (100svh, 100vh where unknown) less --header-h, the header's height where the site sets it (0 without, so a static header above adds to it): the page opens on one full screen, the statement placed in it by contentAt. Below sm the hero is as tall as its content, as with auto: no empty screen on a phone. A boxed cover (width content) ignores it. auto: as before."
|
|
3855
|
+
},
|
|
3856
|
+
"contentAt": {
|
|
3857
|
+
"options": [
|
|
3858
|
+
"start",
|
|
3859
|
+
"end"
|
|
3860
|
+
],
|
|
3861
|
+
"default": "start",
|
|
3862
|
+
"description": "Where the content sits in a hero taller than it (height screen, or a cover with its own height). end: on the bottom edge, the section's bottom padding under it (a title on the image's lower edge, a statement after a void). start: where the layout puts it, as before."
|
|
3825
3863
|
}
|
|
3826
3864
|
},
|
|
3827
3865
|
"props": {
|
|
@@ -5783,6 +5821,17 @@
|
|
|
5783
5821
|
],
|
|
5784
5822
|
"default": "lg",
|
|
5785
5823
|
"description": "Type scale of the body."
|
|
5824
|
+
},
|
|
5825
|
+
"inset": {
|
|
5826
|
+
"options": [
|
|
5827
|
+
"none",
|
|
5828
|
+
"15",
|
|
5829
|
+
"27",
|
|
5830
|
+
"34",
|
|
5831
|
+
"42"
|
|
5832
|
+
],
|
|
5833
|
+
"default": "none",
|
|
5834
|
+
"description": "From md (768px) up, the body's start edge sits at this share of its container's width and the body runs to the container's end: the axis an editorial page sets its text on (an intro in a narrow column, a column set off the page's start). Below md it is the full column. none: as before. The share is of the container the body sits in (in the starter's pages, the reading column)."
|
|
5786
5835
|
}
|
|
5787
5836
|
},
|
|
5788
5837
|
"props": {
|
|
@@ -15,6 +15,7 @@ import { muted } from '../_shared/muted'
|
|
|
15
15
|
|
|
16
16
|
const band = tv({
|
|
17
17
|
slots: {
|
|
18
|
+
column: 'flex flex-col gap-10',
|
|
18
19
|
grid: 'grid gap-10',
|
|
19
20
|
copy: 'flex max-w-3xl flex-col gap-4',
|
|
20
21
|
eyebrow: 'text-sm font-semibold tracking-wide text-accent-text uppercase',
|
|
@@ -46,8 +47,18 @@ const band = tv({
|
|
|
46
47
|
},
|
|
47
48
|
// Accent backgrounds have the least contrast headroom: text on them is never dimmed.
|
|
48
49
|
tone: { default: {}, muted: {}, inverse: {}, accent: { eyebrow: 'text-current' } },
|
|
50
|
+
// Stack only (split ignores it): from md the band's content starts at this share of the frame's width and runs to
|
|
51
|
+
// its end, its text at that edge; below md it is the full column, as without it.
|
|
52
|
+
inset: { none: {}, '15': {}, '27': {}, '34': {}, '42': {} },
|
|
49
53
|
},
|
|
50
|
-
|
|
54
|
+
compoundVariants: [
|
|
55
|
+
{ layout: 'stack', inset: '15', class: { column: 'md:ms-[15%]' } },
|
|
56
|
+
{ layout: 'stack', inset: '27', class: { column: 'md:ms-[27%]' } },
|
|
57
|
+
{ layout: 'stack', inset: '34', class: { column: 'md:ms-[34%]' } },
|
|
58
|
+
{ layout: 'stack', inset: '42', class: { column: 'md:ms-[42%]' } },
|
|
59
|
+
{ layout: 'stack', align: 'center', inset: ['15', '27', '34', '42'], class: { copy: 'md:mx-0 md:items-start md:text-start', actions: 'md:justify-start', item: 'md:items-start md:text-start' } },
|
|
60
|
+
],
|
|
61
|
+
defaultVariants: { layout: 'stack', columns: '3', align: 'start', tone: 'default', inset: 'none' },
|
|
51
62
|
})
|
|
52
63
|
|
|
53
64
|
interface Item {
|
|
@@ -88,12 +99,14 @@ interface Props {
|
|
|
88
99
|
headingLines?: 'flow' | 'lines' | undefined
|
|
89
100
|
/** The same for the lead: `lines` draws each of its lines as a block, still one paragraph. */
|
|
90
101
|
leadLines?: 'flow' | 'lines' | undefined
|
|
102
|
+
/** Stack only: from md the content starts at this share of the frame's width (`15` … `42` %), its text at that edge. `none` (absent): as before. */
|
|
103
|
+
inset?: 'none' | '15' | '27' | '34' | '42' | undefined
|
|
91
104
|
}
|
|
92
105
|
|
|
93
|
-
const { heading, eyebrow, lead, media, items = [], actions = [], headingLevel = 2, layout, columns, align, tone, measured, id, headingLines, leadLines } = Astro.props
|
|
106
|
+
const { heading, eyebrow, lead, media, items = [], actions = [], headingLevel = 2, layout, columns, align, tone, measured, id, headingLines, leadLines, inset } = Astro.props
|
|
94
107
|
// The measured alignment when none is given (`end` has no band layout: it reads as `start`).
|
|
95
108
|
const aligned = align ?? (measured?.align === 'center' ? 'center' : undefined)
|
|
96
|
-
const s = band({ layout: media ? layout : 'stack', columns, align: aligned, tone })
|
|
109
|
+
const s = band({ layout: media ? layout : 'stack', columns, align: aligned, tone, inset })
|
|
97
110
|
const Heading = `h${headingLevel}` as 'h2' | 'h3'
|
|
98
111
|
const ItemHeading = `h${heading ? headingLevel + 1 : headingLevel}` as 'h2' | 'h3' | 'h4'
|
|
99
112
|
// Two bands with the same heading on one page get two ids (`band-<heading>`, then `band-<heading>-2`).
|
|
@@ -101,7 +114,7 @@ const headingId = heading ? (id ? `${id}-title` : instanceId(Astro.locals, undef
|
|
|
101
114
|
const hasCopy = Boolean(heading || eyebrow || lead || actions.length)
|
|
102
115
|
---
|
|
103
116
|
<Section kit="band" tone={tone} id={id} aria-labelledby={headingId} measured={measured}>
|
|
104
|
-
<div class=
|
|
117
|
+
<div class={s.column()}>
|
|
105
118
|
{(hasCopy || media) && (
|
|
106
119
|
<div class={s.grid()}>
|
|
107
120
|
{hasCopy && (
|
|
@@ -5,5 +5,129 @@
|
|
|
5
5
|
{"name": "measured-image-overlay", "props": {"heading": "Visit the farm", "lead": "Open every weekend.", "actions": [{"label": "Plan a visit", "href": "/visit/"}], "measured": {"padY": 120, "minHeight": 480, "tone": "dark", "bg": {"image": "/kit-fixtures/photo-2.svg", "overlay": "rgba(0, 0, 0, 0.55)", "size": "cover", "position": "center"}}, "columns": "1"}},
|
|
6
6
|
{"name": "items-links", "props": {"heading": "Services", "columns": "2", "tone": "muted", "items": [{"title": "Audits", "text": "Where a site loses readers.", "href": "/audits/", "linkLabel": "Read more", "media": "/kit-fixtures/photo-3.svg"}, {"title": "Hosting", "text": "Static hosting, managed.", "href": "/hosting/", "icon": "/kit-fixtures/logo.svg"}]}},
|
|
7
7
|
{"name": "values-points", "props": {"heading": "Plans", "columns": "3", "items": [{"value": "$9", "title": "Starter", "meta": "per month", "points": ["One site", "Email support"]}, {"value": "$29", "title": "Team", "meta": "per month", "points": ["Five sites", "Shared components"], "href": "/pricing/team/", "linkLabel": "Choose Team"}, {"value": "250+", "title": "Sites moved", "text": "Since 2019."}]}},
|
|
8
|
-
{"name": "heading-lines", "props": {"heading": "Fewer tools.\nMore writing.", "headingLines": "lines", "lead": "Your posts, pages and forms in one place.\nNothing to update, nothing to patch.", "leadLines": "lines", "actions": [{"label": "See how", "href": "/how/"}]}}
|
|
8
|
+
{"name": "heading-lines", "props": {"heading": "Fewer tools.\nMore writing.", "headingLines": "lines", "lead": "Your posts, pages and forms in one place.\nNothing to update, nothing to patch.", "leadLines": "lines", "actions": [{"label": "See how", "href": "/how/"}]}},
|
|
9
|
+
{
|
|
10
|
+
"name": "inset-27",
|
|
11
|
+
"props": {
|
|
12
|
+
"heading": "What we do",
|
|
13
|
+
"lead": "Three things, done carefully.",
|
|
14
|
+
"items": [
|
|
15
|
+
{
|
|
16
|
+
"title": "Design",
|
|
17
|
+
"text": "Tokens and components."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"title": "Migration",
|
|
21
|
+
"text": "Every address kept."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"title": "Speed",
|
|
25
|
+
"text": "Static and fast."
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"tone": "inverse",
|
|
29
|
+
"inset": "27"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "center-inset-34",
|
|
34
|
+
"props": {
|
|
35
|
+
"heading": "Our numbers",
|
|
36
|
+
"align": "center",
|
|
37
|
+
"measured": {
|
|
38
|
+
"containerPx": 1140,
|
|
39
|
+
"padY": 96,
|
|
40
|
+
"padX": 24,
|
|
41
|
+
"bg": {
|
|
42
|
+
"color": "#0f172a"
|
|
43
|
+
},
|
|
44
|
+
"columns": {
|
|
45
|
+
"390": 1,
|
|
46
|
+
"768": 2,
|
|
47
|
+
"1280": 4
|
|
48
|
+
},
|
|
49
|
+
"gap": 32,
|
|
50
|
+
"radius": 8
|
|
51
|
+
},
|
|
52
|
+
"items": [
|
|
53
|
+
{
|
|
54
|
+
"title": "12",
|
|
55
|
+
"text": "years"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"title": "340",
|
|
59
|
+
"text": "sites"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"title": "9",
|
|
63
|
+
"text": "countries"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"title": "1",
|
|
67
|
+
"text": "team"
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"columns": "4",
|
|
71
|
+
"inset": "34"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "items-links-inset-15",
|
|
76
|
+
"props": {
|
|
77
|
+
"heading": "Services",
|
|
78
|
+
"columns": "2",
|
|
79
|
+
"tone": "muted",
|
|
80
|
+
"items": [
|
|
81
|
+
{
|
|
82
|
+
"title": "Audits",
|
|
83
|
+
"text": "Where a site loses readers.",
|
|
84
|
+
"href": "/audits/",
|
|
85
|
+
"linkLabel": "Read more",
|
|
86
|
+
"media": "/kit-fixtures/photo-3.svg"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"title": "Hosting",
|
|
90
|
+
"text": "Static hosting, managed.",
|
|
91
|
+
"href": "/hosting/",
|
|
92
|
+
"icon": "/kit-fixtures/logo.svg"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"inset": "15"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "values-points-inset-42",
|
|
100
|
+
"props": {
|
|
101
|
+
"heading": "Plans",
|
|
102
|
+
"columns": "3",
|
|
103
|
+
"items": [
|
|
104
|
+
{
|
|
105
|
+
"value": "$9",
|
|
106
|
+
"title": "Starter",
|
|
107
|
+
"meta": "per month",
|
|
108
|
+
"points": [
|
|
109
|
+
"One site",
|
|
110
|
+
"Email support"
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"value": "$29",
|
|
115
|
+
"title": "Team",
|
|
116
|
+
"meta": "per month",
|
|
117
|
+
"points": [
|
|
118
|
+
"Five sites",
|
|
119
|
+
"Shared components"
|
|
120
|
+
],
|
|
121
|
+
"href": "/pricing/team/",
|
|
122
|
+
"linkLabel": "Choose Team"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"value": "250+",
|
|
126
|
+
"title": "Sites moved",
|
|
127
|
+
"text": "Since 2019."
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"inset": "42"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
9
133
|
]
|
|
@@ -52,6 +52,17 @@
|
|
|
52
52
|
"default": "default",
|
|
53
53
|
"description": "Section background when nothing is measured."
|
|
54
54
|
},
|
|
55
|
+
"inset": {
|
|
56
|
+
"options": [
|
|
57
|
+
"none",
|
|
58
|
+
"15",
|
|
59
|
+
"27",
|
|
60
|
+
"34",
|
|
61
|
+
"42"
|
|
62
|
+
],
|
|
63
|
+
"default": "none",
|
|
64
|
+
"description": "Layout stack only (split ignores it). From md (768px) up, the band's content (copy, image and items) starts at this share of the frame's width and runs to its end, its text at that edge (a centred band's too): a narrow talk beside a wide margin. Below md it is the full column. none: as before."
|
|
65
|
+
},
|
|
55
66
|
"headingLines": {
|
|
56
67
|
"options": [
|
|
57
68
|
"flow",
|
|
@@ -16,7 +16,7 @@ const header = tv({
|
|
|
16
16
|
slots: {
|
|
17
17
|
root: 'z-40 w-full',
|
|
18
18
|
inner: 'container-page flex items-center gap-6 py-4',
|
|
19
|
-
brand: 'flex
|
|
19
|
+
brand: 'flex min-w-0 items-center gap-3 text-lg font-semibold tracking-tight text-current no-underline',
|
|
20
20
|
},
|
|
21
21
|
variants: {
|
|
22
22
|
layout: {
|
|
@@ -94,16 +94,16 @@ const wrap = search ? 'flex-wrap lg:flex-nowrap' : tagline ? 'flex-wrap md:flex-
|
|
|
94
94
|
? (
|
|
95
95
|
<div class="flex min-w-0 basis-full flex-col gap-1 md:basis-auto">
|
|
96
96
|
<a href={safeHref(homeHref)} class={brand()} aria-label={showName ? undefined : siteName} style={brandStyle} data-kit-brand>
|
|
97
|
-
{logo && <KitImage image={logo} priority class="h-8 w-auto" sizes="160px" />}
|
|
98
|
-
{showName && <span>{siteName}</span>}
|
|
97
|
+
{logo && <KitImage image={logo} priority class="h-8 w-auto min-w-0 max-w-full object-contain" sizes="160px" />}
|
|
98
|
+
{showName && <span class="min-w-[3ch] shrink-[8] truncate">{siteName}</span>}
|
|
99
99
|
</a>
|
|
100
100
|
<p class={muted} data-kit-tagline>{tagline}</p>
|
|
101
101
|
</div>
|
|
102
102
|
)
|
|
103
103
|
: (
|
|
104
104
|
<a href={safeHref(homeHref)} class={brand()} aria-label={showName ? undefined : siteName} style={brandStyle} data-kit-brand>
|
|
105
|
-
{logo && <KitImage image={logo} priority class="h-8 w-auto" sizes="160px" />}
|
|
106
|
-
{showName && <span>{siteName}</span>}
|
|
105
|
+
{logo && <KitImage image={logo} priority class="h-8 w-auto min-w-0 max-w-full object-contain" sizes="160px" />}
|
|
106
|
+
{showName && <span class="min-w-[3ch] shrink-[8] truncate">{siteName}</span>}
|
|
107
107
|
</a>
|
|
108
108
|
)}
|
|
109
109
|
{search && (
|
|
@@ -211,5 +211,31 @@
|
|
|
211
211
|
}
|
|
212
212
|
},
|
|
213
213
|
{ "name": "search", "props": { "siteName": "Northwind Journal", "items": [{ "label": "Journal", "href": "/" }, { "label": "About", "href": "/about/" }], "search": { "label": "Search", "placeholder": "Search this site", "submitLabel": "Search" } } },
|
|
214
|
-
{"name": "mega-menu-search", "props": {"siteName": "Northwind", "menu": "mega", "items": [{"label": "Hakkımızda", "href": "/hakkimizda/"}, {"label": "Ürünlerimiz", "href": "#", "children": [{"label": "Aracım İçin", "href": "#", "children": [{"label": "Trafik Sigortası", "href": "/urunlerimiz/trafik-sigortasi/"}, {"label": "Kasko", "href": "/urunlerimiz/kasko/"}]}, {"label": "Evim İçin", "href": "#", "children": [{"label": "Dask", "href": "/urunlerimiz/dask/"}, {"label": "Konut Sigortası", "href": "/urunlerimiz/konut-sigortasi/"}]}, {"label": "Sağlığım İçin", "href": "#", "children": [{"label": "Sağlık Sigortası", "href": "/urunlerimiz/saglik-sigortasi/"}, {"label": "Tamamlayıcı Sağlık", "href": "/urunlerimiz/tamamlayici-saglik/"}]}, {"label": "Diğer", "href": "#", "children": [{"label": "İş Yeri Sigortası", "href": "/urunlerimiz/is-yeri-sigortasi/"}, {"label": "Seyahat Sigortası", "href": "/urunlerimiz/seyahat-sigortasi/"}]}]}, {"label": "Anlaşmalı Sigorta Şirketleri", "href": "/anlasmali-sigorta-sirketleri/"}, {"label": "İletişim", "href": "/iletisim/"}], "action": {"label": "Get a quote", "href": "/contact/"}, "search": {"label": "Search", "placeholder": "Ara", "submitLabel": "Ara"}}}
|
|
214
|
+
{"name": "mega-menu-search", "props": {"siteName": "Northwind", "menu": "mega", "items": [{"label": "Hakkımızda", "href": "/hakkimizda/"}, {"label": "Ürünlerimiz", "href": "#", "children": [{"label": "Aracım İçin", "href": "#", "children": [{"label": "Trafik Sigortası", "href": "/urunlerimiz/trafik-sigortasi/"}, {"label": "Kasko", "href": "/urunlerimiz/kasko/"}]}, {"label": "Evim İçin", "href": "#", "children": [{"label": "Dask", "href": "/urunlerimiz/dask/"}, {"label": "Konut Sigortası", "href": "/urunlerimiz/konut-sigortasi/"}]}, {"label": "Sağlığım İçin", "href": "#", "children": [{"label": "Sağlık Sigortası", "href": "/urunlerimiz/saglik-sigortasi/"}, {"label": "Tamamlayıcı Sağlık", "href": "/urunlerimiz/tamamlayici-saglik/"}]}, {"label": "Diğer", "href": "#", "children": [{"label": "İş Yeri Sigortası", "href": "/urunlerimiz/is-yeri-sigortasi/"}, {"label": "Seyahat Sigortası", "href": "/urunlerimiz/seyahat-sigortasi/"}]}]}, {"label": "Anlaşmalı Sigorta Şirketleri", "href": "/anlasmali-sigorta-sirketleri/"}, {"label": "İletişim", "href": "/iletisim/"}], "action": {"label": "Get a quote", "href": "/contact/"}, "search": {"label": "Search", "placeholder": "Ara", "submitLabel": "Ara"}}},
|
|
215
|
+
{
|
|
216
|
+
"name": "wide-logo-long-name",
|
|
217
|
+
"props": {
|
|
218
|
+
"siteName": "Northwind Journal of Coastal Gardens",
|
|
219
|
+
"logo": {
|
|
220
|
+
"src": "/kit-fixtures/logo-wide.svg",
|
|
221
|
+
"alt": "",
|
|
222
|
+
"width": 230,
|
|
223
|
+
"height": 32
|
|
224
|
+
},
|
|
225
|
+
"items": [
|
|
226
|
+
{
|
|
227
|
+
"label": "Journal",
|
|
228
|
+
"href": "/"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"label": "About",
|
|
232
|
+
"href": "/about/"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"label": "Contact",
|
|
236
|
+
"href": "/contact/"
|
|
237
|
+
}
|
|
238
|
+
]
|
|
239
|
+
}
|
|
240
|
+
}
|
|
215
241
|
]
|
|
@@ -13,6 +13,8 @@ import { coverHeight as heightOf, headingStyle as styleOf } from './hero'
|
|
|
13
13
|
import { muted, mutedInverse } from '../_shared/muted'
|
|
14
14
|
import { BLEED } from '../_shared/bleed'
|
|
15
15
|
|
|
16
|
+
const SCREEN = 'sm:flex sm:flex-col sm:min-h-[calc(100vh-var(--header-h,0px))] sm:supports-[height:100svh]:min-h-[calc(100svh-var(--header-h,0px))] sm:[&>.container-page]:flex sm:[&>.container-page]:flex-1 sm:[&>.container-page]:flex-col sm:[&>.container-page>.grid]:flex-1'
|
|
17
|
+
|
|
16
18
|
const hero = tv({
|
|
17
19
|
slots: {
|
|
18
20
|
grid: 'grid items-center gap-10',
|
|
@@ -60,6 +62,12 @@ const hero = tv({
|
|
|
60
62
|
// padding: set at the grid's bottom and moved past the hero's own bottom padding (`spacing="lg"`: 4rem, 7rem from md),
|
|
61
63
|
// not laid out there, so the next section stays where it was. Only an image that comes last can cross the bottom: one
|
|
62
64
|
// that comes first (`media-first`) would be moved down over the text, so there overlap draws as edge.
|
|
65
|
+
// Centered only (split and cover ignore it): from md the copy's start edge sits at this share of the frame's width,
|
|
66
|
+
// its text at that edge; below md it is centred, as without it.
|
|
67
|
+
inset: { none: {}, '15': {}, '27': {}, '34': {}, '42': {} },
|
|
68
|
+
// Where the content sits in a hero taller than it (a screen-high one, a cover): where the layout puts it, or on the
|
|
69
|
+
// bottom edge, the section's bottom padding under it.
|
|
70
|
+
contentAt: { start: {}, end: { grid: 'content-end' } },
|
|
63
71
|
imageBleed: { none: {}, edge: { media: 'rounded-none' }, overlap: { media: 'relative z-10 self-end translate-y-[calc(4rem+var(--hero-overlap,3rem))] rounded-none md:translate-y-[calc(7rem+var(--hero-overlap,3rem))]' } },
|
|
64
72
|
},
|
|
65
73
|
compoundVariants: [
|
|
@@ -69,8 +77,14 @@ const hero = tv({
|
|
|
69
77
|
// After the centring rules, so the lead leaves them.
|
|
70
78
|
{ leadAlign: 'start', class: { lead: 'mx-0 max-w-none self-stretch text-start' } },
|
|
71
79
|
{ actionsAlign: 'start', class: { actions: 'justify-start self-stretch' } },
|
|
80
|
+
// After the centring rules, so the copy leaves them from md.
|
|
81
|
+
{ layout: 'centered', inset: ['15', '27', '34', '42'], class: { copy: 'md:items-start md:text-start', lead: 'md:mx-0', points: 'md:justify-start', actions: 'md:justify-start' } },
|
|
82
|
+
{ layout: 'centered', inset: '15', class: { copy: 'md:ms-[15%]' } },
|
|
83
|
+
{ layout: 'centered', inset: '27', class: { copy: 'md:ms-[27%]' } },
|
|
84
|
+
{ layout: 'centered', inset: '34', class: { copy: 'md:ms-[34%]' } },
|
|
85
|
+
{ layout: 'centered', inset: '42', class: { copy: 'md:ms-[42%]' } },
|
|
72
86
|
],
|
|
73
|
-
defaultVariants: { layout: 'split', tone: 'default', align: 'center', leadAlign: 'inherit', actionsAlign: 'inherit', width: 'full', headingScale: 'default', headingSize: 'own', headingLines: 'flow', stackOrder: 'text-first', imageBleed: 'none' },
|
|
87
|
+
defaultVariants: { layout: 'split', tone: 'default', align: 'center', leadAlign: 'inherit', actionsAlign: 'inherit', width: 'full', headingScale: 'default', headingSize: 'own', headingLines: 'flow', stackOrder: 'text-first', inset: 'none', contentAt: 'start', imageBleed: 'none' },
|
|
74
88
|
})
|
|
75
89
|
|
|
76
90
|
interface Props {
|
|
@@ -106,17 +120,23 @@ interface Props {
|
|
|
106
120
|
stackOrder?: 'text-first' | 'media-first' | undefined
|
|
107
121
|
/** Split and centered: `edge` runs the image on to the window's edge on its side (both sides when centered); `overlap` also lets it cross the section's bottom edge by `--hero-overlap` (3rem), when the image comes last (with `media-first` it draws as `edge`). `none` (absent): as before. */
|
|
108
122
|
imageBleed?: 'none' | 'edge' | 'overlap' | undefined
|
|
123
|
+
/** Centered only: from md the copy starts at this share of the frame's width (`15` … `42` %), its text at that edge. `none` (absent): as before. */
|
|
124
|
+
inset?: 'none' | '15' | '27' | '34' | '42' | undefined
|
|
125
|
+
/** `screen`: from sm the hero is at least the window's height less `--header-h` (a site that sets it; 0 without), on phones as before. A boxed cover (`width: content`) ignores it. `auto` (absent): as before. */
|
|
126
|
+
height?: 'auto' | 'screen' | undefined
|
|
127
|
+
/** `end`: the content sits on the hero's bottom edge, in a hero taller than it (`height: screen`, a cover). `start` (absent): where the layout puts it, as before. */
|
|
128
|
+
contentAt?: 'start' | 'end' | undefined
|
|
109
129
|
/** The source section's measured style (`MeasuredStyle`): frame, padding, fill, background image, columns per width, gap. Absent, the site's tokens; present, it wins over tone and columns. */
|
|
110
130
|
measured?: MeasuredStyle | undefined
|
|
111
131
|
}
|
|
112
132
|
|
|
113
133
|
|
|
114
|
-
const { heading, level = 1, eyebrow, lead, items = [], actions = [], image, layout = 'split', align, leadAlign, actionsAlign, width = 'full', tone, id: givenId, minHeight, headingScale, headingSize, headingLines, stackOrder, imageBleed, measured } = Astro.props
|
|
134
|
+
const { heading, level = 1, eyebrow, lead, items = [], actions = [], image, layout = 'split', align, leadAlign, actionsAlign, width = 'full', tone, id: givenId, minHeight, headingScale, headingSize, headingLines, stackOrder, imageBleed, inset, height, contentAt, measured } = Astro.props
|
|
115
135
|
// Every section has an id, so a theme or a design layer can address this one: the page's, or `hero`, `hero-2`, … in render order.
|
|
116
136
|
const id = instanceId(Astro.locals, givenId, 'hero')
|
|
117
137
|
// Overlap moves the image down past the section's bottom, so only an image that comes last may: first, it is edge.
|
|
118
138
|
const bleedAs = imageBleed === 'overlap' && stackOrder === 'media-first' ? 'edge' : imageBleed
|
|
119
|
-
const s = hero({ layout, align, leadAlign, actionsAlign, width, tone, headingScale, headingSize, headingLines, stackOrder, imageBleed: bleedAs })
|
|
139
|
+
const s = hero({ layout, align, leadAlign, actionsAlign, width, tone, headingScale, headingSize, headingLines, stackOrder, inset, contentAt, imageBleed: bleedAs })
|
|
120
140
|
const Heading = level === 1 ? 'h1' : 'h2'
|
|
121
141
|
const headingId = `${id}-title`
|
|
122
142
|
const cover = layout === 'cover' && image
|
|
@@ -127,6 +147,10 @@ const sectionMeasured = cover && measured ? { ...measured, bg: measured.bg ? { .
|
|
|
127
147
|
const scrim = cover ? measuredFrame(measured).overlay : undefined
|
|
128
148
|
// The window's edge for a bleeding image: its own side in split (the start side when it comes first), both when centered.
|
|
129
149
|
const bleeds = !cover && image && imageBleed !== undefined && imageBleed !== 'none'
|
|
150
|
+
// A screen-high hero from sm: the section is a column at least the window's height (less a header the site measures as
|
|
151
|
+
// `--header-h`), its frame and grid stretched to fill it, so `contentAt` has the room to place the content in. 100vh
|
|
152
|
+
// where the small viewport unit is unknown. On phones the hero is as tall as its content.
|
|
153
|
+
const screen = height === 'screen' && !(cover && width === 'content') ? SCREEN : undefined
|
|
130
154
|
const bleed = bleeds ? (layout === 'centered' ? `max-w-none md:w-auto ${BLEED.start} ${BLEED.end}` : BLEED[stackOrder === 'media-first' ? 'start' : 'end']) : undefined
|
|
131
155
|
---
|
|
132
156
|
{cover && width === 'content'
|
|
@@ -151,7 +175,7 @@ const bleed = bleeds ? (layout === 'centered' ? `max-w-none md:w-auto ${BLEED.st
|
|
|
151
175
|
)
|
|
152
176
|
: cover
|
|
153
177
|
? (
|
|
154
|
-
<Section kit="hero" measured={sectionMeasured} tone="inverse" spacing="none" width="none" id={id} aria-labelledby={headingId} class=
|
|
178
|
+
<Section kit="hero" measured={sectionMeasured} tone="inverse" spacing="none" width="none" id={id} aria-labelledby={headingId} class={screen ? `relative isolate overflow-hidden ${screen}` : 'relative isolate overflow-hidden'}>
|
|
155
179
|
<KitImage image={image} priority sizes="100vw" class="absolute inset-0 -z-10 h-full w-full object-cover" />
|
|
156
180
|
<div class:list={['absolute inset-0 -z-10', !scrim && 'bg-ink/60']} style={scrim ? `background: ${scrim}` : undefined} aria-hidden="true" />
|
|
157
181
|
<div class:list={['container-page', measured?.padY === undefined && 'py-16 md:py-28']}>
|
|
@@ -168,7 +192,7 @@ const bleed = bleeds ? (layout === 'centered' ? `max-w-none md:w-auto ${BLEED.st
|
|
|
168
192
|
</Section>
|
|
169
193
|
)
|
|
170
194
|
: (
|
|
171
|
-
<Section kit="hero" measured={sectionMeasured} tone={tone} spacing="lg" id={id} aria-labelledby={headingId} class={bleeds
|
|
195
|
+
<Section kit="hero" measured={sectionMeasured} tone={tone} spacing="lg" id={id} aria-labelledby={headingId} class={[bleeds && 'overflow-x-clip', screen].filter(Boolean).join(' ') || undefined}>
|
|
172
196
|
{/* Without an image a split has nothing beside the text: the text takes the whole row, not half of it. */}
|
|
173
197
|
<div class={s.grid({ class: image ? undefined : 'md:grid-cols-1' })}>
|
|
174
198
|
<div class={s.copy()}>
|
|
@@ -248,5 +248,122 @@
|
|
|
248
248
|
{"name": "split-overlap", "props": {"heading": "Your site, moved and checked", "lead": "Every page, address and form carried over.", "imageBleed": "overlap", "tone": "muted", "image": {"src": "/kit-fixtures/photo-1.svg", "alt": "A desk by a window", "width": 1200, "height": 800}}},
|
|
249
249
|
{"name": "centered-media-first-overlap", "props": {"layout": "centered", "heading": "Your site, moved and checked", "lead": "Every page, address and form carried over.", "stackOrder": "media-first", "imageBleed": "overlap", "tone": "muted", "image": {"src": "/kit-fixtures/photo-1.svg", "alt": "A desk by a window", "width": 1200, "height": 800}}},
|
|
250
250
|
{"name": "split-media-first-overlap", "props": {"heading": "Your site, moved and checked", "lead": "Every page, address and form carried over.", "stackOrder": "media-first", "imageBleed": "overlap", "tone": "muted", "image": {"src": "/kit-fixtures/photo-1.svg", "alt": "A desk by a window", "width": 1200, "height": 800}}},
|
|
251
|
-
{"name": "heading-hooks", "theme": {"--font-heading": "var(--font-serif)", "--tracking-heading": "0.04em"}, "props": {"layout": "centered", "eyebrow": "A design direction", "heading": "Headings in a face of their own", "lead": "The heading face and track come from the theme; the lead keeps the body face."}}
|
|
251
|
+
{"name": "heading-hooks", "theme": {"--font-heading": "var(--font-serif)", "--tracking-heading": "0.04em"}, "props": {"layout": "centered", "eyebrow": "A design direction", "heading": "Headings in a face of their own", "lead": "The heading face and track come from the theme; the lead keeps the body face."}},
|
|
252
|
+
{
|
|
253
|
+
"name": "centered-inset-42",
|
|
254
|
+
"props": {
|
|
255
|
+
"heading": "Plan a calmer trip",
|
|
256
|
+
"lead": "Our guides pick fewer places and give each one more time.",
|
|
257
|
+
"layout": "centered",
|
|
258
|
+
"tone": "muted",
|
|
259
|
+
"level": 2,
|
|
260
|
+
"actions": [
|
|
261
|
+
{
|
|
262
|
+
"label": "Browse guides",
|
|
263
|
+
"href": "/category/guides/"
|
|
264
|
+
}
|
|
265
|
+
],
|
|
266
|
+
"image": {
|
|
267
|
+
"src": "/kit-fixtures/photo-2.svg",
|
|
268
|
+
"alt": "",
|
|
269
|
+
"width": 1600,
|
|
270
|
+
"height": 700
|
|
271
|
+
},
|
|
272
|
+
"inset": "42"
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"name": "centered-lead-start-inset-15",
|
|
277
|
+
"props": {
|
|
278
|
+
"heading": "About the studio",
|
|
279
|
+
"lead": "We are a small team of editors and photographers. This page tells you who we are, how we work and what we will never do with your data.",
|
|
280
|
+
"layout": "centered",
|
|
281
|
+
"leadAlign": "start",
|
|
282
|
+
"level": 2,
|
|
283
|
+
"inset": "15"
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"name": "heading-lines-inset-27",
|
|
288
|
+
"props": {
|
|
289
|
+
"layout": "centered",
|
|
290
|
+
"tone": "accent",
|
|
291
|
+
"headingLines": "lines",
|
|
292
|
+
"eyebrow": "Northwind Journal",
|
|
293
|
+
"heading": "Slow travel.\nGood coffee.\nTwelve years on the road.",
|
|
294
|
+
"lead": "Essays, guides and photographs, now in one place.",
|
|
295
|
+
"actions": [
|
|
296
|
+
{
|
|
297
|
+
"label": "Start reading",
|
|
298
|
+
"href": "/journal/"
|
|
299
|
+
}
|
|
300
|
+
],
|
|
301
|
+
"inset": "27"
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"name": "centered-size-h2-inset-34",
|
|
306
|
+
"props": {
|
|
307
|
+
"heading": "Plan a calmer trip",
|
|
308
|
+
"lead": "Our guides pick fewer places and give each one more time.",
|
|
309
|
+
"layout": "centered",
|
|
310
|
+
"tone": "muted",
|
|
311
|
+
"level": 2,
|
|
312
|
+
"actions": [
|
|
313
|
+
{
|
|
314
|
+
"label": "Browse guides",
|
|
315
|
+
"href": "/category/guides/"
|
|
316
|
+
}
|
|
317
|
+
],
|
|
318
|
+
"image": {
|
|
319
|
+
"src": "/kit-fixtures/photo-2.svg",
|
|
320
|
+
"alt": "",
|
|
321
|
+
"width": 1600,
|
|
322
|
+
"height": 700
|
|
323
|
+
},
|
|
324
|
+
"headingSize": "h2",
|
|
325
|
+
"inset": "34"
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
"name": "heading-lines-screen-end-inset-42",
|
|
330
|
+
"props": {
|
|
331
|
+
"layout": "centered",
|
|
332
|
+
"tone": "accent",
|
|
333
|
+
"headingLines": "lines",
|
|
334
|
+
"eyebrow": "Northwind Journal",
|
|
335
|
+
"heading": "Slow travel.\nGood coffee.\nTwelve years on the road.",
|
|
336
|
+
"lead": "Essays, guides and photographs, now in one place.",
|
|
337
|
+
"actions": [
|
|
338
|
+
{
|
|
339
|
+
"label": "Start reading",
|
|
340
|
+
"href": "/journal/"
|
|
341
|
+
}
|
|
342
|
+
],
|
|
343
|
+
"height": "screen",
|
|
344
|
+
"contentAt": "end",
|
|
345
|
+
"inset": "42"
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
"name": "cover-content-at-end",
|
|
350
|
+
"props": {
|
|
351
|
+
"heading": "The long way round",
|
|
352
|
+
"lead": "A year of trains across Europe, one station at a time.",
|
|
353
|
+
"layout": "cover",
|
|
354
|
+
"actions": [
|
|
355
|
+
{
|
|
356
|
+
"label": "Read the series",
|
|
357
|
+
"href": "/series/long-way/"
|
|
358
|
+
}
|
|
359
|
+
],
|
|
360
|
+
"image": {
|
|
361
|
+
"src": "/kit-fixtures/photo-3.svg",
|
|
362
|
+
"alt": "",
|
|
363
|
+
"width": 1600,
|
|
364
|
+
"height": 900
|
|
365
|
+
},
|
|
366
|
+
"contentAt": "end"
|
|
367
|
+
}
|
|
368
|
+
}
|
|
252
369
|
]
|
|
@@ -109,6 +109,33 @@
|
|
|
109
109
|
],
|
|
110
110
|
"default": "none",
|
|
111
111
|
"description": "Split and centered: edge runs the image on to the window's edge on its side (both sides when centered); overlap also lets it cross the section's bottom edge by --hero-overlap (3rem), over the next section's top padding, when the image comes last: with stackOrder media-first it draws as edge, so it never covers the text. A cover ignores it."
|
|
112
|
+
},
|
|
113
|
+
"inset": {
|
|
114
|
+
"options": [
|
|
115
|
+
"none",
|
|
116
|
+
"15",
|
|
117
|
+
"27",
|
|
118
|
+
"34",
|
|
119
|
+
"42"
|
|
120
|
+
],
|
|
121
|
+
"default": "none",
|
|
122
|
+
"description": "Layout centered only (split and cover ignore it). From md (768px) up, the copy's start edge sits at this share of the frame's width and its text is set at that edge, not centred: a statement on an axis, the void before it part of the page. Below md the hero is centred as without it. none: as before."
|
|
123
|
+
},
|
|
124
|
+
"height": {
|
|
125
|
+
"options": [
|
|
126
|
+
"auto",
|
|
127
|
+
"screen"
|
|
128
|
+
],
|
|
129
|
+
"default": "auto",
|
|
130
|
+
"description": "The hero's height. screen: from sm (640px) up, at least the window's height (100svh, 100vh where unknown) less --header-h, the header's height where the site sets it (0 without, so a static header above adds to it): the page opens on one full screen, the statement placed in it by contentAt. Below sm the hero is as tall as its content, as with auto: no empty screen on a phone. A boxed cover (width content) ignores it. auto: as before."
|
|
131
|
+
},
|
|
132
|
+
"contentAt": {
|
|
133
|
+
"options": [
|
|
134
|
+
"start",
|
|
135
|
+
"end"
|
|
136
|
+
],
|
|
137
|
+
"default": "start",
|
|
138
|
+
"description": "Where the content sits in a hero taller than it (height screen, or a cover with its own height). end: on the bottom edge, the section's bottom padding under it (a title on the image's lower edge, a statement after a void). start: where the layout puts it, as before."
|
|
112
139
|
}
|
|
113
140
|
},
|
|
114
141
|
"props": {
|
|
@@ -13,8 +13,11 @@ const prose = tv({
|
|
|
13
13
|
base: 'prose prose-site max-w-none',
|
|
14
14
|
variants: {
|
|
15
15
|
size: { base: 'prose-base', lg: 'prose-lg' },
|
|
16
|
+
// From md, the body's start edge sits at this share of its container's width (the axis an editorial layout sets
|
|
17
|
+
// its text on); it runs to the container's end. Below md it is the full column, as without it.
|
|
18
|
+
inset: { none: '', '15': 'md:ms-[15%]', '27': 'md:ms-[27%]', '34': 'md:ms-[34%]', '42': 'md:ms-[42%]' },
|
|
16
19
|
},
|
|
17
|
-
defaultVariants: { size: 'lg' },
|
|
20
|
+
defaultVariants: { size: 'lg', inset: 'none' },
|
|
18
21
|
})
|
|
19
22
|
|
|
20
23
|
interface Props {
|
|
@@ -26,9 +29,11 @@ interface Props {
|
|
|
26
29
|
searchable?: boolean | undefined
|
|
27
30
|
class?: string | undefined
|
|
28
31
|
size?: 'base' | 'lg' | undefined
|
|
32
|
+
/** From md, the body starts at this share of its container's width (`15` … `42` %). `none` (absent): as before. */
|
|
33
|
+
inset?: 'none' | '15' | '27' | '34' | '42' | undefined
|
|
29
34
|
}
|
|
30
35
|
|
|
31
|
-
const { html, markdown, searchable = true, class: className, size } = Astro.props
|
|
36
|
+
const { html, markdown, searchable = true, class: className, size, inset } = Astro.props
|
|
32
37
|
const body = html ?? await renderMarkdown(markdown)
|
|
33
38
|
---
|
|
34
|
-
{body && <div class={prose({ size, class: className })} data-pagefind-body={searchable ? '' : undefined} set:html={body} />}
|
|
39
|
+
{body && <div class={prose({ size, inset, class: className })} data-pagefind-body={searchable ? '' : undefined} set:html={body} />}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
[
|
|
2
2
|
{ "name": "lg", "frame": "narrow", "props": { "html": "<h2 class=\"wp-block-heading\">Keeping what works</h2><p>A careful migration keeps <strong>addresses</strong>, <a href=\"/about/\">formatting</a> and rankings.</p><ul class=\"wp-block-list\"><li>Permalinks stay put.</li><li>Archives survive.</li></ul><blockquote class=\"wp-block-quote\"><p>The fastest request is the one the server never has to think about.</p><cite>Every performance engineer</cite></blockquote><div class=\"wp-block-buttons is-layout-flex\"><div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"/contact/\">Get in touch</a></div></div>" } },
|
|
3
3
|
{ "name": "base", "frame": "narrow", "props": { "size": "base", "searchable": false, "html": "<p class=\"has-drop-cap\">Moving a WordPress site to a static stack is mostly about keeping what already works.</p><figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th>Metric</th><th>Before</th><th>After</th></tr></thead><tbody><tr><td>Requests</td><td>84</td><td>9</td></tr><tr><td>LCP</td><td>3.1 s</td><td>0.8 s</td></tr></tbody></table></figure>" } },
|
|
4
|
-
{ "name": "markdown", "frame": "narrow", "props": { "markdown": "## From a page section\n\nA section's text is **markdown** in the page model, with [a link](/about/) and a list:\n\n- Written once\n- Rendered at build time", "size": "base" } }
|
|
4
|
+
{ "name": "markdown", "frame": "narrow", "props": { "markdown": "## From a page section\n\nA section's text is **markdown** in the page model, with [a link](/about/) and a list:\n\n- Written once\n- Rendered at build time", "size": "base" } },
|
|
5
|
+
{ "name": "inset-15", "frame": "page", "props": { "html": "<h2 class=\"wp-block-heading\">Keeping what works</h2><p>A careful migration keeps <strong>addresses</strong>, <a href=\"/about/\">formatting</a> and rankings.</p><ul class=\"wp-block-list\"><li>Permalinks stay put.</li><li>Archives survive.</li></ul><blockquote class=\"wp-block-quote\"><p>The fastest request is the one the server never has to think about.</p><cite>Every performance engineer</cite></blockquote><div class=\"wp-block-buttons is-layout-flex\"><div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"/contact/\">Get in touch</a></div></div>", "inset": "15" } },
|
|
6
|
+
{ "name": "inset-27", "frame": "page", "props": { "size": "base", "searchable": false, "html": "<p class=\"has-drop-cap\">Moving a WordPress site to a static stack is mostly about keeping what already works.</p><figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th>Metric</th><th>Before</th><th>After</th></tr></thead><tbody><tr><td>Requests</td><td>84</td><td>9</td></tr><tr><td>LCP</td><td>3.1 s</td><td>0.8 s</td></tr></tbody></table></figure>", "inset": "27" } },
|
|
7
|
+
{ "name": "inset-34", "frame": "page", "props": { "markdown": "## From a page section\n\nA section's text is **markdown** in the page model, with [a link](/about/) and a list:\n\n- Written once\n- Rendered at build time", "size": "base", "inset": "34" } },
|
|
8
|
+
{ "name": "inset-42", "frame": "page", "props": { "html": "<h2 class=\"wp-block-heading\">Keeping what works</h2><p>A careful migration keeps <strong>addresses</strong>, <a href=\"/about/\">formatting</a> and rankings.</p><ul class=\"wp-block-list\"><li>Permalinks stay put.</li><li>Archives survive.</li></ul><blockquote class=\"wp-block-quote\"><p>The fastest request is the one the server never has to think about.</p><cite>Every performance engineer</cite></blockquote><div class=\"wp-block-buttons is-layout-flex\"><div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"/contact/\">Get in touch</a></div></div>", "inset": "42" } }
|
|
5
9
|
]
|
|
@@ -13,6 +13,17 @@
|
|
|
13
13
|
],
|
|
14
14
|
"default": "lg",
|
|
15
15
|
"description": "Type scale of the body."
|
|
16
|
+
},
|
|
17
|
+
"inset": {
|
|
18
|
+
"options": [
|
|
19
|
+
"none",
|
|
20
|
+
"15",
|
|
21
|
+
"27",
|
|
22
|
+
"34",
|
|
23
|
+
"42"
|
|
24
|
+
],
|
|
25
|
+
"default": "none",
|
|
26
|
+
"description": "From md (768px) up, the body's start edge sits at this share of its container's width and the body runs to the container's end: the axis an editorial page sets its text on (an intro in a narrow column, a column set off the page's start). Below md it is the full column. none: as before. The share is of the container the body sits in (in the starter's pages, the reading column)."
|
|
16
27
|
}
|
|
17
28
|
},
|
|
18
29
|
"props": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentrain/astro-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Copy-in Astro components for Contentrain sites (shadcn model): typed props, tailwind-variants, zero JavaScript by default — with a machine-readable catalog",
|
|
6
6
|
"type": "module",
|