Design system refactor: shared CSS tokens, cleaner customer/admin pages, kiosk name privacy, v0.9.1
This commit is contained in:
parent
2f5050b29f
commit
cc27c5db48
10 changed files with 1490 additions and 1224 deletions
|
|
@ -4,221 +4,117 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Request Your Theme Song</title>
|
||||
<style>
|
||||
/*
|
||||
Customer-facing request page.
|
||||
Designed for convention booth tablets/phones. Shows the banner image and
|
||||
a styled card form for name, email, hobbies, facts, style, vocal gender,
|
||||
and extra requests. Hidden when the booth is marked closed.
|
||||
*/
|
||||
*{box-sizing:border-box;}
|
||||
body{
|
||||
font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
|
||||
background:linear-gradient(135deg,#111827 0%,#1e3a8a 50%,#111827 100%);
|
||||
color:#f3f4f6;
|
||||
margin:0;
|
||||
padding:1rem;
|
||||
line-height:1.5;
|
||||
min-height:100vh;
|
||||
}
|
||||
.container{max-width:680px;margin:0 auto;}
|
||||
.banner{
|
||||
width:100%;
|
||||
border-radius:1rem;
|
||||
box-shadow:0 10px 40px rgba(0,0,0,.4);
|
||||
margin-bottom:1.5rem;
|
||||
}
|
||||
.card{
|
||||
background:rgba(31,41,55,.9);
|
||||
padding:1.5rem;
|
||||
border-radius:1rem;
|
||||
box-shadow:0 10px 25px rgba(0,0,0,.3);
|
||||
border:1px solid rgba(96,165,250,.2);
|
||||
}
|
||||
h1{
|
||||
margin-top:0;
|
||||
color:#60a5fa;
|
||||
text-align:center;
|
||||
font-size:1.7rem;
|
||||
}
|
||||
.subtitle{
|
||||
text-align:center;
|
||||
color:#9ca3af;
|
||||
margin-bottom:1.5rem;
|
||||
}
|
||||
label{
|
||||
display:block;
|
||||
margin-top:1rem;
|
||||
font-weight:600;
|
||||
color:#93c5fd;
|
||||
}
|
||||
input,textarea{
|
||||
width:100%;
|
||||
padding:.7rem;
|
||||
border-radius:.5rem;
|
||||
border:1px solid #374151;
|
||||
background:#111827;
|
||||
color:#f3f4f6;
|
||||
font:inherit;
|
||||
margin-top:.25rem;
|
||||
}
|
||||
select{
|
||||
width:100%;
|
||||
padding:.7rem;
|
||||
border-radius:.5rem;
|
||||
border:1px solid #374151;
|
||||
background:#111827;
|
||||
color:#f3f4f6;
|
||||
font:inherit;
|
||||
margin-top:.25rem;
|
||||
}
|
||||
input:focus,textarea:focus,select:focus{
|
||||
outline:none;
|
||||
border-color:#60a5fa;
|
||||
box-shadow:0 0 0 3px rgba(96,165,250,.2);
|
||||
}
|
||||
textarea{min-height:90px;resize:vertical;}
|
||||
button{
|
||||
margin-top:1.5rem;
|
||||
width:100%;
|
||||
padding:1rem;
|
||||
border:none;
|
||||
border-radius:.5rem;
|
||||
background:linear-gradient(90deg,#3b82f6,#8b5cf6);
|
||||
color:#fff;
|
||||
font-weight:700;
|
||||
font-size:1.1rem;
|
||||
cursor:pointer;
|
||||
box-shadow:0 4px 15px rgba(59,130,246,.4);
|
||||
transition:transform .1s,box-shadow .1s;
|
||||
}
|
||||
button:hover{
|
||||
transform:translateY(-2px);
|
||||
box-shadow:0 6px 20px rgba(139,92,246,.5);
|
||||
}
|
||||
.note{
|
||||
margin-top:1rem;
|
||||
font-size:.9rem;
|
||||
color:#9ca3af;
|
||||
text-align:center;
|
||||
}
|
||||
.sparkle{
|
||||
font-size:1.3rem;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.flash{
|
||||
padding:.8rem;
|
||||
background:#064e3b;
|
||||
border-radius:.5rem;
|
||||
margin-bottom:1rem;
|
||||
}
|
||||
.flash.error{background:#450a0a;}
|
||||
</style>
|
||||
<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=Outfit:wght@500;700;800&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/booth.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<body class="booth-page">
|
||||
<div class="container">
|
||||
<!-- Banner graphic for the booth. Served from /static. -->
|
||||
<img src="{{ url_for('static', filename='Trollgorithm_booth.jpg') }}" alt="Trollgorithm Theme Song Booth" class="banner">
|
||||
<img src="{{ url_for('static', filename='Trollgorithm_booth.jpg') }}" alt="Trollgorithm Theme Song Booth" class="banner">
|
||||
|
||||
<div class="card">
|
||||
<h1><span class="sparkle">🎵</span> Get Your Custom Theme Song <span class="sparkle">🎶</span></h1>
|
||||
<p class="subtitle">Tell us about yourself and we'll craft a one-of-a-kind song just for you.</p>
|
||||
<p class="subtitle"><a href="{{ url_for('faq') }}" target="_blank" rel="noopener noreferrer">Questions? Read our FAQ →</a> · <a href="{{ url_for('status_lookup') }}" target="_blank" rel="noopener noreferrer">Already ordered? Check status →</a></p>
|
||||
<div class="card">
|
||||
<h1 class="text-center">Get Your Custom Theme Song</h1>
|
||||
<p class="subtitle">Tell us about yourself and we'll craft a one-of-a-kind song just for you.</p>
|
||||
<p class="subtitle">
|
||||
<a href="{{ url_for('faq') }}" target="_blank" rel="noopener noreferrer">Questions? Read our FAQ</a>
|
||||
·
|
||||
<a href="{{ url_for('status_lookup') }}" target="_blank" rel="noopener noreferrer">Already ordered? Check status</a>
|
||||
</p>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="flash {{ category }}">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="flash {{ category }}">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<form method="POST">
|
||||
<label for="email">Email address</label>
|
||||
<input type="email" id="email" name="email" value="{{ form.email if form else '' }}" required>
|
||||
<form method="POST">
|
||||
<label for="email">Email address</label>
|
||||
<input type="email" id="email" name="email" value="{{ form.email if form else '' }}" required>
|
||||
|
||||
<label for="name">Name / persona you want in the song</label>
|
||||
<input type="text" id="name" name="name" value="{{ form.name if form else '' }}" required>
|
||||
<label for="name">Name / persona you want in the song</label>
|
||||
<input type="text" id="name" name="name" value="{{ form.name if form else '' }}" required>
|
||||
|
||||
<label for="pronouns">Pronouns <span style="color:#f87171">*</span></label>
|
||||
<select id="pronouns" name="pronouns" required>
|
||||
<option value="" {% if not form or not form.pronouns %}selected{% endif %}>— Select pronouns —</option>
|
||||
<option value="He/Him/His" {% if form and form.pronouns == 'He/Him/His' %}selected{% endif %}>He/Him/His</option>
|
||||
<option value="She/Her/Hers" {% if form and form.pronouns == 'She/Her/Hers' %}selected{% endif %}>She/Her/Hers</option>
|
||||
<option value="They/Them/Their" {% if form and form.pronouns == 'They/Them/Their' %}selected{% endif %}>They/Them/Their</option>
|
||||
</select>
|
||||
<label for="pronouns">Pronouns <span class="required">*</span></label>
|
||||
<select id="pronouns" name="pronouns" required>
|
||||
<option value="" {% if not form or not form.pronouns %}selected{% endif %}>— Select pronouns —</option>
|
||||
<option value="He/Him/His" {% if form and form.pronouns == 'He/Him/His' %}selected{% endif %}>He/Him/His</option>
|
||||
<option value="She/Her/Hers" {% if form and form.pronouns == 'She/Her/Hers' %}selected{% endif %}>She/Her/Hers</option>
|
||||
<option value="They/Them/Their" {% if form and form.pronouns == 'They/Them/Their' %}selected{% endif %}>They/Them/Their</option>
|
||||
</select>
|
||||
|
||||
<label for="hobbies">Hobbies & interests</label>
|
||||
<textarea id="hobbies" name="hobbies" maxlength="2000" placeholder="e.g. rock climbing, retro gaming, sourdough baking">{{ form.hobbies if form else '' }}</textarea>
|
||||
<label for="hobbies">Hobbies & interests</label>
|
||||
<textarea id="hobbies" name="hobbies" maxlength="2000" placeholder="e.g. rock climbing, retro gaming, sourdough baking">{{ form.hobbies if form else '' }}</textarea>
|
||||
|
||||
<label for="notable_facts">Notable things about you</label>
|
||||
<textarea id="notable_facts" name="notable_facts" maxlength="2000" placeholder="Anything fun, weird, or heroic we should mention">{{ form.notable_facts if form else '' }}</textarea>
|
||||
<label for="notable_facts">Notable things about you</label>
|
||||
<textarea id="notable_facts" name="notable_facts" maxlength="2000" placeholder="Anything fun, weird, or heroic we should mention">{{ form.notable_facts if form else '' }}</textarea>
|
||||
|
||||
<label for="decade">Decade / era <span style="color:#f87171">*</span></label>
|
||||
<select id="decade" name="decade" required>
|
||||
<option value="" {% if not form or not form.decade %}selected{% endif %}>— Select decade —</option>
|
||||
{% for d in decades %}
|
||||
<option value="{{ d }}" {% if form and form.decade == d %}selected{% endif %}>{{ d }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="decade">Decade / era <span class="required">*</span></label>
|
||||
<select id="decade" name="decade" required>
|
||||
<option value="" {% if not form or not form.decade %}selected{% endif %}>— Select decade —</option>
|
||||
{% for d in decades %}
|
||||
<option value="{{ d }}" {% if form and form.decade == d %}selected{% endif %}>{{ d }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<label for="basic_style">Basic style <span style="color:#f87171">*</span></label>
|
||||
<select id="basic_style" name="basic_style" required>
|
||||
<option value="" {% if not form or not form.basic_style %}selected{% endif %}>— Select style —</option>
|
||||
{% for g in genres %}
|
||||
<option value="{{ g }}" {% if form and form.basic_style == g %}selected{% endif %}>{{ g }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="basic_style">Basic style <span class="required">*</span></label>
|
||||
<select id="basic_style" name="basic_style" required>
|
||||
<option value="" {% if not form or not form.basic_style %}selected{% endif %}>— Select style —</option>
|
||||
{% for g in genres %}
|
||||
<option value="{{ g }}" {% if form and form.basic_style == g %}selected{% endif %}>{{ g }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<label for="additional_style">Additional style (optional)</label>
|
||||
<select id="additional_style" name="additional_style">
|
||||
<option value="" {% if not form or not form.additional_style %}selected{% endif %}>— None —</option>
|
||||
{% for g in genres %}
|
||||
<option value="{{ g }}" {% if form and form.additional_style == g %}selected{% endif %}>{{ g }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="additional_style">Additional style (optional)</label>
|
||||
<select id="additional_style" name="additional_style">
|
||||
<option value="" {% if not form or not form.additional_style %}selected{% endif %}>— None —</option>
|
||||
{% for g in genres %}
|
||||
<option value="{{ g }}" {% if form and form.additional_style == g %}selected{% endif %}>{{ g }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<p style="font-size:.85rem;color:#9ca3af;margin-top:.3rem">Selected style: <span id="style-preview">{% if form %}{{ form.decade or '' }}{% if form.decade and form.basic_style %}, {% endif %}{{ form.basic_style or '' }}{% if form.basic_style and form.additional_style %}, {% endif %}{{ form.additional_style or '' }}{% else %}—{% endif %}</span></p>
|
||||
<p class="copy-hint">Selected style: <span id="style-preview">{% if form %}{{ form.decade or '' }}{% if form.decade and form.basic_style %}, {% endif %}{{ form.basic_style or '' }}{% if form.basic_style and form.additional_style %}, {% endif %}{{ form.additional_style or '' }}{% else %}—{% endif %}</span></p>
|
||||
|
||||
<script>
|
||||
// Live preview of the combined style string as the customer changes dropdowns.
|
||||
(function(){
|
||||
const decade = document.getElementById('decade');
|
||||
const basic = document.getElementById('basic_style');
|
||||
const additional = document.getElementById('additional_style');
|
||||
const preview = document.getElementById('style-preview');
|
||||
function updatePreview(){
|
||||
const parts = [decade.value, basic.value, additional.value].filter(Boolean);
|
||||
preview.textContent = parts.length ? parts.join(', ') : '—';
|
||||
}
|
||||
decade.addEventListener('change', updatePreview);
|
||||
basic.addEventListener('change', updatePreview);
|
||||
additional.addEventListener('change', updatePreview);
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
const decade = document.getElementById('decade');
|
||||
const basic = document.getElementById('basic_style');
|
||||
const additional = document.getElementById('additional_style');
|
||||
const preview = document.getElementById('style-preview');
|
||||
function updatePreview(){
|
||||
const parts = [decade.value, basic.value, additional.value].filter(Boolean);
|
||||
preview.textContent = parts.length ? parts.join(', ') : '—';
|
||||
}
|
||||
decade.addEventListener('change', updatePreview);
|
||||
basic.addEventListener('change', updatePreview);
|
||||
additional.addEventListener('change', updatePreview);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<label for="vocal_gender">Preferred singer voice / gender</label>
|
||||
<select id="vocal_gender" name="vocal_gender">
|
||||
<option value="" {% if not form or not form.vocal_gender %}selected{% endif %}>No preference</option>
|
||||
<option value="female" {% if form and form.vocal_gender == 'female' %}selected{% endif %}>Female</option>
|
||||
<option value="male" {% if form and form.vocal_gender == 'male' %}selected{% endif %}>Male</option>
|
||||
<option value="non-binary" {% if form and form.vocal_gender == 'non-binary' %}selected{% endif %}>Non-binary / Gender-neutral</option>
|
||||
<option value="androgynous" {% if form and form.vocal_gender == 'androgynous' %}selected{% endif %}>Androgynous</option>
|
||||
<option value="other" {% if form and form.vocal_gender == 'other' %}selected{% endif %}>Other (mention in Extra Requests)</option>
|
||||
</select>
|
||||
<label for="vocal_gender">Preferred singer voice / gender</label>
|
||||
<select id="vocal_gender" name="vocal_gender">
|
||||
<option value="" {% if not form or not form.vocal_gender %}selected{% endif %}>No preference</option>
|
||||
<option value="female" {% if form and form.vocal_gender == 'female' %}selected{% endif %}>Female</option>
|
||||
<option value="male" {% if form and form.vocal_gender == 'male' %}selected{% endif %}>Male</option>
|
||||
<option value="non-binary" {% if form and form.vocal_gender == 'non-binary' %}selected{% endif %}>Non-binary / Gender-neutral</option>
|
||||
<option value="androgynous" {% if form and form.vocal_gender == 'androgynous' %}selected{% endif %}>Androgynous</option>
|
||||
<option value="other" {% if form and form.vocal_gender == 'other' %}selected{% endif %}>Other (mention in Extra Requests)</option>
|
||||
</select>
|
||||
|
||||
<label for="extra_requests">Anything else you want in the song? (Trollgorithm is very literal, so be careful!)</label>
|
||||
<textarea id="extra_requests" name="extra_requests" maxlength="2000" placeholder="Specific Lyrics, clean/explicit...">{{ form.extra_requests if form else '' }}</textarea>
|
||||
<label for="extra_requests">Anything else you want in the song? (Trollgorithm is very literal, so be careful!)</label>
|
||||
<textarea id="extra_requests" name="extra_requests" maxlength="2000" placeholder="Specific Lyrics, clean/explicit...">{{ form.extra_requests if form else '' }}</textarea>
|
||||
|
||||
<label for="stems_interest" style="display:flex;align-items:center;gap:.5rem;margin-top:1rem;cursor:pointer;">
|
||||
<input type="checkbox" id="stems_interest" name="stems_interest" value="1" {% if form and form.stems_interest %}checked{% endif %} style="width:auto;margin:0">
|
||||
I'm interested in STEMS / multitrack files (if you know, you know)
|
||||
</label>
|
||||
<label for="stems_interest" class="checkbox-label">
|
||||
<input type="checkbox" id="stems_interest" name="stems_interest" value="1" {% if form and form.stems_interest %}checked{% endif %}>
|
||||
I'm interested in STEMS / multitrack files (if you know, you know)
|
||||
</label>
|
||||
|
||||
<button type="submit">Submit Request</button>
|
||||
</form>
|
||||
<p class="note">Your info is only used to create and deliver your song.</p>
|
||||
</div>
|
||||
<button type="submit" class="button-block">Submit Request</button>
|
||||
</form>
|
||||
<p class="subtitle mb-0">Your info is only used to create and deliver your song.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue