fix(cyberpunk): repair blank-hero .text bug + move responsive layout to Tailwind

Hero blank-hero bug: eyebrow/headline/subheadline/description read
field.text|default:field, which hard-errors in the ninjatpl engine on
bare-string seed values (attribute access on a string), blanking the whole
hero. Switch to field|get:"text"|default:field — the process-global `get`
filter degrades gracefully on both {text,...} objects and bare strings.

Responsive layout back to Tailwind (supersedes the prior CSS-class approach
in 6787a01): the host Tailwind build now scans theme .ninjatpl, so the
cp-grid / cp-cols / cp-span / cp-split / cp-article-grid classes were exact
reimplementations of stock utilities. Restore plain Tailwind in the
templates (grid grid-cols-1 sm:/md:/lg:grid-cols-*, gap-*, columns-*,
col-span-*, before:* timeline connector) across feature-grid, pricing,
stats, team, testimonial, contact-card, featured/related-posts, blog-hero,
menu-list, event-list, hours-location, timeline, footer, gallery,
rich-section, roster_grid, article + hero split section, and delete the
duplicate CSS from manifest css.input_css_append.

Kept as genuinely bespoke design CSS: cp-hero-* bounded clamp() min-heights
(the anti-balloon whitespace fix — not a stock min-h-* utility; restoring
min-h-screen would reintroduce the empty neon void) and the reduced-motion /
high-contrast blocks.

Scroll-reveal: cyberpunk ships no opacity-hidden .reveal content — its two
IntersectionObservers (hero digital-rain, stats countUp) fire on the IO
initial callback when already in view and both have static, visible no-JS /
reduced-motion fallbacks, so content is never hidden behind JS.

make (codeless .bnp) OK; check-safety 32 checks 19 ok 13 skip -> OK.
No version bump. No push.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Alex Dunmow 2026-07-05 17:58:34 +08:00
parent 6787a01515
commit 5221b310ff
20 changed files with 32 additions and 90 deletions

View File

@ -4,7 +4,7 @@
{% if eyebrow %}<p class="cyberpunk-eyebrow text-center">{{ eyebrow }}</p>{% endif %} {% if eyebrow %}<p class="cyberpunk-eyebrow text-center">{{ eyebrow }}</p>{% endif %}
{% if heading %}<h2 class="cyberpunk-display glitch mt-2 text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch mt-2 text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
{% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %} {% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %}
<div class="mt-12 cp-grid cp-s2 cp-lg3"> <div class="mt-12 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{% for member in members %} {% for member in members %}
<div class="hud-frame flex items-center gap-4 rounded-md border border-primary/40 bg-card p-5 text-card-foreground neon-edge-magenta"> <div class="hud-frame flex items-center gap-4 rounded-md border border-primary/40 bg-card p-5 text-card-foreground neon-edge-magenta">
{% if member.avatar %}<span class="clip-cut h-14 w-14 shrink-0 overflow-hidden rounded-md border border-primary/40 bg-muted">{% img member.avatar alt=member.name class="h-full w-full object-cover" %}</span>{% else %}<span class="clip-cut flex h-14 w-14 shrink-0 items-center justify-center rounded-md border border-primary/40 bg-primary/10 text-primary"><svg class="h-6 w-6" aria-hidden="true"><use href="/icons/lucide.svg#user"></use></svg></span>{% endif %} {% if member.avatar %}<span class="clip-cut h-14 w-14 shrink-0 overflow-hidden rounded-md border border-primary/40 bg-muted">{% img member.avatar alt=member.name class="h-full w-full object-cover" %}</span>{% else %}<span class="clip-cut flex h-14 w-14 shrink-0 items-center justify-center rounded-md border border-primary/40 bg-primary/10 text-primary"><svg class="h-6 w-6" aria-hidden="true"><use href="/icons/lucide.svg#user"></use></svg></span>{% endif %}

View File

