/**
 * 2.0 — the shared UI layer. Loaded on BOTH doorways: wp-admin and /app/.
 *
 * The problem this exists to end: 62KB of CSS lived in twenty-five inline
 * <style> blocks travelling with their render callbacks, written at different
 * times, against 12KB in app.css which only ever restyled the WordPress core
 * classes. Nothing had reconciled the screens against each other, so the product
 * carried 141 distinct colour literals, three different row-stripe tones, five
 * different pill radii, and `.aipub-status` declared five separate times with
 * the copies already disagreeing about which states exist.
 *
 * Everything here is a TOKEN or a shared primitive. A screen's own <style> block
 * keeps its screen-specific layout and nothing else. When you find yourself
 * writing a colour literal in a screen, the answer is a token in this file.
 *
 * Scoping: the custom properties sit on :root (all names are `--aipub-`
 * prefixed, so they cannot collide with a theme or with wp-admin). Every rule is
 * scoped to an `.aipub-` class, because this file loads inside wp-admin where
 * restyling a bare element would reach screens that are not ours.
 *
 * Rules honoured, from D:\ClaudeCode\docs\UI-UX-STANDARDS.md:
 *   - nothing under 16px, body 18px (hard rule 6, and the 2026-07-28 amendment
 *     that removed the chip exception)
 *   - dividers >= 2px or clearly darker than #b0b0b8 (hard rule 2)
 *   - no max-width on anything holding text (hard rule 4)
 *   - every text/background pair calculated, never eyeballed (hard rule 7a)
 *   - colour encodes function, never decoration
 */

