Full LCARS library-computer interface for a sci-fi podcast/media outfit. Codeless .bnp. Re-skins every mandatory builtin inside LCARS framing and ships the full Wave A surface. - 49 mandatory template overrides (chrome, marketing, primitives, commerce, blog family, auth, page-suggestions), field-faithful re-skins of the frozen builtin defaults; identity carried by the lcars-* class system. - 8 page templates (default+sidebar rail, full-width, full-display, landing, article, blog-index, contact, auth) with elbow-frame chrome. - 4 persona blocks: episode_console, crew_roster, stardate_log, transmission_status. Legacy lcars_header/sidebar/panel removed (now overrides + page chrome). - 5 dual-mode presets (canonical black + daylight-ops cream), all 19 tokens. - Bundled Antonio + Share Tech Mono (OFL); email-safe LCARS wrapper. - Seed "Subspace Signal": home, about, 3 episodes+articles, contact (hail_signals table + row_inserted email-admins workflow), login. - GO BIG motion: dependency-free canvas panel-sweep on the hero (lazy-init, reduced-motion static frame, no-JS fallback). Build + check-safety green. Visual UNVERIFIED until Wave B. Known frozen-cms limits (contract §11 auth/404 non-dispatch, §12 provider-backed empty lists) authored faithfully. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
4.0 KiB
Plaintext
35 lines
4.0 KiB
Plaintext
{# contact-form override — server-driven; block-id resolution, {% form %} wiring, honeypot, and field loop copied verbatim from the builtin, reskinned with lcars-form primitives. #}
|
|
{% with bid=_block_id|default:context.blockId %}
|
|
<section id="contact-form-{{ bid }}" class="lcars-section {{ class }}"><div class="lcars-content-well" style="max-width:640px;">
|
|
{% if form.submitted %}
|
|
<div class="lcars-card lcars-card-accent lcars-alert-ok" style="text-align:center;padding:2rem;">
|
|
<span class="lcars-mark lcars-mark-circle" aria-hidden="true" style="display:inline-block;margin-bottom:1rem;"></span>
|
|
<p class="lcars-display" style="margin:0;font-size:1.125rem;">{{ form.message|default:successMessage|default:"Thanks — your message has been sent." }}</p>
|
|
</div>
|
|
{% else %}
|
|
{% if heading %}<h2 class="lcars-heading" style="font-size:clamp(1.75rem, 3vw, 2.25rem);margin:0 0 0.75rem 0;"><span class="lcars-heading-h2-accent">{{ heading }}</span></h2>{% endif %}
|
|
{% if description %}<p class="lcars-lede" style="margin:0 0 2rem 0;color:hsl(var(--muted-foreground));">{{ description }}</p>{% endif %}
|
|
{% if form.errors._form %}<div class="lcars-alert-err" style="margin-bottom:1.5rem;border:1px solid hsl(var(--destructive));border-radius:4px;padding:0.75rem 1rem;font-size:0.875rem;color:hsl(var(--destructive));background:hsl(var(--destructive) / 0.08);">{{ form.errors._form }}</div>{% endif %}
|
|
{% with formAction="/api/blocks/"|add:bid|add:"/submit" formTarget="#contact-form-"|add:bid %}
|
|
{% form action=formAction hx_target=formTarget hx_swap="outerHTML" class="lcars-form-grid" %}
|
|
{% for field in fields %}
|
|
<div class="lcars-field {% if field.width == "half" %}{% else %}lcars-field--full{% endif %}">
|
|
{% if field.label %}<label class="lcars-label" for="cf-{{ bid }}-{{ field.name }}">{{ field.label }}{% if field.required %} <span style="color:hsl(var(--destructive));">*</span>{% endif %}</label>{% endif %}
|
|
{% if field.type == "textarea" %}
|
|
<textarea id="cf-{{ bid }}-{{ field.name }}" name="{{ field.name }}" rows="5"{% if field.required %} required{% endif %}{% if field.placeholder %} placeholder="{{ field.placeholder }}"{% endif %} class="lcars-input"></textarea>
|
|
{% elif field.type == "select" %}
|
|
<select id="cf-{{ bid }}-{{ field.name }}" name="{{ field.name }}"{% if field.required %} required{% endif %} class="lcars-input">{% if field.placeholder %}<option value="">{{ field.placeholder }}</option>{% endif %}{% for opt in field.options %}<option value="{{ opt.value }}">{{ opt.label|default:opt.value }}</option>{% endfor %}</select>
|
|
{% else %}
|
|
<input id="cf-{{ bid }}-{{ field.name }}" name="{{ field.name }}" type="{{ field.type|default:"text" }}"{% if field.required %} required{% endif %}{% if field.placeholder %} placeholder="{{ field.placeholder }}"{% endif %} class="lcars-input">
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
<div class="lcars-field--full" aria-hidden="true" style="display:none;"><label>Leave this field empty<input type="text" name="website" tabindex="-1" autocomplete="off"></label></div>
|
|
<div class="lcars-field--full"><button type="submit" class="lcars-btn-primary">{{ submitLabel|default:"Send message" }}</button></div>
|
|
{% endform %}
|
|
{% endwith %}
|
|
{% endif %}
|
|
</div></section>
|
|
<style>#contact-form-{{ bid }} .lcars-form-grid{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.25rem;margin-top:2rem;}#contact-form-{{ bid }} .lcars-field--full{grid-column:1 / -1;}#contact-form-{{ bid }} .lcars-label{display:block;margin-bottom:0.375rem;font-size:0.8125rem;font-weight:500;color:hsl(var(--foreground));font-family:var(--font-heading, "Antonio", "Antonio", system-ui, sans-serif);}#contact-form-{{ bid }} .lcars-input{width:100%;padding:0.5rem 0.75rem;font-size:0.9375rem;font-family:var(--font-body, "Antonio", system-ui, sans-serif);color:hsl(var(--foreground));background:hsl(var(--background));border:1px solid hsl(var(--input));border-radius:4px;box-sizing:border-box;}#contact-form-{{ bid }} .lcars-input:focus{outline:2px solid hsl(var(--ring));outline-offset:1px;}</style>
|
|
{% endwith %}
|