/* SDS Manager admin theme — the grey ramp, warmed, plus five colours by name.
 * ===========================================================================
 *
 * THIS FILE SETS TOKENS ON :root, AND THAT IS DELIBERATE.
 *
 * sidebar.css carries the opposite rule — scope everything, never touch :root —
 * because the sidebar had no business restyling the page editor the VN team
 * works in. That reason does not hold here. This pass exists precisely to
 * restyle those screens: the complaint is that the sidebar is warm espresso and
 * everything to the right of it is Wagtail's neutral grey, so the join reads as
 * two products bolted together. A scoped fix cannot warm a screen it is not
 * scoped to. Hence :root, and hence its own flag —
 * CONTENTAGENT_ADMIN_THEME — separate from the sidebar's.
 *
 * HOW IT WORKS: ONE RAMP, TWO HANDLES
 *
 * Wagtail's nine greys are hue/saturation/lightness triples, and both themes
 * read the same ramp from opposite ends:
 *
 *   :root           surface-page: white       text-context: grey-600
 *   .w-theme-dark   surface-page: grey-600    text-context: grey-50
 *
 * So changing the ramp's hue and saturation warms every screen in both themes,
 * and no template is touched.
 *
 * LIGHTNESS IS LEFT EXACTLY AS WAGTAIL SET IT. Contrast is decided almost
 * entirely by lightness, so every ratio Wagtail measured — across hundreds of
 * screens neither of us has opened — is unchanged. Setting surfaces one at a
 * time would mean guessing at those screens.
 *
 * MEASURED, NOT ASSUMED: eight of the nine families derive their hue and
 * saturation from grey-800 (`hue: var(--w-color-grey-800-hue)`), so two
 * declarations would warm eight of them. All nine are written out anyway:
 * explicit costs sixteen extra lines and survives Wagtail restructuring the
 * derivation, which two declarations would not.
 *
 * The exception that makes that worth doing is grey-50, which is NOT neutral
 * today — `hue: calc(var(--w-color-grey-800-hue) + 240)` and
 * `saturation: calc(... + 12.5%)`, a cool cast on the lightest step. Warming
 * grey-800 alone would have driven it to hue 260, bluer than before.
 */

:root {
  /* --- the ramp: hue and saturation only, nine families, eighteen lines --- */
  --w-color-grey-50-hue: 20;
  --w-color-grey-50-saturation: 10%;
  --w-color-grey-100-hue: 20;
  --w-color-grey-100-saturation: 10%;
  --w-color-grey-150-hue: 20;
  --w-color-grey-150-saturation: 10%;
  --w-color-grey-200-hue: 20;
  --w-color-grey-200-saturation: 10%;
  --w-color-grey-400-hue: 20;
  --w-color-grey-400-saturation: 10%;
  --w-color-grey-500-hue: 20;
  --w-color-grey-500-saturation: 10%;
  --w-color-grey-600-hue: 20;
  --w-color-grey-600-saturation: 10%;
  --w-color-grey-700-hue: 20;
  --w-color-grey-700-saturation: 10%;
  --w-color-grey-800-hue: 20;
  --w-color-grey-800-saturation: 10%;

  /* --- the five colours by name ---------------------------------------- *
   * Measured before writing, because the brief's mapping had two of them
   * the other way round:
   *
   *   --w-color-secondary IS the teal, and it feeds
   *       --w-color-surface-button-default AND --w-color-text-link-default.
   *   --w-color-primary is the dark purple, and it feeds
   *       --w-color-text-label, --w-color-icon-primary, --w-color-surface-menus.
   *
   * So the button colour goes on `secondary`, not on `primary`. Setting
   * `primary` to periwinkle would paint every label in the admin periwinkle —
   * which the brief itself rules out ("Never text"). `primary` is therefore
   * left alone; the sidebar already overrides surface-menus locally.
   */

  /* Buttons and links. hsl(235 70% 59%) = #4F5AE0, white on it 5.4:1.
     The brand periwinkle #626DF9 is 4.14:1 with white and fails, which is why
     the darker step is the one wired to anything bearing text. */
  --w-color-secondary-hue: 235;
  --w-color-secondary-saturation: 70%;
  --w-color-secondary-lightness: 59%;

  /* Waiting on a person. hsl(43 100% 62%) = #FFC93C. 9.9:1 in dark, but only
     1.5:1 on white — so in light mode this is a chip fill and never text.
     Wagtail uses warning-100 as a surface, which is exactly that. */
  --w-color-warning-100-hue: 43;
  --w-color-warning-100-saturation: 100%;
  --w-color-warning-100-lightness: 62%;

  /* Live, published, running. hsl(153 60% 53%) = #3ECF8E, 7.6:1. */
  --w-color-positive-100-hue: 153;
  --w-color-positive-100-saturation: 60%;
  --w-color-positive-100-lightness: 53%;

  /* Something is wrong. hsl(5 66% 65%) = #E0736A, 4.9:1. critical-200 is the
     step --w-color-text-error reads, and critical-100 derives from it. */
  --w-color-critical-200-hue: 5;
  --w-color-critical-200-saturation: 66%;
  --w-color-critical-200-lightness: 65%;
}

