Advisor Portal · Jul – Nov 2026

Advisor Portal — UI Fixes

Page-level design fixes across the advisor portal — book-of-business lists, Client 360 (overview, accounts, margin, meeting prep, Shariah), Portfolio 360, trading, bulk orders and opportunities. Every change is scoped to the advisor-portal app — no design-system (dionysus-ui) package changes.

16
Pages & areas polished
124
Fixes shipped
20
PRs merged
6
Fixes in review
0
Design-system changes

Pull request status

PRScopeStatus
#747 ↗ Clients list ✓ Merged27 Jul 2026
#752 ↗ Portfolios & Accounts lists ✓ Merged27 Jul 2026
#887 ↗ Client 360 — detail page ✓ Merged30 Jul 2026
#1758 ↗ Client 360 — Accounts tab ✓ Merged7 Oct 2026
#1777 ↗ Advisor Home — My tasks ✓ Merged7 Oct 2026
#1788 ↗ Portfolio 360 ✓ Merged8 Oct 2026
#1809 ↗ Client 360 — Margin (cash breakdown) ✓ Merged8 Oct 2026
#1807 ↗ Client 360 — Margin (cards) ✓ Merged9 Oct 2026
#1811 ↗ Client 360 — Margin (facility bar) ✓ Merged9 Oct 2026
#1825 ↗ Client 360 — Overview (Portfolios card) ✓ Merged9 Oct 2026
#1826 ↗ Tab strips — tenant colour ✓ Merged11 Oct 2026
#1868 ↗ Client 360 — Meeting briefing drawer ✓ Merged12 Oct 2026
#1882 ↗ Portfolio 360 — Overview ✓ Merged12 Oct 2026
#1885 ↗ Client 360 — Overview (metrics, facility tag) ✓ Merged12 Oct 2026
#1957 ↗ Trading — order hub & drawer ✓ Merged16 Oct 2026
#1964 ↗ Bulk orders — send button ✓ Merged19 Oct 2026
#1993 ↗ Bulk orders — portfolios table ✓ Merged22 Oct 2026
#2011 ↗ Bulk orders — security search ✓ Merged22 Oct 2026
#2039 ↗ Opportunities ✓ Merged27 Oct 2026
#2083 ↗ Client 360 — Zakat (first pass) ✓ Mergedinto the #2079 branch · 27 Oct 2026 — ships with #2099
#2079 ↗ Client 360 — Shariah purification ✓ Merged1 Nov 2026
#2099 ↗ Client 360 — Zakat ● Openin review · opened 28 Oct 2026

Advisor Home — My tasks card

FixDetail
Download control removedThe Home My tasks card passes hasExportControl={false}, so no download renders; the full Tasks page and the embedded client/account lists keep export (prop defaults to true).

Clients list

PR #747 ↗
FixDetail
Single-line headerswhitespace-nowrap — no header wraps to 2 lines
Client columnFixed 172px width with text-wrapping
Sort / info iconsNormalized to 16×16 box, 12×12 glyph, 8px gap to label
Tasks badge24×24 background
Grey task badgeNormal (non-red) counts get a grey badge, same 24×24; white on row hover
Assisted tag56×20, 10px font, turns white on row hover
Table fitTrimmed cell padding so the table fits with no horizontal scroll; symmetric left/right margins
Sticky headerz-index lifted above the row-actions icon
Overflow (⋯) menu14px items, fit-content width, symmetric spacing, offset tightened to the icon
TooltipPlacement moved to bottom
Text colorConfirmed text-secondary token for table text
SidebarLogo 16px start margin

Portfolios list

PR #752 ↗
FixDetail
Single-line headerswhitespace-nowrap
Sort / info icons16×16 box, 12×12 glyph, 8px gap (matches Clients)
Tasks tooltip dimmingRemoved sortField/sortDisabled so the info icon no longer inherits the sort button's 50% opacity
Overflow (⋯) menufit-content, 14px, symmetric spacing
Export / download controlRemoved
Filter toolbarLeft spacing aligned to Clients
Sticky headerz-index above body rows

Accounts list

PR #752 ↗
FixDetail
Single-line headerswhitespace-nowrap (without touching the horizontal scroll)
Sort / info icons16×16 box, 12×12 glyph, 8px gap
Overflow (⋯) menufit-content, 14px, symmetric spacing
Export / download controlRemoved
Filter toolbarLeft spacing aligned
★ Pinned actions column⋯ column stays fixed while the rest scrolls horizontally (dionysus sticky: "right")
Pinned column shadowSoft edge gradient following the common data-table pattern (Ant Design / TanStack / MUI), not a hard box-shadow
Sticky headerz-index above the pinned column

Client 360 — detail page

