/* =============================================================
 * OxyLo — components (2026-09-23)
 * =============================================================
 * The classes the templates are meant to use, defined entirely
 * from --ox-* tokens. Load AFTER oxylo-theme-v2.css.
 *
 * WHY THIS FILE EXISTS
 * --------------------
 * The templates were written in Bootstrap's vocabulary: 350 uses
 * of `.btn`, 307 of `.form-control`, 314 of `.text-muted`. That
 * means Bootstrap decides the border width, the padding, the
 * radius and the hover of every control, and the --ox-* tokens
 * never get a say. Changing what a secondary button looks like
 * meant editing 165 places or fighting specificity from CSS.
 *
 * These classes take that decision back. Every value here is a
 * var(); there is not a single raw px or hex in the file, which
 * is the property that makes a re-skin one edit rather than a
 * search. If you add a rule, keep it that way.
 *
 * BOOTSTRAP STAYS
 * ---------------
 * Its reset, its 12-column grid and its JS behaviours (dropdown,
 * modal, collapse) are still loaded and still used. What stops
 * being used is its *look*: components and utilities. Migration
 * is per-template and reversible — a page not yet converted goes
 * on working, because Bootstrap is still there.
 *
 * Paired with templates/_ui.html, which is how templates reach
 * these without writing class strings by hand.
 * ============================================================= */


/* -------------------------------------------------------------
 * Buttons
 * -------------------------------------------------------------
 * One shape, three variants, two sizes. `outline` is the default
 * because most actions in this app are secondary — the primary
 * one is usually a single submit at the end of a form.
 * ------------------------------------------------------------- */
.ox-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ox-space-2);

  font-family: var(--ox-font-sans);
  font-size: var(--ox-fs-sm);
  font-weight: var(--ox-weight-medium);
  line-height: var(--ox-lh-tight);

  padding: var(--ox-space-2) var(--ox-space-3);
  border: var(--ox-bw-hairline) solid transparent;
  border-radius: var(--ox-radius-md);

  background: transparent;
  color: var(--ox-ink);
  cursor: pointer;
  text-decoration: none;
  /* A tap target somebody can actually hit, stated once. */
  min-height: 2.25rem;
}
.ox-btn:hover     { text-decoration: none; }
.ox-btn:focus-visible {
  outline: var(--ox-bw-focus) solid var(--ox-accent);
  outline-offset: var(--ox-bw-hairline);
}
.ox-btn:disabled,
.ox-btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }

.ox-btn--primary {
  background: var(--ox-brand);
  border-color: var(--ox-brand);
  color: var(--ox-surface-raised);
  font-weight: var(--ox-weight-semibold);
}
.ox-btn--primary:hover   { background: var(--ox-brand-hover); border-color: var(--ox-brand-hover); color: var(--ox-surface-raised); }
.ox-btn--primary:active  { background: var(--ox-brand-pressed); border-color: var(--ox-brand-pressed); }

.ox-btn--outline {
  background: var(--ox-surface-raised);
  border-color: var(--ox-hairline-strong);
  color: var(--ox-ink);
}
.ox-btn--outline:hover  { background: var(--ox-surface-sunken); color: var(--ox-ink); }

.ox-btn--quiet { color: var(--ox-ink-secondary); }
.ox-btn--quiet:hover { background: var(--ox-surface-sunken); color: var(--ox-ink); }

.ox-btn--danger {
  background: var(--ox-surface-raised);
  border-color: var(--ox-danger-line);
  color: var(--ox-danger-ink);
}
.ox-btn--danger:hover { background: var(--ox-danger-tint); color: var(--ox-danger-ink); }

.ox-btn--sm   { font-size: var(--ox-fs-xs); padding: var(--ox-space-1) var(--ox-space-2); min-height: 2rem; }
.ox-btn--wide { width: 100%; }


/* -------------------------------------------------------------
 * Form fields
 * -------------------------------------------------------------
 * label + control + help, as one unit. `form-label` and
 * `form-control` appeared 222 and 307 times as a pair; this is
 * that pair, said once.
 * ------------------------------------------------------------- */
.ox-field { display: block; margin-bottom: var(--ox-space-4); }

.ox-field__label {
  display: block;
  font-size: var(--ox-fs-xs);
  font-weight: var(--ox-weight-semibold);
  color: var(--ox-ink);
  margin-bottom: var(--ox-space-1);
}
.ox-field__req { color: var(--ox-danger); font-weight: var(--ox-weight-normal); }

.ox-input {
  display: block;
  width: 100%;
  box-sizing: border-box;

  font-family: var(--ox-font-sans);
  font-size: var(--ox-fs-sm);
  line-height: var(--ox-lh-body);
  color: var(--ox-ink);

  padding: var(--ox-space-2) var(--ox-space-3);
  border: var(--ox-bw-hairline) solid var(--ox-hairline-strong);
  border-radius: var(--ox-radius-md);
  background: var(--ox-surface-raised);
  min-height: 2.25rem;
}
.ox-input:focus-visible {
  outline: var(--ox-bw-focus) solid var(--ox-accent);
  outline-offset: 0;
  border-color: var(--ox-accent);
}
.ox-input::placeholder { color: var(--ox-ink-faint); }
.ox-input:disabled { background: var(--ox-surface-sunken); color: var(--ox-ink-muted); }