@ -351,77 +351,19 @@ css:
linear-gradient(to bottom, transparent, hsl(var(--background) / 0.6)); linear-gradient(to bottom, transparent, hsl(var(--background) / 0.6));
} }
/* --- Responsive layout utilities (theme-owned, media-query driven) ---- */ /* --- Hero heights (bespoke bounded clamp — anti-balloon) -------------- */
/* The host Tailwind build does NOT reliably compile responsive utility /* Responsive grids/columns/spans/splits are plain Tailwind utilities in the
variants (sm:/md:/lg:grid-cols-*, min-h-screen, arbitrary values) that templates (grid-cols-*, columns-*, col-span-*, gap-*) — the host build
appear only in this theme's templates, so multi-column grids collapse scans theme .ninjatpl, so no CSS reimplementation of those.
to a single column at every width and heroes lose their min-height. These hero min-heights stay CSS: a bespoke clamp() that caps a sparse
Drive the load-bearing responsive layout from explicit CSS instead. hero so it never balloons into an empty neon void while a populated hero
Layout only — no colour literals (colours stay on semantic tokens). */ still reads full-bleed — not a stock min-h-* utility. */
.cp-grid { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1fr); }
.cp-grid.cp-g-none { gap: 0; }
.cp-grid.cp-g-tight { gap: 1rem; }
.cp-grid.cp-g-wide { gap: 2rem; }
.cp-grid.cp-g-xl { gap: 2.5rem; }
.cp-grid.cp-m2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 640px) {
.cp-grid.cp-s2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 768px) {
.cp-grid.cp-md2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cp-grid.cp-md3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cp-grid.cp-md4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
.cp-grid.cp-lg2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cp-grid.cp-lg3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cp-grid.cp-lg4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cp-grid.cp-lg5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
.cp-span2 { grid-column: span 2; }
@media (min-width: 1024px) { .cp-lg-span1 { grid-column: span 1; } }
/* Masonry column-count (gallery) with the same reliability guarantee. */
.cp-cols { column-gap: 1rem; }
.cp-cols.cp-c2 { columns: 2; }
@media (min-width: 768px) {
.cp-cols.cp-md-c2 { columns: 2; }
.cp-cols.cp-md-c3 { columns: 3; }
.cp-cols.cp-md-c4 { columns: 4; }
}
/* Two-column content split (rich-section, hours-location) + article aside. */
.cp-split { display: grid; gap: 2.5rem; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 768px) {
.cp-split.cp-split-md { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4rem; }
}
.cp-article-grid { display: grid; gap: 2.5rem; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1024px) {
.cp-article-grid { grid-template-columns: minmax(0, 1fr) 260px; }
}
/* --- Hero heights (bounded; host drops min-h-screen / arbitrary vh) ---- */
/* Capped so a sparse hero never balloons into an empty neon void, while a
populated hero still reads full-bleed. */
.cp-hero-tall { min-height: clamp(32rem, 82vh, 50rem); } .cp-hero-tall { min-height: clamp(32rem, 82vh, 50rem); }
.cp-hero-mid { min-height: clamp(28rem, 70vh, 44rem); } .cp-hero-mid { min-height: clamp(28rem, 70vh, 44rem); }
.cp-hero-short { min-height: clamp(20rem, 50vh, 30rem); } .cp-hero-short { min-height: clamp(20rem, 50vh, 30rem); }
.cp-hero-auto { min-height: 22rem; } .cp-hero-auto { min-height: 22rem; }
.cp-hero-split { min-height: clamp(20rem, 46vh, 28rem); } .cp-hero-split { min-height: clamp(20rem, 46vh, 28rem); }
/* Vertical-timeline connector line (arbitrary before:* utilities dropped). */
.cp-timeline { position: relative; }
.cp-timeline::before {
content: "";
position: absolute;
left: 1rem;
top: 0.5rem;
width: 1px;
height: calc(100% - 1rem);
background: hsl(var(--primary) / 0.5);
}
/* --- Reduced motion: kill all motion --------------------- */ /* --- Reduced motion: kill all motion --------------------- */
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {

View File

@ -5,7 +5,7 @@
{{ admin_banner_html|safe }} {{ admin_banner_html|safe }}
<div aria-hidden="true" class="scanlines pointer-events-none fixed inset-0 z-50" data-cyberpunk-scanlines></div> <div aria-hidden="true" class="scanlines pointer-events-none fixed inset-0 z-50" data-cyberpunk-scanlines></div>
<header class="cyberpunk-chrome w-full sticky top-0 z-40" style="background-color: hsl(var(--background) / 0.85); border-bottom: 1px solid hsl(var(--border));">{{ slots.header|safe }}</header> <header class="cyberpunk-chrome w-full sticky top-0 z-40" style="background-color: hsl(var(--background) / 0.85); border-bottom: 1px solid hsl(var(--border));">{{ slots.header|safe }}</header>
<main class="flex-grow w-full max-w-5xl mx-auto px-4 py-12{% if slots.aside %} cp-article-grid{% endif %}"> <main class="flex-grow w-full max-w-5xl mx-auto px-4 py-12{% if slots.aside %} grid gap-10 lg:grid-cols-[1fr_260px]{% endif %}">
<article class="cyberpunk-prose prose prose-invert max-w-none min-w-0">{{ slots.main|safe }}</article> <article class="cyberpunk-prose prose prose-invert max-w-none min-w-0">{{ slots.main|safe }}</article>
{% if slots.aside %}<aside class="cyberpunk-aside cyberpunk-mono hud-frame rounded-md border border-primary/30 p-5 text-sm h-max" style="color: hsl(var(--muted-foreground)); background-color: hsl(var(--card));">{{ slots.aside|safe }}</aside>{% endif %} {% if slots.aside %}<aside class="cyberpunk-aside cyberpunk-mono hud-frame rounded-md border border-primary/30 p-5 text-sm h-max" style="color: hsl(var(--muted-foreground)); background-color: hsl(var(--card));">{{ slots.aside|safe }}</aside>{% endif %}
</main> </main>

View File

@ -7,7 +7,7 @@
{% if subtitle %}<p class="cyberpunk-body mt-3 text-lg text-muted-foreground">{{ subtitle }}</p>{% endif %} {% if subtitle %}<p class="cyberpunk-body mt-3 text-lg text-muted-foreground">{{ subtitle }}</p>{% endif %}
</div> </div>
{% if posts %} {% if posts %}
<div class="mt-10 cp-grid cp-md3"> <div class="mt-10 grid grid-cols-1 gap-6 md:grid-cols-3">
{% for post in posts %} {% for post in posts %}
<article class="hud-frame group flex flex-col rounded-md border border-dashed border-primary/40 bg-card p-4 text-card-foreground neon-edge-magenta{% if forloop.First %} md:col-span-3 md:flex-row md:items-stretch md:gap-6{% endif %}"> <article class="hud-frame group flex flex-col rounded-md border border-dashed border-primary/40 bg-card p-4 text-card-foreground neon-edge-magenta{% if forloop.First %} md:col-span-3 md:flex-row md:items-stretch md:gap-6{% endif %}">
{% if post.featured_image_url %}<a href="{{ post.url }}" class="mb-3 block overflow-hidden rounded-md bg-muted{% if forloop.First %} md:mb-0 md:w-1/2{% endif %}">{% img post.featured_image_url alt=post.title class="aspect-video h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" %}</a>{% endif %} {% if post.featured_image_url %}<a href="{{ post.url }}" class="mb-3 block overflow-hidden rounded-md bg-muted{% if forloop.First %} md:mb-0 md:w-1/2{% endif %}">{% img post.featured_image_url alt=post.title class="aspect-video h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" %}</a>{% endif %}

View File

@ -3,7 +3,7 @@
<div class="mx-auto max-w-4xl px-4"> <div class="mx-auto max-w-4xl px-4">
{% if heading %}<h2 class="cyberpunk-display glitch text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
{% if description %}<p class="mt-3 max-w-2xl text-lg text-muted-foreground">{{ description }}</p>{% endif %} {% if description %}<p class="mt-3 max-w-2xl text-lg text-muted-foreground">{{ description }}</p>{% endif %}
<div class="mt-10 cp-grid cp-g-tight {% if columns == 3 %}cp-s2 cp-lg3{% elif columns == 1 %}{% else %}cp-s2{% endif %}"> <div class="mt-10 grid grid-cols-1 gap-4 {% 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="hud-frame flex items-start gap-4 rounded-md border border-primary/40 bg-card p-5 text-card-foreground neon-edge-magenta"> <div class="hud-frame flex items-start gap-4 rounded-md border border-primary/40 bg-card p-5 text-card-foreground neon-edge-magenta">
{% if channel.icon %}<span class="clip-cut inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-primary/10 text-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="clip-cut inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-primary/10 text-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 %}

View File

@ -4,7 +4,7 @@
{% if heading %}<h2 class="cyberpunk-display glitch text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
{% if intro %}<p class="mt-3 max-w-2xl text-lg text-muted-foreground">{{ intro }}</p>{% endif %} {% if intro %}<p class="mt-3 max-w-2xl text-lg text-muted-foreground">{{ intro }}</p>{% endif %}
{% if layout == "cards" %} {% if layout == "cards" %}
<div class="mt-10 cp-grid cp-s2 cp-lg3"> <div class="mt-10 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{% for event in events %}{% if not (hidePast and event.past) %} {% for event in events %}{% if not (hidePast and event.past) %}
<article class="hud-frame flex flex-col overflow-hidden rounded-md border border-primary/40 bg-card text-card-foreground neon-edge-magenta{% if event.past %} opacity-60{% endif %}"> <article class="hud-frame flex flex-col overflow-hidden rounded-md border border-primary/40 bg-card text-card-foreground neon-edge-magenta{% if event.past %} opacity-60{% endif %}">
{% if event.media %}<div class="aspect-video overflow-hidden bg-muted">{% img event.media alt=event.title class="h-full w-full object-cover" %}</div>{% endif %} {% if event.media %}<div class="aspect-video overflow-hidden bg-muted">{% img event.media alt=event.title class="h-full w-full object-cover" %}</div>{% endif %}

View File

@ -5,7 +5,7 @@
{% if eyebrow %}<p class="cyberpunk-mono text-center text-xs font-semibold uppercase tracking-widest text-accent">{{ eyebrow }}</p>{% endif %} {% if eyebrow %}<p class="cyberpunk-mono text-center text-xs font-semibold uppercase tracking-widest text-accent">{{ eyebrow }}</p>{% endif %}
{% if heading %}<h2 class="cyberpunk-display glitch mt-2 text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch mt-2 text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
{% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %} {% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %}
<div class="mt-12 cp-grid cp-s2 {% if columns == 2 %}cp-lg2{% elif columns == 4 %}cp-lg4{% else %}cp-lg3{% 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" %}hud-frame rounded-md border border-primary/40 bg-card p-6 text-card-foreground neon-edge-magenta transition-transform hover:-translate-y-0.5{% elif layout == "centered" %}text-center{% endif %}"> <div class="{% if layout == "card" %}hud-frame rounded-md border border-primary/40 bg-card p-6 text-card-foreground neon-edge-magenta transition-transform hover:-translate-y-0.5{% elif layout == "centered" %}text-center{% endif %}">
{% if item.icon %}<div class="clip-cut mb-4 inline-flex h-11 w-11 items-center justify-center rounded-md 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="clip-cut mb-4 inline-flex h-11 w-11 items-center justify-center rounded-md 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 %}

