/* ============================================================================
   Awareness platform — administrator interface design system.

   Loaded only by templates/admin_app/base.html. The participant-facing
   simulation templates (templates/sim/*) do not extend that base and never
   link this file, so nothing here can reach them. Every rule is additionally
   scoped under `.aw` on <body> so an accidental future include still cannot
   restyle a simulation page.

   Presentation only: no rule changes a form's name, value, method or action.
   ========================================================================= */

/* --- 1. Tokens ----------------------------------------------------------- */

.aw {
  /* Surfaces and lines */
  --bg:            #f5f6f8;
  --surface:       #ffffff;
  --surface-sunk:  #fafbfc;
  --surface-alt:   #f2f4f7;
  --line:          #e3e7ec;
  --line-strong:   #cdd4dc;

  /* Text */
  --ink:           #16212c;
  --ink-2:         #4d5a67;
  --ink-3:         #74818e;

  /* One primary accent */
  --accent:        #1b4dc1;
  --accent-ink:    #14399a;
  --accent-soft:   #eaf0fd;

  /* Semantic — always paired with text, never colour alone */
  --ok:            #13703f;
  --ok-soft:       #e7f4ec;
  --warn:          #8a5000;
  --warn-soft:     #fdf1e0;
  --danger:        #ac2318;
  --danger-soft:   #fdeceb;
  --info:          #0d6685;
  --info-soft:     #e6f2f7;
  --neutral:       #55626f;
  --neutral-soft:  #eef1f4;

  /* 4px spacing scale */
  --s1: .25rem; --s2: .5rem; --s3: .75rem; --s4: 1rem;
  --s5: 1.5rem; --s6: 2rem;  --s7: 3rem;

  --radius:    .5rem;
  --radius-sm: .3rem;
  --shadow:    0 1px 2px rgba(22, 33, 44, .06), 0 1px 3px rgba(22, 33, 44, .04);

  --nav-w: 15.5rem;
}

/* --- 2. Base ------------------------------------------------------------- */

.aw {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

.aw *, .aw *::before, .aw *::after { box-sizing: border-box; }

.aw a { color: var(--accent); text-decoration: none; }
.aw a:hover { text-decoration: underline; }

.aw h1, .aw h2, .aw h3, .aw h4 { margin: 0; font-weight: 600; line-height: 1.25; }
.aw h1 { font-size: 1.5rem; letter-spacing: -.01em; }
.aw h2 { font-size: 1.125rem; }
.aw h3 { font-size: 1rem; }
.aw p  { margin: 0 0 var(--s3); }
.aw p:last-child { margin-bottom: 0; }

.aw code, .aw pre, .aw .mono {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: .875em;
}
.aw code {
  background: var(--surface-alt); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: .05em .3em;
}

/* Visible keyboard focus everywhere, including on native controls. */
.aw :focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

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

.aw .skip-link {
  position: absolute; left: var(--s3); top: -3rem; z-index: 60;
  background: var(--surface); color: var(--ink);
  padding: var(--s2) var(--s4); border-radius: var(--radius-sm);
  box-shadow: var(--shadow); transition: top .12s ease;
}
.aw .skip-link:focus { top: var(--s3); }

/* --- 3. Application shell ------------------------------------------------ */

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

.sidebar {
  width: var(--nav-w); flex: 0 0 var(--nav-w);
  background: var(--surface);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}

.orgbar { padding: var(--s4); border-bottom: 1px solid var(--line); }
.orgbar__product {
  font-size: .6875rem; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--s2);
}
.orgbar__label {
  font-size: .6875rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3);
}
.orgbar__name {
  font-size: 1rem; font-weight: 600; color: var(--ink);
  overflow-wrap: anywhere; margin-top: .1rem;
}
.orgbar__slug { font-size: .75rem; color: var(--ink-3); }
.orgbar__switch { display: inline-block; margin-top: var(--s2); font-size: .8125rem; }
/* The script un-hides the toggle; this keeps it out of the wide layout, where
   the navigation is always open and the button would do nothing useful. */
.aw .orgbar [data-nav-toggle] { display: none; }

.nav { padding: var(--s3) var(--s2) var(--s4); flex: 1; }
.nav__list { list-style: none; margin: 0; padding: 0; }
.nav__list li { margin: 0; }
.nav__group + .nav__group { margin-top: var(--s4); }
.nav__title {
  font-size: .6875rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-3);
  padding: 0 var(--s3); margin-bottom: var(--s1);
}
.nav__link {
  display: block; padding: .4rem var(--s3); border-radius: var(--radius-sm);
  color: var(--ink-2); font-size: .875rem; line-height: 1.4;
}
.nav__link:hover { background: var(--surface-alt); color: var(--ink); text-decoration: none; }
.nav__link[aria-current="page"] {
  background: var(--accent-soft); color: var(--accent-ink); font-weight: 600;
  box-shadow: inset 2px 0 0 var(--accent);
}

