/* Master Files page (pages/masterfiles.js). Tokens only — lint_css.js rejects any colour literal here.
   Reuses .card / .btn / .badge / .finput / .flabel / .minitable from styles.css; everything else is mf-*. */
.mf-wrap{max-width:1180px;margin:0 auto}

/* header strip */
.mf-header-strip{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:var(--sp-3);margin-bottom:var(--sp-4)}
.mf-header-strip h2{font-size:22px;font-weight:800;color:var(--brand);margin:0 0 4px 0;display:flex;align-items:center;gap:var(--sp-2)}
.mf-header-badges{display:flex;gap:var(--sp-2);flex-wrap:wrap}

/* upload card & hero dropzone */
.mf-upload-card{margin-bottom:var(--sp-5);padding:var(--sp-4)}
.mf-drop{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-3);text-align:center;
  padding:var(--sp-8) var(--sp-6);border:2px dashed var(--line-strong);border-radius:var(--r-xl);background:var(--surface);cursor:pointer;
  box-shadow:var(--sh-1);transition:all var(--dur-fast) var(--ease);min-height:300px}
.mf-drop:hover,.mf-drop:focus-visible{border-color:var(--info-vivid);background:var(--info-wash);box-shadow:0 8px 24px rgba(var(--brand-rgb),0.08);outline:none}
.mf-drop:focus-visible{box-shadow:0 0 0 3px var(--info-line)}
.mf-drop.is-over{border-style:solid;border-color:var(--accent);background:var(--accent-soft);box-shadow:var(--sh-2)}
.mf-drop-ico{width:64px;height:64px;border-radius:18px;background:var(--surface-2);border:1px solid var(--line);box-shadow:var(--sh-1);
  display:flex;align-items:center;justify-content:center;color:var(--info);margin-bottom:var(--sp-1)}
.mf-drop.is-over .mf-drop-ico{background:var(--accent-soft);color:var(--accent-strong)}
.mf-drop-title{font-size:22px;font-weight:800;color:var(--brand)}
.mf-drop-subtitle{font-size:var(--fs-md);color:var(--ink-muted)}
.mf-format-pills{display:flex;gap:var(--sp-2);flex-wrap:wrap;justify-content:center;margin:var(--sp-2) 0}
.mf-format-pill{font-size:var(--fs-xs);font-weight:800;padding:3px 10px;border-radius:var(--r-pill);background:var(--surface-3);color:var(--ink);border:1px solid var(--line-strong)}
.mf-drop-features{display:flex;gap:var(--sp-3);flex-wrap:wrap;justify-content:center;margin:var(--sp-2) 0;font-size:var(--fs-xs);color:var(--ink-faint);font-weight:600}
.mf-feature-tag{display:inline-flex;align-items:center;gap:4px}
.mf-drop-actions{margin-top:var(--sp-3)}

/* spinner — the only motion on the page; tokens.css zeroes it under prefers-reduced-motion */
.mf-spin{width:28px;height:28px;flex:none;border:3px solid var(--line);border-top-color:var(--info-vivid);border-radius:50%;animation:mf-spin .9s linear infinite}
.mf-spin--sm{width:16px;height:16px;border-width:2px}
@keyframes mf-spin{to{transform:rotate(360deg)}}
.mf-busy{display:flex;align-items:center;gap:var(--sp-4);font-weight:600;color:var(--ink)}
.mf-busy-inline{display:flex;align-items:center;gap:var(--sp-2);margin:var(--sp-3) 0;font-size:var(--fs-md);color:var(--ink-muted)}

/* notices */
.mf-note{padding:var(--sp-3) var(--sp-4);border-radius:var(--r-md);border:1px solid var(--line);background:var(--surface-2);
  font-size:var(--fs-md);line-height:1.55;margin:0 0 var(--sp-4);color:var(--ink)}
.mf-note--warn{background:var(--warn-wash);border-color:var(--warn-line);color:var(--warn)}
.mf-note--danger{background:var(--danger-wash);border-color:var(--danger-line);color:var(--danger)}
.mf-note--ok{background:var(--ok-soft);border-color:var(--ok-line);color:var(--ok)}
.mf-note--info{background:var(--info-wash);border-color:var(--info-line);color:var(--info)}
.mf-note b{font-weight:800}
.mf-list{margin:var(--sp-2) 0 0;padding-left:var(--sp-5);line-height:1.55}
.mf-list li{margin:2px 0}
.mf-list--danger{color:var(--danger)}
.mf-list--warn{color:var(--warn)}

/* chips, holds, meta rows */
.mf-filemeta,.mf-chips,.mf-curr,.mf-cands{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:0 0 var(--sp-4)}
.mf-curr{margin:var(--sp-2) 0 0}
.mf-cands{margin:var(--sp-3) 0 0}
.mf-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:var(--r-pill);background:var(--surface-3);border:1px solid var(--line);
  font-size:var(--fs-sm);font-weight:600;color:var(--ink);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mf-chip-k{color:var(--ink-muted);font-weight:700;text-transform:uppercase;letter-spacing:.04em;font-size:var(--fs-xs)}