PR #887 ↗
FixDetail
Header tabs — full widthThe tab bar was inset and clipped ~12px on each side (shared HeaderTabs -mx-3 + overflow-x); expanded it to span the full content width, matching the header above it. Sticky-on-scroll preserved.
Tooltips — width & wrapInfo tooltips now hug their content (width: max-content) up to a 360px cap with text wrapping — short tooltips collapse to a single full line (no lonely trailing word / right-hand gap), long ones wrap. Were ~587px wide & unwrapped; follows shadcn / Radix / MUI guidance
Tooltips — z-indexRaised z-index 10 → 60 so tooltips sit above the sticky tab bar / adjacent cards (were rendering behind)
Client metrics — alignmentReserved two label lines so every value lands on one baseline (wrapping labels no longer stagger their values). Fonts & colours unchanged.
Client metrics — title gapBand keeps its left/right inset, but the extra 16px top margin was removed so the title-to-band gap now matches the standard cards (20px, same as Key metrics)
Client metrics — empty-chart spacingCollapsed the empty chart placeholder (:empty) so the gap below the band matches the 16px above; real charts keep their padding
Client metrics — vertical paddingAdded top & bottom padding inside the grey band so the metrics row isn't flush to the band edges (content sits ~14px off top/bottom)
Client metrics — dividerAligned the section divider to the inset band (was a full-width rule crossing under an inset band)
Client metrics — text sizeReduced label & value text −2px (16 → 14px) for a tighter row; colours unchanged
Key metrics — sub-row spacingSet the gap between each sub-metric label and its value to 8px (Unrealized / Realized P/L) — were pushed apart by justify-between
★ Quick actions — compact menuOverrode the fixed 240px list width so it hugs content (~176px) and shrank rows from 36 → 32px (16 → 14px text, tighter padding) to match the compact action menus elsewhere
★ Quick actions — chevron stateThe custom trigger's chevron was static; now rotates 180° when open (driven by aria-expanded, smooth transition), matching the other header dropdowns
Client info — value alignmentAn empty field value (e.g. no Client ID) collapsed to 0 height and pulled the whole value column up, so values no longer lined up with their labels. Reserve one line per value cell so every row stays aligned — robust to any empty field
Client info — balanced groupsThe two field groups were content-sized, so the left (short values) came out much narrower than the right (long email). Split the leftover width so the two halves read balanced
★ Copy button — click effectThe dionysus button's press-glow (::before inset -4px + 12px shadow) bloomed left over the email on click. Dropped the glow pseudo-elements (kept the active:scale feedback) and set an 8px gap to the icon
★ Header tabs — underlineNon-selected tabs each carried a grey underline and the row a grey baseline; removed both so only the active tab shows its indicator. Also removed a stray 1px vertical scrollbar on the tablist
Header tabs — active indicatorActive tab underline set to 3px teal (design-system text-text-subtle confirmed for the non-active labels)
★ Period dropdown — width & selectedList shipped a fixed 240px; now hugs content. The current value wasn't marked — the selected option is now highlighted (surface-selected tint)
★ Period dropdown — chevron & hoverChevron now rotates while open (all .button-dropdown triggers). Item hover paired a light background with white text (unreadable) — hover text is now dark; disabled options get no hover highlight
Key metrics — label / value gapAdded 8px between each metric label and its number (were flush) so they read as two distinct lines
Client metrics — tab labelsTightened the label leading (loose 24px → 20px) and wrap long titles onto two lines (e.g. "Total relationship / value"); short labels stay one line

Client 360 — Overview

FixDetailPR
Client metrics moved upThe Client metrics chart is now second, before the Portfolios card (which used to sit between the bridge and the trajectory).#1825
"See all" in the headerThe Portfolios card uses the overview card header (border-0 px-4 py-5) with the tab link beside the title — it was in the footer.#1825
Muted label bandHeaders alpheya-label-sm text-text-tertiary (12px) → alpheya-label-md on bg-surface-gray-subtle, matching the margin accounts table.#1825
Figures without monospacefont-mono 12px → alpheya-numerics-md tabular-nums.#1825
Footer at body sizetext-xs "Top 2 of 9 · See all" → alpheya-body-text-md "Top 2 of 9".#1825
Whole row clickableClicking anywhere on a row opens that portfolio through the number's own link — one navigation.#1825
Net assets in the titleThe single-tab ChartSelector is dropped; Net assets shows as a figure at the end of the card title in a subtle panel, with the value-history chart below.#1885
Failed read shows a dashA failed live read shows "–" (not 0) and hides the chart, with no error panel.#1885
Indicative tag right-alignedThe facility card's "indicative" tag moves to the inline-end of the heading row, opposite the title.#1885

Client 360 — Accounts tab

