/* policy-edit screens. Owned by one workstream; shared rules live in css/components.css and css/screens.css.
   Three surfaces: the policy editor (.pe-), the version list and diff on the
   policy viewer (.pv-), and the mail administration screen (.ml-). */

/* ============================================================== policy editor

   Two columns: the section being edited, and the problems panel. The panel is
   sticky because validation is continuous and a list of problems that scrolls
   away is a list nobody reads while typing. */
/* A real anchor that looks like a button. css/components.css styles `button`
   as an element, so an <a> gets none of it; these two screens want the primary
   action to be a LINK (middle click, open in a new tab, a status bar that says
   where it goes) rather than a button that calls navigate(). */
a.button, a.button.ghost {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-3);
  min-height: 34px; padding: var(--s-4) var(--s-6);
  border: var(--bw) solid transparent; border-radius: var(--r-md);
  background: var(--c-accent); color: var(--c-accent-text);
  font-size: var(--t-base); font-weight: var(--t-semibold); line-height: var(--t-tight);
  white-space: nowrap; box-shadow: var(--e-1); text-decoration: none;
}
a.button:hover { background: var(--c-accent-hover); text-decoration: none; }
a.button.ghost { background: var(--c-surface-2); color: var(--c-text); border-color: var(--c-border); box-shadow: none; }
a.button.ghost:hover { background: var(--c-surface-3); border-color: var(--c-border-strong); }
a.button svg { width: 16px; height: 16px; }

.pe-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 340px);
  gap: var(--s-7);
  align-items: start;
  margin-top: var(--s-6);
}
@media (max-width: 1020px) { .pe-split { grid-template-columns: 1fr; } }

.pe-body { min-width: 0; }
.pe-tabs { margin-top: var(--s-5); }

.pe-panel {
  position: sticky;
  top: var(--s-6);
  border: var(--bw) solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-surface);
  padding: var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  max-height: calc(100vh - var(--s-10));
  overflow: auto;
}
@media (max-width: 1020px) { .pe-panel { position: static; max-height: none; } }

.pe-panel-head { display: flex; align-items: center; gap: var(--s-3); }
.pe-panel-title { margin: 0; font-size: var(--t-sm); font-weight: var(--t-semibold); }
.pe-panel-head .sp, .pe-panel-head > :last-child { margin-left: auto; }

.pe-problems { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-4); }
.pe-problem { display: flex; gap: var(--s-3); align-items: flex-start; font-size: var(--t-xs); }
.pe-problem svg { width: 14px; height: 14px; flex: none; margin-top: 2px; color: var(--c-danger); }
.pe-problem-path { display: block; font-size: var(--t-2xs); color: var(--c-text-3); overflow-wrap: anywhere; }
.pe-problem-text { color: var(--c-text-2); line-height: var(--t-body); overflow-wrap: anywhere; }

.pe-panel-ok { display: flex; gap: var(--s-3); align-items: flex-start; font-size: var(--t-xs); color: var(--c-text-2); margin: 0; line-height: var(--t-body); }
.pe-panel-ok svg { width: 14px; height: 14px; flex: none; margin-top: 2px; color: var(--c-success); }

.pe-skipped { border-top: var(--bw) solid var(--c-border); padding-top: var(--s-4); }
.pe-skipped-head { font-size: var(--t-2xs); text-transform: uppercase; letter-spacing: .06em; color: var(--c-text-3); margin-bottom: var(--s-2); }
.pe-skipped ul { margin: 0; padding-left: var(--s-6); font-size: var(--t-2xs); color: var(--c-text-3); line-height: var(--t-body); }
.pe-panel-foot { margin: 0; font-size: var(--t-2xs); color: var(--c-text-3); line-height: var(--t-body); }

.pe-group { margin-top: var(--s-7); }
.pe-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
  gap: var(--s-5);
}
.pe-fields .field-wide { grid-column: 1 / -1; }

/* The two scoring presets, side by side, because the choice between them is the
   single most expensive disagreement in the specification and it deserves to be
   readable rather than a dropdown. */
.pe-presets { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: var(--s-4); margin-bottom: var(--s-6); }
.pe-preset {
  text-align: left; padding: var(--s-5); height: auto; min-height: 0;
  border: var(--bw) solid var(--c-border); border-radius: var(--r-md);
  background: var(--c-surface); color: inherit; display: flex; flex-direction: column; gap: var(--s-2);
  box-shadow: none; white-space: normal;
}
.pe-preset:hover { border-color: var(--c-accent); background: var(--c-hover); }
.pe-preset[aria-pressed="true"] { border-color: var(--c-accent); background: var(--c-accent-quiet); }
.pe-preset-label { font-weight: var(--t-semibold); font-size: var(--t-sm); }
.pe-preset-blurb { font-size: var(--t-2xs); color: var(--c-text-2); line-height: var(--t-body); }
.pe-preset-note { grid-column: 1 / -1; display: flex; gap: var(--s-3); align-items: flex-start; font-size: var(--t-2xs); color: var(--c-text-3); line-height: var(--t-body); }
.pe-preset-note svg { width: 14px; height: 14px; flex: none; margin-top: 2px; }

