/* Buttons (#3438, design epic #3432): Figma Buttons page 1:6, sheets L 1:162,
 * M 1:814, S 1:1042. Four families, three sizes, five states:
 *
 *   .btn                      Secondary (also .btn-secondary)
 *   .btn.btn-primary          Primary
 *   .btn.btn-icon.btn-primary   Primary icon-only
 *   .btn.btn-icon.btn-secondary Secondary icon-only (the table row "Play")
 *   .btn-l / .btn-m / .btn-s  size; M when none is given
 *
 * States: :hover, :active, selected ([aria-pressed="true"] or .is-selected: a
 * persistent toggle, not a press), disabled (:disabled or
 * [aria-disabled="true"]), loading ([aria-busy="true"], the inline spinner
 * in the icon slot). .is-hover, .is-active and .is-disabled force a state for
 * the gallery. Focus is the shell's :focus-visible ring (app.css).
 *
 * Specificity is kept at one class per family (`:where()` holds the state
 * guards), so a page rule in app.css or console.css, loaded after this file,
 * still wins over it until that page migrates (#3432 Phase 2). The two
 * icon-only families are the exception, two classes (.btn-icon.btn-primary):
 * they must beat the one-class text families, and no page rule styles them
 * yet (a page restyling one needs two classes too).
 *
 * Glyph sizing skips .btn-github: its GitHub mark keeps its own 18px.
 *
 * Kept from the pre-v2 .btn family: .btn-sm (= S), .btn-lg (= L),
 * .btn-ghost, .btn-danger, .btn-sort, the 34px ghost .btn-icon; .btn-text,
 * .btn-github (app.css) is unchanged.
 */

/* Button tokens. Colors the Nov-4 Figma draws for buttons and tokens.css
 * has no name for, light and dark in one place: light-dark() follows the
 * color-scheme tokens.css sets for each theme. */
