@use "sass:map";
@use "colors" as *;
@use "config" as *;
@use "functions" as *;
@use "theme" as *;
@use "mixins/tokens" as *;

@layer colors, config, root, reboot, layout, content, forms, components, custom, helpers, utilities;

$root-tokens: () !default;

// scss-docs-start root-tokens
// stylelint-disable @stylistic/value-list-max-empty-lines, @stylistic/function-max-empty-lines, custom-property-no-missing-var-function
// stylelint-disable-next-line scss/dollar-variable-default
$root-tokens: defaults(
  (
    --black: #{$black},
    --white: #{$white},

    --gradient: #{$gradient},

    // scss-docs-start root-body-variables
    // The stack omits system-ui. It resolves to the user interface font of the
    // locale, which shows non-Latin text incorrectly. See twbs/bootstrap#42703.
    --body-font-family: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'",
    --body-font-size: 1rem,
    --body-font-weight: var(--font-weight-normal),
    --body-line-height: 1.5,
    // scss-docs-end root-body-variables

    --heading-color: inherit,

    --hr-border-color: var(--border-color),

    --link-color: light-dark(var(--primary-base), var(--primary-fg)),
    --link-decoration: underline,
    --link-underline-offset: .2em,
    --link-hover-color: color-mix(in oklch, var(--link-color) 90%, #000),

    --font-mono: "ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Monaco, 'Cascadia Mono', Consolas, 'Liberation Mono', monospace",
    --code-font-size: 95%,
    --code-color: var(--fg-2),

    // scss-docs-start root-border-var
    --border-width: #{$border-width},
    --border-width-keyline: .5px,
    --border-style: #{$border-style},
    --border-color: light-dark(var(--gray-200), var(--gray-700)),
    --border-color-translucent: color-mix(in oklch, var(--fg-body) 15%, transparent),
    // scss-docs-end root-border-var

    // scss-docs-start root-box-shadow-variables
    // --box-shadow* tokens are generated below (see root-box-shadow-loop) from
    // the shared $shadows map in scss/_config.scss, which reads these two.
    --shadow-color: #000,
    --shadow-strength: 1,
    // scss-docs-end root-box-shadow-variables

    // scss-docs-start root-transition-variables
    // Shared easing curve for overlay components (dialog, drawer, menu)
    --transition-timing-overlay: cubic-bezier(.22, 1, .36, 1),
    // scss-docs-end root-transition-variables

    --spacer: #{$spacer},

    // scss-docs-start root-focus-variables
    --focus-ring-width: 3px,
    --focus-ring-offset: 1px,
    --focus-ring-color: var(--primary-focus-ring),
    --focus-ring: var(--focus-ring-width) solid var(--focus-ring-color),
    // scss-docs-end root-focus-variables

    // scss-docs-start root-form-variables
    --control-checked-bg: var(--primary-base),
    --control-checked-border-color: var(--control-checked-bg),
    --control-active-bg: var(--primary-base),
    --control-active-border-color: var(--control-active-bg),
    --control-disabled-bg: var(--bg-3),
    --control-disabled-opacity: .65,
    // Shared motion for checkbox/radio marks; slight overshoot so the mark pops in
    --control-transition-duration: .15s,
    --control-transition-timing: cubic-bezier(.34, 1.56, .64, 1),

    --btn-input-fg: var(--fg-body),
    --btn-input-bg: var(--bg-body),

    --btn-input-gap: .375rem,
    --btn-input-min-height: 2.375rem,
    --btn-input-padding-y: .375rem,
    --btn-input-padding-x: .75rem,
    --btn-input-font-size: var(--body-font-size),
    --btn-input-font-weight: var(--font-weight-normal),
    --btn-input-line-height: var(--body-line-height),
    --btn-input-border-radius: var(--radius-5),

    --btn-input-xs-gap: var(--spacer-1),
    --btn-input-xs-min-height: 1.5rem,
    --btn-input-xs-padding-y: .125rem,
    --btn-input-xs-padding-x: .5rem,
    --btn-input-xs-font-size: var(--font-size-xs),
    --btn-input-xs-line-height: 1.125,
    --btn-input-xs-border-radius: var(--radius-5),

    --btn-input-sm-gap: .375rem,
    --btn-input-sm-min-height: 2rem,
    --btn-input-sm-padding-y: .25rem,
    --btn-input-sm-padding-x: .625rem,
    --btn-input-sm-font-size: var(--font-size-sm),
    --btn-input-sm-line-height: var(--line-height-sm),
    --btn-input-sm-border-radius: var(--radius-5),

    --btn-input-lg-gap: .375rem,
    --btn-input-lg-min-height: 2.75rem,
    --btn-input-lg-padding-y: .5rem,
    --btn-input-lg-padding-x: 1rem,
    --btn-input-lg-font-size: var(--font-size-md),
    --btn-input-lg-line-height: var(--line-height-md),
    --btn-input-lg-border-radius: var(--radius-7),
    // scss-docs-end root-form-variables
  ),
  $root-tokens
);
// stylelint-enable @stylistic/value-list-max-empty-lines, @stylistic/function-max-empty-lines, custom-property-no-missing-var-function
// scss-docs-end root-tokens

// scss-docs-start root-font-size-loop
// Generate font-size and line-height tokens
@each $name, $props in $font-sizes {
  $root-tokens: map.set($root-tokens, --font-size-#{$name}, map.get($props, "font-size"));
  $root-tokens: map.set($root-tokens, --line-height-#{$name}, map.get($props, "line-height"));
}
// scss-docs-end root-font-size-loop

// scss-docs-start root-font-weight-loop
// Generate font-weight tokens
@each $name, $value in $font-weights {
  $root-tokens: map.set($root-tokens, --font-weight-#{$name}, $value);
}
// scss-docs-end root-font-weight-loop

// scss-docs-start root-theme-tokens
// Generate semantic theme colors
@each $color-name, $color-map in $theme-colors {
  @each $key, $value in $color-map {
    $root-tokens: map.set($root-tokens, --#{$color-name}-#{$key}, $value);
  }
}

// Generate background tokens
@each $key, $value in $theme-bgs {
  $root-tokens: map.set($root-tokens, --bg-#{$key}, $value);
}

// Generate foreground tokens
@each $key, $value in $theme-fgs {
  $root-tokens: map.set($root-tokens, --fg-#{$key}, $value);
}

// Generate border tokens
@each $key, $value in $theme-borders {
  $root-tokens: map.set($root-tokens, --border-#{$key}, $value);
}
// scss-docs-end root-theme-tokens

// Generate breakpoint tokens
@each $name, $value in $breakpoints {
  $root-tokens: map.set($root-tokens, --breakpoint-#{$name}, $value);
}

// Generate spacer tokens
// scss-docs-start root-spacer-loop
@each $key, $value in $spacers {
  $root-tokens: map.set($root-tokens, --spacer-#{$key}, $value);
}
// scss-docs-end root-spacer-loop

// Generate radius tokens
// scss-docs-start root-radius-loop
@each $key, $value in $radii {
  $root-tokens: map.set($root-tokens, --radius-#{$key}, $value);
}
// stylelint-disable-next-line scss/dollar-variable-default
$root-tokens: map.set($root-tokens, --radius-pill, 50rem);
// scss-docs-end root-radius-loop

// Generate box-shadow tokens
// scss-docs-start root-box-shadow-loop
@each $key, $value in $shadows {
  @if $key == null {
    $root-tokens: map.set($root-tokens, --box-shadow, $value);
  } @else {
    $root-tokens: map.set($root-tokens, --box-shadow-#{$key}, $value);
  }
}
// scss-docs-end root-box-shadow-loop

// Generate z-index tokens
@each $key, $value in $zindex-levels {
  $root-tokens: map.set($root-tokens, --z-#{$key}, $value);
}

:root,
:host {
  @include tokens($root-tokens);

  color-scheme: light dark;
  // Always reserve the viewport scrollbar gutter so layout doesn't shift
  // when overflow: hidden is applied (e.g. when a dialog opens on Windows).
  scrollbar-gutter: stable;
}

// Deepen shadows in dark mode. The shadow-strength token is a plain number, so it
// can't use light-dark() (colors only); vary it alongside color-scheme instead.
@media (prefers-color-scheme: dark) {
  :root,
  :host {
    --shadow-strength: 2.4;
  }
}

[data-bs-theme="dark"] {
  --shadow-strength: 2.4;
  color-scheme: dark;
}

[data-bs-theme="light"] {
  --shadow-strength: 1;
  color-scheme: light;
}
