Compare commits

..

6 Commits

Author SHA1 Message Date
Alex Dunmow
c146a441ab chore(corporate-modernist): bump to 0.5.0 (Wave B remediation)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:08:28 +08:00
Alex Dunmow
df29fae033 feat(corporate-modernist): Wave B gallery reshoot — Meridian Advisory wordmark (home/about/article x light+dark)
Reshot after the wordmark/master-page fix: header now reads 'Meridian
Advisory' (was the leaked gallery instance name). 6 retina shots +
light-canonical preview (home-light).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:08:28 +08:00
Alex Dunmow
9380cfdcf4 fix(corporate-modernist): size icon-shortcode SVGs (shortcode balloon trap)
The CMS ::lucide:name:size:: inline shortcode expands to an UNSIZED
<svg class="inline-block h-N w-N"><use .../></svg> — the theme can't
attribute the shortcode output, so if the host Tailwind JIT drops the
h-N/w-N utility the icon balloons to the SVG default box (the coffee/
Wave-B root cause). Replace all 21 icon shortcodes across 14 templates
with explicit <svg width=.. height=..> markup (preserving the same
class + href, only adding pinned dimensions): sm=16, md=20, lg=24. The
navbar hamburger renders on every page, so this hardens every shot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:08:02 +08:00
Alex Dunmow
517ca93b01 fix(corporate-modernist): unbreak contact-form template register (Wave B blocker)
The mobile inline <style> emitted '@media (min-width:640px){#contact-form-...'
— the '{#' before the ID selector is the ninjatpl comment-open token, so
the lexer read the rest of the line as a single-line comment and failed
on the trailing newline ('Newline not permitted in a single-line comment').
Strict full re-register (theme hot-swap / InstallFromRegistry) 500s on it,
blocking every theme upgrade; the /contact page is also broken. Insert a
space ('){ #contact-form') — valid CSS, breaks the token. Only occurrence
across all templates. make build/verify don't lex templates, so it slipped.

bump to 0.4.2

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:48:03 +08:00
Alex Dunmow
df486e06bd fix(corporate-modernist): SVG geometry guard on <use> icons (Wave B 4d)
Add explicit width/height to the 4 <use> icon SVGs (author-bio-hero
social x3 = 20x20, sidebar-nav = 16x16). The theme's cm-icon class has
no CSS sizing, so an unsized <use> SVG balloons to the SVG default box;
explicit presentation attributes pin the geometry regardless of the
host Tailwind JIT. Matches the art-deco pattern.

