Brings the merged Link component work (PR #3868) plus panelstack and
carousel fixes onto the new Button system.
Conflict resolutions:
- about/{index,history,impact}.page.tsx: keep both branches' imports;
/about CTAs use the new Button; Link component retained for the
inline validators links and FAQ markup.
- StandardCard: link color moves to $black/$lilac-500. Required, not
cosmetic: the branch's $bds-btn-neutral-black no longer exists after
the Button token system was replaced by $bds-btn-palette.
- Compiled CSS regenerated via npm run build-css rather than resolved
by hand.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* BDS component polish: link visibility, static cards, uniform CTAs
Component-level fixes and refinements across the 2026 brand components.
Accessibility / contrast
- StandardCard: pin description link colors. Every card variant has a light
background in both themes, so theme-level link colors were wrong inside it —
dark mode painted plain anchors white and BdsLink lilac-300, both of which
wash out on a pale card. Links (including :visited) now use the card's own
text color with an underline carrying the affordance; hover uses lilac-500,
which clears 4.5:1 on all four card backgrounds.
- Breadcrumbs: point the open dropdown menu at the breadcrumb color tokens so
the trail, trigger, and menu read as one color in both themes, and give dark
mode gray-6 (7.41:1, matching light mode's 7.23:1).
Interaction
- CardOffgrid: drop every hover affordance when a card has neither href nor
onClick. Static cards no longer get a pointer cursor, the color-wipe overlay,
or a pressed state — the tokenization and trading carousels pass link-less
cards and were advertising a click target that did not exist.
- CarouselFeatured: add a 'fade' transition alongside the default 'slide', for
decks whose slides share a heading. Inactive slides are now inert, keeping
focus and pointer events out of them in both styles.
- Add a bds-reduced-motion mixin so components can collapse motion to an
instant state change.
Design consistency
- ButtonGroup: add forceVariant and forceNoPadding overrides, letting a section
opt out of the count-based variant defaults and render one uniform treatment.
Existing consumers are unaffected.
- FeatureTwoColumn: render every link as a tertiary button regardless of count,
flush with the title and description.
- CardImage: render an all-bullet subtitle as a real <ul> so wrapped text hangs
under the first character and screen readers announce it as a list.
- docs: give the node-installation card descriptions a paragraph break before
their "Learn More" link.
Dependencies
- Bump @codemirror/state and view, add lang-javascript, lang-json, and lint,
with overrides pinning state/view to one copy.
Docs updated alongside each component. Built CSS regenerated with the
production script to match the committed artifact's minified format.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* ButtonGroup: don't strip padding from forced filled variants
`noPadding` was derived as `forceNoPadding || isMultiButton`, which was safe
while the 3+ block layout was always tertiary. `forceVariant` also accepts
`primary` and `secondary`, so a 3-button group forcing a filled variant had
`padding: 0 !important` (Button.scss) applied with no way to opt out.
Tie the implied no-padding to the resolved variant being tertiary. Behavior is
unchanged for every caller that doesn't pass `forceVariant`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Stacked hero variant, fade-by-default carousel, component docs
Layout
- HeaderHeroPrimaryMedia: add a `stacked` prop that puts the headline, subtitle,
and buttons in one column (full width at base, 7/8 at md, 9/12 at lg) instead
of the default headline-left / CTA-right split. The headline and CTA block
bottom-align against each other in the two-column layout, so the stacked
variant undoes that. Both arrangements now share the same headline and CTA
elements, so they can't drift apart. Used on the docs landing hero.
Motion
- CarouselFeatured: make `fade` the default transition. Slides that share a
heading are the common case, and a horizontal wipe drags the identical heading
across the screen only to set it back down. `slide` is now opt-in for decks
whose panels are genuinely distinct. Nudge the crossfade to 260ms in / 200ms
out. The home page carousel opts into fade explicitly; developer-funding now
inherits it.
Fixes
- CardTextIconCard: pass `headingAs` through to `cardContent`, which was
accepting the prop but never receiving it.
Docs
- Expand the Button, CardImage, CardTextIcon, PageGrid, CalloutMediaBanner,
LogoSquareGrid, and HeaderHeroPrimaryMedia references.
Built CSS regenerated with the production script.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brings 342 commits of master (last merge base 2026-06-09) onto the rebrand
branch. 10 files conflicted; resolutions below.
Regenerated rather than merged (both are build artifacts):
static/css/devportal2024-v1.css rebuilt via `npm run build-css` (+ .css.map,
which both branches track)
package-lock.json seeded from master, `npm install`
Config/nav:
.gitignore union of both sides
redirects.yaml took master's side: ambassadors.html now points at
ripple.com/impact/ubri/ (supersedes the branch's interim
redirect to /community/developer-funding) and master's
rippled->xrpld redirect block is preserved
redocly.yaml union of ignore entries (branch showcase/** + master
.claude/**); kept the branch's script ordering/defer flags
but adopted MASTER's new Osano CMP URL - taking the branch
side wholesale would have silently reverted cookie consent
top-nav.yaml kept the branch's restructure; master's only changes there
were the TypeScript get-started entry (auto-merged, retained)
and removing Ambassadors (branch already omits it)
Pages/styles:
docs/index.page.tsx, community/index.page.tsx,
community/developer-funding.page.tsx, styles/_docs-landing.scss
kept the branch rewrites, then re-applied master's intent:
"rippled API" -> "xrpld API" in docs/index.page.tsx. Master's
other edits (validator link rename, funding-orange image
removal, .nav-link hover underline removal) were already
satisfied by the rewrites.
Semantic conflict git did not flag:
styles/_tutorials.scss auto-merged cleanly but broke the SCSS build. Master
added light-mode .tutorial-tabs rules using $blue-purple-600/700, which the
rebrand's token consolidation removed (scale now stops at 500, aliased to
$lilac-*). Remapped to $blue-purple-500, matching how the rebrand migrated
the other light-mode $blue-purple-600 usages in the same file.
Verified: `npm run build-css` succeeds; no conflict markers remain; the set of
files still linking to master's renamed rippled-* doc paths is identical to
master's own (49 files, all historical blog posts covered by redirects).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The amendment unifies freeze and deep freeze checks across the six
transactions that move funds to or from a pseudo-account, so the existing
error descriptions on those pages become inaccurate once it activates.
- VaultWithdraw, VaultDeposit: rewrite tecFROZEN and tecLOCKED, and note
the issuer-destination and self-withdrawal cases
- AMMWithdraw, AMMDeposit: describe which accounts and assets are checked
- LoanBrokerCoverWithdraw, LoanBrokerCoverDeposit: add tecFROZEN and
tecLOCKED rows, and drop the incorrect claim that a freeze produces
tecINSUFFICIENT_FUNDS
For MPTs a lock is equivalent to a deep freeze, so the relaxations that
apply to trust lines do not apply to MPTs; the rows distinguish the two.
The disclaimers use mode="updated" because these result codes already
occur on these transactions today; the amendment changes which conditions
produce them rather than introducing the codes.