Titandocs

Screen patterns

How the three screens are laid out, and the composition rules each one demonstrates.

Three routes, each .page-in on its root.

Trade

The densest screen. Fixed, non-scrolling, sized to the viewport.

root      : flex flex-col gap-3 p-3 h-[calc(100vh-64px)] overflow-hidden
pair strip: -mx-3 h-[60px] px-5 border-b
            pair glyph · live price (flash on tick) · 24h change · stats
            PiP detach button on the right
workspace : grid-cols-[1fr_300px_300px] gap-3 flex-1 min-h-0
            └─ main panel (chart) · order book · order form
               (panel order is data-driven: PanelKey = "chart" | "book" | "panel")
positions : rounded-[18px] panel, max-h-[40vh], scrollable, sticky header

Building blocks worth copying:

BlockDetail
TokenIconLogo if available, else a linear-gradient(135deg,…) fallback circle. ring-2 ring-[var(--surface)] when overlapping
PairGlyphTwo overlapping TokenIcons, quote offset left: size*0.62
SparklineInline SVG path, 72×22, stroke = up ? green : red
Side togglegrid-cols-2 p-[3px] rounded-[var(--r)] bg-[var(--surface-3)]; active side fills green/red, text white
Order formSize row grid-cols-[1fr_92px_92px], percent buttons grid-cols-4
Impact cardTriple concentric SVG ring, animated strokeDashoffset
Funding heatmapgrid-cols-12 gap-[3px], intensity via color-mix

Panel order is data-driven (PanelKey), not hardcoded JSX order. That is what makes the order book collapsible and the layout reorderable without touching the grid definition.

The positions table demonstrates three rules at once — the 3px side bar, --warn for liquidation, and right-aligned tabular numerics:

MarketSizeEntryMarkLiq.PnL
BTC-USDCXLONG 10×0.4200061,880.0064,212.2556,410.00+979.55
ETH-USDCXSHORT 5×3.24003,410.203,466.803,980.10−183.38
SOL-USDCXLONG 20×112.00186.40191.02178.55+517.44

Portfolio

Equity overview + holdings + transactions. Scrolls normally.

root      : mx-auto max-w-[1280px] px-6 pt-[30px] pb-24
title     : text-[27px] font-semibold tracking-[-0.02em]
overview  : grid rounded-[22px] border bg-surface
            grid-template-columns: minmax(0,1fr) 372px  (→ 1fr below 1020px)
            ├─ left  : equity area chart (tabs + period selector)
            └─ right : holdings panel (ring donut + allocation rows)
txns      : rounded-[18px] panel, transactions table

Chart controls. Tabs Total value ↔ PnL with an animated underline; period 24H / 3D / 7D / 14D / 30D. The chart replays its reveal on a revealSignature prop built from both controls:

<EquityChart revealSignature={`${period}-${tab}`} />

A deliberate composite, so switching either control re-animates.

Area chart. stroke/fill var(--green), fillOpacity 0.16, margins {top:16,right:50,bottom:24,left:2}, portaled bottom axis (5 labels) and right Y axis (4 ticks). In PnL mode values are signed and the axis prefixes +/−.

Holdings. Ring donut size=172 strokeWidth=18 ringGap=5 baseInnerRadius=34; segments coloured by greenRamp(mix) = color-mix(in oklch, var(--green) <mix>%, var(--surface)). Allocation rows are expandable — chevron rotates 180°, 9px colour dot, expanded rows reveal 28px coin badges.

12,418.42USDCx

TLP — Titan Liquidity Pool

A design playground, not a finished screen. It ships four alternative layouts behind a tab selector, persisted in localStorage["titan-tlp-variant"]. They are competing explorations of the same product — pick one (or merge ideas) for the real build. Do not ship all four.

The route is currently disabled for the MVP; the nav tab is gated off too.

VariantConceptNotable patterns
Composer (default)Focused "how much to stake"max-w-[720px], rounded-[24px] + inset shadow, 60px stake input, .titan-cta, spring bump on earnings
CockpitDense dashboardgrid-cols-[2.5fr_1.5fr_1fr_1.5fr] of min-h-[312px] cards, sticky header backdrop-blur(40px), 48px TVL, inline sparklines
Living Vault"Alive" vaultp-8 split containers, green live-pulse halo, multi-chain dots
Liquid AllocAllocation railgrid-cols-[1fr_60px_1fr] divider column, glossy range thumb, infinite marquee ticker (38s linear)

Picture-in-Picture

The trade page can detach into a Document PiP window (documentPictureInPicture). The mount copies the token stylesheet across, because a PiP document does not inherit the opener's styles — without that copy every token resolves to nothing and the window renders unstyled.

On this page