/* Project Health dashboard: bright redesign (#428). Appearance only: no layout, data or behaviour changes.
   Loaded last on project-health.html. Rollback: remove the <link>.
   Reference: the approved A+C blend mockup (kept outside the repo so it is not served publicly) */

html { background: #fff; }

html body {
  --ink: #15111a;
  --muted: #5f5968;
  --line: #e8e7ef;
  --accent: #5b4de6;
  --mock-purple: #5b4de6;
  --soft: #f8f7ff;
  --good: #12805f;
  --warn: #b45309;
  --danger: #c2362b;
  --radius: 22px;
  --rd-pink: #f0408f;
  --rd-pink-soft: #ff5fa2;
  --rd-acid: #f4ff52;
  background: transparent !important;
  color: var(--ink);
  overflow-x: hidden;
}

/* quiet grid + colour wash behind the top of the page */
html body::before,
html body::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: -2;
  pointer-events: none;
}
html body::before {
  height: 520px;
  background:
    linear-gradient(90deg, rgba(21, 17, 26, 0.04) 1px, transparent 1px),
    linear-gradient(0deg, rgba(21, 17, 26, 0.04) 1px, transparent 1px);
  background-size: 42px 42px;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
}
html body::after {
  height: 440px;
  background:
    radial-gradient(circle at 14% 20%, rgba(255, 95, 162, 0.14), transparent 30%),
    radial-gradient(circle at 80% 10%, rgba(244, 255, 82, 0.28), transparent 28%),
    radial-gradient(circle at 92% 50%, rgba(0, 191, 214, 0.12), transparent 30%);
}

html body .shell { max-width: 1240px; }

/* top bar: same brand mark as the portfolio */
html body .topbar .brand { font-weight: 950; letter-spacing: -0.035em; }
html body .topbar .brand::before {
  content: "";
  display: inline-block;
  width: 18px;
  height: 18px;
  margin-right: 9px;
  vertical-align: -3px;
  border: 2px solid var(--ink);
  border-radius: 6px;
  background: linear-gradient(135deg, #fff 0 42%, var(--rd-acid) 42% 100%);
  box-shadow: 3px 3px 0 var(--ink);
}

/* title */
html body h1 {
  font-size: clamp(44px, 5.6vw, 76px);
  line-height: 0.95;
  letter-spacing: -0.02em;
  word-spacing: 0.02em;
  font-weight: 700;
}
html body .hero h1::after {
  content: "";
  display: block;
  width: 88px;
  height: 9px;
  margin-top: 16px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--rd-pink-soft), var(--rd-acid));
}
html body .eyebrow { color: var(--accent); font-weight: 900; }
html body .lede { font-size: 17px; color: var(--muted); }

