/* ============================================================================
   Button / Default — COMPONENTS.md §1.1

   The subset this app uses: Primary (filled brand), Tertiary (outlined),
   Text (bare), Link Primary and Link Secondary. The full set is 9 types x 3
   states x 4 sizes x danger x show-text = 156 variants; the rest arrive when
   a surface needs them.

   §1.1 records two gaps that are implemented here rather than reproduced:
     · No focus state exists in the variant set. Added, per DESIGN.md §7.
     · No pressed state exists either, "despite solid/brand/pressed and
       soft/brand/pressed being defined in the token layer". Added.

   §1.1 also notes vertical padding is unbound RAW (9 / 5 / 1) on every size,
   because height is fixed and the padding is a derived filler. The Small size's
   raw 1 happens to equal `space/px`, which is a real token, so that one is
   bound; 9 and 5 are marked.

   TODO(tokens): every bare px length in this file is a SIZE.
   DESIGN.md §12.4 records size as not built.
   ========================================================================== */

.btn {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  border: var(--border-width-thin) solid transparent;
  border-radius: var(--shape-radius-button);
  font-family: var(--font-family-text);
  /* §1.1: label text style is Body/MD Regular on every size. */
  font-size: var(--font-body-md-size);
  line-height: var(--font-body-md-line-height);
  font-weight: var(--font-weight-regular);
  letter-spacing: var(--font-letter-spacing-default);
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 100ms ease, border-color 100ms ease, color 100ms ease;
}

/* --- Sizes — §1.1 geometry table ----------------------------------------- */
.btn--lg {
  block-size: 40px;
  padding-inline: var(--space-md);
  padding-block: 9px; /* RAW in the DS — height is fixed, so this is filler */
  gap: var(--space-xs);
}
.btn--md {
  block-size: 32px;
  padding-inline: var(--space-md);
  padding-block: 5px; /* RAW in the DS */
}
.btn--sm {
  block-size: 24px;
  padding-inline: var(--space-xs);
  /* The DS's RAW 1 here is exactly `space/px`, which is a real token. */
  padding-block: var(--space-px);
}
/* §1.1's fourth size: height auto, no radius, no padding, no gap of its own —
   the button is the label's own line box, so it sits on a text baseline rather
   than occupying a control slot. That means no border box either: `.btn` keeps
   a transparent hairline so the outlined types can swap colour without
   shifting, and the 2px it adds is exactly what a control slot is for. An
   Inline button has no slot, so it drops it — which is what puts
   `Comment / Item / Reactions` (§32.5) on the frame's 22 rather than 24. */
.btn--inline {
  block-size: auto;
  padding: var(--space-none);
  border-width: var(--border-width-none);
}

/* --- Primary — filled brand ---------------------------------------------- */
.btn--primary {
  background: var(--color-solid-brand-default);
  border-color: var(--color-border-brand-default);
  color: var(--color-on-solid-brand);
}
.btn--primary:hover {
  background: var(--color-solid-brand-hover);
  /* §1.1: Hover drops the border. */
  border-color: transparent;
}
.btn--primary:active {
  background: var(--color-solid-brand-pressed);
  border-color: transparent;
}

/* --- Tertiary — outlined, transparent fill ------------------------------- */
.btn--tertiary {
  background: none;
  border-color: var(--color-border-default);
  color: var(--color-content-primary);
}
.btn--tertiary:hover {
  border-color: var(--color-border-strong);
  color: var(--color-on-soft-neutral);
}
.btn--tertiary:active {
  background: var(--color-soft-neutral-pressed);
}

/* --- Link Primary — brand-coloured inline link --------------------------- */
.btn--link {
  background: none;
  border-color: transparent;
  color: var(--color-content-brand);
  gap: var(--space-xs); /* §1.1: the link types carry the wider gap */
}
.btn--link:hover {
  color: var(--color-content-brand);
  text-decoration: underline;
}

/* --- Link Secondary — neutral inline link -------------------------------
   §1.1: no fill and no border in any state; `content/primary` at rest going
   to `content/brand` on hover. It is the only link type whose resting ink is
   neutral, which is what makes it right for a row of subordinate actions
   sitting under a body of text — `Comment / Item / Reactions` (§32.5), where
   `Like` and `Reply` must not compete with the comment they belong to.

   Distinct from `.btn--text`, which tints its BACKGROUND on hover, and from
   `.btn--tertiary`, which draws a `border/default` outline at rest. */
.btn--link-secondary {
  background: none;
  border-color: transparent;
  color: var(--color-content-primary);
  gap: var(--space-xs); /* §1.1: the link types carry the wider gap */
}
.btn--link-secondary:hover {
  color: var(--color-content-brand);
  text-decoration: underline;
}

/* --- Disabled — shared across types ------------------------------------- */
.btn:disabled,
.btn[aria-disabled="true"] {
  background: var(--color-solid-disabled);
  border-color: transparent;
  color: var(--color-content-disabled);
  cursor: default;
  pointer-events: none;
}
/* Link and Text keep no fill when disabled — §1.1. */
.btn--link:disabled,
.btn--link[aria-disabled="true"],
.btn--link-secondary:disabled,
.btn--link-secondary[aria-disabled="true"] {
  background: none;
}

/* --- Icon slots ---------------------------------------------------------- */
.btn .icon {
  /* TODO(tokens): size not built. 16px is the DS's icon slot on every size. */
  inline-size: 16px;
  block-size: 16px;
}

/* The Going / Not going pair carry a status colour on the ICON only, with the
   label left at content/primary — verified against the exported assets, whose
   fills are Green/800 and Red/700, i.e. content/success and content/danger.
   That is a correct use of semantic status colour on a neutral control. */
.btn__icon--success {
  color: var(--color-content-success);
}
.btn__icon--danger {
  color: var(--color-content-danger);
}

/* `display` on .btn outranks the UA's `[hidden] { display: none }`, so a
   conditionally-shown button needs this to actually hide. */
.btn[hidden] {
  display: none;
}

/* --- Text — bare, tint on hover -----------------------------------------
   §1.1's fourth type (Ant `type="text"`): no fill, no border, `content/primary`
   → `soft/neutral/default` + `on-soft/neutral` on hover, `content/disabled`
   when disabled. `Text` and `Vertical` share this contract exactly; only the
   icon/label axis differs, and Vertical is not built.
   Added for the sidebar toggle in `Calendar / Header`, the one control in that
   bar with neither a fill nor an outline. */
.btn--text {
  background: none;
  border-color: transparent;
  color: var(--color-content-primary);
}
.btn--text:hover {
  background: var(--color-soft-neutral-default);
  color: var(--color-on-soft-neutral);
}
/* No pressed state exists in the variant set — §1.1 — and
   soft/neutral/pressed is defined and unconsumed. */
.btn--text:active {
  background: var(--color-soft-neutral-pressed);
}

/* --- Icon-only ----------------------------------------------------------
   Not a type; a `Show text = false` button. §1.1's geometry table sets
   padding-x from the size, which assumes a label — with none, the frame pads
   evenly instead (`Calendar / Header`'s 32x32 controls are p8). Square, so the
   inline padding matches the block padding the size already set. */
.btn--icon {
  padding-inline: var(--space-xs);
  aspect-ratio: 1;
}
