Food truck websiteOne-line
MiniMax M3.1 Flash
by MiniMaxReasoning1 console error
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 3 min 31 s
- Cost
- $0.022
- Output tokens
- 36,397
- Spent thinking
- 9,893 tokens
- Speed
- 173.2 tok/s
- Console errors
- 1
- First token after
- 781 ms
- First visible text after
- 1 min 16 s
- Prompt tokens
- 546
- Code size
- 80.2 KB
- Finish reason
- stop
- Served by
- Fireworks
- Model id
minimax/minimax-m3.1-flash- Reasoning sent
{"effort":"max"}- Max output
- 64,000 tokens
- Generated
- Nov 11, 2026
Console errors
Caught in the first 3 seconds after load, in a sandboxed iframe like the one above.
Unexpected token 'return'
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 · 1347 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kimchi Loco — Korean Taco Food Truck 🔥</title>
<meta name="description" content="Kimchi Loco: Korean street tacos on a food truck. Bulgogi, kimchi chicken, crispy tofu & gochujang house sauce. Find the truck, build your taco, eat loud.">
<style>
/* ============ TOKENS ============ */
:root{
--ink:#120F0C; --ink2:#1B1714; --ink3:#241E19;
--cream:#FFF3DE; --paper:#FFE7C4; --muted:#C9B69C;
--red:#E32B22; --red2:#A8140F; --orange:#FF7A2F; --yellow:#FFC93C;
--green:#43A95C; --purple:#9B4DBE; --blue:#2FA3C4;
--sans:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif;
--disp:Impact,Haettenschweiler,"Arial Narrow Bold","Franklin Gothic Heavy","Noto Sans",var(--sans);
--r:16px; --shadow:0 18px 40px rgba(0,0,0,.45);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
margin:0;background:var(--ink);color:var(--cream);font-family:var(--sans);
overflow-x:hidden;line-height:1.55;-webkit-font-smoothing:antialiased;
}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}
h1,h2,h3,h4{margin:0;line-height:1.02}
p{margin:0}
.container{width:min(1220px,92vw);margin-inline:auto}
.disp{font-family:var(--disp);font-weight:900;text-transform:uppercase;letter-spacing:.005em}
.sans{font-family:var(--sans)}
section{position:relative;padding:clamp(58px,8vw,110px) 0}
.eyebrow{
display:inline-flex;align-items:center;gap:.55rem;font-size:.72rem;letter-spacing:.22em;
text-transform:uppercase;font-weight:800;color:var(--yellow);
background:rgba(255,201,60,.08);border:1px solid rgba(255,201,60,.28);
padding:.4rem .85rem;border-radius:999px;
}
.section-title{font-size:clamp(2.3rem,6.2vw,4.4rem);margin:.9rem 0 .6rem;text-transform:uppercase;font-family:var(--disp);font-weight:900;line-height:.92}
.section-sub{color:var(--muted);max-width:62ch;font-size:clamp(1rem,1.6vw,1.12rem)}
.hot{color:var(--red)}
.hl{background:linear-gradient(180deg,transparent 58%,rgba(255,201,60,.85) 58%)}
/* ============ TICKER ============ */
.ticker{background:var(--red);border-bottom:3px solid var(--red2);overflow:hidden;position:relative;z-index:60}
.ticker-track{display:flex;width:max-content;animation:slide 28s linear infinite}
.ticker span{
padding:.42rem 0;font-family:var(--disp);font-size:.95rem;letter-spacing:.08em;
color:#fff;white-space:nowrap;text-transform:uppercase;padding-inline:1.1rem;
}
.ticker span i{font-style:normal;color:var(--yellow);margin:0 .5rem}
@keyframes slide{to{transform:translateX(-50%)}}
/* ============ NAV ============ */
#progress{position:fixed;top:0;left:0;height:3px;width:0;background:var(--yellow);z-index:200;transition:width .1s linear}
.nav{position:sticky;top:0;z-index:100;background:rgba(18,15,12,.82);backdrop-filter:blur(14px);border-bottom:1px solid rgba(255,243,222,.12)}
.nav-in{display:flex;align-items:center;gap:1.1rem;justify-content:space-between;padding:.7rem 0}
.brand{display:flex;align-items:center;gap:.6rem;flex:0 0 auto}
.brand-mark{width:42px;height:42px;filter:drop-shadow(0 4px 8px rgba(0,0,0,.5))}
.brand-text{display:flex;flex-direction:column;line-height:.86;font-family:var(--disp);font-size:1.22rem;letter-spacing:.04em}
.brand-text .loco{color:var(--yellow)}
.nav-links{display:flex;gap:1.5rem;align-items:center}
.nav-links a{font-size:.9rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--paper);opacity:.85;padding:.3rem 0;border-bottom:2px solid transparent;transition:.2s}
.nav-links a:hover{opacity:1;color:var(--yellow);border-color:var(--red)}
.nav-right{display:flex;align-items:center;gap:.6rem}
.status-pill{display:inline-flex;align-items:center;gap:.45rem;font-size:.72rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase;
border:1px solid rgba(255,243,222,.25);border-radius:999px;padding:.34rem .7rem;background:rgba(255,243,222,.06)}
.status-pill .dot{width:9px;height:9px;border-radius:50%;background:var(--muted)}
.status-pill.open .dot{background:#3BE06A;box-shadow:0 0 0 0 rgba(59,224,106,.7);animation:pulse 1.8s infinite}
.status-pill.open{border-color:rgba(59,224,106,.5);color:#9BFFC2}
@keyframes pulse{70%{box-shadow:0 0 0 9px rgba(59,224,106,0)}100%{box-shadow:0 0 0 0 rgba(59,224,106,0)}}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;border:0;cursor:pointer;border-radius:999px;
font-weight:900;letter-spacing:.06em;text-transform:uppercase;padding:.85rem 1.5rem;font-size:.85rem;transition:.18s transform,.18s box-shadow,.18s background}
.btn:hover{transform:translateY(-2px)}
.btn-red{background:var(--red);color:#fff;box-shadow:0 8px 0 var(--red2),0 14px 26px rgba(227,43,34,.35)}
.btn-red:hover{box-shadow:0 10px 0 var(--red2),0 18px 30px rgba(227,43,34,.45)}
.btn-yellow{background:var(--yellow);color:#20160a;box-shadow:0 8px 0 #c98f13,0 14px 26px rgba(255,201,60,.25)}
.btn-yellow:hover{box-shadow:0 10px 0 #c98f13,0 18px 30px rgba(255,201,60,.32)}
.btn-ghost{background:transparent;color:var(--cream);border:2px solid rgba(255,243,222,.35)}
.btn-ghost:hover{border-color:var(--yellow);color:var(--yellow)}
.btn-sm{padding:.6rem 1.05rem;font-size:.74rem}
.burger{display:none;background:none;border:1px solid rgba(255,243,222,.25);border-radius:10px;width:40px;height:38px;cursor:pointer;font-size:1.1rem}
.mobile-menu{display:none;flex-direction:column;gap:.2rem;padding:.6rem 0 1rem;border-top:1px solid rgba(255,243,222,.1)}
.mobile-menu a{padding:.7rem 0;font-weight:800;letter-spacing:.08em;text-transform:uppercase;border-bottom:1px solid rgba(255,243,222,.08)}
.mobile-menu.open{display:flex}
/* ============ HERO ============ */
.hero{overflow:hidden;padding-top:clamp(38px,6vw,72px);padding-bottom:0;
background:
radial-gradient(900px 520px at 76% 22%, rgba(255,122,47,.30), transparent 62%),
radial-gradient(760px 520px at 8% 78%, rgba(227,43,34,.24), transparent 62%),
var(--ink);}
.hero::before{content:"";position:absolute;inset:0;opacity:.16;
background:repeating-linear-gradient(115deg,rgba(255,243,222,.16) 0 2px,transparent 2px 26px);pointer-events:none}
.hero-grid{position:relative;display:grid;grid-template-columns:1.08fr .92fr;gap:clamp(20px,4vw,54px);align-items:center;padding-bottom:clamp(40px,6vw,70px)}
.watermark{position:absolute;right:-4%;top:6%;font-size:clamp(7rem,20vw,17rem);opacity:.055;color:var(--cream);
font-family:var(--disp);transform:rotate(-9deg);pointer-events:none;user-select:none;white-space:nowrap}
.hero h1{font-size:clamp(3.4rem,11.5vw,8.6rem);line-height:.84;margin:.55rem 0 0;font-family:var(--disp);font-weight:900;text-transform:uppercase}
.hero h1 .k{color:var(--cream);text-shadow:5px 5px 0 var(--red),10px 10px 0 rgba(227,43,34,.35)}
.hero h1 .l{color:var(--yellow);text-shadow:5px 5px 0 var(--red),10px 10px 0 rgba(227,43,34,.35);display:block}
.hero .hangul{font-family:var(--sans);font-size:clamp(.9rem,2.4vw,1.3rem);letter-spacing:.5em;color:var(--muted);margin-top:.7rem;font-weight:700}
.hero .lede{font-size:clamp(1.02rem,2.1vw,1.28rem);color:#EBDCC4;max-width:46ch;margin-top:1.1rem}
.hero .lede b{color:var(--yellow)}
.cta-row{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:1.6rem}
.hero-tags{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:1.3rem}
.hero-tags span{font-size:.7rem;font-weight:800;letter-spacing:.11em;text-transform:uppercase;border:1px solid rgba(255,243,222,.22);
color:var(--paper);padding:.36rem .7rem;border-radius:999px;background:rgba(255,243,222,.05)}
.hero-art{position:relative;display:grid;place-items:center;min-height:340px}
.hero-taco{width:min(100%,540px);filter:drop-shadow(0 30px 40px rgba(0,0,0,.55));animation:bob 5s ease-in-out infinite}
@keyframes bob{0%,100%{transform:translateY(0) rotate(-1.4deg)}50%{transform:translateY(-16px) rotate(1.4deg)}}
.steam path{stroke:rgba(255,243,222,.55);stroke-width:5;fill:none;stroke-linecap:round;stroke-dasharray:14 12;animation:steam 3.2s linear infinite}
.steam path:nth-child(2){animation-delay:1s}
.steam path:nth-child(3){animation-delay:2s}
@keyframes steam{to{stroke-dashoffset:-52;opacity:.1}}
.float-badge{position:absolute;background:var(--cream);color:#1b1207;padding:.5rem .85rem;border-radius:14px;font-weight:900;
font-size:.74rem;letter-spacing:.06em;text-transform:uppercase;box-shadow:var(--shadow);display:flex;align-items:center;gap:.4rem;animation:floaty 6s ease-in-out infinite}
.float-badge:nth-of-type(2){animation-delay:1.6s}
.float-badge:nth-of-type(3){animation-delay:3.1s}
.float-badge b{font-size:1.1rem}
@keyframes floaty{0%,100%{transform:translateY(0) rotate(-3deg)}50%{transform:translateY(-12px) rotate(3deg)}}
.fb1{top:6%;left:2%}
.fb2{bottom:16%;right:0;background:var(--yellow)}
.fb3{bottom:2%;left:6%;background:var(--red);color:#fff}
.status-card{margin-top:-2px;background:linear-gradient(180deg,var(--ink3),var(--ink2));border:1px solid rgba(255,243,222,.14);
border-radius:var(--r);padding:1.1rem 1.3rem;display:grid;grid-template-columns:auto 1fr auto;gap:1.1rem;align-items:center;
box-shadow:var(--shadow);position:relative;z-index:5}
.status-card .where{display:flex;align-items:center;gap:.75rem}
.status-card .where svg{width:34px;height:34px;flex:0 0 auto}
.status-card h4{font-size:1.05rem;font-family:var(--disp);letter-spacing:.04em;text-transform:uppercase;font-weight:900}
.status-card .meta{font-size:.86rem;color:var(--muted)}
.status-card .cd{text-align:right}
.status-card .cd b{display:block;font-family:var(--disp);font-size:1.6rem;color:var(--yellow);letter-spacing:.04em}
.status-card .cd span{font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);font-weight:800}
.chip{display:inline-flex;align-items:center;gap:.35rem;font-size:.68rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase;
background:rgba(227,43,34,.16);border:1px solid rgba(227,43,34,.4);color:#ff9b93;padding:.3rem .6rem;border-radius:999px}
/* ============ MARQUEE ============ */
.marquee{border-top:3px solid var(--ink);border-bottom:3px solid var(--ink);background:var(--yellow);color:#20160a;overflow:hidden;padding:.5rem 0}
.marquee-track{display:flex;width:max-content;animation:slide 24s linear infinite}
.marquee-track span{font-family:var(--disp);font-size:clamp(1.1rem,3vw,1.9rem);letter-spacing:.05em;padding-inline:1.2rem;white-space:nowrap}
.marquee-track span i{color:var(--red);font-style:normal}
/* ============ FEATURES ============ */
.features{background:var(--ink2)}
.feat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:1rem;margin-top:2.4rem}
.feat{background:var(--ink3);border:1px solid rgba(255,243,222,.1);border-radius:var(--r);padding:1.4rem 1.3rem;position:relative;overflow:hidden;transition:.25s}
.feat:hover{transform:translateY(-5px);border-color:var(--orange)}
.feat .ico{width:44px;height:44px;margin-bottom:.8rem}
.feat h4{font-family:var(--disp);font-size:1.22rem;letter-spacing:.03em;text-transform:uppercase;margin-bottom:.35rem}
.feat p{font-size:.92rem;color:var(--muted)}
.feat::after{content:"";position:absolute;right:-30px;top:-30px;width:90px;height:90px;border-radius:50%;background:radial-gradient(circle,rgba(255,122,47,.22),transparent 70%)}
/* ============ MENU ============ */
.tabs{display:flex;flex-wrap:wrap;gap:.5rem;margin:1.6rem 0 1.8rem}
.tab{background:transparent;border:2px solid rgba(255,243,222,.22);color:var(--paper);border-radius:999px;padding:.55rem 1.15rem;
font-weight:900;font-size:.78rem;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:.18s}
.tab:hover{border-color:var(--yellow);color:var(--yellow)}
.tab.active{background:var(--red);border-color:var(--red);color:#fff;box-shadow:0 6px 0 var(--red2)}
.menu-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(285px,1fr));gap:1.1rem}
.card{background:linear-gradient(180deg,#241E19,#1B1714);border:1px solid rgba(255,243,222,.11);border-radius:18px;padding:1.2rem;display:flex;flex-direction:column;gap:.6rem;
transition:.25s;position:relative;overflow:hidden}
.card:hover{transform:translateY(-6px);border-color:rgba(255,122,47,.6);box-shadow:0 22px 40px rgba(0,0,0,.45)}
.card.hidden{display:none}
.card-top{display:flex;align-items:flex-start;gap:.85rem}
.card-ico{width:52px;height:52px;flex:0 0 auto;border-radius:14px;background:rgba(255,201,60,.1);padding:7px}
.card h3{font-family:var(--disp);font-size:1.28rem;letter-spacing:.02em;text-transform:uppercase;flex:1}
.tag{display:inline-block;font-size:.6rem;font-weight:900;letter-spacing:.12em;background:var(--red);color:#fff;padding:.22rem .5rem;border-radius:6px;margin-top:.3rem}
.tag.g{background:var(--green)}.tag.y{background:var(--yellow);color:#20160a}.tag.p{background:var(--purple)}
.price{font-family:var(--disp);font-size:1.35rem;color:var(--yellow);letter-spacing:.03em}
.desc{font-size:.92rem;color:var(--muted);flex:1}
.card-foot{display:flex;align-items:center;justify-content:space-between;gap:.6rem;margin-top:.2rem}
.pep-row{display:flex;gap:3px}
.pep{width:17px;height:17px}
.pep.off{opacity:.22;filter:grayscale(1)}
.add-btn{background:rgba(255,243,222,.08);border:1px solid rgba(255,243,222,.25);color:var(--cream);border-radius:999px;
padding:.42rem .85rem;font-weight:900;font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:.18s}
.add-btn:hover{background:var(--yellow);color:#20160a;border-color:var(--yellow)}
.card-foot .add-btn.on{background:var(--green);border-color:var(--green);color:#06180c}
/* ============ TACO LAB ============ */
.lab{background:linear-gradient(180deg,var(--ink2),var(--ink))}
.lab-grid{display:grid;grid-template-columns:.95fr 1.05fr;gap:clamp(20px,3vw,40px);align-items:start}
.lab-preview{background:radial-gradient(600px 320px at 50% 40%,rgba(255,122,47,.16),transparent 70%),var(--ink3);
border:1px solid rgba(255,243,222,.12);border-radius:22px;padding:1.3rem;position:sticky;top:90px}
#pvSvg{width:100%;max-width:400px;margin:0 auto}
.pv-name{font-family:var(--disp);font-size:clamp(1.6rem,4vw,2.2rem);text-transform:uppercase;letter-spacing:.02em;text-align:center;margin-top:.4rem}
.pv-sub{text-align:center;color:var(--muted);font-size:.9rem;min-height:2.6em}
.pv-price{display:flex;align-items:center;justify-content:center;gap:.7rem;margin:.5rem 0 .9rem}
.pv-price b{font-family:var(--disp);font-size:2.3rem;color:var(--yellow)}
.pv-price button{background:rgba(255,243,222,.1);border:1px solid rgba(255,243,222,.25);border-radius:8px;width:34px;height:34px;cursor:pointer;font-weight:900}
.pv-price button:hover{background:var(--yellow);color:#20160a}
.heat-meter{display:flex;justify-content:center;align-items:center;gap:.35rem;margin-bottom:.2rem}
.heat-meter .pep{width:22px;height:22px}
.heat-label{text-align:center;font-weight:900;font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--red);margin-bottom:.7rem}
.opt-group{margin-bottom:1.25rem}
.opt-group > label,.opt-legend{display:block;font-size:.72rem;font-weight:900;letter-spacing:.16em;text-transform:uppercase;color:var(--yellow);margin-bottom:.6rem}
.chips{display:flex;flex-wrap:wrap;gap:.5rem}
.chip-opt{background:var(--ink3);border:2px solid rgba(255,243,222,.16);border-radius:12px;padding:.55rem .85rem;cursor:pointer;
font-weight:800;font-size:.83rem;transition:.16s;display:flex;align-items:center;gap:.4rem}
.chip-opt small{color:var(--muted);font-weight:700;font-size:.72rem}
.chip-opt:hover{border-color:var(--orange)}
.chip-opt.sel{background:var(--red);border-color:var(--red);color:#fff;box-shadow:0 5px 0 var(--red2)}
.chip-opt.sel small{color:#ffd2cd}
.chip-opt.toggle{border-radius:999px}
.chip-opt.toggle.sel{background:var(--green);border-color:var(--green);box-shadow:0 5px 0 #1f6b34}
.chip-opt.toggle.sel small{color:#cdf7d8}
input[type=range]{width:100%;-webkit-appearance:none;height:12px;border-radius:999px;background:linear-gradient(90deg,#3BE06A,#FFC93C,#FF7A2F,#E32B22);outline:none;margin:.2rem 0 .4rem}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:26px;height:26px;border-radius:50%;background:#fff;border:4px solid var(--red);cursor:pointer;box-shadow:0 4px 10px rgba(0,0,0,.5)}
.lab-cta{display:flex;gap:.7rem;flex-wrap:wrap;margin-top:.4rem}
.lab-note{font-size:.78rem;color:var(--muted);margin-top:.8rem}
/* ============ LOCATIONS / MAP ============ */
.truck{background:var(--ink2)}
.truck-grid{display:grid;grid-columns:1.15fr .85fr;gap:clamp(18px,3vw,38px);align-items:start;margin-top:2rem}
.map-wrap{border:1px solid rgba(255,243,222,.13);border-radius:20px;overflow:hidden;background:#171512;position:relative}
.map{width:100%;height:auto;display:block}
.map-legend{position:absolute;left:14px;bottom:14px;background:rgba(18,15,12,.85);border:1px solid rgba(255,243,222,.16);
border-radius:10px;padding:.5rem .7rem;font-size:.72rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;display:flex;align-items:center;gap:.45rem}
.map-legend i{width:10px;height:10px;border-radius:50%;background:var(--red);display:inline-block;animation:pulse 1.8s infinite}
.loc-list{display:flex;flex-direction:column;gap:.55rem}
.loc{display:grid;grid-template-columns:auto 1fr auto;gap:.8rem;align-items:center;background:var(--ink3);border:1px solid rgba(255,243,222,.1);
border-radius:14px;padding:.75rem .9rem;transition:.2s}
.loc:hover{border-color:var(--orange);transform:translateX(4px)}
.loc.today{border-color:var(--red);background:linear-gradient(90deg,rgba(227,43,34,.18),var(--ink3));box-shadow:0 0 0 1px rgba(227,43,34,.35)}
.loc .day{font-family:var(--disp);font-size:1.1rem;width:46px;text-align:center;color:var(--muted);letter-spacing:.04em}
.loc.today .day{color:var(--yellow)}
.loc .place{font-weight:800;font-size:.98rem}
.loc .addr{font-size:.8rem;color:var(--muted)}
.loc .hrs{font-size:.76rem;font-weight:800;color:var(--paper);text-align:right;letter-spacing:.03em}
.loc .badge-today{font-size:.58rem;background:var(--red);color:#fff;border-radius:5px;padding:.12rem .35rem;font-weight:900;letter-spacing:.1em;margin-left:.4rem}
/* ============ REVIEWS ============ */
.reviews{background:var(--ink)}
.rev-box{background:linear-gradient(180deg,#241E19,#1B1714);border:1px solid rgba(255,243,222,.12);border-radius:22px;padding:clamp(1.5rem,4vw,3rem);position:relative;overflow:hidden}
.rev-box::before{content:"\201C";position:absolute;top:-40px;left:12px;font-size:220px;color:rgba(255,201,60,.14);font-family:Georgia,serif}
.rev-slide{display:none;position:relative}
.rev-slide.active{display:block;animation:fadeIn .45s ease}
@keyframes fadeIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.rev-slide p{font-size:clamp(1.08rem,2.4vw,1.55rem);font-weight:600;max-width:60ch;margin-bottom:1.1rem;line-height:1.45}
.rev-who{display:flex;align-items:center;gap:.8rem}
.rev-av{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;font-weight:900;color:#20160a;font-family:var(--disp)}
.rev-who b{display:block;font-size:.98rem}
.rev-who span{font-size:.8rem;color:var(--muted)}
.stars{color:var(--yellow);letter-spacing:.15em;font-size:.95rem}
.rev-nav{display:flex;align-items:center;gap:.6rem;margin-top:1.6rem}
.rev-btn{width:42px;height:42px;border-radius:50%;background:transparent;border:2px solid rgba(255,243,222,.25);cursor:pointer;font-weight:900;transition:.18s}
.rev-btn:hover{background:var(--yellow);color:#20160a;border-color:var(--yellow)}
.rev-dots{display:flex;gap:.4rem;margin-left:.5rem}
.rev-dot{width:9px;height:9px;border-radius:50%;background:rgba(255,243,222,.25);border:0;cursor:pointer;padding:0}
.rev-dot.active{background:var(--red);width:26px;border-radius:99px}
.rating-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:1rem;margin-top:1.4rem}
.rstat{background:var(--ink3);border:1px solid rgba(255,243,222,.1);border-radius:16px;padding:1.1rem;text-align:center}
.rstat b{display:block;font-family:var(--disp);font-size:2rem;color:var(--yellow);line-height:1}
.rstat span{font-size:.74rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:800}
/* ============ ORDER / CATERING ============ */
.cater{background:linear-gradient(180deg,var(--ink2),var(--ink))}
.cater-grid{display:grid;grid-template-columns:.85fr 1.15fr;gap:clamp(20px,3vw,44px);align-items:center}
.perk{display:flex;gap:.8rem;align-items:flex-start;margin-bottom:1rem}
.perk .dotc{width:26px;height:26px;border-radius:50%;background:var(--red);display:grid;place-items:center;font-size:.8rem;flex:0 0 auto}
.perk b{display:block;font-family:var(--disp);letter-spacing:.03em;text-transform:uppercase;font-size:1.05rem}
.perk span{color:var(--muted);font-size:.9rem}
form.order-card{background:var(--ink3);border:1px solid rgba(255,243,222,.12);border-radius:20px;padding:clamp(1.2rem,3vw,2rem);display:grid;gap:.9rem;grid-template-columns:1fr 1fr}
.field{display:flex;flex-direction:column;gap:.35rem}
.field.full{grid-column:1/-1}
.field label{font-size:.7rem;font-weight:900;letter-spacing:.14em;text-transform:uppercase;color:var(--yellow)}
.field input,.field select{background:var(--ink);border:1px solid rgba(255,243,222,.2);border-radius:12px;padding:.78rem .9rem;outline:none;transition:.18s}
.field input:focus,.field select:focus{border-color:var(--yellow);box-shadow:0 0 0 3px rgba(255,201,60,.18)}
.form-msg{display:none;grid-column:1/-1;background:rgba(67,169,92,.15);border:1px solid var(--green);border-radius:12px;padding:.9rem 1rem;font-weight:800;color:#a9f0bd}
.form-msg.show{display:block}
/* ============ FOOTER ============ */
footer{background:var(--ink3);border-top:3px solid var(--red);padding:clamp(44px,6vw,74px) 0 2rem}
.foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1.2fr;gap:2rem}
.foot h4{font-family:var(--disp);font-size:1.1rem;letter-spacing:.06em;text-transform:uppercase;margin-bottom:.8rem;color:var(--yellow)}
.foot a{display:block;color:var(--muted);font-size:.92rem;padding:.22rem 0;transition:.15s}
.foot a:hover{color:var(--cream);transform:translateX(3px)}
.foot p{color:var(--muted);font-size:.92rem;max-width:34ch}
.news{display:flex;gap:.5rem;margin-top:.9rem}
.news input{flex:1;background:var(--ink);border:1px solid rgba(255,243,222,.2);border-radius:999px;padding:.75rem 1rem;outline:none}
.news input:focus{border-color:var(--yellow)}
.foot-bottom{display:flex;flex-wrap:wrap;gap:.8rem;justify-content:space-between;align-items:center;border-top:1px solid rgba(255,243,222,.12);
margin-top:2.4rem;padding-top:1.3rem;font-size:.8rem;color:var(--muted)}
.socials{display:flex;gap:.5rem}
.socials a{width:38px;height:38px;border-radius:50%;border:1px solid rgba(255,243,222,.25);display:grid;place-items:center;font-size:.8rem;font-weight:900;color:var(--cream)}
.socials a:hover{background:var(--red);border-color:var(--red)}
/* ============ CART + TOAST ============ */
.cart-btn{position:fixed;right:18px;bottom:18px;z-index:90;background:var(--red);color:#fff;border:0;border-radius:999px;
padding:.8rem 1.2rem;font-weight:900;letter-spacing:.06em;text-transform:uppercase;font-size:.78rem;cursor:pointer;box-shadow:0 10px 26px rgba(227,43,34,.45);display:flex;align-items:center;gap:.5rem}
.cart-count{background:var(--yellow);color:#20160a;border-radius:999px;min-width:22px;height:22px;display:grid;place-items:center;font-size:.72rem}
.cart-panel{position:fixed;right:18px;bottom:82px;width:min(360px,92vw);background:var(--ink3);border:1px solid rgba(255,243,222,.16);
border-radius:18px;padding:1.1rem;box-shadow:var(--shadow);z-index:91;display:none}
.cart-panel.open{display:block;animation:pop .22s ease}
@keyframes pop{from{opacity:0;transform:translateY(10px) scale(.97)}to{opacity:1;transform:none}}
.cart-panel h4{font-family:var(--disp);font-size:1.15rem;text-transform:uppercase;letter-spacing:.04em;margin-bottom:.7rem}
.cart-item{display:flex;justify-content:space-between;gap:.6rem;font-size:.88rem;padding:.4rem 0;border-bottom:1px dashed rgba(255,243,222,.14)}
.cart-item span:last-child{font-weight:900;color:var(--yellow)}
.cart-total{display:flex;justify-content:space-between;font-family:var(--disp);font-size:1.2rem;letter-spacing:.04em;padding:.7rem 0}
.cart-empty{color:var(--muted);font-size:.86rem;padding:.4rem 0 1rem}
.toast{position:fixed;left:50%;bottom:26px;transform:translate(-50%,120%);background:var(--yellow);color:#20160a;padding:.85rem 1.3rem;
border-radius:999px;font-weight:900;font-size:.85rem;letter-spacing:.05em;z-index:120;box-shadow:0 14px 30px rgba(0,0,0,.5);transition:transform .35s cubic-bezier(.2,1.3,.4,1);max-width:90vw;text-align:center}
.toast.show{transform:translate(-50%,0)}
/* ============ REVEAL ============ */
.reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.3,1)}
.reveal.in{opacity:1;transform:none}
/* ============ RESPONSIVE ============ */
@media (max-width:980px){
.nav-links{display:none}.burger{display:block}
.hero-grid{grid-template-columns:1fr;text-align:center}
.hero .lede{margin-inline:auto}.cta-row,.hero-tags{justify-content:center}
.hero-art{order:-1;min-height:260px}
.float-badge{display:none}
.status-card{grid-template-columns:1fr;text-align:center;gap:.7rem}
.status-card .where{justify-content:center}.status-card .cd{text-align:center}
.lab-grid,.truck-grid,.cater-grid{grid-template-columns:1fr}
.lab-preview{position:relative;top:0}
.foot-grid{grid-template-columns:1fr 1fr}
}
@media (max-width:560px){
.menu-grid{grid-template-columns:1fr}
.foot-grid{grid-template-columns:1fr}
form.order-card{grid-template-columns:1fr}
.status-pill span{display:none}
.status-pill{padding:.4rem}
.hero h1{font-size:clamp(3rem,17vw,5rem)}
.card-top{flex-wrap:wrap}
}
@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;transition-duration:.01ms!important}}
</style>
</head>
<body>
<div id="progress"></div>
<!-- ===== SVG SPRITE ===== -->
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
<defs>
<linearGradient id="gShell" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#FFE39A"/><stop offset=".55" stop-color="#F0BC5C"/><stop offset="1" stop-color="#D2913A"/>
</linearGradient>
<linearGradient id="gMeat" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#8A3A12"/><stop offset="1" stop-color="#5E2408"/>
</linearGradient>
<linearGradient id="gCup" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#FFF7E8"/><stop offset="1" stop-color="#E8D3AE"/>
</linearGradient>
<symbol id="ico-taco" viewBox="0 0 64 64">
<path d="M6 48 A26 26 0 0 1 58 48 Z" fill="url(#gShell)"/>
<path d="M11 44 q3-14 10-7 q3-14 11-6 q4-11 11-5 q7-9 11 6 l-3 10 z" fill="#4FB15C"/>
<path d="M14 42 q3-9 8-4 q4-9 10-3 q4-8 9-3 q6-6 9 5 l-2 8 z" fill="#A8451C"/>
<path d="M22 30 q10 6 20 0" stroke="#FFC93C" stroke-width="3" fill="none" stroke-linecap="round"/>
</symbol>
<symbol id="ico-fries" viewBox="0 0 64 64">
<rect x="21" y="10" width="5" height="26" rx="2" fill="#FFD84D" transform="rotate(-12 23 23)"/>
<rect x="30" y="6" width="5" height="30" rx="2" fill="#FFC93C"/>
<rect x="39" y="10" width="5" height="26" rx="2" fill="#FFD84D" transform="rotate(12 41 23)"/>
<path d="M15 28h34l-5 28H20z" fill="#E32B22"/>
<path d="M15 28h34l-1.5 8H16.5z" fill="#fff" opacity=".85"/>
</symbol>
<symbol id="ico-cup" viewBox="0 0 64 64">
<path d="M18 18h28l-4 40H22z" fill="url(#gCup)"/>
<rect x="15" y="13" width="34" height="7" rx="3.5" fill="#FFF7E8"/>
<path d="M40 14 L48 4" stroke="#E32B22" stroke-width="4" stroke-linecap="round"/>
<path d="M22 30h18l-2 20H24z" fill="#FFB347" opacity=".9"/>
</symbol>
<symbol id="ico-bowl" viewBox="0 0 64 64">
<path d="M8 30h48c0 15-11 26-24 26S8 45 8 30z" fill="#2FA3C4"/>
<path d="M12 30c0-8 9-13 20-13s20 5 20 13z" fill="#FFF7E8"/>
<circle cx="26" cy="26" r="3" fill="#E32B22"/><circle cx="36" cy="24" r="3" fill="#FFC93C"/>
</symbol>
<symbol id="ico-pep" viewBox="0 0 24 24">
<path d="M12.6 4.2c3.9.6 6.6 4.1 6.4 8.2-.2 4.3-3.3 7.3-7.2 7.4 1.9-2.4 2.6-5.4 2.1-8.2-.4-2.4-1.2-4.9-1.3-7.4z" fill="#E32B22"/>
<path d="M11.9 4.6c-.3-1.7.6-3.2 2.6-3.8.3 1.9-.4 3.3-1.6 4.3z" fill="#43A95C"/>
<path d="M13.4 6.2c2.2.6 3.6 2.2 4 4.2" stroke="#fff" stroke-opacity=".55" stroke-width="1.2" fill="none" stroke-linecap="round"/>
</symbol>
<symbol id="ico-truck" viewBox="0 0 64 64">
<path d="M4 18h32v26H4z" fill="#E32B22"/>
<path d="M36 26h12l10 11v7H36z" fill="#FFC93C"/>
<rect x="8" y="24" width="18" height="9" rx="2" fill="#FFF3DE" opacity=".9"/>
<circle cx="18" cy="46" r="7" fill="#1B1714"/><circle cx="18" cy="46" r="2.6" fill="#FFF3DE"/>
<circle cx="48" cy="46" r="7" fill="#1B1714"/><circle cx="48" cy="46" r="2.6" fill="#FFF3DE"/>
<path d="M8 12c4-4 12-4 16 0" stroke="#fff" stroke-width="2.4" fill="none" stroke-linecap="round" opacity=".8"/>
</symbol>
<symbol id="ico-pin" viewBox="0 0 64 64">
<path d="M32 58s18-18 18-30A18 18 0 1 0 14 28c0 12 18 30 18 30z" fill="#E32B22"/>
<circle cx="32" cy="27" r="7" fill="#FFF3DE"/>
</symbol>
<symbol id="ico-star" viewBox="0 0 24 24">
<path d="M12 2l3 6.6 7 .9-5.2 4.8 1.4 7L12 17.9 5.8 21.3l1.4-7L2 9.5l7-.9z" fill="#FFC93C"/>
</symbol>
<symbol id="ico-leaf" viewBox="0 0 24 24">
<path d="M20 3C10 3 4 8 4 15c0 3 2 6 5 6 8 0 11-9 11-18z" fill="#43A95C"/>
<path d="M4 21c3-6 8-10 13-13" stroke="#FFF3DE" stroke-width="1.6" fill="none"/>
</symbol>
<symbol id="ico-flame" viewBox="0 0 24 24">
<path d="M12 2c4 5 7 7 7 12a7 7 0 0 1-14 0c0-3 1.5-5 3-7 .3 2 1 3 2 3 1.5 0 2-1.6 2-3 0-1.6-.6-3 0-5z" fill="#FF7A2F"/>
</symbol>
<symbol id="ico-clock" viewBox="0 0 64 64">
<circle cx="32" cy="32" r="26" fill="none" stroke="#FFC93C" stroke-width="5"/>
<path d="M32 16v18l12 7" stroke="#FFF3DE" stroke-width="5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
</defs>
</svg>
<!-- ===== TICKER ===== -->
<div class="ticker" aria-hidden="true">
<div class="ticker-track">
<span>Fresh Kimchi Daily<i>★</i>Hand-Pulled Gochujang<i>★</i>24-Hour Bulgogi Marinade<i>★</i>Street Tacos, Big Flavor<i>★</i>Est. 2019<i>★</i></span>
<span>Fresh Kimchi Daily<i>★</i>Hand-Pulled Gochujang<i>★</i>24-Hour Bulgogi Marinade<i>★</i>Street Tacos, Big Flavor<i>★</i>Est. 2019<i>★</i></span>
</div>
</div>
<!-- ===== NAV ===== -->
<header class="nav" id="nav">
<div class="container nav-in">
<a class="brand" href="#top" aria-label="Kimchi Loco home">
<svg class="brand-mark" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<span class="brand-text"><b>KIMCHI</b><b class="loco">LOCO</b></span>
</a>
<nav class="nav-links">
<a href="#menu">Menu</a>
<a href="#lab">Taco Lab</a>
<a href="#truck">Find The Truck</a>
<a href="#reviews">Reviews</a>
<a href="#cater">Catering</a>
</nav>
<div class="nav-right">
<span class="status-pill" id="statusPill"><i class="dot"></i><span id="statusText">CHECKING…</span></span>
<a href="#lab" class="btn btn-red btn-sm">Order</a>
<button class="burger" id="burger" aria-label="Open menu">☰</button>
</div>
</div>
<div class="container mobile-menu" id="mobileMenu">
<a href="#menu">Menu</a><a href="#lab">Taco Lab</a><a href="#truck">Find The Truck</a>
<a href="#reviews">Reviews</a><a href="#cater">Catering</a><a href="#lab">Order Now</a>
</div>
</header>
<main id="top">
<!-- ===== HERO ===== -->
<section class="hero" style="padding-bottom:0">
<div class="watermark hangul">김치로코</div>
<div class="container hero-grid">
<div>
<span class="eyebrow">🔥 Korean street tacos on wheels</span>
<h1 class="disp"><span class="k">Kimchi</span><span class="l">Loco</span></h1>
<p class="hangul" style="letter-spacing:.55em">김치 로코</p>
<p class="lede">Crispy-edged tortillas, <b>24-hour marinated bulgogi</b>, house gochujang sauce, and a crunch of fresh kimchi in every single bite. <b>Hot enough to ruin your lunch.</b></p>
<div class="cta-row">
<a href="#lab" class="btn btn-red">Build Your Taco</a>
<a href="#menu" class="btn btn-ghost">See The Menu</a>
</div>
<div class="hero-tags">
<span>🌮 12 signature tacos</span><span>🥬 Veggie options</span><span>🍜 Halal-friendly</span><span>⏱️ 6 min average wait</span>
</div>
</div>
<div class="hero-art">
<svg class="hero-taco" viewBox="0 0 320 300" role="img" aria-label="A loaded kimchi taco">
<g class="steam">
<path d="M120 60c-10-18 10-26 0-44"/>
<path d="M160 40c-11-20 11-28 0-48"/>
<path d="M200 62c-9-17 9-24 0-40"/>
</g>
<ellipse cx="160" cy="272" rx="110" ry="14" fill="#000" opacity=".35"/>
<!-- lettuce -->
<g fill="#4FB15C">
<circle cx="58" cy="190" r="26"/><circle cx="92" cy="150" r="27"/><circle cx="132" cy="124" r="26"/>
<circle cx="176" cy="112" r="27"/><circle cx="216" cy="128" r="26"/><circle cx="250" cy="158" r="26"/><circle cx="268" cy="192" r="24"/>
</g>
<!-- kimchi -->
<g fill="#E32B22">
<path d="M74 172q22-20 44-4t40-16q-8 26-32 30t-52-10z"/>
<path d="M150 120q20-16 38-2t38-10q-6 22-28 26t-48-14z" opacity=".9"/>
</g>
<!-- protein -->
<g fill="#8A3A12">
<circle cx="104" cy="146" r="19"/><circle cx="140" cy="128" r="18"/><circle cx="178" cy="120" r="18"/>
<circle cx="214" cy="136" r="18"/><circle cx="242" cy="160" r="17"/>
</g>
<!-- cheese -->
<path d="M60 178q24 16 48 2t52 4 52-8" stroke="#FFC93C" stroke-width="8" fill="none" stroke-linecap="round"/>
<!-- sauce -->
<path d="M86 160q16 12 34 2t38 2" stroke="#E32B22" stroke-width="5" fill="none" stroke-linecap="round" opacity=".9"/>
<!-- shell -->
<path d="M30 250 A130 130 0 0 1 290 250 Z" fill="url(#gShell)"/>
<path d="M30 250 A130 130 0 0 1 290 250 Z" fill="none" stroke="#B5762A" stroke-width="3" opacity=".7"/>
<g fill="#FFF3DE" opacity=".85">
<ellipse cx="76" cy="206" rx="6" ry="3" transform="rotate(-40 76 206)"/>
<ellipse cx="116" cy="170" rx="6" ry="3" transform="rotate(-25 116 170)"/>
<ellipse cx="160" cy="156" rx="6" ry="3"/>
<ellipse cx="204" cy="170" rx="6" ry="3" transform="rotate(25 204 170)"/>
<ellipse cx="244" cy="206" rx="6" ry="3" transform="rotate(40 244 206)"/>
<ellipse cx="136" cy="222" rx="6" ry="3" transform="rotate(-12 136 222)"/>
<ellipse cx="186" cy="222" rx="6" ry="3" transform="rotate(12 186 222)"/>
</g>
<path d="M44 236q30-66 116-72 86 6 116 72z" fill="#fff" opacity=".08"/>
</svg>
<div class="float-badge fb1">🌶️ <span>House Gochujang</span></div>
<div class="float-badge fb2">🥩 <span>24hr Marinade</span></div>
<div class="float-badge fb3">🔥 <span>Actual Heat</span></div>
</div>
</div>
<div class="container">
<div class="status-card reveal">
<div class="where">
<svg viewBox="0 0 64 64"><use href="#ico-pin"/></svg>
<div>
<h4 id="todayPlace">Eastside Lot</h4>
<div class="meta" id="todayAddr">5th & Mission — Street Food Row</div>
</div>
</div>
<div class="where" style="justify-content:center">
<svg viewBox="0 0 64 64"><use href="#ico-clock"/></svg>
<div>
<span class="chip" id="openChip">Open now</span>
<div class="meta" id="todayHours">11:30 AM — 9:00 PM</div>
</div>
</div>
<div class="cd">
<b id="countdown">--:--</b>
<span id="countdownLabel">until we close</span>
</div>
</div>
</div>
</section>
<div class="marquee" aria-hidden="true">
<div class="marquee-track">
<span>Bulgogi Bomb <i>✦</i> Kimchi Tears <i>✦</i> Shrimp Dynamite <i>✦</i> Tofu Tantrum <i>✦</i> Belly Flop <i>✦</i> </span>
<span>Bulgogi Bomb <i>✦</i> Kimchi Tears <i>✦</i> Shrimp Dynamite <i>✦</i> Tofu Tantrum <i>✦</i> Belly Flop <i>✦</i> </span>
</div>
</div>
<!-- ===== FEATURES ===== -->
<section class="features">
<div class="container">
<span class="eyebrow">Why the line wraps the block</span>
<h2 class="section-title">We do it <span class="hot">different</span></h2>
<p class="section-sub">No freezer, no shortcuts, no sad gas-station tortillas. Everything is built to order, right in front of you, at 400°F.</p>
<div class="feat-grid">
<div class="feat reveal">
<svg class="ico" viewBox="0 0 24 24"><use href="#ico-leaf"/></svg>
<h4>Kimchi made daily</h4>
<p>Napa cabbage, daikon, garlic, gochugaru — fermented 3 days in our kitchen, chopped every morning.</p>
</div>
<div class="feat reveal">
<svg class="ico" viewBox="0 0 24 24"><use href="#ico-flame"/></svg>
<h4>Sauce from scratch</h4>
<p>Gochujang fermented for two years, blended with sesame oil, rice vinegar and a whisper of honey.</p>
</div>
<div class="feat reveal">
<svg class="ico" viewBox="0 0 24 24"><use href="#ico-star"/></svg>
<h4>Marinated 24 hours</h4>
<p>Thin-sliced ribeye and chicken thigh soak in soy, pear juice and garlic. You can taste it.</p>
</div>
<div class="feat reveal">
<svg class="ico" viewBox="0 0 24 24"><use href="#ico-taco"/></svg>
<h4>Everybody gets a taco</h4>
<p>Six vegan options, halal-certified chicken & beef, and gluten-free lettuce wraps on request.</p>
</div>
</div>
</div>
</section>
<!-- ===== MENU ===== -->
<section id="menu">
<div class="container">
<span class="eyebrow">The Menu</span>
<h2 class="section-title">Pick your <span class="hot">weapon</span></h2>
<p class="section-sub">Every taco comes with kimchi slaw, sesame-lime crema and a hot towel. Pick your poison below.</p>
<div class="tabs" id="menuTabs">
<button class="tab active" data-filter="all">Everything</button>
<button class="tab" data-filter="tacos">Tacos</button>
<button class="tab" data-filter="sides">Sides</button>
<button class="tab" data-filter="drinks">Drinks</button>
<button class="tab" data-filter="combos">Combos</button>
</div>
<div class="menu-grid" id="menuGrid">
<article class="card reveal" data-cat="tacos" data-heat="3">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<div style="flex:1"><h3>Bulgogi Bomb</h3><span class="tag">Best seller</span></div>
<span class="price">$4.50</span>
</div>
<p class="desc">Thin-sliced marinated ribeye, gochujang glaze, kimchi slaw, sesame-lime crema, crispy onion.</p>
<div class="card-foot"><div class="pep-row" data-heat="3"></div><button class="add-btn" data-item="Bulgogi Bomb" data-price="4.50">Add</button></div>
</article>
<article class="card reveal" data-cat="tacos" data-heat="4">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<div style="flex:1"><h3>Kimchi Tears</h3><span class="tag">Cries in 3 bites</span></div>
<span class="price">$4.25</span>
</div>
<p class="desc">Buttermilk-brined chicken thigh, kimchi mayo, pickled red onion, sugar dust. Our most-ordered taco.</p>
<div class="card-foot"><div class="pep-row" data-heat="4"></div><button class="add-btn" data-item="Kimchi Tears" data-price="4.25">Add</button></div>
</article>
<article class="card reveal" data-cat="tacos" data-heat="2">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<div style="flex:1"><h3>Shrimp Dynamite</h3><span class="tag y">Crispy</span></div>
<span class="price">$5.50</span>
</div>
<p class="desc">Tempura shrimp, ssamjang drizzle, yuzu mayo, shredded lettuce, nori crunch.</p>
<div class="card-foot"><div class="pep-row" data-heat="2"></div><button class="add-btn" data-item="Shrimp Dynamite" data-price="5.50">Add</button></div>
</article>
<article class="card reveal" data-cat="tacos" data-heat="3">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<div style="flex:1"><h3>Tofu Tantrum</h3><span class="tag g">Vegan</span></div>
<span class="price">$3.95</span>
</div>
<p class="desc">Crispy sesame tofu, spicy kimchi, garlic aioli, scallion, pickled jalapeño.</p>
<div class="card-foot"><div class="pep-row" data-heat="3"></div><button class="add-btn" data-item="Tofu Tantrum" data-price="3.95">Add</button></div>
</article>
<article class="card reveal" data-cat="tacos" data-heat="4">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<div style="flex:1"><h3>Belly Flop</h3><span class="tag p">Chef's pick</span></div>
<span class="price">$4.95</span>
</div>
<p class="desc">Caramelized pork belly, kimchi, fried egg, sriracha mayo, burnt scallion. Sinful.</p>
<div class="card-foot"><div class="pep-row" data-heat="4"></div><button class="add-btn" data-item="Belly Flop" data-price="4.95">Add</button></div>
</article>
<article class="card reveal" data-cat="tacos" data-heat="5">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<div style="flex:1"><h3>Gochujang Jack</h3><span class="tag g">Vegan</span></div>
<span class="price">$4.50</span>
</div>
<p class="desc">Smoky jackfruit & king oyster mushroom, gochujang glaze, crispy shallot, cilantro.</p>
<div class="card-foot"><div class="pep-row" data-heat="5"></div><button class="add-btn" data-item="Gochujang Jack" data-price="4.50">Add</button></div>
</article>
<article class="card reveal" data-cat="sides" data-heat="2">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-fries"/></svg>
<div style="flex:1"><h3>Kimchi Fries</h3><span class="tag">Must order</span></div>
<span class="price">$5.50</span>
</div>
<p class="desc">Skin-on fries, kimchi butter, melted cheese, scallion, sesame, gochujang drizzle.</p>
<div class="card-foot"><div class="pep-row" data-heat="2"></div><button class="add-btn" data-item="Kimchi Fries" data-price="5.50">Add</button></div>
</article>
<article class="card reveal" data-cat="sides" data-heat="1">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<div style="flex:1"><h3>Mandu x6</h3><span class="tag g">Veggie</span></div>
<span class="price">$6.00</span>
</div>
<p class="desc">Pan-fried dumplings — kimchi & tofu, beef & glass noodle, or spicy cheese. Picked to order.</p>
<div class="card-foot"><div class="pep-row" data-heat="1"></div><button class="add-btn" data-item="Mandu (6)" data-price="6.00">Add</button></div>
</article>
<article class="card reveal" data-cat="sides" data-heat="1">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-fries"/></svg>
<div style="flex:1"><h3>Cheese Corn Dog</h3><span class="tag y">Fair food</span></div>
<span class="price">$4.50</span>
</div>
<p class="desc">Crispy panko shell, mozzarella pull, gochujang ketchup, kimchi slaw on the side.</p>
<div class="card-foot"><div class="pep-row" data-heat="1"></div><button class="add-btn" data-item="Cheese Corn Dog" data-price="4.50">Add</button></div>
</article>
<article class="card reveal" data-cat="sides" data-heat="0">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-fries"/></svg>
<div style="flex:1"><h3>Seaweed Crinkle Chips</h3><span class="tag g">Vegan</span></div>
<span class="price">$3.50</span>
</div>
<p class="desc">Crinkle-cut sweet potato & potato chips, sea salt, nori dust. Crunchy on purpose.</p>
<div class="card-foot"><div class="pep-row" data-heat="0"></div><button class="add-btn" data-item="Seaweed Chips" data-price="3.50">Add</button></div>
</article>
<article class="card reveal" data-cat="drinks" data-heat="0">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-cup"/></svg>
<div style="flex:1"><h3>Yuzu Lemonade</h3><span class="tag g">Not spicy</span></div>
<span class="price">$3.50</span>
</div>
<p class="desc">Fresh-squeezed lemon, yuzu, honey, soda. The official taco chaser.</p>
<div class="card-foot"><div class="pep-row" data-heat="0"></div><button class="add-btn" data-item="Yuzu Lemonade" data-price="3.50">Add</button></div>
</article>
<article class="card reveal" data-cat="drinks" data-heat="0">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-cup"/></svg>
<div style="flex:1"><h3>Thai Iced Tea</h3><span class="tag y">Sweet</span></div>
<span class="price">$4.00</span>
</div>
<p class="desc">Strong black tea, condensed milk, star anise. Served with a lime wedge & straw.</p>
<div class="card-foot"><div class="pep-row" data-heat="0"></div><button class="add-btn" data-item="Thai Iced Tea" data-price="4.00">Add</button></div>
</article>
<article class="card reveal" data-cat="drinks" data-heat="0">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-bowl"/></svg>
<div style="flex:1"><h3>Bingsu Barley</h3><span class="tag y">Summer</span></div>
<span class="price">$5.50</span>
</div>
<p class="desc">Shaved ice, roasted barley, condensed milk, fruit cocktail, condensed milk drizzle.</p>
<div class="card-foot"><div class="pep-row" data-heat="0"></div><button class="add-btn" data-item="Bingsu Barley" data-price="5.50">Add</button></div>
</article>
<article class="card reveal" data-cat="drinks" data-heat="0">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-cup"/></svg>
<div style="flex:1"><h3>Soju Lemon Spritz</h3><span class="tag">21+</span></div>
<span class="price">$6.00</span>
</div>
<p class="desc">Korean soju, fresh lemon, soda, a lot of ice. Dangerous after two tacos.</p>
<div class="card-foot"><div class="pep-row" data-heat="0"></div><button class="add-btn" data-item="Soju Lemon Spritz" data-price="6.00">Add</button></div>
</article>
<article class="card reveal" data-cat="combos" data-heat="3">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<div style="flex:1"><h3>The Loco Combo</h3><span class="tag y">Save $2.50</span></div>
<span class="price">$14.50</span>
</div>
<p class="desc">Any 3 tacos + kimchi fries + yuzu lemonade. The standard Tuesday lunch.</p>
<div class="card-foot"><div class="pep-row" data-heat="3"></div><button class="add-btn" data-item="Loco Combo" data-price="14.50">Add</button></div>
</article>
<article class="card reveal" data-cat="combos" data-heat="4">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-truck"/></svg>
<div style="flex:1"><h3>Party Tray</h3><span class="tag g">Serves 8-10</span></div>
<span class="price">$52.00</span>
</div>
<p class="desc">12 tacos, 2 sides, 4 drinks, extra sauces & napkins. Bring a friend with a truck.</p>
<div class="card-foot"><div class="pep-row" data-heat="4"></div><button class="add-btn" data-item="Party Tray" data-price="52.00">Add</button></div>
</article>
</div>
</div>
</section>
<!-- ===== TACO LAB ===== -->
<section id="lab" class="lab">
<div class="container">
<span class="eyebrow">Taco Lab — build it yourself</span>
<h2 class="section-title">Make it <span class="hot">yours</span></h2>
<p class="section-sub">Pick the protein, dial the heat, stack the toppings. We griddle it while you watch.</p>
<div class="lab-grid" style="margin-top:2rem">
<div class="lab-preview">
<svg id="pvSvg" viewBox="0 0 320 300" role="img" aria-label="Your custom taco preview">
<ellipse cx="160" cy="278" rx="104" ry="13" fill="#000" opacity=".35"/>
<g id="pvSteam" class="steam" opacity=".9">
<path d="M130 66c-9-16 9-23 0-38"/>
<path d="M166 50c-10-18 10-25 0-42"/>
<path d="M198 70c-8-15 8-21 0-34"/>
</g>
<!-- lettuce -->
<g fill="#4FB15C">
<circle cx="58" cy="192" r="25"/><circle cx="92" cy="152" r="26"/><circle cx="132" cy="126" r="25"/>
<circle cx="176" cy="114" r="26"/><circle cx="216" cy="130" r="25"/><circle cx="250" cy="160" r="25"/><circle cx="266" cy="194" r="23"/>
</g>
<!-- kimchi (toggle) -->
<g id="pvKimchi" fill="#E32B22" opacity="0">
<path d="M74 174q22-20 44-4t40-16q-8 26-32 30t-52-10z"/>
<path d="M150 122q20-16 38-2t38-10q-6 22-28 26t-48-14z" opacity=".9"/>
</g>
<!-- protein -->
<g id="pvProtein" fill="#8A3A12">
<circle cx="104" cy="148" r="19"/><circle cx="140" cy="130" r="18"/><circle cx="178" cy="122" r="18"/>
<circle cx="214" cy="138" r="18"/><circle cx="242" cy="162" r="17"/>
</g>
<!-- avocado (toggle) -->
<g id="pvAvocado" opacity="0">
<path d="M96 160q14 8 22-2-4 16-18 12z" fill="#7BC96F"/>
<path d="M212 152q14 6 20-6 2 18-16 16z" fill="#7BC96F"/>
</g>
<!-- onion (toggle) -->
<g id="pvOnion" fill="none" stroke="#B87AD6" stroke-width="5" stroke-linecap="round" opacity="0">
<path d="M120 140q10-10 20 0t20 0"/><path d="M186 128q10-10 20 0"/>
</g>
<!-- egg (toggle) -->
<g id="pvEgg" opacity="0">
<ellipse cx="160" cy="72" rx="26" ry="18" fill="#FFF7E8"/>
<circle cx="160" cy="72" r="9" fill="#FFC93C"/>
</g>
<!-- cheese drizzle -->
<path id="pvCheese" d="M60 180q24 16 48 2t52 4 52-8" stroke="#FFC93C" stroke-width="8" fill="none" stroke-linecap="round"/>
<!-- hot sauce drizzle -->
<path id="pvSauce" d="M86 162q16 12 34 2t38 2" stroke="#E32B22" stroke-width="5" fill="none" stroke-linecap="round"/>
<!-- flames for heat -->
<g id="pvFlames" opacity="0">
<use href="#ico-flame" x="228" y="40" width="30" height="30"/>
<use href="#ico-flame" x="252" y="62" width="22" height="22"/>
</g>
<!-- shell -->
<path d="M30 250 A130 130 0 0 1 290 250 Z" fill="url(#gShell)"/>
<path d="M30 250 A130 130 0 0 1 290 250 Z" fill="none" stroke="#B5762A" stroke-width="3" opacity=".7"/>
<g fill="#FFF3DE" opacity=".85">
<ellipse cx="76" cy="208" rx="6" ry="3" transform="rotate(-40 76 208)"/>
<ellipse cx="116" cy="172" rx="6" ry="3" transform="rotate(-25 116 172)"/>
<ellipse cx="160" cy="158" rx="6" ry="3"/>
<ellipse cx="204" cy="172" rx="6" ry="3" transform="rotate(25 204 172)"/>
<ellipse cx="244" cy="208" rx="6" ry="3" transform="rotate(40 244 208)"/>
</g>
</svg>
<h3 class="pv-name" id="pvName">The Bulgogi Bomb</h3>
<p class="pv-sub" id="pvSub">Marinated ribeye · corn tortilla · kimchi slaw</p>
<div class="heat-meter" id="pvHeatIcons"></div>
<div class="heat-label" id="pvHeatLabel">Level 3 — Hot</div>
<div class="pv-price">
<button id="priceDown" aria-label="Decrease">−</button>
<b id="pvPrice">$4.50</b>
<button id="priceUp" aria-label="Increase">+</button>
</div>
<button class="btn btn-red" id="addToCart" style="width:100%">Add To Bag</button>
<p class="lab-note" style="text-align:center">Tortillas pressed to order · 6 minute average wait</p>
</div>
<div>
<div class="opt-group">
<span class="opt-legend">1 · Protein</span>
<div class="chips" id="optProtein">
<button class="chip-opt sel" data-id="bulgogi" data-price="4.50" data-name="The Bulgogi Bomb" data-color="#8A3A12" data-desc="Marinated ribeye">Bulgogi <small>$4.50</small></button>
<button class="chip-opt" data-id="chicken" data-price="4.25" data-name="Kimchi Tears" data-color="#C4632C" data-desc="Kimchi-marinated chicken thigh">Kimchi Chicken <small>$4.25</small></button>
<button class="chip-opt" data-id="shrimp" data-price="5.50" data-name="Shrimp Dynamite" data-color="#E78B4A" data-desc="Crispy tempura shrimp">Garlic Shrimp <small>$5.50</small></button>
<button class="chip-opt" data-id="tofu" data-price="3.95" data-name="Tofu Tantrum" data-color="#E3D6A0" data-desc="Crispy sesame tofu">Crispy Tofu <small>$3.95</small></button>
<button class="chip-opt" data-id="pork" data-price="4.95" data-name="Belly Flop" data-color="#B4603A" data-desc="Caramelized pork belly">Pork Belly <small>$4.95</small></button>
<button class="chip-opt" data-id="jack" data-price="4.50" data-name="Gochujang Jack" data-color="#7A4A22" data-desc="Smoky jackfruit & mushroom">Gochujang Jack <small>$4.50</small></button>
</div>
</div>
<div class="opt-group">
<span class="opt-legend">2 · Base</span>
<div class="chips" id="optBase">
<button class="chip-opt sel" data-id="corn" data-price="0" data-name="corn tortilla">Corn Tortilla</button>
<button class="chip-opt" data-id="flour" data-price="0" data-name="flour tortilla">Flour Tortilla</button>
<button class="chip-opt" data-id="wrap" data-price="0" data-name="lettuce wrap">Lettuce Wrap</button>
<button class="chip-opt" data-id="brioche" data-price="0.75" data-name="brioche bun">Brioche Bun <small>+$0.75</small></button>
</div>
</div>
<div class="opt-group">
<label for="heat">3 · Heat level — <span id="heatWord">Hot</span></label>
<input type="range" id="heat" min="0" max="5" step="1" value="3">
<div style="display:flex;justify-content:space-between;font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:800">
<span>Mild</span><span>Medium</span><span>Unhinged</span>
</div>
</div>
<div class="opt-group">
<span class="opt-legend">4 · Stack extras</span>
<div class="chips" id="optExtras">
<button class="chip-opt toggle" data-price="1.00" data-name="kimchi">Kimchi <small>+$1</small></button>
<button class="chip-opt toggle" data-price="1.50" data-name="a fried egg">Fried Egg <small>+$1.50</small></button>
<button class="chip-opt toggle" data-price="1.00" data-name="cheese">Cheese <small>+$1</small></button>
<button class="chip-opt toggle" data-price="1.25" data-name="avocado">Avocado <small>+$1.25</small></button>
<button class="chip-opt toggle" data-price="0.50" data-name="nori crunch">Nori Crunch <small>+$0.50</small></button>
<button class="chip-opt toggle" data-price="0.75" data-name="extra sauce">Extra Sauce <small>+$0.75</small></button>
</div>
</div>
<div class="lab-cta">
<button class="btn btn-yellow" id="randomTaco">🎲 Surprise Me</button>
<button class="btn btn-ghost" id="resetTaco">Reset</button>
</div>
<p class="lab-note">Allergy note: sesame, soy, dairy, shellfish. Ask for the gluten-free lettuce wrap and we'll take care of you.</p>
</div>
</div>
</div>
</section>
<!-- ===== TRUCK / LOCATIONS ===== -->
<section id="truck" class="truck">
<div class="container">
<span class="eyebrow">Find the truck</span>
<h2 class="section-title">We're <span class="hot">on the move</span></h2>
<p class="section-sub">One truck, seven stops, zero chill. Here is where we'll be this week — set a reminder and we'll ping you when we roll in.</p>
<div class="truck-grid">
<div class="map-wrap reveal">
<svg class="map" viewBox="0 0 900 420" role="img" aria-label="Stylized map showing the truck route">
<rect width="900" height="420" fill="#171512"/>
<g fill="#201D19">
<rect x="40" y="40" width="180" height="120" rx="8"/>
<rect x="270" y="30" width="150" height="90" rx="8"/>
<rect x="470" y="50" width="200" height="110" rx="8"/>
<rect x="730" y="40" width="130" height="150" rx="8"/>
<rect x="40" y="230" width="200" height="140" rx="8"/>
<rect x="300" y="220" width="180" height="150" rx="8"/>
<rect x="540" y="220" width="150" height="130" rx="8"/>
</g>
<path d="M0 195h900" stroke="#2E2A25" stroke-width="30"/>
<path d="M270 0v420M690 0v420" stroke="#2E2A25" stroke-width="24"/>
<path d="M0 360h900" stroke="#2E2A25" stroke-width="22"/>
<path d="M0 195h900" stroke="#3B3630" stroke-width="3" stroke-dasharray="14 16"/>
<path d="M270 0v420" stroke="#3B3630" stroke-width="3" stroke-dasharray="14 16"/>
<path d="M690 0v420" stroke="#3B3630" stroke-width="3" stroke-dasharray="14 16"/>
<rect x="545" y="230" width="140" height="110" rx="10" fill="#1F3A2A"/>
<text x="580" y="292" fill="#43A95C" font-family="sans-serif" font-size="17" font-weight="700" opacity=".85">RIVERSIDE</text>
<g id="truckMarker">
<animateMotion dur="22s" repeatCount="indefinite" path="M120,355 L255,355 L255,195 L660,195 L660,90 L820,90" />
<g>
<circle r="26" fill="#E32B22" opacity=".28"><animate attributeName="r" values="18;32;18" dur="2.4s" repeatCount="indefinite"/></circle>
<circle r="13" fill="#E32B22" stroke="#FFF3DE" stroke-width="3"/>
<g transform="translate(-30,-30) scale(1)">
<svg width="60" height="60" viewBox="0 0 64 64"><use href="#ico-truck"/></svg>
</g>
</g>
</g>
</svg>
<div class="map-legend"><i></i> Truck is moving · live route</div>
</div>
<div class="loc-list reveal" id="locList"></div>
</div>
<div class="status-card reveal" style="margin-top:1.4rem;grid-template-columns:auto 1fr auto">
<div class="where">
<svg viewBox="0 0 64 64"><use href="#ico-pin"/></svg>
<div><h4>Get the location ping</h4><div class="meta">We'll text you the exact spot when the truck parks.</div></div>
</div>
<form class="news" id="pingForm" style="margin:0">
<input type="tel" id="pingPhone" placeholder="Your phone number" required>
<button class="btn btn-red" type="submit">Ping Me</button>
</form>
<div></div>
</div>
</div>
</section>
<!-- ===== REVIEWS ===== -->
<section id="reviews">
<div class="container">
<span class="eyebrow">Word on the street</span>
<h2 class="section-title">People <span class="hot">talk</span></h2>
<div class="rev-box reveal">
<div class="rev-slide active">
<div class="stars">★★★★★</div>
<p>“I went in for one taco and left with four. The bulgogi is legitimately juicy, the kimchi slaw is tangy as hell, and the sauce has this smoky heat that builds the whole way through. I've been chasing this truck around the city all week.”</p>
<div class="rev-who">
<div class="rev-av" style="background:#FFC93C">MR</div>
<div><b>Marcus R.</b><span>Local · 27 taco orders this month</span></div>
</div>
</div>
<div class="rev-slide">
<div class="stars">★★★★★</div>
<p>“Kimchi Tears broke me. I have no notes. The staff handed me extra napies with a straight face and I think that made it better. Tofu Tantrum is legit too — my vegan friend almost cried.”</p>
<div class="rev-who">
<div class="rev-av" style="background:#E32B22;color:#fff">AK</div>
<div><b>Aisha K.</b><span>Google Review · ★★★★★</span></div>
</div>
</div>
<div class="rev-slide">
<div class="stars">★★★★★</div>
<p>“We booked Kimchi Loco for our company rooftop party and the line lasted 45 minutes. People were still talking about the shrimp dynamite two days later. Worth every dollar.”</p>
<div class="rev-who">
<div class="rev-av" style="background:#43A95C">DT</div>
<div><b>Devon T.</b><span>Catering client · Rooftop, 90 guests</span></div>
</div>
</div>
<div class="rev-slide">
<div class="stars">★★★★☆</div>
<p>“The Kimchi Fries alone are a reason to find the truck. Only knock: I wish they had more of the sesame-lime crema. They also ran out of yuzu lemonade by 8pm, so plan ahead.”</p>
<div class="rev-who">
<div class="rev-av" style="background:#9B4DBE;color:#fff">SL</div>
<div><b>Sam L.</b><span>Yelp · ★★★★☆</span></div>
</div>
</div>
<div class="rev-nav">
<button class="rev-btn" id="revPrev" aria-label="Previous review">‹</button>
<button class="rev-btn" id="revNext" aria-label="Next review">›</button>
<div class="rev-dots" id="revDots"></div>
</div>
</div>
<div class="rating-strip">
<div class="rstat"><b>4.9</b><span>Google Rating</span></div>
<div class="rstat"><b>2,847</b><span>Tacos Served / Month</span></div>
<div class="rstat"><b>18 min</b><span>Avg. Wait at Peak</span></div>
<div class="rstat"><b>#1</b><span>Street Taco in Town</span></div>
</div>
</div>
</section>
<!-- ===== CATERING ===== -->
<section id="cater" class="cater">
<div class="container">
<div class="cater-grid">
<div class="reveal">
<span class="eyebrow">Catering & events</span>
<h2 class="section-title">Bring the <span class="hot">truck</span></h2>
<p class="section-sub">Office parties, weddings, festivals, 2 a.m. dorm rooms — if it needs hot food and a great story, we're there.</p>
<div style="margin-top:1.6rem">
<div class="perk"><div class="dotc">🌮</div><div><b>Full taco bar</b><span>6 proteins, 14 toppings, staff on site for 3 hours.</span></div></div>
<div class="perk"><div class="dotc">🚚</div><div><b>We bring the fire</b><span>Generator, griddle and 400+ tacos. You just bring the appetite.</span></div></div>
<div class="perk"><div class="dotc">🎉</div><div><b>Late night option</b><span>Yes, we will roll up at midnight. We've done it 40+ times.</span></div></div>
<div class="perk"><div class="dotc">🥇</div><div><b>1,200 events served</b><span>Zero sad plates. Zero leftovers of the good stuff.</span></div></div>
</div>
</div>
<form class="order-card reveal" id="caterForm" novalidate>
<div class="field"><label for="cName">Your name</label><input id="cName" type="text" placeholder="Jamie Park" required></div>
<div class="field"><label for="cEmail">Email</label><input id="cEmail" type="email" placeholder="jamie@company.com" required></div>
<div class="field"><label for="cDate">Event date</label><input id="cDate" type="date" required></div>
<div class="field"><label for="cGuests">Guests</label>
<select id="cGuests"><option>25–50</option><option>50–100</option><option>100–250</option><option>250+</option></select>
</div>
<div class="field full"><label for="cType">Event type</label>
<select id="cType"><option>Office party</option><option>Wedding / reception</option><option>Festival / street fair</option><option>Private party</option><option>Brand activation</option><option>Something else</option></select>
</div>
<div class="field full"><button class="btn btn-red" type="submit" style="width:100%">Request Availability</button></div>
<div class="form-msg" id="caterMsg">🎉 Got it! We'll check the calendar and hit your inbox within 24 hours with truck availability + a quote.</div>
</form>
</div>
</div>
</section>
</main>
<!-- ===== FOOTER ===== -->
<footer>
<div class="container">
<div class="foot-grid">
<div class="foot">
<a class="brand" href="#top" style="margin-bottom:.8rem">
<svg class="brand-mark" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<span class="brand-text"><b>KIMCHI</b><b class="loco">LOCO</b></span>
</a>
<p>Mexican street tacos, Korean pantry, zero apologies. Serving the city from a 1986 step van since 2019.</p>
<div class="socials" style="margin-top:1rem">
<a href="#top" aria-label="Instagram">IG</a><a href="#top" aria-label="TikTok">TT</a><a href="#top" aria-label="Twitter">X</a><a href="#top" aria-label="Yelp">Y</a>
</div>
</div>
<div class="foot">
<h4>Menu</h4>
<a href="#menu">Tacos</a><a href="#menu">Sides</a><a href="#menu">Drinks</a><a href="#menu">Combos</a><a href="#lab">Taco Lab</a>
</div>
<div class="foot">
<h4>Visit</h4>
<a href="#truck">Weekly route</a><a href="#cater">Catering</a><a href="#reviews">Reviews</a><a href="#top">Instagram</a>
</div>
<div class="foot">
<h4>Get the secret menu</h4>
<p>One email a week: where we're parked + the limited-drop taco nobody else is ordering.</p>
<form class="news" id="newsForm">
<input type="email" id="newsEmail" placeholder="you@email.com" required>
<button class="btn btn-yellow" type="submit">Join</button>
</form>
<p class="form-msg" id="newsMsg" style="margin-top:.6rem">You're in. Check your inbox for a welcome taco. 🌮</p>
</div>
</div>
<div class="foot-bottom">
<span>© 2025 Kimchi Loco Food Truck · Made with gochujang & stubbornness</span>
<span>🌶️ Spice levels: mild → unhinged</span>
</div>
</div>
</footer>
<button class="cart-btn" id="cartBtn">🛒 Bag <span class="cart-count" id="cartCount">0</span></button>
<div class="cart-panel" id="cartPanel">
<h4>Your Bag</h4>
<div id="cartItems"><p class="cart-empty">Empty. The truck is judging you.</p></div>
<div class="cart-total"><span>Total</span><span id="cartTotal">$0.00</span></div>
<button class="btn btn-red" id="checkout" style="width:100%">Checkout</button>
</div>
<div class="toast" id="toast"></div>
<script>
(function(){
"use strict";
var $=function(s,c){return (c||document).querySelector(s);};
var $$=function(s,c){return Array.prototype.slice.call((c||document).querySelectorAll(s));};
/* ---------- Toast ---------- */
var toastEl=$('#toast'), toastT;
function toast(msg){toastEl.textContent=msg;toastEl.classList.add('show');clearTimeout(toastT);toastT=setTimeout(function(){toastEl.classList.remove('show');},2600);}
/* ---------- Hangul fallback (hide if font missing) ---------- */
function supportsGlyph(ch){
try{
var c=document.createElement('canvas').getContext('2d');
c.font='72px sans-serif';
var w1=c.measureText(ch).width, w2=c.measureText('\uFFFF').width;
return w1>0 && Math.abs(w1-w2)>0.5;
}catch(e){return false;}
}
if(!supportsGlyph('\uAE40')){ $$('.hangul').forEach(function(el){el.style.display='none';}); }
/* ---------- Scroll progress + reveal ---------- */
var prog=$('#progress');
function onScroll(){
var h=document.documentElement.scrollHeight-window.innerHeight;
prog.style.width=(h>0?(window.scrollY/h)*100:0)+'%';
}
window.addEventListener('scroll',onScroll,{passive:true}); onScroll();
if('IntersectionObserver' in window){
var io=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target);}});},{threshold:.12});
$$('.reveal').forEach(function(el){io.observe(el);});
}else{ $$('.reveal').forEach(function(el){el.classList.add('in');}); }
/* ---------- Mobile nav ---------- */
var burger=$('#burger'), mm=$('#mobileMenu');
burger.addEventListener('click',function(){mm.classList.toggle('open');});
$$('#mobileMenu a').forEach(function(a){a.addEventListener('click',function(){mm.classList.remove('open');});});
/* ---------- Location data ---------- */
var LOC=[
{d:'MON',place:'Eastside Lot',addr:'5th & Mission — Street Food Row',open:'11:30',close:'21:00',tag:'Lunch + dinner'},
{d:'TUE',place:'Night Market',addr:'Union Square Alley — Rooftop Deck',open:'16:00',close:'23:00',tag:'Late night'},
{d:'WED',place:'Campus Quad',addr:'State U — Gate B Lawn',open:'11:00',close:'19:00',tag:'Student deal 10% off'},
{d:'THU',place:'The Yard',addr:'Dock St. Warehouse 3',open:'11:30',close:'21:00',tag:'Cider & tacos'},
{d:'FRI',place:'Ballpark Lot',addr:'Right Field Gate 2',open:'15:00',close:'23:30',tag:'Game day crush'},
{d:'SAT',place:'Art District',addr:'6th & Vine — Mural Plaza',open:'10:00',close:'22:00',tag:'Brunch tacos'},
{d:'SUN',place:'Riverside Park',addr:'South Lawn — by the bandshell',open:'10:00',close:'20:00',tag:'Family day'}
];
var todayIdx=(new Date().getDay()+6)%7; // Mon=0
var locList=$('#locList');
LOC.forEach(function(L,i){
var el=document.createElement('div');
el.className='loc'+(i===todayIdx?' today':'');
el.innerHTML='<div class="day">'+L.d+'</div>'+
'<div><div class="place">'+L.place+(i===todayIdx?'<span class="badge-today">TODAY</span>':'')+'</div>'+
'<div class="addr">'+L.addr+' · '+L.tag+'</div></div>'+
'<div class="hrs">'+fmt(L.open)+'<br>'+fmt(L.close)+'</div>';
locList.appendChild(el);
});
function fmt(t){var p=t.split(':'),h=+p[0],m=p[1],ap=h>=12?'PM':'AM';h=h%12;if(h===0)h=12;return h+':'+m+' '+ap;}
function toMin(t){var p=t.split(':'),return (+p[0])*60+(+p[1]);}
function toHM(mins){mins=((mins%1440)+1440)%1440;var h=Math.floor(mins/60),m=mins%60,ap=h>=12?'PM':'AM';h=h%12;if(h===0)h=12;return h+':'+String(m).padStart(2,'0')+' '+ap;}
/* ---------- Status + countdown ---------- */
var L=LOC[todayIdx];
$('#todayPlace').textContent=L.place;
$('#todayAddr').textContent=L.addr;
$('#todayHours').textContent=fmt(L.open)+' — '+fmt(L.close);
function tick(){
var now=new Date(), cur=now.getHours()*60+now.getMinutes();
var o=toMin(L.open), c=toMin(L.close);
var pill=$('#statusPill'), chip=$('#openChip'), cd=$('#countdown'), lb=$('#countdownLabel');
if(cur>=o&&cur<c){
pill.classList.add('open'); $('#statusText').textContent='Open now';
chip.textContent='Open now'; chip.style.background='rgba(67,169,92,.16)'; chip.style.borderColor='rgba(67,169,92,.5)'; chip.style.color='#9BFFC2';
var m=c-cur; cd.textContent=toHM(m); lb.textContent='until we close';
}else{
pill.classList.remove('open');
var nextO=cur<o?o:(c+0); // tomorrow open
$('#statusText').textContent='Closed · opens '+fmt(L.open);
chip.textContent='Closed right now'; chip.style.background='rgba(227,43,34,.16)'; chip.style.borderColor='rgba(227,43,34,.4)'; chip.style.color='#ff9b93';
var diff=nextO-cur; if(diff<=0) diff+=1440;
cd.textContent=toHM(diff); lb.textContent='until we open';
}
}
tick(); setInterval(tick,30000);
/* ---------- Pepper rows ---------- */
function pepperSVG(){return '<svg class="pep" viewBox="0 0 24 24"><use href="#ico-pep"/></svg>';}
$$('.pep-row').forEach(function(row){
var h=+row.getAttribute('data-heat'),html='';
for(var i=0;i<5;i++){html+=pepperSVG().replace('class="pep"','class="pep '+(i<h?'on':'off')+'"');}
row.innerHTML=html;
});
/* ---------- Menu tabs ---------- */
$('#menuTabs').addEventListener('click',function(e){
var b=e.target.closest('.tab'); if(!b)return;
$$('#menuTabs .tab').forEach(function(t){t.classList.remove('active');});
b.classList.add('active');
var f=b.getAttribute('data-filter');
$$('#menuGrid .card').forEach(function(c){
var show=(f==='all'||c.getAttribute('data-cat')===f);
c.classList.toggle('hidden',!show);
if(show){c.style.animation='none';void c.offsetWidth;c.style.animation='fadeIn .35s ease';}
});
});
/* ---------- Cart ---------- */
var cart=[], cartCount=$('#cartCount'), cartPanel=$('#cartPanel');
function renderCart(){
cartCount.textContent=cart.reduce(function(a,i){return a+i.q;},0);
var box=$('#cartItems');
if(!cart.length){box.innerHTML='<p class="cart-empty">Empty. The truck is judging you.</p>';$('#cartTotal').textContent='$0.00';return;}
box.innerHTML='';
cart.forEach(function(it,i){
var d=document.createElement('div'); d.className='cart-item';
d.innerHTML='<span>'+it.q+'× '+it.name+'</span><span>$'+(it.price*it.q).toFixed(2)+'</span>';
box.appendChild(d);
});
$('#cartTotal').textContent='$'+cart.reduce(function(a,i){return a+i.price*i.q;},0).toFixed(2);
}
function addToCart(name,price){
var ex=cart.find(function(i){return i.name===name;});
if(ex){ex.q++;}else{cart.push({name:name,price:price,q:1});}
renderCart(); toast('Added '+name+' to your bag 🌮');
}
document.addEventListener('click',function(e){
var b=e.target.closest('.add-btn'); if(!b)return;
addToCart(b.getAttribute('data-item'),parseFloat(b.getAttribute('data-price')));
b.classList.add('on'); b.textContent='Added ✓';
setTimeout(function(){b.classList.remove('on');b.textContent='Add';},1200);
});
$('#cartBtn').addEventListener('click',function(){cartPanel.classList.toggle('open');});
$('#checkout').addEventListener('click',function(){
if(!cart.length){toast('Your bag is empty — add a taco first!');return;}
toast('Order placed! Pick up at the window in ~6 min 🔥');
cart=[];renderCart();cartPanel.classList.remove('open');
});
/* ---------- Taco Lab ---------- */
var PROTEINS={bulgogi:{color:'#8A3A12',desc:'Marinated ribeye'},chicken:{color:'#C4632C',desc:'Kimchi-marinated chicken thigh'},
shrimp:{color:'#E78B4A',desc:'Crispy tempura shrimp'},tofu:{color:'#E0D09A',desc:'Crispy sesame tofu'},
pork:{color:'#B4603A',desc:'Caramelized pork belly'},jack:{color:'#7A4A22',desc:'Smoky jackfruit & mushroom'}};
var state={protein:'bulgogi',base:'corn',heat:3,qty:1,extras:{}};
var HEAT_WORDS=['Mild','Mild-Hot','Medium','Hot','Very Hot','UNHINGED'];
var HEAT_COLORS=['#43A95C','#8FBF3F','#FFC93C','#FF7A2F','#E32B22','#A8140F'];
var pvProtein=$('#pvProtein'), pvKimchi=$('#pvKimchi'), pvOnion=$('#pvOnion'), pvEgg=$('#pvEgg'),
pvAvocado=$('#pvAvocado'), pvCheese=$('#pvCheese'), pvSauce=$('#pvSauce'), pvFlames=$('#pvFlames'), pvSteam=$('#pvSteam');
function chipPrice(group){var p=0;$$('#'+group+' .chip-opt.sel').forEach(function(c){p+=parseFloat(c.getAttribute('data-price'))||0;});return p;}
function selectedChip(group){return $('#'+group+' .chip-opt.sel');}
function extrasPrice(){var p=0;$$('#optExtras .chip-opt.sel').forEach(function(c){p+=parseFloat(c.getAttribute('data-price'))||0;});return p;}
function extrasNames(){return $$('#optExtras .chip-opt.sel').map(function(c){return c.getAttribute('data-name');});}
function render(){
var chip=selectedChip('optProtein');
var pid=chip.getAttribute('data-id');
state.protein=pid;
var baseChip=selectedChip('optBase');
state.base=baseChip.getAttribute('data-id');
state.heat=parseInt($('#heat').value,10);
var basePrice=parseFloat(chip.getAttribute('data-price'));
var total=(basePrice+chipPrice('optBase')+extrasPrice())*state.qty;
pvProtein.setAttribute('fill',PROTEINS[pid].color);
var names=extrasNames();
pvKimchi.setAttribute('opacity',names.indexOf('kimchi')>-1?'1':'0');
pvEgg.setAttribute('opacity',names.indexOf('a fried egg')>-1?'1':'0');
pvOnion.setAttribute('opacity',names.indexOf('nori crunch')>-1?'.9':'0');
pvAvocado.setAttribute('opacity',names.indexOf('avocado')>-1?'1':'0');
pvCheese.setAttribute('opacity',names.indexOf('cheese')>-1?'1':'0');
pvSauce.setAttribute('opacity',(names.indexOf('extra sauce')>-1||state.heat>=4)?'1':'.85');
pvSauce.setAttribute('stroke',state.heat>=4?HEAT_COLORS[5]:'#E32B22');
pvFlames.setAttribute('opacity',state.heat>=4?(state.heat===5?'1':'.75'):'0');
pvSteam.setAttribute('opacity',state.heat>=4?'1':'.35');
$('#pvName').textContent=chip.getAttribute('data-name');
var baseName=baseChip.getAttribute('data-name');
var sub=PROTEINS[pid].desc+' · '+baseName;
if(names.length) sub+=' + '+names.join(', ');
if(state.qty>1) sub='×'+state.qty+' — '+sub;
$('#pvSub').textContent=sub;
$('#pvPrice').textContent='$'+total.toFixed(2);
var icons='';
for(var i=0;i<5;i++){icons+=pepperSVG().replace('class="pep"','class="pep '+(i<state.heat?'on':'off')+'"');}
$('#pvHeatIcons').innerHTML=icons;
$('#pvHeatLabel').textContent='Level '+state.heat+' — '+HEAT_WORDS[state.heat];
$('#pvHeatLabel').style.color=HEAT_COLORS[state.heat];
$('#heatWord').textContent=HEAT_WORDS[state.heat];
$('#heatWord').style.color=HEAT_COLORS[state.heat];
}
$('#optProtein').addEventListener('click',function(e){var b=e.target.closest('.chip-opt');if(!b)return;
$$('#optProtein .chip-opt').forEach(function(c){c.classList.remove('sel');});b.classList.add('sel');render();});
$('#optBase').addEventListener('click',function(e){var b=e.target.closest('.chip-opt');if(!b)return;
$$('#optBase .chip-opt').forEach(function(c){c.classList.remove('sel');});b.classList.add('sel');render();});
$('#optExtras').addEventListener('click',function(e){var b=e.target.closest('.chip-opt');if(!b)return;
b.classList.toggle('sel');render();});
$('#heat').addEventListener('input',render);
$('#priceUp').addEventListener('click',function(){state.qty=Math.min(12,state.qty+1);render();});
$('#priceDown').addEventListener('click',function(){state.qty=Math.max(1,state.qty-1);render();});
$('#addToCart').addEventListener('click',function(){
var chip=selectedChip('optProtein');
var label=chip.getAttribute('data-name')+(state.qty>1?' ×'+state.qty:'');
var price=(parseFloat(chip.getAttribute('data-price'))+chipPrice('optBase')+extrasPrice())*state.qty;
addToCart(label,price);
});
$('#resetTaco').addEventListener('click',function(){
$$('#optExtras .chip-opt').forEach(function(c){c.classList.remove('sel');});
$$('#optProtein .chip-opt')[0].classList.add('sel');
$$('#optProtein .chip-opt').slice(1).forEach(function(c){c.classList.remove('sel');});
$$('#optBase .chip-opt')[0].classList.add('sel');
$$('#optBase .chip-opt').slice(1).forEach(function(c){c.classList.remove('sel');});
$('#heat').value=3;state.qty=1;render();toast('Taco reset — clean slate.');
});
$('#randomTaco').addEventListener('click',function(){
var ps=$$('#optProtein .chip-opt'), bs=$$('#optBase .chip-opt'), es=$$('#optExtras .chip-opt');
ps.forEach(function(c){c.classList.remove('sel');}); ps[Math.floor(Math.random()*ps.length)].classList.add('sel');
bs.forEach(function(c){c.classList.remove('sel');}); bs[Math.floor(Math.random()*bs.length)].classList.add('sel');
es.forEach(function(c){c.classList.remove('sel');});
var n=1+Math.floor(Math.random()*3);
for(var i=0;i<n;i++){es[Math.floor(Math.random()*es.length)].classList.add('sel');}
$('#heat').value=Math.floor(Math.random()*6); state.qty=1; render();
toast('The truck gods have spoken. 🔮');
});
render();
/* ---------- Reviews carousel ---------- */
var slides=$$('.rev-slide'), dots=$('#revDots'), idx=0;
slides.forEach(function(s,i){
var d=document.createElement('button'); d.className='rev-dot'+(i===0?' active':''); d.setAttribute('aria-label','Review '+(i+1));
d.addEventListener('click',function(){go(i);}); dots.appendChild(d);
});
var dotEls=$$('#revDots .rev-dot');
function go(i){idx=(i+slides.length)%slides.length;
slides.forEach(function(s,k){s.classList.toggle('active',k===idx);});
dotEls.forEach(function(d,k){d.classList.toggle('active',k===idx);});}
$('#revNext').addEventListener('click',function(){go(idx+1);});
$('#revPrev').addEventListener('click',function(){go(idx-1);});
setInterval(function(){go(idx+1);},5200);
/* ---------- Forms ---------- */
$('#caterForm').addEventListener('submit',function(e){e.preventDefault();
var m=$('#caterMsg');m.classList.add('show');this.reset();toast('Request sent! We reply within 24 hours 🎉');});
$('#newsForm').addEventListener('submit',function(e){e.preventDefault();
$('#newsMsg').classList.add('show');this.reset();toast('Welcome to the fam 🌮');});
$('#pingForm').addEventListener('submit',function(e){e.preventDefault();
toast('You\'re on the list — we\'ll text you the spot!');this.reset();});
/* ---------- Smooth anchors with offset ---------- */
$$('a[href^="#"]').forEach(function(a){
a.addEventListener('click',function(e){
var id=a.getAttribute('href'); if(id.length<2)return;
var t=document.querySelector(id); if(!t)return;
e.preventDefault();
var y=t.getBoundingClientRect().top+window.scrollY-74;
window.scrollTo({top:y,behavior:'smooth'});
});
});
})();
</script>
</body>
</html>Reasoning trace (9,893 tokens)
The user wants a website for a Korean taco food truck called "Kimchi Loco". It should be appetizing, bold, vibrant. Let me make a single HTML file with inline CSS/JS.
Key elements:
- Hero with big bold type, Korean-inspired colors (gochujang red, kimchi orange, sesame cream, nori green, purple cabbage)
- Live "truck locations & hours" schedule with current status (OPEN NOW / CLOSED / opens in X)
- Menu with tacos, prices, hover animations
- "Build your taco" interactive (spicy level slider, protein choice) — fun and engaging
- Reviews/testimonials carousel
- Instagram feed mock
- Order form / "Get notified" signup
- Food truck festival look: marquee ticker, neon signs
- Animated elements: floating ingredients, steam
- Korean text accents (김치 로코)
- Countdown to next opening
- Scroll animations
Let me design a distinctive aesthetic: street-food night market meets modern. Dark charcoal background with vivid accents (gochujang red #E5242B, kimchi orange #F26419, gochugaru, sesame cream #F6E7C8, nori green #1F6F4A, yuzu yellow). Big condensed type via Google Fonts? CDN fonts allowed? The task says "No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task." The task doesn't explicitly allow CDN URLs. Safer: use system fonts stack with strong fallbacks. But we could use Google Fonts... risky. The rule says except CDN URLs explicitly allowed by the task — no CDN allowed here, so use system fonts only.
Use font stacks: 'Impact', 'Haettenschweiler', 'Arial Narrow Bold', sans-serif for display; system-ui for body. Impact is widely available on Windows, macOS has Impact too. Use fallback.
Images: no external images. Use CSS-drawn illustrations — SVG inline for taco illustrations, kimchi, truck. That's a big part of the visual appeal. Let me create inline SVG taco illustrations with gradients.
Let me plan the sections:
1. Sticky nav with logo (SVG taco icon) + links + "ORDER NOW" button + live status pill.
2. Hero: full viewport, big headline "KIMCHI LOCO", Korean subtitle 김치로코, tagline "Korean street tacos. Actually hot." CTAs. Animated taco SVG floating. Steam animation. Marquee ticker at bottom of hero.
3. Live strip: "🔥 OPEN NOW — East Side Lot, 5th & Mission • closes 10:00 PM" with pulsing dot, plus countdown.
4. Menu: tabs (Tacos / Sides / Drinks / Combos), cards with SVG illustrations and prices, spice level indicator. Maybe a signature item featured large.
5. Build-your-own "Taco Lab" interactive: choose protein (bulgogi, kimchi chicken, tofu, shrimp), choose base (corn/butter/brioche?), spice slider (mild →灭), toppings toggles, live-updating name & price and a rendered taco preview. That's engaging and self-demonstrating.
6. "Why people line up" / What's in the sauce - feature section with animated ingredients.
7. Reviews carousel with auto-rotate + ratings.
8. Find the truck: rotating location schedule with today highlighted, map-ish SVG route illustration.
9. Catering / events form (no external submission, just front-end with a success message).
10. Footer with social, newsletter.
11. Floating order button.
Color palette:
- Background: #12100E (near-black brown)
- Cream: #FFF3E0
- Red: #E4231F / gochujang #D62828
- Orange: #FF6B2C
- Yellow: #FFC93C
- Green: #2FA84F (nori)
- Purple: #7B2D8E (cabbage)
Let's write it. Considerable CSS. Need to be careful with no horizontal scrollbar: use overflow-x hidden on body and marquee with transform.
For the marquee, use a container with overflow hidden and inner track with animation translateX(-50%) with duplicated content.
Let me write the SVG taco illustration. A taco: semicircle shell with texture dots, lettuce frills, meat filling, toppings.
I'll build a reusable SVG with classes for coloring.
Let me write a decent taco SVG:
```svg
<svg viewBox="0 0 200 160">
<!-- shell -->
<path d="M20 140 A 80 80 0 0 1 180 140 Z" fill="url(#shellGrad)"/>
...
</svg>
```
For the hero, a big taco with steam and sesame seeds.
Also add "sticky" element on scroll maybe.
Let's implement the Taco Lab:
- Proteins: Beef Bulgogi $4.50, Kimchi Chicken $4.25, Crispy Tofu $3.75, Garlic Shrimp $5.25, Pork Belly $4.75
- Base: Corn Tortilla, Flour Tortilla, Brioche Bun (+$0.75), Lettuce Wrap (0)
- Heat slider 0-5: " mild, mild-hot, hot, VERY hot, unhinged, legend"
- Extras toggles: Kimchi (+1), Fried Egg (+1.5), Cheese (+1), Avocado (+1.25), Crunch (+0.5), Extra Sauce (+0.75), Pickled Onion (0)
- Live taco name: e.g. "The Bulgogi Bomb" - generated from protein+toppings
- Price updates with animated counter
- Preview taco SVG updates colors with heat
- "Add to order" button → toast, and a mini cart in the corner showing items. A small order summary panel makes it feel real.
Cart with total and a "checkout" that shows a confirmation message.
Reviews: auto-rotating carousel with dots and prev/next.
Location schedule: list of days with times; today highlighted (JS). Plus "Get text alerts" input for next location (form with success message).
Also a "Nutrition? no". Add "Halal-friendly / Veggie options" badges maybe.
Also include a fun animated "spice meter" that shakes.
Let me think about first-paint: The hero must be immediately striking. Include:
- Top marquee ticker (red band, moving text with stars)
- Nav
- Hero headline huge "KIMCHI LOCO" with a yellow/cream outline and red offset shadow
- Korean "김치 로코"
- Subcopy
- Buttons
- Taco SVG art
- Live status pill
- Scroll cue
Let me carefully write the code now.
CSS approach: variables, clamp() for typography.
I'll write it all out. Let's be meticulous about responsive: at 375px, nav links collapse (hide some), grid becomes 1 column, hero font smaller, taco art below.
Let me write the HTML.
Sections IDs: #menu, #taco-lab, #locations, #reviews, #order.
Nav: links Menu, Taco Lab, Locations, Reviews, and a CTA "Order Now" that scrolls to taco lab.
Add a small "truck status" dot in nav.
Let me write the taco SVG component for the hero (big, detailed):
```html
<svg class="hero-taco" viewBox="0 0 420 340" ...>
<defs>
<linearGradient id="shell" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#F7D68A"/><stop offset="1" stop-color="#D89A3E"/>
</linearGradient>
...
</defs>
<!-- steam paths -->
<g class="steam">
<path d="M140 90 c -12 -22 12 -30 0 -52" ... />
</g>
<!-- lettuce -->
<!-- meat -->
<!-- shell with sesame -->
</svg>
```
Steam animation: stroke-dasharray with dashoffset animation, opacity.
I'll also do a "chili pepper" floating emojis? Avoid emoji overload but a few are fine and add color. Use simple emoji sparingly: 🔥🌶️ in the ticker. That's fine.
Let me now write out the full file. I'll aim for high quality and polish.
Key interactive bits in JS:
1. Tab switching for menu categories.
2. Taco Lab builder with live preview & price.
3. Cart add + toast.
4. Reviews carousel auto-advance.
5. Countdown to closing/opening based on a schedule (use a fixed fictional schedule but based on real current time; compute next open/close). Since it's a food truck demo, I'll compute using real local time and the location schedule, showing "OPEN NOW" or "CLOSED — OPENS AT 5:00 PM".
6. Scroll reveal animations (IntersectionObserver).
7. Mobile nav toggle.
8. Newsletter form → success message.
Let me define schedule data:
```js
const LOCATIONS = [
{day:'Mon', dateOffset:0, place:'Eastside Lot', addr:'5th & Mission', open:'11:30', close:'21:00'},
{day:'Tue', ...}
]
```
Simplify: an array of 7 entries with names/addresses/times, plus a "where's the truck" section.
Actually a nicer concept: the truck moves daily; the Locations section shows a weekly rotation list with today highlighted. And the status banner in nav says "OPEN NOW — <today's place>" if within hours.
For the countdown: compute next open/close. Use today's entry hours; if now within, show time left until close; else show time until next open (if today later, else tomorrow).
Implementation:
```js
function parseHM(s){const [h,m]=s.split(':').map(Number);return h*60+m;}
const now=new Date(); const cur=now.getHours()*60+now.getMinutes();
```
Location list: 7 days, each with place, address, hours.
Let's give it a rotating feel. Highlight today's row.
Also add "See the truck near you" — a fake map SVG with a moving truck marker? Could be cute: a stylized street map with the truck driving along a path with animation. That'd be a nice visual. Let me include a simplified map illustration: roads as lines, blocks as rects, and a little truck icon that animates along the path with `offset-path`? offset-path support is good in Chrome. Use CSS `offset-path: path("...")` on the truck group, animate offset-distance 0→100%. That's a nice touch and works in modern Chrome. I'll include fallback (just position) though.
Maybe simpler: a truck emoji-ish SVG in a badge that moves horizontally back and forth on a road. Let's do the map with offset-path.
Let's write code.
Detailed CSS plan:
```
:root{
--ink:#12100E; --ink2:#1C1916; --cream:#FFF4E2; --paper:#FFE9C9;
--red:#E32B22; --red2:#B71C1C; --orange:#FF7A2F; --yellow:#FFC93C;
--green:#3FA65A; --purple:#8E44AD;
--font-display: 'Impact','Haettenschweiler','Arial Narrow Bold','Anton',sans-serif;
}
```
Google font not allowed, so Impact. On Linux (sandbox likely Linux Chrome), Impact may not exist. Fallbacks: 'Anton' not available either. Hmm — the screenshot in the sandbox might be on Linux where Impact isn't installed. Then display font falls back to sans-serif bold, which is okay but less punchy. Alternative: use a variable-weight system font stack and heavy letter-spacing, uppercase — still looks strong. Or embed a font as base64? Too heavy.
Better: use `font-family: 'Archivo Black', 'Impact', 'Haettenschweiler', 'Arial Narrow Bold', sans-serif;` and rely on generic sans fallback. With -webkit-text-stroke maybe add punch. I'll use font-weight 900 and tight letter-spacing with uppercase; plus italic skew for some elements. That reads bold regardless.
Actually, I could attempt loading Google Fonts with a link — the task says "No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task." Since not allowed, I won't. But if the font fails to load, page still works (no error). Still, instructions say no network requests. I'll skip fonts entirely and rely on system fonts.
To make display type look distinctive without a custom font, I'll use: uppercase, font-weight 900, letter-spacing -0.03em, and a thick text-shadow offset in red for the hero, plus skewed badges.
Hmm, in the sandbox (likely Linux), the available system fonts are DejaVu Sans, Liberation Sans, maybe Noto. font-weight 900 would map to bold DejaVu Sans Bold. That's acceptable and still looks like a poster with the right color treatment.
Let's also add subtle grain/noise via CSS repeating-radial-gradient for texture.
Now, write everything.
Menu items with prices and tags:
TACOS (each served with kimchi slaw + sesame lime):
1. The Original Bulgogi — $4.50 — "Sweet-soy marinated ribeye, gochujang glaze, kimchi slaw"
2. Kimchi Chicken ( cries ) — $4.25 — "Buttermilk-brined thigh, kimchi mayo, pickled onion"
3. Seoul Crunch Shrimp — $5.50 — "Tempura shrimp, ssamjang drizzle, yuzu mayo"
4. Tofu Kimchi (V) — $3.95 — "Crispy tofu, spicy kimchi, sesame aioli"
5. Pork Belly Boss (W) — $4.95 — "Caramelized pork belly, kimchi, egg, sriracha"
6. Gochujang Jack (V) — $4.50 — "Mushroom + jackfruit, smoky gochujang, crispy shallot"
SIDES:
- Kimchi Fries $5.50
- Mandu (dumplings) x6 $6.00
- Cheese Corn Dog $4.50
- Seaweed Crinkle Chips $3.50
- Kimchi Grilled Cheese $7.00
DRINKS:
- Yuzu Lemonade $3.50
- Thai Iced Tea $4.00
- Barley (Bingsu) $5.50
- Soju Lemon Spritz $6.00
COMBOS:
- Loco Combo: 3 tacos + fries + drink $14.50
- Family Party Tray: 12 tacos + 2 sides + 4 drinks $52
Cards with SVG mini illustration? Making 18 SVGs is heavy. Instead: cards with a colored top band, a small inline SVG "taco" glyph or emoji-free icon, price tag, spice meter. I'll create a generic mini taco SVG used in cards (one reusable symbol via <symbol> + <use>). Use an SVG sprite with symbols: #ico-taco, #ico-fries, #ico-cup, #ico-chili. Good idea.
Let me define an inline SVG sprite at top of body (hidden) with symbols.
Sprite symbols:
- taco: shell semicircle + fillings
- fries: red carton + sticks
- cup: drink cup with straw
- bowl: bingsu/ bowl
- pepper: chili
- star, etc.
Cards use `<svg class="card-ico"><use href="#ico-taco"/></svg>` with currentColor / gradient fills defined inside symbol using fills that work. Symbols with gradient references: define gradients in the sprite defs; referencing from a shadow-cloned <use> can be tricky (gradients defined in the same document work fine with use). Yes, defs are document-level, so gradient refs inside symbol resolve fine.
Ok.
Menu tab filter: buttons "Tacos / Sides / Drinks / Combos" filter cards by data-cat with a fade.
Taco Lab UI layout: left = preview (big taco SVG that changes color based on protein & heat, plus lettuce etc.), right = controls. Below = cart panel with items.
Actually simpler & better: left column = the custom taco preview + name + price + Add to bag; right column = option groups.
Preview taco: a big SVG where I can toggle element visibility by class: shells (2 base options), protein color (set fill), heat = flame icons count, toppings show/hide (egg, avocado, cheese, kimchi, onion, crunch).
I'll craft one preview SVG with groups:
- #pv-base (corn shell), #pv-brioche (bun) toggled
- #pv-lettuce (always)
- #pv-protein (path with fill set by JS)
- #pv-kimchi (red strip), #pv-onion (purple squiggles), #pv-cheese (yellow drips), #pv-egg (white/yolk), #pv-avocado (green slices), #pv-crunch (small dots)
- #pv-sauce (drizzle)
- heat: #pv-flames opacity by heat.
Good. Let's design the taco shape viewBox 0 0 320 260.
Shell: path M30 230 Q160 40 290 230 Z? That's a shell standing up like a "U" open at top... A taco viewed from front: semicircle with flat side up? Classic taco icon: a half-circle with the flat edge at top and fillings poking above. Let's do: shell = path "M20 210 A 140 140 0 0 1 300 210 Z" (arc top, flat bottom) — hmm that's a dome. The classic taco emoji: a semicircle with flat bottom on a plate, fillings visible at top. Actually taco emoji is a half-moon (flat side up-left).
Let's do: shell as a "U" open at top: path "M40 220 Q40 60 160 60 Q280 60 280 220 Z" gives a dome with flat bottom. Fillings sit on the top opening. Hmm dome with the top arc.
Simplest attractive: side-view taco standing on its bottom edge? I'll do the "dome" shell with fillings layered on top of the arc, which reads well:
- Shell dome: M25 225 C25 120 85 45 160 45 C235 45 295 120 295 225 Z → dome, flat bottom at 225.
- Fillings: lettuce waves sitting along the top arc from x=60..260 at y ~70-110, meat mound behind.
Hmm, but a taco's filling is inside the shell, visible above the shell's top edge. With a dome, the top edge is the arc. So layers should appear just above the arc line. Let me instead do the "folded tortilla" style: two overlapping arcs forming a V shape (like a hard shell taco) with fillings in the V.
Design:
- Shell back: path M20 60 L160 200 L300 60 A140 140 0 0 0 20 60 Z?
I'll do the classic: shell = semicircle flat side UP, i.e. path "M30 200 A 130 130 0 0 1 290 200 Z" — that arc from (30,200) to (290,200) with sweep... With large-arc-flag 1 and sweep 1, arc goes below? Let's think: A rx ry rot large sweep x y. From (30,200) to (290,200), rx=130: two possible centers at (160, 200±sqrt(130²-130²)) = (160,200) only when chord = diameter. Chord length 260 = 2*130, so it's a semicircle, center (160,200). sweep=1 means clockwise in SVG coords (y down) → arc goes from (30,200) up? Clockwise from left point (angle 180°) decreasing angle... In SVG, sweep-flag=1 means the arc is drawn in the "positive angle" direction, which with y-down appears clockwise. Starting at (30,200) (left), going clockwise (in screen) means going up over the top to (290,200). Hmm: clockwise on screen starting at 9 o'clock position goes to 12 o'clock then 3 o'clock. Yes → arc over the top. large-arc-flag 1 is irrelevant for a semicircle (both halves equal). So path "M30 200 A130 130 0 0 1 290 200 Z" gives a dome (flat bottom at y=200, curved top reaching y=70).
That's a dome = a hard-shell taco standing on its flat bottom? Real hard-shell tacos: the shell is a U shape (open top), viewed from the side, it's like a "V"/half circle with filling inside visible at the top. The dome shape with filling above the top curve reads as a "taco" from emoji style (🌮 shows a U-ish shape with fillings above). The emoji 🌮 is basically a half-circle (dome up? no, it's a U shape with the filling at the top opening... ). 🌮 taco emoji: it's a yellow half circle with the curved part up (dome) and fillings on top of the curve. Yes! The taco emoji is a dome with lettuce/cheese/meat visible along the top edge.
So: dome shell + filling layers above the dome arc. The top of dome at y=70. Fillings sit between y=40 and y=100, overlapping the arc.
Great. Let me build:
- Fillings (drawn first, behind the shell? no, in front at top): Actually in the emoji, the filling is behind/above the shell's front face, and the shell's front panel covers the bottom. Order: draw fillings, then draw shell dome on top (covering lower parts) → filling appears poking out above the shell's edge. But the dome covers y>=70... the filling drawn between 40-100 would show above y=70 only. That works: draw filling mound first, then shell over it.
Plan preview SVG layers:
1. lettuce waves (green, along arc y ~ 60-100)
2. protein chunks (brown/red bits)
3. cheese drizzle (yellow)
4. kimchi (red strips)
5. onion (purple)
6. avocado (green crescents)
7. egg (white blob + yolk)
8. shell dome on top (with sesame seeds and texture) → covers below
9. sauce drizzle over the shell? Maybe a zigzag on top edge.
But then the shell covers most toppings, only showing above the arc. To show more toppings, make the shell slightly lower and toppings taller. Also for visibility of protein, draw the protein band ON the arc (i.e., protein drawn after the shell, hugging the arc). Let's do: shell dome first (fills lower), then toppings layered along the top arc band drawn after the shell, so they appear in front of the shell near the top. That shows more color. Like emoji: the front shell is yellow and lettuce is on top of it. Fine: draw shell, then a row of toppings along the top arc (clipped to above y=... no clip needed).
So: shell dome from y=70 to 200, and toppings drawn as a band following the arc from (45,150) up over (160,60) to (275,150). Lettuce = wavy green band; protein = chunky colored band; cheese = yellow zigzag.
I'll use a path band: for the band, define an outer path and inner path. Simpler: use several small shapes positioned along the arc (rotated rects/ellipses). Since we need a "wavy lettuce" I can use a path with quadratic waves: "M40 160 C 60 130, 90 120, 110 95 S 160 60, 190 70 S 250 110, 280 155 L 280 175 C 250 135, 225 125, 205 100 S 150 90, 125 115 S 70 140, 45 175 Z" — hand-crafting is error-prone.
Alternative simpler approach: draw the filling as a set of overlapping circles/ellipses (meat chunks) along an arc, plus lettuce as circles of green, plus cheese as a zigzag line, plus onion as small purple arcs. Overlapping circles along an arc read nicely as a chunky filling. Let's do that with a JS-generated set of circles positioned along the arc via cos/sin.
Actually I can compute positions in JS and inject. But static SVG is safer for first paint. I can hand-place ~10 circles.
Arc: center (160, 200), radius 130. Points at angles from 200° to 340° (measuring standard math with y inverted). Let me just place by hand:
Angle θ measured from center (160,200) with y-up. Point = (160 + 130*cosθ, 200 - 130*sinθ).
- θ=170°: (160-128, 200-22.6) = (32, 177)
- θ=150°: (160-112.6, 200-65) = (47, 135)
- θ=130°: (160-83.6, 200-99.6) = (76, 100)
- θ=110°: (160-44.5, 200-122) = (115, 78)
- θ=90°: (160, 70)
- θ=70°: (204.5, 78)
- θ=50°: (243.6, 100)
- θ=30°: (272.6, 135)
- θ=10°: (288, 177)
So circles at radius 130 with r≈22, slightly outside radius 130 (i.e., radius 125) so they poke out. Use radius 118 with r=24 → they span radius 94..142, poking 12px beyond the shell.
Lettuce: green circles at radius 120, r=26, a subset (every other).
Protein: brown/red circles at radius 126, r=20.
Cheese: yellow zigzag path across top.
Sauce: red drizzle zigzag.
Onion: purple thin arcs.
Avocado: green crescents (use ellipses rotated).
Egg: white circle + yellow yolk circle at (160, 60).
Kimchi: red angular strips.
Fine, I'll hand-write these.
Shell: "M30 200 A130 130 0 0 1 290 200 Z" fill gradient, plus a darker bottom edge, plus sesame seeds (small ellipses rotated along the arc at radius 105), plus subtle texture lines.
And a subtle shadow ellipse under the taco.
Good.
Now for the hero: reuse the same taco but bigger and add steam, plus floating jalapeño/chili elements, maybe an animated "GOCHUJANG" glow.
Hero layout: two columns on desktop — left text, right big taco. On mobile stacked.
Add a hero background: radial gradients + diagonal stripes pattern + big rotated Korean text watermark.
Also include a "live" status card with today's location, hours, countdown, and a "Get directions" button.
Marquee ticker: red band under hero with items separated by ★.
Let me write the CSS with sections having alternating backgrounds.
I'll now write the final code. Length will be long but that's fine.
JS details:
```js
const LOC = [
{d:'MON', place:'Eastside Lot', addr:'5th & Mission', open:'11:30', close:'21:00', note:'Street Food Row'},
{d:'TUE', place:'Night Market', addr:'Union Square Alley', open:'16:00', close:'23:00', note:'Rooftop Deck'},
{d:'WED', place:'Campus Quad', addr:'State U, Gate B', open:'11:00', close:'19:00', note:'Student Specials'},
{d:'THU', place:'The Yard', addr:'Dock St. Warehouse 3', open:'11:30', close:'21:00', note:'Cider + Tacos'},
{d:'FRI', place:'Ballpark Lot', addr:'Right Field Gate 2', open:'15:00', close:'23:30', note:'Late Night'},
{d:'SAT', place:'Art District', addr:'6th & Vine', open:'10:00', close:'22:00', note:'Brunch Tacos'},
{d:'SUN', place:'Riverside Park', addr:'South Lawn', open:'10:00', close:'20:00', note:'Family Day'}
];
```
Status logic: today = new Date().getDay() (0=Sun). Map to index. If within hours → OPEN, else CLOSED with next open.
Countdown: to close if open, else to next open.
Show in nav pill: "OPEN NOW" or "CLOSED · OPENS 11:30".
Also location section: list of all 7 with today's highlighted, plus mini map SVG.
Map SVG: 800x360 viewBox, roads as gray lines, blocks, park green, and a truck marker that animates along a road via CSS offset-path on an SVG group? offset-path doesn't apply to SVG elements well (it applies to HTML/CSS boxes). Instead use SVG <animateMotion> — supported in Chrome! Use `<animateMotion dur="12s" repeatCount="indefinite" path="M..."/>` with `<mpath>`. That works in Chrome and is self-contained. But SMIL animations might be paused in some contexts? They work in Chrome. I'll use animateMotion for the truck marker on the map, with a fallback: also CSS animate the marker via transform? If SMIL fails, the truck sits at the start of path — acceptable.
Also make sure the map section is visible & fun.
Reviews carousel: 4 reviews, auto every 5s, dots, prev/next, pause on hover.
Catering form: fields name, email, date, guests, submit → success message + confetti-ish toast.
Newsletter form in footer: email input → success.
Scroll reveal: `.reveal` class with IntersectionObserver adding `.in`.
Nav mobile: hamburger toggles a dropdown panel.
Let me also add a floating "🛒 cart" button bottom-right with count badge that opens a small cart drawer. Keep it simple: a cart panel fixed bottom-right that expands.
Let me manage time and write it.
One more: "Spice meter" component — 5 chili icons filled per level. Used in menu cards and lab preview.
I'll write the spice as inline SVG pepper symbol used with `<use>` and a class 'on'/'off' controlling fill via CSS: `.pepper .fill{opacity:0}` `.pepper.on .fill{opacity:1}`.
OK, writing now. I'll be careful with escaping and no syntax errors.
For the sprite, define:
```html
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
<defs>
<linearGradient id="gShell" ...>
<symbol id="ico-taco" viewBox="0 0 64 64">...</symbol>
...
</defs>
</svg>
```
Note: `<use href="#ico-taco">` with symbol requires the symbol to have viewBox and the use needs width/height. I'll set `<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>`. The symbol's own viewBox scales. Works.
Icons:
- ico-taco: dome + lettuce
- ico-fries: red carton with yellow sticks
- ico-cup: cup with straw
- ico-pepper: chili
- ico-bowl: bowl of bingsu
- ico-star
- ico-truck: food truck
- ico-pin: map pin
Let me write those paths simply.
ico-taco (64x64): shell path "M8 46 A24 24 0 0 1 56 46 Z" fill #F3C169; lettuce: three small green bumps along top: circles at (18,40)? Let's: filling bumps: path "M12 40 q4 -12 10 -6 q2 -12 10 -6 q4 -10 10 -4 q6 -8 10 2 l0 10 H12 Z" fill green. Simplify with circles.
Fine, small details.
ico-fries: carton: polygon (18,30 46,30 42,58 22,58) fill red; fries: rects yellow at various positions above.
ico-cup: cup polygon (18,18 46,18 42,58 22,58) fill cream; lid line; straw line red.
ico-bowl: bowl path semicircle fill purple-blue; white top blob.
ico-pepper: path for chili: "M32 12 c 10 4 14 14 10 24 c -3 8 -10 12 -16 12 c 8 -8 10 -18 6 -26 z" plus stem. Simplify: use a rounded shape with a curve, fill red, stem green.
ico-truck: rect body + cab + wheels.
ico-pin: teardrop path.
OK, writing the final answer now. I'll keep the code organized and long.
Let me draft the CSS carefully.
```css
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--ink);color:var(--cream);font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow-x:hidden}
```
Sections padding: clamp(56px, 8vw, 110px) 0.
Container: width min(1200px, 92vw) margin auto.
Display font class: .disp{font-family:Impact,"Haettenschweiler","Arial Narrow Bold",var(--sans);font-weight:900;text-transform:uppercase;letter-spacing:-.01em}
Hmm Impact has no lowercase distinction... fine.
Hero headline: font-size clamp(3.2rem, 12vw, 9rem); line-height .85; color cream; text-shadow: 6px 6px 0 var(--red), plus a stroke: -webkit-text-stroke: 3px var(--ink) maybe.
I'll do: hero title "KIMCHI" (cream w/ red shadow) "LOCO" (yellow w/ red shadow) stacked.
Korean subtitle: "김치 로코" — Korean glyphs may not render in sandbox without Korean font (DejaVu doesn't have Hangul; Noto CJK may not be installed). If missing → tofu boxes. Risky! That would look broken. Hmm. Many Linux sandboxes do have Noto CJK? Not guaranteed. Safer to avoid Korean text, or use it decoratively with fallback... Tofu boxes would be bad.
Alternative: render the Korean text as SVG paths? Too complex. I'll include Hangul but guard: Actually I can detect font support via canvas measureText comparison with a known-missing glyph. If unsupported, hide the element. That's a nice robust trick:
```js
function hasGlyph(ch, font){ ... measure width of ch vs width of \uFFFF ... }
```
Standard technique: render '\uD83D\uDE00' (emoji) or use a box char. Use: measure '김' with font and compare with measure '\uFFFF' (guaranteed .notdef). If equal widths → likely tofu. Hmm widths might coincidentally be equal. Use canvas: ctx.font='72px sans-serif'; const w1=ctx.measureText('김').width; const w2=ctx.measureText('\uFFFF').width; if(Math.abs(w1-w2)<0.5) → not supported → hide.
I'll apply that to elements with class .hangul, hiding them if unsupported. Good. Also keep plenty of non-Korean text so design doesn't depend on it.
Actually simpler: just don't rely on Hangul at all for meaning; use it as a decorative accent, hidden if unsupported. Yes, do that.
Let me write the code.
Additional fun: "🔥 SPICE LEVEL" meter in lab; a "Taco Translator"? Skip.
Also include a section "OUR SAUCE" with a big animated bottle? Maybe a "5-ingredient" list. Let's include a feature strip with 4 features: "Marinated 24hrs", "Fresh-pressed kimchi daily", "Gochujang from scratch", "Halal & veggie options" with icons.
Also "As seen on" logos strip (text-based fake logos) — a marquee: "★ EAT STREET ★ FOOD&WINE ★ ..." Hmm fake publications might be odd but it's a demo. I'll do "Voted Best Street Taco — City Food Awards 2024" badge instead. Fine.
Let me write out the code now, for real.
For the cart drawer, I'll do a fixed panel bottom-right that slides up when there are items or when clicking the cart button. Items list with name, price, qty +/-, total, "Checkout" → shows "Order placed! We'll text you 🐮" message. Avoid emoji? Fine, use text.
I'll include a toast element.
Now write.
Also, add `prefers-reduced-motion` handling minimal.
Final check on no-horizontal-scroll: the marquee track will be wider but inside overflow:hidden containers. The map SVG: width 100%. The big rotating Korean watermark: position absolute, transform rotate, might overflow → parent overflow hidden. ok.
Writing the code:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Kimchi Loco — Korean Taco Food Truck</title>
<meta name="description" content="...">
<style>...</style>
</head>
<body>
<svg sprite>
<header nav>
<main>
sections
</main>
<footer>
<toast, cart>
<script>...</script>
</body>
</html>
```
Let me write the nav:
```html
<header class="nav" id="nav">
<div class="nav-in">
<a class="brand" href="#top">
<svg class="brand-mark" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<span class="brand-text"><b>KIMCHI</b><b class="loco">LOCO</b></span>
</a>
<nav class="nav-links">
<a href="#menu">Menu</a><a href="#lab">Taco Lab</a><a href="#truck">Find Us</a><a href="#reviews">Reviews</a>
</nav>
<div class="nav-right">
<span class="status-pill" id="statusPill"><i class="dot"></i><span id="statusText">OPEN NOW</span></span>
<a href="#lab" class="btn btn-red btn-sm">Order</a>
<button class="burger" id="burger" aria-label="Menu">☰</button>
</div>
</div>
<div class="mobile-menu" id="mobileMenu"> links </div>
</header>
```
Ticker above nav? Put ticker at very top (a thin red band) then nav sticky below. Let's put ticker above the nav, and nav sticky top:0.
Hero section id="top".
Let me write all the markup now concretely. I'll produce the final file.
Menu card markup:
```html
<article class="card reveal" data-cat="tacos" data-spice="3">
<div class="card-top">
<svg class="card-ico" viewBox="0 0 64 64"><use href="#ico-taco"/></svg>
<div class="card-head">
<h3>The Original Bulgogi</h3>
<span class="tag">BEST SELLER</span>
</div>
<span class="price">$4.50</span>
</div>
<p class="desc">Sweet-soy marinated steak, gochujang glaze, kimchi slaw, sesame-lime crema.</p>
<div class="card-foot">
<div class="pep-row" data-heat="3">...</div>
<button class="add-btn" data-item="The Original Bulgogi" data-price="4.50">Add</button>
</div>
</article>
```
Spice row generated by JS for each card? I'll just hand-write 5 pepper svgs per card — that's 18 cards × 5 = 90 svgs. Too much. Instead, generate pepper row via JS on load: for each .pep-row[data-heat], fill with N `.pep.on` and 5-N `.pep.off`. Good — small JS.
Icons in the pepper row: `<svg class="pep" viewBox="0 0 24 24"><use href="#ico-pep"/></svg>` and CSS controls the fill via `.pep .body{opacity:0}`? With <use> referencing a symbol, CSS can't target inside shadow DOM easily. Instead: give the symbol two shapes? Simpler: use CSS `filter`/opacity on the whole use? The pepper symbol fill is red; for "off" state, set the svg's opacity .25 and grayscale filter. That works: `.pep.off{opacity:.28;filter:grayscale(1)}`.
Good.
Now the Lab controls markup: radios styled as chips; extras as toggle buttons with aria-pressed.
I'll implement with buttons and data attributes.
Price calc: base protein price + base tortilla + extras + heat surcharge (maybe heat>=4 +0.50 "legend tax"? no, keep it simple: no surcharge; instead "spice level" only).
Name generator: e.g., protein names: "Bulgogi", "Kimchi Chicken", "Crispy Tofu", "Garlic Shrimp", "Pork Belly", "Gochujang Jack". Combined with toppings → nickname like "The Kimchi Volcano", etc. I'll do: base name + "Loaded"/"Stacked" if >2 toppings; e.g. "Bulgogi Bomb". Fun mapping:
- Bulgogi → "The Bulgogi Bomb"
- Kimchi Chicken → "Kimchi Tears"
- Crispy Tofu → "Tofu Tantrum"
- Garlic Shrimp → "Shrimp Dynamite"
- Pork Belly → "Belly Flop"
- Gochujang Jack → "Jack in the Box"
Then if kimchi selected add " w/ Kimchi"? Better: name = proteinNickname; if egg → "Sunny Side"; hmm keep the nickname plus a dynamic subtitle listing toppings.
Preview: update colors: protein fill changes (#B4531F bulgogi, #E4703A chicken, #E8D9A0 tofu, #F5A25D shrimp, #D98A5B pork, #8E5A2B jack). Heat → flame group opacity & sauce color.
Let me add flames SVG group with 3-5 chili flames, JS sets opacity per flame based on heat.
OK writing final code. I'll try to keep it tight but complete.
For the cart: items array; render list; total; "Checkout" button shows success.
I'll add a subtle "order counter" in nav.
Also add scroll progress bar at top (red).
Let me write everything now — final answer.
One more consideration: "Something meaningful must be visible on first paint" — hero + ticker. Good.
Now writing the actual code text.
CSS sections:
1. reset/vars
2. ticker
3. nav
4. hero
5. status card
6. marquee
7. features
8. menu
9. lab
10. truck/map/locations
11. reviews
12. catering form
13. footer
14. cart/toast
15. reveal animations
16. responsive
Let me go. I'll write the code in one pass, checking syntax as I go.
For the hero background, use:
```css
.hero{position:relative;overflow:hidden;background:
radial-gradient(900px 500px at 78% 25%, rgba(255,122,47,.28), transparent 60%),
radial-gradient(700px 500px at 10% 80%, rgba(227,43,34,.22), transparent 60%),
var(--ink);}
```
plus a repeating diagonal stripe overlay with low opacity.
Hero content grid: `grid-template-columns: 1.1fr .9fr; gap:40px; align-items:center;`
Hero right: taco SVG with steam + floating badges ("24HR MARINADE", "FRESH KIMCHI DAILY", "GOCHUJANG HOUSE SAUCE") arranged around it.
Let's include animated float on badges.
Status card below CTA: a card with location, hours, countdown, "Get directions" button.
Also add a "scroll" indicator.
Write now. Also add `id="top"` to hero.
For the map:
```html
<svg class="map" viewBox="0 0 900 420">
<rect width="900" height="420" fill="#1b1a18"/>
blocks rects, roads lines stroke #2e2c28 width 26, park polygon,
<g id="truckMarker"> truck icon + pulsing circle
<animateMotion dur="18s" repeatCount="indefinite" path="M120,300 L380,300 L380,140 L700,140" />
</g>
</svg>
```
Wait animateMotion path with multiple L commands works.
Also add a pulsing "you are here" circle at the truck.
The locations list next to the map: 7 rows, today's highlighted with a "TODAY" badge.
Let's write it all.
Also the catering/order form section: "Book the truck" with fields: Name, Email, Date, Guests, Event type. Submit → success card.
Alright, final code.
I need to double check the CSS `text-wrap: balance` etc. Fine.
Let me produce.