/* EcoPulse AI admin console — "Harmattan" palette.
   Warm earth, flat washes, no gradients.
   Bricolage Grotesque (display) over Hanken Grotesk (body), Martian Mono for figures.

   Contrast tokens below were audited against WCAG 2.2 AA. Ratios in comments are
   measured, not estimated. Three rules fall out of that audit and are binding:
     1. --line is decorative only. Any boundary that identifies a control uses
        --line-strong (3.51:1 on raised).
     2. --signal is never text on --raised (4.36:1, fails). Use --signal-soft.
     3. --chalk is never text on a --signal or --growth-deep fill. Use --ink. */

@font-face {
  font-family: "Bricolage Grotesque";
  src: url("/admin/static/fonts/BricolageGrotesque-Variable.ttf") format("truetype-variations");
  font-weight: 200 800;
  font-display: swap;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/admin/static/fonts/HankenGrotesk-Variable.ttf") format("truetype-variations");
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/admin/static/fonts/HankenGrotesk-Italic-Variable.ttf") format("truetype-variations");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Martian Mono";
  src: url("/admin/static/fonts/MartianMono-Variable.ttf") format("truetype-variations");
  font-weight: 100 800;
  font-display: swap;
}

:root {
  --base:        #12100E;   /* page */
  --surface:     #1C1916;   /* cards */
  --raised:      #262019;   /* buttons, table headers, chips */
  --line:        #342D24;   /* DECORATIVE ONLY — 1.29:1, never on a control */
  --line-strong: #7D7469;   /* control boundaries — 3.51:1 on raised */

  --signal:      #E4571B;   /* laterite. text on base 5.13:1 / surface 4.73:1 */
  --signal-soft: #F0854E;   /* text on raised 6.27:1 — use this on raised */
  --growth:      #6FBF59;   /* 7.12:1 on raised */
  --growth-deep: #4C8B3C;   /* borders and large text only */
  --brass:       #E8B33A;   /* 8.40:1 on raised */
  --water:       #4F9FAD;   /* 5.29:1 on raised */
  --danger:      #E8614F;   /* 4.80:1 on raised */

  --chalk:       #F4EFE6;   /* body text — 14.07:1 on raised */
  --muted:       #B4A99B;   /* secondary — 6.98:1 on raised */
  --dim:         #9A8F82;   /* labels/captions — 5.08:1 on raised */
  --ink:         #170D06;   /* the only text colour on signal/growth fills */
  --focus-ring:  #F4EFE6;

  --radius: 0.875rem;
  --radius-sm: 0.5rem;
  --shadow: 0 1px 0 rgba(255,255,255,0.03) inset, 0 0.75rem 1.75rem rgba(0,0,0,0.35);
  --header-h: 0rem;

  --display: "Bricolage Grotesque", Georgia, "Times New Roman", serif;
  --body: "Hanken Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: "Martian Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
}

* { box-sizing: border-box; }

/* Never a px root size: it overrides the reader's browser preference. */
html { font-size: 100%; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--base);
  color: var(--chalk);
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.6;
  background-image:
    radial-gradient(circle at 12% 8%, rgba(228,87,27,0.05), transparent 42%),
    radial-gradient(circle at 88% 0%, rgba(232,179,58,0.04), transparent 38%);
  background-attachment: fixed;
}

/* Underline every link in prose: --signal-soft against --chalk is only 2.25:1,
   so colour alone cannot distinguish a link from its surrounding text. */
a { color: var(--signal-soft); text-underline-offset: 0.15em; }
.nav a, .tabs a, .btn, .skip-link, .stat-link { text-decoration: none; }

/* Two-tone ring: the inner dark band separates the outer band from any fill
   colour, so one ring works on brass, signal and chalk alike. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus {
  outline: none;
  box-shadow: 0 0 0 2px var(--base), 0 0 0 4px var(--focus-ring);
  border-radius: 4px;
}
:where(a, button, input, select, textarea, summary, [tabindex]):focus:not(:focus-visible) {
  box-shadow: none;
}
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  box-shadow: 0 0 0 2px var(--base), 0 0 0 4px var(--focus-ring);
}

/* A sticky header must never cover the element that just received focus. */
:where(a, button, input, select, textarea, summary, [tabindex]) {
  scroll-margin-top: calc(var(--header-h) + 1rem);
  scroll-margin-bottom: 1rem;
}

main:focus { outline: none; box-shadow: none; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Off-screen, not display:none — the latter removes it from the focus order
   entirely and the link never works. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--raised);
  color: var(--chalk);
  padding: 0.75rem 1.25rem;
  border: 1px solid var(--line-strong);
  border-radius: 0 0 6px 0;
  font-weight: 700;
}
.skip-link:focus { left: 0; }

/* ------------------------------------------------------------------ layout */

