Compare commits
6 Commits
32455b5497
...
46a45d7160
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46a45d7160 | ||
|
|
ac4ba1523c | ||
|
|
7456205750 | ||
|
|
c71eebf919 | ||
|
|
bf89cdba6d | ||
|
|
c2fc45e7f7 |
@ -2,7 +2,7 @@
|
|||||||
name = "earthen"
|
name = "earthen"
|
||||||
display_name = "Earthen"
|
display_name = "Earthen"
|
||||||
scope = "@themes"
|
scope = "@themes"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
description = "Botanical nonprofit theme in moss, clay, sage and cream — hand-illustrated motifs for cause-driven sites."
|
description = "Botanical nonprofit theme in moss, clay, sage and cream — hand-illustrated motifs for cause-driven sites."
|
||||||
kind = "theme"
|
kind = "theme"
|
||||||
categories = ["templates"]
|
categories = ["templates"]
|
||||||
|
|||||||
BIN
preview.png
|
Before Width: | Height: | Size: 325 KiB After Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 325 KiB After Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 339 KiB After Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 246 KiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 251 KiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 3.0 MiB |
BIN
seed/media/botanical.jpg
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
seed/media/forest.jpg
Normal file
|
After Width: | Height: | Size: 415 KiB |
BIN
seed/media/hands-soil.jpg
Normal file
|
After Width: | Height: | Size: 317 KiB |
BIN
seed/media/leaf-veins.jpg
Normal file
|
After Width: | Height: | Size: 738 KiB |
BIN
seed/media/seedling.jpg
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
seed/media/terracotta.jpg
Normal file
|
After Width: | Height: | Size: 244 KiB |
500
seed/seed.json
@ -6,16 +6,74 @@
|
|||||||
"tagline": "We restore land with the people who live on it."
|
"tagline": "We restore land with the people who live on it."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"media": [
|
||||||
|
{
|
||||||
|
"id": "41830fd8-442a-4255-bc96-9fb12e428ef1",
|
||||||
|
"file": "media/hands-soil.jpg",
|
||||||
|
"alt": "Hands lowering a young seedling into dark soil",
|
||||||
|
"folder": "earthen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "152f8386-ecf1-4f0c-899a-2c947766644d",
|
||||||
|
"file": "media/seedling.jpg",
|
||||||
|
"alt": "Cupped hands holding a seedling above turned earth",
|
||||||
|
"folder": "earthen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "c71264ea-0217-4826-a796-baffab1cf041",
|
||||||
|
"file": "media/forest.jpg",
|
||||||
|
"alt": "Sunlight through moss-covered trees in regrown forest",
|
||||||
|
"folder": "earthen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "603fdac3-2fa5-4511-8357-aa65550d9a31",
|
||||||
|
"file": "media/leaf-veins.jpg",
|
||||||
|
"alt": "Rain-washed leaf showing its veins in deep green",
|
||||||
|
"folder": "earthen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "02a30527-5464-45e2-a1f9-529fd9f46787",
|
||||||
|
"file": "media/terracotta.jpg",
|
||||||
|
"alt": "Terracotta pots of native tube stock ready for planting",
|
||||||
|
"folder": "earthen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a8c164d1-5f0c-496d-bb77-d1e8ba769527",
|
||||||
|
"file": "media/botanical.jpg",
|
||||||
|
"alt": "Fern fronds unfurling on the forest floor",
|
||||||
|
"folder": "earthen"
|
||||||
|
}
|
||||||
|
],
|
||||||
"data_tables": [
|
"data_tables": [
|
||||||
{
|
{
|
||||||
"key": "contact_submissions",
|
"key": "contact_submissions",
|
||||||
"name": "Contact Enquiries",
|
"name": "Contact Enquiries",
|
||||||
"description": "Seeded contact-form submissions for the Rootline Trust demo. A submission becomes a row here and emails the site admins.",
|
"description": "Contact-form submissions for Rootline Trust. A submission becomes a row here and emails the site admins.",
|
||||||
"columns": [
|
"columns": [
|
||||||
{ "key": "name", "label": "Name", "type": "text", "required": true },
|
{
|
||||||
{ "key": "email", "label": "Email", "type": "email", "required": true },
|
"key": "name",
|
||||||
{ "key": "region", "label": "Region", "type": "text", "required": false },
|
"label": "Name",
|
||||||
{ "key": "message", "label": "Message", "type": "text", "required": true }
|
"type": "text",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "email",
|
||||||
|
"label": "Email",
|
||||||
|
"type": "email",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "region",
|
||||||
|
"label": "Region",
|
||||||
|
"type": "text",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "message",
|
||||||
|
"label": "Message",
|
||||||
|
"type": "text",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -31,42 +89,122 @@
|
|||||||
"slot": "hero",
|
"slot": "hero",
|
||||||
"sort_order": 1,
|
"sort_order": 1,
|
||||||
"content": {
|
"content": {
|
||||||
"template": "centered",
|
"template": "split",
|
||||||
"eyebrow": "Land restoration",
|
"eyebrow": "Land restoration",
|
||||||
"headline": "Bring the land back to life.",
|
"headline": "Bring the land back to life.",
|
||||||
"subheadline": "We restore land with the people who live on it.",
|
"subheadline": "We restore land with the people who live on it.",
|
||||||
"description": "Rootline Trust plants native cover, mends waterways and hands care of the land back to local hands. Small work, done every season, in places that need it.",
|
"description": "Rootline Trust plants native cover, mends waterways and hands the care of the land back to local hands. Small work, done every season, in the places that need it most.",
|
||||||
"ctaPrimary": { "text": "Donate", "url": "/contact" },
|
"backgroundImage": "media:41830fd8-442a-4255-bc96-9fb12e428ef1",
|
||||||
"ctaSecondary": { "text": "Read a field note", "url": "/blog" }
|
"mediaPosition": "right",
|
||||||
|
"ctaPrimary": {
|
||||||
|
"text": "Donate",
|
||||||
|
"url": "/contact"
|
||||||
|
},
|
||||||
|
"ctaSecondary": {
|
||||||
|
"text": "See our work",
|
||||||
|
"url": "/about"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"block_key": "earthen:impact_report",
|
"block_key": "stats",
|
||||||
"title": "Impact Report",
|
"title": "Season in numbers",
|
||||||
"slot": "main",
|
"slot": "main",
|
||||||
"sort_order": 1,
|
"sort_order": 1,
|
||||||
"content": {
|
"content": {
|
||||||
"period": "Season 2025",
|
"heading": "The last season, in the ground",
|
||||||
"title": "What we grew together",
|
"intro": "Every figure here is an acre planted, a bank mended, or a day given by someone who lives beside the work.",
|
||||||
"summary": "<p>Every acre here started as a pledge. This is where those pledges went last season. The figures below are example figures for this demo site.</p>",
|
"columns": 4,
|
||||||
"outcomes": [
|
"countUp": false,
|
||||||
{ "value": "840 acres", "label": "Native cover planted", "detail": "Across twelve restoration sites." },
|
"items": [
|
||||||
{ "value": "19 km", "label": "Creek bank mended", "detail": "Fenced, replanted and handed to local carers." },
|
{
|
||||||
{ "value": "1,200", "label": "Volunteer days", "detail": "Given by people who live near the work." }
|
"value": "840",
|
||||||
],
|
"suffix": " acres",
|
||||||
"sourceNote": "Example figures for demonstration."
|
"label": "Native cover planted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "19",
|
||||||
|
"suffix": " km",
|
||||||
|
"label": "Creek bank mended"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "1,200",
|
||||||
|
"label": "Volunteer days given"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "12",
|
||||||
|
"label": "Restoration sites"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "feature-grid",
|
||||||
|
"title": "How we work",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 2,
|
||||||
|
"content": {
|
||||||
|
"eyebrow": "How we work",
|
||||||
|
"heading": "Three steps, every site",
|
||||||
|
"intro": "Restoration is not one grand act. It is the same patient sequence, repeated season after season, with the people who live on the land.",
|
||||||
|
"columns": 3,
|
||||||
|
"layout": "card",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"icon": "lucide:sprout",
|
||||||
|
"title": "Plant native cover",
|
||||||
|
"text": "We raise local tube stock and plant the species that belong on each site — the ones that hold soil, feed pollinators and come back on their own."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "lucide:waves",
|
||||||
|
"title": "Mend the waterways",
|
||||||
|
"text": "We fence stock out of the creek lines, stabilise the banks and let the water run clean again. A mended creek carries a whole valley with it."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "lucide:heart-handshake",
|
||||||
|
"title": "Hand the land back",
|
||||||
|
"text": "From the first day we work beside local carers. By the third season we step back, and the people who live there keep it going."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "divider",
|
||||||
|
"title": "Botanical divider",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 3,
|
||||||
|
"content": {
|
||||||
|
"variant": "ornament",
|
||||||
|
"width": "wide",
|
||||||
|
"icon": "lucide:leaf"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"block_key": "earthen:field_note",
|
"block_key": "earthen:field_note",
|
||||||
"title": "Field Note",
|
"title": "Field Note",
|
||||||
"slot": "main",
|
"slot": "main",
|
||||||
"sort_order": 2,
|
"sort_order": 4,
|
||||||
"content": {
|
"content": {
|
||||||
"author": "Mara Ellison",
|
"author": "Mara Ellison",
|
||||||
"location": "Wirra Creek",
|
"location": "Wirra Creek",
|
||||||
"dateline": "March 2025",
|
"dateline": "March 2025",
|
||||||
"body": "<p>The first rain after planting is the one that tells you. We walked the creek line at dawn and the tube stock had held. Small green points, thousands of them, holding the bank against the next flood.</p><p>Restoration is slow. You plant, you fence, you wait. Then one morning the land answers back.</p>"
|
"image": "media:152f8386-ecf1-4f0c-899a-2c947766644d",
|
||||||
|
"body": "<p>The first rain after planting is the one that tells you. We walked the creek line at dawn and the tube stock had held — thousands of small green points, holding the bank against the next flood.</p><p>You plant, you fence, you wait. Restoration keeps its own slow clock. Then one ordinary morning the land answers back, and you understand you were only ever helping it remember what it already knew how to do.</p>"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "newsletter-signup",
|
||||||
|
"title": "Newsletter",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 5,
|
||||||
|
"content": {
|
||||||
|
"title": "Field notes in your inbox",
|
||||||
|
"description": "A short dispatch from the sites each season — what we planted, what held, and where we are headed next. No noise.",
|
||||||
|
"listSlug": "main",
|
||||||
|
"source": "home",
|
||||||
|
"submitText": "Subscribe",
|
||||||
|
"placeholder": "you@example.com",
|
||||||
|
"layout": "card"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -76,10 +214,90 @@
|
|||||||
"title": "Our work",
|
"title": "Our work",
|
||||||
"template_key": "default",
|
"template_key": "default",
|
||||||
"blocks": [
|
"blocks": [
|
||||||
{ "block_key": "heading", "title": "Heading", "slot": "main", "sort_order": 1, "content": { "text": "Our work", "level": 1 } },
|
{
|
||||||
{ "block_key": "rich-text", "title": "Story", "slot": "main", "sort_order": 2, "content": { "html": "<p>Rootline Trust began with one degraded paddock and a handful of neighbours who wanted it back. We plant native cover, mend waterways and fence stock out of creek lines. Then we hand the care of the land to the people who live beside it.</p><p>We work slowly and in public. Every site is chosen with local carers. Every season is reported to the people who fund it.</p>" } },
|
"block_key": "heading",
|
||||||
{ "block_key": "divider", "title": "Divider", "slot": "main", "sort_order": 3, "content": { "variant": "ornament", "icon": "lucide:sprout" } },
|
"title": "Heading",
|
||||||
{ "block_key": "quote", "title": "Quote", "slot": "main", "sort_order": 4, "content": { "style": "block", "align": "center", "quote": "You plant, you fence, you wait. Then the land answers back.", "attribution": "Mara Ellison, Field Lead" } }
|
"slot": "main",
|
||||||
|
"sort_order": 1,
|
||||||
|
"content": {
|
||||||
|
"text": "Our work",
|
||||||
|
"level": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "image",
|
||||||
|
"title": "Forest regrowth",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 3,
|
||||||
|
"content": {
|
||||||
|
"src": "media:a8c164d1-5f0c-496d-bb77-d1e8ba769527",
|
||||||
|
"alt": "Fern fronds unfurling on the forest floor",
|
||||||
|
"caption": "Ferns returning to the understorey at Wirra Creek, three seasons after fencing.",
|
||||||
|
"size": "lg",
|
||||||
|
"aspectRatio": "wide"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "rich-text",
|
||||||
|
"title": "Story",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 2,
|
||||||
|
"content": {
|
||||||
|
"html": "<p>Rootline Trust began with one degraded paddock and a handful of neighbours who wanted it back. We plant native cover, mend waterways and fence stock out of the creek lines. Then we hand the care of the land to the people who live beside it.</p><p>We work slowly and in public. Every site is chosen with local carers, planted from local stock, and reported honestly to the people who fund it. Nothing here happens in a season — it happens over three, or five, or ten, and it lasts because the people who live there stay long after we have gone.</p><p>We are a small trust on purpose. It keeps us close to the ground, close to the water, and close to the people whose land we are helping to mend.</p>"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "earthen:impact_report",
|
||||||
|
"title": "Impact Report",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 4,
|
||||||
|
"content": {
|
||||||
|
"period": "Season 2025",
|
||||||
|
"title": "What we grew together",
|
||||||
|
"summary": "<p>Every acre here began as a pledge from someone who wanted a piece of degraded land to come back. This is where those pledges went last season — twelve sites, one patient sequence, repeated until the ground took hold.</p>",
|
||||||
|
"outcomes": [
|
||||||
|
{
|
||||||
|
"value": "840 acres",
|
||||||
|
"label": "Native cover planted",
|
||||||
|
"detail": "Across twelve restoration sites, raised from local tube stock."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "19 km",
|
||||||
|
"label": "Creek bank mended",
|
||||||
|
"detail": "Fenced, replanted and handed to the carers who live beside it."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "1,200",
|
||||||
|
"label": "Volunteer days",
|
||||||
|
"detail": "Given by people who live within a day's drive of the work."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "divider",
|
||||||
|
"title": "Divider",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 5,
|
||||||
|
"content": {
|
||||||
|
"variant": "line",
|
||||||
|
"weight": "thin",
|
||||||
|
"width": "wide"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "quote",
|
||||||
|
"title": "Quote",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 6,
|
||||||
|
"content": {
|
||||||
|
"style": "pull",
|
||||||
|
"align": "left",
|
||||||
|
"quote": "You plant, you fence, you wait. Then the land answers back.",
|
||||||
|
"attribution": "Mara Ellison",
|
||||||
|
"role": "Field Lead, Wirra Creek"
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -87,9 +305,48 @@
|
|||||||
"title": "Field Journal",
|
"title": "Field Journal",
|
||||||
"template_key": "blog-index",
|
"template_key": "blog-index",
|
||||||
"blocks": [
|
"blocks": [
|
||||||
{ "block_key": "card", "title": "Post: First Rain", "slot": "main", "sort_order": 1, "content": { "layout": "vertical", "title": "The first rain after planting", "text": "<p>What a dawn walk along Wirra Creek tells you about a season of restoration.</p>", "link": "/blog/the-first-rain-after-planting", "linkLabel": "Read the dispatch" } },
|
{
|
||||||
{ "block_key": "card", "title": "Post: Fencing", "slot": "main", "sort_order": 2, "content": { "layout": "vertical", "title": "Why we fence before we plant", "text": "<p>The least glamorous work protects everything that comes after it.</p>", "link": "/blog/why-we-fence-before-we-plant", "linkLabel": "Read the dispatch" } },
|
"block_key": "card",
|
||||||
{ "block_key": "card", "title": "Post: Handover", "slot": "main", "sort_order": 3, "content": { "layout": "vertical", "title": "Handing the land back", "text": "<p>Restoration is not finished when we leave. It is finished when local carers take it on.</p>", "link": "/blog/handing-the-land-back", "linkLabel": "Read the dispatch" } }
|
"title": "Post: First Rain",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 1,
|
||||||
|
"content": {
|
||||||
|
"layout": "vertical",
|
||||||
|
"media": "media:603fdac3-2fa5-4511-8357-aa65550d9a31",
|
||||||
|
"title": "The first rain after planting",
|
||||||
|
"text": "<p>What a dawn walk along Wirra Creek tells you about a whole season of restoration.</p>",
|
||||||
|
"link": "/blog/the-first-rain-after-planting",
|
||||||
|
"linkLabel": "Read the dispatch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "card",
|
||||||
|
"title": "Post: Fencing",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 2,
|
||||||
|
"content": {
|
||||||
|
"layout": "vertical",
|
||||||
|
"media": "media:c71264ea-0217-4826-a796-baffab1cf041",
|
||||||
|
"title": "Why we fence before we plant",
|
||||||
|
"text": "<p>The least glamorous work on any site is the thing that protects everything that comes after it.</p>",
|
||||||
|
"link": "/blog/why-we-fence-before-we-plant",
|
||||||
|
"linkLabel": "Read the dispatch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "card",
|
||||||
|
"title": "Post: Handover",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 3,
|
||||||
|
"content": {
|
||||||
|
"layout": "vertical",
|
||||||
|
"media": "media:02a30527-5464-45e2-a1f9-529fd9f46787",
|
||||||
|
"title": "Handing the land back",
|
||||||
|
"text": "<p>Restoration is not finished when we leave. It is finished when the local carers take it on.</p>",
|
||||||
|
"link": "/blog/handing-the-land-back",
|
||||||
|
"linkLabel": "Read the dispatch"
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -98,8 +355,38 @@
|
|||||||
"template_key": "article",
|
"template_key": "article",
|
||||||
"parent_slug": "/blog",
|
"parent_slug": "/blog",
|
||||||
"blocks": [
|
"blocks": [
|
||||||
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "The first rain after planting", "level": 1 } },
|
{
|
||||||
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "<p>We walked the creek line at dawn and the tube stock had held. Small green points, thousands of them, holding the bank against the next flood.</p><p>The first rain after planting is the one that tells you whether the season will take. This one took. The soil was dark and the roots had gripped.</p><p>Restoration is slow. You plant, you fence, you wait. Then one morning the land answers back.</p>" } }
|
"block_key": "heading",
|
||||||
|
"title": "Title",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 1,
|
||||||
|
"content": {
|
||||||
|
"text": "The first rain after planting",
|
||||||
|
"level": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "image",
|
||||||
|
"title": "Creek line at dawn",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 2,
|
||||||
|
"content": {
|
||||||
|
"src": "media:c71264ea-0217-4826-a796-baffab1cf041",
|
||||||
|
"alt": "Sunlight through moss-covered trees in regrown forest",
|
||||||
|
"caption": "The oldest reach at Wirra Creek, three seasons in — canopy closing, bank holding.",
|
||||||
|
"size": "lg",
|
||||||
|
"aspectRatio": "wide"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "rich-text",
|
||||||
|
"title": "Body",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 3,
|
||||||
|
"content": {
|
||||||
|
"html": "<p>We walked the creek line at dawn, before the heat, the way we always do on the morning after the first real rain. The ground was dark and giving underfoot. Along the bank, where six weeks ago there had been bare clay and the stubble of old grazing, the tube stock had held — thousands of small green points, each one a native seedling with its roots now gripping the soil we had loosened for it.</p><p>The first rain after planting is the one that tells you. Everything before it is hope and hard work: you clear, you fence, you dig the holes on contour, you sink the tubes and firm the earth around each one. Then you wait, and you watch the sky, because a young planting that dries out in its first fortnight will not come back no matter how carefully it was put in. This rain came in the second week. It came slow and steady overnight, the kind that soaks in instead of running off, and by dawn the whole site had drunk it.</p><p>Restoration is slow, and it is meant to be. You cannot hurry a root system. You cannot argue a creek bank into stability. What you can do is give the land the conditions it needs and then get out of its way — fence the stock out, keep the weeds off the young growth, and let the seasons do the rest. We plant, we fence, we wait. It is the least heroic sequence imaginable, and it is the only one that works.</p><p>Wirra Creek was one of the worst sites we had taken on. Decades of stock had trodden the banks to bare earth; every flood carried another metre of topsoil downstream, and the water ran the colour of milky tea for days after any rain. When we first walked it with the carers who live along it, nobody pretended it would be quick. We agreed a ten-year horizon out loud, in the paddock, so that no one would mistake a single good season for the finish line.</p><p>The species matter more than people expect. We raise our tube stock from local seed — the sedges and wattles and paperbarks that already know this soil and this rainfall — because a plant that belongs on a site will hold on through the years we are not watching. The nursery work is unglamorous and it is where half the outcome is decided. A good seedling, hardened off properly, will take the first rain and run with it. A soft one, forced under lights and shipped in from far away, will sulk and die at the first hot week.</p><p>By mid-morning the sun was up and the carers had arrived to walk the line with us. There is a particular quiet that comes over people on a morning like that — nobody says much. You crouch by a tube, you feel the soil, you check that the guard has held and the stem is firm, and you move on to the next. Down the line someone laughs, because a seedling that was leaning last week has stood itself upright overnight, the way they do once the roots find water.</p><p>Not everything held. It never does. In the low corner where the flood sits longest we lost a run of tubes to waterlogging, and up on the dry western bank a few had been nosed out by something — a wallaby, most likely, testing the guards. We marked the gaps to replant in autumn. Losing some is part of the arithmetic; you plant knowing a portion will fail, and you plant enough that the survivors still close the canopy in time.</p><p>The fence is what makes all of it possible. Before a single tube goes in, we fence the stock out of the creek line and hold that line for years. It is the least glamorous work we do and it is the work that protects everything else. A good fence buys a young planting three quiet years to establish, and three years is usually all a native system needs to look after itself.</p><p>We finished the walk at the top of the reach, where the oldest planting — three seasons in now — has grown past head height and thrown enough shade that the bank beneath it stays damp and dark. Frogs have come back to that stretch. You can hear them after rain. It is the plainest possible proof that the work is working: you make a place liveable again, and the living things move back in without being asked.</p><p>That is the whole of it, really. You plant, you fence, you wait. Restoration keeps its own slow clock and there is no cheating it. Then one ordinary morning after rain the land answers back — a bank that holds, a creek that runs clear, a chorus of frogs where there was bare clay — and you understand that you were only ever helping the land remember what it already knew how to do.</p>"
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -108,8 +395,25 @@
|
|||||||
"template_key": "article",
|
"template_key": "article",
|
||||||
"parent_slug": "/blog",
|
"parent_slug": "/blog",
|
||||||
"blocks": [
|
"blocks": [
|
||||||
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Why we fence before we plant", "level": 1 } },
|
{
|
||||||
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "<p>Stock will find new growth before it has a chance to root. So we fence first. It is the least glamorous work we do and it protects everything that comes after.</p><p>A good fence buys a young planting three years of quiet. That is usually enough.</p>" } }
|
"block_key": "heading",
|
||||||
|
"title": "Title",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 1,
|
||||||
|
"content": {
|
||||||
|
"text": "Why we fence before we plant",
|
||||||
|
"level": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "rich-text",
|
||||||
|
"title": "Body",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 2,
|
||||||
|
"content": {
|
||||||
|
"html": "<p>Stock will find new growth before it has a chance to root. A single mob of cattle can undo a season's planting in an afternoon, and they always seem to know exactly where the softest new leaves are. So we fence first. Every time. It is the least glamorous work we do and it is the thing that protects everything that comes after.</p><p>A good fence buys a young planting three years of quiet — long enough for the roots to reach down, the canopy to start closing, and the site to stop needing us. Three years is usually all a native system asks for. Get the fence right and hold the line, and the rest of restoration is mostly patience.</p><p>People ask why we do not just plant more to make up for what gets eaten. The answer is that a fence is cheaper than a failure, and far cheaper than the heartbreak of walking a chewed-out site the morning after. We would rather spend the first budget on posts and wire than replant the same bank three times over.</p>"
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -118,8 +422,25 @@
|
|||||||
"template_key": "article",
|
"template_key": "article",
|
||||||
"parent_slug": "/blog",
|
"parent_slug": "/blog",
|
||||||
"blocks": [
|
"blocks": [
|
||||||
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Handing the land back", "level": 1 } },
|
{
|
||||||
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "<p>Restoration is not finished when we leave. It is finished when local carers take it on. We plant with them from the first day so the knowledge stays on the land.</p><p>By the third season we step back. The site keeps going because the people beside it keep going.</p>" } }
|
"block_key": "heading",
|
||||||
|
"title": "Title",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 1,
|
||||||
|
"content": {
|
||||||
|
"text": "Handing the land back",
|
||||||
|
"level": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "rich-text",
|
||||||
|
"title": "Body",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 2,
|
||||||
|
"content": {
|
||||||
|
"html": "<p>Restoration is not finished when we leave. It is finished when the local carers take it on. We plant with them from the first day — not as spectators, but with hands in the soil — so the knowledge stays on the land instead of leaving in the back of our ute.</p><p>By the third season we start to step back. The watering slows, the replanting tapers off, and the walks along the line become the carers' walks, not ours. The site keeps going because the people beside it keep going, and they keep going because it was theirs the whole way through.</p><p>We measure our success by how little we are needed at the end. A site we can walk away from is the goal. It sounds strange for an organisation to aim at its own irrelevance, but that is exactly the point: land that can look after itself, in the care of people who will be there long after the last of our fences has weathered grey.</p>"
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -138,12 +459,40 @@
|
|||||||
"submitLabel": "Send message",
|
"submitLabel": "Send message",
|
||||||
"successMessage": "Thank you. Your message has been received. We will reply by email.",
|
"successMessage": "Thank you. Your message has been received. We will reply by email.",
|
||||||
"fields": [
|
"fields": [
|
||||||
{ "name": "name", "label": "Your name", "type": "text", "required": true, "width": "half" },
|
{
|
||||||
{ "name": "email", "label": "Email", "type": "email", "required": true, "width": "half" },
|
"name": "name",
|
||||||
{ "name": "region", "label": "Region", "type": "text", "required": false, "width": "half" },
|
"label": "Your name",
|
||||||
{ "name": "message", "label": "How can we help?", "type": "textarea", "required": true, "width": "full" }
|
"type": "text",
|
||||||
|
"required": true,
|
||||||
|
"width": "half"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"label": "Email",
|
||||||
|
"type": "email",
|
||||||
|
"required": true,
|
||||||
|
"width": "half"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "region",
|
||||||
|
"label": "Region",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"width": "half"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "message",
|
||||||
|
"label": "How can we help?",
|
||||||
|
"type": "textarea",
|
||||||
|
"required": true,
|
||||||
|
"width": "full"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"formConfig": { "enabled": true, "captchaEnabled": false, "targetTable": "contact_submissions" }
|
"formConfig": {
|
||||||
|
"enabled": true,
|
||||||
|
"captchaEnabled": false,
|
||||||
|
"targetTable": "contact_submissions"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -154,10 +503,22 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"heading": "Office hours",
|
"heading": "Office hours",
|
||||||
"hours": [
|
"hours": [
|
||||||
{ "day": "Monday to Thursday", "hours": "9am to 5pm" },
|
{
|
||||||
{ "day": "Friday", "hours": "9am to 3pm" },
|
"day": "Monday to Thursday",
|
||||||
{ "day": "Saturday", "hours": "Field days only" },
|
"hours": "9am to 5pm"
|
||||||
{ "day": "Sunday", "closed": true }
|
},
|
||||||
|
{
|
||||||
|
"day": "Friday",
|
||||||
|
"hours": "9am to 3pm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"day": "Saturday",
|
||||||
|
"hours": "Field days only"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"day": "Sunday",
|
||||||
|
"closed": true
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"specialHoursNote": "Planting days run most weekends in autumn. Check the field journal.",
|
"specialHoursNote": "Planting days run most weekends in autumn. Check the field journal.",
|
||||||
"address": "3 Wattle Road\nWirra Creek",
|
"address": "3 Wattle Road\nWirra Creek",
|
||||||
@ -171,15 +532,52 @@
|
|||||||
"title": "Members",
|
"title": "Members",
|
||||||
"template_key": "auth",
|
"template_key": "auth",
|
||||||
"blocks": [
|
"blocks": [
|
||||||
{ "block_key": "auth-form", "title": "Sign in", "slot": "main", "sort_order": 1, "content": { "default_tab": "login", "show_social": false } },
|
{
|
||||||
{ "block_key": "text", "title": "Foot", "slot": "footer", "sort_order": 1, "content": { "text": "<p>Members track pledges and see each site's season report first.</p>" } }
|
"block_key": "auth-form",
|
||||||
|
"title": "Sign in",
|
||||||
|
"slot": "main",
|
||||||
|
"sort_order": 1,
|
||||||
|
"content": {
|
||||||
|
"default_tab": "login",
|
||||||
|
"show_social": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"block_key": "text",
|
||||||
|
"title": "Foot",
|
||||||
|
"slot": "footer",
|
||||||
|
"sort_order": 1,
|
||||||
|
"content": {
|
||||||
|
"text": "<p>Members track pledges and see each site's season report first.</p>"
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"menu_items": [
|
"menu_items": [
|
||||||
{ "menu": "main", "label": "Home", "page_slug": "/", "sort_order": 1 },
|
{
|
||||||
{ "menu": "main", "label": "Our work", "page_slug": "/about", "sort_order": 2 },
|
"menu": "main",
|
||||||
{ "menu": "main", "label": "Field Journal", "page_slug": "/blog", "sort_order": 3 },
|
"label": "Home",
|
||||||
{ "menu": "main", "label": "Get in touch", "page_slug": "/contact", "sort_order": 4 }
|
"page_slug": "/",
|
||||||
|
"sort_order": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"menu": "main",
|
||||||
|
"label": "Our work",
|
||||||
|
"page_slug": "/about",
|
||||||
|
"sort_order": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"menu": "main",
|
||||||
|
"label": "Field Journal",
|
||||||
|
"page_slug": "/blog",
|
||||||
|
"sort_order": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"menu": "main",
|
||||||
|
"label": "Get in touch",
|
||||||
|
"page_slug": "/contact",
|
||||||
|
"sort_order": 4
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -3,9 +3,7 @@
|
|||||||
{{ head_html|safe }}
|
{{ head_html|safe }}
|
||||||
<body class="bg-paper-grain earthen-body antialiased min-h-screen flex flex-col" style="background-color: hsl(var(--background)); color: hsl(var(--foreground)); font-family: var(--font-body, "Work Sans", ui-sans-serif, system-ui, sans-serif);">
|
<body class="bg-paper-grain earthen-body antialiased min-h-screen flex flex-col" style="background-color: hsl(var(--background)); color: hsl(var(--foreground)); font-family: var(--font-body, "Work Sans", ui-sans-serif, system-ui, sans-serif);">
|
||||||
{{ admin_banner_html|safe }}
|
{{ admin_banner_html|safe }}
|
||||||
<header class="w-full" style="border-bottom: 1px solid hsl(var(--border));">
|
<header class="w-full">{{ slots.header|safe }}</header>
|
||||||
<div class="max-w-3xl mx-auto px-4">{{ slots.header|safe }}</div>
|
|
||||||
</header>
|
|
||||||
{% if slots.lede %}<section class="w-full max-w-3xl mx-auto px-4 pt-12">{{ slots.lede|safe }}</section>{% endif %}
|
{% if slots.lede %}<section class="w-full max-w-3xl mx-auto px-4 pt-12">{{ slots.lede|safe }}</section>{% endif %}
|
||||||
<div class="flex-grow w-full grid grid-cols-1 lg:grid-cols-[1fr,260px] gap-12 max-w-5xl mx-auto px-4 py-12">
|
<div class="flex-grow w-full grid grid-cols-1 lg:grid-cols-[1fr,260px] gap-12 max-w-5xl mx-auto px-4 py-12">
|
||||||
<main>{% if slots.main %}<article class="earthen-article">{{ slots.main|safe }}</article>{% else %}<p style="color: hsl(var(--muted-foreground));">No story body yet.</p>{% endif %}</main>
|
<main>{% if slots.main %}<article class="earthen-article">{{ slots.main|safe }}</article>{% else %}<p style="color: hsl(var(--muted-foreground));">No story body yet.</p>{% endif %}</main>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<body class="bg-paper-grain earthen-body antialiased min-h-screen flex flex-col" style="background-color: hsl(var(--background)); color: hsl(var(--foreground)); font-family: var(--font-body, "Work Sans", ui-sans-serif, system-ui, sans-serif);">
|
<body class="bg-paper-grain earthen-body antialiased min-h-screen flex flex-col" style="background-color: hsl(var(--background)); color: hsl(var(--foreground)); font-family: var(--font-body, "Work Sans", ui-sans-serif, system-ui, sans-serif);">
|
||||||
{{ admin_banner_html|safe }}
|
{{ admin_banner_html|safe }}
|
||||||
<section class="w-full">{{ slots.hero|safe }}</section>
|
<section class="w-full">{{ slots.hero|safe }}</section>
|
||||||
<main class="flex-grow">{% if slots.main %}<div class="max-w-5xl mx-auto px-4 py-16">{{ slots.main|safe }}</div>{% endif %}</main>
|
<main class="flex-grow w-full">{% if slots.main %}{{ slots.main|safe }}{% endif %}</main>
|
||||||
<section class="w-full">{{ slots.cta|safe }}</section>
|
<section class="w-full">{{ slots.cta|safe }}</section>
|
||||||
<footer class="w-full mt-auto">{{ slots.footer|safe }}</footer>
|
<footer class="w-full mt-auto">{{ slots.footer|safe }}</footer>
|
||||||
{{ body_end_html|safe }}
|
{{ body_end_html|safe }}
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<div data-block-override="earthen:announcement-bar" data-bn-announcement data-bn-annkey="{{ variant|default:'info' }}:{{ message|slugify }}" class="bn-announcement w-full border-b border-border {{ anncls }} {{ class }}">
|
<div data-block-override="earthen:announcement-bar" data-bn-announcement data-bn-annkey="{{ variant|default:'info' }}:{{ message|slugify }}" class="bn-announcement w-full border-b border-border {{ anncls }} {{ class }}">
|
||||||
<div class="max-w-7xl mx-auto px-10 py-2 relative flex items-center justify-center gap-2 text-sm text-center">
|
<div class="max-w-7xl mx-auto px-10 py-2 relative flex items-center justify-center gap-2 text-sm text-center">
|
||||||
<p class="font-medium" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif);">{{ message }}{% if linkText and linkUrl %} <a href="{{ linkUrl }}" class="underline underline-offset-2 hover:opacity-80">{{ linkText }}</a>{% endif %}</p>
|
<p class="font-medium" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif);">{{ message }}{% if linkText and linkUrl %} <a href="{{ linkUrl }}" class="underline underline-offset-2 hover:opacity-80">{{ linkText }}</a>{% endif %}</p>
|
||||||
{% if dismissable %}<button type="button" data-bn-ann-dismiss aria-label="Dismiss announcement" class="absolute right-3 top-1/2 -translate-y-1/2 inline-flex items-center justify-center p-1 rounded-lg hover:bg-black/10 transition-colors"><svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg></button>{% endif %}
|
{% if dismissable %}<button type="button" data-bn-ann-dismiss aria-label="Dismiss announcement" class="absolute right-3 top-1/2 -translate-y-1/2 inline-flex items-center justify-center p-1 rounded-lg hover:bg-black/10 transition-colors"><svg width="16" height="16" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg></button>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if dismissable %}<script>
|
{% if dismissable %}<script>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<button type="button" onclick="this.nextElementSibling.classList.toggle('hidden')" class="flex items-center gap-2 text-sm font-medium opacity-90 hover:opacity-100 px-3 py-1.5 transition-colors">
|
<button type="button" onclick="this.nextElementSibling.classList.toggle('hidden')" class="flex items-center gap-2 text-sm font-medium opacity-90 hover:opacity-100 px-3 py-1.5 transition-colors">
|
||||||
<span class="inline-flex h-7 w-7 items-center justify-center rounded-full text-[0.7rem] font-bold" style="background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));">{{ context.publicDisplayName|default:context.publicUsername|first|upper }}</span>
|
<span class="inline-flex h-7 w-7 items-center justify-center rounded-full text-[0.7rem] font-bold" style="background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));">{{ context.publicDisplayName|default:context.publicUsername|first|upper }}</span>
|
||||||
<span>{{ context.publicDisplayName|default:context.publicUsername }}</span>
|
<span>{{ context.publicDisplayName|default:context.publicUsername }}</span>
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
|
<svg width="16" height="16" class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
|
||||||
</button>
|
</button>
|
||||||
<div id="auth-dropdown-menu" class="hidden absolute right-0 top-full mt-1 w-48 earthen-panel py-1 z-50">
|
<div id="auth-dropdown-menu" class="hidden absolute right-0 top-full mt-1 w-48 earthen-panel py-1 z-50">
|
||||||
<a href="/account" class="block px-4 py-2 text-sm text-foreground hover:bg-muted">My profile</a>
|
<a href="/account" class="block px-4 py-2 text-sm text-foreground hover:bg-muted">My profile</a>
|
||||||
|
|||||||
@ -12,10 +12,10 @@
|
|||||||
{% if author.location %}<span>{{ author.location }}</span>{% endif %}
|
{% if author.location %}<span>{{ author.location }}</span>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if showSocial %}<div class="mt-6 flex items-center justify-center gap-4">
|
{% if showSocial %}<div class="mt-6 flex items-center justify-center gap-4">
|
||||||
{% if author.website_url %}<a href="{{ author.website_url }}" target="_blank" rel="noopener noreferrer" class="text-muted-foreground transition-colors hover:text-primary" title="Website"><svg class="h-5 w-5" aria-hidden="true"><use href="/icons/lucide.svg#globe"></use></svg></a>{% endif %}
|
{% if author.website_url %}<a href="{{ author.website_url }}" target="_blank" rel="noopener noreferrer" class="text-muted-foreground transition-colors hover:text-primary" title="Website"><svg width="20" height="20" class="h-5 w-5" aria-hidden="true"><use href="/icons/lucide.svg#globe"></use></svg></a>{% endif %}
|
||||||
{% if author.twitter_handle %}<a href="https://twitter.com/{{ author.twitter_handle|cut:"@" }}" target="_blank" rel="noopener noreferrer" class="text-muted-foreground transition-colors hover:text-primary" title="Twitter"><svg class="h-5 w-5" aria-hidden="true"><use href="/icons/simple-icons.svg#x"></use></svg></a>{% endif %}
|
{% if author.twitter_handle %}<a href="https://twitter.com/{{ author.twitter_handle|cut:"@" }}" target="_blank" rel="noopener noreferrer" class="text-muted-foreground transition-colors hover:text-primary" title="Twitter"><svg width="20" height="20" class="h-5 w-5" aria-hidden="true"><use href="/icons/simple-icons.svg#x"></use></svg></a>{% endif %}
|
||||||
{% if author.linkedin_url %}<a href="{{ author.linkedin_url }}" target="_blank" rel="noopener noreferrer" class="text-muted-foreground transition-colors hover:text-primary" title="LinkedIn"><svg class="h-5 w-5" aria-hidden="true"><use href="/icons/simple-icons.svg#linkedin"></use></svg></a>{% endif %}
|
{% if author.linkedin_url %}<a href="{{ author.linkedin_url }}" target="_blank" rel="noopener noreferrer" class="text-muted-foreground transition-colors hover:text-primary" title="LinkedIn"><svg width="20" height="20" class="h-5 w-5" aria-hidden="true"><use href="/icons/simple-icons.svg#linkedin"></use></svg></a>{% endif %}
|
||||||
{% if author.github_url %}<a href="{{ author.github_url }}" target="_blank" rel="noopener noreferrer" class="text-muted-foreground transition-colors hover:text-primary" title="GitHub"><svg class="h-5 w-5" aria-hidden="true"><use href="/icons/simple-icons.svg#github"></use></svg></a>{% endif %}
|
{% if author.github_url %}<a href="{{ author.github_url }}" target="_blank" rel="noopener noreferrer" class="text-muted-foreground transition-colors hover:text-primary" title="GitHub"><svg width="20" height="20" class="h-5 w-5" aria-hidden="true"><use href="/icons/simple-icons.svg#github"></use></svg></a>{% endif %}
|
||||||
</div>{% endif %}
|
</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{% if showHome %}<li class="flex items-center"><a href="/" class="text-muted-foreground transition-colors hover:text-primary">{{ homeLabel|default:"Home" }}</a></li>{% endif %}
|
{% if showHome %}<li class="flex items-center"><a href="/" class="text-muted-foreground transition-colors hover:text-primary">{{ homeLabel|default:"Home" }}</a></li>{% endif %}
|
||||||
{% for item in breadcrumbs %}
|
{% for item in breadcrumbs %}
|
||||||
<li class="flex items-center">
|
<li class="flex items-center">
|
||||||
{% if showHome or not forloop.First %}{% if arrows %}<svg class="mx-2 h-3.5 w-3.5 text-accent" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>{% else %}<span class="mx-2 text-accent">{{ separator|default:"/" }}</span>{% endif %}{% endif %}
|
{% if showHome or not forloop.First %}{% if arrows %}<svg width="14" height="14" class="mx-2 h-3.5 w-3.5 text-accent" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>{% else %}<span class="mx-2 text-accent">{{ separator|default:"/" }}</span>{% endif %}{% endif %}
|
||||||
{% if item.is_current %}{% if showCurrent %}<span class="font-medium text-foreground" aria-current="page">{{ item.label }}</span>{% endif %}{% else %}<a href="{{ item.url }}" class="text-muted-foreground transition-colors hover:text-primary">{{ item.label }}</a>{% endif %}
|
{% if item.is_current %}{% if showCurrent %}<span class="font-medium text-foreground" aria-current="page">{{ item.label }}</span>{% endif %}{% else %}<a href="{{ item.url }}" class="text-muted-foreground transition-colors hover:text-primary">{{ item.label }}</a>{% endif %}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<div class="mt-12 grid grid-cols-1 gap-6 text-left {% if columns == 3 %}sm:grid-cols-2 lg:grid-cols-3{% elif columns == 1 %}{% else %}sm:grid-cols-2{% endif %}">
|
<div class="mt-12 grid grid-cols-1 gap-6 text-left {% if columns == 3 %}sm:grid-cols-2 lg:grid-cols-3{% elif columns == 1 %}{% else %}sm:grid-cols-2{% endif %}">
|
||||||
{% for channel in channels %}
|
{% for channel in channels %}
|
||||||
<div class="earthen-panel earthen-blob-soft flex items-start gap-4 p-6">
|
<div class="earthen-panel earthen-blob-soft flex items-start gap-4 p-6">
|
||||||
{% if channel.icon %}<span class="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-xl" style="background-color:hsl(var(--primary)/0.12);color:hsl(var(--primary));"><svg class="h-5 w-5" aria-hidden="true"><use href="/icons/{{ channel.icon|split:":"|first }}.svg#{{ channel.icon|split:":"|last }}"></use></svg></span>{% endif %}
|
{% if channel.icon %}<span class="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-xl" style="background-color:hsl(var(--primary)/0.12);color:hsl(var(--primary));"><svg width="20" height="20" class="h-5 w-5" aria-hidden="true"><use href="/icons/{{ channel.icon|split:":"|first }}.svg#{{ channel.icon|split:":"|last }}"></use></svg></span>{% endif %}
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
{% if channel.label %}<div class="text-xs font-semibold uppercase tracking-[0.14em]" style="color:hsl(var(--muted-foreground));">{{ channel.label }}</div>{% endif %}
|
{% if channel.label %}<div class="text-xs font-semibold uppercase tracking-[0.14em]" style="color:hsl(var(--muted-foreground));">{{ channel.label }}</div>{% endif %}
|
||||||
{% if channel.value %}<div class="mt-1 break-words text-lg font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--foreground));">{% if channel.link %}<a href="{{ channel.link }}" class="earthen-link">{{ channel.value }}</a>{% else %}{{ channel.value }}{% endif %}</div>{% endif %}
|
{% if channel.value %}<div class="mt-1 break-words text-lg font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--foreground));">{% if channel.link %}<a href="{{ channel.link }}" class="earthen-link">{{ channel.value }}</a>{% else %}{{ channel.value }}{% endif %}</div>{% endif %}
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-8 hidden" data-countdown-expired>
|
<div class="mt-8 hidden" data-countdown-expired>
|
||||||
<p class="text-xl font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif)">{{ expiredMessage|default:"This has started." }}</p>
|
<p class="text-xl font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif)">{{ expiredMessage|default:"This has started." }}</p>
|
||||||
{% if expiredUrl and expiredLabel %}<a href="{{ expiredUrl }}" class="earthen-cta mt-4 inline-flex items-center gap-2 px-5 py-3 font-semibold">{{ expiredLabel }}<svg class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
{% if expiredUrl and expiredLabel %}<a href="{{ expiredUrl }}" class="earthen-cta mt-4 inline-flex items-center gap-2 px-5 py-3 font-semibold">{{ expiredLabel }}<svg width="16" height="16" class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<noscript><p class="mt-6 text-muted-foreground">Counting down to <time datetime="{{ target }}">{{ target }}</time>.</p></noscript>
|
<noscript><p class="mt-6 text-muted-foreground">Counting down to <time datetime="{{ target }}">{{ target }}</time>.</p></noscript>
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
{% if text %}<p class="mt-3 text-lg {% if background == "band" %}text-primary-foreground/80{% else %}text-muted-foreground{% endif %}" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ text }}</p>{% endif %}
|
{% if text %}<p class="mt-3 text-lg {% if background == "band" %}text-primary-foreground/80{% else %}text-muted-foreground{% endif %}" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ text }}</p>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-wrap items-center justify-center gap-3 {% if background != "split" %}mt-8{% else %}shrink-0{% endif %}">
|
<div class="flex flex-wrap items-center justify-center gap-3 {% if background != "split" %}mt-8{% else %}shrink-0{% endif %}">
|
||||||
{% if primaryUrl and primaryLabel %}<a href="{{ primaryUrl }}" class="earthen-cta inline-flex items-center gap-2 px-6 py-3 font-semibold">{{ primaryLabel }}<svg class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
{% if primaryUrl and primaryLabel %}<a href="{{ primaryUrl }}" class="earthen-cta inline-flex items-center gap-2 px-6 py-3 font-semibold">{{ primaryLabel }}<svg width="16" height="16" class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
||||||
{% if secondaryUrl and secondaryLabel %}<a href="{{ secondaryUrl }}" class="inline-flex items-center rounded-lg px-6 py-3 font-semibold transition-colors {% if background == "band" %}hover:bg-white/10{% else %}hover:bg-muted{% endif %}" style="{% if background == "band" %}border:1.5px solid hsl(var(--primary-foreground) / 0.4);color:hsl(var(--primary-foreground));{% else %}border:1.5px solid hsl(var(--border));color:hsl(var(--primary));{% endif %}">{{ secondaryLabel }}</a>{% endif %}
|
{% if secondaryUrl and secondaryLabel %}<a href="{{ secondaryUrl }}" class="inline-flex items-center rounded-lg px-6 py-3 font-semibold transition-colors {% if background == "band" %}hover:bg-white/10{% else %}hover:bg-muted{% endif %}" style="{% if background == "band" %}border:1.5px solid hsl(var(--primary-foreground) / 0.4);color:hsl(var(--primary-foreground));{% else %}border:1.5px solid hsl(var(--border));color:hsl(var(--primary));{% endif %}">{{ secondaryLabel }}</a>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<h3 class="text-xl font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--foreground));">{{ event.title }}</h3>
|
<h3 class="text-xl font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--foreground));">{{ event.title }}</h3>
|
||||||
{% if event.venue %}<p class="text-xs uppercase tracking-[0.12em]" style="color:hsl(var(--muted-foreground));">{{ event.venue }}</p>{% endif %}
|
{% if event.venue %}<p class="text-xs uppercase tracking-[0.12em]" style="color:hsl(var(--muted-foreground));">{{ event.venue }}</p>{% endif %}
|
||||||
{% if event.description %}<p class="text-sm" style="color:hsl(var(--muted-foreground));font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif);">{{ event.description }}</p>{% endif %}
|
{% if event.description %}<p class="text-sm" style="color:hsl(var(--muted-foreground));font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif);">{{ event.description }}</p>{% endif %}
|
||||||
{% if event.link %}<a href="{{ event.link }}" class="earthen-link mt-auto inline-flex items-center gap-2 pt-3 text-sm font-semibold">{{ event.linkLabel|default:"Details" }}<svg class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
{% if event.link %}<a href="{{ event.link }}" class="earthen-link mt-auto inline-flex items-center gap-2 pt-3 text-sm font-semibold">{{ event.linkLabel|default:"Details" }}<svg width="16" height="16" class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
{% endif %}{% endfor %}
|
{% endif %}{% endfor %}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
<details class="group py-2"{% if variant == "open-list" %} open{% endif %}>
|
<details class="group py-2"{% if variant == "open-list" %} open{% endif %}>
|
||||||
<summary class="flex cursor-pointer list-none items-center justify-between gap-4 py-3 text-lg font-semibold marker:content-none [&::-webkit-details-marker]:hidden" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--foreground))">
|
<summary class="flex cursor-pointer list-none items-center justify-between gap-4 py-3 text-lg font-semibold marker:content-none [&::-webkit-details-marker]:hidden" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--foreground))">
|
||||||
<span>{{ item.question }}</span>
|
<span>{{ item.question }}</span>
|
||||||
<svg class="h-5 w-5 shrink-0 text-primary transition-transform duration-200 group-open:rotate-180" aria-hidden="true"><use href="/icons/lucide.svg#chevron-down"></use></svg>
|
<svg width="20" height="20" class="h-5 w-5 shrink-0 text-primary transition-transform duration-200 group-open:rotate-180" aria-hidden="true"><use href="/icons/lucide.svg#chevron-down"></use></svg>
|
||||||
</summary>
|
</summary>
|
||||||
<div class="pb-4 text-muted-foreground [&_a]:text-primary [&_a]:underline" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ item.answer|safe }}</div>
|
<div class="pb-4 text-muted-foreground [&_a]:text-primary [&_a]:underline" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ item.answer|safe }}</div>
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@ -7,10 +7,10 @@
|
|||||||
<div class="mt-12 grid grid-cols-1 gap-6 sm:grid-cols-2 {% if columns == 2 %}lg:grid-cols-2{% elif columns == 4 %}lg:grid-cols-4{% else %}lg:grid-cols-3{% endif %}">
|
<div class="mt-12 grid grid-cols-1 gap-6 sm:grid-cols-2 {% if columns == 2 %}lg:grid-cols-2{% elif columns == 4 %}lg:grid-cols-4{% else %}lg:grid-cols-3{% endif %}">
|
||||||
{% for item in items %}
|
{% for item in items %}
|
||||||
<div class="{% if layout == "card" %}earthen-panel earthen-blob-soft p-6 transition-shadow{% elif layout == "centered" %}text-center{% endif %}">
|
<div class="{% if layout == "card" %}earthen-panel earthen-blob-soft p-6 transition-shadow{% elif layout == "centered" %}text-center{% endif %}">
|
||||||
{% if item.icon %}<div class="mb-4 inline-flex h-11 w-11 items-center justify-center earthen-blob-soft bg-primary/10 text-primary{% if layout == "centered" %} mx-auto{% endif %}"><svg class="h-6 w-6" aria-hidden="true"><use href="/icons/{{ item.icon|split:":"|first }}.svg#{{ item.icon|split:":"|last }}"></use></svg></div>{% endif %}
|
{% if item.icon %}<div class="mb-4 inline-flex h-11 w-11 items-center justify-center earthen-blob-soft bg-primary/10 text-primary{% if layout == "centered" %} mx-auto{% endif %}"><svg width="24" height="24" class="h-6 w-6" aria-hidden="true"><use href="/icons/{{ item.icon|split:":"|first }}.svg#{{ item.icon|split:":"|last }}"></use></svg></div>{% endif %}
|
||||||
<h3 class="text-lg font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--foreground))">{% if item.linkUrl %}<a href="{{ item.linkUrl }}" class="transition-colors hover:text-primary">{{ item.title }}</a>{% else %}{{ item.title }}{% endif %}</h3>
|
<h3 class="text-lg font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--foreground))">{% if item.linkUrl %}<a href="{{ item.linkUrl }}" class="transition-colors hover:text-primary">{{ item.title }}</a>{% else %}{{ item.title }}{% endif %}</h3>
|
||||||
{% if item.text %}<p class="mt-2 text-muted-foreground" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ item.text }}</p>{% endif %}
|
{% if item.text %}<p class="mt-2 text-muted-foreground" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ item.text }}</p>{% endif %}
|
||||||
{% if item.linkUrl and item.linkLabel %}<a href="{{ item.linkUrl }}" class="earthen-link mt-3 inline-flex items-center gap-1 text-sm">{{ item.linkLabel }}<svg class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
{% if item.linkUrl and item.linkLabel %}<a href="{{ item.linkUrl }}" class="earthen-link mt-3 inline-flex items-center gap-1 text-sm">{{ item.linkLabel }}<svg width="16" height="16" class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -10,10 +10,10 @@
|
|||||||
ov.style.cssText='position:fixed;inset:0;z-index:9999;display:none;align-items:center;justify-content:center;background:rgba(0,0,0,0.9);padding:2rem;';
|
ov.style.cssText='position:fixed;inset:0;z-index:9999;display:none;align-items:center;justify-content:center;background:rgba(0,0,0,0.9);padding:2rem;';
|
||||||
var btn='position:absolute;width:2.75rem;height:2.75rem;display:inline-flex;align-items:center;justify-content:center;border-radius:9999px;border:none;background:hsl(var(--background));color:hsl(var(--foreground));cursor:pointer;';
|
var btn='position:absolute;width:2.75rem;height:2.75rem;display:inline-flex;align-items:center;justify-content:center;border-radius:9999px;border:none;background:hsl(var(--background));color:hsl(var(--foreground));cursor:pointer;';
|
||||||
ov.innerHTML=
|
ov.innerHTML=
|
||||||
'<button type="button" data-lb-close aria-label="Close" style="'+btn+'top:1rem;right:1rem;"><svg style="width:1.25rem;height:1.25rem" aria-hidden="true"><use href="/icons/lucide.svg#x"/></svg></button>'+
|
'<button type="button" data-lb-close aria-label="Close" style="'+btn+'top:1rem;right:1rem;"><svg width="20" height="20" style="width:1.25rem;height:1.25rem" aria-hidden="true"><use href="/icons/lucide.svg#x"/></svg></button>'+
|
||||||
'<button type="button" data-lb-prev aria-label="Previous image" style="'+btn+'left:1rem;top:50%;transform:translateY(-50%);"><svg style="width:1.25rem;height:1.25rem" aria-hidden="true"><use href="/icons/lucide.svg#chevron-left"/></svg></button>'+
|
'<button type="button" data-lb-prev aria-label="Previous image" style="'+btn+'left:1rem;top:50%;transform:translateY(-50%);"><svg width="20" height="20" style="width:1.25rem;height:1.25rem" aria-hidden="true"><use href="/icons/lucide.svg#chevron-left"/></svg></button>'+
|
||||||
'<figure style="margin:0;max-width:92vw;max-height:92vh;display:flex;flex-direction:column;align-items:center;gap:0.75rem;"><img data-lb-img alt="" style="max-width:92vw;max-height:82vh;object-fit:contain;border-radius:0.5rem;'+(reduce?'':'transition:opacity .2s ease;')+'"><figcaption data-lb-cap style="color:hsl(var(--background));opacity:.85;font-size:.875rem;text-align:center;max-width:60ch;"></figcaption></figure>'+
|
'<figure style="margin:0;max-width:92vw;max-height:92vh;display:flex;flex-direction:column;align-items:center;gap:0.75rem;"><img data-lb-img alt="" style="max-width:92vw;max-height:82vh;object-fit:contain;border-radius:0.5rem;'+(reduce?'':'transition:opacity .2s ease;')+'"><figcaption data-lb-cap style="color:hsl(var(--background));opacity:.85;font-size:.875rem;text-align:center;max-width:60ch;"></figcaption></figure>'+
|
||||||
'<button type="button" data-lb-next aria-label="Next image" style="'+btn+'right:1rem;top:50%;transform:translateY(-50%);"><svg style="width:1.25rem;height:1.25rem" aria-hidden="true"><use href="/icons/lucide.svg#chevron-right"/></svg></button>';
|
'<button type="button" data-lb-next aria-label="Next image" style="'+btn+'right:1rem;top:50%;transform:translateY(-50%);"><svg width="20" height="20" style="width:1.25rem;height:1.25rem" aria-hidden="true"><use href="/icons/lucide.svg#chevron-right"/></svg></button>';
|
||||||
document.body.appendChild(ov);
|
document.body.appendChild(ov);
|
||||||
imgEl=ov.querySelector('[data-lb-img]');capEl=ov.querySelector('[data-lb-cap]');
|
imgEl=ov.querySelector('[data-lb-img]');capEl=ov.querySelector('[data-lb-cap]');
|
||||||
ov.addEventListener('click',function(e){if(e.target===ov||e.target.closest('[data-lb-close]'))close();});
|
ov.addEventListener('click',function(e){if(e.target===ov||e.target.closest('[data-lb-close]'))close();});
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{# image override — recycled-paper frame with soft organic corners. Fields mirror builtin: src, alt, caption, size, align, aspectRatio, objectFit. Media resolved via {% img %} (media filter is not registered in the block render path). #}
|
{# image override — recycled-paper frame with soft organic corners. Fields mirror builtin: src, alt, caption, size, align, aspectRatio, objectFit. Media resolved via {% img %} (media filter is not registered in the block render path). #}
|
||||||
{% with size=size|default:"full" align=align|default:"center" objectFit=objectFit|default:"cover" %}
|
{% with size=size|default:"full" align=align|default:"center" objectFit=objectFit|default:"cover" %}
|
||||||
<figure data-block-override="earthen:image" class="my-8 flex-1 {% if align == "left" %}flex justify-start{% elif align == "right" %}flex justify-end{% else %}flex justify-center{% endif %}{% if class %} {{ class }}{% endif %}">
|
<figure data-block-override="earthen:image" class="my-8 flex-1 flex flex-col {% if align == "left" %}items-start{% elif align == "right" %}items-end{% else %}items-center{% endif %}{% if class %} {{ class }}{% endif %}">
|
||||||
<div class="earthen-paper-frame-inner earthen-blob-soft overflow-hidden {% if size == "xs" %}max-w-[200px] w-full{% elif size == "sm" %}max-w-[400px] w-full{% elif size == "md" %}max-w-[600px] w-full{% elif size == "lg" %}max-w-[800px] w-full{% else %}w-full{% endif %}" style="border:1px solid hsl(var(--border));padding:6px;background-color:hsl(var(--card));">
|
<div class="earthen-paper-frame-inner earthen-blob-soft overflow-hidden {% if size == "xs" %}max-w-[200px] w-full{% elif size == "sm" %}max-w-[400px] w-full{% elif size == "md" %}max-w-[600px] w-full{% elif size == "lg" %}max-w-[800px] w-full{% else %}w-full{% endif %}" style="border:1px solid hsl(var(--border));padding:6px;background-color:hsl(var(--card));">
|
||||||
<div class="earthen-blob-soft relative overflow-hidden bg-muted {% if aspectRatio == "square" %}aspect-square{% elif aspectRatio == "video" %}aspect-video{% elif aspectRatio == "portrait" %}aspect-[3/4]{% elif aspectRatio == "wide" %}aspect-[21/9]{% endif %}">
|
<div class="earthen-blob-soft relative overflow-hidden bg-muted {% if aspectRatio == "square" %}aspect-square{% elif aspectRatio == "video" %}aspect-video{% elif aspectRatio == "portrait" %}aspect-[3/4]{% elif aspectRatio == "wide" %}aspect-[21/9]{% endif %}">
|
||||||
{% if objectFit == "contain" %}{% img src alt=alt class="w-full h-full object-contain" layout=size %}{% elif objectFit == "fill" %}{% img src alt=alt class="w-full h-full object-fill" layout=size %}{% elif objectFit == "none" %}{% img src alt=alt class="w-full h-full object-none" layout=size %}{% else %}{% img src alt=alt class="w-full h-full object-cover" layout=size %}{% endif %}
|
{% if objectFit == "contain" %}{% img src alt=alt class="w-full h-full object-contain" layout=size %}{% elif objectFit == "fill" %}{% img src alt=alt class="w-full h-full object-fill" layout=size %}{% elif objectFit == "none" %}{% img src alt=alt class="w-full h-full object-none" layout=size %}{% else %}{% img src alt=alt class="w-full h-full object-cover" layout=size %}{% endif %}
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
{% set bg = backgroundColor|default:"bg-background" %}
|
{% set bg = backgroundColor|default:"bg-background" %}
|
||||||
{% macro navlink(item) %}<a href="{{ item.url|default:'#' }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %}{% if item.title %} title="{{ item.title }}"{% endif %} class="px-3 py-2 text-sm font-medium text-foreground/75 hover:text-primary transition-colors {{ item.css_class }}" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif);">{{ item.label }}</a>{% endmacro %}
|
{% macro navlink(item) %}<a href="{{ item.url|default:'#' }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %}{% if item.title %} title="{{ item.title }}"{% endif %} class="px-3 py-2 text-sm font-medium text-foreground/75 hover:text-primary transition-colors {{ item.css_class }}" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif);">{{ item.label }}</a>{% endmacro %}
|
||||||
{% macro dropdown(item) %}<div class="relative group">
|
{% macro dropdown(item) %}<div class="relative group">
|
||||||
<button type="button" class="px-3 py-2 text-sm font-medium text-foreground/75 hover:text-primary transition-colors inline-flex items-center gap-1" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif);">{{ item.label }}<svg class="h-4 w-4 transition-transform group-hover:rotate-180" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg></button>
|
<button type="button" class="px-3 py-2 text-sm font-medium text-foreground/75 hover:text-primary transition-colors inline-flex items-center gap-1" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif);">{{ item.label }}<svg width="16" height="16" class="h-4 w-4 transition-transform group-hover:rotate-180" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg></button>
|
||||||
{% if use_mega %}<div class="absolute left-1/2 -translate-x-1/2 mt-2 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50"><div class="earthen-panel rounded-2xl p-6 grid gap-8" style="grid-template-columns:repeat({{ item.children|length|default:1 }},minmax(10rem,1fr));min-width:min(90vw,42rem)">{% for child in item.children %}<div class="space-y-1">{% if child.item_type == "header" %}<div class="px-2 py-1 text-[0.65rem] font-semibold uppercase tracking-wider text-primary border-b border-border mb-2">{{ child.label }}</div>{% else %}<a href="{{ child.url|default:'#' }}"{% if child.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="block px-2 py-2 rounded-lg hover:bg-muted transition-colors {{ child.css_class }}">{% if child.icon %}<span class="mr-1.5 text-primary">::{{ child.icon }}::</span>{% endif %}<span class="text-sm font-medium text-foreground">{{ child.label }}</span>{% if child.description %}<span class="block text-xs text-muted-foreground mt-0.5">{{ child.description }}</span>{% endif %}</a>{% endif %}</div>{% endfor %}</div></div>
|
{% if use_mega %}<div class="absolute left-1/2 -translate-x-1/2 mt-2 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50"><div class="earthen-panel rounded-2xl p-6 grid gap-8" style="grid-template-columns:repeat({{ item.children|length|default:1 }},minmax(10rem,1fr));min-width:min(90vw,42rem)">{% for child in item.children %}<div class="space-y-1">{% if child.item_type == "header" %}<div class="px-2 py-1 text-[0.65rem] font-semibold uppercase tracking-wider text-primary border-b border-border mb-2">{{ child.label }}</div>{% else %}<a href="{{ child.url|default:'#' }}"{% if child.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="block px-2 py-2 rounded-lg hover:bg-muted transition-colors {{ child.css_class }}">{% if child.icon %}<span class="mr-1.5 text-primary">::{{ child.icon }}::</span>{% endif %}<span class="text-sm font-medium text-foreground">{{ child.label }}</span>{% if child.description %}<span class="block text-xs text-muted-foreground mt-0.5">{{ child.description }}</span>{% endif %}</a>{% endif %}</div>{% endfor %}</div></div>
|
||||||
{% else %}<div class="absolute left-0 mt-2 w-56 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50"><div class="earthen-panel rounded-2xl py-2">{% for child in item.children %}{% if child.item_type == "header" %}<div class="px-4 py-2 text-[0.65rem] font-semibold uppercase tracking-wider text-primary">{{ child.label }}</div>{% else %}<a href="{{ child.url|default:'#' }}"{% if child.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="block px-4 py-2 text-sm text-foreground hover:bg-muted transition-colors {{ child.css_class }}">{{ child.label }}</a>{% endif %}{% endfor %}</div></div>{% endif %}
|
{% else %}<div class="absolute left-0 mt-2 w-56 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50"><div class="earthen-panel rounded-2xl py-2">{% for child in item.children %}{% if child.item_type == "header" %}<div class="px-4 py-2 text-[0.65rem] font-semibold uppercase tracking-wider text-primary">{{ child.label }}</div>{% else %}<a href="{{ child.url|default:'#' }}"{% if child.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="block px-4 py-2 text-sm text-foreground hover:bg-muted transition-colors {{ child.css_class }}">{{ child.label }}</a>{% endif %}{% endfor %}</div></div>{% endif %}
|
||||||
</div>{% endmacro %}
|
</div>{% endmacro %}
|
||||||
@ -33,7 +33,7 @@
|
|||||||
<div class="hidden md:flex items-center gap-1">{% for item in menu.items %}{% if item.children %}{{ dropdown(item) }}{% else %}{{ navlink(item) }}{% endif %}{% endfor %}{{ ctabtn("ml-3") }}</div>
|
<div class="hidden md:flex items-center gap-1">{% for item in menu.items %}{% if item.children %}{{ dropdown(item) }}{% else %}{{ navlink(item) }}{% endif %}{% endfor %}{{ ctabtn("ml-3") }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="flex items-center md:hidden">
|
<div class="flex items-center md:hidden">
|
||||||
<label for="bn-navbar-toggle" data-bn-nav-open aria-controls="bn-navbar-drawer" aria-expanded="false" class="inline-flex items-center justify-center p-2 rounded-lg cursor-pointer hover:bg-muted transition-colors"><span class="sr-only">Open menu</span><svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg></label>
|
<label for="bn-navbar-toggle" data-bn-nav-open aria-controls="bn-navbar-drawer" aria-expanded="false" class="inline-flex items-center justify-center p-2 rounded-lg cursor-pointer hover:bg-muted transition-colors"><span class="sr-only">Open menu</span><svg width="24" height="24" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -41,8 +41,8 @@
|
|||||||
<input type="checkbox" id="bn-navbar-toggle" class="bn-navbar-toggle" aria-hidden="true"/>
|
<input type="checkbox" id="bn-navbar-toggle" class="bn-navbar-toggle" aria-hidden="true"/>
|
||||||
<label for="bn-navbar-toggle" class="bn-navbar-overlay fixed inset-0 bg-black/50 z-40 md:hidden" aria-hidden="true"></label>
|
<label for="bn-navbar-toggle" class="bn-navbar-overlay fixed inset-0 bg-black/50 z-40 md:hidden" aria-hidden="true"></label>
|
||||||
<div id="bn-navbar-drawer" class="bn-navbar-drawer fixed top-0 right-0 h-full w-80 max-w-[85vw] bg-background text-foreground z-50 shadow-xl md:hidden flex flex-col border-l border-border" role="dialog" aria-modal="true" aria-label="Site menu">
|
<div id="bn-navbar-drawer" class="bn-navbar-drawer fixed top-0 right-0 h-full w-80 max-w-[85vw] bg-background text-foreground z-50 shadow-xl md:hidden flex flex-col border-l border-border" role="dialog" aria-modal="true" aria-label="Site menu">
|
||||||
<div class="flex items-center justify-between p-4 border-b border-border">{{ brand("h-8") }}<label for="bn-navbar-toggle" data-bn-nav-close class="p-2 rounded-lg cursor-pointer text-muted-foreground hover:text-primary hover:bg-muted"><span class="sr-only">Close menu</span><svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg></label></div>
|
<div class="flex items-center justify-between p-4 border-b border-border">{{ brand("h-8") }}<label for="bn-navbar-toggle" data-bn-nav-close class="p-2 rounded-lg cursor-pointer text-muted-foreground hover:text-primary hover:bg-muted"><span class="sr-only">Close menu</span><svg width="24" height="24" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg></label></div>
|
||||||
<nav class="flex-1 overflow-y-auto py-4" aria-label="Mobile">{% for item in menu.items %}{% if item.children %}<details class="group/acc"><summary class="flex items-center justify-between px-6 py-3 text-base font-medium cursor-pointer hover:bg-muted transition-colors list-none">{{ item.label }}<svg class="h-4 w-4 transition-transform group-open/acc:rotate-180" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg></summary><div class="pl-8 pb-2">{% for child in item.children %}{% if child.item_type != "header" %}<a href="{{ child.url|default:'#' }}"{% if child.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="block px-2 py-2 text-sm text-muted-foreground hover:text-primary transition-colors">{{ child.label }}</a>{% endif %}{% endfor %}</div></details>{% else %}<a href="{{ item.url|default:'#' }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="block px-6 py-3 text-base font-medium hover:bg-muted transition-colors">{{ item.label }}</a>{% endif %}{% endfor %}</nav>
|
<nav class="flex-1 overflow-y-auto py-4" aria-label="Mobile">{% for item in menu.items %}{% if item.children %}<details class="group/acc"><summary class="flex items-center justify-between px-6 py-3 text-base font-medium cursor-pointer hover:bg-muted transition-colors list-none">{{ item.label }}<svg width="16" height="16" class="h-4 w-4 transition-transform group-open/acc:rotate-180" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg></summary><div class="pl-8 pb-2">{% for child in item.children %}{% if child.item_type != "header" %}<a href="{{ child.url|default:'#' }}"{% if child.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="block px-2 py-2 text-sm text-muted-foreground hover:text-primary transition-colors">{{ child.label }}</a>{% endif %}{% endfor %}</div></details>{% else %}<a href="{{ item.url|default:'#' }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="block px-6 py-3 text-base font-medium hover:bg-muted transition-colors">{{ item.label }}</a>{% endif %}{% endfor %}</nav>
|
||||||
{% if cta_text %}<div class="p-4 border-t border-border"><a href="{{ cta_url|default:'#' }}" class="earthen-cta block w-full text-center px-4 py-3 text-base font-semibold">{{ cta_text }}</a></div>{% endif %}
|
{% if cta_text %}<div class="p-4 border-t border-border"><a href="{{ cta_url|default:'#' }}" class="earthen-cta block w-full text-center px-4 py-3 text-base font-semibold">{{ cta_text }}</a></div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
</p>
|
</p>
|
||||||
{% if tier.description %}<p class="mt-3 text-center text-sm text-muted-foreground" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ tier.description }}</p>{% endif %}
|
{% if tier.description %}<p class="mt-3 text-center text-sm text-muted-foreground" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ tier.description }}</p>{% endif %}
|
||||||
{% if tier.features %}<ul class="mt-6 flex-1 space-y-3 text-sm">
|
{% if tier.features %}<ul class="mt-6 flex-1 space-y-3 text-sm">
|
||||||
{% for feature in tier.features %}<li class="flex items-start gap-2"><svg class="mt-0.5 h-4 w-4 shrink-0 text-primary" aria-hidden="true"><use href="/icons/lucide.svg#check"></use></svg><span>{{ feature }}</span></li>{% endfor %}
|
{% for feature in tier.features %}<li class="flex items-start gap-2"><svg width="16" height="16" class="mt-0.5 h-4 w-4 shrink-0 text-primary" aria-hidden="true"><use href="/icons/lucide.svg#check"></use></svg><span>{{ feature }}</span></li>{% endfor %}
|
||||||
</ul>{% endif %}
|
</ul>{% endif %}
|
||||||
{% if tier.ctaUrl and tier.ctaLabel %}{% if tier.highlighted %}<a href="{{ tier.ctaUrl }}" class="earthen-cta mt-8 inline-flex w-full items-center justify-center px-5 py-3 font-semibold">{{ tier.ctaLabel }}</a>{% else %}<a href="{{ tier.ctaUrl }}" class="mt-8 inline-flex w-full items-center justify-center rounded-lg px-5 py-3 font-semibold transition-colors hover:bg-muted" style="border:1.5px solid hsl(var(--border));color:hsl(var(--primary));">{{ tier.ctaLabel }}</a>{% endif %}{% endif %}
|
{% if tier.ctaUrl and tier.ctaLabel %}{% if tier.highlighted %}<a href="{{ tier.ctaUrl }}" class="earthen-cta mt-8 inline-flex w-full items-center justify-center px-5 py-3 font-semibold">{{ tier.ctaLabel }}</a>{% else %}<a href="{{ tier.ctaUrl }}" class="mt-8 inline-flex w-full items-center justify-center rounded-lg px-5 py-3 font-semibold transition-colors hover:bg-muted" style="border:1.5px solid hsl(var(--border));color:hsl(var(--primary));">{{ tier.ctaLabel }}</a>{% endif %}{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{% if eyebrow %}<div class="mb-3 flex items-center gap-3"><span class="h-px w-8" style="background-color:hsl(var(--accent));"></span><p class="text-xs font-semibold uppercase tracking-wider" style="color:hsl(var(--primary));">{{ eyebrow }}</p></div>{% endif %}
|
{% if eyebrow %}<div class="mb-3 flex items-center gap-3"><span class="h-px w-8" style="background-color:hsl(var(--accent));"></span><p class="text-xs font-semibold uppercase tracking-wider" style="color:hsl(var(--primary));">{{ eyebrow }}</p></div>{% endif %}
|
||||||
{% if heading %}<h2 class="mt-2 inline-block crayon-underline text-3xl md:text-4xl font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--primary))">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="mt-2 inline-block crayon-underline text-3xl md:text-4xl font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--primary))">{{ heading }}</h2>{% endif %}
|
||||||
{% if body %}<div class="mt-4 space-y-4 text-lg text-muted-foreground [&_a]:text-primary [&_a]:underline [&_strong]:text-foreground" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ body|safe }}</div>{% endif %}
|
{% if body %}<div class="mt-4 space-y-4 text-lg text-muted-foreground [&_a]:text-primary [&_a]:underline [&_strong]:text-foreground" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ body|safe }}</div>{% endif %}
|
||||||
{% if ctaUrl and ctaLabel %}<a href="{{ ctaUrl }}" class="earthen-cta mt-6 inline-flex items-center gap-2 px-5 py-3 font-semibold">{{ ctaLabel }}<svg class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
{% if ctaUrl and ctaLabel %}<a href="{{ ctaUrl }}" class="earthen-cta mt-6 inline-flex items-center gap-2 px-5 py-3 font-semibold">{{ ctaLabel }}<svg width="16" height="16" class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="{% if mediaPosition == "left" %}md:order-1{% else %}md:order-2{% endif %}">
|
<div class="{% if mediaPosition == "left" %}md:order-1{% else %}md:order-2{% endif %}">
|
||||||
{% if media %}<div class="earthen-blob-soft earthen-paper-frame overflow-hidden">{% img media alt=mediaAlt class="w-full h-auto object-cover" %}</div>{% endif %}
|
{% if media %}<div class="earthen-blob-soft earthen-paper-frame overflow-hidden">{% img media alt=mediaAlt class="w-full h-auto object-cover" %}</div>{% endif %}
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
{% if title %}<h3 class="crayon-underline inline-block {% if compact %}px-2 mb-4 text-xs{% else %}px-3 mb-5 text-sm{% endif %} font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--primary));">{{ title }}</h3>{% endif %}
|
{% if title %}<h3 class="crayon-underline inline-block {% if compact %}px-2 mb-4 text-xs{% else %}px-3 mb-5 text-sm{% endif %} font-semibold" style="font-family:var(--font-heading, 'Fraunces', 'Playfair Display', Georgia, serif);color:hsl(var(--primary));">{{ title }}</h3>{% endif %}
|
||||||
<ul class="{% if compact %}space-y-0.5{% else %}space-y-1{% endif %}">
|
<ul class="{% if compact %}space-y-0.5{% else %}space-y-1{% endif %}">
|
||||||
{% for item in menu.items %}
|
{% for item in menu.items %}
|
||||||
<li><a href="{{ item.url|default:'#' }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %}{% if item.title %} title="{{ item.title }}"{% endif %} data-bn-sidebar-link class="flex items-center rounded-lg text-sm text-muted-foreground transition-colors hover:text-primary hover:bg-muted {% if compact %}px-2 py-1.5{% else %}px-3 py-2{% endif %} {{ item.css_class }}">{% if item.icon %}<svg class="mr-2 h-4 w-4 text-accent" aria-hidden="true"><use href="/icons/{{ item.icon|split:":"|first }}.svg#{{ item.icon|split:":"|last }}"></use></svg>{% endif %}{{ item.label }}</a></li>
|
<li><a href="{{ item.url|default:'#' }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %}{% if item.title %} title="{{ item.title }}"{% endif %} data-bn-sidebar-link class="flex items-center rounded-lg text-sm text-muted-foreground transition-colors hover:text-primary hover:bg-muted {% if compact %}px-2 py-1.5{% else %}px-3 py-2{% endif %} {{ item.css_class }}">{% if item.icon %}<svg width="16" height="16" class="mr-2 h-4 w-4 text-accent" aria-hidden="true"><use href="/icons/{{ item.icon|split:":"|first }}.svg#{{ item.icon|split:":"|last }}"></use></svg>{% endif %}{{ item.label }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{% for link in links %}{% if link.url %}
|
{% for link in links %}{% if link.url %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ link.url }}" target="_blank" rel="noopener noreferrer" aria-label="{{ link.label|default:link.network }}" class="inline-flex items-center gap-2 rounded-xl border text-foreground transition-colors hover:bg-accent/10 hover:text-accent {% if style == "stack" %}w-full px-4 py-2.5{% else %}p-2.5{% endif %}" style="border-color:hsl(var(--border));">
|
<a href="{{ link.url }}" target="_blank" rel="noopener noreferrer" aria-label="{{ link.label|default:link.network }}" class="inline-flex items-center gap-2 rounded-xl border text-foreground transition-colors hover:bg-accent/10 hover:text-accent {% if style == "stack" %}w-full px-4 py-2.5{% else %}p-2.5{% endif %}" style="border-color:hsl(var(--border));">
|
||||||
{% if link.network %}<svg class="h-5 w-5" style="color:hsl(var(--primary));" aria-hidden="true"><use href="/icons/{{ link.network|split:":"|first }}.svg#{{ link.network|split:":"|last }}"></use></svg>{% endif %}
|
{% if link.network %}<svg width="20" height="20" class="h-5 w-5" style="color:hsl(var(--primary));" aria-hidden="true"><use href="/icons/{{ link.network|split:":"|first }}.svg#{{ link.network|split:":"|last }}"></use></svg>{% endif %}
|
||||||
{% if style == "stack" and link.label %}<span class="text-xs font-semibold uppercase tracking-[0.12em]">{{ link.label }}</span>{% endif %}
|
{% if style == "stack" and link.label %}<span class="text-xs font-semibold uppercase tracking-[0.12em]">{{ link.label }}</span>{% endif %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
{% if member.role %}<p class="text-xs font-semibold uppercase tracking-wider" style="color:hsl(var(--primary))">{{ member.role }}</p>{% endif %}
|
{% if member.role %}<p class="text-xs font-semibold uppercase tracking-wider" style="color:hsl(var(--primary))">{{ member.role }}</p>{% endif %}
|
||||||
{% if member.bio %}<p class="mt-2 text-sm text-muted-foreground" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ member.bio }}</p>{% endif %}
|
{% if member.bio %}<p class="mt-2 text-sm text-muted-foreground" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{{ member.bio }}</p>{% endif %}
|
||||||
{% if member.socials %}<div class="mt-3 flex gap-3 {% if layout != "list" %}justify-center{% endif %}">
|
{% if member.socials %}<div class="mt-3 flex gap-3 {% if layout != "list" %}justify-center{% endif %}">
|
||||||
{% for social in member.socials %}{% if social.url %}<a href="{{ social.url }}" class="text-muted-foreground transition-colors hover:text-primary" aria-label="Social link"><svg class="h-5 w-5" aria-hidden="true"><use href="/icons/{{ social.icon|split:":"|first }}.svg#{{ social.icon|split:":"|last }}"></use></svg></a>{% endif %}{% endfor %}
|
{% for social in member.socials %}{% if social.url %}<a href="{{ social.url }}" class="text-muted-foreground transition-colors hover:text-primary" aria-label="Social link"><svg width="20" height="20" class="h-5 w-5" aria-hidden="true"><use href="/icons/{{ social.icon|split:":"|first }}.svg#{{ social.icon|split:":"|last }}"></use></svg></a>{% endif %}{% endfor %}
|
||||||
</div>{% endif %}
|
</div>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,11 +6,11 @@
|
|||||||
{% for q in quotes %}
|
{% for q in quotes %}
|
||||||
<figure class="earthen-panel earthen-blob-soft flex flex-col p-6{% if layout == "carousel" %} min-w-[18rem] max-w-sm shrink-0 snap-start{% endif %}">
|
<figure class="earthen-panel earthen-blob-soft flex flex-col p-6{% if layout == "carousel" %} min-w-[18rem] max-w-sm shrink-0 snap-start{% endif %}">
|
||||||
{% if q.rating %}<div class="mb-3 flex justify-center gap-0.5" aria-label="Rated {{ q.rating }} out of 5">
|
{% if q.rating %}<div class="mb-3 flex justify-center gap-0.5" aria-label="Rated {{ q.rating }} out of 5">
|
||||||
<svg class="h-4 w-4 {% if q.rating >= 1 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
<svg width="16" height="16" class="h-4 w-4 {% if q.rating >= 1 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
||||||
<svg class="h-4 w-4 {% if q.rating >= 2 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
<svg width="16" height="16" class="h-4 w-4 {% if q.rating >= 2 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
||||||
<svg class="h-4 w-4 {% if q.rating >= 3 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
<svg width="16" height="16" class="h-4 w-4 {% if q.rating >= 3 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
||||||
<svg class="h-4 w-4 {% if q.rating >= 4 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
<svg width="16" height="16" class="h-4 w-4 {% if q.rating >= 4 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
||||||
<svg class="h-4 w-4 {% if q.rating >= 5 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
<svg width="16" height="16" class="h-4 w-4 {% if q.rating >= 5 %}text-accent{% else %}text-muted-foreground/30{% endif %}" aria-hidden="true"><use href="/icons/lucide.svg#star"></use></svg>
|
||||||
</div>{% endif %}
|
</div>{% endif %}
|
||||||
<blockquote class="flex-1 text-center text-lg leading-relaxed" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{% if q.quote %}“{{ q.quote }}”{% endif %}</blockquote>
|
<blockquote class="flex-1 text-center text-lg leading-relaxed" style="font-family:var(--font-body, 'Work Sans', ui-sans-serif, system-ui, sans-serif)">{% if q.quote %}“{{ q.quote }}”{% endif %}</blockquote>
|
||||||
<div class="mx-auto my-4 h-px w-16" style="background-color:hsl(var(--accent));"></div>
|
<div class="mx-auto my-4 h-px w-16" style="background-color:hsl(var(--accent));"></div>
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
{% for step in steps %}
|
{% for step in steps %}
|
||||||
<li class="{% if orientation == "horizontal" %}text-center{% else %}relative pl-14{% endif %}">
|
<li class="{% if orientation == "horizontal" %}text-center{% else %}relative pl-14{% endif %}">
|
||||||
<span class="flex h-8 w-8 items-center justify-center earthen-blob-soft text-sm font-semibold {% if orientation == "horizontal" %}mx-auto{% else %}absolute left-0 top-0 ring-4 ring-background{% endif %}" style="background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));">
|
<span class="flex h-8 w-8 items-center justify-center earthen-blob-soft text-sm font-semibold {% if orientation == "horizontal" %}mx-auto{% else %}absolute left-0 top-0 ring-4 ring-background{% endif %}" style="background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));">
|
||||||
{% if marker == "numbered" %}{{ forloop.counter }}{% elif marker == "dot" %}<span class="h-2 w-2 rounded-full bg-primary-foreground"></span>{% else %}<svg class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#flag"></use></svg>{% endif %}
|
{% if marker == "numbered" %}{{ forloop.counter }}{% elif marker == "dot" %}<span class="h-2 w-2 rounded-full bg-primary-foreground"></span>{% else %}<svg width="16" height="16" class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#flag"></use></svg>{% endif %}
|
||||||
</span>
|
</span>
|
||||||
<div class="{% if orientation == "horizontal" %}mt-4{% else %}pt-1{% endif %}">
|
<div class="{% if orientation == "horizontal" %}mt-4{% else %}pt-1{% endif %}">
|
||||||
{% if step.label %}<p class="text-xs font-semibold uppercase tracking-wider" style="color:hsl(var(--primary))">{{ step.label }}</p>{% endif %}
|
{% if step.label %}<p class="text-xs font-semibold uppercase tracking-wider" style="color:hsl(var(--primary))">{{ step.label }}</p>{% endif %}
|
||||||
|
|||||||