:root {
  /* Primary: dark mode inverts it (the sheet: green default, ink hover). */
  --btn-on-fill: #ffffff;    /* label on a filled button, both themes */
  --btn-primary-bg: light-dark(#0d1117, #0d845a);
  --btn-primary-hover-bg: light-dark(#0d845a, #0d1117);
  --btn-primary-disabled-border: light-dark(#c8d0d8, #30363d);
  --btn-primary-disabled-fg: light-dark(#8b949e, #69737f);
  /* Secondary. The light label is the sheet's raw #4f5b56 (issue Q3). */
  --btn-secondary-bg: light-dark(#ffffff, #21262d);
  --btn-secondary-fg: light-dark(#4f5b56, #ffffff);
  --btn-secondary-ink: light-dark(#0d1117, #ffffff);
  --btn-secondary-active-border: light-dark(transparent, #4b5563);
  --btn-secondary-active-inset: light-dark(transparent, rgba(13, 17, 23, 0.2));
  --btn-disabled-fg: light-dark(#8c96a3, #697582);
  --btn-disabled-icon: light-dark(#9aa6ac, #697582);
  /* Icon-only. */
  --btn-icon-primary-bg: light-dark(#0d1117, #064e3b);
  --btn-icon-primary-border: light-dark(#30363d, #4b5563);
  --btn-icon-primary-hover-bg: #0a8662;
  --btn-icon-primary-active-bg: light-dark(#065f46, #0a8662);
  /* Light: dark ink as the sheet renders it (issue Q4); dark: mint. */
  --btn-icon-secondary-glyph: light-dark(#0d1117, #34d399);
  --btn-icon-secondary-accent: light-dark(#0a8662, #34d399);
  --btn-icon-secondary-disabled: #697582;
  /* Danger (proposed, not in Figma: issue Q5). */
  --btn-danger-bg: #be123c;
  --btn-danger-hover-bg: #9f1239;
}

/* ---- Base and sizes ---- */
.btn {
  --btn-h: 36px; --btn-px: 14px; --btn-gap: 6px; --btn-r: var(--radius-md); --btn-r-primary: var(--radius);
  --btn-box: 30px; --btn-glyph: 12px; --btn-font: var(--type-button-m);
  --btn-icon: currentColor;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--btn-gap);
  box-sizing: border-box; min-height: var(--btn-h); padding: 0 var(--btn-px);
  border: 1px solid var(--border-control); border-radius: var(--btn-r);
  background: var(--btn-secondary-bg); color: var(--btn-secondary-fg);
  font: var(--btn-font); letter-spacing: normal; text-transform: none;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color var(--motion-fast, 120ms) var(--ease-standard, ease-in-out),
    border-color var(--motion-fast, 120ms) var(--ease-standard, ease-in-out),
    box-shadow var(--motion-fast, 120ms) var(--ease-standard, ease-in-out),
    color var(--motion-fast, 120ms) var(--ease-standard, ease-in-out);
}
@media (prefers-reduced-motion: reduce) { .btn { transition: none; } }
.btn-l, .btn-lg {
  --btn-h: 44px; --btn-px: 16px; --btn-gap: 8px; --btn-r: var(--radius); --btn-r-primary: var(--radius-lg);
  --btn-box: 35px; --btn-glyph: 14px; --btn-font: var(--type-button-l);
}
.btn-m { --btn-h: 36px; }
.btn-s, .btn-sm {
  --btn-h: 28px; --btn-px: 10px; --btn-gap: 4px; --btn-r: var(--radius-sm); --btn-r-primary: var(--radius-md);
  --btn-box: 24px; --btn-glyph: 10px; --btn-font: var(--type-button-s);
}
/* Glyphs: the icon slot's size, in the state's icon color. Stroke 2.5 of the
   24-unit Lucide grid draws about 1.4px at 10-14px, the weight of Figma's
   2px stroke on its own smaller glyph; the 18px ghost keeps Lucide's 2. */
.btn:where(:not(.btn-github)) > svg { flex: none; width: var(--btn-glyph); height: var(--btn-glyph); color: var(--btn-icon); stroke-width: 2.5; }
.btn > .inline-spinner { width: var(--btn-glyph); height: var(--btn-glyph); margin: 0; color: var(--btn-icon); }
.btn[aria-busy="true"] { cursor: progress; }
.btn-secondary { --btn-icon: var(--btn-secondary-ink); }
.btn-primary { border-radius: var(--btn-r-primary); }
.btn-icon { width: var(--btn-box); min-height: var(--btn-box); height: var(--btn-box); padding: 0; border-radius: var(--btn-r); }

/* ---- Secondary (the base) ---- */
.btn:where(:hover, .is-hover):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  background: var(--hover-tint); border-color: var(--hover-border); color: var(--btn-secondary-ink);
}
.btn:where([aria-pressed="true"], .is-selected):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  background: var(--selected-tint); border-color: var(--brand); color: var(--btn-secondary-ink);
  box-shadow: inset 0 0 0 1px var(--brand);
}
.btn:where(:active, .is-active):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  background: var(--pressed-tint); border-color: var(--btn-secondary-active-border); color: var(--btn-secondary-ink);
  box-shadow: inset 0 2px 3px var(--btn-secondary-active-inset);
}
.btn:where(:disabled, [aria-disabled="true"], .is-disabled) {
  --btn-icon: var(--btn-disabled-icon);
  background: var(--surface-disabled); border-color: transparent; color: var(--btn-disabled-fg);
  box-shadow: none; cursor: not-allowed;
}

/* ---- Primary ---- */
.btn-primary {
  --btn-icon: var(--brand-mint);
  background: var(--btn-primary-bg); border-color: transparent; color: var(--btn-on-fill);
}
.btn-primary:where(:hover, .is-hover):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  background: var(--btn-primary-hover-bg); border-color: transparent; color: var(--btn-on-fill); box-shadow: var(--shadow-brand-glow);
}
.btn-primary:where([aria-pressed="true"], .is-selected):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  background: var(--brand-selected); border-color: var(--brand); color: var(--btn-on-fill); box-shadow: inset 0 0 0 1px var(--brand);
}
.btn-primary:where(:active, .is-active):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  background: var(--brand-pressed); border-color: transparent; color: var(--btn-on-fill); box-shadow: var(--shadow-pressed);
}
.btn-primary:where(:disabled, [aria-disabled="true"], .is-disabled) {
  --btn-icon: var(--btn-disabled-icon);
  background: var(--surface-disabled); border-color: var(--btn-primary-disabled-border); color: var(--btn-primary-disabled-fg);
  box-shadow: none; cursor: not-allowed;
}

/* ---- Primary icon-only ---- */
.btn-icon.btn-primary {
  --btn-icon: var(--brand-mint);
  background: var(--btn-icon-primary-bg); border-color: var(--btn-icon-primary-border); box-shadow: var(--shadow-icon-btn);
}
/* Hover and press: a white glyph. Figma draws mint, 2.4:1 on that green,
   below the 3:1 an icon-only control needs (WCAG 1.4.11). */
.btn-icon.btn-primary:where(:hover, .is-hover):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  --btn-icon: var(--btn-on-fill);
  background: var(--btn-icon-primary-hover-bg); border-color: transparent; box-shadow: none;
}
.btn-icon.btn-primary:where([aria-pressed="true"], .is-selected):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  --btn-icon: var(--brand-mint);
  background: var(--brand-selected); border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand);
}
.btn-icon.btn-primary:where(:active, .is-active):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  --btn-icon: var(--btn-on-fill);
  background: var(--btn-icon-primary-active-bg); border-color: transparent; box-shadow: var(--shadow-pressed-soft);
}
.btn-icon.btn-primary:where(:disabled, [aria-disabled="true"], .is-disabled) {
  --btn-icon: var(--btn-disabled-icon);
  background: var(--surface-disabled); border-color: transparent; box-shadow: none;
}

/* ---- Secondary icon-only ---- */
.btn-icon.btn-secondary { --btn-icon: var(--btn-icon-secondary-glyph); }
.btn-icon.btn-secondary:where(:hover, .is-hover, [aria-pressed="true"], .is-selected, :active, .is-active):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  --btn-icon: var(--btn-icon-secondary-accent);
}
.btn-icon.btn-secondary:where(:active, .is-active):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  border-color: var(--border-control); box-shadow: var(--shadow-pressed-soft);
}

.btn-icon.btn-secondary:where(:disabled, [aria-disabled="true"], .is-disabled) { --btn-icon: var(--btn-icon-secondary-disabled); }

/* Ghost: no fill, no border, the page's text color; a grey wash on hover. */
.btn-ghost { border-color: transparent; background: none; color: var(--fg); }
.btn-ghost:where(:hover, .is-hover, :active, .is-active):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  background: var(--surface-sunken); border-color: transparent; color: var(--fg); box-shadow: none;
}
.btn-ghost:where(:disabled, [aria-disabled="true"], .is-disabled) { background: none; }

/* ---- Danger (proposed, not in Figma) ---- */
.btn-danger { --btn-icon: var(--danger-fg); border-color: var(--danger-fg); color: var(--danger-fg); }
.btn-danger:where(:hover, .is-hover):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  background: var(--danger-bg); border-color: var(--danger-fg); color: var(--danger-fg);
}
.btn-primary.btn-danger { --btn-icon: var(--btn-on-fill); background: var(--btn-danger-bg); border-color: transparent; color: var(--btn-on-fill); }
.btn-primary.btn-danger:where(:hover, .is-hover, :active, .is-active):where(:not(:disabled, [aria-disabled="true"], .is-disabled)) {
  background: var(--btn-danger-hover-bg); color: var(--btn-on-fill); box-shadow: none;
}
/* The filled one too: .btn-primary.btn-danger's fill otherwise outranks it. */
.btn-danger:where(:disabled, [aria-disabled="true"], .is-disabled),
.btn-primary.btn-danger:where(:disabled, [aria-disabled="true"], .is-disabled) {
  --btn-icon: var(--btn-disabled-icon);
  background: var(--surface-disabled); border-color: transparent; color: var(--btn-disabled-fg);
}
/* A ghost danger button (Revoke): the danger label with no border; disabled,
   it stays unfilled like any ghost. */
.btn-ghost.btn-danger { border-color: transparent; }
.btn-ghost.btn-danger:where(:disabled, [aria-disabled="true"], .is-disabled) { background: none; }

/* ---- Kept from the pre-v2 family ---- */
/* An icon button with no family (uiIconButton's ghost, the refresh button)
   keeps its 34px box and 18px glyph until its page migrates. */
.btn-icon:where(:not(.btn-primary, .btn-secondary)) { --btn-box: 34px; --btn-glyph: 18px; }
.btn-icon:where(:not(.btn-primary, .btn-secondary)) > svg { stroke-width: 2; }
.btn-sort { padding: 0; min-height: 0; border: 0; background: none; font: inherit; font-weight: 600; }
