mavweb: ui design system refresh — shared nav, cards, component classes
- Rewrote ui.css with design tokens, card/btn/badge/dot components - All pages wrapped in <main class=page> with max-width container - Replaced inline <style> blocks with ui.css classes - passkey page now uses shared nav.site template - PWA voice page unified under shared nav.site (no more separate tab nav) - Inline lang toggle moved from nav to voice page body
This commit is contained in:
+114
-44
@@ -1,65 +1,135 @@
|
||||
/* maven web ui — one theme for every server-rendered page.
|
||||
Palette and type mirror the PWA (static/index.html): dark, restrained,
|
||||
#00aaff accent. Pages carry NO inline <style> beyond true one-offs. */
|
||||
/* maven design system — dark, restrained, #00aaff accent.
|
||||
Every server-rendered page uses this single stylesheet.
|
||||
Pages carry NO inline <style> beyond true one-offs. */
|
||||
|
||||
/* ── Design Tokens ── */
|
||||
:root{
|
||||
--bg:#111; --panel:#1a1a2e; --line:#222; --border:#333;
|
||||
--fg:#ddd; --soft:#aaa; --muted:#888; --dim:#555;
|
||||
--accent:#00aaff; --ok:#00ff88; --warn:#ffaa00; --err:#ff4444;
|
||||
--bg:#111;--panel:#1a1a2e;--line:#222;--border:#333;
|
||||
--fg:#ddd;--soft:#aaa;--muted:#888;--dim:#555;
|
||||
--accent:#00aaff;--ok:#00ff88;--warn:#ffaa00;--err:#ff4444;
|
||||
|
||||
--surface-page:var(--bg);
|
||||
--surface-card:var(--panel);
|
||||
--surface-raised:#222;
|
||||
--surface-input:#181818;
|
||||
--surface-hover:rgba(255,255,255,.04);
|
||||
|
||||
--fs-xs:.7rem;--fs-sm:.8rem;--fs-base:14px;
|
||||
--fs-lg:1.25rem;--fs-xl:1.5rem;
|
||||
--space-xs:.25rem;--space-sm:.5rem;--space-md:.75rem;
|
||||
--space-lg:1.25rem;--space-xl:2rem;
|
||||
--radius-sm:3px;--radius-md:6px;--radius-lg:10px;
|
||||
--shadow-sm:0 1px 3px rgba(0,0,0,.3);
|
||||
--shadow-md:0 2px 8px rgba(0,0,0,.4);
|
||||
--transition:150ms ease;
|
||||
}
|
||||
|
||||
/* ── Reset / Base ── */
|
||||
*{box-sizing:border-box}
|
||||
body{background:var(--bg);color:var(--fg);font:14px/1.5 system-ui,sans-serif;
|
||||
margin:0;padding:1rem;-webkit-text-size-adjust:100%}
|
||||
h1,h2{font-weight:400;color:var(--muted);letter-spacing:.1em;text-transform:uppercase}
|
||||
h1{font-size:1.2rem;margin:.2rem 0 .6rem}
|
||||
h2{font-size:.95rem;margin:1.4rem 0 .3rem}
|
||||
h1 small,h2 small{color:var(--dim);letter-spacing:0;text-transform:none}
|
||||
body{background:var(--surface-page);color:var(--fg);font:var(--fs-base)/1.6 system-ui,sans-serif;
|
||||
margin:0;padding:1rem;-webkit-text-size-adjust:100%;min-height:100vh}
|
||||
|
||||
/* ── Typography ── */
|
||||
h1,h2,h3{font-weight:400;color:var(--muted);letter-spacing:.1em;text-transform:uppercase}
|
||||
h1{font-size:var(--fs-lg);margin:0 0 var(--space-lg)}
|
||||
h2{font-size:.95rem;margin:var(--space-lg) 0 var(--space-sm)}
|
||||
h3{font-size:.85rem;margin:var(--space-md) 0 var(--space-xs)}
|
||||
h1 small,h2 small,h3 small{color:var(--dim);letter-spacing:0;text-transform:none}
|
||||
a{color:var(--accent);text-decoration:none}
|
||||
a:hover{text-decoration:underline}
|
||||
|
||||
/* shared site nav (the "nav" template partial) */
|
||||
/* ── Page Layout ── */
|
||||
.page{max-width:80rem;margin:0 auto;padding:0 .5rem var(--space-xl)}
|
||||
|
||||
/* ── Nav (shared site nav) ── */
|
||||
nav.site{display:flex;gap:1rem;flex-wrap:wrap;align-items:center;
|
||||
border-bottom:1px solid var(--line);padding-bottom:.6rem;margin-bottom:1rem}
|
||||
nav.site a{font-size:.8rem;letter-spacing:.08em;text-transform:uppercase;color:var(--dim)}
|
||||
border-bottom:1px solid var(--line);padding-bottom:.6rem;margin-bottom:var(--space-lg)}
|
||||
nav.site a{font-size:var(--fs-sm);letter-spacing:.08em;text-transform:uppercase;
|
||||
color:var(--dim);transition:color var(--transition)}
|
||||
nav.site a:hover{color:var(--fg);text-decoration:none}
|
||||
nav.site a.active{color:var(--accent)}
|
||||
|
||||
/* tables: always inside a .scroll wrapper so wide data pans instead of
|
||||
breaking the page on a phone */
|
||||
.scroll{overflow-x:auto}
|
||||
table{width:100%;border-collapse:collapse;margin-top:.4rem}
|
||||
th,td{padding:.35rem .5rem;text-align:left;vertical-align:top;
|
||||
/* ── Cards ── */
|
||||
.card{background:var(--surface-card);border-radius:var(--radius-md);
|
||||
padding:var(--space-md) var(--space-lg);margin-bottom:var(--space-lg);
|
||||
box-shadow:var(--shadow-sm)}
|
||||
.card-title{font-size:.95rem;margin:0 0 var(--space-sm);color:var(--muted);
|
||||
display:flex;align-items:center;gap:var(--space-sm)}
|
||||
.card-sub{font-size:var(--fs-sm);color:var(--dim);margin:0 0 var(--space-sm)}
|
||||
|
||||
/* ── Tables ── */
|
||||
.scroll{overflow-x:auto;margin-bottom:var(--space-sm)}
|
||||
table{width:100%;border-collapse:collapse}
|
||||
th,td{padding:.4rem .6rem;text-align:left;vertical-align:top;
|
||||
border-bottom:1px solid var(--line)}
|
||||
th{color:var(--dim);font-size:.75rem;text-transform:uppercase;
|
||||
letter-spacing:.05em;white-space:nowrap}
|
||||
th{color:var(--dim);font-size:var(--fs-xs);text-transform:uppercase;
|
||||
letter-spacing:.05em;white-space:nowrap;font-weight:500}
|
||||
td{color:var(--soft)}
|
||||
tr:hover td{background:var(--surface-hover)}
|
||||
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
|
||||
code,.key{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--ok)}
|
||||
|
||||
/* status colors — nudge outcomes, presence, booleans */
|
||||
.pending{color:var(--muted)}.acted{color:var(--ok)}
|
||||
.snoozed{color:var(--warn)}.ignored{color:var(--err)}
|
||||
.pres,.green{color:var(--ok)}.away,.gray{color:var(--muted)}.red{color:var(--err)}
|
||||
.badge{font-size:.75rem;color:var(--dim);background:var(--panel);
|
||||
padding:.15rem .35rem;border-radius:3px;white-space:nowrap}
|
||||
.updated,.muted{color:var(--dim);font-size:.85rem}
|
||||
.empty{color:var(--dim);padding:2rem;text-align:center}
|
||||
/* ── Status / Semantic Colors ── */
|
||||
.pending,.away,.gray{color:var(--muted)}
|
||||
.acted,.pres,.green{color:var(--ok)}
|
||||
.snoozed{color:var(--warn)}
|
||||
.ignored,.red{color:var(--err)}
|
||||
.updated,.muted{color:var(--dim);font-size:var(--fs-sm)}
|
||||
.empty{color:var(--dim);padding:var(--space-xl);text-align:center}
|
||||
.voided{opacity:.45;text-decoration:line-through}
|
||||
.void-badge{color:var(--dim);font-size:.8rem;margin-right:.3rem}
|
||||
.void-badge{color:var(--dim);font-size:var(--fs-sm);margin-right:.3rem}
|
||||
|
||||
/* controls */
|
||||
button{font:inherit;font-size:.85rem;background:var(--panel);color:var(--fg);
|
||||
border:1px solid var(--border);border-radius:3px;padding:.25rem .6rem;cursor:pointer}
|
||||
button:hover{border-color:var(--accent)}
|
||||
button:disabled{opacity:.4;cursor:not-allowed}
|
||||
input[type=text]{font:inherit;font-size:.85rem;background:var(--bg);color:var(--fg);
|
||||
border:1px solid var(--border);border-radius:3px;padding:.25rem .4rem;max-width:100%}
|
||||
input[type=checkbox]{accent-color:var(--accent)}
|
||||
label{color:var(--soft)}
|
||||
/* ── Badges ── */
|
||||
.badge{font-size:var(--fs-xs);color:var(--dim);background:var(--surface-raised);
|
||||
padding:.15rem .4rem;border-radius:var(--radius-sm);white-space:nowrap}
|
||||
.badge-accent{color:var(--accent);background:rgba(0,170,255,.12)}
|
||||
.badge-ok{color:var(--ok);background:rgba(0,255,136,.1)}
|
||||
.badge-warn{color:var(--warn);background:rgba(255,170,0,.12)}
|
||||
.badge-err{color:var(--err);background:rgba(255,68,68,.12)}
|
||||
|
||||
/* inline feedback (/history revert, /tools enable, /auth/passkey) */
|
||||
.msg{margin:.6rem 0;padding:.5rem .7rem;border-radius:3px;border:1px solid var(--line)}
|
||||
/* ── Status Dot ── */
|
||||
.dot{display:inline-block;width:8px;height:8px;border-radius:50%;vertical-align:middle}
|
||||
.dot-ok{background:var(--ok);box-shadow:0 0 5px var(--ok)}
|
||||
.dot-warn{background:var(--warn);box-shadow:0 0 5px var(--warn)}
|
||||
.dot-err{background:var(--err);box-shadow:0 0 5px var(--err)}
|
||||
.dot-dim{background:var(--dim)}
|
||||
|
||||
/* ── Buttons ── */
|
||||
.btn{font:inherit;font-size:var(--fs-sm);background:var(--surface-card);color:var(--fg);
|
||||
border:1px solid var(--border);border-radius:var(--radius-sm);padding:.35rem .7rem;
|
||||
cursor:pointer;transition:border-color var(--transition),background var(--transition);
|
||||
display:inline-flex;align-items:center;gap:.3rem}
|
||||
.btn:hover{border-color:var(--accent);background:var(--surface-hover)}
|
||||
.btn:disabled{opacity:.4;cursor:not-allowed}
|
||||
.btn-primary{background:var(--accent);color:#111;border-color:var(--accent);font-weight:500}
|
||||
.btn-primary:hover{background:#0099ee;border-color:#0099ee}
|
||||
.btn-danger{border-color:var(--err);color:var(--err)}
|
||||
.btn-danger:hover{border-color:var(--err);background:rgba(255,68,68,.1)}
|
||||
|
||||
/* ── Form Elements ── */
|
||||
input[type=text],input[type=url]{font:inherit;font-size:var(--fs-sm);
|
||||
background:var(--surface-input);color:var(--fg);
|
||||
border:1px solid var(--border);border-radius:var(--radius-sm);
|
||||
padding:.35rem .5rem;max-width:100%;transition:border-color var(--transition)}
|
||||
input[type=text]:focus,input[type=url]:focus{border-color:var(--accent);outline:none}
|
||||
input[type=checkbox]{accent-color:var(--accent);width:1rem;height:1rem;vertical-align:middle}
|
||||
label{color:var(--soft);cursor:pointer;display:inline-flex;align-items:center;gap:.3rem}
|
||||
|
||||
/* ── Messages / Feedback ── */
|
||||
.msg{margin:.6rem 0;padding:.5rem .7rem;border-radius:var(--radius-sm);
|
||||
border:1px solid var(--line);font-size:var(--fs-sm)}
|
||||
.msg-ok{border-color:var(--ok);color:var(--ok)}
|
||||
.msg-err{border-color:var(--err);color:var(--err)}
|
||||
#msg{white-space:pre-wrap}
|
||||
|
||||
details{color:var(--soft);font-size:.85rem}
|
||||
summary{cursor:pointer;color:var(--dim)}
|
||||
/* ── Collapsible Details ── */
|
||||
details{color:var(--soft);font-size:var(--fs-sm)}
|
||||
summary{cursor:pointer;color:var(--dim);transition:color var(--transition)}
|
||||
summary:hover{color:var(--fg)}
|
||||
details[open]{margin-top:var(--space-xs)}
|
||||
|
||||
/* ── Utilities ── */
|
||||
.val{word-break:break-all;max-width:20rem}
|
||||
.text-max{max-width:22rem}
|
||||
.input-wide{width:20rem}
|
||||
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
|
||||
|
||||
Reference in New Issue
Block a user