.mf-holds{display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--sp-2) var(--sp-3);align-items:center;margin:0 0 var(--sp-4);
  padding:var(--sp-3) var(--sp-4);border-radius:var(--r-md);background:var(--warn-wash);border:1px solid var(--warn-line)}
.mf-hold-text{font-size:var(--fs-md);color:var(--warn);line-height:1.45}
.mf-evidence{margin:0 0 var(--sp-4);border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface-2);padding:var(--sp-2) var(--sp-4)}
.mf-evidence>summary{cursor:pointer;font-size:var(--fs-md);font-weight:600;color:var(--ink);padding:var(--sp-1) 0}
.mf-evidence[open]>summary{margin-bottom:var(--sp-2)}

/* form grid */
.mf-sub{margin:var(--sp-5) 0 var(--sp-3);font-size:var(--fs-sm);font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-muted);
  display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.mf-sub>svg.ic{color:var(--ink-faint)}
.mf-sub .muted{text-transform:none;letter-spacing:0;font-weight:500;margin-left:var(--sp-2)}
.mf-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:var(--sp-4) var(--sp-4);margin-bottom:var(--sp-3)}
.mf-grid--pricing{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.mf-field{min-width:0;display:flex;flex-direction:column}
.mf-field--wide{grid-column:1/-1}
.mf-field .finput{background:var(--surface)}
.mf-fhint{display:block;margin-top:var(--sp-1);font-size:var(--fs-xs);color:var(--ink-faint);line-height:1.4}
/* A seasonal brand's two rates under the factor, the one in use marked (MF7) */
.mf-rates{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.mf-rate{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:var(--r-pill);border:1px solid var(--line);background:var(--surface-2);color:var(--ink-muted)}
.mf-rate.is-in-use{border-color:var(--ok-line);background:var(--ok-soft);color:var(--ink)}
.mf-rate .badge{font-size:var(--fs-xs)}
.mf-mono{font-family:var(--font-mono);letter-spacing:.02em}
.mf-hint{margin:var(--sp-2) 0 0;line-height:1.5}
.mf-derive{margin:0 0 var(--sp-2);padding:var(--sp-2) var(--sp-3);border-radius:var(--r-sm);background:var(--info-wash);border:1px solid var(--info-line);
  color:var(--info);font-size:var(--fs-md);line-height:1.5}
.mf-example{font-family:var(--font-mono);font-size:var(--fs-base);font-weight:600;color:var(--ok);padding:var(--sp-3) var(--sp-4);
  border-radius:var(--r-md);background:var(--ok-soft);border:1px solid var(--ok-line);line-height:1.5;word-break:break-word}
.mf-example.is-bad{color:var(--danger);background:var(--danger-wash);border-color:var(--danger-line)}
.mf-depts{margin-bottom:var(--sp-2)}
.mf-depts td{vertical-align:middle}
.mf-depts .finput{padding:7px 10px;min-width:120px}
.mf-dept-ex{font-family:var(--font-mono);white-space:nowrap}
.mf-dept-ex.is-bad{color:var(--danger)}
.finput[aria-invalid="true"]{border-color:var(--danger-vivid)}

/* preview */
.mf-preview{max-height:320px;overflow:auto;margin-bottom:var(--sp-2)}
.mf-preview table{min-width:max-content}
.mf-preview td{white-space:nowrap;max-width:260px;overflow:hidden;text-overflow:ellipsis;font-size:var(--fs-sm)}

/* actions */
.mf-actions{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin-top:var(--sp-5);padding-top:var(--sp-4);border-top:1px solid var(--line)}
.mf-actions-gap{flex:1}
.mf-actions .btn[disabled]{opacity:.55;cursor:progress;transform:none}

/* stage timeline */
.mf-stages{list-style:none;margin:var(--sp-2) 0 var(--sp-4);padding:0;display:flex;flex-wrap:wrap;gap:var(--sp-2) 0}
.mf-stage{position:relative;display:flex;align-items:center;gap:6px;padding:6px 14px 6px 0;font-size:var(--fs-sm);font-weight:600;color:var(--ink-faint)}
.mf-stage::after{content:"";width:14px;height:1px;background:var(--line-strong);margin-left:6px}
.mf-stage:last-child::after{display:none}
.mf-stage-dot{width:12px;height:12px;border-radius:50%;border:2px solid var(--line-strong);background:var(--surface);flex:none}
.mf-stage.is-done{color:var(--ink)}
.mf-stage.is-done .mf-stage-dot{background:var(--ok-vivid);border-color:var(--ok-vivid)}
.mf-stage.is-cur{color:var(--info-strong)}
.mf-stage.is-cur .mf-stage-dot{background:var(--surface);border-color:var(--info-vivid);box-shadow:0 0 0 4px var(--info-soft)}
.mf-stage.is-held{color:var(--warn)}
.mf-stage.is-held .mf-stage-dot{background:var(--warn-vivid);border-color:var(--warn-vivid);box-shadow:0 0 0 4px var(--warn-soft)}
.mf-stage.is-failed,.mf-stage.is-cancelled{color:var(--danger)}
.mf-stage.is-failed .mf-stage-dot,.mf-stage.is-cancelled .mf-stage-dot{background:var(--danger-vivid);border-color:var(--danger-vivid);box-shadow:0 0 0 4px var(--danger-soft)}

/* log */
.mf-log{max-height:260px;overflow:auto;padding:var(--sp-3) var(--sp-4);border-radius:var(--r-md);background:var(--brand);color:var(--on-dark-muted);
  font-family:var(--font-mono);font-size:var(--fs-sm);line-height:1.6}
.mf-log:focus-visible{outline:2px solid var(--info-vivid);outline-offset:2px}
.mf-logline{display:flex;gap:var(--sp-3);align-items:baseline}
.mf-logt{flex:none;color:var(--ink-faint);font-variant-numeric:tabular-nums}

/* results */
.mf-rgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--sp-4);margin-bottom:var(--sp-2)}
.mf-panel{border:1px solid var(--line);border-radius:var(--r-lg);padding:var(--sp-4);background:var(--surface-2);min-width:0}
.mf-panel h4{margin:0 0 var(--sp-3);font-size:var(--fs-sm);font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-muted)}
.mf-panel-h{font-weight:800;font-size:var(--fs-sm);margin-top:var(--sp-3)}
.mf-danger{color:var(--danger)} .mf-warn{color:var(--warn)}
.mf-ok{color:var(--ok);font-weight:600;margin:0;font-size:var(--fs-md)}
.mf-kv{display:flex;gap:var(--sp-4);flex-wrap:wrap;margin-bottom:var(--sp-2)}
.mf-kv-i{display:flex;flex-direction:column}
.mf-kv-k{font-size:var(--fs-xs);font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-muted)}
.mf-kv-v{font-size:var(--fs-xl);font-weight:800;color:var(--brand);line-height:1.2}
.mf-coll{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);padding:var(--sp-3);border-radius:var(--r-md);font-size:var(--fs-md);line-height:1.5}
.mf-coll--ok{background:var(--ok-soft);border:1px solid var(--ok-line);color:var(--ok)}
.mf-coll--bad{background:var(--danger-wash);border:1px solid var(--danger-line);color:var(--danger)}
.mf-coll p{flex-basis:100%;margin:0}
.mf-split{display:flex;flex-direction:column;gap:var(--sp-2)}
.mf-split-i{display:grid;grid-template-columns:64px minmax(0,1fr);gap:0 var(--sp-3);align-items:center;padding:var(--sp-2) var(--sp-3);border-radius:var(--r-md);
  border:1px solid var(--line);border-left-width:4px;background:var(--surface)}
