58 lines
5.1 KiB
Plaintext
58 lines
5.1 KiB
Plaintext
{# hero override — LCARS command-deck hero. GO BIG motion tier: one dependency-free canvas panel-sweep behind the content, lazy-inited, prefers-reduced-motion honored, with the fully-styled hero as the static no-JS fallback. All content fields preserved verbatim from the builtin. Styled-text fields accept {text,color} OR a bare string. #}
|
|
{% set eyebrowText = eyebrow.text|default:eyebrow %}
|
|
{% set headlineText = headline.text|default:headline %}
|
|
{% set subText = subheadline.text|default:subheadline %}
|
|
{% set descText = description.text|default:description %}
|
|
{% set pText = ctaPrimary.text %}
|
|
{% set pUrl = ctaPrimary.url %}
|
|
{% set sText = ctaSecondary.text %}
|
|
{% set sUrl = ctaSecondary.url %}
|
|
{% set variant = template|default:"centered" %}
|
|
{% macro herobody() %}
|
|
{% if eyebrowText %}<p class="lcars-eyebrow">{{ eyebrowText }}</p>{% endif %}
|
|
{% if headlineText %}<h1 class="lcars-hero-headline lcars-display" style="margin: 0;">{{ headlineText }}</h1>{% endif %}
|
|
{% if subText %}<p class="lcars-hero-sub lcars-lede" style="margin: 1.25rem 0 0 0; max-width: 60ch;">{{ subText }}</p>{% endif %}
|
|
{% if descText %}<p class="lcars-text" style="margin: 1rem 0 0 0; color: hsl(var(--muted-foreground)); max-width: 60ch;">{{ descText }}</p>{% endif %}
|
|
{% if pText or sText %}<div class="lcars-btn-row" style="margin-top: 2rem;">{% if pText and pUrl %}<a class="lcars-btn-primary lcars-btn-lg" href="{{ pUrl }}">{{ pText }}</a>{% endif %}{% if sText and sUrl %}<a class="lcars-btn-outline lcars-btn-lg" href="{{ sUrl }}">{{ sText }}</a>{% endif %}</div>{% endif %}
|
|
{% if trustLogos %}<div class="lcars-hairline-top" style="margin-top: 3rem; padding-top: 1.5rem;"><p class="lcars-kicker lcars-eyebrow" style="margin-bottom: 1rem; color: hsl(var(--muted-foreground));">Trusted by</p><div class="lcars-logo-row">{% for logo in trustLogos %}{% if logo.url %}<a href="{{ logo.url }}">{% img logo.image alt=logo.alt class="lcars-logo" %}</a>{% else %}{% img logo.image alt=logo.alt class="lcars-logo" %}{% endif %}{% endfor %}</div></div>{% endif %}
|
|
{% endmacro %}
|
|
{% if variant == "split" %}
|
|
<section class="lcars-hero lcars-hero-split lcars-hero-canvas-host {{ class }}"><canvas class="lcars-hero-canvas" data-lcars-hero-canvas aria-hidden="true"></canvas><div class="lcars-content-well"><div class="lcars-grid lcars-grid-2" style="align-items: center;"><div>{{ herobody() }}</div><div class="lcars-media-frame" style="aspect-ratio: 4 / 3; {% if mediaPosition == "left" %}order: -1;{% endif %}">{% if backgroundImage %}{% img backgroundImage alt=headlineText class="lcars-hero-media" %}{% endif %}</div></div></div></section>
|
|
{% else %}
|
|
<section class="lcars-hero lcars-hero-canvas-host {{ class }}" style="{% if variant == "left-aligned" %}text-align: left;{% else %}text-align: center;{% endif %}"><canvas class="lcars-hero-canvas" data-lcars-hero-canvas aria-hidden="true"></canvas><div class="lcars-content-well" style="{% if variant != "left-aligned" %}display: flex; flex-direction: column; align-items: center;{% endif %}"><div style="max-width: 60ch; width: 100%;">{{ herobody() }}</div></div></section>
|
|
{% endif %}
|
|
<script>
|
|
(function(){
|
|
if(window.__lcarsHeroInit)return;window.__lcarsHeroInit=1;
|
|
function reduced(){return window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;}
|
|
function tok(el,name){var v=getComputedStyle(el).getPropertyValue(name);return (v&&v.trim())?('hsl('+v.trim()+')'):'currentColor';}
|
|
function start(cv){
|
|
if(cv.__on)return;cv.__on=1;
|
|
var ctx=cv.getContext&&cv.getContext('2d');if(!ctx)return;
|
|
var host=cv.parentElement;
|
|
var cols=[tok(host,'--primary'),tok(host,'--secondary'),tok(host,'--accent')];
|
|
var bars=[];
|
|
function seed(w,h){bars=[];var n=Math.max(4,Math.floor(h/46));for(var i=0;i<n;i++){bars.push({y:(i+0.5)*(h/n),w:40+Math.random()*160,x:Math.random()*w,v:(0.25+Math.random()*0.9)*(Math.random()<0.5?-1:1),c:cols[i%3]});}}
|
|
function size(){var r=host.getBoundingClientRect();var dpr=Math.min(window.devicePixelRatio||1,2);cv.width=Math.max(1,r.width*dpr);cv.height=Math.max(1,r.height*dpr);ctx.setTransform(dpr,0,0,dpr,0,0);seed(r.width,r.height);}
|
|
size();
|
|
var still=reduced();
|
|
function frame(){
|
|
var r=host.getBoundingClientRect();ctx.clearRect(0,0,r.width,r.height);ctx.globalAlpha=0.16;
|
|
for(var i=0;i<bars.length;i++){var b=bars[i];ctx.fillStyle=b.c;var h=14;var rad=h/2;var x=b.x,y=b.y-h/2;
|
|
ctx.beginPath();ctx.moveTo(x+rad,y);ctx.arcTo(x+b.w,y,x+b.w,y+h,rad);ctx.arcTo(x+b.w,y+h,x,y+h,rad);ctx.arcTo(x,y+h,x,y,rad);ctx.arcTo(x,y,x+b.w,y,rad);ctx.closePath();ctx.fill();
|
|
if(!still){b.x+=b.v;if(b.x>r.width)b.x=-b.w;if(b.x<-b.w)b.x=r.width;}}
|
|
if(!still)cv.__raf=requestAnimationFrame(frame);
|
|
}
|
|
frame();
|
|
var rt;window.addEventListener('resize',function(){clearTimeout(rt);rt=setTimeout(size,150);},{passive:true});
|
|
}
|
|
function init(){
|
|
var nodes=document.querySelectorAll('[data-lcars-hero-canvas]');
|
|
if(!('IntersectionObserver' in window)){nodes.forEach(start);return;}
|
|
var io=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){start(e.target);io.unobserve(e.target);}});},{rootMargin:'120px'});
|
|
nodes.forEach(function(n){io.observe(n);});
|
|
}
|
|
if(document.readyState!='loading')init();else document.addEventListener('DOMContentLoaded',init);
|
|
})();
|
|
</script>
|