mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-04-29 15:37:48 +00:00
* qa/section-cards: link colors, dark mode green TextCard, CardTextIconCard text color Co-Authored-By: Oz <oz-agent@warp.dev> * updating documentation, fix per QA feedback * removing important and css clean up --------- Co-authored-by: Oz <oz-agent@warp.dev>
626 lines
17 KiB
SCSS
626 lines
17 KiB
SCSS
// BDS TextCard Component Styles
|
|
// Brand Design System - Card with title and description
|
|
//
|
|
// Naming Convention: BEM with 'bds' namespace
|
|
// .bds-text-card - Base card container
|
|
// .bds-text-card--green - Green variant
|
|
// .bds-text-card--neutral-light - Neutral light variant
|
|
// .bds-text-card--neutral-dark - Neutral dark variant
|
|
// .bds-text-card--lilac - Lilac variant
|
|
// .bds-text-card--yellow - Yellow variant
|
|
// .bds-text-card--blue - Blue variant
|
|
// .bds-text-card__overlay - Hover gradient overlay (window shade animation)
|
|
// .bds-text-card__title - Card title (heading-lg)
|
|
// .bds-text-card__description - Card description (body-l)
|
|
//
|
|
// Color states from Figma (Light Mode):
|
|
// - Green: Default $green-200, Hover $green-300, Pressed $green-400
|
|
// - NeutralLight: Default $gray-200, Hover $gray-300, Pressed $gray-400
|
|
// - NeutralDark: Default $gray-300, Hover $gray-200, Pressed $gray-400
|
|
// - Lilac: Default $lilac-200, Hover $lilac-300, Pressed $lilac-400
|
|
// - Yellow: Default $yellow-100, Hover $yellow-200, Pressed $yellow-300
|
|
// - Blue: Default $blue-100, Hover $blue-200, Pressed $blue-300
|
|
|
|
// =============================================================================
|
|
// Design Tokens from Figma
|
|
// =============================================================================
|
|
// Note: Uses centralized spacing tokens from _spacing.scss where applicable.
|
|
// Component-specific values (heights, max-widths) remain local.
|
|
|
|
// Card internal padding - uses centralized spacing tokens
|
|
$bds-text-card-padding-mobile: $bds-space-lg; // 16px - spacing('lg')
|
|
$bds-text-card-padding-tablet: $bds-space-xl; // 20px - spacing('xl')
|
|
$bds-text-card-padding-desktop: $bds-space-2xl; // 24px - spacing('2xl')
|
|
|
|
// Card heights (fixed per breakpoint) - component-specific
|
|
$bds-text-card-height-mobile: 274px;
|
|
$bds-text-card-height-tablet: 309px;
|
|
$bds-text-card-height-desktop: 340px;
|
|
|
|
// Card description max-width (from Figma) - component-specific
|
|
$bds-text-card-description-max-width: 478px;
|
|
|
|
// Colors - Light Mode (from Figma)
|
|
$bds-text-color: $black; // #141414 - Neutral black
|
|
|
|
// =============================================================================
|
|
// TextCard Component
|
|
// =============================================================================
|
|
|
|
.bds-text-card {
|
|
// Use shared window shade animation base
|
|
@include bds-window-shade-base;
|
|
|
|
// Layout
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
text-decoration: none;
|
|
box-sizing: border-box;
|
|
|
|
// Mobile dimensions and padding
|
|
height: $bds-text-card-height-mobile;
|
|
padding: $bds-text-card-padding-mobile;
|
|
|
|
@include media-breakpoint-up(md) {
|
|
height: $bds-text-card-height-tablet;
|
|
padding: $bds-text-card-padding-tablet;
|
|
}
|
|
|
|
@include media-breakpoint-up(lg) {
|
|
height: $bds-text-card-height-desktop;
|
|
padding: $bds-text-card-padding-desktop;
|
|
}
|
|
|
|
// Interaction
|
|
cursor: pointer;
|
|
|
|
// Focus styles - Light Mode
|
|
@include bds-focus-styles($black);
|
|
|
|
// Hover state for linked cards
|
|
&:hover {
|
|
text-decoration: none;
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Overlay (Window Shade Animation)
|
|
// =============================================================================
|
|
|
|
.bds-text-card__overlay {
|
|
@include bds-window-shade-overlay;
|
|
}
|
|
|
|
// Hover state: reveal overlay
|
|
.bds-text-card:hover .bds-text-card__overlay {
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
|
|
// =============================================================================
|
|
// Color Variants - Light Mode
|
|
// =============================================================================
|
|
// Desktop interaction (lg+): hover → overlay; active → pressed overlay; mouse
|
|
// release while still hovering → hover again (:hover + :focus:not(:focus-visible)).
|
|
// Keyboard: :focus-visible uses the same surface as hover for neutrals.
|
|
// Visited links: default surface + overlay hidden when not hovering/active.
|
|
|
|
// Green Variant
|
|
// Default: $green-200, Hover: $green-300, Pressed: $green-400
|
|
.bds-text-card--green {
|
|
background-color: $green-200;
|
|
|
|
&:focus-visible {
|
|
background-color: $green-200;
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
background-color: $green-200;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
background-color: $green-300;
|
|
}
|
|
|
|
&:active {
|
|
.bds-text-card__overlay {
|
|
background-color: $green-400;
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Neutral Light Variant (Light Mode)
|
|
// Default: $gray-200, Hover: $gray-300, Focus (keyboard): $gray-300, Pressed: $gray-400
|
|
.bds-text-card--neutral-light {
|
|
background-color: $gray-200;
|
|
|
|
&:focus-visible {
|
|
background-color: $gray-300;
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
background-color: $gray-200;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
background-color: $gray-300;
|
|
}
|
|
|
|
&:active {
|
|
.bds-text-card__overlay {
|
|
background-color: $gray-400;
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Neutral Dark Variant (Light Mode)
|
|
// Default: $gray-300, Hover: $gray-200, Focus (keyboard): $gray-200, Pressed: $gray-400
|
|
.bds-text-card--neutral-dark {
|
|
background-color: $gray-300;
|
|
|
|
&:focus-visible {
|
|
background-color: $gray-200;
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
background-color: $gray-300;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
background-color: $gray-200;
|
|
}
|
|
|
|
&:active {
|
|
.bds-text-card__overlay {
|
|
background-color: $gray-400;
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Lilac Variant
|
|
// Default: $lilac-200, Hover: $lilac-300, Pressed: $lilac-400
|
|
.bds-text-card--lilac {
|
|
background-color: $lilac-200;
|
|
|
|
&:focus-visible {
|
|
background-color: $lilac-200;
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
background-color: $lilac-200;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
background-color: $lilac-300;
|
|
}
|
|
|
|
&:active {
|
|
.bds-text-card__overlay {
|
|
background-color: $lilac-400;
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Yellow Variant
|
|
// Default: $yellow-100, Hover: $yellow-200, Pressed: $yellow-300
|
|
.bds-text-card--yellow {
|
|
background-color: $yellow-100;
|
|
|
|
&:focus-visible {
|
|
background-color: $yellow-100;
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
background-color: $yellow-100;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
background-color: $yellow-200;
|
|
}
|
|
|
|
&:active {
|
|
.bds-text-card__overlay {
|
|
background-color: $yellow-300;
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Blue Variant
|
|
// Default: $blue-100, Hover: $blue-200, Pressed: $blue-300
|
|
.bds-text-card--blue {
|
|
background-color: $blue-100;
|
|
|
|
&:focus-visible {
|
|
background-color: $blue-100;
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
background-color: $blue-100;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
background-color: $blue-200;
|
|
}
|
|
|
|
&:active {
|
|
.bds-text-card__overlay {
|
|
background-color: $blue-300;
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Card Title
|
|
// =============================================================================
|
|
|
|
.bds-text-card__title {
|
|
width: 100%;
|
|
position: relative;
|
|
z-index: 1;
|
|
margin: 0;
|
|
color: $bds-text-color;
|
|
// Typography handled by .h-lg class from _font.scss
|
|
}
|
|
|
|
// =============================================================================
|
|
// Card Description
|
|
// =============================================================================
|
|
|
|
.bds-text-card__description {
|
|
width: 100%;
|
|
position: relative;
|
|
z-index: 1;
|
|
margin: 0;
|
|
color: $bds-text-color;
|
|
max-width: $bds-text-card-description-max-width;
|
|
// Typography handled by .body-l class from _font.scss
|
|
}
|
|
|
|
// =============================================================================
|
|
// Disabled State
|
|
// =============================================================================
|
|
|
|
.bds-text-card--disabled {
|
|
pointer-events: none;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
// =============================================================================
|
|
// Light Mode Overrides
|
|
// =============================================================================
|
|
// Override the light theme rule: a:not(.bds-link):not(.btn):focus { background-color: transparent }
|
|
// This rule has higher specificity, so we need html.light scoped rules
|
|
|
|
html.light {
|
|
a.bds-text-card.bds-text-card--green:focus-visible,
|
|
a.bds-text-card.bds-text-card--green:focus:not(:focus-visible) {
|
|
background-color: $green-200;
|
|
}
|
|
a.bds-text-card.bds-text-card--neutral-light:focus-visible {
|
|
background-color: $gray-300;
|
|
}
|
|
a.bds-text-card.bds-text-card--neutral-light:focus:not(:focus-visible) {
|
|
background-color: $gray-200;
|
|
}
|
|
a.bds-text-card.bds-text-card--neutral-dark:focus-visible {
|
|
background-color: $gray-200;
|
|
}
|
|
a.bds-text-card.bds-text-card--neutral-dark:focus:not(:focus-visible) {
|
|
background-color: $gray-300;
|
|
}
|
|
a.bds-text-card.bds-text-card--lilac:focus-visible,
|
|
a.bds-text-card.bds-text-card--lilac:focus:not(:focus-visible) {
|
|
background-color: $lilac-200;
|
|
}
|
|
a.bds-text-card.bds-text-card--yellow:focus-visible,
|
|
a.bds-text-card.bds-text-card--yellow:focus:not(:focus-visible) {
|
|
background-color: $yellow-100;
|
|
}
|
|
a.bds-text-card.bds-text-card--blue:focus-visible,
|
|
a.bds-text-card.bds-text-card--blue:focus:not(:focus-visible) {
|
|
background-color: $blue-100;
|
|
}
|
|
|
|
// Visited (scoped to light theme so neutral grays match light-mode card defaults)
|
|
a.bds-text-card.bds-text-card--green:visited:not(:hover):not(:active) {
|
|
background-color: $green-200;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--neutral-light:visited:not(:hover):not(:active) {
|
|
background-color: $gray-200;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--neutral-dark:visited:not(:hover):not(:active) {
|
|
background-color: $gray-300;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--lilac:visited:not(:hover):not(:active) {
|
|
background-color: $lilac-200;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--yellow:visited:not(:hover):not(:active) {
|
|
background-color: $yellow-100;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--blue:visited:not(:hover):not(:active) {
|
|
background-color: $blue-100;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
// Disabled state in light mode: $gray-100 background, $gray-500 text
|
|
.bds-text-card--disabled {
|
|
background-color: $gray-100 !important;
|
|
|
|
.bds-text-card__title,
|
|
.bds-text-card__description {
|
|
color: $gray-500;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Dark Mode Styles
|
|
// =============================================================================
|
|
// In dark mode:
|
|
// - Focus border changes from black to white
|
|
// - Text color remains black (cards have light-colored backgrounds)
|
|
// - Neutral-light dark mode: Default $gray-300, Hover $gray-200, Focus $gray-200, Pressed $gray-400
|
|
// - Neutral-dark dark mode: Default $gray-400, Hover $gray-300, Focus $gray-300, Pressed $gray-500
|
|
|
|
html.dark {
|
|
.bds-text-card {
|
|
// Focus styles - Dark Mode (white border)
|
|
&:focus-visible {
|
|
outline-color: $white;
|
|
}
|
|
}
|
|
|
|
// Green — same tokens as light mode (TextCard.md)
|
|
.bds-text-card--green {
|
|
background-color: $green-200;
|
|
|
|
&:focus-visible {
|
|
background-color: $green-200;
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
background-color: $green-200;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
background-color: $green-300;
|
|
}
|
|
|
|
&:active {
|
|
.bds-text-card__overlay {
|
|
background-color: $green-400;
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Neutral Light in dark mode
|
|
// Default: $gray-300, Hover: $gray-200, Focus (keyboard): $gray-200, Pressed: $gray-400
|
|
.bds-text-card--neutral-light {
|
|
background-color: $gray-300;
|
|
|
|
&:focus-visible {
|
|
background-color: $gray-200;
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
background-color: $gray-300;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
background-color: $gray-200;
|
|
}
|
|
|
|
&:active {
|
|
.bds-text-card__overlay {
|
|
background-color: $gray-400;
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Neutral Dark in dark mode
|
|
// Default: $gray-400, Hover: $gray-300, Focus (keyboard): $gray-300, Pressed: $gray-500
|
|
.bds-text-card--neutral-dark {
|
|
background-color: $gray-400;
|
|
|
|
&:focus-visible {
|
|
background-color: $gray-300;
|
|
}
|
|
|
|
&:focus:not(:focus-visible) {
|
|
background-color: $gray-400;
|
|
}
|
|
|
|
.bds-text-card__overlay {
|
|
background-color: $gray-300;
|
|
}
|
|
|
|
&:active {
|
|
.bds-text-card__overlay {
|
|
background-color: $gray-500;
|
|
@include bds-window-shade-revealed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Focus overrides for dark mode (to override light theme rules)
|
|
a.bds-text-card.bds-text-card--green:focus-visible,
|
|
a.bds-text-card.bds-text-card--green:focus:not(:focus-visible) {
|
|
background-color: $green-200;
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--neutral-light:focus-visible {
|
|
background-color: $gray-200;
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--neutral-light:focus:not(:focus-visible) {
|
|
background-color: $gray-300;
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--neutral-dark:focus-visible {
|
|
background-color: $gray-300;
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--neutral-dark:focus:not(:focus-visible) {
|
|
background-color: $gray-400;
|
|
}
|
|
|
|
// Visited: use dark-mode card defaults (must live under html.dark — not global :visited)
|
|
a.bds-text-card.bds-text-card--green:visited:not(:hover):not(:active) {
|
|
background-color: $green-200;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--neutral-light:visited:not(:hover):not(:active) {
|
|
background-color: $gray-300;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--neutral-dark:visited:not(:hover):not(:active) {
|
|
background-color: $gray-400;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--lilac:visited:not(:hover):not(:active) {
|
|
background-color: $lilac-200;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--yellow:visited:not(:hover):not(:active) {
|
|
background-color: $yellow-100;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
a.bds-text-card.bds-text-card--blue:visited:not(:hover):not(:active) {
|
|
background-color: $blue-100;
|
|
|
|
.bds-text-card__overlay {
|
|
clip-path: inset(100% 0 0 0);
|
|
}
|
|
}
|
|
|
|
// Disabled state in dark mode: $gray-500 background with 30% opacity
|
|
.bds-text-card--disabled {
|
|
background-color: rgba($gray-500, 0.3) !important;
|
|
|
|
.bds-text-card__overlay {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Tablet + mobile: no clip-path wipe (quick taps outrun the animation)
|
|
// Same intent as TileLogo — below lg, overlay transition off; hover / focus-visible
|
|
// jump straight to the pressed overlay color (full clip-path).
|
|
// =============================================================================
|
|
@include media-breakpoint-down(lg) {
|
|
.bds-text-card__overlay {
|
|
transition: none;
|
|
}
|
|
|
|
.bds-text-card--green:not(.bds-text-card--disabled) {
|
|
&:hover .bds-text-card__overlay,
|
|
&:focus-visible .bds-text-card__overlay {
|
|
background-color: $green-400;
|
|
clip-path: inset(0 0 0 0);
|
|
}
|
|
}
|
|
|
|
.bds-text-card--neutral-light:not(.bds-text-card--disabled) {
|
|
&:hover .bds-text-card__overlay,
|
|
&:focus-visible .bds-text-card__overlay {
|
|
background-color: $gray-400;
|
|
clip-path: inset(0 0 0 0);
|
|
}
|
|
}
|
|
|
|
// Neutral-dark: use pressed $gray-500 so it differs from neutral-light ($gray-400) on tap
|
|
.bds-text-card--neutral-dark:not(.bds-text-card--disabled) {
|
|
&:hover .bds-text-card__overlay,
|
|
&:focus-visible .bds-text-card__overlay {
|
|
background-color: $gray-500;
|
|
clip-path: inset(0 0 0 0);
|
|
}
|
|
}
|
|
|
|
.bds-text-card--lilac:not(.bds-text-card--disabled) {
|
|
&:hover .bds-text-card__overlay,
|
|
&:focus-visible .bds-text-card__overlay {
|
|
background-color: $lilac-400;
|
|
clip-path: inset(0 0 0 0);
|
|
}
|
|
}
|
|
|
|
.bds-text-card--yellow:not(.bds-text-card--disabled) {
|
|
&:hover .bds-text-card__overlay,
|
|
&:focus-visible .bds-text-card__overlay {
|
|
background-color: $yellow-300;
|
|
clip-path: inset(0 0 0 0);
|
|
}
|
|
}
|
|
|
|
.bds-text-card--blue:not(.bds-text-card--disabled) {
|
|
&:hover .bds-text-card__overlay,
|
|
&:focus-visible .bds-text-card__overlay {
|
|
background-color: $blue-300;
|
|
clip-path: inset(0 0 0 0);
|
|
}
|
|
}
|
|
}
|