From bf75ef344cb26debcc2245cef764b7671158e49b Mon Sep 17 00:00:00 2001 From: dirtydishes Date: Sun, 17 May 2026 11:25:31 -0400 Subject: [PATCH] polish terminal view --- apps/web/app/globals.css | 106 +++++++++- .../2026-05-17-1123-polish-terminal-view.html | 182 ++++++++++++++++++ 2 files changed, 279 insertions(+), 9 deletions(-) create mode 100644 docs/turns/2026-05-17-1123-polish-terminal-view.html diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css index 46f20bb..7a56b6a 100644 --- a/apps/web/app/globals.css +++ b/apps/web/app/globals.css @@ -20,6 +20,7 @@ --blue-soft: oklch(0.72 0.13 247 / 0.11); --rail-width: 236px; --topbar-height: 64px; + --ease-out-terminal: cubic-bezier(0.22, 1, 0.36, 1); } * { @@ -32,6 +33,29 @@ body { min-height: 100%; } +* { + scrollbar-color: oklch(0.78 0.12 74 / 0.24) oklch(0.12 0.01 250 / 0.5); +} + +*::-webkit-scrollbar { + width: 10px; + height: 10px; +} + +*::-webkit-scrollbar-track { + background: oklch(0.12 0.01 250 / 0.5); +} + +*::-webkit-scrollbar-thumb { + border: 2px solid oklch(0.12 0.01 250 / 0.72); + border-radius: 999px; + background: oklch(0.78 0.12 74 / 0.24); +} + +*::-webkit-scrollbar-thumb:hover { + background: oklch(0.78 0.12 74 / 0.36); +} + body { min-height: 100vh; font-family: var(--font-sans), sans-serif; @@ -140,7 +164,10 @@ input { text-transform: uppercase; letter-spacing: 0.14em; font-size: 0.76rem; - transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease; + transition: + border-color 160ms var(--ease-out-terminal), + background-color 160ms var(--ease-out-terminal), + color 160ms var(--ease-out-terminal); } .terminal-nav-link:hover { @@ -160,6 +187,7 @@ input { border-color: var(--border-strong); color: var(--text); background: var(--accent-soft); + box-shadow: inset 0 0 0 1px oklch(0.78 0.12 74 / 0.08); } .shell-metrics { @@ -172,7 +200,7 @@ input { padding: 11px 13px; border-radius: 10px; border: 1px solid var(--border); - background: var(--bg-soft); + background: linear-gradient(180deg, oklch(0.97 0.008 250 / 0.05), oklch(0.97 0.008 250 / 0.025)); } .shell-metric-label, @@ -383,6 +411,36 @@ input { text-transform: uppercase; letter-spacing: 0.12em; font-size: 0.72rem; + transition: + border-color 160ms var(--ease-out-terminal), + background-color 160ms var(--ease-out-terminal), + color 160ms var(--ease-out-terminal), + opacity 160ms var(--ease-out-terminal); +} + +.terminal-button:hover:not(:disabled), +.mode-button:hover:not(:disabled), +.filter-clear:hover:not(:disabled), +.jump-button:hover:not(:disabled), +.pause-button:hover:not(:disabled), +.interval-button:hover:not(:disabled), +.overlay-toggle:hover:not(:disabled), +.drawer-close:hover:not(:disabled) { + border-color: oklch(0.78 0.09 74 / 0.36); + background: oklch(0.78 0.12 74 / 0.075); + color: var(--text); +} + +.terminal-button:active:not(:disabled), +.mode-button:active:not(:disabled), +.filter-clear:active:not(:disabled), +.jump-button:active:not(:disabled), +.pause-button:active:not(:disabled), +.interval-button:active:not(:disabled), +.overlay-toggle:active:not(:disabled), +.drawer-close:active:not(:disabled) { + border-color: oklch(0.78 0.1 74 / 0.5); + background: oklch(0.78 0.12 74 / 0.12); } .terminal-button:disabled, @@ -411,7 +469,7 @@ input { padding: 5px 8px 5px 10px; border: 1px solid var(--border-strong); border-radius: 8px; - background: oklch(0.78 0.12 74 / 0.07); + background: linear-gradient(180deg, oklch(0.78 0.12 74 / 0.09), oklch(0.78 0.12 74 / 0.045)); color: var(--text); font-family: var(--font-mono), monospace; font-size: 0.72rem; @@ -456,6 +514,12 @@ input { outline: none; } +.instrument-cell-button:focus-visible { + outline: 1px solid oklch(0.83 0.08 74 / 0.82); + outline-offset: 3px; + border-radius: 4px; +} + .pause-button { padding: 7px 10px; font-size: 0.66rem; @@ -721,7 +785,9 @@ h3 { flex-direction: column; border: 1px solid var(--border); border-radius: 14px; - background: var(--bg-pane); + background: + linear-gradient(180deg, oklch(0.21 0.013 250 / 0.42), transparent 140px), + var(--bg-pane); overflow: hidden; } @@ -732,7 +798,7 @@ h3 { gap: 12px; padding: 15px 18px; border-bottom: 1px solid var(--border); - background: oklch(0.2 0.012 250 / 0.38); + background: oklch(0.2 0.012 250 / 0.48); } .terminal-pane-title-row { @@ -1022,6 +1088,7 @@ h3 { overflow-y: hidden; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); + border-radius: 10px; background: oklch(0.14 0.01 250 / 0.72); } @@ -1105,6 +1172,10 @@ h3 { letter-spacing: 0.08em; } +.data-table-head .data-table-cell { + font-size: inherit; +} + .data-table-row { width: 100%; height: 40px; @@ -1115,6 +1186,9 @@ h3 { color: inherit; font: inherit; text-align: left; + transition: + background-color 140ms var(--ease-out-terminal), + box-shadow 140ms var(--ease-out-terminal); } .data-table-row.is-even { @@ -1130,7 +1204,8 @@ h3 { .data-table-row:hover, .data-table-row:focus-visible { - outline: none; + outline: 1px solid oklch(0.78 0.12 74 / 0.36); + outline-offset: -1px; background: oklch(0.78 0.12 74 / 0.05); } @@ -1230,6 +1305,7 @@ h3 { text-overflow: ellipsis; white-space: nowrap; font-size: 0.72rem; + line-height: 1.25; } .data-table-cell-number { @@ -1568,8 +1644,11 @@ h3 { padding: 18px; border-radius: 12px; border: 1px dashed var(--border); - background: var(--bg-soft); + background: + linear-gradient(135deg, oklch(0.78 0.12 74 / 0.045), transparent 42%), + var(--bg-soft); color: var(--text-dim); + line-height: 1.45; } .drawer { @@ -2012,12 +2091,13 @@ h3 { } .shell-metrics { - display: flex; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } .shell-metric { - flex: 0 0 156px; + min-width: 0; } .terminal-content { @@ -2042,6 +2122,12 @@ h3 { align-items: flex-start; } + .page-actions { + width: 100%; + flex-direction: column; + align-items: stretch; + } + .terminal-pane-title-row { flex-direction: column; align-items: flex-start; @@ -2083,9 +2169,11 @@ h3 { .terminal-topbar-mode .terminal-button, .terminal-topbar-controls > .terminal-button, + .page-actions > .contract-filter-button, .page-actions > .terminal-button, .page-actions > .flow-filter-popover { width: 100%; + max-width: none; } .instrument-focus-chip { diff --git a/docs/turns/2026-05-17-1123-polish-terminal-view.html b/docs/turns/2026-05-17-1123-polish-terminal-view.html new file mode 100644 index 0000000..2fee553 --- /dev/null +++ b/docs/turns/2026-05-17-1123-polish-terminal-view.html @@ -0,0 +1,182 @@ + + + + + + 2026-05-17 11:23, Polish Terminal View + + + +
+
+
Turn Document, 2026-05-17 11:23 ET
+

Polish Terminal View

+

+ Refined the Islandflow web terminal shell so the Tape view feels more deliberate, more keyboard-readable, and more stable across desktop and mobile. +

+
+ +
+

Summary

+

+ This was a focused product polish pass on apps/web/app/globals.css. The work stayed inside the established Islandflow terminal design language: dark operational surfaces, scarce amber emphasis, compact controls, and clear evidence-console states. +

+
+ +
+

Changes Made

+
    +
  • Added a shared terminal easing token for consistent, restrained interaction transitions.
  • +
  • Styled scrollbars to match the terminal surface instead of falling back to browser defaults.
  • +
  • Improved nav, button, and active-control hover and pressed states using the existing OKLCH palette.
  • +
  • Refined shell metrics, pane headers, table shells, row focus states, and empty states for clearer hierarchy.
  • +
  • Adjusted mobile metric cards and Tape action controls so they align cleanly without horizontal page overflow.
  • +
+
+ +
+

Context

+

+ Islandflow is a serious market-data terminal for traders and researchers. The polish target was product UI, not brand theater, so the changes prioritize trust, legibility, predictable controls, and stable responsive structure. +

+
+ +
+

Important Implementation Details

+
    +
  • All new color work uses existing OKLCH roles and keeps amber as a scarce signal rather than a decorative wash.
  • +
  • Keyboard focus on table rows and instrument buttons is now visible without introducing layout shift.
  • +
  • Mobile shell metrics now use a two-column grid, and page actions stretch to the viewport width.
  • +
  • The polish is CSS-only, so no data contracts, route behavior, or live-stream logic changed.
  • +
+
+ +
+

Expected Impact for End-Users

+

+ Users should experience a terminal that reads as more finished under pressure: clearer controls, cleaner empty states, better keyboard affordances, and less visual friction on narrow screens. +

+
+ +
+

Validation

+
    +
  • bun install completed to restore missing workspace dependencies.
  • +
  • bun test apps/web/app/terminal.test.ts apps/web/app/routes.test.ts passed with 69 tests.
  • +
  • bun --cwd=apps/web run build passed.
  • +
  • Playwright visual QA checked http://localhost:3000/tape at 1440x1000 and 390x900.
  • +
  • Visual QA confirmed no document-level horizontal overflow after the responsive polish.
  • +
+
+ +
+

Issues, Limitations, and Mitigations

+
    +
  • The local backend WebSocket at localhost:4000 was offline during visual QA, so the screen showed disconnected empty states. This was useful for validating the empty-state polish but did not exercise live data density.
  • +
  • Playwright needed a locally cached Chromium executable. The visual check used an existing browser cache path after the default runtime binary was unavailable.
  • +
+
+ +
+

Follow-up Work

+

+ No new Beads follow-up issue was filed. Live-data density should be rechecked naturally when the full local stack is running, but this polish did not reveal a separate actionable defect. +

+
+
+ +