FixDetail
Download control removedThe Accounts tab no longer passes the table export prop; other Client 360 tabs and the Closed Accounts page keep export.
Column headers wrapColumn headers now wrap to two lines.
Valuation note as a calloutThe valuation note becomes an info-styled callout.
Filter row alignedThe filter row now aligns with the table.
Balance label copy"Account value/balance" → "Account balance" / "رصيد الحساب" (en + ar), wherever those labels render.

Client 360 — Margin tab

FixDetailPR
Header inset 32 → 16pxBoth cards share a new MarginCard wrapper with the Client 360 card chrome: header px-4 (was 32px), body p-4, the standard card title.#1807
Equal-height cardsThe grid uses items-stretch and the cards h-full, so both cards are the same height.#1807
Tinted hero panelHero rows sit on a LedgerHero panel (bg-surface-gray-subtle, rounded-lg); values alpheya-numerics-lg → alpheya-metrics-sm, labels alpheya-body-text-lg.#1807
Ledger rows 12px → bodyRows alpheya-body-text-sm/numerics-sm (12px) → alpheya-body-text-md/alpheya-numerics-md.#1807
Matching bar thicknessThe balance card's "Margin used" bar now matches the facility bar — it was half as thick.#1807
Breakdown open by defaultThe cash-account breakdown starts expanded and still folds on request.#1809
Scrolling tableA fixed 5-column table in 520px let amounts overlap; now an overflow-auto max-h-96 scroller with a w-full min-w-max table and no-wrap cells, scrolling on both axes.#1809
Sticky headerSticky top, bg-surface-gray-subtle, label-md, 40px tall.#1809
Pinned account columnThe account cell (number over type) stays pinned at inline-start while scrolling.#1809
Right-aligned numericsCells use numerics-md, px-4 py-3 and hairline dividers; rows measure 53px.#1809
Sticky total rowThe tfoot is sticky at the bottom, medium weight on bg-background, repeating the card totals.#1809
Segment tooltip on hoverEach facility bar band shows label, amount and share of drawing power — e.g. "Drawn / $32,000,000.00 · 15.20%".#1811
Indicative bar tooltipWith no active facility, the single bar reads "Drawing power / $210,470,000.00 · 34.34%".#1811
Bar stops clippingThe container no longer clips the tooltip; first and last bands round their own ends; height and colours unchanged.#1811
Zero-share bands hiddenA band is not drawn when its share is 0 or rounds to 0.00%.#1811

Client 360 — Meeting briefing drawer

FixDetail
Drawer title weightalpheya-headline-sm font-normal 24/28 light → alpheya-title-lg 24/28 medium.
Section titles 12 → 16pxSection titles and the loading/timeout/empty headings: body-text-sm font-bold 12/16 → alpheya-title-md 16/24.
Body copy 12 → 14pxSnapshot, bullets, talking points, descriptions and error rows: body-text-sm 12/16 → body-text-md 14/20.
Internal-note calloutText 12 → 14px, padding 12 → 16px; the warning icon changes from dark to text-text-error red.
Field labelsalpheya-body-text-sm → alpheya-label-md.
Hints 10 → 12pxHints, date errors and the window caption: body-text-xs 10/14 → body-text-sm 12/16; all spacing now on the DS 4px grid.

Client 360 — Shariah purification

FixDetail
One summary cardFour bordered KPI tiles → one CardV2: the lead purification amount plus three divided rows (needing attention, awaiting approval, paid to charity).
DS stacked bar chartStackedBarChartNew replaces the axis-less hand-built chart — 0–1,200 axis, gridlines, Jan–Sep labels, Paid/Approved/Calculated/Pending legend; the tooltip shows each status plus the month total.
Line tabs for the view switchPill SegmentedControls → TabsV2 variant="line" (Distribution events / By holding).
Filter chips with dotsThe "(count)" buttons become ButtonV2 chips with a series dot and count, e.g. "Calculated 2".
Status badges with dotsBadgeV2 with a leading series-coloured dot.
Sample-data note softenedThe bold outline "Illustrative sample data" badge becomes a subtle Info-icon note.
Tokens + one-line headerThe dead alpheya-body-sm class is replaced with alpheya-body-text-*, alpheya-numerics-* and data-visualisation-* tokens; "Gross received" stays on one line.

Client 360 — Zakat

FixDetail
Zakat-due calculation cardOne CardV2 leads with the Zakat-due amount and an Estimate dot badge (the left column used to lead with the hawl date).
Vertical waterfallzakatable → − liabilities → = net base → × rate, with operator chips (was horizontal).
Hawl progress barAt the card foot with a bg-interaction-color-primary-bg fill.
Supporting cardsConsolidation (accounts + declared external assets), the breakdown and the Zakat history each sit in their own CardV2, with CheckboxV2 inclusion rows.
Tables on DS DataTableBreakdown and history (previously a raw <table>) use the DS DataTable with one-line headers.
Status dot badgesBadgeV2 dots — Estimate → data-visualisation-orange-02, Paid → data-visualisation-green; dead alpheya-body-sm/xs → alpheya-body-text-sm/xs.