.account {
  border-top: 1px solid var(--line); padding: var(--s3) var(--s4);
  font-size: .8125rem; color: var(--ink-2);
}
.account__who { font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.account__role { color: var(--ink-3); }
.account__links { margin-top: var(--s2); display: flex; gap: var(--s3); flex-wrap: wrap; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar { display: none; }

.content {
  flex: 1; width: 100%; max-width: 78rem;
  margin: 0 auto; padding: var(--s5) var(--s5) var(--s7);
}

/* --- 4. Page header ------------------------------------------------------ */

.crumbs {
  font-size: .8125rem; color: var(--ink-3);
  margin-bottom: var(--s2); display: flex; flex-wrap: wrap; gap: .35rem;
}
.crumbs ol { list-style: none; margin: 0; padding: 0; display: contents; }
.crumbs li { display: flex; align-items: center; gap: .35rem; }
.crumbs li + li::before { content: "/"; color: var(--line-strong); }
.crumbs a { color: var(--ink-2); }
.crumbs [aria-current="page"] { color: var(--ink-2); }

.page-head {
  display: flex; flex-wrap: wrap; gap: var(--s4);
  align-items: flex-start; justify-content: space-between;
  margin-bottom: var(--s4);
}
.page-head__text { min-width: 0; }
.page-head__lede { color: var(--ink-2); font-size: .9375rem; margin: var(--s2) 0 0; max-width: 62ch; }
.page-head__meta { color: var(--ink-3); font-size: .8125rem; margin: var(--s1) 0 0; }
.page-head__actions { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }

.section { margin-top: var(--s6); }
.section__head {
  display: flex; flex-wrap: wrap; gap: var(--s3);
  align-items: baseline; justify-content: space-between; margin-bottom: var(--s3);
}
.section__note { color: var(--ink-2); font-size: .875rem; margin: 0 0 var(--s3); max-width: 78ch; }

/* --- 5. Panels ----------------------------------------------------------- */

.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.panel + .panel { margin-top: var(--s4); }
.panel__head {
  padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: var(--s3);
  align-items: baseline; justify-content: space-between;
}
.panel__title { font-size: .9375rem; font-weight: 600; }
.panel__body { padding: var(--s4); }
.panel__foot {
  padding: var(--s3) var(--s4); border-top: 1px solid var(--line);
  background: var(--surface-sunk);
  border-radius: 0 0 var(--radius) var(--radius);
  display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center;
}

/* --- 6. Buttons and controls -------------------------------------------- */

.aw .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: 2.25rem; padding: .4rem .9rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: .875rem; font-weight: 500;
  cursor: pointer; text-decoration: none; white-space: nowrap;
}
.aw .btn:hover { background: var(--surface-alt); text-decoration: none; }
.aw .btn--primary {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.aw .btn--primary:hover { background: var(--accent-ink); border-color: var(--accent-ink); }
.aw .btn--danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.aw .btn--danger:hover { background: #8f1c13; border-color: #8f1c13; }
.aw .btn--ghost { background: transparent; border-color: transparent; color: var(--accent); }
.aw .btn--ghost:hover { background: var(--accent-soft); }
.aw .btn--sm { min-height: 1.875rem; padding: .2rem .6rem; font-size: .8125rem; }
.aw .btn[disabled] { opacity: .55; cursor: not-allowed; }

/* A link that must post. Looks like a link, behaves like a button. */
.aw .linkish {
  background: none; border: 0; padding: 0; margin: 0;
  color: var(--accent); font: inherit; font-size: inherit;
  cursor: pointer; text-decoration: none;
}
.aw .linkish:hover { text-decoration: underline; }
.aw .linkish--danger { color: var(--danger); }

/* A flex container's min-content width is its widest child, so inside a
   `width: 1%` table cell a wrapping row of actions collapses to one item per
   line and trebles the row height. Keeping it on one line lets the column take
   its max-content width instead. */
.row-actions {
  display: inline-flex; gap: var(--s2); align-items: center;
  flex-wrap: nowrap; white-space: nowrap; font-size: .8125rem;
}
.row-actions > * { white-space: nowrap; }
.row-actions .sep { color: var(--line-strong); }

/* Two lines, for a row whose action set has outgrown one.
   The participant row is the case: everyday actions on the first line, the
   two privacy actions on a subordinate second. Kept off the shared class on
   purpose -- increment 10 found that row actions collapsing to one per line
   inside a `width: 1%` cell was a defect, and this is not that: each line is
   still `nowrap`, and the split is chosen rather than a consequence of the
   column being squeezed.
   The cell must also drop `white-space: nowrap`, or the group cannot break at
   all and the table simply grows wider than the page -- which is how this was
   found, with Delete clipped past the right edge of a screenshot. */
.cell-actions { white-space: normal !important; }
.row-actions--stacked { display: block; }
.row-actions--stacked .row-actions__line {
  display: flex; gap: var(--s2); align-items: center; flex-wrap: nowrap;
}
.row-actions--stacked .row-actions__line + .row-actions__line {
  margin-top: .2rem;
}
.row-actions--stacked .row-actions__line--minor { color: var(--ink-3); }

/* --- 7. Forms ------------------------------------------------------------ */

.aw input[type="text"], .aw input[type="email"], .aw input[type="password"],
.aw input[type="number"], .aw input[type="url"], .aw input[type="search"],
.aw input[type="tel"], .aw input[type="date"], .aw input[type="time"],
.aw input[type="datetime-local"], .aw input:not([type]),
.aw select, .aw textarea {
  width: 100%; max-width: 100%;
  min-height: 2.25rem; padding: .4rem .6rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: .9375rem;
}
.aw textarea { min-height: 6rem; line-height: 1.5; resize: vertical; }
.aw select { padding-right: var(--s5); }
.aw input[type="file"] {
  font: inherit; font-size: .875rem; max-width: 100%;
  padding: .4rem 0;
}
.aw input[type="checkbox"], .aw input[type="radio"] {
  width: 1.05rem; height: 1.05rem; margin: 0; accent-color: var(--accent);
  flex: 0 0 auto; cursor: pointer;
}

.form { max-width: 46rem; }
.form--wide { max-width: none; }

.fieldset { border: 0; margin: 0 0 var(--s5); padding: 0; }
.fieldset:last-of-type { margin-bottom: 0; }
.fieldset__legend {
  padding: 0; font-size: .9375rem; font-weight: 600; color: var(--ink);
  margin-bottom: var(--s1);
}
.fieldset__note {
  color: var(--ink-2); font-size: .8125rem; margin: 0 0 var(--s3); max-width: 70ch;
}
.fieldset__body {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); padding: var(--s4);
}

.field { margin-bottom: var(--s4); }
.field:last-child { margin-bottom: 0; }
.field__label {
  display: block; font-size: .8125rem; font-weight: 600;
  color: var(--ink); margin-bottom: var(--s1);
}
.field__optional { font-weight: 400; color: var(--ink-3); }
.field__req { color: var(--danger); font-weight: 400; }
.field__help { font-size: .8125rem; color: var(--ink-2); margin: var(--s1) 0 0; max-width: 70ch; }
.field__error {
  font-size: .8125rem; color: var(--danger); margin: var(--s1) 0 0; font-weight: 500;
}
.field--invalid input, .field--invalid select, .field--invalid textarea {
  border-color: var(--danger);
}
/* A checkbox reads as "control, then label". */
.field--check { display: flex; gap: var(--s2); align-items: flex-start; }
.field--check .field__label { margin-bottom: 0; font-weight: 500; }
.field--check .field__body { padding-top: .15rem; }
/* Django wraps a multi-input widget in a <fieldset>; its default border would
   sit around the list's own. */
.field__fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.field__fieldset > .field__label { padding: 0; }
/* Checkbox / radio lists produced by CheckboxSelectMultiple. */
.field ul { list-style: none; margin: 0; padding: 0;
  max-height: 16rem; overflow-y: auto;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: var(--s2); background: var(--surface-sunk); }
.field ul li { margin: 0; }
.field ul label {
  display: flex; gap: var(--s2); align-items: center;
  padding: .2rem var(--s1); font-size: .875rem; cursor: pointer;
}
.field ul label:hover { background: var(--surface-alt); border-radius: var(--radius-sm); }

.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s4); align-items: start; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s4); }