/* Links have to be theme-dependent, and this is the one place the ramp cannot
   do it for us. Wagtail already splits them — :root reads --w-color-secondary,
   .w-theme-dark reads --w-color-secondary-100 — and the split matters because
   the light link #4F5AE0 is 5.4:1 on white while the dark link #8A93FF is
   2.7:1 on white and fails outright. Naming the dark value explicitly rather
   than trusting the derived step keeps it at the measured 5.6:1. */
.w-theme-dark {
  --w-color-text-link-default: hsl(235 100% 77%); /* #8A93FF, 5.6:1 on the page */
  --w-color-text-link-hover: hsl(235 100% 85%);
}

@media (prefers-color-scheme: dark) {
  .w-theme-system {
    --w-color-text-link-default: hsl(235 100% 77%);
    --w-color-text-link-hover: hsl(235 100% 85%);
  }
}

/* The contrast setting is untouched. w-contrast-more raises Wagtail's own
   border and text tokens on the root element, and nothing here sets any of
   them — only hue and saturation, which a contrast mode does not care about.
   The (prefers-color-scheme: dark) and (prefers-contrast: more) block keeps
   working for the same reason. */

/* ===========================================================================
 * The dashboard's own furniture.
 *
 * These live here rather than in contentagent.css because every one of them
 * renders only when this flag is on: the summary items and the workbench panel
 * are registered by hooks that return early when it is off, and the greeting
 * falls back to Wagtail's heading. Styling them in the always-on stylesheet
 * would leave rules for markup that does not exist.
 * =========================================================================== */

/* --- the greeting --------------------------------------------------------- */
.ca-welcome__sub {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--w-color-text-meta);
}

/* --- the four counts ------------------------------------------------------ */
.w-summary__list .ca-sum a {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  text-decoration: none;
}

.ca-sum__count {
  font-weight: 700;
}

.ca-sum__label {
  color: var(--w-color-text-context);
}

/* Only the two a person acts on carry a colour. A count that is merely a fact
   stays neutral, which is what keeps the coloured ones meaning anything. */
.ca-sum--live .ca-sum__count {
  color: var(--w-color-positive-100);
}

.ca-sum--draft .ca-sum__count {
  color: var(--w-color-warning-100);
}

.ca-sum--neutral .ca-sum__count {
  color: var(--w-color-text-label);
}

/* --- the workbench panel -------------------------------------------------- */
.ca-bench__cols {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
}

@media (max-width: 60rem) {
  .ca-bench__cols {
    grid-template-columns: minmax(0, 1fr);
  }
}

.ca-bench__month {
  /* Fallback: the selector cannot show it sits inside .contentagent-ui. */
  margin-top: var(--ca-space-4, 2rem);
}

