/* SteadiLev Design System — components.css
   Component primitives. Sections populated by Tasks 7-12:
     Task 7  · Type presets (.t-*)
     Task 8  · Buttons (.btn)
     Task 9  · Badges (.badge)
     Task 10 · Inputs (.input)
     Task 11 · Cards (.card)
     Task 12 · Dividers (.divider) */

/* === Type presets ==============================================
   Display tier reconciled 2026-08-12 with the live steadilev.ai, which is
   fluid throughout. The old fixed caps land almost exactly on the live ones
   (80→82, 56→58, 40→38, 20→21), so this is the same ladder clamped, not a
   new one. The floors are what a phone gets; the caps are what a desktop got
   before and still gets.

   The h3 rung is Geist 400, not 900. That is a deliberate cliff: rungs above
   it are the shouting tier and hierarchy inside it comes from size, while h3
   is a component title sitting on top of body copy and wants to be read, not
   announced. It is the one display rung that is quieter than its neighbour. */

.t-display-xl { font-family: var(--font-display); font-weight: 900; font-size: clamp(38px, 6.1vw, 82px); line-height: 0.98; letter-spacing: -0.035em; }
.t-display    { font-family: var(--font-display); font-weight: 900; font-size: clamp(30px, 4.6vw, 58px); line-height: 1.04; letter-spacing: -0.028em; }
.t-h1         { font-family: var(--font-display); font-weight: 900; font-size: clamp(21px, 2.9vw, 38px); line-height: 1.08; letter-spacing: -0.028em; }
.t-h2         { font-family: var(--font-display); font-weight: 900; font-size: clamp(19px, 2.2vw, 28px); line-height: 1.16; letter-spacing: -0.020em; }
.t-h3         { font-family: var(--font-display); font-weight: 400; font-size: clamp(17px, 1.7vw, 21px); line-height: 1.15; letter-spacing: -0.010em; }
.t-body-lg    { font-family: var(--font-body);    font-weight: 400; font-size: clamp(15px, 1.4vw, 18px); line-height: 1.62; }
.t-body       { font-family: var(--font-body);    font-weight: 300; font-size: 15px; line-height: 1.65; }
.t-body-sm    { font-family: var(--font-body);    font-weight: 300; font-size: 13px; line-height: 1.50; color: var(--color-text-muted); }

/* Mono tier is LOWERCASE. This is the brand's most repeated element and the
   easiest one to get wrong: the identity is lowercase plus wide tracking, and
   uppercase mono reads as a different company. Tracking runs .16em-.24em;
   .t-meta sits mid-band for general labels, .t-eyebrow takes the top of it
   for the section eyebrow, which is the loudest label on any surface. */
.t-eyebrow    { font-family: var(--font-mono);    font-weight: 500; font-size: 11px; line-height: 1.40; letter-spacing: 0.24em; text-transform: lowercase; color: var(--color-accent); }
.t-meta       { font-family: var(--font-mono);    font-weight: 500; font-size: 11px; line-height: 1.40; letter-spacing: 0.18em; text-transform: lowercase; color: var(--color-text-muted); }
.t-code       { font-family: var(--font-mono);    font-weight: 400; font-size: 14px; line-height: 1.55; color: var(--color-accent-muted); }

/* === Buttons =================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  padding: 10px 18px;
  font-family: var(--font-body); font-weight: 500; font-size: 14px; line-height: 1;
  border: 1px solid transparent; border-radius: var(--radius-md);
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.btn-sm { padding: 7px 12px;  font-size: 12px; }
.btn-lg { padding: 14px 24px; font-size: 16px; }

/* Primary is the action colour, not the accent (reconciled 2026-08-12).
   Teal fill gives a 4.46:1 label, under the 4.5 floor; Soft Linen gives 16.8:1
   and keeps Teal as the identity colour rather than the loudest object. */
.btn-primary { background: var(--color-action); color: var(--color-action-ink); border-color: var(--color-action); }
.btn-primary:hover { background: var(--color-action-lift); border-color: var(--color-action-lift); }

.btn-secondary {
  background: transparent; color: var(--color-trust);
  border-color: color-mix(in srgb, var(--color-trust) var(--tint-line), transparent);
}
.btn-secondary:hover { background: color-mix(in srgb, var(--color-trust) var(--tint-soft), transparent); }

.btn-ghost { background: transparent; color: var(--color-text); border-color: var(--color-border); }
.btn-ghost:hover { border-color: var(--color-text-muted); }

.btn-danger { background: var(--color-danger); color: var(--color-bg); }
.btn-danger:hover { background: color-mix(in srgb, var(--color-danger) 90%, white); }

.btn-link {
  background: none; border: none; padding: 0;
  color: var(--color-accent);
  text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--color-accent) var(--tint-line), transparent);
}
.btn-link:hover { text-decoration-color: var(--color-accent); }

/* === Badges ==================================================== */

/* Stamp / serial-plate aesthetic (2026-06-08): 4px corners, solid fill,
   inverse text, slight inset shadow for the punched-ticket feel.
   Deliberately NOT the pill + tinted-bg + colored-dot pattern that
   Anthropic / Linear / Cursor share. Steady weight, no soft flourish.
   .badge-dot is retained as an opt-in element for callers that want a
   leading status mark, but the default badge no longer has one.
   Cased down 2026-08-12: the stamp rationale is about shape and fill, which
   are untouched. Case belongs to the mono tier, and that tier is lowercase. */
.badge {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 3px 9px;
  border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-weight: 700; font-size: 11px; line-height: 1.4;
  letter-spacing: 0.16em; text-transform: lowercase;
  box-shadow: inset 0 -1px 0 0 rgba(0,0,0,0.18);
}
.badge-dot { width: 6px; height: 6px; border-radius: var(--radius-full); background: currentColor; opacity: 0.85; }

.badge-accent  { background: var(--color-accent);       color: var(--color-bg); }
.badge-success { background: var(--color-success);      color: var(--color-bg); }
.badge-danger  { background: var(--color-danger);       color: var(--color-bg); }
.badge-trust   { background: var(--color-accent-muted); color: var(--color-bg); }
.badge-neutral { background: var(--color-text-muted);   color: var(--color-bg); }

/* === Inputs ==================================================== */

.input {
  background: var(--color-bg); color: var(--color-text);
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  padding: 10px 14px;
  font-family: var(--font-body); font-size: 14px; line-height: 1.4;
  min-width: 260px;
}
.input::placeholder { color: var(--color-text-dim); }
.input:focus-visible {
  outline: 2px solid var(--color-action);
  outline-offset: 3px;
  border-color: var(--color-accent);
}

/* === Cards ===================================================== */

/* A card is an object you are meant to read as an object, so its edge is
   --color-border, not --color-border-subtle (reconciled 2026-08-12). Subtle
   on Onyx is ~1.3:1 and vanishes on a projector. */
.card {
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.card-eyebrow { color: var(--color-accent); margin-bottom: var(--space-2); }
.card-title   { margin: var(--space-2) 0 var(--space-2); }
.card-body    { color: var(--color-text-muted); }

.card-interactive { cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease; }
.card-interactive:hover { border-color: color-mix(in srgb, var(--color-accent) var(--tint-line), transparent); }

.card-featured {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--color-accent) var(--tint-glow), transparent),
    0 12px 40px -10px rgba(0, 0, 0, 0.7);
}

/* === Dividers ================================================== */

/* A divider is a rule between things, so it is the hairline weight. */
.divider { height: 1px; background: var(--color-hairline); border: none; margin: 0; }
