Food truck websiteOne-line
DeepSeek V4.1 Flash 1017
by DeepSeekReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 2 min 14 s
- Cost
- $0.018
- Output tokens
- 37,049
- Spent thinking
- 22,377 tokens
- Speed
- 278.1 tok/s
- Console errors
- 0
- First token after
- 323 ms
- First visible text after
- 1 min 28 s
- Prompt tokens
- 389
- Code size
- 42.8 KB
- Finish reason
- stop
- Served by
- Ionstream
- Model id
deepseek/deepseek-v4.1-flash-1017- Reasoning sent
{"effort":"max"}- Max output
- 64,000 tokens
- Generated
- Nov 11, 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 · 903 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 Tacos, Los Angeles</title>
<style>
/* ============ BASE ============ */
:root{
--ink:#17100E;
--ink-2:#241814;
--cream:#FFF4E3;
--cream-2:#F8E7CE;
--red:#E5322B;
--red-d:#B31217;
--gold:#FFB03B;
--lime:#C8F04A;
--green:#5F8D3E;
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
margin:0;background:var(--cream);color:var(--ink);
font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;
font-size:17px;line-height:1.55;overflow-x:hidden;
-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
body::after{
content:"";position:fixed;inset:0;z-index:9998;pointer-events:none;opacity:.045;
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
::selection{background:var(--red);color:#fff}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit}
h1,h2,h3,h4{
margin:0;font-family:"Arial Black","Helvetica Neue",Helvetica,Arial,sans-serif;
font-weight:900;letter-spacing:-.038em;line-height:.88;text-transform:uppercase;
}
p{margin:0}
ul{margin:0;padding:0;list-style:none}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.wrap{width:100%;max-width:1240px;margin:0 auto;padding:0 clamp(18px,4vw,40px)}
/* ============ BUTTONS ============ */
.btn{
display:inline-flex;align-items:center;justify-content:center;gap:9px;
padding:14px 22px;border-radius:999px;border:2.5px solid var(--ink);
background:var(--cream);color:var(--ink);
font-weight:800;font-size:13px;letter-spacing:.06em;text-transform:uppercase;
cursor:pointer;box-shadow:4px 4px 0 var(--ink);
transition:transform .15s ease,box-shadow .15s ease,background .15s ease;
white-space:nowrap;
}
.btn:hover{transform:translate(-2px,-2px);box-shadow:6px 6px 0 var(--ink)}
.btn:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--ink)}
.btn-primary{background:var(--red);color:#fff}
.btn-lime{background:var(--lime)}
.btn-ink{background:var(--ink);color:var(--cream)}
.btn-outline{background:transparent}
.btn-sm{padding:10px 17px;font-size:11.5px;box-shadow:3px 3px 0 var(--ink)}
.btn-lg{padding:18px 30px;font-size:15px}
/* ============ NAV ============ */
.nav{
position:sticky;top:0;z-index:60;display:flex;align-items:center;gap:22px;
padding:11px clamp(16px,3.5vw,36px);
background:rgba(255,244,227,.9);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
border-bottom:2.5px solid var(--ink);
}
.brand{display:flex;align-items:center;gap:11px;margin-right:auto}
.brand .mark{width:40px;height:40px;flex:none;transition:transform .5s cubic-bezier(.34,1.56,.64,1)}
.brand:hover .mark{transform:rotate(-14deg) scale(1.06)}
.brand b{display:block;font-family:"Arial Black",Helvetica,Arial,sans-serif;font-size:16px;letter-spacing:-.02em;text-transform:uppercase;line-height:1}
.brand i{display:block;font-style:normal;font-size:9.5px;letter-spacing:.19em;text-transform:uppercase;opacity:.55;margin-top:4px;font-weight:700}
.nav-links{display:flex;gap:26px;font-size:12px;font-weight:800;letter-spacing:.11em;text-transform:uppercase}
.nav-links a{position:relative;padding:4px 0}
.nav-links a::after{content:"";position:absolute;left:0;bottom:0;width:0;height:2.5px;background:var(--red);transition:width .25s ease}
.nav-links a:hover::after{width:100%}
@media(max-width:780px){.nav-links{display:none}}
/* ============ HERO ============ */
.hero{position:relative;overflow:hidden;padding:clamp(26px,4vw,50px) 0 clamp(30px,5vw,64px)}
.hero-inner{
display:grid;grid-template-columns:1.02fr .98fr;gap:clamp(16px,3vw,40px);
align-items:center;max-width:1240px;margin:0 auto;padding:0 clamp(18px,4vw,40px);
}
.pill{
display:inline-flex;align-items:center;gap:9px;padding:8px 15px 8px 12px;
border:2.5px solid var(--ink);border-radius:999px;background:#fff;
font-size:11.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
box-shadow:3px 3px 0 var(--ink);line-height:1.2;
}
.dot{width:9px;height:9px;flex:none;border-radius:50%;background:#2BB673;animation:pulse 2.2s infinite}
.dot.closed{background:var(--red);animation:none}
@keyframes pulse{
0%{box-shadow:0 0 0 0 rgba(43,182,115,.55)}
70%{box-shadow:0 0 0 9px rgba(43,182,115,0)}
100%{box-shadow:0 0 0 0 rgba(43,182,115,0)}
}
.hero h1{
font-size:clamp(44px,8.2vw,104px);line-height:.85;letter-spacing:-.048em;
margin:18px 0 0;
}
.hero h1 .hl{color:var(--red);text-shadow:5px 5px 0 rgba(23,16,14,.1)}
.lede{
margin-top:20px;max-width:40ch;font-size:clamp(15px,1.3vw,17.5px);
font-weight:500;color:#4A3830;line-height:1.5;
}
.hero-cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:24px}
.hero-meta{
display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:26px;
font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;font-weight:800;color:#6B5346;
}
.hero-meta b{color:var(--ink)}
.stars{color:var(--gold);letter-spacing:1px;font-size:14px;-webkit-text-stroke:.6px var(--ink)}
.meta-sep{width:1px;height:14px;background:rgba(23,16,14,.25)}
#rotator{display:inline-block;min-width:150px;color:var(--red);transition:opacity .25s ease}
#rotator.fade{opacity:0}
/* --- hero art --- */
.hero-art{position:relative;display:grid;place-items:center;isolation:isolate}
.glow{
position:absolute;width:118%;aspect-ratio:1;border-radius:50%;z-index:-1;
background:radial-gradient(circle,rgba(255,176,59,.55) 0%,rgba(255,120,70,.22) 42%,rgba(255,120,70,0) 68%);
filter:blur(6px);
}
.taco-float{width:min(100%,520px);animation:floaty 7s ease-in-out infinite}
@keyframes floaty{0%,100%{transform:translateY(-7px) rotate(-1deg)}50%{transform:translateY(9px) rotate(1.4deg)}}
.taco{width:100%;height:auto;filter:drop-shadow(0 26px 34px rgba(150,60,25,.28))}
.sticker{
position:absolute;top:4%;right:2%;width:104px;height:104px;border-radius:50%;
background:var(--lime);border:3px solid var(--ink);box-shadow:5px 5px 0 var(--ink);
display:grid;place-items:center;text-align:center;transform:rotate(-13deg);
font-family:"Arial Black",Helvetica,Arial,sans-serif;font-size:12px;line-height:1.05;
letter-spacing:-.02em;text-transform:uppercase;padding:8px;
animation:stickerSpin 1s ease-out both;
}
@keyframes stickerSpin{from{transform:rotate(-13deg) scale(.4);opacity:0}to{transform:rotate(-13deg) scale(1);opacity:1}}
.fl{position:absolute;pointer-events:none}
.fl-chili{width:56px;left:-2%;top:12%;transform:rotate(-16deg);animation:floaty 6s ease-in-out infinite reverse}
.fl-lime{width:78px;right:2%;bottom:6%;transform:rotate(10deg);animation:floaty 5.4s ease-in-out infinite}
.fl-leaf{width:52px;right:6%;top:16%;transform:rotate(24deg);animation:floaty 8s ease-in-out infinite}
@media(max-width:900px){
.hero-inner{grid-template-columns:1fr}
.hero-art{max-width:400px;margin:6px auto 0;width:100%}
.fl-chili{width:44px;left:-2%}
.fl-lime{width:58px}
.fl-leaf{width:40px;right:0}
.sticker{width:86px;height:86px;font-size:10.5px;top:0;right:0}
}
/* ============ TICKER ============ */
.ticker-wrap{overflow:hidden;padding:22px 0 30px;margin:6px 0 0}
.ticker{
transform:rotate(-1.4deg);width:106%;margin-left:-3%;
background:var(--red);border-top:3px solid var(--ink);border-bottom:3px solid var(--ink);
padding:12px 0;overflow:hidden;
}
.ticker-anim{display:flex;width:max-content;animation:marquee 38s linear infinite}
.ticker-track{
display:flex;align-items:center;gap:26px;padding-right:26px;white-space:nowrap;
color:#fff;font-weight:900;font-size:14px;letter-spacing:.13em;text-transform:uppercase;
}
.ticker-track i{color:var(--gold);font-style:normal;font-size:15px}
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
/* ============ SECTION HEADS ============ */
.section{padding:clamp(46px,7vw,100px) 0}
.sec-head{display:flex;flex-wrap:wrap;align-items:flex-end;gap:14px 26px;margin-bottom:clamp(26px,4vw,44px)}
.sec-num{
font-family:"Arial Black",Helvetica,Arial,sans-serif;font-size:13px;letter-spacing:.1em;
border:2.5px solid var(--ink);border-radius:8px;padding:5px 9px;background:var(--gold);
box-shadow:3px 3px 0 var(--ink);transform:translateY(-6px);
}
.sec-head h2{font-size:clamp(34px,5.2vw,62px);flex:none}
.sec-sub{max-width:38ch;font-size:15px;color:#5A4438;font-weight:500;margin-left:auto;line-height:1.45}
@media(max-width:760px){.sec-sub{margin-left:0;max-width:100%}}
/* ============ MENU ============ */
.menu-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,2vw,22px)}
@media(max-width:1000px){.menu-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.menu-grid{grid-template-columns:1fr}}
.card{
position:relative;display:flex;flex-direction:column;gap:10px;
background:#fff;border:2.5px solid var(--ink);border-radius:20px;
padding:20px 20px 18px;box-shadow:5px 5px 0 var(--ink);
transition:transform .2s ease,box-shadow .2s ease,background .2s ease;
}
.card:hover{transform:translate(-4px,-4px);box-shadow:11px 11px 0 var(--ink);background:var(--cream)}
.card-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.card-idx{font-size:11px;font-weight:900;letter-spacing:.16em;color:#9A8274}
.tag{
font-size:9.5px;font-weight:900;letter-spacing:.11em;text-transform:uppercase;
padding:4px 8px;border-radius:6px;border:2px solid var(--ink);background:var(--cream-2);
}
.tag-hot{background:var(--lime)}
.tag-new{background:var(--gold)}
.card h3{font-size:clamp(19px,1.9vw,23px);line-height:1.02;letter-spacing:-.03em}
.card p{font-size:13.5px;line-height:1.45;color:#5A4438;font-weight:500}
.card-foot{display:flex;align-items:center;justify-content:space-between;margin-top:auto;padding-top:8px}
.price{font-family:"Arial Black",Helvetica,Arial,sans-serif;font-size:22px;letter-spacing:-.03em}
.price small{font-size:12px;opacity:.45;font-weight:700}
.spice{display:flex;gap:4px;align-items:center}
.spice i{width:8px;height:8px;border-radius:50%;border:1.6px solid var(--ink);background:transparent}
.spice i.on{background:var(--red)}
.menu-note{
margin-top:26px;font-size:12.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
color:#7A6154;display:flex;align-items:center;gap:10px;flex-wrap:wrap;
}
.menu-note::before{content:"";width:26px;height:3px;background:var(--red);border-radius:2px}
/* ============ FIND ============ */
.find{background:var(--ink);color:var(--cream);position:relative;overflow:hidden}
.find .sec-num{background:var(--red);color:#fff;border-color:var(--cream)}
.find .sec-head h2{color:var(--cream)}
.find .sec-sub{color:#BBA79A}
.find-grid{display:grid;grid-template-columns:1.02fr 1fr;gap:clamp(18px,3vw,34px);align-items:start}
@media(max-width:860px){.find-grid{grid-template-columns:1fr}}
.today-card{
background:var(--lime);color:var(--ink);border:3px solid var(--ink);border-radius:22px;
padding:clamp(20px,3vw,30px);box-shadow:9px 9px 0 var(--red);position:relative;
}
.today-card .status{
display:inline-flex;align-items:center;gap:9px;background:#fff;border:2.5px solid var(--ink);
border-radius:999px;padding:7px 14px;font-size:11.5px;font-weight:900;
letter-spacing:.07em;text-transform:uppercase;box-shadow:3px 3px 0 var(--ink);
}
.today-card h3{font-size:clamp(30px,4.4vw,46px);margin:18px 0 6px;line-height:.94}
.today-card .addr{font-size:14.5px;font-weight:700;color:#38401F;letter-spacing:.01em}
.today-card .hours{
margin-top:16px;display:flex;flex-wrap:wrap;gap:8px 20px;font-size:12.5px;
font-weight:900;letter-spacing:.08em;text-transform:uppercase;
}
.today-card .hours span{display:flex;align-items:center;gap:7px}
.today-card .hours b{font-size:14px}
.today-card .btn{margin-top:20px;box-shadow:4px 4px 0 var(--ink)}
.sched-head{
display:flex;align-items:center;justify-content:space-between;
font-size:11px;font-weight:900;letter-spacing:.16em;text-transform:uppercase;color:#B39B8C;
padding:0 4px 12px;border-bottom:2px solid rgba(255,244,227,.16);margin-bottom:4px;
}
.sched li{
display:grid;grid-template-columns:44px 1fr auto;align-items:center;gap:14px;
padding:13px 12px;border-radius:12px;border-bottom:1px solid rgba(255,244,227,.09);
transition:background .2s ease;
}
.sched li:last-child{border-bottom:0}
.sched li:hover{background:rgba(255,244,227,.06)}
.s-day{font-family:"Arial Black",Helvetica,Arial,sans-serif;font-size:12px;letter-spacing:.06em;color:#9C8578;text-transform:uppercase}
.s-place{font-weight:800;font-size:14.5px;letter-spacing:-.01em;display:flex;flex-direction:column;line-height:1.25}
.s-place em{font-style:normal;font-size:11.5px;font-weight:600;color:#9C8578;letter-spacing:.02em;margin-top:2px}
.s-hrs{font-size:11.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#C9B4A6;white-space:nowrap}
.sched li.is-today{background:var(--red);border-bottom-color:transparent;box-shadow:0 6px 0 rgba(0,0,0,.25)}
.sched li.is-today .s-day,.sched li.is-today .s-hrs{color:rgba(255,255,255,.82)}
.sched li.is-today .s-place{color:#fff}
.sched li.is-today .s-place em{color:rgba(255,255,255,.75)}
@media(max-width:460px){.s-place em{display:none}.sched li{grid-template-columns:38px 1fr auto;gap:10px;padding:12px 8px}}
/* ============ STORY ============ */
.story-grid{display:grid;grid-template-columns:.95fr 1.05fr;gap:clamp(24px,5vw,64px);align-items:start}
@media(max-width:880px){.story-grid{grid-template-columns:1fr}}
.kicker{
display:inline-block;font-size:11px;font-weight:900;letter-spacing:.2em;text-transform:uppercase;
color:var(--red);border-bottom:3px solid var(--red);padding-bottom:5px;
}
.story h2{font-size:clamp(32px,4.8vw,58px);margin-top:18px;line-height:.9}
.story h2 .hl{color:var(--red)}
.story-right p{font-size:15.5px;line-height:1.65;color:#4A3830;margin-bottom:16px}
.story-right .lead{font-size:17px;font-weight:600;color:var(--ink)}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:26px;padding-top:22px;border-top:2.5px solid rgba(23,16,14,.16)}
.stats b{
display:block;font-family:"Arial Black",Helvetica,Arial,sans-serif;font-size:clamp(26px,3.4vw,38px);
letter-spacing:-.04em;line-height:1;color:var(--red);
}
.stats span{display:block;font-size:10.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:#6B5346;margin-top:6px;line-height:1.3}
/* ============ CTA ============ */
.cta{
background:var(--red);color:var(--cream);position:relative;overflow:hidden;
border-top:3px solid var(--ink);border-bottom:3px solid var(--ink);
padding:clamp(48px,7vw,92px) 0;text-align:center;
}
.cta::before{
content:"";position:absolute;inset:-40% -10% auto;height:120%;z-index:0;
background:radial-gradient(circle at 50% 0%,rgba(255,176,59,.45),transparent 62%);
}
.cta .wrap{position:relative;z-index:1}
.cta h2{font-size:clamp(38px,7vw,84px);line-height:.86;letter-spacing:-.045em;color:#fff}
.cta h2 .hl{color:var(--gold)}
.cta-sub{max-width:52ch;margin:20px auto 0;font-size:15.5px;line-height:1.55;color:rgba(255,244,227,.93);font-weight:500}
.cta-actions{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-top:28px}
.signup{
display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin:34px auto 0;max-width:560px;
}
.signup input{
flex:1 1 240px;min-width:0;padding:15px 18px;border-radius:999px;border:2.5px solid var(--ink);
background:#fff;color:var(--ink);font-size:15px;font-weight:600;outline:none;
box-shadow:4px 4px 0 var(--ink);
}
.signup input::placeholder{color:#A08A7C;font-weight:600}
.signup input:focus{background:#FFF9F0}
.form-msg{
flex-basis:100%;font-size:12.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
color:#FFE6A8;min-height:18px;transition:opacity .3s;
}
.fine{margin-top:18px;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:rgba(255,244,227,.6);font-weight:800}
/* ============ FOOTER ============ */
footer{background:var(--ink);color:#C9B4A6;padding:44px 0 34px}
.foot-top{display:flex;flex-wrap:wrap;gap:26px;align-items:flex-start;justify-content:space-between;padding-bottom:26px;border-bottom:1px solid rgba(255,244,227,.13)}
.foot-brand{display:flex;align-items:center;gap:11px;color:var(--cream)}
.foot-brand .mark{width:38px;height:38px}
.foot-brand b{display:block;font-family:"Arial Black",Helvetica,Arial,sans-serif;font-size:15px;letter-spacing:-.01em;text-transform:uppercase;line-height:1}
.foot-brand i{display:block;font-style:normal;font-size:9.5px;letter-spacing:.19em;text-transform:uppercase;opacity:.55;margin-top:4px;font-weight:700}
.foot-links{display:flex;gap:22px;flex-wrap:wrap;font-size:11.5px;font-weight:800;letter-spacing:.11em;text-transform:uppercase}
.foot-links a{color:#C9B4A6;transition:color .2s}
.foot-links a:hover{color:var(--lime)}
.foot-bottom{display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between;padding-top:20px;font-size:11px;letter-spacing:.06em;color:#7A655A;font-weight:600}
/* ============ TOAST ============ */
.toast{
position:fixed;left:50%;bottom:24px;transform:translate(-50%,24px);
background:var(--ink);color:var(--cream);border:2.5px solid var(--cream);
padding:13px 22px;border-radius:14px;font-size:13.5px;font-weight:800;
letter-spacing:.04em;z-index:10000;opacity:0;pointer-events:none;
transition:opacity .3s ease,transform .3s ease;max-width:88vw;text-align:center;
box-shadow:0 14px 40px rgba(0,0,0,.35);
}
.toast.show{opacity:1;transform:translate(-50%,0)}
/* ============ REVEAL ============ */
.reveal{opacity:0;transform:translateY(26px);transition:opacity .7s cubic-bezier(.2,.7,.3,1),transform .7s cubic-bezier(.2,.7,.3,1)}
.reveal.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
*,*::before,*::after{animation-duration:.001s!important;animation-iteration-count:1!important;transition-duration:.001s!important}
.reveal{opacity:1;transform:none}
html{scroll-behavior:auto}
}
</style>
</head>
<body>
<!-- ================= NAV ================= -->
<header class="nav">
<a class="brand" href="#top" aria-label="Kimchi Loco home">
<svg class="mark" viewBox="0 0 40 40" aria-hidden="true">
<circle cx="20" cy="20" r="19" fill="#E5322B" stroke="#17100E" stroke-width="2.5"/>
<path d="M9 24a11 11 0 0 1 22 0z" fill="#FFB03B" stroke="#17100E" stroke-width="2"/>
<path d="M12 22c2-4 5-5 8-4s4-4 8-3" fill="none" stroke="#7BB04A" stroke-width="3" stroke-linecap="round"/>
<circle cx="16" cy="18" r="2.1" fill="#FFF4E3"/>
<circle cx="24" cy="16.5" r="1.8" fill="#FFF4E3"/>
</svg>
<span class="brand-text">
<b>Kimchi Loco</b>
<i>Korean Tacos · Los Angeles</i>
</span>
</a>
<nav class="nav-links">
<a href="#menu">Menu</a>
<a href="#find">Find Us</a>
<a href="#story">Story</a>
</nav>
<a class="btn btn-sm btn-primary" href="#find">Find the truck</a>
</header>
<main id="top">
<!-- ================= HERO ================= -->
<section class="hero">
<div class="hero-inner">
<div class="hero-copy">
<div class="pill">
<span class="dot" id="heroDot"></span>
<span id="heroStatus">Open now · Silver Lake · till 9pm</span>
</div>
<h1>Korean<br>Mexican<br><span class="hl">Loco.</span></h1>
<p class="lede">
Gochujang-slapped tacos, twelve-hour bulgogi, and kimchi that bites back.
We're a truck. We're loud. We sell out by eight.
</p>
<div class="hero-cta">
<a class="btn btn-primary" href="#menu">See the menu</a>
<a class="btn" href="#find">Find the truck →</a>
</div>
<div class="hero-meta">
<span class="stars" aria-hidden="true">★★★★★</span>
<span><b>4.9</b> · 1,284 reviews</span>
<span class="meta-sep" aria-hidden="true"></span>
<span>Now serving <b id="rotator">Gochujang Bulgogi</b></span>
</div>
</div>
<div class="hero-art" id="heroArt">
<div class="glow" aria-hidden="true"></div>
<div class="taco-float">
<svg class="taco" viewBox="0 0 420 400" role="img" aria-label="Illustration of a Korean taco loaded with bulgogi, kimchi and crema">
<defs>
<radialGradient id="tGlow" cx="50%" cy="55%" r="50%">
<stop offset="0%" stop-color="#FFD07A" stop-opacity=".9"/>
<stop offset="62%" stop-color="#FF9A4D" stop-opacity=".22"/>
<stop offset="100%" stop-color="#FF9A4D" stop-opacity="0"/>
</radialGradient>
<linearGradient id="tShell" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FFD98A"/>
<stop offset="42%" stop-color="#F7AE4A"/>
<stop offset="100%" stop-color="#C9711D"/>
</linearGradient>
<linearGradient id="tMeat" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#8F3D1F"/>
<stop offset="100%" stop-color="#4E1C0C"/>
</linearGradient>
<clipPath id="tShellClip">
<path d="M60 200 A150 150 0 0 0 360 200 Z"/>
</clipPath>
</defs>
<!-- glow -->
<circle cx="210" cy="240" r="185" fill="url(#tGlow)"/>
<!-- shadow -->
<ellipse cx="210" cy="368" rx="118" ry="15" fill="#17100E" opacity=".12"/>
<!-- ===== FILLINGS ===== -->
<path d="M62 202 C66 176 78 156 100 148 C104 128 124 112 146 118 C156 100 184 92 200 108 C216 92 246 96 256 116 C280 108 306 118 314 142 C336 150 350 172 352 202 Z" fill="#6EA23E"/>
<path d="M120 160 C130 138 152 132 168 146 C180 128 208 128 216 148 C236 140 252 152 254 172 C232 186 152 186 120 160 Z" fill="#87BC50"/>
<!-- kimchi -->
<g fill="#E5322B" stroke="#8E1610" stroke-width="1.6">
<rect x="128" y="136" width="38" height="21" rx="9" transform="rotate(-15 147 146)"/>
<rect x="196" y="118" width="42" height="21" rx="9" transform="rotate(11 217 128)"/>
<rect x="262" y="138" width="36" height="21" rx="9" transform="rotate(-8 280 148)"/>
</g>
<g fill="#FF7A6B" opacity=".85">
<rect x="137" y="140" width="16" height="6" rx="3" transform="rotate(-15 145 143)"/>
<rect x="205" y="122" width="16" height="6" rx="3" transform="rotate(11 213 125)"/>
<rect x="270" y="142" width="14" height="6" rx="3" transform="rotate(-8 277 145)"/>
</g>
<!-- bulgogi -->
<g fill="url(#tMeat)" stroke="#2E0E05" stroke-width="1.4" opacity=".98">
<rect x="110" y="160" width="56" height="25" rx="12" transform="rotate(-9 138 172)"/>
<rect x="168" y="146" width="62" height="25" rx="12" transform="rotate(6 199 158)"/>
<rect x="232" y="158" width="54" height="25" rx="12" transform="rotate(-7 259 170)"/>
<rect x="148" y="180" width="58" height="22" rx="11" transform="rotate(4 177 191)"/>
<rect x="224" y="182" width="56" height="22" rx="11" transform="rotate(-5 252 193)"/>
</g>
<!-- crema drizzle -->
<path d="M90 192 C112 168 134 198 156 180 C176 164 194 196 216 178 C236 162 252 192 274 174 C294 158 314 184 330 170"
fill="none" stroke="#FFF8EC" stroke-width="8.5" stroke-linecap="round" opacity=".96"/>
<!-- sesame -->
<g fill="#FFF0D2">
<ellipse cx="150" cy="152" rx="4.2" ry="2.6" transform="rotate(-22 150 152)"/>
<ellipse cx="206" cy="138" rx="4.2" ry="2.6" transform="rotate(18 206 138)"/>
<ellipse cx="248" cy="166" rx="4.2" ry="2.6" transform="rotate(-12 248 166)"/>
<ellipse cx="180" cy="176" rx="4.2" ry="2.6" transform="rotate(28 180 176)"/>
<ellipse cx="300" cy="160" rx="4.2" ry="2.6" transform="rotate(-30 300 160)"/>
<ellipse cx="112" cy="178" rx="4.2" ry="2.6" transform="rotate(14 112 178)"/>
</g>
<!-- ===== SHELL ===== -->
<path d="M60 200 A150 150 0 0 0 360 200 Z" fill="url(#tShell)" stroke="#8A4A12" stroke-width="3.5"/>
<g clip-path="url(#tShellClip)">
<ellipse cx="140" cy="248" rx="27" ry="17" fill="#B4611A" opacity=".32"/>
<ellipse cx="252" cy="278" rx="35" ry="19" fill="#B4611A" opacity=".28"/>
<ellipse cx="196" cy="322" rx="23" ry="13" fill="#B4611A" opacity=".26"/>
<ellipse cx="310" cy="238" rx="16" ry="11" fill="#B4611A" opacity=".22"/>
<path d="M112 232 C130 276 168 308 212 326" stroke="#FFE2A8" stroke-width="15" fill="none" opacity=".45" stroke-linecap="round"/>
<path d="M76 214 C82 244 92 268 108 288" stroke="#FFE2A8" stroke-width="9" fill="none" opacity=".3" stroke-linecap="round"/>
</g>
<path d="M60 200 A150 150 0 0 0 360 200" fill="none" stroke="#8A4A12" stroke-width="3.5"/>
</svg>
</div>
<div class="sticker" aria-hidden="true">Sold out<br>by 8pm</div>
<svg class="fl fl-chili" viewBox="0 0 60 100" aria-hidden="true">
<path d="M30 20 C46 32 50 62 34 84 C27 93 13 96 8 88 C22 82 34 64 34 46 C34 34 32 26 30 20 Z" fill="#E5322B" stroke="#17100E" stroke-width="4" stroke-linejoin="round"/>
<path d="M30 20 C26 12 16 9 8 13" fill="none" stroke="#5F8D3E" stroke-width="9" stroke-linecap="round"/>
</svg>
<svg class="fl fl-lime" viewBox="0 0 80 80" aria-hidden="true">
<circle cx="40" cy="40" r="30" fill="#C8F04A" stroke="#17100E" stroke-width="4"/>
<circle cx="40" cy="40" r="22" fill="#E9FFA8" stroke="#17100E" stroke-width="3"/>
<g stroke="#17100E" stroke-width="2.4" stroke-linecap="round">
<path d="M40 40V19M40 40v21M40 40H19M40 40h21M40 40 25.1 25.1M40 40l14.9 14.9M40 40l14.9-14.9M40 40 25.1 54.9"/>
</g>
</svg>
<svg class="fl fl-leaf" viewBox="0 0 60 60" aria-hidden="true">
<path d="M30 54 C30 40 12 36 8 20 C20 16 30 26 30 38 C30 26 40 16 52 20 C48 36 30 40 30 54Z" fill="#7BB04A" stroke="#17100E" stroke-width="3" stroke-linejoin="round"/>
</svg>
</div>
</div>
</section>
<!-- ================= TICKER ================= -->
<div class="ticker-wrap" aria-hidden="true">
<div class="ticker">
<div class="ticker-anim">
<div class="ticker-track">
<span>Gochujang everything</span><i>★</i>
<span>12-hour bulgogi</span><i>★</i>
<span>Kimchi that bites back</span><i>★</i>
<span>Sold out by 8</span><i>★</i>
<span>Corn tortillas, pressed to order</span><i>★</i>
</div>
<div class="ticker-track">
<span>Gochujang everything</span><i>★</i>
<span>12-hour bulgogi</span><i>★</i>
<span>Kimchi that bites back</span><i>★</i>
<span>Sold out by 8</span><i>★</i>
<span>Corn tortillas, pressed to order</span><i>★</i>
</div>
</div>
</div>
</div>
<!-- ================= MENU ================= -->
<section class="section" id="menu">
<div class="wrap">
<div class="sec-head reveal">
<span class="sec-num">01</span>
<h2>The Lineup</h2>
<p class="sec-sub">Six things. Made to order. Get here before the bulgogi runs out — that's not a marketing line, that's a Tuesday.</p>
</div>
<div class="menu-grid">
<article class="card reveal" style="transition-delay:.02s">
<div class="card-top"><span class="card-idx">01</span><span class="tag tag-hot">Fan favorite</span></div>
<h3>Seoul City Bulgogi</h3>
<p>Twelve-hour marinated ribeye, gochujang crema, pickled onion, cilantro, toasted sesame.</p>
<div class="card-foot">
<span class="price">$12</span>
<span class="spice" aria-label="Heat 2 of 4"><i class="on"></i><i class="on"></i><i></i><i></i></span>
</div>
</article>
<article class="card reveal" style="transition-delay:.08s">
<div class="card-top"><span class="card-idx">02</span></div>
<h3>Kimchi Crujiente</h3>
<p>Crispy pork belly, house kimchi, charred pineapple, cotija, a hard squeeze of lime.</p>
<div class="card-foot">
<span class="price">$11</span>
<span class="spice" aria-label="Heat 3 of 4"><i class="on"></i><i class="on"></i><i class="on"></i><i></i></span>
</div>
</article>
<article class="card reveal" style="transition-delay:.14s">
<div class="card-top"><span class="card-idx">03</span><span class="tag tag-new">New</span></div>
<h3>El Loco</h3>
<p>Gochujang-glazed short rib, avocado mash, pickled jalapeño, crispy shallot, salsa verde.</p>
<div class="card-foot">
<span class="price">$13</span>
<span class="spice" aria-label="Heat 2 of 4"><i class="on"></i><i class="on"></i><i></i><i></i></span>
</div>
</article>
<article class="card reveal" style="transition-delay:.02s">
<div class="card-top"><span class="card-idx">04</span></div>
<h3>K-Fried Chicken</h3>
<p>Double-fried thigh, soy-garlic glaze, sesame slaw, sriracha crema. Napkins are not optional.</p>
<div class="card-foot">
<span class="price">$12</span>
<span class="spice" aria-label="Heat 3 of 4"><i class="on"></i><i class="on"></i><i class="on"></i><i></i></span>
</div>
</article>
<article class="card reveal" style="transition-delay:.08s">
<div class="card-top"><span class="card-idx">05</span><span class="tag">Shareable</span></div>
<h3>Bulgogi Fries</h3>
<p>Crinkle fries, bulgogi beef, cheese sauce, chopped kimchi, scallion, fried egg.</p>
<div class="card-foot">
<span class="price">$10</span>
<span class="spice" aria-label="Heat 1 of 4"><i class="on"></i><i></i><i></i><i></i></span>
</div>
</article>
<article class="card reveal" style="transition-delay:.14s">
<div class="card-top"><span class="card-idx">06</span></div>
<h3>Kimchi Queso</h3>
<p>Molten Oaxaca, aged kimchi, gochugaru oil, warm tortillas for scooping.</p>
<div class="card-foot">
<span class="price">$8</span>
<span class="spice" aria-label="Heat 2 of 4"><i class="on"></i><i class="on"></i><i></i><i></i></span>
</div>
</article>
</div>
<p class="menu-note reveal">Corn tortillas, always · Gluten-free on request · Cash & card</p>
</div>
</section>
<!-- ================= FIND ================= -->
<section class="section find" id="find">
<div class="wrap">
<div class="sec-head reveal">
<span class="sec-num">02</span>
<h2>Find the Truck</h2>
<p class="sec-sub">A truck has to move. Here's where the red one with the loud music is parked this week.</p>
</div>
<div class="find-grid">
<div class="today-card reveal">
<div class="status">
<span class="dot" id="cardDot"></span>
<span id="cardStatus">Open now · till 9pm</span>
</div>
<h3 id="todayPlace">Silver Lake</h3>
<p class="addr" id="todayAddr">Sunset Junction · 3820 Sunset Blvd, Los Angeles</p>
<div class="hours">
<span>Hours <b id="todayHours">11:30a – 9p</b></span>
<span>Service <b>Walk-up only</b></span>
</div>
<button class="btn btn-ink" id="dirBtn" type="button">Get directions →</button>
</div>
<div class="reveal" style="transition-delay:.1s">
<div class="sched-head">
<span>This week</span>
<span>All times PT</span>
</div>
<ul class="sched" id="schedList"></ul>
</div>
</div>
</div>
</section>
<!-- ================= STORY ================= -->
<section class="section story" id="story">
<div class="wrap story-grid">
<div class="reveal">
<span class="kicker">Our story</span>
<h2>Two kitchens.<br>One truck.<br><span class="hl">Zero chill.</span></h2>
</div>
<div class="story-right reveal" style="transition-delay:.1s">
<p class="lead">Mina Park grew up on her grandmother's galbi in Koreatown. Hector Ruiz learned to braise at his abuela's taqueria in Boyle Heights. They met at a food festival, argued about salsa, and now they share a 24-foot truck and a very loud sound system.</p>
<p>Every batch of kimchi is buried in the walk-in for 48 hours. Every ribeye sits in soy, pear and garlic for twelve. The tortillas are pressed to order — always corn, always warm. This isn't fusion for the sake of it. It's the food we actually want to eat at 11pm.</p>
<div class="stats">
<div><b>12</b><span>Hour marinade</span></div>
<div><b>48</b><span>Hour kimchi</span></div>
<div><b>4.9</b><span>1,284 reviews</span></div>
</div>
</div>
</div>
</section>
<!-- ================= CTA ================= -->
<section class="cta">
<div class="wrap">
<h2 class="reveal">Come hungry.<br>Leave <span class="hl">loco.</span></h2>
<p class="cta-sub reveal" style="transition-delay:.06s">The line moves fast. The truck doesn't. Check this week's spots, then come find the red truck with the loud music and the smell you can follow from a block away.</p>
<div class="cta-actions reveal" style="transition-delay:.12s">
<a class="btn btn-lg btn-ink" href="#find">Find the truck</a>
<a class="btn btn-lg btn-outline" href="#menu">View the menu</a>
</div>
<form class="signup reveal" id="signup" style="transition-delay:.18s" novalidate>
<label class="sr-only" for="email">Email address</label>
<input id="email" name="email" type="email" placeholder="you@email.com" autocomplete="email" required>
<button class="btn btn-lime" type="submit">Join the Loco List</button>
<span class="form-msg" id="formMsg" role="status" aria-live="polite"></span>
</form>
<p class="fine">One email a week. Where the truck is. What's new. Nothing else.</p>
</div>
</section>
</main>
<!-- ================= FOOTER ================= -->
<footer>
<div class="wrap">
<div class="foot-top">
<div class="foot-brand">
<svg class="mark" viewBox="0 0 40 40" aria-hidden="true">
<circle cx="20" cy="20" r="19" fill="#E5322B" stroke="#FFF4E3" stroke-width="2.5"/>
<path d="M9 24a11 11 0 0 1 22 0z" fill="#FFB03B" stroke="#FFF4E3" stroke-width="2"/>
<path d="M12 22c2-4 5-5 8-4s4-4 8-3" fill="none" stroke="#7BB04A" stroke-width="3" stroke-linecap="round"/>
<circle cx="16" cy="18" r="2.1" fill="#FFF4E3"/>
<circle cx="24" cy="16.5" r="1.8" fill="#FFF4E3"/>
</svg>
<span>
<b>Kimchi Loco</b>
<i>Korean Tacos · Los Angeles</i>
</span>
</div>
<nav class="foot-links">
<a href="#menu">Menu</a>
<a href="#find">Find Us</a>
<a href="#story">Story</a>
<a href="#" id="igLink">@kimchiloco</a>
</nav>
</div>
<div class="foot-bottom">
<span>© 2025 Kimchi Loco LLC · Los Angeles, CA</span>
<span>Made with gochujang, lime, and a very loud sound system.</span>
</div>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script>
(function () {
'use strict';
var $ = function (sel, ctx) { return (ctx || document).querySelector(sel); };
var $$ = function (sel, ctx) { return Array.prototype.slice.call((ctx || document).querySelectorAll(sel)); };
/* ------------------------------------------------------------------
SCHEDULE DATA
------------------------------------------------------------------ */
var SCHEDULE = [
{ d: 'Mon', place: 'Arts District', addr: '4th & Alameda', open: 11.5, close: 21, hrs: '11:30a – 9p' },
{ d: 'Tue', place: 'Silver Lake', addr: 'Sunset Junction', open: 11.5, close: 21, hrs: '11:30a – 9p' },
{ d: 'Wed', place: 'Downtown LA', addr: 'Grand Central Market', open: 11, close: 20, hrs: '11a – 8p' },
{ d: 'Thu', place: 'Echo Park', addr: 'Sunset & Alvarado', open: 11.5, close: 21, hrs: '11:30a – 9p' },
{ d: 'Fri', place: 'West Hollywood', addr: 'Plummer Park', open: 17, close: 24, hrs: '5p – 12a' },
{ d: 'Sat', place: 'Smorgasburg', addr: 'ROW DTLA', open: 10, close: 16, hrs: '10a – 4p' },
{ d: 'Sun', place: 'Private Events', addr: 'You bring the crowd', open: null, close: null, hrs: 'Booked' }
];
var DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var now = new Date();
var todayName = DAY_NAMES[now.getDay()];
var todayEntry = null;
for (var i = 0; i < SCHEDULE.length; i++) {
if (SCHEDULE[i].d === todayName) { todayEntry = SCHEDULE[i]; break; }
}
function fmtHour(h) {
if (h === 24) return '12a';
if (h === 12) return '12p';
if (h > 12) return (h - 12) + 'p';
return h + 'a';
}
var nowH = now.getHours() + now.getMinutes() / 60;
var isOpen = !!(todayEntry && todayEntry.open !== null && nowH >= todayEntry.open && nowH < todayEntry.close);
var statusText;
if (isOpen) {
statusText = 'Open now · ' + todayEntry.place + ' · till ' + fmtHour(todayEntry.close);
} else if (todayEntry && todayEntry.open !== null) {
statusText = nowH < todayEntry.open
? 'Closed · opens ' + fmtHour(todayEntry.open) + ' · ' + todayEntry.place
: 'Closed for today · back tomorrow';
} else {
statusText = 'Private events today · back tomorrow';
}
/* hero pill + card */
var heroStatus = $('#heroStatus');
var cardStatus = $('#cardStatus');
var heroDot = $('#heroDot');
var cardDot = $('#cardDot');
if (heroStatus) heroStatus.textContent = statusText;
if (cardStatus) cardStatus.textContent = isOpen ? 'Open now · till ' + fmtHour(todayEntry.close) : statusText;
if (!isOpen) {
if (heroDot) heroDot.classList.add('closed');
if (cardDot) cardDot.classList.add('closed');
}
if (todayEntry) {
var tp = $('#todayPlace'), ta = $('#todayAddr'), th = $('#todayHours');
if (tp) tp.textContent = todayEntry.place;
if (ta) ta.textContent = todayEntry.addr + ' · Los Angeles';
if (th) th.textContent = todayEntry.hrs;
}
/* schedule list */
var list = $('#schedList');
if (list) {
var html = '';
for (var j = 0; j < SCHEDULE.length; j++) {
var s = SCHEDULE[j];
var isToday = s.d === todayName;
html += '<li class="' + (isToday ? 'is-today' : '') + '">' +
'<span class="s-day">' + s.d + '</span>' +
'<span class="s-place">' + s.place + '<em>' + s.addr + '</em></span>' +
'<span class="s-hrs">' + s.hrs + '</span>' +
'</li>';
}
list.innerHTML = html;
}
/* ------------------------------------------------------------------
ROTATOR
------------------------------------------------------------------ */
var rotator = $('#rotator');
var specials = ['Gochujang Bulgogi', 'Kimchi Crujiente', 'El Loco', 'Bulgogi Fries', 'K-Fried Chicken'];
var ri = 0;
if (rotator) {
setInterval(function () {
rotator.classList.add('fade');
setTimeout(function () {
ri = (ri + 1) % specials.length;
rotator.textContent = specials[ri];
rotator.classList.remove('fade');
}, 260);
}, 2600);
}
/* ------------------------------------------------------------------
REVEAL ON SCROLL
------------------------------------------------------------------ */
var reveals = $$('.reveal');
if ('IntersectionObserver' in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
entry.target.classList.add('in');
io.unobserve(entry.target);
}
});
}, { threshold: 0.12, rootMargin: '0px 0px -40px 0px' });
reveals.forEach(function (el) { io.observe(el); });
} else {
reveals.forEach(function (el) { el.classList.add('in'); });
}
/* failsafe: never leave content invisible */
setTimeout(function () {
reveals.forEach(function (el) { el.classList.add('in'); });
}, 2200);
/* ------------------------------------------------------------------
HERO PARALLAX
------------------------------------------------------------------ */
var art = $('#heroArt');
var finePointer = window.matchMedia && window.matchMedia('(pointer:fine)').matches;
var reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (art && finePointer && !reduced) {
var raf = null, tx = 0, ty = 0;
window.addEventListener('mousemove', function (e) {
var r = art.getBoundingClientRect();
var cx = r.left + r.width / 2;
var cy = r.top + r.height / 2;
tx = Math.max(-1, Math.min(1, (e.clientX - cx) / (r.width * 1.2)));
ty = Math.max(-1, Math.min(1, (e.clientY - cy) / (r.height * 1.2)));
if (raf) return;
raf = requestAnimationFrame(function () {
art.style.transform = 'translate3d(' + (tx * 16).toFixed(2) + 'px,' + (ty * 14).toFixed(2) + 'px,0)';
raf = null;
});
}, { passive: true });
}
/* ------------------------------------------------------------------
TOAST
------------------------------------------------------------------ */
var toast = $('#toast');
var toastTimer = null;
function showToast(msg) {
if (!toast) return;
toast.textContent = msg;
toast.classList.add('show');
if (toastTimer) clearTimeout(toastTimer);
toastTimer = setTimeout(function () { toast.classList.remove('show'); }, 3200);
}
var dirBtn = $('#dirBtn');
if (dirBtn) {
dirBtn.addEventListener('click', function () {
var place = todayEntry ? todayEntry.place : 'Silver Lake';
var addr = todayEntry ? todayEntry.addr : 'Sunset Junction';
showToast('📍 ' + place + ' · ' + addr + ' — look for the red truck');
});
}
var igLink = $('#igLink');
if (igLink) {
igLink.addEventListener('click', function (e) {
e.preventDefault();
showToast('@kimchiloco — we post the location every morning at 9');
});
}
/* ------------------------------------------------------------------
SIGNUP FORM
------------------------------------------------------------------ */
var form = $('#signup');
var formMsg = $('#formMsg');
if (form) {
form.addEventListener('submit', function (e) {
e.preventDefault();
var input = $('#email');
var value = input ? input.value.trim() : '';
var ok = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(value);
if (!ok) {
if (formMsg) formMsg.textContent = 'Hmm, that email looks under-seasoned. Try again.';
if (input) input.focus();
return;
}
if (formMsg) formMsg.textContent = "You're on the list. See you at the window.";
if (input) input.value = '';
showToast("🌮 You're on the Loco List. First taco's on us.");
});
}
})();
</script>
</body>
</html>Reasoning trace (22,377 tokens)
Let me build a mouth-watering, immersive one-page site for "Kimchi Loco" — a Korean taco food truck. Requirements: self-contained HTML, inline CSS/JS, no external resources. Should look great at 1280×800 and adapt to 375px.
Note: "Games must start in self-playing demo mode" — but this isn't a game, it's a website. The "Click or press a key to start" rule applies to games. But there's also the rule: "if the demo uses the keyboard, display a clear message". I'll avoid requiring keyboard. Let me instead make something visually stunning with a bit of interactivity that shows on first paint.
Design direction: bold, spicy, high-energy. Colors: gochujang red (#E23B2E), deep charcoal (#141110), warm cream (#FFF6E9), sesame gold (#F5A623), and a hit of lime green or perilla. Typography: big bold display type. Since no external fonts allowed, I'll use system fonts with heavy weights — e.g., font-family: 'Helvetica Neue', Arial Black, Impact... For Korean-ish flavor I could use a strong sans. Let's use a stack: `-apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif` for body and `Impact, "Haettenschweiler", "Arial Narrow Bold", sans-serif` for display? Impact is quite distinctive but may look dated. Actually a heavy system sans with tight tracking works nicely: `font-weight: 900; letter-spacing: -0.04em;`. Let's use that.
Content:
- Nav: Kimchi Loco logo (a little chili/taco mark), links: Menu, Find Us, Story, Order.
- Hero: huge headline "KOREAN. MEXICAN. LOCO." with subline. Truck illustration? Maybe an SVG truck. CTA buttons: "See the Menu" and "Find the Truck". A live "Open now" status pill with today's location + rotating marquee of taco love.
- A hero visual: an SVG taco with radial glow, steam, floating ingredients, animated. That would be lovely. I'll craft a decent CSS/SVG taco.
Then: "The Lineup" menu section — 4-5 items as bold cards with price, description, spicy level indicator, hover lift. Include a "Fan favorite" badge.
Then: "Find the Truck" — a schedule with days and locations, with "today" highlighted dynamically via JS. That's a nice touch and shows interaction. Also a small stylized map? Maybe a simple SVG map abstraction with a pin. Keep it light.
Then: a story strip with big pull quote.
Then: newsletter/reserve CTA + footer.
Also a marquee ticker band scrolling "GOCHUJANG • BULGOGI • KIMCHI • ..." using CSS animation.
Micro-interactions: cursor-following? Keep simple. Maybe a "spice level" interactive thing... Actually, an interesting idea: a taco builder where clicking ingredient chips adds them to the taco SVG, and it calculates a price. That's interactive and fun, visible on first paint. Hmm, but that might clutter. Let's consider: the request is "make people really want to come" — appetite appeal + clear info (location/time/order) + energy.
I'll do:
1. Hero with animated taco SVG, floating ingredients, spicy glow.
2. Scrolling marquee band.
3. Menu cards (4 tacos + 2 sides), with spice dots, hover, and an "All tacos" note.
4. "Tonight's Location" block with live status computed from JS current time — showing "OPEN NOW till 9pm" or "Closed — back tomorrow at 11". Plus a schedule list.
5. Testimonial / press quotes.
6. Big CTA footer with email signup form (prevent default, show thank-you message).
Add a small interactive: clicking a menu card flips/expands? Or a "heat meter" — clicking a spice icon toggles the whole page's spice level? Too gimmicky. Instead: hover/tap on menu card lifts it and reveals the "salsa" line.
Let me also add a subtle grain/noise texture via SVG feTurbulence data URI (allowed — inline data, no network). Good for warmth.
Also a hero "steam" animation and a subtle parallax on mouse move for the taco (respecting reduced motion).
Let's also add an auto-rotating "now serving" line? Maybe a rotating text in the hero: "Now serving: [Gochujang Bulgogi] [Crispy Kimchi]..." cycling every 2.2s. Good, visible on first paint.
Let me write the SVG taco carefully. Drawing a taco in SVG: a folded tortilla shell (semicircle) viewed from the front, with fillings visible. Approach:
- Shape: a half-disc taco shell: path M 20 180 A 160 160 0 0 1 340 180 Z → that gives a semicircle opening downward (flat side on bottom). Actually the taco shell opens upward when viewed from front; the filling peaks above the shell rim. So draw the shell as a semicircle: flat top? Let's think: front view of a taco held: the shell is a semicircle with flat edge at top (the rim where the opening is), curved bottom. Fillings stick out above the rim. So: path "M 40 200 A 160 160 0 0 1 360 200 Z" — this arc from (40,200) to (360,200) with radius 160 sweeping... large-arc=0, sweep=1 goes above? For an arc from left to right with sweep=1, the curve bulges downward. Hmm, sweep-flag=1 means positive-angle direction (clockwise in standard SVG coords where y is down). From (40,200) to (360,200) clockwise → goes up over the top. Let me just use: M 40 200 A 160 160 0 0 1 360 200 Z — sweep 1 → clockwise → from left point going clockwise means going up and over to the right. Yes, that bulges upward. And the Z closes back along the bottom line. So we get a semicircle with flat bottom at y=200 and the dome above. That's the taco viewed... no.
Actually simpler and more readable: the taco is a semicircle with the curved part at the bottom and the flat rim at the top, because the shell sits in a holder. Fillings burst above the flat top edge. Let me do: M 40 200 A 160 160 0 0 0 360 200 Z — sweep 0 → counter-clockwise from (40,200) to (360,200) → bulges downward. That gives a "U" shape: the dome is below. Yes! With fillings on top at y ≈ 200 and above.
So the shell path: `M 40 200 A 160 160 0 0 0 360 200 Z` — a semicircle from (40,200) to (360,200), bulging down to y=360. Then fillings drawn above y=200, clipped by the shell? No — fillings should be visible above the rim and slightly overlap. Draw fillings first (behind), then shell on top? But then the fillings below the rim would be hidden — good, since shell covers them. But we want fillings visible in the opening. Hmm — for a front view, you see the outside of the shell (the folded edge faces you) and the fillings poke above. So: draw filling shapes that extend above y=200, then draw the shell on top so it covers everything below y=200. Fillings that peek above the rim remain visible.
Fillings:
- Lettuce/cilantro: green wavy blobs.
- Kimchi: red-orange chunks.
- Meat: dark brown chunks.
- Crema drizzle: white wavy line.
- Sesame seeds: tiny ellipses.
Colors: shell #F2B441 / #E39A2B gradient (toasted corn tortilla), with darker spots.
Add a "glow" radial gradient behind in red.
Also add a floating chili and lime wedge around. And a lime wedge SVG is easy: circle with wedges.
Let's keep the SVG moderately detailed but not insane.
Now, layout: hero grid 2 columns on desktop (text left, taco right), stacked on mobile.
Let me write it.
```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 Tacos, LA</title>
<style>...</style>
</head>
<body>
...
</body>
</html>
```
Colors:
--ink: #17100E (warm near-black)
--cream: #FFF4E3
--red: #E5322B (gochujang)
--red-deep: #B31217
--gold: #FFB03B
--lime: #B8E12C? Maybe a perilla green #7FB069 or vivid lime #C6F04A. Let's use #C9F04A as an accent for "open now" pill and a few highlights. Hmm, with red + cream + gold, a lime accent feels fresh. Good.
Type scale: hero h1 clamp(48px, 9vw, 128px), line-height .84, letter-spacing -0.045em, weight 900, uppercase.
Let's write full CSS.
```css
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
background:var(--cream);
color:var(--ink);
font-family:"Helvetica Neue",Helvetica,Arial,"Segoe UI",sans-serif;
-webkit-font-smoothing:antialiased;
overflow-x:hidden;
}
```
Grain overlay: `body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:999;opacity:.055;background-image:url("data:image/svg+xml,...feTurbulence...")}`. Use a small svg:
`<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3'/></filter><rect width='120' height='120' filter='url(%23n)'/></svg>`
URL-encode: `#` → `%23`, quotes fine. Should be OK.
Nav: sticky top, backdrop blur, cream translucent with border-bottom. Logo: a small circular mark with a chili + taco? Let's do a simple SVG mark: circle with red fill and a cream taco glyph, plus wordmark "KIMCHI LOCO" in heavy letters with "LOCÓ" accented? Keep "KIMCHI LOCO" and a tiny "KOREAN TACOS • LA" below.
Actually let's make the logo a taco-ish mark: an arc with a chili. Simple:
```svg
<svg viewBox="0 0 40 40"> <circle cx="20" cy="20" r="20" fill="#E5322B"/> <path d="M8 26a12 12 0 0 1 24 0z" fill="#FFF4E3"/> ... </svg>
```
Hmm the shell as a dome facing up: `M8 26 a12 12 0 0 1 24 0 z` gives dome from (8,26) to (32,26) bulging up. Good — that's the shell edge. Add filling: a few small circles above.
Actually simpler: a red circle with a cream "chili" shape. Let's do the taco dome: red circle bg, cream dome bottom, three little dots above in cream/gold. Fine.
Hero:
- left: eyebrow pill "★ LA's loudest food truck", h1 "KOREAN<br>MEXICAN<br><span class=accent>LOCO.</span>", p description, buttons, small meta row (rating, locations).
- right: taco SVG with glow, floating bits, rotation.
Let me write the rotator: "Now serving: <span id=rot>Gochujang Bulgogi</span>".
Marquee: a band with red bg, cream text, uppercase, rotating items with a taco divider (● ). CSS animation translateX(-50%) with duplicated content.
Section: "The Lineup" — heading with number "01 / MENU". Grid of cards: each card has a big emoji-free icon? Better: small colored SVG chips. Let's include a mini color blob + name + description + price + spice level dots.
Cards:
1. The Kimchi Loco — "Bulldog" ... let's name:
- SEOUL CITY BULGOGI — $12 — marinated ribeye, gochujang crema, pickled onion, cilantro, sesame. Spice 2.
- KIMCHI LOVERS — $11 — crispy kimchi, carnitas... hmm name "KIMCHI CRUJIENTE".
- EL LOCO — $13 — spicy pork, pineapple, cotija...
- BULGOGI FRIES — $10
- K-TACO KOREAN FRIED CHICKEN — $12
- MEX-KIM QUESADILLA
Keep 4 tacos + 2 sides = 6 cards. On desktop, 3 columns × 2 rows.
Each card: number, name, description, price, spice dots, "Fan favorite" tag on one, "Sold out fast" on another. Hover: translateY(-6px), shadow, top border red.
Section: "Find the Truck" — big red block (or dark), with:
- Left: "Tonight's location" big text, "OPEN NOW" pill with pulsing dot, address, hours, CTA "Get directions".
- Right: schedule list of 5 days with today highlighted.
JS computes day index and whether open.
Let's make the schedule static and the "today" highlight dynamic. Use a compact list:
Mon — Arts District, 4th & Alameda — 11:30–9
Tue — Silver Lake, Sunset Junction — 11:30–9
Wed — DTLA, Grand Central Mkt — 11–8
Thu — Echo Park, Sunset & Alvarado — 11:30–9
Fri — WeHo, Plummer Park — 5pm–midnight
Sat — Smorgasburg, ROW DTLA — 10–4
Sun — Private events / off
That's 7 rows; fine on desktop, could be tall. Maybe 5. I'll do 7 in a compact list with small type and dividers. It's fine.
Actually to keep the visual balance, use 2 columns for the schedule on desktop? Let's do the list single column, rows ~44px → 308px. OK next to the info block.
Section: "Why people line up" — 3 small items with icons (Storm of flavor, etc.). Maybe a quote block instead. Let's do a quote + 3 stats.
Section: CTA — dark ink block, big "COME HUNGRY." with email form and a note "We text you the location... " but no SMS. Just "Join the Loco List" email form → on submit shows "You're on the list. See you at the window." Also socials (text links).
Footer: small print, copyright, "Made with gochujang".
Animations:
- Slide/fade reveal on scroll via IntersectionObserver (add .in class). Must ensure content visible if JS fails? First paint screenshot at 3s — the hero should be visible. Use IO with a fallback: elements start visible unless JS adds a class `js` to html. I'll add `document.documentElement.classList.add('js')` then CSS `.js .reveal{opacity:0...}`. Since script runs at end of body, fine. But careful: if JS errors, content hidden. Keep it simple and safe.
Actually simpler: use CSS animation with delay for the hero (on load), and IntersectionObserver for sections below the fold. Fine.
- Steam wisps above taco: 3 paths with animation moving up and fading.
- Mouse parallax on taco: transform translate based on pointer.
- Marquee infinite.
Reduced motion: media query to disable.
Let me write the taco SVG.
```svg
<svg viewBox="0 0 420 420" class="taco-svg">
<defs>
<radialGradient id="glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#FFD36E" stop-opacity=".95"/>
<stop offset="55%" stop-color="#FF8A3D" stop-opacity=".55"/>
<stop offset="100%" stop-color="#FF8A3D" stop-opacity="0"/>
</radialGradient>
<linearGradient id="shell" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FFC65C"/>
<stop offset="55%" stop-color="#F2A03A"/>
<stop offset="100%" stop-color="#C9711D"/>
</linearGradient>
<linearGradient id="shellInner" ...>
<clipPath id="shellClip"><path d="M..."/></clipPath>
</defs>
</svg>
```
Shell path: center at (210, 200) radius 150: `M 60 200 A 150 150 0 0 0 360 200 Z`. Wait — the arc from (60,200) to (360,200) radius 150 with sweep=0 goes... Let's verify: sweep=0 means counter-clockwise in the SVG coordinate system? The SVG spec: sweep-flag=1 means the arc is drawn in a "positive-angle" direction, which in the standard coordinate system (y down) is clockwise. sweep=0 → counter-clockwise → from (60,200) counter-clockwise would go downward first (since counter-clockwise from leftmost point going... hmm).
Let's param: center (210,200), radius 150. Point at angle 180° = (60,200). Point at 0° = (360,200). In SVG, angle 0 = +x, positive angles go clockwise because y is down (i.e., point at angle θ is (cx + r cos θ, cy + r sin θ) with θ increasing downward). So going from θ=180° to θ=0° increasing θ → 180→360 (i.e., -180→... ) ugh.
Simpler: sweep=1 draws the arc so that the direction of travel is clockwise on screen. From (60,200) (left) to (360,200) (right), clockwise on screen means going up over the top. So sweep=1 → dome above. sweep=0 → dome below.
I want dome below (the shell's curved bottom). So sweep=0: `M 60 200 A 150 150 0 0 0 360 200 Z`.
Fillings visible above y=200. Draw them first, then the shell on top.
Filling shapes (above the rim, y < 200, and dipping slightly below so they get covered by the shell):
- Green lettuce/cilantro: several rounded blobs, y between 130 and 205.
- Meat chunks: dark brown rounded rects rotated.
- Kimchi: red-orange chunks.
- Crema: white curvy line — draw as a path with stroke, width 8, round caps, above the fillings? Actually a drizzle on top. Draw after fillings.
- Sesame seeds: tiny ellipses cream.
The fillings should be drawn between the rim (y=200) and the top of the taco, forming a mound. Let's do a mound path: `M 60 200 Q 90 120 150 130 Q 210 100 270 130 Q 330 120 360 200 Z` — a lumpy mound. Then overlay chunks.
Let me structure the taco:
1. Glow circle behind.
2. Mound base: green lettuce (a big lumpy green shape) — `#7FB04A`.
3. Kimchi chunks: red-orange blobs.
4. Meat chunks: dark brown.
5. Crema drizzle: white curve stroke.
6. Sesame seeds.
7. Shell (with gradient + toasted spots) on top, covering the bottom part.
8. Shell highlights.
For the shell's inner rim, I could add a slightly darker band at the top edge — a thin ellipse at y=200 clipped by the shell? Actually the top edge of the shell is the flat line at y=200. Add a thin darker line along it. Or just a highlight arc.
For a nicer look: add toasted spots with clip-path on the shell — small ellipses in #B4611A at opacity .5, clipped to the shell path.
Since the taco is a huge element, it should look good. Let's also add a small "floating" animation: whole taco group translateY(-8px) rotate(2deg) over 6s.
Also lime wedge floating top-left and a chili floating bottom-right, red onion etc. Let's add a few floating elements as separate SVGs positioned absolutely around the taco, with a gentle float animation. Maybe just use a couple of small decorative shapes: a chili pepper, a lime wedge, a sesame seed, a cilantro leaf. Keep it simple:
- Chili: `M0 0` red curved shape with a green stem.
- Lime: circle with a lighter inner circle and 6 lines.
I'll do these as small absolutely positioned SVGs with animations, hidden on small screens (or kept smaller).
Now, hero background: cream with a large soft radial red glow behind the taco, plus a faint repeating pattern? Keep it clean.
Let me write the code now. I'll be careful about the "no horizontal scrollbar" requirement — use `overflow-x:hidden` on body and make sure marquee items don't overflow (use overflow hidden on the band).
Also the marquee with `display:flex; width:max-content; animation: marquee 28s linear infinite;` translateX(-50%) with the content duplicated twice.
For the nav on mobile: hide the links, show a "Find us" button. Simpler: nav shows logo + a small "Order" button on mobile. Hide links under 720px.
Let me write it out.
```html
<body>
<header class="nav">
<a class="brand" href="#top">
<span class="mark">...svg...</span>
<span class="brand-text"><b>Kimchi Loco</b><i>Korean Tacos · LA</i></span>
</a>
<nav class="nav-links">
<a href="#menu">Menu</a>
<a href="#find">Find Us</a>
<a href="#story">Story</a>
</nav>
<a class="btn btn-sm" href="#find">Order now</a>
</header>
<main id="top">
<section class="hero"> ... </section>
<div class="marquee"> ... </div>
<section id="menu" class="section menu"> ... </section>
<section id="find" class="section find"> ... </section>
<section id="story" class="section story"> ... </section>
<section class="cta"> ... </section>
</main>
<footer> ... </footer>
```
Hmm, sticky nav + hero. Fine.
Hero content:
```html
<section class="hero">
<div class="hero-glow"></div>
<div class="hero-inner">
<div class="hero-copy">
<div class="pill"><span class="dot"></span> Open now · Silver Lake · till 9pm</div>
<h1>Korean<br>Mexican<br><span class="hl">Loco</span></h1>
<p class="lede">Gochujang-slapped tacos, burnt-sugar bulgogi, and kimchi that bites back. We're a truck. We're loud. We sell out by 8.</p>
<div class="hero-cta">
<a href="#menu" class="btn btn-primary">See the menu</a>
<a href="#find" class="btn btn-ghost">Find the truck →</a>
</div>
<div class="hero-meta">
<div class="stars">★★★★★</div>
<span><b>4.9</b> · 1,284 reviews</span>
<span class="sep"></span>
<span>Now serving: <b id="rotator">Gochujang Bulgogi</b></span>
</div>
</div>
<div class="hero-art">
... taco svg + floaters ...
</div>
</div>
</section>
```
Wait — the pill says "Open now" and "till 9pm" — I can compute via JS to be accurate. Let's have JS update the pill text: if the current hour is between 11 and 21, show "Open now · {location} · till 9pm" else "Closed · back tomorrow at 11". Nice touch of realism. Monday–Sunday schedule. But careful: it could show "Closed" at screenshot time. That's fine/realistic; but maybe better to keep a positive vibe. I'll make the pill always show "Open now" style but if closed show "Back at 11am · {location}". Hmm, to keep it appealing, I'll do: if closed → "Now booking events · Find us this week". Eh.
Let's just do a computed pill: open hours 11:00–21:00 daily → "Open now · till 9pm" or "Closed · opens 11am". Plus the location changes by day. That's honest and dynamic. And there's a nice pulsing dot only when open.
Also I'll show the "today" row in the schedule highlighted.
Now the font for the h1: heavy, condensed-ish. I'll use font-stretch? Not reliable. Use `font-family: "Arial Black", "Helvetica Neue", Impact, sans-serif;` — Arial Black is available on macOS/Windows; on Linux Chrome it may fall back to something. Chrome on Linux with no Arial Black → "Helvetica Neue" → Liberation Sans? It'd be bold sans. With font-weight 900 and letter-spacing tightened, it'll look decent. I'll set `font-family:"Arial Black","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:900;` — on Linux, Arial Black missing → Helvetica Neue missing → Helvetica → mapped to Liberation Sans → Arial. Bold enough.
To make it more distinctive, I can use `-webkit-text-stroke` for an outline effect on one word, e.g., "LOCO" in cream with red stroke or a filled/outline combo. Let's do: "KOREAN" solid ink, "MEXICAN" solid ink, "LOCO." in red with a slight skew? Or make "LOCO" text-stroke only (transparent fill, red stroke) — cool. But text-stroke on heavy sans looks great. Use it with `paint-order` maybe. Let's do: LOCO in red gradient. Hmm the reference: many food truck sites use solid bold with an accent word. I'll do "LOCO" in red with a subtle outline offset. Keep it: cream text → no. Let me do:
h1: color ink; the accent span gets `color: var(--red); -webkit-text-stroke: 3px var(--ink)`. That's a chunky outlined red word — very "food truck". Wait, with the stroke, the letters get bolder and the red stays inside. Good. But on Linux, text-stroke works in Chrome. Fine.
Hmm, but the hero h1 is on cream background. The red + ink stroke is punchy. Let's do it.
Also add a subtle "hand-drawn" underline or a starburst badge "SOLD OUT BY 8" rotated near the taco. Nice.
Let's write the CSS carefully.
```css
:root{
--ink:#17100E;
--ink-2:#2A1D18;
--cream:#FFF4E3;
--cream-2:#F7E6CE;
--red:#E5322B;
--red-deep:#B31217;
--gold:#FFB03B;
--lime:#C9F04A;
--green:#5F8D3E;
--radius:22px;
}
```
Sections:
```css
.section{padding:clamp(56px,8vw,120px) clamp(20px,4vw,56px); max-width:1280px; margin:0 auto}
```
Wait, the container should have max-width 1280 and margin auto, with padding inside.
Hero: min-height ~ calc(100vh - 70px)? At 1280×800, we want the hero to fill mostly the viewport. Use `padding: clamp(24px,4vw,48px) clamp(20px,4vw,56px) clamp(40px,6vw,80px)`, min-height: 88vh. Grid: 1.05fr .95fr, gap 32px, align-items:center.
On <900px: single column, art first? Text first probably better; art after. Actually the taco should be visible in the initial screenshot on mobile too. At 375px wide, the screenshot is 375×~800 (Cropped). Text first means the taco might be below the fold. Since the screenshot at 3s is at 1280×800 presumably for desktop comparison, and mobile adaptation is a secondary check. I'll put text first, and keep the h1 compact so the taco starts peeking. Actually, better: on mobile reduce the art size to ~220px and put it right after the buttons... it's a single flow. Text block: pill + h1 (3 lines at ~46px = 140px) + lede + buttons + meta ≈ 480px. Then taco starts around 520px. At 800px tall viewport, taco is partially visible. Good enough.
Let me now think about the taco SVG dimensions in the layout: `.hero-art{position:relative; display:grid; place-items:center;}` with `.taco-svg{width:min(100%,560px); height:auto; filter: drop-shadow(0 30px 40px rgba(180,60,20,.28))}`.
Glow: `.hero-glow{position:absolute; width:720px;height:720px;border-radius:50%;background:radial-gradient(circle, rgba(255,170,60,.55), rgba(255,110,60,.18) 45%, transparent 70%); filter:blur(10px); right:-8%; top:-10%; z-index:0; pointer-events:none}`. Need overflow hidden on hero.
Also add a subtle dot grid? Nah.
Marquee band:
```css
.marquee{background:var(--ink); color:var(--cream); padding:14px 0; overflow:hidden; border-top:3px solid var(--ink); border-bottom:3px solid var(--ink); transform:rotate(-1.2deg) scale(1.03);}
```
Rotated band adds energy. Careful with overflow-x → body overflow hidden handles it. But rotating a full-width band creates overflow at the sides; body overflow-x hidden clips. But that might also hide the vertical scrollbar... no, overflow-x:hidden on body with overflow-y visible can cause issues. Use `overflow-x:clip` on html? Simplest: wrap the marquee in a container with overflow:hidden, and rotate the inner. I'll do:
```html
<div class="marquee-wrap"><div class="marquee"><div class="marquee-track">...</div></div></div>
```
`.marquee-wrap{overflow:hidden; padding: 12px 0; }` and `.marquee{transform:rotate(-1.2deg); background:var(--red); ...}` — but rotate on a full-width element leaves gaps at the corners. Use `width:110%; margin-left:-5%;` to compensate. Actually with the outer overflow hidden and rotating -1.2deg, the corners will show wedge gaps at the top/bottom. Since the wrap has padding 12px and the background of the page is cream, the gaps would show cream wedges — that's fine, it looks like a rotated sticker. Actually it might look like an anti-aliased edge. Let's simply not rotate, and instead use a straight band with a red background and bold text, with two bands? Hmm. Rotated bands look cool. Let's do a straight band but add a slight top/bottom border and use the red color. Honestly, a straight marquee is clean and safe. I'll do a straight band, ink background, with red/gold accents.
Alternatively, rotate the band by -1.5deg with a wrapper that has extra vertical padding and the band scaled up 1.15 in width and height. Let's do:
```css
.ticker{background:var(--red); color:var(--cream); padding:0; transform:rotate(-1.6deg); width:112%; margin: 24px -6%; overflow:hidden; border-top:3px solid var(--ink); border-bottom:3px solid var(--ink);}
```
Hmm, with width 112% and margin -6%, and overflow hidden on body — the rotation goes beyond vertical, but body overflow-x hidden handles horizontal. The vertical overflow just overlaps the neighbors, which is fine visually if the neighbors have space. I'll give the ticker container margin: 40px 0 to compensate. Let's try -1.5deg. I think it looks great. But the risk of it looking broken... I'll go with a subtle -1.2deg and generous spacing. Actually — a big risk: the rotated band's text might get clipped at the left/right by the body's overflow-x:hidden, which is fine.
I'll include the ticker inside a wrapper with `overflow:hidden; padding: 28px 0` so it doesn't create horizontal scroll, and the band inside rotates.
OK. Menu section.
```html
<section id="menu" class="section menu">
<div class="sec-head">
<div class="sec-num">01</div>
<h2>The Lineup</h2>
<p class="sec-sub">Six things. Made to order. Get here before the bulgogi runs out.</p>
</div>
<div class="menu-grid">
<article class="card">
<div class="card-top"><span class="card-idx">01</span><span class="tag tag-hot">Fan favorite</span></div>
<h3>Seoul City Bulgogi</h3>
<p>Sweet-savory ribeye, gochujang crema, pickled onion, cilantro, sesame. The one that started the line.</p>
<div class="card-foot">
<span class="price">$12</span>
<span class="spice" title="Heat 2 of 4">●●○○</span>
</div>
</article>
...
</div>
<p class="menu-note">All tacos come on corn tortillas. Add a side of kimchi fried rice for $4. Cash & card.</p>
</section>
```
Card style: cream-2 background w/ 2px ink border, radius 20px, padding 22px, hover translate -6px + shadow. On hover, show a red bar at top? Add `box-shadow: 8px 8px 0 var(--ink)` on hover — a brutalist offset shadow. That's a nice look with the ink borders. Let's adopt the brutalist-ish style: 2px ink borders, hard offset shadows (no blur). This fits the food truck vibe.
Actually the whole design could be neo-brutalist: heavy borders, offset shadows, bold type, high-contrast colors. That's a strong, coherent direction and it looks good in screenshots. Let's do it: cards with `border:2.5px solid var(--ink)`, `box-shadow: 6px 6px 0 var(--ink)` and on hover `translate(-3px,-3px)` with `box-shadow: 10px 10px 0 var(--ink)`. Buttons: ink bg with cream text, hard shadow, active press.
But then the hero: the taco with a glow is more "premium" — that's fine, mix a soft glow with a brutalist frame. Hmm, maybe drop the glow and keep it flat/graphic. I'll keep a subtle glow behind the taco, it adds appetite.
Actually — let me reconsider the overall art direction for maximum "wow":
- Cream background, hard ink borders, red/ink/gold/lime accents, chunky type, offset shadows, sticker badges, rotated ticker. That's cohesive, modern, and very "food truck". Plus an appetite-appealing taco illustration. Good. Let's commit.
The hero: h1 huge, with a red underlined/stroked accent. Maybe put a lime "sticker" behind the word LOCO? Let's keep the h1 as is with the text-stroke on LOCO.
Add a sticker badge near the taco: a circular sticker rotated -12deg, gold background, ink border, text "SOLD OUT BY 8PM" curved? Curved text needs textPath — doable but fiddly. Simpler: a rotated rounded-rect sticker: "★ LINE FORMS HERE ★". Let's do a circular sticker with two lines of text: "SOLD OUT" / "BY 8 PM" with a star. Easy with flex + rotation, absolutely positioned on the hero art.
Find section:
```html
<section id="find" class="section find">
<div class="sec-head">...</div>
<div class="find-grid">
<div class="find-card">
<div class="status"><span class="dot"></span><span id="statusText">Open now · till 9pm</span></div>
<h3 id="findTitle">Silver Lake</h3>
<p id="findAddr">Sunset Junction · 3820 Sunset Blvd, Los Angeles</p>
<ul class="hours-list">...</ul>
<a class="btn btn-primary" href="#find">Get directions</a>
<span class="fine">Truck moves daily. Check the board.</span>
</div>
<div class="sched">
<h4>This week</h4>
<ul id="schedList"> ... </ul>
</div>
</div>
</section>
```
HTML generated for the schedule by JS from a data array, marking today.
Story section:
Big quote + 3 stats. E.g.:
"Chef Mina Park grew up in Koreatown, learned to braise from her halmoni, and married a taquero from Boyle Heights. Kimchi Loco is what happens when two great kitchens share a truck."
Stats: "12 hrs" bulgogi marinade · "48 hrs" kimchi · "1,284" five-star reviews.
CTA section: ink background, big text "Come hungry. / Leave with a story." with buttons and a form. And "Follow @kimchiloco" text links.
Footer: small.
Let me add a subtle marquee and reveal animations.
JS:
1. Rotator words.
2. Status + schedule.
3. Reveal on scroll (IO).
4. Parallax on the taco (mouse move) — with pointer: fine check.
5. Form submit → thank-you message, with a fallback.
6. Smooth scroll for anchor links (CSS scroll-behavior: smooth).
Careful: no console errors. IntersectionObserver is supported.
Now, details of the schedule data:
```js
const SCHEDULE = [
{day:'Mon', place:'Arts District', addr:'4th & Alameda', hours:'11:30 – 9'},
{day:'Tue', place:'Silver Lake', addr:'Sunset Junction', hours:'11:30 – 9'},
{day:'Wed', place:'DTLA', addr:'Grand Central Market', hours:'11 – 8'},
{day:'Thu', place:'Echo Park', addr:'Sunset & Alvarado', hours:'11:30 – 9'},
{day:'Fri', place:'West Hollywood', addr:'Plummer Park', hours:'5 – 12'},
{day:'Sat', place:'Smorgasburg', addr:'ROW DTLA', hours:'10 – 4'},
{day:'Sun', place:'Private events', addr:'Book us', hours:'—'},
];
```
Index 0=Sun? Let's use JS `new Date().getDay()` where 0=Sun. So put Sun first or reorder. I'll build the array in Mon..Sun order and use an index map: `const map=[6,0,1,2,3,4,5]` where getDay()=0 (Sun) → index 6.
Simplify: array order Sun..Sat: `[Sun, Mon, Tue, Wed, Thu, Fri, Sat]` and `SCHEDULE[new Date().getDay()]`. Display order: I'll display Mon..Sun but highlight by matching the day name. Let's just display in Sun..Sat order but start with Mon for aesthetics. Meh — I'll display Mon-Sun and match by name.
```js
const days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
const today = new Date().getDay();
```
Each entry has d: 'Mon' etc. Find `entries.find(e=>e.d===days[today])`.
Open status: parse hours string. For simplicity, define each day's open/close in 24h: openHour, closeHour. Then:
```js
const now = new Date(); const h = now.getHours() + now.getMinutes()/60;
const e = byDay[days[today]];
const isOpen = e && e.open!=null && h >= e.open && h < e.close;
```
For Friday 5–12, close is 24. Fine.
Pill text: if isOpen → `Open now · ${e.place} · till ${fmt(e.close)}`; else if e.open != null → `Closed · back ${nextOpenDay}`. Let's simplify: if not open → `Closed now · opens ${e.openLabel}` if today has hours, else `Closed · private event day`. Keep it simple and never show something depressing.
Actually maybe the pill should always show something positive: `Open now · Silver Lake · till 9pm` or `Closed · opens tomorrow 11:30am`. Good.
The hero pill text length is long on mobile; make it wrap or shrink font. Fine.
The "Find" card title updates to today's location.
Now let's think about the mobile hero h1 font-size: clamp(46px, 13vw, 92px)? At 1280 wide, 13vw = 166px — too big. Use clamp(44px, 8.5vw, 108px). At 1280 → 108px. Three lines of 108px × 0.86 line-height ≈ 279px. Plus the pill, lede, buttons, meta ≈ 200px. Total ~520px, plus padding. Fits in 800 with the art beside it. Good.
At 375 → 8.5vw = 32px, but the clamp min is 44px → 44px. Three lines ≈ 113px. Good.
Now the nav height ~70px. Hero min-height calc(100vh - 70px) but max 800. Fine.
Let me write the taco SVG in detail now.
```html
<svg class="taco-svg" viewBox="0 0 420 420" aria-hidden="true">
<defs>
<radialGradient id="tGlow" cx="50%" cy="52%" r="50%">
<stop offset="0%" stop-color="#FFC46B" stop-opacity=".85"/>
<stop offset="60%" stop-color="#FF9A4D" stop-opacity=".30"/>
<stop offset="100%" stop-color="#FF9A4D" stop-opacity="0"/>
</radialGradient>
<linearGradient id="tShell" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FFD47A"/>
<stop offset="45%" stop-color="#F7AE4A"/>
<stop offset="100%" stop-color="#C9711D"/>
</linearGradient>
<linearGradient id="tMeat" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#8A3A1E"/>
<stop offset="100%" stop-color="#4E1C0C"/>
</linearGradient>
<clipPath id="tShellClip">
<path d="M60 200 A150 150 0 0 0 360 200 Z"/>
</clipPath>
</defs>
<!-- glow -->
<circle cx="210" cy="235" r="200" fill="url(#tGlow)"/>
...
```
Wait, the circle at cx=210 cy=235 r=200 extends to y=435, beyond the viewBox (420) — it's a radial gradient so it fades. Fine.
Fillings:
Lettuce mound (green):
```svg
<path d="M64 202 C70 150 96 128 130 132 C140 108 176 100 198 118 C212 100 250 98 268 118 C296 104 330 118 340 146 C356 154 362 178 356 202 Z" fill="#6FA23F"/>
```
That's a lumpy mound. Then a darker green layer for depth: a second path offset.
Meat chunks (drawn over the lettuce, above the rim):
```svg
<g fill="url(#tMeat)">
<rect x="120" y="150" width="46" height="26" rx="12" transform="rotate(-8 143 163)"/>
...
</g>
```
Then kimchi chunks in red-orange (#E5322B and #C8211B).
Then the crema drizzle: `<path d="M96 186 C120 160 150 196 176 174 C198 156 224 190 250 168 C272 150 300 182 326 164" stroke="#FFF8EC" stroke-width="9" fill="none" stroke-linecap="round"/>` — hmm, but that would sit on top of the shell which is drawn after. Since the shell is drawn after (on top), the drizzle below y=200 gets hidden. That's fine as long as the drizzle is above y=200 — I'll set the y-range of the drizzle to 160-195. But then the shell covers the bottom part of the filling — good, that's the effect we want. But I want the drizzle to look like it's on top of the fillings. Draw order: lettuce → meat → kimchi → crema → sesame → shell. Since the shell covers everything below y=200, only the visible top is shown. Good.
Actually, the mound top: the lettuce path goes up to y≈110. The meat chunks should be around y=140-200. Let me lay out the mound shape from y=200 (rim) up to ~y=105 at the peak.
Hmm: the shell's rim is at y=200 and the shell's dome extends down to y=350. The fillings must poke above the rim. So the fillings occupy y from ~110 to ~200. And the shell covers y ≥ 200. Wait, the shell path is the semicircle below y=200 (dome down). So the top edge of the shell is the horizontal line y=200 from x=60 to x=360. Everything above that line is the filling visible. Right.
So the fillings should be a mound sitting on the line y=200, spanning roughly x=70..350, with the peak at y≈115.
Then the whole taco occupies y=105..350, which is vertically centered-ish in the 420 viewBox. Good; the glow circle at (210,240).
Let me write the fillings:
```svg
<!-- lettuce -->
<path d="M62 202 C66 176 78 156 100 148 C104 128 124 112 146 118 C156 100 184 92 200 108 C216 92 246 96 256 116 C280 108 306 118 314 142 C336 150 350 172 352 202 Z" fill="#6EA23E"/>
<path d="M62 202 C66 176 78 156 100 148 C104 128 124 112 146 118 C156 100 184 92 200 108 C216 92 246 96 256 116 C280 108 306 118 314 142 C336 150 350 172 352 202 Z" fill="none" stroke="#4C7A2A" stroke-width="3" opacity=".5"/>
```
Then a second, lighter green layer for highlights:
```svg
<path d="M120 160 C130 138 152 132 168 146 C180 128 208 128 216 148 C236 140 252 152 254 172 C232 186 152 186 120 160Z" fill="#84BB4E" opacity=".85"/>
```
Meat chunks (5-6 rounded rects rotated):
```svg
<g fill="url(#tMeat)">
<rect x="112" y="158" width="52" height="24" rx="11" transform="rotate(-9 138 170)"/>
<rect x="168" y="146" width="58" height="24" rx="11" transform="rotate(6 197 158)"/>
<rect x="232" y="156" width="50" height="24" rx="11" transform="rotate(-7 257 168)"/>
<rect x="150" y="178" width="56" height="22" rx="11" transform="rotate(4 178 189)"/>
<rect x="226" y="180" width="54" height="22" rx="11" transform="rotate(-5 253 191)"/>
</g>
```
Hmm, but they should be behind the lettuce? Actually chunks of bulgogi sit among the lettuce. Since these are all above y=200, and the shell covers the bottom, the arrangement will read fine. Add a subtle darker outline: `stroke="#3A130A" stroke-width="1.5" opacity=".35"`.
Kimchi chunks:
```svg
<g fill="#E5322B">
<rect x="128" y="136" width="34" height="20" rx="8" transform="rotate(-14 145 146)"/>
<rect x="196" y="122" width="38" height="20" rx="8" transform="rotate(10 215 132)"/>
<rect x="262" y="140" width="34" height="20" rx="8" transform="rotate(-8 279 150)"/>
</g>
```
With lighter highlights on top (#FF6A5A small rects).
Crema drizzle:
```svg
<path d="M92 190 C112 168 134 196 156 178 C176 162 194 194 216 176 C236 160 252 190 274 172 C294 156 314 182 330 168" fill="none" stroke="#FFF8EC" stroke-width="8" stroke-linecap="round" opacity=".95"/>
```
But that squiggle hits y=196 near the shell top, which is fine (the shell covers from 200 down).
Sesame seeds: tiny ellipses at random points above y=200.
```svg
<g fill="#FFF0D2">
<ellipse cx="150" cy="150" rx="4" ry="2.6" transform="rotate(-20 150 150)"/>
...
</g>
```
Shell:
```svg
<path d="M60 200 A150 150 0 0 0 360 200 Z" fill="url(#tShell)" stroke="#8A4A12" stroke-width="3"/>
<g clip-path="url(#tShellClip)">
<!-- toasted spots -->
<ellipse cx="140" cy="250" rx="26" ry="16" fill="#B4611A" opacity=".35"/>
<ellipse cx="250" cy="280" rx="34" ry="18" fill="#B4611A" opacity=".3"/>
<ellipse cx="200" cy="320" rx="22" ry="12" fill="#B4611A" opacity=".28"/>
<!-- highlight -->
<path d="M110 215 C130 265 170 300 210 320" stroke="#FFDC9E" stroke-width="14" fill="none" opacity=".45" stroke-linecap="round"/>
</g>
```
Hmm, the highlight arc should follow the shell's curvature. A nice arc: `M110 230 A 120 120 0 0 0 210 318` ... let's just use a curved path from the upper-left of the shell down to the bottom-center. Fine.
Also add a thin darker band along the top rim to suggest the fold: `<path d="M60 200 H360" stroke="#A55A18" stroke-width="4"/>`? That's a straight line; instead, add an ellipse rim. I'll add a rounded rect at the top edge: `<rect x="60" y="194" width="300" height="12" rx="6" fill="#C9711D"/>` clipped... it'd stick out at the sides. Just skip, or add a subtle dark line with opacity .3.
I'll add: `<path d="M60 200 A150 150 0 0 0 360 200" fill="none" stroke="#8A4A12" stroke-width="3"/>` — that's the bottom arc, already the outline. Fine.
Add the second tortilla behind the front one for a double-shell look? Nice touch: a slightly offset arc behind. Skip.
Now, the drop shadow under the taco: an ellipse at the bottom: `<ellipse cx="210" cy="368" rx="120" ry="16" fill="#000" opacity=".10"/>`. Good.
Floating stickers around the taco:
- A chili pepper SVG at top-left.
- A lime wedge at the bottom-right.
- A cilantro leaf at the top-right.
- Sesame seeds scattered.
Let me create the chili:
```svg
<svg viewBox="0 0 60 100" class="fl fl-chili">
<path d="M30 18 C48 30 52 60 36 82 C28 92 12 96 6 88 C20 84 34 66 34 46 C34 34 32 24 30 18Z" fill="#E5322B" stroke="#17100E" stroke-width="3" stroke-linejoin="round"/>
<path d="M30 18 C26 10 16 6 8 10" fill="none" stroke="#6EA23E" stroke-width="8" stroke-linecap="round"/>
</svg>
```
Good enough. The chili shape is a tapered curve. Nice.
A lime wedge:
```svg
<svg viewBox="0 0 80 80">
<circle cx="40" cy="40" r="34" fill="#C9F04A" stroke="#17100E" stroke-width="3"/>
<circle cx="40" cy="40" r="27" fill="#E8FFA3" stroke="#17100E" stroke-width="2.5"/>
<g stroke="#17100E" stroke-width="2">
<path d="M40 13 V67"/><path d="M13 40 H67"/> ...
</g>
</svg>
```
Better: use a wedge (a semicircle) instead of a full circle. Let's do a full lime wheel with 8 segments — reads as a lime slice. With seeds. Fine.
I'll keep the floating elements subtle: opacity ~.9, small, with float animation.
Positioning: `.hero-art{position:relative}` and the floaters `position:absolute` with percentages. Hide them below 700px? They could get cramped. I'll scale them down on mobile and keep two of them.
Now: sticker badge. `.sticker{position:absolute; right:2%; top:8%; width:112px;height:112px;border-radius:50%;background:var(--lime);border:3px solid var(--ink); display:grid; place-items:center; text-align:center; font-weight:900; font-size:12px; line-height:1.1; transform:rotate(-12deg); box-shadow:4px 4px 0 var(--ink); letter-spacing:.02em}`. Text: "SOLD OUT<br>BY 8PM". Add a star. Maybe animate a slow rotate. Also add a second sticker "LA'S BEST".
Careful: the sticker must not overlap badly on mobile. Keep `transform: scale(.85)` on small screens.
Now the "Find" section design. Full-width dark ink block with a red accent? Let's make it a cream section with a huge red card containing the info. Or the "Find" section has a dark background with cream text. Let's have the section background ink with cream text, rounded? We'll do full-bleed ink with cream cards inside. Actually the CTA at the bottom is also ink. Let's differentiate: Find section = cream with a red card + white schedule card. Hmm.
Plan:
- hero: cream
- ticker: red
- menu: cream
- find: ink (dark) — strong contrast, gives the page rhythm
- story: cream
- CTA: red gradient with a big headline
- footer: ink
That's good rhythm.
Find section (ink bg):
```
.find { background: var(--ink); color: cream; }
```
Inside: heading in cream, "01" numbering in gold. Grid: left card (dark-2 bg with border cream/20), right schedule.
Actually with the brutalist style, on dark: cards with `border:2.5px solid #3a2a22` and `background:#221815`. Hmm, but the brutalist offset shadow is ink. For the dark section, use a lime card for the "today" info: bg lime, ink text, ink border, offset shadow in red. That pops. And the schedule list on dark with cream text.
Let's do:
- Left: a lime card with the status, location, address, hours, buttons.
- Right: schedule rows with day letter in a small chip, place name, hours; today's row highlighted (red bg chip / red text).
Good.
Story section: two-column: left a big quote in heavy type, right the stats + story paragraph. On cream.
CTA: red bg with a big "COME HUNGRY." and a form. Maybe use the gold as accent.
Let's write the code now. I'll be thorough but keep the file manageable (~900 lines).
One more: add a "skip to content"? Not needed.
Accessibility: alt text for the SVG (aria-hidden for decorative), buttons with aria-labels, etc.
Let me write.
```css
/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth; -webkit-text-size-adjust:100%}
body{margin:0;background:var(--cream);color:var(--ink);font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:17px;line-height:1.55;overflow-x:hidden;-webkit-font-smoothing:antialiased}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit}
h1,h2,h3,h4{margin:0;font-family:"Arial Black","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:900;letter-spacing:-.035em;line-height:.9;text-transform:uppercase}
p{margin:0}
ul{margin:0;padding:0;list-style:none}
```
Careful with `.hero h1` line-height .86.
Container: `.wrap{width:100%;max-width:1240px;margin:0 auto;padding:0 clamp(18px,4vw,40px)}`.
Nav:
```css
.nav{position:sticky;top:0;z-index:50;display:flex;align-items:center;gap:24px;padding:12px clamp(16px,3.5vw,36px);background:rgba(255,244,227,.86);backdrop-filter:blur(12px);border-bottom:2.5px solid var(--ink)}
.brand{display:flex;align-items:center;gap:10px;margin-right:auto}
.brand svg{width:38px;height:38px}
.brand b{display:block;font-family:"Arial Black",...;font-size:17px;letter-spacing:-.02em;text-transform:uppercase;line-height:1}
.brand i{display:block;font-style:normal;font-size:10px;letter-spacing:.16em;text-transform:uppercase;opacity:.6;margin-top:3px}
.nav-links{display:flex;gap:26px;font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}
.nav-links a{position:relative;padding:4px 0}
.nav-links a::after{content:"";position:absolute;left:0;bottom:0;width:0;height:2.5px;background:var(--red);transition:width .25s}
.nav-links a:hover::after{width:100%}
```
Buttons:
```css
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:14px 22px;border-radius:999px;border:2.5px solid var(--ink);background:var(--cream);color:var(--ink);font-weight:800;font-size:14px;letter-spacing:.04em;text-transform:uppercase;cursor:pointer;box-shadow:4px 4px 0 var(--ink);transition:transform .15s, box-shadow .15s, background .15s}
.btn:hover{transform:translate(-2px,-2px);box-shadow:6px 6px 0 var(--ink)}
.btn:active{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--ink)}
.btn-primary{background:var(--red);color:#fff}
.btn-sm{padding:10px 16px;font-size:12px;box-shadow:3px 3px 0 var(--ink)}
.btn-lime{background:var(--lime)}
.btn-lg{padding:18px 30px;font-size:16px}
```
Hero:
```css
.hero{position:relative;overflow:hidden;padding:clamp(28px,4vw,56px) 0 clamp(48px,6vw,80px)}
.hero-inner{display:grid;grid-template-columns:1.02fr .98fr;gap:clamp(20px,4vw,48px);align-items:center;max-width:1240px;margin:0 auto;padding:0 clamp(18px,4vw,40px)}
@media(max-width:860px){.hero-inner{grid-template-columns:1fr}}
```
Pill:
```css
.pill{display:inline-flex;align-items:center;gap:9px;padding:8px 15px 8px 12px;border:2.5px solid var(--ink);border-radius:999px;background:#fff;font-size:12.5px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;box-shadow:3px 3px 0 var(--ink)}
.dot{width:9px;height:9px;border-radius:50%;background:#2BB673;box-shadow:0 0 0 0 rgba(43,182,115,.6);animation:pulse 2s infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(43,182,115,.55)}70%{box-shadow:0 0 0 9px rgba(43,182,115,0)}100%{box-shadow:0 0 0 0 rgba(43,182,115,0)}}
```
Hmm, the dot color could also change with the open state. Use `.dot.closed{background:#E5322B}`.
h1:
```css
.hero h1{font-size:clamp(46px,8.4vw,110px);line-height:.84;margin:18px 0 0;letter-spacing:-.045em}
.hero h1 .hl{color:var(--red);-webkit-text-stroke:3px var(--ink);paint-order:stroke fill}
```
Hmm, -webkit-text-stroke with paint-order stroke fill works in Chrome. But with a 3px stroke on a 110px font, the stroke is drawn half inside/half outside. Fine.
Actually maybe skip the stroke and use a red "LOCO." with a lime highlighter behind? I'll do text-stroke since it's punchy. Let's use `-webkit-text-stroke:2.5px var(--ink)` — hmm, at 110px that's thin. Use 4px. Let's test mentally: the stroke will thicken the letters. Should look bold and graphic. And the red letters with ink outline. Good.
Hmm, one risk: `-webkit-text-stroke` with the color on the outside can make the counters (holes) fill in. At 4px on 110px text, holes like in "O" and "C" (about 30px wide) would shrink by 2px each side but still be visible. Fine.
Wait, "LOCO" — the pill above and the "Loco" accent... Let's make the h1 exactly:
```
KOREAN
MEXICAN
LOCO.
```
Then ".hl" wraps "LOCO." in red.
Lede: `font-size:clamp(15px,1.35vw,18px); max-width:42ch; margin-top:20px; color:#3B2B22; font-weight:500`. The default body weight 400; fine.
Hero meta row: `display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-top:26px; font-size:12.5px; text-transform:uppercase; letter-spacing:.08em; font-weight:700; color:#5B4438`. Stars in gold.
Rotator: `#rotator{display:inline-block; min-width:...}` — the text changes; to avoid layout shift, use a fixed-width inline-block? Text width varies. It's fine; it will just shift. Actually a shifting line looks janky. I'll set the rotator to `display:inline-block; min-width: 150px;` hmm. Alternative: put "Now serving: X" on its own line under the meta. Let's put it as a separate line that's stable-ish, using a transition fade on the text change. I'll add a fade class: set opacity 0 then change text and opacity 1. Slight jitter acceptable. Use `white-space:nowrap` and the longest item "Korean Fried Chicken" — the container wouldn't resize if I set `min-width: 11ch`. Actually with `white-space:nowrap` and `min-width`, the width will grow when the text is longer than the min. Meh — the container is in the meta row which can wrap. It's fine.
Better: put the rotator inside a small "specials board" line: `<span class="rot-label">Now serving</span> <b id="rotator">...</b>` with the b having a fixed width and `overflow:hidden; text-overflow:ellipsis`. Let's do `display:inline-block;min-width:180px`. Then short items leave whitespace. Hmm, better: keep it in the meta row as the last item, it wraps as needed. Fine.
Actually, simpler: drop the rotator from the hero and use it in the ticker? The ticker already scrolls. I'll keep the rotator in the hero meta but as a distinct mini-element with a fixed min-width of 170px. Good enough.
Let me now write the whole file. I'll go step by step.
For the reveal animation, I'll use:
```css
.reveal{opacity:0;transform:translateY(24px);transition:opacity .7s cubic-bezier(.2,.7,.3,1),transform .7s cubic-bezier(.2,.7,.3,1)}
.reveal.in{opacity:1;transform:none}
```
And to be safe against a JS failure, only apply `.reveal` opacity 0 when `html.js` is set... but if the JS fails, the reveal never happens. The IO code is simple and robust. I'll add a failsafe: `setTimeout(()=>document.querySelectorAll('.reveal').forEach(el=>el.classList.add('in')), 2500)`. That guarantees visibility. Good.
Now, writing all the content.
Menu items (6):
1. SEOUL CITY BULGOGI — $12 — "12-hour marinated ribeye, gochujang crema, pickled onion, cilantro, sesame." Heat 2. Tag: Fan favorite.
2. KIMCHI CRUJIENTE — $11 — "Crispy pork belly, house kimchi, charred pineapple, cotija, lime." Heat 3. Tag: "Spicy".
3. EL LOCO — $13 — "Gochujang-glazed short rib, avocado mash, pickled jalapeño, crispy shallot." Heat 2. Tag: "New".
4. K-FRIED CHICKEN — $12 — "Double-fried thigh, soy-garlic glaze, sesame slaw, sriracha crema." Heat 3.
5. BULGOGI FRIES — $10 — "Crinkle fries, bulgogi beef, cheese sauce, kimchi, scallion, fried egg." Heat 1. Tag: "Shareable".
6. KIMCHI QUESO — $8 — "Molten Oaxaca, kimchi, gochugaru oil, warm tortillas." Heat 2.
Prices in $.
I can add a small "V" vegetarian option? Not needed.
Note under the grid: "Corn tortillas, always. Gluten-free on request. Cash & card. We sell out — that's not a marketing line."
Reveal: each card gets a stagger via `transition-delay` set inline via style or nth-child. I'll set `--d` inline and use `transition-delay: var(--d,0s)`.
Simpler: use `.reveal` on the container and stagger by CSS nth-child on the cards with `transition-delay:calc(var(--i)*60ms)` where --i is set inline. I'll just write inline `style="--i:0"` etc.
Hmm, keep it simpler: the .reveal class with IO and a `data-delay` attribute applied in JS. Let me just do CSS: `.menu-grid .reveal:nth-child(2){transition-delay:.08s}` etc. Meh. I'll add inline style="transition-delay:.05s".
OK writing the final HTML now. I'll be careful with the quotes inside the data URI for the grain.
Grain data URI:
```
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
```
This produces a noise image. With 5% opacity over the page. Good.
I'll put it on `body::after` with `position:fixed;inset:0;z-index:9999;pointer-events:none;opacity:.05;mix-blend-mode:multiply`.
Careful with `mix-blend-mode` on a fixed element plus backdrop-filter — can be heavy but fine.
Now writing the SVG taco. One more consideration: the hero art size. On desktop, `width:min(100%,540px)`.
Also the `filter: drop-shadow(...)` on the taco SVG: a soft sepia shadow. Good.
Let me write the parallax:
```js
const art = document.querySelector('.hero-art');
if(art && window.matchMedia('(pointer:fine)').matches){
window.addEventListener('mousemove', e=>{
const r = art.getBoundingClientRect();
const x = (e.clientX - (r.left+r.width/2)) / r.width;
const y = (e.clientY - (r.top+r.height/2)) / r.height;
art.style.transform = `translate3d(${x*14}px,${y*12}px,0)`;
});
}
```
But that overrides the transform on the art which might be used elsewhere. The floaters are positioned inside, so fine. Add `transition:transform .3s ease-out` maybe not, since it's following the mouse: use `transition: transform .18s ease-out`. Hmm, that would lag. Use `will-change`. Fine.
Actually throttle with rAF. Let's just do it directly — it's cheap enough.
Let's also handle the reduced-motion preference: disable animations.
Let me write the final code.
For the schedule list, generate:
```js
const SCHEDULE = [
{d:'Mon', place:'Arts District', addr:'4th & Alameda', open:11.5, close:21, hrs:'11:30a – 9p'},
{d:'Tue', place:'Silver Lake', addr:'Sunset Junction', open:11.5, close:21, hrs:'11:30a – 9p'},
{d:'Wed', place:'Downtown LA', addr:'Grand Central Market', open:11, close:20, hrs:'11a – 8p'},
{d:'Thu', place:'Echo Park', addr:'Sunset & Alvarado', open:11.5, close:21, hrs:'11:30a – 9p'},
{d:'Fri', place:'West Hollywood', addr:'Plummer Park', open:17, close:24, hrs:'5p – 12a'},
{d:'Sat', place:'Smorgasburg', addr:'ROW DTLA', open:10, close:16, hrs:'10a – 4p'},
{d:'Sun', place:'Private Events', addr:'You bring the crowd', open:null, close:null, hrs:'Booked'},
];
```
Then `const todayIdx = new Date().getDay();` and `const byName = {Sun:0,...}`. Map: `days[todayIdx]` where `days=['Sun','Mon',...]`. Then `SCHEDULE.find(s=>s.d===days[todayIdx])`.
The status: compute now hours. If `open==null` → not open. And "opens next" — find the next day with hours. Let's just write:
- if open: `Open now · ${place} · till ${closeLabel}`
- else if today has open: `Opens today at ${openLabel}`
- else: `Closed today · back tomorrow`
For the find card, I'll update:
- `#findTitle` → today's place
- `#findAddr` → today's addr
- `#findHours` → today's hrs
- `#statusText` → the status string
Also the hero pill uses `#heroStatus` (same text, shorter). I'll use one text for both, written into both elements. Keep it short: `Open now · till 9p` and in the card `Open now · closes 9pm`.
Simplify: one status string used in both. `Open now · Silver Lake · till 9p`. On mobile that's long for the pill but it can wrap. I'll allow the pill to wrap.
OK let's write it.
Also the day rows: highlight today's row with a red background and cream text? On a dark section, with red bg and cream text = nice. Add a "TODAY" chip.
Let me write the whole HTML now, carefully.
Also, a nice touch: the "Directions" button — use Google Maps link? It's an external link which might be blocked, but a link is fine (no network request until click). I'll use `href="#"` with a prevented default? Better to keep href="#find" to avoid navigation. Or use `https://maps.google.com/?q=...` — it would open a new tab; window.open is blocked, but a normal anchor with target=_blank... "window.open is blocked" — a plain anchor is a user-initiated navigation which might be allowed. But to be safe, use `href="#"` with JS preventing default. Hmm, but then clicking "Get directions" does nothing. In a sandboxed iframe the navigation is blocked. Let's make it show a little toast "3820 Sunset Blvd — see you there" instead of navigating. Cute. I'll make the button onclick show a small inline confirmation. Actually simpler: make the directions button a `<a href="#find">` with a tooltip. Meh. Let's have it toggle a short "copied address" toast. But no clipboard API (needs permission). I'll just show a toast: "3820 Sunset Blvd · look for the red truck". Nice.
I'll implement a tiny toast div.
Now the CTA form: an email input + submit. On submit: preventDefault, check validity, show "You're on the list. See you at the window." and clear. Use a simple `required` on the input with `type=email`. Careful: native validation bubbles appear — that's fine.
Alright. Writing now for real.
One more thought on the header: sticky with backdrop blur. The hero is directly below. Good.
Let me write the story section content:
```
<section class="story" id="story">
<div class="wrap story-grid">
<div class="story-left">
<span class="kicker">Our story</span>
<h2>Two kitchens.<br>One truck.<br><span class="hl">Zero chill.</span></h2>
</div>
<div class="story-right">
<p class="lead">Mina Park grew up on her grandmother's galbi in Koreatown. Hector Ruiz learned to braise at his abuela's taqueria in Boyle Heights. They met at a food festival, argued about salsa, and now they share a 24-foot truck and a very loud sound system.</p>
<p>Every batch of kimchi is buried in the walk-in for 48 hours. Every ribeye sits in soy, pear, and garlic for twelve. The tortillas are pressed to order — always corn, always warm. This is not fusion for the sake of it. It's the food we actually want to eat.</p>
<div class="stats">
<div><b>12</b><span>hour marinade</span></div>
<div><b>48</b><span>hour kimchi</span></div>
<div><b>4.9</b><span>1,284 reviews</span></div>
</div>
</div>
</div>
</section>
```
CTA:
```
<section class="cta">
<div class="wrap cta-inner">
<h2>Come hungry.<br>Leave <span class="hl">loco.</span></h2>
<p class="cta-sub">The line moves fast. The truck doesn't. Check this week's spots, then come find the red truck with the loud music.</p>
<div class="cta-actions">
<a class="btn btn-lg btn-ink" href="#find">Find the truck</a>
<a class="btn btn-lg btn-outline" href="#menu">View the menu</a>
</div>
<form class="signup" id="signup">
<label class="sr-only" for="email">Email address</label>
<input id="email" type="email" placeholder="you@email.com" required>
<button class="btn btn-lime" type="submit">Join the Loco List</button>
<span class="form-msg" id="formMsg"></span>
</form>
</div>
</section>
```
The form with an input and button inline.
Footer more compact.
I need to be careful that the CTA section is red — the `btn-lime` on red pops. And `.btn-ink` is ink with cream text.
Alright, code time. I'll write it out fully.
Actually one concern: too many sections could make this long, but that's fine. The key is the first screen.
Let me write out all the CSS.
```css
:root{
--ink:#17100E; --ink-2:#241814; --cream:#FFF4E3; --cream-2:#F8E7CE;
--red:#E5322B; --red-d:#B31217; --gold:#FFB03B; --lime:#C8F04A; --green:#5F8D3E;
}
```
Note: `--lime` in the original. Fine.
Let me write the final code.
For the hero h1, I want the "LOCO." red with the ink stroke. Also maybe the period in gold. Nah.
Also I'll add a small rotated "taco sauce" scribble? Skip.
Writing final.
I'll double-check `@media (max-width:860px)` rules: hero-inner single column, art max-width 380px margin auto, hero h1 clamp smaller.
For very small screens (375px), the nav: brand + Order button. Hide `.nav-links`. Good.
Menu grid: `grid-template-columns:repeat(3,1fr)` at ≥980px; `repeat(2,1fr)` at ≥640; 1 column below.
Find grid: 2 columns ≥900, 1 below.
Story grid: 1fr 1.1fr ≥900, 1 below.
Stat row: 3 cols always.
CTA: centered text.
Let me now also handle the ticker content. Items: "GOCHUJANG EVERYTHING", "BULGOGI", "KIMCHI", "SOLD OUT BY 8", "EL LOCO", "KOREAN TACOS", "LA". With a small star/asterisk separator.
```html
<div class="ticker-wrap">
<div class="ticker">
<div class="ticker-track">
<span>Gochujang everything</span><i>★</i><span>Bulgogi</span><i>★</i>...
</div>
<div class="ticker-track" aria-hidden="true">...duplicate...</div>
</div>
</div>
```
For seamless: `.ticker{display:flex; width:max-content; animation:scroll 26s linear infinite}` and translateX(-50%) of the whole track? If the ticker contains two identical tracks side by side, animating translateX(-50%) works. Let's do:
```css
.ticker{display:flex;width:max-content;animation:marquee 30s linear infinite}
.ticker-track{display:flex;align-items:center;gap:28px;padding-right:28px}
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
```
With two equal tracks, -50% of the total width = one track's width.
The ticker band: `background:var(--red); color:#fff; border-top:3px solid var(--ink); border-bottom:3px solid var(--ink); padding:12px 0; font-weight:900; text-transform:uppercase; letter-spacing:.04em; font-size:15px;` and rotate -1.4deg on the inner ticker with width 110% margin-left -5%. Hmm, the wrapper has overflow hidden.
```css
.ticker-wrap{overflow:hidden;padding:26px 0;margin:10px 0}
.ticker{transform:rotate(-1.4deg);width:106%;margin-left:-3%;background:var(--red);border-top:3px solid var(--ink);border-bottom:3px solid var(--ink);padding:11px 0;overflow:hidden;display:flex;width:106%;...}
```
Hmm, `.ticker` has both display:flex and the tracks. Let me restructure: `.ticker` (rotated band, overflow hidden) > `.ticker-track` ×2? No, I need the animation to move both tracks together. Put the band as the rotated wrapper and the animating flex inside:
```html
<div class="ticker-wrap">
<div class="ticker">
<div class="ticker-anim">
<div class="ticker-track">...</div>
<div class="ticker-track">...</div>
</div>
</div>
</div>
```
```css
.ticker{transform:rotate(-1.4deg);background:var(--red);border-top:3px solid var(--ink);border-bottom:3px solid var(--ink);padding:12px 0;overflow:hidden;width:106%;margin-left:-3%}
.ticker-anim{display:flex;width:max-content;animation:marquee 34s linear infinite}
.ticker-track{display:flex;align-items:center;gap:26px;padding-right:26px;color:#fff;font-weight:900;font-size:14px;letter-spacing:.12em;text-transform:uppercase;white-space:nowrap}
.ticker-track i{color:var(--gold);font-style:normal}
```
Good.
Now the whole thing. Let me write it.
I also want to ensure the first paint shows something interesting — the hero is visible with the taco. Good.
Final check on the `-webkit-text-stroke` + `paint-order: stroke fill` — `paint-order` works for SVG text and CSS text? In Chrome, `paint-order` applies to text with `-webkit-text-stroke`. Actually `paint-order` support for HTML text: Chrome supports `paint-order` on text since ~Chrome 68? I believe it applies to SVG and HTML text. If not supported, the stroke paints over the fill, which at 4px on a 110px font would still look OK (thick letters). It's fine either way.
Actually, maybe I should avoid text-stroke since it could look ugly/aliased. Alternative: use a solid red with a lime "highlight" behind the last word (a skewed box). Let's do a safer, cooler approach: `LOCO.` in red, with an ink offset shadow (text-shadow: 5px 5px 0 var(--ink))? That's a nice brutalist look with no stroke. Hmm, but red text with an ink shadow = muddy. Or ink text with a red shadow — `text-shadow: 4px 4px 0 var(--red)` on the ink h1. That's a classic bold look. Let's do: h1 is ink, and the `.hl` span is red with a "highlight" lime swipe behind?
Decision: h1 all ink; `.hl` gets `color:var(--red)` with `-webkit-text-stroke: 3px var(--ink)`. I'll go with the stroke — I'm fairly confident it looks good. Hmm, risk assessment: if the stroke looks bad, the whole design suffers. Let's test with a safer variant:
`.hl{color:var(--red)}` and add a wrapped `<span class="hl">` with `background:var(--lime); padding:0 .08em; box-shadow: 8px 8px 0 var(--ink);`? Highlighted text on a "loco" — that's very food-truck. Actually the lime highlight behind red letters could look great. But the h1 lines are big (110px); a lime highlight rectangle behind "LOCO." would be a strong graphic element. Combined with the red letters. Hmm, dark red on lime might be less legible? Red #E5322B on lime #C8F04A — decent contrast.
I'll do: `.hl{color:var(--cream); background:var(--red); padding:0 .1em .04em; -webkit-box-decoration-break:clone; box-decoration-break:clone; display:inline-block; transform:rotate(-1.5deg);}` with an ink border and shadow. Hmm, transform on inline-block inside a heading — fine.
Simplest and safest: `.hl{color:var(--red)}` — the word "LOCO." in red, everything else ink. Clean, safe, still striking given the size. And add a hand-drawn underline scribble SVG underneath? Overkill.
I'll go with red + a subtle offset: `text-shadow: 6px 6px 0 rgba(23,16,14,.14)`. Clean. Decision made: no stroke.
Hmm, but let me add a bit more punch: use a red underline swipe under the h1 (a wavy SVG path). Cheap and effective. Let's add an SVG squiggle below "LOCO." — actually, the h1 is 3 lines; a squiggle under the last line that's the same red would be nice. I'll skip it; the hero already has plenty.
OK, writing.
One thing: `font-family:"Arial Black"` on the h1 with `font-weight:900` — on a machine without Arial Black, it falls back to Helvetica bold. Good.
Let's finalize the h1 sizing: `font-size:clamp(44px,8.2vw,104px)`. At 1280: 104.9 → 104. Three lines at 0.84 line-height = 262px tall. Plus the pill (36px) + margin 18 → 316. Plus lede 3 lines × 27 = 81 + margin 20 → 417. Plus buttons 54+22 = 493. Plus meta 30+26 = 549. Plus hero padding 112 → 661. Plus nav 66 = 727. Fits in 800 with 73px to spare.
The art at 540px tall is centered against 549px of text. Good.
At 375px: h1 = 8.2vw=30.75 → clamp min 44px. 3 lines × 0.84 = 111px. Nice.
Let me write the mobile nav: the "Order now" button becomes "Find us". Fine, same.
Write it.
For the toast:
```css
.toast{position:fixed;left:50%;bottom:26px;transform:translate(-50%,20px);background:var(--ink);color:var(--cream);padding:14px 22px;border-radius:14px;border:2.5px solid var(--cream);font-weight:700;font-size:14px;z-index:200;opacity:0;pointer-events:none;transition:.3s}
.toast.show{opacity:1;transform:translate(-50%,0)}
```
Hmm, `border: 2.5px solid var(--cream)` on ink over the page — fine.
Now the JS.
```js
(function(){
const $ = (s,c=document)=>c.querySelector(s);
const $$ = (s,c=document)=>[...c.querySelectorAll(s)];
...
})();
```
Reveal:
```js
const io = 'IntersectionObserver' in window ? new IntersectionObserver((es)=>{
es.forEach(e=>{ if(e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target);} });
},{threshold:.12, rootMargin:'0px 0px -40px 0px'}) : null;
$$('.reveal').forEach(el=>{ if(io) io.observe(el); else el.classList.add('in'); });
```
Careful: `io` shadows the assignment inside the callback. Use `const io = new IntersectionObserver(...)` and inside reference `io` — TDZ? The callback runs later so it's fine. But if IntersectionObserver is unsupported, the expression is null and calling `new` is guarded. OK.
Also the failsafe timeout.
Now, the hero art parallax. And the sticker rotation.
Let me write everything now.
For the "today" highlight in the schedule, generate rows:
```js
function renderSchedule(){
const list = $('#schedList');
list.innerHTML = SCHEDULE.map(s=>{
const isToday = s.d === todayName;
return `<li class="${isToday?'is-today':''}">
<span class="s-day">${s.d}</span>
<span class="s-place">${s.place}<em>${s.addr}</em></span>
<span class="s-hrs">${s.hrs}</span>
${isToday?'<span class="s-now">Today</span>':''}
</li>`;
}).join('');
}
```
Hmm, grid layout for the li. Use `display:grid; grid-template-columns: 44px 1fr auto auto; align-items:center; gap:14px;`.
The `em` inside the place needs `display:block; font-style:normal; font-size:11px; opacity:.6;`. On mobile that might be too much; hide `em` below 480px.
Now, writing the final file. Let me be careful with the template literals inside the script (no conflicts with `</script>`).
Let me produce it.
Also: should I add a `prefers-reduced-motion` guard? Yes, quick.
Writing everything now — final answer below.
One more consideration on the "Find the truck" directions link: `href="#find"` is a no-op scroll. I'll use `href="#"` with `onclick` prevented via JS and the toast shown. Actually with `href="#"` and preventDefault, fine.
Write the code.
For the hero art stickers, I'll add:
- `.sticker` (circle, lime, rotated) "SOLD OUT BY 8PM"
- `.fl-chili`, `.fl-lime`, `.fl-leaf`
- the glow
Positions:
- chili: top 6%, left 0%, rotate -18deg, w 62px.
- lime: bottom 10%, right 2%, rotate 12deg, w 88px.
- leaf: top 12%, right 8%, w 54px.
Small decorative. Good.
Now, the `.hero-art` needs `position:relative` and the taco SVG inside a `.taco-wrap` with a float animation.
Let me write it out.
Final structure of the hero art:
```html
<div class="hero-art">
<div class="glow"></div>
<div class="taco-float">
<svg class="taco" viewBox="0 0 420 400">...</svg>
</div>
<div class="sticker">Sold out<br>by 8pm</div>
<svg class="fl fl-chili" viewBox="0 0 60 100">...</svg>
<svg class="fl fl-lime" viewBox="0 0 80 80">...</svg>
<svg class="fl fl-leaf" viewBox="0 0 60 60">...</svg>
</div>
```
viewBox 0 0 420 400 for the taco so the shell fits: rim at y=200, dome to y=350, plus shadow to 368. Let me use 0 0 420 400 to be safe... but the fillings go up to y=110. So the content spans 100..370. Center around 235. Fine, use viewBox="0 0 420 400" and the whole thing is fine.
Wait, my earlier coordinates assumed the shell center at (210,200), radius 150: `M60 200 A150 150 0 0 0 360 200 Z` → the bottom of the dome at y=350. In a 400-tall viewBox, there's 50px below. OK. And the shadow ellipse at cy=372 would be near the edge. Let me use viewBox="0 0 420 400" and put the shadow at cy=370, rx=110, ry=14. Fine.
Writing now.
For the lime float SVG:
```svg
<svg class="fl fl-lime" viewBox="0 0 80 80" aria-hidden="true">
<circle cx="40" cy="40" r="30" fill="#C8F04A" stroke="#17100E" stroke-width="4"/>
<circle cx="40" cy="40" r="22" fill="#E9FFA8" stroke="#17100E" stroke-width="3"/>
<g stroke="#17100E" stroke-width="2.5" stroke-linecap="round">
<path d="M40 18v44M18 40h44M25 25l30 30M55 25L25 55"/>
</g>
</svg>
```
Hmm, 8 spokes — ok but the circle r=22 and the lines going to 18/62 exceeds the inner circle. Let me clip: lines from r=0 to r=21: e.g. `M40 40 L40 19` vertically, `M40 40 L61 40`, etc. Diagonals at 45°: 21*0.707=14.8 → (54.8,25.2). Let's use `M40 40 L40 19`, `M40 40 L40 61`, `M40 40 L19 40`, `M40 40 L61 40`, `M40 40 L25.1 25.1`, `M40 40 L54.9 54.9`, `M40 40 L54.9 25.1`, `M40 40 L25.1 54.9`. That's a nice wheel. Good.
The chili:
```svg
<svg class="fl fl-chili" viewBox="0 0 60 100" aria-hidden="true">
<path d="M30 20 C46 32 50 62 34 84 C27 93 13 96 8 88 C22 82 34 64 34 46 C34 34 32 26 30 20 Z" fill="#E5322B" stroke="#17100E" stroke-width="4" stroke-linejoin="round"/>
<path d="M30 20 C26 12 16 9 8 13" fill="none" stroke="#5F8D3E" stroke-width="9" stroke-linecap="round"/>
</svg>
```
Hmm, the stem path starts at (30,20) which is the chili's top. Good.
The leaf (cilantro):
```svg
<svg class="fl fl-leaf" viewBox="0 0 60 60" aria-hidden="true">
<path d="M30 54 C30 40 12 36 8 20 C20 16 30 26 30 38 C30 26 40 16 52 20 C48 36 30 40 30 54Z" fill="#7BB04A" stroke="#17100E" stroke-width="3" stroke-linejoin="round"/>
</svg>
```
Looks like a two-lobed leaf. Fine.
Now, writing the whole file.
I also want to add a small `::selection` style. Nice touch.
Let me now write the code in full.
Careful with the HTML escaping: `&` → `&`.
Final answer below.