/* Editable tables. The inputs are borderless until touched so a table of forty
   controls reads as a table rather than as a wall of boxes. */
/* width:max-content and not 100%, because these tables are inside scrollX and a
   table forced to the container's width shrinks its cells until every control
   in them truncates its own value. The first screenshot of this screen showed
   "task_comp" and "can_score_dail", which is a table that has stopped being
   readable to save a scrollbar nobody minds. min-width keeps a narrow table
   filling the space it has. */
.pe-table { width: max-content; min-width: 100%; }
.pe-table-narrow { max-width: 620px; width: 100%; }
.pe-table td { padding: var(--s-2) var(--s-3); vertical-align: middle; }
.pe-in {
  width: 100%; min-width: 128px; height: 30px; padding: 0 var(--s-3);
  border: var(--bw) solid transparent; border-radius: var(--r-sm);
  background: transparent; color: var(--c-text); font-size: var(--t-xs); font-family: inherit;
}
.pe-in:hover { border-color: var(--c-border); }
.pe-in:focus { border-color: var(--c-accent); background: var(--c-bg); outline: none; }
select.pe-in { height: 30px; }
.pe-in-code { font-family: var(--t-mono); font-size: var(--t-2xs); min-width: 168px; }
.pe-in-num { text-align: right; font-variant-numeric: tabular-nums; width: 76px; min-width: 76px; }
.pe-table-narrow .pe-in { min-width: 0; }
.pe-table-narrow .pe-in-code { min-width: 0; }
.pe-scroll { margin-top: var(--s-2); }

.pe-row-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; margin-top: var(--s-4); }
.pe-row-actions .field-hint { margin: 0; }

/* Awards: each one is a card, because an award is a rule with a list of typed
   effects hanging off it and a row in a table cannot hold that. */
.pe-awards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: var(--s-5); }
.pe-award-top { display: flex; align-items: center; gap: var(--s-3); }
.pe-award-label { font-weight: var(--t-semibold); font-size: var(--t-sm); }
.pe-award-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 130px), 1fr)); gap: var(--s-3); margin-top: var(--s-4); }
.pe-cell { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
.pe-cell-label { font-size: var(--t-2xs); color: var(--c-text-3); }
.pe-effects { margin-top: var(--s-5); border-top: var(--bw) solid var(--c-border); padding-top: var(--s-4); display: flex; flex-direction: column; gap: var(--s-2); align-items: flex-start; }
.pe-effects-head { font-size: var(--t-2xs); text-transform: uppercase; letter-spacing: .06em; color: var(--c-text-3); }
.pe-effect { display: flex; gap: var(--s-2); align-items: center; width: 100%; min-width: 0; }
.pe-effect > select.pe-in { flex: 0 0 150px; }
.pe-effect-args { flex: 1 1 auto; font-family: var(--t-mono); font-size: var(--t-2xs); }

.pe-json {
  width: 100%; font-family: var(--t-mono); font-size: var(--t-2xs); line-height: 1.6;
  border: var(--bw) solid var(--c-border); border-radius: var(--r-md);
  background: var(--c-bg); color: var(--c-text); padding: var(--s-4); resize: vertical;
}
.pe-json-status[data-tone="bad"] { color: var(--c-danger); }
.pe-json-status[data-tone="good"] { color: var(--c-success); }

/* The publish dialog's diff. */
.pe-publish-diff { display: flex; flex-direction: column; gap: var(--s-4); max-height: 42vh; overflow: auto; }
.pe-publish-sec-head { display: flex; gap: var(--s-3); align-items: center; font-size: var(--t-xs); font-weight: var(--t-semibold); text-transform: capitalize; }
.pe-publish-count { font-family: var(--t-mono); font-size: var(--t-2xs); color: var(--c-text-3); }
.pe-publish-sec ul { margin: var(--s-2) 0 0; padding-left: var(--s-6); font-size: var(--t-2xs); color: var(--c-text-2); line-height: 1.8; }
.pe-publish-sec code { font-size: var(--t-2xs); color: var(--c-text-3); }
.pe-publish-sec svg { width: 12px; height: 12px; vertical-align: -1px; color: var(--c-text-3); }
.pe-was { color: var(--c-text-3); text-decoration: line-through; }
.pe-now { color: var(--c-text); font-weight: var(--t-medium); }

/* ============================================================== policy viewer

   The version list and the key level diff. */
.pv-versions { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-2); }
.pv-version {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--s-3) var(--s-4);
  align-items: baseline; padding: var(--s-4) var(--s-5);
  border: var(--bw) solid var(--c-border); border-radius: var(--r-md); background: var(--c-surface);
}
.pv-version[data-active="1"] { border-color: var(--c-accent); background: var(--c-accent-quiet); }
.pv-num { font-family: var(--t-mono); font-weight: var(--t-semibold); font-size: var(--t-sm); }
.pv-note { font-size: var(--t-xs); color: var(--c-text-2); line-height: var(--t-body); overflow-wrap: anywhere; }
.pv-meta { font-size: var(--t-2xs); color: var(--c-text-3); display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-1); }
.pv-picker { display: flex; flex-wrap: wrap; gap: var(--s-4); align-items: flex-end; margin: var(--s-7) 0 var(--s-5); }
.pv-picker label { display: flex; flex-direction: column; gap: var(--s-1); font-size: var(--t-2xs); color: var(--c-text-3); }
.pv-picker select { min-width: 190px; }

