/* ============================================================
   Buttons

   Every `.btn` reads its colours and metrics from a small set of
   custom properties. A variant class (or any stylesheet that wants to
   restyle a button in place, e.g. the partner CTAs) only redefines the
   properties it cares about; the state rules below never have to be
   repeated. This is the per-variant-property pattern Bootstrap used,
   kept because the app depends on it, renamed to `--btn-*`.
   ============================================================ */

@layer components {
  .btn {
    /* Metrics */
    --btn-padding-y: 0.625rem;
    --btn-padding-x: 1.5rem;
    --btn-font-size: 1rem;
    --btn-font-weight: 600;
    --btn-line-height: 1.5;
    --btn-border-width: 1px;
    --btn-radius: var(--radius);

    /* Resting colours */
    --btn-fg: var(--color-body);
    --btn-bg: transparent;
    --btn-border: transparent;

    /* Hover / focus. Each falls back to the resting value, so a variant
       that only sets `--btn-bg` still behaves sanely on hover. */
    --btn-fg-hover: var(--btn-fg);
    --btn-bg-hover: var(--btn-bg);
    --btn-border-hover: var(--btn-border);

    /* Pressed / checked / .active / .show */
    --btn-fg-active: var(--btn-fg-hover);
    --btn-bg-active: var(--btn-bg-hover);
    --btn-border-active: var(--btn-border-hover);

    /* Disabled keeps the resting fill and drops the opacity */
    --btn-fg-disabled: var(--btn-fg);
    --btn-bg-disabled: var(--btn-bg);
    --btn-border-disabled: var(--btn-border);
    --btn-disabled-opacity: 0.65;

    /* One focus ring for every variant */
    --btn-focus-shadow: 0 0 0 3px var(--primary-ring-strong);

    /* Hover lift: the button rises by --btn-lift and gains a shadow.
       Both are properties so a container can cancel the lift with
       `--btn-lift: 0`. */
    --btn-lift: -1px;
    --btn-shadow-current: var(--shadow);

    display: inline-block;
    padding: var(--btn-padding-y) var(--btn-padding-x);
    font-family: inherit;
    font-size: var(--btn-font-size);
    font-weight: var(--btn-font-weight);
    line-height: var(--btn-line-height);
    letter-spacing: 0.01em;
    color: var(--btn-fg);
    text-align: center;
    vertical-align: middle;
    cursor: pointer;
    user-select: none;
    background-color: var(--btn-bg);
    border: var(--btn-border-width) solid var(--btn-border);
    border-radius: var(--btn-radius);
    /* `all` rather than an explicit property list so the lift animates too */
    transition: all 0.2s ease;

    &:hover {
      color: var(--btn-fg-hover);
      background-color: var(--btn-bg-hover);
      border-color: var(--btn-border-hover);
      text-decoration: none;
      transform: translateY(var(--btn-lift));
      box-shadow: var(--btn-shadow-current);
    }

    &:focus-visible {
      color: var(--btn-fg-hover);
      background-color: var(--btn-bg-hover);
      border-color: var(--btn-border-hover);
      outline: none;
      box-shadow: var(--btn-focus-shadow);
    }

    /* The press cancels the lift; the colour swap lives in the shared
       "active" rule below, which also covers .active and :checked labels. */
    &:active {
      transform: translateY(0);
    }

    &:disabled,
    &.disabled {
      color: var(--btn-fg-disabled);
      background-color: var(--btn-bg-disabled);
      border-color: var(--btn-border-disabled);
      opacity: var(--btn-disabled-opacity);
      pointer-events: none;
    }

    & .badge {
      position: relative;
      top: -1px;
    }
  }

  fieldset:disabled .btn {
    color: var(--btn-fg-disabled);
    background-color: var(--btn-bg-disabled);
    border-color: var(--btn-border-disabled);
    opacity: var(--btn-disabled-opacity);
    pointer-events: none;
  }

  @media (prefers-reduced-motion: reduce) {
    .btn {
      transition: none;
    }
  }

  /* ---- Sizes ---- */

  .btn-sm {
    --btn-padding-y: 0.25rem;
    --btn-padding-x: 0.5rem;
    --btn-font-size: 0.875rem;
    --btn-radius: var(--radius-sm);
  }

  .btn-lg {
    --btn-padding-y: 0.5rem;
    --btn-padding-x: 1rem;
    --btn-font-size: 1.25rem;
    --btn-radius: var(--radius-lg);
  }

  /* ---- Variants ----------------------------------------------------
     Solid variants below primary keep dark text: these fills are light
     enough that black reads better than white on them.
     ------------------------------------------------------------------ */

  .btn-primary {
    --btn-fg: #fff;
    --btn-bg: #6774e4;
    --btn-border: #6774e4;
    /* The two hover/active fills are the resting fill with its HSL
       lightness pulled down 8% and 12%. */
    --btn-fg-hover: #fff;
    --btn-bg-hover: #4454de;
    --btn-border-hover: #4454de;
    --btn-fg-active: #fff;
    --btn-bg-active: #3344db;
    --btn-border-active: #3344db;
  }

  .btn-success {
    --btn-fg: #000;
    --btn-bg: var(--color-success);
    --btn-border: var(--color-success);
    --btn-fg-hover: #000;
    --btn-bg-hover: #43ce76;
    --btn-border-hover: #38cb6e;
    --btn-fg-active: #000;
    --btn-bg-active: #4ed17e;
    --btn-border-active: #38cb6e;
  }

  .btn-danger {
    --btn-fg: #000;
    --btn-bg: var(--color-danger);
    --btn-border: var(--color-danger);
    --btn-fg-hover: #000;
    --btn-bg-hover: #f16060;
    --btn-border-hover: #f15757;
    --btn-fg-active: #000;
    --btn-bg-active: #f26969;
    --btn-border-active: #f15757;
  }

  .btn-light {
    --btn-fg: #000;
    --btn-bg: var(--color-light);
    --btn-border: var(--color-light);
    --btn-fg-hover: #000;
    --btn-bg-hover: #d3d4d6;
    --btn-border-hover: #c6c7ca;
    --btn-fg-active: #000;
    --btn-bg-active: #c6c7ca;
    --btn-border-active: #babbbd;
  }

  /* Outline variants: transparent until hover, then they fill with the
     border colour. */
  .btn-outline-primary {
    --btn-border-width: 1.5px;
    --btn-fg: #6774e4;
    --btn-bg: transparent;
    --btn-border: #6774e4;
    --btn-fg-hover: #fff;
    --btn-bg-hover: #6774e4;
    --btn-border-hover: #6774e4;
    --btn-fg-active: #000;
    --btn-bg-active: var(--color-primary);
    --btn-border-active: var(--color-primary);
    --btn-fg-disabled: #6774e4;
    --btn-bg-disabled: transparent;
    --btn-border-disabled: #6774e4;
  }

  .btn-outline-secondary {
    --btn-fg: var(--color-secondary);
    --btn-bg: transparent;
    --btn-border: var(--color-secondary);
    --btn-fg-hover: #000;
    --btn-bg-hover: var(--color-secondary);
    --btn-border-hover: var(--color-secondary);
    --btn-fg-active: #000;
    --btn-bg-active: var(--color-secondary);
    --btn-border-active: var(--color-secondary);
    --btn-fg-disabled: var(--color-secondary);
    --btn-bg-disabled: transparent;
    --btn-border-disabled: var(--color-secondary);
  }

  .btn-outline-danger {
    --btn-fg: var(--color-danger);
    --btn-bg: transparent;
    --btn-border: var(--color-danger);
    --btn-fg-hover: #000;
    --btn-bg-hover: var(--color-danger);
    --btn-border-hover: var(--color-danger);
    --btn-fg-active: #000;
    --btn-bg-active: var(--color-danger);
    --btn-border-active: var(--color-danger);
    --btn-fg-disabled: var(--color-danger);
    --btn-bg-disabled: transparent;
    --btn-border-disabled: var(--color-danger);
  }

  /* A button that reads as a link: no chrome, underline on hover. */
  .btn-link {
    --btn-font-weight: 400;
    --btn-fg: var(--color-primary);
    --btn-bg: transparent;
    --btn-border: transparent;
    --btn-fg-hover: #4f52c1;
    --btn-border-hover: transparent;
    --btn-fg-active: #4f52c1;
    --btn-border-active: transparent;
    --btn-fg-disabled: #6c757d;
    --btn-bg-disabled: transparent;
    --btn-border-disabled: transparent;

    text-decoration: none;

    &:hover,
    &:focus-visible {
      text-decoration: underline;
    }

    /* Keyboard focus alone must not darken the label; only hover does. */
    &:focus-visible {
      color: var(--btn-fg);
    }

    &:hover {
      color: var(--btn-fg-hover);
    }
  }

  /* ---- Toggle buttons ----------------------------------------------
     `.btn-check` is a visually hidden radio/checkbox whose adjacent
     `.btn` label carries every visible state. The input stays in the
     accessibility tree and focusable, so it is clipped rather than
     `display: none`.
     ------------------------------------------------------------------ */

  .btn-check {
    position: absolute;
    clip-path: inset(50%);
    pointer-events: none;
  }

  /* Hovering a toggle label must not preview the hover fill: whether it
     looks pressed is decided by the input's checked state alone. */
  .btn-check + .btn:hover {
    color: var(--btn-fg);
    background-color: var(--btn-bg);
    border-color: var(--btn-border);
  }

  /* The label cannot match :focus-visible itself, so the focus ring has
     to be driven from the input. */
  .btn-check:focus-visible + .btn,
  .btn-check:checked:focus-visible + .btn {
    border-color: var(--btn-border-hover);
    outline: 0;
    box-shadow: var(--btn-focus-shadow);
  }

  .btn-check[disabled] + .btn,
  .btn-check:disabled + .btn {
    opacity: var(--btn-disabled-opacity);
    pointer-events: none;
    filter: none;
  }

  /* Pressed, toggled and checked all read the same three properties.
     `:not(.btn-check) + .btn:active` and `.btn:first-child:active` exist so
     that pressing a label in a .btn-check group does not fight the checked
     styling of its sibling. */
  .btn-check:checked + .btn,
  :not(.btn-check) + .btn:active,
  .btn:first-child:active,
  .btn.active,
  .btn.show {
    color: var(--btn-fg-active);
    background-color: var(--btn-bg-active);
    border-color: var(--btn-border-active);
  }

  .btn-check:checked + .btn:focus-visible,
  :not(.btn-check) + .btn:active:focus-visible,
  .btn:first-child:active:focus-visible,
  .btn.active:focus-visible,
  .btn.show:focus-visible {
    box-shadow: var(--btn-focus-shadow);
  }

  /* ---- Close button -------------------------------------------------
     A bare 1em box painted with an inline SVG cross. `background-size`
     is `1em auto`, so the glyph scales with font-size. The white variant
     inverts the same artwork with a filter instead of shipping a second
     SVG.
     ------------------------------------------------------------------ */

  .btn-close {
    --btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e");
    --btn-close-filter: none;
    --btn-close-opacity: 0.5;
    --btn-close-hover-opacity: 0.75;
    --btn-close-focus-opacity: 1;
    --btn-close-disabled-opacity: 0.25;
    --btn-close-focus-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--color-primary) 25%, transparent);

    /* content-box keeps the 1em glyph at 1em and lets the padding grow
       the hit area around it. */
    box-sizing: content-box;
    width: 1em;
    height: 1em;
    padding: 0.25em;
    color: #000;
    background: transparent var(--btn-close-bg) center/1em auto no-repeat;
    filter: var(--btn-close-filter);
    border: 0;
    border-radius: var(--radius);
    opacity: var(--btn-close-opacity);

    &:hover {
      color: #000;
      text-decoration: none;
      opacity: var(--btn-close-hover-opacity);
    }

    &:focus {
      outline: 0;
      box-shadow: var(--btn-close-focus-shadow);
      opacity: var(--btn-close-focus-opacity);
    }

    &:disabled,
    &.disabled {
      opacity: var(--btn-close-disabled-opacity);
      pointer-events: none;
      user-select: none;
    }
  }

  .btn-close-white {
    --btn-close-filter: invert(1) grayscale(100%) brightness(200%);
  }
}
