/* ============================================================
   jb-v2.css — JobBored visual refactor (Atlas / Phase 1)
   ------------------------------------------------------------
   Owner:    Atlas (foundation agent)
   Purpose:  Body-scoped base typography and document-level
             styles for the v2 design system. Consumes tokens
             defined in tokens-v2.css.
   Additivity guarantee:
             Every rule is scoped under `body.jb-v2`. This file
             is purely additive and has ZERO effect on the
             legacy UI when the `jb-v2` class is absent from
             <body>. No component styles live here — Forge
             owns components in Phase 2.
   ============================================================ */

/* Fonts loaded via <link> in index.html (see docs/redesign/jb-fonts-perf.md). */

body.jb-v2 {
  --jb-flow-max: 1220px;
  --jb-flow-gutter: clamp(16px, 3vw, 32px);
  --jb-flow-content-width: min(
    var(--jb-flow-max),
    calc(100% - var(--jb-flow-gutter) - var(--jb-flow-gutter))
  );
  background: var(--jb-paper);
  color: var(--jb-ink);
  font-family: var(--jb-font-body);
  font-size: var(--jb-text-base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

:where(body.jb-v2) h1,
:where(body.jb-v2) h2 {
  font-family: var(--jb-font-display);
  line-height: 1.05;
  letter-spacing: 0;
  font-weight: 600;
  color: var(--jb-ink);
}

:where(body.jb-v2) h3,
:where(body.jb-v2) h4,
:where(body.jb-v2) h5,
:where(body.jb-v2) h6 {
  font-family: var(--jb-font-body);
  font-weight: 600;
  color: var(--jb-ink);
  line-height: 1.25;
}

body.jb-v2 a {
  color: var(--jb-mint-deep);
  text-decoration: none;
  transition: color var(--jb-transition-fast);
}

body.jb-v2 a:hover {
  text-decoration: underline;
  color: var(--jb-mint-deep);
}

body.jb-v2 ::selection {
  background: var(--jb-mint-tint);
  color: var(--jb-ink);
}

/* Focus: 2px navy ring on a 2px paper gap, 12:1 (AX-11). */
body.jb-v2 :focus-visible {
  outline: 2px solid var(--jb-focus-color);
  outline-offset: 2px;
  border-radius: var(--jb-radius-sm);
}

body.jb-v2 .jb-mono {
  font-family: var(--jb-font-mono);
  font-feature-settings: "ss01", "cv11";
}

@media (prefers-reduced-motion: reduce) {
  body.jb-v2 *,
  body.jb-v2 *::before,
  body.jb-v2 *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* Applied-age badge — lightly surfaces how long ago a role was applied to,
   colored worse the longer it's been (fresh -> aging -> stale -> cold).
   Shared, unscoped class so both v2 boards (pipeline + lattice) reuse it. */
.jb-applied-age {
  display: inline-flex;
  align-items: center;
  font-size: var(--jb-type-label);
  font-weight: 600;
  line-height: 1.5;
  padding: 0 7px;
  border-radius: var(--jb-radius-pill);
  white-space: nowrap;
  letter-spacing: 0.01em;
}
.jb-applied-age[data-age="fresh"] { color: var(--jb-ok); background: var(--jb-ok-tint); }
.jb-applied-age[data-age="aging"] { color: var(--jb-warn); background: var(--jb-warn-tint); }
.jb-applied-age[data-age="stale"] { color: var(--jb-ink); background: var(--jb-amber-soft); }
.jb-applied-age[data-age="cold"]  { color: var(--jb-err); background: var(--jb-err-tint); }

/* Discovery run-status button states — renderDiscoveryRunStatus()
   (discovery-status-handoff.js) toggles run-<status> classes on
   #discoveryBtn. Active runs take minutes; the kickoff toast auto-dismisses
   in seconds, so the button itself carries a pulsing dot while a run is
   live and flashes once on a terminal outcome. Shared, unscoped classes
   like .jb-applied-age above — the button renders in both UIs. */
.btn-discovery.run-pending::before,
.btn-discovery.run-running::before,
.btn-discovery.run-polling_error::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent, var(--jb-mint));
  animation: jb-run-pulse 1.2s ease-in-out infinite;
}
.btn-discovery.run-polling_error::before {
  background: var(--jb-amber);
}
.btn-discovery.run-completed,
.btn-discovery.run-empty {
  animation: jb-run-flash-ok 1.4s ease-out 1;
}
.btn-discovery.run-partial {
  animation: jb-run-flash-warn 1.4s ease-out 1;
}
.btn-discovery.run-failed {
  animation: jb-run-flash-fail 1.4s ease-out 1;
}
@keyframes jb-run-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.72); }
}
@keyframes jb-run-flash-ok {
  0% { background: rgba(89, 203, 137, 0.4); }
  100% { background: var(--surface, transparent); }
}
@keyframes jb-run-flash-warn {
  0% { background: rgba(234, 179, 8, 0.4); }
  100% { background: var(--surface, transparent); }
}
@keyframes jb-run-flash-fail {
  0% { background: rgba(239, 68, 68, 0.4); }
  100% { background: var(--surface, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .btn-discovery.run-pending::before,
  .btn-discovery.run-running::before,
  .btn-discovery.run-polling_error::before,
  .btn-discovery.run-completed,
  .btn-discovery.run-empty,
  .btn-discovery.run-partial,
  .btn-discovery.run-failed {
    animation: none;
  }
}

/* Materials queue — stalled-heartbeat pill (materials-queue.js). A
   non-terminal phase whose worker heartbeat is >10min old renders
   STALLED? instead of an eternally climbing DRAFTING timer. */
.mq__phase[data-phase="stalled"] {
  background: rgba(192, 76, 76, 0.14);
  border-color: rgba(192, 76, 76, 0.5);
  color: var(--jb-err);
}
