@use "sass:color";
@use "sass:map";
@use "color" as cl;

// Semantic variants — the single source of truth for every component.
//
// Buttons, badges, alerts, inputs and links all loop over this map, so a new
// semantic colour is added in exactly one place and every component picks it
// up. Each entry carries the full state set a component needs:
//
//   base   fill / border colour at rest
//   hover  fill at :hover        (−8% lightness unless a token exists)
//   active fill at :active       (−12% lightness unless a token exists)
//   on     text colour that sits legibly on `base`
//   soft   pale tint fill
//   ink    text colour that sits legibly on `soft`
//
// `hover`/`active` are pre-computed here rather than in each component so the
// two never drift apart, and so a design token (`$text-primary-hover`,
// `$text-danger-hover`) wins over the computed step wherever one exists.

@function _darken($c, $amount) {
  @return color.adjust($c, $lightness: -$amount);
}

$variants: (
  primary: (
    base: cl.$background-primary,
    hover: cl.$text-primary-hover,
    active: _darken(cl.$background-primary, 12%),
    on: cl.$text-light,
    soft: cl.$background-primary-soft,
    ink: cl.$text-primary,
  ),
  secondary: (
    base: cl.$background-secondary,
    hover: _darken(cl.$background-secondary, 4%),
    active: _darken(cl.$background-secondary, 8%),
    on: cl.$text-dark,
    soft: cl.$background-secondary,
    ink: cl.$text-secondary,
  ),
  success: (
    base: cl.$background-success,
    hover: _darken(cl.$background-success, 8%),
    active: _darken(cl.$background-success, 12%),
    on: cl.$text-light,
    soft: cl.$background-success-soft,
    ink: cl.$text-success,
  ),
  warning: (
    base: cl.$background-warning,
    hover: _darken(cl.$background-warning, 8%),
    active: _darken(cl.$background-warning, 12%),
    on: cl.$text-light,
    soft: cl.$background-warning-soft,
    ink: cl.$text-warning,
  ),
  danger: (
    base: cl.$background-danger,
    hover: cl.$text-danger-hover,
    active: _darken(cl.$background-danger, 12%),
    on: cl.$text-light,
    soft: cl.$background-danger-soft,
    ink: cl.$text-danger,
  ),
  info: (
    base: cl.$background-info,
    hover: _darken(cl.$background-info, 8%),
    active: _darken(cl.$background-info, 12%),
    on: cl.$text-light,
    soft: cl.$background-info-soft,
    ink: cl.$text-info,
  ),
  dark: (
    base: cl.$background-dark,
    hover: _darken(cl.$background-dark, 6%),
    active: _darken(cl.$background-dark, 10%),
    on: cl.$text-light,
    soft: cl.$background-secondary,
    ink: cl.$text-darker,
  ),
  light: (
    base: cl.$background-light,
    hover: _darken(cl.$background-light, 4%),
    active: _darken(cl.$background-light, 8%),
    on: cl.$text-dark,
    soft: cl.$background-light,
    ink: cl.$text-dark,
  ),
  default: (
    base: cl.$background-default,
    hover: cl.$background-secondary,
    active: _darken(cl.$background-secondary, 4%),
    on: cl.$text-dark,
    soft: cl.$background-default,
    ink: cl.$text-dark,
  ),
  tertiary: (
    base: cl.$background-tertiary,
    hover: _darken(cl.$background-tertiary, 8%),
    active: _darken(cl.$background-tertiary, 12%),
    on: cl.$text-light,
    soft: cl.$background-tertiary,
    ink: cl.$text-tertiary,
  ),
) !default;

// Status variants — tint-only. These name a *state of a record*, not a
// component colour, so they get `soft`/`ink` and nothing else: there is no
// such thing as a solid "system role" button.
$status-variants: (
  standard: (soft: cl.$background-primary-soft, ink: cl.$text-custom),
  lite: (soft: cl.$background-lite-soft, ink: cl.$text-lite),
  system: (soft: cl.$background-system-soft, ink: cl.$text-system),
  custom: (soft: cl.$background-custom-soft, ink: cl.$text-custom),
  active: (soft: cl.$background-success-soft, ink: cl.$text-success),
) !default;

// Every variant that has a tint, solid or not — what badges and alerts loop.
$tint-variants: map.merge($variants, $status-variants) !default;

@function v($name, $key) {
  @return map.get(map.get($variants, $name), $key);
}
@function tint($name, $key) {
  @return map.get(map.get($tint-variants, $name), $key);
}