.pv-diffhost { margin-top: var(--s-5); display: flex; flex-direction: column; gap: var(--s-4); }
.pv-section { border: var(--bw) solid var(--c-border); border-radius: var(--r-md); background: var(--c-surface); }
.pv-section > summary { padding: var(--s-4) var(--s-5); cursor: pointer; font-size: var(--t-sm); display: flex; gap: var(--s-3); align-items: baseline; text-transform: capitalize; }
.pv-section > summary::-webkit-details-marker { display: none; }
.pv-section[open] > summary { border-bottom: var(--bw) solid var(--c-border); }
.pv-section .scroll-x-wrap { padding: 0 var(--s-2) var(--s-2); }

.pv-diff { width: 100%; }
.pv-diff td, .pv-diff th { vertical-align: top; }
.pv-path { font-family: var(--t-mono); font-size: var(--t-2xs); overflow-wrap: anywhere; color: var(--c-text-2); }
.pv-val { font-family: var(--t-mono); font-size: var(--t-2xs); overflow-wrap: anywhere; }
.pv-val[data-side="before"] { color: var(--c-text-3); }
/* The diff's added / removed / changed marker. It was drawing --c-success at
   10px, which measures 4.39:1 against the paper and 3.86:1 on the dark ground:
   both under the 4.5:1 floor, and this is the one word in the row that carries
   the meaning. Semibold at the same size crosses it without a new colour, and
   uppercase at this size needs the weight anyway. */
.pv-kind { font-size: var(--t-2xs); text-transform: uppercase; letter-spacing: .05em;
           font-weight: var(--t-semibold); }
/* Mixed toward the ink. The bare status colours are tuned for a chip at body
   size and measure 4.39:1 at 10px, just under the floor; a fifth of the text
   colour carries them over it and the three stay tellable apart. */
.pv-kind[data-kind="added"] { color: color-mix(in srgb, var(--c-success) 78%, var(--c-text)); }
.pv-kind[data-kind="removed"] { color: color-mix(in srgb, var(--c-danger) 78%, var(--c-text)); }
.pv-kind[data-kind="changed"] { color: color-mix(in srgb, var(--c-warn) 78%, var(--c-text)); }

/* ================================================================ mail screen */
.ml-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: var(--s-5); margin-bottom: var(--s-6); }
.ml-conn .card-body { display: flex; flex-direction: column; gap: var(--s-4); }
.ml-state { display: flex; align-items: center; gap: var(--s-3); }
.ml-state-dot { width: 9px; height: 9px; border-radius: var(--r-full); background: var(--c-text-3); flex: none; }
.ml-state[data-state="sending"] .ml-state-dot { background: var(--c-success); }
.ml-state[data-state="holding"] .ml-state-dot,
.ml-state[data-state="unknown"] .ml-state-dot { background: var(--c-warn); }
.ml-state[data-state="none"] .ml-state-dot { background: var(--c-danger); }
.ml-state-title { font-weight: var(--t-semibold); font-size: var(--t-sm); }
.ml-state-body { font-size: var(--t-xs); color: var(--c-text-2); line-height: var(--t-body); margin: 0; }

.ml-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--s-2) var(--s-5); font-size: var(--t-xs); margin: 0; }
.ml-facts dt { color: var(--c-text-3); }
.ml-facts dd { margin: 0; min-width: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.ml-facts code { font-size: var(--t-2xs); }
.ml-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); }

.ml-secret { display: flex; gap: var(--s-3); align-items: flex-start; font-size: var(--t-2xs); color: var(--c-text-3); line-height: var(--t-body); }
.ml-secret svg { width: 13px; height: 13px; flex: none; margin-top: 2px; }

