feat: tighten mobile tabs and mission console theme
This commit is contained in:
+4
-3
@@ -9,7 +9,6 @@ import type { AppState, Feature, FeatureColumn, ParkingLotItem, PulseEvent, Risk
|
|||||||
import { arrayToLines, formatDateTime, linesToArray, nowIso, slugify } from './utils/format'
|
import { arrayToLines, formatDateTime, linesToArray, nowIso, slugify } from './utils/format'
|
||||||
|
|
||||||
const TABS: Array<{ key: TabKey; label: string }> = [
|
const TABS: Array<{ key: TabKey; label: string }> = [
|
||||||
{ key: 'functionalities', label: 'Functionalities' },
|
|
||||||
{ key: 'feature-plan', label: 'Feature Plan' },
|
{ key: 'feature-plan', label: 'Feature Plan' },
|
||||||
{ key: 'parking-lot', label: 'Parking Lot' },
|
{ key: 'parking-lot', label: 'Parking Lot' },
|
||||||
{ key: 'pulse-log', label: 'Pulse Log' },
|
{ key: 'pulse-log', label: 'Pulse Log' },
|
||||||
@@ -66,7 +65,7 @@ const downloadText = (filename: string, text: string, contentType = 'text/plain;
|
|||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [appState, setAppState] = useState<AppState>(() => loadAppState())
|
const [appState, setAppState] = useState<AppState>(() => loadAppState())
|
||||||
const [activeTab, setActiveTab] = useState<TabKey>('functionalities')
|
const [activeTab, setActiveTab] = useState<TabKey>('feature-plan')
|
||||||
const [statusMessage, setStatusMessage] = useState('Seeded with BuildPulse so you can dogfood it immediately.')
|
const [statusMessage, setStatusMessage] = useState('Seeded with BuildPulse so you can dogfood it immediately.')
|
||||||
const [selectedFeatureId, setSelectedFeatureId] = useState<string | null>(null)
|
const [selectedFeatureId, setSelectedFeatureId] = useState<string | null>(null)
|
||||||
const [selectedParkingId, setSelectedParkingId] = useState<string | null>(null)
|
const [selectedParkingId, setSelectedParkingId] = useState<string | null>(null)
|
||||||
@@ -786,11 +785,13 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<nav className="tab-bar" aria-label="Main views">
|
<nav className="tab-bar" aria-label="BuildPulse v0.1 views" role="tablist">
|
||||||
{TABS.map((tab) => (
|
{TABS.map((tab) => (
|
||||||
<button
|
<button
|
||||||
key={tab.key}
|
key={tab.key}
|
||||||
type="button"
|
type="button"
|
||||||
|
role="tab"
|
||||||
|
aria-selected={tab.key === activeTab}
|
||||||
className={tab.key === activeTab ? 'tab active' : 'tab'}
|
className={tab.key === activeTab ? 'tab active' : 'tab'}
|
||||||
onClick={() => setActiveTab(tab.key)}
|
onClick={() => setActiveTab(tab.key)}
|
||||||
>
|
>
|
||||||
|
|||||||
+270
@@ -782,3 +782,273 @@ pre {
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mission Console refresh — proper mobile tabs, less scroll archaeology. */
|
||||||
|
:root {
|
||||||
|
color: #f4f7fb;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 12% -8%, rgba(34, 211, 238, 0.2), transparent 28%),
|
||||||
|
radial-gradient(circle at 92% 0%, rgba(250, 204, 21, 0.12), transparent 24%),
|
||||||
|
linear-gradient(145deg, #070a12 0%, #0d1323 48%, #111827 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background:
|
||||||
|
linear-gradient(rgba(255, 255, 255, 0.018) 1px, transparent 1px),
|
||||||
|
linear-gradient(90deg, rgba(255, 255, 255, 0.018) 1px, transparent 1px),
|
||||||
|
#070a12;
|
||||||
|
background-size: 42px 42px, 42px 42px, auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
body::before {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 18% 16%, rgba(34, 211, 238, 0.16), transparent 18%),
|
||||||
|
radial-gradient(circle at 82% 12%, rgba(251, 191, 36, 0.12), transparent 18%),
|
||||||
|
linear-gradient(180deg, rgba(15, 23, 42, 0), rgba(2, 6, 23, 0.42));
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-shell {
|
||||||
|
width: min(1240px, calc(100% - 1.5rem));
|
||||||
|
padding-top: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card,
|
||||||
|
.card {
|
||||||
|
background: linear-gradient(180deg, rgba(15, 23, 42, 0.88), rgba(8, 13, 26, 0.82));
|
||||||
|
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||||
|
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.035);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card {
|
||||||
|
border-radius: 22px;
|
||||||
|
padding: 1.15rem;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(110deg, rgba(34, 211, 238, 0.08), transparent 42%, rgba(251, 191, 36, 0.08));
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card > * {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card h1 {
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
font-size: clamp(2rem, 6vw, 4.7rem);
|
||||||
|
line-height: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-copy,
|
||||||
|
.hero-goal,
|
||||||
|
.section-heading p,
|
||||||
|
.functionality-hero p,
|
||||||
|
.functionality-card p,
|
||||||
|
.functionality-roadmap p,
|
||||||
|
.functionality-detail-grid p,
|
||||||
|
.functionality-detail-grid ul {
|
||||||
|
color: #aebdd4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eyebrow {
|
||||||
|
color: #67e8f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-stats div,
|
||||||
|
.functionality-scorecard div,
|
||||||
|
.roadmap-grid div,
|
||||||
|
.focus-panel,
|
||||||
|
.functionality-detail-grid article {
|
||||||
|
background: rgba(3, 7, 18, 0.58);
|
||||||
|
border: 1px solid rgba(148, 163, 184, 0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
border-radius: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-card {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-strip {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.85rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-bar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0.65rem;
|
||||||
|
z-index: 20;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
gap: 0.35rem;
|
||||||
|
padding: 0.35rem;
|
||||||
|
overflow-x: auto;
|
||||||
|
overscroll-behavior-x: contain;
|
||||||
|
scrollbar-width: none;
|
||||||
|
border: 1px solid rgba(148, 163, 184, 0.2);
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(3, 7, 18, 0.78);
|
||||||
|
box-shadow: 0 18px 36px rgba(0, 0, 0, 0.28);
|
||||||
|
backdrop-filter: blur(18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-bar::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
min-width: 8.5rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
border-color: transparent;
|
||||||
|
background: transparent;
|
||||||
|
color: #9fb0c9;
|
||||||
|
padding: 0.72rem 0.95rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
transition: transform 160ms ease, background 160ms ease, color 160ms ease, border-color 160ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab:hover {
|
||||||
|
color: #e5f4ff;
|
||||||
|
background: rgba(148, 163, 184, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab.active,
|
||||||
|
.tab[aria-selected='true'] {
|
||||||
|
color: #06111c;
|
||||||
|
background: linear-gradient(135deg, #67e8f9, #facc15);
|
||||||
|
border-color: rgba(255, 255, 255, 0.18);
|
||||||
|
box-shadow: 0 10px 24px rgba(34, 211, 238, 0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-actions {
|
||||||
|
justify-content: center;
|
||||||
|
border-style: dashed;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
.button-inline-row button,
|
||||||
|
.quick-actions button {
|
||||||
|
border-radius: 999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:not(.tab) {
|
||||||
|
transition: transform 140ms ease, border-color 140ms ease, background 140ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:not(.tab):hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
background: rgba(3, 7, 18, 0.72);
|
||||||
|
border-color: rgba(148, 163, 184, 0.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.board-grid {
|
||||||
|
grid-template-columns: repeat(4, minmax(240px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
border-top: 3px solid rgba(103, 232, 249, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.column:nth-child(2) {
|
||||||
|
border-top-color: rgba(250, 204, 21, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
.column:nth-child(3) {
|
||||||
|
border-top-color: rgba(167, 139, 250, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
.column:nth-child(4) {
|
||||||
|
border-top-color: rgba(74, 222, 128, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-card {
|
||||||
|
background: rgba(2, 6, 23, 0.52);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 860px) {
|
||||||
|
.app-shell {
|
||||||
|
width: min(100% - 0.8rem, 100%);
|
||||||
|
padding-top: 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-stats {
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-strip {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-bar {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin-left: -0.05rem;
|
||||||
|
margin-right: -0.05rem;
|
||||||
|
border-radius: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
min-width: max-content;
|
||||||
|
padding: 0.72rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.board-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.quick-actions,
|
||||||
|
.tab-bar,
|
||||||
|
.button-row,
|
||||||
|
.button-inline-row,
|
||||||
|
.filter-row,
|
||||||
|
.status-strip,
|
||||||
|
.status-strip-row,
|
||||||
|
.status-bar,
|
||||||
|
.feature-signal-row {
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-bar {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-actions {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-actions button:last-child:nth-child(odd) {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep v0.1 project-summary editing visible; it is part of the cockpit, just visually quieter. */
|
||||||
|
.project-card {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user