.form-actions {
  display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center;
  margin-top: var(--s5); padding-top: var(--s4); border-top: 1px solid var(--line);
}
.form-actions--plain { border-top: 0; padding-top: 0; }

/* --- 8. Filter bar ------------------------------------------------------- */

.filters {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--s3) var(--s4);
  box-shadow: var(--shadow);
}
.filters__row {
  display: flex; flex-wrap: wrap; gap: var(--s3); align-items: flex-end;
}
.filters__field { display: flex; flex-direction: column; gap: .2rem; min-width: 9rem; }
.filters__field--grow { flex: 1 1 14rem; }
.filters__field label {
  font-size: .75rem; font-weight: 600; color: var(--ink-2);
  text-transform: uppercase; letter-spacing: .04em;
}
.filters__actions { display: flex; gap: var(--s2); align-items: center; }

.chips { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; margin-top: var(--s3); }
.chip {
  display: inline-flex; align-items: center; gap: .35rem;
  background: var(--accent-soft); color: var(--accent-ink);
  border: 1px solid #cddcf8; border-radius: 999px;
  padding: .1rem .6rem; font-size: .8125rem;
}
.chip b { font-weight: 600; }

.result-bar {
  display: flex; flex-wrap: wrap; gap: var(--s3);
  align-items: center; justify-content: space-between;
  margin: var(--s4) 0 var(--s2);
}
.result-bar__count { font-size: .875rem; color: var(--ink-2); }
.result-bar__count b { color: var(--ink); }