/* buttons: pills */
html body .button {
  min-height: 40px;
  border: 1px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  font-weight: 800;
  box-shadow: none;
  transition: transform 180ms ease, box-shadow 180ms ease;
}
html body .button:hover:not([disabled]) { transform: translateY(-2px); box-shadow: 0 12px 24px rgba(21, 17, 26, 0.12); background: #fff; border-color: var(--ink); }
html body .button.primary { background: var(--ink); border-color: var(--ink); color: #fff; }
html body .button[disabled] { border-color: var(--line); color: var(--muted); }
/* a disabled primary (e.g. "Run all AI evals" during the run cooldown) matches other disabled buttons, not grey-on-grey */
html body .button.primary[disabled] { background: #f3f2f7; border-color: var(--line); color: var(--muted); }

/* project chooser cards */
html body .project-card {
  border: 1px solid var(--line);
  border-radius: 24px;
  background: #fff;
  box-shadow: none;
  transition: transform 220ms ease, box-shadow 220ms ease;
}
html body .project-card:hover { transform: translateY(-4px); box-shadow: 0 22px 50px rgba(21, 17, 26, 0.1); }
html body .overview-grid .project-card.project-card.active,
html body .project-card.active {
  border-color: var(--ink);
  outline: 0;
  background: linear-gradient(145deg, #fff1fa, #f5f0ff 55%, #e8fbff) !important;
  box-shadow: 5px 5px 0 var(--ink);
  transform: none;
}

/* selected project panel */
html body .detail-head h2 { letter-spacing: -0.02em; word-spacing: 0.02em; font-weight: 700; }
html body .project-tabs { border-bottom-color: var(--line); }
html body .project-tab { font-weight: 800; color: var(--muted); }
html body .project-tab.active { color: var(--ink); border-bottom-color: var(--rd-pink); border-bottom-width: 3px; }

/* inner surfaces: soft tinted tiles instead of outlines */
html body .metric,
html body .eval-card,
html body .service-card,
html body .delivery-environment,
html body .coverage-item,
html body .focus-block,
html body .eval-overview {
  border-radius: 18px;
  background: var(--soft);
  border-color: transparent;
}
html body .metric:nth-child(3n+2) { background: #fff4f9; }
html body .metric:nth-child(3n+3) { background: #eefcff; }

html body .attention { border-radius: 18px; }
html body .panel-title-row h2,
html body .panel h2,
html body .panel h3 { letter-spacing: -0.03em; }

/* small labels: calm violet */
html body .agent-kicker,
html body .readiness-pill { color: var(--accent); }

/* the overview dashboard block (mock-*): same soft surface and rounding as the top of the page */
html body .mock-dashboard {
  background: var(--soft) !important;
  border-radius: 24px;
}
html body .mock-dashboard .mock-dashboard-section {
  border: 0 !important;
  border-radius: 22px !important;
  background: #fff !important;
  box-shadow: none !important;
}
html body .mock-dashboard .mock-attention-banner.is-healthy {
  background: linear-gradient(105deg, #effcf6, #f4fff9) !important;
}
html body .mock-dashboard :is(.mock-metric, .mock-quality-card, .mock-health-card, .mock-kpi-grid > *) {
  border: 0 !important;
  border-radius: 18px !important;
  background: var(--soft) !important;
  box-shadow: none !important;
}
html body .mock-dashboard .mock-dashboard-section :is(.mock-metric, .mock-quality-card, .mock-health-card) { background: var(--soft) !important; }
html body .mock-dashboard .mock-kpi-grid > * { background: #fff !important; }
html body .mock-dashboard h3 { letter-spacing: -0.03em; }

/* lower panels: same soft tinted surface as the top of the page */
html body .detail .panel,
html body .detail .grid > .panel {
  border: 0 !important;
  border-radius: 24px !important;
  background: var(--soft) !important;
  padding: 24px !important;
}
html body .detail .grid { gap: 14px; }
html body .detail .panel :is(.metric, .eval-card, .service-card, .delivery-environment, .coverage-item, .focus-block, .eval-overview) { background: #fff !important; }
html body .detail .panel :is(.row, .activity-item, .review-item) { border-color: rgba(21, 17, 26, 0.07) !important; }
html body .detail .panel h2, html body .detail .panel h3 { letter-spacing: -0.03em; }

/* unknown / loading quality values read as neutral grey, never as a green zero */
html body .mock-kpi-signal.unknown { color: var(--muted); }

/* loading state: neutral skeleton, not an orange warning */
html body .mock-dashboard .mock-attention-banner.is-checking {
  border: 0 !important;
  background: #f8f7ff !important;
}
html body .mock-dashboard .mock-attention-banner.is-checking .mock-attention-icon {
  background: #e8e7ef !important;
  color: transparent;
  display: grid;
  place-items: center;
}
html body .mock-dashboard .mock-attention-banner.is-checking .mock-attention-copy h3 { color: var(--ink); }
html body .mock-dashboard .mock-attention-banner.is-checking .mock-attention-copy > p { color: var(--muted); }
.mock-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid rgba(21, 17, 26, 0.2);
  border-top-color: var(--ink);
  border-radius: 50%;
  animation: phSpin 0.9s linear infinite;
}
.mock-skeleton { display: grid; gap: 8px; margin-top: 12px; }
.mock-skeleton i {
  display: block;
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(90deg, #ecebf3 25%, #f6f5fb 50%, #ecebf3 75%);
  background-size: 200% 100%;
  animation: phShimmer 1.4s ease-in-out infinite;
}
.mock-skeleton i:first-child { width: 62%; }
.mock-skeleton i:last-child { width: 38%; }
@keyframes phSpin { to { transform: rotate(360deg); } }
@keyframes phShimmer { to { background-position: -200% 0; } }

/* headings: same weight and tracking as the portfolio (reviewer feedback #10); tool pages stay sans */
html body :is(h1, h2, h3, h4):not(#_) { font-weight: 700 !important; letter-spacing: -0.02em !important; word-spacing: 0.02em !important; }

@media (max-width: 680px) {
  html body h1 { font-size: clamp(40px, 12vw, 56px); }
  html body .project-card.active { box-shadow: 3px 3px 0 var(--ink); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.001ms !important; animation-duration: 0.001ms !important; }
}

/* incomplete: a signal failed to load. Neutral grey with a "?" icon, never the green healthy state. */
html body .mock-dashboard .mock-attention-banner.is-incomplete {
  border: 0 !important;
  background: #f6f6f8 !important;
}
html body .mock-dashboard .mock-attention-banner.is-incomplete .mock-attention-icon { background: #8a8796 !important; color: #fff; }
html body .mock-dashboard .mock-attention-banner.is-incomplete .mock-attention-copy h3 { color: var(--ink); }
html body .mock-dashboard .mock-attention-banner.is-incomplete .mock-attention-copy > p { color: var(--muted); }
html body .mock-dashboard .mock-attention-banner.is-incomplete .mock-issue-dot { background: #8a8796; }
html body .status-pill.incomplete { background: #f1f1f4 !important; color: #5f5c6b !important; }

/* quality not measured by design (Cowork, Oct 11): delivery and runtime are fine, but there is no quality source,
   so the banner and pill stay neutral instead of the green "healthy" state. Not the same as incomplete (a failed request). */
html body .mock-dashboard .mock-attention-banner.is-partial {
  border: 0 !important;
  background: #f6f7f6 !important;
}
html body .mock-dashboard .mock-attention-banner.is-partial .mock-attention-icon { background: #7d8a83 !important; color: #fff; }
html body .mock-dashboard .mock-attention-banner.is-partial .mock-attention-copy h3 { color: var(--ink); }
html body .mock-dashboard .mock-attention-banner.is-partial .mock-attention-copy > p { color: var(--muted); }
html body .mock-dashboard .mock-attention-banner.is-partial .mock-issue-dot { background: #7d8a83; }
html body .status-pill.partial { background: #f1f3f1 !important; color: #4f5a54 !important; }

/* Project header (visual pass, Oct 11). "Live site" and "GitHub" are quiet text links beside the title, so the
   button row holds only actions: Investigate, the run button and •••. Each paid-call note sits directly under the
   button it describes (width pinned to the button so notes never widen the row). */
html body .project-title-links { display: inline-flex; align-items: center; gap: 14px; margin-left: 4px; }
html body .project-title-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: #4f46d9;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.3;
  text-decoration: none;
  border-radius: 4px;
}
html body .project-title-link:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
html body .project-title-link[hidden] { display: none; }
html body .project-title-link-icon { flex: 0 0 auto; }

html body .detail-actions { align-items: flex-start; }
html body .action-with-note { display: inline-grid; justify-items: center; gap: 5px; }
html body .action-with-note[hidden] { display: none; }
html body .action-note { width: 0; min-width: 100%; color: var(--muted); font-size: 11px; line-height: 1.3; text-align: center; }
html body .action-note[hidden] { display: none; }
html body .action-note-line { display: block; white-space: nowrap; }
html body .detail-actions { flex: 0 0 auto; }
html body .detail-actions .button { white-space: nowrap; }

/* The "View source" link looked raised with a drop shadow: that was the pill hover lift above (translateY(-2px) plus a
   shadow) left applied after a new-tab link is clicked, because the browser keeps :hover until the pointer moves again.
   Links that open a new tab do not lift. */
html body a.button[target="_blank"]:hover { transform: none; box-shadow: none; }

@media (max-width: 560px) {
  html body .project-title-links { flex-basis: 100%; margin-left: 0; }
  /* Buttons stay one line (a two-line pill crowds its curved ends); if a long run label still cannot fit, the row
     wraps rather than squeezing the label. */
  html body .detail-actions { flex-wrap: wrap; gap: 8px 6px; width: 100%; }
  html body .detail-actions .button { padding: 6px 10px; font-size: 12px; }
  html body .detail-actions .overflow-button { min-width: 40px; padding-inline: 10px; }
}

/* Pill buttons are for one-line labels. Section headers with a "View all … →" button wrap the button under the heading
   on narrow screens instead of breaking it onto two lines. */
html body :is(.mock-quality-detail-head, .mock-investigation-head) { flex-wrap: wrap; }
html body :is(.mock-quality-detail-head, .mock-investigation-head) > .button { white-space: nowrap; }

/* Eval-suite actions (AI Evals tab): a title, a description and "Run →" do not fit a pill, so they are cards with the
   page's card radius. "Run →" sits in its own column, centred, so both cards line up. */
html body .button.suite-action {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px;
  min-height: 0;
  padding: 14px 16px 15px;
  border-color: #d9d6e3;
  border-radius: 13px;
  text-align: left;
  white-space: normal;
}
html body .button.suite-action:hover:not([disabled]) { border-color: var(--ink); }
html body .suite-action-copy { gap: 4px; }
html body .suite-action-copy > strong { font-size: 14px; line-height: 1.25; }
html body .suite-action-copy > span { max-width: 44ch; font-size: 12.5px; font-weight: 600; line-height: 1.45; }
html body .suite-action-run { font-size: 12.5px; }
html body .button.suite-action[disabled] .suite-action-run { color: var(--muted); }
html body .suite-action-grid { grid-template-columns: repeat(2, minmax(0, 360px)); gap: 12px; }
html body .eval-suite-actions > p { margin-bottom: 12px; }
@media (max-width: 720px) {
  html body .suite-action-grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  /* on phones the status line ("Run →" / "Available in 7 min") goes under the description so the copy keeps its width */
  html body .button.suite-action { grid-template-columns: 1fr; gap: 8px; }
}
