From c0c3bfe18515ba1f9f98d00a0b1e3acbd4b78fbc Mon Sep 17 00:00:00 2001 From: Tim Down <158919+timdown@users.noreply.github.com> Date: Thu, 13 Nov 2025 11:37:37 +0000 Subject: [PATCH] DS button CSS and component implementation plus move most --ciam variables to --ds GitOrigin-RevId: 5dd6b490a6f597892b47a89aabce748cea3e3bc6 --- .../js/shared/components/ds/ds-button.tsx | 60 ++++++++++ .../stories/shared/ds-button.stories.tsx | 37 ++++++ .../stylesheets/abstracts/mixins.scss | 5 +- .../web/frontend/stylesheets/ciam/all.scss | 4 +- .../stylesheets/ciam/ciam-colors.scss | 68 ----------- .../stylesheets/ciam/ciam-layout.scss | 34 +++--- .../stylesheets/ciam/ciam-mixins.scss | 107 ----------------- .../stylesheets/ciam/ciam-spacing.scss | 66 ----------- .../stylesheets/ciam/ciam-variables.scss | 8 +- services/web/frontend/stylesheets/ds/all.scss | 7 ++ .../web/frontend/stylesheets/ds/border.scss | 13 +++ .../web/frontend/stylesheets/ds/colors.scss | 83 +++++++++++++ .../stylesheets/ds/components/all.scss | 1 + .../stylesheets/ds/components/button.scss | 81 +++++++++++++ .../web/frontend/stylesheets/ds/mixins.scss | 109 ++++++++++++++++++ .../web/frontend/stylesheets/ds/spacing.scss | 31 +++++ .../web/frontend/stylesheets/ds/theme.scss | 30 +++++ .../frontend/stylesheets/ds/typography.scss | 34 ++++++ 18 files changed, 508 insertions(+), 270 deletions(-) create mode 100644 services/web/frontend/js/shared/components/ds/ds-button.tsx create mode 100644 services/web/frontend/stories/shared/ds-button.stories.tsx delete mode 100644 services/web/frontend/stylesheets/ciam/ciam-colors.scss delete mode 100644 services/web/frontend/stylesheets/ciam/ciam-mixins.scss delete mode 100644 services/web/frontend/stylesheets/ciam/ciam-spacing.scss create mode 100644 services/web/frontend/stylesheets/ds/all.scss create mode 100644 services/web/frontend/stylesheets/ds/border.scss create mode 100644 services/web/frontend/stylesheets/ds/colors.scss create mode 100644 services/web/frontend/stylesheets/ds/components/all.scss create mode 100644 services/web/frontend/stylesheets/ds/components/button.scss create mode 100644 services/web/frontend/stylesheets/ds/mixins.scss create mode 100644 services/web/frontend/stylesheets/ds/spacing.scss create mode 100644 services/web/frontend/stylesheets/ds/theme.scss create mode 100644 services/web/frontend/stylesheets/ds/typography.scss diff --git a/services/web/frontend/js/shared/components/ds/ds-button.tsx b/services/web/frontend/js/shared/components/ds/ds-button.tsx new file mode 100644 index 0000000000..9fd8342f60 --- /dev/null +++ b/services/web/frontend/js/shared/components/ds/ds-button.tsx @@ -0,0 +1,60 @@ +import { forwardRef, ReactNode } from 'react' +import { Button, ButtonProps } from 'react-bootstrap' + +type DSButtonProps = Pick< + ButtonProps, + | 'children' + | 'disabled' + | 'href' + | 'id' + | 'target' + | 'rel' + | 'onClick' + | 'onMouseDown' + | 'onMouseOver' + | 'onMouseOut' + | 'onFocus' + | 'onBlur' + | 'size' + | 'active' + | 'type' +> & { + leadingIcon?: ReactNode + trailingIcon?: ReactNode + variant?: 'primary' | 'secondary' | 'tertiary' | 'danger' +} + +const DSButton = forwardRef( + ( + { + children, + leadingIcon, + trailingIcon, + variant = 'primary', + size, + ...props + }, + ref + ) => { + return ( + + ) + } +) + +DSButton.displayName = 'DSButton' + +export default DSButton diff --git a/services/web/frontend/stories/shared/ds-button.stories.tsx b/services/web/frontend/stories/shared/ds-button.stories.tsx new file mode 100644 index 0000000000..359e483cb9 --- /dev/null +++ b/services/web/frontend/stories/shared/ds-button.stories.tsx @@ -0,0 +1,37 @@ +import { Meta } from '@storybook/react' +import { figmaDesignUrl } from '../../../.storybook/utils/figma-design-url' +import DSButton from '@/shared/components/ds/ds-button' + +type Args = React.ComponentProps + +export const Button = (args: Args) => { + return +} + +const meta: Meta = { + title: 'Shared / Components / DS Button', + component: DSButton, + args: { + children: 'Button', + }, + argTypes: { + size: { + control: 'radio', + options: ['lg', 'md', 'sm'], + }, + variant: { + control: 'radio', + options: ['primary', 'secondary', 'tertiary', 'danger'], + }, + }, + parameters: { + controls: { + include: ['children', 'disabled', 'size', 'variant'], + }, + ...figmaDesignUrl( + 'https://www.figma.com/design/aJQlecvqCS9Ry8b6JA1lQN/DS---Components?node-id=4565-2932&m=dev' + ), + }, +} + +export default meta diff --git a/services/web/frontend/stylesheets/abstracts/mixins.scss b/services/web/frontend/stylesheets/abstracts/mixins.scss index 6c61d20e5e..1a1080491d 100644 --- a/services/web/frontend/stylesheets/abstracts/mixins.scss +++ b/services/web/frontend/stylesheets/abstracts/mixins.scss @@ -21,7 +21,8 @@ $borderless: true, $disabled-color: $content-disabled, $disabled-background: $bg-light-disabled, - $disabled-border: $bg-light-disabled + $disabled-border: $disabled-background, + $active-background: $hover-background ) { --bs-btn-color: #{$color}; --bs-btn-bg: #{$background}; @@ -30,7 +31,7 @@ --bs-btn-hover-bg: #{$hover-background}; --bs-btn-hover-border-color: #{$hover-border}; --bs-btn-active-color: #{$color}; - --bs-btn-active-bg: #{$hover-background}; + --bs-btn-active-bg: #{$active-background}; --bs-btn-active-border-color: #{$hover-border}; --bs-btn-disabled-color: #{$disabled-color}; --bs-btn-disabled-bg: #{$disabled-background}; diff --git a/services/web/frontend/stylesheets/ciam/all.scss b/services/web/frontend/stylesheets/ciam/all.scss index 8c890eb90d..d210b6d1df 100644 --- a/services/web/frontend/stylesheets/ciam/all.scss +++ b/services/web/frontend/stylesheets/ciam/all.scss @@ -1,5 +1,3 @@ -@import 'ciam-colors'; +@import '../ds/all'; // DS design system styles @import 'ciam-layout'; -@import 'ciam-mixins'; -@import 'ciam-spacing'; @import 'ciam-variables'; diff --git a/services/web/frontend/stylesheets/ciam/ciam-colors.scss b/services/web/frontend/stylesheets/ciam/ciam-colors.scss deleted file mode 100644 index a48203a34b..0000000000 --- a/services/web/frontend/stylesheets/ciam/ciam-colors.scss +++ /dev/null @@ -1,68 +0,0 @@ -.ciam-enabled { - --ciam-color-neutral-50: #fafafa; - --ciam-color-neutral-100: #f2f2f2; - --ciam-color-neutral-200: #e6e6e6; - --ciam-color-neutral-300: #d6d6d6; - --ciam-color-neutral-400: #c7c7c7; - --ciam-color-neutral-500: #b5b5b5; - --ciam-color-neutral-600: #a1a1a1; - --ciam-color-neutral-700: #8a8a8a; - --ciam-color-neutral-800: #6b6b6b; - --ciam-color-neutral-900: #383838; - --ciam-color-neutral-950: #262626; - --ciam-color-green-50: #f2f8f5; - --ciam-color-green-100: #e3f2eb; - --ciam-color-green-200: #c0e7d6; - --ciam-color-green-300: #8adbb7; - --ciam-color-green-400: #38cc89; - --ciam-color-green-500: #26b072; - --ciam-color-green-600: #158954; - --ciam-color-green-700: #19754c; - --ciam-color-green-800: #196241; - --ciam-color-green-900: #164630; - --ciam-color-green-950: #112c20; - --ciam-color-yellow-50: #fffaeb; - --ciam-color-yellow-100: #fff7db; - --ciam-color-yellow-200: #ffeeb8; - --ciam-color-yellow-300: #ffe58f; - --ciam-color-yellow-400: #ffda61; - --ciam-color-yellow-500: #ffcc20; - --ciam-color-yellow-600: #f0b800; - --ciam-color-yellow-700: #d1a000; - --ciam-color-yellow-800: #ad8500; - --ciam-color-yellow-900: #806200; - --ciam-color-yellow-950: #574200; - --ciam-color-red-50: #fff5f7; - --ciam-color-red-100: #fee7eb; - --ciam-color-red-200: #fdc9d3; - --ciam-color-red-300: #fba7b7; - --ciam-color-red-400: #f97b92; - --ciam-color-red-500: #f51d43; - --ciam-color-red-600: #e60a32; - --ciam-color-red-700: #c3092b; - --ciam-color-red-800: #a10723; - --ciam-color-red-900: #75051a; - --ciam-color-red-950: #530412; - --ciam-color-blue-50: #f7fafd; - --ciam-color-blue-100: #ecf2f9; - --ciam-color-blue-200: #d4e3f2; - --ciam-color-blue-300: #bdd4ea; - --ciam-color-blue-400: #a2c3e2; - --ciam-color-blue-500: #7facd7; - --ciam-color-blue-600: #5893cb; - --ciam-color-blue-700: #3470a8; - --ciam-color-blue-800: #2b5d8c; - --ciam-color-blue-900: #1e4161; - --ciam-color-blue-950: #17314a; - --ciam-color-teal-50: #f1f8f8; - --ciam-color-teal-100: #e3f2f1; - --ciam-color-teal-200: #c1e2df; - --ciam-color-teal-300: #9ed1cd; - --ciam-color-teal-400: #6dbab4; - --ciam-color-teal-500: #4a9d96; - --ciam-color-teal-600: #438e88; - --ciam-color-teal-700: #3b7d77; - --ciam-color-teal-800: #2f6460; - --ciam-color-teal-900: #244c49; - --ciam-color-teal-950: #193432; -} diff --git a/services/web/frontend/stylesheets/ciam/ciam-layout.scss b/services/web/frontend/stylesheets/ciam/ciam-layout.scss index 6934702b47..05e044eb70 100644 --- a/services/web/frontend/stylesheets/ciam/ciam-layout.scss +++ b/services/web/frontend/stylesheets/ciam/ciam-layout.scss @@ -1,18 +1,16 @@ -@import 'ciam-mixins'; - .ciam-layout { - padding: var(--ciam-spacing-350); + padding: var(--ds-spacing-350); display: flex; min-height: 100vh; flex-direction: column; - @include ciam-body-md-regular; + @include ds-body-md-regular; } .ciam-enabled { - font-family: var(--ciam-font-family-sans), sans-serif; - color: var(--ciam-color-text-primary); - font-size: var(--ciam-font-size-400); + font-family: var(--ds-font-family-sans), sans-serif; + color: var(--ds-color-text-primary); + font-size: var(--ds-font-size-400); line-height: 1.5; .ciam-container { @@ -25,48 +23,48 @@ background-size: contain; height: 64px; width: 130px; - margin: var(--ciam-spacing-350) auto; + margin: var(--ds-spacing-350) auto; display: block; @include media-breakpoint-up(sm) { - margin: var(--ciam-spacing-350) var(--ciam-spacing-800); + margin: var(--ds-spacing-350) var(--ds-spacing-800); } } h1 { - @include ciam-heading-sm-semibold; + @include ds-heading-sm-semibold; } .ciam-card { box-shadow: 0 4px 6px -4px rgb(0 0 0 / 10%), 0 1px 29px -3px rgb(0 0 0 / 16%); - padding: var(--ciam-spacing-800) var(--ciam-spacing-400); - border-radius: var(--ciam-border-radius-400); + padding: var(--ds-spacing-800) var(--ds-spacing-400); + border-radius: var(--ds-border-radius-400); max-width: 460px; - margin: var(--ciam-spacing-400) auto; + margin: var(--ds-spacing-400) auto; @include media-breakpoint-up(sm) { - padding: var(--ciam-spacing-1300); + padding: var(--ds-spacing-1300); } } footer { display: flex; - gap: var(--ciam-spacing-600); + gap: var(--ds-spacing-600); text-transform: uppercase; justify-content: center; - margin: var(--ciam-spacing-350) auto; + margin: var(--ds-spacing-350) auto; @include media-breakpoint-up(sm) { - margin: var(--ciam-spacing-350) var(--ciam-spacing-800); + margin: var(--ds-spacing-350) var(--ds-spacing-800); justify-content: start; } a { text-decoration: none; - @include ciam-body-sm-regular; + @include ds-body-sm-regular; } } } diff --git a/services/web/frontend/stylesheets/ciam/ciam-mixins.scss b/services/web/frontend/stylesheets/ciam/ciam-mixins.scss deleted file mode 100644 index 781ec1e200..0000000000 --- a/services/web/frontend/stylesheets/ciam/ciam-mixins.scss +++ /dev/null @@ -1,107 +0,0 @@ -@mixin ciam-body-xs-regular() { - font-size: 0.75rem; - font-weight: 400; - line-height: 1.25rem; -} - -@mixin ciam-body-xs-semibold() { - font-size: 0.75rem; - font-weight: 600; - line-height: 1.25rem; -} - -@mixin ciam-body-sm-regular() { - font-size: 0.875rem; - font-weight: 400; - line-height: 1.25rem; -} - -@mixin ciam-body-sm-semibold() { - font-size: 0.875rem; - font-weight: 600; - line-height: 1.25rem; -} - -@mixin ciam-body-md-regular() { - font-size: 1rem; - font-weight: 400; - line-height: 1.5rem; -} - -@mixin ciam-body-md-semibold() { - font-size: 1rem; - font-weight: 600; - line-height: 1.5rem; -} - -@mixin ciam-body-lg-regular() { - font-size: 1.125rem; - font-weight: 400; - line-height: 1.75rem; -} - -@mixin ciam-body-lg-semibold() { - font-size: 1.125rem; - font-weight: 600; - line-height: 1.75rem; -} - -@mixin ciam-heading-xs-regular() { - font-size: 1.125rem; - font-weight: 400; - line-height: 1.5rem; -} - -@mixin ciam-heading-xs-semibold() { - font-size: 1.125rem; - font-weight: 600; - line-height: 1.5rem; -} - -@mixin ciam-heading-sm-regular() { - font-size: 1.25rem; - font-weight: 400; - line-height: 1.75rem; -} - -@mixin ciam-heading-sm-semibold() { - font-size: 1.25rem; - font-weight: 600; - line-height: 1.75rem; -} - -@mixin ciam-heading-md-regular() { - font-size: 1.5rem; - font-weight: 400; - line-height: 2rem; -} - -@mixin ciam-heading-md-semibold() { - font-size: 1.5rem; - font-weight: 600; - line-height: 2rem; -} - -@mixin ciam-heading-lg-regular() { - font-size: 2rem; - font-weight: 400; - line-height: 2.5rem; -} - -@mixin ciam-heading-lg-semibold() { - font-size: 2rem; - font-weight: 600; - line-height: 2.5rem; -} - -@mixin ciam-heading-xl-regular() { - font-size: 2.5rem; - font-weight: 400; - line-height: 3rem; -} - -@mixin ciam-heading-xl-semibold() { - font-size: 2.5rem; - font-weight: 600; - line-height: 3rem; -} diff --git a/services/web/frontend/stylesheets/ciam/ciam-spacing.scss b/services/web/frontend/stylesheets/ciam/ciam-spacing.scss deleted file mode 100644 index 5002f6badf..0000000000 --- a/services/web/frontend/stylesheets/ciam/ciam-spacing.scss +++ /dev/null @@ -1,66 +0,0 @@ -.ciam-enabled { - --ciam-font-weight-regular: 400; - --ciam-font-weight-medium: 500; - --ciam-font-weight-semibold: 600; - --ciam-font-weight-bold: 700; - --ciam-font-family-sans: inter, sans-serif; - --ciam-spacing-50: 2px; - --ciam-spacing-100: 4px; - --ciam-spacing-150: 6px; - --ciam-spacing-200: 8px; - --ciam-spacing-250: 10px; - --ciam-spacing-300: 12px; - --ciam-spacing-350: 14px; - --ciam-spacing-400: 16px; - --ciam-spacing-500: 20px; - --ciam-spacing-600: 24px; - --ciam-spacing-700: 28px; - --ciam-spacing-800: 32px; - --ciam-spacing-900: 36px; - --ciam-spacing-1000: 40px; - --ciam-spacing-1100: 44px; - --ciam-spacing-1200: 48px; - --ciam-spacing-1300: 52px; - --ciam-spacing-1400: 56px; - --ciam-spacing-1500: 60px; - --ciam-spacing-1600: 64px; - --ciam-spacing-1700: 68px; - --ciam-spacing-1800: 72px; - --ciam-spacing-1900: 76px; - --ciam-spacing-2000: 80px; - --ciam-spacing-2100: 84px; - --ciam-spacing-2200: 88px; - --ciam-spacing-2300: 92px; - --ciam-spacing-2400: 96px; - --ciam-base-unit: 4px; - --ciam-font-size-300: 12px; - --ciam-font-size-350: 14px; - --ciam-font-size-400: 16px; - --ciam-font-size-450: 18px; - --ciam-font-size-500: 20px; - --ciam-font-size-600: 24px; - --ciam-font-size-700: 28px; - --ciam-font-size-800: 32px; - --ciam-font-size-1000: 40px; - --ciam-font-size-1400: 56px; - --ciam-font-size-1800: 72px; - --ciam-font-line-height-400: 16px; - --ciam-font-line-height-500: 20px; - --ciam-font-line-height-600: 24px; - --ciam-font-line-height-700: 28px; - --ciam-font-line-height-800: 32px; - --ciam-font-line-height-900: 36px; - --ciam-font-line-height-1000: 40px; - --ciam-font-line-height-1200: 48px; - --ciam-font-line-height-1600: 64px; - --ciam-font-line-height-1800: 72px; - --ciam-border-width-25: 1px; - --ciam-border-width-50: 2px; - --ciam-border-radius-50: 2px; - --ciam-border-radius-100: 4px; - --ciam-border-radius-200: 8px; - --ciam-border-radius-300: 12px; - --ciam-border-radius-400: 16px; - --ciam-border-radius-600: 24px; - --ciam-border-radius-full: 9999px; -} diff --git a/services/web/frontend/stylesheets/ciam/ciam-variables.scss b/services/web/frontend/stylesheets/ciam/ciam-variables.scss index 00806c2a99..032100a4e6 100644 --- a/services/web/frontend/stylesheets/ciam/ciam-variables.scss +++ b/services/web/frontend/stylesheets/ciam/ciam-variables.scss @@ -1,17 +1,13 @@ // TODO: Replace `fuchsia` by the correct colors. .ciam-enabled { - // Base variables - --ciam-color-text-secondary: var(--ciam-color-neutral-800); - --ciam-color-text-primary: var(--ciam-color-neutral-900); - // Links // used in services/web/frontend/stylesheets/base/links.scss - --link-color: var(--ciam-color-text-secondary); + --link-color: var(--ds-color-text-secondary); --link-hover-color: fuchsia; // TODO: validate that this is correct - --link-visited-color: var(--ciam-color-text-secondary); + --link-visited-color: var(--ds-color-text-secondary); --link-color-dark: fuchsia; --link-hover-color-dark: fuchsia; --link-visited-color-dark: fuchsia; diff --git a/services/web/frontend/stylesheets/ds/all.scss b/services/web/frontend/stylesheets/ds/all.scss new file mode 100644 index 0000000000..95bfd7b243 --- /dev/null +++ b/services/web/frontend/stylesheets/ds/all.scss @@ -0,0 +1,7 @@ +@import 'colors'; +@import 'typography'; +@import 'spacing'; +@import 'border'; +@import 'theme'; +@import 'mixins'; +@import 'components/all'; diff --git a/services/web/frontend/stylesheets/ds/border.scss b/services/web/frontend/stylesheets/ds/border.scss new file mode 100644 index 0000000000..005c63e1ad --- /dev/null +++ b/services/web/frontend/stylesheets/ds/border.scss @@ -0,0 +1,13 @@ +:root { + --ds-border-width-25: 1px; + --ds-border-width-50: 2px; + + // Border radius + --ds-border-radius-full: 9999px; + --ds-border-radius-50: 2px; + --ds-border-radius-100: 4px; + --ds-border-radius-200: 8px; + --ds-border-radius-300: 12px; + --ds-border-radius-400: 16px; + --ds-border-radius-600: 24px; +} diff --git a/services/web/frontend/stylesheets/ds/colors.scss b/services/web/frontend/stylesheets/ds/colors.scss new file mode 100644 index 0000000000..6f52e2d0c1 --- /dev/null +++ b/services/web/frontend/stylesheets/ds/colors.scss @@ -0,0 +1,83 @@ +:root { + // Neutral/grey + --ds-color-neutral-50: #fafafa; + --ds-color-neutral-100: #f2f2f2; + --ds-color-neutral-200: #e6e6e6; + --ds-color-neutral-300: #d6d6d6; + --ds-color-neutral-400: #c7c7c7; + --ds-color-neutral-500: #b5b5b5; + --ds-color-neutral-600: #a1a1a1; + --ds-color-neutral-700: #8a8a8a; + --ds-color-neutral-800: #6b6b6b; + --ds-color-neutral-900: #383838; + --ds-color-neutral-950: #262626; + + // Green + --ds-color-green-50: #f2f8f5; + --ds-color-green-100: #e3f2eb; + --ds-color-green-200: #c0e7d6; + --ds-color-green-300: #8adbb7; + --ds-color-green-400: #38cc89; + --ds-color-green-500: #26b072; + --ds-color-green-600: #158954; + --ds-color-green-700: #19754c; + --ds-color-green-800: #196241; + --ds-color-green-900: #164630; + --ds-color-green-950: #112c20; + + // Yellow + --ds-color-yellow-50: #fffaeb; + --ds-color-yellow-100: #fff7db; + --ds-color-yellow-200: #ffeeb8; + --ds-color-yellow-300: #ffe58f; + --ds-color-yellow-400: #ffda61; + --ds-color-yellow-500: #ffcc20; + --ds-color-yellow-600: #f0b800; + --ds-color-yellow-700: #d1a000; + --ds-color-yellow-800: #ad8500; + --ds-color-yellow-900: #806200; + --ds-color-yellow-950: #574200; + + // Red + --ds-color-red-50: #fff5f7; + --ds-color-red-100: #fee7eb; + --ds-color-red-200: #fdc9d3; + --ds-color-red-300: #fba7b7; + --ds-color-red-400: #f97b92; + --ds-color-red-500: #f51d43; + --ds-color-red-600: #e60a32; + --ds-color-red-700: #c3092b; + --ds-color-red-800: #a10723; + --ds-color-red-900: #75051a; + --ds-color-red-950: #530412; + + // Blue + --ds-color-blue-50: #f7fafd; + --ds-color-blue-100: #ecf2f9; + --ds-color-blue-200: #d4e3f2; + --ds-color-blue-300: #bdd4ea; + --ds-color-blue-400: #a2c3e2; + --ds-color-blue-500: #7facd7; + --ds-color-blue-600: #5893cb; + --ds-color-blue-700: #3470a8; + --ds-color-blue-800: #2b5d8c; + --ds-color-blue-900: #1e4161; + --ds-color-blue-950: #17314a; + + // Teal + --ds-color-teal-50: #f1f8f8; + --ds-color-teal-100: #e3f2f1; + --ds-color-teal-200: #c1e2df; + --ds-color-teal-300: #9ed1cd; + --ds-color-teal-400: #6dbab4; + --ds-color-teal-500: #4a9d96; + --ds-color-teal-600: #438e88; + --ds-color-teal-700: #3b7d77; + --ds-color-teal-800: #2f6460; + --ds-color-teal-900: #244c49; + --ds-color-teal-950: #193432; + + // Black and white + --ds-color-white: #fff; + --ds-color-black: #000; +} diff --git a/services/web/frontend/stylesheets/ds/components/all.scss b/services/web/frontend/stylesheets/ds/components/all.scss new file mode 100644 index 0000000000..2d43224818 --- /dev/null +++ b/services/web/frontend/stylesheets/ds/components/all.scss @@ -0,0 +1 @@ +@import 'button'; diff --git a/services/web/frontend/stylesheets/ds/components/button.scss b/services/web/frontend/stylesheets/ds/components/button.scss new file mode 100644 index 0000000000..915537ffa8 --- /dev/null +++ b/services/web/frontend/stylesheets/ds/components/button.scss @@ -0,0 +1,81 @@ +.btn.btn-ds { + --bs-btn-font-family: var(--ds-font-family-sans); + --bs-btn-border-radius: var(--ds-border-radius-200); + + &:focus-visible { + outline: 2px solid var(--ds-color-yellow-500); + outline-offset: 2px; + box-shadow: none; + } + + // Default size + @include ol-button-size( + $font-size: var(--ds-font-size-400), + $line-height: var(--ds-font-line-height-600), + $padding-x: var(--ds-spacing-400), + $padding-y: var(--ds-spacing-100) + ); + + &.btn-lg { + @include ol-button-size( + $font-size: var(--ds-font-size-400), + $line-height: var(--ds-font-line-height-600), + $padding-x: var(--ds-spacing-400), + $padding-y: var(--ds-spacing-250) + ); + } + + &.btn-sm { + @include ol-button-size( + $font-size: var(--ds-font-size-350), + $line-height: var(--ds-font-line-height-500), + $padding-x: var(--ds-spacing-200), + $padding-y: var(--ds-spacing-100) + ); + } + + // Variants + &.btn-primary { + @include ol-button-variant( + $color: var(--ds-color-white), + $background: var(--ds-color-neutral-950), + $hover-background: var(--ds-color-neutral-900), + $active-background: var(--ds-color-neutral-800), + $disabled-color: var(--ds-color-neutral-700), + $disabled-background: var(--ds-color-neutral-100) + ); + } + + &.btn-secondary { + @include ol-button-variant( + $color: var(--ds-color-neutral-950), + $background: var(--ds-color-neutral-200), + $hover-background: var(--ds-color-neutral-300), + $active-background: var(--ds-color-neutral-400), + $disabled-color: var(--ds-color-neutral-700), + $disabled-background: var(--ds-color-neutral-100) + ); + } + + &.btn-tertiary { + @include ol-button-variant( + $color: var(--ds-color-neutral-950), + $background: var(--ds-color-white), + $hover-background: var(--ds-color-neutral-100), + $active-background: var(--ds-color-neutral-200), + $disabled-color: var(--ds-color-neutral-700), + $disabled-background: var(--ds-color-neutral-100) + ); + } + + &.btn-danger { + @include ol-button-variant( + $color: var(--ds-color-white), + $background: var(--ds-color-red-700), + $hover-background: var(--ds-color-red-800), + $active-background: var(--ds-color-red-900), + $disabled-color: var(--ds-color-neutral-700), + $disabled-background: var(--ds-color-neutral-100) + ); + } +} diff --git a/services/web/frontend/stylesheets/ds/mixins.scss b/services/web/frontend/stylesheets/ds/mixins.scss new file mode 100644 index 0000000000..b50207c20f --- /dev/null +++ b/services/web/frontend/stylesheets/ds/mixins.scss @@ -0,0 +1,109 @@ +// Typography mixins for consistent text styles + +@mixin ds-body-xs-regular() { + font-size: var(--ds-font-size-300); + font-weight: var(--ds-font-weight-regular); + line-height: var(--ds-font-line-height-500); +} + +@mixin ds-body-xs-semibold() { + font-size: var(--ds-font-size-300); + font-weight: var(--ds-font-weight-semibold); + line-height: var(--ds-font-line-height-500); +} + +@mixin ds-body-sm-regular() { + font-size: var(--ds-font-size-350); + font-weight: var(--ds-font-weight-regular); + line-height: var(--ds-font-line-height-500); +} + +@mixin ds-body-sm-semibold() { + font-size: var(--ds-font-size-350); + font-weight: var(--ds-font-weight-semibold); + line-height: var(--ds-font-line-height-500); +} + +@mixin ds-body-md-regular() { + font-size: var(--ds-font-size-400); + font-weight: var(--ds-font-weight-regular); + line-height: var(--ds-font-line-height-600); +} + +@mixin ds-body-md-semibold() { + font-size: var(--ds-font-size-400); + font-weight: var(--ds-font-weight-semibold); + line-height: var(--ds-font-line-height-600); +} + +@mixin ds-body-lg-regular() { + font-size: var(--ds-font-size-450); + font-weight: var(--ds-font-weight-regular); + line-height: var(--ds-font-line-height-700); +} + +@mixin ds-body-lg-semibold() { + font-size: var(--ds-font-size-450); + font-weight: var(--ds-font-weight-semibold); + line-height: var(--ds-font-line-height-700); +} + +@mixin ds-heading-xs-regular() { + font-size: var(--ds-font-size-450); + font-weight: var(--ds-font-weight-regular); + line-height: var(--ds-font-line-height-600); +} + +@mixin ds-heading-xs-semibold() { + font-size: var(--ds-font-size-450); + font-weight: var(--ds-font-weight-semibold); + line-height: var(--ds-font-line-height-600); +} + +@mixin ds-heading-sm-regular() { + font-size: var(--ds-font-size-500); + font-weight: var(--ds-font-weight-regular); + line-height: var(--ds-font-line-height-700); +} + +@mixin ds-heading-sm-semibold() { + font-size: var(--ds-font-size-500); + font-weight: var(--ds-font-weight-semibold); + line-height: var(--ds-font-line-height-700); +} + +@mixin ds-heading-md-regular() { + font-size: var(--ds-font-size-600); + font-weight: var(--ds-font-weight-regular); + line-height: var(--ds-font-line-height-800); +} + +@mixin ds-heading-md-semibold() { + font-size: var(--ds-font-size-600); + font-weight: var(--ds-font-weight-semibold); + line-height: var(--ds-font-line-height-800); +} + +@mixin ds-heading-lg-regular() { + font-size: var(--ds-font-size-800); + font-weight: var(--ds-font-weight-regular); + line-height: var(--ds-font-line-height-1000); +} + +@mixin ds-heading-lg-semibold() { + font-size: var(--ds-font-size-800); + font-weight: var(--ds-font-weight-semibold); + line-height: var(--ds-font-line-height-1000); +} + +@mixin ds-heading-xl-regular() { + font-size: var(--ds-font-size-1000); + font-weight: var(--ds-font-weight-regular); + line-height: var(--ds-font-line-height-1200); +} + +@mixin ds-heading-xl-semibold() { + font-size: var(--ds-font-size-1000); + font-weight: var(--ds-font-weight-semibold); + line-height: var(--ds-font-line-height-1200); +} diff --git a/services/web/frontend/stylesheets/ds/spacing.scss b/services/web/frontend/stylesheets/ds/spacing.scss new file mode 100644 index 0000000000..10410ee4d0 --- /dev/null +++ b/services/web/frontend/stylesheets/ds/spacing.scss @@ -0,0 +1,31 @@ +:root { + --ds-base-unit: 4px; + --ds-spacing-50: 2px; + --ds-spacing-100: 4px; + --ds-spacing-150: 6px; + --ds-spacing-200: 8px; + --ds-spacing-250: 10px; + --ds-spacing-300: 12px; + --ds-spacing-350: 14px; + --ds-spacing-400: 16px; + --ds-spacing-500: 20px; + --ds-spacing-600: 24px; + --ds-spacing-700: 28px; + --ds-spacing-800: 32px; + --ds-spacing-900: 36px; + --ds-spacing-1000: 40px; + --ds-spacing-1100: 44px; + --ds-spacing-1200: 48px; + --ds-spacing-1300: 52px; + --ds-spacing-1400: 56px; + --ds-spacing-1500: 60px; + --ds-spacing-1600: 64px; + --ds-spacing-1700: 68px; + --ds-spacing-1800: 72px; + --ds-spacing-1900: 76px; + --ds-spacing-2000: 80px; + --ds-spacing-2100: 84px; + --ds-spacing-2200: 88px; + --ds-spacing-2300: 92px; + --ds-spacing-2400: 96px; +} diff --git a/services/web/frontend/stylesheets/ds/theme.scss b/services/web/frontend/stylesheets/ds/theme.scss new file mode 100644 index 0000000000..90e770c10a --- /dev/null +++ b/services/web/frontend/stylesheets/ds/theme.scss @@ -0,0 +1,30 @@ +:root { + // Default to the light theme + --ds-color-bg-default: var(--ds-color-white); + --ds-color-text-primary: var(--ds-color-neutral-900); + --ds-color-text-secondary: var(--ds-color-neutral-800); + --ds-color-text-disabled: var(--ds-color-neutral-500); + --ds-color-text-danger-default: var(--ds-color-red-700); + --ds-color-text-danger-hover: var(--ds-color-red-800); + --ds-color-text-warning-default: var(--ds-color-yellow-900); + --ds-color-text-warning-hover: var(--ds-color-yellow-950); + --ds-color-text-info-default: var(--ds-color-blue-700); + --ds-color-text-info-hover: var(--ds-color-blue-800); + --ds-color-text-success-default: var(--ds-color-green-700); + --ds-color-text-success-hover: var(--ds-color-green-800); + + .ds-theme-dark { + --ds-color-bg-default: var(--ds-color-neutral-950); + --ds-color-text-primary: var(--ds-color-white); + --ds-color-text-secondary: var(--ds-color-neutral-50); + --ds-color-text-disabled: var(--ds-color-neutral-500); + --ds-color-text-danger-default: var(--ds-color-red-700); + --ds-color-text-danger-hover: var(--ds-color-red-800); + --ds-color-text-warning-default: var(--ds-color-yellow-900); + --ds-color-text-warning-hover: var(--ds-color-yellow-950); + --ds-color-text-info-default: var(--ds-color-blue-700); + --ds-color-text-info-hover: var(--ds-color-blue-800); + --ds-color-text-success-default: var(--ds-color-green-700); + --ds-color-text-success-hover: var(--ds-color-green-800); + } +} diff --git a/services/web/frontend/stylesheets/ds/typography.scss b/services/web/frontend/stylesheets/ds/typography.scss new file mode 100644 index 0000000000..86f1024269 --- /dev/null +++ b/services/web/frontend/stylesheets/ds/typography.scss @@ -0,0 +1,34 @@ +:root { + --ds-font-family-sans: 'Inter'; + + // Font weight + --ds-font-weight-regular: 400; + --ds-font-weight-medium: 500; + --ds-font-weight-semibold: 600; + --ds-font-weight-bold: 700; + + // Font size + --ds-font-size-300: 0.75rem; // 12px + --ds-font-size-350: 0.875rem; // 14px + --ds-font-size-400: 1rem; // 16px + --ds-font-size-450: 1.125rem; // 18px + --ds-font-size-500: 1.25rem; // 20px + --ds-font-size-600: 1.5rem; // 24px + --ds-font-size-700: 1.75rem; // 28px + --ds-font-size-800: 2rem; // 32px + --ds-font-size-1000: 2.5rem; // 40px + --ds-font-size-1400: 3.5rem; // 56px + --ds-font-size-1800: 4.5rem; // 72px + + // Line height + --ds-font-line-height-400: 1rem; // 16px + --ds-font-line-height-500: 1.25rem; // 20px + --ds-font-line-height-600: 1.5rem; // 24px + --ds-font-line-height-700: 1.75rem; // 28px + --ds-font-line-height-800: 2rem; // 32px + --ds-font-line-height-1000: 2.5rem; // 40px + --ds-font-line-height-1200: 3rem; // 48px + --ds-font-line-height-1600: 4rem; // 64px + --ds-font-line-height-1800: 4.5rem; // 72px + --ds-font-line-height-900: 2.25rem; // 36px +}