diff --git a/apps/web/app/concepts/page.tsx b/apps/web/app/concepts/page.tsx new file mode 100644 index 0000000..dda1f9b --- /dev/null +++ b/apps/web/app/concepts/page.tsx @@ -0,0 +1,724 @@ +import Link from "next/link"; +import type { ReactNode } from "react"; +import { + Bebas_Neue, + DM_Serif_Display, + Manrope, + Newsreader, + Oswald, + Sora, + Special_Elite +} from "next/font/google"; + +const brutal = Bebas_Neue({ + subsets: ["latin"], + weight: "400", + variable: "--font-concept-brutal" +}); + +const editorialDisplay = DM_Serif_Display({ + subsets: ["latin"], + weight: "400", + variable: "--font-concept-editorial-display" +}); + +const conceptSans = Manrope({ + subsets: ["latin"], + weight: ["400", "500", "600", "700"], + variable: "--font-concept-sans" +}); + +const editorialBody = Newsreader({ + subsets: ["latin"], + weight: ["400", "500", "600"], + variable: "--font-concept-editorial-body" +}); + +const condensed = Oswald({ + subsets: ["latin"], + weight: ["400", "500", "600"], + variable: "--font-concept-condensed" +}); + +const future = Sora({ + subsets: ["latin"], + weight: ["400", "500", "600", "700"], + variable: "--font-concept-future" +}); + +const notebook = Special_Elite({ + subsets: ["latin"], + weight: "400", + variable: "--font-concept-notebook" +}); + +const feedStates = [ + { label: "Opt", tone: "positive", value: "Live" }, + { label: "Eq", tone: "positive", value: "Live" }, + { label: "Flow", tone: "accent", value: "Dense" }, + { label: "Alert", tone: "negative", value: "9 high" } +]; + +const overviewMetrics = [ + { label: "Options", value: "284" }, + { label: "Equities", value: "142" }, + { label: "Flow", value: "36" }, + { label: "Alerts", value: "9" }, + { label: "Rules", value: "14" }, + { label: "Dark", value: "3" } +]; + +const alertRows = [ + { + title: "Stealth Accumulation", + meta: "Bullish | Score 92 | NVDA", + note: "Repeated bid-side sweeps with dark follow-through.", + tone: "positive" + }, + { + title: "Distribution Cluster", + meta: "Bearish | Score 81 | SPY", + note: "Offer-heavy packets rolling across three expiries.", + tone: "negative" + }, + { + title: "Gamma Pressure", + meta: "Neutral | Score 74 | QQQ", + note: "Market makers pinned near intraday resistance.", + tone: "neutral" + } +] as const; + +const flowRows = [ + { + title: "SPY 2026-06-21 C605", + meta: "18 prints | $2.8M notional | Agg 78%", + note: "Window 640ms with ask-side urgency.", + tone: "accent" + }, + { + title: "AAPL 2026-05-17 P185", + meta: "11 prints | $1.1M notional | Spread $0.07", + note: "Sweeps split across ARCA and CBOE.", + tone: "negative" + }, + { + title: "TSLA 2026-07-19 C240", + meta: "8 prints | $980k notional | In 33%", + note: "Late acceleration after lit print burst.", + tone: "positive" + } +] as const; + +const equityRows = [ + { + title: "NVDA", + meta: "$972.44 | 28,400x | Off-Ex", + note: "Dark ratio lifting into midday highs.", + tone: "positive" + }, + { + title: "SPY", + meta: "$604.12 | 91,300x | Lit", + note: "Index tape absorbing after alert burst.", + tone: "neutral" + }, + { + title: "AAPL", + meta: "$214.77 | 18,100x | Off-Ex", + note: "Block prints clustering beneath ask.", + tone: "accent" + } +] as const; + +const conceptSummary = [ + { + id: "concept-1", + index: "01", + title: "Mission Control", + style: "Dark command center" + }, + { + id: "concept-2", + index: "02", + title: "Market Journal", + style: "Editorial financial desk" + }, + { + id: "concept-3", + index: "03", + title: "Aurora Glass", + style: "Futurist glass cockpit" + }, + { + id: "concept-4", + index: "04", + title: "Tape Wall", + style: "Brutalist signal board" + }, + { + id: "concept-5", + index: "05", + title: "Field Notebook", + style: "Analyst workbench" + } +] as const; + +type ConceptSectionProps = { + id: string; + index: string; + title: string; + label: string; + summary: string; + designChoices: string[]; + responsive: string[]; + className: string; + children: ReactNode; +}; + +function ConceptSection({ + id, + index, + title, + label, + summary, + designChoices, + responsive, + className, + children +}: ConceptSectionProps) { + return ( +
+
+
+
+ {`Concept ${index}`} + {label} +
+

{title}

+

{summary}

+
+ +
+

Key Design Choices

+
    + {designChoices.map((choice) => ( +
  • {choice}
  • + ))} +
+
+ +
+

Responsive Considerations

+
    + {responsive.map((item) => ( +
  • {item}
  • + ))} +
+
+
+ +
{children}
+
+ ); +} + +function MockTopbar({ brand, kicker }: { brand: string; kicker: string }) { + return ( +
+
+ {kicker} + {brand} +
+ +
+ {feedStates.map((feed) => ( +
+ {feed.label} + {feed.value} +
+ ))} +
+ +
+
Filter: SPY, NVDA, AAPL
+ +
+
+ ); +} + +function MetricRack() { + return ( +
+ {overviewMetrics.map((metric) => ( +
+ {metric.label} + {metric.value} +
+ ))} +
+ ); +} + +function Module({ + title, + subtitle, + children, + className = "" +}: { + title: string; + subtitle?: string; + children: ReactNode; + className?: string; +}) { + return ( +
+
+
+

{subtitle ?? "Core module"}

+

{title}

+
+ Live +
+ {children} +
+ ); +} + +function ChartModule({ label }: { label: string }) { + return ( +
+
+ {label} + Signals layered on price +
+ +
+ 09:30 + 11:00 + 12:30 + 14:00 + 15:30 +
+
+ ); +} + +type MockRow = { + title: string; + meta: string; + note: string; + tone: string; +}; + +function ListModule({ + title, + subtitle, + rows +}: { + title: string; + subtitle: string; + rows: readonly MockRow[]; +}) { + return ( + +
+ {rows.map((row) => ( +
+
+

{row.title}

+ +
+

{row.meta}

+

{row.note}

+
+ ))} +
+
+ ); +} + +function MissionControlMockup() { + return ( +
+ + + +
+
+ + + + +
+
+ Highest urgency + Stealth accumulation in NVDA +
+
+ Replay readiness + Databento and Alpaca aligned +
+
+
+
+ +
+ + +
+
+ +
+ + +
+
+ Mode + Live +
+
+ Source + Auto +
+
+ Dark hits + 03 +
+
+ Focus ticker + NVDA +
+
+
+
+
+ ); +} + +function MarketJournalMockup() { + return ( +
+
+
+ Vol. 27 +

The Islandflow Market Journal

+
+
+ Overview page redesign + Same trading intelligence, calmer reading flow +
+
+ +
+ Filter: SPY, NVDA, AAPL + Mode: Live + Replay ready +
+ +
+ + + + + +
+

+ The page reads like a market front page: chart first, context second, then secondary + feeds as supporting columns. +

+

+ The same terminal content feels more analytical and less mechanical, which suits + review sessions and replay mode. +

+
+
+
+ +
+ + + +
+
+ ); +} + +function AuroraGlassMockup() { + return ( +
+ + +
+ + + + + + + +
+ +
+ + +
+
+ ); +} + +function TapeWallMockup() { + return ( +
+
+
+ Islandflow Overview +

Watch the tape before the tape watches you.

+
+
+ Live mode + Filter: SPY, NVDA, AAPL + Replay hotkey ready +
+
+ +
+ + + + + + + +
+ +
+ + + +
+
+ ); +} + +function FieldNotebookMockup() { + return ( +
+
+
+ Islandflow Research Board +

Overview page as an analyst workbench

+
+
+ Live + Replay + Filtered: NVDA / SPY / AAPL +
+
+ +
+
+ + + + +
+
+ Alert bias + Bullish momentum concentrated in tech. +
+
+ Flow quality + Packet clustering suggests institutional pacing. +
+
+ Replay use + Good for post-close annotation and handoff. +
+
+
+
+ +
+ + + +
+
+
+ ); +} + +export default function ConceptsPage() { + const fontVariables = [ + brutal.variable, + editorialDisplay.variable, + conceptSans.variable, + editorialBody.variable, + condensed.variable, + future.variable, + notebook.variable + ].join(" "); + + return ( +
+
+
+

Frontend redesign study

+

Five Overview concepts for Islandflow

+

+ Each concept keeps the same product story intact: filter controls, live or replay mode, + chart context, alerts, flow packets, and equities tape. What changes is the visual + system, layout logic, and the feeling of operating the page. +

+
+
+ + Current overview + +
+
+ +
+
+

What stays consistent

+

+ Every direction below preserves the same core modules and the same analyst workflow. + These are presentation explorations, not product scope changes. +

+
+ +
+ {conceptSummary.map((concept) => ( + + {concept.index} + {concept.title} + {concept.style} + + ))} +
+
+ + + + + + + + + + + + + + + + + + + + +
+ ); +} diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css index 0769f2a..1bd2be9 100644 --- a/apps/web/app/globals.css +++ b/apps/web/app/globals.css @@ -1079,3 +1079,823 @@ h3 { margin-top: 14px; } } + +.concepts-page { + display: grid; + gap: 28px; + padding-bottom: 56px; +} + +.concepts-header { + align-items: flex-start; +} + +.concepts-eyebrow { + margin: 0 0 8px; + color: var(--accent); + font-size: 0.78rem; + letter-spacing: 0.2em; + text-transform: uppercase; +} + +.concepts-lead { + max-width: 78ch; + margin: 14px 0 0; + color: var(--text-dim); + line-height: 1.7; +} + +.concepts-intro { + display: grid; + gap: 16px; + grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr); +} + +.concepts-intro-card { + padding: 22px 24px; + border-radius: 20px; + border: 1px solid var(--border); + background: linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.02)); +} + +.concepts-intro-card p { + margin: 0; + color: var(--text-dim); + line-height: 1.7; +} + +.concepts-intro-title { + margin: 0 0 10px; + font-size: 1.15rem; +} + +.concept-anchors { + display: grid; + gap: 14px; + grid-template-columns: repeat(5, minmax(0, 1fr)); +} + +.concept-anchor { + display: grid; + gap: 6px; + padding: 18px; + border-radius: 18px; + border: 1px solid var(--border); + background: rgba(255, 255, 255, 0.02); + transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease; +} + +.concept-anchor:hover { + transform: translateY(-2px); + border-color: rgba(245, 166, 35, 0.3); + background: rgba(255, 255, 255, 0.04); +} + +.concept-anchor span, +.concept-anchor small { + color: var(--text-dim); + font-size: 0.72rem; + text-transform: uppercase; + letter-spacing: 0.14em; +} + +.concept-anchor strong { + font-size: 0.96rem; +} + +.concept-section { + display: grid; + gap: 22px; + padding: 24px; + border-radius: 28px; + border: 1px solid var(--border); + background: + radial-gradient(circle at top right, rgba(245, 166, 35, 0.08), transparent 28%), + rgba(8, 11, 16, 0.94); +} + +.concept-copy { + display: grid; + gap: 18px; + align-content: start; +} + +.concept-copy-head { + display: grid; + gap: 10px; +} + +.concept-kicker { + display: flex; + flex-wrap: wrap; + gap: 10px; + color: var(--text-dim); + font-size: 0.72rem; + letter-spacing: 0.16em; + text-transform: uppercase; +} + +.concept-name { + font-size: clamp(2rem, 2.2vw, 2.7rem); +} + +.concept-summary { + margin: 0; + color: var(--text-dim); + line-height: 1.75; +} + +.concept-detail { + display: grid; + gap: 10px; +} + +.concept-detail-title { + font-size: 0.9rem; + color: var(--text); +} + +.concept-bullet-list { + margin: 0; + padding-left: 18px; + color: var(--text-dim); + display: grid; + gap: 10px; + line-height: 1.6; +} + +.concept-preview { + min-width: 0; +} + +.mockup-frame { + --mock-bg: #0d141c; + --mock-surface: rgba(10, 16, 22, 0.86); + --mock-surface-2: rgba(255, 255, 255, 0.06); + --mock-border: rgba(255, 255, 255, 0.1); + --mock-text: #eff6ff; + --mock-dim: #8d9fb2; + --mock-accent: #ffb13c; + --mock-accent-soft: rgba(255, 177, 60, 0.16); + --mock-positive: #76e7aa; + --mock-negative: #ff7f79; + --mock-neutral: #83beff; + position: relative; + overflow: hidden; + padding: 20px; + border-radius: 26px; + border: 1px solid var(--mock-border); + color: var(--mock-text); + background: var(--mock-bg); + box-shadow: 0 28px 70px rgba(0, 0, 0, 0.28); +} + +.mock-topbar, +.mock-metric-rack, +.mission-command, +.mission-footer, +.editorial-hero, +.editorial-columns, +.glass-overview, +.glass-secondary, +.brutal-main, +.brutal-ribbons, +.notebook-main, +.notebook-notes, +.mock-summary-grid, +.mock-operator-grid, +.notebook-callouts { + display: grid; + gap: 16px; +} + +.mock-topbar { + grid-template-columns: minmax(180px, auto) minmax(0, 1fr) minmax(220px, auto); + align-items: center; + padding: 16px 18px; + border-radius: 20px; + border: 1px solid var(--mock-border); + background: var(--mock-surface); + backdrop-filter: blur(20px); +} + +.mock-brand { + display: grid; + gap: 4px; +} + +.mock-brand-kicker, +.mock-module-kicker, +.mock-metric span, +.mock-row-meta, +.editorial-volume, +.editorial-toolbar, +.notebook-title span { + text-transform: uppercase; + letter-spacing: 0.14em; + font-size: 0.72rem; +} + +.mock-brand-kicker, +.mock-module-kicker, +.mock-metric span, +.mock-module-meta, +.mock-filter, +.mock-row-meta, +.mock-chart-labels, +.mock-chart-axis, +.editorial-volume, +.editorial-meta, +.editorial-toolbar, +.notebook-title span { + color: var(--mock-dim); +} + +.mock-brand-name { + font-size: 1.3rem; + font-weight: 700; +} + +.mock-status-cluster, +.mock-actions { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; +} + +.mock-status-cluster { + justify-content: center; +} + +.mock-actions { + justify-content: flex-end; +} + +.mock-chip, +.mock-button, +.mock-filter, +.notebook-tabs span, +.brutal-badges span { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 10px 12px; + border-radius: 999px; + border: 1px solid var(--mock-border); + background: var(--mock-surface-2); + font-size: 0.74rem; +} + +.mock-chip strong { + color: var(--mock-text); +} + +.mock-chip-positive { + border-color: rgba(118, 231, 170, 0.35); + background: rgba(118, 231, 170, 0.12); +} + +.mock-chip-negative { + border-color: rgba(255, 127, 121, 0.35); + background: rgba(255, 127, 121, 0.12); +} + +.mock-chip-accent { + border-color: rgba(255, 177, 60, 0.35); + background: rgba(255, 177, 60, 0.14); +} + +.mock-button { + color: var(--mock-text); +} + +.mock-filter { + min-width: 220px; +} + +.mock-metric-rack { + grid-template-columns: repeat(6, minmax(0, 1fr)); +} + +.mock-metric { + display: grid; + gap: 8px; + padding: 16px; + border-radius: 18px; + border: 1px solid var(--mock-border); + background: var(--mock-surface); +} + +.mock-metric strong { + font-size: 1.2rem; +} + +.mock-module { + display: grid; + gap: 14px; + min-width: 0; + padding: 18px; + border-radius: 22px; + border: 1px solid var(--mock-border); + background: var(--mock-surface); +} + +.mock-module-head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 16px; +} + +.mock-module-kicker { + margin: 0 0 6px; +} + +.mock-module-title, +.mock-row-head h4, +.editorial-masthead h3, +.brutal-banner h3, +.notebook-topbar h3 { + margin: 0; +} + +.mock-module-title { + font-size: 1.05rem; + line-height: 1.2; +} + +.mock-module-meta { + font-size: 0.72rem; + text-transform: uppercase; + letter-spacing: 0.14em; +} + +.mock-chart { + display: grid; + gap: 12px; +} + +.mock-chart-labels, +.mock-chart-axis { + display: flex; + justify-content: space-between; + gap: 12px; +} + +.mock-chart-svg { + width: 100%; + height: 250px; + border-radius: 18px; + border: 1px solid var(--mock-border); + background: + linear-gradient(0deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px), + linear-gradient(90deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px), + rgba(6, 10, 14, 0.45); + background-size: 100% 25%, 12.5% 100%; +} + +.mock-chart-area { + fill: var(--mock-accent-soft); +} + +.mock-chart-line { + stroke: var(--mock-accent); + stroke-width: 4; + stroke-linecap: round; + stroke-linejoin: round; +} + +.mock-chart-marker { + fill: var(--mock-positive); + stroke: rgba(0, 0, 0, 0.35); + stroke-width: 2; +} + +.mock-chart-marker-alt { + fill: var(--mock-negative); +} + +.mock-row-list { + display: grid; + gap: 12px; +} + +.mock-row { + display: grid; + gap: 8px; + padding: 14px 15px; + border-radius: 18px; + border: 1px solid var(--mock-border); + background: rgba(255, 255, 255, 0.03); +} + +.mock-row-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; +} + +.mock-row-head h4 { + font-size: 0.96rem; +} + +.mock-row-meta, +.mock-row-note, +.editorial-copy p, +.concept-anchors small { + margin: 0; +} + +.mock-row-note, +.editorial-copy p { + line-height: 1.55; +} + +.mock-tone-dot { + width: 10px; + height: 10px; + border-radius: 999px; +} + +.mock-tone-dot-positive { + background: var(--mock-positive); +} + +.mock-tone-dot-negative { + background: var(--mock-negative); +} + +.mock-tone-dot-neutral { + background: var(--mock-neutral); +} + +.mock-tone-dot-accent { + background: var(--mock-accent); +} + +.mock-summary-grid, +.mock-operator-grid, +.notebook-callouts { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.mock-summary-card, +.mock-operator-item, +.notebook-callout { + display: grid; + gap: 8px; + padding: 16px; + border-radius: 18px; + border: 1px solid var(--mock-border); + background: rgba(255, 255, 255, 0.03); +} + +.mock-summary-card span, +.mock-operator-item span, +.notebook-callout span { + color: var(--mock-dim); + font-size: 0.72rem; + text-transform: uppercase; + letter-spacing: 0.14em; +} + +.mission-frame { + font-family: var(--font-concept-sans), sans-serif; + background: + radial-gradient(circle at top left, rgba(255, 177, 60, 0.14), transparent 25%), + linear-gradient(145deg, #0a1118, #101923 60%, #081018); +} + +.mission-frame .mock-brand-name, +.mission-frame .mock-module-title { + font-family: var(--font-concept-condensed), sans-serif; + letter-spacing: 0.03em; +} + +.mission-command { + margin-top: 16px; + grid-template-columns: minmax(0, 1.5fr) minmax(280px, 0.95fr); +} + +.mission-main, +.mission-side { + display: grid; + gap: 16px; +} + +.mission-footer { + margin-top: 16px; + grid-template-columns: minmax(0, 1.3fr) minmax(260px, 0.9fr); +} + +.editorial-frame { + --mock-bg: linear-gradient(180deg, #f4eedf, #ece3cf); + --mock-surface: rgba(255, 252, 245, 0.85); + --mock-surface-2: rgba(130, 100, 56, 0.08); + --mock-border: rgba(98, 81, 53, 0.18); + --mock-text: #2d2418; + --mock-dim: #77624a; + --mock-accent: #95622a; + --mock-accent-soft: rgba(149, 98, 42, 0.16); + --mock-positive: #2f8454; + --mock-negative: #a14d4b; + --mock-neutral: #4c6f97; + font-family: var(--font-concept-editorial-body), serif; + box-shadow: 0 28px 70px rgba(35, 24, 12, 0.16); +} + +.editorial-frame .mock-module-title, +.editorial-masthead h3 { + font-family: var(--font-concept-editorial-display), serif; + letter-spacing: 0; +} + +.editorial-masthead { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 18px; + padding-bottom: 16px; + margin-bottom: 14px; + border-bottom: 1px solid rgba(98, 81, 53, 0.18); +} + +.editorial-masthead h3 { + font-size: clamp(2rem, 3vw, 3.2rem); + line-height: 0.95; +} + +.editorial-meta { + display: grid; + gap: 6px; + justify-items: end; + text-align: right; + font-size: 0.8rem; +} + +.editorial-toolbar { + display: flex; + flex-wrap: wrap; + gap: 18px; + padding-bottom: 16px; + margin-bottom: 16px; + border-bottom: 1px dashed rgba(98, 81, 53, 0.24); +} + +.editorial-hero { + grid-template-columns: minmax(0, 1.45fr) minmax(260px, 0.85fr); +} + +.editorial-columns { + grid-template-columns: repeat(3, minmax(0, 1fr)); + margin-top: 16px; +} + +.editorial-copy { + display: grid; + gap: 12px; +} + +.glass-frame { + --mock-bg: linear-gradient(145deg, rgba(7, 12, 18, 0.96), rgba(21, 45, 69, 0.94)); + --mock-surface: rgba(255, 255, 255, 0.08); + --mock-surface-2: rgba(255, 255, 255, 0.06); + --mock-border: rgba(180, 220, 255, 0.18); + --mock-text: #f4fbff; + --mock-dim: #b2c8dc; + --mock-accent: #93d8ff; + --mock-accent-soft: rgba(147, 216, 255, 0.17); + --mock-positive: #8effc2; + --mock-negative: #ff93ad; + --mock-neutral: #b8cfff; + font-family: var(--font-concept-future), sans-serif; + background: + radial-gradient(circle at 15% 18%, rgba(125, 222, 255, 0.28), transparent 20%), + radial-gradient(circle at 88% 12%, rgba(180, 122, 255, 0.22), transparent 22%), + radial-gradient(circle at 55% 82%, rgba(126, 255, 201, 0.18), transparent 24%), + linear-gradient(145deg, rgba(7, 12, 18, 0.98), rgba(21, 45, 69, 0.94)); +} + +.glass-overview { + grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.4fr) minmax(260px, 0.92fr); + margin-top: 16px; +} + +.glass-secondary { + grid-template-columns: repeat(2, minmax(0, 1fr)); + margin-top: 16px; +} + +.glass-frame .mock-module, +.glass-frame .mock-topbar, +.glass-frame .mock-metric { + backdrop-filter: blur(24px); +} + +.brutal-frame { + --mock-bg: #f0dd53; + --mock-surface: rgba(255, 250, 207, 0.92); + --mock-surface-2: rgba(13, 14, 16, 0.08); + --mock-border: rgba(13, 14, 16, 0.9); + --mock-text: #111318; + --mock-dim: rgba(17, 19, 24, 0.7); + --mock-accent: #111318; + --mock-accent-soft: rgba(17, 19, 24, 0.12); + --mock-positive: #208b4d; + --mock-negative: #bf3730; + --mock-neutral: #2b66c7; + font-family: var(--font-concept-sans), sans-serif; + box-shadow: 0 28px 70px rgba(36, 28, 7, 0.22); +} + +.brutal-banner { + display: grid; + gap: 14px; + padding: 18px; + border: 2px solid rgba(13, 14, 16, 0.92); + border-radius: 22px; + background: rgba(255, 250, 207, 0.92); +} + +.brutal-banner-copy span, +.brutal-badges span, +.brutal-frame .mock-module-kicker, +.brutal-frame .mock-metric span { + font-family: var(--font-concept-brutal), sans-serif; + letter-spacing: 0.12em; +} + +.brutal-banner h3 { + font-family: var(--font-concept-brutal), sans-serif; + font-size: clamp(2.5rem, 4vw, 4.3rem); + line-height: 0.9; + text-transform: uppercase; + letter-spacing: 0.03em; +} + +.brutal-badges { + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +.brutal-main { + grid-template-columns: minmax(250px, 0.7fr) minmax(0, 1.4fr); + margin-top: 16px; +} + +.brutal-ribbons { + grid-template-columns: repeat(3, minmax(0, 1fr)); + margin-top: 16px; +} + +.brutal-frame .mock-module, +.brutal-frame .mock-metric, +.brutal-frame .mock-row, +.brutal-frame .mock-chart-svg { + border-width: 2px; + box-shadow: 8px 8px 0 rgba(17, 19, 24, 0.18); +} + +.notebook-frame { + --mock-bg: linear-gradient(180deg, #efe5d1, #e5d7bc); + --mock-surface: rgba(255, 248, 235, 0.85); + --mock-surface-2: rgba(118, 92, 54, 0.08); + --mock-border: rgba(124, 101, 67, 0.22); + --mock-text: #2d261d; + --mock-dim: #6e5d47; + --mock-accent: #8a6233; + --mock-accent-soft: rgba(138, 98, 51, 0.14); + --mock-positive: #4d8f60; + --mock-negative: #a45a53; + --mock-neutral: #607996; + font-family: var(--font-concept-editorial-body), serif; + box-shadow: 0 28px 70px rgba(50, 38, 23, 0.18); +} + +.notebook-topbar { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 16px; + padding-bottom: 12px; + margin-bottom: 16px; + border-bottom: 1px dashed rgba(124, 101, 67, 0.3); +} + +.notebook-title h3, +.notebook-frame .mock-module-title { + font-family: var(--font-concept-notebook), serif; + text-transform: none; + letter-spacing: 0.02em; +} + +.notebook-title h3 { + font-size: clamp(1.8rem, 2.3vw, 2.4rem); + line-height: 1.1; +} + +.notebook-tabs { + display: flex; + flex-wrap: wrap; + gap: 10px; + justify-content: flex-end; +} + +.notebook-layout { + display: grid; + gap: 16px; +} + +.notebook-main { + grid-template-columns: minmax(0, 1.25fr) minmax(280px, 0.9fr); +} + +.notebook-notes { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.notebook-callouts { + grid-template-columns: minmax(0, 1fr); +} + +@media (min-width: 1181px) { + .concept-section { + grid-template-columns: minmax(290px, 360px) minmax(0, 1fr); + } +} + +@media (max-width: 1180px) { + .concepts-intro, + .concept-anchors, + .glass-overview, + .mission-command, + .mission-footer, + .editorial-hero, + .editorial-columns, + .glass-secondary, + .brutal-main, + .brutal-ribbons, + .notebook-main, + .notebook-notes { + grid-template-columns: minmax(0, 1fr); + } + + .concept-anchors { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 900px) { + .mock-topbar, + .mock-metric-rack, + .mock-summary-grid, + .mock-operator-grid { + grid-template-columns: minmax(0, 1fr); + } + + .mock-status-cluster, + .mock-actions, + .editorial-meta, + .notebook-tabs { + justify-content: flex-start; + text-align: left; + } + + .editorial-masthead, + .notebook-topbar { + flex-direction: column; + align-items: flex-start; + } +} + +@media (max-width: 720px) { + .concepts-page { + gap: 22px; + } + + .concept-section, + .mockup-frame { + padding: 18px; + } + + .concept-anchors { + grid-template-columns: minmax(0, 1fr); + } + + .mock-filter { + min-width: 0; + width: 100%; + } + + .brutal-banner h3, + .editorial-masthead h3 { + font-size: 2.2rem; + } + + .mock-chart-svg { + height: 220px; + } +} diff --git a/apps/web/app/terminal.tsx b/apps/web/app/terminal.tsx index 8f1c2e0..a5b09d3 100644 --- a/apps/web/app/terminal.tsx +++ b/apps/web/app/terminal.tsx @@ -3223,7 +3223,8 @@ const NAV_ITEMS = [ { href: "/tape", label: "Tape" }, { href: "/signals", label: "Signals" }, { href: "/charts", label: "Charts" }, - { href: "/replay", label: "Replay" } + { href: "/replay", label: "Replay" }, + { href: "/concepts", label: "Concepts" } ]; type PageFrameProps = {