// BDS CardImage Component Styles // Brand Design System - Responsive card with image, title, subtitle, and CTA button // // Naming Convention: BEM with 'bds' namespace // .bds-card-image - Base card container // .bds-card-image--hovered - Hover state (scales image only) // .bds-card-image--disabled - Disabled state // .bds-card-image__image-container - Gray background image wrapper // .bds-card-image__image - The actual image element // .bds-card-image__content - Title/subtitle/button wrapper // .bds-card-image__text - Title and subtitle wrapper // .bds-card-image__title - Card title (uses .sh-md-r) // .bds-card-image__subtitle - Card subtitle (uses .body-l) // // Note: This file is imported within xrpl.scss after Bootstrap and project // variables are loaded, so $grid-breakpoints, colors, and mixins are available. // ============================================================================= // Design Tokens (from Figma) // ============================================================================= // Note: Uses centralized spacing tokens from _spacing.scss where applicable. // Component-specific values (heights, dimensions) remain local. // Card dimensions - LG (Large) variant (default, ≥992px) $bds-card-image-height-lg: 620px; $bds-card-image-image-height-lg: 400px; // Card dimensions - MD (Medium) variant (576px - 991px) $bds-card-image-height-md: 560px; $bds-card-image-image-height-md: 280px; // Card dimensions - SM (Small) variant (<576px) $bds-card-image-height-sm: 536px; $bds-card-image-image-height-sm: 268px; // Spacing - LG (Large) variant (default, ≥992px) $bds-card-image-gap-lg: $bds-space-2xl; // 24px - Gap between image and content $bds-card-image-title-gap-lg: $bds-space-md; // 12px - Gap between title and subtitle $bds-card-image-content-padding: $bds-space-sm; // 8px - Horizontal padding for content $bds-card-image-button-margin-lg: $bds-space-3xl; // 32px - Margin above button // Spacing - MD (Medium) variant (576px - 991px) $bds-card-image-gap-md: $bds-space-lg; // 16px - Gap between image and content $bds-card-image-title-gap-md: $bds-space-sm; // 8px - Gap between title and subtitle $bds-card-image-button-margin-md: $bds-space-2xl; // 24px - Margin above button // Spacing - SM (Small) variant (<576px) $bds-card-image-gap-sm: $bds-space-lg; // 16px - Gap between image and content $bds-card-image-title-gap-sm: $bds-space-sm; // 8px - Gap between title and subtitle $bds-card-image-button-margin-sm: $bds-space-2xl; // 24px - Margin above button // Bulleted subtitle hanging indent (width of the bullet + its trailing space) $bds-card-image-bullet-indent: 0.75em; // Colors $bds-card-image-bg: $white; $bds-card-image-image-bg: $gray-100; $bds-card-image-text-color: #141414; // Neutral black from Figma // Animation - uses centralized tokens from _animations.scss $bds-card-image-transition-duration: 150ms; // Component-specific (faster than default) $bds-card-image-transition-timing: $bds-transition-timing; // ============================================================================= // Base Card Styles // ============================================================================= .bds-card-image { // Card container display: flex; flex-direction: column; gap: $bds-card-image-gap-lg; // Gap between image container and content width: 100%; // Fill available width (4-column span on LG+) background-color: $bds-card-image-bg; cursor: pointer; // Suppress the default underline (the card renders as an when `href` is set) // so the title/subtitle never pick up the global anchor hover underline. &, &:hover, &:focus, &:active { text-decoration: none; } // When inside a grid column, fill the column width .bds-grid__col & { flex: 1 1 auto; width: 100%; } // Focus styles &:focus { outline: 2px solid $bds-card-image-text-color; outline-offset: 2px; } &:focus:not(:focus-visible) { outline: none; } &:focus-visible { outline: 2px solid $bds-card-image-text-color; outline-offset: 2px; } } // ============================================================================= // Image Container // ============================================================================= // Image container has fixed height per breakpoint. // Image within maintains its aspect ratio using object-fit: contain. .bds-card-image__image-container { display: flex; align-items: center; justify-content: center; width: 100%; height: $bds-card-image-image-height-lg; background-color: var(--bds-card-image-bg, $bds-card-image-image-bg); overflow: hidden; flex-shrink: 0; } .bds-card-image__image { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; // Maintain image aspect ratio (1:1 for this design) object-position: center; transition: transform $bds-card-image-transition-duration $bds-card-image-transition-timing; } // ============================================================================= // Full Bleed Modifier // ============================================================================= // When fullBleed is true, image fills entire container with object-fit: cover // and uses aspect-ratio for responsive sizing .bds-card-image--full-bleed { // Override fixed heights - use auto height with aspect ratio height: auto; width: 100%; // Ensure card fills parent container .bds-card-image__image-container { // Use aspect-ratio instead of fixed height for responsive scaling width: 100%; height: auto; // 1:1 aspect ratio for all breakpoints (from Figma designs) aspect-ratio: 1 / 1; } .bds-card-image__image { width: 100%; height: 100%; max-width: none; max-height: none; object-fit: cover; } } // ============================================================================= // Content Area // ============================================================================= .bds-card-image__content { display: flex; flex-direction: column; justify-content: space-between; // Distribute space between text and button flex: 1; padding: 0 $bds-card-image-content-padding; // Horizontal padding only padding-bottom: $bds-card-image-content-padding; min-height: 0; // Allow flex shrinking } .bds-card-image__text { display: flex; flex-direction: column; gap: $bds-card-image-title-gap-lg; flex-shrink: 0; // Don't shrink text container } .bds-card-image__title { // Typography handled by .sh-md-r class from _font.scss color: $bds-card-image-text-color; margin: 0; text-align: left; // Always left-align, regardless of parent // Title should be 1 line only overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .bds-card-image__subtitle { // Typography handled by .body-l class from _font.scss color: $bds-card-image-text-color; margin: 0; text-align: left; // Always left-align, regardless of parent display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; // Honor explicit `\n` in the subtitle string as a line break, while still // collapsing runs of spaces and wrapping normally. white-space: pre-line; } // Bulleted subtitle: rendered as a