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>
86 lines
6.5 KiB
Plaintext
86 lines
6.5 KiB
Plaintext
{# hero kindergarten override (GO-BIG showpiece): a bouncing mascot, wiggling ABC letters, and a dependency-free confetti canvas fill the panel when there is no backgroundImage. The canvas lazy-inits on view, honours prefers-reduced-motion, and degrades to a static confetti wash with JS off. Sizing + typography are driven by compiled .kg-hero* CSS (NOT min-h-screen / responsive Tailwind, which the host JIT drops on a cold provision). All builtin field reads are preserved from the default hero. #}
|
|
{% set eyebrowText = eyebrow|get:"text"|default:eyebrow %}
|
|
{% set headlineText = headline|get:"text"|default:headline %}
|
|
{% set subText = subheadline|get:"text"|default:subheadline %}
|
|
{% set descText = description|get:"text"|default:description %}
|
|
{% set pText = ctaPrimary.text %}
|
|
{% set pUrl = ctaPrimary.url %}
|
|
{% set sText = ctaSecondary.text %}
|
|
{% set sUrl = ctaSecondary.url %}
|
|
{% set variant = template|default:"centered" %}
|
|
{% set hasImage = backgroundImage %}
|
|
{% set showOverlay = hasImage and overlayColor != "none" and overlayColor != "" %}
|
|
{% set align = "center" %}
|
|
{% if variant == "left-aligned" or variant == "split" %}{% set align = "left" %}{% endif %}
|
|
<section class="kg-hero {% if align == "center" %}kg-hero--center{% endif %}{% if class %} {{ class }}{% endif %}">
|
|
{% if hasImage %}<div class="kg-hero-media">{% img backgroundImage alt=headlineText class="h-full w-full object-cover" layout="hero" %}{% if showOverlay %}<div class="kg-hero-overlay"></div>{% endif %}</div>{% else %}<div class="kg-hero-media" aria-hidden="true"><div class="kg-confetti-wrap"><div class="kg-confetti-fallback"></div><canvas class="kg-confetti-canvas"></canvas></div><span class="kg-hero-mascot"><span class="kg-mascot inline-block"><svg viewBox="0 0 200 200" width="150" height="150" role="img" aria-label="Pip the mascot"><circle cx="100" cy="115" r="70" fill="hsl(var(--accent))" stroke="hsl(var(--foreground))" stroke-width="4"></circle><circle cx="78" cy="100" r="8" fill="hsl(var(--foreground))"></circle><circle cx="122" cy="100" r="8" fill="hsl(var(--foreground))"></circle><circle cx="78" cy="98" r="3" fill="hsl(var(--background))"></circle><circle cx="122" cy="98" r="3" fill="hsl(var(--background))"></circle><path d="M 75 130 Q 100 155 125 130" stroke="hsl(var(--foreground))" stroke-width="5" fill="none" stroke-linecap="round"></path><circle cx="60" cy="115" r="6" fill="hsl(var(--secondary))"></circle><circle cx="140" cy="115" r="6" fill="hsl(var(--secondary))"></circle><path d="M 50 60 L 60 35 L 80 50 Z" fill="hsl(var(--primary))"></path><path d="M 150 60 L 140 35 L 120 50 Z" fill="hsl(var(--primary))"></path></svg></span></span></div>{% endif %}
|
|
<div class="kg-hero-inner">
|
|
{% if eyebrowText %}<span class="kg-sticker">{{ eyebrowText }}</span>{% endif %}
|
|
{% if headlineText %}<h1 class="kg-display kg-hero-title"><span class="kg-crayon-underline">{{ headlineText }}</span></h1>{% endif %}
|
|
<span class="kg-hero-abc" aria-hidden="true"><span class="kg-wiggle-letter">A</span><span class="kg-wiggle-letter">B</span><span class="kg-wiggle-letter">C</span></span>
|
|
{% if subText %}<h2 class="kg-hero-sub">{{ subText }}</h2>{% endif %}
|
|
{% if descText %}<p class="kg-hero-desc">{{ descText }}</p>{% endif %}
|
|
{% if pText or sText %}<div class="kg-hero-cta">
|
|
{% if pText and pUrl %}<a href="{{ pUrl }}" class="kg-btn kg-btn-primary kg-pop">{{ pText }}</a>{% endif %}
|
|
{% if sText and sUrl %}<a href="{{ sUrl }}" class="kg-btn kg-btn-outline kg-pop">{{ sText }}</a>{% endif %}
|
|
</div>{% endif %}
|
|
{% if trustLogos %}<div class="kg-hero-trust">
|
|
<p class="kg-eyebrow">Loved by families at</p>
|
|
<div class="kg-hero-logos">{% for logo in trustLogos %}{% if logo.url %}<a href="{{ logo.url }}" target="_blank" rel="noopener noreferrer" class="opacity-70 transition-opacity hover:opacity-100">{% img logo.image alt=logo.alt class="h-8 w-auto" %}</a>{% else %}{% img logo.image alt=logo.alt class="h-8 w-auto opacity-70" %}{% endif %}{% endfor %}</div>
|
|
</div>{% endif %}
|
|
</div>
|
|
</section>
|
|
<script>
|
|
(function(){
|
|
if(window.__kgConfetti)return;window.__kgConfetti=1;
|
|
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
function initCanvas(cv){
|
|
if(cv.__init)return;cv.__init=1;
|
|
var ctx=cv.getContext&&cv.getContext('2d');if(!ctx)return;
|
|
var wrap=cv.parentElement;
|
|
var cs=getComputedStyle(document.documentElement);
|
|
function raw(n){return cs.getPropertyValue(n).trim();}
|
|
var cols=['hsl('+(raw('--primary')||'0 0% 50%')+')','hsl('+(raw('--secondary')||raw('--primary')||'0 0% 50%')+')','hsl('+(raw('--accent')||raw('--primary')||'0 0% 50%')+')'];
|
|
var W=0,H=0,dpr=1,pieces=[];
|
|
function make(){return {x:Math.random(),y:Math.random()*-1,r:6+Math.random()*8,rot:Math.random()*6.28,vr:(Math.random()-0.5)*0.15,sp:0.0016+Math.random()*0.0026,sway:0.3+Math.random()*0.7,c:cols[Math.floor(Math.random()*cols.length)],sq:Math.random()<0.5};}
|
|
function resize(){
|
|
dpr=Math.min(window.devicePixelRatio||1,2);
|
|
W=wrap.clientWidth;H=wrap.clientHeight;
|
|
if(W===0||H===0)return;
|
|
cv.width=W*dpr;cv.height=H*dpr;ctx.setTransform(dpr,0,0,dpr,0,0);
|
|
var n=Math.max(16,Math.min(70,Math.floor(W/16)));
|
|
pieces=[];for(var i=0;i<n;i++){var p=make();p.y=Math.random();pieces.push(p);}
|
|
}
|
|
resize();
|
|
var last=0,fps=1000/32;
|
|
function frame(t){
|
|
requestAnimationFrame(frame);
|
|
if(t-last<fps)return;last=t;
|
|
if(W===0||H===0){resize();return;}
|
|
ctx.clearRect(0,0,W,H);
|
|
for(var i=0;i<pieces.length;i++){
|
|
var p=pieces[i];
|
|
p.y+=p.sp;p.rot+=p.vr;
|
|
var px=(p.x*W)+Math.sin(p.y*6.28*p.sway)*14;
|
|
var py=p.y*H;
|
|
ctx.save();ctx.translate(px,py);ctx.rotate(p.rot);ctx.fillStyle=p.c;
|
|
if(p.sq){ctx.fillRect(-p.r/2,-p.r/2,p.r,p.r);}else{ctx.beginPath();ctx.arc(0,0,p.r/2,0,6.28);ctx.fill();}
|
|
ctx.restore();
|
|
if(py>H+20){pieces[i]=make();}
|
|
}
|
|
}
|
|
if(window.ResizeObserver){var ro=new ResizeObserver(resize);ro.observe(wrap);}else{window.addEventListener('resize',resize);}
|
|
requestAnimationFrame(frame);
|
|
}
|
|
function boot(){
|
|
if(reduce)return;
|
|
var cvs=document.querySelectorAll('.kg-confetti-canvas');
|
|
if(!cvs.length)return;
|
|
if(!('IntersectionObserver' in window)){cvs.forEach(initCanvas);return;}
|
|
var io=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){initCanvas(e.target);io.unobserve(e.target);}});},{threshold:0.05});
|
|
cvs.forEach(function(c){io.observe(c);});
|
|
}
|
|
if(document.readyState!='loading')boot();else document.addEventListener('DOMContentLoaded',boot);
|
|
})();
|
|
</script>
|