fix(theme): drive responsive layout from theme-owned CSS
Host Tailwind JIT does not scan theme templates, so responsive grid/hero utilities (sm:/md:/lg:grid-cols-*, min-h-screen, arbitrary values) are dropped and multi-column layouts collapse to one column. Ship the load-bearing responsive layout as compiled theme CSS and point the override templates at it. Layout only — colours stay on semantic tokens. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
895d76f612
commit
0b3013ce81
@ -338,3 +338,52 @@ css:
|
|||||||
.noir-redact { transition: none; }
|
.noir-redact { transition: none; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
Explicit responsive layout (authored CSS — NOT purged).
|
||||||
|
The host Tailwind JIT does not reliably scan a theme's override
|
||||||
|
templates, so sm:/md:/lg: grid variants declared there can be
|
||||||
|
dropped from the build (a grid then never expands on desktop
|
||||||
|
and never collapses on mobile). These media-query rules own the
|
||||||
|
column counts deterministically and always collapse to a single
|
||||||
|
column on phones.
|
||||||
|
============================================================ */
|
||||||
|
.noir-cols { display: grid; grid-template-columns: 1fr; gap: 1.5rem; }
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
.noir-cols-2, .noir-cols-3, .noir-cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||||
|
}
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.noir-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
||||||
|
.noir-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
|
||||||
|
}
|
||||||
|
/* Grids that stay two-up on phones (galleries, stat rows, footer links). */
|
||||||
|
.noir-cols-2up { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.noir-cols-2up-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
||||||
|
.noir-cols-2up-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
|
||||||
|
}
|
||||||
|
/* Media/text split — one column on phones, two from the tablet width. */
|
||||||
|
.noir-split { display: grid; grid-template-columns: 1fr; gap: 2.5rem; }
|
||||||
|
@media (min-width: 768px) { .noir-split { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
||||||
|
/* Gap modifiers (used alongside any grid class above). */
|
||||||
|
.noir-gap-sm { gap: 0.75rem; }
|
||||||
|
.noir-gap-lg { gap: 2rem; }
|
||||||
|
|
||||||
|
/* Hero vertical rhythm — replaces the unreliable min-h-[75vh] arbitrary
|
||||||
|
class so the masthead has bounded, predictable breathing room instead
|
||||||
|
of collapsing to nothing or ballooning to 75vh of empty space. */
|
||||||
|
.noir-hero-pad { padding-top: 3.5rem; padding-bottom: 3.5rem; }
|
||||||
|
@media (min-width: 768px) { .noir-hero-pad { padding-top: 5rem; padding-bottom: 5rem; } }
|
||||||
|
@media (min-width: 1024px) { .noir-hero-pad { padding-top: 6.5rem; padding-bottom: 6.5rem; } }
|
||||||
|
|
||||||
|
/* Empty-media graceful state — the demo seed ships no images, so any
|
||||||
|
media frame that renders an empty <img> must not balloon into a grey
|
||||||
|
box or show broken-image chrome. Images never exceed their column. */
|
||||||
|
.noir-file img, .bn-card img, .bn-gallery img, figure img { max-width: 100%; height: auto; }
|
||||||
|
img[src=""], img:not([src]) { display: none; }
|
||||||
|
|
||||||
|
/* Overflow safety — long typed/mono labels wrap rather than push the
|
||||||
|
page wider than a phone viewport (uppercase + wide tracking is the risk). */
|
||||||
|
.noir-label, .noir-mono, .noir-heading { overflow-wrap: break-word; }
|
||||||
|
/* Never let a block force a horizontal scrollbar on small screens. */
|
||||||
|
[data-block-override], [data-block] { max-width: 100%; }
|
||||||
|
|||||||
@ -22,8 +22,11 @@
|
|||||||
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||||
var els=document.querySelectorAll('.noir-reveal');
|
var els=document.querySelectorAll('.noir-reveal');
|
||||||
if(reduce||!('IntersectionObserver' in window)){els.forEach(function(el){el.classList.add('noir-in');});return;}
|
if(reduce||!('IntersectionObserver' in window)){els.forEach(function(el){el.classList.add('noir-in');});return;}
|
||||||
var io=new IntersectionObserver(function(entries){entries.forEach(function(e){if(e.isIntersecting){e.target.classList.add('noir-in');io.unobserve(e.target);}});},{threshold:0.12});
|
var io=new IntersectionObserver(function(entries){entries.forEach(function(e){if(e.isIntersecting){e.target.classList.add('noir-in');io.unobserve(e.target);}});},{threshold:0,rootMargin:'0px 0px -8% 0px'});
|
||||||
els.forEach(function(el){io.observe(el);});
|
function showAll(){els.forEach(function(el){el.classList.add('noir-in');});}
|
||||||
|
els.forEach(function(el){var r=el.getBoundingClientRect();var h=window.innerHeight||document.documentElement.clientHeight||0;if(r.top<h*0.92&&r.bottom>0){el.classList.add('noir-in');}else{io.observe(el);}});
|
||||||
|
window.addEventListener('load',showAll);
|
||||||
|
setTimeout(showAll,1600);
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
{{ admin_banner_html|safe }}
|
{{ admin_banner_html|safe }}
|
||||||
<section class="w-full relative noir-grain noir-spotlight">{{ slots.hero|safe }}</section>
|
<section class="w-full relative noir-grain noir-spotlight">{{ slots.hero|safe }}</section>
|
||||||
<main class="flex-grow">
|
<main class="flex-grow">
|
||||||
{% if slots.main %}<div class="max-w-5xl mx-auto px-4 py-16 noir-reveal">{{ slots.main|safe }}</div>{% endif %}
|
{% if slots.main %}<div class="max-w-3xl mx-auto w-full px-4 py-10 noir-reveal">{{ slots.main|safe }}</div>{% endif %}
|
||||||
</main>
|
</main>
|
||||||
<section class="w-full">{{ slots.cta|safe }}</section>
|
<section class="w-full">{{ slots.cta|safe }}</section>
|
||||||
<footer class="w-full mt-auto noir-rule">
|
<footer class="w-full mt-auto noir-rule">
|
||||||
@ -19,8 +19,11 @@
|
|||||||
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||||
var els=document.querySelectorAll('.noir-reveal');
|
var els=document.querySelectorAll('.noir-reveal');
|
||||||
if(reduce||!('IntersectionObserver' in window)){els.forEach(function(el){el.classList.add('noir-in');});return;}
|
if(reduce||!('IntersectionObserver' in window)){els.forEach(function(el){el.classList.add('noir-in');});return;}
|
||||||
var io=new IntersectionObserver(function(entries){entries.forEach(function(e){if(e.isIntersecting){e.target.classList.add('noir-in');io.unobserve(e.target);}});},{threshold:0.12});
|
var io=new IntersectionObserver(function(entries){entries.forEach(function(e){if(e.isIntersecting){e.target.classList.add('noir-in');io.unobserve(e.target);}});},{threshold:0,rootMargin:'0px 0px -8% 0px'});
|
||||||
els.forEach(function(el){io.observe(el);});
|
function showAll(){els.forEach(function(el){el.classList.add('noir-in');});}
|
||||||
|
els.forEach(function(el){var r=el.getBoundingClientRect();var h=window.innerHeight||document.documentElement.clientHeight||0;if(r.top<h*0.92&&r.bottom>0){el.classList.add('noir-in');}else{io.observe(el);}});
|
||||||
|
window.addEventListener('load',showAll);
|
||||||
|
setTimeout(showAll,1600);
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
{% if subtitle %}<p class="noir-body mt-3 text-lg" style="color:hsl(var(--muted-foreground));">{{ subtitle }}</p>{% endif %}
|
{% if subtitle %}<p class="noir-body mt-3 text-lg" style="color:hsl(var(--muted-foreground));">{{ subtitle }}</p>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if posts %}
|
{% if posts %}
|
||||||
<div class="mt-10 grid grid-cols-1 gap-6 md:grid-cols-3">
|
<div class="mt-10 noir-cols noir-cols-3">
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
<article class="group flex flex-col{% if forloop.First %} md:col-span-3 md:flex-row md:items-stretch md:gap-6{% endif %}">
|
<article class="group flex flex-col{% 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 bg-muted grayscale{% 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 bg-muted grayscale{% 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 %}
|
||||||
|
|||||||
@ -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="noir-heading text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
{% if description %}<p class="noir-body mt-3 max-w-2xl text-lg" style="color:hsl(var(--muted-foreground));">{{ description }}</p>{% endif %}
|
{% if description %}<p class="noir-body mt-3 max-w-2xl text-lg" style="color:hsl(var(--muted-foreground));">{{ description }}</p>{% 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 %}">
|
<div class="mt-10 noir-cols {% if columns == 3 %}noir-cols-3{% elif columns == 1 %}{% else %}noir-cols-2{% endif %}">
|
||||||
{% for channel in channels %}
|
{% for channel in channels %}
|
||||||
<div class="noir-file flex items-start gap-4 p-5">
|
<div class="noir-file flex items-start gap-4 p-5">
|
||||||
{% if channel.icon %}<span class="inline-flex h-10 w-10 shrink-0 items-center justify-center border border-border 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="inline-flex h-10 w-10 shrink-0 items-center justify-center border border-border 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 %}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{# noir override — cta; preserves heading, text, background (band/card/split), primaryUrl/primaryLabel, secondaryUrl/secondaryLabel. Arrow svg markup verbatim; band adds .noir-grain. #}
|
{# noir override — cta; preserves heading, text, background (band/card/split), primaryUrl/primaryLabel, secondaryUrl/secondaryLabel. Arrow svg markup verbatim; band adds .noir-grain. #}
|
||||||
<section data-block-override="noir:cta" class="py-16 md:py-24 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
|
<section data-block-override="noir:cta" 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">
|
||||||
<div class="{% if background == "band" %}noir-file noir-grain bg-primary px-6 py-14 text-center text-primary-foreground md:px-12{% elif background == "card" %}noir-file px-6 py-14 text-center text-card-foreground md:px-12{% else %}noir-file flex flex-col items-center gap-8 bg-muted px-6 py-12 text-foreground md:flex-row md:justify-between md:px-12 md:text-left{% endif %}">
|
<div class="{% if background == "band" %}noir-file noir-grain bg-primary px-6 py-14 text-center text-primary-foreground md:px-12{% elif background == "card" %}noir-file px-6 py-14 text-center text-card-foreground md:px-12{% else %}noir-file flex flex-col items-center gap-8 bg-muted px-6 py-12 text-foreground md:flex-row md:justify-between md:px-12 md:text-left{% endif %}">
|
||||||
<div class="{% if background != "split" %}mx-auto max-w-2xl{% endif %}">
|
<div class="{% if background != "split" %}mx-auto max-w-2xl{% endif %}">
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
{% if heading %}<h2 class="noir-heading text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
{% if intro %}<p class="noir-body mt-3 max-w-2xl text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
{% if intro %}<p class="noir-body mt-3 max-w-2xl text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
||||||
{% if layout == "cards" %}
|
{% if layout == "cards" %}
|
||||||
<div class="mt-10 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
<div class="mt-10 noir-cols noir-cols-3">
|
||||||
{% for event in events %}{% if not (hidePast and event.past) %}
|
{% for event in events %}{% if not (hidePast and event.past) %}
|
||||||
<article class="noir-file flex flex-col overflow-hidden{% if event.past %} opacity-60{% endif %}">
|
<article class="noir-file flex flex-col overflow-hidden{% if event.past %} opacity-60{% endif %}">
|
||||||
{% if event.media %}<div class="aspect-video overflow-hidden bg-muted grayscale">{% 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 grayscale">{% img event.media alt=event.title class="h-full w-full object-cover" %}</div>{% endif %}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
{# noir override — feature-grid; preserves eyebrow, heading, intro, columns, layout, items[].icon/.title/.text/.linkUrl/.linkLabel, icon split markup verbatim. #}
|
{# noir override — feature-grid; preserves eyebrow, heading, intro, columns, layout, items[].icon/.title/.text/.linkUrl/.linkLabel, icon split markup verbatim. #}
|
||||||
<section data-block-override="noir:feature-grid" class="py-16 md:py-24 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
|
<section data-block-override="noir:feature-grid" 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 eyebrow %}<p class="text-center noir-label" style="color:hsl(var(--primary));">{{ eyebrow }}</p>{% endif %}
|
{% if eyebrow %}<p class="text-center noir-label" style="color:hsl(var(--primary));">{{ eyebrow }}</p>{% endif %}
|
||||||
{% if heading %}<h2 class="noir-heading mt-2 text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading mt-2 text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% 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 %}">
|
<div class="mt-10 noir-cols {% if columns == 2 %}noir-cols-2{% elif columns == 4 %}noir-cols-4{% else %}noir-cols-3{% endif %}">
|
||||||
{% for item in items %}
|
{% for item in items %}
|
||||||
<div class="{% if layout == "card" %}noir-file p-6 text-card-foreground transition-colors{% elif layout == "centered" %}text-center{% endif %}">
|
<div class="{% if layout == "card" %}noir-file p-6 text-card-foreground transition-colors{% elif layout == "centered" %}text-center{% endif %}">
|
||||||
{% if item.icon %}<div class="mb-4 inline-flex h-11 w-11 items-center justify-center border border-border bg-primary/10 text-primary{% if layout == "centered" %} mx-auto{% endif %}"><svg class="h-6 w-6" aria-hidden="true"><use href="/icons/{{ item.icon|split:":"|first }}.svg#{{ item.icon|split:":"|last }}"></use></svg></div>{% endif %}
|
{% if item.icon %}<div class="mb-3 text-primary{% if layout == "centered" %} flex justify-center{% endif %}"><svg class="h-7 w-7" aria-hidden="true"><use href="/icons/{{ item.icon|split:":"|first }}.svg#{{ item.icon|split:":"|last }}"></use></svg></div>{% endif %}
|
||||||
<h3 class="noir-heading text-lg" style="color:hsl(var(--foreground));">{% if item.linkUrl %}<a href="{{ item.linkUrl }}" class="transition-colors hover:text-primary">{{ item.title }}</a>{% else %}{{ item.title }}{% endif %}</h3>
|
<h3 class="noir-heading text-lg" style="color:hsl(var(--foreground));">{% if item.linkUrl %}<a href="{{ item.linkUrl }}" class="transition-colors hover:text-primary">{{ item.title }}</a>{% else %}{{ item.title }}{% endif %}</h3>
|
||||||
{% if item.text %}<p class="noir-body mt-2" style="color:hsl(var(--muted-foreground));">{{ item.text }}</p>{% endif %}
|
{% if item.text %}<p class="noir-body mt-2" style="color:hsl(var(--muted-foreground));">{{ item.text }}</p>{% endif %}
|
||||||
{% if item.linkUrl and item.linkLabel %}<a href="{{ item.linkUrl }}" class="noir-link mt-3 inline-flex items-center gap-1 text-sm">{{ item.linkLabel }}<svg class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
{% if item.linkUrl and item.linkLabel %}<a href="{{ item.linkUrl }}" class="noir-link mt-3 inline-flex items-center gap-1 text-sm">{{ item.linkLabel }}<svg class="h-4 w-4" aria-hidden="true"><use href="/icons/lucide.svg#arrow-right"></use></svg></a>{% endif %}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<section data-block-override="noir:featured-posts" class="py-12 md:py-16 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
|
<section data-block-override="noir:featured-posts" 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="noir-heading mb-8 text-2xl md:text-3xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading mb-8 text-2xl md:text-3xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% 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 %}">
|
<div class="noir-cols {% if columns == 2 %}noir-cols-2{% elif columns == 4 %}noir-cols-4{% else %}noir-cols-3{% endif %}">
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
<article class="noir-file group flex flex-col overflow-hidden">
|
<article class="noir-file group flex flex-col overflow-hidden">
|
||||||
{% if showFeaturedImage and post.featured_image_url %}<a href="{{ post.url }}" class="block aspect-video overflow-hidden bg-muted grayscale">{% 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 grayscale">{% 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 %}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{# noir override — gallery; preserves layout, gap, columns, lightbox, images[].src/.alt/.caption, data-bn-gallery, data-lightbox, data-bn-gallery-item, data-caption, {% img %} calls, and the full lightbox IIFE verbatim. Only grid tiles restyled (square hairline frames, grayscale). #}
|
{# noir override — gallery; preserves layout, gap, columns, lightbox, images[].src/.alt/.caption, data-bn-gallery, data-lightbox, data-bn-gallery-item, data-caption, {% img %} calls, and the full lightbox IIFE verbatim. Only grid tiles restyled (square hairline frames, grayscale). #}
|
||||||
{% with layout=layout|default:"grid" gap=gap|default:"md" cols=columns|default:3 %}<div data-block-override="noir:gallery" class="bn-gallery my-8{% 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="noir-hairline group relative block overflow-hidden bg-muted grayscale transition hover:grayscale-0 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 data-block-override="noir:gallery" class="bn-gallery my-8{% 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 %}noir-cols-2up {% if cols == 4 %}noir-cols-2up-4{% elif cols == 2 %}{% else %}noir-cols-2up-3{% endif %} {% if gap == "sm" %}noir-gap-sm{% elif gap == "lg" %}noir-gap-lg{% endif %}{% endif %}">{% for image in images %}<a href="{{ image.src|mediaURL }}" data-bn-gallery-item data-caption="{{ image.caption|default:"" }}" class="noir-hairline group relative block overflow-hidden bg-muted grayscale transition hover:grayscale-0 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;
|
||||||
|
|||||||
@ -25,14 +25,14 @@
|
|||||||
</div>{% endif %}
|
</div>{% endif %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
{% if variant == "split" %}
|
{% if variant == "split" %}
|
||||||
<section data-block-override="noir:hero" class="hero grid grid-cols-1 lg:grid-cols-2 overflow-hidden bg-background text-foreground noir-grain{% if class %} {{ class }}{% endif %}">
|
<section data-block-override="noir:hero" class="hero {% if hasImage %}noir-split{% endif %} overflow-hidden bg-background text-foreground noir-grain{% if class %} {{ class }}{% endif %}">
|
||||||
<div class="relative min-h-[320px] bg-muted grayscale {% 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" %}{% endif %}</div>
|
{% if hasImage %}<div class="relative bg-muted grayscale" style="min-height:20rem;">{% img backgroundImage alt=headlineText class="absolute inset-0 h-full w-full object-cover" layout="hero" %}</div>{% endif %}
|
||||||
<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 noir-hero-pad px-6 lg:px-12"><div class="max-w-lg text-left">{{ herocontent("left") }}</div></div>
|
||||||
</section>
|
</section>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set align = "center" %}
|
{% set align = "center" %}
|
||||||
{% if variant == "left-aligned" %}{% set align = "left" %}{% endif %}
|
{% if variant == "left-aligned" %}{% set align = "left" %}{% endif %}
|
||||||
<section data-block-override="noir:hero" class="hero relative flex flex-col overflow-hidden bg-background text-foreground noir-grain {% if minHeight == "screen" %}min-h-screen{% elif minHeight == "50vh" %}min-h-[50vh]{% elif minHeight == "auto" %}min-h-[400px]{% else %}min-h-[75vh]{% endif %} {% if verticalAlign == "top" %}justify-start pt-20{% elif verticalAlign == "bottom" %}justify-end pb-20{% else %}justify-center{% endif %}{% if class %} {{ class }}{% endif %}">
|
<section data-block-override="noir:hero" class="hero relative flex flex-col overflow-hidden bg-background text-foreground noir-grain {% if minHeight == "screen" %}min-h-screen justify-center{% else %}noir-hero-pad{% endif %}{% if class %} {{ class }}{% endif %}">
|
||||||
{% if hasImage %}<div class="absolute inset-0 z-0 noir-spotlight grayscale">{% img backgroundImage alt=headlineText class="h-full w-full object-cover" layout="hero" %}{% if showOverlay %}<div class="absolute inset-0 {% if overlayColor == "light" %}bg-background/60{% elif overlayColor == "primary" %}bg-primary/50{% elif overlayOpacity <= 30 %}bg-black/30{% elif overlayOpacity <= 50 %}bg-black/50{% elif overlayOpacity <= 70 %}bg-black/70{% else %}bg-black/80{% endif %}"></div>{% endif %}</div>{% endif %}
|
{% if hasImage %}<div class="absolute inset-0 z-0 noir-spotlight grayscale">{% img backgroundImage alt=headlineText class="h-full w-full object-cover" layout="hero" %}{% if showOverlay %}<div class="absolute inset-0 {% if overlayColor == "light" %}bg-background/60{% elif overlayColor == "primary" %}bg-primary/50{% elif overlayOpacity <= 30 %}bg-black/30{% elif overlayOpacity <= 50 %}bg-black/50{% elif overlayOpacity <= 70 %}bg-black/70{% else %}bg-black/80{% endif %}"></div>{% endif %}</div>{% endif %}
|
||||||
<div class="relative z-10 mx-auto w-full max-w-4xl px-4 sm:px-6 lg:px-8 {% if variant == "left-aligned" %}text-left{% else %}text-center{% endif %}">{{ herocontent(align) }}</div>
|
<div class="relative z-10 mx-auto w-full max-w-4xl px-4 sm:px-6 lg:px-8 {% if variant == "left-aligned" %}text-left{% else %}text-center{% endif %}">{{ herocontent(align) }}</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<section data-block-override="noir:hours-location" class="py-16 md:py-24 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
|
<section data-block-override="noir:hours-location" 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="noir-heading text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
<div class="mt-10 grid grid-cols-1 gap-10 md:grid-cols-2">
|
<div class="mt-10 noir-split">
|
||||||
<div class="noir-file p-6 md:p-8">
|
<div class="noir-file p-6 md:p-8">
|
||||||
{% if hours %}
|
{% if hours %}
|
||||||
<table class="w-full text-sm">
|
<table class="w-full text-sm">
|
||||||
|
|||||||
@ -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="noir-heading text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
{% if intro %}<p class="noir-body mt-3 max-w-2xl text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
{% if intro %}<p class="noir-body mt-3 max-w-2xl text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
||||||
<div class="mt-10 grid grid-cols-1 gap-x-12 gap-y-10 {% if columns == 2 %}md:grid-cols-2{% endif %}">
|
<div class="mt-10 noir-cols noir-gap-lg {% if columns == 2 %}noir-cols-2{% endif %}">
|
||||||
{% for section in sections %}
|
{% for section in sections %}
|
||||||
<div class="menu-section">
|
<div class="menu-section">
|
||||||
{% if section.title %}<h3 class="noir-label noir-rule pb-2 text-sm" style="color:hsl(var(--primary));">{{ section.title }}</h3>{% endif %}
|
{% if section.title %}<h3 class="noir-label noir-rule pb-2 text-sm" style="color:hsl(var(--primary));">{{ section.title }}</h3>{% endif %}
|
||||||
|
|||||||
@ -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="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
||||||
<div class="mt-12 grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
<div class="mt-10 noir-cols noir-cols-3">
|
||||||
{% for tier in tiers %}
|
{% for tier in tiers %}
|
||||||
<div class="relative flex flex-col p-6 {% if tier.highlighted %}noir-file ring-1 ring-[hsl(var(--primary))]{% else %}noir-file{% endif %}">
|
<div class="relative flex flex-col p-6 {% if tier.highlighted %}noir-file ring-1 ring-[hsl(var(--primary))]{% else %}noir-file{% endif %}">
|
||||||
{% if tier.badge %}<span class="noir-label absolute -top-3 left-1/2 -translate-x-1/2 bg-primary px-3 py-1 text-primary-foreground">{{ tier.badge }}</span>{% endif %}
|
{% if tier.badge %}<span class="noir-label absolute -top-3 left-1/2 -translate-x-1/2 bg-primary px-3 py-1 text-primary-foreground">{{ tier.badge }}</span>{% endif %}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<section data-block-override="noir:related-posts" class="noir-rule py-12 md:py-16 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
|
<section data-block-override="noir:related-posts" class="noir-rule 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="noir-heading mb-8 text-2xl md:text-3xl" style="color:hsl(var(--foreground));">{{ heading|default:"Related posts" }}</h2>
|
<h2 class="noir-heading mb-8 text-2xl md:text-3xl" style="color:hsl(var(--foreground));">{{ heading|default:"Related posts" }}</h2>
|
||||||
<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 %}">
|
<div class="noir-cols {% if columns == 2 %}noir-cols-2{% else %}noir-cols-3{% endif %}">
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
<article class="group flex flex-col">
|
<article class="group flex flex-col">
|
||||||
{% if post.featured_image_url %}<a href="{{ post.url }}" class="mb-3 block aspect-video overflow-hidden bg-muted grayscale">{% 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 bg-muted grayscale">{% 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 %}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{# noir override — rich-section; preserves background, mediaPosition, eyebrow, heading, body, ctaUrl/ctaLabel, media/mediaAlt, {% img %} + icon markup verbatim. #}
|
{# noir override — rich-section; preserves background, mediaPosition, eyebrow, heading, body, ctaUrl/ctaLabel, media/mediaAlt, {% img %} + icon markup verbatim. #}
|
||||||
<section data-block-override="noir:rich-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 data-block-override="noir:rich-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 grid max-w-6xl items-center gap-10 px-4 md:grid-cols-2 md:gap-16">
|
<div class="mx-auto noir-split items-center max-w-6xl px-4">
|
||||||
<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 %}<div class="mb-3 flex items-center gap-4"><span class="noir-rule w-12"></span><p class="noir-label" style="color:hsl(var(--primary));">{{ eyebrow }}</p></div>{% endif %}
|
{% if eyebrow %}<div class="mb-3 flex items-center gap-4"><span class="noir-rule w-12"></span><p class="noir-label" style="color:hsl(var(--primary));">{{ eyebrow }}</p></div>{% endif %}
|
||||||
{% if heading %}<h2 class="noir-heading mt-2 text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading mt-2 text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
|
|||||||
@ -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="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
||||||
<dl class="mt-12 grid grid-cols-2 gap-8 divide-x divide-border {% if columns == 2 %}md:grid-cols-2{% elif columns == 3 %}md:grid-cols-3{% else %}md:grid-cols-4{% endif %}">
|
<dl class="mt-10 noir-cols-2up noir-gap-lg divide-x divide-border {% if columns == 2 %}{% elif columns == 3 %}noir-cols-2up-3{% else %}noir-cols-2up-4{% endif %}">
|
||||||
{% for item in items %}
|
{% for item in items %}
|
||||||
<div class="px-2 text-center">
|
<div class="px-2 text-center">
|
||||||
<dd class="noir-mono text-4xl font-bold tracking-tight md:text-5xl" style="color:hsl(var(--primary));">{% 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="noir-mono text-4xl font-bold tracking-tight md:text-5xl" style="color:hsl(var(--primary));">{% 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>
|
||||||
|
|||||||
@ -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="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--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 %}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 %}">
|
<div class="mt-10 {% if layout == "list" %}mx-auto max-w-3xl space-y-6{% elif layout == "single" %}mx-auto max-w-xl{% else %}noir-cols noir-gap-lg {% if columns == 2 %}noir-cols-2{% elif columns == 4 %}noir-cols-4{% else %}noir-cols-3{% endif %}{% endif %}">
|
||||||
{% for member in members %}
|
{% for member in members %}
|
||||||
<div class="{% if layout == "list" %}noir-file flex items-start gap-5 p-5{% else %}text-center{% endif %}">
|
<div class="{% if layout == "list" %}noir-file flex items-start gap-5 p-5{% 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 grayscale">{% 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 grayscale">{% img member.photo alt=member.name class="h-full w-full object-cover" %}</span>{% endif %}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<section data-block-override="noir:testimonial" class="py-16 md:py-24 bg-background text-foreground{% if class %} {{ class }}{% endif %}">
|
<section data-block-override="noir:testimonial" 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="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ 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 %}grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3{% 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 %}noir-cols noir-cols-3{% endif %}">
|
||||||
{% for q in quotes %}
|
{% for q in quotes %}
|
||||||
<figure class="noir-file flex flex-col p-6 text-card-foreground{% if layout == "carousel" %} min-w-[18rem] max-w-sm shrink-0 snap-start{% endif %}">
|
<figure class="noir-file flex flex-col p-6 text-card-foreground{% 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">
|
||||||
|
|||||||
@ -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="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
{% if heading %}<h2 class="noir-heading text-center text-3xl md:text-4xl" style="color:hsl(var(--foreground));">{{ heading }}</h2>{% endif %}
|
||||||
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% endif %}
|
{% if intro %}<p class="noir-body mx-auto mt-4 max-w-2xl text-center text-lg" style="color:hsl(var(--muted-foreground));">{{ intro }}</p>{% 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-border{% endif %}">
|
<ol class="mt-12 {% if orientation == "horizontal" %}noir-cols noir-gap-lg noir-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-border{% 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="noir-mono flex h-8 w-8 items-center justify-center rounded-full bg-primary text-sm font-semibold text-primary-foreground {% if orientation == "horizontal" %}mx-auto{% else %}absolute left-0 top-0 ring-4 ring-background{% endif %}">
|
<span class="noir-mono flex h-8 w-8 items-center justify-center rounded-full bg-primary text-sm font-semibold text-primary-foreground {% if orientation == "horizontal" %}mx-auto{% else %}absolute left-0 top-0 ring-4 ring-background{% endif %}">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user