/**
 * autowire — component layer
 *
 * Reusable blocks with variants: buttons, cards, forms, badges, messages.
 * A block is a flat noun (.card), a variant is a hyphenated sibling class
 * (.card-dark), state is .is-*.
 *
 * Load order:  tokens.css → tokens-app.css → base.css → components.css → <page>.css
 *
 * SHARED FILE — a byte-identical copy lives in the autowire-account repo.
 * Edit it here and run ./sync-design-system.sh from there; ./scripts-check.sh
 * fails on a hand-edited copy. See css/README.md.
 */


/* ═══════════════════════════════════════════════════════════════════════
   BUTTONS — all pills. Brand always carries black text (white on brand is
   1.18:1), and brand is never a thin element on white.
   ═══════════════════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--btn-h-md);
  padding: 0 var(--btn-px-md);
  border: 0;
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--btn-primary-fs);
  font-weight: var(--btn-primary-fw);
  line-height: 1;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.btn-primary { background: var(--btn-primary-bg); color: var(--btn-primary-fg); }
.btn-primary:hover { background: var(--color-brand-dark); }

.btn-dark { background: var(--btn-dark-bg); color: var(--btn-dark-fg); }
.btn-dark:hover { background: var(--color-black); }

/* The primary action on a brand band, where a brand pill would vanish. */
.btn-light { background: var(--color-white); color: var(--color-black); }
.btn-light:hover { background: var(--color-gray-200); }

.btn-secondary {
  background: var(--btn-secondary-bg);
  color: var(--btn-secondary-fg);
  box-shadow: inset 0 0 0 1px var(--border-strong);
}
.btn-secondary:hover { background: var(--btn-secondary-bg-hover); }
.section-dark .btn-secondary {
  color: var(--fg-on-dark);
  box-shadow: inset 0 0 0 1px var(--border-on-dark);
}
.section-dark .btn-secondary:hover { background: rgba(255, 255, 255, 0.08); }

.btn-sm    { height: var(--btn-h-sm); padding: 0 var(--btn-px-sm); font-size: var(--text-body-m); }
.btn-block { width: 100%; }
.btn-fit   { width: fit-content; }

/* A control that is unavailable is not a control that is busy: `not-allowed`
   for disabled, `progress` only while something is actually in flight. */
.btn[disabled], .btn.is-disabled {
  opacity: var(--opacity-disabled);
  cursor: not-allowed;
  pointer-events: none;
}
.btn.is-loading {
  opacity: var(--opacity-disabled);
  cursor: progress;
  pointer-events: none;
}

.btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); }

/* Destructive actions are text links, not buttons — they must be reachable
   but must not compete with the primary action. */
.btn-text {
  background: none;
  border: 0;
  padding: 0;
  height: auto;
  font-family: var(--font-sans);
  font-size: var(--text-body-s);
  color: var(--fg-secondary-strong);
  text-decoration: underline;
  text-underline-offset: 4px;
  cursor: pointer;
  width: fit-content;
}
.btn-text:hover { color: var(--fg-primary); }
.btn-text-danger { color: var(--fg-danger); }

/* A text link that has to read as an action, used where a pill is too loud. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-body-m);
  color: var(--fg-primary);
  text-decoration: underline;
  text-underline-offset: 4px;
  width: fit-content;
}

/* Paired CTAs: once they stop fitting side by side, stack them at equal width
   rather than leaving two differently sized pills. */
@media (max-width: 560px) {
  .btn-row { flex-direction: column; align-items: stretch; }
  .btn-row > .btn { width: 100%; }
  /* The text link stacks with the rest and centres like the pills above it. */
  .btn-row > .btn-text { width: 100%; text-align: center; }
}


/* ═══════════════════════════════════════════════════════════════════════
   CARDS
   Density is --card-gap: two tight lines on the marketing pages, whole
   sections on the account page, which turns it up once for the surface.
   ═══════════════════════════════════════════════════════════════════════ */

.card {
  background: var(--bg-card);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  padding: var(--card-padding-web);
  display: flex;
  flex-direction: column;
  gap: var(--card-gap);
}
.card-dark {
  background: var(--color-dark);
  border-color: var(--color-dark);
  color: var(--fg-on-dark);
}