.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: 15.25rem;
  flex: 0 0 15.25rem;
  background: var(--surface);
  border-right: 1px solid var(--line);
  padding: 1.375rem 1rem;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.brand { display: flex; align-items: center; gap: 0.625rem; margin-bottom: 1.625rem; }
.brand-mark {
  width: 1.875rem; min-height: 1.875rem; border-radius: 0.5625rem;
  background: var(--signal); color: var(--ink);
  display: grid; place-items: center;
  font-family: var(--display); font-weight: 800; font-size: 1.0625rem;
}
.brand-name { font-family: var(--display); font-weight: 700; font-size: 1.0625rem; letter-spacing: -0.2px; }
.brand-sub { font-size: 0.6875rem; color: var(--dim); letter-spacing: 0.08em; text-transform: uppercase; }

.nav-group { margin-bottom: 1.25rem; }
.nav-label {
  font-size: 0.6875rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--dim); margin: 0 0 0.4375rem 0.625rem; font-weight: 600;
}
.nav ul { list-style: none; margin: 0; padding: 0; }
.nav a {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.5rem 0.625rem; border-radius: var(--radius-sm);
  color: var(--muted); font-size: 0.9375rem; font-weight: 500;
  min-height: 2.25rem;
  border-left: 3px solid transparent;
}
.nav a:hover { background: var(--raised); color: var(--chalk); }
/* Current page: bar + weight + aria-current. Colour is the third signal, never
   the only one. */
.nav a[aria-current="page"] {
  background: var(--raised);
  color: var(--chalk);
  border-left-color: var(--signal);
  font-weight: 700;
}
.nav .pill {
  font-family: var(--mono); font-size: 0.6875rem;
  background: var(--signal); color: var(--ink);
  padding: 0.0625rem 0.4375rem; border-radius: 1.25rem; font-weight: 700;
}

.main { flex: 1; min-width: 0; padding: 1.625rem 1.875rem 4rem; }

.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1.25rem; margin-bottom: 1.5rem; flex-wrap: wrap;
}
h1 {
  font-family: var(--display); font-size: 1.875rem; font-weight: 700;
  margin: 0 0 0.25rem; letter-spacing: -0.6px; line-height: 1.2;
}
.page-head p { margin: 0; color: var(--muted); max-width: 62ch; }

h2 { font-family: var(--display); font-size: 1.1875rem; font-weight: 600; margin: 0 0 0.75rem; }
h3 { font-family: var(--display); font-size: 1rem; margin: 0 0 0.375rem; font-weight: 600; }

/* ------------------------------------------------------------------- cards */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: 1.125rem;
  box-shadow: var(--shadow);
}
.card-flush { padding: 0; overflow: hidden; }

.grid { display: grid; gap: 1rem; }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }

/* min-height, never height: must survive 200% text spacing without clipping. */
.stat {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem 1.125rem; min-height: 5.5rem;
  display: block;
}
a.stat:hover { border-color: var(--line-strong); }
.stat-value {
  font-family: var(--mono); font-size: 1.6875rem; font-weight: 700;
  letter-spacing: -1.5px; line-height: 1.15; display: block;
}
.stat-label {
  font-size: 0.75rem; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--dim); margin-top: 0.3125rem; font-weight: 600; display: block;
}
.stat-note { font-size: 0.8125rem; color: var(--muted); margin-top: 0.375rem; }
.accent-signal .stat-value { color: var(--signal-soft); }
.accent-growth .stat-value { color: var(--growth); }
.accent-brass  .stat-value { color: var(--brass); }
.accent-water  .stat-value { color: var(--water); }

/* ----------------------------------------------------------------- banners */

.banner {
  border-radius: var(--radius); padding: 0.875rem 1rem; margin-bottom: 1.125rem;
  border: 1px solid var(--line-strong); background: var(--surface);
}
.banner h2 { font-size: 1rem; margin: 0 0 0.375rem; }
.banner p { margin: 0; color: var(--muted); font-size: 0.9375rem; }
.banner ul { margin: 0.5rem 0 0; padding-left: 1.125rem; color: var(--muted); }
.banner-warn   { border-left: 4px solid var(--brass); }
.banner-ok     { border-left: 4px solid var(--growth); }
.banner-danger { border-left: 4px solid var(--danger); }

/* ------------------------------------------------------------------- forms */

fieldset { border: 0; padding: 0; margin: 0 0 1.5rem; }
legend {
  font-family: var(--display); font-size: 1.1875rem; font-weight: 600;
  padding: 0; margin-bottom: 0.25rem;
}