Portfolio 360

FixDetailPR
Tab strip to the page edgeRuns to the inline-end page edge (RTL-safe -me-6); the first tab stays aligned with the content and the white band is gone.#1788
Accounts widget — no downloadDownload control removed from the Overview Accounts widget.#1788
Accounts widget — single scrollNested card-body and table-wrapper scrollbars collapse into one vertical scroll.#1788
Bridge operators inline+/−/= sit inline on the figure baseline with tight spacing (were separate centred items ~12px away).#1788
Bridge row paddingFigure row padding py-4 → py-8.#1788
Allocation card tidyDownload removed; the drift figure is text-text-secondary (was the blue data-viz colour); value column right-aligned.#1788
Portfolio history as a standard cardThe live net value becomes a figure on the period-selector row instead of a tab; the two stacked plots share one width.#1882
Period pill in tenant colourThe selected period pill uses the tenant primary — a shared selector, so history, income & expense and P&L breakdown all follow.#1882
Income & expense hero tilesTwo side-by-side hero figures on subtle tiles; the trading-fees row loses its leading accent border.#1882
Header dividers restoredIncome & expense and Key metrics get the DS header divider back (opt-in showHeaderDivider).#1882
Relevant news spacingControls sit below the header with standard p-4 spacing.#1882
Top 5 holdings typeUses the DS type scale, with "See all" in the card footer.#1882
Allocation after Top 5The Holdings allocation card is ordered directly after Top 5 holdings.#1882

Trading — order hub & order drawer

FixDetail
Create order icon, centredA leading Plus icon (h-4 w-4) matches the Order-book CTA; the button is centred in the header.
Hub margins match the gutterp-4 space-y-6 → space-y-6, so the cards align to the dashboard gutter.
Download controls removedAccounts, Holdings, Recent Orders and the drawer's Executions tables drop export.
Hover only on clickable rowsRow hover removed from Accounts and Holdings; kept on Recent Orders, whose rows open the drawer.
Recent Orders ID & headersThe Order ID sits flush-left (OMS live-status indicator dropped); headers use whitespace-nowrap.
Drawer Order ID sizealpheya-body-text-lg → alpheya-body-text-sm (12px caption).
Reference-code card on one lineLabel, code and copy control sit in one wrapping row — shared, so every error panel and the error modal follow.
FixDetailPR
Send button copy"Send block order" → "Send bulk order", matching the "Bulk order" title and the Arabic.#1964
Header matches DS DataTablealpheya-label-md text-text-secondary px-4 py-3 → bg-muted (#F2F6F9) alpheya-label-lg text-foreground p-3 h-12 (48px).#1993
Rows 56px, middle-alignedpx-4 py-3 align-top → p-3 h-14 (56px), aligned to the middle.#1993
Row dividersborder-separate + border-t border-border-subtle → border-collapse + border-b border-border.#1993
Numeric figurestabular-nums → alpheya-numerics-md.#1993
Search dropdown overlays the fieldThe panel is now absolute inset-x-0 top-full z-30 w-full — the old in-flow w-3/4 min-w-[424px] reflowed the filter bar and spilled over the Side control; the order-ticket modal is unchanged.#2011

Opportunities

FixDetail
Long references truncateLong reference numbers (e.g. portfolio_<uuid>) truncate to one line in the table and the drawer via the shared OpportunityReferenceNumber — they used to overflow and wrap.
Full value on hoverA native title shows the full value; a missing reference shows the empty-state placeholder.
Linked-to cell constrainedmin-w-0 keeps content inside the column; short KFH-UHNW-* ids show in full.
Co-owner count stays visible(+N) sits in its own non-shrinking span when a long primary name truncates, and is added to the hover title.

Tab strips — portal-wide

FixDetail
Selected tab in tenant colourThe selected-tab underline uses the tenant's primary interaction colour instead of DS teal — tab bottom border, status-strip underline and the TabsV2 indicator.
3:1 contrast fallbackUses the first of primary/hover/pressed with ≥3:1 on white and on the page background — KFH primary #AA9F8C (2.61:1) yields to hover #887F70 (3.95:1).
DS default when none passTenants with no primary, or all shades below 3:1, keep the DS underline; focus rings, the progress bar and the spinner keep the DS highlight.

Generated for Alpheya · Advisor Portal · updated 2 Nov 2026