Files
xrpl-dev-portal/shared/components/Button/Button.scss
akcodez 44614dba9d Refactor Button Styles for Responsive Design
Updated button styles to enhance responsiveness across devices by replacing fixed breakpoints with a mixin for the xl breakpoint. Adjusted typography and padding for smaller screens to ensure consistent appearance and usability. Improved comments for clarity on the import order and design tokens.
2025-12-02 12:40:27 -08:00

1022 lines
37 KiB
SCSS

// 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 (shared)
$bds-btn-disabled-bg: $gray-200; // #E0E0E1
$bds-btn-disabled-text: $gray-500; // #838386
// 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
.bds-btn {
// Layout
display: inline-flex;
align-items: center;
justify-content: center;
max-height: 40px;
// Typography - Label R token
font-family: 'Booton', sans-serif;
font-size: 16px;
font-weight: 400;
line-height: 23.2px;
letter-spacing: 0px;
white-space: nowrap;
// 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);
}
}
// ---------------------------------------------------------------------------
// Responsive Typography (<xl breakpoint)
// ---------------------------------------------------------------------------
@include media-breakpoint-down(xl) {
// Typography - Label R token (smaller screens)
font-size: 14px;
line-height: 20.1px;
}
}
// =============================================================================
// 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 (<xl breakpoint)
// ---------------------------------------------------------------------------
@include media-breakpoint-down(xl) {
// Default/Enabled padding for smaller screens
padding: 8px 15px 8px 16px;
gap: 16px;
// No icon - symmetric padding for smaller screens
&.bds-btn--no-icon {
padding: 8px 16px;
}
// Hover state - smaller screens (with icon)
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
padding: 8px 10px 8px 16px;
gap: 21px;
}
// Focus state - smaller screens (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 10px 8px 16px;
gap: 21px;
}
// Focus state - smaller screens (no icon)
&: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 16px;
}
// Active state - smaller screens (maintains default padding)
&:active:not(:disabled):not(.bds-btn--disabled) {
padding: 8px 15px 8px 16px;
gap: 16px;
}
}
}
// =============================================================================
// Secondary Variant
// =============================================================================
// HOVER ANIMATION: Background fills bottom-to-top (Transparent → Green 100)
// Text/arrow color fades from green-400 to green-500 via currentColor
// Animation structure inherited from base .bds-btn class
.bds-btn--secondary {
// Default/Enabled state
color: $bds-btn-secondary-text;
background-color: transparent;
border: 2px solid $bds-btn-secondary-border;
// Set the hover background color for ::before pseudo-element
&::before {
background-color: $bds-btn-secondary-bg-hover;
}
// Desktop padding and gap (≥1024px) - compensate for 2px border
padding: 6px 17px 6px 18px;
gap: 16px;
// No icon - symmetric padding
&.bds-btn--no-icon {
padding: 6px 18px;
}
// ---------------------------------------------------------------------------
// Hover State
// ---------------------------------------------------------------------------
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $bds-btn-secondary-text-hover;
border-color: $bds-btn-secondary-border-hover;
padding: 6px 11px 6px 18px;
gap: 22px;
// Background animation handled by shared ::before in base class
}
&:hover:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $bds-btn-secondary-text-hover;
border-color: $bds-btn-secondary-border-hover;
}
// ---------------------------------------------------------------------------
// Focus State (keyboard navigation)
// ---------------------------------------------------------------------------
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $bds-btn-secondary-text-hover;
border: none;
outline: $bds-btn-focus-border-width solid $bds-btn-primary-focus-border;
outline-offset: 2px;
// Add 2px padding to compensate for removed border, maintain hover padding
padding: 6px 13px 6px 20px;
gap: 22px;
}
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $bds-btn-secondary-text-hover;
border: none;
outline: $bds-btn-focus-border-width solid $bds-btn-primary-focus-border;
outline-offset: 2px;
// Add 2px padding to compensate for removed border
padding: 6px 20px;
}
// ---------------------------------------------------------------------------
// Active State (being pressed)
// ---------------------------------------------------------------------------
&:active:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-secondary-text;
border-color: $bds-btn-secondary-border;
padding: 6px 17px 6px 18px;
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-secondary-disabled-text;
background-color: transparent;
border-color: $bds-btn-secondary-disabled-border;
cursor: not-allowed;
pointer-events: none;
// Disable background animation on disabled
&::before {
display: none;
}
}
// ---------------------------------------------------------------------------
// Tablet & Mobile Responsive Styles (<xl breakpoint)
// ---------------------------------------------------------------------------
@include media-breakpoint-down(xl) {
padding: 6px 13px 6px 14px;
gap: 16px;
&.bds-btn--no-icon {
padding: 6px 14px;
}
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
padding: 6px 8px 6px 14px;
gap: 21px;
}
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
border: none;
outline: $bds-btn-focus-border-width solid $bds-btn-primary-focus-border;
outline-offset: 2px;
// Add 2px padding to compensate for removed border, maintain hover padding
padding: 6px 10px 6px 16px;
gap: 21px;
}
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
border: none;
outline: $bds-btn-focus-border-width solid $bds-btn-primary-focus-border;
outline-offset: 2px;
// Add 2px padding to compensate for removed border
padding: 6px 16px;
}
&:active:not(:disabled):not(.bds-btn--disabled) {
padding: 6px 13px 6px 14px;
gap: 16px;
}
}
}
// =============================================================================
// Color Themes
// =============================================================================
// Green theme (.bds-btn--green) is the default - no overrides needed.
// Black theme (.bds-btn--black) overrides colors for all variants.
// Black theme - overrides colors for primary, secondary, and tertiary variants
.bds-btn--black {
// ---------------------------------------------------------------------------
// Black Primary Button
// ---------------------------------------------------------------------------
&.bds-btn--primary {
color: $bds-btn-primary-black-text;
background-color: $bds-btn-primary-black-bg;
// Set hover background for ::before pseudo-element
&::before {
background-color: $bds-btn-primary-black-bg-hover;
}
// Hover state - background animates, colors stay same
&:hover:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-primary-black-text;
}
// Focus state
&:focus-visible:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-primary-black-text;
outline: $bds-btn-focus-border-width solid $bds-btn-neutral-black;
outline-offset: 2px;
}
// Active state
&:active:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-primary-black-text;
}
// Disabled state - same as green disabled
&:disabled,
&.bds-btn--disabled {
color: $bds-btn-disabled-text;
background-color: $bds-btn-disabled-bg;
}
}
// ---------------------------------------------------------------------------
// Black Secondary Button
// ---------------------------------------------------------------------------
&.bds-btn--secondary {
color: $bds-btn-secondary-black-text;
border-color: $bds-btn-secondary-black-border;
// Set hover background for ::before pseudo-element
&::before {
background-color: $bds-btn-secondary-black-bg-hover;
}
// Hover state - text stays black, background fills with 15% black
&:hover:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-secondary-black-text;
border-color: $bds-btn-secondary-black-border;
}
// Focus state
&:focus-visible:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-secondary-black-text;
border: none;
outline: $bds-btn-focus-border-width solid $bds-btn-neutral-black;
outline-offset: 2px;
}
// Active state
&:active:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-secondary-black-text;
border-color: $bds-btn-secondary-black-border;
}
// Disabled state
&:disabled,
&.bds-btn--disabled {
color: $bds-btn-disabled-text;
border-color: $bds-btn-secondary-disabled-border;
}
}
// ---------------------------------------------------------------------------
// Black Tertiary Button
// ---------------------------------------------------------------------------
&.bds-btn--tertiary {
color: $bds-btn-tertiary-black-text;
// Hover state - text stays black, underline appears (override base tertiary green hover)
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $bds-btn-tertiary-black-text !important; // Ensure black color overrides green
text-decoration: underline;
padding: 8px 14px 8px 20px; // Match base tertiary hover padding
gap: 22px; // Match base tertiary hover gap
}
&:hover:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $bds-btn-tertiary-black-text !important; // Ensure black color overrides green
text-decoration: underline;
}
// Focus state
&:focus-visible:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-tertiary-black-text !important; // Ensure black color overrides green
text-decoration: underline;
border-radius: 0; // Square corners for focus outline
outline: 2px solid $bds-btn-tertiary-black-focus-outline;
outline-offset: -2px; // Negative offset brings outline closer to content
// Padding will be inherited from base tertiary focus state
}
// Active state
&:active:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-tertiary-black-text !important; // Ensure black color overrides green
text-decoration: underline;
}
// Disabled state - same as green disabled
&:disabled,
&.bds-btn--disabled {
color: $bds-btn-disabled-text;
}
// Responsive hover states - ensure black color on mobile too
@include media-breakpoint-down(xl) {
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $bds-btn-tertiary-black-text !important;
padding: 8px 11px 8px 16px; // Match base tertiary mobile hover padding
gap: 21px;
}
}
}
}
// =============================================================================
// Tertiary Variant
// =============================================================================
// NOTE: Arrow icon animation is inherited from base .bds-btn class.
// The icon color automatically follows text color via currentColor.
// Only define: colors, text decoration, padding, gap, and focus outline.
.bds-btn--tertiary {
// Default/Enabled state
color: $bds-btn-tertiary-text;
background-color: $bds-btn-tertiary-bg;
border: none;
text-decoration: none;
// Typography - Body R token (different from Primary/Secondary)
font-size: 18px;
line-height: 26.1px;
letter-spacing: -0.5px;
// Desktop padding and gap (≥1024px)
padding: 8px 20px;
gap: 16px;
// No icon - symmetric padding
&.bds-btn--no-icon {
padding: 8px 20px;
}
// Disable background animation (no ::before needed for tertiary)
&::before {
display: none;
}
// ---------------------------------------------------------------------------
// Hover State
// ---------------------------------------------------------------------------
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $bds-btn-tertiary-text-hover;
text-decoration: underline;
padding: 8px 14px 8px 20px;
gap: 22px;
}
&:hover:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $bds-btn-tertiary-text-hover;
text-decoration: underline;
}
// ---------------------------------------------------------------------------
// Focus State (keyboard navigation)
// ---------------------------------------------------------------------------
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $bds-btn-tertiary-text-hover;
text-decoration: underline;
border-radius: 0; // Square corners for focus outline
outline: 2px solid $bds-btn-tertiary-focus-outline;
outline-offset: -2px; // Negative offset brings outline closer to content
padding: 5px 2px 2px; // Top: 5px, Left/Right: 2px, Bottom: 2px
gap: 22px;
}
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $bds-btn-tertiary-text-hover;
text-decoration: underline;
border-radius: 0; // Square corners for focus outline
outline: 2px solid $bds-btn-tertiary-focus-outline;
outline-offset: -2px; // Negative offset brings outline closer to content
padding: 5px 2px 2px; // Top: 5px, Left/Right: 2px, Bottom: 2px
}
// ---------------------------------------------------------------------------
// Active State (being pressed)
// ---------------------------------------------------------------------------
&:active:not(:disabled):not(.bds-btn--disabled) {
color: $bds-btn-tertiary-text;
text-decoration: underline;
padding: 8px 20px;
gap: 16px;
}
// ---------------------------------------------------------------------------
// Disabled State
// Note: Icon is hidden via component logic when disabled
// ---------------------------------------------------------------------------
&:disabled,
&.bds-btn--disabled {
color: $bds-btn-tertiary-disabled-text;
background-color: transparent;
text-decoration: none;
cursor: not-allowed;
pointer-events: none;
// Disable background animation on disabled
&::before {
display: none;
}
}
// ---------------------------------------------------------------------------
// Tablet & Mobile Responsive Styles (<xl breakpoint)
// ---------------------------------------------------------------------------
@include media-breakpoint-down(xl) {
// Typography - Body R token (smaller screens)
font-size: 16px;
line-height: 23.2px;
letter-spacing: 0px;
padding: 8px 16px;
gap: 16px;
&.bds-btn--no-icon {
padding: 8px 16px;
}
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
padding: 8px 11px 8px 16px;
gap: 21px;
}
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $bds-btn-tertiary-text-hover;
text-decoration: underline;
border-radius: 0; // Square corners for focus outline
outline: 2px solid $bds-btn-tertiary-focus-outline;
outline-offset: -2px; // Negative offset brings outline closer to content
padding: 5px 2px 2px; // Top: 5px, Left/Right: 2px, Bottom: 2px
gap: 21px;
}
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $bds-btn-tertiary-text-hover;
text-decoration: underline;
border-radius: 0; // Square corners for focus outline
outline: 2px solid $bds-btn-tertiary-focus-outline;
outline-offset: -2px; // Negative offset brings outline closer to content
padding: 5px 2px 2px; // Top: 5px, Left/Right: 2px, Bottom: 2px
}
&:active:not(:disabled):not(.bds-btn--disabled) {
padding: 8px 16px;
gap: 16px;
}
}
}
// =============================================================================
// Dark Mode Styles - Primary and Secondary Buttons
// =============================================================================
html.dark {
.bds-btn--primary {
// Focus State (keyboard navigation) - with icon - Desktop
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
outline: $bds-btn-focus-border-width solid $white;
outline-offset: 2px;
padding: 8px 13px 8px 20px;
gap: 22px;
}
// Focus State (no icon) - Desktop
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
outline: $bds-btn-focus-border-width solid $white;
outline-offset: 2px;
padding: 8px 20px;
}
// Focus State (keyboard navigation) - with icon - Tablet & Mobile (≤1023px)
@include media-breakpoint-down(xl) {
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
outline: $bds-btn-focus-border-width solid $white;
outline-offset: 2px;
padding: 8px 10px 8px 16px;
gap: 21px;
}
// Focus State (no icon) - Tablet & Mobile
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
outline: $bds-btn-focus-border-width solid $white;
outline-offset: 2px;
padding: 8px 16px;
}
}
}
// =============================================================================
// Dark Mode Styles - Secondary Button (Green variant only)
// =============================================================================
// Based on Figma design: Enabled (Green 300), Hover/Focus (Green 200 text, Green 500 bg, Green 200 border),
// Active (Green 300), Disabled (Gray 400)
// Note: Black variant (.bds-btn--black.bds-btn--secondary) uses its own styles defined above
.bds-btn--secondary:not(.bds-btn--black) {
// ---------------------------------------------------------------------------
// Enabled State - Desktop
// ---------------------------------------------------------------------------
color: $green-300; // Green 300 - Text
border-color: $green-300; // Green 300 - Border
// Set hover background color for ::before pseudo-element
&::before {
background-color: $green-500; // Green 500 - Hover/Focus background
}
// ---------------------------------------------------------------------------
// Hover State - Desktop
// ---------------------------------------------------------------------------
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $green-200; // Green 200 - Text
border-color: $green-200; // Green 200 - Border
padding: 6px 11px 6px 18px;
gap: 22px;
// Background animation handled by shared ::before in base class
}
&:hover:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $green-200; // Green 200 - Text
border-color: $green-200; // Green 200 - Border
}
// ---------------------------------------------------------------------------
// Focus State (keyboard navigation) - Desktop
// ---------------------------------------------------------------------------
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $green-200; // Green 200 - Text
border: none;
outline: $bds-btn-focus-border-width solid $white; // White - Outline (per Figma design)
outline-offset: 2px;
// Add 2px padding to compensate for removed border, maintain hover padding
padding: 6px 13px 6px 20px;
gap: 22px;
}
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $green-200; // Green 200 - Text
border: none;
outline: $bds-btn-focus-border-width solid $white; // White - Outline (per Figma design)
outline-offset: 2px;
// Add 2px padding to compensate for removed border
padding: 6px 20px;
}
// ---------------------------------------------------------------------------
// Active State (being pressed) - Desktop
// ---------------------------------------------------------------------------
&:active:not(:disabled):not(.bds-btn--disabled) {
color: $green-300; // Green 300 - Text
border-color: $green-300; // Green 300 - Border
padding: 6px 17px 6px 18px;
gap: 16px;
// Background reset handled by shared ::before in base class
}
// ---------------------------------------------------------------------------
// Disabled State
// ---------------------------------------------------------------------------
&:disabled,
&.bds-btn--disabled {
color: $gray-400; // Gray 400 - Text
background-color: transparent;
border-color: $gray-400; // Gray 400 - Border
cursor: not-allowed;
pointer-events: none;
// Disable background animation on disabled
&::before {
display: none;
}
}
// ---------------------------------------------------------------------------
// Tablet & Mobile Responsive Styles (<xl breakpoint)
// ---------------------------------------------------------------------------
@include media-breakpoint-down(xl) {
// Hover state - smaller screens (with icon)
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $green-200; // Green 200 - Text
border-color: $green-200; // Green 200 - Border
padding: 6px 8px 6px 14px;
gap: 21px;
}
// Focus state - smaller screens (with icon)
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $green-200; // Green 200 - Text
border: none;
outline: $bds-btn-focus-border-width solid $white; // White - Outline (per Figma design)
outline-offset: 2px;
// Add 2px padding to compensate for removed border, maintain hover padding
padding: 6px 10px 6px 16px;
gap: 21px;
}
// Focus state - smaller screens (no icon)
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $green-200; // Green 200 - Text
border: none;
outline: $bds-btn-focus-border-width solid $white; // White - Outline (per Figma design)
outline-offset: 2px;
// Add 2px padding to compensate for removed border
padding: 6px 16px;
}
// Active state - smaller screens (maintains default padding)
&:active:not(:disabled):not(.bds-btn--disabled) {
color: $green-300; // Green 300 - Text
border-color: $green-300; // Green 300 - Border
padding: 6px 13px 6px 14px;
gap: 16px;
}
}
}
// =============================================================================
// Dark Mode Styles - Tertiary Button (Green variant only)
// =============================================================================
// Based on Figma design: Enabled (Green 300), Hover (Green 200), Focus (Green 200 text, Green 200 outline),
// Active (Green 300), Disabled (Gray 400)
// Note: Black variant (.bds-btn--black.bds-btn--tertiary) uses its own styles defined above
.bds-btn--tertiary:not(.bds-btn--black) {
// ---------------------------------------------------------------------------
// Enabled State - Desktop
// ---------------------------------------------------------------------------
color: $green-300; // Green 300 - Text
// ---------------------------------------------------------------------------
// Hover State - Desktop
// ---------------------------------------------------------------------------
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $green-200; // Green 200 - Text
text-decoration: underline;
padding: 8px 14px 8px 20px;
gap: 22px;
}
&:hover:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $green-200; // Green 200 - Text
text-decoration: underline;
}
// ---------------------------------------------------------------------------
// Focus State (keyboard navigation) - Desktop
// ---------------------------------------------------------------------------
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $green-200; // Green 200 - Text
text-decoration: underline;
border-radius: 0; // Square corners for focus outline
outline: 2px solid $white; // White - Outline (per Figma design)
outline-offset: -2px; // Negative offset brings outline closer to content
padding: 5px 2px 2px; // Top: 5px, Left/Right: 2px, Bottom: 2px
gap: 22px;
}
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $green-200; // Green 200 - Text
text-decoration: underline;
border-radius: 0; // Square corners for focus outline
outline: 2px solid $white; // White - Outline (per Figma design)
outline-offset: -2px; // Negative offset brings outline closer to content
padding: 5px 2px 2px; // Top: 5px, Left/Right: 2px, Bottom: 2px
}
// ---------------------------------------------------------------------------
// Active State (being pressed) - Desktop
// ---------------------------------------------------------------------------
&:active:not(:disabled):not(.bds-btn--disabled) {
color: $green-300; // Green 300 - Text
text-decoration: underline;
padding: 8px 20px;
gap: 16px;
}
// ---------------------------------------------------------------------------
// Disabled State
// ---------------------------------------------------------------------------
&:disabled,
&.bds-btn--disabled {
color: $gray-400; // Gray 400 - Text
background-color: transparent;
text-decoration: none;
cursor: not-allowed;
pointer-events: none;
}
// ---------------------------------------------------------------------------
// Tablet & Mobile Responsive Styles (<xl breakpoint)
// ---------------------------------------------------------------------------
@include media-breakpoint-down(xl) {
// Hover state - smaller screens (with icon)
&:hover:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $green-200; // Green 200 - Text
text-decoration: underline;
padding: 8px 11px 8px 16px;
gap: 21px;
}
// Focus state - smaller screens (with icon)
&:focus-visible:not(:disabled):not(.bds-btn--disabled):not(.bds-btn--no-icon) {
color: $green-200; // Green 200 - Text
text-decoration: underline;
border-radius: 0; // Square corners for focus outline
outline: 2px solid $white; // White - Outline (per Figma design)
outline-offset: -2px; // Negative offset brings outline closer to content
padding: 5px 2px 2px; // Top: 5px, Left/Right: 2px, Bottom: 2px
gap: 21px;
}
// Focus state - smaller screens (no icon)
&:focus-visible:not(:disabled):not(.bds-btn--disabled).bds-btn--no-icon {
color: $green-200; // Green 200 - Text
text-decoration: underline;
border-radius: 0; // Square corners for focus outline
outline: 2px solid $white; // White - Outline (per Figma design)
outline-offset: -2px; // Negative offset brings outline closer to content
padding: 5px 2px 2px; // Top: 5px, Left/Right: 2px, Bottom: 2px
}
// Active state - smaller screens (maintains default padding)
&:active:not(:disabled):not(.bds-btn--disabled) {
color: $green-300; // Green 300 - Text
text-decoration: underline;
padding: 8px 16px;
gap: 16px;
}
}
}
}