Models 44

Claude Sonnet 5.5

by Anthropicreasoning defaultClean
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
4 min 48 s
Cost
$0.430
Output tokens
42,895
Spent thinking
13,419 tokens
Speed
149.9 tok/s
Console errors
0
First token after
2.4 s
First visible text after
2 min 7 s
Prompt tokens
543
Code size
55.5 KB
Finish reason
stop
Served by
Claude Platform on AWS
Model id
anthropic/claude-sonnet-5.5
Reasoning sent
model default
Max output
128,000 tokens
Generated
Nov 12, 2026

What it was asked

The prompt
“i'm opening a korean taco food truck called "Kimchi Loco", make me a website that makes people really want to come”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task.

Output rules:
- Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block.
- Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task.
- Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw.
- The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar.
- Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction.
- Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session.
- Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing.
- The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message.
- The code must run with zero errors in the console of the latest Chrome.

Code run-1.html · 722 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 Truck</title>
<meta name="description" content="Kimchi Loco is a Korean taco food truck. Bulgogi, spicy pork, crispy chicken and fire kimchi folded into warm tortillas.">
<style>
:root{
  --red:#e63312; --deep:#b01e0a; --ink:#1a0f0c; --ink2:#2a1713; --cream:#fff3dc; --cream2:#ffe7bd;
  --yellow:#ffc72c; --green:#3ea34b; --pink:#ff7a90;
  --head:"Arial Black","Helvetica Neue",Impact,system-ui,sans-serif;
  --body:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;scroll-padding-top:70px}
