// 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-80: rgba(20, 20, 20, 0.8); // 80% black for hover $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; $bds-btn-primary-black-bg-hover: $bds-btn-neutral-black-80; $bds-btn-primary-black-text: $white; // Colors - Disabled State (Light Mode) // Note: Dark mode uses different colors - see html.dark section $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; // 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); // ============================================================================= // Base Button Styles // ============================================================================= // // SHARED HOVER ANIMATION: // - Background fills from bottom-to-top using ::before pseudo-element // - On unhover: background empties top-to-bottom // - Each variant defines its own ::before background-color // Anchor reset for link-based buttons // Override global anchor styles using selector chaining for specificity // Chaining .bds-btn.bds-btn increases specificity without !important // ============================================================================= // Light Mode - Anchor Button Overrides // ============================================================================= html.light { a.bds-btn.bds-btn { text-decoration: none; &:hover, &:focus, &:focus-visible, &:active, &:visited { text-decoration: none; } // 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; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $bds-btn-primary-black-text; stroke: $bds-btn-primary-black-text; } &:hover, &:focus, &:focus-visible, &:active, &:visited { color: $bds-btn-primary-black-text; background-color: $bds-btn-primary-black-bg; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $bds-btn-primary-black-text; stroke: $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, &: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; &:hover, &:focus, &:focus-visible, &:active, &:visited { color: $bds-btn-tertiary-black-text; background-color: transparent; } } } } // ============================================================================= // Dark Mode - Anchor Button Overrides // ============================================================================= html.dark { a.bds-btn.bds-btn { text-decoration: none; &:hover, &:focus, &:focus-visible, &:active, &:visited { text-decoration: none; } // 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) .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $bds-btn-primary-text; stroke: $bds-btn-primary-text; } &:hover, &:focus, &:focus-visible, &:active, &:visited { color: $bds-btn-primary-text; background-color: $bds-btn-primary-bg; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $bds-btn-primary-text; stroke: $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; &:hover, &:focus, &:focus-visible { color: $green-200; // Green 200 text border-color: $green-200; // Green 200 border background-color: $green-500; // Green 500 background } &:active, &:visited { color: $green-300; border-color: $green-300; background-color: transparent; } } // 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 - Button Element Overrides (non-anchor) // ============================================================================= // Per Figma design (dark mode): // BLACK variant in dark mode uses GREEN colors (same as green variant) // - Enabled: Text = Neutral Black (#141414), Background = Green 300 (#21E46B) // - Hover: Text = Neutral Black (#141414), Background = Green 200 (#70EE97) // - Focus: Text = Neutral Black (#141414), Background = Green 200 (#70EE97) // - Active: Text = Neutral Black (#141414), Background = Green 300 (#21E46B) // - Disabled: Text = Neutral 500 (#72777E), Background = Neutral 300 (#CAD4DF) html.dark { // Primary Black Button - Dark Mode uses GREEN colors .bds-btn.bds-btn.bds-btn--primary.bds-btn--primary.bds-btn--black { // Enabled state - GREEN colors (black text on green background) color: $bds-btn-primary-text; // #141414 - Neutral Black background-color: $bds-btn-primary-bg; // Green 300 // Hover background for ::before pseudo-element &::before { background-color: $bds-btn-primary-bg-hover; // Green 200 } // Icon colors - black to match text .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $bds-btn-primary-text; stroke: $bds-btn-primary-text; } // Hover state &:hover:not(:disabled):not(.bds-btn--disabled) { color: $bds-btn-primary-text; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $bds-btn-primary-text; stroke: $bds-btn-primary-text; } } // Focus state - white outline for dark mode &:focus-visible:not(:disabled):not(.bds-btn--disabled) { color: $bds-btn-primary-text; outline: $bds-btn-focus-border-width solid $white; outline-offset: 2px; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $bds-btn-primary-text; stroke: $bds-btn-primary-text; } } // Active state &:active:not(:disabled):not(.bds-btn--disabled) { color: $bds-btn-primary-text; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $bds-btn-primary-text; stroke: $bds-btn-primary-text; } } // Disabled state - Dark Mode specific colors &:disabled, &.bds-btn--disabled { color: $gray-500; // #72777E - Neutral 500 background-color: $gray-300; // #CAD4DF - Neutral 300 cursor: not-allowed; pointer-events: none; &::before { display: none; } } } // Secondary Black Button - Dark Mode uses GREEN colors // Per Figma design (dark mode): // - Enabled: Text = Green 300, Stroke = Green 300, Background = transparent // - Hover: Text = Green 200, Stroke = Green 200, Background = Green 500 // - Focus: Text = Green 200, Stroke = Green 200, Background = Green 500 // - Active: Text = Green 300, Stroke = Green 300, Background = transparent // - Disabled: Text = Neutral 400, Stroke = Neutral 400, Background = transparent .bds-btn.bds-btn.bds-btn--secondary.bds-btn--secondary.bds-btn--black { // Enabled state - GREEN colors color: $green-300; border-color: $green-300; background-color: transparent; // Hover background for ::before pseudo-element &::before { background-color: $green-500; } // Icon colors .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $green-300; stroke: $green-300; } // Hover state &:hover:not(:disabled):not(.bds-btn--disabled) { color: $green-200; border-color: $green-200; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $green-200; stroke: $green-200; } } // Focus state &:focus-visible:not(:disabled):not(.bds-btn--disabled) { color: $green-200; border-color: $green-200; outline: $bds-btn-focus-border-width solid $white; outline-offset: 2px; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $green-200; stroke: $green-200; } } // Active state &:active:not(:disabled):not(.bds-btn--disabled) { color: $green-300; border-color: $green-300; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $green-300; stroke: $green-300; } } // Disabled state &:disabled, &.bds-btn--disabled { color: $gray-400; // Neutral 400 border-color: $gray-400; background-color: transparent; cursor: not-allowed; pointer-events: none; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $gray-400; stroke: $gray-400; } &::before { display: none; } } } // Tertiary Black Button - Dark Mode uses GREEN colors // Per Figma design (dark mode): // - Enabled: Text = Green 300, Background = transparent // - Hover: Text = Green 200, Background = transparent // - Focus: Text = Green 200, Background = transparent // - Active: Text = Green 300, Background = transparent // - Disabled: Text = Neutral 400, Background = transparent .bds-btn.bds-btn.bds-btn--tertiary.bds-btn--tertiary.bds-btn--black { // Enabled state - GREEN colors color: $green-300; background-color: transparent; // Icon colors .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $green-300; stroke: $green-300; } // Hover state - use !important to override light mode global styles &:hover:not(:disabled):not(.bds-btn--disabled) { color: $green-200 !important; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $green-200 !important; stroke: $green-200 !important; } } // Focus state - use !important to override light mode global styles &:focus-visible:not(:disabled):not(.bds-btn--disabled) { color: $green-200 !important; outline: $bds-btn-focus-border-width solid $white; outline-offset: 2px; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $green-200 !important; stroke: $green-200 !important; } } // Active state - use !important to override light mode global styles &:active:not(:disabled):not(.bds-btn--disabled) { color: $green-300 !important; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $green-300 !important; stroke: $green-300 !important; } } // Disabled state &:disabled, &.bds-btn--disabled { color: $gray-400; // Neutral 400 background-color: transparent; cursor: not-allowed; pointer-events: none; .bds-btn__icon, .bds-btn__icon-line, .bds-btn__icon-chevron { color: $gray-400; stroke: $gray-400; } } } } .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; } // --------------------------------------------------------------------------- // Active State (being pressed) // --------------------------------------------------------------------------- &:active:not(:disabled):not(.bds-btn--disabled) { // Maintains default padding and gap padding: 8px 19px 8px 20px; gap: 16px; // Background reset handled by shared ::before in base class } // --------------------------------------------------------------------------- // 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 (