/* ─────────────────────────────────────────────────────────────────────────────
   COMPONENT STYLES — Danbi

   Plain CSS, built entirely on the design tokens. The React primitives in
   components/ are thin: they emit this markup + these class names. Shipping the
   classes (via styles.css) means a consumer can use the look with or without the
   JSX. Brutalist rules of the house:
     · corners sharp (radius 0–2px)        · borders honest (hairline + structural)
     · solid controls press into the page  · mono + uppercase before icons
   ──────────────────────────────────────────────────────────────────────────── */

/* ── Button ──────────────────────────────────────────────────────────────── */
.ha-btn {
  font-family: var(--font-mono);
  font-size: var(--btn-size);
  font-weight: var(--weight-medium);
  letter-spacing: var(--label-track);
  text-transform: var(--label-transform);
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.5em 1em;
  border: var(--border-1) solid var(--line-strong);
  border-radius: var(--radius-1);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  /* Only transition transform + shadow — NOT background/color. Those tokens change
     on a theme flip, and an in-flight colour transition freezes at its start value. */
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.ha-btn:focus-visible {
  outline: var(--focus-width) solid var(--focus-ring);
  outline-offset: var(--focus-offset);
}
.ha-btn--sm { font-size: var(--text-xs); padding: 0.4em 0.8em; }
.ha-btn--lg { font-size: var(--text-base); padding: 0.7em 1.4em; }
.ha-btn--icon { padding: 0.5em; aspect-ratio: 1; }

/* Solid variants carry the signature hard shadow + press */
.ha-btn--primary {
  background: var(--primary); color: var(--primary-ink); border-color: var(--primary);
  box-shadow: var(--shadow-block-sm);
}
/* Brutalist themes keep the crisp dark edge on the filled button. */
[data-theme='hanji'] .ha-btn--primary,
[data-theme='meok'] .ha-btn--primary,
[data-theme='dark'] .ha-btn--primary,
[data-theme='terminal'] .ha-btn--primary,
[data-theme='contrast'] .ha-btn--primary {
  border-color: var(--primary-active);
}
.ha-btn--primary:hover { background: var(--primary-hover); }
.ha-btn--primary:active { background: var(--primary-active); transform: translate(1px, 1px); box-shadow: none; }

.ha-btn--danger {
  background: var(--oxide-500); color: var(--stone-50); border-color: var(--oxide-700);
  box-shadow: var(--shadow-block-sm);
}
.ha-btn--danger:hover { background: var(--oxide-600); }
.ha-btn--danger:active { background: var(--oxide-700); transform: translate(1px, 1px); box-shadow: none; }

/* Tint = the logomark's light-celadon band, solid like primary but quieter —
   a brand accent for calls-to-action that shouldn't shout. Theme-invariant
   (see the --tint tokens in colors.css). */
.ha-btn--tint {
  background: var(--tint); color: var(--tint-ink); border-color: var(--tint);
  box-shadow: var(--shadow-block-sm);
}
.ha-btn--tint:hover  { background: var(--tint-hover); }
.ha-btn--tint:active { background: var(--tint-active); transform: translate(1px, 1px); box-shadow: none; }

/* Secondary = outline; ghost = quiet. Both flat. */
.ha-btn--secondary { background: var(--surface); color: var(--ink); border-color: var(--line-strong); }
.ha-btn--secondary:hover { background: var(--bg-sunken); }
.ha-btn--secondary:active { background: var(--surface-inset); }

.ha-btn--ghost { background: transparent; color: var(--ink-muted); border-color: transparent; }
.ha-btn--ghost:hover { background: var(--bg-sunken); color: var(--ink); }
.ha-btn--ghost:active { background: var(--surface-inset); }

.ha-btn:disabled, .ha-btn[aria-disabled='true'] {
  opacity: 0.45; cursor: not-allowed; pointer-events: none;
  transform: none !important; box-shadow: none !important;
}

/* ── GateChip — the deterministic gate milestone (signature) ─────────────── */
.ha-gate {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  letter-spacing: 0.02em;
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.28em 0.6em;
  border: var(--border-hair) solid var(--idle-line);
  border-radius: var(--radius-1);
  background: transparent;
  color: var(--idle-fg);
}
.ha-gate__mark { display: inline-block; font-weight: var(--weight-semibold); }
.ha-gate--idle  { opacity: 0.6; }
.ha-gate--start { color: var(--run-fg);  background: var(--run-bg);  border-color: var(--run-line); }
.ha-gate--pass  { color: var(--pass-fg); background: transparent; border-color: var(--pass-line); }
.ha-gate--fail  { color: var(--fail-fg); background: var(--fail-bg); border-color: var(--fail-line); }
/* The running mark spins as a CSS ring, not the ⟳ glyph — a text glyph's ink is
   off-center in its em box, so rotating it wobbles. The glyph stays in the markup
   (copy/paste, screen readers) but its ink is hidden; the ring is drawn with
   borders and rotates around its true center. */
.ha-gate--start .ha-gate__mark {
  width: 0.8em; height: 0.8em; box-sizing: border-box;
  overflow: hidden; text-indent: 5em; white-space: nowrap;
  border: 1.5px solid currentColor; border-right-color: transparent;
  border-radius: 50%; vertical-align: -0.05em;
  animation: ha-spin 0.9s linear infinite;
}

/* ── StatusBadge — task lifecycle state ──────────────────────────────────── */
.ha-badge {
  font-family: var(--font-mono);
  font-size: var(--text-xs);   /* matches .ha-gate — one uniform chip size */
  font-weight: var(--label-weight);
  text-transform: var(--label-transform);
  letter-spacing: var(--label-track);
  display: inline-flex; align-items: center; gap: 0.4em;
  padding: 0.28em 0.6em;   /* matches .ha-gate */
  border: var(--border-hair) solid;
  border-radius: var(--radius-1);
}
.ha-badge__dot { width: 0.5em; height: 0.5em; border-radius: var(--radius-pill); background: currentColor; }
.ha-badge--in_progress { color: var(--run-fg);  background: var(--run-bg);  border-color: var(--run-line); }
.ha-badge--in_progress .ha-badge__dot { animation: ha-pulse 1.5s ease-in-out infinite; }
.ha-badge--done    { color: var(--pass-fg); background: transparent; border-color: var(--pass-line); }
.ha-badge--blocked { color: var(--fail-fg); background: var(--fail-bg); border-color: var(--fail-line); }
.ha-badge--cloud   { color: var(--cloud-ink); background: var(--cloud-soft); border-color: var(--cloud); }
.ha-badge--neutral { color: var(--ink-muted); background: transparent; border-color: var(--idle-line); }

/* ── Tag — small mono marker (UI tag, model kind, etc.) ──────────────────── */
.ha-tag {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--label-weight);
  text-transform: var(--label-transform);
  letter-spacing: var(--tracking-wide);
  display: inline-flex; align-items: center;
  padding: 0.15em 0.45em;
  border: var(--border-hair) solid var(--line);
  border-radius: var(--radius-1);
  color: var(--ink-muted);
  background: transparent;
}
.ha-tag--solid   { background: var(--ink); color: var(--ink-invert); border-color: var(--ink); }
.ha-tag--primary { background: var(--primary-soft); color: var(--pass-fg); border-color: var(--pass-line); }
.ha-tag--cloud   { background: var(--cloud-soft); color: var(--cloud-ink); border-color: var(--cloud); }