.mf-split-i--good{border-left-color:var(--ok-vivid)} .mf-split-i--info{border-left-color:var(--info-vivid)} .mf-split-i--critical{border-left-color:var(--danger-vivid)}
.mf-split-n{grid-row:span 2;font-size:var(--fs-xl);font-weight:800;color:var(--brand);font-variant-numeric:tabular-nums}
.mf-split-l{font-weight:700;font-size:var(--fs-md)}
.mf-downloads{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.mf-downloads li{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.mf-downloads .btn.is-busy{opacity:.6;cursor:progress}
.mf-dl-kind{font-size:var(--fs-sm);color:var(--ink-muted);display:inline-flex;align-items:center;gap:6px}

/* history */
.mf-history .card-h{align-items:center}
.mf-histrow{cursor:pointer}
.mf-histrow.is-cur td{background:var(--info-wash)}
.mf-histrow:focus-visible{outline:2px solid var(--info-vivid);outline-offset:-2px}
.mf-histerr{font-size:var(--fs-xs);color:var(--danger);margin-top:2px;max-width:420px;white-space:normal}

@media(max-width:640px){
  .mf-drop{padding:var(--sp-6) var(--sp-4)}
  .mf-grid,.mf-grid--pricing{grid-template-columns:1fr}
  .mf-holds{grid-template-columns:1fr;gap:var(--sp-1)}
  .mf-kv-v{font-size:var(--fs-lg)}
  .mf-stage{padding-right:8px}
  .mf-stage::after{width:6px;margin-left:2px}
  .mf-actions .btn{flex:1 1 auto;justify-content:center}
  .mf-actions-gap{display:none}
  .mf-downloads li{flex-direction:column;align-items:flex-start}
}

/* --- browse tabs (Files / Gaps / History) ------------------------------------------------------
   Deliberately thin: the tab strip reuses .segmented/.seg/.seg-n from styles.css, the counters reuse
   .mf-kv, the gap rows reuse .mf-split, and the tables reuse .minitable + .mf-histrow. */
.mf-tabs{margin:var(--sp-3) 0}
.segmented .seg--warn .seg-n{color:var(--warn)}
.segmented .seg.on.seg--warn .seg-n{color:var(--on-dark)}
.mf-browse-filters{display:flex;gap:var(--sp-3);align-items:flex-end;flex-wrap:wrap;margin:var(--sp-3) 0 var(--sp-2)}
.mf-browse-count{margin:0 0 var(--sp-2)}
.mf-browse-page{margin-top:var(--sp-3)}
.mf-filerow .mf-mono{font-size:var(--fs-xs);word-break:break-all}
.mf-split-i--warn{border-left-color:var(--warn-vivid)}
.mf-split-i{grid-template-columns:64px minmax(0,1fr) auto}
.mf-split-a{justify-self:end}
.mf-histrow.is-ledger{cursor:default}
/* The role strip is five pills wide (463px) and the brand select carries long folder names, so both
   overflow a 375px phone. Per the house rule, wide content scrolls INSIDE its own container -- the
   page body must never scroll sideways. .segmented keeps overflow:hidden for its rounded ends, so
   the scroller has to be a wrapper around it, not the strip itself. */
.mf-segscroll{max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
.mf-segscroll .segmented{width:max-content}
.mf-browse-filters .mf-field{min-width:0;max-width:100%}
.mf-browse-filters .finput{max-width:100%}
@media(max-width:640px){
  .mf-browse-filters{flex-direction:column;align-items:stretch}
  .mf-browse-filters .mf-field,.mf-browse-filters .mf-field--wide{width:100%}
  .mf-split-i{grid-template-columns:48px minmax(0,1fr)}
  .mf-split-a{grid-column:1/-1;justify-self:start;margin-top:var(--sp-1)}
  .mf-filerow .mf-mono{max-width:52vw}
}

/* --- stop-and-ask gates ------------------------------------------------------------------------
   Each row is a question with its consequence underneath. Unanswered rows carry a danger edge and
   the tick is empty; answering flips the edge to ok. There is no "accept all" control, by design. */
.mf-gates{display:flex;flex-direction:column;gap:var(--sp-1);margin:var(--sp-2) 0 var(--sp-4)}
.mf-gate{display:grid;grid-template-columns:28px minmax(0,1fr);gap:var(--sp-3);align-items:start;
  padding:var(--sp-2) var(--sp-3);border-radius:var(--r-md);background:var(--surface-2);
  border-left:3px solid var(--danger-vivid)}
.mf-gate.is-acked{border-left-color:var(--ok-vivid);background:var(--surface)}
.mf-gate--changed{background:var(--warn-wash)}
.mf-gate-ack{width:24px;height:24px;border-radius:50%;border:2px solid var(--line);background:var(--surface);
  cursor:pointer;font-size:14px;font-weight:800;line-height:1;color:var(--ok);padding:0;
  display:flex;align-items:center;justify-content:center}
.mf-gate.is-acked .mf-gate-ack{border-color:var(--ok-vivid);background:var(--ok-soft)}
.mf-gate-ack:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.mf-gate-h{display:flex;gap:var(--sp-2);align-items:baseline;flex-wrap:wrap}
.mf-gate-v{font-weight:700;color:var(--brand);font-size:var(--fs-sm)}
.mf-gate-src{font-size:var(--fs-xs);color:var(--ink-muted)}
.mf-gate-why{font-size:var(--fs-xs);color:var(--ink-muted);margin-top:2px;line-height:1.45}
@media(max-width:640px){
  .mf-gate{grid-template-columns:24px minmax(0,1fr);gap:var(--sp-2)}
  .mf-gate-h{gap:var(--sp-1)}
}

/* Breadcrumb back to the set of brands a drop produced. Tokens only. */
.mf-crumb { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.mf-crumb .muted { font-size: var(--fs-sm); }

/* One design, one price — design families (erp/masterfiles/families.py).
   Reuses .mf-gate-ack for the tick so a family member reads as the same kind of decision as a gate. */
.mf-fams{display:flex;flex-direction:column;gap:10px;margin:8px 0 4px}
.mf-fam{border:1px solid var(--line);border-radius:10px;padding:10px 12px;background:var(--surface-2)}
.mf-fam.is-on{background:var(--surface);border-color:var(--ok-vivid)}
.mf-fam-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:6px}
.mf-fam-f{margin-top:6px;font-size:12.5px}
.mf-fam .minitable table{margin:0}
.mf-fam-tick{width:20px;height:20px;font-size:11px}
/* An unticked member is still legible — it is a choice on offer, not disabled furniture. */
.mf-fam tr.is-off td{opacity:.55}

/* The stage flow and the approval summary (erp/masterfiles/approval.py).
   Seven numbered steps, each saying what it decided — not a dot strip with engine stage names. */
.mf-flow{list-style:none;margin:8px 0 4px;padding:0;display:flex;flex-direction:column;gap:6px}
.mf-flow-s{display:flex;gap:10px;align-items:flex-start;padding:8px 10px;border-radius:10px;
  border:1px solid var(--line);background:var(--surface-2)}
.mf-flow-s.is-active{background:var(--surface);border-color:var(--brand);box-shadow:var(--shadow)}
.mf-flow-s.is-blocked{border-color:var(--danger-vivid)}
/* A step not reached yet is legible but plainly not the thing to read now. */
.mf-flow-s.is-waiting,.mf-flow-s.is-skipped{opacity:.5}
.mf-flow-n{flex:0 0 auto;width:20px;height:20px;border-radius:50%;display:inline-flex;
  align-items:center;justify-content:center;font-size:11px;background:var(--surface);
  border:1px solid var(--line);font-variant-numeric:tabular-nums}
.mf-flow-s.is-done .mf-flow-n{background:var(--ok-soft);border-color:var(--ok-vivid)}
.mf-flow-s.is-blocked .mf-flow-n{background:var(--danger-soft);border-color:var(--danger-vivid)}
.mf-flow-b{min-width:0;flex:1}
.mf-flow-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.mf-flow-st{text-transform:none}
.mf-flow-d{font-size:12.5px;margin-top:2px}
.mf-flow-cases{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}

.mf-costsrc{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0 10px}

/* One box per sampled row: everything needed to check that row by hand, and nothing else. */
.mf-samples{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:8px;margin:8px 0}
.mf-sample{border:1px solid var(--line);border-radius:10px;padding:9px 10px;background:var(--surface-2)}
.mf-sample.is-flagged{border-color:var(--danger-vivid)}
.mf-sample-h{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.mf-sample-d{font-size:12px;color:var(--ink-muted);margin:2px 0 6px}
.mf-sample-k{display:flex;align-items:baseline;gap:6px;font-size:12px;
  border-top:1px solid var(--line);padding:3px 0}
.mf-sample-k span:first-child{flex:0 0 62px;color:var(--ink-muted)}
.mf-sample-k b{font-variant-numeric:tabular-nums}
.mf-sample-f{margin-top:6px}

.mf-approve{margin-top:14px;padding:12px;border-radius:10px;border:1px solid var(--line);
  background:var(--surface-2);display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.mf-approve-l{flex:0 0 auto;font-size:12.5px}
.mf-approve .finput{flex:1 1 220px}
.mf-approve .mf-hint{flex:1 1 100%;margin:0}

/* ── The phase bar: five phases for the whole drop ──────────────────────────────────────────────
   "on top active bar number of phases and next to check files, answers, prepare" (owner 2026-09-10).
   Folded server-side by approval.drop_phases(); this only paints it.

   Token scale throughout (--sp-N / --r-* / --fs-*), matching the first two-thirds of this file. The
   newer blocks below it drifted to raw pixels; nothing new should. No new colours either — the
   states reuse the semantic ramps, because the Overview redesign already established that the fix
   for "everything at one weight" is hierarchy, not more hues. */
.mf-phase{padding:var(--sp-4) var(--sp-5);margin-bottom:var(--sp-4)}
.mf-phase-h{display:flex;align-items:baseline;gap:var(--sp-3);margin-bottom:var(--sp-3);font-size:var(--fs-sm)}
.mf-phases{list-style:none;display:flex;gap:var(--sp-2);margin:0;padding:0;flex-wrap:wrap}
.mf-ph{flex:1 1 128px;min-width:118px;display:flex;flex-direction:column;gap:2px;
  padding:var(--sp-3) var(--sp-4);border-radius:var(--r-md);background:var(--surface-2);
  border:1px solid var(--line);border-top:3px solid var(--line)}
.mf-ph-n{font-size:var(--fs-xs);color:var(--ink-muted);font-variant-numeric:tabular-nums}
.mf-ph-l{font-weight:600;font-size:var(--fs-sm);display:flex;align-items:center;gap:6px}
.mf-ph-l>svg.ic{color:var(--ink-faint)}
.mf-ph.is-active .mf-ph-l>svg.ic{color:var(--brand)}
.mf-ph.is-done .mf-ph-l>svg.ic{color:var(--ok)}
/* the per-phase meter: how much of the drop has cleared this step */
.mf-ph-bar{height:4px;margin-top:4px}
.mf-ph.is-done .mf-ph-bar>i{background:var(--ok-vivid)}
.mf-ph.has-attention .mf-ph-bar>i{background:var(--accent)}
.mf-ph-c{font-size:var(--fs-xs);color:var(--ink-muted);font-variant-numeric:tabular-nums}

/* Done is quiet on purpose: finished work should not compete with the phase that needs a person. */
.mf-ph.is-done{border-top-color:var(--ok-vivid);opacity:.72}
.mf-ph.is-done .mf-ph-c{color:var(--ok)}
.mf-ph.is-active{background:var(--surface);border-top-color:var(--brand);box-shadow:var(--sh-1)}
.mf-ph.is-blocked{border-top-color:var(--danger-vivid);background:var(--danger-wash)}
.mf-ph.is-waiting,.mf-ph.is-skipped{opacity:.5}
/* The one thing on the bar that is a call to action, so it gets the only strong colour. */
.mf-ph.has-attention{border-top-color:var(--warn-vivid);background:var(--warn-wash)}
.mf-ph.has-attention .mf-ph-c{color:var(--warn);font-weight:600}

@media (max-width:640px){
  .mf-phases{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch}
  .mf-ph{flex:0 0 auto;min-width:104px}
}

/* The drop's file list. The whole row is the control — it used to carry a warn pill reading
   "Confirm" beside a separate "Open" button, which is two affordances for one action, and the pill
   looked more like the button than the button did. */
.mf-droprow{cursor:pointer}
.mf-droprow:hover{background:var(--surface-2)}
.mf-droprow:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}

/* ── Gate bands ────────────────────────────────────────────────────────────────────────────────
   Eighteen questions at one weight is what made this card unreadable: the one broken value looked
   exactly like the seventeen routine ones. EVERY GATE STILL HAS ITS OWN TICK — the owner was
   offered fewer and declined — so the whole fix is hierarchy.
   Native <details>, so there is no new state to lose on a repaint and no JS to go wrong. */
.mf-band{border:1px solid var(--line);border-radius:var(--r-md);margin-bottom:var(--sp-3);
  background:var(--surface-2);overflow:hidden}
.mf-band--flat{padding:var(--sp-2)}
.mf-band-h{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;cursor:pointer;
  padding:var(--sp-3) var(--sp-4);font-size:var(--fs-sm);list-style:none}
.mf-band-h::-webkit-details-marker{display:none}
.mf-band-h::before{content:"▸";display:inline-block;width:.8em;color:var(--ink-muted);transition:transform var(--dur) var(--ease)}
.mf-band[open] > .mf-band-h::before{transform:rotate(90deg)}
.mf-band-h:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
.mf-band-n{margin-left:auto;color:var(--ink-muted);font-variant-numeric:tabular-nums;font-size:var(--fs-xs)}
.mf-band > .mf-gate{margin:0 var(--sp-3) var(--sp-3)}
.mf-band--flat > .mf-gate{margin:0}

/* A gate with no value, and a gate whose DISPLAY is a hole punched by one. These are the only two
   states on this card that mean "stop", so they are the only two carrying a strong edge. */
.mf-gate--missing{border-left-color:var(--danger-vivid);background:var(--danger-wash)}
.mf-gate--incomplete{border-left-color:var(--warn-vivid)}

/* The strip above the bands: one sentence per missing value, naming every display it breaks.
   Anchors, never copies — a duplicated gate row would half-update on a tick. */
.mf-needs{margin:0 0 var(--sp-4)}
.mf-needs-i{display:flex;align-items:baseline;gap:var(--sp-3);flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-4);border-radius:var(--r-md);
  background:var(--danger-wash);border:1px solid var(--danger-line);font-size:var(--fs-sm)}
.mf-needs-i + .mf-needs-i{margin-top:var(--sp-2)}
.mf-needs-i code{font-family:var(--font-mono);font-size:var(--fs-xs)}
/* A column the file simply does not have. No answer fixes it, so it does not offer a "Set it". */
.mf-needs-i--hard{background:var(--danger-soft)}

/* The item code, as a control rather than a label. Five sanctioned shapes, each rendered against
   this file's own first row, plus what every segment reads from. An item code is permanent, so the
   choice is deliberately a closed set — not a free-form builder. */
.mf-icb{margin-top:var(--sp-3);padding:var(--sp-3);border-radius:var(--r-md);
  background:var(--surface);border:1px solid var(--line)}
.mf-icb-l{display:block;font-size:var(--fs-xs);color:var(--ink-muted);margin-bottom:2px}
.mf-icb-p{margin-top:var(--sp-2);font-size:var(--fs-sm)}
.mf-icb-t{margin-top:var(--sp-3)}
.mf-icb-t tr.is-off td{opacity:.6}

/* --- what is already on the shelf (precheck.stock_lookup) ---------------------------------------------- */
.mf-stock{margin:var(--sp-3) 0;padding:var(--sp-3);border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--surface-2)}
.mf-stock-h{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-md);margin-bottom:var(--sp-2)}
.mf-stock-h .muted{margin-left:auto;font-size:var(--fs-xs)}
.mf-shoprow{display:grid;grid-template-columns:minmax(96px,150px) 1fr auto;align-items:center;gap:var(--sp-3);
  font-size:var(--fs-sm);padding:2px 0}
.mf-shoprow b{font-variant-numeric:tabular-nums}
.mf-stock .mf-hint{margin:var(--sp-2) 0 0}

/* --- row notes, kept by barcode (erp/masterfiles/notes.py) -------------------------------------------- */
.mf-note-row{display:flex;align-items:center;gap:var(--sp-2);margin-top:var(--sp-2);font-size:var(--fs-xs)}
.mf-note-lab{display:inline-flex;align-items:center;gap:4px;color:var(--ink-faint);font-weight:700;
  text-transform:uppercase;letter-spacing:.04em;flex:none}
.mf-note-row.has-note .mf-note-lab{color:var(--accent-strong)}
.mf-note-i{flex:1 1 auto;min-width:0;font-size:var(--fs-sm);padding:4px 8px}
.mf-note-at{flex:none;font-variant-numeric:tabular-nums}

/* --- a file's place in the flow: five-step stepper, state chip, drop nav, verdict ------------------------- */
.mf-stepper{display:inline-flex;gap:4px;align-items:center;vertical-align:middle}
.mf-step{display:inline-block;width:10px;height:10px;border-radius:var(--r-pill);background:var(--line)}
.mf-step.is-done{background:var(--ok-vivid)}
.mf-step.is-now{background:var(--brand);box-shadow:0 0 0 3px var(--info-line)}
.mf-step.is-blocked{background:var(--danger-vivid)}
.mf-status{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:var(--r-pill);
  font-size:var(--fs-xs);font-weight:700;border:1px solid transparent;white-space:nowrap}
.mf-status.is-need,.mf-status.is-warn{background:var(--warn-soft);color:var(--warn);border-color:var(--warn-line)}
.mf-status.is-danger{background:var(--danger-soft);color:var(--danger);border-color:var(--danger-line)}
.mf-status.is-running{background:var(--info-soft);color:var(--info);border-color:var(--info-line)}
.mf-status.is-done{background:var(--ok-soft);color:var(--ok);border-color:var(--ok-line)}
.mf-status.is-muted{background:var(--surface-3);color:var(--ink-muted);border-color:var(--line)}
.mf-drop-counts{margin:0 0 var(--sp-3)}
.mf-droprow{cursor:pointer}
.mf-droprow:hover{background:var(--surface-2)}
.mf-crumb{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-3)}
.mf-verdict{margin:var(--sp-3) 0;padding:var(--sp-3) var(--sp-4);border-radius:var(--r-md);background:var(--surface-2);
  border:1px solid var(--line);border-left:4px solid var(--line)}
