fix: comprehensive iPhone UI overhaul — glassmorphism, responsive layouts, theme unification

- base.html: add missing {% block extra_styles %}, mobile hamburger menu with
  slide-out nav, interactive-widget viewport meta, -webkit-text-size-adjust
- style.css: define 15+ missing CSS variables (--bg-secondary, --text-muted,
  --accent, --success, --danger, etc.), add missing utility classes (.grid,
  .stat, .agent-card, .agent-avatar, .form-group), glassmorphism card effects,
  iPhone breakpoints (768px, 390px), 44pt min touch targets, smooth animations
- mobile.html: rewrite with proper theme variables, glass cards, touch-friendly
  quick actions grid, chat with proper message bubbles
- swarm_live.html: replace undefined CSS vars, use mc-panel theme cards
- marketplace.html: responsive agent cards that stack on iPhone, themed pricing
- voice_button.html & voice_enhanced.html: proper theme integration, touch-sized
  buttons, themed result containers
- create_task.html: mobile-friendly forms with 16px font (prevents iOS zoom)
- tools.html & creative.html: themed headers, responsive column stacking
- spark.html: replace all hardcoded blue (#00d4ff) colors with theme purple/orange
- briefing.html: replace hardcoded bootstrap colors with theme variables

Fixes: header nav overflow on iPhone (7 links in single row), missing
extra_styles block silently dropping child template styles, undefined CSS
variables breaking mobile/swarm/marketplace/voice pages, sub-44pt touch
targets, missing -webkit-text-size-adjust, inconsistent color themes.

97 UI tests pass (91 UI-specific + 6 creative route).

https://claude.ai/code/session_01JiyhGyee2zoMN4p8xWYqEe
This commit is contained in:
Claude
2026-02-24 22:25:04 +00:00
parent d96b7593fc
commit 65a278dbee
13 changed files with 2121 additions and 1318 deletions

View File

@@ -2,10 +2,154 @@
{% block title %}Timmy Time — Morning Briefing{% endblock %}
{% block extra_styles %}
<style>
/* ── Briefing-specific styles ── */
.briefing-container { max-width: 680px; }
.briefing-header {
border-left: 3px solid var(--amber);
padding-left: 1rem;
}
.briefing-greeting {
font-size: 1.6rem;
font-weight: 700;
color: var(--amber);
letter-spacing: 0.04em;
font-family: var(--font);
}
.briefing-timestamp {
font-size: 0.75rem;
color: var(--text-dim);
margin-top: 0.25rem;
}
.briefing-ts-val { color: var(--text); }
.briefing-prose {
font-size: 1rem;
line-height: 1.75;
color: var(--text-bright);
white-space: pre-wrap;
word-break: break-word;
}
/* Approval cards */
.approval-card {
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 1rem;
margin-bottom: 0.75rem;
background: rgba(24, 10, 45, 0.5);
transition: border-color 0.2s;
}
.approval-card.approved {
border-color: var(--green);
opacity: 0.7;
}
.approval-card.rejected {
border-color: var(--red);
opacity: 0.7;
}
.approval-card-title {
font-weight: 600;
font-size: 0.95rem;
color: var(--text-bright);
margin-bottom: 0.25rem;
}
.approval-card-desc {
font-size: 0.85rem;
color: var(--text);
margin-bottom: 0.5rem;
}
.approval-card-action {
font-size: 0.8rem;
color: var(--text-dim);
font-family: var(--font);
margin-bottom: 0.75rem;
border-left: 2px solid var(--border);
padding-left: 0.5rem;
}
.impact-badge {
font-size: 0.7rem;
padding: 0.2em 0.5em;
border-radius: 4px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.impact-low { background: var(--green-dim); color: var(--green); }
.impact-medium { background: var(--amber-dim); color: var(--amber); }
.impact-high { background: var(--red-dim); color: var(--red); }
.approval-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.btn-approve {
background: var(--green-dim);
color: var(--green);
border: 1px solid var(--green);
border-radius: var(--radius-sm);
padding: 0.4rem 0.9rem;
font-size: 0.82rem;
font-family: var(--font);
cursor: pointer;
min-height: 44px;
transition: background 0.15s;
touch-action: manipulation;
}
.btn-approve:hover { background: rgba(0, 232, 122, 0.2); }
.btn-reject {
background: transparent;
color: var(--red);
border: 1px solid var(--red);
border-radius: var(--radius-sm);
padding: 0.4rem 0.9rem;
font-size: 0.82rem;
font-family: var(--font);
cursor: pointer;
min-height: 44px;
transition: background 0.15s;
touch-action: manipulation;
}
.btn-reject:hover { background: rgba(255, 68, 85, 0.1); }
.no-approvals {
text-align: center;
color: var(--text-dim);
padding: 2rem 0;
font-size: 0.9rem;
}
.btn-refresh {
background: transparent;
color: var(--text);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 0.3rem 0.7rem;
font-size: 0.75rem;
font-family: var(--font);
cursor: pointer;
text-decoration: none;
display: inline-block;
transition: border-color 0.15s;
}
.btn-refresh:hover { border-color: var(--purple); color: var(--text-bright); }
@media (max-width: 576px) {
.briefing-greeting { font-size: 1.3rem; }
.briefing-prose { font-size: 0.95rem; }
}
</style>
{% endblock %}
{% block content %}
<div class="container briefing-container py-4">
<!-- Header -->
<div class="briefing-header mb-4">
<div class="briefing-greeting">Good morning.</div>
<div class="briefing-timestamp">
@@ -18,191 +162,26 @@
</div>
</div>
<!-- Summary -->
<div class="card mc-panel briefing-summary mb-5">
<div class="card mc-panel briefing-summary mb-4">
<div class="card-header mc-panel-header">// TIMMY&rsquo;S REPORT</div>
<div class="card-body p-4">
<div class="briefing-prose">{{ briefing.summary | e }}</div>
</div>
</div>
<!-- Approval Queue -->
<div class="card mc-panel">
<div class="card-header mc-panel-header d-flex justify-content-between align-items-center">
<span>// APPROVAL QUEUE</span>
<span class="badge bg-warning text-dark"
id="approval-count">{{ briefing.approval_items | length }} pending</span>
<span class="badge badge-warning" id="approval-count">{{ briefing.approval_items | length }} pending</span>
</div>
<div class="card-body p-3"
id="approval-queue"
hx-get="/briefing/approvals"
hx-trigger="load"
hx-swap="innerHTML">
<!-- HTMX fills this on load with live data -->
<div class="text-center text-muted py-3">Loading approval items&hellip;</div>
<div style="text-align:center; color:var(--text-dim); padding:16px; font-size:0.85rem;">Loading approval items&hellip;</div>
</div>
</div>
</div>
<style>
/* ------------------------------------------------------------------ */
/* Briefing-specific styles — mobile-first */
/* ------------------------------------------------------------------ */
.briefing-container {
max-width: 680px;
}
.briefing-header {
border-left: 3px solid var(--mc-amber, #ffc107);
padding-left: 1rem;
}
.briefing-greeting {
font-size: 1.6rem;
font-weight: 700;
color: var(--mc-amber, #ffc107);
letter-spacing: 0.04em;
font-family: 'JetBrains Mono', monospace;
}
.briefing-timestamp {
font-size: 0.75rem;
color: #6c757d;
margin-top: 0.25rem;
}
.briefing-ts-val {
color: #adb5bd;
}
.briefing-prose {
font-size: 1rem;
line-height: 1.75;
color: #dee2e6;
white-space: pre-wrap;
word-break: break-word;
}
/* Approval cards */
.approval-card {
border: 1px solid #2a3a4a;
border-radius: 6px;
padding: 1rem;
margin-bottom: 0.75rem;
background: #0d1b2a;
transition: border-color 0.2s;
}
.approval-card.approved {
border-color: #198754;
opacity: 0.7;
}
.approval-card.rejected {
border-color: #dc3545;
opacity: 0.7;
}
.approval-card-title {
font-weight: 600;
font-size: 0.95rem;
color: #f8f9fa;
margin-bottom: 0.25rem;
}
.approval-card-desc {
font-size: 0.85rem;
color: #adb5bd;
margin-bottom: 0.5rem;
}
.approval-card-action {
font-size: 0.8rem;
color: #6c757d;
font-family: 'JetBrains Mono', monospace;
margin-bottom: 0.75rem;
border-left: 2px solid #495057;
padding-left: 0.5rem;
}
.impact-badge {
font-size: 0.7rem;
padding: 0.2em 0.5em;
border-radius: 4px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.impact-low { background: #198754; color: #fff; }
.impact-medium { background: #fd7e14; color: #fff; }
.impact-high { background: #dc3545; color: #fff; }
.approval-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.btn-approve {
background: #198754;
color: #fff;
border: none;
border-radius: 4px;
padding: 0.4rem 0.9rem;
font-size: 0.82rem;
font-family: 'JetBrains Mono', monospace;
cursor: pointer;
min-height: 44px;
}
.btn-approve:hover { background: #157347; }
.btn-reject {
background: transparent;
color: #dc3545;
border: 1px solid #dc3545;
border-radius: 4px;
padding: 0.4rem 0.9rem;
font-size: 0.82rem;
font-family: 'JetBrains Mono', monospace;
cursor: pointer;
min-height: 44px;
}
.btn-reject:hover { background: #dc354520; }
.no-approvals {
text-align: center;
color: #6c757d;
padding: 2rem 0;
font-size: 0.9rem;
}
/* Refresh button */
.btn-refresh {
background: transparent;
color: #adb5bd;
border: 1px solid #495057;
border-radius: 4px;
padding: 0.3rem 0.7rem;
font-size: 0.75rem;
font-family: 'JetBrains Mono', monospace;
cursor: pointer;
text-decoration: none;
display: inline-block;
}
.btn-refresh:hover {
color: #f8f9fa;
border-color: #6c757d;
}
@media (max-width: 576px) {
.briefing-greeting { font-size: 1.3rem; }
.briefing-prose { font-size: 0.95rem; }
}
</style>
{% endblock %}