:root {
	/* -- Surfaces ------------------------------------------------------- */
	--aipub-page: #f4f5f7;
	--aipub-surface: #ffffff;
	--aipub-surface-sunk: #f6f7f7;
	--aipub-stripe: #f7f5ef;          /* the ONE row stripe. A warm cream, not a barely-there grey. */
	--aipub-hover: #eef3f8;

	/* -- Ink ------------------------------------------------------------ */
	--aipub-ink: #212121;             /* 16.10:1 on white. Body text, never a grey-blue tint. */
	--aipub-ink-quiet: #565a60;       /* 6.94:1 on white, 6.36:1 on the page and the stripe. */
	--aipub-ink-brand: #1d2e40;       /* 13.84:1 on white. Headings and the app header fill. */
	--aipub-ink-on-dark: #dce4ec;     /* 10.78:1 on --aipub-ink-brand. */
	--aipub-core-muted: #646970;      /* WP core's OWN .description grey, matched deliberately in
	                                      two screens — a different value from --aipub-ink-quiet on
	                                      purpose, not a duplicate of it. 5.53:1 on white. */

	/* -- Lines ---------------------------------------------------------- */
	--aipub-line: #b0b0b8;            /* the standards floor: anything lighter is imperceptible */
	--aipub-line-strong: #6f7780;     /* control boundaries: 4.54:1 on white, 4.16:1 on the page (1.4.11 wants 3:1) */
	--aipub-line-cell: #d8dee4;       /* between rows only, never a section boundary */

	/* -- Accent --------------------------------------------------------- */
	--aipub-accent: #e1a140;          /* on dark only: 6.18:1 on --aipub-ink-brand */
	--aipub-accent-ink: #8a5a12;      /* the same accent as TEXT on light: 5.91:1 on white, 5.42:1 on the page */

	/* -- Function colours (hard rule 1: same action, same colour, product-wide).
	      Each is a FILL carrying white text; the -ink value is the same function
	      as text on a light surface. Both measured. ------------------------ */
	--aipub-fn-review: #1d4ed8;       /* review / read      — 6.70:1 with white */
	--aipub-fn-publish: #15803d;      /* publish / go live  — 5.02:1 with white */
	--aipub-fn-social: #6d28d9;       /* social             — 7.10:1 with white */
	--aipub-fn-fix: #b3261e;          /* destructive / fix  — 6.54:1 with white */
	--aipub-fn-push: #0e7490;         /* push to a site     — 5.36:1 with white */
	--aipub-fn-neutral: #33404d;      /* secondary          — 10.60:1 with white */

	/* Hover fills. Rule 7b: a hover confirms, so it must hold contrast or GAIN it,
	   never spend it. Every one of these measures higher against white than the
	   resting fill it replaces. Two reds were in use for one function (#b91c1c and
	   #b3261e, 6.47:1 and 6.54:1); the fix was deleting the outlier, not adding a
	   token, so `fn-fix` is the value already used twenty-odd times elsewhere. */
	--aipub-fn-review-hover: #173eae;   /* 8.99:1 */
	--aipub-fn-publish-hover: #116630;  /* 7.08:1 */
	--aipub-fn-social-hover: #5721ad;   /* 9.43:1 */
	--aipub-fn-fix-hover: #8f1d17;      /* 8.91:1 */
	--aipub-fn-push-hover: #0b5c74;     /* 7.51:1 */

	/* -- Status tones. Seven, measured as a set: every pair of fills is at least
	      dE 14 apart in CIELAB (so no two read as one tone at pill size) and every
	      text/fill pair clears 5.6:1. Do not add an eighth without re-running the
	      measurement — the pale blue-violet-grey corner is already full, and two
	      tones that need their labels to be told apart encode nothing. ------- */
	--aipub-t-planned-bg: #ddd2fa;
	--aipub-t-planned-fg: #4c1d95;   /* 7.65:1 */
	--aipub-t-working-bg: #b9ecf5;
	--aipub-t-working-fg: #0f5666;   /* 6.44:1 */
	--aipub-t-ready-bg: #fbe3a0;
	--aipub-t-ready-fg: #7a4f00;     /* 5.63:1 */
	--aipub-t-review-bg: #b3d4fb;
	--aipub-t-review-fg: #17398f;    /* 6.80:1 */
	--aipub-t-published-bg: #b2eccd;
	--aipub-t-published-fg: #05553f; /* 6.63:1 */
	--aipub-t-failed-bg: #fbcccc;
	--aipub-t-failed-fg: #8f1a1a;    /* 6.27:1 */
	--aipub-t-unknown-bg: #e0e3e7;
	--aipub-t-unknown-fg: #2f3a45;   /* 9.00:1 */

	/* -- Secondary surfaces & banner tones. NOT the closed 7-tone system above —
	      those are per-pill states; these are border-left + background treatments
	      for a whole section, plus one small success badge and one neutral fill.
	      Every value here already appeared identically across 3-7 screens before
	      this existed (measured 2026-09-01): not drift needing reconciliation, an
	      established choice that only lacked a name. -------------------------- */
	--aipub-neutral-bg: #f0f0f1;        /* plain/secondary button and chip fills */
	--aipub-neutral-line: #50575e;      /* pairs with it as a border — 6.43:1 on it, 7.33:1 on white */
	--aipub-banner-attn-bg: #fff8e1;    /* a section needs a look: stale, pending */
	--aipub-banner-attn-line: #e3a200;  /* border/left-accent use ONLY: 2.23:1 with white text, fails */
	--aipub-banner-attn-fill: #8a6d00;  /* the same amber, darkened for a SOLID fill under white text — 4.92:1 */
	--aipub-banner-clear-bg: #eaf3ea;   /* a section is healthy / in sync */
	--aipub-banner-clear-line: #166534;
	--aipub-banner-fix-bg: #fcf0f1;     /* a section has a real problem, pairs with --aipub-fn-fix */
	--aipub-badge-success-bg: #d1fae5;  /* a small positive badge, distinct scale from the banner above */
	--aipub-badge-success-fg: #065f46;  /* 6.78:1 on --aipub-badge-success-bg */
	--aipub-state-new: #1e6b3a;         /* a fresh/positive state as text or a thin border — 6.52:1 on white */
	--aipub-badge-amber-bg: #fef3c7;    /* a small highlighted badge (admin, paused) */
	--aipub-badge-amber-fg: #7c4a00;    /* 6.65:1 on --aipub-badge-amber-bg */
	--aipub-text-warn: #92400e;         /* paused/running/warn text — 7.09:1 on white, 6.37:1 on the badge above */
	/* The ordinary anchor colour, not a highlight: app.css's blanket `a` rule plus
	   four review-flavoured screens (review view/admin, coverage, social) had all
	   landed on this exact blue independently before it had a name. */
	--aipub-link-fg: #1565c0;           /* 5.75:1 on white, 5.27:1 on the page */
	--aipub-link-fg-hover: #0d47a1;     /* 8.63:1 on white — gains, never spends (rule 7b) */
	--aipub-link-next-fg: #0a4b78;      /* the "do this next" highlight — 9.17:1 on white, 7.95:1 on its own bg */
	--aipub-link-next-bg: #e7f0f8;
	--aipub-link-next-border: #9ec2e6;
	--aipub-chip-neutral-fg: #334155;   /* a neutral inline chip/aside — 10.35:1 on white, 8.40:1 on its own bg */
	--aipub-chip-neutral-bg: #e2e8f0;
	--aipub-chip-neutral-border: #64748b;
	/* A three-state badge system (good/pending/bad), reused across three
	   unrelated feature areas in one file alone (NEURONwriter status, deploy
	   status, content score) before this existed. --aipub-badge-good-fg is
	   --aipub-banner-clear-line's own value on purpose: one green, not two. */
	--aipub-badge-good-bg: #dcfce7;      /* 6.49:1 with --aipub-banner-clear-line */
	--aipub-badge-pending-bg: #fef9c3;
	--aipub-badge-pending-fg: #854d0e;   /* 6.38:1 on --aipub-badge-pending-bg */
	--aipub-badge-bad-bg: #fee2e2;
	--aipub-badge-bad-fg: #991b1b;       /* 6.80:1 on --aipub-badge-bad-bg */
	--aipub-badge-neutral-bg: #e5e7eb;   /* a skipped/cancelled state, not good, bad, or pending */
	--aipub-state-approved: #0f766e;    /* the D-1 "approved" teal — 5.47:1 on white, 4.78:1 on the badge below */
	--aipub-badge-approved-bg: #e3f3f1;

	/* -- Type scale. Nineteen distinct sizes were in play; these are the six.
	      The floor is 16px with no chip exception. ------------------------- */
	--aipub-fs-body: 18px;
	--aipub-fs-small: 16px;
	--aipub-fs-h3: 20px;
	--aipub-fs-h2: 23px;
	--aipub-fs-h1: 28px;
	--aipub-fs-figure: 30px;          /* stat tiles only */

	/* -- Geometry ------------------------------------------------------- */
	--aipub-radius: 6px;              /* panels, cards, inputs */
	--aipub-radius-pill: 999px;       /* a pill is a pill; five different radii were not */
	--aipub-gap: 14px;
}

