Mobile Phase 8i: bottom-tab SVG line-icons + ·Ten31· top-bar wordmark
Replace the four bottom-tab emoji glyphs with the dc tabIcon SVGs (BottomTabIcon, currentColor so they flip with active/theme) and add the ·Ten31· mobile-wordmark to the top bar, making the page title desktop-only. Closes S1/S2 — Phase 8 (8a–8i) complete; next is deploy + device-test.
This commit is contained in:
+64
-8
@@ -2084,7 +2084,7 @@
|
||||
transition: color 0.15s ease;
|
||||
}
|
||||
.bottom-tab.active { color: var(--accent); }
|
||||
.bottom-tab-icon { font-size: 20px; line-height: 1; }
|
||||
.bottom-tab-icon { display: flex; align-items: center; justify-content: center; width: 20px; height: 20px; }
|
||||
.bottom-tab-label {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: var(--mobile-font-tab-label);
|
||||
@@ -2093,6 +2093,16 @@
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Mobile top-bar wordmark (Phase 8i) — the dc top bar's left mark (GridApp.dc.html:51).
|
||||
Replaces the redundant page title on mobile (each surface renders its own heading). */
|
||||
.mobile-wordmark {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Bottom-sheet primitive — replaces the centered modal + right slide-over on mobile.
|
||||
Rendered by the <BottomSheet> component; `.open` is toggled to animate in. */
|
||||
.sheet-scrim {
|
||||
@@ -14089,6 +14099,51 @@
|
||||
);
|
||||
};
|
||||
|
||||
// Bottom-tab line-icons (Phase 8i) — the dc tabIcon SVGs (GridApp.dc.html:585),
|
||||
// replacing the prior emoji glyphs. Strokes/fills are currentColor so each icon
|
||||
// inherits its .bottom-tab color: --text-subtle inactive, --accent when active,
|
||||
// and it flips automatically across the light/dark themes.
|
||||
const BottomTabIcon = ({ name }) => {
|
||||
const common = { width: 20, height: 20, viewBox: '0 0 20 20', fill: 'none', 'aria-hidden': 'true' };
|
||||
if (name === 'grid') {
|
||||
return (
|
||||
<svg {...common} stroke="currentColor" strokeWidth="1.6">
|
||||
<rect x="3" y="3" width="6" height="6" rx="1" />
|
||||
<rect x="11" y="3" width="6" height="6" rx="1" />
|
||||
<rect x="3" y="11" width="6" height="6" rx="1" />
|
||||
<rect x="11" y="11" width="6" height="6" rx="1" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
if (name === 'pipeline') {
|
||||
return (
|
||||
<svg {...common}>
|
||||
<rect x="3" y="3" width="4.5" height="14" rx="1" stroke="currentColor" strokeWidth="1.6" />
|
||||
<rect x="9.25" y="3" width="4.5" height="10" rx="1" stroke="currentColor" strokeWidth="1.6" />
|
||||
<rect x="15.5" y="3" width="1.5" height="6" rx="0.7" fill="currentColor" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
if (name === 'reminders') {
|
||||
return (
|
||||
<svg {...common} stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
|
||||
<circle cx="10" cy="11" r="6.2" />
|
||||
<line x1="10" y1="11" x2="10" y2="7.5" />
|
||||
<line x1="10" y1="11" x2="12.4" y2="12" />
|
||||
<line x1="7" y1="3.4" x2="4.4" y2="5.4" />
|
||||
<line x1="13" y1="3.4" x2="15.6" y2="5.4" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
// contacts — head + shoulders
|
||||
return (
|
||||
<svg {...common} stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
|
||||
<circle cx="10" cy="7" r="3.2" />
|
||||
<path d="M4 16.5c0-3 2.7-4.8 6-4.8s6 1.8 6 4.8" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
// Quick-log — the dc top-bar pencil (GridApp:53-55): log a communication against any investor
|
||||
// without first opening its detail. Two steps: pick an investor (search + recent-first pool) →
|
||||
// inline log form. Writes via the one-row /api/fundraising/log-communication path (same write
|
||||
@@ -14484,8 +14539,9 @@
|
||||
<div className="main-content">
|
||||
<div className="header">
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
|
||||
{sidebarHidden && <button className="sidebar-toggle" onClick={() => setSidebarHidden(false)}>Show Menu</button>}
|
||||
<div className="header-title">
|
||||
{sidebarHidden && <button className="sidebar-toggle desktop-only" onClick={() => setSidebarHidden(false)}>Show Menu</button>}
|
||||
<span className="mobile-wordmark mobile-only">·Ten31·</span>
|
||||
<div className="header-title desktop-only">
|
||||
{page === 'fundraising-grid' && 'Fundraising Grid'}
|
||||
{page === 'dashboard' && 'Dashboard'}
|
||||
{page === 'contacts' && 'Contacts'}
|
||||
@@ -14593,10 +14649,10 @@
|
||||
desktop nav. Other destinations are intentionally absent on mobile. */}
|
||||
<nav className="bottom-tab-bar" aria-label="Primary">
|
||||
{[
|
||||
{ id: 'fundraising-grid', icon: '▦', label: 'Grid' },
|
||||
{ id: 'pipeline', icon: '↗', label: 'Pipeline' },
|
||||
{ id: 'reminders', icon: '⏰', label: 'Reminders' },
|
||||
{ id: 'contacts', icon: '◎', label: 'Contacts' },
|
||||
{ id: 'fundraising-grid', icon: 'grid', label: 'Grid' },
|
||||
{ id: 'pipeline', icon: 'pipeline', label: 'Pipeline' },
|
||||
{ id: 'reminders', icon: 'reminders', label: 'Reminders' },
|
||||
{ id: 'contacts', icon: 'contacts', label: 'Contacts' },
|
||||
].map((t) => (
|
||||
<button
|
||||
key={t.id}
|
||||
@@ -14604,7 +14660,7 @@
|
||||
onClick={() => setPage(t.id)}
|
||||
aria-current={page === t.id ? 'page' : undefined}
|
||||
>
|
||||
<span className="bottom-tab-icon">{t.icon}</span>
|
||||
<span className="bottom-tab-icon"><BottomTabIcon name={t.icon} /></span>
|
||||
<span className="bottom-tab-label">{t.label}</span>
|
||||
</button>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user