.field { margin-bottom: 1.25rem; padding-bottom: 1.25rem; border-bottom: 1px solid var(--line); }
.field:last-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }
.field > label { display: block; font-weight: 600; margin-bottom: 0.25rem; }
.field__hint { color: var(--muted); font-size: 0.875rem; margin: 0 0 0.5625rem; max-width: 68ch; }
.field__err { color: var(--danger); font-size: 0.875rem; margin: 0.375rem 0 0; font-weight: 600; }
.field__state {
  display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap;
  font-size: 0.875rem; margin: 0 0 0.375rem; font-weight: 600;
}
.field__state-set { color: var(--growth); }
.field__state-unset { color: var(--dim); }
.field__state .mask { font-family: var(--mono); font-size: 0.75rem; color: var(--muted); font-weight: 400; }
.field__actions { margin-top: 0.5rem; }
.field__danger { margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px dashed var(--line-strong); }
.req { color: var(--dim); font-weight: 400; font-size: 0.875rem; }

input[type="text"], input[type="email"], input[type="password"],
input[type="number"], select, textarea {
  width: 100%;
  background: var(--base);
  /* line-strong, not line: this boundary is the only thing identifying the control. */
  border: 1px solid var(--line-strong);
  color: var(--chalk);
  border-radius: var(--radius-sm);
  padding: 0.625rem 0.75rem;
  font-family: var(--body);
  font-size: 1rem;
  min-height: 2.75rem;
}
input[type="password"], .mono-input { font-family: var(--mono); font-size: 0.8125rem; }
textarea { min-height: 7rem; resize: vertical; line-height: 1.6; }
textarea.code { font-family: var(--mono); font-size: 0.8125rem; }
input:focus, select:focus, textarea:focus { border-color: var(--signal); }
[aria-invalid="true"] { border-color: var(--danger); border-width: 2px; }

.switch { display: flex; align-items: flex-start; gap: 0.625rem; }
.switch input[type="checkbox"] {
  width: 1.5rem; height: 1.5rem; min-width: 1.5rem;
  accent-color: var(--signal); margin: 0;
}
.switch label { font-weight: 600; }

.error-summary {
  border: 2px solid var(--danger); border-radius: var(--radius);
  padding: 1rem 1.25rem; margin-bottom: 1.5rem; background: var(--surface);
}
.error-summary h2 { color: var(--danger); margin-bottom: 0.5rem; }
.error-summary ul { list-style: none; margin: 0; padding: 0; }
.error-summary li { margin-bottom: 0.25rem; }

.inline { display: flex; gap: 0.625rem; align-items: center; flex-wrap: wrap; }
.row-actions { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }

/* ----------------------------------------------------------------- buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4375rem;
  background: var(--raised); color: var(--chalk);
  /* transparent border so one materialises in Windows forced-colors mode. */
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 0.5625rem 0.9375rem;
  font-family: var(--body); font-size: 0.9375rem; font-weight: 600;
  cursor: pointer; min-height: 2.75rem;
}
.btn:hover { border-color: var(--chalk); }
.btn-primary { background: var(--signal); border-color: var(--signal); color: var(--ink); }
.btn-primary:hover { background: var(--signal-soft); border-color: var(--signal-soft); }
/* growth, not growth-deep: ink on growth is 8.46:1 rather than a marginal 4.62. */
.btn-go { background: var(--growth); border-color: var(--growth); color: var(--ink); }
.btn-danger { background: transparent; border-color: var(--danger); color: var(--danger); }
.btn-sm { padding: 0.3125rem 0.625rem; font-size: 0.875rem; min-height: 1.5rem; }
.btn[aria-disabled="true"] { opacity: 0.6; cursor: progress; }
.btn__spinner { animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Icon-only controls still need a 24px target (SC 2.5.8). */
.icon-btn {
  display: inline-grid; place-items: center;
  min-width: 2rem; min-height: 2rem;
  background: transparent; border: 1px solid transparent;
  border-radius: var(--radius-sm); color: var(--muted); cursor: pointer;
}
.icon-btn:hover { color: var(--chalk); border-color: var(--line-strong); }

/* ------------------------------------------------------------------ tables */

/* Tables are an explicit exception to reflow: let them scroll horizontally
   rather than breaking their semantics with display:block. */
.table-scroll { overflow-x: auto; }
.table-scroll:focus-visible { box-shadow: 0 0 0 2px var(--base), 0 0 0 4px var(--focus-ring); }

table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
caption { text-align: left; }
th {
  text-align: left; font-size: 0.75rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--dim); font-weight: 700; padding: 0.6875rem 0.875rem;
  border-bottom: 1px solid var(--line); background: var(--raised);
}
thead th { position: sticky; top: 0; z-index: 1; }
td, tbody th {
  padding: 0.6875rem 0.875rem; border-bottom: 1px solid var(--line);
  vertical-align: middle; text-align: left; font-weight: 400;
}
tbody th { color: var(--chalk); font-weight: 600; }
tbody tr:hover { background: rgba(255,255,255,0.018); }
tbody tr:last-child td, tbody tr:last-child th { border-bottom: 0; }
td.num, th.num { font-family: var(--mono); text-align: right; font-size: 0.8125rem; }