View File

@ -3,7 +3,7 @@
<section class="py-12 md:py-16 bg-background text-foreground{% if class %} {{ class }}{% endif %}"> <section class="py-12 md:py-16 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
<div class="mx-auto max-w-6xl px-4"> <div class="mx-auto max-w-6xl px-4">
{% if heading %}<h2 class="cyberpunk-display glitch mb-8 text-2xl font-semibold tracking-tight md:text-3xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch mb-8 text-2xl font-semibold tracking-tight md:text-3xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
<div class="cp-grid cp-s2 {% if columns == 2 %}cp-lg2{% elif columns == 4 %}cp-lg4{% else %}cp-lg3{% endif %}"> <div class="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 post in posts %} {% for post in posts %}
<article class="hud-frame group flex flex-col overflow-hidden rounded-md border border-dashed border-primary/40 bg-card text-card-foreground neon-edge-magenta transition-transform hover:-translate-y-0.5"> <article class="hud-frame group flex flex-col overflow-hidden rounded-md border border-dashed border-primary/40 bg-card text-card-foreground neon-edge-magenta transition-transform hover:-translate-y-0.5">
{% if showFeaturedImage and post.featured_image_url %}<a href="{{ post.url }}" class="block aspect-video overflow-hidden bg-muted">{% img post.featured_image_url alt=post.title class="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" %}</a>{% endif %} {% if showFeaturedImage and post.featured_image_url %}<a href="{{ post.url }}" class="block aspect-video overflow-hidden bg-muted">{% img post.featured_image_url alt=post.title class="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" %}</a>{% endif %}