.contentagent-ui .ca-edits,
.contentagent-ui .ca-starts,
.contentagent-ui .ca-figures {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.contentagent-ui .ca-edit {
  display: grid;
  gap: 0.1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--w-color-border-furniture);
}

.contentagent-ui .ca-edit__title {
  font-size: 0.9375rem;
  text-decoration: none;
}

.contentagent-ui .ca-edit__meta {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8125rem;
  color: var(--w-color-text-meta);
}

.contentagent-ui .ca-start {
  display: grid;
  gap: 0.1rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--w-color-border-furniture);
  border-radius: 7px;
  text-decoration: none;
}

.contentagent-ui .ca-start:hover {
  border-color: var(--w-color-text-meta);
}

.contentagent-ui .ca-start--primary {
  border-color: var(--w-color-secondary);
}

.contentagent-ui .ca-start__label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--w-color-text-label);
}

.contentagent-ui .ca-start__note {
  font-size: 0.75rem;
  color: var(--w-color-text-meta);
}

.contentagent-ui .ca-figure {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.contentagent-ui .ca-figure__value {
  min-width: 1.75rem;
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--w-color-text-label);
}

.contentagent-ui .ca-figure__label {
  font-size: 0.8125rem;
  color: var(--w-color-text-meta);
}


/* ===========================================================================
 * Dashboard spacing, measured.
 * =========================================================================== */

/* PANELS ARE CARDS (measured before: background rgba(0,0,0,0), border 0px,
   radius 0px, padding 0px top and bottom).
 *
 * `nice-padding` was doing something, just not what the templates assumed: in
 * Wagtail 6.3 it is `padding-inline-start/end` only — 1.25rem, 5rem at wide
 * breakpoints — and supplies no vertical padding at all. So it stays for the
 * horizontal gutter and the vertical spacing is owned here.
 *
 * THE BOARD SAYS --w-color-grey-500 AND THAT IS WRONG, measured both ways.
 * The reasoning behind it was that a variable would let light mode take care
 * of itself, but grey-500 is not theme-relative: its lightness is
 * `calc(11.4% + 8.6%)` = 20% in *both* themes, because only the semantic
 * tokens flip which end of the ramp they read. Using it turned the light
 * dashboard into the two dark slabs the brief warned about — measured
 * rgb(56, 49, 46) on a white page.
 *
 * --w-color-surface-field-inactive is the token that actually does the job:
 * #F8F7F6 in light and #38312E in dark, a surface raised a step from the page
 * in each. It is also what the table headers already use, so cards and table
 * headers agree. In dark it resolves to the same value grey-500 gave, which
 * is why the dark screenshot looked right and hid the bug.
 */
.contentagent-ui.ca-dashpanel,
.contentagent-ui.ca-bench {
  background-color: var(--w-color-surface-field-inactive);
  border: 1px solid var(--w-color-border-furniture);
  border-radius: 10px;
  padding-top: var(--ca-space-3);
  padding-bottom: var(--ca-space-3);
  margin-bottom: var(--ca-space-3);
}

/* The one panel asking for something keeps an amber edge. */
.contentagent-ui.ca-dashpanel {
  border-inline-start: 3px solid var(--w-color-warning-100);
}

/* CAPTIONS BIND DOWNWARD.
 *
 * "THIS MONTH" read as a caption for the Upload images card above it rather
 * than a heading for the three numbers below. The cause was specificity, not
 * the value: `.ca-bench__month { margin-top: 1.5rem }` is (0,1,0) and lost to
 * `.contentagent-ui .ca-panel__title { margin: 0 }` at (0,2,0), so the
 * measured margin-top was 0px. Matching the winning specificity is the fix.
 *
 * A large gap above and a small one below is what makes a caption belong to
 * its own content. The pairs that measured 2px apart — a number and its
 * label, a card title and its note — are left alone: tightness is how those
 * read as one object.
 */
