feat: implement Tabletop QR Stand Generator with high-res PNG and print-ready A5 PDF export

This commit is contained in:
AyrisAI
2026-08-20 18:16:49 +03:00
parent 54a27903c8
commit d396cbb221
12 changed files with 1039 additions and 5 deletions
+308
View File
@@ -0,0 +1,308 @@
# The Urban Burger - Tabletop QR Menu Stand Design System
## Color Palette
- **Forest Green Background**: `#1c3e2b` / `#163323` (ambient tabletop / environment backdrop)
- **Rust / Terracotta Leather Plaque**: `#a64d2a` / `#b35431` (primary card & stand body)
- **Cream / Warm Alabaster QR Inset**: `#f8f3eb` (QR code container background)
- **Rust QR Pattern**: `#a64d2a` / `#944222` (custom branded QR pixel matrix)
- **Warm Golden Wheat**: `#f5be72` / `#e9b366` (logo outline, flame accents, hand-drawn icons)
- **Pure White / Cream UI Text**: `#ffffff` / `#fef8f0` (display headers, scan instructions, category list)
- **Subtle Divider / Border Lines**: `#c96b46` / `rgba(255, 255, 255, 0.2)` (category separation rules)
## Typography
- **Display / Headers**: `Montserrat`, `Plus Jakarta Sans`, or `Oswald` (weights 800-900, uppercase, clean geometric sans-serif with tight line-height)
- **Logo Typography**: Stylized bold outline font with flame icon ligature (or stylized custom geometric sans)
- **Instructional & Body**: `Inter`, `Plus Jakarta Sans`, or `DM Sans` (weights 500-700, generous tracking `0.1em` to `0.2em`)
Font imports:
```css
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@700;800;900&family=Plus+Jakarta+Sans:wght@500;600;700;800&display=swap');
```
## Spacing & Layout
- **Stand Plaque Dimensions**: `360px` `400px` width, `~700px` height (aspect ratio ~1:1.8 portrait tabletop stand)
- **Border Radius**: `28px` (`rounded-[2rem]`) on outer card with physical drop shadow
- **QR Plate Corner Radius**: `24px` (`rounded-3xl`) with inset shadow
- **Hierarchy Order**:
1. Brand Logo (Top)
2. Action Callout (`DIGITAL MENU / SCAN TO ORDER`)
3. Centered Large QR Code Box with custom rounded finder patterns
4. Camera Prompt (`Use your phone's camera`)
5. Category Quick-View List (Burgers, Fries, Shakes, Vegan Options) flanked by illustrative line icons
---
## Reusable Components
### 1. Urban Burger Brand Badge & Header
```html
<div class="flex flex-col items-center text-center">
<!-- Stylized Brand Logo -->
<div class="border-2 border-[#f5be72] rounded-xl px-4 py-2 flex flex-col items-center mb-5 bg-[#a64d2a]/60 shadow-sm">
<div class="flex items-center gap-1.5 text-[#f5be72] font-black text-xl tracking-wider uppercase font-['Montserrat']">
<span>THE URBAN</span>
<!-- Flame Icon -->
<svg class="w-5 h-5 fill-[#f5be72]" viewBox="0 0 24 24">
<path d="M12 2c1.5 3.5 4 6.5 4 10 0 4.42-3.58 8-8 8s-8-3.58-8-8c0-3.5 2.5-6.5 4-10 .5 2 1.5 3.5 3 4.5.5-2.5 2-5 5-6.5z"/>
</svg>
</div>
<span class="text-[#f5be72] font-black text-2xl tracking-[0.25em] uppercase font-['Montserrat'] -mt-1">
BURGER
</span>
</div>
<!-- Scan Call to Action -->
<h2 class="text-white font-['Montserrat'] font-black text-2xl sm:text-3xl tracking-tight uppercase leading-[0.95] drop-shadow-sm">
DIGITAL MENU<br>
<span class="tracking-wide">SCAN TO ORDER</span>
</h2>
</div>
```
### 2. Custom Branded QR Code Box
```html
<div class="w-56 h-56 sm:w-64 sm:h-64 bg-[#f8f3eb] rounded-[2rem] p-5 shadow-inner flex items-center justify-center relative border border-black/10 my-6">
<!-- QR Code SVG with Custom Rust Pixels -->
<svg class="w-full h-full text-[#a64d2a]" viewBox="0 0 100 100" fill="currentColor">
<!-- Top-Left Finder -->
<rect x="5" y="5" width="28" height="28" rx="8" fill="currentColor"/>
<rect x="10" y="10" width="18" height="18" rx="5" fill="#f8f3eb"/>
<rect x="14" y="14" width="10" height="10" rx="3" fill="currentColor"/>
<!-- Top-Right Finder -->
<rect x="67" y="5" width="28" height="28" rx="8" fill="currentColor"/>
<rect x="72" y="10" width="18" height="18" rx="5" fill="#f8f3eb"/>
<rect x="76" y="14" width="10" height="10" rx="3" fill="currentColor"/>
<!-- Bottom-Left Finder -->
<rect x="5" y="67" width="28" height="28" rx="8" fill="currentColor"/>
<rect x="10" y="72" width="18" height="18" rx="5" fill="#f8f3eb"/>
<rect x="14" y="76" width="10" height="10" rx="3" fill="currentColor"/>
<!-- Data Blocks -->
<rect x="38" y="8" width="8" height="8" rx="2"/>
<rect x="50" y="8" width="8" height="14" rx="2"/>
<rect x="38" y="22" width="14" height="8" rx="2"/>
<rect x="8" y="38" width="8" height="12" rx="2"/>
<rect x="20" y="42" width="12" height="8" rx="2"/>
<rect x="38" y="38" width="24" height="24" rx="4"/>
<rect x="42" y="42" width="16" height="16" rx="2" fill="#f8f3eb"/>
<rect x="46" y="46" width="8" height="8" rx="2" fill="currentColor"/>
<rect x="68" y="38" width="10" height="14" rx="2"/>
<rect x="82" y="42" width="10" height="10" rx="2"/>
<rect x="38" y="68" width="12" height="10" rx="2"/>
<rect x="54" y="72" width="8" height="18" rx="2"/>
<rect x="68" y="68" width="12" height="12" rx="2"/>
<rect x="84" y="72" width="8" height="8" rx="2"/>
<rect x="68" y="84" width="24" height="8" rx="2"/>
</svg>
</div>
```
### 3. Menu Quick-Categories Section with Floating Icons
```html
<div class="w-full relative px-6 mt-2 text-center">
<p class="text-white/90 text-sm font-['Plus_Jakarta_Sans'] tracking-wide mb-4 font-medium">
Use your phone's camera
</p>
<!-- Left Burger Line Icon -->
<div class="absolute left-2 bottom-3 text-[#f5be72] opacity-80">
<svg class="w-10 h-10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round">
<path d="M4 11a8 8 0 0 1 16 0H4z"/>
<rect x="3" y="14" width="18" height="3" rx="1.5"/>
<path d="M5 20a3 3 0 0 0 14 0H5z"/>
</svg>
</div>
<!-- Right Drink / Shake Line Icon -->
<div class="absolute right-2 bottom-3 text-[#f5be72] opacity-80">
<svg class="w-10 h-10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round">
<path d="M7 8h10l-1.5 13h-7L7 8z"/>
<path d="M5 8h14"/>
<path d="M12 2v6"/>
<path d="M9 2l3 6"/>
</svg>
</div>
<!-- Category List -->
<div class="flex flex-col gap-2 max-w-[200px] mx-auto text-white font-['Montserrat'] font-extrabold uppercase tracking-widest text-base sm:text-lg">
<div class="py-1">BURGERS</div>
<div class="w-full h-[1px] bg-white/20"></div>
<div class="py-1">FRIES</div>
<div class="w-full h-[1px] bg-white/20"></div>
<div class="py-1">SHAKES</div>
<div class="w-full h-[1px] bg-white/20"></div>
<div class="py-1 text-sm sm:text-base">VEGAN OPTIONS</div>
</div>
</div>
```
---
## Full Responsive Standalone HTML / CSS Implementation
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>The Urban Burger - Tabletop QR Menu</title>
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
tableGreen: '#1a3a29',
tableGreenDark: '#12281c',
rustStand: '#a64d2a',
rustStandDark: '#8e3f20',
qrCream: '#f8f3eb',
goldWheat: '#f5be72',
},
fontFamily: {
display: ['Montserrat', 'sans-serif'],
sans: ['Plus Jakarta Sans', 'sans-serif']
}
}
}
}
</script>
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@700;800;900&family=Plus+Jakarta+Sans:wght@500;600;700;800&display=swap" rel="stylesheet">
<style>
body {
background-color: #1a3a29;
background-image:
radial-gradient(circle at 50% 50%, rgba(26, 58, 41, 0.9) 0%, rgba(14, 32, 22, 1) 100%),
repeating-linear-gradient(45deg, rgba(0,0,0,0.03) 0px, rgba(0,0,0,0.03) 2px, transparent 2px, transparent 8px);
font-family: 'Plus Jakarta Sans', sans-serif;
}
.leather-texture {
background-color: #a64d2a;
background-image:
radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.08) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(0, 0, 0, 0.18) 0%, transparent 60%);
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4 sm:p-8 select-none">
<!-- Outer Tabletop QR Stand Plaque -->
<main class="w-full max-w-[380px] leather-texture rounded-[2.5rem] p-6 sm:p-7 flex flex-col items-center text-white relative shadow-[0_25px_60px_rgba(0,0,0,0.6),0_4px_10px_rgba(0,0,0,0.3)] border-2 border-black/30">
<!-- Subtle Inner Border Accent -->
<div class="absolute inset-2.5 rounded-[2rem] border border-white/10 pointer-events-none"></div>
<!-- 01. Top Brand Badge -->
<header class="flex flex-col items-center text-center mt-2 z-10">
<div class="border-2 border-goldWheat rounded-xl px-4 py-1.5 flex flex-col items-center mb-5 bg-[#a64d2a]/80 shadow-md">
<div class="flex items-center gap-1 text-goldWheat font-black text-lg sm:text-xl tracking-wider uppercase font-display">
<span>THE URBAN</span>
<!-- Flame Icon -->
<svg class="w-4 h-4 sm:w-5 sm:h-5 fill-goldWheat" viewBox="0 0 24 24">
<path d="M12 2c1.5 3.5 4 6.5 4 10 0 4.42-3.58 8-8 8s-8-3.58-8-8c0-3.5 2.5-6.5 4-10 .5 2 1.5 3.5 3 4.5.5-2.5 2-5 5-6.5z"/>
</svg>
</div>
<span class="text-goldWheat font-black text-2xl tracking-[0.22em] uppercase font-display -mt-1">
BURGER
</span>
</div>
<!-- Main Action Callout -->
<h1 class="font-display font-black text-2xl sm:text-3xl tracking-tight uppercase leading-[0.92] text-white drop-shadow">
DIGITAL MENU<br>
<span class="tracking-wider">SCAN TO ORDER</span>
</h1>
</header>
<!-- 02. Centered Branded QR Code Box -->
<section class="w-60 h-60 sm:w-64 sm:h-64 bg-qrCream rounded-3xl p-5 shadow-2xl flex items-center justify-center my-6 relative border-2 border-black/15 z-10">
<svg class="w-full h-full text-rustStand" viewBox="0 0 100 100" fill="currentColor">
<!-- Top-Left Target -->
<rect x="6" y="6" width="28" height="28" rx="8" fill="currentColor"/>
<rect x="11" y="11" width="18" height="18" rx="5" fill="#f8f3eb"/>
<rect x="15" y="15" width="10" height="10" rx="3" fill="currentColor"/>
<!-- Top-Right Target -->
<rect x="66" y="6" width="28" height="28" rx="8" fill="currentColor"/>
<rect x="71" y="11" width="18" height="18" rx="5" fill="#f8f3eb"/>
<rect x="75" y="15" width="10" height="10" rx="3" fill="currentColor"/>
<!-- Bottom-Left Target -->
<rect x="6" y="66" width="28" height="28" rx="8" fill="currentColor"/>
<rect x="11" y="71" width="18" height="18" rx="5" fill="#f8f3eb"/>
<rect x="15" y="75" width="10" height="10" rx="3" fill="currentColor"/>
<!-- Data Matrix Pattern -->
<rect x="38" y="8" width="8" height="8" rx="2"/>
<rect x="50" y="8" width="8" height="14" rx="2"/>
<rect x="38" y="22" width="14" height="8" rx="2"/>
<rect x="8" y="38" width="8" height="12" rx="2"/>
<rect x="20" y="42" width="12" height="8" rx="2"/>
<rect x="38" y="38" width="24" height="24" rx="5"/>
<rect x="42" y="42" width="16" height="16" rx="3" fill="#f8f3eb"/>
<rect x="46" y="46" width="8" height="8" rx="2" fill="currentColor"/>
<rect x="68" y="38" width="10" height="14" rx="2"/>
<rect x="82" y="42" width="10" height="10" rx="2"/>
<rect x="38" y="68" width="12" height="10" rx="2"/>
<rect x="54" y="72" width="8" height="18" rx="2"/>
<rect x="68" y="68" width="12" height="12" rx="2"/>
<rect x="84" y="72" width="8" height="8" rx="2"/>
<rect x="68" y="84" width="24" height="8" rx="2"/>
</svg>
</section>
<!-- 03. Prompt & Category Highlights -->
<footer class="w-full relative px-4 text-center z-10 pb-2">
<p class="text-white/90 text-sm font-sans tracking-wide mb-3 font-semibold">
Use your phone's camera
</p>
<!-- Left Decorative Burger Icon -->
<div class="absolute left-1 bottom-4 text-goldWheat/90">
<svg class="w-10 h-10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round">
<path d="M4 10a8 8 0 0 1 16 0H4z"/>
<rect x="3" y="13" width="18" height="3" rx="1.5"/>
<path d="M5 19a3 3 0 0 0 14 0H5z"/>
</svg>
</div>
<!-- Right Decorative Shake Icon -->
<div class="absolute right-1 bottom-4 text-goldWheat/90">
<svg class="w-10 h-10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round">
<path d="M7 8h10l-1.5 13h-7L7 8z"/>
<path d="M5 8h14"/>
<path d="M12 2v6"/>
<path d="M9 2l3 6"/>
</svg>
</div>
<!-- Category Text Stack -->
<div class="flex flex-col gap-1.5 max-w-[190px] mx-auto text-white font-display font-extrabold uppercase tracking-widest text-base">
<div class="py-0.5">BURGERS</div>
<div class="w-full h-[1px] bg-white/25"></div>
<div class="py-0.5">FRIES</div>
<div class="w-full h-[1px] bg-white/25"></div>
<div class="py-0.5">SHAKES</div>
<div class="w-full h-[1px] bg-white/25"></div>
<div class="py-0.5 text-sm tracking-wider">VEGAN OPTIONS</div>
</div>
</footer>
</main>
</body>
</html>
```
## Design Philosophy
- **Tactile Leather Plaque Aesthetic**: Earthy rust-terracotta background paired with an ambient forest green setting to replicate physical wooden/leather restaurant table stands.
- **High-Scanability Contrast**: Clean high-contrast cream QR card embedded with rust custom rounded pixels for instant mobile scanning.
- **Bold Urban Typography**: Punchy condensed uppercase headings paired with clean line-art food icons for quick menu category orientation.