bump to 0.4.1

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:44:33 +08:00
Alex Dunmow
68c52394fd fix(corporate-modernist): brand wordmark + article depth (Wave B remediation)
Header wordmark leaked the gallery instance name ('Gallery
corporate-modernist') because the navbar master-page block set no
logoText, so it fell through to context.site.title (= the instance
name). Every correctly-rendering theme (art-deco, kindergarten,
terminal, gotham, noir) sets logoType/logoText on its navbar; this
theme was the only one that did not. Add logoText 'Meridian Advisory'
to both navbar master blocks (default + landing).

Seed: switch settings key to the fleet-standard companyName and add
settings.override.title so a consented customer install also sets the
real site title (SEO/meta/RSS/email); the gallery relies on the
master-page wordmark since demo-install override is grant-gated.

Expand the captured /blog/operations-reset article to 10 substantive
management-consulting paragraphs (was 2, stranding a dead band above
the footer); bring the other two articles to 5 paragraphs each.

bump to 0.4.0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 10:44:41 +08:00
27 changed files with 29 additions and 26 deletions

View File

@ -4,7 +4,7 @@
"title": "Corporate Modernist Default Master", "title": "Corporate Modernist Default Master",
"page_templates": ["default", "article", "blog-index", "full-width"], "page_templates": ["default", "article", "blog-index", "full-width"],
"blocks": [ "blocks": [
{ "block_key": "navbar", "title": "Main Navigation", "content": { "variant": "standard", "menuName": "main" }, "slot": "header", "sort_order": 0 }, { "block_key": "navbar", "title": "Main Navigation", "content": { "variant": "standard", "menuName": "main", "logoType": "text", "logoText": { "text": "Meridian Advisory" } }, "slot": "header", "sort_order": 0 },
{ "block_key": "slot", "title": "Main Content Slot", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, { "block_key": "slot", "title": "Main Content Slot", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 },
{ "block_key": "footer", "title": "Site Footer", "content": { "layout": "columns", "showSocial": true, "companyName": "Meridian Advisory", "tagline": "Strategy, operations, and risk counsel for boards.", "copyright": "Meridian Advisory" }, "slot": "footer", "sort_order": 0 } { "block_key": "footer", "title": "Site Footer", "content": { "layout": "columns", "showSocial": true, "companyName": "Meridian Advisory", "tagline": "Strategy, operations, and risk counsel for boards.", "copyright": "Meridian Advisory" }, "slot": "footer", "sort_order": 0 }
] ]
@ -14,7 +14,7 @@
"title": "Corporate Modernist Landing Master", "title": "Corporate Modernist Landing Master",
"page_templates": ["landing"], "page_templates": ["landing"],
"blocks": [ "blocks": [
{ "block_key": "navbar", "title": "Main Navigation", "content": { "variant": "standard", "menuName": "main" }, "slot": "header", "sort_order": 0 }, { "block_key": "navbar", "title": "Main Navigation", "content": { "variant": "standard", "menuName": "main", "logoType": "text", "logoText": { "text": "Meridian Advisory" } }, "slot": "header", "sort_order": 0 },
{ "block_key": "hero", "title": "Landing Hero", "content": { "template": "left-aligned", "eyebrow": "B2B advisory", "headline": "Precise counsel for boards that move first", "subheadline": "Strategy, operations, and risk work delivered on a fixed scope." }, "slot": "hero", "sort_order": 0 }, { "block_key": "hero", "title": "Landing Hero", "content": { "template": "left-aligned", "eyebrow": "B2B advisory", "headline": "Precise counsel for boards that move first", "subheadline": "Strategy, operations, and risk work delivered on a fixed scope." }, "slot": "hero", "sort_order": 0 },
{ "block_key": "slot", "title": "Main Content Slot", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, { "block_key": "slot", "title": "Main Content Slot", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 },
{ "block_key": "cta", "title": "Closing CTA", "content": { "background": "band", "heading": "Book a working session", "text": "Ninety minutes with a principal. No pitch deck.", "primaryLabel": "Request a session", "primaryUrl": "/contact" }, "slot": "cta", "sort_order": 0 }, { "block_key": "cta", "title": "Closing CTA", "content": { "background": "band", "heading": "Book a working session", "text": "Ninety minutes with a principal. No pitch deck.", "primaryLabel": "Request a session", "primaryUrl": "/contact" }, "slot": "cta", "sort_order": 0 },

View File

@ -2,7 +2,7 @@
name = "corporate-modernist" name = "corporate-modernist"
display_name = "Corporate Modernist" display_name = "Corporate Modernist"
scope = "@themes" scope = "@themes"
version = "0.3.0" version = "0.5.0"
description = "Swiss-grid B2B theme with restrained typography, a single configurable accent, and trust-signal blocks for enterprise sites." description = "Swiss-grid B2B theme with restrained typography, a single configurable accent, and trust-signal blocks for enterprise sites."
kind = "theme" kind = "theme"
categories = ["templates"] categories = ["templates"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 422 KiB

View File

@ -2,8 +2,11 @@
"demo": true, "demo": true,
"settings": { "settings": {
"merge": { "merge": {
"site_name": "Meridian Advisory", "companyName": "Meridian Advisory",
"tagline": "Strategy, operations, and risk counsel for boards." "tagline": "Strategy, operations, and risk counsel for boards."
},
"override": {
"title": "Meridian Advisory"
} }
}, },
"data_tables": [ "data_tables": [
@ -67,7 +70,7 @@
"reconcile_blocks": true, "reconcile_blocks": true,
"blocks": [ "blocks": [
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Resetting a branch operating model", "level": 1 } }, { "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Resetting a branch operating model", "level": 1 } },
{ "block_key": "text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "text": "<p>A regional bank asked us to cut cost to serve without closing branches. We started with the numbers the board already trusted. Then we tested each assumption against a week of real transactions.</p><p>The answer was not fewer branches. It was fewer tasks per branch. We moved back-office work to a shared team and gave each branch a single metric it could hold.</p>" } } { "block_key": "text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "text": "<p>A regional bank came to us with a hard constraint and a soft one. The hard constraint was cost: the branch network ran at a cost to serve the board could no longer defend to its investors. The soft constraint was reputation: closing branches in the towns that had banked with the firm for a century was not on the table. The brief, in one line, was to cut the cost of the network without shrinking it.</p><p>The obvious answer was the wrong one. Every prior review had reached for the same lever, closing the smallest branches and rolling their customers into a larger site down the road. On a spreadsheet that lever works. In the field it moves cost rather than removing it, because the demand does not disappear with the building. It reappears as longer queues, higher attrition, and a call centre absorbing the overflow at a worse unit cost than the branch it replaced.</p><p>So we started where the board was most comfortable, with its own numbers. We took the management accounts the directors already trusted and treated every figure in them as a hypothesis rather than a fact. A cost-to-serve model is only as good as its assumptions about what staff actually do all day, and those assumptions are almost never measured. They are inherited.</p><p>To test them we spent a week inside four representative branches, logging every transaction and the time it consumed. Not a survey and not a workshop, but a straight count of the work as it happened. The picture that came back did not match the model. More than half of branch staff time went to back-office tasks that had drifted to the counter over the years: reconciliations, exception handling, compliance paperwork, and the small administrative jobs that no one had ever formally assigned to the front line.</p><p>That reframed the problem. The network was not carrying too many branches. It was carrying too many tasks per branch, and most of those tasks did not need a customer in front of them to be done. The cost was real, but it was in the work mix, not in the property.</p><p>The intervention followed from the diagnosis. We lifted the back-office work out of the branches and consolidated it into a single shared operations team, sized to the real volume rather than the headcount that history had left in each site. Branches kept the work that genuinely required presence and judgement: advice, complex transactions, and the relationships that brought the deposits in.</p><p>The harder change was cultural, not structural. Branch managers had come to measure themselves by activity, by how busy the floor looked, and a floor doing less back-office work looks quieter even when it is more productive. We replaced the crowded dashboard each manager had been chasing with one metric they could actually hold: cost to serve per active customer, reported monthly, owned by name.</p><p>A single metric does two things a dashboard cannot. It removes the argument about which number matters this quarter, and it makes the trade-offs visible to the person making them. When a manager can see that adding an hour of back-office work to the counter raises their one number, they stop asking for it back. The behaviour changes without a memo.</p><p>The results held because the design made them cheap to sustain. Cost to serve fell by roughly a third across the pilot branches inside two quarters, with no reduction in the network and no measurable hit to customer satisfaction. The shared team ran the consolidated work at a lower unit cost than the branches had, precisely because it was built for volume and specialisation rather than proximity.</p><p>We finished the way we try to finish every engagement, by making ourselves unnecessary. The model, the metric, and the reporting cadence stayed with the bank's own operations leadership, and the owners of each number were named before we left. A year on, the firm had extended the same operating model to the rest of the network without us. That is the outcome we measure: not the report we hand over, but the decision the client can keep making on their own.</p>" } }
] ]
}, },
{ {
@ -78,7 +81,7 @@
"reconcile_blocks": true, "reconcile_blocks": true,
"blocks": [ "blocks": [
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Reading a risk register the board will use", "level": 1 } }, { "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Reading a risk register the board will use", "level": 1 } },
{ "block_key": "text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "text": "<p>A risk register written for auditors lists everything. A register written for directors ranks a few things and says who owns them. The second kind gets read.</p><p>We keep the top ten risks on one page. Each has an owner, a trend, and a next action. Everything else lives in the appendix.</p>" } } { "block_key": "text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "text": "<p>A risk register written for auditors lists everything. It is exhaustive by design, because its job is to prove that nothing was missed. A register written for directors does the opposite job. It ranks a few things, says who owns them, and helps a board decide where to spend its limited attention. The two documents look alike and serve almost opposite purposes, and most firms only own the first kind.</p><p>The tell is length. When a register runs to sixty lines, no director reads past the first page, and the risks that matter sink into the same grey list as the ones that do not. Completeness, past a point, is indistinguishable from noise. The board ends up governing by exception report rather than by the register itself.</p><p>We keep the top ten risks on a single page. Each has an owner named in person rather than by committee, a direction of travel since the last meeting, and a specific next action with a date. Everything else still exists, fully documented, in an appendix the auditors can have. The board's page is not the whole truth. It is the part of the truth a board can act on.</p><p>Ranking is the work most firms skip. It forces the executive team to agree, before the meeting, which risks are genuinely material this quarter, and that argument is uncomfortable because it cannot hide behind a long list. But a board that has seen the ranking debated trusts the register in a way it never trusts a catalogue.</p><p>The trend column earns its place by turning the register from a snapshot into a story. A risk that is amber and improving needs a different conversation from one that is amber and worsening, and only the direction of travel tells them apart. Directors govern change, not states, and the register should be built to show change.</p>" } }
] ]
}, },
{ {
@ -89,7 +92,7 @@
"reconcile_blocks": true, "reconcile_blocks": true,
"blocks": [ "blocks": [
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "The ninety-day decision", "level": 1 } }, { "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "The ninety-day decision", "level": 1 } },
{ "block_key": "text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "text": "<p>Long engagements drift because no decision anchors them. We set a real decision inside the first ninety days. It forces the evidence to be good enough to act on.</p><p>The decision does not have to be final. It has to be real. A board that decides once will decide again faster.</p>" } } { "block_key": "text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "text": "<p>Long engagements drift because no decision anchors them. Work expands to fill the time available, evidence accumulates without ever being tested against a choice, and the project mistakes activity for progress. The cure is not tighter project management. It is a real decision, scheduled early, that the whole effort has to earn.</p><p>We set that decision inside the first ninety days. The date is fixed at the start and treated as immovable, because a movable deadline sets no discipline at all. Everything before it exists to make that one choice well: the analysis, the interviews, the modelling. Everything is scoped to the question the board will actually have to answer.</p><p>Ninety days is deliberate. It is long enough to gather evidence that is good enough to act on, and short enough that the organisation has not yet lost interest or reorganised around the problem. Past the first quarter, the cost of delay stops being analytical and starts being political, as sponsors move on and the mandate quietly erodes.</p><p>The decision does not have to be final. It has to be real, meaning it commits resources, closes off an option, and creates something to be right or wrong about. A reversible decision made on time teaches an organisation far more than a perfect decision made too late, because it produces feedback while the team still cares about the answer.</p><p>What we are really installing is a habit. A board that decides once, on evidence, inside a deadline, will decide again faster the next time, because it has learned that waiting for certainty is itself a decision, and usually the most expensive one available.</p>" } }
] ]
}, },
{ {

View File

@ -3,6 +3,6 @@
<div data-bn-announcement data-bn-annkey="{{ variant|default:'info' }}:{{ message|slugify }}" class="cm-announce {{ annvar }} {{ class }}" style="{{ annsty }}"> <div data-bn-announcement data-bn-annkey="{{ variant|default:'info' }}:{{ message|slugify }}" class="cm-announce {{ annvar }} {{ class }}" style="{{ annsty }}">
<div class="cm-content-well cm-announce-row" style="position:relative;display:flex;align-items:center;justify-content:center;gap:0.75rem;padding-top:0.5rem;padding-bottom:0.5rem;font-size:0.875rem;text-align:center;"> <div class="cm-content-well cm-announce-row" style="position:relative;display:flex;align-items:center;justify-content:center;gap:0.75rem;padding-top:0.5rem;padding-bottom:0.5rem;font-size:0.875rem;text-align:center;">
<p style="margin:0;font-weight:500;">{{ message }}{% if linkText and linkUrl %} <a href="{{ linkUrl }}" style="color:inherit;text-decoration:underline;text-underline-offset:2px;">{{ linkText }}</a>{% endif %}</p> <p style="margin:0;font-weight:500;">{{ message }}{% if linkText and linkUrl %} <a href="{{ linkUrl }}" style="color:inherit;text-decoration:underline;text-underline-offset:2px;">{{ linkText }}</a>{% endif %}</p>
{% if dismissable %}<button type="button" data-bn-ann-dismiss aria-label="Dismiss announcement" class="cm-announce-close" style="position:absolute;right:0.75rem;top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;padding:0.25rem;background:none;border:0;color:inherit;cursor:pointer;">::lucide:x:sm::</button>{% endif %} {% if dismissable %}<button type="button" data-bn-ann-dismiss aria-label="Dismiss announcement" class="cm-announce-close" style="position:absolute;right:0.75rem;top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;padding:0.25rem;background:none;border:0;color:inherit;cursor:pointer;"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#x"/></svg></button>{% endif %}
</div> </div>
</div> </div>

View File

@ -6,8 +6,8 @@
{% if title %}<p class="cm-display" style="margin:0;font-size:0.9375rem;color:hsl(var(--foreground));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ title }}</p>{% endif %} {% if title %}<p class="cm-display" style="margin:0;font-size:0.9375rem;color:hsl(var(--foreground));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ title }}</p>{% endif %}
{% if artist %}<p style="margin:0;font-size:0.8125rem;color:hsl(var(--muted-foreground));">{{ artist }}</p>{% endif %} {% if artist %}<p style="margin:0;font-size:0.8125rem;color:hsl(var(--muted-foreground));">{{ artist }}</p>{% endif %}
<div data-bn-audio-slot style="display:flex;align-items:center;gap:0.75rem;margin-top:0.5rem;"> <div data-bn-audio-slot style="display:flex;align-items:center;gap:0.75rem;margin-top:0.5rem;">
<button type="button" data-bn-audio-play class="cm-btn-primary cm-btn-sm" aria-label="Play{% if title %}: {{ title }}{% endif %}" style="display:inline-flex;align-items:center;gap:0.375rem;">::lucide:play:sm:: Play</button> <button type="button" data-bn-audio-play class="cm-btn-primary cm-btn-sm" aria-label="Play{% if title %}: {{ title }}{% endif %}" style="display:inline-flex;align-items:center;gap:0.375rem;"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#play"/></svg> Play</button>
{% if download %}<a href="{% if media %}{{ media|mediaURL }}{% else %}{{ url }}{% endif %}" download class="cm-btn-ghost" style="display:inline-flex;align-items:center;gap:0.25rem;font-size:0.8125rem;color:hsl(var(--muted-foreground));text-decoration:none;">::lucide:download:sm:: Download</a>{% endif %} {% if download %}<a href="{% if media %}{{ media|mediaURL }}{% else %}{{ url }}{% endif %}" download class="cm-btn-ghost" style="display:inline-flex;align-items:center;gap:0.25rem;font-size:0.8125rem;color:hsl(var(--muted-foreground));text-decoration:none;"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#download"/></svg> Download</a>{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1 +1 @@
{% if context.currentAuthor %}<section class="cm-section {{ class }}" data-block="corporate-modernist:author-bio-hero"><div class="cm-content-well"><div class="cm-measure cm-stack" style="text-align: center; margin-left: auto; margin-right: auto;">{% if showAvatar and context.currentAuthor.avatarUrl %}<img class="cm-avatar" src="{{ context.currentAuthor.avatarUrl }}" alt="{{ context.currentAuthor.displayName }}" style="width: 6rem; height: 6rem; border-radius: 9999px; object-fit: cover; margin-left: auto; margin-right: auto;">{% else %}<span class="cm-mark cm-mark-ring" aria-hidden="true" style="margin-left: auto; margin-right: auto;"></span>{% endif %}<h1 class="cm-display" style="margin: 0;">{{ context.currentAuthor.displayName }}</h1>{% if context.currentAuthor.bio %}<p class="cm-lede" style="margin: 0;">{{ context.currentAuthor.bio }}</p>{% endif %}{% if showSocial %}<div class="cm-btn-row" style="justify-content: center;">{% if context.currentAuthor.websiteUrl %}<a class="cm-btn-ghost cm-btn-sm" href="{{ context.currentAuthor.websiteUrl }}" target="_blank" rel="noopener noreferrer" title="Website"><svg class="cm-icon" aria-hidden="true"><use href="/icons/lucide.svg#globe"/></svg></a>{% endif %}{% if context.currentAuthor.twitterHandle %}<a class="cm-btn-ghost cm-btn-sm" href="https://twitter.com/{{ context.currentAuthor.twitterHandle|cut:"@" }}" target="_blank" rel="noopener noreferrer" title="X"><svg class="cm-icon" aria-hidden="true"><use href="/icons/simple-icons.svg#x"/></svg></a>{% endif %}{% if context.currentAuthor.linkedinUrl %}<a class="cm-btn-ghost cm-btn-sm" href="{{ context.currentAuthor.linkedinUrl }}" target="_blank" rel="noopener noreferrer" title="LinkedIn"><svg class="cm-icon" aria-hidden="true"><use href="/icons/simple-icons.svg#linkedin"/></svg></a>{% endif %}</div>{% endif %}</div></div></section>{% endif %} {% if context.currentAuthor %}<section class="cm-section {{ class }}" data-block="corporate-modernist:author-bio-hero"><div class="cm-content-well"><div class="cm-measure cm-stack" style="text-align: center; margin-left: auto; margin-right: auto;">{% if showAvatar and context.currentAuthor.avatarUrl %}<img class="cm-avatar" src="{{ context.currentAuthor.avatarUrl }}" alt="{{ context.currentAuthor.displayName }}" style="width: 6rem; height: 6rem; border-radius: 9999px; object-fit: cover; margin-left: auto; margin-right: auto;">{% else %}<span class="cm-mark cm-mark-ring" aria-hidden="true" style="margin-left: auto; margin-right: auto;"></span>{% endif %}<h1 class="cm-display" style="margin: 0;">{{ context.currentAuthor.displayName }}</h1>{% if context.currentAuthor.bio %}<p class="cm-lede" style="margin: 0;">{{ context.currentAuthor.bio }}</p>{% endif %}{% if showSocial %}<div class="cm-btn-row" style="justify-content: center;">{% if context.currentAuthor.websiteUrl %}<a class="cm-btn-ghost cm-btn-sm" href="{{ context.currentAuthor.websiteUrl }}" target="_blank" rel="noopener noreferrer" title="Website"><svg class="cm-icon" width="20" height="20" aria-hidden="true"><use href="/icons/lucide.svg#globe"/></svg></a>{% endif %}{% if context.currentAuthor.twitterHandle %}<a class="cm-btn-ghost cm-btn-sm" href="https://twitter.com/{{ context.currentAuthor.twitterHandle|cut:"@" }}" target="_blank" rel="noopener noreferrer" title="X"><svg class="cm-icon" width="20" height="20" aria-hidden="true"><use href="/icons/simple-icons.svg#x"/></svg></a>{% endif %}{% if context.currentAuthor.linkedinUrl %}<a class="cm-btn-ghost cm-btn-sm" href="{{ context.currentAuthor.linkedinUrl }}" target="_blank" rel="noopener noreferrer" title="LinkedIn"><svg class="cm-icon" width="20" height="20" aria-hidden="true"><use href="/icons/simple-icons.svg#linkedin"/></svg></a>{% endif %}</div>{% endif %}</div></div></section>{% endif %}

View File

@ -1 +1 @@
<article class="cm-card cm-card-accent {{ class }}">{% if media %}<div class="cm-media-frame" style="aspect-ratio: 16 / 9; margin: -1.5rem -1.5rem 1.25rem -1.5rem; border: 0; border-bottom: 1px solid hsl(var(--border));">{% img media alt=title|default:"" class="cm-card-media" %}</div>{% endif %}{% if title %}<h3 class="cm-feature-title" style="margin-top: 0; font-size: 1.25rem;">{{ title }}</h3>{% endif %}{% if text %}<div class="cm-text" style="font-size: 0.9375rem; line-height: 1.6; color: hsl(var(--muted-foreground));">{{ text|safe }}</div>{% endif %}{% if linkLabel and link %}<a class="cm-btn-ghost" href="{{ link }}" style="margin-top: 1rem;">{{ linkLabel }}::lucide:arrow-right:sm::</a>{% endif %}</article> <article class="cm-card cm-card-accent {{ class }}">{% if media %}<div class="cm-media-frame" style="aspect-ratio: 16 / 9; margin: -1.5rem -1.5rem 1.25rem -1.5rem; border: 0; border-bottom: 1px solid hsl(var(--border));">{% img media alt=title|default:"" class="cm-card-media" %}</div>{% endif %}{% if title %}<h3 class="cm-feature-title" style="margin-top: 0; font-size: 1.25rem;">{{ title }}</h3>{% endif %}{% if text %}<div class="cm-text" style="font-size: 0.9375rem; line-height: 1.6; color: hsl(var(--muted-foreground));">{{ text|safe }}</div>{% endif %}{% if linkLabel and link %}<a class="cm-btn-ghost" href="{{ link }}" style="margin-top: 1rem;">{{ linkLabel }}<svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"/></svg></a>{% endif %}</article>

View File

@ -11,7 +11,7 @@
<h3 class="cm-feature-title" style="font-size:1.125rem;margin:0;">{{ event.title }}</h3> <h3 class="cm-feature-title" style="font-size:1.125rem;margin:0;">{{ event.title }}</h3>
{% if event.venue %}<p style="margin:0;font-size:0.875rem;color:hsl(var(--muted-foreground));">{{ event.venue }}</p>{% endif %} {% if event.venue %}<p style="margin:0;font-size:0.875rem;color:hsl(var(--muted-foreground));">{{ event.venue }}</p>{% endif %}
{% if event.description %}<p style="margin:0;font-size:0.875rem;color:hsl(var(--muted-foreground));">{{ event.description }}</p>{% endif %} {% if event.description %}<p style="margin:0;font-size:0.875rem;color:hsl(var(--muted-foreground));">{{ event.description }}</p>{% endif %}
{% if event.link %}<a class="cm-btn-ghost" href="{{ event.link }}" style="margin-top:auto;display:inline-flex;align-items:center;gap:0.375rem;">{{ event.linkLabel|default:"Details" }}::lucide:arrow-right:sm::</a>{% endif %} {% if event.link %}<a class="cm-btn-ghost" href="{{ event.link }}" style="margin-top:auto;display:inline-flex;align-items:center;gap:0.375rem;">{{ event.linkLabel|default:"Details" }}<svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"/></svg></a>{% endif %}
</div> </div>
</article>{% endif %}{% endfor %} </article>{% endif %}{% endfor %}
</div><style>.cm-event-media{display:block;width:100%;height:100%;object-fit:cover;}</style> </div><style>.cm-event-media{display:block;width:100%;height:100%;object-fit:cover;}</style>

View File

@ -2,5 +2,5 @@
<section class="cm-section {{ class }}"><div class="cm-content-well cm-measure"> <section class="cm-section {{ class }}"><div class="cm-content-well cm-measure">
{% if heading %}<h2 class="cm-heading" style="font-size: clamp(1.75rem, 3vw, 2.25rem); margin: 0 0 0.75rem 0;"><span class="cm-heading-h2-accent">{{ heading }}</span></h2>{% endif %} {% if heading %}<h2 class="cm-heading" style="font-size: clamp(1.75rem, 3vw, 2.25rem); margin: 0 0 0.75rem 0;"><span class="cm-heading-h2-accent">{{ heading }}</span></h2>{% endif %}
{% if intro %}<p class="cm-lede" style="max-width: 60ch; margin: 0 0 2rem 0; color: hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %} {% if intro %}<p class="cm-lede" style="max-width: 60ch; margin: 0 0 2rem 0; color: hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
{% if items %}<div class="cm-hairline-top" style="margin-top: 1.5rem;">{% for item in items %}<details class="cm-faq-item cm-hairline-bottom"{% if variant == "open-list" %} open{% endif %}><summary class="cm-heading" style="display: flex; justify-content: space-between; align-items: center; gap: 1rem; cursor: pointer; padding: 1rem 0; font-size: 1.125rem; list-style: none;">{{ item.question }}<span class="cm-faq-chevron" aria-hidden="true" style="color: hsl(var(--muted-foreground)); flex: none;">::lucide:chevron-down:sm::</span></summary><div class="cm-faq-answer cm-text" style="padding-bottom: 1rem; color: hsl(var(--muted-foreground));">{{ item.answer|safe }}</div></details>{% endfor %}</div>{% endif %} {% if items %}<div class="cm-hairline-top" style="margin-top: 1.5rem;">{% for item in items %}<details class="cm-faq-item cm-hairline-bottom"{% if variant == "open-list" %} open{% endif %}><summary class="cm-heading" style="display: flex; justify-content: space-between; align-items: center; gap: 1rem; cursor: pointer; padding: 1rem 0; font-size: 1.125rem; list-style: none;">{{ item.question }}<span class="cm-faq-chevron" aria-hidden="true" style="color: hsl(var(--muted-foreground)); flex: none;"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#chevron-down"/></svg></span></summary><div class="cm-faq-answer cm-text" style="padding-bottom: 1rem; color: hsl(var(--muted-foreground));">{{ item.answer|safe }}</div></details>{% endfor %}</div>{% endif %}
</div></section> </div></section>

View File

@ -3,5 +3,5 @@
{% if eyebrow %}<p class="cm-eyebrow">{{ eyebrow }}</p>{% endif %} {% if eyebrow %}<p class="cm-eyebrow">{{ eyebrow }}</p>{% endif %}
{% if heading %}<h2 class="cm-heading" style="font-size: clamp(1.75rem, 3vw, 2.25rem); margin: 0 0 0.75rem 0;"><span class="cm-heading-h2-accent">{{ heading }}</span></h2>{% endif %} {% if heading %}<h2 class="cm-heading" style="font-size: clamp(1.75rem, 3vw, 2.25rem); margin: 0 0 0.75rem 0;"><span class="cm-heading-h2-accent">{{ heading }}</span></h2>{% endif %}
{% if intro %}<p class="cm-lede" style="max-width: 60ch; margin: 0 0 2.5rem 0; color: hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %} {% if intro %}<p class="cm-lede" style="max-width: 60ch; margin: 0 0 2.5rem 0; color: hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
{% if items %}<div class="cm-grid {% if columns == 2 %}cm-grid-2{% elif columns == 4 %}cm-grid-4{% else %}cm-grid-3{% endif %}">{% for item in items %}<div class="cm-feature">{% if item.icon %}<span class="cm-mark cm-mark-square" aria-hidden="true">::{{ item.icon }}:sm::</span>{% else %}<span class="cm-mark cm-mark-square" aria-hidden="true"></span>{% endif %}{% if item.title %}<h3 class="cm-feature-title">{% if item.linkUrl %}<a href="{{ item.linkUrl }}" style="color: inherit; text-decoration: none;">{{ item.title }}</a>{% else %}{{ item.title }}{% endif %}</h3>{% endif %}{% if item.text %}<p class="cm-text" style="font-size: 0.9375rem; line-height: 1.6; color: hsl(var(--muted-foreground));">{{ item.text }}</p>{% endif %}{% if item.linkUrl and item.linkLabel %}<a class="cm-btn-ghost" href="{{ item.linkUrl }}" style="margin-top: 0.75rem;">{{ item.linkLabel }}::lucide:arrow-right:sm::</a>{% endif %}</div>{% endfor %}</div>{% endif %} {% if items %}<div class="cm-grid {% if columns == 2 %}cm-grid-2{% elif columns == 4 %}cm-grid-4{% else %}cm-grid-3{% endif %}">{% for item in items %}<div class="cm-feature">{% if item.icon %}<span class="cm-mark cm-mark-square" aria-hidden="true">::{{ item.icon }}:sm::</span>{% else %}<span class="cm-mark cm-mark-square" aria-hidden="true"></span>{% endif %}{% if item.title %}<h3 class="cm-feature-title">{% if item.linkUrl %}<a href="{{ item.linkUrl }}" style="color: inherit; text-decoration: none;">{{ item.title }}</a>{% else %}{{ item.title }}{% endif %}</h3>{% endif %}{% if item.text %}<p class="cm-text" style="font-size: 0.9375rem; line-height: 1.6; color: hsl(var(--muted-foreground));">{{ item.text }}</p>{% endif %}{% if item.linkUrl and item.linkLabel %}<a class="cm-btn-ghost" href="{{ item.linkUrl }}" style="margin-top: 0.75rem;">{{ item.linkLabel }}<svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"/></svg></a>{% endif %}</div>{% endfor %}</div>{% endif %}
</div></section> </div></section>

View File

@ -7,11 +7,11 @@
{% if specialHoursNote %}<p class="cm-surface-muted" style="margin-top:1rem;border:1px solid hsl(var(--border));background:hsl(var(--muted));padding:0.5rem 0.75rem;font-size:0.875rem;color:hsl(var(--muted-foreground));">{{ specialHoursNote }}</p>{% endif %} {% if specialHoursNote %}<p class="cm-surface-muted" style="margin-top:1rem;border:1px solid hsl(var(--border));background:hsl(var(--muted));padding:0.5rem 0.75rem;font-size:0.875rem;color:hsl(var(--muted-foreground));">{{ specialHoursNote }}</p>{% endif %}
{% if address %}<div style="margin-top:1.5rem;"><div class="cm-stat-label" style="margin:0;">Address</div><address style="margin-top:0.25rem;white-space:pre-line;font-style:normal;color:hsl(var(--foreground));">{{ address }}</address></div>{% endif %} {% if address %}<div style="margin-top:1.5rem;"><div class="cm-stat-label" style="margin:0;">Address</div><address style="margin-top:0.25rem;white-space:pre-line;font-style:normal;color:hsl(var(--foreground));">{{ address }}</address></div>{% endif %}
{% if phone %}<div style="margin-top:1rem;"><div class="cm-stat-label" style="margin:0;">Phone</div><a href="tel:{{ phone }}" style="display:inline-block;margin-top:0.25rem;color:hsl(var(--foreground));text-decoration:none;">{{ phone }}</a></div>{% endif %} {% if phone %}<div style="margin-top:1rem;"><div class="cm-stat-label" style="margin:0;">Phone</div><a href="tel:{{ phone }}" style="display:inline-block;margin-top:0.25rem;color:hsl(var(--foreground));text-decoration:none;">{{ phone }}</a></div>{% endif %}
{% if directionsUrl %}<a href="{{ directionsUrl }}" target="_blank" rel="noopener noreferrer" class="cm-btn-outline" style="margin-top:1.5rem;display:inline-flex;align-items:center;gap:0.5rem;">::lucide:navigation:sm::Get directions</a>{% endif %} {% if directionsUrl %}<a href="{{ directionsUrl }}" target="_blank" rel="noopener noreferrer" class="cm-btn-outline" style="margin-top:1.5rem;display:inline-flex;align-items:center;gap:0.5rem;"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#navigation"/></svg>Get directions</a>{% endif %}
</div> </div>
{% if mapEmbedUrl %} {% if mapEmbedUrl %}
<div class="cm-media-frame" style="width:100%;min-height:16rem;aspect-ratio:4 / 3;overflow:hidden;border:1px solid hsl(var(--border));border-radius:4px;background:hsl(var(--muted));"> <div class="cm-media-frame" style="width:100%;min-height:16rem;aspect-ratio:4 / 3;overflow:hidden;border:1px solid hsl(var(--border));border-radius:4px;background:hsl(var(--muted));">
<button type="button" data-map-src="{{ mapEmbedUrl }}" onclick="var f=document.createElement('iframe');f.src=this.getAttribute('data-map-src');f.setAttribute('style','width:100%;height:100%;border:0;');f.setAttribute('loading','lazy');f.setAttribute('referrerpolicy','no-referrer-when-downgrade');f.setAttribute('title','Map');this.parentNode.replaceChild(f,this);" style="display:flex;align-items:center;justify-content:center;gap:0.5rem;width:100%;height:100%;min-height:16rem;border:0;background:none;cursor:pointer;color:hsl(var(--foreground));font-family:var(--font-heading, 'Inter Tight', 'Inter', system-ui, sans-serif);font-weight:500;">::lucide:map-pin:md::{{ mapButtonLabel|default:"Load map" }}</button> <button type="button" data-map-src="{{ mapEmbedUrl }}" onclick="var f=document.createElement('iframe');f.src=this.getAttribute('data-map-src');f.setAttribute('style','width:100%;height:100%;border:0;');f.setAttribute('loading','lazy');f.setAttribute('referrerpolicy','no-referrer-when-downgrade');f.setAttribute('title','Map');this.parentNode.replaceChild(f,this);" style="display:flex;align-items:center;justify-content:center;gap:0.5rem;width:100%;height:100%;min-height:16rem;border:0;background:none;cursor:pointer;color:hsl(var(--foreground));font-family:var(--font-heading, 'Inter Tight', 'Inter', system-ui, sans-serif);font-weight:500;"><svg class="inline-block h-5 w-5" width="20" height="20" aria-hidden="true"><use href="/icons/lucide.svg#map-pin"/></svg>{{ mapButtonLabel|default:"Load map" }}</button>
</div> </div>
{% endif %} {% endif %}
</div> </div>

View File

@ -1 +1 @@
<nav class="cm-navbar {{ class }}" aria-label="Primary"><a class="cm-brand" href="/"><span class="cm-mark cm-mark-square" aria-hidden="true"></span>{% if logoType == "image" and logo %}{% img logo alt=alt|default:"Home" class="cm-brand-logo" %}{% else %}<span>{{ logoText.text|default:logoText|default:context.site.title|default:"Studio" }}</span>{% endif %}</a><div class="cm-nav-links">{% for item in menu.items %}<a class="cm-nav-link" href="{{ item.url }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %}>{{ item.label|default:item.title }}</a>{% endfor %}{% if cta.text and cta.url %}<a class="cm-btn-primary cm-btn-sm" href="{{ cta.url }}">{{ cta.text }}</a>{% endif %}</div><input type="checkbox" id="cm-nav-toggle-cb" class="cm-nav-cb" style="display:none;"><label for="cm-nav-toggle-cb" class="cm-nav-toggle cm-btn-outline cm-btn-sm" aria-label="Toggle menu">::lucide:menu:sm::</label><div class="cm-nav-drawer">{% for item in menu.items %}<a href="{{ item.url }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %}>{{ item.label|default:item.title }}</a>{% endfor %}{% if cta.text and cta.url %}<a href="{{ cta.url }}" class="cm-btn-primary cm-btn-sm" style="margin-top:0.75rem;">{{ cta.text }}</a>{% endif %}</div><style>.cm-nav-cb:checked ~ .cm-nav-drawer{display:flex;}</style></nav> <nav class="cm-navbar {{ class }}" aria-label="Primary"><a class="cm-brand" href="/"><span class="cm-mark cm-mark-square" aria-hidden="true"></span>{% if logoType == "image" and logo %}{% img logo alt=alt|default:"Home" class="cm-brand-logo" %}{% else %}<span>{{ logoText.text|default:logoText|default:context.site.title|default:"Studio" }}</span>{% endif %}</a><div class="cm-nav-links">{% for item in menu.items %}<a class="cm-nav-link" href="{{ item.url }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %}>{{ item.label|default:item.title }}</a>{% endfor %}{% if cta.text and cta.url %}<a class="cm-btn-primary cm-btn-sm" href="{{ cta.url }}">{{ cta.text }}</a>{% endif %}</div><input type="checkbox" id="cm-nav-toggle-cb" class="cm-nav-cb" style="display:none;"><label for="cm-nav-toggle-cb" class="cm-nav-toggle cm-btn-outline cm-btn-sm" aria-label="Toggle menu"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#menu"/></svg></label><div class="cm-nav-drawer">{% for item in menu.items %}<a href="{{ item.url }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %}>{{ item.label|default:item.title }}</a>{% endfor %}{% if cta.text and cta.url %}<a href="{{ cta.url }}" class="cm-btn-primary cm-btn-sm" style="margin-top:0.75rem;">{{ cta.text }}</a>{% endif %}</div><style>.cm-nav-cb:checked ~ .cm-nav-drawer{display:flex;}</style></nav>

View File

@ -1 +1 @@
<section class="cm-section {{ class }}" data-block="corporate-modernist:page-suggestions"><div class="cm-content-well"><div class="cm-measure cm-stack"><span class="cm-mark cm-mark-triangle" aria-hidden="true"></span><h2 class="cm-heading" style="font-size: clamp(1.5rem, 2.5vw, 2rem); margin: 0;"><span class="cm-heading-h2-accent">{{ title|default:"Were you looking for..." }}</span></h2>{% if suggestions %}<ul class="cm-stack-sm" style="list-style: none; margin: 0; padding: 0;">{% for s in suggestions %}<li><a class="cm-sidebar-link" href="/{{ s.slug }}" style="display: block;"><span class="cm-post-title" style="font-size: 1rem;">{{ s.title }}</span>{% if showDescription and s.excerpt %}<span class="cm-text" style="display: block; font-size: 0.875rem; color: hsl(var(--muted-foreground));">{{ s.excerpt }}</span>{% endif %}</a></li>{% endfor %}</ul>{% else %}{% if emptyMessage %}<p class="cm-text" style="margin: 0; color: hsl(var(--muted-foreground));">{{ emptyMessage }}</p>{% endif %}<div class="cm-btn-row"><a class="cm-btn-outline cm-btn-sm" href="/">::lucide:home:sm::Home</a><a class="cm-btn-outline cm-btn-sm" href="/blog">::lucide:newspaper:sm::Blog</a></div>{% endif %}</div></div></section> <section class="cm-section {{ class }}" data-block="corporate-modernist:page-suggestions"><div class="cm-content-well"><div class="cm-measure cm-stack"><span class="cm-mark cm-mark-triangle" aria-hidden="true"></span><h2 class="cm-heading" style="font-size: clamp(1.5rem, 2.5vw, 2rem); margin: 0;"><span class="cm-heading-h2-accent">{{ title|default:"Were you looking for..." }}</span></h2>{% if suggestions %}<ul class="cm-stack-sm" style="list-style: none; margin: 0; padding: 0;">{% for s in suggestions %}<li><a class="cm-sidebar-link" href="/{{ s.slug }}" style="display: block;"><span class="cm-post-title" style="font-size: 1rem;">{{ s.title }}</span>{% if showDescription and s.excerpt %}<span class="cm-text" style="display: block; font-size: 0.875rem; color: hsl(var(--muted-foreground));">{{ s.excerpt }}</span>{% endif %}</a></li>{% endfor %}</ul>{% else %}{% if emptyMessage %}<p class="cm-text" style="margin: 0; color: hsl(var(--muted-foreground));">{{ emptyMessage }}</p>{% endif %}<div class="cm-btn-row"><a class="cm-btn-outline cm-btn-sm" href="/"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#home"/></svg>Home</a><a class="cm-btn-outline cm-btn-sm" href="/blog"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#newspaper"/></svg>Blog</a></div>{% endif %}</div></div></section>

View File

@ -7,5 +7,5 @@
<div class="cm-field cm-field--full"><label class="cm-label" for="cm-reset-email">Email</label><input class="cm-input" type="email" name="email" id="cm-reset-email" required></div> <div class="cm-field cm-field--full"><label class="cm-label" for="cm-reset-email">Email</label><input class="cm-input" type="email" name="email" id="cm-reset-email" required></div>
<button type="submit" class="cm-btn-primary" hx-disabled-elt="this" style="width:100%; justify-content:center;">Send reset link</button> <button type="submit" class="cm-btn-primary" hx-disabled-elt="this" style="width:100%; justify-content:center;">Send reset link</button>
</form> </form>
<a class="cm-btn-ghost cm-btn-sm" href="/login" style="align-self: flex-start;">::lucide:arrow-left:sm::Back to sign in</a> <a class="cm-btn-ghost cm-btn-sm" href="/login" style="align-self: flex-start;"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#arrow-left"/></svg>Back to sign in</a>
</div> </div>

View File

@ -7,7 +7,7 @@
{% if tier.name %}<h3 class="cm-feature-title" style="margin: 0;">{{ tier.name }}</h3>{% endif %} {% if tier.name %}<h3 class="cm-feature-title" style="margin: 0;">{{ tier.name }}</h3>{% endif %}
<p style="display: flex; align-items: baseline; gap: 0.25rem; margin: 1rem 0 0 0;"><span class="cm-price numeric-tabular" style="font-family: var(--font-mono, ui-monospace, monospace); font-size: clamp(2rem, 4vw, 2.75rem); font-weight: 500; line-height: 1; color: hsl(var(--foreground));">{% if currency %}{{ currency }}{% else %}${% endif %}{{ tier.price }}</span>{% if tier.period %}<span class="cm-price-period cm-stat-label" style="margin-top: 0;">{{ tier.period }}</span>{% endif %}</p> <p style="display: flex; align-items: baseline; gap: 0.25rem; margin: 1rem 0 0 0;"><span class="cm-price numeric-tabular" style="font-family: var(--font-mono, ui-monospace, monospace); font-size: clamp(2rem, 4vw, 2.75rem); font-weight: 500; line-height: 1; color: hsl(var(--foreground));">{% if currency %}{{ currency }}{% else %}${% endif %}{{ tier.price }}</span>{% if tier.period %}<span class="cm-price-period cm-stat-label" style="margin-top: 0;">{{ tier.period }}</span>{% endif %}</p>
{% if tier.description %}<p class="cm-text" style="font-size: 0.9375rem; color: hsl(var(--muted-foreground)); margin-top: 0.75rem;">{{ tier.description }}</p>{% endif %} {% if tier.description %}<p class="cm-text" style="font-size: 0.9375rem; color: hsl(var(--muted-foreground)); margin-top: 0.75rem;">{{ tier.description }}</p>{% endif %}
{% if tier.features %}<ul class="cm-stack-sm" style="list-style: none; padding: 0; margin: 1.5rem 0 0 0; display: flex; flex-direction: column; gap: 0.625rem; flex: 1;">{% for feature in tier.features %}<li class="cm-check" style="display: flex; gap: 0.5rem; align-items: flex-start; font-size: 0.9375rem; color: hsl(var(--foreground));"><span style="color: hsl(var(--accent)); flex: none;">::lucide:check:sm::</span><span>{{ feature }}</span></li>{% endfor %}</ul>{% endif %} {% if tier.features %}<ul class="cm-stack-sm" style="list-style: none; padding: 0; margin: 1.5rem 0 0 0; display: flex; flex-direction: column; gap: 0.625rem; flex: 1;">{% for feature in tier.features %}<li class="cm-check" style="display: flex; gap: 0.5rem; align-items: flex-start; font-size: 0.9375rem; color: hsl(var(--foreground));"><span style="color: hsl(var(--accent)); flex: none;"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#check"/></svg></span><span>{{ feature }}</span></li>{% endfor %}</ul>{% endif %}
{% if tier.ctaUrl and tier.ctaLabel %}{% if tier.highlighted %}<a class="cm-btn-primary" href="{{ tier.ctaUrl }}" style="margin-top: 1.5rem; width: 100%; box-sizing: border-box; text-align: center;">{{ tier.ctaLabel }}</a>{% else %}<a class="cm-btn-outline" href="{{ tier.ctaUrl }}" style="margin-top: 1.5rem; width: 100%; box-sizing: border-box; text-align: center;">{{ tier.ctaLabel }}</a>{% endif %}{% endif %} {% if tier.ctaUrl and tier.ctaLabel %}{% if tier.highlighted %}<a class="cm-btn-primary" href="{{ tier.ctaUrl }}" style="margin-top: 1.5rem; width: 100%; box-sizing: border-box; text-align: center;">{{ tier.ctaLabel }}</a>{% else %}<a class="cm-btn-outline" href="{{ tier.ctaUrl }}" style="margin-top: 1.5rem; width: 100%; box-sizing: border-box; text-align: center;">{{ tier.ctaLabel }}</a>{% endif %}{% endif %}
</div>{% endfor %}</div>{% endif %} </div>{% endfor %}</div>{% endif %}
{% if billingNote %}<p class="cm-stat-label" style="text-align: center; margin-top: 2rem;">{{ billingNote }}</p>{% endif %} {% if billingNote %}<p class="cm-stat-label" style="text-align: center; margin-top: 2rem;">{{ billingNote }}</p>{% endif %}

View File

@ -4,7 +4,7 @@
{% if eyebrow %}<p class="cm-eyebrow">{{ eyebrow }}</p>{% endif %} {% if eyebrow %}<p class="cm-eyebrow">{{ eyebrow }}</p>{% endif %}
{% if heading %}<h2 class="cm-heading" style="font-size: clamp(1.75rem, 3vw, 2.25rem); margin: 0 0 1rem 0;"><span class="cm-heading-h2-accent">{{ heading }}</span></h2>{% endif %} {% if heading %}<h2 class="cm-heading" style="font-size: clamp(1.75rem, 3vw, 2.25rem); margin: 0 0 1rem 0;"><span class="cm-heading-h2-accent">{{ heading }}</span></h2>{% endif %}
{% if body %}<div class="cm-text" style="color: hsl(var(--muted-foreground)); line-height: 1.7;">{{ body|safe }}</div>{% endif %} {% if body %}<div class="cm-text" style="color: hsl(var(--muted-foreground)); line-height: 1.7;">{{ body|safe }}</div>{% endif %}
{% if ctaUrl and ctaLabel %}<a class="cm-btn-ghost" href="{{ ctaUrl }}" style="margin-top: 1.5rem;">{{ ctaLabel }}::lucide:arrow-right:sm::</a>{% endif %} {% if ctaUrl and ctaLabel %}<a class="cm-btn-ghost" href="{{ ctaUrl }}" style="margin-top: 1.5rem;">{{ ctaLabel }}<svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"/></svg></a>{% endif %}
</div> </div>
<div class="cm-media-frame" style="aspect-ratio: 4 / 3; background: hsl(var(--muted)); border: 1px solid hsl(var(--border)); overflow: hidden; {% if mediaPosition == "left" %}order: -1;{% endif %}">{% if media %}{% img media alt=mediaAlt class="cm-rich-media" %}{% endif %}</div> <div class="cm-media-frame" style="aspect-ratio: 4 / 3; background: hsl(var(--muted)); border: 1px solid hsl(var(--border)); overflow: hidden; {% if mediaPosition == "left" %}order: -1;{% endif %}">{% if media %}{% img media alt=mediaAlt class="cm-rich-media" %}{% endif %}</div>
</div></div></section> </div></div></section>

View File

@ -1,3 +1,3 @@
<nav class="{{ class }}" data-block="corporate-modernist:sidebar-nav" style="{% if showBorder %}border-right: 1px solid hsl(var(--border)); padding-right: 1rem;{% endif %}">{% if title %}<h3 class="cm-kicker" style="margin-top: 0;">{{ title }}</h3>{% endif %}<ul class="cm-stack-sm" style="list-style: none; margin: 0; padding: 0;">{% for item in menu.items %}<li><a class="cm-sidebar-link" 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>{% if item.icon %}<svg class="cm-icon" aria-hidden="true"><use href="/icons/{{ item.icon|split:":"|first }}.svg#{{ item.icon|split:":"|last }}"/></svg>{% endif %}{{ item.label }}</a></li>{% endfor %}</ul>{% if highlightCurrent %}<script> <nav class="{{ class }}" data-block="corporate-modernist:sidebar-nav" style="{% if showBorder %}border-right: 1px solid hsl(var(--border)); padding-right: 1rem;{% endif %}">{% if title %}<h3 class="cm-kicker" style="margin-top: 0;">{{ title }}</h3>{% endif %}<ul class="cm-stack-sm" style="list-style: none; margin: 0; padding: 0;">{% for item in menu.items %}<li><a class="cm-sidebar-link" 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>{% if item.icon %}<svg class="cm-icon" width="16" height="16" aria-hidden="true"><use href="/icons/{{ item.icon|split:":"|first }}.svg#{{ item.icon|split:":"|last }}"/></svg>{% endif %}{{ item.label }}</a></li>{% endfor %}</ul>{% if highlightCurrent %}<script>
(function(){var p=window.location.pathname;document.querySelectorAll('[data-bn-sidebar-link]').forEach(function(a){if(a.getAttribute('href')===p){a.setAttribute('aria-current','page');}});})(); (function(){var p=window.location.pathname;document.querySelectorAll('[data-bn-sidebar-link]').forEach(function(a){if(a.getAttribute('href')===p){a.setAttribute('aria-current','page');}});})();
</script>{% endif %}</nav> </script>{% endif %}</nav>

View File

@ -2,7 +2,7 @@
<section class="cm-section {{ class }}"><div class="cm-content-well"> <section class="cm-section {{ class }}"><div class="cm-content-well">
{% if heading %}<h2 class="cm-heading" style="font-size: clamp(1.75rem, 3vw, 2.25rem); margin: 0 0 2.5rem 0;"><span class="cm-heading-h2-accent">{{ heading }}</span></h2>{% endif %} {% if heading %}<h2 class="cm-heading" style="font-size: clamp(1.75rem, 3vw, 2.25rem); margin: 0 0 2.5rem 0;"><span class="cm-heading-h2-accent">{{ heading }}</span></h2>{% endif %}
<div class="{% if layout == "single" %}cm-measure{% else %}cm-grid cm-grid-3{% endif %}">{% for q in quotes %}<figure class="cm-quote-block cm-card" style="margin: 0; display: flex; flex-direction: column;"> <div class="{% if layout == "single" %}cm-measure{% else %}cm-grid cm-grid-3{% endif %}">{% for q in quotes %}<figure class="cm-quote-block cm-card" style="margin: 0; display: flex; flex-direction: column;">
{% if q.rating %}<div class="cm-rating" aria-label="Rated {{ q.rating }} out of 5" style="display: flex; gap: 0.125rem; margin-bottom: 0.75rem;"><span style="color: {% if q.rating >= 1 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};">::lucide:star:sm::</span><span style="color: {% if q.rating >= 2 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};">::lucide:star:sm::</span><span style="color: {% if q.rating >= 3 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};">::lucide:star:sm::</span><span style="color: {% if q.rating >= 4 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};">::lucide:star:sm::</span><span style="color: {% if q.rating >= 5 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};">::lucide:star:sm::</span></div>{% endif %} {% if q.rating %}<div class="cm-rating" aria-label="Rated {{ q.rating }} out of 5" style="display: flex; gap: 0.125rem; margin-bottom: 0.75rem;"><span style="color: {% if q.rating >= 1 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#star"/></svg></span><span style="color: {% if q.rating >= 2 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#star"/></svg></span><span style="color: {% if q.rating >= 3 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#star"/></svg></span><span style="color: {% if q.rating >= 4 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#star"/></svg></span><span style="color: {% if q.rating >= 5 %}hsl(var(--accent)){% else %}hsl(var(--muted-foreground) / 0.35){% endif %};"><svg class="inline-block h-4 w-4" width="16" height="16" aria-hidden="true"><use href="/icons/lucide.svg#star"/></svg></span></div>{% endif %}
{% if q.quote %}<blockquote class="cm-pull-quote" style="flex: 1; margin: 0;">{{ q.quote }}</blockquote>{% endif %} {% if q.quote %}<blockquote class="cm-pull-quote" style="flex: 1; margin: 0;">{{ q.quote }}</blockquote>{% endif %}
<figcaption class="cm-quote-cite" style="display: flex; align-items: center; gap: 0.75rem; margin-top: 1.25rem;">{% if q.avatar %}<span class="cm-avatar" style="width: 2.75rem; height: 2.75rem; border-radius: 9999px; overflow: hidden; background: hsl(var(--muted)); display: inline-flex; flex: none;">{% img q.avatar alt=q.name class="cm-avatar-img" %}</span>{% endif %}<span>{% if q.name %}<span class="cm-feature-title" style="display: block; font-size: 0.9375rem;">{{ q.name }}</span>{% endif %}{% if q.role %}<span class="cm-stat-label" style="margin-top: 0;">{{ q.role }}</span>{% endif %}</span></figcaption> <figcaption class="cm-quote-cite" style="display: flex; align-items: center; gap: 0.75rem; margin-top: 1.25rem;">{% if q.avatar %}<span class="cm-avatar" style="width: 2.75rem; height: 2.75rem; border-radius: 9999px; overflow: hidden; background: hsl(var(--muted)); display: inline-flex; flex: none;">{% img q.avatar alt=q.name class="cm-avatar-img" %}</span>{% endif %}<span>{% if q.name %}<span class="cm-feature-title" style="display: block; font-size: 0.9375rem;">{{ q.name }}</span>{% endif %}{% if q.role %}<span class="cm-stat-label" style="margin-top: 0;">{{ q.role }}</span>{% endif %}</span></figcaption>
</figure>{% endfor %}</div> </figure>{% endfor %}</div>

View File

@ -4,7 +4,7 @@
<div class="cm-video-frame" data-bn-video data-video-url="{{ url|default:'' }}" data-video-media="{% if media %}{{ media|mediaURL }}{% endif %}" style="position:relative;width:100%;overflow:hidden;border:1px solid hsl(var(--border));border-radius:4px;background:hsl(var(--muted));aspect-ratio:{{ vratio }};"> <div class="cm-video-frame" data-bn-video data-video-url="{{ url|default:'' }}" data-video-media="{% if media %}{{ media|mediaURL }}{% endif %}" style="position:relative;width:100%;overflow:hidden;border:1px solid hsl(var(--border));border-radius:4px;background:hsl(var(--muted));aspect-ratio:{{ vratio }};">
<button type="button" data-bn-video-play class="cm-video-play" aria-label="Play video{% if title %}: {{ title }}{% endif %}" style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;width:100%;height:100%;border:0;background:none;cursor:pointer;"> <button type="button" data-bn-video-play class="cm-video-play" aria-label="Play video{% if title %}: {{ title }}{% endif %}" style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;width:100%;height:100%;border:0;background:none;cursor:pointer;">
{% if poster %}{% img poster alt=title|default:"" class="cm-video-poster" %}{% endif %} {% if poster %}{% img poster alt=title|default:"" class="cm-video-poster" %}{% endif %}
<span class="cm-video-play-badge" style="position:relative;display:inline-flex;align-items:center;justify-content:center;width:4rem;height:4rem;border-radius:4px;background:hsl(var(--accent));color:hsl(var(--accent-foreground));">::lucide:play:lg::</span> <span class="cm-video-play-badge" style="position:relative;display:inline-flex;align-items:center;justify-content:center;width:4rem;height:4rem;border-radius:4px;background:hsl(var(--accent));color:hsl(var(--accent-foreground));"><svg class="inline-block h-6 w-6" width="24" height="24" aria-hidden="true"><use href="/icons/lucide.svg#play"/></svg></span>
</button> </button>
</div> </div>
{% if caption %}<figcaption class="cm-stat-label" style="margin-top:0.5rem;text-align:center;">{{ caption }}</figcaption>{% endif %} {% if caption %}<figcaption class="cm-stat-label" style="margin-top:0.5rem;text-align:center;">{{ caption }}</figcaption>{% endif %}