Conversation
…e transition Phase 1 of a unified overlay motion system. A shared ScaleFade transition (opacity 0→1 + scale 0.96→1, modeled on MUI's Grow) is wired as the default TransitionComponent for MuiMenu and MuiPopover at 100ms, so all menus, selects and popovers pop consistently instead of using MUI's default Grow. Timing lives in a single motion-tokens module. - src/utils/motion.ts: central duration/easing tokens (single source of truth) - ScaleFade: MUI-compatible transition primitive (scale 0.96, not Grow's 0.75) - theme: MuiMenu/MuiPopover transition defaults + global prefers-reduced-motion - showcase: Select/Menu specimens in the Overlays section Modals and drawers are intentionally untouched (deferred to later phases).
The outlined variant sets border:none at rest, but its :hover block only changed background + re-asserted the box-shadow ring, so MUI's built-in .MuiButton-outlinedPrimary:hover border leaked through on hover only. Force border:none in the hover/focus block so the borderless pill stays borderless.
…radients - figmaColors.ts: single source of truth for color tokens + the figVars var() accessor. - theme.tsx: flatten tokens onto the MUI CssVars palette (P3 + sRGB fallback); emit P3 vars. - colorToP3.ts: Display-P3 conversion for the @supports P3 override layer. - gradients slot/type removed; the new branding uses the solid purple-1 token.
Sweep explicit color reads onto flattened figma tokens (bare sx strings / figVars) for P3. Also swaps the brand gradient for the solid purple-1 token in the affected components.
Same token sweep across module components for Display-P3 with sRGB fallback. Swaps the brand gradient for purple-1 in the E-Mode button, StakeActionBox and version badge.
Token sweep across layouts; swaps the newGradient banner for purple-1 in TopBarNotify.
Buttons, icon and toggle buttons scale to 0.99 on :active (not disabled) via a shared fragment. MarketSwitcher's custom Box trigger gets the same press feedback inline.
DotsHorizontalIcon: currentColor meatball icon replacing the '...' text supply dropdown. iconButtonSx (buttonStyles.ts): square icon-only button styling (min-width 0, 0.25rem pad). Desktop table action buttons across the four dashboard lists set to size=small.
|
The Collateral / Borrowable rows on the reserve-overview page painted their icon from a palette slot and their label from a hardcoded hex, so the two halves of each status came from different sources and did not match. Both now take data-green when enabled and data-red when disabled. The icons' `color="success"` / `color="error"` props are dropped rather than left under the new sx, which would have given each icon two colour sources with sx silently winning. These are SvgIcon components, so the token resolves as CSS. Unlike the hexes they replace, the tokens carry dark-mode values: the red softens to #E05269 and the green to #66C399 on the dark card. The warning branch — the amber icon shown for a 0% LTV asset — is untouched and still pairs `color="warning"` with a hardcoded #E8A838.
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
The alerts under the dashboard asset cards — "To borrow you need to supply any asset as collateral", the isolation-mode and e-mode warnings, the health-factor error — sat in a px:6 box, so they were inset 24px from the edges of the card they sit beneath. They already carry width: 100%, so dropping the padding is enough to line them up. The supply card had the byte-identical wrapper. These two are structural twins that render next to each other, so fixing only the one that was reported would have left them visibly mismatched. ListWrapper's below-card slot also rendered at mt: 3 (12px); it is 1rem now. That slot is shared with SuppliedPositionsList, which already wrapped its content without padding and was correct.
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
"Stake {symbol}" was h4 (16/600) while the markets and dashboard tables use
subheader1 (14/600) for the asset name — the same 2px discrepancy the markets
row itself carried before it was aligned to the dashboard. All three tables now
agree.
StakeAssetName is shared, so this covers the desktop table, the mobile item and
the disconnected view at once.
The line below it — "Total staked: $X" — still differs: caption (12/400, fg-2)
against the markets sub-line's subheader2 (12/500, fg-3). Same size, so it is a
weight step and a shade rather than a size jump, and the two carry different
content, so it is left for a separate call.
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
Nested rows and staking panels move from border-2/surface-elevated to border-0/bg-2, keeping them on the warm dark ramp rather than surface-elevated's cooler #1E1E20. SavingsCardSkeleton follows, so the sGho/stkGho rows no longer pop tokens when data lands. DarkTooltip drops its hardcoded rgba(15, 18, 29, 0.8) for the scrim token behind a backdrop blur, and takes ContentWithTooltip's radius, inset hairline and shadow so the two tooltip flavours read as one component. It follows the colour scheme now instead of being fixed dark, so the name is a misnomer. The swap token picker uses TxModalTitle for its header, a uniform 1rem rhythm between header, search, Popular and list, no divider, and a scroll container that lets the scrollbar ride the modal's inner edge while rows stay level with the search input. Bridge GHO's title uses the same component. Also: 8px label-to-field gaps in AssetInput, TxModalDetails and BridgeDestinationInput; data-size="small" on the cap and debt-ceiling warnings; Paper variant="card" on the governance panels; outlined buttons with buttonM labels for e-mode and governance links; "Back" in the language submenu; a 40px markets footer band with an inset divider; and a dimmed border on the disabled swap-direction button, which no longer had the removed opacity fading it.
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
The header band was the only one of the two stacked bands still on bg-2 in dark; PageHeader/pageBandSx already used bg-1. They now share one surface, with the inset border-0 hairline separating them instead of a fill step. Light mode was already consistent at bg-3. The V4, Swap, Bridge GHO, wallet and settings triggers move from the tertiary pill to the secondary one, which the theme spells variant="outlined" (secondaryPillStyle, theme.tsx:640) — there is no variant="secondary". Dark-mode only: the fill drops from bg-4 to bg-3 and the hover tint softens, so the pills keep a clear step against the now-darker band. This continues the move started in DashboardEModeButton and GovernanceTopPanel. The TESTNET/FORK badges and the disable-testnet/disable-fork buttons stay tertiary — status indicators and popover actions rather than nav chrome.
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
The proposal page's cards take the reserve-overview padding recipe, which fixes a bottom pad (16px) that sat tighter than the sides (24px) and adds the mobile step-down the reference has. That recipe was already written out nine times repo-wide, so it moves to cardPaddingSx alongside the existing buttonStyles/pageBandSx consts rather than into the card variant — several cards pad an inner Box and would double up. Sidebar card spacing moves off six copies of mb: 2.5 (10px) onto one 16px gap on the column, matching UserGovernanceInfo, which also drops the stray margin below the last card and the phantom gaps when a card renders null. The back-button strip is now just the button at py: 6, replacing a full page band that also rendered an empty PageTitle: five media queries and five store subscriptions for a header with one control. ContentContainer gains disableTopPadding so the strip owns the whole 1.5rem to the content; both ProposalTopPanel consumers pass it. Trailing action columns right-align via ListColumn's own align prop — markets, faucet, bridge, history and staking, with their loaders so the control doesn't jump when data lands. The dashboard lists already did this through ListButtonsColumn. StakingDropdown takes fullWidth as a prop instead of re-deriving its caller's card breakpoint. Its two callers are mutually exclusive on that exact breakpoint, so the copy could silently disagree with the table — and did, leaving the stake button full-width inside the desktop table between 1125px and 1280px. Also: the GHO about-panel links and the governance header links share one ExternalLinkButton; the governance title matches the other core pages at h2/30px medium; the search field keeps its outline stroke without the drop shadow; and ReserveConfigurationWrapper expresses its responsive padding in sx rather than a media-query hook.
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
The funkit checkout was still on the fun team's stock customer palette — blue-grey #2A2E40 surfaces and #A5A8B5 ink on a bg-1 page, with flat 4px radii and a pinned SF-Pro stack. Every colour now resolves from the Figma tokens, radii follow the app's scale, and the type comes from the app's FONT and its size/line-height pairs, so the modal title matches TxModalTitle. The two mirrored ~45-key palettes collapse into one buildColors(mode, overrides): they differed in seven values, and writing them twice had already let generalBorder and inputBorderHover be set in dark only. Nested surfaces on the sGHO and staking pages drop their background instead of restating it. The wrapping Paper variant="card" already paints surface-elevated/bg-2, so the inner boxes only needed to stop painting bg-2 over it — which they did in dark by coincidence and not in light. StakeActionBox keeps an explicit fill, where it masks its own :after ring, and the two staking panels get their mobile no-fill back. Card headers share one 36px band: cardHeadingSx across the eight governance panels and the same constant in ListWrapper, whose dashboard headers were collapsing to the title's line height when there was nothing to hide. minHeight rather than height, so a longer localised heading grows instead of overflowing. The reserve header clips long asset names with a tooltip for the full string, and its stats hold one row rather than wrapping under the token block. Its icon and name stop being components declared during render, which was remounting them — and the new tooltip with them — on every poll. Also: the proposal page's share icons all take fg-3 (Lens painted a palette branch into an SVG fill attribute, so it now inherits currentColor); the Edit address modal follows Bridge/Swap spacing and no longer reserves a hidden error line per row; and the e-mode ring's interior moves to bg-3, the outlined variant's own fill.
Test Mode replaces the magenta TESTNET pill with a teal label after a 1px separator, opening a standard Menu with a single Disable testnet option instead of a tooltip you had to click twice to dismiss. Its ink is an inline exact-P3 pair rather than a token: colorToP3 remaps channels naively, which would turn Figma's 0.1686 0.6784 0.6431 into a visibly different colour. Dark is sRGB-only until we have its P3 value. With an env badge enabled the header runs out of room, so the action triggers stay icon-only and the mobile handover moves up a breakpoint. That threshold now lives in headerBreakpoints so NavItems branches on the same value — it was still reading mdlg, which rendered the desktop nav row inside the drawer between 1125px and 1280px. Mobile fit: the wordmark gives way to the face mark below xsm (both share one path set), V4 moves into the drawer, and the wallet button shortens its label. Note the connected name is unchanged — UserNameText only compacts an ENS name past 18 characters, so CompactMode can't tighten it; the logo is what buys the room back. Table dashes default to fg-4 on NoData itself, dropping the per-cell colour from nine call sites. The two that need their container's ink say so with `inherit`. The default is applied after the prop spread, since IncentivesCard forwards a possibly-undefined colour. Also: table token icons 40px with their skeletons in step, page-header descriptions on the description variant (400, not h5's 500), inter-input direction arrows fg-3, and the market picker fades its title, logo, badge and chevron together on hover.
The tab icon was still the pre-uplift Aave logo, in one static .ico, so it disagreed with the rebrand in every scheme. It now switches in three layers. favicon.svg carries its own prefers-color-scheme block and is what renders before hydration and with JS off; FaviconSwitcher then repoints that link at favicon-light.svg or favicon-dark.svg once the scheme resolves, so the tab follows the app's own toggle rather than the OS. The two disagree whenever someone overrides `system`, which is exactly the case a CSS-only favicon gets wrong. It resolves 'system' through systemMode the same way DarkModeSwitcher does, and no-ops while the mode is still undefined, leaving the self-switching file in place — otherwise a dark-OS user gets a light flash on every load. The combined file keeps its light and non-P3 colours on fill attributes and puts only the dark and @supports P3 overrides in <style>. Written the obvious way — base rules in the stylesheet — svgo's inlineStyles pass hoists them into a style attribute and strips the classes, which both kills the @media selectors and outranks them. That pass runs on every commit through lint-staged, so the icon would have frozen in light mode without ever failing a check. All three SVGs carry Figma's exact P3 values with an sRGB fallback. Rasters come off the same art: the browser icons keep the rounded tile's transparent corners, while apple-touch-icon and the manifest sizes are opaque squares, since iOS and Android apply their own corner mask and would otherwise plate the transparency. favicon.ico is rebuilt at 16/32/48 from the dark tile — it can't be scheme-aware, and that reads better against default light browser chrome — so Safari no longer shows the old logo while Chrome shows the new one. manifest.json pointed at favicon32.png, which has never existed in this repo, and start_url at ./index.html, which 404s on an installed PWA. Both now point at real files. theme_color moves off #1B2030, a pre-uplift value, onto bg-1 per scheme, matching the two theme-color metas that replace the single stale one in _document.
…king The market picker's popover anchored to the whole trigger Box, which is a column containing the title row *and* the market blurb, so its bottom edge moved with the copy. Only three of twenty-six markets have a blurb, and the mt: -1rem offset was cancelling part of that gap — so on every other market the panel opened 16px *above* the row and covered the title it belongs to. Turning on test mode switches to a testnet market, which is how this surfaced, but Base or Avalanche on mainnet reproduce it identically. It now anchors to a ref on the title row, so the offset is the same for all twenty-six. The same variable height moved the whole header band. PageHeader bottom-aligned both columns, so whichever was taller pinned the other: with a blurb the title sat at the top and the stats dropped 19px; without one the stats sat at the top and the title dropped 17px — a 36px swing between markets. flex-end now lives on the stats column via alignSelf, which states the actual rule (only the stats want a bottom baseline) and leaves the title where a page title belongs. Rendering is unchanged wherever the title column is the taller one, which is all five consumers today. Staking silently did nothing in test mode. The page pins the market to Core, but setCurrentMarket early-returns for anything outside availableMarkets, which test mode filters to testnets — so the pin was a no-op and the page ran against a market with no umbrella config, landing on "no stake assets configured" after a long wait. usePinnedMarket now reports whether the pin could take, and the page says so instead. safety-module has the same call and still ignores it. Its loading state also returned before the column header and padded the gap with a bare 44px box, which read as an empty table with divider lines. Both umbrella lists now keep the header up during loading, like the faucet table already did. Two new tokens. border-opaque (#e5e6e6 / #262626) is the swap and bridge switch button's ring: the alpha border-2 composited to #39393b over the button's dark fill, far louder than the design. Its fill moves from surface-elevated to bg-2 — the same token the inputs it sits between use, so it stops reading as a cooler, lighter chip on the seam in dark mode; hover steps to bg-3 rather than bg-2, which is now the base. overlay-hover (8% black / 8% white) is the governance Connect button and the Test Mode label, both of which previously fell through to MUI's 2.5% action.hover and disappeared into the surface. Both go through the shared hoverOverlay recipe, which tints the existing fill instead of replacing it and brings focus-visible and open-state coverage with it. Full-width tables go to a 20px gutter — markets, umbrella and faucet, header and rows and skeletons together so the columns stay under their headings. The faucet description drops a hardcoded #A5A8B6 for fg-3 and a fixed responsive width for a maxWidth, matching governance, which in turn picks up the description variant it was missing. Reserve token dropdown rows move to ListItemText so they inherit the theme's 14px/400 menu text instead of restating semibold subheader1, with a 16px icon at a 10px gutter. The market picker's hover fade narrows to the label alone — the logo, version badge and chevron no longer dim with it.
# Conflicts: # src/locales/el/messages.js # src/locales/en/messages.js # src/locales/en/messages.po # src/locales/es/messages.js # src/locales/fr/messages.js
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖
|
| Page | Size (compressed) |
|---|---|
global |
1.34 MB (🟡 +13.89 KB) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
Sixteen Pages Changed Size
The following pages changed size from the code in this PR compared to its base branch:
| Page | Size (compressed) | First Load |
|---|---|---|
/ |
91.41 KB (🟢 -4.63 KB) |
1.43 MB |
/404 |
2.11 KB (🟢 -742 B) |
1.34 MB |
/500 |
2.44 KB (🟢 -744 B) |
1.34 MB |
/bridge |
37.8 KB (🟡 +68 B) |
1.37 MB |
/dashboard |
81.25 KB (🟢 -4.36 KB) |
1.42 MB |
/faucet |
11.17 KB (🟢 -3.88 KB) |
1.35 MB |
/governance |
42.41 KB (🟢 -546 B) |
1.38 MB |
/governance/ipfs-preview |
99.21 KB (🟢 -2.45 KB) |
1.43 MB |
/governance/v3/proposal |
85.42 KB (🟢 -3.37 KB) |
1.42 MB |
/history |
32.55 KB (🟢 -3.78 KB) |
1.37 MB |
/markets |
52.75 KB (🟢 -2.17 KB) |
1.39 MB |
/reserve-overview |
38.57 KB (🟢 -1.29 KB) |
1.37 MB |
/safety-module |
54.85 KB (🟢 -1.63 KB) |
1.39 MB |
/sgho |
92.01 KB (🟢 -1.01 KB) |
1.43 MB |
/staking |
31.19 KB (🟢 -2.3 KB) |
1.37 MB |
/v3-migration |
48.08 KB (🟢 -4.59 KB) |
1.38 MB |
Details
Only the gzipped size is provided here based on an expert tip.
First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this.
…recipes Mobile styling was written as overrides rather than as responsive CSS: 70 useMediaQuery call sites, ~20 duplicate *Mobile* components restating padding and typography by hand, and per-page constants forking the theme. The same rule was often written two to eight times, and the copies had drifted. Typography leads the sweep. `downToSM ? 'h4' : 'h2'` was re-derived in eight files — UmbrellaHeader had baked 'h4' | 'h2' into a public prop type and SGhoHeader derived an icon size off the result — and the page title was derived twice, once in PageTitle and once in MarketSwitcher, for the same rendered row. Those become three theme variants, statValue, statValueNoData and pageTitle, composed from the existing pairs so a retune of h2/h4 carries through, with the breakpoints read off the built theme rather than hardcoded. Nine components drop matchMedia entirely; the count goes 70 to 50. Named breakpoints replace the spellings. LIST_CARDS_BELOW and TABLE_CARDS_BELOW cover seventeen call sites, including three that wrote down(1125) — which is mdlg, so a retune would have moved half the tables. HEADER_COLLAPSE_BELOW and HEADER_HEIGHT join HEADER_MOBILE_BELOW, and the height stops being prop-drilled through MobileMenu into DrawerWrapper. Repeated sx becomes recipes: depositRowActionSx, stakePanelActionSx and panelStatLabelSx cover fourteen sites, and cardPaddingSx picks up four more, including the skeleton that stands in for the two staking panels. Four fixes are not styling. MigrationListMobileItem painted a literal 'white' where its desktop twin uses surface-elevated, so those buttons were wrong in dark mode. Mobile history never sorted its date groups. Mobile migration never rendered the isolation-mode warning that tells you some assets will not be used as collateral — now one shared component instead of a second copy. And DashboardContentNoData's `sxm` key silently dropped its own value. Staking was broken in test mode: the page pins the market to Core, but setCurrentMarket early-returns for anything outside availableMarkets, which test mode filters to testnets, so the pin was a silent no-op and the page ran against a market with no umbrella config. It now says so. Its loading state also returned before the column header and padded the gap with a bare 44px box; both umbrella lists keep the header up while loading, like faucet. Loaders match the rows they stand in for — faucet and history were out by 8px and 12px — and the two that differed only by a dropped column collapse behind a `compact` prop. Mobile cards stop drawing a leading divider under ListWrapper's own hairline, which also retires two container-level copies of that rule. Dead code goes: SupplyAssetsListMobileItem, StakingMenu's mobile branch, MarketSwitcher's hideTitleChrome and titlePrefix, and a spacer Box in two top panels that had width but no height. Also: dashboard list headers stop truncating their last column, which can size to its label and spill into the empty actions cell beside it; "Wallet balance" becomes "Balance"; full-width tables go to a 20px gutter; and the app shell and modal move to 100dvh, matching the drawer.
… governance Designer review of the mobile layouts. Most of these are one rule each; the two button ones had causes worth recording. Supply and Details sat at different heights in the dashboard's mobile rows because FunSupplyButton hardcodes size="small" (28px) while its Details sibling takes the default medium (36px). Its prop spread already allowed an override, so the mobile call site passes size="medium"; desktop keeps small. The safety module's Claim and Restake were not a size problem at all — both resolve to sizeMedium, which is 36px. Their container was a column on mobile, and `flex: 1` there sets flex-basis on the *vertical* axis, overriding the height and collapsing them. They share a row at every width now, so plain `flex: 1` is right again. GhoStakingPanel has a single Claim button, so its wrapper Box was undoing a stretch it caused itself — the box goes and the button takes `fullWidth`. ListWrapper's heading row now wraps. The E-Mode control used to stack under the title below xsm; it sits beside the title, and when the card also has a Hide button it takes a right-aligned line of its own. That needs title, subtitle and button to be siblings in one formatting context, so the subtitle moved out of the title box and sorts with a single responsive `order`. The category filter was rendered twice — in the header on desktop and again under the list on mobile. One instance in the header at every width. Because `showCards` is false during SSR and flips after hydration, the old pair also unmounted and remounted across every mobile dashboard load, firing a spurious setSelectedCategories([]) per list. The sGHO markets banner double-counted its spacing (a 3rem parent gap plus its own mt) and its coin graphic was deliberately overhung with top: -8, so it clipped on a narrow card. Dropping it from the mobile variant also stops a 99KB PNG being fetched on mobile, since the element is created after the mobile early return. Also: the market sheet loses its close button — the drag handle already reads as the affordance, and both onClose paths still work — and its search ring, which only showed as two stray rules at full-bleed width; the Hide button drops its icon on mobile; the sGHO and stkGHO deposit rows give their actions their own line; StakeAssetName gets its row container back, since it returns a bare fragment; and assorted gaps move to the values the designer named. Three sx recipes come out of the repeated blocks: depositRowSx and depositRowActionsSx join depositRowActionSx for the two deposit-row twins, which had drifted again in this very pass.
Add a hover state to the governance proposal rows. Nothing in the palette was 4% in both modes (button-hover-tertiary is 4% light but 6% dark), so add an overlay-hover-subtle pair. The row has no fill of its own, so it composites straight over table-bg via bgcolor rather than needing hoverOverlay's ::before layer. The table Paper gains overflow: hidden — the last row is flush with its bottom edge and the Paper is 10px radius with no clipping, so the fill (and the pre-existing last-row border) would otherwise paint past the rounded corner. Recentre the modal close button. 8261c8c bumped the icon 24px -> 30px but left the inset at ~24px, so the X has been 2.5px below the title line in every modal since: Paper p:6 plus TxModalTitle's 1.5rem line puts the header centre at 36px, while the icon box sat 23.5-53.5, centre 38.5. top: 21px (24 + 12 - 15) restores the centring the 24px icon had. Also collapse the zero-size absolute Box wrapping an absolute IconButton — right: 54px only landed on the 24px gutter because the child happened to be 30px wide; right: 24px is the same position stated directly. Replace the Test Mode button's background hover with a colour step, so it reads like the neighbouring header links: darker in light, lighter in dark. green-1/green-3 from the existing ramp, at 100ms. The chip geometry goes with the fill; px and its cancelling mx came out together, so the resting layout is unchanged. aria-expanded takes the hover colour too, keeping the state hoverOverlay was providing while the menu is open. The resting teal stays a local hex + @supports pair rather than becoming a token, because colorToP3 derives P3 naively and would replace Figma's exact 0.1686 0.6784 0.6431 with 0 0.702 0.651.
No description provided.