.card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
}
.card-title {
  font-size: var(--text-h-card);
  font-weight: var(--fw-bold);
  line-height: var(--lh-snug);
  color: inherit;
}
.card-text {
  font-size: 15px;
  line-height: 1.55;
  color: var(--fg-secondary-strong);
}
.card-dark .card-text { color: var(--fg-on-dark-muted); }
.card-note {
  font-size: var(--text-body-s);
  line-height: var(--lh-loose);
  color: var(--fg-secondary-strong);
}
.card-body {
  font-size: var(--text-body-m);
  line-height: var(--lh-loose);
  color: var(--fg-secondary);
  max-width: 68ch;
}

/* Card with a 12px brand dot beside the text column — the design system's
   bullet-card pattern. The dot is decorative, so its 1.18:1 against white
   carries no meaning. */
.card-bullet { flex-direction: row; align-items: flex-start; gap: 14px; }
.card-bullet-dot {
  width: 12px; height: 12px;
  border-radius: var(--radius-pill);
  background: var(--color-brand);
  flex: none;
  margin-top: 6px;
}
.card-bullet-body { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }

/* A whole card that is a link. */
a.card { text-decoration: none; color: inherit; transition: border-color var(--transition-fast); }
a.card:hover { border-color: var(--border-strong); }
a.card .card-title { text-decoration: underline; text-underline-offset: 4px; }


/* ═══════════════════════════════════════════════════════════════════════
   FORMS
   ═══════════════════════════════════════════════════════════════════════ */

.field { display: flex; flex-direction: column; gap: var(--space-2); }

/* tokens.css colours bare <label> at --fg-label (#858585 — 3.75:1). */
.field-label {
  font-size: var(--input-label-fs);
  color: var(--fg-label-strong);
}

.input {
  width: 100%;
  height: var(--input-h-web);
  padding: 0 var(--space-4);
  background: var(--input-bg);
  border: var(--input-border);
  border-radius: var(--input-radius);
  font-family: var(--font-sans);
  font-size: var(--text-body-m);
  color: var(--fg-primary);
}
.input:focus { border-color: var(--input-border-focus); }
.input:disabled { background: var(--input-bg-disabled); color: var(--fg-disabled); }
.input.is-invalid, .is-invalid { border-color: var(--input-border-invalid); }


/* ═══════════════════════════════════════════════════════════════════════
   BADGES / STATUS CHIPS
   Colour never carries meaning alone — a badge always has text too.
   ═══════════════════════════════════════════════════════════════════════ */

.badge {
  display: inline-flex;
  align-items: center;
  height: var(--badge-h);
  padding: 0 var(--badge-px);
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--badge-fs);
  font-weight: var(--badge-fw);
  line-height: 1;
  white-space: nowrap;
  hyphens: none;
  background: var(--status-neutral-bg);
  color: var(--status-neutral-fg);
}
.badge-ok      { background: var(--status-ok-bg);      color: var(--status-ok-fg); }
.badge-neutral { background: var(--status-neutral-bg); color: var(--status-neutral-fg); }
.badge-off     { background: var(--status-off-bg);     color: var(--status-off-fg); }
.badge-warn    { background: var(--status-warn-bg);    color: var(--status-warn-fg); }

/* An outlined neutral reads as deliberate, not as "no data". */
.badge-neutral.badge-outlined { box-shadow: inset 0 0 0 1px var(--color-gray-500); }


/* ═══════════════════════════════════════════════════════════════════════
   BANNERS / INLINE MESSAGES

   .banner is the static form: the tone is in the markup and the box is
   always visible. A message whose tone is chosen at runtime uses the .is-*
   state form instead — see .form-status in account.css, which shares these
   tokens rather than these class names because its script builds the class
   as `is-${kind}`.
   ═══════════════════════════════════════════════════════════════════════ */

.banner {
  padding: var(--banner-py) var(--banner-px);
  border-radius: var(--banner-radius);
  font-size: 15px;
  line-height: 1.55;
}
.banner-info    { background: var(--bg-info-soft);    color: var(--fg-info); }
.banner-success { background: var(--bg-success-soft); color: var(--fg-success); }
.banner-warning { background: var(--bg-warning-soft); color: var(--fg-warning); }
.banner-danger  { background: var(--bg-danger-soft);  color: var(--fg-danger); }
.banner-neutral { background: var(--bg-neutral-soft); color: var(--fg-neutral); }
