:root{
  --bg:#f7f8f9; --surface:#fff; --text:#16191d; --muted:#6b7280;
  --border:#e3e6ea; --border2:#cbd2da; --primary:#1a4f8a;
  --ok:#0f7a48; --okbg:#e9f6ef; --warn:#8a5a00; --warnbg:#fdf3da;
  --bad:#b42318; --badbg:#fdeeec; --info:#28559a; --infobg:#eef3fb;
}
*{box-sizing:border-box}
/* The `hidden` attribute is only display:none in the browser's own
   stylesheet, so any rule of ours that sets a display outranks it and
   the element stays visible. Several do -- .btn, .subtle, .camera, the
   dialog -- which is why buttons meant to appear only once rows are
   ticked were showing all the time. Stated once, for everything. */
[hidden]{display:none !important}
body{margin:0;background:var(--bg);color:var(--text);
  font:13px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
  -webkit-font-smoothing:antialiased}
a{text-decoration:none;color:inherit}

/* ---- shell: a header, an optional sidebar, and the page ---- */
.app-header{background:#fff;border-bottom:1px solid var(--border);position:sticky;top:0;z-index:20;
  height:44px;display:flex;align-items:center;gap:18px;padding:0 18px}
.brand{font-weight:800;letter-spacing:-.02em;white-space:nowrap;font-size:14px}
.brand span{color:var(--muted);font-weight:600}
.spacer{flex:1}