.mf-verdict.is-ok{border-left-color:var(--ok-vivid);background:var(--ok-soft)}
.mf-verdict.is-warn{border-left-color:var(--warn-vivid);background:var(--warn-wash)}
.mf-verdict.is-danger{border-left-color:var(--danger-vivid);background:var(--danger-wash)}
.mf-verdict-h{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-md)}
.mf-verdict-a{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin-top:var(--sp-2)}

/* ---- missing information (owner, 2026-09-13): named on the card and the result, never guessed ---- */
.mf-missing{margin:var(--sp-3) 0;padding:var(--sp-3) var(--sp-4);border:1px solid var(--warn-line);border-left:4px solid var(--warn-vivid);
  border-radius:var(--r-md);background:var(--warn-wash)}
.mf-missing.is-clear{display:flex;align-items:center;gap:var(--sp-2);border-color:var(--ok-line);border-left-color:var(--ok-vivid);background:var(--ok-soft)}
.mf-missing-h{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-1) var(--sp-2);margin-bottom:var(--sp-2)}
.mf-missing-h .muted{font-size:var(--fs-sm)}
.mf-missing-l{list-style:none;margin:0;padding:0;display:grid;gap:var(--sp-2)}
.mf-missing-l li{display:grid;grid-template-columns:minmax(56px,auto) minmax(0,1fr);gap:var(--sp-3);align-items:baseline}
.mf-missing-n{font-size:var(--fs-lg);font-weight:800;font-variant-numeric:tabular-nums;text-align:right;color:var(--ink-strong)}
.mf-missing-t{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--sp-1) var(--sp-2)}
.mf-missing-t .muted{flex-basis:100%;font-size:var(--fs-sm)}
.mf-missing-chip{display:inline-flex;align-items:center;gap:4px;margin-left:var(--sp-1);padding:1px 8px;border-radius:999px;font-size:var(--fs-xs);
  font-weight:700;color:var(--warn);background:var(--warn-soft);border:1px solid var(--warn-line);white-space:nowrap}