View File

@ -23,15 +23,15 @@
</div> </div>
{{ legalbar() }} {{ legalbar() }}
{% else %} {% else %}
<div class="cp-grid cp-g-wide cp-m2 cp-md4 cp-lg5"> <div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-8">
<div class="cp-span2"> <div class="col-span-2 lg:col-span-2">
{% if logo %}<img src="{{ logo }}" alt="{{ companyName }}" class="h-9 w-auto"/>{% elif companyName %}<span class="cyberpunk-display text-xl font-bold text-foreground">{{ companyName }}</span>{% endif %} {% if logo %}<img src="{{ logo }}" alt="{{ companyName }}" class="h-9 w-auto"/>{% elif companyName %}<span class="cyberpunk-display text-xl font-bold text-foreground">{{ companyName }}</span>{% endif %}
{% if tagline %}<p class="mt-3 max-w-xs text-sm text-muted-foreground">{{ tagline }}</p>{% endif %} {% if tagline %}<p class="mt-3 max-w-xs text-sm text-muted-foreground">{{ tagline }}</p>{% endif %}
{% if address or email or phone %}<address class="mt-4 not-italic text-sm text-muted-foreground space-y-1">{% if address %}<div>{{ address }}</div>{% endif %}{% if email %}<div><a href="mailto:{{ email }}" class="hover:text-primary transition-colors">{{ email }}</a></div>{% endif %}{% if phone %}<div><a href="tel:{{ phone }}" class="hover:text-primary transition-colors">{{ phone }}</a></div>{% endif %}</address>{% endif %} {% if address or email or phone %}<address class="mt-4 not-italic text-sm text-muted-foreground space-y-1">{% if address %}<div>{{ address }}</div>{% endif %}{% if email %}<div><a href="mailto:{{ email }}" class="hover:text-primary transition-colors">{{ email }}</a></div>{% endif %}{% if phone %}<div><a href="tel:{{ phone }}" class="hover:text-primary transition-colors">{{ phone }}</a></div>{% endif %}</address>{% endif %}
{{ sociallinks("mt-5") }} {{ sociallinks("mt-5") }}
</div> </div>
{% for col in columns %}<div><h3 class="cyberpunk-mono uppercase tracking-widest text-xs font-semibold text-accent">{{ col.header }}</h3><ul class="mt-3 space-y-2">{% for item in col.items %}<li><a href="{{ item.url|default:'#' }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="text-sm text-muted-foreground hover:text-primary transition-colors">{{ item.label }}</a></li>{% endfor %}</ul></div>{% endfor %} {% for col in columns %}<div><h3 class="cyberpunk-mono uppercase tracking-widest text-xs font-semibold text-accent">{{ col.header }}</h3><ul class="mt-3 space-y-2">{% for item in col.items %}<li><a href="{{ item.url|default:'#' }}"{% if item.open_in_new_tab %} target="_blank" rel="noopener"{% endif %} class="text-sm text-muted-foreground hover:text-primary transition-colors">{{ item.label }}</a></li>{% endfor %}</ul></div>{% endfor %}
{% if showNewsletter %}<div class="cp-span2 cp-lg-span1">{{ newsletter() }}</div>{% endif %} {% if showNewsletter %}<div class="col-span-2 lg:col-span-1">{{ newsletter() }}</div>{% endif %}
</div> </div>
{{ legalbar() }} {{ legalbar() }}
{% endif %} {% endif %}

View File

