Skip to content

refactor(theme): replace html.dark selectors with semantic tokens#10

Open
chef-eric wants to merge 190 commits into
mainfrom
feat/perps-simple3
Open

refactor(theme): replace html.dark selectors with semantic tokens#10
chef-eric wants to merge 190 commits into
mainfrom
feat/perps-simple3

Conversation

@chef-eric

Copy link
Copy Markdown
Collaborator

Summary

  • Replaced every html.dark & block in styled-components with theme-aware semantic tokens (CSS vars), so dark/light switching flows through --pcs-colors-* instead of selector-keyed overrides.
  • Added new tokens for cases without an exact existing match: v2Inverse/v2Default (pure black/white inverse), tooltipInverseBg/tooltipInverseText (high-contrast tooltip surface), negative60/negativeSubtle (long/short shades that differ from destructive*), walletChip* (spot/perp bucket chips), timeframe* (TfRoot in WalletPanel), levTrackBg (leverage-slider gradient), and sunken/sunkenStrong shadow tokens. All exposed via pcsTheme for styled-components.
  • Refactored .storybook/preview.css to read CSS vars directly in both modes — only html.dark { color-scheme: dark } remains because the browser needs that signal for native form/scrollbar styling.
  • Added an ESLint rule (no-restricted-syntax) that bans html.dark inside any styled / css / keyframes / createGlobalStyle template literal, with a guidance message pointing at the design-system files. Documented in AGENTS.md.
  • Cleared the lint debt that blocked the commit: react-refresh disables on shared modules, removed dead styled-components in SimpleBetPanel, _-prefixed unused props, restored hooks order in OrderForm (early if (isMobile) return now sits below all hooks), and added a project-wide eslint allowance for _-prefixed identifiers.

Test plan

  • Toggle dark/light in Storybook toolbar — grabber pills, tooltips, PnL chips, side toggles, leverage slider, wallet bucket chips, and timeframe pills all flip correctly.
  • Storybook docs pages render with the right background/text in both modes.
  • pnpm lint passes with no no-restricted-syntax violations.
  • pnpm build:lib produces dist/primitives.js + dist/widgets.js with no TS errors.
  • Smoke-test: PerpsPage and SimplePerpsPage stories render without visual regressions.

🤖 Generated with Claude Code

ChefSalade and others added 30 commits April 27, 2026 14:33
Introduces a Spot / Perp / Farming bucket model so users can see how
their balance is distributed across EOA wallet, Aster perp contract,
and PCS LP positions, with weighted PnL across all three.

- Total + weighted PnL hero with 24H/7D/All segmented control
- Top composition strip (purple/amber/teal) with legend
- Three collapsible bucket cards, each with subtotal + per-bucket PnL
  pill + % share bar
  - Spot expands to token rows + Send/Receive/Swap actions
  - Perp expands to margin used/available + open positions
  - Farming expands to pending CAKE rewards + LP positions with
    in-range/out-of-range tags
- Hide-balance eye toggle, Hide-small-balances checkbox, Bridge link
- Themes via PCS CSS variables — light/dark switch automatically
- Storybook variants for default + each bucket expanded + timeframes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Refine WalletPanel to match Figma simplified design (Spot + Perps only,
  drop Farming/eye/hide-small-balances row, add chain grid wallet chip,
  inline-decimal hero, gradient composition bar, click-to-expand bucket
  cards with token/position lists and Send/Receive/Swap or
  Deposit/Withdraw/Manage actions).
- Add WalletPanelCompact: groups composition + buckets into a single
  Overview-titled card with internal 1px section dividers.
- Add WalletPanelCompactV1: drill-down navigation pattern — bucket rows
  show vertical color bar + right chevron; clicking opens a full bucket
  detail view with back-arrow header.
- Standardize "Hide small balances" pill across all 3 variants
  (8px padding, 12px radius, card-secondary bg, 1/1/2/1 borders).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… polish

PerpsPage
- Renders MobilePerpsPage at viewports ≤ 767 px via a small
  matchMedia hook (mobile breakpoint = 767). MobilePerpsPage
  fills the responsive viewport up to the same 767 px cap.