/* ---- what ERPmax already holds: the answer first, then one tile per bucket ---- */
.mf-erp-h{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2)}
.mf-erp-h h4{margin:0}
.mf-erp-h .badge{display:inline-flex;align-items:center;gap:4px}
.mf-erp-sub{margin:var(--sp-1) 0 var(--sp-3);font-size:var(--fs-sm);color:var(--ink-muted)}
.mf-erp-lead{display:flex;gap:var(--sp-2);align-items:flex-start;padding:var(--sp-3);border-radius:var(--r-md);border:1px solid var(--line);line-height:1.5}
.mf-erp-lead .muted{display:block;margin-top:2px;font-size:var(--fs-sm)}
.mf-erp-lead--ok{background:var(--ok-soft);border-color:var(--ok-line)}
.mf-erp-lead--warn{background:var(--warn-soft);border-color:var(--warn-line)}
.mf-erp-lead--info{background:var(--info-soft);border-color:var(--info-line)}
.mf-erp-info{display:flex;align-items:center;gap:var(--sp-2);margin:var(--sp-3) 0 0;font-size:var(--fs-sm);color:var(--ink-muted)}
.mf-erp-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:var(--sp-2);margin-top:var(--sp-3)}
.mf-erp-b{display:flex;flex-direction:column;gap:2px;min-width:0;padding:var(--sp-3);border:1px solid var(--line);border-left:4px solid var(--line);
  border-radius:var(--r-md);background:var(--surface)}