.ml-counts { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: var(--s-4); }
.ml-count { display: flex; flex-direction: column; gap: var(--s-1); }
.ml-count-value { font-size: var(--t-xl); font-weight: var(--t-semibold); font-variant-numeric: tabular-nums; line-height: 1; }
.ml-count-value[data-tone="bad"] { color: var(--c-danger); }
.ml-count-value[data-tone="warn"] { color: var(--c-warn); }
.ml-count-label { font-size: var(--t-2xs); color: var(--c-text-3); }

.ml-routes td { vertical-align: middle; }
.ml-route-code { font-family: var(--t-mono); font-size: var(--t-2xs); }
.ml-route-desc { font-size: var(--t-2xs); color: var(--c-text-3); line-height: var(--t-body); max-width: 46ch; }
/* An identifier never wraps. The first screenshot of this table broke
   `candidate.created` across two lines as "candidate.create" and "d", which
   turns a name somebody has to recognise into two things that are not it. The
   table already lives in a horizontal scroller, so width is available and
   legibility is not a thing to trade for it. */
.ml-cond { font-family: var(--t-mono); font-size: var(--t-2xs); color: var(--c-text-2); white-space: nowrap; }
/* Conditions are the exception: a merge of several paths is genuinely long and
   is read rather than recognised, so it wraps inside its own column. */
.ml-routes td:nth-child(5) .ml-cond { white-space: normal; overflow-wrap: anywhere; max-width: 32ch; display: inline-block; }
.ml-tags { display: flex; flex-wrap: wrap; gap: var(--s-1); max-width: 34ch; }
.ml-tag { font-family: var(--t-mono); font-size: 10px; padding: 1px var(--s-2); border-radius: var(--r-sm); background: var(--c-surface-3); color: var(--c-text-2); }

/* The switch. A checkbox rather than a button because it reports its own state
   to a screen reader without any extra wiring. */
.ml-switch { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--t-2xs); color: var(--c-text); cursor: pointer; }

.ml-preview { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: var(--s-6); align-items: start; }
@media (max-width: 900px) { .ml-preview { grid-template-columns: 1fr; } }
.ml-preview-form { display: flex; flex-direction: column; gap: var(--s-4); }
.ml-preview-json { width: 100%; font-family: var(--t-mono); font-size: var(--t-2xs); border: var(--bw) solid var(--c-border); border-radius: var(--r-md); background: var(--c-bg); color: var(--c-text); padding: var(--s-4); resize: vertical; line-height: 1.6; }
.ml-preview-out { min-width: 0; display: flex; flex-direction: column; gap: var(--s-4); }
.ml-fire { border: var(--bw) solid var(--c-border); border-radius: var(--r-md); padding: var(--s-4) var(--s-5); background: var(--c-surface); }
.ml-fire[data-fired="1"] { border-color: var(--c-success); }
.ml-fire-head { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; }
.ml-fire-code { font-family: var(--t-mono); font-size: var(--t-xs); font-weight: var(--t-semibold); }
.ml-fire-why { font-size: var(--t-2xs); color: var(--c-text-3); }
.ml-merge { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--s-1) var(--s-4); margin: var(--s-3) 0 0; font-size: var(--t-2xs); }
.ml-merge dt { font-family: var(--t-mono); color: var(--c-text-3); }
.ml-merge dd { margin: 0; overflow-wrap: anywhere; }
.ml-key { font-family: var(--t-mono); font-size: 10px; color: var(--c-text-3); overflow-wrap: anywhere; display: block; margin-top: var(--s-2); }

.ml-status { font-size: var(--t-2xs); text-transform: uppercase; letter-spacing: .05em; }
/* Mixed toward the ink, the same reason as the diff marker above: the bare
   status colours are tuned for a chip at body size and fall just under the
   floor at 10px. */
.ml-status[data-s="delivered"] { color: color-mix(in srgb, var(--c-success) 78%, var(--c-text)); }
.ml-status[data-s="pending"] { color: color-mix(in srgb, var(--c-warn) 78%, var(--c-text)); }
.ml-status[data-s="dead"] { color: color-mix(in srgb, var(--c-danger) 78%, var(--c-text)); }
.ml-err { font-size: var(--t-2xs); color: var(--c-text-2); max-width: 46ch; overflow-wrap: anywhere; line-height: var(--t-body); }
.ml-mono { font-family: var(--t-mono); font-size: var(--t-2xs); color: var(--c-text-2); overflow-wrap: anywhere; }

/* A checkbox is 13px of ink in a 22px box, which the audit measures against a
   32px floor for a control a finger has to hit. The ink stays a checkbox; the
   box around it becomes the target. */
/* 32px, which is the floor for a control a finger has to hit, and this one
   switches a whole category of mail on and off. A checkbox the browser sizes
   for a mouse is 13px of ink in a 22px box. */
.ml-switch input[type="checkbox"] { width: 32px; height: 32px; accent-color: var(--c-accent); }
.ml-switch { min-height: 32px; }