/* --- 9. Tables ----------------------------------------------------------- */

.table-wrap {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden;
  position: relative;
}
/* `position: relative` is load-bearing, not decoration. Without it the
   absolutely-positioned .visually-hidden labels inside the cells have no
   positioned ancestor, so their containing block is the viewport: they escape
   the scroll container and stretch the document to the table's full width,
   giving every wide table a horizontal page scrollbar. */
.table-scroll { overflow-x: auto; position: relative; }

.aw table.table { width: 100%; border-collapse: collapse; background: var(--surface); }
.aw table.table caption { text-align: left; padding: var(--s3) var(--s4); color: var(--ink-2); font-size: .875rem; }
.aw table.table th, .aw table.table td {
  padding: .55rem var(--s4); text-align: left; font-size: .875rem;
  border-bottom: 1px solid var(--line); vertical-align: top;
}
.aw table.table thead th {
  background: var(--surface-sunk); color: var(--ink-2);
  font-size: .75rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
  white-space: nowrap; position: sticky; top: 0; z-index: 1;
  border-bottom: 1px solid var(--line-strong);
}
.aw table.table tbody tr:last-child td { border-bottom: 0; }
.aw table.table tbody tr:hover { background: var(--surface-sunk); }
.aw table.table td.num, .aw table.table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.aw table.table .nowrap { white-space: nowrap; }
.aw table.table .shrink { width: 1%; white-space: nowrap; }

.sortlink { display: inline-flex; align-items: center; gap: .25rem; color: var(--ink-2); }
.sortlink:hover { color: var(--accent); }
.sortlink__dir { font-size: .7rem; color: var(--accent); }
th[aria-sort] .sortlink { color: var(--accent-ink); font-weight: 700; }

.cell-name { font-weight: 600; color: var(--ink); }
.cell-sub { display: block; color: var(--ink-3); font-size: .8125rem; font-weight: 400; }
.ts { font-variant-numeric: tabular-nums; white-space: nowrap; }
.ts__zone { color: var(--ink-3); font-size: .75rem; }
/* In a column header the zone sits straight after the header's own word, and an
   IANA name is two words with a slash in it: "STARTED EUROPE/LONDON" reads as
   one phrase. Parentheses separate them. Not applied to the inline use beside a
   value, where "14:00 Europe/London" already reads correctly. */
.aw table.table th .ts__zone::before { content: "("; }
.aw table.table th .ts__zone::after { content: ")"; }
.muted { color: var(--ink-3); }

/* --- 10. Status pills ---------------------------------------------------- */

.pill {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .1rem .55rem; border-radius: 999px;
  font-size: .75rem; font-weight: 600; white-space: nowrap;
  border: 1px solid transparent;
}
.pill::before {
  content: ""; width: .45rem; height: .45rem; border-radius: 50%;
  background: currentColor; flex: 0 0 auto;
}
.pill--neutral, .pill--draft, .pill--queued, .pill--skipped, .pill--cancelled {
  background: var(--neutral-soft); color: var(--neutral); border-color: #dde2e8;
}
.pill--info, .pill--scheduled, .pill--sending, .pill--opened {
  background: var(--info-soft); color: var(--info); border-color: #cfe6ef;
}
.pill--accent, .pill--running {
  background: var(--accent-soft); color: var(--accent-ink); border-color: #cddcf8;
}
.pill--ok, .pill--completed, .pill--sent, .pill--reported, .pill--trained {
  background: var(--ok-soft); color: var(--ok); border-color: #cfe7d9;
}
.pill--warn, .pill--expired, .pill--retry, .pill--uncertain, .pill--retrying, .pill--clicked {
  background: var(--warn-soft); color: var(--warn); border-color: #f2ddbe;
}
.pill--danger, .pill--failed, .pill--submitted {
  background: var(--danger-soft); color: var(--danger); border-color: #f6d2cf;
}
/* RUNNING deserves a live cue, but never motion alone and never for people
   who have asked for less of it. */
