mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-12-06 17:27:57 +00:00
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.
1022 lines
37 KiB
SCSS
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;
|
|
}
|
|
}
|
|
}
|
|
} |