/*
 * Badge
 *
 * Geometry measured from Figma `Badge` (152:73). Six intents x three sizes x
 * two shapes.
 *
 * v2: Badge owns no tokens. Every value here is an Interface token, a Semantics
 * token, or a spacing primitive — the same ones the Figma component binds, so
 * the two cannot drift. Even Large, at 32px, is not a control: it has no hit
 * target and no state, so it does not read the control scale.
 *
 * HEIGHT IS PINNED, NOT DERIVED. Figma binds each size's height to
 * spacing/20|24|32, and the 2px vertical padding it also carries is inert
 * because the pinned height already exceeds it. Reproducing that padding
 * instead of the height is exactly how Button's ramp once landed 2px off on
 * every size, so this reads the height token and pads the inline axis only.
 *
 * SMALL IS THE DEFAULT, matching Figma's default variant and the single size
 * this component shipped with before the ramp existed.
 */
.ion-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--spacing-20);

  /*
   * Figma's 1px stroke is drawn INSIDE the box; a CSS border sits outside the
   * padding. Subtracting one border width keeps the label the same distance
   * from the outer edge in both. Same correction as Checkbox and Radio, and
   * only needed on the inline axis now that height is pinned.
   */
  padding-inline: calc(var(--spacing-4) - var(--border-width-default));
  gap: var(--spacing-4);
  font-family: var(--font-family-sans);

  /*
   * Medium, not semibold. Figma's Badge label is Host Grotesk Medium; this was
   * semibold in code and is the only typographic mismatch the measurement found.
   */
  font-weight: var(--font-weight-medium);
  font-size: var(--type-caption);
  line-height: var(--type-caption-line-height);
  border-radius: var(--radius-full);
  border-width: var(--border-width-default);
  border-style: solid;
  user-select: none;
  white-space: nowrap;
}

/*
 * Dot marker. It tracks the label exactly, so `currentcolor` is right — Figma
 * binds it to the same token the label uses.
 */
.ion-badge__dot {
  width: var(--spacing-6);
  height: var(--spacing-6);
  border-radius: var(--radius-full);
  background-color: currentcolor;
  flex-shrink: 0;
}

/*
 * The icon does NOT track the label. v2 splits `fg` into `text` and `icon`
 * precisely so an icon can sit a step brighter than the copy beside it — for
 * error that is #dc2828 against the label's #ba1c1c. `@ionbase-ui/icons` renders
 * with `currentColor`, so each intent sets `color` on the svg directly.
 *
 * Icon size IS set now, and is on the ladder. The previous note here recorded
 * Figma at a single off-scale 14px and declined to follow it, on the grounds
 * that it looked like a slip. The retuned component reads icon-size/2xs, /sm
 * and /md — 12, 16, 20 — one rung per size, so the slip is gone and there is
 * something to follow.
 */
.ion-badge svg {
  flex-shrink: 0;
  width: var(--icon-size-2xs);
  height: var(--icon-size-2xs);
}

/*
 * The label carries its own inline padding, which is Figma's `Label Slot`
 * frame. The dot and the icon are its siblings rather than its children, so
 * they sit at the badge's own padding and only the text takes the extra inset.
 * Collapsing the two into one padding would move the dot.
 */
.ion-badge__label {
  padding-inline: var(--spacing-2);
}

/* Size modifiers — Small is the base. */

.ion-badge--md {
  min-height: var(--spacing-24);
  font-size: var(--type-body-sm);
  line-height: var(--type-body-sm-line-height);
}

.ion-badge--md .ion-badge__label {
  padding-inline: var(--spacing-4);
}

.ion-badge--md svg {
  width: var(--icon-size-sm);
  height: var(--icon-size-sm);
}

.ion-badge--lg {
  min-height: var(--spacing-32);
  padding-inline: calc(var(--spacing-6) - var(--border-width-default));
  gap: var(--spacing-6);
  font-size: var(--type-body-sm);
  line-height: var(--type-body-sm-line-height);
}

.ion-badge--lg .ion-badge__label {
  padding-inline: var(--spacing-6);
}

.ion-badge--lg svg {
  width: var(--icon-size-md);
  height: var(--icon-size-md);
}

/*
 * Shape. Pill is the base radius/full; Rounded steps with the size so the
 * corner stays proportional — 4 / 6 / 8 against heights of 20 / 24 / 32.
 */

.ion-badge--rounded {
  border-radius: var(--radius-xs);
}

.ion-badge--md.ion-badge--rounded {
  border-radius: var(--radius-sm);
}

.ion-badge--lg.ion-badge--rounded {
  border-radius: var(--radius-md);
}

/* Intent modifiers */

/*
 * Neutral sits on `surface/page`, not `surface/muted`. Figma retuned it there
 * on 2026-09-02 (152:43, and every Medium/Large/Rounded neutral variant), which
 * lifts the light-mode fill from #f0f2f4 to #f6f8f9 and drops the dark one from
 * #1d2735 to #131923. The point of the move is that a neutral badge should read
 * as unfilled next to the five coloured intents — those all sit on a `*-subtle`
 * surface a shade off the page, so a neutral one a shade the OTHER way looked
 * like a seventh intent rather than the absence of one.
 */
.ion-badge--neutral {
  background-color: var(--surface-page);
  color: var(--text-secondary);
  border-color: var(--border-default);
}

.ion-badge--neutral svg {
  color: var(--icon-secondary);
}

.ion-badge--primary {
  background-color: var(--surface-primary-subtle);
  color: var(--text-link);
  border-color: var(--border-primary-subtle);
}

.ion-badge--primary svg {
  color: var(--icon-primary);
}

.ion-badge--success {
  background-color: var(--surface-success-subtle);
  color: var(--text-success);
  border-color: var(--border-success-subtle);
}

.ion-badge--success svg {
  color: var(--icon-success);
}

.ion-badge--warning {
  background-color: var(--surface-warning-subtle);
  color: var(--text-warning);
  border-color: var(--border-warning-subtle);
}

.ion-badge--warning svg {
  color: var(--icon-warning);
}

.ion-badge--error {
  background-color: var(--surface-error-subtle);
  color: var(--text-error);
  border-color: var(--border-error-subtle);
}

.ion-badge--error svg {
  color: var(--icon-error);
}

.ion-badge--information {
  background-color: var(--surface-information-subtle);
  color: var(--text-information);
  border-color: var(--border-information-subtle);
}

.ion-badge--information svg {
  color: var(--icon-information);
}

/*
 * As Logo: a `color` on the <svg> survives forced colours, so the icon kept
 * its intent colour on a remapped background. Inherited, it matches the text.
 */
@media (forced-colors: active) {
  .ion-badge svg {
    color: inherit;
  }
}
