Food truck websiteOne-line
Nemotron 3 Ultra (free)
by NVIDIAReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 3 min 21 s
- Cost
- $0
- Output tokens
- 17,793
- Spent thinking
- 0 tokens
- Speed
- 89 tok/s
- Console errors
- 0
- First token after
- 731 ms
- First visible text after
- 731 ms
- Prompt tokens
- 381
- Code size
- 51.3 KB
- Finish reason
- stop
- Served by
- Nvidia
- Model id
nvidia/nemotron-3-ultra-550b-a55b:free- Reasoning sent
{"effort":"none"}- Max output
- 32,000 tokens
- Generated
- Nov 9, 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 · 1428 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kimchi Loco - Korean Taco Food Truck</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Anton&family=Space+Grotesk:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root {
--bg: #0d0d0d;
--fg: #fafafa;
--muted: #a3a3a3;
--accent: #ff3b30;
--accent-dim: #cc2f26;
--gold: #ffd700;
--card: #1a1a1a;
--border: #333;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
body {
font-family: 'Space Grotesk', sans-serif;
background: var(--bg);
color: var(--fg);
overflow-x: hidden;
line-height: 1.6;
}
.font-display { font-family: 'Anton', sans-serif; letter-spacing: 0.05em; }
/* Background canvas */
#bg-canvas {
position: fixed;
inset: 0;
z-index: 0;
pointer-events: none;
}
/* Noise overlay */
.noise-overlay {
position: fixed;
inset: 0;
z-index: 1;
pointer-events: none;
opacity: 0.04;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
}
/* Gradient orbs */
.orb {
position: fixed;
border-radius: 50%;
filter: blur(120px);
pointer-events: none;
z-index: -1;
}
.orb-1 {
width: 500px; height: 500px;
background: radial-gradient(circle, var(--accent) 0%, transparent 70%);
top: -100px; right: -100px;
opacity: 0.3;
}
.orb-2 {
width: 400px; height: 400px;
background: radial-gradient(circle, var(--gold) 0%, transparent 70%);
bottom: 20%; left: -100px;
opacity: 0.2;
}
/* Navigation */
nav {
position: fixed;
top: 0; left: 0; right: 0;
z-index: 100;
padding: 1.5rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
background: linear-gradient(180deg, rgba(13,13,13,0.95) 0%, transparent 100%);
}
.logo {
font-size: 1.75rem;
font-weight: 700;
color: var(--fg);
text-decoration: none;
display: flex;
align-items: center;
gap: 0.5rem;
}
.logo span { color: var(--accent); }
.nav-links {
display: none;
gap: 2.5rem;
list-style: none;
}
.nav-links a {
color: var(--muted);
text-decoration: none;
font-size: 0.9rem;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.1em;
transition: color 0.2s;
}
.nav-links a:hover { color: var(--accent); }
.nav-cta {
display: none;
background: var(--accent);
color: var(--fg);
padding: 0.75rem 1.5rem;
border-radius: 9999px;
font-weight: 700;
text-decoration: none;
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.1em;
transition: background 0.2s, transform 0.2s;
}
.nav-cta:hover { background: var(--accent-dim); transform: scale(1.02); }
@media (min-width: 768px) {
.nav-links, .nav-cta { display: flex; }
}
/* Hero */
.hero {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 6rem 1.5rem 4rem;
position: relative;
z-index: 10;
}
.hero-badge {
display: inline-flex;
align-items: center;
gap: 0.5rem;
background: rgba(255, 59, 48, 0.15);
border: 1px solid rgba(255, 59, 48, 0.3);
padding: 0.5rem 1rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--accent);
margin-bottom: 2rem;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(255, 59, 48, 0.4); }
50% { box-shadow: 0 0 0 8px rgba(255, 59, 48, 0); }
}
.hero h1 {
font-size: clamp(3rem, 12vw, 7rem);
line-height: 1.05;
margin-bottom: 1.5rem;
text-transform: uppercase;
}
.hero h1 .line { display: block; }
.hero h1 .kimchi { color: var(--fg); }
.hero h1 .loco { color: var(--accent); }
.hero-sub {
font-size: clamp(1.1rem, 3vw, 1.5rem);
color: var(--muted);
max-width: 600px;
margin-bottom: 3rem;
font-weight: 400;
}
.hero-ctas {
display: flex;
flex-wrap: wrap;
gap: 1rem;
justify-content: center;
margin-bottom: 4rem;
}
.btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 1rem 2rem;
border-radius: 9999px;
font-weight: 700;
font-size: 0.9rem;
text-transform: uppercase;
letter-spacing: 0.1em;
text-decoration: none;
transition: all 0.2s;
border: 2px solid transparent;
}
.btn-primary {
background: var(--accent);
color: var(--fg);
}
.btn-primary:hover {
background: var(--accent-dim);
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(255, 59, 48, 0.3);
}
.btn-secondary {
background: transparent;
color: var(--fg);
border-color: var(--border);
}
.btn-secondary:hover {
border-color: var(--fg);
background: rgba(255,255,255,0.05);
}
/* Truck illustration */
.truck-container {
position: relative;
width: 100%;
max-width: 500px;
margin-top: 2rem;
}
.truck-svg {
width: 100%;
height: auto;
filter: drop-shadow(0 30px 60px rgba(0,0,0,0.5));
animation: float 4s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.steam {
position: absolute;
width: 8px; height: 8px;
background: rgba(255,255,255,0.6);
border-radius: 50%;
filter: blur(2px);
animation: steam 2s ease-in-out infinite;
opacity: 0;
}
.steam-1 { top: 20%; left: 65%; animation-delay: 0s; }
.steam-2 { top: 18%; left: 68%; animation-delay: 0.4s; }
.steam-3 { top: 22%; left: 62%; animation-delay: 0.8s; }
@keyframes steam {
0% { transform: translateY(0) scale(0.5); opacity: 0; }
20% { opacity: 0.6; }
100% { transform: translateY(-40px) scale(1.5); opacity: 0; }
}
/* Location bar */
.location-bar {
display: flex;
flex-wrap: wrap;
gap: 1rem;
justify-content: center;
align-items: center;
background: var(--card);
border: 1px solid var(--border);
border-radius: 16px;
padding: 1.25rem 2rem;
margin-top: 2rem;
max-width: 900px;
width: 100%;
}
.location-item {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
}
.location-icon {
width: 20px; height: 20px;
color: var(--accent);
flex-shrink: 0;
}
.location-label { color: var(--muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.1em; }
.location-value { font-weight: 600; }
.location-divider {
width: 1px; height: 24px; background: var(--border);
}
@media (max-width: 640px) {
.location-divider { display: none; }
}
/* Sections */
section { padding: 6rem 1.5rem; position: relative; z-index: 10; }
.container { max-width: 1200px; margin: 0 auto; }
.section-header {
text-align: center;
margin-bottom: 4rem;
}
.section-tag {
display: inline-block;
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--accent);
margin-bottom: 1rem;
}
.section-title {
font-size: clamp(2.5rem, 6vw, 4rem);
line-height: 1.1;
text-transform: uppercase;
}
/* Menu */
.menu-grid {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
}
@media (min-width: 640px) {
.menu-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
.menu-grid { grid-template-columns: repeat(3, 1fr); }
}
.menu-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 20px;
padding: 2rem;
position: relative;
overflow: hidden;
transition: transform 0.3s, border-color 0.3s, box-shadow 0.3s;
}
.menu-card::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(255,59,48,0.05) 0%, transparent 50%);
opacity: 0;
transition: opacity 0.3s;
}
.menu-card:hover {
transform: translateY(-8px);
border-color: var(--accent);
box-shadow: 0 20px 40px rgba(0,0,0,0.4);
}
.menu-card:hover::before { opacity: 1; }
.menu-card.featured {
border-color: var(--accent);
grid-column: span 1;
}
@media (min-width: 1024px) {
.menu-card.featured { grid-column: span 2; }
}
.menu-badge {
display: inline-block;
background: var(--accent);
color: var(--fg);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
margin-bottom: 1rem;
}
.menu-card h3 {
font-size: 1.5rem;
font-weight: 700;
margin-bottom: 0.5rem;
font-family: 'Space Grotesk', sans-serif;
text-transform: uppercase;
}
.menu-card .desc {
color: var(--muted);
font-size: 0.95rem;
margin-bottom: 1.5rem;
line-height: 1.7;
}
.menu-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 1rem;
border-top: 1px solid var(--border);
}
.price { font-size: 1.5rem; font-weight: 700; color: var(--gold); font-family: 'Anton', sans-serif; }
.btn-small {
padding: 0.6rem 1.25rem;
font-size: 0.75rem;
}
/* Featured card special layout */
.menu-card.featured .menu-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
align-items: center;
}
@media (max-width: 768px) {
.menu-card.featured .menu-content { grid-template-columns: 1fr; }
}
.featured-visual {
aspect-ratio: 1;
border-radius: 16px;
background: linear-gradient(135deg, #2a1a1a 0%, #1a1a1a 100%);
border: 1px solid rgba(255,59,48,0.3);
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.featured-visual::before {
content: '';
position: absolute;
inset: -50%;
background: radial-gradient(circle, rgba(255,59,48,0.1) 0%, transparent 70%);
animation: rotate 20s linear infinite;
}
@keyframes rotate { to { transform: rotate(360deg); } }
/* Schedule */
.schedule {
background: linear-gradient(180deg, transparent 0%, rgba(255,59,48,0.03) 50%, transparent 100%);
}
.schedule-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
max-width: 1000px;
margin: 0 auto;
}
.day-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 16px;
padding: 2rem;
text-align: center;
transition: all 0.3s;
position: relative;
}
.day-card.today {
border-color: var(--accent);
box-shadow: 0 0 0 1px var(--accent), 0 20px 40px rgba(255,59,48,0.15);
}
.day-card.today::before {
content: 'TODAY';
position: absolute;
top: -12px;
left: 50%;
transform: translateX(-50%);
background: var(--accent);
color: var(--fg);
font-size: 0.6rem;
font-weight: 700;
padding: 0.25rem 1rem;
border-radius: 9999px;
letter-spacing: 0.1em;
}
.day-name {
font-family: 'Anton', sans-serif;
font-size: 2rem;
letter-spacing: 0.05em;
margin-bottom: 0.5rem;
}
.day-date { color: var(--muted); font-size: 0.9rem; margin-bottom: 1.5rem; }
.day-location { font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem; }
.day-time { color: var(--muted); font-size: 0.9rem; }
.day-card.closed .day-location { color: var(--muted); }
.day-card.closed .day-time { color: #666; }
/* Story */
.story {
background: var(--card);
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
}
.story-grid {
display: grid;
grid-template-columns: 1fr;
gap: 3rem;
align-items: center;
max-width: 1000px;
margin: 0 auto;
}
@media (min-width: 768px) {
.story-grid { grid-template-columns: 1fr 1fr; }
}
.story-text h2 { text-align: left; }
.story-text p {
color: var(--muted);
font-size: 1.1rem;
line-height: 1.8;
margin-bottom: 1.5rem;
}
.story-stats {
display: flex;
flex-wrap: wrap;
gap: 2rem;
margin-top: 2rem;
}
.stat {
text-align: center;
}
.stat-number {
font-family: 'Anton', sans-serif;
font-size: 3rem;
color: var(--accent);
line-height: 1;
}
.stat-label {
font-size: 0.85rem;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.1em;
}
.story-visual {
aspect-ratio: 4/3;
border-radius: 20px;
background: linear-gradient(135deg, #1a1a1a 0%, #0d0d0d 100%);
border: 1px solid var(--border);
position: relative;
overflow: hidden;
}
.story-visual::before {
content: '';
position: absolute;
inset: 0;
background:
radial-gradient(ellipse at 20% 30%, rgba(255,59,48,0.15) 0%, transparent 50%),
radial-gradient(ellipse at 80% 70%, rgba(255,215,0,0.1) 0%, transparent 50%);
}
/* Reviews */
.reviews-grid {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
}
@media (min-width: 768px) {
.reviews-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
.reviews-grid { grid-template-columns: repeat(3, 1fr); }
}
.review-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 16px;
padding: 2rem;
transition: transform 0.3s, border-color 0.3s;
}
.review-card:hover {
transform: translateY(-4px);
border-color: rgba(255,215,0,0.3);
}
.review-stars {
display: flex;
gap: 0.25rem;
margin-bottom: 1rem;
color: var(--gold);
}
.review-text {
color: var(--muted);
line-height: 1.7;
margin-bottom: 1.5rem;
font-size: 0.95rem;
}
.review-author {
display: flex;
align-items: center;
gap: 0.75rem;
}
.author-avatar {
width: 44px; height: 44px;
border-radius: 50%;
background: linear-gradient(135deg, var(--accent), var(--gold));
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 1rem;
color: var(--bg);
}
.author-name { font-weight: 600; }
.author-handle { color: var(--muted); font-size: 0.85rem; }
/* CTA Section */
.cta-section {
text-align: center;
background: linear-gradient(135deg, rgba(255,59,48,0.1) 0%, transparent 100%);
border-top: 1px solid rgba(255,59,48,0.2);
border-bottom: 1px solid rgba(255,59,48,0.2);
}
.cta-section h2 { margin-bottom: 1.5rem; }
.cta-section p {
color: var(--muted);
font-size: 1.1rem;
max-width: 600px;
margin: 0 auto 2.5rem;
}
.social-links {
display: flex;
justify-content: center;
gap: 1rem;
margin-top: 2rem;
}
.social-link {
width: 48px; height: 48px;
border-radius: 50%;
background: var(--card);
border: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: center;
color: var(--muted);
text-decoration: none;
transition: all 0.2s;
}
.social-link:hover {
border-color: var(--accent);
color: var(--accent);
transform: translateY(-2px);
}
/* Footer */
footer {
padding: 3rem 1.5rem;
border-top: 1px solid var(--border);
text-align: center;
}
.footer-content {
max-width: 1200px;
margin: 0 auto;
}
.footer-logo {
font-family: 'Anton', sans-serif;
font-size: 2rem;
letter-spacing: 0.05em;
margin-bottom: 1rem;
}
.footer-logo span { color: var(--accent); }
.footer-links {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 1.5rem;
margin-bottom: 2rem;
}
.footer-links a {
color: var(--muted);
text-decoration: none;
font-size: 0.9rem;
transition: color 0.2s;
}
.footer-links a:hover { color: var(--accent); }
.copyright {
color: #525252;
font-size: 0.85rem;
}
/* Scroll reveal */
.reveal {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1), transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.visible {
opacity: 1;
transform: translateY(0);
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
.reveal { opacity: 1; transform: none; transition: none; }
.truck-svg, .steam { animation: none; }
.hero-badge { animation: none; }
.featured-visual::before { animation: none; }
}
</style>
</head>
<body>
<canvas id="bg-canvas"></canvas>
<div class="noise-overlay"></div>
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<nav role="navigation" aria-label="Main navigation">
<a href="#" class="logo font-display">KIMCHI <span>LOCO</span></a>
<ul class="nav-links">
<li><a href="#menu">Menu</a></li>
<li><a href="#schedule">Schedule</a></li>
<li><a href="#story">Story</a></li>
<li><a href="#reviews">Reviews</a></li>
</ul>
<a href="#schedule" class="nav-cta btn btn-primary">Find Us</a>
</nav>
<header class="hero" role="banner">
<div class="hero-badge" aria-label="New location alert">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
<span>NEW: Now at Brewery District Thu-Sat</span>
</div>
<h1 class="font-display">
<span class="line kimchi">KIMCHI</span>
<span class="line loco">LOCO</span>
</h1>
<p class="hero-sub">Korean fire meets Mexican soul. Hand-pressed tortillas, slow-fermented kimchi, gochujang crema, and the crunch you've been dreaming about.</p>
<div class="hero-ctas">
<a href="#schedule" class="btn btn-primary">Track the Truck</a>
<a href="#menu" class="btn btn-secondary">Peep the Menu</a>
</div>
<div class="truck-container" aria-hidden="true">
<svg class="truck-svg" viewBox="0 0 500 320" xmlns="http://www.w3.org/2000/svg">
<!-- Truck body -->
<defs>
<linearGradient id="truckBody" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#ff3b30"/>
<stop offset="100%" style="stop-color:#cc2f26"/>
</linearGradient>
<linearGradient id="truckDark" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#1a1a1a"/>
<stop offset="100%" style="stop-color:#0d0d0d"/>
</linearGradient>
<linearGradient id="windowGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#1a2a3a"/>
<stop offset="100%" style="stop-color:#0d1520"/>
</linearGradient>
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Wheels -->
<g>
<circle cx="90" cy="260" r="38" fill="#0d0d0d" stroke="#333" stroke-width="2"/>
<circle cx="90" cy="260" r="22" fill="#1a1a1a"/>
<circle cx="90" cy="260" r="12" fill="#2a2a2a"/>
<g fill="#ff3b30" opacity="0.3">
<rect x="85" y="245" width="10" height="30" rx="2" transform="rotate(-45 90 260)"/>
<rect x="85" y="245" width="10" height="30" rx="2" transform="rotate(45 90 260)"/>
</g>
<circle cx="410" cy="260" r="38" fill="#0d0d0d" stroke="#333" stroke-width="2"/>
<circle cx="410" cy="260" r="22" fill="#1a1a1a"/>
<circle cx="410" cy="260" r="12" fill="#2a2a2a"/>
<g fill="#ff3b30" opacity="0.3">
<rect x="405" y="245" width="10" height="30" rx="2" transform="rotate(-45 410 260)"/>
<rect x="405" y="245" width="10" height="30" rx="2" transform="rotate(45 410 260)"/>
</g>
</g>
<!-- Main body -->
<path d="M50 220 L50 120 Q50 80 90 80 L310 80 Q350 80 350 120 L350 160 L400 160 L400 220 Z" fill="url(#truckBody)" stroke="#cc2f26" stroke-width="1"/>
<!-- Cab window -->
<path d="M95 125 L95 90 Q95 82 103 82 L160 82 Q168 82 168 90 L168 125 Z" fill="url(#windowGrad)" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"/>
<!-- Service window -->
<rect x="180" y="100" width="140" height="80" rx="4" fill="url(#windowGrad)" stroke="rgba(255,59,48,0.3)" stroke-width="1.5"/>
<rect x="188" y="108" width="124" height="64" rx="2" fill="rgba(255,215,0,0.05)"/>
<!-- Taco in window -->
<g transform="translate(250, 140)">
<path d="M-20 0 Q-20 -15 0 -15 Q20 -15 20 0 Q20 15 0 15 Q-20 15 -20 0" fill="#d47b2a" stroke="#b8651a" stroke-width="1"/>
<path d="M-18 0 Q-18 -12 0 -12 Q18 -12 18 0" fill="#c46b1a" opacity="0.5"/>
<ellipse cx="0" cy="-8" rx="6" ry="3" fill="#ff3b30" opacity="0.8"/>
<ellipse cx="-8" cy="2" rx="5" ry="2" fill="#4ade80" opacity="0.9"/>
<ellipse cx="8" cy="2" rx="5" ry="2" fill="#fbbf24" opacity="0.9"/>
</g>
<!-- Roof vent -->
<rect x="120" y="50" width="60" height="18" rx="4" fill="#1a1a1a" stroke="#333" stroke-width="1"/>
<rect x="128" y="54" width="44" height="10" rx="2" fill="#0d0d0d"/>
<!-- "KIMCHI LOCO" text on side -->
<text x="250" y="195" font-family="Anton, sans-serif" font-size="28" fill="#fff" text-anchor="middle" letter-spacing="4" opacity="0.95">KIMCHI LOCO</text>
<text x="250" y="220" font-family="Anton, sans-serif" font-size="14" fill="#ffd700" text-anchor="middle" letter-spacing="8">KOREAN TACOS</text>
<!-- Side graphics -->
<g transform="translate(100, 140)" opacity="0.8">
<path d="M0 0 Q-15 -10 -10 -25 Q-5 -40 15 -35 Q25 -20 0 0" fill="#ff3b30"/>
<path d="M0 0 Q-10 -5 -5 -15 Q0 -22 8 -18 Q12 -10 0 0" fill="#ffd700" opacity="0.6"/>
</g>
<g transform="translate(380, 140) scale(-1, 1)" opacity="0.8">
<path d="M0 0 Q-15 -10 -10 -25 Q-5 -40 15 -35 Q25 -20 0 0" fill="#ff3b30"/>
<path d="M0 0 Q-10 -5 -5 -15 Q0 -22 8 -18 Q12 -10 0 0" fill="#ffd700" opacity="0.6"/>
</g>
<!-- Exhaust pipe -->
<rect x="45" y="180" width="12" height="50" rx="2" fill="#2a2a2a" stroke="#333" stroke-width="1"/>
<g class="steam steam-1"><circle cx="51" cy="175" r="4" fill="rgba(255,255,255,0.6)"/></g>
<g class="steam steam-2"><circle cx="48" cy="178" r="3" fill="rgba(255,255,255,0.5)"/></g>
<g class="steam steam-3"><circle cx="54" cy="176" r="3" fill="rgba(255,255,255,0.5)"/></g>
<!-- Headlight -->
<ellipse cx="48" cy="200" rx="8" ry="5" fill="#fff" opacity="0.9" filter="url(#glow)"/>
<ellipse cx="48" cy="200" rx="4" ry="2" fill="#fff"/>
<!-- Taillight -->
<rect x="352" y="190" width="6" height="20" rx="2" fill="#ff3b30" filter="url(#glow)"/>
</svg>
</div>
<div class="location-bar" role="region" aria-label="Current location and hours">
<div class="location-item">
<svg class="location-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
<div>
<div class="location-label">Location</div>
<div class="location-value" id="current-location">Downtown Arts District</div>
</div>
</div>
<div class="location-divider" aria-hidden="true"></div>
<div class="location-item">
<svg class="location-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
<div>
<div class="location-label">Hours Today</div>
<div class="location-value" id="current-hours">11:00 AM - 9:00 PM</div>
</div>
</div>
<div class="location-divider" aria-hidden="true"></div>
<div class="location-item">
<svg class="location-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="M22 4L12 14.01l-3-3"/></svg>
<div>
<div class="location-label">Status</div>
<div class="location-value" style="color: #4ade80;" id="current-status">OPEN NOW</div>
</div>
</div>
</div>
</header>
<main>
<section id="menu" class="menu reveal" aria-labelledby="menu-title">
<div class="container">
<header class="section-header">
<span class="section-tag">The Goods</span>
<h2 id="menu-title" class="section-title font-display">Menu</h2>
</header>
<div class="menu-grid" role="list">
<!-- Featured -->
<article class="menu-card featured" role="listitem">
<span class="menu-badge">Crowd Favorite</span>
<div class="menu-content">
<div>
<h3>Kimchi Loco Supreme</h3>
<p class="desc">Double corn tortillas, carne asada marinated in gochujang-soy, house kimchi aged 21 days, gochujang crema, pickled daikon, cilantro, lime. Served with kimchi fries.</p>
<div class="menu-footer">
<span class="price">$16</span>
<a href="#" class="btn btn-primary btn-small">Order This</a>
</div>
</div>
<div class="featured-visual" aria-hidden="true">
<svg viewBox="0 0 200 200" width="180" height="180" xmlns="http://www.w3.org/2000/svg">
<!-- Taco illustration -->
<g transform="translate(100, 110)">
<!-- Shell -->
<path d="M-55 0 Q-55 -35 0 -35 Q55 -35 55 0 Q55 35 0 35 Q-55 35 -55 0" fill="#d4a574" stroke="#b88d5c" stroke-width="2"/>
<path d="M-50 0 Q-50 -28 0 -28 Q50 -28 50 0" fill="#c49564" opacity="0.5"/>
<!-- Meat -->
<path d="M-45 5 Q-45 -20 0 -20 Q45 -20 45 5 Q45 25 0 25 Q-45 25 -45 5" fill="#8b3a2a"/>
<path d="M-40 8 Q-40 -12 0 -12 Q40 -12 40 8" fill="#a04a3a" opacity="0.6"/>
<!-- Kimchi -->
<g fill="#ff3b30">
<ellipse cx="-30" cy="-5" rx="8" ry="5"/>
<ellipse cx="-10" cy="-12" rx="6" ry="4"/>
<ellipse cx="10" cy="-8" rx="7" ry="4"/>
<ellipse cx="30" cy="-3" rx="8" ry="5"/>
<ellipse cx="-5" cy="5" rx="6" ry="3"/>
<ellipse cx="20" cy="3" rx="7" ry="4"/>
</g>
<!-- Crema drizzle -->
<path d="M-40 15 Q-20 5 0 15 Q20 5 40 15" stroke="#fff" stroke-width="2" fill="none" opacity="0.8"/>
<!-- Garnish -->
<g fill="#4ade80">
<ellipse cx="-35" cy="18" rx="4" ry="2"/>
<ellipse cx="0" cy="22" rx="5" ry="2"/>
<ellipse cx="35" cy="18" rx="4" ry="2"/>
</g>
<g fill="#fbbf24">
<ellipse cx="-20" cy="20" rx="3" ry="1.5"/>
<ellipse cx="20" cy="20" rx="3" ry="1.5"/>
</g>
</g>
</svg>
</div>
</div>
</article>
<!-- Regular items -->
<article class="menu-card reveal" role="listitem" style="transition-delay: 0.1s;">
<span class="menu-badge">Signature</span>
<h3>Bulgogi Taco</h3>
<p class="desc">Thin-sliced ribeye bulgogi, sesame slaw, ssamjang aioli, scallions, toasted sesame on charred corn tortilla.</p>
<div class="menu-footer">
<span class="price">$5.50</span>
<a href="#" class="btn btn-primary btn-small">Add</a>
</div>
</article>
<article class="menu-card reveal" role="listitem" style="transition-delay: 0.2s;">
<span class="menu-badge">Spicy</span>
<h3>Fire Chicken Taco</h3>
<p class="desc">Dakgalbi-style gochujang chicken, pickled cucumber, mayo, kimchi slaw, crispy shallots. Heat level: legit.</p>
<div class="menu-footer">
<span class="price">$5.50</span>
<a href="#" class="btn btn-primary btn-small">Add</a>
</div>
</article>
<article class="menu-card reveal" role="listitem" style="transition-delay: 0.3s;">
<span class="menu-badge">Vegan</span>
<h3>Tofu Kimchi Taco</h3>
<p class="desc">Crispy gochujang-glazed tofu, house kimchi, pickled radish, scallion, vegan crema. No compromise.</p>
<div class="menu-footer">
<span class="price">$5</span>
<a href="#" class="btn btn-primary btn-small">Add</a>
</div>
</article>
<article class="menu-card reveal" role="listitem" style="transition-delay: 0.1s;">
<span class="menu-badge">Side</span>
<h3>Kimchi Fries</h3>
<p class="desc">Crinkle-cut fries, carne asada, kimchi, queso fundido, gochujang crema, scallions, cilantro. Shareable (barely).</p>
<div class="menu-footer">
<span class="price">$12</span>
<a href="#" class="btn btn-primary btn-small">Add</a>
</div>
</article>
<article class="menu-card reveal" role="listitem" style="transition-delay: 0.2s;">
<span class="menu-badge">Drink</span>
<h3>Yuzu Ade / Cold Brew</h3>
<p class="desc">House-made yuzu lemonade or nitro cold brew. Rotating seasonal agua frescas. Ask what's fresh.</p>
<div class="menu-footer">
<span class="price">$4</span>
<a href="#" class="btn btn-primary btn-small">Add</a>
</div>
</article>
</div>
</div>
</section>
<section id="schedule" class="schedule reveal" aria-labelledby="schedule-title">
<div class="container">
<header class="section-header">
<span class="section-tag">Where We At</span>
<h2 id="schedule-title" class="section-title font-display">Schedule</h2>
</header>
<div class="schedule-grid" role="list">
<article class="day-card today reveal" role="listitem" style="transition-delay: 0.1s;">
<div class="day-name font-display">MONDAY</div>
<div class="day-date">December 16</div>
<div class="day-location">Downtown Arts District</div>
<div class="day-time">11:00 AM – 9:00 PM</div>
</article>
<article class="day-card today reveal" role="listitem" style="transition-delay: 0.2s;">
<div class="day-name font-display">TUESDAY</div>
<div class="day-date">December 17</div>
<div class="day-location">Tech Campus Food Court</div>
<div class="day-time">11:00 AM – 3:00 PM</div>
</article>
<article class="day-card reveal" role="listitem" style="transition-delay: 0.3s;">
<div class="day-name font-display">WEDNESDAY</div>
<div class="day-date">December 18</div>
<div class="day-location">Riverfront Park</div>
<div class="day-time">4:00 PM – 10:00 PM</div>
</article>
<article class="day-card reveal" role="listitem" style="transition-delay: 0.4s;">
<div class="day-name font-display">THURSDAY</div>
<div class="day-date">December 19</div>
<div class="day-location">Brewery District</div>
<div class="day-time">4:00 PM – 11:00 PM</div>
</article>
<article class="day-card reveal" role="listitem" style="transition-delay: 0.5s;">
<div class="day-name font-display">FRIDAY</div>
<div class="day-date">December 20</div>
<div class="day-location">Brewery District</div>
<div class="day-time">4:00 PM – 12:00 AM</div>
</article>
<article class="day-card reveal" role="listitem" style="transition-delay: 0.6s;">
<div class="day-name font-display">SATURDAY</div>
<div class="day-date">December 21</div>
<div class="day-location">Farmers Market (9-2) → Brewery District (4-12)</div>
<div class="day-time">Double shift!</div>
</article>
<article class="day-card closed reveal" role="listitem" style="transition-delay: 0.7s;">
<div class="day-name font-display">SUNDAY</div>
<div class="day-date">December 22</div>
<div class="day-location">Closed</div>
<div class="day-time">Prep day — we'll be back Monday</div>
</article>
</div>
</div>
</section>
<section id="story" class="story reveal" aria-labelledby="story-title">
<div class="container">
<div class="story-grid">
<div class="story-text">
<span class="section-tag">Origin Story</span>
<h2 id="story-title" class="section-title font-display">Two Cultures, One Truck</h2>
<p>Jin grew up in his halmoni's kitchen in Seoul, learning the patience of fermentation. Marco grew up in his abuela's taqueria in East LA, learning the speed of the plancha. They met in a Seoul food hall, argued about spice levels for three hours, and decided to open a truck together.</p>
<p>Every tortilla is pressed to order. Every batch of kimchi ferments for 21 days. The gochujang crema takes six hours. The carne asada marinades overnight. No shortcuts. No pre-made. Just two kids from opposite sides of the Pacific making the food they wish existed.</p>
<div class="story-stats">
<div class="stat">
<div class="stat-number font-display" data-count="21">0</div>
<div class="stat-label">Days Fermentation</div>
</div>
<div class="stat">
<div class="stat-number font-display" data-count="847">0</div>
<div class="stat-label">Tacos Served Weekly</div>
</div>
<div class="stat">
<div class="stat-number font-display" data-count="2">0</div>
<div class="stat-label">Founders</div>
</div>
<div class="stat">
<div class="stat-number font-display" data-count="100">0</div>
<div class="stat-label">% Handmade</div>
</div>
</div>
</div>
<div class="story-visual" aria-hidden="true"></div>
</div>
</div>
</section>
<section id="reviews" class="reveal" aria-labelledby="reviews-title">
<div class="container">
<header class="section-header">
<span class="section-tag">Real Ones Know</span>
<h2 id="reviews-title" class="section-title font-display">Reviews</h2>
</header>
<div class="reviews-grid" role="list">
<article class="review-card reveal" role="listitem" style="transition-delay: 0.1s;">
<div class="review-stars" aria-label="5 out of 5 stars">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</div>
<p class="review-text">"The Kimchi Loco Supreme changed my life. Not being dramatic. The kimchi has that deep funk you only get from real fermentation, the crema cuts through the richness, and the tortilla holds everything together. I dream about this taco."</p>
<div class="review-author">
<div class="author-avatar">SC</div>
<div>
<div class="author-name">Sarah Chen</div>
<div class="author-handle">@sarocheats • 2 days ago</div>
</div>
</div>
</article>
<article class="review-card reveal" role="listitem" style="transition-delay: 0.2s;">
<div class="review-stars" aria-label="5 out of 5 stars">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</div>
<p class="review-text">"Finally, a fusion concept that respects both cuisines. The bulgogi taco has proper sesame slaw, not just cabbage. The fire chicken actually brings heat. These folks did their homework. Line moves fast too."</p>
<div class="review-author">
<div class="author-avatar">MR</div>
<div>
<div class="author-name">Marcus Rodriguez</div>
<div class="author-handle">@marceatsla • 1 week ago</div>
</div>
</div>
</article>
<article class="review-card reveal" role="listitem" style="transition-delay: 0.3s;">
<div class="review-stars" aria-label="5 out of 5 stars">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</div>
<p class="review-text">"As a Korean-American who grew up on both Korean food and LA street tacos, this hits different. The tofu kimchi taco is vegan but doesn't taste like compromise. Kimchi fries are dangerous. Follow their IG for locations."</p>
<div class="review-author">
<div class="author-avatar">JK</div>
<div>
<div class="author-name">Ji-hoon Kim</div>
<div class="author-handle">@jihooneats • 3 days ago</div>
</div>
</div>
</article>
</div>
</div>
</section>
<section class="cta-section reveal" aria-labelledby="cta-title">
<div class="container">
<h2 id="cta-title" class="section-title font-display">Catch Us If You Can</h2>
<p>Follow the truck, get drop alerts, see what's fresh today. We move fast but the food's worth the chase.</p>
<div class="hero-ctas">
<a href="#schedule" class="btn btn-primary">Track the Truck</a>
<a href="https://instagram.com" target="_blank" rel="noopener" class="btn btn-secondary">Follow @kimchiloco</a>
</div>
<div class="social-links" role="list" aria-label="Social media links">
<a href="https://instagram.com" target="_blank" rel="noopener" class="social-link" role="listitem" aria-label="Instagram">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"/><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/></svg>
</a>
<a href="https://twitter.com" target="_blank" rel="noopener" class="social-link" role="listitem" aria-label="Twitter">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"/></svg>
</a>
<a href="https://tiktok.com" target="_blank" rel="noopener" class="social-link" role="listitem" aria-label="TikTok">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M16 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2"/><path d="M12 17v4"/><path d="M16 17h4"/></svg>
</a>
</div>
</div>
</section>
</main>
<footer role="contentinfo">
<div class="footer-content">
<div class="footer-logo font-display">KIMCHI <span>LOCO</span></div>
<nav class="footer-links" aria-label="Footer navigation">
<a href="#menu">Menu</a>
<a href="#schedule">Schedule</a>
<a href="#story">Our Story</a>
<a href="#reviews">Reviews</a>
<a href="#">Catering</a>
<a href="#">Merch</a>
</nav>
<p class="copyright">© 2024 Kimchi Loco. Hand-pressed with patience in Los Angeles.</p>
</div>
</footer>
<script>
// Background canvas animation
const canvas = document.getElementById('bg-canvas');
const ctx = canvas.getContext('2d');
let particles = [];
let animationId = null;
let prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
class Particle {
constructor() {
this.reset();
}
reset() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.size = Math.random() * 1.5 + 0.5;
this.speedX = (Math.random() - 0.5) * 0.3;
this.speedY = (Math.random() - 0.5) * 0.3;
this.opacity = Math.random() * 0.3 + 0.1;
this.color = Math.random() > 0.5 ? '#ff3b30' : '#ffd700';
}
update() {
this.x += this.speedX;
this.y += this.speedY;
if (this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height) {
this.reset();
}
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.globalAlpha = this.opacity;
ctx.fill();
ctx.globalAlpha = 1;
}
}
function initParticles() {
const count = Math.min(80, Math.floor((canvas.width * canvas.height) / 15000));
particles = [];
for (let i = 0; i < count; i++) {
particles.push(new Particle());
}
}
function animate() {
if (prefersReducedMotion) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
particles.forEach(p => {
p.update();
p.draw();
});
animationId = requestAnimationFrame(animate);
}
// Initialize
resizeCanvas();
initParticles();
if (!prefersReducedMotion) animate();
window.addEventListener('resize', () => {
resizeCanvas();
initParticles();
});
// Intersection Observer for scroll reveal
const observerOptions = {
root: null,
rootMargin: '0px 0px -10% 0px',
threshold: 0.1
};
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
// Stagger children
const children = entry.target.querySelectorAll('.reveal');
children.forEach((child, i) => {
child.style.transitionDelay = `${i * 0.1}s`;
});
revealObserver.unobserve(entry.target);
}
});
}, observerOptions);
document.querySelectorAll('.reveal').forEach(el => {
revealObserver.observe(el);
});
// Counter animation for stats
const statObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const counters = entry.target.querySelectorAll('[data-count]');
counters.forEach(counter => {
const target = parseInt(counter.dataset.count);
const duration = 2000;
const step = target / (duration / 16);
let current = 0;
const updateCounter = () => {
current += step;
if (current < target) {
counter.textContent = Math.floor(current).toLocaleString();
requestAnimationFrame(updateCounter);
} else {
counter.textContent = target.toLocaleString();
}
};
updateCounter();
});
statObserver.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
document.querySelector('.story-stats') && statObserver.observe(document.querySelector('.story-stats'));
// Dynamic location/time update
function updateLocationInfo() {
const now = new Date();
const day = now.getDay(); // 0 = Sunday
const hour = now.getHours();
const schedule = [
{ location: 'Closed', hours: 'Prep day', open: false }, // Sun
{ location: 'Downtown Arts District', hours: '11:00 AM – 9:00 PM', open: hour >= 11 && hour < 21 }, // Mon
{ location: 'Tech Campus Food Court', hours: '11:00 AM – 3:00 PM', open: hour >= 11 && hour < 15 }, // Tue
{ location: 'Riverfront Park', hours: '4:00 PM – 10:00 PM', open: hour >= 16 && hour < 22 }, // Wed
{ location: 'Brewery District', hours: '4:00 PM – 11:00 PM', open: hour >= 16 && hour < 23 }, // Thu
{ location: 'Brewery District', hours: '4:00 PM – 12:00 AM', open: hour >= 16 && hour < 24 }, // Fri
{ location: 'Farmers Market → Brewery District', hours: '9:00 AM – 2:00 PM / 4:00 PM – 12:00 AM', open: (hour >= 9 && hour < 14) || (hour >= 16 && hour < 24) } // Sat
];
const today = schedule[day];
document.getElementById('current-location').textContent = today.location;
document.getElementById('current-hours').textContent = today.hours;
const statusEl = document.getElementById('current-status');
statusEl.textContent = today.open ? 'OPEN NOW' : 'CLOSED';
statusEl.style.color = today.open ? '#4ade80' : '#ff3b30';
}
updateLocationInfo();
// Update every minute
setInterval(updateLocationInfo, 60000);
// Highlight current day in schedule
const dayNames = ['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY'];
const todayName = dayNames[new Date().getDay()];
document.querySelectorAll('.day-card').forEach(card => {
const nameEl = card.querySelector('.day-name');
if (nameEl && nameEl.textContent === todayName) {
card.classList.add('today');
if (!card.classList.contains('closed')) {
const badge = document.createElement('div');
badge.style.cssText = 'position:absolute;top:-12px;left:50%;transform:translateX(-50%);background:var(--accent);color:var(--fg);font-size:0.6rem;font-weight:700;padding:0.25rem 1rem;border-radius:9999px;letter-spacing:0.1em;';
badge.textContent = 'TODAY';
card.style.position = 'relative';
card.prepend(badge);
}
}
});
// Smooth scroll for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
const target = document.querySelector(this.getAttribute('href'));
if (target) {
e.preventDefault();
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
// Cleanup on unload
window.addEventListener('beforeunload', () => {
if (animationId) cancelAnimationFrame(animationId);
});
</script>
</body>
</html>