@ -1,5 +1,5 @@
{# gallery cyberpunk override: neon-edged tiles. Lightbox script + data-bn-* attributes + {% img %} preserved byte-for-byte. #} {# gallery cyberpunk override: neon-edged tiles. Lightbox script + data-bn-* attributes + {% img %} preserved byte-for-byte. #}
{% with layout=layout|default:"grid" gap=gap|default:"md" cols=columns|default:3 %}<div class="bn-gallery my-6{% if class %} {{ class }}{% endif %}" data-bn-gallery data-lightbox="{% if lightbox %}true{% else %}false{% endif %}"><div class="{% if layout == "carousel" %}flex snap-x snap-mandatory overflow-x-auto pb-2 {% if gap == "sm" %}gap-2{% elif gap == "lg" %}gap-6{% else %}gap-4{% endif %}{% elif layout == "masonry" %}cp-cols cp-c2 {% if cols == 4 %}cp-md-c4{% elif cols == 2 %}cp-md-c2{% else %}cp-md-c3{% endif %} {% if gap == "sm" %}gap-2{% elif gap == "lg" %}gap-6{% else %}gap-4{% endif %}{% else %}cp-grid cp-m2 {% if cols == 4 %}cp-md4{% elif cols == 2 %}cp-md2{% else %}cp-md3{% endif %} {% if gap == "sm" %}cp-g-tight{% elif gap == "lg" %}{% else %}cp-g-tight{% endif %}{% endif %}">{% for image in images %}<a href="{{ image.src|mediaURL }}" data-bn-gallery-item data-caption="{{ image.caption|default:"" }}" class="group relative block overflow-hidden rounded-md border border-primary/30 bg-muted neon-edge-magenta focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 {% if layout == "carousel" %}w-64 shrink-0 snap-start sm:w-80{% elif layout == "masonry" %}mb-4 w-full break-inside-avoid{% endif %}">{% if layout == "grid" %}{% img image.src alt=image.alt|default:"" class="aspect-square w-full object-cover" %}{% else %}{% img image.src alt=image.alt|default:"" class="h-auto w-full" %}{% endif %}{% if image.caption %}<span class="sr-only">{{ image.caption }}</span>{% endif %}</a>{% endfor %}</div></div>{% if lightbox %}<script> {% with layout=layout|default:"grid" gap=gap|default:"md" cols=columns|default:3 %}<div class="bn-gallery my-6{% if class %} {{ class }}{% endif %}" data-bn-gallery data-lightbox="{% if lightbox %}true{% else %}false{% endif %}"><div class="{% if layout == "carousel" %}flex snap-x snap-mandatory overflow-x-auto pb-2 {% if gap == "sm" %}gap-2{% elif gap == "lg" %}gap-6{% else %}gap-4{% endif %}{% elif layout == "masonry" %}columns-2 {% if cols == 4 %}md:columns-4{% elif cols == 2 %}md:columns-2{% else %}md:columns-3{% endif %} {% if gap == "sm" %}gap-2{% elif gap == "lg" %}gap-6{% else %}gap-4{% endif %}{% else %}grid grid-cols-2 {% if cols == 4 %}md:grid-cols-4{% elif cols == 2 %}md:grid-cols-2{% else %}md:grid-cols-3{% endif %} {% if gap == "sm" %}gap-2{% elif gap == "lg" %}gap-6{% else %}gap-4{% endif %}{% endif %}">{% for image in images %}<a href="{{ image.src|mediaURL }}" data-bn-gallery-item data-caption="{{ image.caption|default:"" }}" class="group relative block overflow-hidden rounded-md border border-primary/30 bg-muted neon-edge-magenta focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 {% if layout == "carousel" %}w-64 shrink-0 snap-start sm:w-80{% elif layout == "masonry" %}mb-4 w-full break-inside-avoid{% endif %}">{% if layout == "grid" %}{% img image.src alt=image.alt|default:"" class="aspect-square w-full object-cover" %}{% else %}{% img image.src alt=image.alt|default:"" class="h-auto w-full" %}{% endif %}{% if image.caption %}<span class="sr-only">{{ image.caption }}</span>{% endif %}</a>{% endfor %}</div></div>{% if lightbox %}<script>
(function(){ (function(){
if(window.__bnLightbox)return;window.__bnLightbox=true; if(window.__bnLightbox)return;window.__bnLightbox=true;
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches; var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;

View File

@ -1,8 +1,8 @@
{# hero cyberpunk override (GO-BIG showpiece): canvas digital-rain background, glitch headline, scanline overlay. All builtin field reads + macro + branch structure preserved. The rain shows when there is no backgroundImage; it lazy-inits on view, honors prefers-reduced-motion, degrades to a static neon gradient with JS off, and is dependency-free. #} {# hero cyberpunk override (GO-BIG showpiece): canvas digital-rain background, glitch headline, scanline overlay. All builtin field reads + macro + branch structure preserved. The rain shows when there is no backgroundImage; it lazy-inits on view, honors prefers-reduced-motion, degrades to a static neon gradient with JS off, and is dependency-free. #}
{% set eyebrowText = eyebrow.text|default:eyebrow %} {% set eyebrowText = eyebrow|get:"text"|default:eyebrow %}
{% set headlineText = headline.text|default:headline %} {% set headlineText = headline|get:"text"|default:headline %}
{% set subText = subheadline.text|default:subheadline %} {% set subText = subheadline|get:"text"|default:subheadline %}
{% set descText = description.text|default:description %} {% set descText = description|get:"text"|default:description %}
{% set pText = ctaPrimary.text %} {% set pText = ctaPrimary.text %}
{% set pUrl = ctaPrimary.url %} {% set pUrl = ctaPrimary.url %}
{% set sText = ctaSecondary.text %} {% set sText = ctaSecondary.text %}
@ -25,7 +25,7 @@
</div>{% endif %} </div>{% endif %}
{% endmacro %} {% endmacro %}
{% if variant == "split" %} {% if variant == "split" %}
<section class="hero cp-grid cp-g-none cp-lg2 overflow-hidden bg-background text-foreground{% if class %} {{ class }}{% endif %}"> <section class="hero grid grid-cols-1 lg:grid-cols-2 overflow-hidden bg-background text-foreground{% if class %} {{ class }}{% endif %}">
<div class="relative cp-hero-split bg-muted {% if mediaPosition == "left" %}order-1 lg:order-1{% else %}order-1 lg:order-2{% endif %}">{% if hasImage %}{% img backgroundImage alt=headlineText class="absolute inset-0 h-full w-full object-cover" layout="hero" %}{% else %}<div class="cyberpunk-rain-wrap"><div class="cyberpunk-rain-fallback"></div><canvas class="cyberpunk-rain-canvas" aria-hidden="true"></canvas></div>{% endif %}<div aria-hidden="true" class="scanlines pointer-events-none absolute inset-0"></div></div> <div class="relative cp-hero-split bg-muted {% if mediaPosition == "left" %}order-1 lg:order-1{% else %}order-1 lg:order-2{% endif %}">{% if hasImage %}{% img backgroundImage alt=headlineText class="absolute inset-0 h-full w-full object-cover" layout="hero" %}{% else %}<div class="cyberpunk-rain-wrap"><div class="cyberpunk-rain-fallback"></div><canvas class="cyberpunk-rain-canvas" aria-hidden="true"></canvas></div>{% endif %}<div aria-hidden="true" class="scanlines pointer-events-none absolute inset-0"></div></div>
<div class="flex flex-col justify-center px-6 py-16 lg:px-12 {% if mediaPosition == "left" %}order-2 lg:order-2{% else %}order-2 lg:order-1{% endif %}"><div class="max-w-lg text-left">{{ herocontent("left") }}</div></div> <div class="flex flex-col justify-center px-6 py-16 lg:px-12 {% if mediaPosition == "left" %}order-2 lg:order-2{% else %}order-2 lg:order-1{% endif %}"><div class="max-w-lg text-left">{{ herocontent("left") }}</div></div>
</section> </section>

View File

@ -2,7 +2,7 @@
<section class="py-16 md:py-24 bg-background text-foreground{% if class %} {{ class }}{% endif %}"> <section class="py-16 md:py-24 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
<div class="mx-auto max-w-5xl px-4"> <div class="mx-auto max-w-5xl px-4">
{% if heading %}<h2 class="cyberpunk-display glitch text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
<div class="mt-10 cp-grid cp-g-xl cp-md2"> <div class="mt-10 grid grid-cols-1 gap-10 md:grid-cols-2">
<div> <div>
{% if hours %} {% if hours %}
<table class="cyberpunk-mono w-full text-sm"> <table class="cyberpunk-mono w-full text-sm">

View File

@ -3,7 +3,7 @@
<div class="mx-auto max-w-5xl px-4"> <div class="mx-auto max-w-5xl px-4">
{% if heading %}<h2 class="cyberpunk-display glitch text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
{% if intro %}<p class="mt-3 max-w-2xl text-lg text-muted-foreground">{{ intro }}</p>{% endif %} {% if intro %}<p class="mt-3 max-w-2xl text-lg text-muted-foreground">{{ intro }}</p>{% endif %}
<div class="mt-10 cp-grid cp-g-xl {% if columns == 2 %}cp-md2{% endif %}"> <div class="mt-10 grid grid-cols-1 gap-x-12 gap-y-10 {% if columns == 2 %}md:grid-cols-2{% endif %}">
{% for section in sections %} {% for section in sections %}
<div class="menu-section"> <div class="menu-section">
{% if section.title %}<h3 class="cyberpunk-display border-b border-primary/40 pb-2 text-xl font-semibold">{{ section.title }}</h3>{% endif %} {% if section.title %}<h3 class="cyberpunk-display border-b border-primary/40 pb-2 text-xl font-semibold">{{ section.title }}</h3>{% endif %}

View File

@ -4,7 +4,7 @@
<div class="relative z-10 mx-auto max-w-6xl px-4"> <div class="relative z-10 mx-auto max-w-6xl px-4">
{% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
{% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %} {% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %}
<div class="mt-12 cp-grid cp-md2 cp-lg3"> <div class="mt-12 grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{% for tier in tiers %} {% for tier in tiers %}
<div class="hud-frame relative flex flex-col rounded-md border p-6 {% if tier.highlighted %}border-primary bg-card text-card-foreground neon-edge-magenta ring-1 ring-primary{% else %}border-primary/40 bg-card text-card-foreground neon-edge-cyan{% endif %}"> <div class="hud-frame relative flex flex-col rounded-md border p-6 {% if tier.highlighted %}border-primary bg-card text-card-foreground neon-edge-magenta ring-1 ring-primary{% else %}border-primary/40 bg-card text-card-foreground neon-edge-cyan{% endif %}">
{% if tier.badge %}<span class="cyberpunk-mono clip-cut absolute -top-3 left-1/2 -translate-x-1/2 rounded-none bg-primary px-3 py-1 text-xs font-semibold uppercase tracking-widest text-primary-foreground">{{ tier.badge }}</span>{% endif %} {% if tier.badge %}<span class="cyberpunk-mono clip-cut absolute -top-3 left-1/2 -translate-x-1/2 rounded-none bg-primary px-3 py-1 text-xs font-semibold uppercase tracking-widest text-primary-foreground">{{ tier.badge }}</span>{% endif %}

View File

@ -3,7 +3,7 @@
<section class="border-t border-primary/30 py-12 md:py-16 bg-background text-foreground{% if class %} {{ class }}{% endif %}"> <section class="border-t border-primary/30 py-12 md:py-16 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
<div class="mx-auto max-w-6xl px-4"> <div class="mx-auto max-w-6xl px-4">
<h2 class="cyberpunk-display glitch mb-8 text-2xl font-semibold tracking-tight" data-text="{{ heading|default:'Related posts' }}">{{ heading|default:"Related posts" }}</h2> <h2 class="cyberpunk-display glitch mb-8 text-2xl font-semibold tracking-tight" data-text="{{ heading|default:'Related posts' }}">{{ heading|default:"Related posts" }}</h2>
<div class="cp-grid cp-s2 {% if columns == 2 %}cp-lg2{% else %}cp-lg3{% endif %}"> <div class="grid grid-cols-1 gap-6 sm:grid-cols-2 {% if columns == 2 %}lg:grid-cols-2{% else %}lg:grid-cols-3{% endif %}">
{% for post in posts %} {% for post in posts %}
<article class="hud-frame group flex flex-col rounded-md border border-dashed border-primary/40 bg-card p-4 text-card-foreground neon-edge-cyan transition-transform hover:-translate-y-0.5"> <article class="hud-frame group flex flex-col rounded-md border border-dashed border-primary/40 bg-card p-4 text-card-foreground neon-edge-cyan transition-transform hover:-translate-y-0.5">
{% if post.featured_image_url %}<a href="{{ post.url }}" class="mb-3 block aspect-video overflow-hidden rounded-md bg-muted">{% img post.featured_image_url alt=post.title class="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" %}</a>{% endif %} {% if post.featured_image_url %}<a href="{{ post.url }}" class="mb-3 block aspect-video overflow-hidden rounded-md bg-muted">{% img post.featured_image_url alt=post.title class="h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" %}</a>{% endif %}

View File

@ -1,6 +1,6 @@
{# rich_section cyberpunk override: mono eyebrow, glitch heading, HUD-framed media, clip-cut CTA. Field reads + {% img %} preserved. #} {# rich_section cyberpunk override: mono eyebrow, glitch heading, HUD-framed media, clip-cut CTA. Field reads + {% img %} preserved. #}
<section class="py-16 md:py-24 {% if background == "muted" %}bg-muted text-foreground{% elif background == "card" %}bg-card text-card-foreground{% else %}bg-background text-foreground{% endif %}{% if class %} {{ class }}{% endif %}"> <section class="py-16 md:py-24 {% if background == "muted" %}bg-muted text-foreground{% elif background == "card" %}bg-card text-card-foreground{% else %}bg-background text-foreground{% endif %}{% if class %} {{ class }}{% endif %}">
<div class="mx-auto cp-split cp-split-md max-w-6xl items-center px-4"> <div class="mx-auto grid max-w-6xl items-center gap-10 px-4 md:grid-cols-2 md:gap-16">
<div class="{% if mediaPosition == "left" %}md:order-2{% else %}md:order-1{% endif %}"> <div class="{% if mediaPosition == "left" %}md:order-2{% else %}md:order-1{% endif %}">
{% if eyebrow %}<p class="cyberpunk-mono text-xs font-semibold uppercase tracking-widest text-accent">{{ eyebrow }}</p>{% endif %} {% if eyebrow %}<p class="cyberpunk-mono text-xs font-semibold uppercase tracking-widest text-accent">{{ eyebrow }}</p>{% endif %}
{% if heading %}<h2 class="cyberpunk-display glitch mt-2 text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch mt-2 text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}

View File

@ -4,7 +4,7 @@
<div class="relative z-10 mx-auto max-w-6xl px-4"> <div class="relative z-10 mx-auto max-w-6xl px-4">
{% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
{% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %} {% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %}
<dl class="mt-12 cp-grid cp-g-wide cp-m2 {% if columns == 2 %}cp-md2{% elif columns == 3 %}cp-md3{% else %}cp-md4{% endif %}"> <dl class="mt-12 grid grid-cols-2 gap-8 {% if columns == 2 %}md:grid-cols-2{% elif columns == 3 %}md:grid-cols-3{% else %}md:grid-cols-4{% endif %}">
{% for item in items %} {% for item in items %}
<div class="hud-frame text-center"> <div class="hud-frame text-center">
<dd class="cyberpunk-display text-4xl font-bold tracking-tight md:text-5xl" style="font-family:var(--font-heading)">{% if item.prefix %}{{ item.prefix }}{% endif %}<span{% if countUp %} data-countup-value="{{ item.value }}"{% endif %}>{{ item.value }}</span>{% if item.suffix %}{{ item.suffix }}{% endif %}</dd> <dd class="cyberpunk-display text-4xl font-bold tracking-tight md:text-5xl" style="font-family:var(--font-heading)">{% if item.prefix %}{{ item.prefix }}{% endif %}<span{% if countUp %} data-countup-value="{{ item.value }}"{% endif %}>{{ item.value }}</span>{% if item.suffix %}{{ item.suffix }}{% endif %}</dd>

View File

@ -3,7 +3,7 @@
<div class="mx-auto max-w-6xl px-4"> <div class="mx-auto max-w-6xl px-4">
{% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
{% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %} {% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %}
<div class="mt-12 {% if layout == "list" %}mx-auto max-w-3xl space-y-6{% elif layout == "single" %}mx-auto max-w-xl{% else %}cp-grid cp-g-wide cp-s2 {% if columns == 2 %}cp-lg2{% elif columns == 4 %}cp-lg4{% else %}cp-lg3{% endif %}{% endif %}"> <div class="mt-12 {% if layout == "list" %}mx-auto max-w-3xl space-y-6{% elif layout == "single" %}mx-auto max-w-xl{% else %}grid grid-cols-1 gap-8 sm:grid-cols-2 {% if columns == 2 %}lg:grid-cols-2{% elif columns == 4 %}lg:grid-cols-4{% else %}lg:grid-cols-3{% endif %}{% endif %}">
{% for member in members %} {% for member in members %}
<div class="{% if layout == "list" %}hud-frame flex items-start gap-5 rounded-md border border-dashed border-primary/50 bg-card p-5 text-card-foreground neon-edge-lime{% else %}text-center{% endif %}"> <div class="{% if layout == "list" %}hud-frame flex items-start gap-5 rounded-md border border-dashed border-primary/50 bg-card p-5 text-card-foreground neon-edge-lime{% else %}text-center{% endif %}">
{% if member.photo %}<span class="{% if layout == "list" %}h-20 w-20{% else %}mx-auto h-28 w-28{% endif %} block shrink-0 overflow-hidden rounded-full bg-muted">{% img member.photo alt=member.name class="h-full w-full object-cover" %}</span>{% endif %} {% if member.photo %}<span class="{% if layout == "list" %}h-20 w-20{% else %}mx-auto h-28 w-28{% endif %} block shrink-0 overflow-hidden rounded-full bg-muted">{% img member.photo alt=member.name class="h-full w-full object-cover" %}</span>{% endif %}

View File

@ -2,7 +2,7 @@
<section class="py-16 md:py-24 bg-background text-foreground{% if class %} {{ class }}{% endif %}"> <section class="py-16 md:py-24 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
<div class="mx-auto max-w-6xl px-4"> <div class="mx-auto max-w-6xl px-4">
{% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
<div class="mt-12 {% if layout == "single" %}mx-auto max-w-3xl{% elif layout == "carousel" %}flex snap-x snap-mandatory gap-6 overflow-x-auto pb-4{% else %}cp-grid cp-md2 cp-lg3{% endif %}"> <div class="mt-12 {% if layout == "single" %}mx-auto max-w-3xl{% elif layout == "carousel" %}flex snap-x snap-mandatory gap-6 overflow-x-auto pb-4{% else %}grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3{% endif %}">
{% for q in quotes %} {% for q in quotes %}
<figure class="hud-frame flex flex-col rounded-md border border-dashed border-primary/50 bg-card p-6 text-card-foreground neon-edge-cyan{% if layout == "carousel" %} min-w-[18rem] max-w-sm shrink-0 snap-start{% endif %}"> <figure class="hud-frame flex flex-col rounded-md border border-dashed border-primary/50 bg-card p-6 text-card-foreground neon-edge-cyan{% if layout == "carousel" %} min-w-[18rem] max-w-sm shrink-0 snap-start{% endif %}">
{% if q.rating %}<div class="mb-3 flex gap-0.5" aria-label="Rated {{ q.rating }} out of 5"> {% if q.rating %}<div class="mb-3 flex gap-0.5" aria-label="Rated {{ q.rating }} out of 5">

View File

@ -3,7 +3,7 @@
<div class="mx-auto max-w-4xl px-4"> <div class="mx-auto max-w-4xl px-4">
{% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %} {% if heading %}<h2 class="cyberpunk-display glitch text-center text-3xl font-semibold tracking-tight md:text-4xl" data-text="{{ heading }}">{{ heading }}</h2>{% endif %}
{% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %} {% if intro %}<p class="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">{{ intro }}</p>{% endif %}
<ol class="mt-12 {% if orientation == "horizontal" %}cp-grid cp-g-wide cp-s2 cp-lg4{% else %}cp-timeline space-y-8{% endif %}"> <ol class="mt-12 {% if orientation == "horizontal" %}grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-4{% else %}relative space-y-8 before:absolute before:left-4 before:top-2 before:h-[calc(100%-1rem)] before:w-px before:bg-primary/50{% endif %}">
{% 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="clip-cut flex h-8 w-8 items-center justify-center rounded-md bg-primary text-sm font-semibold text-primary-foreground cyberpunk-mono {% if orientation == "horizontal" %}mx-auto{% else %}absolute left-0 top-0 ring-4 ring-background{% endif %}"> <span class="clip-cut flex h-8 w-8 items-center justify-center rounded-md bg-primary text-sm font-semibold text-primary-foreground cyberpunk-mono {% if orientation == "horizontal" %}mx-auto{% else %}absolute left-0 top-0 ring-4 ring-background{% endif %}">