body{font-family:var(--body);background:var(--cream);color:var(--ink);line-height:1.5;overflow-x:clip;-webkit-font-smoothing:antialiased}
h1,h2,h3{font-family:var(--head);font-weight:900;letter-spacing:-.02em;line-height:.95}
button{font:inherit;cursor:pointer;border:0;background:none;color:inherit}
a{color:inherit}
.wrap{max-width:1200px;margin:0 auto;padding:0 22px}
.btn{display:inline-flex;align-items:center;gap:8px;padding:14px 24px;border-radius:999px;font-weight:800;font-size:1rem;text-decoration:none;transition:transform .15s, box-shadow .15s, background .15s;border:3px solid var(--ink);box-shadow:4px 4px 0 var(--ink)}
.btn:hover{transform:translate(-2px,-2px);box-shadow:6px 6px 0 var(--ink)}
.btn:active{transform:translate(3px,3px);box-shadow:1px 1px 0 var(--ink)}
.btn.red{background:var(--red);color:#fff}
.btn.yel{background:var(--yellow);color:var(--ink)}
.btn.ghost{background:var(--cream);color:var(--ink)}
.eyebrow{display:inline-block;font-weight:800;text-transform:uppercase;letter-spacing:.16em;font-size:.78rem;color:var(--red);margin-bottom:12px}
.sec-title{font-size:clamp(2.2rem,5.5vw,4rem);margin-bottom:14px}
.sec-sub{max-width:560px;font-size:1.08rem;opacity:.8}

/* NAV */
nav{position:sticky;top:0;z-index:50;background:rgba(26,15,12,.92);backdrop-filter:blur(8px);color:var(--cream)}
nav .wrap{display:flex;align-items:center;gap:22px;height:64px}
.logo{display:flex;align-items:center;gap:8px;text-decoration:none;font-family:var(--head);font-size:1.25rem;letter-spacing:-.02em}
.logo b{background:var(--yellow);color:var(--ink);padding:2px 9px 3px;border-radius:8px;transform:rotate(-4deg);display:inline-block}
.logo span{color:var(--cream)}
nav .links{margin-left:auto;display:flex;gap:24px;font-weight:700;font-size:.95rem}
nav .links a{text-decoration:none;opacity:.85}
nav .links a:hover{opacity:1;color:var(--yellow)}
.tray-btn{display:flex;align-items:center;gap:8px;background:var(--red);color:#fff;font-weight:800;padding:9px 16px;border-radius:999px;font-size:.92rem;transition:transform .15s}
.tray-btn:hover{transform:scale(1.05)}
.tray-btn .n{background:var(--yellow);color:var(--ink);min-width:22px;height:22px;border-radius:11px;display:grid;place-items:center;font-size:.8rem;padding:0 5px}
.tray-btn.bump{animation:bump .4s}
@keyframes bump{40%{transform:scale(1.18) rotate(-4deg)}}

/* HERO */
.hero{position:relative;background:radial-gradient(900px 500px at 75% 60%,rgba(230,51,18,.45),transparent 70%),var(--ink);color:var(--cream);overflow:hidden;padding:84px 0 40px}
.lights{position:absolute;left:0;right:0;top:0;height:64px;pointer-events:none}
.lights svg{position:absolute;inset:0;width:100%;height:60px}
.bulb{position:absolute;width:12px;height:16px;border-radius:50% 50% 50% 50%/40% 40% 60% 60%;transform:translate(-50%,0);animation:twinkle 2.4s infinite}
@keyframes twinkle{0%,100%{opacity:1;filter:drop-shadow(0 0 8px currentColor)}50%{opacity:.45;filter:none}}
.hero .wrap{display:grid;grid-template-columns:1fr 1.05fr;gap:20px;align-items:center}
.status{display:inline-flex;align-items:center;gap:10px;background:rgba(255,243,220,.1);border:1px solid rgba(255,243,220,.25);padding:8px 16px;border-radius:999px;font-weight:700;font-size:.88rem;margin-bottom:22px}
.status .dot{width:10px;height:10px;border-radius:50%;background:#999;flex:none}
.status.open .dot{background:#4cf06b;box-shadow:0 0 0 0 rgba(76,240,107,.7);animation:ping 1.6s infinite}
.status.soon .dot{background:var(--yellow)}
@keyframes ping{to{box-shadow:0 0 0 12px rgba(76,240,107,0)}}
.hero h1{font-size:clamp(3rem,7vw,5.9rem);margin-bottom:22px}
.hero h1 .l2{color:var(--yellow);display:inline-block;text-shadow:0 0 28px rgba(255,199,44,.55);animation:flick 5s infinite}
.hero h1 .l1{display:block}
@keyframes flick{0%,92%,100%{opacity:1}93%{opacity:.6}94%{opacity:1}96%{opacity:.7}97%{opacity:1}}
.hero p.lead{font-size:1.2rem;max-width:480px;opacity:.88;margin-bottom:30px}
.hero .cta{display:flex;gap:14px;flex-wrap:wrap}
.hero .btn{border-color:var(--cream);box-shadow:4px 4px 0 rgba(255,243,220,.9)}
.hero .btn:hover{box-shadow:6px 6px 0 rgba(255,243,220,.9)}
.hero .btn.red{border-color:var(--cream)}
.proof{display:flex;gap:26px;margin-top:34px;flex-wrap:wrap;font-size:.86rem;font-weight:700;opacity:.85}
.proof div{display:flex;align-items:center;gap:8px}
.proof i{width:10px;height:10px;background:var(--yellow);transform:rotate(45deg);display:block}
.hero-art{position:relative;aspect-ratio:640/400}
.hero-art>svg.truck{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.sun{position:absolute;left:50%;top:6%;width:70%;aspect-ratio:1;transform:translateX(-50%);border-radius:50%;background:linear-gradient(180deg,var(--yellow),var(--red));opacity:.9;filter:blur(.5px);box-shadow:0 0 90px rgba(255,100,40,.5)}
.sun::after{content:"";position:absolute;inset:55% 0 0 0;background:repeating-linear-gradient(180deg,transparent 0 10px,var(--ink) 10px 16px);border-radius:0 0 50% 50%}
.float-taco{position:absolute;width:26%;right:2%;top:-4%;animation:floaty 4s ease-in-out infinite;filter:drop-shadow(0 12px 12px rgba(0,0,0,.4))}
.float-taco.b{width:15%;left:3%;top:18%;right:auto;animation-delay:-2s;animation-duration:5s}
@keyframes floaty{0%,100%{transform:translateY(0) rotate(-8deg)}50%{transform:translateY(-14px) rotate(6deg)}}
#truckG{animation:drive 2.2s cubic-bezier(.17,.8,.25,1) both}
@keyframes drive{from{transform:translateX(-780px)}to{transform:translateX(0)}}
.spokes{transform-box:fill-box;transform-origin:center;animation:spin 2.2s cubic-bezier(.17,.8,.25,1) both}
@keyframes spin{from{transform:rotate(0)}to{transform:rotate(1100deg)}}
.puff{animation:puff 3s infinite ease-out;opacity:0}
.puff:nth-child(2){animation-delay:1s}.puff:nth-child(3){animation-delay:2s}
@keyframes puff{0%{transform:translateY(0) scale(.5);opacity:0}15%{opacity:.8}100%{transform:translateY(-70px) scale(1.6);opacity:0}}
#truckBody{animation:idle 1.2s ease-in-out 2.2s infinite}
@keyframes idle{50%{transform:translateY(-1.5px)}}

/* MARQUEE */
.marquee{background:var(--yellow);color:var(--ink);border-block:4px solid var(--ink);overflow:hidden;white-space:nowrap;transform:rotate(-1deg);margin:-6px -10px 0;position:relative;z-index:2}
.marquee .track{display:inline-flex;animation:scroll 28s linear infinite;padding:12px 0}
.marquee span{font-family:var(--head);font-size:1.4rem;text-transform:uppercase;display:inline-flex;align-items:center}
.marquee i{width:16px;height:16px;margin:0 26px;background:var(--red);clip-path:polygon(50% 0,62% 35%,100% 35%,69% 57%,80% 94%,50% 72%,20% 94%,31% 57%,0 35%,38% 35%)}
@keyframes scroll{to{transform:translateX(-50%)}}

/* MENU */
section{padding:96px 0}
#menu{padding-top:110px}
.tabs{display:flex;gap:10px;margin:28px 0 34px;flex-wrap:wrap}
.tab{padding:10px 22px;border-radius:999px;border:3px solid var(--ink);font-weight:800;background:transparent;transition:.15s}
.tab:hover{background:var(--cream2)}
.tab[aria-selected="true"]{background:var(--ink);color:var(--cream)}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:26px}
.card{background:#fff;border:3px solid var(--ink);border-radius:22px;box-shadow:6px 6px 0 var(--ink);overflow:hidden;display:flex;flex-direction:column;transition:transform .2s, box-shadow .2s;animation:pop .45s both}
.card:hover{transform:translate(-3px,-5px) rotate(-.6deg);box-shadow:9px 11px 0 var(--ink)}
@keyframes pop{from{opacity:0;transform:translateY(18px) scale(.97)}}
.card .art{position:relative;padding:20px 20px 8px;border-bottom:3px solid var(--ink)}
.card .art svg{width:100%;height:auto;display:block;max-height:170px;transition:transform .35s cubic-bezier(.3,1.6,.5,1)}
.card:hover .art svg{transform:scale(1.08) rotate(-4deg)}
.tag{position:absolute;top:12px;left:12px;background:var(--ink);color:var(--yellow);font-size:.7rem;font-weight:800;text-transform:uppercase;letter-spacing:.08em;padding:5px 10px;border-radius:8px;transform:rotate(-3deg)}
.card .body{padding:18px 20px 20px;display:flex;flex-direction:column;gap:8px;flex:1}
.card h3{font-size:1.4rem;line-height:1}
.card p{font-size:.93rem;opacity:.78;flex:1}
.heat{display:flex;align-items:center;gap:2px;font-size:.72rem;font-weight:800;text-transform:uppercase;letter-spacing:.08em}
.heat svg{width:17px;height:17px}
.heat span{margin-right:8px;opacity:.6}
.buy{display:flex;align-items:center;justify-content:space-between;margin-top:6px}
.price{font-family:var(--head);font-size:1.6rem}
.add{background:var(--red);color:#fff;font-weight:800;padding:10px 18px;border-radius:999px;border:3px solid var(--ink);transition:.15s}
.add:hover{background:var(--ink);transform:scale(1.06)}
.deal{margin-top:34px;display:flex;align-items:center;gap:14px;background:var(--ink);color:var(--cream);padding:16px 22px;border-radius:16px;font-weight:700;flex-wrap:wrap}
.deal b{color:var(--yellow);font-family:var(--head);font-size:1.3rem}

/* BUILDER */
#build{background:var(--yellow);border-block:4px solid var(--ink);position:relative;overflow:hidden}
#build::before{content:"";position:absolute;inset:0;background:radial-gradient(circle,rgba(26,15,12,.1) 2px,transparent 2.5px) 0 0/22px 22px;pointer-events:none}
#build .wrap{position:relative;display:grid;grid-template-columns:1fr 1.1fr;gap:40px;align-items:center}
#build .eyebrow{color:var(--deep)}
.preview{background:var(--cream);border:4px solid var(--ink);border-radius:30px;box-shadow:10px 10px 0 var(--ink);padding:26px;text-align:center}
.preview svg{width:100%;max-width:380px;height:auto;filter:drop-shadow(0 10px 8px rgba(0,0,0,.15))}
.preview svg.wob{animation:wob .5s}
@keyframes wob{30%{transform:scale(1.07) rotate(-3deg)}60%{transform:scale(.98) rotate(2deg)}}
.preview h3{font-size:2.1rem;margin:6px 0 4px}
.preview .sub{font-size:.95rem;opacity:.75;min-height:2.9em}
.preview .row{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px;flex-wrap:wrap}
.opts h4{font-weight:800;text-transform:uppercase;letter-spacing:.1em;font-size:.8rem;margin:20px 0 10px}
.opts h4:first-of-type{margin-top:0}
.chips{display:flex;flex-wrap:wrap;gap:10px}
.chip{display:inline-flex;align-items:center;gap:8px;padding:9px 16px;border-radius:999px;border:3px solid var(--ink);background:var(--cream);font-weight:700;font-size:.92rem;transition:.15s}
.chip i{width:14px;height:14px;border-radius:50%;border:2px solid var(--ink);display:block}
.chip:hover{transform:translateY(-2px)}
.chip[aria-pressed="true"]{background:var(--ink);color:var(--cream);box-shadow:3px 3px 0 var(--red)}
.chip[aria-pressed="true"] i{border-color:var(--cream)}
.surprise{margin-top:26px}

/* PROMO */
#opening{background:var(--red);color:#fff;text-align:center;padding:80px 0;position:relative;overflow:hidden}
#opening h2{font-size:clamp(2.4rem,6.5vw,5rem);margin-bottom:12px}
#opening h2 em{font-style:normal;color:var(--yellow)}
#opening p{max-width:560px;margin:0 auto 30px;font-size:1.12rem}
.count{display:flex;justify-content:center;gap:14px;margin-bottom:34px;flex-wrap:wrap}
.count div{background:var(--ink);border-radius:18px;padding:16px 8px;min-width:92px;border:3px solid var(--cream);box-shadow:5px 5px 0 rgba(0,0,0,.35)}
.count b{display:block;font-family:var(--head);font-size:2.6rem;color:var(--yellow);line-height:1;font-variant-numeric:tabular-nums}
.count small{font-weight:800;text-transform:uppercase;letter-spacing:.14em;font-size:.68rem;opacity:.85}
.conf{position:absolute;width:14px;height:14px;opacity:.8;animation:fall linear infinite}
@keyframes fall{from{transform:translateY(-40px) rotate(0)}to{transform:translateY(520px) rotate(540deg)}}

/* FIND */
#find .wrap{display:grid;grid-template-columns:1fr 1.1fr;gap:44px;align-items:start}
.days{margin-top:26px;display:flex;flex-direction:column;gap:10px}
.day{display:grid;grid-template-columns:62px 1fr auto;gap:12px;align-items:center;text-align:left;padding:14px 18px;border-radius:16px;border:3px solid var(--ink);background:#fff;transition:.15s}
.day:hover{transform:translateX(5px)}
.day .d{font-family:var(--head);font-size:1.15rem}
.day .p{font-weight:700;font-size:.95rem;line-height:1.2}
.day .t{font-size:.82rem;opacity:.7;white-space:nowrap}
.day.today .d::after{content:"TODAY";display:block;font-family:var(--body);font-size:.58rem;letter-spacing:.12em;color:var(--red)}
.day[aria-pressed="true"]{background:var(--ink);color:var(--cream);box-shadow:5px 5px 0 var(--red)}
.day[aria-pressed="true"] .d::after{color:var(--yellow)}
.day.off{opacity:.65;background:var(--cream2)}
.day.off[aria-pressed="true"]{background:var(--ink);opacity:1}
.mapcard{position:sticky;top:84px;background:#fff;border:4px solid var(--ink);border-radius:26px;box-shadow:10px 10px 0 var(--ink);overflow:hidden}
.mapcard svg{display:block;width:100%;height:auto}
.pin{transition:transform .7s cubic-bezier(.3,1.5,.5,1)}
.pin .bounce{animation:bounce 1s ease-in-out infinite}
@keyframes bounce{50%{transform:translateY(-9px)}}
.ring{animation:ring 1.8s infinite;transform-box:fill-box;transform-origin:center}
@keyframes ring{from{transform:scale(.4);opacity:.9}to{transform:scale(2.6);opacity:0}}
.info{padding:20px 24px 24px;border-top:4px solid var(--ink);background:var(--cream)}
.info h3{font-size:1.6rem;margin-bottom:6px}
.info .addr{font-weight:700}
.info .meta{display:flex;gap:18px;flex-wrap:wrap;margin-top:8px;font-size:.92rem}
.info .meta span{background:#fff;border:2px solid var(--ink);border-radius:999px;padding:3px 12px;font-weight:700}

/* REVIEWS */
#love{background:var(--ink);color:var(--cream);overflow:hidden}
#love .eyebrow{color:var(--yellow)}
.quotes{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:26px;margin-top:40px}
.q{background:var(--cream);color:var(--ink);border-radius:22px;padding:26px;position:relative;transition:transform .25s}
.q:nth-child(1){transform:rotate(-1.8deg)}.q:nth-child(2){transform:rotate(1.2deg) translateY(10px);background:var(--yellow)}.q:nth-child(3){transform:rotate(-.8deg)}
.q:hover{transform:rotate(0) scale(1.03)}
.q::before{content:"\201C";position:absolute;top:-8px;left:18px;font-family:var(--head);font-size:5rem;color:var(--red);line-height:1}
.q p{margin-top:28px;font-size:1.08rem;font-weight:600}
.q footer{margin-top:16px;font-weight:800;font-size:.85rem;text-transform:uppercase;letter-spacing:.08em;opacity:.7}
.stars{color:var(--red);letter-spacing:3px;font-size:1.1rem;margin-top:12px}

/* CONTACT */
#contact .wrap{display:grid;grid-template-columns:1fr 1fr;gap:28px}
.box{border:3px solid var(--ink);border-radius:26px;padding:34px;background:#fff;box-shadow:7px 7px 0 var(--ink)}
.box.alt{background:var(--green);color:#fff}
.box h3{font-size:2rem;margin-bottom:10px}
.box p{margin-bottom:18px}
form{display:flex;flex-direction:column;gap:12px}
input,select{font:inherit;padding:13px 16px;border-radius:12px;border:3px solid var(--ink);background:var(--cream);color:var(--ink);width:100%}
input:focus,select:focus{outline:3px solid var(--yellow);outline-offset:1px}
.thanks{font-family:var(--head);font-size:1.5rem;line-height:1.1;animation:pop .4s}
footer.site{background:var(--ink);color:var(--cream);padding:50px 0 34px;text-align:center}
footer.site .big{font-family:var(--head);font-size:clamp(2.6rem,11vw,8rem);line-height:.9;color:var(--red);letter-spacing:-.04em}
footer.site .big span{color:var(--yellow)}
footer.site p{opacity:.7;margin-top:14px;font-size:.9rem}

/* TRAY */
#scrim{position:fixed;inset:0;background:rgba(0,0,0,.55);opacity:0;pointer-events:none;transition:.25s;z-index:80}
#scrim.on{opacity:1;pointer-events:auto}
#tray{position:fixed;top:0;right:0;bottom:0;width:min(420px,100%);background:var(--cream);z-index:90;transform:translateX(105%);transition:transform .35s cubic-bezier(.2,.9,.3,1);display:flex;flex-direction:column;border-left:4px solid var(--ink)}
#tray.on{transform:none}
#tray header{display:flex;justify-content:space-between;align-items:center;padding:20px 22px;border-bottom:3px solid var(--ink);background:var(--yellow)}
#tray header h3{font-size:1.6rem}
#tray .x{width:38px;height:38px;border-radius:50%;border:3px solid var(--ink);font-weight:900;font-size:1.1rem;background:var(--cream)}
#trayBody{flex:1;overflow:auto;padding:16px 22px}
.line{display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center;padding:12px 0;border-bottom:2px dashed rgba(26,15,12,.25)}
.line b{display:block;line-height:1.15}
.line small{opacity:.65}
.qty{display:flex;align-items:center;gap:6px}
.qty button{width:28px;height:28px;border-radius:50%;border:2px solid var(--ink);font-weight:900;background:#fff}
.qty button:hover{background:var(--yellow)}
.empty{text-align:center;padding:50px 10px;opacity:.75;font-weight:600}
#trayFoot{padding:18px 22px 24px;border-top:3px solid var(--ink);background:#fff}
.sum{display:flex;justify-content:space-between;font-weight:700;margin-bottom:6px}
.sum.disc{color:var(--green)}
.sum.tot{font-family:var(--head);font-size:1.5rem;margin:8px 0 14px}
#trayFoot .btn{width:100%;justify-content:center}
.done{text-align:center;padding:30px 6px}
.done h4{font-family:var(--head);font-size:2rem;line-height:1;margin:14px 0 10px}
.done .no{display:inline-block;background:var(--ink);color:var(--yellow);font-family:var(--head);padding:8px 16px;border-radius:12px;margin:10px 0;transform:rotate(-2deg)}
#toast{position:fixed;left:50%;bottom:24px;transform:translate(-50%,120px);background:var(--ink);color:var(--cream);padding:12px 22px;border-radius:999px;font-weight:700;z-index:100;transition:transform .35s cubic-bezier(.3,1.5,.5,1);border:2px solid var(--yellow);max-width:92vw;text-align:center}
#toast.on{transform:translate(-50%,0)}

.js .reveal{opacity:0;transform:translateY(28px);transition:opacity .7s, transform .7s}
.js .reveal.in{opacity:1;transform:none}

@media (max-width:960px){
  .hero .wrap,#build .wrap,#find .wrap,#contact .wrap{grid-template-columns:1fr}
  .hero{padding-top:90px}
  .mapcard{position:static}
  nav .links{display:none}
  .tray-btn{margin-left:auto}
}
@media (max-width:520px){
  section{padding:70px 0}
  .day{grid-template-columns:54px 1fr;}
  .day .t{grid-column:2}
  .box{padding:24px}
  .count div{min-width:70px}
  .count b{font-size:2rem}
  .logo{font-size:1.1rem}
}
@media (prefers-reduced-motion:reduce){*{animation-duration:.01s!important;animation-iteration-count:1!important;transition:none!important}}
</style>
</head>
<body>

<nav>
  <div class="wrap">
    <a href="#top" class="logo" aria-label="Kimchi Loco home"><b>KIMCHI</b><span>LOCO</span></a>
    <div class="links">
      <a href="#menu">Menu</a><a href="#build">Build-a-Taco</a><a href="#find">Find the truck</a><a href="#contact">Catering</a>
    </div>
    <button class="tray-btn" id="trayBtn" aria-label="Open your tray">Tray <span class="n" id="trayN">0</span></button>
  </div>
</nav>

<header class="hero" id="top">
  <div class="lights" id="lights"><svg id="wire" viewBox="0 0 1200 60" preserveAspectRatio="none"></svg></div>
  <div class="wrap">
    <div class="hero-copy">
      <div class="status" id="status"><span class="dot"></span><span id="statusTxt">Checking where the truck is…</span></div>
      <h1><span class="l1">Korean fire.</span><span class="l2">Taco soul.</span></h1>
      <p class="lead">Overnight-marinated bulgogi, house-fermented kimchi and sauces that talk back, all folded into warm tortillas and served out of a truck that's probably parked near you.</p>
      <div class="cta">
        <a class="btn red" href="#menu">Get tacos →</a>
        <a class="btn ghost" href="#find">Where's the truck?</a>
      </div>
      <div class="proof">
        <div><i></i>12-hour marinade</div>
        <div><i></i>Kimchi fermented in-house</div>
        <div><i></i>Cooked to order, always</div>
      </div>
    </div>

    <div class="hero-art">
      <div class="sun"></div>
      <div class="float-taco" id="ft1"></div>
      <div class="float-taco b" id="ft2"></div>
      <svg class="truck" viewBox="0 0 640 400" aria-label="The Kimchi Loco food truck" role="img">
        <rect x="-200" y="335" width="1040" height="6" fill="#ffe7bd" opacity=".25"/>
        <g opacity=".35" fill="#ffe7bd"><rect x="-100" y="372" width="70" height="6" rx="3"/><rect x="60" y="372" width="70" height="6" rx="3"/><rect x="220" y="372" width="70" height="6" rx="3"/><rect x="380" y="372" width="70" height="6" rx="3"/><rect x="540" y="372" width="70" height="6" rx="3"/></g>
        <ellipse cx="340" cy="342" rx="300" ry="9" fill="#000" opacity=".4"/>
        <g id="truckG">
          <g id="truckBody">
            <!-- steam -->
            <g fill="#fff3dc"><circle class="puff" cx="170" cy="48" r="12"/><circle class="puff" cx="190" cy="48" r="10"/><circle class="puff" cx="150" cy="48" r="9"/></g>
            <rect x="150" y="48" width="44" height="16" rx="3" fill="#8a8a8a"/>
            <!-- cargo box -->
            <rect x="80" y="62" width="380" height="248" rx="20" fill="#e63312" stroke="#1a0f0c" stroke-width="5"/>
            <rect x="80" y="262" width="380" height="48" fill="#b01e0a" stroke="#1a0f0c" stroke-width="5"/>
            <!-- cab -->
            <path d="M460 140 L530 140 Q555 140 568 164 L602 220 Q612 236 612 256 L612 310 L460 310Z" fill="#c42a0e" stroke="#1a0f0c" stroke-width="5" stroke-linejoin="round"/>
            <path d="M478 156 L524 156 Q538 156 546 170 L570 214 L478 214Z" fill="#bfe6ff" stroke="#1a0f0c" stroke-width="4"/>
            <path d="M486 164 L520 164 L500 206 L486 206Z" fill="#fff" opacity=".35"/>
            <rect x="596" y="250" width="22" height="16" rx="4" fill="#ffc72c" stroke="#1a0f0c" stroke-width="3"/>
            <rect x="470" y="226" width="26" height="6" rx="3" fill="#1a0f0c"/>
            <!-- sign -->
            <rect x="106" y="76" width="328" height="46" rx="12" fill="#1a0f0c"/>
            <text x="270" y="109" text-anchor="middle" font-family="Arial Black,Impact,sans-serif" font-size="32" fill="#ffc72c" letter-spacing="1">KIMCHI LOCO</text>
            <!-- window -->
            <rect x="110" y="152" width="320" height="86" rx="6" fill="#2a1410" stroke="#1a0f0c" stroke-width="5"/>
            <rect x="116" y="158" width="308" height="74" fill="#ffb347" opacity=".35"/>
            <!-- chef -->
            <g>
              <rect x="248" y="198" width="52" height="40" rx="10" fill="#fff3dc"/>
              <circle cx="274" cy="186" r="15" fill="#f1c9a0"/>
              <path d="M259 178 Q259 158 274 160 Q289 158 289 178Z" fill="#fff"/>
              <rect x="258" y="174" width="32" height="7" fill="#fff"/>
              <circle cx="269" cy="188" r="1.8" fill="#1a0f0c"/><circle cx="279" cy="188" r="1.8" fill="#1a0f0c"/>
              <path d="M269 194 Q274 198 279 194" stroke="#1a0f0c" stroke-width="2" fill="none" stroke-linecap="round"/>
            </g>
            <!-- awning -->
            <g>
              <rect x="100" y="132" width="340" height="22" fill="#fff3dc" stroke="#1a0f0c" stroke-width="4"/>
              <g fill="#ffc72c"><rect x="100" y="132" width="34" height="22"/><rect x="168" y="132" width="34" height="22"/><rect x="236" y="132" width="34" height="22"/><rect x="304" y="132" width="34" height="22"/><rect x="372" y="132" width="34" height="22"/></g>
              <g stroke="#1a0f0c" stroke-width="4"><path d="M100 154 q17 20 34 0 q17 20 34 0 q17 20 34 0 q17 20 34 0 q17 20 34 0 q17 20 34 0 q17 20 34 0 q17 20 34 0 q17 20 34 0 q17 20 34 0" fill="none" transform="translate(0 0) scale(1)"/></g>
            </g>
            <!-- counter -->
            <rect x="100" y="238" width="340" height="12" rx="3" fill="#cfcfcf" stroke="#1a0f0c" stroke-width="4"/>
            <!-- plate of tacos on counter -->
            <ellipse cx="170" cy="236" rx="30" ry="4" fill="#fff"/>
            <path d="M150 236 Q170 206 190 236Z" fill="#f4cd78" stroke="#1a0f0c" stroke-width="2.5"/>
            <path d="M156 222 q14 -12 28 0" stroke="#d8332a" stroke-width="5" fill="none" stroke-linecap="round"/>
            <!-- lower panel -->
            <text x="270" y="293" text-anchor="middle" font-family="Arial Black,Impact,sans-serif" font-size="17" fill="#fff3dc" letter-spacing="3">KOREAN TACOS · EST. NOW</text>
            <!-- chili deco -->
            <path d="M104 88 q-16 10 -4 30 q4 -18 16 -22z" fill="#3ea34b" opacity="0"/>
          </g>
          <!-- wheels -->
          <g>
            <circle cx="190" cy="312" r="42" fill="#111" stroke="#1a0f0c" stroke-width="4"/>
            <g class="spokes"><circle cx="190" cy="312" r="24" fill="#bdbdbd" stroke="#1a0f0c" stroke-width="3"/><g stroke="#1a0f0c" stroke-width="4" stroke-linecap="round"><path d="M190 292V332M170 312H210M176 298L204 326M204 298L176 326"/></g></g>
            <circle cx="190" cy="312" r="6" fill="#ffc72c"/>
            <circle cx="520" cy="312" r="42" fill="#111" stroke="#1a0f0c" stroke-width="4"/>
            <g class="spokes"><circle cx="520" cy="312" r="24" fill="#bdbdbd" stroke="#1a0f0c" stroke-width="3"/><g stroke="#1a0f0c" stroke-width="4" stroke-linecap="round"><path d="M520 292V332M500 312H540M506 298L534 326M534 298L506 326"/></g></g>
            <circle cx="520" cy="312" r="6" fill="#ffc72c"/>
          </g>
        </g>
      </svg>
    </div>
  </div>
</header>

<div class="marquee" aria-hidden="true"><div class="track" id="track"></div></div>

<section id="menu">
  <div class="wrap">
    <div class="reveal">
      <span class="eyebrow">The lineup</span>
      <h2 class="sec-title">Fold. Bite. Repeat.</h2>
      <p class="sec-sub">Every taco comes on two warm, griddled tortillas. Because one is never enough and structural integrity matters.</p>
    </div>
    <div class="tabs reveal" role="tablist">
      <button class="tab" role="tab" aria-selected="true" data-cat="tacos">Tacos</button>
      <button class="tab" role="tab" aria-selected="false" data-cat="sides">Sides</button>
      <button class="tab" role="tab" aria-selected="false" data-cat="drinks">Drinks</button>
    </div>
    <div class="grid" id="menuGrid"></div>
    <div class="deal reveal"><b>Taco Trio Deal</b> Order any 3 tacos and we knock $1.50 off. Automatically, no code.</div>
  </div>
</section>

<section id="build">
  <div class="wrap">
    <div class="preview reveal">
      <div id="prevArt"></div>
      <h3 id="prevName">Loco Bulgogi</h3>
      <div class="sub" id="prevSub"></div>
      <div class="heat" id="prevHeat" style="justify-content:center;margin-top:6px"></div>
      <div class="row"><span class="price" id="prevPrice">$5.50</span><button class="add" id="prevAdd">+ Add to tray</button></div>
    </div>
    <div class="opts reveal">
      <span class="eyebrow">Build-a-Taco</span>
      <h2 class="sec-title">Your taco, <br>your rules.</h2>
      <h4>1 · Pick your protein</h4><div class="chips" id="gP"></div>
      <h4>2 · Kimchi heat</h4><div class="chips" id="gK"></div>
      <h4>3 · Sauce</h4><div class="chips" id="gS"></div>
      <h4>4 · Finish it</h4><div class="chips" id="gT"></div>
      <button class="btn red surprise" id="rand">🎲 Surprise me</button>
    </div>
  </div>
</section>

<section id="opening">
  <div class="wrap reveal">
    <span class="eyebrow" style="color:var(--yellow)">Grand opening</span>
    <h2>Free <em>Kimchi Fries</em><br>for the first 100.</h2>
    <p>Come hungry to our opening day. The first 100 people in line get a full order of Kimchi Fries on the house, plus a sticker you'll absolutely put on your laptop.</p>
    <div class="count" id="count">
      <div><b id="cd">0</b><small>Days</small></div><div><b id="ch">0</b><small>Hours</small></div><div><b id="cm">0</b><small>Min</small></div><div><b id="cs">0</b><small>Sec</small></div>
    </div>
    <a class="btn yel" href="#find">See the opening spot →</a>
  </div>
</section>

<section id="find">
  <div class="wrap">
    <div class="reveal">
      <span class="eyebrow">On the road</span>
      <h2 class="sec-title">Chase the truck.</h2>
      <p class="sec-sub">We roll to a different spot most days. Tap a day to see where we'll be parked.</p>
      <!-- Edit the SCHEDULE array in the script to match your real stops. -->
      <div class="days" id="days"></div>
    </div>
    <div class="mapcard reveal">
      <svg viewBox="0 0 400 300" id="map" role="img" aria-label="Map showing the truck location">
        <rect width="400" height="300" fill="#f5e8c9"/>
        <path d="M-10 230 C80 190 130 270 220 240 S360 190 410 210 L410 250 C360 235 300 285 220 285 S60 250 -10 270Z" fill="#9fd3e8"/>
        <ellipse cx="90" cy="70" rx="62" ry="42" fill="#b9deaa"/><ellipse cx="320" cy="110" rx="48" ry="34" fill="#b9deaa"/>
        <g stroke="#fff" stroke-width="10" stroke-linecap="round" fill="none"><path d="M0 130H400"/><path d="M180 0V300"/><path d="M0 40L400 190"/><path d="M280 0V180"/><path d="M60 150V230"/></g>
        <g stroke="#e9d6a8" stroke-width="2" fill="none"><path d="M0 130H400"/><path d="M180 0V300"/><path d="M280 0V180"/></g>
        <g font-family="system-ui,sans-serif" font-size="10" font-weight="700" fill="#6b5a3a" opacity=".8"><text x="48" y="74">GREEN PARK</text><text x="296" y="114">PLAZA</text><text x="188" y="22" transform="rotate(90 188 22)">MAIN ST</text><text x="150" y="268">RIVER</text></g>
        <g class="pin" id="pin" style="transform:translate(200px,130px)">
          <ellipse cx="0" cy="0" rx="14" ry="5" fill="#000" opacity=".25"/>
          <circle class="ring" cx="0" cy="0" r="12" fill="none" stroke="#e63312" stroke-width="3"/>
          <g class="bounce"><path d="M0 0 C-12 -18 -19 -26 -19 -38 a19 19 0 1 1 38 0 C19 -26 12 -18 0 0Z" fill="#e63312" stroke="#1a0f0c" stroke-width="3"/><circle cx="0" cy="-38" r="8" fill="#ffc72c" stroke="#1a0f0c" stroke-width="2"/></g>
        </g>
      </svg>
      <div class="info" id="info"></div>
    </div>
  </div>
</section>

<section id="love">
  <div class="wrap">
    <div class="reveal"><span class="eyebrow">Soft-launch tasters</span><h2 class="sec-title">Words from our first bites.</h2></div>
    <div class="quotes">
      <div class="q reveal"><p>I came for the bulgogi and left thinking about that gochujang crema for three days straight.</p><div class="stars">★★★★★</div><footer>Dana · tasting night regular</footer></div>
      <div class="q reveal"><p>Kimchi Fire made me cry a little, and I immediately got in line again. Send help (and more crema).</p><div class="stars">★★★★★</div><footer>Marcus · heat seeker</footer></div>
      <div class="q reveal"><p>Finally a vegan taco that isn't an afterthought. The tofu bokkeum is smoky, sticky and gone in four bites.</p><div class="stars">★★★★★</div><footer>Priya · tofu convert</footer></div>
    </div>
  </div>
</section>

<section id="contact">
  <div class="wrap">
    <div class="box reveal">
      <h3>Get the text drop.</h3>
      <p>One short message when we park, plus secret specials we never post anywhere else. No spam, just tacos.</p>
      <form id="f1"><input type="email" required placeholder="you@email.com" aria-label="Email"><button class="btn red" type="submit">Tell me where →</button></form>
    </div>
    <div class="box alt reveal">
      <h3>Book us for your party.</h3>
      <p>Weddings, offices, birthdays, block parties. We'll roll up and feed 30 to 300 people.</p>
      <form id="f2">
        <input type="text" required placeholder="Your name" aria-label="Name">
        <select aria-label="Guests"><option>About 30 guests</option><option>50 – 100 guests</option><option>100 – 200 guests</option><option>200+ guests</option></select>
        <input type="email" required placeholder="Email" aria-label="Contact email">
        <button class="btn yel" type="submit">Get a quote →</button>
      </form>
    </div>
  </div>
</section>

<footer class="site">
  <div class="wrap">
    <div class="big">KIMCHI <span>LOCO</span></div>
    <p>@kimchiloco.truck · hello@kimchiloco.example · Made with gochugaru and questionable decisions.</p>
  </div>
</footer>

<div id="scrim"></div>
<aside id="tray" aria-label="Your tray" aria-hidden="true">
  <header><h3>Your tray</h3><button class="x" id="trayX" aria-label="Close">✕</button></header>
  <div id="trayBody"></div>
  <div id="trayFoot"></div>
</aside>
<div id="toast" role="status"></div>

<script>
document.documentElement.classList.add('js');
const $=s=>document.querySelector(s), $$=s=>[...document.querySelectorAll(s)];
const money=n=>'$'+n.toFixed(2);

/* ---------- TACO ILLUSTRATION ---------- */
const P=[[44,52],[62,60],[80,48],[98,56],[116,46],[132,58],[150,50],[168,60],[184,54],[72,72],[104,70],[140,72],[162,74],[56,76],[124,62],[90,64]];
function taco(o){
  const sh=o.shell||'#f4cd78', sd=o.shellD||'#c98f3b', base=o.base||'#8fd16a';
  let g='';
  for(let i=0;i<7;i++){const cx=28+i*26,cy=64+(i%2)*7;g+=`<ellipse cx="${cx}" cy="${cy}" rx="17" ry="12" fill="${base}" stroke="rgba(0,0,0,.18)" stroke-width="1.5" transform="rotate(${(i*37)%40-20} ${cx} ${cy})"/>`}
  for(let i=0;i<6;i++){const x=34+i*27,y=62+((i*5)%3)*7;g+=`<rect x="${x}" y="${y}" width="26" height="17" rx="8" fill="${o.meat}" stroke="rgba(0,0,0,.3)" stroke-width="1.5" transform="rotate(${(i*29)%50-25} ${x+13} ${y+8})"/><ellipse cx="${x+10}" cy="${y+6}" rx="5" ry="2.5" fill="rgba(255,255,255,.22)"/>`}
  if(o.kimchi){for(let i=0;i<5;i++){g+=`<path d="M${38+i*32} ${64+(i%2)*10} q9 -16 18 0 q5 8 12 -2" stroke="${o.kimchi}" stroke-width="7" fill="none" stroke-linecap="round"/><path d="M${42+i*32} ${64+(i%2)*10} q6 -8 10 -4" stroke="rgba(255,255,255,.3)" stroke-width="2" fill="none" stroke-linecap="round"/>`}}
  if(o.sauce){g+=`<path d="M26 62 q10 -18 20 0 t20 0 t20 0 t20 0 t20 0 t20 0 t20 0 t20 0" stroke="${o.sauce}" stroke-width="5.5" fill="none" stroke-linecap="round" stroke-linejoin="round" style="filter:drop-shadow(0 1px 0 rgba(0,0,0,.25))"/>`}
  (o.top||[]).forEach((t,k)=>{P.forEach((p,i)=>{if((i+k)%2)return;const [x,y]=p,r=(i*53)%180;
    if(t==='sesame')g+=`<ellipse cx="${x}" cy="${y}" rx="2.8" ry="1.7" fill="#fff8e8" stroke="rgba(0,0,0,.2)" stroke-width=".5" transform="rotate(${r} ${x} ${y})"/>`;
    if(t==='scallion')g+=`<rect x="${x-4}" y="${y-1.3}" width="9" height="2.8" rx="1.4" fill="#4cb85a" transform="rotate(${r} ${x} ${y})"/>`;
    if(t==='cilantro')g+=`<circle cx="${x}" cy="${y}" r="3.4" fill="#2f8f3a"/><circle cx="${x+3}" cy="${y-2}" r="2.2" fill="#46ad52"/>`;
    if(t==='onion')g+=`<path d="M${x-5} ${y} q5 -8 10 0" stroke="#e8b24c" stroke-width="2.6" fill="none" stroke-linecap="round"/>`;
    if(t==='cheese')g+=`<rect x="${x-4}" y="${y-4}" width="8" height="8" rx="1.5" fill="#ffc72c" stroke="rgba(0,0,0,.2)" stroke-width=".8" transform="rotate(${r} ${x} ${y})"/>`;
  })});
  return `<svg viewBox="0 0 220 170" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
  <ellipse cx="110" cy="160" rx="82" ry="7" fill="rgba(0,0,0,.18)"/>
  <path d="M10 80 C20 160 200 160 210 80 Q110 34 10 80Z" fill="${sd}"/>
  ${g}
  <path d="M12 84 C24 168 196 168 208 84 Q110 108 12 84Z" fill="${sh}"/>
  <path d="M12 84 Q110 108 208 84" stroke="${sd}" stroke-width="3" fill="none" stroke-linecap="round"/>
  <path d="M30 118 C62 152 158 152 190 118" stroke="${sd}" stroke-width="4" opacity=".35" fill="none" stroke-linecap="round"/>
  <g fill="${sd}" opacity=".4"><circle cx="60" cy="112" r="3"/><circle cx="96" cy="128" r="2.5"/><circle cx="140" cy="122" r="3.2"/><circle cx="168" cy="106" r="2.4"/><circle cx="82" cy="104" r="2"/></g>
  <path d="M26 96 Q34 128 62 142" stroke="rgba(255,255,255,.5)" stroke-width="4" fill="none" stroke-linecap="round"/>
  </svg>`;
}
function side(kind,c){
  const sv=b=>`<svg viewBox="0 0 220 170" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><ellipse cx="110" cy="160" rx="80" ry="7" fill="rgba(0,0,0,.18)"/>${b}</svg>`;
  if(kind==='fries'){let f='';for(let i=0;i<9;i++)f+=`<rect x="${56+i*12}" y="${38+(i%3)*8}" width="9" height="66" rx="3" fill="#ffc72c" stroke="#d99a0b" stroke-width="1.5" transform="rotate(${(i-4)*4} ${60+i*12} 100)"/>`;
    f+=`<path d="M58 62 q10 -14 20 0 t20 0 t20 0 t20 0 t20 0" stroke="#fff8e8" stroke-width="5" fill="none" stroke-linecap="round"/><path d="M60 72 q12 -10 24 0 t24 0 t24 0 t24 0" stroke="#e63312" stroke-width="4" fill="none" stroke-linecap="round"/>`;
    for(let i=0;i<6;i++)f+=`<circle cx="${64+i*18}" cy="${54+(i%2)*10}" r="5" fill="#6b3419"/>`;
    for(let i=0;i<8;i++)f+=`<rect x="${60+i*14}" y="${46+(i%3)*9}" width="7" height="2.5" rx="1" fill="#4cb85a" transform="rotate(${i*30} ${63+i*14} 50)"/>`;
    return sv(f+`<path d="M46 92 L174 92 L160 156 L60 156Z" fill="#e63312" stroke="#1a0f0c" stroke-width="3.5" stroke-linejoin="round"/><circle cx="110" cy="124" r="17" fill="#ffc72c" stroke="#1a0f0c" stroke-width="3"/><path d="M103 124h14M110 117v14" stroke="#1a0f0c" stroke-width="3"/>`)}
  if(kind==='mandu'){const d=(x,y,s)=>`<path d="M${x-34*s} ${y} Q${x} ${y-56*s} ${x+34*s} ${y} Q${x} ${y+14*s} ${x-34*s} ${y}Z" fill="#f9e9c8" stroke="#c99b55" stroke-width="3"/><g stroke="#c99b55" stroke-width="2.5" stroke-linecap="round"><path d="M${x-18*s} ${y-12*s}l2 8M${x-8*s} ${y-18*s}l1 9M${x+3*s} ${y-19*s}l0 10M${x+13*s} ${y-16*s}l-1 9M${x+22*s} ${y-9*s}l-2 7"/></g>`;
    return sv(`<ellipse cx="105" cy="134" rx="92" ry="22" fill="#fff" stroke="#1a0f0c" stroke-width="3"/>`+d(66,128,1)+d(144,128,1)+d(105,104,1)+`<ellipse cx="185" cy="130" rx="20" ry="8" fill="#3a1c10" stroke="#1a0f0c" stroke-width="3"/><circle cx="178" cy="128" r="2" fill="#fff"/>`)}
  if(kind==='corn'){let f='';for(let i=0;i<20;i++)f+=`<circle cx="${70+(i%7)*13}" cy="${60+Math.floor(i/7)*13-(i%7===3?8:0)}" r="9" fill="${i%3?'#ffd84a':'#ffc72c'}" stroke="#d99a0b" stroke-width="1.2"/>`;
    return sv(f+`<path d="M62 70 q20 -20 50 -4 t50 6 l-6 16 q-30 12 -88 0Z" fill="#ffb347" opacity=".75"/><path d="M130 76 q4 30 -6 40" stroke="#ffb347" stroke-width="5" fill="none" stroke-linecap="round"/><g fill="#4cb85a"><rect x="86" y="54" width="9" height="3" rx="1.5"/><rect x="118" y="62" width="9" height="3" rx="1.5" transform="rotate(40 122 63)"/><rect x="102" y="70" width="9" height="3" rx="1.5" transform="rotate(-30 106 71)"/></g><path d="M54 84 L166 84 L154 156 L66 156Z" fill="#fff" stroke="#1a0f0c" stroke-width="3.5" stroke-linejoin="round"/><path d="M58 108 L162 108 L158 128 L62 128Z" fill="#e63312"/>`)}
  if(kind==='tteok'){let f='';for(let i=0;i<8;i++)f+=`<rect x="${48+(i%4)*32}" y="${64+Math.floor(i/4)*20}" width="34" height="17" rx="8" fill="#e8501c" stroke="#a82c0a" stroke-width="2" transform="rotate(${(i*23)%30-15} ${65+(i%4)*32} ${72+Math.floor(i/4)*20})"/><ellipse cx="${58+(i%4)*32}" cy="${68+Math.floor(i/4)*20}" rx="6" ry="2.5" fill="rgba(255,255,255,.35)"/>`;
    return sv(`<ellipse cx="110" cy="98" rx="88" ry="14" fill="#3a1c10"/>`+f+`<g fill="#fff8e8"><ellipse cx="80" cy="60" rx="3" ry="1.8"/><ellipse cx="130" cy="76" rx="3" ry="1.8"/><ellipse cx="160" cy="68" rx="3" ry="1.8"/></g><g fill="#4cb85a"><rect x="96" y="58" width="9" height="3" rx="1.5"/><rect x="146" y="82" width="9" height="3" rx="1.5"/></g><path d="M20 98 H200 C200 150 166 160 110 160 C54 160 20 150 20 98Z" fill="#2b1b16" stroke="#1a0f0c" stroke-width="3.5" stroke-linejoin="round"/><path d="M40 110 C48 140 66 148 90 150" stroke="rgba(255,255,255,.3)" stroke-width="4" fill="none" stroke-linecap="round"/>`)}
  // drinks
  let ex='';
  if(kind==='yuja')ex=`<circle cx="148" cy="72" r="20" fill="#ffe36b" stroke="#1a0f0c" stroke-width="3"/><circle cx="148" cy="72" r="13" fill="#fff6b0"/><path d="M148 72v-13M148 72l11 6M148 72l-11 6" stroke="#ffe36b" stroke-width="2"/>`;
  if(kind==='melon')ex=`<g fill="#fff" opacity=".7" stroke="#fff"><rect x="82" y="86" width="22" height="22" rx="4"/><rect x="112" y="104" width="22" height="22" rx="4" transform="rotate(12 123 115)"/><rect x="92" y="118" width="20" height="20" rx="4" transform="rotate(-10 102 128)"/></g>`;
  if(kind==='banana')ex=`<rect x="84" y="96" width="52" height="34" rx="6" fill="#fff" stroke="#1a0f0c" stroke-width="2.5"/><path d="M92 118 q16 -22 34 -6" stroke="#ffc72c" stroke-width="7" fill="none" stroke-linecap="round"/>`;
  if(kind==='tea')ex=`<g fill="#fff" opacity=".35"><rect x="84" y="90" width="22" height="22" rx="4"/><rect x="114" y="110" width="22" height="22" rx="4" transform="rotate(12 125 121)"/></g>`;
  return sv(`<path d="M120 20 L132 14 L142 82" stroke="#1a0f0c" stroke-width="7" fill="none" stroke-linecap="round" transform="translate(-14 0)"/><path d="M118 20 L128 14 L138 82" stroke="${c.straw||'#fff'}" stroke-width="3.5" fill="none" stroke-linecap="round" transform="translate(-14 0)"/><path d="M62 68 L158 68 L146 156 L74 156Z" fill="${c.col}" stroke="#1a0f0c" stroke-width="3.5" stroke-linejoin="round"/>${ex}<rect x="56" y="56" width="108" height="14" rx="7" fill="#fff" stroke="#1a0f0c" stroke-width="3.5"/><path d="M72 80 L76 140" stroke="rgba(255,255,255,.5)" stroke-width="5" stroke-linecap="round"/>`);
}
const flame=(on)=>`<svg viewBox="0 0 24 24"><path d="M12 2c1 4 6 6 6 12a6 6 0 0 1-12 0c0-3 2-4 3-7 1 1 1 2 2 3 0-3 0-5 1-8z" fill="${on?'#e63312':'#1a0f0c'}" ${on?'stroke="#1a0f0c" stroke-width="1.6"':'opacity=".15"'} stroke-linejoin="round"/></svg>`;
const heatHTML=n=>`<span>Heat</span>`+[1,2,3,4,5].map(i=>flame(i<=n)).join('');

/* ---------- MENU DATA ---------- */
const SH_DARK={shell:'#3b2a24',shellD:'#1f1411'};
const MENU={
 tacos:[
  {id:'t1',name:'Bulgogi Loco',price:5.5,heat:2,tag:'Best seller',bg:'#ffd9c9',desc:'Soy-garlic marinated ribeye, kimchi slaw, gochujang crema, toasted sesame.',t:{meat:'#6b3419',base:'#9bd873',kimchi:'#d8332a',sauce:'#fff0dc',top:['sesame','scallion']}},
  {id:'t2',name:'Dweji Fire',price:5.5,heat:4,bg:'#ffe08a',desc:'Gochujang-glazed pork shoulder, pickled daikon, cilantro and a squeeze of lime.',t:{meat:'#b8401c',base:'#e9f0b8',kimchi:'#d8332a',sauce:'#f2dd6c',top:['cilantro','sesame']}},
  {id:'t3',name:'Crunch Chicken',price:5.75,heat:3,bg:'#c9ecd0',desc:'Double-fried yangnyeom chicken, sticky-sweet glaze, scallion, spicy mayo.',t:{meat:'#e2a23c',base:'#a4de78',sauce:'#ff9a7a',top:['scallion','sesame']}},
  {id:'t4',name:'Galbi Short Rib',price:7,heat:2,tag:'Premium',bg:'#f8c6d0',desc:'Charred LA-style short rib, ssamjang, crispy onions, fresh perilla leaf.',t:{meat:'#4a2214',base:'#7fcf6a',sauce:'#b0502e',top:['onion','sesame']}},
  {id:'t5',name:'Tofu Bokkeum',price:5,heat:2,tag:'Vegan',bg:'#d6eec0',desc:'Smoky sesame-soy tofu, quick-pickled cucumber, kimchi slaw, scallion.',t:{meat:'#e8cf8a',base:'#8fd16a',kimchi:'#e8a58f',sauce:'#fff0dc',top:['scallion','sesame']}},
  {id:'t6',name:'Kimchi Fire',price:6.5,heat:5,tag:'Loco special',bg:'#ff9d82',desc:'Ghost-pepper kimchi, spicy pork, molten cheese. Order at your own risk.',t:{...SH_DARK,meat:'#b8401c',base:'#e9f0b8',kimchi:'#8c0f22',sauce:'#ffc72c',top:['cheese','scallion']}}
 ],
 sides:[
  {id:'s1',name:'Kimchi Fries',price:9,heat:3,tag:'Famous',bg:'#ffe08a',desc:'Crispy fries buried in bulgogi, kimchi, melted cheese and sriracha mayo.',s:['fries']},
  {id:'s2',name:'Mandu Trio',price:6.5,heat:1,bg:'#ffd9c9',desc:'Pan-fried pork & chive dumplings with a sticky soy-vinegar dip.',s:['mandu']},
  {id:'s3',name:'Corn Cheese Cup',price:5,heat:1,tag:'Vegetarian',bg:'#c9ecd0',desc:'Sweet corn, bubbling mozzarella and kewpie. Dangerously snackable.',s:['corn']},
  {id:'s4',name:'Tteok Bites',price:7,heat:3,bg:'#f8c6d0',desc:'Chewy rice cakes tossed in spicy-sweet gochujang glaze.',s:['tteok']}
 ],
 drinks:[
  {id:'d1',name:'Yuja Lemonade',price:4,heat:0,bg:'#fff0a8',desc:'Tangy Korean citron over ice. Brighter than your future.',s:['yuja',{col:'#ffe36b'}]},
  {id:'d2',name:'Banana Milk',price:4,heat:0,tag:'Cult fave',bg:'#ffe9b0',desc:'Creamy, sweet and nostalgic. Cools down Kimchi Fire.',s:['banana',{col:'#fff2b0',straw:'#ff7a90'}]},
  {id:'d3',name:'Iced Barley Tea',price:3,heat:0,bg:'#e6d1b8',desc:'Toasty, nutty and unsweetened. The perfect palate reset.',s:['tea',{col:'#c88a4a'}]},
  {id:'d4',name:'Melon Soda',price:3.5,heat:0,bg:'#c9ecd0',desc:'Fizzy, neon-green and ridiculously refreshing.',s:['melon',{col:'#8fe3a2',straw:'#ffc72c'}]}
 ]
};
const ITEMS={};
Object.entries(MENU).forEach(([c,l])=>l.forEach(i=>{i.cat=c;ITEMS[i.id]=i}));

function art(i){return i.t?taco(i.t):side(i.s[0],i.s[1]||{})}
function renderMenu(cat){
  $('#menuGrid').innerHTML=MENU[cat].map((i,k)=>`
   <article class="card" style="animation-delay:${k*60}ms">
     <div class="art" style="background:${i.bg}">${i.tag?`<span class="tag">${i.tag}</span>`:''}${art(i)}</div>
     <div class="body"><h3>${i.name}</h3>
       ${i.heat?`<div class="heat">${heatHTML(i.heat)}</div>`:'<div class="heat"><span>Heat · none, just chill</span></div>'}
       <p>${i.desc}</p>
       <div class="buy"><span class="price">${money(i.price)}</span><button class="add" data-add="${i.id}">+ Add</button></div>
     </div></article>`).join('');
}
$$('.tab').forEach(t=>t.addEventListener('click',()=>{
  $$('.tab').forEach(x=>x.setAttribute('aria-selected',x===t));
  renderMenu(t.dataset.cat);
}));
renderMenu('tacos');

/* ---------- TRAY ---------- */
const cart={};let placed=null;
function toast(m){const t=$('#toast');t.textContent=m;t.classList.add('on');clearTimeout(toast.t);toast.t=setTimeout(()=>t.classList.remove('on'),1900)}
function addItem(it){
  placed=null;
  (cart[it.id]=cart[it.id]||{...it,qty:0}).qty++;
  updateTray();toast(`Added ${it.name} to your tray`);
  const b=$('#trayBtn');b.classList.remove('bump');void b.offsetWidth;b.classList.add('bump');
}
function totals(){
  let sub=0,tc=0,n=0;Object.values(cart).forEach(i=>{sub+=i.price*i.qty;n+=i.qty;if(i.cat==='tacos')tc+=i.qty});
  const disc=Math.floor(tc/3)*1.5;return{sub,disc,tot:sub-disc,n,tc};
}
function updateTray(){
  const T=totals();$('#trayN').textContent=T.n;
  const body=$('#trayBody'),foot=$('#trayFoot');
  if(placed){
    body.innerHTML=`<div class="done"><svg viewBox="0 0 220 170" width="150">${taco(ITEMS.t1.t).replace(/<svg[^>]*>|<\/svg>/g,'')}</svg><h4>You're in the queue!</h4><div class="no">${placed.no}</div><p>Tell us this number at the window.<br>Ready in about <b>${placed.min} minutes</b>. We'll be the ones waving.</p></div>`;
    foot.innerHTML=`<button class="btn yel" id="doneBtn">Back to the menu</button>`;
    $('#doneBtn').onclick=closeTray;return;
  }
  const ids=Object.keys(cart);
  if(!ids.length){body.innerHTML=`<div class="empty">Your tray is empty.<br>Tacos won't eat themselves.</div>`;foot.innerHTML='';return}
  body.innerHTML=ids.map(id=>{const i=cart[id];return `<div class="line"><div><b>${i.name}</b><small>${money(i.price)} each${i.note?' · '+i.note:''}</small></div><div class="qty"><button data-dec="${id}" aria-label="Less">−</button><b>${i.qty}</b><button data-inc="${id}" aria-label="More">+</button></div><b>${money(i.price*i.qty)}</b></div>`}).join('');
  foot.innerHTML=`<div class="sum"><span>Subtotal</span><span>${money(T.sub)}</span></div>${T.disc?`<div class="sum disc"><span>Taco Trio deal</span><span>−${money(T.disc)}</span></div>`:(T.tc?`<div class="sum" style="opacity:.6"><span>Add ${3-T.tc%3} more taco${3-T.tc%3>1?'s':''} to save $1.50</span><span></span></div>`:'')}<div class="sum tot"><span>Total</span><span>${money(T.tot)}</span></div><button class="btn red" id="placeBtn">Place pickup order →</button>`;
  $('#placeBtn').onclick=()=>{placed={no:'LOCO-'+(1000+Math.floor(Math.random()*9000)),min:6+Math.floor(Math.random()*8)};Object.keys(cart).forEach(k=>delete cart[k]);updateTray()};
}
function openTray(){$('#tray').classList.add('on');$('#scrim').classList.add('on');$('#tray').setAttribute('aria-hidden','false')}
function closeTray(){$('#tray').classList.remove('on');$('#scrim').classList.remove('on');$('#tray').setAttribute('aria-hidden','true');if(placed){placed=null;updateTray()}}
$('#trayBtn').onclick=openTray;$('#trayX').onclick=closeTray;$('#scrim').onclick=closeTray;
document.addEventListener('keydown',e=>{if(e.key==='Escape')closeTray()});
document.addEventListener('click',e=>{
  const a=e.target.closest('[data-add]');if(a){addItem(ITEMS[a.dataset.add]);return}
  const inc=e.target.closest('[data-inc]');if(inc){cart[inc.dataset.inc].qty++;updateTray();return}
  const dec=e.target.closest('[data-dec]');if(dec){const i=cart[dec.dataset.dec];if(--i.qty<=0)delete cart[dec.dataset.dec];updateTray()}
});
updateTray();

/* ---------- BUILDER ---------- */
const OPT={
 P:[{id:'beef',n:'Bulgogi',c:'#6b3419',d:0},{id:'pork',n:'Spicy Pork',s:'Pork',c:'#b8401c',d:0},{id:'chk',n:'Crispy Chicken',s:'Chicken',c:'#e2a23c',d:.25},{id:'tofu',n:'Tofu',c:'#e8cf8a',d:-.5},{id:'galbi',n:'Short Rib',s:'Galbi',c:'#4a2214',d:1.5}],
 K:[{id:'mild',n:'Mild napa',adj:'Sweet',c:'#e8a58f',h:1},{id:'cls',n:'Classic',adj:'Loco',c:'#d8332a',h:3},{id:'fire',n:'Ghost pepper',adj:'Dragon',c:'#8c0f22',h:5}],
 S:[{id:'crema',n:'Gochujang crema',c:'#fff0dc',h:0},{id:'ssam',n:'Ssamjang',c:'#b0502e',h:1},{id:'yuzu',n:'Yuzu mayo',c:'#f2dd6c',h:0}],
 T:[{id:'ses',n:'Sesame + scallion',t:['sesame','scallion'],c:'#fff8e8',d:0},{id:'oni',n:'Crispy onions',t:['onion','sesame'],c:'#e8b24c',d:0},{id:'chs',n:'Melty cheese (+$.50)',t:['cheese','scallion'],c:'#ffc72c',d:.5},{id:'cil',n:'Cilantro + lime',t:['cilantro','sesame'],c:'#2f8f3a',d:0}]
};
const sel={P:0,K:1,S:0,T:0};
const GID={P:'gP',K:'gK',S:'gS',T:'gT'};
Object.keys(OPT).forEach(k=>{$('#'+GID[k]).innerHTML=OPT[k].map((o,i)=>`<button class="chip" data-g="${k}" data-i="${i}" aria-pressed="${sel[k]===i}"><i style="background:${o.c}"></i>${o.n}</button>`).join('')});
function cur(){const p=OPT.P[sel.P],k=OPT.K[sel.K],s=OPT.S[sel.S],t=OPT.T[sel.T];
  const price=5+p.d+t.d;const heat=Math.min(5,Math.max(1,Math.round((k.h*2+s.h+(p.id==='pork'?1.5:0))/2.2)));
  const name=`${k.adj} ${p.s||p.n}`;
  const o={meat:p.c,base:p.id==='tofu'?'#8fd16a':'#9bd873',kimchi:k.c,sauce:s.c,top:t.t};
  if(k.id==='fire'){o.shell='#3b2a24';o.shellD='#1f1411'}
  return{p,k,s,t,price,heat,name,o}}
function renderBuild(anim){
  const c=cur();
  $$('.chip').forEach(b=>b.setAttribute('aria-pressed',sel[b.dataset.g]===+b.dataset.i));
  $('#prevArt').innerHTML=taco(c.o);
  if(anim){const sv=$('#prevArt svg');sv.classList.add('wob')}
  $('#prevName').textContent=`The ${c.name}`;
  $('#prevSub').textContent=`${c.p.n} · ${c.k.n} kimchi · ${c.s.n} · ${c.t.n.replace(' (+$.50)','')}`;
  $('#prevHeat').innerHTML=heatHTML(c.heat);
  $('#prevPrice').textContent=money(c.price);
}
$('#build').addEventListener('click',e=>{const b=e.target.closest('.chip');if(!b)return;sel[b.dataset.g]=+b.dataset.i;renderBuild(true)});
$('#rand').onclick=()=>{Object.keys(sel).forEach(k=>sel[k]=Math.floor(Math.random()*OPT[k].length));renderBuild(true)};
$('#prevAdd').onclick=()=>{const c=cur();addItem({id:'c-'+c.p.id+c.k.id+c.s.id+c.t.id,name:`The ${c.name}`,price:c.price,cat:'tacos',note:'custom'})};
renderBuild(false);

/* ---------- SCHEDULE / STATUS / MAP ---------- */
// Edit these stops to match your real schedule. d = getDay() (0 = Sunday). Times are 24h decimals.
const SCHEDULE={
 0:{n:'Sunday',s:'Sun',place:'Westside Skate Park',addr:'1420 W Marlow Ave',from:12,to:20,xy:[95,215],note:'Chill vibes & late-lunch crowd'},
 1:{n:'Monday',s:'Mon',place:'Resting & fermenting',addr:'The Kimchi Kitchen (no pickup)',off:1,xy:[205,150],note:'Truck day off, kimchi is bubbling'},
 2:{n:'Tuesday',s:'Tue',place:'Market Square',addr:'100 Main St',from:11,to:15,xy:[185,95],note:'Lunch rush, order ahead!'},
 3:{n:'Wednesday',s:'Wed',place:'Riverside Brewery Yard',addr:'55 Riverfront Dr',from:17,to:22,xy:[305,205],note:'Pairs great with a cold one'},
 4:{n:'Thursday',s:'Thu',place:'Tech Campus Plaza',addr:'2200 Innovation Way',from:11.5,to:14.5,xy:[320,75],note:'Short window, long line'},
 5:{n:'Friday',s:'Fri',place:'Old Town Night Market',addr:'Lantern Alley & 3rd',from:18,to:23.5,xy:[120,125],note:'Open late, party mode'},
 6:{n:'Saturday',s:'Sat',place:'Sunset Park Farmers Market',addr:'800 Sunset Blvd',from:10,to:16,xy:[85,70],note:'Grand-opening spot!'}
};
const ORDER=[1,2,3,4,5,6,0];
const fmt=h=>{const H=Math.floor(h),M=Math.round((h-H)*60),ap=H>=12&&H<24?'pm':'am';return `${(H%12)||12}${M?':'+String(M).padStart(2,'0'):''}${ap}`};
const hrs=d=>d.off?'Closed':`${fmt(d.from)} – ${fmt(d.to)}`;
const now=new Date(),today=now.getDay(),hNow=now.getHours()+now.getMinutes()/60;
(function status(){
  const d=SCHEDULE[today],el=$('#status'),tx=$('#statusTxt');
  if(!d.off&&hNow>=d.from&&hNow<d.to){el.classList.add('open');tx.innerHTML=`<b>Open now</b> · ${d.place} · until ${fmt(d.to)}`;return}
  if(!d.off&&hNow<d.from){el.classList.add('soon');tx.innerHTML=`<b>Today</b> · ${d.place} · opens ${fmt(d.from)}`;return}
  for(let k=1;k<=7;k++){const dd=SCHEDULE[(today+k)%7];if(!dd.off){el.classList.add('soon');tx.innerHTML=`<b>Next stop:</b> ${k===1?'Tomorrow':dd.n} · ${dd.place} · ${fmt(dd.from)}`;return}}
})();
$('#days').innerHTML=ORDER.map(k=>{const d=SCHEDULE[k];return `<button class="day ${k===today?'today':''} ${d.off?'off':''}" data-day="${k}" aria-pressed="false"><span class="d">${d.s}</span><span class="p">${d.place}</span><span class="t">${hrs(d)}</span></button>`}).join('');
function showDay(k){
  const d=SCHEDULE[k];
  $$('.day').forEach(b=>b.setAttribute('aria-pressed',+b.dataset.day===k));
  $('#pin').style.transform=`translate(${d.xy[0]}px,${d.xy[1]}px)`;
  $('#info').innerHTML=`<h3>${d.place}</h3><div class="addr">${d.addr}</div><div class="meta"><span>${d.n}</span><span>${hrs(d)}</span><span>${d.note}</span></div>`;
}
$('#days').addEventListener('click',e=>{const b=e.target.closest('.day');if(b)showDay(+b.dataset.day)});
showDay(today);

/* ---------- COUNTDOWN ---------- */
function nextOpening(){const d=new Date();d.setHours(10,0,0,0);let add=(6-d.getDay()+7)%7;d.setDate(d.getDate()+add);if(d<=new Date())d.setDate(d.getDate()+7);return d}
const target=nextOpening();
function tick(){let s=Math.max(0,Math.floor((target-new Date())/1000));
  const D=Math.floor(s/86400);s%=86400;const H=Math.floor(s/3600);s%=3600;const M=Math.floor(s/60);s%=60;
  $('#cd').textContent=D;$('#ch').textContent=String(H).padStart(2,'0');$('#cm').textContent=String(M).padStart(2,'0');$('#cs').textContent=String(s).padStart(2,'0')}
tick();setInterval(tick,1000);

/* ---------- DECOR ---------- */
// marquee
(function(){const words=['Bulgogi','Kimchi','Gochujang','Crispy chicken','Sesame','Spicy pork','Fire','Short rib','Scallion','Loco'];
  const one=words.map(w=>`<span>${w}<i></i></span>`).join('');$('#track').innerHTML=one+one+one+one})();
// hero tacos
$('#ft1').innerHTML=taco(MENU.tacos[0].t);$('#ft2').innerHTML=taco(MENU.tacos[5].t);
// string lights
(function(){
  const cols=['#ffc72c','#ff5a3c','#ffe7bd','#ff7a90','#7cf0a0'];let w='M0 8',b='';
  for(let s=0;s<4;s++){w+=` Q${s*300+150} 50 ${s*300+300} 8`;
    for(let j=1;j<=4;j++){const t=j/5,x=s*300+300*t,y=(1-t)*(1-t)*8+2*(1-t)*t*50+t*t*8;
      b+=`<span class="bulb" style="left:${x/12}%;top:${y+2}px;background:${cols[(s*4+j)%5]};color:${cols[(s*4+j)%5]};animation-delay:${((s*4+j)*.37)%2.4}s"></span>`}}
  $('#wire').innerHTML=`<path d="${w}" fill="none" stroke="#000" stroke-width="2" vector-effect="non-scaling-stroke" opacity=".6"/>`;
  $('#lights').insertAdjacentHTML('beforeend',b);
})();
// confetti
(function(){const c=['#ffc72c','#fff3dc','#1a0f0c','#ff7a90'];let h='';
  for(let i=0;i<22;i++)h+=`<span class="conf" style="left:${(i*4.7+3)%100}%;top:${-(i*37)%60}px;background:${c[i%4]};border-radius:${i%3?'2px':'50%'};animation-duration:${6+(i%5)*1.7}s;animation-delay:${-(i%7)*1.3}s;width:${8+i%3*4}px;height:${8+i%4*3}px"></span>`;
  $('#opening').insertAdjacentHTML('afterbegin',h)})();
// forms
function formDone(id,msg){$(id).addEventListener('submit',e=>{e.preventDefault();e.target.outerHTML=`<div class="thanks">${msg}</div>`})}
formDone('#f1',"You're on the list! Watch your phone for the next drop. 🌶");
formDone('#f2',"Got it! We'll email your quote within 24 hours. Save us a spot near the cake.");
// reveal on scroll
if('IntersectionObserver' in window){
  const io=new IntersectionObserver(es=>es.forEach(en=>{if(en.isIntersecting){en.target.classList.add('in');io.unobserve(en.target)}}),{threshold:.12});
  $$('.reveal').forEach(el=>io.observe(el));
}else $$('.reveal').forEach(el=>el.classList.add('in'));
</script>
</body>
</html>
Reasoning trace (13,419 tokens)
I'm planning a single-file website for the Kimchi Loco taco truck, built only from inline SVG and CSS so it needs no outside resources or images. I'm sketching a bold gochujang red-orange palette for the design.

I'm settling the rest of the palette and typography, with heavy system fonts and a fallback to Arial Black. Next I'm laying out the page sections: a sticky nav, a hero with an animated taco and a live open-now badge, a marquee strip, a filterable menu with a cart, a taco builder, and a weekly schedule that's just starting to take shape.

Still writing the taco SVG code...

Still writing the taco SVG code...

Still writing the taco SVG code...

Still writing taco SVG...

Now I'm listing the menu items with their prices and heat levels, plus the side dishes and drinks. Next I'm working out how to draw the sides and drinks without relying on emoji.

I'm weighing how to draw the side dishes and drinks without emoji, since they might render as empty boxes on systems without the right fonts. I'm leaning toward simple inline SVG icons for fries, dumplings, and cups instead, and I'm keeping any Hangul decoration minimal in case Korean fonts are missing.

I'm drawing simple inline SVG icons for the sides and drinks, like fries, a dumpling, a corn cup, and a drink cup, through one generic function. Next I'm working on the cart, which tracks the item count and total in a drawer and shows a simulated pickup confirmation with an order number and an 8-minute ready time. For the truck status, I'm setting up a weekly schedule with start and end hours, Monday closed for kimchi prep, Tuesday at the downtown market, Wednesday at the riverside brewery yard, and Thursday at the tech campus plaza, so the badge can compute whether it's open now.

Still writing the weekday schedule and the hours for each stop...

I'm picking the truck for the hero's right side, floating a taco beside it, and putting a giant taco in the builder section. The truck will drive in on load with spinning wheels, and I'm going dark charcoal for the hero with hot red and yellow neon accents, with the cream sections alternating below.

Still writing the CSS font stack and the builder options for the taco.

I'm assigning colors to each taco component: beef, pork, chicken, and tofu for the protein, mild, classic, and fire levels for the kimchi, crema, ssamjang, and yuzu for the sauce, plus sesame, crispy onion, and cheese as toppers.

Next I'm planning the tasting feedback copy and a "Loco Pass" email signup that just shows a thank-you without any network call. I'm also setting up a grand opening banner with a countdown to the next Saturday at 10:00, so it always points to a future date.

Next I'm setting up the CSS color variables and the nav with a small inline SVG logo, plus the hero markup with a status line and the headline.

Still writing the hero markup and the marquee strip.

Still writing the truck SVG...

Still writing the truck SVG...

Still writing the truck's sign, awning, and window details...

Still writing the truck SVG...

Still writing the menu cards and the chili rating icons...

Still writing the chili icon path and the cart state, which maps each item to its name, price, and quantity.

Now I'm working out the builder section, a yellow panel with a large taco preview, the name, the price, and an add button on the left, and option chips on the right. The taco's name will come from the protein and the kimchi heat level, and the price will start at a base and add the protein's cost.

Now I'm working out the find-us section, with a weekly schedule on the left where clicking a day updates a stylized map and details card on the right. The grand opening countdown band will sit between the builder and find-us sections, and I'm adding a few tilted review cards at the end.

Next I'm finishing the footer with the logo, handle, and tagline, and adding mobile rules so the nav collapses under 720px and the hero stacks. Then I'll start the JavaScript, beginning with a taco-drawing function that builds the SVG from shell, meat, veg, sauce, and topping options.

Still writing the taco SVG...

Still working out the taco's fillings, with cabbage and meat chunks layered above the shell and a sauce drizzle on top.

Still writing the taco SVG...

Still writing the taco SVG...

Still writing the SVG drawing code for the sides...

Still writing the side dish and drink icons...

Still writing the menu entries, with the taco descriptions and prices.

Still writing the menu prices, with the tacos, sides, and drinks listed.

Still writing the Taco Trio discount and the tray logic.

Next I'm mapping out the weekly schedule: Sunday at the Westside Skate Park, Monday closed, Tuesday at Market Square, Wednesday at the Riverside Brewery Yard, Thursday at the Tech Campus Plaza, Friday at the Old Town Night Market, and Saturday at the Sunset Park Farmers Market, each with its hours.

Still writing the status logic and the map SVG with its pin and transitions.

Still writing the hero's CSS and the reveal animation, which uses an IntersectionObserver so sections fade up as they scroll in. Next I'm setting up the countdown to the next Saturday at 10:00, the details card under the map, and a simple text-and-chili logo styled in CSS.

Now I'm writing the hero's headline and subtitle copy, with the second line glowing yellow and two call-to-action buttons. The hero will be a two-column grid that stacks on smaller screens, and I'm adding a string of light bulbs across the top edge.

Now I'm working out the string lights along the top of the hero: a wire drawn as a sagging curve, with the bulbs placed at the low points of that curve.

Still working out the string lights along the top of the hero, placing the bulbs at points along a sagging curve drawn as a series of quadratic segments.

Next I'm sketching the taco's builder options: proteins like bulgogi, spicy pork, crispy chicken, tofu, and galbi rib, each with a color and a price adjustment, plus kimchi heat levels from mild napa to classic.

Still working out the builder's option data: sauces like gochujang crema, ssamjang, and yuzu mayo, plus toppers like sesame, scallion, and cilantro. I'm also setting how a taco's name and price get built from the protein and kimchi choices.

Still writing the taco SVG and its shell shading.

Still writing the taco SVG, with the base leaves drawn as a row of rotated ellipses under the shell.

Still writing the taco SVG, with the meat chunks and a darker char spot on each piece.

Still writing the taco's toppings, placing sesame, scallion, cilantro, onion, and cheese bits across the filling.

Still writing the taco SVG, with the shell drawn as a front path with a rim and a fold shading, plus a darker back shell and a shadow beneath it.

Still writing the side dish SVGs, starting with the fries box and its toppings.

Still writing the side dish SVGs, with the mandu dumplings and corn cup next.

Still writing the cup SVGs, with lids, straws, and ice cubes, plus the card backgrounds. Next I'm laying out the tray drawer's markup.

I'm wiring up the tray: a drawer with a body, a footer, and a close button, plus a scrim behind it. Adding to the cart will go through event delegation on the add buttons, looking up items by id, including the custom builder taco.

Still writing the map SVG, with the river, park, and street grid, and placing each day's pin at its own spot.

Still writing the map pins, with a bouncing teardrop marker and a pulsing ring, and setting its position through a transform transition.

Last bit of the page setup: I'm making sure the body doesn't scroll sideways, then I'm moving on to the code.