Files
xrpl-dev-portal/@theme/styles.css
Calvin 5021556c8e BDS component polish: link contrast, static cards, uniform CTAs, stacked hero (#3851)
* 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>
2026-08-18 16:49:10 -07:00

450 lines
14 KiB
CSS

html.light pre code {
color: var(--code-block-controls-text-color) !important;
}
ul.nav.navbar-nav {
align-items: center;
width: 100%;
}
.top-nav .topnav-search {
flex-grow: 1;
}
.clio-only-notice {
background-color: var(--admonition-info-bg-color);
margin-left: var(--spacing-sm);
padding: var(--spacing-xs);
border-radius: var(--border-radius);
}
#content .heading-anchor h1,
#content .heading-anchor h2,
#content .heading-anchor h3,
#content .heading-anchor h4,
#content .heading-anchor h5,
#content .heading-anchor h6 {
/* Fix left-alignment of headers in md content */
gap: 0;
}
:root, :root.dark {
--navbar-height: 80px;
/* XRPL color palette; match to styles/_colors.scss
Some colors don't have a 10 equivalent so 9 is repeated.
These are in reverse order of the ones in styles/_colors.scss
so that they correspond to the same-named variables provided by
styled-components as part of Redocly.
*/
/* Redocly doesn't have vars for grays by default */
--color-gray-1: #111112;
--color-gray-2: #232325;
--color-gray-3: #343437;
--color-gray-4: #454549;
--color-gray-5: #838386;
--color-gray-6: #A2A2A4;
--color-gray-7: #C1C1C2;
--color-gray-8: #E0E0E1;
--color-gray-9: #F5F5F7;
--color-gray-10: var(--color-gray-9);
/* color-red = XRPL $magenta */
--color-red-1: #4C0026;
--color-red-2: #4C0026;
--color-red-3: #80003F;
--color-red-4: #B20058;
--color-red-5: #E50071;
--color-red-6: #FF198B;
--color-red-7: #FF4BA4;
--color-red-8: #FF80BF;
--color-red-9: #FFB2D8;
--color-red-10: #FFE5F2;
/* color-green = XRPL $green */
--color-green-1: #0A2E1B;
--color-green-2: #145C35;
--color-green-3: #1E8A50;
--color-green-4: #28B86A;
--color-green-5: #2DCF78;
--color-green-6: #32E685;
--color-green-7: #5BEB9D;
--color-green-8: #84F0B6;
--color-green-9: #ADF5CE;
--color-green-10: #D6FAE7;
/* color-gold = XRPL $yellow */
--color-gold-1: #4B4C00;
--color-gold-2: #4B4C00;
--color-gold-3: #7D8000;
--color-gold-4: #AEB200;
--color-gold-5: #E0E500;
--color-gold-6: #FAFF19;
--color-gold-7: #FBFF4C;
--color-gold-8: #FCFF80;
--color-gold-9: #FDFFB2;
--color-gold-10: #FEFFE5;
/* color-blue = XRPL $blue */
--color-blue-1: #001133;
--color-blue-2: #002E4C;
--color-blue-3: #004D80;
--color-blue-4: #006BB2;
--color-blue-5: #008AE5;
--color-blue-6: #19A3FF;
--color-blue-7: #4BB7FF;
--color-blue-8: #80CCFF;
--color-blue-9: #B2E0FF;
--color-blue-10: #E5F5FF;
/* color purple = XRPL $blue-purple */
--color-purple-1: #20004C;
--color-purple-2: #20004C;
--color-purple-3: #350080;
--color-purple-4: #4A00B2;
--color-purple-5: #5F00E5;
--color-purple-6: #7919FF;
--color-purple-7: #9A52FF;
--color-purple-8: #B480FF;
--color-purple-9: #D2B2FF;
--color-purple-10: #F0E5FF;
/* color-magenta = XRPL $red-purple */
--color-magenta-1: #40004C;
--color-magenta-2: #40004C;
--color-magenta-3: #6B0080;
--color-magenta-4: #9500B2;
--color-magenta-5: #C000E5;
--color-magenta-6: #D919FF;
--color-magenta-7: #E24CFF;
--color-magenta-8: #EA80FF;
--color-magenta-9: #F2B2FF;
--color-magenta-10: #FBE5FF;
/* XRPL doesn't have a color-cyan equivalent*
--color-cyan-1: #002329;*
--color-cyan-2: #00474f;*
--color-cyan-3: #006d75;*
--color-cyan-4: #08979c;*
--color-cyan-5: #13c2c2;*
--color-cyan-6: #36cfc9;*
--color-cyan-7: #5cdbd3;*
--color-cyan-8: #87e8de;*
--color-cyan-9: #b5f5ec;*
--color-cyan-10: #e6fffb; */
/* color-yellow = XRPL $yellow */
--color-yellow-1: #4B4C00;
--color-yellow-2: #4B4C00;
--color-yellow-3: #7D8000;
--color-yellow-4: #AEB200;
--color-yellow-5: #E0E500;
--color-yellow-6: #FAFF19;
--color-yellow-7: #FBFF4C;
--color-yellow-8: #FCFF80;
--color-yellow-9: #FDFFB2;
--color-yellow-10: #FEFFE5;
/* XRPL doesn't have a color-lime equivalent*
--color-lime-1: #254000;*
--color-lime-2: #3f6600;*
--color-lime-3: #5b8c00;*
--color-lime-4: #7cb305;*
--color-lime-5: #a0d911;*
--color-lime-6: #bae637;*
--color-lime-7: #d3f261;*
--color-lime-8: #eaff8f;*
--color-lime-9: #f4ffb8;*
--color-lime-10: #fcffe6; */
/* XRPL doesn't have a color-geekblue equivalent*
--color-geekblue-1: #030852;*
--color-geekblue-2: #061178;*
--color-geekblue-3: #10239e;*
--color-geekblue-4: #1d39c4;*
--color-geekblue-5: #2f54eb;*
--color-geekblue-6: #597ef7;*
--color-geekblue-7: #85a5ff;*
--color-geekblue-8: #adc6ff;*
--color-geekblue-9: #d6e4ff;*
--color-geekblue-10: #f0f5ff; */
/* Dark mode colors by default */
--color-primary-bg: var(--color-gray-10);
/* --color-primary-bg-hover: #d6dfff;
--color-primary-border: #adbcff;
--color-primary-border-hover: #8a99ff;
--color-primary-hover: #6678ff;
--color-primary-base: #434dfa;
--color-primary-active: #2f31d4;
--color-primary-text-hover: #201dad;
--color-primary-text: #161087;
--color-primary-text-active: #0d086e;*/
--link-color-primary: white;
--link-decoration: underline;
--link-font-weight: var(--font-weight-regular);
--link-color-primary-hover: var(--color-purple-7);
--link-decoration-hover: underline;
--link-color-visited: white;
--link-visited-decoration: underline;
--bg-color: var(--color-gray-1); /* was --color-gray-10 */
--bg-color-raised: var(--color-gray-2);
--background-color: var(--bg-color);
--font-family-base: 'Work Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
--heading-font-family: var(--font-family-base);
--inline-code-font-family: "Space Mono", monospace;
--inline-code-text-color: var(--color-green-7);
--inline-code-bg-color: var(--color-green-1);
--inline-code-border-radius: 0;
--heading-anchor-color: var(--color-purple-7);
--h1-font-size: 3rem;
--h2-font-size: 2.5rem;
--h3-font-size: 2.125rem;
--h3-font-weight: 600;
--h4-font-size: 1.75rem;
--h4-line-height: 2rem;
--h5-font-size: 1.25rem;
--h5-line-height: 1.5rem;
--menu-container-padding-top: 0;
--md-content-padding: 4px 0;
--toc-offset-top: 2px;
--sidebar-border-color: transparent;
--sidebar-bg-color: transparent;
--sidebar-margin-horizontal: 32px;
--border-radius-md: 4px;
--code-block-bg-color: var(--color-gray-2);
--code-block-controls-bg-color: var(--color-gray-2);
--code-block-controls-border: none;
--code-block-padding: 0 2rem 1.5rem 2rem;
--breadcrumbs-margin-bottom: 0.5rem;
--breadcrumbs-text-color: var(--color-gray-4);
--breadcrumbs-gap: 0 8px;
--breadcrumbs-font-size: 0.833em;
--footer-bg-color: transparent;
--footer-column-divider-color: transparent;
--footer-border-color: transparent;
--footer-title-font-weight: 600;
--footer-title-font-size: 1rem;
--footer-title-text-color: var(--color-gray-6);
--menu-item-padding-horizontal: 0px;
--menu-item-bg-color-active: var(--color-gray-2);
--menu-item-bg-color-active-hover: var(--color-gray-3);
--md-list-left-padding: 40px;
--md-list-margin: 0 0 20px 0;
--md-table-header-bg-color: var(--color-gray-3);
--md-table-border-color: var(--color-gray-3);
--md-tabs-content-padding: 0;
--md-tabs-tab-wrapper-padding: 0;
--text-color-helper: var(--color-gray-6);
--color-text-primary: white;
--button-color-hover: white;
--text-color-secondary: var(--color-gray-9); /* inherited for adominition text color */
--admonition-success-bg-color: var(--color-green-2);
--admonition-info-bg-color: var(--color-blue-4);
/* none of the yellow shades in the XRPL palette work well with "warning"
admonitions, so leave it the default */
--admonition-danger-bg-color: var(--color-red-3);
}
:root.light {
/* #141414 == Sass $black / $gray-900 (styles/_colors.scss). Hardcoded
because this is plain CSS and can't reference Sass vars; defining it on
the SCSS side instead gets stripped by PurgeCSS (its var() consumer, the
generated link rule, lives in this theme layer, not the SCSS bundle). */
--link-color-primary: black;
--link-color-primary-hover: var(--color-purple-4);
--link-color-visited: black;
--text-color-secondary: black;
--code-block-bg-color: var(--color-gray-8);
--code-block-controls-bg-color: var(--color-gray-8);
--code-block-controls-border: none;
--md-tabs-active-tab-bg-color: var(--color-gray-7);
--md-tabs-hover-tab-bg-color: var(--color-gray-8);
--inline-code-bg-color: var(--color-gray-8);
--search-trigger-bg-color: var(--color-gray-8);
--search-trigger-color: var(--color-gray-5);
--modal-bg-color: var(--color-gray-9);
--language-picker-border-color: var(--color-gray-7);
--language-picker-background-color: var(--color-gray-8);
--select-list-bg-color: var(--color-gray-8);
--button-bg-color-secondary: var(--color-gray-8);
--footer-title-text-color: black;
--bg-color: var(--color-gray-9);
--bg-color-raised: var(--color-gray-8);
--button-content-color-link: black;
--menu-item-bg-color-active: var(--color-gray-8);
--menu-item-bg-color-active-hover: var(--color-gray-7);
--md-table-header-bg-color: var(--color-gray-8);
--md-table-border-color: var(--color-gray-8);
--bg-color: var(--color-gray-8);
--code-panel-bg-color: var(--color-blue-7);
--layer-color-hover: var(--color-gray-9);
--code-block-text-color: var(--color-gray-1);
--code-block-tokens-comment-color: var(--color-gray-4);
--code-block-tokens-constant-color: var(--color-gray-1);
--code-block-tokens-function-color: var(--color-red-4);
--code-block-tokens-keyword-color: var(--color-magenta-5);
--code-block-tokens-operator-color: black;
--code-block-tokens-string-color: var(--color-green-3);
--bg-raised-gradient: "";
--text-color-helper: var(--color-gray-4);
--button-color-hover: black;
--admonition-success-bg-color: var(--color-green-9);
--admonition-info-bg-color: var(--color-blue-9);
--admonition-warning-bg-color: var(--color-yellow-9);
--admonition-danger-bg-color: var(--color-red-9);
}
:root.dark {
--link-color-primary: white;
--link-color-visited: white;
--link-color-primary-hover: var(--color-purple-7);
--navbar-bg-color: var(--color-gray-2); /* controls search box bg */
--modal-bg-color: var(--color-gray-2); /* controls search modal bg */
--search-highlight-text-color: var(--color-blue-7);
--code-block-text-color: var(--color-gray-9);
--code-block-tokens-comment-color: var(--color-gray-7);
--code-block-tokens-constant-color: var(--color-gray-9);
--code-block-tokens-keyword-color: var(--color-magenta-8);
--code-block-tokens-string-color: var(--color-blue-8);
--md-tabs-active-tab-bg-color: var(--color-gray-4);
--md-tabs-hover-tab-bg-color: var(--color-gray-3);
--code-panel-bg-color: var(--color-blue-3);
--layer-color-hover: var(--color-gray-3);
--bg-raised-gradient: "";
/* The base value (--color-gray-4) is tuned for the light background; dark mode
needs the inverse end of the scale. gray-6 on gray-1 is 7.41:1, matching light
mode's 7.23:1, so breadcrumbs are equally de-emphasized in both themes. */
--breadcrumbs-text-color: var(--color-gray-6);
}
/* The open breadcrumb dropdown menu inherits the generic --dropdown-menu-item-color
(--text-color-secondary: gray-9 in dark, black in light), which is brighter than
the breadcrumb trail. Re-point the menu at the breadcrumb tokens so the trail, the
trigger, and the open menu all read as one color in both themes. Scoped to
breadcrumbs so the language picker and nav dropdowns are unaffected.
Two things this rule has to live with:
- It belongs in this theme layer, not the SCSS bundle: PurgeCSS runs with
`variables: true`, and these tokens' var() consumers are Redocly's runtime
styled-components under node_modules (excluded from its `content`), so a
custom-property-only rule in the SCSS bundle gets stripped.
- --dropdown-menu-item-color is the token that matters, not
--dropdown-menu-text-color. The former is declared at :root as
var(--dropdown-menu-text-color), so that var() is substituted in :root's
context; redefining only the source token here would silently do nothing. */
[data-component-name="Breadcrumbs/BreadcrumbDropdown"] {
--dropdown-menu-text-color: var(--breadcrumbs-text-color);
--dropdown-menu-item-color: var(--breadcrumbs-text-color);
--dropdown-menu-item-color-hover: var(--breadcrumbs-text-color-active);
}
:root .form-control-plaintext {
color: var(--text-color);
}
/* Keep active tab visually static on hover */
button[role="tab"].active {
--md-tabs-hover-tab-bg-color: var(--md-tabs-active-tab-bg-color);
--md-tabs-hover-tab-text-color: var(--md-tabs-active-tab-text-color);
}
/* Fix unnecessary horizontal scrolling of tables in Japanese */
[lang="ja"] table.md {
word-break: break-word;
}
[lang="ja"] table.md th {
min-width: 7em;
}
[data-component-name="Search/SearchTrigger"] > div {
justify-content: start;
width: 100%;
}
[data-component-name="Markdown/Markdown"] {
--md-table-font-size: 14px;
--md-table-line-height: 1.5;
}
[data-component-name="Markdown/Markdown"] td p {
font-size: var(--md-table-font-size);
line-height: var(--md-table-line-height);
}
@media screen and (max-width: 959.9px) {
[data-component-name="Layout/PageLayout"] {
flex-direction: column-reverse;
}
[data-component-name="Sidebar/Sidebar"] {
display: block;
position: static;
height: auto;
}
#content {
width: auto;
}
[data-component-name="Menu/MenuContainer"] {
overscroll-behavior: auto;
}
}
:root {
--ai-assistant-button-bottom: 16px;
--ai-assistant-button-right: 71px; /* align w/ Osano cookie widget (mobile) */
}
@media screen and (min-width: 990px) {
:root {
--ai-assistant-button-right: 86px;
}
[data-component-name="LanguagePicker/LanguagePicker"] {
display: block;
}
[data-component-name="Search/SearchTrigger"] > button {
display: none;
}
[data-component-name="Search/SearchTrigger"] > div {
display: inline-flex;
}
}