.pill--running::before { animation: pulse 2.4s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }
@media (prefers-reduced-motion: reduce) {
  .aw *, .aw *::before, .aw *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* --- 11. Metrics --------------------------------------------------------- */

.metrics {
  display: grid; gap: var(--s3);
  grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
}
.metric {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--s3) var(--s4);
}
.metric--lead { border-left: 3px solid var(--accent); }
.metric__value {
  display: block; font-size: 1.625rem; font-weight: 650;
  line-height: 1.1; font-variant-numeric: tabular-nums; color: var(--ink);
}
.metric__label { display: block; font-size: .8125rem; color: var(--ink-2); margin-top: .15rem; }
.metric__scope { display: block; font-size: .75rem; color: var(--ink-3); margin-top: .15rem; }
.metric a.metric__label:hover { color: var(--accent); }

.deflist { margin: 0; display: grid;
  grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
  gap: .35rem var(--s4); }
.deflist dt { color: var(--ink-2); font-size: .8125rem; }
.deflist dd { margin: 0; font-size: .875rem; }

/* --- 12. Notices, empty states, details ---------------------------------- */

.notice {
  border: 1px solid var(--line); border-left-width: 3px;
  border-radius: var(--radius-sm);
  padding: var(--s3) var(--s4); margin-bottom: var(--s3);
  background: var(--surface); font-size: .875rem;
}
.notice__title { font-weight: 600; margin-bottom: .15rem; }
.notice ul { margin: var(--s2) 0 0; padding-left: 1.1rem; }
.notice li { margin-bottom: .2rem; }
.notice--info    { border-left-color: var(--info);    background: var(--info-soft); }
.notice--ok      { border-left-color: var(--ok);      background: var(--ok-soft); }
.notice--warn    { border-left-color: var(--warn);    background: var(--warn-soft); }
.notice--danger  { border-left-color: var(--danger);  background: var(--danger-soft); }
.notice--neutral { border-left-color: var(--line-strong); background: var(--surface-sunk); }

.messages { margin-bottom: var(--s4); }

.empty {
  background: var(--surface); border: 1px dashed var(--line-strong);
  border-radius: var(--radius); padding: var(--s6) var(--s5); text-align: center;
}
.empty__title { font-size: 1rem; font-weight: 600; margin-bottom: var(--s2); }
.empty__body { color: var(--ink-2); font-size: .875rem; max-width: 52ch; margin: 0 auto var(--s4); }
.empty__actions { display: flex; gap: var(--s2); justify-content: center; flex-wrap: wrap; }
td .empty { border: 0; background: none; padding: var(--s5); }

.aw details.explain {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); margin-bottom: var(--s3);
}
.aw details.explain > summary {
  cursor: pointer; padding: var(--s2) var(--s3);
  font-size: .875rem; font-weight: 600; color: var(--ink-2);
  list-style-position: inside;
}
.aw details.explain > summary:hover { color: var(--accent); }
.aw details.explain[open] > summary { border-bottom: 1px solid var(--line); }
.aw details.explain .explain__body { padding: var(--s3); font-size: .875rem; color: var(--ink-2); }
.aw details.explain .explain__body p { max-width: 80ch; }

/* --- 13. Checklist (empty-organization guidance) ------------------------- */