MobilePerpsPage
- Wired all the previously-static affordances to real interactions
  matching the desktop:
    • leverage pill opens the LeverageModal (BunnySlider inside)
    • order-type select opens a portaled menu with
      Market / Limit / Stop Limit / Stop Market
    • symbol pill opens a full-page MarketsDropdown action sheet
    • star toggles activeSymbol in the favourites set (style
      mirrors the dropdown's StarSvg)
    • order-book footer icon mirrors the desktop view-icons
      (Both / Asks / Bids) and opens a bottom action sheet
    • tick-size button opens a 0.1 → 100 dropdown
    • history icon opens a full-page History sheet with
      Order / Trade / Transactions tabs (PCS styling)
- Replaced the broken history SVG with the standard MD `history`
  glyph; replaced the local Chart with PCS ChartIcon /
  ChartDisableIcon (filled / strike-through state).
- Removed the bottom-right filter icon and the unused Filter SVG.
- Account row: removed Transfer; Deposit promoted to primary
  teal CTA.
- All sheet headers put the close button on the right and use
  textSubtle fill (PCS secondary-fill icon colour).

MarketsDropdown
- @media (max-width: 767px) → full-page action sheet with no
  border / radius / shadow so the widget itself reads identically
  to the symbol-pill sheet on MobilePerpsPage.
- Row hover swapped from `input` to `cardSecondary` and given an
  8 px border-radius + 0.12s transition.

PositionsPanel
- Row-hover padding reduced to 16 × 12 across all 4 tables.
  Padding now lives on RowGroup's `& > *` so it actually applies
  to the data cells (parent grid's `& > *` only reaches Th
  headers because RowGroup is display:contents).

Modal primitive
- Close button gets `mr="-4px"` so the icon optically aligns 4 px
  closer to the modal's right edge across every Modal-backed
  widget.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…pansion

- Replace placeholder lavender squares with real 3D PNG icons (brown
  leather wallet for Spot, blue candle chart for Perps); remove the
  vertical color bars on bucket rows.
- Detail view top group (hero + track + description) tightened to
  8px gaps via new `.wpc1-detail-top` wrapper; root keeps 16px gap
  to the next section.
- Perp detail (when user clicks Perps Balance row) replaced with the
  new layout: simplified description, no positions list at top,
  Balance + Unrealized PnL stats card, Transfer / Withdraw / Deposit
  action buttons (Deposit is primary).
- Stats card supports per-row expansion (mutually exclusive). Click
  caret on Balance: shows Hide small balances + USDC/ETH/BNB token
  rows. Click caret on Unrealized PnL: shows Hide small balances +
  ETH Long / BTC Short / BNB Long position rows. Caret rotates 180°
  when its section is expanded.
- Add `balanceTokens` field to perp bucket data with mock USDC/ETH/BNB
  collateral.
- Update perp action prop type to include 'transfer'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add OrderHistoryRow type + orderHistory prop. Replace the "coming soon"
placeholder with a table that renders date/time/symbol/side/type/price/
size/filled/status. Tab label reflects row count.

Consumed by pancake-frontend's PositionsPanel adapter via the new
usePrivateOrderHistory hook (separate PR on feat/perps-aster).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
LeverageModal:
- Swap BunnySlider for the primitive Slider with variant="dotted".
  Round dots land on multiples of `max/4`: BTCUSDT (max 200) → stops at
  1/50/100/150/200, SOLUSDT (max 100) → 1/25/50/75/100. Slider min=0
  with caller-side clamp keeps the user-facing minimum at 1.

SimpleBetPanel:
- Add `betError?: string` prop rendered under the bet input as a
  failure-colored hint. Consumer pairs with `canSubmit={false}` so
  UP/DOWN disable while the message is showing — gives a visible reason
  ("At least 3.83 USDT required") instead of a silent disable when the
  bet would floor to a sub-lot-size qty.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
411px modal with 24px radius, 1/1/2/1 cardBorder, dual shadow.
Header "Order Confirmation" Kanit 16/600. Token row shows pair +
↑ Up / ↓ Down pill (success/failure colored). 4 detail rows
(Price / Est. Liquidation price / Position size / Time duration).
"Don't show again" inset card (8/16 padding, 16px radius, 1/1/2/1
border, cardSecondary bg) with custom 24×24 checkbox (8px radius,
2px border-bottom, success-green bg + white tick when checked,
secondary purple focus ring). Confirm (primary teal) / Cancel
(tertiary light) buttons match the Deposit/Withdraw button spec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… overflow

- Replace BTC/USD label + Perp tag with single PairDropdown pill
  (24px tall, 8px radius, 1/1/2/1 input-secondary borders, input-
  primary bg, Kanit 14/600/21px text + 20px arrow icon)
- Markets popover opens on click: 697px wide, 24px radius,
  1/1/2/1 cardBorder, dual shadow. Tabs Favorites (active
  secondary purple) / All markets. Search field 7/8/9/16 padding,
  16px radius, 1/1/2/1 input-secondary border, input-primary bg.
  Table SYMBOLS / LAST PRICE / 1D CHANGE / 1D VOLUME (USDT) with
  3 mock rows (BTC / CAKE / ETH) + favorited star
- Responsive metrics: each Stat flex-shrink: 0 to keep 24px gap
  constant; ticker info Left flex-shrink: 0 so it never collapses;
  Card's space-between makes the gap between info and metrics
  shrink first. ResizeObserver-driven chevron `>` appears at the
  right edge of StatsWrap when metrics overflow

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Deposit/Withdraw buttons: padding 11px 12px 13px 12px, flex 1 0 0
  align-self: stretch, 16px radius, 2px asymmetric border-bottom
  (0.20 for primary teal / 0.10 for secondary), background switches
  V1-Global-Primary vs V1-Main-Tertiary (#EFF4F5), Kanit 16/600
- Unrealized PnL card: padding 16, 24px radius, 1/1/2/1 cardBorder,
  cardSecondary (#FAF9FA) bg. Label H4 (Kanit 20/600/30px text-
  subtle). Value H2 Mobile (Kanit 32/600/120% text-primary right-
  aligned)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add card chrome to the SimpleBetPanel Root: 24px radius,
1/1/2/1 cardBorder, overflow: hidden, card-primary bg. The
inner StyledCardInner has its border-radius forced to 0 to
prevent nested rounded corners. Move padding from the inner
div onto TopCard and Bottom (24px each) so the Bottom's
border-top divider goes edge-to-edge across the panel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Tabs: padding 8/16, gap 4, align-self stretch. Active tab uses
  secondary purple Kanit 16/600 with 12/12/12/16 padding + 16px
  radius pill. Inactive tabs use text-subtle Kanit 16/400 with
  uniform 12px padding (no underline)
- Column headers (Th): secondary purple Kanit 12/600 uppercase
  0.24px tracking (Pretitle)
- Value cells (Td): text-primary Kanit 16/400 right-aligned
  (Body)
- PnL cell: Kanit 20/600/-0.2px (H4). Positive uses --pcs-colors-
  positive60 (#129E7D) instead of generic theme.colors.success
  for the dimmer shade Figma calls for

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ton refinements

- ZonePill: spec'd borders/bg per zone (#129E7D safe, #FFB237 warn, #ED4B9E danger),
  emoji slot (🌿/⚡️/🔥), 2-line clamp, and hover/focus tooltip with copy per zone
- UP/DOWN buttons: 24px radius, 2/2/4/2 dark border, 24px Kanit text, 24×24 arrow SVGs;
  always wrapped in UpDownCard with stats list rendered only when bet is filled
- Bet field: focus ring (#7645D9 + purple-20 halo) via :focus-within; whole field is
  clickable (rendered as <label>) so empty space focuses the input
- Leverage: removed colored zone fill so the bubblegum gradient stays visible end-to-end
  (light keeps gradient, dark falls back to backgroundBubblegum); custom-input suffix
  switched to %
- Ticker % pill: spec'd flex/padding/gap, #EAFBF7 / #FFF0F9 backgrounds, new triangle
  SVG paths in #129E7D / #ED4B9E
- Positions table close button: 32×32, 8px radius, 1/1/2/1 #ED4B9E border, #FFF0F9 fill

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Perpetual / 1h / 30m / 15m / 5m" row was a static prototype
placeholder. Aster's regular perp REST API (POST /fapi/v3/order) has
no duration / auto-settle field — fixed-duration bets only exist on
the separate on-chain `predictAndBet` contract powering the
`/trade/1001x/...` prediction product, which is a different
integration entirely. Drop the dead UI; restore here only if/when we
wire the prediction product.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
These row interfaces have been declared on PositionsPanel since the
trade/tx history tabs were introduced, but they were missing from
the barrel export — consumers couldn't type their adapter mappers
against them. Surface them alongside OrderHistoryRow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Order History / Trade History / Transaction History tables previously
grew to fit every row. With ~100 entries on a busy account the panel
pushed the rest of the page off-screen.

Add a shared `historyTableScroll` mixin (max-height 360px,
overflow-y: auto) on the three history tables and make `Th` cells
position: sticky so the header row stays anchored while rows scroll.
Sticky is a no-op when the parent doesn't scroll, so this is safe on
the Positions / Open Orders tables which don't use the mixin today.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…olHeader

Add `marketsOpen` + `onMarketsOpenChange` props so the consumer can
lift the dropdown's open lifecycle into a shared atom — needed when
another markets trigger lives elsewhere on the page (e.g. the Simple
ticker chevron, the bet panel asset chip) and would otherwise pop a
second dropdown alongside this one.

When `marketsOpen` is omitted the widget falls back to its own
useState, so existing call sites keep working unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Radix-Popover-backed tooltip hook with the same return shape as
@pancakeswap/uikit's useTooltip — call sites are portable across
this repo and pancake-frontend. Replaces the ad-hoc CSS-hover
ZoneTipBubble in SimpleBetPanel and documents the canonical pattern
plus the Anchor-must-be-sibling gotcha under "Tooltips" in AGENTS.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit added the dep to package.json but the lockfile
update from `pnpm install` was lost during a stash dance — CI's
`--frozen-lockfile` would fail without this.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chef-eric and others added 2 commits May 8, 2026 16:55
AccountPanel, SymbolHeader, OrderForm, PositionsPanel, OrderBook, and
ChartPanel previously branched on isMobile only (xs+sm, <576px), so a
tablet-width viewport rendered the desktop variant inside a mobile
shell. Treat tablet (md/lg, 576-967px) as mobile too — the touch-
optimized layout now covers everything below uikit's xl/968px.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chef-eric and others added 2 commits May 8, 2026 17:56
Lets callers (e.g. pancake-frontend's Mobile.tsx / Desktop.tsx, which
already decide layout at a higher level) lock the rendered variant
instead of branching on viewport. Critical for chart libraries that
don't survive an unmount/remount cycle — TradingView's paid Charting
Library breaks after widget.remove(), so the second instance after a
viewport-driven flip never bootstraps. Auto-responsive behavior is
unchanged when variant is omitted.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chef-eric and others added 2 commits May 9, 2026 14:56
…pdown

Replaces the generic Select primitive with the same MenuPanel chrome the
Stop Limit / Stop Market type-tab dropdown uses, so the two selects in the
order form share one visual language. Renames the styled components from
Stop* to Menu* and reuses them; the trigger lives inline inside the row
as a borderless button so the row's existing input chrome owns the frame.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chef-eric and others added 2 commits May 9, 2026 15:05
Replace the title-bar-and-tight-prose layout with a centered warning
glyph (warning60 on a warning10 disc with a soft warning20 halo) above
the message, and full-width Cancel/Confirm buttons pinned to the
bottom. Update the copy to spell out the dual cancel-orders + market-
close-positions effect of the action.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chef-eric and others added 2 commits May 9, 2026 15:17
…AN-11856)

Mirrors asterdex's TIF descriptions. Each MenuPanelItem now owns a
useTooltip instance with the long-form explanation pulled straight from
the ticket screenshot:

- GTC: order continues to work until it fills or is canceled.
- IOC: executes all or part immediately and cancels any unfilled
  portion.
- FOK: must be filled immediately in its entirety or not at all.

Hooks can't sit inside a .map body, so the per-row content is split out
into a TifMenuItem subcomponent. Tooltip placement is 'left' to match
the screenshot — Radix flips automatically when there isn't enough room.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chef-eric and others added 2 commits May 9, 2026 15:32
- Strip the warning10 disc + warning20 blurred bloom around the warning
  glyph; render it plain in warning60 at 40px so it doesn't fight the
  modal's own surface.
- Pass headerBorderColor=transparent to hide the 1px cardBorder
  bottom rule on the now-empty modal header.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chef-eric and others added 2 commits May 9, 2026 18:28
…mula

Replaces `availableBalance` prop with caller-owned
`remainingOpenableAtLeverage(lev)` so consumers can wire the venue's
real headroom — `min(bracketCap − usedNotional, oiRemaining[ceil(lev)])`
— instead of the simple `balance × lev` overestimate that caused
-2027 surprises at high leverage. Updates copy + adds the
"leverage applies to open positions and orders" warning to match
asterdex.com. Stories now demonstrate both clamps (bracket-bound at
high lev, platform-OI-bound at low lev) and the loading / fallback
paths. PAN-11910.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Juan Pablo Velez and others added 2 commits May 26, 2026 20:00
…ickers

New AI Copilot app (Apps/AI Copilot) forked from PerpsPage with a 3-tab
chart-side panel and the full trade-idea flow:

- AiCopilotPanel: underline tabs (AI Copilot | Order Book | Trades). The
  Copilot tab has the margin input (focus glow), Style/Strategy
  dropdowns, a "Generate trade ideas" button with a metallic sheen, and a
  fixed 732px height with the idea list scrolling internally.
  - Generate flow: empty state (Bruce mascot + dashed card) →
    "Analyzing BTC-USDT…" loading button + shimmering skeleton →
    staggered fade/rise idea cards (sheen stops once ideas exist).
  - Idea card: Long/Short + style tags, Entry/TP/SL, SL→TP range bar with
    high-contrast marker, R:R tag, margin-derived P/L, "Why this setup?"
    inline accordion, Create long/short CTA.
  - Mascot PNG with mix-blend-screen + a sheen sweep synced to the button.

- QuickOrderPanel: slides in from the left over the trading card on a
  Create CTA. Market/Limit toggle (limit adds a price field), Cross/50x,
  Avbl row, size input + dotted bunny slider, summary rows, Confirm CTA.

- OptionPickerModal: centered pop-up (overlay rgba(40,13,95,0.6)) for the
  Style + Strategy dropdowns — option cards with a green check on the
  selected one; mounted only while open so the tentative selection seeds
  from the committed value without a reset effect.

- Size input <-> bunny slider linked through the available balance in both
  the Quick Order panel and the main OrderForm. Mock random available
  balance shared across the order form, Avbl row, and quick order.
Juan Pablo Velez and others added 2 commits May 26, 2026 20:34
- Remove the desktop "Transaction History" tab under all states
  (dropped from the tab row and tabOrder).
- Trade History rows: Time and Symbol are now single-line (date + time /
  symbol + side on one row); tightened row padding + row-gap.
- Add an "Executed Value" column (price x quantity, derived when the row
  doesn't supply it) between Quantity and Fee.
- Distribute the trade-history columns evenly (repeat(7, 1fr)).
- Buy/Sell side label inherits the standard cell font size/weight
  (dropped the 12px override) — matches the other sections.
- Replace the share icon with the brand share glyph, colored
  theme.colors.primary (#1FC7D4).
- Drop the row-hover highlight on the trade-history table (read as an odd
  partial band); other tabs keep it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants