// BDS Button Component Styles // Brand Design System - Scalable button component // // Naming Convention: BEM with 'bds' namespace // .bds-btn - Base button (shared layout, typography, icon animation) // .bds-btn--primary - Primary variant (solid background) // .bds-btn--secondary - Secondary variant (outline style) // .bds-btn--green - Green color theme (default) // .bds-btn--black - Black color theme // .bds-btn--tertiary - Tertiary variant (text-only style) // .bds-btn__label - Label element // .bds-btn__icon - Icon element (inherits color via currentColor) // .bds-btn--disabled - Disabled state modifier // .bds-btn--no-icon - No icon modifier // // 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 // ============================================================================= // Neutral Black (used across variants) $bds-btn-neutral-black: #141414; $bds-btn-neutral-black-15: rgba(20, 20, 20, 0.15); // 15% black for secondary hover // Colors - Green Primary Button $bds-btn-primary-bg: $green-300; // #21E46B - Enabled $bds-btn-primary-bg-hover: $green-200; // #70EE97 - Hover/Focus $bds-btn-primary-text: $bds-btn-neutral-black; $bds-btn-primary-focus-border: $bds-btn-neutral-black; // Colors - Black Primary Button $bds-btn-primary-black-bg: $bds-btn-neutral-black; // Must contrast with $bds-btn-primary-black-bg: semi-transparent rgb(20,20,20) over #141414 // composites to the same color, so the ::before hover fill looked invisible. $bds-btn-primary-black-bg-hover: #434343; // #434343 — visible lift on neutral black $bds-btn-primary-black-text: $white; // Colors - Disabled State (Light Mode) // Note: Theme overrides use @include bds-theme-mode(light) / (dark) nested under each selector $bds-btn-disabled-bg: $gray-200; // #E6EAF0 (Light mode) $bds-btn-disabled-text: $gray-500; // #72777E // Colors - Green Secondary Button $bds-btn-secondary-text: $green-400; // #0DAA3E - Enabled $bds-btn-secondary-text-hover: $green-500; // #078139 - Hover/Focus $bds-btn-secondary-bg: transparent; $bds-btn-secondary-bg-hover: $green-100; // #EAFCF1 - Hover/Focus fill $bds-btn-secondary-border: $green-400; // #0DAA3E - Enabled $bds-btn-secondary-border-hover: $green-500; // #078139 - Hover/Focus $bds-btn-secondary-disabled-text: $gray-400; // Disabled text $bds-btn-secondary-disabled-border: $gray-400; // Disabled border // Colors - Tertiary Button $bds-btn-tertiary-text: $green-400; // #0DAA3E - Enabled $bds-btn-tertiary-text-hover: $green-500; // #078139 - Hover/Focus/Active $bds-btn-tertiary-bg: transparent; $bds-btn-tertiary-focus-outline: $bds-btn-neutral-black; // #141414 - Focus outline (black) $bds-btn-tertiary-disabled-text: $gray-400; // Disabled text // Colors - Black Secondary Button $bds-btn-secondary-black-text: $bds-btn-neutral-black; $bds-btn-secondary-black-bg-hover: $bds-btn-neutral-black-15; $bds-btn-secondary-black-border: $bds-btn-neutral-black; // Colors - Black Tertiary Button $bds-btn-tertiary-black-text: $bds-btn-neutral-black; $bds-btn-tertiary-black-focus-outline: $bds-btn-neutral-black; // Black secondary / tertiary — active/pressed only (text + border + icon; defaults stay #141414) $bds-btn-black-pressed: #434343; // Spacing $bds-btn-border-radius: 100px; $bds-btn-focus-border-width: 2px; // Transitions // Motion: Duration 150ms, Custom bezier for smooth in-out feel $bds-btn-transition-duration: 150ms; $bds-btn-transition-timing: cubic-bezier(0.98, 0.12, 0.12, 0.98); // ============================================================================= // File-local helpers (this stylesheet only) // ============================================================================= @mixin bds-btn-anchor-link-decoration-reset { text-decoration: none; &:hover, &:focus, &:focus-visible, &:active, &:visited { text-decoration: none; } } @mixin bds-btn-icon-stroke-color($color) { .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $color; stroke: $color; } } @mixin bds-btn-icon-stroke-color-important($color) { .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $color !important; stroke: $color !important; } } // ============================================================================= // Anchor link buttons — theme overrides // Chaining .bds-btn.bds-btn increases specificity without !important // ============================================================================= a.bds-btn.bds-btn { @include bds-theme-mode(light) { @include bds-btn-anchor-link-decoration-reset; // Primary green link button &.bds-btn--primary.bds-btn--green { color: $bds-btn-primary-text; background-color: $bds-btn-primary-bg; &:hover, &:focus, &:focus-visible, &:active, &:visited { color: $bds-btn-primary-text; background-color: $bds-btn-primary-bg; } } // Primary black link button &.bds-btn--primary.bds-btn--black { color: $bds-btn-primary-black-text; background-color: $bds-btn-primary-black-bg; @include bds-btn-icon-stroke-color($bds-btn-primary-black-text); &:hover, &:focus, &:focus-visible, &:active, &:visited { color: $bds-btn-primary-black-text; background-color: $bds-btn-primary-black-bg; @include bds-btn-icon-stroke-color($bds-btn-primary-black-text); } } // Secondary green link button &.bds-btn--secondary.bds-btn--green { color: $bds-btn-secondary-text; background-color: $bds-btn-secondary-bg; &:hover, &:focus, &:focus-visible { color: $bds-btn-secondary-text-hover; background-color: $bds-btn-secondary-bg-hover; } &:active, &:visited { color: $bds-btn-secondary-text; background-color: $bds-btn-secondary-bg; } } // Secondary black link button &.bds-btn--secondary.bds-btn--black { color: $bds-btn-secondary-black-text; background-color: transparent; &:hover, &:focus, &:focus-visible { color: $bds-btn-secondary-black-text; background-color: $bds-btn-secondary-black-bg-hover; } &:active { color: $bds-btn-black-pressed; border-color: $bds-btn-black-pressed; @include bds-btn-icon-stroke-color($bds-btn-black-pressed); } &:visited { color: $bds-btn-secondary-black-text; background-color: transparent; } } // Tertiary green link button &.bds-btn--tertiary.bds-btn--green { color: $bds-btn-tertiary-text; background-color: $bds-btn-tertiary-bg; &:hover, &:focus, &:focus-visible { color: $bds-btn-tertiary-text-hover; } &:active, &:visited { color: $bds-btn-tertiary-text; background-color: $bds-btn-tertiary-bg; } } // Tertiary black link button &.bds-btn--tertiary.bds-btn--black { color: $bds-btn-tertiary-black-text; background-color: transparent; @include bds-btn-icon-stroke-color($bds-btn-tertiary-black-text); &:hover, &:focus, &:focus-visible { color: $bds-btn-tertiary-black-text; background-color: transparent; @include bds-btn-icon-stroke-color($bds-btn-tertiary-black-text); } &:active { color: $bds-btn-black-pressed; background-color: transparent; @include bds-btn-icon-stroke-color($bds-btn-black-pressed); } &:visited { color: $bds-btn-tertiary-black-text; background-color: transparent; @include bds-btn-icon-stroke-color($bds-btn-tertiary-black-text); } } } // --------------------------------------------------------------------------- // Dark mode (anchor) // --------------------------------------------------------------------------- @include bds-theme-mode(dark) { @include bds-btn-anchor-link-decoration-reset; // Primary green link button &.bds-btn--primary.bds-btn--green { color: $bds-btn-primary-text; background-color: $bds-btn-primary-bg; &:hover, &:focus, &:focus-visible, &:active, &:visited { color: $bds-btn-primary-text; background-color: $bds-btn-primary-bg; } } // Primary black link button - uses GREEN colors in dark mode &.bds-btn--primary.bds-btn--black { color: $bds-btn-primary-text; // Black text (same as green) background-color: $bds-btn-primary-bg; // Green 300 (same as green) @include bds-btn-icon-stroke-color($bds-btn-primary-text); &:hover, &:focus, &:focus-visible, &:active, &:visited { color: $bds-btn-primary-text; background-color: $bds-btn-primary-bg; @include bds-btn-icon-stroke-color($bds-btn-primary-text); } } // Secondary green link button - dark mode uses different green shades &.bds-btn--secondary.bds-btn--green { color: $green-300; // Green 300 in dark mode border-color: $green-300; background-color: transparent; &:hover, &:focus, &:focus-visible { color: $green-200; // Green 200 in dark mode border-color: $green-200; background-color: $green-500; // Green 500 background } &:active, &:visited { color: $green-300; border-color: $green-300; background-color: transparent; } } // Secondary black link button - uses GREEN colors in dark mode &.bds-btn--secondary.bds-btn--black { color: $green-300; // Green 300 text border-color: $green-300; // Green 300 border background-color: transparent; @include bds-btn-icon-stroke-color($green-300); &:hover, &:focus, &:focus-visible { color: $green-200; // Green 200 text border-color: $green-200; // Green 200 border background-color: $green-500; // Green 500 background @include bds-btn-icon-stroke-color($green-200); } &:active { color: $green-300; border-color: $green-300; background-color: transparent; @include bds-btn-icon-stroke-color($green-300); } &:visited { color: $green-300; border-color: $green-300; background-color: transparent; @include bds-btn-icon-stroke-color($green-300); } } // Tertiary green link button - dark mode uses different green shades &.bds-btn--tertiary.bds-btn--green { color: $green-300; background-color: transparent; &:hover, &:focus, &:focus-visible { color: $green-200; } &:active, &:visited { color: $green-300; background-color: transparent; } } // Tertiary black link button - uses GREEN colors in dark mode &.bds-btn--tertiary.bds-btn--black { color: $green-300; background-color: transparent; &:hover, &:focus, &:focus-visible { color: $green-200; } &:active, &:visited { color: $green-300; background-color: transparent; } } } } // ============================================================================= // Dark mode — anchor (green secondary / tertiary links) // ============================================================================= a.bds-btn { @include bds-theme-mode(dark) { // Secondary green link button - dark mode &.bds-btn--secondary.bds-btn--green { color: $green-300; &:hover, &:focus { color: $green-200; } &:active, &:visited { color: $green-300; } } // Tertiary green link button - dark mode &.bds-btn--tertiary.bds-btn--green { color: $green-300; &:hover, &:focus { color: $green-200; } &:active, &:visited { color: $green-300; } } } } // ============================================================================= // Base button + variants (see file header for BEM map) // ============================================================================= .bds-btn { // Layout display: inline-flex; align-items: center; justify-content: center; max-height: 40px; // Typography - Label R token (responsive) // - Desktop (lg+): 16px / 23.2px // - Mobile/Tablet: 14px / 20.1px @include type(label-r); white-space: nowrap; margin-bottom: 0; // Reset paragraph spacing from type mixin // Border border: none; border-radius: $bds-btn-border-radius; // Interaction cursor: pointer; // Required for pseudo-element background animation (shared) position: relative; overflow: hidden; z-index: 1; // Transitions (shared) transition: color $bds-btn-transition-duration $bds-btn-transition-timing, border-color $bds-btn-transition-duration $bds-btn-transition-timing, padding $bds-btn-transition-duration $bds-btn-transition-timing, gap $bds-btn-transition-duration $bds-btn-transition-timing, transform $bds-btn-transition-duration $bds-btn-transition-timing; // Background fill pseudo-element (shared structure) // Each variant sets its own background-color &::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: -1; // Start scaled to 0 from bottom - fills bottom-to-top on hover transform: scaleY(0); transform-origin: bottom center; transition: transform $bds-btn-transition-duration $bds-btn-transition-timing; } // Hover/Focus state - animate background fill (shared) &:hover:not(:disabled):not(.bds-btn--disabled), &:focus-visible:not(:disabled):not(.bds-btn--disabled) { &::before { transform: scaleY(1); } } // Active state - reset background (shared) &:active:not(:disabled):not(.bds-btn--disabled) { &::before { transform: scaleY(0); } } // Label element &__label { flex-shrink: 0; position: relative; z-index: 1; } // Icon element (SVG container) &__icon { width: 15px; height: 14px; flex-shrink: 0; transition: opacity $bds-btn-transition-duration $bds-btn-transition-timing; color: currentColor; overflow: visible; position: relative; z-index: 1; } // Arrow horizontal line - shrinks on hover/focus &__icon-line { transform-box: fill-box; // Makes transform-origin relative to element's bounding box transform-origin: right center; transform: scaleX(1); transition: transform $bds-btn-transition-duration $bds-btn-transition-timing; } // Arrow chevron - stays visible, shifts via gap change &__icon-chevron { transition: transform $bds-btn-transition-duration $bds-btn-transition-timing; } // Hover state - shrink line for all button variants &:hover:not(:disabled):not(.bds-btn--disabled), &:focus-visible:not(:disabled):not(.bds-btn--disabled) { .bds-btn__icon-line { transform: scaleX(0); } } } // ============================================================================= // Primary Variant // ============================================================================= // HOVER ANIMATION: Background fills bottom-to-top (Green 300 → Green 200) .bds-btn--primary { // Default/Enabled state colors color: $bds-btn-primary-text; background-color: $bds-btn-primary-bg; // Set the hover background color for ::before pseudo-element &::before { background-color: $bds-btn-primary-bg-hover; } // Desktop padding and gap (default - ≥1024px) padding: 8px 19px 8px 20px; gap: 16px; // No icon - symmetric padding &.bds-btn--no-icon { padding: 8px 20px; } // --------------------------------------------------------------------------- // Hover State (with icon) // --------------------------------------------------------------------------- &:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) { // Background animation handled by shared ::before pseudo-element padding: 8px 13px 8px 20px; gap: 22px; } // Hover State (no icon) - background animation only // (no padding/gap changes needed) // --------------------------------------------------------------------------- // Focus State (keyboard navigation) - with icon // --------------------------------------------------------------------------- &:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) { outline: $bds-btn-focus-border-width solid $bds-btn-primary-focus-border; outline-offset: 2px; padding: 8px 13px 8px 20px; gap: 22px; } // Focus State (no icon) - only add outline &:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon { outline: $bds-btn-focus-border-width solid $bds-btn-primary-focus-border; outline-offset: 2px; padding: 8px 20px; } // --------------------------------------------------------------------------- // Disabled State // Note: Icon is hidden via component logic when disabled // --------------------------------------------------------------------------- &:disabled, &.bds-btn--disabled { color: $bds-btn-disabled-text; background-color: $bds-btn-disabled-bg; cursor: not-allowed; pointer-events: none; // Disable background animation on disabled &::before { display: none; } } // --------------------------------------------------------------------------- // Tablet & Mobile Responsive Styles (