/* ------------------------------------------------------------------- chips */

/* Flat background, never an alpha tint: a 12% tint drops danger text to
   4.49:1. Border is currentColor so it survives forced-colors mode, and the
   icon carries meaning independently of hue. */
.chip {
  display: inline-flex; align-items: center; gap: 0.375rem;
  background: var(--raised);
  border: 1px solid currentColor;
  color: var(--muted);
  border-radius: 999px;
  padding: 0.25rem 0.625rem;
  min-height: 1.5rem;
  font-size: 0.875rem; font-weight: 700; line-height: 1.4;
  white-space: nowrap;
}
.chip__icon { flex: 0 0 auto; }
.chip--pending   { color: var(--muted); }
.chip--verified  { color: var(--growth); }
.chip--assigned  { color: var(--water); }
.chip--resolved  { color: var(--growth); }
.chip--rejected  { color: var(--danger); }
.chip--duplicate { color: var(--muted); }
.chip--urgent    { color: var(--danger); }
.chip--high      { color: var(--brass); }
.chip--normal, .chip--low { color: var(--dim); }
.chip--flag { color: var(--brass); font-weight: 600; }

.mono { font-family: var(--mono); font-size: 0.8125rem; }
.muted { color: var(--muted); }
.dim { color: var(--dim); font-size: 0.875rem; }
.tiny { font-size: 0.8125rem; }

/* ---------------------------------------------------------------- provider */

.provider {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 0.875rem; padding: 0.875rem 0; border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.provider:last-child { border-bottom: 0; }
.provider-name { font-weight: 600; display: flex; align-items: center; gap: 0.375rem; }
.provider-msg { font-size: 0.875rem; color: var(--muted); margin: 0.25rem 0 0; max-width: 60ch; }
.provider-state { font-weight: 700; font-size: 0.875rem; }
.state-ok { color: var(--growth); }
.state-bad { color: var(--danger); }
.state-unknown { color: var(--dim); }

/* ------------------------------------------------------------------- login */

.login-page { display: grid; place-items: center; min-height: 100vh; padding: 1.25rem; }
.login-card { width: 100%; max-width: 25rem; }
.login-card .brand { justify-content: center; margin-bottom: 1.25rem; }

/* -------------------------------------------------------------------- misc */

.tabs { display: flex; gap: 0.375rem; flex-wrap: wrap; margin-bottom: 1.125rem; list-style: none; padding: 0; }
.tabs a {
  display: inline-flex; align-items: center;
  padding: 0.4375rem 0.8125rem; border-radius: 1.25rem;
  font-size: 0.875rem; font-weight: 600;
  color: var(--muted); border: 1px solid var(--line-strong);
  min-height: 1.5rem;
}
.tabs a:hover { color: var(--chalk); }
.tabs a[aria-current="page"] { background: var(--chalk); color: var(--base); border-color: var(--chalk); }

.evidence { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 0.875rem; }
.evidence figure { margin: 0; }
.evidence img {
  width: 100%; height: auto; border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong); display: block;
}
.evidence figcaption {
  font-size: 0.8125rem; color: var(--dim); margin-top: 0.375rem;
  text-transform: uppercase; letter-spacing: 0.07em;
}
.evidence .no-description {
  font-size: 0.875rem; color: var(--brass); margin-top: 0.375rem; font-weight: 600;
}

.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { padding: 0.5625rem 0 0.5625rem 1.25rem; border-left: 2px solid var(--line-strong); position: relative; }
.timeline li::before {
  content: ""; position: absolute; left: -0.3125rem; top: 0.9375rem;
  width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--signal);
}
.timeline .when { font-family: var(--mono); font-size: 0.75rem; color: var(--dim); display: block; }

.empty { text-align: center; padding: 2.75rem 1.25rem; color: var(--muted); }
.empty h2 { color: var(--chalk); }

.readable { max-width: 72ch; }
.stack > * + * { margin-top: 1rem; }

/* Reflow to 320px. Tables keep their own horizontal scroll. */
@media (max-width: 54rem) {
  .shell { flex-direction: column; }
  .sidebar { width: 100%; flex: none; height: auto; position: static; }
  .main { padding: 1.25rem 1rem 3rem; }
  h1 { font-size: 1.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Windows High Contrast: keep chip and control boundaries, map focus to the
   system Highlight colour. Icons are inline SVG using currentColor, so they
   survive here where background-image icons would vanish. */
@media (forced-colors: active) {
  .chip, .btn, .stat, .card, input, select, textarea { border: 1px solid CanvasText; }
  .nav a[aria-current="page"] { border-left-color: Highlight; }
  :where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 3px solid Highlight;
    outline-offset: 2px;
    box-shadow: none;
  }
}