.contentagent-ui .ca-bench__main > .ca-panel__title,
.contentagent-ui .ca-bench__side > .ca-panel__title {
  margin-top: 0;
  margin-bottom: var(--ca-space-1);
}

.contentagent-ui .ca-bench__side > .ca-panel__title.ca-bench__month {
  margin-top: var(--ca-space-4);
}

/* THE FOUR COUNTS: a deliberate 2x2, not an accidental 3+1.
 *
 * The first attempt at this did nothing, and the measurement said why:
 * `display` computed to `flex`, while `grid-template-columns` computed to the
 * value below. Wagtail's rule is `.w-summary .w-summary__list` at (0,2,0) and
 * ours was `.w-summary__list` at (0,1,0) — so the columns applied to a flex
 * container, where they mean nothing, and the items kept flex-wrapping 3 + 1.
 * Matching the selector is the fix; the values were never the problem.
 *
 * THE BREAKPOINT WAS ALSO WRONG, and for a reason a viewport query cannot see:
 * the list shares the header row with the account panel, so what constrains it
 * is the width left over, not the window. Measured left-column widths were
 * 628px at a 1280 window, 765px at 1470, 992px at 1700, while four items plus
 * three 2rem gaps need 695px. So 1470 (91.9rem) sat 10px short and fell back
 * to 3 + 1 despite being past the old 90rem breakpoint.
 *
 * Two changes: the column gap drops to --ca-space-3, which brings the four
 * across down to 659px, and the breakpoint moves to 88rem (1408px), where the
 * leftover width is about 700px. Verified at 1280, 1470 and 1700.
 *
 * NEITHER OF THOSE TOOK EFFECT AS WRITTEN (2026-09-23). The --ca-space-*
 * tokens are defined on .contentagent-ui, and this list is in Wagtail's own
 * header, outside every .contentagent-ui element. So the gap resolved to
 * nothing and the four tiles sat with a 0px gap between them. The fallbacks
 * below are the token values themselves.
 *
 * The breakpoint is now a CONTAINER query on .w-summary, so it measures the
 * width the list actually has rather than the window. Measured in headless
 * Chrome: the four tiles are 95 + 148 + 165 + 194 = 602px at max-content,
 * plus three 20px gaps, which makes 662px. 41.5rem is 664px. Past that, four
 * across never squeezes. Below it the list stays 2×2, however wide the
 * account panel grows. The one number left is the tiles' own content width.
 * It moves only if their labels or the width of their figures change.
 * A browser without container queries (all of the ones Wagtail 6.3 supports
 * have them) keeps the 2×2 layout.
 */
.w-summary {
  container-type: inline-size;
}

.w-summary .w-summary__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, auto));
  gap: var(--ca-space-1, 0.5rem) var(--ca-space-3, 1.25rem);
  justify-content: start;
}

@container (min-width: 41.5rem) {
  /* Where the width genuinely exists, four across as the board draws it. */
  .w-summary .w-summary__list {
    grid-template-columns: repeat(4, minmax(0, auto));
  }
}

/* The agent activity list, replacing the recent-edits list. */
.contentagent-ui .ca-acts {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--ca-space-1);
}

.contentagent-ui .ca-act {
  display: grid;
  gap: 0.1rem;
  padding-bottom: var(--ca-space-1);
  border-bottom: 1px solid var(--w-color-border-furniture);
}

.contentagent-ui .ca-act__title {
  font-size: 0.9375rem;
  text-decoration: none;
}

.contentagent-ui .ca-act__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem;
  font-size: 0.8125rem;
  color: var(--w-color-text-meta);
}