.header-actions{margin-left:auto;display:flex;align-items:center;gap:10px}
.whoami{font-size:11.5px;color:var(--muted);font-weight:600;max-width:170px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.signout{font-size:11.5px;font-weight:700;color:var(--primary)}
.layout-toggle{width:24px;height:24px;display:grid;place-items:center;border:1px solid var(--border);
  border-radius:5px;color:var(--muted);font-size:13px;line-height:1}
.layout-toggle:hover{background:#f2f4f6;color:var(--text)}
.mode{font-size:10px;font-weight:800;letter-spacing:.05em;padding:3px 7px;border-radius:4px}
.mode.shadow{background:#eef0f3;color:#4b5563}
.mode.live{background:var(--badbg);color:var(--bad)}
.mode.redirect{background:var(--warnbg);color:var(--warn)}

.app-body{display:flex;align-items:flex-start;min-height:calc(100vh - 44px)}

/* Sidebar: grouped, so ten destinations stay scannable. */
.side-nav{width:186px;flex:0 0 186px;background:#fff;border-right:1px solid var(--border);
  padding:10px 0 24px;position:sticky;top:44px;max-height:calc(100vh - 44px);overflow-y:auto}
.side-group{font-size:10px;font-weight:700;color:var(--muted);text-transform:uppercase;
  letter-spacing:.06em;padding:12px 14px 5px}
.side-group:first-child{padding-top:4px}
.side-nav a{display:block;padding:6px 14px;color:#3f4854;font-weight:600;border-left:2px solid transparent}
.side-nav a:hover{background:#f5f7f9;color:var(--text)}
.side-nav a.active{background:#eef3fb;color:var(--primary);border-left-color:var(--primary)}

/* Top bar: the same links in one row, for people who prefer the width. */
.top-nav{display:none;gap:16px;align-items:center;height:100%;overflow-x:auto}
.top-nav a{display:flex;align-items:center;height:100%;color:var(--muted);font-weight:600;
  white-space:nowrap;border-bottom:2px solid transparent;margin-bottom:-1px}
.top-nav a:hover{color:var(--text)}
.top-nav a.active{color:var(--text);border-bottom-color:var(--primary)}

.layout-top .side-nav{display:none}
.layout-top .top-nav{display:flex}

/* Fills the space beside the nav rather than stopping short of it. The
   old 1500px cap left every screen wider than that with a large dead
   margin on the right only, because nothing centred what was left. These
   pages are tables and toolbars, which use width well, so the width is
   given to them and the header padding is matched so the two line up. */
.page{flex:1;min-width:0;padding:14px 18px;width:100%;box-sizing:border-box;
  margin-inline:auto}
.notice{background:var(--infobg);border:1px solid #cddcf0;color:#1b4a7d;
  border-radius:5px;padding:8px 11px;margin-bottom:10px;font-weight:600}

/* ---- panel ---- */
.work-panel{background:#fff;border:1px solid var(--border);border-radius:6px;overflow:hidden}
.toolbar{padding:8px 10px;border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
.toolbar-actions{display:flex;gap:8px;align-items:center}
.filter-tabs{display:flex;gap:2px}
.filter-tabs a{padding:5px 9px;border-radius:5px;color:var(--muted);font-weight:600;white-space:nowrap}
.filter-tabs a:hover{background:#f2f4f6}
.filter-tabs a b{font-weight:700;color:var(--text);margin-left:3px}
.filter-tabs a.active{background:#eef1f5;color:var(--text)}
.search-input{height:30px;width:230px;border:1px solid var(--border2);border-radius:5px;padding:0 9px;font-size:13px}
.search-input:focus{outline:2px solid #cddcf0;outline-offset:-1px;border-color:var(--primary)}
.inline-form{display:inline}

.btn{height:30px;border:1px solid var(--border2);border-radius:5px;padding:0 11px;
  font-weight:700;font-size:13px;background:#fff;cursor:pointer;
  display:inline-flex;align-items:center;white-space:nowrap}
.btn:hover{background:#f7f8f9}
.btn.primary{background:var(--primary);border-color:var(--primary);color:#fff}
.btn.primary:hover{background:#16436f}
.btn.secondary{background:#fff}
.btn:disabled{opacity:.5;cursor:default}

/* ---- table ---- */
table{width:100%;border-collapse:collapse}
th{text-align:left;color:var(--muted);font-size:10px;text-transform:uppercase;
  letter-spacing:.05em;font-weight:700;background:#fafbfc;padding:7px 12px;
  border-bottom:1px solid var(--border)}
td{padding:9px 12px;border-bottom:1px solid #eef0f2;vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:#fafbfc}
.right{text-align:right}
.subtle{display:block;color:var(--muted);font-size:11.5px;margin-top:1px}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px}
.source-tag{display:inline-block;border:1px solid var(--border);background:#f8f9fa;
  border-radius:4px;padding:2px 6px;font-size:10.5px;font-weight:700;color:#4b5563}
.status{display:inline-block;border-radius:4px;padding:2px 7px;font-size:11px;font-weight:700}
.status-ready{color:var(--info);background:var(--infobg)}
.status-sending{color:#5b4c9d;background:#f2effb}
.status-sent,.status-delivered{color:var(--ok);background:var(--okbg)}
.status-failed{color:var(--bad);background:var(--badbg)}
.status-review{color:var(--warn);background:var(--warnbg)}
.status-shadow{color:#5b4c9d;background:#f2effb}
.status-skipped{color:var(--muted);background:#f0f2f4}
.error-note{display:block;color:var(--bad);font-size:11.5px;margin-top:2px}
.text-link{color:var(--primary);font-weight:700}

/* The saved screenshot and passport for one candidate. Stacked rather
   than inline: two links side by side in a narrow cell wrap badly. */
.file-links{display:flex;flex-direction:column;gap:2px}
.file-links a{color:var(--primary);font-size:11.5px;text-decoration:none}
.file-links a:hover{text-decoration:underline}
.mobile-card .file-links{flex-direction:row;gap:10px;margin-top:2px}

/* The Review row: screenshot on the left, the form on the right. The
   number being asked for is only legible in the image, so the two belong
   side by side rather than stacked -- reading and typing should not mean
   scrolling between them. */
.review-work{display:flex;gap:16px;align-items:flex-start;margin-top:8px;flex-wrap:wrap}
.review-fields{flex:1;min-width:300px}
.review-shot{display:block;flex:0 0 auto;width:340px;max-width:100%}
.review-shot img{display:block;width:100%;max-height:260px;object-fit:contain;
  border:1px solid var(--border);border-radius:4px;background:#fff}
.review-shot-missing{flex:0 0 auto;width:340px;max-width:100%;padding:24px 12px;
  text-align:center;border:1px dashed var(--border2);border-radius:4px;
  background:#fafbfc}

/* A number recovered from a padded field. Deliberately not filled into
   the box: it is a suggestion a person checks, one click from being
   used, and never one click from being sent. */
.suggestion{margin-bottom:10px;padding:9px 11px;background:var(--infobg);
  border:1px solid #cddcf0;border-radius:5px}
.suggestion-head{font-size:10.5px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:#28559a;margin-bottom:3px}
.suggestion-value{border:1px solid var(--border2);background:#fff;
  border-radius:4px;padding:4px 9px;font-size:13.5px;font-weight:700;
  color:var(--primary);cursor:pointer}
.suggestion-value:hover{background:#eef3fb;border-color:var(--primary)}
.suggestion-note{margin-top:4px;font-size:11.5px;color:#3f5878}
.empty-state{padding:52px 20px;text-align:center}
.empty-state p{color:var(--muted);margin:5px 0 0}

/* Some pages use .empty, some .empty-state. Both are empty states and
   both need the same room, or the text sits flush against the border. */
.empty{padding:30px 18px}
.empty h3{margin:0 0 4px;font-size:14px;font-weight:700}
.panel-body{padding:12px 18px}

/* Prose does not use width the way a table does: a sentence running the
   full span of a wide monitor is hard to read, so only the text is
   capped, never the tables. */
.empty p,.panel-body p,.empty-state p{max-width:74ch}
.empty-state p{margin-inline:auto}

/* ---- review + agencies ---- */
.review-row{padding:11px 12px;border-bottom:1px solid #eef0f2}
.review-row:last-child{border-bottom:0}
.review-head{display:flex;justify-content:space-between;gap:12px;align-items:flex-start}
.resolve-form{display:flex;gap:6px;align-items:center;margin-top:8px;flex-wrap:wrap}
.resolve-form input{height:30px;border:1px solid var(--border2);border-radius:5px;
  padding:0 9px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;width:170px;font-size:13px}

/* ---- settings ---- */
.settings-list{background:#fff;border:1px solid var(--border);border-radius:6px;overflow:hidden}
.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:11px 14px;border-bottom:1px solid #eef0f2}
.settings-row:last-child{border-bottom:0}
.settings-row h2{font-size:13px;margin:0 0 2px;font-weight:700}
.settings-row p{margin:0;color:var(--muted);font-size:12px}
.section-title{font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;
  letter-spacing:.05em;margin:18px 0 7px}
.section-title:first-child{margin-top:0}

.mobile-list{display:none}

@media(max-width:860px){
  .shell{width:calc(100% - 18px)}
  .header-inner{height:auto;padding:8px 0;flex-wrap:wrap;gap:10px}
  .brand span{display:none}
  .top-nav{order:3;flex-basis:100%;gap:16px;overflow-x:auto;height:32px}
  .top-nav a{border-bottom:none;font-size:13px}
  .top-nav a.active{border-bottom:2px solid var(--primary)}
  .toolbar{gap:8px}
  .filter-tabs{overflow-x:auto;flex:1;-webkit-overflow-scrolling:touch}
  .toolbar-actions{flex:1}
  .search-input{width:100%;flex:1}
  .desktop-table{display:none}
  .mobile-list{display:block}
  .mobile-card{padding:11px 12px;border-bottom:1px solid #eef0f2}
  .mobile-card:last-child{border-bottom:0}
  .mobile-card-top{display:flex;justify-content:space-between;gap:10px;align-items:flex-start}
  .mobile-card-bottom{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-top:9px}
  .settings-row{flex-wrap:wrap}
}
.field-state{margin-top:4px;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.field-input{flex:0 0 300px}
.field-input input{width:100%;height:30px;border:1px solid var(--border2);border-radius:5px;padding:0 9px;font-size:13px}
.field-input input:focus{outline:2px solid #cddcf0;outline-offset:-1px;border-color:var(--primary)}
.save-bar{display:flex;align-items:center;gap:12px;margin-top:14px;flex-wrap:wrap}
@media(max-width:860px){.field-input{flex:1 1 100%}}
.lang-switch{display:inline-flex;border:1px solid var(--border);border-radius:5px;overflow:hidden}
.lang-switch a{padding:3px 7px;font-size:10.5px;font-weight:700;color:var(--muted);border-right:1px solid var(--border)}
.lang-switch a:last-child{border-right:0}
.lang-switch a:hover{background:#f2f4f6}
.lang-switch a.active{background:var(--primary);color:#fff}
.tpl-input{width:100%;height:28px;border:1px solid var(--border2);border-radius:4px;padding:0 7px;font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.tpl-approved{display:flex;align-items:center;gap:4px;margin-top:4px;font-size:11px;color:var(--muted);font-weight:600}
.tpl-approved input{margin:0}
.lang-select{height:26px;border:1px solid var(--border2);border-radius:4px;font-size:12px;background:#fff;padding:0 4px;max-width:130px}
.add-row{display:flex;align-items:center;gap:7px;padding:9px 12px;border-top:1px solid var(--border);background:#fafbfc;flex-wrap:wrap}
/* A button that looks like a link. display:block is deliberate here, so
   it sits under whatever it belongs to -- which is also why it must not
   be used on a table cell, where it would break the row. Use .failed-text
   for that. */
.link-danger{background:none;border:0;color:var(--bad);font-size:11px;font-weight:700;cursor:pointer;padding:0;margin-top:3px;display:block}

/* Failed text inside a cell: the colour without the button layout. */
.failed-text{color:var(--bad);font-weight:600}
.wafid-help{font-size:13px;max-width:80ch!important}
.wafid-upload{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:14px 0 5px}
.wafid-drop-zone{display:grid;gap:5px;width:min(100%,440px);padding:16px;border:2px dashed var(--border2);border-radius:7px;background:#fafbfc;color:var(--muted);text-align:center}
.wafid-drop-zone strong{font-size:14px;color:var(--text)}
.wafid-drop-zone.drag-over{border-color:var(--primary);background:var(--infobg)}
.wafid-drop-zone input{max-width:100%;margin:6px auto 0;font-size:12px}
.wafid-selected{font-size:12px;font-weight:700;color:var(--primary);overflow-wrap:anywhere}
.wafid-decision{display:flex;align-items:center;gap:12px;padding:13px 18px;border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
.wafid-decision strong{font-size:16px}.wafid-decision span{color:#46515d}
.wafid-decision.safe{background:var(--okbg);color:var(--ok)}
.wafid-decision.stop{background:var(--badbg);color:var(--bad)}
.wafid-decision.review{background:var(--warnbg);color:var(--warn)}
.wafid-summary{display:flex;gap:22px;flex-wrap:wrap;border-bottom:1px solid var(--border)}
.wafid-summary div{display:grid;gap:1px}.wafid-summary span{font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);font-weight:700}
.wafid-summary strong{font-size:12.5px}.wafid-table-wrap{overflow-x:auto}
.wafid-table{min-width:850px}.wafid-row-mismatch{background:#fff8f7}.wafid-row-unknown{background:#fffdf7}.wafid-row-not_checked{background:#f8f9fa}
.wafid-raw{margin:12px 18px 16px;color:var(--muted)}.wafid-raw summary{cursor:pointer;font-weight:700;color:var(--primary)}
.wafid-raw pre{white-space:pre-wrap;max-height:260px;overflow:auto;background:#f7f8f9;border:1px solid var(--border);padding:10px;border-radius:5px;font-size:11px}
@media(max-width:700px){.wafid-upload{align-items:stretch}.wafid-upload .btn{width:100%;justify-content:center;height:38px}.wafid-drop-zone{width:100%}.wafid-decision{align-items:flex-start;flex-direction:column;gap:2px}}
.link-danger:hover{text-decoration:underline}
.tpl-body{width:100%;min-width:190px;border:1px solid var(--border2);border-radius:4px;padding:5px 7px;font-size:12px;font-family:inherit;resize:vertical}
.sms-values{display:flex;gap:10px;padding:10px 12px;border-bottom:1px solid var(--border);background:#fafbfc;flex-wrap:wrap}
.sms-values label{display:flex;flex-direction:column;gap:3px;font-size:11px;font-weight:700;color:var(--muted);text-transform:capitalize}
.sms-values input{width:150px;font-family:inherit}
.sms-preview{padding:9px 12px;border-bottom:1px solid var(--border);display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.sms-preview .sample{color:var(--muted);font-size:12px}
.sms-values .req{color:var(--bad)}
.filter-tabs a.active{background:var(--primary);color:#fff}
.filter-tabs a.active b{color:#fff}
.file-input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
label.btn{cursor:pointer}
.camera{position:fixed;inset:0;background:#0f172ae6;z-index:50;display:flex;align-items:center;justify-content:center;padding:16px}
.camera[hidden]{display:none}
.camera-box{background:#fff;border-radius:8px;width:min(860px,100%);max-height:calc(100vh - 32px);display:flex;flex-direction:column;overflow:hidden}
.camera-head{display:flex;align-items:center;gap:10px;padding:10px 12px;border-bottom:1px solid var(--border)}
.camera-head strong{flex:1}
.camera-stage{position:relative;background:#0b1220;display:flex;align-items:center;justify-content:center;min-height:260px}
.camera-stage video{width:100%;max-height:56vh;display:block;object-fit:contain}
.camera-guide{position:absolute;inset:8% 6%;border:2px dashed #ffffff66;border-radius:6px;display:flex;align-items:flex-end;justify-content:center;pointer-events:none}
.camera-guide span{background:#0b1220cc;color:#e6edf5;font-size:11.5px;padding:4px 9px;border-radius:4px;margin-bottom:8px;text-align:center}
.camera-shots{display:flex;gap:8px;padding:9px 12px;overflow-x:auto;border-bottom:1px solid var(--border)}
.camera-shots:empty{display:none}
.shot{position:relative;flex:0 0 auto}
.shot img{height:64px;border-radius:4px;border:1px solid var(--border2);display:block}
.shot button{position:absolute;top:-6px;right:-6px;width:19px;height:19px;border-radius:50%;border:1px solid var(--border2);background:#fff;cursor:pointer;font-size:13px;line-height:1;padding:0}
.camera-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;flex-wrap:wrap}
@media(max-width:640px){.camera-stage video{max-height:44vh}.camera-foot{flex-direction:column;align-items:stretch}}
.btn.disabled{opacity:.5;pointer-events:none}
.status-needs-details{color:var(--warn);background:var(--warnbg)}
.status-working{color:#5b4c9d;background:#f2effb}
.status-pending{color:var(--info);background:var(--infobg)}
.status-done{color:var(--ok);background:var(--okbg)}
.group-head{font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;
  letter-spacing:.05em;padding:12px 14px 5px;border-top:1px solid var(--border);background:#fafbfc}
.settings-list+.group-head{border-top:1px solid var(--border)}
.save-bar{display:flex;align-items:center;gap:12px;padding:12px 14px;border-top:1px solid var(--border);background:#fafbfc;flex-wrap:wrap}
.signin{display:flex;justify-content:center;padding:56px 0}
.signin-card{background:#fff;border:1px solid var(--border);border-radius:8px;padding:26px;width:min(380px,100%);display:flex;flex-direction:column;gap:13px}
.signin-card h1{margin:0;font-size:19px;letter-spacing:-.02em}
.signin-card .subtle{margin:-8px 0 4px}
.signin-card label{display:flex;flex-direction:column;gap:5px;font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.signin-card input{height:36px;border:1px solid var(--border2);border-radius:5px;padding:0 10px;font-size:14px;font-family:inherit}
.signin-card input:focus{outline:2px solid #cddcf0;outline-offset:-1px;border-color:var(--primary)}
.signin-card .btn{justify-content:center;height:38px;margin-top:4px}
.signin-error{background:var(--badbg);border:1px solid #f3c9c4;color:var(--bad);border-radius:5px;padding:9px 11px;font-size:12.5px}
.signin-note{margin:2px 0 0;font-size:11.5px}
.whoami{font-size:11.5px;color:var(--muted);font-weight:600;max-width:190px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.signout{font-size:11.5px;font-weight:700;color:var(--primary)}

/* Narrow screens: the sidebar becomes a scrolling strip. */
@media(max-width:900px){
  .app-body{flex-direction:column}
  .side-nav{width:100%;flex:none;position:static;max-height:none;display:flex;gap:2px;
    overflow-x:auto;border-right:0;border-bottom:1px solid var(--border);padding:6px 8px}
  .side-group{display:none}
  .side-nav a{border-left:0;border-radius:5px;padding:6px 10px;white-space:nowrap}
  .side-nav a.active{border-left:0}
  .brand span,.whoami{display:none}
  .page{padding:10px}
}

/* ---- documents: one card per slot, showing the document itself ---- */
/* "on file" is not verifiable -- an operator cannot tell from those words
   whether the right page is there, or whether it is upside down. The
   thumbnail is the point of this screen. */
.doc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));
  gap:12px;padding:12px 18px}
.doc-slot{border:1px solid var(--border);border-radius:6px;padding:11px 12px;background:#fff;
  display:flex;flex-direction:column;gap:7px}
.doc-slot.doc-missing{border-color:#f0dca8;background:var(--warnbg)}
.doc-slot-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.doc-slot-head strong{font-size:13px}
.doc-slot p.subtle{margin:0}
.doc-thumb{display:flex;align-items:center;justify-content:center;height:120px;
  border:1px solid var(--border2);border-radius:5px;background:#fafbfc;overflow:hidden}
.doc-thumb img{max-width:100%;max-height:118px;object-fit:contain;display:block}
.doc-thumb-empty{border-style:dashed;background:transparent}
.doc-pdf{font-weight:800;font-size:15px;letter-spacing:.06em;color:var(--muted)}
.doc-form{display:flex;flex-direction:column;gap:6px}
.doc-form input[type=file]{font-size:11.5px;max-width:100%}
.doc-form .btn{justify-content:center}

/* ---- pager ---- */
/* A count that does not match the rows on screen is worse than none, so
   the range and the total are both shown. */
.pager{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:10px 18px;border-top:1px solid var(--border);flex-wrap:wrap}
.pager-links{display:flex;align-items:center;gap:10px}

/* Shared Gmail mailbox: plain-text message bodies are deliberately not
   rendered as email HTML, so remote images and unsafe markup stay inert. */
.inbox-search{flex-wrap:wrap}
.inbox-search .search-input{width:min(400px,55vw)}
.inbox-list{display:flex;flex-direction:column}
.inbox-row{display:grid;grid-template-columns:minmax(140px,230px) minmax(0,1fr) auto auto;
  align-items:center;gap:12px;padding:11px 14px;border-bottom:1px solid var(--border);color:var(--text)}
.inbox-row:hover{background:#f7f9fc}
.inbox-row.unread{background:#f3f7ff}
.inbox-row-who,.inbox-row-main strong,.inbox-row-main span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.inbox-row-main{display:flex;min-width:0;gap:8px}
.inbox-row-main strong{flex-shrink:0;max-width:52%}
.inbox-row-main span{color:var(--muted);min-width:0}
.inbox-row-date{font-size:12px;color:var(--muted);white-space:nowrap}
.inbox-error,.inbox-warning{padding:10px 14px;border-bottom:1px solid var(--border)}
.inbox-error{background:var(--badbg);color:var(--bad)}
.inbox-warning{background:var(--warnbg);color:var(--warn)}
.inbox-form{display:flex;flex-direction:column;gap:14px;padding:18px;max-width:850px}
.inbox-form label{display:flex;flex-direction:column;gap:5px;font-weight:700}
.inbox-form input[type=text],.inbox-form textarea{width:100%;box-sizing:border-box;border:1px solid var(--border2);
  border-radius:5px;padding:9px;font:inherit;font-weight:400}
.inbox-form textarea{resize:vertical;line-height:1.45}
.inbox-thread{background:var(--bg)}
.inbox-thread-head{padding:20px 24px 16px;background:var(--surface);border-bottom:1px solid var(--border)}
.inbox-thread-head h1{font-size:19px;line-height:1.35;margin:0 0 10px;overflow-wrap:anywhere;font-weight:700}
.inbox-case-ref{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 8px;font-size:13px}
#inbox-messages{display:flex;flex-direction:column;gap:12px;padding:16px 24px}
.inbox-message{background:var(--surface);border:1px solid var(--border);border-radius:8px;
  padding:16px 20px;box-shadow:0 1px 2px rgba(16,24,40,.03)}
.inbox-message-head{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding-bottom:10px;margin-bottom:12px;border-bottom:1px solid var(--border)}
.inbox-message-head strong{font-size:13.5px}
.inbox-message-head span{color:var(--muted);font-size:12px;white-space:nowrap}
.inbox-body{font:13px/1.6 ui-sans-serif,system-ui,sans-serif;white-space:pre-wrap;overflow-wrap:anywhere;
  word-break:break-word;max-width:78ch;color:var(--text)}
.inbox-body-preview{font-size:13px;line-height:1.5;color:var(--muted);margin:0;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}

/* The sandboxed message-body iframe (app/templates/shared_thread.html)
   has no allow-same-origin, so its own scrollHeight can never be read
   from the parent page to auto-size it -- that permission is exactly
   what would let it read and manipulate the Hub page in turn. A tall
   default plus a manual resize handle is the safe compromise: no email,
   however long, is ever clipped without the option to see the rest. */
.inbox-body-frame{width:100%;max-width:820px;height:420px;min-height:120px;
  border:1px solid var(--border);border-radius:6px;resize:vertical;
  overflow:auto;background:#fff;display:block}

/* A row of small "N — label" tiles, e.g. the new/follow-up/answered
   counts atop the Musaned requests page -- a glance at where a large
   queue actually stands before picking which batch to work from. */
.stat-row{display:flex;gap:10px;flex-wrap:wrap;margin:14px 0 4px}
.stat{flex:1 1 140px;min-width:120px;border:1px solid var(--border);
  border-radius:8px;padding:10px 14px;background:var(--surface)}
.stat strong{display:block;font-size:22px;line-height:1.2;color:var(--text)}
.stat span{display:block;font-size:12px;color:var(--muted);margin-top:2px}
.inbox-attachments{display:flex;flex-wrap:wrap;gap:7px;margin-top:14px;padding-top:14px;
  border-top:1px solid var(--border)}

/* Skeleton state: the page's own header/participants render instantly
   from the local mirror while the real body loads in behind them. */
.inbox-message-skeleton{position:relative;overflow:hidden}
.inbox-loading-bar{height:3px;background:var(--border);border-radius:2px;margin-top:14px;overflow:hidden}
.inbox-loading-bar span{display:block;height:100%;width:40%;background:var(--primary);
  border-radius:2px;animation:inbox-loading 1.1s ease-in-out infinite}
@keyframes inbox-loading{
  0%{transform:translateX(-100%)}
  100%{transform:translateX(350%)}
}

.inbox-reply-form{max-width:none;background:var(--surface);border-top:1px solid var(--border);
  padding:18px 24px 22px;gap:10px}
.inbox-reply-form textarea{max-width:78ch}
.inbox-reply-footer{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.inbox-reply-footer .subtle{flex:1;min-width:220px;font-size:12px}
.inbox-file-label input[type=file]{font-size:12.5px;max-width:220px}
@media(max-width:760px){
  .inbox-row{grid-template-columns:minmax(0,1fr) auto;gap:4px 8px}
  .inbox-row-who,.inbox-row-main{grid-column:1}
  .inbox-row-main{display:block}
  .inbox-row-main strong,.inbox-row-main span{display:block;max-width:none}
  .inbox-row-date{grid-column:2;grid-row:1}
  .inbox-row .source-tag{grid-column:2;grid-row:2;justify-self:end}
}

/* Separates the stage tabs from the source tabs in the same strip. */
.tab-divider{width:1px;align-self:stretch;background:var(--border);margin:0 4px}

.email-input{height:28px;width:200px;border:1px solid var(--border2);border-radius:5px;
  padding:0 8px;font-size:12px;font-family:inherit}

/* Process steps: a fixed, narrow time column so the message gets the
   width. Step text can be long -- an address plus a candidate name -- and
   must wrap inside its own cell rather than pushing the row apart. */
.step-time{width:5.5rem;white-space:nowrap;vertical-align:top}
.grid td.failed-text,.grid td{overflow-wrap:anywhere}

/* Sortable headers. Kept looking like a header rather than a link: the
   arrow is what says which column is sorted, not the colour. */
.sort-link{color:inherit;font:inherit;text-decoration:none;white-space:nowrap}
.sort-link:hover{color:var(--primary)}

.edit-input{height:28px;width:100%;max-width:230px;border:1px solid var(--border2);
  border-radius:5px;padding:0 8px;font-size:12.5px;font-family:inherit}
.edit-input.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}

/* Dropdown menu, used for exports. A <details> rather than a scripted
   popup: it opens and closes on its own, works with the keyboard, and
   the links inside still work if JavaScript fails. */
.menu{position:relative;display:inline-block}
.menu>summary{list-style:none;user-select:none}
.menu>summary::-webkit-details-marker{display:none}
/* The caret says it opens something, and turns when it does. */
.menu>summary::after{content:"";margin-left:7px;border:4px solid transparent;
  border-top-color:currentColor;margin-top:3px}
.menu[open]>summary::after{margin-top:-3px;
  border-top-color:transparent;border-bottom-color:currentColor}
.menu[open]>summary{background:#f7f8f9}

.menu-body{position:absolute;top:calc(100% + 4px);right:0;z-index:40;
  min-width:232px;padding:6px;background:#fff;border:1px solid var(--border2);
  border-radius:6px;box-shadow:0 6px 20px rgba(16,26,40,0.13)}
.menu-body a,.menu-body button{display:flex;align-items:center;
  justify-content:space-between;gap:16px;width:100%;box-sizing:border-box;
  padding:7px 10px;border:0;border-radius:4px;background:none;
  font:inherit;font-size:13px;color:var(--text);text-align:left;
  text-decoration:none;cursor:pointer;white-space:nowrap}
.menu-body a:hover,.menu-body button:hover{background:#eef2f7}

/* A section heading inside the menu -- "This view", "Everything". The
   scope is the thing people get wrong, so it is a label, not a suffix. */
.menu-label{padding:8px 10px 4px;font-size:11px;font-weight:700;
  letter-spacing:0.4px;text-transform:uppercase;color:var(--muted)}
.menu-label:first-child{padding-top:4px}

/* How many rows that choice would produce. */
.menu-note{font-variant-numeric:tabular-nums;font-weight:700;
  font-size:12px;color:var(--muted)}

/* ---- confirmation dialog ---- */
/* Used wherever a browser confirm() was. The actions behind these reach
   real agencies and real candidate records, so the dialog has room to
   say what is about to happen rather than one unstyled line. */
.dialog-backdrop{position:fixed;inset:0;z-index:100;background:rgba(16,26,40,.42);
  display:flex;align-items:center;justify-content:center;padding:20px}

body.dialog-open{overflow:hidden}
.dialog{width:100%;max-width:440px;background:#fff;border-radius:8px;
  box-shadow:0 18px 48px rgba(16,26,40,.24);padding:20px 22px 16px}
.dialog-title{margin:0 0 6px;font-size:15.5px;font-weight:700;letter-spacing:-.01em}
.dialog-body{margin:0;color:#3f4854;line-height:1.5;font-size:13.5px}

/* The specifics -- which candidates, which channel, how many. Set apart
   because it is what someone checks before pressing the button. */
.dialog-detail{margin-top:10px;padding:9px 11px;background:#f7f9fb;
  border:1px solid var(--border);border-radius:5px;
  font-size:12.5px;color:#3f4854;line-height:1.5;white-space:pre-line}

/* An option belonging to this one action, not to Settings. */
.dialog-option{display:flex;align-items:flex-start;gap:8px;margin-top:12px;
  padding:9px 11px;border:1px solid var(--border);border-radius:5px;
  font-size:12.5px;color:#3f4854;cursor:pointer;line-height:1.45}
.dialog-option input{margin:1px 0 0}

.dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:18px}
.dialog-actions .btn{height:32px}
/* Irreversible or outward-facing actions read as such. */
.dialog-actions .btn.danger{background:var(--bad);border-color:var(--bad);color:#fff}
.dialog-actions .btn.danger:hover{background:#9a1d14}

/* Agencies: paste-a-passport-list filter. */
.passport-filter{margin:0 0 12px}
.passport-filter>summary{display:inline-block;list-style:none;cursor:pointer}
.passport-filter>summary::-webkit-details-marker{display:none}
.passport-filter-form{display:flex;flex-direction:column;gap:8px;margin-top:8px;max-width:640px}
.passport-filter-form textarea{width:100%}

/* Public privacy policy: a readable document, not a work screen. */
.policy{max-width:700px;margin:0 auto;padding:36px 0 56px;line-height:1.6;font-size:14.5px}
.policy h1{margin:0 0 4px;font-size:24px;letter-spacing:-.02em}
.policy h2{margin:28px 0 8px;font-size:16px}
.policy p,.policy ul{margin:0 0 12px}
.policy ul{padding-left:20px}
.policy li{margin-bottom:6px}