/* ===================================================== Status pills ===== */
/*
 * ONE definition. AIPub_Status::pill() is the only thing that writes this
 * markup, so a state cannot appear as coloured text on one screen and a pill on
 * the next.
 *
 * line-height is explicit and not inherited: a pill whose height comes from
 * whichever glyph happens to be inside it clips its descenders the moment the
 * glyph is removed (UI-UX-STANDARDS gotcha 6).
 */
.aipub-pill {
	display: inline-block;
	padding: 2px 11px;
	border-radius: var(--aipub-radius-pill);
	font-size: var(--aipub-fs-small);
	line-height: 1.5;
	font-weight: 600;
	white-space: nowrap;
	vertical-align: middle;
	background: var(--aipub-t-unknown-bg);
	color: var(--aipub-t-unknown-fg);
}

.aipub-tone-planned   { background: var(--aipub-t-planned-bg);   color: var(--aipub-t-planned-fg); }
.aipub-tone-working   { background: var(--aipub-t-working-bg);   color: var(--aipub-t-working-fg); }
.aipub-tone-ready     { background: var(--aipub-t-ready-bg);     color: var(--aipub-t-ready-fg); }
.aipub-tone-review    { background: var(--aipub-t-review-bg);    color: var(--aipub-t-review-fg); }
.aipub-tone-published { background: var(--aipub-t-published-bg); color: var(--aipub-t-published-fg); }
.aipub-tone-failed    { background: var(--aipub-t-failed-bg);    color: var(--aipub-t-failed-fg); }
.aipub-tone-unknown   { background: var(--aipub-t-unknown-bg);   color: var(--aipub-t-unknown-fg); }