/* Anything countable reads in mono: identifiers, quantities,
 * dates, passage numbers. Stated here so a form does not have to
 * remember. */
.ox-input--mono { font-family: var(--ox-font-mono); }

.ox-field__help  { font-size: var(--ox-fs-xs); color: var(--ox-ink-muted); margin-top: var(--ox-space-1); }
.ox-field__error { font-size: var(--ox-fs-xs); color: var(--ox-danger-ink); margin-top: var(--ox-space-1); }

/* A boolean is a checkbox and its label on one line — the shape
 * Phase 7 asks for, so it is not invented six times. */
.ox-check { display: flex; align-items: flex-start; gap: var(--ox-space-2); margin-bottom: var(--ox-space-2); }
.ox-check__box   { width: 1rem; height: 1rem; margin-top: 0.15rem; flex-shrink: 0; accent-color: var(--ox-brand); }
.ox-check__label { font-size: var(--ox-fs-sm); line-height: var(--ox-lh-body); color: var(--ox-ink); }


/* -------------------------------------------------------------
 * Cards
 * ------------------------------------------------------------- */
.ox-card {
  background: var(--ox-surface-raised);
  border: var(--ox-bw-hairline) solid var(--ox-hairline);
  border-radius: var(--ox-radius-lg);
  margin-bottom: var(--ox-space-5);
}
.ox-card__head {
  display: flex;
  align-items: center;
  gap: var(--ox-space-2);
  padding: var(--ox-space-3) var(--ox-space-4);
  border-bottom: var(--ox-bw-hairline) solid var(--ox-hairline-soft);
  font-size: var(--ox-fs-sm);
  font-weight: var(--ox-weight-semibold);
}
.ox-card__body { padding: var(--ox-space-4); }
.ox-card__foot {
  padding: var(--ox-space-3) var(--ox-space-4);
  border-top: var(--ox-bw-hairline) solid var(--ox-hairline-soft);
  background: var(--ox-surface-footer);
  font-size: var(--ox-fs-xs);
  color: var(--ox-ink-muted);
}


/* -------------------------------------------------------------
 * Tables
 * ------------------------------------------------------------- */
.ox-table { width: 100%; border-collapse: collapse; font-size: var(--ox-fs-sm); }
.ox-table th {
  text-align: left;
  font-size: var(--ox-fs-xxs);
  font-weight: var(--ox-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ox-ink-secondary);
  padding: var(--ox-space-2) var(--ox-space-3);
  border-bottom: var(--ox-bw-hairline) solid var(--ox-hairline-table);
  background: var(--ox-surface-header);
}
.ox-table td {
  padding: var(--ox-space-3);
  border-bottom: var(--ox-bw-hairline) solid var(--ox-hairline-soft);
  vertical-align: middle;
}
.ox-table tbody tr:hover { background: var(--ox-surface-footer); }
.ox-table__num { font-family: var(--ox-font-mono); }
.ox-table__actions { text-align: right; white-space: nowrap; }


/* -------------------------------------------------------------
 * Text roles
 * -------------------------------------------------------------
 * `text-muted` appeared 314 times and is Bootstrap's grey, not
 * --ox-ink-muted. These say the role rather than the colour.
 * ------------------------------------------------------------- */
.ox-meta    { font-size: var(--ox-fs-xs); color: var(--ox-ink-muted); }
.ox-caption { font-size: var(--ox-fs-xs); color: var(--ox-ink-secondary); }
.ox-eyebrow {
  font-size: var(--ox-fs-xxs);
  font-weight: var(--ox-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ox-ink-secondary);
}


/* -------------------------------------------------------------
 * Category marks — the notebook-template section types
 * -------------------------------------------------------------
 * Two classes, on purpose. `.ox-cat-N` only declares which step of
 * the ramp applies and paints nothing; `.ox-cat-icon` and
 * `.ox-cat-edge` are what consume it. That way a card can carry the
 * step and the icon inside it inherits, without the card's own text
 * turning violet.
 *
 * Both consumers fall back, so a section type nobody has styled gets
 * a muted icon and a hairline rule rather than a transparent border
 * and a black icon that looks deliberate.
 * ------------------------------------------------------------- */
.ox-cat-1 { --ox-cat: var(--ox-cat-1); }
.ox-cat-2 { --ox-cat: var(--ox-cat-2); }
.ox-cat-3 { --ox-cat: var(--ox-cat-3); }
.ox-cat-4 { --ox-cat: var(--ox-cat-4); }
.ox-cat-5 { --ox-cat: var(--ox-cat-5); }
.ox-cat-6 { --ox-cat: var(--ox-cat-6); }
.ox-cat-7 { --ox-cat: var(--ox-cat-7); }

.ox-cat-icon { color: var(--ox-cat, var(--ox-ink-muted)); }

.ox-cat-edge {
  border-inline-start: var(--ox-bw-edge) solid
                       var(--ox-cat, var(--ox-hairline-strong));
}