.checklist { list-style: none; margin: 0; padding: 0; }
.checklist li {
  display: flex; gap: var(--s3); align-items: flex-start;
  padding: var(--s3) 0; border-bottom: 1px solid var(--line);
}
.checklist li:last-child { border-bottom: 0; }
.checklist__mark {
  flex: 0 0 auto; width: 1.4rem; height: 1.4rem; border-radius: 50%;
  display: grid; place-items: center; font-size: .75rem; font-weight: 700;
  background: var(--neutral-soft); color: var(--ink-3); border: 1px solid var(--line-strong);
}
.checklist__mark--done { background: var(--ok-soft); color: var(--ok); border-color: #cfe7d9; }
.checklist__text { min-width: 0; }
/* Both are spans so they can live inside a span; they still need to stack. */
.checklist__title { display: block; font-weight: 600; font-size: .9375rem; }
.checklist__title .pill { vertical-align: 1px; margin-left: var(--s1); }
.checklist__why { display: block; color: var(--ink-2); font-size: .8125rem; margin-top: .15rem; }
.checklist__why a { white-space: nowrap; }

/* --- 14. Step indicator (mirrors the real screens, nothing more) ---------- */

.steps { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s4); padding: 0; list-style: none; }
.steps li {
  display: flex; align-items: center; gap: .4rem;
  font-size: .8125rem; color: var(--ink-3);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: .2rem .7rem;
}
.steps li b { font-weight: 600; }
.steps li[aria-current="step"] {
  background: var(--accent-soft); border-color: #cddcf8; color: var(--accent-ink); font-weight: 600;
}
.steps li.is-done { color: var(--ok); border-color: #cfe7d9; background: var(--ok-soft); }
.steps__n {
  width: 1.25rem; height: 1.25rem; border-radius: 50%;
  background: var(--surface-alt); color: inherit;
  display: grid; place-items: center; font-size: .6875rem; font-weight: 700;
}

/* --- 15. Charts and code editors ---------------------------------------- */

.chart { background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--s4); }
/* The chart is server-rendered SVG with a fixed height attribute and a wider
   viewBox, which letterboxes it into the centre at full width. Overriding the
   height lets it scale on its own aspect ratio instead. */
.chart svg { display: block; width: 100%; height: auto; }
.legend { display: flex; flex-wrap: wrap; gap: var(--s4); font-size: .8125rem; color: var(--ink-2); margin-bottom: var(--s2); }
.legend span { display: inline-flex; align-items: center; gap: .4rem; }
.legend i { width: .75rem; height: .2rem; border-radius: 1px; display: inline-block; }

/* The authored-content editors hold raw HTML. Django renders the widget, so the
   class cannot be set on it; the ids it generates are stable and are what these
   rules hang off. */
.aw #id_html_body, .aw #id_text_body, .aw #id_html {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: .8125rem; line-height: 1.6; min-height: 18rem;
  background: var(--surface-sunk); tab-size: 2;
}
.aw #id_text_body { min-height: 10rem; }
.aw textarea.code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: .8125rem; line-height: 1.55; min-height: 20rem;
  background: var(--surface-sunk); white-space: pre; overflow-wrap: normal;
}

.tokenbar {
  display: flex; flex-wrap: wrap; gap: var(--s1); align-items: center;
  margin-bottom: var(--s2);
}
.tokenbar__label { font-size: .75rem; color: var(--ink-2); margin-right: var(--s1); }
.aw .token-btn {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .75rem; padding: .15rem .45rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--surface-alt); color: var(--ink-2); cursor: pointer;
}
.aw .token-btn:hover { background: var(--accent-soft); color: var(--accent-ink); border-color: #cddcf8; }

.aw pre.codes {
  background: var(--surface-sunk); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: var(--s4); margin: 0 0 var(--s4);
  font-size: .9375rem; line-height: 1.8; letter-spacing: .04em;
  overflow-x: auto;
}

/* --- 16. Selection bar (participant bulk actions) ----------------------- */

.selectbar {
  display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center;
  padding: var(--s3) var(--s4); border-top: 1px solid var(--line);
  background: var(--surface-sunk);
}
.selectbar__count { font-size: .875rem; color: var(--ink-2); }
.selectbar__count b { color: var(--ink); }

/* --- 17. Authentication pages ------------------------------------------- */

.auth { min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: var(--s5) var(--s4); background: var(--bg); }
.auth__card {
  width: 100%; max-width: 27rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: 0 2px 12px rgba(22, 33, 44, .07);
  padding: var(--s6);
}
.auth__brand {
  font-size: .6875rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--s3);
}
.auth__title { font-size: 1.25rem; margin-bottom: var(--s2); }
.auth__lede { color: var(--ink-2); font-size: .875rem; margin-bottom: var(--s5); }
.auth__card .btn { width: 100%; }
.auth__foot { margin-top: var(--s4); font-size: .8125rem; color: var(--ink-3); text-align: center; }
.auth__qr {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: var(--s3); width: fit-content; margin: 0 auto var(--s3);
}
.auth__qr svg, .auth__qr img { display: block; max-width: 11rem; height: auto; }

/* --- 18. Report layout and print ---------------------------------------- */

