Food truck websiteOne-line
MiniMax M3.1 Flash
by MiniMaxReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 2 min 45 s
- Cost
- $0.020
- Output tokens
- 33,244
- Spent thinking
- 8,451 tokens
- Speed
- 202.5 tok/s
- Console errors
- 0
- First token after
- 644 ms
- First visible text after
- 1 min 1 s
- Prompt tokens
- 537
- Code size
- 73.9 KB
- Finish reason
- stop
- Served by
- Nebius
- Model id
minimax/minimax-m3.1-flash- Reasoning sent
model default- Max output
- 524,288 tokens
- Generated
- Nov 13, 2026
What it was asked
The prompt
“i'm opening a korean taco food truck called "Kimchi Loco", make me a website that makes people really want to come”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task. Output rules: - Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block. - Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task. - Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw. - The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar. - Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction. - Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session. - Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing. - The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message. - The code must run with zero errors in the console of the latest Chrome.
Code run-1.html · 1251 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kimchi Loco — Korean-Mexican Street Tacos | Food Truck & Catering</title>
<meta name="description" content="Kimchi Loco: slow-braised carnitas, sizzling bulgogi and fermented kimchi tucked into tortillas pressed to order. Find the truck, order ahead, or book us for your event." />
<style>
/* ============================================================
KIMCHI LOCO — all styles inline
============================================================ */
:root{
--cream:#FFF7EC;
--cream-2:#FCEBD6;
--cream-3:#F6E0C6;
--ink:#1E1512;
--ink-2:#3A2C24;
--muted:#6E5B4F;
--red:#E03127;
--red-d:#B71F19;
--orange:#F2751A;
--gold:#FFC93C;
--green:#3F9A45;
--purple:#8E2F6E;
--white:#fff;
--radius:22px;
--shadow:0 18px 40px -18px rgba(30,21,18,.45);
--shadow-lg:0 34px 70px -26px rgba(30,21,18,.55);
--sans:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
margin:0;
background:var(--cream);
color:var(--ink);
font-family:var(--sans);
font-size:17px;
line-height:1.6;
overflow-x:hidden;
-webkit-font-smoothing:antialiased;
}
body::before{
content:"";position:fixed;inset:0;pointer-events:none;z-index:0;opacity:.5;
background-image:radial-gradient(rgba(224,49,39,.07) 1px,transparent 1px);
background-size:22px 22px;
}
img,svg{max-width:100%}
a{color:inherit;text-decoration:none}
button{font-family:inherit}
.container{width:100%;max-width:1180px;margin:0 auto;padding:0 22px;position:relative;z-index:1}
section{position:relative;z-index:1}
/* ---------- type ---------- */
h1,h2,h3,h4{line-height:1.02;margin:0 0 .5em;font-weight:900;letter-spacing:-.025em}
h1{font-size:clamp(3.1rem,10vw,6.4rem);text-transform:uppercase}
h2{font-size:clamp(2.1rem,5.4vw,3.6rem);text-transform:uppercase}
h3{font-size:1.22rem}
p{margin:0 0 1em}
.eyebrow{
display:inline-flex;align-items:center;gap:.55rem;
font-size:.76rem;font-weight:900;letter-spacing:.18em;text-transform:uppercase;
background:var(--gold);color:var(--ink);padding:.42rem .9rem;border-radius:100px;
box-shadow:3px 3px 0 var(--ink);margin-bottom:1.1rem;
}
.eyebrow.dark{background:rgba(255,201,60,.16);color:var(--gold);box-shadow:none;border:1px solid rgba(255,201,60,.4)}
.lead{font-size:clamp(1.05rem,1.6vw,1.2rem);color:var(--ink-2);max-width:60ch}
.muted{color:var(--muted)}
.center{text-align:center}
.center .lead{margin-left:auto;margin-right:auto}
/* ---------- buttons ---------- */
.btn{
display:inline-flex;align-items:center;justify-content:center;gap:.55rem;
padding:.95rem 1.5rem;border-radius:100px;font-weight:900;font-size:.95rem;
letter-spacing:.02em;border:2px solid transparent;cursor:pointer;
transition:transform .18s cubic-bezier(.2,.9,.3,1.4),box-shadow .18s,background .18s,color .18s;
white-space:nowrap;
}
.btn:active{transform:translateY(2px) scale(.98)}
.btn-red{background:var(--red);color:#fff;box-shadow:0 8px 0 var(--red-d),0 16px 26px -12px rgba(224,49,39,.8)}
.btn-red:hover{transform:translateY(-3px);box-shadow:0 11px 0 var(--red-d),0 22px 30px -12px rgba(224,49,39,.85)}
.btn-dark{background:var(--ink);color:var(--gold);box-shadow:0 8px 0 #000}
.btn-dark:hover{transform:translateY(-3px)}
.btn-ghost{background:transparent;border-color:var(--ink);color:var(--ink);box-shadow:0 8px 0 rgba(30,21,18,.15)}
.btn-ghost:hover{transform:translateY(-3px);background:var(--ink);color:var(--cream)}
.btn-ghost.light{border-color:rgba(255,255,255,.7);color:#fff;box-shadow:0 8px 0 rgba(0,0,0,.25)}
.btn-ghost.light:hover{background:#fff;color:var(--ink)}
.btn-gold{background:var(--gold);color:var(--ink);box-shadow:0 8px 0 #d79f16}
.btn-gold:hover{transform:translateY(-3px)}
.btn-lg{padding:1.15rem 2rem;font-size:1.02rem}
.btn-block{width:100%}
/* ---------- marquee ---------- */
.marquee{
background:var(--ink);color:var(--cream);overflow:hidden;white-space:nowrap;
border-top:3px solid var(--ink);border-bottom:3px solid var(--ink);
padding:.65rem 0;
}
.marquee.gold{background:var(--gold);color:var(--ink);border-color:var(--ink)}
.marquee-track{display:inline-flex;gap:0;animation:slide 32s linear infinite;will-change:transform}
.marquee span{
display:inline-flex;align-items:center;gap:.9rem;padding:0 1.1rem;
font-weight:900;letter-spacing:.14em;text-transform:uppercase;font-size:.86rem;
}
.marquee .dot{color:var(--red)}
.marquee.gold .dot{color:var(--ink)}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}
/* ---------- nav ---------- */
.nav{
position:sticky;top:0;z-index:60;background:rgba(255,247,236,.88);
backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
border-bottom:2px solid transparent;transition:border-color .2s,box-shadow .2s;
}
.nav.stuck{border-bottom-color:var(--ink);box-shadow:0 10px 30px -22px rgba(30,21,18,.6)}
.nav-inner{display:flex;align-items:center;gap:1rem;padding:.7rem 22px;max-width:1240px;margin:0 auto}
.brand{display:flex;align-items:center;gap:.65rem;margin-right:auto}
.brand-mark{width:46px;height:46px;flex:none;display:grid;place-items:center;background:var(--red);
border-radius:14px;box-shadow:3px 3px 0 var(--ink);transform:rotate(-4deg)}
.brand-text{display:flex;flex-direction:column;line-height:1}
.brand-text strong{font-size:1.06rem;font-weight:900;letter-spacing:-.02em}
.brand-text .loc{font-size:1.06rem;font-weight:900;color:var(--red);letter-spacing:-.02em}
.brand-text em{font-style:normal;font-size:.62rem;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);margin-top:3px;font-weight:800}
.nav-links{display:flex;gap:.25rem;align-items:center}
.nav-links a{padding:.55rem .8rem;border-radius:100px;font-weight:800;font-size:.9rem;transition:background .15s,color .15s}
.nav-links a:hover{background:var(--gold);color:var(--ink)}
.nav-cta{padding:.7rem 1.2rem;font-size:.9rem;box-shadow:0 5px 0 var(--red-d)}
.burger{display:none;width:46px;height:46px;border:2px solid var(--ink);background:var(--gold);border-radius:12px;cursor:pointer;
font-size:1.3rem;line-height:1;align-items:center;justify-content:center}
.mobile-menu{display:none;background:var(--cream);border-top:2px solid var(--ink);padding:1rem 22px 1.4rem}
.mobile-menu.open{display:block}
.mobile-menu a{display:block;padding:.75rem .2rem;font-weight:900;font-size:1.05rem;border-bottom:1px dashed var(--cream-3)}
.mobile-menu .btn{margin-top:1rem;width:100%}
@media(max-width:900px){
.nav-links,.nav-cta{display:none}
.burger{display:flex}
}
/* ---------- hero ---------- */
.hero{padding:clamp(2rem,5vw,4rem) 0 clamp(2.2rem,5vw,3.6rem);overflow:hidden}
.hero-grid{display:grid;grid-template-columns:1.04fr .96fr;gap:clamp(1.5rem,4vw,3rem);align-items:center}
.hero h1{margin-bottom:.35rem}
.h1-k{display:block;color:var(--ink)}
.h1-l{
display:block;color:var(--red);position:relative;letter-spacing:-.04em;
text-shadow:5px 5px 0 var(--gold);
}
.h1-l span{position:relative;z-index:2}
.h1-l::after{
content:"";position:absolute;left:-6px;right:-6px;bottom:6px;height:16px;background:var(--ink);
transform:rotate(-1.2deg);z-index:1;opacity:.14;border-radius:4px;
}
.hero-sub{font-size:clamp(1.05rem,2vw,1.3rem);font-weight:800;color:var(--ink);margin:.2rem 0 1rem}
.hero-sub b{color:var(--red)}
.hero p.lead{margin-bottom:1.6rem}
.cta-row{display:flex;flex-wrap:wrap;gap:.9rem;margin-bottom:1.5rem}
.trust{display:flex;align-items:center;gap:.85rem;flex-wrap:wrap}
.stars{color:var(--gold);font-size:1.12rem;letter-spacing:2px;text-shadow:0 2px 0 rgba(30,21,18,.25)}
.trust small{display:block;color:var(--muted);font-weight:700;font-size:.82rem}
.badges{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:1.4rem}
.badge-pill{font-size:.75rem;font-weight:900;letter-spacing:.06em;text-transform:uppercase;
border:2px solid var(--ink);border-radius:100px;padding:.34rem .72rem;background:#fff}
.badge-pill.v{background:#E7F5E5;color:#27662b}
.badge-pill.g{background:#FFF1CE}
.hero-art{position:relative;display:grid;place-items:center;min-height:340px}
.art-blob{
position:absolute;width:min(430px,88%);aspect-ratio:1;border-radius:50%;
background:radial-gradient(circle at 35% 30%,#FFE9A8,var(--gold) 45%,#F2A33A 100%);
box-shadow:inset 0 -18px 40px rgba(180,90,10,.25);
}
.art-blob::after{
content:"";position:absolute;inset:-14px;border-radius:50%;
border:3px dashed rgba(30,21,18,.25);
}
.taco-wrap{position:relative;z-index:2;width:min(430px,92%);animation:float 5.5s ease-in-out infinite}
@keyframes float{0%,100%{transform:translateY(-8px) rotate(-6deg)}50%{transform:translateY(10px) rotate(-2deg)}}
.sticker{
position:absolute;z-index:3;background:var(--red);color:#fff;font-weight:900;
padding:.7rem 1.05rem;border-radius:18px;box-shadow:4px 5px 0 var(--ink);
font-size:.82rem;line-height:1.15;text-transform:uppercase;letter-spacing:.04em;text-align:center;
}
.sticker.s1{top:2%;left:-4%;transform:rotate(-9deg)}
.sticker.s2{bottom:6%;right:-3%;transform:rotate(7deg);background:var(--ink);color:var(--gold)}
.float-item{position:absolute;z-index:3;font-size:2rem;animation:bob 4s ease-in-out infinite}
@keyframes bob{0%,100%{transform:translateY(0) rotate(0)}50%{transform:translateY(-14px) rotate(12deg)}}
.fi1{top:12%;right:8%}
.fi2{bottom:20%;left:2%;animation-delay:.7s}
.fi3{top:44%;left:-6%;animation-delay:1.3s;font-size:1.6rem}
@media(max-width:860px){
.hero-grid{grid-template-columns:1fr}
.hero-art{order:-1;min-height:290px}
.sticker.s1{left:2%}
.sticker.s2{right:2%}
}
/* stats strip */
.stats{background:var(--ink);color:var(--cream);padding:2.1rem 0}
.stats-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem;text-align:center}
.stat b{display:block;font-size:clamp(1.7rem,4vw,2.5rem);color:var(--gold);font-weight:900;line-height:1}
.stat span{font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;color:#CBB6A6;font-weight:800}
@media(max-width:640px){.stats-grid{grid-template-columns:repeat(2,1fr);gap:1.6rem}}
/* ---------- section base ---------- */
.sec{padding:clamp(3.4rem,7vw,5.6rem) 0}
.sec-head{max-width:760px;margin-bottom:2.6rem}
.sec-head.center{margin-left:auto;margin-right:auto}
.dark{background:var(--ink);color:var(--cream)}
.dark h1,.dark h2,.dark h3{color:#fff}
.dark .lead{color:#D8C7B8}
.dark .muted{color:#B7A395}
/* ---------- menu ---------- */
.filters{display:flex;flex-wrap:wrap;gap:.55rem;margin-bottom:2rem;justify-content:center}
.chip{
border:2px solid var(--ink);background:#fff;color:var(--ink);border-radius:100px;
padding:.5rem 1.05rem;font-weight:900;font-size:.84rem;letter-spacing:.05em;text-transform:uppercase;cursor:pointer;
transition:.18s;box-shadow:0 5px 0 rgba(30,21,18,.14)
}
.chip:hover{transform:translateY(-2px)}
.chip.active{background:var(--ink);color:var(--gold)}
.menu-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(245px,1fr));gap:1.35rem}
.card{
background:#fff;border:2px solid var(--ink);border-radius:var(--radius);padding:1rem;
box-shadow:6px 6px 0 var(--ink);display:flex;flex-direction:column;position:relative;
transition:transform .22s cubic-bezier(.2,.9,.3,1.3),box-shadow .22s;
animation:pop .35s backwards;
}
@keyframes pop{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}
.card:hover{transform:translateY(-6px) rotate(-.5deg);box-shadow:10px 14px 0 var(--ink)}
.card.hidden{display:none}
.thumb{
height:132px;border-radius:16px;display:grid;place-items:center;margin-bottom:.9rem;position:relative;overflow:hidden;
background:radial-gradient(circle at 50% 120%,var(--cream-3),var(--cream-2));
border:2px solid var(--ink);
}
.thumb svg{width:96px;height:96px;filter:drop-shadow(0 8px 8px rgba(30,21,18,.25));transition:transform .3s}
.card:hover .thumb svg{transform:scale(1.08) rotate(-4deg)}
.ribbon{
position:absolute;top:10px;left:-6px;background:var(--red);color:#fff;font-size:.64rem;font-weight:900;
letter-spacing:.1em;text-transform:uppercase;padding:.3rem .7rem;border-radius:0 100px 100px 0;box-shadow:2px 2px 0 var(--ink)
}
.card h3{margin-bottom:.25rem;display:flex;align-items:baseline;gap:.4rem;flex-wrap:wrap}
.card h3 .tag{font-size:.6rem;font-weight:900;letter-spacing:.09em;text-transform:uppercase;background:#E7F5E5;color:#27662b;border:1.5px solid #9CCB96;padding:.12rem .4rem;border-radius:6px}
.card p{font-size:.9rem;color:var(--muted);margin-bottom:.75rem;flex:1}
.heat{display:inline-flex;align-items:center;gap:.3rem;margin-right:.7rem}
.heat i{width:9px;height:9px;border-radius:50%;background:var(--cream-3);display:block;border:1.5px solid rgba(30,21,18,.2)}
.heat i.on{background:var(--red);border-color:var(--red-d)}
.card-foot{display:flex;align-items:center;justify-content:space-between;border-top:2px dashed var(--cream-3);padding-top:.7rem;margin-top:.2rem}
.price{font-size:1.35rem;font-weight:900;color:var(--ink)}
.price small{font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);display:block;font-weight:800}
.add-btn{
width:44px;height:44px;border-radius:50%;border:2px solid var(--ink);background:var(--gold);
font-size:1.5rem;font-weight:900;line-height:1;cursor:pointer;display:grid;place-items:center;
transition:.16s;box-shadow:3px 3px 0 var(--ink)
}
.add-btn:hover{background:var(--red);color:#fff;transform:rotate(90deg)}
.add-btn:active{box-shadow:1px 1px 0 var(--ink);transform:translateY(2px)}
/* ---------- builder ---------- */
.builder{display:grid;grid-template-columns:.95fr 1.05fr;gap:clamp(1.5rem,4vw,3rem);align-items:center}
.build-stage{
border:2px solid rgba(255,255,255,.22);border-radius:28px;padding:1.4rem;text-align:center;position:relative;
background:radial-gradient(circle at 50% 15%,rgba(255,201,60,.18),transparent 62%),rgba(255,255,255,.05);
}
.build-stage .taco-svg{width:min(360px,84%);filter:drop-shadow(0 22px 22px rgba(0,0,0,.45))}
.heat-label{font-size:1.5rem;font-weight:900;color:var(--gold);text-transform:uppercase;margin:.4rem 0 .1rem;letter-spacing:-.01em}
.heat-desc{color:#C8B6A6;font-size:.94rem;margin:0 0 1rem}
.slider-wrap{background:rgba(255,255,255,.07);border:1.5px solid rgba(255,255,255,.16);border-radius:18px;padding:1rem 1.1rem;margin-bottom:1rem}
.slider-top{display:flex;justify-content:space-between;font-weight:900;font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;color:#D9C6B4;margin-bottom:.6rem}
input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:100px;outline:none;
background:linear-gradient(90deg,#FFC93C,#F2751A,#E03127)}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:30px;height:30px;border-radius:50%;background:#fff;border:4px solid var(--ink);cursor:grab;box-shadow:0 4px 10px rgba(0,0,0,.4)}
input[type=range]::-moz-range-thumb{width:24px;height:24px;border-radius:50%;background:#fff;border:4px solid var(--ink);cursor:grab}
.build-price{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-top:.4rem}
.build-price .p{font-size:2.2rem;font-weight:900;color:var(--gold);line-height:1}
.sauce-list{display:grid;grid-template-columns:repeat(2,1fr);gap:.7rem;margin-top:1.2rem}
.sauce{background:rgba(255,255,255,.06);border:1.5px solid rgba(255,255,255,.14);border-radius:14px;padding:.7rem .8rem;display:flex;gap:.65rem;align-items:center}
.sauce b{display:block;font-size:.86rem;font-weight:900}
.sauce span{font-size:.74rem;color:#B7A395}
.sauce .dotc{width:30px;height:30px;border-radius:50%;flex:none;border:2px solid rgba(255,255,255,.35)}
@media(max-width:860px){.builder{grid-template-columns:1fr}.sauce-list{grid-template-columns:1fr}}
/* ---------- story ---------- */
.story-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(1.6rem,4vw,3rem);align-items:center}
.story-art{position:relative}
.story-art svg{width:100%;height:auto;filter:drop-shadow(0 26px 26px rgba(30,21,18,.3))}
.values{display:grid;grid-template-columns:repeat(2,1fr);gap:1rem;margin-top:1.6rem}
.value{border:2px solid var(--ink);border-radius:16px;padding:1rem;background:#fff;box-shadow:5px 5px 0 var(--ink)}
.value .ic{font-size:1.5rem;margin-bottom:.35rem}
.value b{display:block;font-weight:900;font-size:1rem}
.value span{font-size:.85rem;color:var(--muted)}
@media(max-width:860px){.story-grid{grid-template-columns:1fr}.values{grid-template-columns:1fr 1fr}}
@media(max-width:420px){.values{grid-template-columns:1fr}}
.founder{
margin-top:1.6rem;display:flex;gap:1rem;align-items:center;background:var(--cream-2);
border-left:6px solid var(--red);padding:1rem 1.1rem;border-radius:0 16px 16px 0
}
.avatar{width:58px;height:58px;border-radius:50%;background:linear-gradient(135deg,var(--red),var(--orange));color:#fff;
display:grid;place-items:center;font-weight:900;font-size:1.2rem;flex:none;box-shadow:3px 3px 0 var(--ink)}
.founder b{display:block}
.founder span{font-size:.86rem;color:var(--muted)}
/* ---------- reviews ---------- */
.rev-track{display:flex;transition:transform .55s cubic-bezier(.4,.1,.2,1)}
.rev-slide{min-width:100%;padding:.4rem}
.rev{
background:#fff;border:2px solid var(--ink);border-radius:26px;padding:clamp(1.4rem,3vw,2.2rem);
box-shadow:8px 8px 0 var(--gold);max-width:780px;margin:0 auto;position:relative
}
.rev::before{content:"“";position:absolute;top:-.2rem;left:1.2rem;font-size:6rem;line-height:1;color:var(--cream-3);font-family:Georgia,serif}
.rev p{font-size:clamp(1.05rem,2vw,1.3rem);font-weight:700;position:relative}
.rev-by{display:flex;align-items:center;gap:.8rem;margin-top:1.2rem}
.rev-by b{display:block;font-size:.95rem}
.rev-by span{font-size:.78rem;color:var(--muted);letter-spacing:.06em;text-transform:uppercase;font-weight:800}
.dots{display:flex;gap:.5rem;justify-content:center;margin-top:1.6rem}
.dot-btn{width:12px;height:12px;border-radius:50%;border:2px solid var(--ink);background:transparent;cursor:pointer;padding:0;transition:.2s}
.dot-btn.active{background:var(--red);width:30px;border-radius:100px}
.rev-arrows{display:flex;gap:.6rem;justify-content:center;margin-top:.9rem}
.rev-arrows button{width:46px;height:46px;border-radius:50%;border:2px solid var(--ink);background:#fff;cursor:pointer;font-weight:900;font-size:1.1rem;transition:.18s}
.rev-arrows button:hover{background:var(--gold)}
/* ---------- catering ---------- */
.cater-grid{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(1.6rem,4vw,3rem);align-items:start}
.form-card{background:#fff;border:2px solid var(--ink);border-radius:26px;padding:clamp(1.3rem,3vw,2rem);box-shadow:8px 8px 0 var(--ink)}
.field{margin-bottom:1rem}
.field label{display:block;font-size:.76rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase;margin-bottom:.35rem;color:var(--ink-2)}
.field input,.field select,.field textarea{
width:100%;padding:.85rem 1rem;border:2px solid var(--ink);border-radius:14px;background:var(--cream);
font-family:inherit;font-size:1rem;font-weight:600;color:var(--ink);transition:.15s
}
.field textarea{min-height:92px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;box-shadow:0 0 0 4px rgba(255,201,60,.55);background:#fff}
.two{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
.err{color:var(--red);font-size:.8rem;font-weight:800;margin-top:.3rem;display:none}
.err.show{display:block}
.form-ok{display:none;background:#E7F5E5;border:2px solid #3F9A45;border-radius:16px;padding:1.1rem;font-weight:800;color:#27662b}
.form-ok.show{display:block;animation:pop .35s}
.perk{display:flex;gap:.7rem;align-items:flex-start;margin-bottom:.9rem}
.perk .tick{width:26px;height:26px;border-radius:50%;background:var(--gold);border:2px solid var(--ink);display:grid;place-items:center;flex:none;font-size:.8rem;font-weight:900}
.perk b{display:block;font-size:.98rem}
.perk span{font-size:.87rem;color:var(--muted)}
@media(max-width:860px){.cater-grid{grid-template-columns:1fr}.two{grid-template-columns:1fr}}
/* ---------- locations ---------- */
.loc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.2rem;margin-bottom:2.2rem}
.loc{border:2px solid var(--ink);border-radius:20px;background:#fff;padding:1.2rem;box-shadow:6px 6px 0 var(--ink);transition:.22s}
.loc:hover{transform:translateY(-5px)}
.loc .live{display:inline-flex;align-items:center;gap:.4rem;font-size:.68rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase;
background:#E7F5E5;color:#27662b;padding:.25rem .6rem;border-radius:100px;border:1.5px solid #9CCB96;margin-bottom:.6rem}
.loc .live i{width:8px;height:8px;border-radius:50%;background:#3F9A45;animation:pulse 1.6s infinite}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.8)}}
.loc h3{margin-bottom:.2rem}
.loc address{font-style:normal;font-size:.88rem;color:var(--muted);margin-bottom:.7rem}
.hours{font-size:.85rem;border-top:2px dashed var(--cream-3);padding-top:.6rem;margin-bottom:.9rem}
.hours div{display:flex;justify-content:space-between}
.hours b{color:var(--red)}
@media(max-width:860px){.loc-grid{grid-template-columns:1fr}}
.map-wrap{border:2px solid var(--ink);border-radius:24px;overflow:hidden;box-shadow:8px 8px 0 var(--ink)}
.map-wrap svg{display:block;width:100%;height:auto}
/* ---------- gallery ---------- */
.gal{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.9rem}
.gal div{aspect-ratio:1;border-radius:18px;border:2px solid var(--ink);display:grid;place-items:center;font-size:2.6rem;
box-shadow:4px 4px 0 var(--ink);transition:.25s;position:relative;overflow:hidden}
.gal div:hover{transform:rotate(-2deg) scale(1.04)}
.gal .g1{background:linear-gradient(135deg,#FFD97A,#F2751A)}
.gal .g2{background:linear-gradient(135deg,#FF9B8A,#E03127)}
.gal .g3{background:linear-gradient(135deg,#BFE8A6,#3F9A45)}
.gal .g4{background:linear-gradient(135deg,#E7C7F0,#8E2F6E)}
.gal .g5{background:linear-gradient(135deg,#FFF0C2,#FFC93C)}
.gal .g6{background:linear-gradient(135deg,#BBD9F0,#2E6E8E)}
.handle{display:inline-flex;align-items:center;gap:.6rem;font-weight:900;margin-top:1.2rem;color:var(--red)}
/* ---------- faq ---------- */
.faq{max-width:820px;margin:0 auto}
details{background:#fff;border:2px solid var(--ink);border-radius:18px;margin-bottom:.9rem;box-shadow:5px 5px 0 var(--cream-3);overflow:hidden;transition:.2s}
details[open]{box-shadow:6px 6px 0 var(--gold)}
summary{cursor:pointer;list-style:none;padding:1.05rem 1.3rem;font-weight:900;font-size:1.02rem;display:flex;justify-content:space-between;gap:1rem;align-items:center}
summary::-webkit-details-marker{display:none}
summary::after{content:"+";font-size:1.5rem;line-height:1;color:var(--red);flex:none}
details[open] summary::after{content:"–"}
details p{padding:0 1.3rem 1.2rem;margin:0;color:var(--muted)}
/* ---------- cta band ---------- */
.cta-band{background:var(--red);color:#fff;padding:clamp(2.6rem,6vw,4.4rem) 0;text-align:center;position:relative;overflow:hidden}
.cta-band::before{content:"";position:absolute;inset:0;background:repeating-linear-gradient(135deg,rgba(255,255,255,.07) 0 22px,transparent 22px 44px)}
.cta-band h2{color:#fff;position:relative;text-shadow:4px 4px 0 rgba(0,0,0,.22)}
.cta-band p{color:#FFE3C7;position:relative;max-width:56ch;margin:0 auto 1.6rem;font-weight:700}
.cta-band .btn-row{display:flex;gap:.9rem;justify-content:center;flex-wrap:wrap;position:relative}
/* ---------- footer ---------- */
footer{background:var(--ink);color:#CBB6A6;padding:3.4rem 0 1.6rem}
.f-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1.3fr;gap:2rem}
footer h4{color:#fff;font-size:.78rem;letter-spacing:.16em;text-transform:uppercase;margin-bottom:.9rem}
footer a{display:block;padding:.28rem 0;font-size:.93rem;transition:.15s}
footer a:hover{color:var(--gold)}
.f-logo{display:flex;align-items:center;gap:.6rem;margin-bottom:1rem}
.f-logo .brand-mark{background:var(--red)}
.f-logo b{color:#fff;font-size:1.15rem;letter-spacing:-.01em}
.news{display:flex;gap:.5rem;margin-top:.6rem}
.news input{flex:1;padding:.8rem 1rem;border-radius:100px;border:2px solid #4A3B33;background:#2A201B;color:#fff;font-family:inherit;font-size:.92rem}
.news input:focus{outline:none;border-color:var(--gold)}
.news button{border:2px solid var(--gold);background:var(--gold);color:var(--ink);border-radius:100px;padding:.8rem 1.1rem;font-weight:900;cursor:pointer;transition:.18s}
.news button:hover{background:#fff;border-color:#fff}
.news-ok{display:none;margin-top:.7rem;color:#8FD98F;font-weight:800;font-size:.88rem}
.news-ok.show{display:block}
.social{display:flex;gap:.6rem;margin-top:1.2rem}
.social a{width:42px;height:42px;border-radius:12px;border:2px solid #4A3B33;display:grid;place-items:center;padding:0;transition:.2s}
.social a:hover{background:var(--red);border-color:var(--red);transform:translateY(-3px)}
.f-bottom{border-top:1px solid #3A2C24;margin-top:2.4rem;padding-top:1.2rem;display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;font-size:.84rem}
@media(max-width:860px){.f-grid{grid-template-columns:1fr 1fr}}
@media(max-width:520px){.f-grid{grid-template-columns:1fr}}
/* ---------- cart ---------- */
.cart-pill{
position:fixed;right:16px;bottom:16px;z-index:70;display:none;align-items:center;gap:.6rem;
background:var(--ink);color:var(--gold);border:2px solid var(--gold);border-radius:100px;
padding:.7rem 1.1rem;font-weight:900;cursor:pointer;box-shadow:0 12px 26px -10px rgba(0,0,0,.6)
}
.cart-pill.show{display:flex;animation:pop .3s}
.cart-pill .cnt{background:var(--red);color:#fff;border-radius:50%;width:24px;height:24px;display:grid;place-items:center;font-size:.78rem}
.drawer{
position:fixed;top:0;right:0;bottom:0;width:min(380px,92vw);background:var(--cream);z-index:90;
transform:translateX(105%);transition:transform .35s cubic-bezier(.4,.1,.2,1);border-left:3px solid var(--ink);
display:flex;flex-direction:column;box-shadow:-20px 0 50px rgba(0,0,0,.25)
}
.drawer.open{transform:none}
.drawer-head{display:flex;justify-content:space-between;align-items:center;padding:1.1rem 1.2rem;border-bottom:2px solid var(--ink);background:var(--gold)}
.drawer-head b{font-size:1.1rem;font-weight:900;text-transform:uppercase}
.drawer-close{background:var(--ink);color:#fff;border:none;border-radius:50%;width:36px;height:36px;font-size:1.1rem;cursor:pointer;font-weight:900}
.drawer-body{flex:1;overflow:auto;padding:1rem 1.2rem}
.dline{display:flex;justify-content:space-between;gap:.6rem;padding:.6rem 0;border-bottom:1px dashed var(--cream-3);font-weight:700;font-size:.94rem}
.dline button{background:none;border:none;color:var(--red);font-weight:900;cursor:pointer;font-size:.85rem}
.drawer-foot{padding:1.1rem 1.2rem;border-top:2px solid var(--ink);background:#fff}
.drawer-total{display:flex;justify-content:space-between;font-weight:900;font-size:1.2rem;margin-bottom:.8rem}
.toast{
position:fixed;left:16px;bottom:16px;z-index:95;background:var(--ink);color:var(--cream);
padding:.85rem 1.1rem;border-radius:14px;border-left:6px solid var(--gold);font-weight:800;font-size:.9rem;
transform:translateY(160%);transition:transform .35s;box-shadow:0 16px 30px -14px rgba(0,0,0,.6);max-width:80vw
}
.toast.show{transform:none}
.backdrop{position:fixed;inset:0;background:rgba(30,21,18,.5);z-index:85;opacity:0;pointer-events:none;transition:.3s;backdrop-filter:blur(2px)}
.backdrop.show{opacity:1;pointer-events:auto}
.reveal{opacity:0;transform:translateY(26px);transition:opacity .7s cubic-bezier(.2,.7,.3,1),transform .7s cubic-bezier(.2,.7,.3,1)}
.reveal.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
*{animation-duration:.001ms !important;transition-duration:.001ms !important}
.reveal{opacity:1;transform:none}
}
</style>
</head>
<body id="top">
<!-- ======================= MARQUEE TOP ======================= -->
<div class="marquee" aria-hidden="true">
<div class="marquee-track" id="mTrack1"></div>
</div>
<!-- ======================= NAV ======================= -->
<header class="nav" id="nav">
<div class="nav-inner">
<a class="brand" href="#top" aria-label="Kimchi Loco home">
<span class="brand-mark">
<svg viewBox="0 0 100 100" width="34" height="34" aria-hidden="true">
<path d="M18 76 L18 58 C18 44 33 34 50 34 C67 34 82 44 82 58 L82 76 Z" fill="#FFC93C"/>
<path d="M22 60 C22 38 38 26 50 26 C64 26 80 38 80 60 Z" fill="#E03127"/>
<path d="M26 52 L36 44 L46 52 L56 44 L66 52 L74 46" stroke="#3F9A45" stroke-width="7" fill="none" stroke-linecap="round"/>
<path d="M18 76 L82 76" stroke="#1E1512" stroke-width="5" stroke-linecap="round"/>
</svg>
</span>
<span class="brand-text">
<strong>KIMCHI</strong><span class="loc">LOCO</span>
<em>Korean-Mexican Tacos</em>
</span>
</a>
<nav class="nav-links">
<a href="#menu">Menu</a>
<a href="#build">Build your taco</a>
<a href="#story">Our story</a>
<a href="#reviews">Reviews</a>
<a href="#catering">Catering</a>
<a href="#find">Find us</a>
</nav>
<a class="btn btn-red nav-cta" href="tel:+15550184264">📞 Order Now</a>
<button class="burger" id="burger" aria-label="Open menu" aria-expanded="false">☰</button>
</div>
<div class="mobile-menu" id="mobileMenu">
<a href="#menu">Menu</a>
<a href="#build">Build your taco</a>
<a href="#story">Our story</a>
<a href="#reviews">Reviews</a>
<a href="#catering">Catering</a>
<a href="#find">Find us</a>
<a class="btn btn-red" href="tel:+15550184264">📞 Call to order</a>
</div>
</header>
<!-- ======================= HERO ======================= -->
<section class="hero">
<div class="container hero-grid">
<div class="hero-copy">
<span class="eyebrow">★ Est. 2019 · Seoul-meets-Tijuana</span>
<h1>
<span class="h1-k">Kimchi</span>
<span class="h1-l"><span>Loco</span></span>
</h1>
<p class="hero-sub">Slow-braised <b>carnitas</b>, sizzling <b>bulgogi</b>, house-fermented <b>kimchi</b> — tucked into tortillas pressed to order.</p>
<p class="lead">Three trucks, one griddle, zero regrets. We marinate for 24 hours, ferment our kimchi for three days, and fry everything to order. If you don't leave with sauce on your shirt, we haven't done our job.</p>
<div class="cta-row">
<a class="btn btn-red btn-lg" href="#menu">See the menu 🌮</a>
<a class="btn btn-ghost btn-lg" href="#find">📍 Find the truck</a>
</div>
<div class="trust">
<span class="stars">★★★★★</span>
<small><b style="color:var(--ink);font-size:.95rem">4.9 / 5</b> — 2,400+ taco addicts<br>Google · Yelp · Instagram</small>
</div>
<div class="badges">
<span class="badge-pill v">100% vegan options</span>
<span class="badge-pill g">Gluten-free tortillas</span>
<span class="badge-pill g">Halal chicken</span>
<span class="badge-pill g">Sauces made in-house</span>
</div>
</div>
<div class="hero-art">
<div class="art-blob"></div>
<div class="float-item fi1">🌶️</div>
<div class="float-item fi2">🥬</div>
<div class="float-item fi3">🍋</div>
<div class="sticker s1">Fresh tortillas<br>pressed daily 🔥</div>
<div class="sticker s2">Secret gochujang<br>cream sauce</div>
<div class="taco-wrap" id="heroTaco"></div>
</div>
</div>
</section>
<!-- ======================= STATS ======================= -->
<div class="stats">
<div class="container stats-grid">
<div class="stat"><b>85k+</b><span>Tacos served</span></div>
<div class="stat"><b>14</b><span>Signature tacos</span></div>
<div class="stat"><b>3</b><span>Trucks on the road</span></div>
<div class="stat"><b>3 days</b><span>Kimchi fermented</span></div>
</div>
</div>
<!-- ======================= MARQUEE MID ======================= -->
<div class="marquee gold" aria-hidden="true">
<div class="marquee-track" id="mTrack2"></div>
</div>
<!-- ======================= MENU ======================= -->
<section class="sec" id="menu">
<div class="container">
<div class="sec-head center reveal">
<span class="eyebrow">The Loco Lineup</span>
<h2>Pick your fighter</h2>
<p class="lead">Every taco is built to order on a hot plancha. Prices include two soft corn tortillas unless noted — because one is never enough.</p>
</div>
<div class="filters" id="filters">
<button class="chip active" data-cat="all">Everything</button>
<button class="chip" data-cat="tacos">Tacos</button>
<button class="chip" data-cat="bowls">Bowls</button>
<button class="chip" data-cat="sides">Sides</button>
<button class="chip" data-cat="drinks">Drinks</button>
</div>
<div class="menu-grid" id="menuGrid"></div>
<p class="center muted" style="margin-top:1.8rem;font-size:.9rem">* Add-ons: extra protein +$2 · extra crema +$0.50 · guacamole +$1.50 · fried egg +$1.00</p>
</div>
</section>
<!-- ======================= BUILDER ======================= -->
<section class="sec dark" id="build">
<div class="container">
<div class="sec-head reveal">
<span class="eyebrow dark">Build your heat</span>
<h2>How spicy can we make it?</h2>
<p class="lead">Drag the slider. We'll load the jalapeños, the gochujang and the extra napkins. No judgment — our staff has taken down a 5 on a dare.</p>
</div>
<div class="builder">
<div class="build-stage reveal" id="buildStage"></div>
<div class="reveal">
<div class="slider-wrap">
<div class="slider-top"><span>Heat level</span><span id="heatNum">2 / 5</span></div>
<input type="range" id="heat" min="0" max="5" step="1" value="2" aria-label="Spice level">
</div>
<div class="heat-label" id="heatLabel">Medium</div>
<p class="heat-desc" id="heatDesc"></p>
<div class="build-price">
<div>
<div class="p" id="buildPrice">$5.75</div>
<small style="color:#B7A395;font-weight:800;letter-spacing:.1em;text-transform:uppercase;font-size:.72rem">One loaded taco · 2 tortillas</small>
</div>
<button class="btn btn-gold" id="buildAdd">Add to my order 🛒</button>
</div>
<div class="sauce-list">
<div class="sauce"><span class="dotc" style="background:linear-gradient(135deg,#E03127,#8E150F)"></span><div><b>Gochujang Cream</b><span>Sweet heat · our signature</span></div></div>
<div class="sauce"><span class="dotc" style="background:linear-gradient(135deg,#FFF3D6,#E8D3A6)"></span><div><b>Ssam Cream</b><span>Sesame, bright & cool</span></div></div>
<div class="sauce"><span class="dotc" style="background:linear-gradient(135deg,#FFC93C,#E88A0B)"></span><div><b>Kimchi Butter</b><span>Rich, funky, tangy</span></div></div>
<div class="sauce"><span class="dotc" style="background:linear-gradient(135deg,#FFEFA8,#B9D94B)"></span><div><b>Yuzu Salsa Verde</b><span>Citrusy, zero mercy</span></div></div>
</div>
</div>
</div>
</div>
</section>
<!-- ======================= STORY ======================= -->
<section class="sec" id="story">
<div class="container story-grid">
<div class="story-art reveal" id="truckArt"></div>
<div class="reveal">
<span class="eyebrow">Two cultures, one griddle</span>
<h2>We met in a food truck queue</h2>
<p class="lead">Danny grew up flipping <em>bingsoo</em> at his abuela's Seoul kitchen. Mina spent her teens on a taco-truck route in Tijuana. One slow night in 2018, they traded recipes on a napkin — bulgogi folded into a warm tortilla, kimchi turned into slaw — and Kimchi Loco was born out of that napkin.</p>
<p class="muted">Three trucks later we're still chasing the same idea: food that respects where it comes from, and never apologises for being loud.</p>
<div class="values">
<div class="value"><div class="ic">🫓</div><b>Tortillas pressed to order</b><span>Nixtamal corn, ground weekly, never reheated.</span></div>
<div class="value"><div class="ic">🥬</div><b>Kimchi fermented 3 days</b><span>Cabbage, daikon, gochugaru, patience.</span></div>
<div class="value"><div class="ic">🔥</div><b>Sauce from scratch</b><span>Four house sauces, zero shortcuts.</span></div>
<div class="value"><div class="ic">♻️</div><b>Zero-waste kitchen</b><span>Kimchi stems become slaw. Nothing wasted.</span></div>
</div>
<div class="founder">
<div class="avatar">M&D</div>
<div><b>Mina Park & Danny Reyes</b><span>Founders · still working the plancha on Fridays</span></div>
</div>
</div>
</div>
</section>
<!-- ======================= REVIEWS ======================= -->
<section class="sec" style="background:var(--cream-2)" id="reviews">
<div class="container">
<div class="sec-head center reveal">
<span class="eyebrow">Word on the street</span>
<h2>4.9 stars, 2,400 reviews</h2>
<p class="lead">We don't pay for reviews. We just make very loud, very good tacos.</p>
</div>
<div class="rev-track" id="revTrack"></div>
<div class="dots" id="revDots"></div>
<div class="rev-arrows">
<button id="prevRev" aria-label="Previous review">←</button>
<button id="nextRev" aria-label="Next review">→</button>
</div>
</div>
</section>
<!-- ======================= CATERING ======================= -->
<section class="sec" id="catering">
<div class="container cater-grid">
<div class="reveal">
<span class="eyebrow">Feed a crowd</span>
<h2>Catering that actually shows up</h2>
<p class="lead">Office lunches, weddings, festivals, album releases, 2am studio sessions. We bring the truck (or the taco bar) and handle everything else.</p>
<div style="margin-top:1.4rem">
<div class="perk"><span class="tick">✓</span><div><b>Full taco bar setup</b><span>Two build-your-own stations, planters, warmers, napkins, sauce flight.</span></div></div>
<div class="perk"><span class="tick">✓</span><div><b>Menu built for you</b><span>Choose 4–8 tacos, bowls and sides. Veggie & halal options included.</span></div></div>
<div class="perk"><span class="tick">✓</span><div><b>We handle the crowd</b><span>Staff, serving, clean-up. You enjoy the party.</span></div></div>
<div class="perk"><span class="tick">✓</span><div><b>Live-fire add-on</b><span>Chef's bulkogi or a flaming guac bomb for the big moments.</span></div></div>
</div>
<div class="badges" style="margin-top:1.2rem">
<span class="badge-pill">From 25 guests</span>
<span class="badge-pill">48-hour notice</span>
<span class="badge-pill">5.0 catering rating</span>
</div>
</div>
<div class="form-card reveal">
<h3 style="margin-bottom:.3rem">Request a quote</h3>
<p class="muted" style="font-size:.9rem">Tell us the vibe. We reply within 2 hours during service hours (11am–9pm).</p>
<form id="caterForm" novalidate>
<div class="field">
<label for="cName">Your name</label>
<input id="cName" type="text" placeholder="Alex Rivera" required>
<div class="err" id="eName">We need a name to put on the invoice 🌮</div>
</div>
<div class="two">
<div class="field">
<label for="cEmail">Email</label>
<input id="cEmail" type="email" placeholder="you@company.com" required>
<div class="err" id="eEmail">That email looks a little spicy-broken.</div>
</div>
<div class="field">
<label for="cPhone">Phone</label>
<input id="cPhone" type="tel" placeholder="(555) 018-4264" required>
<div class="err" id="ePhone">A phone number, please — just in case.</div>
</div>
</div>
<div class="two">
<div class="field">
<label for="cType">Event type</label>
<select id="cType">
<option>Office lunch</option>
<option>Party / celebration</option>
<option>Wedding</option>
<option>Festival / market</option>
<option>Brand activation</option>
<option>Just because</option>
</select>
</div>
<div class="field">
<label for="cGuests">Guest count</label>
<select id="cGuests">
<option>25–50</option><option>50–100</option><option>100–250</option><option>250+</option>
</select>
</div>
</div>
<div class="field">
<label for="cDate">Date & location</label>
<input id="cDate" type="text" placeholder="Sat, June 14 — 12pm, 220 Pine St" required>
<div class="err" id="eDate">When and where? We'll bring the griddle.</div>
</div>
<button class="btn btn-red btn-block btn-lg" type="submit">Send my request 🔥</button>
</form>
<div class="form-ok" id="caterOk">🎉 Request received! Our catering crew is already firing up the planchas — expect a reply within 2 hours.</div>
</div>
</div>
</section>
<!-- ======================= LOCATIONS ======================= -->
<section class="sec" id="find" style="background:var(--cream-2)">
<div class="container">
<div class="sec-head center reveal">
<span class="eyebrow">Find the loco</span>
<h2>Three trucks. Zero wrong turns.</h2>
<p class="lead">We post daily locations on Instagram at 10am. Or just follow the smell of gochujang.</p>
</div>
<div class="loc-grid">
<div class="loc reveal">
<span class="live"><i></i> Open now · until 9pm</span>
<h3>Downtown Lot</h3>
<address>220 Pine St (under the old clock tower)</address>
<div class="hours"><div><span>Mon–Thu</span><b>11:00 – 20:00</b></div><div><span>Fri–Sat</span><b>11:00 – 23:00</b></div><div><span>Sunday</span><b>12:00 – 19:00</b></div></div>
<a class="btn btn-ghost" style="box-shadow:0 5px 0 rgba(30,21,18,.15)" href="tel:+15550184264">Get directions</a>
</div>
<div class="loc reveal">
<span class="live"><i></i> Open now · until 10pm</span>
<h3>Midtown Plaza</h3>
<address>48th & Market, food court island 3</address>
<div class="hours"><div><span>Tue–Thu</span><b>11:30 – 21:00</b></div><div><span>Fri–Sat</span><b>11:30 – 23:30</b></div><div><span>Sun–Mon</span><b>Closed</b></div></div>
<a class="btn btn-ghost" style="box-shadow:0 5px 0 rgba(30,21,18,.15)" href="tel:+15550184264">Get directions</a>
</div>
<div class="loc reveal">
<span class="live"><i></i> Fri–Sun only</span>
<h3>Riverside Park</h3>
<address>South lawn, next to the taco benches</address>
<div class="hours"><div><span>Fri–Sat</span><b>16:00 – 23:00</b></div><div><span>Sunday</span><b>13:00 – 20:00</b></div><div><span>Mon–Thu</span><b>Closed</b></div></div>
<a class="btn btn-ghost" style="box-shadow:0 5px 0 rgba(30,21,18,.15)" href="tel:+15550184264">Get directions</a>
</div>
</div>
<div class="map-wrap reveal" id="mapArt"></div>
</div>
</section>
<!-- ======================= GALLERY ======================= -->
<section class="sec">
<div class="container">
<div class="sec-head center reveal">
<span class="eyebrow">@kimchiloco.eats</span>
<h2>Tag us. We repost.</h2>
</div>
<div class="gal reveal">
<div class="g1">🌮</div><div class="g2">🌶️</div><div class="g3">🥬</div>
<div class="g4">🍜</div><div class="g5">🧀</div><div class="g6">🥤</div>
</div>
<div class="center"><a class="handle" href="#top">→ Follow @kimchiloco.eats</a></div>
</div>
</section>
<!-- ======================= FAQ ======================= -->
<section class="sec" style="background:var(--cream-2)">
<div class="container">
<div class="sec-head center reveal">
<span class="eyebrow">Before you ask</span>
<h2>Good questions</h2>
</div>
<div class="faq reveal">
<details open><summary>Do you have vegan & vegetarian options?</summary><p>Yes! Our Bibimbap Bowl (no meat, add egg or avocado), Kimchi Fries, Yuzu Salsa Chickenless Tacos and the Kimchi Corn are 100% plant-based. About 30% of our menu is meat-free and we never charge extra for veg swaps.</p></details>
<details><summary>Are your tortillas gluten-free?</summary><p>Our corn tortillas are naturally gluten-free and pressed in-house. We keep a separate griddle for gluten-free orders so there's zero cross-contact. The only gluten on the menu is in our Korean-fried chicken breading and our Yuzu soda bread.</p></details>
<details><summary>Can I order ahead?</summary><p>Yes — call the number above or tap "Order Now" and we'll text you a pickup time. Orders placed 20+ minutes ahead skip the line. We also do delivery through our partners on weekends.</p></details>
<details><summary>Do you cater events?</summary><p>Absolutely. Taco bars start at 25 guests, full truck service at 100+. Send us the details in the catering form and we'll send a quote with menu options within 2 hours.</p></details>
<details><summary>What if I can't handle spicy?</summary><p>Order heat level 0 and you'll get a gentle, buttery-sweet sauce with zero heat. We also offer yuzu salsa verde and ssam cream on the side. Nobody leaves crying — except the people who order level 5 on a dare.</p></details>
</div>
</div>
</section>
<!-- ======================= CTA BAND ======================= -->
<section class="cta-band">
<div class="container">
<h2 class="reveal">Your lunch break is<br>about to get better</h2>
<p class="reveal">Two tacos, a side of kimchi fries and an iced yuzu lemonade. Usually under $15. Usually gone in ten minutes.</p>
<div class="btn-row reveal">
<a class="btn btn-gold btn-lg" href="tel:+15550184264">📞 Call to order</a>
<a class="btn btn-ghost light btn-lg" href="#menu">Browse the menu</a>
</div>
</div>
</section>
<!-- ======================= FOOTER ======================= -->
<footer>
<div class="container">
<div class="f-grid">
<div>
<div class="f-logo">
<span class="brand-mark">
<svg viewBox="0 0 100 100" width="32" height="32" aria-hidden="true">
<path d="M18 76 L18 58 C18 44 33 34 50 34 C67 34 82 44 82 58 L82 76 Z" fill="#FFC93C"/>
<path d="M22 60 C22 38 38 26 50 26 C64 26 80 38 80 60 Z" fill="#E03127"/>
<path d="M26 52 L36 44 L46 52 L56 44 L66 52 L74 46" stroke="#3F9A45" stroke-width="7" fill="none" stroke-linecap="round"/>
<path d="M18 76 L82 76" stroke="#1E1512" stroke-width="5" stroke-linecap="round"/>
</svg>
</span>
<b>KIMCHI LOCO</b>
</div>
<p style="font-size:.93rem;max-width:34ch">Korean-Mexican street tacos, fermented in-house and pressed to order. Seoul heat, Tijuana soul.</p>
<div class="social">
<a href="#top" aria-label="Instagram"><svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#CBB6A6" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17" cy="7" r="1.4" fill="#CBB6A6" stroke="none"/></svg></a>
<a href="#top" aria-label="TikTok"><svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#CBB6A6" stroke-width="2"><path d="M14 4v10a3.5 3.5 0 1 1-3-3.46"/><path d="M14 4c.6 2.6 2.2 4 4.5 4.4"/></svg></a>
<a href="tel:+15550184264" aria-label="Phone"><svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#CBB6A6" stroke-width="2"><path d="M4 4h4l2 5-2.5 1.5a11 11 0 0 0 6 6L15 14l5 2v4a1 1 0 0 1-1.1 1A16 16 0 0 1 3 5.1 1 1 0 0 1 4 4z"/></svg></a>
</div>
</div>
<div>
<h4>Menu</h4>
<a href="#menu">Tacos</a><a href="#menu">Bowls</a><a href="#menu">Sides & fries</a><a href="#menu">Drinks</a><a href="#build">Build your heat</a>
</div>
<div>
<h4>Company</h4>
<a href="#story">Our story</a><a href="#catering">Catering</a><a href="#reviews">Reviews</a><a href="#find">Find us</a><a href="#top">Franchise</a>
</div>
<div>
<h4>Get the good stuff</h4>
<p style="font-size:.9rem;margin-bottom:.5rem">Secret sauces, pop-up locations and a free fountain drink. No spam, we hate spam too.</p>
<form class="news" id="newsForm">
<input type="email" id="newsEmail" placeholder="you@email.com" aria-label="Email address">
<button type="submit">Join</button>
</form>
<div class="news-ok" id="newsOk">You're in! Check your inbox for 10% off your first taco order. 🌮</div>
</div>
</div>
<div class="f-bottom">
<span>© <span id="year"></span> Kimchi Loco Food Truck LLC. All rights reserved. Made with love & gochujang.</span>
<span>Privacy · Terms · Allergens · <a href="tel:+15550184264" style="display:inline">(555) 018-KIMCHI</a></span>
</div>
</div>
</footer>
<!-- ======================= CART UI ======================= -->
<button class="cart-pill" id="cartPill"><span class="cnt" id="cartCount">0</span> <span id="cartTotal">$0.00</span> <span>· View order</span></button>
<div class="backdrop" id="backdrop"></div>
<aside class="drawer" id="drawer" aria-label="Your order">
<div class="drawer-head"><b>Your order 🛒</b><button class="drawer-close" id="drawerClose" aria-label="Close order">✕</button></div>
<div class="drawer-body" id="drawerBody"><p class="muted">Nothing here yet. The truck is judging you.</p></div>
<div class="drawer-foot">
<div class="drawer-total"><span>Subtotal</span><span id="drawerTotal">$0.00</span></div>
<a class="btn btn-red btn-block" href="tel:+15550184264">Call to finish my order</a>
<button class="btn btn-ghost btn-block" style="margin-top:.6rem" id="clearCart">Clear order</button>
</div>
</aside>
<div class="toast" id="toast"></div>
<script>
(function(){
"use strict";
/* ============ helpers ============ */
const $ = s => document.querySelector(s);
const $$ = s => Array.from(document.querySelectorAll(s));
const money = n => "$" + n.toFixed(2);
let uid = 0;
/* ============ marquees ============ */
const m1 = ["Order ahead & skip the line","Now serving Downtown + Midtown","Vegan Kimchi Crunch Bowl just dropped","Free fountain drink over $15","Kimchi fries with queso","Secret gochujang cream","Open late on Fridays","Catering available — 25+ guests"];
const m2 = ["BIBIMBAP TACO","BULGOGI CRUNCH","KIMCHI FRIES","GOCHUJANG CORN","TTEOKBOKKI FRIES","CHILE RELLENO","YUZU LEMONADE","CRISPY CHICKEN","SODA FOUNTAIN"];
function fillMarquee(el, arr, sep){
const one = arr.map(t => `<span>${t}<b class="dot">${sep}</b></span>`).join("");
el.innerHTML = one + one;
}
fillMarquee($("#mTrack1"), m1, "★");
fillMarquee($("#mTrack2"), m2, "✦");
/* ============ taco illustration ============ */
function tacoSVG(spice, className){
const id = "tk" + (++uid);
const jalPos = [[58,58],[98,46],[138,52],[178,44],[216,56],[248,66]];
let jal = "";
for(let i=0;i<spice && i<6;i++){
const x = jalPos[i][0], y = jalPos[i][1];
jal += `<g class="jal"><circle cx="${x}" cy="${y}" r="9.5" fill="#7BC94A" stroke="#2E7A22" stroke-width="1.6"/><circle cx="${x}" cy="${y}" r="4" fill="#D9EFB0"/></g>`;
}
const glow = spice >= 4
? `<circle cx="150" cy="72" r="100" fill="url(#${id}-fire)"/>`
: "";
return `
<svg class="taco-svg ${className||''}" viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Illustration of a loaded Korean taco">
<defs>
<linearGradient id="${id}-shell" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#FCE07F"/><stop offset=".55" stop-color="#F8C748"/><stop offset="1" stop-color="#E39C1F"/>
</linearGradient>
<linearGradient id="${id}-meat" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#C0652A"/><stop offset="1" stop-color="#8A3D14"/>
</linearGradient>
<radialGradient id="${id}-fire">
<stop offset="0" stop-color="#FF7A2A" stop-opacity=".55"/><stop offset="1" stop-color="#FF7A2A" stop-opacity="0"/>
</radialGradient>
</defs>
<ellipse cx="150" cy="181" rx="108" ry="13" fill="rgba(30,21,18,.18)"/>
${glow}
<g transform="rotate(-7 150 110)">
<path d="M38 92 C40 56 74 34 106 46 C130 28 168 30 188 50 C216 40 250 56 262 88 L262 124 L38 124 Z" fill="${id}-meat"/>
<path d="M44 86 C46 56 78 40 102 52 C124 36 160 38 180 56 C208 46 244 60 258 88 L258 124 L44 124 Z" fill="#4E9A3E"/>
<path d="M58 78 C62 52 92 42 112 56 L112 124 L58 124 Z" fill="#A03A82"/>
<path d="M150 96 C164 78 196 76 208 92 C196 100 166 106 150 96 Z" fill="#E03127"/>
<path d="M62 50 L74 40 L86 50 L98 40 L110 50 L122 40 L134 50 L146 40 L158 50 L170 40 L182 50 L194 42 L206 50 L218 42" fill="none" stroke="#FFC93C" stroke-width="7" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M70 68 L82 60 L94 68 L106 60 L118 68 L130 60 L142 68 L154 60 L166 68 L178 60 L190 68" fill="none" stroke="#FFF6E6" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
${jal}
<g fill="#F6E6B4">
<ellipse cx="96" cy="34" rx="3.4" ry="2.2" transform="rotate(-20 96 34)"/>
<ellipse cx="126" cy="28" rx="3.4" ry="2.2" transform="rotate(15 126 28)"/>
<ellipse cx="160" cy="36" rx="3.4" ry="2.2" transform="rotate(-8 160 36)"/>
<ellipse cx="200" cy="30" rx="3.4" ry="2.2" transform="rotate(24 200 30)"/>
<ellipse cx="224" cy="44" rx="3.4" ry="2.2" transform="rotate(-14 224 44)"/>
</g>
<path d="M30 140 C30 112 58 90 98 82 C146 72 220 88 270 140 Z" fill="url(#${id}-shell)" stroke="#D3911B" stroke-width="3" stroke-linejoin="round"/>
<g fill="#E2A82B" opacity=".65">
<circle cx="72" cy="112" r="4"/><circle cx="106" cy="98" r="3.2"/><circle cx="152" cy="104" r="3.6"/>
<circle cx="196" cy="112" r="3.2"/><circle cx="232" cy="124" r="3.6"/><circle cx="118" cy="124" r="2.8"/>
</g>
<path d="M30 140 C30 112 58 90 98 82" fill="none" stroke="#FCE07F" stroke-width="4" stroke-linecap="round"/>
<path d="M40 140 C74 132 214 130 262 140" fill="none" stroke="#D3911B" stroke-width="2.4" opacity=".6"/>
</g>
</svg>`;
}
$("#heroTaco").innerHTML = tacoSVG(2);
/* ============ menu data ============ */
const icons = {
taco:`<svg viewBox="0 0 120 96" xmlns="http://www.w3.org/2000/svg"><path d="M22 84 L22 58 C22 44 36 34 60 34 C84 34 98 44 98 58 L98 84 Z" fill="#F6C243" stroke="#D3911B" stroke-width="3"/><path d="M26 60 C26 40 42 28 60 28 C78 28 94 40 94 60 Z" fill="#E03127"/><path d="M32 52 L42 44 L52 52 L62 44 L72 52 L82 45" stroke="#4E9A3E" stroke-width="6" fill="none" stroke-linecap="round"/><path d="M22 84 L98 84" stroke="#1E1512" stroke-width="5" stroke-linecap="round"/><circle cx="40" cy="36" r="3" fill="#F6E6B4"/><circle cx="70" cy="32" r="3" fill="#F6E6B4"/></svg>`,
bowl:`<svg viewBox="0 0 120 96" xmlns="http://www.w3.org/2000/svg"><path d="M16 44 H104 C104 70 84 88 60 88 C36 88 16 70 16 44 Z" fill="#3A2C24" stroke="#1E1512" stroke-width="3"/><path d="M14 42 C20 28 34 22 46 26 C56 16 74 18 82 28 C96 24 106 32 106 42 Z" fill="#E03127"/><path d="M30 40 C34 30 44 26 52 30" stroke="#FFC93C" stroke-width="5" fill="none" stroke-linecap="round"/><circle cx="74" cy="30" r="8" fill="#FFF6E6" stroke="#E6DCC8" stroke-width="2"/><path d="M40 84 H80" stroke="#1E1512" stroke-width="4" stroke-linecap="round"/></svg>`,
fries:`<svg viewBox="0 0 120 96" xmlns="http://www.w3.org/2000/svg"><g stroke="#F6C243" stroke-width="9" stroke-linecap="round"><path d="M40 48 V14"/><path d="M52 46 V8"/><path d="M64 46 V18"/><path d="M76 48 V10"/></g><path d="M30 42 H90 L80 90 H40 Z" fill="#E03127" stroke="#1E1512" stroke-width="3" stroke-linejoin="round"/><path d="M44 62 H76" stroke="#FFF6E6" stroke-width="6" stroke-linecap="round"/><path d="M50 76 H70" stroke="#FFC93C" stroke-width="5" stroke-linecap="round"/></svg>`,
ques:`<svg viewBox="0 0 120 96" xmlns="http://www.w3.org/2000/svg"><path d="M20 78 L20 56 C20 42 38 32 60 32 C82 32 100 42 100 56 L100 78 Z" fill="#F6C243" stroke="#D3911B" stroke-width="3"/><path d="M20 78 H100" stroke="#1E1512" stroke-width="5" stroke-linecap="round"/><path d="M34 60 C40 48 54 44 62 50 C72 44 86 50 90 60 L90 78 L34 78 Z" fill="#FFC93C"/><path d="M38 66 L84 66" stroke="#D3911B" stroke-width="3" stroke-linecap="round"/></svg>`,
drink:`<svg viewBox="0 0 120 96" xmlns="http://www.w3.org/2000/svg"><path d="M34 30 H86 L78 88 H42 Z" fill="#FFF6E6" stroke="#1E1512" stroke-width="3" stroke-linejoin="round"/><path d="M36 52 H84 L78 88 H42 Z" fill="#FFC93C"/><path d="M40 62 H80" stroke="#E03127" stroke-width="5" stroke-linecap="round"/><path d="M66 30 L78 6" stroke="#E03127" stroke-width="6" stroke-linecap="round"/><ellipse cx="60" cy="30" rx="26" ry="6" fill="#fff" stroke="#1E1512" stroke-width="3"/></svg>`,
nachos:`<svg viewBox="0 0 120 96" xmlns="http://www.w3.org/2000/svg"><path d="M18 78 L40 32 L62 78 Z" fill="#F6C243" stroke="#D3911B" stroke-width="3" stroke-linejoin="round"/><path d="M58 78 L80 32 L102 78 Z" fill="#F6C243" stroke="#D3911B" stroke-width="3" stroke-linejoin="round"/><path d="M26 62 h16" stroke="#E03127" stroke-width="5" stroke-linecap="round"/><path d="M70 60 h16" stroke="#4E9A3E" stroke-width="5" stroke-linecap="round"/><circle cx="52" cy="52" r="6" fill="#FFF6E6"/></svg>`
};
const MENU = [
{n:"Kimchi Carnitas", p:4.25, c:"tacos", i:"taco", h:2, tag:"Best Seller", d:"12-hour braised pork shoulder, kimchi slaw, pickled onion, gochujang crema. The one that started it all."},
{n:"Bulgogi Crunch", p:4.75, c:"tacos", i:"taco", h:1, tag:"Fan fave", d:"Thin-sliced sirloin seared hot, sesame-ssam slaw, crisp shallots, yuzu crema."},
{n:"Gochujang Chicken", p:4.50, c:"tacos", i:"taco", h:3, tag:"", d:"Twice-fried chicken in our sticky gochujang glaze, cool ranchero, cabbage. Two per order."},
{n:"Kimchi Dog Taco", p:5.25, c:"tacos", i:"taco", h:2, tag:"New", d:"Griddled hot dog, kimchi mustard, kimchi butter, melted cheese. Yes, really."},
{n:"Seoul Quesadilla", p:8.50, c:"tacos", i:"ques", h:2, tag:"", d:"Melted cheese, kimchi, scallion, your choice of protein, served with salsa verde."},
{n:"Bibimbap Bowl", p:11.00, c:"bowls", i:"bowl", h:1, tag:"Vegan", d:"Warm rice, seasoned vegetables, house gochujang, fried egg or avocado. Clean, bright, addictive."},
{n:"Bulgogi Rice Bowl", p:12.50, c:"bowls", i:"bowl", h:2, tag:"", d:"Seared beef over rice, kimchi fried egg, kimchi butter, ssam, sesame. Extra napkins included."},
{n:"Kimchi Fries", p:6.00, c:"sides", i:"fries", h:2, tag:"Must try", d:"Crispy fries tossed in kimchi butter, smothered in queso, crema and furikake. Illegal in three states."},
{n:"Tteokbokki Fries", p:7.50, c:"sides", i:"fries", h:3, tag:"", d:"Chewy rice cakes, tteokbokki sauce, cheese sauce, scallion. Pick up with a fork. Maybe."},
{n:"Kimchi Nachos", p:9.00, c:"sides", i:"nachos", h:2, tag:"Shareable", d:"Tortilla chips, queso, kimchi, crema, pickled jalapeño. Built for groups of four or one."},
{n:"Yuzu Lemonade", p:3.50, c:"drinks", i:"drink", h:0, tag:"Vegan", d:"Yuzu, lemon, mint and sparkling water. Extremely refreshing with spicy food."},
{n:"Horchata & Kimchi Cola", p:3.50, c:"drinks", i:"drink", h:0, tag:"", d:"Cinnamon horchata or our house sweet kimchi cola. Both are weird. Both are good."}
];
const grid = $("#menuGrid");
function renderMenu(cat){
grid.innerHTML = "";
MENU.forEach((it, idx) => {
if(cat !== "all" && it.c !== cat) return;
const heat = Array.from({length:3}).map((_,k)=>`<i class="${k<it.h?'on':''}"></i>`).join("");
const art = document.createElement("article");
art.className = "card reveal in";
art.style.animationDelay = (idx*45)+"ms";
art.innerHTML = `
<div class="thumb">${icons[it.i]}${it.tag?`<span class="ribbon">${it.tag}</span>`:""}</div>
<h3>${it.n}</h3>
<p>${it.d}</p>
<div>
<span class="heat" title="Heat level ${it.h} of 3">${heat}</span>
<span style="font-size:.72rem;font-weight:900;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)">${["No heat","Mild","Medium","Hot"][it.h]}</span>
</div>
<div class="card-foot">
<span class="price">${money(it.p)}<small>per order</small></span>
<button class="add-btn" data-name="${it.n}" data-price="${it.p}" aria-label="Add ${it.n} to order">+</button>
</div>`;
grid.appendChild(art);
});
}
renderMenu("all");
$$("#filters .chip").forEach(btn => {
btn.addEventListener("click", () => {
$$("#filters .chip").forEach(b => b.classList.remove("active"));
btn.classList.add("active");
renderMenu(btn.dataset.cat);
});
});
/* ============ cart ============ */
let cart = [];
const drawer = $("#drawer"), backdrop = $("#backdrop");
function addItem(name, price){
cart.push({name, price});
toast("Added " + name + " — " + money(price));
updateCart();
}
function updateCart(){
const count = cart.length;
const total = cart.reduce((s,i)=>s+i.price,0);
$("#cartCount").textContent = count;
$("#cartTotal").textContent = money(total);
$("#drawerTotal").textContent = money(total);
$("#cartPill").classList.toggle("show", count>0);
const body = $("#drawerBody");
if(!count){ body.innerHTML = '<p class="muted">Nothing here yet. The truck is judging you.</p>'; }
else{
body.innerHTML = cart.map((it,i)=>`<div class="dline"><span>${it.name}</span><span style="display:flex;gap:.6rem;align-items:center">${money(it.price)}<button data-rm="${i}">remove</button></span></div>`).join("");
}
}
function toast(msg){
const t = $("#toast");
t.textContent = msg;
t.classList.add("show");
clearTimeout(t._tm);
t._tm = setTimeout(()=>t.classList.remove("show"), 2400);
}
document.addEventListener("click", e => {
const add = e.target.closest(".add-btn");
if(add){ addItem(add.dataset.name, parseFloat(add.dataset.price)); return; }
const rm = e.target.closest("[data-rm]");
if(rm){ cart.splice(parseInt(rm.dataset.rm),1); updateCart(); }
});
function openDrawer(){ drawer.classList.add("open"); backdrop.classList.add("show"); }
function closeDrawer(){ drawer.classList.remove("open"); backdrop.classList.remove("show"); }
$("#cartPill").addEventListener("click", openDrawer);
$("#drawerClose").addEventListener("click", closeDrawer);
backdrop.addEventListener("click", closeDrawer);
$("#clearCart").addEventListener("click", () => { cart = []; updateCart(); });
/* ============ heat builder ============ */
const heatNames = ["No heat","Mild","Medium","Hot","Seoul Hot","Nuclear"];
const heatDescs = [
"Just sweet gochujang cream and good vibes. Perfect for your brave-but-cautious friend.",
"A gentle warmth that arrives about four seconds late. Very polite.",
"The classic Kimchi Loco heat — gochujang, jalapeño, a confident kick.",
"Now we're talking. You'll reach for the yuzu lemonade immediately.",
"Sweating through the queso. The staff will start a fan for you.",
"Level 5. We serve water, we don't make eye contact, and there's a waiver. (There isn't a waiver.)"
];
const heatSlider = $("#heat");
function renderBuild(){
const v = parseInt(heatSlider.value);
$("#buildStage").innerHTML = tacoSVG(v);
$("#heatNum").textContent = v + " / 5";
$("#heatLabel").textContent = heatNames[v];
$("#heatDesc").textContent = heatDescs[v];
$("#buildPrice").textContent = money(4.75 + v*0.20);
}
heatSlider.addEventListener("input", renderBuild);
renderBuild();
$("#buildAdd").addEventListener("click", () => {
const v = parseInt(heatSlider.value);
addItem("Custom taco (" + heatNames[v] + ")", 4.75 + v*0.20);
});
/* ============ reviews ============ */
const REVIEWS = [
{q:"The Kimchi Carnitas taco genuinely ruined every other taco for me. I have a 25-minute drive for it and I make it weekly. Worth it.", n:"Dana R.", s:"Yelp · Verified", c:"linear-gradient(135deg,#E03127,#F2751A)", stars:5},
{q:"Best food truck in the city, no contest. The bulgogi crunch taco is a religious experience — that yuzu crema is life-changing.", n:"Marcus T.", s:"Google · Verified", c:"linear-gradient(135deg,#F2751A,#FFC93C)", stars:5},
{q:"We booked Kimchi Loco for our wedding and the line wrapped around the courtyard. Not one complaint. The bulkogi bomb went off at 9pm.", n:"Priya & Sam", s:"Wedding catering", c:"linear-gradient(135deg,#8E2F6E,#E03127)", stars:5},
{q:"Finally a vegan taco that isn't a compromise. The Bibimbap Bowl is loaded with flavour and the kimchi fries are dangerously good.", n:"Alex N.", s:"Instagram", c:"linear-gradient(135deg,#3F9A45,#FFC93C)", stars:5}
];
const track = $("#revTrack");
track.innerHTML = REVIEWS.map(r=>`
<div class="rev-slide"><div class="rev">
<div class="stars">${"★".repeat(r.stars)}</div>
<p>${r.q}</p>
<div class="rev-by">
<div class="avatar" style="background:${r.c}">${r.n.slice(0,1)}</div>
<div><b>${r.n}</b><span>${r.s}</span></div>
</div>
</div></div>`).join("");
const dots = $("#revDots");
REVIEWS.forEach((_,i)=>{ const b=document.createElement("button"); b.className="dot-btn"+(i===0?" active":""); b.setAttribute("aria-label","Review "+(i+1)); b.addEventListener("click",()=>go(i)); dots.appendChild(b); });
let ri = 0, timer;
function go(i){
ri = (i + REVIEWS.length) % REVIEWS.length;
track.style.transform = `translateX(-${ri*100}%)`;
Array.from(dots.children).forEach((d,k)=>d.classList.toggle("active",k===ri));
}
function auto(){ clearInterval(timer); timer = setInterval(()=>go(ri+1), 5200); }
$("#nextRev").addEventListener("click", ()=>{go(ri+1);auto();});
$("#prevRev").addEventListener("click", ()=>{go(ri-1);auto();});
auto();
/* ============ truck art ============ */
$("#truckArt").innerHTML = `
<svg viewBox="0 0 560 300" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="The Kimchi Loco food truck">
<defs>
<linearGradient id="winGlow" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#FFD97A"/><stop offset="1" stop-color="#F2751A"/>
</linearGradient>
</defs>
<ellipse cx="280" cy="272" rx="250" ry="16" fill="rgba(30,21,18,.15)"/>
<!-- roof sign -->
<rect x="120" y="16" width="196" height="50" rx="12" fill="#FFC93C" stroke="#1E1512" stroke-width="4"/>
<text x="218" y="49" text-anchor="middle" font-family="ui-sans-serif,system-ui,Arial" font-size="26" font-weight="900" fill="#1E1512" letter-spacing="1">KIMCHI LOCO</text>
<g stroke="#E03127" stroke-width="4" stroke-linecap="round" opacity=".55">
<path d="M96 24 c8 -10 -6 -18 2 -28"/><path d="M340 24 c8 -10 -6 -18 2 -28"/>
</g>
<!-- box body -->
<rect x="30" y="80" width="340" height="150" rx="18" fill="#FFF3E0" stroke="#1E1512" stroke-width="4"/>
<path d="M30 176 H370 V212 A18 18 0 0 1 352 230 H48 A18 18 0 0 1 30 212 Z" fill="#E03127" stroke="#1E1512" stroke-width="4"/>
<!-- serving window -->
<rect x="58" y="104" width="176" height="76" rx="10" fill="#2B1B14" stroke="#1E1512" stroke-width="4"/>
<rect x="68" y="112" width="156" height="58" rx="6" fill="url(#winGlow)"/>
<circle cx="120" cy="138" r="13" fill="#1E1512" opacity=".75"/>
<path d="M98 170 q22 -28 44 0 z" fill="#1E1512" opacity=".75"/>
<rect x="170" y="118" width="46" height="26" rx="5" fill="#FFF3E0" stroke="#1E1512" stroke-width="3"/>
<!-- awning -->
<g>
<path d="M48 92 H244 V104 H48 Z" fill="#1E1512"/>
<g fill="#E03127"><rect x="54" y="96" width="24" height="16" rx="4"/><rect x="102" y="96" width="24" height="16" rx="4"/><rect x="150" y="96" width="24" height="16" rx="4"/><rect x="198" y="96" width="24" height="16" rx="4"/></g>
<g fill="#FFF3E0"><rect x="78" y="96" width="24" height="16" rx="4"/><rect x="126" y="96" width="24" height="16" rx="4"/><rect x="174" y="96" width="24" height="16" rx="4"/><rect x="222" y="96" width="24" height="16" rx="4"/></g>
</g>
<text x="300" y="120" text-anchor="middle" font-family="ui-sans-serif,system-ui,Arial" font-size="22" font-weight="900" fill="#1E1512">SEOUL</text>
<text x="300" y="146" text-anchor="middle" font-family="ui-sans-serif,system-ui,Arial" font-size="22" font-weight="900" fill="#E03127">× MEXICO</text>
<text x="300" y="170" text-anchor="middle" font-family="ui-sans-serif,system-ui,Arial" font-size="12" font-weight="800" fill="#6E5B4F" letter-spacing="3">EST. 2019</text>
<!-- cab -->
<path d="M370 230 V128 H428 L482 190 H520 V230 Z" fill="#E03127" stroke="#1E1512" stroke-width="4" stroke-linejoin="round"/>
<path d="M382 138 H424 L462 182 H382 Z" fill="#BFE6F0" stroke="#1E1512" stroke-width="4" stroke-linejoin="round"/>
<circle cx="500" cy="200" r="9" fill="#FFC93C" stroke="#1E1512" stroke-width="3"/>
<rect x="366" y="196" width="16" height="34" rx="4" fill="#1E1512"/>
<!-- wheels -->
<g><circle cx="108" cy="232" r="32" fill="#1E1512"/><circle cx="108" cy="232" r="13" fill="#FFC93C" stroke="#1E1512" stroke-width="4"/>
<circle cx="432" cy="232" r="32" fill="#1E1512"/><circle cx="432" cy="232" r="13" fill="#FFC93C" stroke="#1E1512" stroke-width="4"/></g>
<!-- string lights -->
<g fill="#FFC93C" stroke="#1E1512" stroke-width="2">
<circle cx="60" cy="74" r="6"/><circle cx="96" cy="80" r="6"/><circle cx="132" cy="82" r="6"/><circle cx="168" cy="80" r="6"/><circle cx="204" cy="76" r="6"/>
</g>
</svg>`;
/* ============ map art ============ */
$("#mapArt").innerHTML = `
<svg viewBox="0 0 900 420" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Map showing Kimchi Loco locations">
<rect width="900" height="420" fill="#EDE0C9"/>
<path d="M0 330 q140 -40 280 0 t300 -10 q160 -30 320 10 V420 H0 Z" fill="#9FD3E4" opacity=".85"/>
<path d="M600 40 q120 40 120 130 t-60 120 q-80 40 -110 -20 q-20 -50 30 -80 q60 -40 20 -150 Z" fill="#A9D6A2"/>
<g stroke="#FDF6EA" stroke-width="26" stroke-linecap="round" fill="none">
<path d="M-10 120 H910"/><path d="M-10 250 H910"/><path d="M220 -10 V420"/><path d="M520 -10 V420"/><path d="M780 -10 V420"/>
</g>
<g stroke="#D9C7A8" stroke-width="3" stroke-dasharray="14 16" stroke-linecap="round" fill="none">
<path d="M-10 120 H910"/><path d="M-10 250 H910"/><path d="M220 -10 V420"/><path d="M520 -10 V420"/><path d="M780 -10 V420"/>
</g>
<g fill="#DCCBAE" opacity=".8">
<rect x="60" y="150" width="120" height="70" rx="8"/><rect x="265" y="150" width="215" height="70" rx="8"/>
<rect x="60" y="285" width="120" height="70" rx="8"/><rect x="560" y="150" width="180" height="70" rx="8"/>
<rect x="560" y="285" width="180" height="70" rx="8"/><rect x="265" y="285" width="215" height="70" rx="8"/>
</g>
<g font-family="ui-sans-serif,system-ui,Arial" font-size="13" font-weight="800" fill="#6E5B4F">
<text x="270" y="188">DOWNTOWN DISTRICT</text><text x="570" y="188">MIDTOWN PLAZA</text><text x="60" y="320">RIVERSIDE PARK</text>
</g>
<!-- pins -->
<g>
<path d="M300 176 c0 0 -22 -26 -22 -42 a22 22 0 1 1 44 0 c0 16 -22 42 -22 42 z" fill="#E03127" stroke="#1E1512" stroke-width="3"/>
<circle cx="300" cy="134" r="9" fill="#FFF7EC"/>
<text x="300" y="200" text-anchor="middle" font-family="ui-sans-serif,system-ui,Arial" font-size="12" font-weight="900" fill="#1E1512">KIMCHI LOCO</text>
</g>
<g>
<path d="M650 196 c0 0 -18 -21 -18 -34 a18 18 0 1 1 36 0 c0 13 -18 34 -18 34 z" fill="#F2751A" stroke="#1E1512" stroke-width="3"/>
<circle cx="650" cy="162" r="7" fill="#FFF7EC"/>
<text x="650" y="216" text-anchor="middle" font-family="ui-sans-serif,system-ui,Arial" font-size="11" font-weight="900" fill="#1E1512">MIDTOWN</text>
</g>
<g>
<path d="M120 330 c0 0 -18 -21 -18 -34 a18 18 0 1 1 36 0 c0 13 -18 34 -18 34 z" fill="#3F9A45" stroke="#1E1512" stroke-width="3"/>
<circle cx="120" cy="296" r="7" fill="#FFF7EC"/>
<text x="120" y="350" text-anchor="middle" font-family="ui-sans-serif,system-ui,Arial" font-size="11" font-weight="900" fill="#1E1512">RIVERSIDE</text>
</g>
<g>
<circle cx="430" cy="300" r="15" fill="#1E1512"/><circle cx="430" cy="300" r="6" fill="#FFC93C"/>
<text x="430" y="332" text-anchor="middle" font-family="ui-sans-serif,system-ui,Arial" font-size="11" font-weight="900" fill="#1E1512">YOU ARE HERE</text>
</g>
</svg>`;
/* ============ forms ============ */
const cater = $("#caterForm");
cater.addEventListener("submit", e => {
e.preventDefault();
let ok = true;
const name=$("#cName"), email=$("#cEmail"), phone=$("#cPhone"), date=$("#cDate");
const set=(input, errId, bad)=>{ document.getElementById(errId).classList.toggle("show", bad); if(bad) ok=false; };
set(name,"eName", name.value.trim().length < 2);
set(email,"eEmail", !/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email.value.trim()));
set(phone,"ePhone", phone.value.replace(/\D/g,"").length < 7);
set(date,"eDate", date.value.trim().length < 4);
if(ok){
cater.style.display = "none";
$("#caterOk").classList.add("show");
$("#caterOk").scrollIntoView({behavior:"smooth", block:"center"});
}
});
const news = $("#newsForm");
news.addEventListener("submit", e => {
e.preventDefault();
const v = $("#newsEmail").value.trim();
if(/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(v)){
news.style.display="none";
$("#newsOk").classList.add("show");
} else {
toast("Hmm, that email looks a little off. Try again!");
}
});
/* ============ nav behaviour ============ */
const nav = $("#nav");
window.addEventListener("scroll", () => nav.classList.toggle("stuck", window.scrollY > 12));
const burger = $("#burger"), mobile = $("#mobileMenu");
burger.addEventListener("click", () => {
const open = mobile.classList.toggle("open");
burger.setAttribute("aria-expanded", open ? "true":"false");
burger.textContent = open ? "✕" : "☰";
});
$$("#mobileMenu a").forEach(a => a.addEventListener("click", () => {
mobile.classList.remove("open"); burger.textContent = "☰"; burger.setAttribute("aria-expanded","false");
}));
/* ============ reveal on scroll ============ */
const io = new IntersectionObserver(entries => {
entries.forEach(en => { if(en.isIntersecting){ en.target.classList.add("in"); io.unobserve(en.target); } });
}, {threshold:.12, rootMargin:"0px 0px -40px 0px"});
$$(".reveal").forEach(el => io.observe(el));
/* ============ card tilt (desktop) ============ */
if(window.matchMedia("(hover:hover) and (pointer:fine)").matches){
document.addEventListener("mousemove", e => {
const card = e.target.closest(".card");
if(!card) return;
const r = card.getBoundingClientRect();
const x = (e.clientX - r.left) / r.width - .5;
const y = (e.clientY - r.top) / r.height - .5;
card.style.transform = `translateY(-6px) rotateX(${(-y*7).toFixed(2)}deg) rotateY(${(x*8).toFixed(2)}deg)`;
});
document.addEventListener("mouseout", e => {
const card = e.target.closest(".card");
if(card && !card.contains(e.relatedTarget)) card.style.transform = "";
});
}
$("#year").textContent = new Date().getFullYear();
})();
</script>
</body>
</html>Reasoning trace (8,451 tokens)
The user wants a website for a Korean taco food truck called "Kimchi Loco". It should be really appealing. Let me build a vibrant, appetizing single-page site with:
- Bold hero with food imagery (can't use external images... but I can use CSS gradients, emoji, SVG illustrations). Actually I can create SVG illustrations of tacos, kimchi, etc. Emoji might look cheap but can work well if styled well. Let me do custom SVG illustrations — a taco, a truck, kimchi jar, etc.
- Sections: Hero with big title, marquee ticker, menu (with prices, spice levels, "Chef's Special"), the story, "Why people love it", reviews, catering/event booking form, location/hours, social proof, newsletter, footer.
- Colors: kimchi red, gochujang orange, warm cream, charcoal, avocado green.
- Animations: scroll reveal, marquee, floating taco, hover effects, spice meter.
- Responsive down to 375px.
- Maybe a little interactive: a "spice level" slider that updates the taco description/emoji, a menu filter, a live "truck location" card.
- Should be self-playing? It's not a game, so no requirement. But maybe add a fun interactive element — like a "build your taco" or a spinning taco. Keep it tasteful.
Let me design:
Palette:
- Background cream: #FFF6E9
- Charcoal: #1A1512
- Kimchi red: #E4322B
- Gochujang: #F26B21
- Cheese yellow: #FFC93C
- Green (scallion): #3FA34D
- Purple cabbage: #7B2D8E
Fonts: system fonts with heavy display. Could use Google Fonts CDN? Task says "No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task." No CDN URLs specified in the task, so I should avoid external fonts. Use system font stack: for display, "Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif"? Hmm, that's blocky. Better: use a bold sans stack with heavy weight and tight letter spacing: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica Neue, Arial. With font-weight 900 and uppercase + slight skew for a street-food vibe.
Actually I could add a subtle text-shadow/3D effect for the poster look.
Structure:
1. Sticky top nav with logo (SVG taco in circle), links, phone CTA "Order Now" + mobile menu.
2. Announcement ticker bar (marquee) — "🔥 Now serving at ... "
3. Hero: big headline "KIMCHI LOCO", subhead "Korean-Mexican street tacos. Seoul heat. Taco Tuesday energy." Big CTA buttons "See the Menu" / "Find the Truck". A large illustrated taco SVG with floating elements (sesame, green onion, chili). Stats row: 4.9★ (2,400+ reviews), 12+ taco styles, 100% halal... hmm. "Hand-made tortillas daily", "Secret gochujang sauce".
4. Marquee strip #2.
5. "The Loco Lineup" menu section — cards with SVG-ish visuals, price, tags, spice meter dots, "Best Seller" ribbon. Category filter (All / Tacos / Quesadillas / Sides / Drinks). Interactive filter with JS.
6. Interactive fun: "Find your heat" spice slider that changes a taco's color & description. Or a "Taco Builder". Let's do a "Build-a-Bowl" mini game? Might be overkill but adds interactivity: a "Spice-o-meter" slider with live taco rendering (SVG layers appearing: lettuce, meat, kimchi, cheese, crema, jalapeño). That's fun and shows craft. Let's do it: slider 0-5 → taco illustration fills with toppings, price updates, and a caption. Good.
7. Story/About section: our story with timeline (2019 food truck, etc.), founder, values. Image replaced by SVG illustration of the truck.
8. "Why people obsess" features grid with icons.
9. Reviews: carousel of review cards, auto-rotating (self-playing) with dots.
10. Catering / events: form (name, event type, guests, date, email) with validation and success message (no network). Plus perks.
11. Visit us: hours table, locations list, "Get directions" (no external link? map link can be a link with href="#"). Use a stylized map SVG.
12. Instagram feed grid (CSS gradient tiles with emoji/SVG) + handle.
13. FAQ accordion.
14. Newsletter + footer with big logo, socials, legal.
Let me make the SVG illustrations nice. I'll write a reusable taco SVG in JS or inline.
Hero visual: Big circular badge with a taco illustration, plus floating sesame seeds, scallions, chili peppers, lime wedge. I'll animate float.
Let me carefully craft the taco SVG:
Taco shape: a half-circle shell (like a U shape rotated). I'll do a shell as path: M 20 120 A 90 90 0 0 1 200 120 L 200 120 ... Actually a taco viewed from the side: shell is a semicircle (dome) with filling visible at the top. Let's draw: shell semicircle path "M10,130 A100,100 0 0,1 210,130" filled yellow with darker stroke and small spots. Then filling: an arc band above/inside top of shell: a wavy shape sitting on the shell's rim.
Better approach: draw the taco "open" facing up-right at an angle. Let's make a simpler but attractive illustration:
- Shell: path M 15,125 C 15,55 105,15 175,35 C 225,50 245,95 235,125 Z — hmm handcrafting is risky.
Alternative: use a tilted folded tortilla: an ellipse-ish shape. Let me do a clean approach:
Shell (folded tortilla, side view tilted ~ -15deg):
```
<g transform="rotate(-12 120 120)">
<path d="M25 120 C25 55 85 20 130 20 C175 20 215 55 215 120 Z" fill="#F7C24B"/>
```
That's a dome (semicircle-ish) representing the outer shell back. Then the front shell flap overlaps lower half:
```
<path d="M25 120 C25 70 60 45 90 40 L 90 120 Z" ...
```
Hmm.
Let's do a classic taco icon: outer shell shape like a "U" filled, with the top edge being wavy filling.
Simplify: taco shape =
- back shell: `M20,130 C20,60 80,25 130,25 C180,25 230,60 230,130 Z` (dome) in darker yellow (#E9A825) representing back shell.
- filling layers poking above the front: several wavy blobs between y=40 and y=85.
- front shell: `M20,130 C20,95 55,70 90,62 C150,48 205,75 230,130 Z` in lighter yellow (#FBCB57) with a lighter rim highlight.
Order: back shell dome (but that dome would be hidden). Hmm. Actually classic flat-design taco icon: a semicircle shell (flat side down), and the filling is drawn as a wavy band across the top of the semicircle, plus the shell covers lower. Let's do:
- Filling band (drawn first, behind): wavy shape spanning x 30..230, y around 55..95, colors green (lettuce/scallion), purple (kimchi), red (gochujang meat).
- Shell: a shape that looks like a folded tortilla: `M25,135 C25,85 70,50 130,50 C190,50 235,85 235,135 Z` filled with gradient yellow. But that would cover the filling entirely since filling band is at y 55-95 which is inside the shell region (shell top is y=50). Hmm the filling should peek above the shell's top rim. So shell rim top should be around y=95 and filling band from 45 to 100. So shell path: `M25,135 C25,100 60,78 95,72 C140,64 200,85 235,135 Z`? Then the shell is a shallow bowl shape and filling sits above it. That reads like a taco. Good.
Let me set the shell as a "U" bowl:
`M 22,132 C 22,92 68,70 130,70 C 192,70 238,92 238,132 Z` — that's a dome again (top at 70). Then filling above at y 40-75.
Then add a front shell flap: `M 22,132 C 22,98 55,80 95,74 L 95,132 Z`? That would give the sense of a folded shell with a diagonal seam. Actually the classic taco: there's a diagonal line across the shell suggesting the two sides of the folded tortilla. I'll add a curved stroke from lower-left to right at mid.
I'll do:
1. Shadow ellipse under.
2. Back tortilla edge (slightly offset, darker)
3. Filling stack: wavy bands (green lettuce zigzag, purple kimchi, brown meat, red sauce drizzle, white crema zigzag, yellow cheese shreds).
4. Front tortilla: a shape covering the bottom portion with a slightly diagonal top edge — like a shell curved up on the right side.
5. Sesame seeds, scallion rings.
Front tortilla path: `M 18,136 C 18,100 48,78 90,70 C 140,60 210,74 242,136 Z`? That's basically the full dome. Then the filling above must be at y<70... but filling drawn before will be hidden by the front tortilla only where it overlaps. If front tortilla top edge is around y=70 at center and filling spans y 38-80, the top portion of filling (38-70) shows above the shell rim.
So: filling drawn first from y≈30 to y≈95 (so lower part hidden by shell). Shell path covers from its rim curve downward. Rim curve: `M18,136 C18,102 46,80 88,72 C140,62 214,78 242,136 Z`. Topmost rim point ~y=68 near x=120. Filling from y=30 to y=95 will show 30..68. Good — that's the "stuff" poking out.
Let's give filling a wavy bottom-ish. I'll just use rounded blobs: a green blob, purple blob, brown blob, red stripe, white zigzag, yellow shreds.
I'll craft with ellipse-like paths. Let me define viewBox "0 0 260 160".
Green (scallion/lettuce): path "M40,70 C45,40 70,28 92,42 C110,30 135,30 150,44 C175,30 205,42 220,62 L220,90 L40,90 Z" — that covers a lot; then the shell covers lower.
Then purple kimchi: smaller blob on left: "M45,75 C50,52 72,46 88,55 L88,88 L45,88 Z".
Meat brown: "M100,60 C110,38 140,36 152,52 L152,86 L100,86 Z".
Cheese yellow shreds: zigzag path across top: "M60,52 L75,44 L90,52 L105,44 L120,52 L135,44 L150,52 L165,44 L180,52" stroke width 6 yellow.
Crema white zigzag: similar offset lower.
Red sauce: a swoosh.
Sesame: small ellipses.
That should read as a delicious taco. I'll add it with a slight rotation and drop shadow.
Also the food truck SVG for the story section: a stylized truck side view — cab + box body, wheels, "KIMCHI LOCO" lettering, awning stripes, roof sign, exhaust, serving window. That's doable.
Let me write the truck SVG:
viewBox 0 0 520 260.
- Wheels: circles at (110,215) r=26 and (395,215) r=26, dark with hub.
- Body: rounded rect for the box: x=60 y=60 w=300 h=130 rx=14 fill cream/red.
- Cab: path from x=360 to 480: `M360,190 L360,110 L410,110 L455,160 L480,160 L480,190 Z` fill red.
- Window: rect in cab, teal.
- Serving window in box: rounded rect x=95 y=85 w=140 h=60 fill dark.
- Awning: scalloped striped rect above window.
- Sign on top: rect x=120 y=20 w=180 h=40 fill yellow with text "KIMCHI LOCO".
- Lettering on body: "KIMCHI LOCO" text? Could use SVG text with font-family inherit — fine.
OK. Also a map SVG for the location section: stylized streets, a pin, park, etc. Doable with rects and paths.
Reviews carousel: auto-rotating every 4s, with manual dots.
Menu filter: buttons All / Tacos / Bowls / Sides / Drinks with JS filtering cards.
Spice builder: slider input range 0..5 → updates taco SVG (shows jalapeño count, color of sauce), price (base + $0.50/level), and a text line "Mild / Medium / Hot / 🔥 Seoul Hot / 🌶️ Nuclear". Also button "Add to order" → shows a little toast / counter "Your order: 2 tacos — $13.00". Nice interactive touch without storage.
Also add: "Order now" CTA opens... no external. Maybe the order button scrolls to builder.
Accessibility: prefers-reduced-motion handling maybe.
Let me write the code.
Key visual details to make it "make people really want to come":
- Appetizing warm colors, big food illustrations, prices, social proof, "sold out" urgency? Could add a "Today's special: Kimchi Carnitas — limited to 40 orders" countdown timer. A live countdown adds energy. Let's add a small countdown in the hero (like "Deal ends in"). Hmm, maybe as "Lunch rush in 02:14:33" — fun. I'll add a subtle countdown to the specials section: "Chef's Special drops in" countdown to next lunch.
Let me add a sticky "Order" bar? A top announcement bar with phone number and "Order ahead" button.
Also a "hover" tilt on menu cards (3D transform on mousemove) — nice.
Let me now write the HTML.
Sections detail:
**Nav**: logo (SVG circle with taco + text "KIMCHI LOCO" + small "Korean-Mexican Tacos"), links: Menu, Our Story, Reviews, Find Us, Catering, button "Order Now" (href="#order" or tel:). Mobile: hamburger toggling a dropdown panel.
**Announcement bar**: marquee with items separated by a star/emoji: "🌮 Order ahead & skip the line · Now serving Downtown + Midtown · Vegan Crunch Bowl just dropped · Free fountain drink over $15". Marquee CSS animation.
**Hero**:
- Left: eyebrow "Est. 2019 · Street food, Seoul-meets-Tijuana", H1 "KIMCHI LOCO" with "SEOUL HEAT. TACO ENERGY." subhead, paragraph, CTAs: "Order for pickup" (primary red) + "Find the truck" (outline), trust row: stars + "4.9 from 2,400+ taco addicts", small badges: "Halal-friendly chicken", "Vegan & gluten-free options", "Sauce is secret".
- Right: big rotating circular badge? Plus the big taco illustration with floating ingredients and a sticker "Fresh tortillas daily 🥑".
- Bottom stat strip: 12+ taco styles, 4.9★ rating, 3 food trucks, 85k tacos served.
**Marquee 2**: "BIBIMBAP TACOS · KIMCHI FRIES · GOCHUJANG CORN · CHEESE QUESO FRIES · BULGOGI TACOS ·"
**Menu section** with filter chips and grid of 8 items. Each card: illustration thumb (SVG mini: taco/bowl/fries/drink), name, tags (V, GF, Spicy), description, price, spice meter, "Best seller" ribbon on one, "Add" button that increments the order counter at top-right (a floating order pill showing count + total). That connects with the builder.
Items:
1. Kimchi Carnitas Taco — $4.25 — "Braised pork shoulder, kimchi slaw, pickled onion, gochujang crema" — 🌶🌶 Best seller.
2. Bulgogi Crunch Taco — $4.75 — "Thin-sliced sirloin, sesame, ssam, lime crema" — 🌶
3. Seoul Quesadilla — $8.50 — "Melted cheese, kimchi, scallion, choice of protein" — 🌶🌶
4. Kimchi Fries — $6.00 — "Fries, kimchi butter, queso, crema, furikake" — 🌶 Veg
5. Gochujang Chicken Tacos (2) — $8.00 — "Crispy gochujang chicken, slaw, ranchero" — 🌶🌶🌶
6. Bibimbap Bowl — $11.00 — "Rice, bulgogi, pickled veg, egg, gochujang" — Veg
7. Tteokbokki Fries — $7.50 — "Chewy rice cakes, spicy sauce, cheese, scallion" — 🌶🌶🌶
8. Yuzu Lemonade / Horchata — $3.50 — "Yuzu citrus, mint, sparkling" — Veg
9. Kimchi Nachos — $9
Maybe 6-8 cards. I'll do 8.
**Spice builder section** ("Build Your Heat"): interactive slider, live taco SVG that changes, price, description, add button, plus "Housemade sauces" list with icons: Gochujang, Ssam Cream, Kimchi Butter, Yuzu Salsa with heat dots.
**Story section**: "Two cultures, one griddle." Text about a Korean-Mexican fusion, the founder (e.g., "Mina & Danny"), the truck illustration, values list: Tortillas pressed to order, Kimchi fermented 3 days in-house, Sauces from scratch, Zero waste.
**Reviews**: 3-4 review cards auto-rotating with avatar circles (initials), stars, names, "Google / Yelp".
**Catering / Events**: form with fields, on submit show success card "Request received! We reply within 2 hours during service hours." plus chips of event types (Corporate lunch, Wedding, Festival, Party). Also a photo grid of events (CSS gradient tiles).
**Find us**: three location cards (Downtown Lot, Midtown Plaza, Riverside Park) with today's hours, "Get directions" button, plus a stylized map SVG.
**FAQ accordion**: 5 questions.
**Footer**: big logo, columns (Menu, Company, Visit), social icons (SVG), newsletter input, copyright, "Made with love & gochujang".
Floating order pill bottom-right showing count & total with "Checkout" (which triggers a modal? Keep simple: clicking expands a small panel listing items and a "Call to order" number). Let's implement a small drawer that slides in from the right listing added items, subtotal, and "Call (555) 018-KIMCHI to finish" — no alert. That adds interactivity and delight.
Alright, let's write it. I'll be careful about length but thorough.
CSS specifics:
- :root variables.
- body background cream with subtle noise? Use a repeating radial gradient dots. Fine.
- Section spacing: padding 96px 0 desktop, 64px mobile.
- Container: max-width 1180px, padding 0 24px.
- Display font: I'll use a stack: 'Archivo Black', 'Arial Black', system-ui... 'Arial Black' is available on most systems but not Linux/Chrome Linux. In the sandbox, likely Linux Chrome → Arial Black may not exist. Use font-weight 900 with system-ui; on Linux, system-ui = DejaVu Sans probably. Bold uppercase looks fine. To get more character, I'll use letter-spacing and skew and maybe a text-stroke. Let's not rely on exotic fonts. Use font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif with weight 900. Add slight italic skew for display headings to give poster energy.
Headings: uppercase, weight 900, letter-spacing -0.02em, line-height 0.95, with an outline option for "SEOUL" word.
Add a "scribble underline" SVG under key words.
Marquee: overflow hidden, inner flex with animation translateX(-50%) infinite, duplicate content.
Reveal on scroll: IntersectionObserver adding .in class with transition.
Reduced motion: disable transforms.
Let me write code now.
For the taco SVG, I'll write a function in JS that renders a taco with a given spice level and used in both hero (static inline) and builder. Better: define a JS function buildTaco(spice) returning SVG markup string, inject into containers. Hero uses buildTaco(2) with a different scale. Card thumbnails: use smaller simple icons — I'll write a helper `tacoIcon(color)`.
Simpler: write separate small SVG icons inline in HTML for menu cards (taco, quesadilla, fries, bowl, drink, nachos) — but that's a lot of markup. I'll make a JS icon library returning strings, and render menu cards via JS from a data array. That keeps HTML small and lets me implement filtering + add-to-cart easily. Good.
Menu card thumbnail: a circular gradient background with a big emoji-free SVG glyph. Let me design simple but cute glyphs:
- taco: mini taco (reuse simplified taco shape).
- bowl: bowl shape with stripes.
- fries: red carton with fries.
- quesadilla: folded half-circle with grill lines.
- drink: cup with straw.
- nachos: triangle chips with toppings.
I'll write these as simple SVGs in a 64x64 viewBox.
Let me write the taco glyph:
```
<svg viewBox="0 0 120 90"><path d="M10 80 C10 50 35 30 60 30 C85 30 110 50 110 80 Z" fill="#F6C243"/>...
```
Hmm for the icon, a simpler taco: a half-circle shell with a wavy top of green/red. Let me do: shell path M12,78 A48,48 0 0 1 108,78 Z (semicircle) — but the filling needs to show above the shell rim, and a semicircle's rim is the flat bottom... For a semicircle (dome up), the flat edge is at the bottom, so filling above would be at the top of the dome. Not right.
Correct taco icon: the shell forms a "U" (cup) shape with filling heaped above. So: shell path: `M20,80 L20,58 C20,44 36,36 60,36 C84,36 100,44 100,58 L100,80 Z` — a cup. Filling: blob above the rim: `M24,60 C24,40 40,28 60,28 C80,28 96,40 96,60 Z` in red/green with zigzag. So filling drawn first, then shell cup on top covering bottom half of filling. Good.
For the hero big taco I'll do the more detailed one described.
Let me write the detailed hero taco with viewBox "0 0 300 200".
Elements:
- ellipse shadow: cx=150 cy=180 rx=110 ry=14 fill rgba(0,0,0,.15)
- group rotate(-8 150 110)
- filling base (meat brown): path `M38,86 C42,52 78,34 108,46 C130,30 168,32 186,50 C214,40 248,54 262,84 L262,120 L38,120 Z` fill #8C3B1E? Maybe meat color #B4511F.
- kimchi purple accents, lettuce green: `M45,80 C48,54 76,42 100,52 C120,38 158,38 176,54 C204,44 240,56 256,82 L256,120 L45,120 Z` fill #4E9A3E.
- purple kimchi: `M60,74 C64,52 92,44 112,56 L112,120 L60,120 Z` fill #8E2F6E.
- red gochujang sauce swoosh: stroke path.
- cheese shreds: zigzag polyline stroke #FFC93C width 7 linecap round.
- crema zigzag: stroke #FFF6E6 width 6.
- sesame seeds: small ellipses #F2E2B0.
- front tortilla: `M30,140 C30,110 56,88 96,80 C142,70 218,86 270,140 Z` fill url(#shellGrad) — this covers from y=80ish down to 140. Wait need shell to cover the bottom of the filling so the taco bottom is flat-ish: add `L30,140 Z`. Yes path closes with a line to bottom.
Hmm, path: `M30,140 C30,112 58,90 98,82 C146,72 220,88 270,140 Z` — closes straight to (30,140). Bottom edge flat. Good.
- Tortilla edge highlight: same path stroke #E0A82E width 3.
- Tortilla spots (bubbles): small circles #E8B33A opacity .5.
- scallion rings: small green circles on top of filling.
- Add a folded seam line from (60,138) curve to (250,136)? Not needed.
Then greens poke above the shell rim (rim around y=80-90 center). Filling from y=32 to 120 → visible 32..85.
For the builder, extra toppings by spice level: jalapeño slices (green circles with inner) count = level, plus sauce color, plus maybe a "fire" glow. I'll build via JS with the same base plus jalapeños.
OK, and the "hue" changes: at higher spice, add a red glow filter around taco.
I'll write the SVG generation function `tacoSVG(spice, opts)`.
Let me write JS:
```js
function tacoSVG(spice=2, size=300){
const jal = [];
for(let i=0;i<spice;i++){ ... positions }
return `<svg viewBox="0 0 300 200" ...>`
}
```
Jalapeño positions: along the top of filling: x = 60 + i*30 + offset, y = 58 + (i%2)*10.
Now let me write everything.
Order drawer: right side panel, items list, subtotal, "Call to order" tel link, "Clear".
Add-to-cart from menu cards: each card has a "+" button; clicking adds and shows a toast "Added Kimchi Carnitas Taco — $4.25".
Toast: fixed bottom-left, auto-hide 2.2s.
Floating cart pill: fixed bottom-right (above drawer), shows "🛒 2 · $13.00" — click opens drawer. On mobile it's smaller.
Countdown: to next "lunch rush" — compute time until next 11:30 local. Display HH:MM:SS in a small card in the hero specials badge. I'll do a simple countdown to next hour? Let's do "Chef's Special available for the next" counting down 59:59 from load? That's fake but fun. I'll do countdown to next 11:00 or 17:00 whichever is next, labelled "Lunch rush starts in". Simpler and honest-ish: "Lunch rush starts in 02:14:07". Fine.
Auto-rotating reviews: setInterval 5s, translateX track. Use a flex track with transform translateX(-index*100%).
Let me write the FAQ with <details> for simplicity + custom styling with markers. Use details/summary → accessible and no JS needed. Good.
Now write the code. I'll aim for clean, complete, well-organized.
Colors final:
--cream: #FFF7EC
--cream2: #FDEEDB
--ink: #1E1512
--ink-soft: #4A3B33
--red: #E03127
--red-dark: #B71F1A
--orange: #F2751A
--gold: #FFC93C
--green: #3F9A45
--purple: #8E2F6E
--white: #fff
Section backgrounds alternate: cream, deep ink (#1E1512) for the "spice builder" section and footer, and red for a CTA band.
Let me write the "Let's get tacos" CTA band in red with big text and buttons.
Alright — writing it all out now.
Details for nav:
```
<header class="nav">
<div class="nav-inner container">
<a class="brand" href="#top">
<span class="brand-mark">[taco svg]</span>
<span class="brand-text"><strong>KIMCHI</strong><span> LOCO</span><em>Korean-Mexican Tacos</em></span>
</a>
<nav class="nav-links">...</nav>
<a class="btn btn-red nav-cta" href="tel:+15550184264">Order Now</a>
<button class="burger" ...>
</div>
</header>
```
Mobile menu: a panel that slides down under header when .open.
Sticky header with backdrop blur and shadow on scroll.
Let me write the CSS with attention to responsiveness: use clamp() for font sizes.
H1: font-size: clamp(3rem, 9vw, 6.5rem). "KIMCHI" and "LOCO" maybe stacked with different colors: "KIMCHI" in ink, "LOCO" in red with outline? Or "KIMCHI" white on red block and "LOCO" ink. Let's do: two lines, "KIMCHI" (ink, filled) / "LOCO" (red with gold offset shadow). Plus small tag line.
Hero layout: grid 1.05fr .95fr, gap 40. Mobile: stack, with the taco illustration after text (or before? Keep text first, visual second; but maybe show the visual first on mobile for appetite. I'll keep text first but make the visual big.)
Now the code.
I also need to make sure no horizontal scroll: use overflow-x hidden on body, and marquee inside overflow hidden.
Let me write out the full file.
For the truck SVG, I'll craft:
viewBox "0 0 560 280".
- ground shadow ellipse
- box body: rect x=40 y=70 w=330 h=130 rx=16 fill="#FFF3E0" stroke ink 3
- red lower stripe: rect x=40 y=160 w=330 h=40 (rounded bottom) fill red
- serving window: rect x=70 y=95 w=150 h=70 rx=10 fill="#2B1B14"
- inside window glow: rect with warm gradient, plus little taco shapes & a cook silhouette? Add a circle head + shoulders silhouette in warm yellow.
- awning: group of scalloped shapes above window: path stripes.
- roof sign: rounded rect x=110 y=18 w=190 h=44 fill gold stroke ink, text "KIMCHI LOCO" in ink bold; plus small taco glyph.
- cab: path `M370,200 L370,120 L420,120 L470,175 L520,175 L520,200 Z` fill red; windshield: polygon `M378,128 L416,128 L456,170 L378,170 Z` fill #BFE6F0 stroke ink; headlight circle;
- wheels: circles (110,205) r=28 and (430,205) r=28 fill ink, inner circle r=11 gold.
- bumper, side text "SEOUL × MEXICO" vertical? Add "EST. 2019" text on the body.
- steam/smoke curls from roof.
- string lights along the top.
I'll simplify to keep it manageable but attractive.
Map SVG: viewBox 0 0 800 420. Background #EFE3D0, park green blob, water, roads as thick white lines with dashed center, blocks as light rects, a red pin at center with shadow, labels "DOWNTOWN LOT", "MIDTOWN PLAZA", "RIVERSIDE PARK" small text, and "YOU ARE HERE".
OK, writing final code now. Long but let's go.
For the menu data, each item: id, name, price, desc, tags[], heat (0-3), icon type, badge.
Card layout:
```
<article class="card" data-cat="tacos">
<div class="card-top">
<div class="thumb">SVG</div>
<span class="badge">Best Seller</span>
</div>
<div class="card-body">
<h3>Name</h3>
<p>desc</p>
<div class="meta">tags + heat dots</div>
</div>
<div class="card-foot"><span class="price">$4.25</span><button class="add">+</button></div>
</article>
```
Cards in a grid, 4 columns desktop? With thumbs, 3 columns may be better. I'll use auto-fill minmax(240px,1fr).
Heat dots: 🌶 emoji or CSS dots. I'll use a small flame SVG repeated. Simpler: spans with class hot filled. Use "●" styling: 3 dots, filled = spicy. Add a label like "Medium".
Now writing the final answer.
Careful with template literals inside the JS containing backticks — fine since it's all in one code block. Avoid `</script>` inside strings.
Let me write.
One more: the "Click or press a key to start" message is for games. This isn't a game, so not needed. But the auto-rotating reviews act as self-playing content. Good.
Final code:
I'll write CSS thoroughly but efficiently.
Let me draft the JS sections:
1. Data + render menu
2. Filter
3. Cart state + add, toast, drawer render, pill update
4. Tilt effect on cards (desktop only, pointer: fine)
5. Reveal on scroll
6. Reviews rotator
7. Countdown
8. Spice builder
9. Mobile nav
10. Newsletter form success
11. Catering form validation + success
12. Year in footer
Let me write it.
For reveal: elements with class "reveal" get observer.
Time to output. I'll make sure the whole thing is valid.
Let me write the taco SVG function carefully:
```js
function tacoSVG(spice = 2, cls = "") {
let jal = "";
const spots = [[62,58],[100,46],[140,52],[178,44],[214,56],[246,66]];
for (let i = 0; i < spice && i < 6; i++) {
const [x,y] = spots[i];
jal += `<g class="jal"><circle cx="${x}" cy="${y}" r="9" fill="#6FBF3F"/><circle cx="${x}" cy="${y}" r="4" fill="#D9EFB0"/><circle cx="${x}" cy="${y}" r="9" fill="none" stroke="#2E7A22" stroke-width="1.5"/></g>`;
}
const glow = spice >= 4 ? `<circle cx="150" cy="70" r="95" fill="url(#fireGlow)"/>` : "";
return `
<svg class="taco-svg ${cls}" viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Illustration of a Korean taco">
<defs>
<linearGradient id="shell-${spice}" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#FBD75E"/><stop offset="1" stop-color="#EBA72C"/>
</linearGradient>
...
</defs>
...
</svg>`;
}
```
Problem: duplicate gradient IDs if multiple taco SVGs on page. I'll use unique id per instance via a counter.
Since IDs must be unique across the document, use a global counter `let uid=0;` and `const id = 'sh'+ (++uid)`.
Also the defs: shell gradient, fire glow radial.
Render hero taco once, and the builder re-renders on slider change (replacing innerHTML) → new uid each time; fine (old defs removed with element).
Let me write it all out now. I'll produce the final file.
For the fire glow radial gradient: `<radialGradient id="fire"><stop offset="0" stop-color="#FF6A2A" stop-opacity=".55"/><stop offset="1" stop-color="#FF6A2A" stop-opacity="0"/></radialGradient>`.
Also add tiny animated steam? Skip.
OK writing.
Review data: 4 reviews:
- "The Kimchi Carnitas taco ruined every other taco for me. I drive 20 minutes for it." — Dana R., Yelp ★★★★★
- "Best street food truck in the city, hands down. The bulgogi crunch taco is a religious experience." — Marcus T., Google
- "We booked them for our wedding and the line was out the door. Worth every penny." — Priya & Sam, Event
- "Finally, a vegan taco that doesn't taste like a compromise. The Bibimbap Bowl is 🔥" — Alex N., Instagram
Names + avatar initials + color.
Catering perks list.
FAQ:
1. Do you offer vegan/vegetarian options?
2. Is there gluten in your tortillas?
3. Can you cater our event?
4. Where exactly is the truck right now?
5. Do you accept online orders / cash?
Hours for locations.
Footer.
Let me write the final HTML now. I'll keep the code organized with comments.
Length will be long — that's fine.
Careful: In HTML, avoid unescaped `<` in text. Use < where needed.
Let me produce.