/* A pill inside a link must not take the link's underline or blue: the pill IS
 * the affordance, and a blue-underlined green pill reads as two states at once. */
a .aipub-pill { text-decoration: none; }

/* ======================================================= Card + tile ==== */
/*
 * The Dashboard, Today's Work and Usage each grew their own card and their own
 * stat tile. Same job, three definitions, three radii.
 */
.aipub-card,
.aipub-tile {
	background: var(--aipub-surface);
	border: 1px solid var(--aipub-line);
	border-radius: var(--aipub-radius);
	text-decoration: none;
	display: flex;
	flex-direction: column;
	transition: box-shadow .12s, border-color .12s;
}

.aipub-card { padding: 12px 14px; gap: 4px; }
.aipub-tile { padding: 16px 18px; gap: 2px; flex: 1 1 160px; min-width: 150px; }

a.aipub-card:hover,
a.aipub-tile:hover {
	border-color: var(--aipub-fn-review);
	box-shadow: 0 1px 6px rgba(0, 0, 0, .12);
}

a.aipub-card:focus-visible,
a.aipub-tile:focus-visible {
	outline: 3px solid var(--aipub-accent-ink);
	outline-offset: 2px;
}

.aipub-tile-n {
	font-size: var(--aipub-fs-figure);
	font-weight: 700;
	line-height: 1.1;
	color: var(--aipub-ink-brand);
	font-variant-numeric: tabular-nums;
}

.aipub-tile-l,
.aipub-card-d {
	font-size: var(--aipub-fs-small);
	color: var(--aipub-ink-quiet);
	line-height: 1.45;
}

.aipub-tile-l {
	text-transform: uppercase;
	letter-spacing: .03em;
}

.aipub-card-t {
	font-weight: 700;
	color: var(--aipub-ink-brand);
}

/* ==================================================== Section chrome ==== */
/*
 * The uppercase micro-label that says "this band is a labelled zone, not
 * content" — the one signal reused across every screen that has bands.
 */
.aipub-eyebrow {
	margin: 14px 0 6px;
	font-size: var(--aipub-fs-small);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--aipub-ink-quiet);
}

/* Secondary lines are real text: >= 16px and >= 4.5:1. Never tiny AND light. */
.aipub-quiet {
	font-size: var(--aipub-fs-small);
	color: var(--aipub-ink-quiet);
}

/* An empty result is not an error. It gets the neutral surface and a sentence
 * saying why nothing is wrong, never the failure red. */
.aipub-empty {
	background: var(--aipub-surface-sunk);
	border: 1px solid var(--aipub-line);
	border-radius: var(--aipub-radius);
	padding: 14px 16px;
	color: var(--aipub-ink);
	font-size: var(--aipub-fs-body);
}

/* ========================================================== Striping ==== */
/*
 * ONE stripe tone. There were three: cream #f7f5ef in app.css and on Review,
 * grey-blue #f3f5f7 on Today's Work.
 *
 * `th` is in the selector on purpose. Leaving it out is what made the Dashboard
 * matrix stripe its site-name column differently from its number columns on the
 * same row: the row header is a <th>, so it kept whatever the theme paints while
 * every <td> beside it took the cream.
 */
.aipub-striped tbody tr:nth-child(even) > td,
.aipub-striped tbody tr:nth-child(even) > th {
	background: var(--aipub-stripe);
}