.report { background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--s6); box-shadow: var(--shadow); }
.report__masthead { border-bottom: 2px solid var(--ink); padding-bottom: var(--s3); margin-bottom: var(--s4); }
.report__org { font-size: .75rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
.report__title { font-size: 1.5rem; margin: var(--s1) 0; }
.report h2 {
  font-size: 1rem; margin: var(--s6) 0 var(--s3);
  padding-bottom: var(--s1); border-bottom: 1px solid var(--line);
}
.report h2:first-of-type { margin-top: var(--s5); }
.report .table-wrap { box-shadow: none; }

@media print {
  .aw { background: #fff; font-size: 11pt; }
  .noprint, .sidebar, .topbar, .messages, .page-head__actions, .skip-link { display: none !important; }
  /* Paper has no scrollbar: a table clipped on screen must print in full. */
  .table-wrap, .table-scroll { overflow: visible !important; }
  .content { max-width: none; padding: 0; margin: 0; }
  .shell { display: block; }
  .report { border: 0; border-radius: 0; box-shadow: none; padding: 0; }
  .panel, .table-wrap, .metric, .chart { box-shadow: none; border-color: #bbb; break-inside: avoid; }
  .aw table.table thead th { position: static; background: #f0f0f0; color: #000; }
  .aw table.table { break-inside: auto; }
  .aw table.table tr { break-inside: avoid; break-after: auto; }
  .aw table.table thead { display: table-header-group; }
  .pill { border: 1px solid #999 !important; background: #fff !important; color: #000 !important; }
  .report h2 { break-after: avoid; }
  .aw a { color: #000; text-decoration: none; }
  .metrics { grid-template-columns: repeat(4, 1fr); }
  @page { margin: 16mm; }
}

/* --- 19. Responsive ------------------------------------------------------ */

@media (max-width: 1100px) {
  .content { padding: var(--s4) var(--s4) var(--s6); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  .shell { display: block; }
  .sidebar {
    position: static; width: auto; height: auto; flex: none;
    border-right: 0; border-bottom: 1px solid var(--line);
  }
  /* Collapsed by default on a phone, but only when the toggle is present —
     without JavaScript the nav simply stays open rather than disappearing. */
  .sidebar.is-collapsible .nav,
  .sidebar.is-collapsible .account { display: none; }
  .sidebar.is-collapsible.is-open .nav,
  .sidebar.is-collapsible.is-open .account { display: block; }
  .orgbar { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s3); }
  .aw .orgbar [data-nav-toggle]:not([hidden]) { display: inline-flex; }
  .topbar { display: block; }
  .nav { display: block; }
  .nav__group + .nav__group { margin-top: var(--s3); }
  .content { padding: var(--s4) var(--s3) var(--s6); }
  .grid-2, .grid-3 { grid-template-columns: minmax(0, 1fr); }
  .page-head { flex-direction: column; align-items: stretch; }
  .metrics { grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); }
  .aw table.table th, .aw table.table td { padding: .5rem var(--s3); }
}

@media (max-width: 560px) {
  .aw { font-size: 15px; }
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .metric__value { font-size: 1.375rem; }
  .filters__field { min-width: 0; flex: 1 1 100%; }
  .form-actions .btn { flex: 1 1 auto; }
  .panel__body, .fieldset__body { padding: var(--s3); }
  .report { padding: var(--s4); }
  /* Two columns of definitions do not fit a phone; stack them instead of
     letting the term column squeeze the value into an overflow. */
  .deflist { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .deflist dt { margin-top: var(--s3); font-weight: 600; }
  .deflist dt:first-child { margin-top: 0; }
}

/* ---------------------------------------------------------------------------
   Landing page builder
   ---------------------------------------------------------------------------
   A code editor and a preview stage. Both want more height than a form field
   and neither may introduce a second scrollbar, so the editor grows and the
   preview stage scrolls inside itself rather than nesting page scroll.
   --------------------------------------------------------------------------- */

/* `.aw #id_html` already styles the content editors by id -- the widget is
   Django's, so a class cannot be put on it -- and an id outranks any number of
   classes. The builder's editor therefore has to name the id too, or it keeps
   the 18rem height the smaller editors use. */
.aw .editor #id_html,
.aw .editor textarea.code,
.aw .editor textarea {
  min-height: 600px;
  line-height: 1.55;
  tab-size: 2;
  white-space: pre;        /* horizontal scrolling for long lines, not wrapping */
  overflow: auto;
  resize: vertical;
}

@media (max-width: 720px) {
  .aw .editor #id_html,
  .aw .editor textarea { min-height: 22rem; }
}

.editor__status {
  display: flex;
  gap: var(--s2);
  align-items: baseline;
  margin: var(--s2) 0 0;
  font-size: .75rem;
  color: var(--muted);
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}

.preview {
  border: 1px solid var(--line);
  border-radius: var(--r2, .5rem);
  background: var(--surface, #fff);
  overflow: hidden;
}

.preview__bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  align-items: center;
  padding: var(--s3);
  border-bottom: 1px solid var(--line);
  background: var(--surface-2, #f7f8f9);
}

.preview__widths { margin-left: auto; display: flex; gap: var(--s2); }

/* The stage is the scroll container, so a tall preview never adds a second
   scrollbar to the page itself. */
.preview__stage {
  padding: var(--s3);
  background: var(--surface-2, #f7f8f9);
  max-height: 46rem;
  overflow: auto;
  display: flex;
  justify-content: center;
}

.preview__stage iframe {
  width: 100%;
  max-width: 100%;
  height: 42rem;
  border: 1px solid var(--line);
  background: #fff;
}

/* An empty stage is a hint, not a large blank rectangle pretending to be a
   page that failed to load. */
.preview__stage--empty { min-height: 0; padding: var(--s5) var(--s3); }
.preview__hint { margin: 0; color: var(--muted); font-size: .8125rem; }

.section__actions { margin: var(--s3) 0 0; }

/* --- 20. Pagination ------------------------------------------------------ */
/* Server-side only. There is no "show all": the cap is the point, and the CSV
   export is the answer to wanting the whole set. Disabled controls are rendered
   rather than omitted, so the row does not shift under the pointer between the
   first page and the second. State is never carried by colour alone — the
   current page is marked with aria-current and a filled background *and* a
   heavier weight, and a disabled control carries aria-disabled. */

.pager {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s3) var(--s4); margin: var(--s4) 0 0;
}
.pager__status { margin: 0; font-size: .875rem; color: var(--ink-2); }
.pager__status b { color: var(--ink); }

.pager__list {
  display: flex; flex-wrap: wrap; gap: var(--s1);
  list-style: none; margin: 0; padding: 0;
}

.pager__link {
  display: inline-block; min-width: 2.25rem; text-align: center;
  padding: .3rem .6rem; border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm); background: var(--surface);
  color: var(--accent-ink); text-decoration: none; font-size: .875rem;
}
a.pager__link:hover { background: var(--accent-soft); }
a.pager__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pager__link--now {
  background: var(--accent); border-color: var(--accent);
  color: #fff; font-weight: 700;
}
.pager__link--off { color: var(--ink-3); background: var(--surface-alt); }

.pager__note {
  flex-basis: 100%; margin: 0; font-size: .8125rem; color: var(--muted, var(--ink-3));
}
.pager__note code {
  background: var(--surface-alt); padding: 0 .25rem; border-radius: var(--radius-sm);
}

@media print { .pager { display: none; } }

/* --- 21. Preview provenance ---------------------------------------------- */
/* Which organization, which content and which saved revision a preview shows.
   Rendered outside the frame on purpose: a full-page landing preview runs the
   author's own script, and a caption the previewed document could rewrite is
   not a caption. See templates/admin_app/_c/preview_label.html. */

.preview__origin {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem .5rem;
  margin: 0 0 var(--s2); font-size: .8125rem; color: var(--ink-2);
}
/* One wrapping unit per piece, so a line never begins with the comma that
   belongs to the name on the line above. */
.preview__origin-item { display: inline-flex; align-items: baseline; gap: .35rem; }
.preview__origin-item + .preview__origin-item::before {
  content: "\00b7"; color: var(--line-strong); margin-right: .35rem;
}
.preview__origin-key {
  text-transform: uppercase; letter-spacing: .04em;
  font-size: .6875rem; color: var(--ink-3);
}
.preview__origin strong { color: var(--ink); font-weight: 600; }
.preview__origin-sep { color: var(--line-strong); }
.preview__origin-note {
  margin: 0 0 var(--s3); font-size: .8125rem; color: var(--ink-3);
}


/* The widest column in the delivery log and the participant timeline alike. An
   SMTP server's reply is an arbitrary string, and eight columns beside it push
   the table past the page; letting this one wrap inside a bounded width keeps
   the whole row visible without a horizontal scroll, which matters because the
   row's own outcome is the thing being read.

   It is shown in full, never truncated. A containment refusal or a provider's
   rejection carries the remedy in its tail -- the address to point at, the flag
   to set -- so a clipped reply states the problem and withholds the fix. The
   string is already capped at MAX_RESPONSE_CHARS (500) and scrubbed of
   credentials and tokens by `sending.mailer.scrub` before it is ever stored, so
   there is nothing here a width limit is protecting anyone from. */
.response { max-width: 24rem; }
.response .mono { overflow-wrap: anywhere; }
