From 58ff9bb0625dc11aae11a4a4b2b7e7c38114074d Mon Sep 17 00:00:00 2001 From: dirtydishes Date: Thu, 11 Jun 2026 18:29:03 -0400 Subject: [PATCH] add no-card mock redesign routes --- .beads/issues.jsonl | 1 + apps/web/app/dashboard-mocks.tsx | 532 ++++++++++++++++- apps/web/app/globals.css | 546 +++++++++++++++++- apps/web/app/mock5/page.tsx | 7 + apps/web/app/mock6/page.tsx | 7 + apps/web/app/mock7/page.tsx | 7 + apps/web/app/mock8/page.tsx | 7 + ...26-06-11-1822-add-no-card-mock-routes.html | 393 +++++++++++++ 8 files changed, 1483 insertions(+), 17 deletions(-) create mode 100644 apps/web/app/mock5/page.tsx create mode 100644 apps/web/app/mock6/page.tsx create mode 100644 apps/web/app/mock7/page.tsx create mode 100644 apps/web/app/mock8/page.tsx create mode 100644 docs/turns/2026-06-11-1822-add-no-card-mock-routes.html diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index ceaced7..d053c50 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -27,6 +27,7 @@ {"_type":"issue","id":"islandflow-ayo","title":"Drop stale backlog events from live fanout","description":"Follow-up to live freshness rollout: /ws/live was still fanning out stale backlog events for freshness-gated channels, which kept tape panes in Live feed behind despite active synthetic ingest. Gate fanout and cache ingest by freshness for options/nbbo/equities/flow.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-04-28T21:26:39Z","created_by":"dirtydishes","updated_at":"2026-04-28T21:26:44Z","started_at":"2026-04-28T21:26:44Z","closed_at":"2026-04-28T21:26:44Z","close_reason":"Completed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-0v6","title":"Fix tape freshness, NBBO coverage, pause controls, and filter popup","description":"Implement the tape fixes requested for synthetic options notional sizing, strict live freshness, live-mode pause/resume behavior, stronger NBBO snapshot coverage, and moving flow filters behind a popup. Includes server-side live cache changes, web terminal state/UI changes, and tests for synthetic pricing, live snapshot freshness/NBBO retention, and live pause/filter interactions.","status":"closed","priority":1,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-04-28T21:02:52Z","created_by":"dirtydishes","updated_at":"2026-04-28T21:13:38Z","started_at":"2026-04-28T21:02:57Z","closed_at":"2026-04-28T21:13:38Z","close_reason":"Completed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-e4r","title":"Implement smart-money flow filtering and synthetic firehose modes","description":"Implement the approved multi-surface plan for named synthetic market profiles, options raw-vs-signal filtering, live/API filter contracts, Tape page client-side flow filters, firehose-readiness improvements, tests, and README updates.","status":"closed","priority":1,"issue_type":"feature","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-04-28T20:10:49Z","created_by":"dirtydishes","updated_at":"2026-04-28T20:29:29Z","started_at":"2026-04-28T20:10:53Z","closed_at":"2026-04-28T20:29:29Z","close_reason":"Implemented synthetic market profiles, options signal-path filtering, signal-aware API/replay contracts, Tape page filters, tests, and README updates. Follow-up tracked in islandflow-biq.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"islandflow-q7v","title":"add four no-card mock redesign routes","description":"Add four additional mock redesign routes to the web app without replacing the existing mock1-mock4 routes. The new routes should avoid card-style structures entirely and show varied market-activity workflows grounded in the Islandflow options flow -\u003e flow packet -\u003e smart money alert reasoning model.","status":"closed","priority":2,"issue_type":"task","owner":"dishes@dpdrm.com","created_at":"2026-06-11T22:14:44Z","created_by":"dirtydishes","updated_at":"2026-06-11T22:28:22Z","closed_at":"2026-06-11T22:28:22Z","close_reason":"Added /mock5-/mock8 no-card mock redesign routes, created required turn documentation, and validated with web build plus browser DOM checks.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-2x7","title":"Redesign mock routes from the ground up","description":"Rework the /mock1 through /mock4 frontend concepts so each route has a fresh layout, navigation treatment, and palette independent of the existing terminal chrome.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-06-11T09:09:12Z","created_by":"dirtydishes","updated_at":"2026-06-11T09:10:42Z","started_at":"2026-06-11T09:09:17Z","closed_at":"2026-06-11T09:10:42Z","close_reason":"Implemented fresh mock redesigns for /mock1 through /mock4, bypassed the terminal shell for mock routes, verified in the in-app browser, and passed bun web build plus focused route/terminal tests.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-3vr","title":"create ground-up frontend redesign mocks","description":"Generate a set of production-quality app mock redesigns that reuse Islandflow fundamentals in new interface models for evaluation.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-06-11T08:10:00Z","created_by":"dirtydishes","updated_at":"2026-06-11T08:17:51Z","started_at":"2026-06-11T08:10:09Z","closed_at":"2026-06-11T08:17:51Z","close_reason":"Created four ground-up frontend redesign mock routes and documented the work.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"islandflow-9ns","title":"Refine command deck header","description":"Simplify the overview command deck header after live visual iteration, keeping live status, last tick, replay switching, and active filter controls prominent at the top of the page.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-06-06T11:30:15Z","created_by":"dirtydishes","updated_at":"2026-06-06T11:32:07Z","started_at":"2026-06-06T11:30:25Z","closed_at":"2026-06-06T11:32:07Z","close_reason":"accepted compact command deck header from live iteration, added active filter chips with hover clear controls, and validated web build/tests","dependency_count":0,"dependent_count":0,"comment_count":0} diff --git a/apps/web/app/dashboard-mocks.tsx b/apps/web/app/dashboard-mocks.tsx index ca2555c..7f4bce1 100644 --- a/apps/web/app/dashboard-mocks.tsx +++ b/apps/web/app/dashboard-mocks.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import type { CSSProperties, ReactNode } from "react"; -type MockVariant = "mock1" | "mock2" | "mock3" | "mock4"; +type MockVariant = "mock1" | "mock2" | "mock3" | "mock4" | "mock5" | "mock6" | "mock7" | "mock8"; type DashboardMockProps = { variant: MockVariant; @@ -47,17 +47,93 @@ const concepts: Record = { premise: "Cross-market pressure is drawn as territories, so the trader can see where attention clusters before opening a single-symbol case.", bodyClass: "mock-map" + }, + mock5: { + title: "Options Intake", + shortName: "Options", + routeName: "Options", + premise: + "A dense OPRA-style blotter turns contract activity into candidate flow packets, with strike context, sweep shape, venue mix, and confidence deltas visible in one scan.", + bodyClass: "mock-options" + }, + mock6: { + title: "Packet Forensics", + shortName: "Packets", + routeName: "Flow Packets", + premise: + "Options prints, equity tape, venue imbalance, and news fragments are assembled into packets before any alert can earn attention.", + bodyClass: "mock-packets" + }, + mock7: { + title: "Alert Reason Wall", + shortName: "Alerts", + routeName: "Alerts", + premise: + "Every smart money party alert is shown with the reason, type, invalidation path, and evidence lineage that caused it to fire.", + bodyClass: "mock-alerts" + }, + mock8: { + title: "Market Activity Graph", + shortName: "Graph", + routeName: "Activity Graph", + premise: + "A route-wide intelligence board connects options flow to packets, packets to alerts, and alerts to broader market pressure without repeating the same evidence twice.", + bodyClass: "mock-graph" } }; -const variantOrder: MockVariant[] = ["mock1", "mock2", "mock3", "mock4"]; +const variantOrder: MockVariant[] = [ + "mock1", + "mock2", + "mock3", + "mock4", + "mock5", + "mock6", + "mock7", + "mock8" +]; const symbols = [ - { symbol: "AAPL", price: "194.88", move: "+1.22%", direction: "up", score: 94, sector: "Mega cap tech" }, - { symbol: "NVDA", price: "120.19", move: "-0.41%", direction: "down", score: 81, sector: "AI semis" }, - { symbol: "TSLA", price: "180.72", move: "+0.72%", direction: "up", score: 76, sector: "EV complex" }, - { symbol: "AMZN", price: "186.31", move: "+0.35%", direction: "up", score: 68, sector: "Consumer platform" }, - { symbol: "IWM", price: "205.41", move: "+0.21%", direction: "up", score: 59, sector: "Small caps" } + { + symbol: "AAPL", + price: "194.88", + move: "+1.22%", + direction: "up", + score: 94, + sector: "Mega cap tech" + }, + { + symbol: "NVDA", + price: "120.19", + move: "-0.41%", + direction: "down", + score: 81, + sector: "AI semis" + }, + { + symbol: "TSLA", + price: "180.72", + move: "+0.72%", + direction: "up", + score: 76, + sector: "EV complex" + }, + { + symbol: "AMZN", + price: "186.31", + move: "+0.35%", + direction: "up", + score: 68, + sector: "Consumer platform" + }, + { + symbol: "IWM", + price: "205.41", + move: "+0.21%", + direction: "up", + score: 59, + sector: "Small caps" + } ]; const anomalies = [ @@ -130,12 +206,183 @@ const timeline = [ ]; const atlasGroups = [ - { name: "Mega cap tech", heat: 92, flow: "+$8.4M", symbols: ["AAPL", "MSFT", "AMZN"], x: 16, y: 22 }, + { + name: "Mega cap tech", + heat: 92, + flow: "+$8.4M", + symbols: ["AAPL", "MSFT", "AMZN"], + x: 16, + y: 22 + }, { name: "AI semis", heat: 81, flow: "+$5.1M", symbols: ["NVDA", "AMD", "AVGO"], x: 64, y: 26 }, - { name: "Beta basket", heat: 66, flow: "+$3.8M", symbols: ["TSLA", "COIN", "PLTR"], x: 34, y: 66 }, + { + name: "Beta basket", + heat: 66, + flow: "+$3.8M", + symbols: ["TSLA", "COIN", "PLTR"], + x: 34, + y: 66 + }, { name: "Defensive", heat: 38, flow: "-$1.2M", symbols: ["XLU", "XLV", "PG"], x: 74, y: 70 } ]; +const intakeRows = [ + [ + "09:41:23.420", + "AAPL", + "17MAY24 195C", + "12,480", + "$4.32M", + "sweep", + "61%", + "+3.8σ", + "candidate" + ], + [ + "09:41:18.092", + "AAPL", + "21JUN24 200C", + "8,920", + "$2.74M", + "split sweep", + "58%", + "+2.9σ", + "join" + ], + [ + "09:40:52.774", + "QQQ", + "17MAY24 458C", + "19,600", + "$5.10M", + "block lift", + "49%", + "+2.1σ", + "confirm" + ], + ["09:40:11.018", "NVDA", "24MAY24 120C", "7,340", "$2.01M", "iso sweep", "42%", "+1.7σ", "watch"], + [ + "09:39:47.660", + "TSLA", + "19JUL24 205C", + "10,000", + "$3.45M", + "block", + "38%", + "+2.4σ", + "candidate" + ], + ["09:39:12.105", "AMZN", "17MAY24 185P", "4,500", "$1.20M", "sweep", "36%", "-1.9σ", "reject"], + ["09:38:59.443", "IWM", "17MAY24 205C", "14,250", "$1.92M", "multi-leg", "31%", "+1.4σ", "watch"] +]; + +const packetSteps = [ + { + label: "options burst", + time: "09:41:23", + weight: 92, + detail: "AAPL 195C + 200C clustered inside 72s with ask-side pressure" + }, + { + label: "equity trace", + time: "09:41:48", + weight: 74, + detail: "25k dark buy and visible bid lift hold above 194.50" + }, + { + label: "venue mix", + time: "09:42:06", + weight: 68, + detail: "Off-exchange share at 64%, above session baseline by 18 points" + }, + { + label: "sector echo", + time: "09:42:31", + weight: 57, + detail: "QQQ confirms, semis neutral, no broad risk-off objection" + }, + { + label: "packet ready", + time: "09:42:44", + weight: 86, + detail: "Smart money party candidate: stealth accumulation into short-dated calls" + } +]; + +const packetRows = [ + ["PKT-8841", "AAPL", "ready", "5 sources", "stealth accumulation", "86"], + ["PKT-8838", "TSLA", "building", "3 sources", "momentum ignition", "71"], + ["PKT-8834", "NVDA", "held", "2 sources", "call wall absorption", "63"], + ["PKT-8827", "AMZN", "rejected", "2 sources", "put sweep divergence", "39"] +]; + +const alertRows = [ + [ + "09:42:51", + "AAPL", + "Party Alert", + "stealth accumulation", + "options led equity by 72s; dark venue share elevated", + "accept above 194.50", + "high" + ], + [ + "09:41:58", + "TSLA", + "Ignition Watch", + "momentum ignition", + "block call buy plus tape acceleration", + "fails below 178.80", + "medium" + ], + [ + "09:40:34", + "NVDA", + "Absorption", + "call wall defense", + "buyers absorbed at 120 but price did not expand", + "rejects 120.40", + "watch" + ], + [ + "09:39:22", + "AMZN", + "Divergence", + "put sweep against basket", + "bearish premium while sector bid held", + "reclaims 186.20", + "low" + ] +]; + +const graphLanes = [ + { label: "Options", x1: "5%", x2: "31%", y: "18%", tone: "good", text: "195C sweep + 200C join" }, + { + label: "Packet", + x1: "35%", + x2: "60%", + y: "35%", + tone: "info", + text: "PKT-8841 ready, 5 sources" + }, + { + label: "Alert", + x1: "63%", + x2: "88%", + y: "22%", + tone: "accent", + text: "Party Alert: stealth accumulation" + }, + { + label: "Market", + x1: "20%", + x2: "82%", + y: "69%", + tone: "watch", + text: "QQQ confirms; semis neutral" + } +]; + export function DashboardMock({ variant }: DashboardMockProps) { const concept = concepts[variant]; @@ -146,6 +393,10 @@ export function DashboardMock({ variant }: DashboardMockProps) { {variant === "mock2" ? : null} {variant === "mock3" ? : null} {variant === "mock4" ? : null} + {variant === "mock5" ? : null} + {variant === "mock6" ? : null} + {variant === "mock7" ? : null} + {variant === "mock8" ? : null} ); } @@ -190,8 +441,8 @@ function SignalCourt() {
AAPL

Dark sweep pressure is confirmed by call lift.

- Treat the alert as a claim to prove. The board shows confirming evidence, - contradictions, and what must happen next before the trade deserves attention. + Treat the alert as a claim to prove. The board shows confirming evidence, contradictions, + and what must happen next before the trade deserves attention.

@@ -230,7 +481,10 @@ function TriageDesk() { {anomalies.map((item, index) => ( -
+
{item.symbol} @@ -318,7 +572,13 @@ function SectorCartography() {
{group.name} {group.flow} @@ -344,7 +604,228 @@ function SectorCartography() { ); } -function Panel({ className, title, children }: { className?: string; title: string; children: ReactNode }) { +function OptionsIntake() { + return ( +
+
+ {["OPRA LIVE", "ASK SIDE", "ABOVE 2 SIGMA", "PACKETABLE", "AAPL FOCUS"].map( + (item, index) => ( + + ) + )} +
+
+
+ {["Time", "Sym", "Contract", "Qty", "Premium", "Shape", "Ask", "Base", "Use"].map( + (item) => ( + + {item} + + ) + )} +
+ {intakeRows.map(([time, symbol, contract, size, premium, shape, ask, baseline, use]) => ( +
+ + {symbol} + {contract} + {size} + {premium} + {shape} + {ask} + {baseline} + + {use} + +
+ ))} +
+ + +
+ ); +} + +function PacketForensics() { + return ( +
+
+ {packetSteps.map((step, index) => ( +
+ + {step.label} +

{step.detail}

+ + {index === packetSteps.length - 1 ? "alert eligible" : `${step.weight}% contribution`} + +
+ ))} +
+
+
+ {["Packet", "Symbol", "State", "Evidence", "Reason", "Score"].map((item) => ( + + {item} + + ))} +
+ {packetRows.map(([id, symbol, state, sources, reason, score]) => ( +
+ {id} + {symbol} + + {state} + + {sources} + {reason} + {score} +
+ ))} +
+ +
+ ); +} + +function AlertReasonWall() { + return ( +
+
+
+ {["Time", "Sym", "Type", "Reason", "Why it fired", "Invalidation", "Severity"].map( + (item) => ( + + {item} + + ) + )} +
+ {alertRows.map(([time, symbol, type, reason, why, invalidation, severity]) => ( +
+ + {symbol} + {type} + {reason} +

{why}

+ {invalidation} + + {severity} + +
+ ))} +
+ +
+ ); +} + +function MarketActivityGraph() { + return ( +
+
+ {graphLanes.map((lane) => ( +
+ {lane.label} + {lane.text} +
+ ))} +
Options intake
+
Packet PKT-8841
+
Party alert
+
Market context
+
+
+ {[ + ["Options page", "raw prints become packet candidates"], + ["Packets page", "evidence sources are merged and scored"], + ["Alerts page", "reason/type/invalidation are exposed"], + ["Replay page", "the same chain can be audited after the fact"] + ].map(([route, purpose]) => ( +
+ {route} + {purpose} +
+ ))} +
+
+ +
+
+ ); +} + +function Panel({ + className, + title, + children +}: { + className?: string; + title: string; + children: ReactNode; +}) { return (
@@ -430,6 +911,21 @@ function FlowRows({ compact = false }: { compact?: boolean }) { ); } +function FlowLadder() { + return ( +
+ {["raw option print", "candidate flow", "packet assembly", "party alert"].map( + (item, index) => ( +
+ {index + 1} + {item} +
+ ) + )} +
+ ); +} + function HealthRows() { return (
@@ -481,7 +977,13 @@ function Meter({ value }: { value: number }) { function Badge({ tone, children }: { tone: string; children: ReactNode }) { const normalized = - tone === "Bearish" ? "bearish" : tone === "Watch" || tone === "Mixed" ? "watch" : tone === "Info" ? "info" : "bullish"; + tone === "Bearish" + ? "bearish" + : tone === "Watch" || tone === "Mixed" + ? "watch" + : tone === "Info" + ? "info" + : "bullish"; return {children}; } diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css index ada9420..0a3aaab 100644 --- a/apps/web/app/globals.css +++ b/apps/web/app/globals.css @@ -3973,6 +3973,58 @@ h3 { --mock-alt-soft: oklch(0.74 0.16 52 / 0.14); } +.mock-redesign.mock-options { + --mock-bg: oklch(0.075 0.02 250); + --mock-surface: oklch(0.105 0.024 250); + --mock-surface-2: oklch(0.13 0.03 250); + --mock-line: oklch(0.76 0.048 236 / 0.26); + --mock-line-strong: oklch(0.82 0.16 82 / 0.58); + --mock-accent: oklch(0.86 0.17 84); + --mock-accent-soft: oklch(0.86 0.17 84 / 0.12); + --mock-alt: oklch(0.74 0.2 32); + --mock-alt-soft: oklch(0.74 0.2 32 / 0.13); + background: + linear-gradient(90deg, oklch(0.7 0.05 240 / 0.11) 1px, transparent 1px) 0 0 / 34px 34px, + linear-gradient(180deg, oklch(0.11 0.026 250), var(--mock-bg) 42vh), + var(--mock-bg); +} + +.mock-redesign.mock-packets { + --mock-bg: oklch(0.13 0.014 198); + --mock-surface: oklch(0.17 0.022 198); + --mock-surface-2: oklch(0.11 0.018 198); + --mock-line: oklch(0.76 0.04 198 / 0.22); + --mock-line-strong: oklch(0.78 0.15 176 / 0.54); + --mock-accent: oklch(0.78 0.15 176); + --mock-accent-soft: oklch(0.78 0.15 176 / 0.13); + --mock-alt: oklch(0.77 0.14 300); + --mock-alt-soft: oklch(0.77 0.14 300 / 0.13); +} + +.mock-redesign.mock-alerts { + --mock-bg: oklch(0.11 0.026 22); + --mock-surface: oklch(0.16 0.032 22); + --mock-surface-2: oklch(0.13 0.028 22); + --mock-line: oklch(0.8 0.04 42 / 0.23); + --mock-line-strong: oklch(0.8 0.17 58 / 0.54); + --mock-accent: oklch(0.8 0.17 58); + --mock-accent-soft: oklch(0.8 0.17 58 / 0.13); + --mock-alt: oklch(0.74 0.16 24); + --mock-alt-soft: oklch(0.74 0.16 24 / 0.14); +} + +.mock-redesign.mock-graph { + --mock-bg: oklch(0.1 0.026 274); + --mock-surface: oklch(0.155 0.034 274); + --mock-surface-2: oklch(0.125 0.03 274); + --mock-line: oklch(0.78 0.05 274 / 0.22); + --mock-line-strong: oklch(0.76 0.17 220 / 0.52); + --mock-accent: oklch(0.76 0.17 220); + --mock-accent-soft: oklch(0.76 0.17 220 / 0.13); + --mock-alt: oklch(0.78 0.16 340); + --mock-alt-soft: oklch(0.78 0.16 340 / 0.13); +} + .mock-nav { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; @@ -4761,13 +4813,466 @@ h3 { font-style: normal; } +.mock-options-layout, +.mock-packet-layout, +.mock-alert-layout, +.mock-graph-layout { + max-width: 1600px; + margin: 0 auto; + display: grid; + gap: 12px; +} + +.mock-options-layout { + grid-template-columns: minmax(720px, 1fr) 270px; + grid-template-areas: + "command depth" + "tape depth" + "ladder ladder"; +} + +.mock-options-command { + grid-area: command; + display: flex; + flex-wrap: wrap; + gap: 7px; + border-block: 1px solid var(--mock-line); + padding: 8px 0; +} + +.mock-options-command button { + min-height: 30px; + border: 1px solid var(--mock-line); + border-radius: 4px; + padding: 5px 9px; + background: transparent; + color: var(--mock-muted); + font-family: var(--font-mono), monospace; + font-size: 0.64rem; + letter-spacing: 0.06em; + text-transform: uppercase; +} + +.mock-options-command button:hover, +.mock-options-command button:focus-visible, +.mock-options-command button.is-active { + border-color: var(--mock-line-strong); + color: var(--mock-accent); + outline: none; +} + +.mock-options-tape { + grid-area: tape; + overflow-x: auto; + border-block: 1px solid var(--mock-line); + background: oklch(from var(--mock-surface) l c h / 0.54); +} + +.mock-options-row { + min-width: 1060px; + min-height: 38px; + display: grid; + grid-template-columns: 116px 64px minmax(170px, 1fr) 86px 92px 110px 70px 82px 96px; + gap: 10px; + align-items: center; + border-bottom: 1px solid var(--mock-line); + padding: 0 10px; + color: var(--mock-muted); + font-family: var(--font-mono), monospace; + font-size: 0.72rem; +} + +.mock-options-row:last-child { + border-bottom: 0; +} + +.mock-options-row.is-head { + min-height: 30px; + color: var(--mock-faint); + font-size: 0.62rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.mock-options-row:not(.is-head):hover { + background: var(--mock-accent-soft); +} + +.mock-options-row.is-candidate, +.mock-options-row.is-join, +.mock-options-row.is-confirm { + color: var(--mock-ink); +} + +.mock-options-row.is-reject { + color: color-mix(in oklch, var(--mock-bad) 70%, var(--mock-muted)); +} + +.mock-options-depth { + grid-area: depth; + border-block: 1px solid var(--mock-line); + padding-block: 12px; +} + +.mock-options-depth h2, +.mock-packet-inspector h2, +.mock-alert-reason h2 { + margin: 0 0 12px; + font-size: 1rem; + letter-spacing: -0.01em; +} + +.mock-options-depth dl { + display: grid; + gap: 0; + margin: 0; +} + +.mock-options-depth div, +.mock-graph-routes div { + display: grid; + gap: 4px; + border-top: 1px solid var(--mock-line); + padding: 11px 0; +} + +.mock-options-depth div:last-child, +.mock-graph-routes div:last-child { + border-bottom: 1px solid var(--mock-line); +} + +.mock-options-depth dt, +.mock-flow-ladder span, +.mock-graph-routes span { + color: var(--mock-faint); + font-family: var(--font-mono), monospace; + font-size: 0.66rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.mock-options-depth dd { + margin: 0; + color: var(--mock-ink); + font-family: var(--font-mono), monospace; + font-size: 1.12rem; +} + +.mock-flow-ladder { + grid-area: ladder; + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + border-block: 1px solid var(--mock-line); +} + +.mock-flow-ladder div { + min-height: 70px; + display: grid; + align-content: center; + gap: 5px; + border-right: 1px solid var(--mock-line); + padding: 10px 12px; +} + +.mock-flow-ladder div:last-child { + border-right: 0; +} + +.mock-flow-ladder div.is-active { + background: var(--mock-accent-soft); +} + +.mock-flow-ladder strong { + font-size: 0.92rem; + text-transform: capitalize; +} + +.mock-packet-layout { + grid-template-columns: minmax(640px, 1.2fr) minmax(330px, 0.8fr); + grid-template-areas: + "chain inspector" + "ledger inspector"; +} + +.mock-packet-chain { + grid-area: chain; + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + border-block: 1px solid var(--mock-line); +} + +.mock-packet-chain article { + min-width: 0; + display: grid; + gap: 8px; + border-right: 1px solid var(--mock-line); + padding: 12px; + background: + linear-gradient(180deg, color-mix(in oklch, var(--mock-accent) calc(var(--weight) * 0.1%), transparent), transparent 78%), + transparent; +} + +.mock-packet-chain article:last-child { + border-right: 0; +} + +.mock-packet-chain time, +.mock-alert-row time { + color: var(--mock-faint); + font-family: var(--font-mono), monospace; + font-size: 0.66rem; +} + +.mock-packet-chain strong { + font-family: var(--font-mono), monospace; + text-transform: uppercase; +} + +.mock-packet-chain p { + margin: 0; + color: var(--mock-muted); + font-size: 0.8rem; + line-height: 1.42; +} + +.mock-packet-chain span { + color: var(--mock-accent); + font-family: var(--font-mono), monospace; + font-size: 0.68rem; +} + +.mock-packet-ledger { + grid-area: ledger; + overflow-x: auto; + border-block: 1px solid var(--mock-line); +} + +.mock-packet-row { + min-width: 760px; + min-height: 42px; + display: grid; + grid-template-columns: 98px 66px 92px 92px minmax(220px, 1fr) 60px; + gap: 10px; + align-items: center; + border-bottom: 1px solid var(--mock-line); + padding: 0 10px; + color: var(--mock-muted); + font-size: 0.76rem; +} + +.mock-packet-row:last-child { + border-bottom: 0; +} + +.mock-packet-row.is-head { + min-height: 30px; + color: var(--mock-faint); + font-family: var(--font-mono), monospace; + font-size: 0.62rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.mock-packet-inspector { + grid-area: inspector; + border-block: 1px solid var(--mock-line); + padding-block: 12px; +} + +.mock-alert-layout { + grid-template-columns: minmax(800px, 1fr) 320px; + grid-template-areas: "wall reason"; +} + +.mock-alert-wall { + grid-area: wall; + overflow-x: auto; + border-block: 1px solid var(--mock-line); +} + +.mock-alert-row { + min-width: 1080px; + min-height: 58px; + display: grid; + grid-template-columns: 78px 68px 118px 170px minmax(260px, 1fr) 170px 86px; + gap: 10px; + align-items: center; + border-bottom: 1px solid var(--mock-line); + padding: 0 10px; + color: var(--mock-muted); + font-size: 0.76rem; +} + +.mock-alert-row:last-child { + border-bottom: 0; +} + +.mock-alert-row.is-head { + min-height: 30px; + color: var(--mock-faint); + font-family: var(--font-mono), monospace; + font-size: 0.62rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.mock-alert-row.is-high { + background: var(--mock-accent-soft); + color: var(--mock-ink); +} + +.mock-alert-row p { + margin: 0; + line-height: 1.35; +} + +.mock-alert-reason { + grid-area: reason; + border-block: 1px solid var(--mock-line); + padding-block: 12px; +} + +.mock-alert-reason ol { + display: grid; + gap: 0; + margin: 0; + padding: 0; + list-style: none; +} + +.mock-alert-reason li { + display: grid; + gap: 5px; + border-top: 1px solid var(--mock-line); + padding: 12px 0; +} + +.mock-alert-reason li:last-child { + border-bottom: 1px solid var(--mock-line); +} + +.mock-alert-reason strong { + color: var(--mock-ink); +} + +.mock-alert-reason span { + color: var(--mock-muted); + font-size: 0.84rem; + line-height: 1.42; +} + +.mock-graph-layout { + grid-template-columns: minmax(680px, 1fr) 310px; + grid-template-areas: + "canvas routes" + "canvas strip"; +} + +.mock-graph-canvas { + grid-area: canvas; + position: relative; + min-height: 620px; + border-block: 1px solid var(--mock-line); + overflow: hidden; + background: + linear-gradient(0deg, var(--mock-line) 1px, transparent 1px) 0 0 / 100% 62px, + linear-gradient(90deg, var(--mock-line) 1px, transparent 1px) 0 0 / 82px 100%; +} + +.mock-graph-link { + position: absolute; + left: var(--x1); + top: var(--y); + width: calc(var(--x2) - var(--x1)); + display: grid; + gap: 4px; + border-top: 2px solid var(--mock-accent); + padding-top: 8px; +} + +.mock-graph-link.is-good { + border-color: var(--mock-good); +} + +.mock-graph-link.is-info { + border-color: var(--mock-info); +} + +.mock-graph-link.is-watch { + border-color: var(--mock-alt); +} + +.mock-graph-link strong { + font-family: var(--font-mono), monospace; + font-size: 0.74rem; + text-transform: uppercase; +} + +.mock-graph-link span { + color: var(--mock-muted); + font-size: 0.8rem; +} + +.mock-graph-node { + position: absolute; + display: grid; + place-items: center; + min-height: 46px; + border: 1px solid var(--mock-line-strong); + border-radius: 6px; + padding: 9px 12px; + background: var(--mock-surface-2); + color: var(--mock-ink); + font-family: var(--font-mono), monospace; + font-size: 0.72rem; + text-transform: uppercase; +} + +.mock-graph-node.is-options { + left: 7%; + top: 14%; +} + +.mock-graph-node.is-packet { + left: 38%; + top: 31%; +} + +.mock-graph-node.is-alert { + right: 8%; + top: 17%; +} + +.mock-graph-node.is-market { + left: 24%; + bottom: 19%; +} + +.mock-graph-routes { + grid-area: routes; + border-block: 1px solid var(--mock-line); + padding-block: 8px; +} + +.mock-graph-routes strong { + color: var(--mock-ink); +} + +.mock-graph-strip { + grid-area: strip; +} + @media (max-width: 1180px) { .mock-nav, .mock-hero, .mock-court-layout, .mock-desk-layout, .mock-theatre-layout, - .mock-map-layout { + .mock-map-layout, + .mock-options-layout, + .mock-packet-layout, + .mock-alert-layout, + .mock-graph-layout { grid-template-columns: 1fr; grid-template-areas: none; } @@ -4776,7 +5281,11 @@ h3 { .mock-court-layout > *, .mock-desk-layout > *, .mock-theatre-layout > *, - .mock-map-layout > * { + .mock-map-layout > *, + .mock-options-layout > *, + .mock-packet-layout > *, + .mock-alert-layout > *, + .mock-graph-layout > * { grid-area: auto; } @@ -4793,6 +5302,22 @@ h3 { .mock-desk-rail button { width: auto; } + + .mock-packet-chain, + .mock-flow-ladder { + grid-template-columns: 1fr; + } + + .mock-packet-chain article, + .mock-flow-ladder div { + border-right: 0; + border-bottom: 1px solid var(--mock-line); + } + + .mock-packet-chain article:last-child, + .mock-flow-ladder div:last-child { + border-bottom: 0; + } } @media (max-width: 720px) { @@ -4834,4 +5359,21 @@ h3 { width: 132px; min-height: 94px; } + + .mock-options-command button { + flex: 1 1 130px; + } + + .mock-graph-canvas { + min-height: 520px; + } + + .mock-graph-link { + width: 42%; + } + + .mock-graph-node { + max-width: 150px; + text-align: center; + } } diff --git a/apps/web/app/mock5/page.tsx b/apps/web/app/mock5/page.tsx new file mode 100644 index 0000000..29077e9 --- /dev/null +++ b/apps/web/app/mock5/page.tsx @@ -0,0 +1,7 @@ +import { DashboardMock } from "../dashboard-mocks"; + +export const dynamic = "force-dynamic"; + +export default function Mock5Page() { + return ; +} diff --git a/apps/web/app/mock6/page.tsx b/apps/web/app/mock6/page.tsx new file mode 100644 index 0000000..8ccc83b --- /dev/null +++ b/apps/web/app/mock6/page.tsx @@ -0,0 +1,7 @@ +import { DashboardMock } from "../dashboard-mocks"; + +export const dynamic = "force-dynamic"; + +export default function Mock6Page() { + return ; +} diff --git a/apps/web/app/mock7/page.tsx b/apps/web/app/mock7/page.tsx new file mode 100644 index 0000000..9ab0708 --- /dev/null +++ b/apps/web/app/mock7/page.tsx @@ -0,0 +1,7 @@ +import { DashboardMock } from "../dashboard-mocks"; + +export const dynamic = "force-dynamic"; + +export default function Mock7Page() { + return ; +} diff --git a/apps/web/app/mock8/page.tsx b/apps/web/app/mock8/page.tsx new file mode 100644 index 0000000..da1bc8d --- /dev/null +++ b/apps/web/app/mock8/page.tsx @@ -0,0 +1,7 @@ +import { DashboardMock } from "../dashboard-mocks"; + +export const dynamic = "force-dynamic"; + +export default function Mock8Page() { + return ; +} diff --git a/docs/turns/2026-06-11-1822-add-no-card-mock-routes.html b/docs/turns/2026-06-11-1822-add-no-card-mock-routes.html new file mode 100644 index 0000000..fd722f5 --- /dev/null +++ b/docs/turns/2026-06-11-1822-add-no-card-mock-routes.html @@ -0,0 +1,393 @@ + + + + + + Add no-card mock routes - Islandflow turn + + + +
+
+

Repository Implementation Turn

+

Added four no-card market-activity mock routes.

+

This turn kept the existing mock redesigns and added four new routes that model the Islandflow logic chain from options flow, to flow packets, to smart money party alerts, to route-wide market-activity context.

+
+ 2026-06-11 18:22 ET + Beads: islandflow-q7v + Scope: apps/web +
+
+ +
+

Summary

+

Created /mock5, /mock6, /mock7, and /mock8 as additional mock redesign routes. The new concepts intentionally avoid new card or panel primitives and use dense tables, line-separated ledgers, split panes, chains, and graph-like routing views instead.

+
+ +
+

Changes Made

+
    +
  • Extended DashboardMock to support four new variants while preserving /mock1 through /mock4.
  • +
  • Added route files for /mock5, /mock6, /mock7, and /mock8.
  • +
  • Added route-specific mock data for options intake rows, flow packet assembly, smart money alert reasons, and activity graph lanes.
  • +
  • Added CSS for no-card layouts built from rows, rails, split panes, ledgers, and graph nodes.
  • +
+
+
/mock5 optionsRaw options prints become packet candidates through a dense OPRA-style blotter.
+
/mock6 packetsFlow packets assemble options, equity, venue, sector, and readiness evidence.
+
/mock7 alertsSmart money party alerts expose reason, type, invalidation, and lineage.
+
/mock8 graphRoute-wide map connects options, packets, alerts, and market context without duplicating views.
+
+
+ +
+

Context

+

The existing mock lab already explored four broad design directions. This turn adds a second set focused on workflow semantics: options flow enters the system, becomes packet evidence, may generate an alert, and remains traceable through market context.

+

The user gave one non-negotiable rule: absolutely no cards. The new routes therefore avoid new card/panel class names and avoid content structures that read as repeated card grids.

+
+ +
+

Important Implementation Details

+
    +
  • MockVariant and variantOrder now include mock5 through mock8, so the mock navigation keeps all current variants and exposes the new ones.
  • +
  • The Options route uses a horizontally scrollable blotter only inside the table lane, preventing page-level overflow on mobile.
  • +
  • The Packets route makes packet assembly explicit before alert eligibility, matching the repo logic instead of inventing unrelated analytics.
  • +
  • The Alerts route gives every smart money party alert a reason, type, why-it-fired explanation, and invalidation condition.
  • +
  • The Activity Graph route explains how the themed routes relate to each other without introducing redundant feature surfaces.
  • +
+
+ +
+

Relevant Diff Snippets

+

The rendered excerpt below is generated with @pierre/diffs/ssr from a focused app mock-route patch excerpt.

+
+
apps/web/app/dashboard-mocks.tsx
-2+47
3 unmodified lines
4
45 unmodified lines
3 unmodified lines
53
290 unmodified lines
3 unmodified lines
type MockVariant = "mock1" | "mock2" | "mock3" | "mock4";
45 unmodified lines
3 unmodified lines
const variantOrder: MockVariant[] = ["mock1", "mock2", "mock3", "mock4"];
290 unmodified lines
3 unmodified lines
4
45 unmodified lines
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
3 unmodified lines
85
86
87
88
89
90
91
92
93
94
290 unmodified lines
385
386
387
388
3 unmodified lines
type MockVariant = "mock1" | "mock2" | "mock3" | "mock4" | "mock5" | "mock6" | "mock7" | "mock8";
45 unmodified lines
},
mock5: {
title: "Options Intake",
shortName: "Options",
routeName: "Options",
premise:
"A dense OPRA-style blotter turns contract activity into candidate flow packets, with strike context, sweep shape, venue mix, and confidence deltas visible in one scan.",
bodyClass: "mock-options"
},
mock6: {
title: "Packet Forensics",
shortName: "Packets",
routeName: "Flow Packets",
premise:
"Options prints, equity tape, venue imbalance, and news fragments are assembled into packets before any alert can earn attention.",
bodyClass: "mock-packets"
},
mock7: {
title: "Alert Reason Wall",
shortName: "Alerts",
routeName: "Alerts",
premise:
"Every smart money party alert is shown with the reason, type, invalidation path, and evidence lineage that caused it to fire.",
bodyClass: "mock-alerts"
},
mock8: {
title: "Market Activity Graph",
shortName: "Graph",
routeName: "Activity Graph",
premise:
"A route-wide intelligence board connects options flow to packets, packets to alerts, and alerts to broader market pressure without repeating the same evidence twice.",
bodyClass: "mock-graph"
3 unmodified lines
const variantOrder: MockVariant[] = [
"mock1",
"mock2",
"mock3",
"mock4",
"mock5",
"mock6",
"mock7",
"mock8"
];
290 unmodified lines
{variant === "mock5" ? <OptionsIntake /> : null}
{variant === "mock6" ? <PacketForensics /> : null}
{variant === "mock7" ? <AlertReasonWall /> : null}
{variant === "mock8" ? <MarketActivityGraph /> : null}
+
apps/web/app/globals.css
+71
3973 unmodified lines
788 unmodified lines
3973 unmodified lines
788 unmodified lines
3973 unmodified lines
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
788 unmodified lines
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
3973 unmodified lines
.mock-redesign.mock-options {
--mock-bg: oklch(0.075 0.02 250);
--mock-surface: oklch(0.105 0.024 250);
--mock-surface-2: oklch(0.13 0.03 250);
--mock-line: oklch(0.76 0.048 236 / 0.26);
--mock-line-strong: oklch(0.82 0.16 82 / 0.58);
--mock-accent: oklch(0.86 0.17 84);
--mock-accent-soft: oklch(0.86 0.17 84 / 0.12);
--mock-alt: oklch(0.74 0.2 32);
--mock-alt-soft: oklch(0.74 0.2 32 / 0.13);
background:
linear-gradient(90deg, oklch(0.7 0.05 240 / 0.11) 1px, transparent 1px) 0 0 / 34px 34px,
linear-gradient(180deg, oklch(0.11 0.026 250), var(--mock-bg) 42vh),
var(--mock-bg);
}
+
.mock-redesign.mock-packets {
--mock-bg: oklch(0.13 0.014 198);
--mock-surface: oklch(0.17 0.022 198);
--mock-surface-2: oklch(0.11 0.018 198);
--mock-line: oklch(0.76 0.04 198 / 0.22);
--mock-line-strong: oklch(0.78 0.15 176 / 0.54);
--mock-accent: oklch(0.78 0.15 176);
--mock-accent-soft: oklch(0.78 0.15 176 / 0.13);
--mock-alt: oklch(0.77 0.14 300);
--mock-alt-soft: oklch(0.77 0.14 300 / 0.13);
}
+
.mock-redesign.mock-alerts {
--mock-bg: oklch(0.11 0.026 22);
--mock-surface: oklch(0.16 0.032 22);
--mock-surface-2: oklch(0.13 0.028 22);
--mock-line: oklch(0.8 0.04 42 / 0.23);
--mock-line-strong: oklch(0.8 0.17 58 / 0.54);
--mock-accent: oklch(0.8 0.17 58);
--mock-accent-soft: oklch(0.8 0.17 58 / 0.13);
--mock-alt: oklch(0.74 0.16 24);
--mock-alt-soft: oklch(0.74 0.16 24 / 0.14);
}
+
.mock-redesign.mock-graph {
--mock-bg: oklch(0.1 0.026 274);
--mock-surface: oklch(0.155 0.034 274);
--mock-surface-2: oklch(0.125 0.03 274);
--mock-line: oklch(0.78 0.05 274 / 0.22);
--mock-line-strong: oklch(0.76 0.17 220 / 0.52);
--mock-accent: oklch(0.76 0.17 220);
--mock-accent-soft: oklch(0.76 0.17 220 / 0.13);
--mock-alt: oklch(0.78 0.16 340);
--mock-alt-soft: oklch(0.78 0.16 340 / 0.13);
}
788 unmodified lines
.mock-options-layout,
.mock-packet-layout,
.mock-alert-layout,
.mock-graph-layout {
max-width: 1600px;
margin: 0 auto;
display: grid;
gap: 12px;
}
+
.mock-options-layout {
grid-template-columns: minmax(720px, 1fr) 270px;
grid-template-areas:
"command depth"
"tape depth"
"ladder ladder";
}
+
.mock-options-command {
grid-area: command;
+
+
+ +
+

Expected Impact for End-Users

+

Traders reviewing the mock lab now have more varied route-level concepts that better explain how Islandflow turns raw options activity into trustworthy, evidence-linked alerts. The new mocks should make the product model easier to critique because each route owns a specific stage of the investigation.

+
+ +
+

Validation

+
+
Passed: bun --cwd=apps/web run build
+
Passed: Browser DOM checks for /mock5, /mock6, /mock7, and /mock8 at 1280px confirmed the routes render, expose expected content, and do not introduce page-level horizontal overflow.
+
Passed: Browser DOM checks at 390px confirmed page-level overflow stays contained and dense tables scroll inside their own lanes.
+
Passed: Browser console error check returned no errors.
+
Partial: A browser screenshot capture timed out in the local browser runtime, so visual confirmation used DOM layout checks rather than saved screenshots.
+
+
+ +
+

Issues, Limitations, and Mitigations

+
    +
  • The new mock routes are static concept screens, not connected to live API data. They are intended to guide product direction and critique.
  • +
  • Dense rows are intentionally scrollable on mobile. This preserves the terminal/blotter behavior without allowing the whole page to overflow.
  • +
  • The existing mock navigation still uses compact tab-like links from the previous mock lab. The no-card rule was applied to the new route content and new layout primitives.
  • +
+
+ +
+

Follow-up Work

+
    +
  • Turn the strongest concept into real /options, /alerts, and packet detail routes when the product direction is chosen.
  • +
  • Add browser-level visual regression checks for the mock lab once the route direction stabilizes.
  • +
  • Consider a follow-up Beads issue for wiring alert reasons to real packet provenance once backend data contracts are ready.
  • +
+
+
+ +