@layer components {
  .btn {
    --icon-size: var(--btn-icon-size, 1.3em);
    --btn-border-radius: var(--radius);
    --btn-hover-brightness: 0.9;
    --chamfer: var(--btn-chamfer, var(--chamfer-small));

    align-items: center;
    background-color: var(--btn-background, var(--color-surface));
    background-image: var(--btn-background-image, none);
    border-radius: var(--btn-border-radius);
    border: var(--btn-border-size, 1px) solid
      var(--btn-border-color, var(--color-ink-light));
    color: var(--btn-color, var(--color-ink));
    cursor: pointer;
    display: inline-flex;
    font-family: var(--font-display);
    font-size: var(--text-x-small);
    font-weight: var(--btn-font-weight, 600);
    gap: var(--btn-gap, 0.5em);
    justify-content: center;
    letter-spacing: var(--letter-spacing-loose);
    padding: var(--btn-padding, calc(0.67 * var(--block-space-half)) 1.1em);
    text-transform: uppercase;
    pointer-events: auto;
    position: relative;
    text-decoration: none;
    transition: 100ms ease-out;
    transition-property:
      background-color, border, box-shadow, color, opacity, scale;

    @media (any-hover: hover) {
      &:hover {
        filter: brightness(var(--btn-hover-brightness));
      }
    }

    html[data-theme="dark"] & {
      --btn-hover-brightness: 1.25;
    }

    @media (prefers-color-scheme: dark) {
      html:not([data-theme]) & {
        --btn-hover-brightness: 1.25;
      }
    }

    &[disabled],
    &:has([disabled]),
    [disabled] &[type="submit"],
    &[type="submit"]:disabled {
      cursor: not-allowed;
      opacity: 0.3;
      pointer-events: none;
    }

    form[aria-busy] &:disabled {
      --submitting-border-size: 2px;
      --submitting-color: var(
        --btn-submitting-color,
        var(--btn-border-color, var(--color-ink-light))
      );

      opacity: 1;
      position: relative;

      &::after {
        animation: submitting 1s infinite linear;
        background: conic-gradient(
          from var(--submitting-angle),
          transparent 0% 72%,
          color-mix(in srgb, var(--submitting-color) 20%, transparent) 78%,
          var(--submitting-color) 88% 94%,
          transparent 100%
        );
        border-radius: inherit;
        box-sizing: border-box;
        clip-path: inherit;
        content: "";
        inset: 0;
        -webkit-mask:
          linear-gradient(#000 0 0) content-box,
          linear-gradient(#000 0 0);
        -webkit-mask-composite: xor;
        mask:
          linear-gradient(#000 0 0) content-box,
          linear-gradient(#000 0 0);
        mask-composite: exclude;
        padding: var(--submitting-border-size);
        pointer-events: none;
        position: absolute;

        @media (prefers-reduced-motion: reduce) {
          animation: none;
          background: var(--submitting-color);
        }
      }
    }
  }

  /* Row-like buttons — list rows of people or teams, and popup menu items —
     carry user content, not commands, so they keep sentence-case body type. */
  .btn:is(.justify-start, .popup__btn) {
    font-family: var(--font-sans);
    font-size: var(--text-small);
    font-weight: 500;
    letter-spacing: normal;
    text-transform: none;
  }

  /* Variants
  /* ------------------------------------------------------------------------ */

  .btn--outline {
    --btn-background: transparent;
    --btn-border-color: var(--color-ink-medium);
  }

  .btn--ghost {
    --btn-background: transparent;
    --btn-border-color: transparent;

    &:hover {
      --btn-background: color-mix(in srgb, var(--color-canvas) 40%, transparent);
    }
  }

  .btn--wide {
    min-width: 25ch;
  }

  /* The brand button: gold on ink. Its own focus ring is retinted so the */
  /* ring doesn't disappear against the fill. */
  .btn--primary {
    --btn-background: var(--color-primary);
    --btn-background-image: repeating-linear-gradient(
      0deg,
      transparent 0 3px,
      color-mix(in srgb, var(--btn-color) 4%, transparent) 3px 4px
    );
    --btn-border-color: var(--color-primary-dark);
    --btn-color: var(--color-ink);
    --focus-ring-color: var(--color-primary-dark);
  }

  .btn--link {
    --btn-background: var(--color-link);
    --btn-border-color: var(--color-canvas);
    --btn-color: var(--color-ink-inverted);
    --focus-ring-color: var(--color-link);
  }

  .btn--icon {
    --btn-padding: var(--inline-space);
  }

  /* Buttons carry the chamfer without opting in. Segments of a button group and
     borderless popup rows are excluded: the cut would break the seam between
     joined segments, and menu rows read as list items rather than buttons. */
  .btn:not(.btn__group *, .popup__btn) {
    clip-path: var(--chamfer-clip);

    /* clip-path erases anything painted outside the border box, so the focus
       ring is drawn inside the button rather than as an offset outline. */
    &:focus-visible {
      box-shadow: inset 0 0 0 var(--focus-ring-size) var(--focus-ring-color);
      outline: none;
    }
  }

  .btn--circle,
  .btn[aria-label]:where(:has(.icon)),
  .btn:where(:has(.for-screen-reader):has(.icon)) {
    --btn-padding: 0;
    --icon-size: 75%;

    aspect-ratio: 1;
    block-size: var(--btn-size);
    display: grid;
    inline-size: var(--btn-size);
    justify-content: normal; /* FF fix */
    place-items: center;

    > * {
      grid-area: 1/1;
    }
  }

  /* Make a normal button circular on mobile */
  @media (max-width: 639px) {
    .btn--circle-mobile {
      --btn-size: 3em;
      --btn-padding: 0;
      --icon-size: 75%;

      aspect-ratio: 1;
      inline-size: var(--btn-size);

      kbd,
      span:last-of-type:not(.icon) {
        display: none;
      }
    }
  }

  @media (min-width: 640px) {
    .btn .icon--mobile-only {
      display: none !important;
    }
  }

  .btn--negative {
    --btn-background: color-mix(in srgb, var(--color-negative) 90%, transparent);
    --btn-border-color: var(--color-negative);
    --btn-color: var(--color-ink-inverted);
    --focus-ring-color: var(--color-negative);
  }

  /* Solid red is reserved for the primary destructive action of a page or a
     dialog. Inside a panel it's a per-row action, so it outlines instead — a
     column of solid red overwhelms the content it acts on. */
  .panel:not(.dialog) .btn--negative {
    --btn-background: transparent;
    --btn-border-color: color-mix(in srgb, var(--color-negative) 45%, transparent);
    --btn-color: var(--color-negative);

    &:hover {
      --btn-background: color-mix(in srgb, var(--color-negative) 5%, transparent);
    }
  }

  .btn--positive {
    --btn-background: var(--color-positive);
    --btn-border-color: var(--color-canvas);
    --btn-color: var(--color-ink-inverted);
    --focus-ring-color: var(--color-positive);
  }

  .btn--success {
    --success-timing-function: cubic-bezier(0.25, 1.25, 0.5, 1);
    animation: success 1s var(--success-timing-function);

    .icon {
      animation: zoom-fade 500ms var(--success-timing-function);
    }
  }

  /* Fake button used to help space things out */
  .btn--placeholder {
    pointer-events: none;
    visibility: hidden;
  }

  .btn--remove {
    --btn-icon-size: 0.7em;
  }

  .btn--reversed {
    --btn-background: var(--color-ink);
    --btn-border-color: var(--color-canvas);
    --btn-color: var(--color-canvas);
    --focus-ring-color: var(--color-ink);
  }

  /* Toggleable buttons
  /* ------------------------------------------------------------------------ */

  .btn {
    &:has(input[type="radio"], input[type="checkbox"]) {
      position: relative;

      :is(input[type="radio"], input[type="checkbox"]) {
        appearance: none;
        border-radius: var(--btn-border-radius);
        cursor: pointer;
        display: flex;
        inset: 0;
        margin: 0;
        padding: 0;
        position: absolute;

        &:focus-visible {
          outline: none;
        }
      }

      .checked {
        display: none;
      }
    }

    &:has(input:checked) {
      --btn-background: var(--color-ink);
      --btn-border-color: var(--color-ink);
      --btn-color: var(--color-ink-inverted);
      --focus-ring-color: var(--color-ink);

      .checked {
        display: block;
      }
    }

    &:has(input:focus-visible) {
      outline: var(--focus-ring-size) solid var(--focus-ring-color);
      outline-offset: var(--focus-ring-offset);
    }
  }

  .btn--back {
    --btn-border-size: 0;

    @media (max-width: 639px) {
      strong,
      kbd {
        display: none;
      }
    }

    @media (min-width: 640px) {
      font-size: var(--text-medium);

      .icon--arrow-left {
        display: none;
      }
    }
  }

  /* Button groups
  /* ------------------------------------------------------------------------ */

  .btn__group {
    .btn {
      --btn-border-radius: 0;
      --group-radius: var(--radius);

      flex: 1 0 33%;
      inline-size: 100%;
      justify-content: center;
      white-space: nowrap;
    }

    form {
      flex: 1 1 0%;
    }

    :first-of-type .btn {
      border-end-start-radius: var(--group-radius);
      border-inline-end: 0;
      border-start-start-radius: var(--group-radius);
      padding-inline-end: 0.8em;
    }

    :last-of-type .btn {
      border-end-end-radius: var(--group-radius);
      border-inline-start: 0;
      border-start-end-radius: var(--group-radius);
      padding-inline-start: 0.8em;
    }

    span {
      inline-size: 100%;
    }
  }

  /* Button utilities
  /* ------------------------------------------------------------------------ */

  :is([data-platform~="mobile"], [data-platform~="native"]) {
    .btn--ensure-tap-target-size {
      --tap-target-z-index: 1;
      --tap-target-min-size: 44px;

      z-index: var(--tap-target-z-index);

      &::before {
        content: "";
        display: block;
        block-size: var(--tap-target-min-size);
        inline-size: var(--tap-target-min-size);
        inset: calc(50% - var(--tap-target-min-size) / 2) auto auto
          calc(50% - var(--tap-target-min-size) / 2);
        opacity: 0;
        position: absolute;
      }
    }
  }
}