.mf-erp-b--good{border-left-color:var(--ok-vivid)} .mf-erp-b--info{border-left-color:var(--info-vivid)}
.mf-erp-b--warn{border-left-color:var(--warn-vivid)} .mf-erp-b--critical{border-left-color:var(--danger-vivid)}
.mf-erp-n{font-size:var(--fs-xl);font-weight:800;line-height:1.1;font-variant-numeric:tabular-nums;color:var(--ink-strong)}
.mf-erp-l{font-weight:700;font-size:var(--fs-md)}
.mf-erp-t{font-size:var(--fs-sm);color:var(--ink-muted);line-height:1.45}

/* ---- 6-step visual workflow stepper ---- */
.mf-stepper-card{margin-bottom:var(--sp-4);background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh-1);padding:var(--sp-4)}
.mf-stepper-h{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding-bottom:var(--sp-3);border-bottom:1px solid var(--line);margin-bottom:var(--sp-4);flex-wrap:wrap}
.mf-stepper-title{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.mf-stepper-pulse{width:10px;height:10px;border-radius:50%;background:var(--info-vivid);box-shadow:0 0 0 3px var(--info-soft);animation:mf-pulse 2s infinite}
@keyframes mf-pulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.25);opacity:.6}}
.mf-stepper-track{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);overflow-x:auto;padding:var(--sp-1) 0}
.mf-st-node{display:flex;align-items:center;gap:var(--sp-2);flex:none}
.mf-st-dot{width:32px;height:32px;border-radius:50%;border:2px solid var(--line-strong);background:var(--surface-2);color:var(--ink-muted);
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:var(--fs-sm);transition:all var(--dur-fast) var(--ease)}
.mf-st-info{display:flex;flex-direction:column}
.mf-st-name{font-size:var(--fs-sm);font-weight:700;color:var(--ink-muted);line-height:1.2}
.mf-st-sub{font-size:var(--fs-xs);color:var(--ink-faint);line-height:1.2}
.mf-st-connector{flex:1;height:2px;background:var(--line);min-width:14px}

.mf-st-node.is-done .mf-st-dot{background:var(--ok-vivid);border-color:var(--ok-vivid);color:var(--on-dark)}
.mf-st-node.is-done .mf-st-name{color:var(--ok)}
.mf-st-node.is-done + .mf-st-connector{background:var(--ok-line)}

.mf-st-node.is-active .mf-st-dot{background:var(--brand);border-color:var(--info-vivid);color:var(--on-dark);box-shadow:0 0 0 4px var(--info-soft)}
.mf-st-node.is-active .mf-st-name{color:var(--brand);font-weight:800}

.mf-st-node.is-pending .mf-st-dot{opacity:.5}
.mf-st-node.is-pending .mf-st-name{opacity:.5}
@media(max-width:768px){
  .mf-st-sub{display:none}
  .mf-st-connector{min-width:8px}
}

/* Genders typed on a sheet sent back (2026-09-27): what the sheet would fill, before Apply */
.mf-gsheet { margin: var(--sp-3) 0; padding: var(--sp-3) var(--sp-4); border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface-2); }
.mf-gsheet-h { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.mf-gsheet p { margin: 0 0 var(--sp-2); font-size: var(--fs-sm); }