/* ── Kbd — keycap ────────────────────────────────────────────────────────── */
.ha-kbd {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1;
  display: inline-flex; align-items: center;
  padding: 0.3em 0.5em;
  border: var(--border-hair) solid var(--line-strong);
  border-bottom-width: var(--border-2);
  border-radius: var(--radius-1);
  background: var(--surface);
  color: var(--ink);
}

/* ── Panel — brutalist bordered surface ──────────────────────────────────── */
.ha-panel {
  background: var(--surface);
  border: var(--border-1) solid var(--line-strong);
  border-radius: var(--radius-0);
  padding: var(--space-4);
}
.ha-panel--raised { box-shadow: var(--shadow-block); }
.ha-panel--flush  { padding: 0; }
.ha-panel__head {
  display: flex; align-items: center; gap: var(--space-3);
  margin: 0 0 var(--space-3);
}
.ha-panel__title {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--label-weight-strong);
  text-transform: var(--label-transform);
  letter-spacing: var(--label-track);
  color: var(--ink-faint);
  margin: 0;
}
.ha-panel__head .ha-panel__title { flex: 1; }

/* ── Field — labelled input ──────────────────────────────────────────────── */
.ha-field { display: flex; flex-direction: column; gap: 0.45em; }
.ha-field__label {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--label-weight);
  text-transform: var(--label-transform);
  letter-spacing: var(--label-track);
  color: var(--ink-muted);
}
.ha-field__control {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink);
  background: var(--surface-inset);
  border: var(--border-1) solid var(--line-strong);
  border-radius: var(--radius-1);
  padding: 0.55em 0.7em;
  width: 100%;
  /* Transition border-color + box-shadow only. Excluding `background` is deliberate:
     --surface-inset changes on a theme flip, and a transitioning background freezes
     at its pre-flip value (e.g. a dark input stuck on a light page). */
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.ha-field__control::placeholder { color: var(--ink-faint); }
.ha-field__control:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: inset 0 0 0 1px var(--primary);
}
.ha-field__control:disabled { opacity: 0.5; cursor: not-allowed; }
.ha-field__hint { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--ink-faint); }
.ha-field--error .ha-field__control { border-color: var(--fail-line); }
.ha-field--error .ha-field__hint { color: var(--fail-fg); }

/* ── TaskRow — one row of the run ledger ─────────────────────────────────── */
.ha-task {
  background: var(--surface);
  border: var(--border-1) solid var(--line);
  border-radius: var(--radius-0);
  border-left: var(--border-structural) solid var(--idle-line);
  padding: var(--space-3) var(--space-4);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.ha-task--in_progress { border-left-color: var(--run-line); }
.ha-task--done    { border-left-color: var(--pass-line); }
.ha-task--blocked { border-left-color: var(--fail-line); }
.ha-task__head { display: flex; align-items: center; gap: var(--space-3); }
.ha-task__id {
  font-family: var(--font-mono); font-weight: var(--weight-semibold);
  font-size: var(--text-sm); color: var(--ink); white-space: nowrap;
}
.ha-task__spacer { flex: 1; }
.ha-task__meta {
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink-muted);
  display: flex; gap: var(--space-4); flex-wrap: wrap;
}
.ha-task__meta b { color: var(--ink); font-weight: var(--weight-medium); }
.ha-task__gates { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* ── Shared keyframes ────────────────────────────────────────────────────── */
@keyframes ha-spin { to { transform: rotate(360deg); } }
@keyframes ha-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) {
  .ha-gate--start .ha-gate__mark, .ha-badge--in_progress .ha-badge__dot { animation: none; }
}

/* ── Concrete grain — the brand's one organic gesture against the grid ────── */
.ha-grain { position: relative; isolation: isolate; }
.ha-grain::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.04;
}