/* ===========================================================================
 * Modeladmin listings: row actions and the title column.
 *
 * Measured on /admin/article/contentlibrarypost/ at 1440 (2026-09-24): each
 * row stacked Edit, Copy, Unpublish and Delete four high under the ID, in four
 * styles with Copy and Unpublish drawn heavier than Edit, and "Unpublish"
 * wrapped to "Unpu / blish" inside its own button. The title column was 112px,
 * so "Flammable Storage Cabinet Checklist" ran one word to a line.
 *
 * Three causes, all Wagtail's own rules meeting a narrow first column:
 * `.listing .actions` floats the list and each item, so they stack as soon as
 * the column is narrower than all four; `.actions .button` sets
 * `white-space: normal`, which is what lets a label break inside its button;
 * and the column widths are the browser's auto layout, which gave the title
 * what was left.
 *
 * The page belongs to the article app. This stylesheet is on it, as on every
 * admin page, so the fix is here and article/ is untouched. <body> carries
 * only `modeladmin`, with nothing naming the model, so these rules reach every
 * modeladmin listing (Content Library, categories, webinars, registrations,
 * mail templates, authors). They share this markup and the same fault.
 * =========================================================================== */

/* The four actions, two by two under the ID. Four across would need about
 * 270px, and the list column is 980px at 1440 for nine columns, the first of
 * them carrying Wagtail's 80px gutter padding. A grid rather than a wrapping
 * row, so every listing breaks the same way whatever its buttons' widths. */
.modeladmin .listing ul.actions {
  float: none;
  display: grid;
  grid-template-columns: repeat(2, max-content);
  gap: 0.3rem 0.35rem;
  align-items: center;
  margin: 0.4rem 0 0;
}

.modeladmin .listing ul.actions > li {
  float: none;
  padding: 0;
}

/* A label never breaks inside its button, and a little less padding keeps
   the two-by-two block to 136px. */
.modeladmin .listing ul.actions .button {
  padding-inline: 0.5rem;
  white-space: nowrap;
}

/* A hierarchy: Edit is the action, drawn filled. Copy and Unpublish are
   there when needed, drawn as outlines. Delete is the one that cannot be
   taken back, so it is quiet and last: red text, no box. */
.modeladmin .listing ul.actions .button,
.modeladmin .listing ul.actions .button-secondary {
  background-color: transparent;
  border-color: var(--w-color-border-button-outline-default);
  color: var(--w-color-text-button-outline-default);
}

.modeladmin .listing ul.actions .button:hover {
  background-color: var(--w-color-surface-button-outline-hover);
  border-color: var(--w-color-border-button-outline-hover);
  color: var(--w-color-text-button-outline-hover);
}

.modeladmin .listing ul.actions a.button[href*="/edit/"] {
  background-color: var(--w-color-surface-button-default);
  border-color: var(--w-color-surface-button-default);
  color: var(--w-color-text-button);
}

.modeladmin .listing ul.actions a.button[href*="/edit/"]:hover {
  background-color: var(--w-color-surface-button-hover);
  border-color: var(--w-color-surface-button-hover);
  color: var(--w-color-text-button);
}

.modeladmin .listing ul.actions .button.no {
  background-color: transparent;
  border-color: transparent;
  color: var(--w-color-text-error);
}

.modeladmin .listing ul.actions .button.no:hover {
  background-color: transparent;
  border-color: var(--w-color-text-error);
  color: var(--w-color-text-error);
}

/* The title gets room to read. Its floor is what the other eight columns
 * can spare, measured: headers that may wrap ("Locale short name" was held
 * at 152px on one line) give back about 100px, and the title keeps 11rem at
 * 1440 (212px wide, two lines for "Flammable Storage Cabinet Checklist"
 * instead of four) and 9rem below 85rem (144px at 1280). More would push the
 * last column under the filter panel, which sits beside the table at a fixed
 * share of the page. */
.modeladmin .listing thead th,
.modeladmin .listing thead th a {
  white-space: normal;
}

.modeladmin .listing th.column-title,
.modeladmin .listing td.field-title {
  min-width: 11rem;
}

@media (max-width: 85rem) {
  .modeladmin .listing th.column-title,
  .modeladmin .listing td.field-title {
    min-width: 9rem;
  }
}
