diff --git a/README.md b/README.md index 4ca56737..60662ec4 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,38 @@ Open your browser to **http://localhost:8000** --- +## Access from your phone + +The dashboard is mobile-optimized. To open it on your phone: + +**Step 1 — bind to your local network** (instead of just localhost): + +```bash +uvicorn dashboard.app:app --host 0.0.0.0 --port 8000 --reload +``` + +**Step 2 — find your Mac's IP address:** + +```bash +ipconfig getifaddr en0 +``` + +This prints something like `192.168.1.42`. If you're on ethernet instead of Wi-Fi, try `en1`. + +**Step 3 — open on your phone:** + +Make sure your phone is on the **same Wi-Fi network** as your Mac, then open: + +``` +http://192.168.1.42:8000 +``` + +(replace with your actual IP) + +On mobile the layout switches to a single column — status panels become a horizontal scroll strip at the top, chat fills the rest of the screen. The input field is sized to prevent iOS from zooming in when you tap it. + +--- + ## What you'll see The dashboard has two panels on the left and a chat window on the right: diff --git a/src/dashboard/templates/base.html b/src/dashboard/templates/base.html index db0c0d25..4e84890c 100644 --- a/src/dashboard/templates/base.html +++ b/src/dashboard/templates/base.html @@ -2,7 +2,10 @@ - + + + + {% block title %}Timmy Time — Mission Control{% endblock %} diff --git a/static/style.css b/static/style.css index 67a5dd83..e3e96148 100644 --- a/static/style.css +++ b/static/style.css @@ -15,6 +15,7 @@ --red-dim: #7a1a22; --blue: #00aaff; --font: 'JetBrains Mono', 'Courier New', monospace; + --header-h: 52px; } * { box-sizing: border-box; margin: 0; padding: 0; } @@ -24,8 +25,10 @@ body { color: var(--text); font-family: var(--font); font-size: 13px; - min-height: 100vh; + min-height: 100dvh; overflow-x: hidden; + /* prevent bounce-scroll from revealing background on iOS */ + overscroll-behavior: none; } /* ── Header ─────────────────────────────────────── */ @@ -34,12 +37,14 @@ body { justify-content: space-between; align-items: center; padding: 12px 24px; + padding-top: max(12px, env(safe-area-inset-top)); background: var(--bg-panel); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 100; } +.mc-header-left { display: flex; align-items: baseline; gap: 0; } .mc-title { font-size: 18px; font-weight: 700; @@ -58,13 +63,13 @@ body { letter-spacing: 0.1em; } -/* ── Layout ──────────────────────────────────────── */ +/* ── Layout — desktop ────────────────────────────── */ .mc-main { display: grid; grid-template-columns: 260px 1fr; gap: 16px; padding: 16px; - height: calc(100vh - 52px); + height: calc(100dvh - var(--header-h)); } /* ── Panels ──────────────────────────────────────── */ @@ -86,7 +91,7 @@ body { } .panel-body { padding: 14px; } -/* ── Sidebar ─────────────────────────────────────── */ +/* ── Sidebar — desktop ───────────────────────────── */ .sidebar { grid-column: 1; display: flex; @@ -156,11 +161,13 @@ body { display: flex; flex-direction: column; grid-column: 2; + min-height: 0; } .chat-log { flex: 1; overflow-y: auto; padding: 14px; + -webkit-overflow-scrolling: touch; } .chat-message { margin-bottom: 16px; } .msg-meta { @@ -169,8 +176,8 @@ body { margin-bottom: 4px; letter-spacing: 0.12em; } -.chat-message.user .msg-meta { color: var(--blue); } -.chat-message.agent .msg-meta { color: var(--green); } +.chat-message.user .msg-meta { color: var(--blue); } +.chat-message.agent .msg-meta { color: var(--green); } .chat-message.error-msg .msg-meta { color: var(--red); } .msg-body { @@ -189,10 +196,13 @@ body { /* ── Chat Input ──────────────────────────────────── */ .chat-input-bar { padding: 12px 14px; + /* safe area for iPhone home bar */ + padding-bottom: max(12px, env(safe-area-inset-bottom)); background: var(--bg-card); border-top: 1px solid var(--border); display: flex; gap: 8px; + flex-shrink: 0; } .chat-input-bar input { flex: 1; @@ -222,6 +232,8 @@ body { cursor: pointer; letter-spacing: 0.12em; transition: background 0.15s, color 0.15s; + /* prevent double-tap zoom on iOS */ + touch-action: manipulation; } .chat-input-bar button:hover { background: var(--blue); color: var(--bg-deep); } @@ -236,3 +248,78 @@ body { ::-webkit-scrollbar-track { background: var(--bg-deep); } ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; } ::-webkit-scrollbar-thumb:hover { background: var(--border-glow); } + + +/* ════════════════════════════════════════════════════ + MOBILE (≤ 768 px) + ════════════════════════════════════════════════════ */ +@media (max-width: 768px) { + + :root { --header-h: 44px; } + + /* Compact header */ + .mc-header { padding: 10px 16px; padding-top: max(10px, env(safe-area-inset-top)); } + .mc-title { font-size: 14px; letter-spacing: 0.1em; } + .mc-subtitle { display: none; } + .mc-time { font-size: 12px; } + + /* Single-column stack; sidebar on top, chat below */ + .mc-main { + grid-template-columns: 1fr; + grid-template-rows: auto minmax(0, 1fr); + padding: 8px; + gap: 8px; + height: calc(100dvh - var(--header-h)); + } + + /* Sidebar becomes a horizontal scroll strip */ + .sidebar { + grid-column: 1; + grid-row: 1; + flex-direction: row; + overflow-x: auto; + overflow-y: hidden; + gap: 8px; + flex-shrink: 0; + scrollbar-width: none; /* Firefox */ + -webkit-overflow-scrolling: touch; + } + .sidebar::-webkit-scrollbar { display: none; } + + /* Each panel card has a fixed width so they don't squash */ + .sidebar .panel { + min-width: 200px; + flex-shrink: 0; + } + + /* Chat fills remaining vertical space */ + .chat-panel { + grid-column: 1; + grid-row: 2; + min-height: 0; + } + + /* Tighter message padding */ + .chat-log { padding: 10px; } + .msg-body { padding: 8px 10px; font-size: 13px; } + .chat-message { margin-bottom: 12px; } + + /* Touch-friendly input bar */ + .chat-input-bar { + padding: 8px 10px; + padding-bottom: max(8px, env(safe-area-inset-bottom)); + gap: 6px; + } + .chat-input-bar input { + /* 16px prevents iOS from zooming when the field focuses */ + font-size: 16px; + min-height: 44px; + padding: 0 12px; + } + .chat-input-bar button { + min-height: 44px; + min-width: 64px; + font-size: 12px; + padding: 0 14px; + } +}