/* ============================================================================
   Opus Bench — app chrome.
   media="screen" is set on the <link>: exported and printed DOCUMENTS never
   read these tokens. exports.js writes its own literal CSS into a standalone
   file, so a manuscript is black-on-white on paper no matter what the app
   looks like on screen. Adding a rule here can never change a submission.
   ========================================================================= */

/* ---------- Design tokens ---------------------------------------------- */
:root{
  color-scheme:light;

  /* Brand. Emory navy, shared with the sibling apps; the manuscript app's own
     identity comes from --quill (the editorial accent used for revision marks
     and the active rail), not from a different brand colour. */
  --navy:#012169; --navy-2:#0b2f7e; --blue:#2c5cc5; --blue-lt:#e8eefb;
  --blue-line:#b9c9ec; --nav-fill:#012169;
  --quill:#7b1e3c; --quill-bg:#fbeef2; --quill-line:#e2b9c6;
  /* Sign-in buttons, drawn from the app-icon gradient (slate-blue + rose). */
  --gate-blue:#3f5583; --gate-blue-h:#354a73; --gate-rose:#a86b7b; --gate-rose-h:#96606e;

  /* Surfaces, lightest to most recessed. */
  --bg:#f4f5f8; --panel:#ffffff;
  --surface-2:#fafbfc; --surface-3:#fcfcfd; --surface-hover:#fafbfd; --surface-sel:#f2f6fd;
  --input-bg:#ffffff; --input-line:#868e9e;

  /* Hairlines. */
  --line:#dde1e8; --line-2:#eceef2; --line-strong:#c9cfda; --dash-line:#b9c1cf; --rail:#cfd8ea;

  /* Ink. */
  --ink:#1c2433; --ink-2:#5a6475; --ink-3:#5c6371; --ink-4:#8b93a3; --on-accent:#ffffff;

  /* Semantic triples: ink / tinted ground / border. */
  --green:#1e7a3c; --green-bg:#e7f4ec; --green-line:#bcdcc8;
  --red:#b3261e;   --red-bg:#fbeae9;   --red-line:#e5b6b3;
  --amber:#8a5c00; --amber-bg:#fff3d6; --amber-line:#e6d09a;
  --purple:#5b3fa8;--purple-bg:#efeafa;--purple-line:#c3b2ee;

  /* The manuscript page itself — deliberately a different material from the
     app chrome so the writing surface reads as paper even inside the shell. */
  --paper:#ffffff; --paper-ink:#161a22; --paper-line:#e3e6ec; --paper-shadow:rgba(20,28,48,.08);
  --paper-rule:#eef0f4;

  /* Toolbar, its own strip material (not --panel) so a card scrolling under it
     still reads as a separate surface. Two cues carry "this is a control" — a
     fill step AND a hairline — because at 28px either alone is deniable. */
  --tb-bg:#fbfcfd; --tb-line:#c9cfda; --tb-sep:#d7dce4;
  --tb-btn-bg:#ffffff; --tb-btn-line:#868e9e;
  --tb-btn-hover:#eef1f6; --tb-btn-active:#e3e8f0;
  --tb-menu-bg:#ffffff;

  --toast-bg:#1c2433; --toast-ink:#ffffff; --scroll-thumb:#c8cdd6;
  --hero-bg:#012169; --hero-ink-2:#9fb0d8; --nav-edge:#012169;
  --viewer-bg:#2a2f3a; --frame-bg:#525659;

  --radius:10px; --radius-sm:6px;
  --shadow:0 1px 2px rgba(16,24,40,.06),0 1px 3px rgba(16,24,40,.10);
  --shadow-lg:0 8px 28px rgba(16,24,40,.16),0 2px 8px rgba(16,24,40,.08);

  /* Type scale, named by ROLE — new work picks a role, not a pixel value. */
  --fs-micro:10px; --fs-tag:10.5px; --fs-cap:11px; --fs-meta:11.5px;
  --fs-sm:12px; --fs-ui:12.5px; --fs-base:13px; --fs-md:13.5px;
  --fs-title:14px; --fs-lead:15px;

  /* Spacing ladder. Odd values elsewhere are deliberate optical nudges. */
  --sp-1:2px; --sp-2:4px; --sp-3:6px; --sp-4:8px; --sp-5:10px; --sp-6:12px;
  --sp-7:14px; --sp-8:16px; --sp-9:18px; --sp-10:20px; --sp-12:24px; --sp-16:32px;

  --ui-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --doc-font:"Times New Roman",Times,Georgia,serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  --sidebar-w:264px;
}

:root[data-theme="dark"]{
  color-scheme:dark;
  --navy:#8aa6e8; --navy-2:#9db6ee; --blue:#7ea3ef; --blue-lt:#1b2540;
  --blue-line:#33436b; --nav-fill:#0d1526;
  --quill:#e79ab2; --quill-bg:#2c1621; --quill-line:#5b2c3d;

  --bg:#0e1420; --panel:#161d2b;
  --surface-2:#1a2130; --surface-3:#1c2433; --surface-hover:#1e2636; --surface-sel:#1e2a44;
  --input-bg:#111827; --input-line:#5b6577;

  --line:#28303f; --line-2:#222a38; --line-strong:#3a4353; --dash-line:#3e4757; --rail:#33415e;

  --ink:#e6e9ef; --ink-2:#a8b1c1; --ink-3:#9aa3b3; --ink-4:#79839a; --on-accent:#0e1420;

  --green:#5fce8b; --green-bg:#12291c; --green-line:#2c5b3d;
  --red:#f08a82;   --red-bg:#2d1614;   --red-line:#5e2c28;
  --amber:#e8b44f; --amber-bg:#2b2110; --amber-line:#5b4a20;
  --purple:#b39cf0;--purple-bg:#221b38;--purple-line:#443a6b;

  --paper:#141b27; --paper-ink:#e3e7ee; --paper-line:#2a3242; --paper-shadow:rgba(0,0,0,.5);
  --paper-rule:#222a38;

  --tb-bg:#131a27; --tb-line:#2f3a4c; --tb-sep:#28303f;
  --tb-btn-bg:#1b2331; --tb-btn-line:#5b6577;
  --tb-btn-hover:#232c3d; --tb-btn-active:#2a3548;
  --tb-menu-bg:#1b2331;

  --toast-bg:#e6e9ef; --toast-ink:#0e1420; --scroll-thumb:#3a4353;
  --hero-bg:#131c30; --hero-ink-2:#8fa3cf; --nav-edge:#0b1220;
  --viewer-bg:#0b0f17; --frame-bg:#0b0f17;

  --shadow:0 1px 2px rgba(0,0,0,.5),0 1px 3px rgba(0,0,0,.4);
  --shadow-lg:0 10px 34px rgba(0,0,0,.6),0 2px 8px rgba(0,0,0,.45);
}

/* Author palette. Eight hues that stay distinguishable side by side and keep
   >=4.5:1 against their own tint in BOTH themes — tracked changes and comment
   avatars are colour-coded by author, so these are load-bearing, not decorative. */
:root{
  --au-1:#1f5fbf; --au-1-bg:#e7effc;
  --au-2:#a3341f; --au-2-bg:#fcece8;
  --au-3:#1d7a52; --au-3-bg:#e4f4ec;
  --au-4:#7a3fa8; --au-4-bg:#f1e9fa;
  --au-5:#96631a; --au-5-bg:#fbf0dc;
  --au-6:#00707f; --au-6-bg:#e0f3f5;
  --au-7:#a82a6a; --au-7-bg:#fce9f2;
  --au-8:#41567a; --au-8-bg:#eaeef5;
}
:root[data-theme="dark"]{
  --au-1:#7fb0f5; --au-1-bg:#16233c;
  --au-2:#f0917c; --au-2-bg:#33201a;
  --au-3:#63cb9c; --au-3-bg:#122a20;
  --au-4:#c3a2ef; --au-4-bg:#241c38;
  --au-5:#dfae5c; --au-5-bg:#2c2312;
  --au-6:#5cc3ce; --au-6-bg:#0f2a2d;
  --au-7:#ef8fbc; --au-7-bg:#331a26;
  --au-8:#9fb2d4; --au-8-bg:#1c2436;
}

/* ---------- Reset / base ------------------------------------------------ */
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font:var(--fs-base)/1.5 var(--ui-font);
  -webkit-font-smoothing:antialiased;
  overflow:hidden;
}
button,input,select,textarea{font:inherit;color:inherit}
a{color:var(--blue);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4{margin:0;font-weight:640;letter-spacing:-.01em}
p{margin:0}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:var(--scroll-thumb);border-radius:6px;border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-track{background:transparent}

/* One universal focus ring. Deliberately does NOT set border-radius — doing so
   squared off every button in a sibling app. */
:focus-visible{outline:2px solid var(--blue);outline-offset:2px}

/* ---------- Boot watchdog ---------------------------------------------- */
#boot{position:fixed;inset:0;display:grid;place-items:center;background:var(--bg);z-index:9000}
.boot-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:var(--sp-12) var(--sp-16);box-shadow:var(--shadow);min-width:300px;text-align:center}
.boot-title{font-size:var(--fs-lead);font-weight:680;color:var(--ac-ink)}
.boot-msg{margin-top:var(--sp-4);color:var(--ink-2);font-size:var(--fs-ui)}
.boot-actions{margin-top:var(--sp-8)}
.boot-err{margin-top:var(--sp-8);text-align:left;font:var(--fs-cap)/1.5 var(--mono);
  color:var(--red);background:var(--red-bg);border:1px solid var(--red-line);
  border-radius:var(--radius-sm);padding:var(--sp-5);max-width:520px;max-height:180px;overflow:auto;white-space:pre-wrap}

/* ---------- App frame --------------------------------------------------- */
#app{display:flex;height:100%;position:relative}
#sidebar{
  width:var(--sidebar-w);flex:0 0 auto;background:var(--nav-fill);color:#dbe3f5;
  border-right:1px solid var(--nav-edge);display:flex;flex-direction:column;overflow:hidden;
  transition:width .16s ease;
}
#app.nav-collapsed #sidebar{width:0;border-right:0}

/* The collapse control in the sidebar head, and its twin in the topbar. The
   topbar one is always present because once the sidebar is gone it is the only
   way back — and on a narrow screen it is the only way in at all. */
.nav-headtxt{min-width:0;flex:1 1 auto}
.nav-collapse{flex:0 0 auto;width:24px;height:24px;border-radius:6px;border:0;cursor:pointer;
  background:#ffffff14;color:#dbe3f5;font-size:15px;line-height:1;display:grid;place-items:center}
.nav-collapse:hover{background:#ffffff24;color:#fff}
.tb-nav{flex:0 0 auto;width:28px;height:28px;margin-right:var(--sp-5);border-radius:var(--radius-sm);
  border:1px solid transparent;background:none;cursor:pointer;color:var(--ink-3);font-size:14px;
  display:grid;place-items:center}
.tb-nav:hover{background:var(--surface-hover);color:var(--ink);border-color:var(--line)}

/* Peek: point at the left edge and the sidebar slides back OVER the content, so
   a quick look costs no click and the writing surface never moves. */
#navPeek{position:absolute;left:0;top:0;bottom:0;width:12px;z-index:40;display:none}
#app.nav-collapsed:not(.narrow) #navPeek{display:block}
#app.nav-peek:not(.narrow) #sidebar{width:var(--sidebar-w);position:absolute;left:0;top:0;bottom:0;
  z-index:60;box-shadow:0 10px 40px rgba(16,24,40,.28);border-right:1px solid var(--nav-edge)}

/* Narrow: the sidebar becomes a drawer over the content, because there is no
   room to give it. It always starts closed — a drawer restored open would
   cover a phone screen entirely. */
#navScrim{position:absolute;inset:0;background:rgba(16,24,40,.42);z-index:50;display:none}
#app.narrow.nav-open #navScrim{display:block}
#app.narrow #sidebar{position:absolute;left:0;top:0;bottom:0;z-index:60;
  width:min(300px,86vw);border-right:1px solid var(--nav-edge);
  transform:translateX(-100%);transition:transform .18s ease}
#app.narrow.nav-open #sidebar{transform:none;box-shadow:0 10px 40px rgba(16,24,40,.34)}
/* Collapsed is the resting state on narrow, so the width-zero rule must not win. */
#app.narrow.nav-collapsed #sidebar{width:min(300px,86vw);border-right:1px solid var(--nav-edge)}
@media (prefers-reduced-motion:reduce){#sidebar{transition:none}}

#main{flex:1 1 auto;display:flex;flex-direction:column;min-width:0}
#topbar{flex:0 0 auto}
#content{flex:1 1 auto;overflow:auto;position:relative}

/* ---------- Sidebar ----------------------------------------------------- */
.nav-head{padding:var(--sp-10) var(--sp-10) var(--sp-6);display:flex;align-items:center;gap:var(--sp-5)}
.nav-mark{width:26px;height:26px;border-radius:7px;background:#ffffff1a;display:grid;place-items:center;
  font-weight:800;font-size:var(--fs-cap);letter-spacing:.02em;color:#fff;flex:0 0 auto}
.nav-title{font-size:var(--fs-md);font-weight:660;color:#fff;letter-spacing:-.01em}
.nav-sub{font-size:var(--fs-micro);color:#9fb0d8;text-transform:uppercase;letter-spacing:.08em}
.nav-scroll{flex:1 1 auto;overflow:auto;padding:var(--sp-4) var(--sp-5) var(--sp-10)}
.nav-sec{margin-top:var(--sp-8)}
/* A section head is a CONTROL now, not a caption — it opens and shuts the
   section. It was a <div>, so it needs the button reset. */
.nav-sec-head{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-3) var(--sp-5);
  font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.09em;color:#8fa3cf;font-weight:700;
  width:100%;background:none;border:0;font-family:inherit;cursor:pointer;text-align:left;
  border-radius:var(--radius-sm)}
.nav-sec-head:hover{background:#ffffff10;color:#cdd8ee}
.nav-sec-head:focus-visible{outline:2px solid #ffffff5c;outline-offset:-2px}
/* The count stays readable while the section is shut — it is the whole reason
   you would leave one closed, so hiding it with the contents defeats the point. */
.nav-sec-head .cnt{margin-left:auto;font-weight:600;letter-spacing:0}
.nav-sec-head .lbl{flex:0 0 auto}
.nav-sec-head .tw{width:10px;flex:0 0 auto;font-size:8px;opacity:.75;
  transition:transform .14s ease;transform:rotate(90deg)}
.nav-sec.is-collapsed .nav-sec-head .tw{transform:rotate(0deg)}

/* The guide line down a nested group, straight from the Expense Suite rail:
   it is what makes six indented rows read as belonging to the heading above
   rather than as six more top-level rows that happen to be inset. */
.nav-children{position:relative;padding-left:var(--sp-5)}
.nav-children::before{content:"";position:absolute;left:calc(var(--sp-5) - 3px);top:2px;bottom:2px;
  width:1px;background:#ffffff1f}

/* "Nothing yet" is a row, not an absence. An empty section that renders nothing
   looks broken; one that says so looks finished. */
.nav-row.is-empty{color:#8fa3cf;font-style:italic;cursor:default;opacity:.75}
.nav-row.is-empty:hover{background:none;color:#8fa3cf}

/* The locker sits a step in from the documents it serves, so it reads as a
   reference shelf rather than a fifth kind of paper. */
.nav-row.nav-locker{margin-top:var(--sp-3);color:#b9c7e6}
.nav-row.nav-locker .mk{opacity:.7}
.nav-row.nav-locker .cnt{margin-left:auto;font-size:var(--fs-tag);color:#9fb0d8}
.nav-row{display:flex;align-items:center;gap:var(--sp-5);padding:var(--sp-4) var(--sp-5);
  border-radius:var(--radius-sm);cursor:pointer;color:#cdd8ee;font-size:var(--fs-ui);
  border:1px solid transparent;user-select:none}
.nav-row:hover{background:#ffffff12;color:#fff}
.nav-row.sel{background:#ffffff1f;color:#fff;border-color:#ffffff26;font-weight:600}
.nav-row .mk{width:16px;flex:0 0 auto;display:grid;place-items:center;opacity:.9}
.nav-row .lbl{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nav-row .val{font-size:var(--fs-tag);color:#9fb0d8;flex:0 0 auto}
.nav-foot{flex:0 0 auto;border-top:1px solid #ffffff1f;padding:var(--sp-5)}

/* ---------- Topbar ------------------------------------------------------ */
/* The bar WRAPS before it clips. overflow:clip on its own silently amputated
   the right-hand group: between roughly 760px and 900px that took Export with
   it — the only way to get a manuscript out of the app — with no scroll to
   bring it back. Wrapping costs a second row at those widths and loses nothing.
   The clip stays as a last resort against a stray unshrinkable child. */
.tb{background:var(--tb-bg);border-bottom:1px solid var(--tb-line);
  padding:var(--sp-5) var(--sp-8);display:flex;align-items:center;gap:var(--sp-6);
  flex-wrap:wrap;row-gap:var(--sp-4);
  overflow:clip;overflow-clip-margin:8px}
.tb-crumb{flex:1 1 0;min-width:0}
.tb-sec{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.08em;color:var(--ink-4);font-weight:700}
.tb-name{font-size:var(--fs-title);font-weight:660;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tb-facts{font-size:var(--fs-cap);color:var(--ink-3);display:flex;gap:var(--sp-5);flex-wrap:wrap}
.tb-facts b{font-weight:640;color:var(--ink-2)}
.tb-style select{font-size:var(--fs-cap);padding:0 var(--sp-3);height:20px;line-height:1;
  border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--surface-2);
  color:var(--ink-2);max-width:120px}
/* The action group wraps internally too. `flex:0 0 auto` made it one
   unshrinkable block, so a single over-wide group still ran past the clip and
   took the last button (Send back, on a co-author copy) off-screen. */
.tb-right{display:flex;align-items:center;gap:var(--sp-6);
  flex:0 1 auto;min-width:0;flex-wrap:wrap;row-gap:var(--sp-4);justify-content:flex-end}
/* Related controls sit together and are separated from the next group by a
   rule, so the bar reads as three decisions rather than six loose buttons. */
.tb-group{display:inline-flex;align-items:center;gap:var(--sp-3)}
.tb-group + .tb-group::before,.tb-group + .btn::before,.tb-group + .btn.primary::before{
  content:"";display:inline-block;width:1px;height:18px;background:var(--line);
  margin-right:var(--sp-5);vertical-align:middle}
/* A control that opens a menu says so. A bare ⋯ gave no reason to press it. */
.tb-car{font-size:9px;opacity:.6;margin-left:1px}
/* Save state. Shape and wording carry it, not colour alone — the tick and the
   word read the same to someone who cannot tell red from grey. */
.save-ind{display:inline-flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-cap);
  color:var(--ink-3);white-space:nowrap}
.save-ind.bad{color:var(--red);font-weight:640}
.save-ind.bad .btn{margin-left:var(--sp-2)}

/* ---------- Buttons / controls ------------------------------------------ */
.btn{
  display:inline-flex;align-items:center;gap:var(--sp-4);
  background:var(--tb-btn-bg);border:1px solid var(--tb-btn-line);color:var(--ink);
  padding:5px 11px;border-radius:var(--radius-sm);cursor:pointer;font-size:var(--fs-ui);
  font-weight:520;line-height:1.35;white-space:nowrap
}
.btn:hover{background:var(--tb-btn-hover)}
.btn:active{background:var(--tb-btn-active)}
.btn[disabled]{opacity:.45;cursor:default;pointer-events:none}
/* The three accent roles in one rule, which is the clearest place to see why
   they have to be three: the fill needs 3:1 against the panel behind it, and
   the label on top needs 4.5:1 against the FILL — which in dark mode means a
   near-black label on a bright button, not white. */
.btn.primary{background:var(--ac-fill);border-color:var(--ac-fill);color:var(--ac-on);font-weight:600}
.btn.primary:hover{background:var(--ac-fill-hover);border-color:var(--ac-fill-hover)}
.btn.danger{background:var(--red-bg);border-color:var(--red-line);color:var(--red);font-weight:600}
.btn.ghost{background:transparent;border-color:transparent;color:var(--ink-2)}
.btn.ghost:hover{background:var(--tb-btn-hover);color:var(--ink)}
.btn.sm{padding:3px 8px;font-size:var(--fs-sm)}
.btn.on{background:var(--surface-sel);border-color:var(--blue);color:var(--ac-ink);font-weight:640}

input[type=text],input[type=email],input[type=number],input[type=date],input[type=search],select,textarea{
  background:var(--input-bg);border:1px solid var(--input-line);border-radius:var(--radius-sm);
  padding:5px 8px;font-size:var(--fs-ui);width:100%
}
textarea{resize:vertical;line-height:1.5}
label.fld{display:block;margin-bottom:var(--sp-6)}
label.fld > span{display:block;font-size:var(--fs-cap);color:var(--ink-2);font-weight:600;margin-bottom:var(--sp-2)}
.row{display:flex;gap:var(--sp-6);flex-wrap:wrap}
.row > *{flex:1 1 160px;min-width:0}
.hint{font-size:var(--fs-cap);color:var(--ink-3)}
.spacer{flex:1 1 auto}

/* ---------- Cards / layout --------------------------------------------- */
.page{padding:var(--sp-12) var(--sp-16);max-width:1180px;margin:0 auto}
.page.wide{max-width:none}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);margin-bottom:var(--sp-12);position:relative}
.card-head{display:flex;align-items:center;gap:var(--sp-6);padding:var(--sp-8) var(--sp-10);
  border-bottom:1px solid var(--line-2)}
.card-head h3{font-size:var(--fs-title)}
.card-body{padding:var(--sp-10)}
.card.collapsed > :not(.card-head){display:none}
.card.collapsed .card-head{border-bottom:0}
.empty{padding:var(--sp-16);text-align:center;color:var(--ink-3);font-size:var(--fs-ui)}

.tag{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-tag);font-weight:650;
  padding:1px 7px;border-radius:999px;border:1px solid var(--line-strong);background:var(--surface-2);color:var(--ink-2)}
.tag.green{background:var(--green-bg);border-color:var(--green-line);color:var(--green)}
.tag.amber{background:var(--amber-bg);border-color:var(--amber-line);color:var(--amber)}
.tag.red{background:var(--red-bg);border-color:var(--red-line);color:var(--red)}
.tag.blue{background:var(--blue-lt);border-color:var(--blue-line);color:var(--ac-ink)}
.tag.purple{background:var(--purple-bg);border-color:var(--purple-line);color:var(--purple)}

.notice{border:1px solid var(--line);border-left:3px solid var(--ink-4);background:var(--surface-2);
  border-radius:var(--radius-sm);padding:var(--sp-6) var(--sp-8);font-size:var(--fs-ui);margin-bottom:var(--sp-8)}
.notice.info{border-left-color:var(--blue);background:var(--blue-lt)}
.notice.warn{border-left-color:var(--amber);background:var(--amber-bg)}
.notice.bad{border-left-color:var(--red);background:var(--red-bg)}
.notice.good{border-left-color:var(--green);background:var(--green-bg)}

table.grid{width:100%;border-collapse:collapse;font-size:var(--fs-ui)}
table.grid th{text-align:left;font-size:var(--fs-cap);text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-3);font-weight:700;padding:var(--sp-4) var(--sp-6);border-bottom:1px solid var(--line-strong)}
table.grid td{padding:var(--sp-5) var(--sp-6);border-bottom:1px solid var(--line-2);vertical-align:top}
table.grid tr:hover td{background:var(--surface-hover)}

/* ---------- Toasts ------------------------------------------------------ */
#toasts{position:fixed;bottom:var(--sp-12);left:50%;transform:translateX(-50%);z-index:8000;
  display:flex;flex-direction:column;gap:var(--sp-4);align-items:center;pointer-events:none}
.toast{background:var(--toast-bg);color:var(--toast-ink);padding:var(--sp-5) var(--sp-10);
  border-radius:999px;font-size:var(--fs-ui);font-weight:560;box-shadow:var(--shadow-lg);
  animation:toastIn .16s ease-out;max-width:70vw}
.toast.bad{background:var(--red);color:#fff}
.toast.good{background:var(--green);color:#fff}
@keyframes toastIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ---------- Modals ------------------------------------------------------ */
.scrim{position:fixed;inset:0;background:rgba(12,18,32,.42);backdrop-filter:blur(2px);
  z-index:7000;display:grid;place-items:center;padding:var(--sp-16)}
.modal{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow-lg);width:min(640px,100%);max-height:86vh;display:flex;flex-direction:column;
  animation:menuIn .14s ease-out}
.modal.lg{width:min(980px,100%)}
.modal.xl{width:min(1240px,100%)}
.modal-head{display:flex;align-items:center;gap:var(--sp-6);padding:var(--sp-8) var(--sp-10);
  border-bottom:1px solid var(--line-2)}
.modal-head h3{font-size:var(--fs-title);flex:1 1 auto}
.modal-body{padding:var(--sp-10);overflow:auto;flex:1 1 auto}
.modal-foot{display:flex;align-items:center;gap:var(--sp-5);padding:var(--sp-8) var(--sp-10);
  border-top:1px solid var(--line-2);justify-content:flex-end}
@keyframes menuIn{from{opacity:0;transform:scale(.98) translateY(-4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.modal,.toast{animation:none}}

/* ---------- Dropdown menus --------------------------------------------- */
.dropmenu{position:fixed;z-index:7500;background:var(--tb-menu-bg);border:1px solid var(--line-strong);
  border-radius:var(--radius-sm);box-shadow:var(--shadow-lg);padding:var(--sp-3);min-width:190px;
  max-height:70vh;overflow:auto;animation:menuIn .12s ease-out}
.dropmenu button{display:flex;align-items:center;gap:var(--sp-5);width:100%;text-align:left;
  background:none;border:0;padding:var(--sp-4) var(--sp-6);border-radius:var(--radius-sm);
  cursor:pointer;font-size:var(--fs-ui);white-space:nowrap}
.dropmenu button:hover{background:var(--surface-hover)}
.dropmenu button.danger{color:var(--red)}
.dropmenu .sep{height:1px;background:var(--line-2);margin:var(--sp-3) 0}
.dropmenu .grp{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.08em;
  color:var(--ink-4);font-weight:700;padding:var(--sp-4) var(--sp-6) var(--sp-2)}

/* ============================================================================
   The manuscript editor
   ========================================================================= */
.ed{display:flex;height:100%;min-height:0}
.ed-outline{width:230px;flex:0 0 auto;border-right:1px solid var(--line);background:var(--surface-2);
  overflow:auto;padding:var(--sp-6)}
.ed-main{flex:1 1 auto;overflow:auto;min-width:0}
.ed-side{width:340px;flex:0 0 auto;border-left:1px solid var(--line);background:var(--surface-2);
  display:none;flex-direction:column;min-width:240px;overflow:hidden}
.ed.show-side .ed-side{display:flex}
.ed-grip{flex:0 0 5px;cursor:col-resize;background:transparent;position:relative;z-index:5}
.ed-grip::after{content:"";position:absolute;inset:0 2px;background:var(--line);opacity:0;transition:opacity .12s}
.ed-grip:hover::after{opacity:1}
@media (max-width:1180px){.ed-outline{display:none}}
@media (max-width:900px){.ed-side,.ed-grip{display:none !important}}

/* ---------- Pane stack ---------------------------------------------------
   One editor in the centre, N read-only viewers on the right. Each pane owns
   its own scroll, so reading Methods in one pane never moves Table 2 in
   another. Panes are viewers by construction: a second editable surface over
   the same blocks would put two carets on one paragraph. */
.pane-head{flex:0 0 auto;display:flex;align-items:center;gap:var(--sp-4);
  padding:var(--sp-4) var(--sp-6);border-bottom:1px solid var(--line);background:var(--surface-2)}
.pane-title{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.09em;
  color:var(--ink-4);font-weight:700;flex:1 1 auto}
.pane-stack{flex:1 1 auto;display:flex;flex-direction:column;overflow:hidden;min-height:0}
.pane{flex:1 1 0;display:flex;flex-direction:column;min-height:0;
  border-bottom:1px solid var(--line)}
.pane:last-child{border-bottom:0}
.pane[data-collapsed]{flex:0 0 auto}
.pane[data-collapsed] .pane-body{display:none}
.pane-bar{flex:0 0 auto;display:flex;align-items:center;gap:var(--sp-2);
  padding:var(--sp-3) var(--sp-4);background:var(--surface-3);border-bottom:1px solid var(--line-2)}
.pane-fold{background:none;border:0;cursor:pointer;color:var(--ink-3);width:18px;
  font-size:var(--fs-cap);padding:0;line-height:1}
.pane-pick{flex:1 1 auto;min-width:0;font-size:var(--fs-sm);padding:2px 6px;
  border-color:var(--line-strong);background:var(--panel)}
.pane-body{flex:1 1 auto;overflow:auto;min-height:0}
.pv{padding:var(--sp-6) var(--sp-8);font-family:var(--doc-font);font-size:14px;line-height:1.6}
.pv-p{margin:0 0 var(--sp-6)}
.pv-h2{font-family:var(--ui-font);font-size:14px;font-weight:680;margin:var(--sp-8) 0 var(--sp-3)}
.pv-h3{font-family:var(--ui-font);font-size:12px;font-weight:700;text-transform:uppercase;
  letter-spacing:.05em;color:var(--ink-2);margin:var(--sp-7) 0 var(--sp-2)}
.pv-meta{padding:var(--sp-4) var(--sp-8);font-size:var(--fs-cap);color:var(--ink-3);
  border-bottom:1px solid var(--line-2);background:var(--surface-2)}
.pane-body .tblbox{margin:var(--sp-6) var(--sp-6) 0}
.pane-body .figbox{margin:var(--sp-6)}
.pane-body .cap{padding:0 var(--sp-8) var(--sp-6)}

.out-row{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-4) var(--sp-5);
  border-radius:var(--radius-sm);cursor:pointer;font-size:var(--fs-sm);color:var(--ink-2);user-select:none}
.out-row:hover{background:var(--surface-hover)}
.out-row.sel{background:var(--surface-sel);color:var(--ac-ink);font-weight:640}
.out-row .n{width:18px;text-align:right;color:var(--ink-4);font-size:var(--fs-cap);flex:0 0 auto}
.out-row .lbl{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.out-row .wc{font-size:var(--fs-micro);color:var(--ink-4);flex:0 0 auto}
.out-row .wc.over{color:var(--red);font-weight:700}
.out-row.drag{opacity:.45}
.out-row.drop-before{box-shadow:inset 0 2px 0 var(--blue)}
.out-row.drop-after{box-shadow:inset 0 -2px 0 var(--blue)}

/* The paper. A manuscript section is a sheet, not a form field. */
/* The writing surface runs the full width between the outline and the viewers,
   with only a hair of separation — the measure is controlled by the sheet's own
   generous side padding rather than by a narrow column. */
.sheetwrap{padding:4px 4px 40vh;display:flex;flex-direction:column;align-items:stretch}
.sheetbox{width:100%;display:flex;flex-direction:column;margin-bottom:var(--sp-6)}
.sheet{background:var(--paper);color:var(--paper-ink);border:1px solid var(--paper-line);
  border-radius:8px;box-shadow:0 1px 3px var(--paper-shadow);width:100%;
  padding:var(--sp-16) 56px var(--sp-16)}
.sheet.narrow{width:100%}
/* Justified body text. The alignment lives on the block MODEL and this class
   is applied at render — never written into the stored HTML, which the
   sanitiser would strip. */
.bd.just{text-align:justify;text-justify:inter-word}

/* The citations for this section, in their own bubble UNDER the sheet — the
   footnote strip you glance at while writing. Never the document's own
   typography: it is apparatus, not text on the page, and it must not read as
   part of the manuscript. Open by default, because the whole point is not
   having to go and ask for it. */
.citefoot{margin-top:6px;background:var(--surface-2);border:1px solid var(--line);
  border-radius:10px;padding:0 var(--sp-8) var(--sp-2);
  font-family:var(--ui-font);font-size:var(--fs-sm)}
.cf-head{display:flex;align-items:center;gap:var(--sp-4);width:100%;background:none;border:0;
  padding:var(--sp-6) 0 var(--sp-4);cursor:pointer;color:var(--ink-3);
  font:inherit;font-weight:650;text-align:left}
.citefoot:not(.closed) .cf-head{border-bottom:1px solid var(--line-2)}
.cf-head:hover{color:var(--ink-2)}
.cf-caret{width:12px;display:inline-block;color:var(--ink-4)}
.cf-count{margin-left:auto;font-variant-numeric:tabular-nums;color:var(--ink-4);font-weight:600}
.cf-list{padding-bottom:var(--sp-4)}
.cf-row{display:flex;gap:var(--sp-5);align-items:flex-start;padding:var(--sp-3) 0;
  line-height:1.45;color:var(--ink-2)}
.cf-row + .cf-row{border-top:1px solid var(--line-2)}
.cf-n{flex:0 0 22px;text-align:right;font-variant-numeric:tabular-nums;font-weight:700;
  color:var(--ink-3)}
.cf-t{flex:1 1 auto;min-width:0}
.cf-row .btn{flex:0 0 auto;opacity:0;padding:0 5px}
.cf-row:hover .btn,.cf-row:focus-within .btn{opacity:1}
.cf-missing .cf-t{color:var(--red)}

/* The cite-a-reference picker: one search box over this paper, your library
   and a bare DOI/PMID. Keyboard-first, so the selected row is a real state
   and not just a hover. */
.pc-list{max-height:46vh;overflow:auto;border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--surface-2)}
.pc-row{display:flex;gap:var(--sp-5);align-items:flex-start;width:100%;text-align:left;
  background:none;border:0;border-bottom:1px solid var(--line-2);padding:var(--sp-5) var(--sp-6);
  cursor:pointer;font:inherit;font-size:var(--fs-sm);color:var(--ink-2);line-height:1.45}
.pc-row:last-child{border-bottom:0}
.pc-row:hover{background:var(--surface-hover)}
.pc-row.on{background:var(--surface-sel);color:var(--ink)}
.pc-n{flex:0 0 26px;text-align:right;font-variant-numeric:tabular-nums;font-weight:700;
  color:var(--ink-3)}
.pc-tag{flex:0 0 auto;font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.07em;
  font-weight:700;color:var(--ink-4);border:1px solid var(--line);border-radius:999px;
  padding:1px 6px;margin-top:1px}
.pc-tag.pc-new{color:var(--ac-ink);border-color:var(--ac-fill)}
.pc-t{flex:1 1 auto;min-width:0}

/* ---------- Conference abstracts ---------------------------------------- */
/* Everything that governs an abstract — the meeting, the deadline, the limit
   and how much of it is spent — sits on the page you are typing on. The
   number is the whole job, so it is never behind a menu. */
.abs-wrap{height:100%;overflow:auto}
.abs-main{max-width:900px;margin:0 auto;padding:var(--sp-10) var(--sp-12) 60px}
.abs-head .card-body{padding-bottom:var(--sp-6)}
.abs-meter{display:flex;align-items:center;gap:var(--sp-6);margin-top:var(--sp-4)}
.abs-bar{flex:1 1 auto;height:6px;border-radius:999px;background:var(--line-2);overflow:hidden}
.abs-bar-fill{height:100%;width:0;background:var(--ink-4);border-radius:999px;
  transition:width .15s ease}
.abs-bar-fill.good{background:var(--green)}
.abs-bar-fill.warn{background:var(--amber)}
.abs-bar-fill.bad{background:var(--red)}
.abs-count{flex:0 0 auto;font-size:var(--fs-ui);color:var(--ink-3);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.abs-count b{color:var(--ink);font-weight:700}
.abs-count.bad,.abs-count.bad b{color:var(--red)}
.abs-count.warn b{color:var(--amber)}
.abs-over{color:var(--red);font-weight:700}
.abs-left{color:var(--ink-4)}
/* The sheet inside an abstract is short: no page furniture, just the text. */
.abs-main .sheet{width:100%;padding:var(--sp-12) var(--sp-16)}
.sh-head{display:flex;align-items:baseline;gap:var(--sp-6);border-bottom:1px solid var(--paper-rule);
  padding-bottom:var(--sp-6);margin-bottom:var(--sp-10)}
.sh-kind{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.1em;color:var(--ink-4);font-weight:700}
.sh-title{font-size:19px;font-weight:680;font-family:var(--ui-font);letter-spacing:-.015em;flex:1 1 auto}
.sh-count{font-size:var(--fs-cap);color:var(--ink-3);font-variant-numeric:tabular-nums}
.sh-count.over{color:var(--red);font-weight:700}

/* Blocks. Every block carries a durable id in data-bid — the whole tracked-change,
   comment-anchor and sync model hangs off it, so it must never be regenerated. */
.blk{position:relative;margin:0 0 var(--sp-8);padding:2px 0 2px 0;border-radius:4px}
.blk .bd{font-family:var(--doc-font);font-size:16px;line-height:1.7;outline:none;
  min-height:1.7em;white-space:pre-wrap;word-wrap:break-word}
.blk[data-t="h2"] .bd{font-family:var(--ui-font);font-size:17px;font-weight:680;line-height:1.35}
.blk[data-t="h3"] .bd{font-family:var(--ui-font);font-size:14.5px;font-weight:680;
  text-transform:uppercase;letter-spacing:.05em;line-height:1.35;color:var(--ink-2)}
.blk[data-t="ul"] .bd,.blk[data-t="ol"] .bd{padding-left:22px}
.blk[data-t="quote"] .bd{border-left:3px solid var(--paper-line);padding-left:14px;color:var(--ink-2);font-style:italic}
.blk .bd:empty::before{content:attr(data-ph);color:var(--ink-4);font-style:italic;pointer-events:none}
.blk.focus{background:color-mix(in srgb,var(--surface-sel) 55%,transparent)}
.blk-gut{position:absolute;left:-38px;top:2px;width:30px;display:flex;flex-direction:column;
  align-items:flex-end;gap:2px;opacity:0;transition:opacity .1s}
.blk:hover .blk-gut,.blk.focus .blk-gut{opacity:1}
.blk-gut button{background:none;border:0;cursor:pointer;color:var(--ink-4);font-size:var(--fs-cap);
  padding:1px 3px;border-radius:4px;line-height:1}
.blk-gut button:hover{background:var(--surface-hover);color:var(--ink)}
.blk.locked{background:var(--amber-bg);outline:1px dashed var(--amber-line)}
.blk-lock{position:absolute;right:-6px;top:-14px;font-size:var(--fs-micro);font-weight:700;
  background:var(--amber);color:#fff;padding:1px 6px;border-radius:999px}

/* Tracked changes, coloured by author. */
ins.tc{text-decoration:none;border-bottom:1.5px solid currentColor;background:var(--tc-bg,transparent);color:var(--tc-ink,var(--au-1))}
del.tc{text-decoration:line-through;opacity:.75;color:var(--tc-ink,var(--au-1))}
.tc-hidden ins.tc{border-bottom:0;background:none;color:inherit}
.tc-hidden del.tc{display:none}
.cmt-mark{background:var(--amber-bg);box-shadow:inset 0 -2px 0 var(--amber);cursor:pointer;border-radius:2px}
.cmt-mark.sel{background:var(--amber);color:#fff;box-shadow:none}
.cmt-mark.resolved{background:transparent;box-shadow:inset 0 -1px 0 var(--line-strong)}
.sp-bad{background:linear-gradient(transparent 88%,var(--red) 88%,var(--red) 96%,transparent 96%);cursor:pointer}
.gr-bad{background:linear-gradient(transparent 88%,var(--blue) 88%,var(--blue) 96%,transparent 96%);cursor:pointer}

/* Comment rail */
.cmt{border:1px solid var(--line);background:var(--panel);border-radius:var(--radius-sm);
  padding:var(--sp-6);margin:0 var(--sp-6) var(--sp-6);font-size:var(--fs-sm)}
.cmt.sel{border-color:var(--blue);box-shadow:0 0 0 2px var(--blue-lt)}
.cmt.resolved{opacity:.58}
.cmt-top{display:flex;align-items:center;gap:var(--sp-4);margin-bottom:var(--sp-4)}
.cmt-who{font-weight:660}
.cmt-when{font-size:var(--fs-micro);color:var(--ink-4);margin-left:auto}
.cmt-quote{font-size:var(--fs-cap);color:var(--ink-3);border-left:2px solid var(--amber);
  padding-left:var(--sp-5);margin-bottom:var(--sp-4);font-style:italic}
.cmt-body{white-space:pre-wrap}
.cmt-reply{margin-top:var(--sp-5);padding-top:var(--sp-5);border-top:1px solid var(--line-2)}
/* No `color` here on purpose: people.avatarHtml sets the paired --au-N-bg ink
   inline alongside the background, because only the pair is guaranteed 4.5:1 in
   BOTH themes. A default of #fff lived here and was unreadable in dark. */
.avatar{width:20px;height:20px;border-radius:999px;display:grid;place-items:center;flex:0 0 auto;
  font-size:var(--fs-micro);font-weight:800;letter-spacing:-.02em}
.avatar.has-photo{background:var(--surface-3);overflow:hidden}
.avatar.has-photo img{width:100%;height:100%;object-fit:cover;display:block}

/* Profile identity block in Settings */
.me-id{display:flex;gap:var(--sp-4);align-items:center;margin-bottom:var(--sp-4)}
.me-id-txt{min-width:0}
.me-photo{position:relative;width:56px;height:56px;border-radius:999px;padding:0;flex:0 0 auto;
  border:1px solid var(--line);background:var(--surface-3);cursor:pointer;overflow:hidden;display:block}
.me-photo:hover{border-color:var(--ac-fill)}
.me-photo img,.me-photo .me-mono{width:100%;height:100%;display:block;object-fit:cover}
.me-photo .me-mono{display:grid;place-items:center;color:#fff;font-weight:800;font-size:var(--fs-lead)}
.me-photo-cam{position:absolute;right:-1px;bottom:-1px;width:20px;height:20px;border-radius:999px;
  background:var(--ac-fill);color:#fff;display:grid;place-items:center;font-size:11px;
  border:2px solid var(--surface-2)}

/* Side panel tabs */
.sp-tabs{display:flex;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--surface-2);z-index:2}
.sp-tabs button{flex:1 1 0;background:none;border:0;border-bottom:2px solid transparent;
  padding:var(--sp-6) var(--sp-4);cursor:pointer;font-size:var(--fs-sm);font-weight:600;color:var(--ink-3)}
.sp-tabs button.on{color:var(--ac-ink);border-bottom-color:var(--ac-ink)}
.sp-body{padding:var(--sp-6) 0}

/* Diff view */
.diff{font-family:var(--doc-font);font-size:15px;line-height:1.7}
.diff ins{background:var(--green-bg);color:var(--green);text-decoration:none}
.diff del{background:var(--red-bg);color:var(--red)}
.diffcols{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-10)}
@media (max-width:900px){.diffcols{grid-template-columns:1fr}}

/* Tables & figures */
.tblbox{overflow-x:auto;border:1px solid var(--paper-line);border-radius:var(--radius-sm)}
table.mstable{border-collapse:collapse;width:100%;font-size:13px;font-family:var(--ui-font)}
table.mstable th,table.mstable td{border:1px solid var(--paper-line);padding:5px 8px;text-align:left;vertical-align:top}
table.mstable th{background:var(--surface-2);font-weight:660}
table.mstable td.num,table.mstable th.num{text-align:right;font-variant-numeric:tabular-nums}
.figbox{border:1px solid var(--paper-line);border-radius:var(--radius-sm);padding:var(--sp-6);
  background:var(--surface-3);text-align:center}
.figbox img{max-width:100%;height:auto;border-radius:4px}
.cap{font-size:var(--fs-sm);color:var(--ink-2);margin-top:var(--sp-5);text-align:left;line-height:1.5}
.cap b{color:var(--ink)}

/* PDF reader (peer review) */
.rvwrap{display:flex;height:100%;min-height:0}
.rv-pdf{flex:1 1 55%;background:var(--frame-bg);overflow:auto;padding:var(--sp-8);min-width:0}
.rv-pdf canvas{display:block;margin:0 auto var(--sp-8);max-width:100%;box-shadow:var(--shadow-lg);background:#fff}
.rv-form{flex:1 1 45%;overflow:auto;min-width:0;background:var(--bg)}
.pdftools{position:sticky;top:0;z-index:3;background:var(--tb-bg);border-bottom:1px solid var(--tb-line);
  padding:var(--sp-4) var(--sp-6);display:flex;align-items:center;gap:var(--sp-4);margin:calc(var(--sp-8) * -1) calc(var(--sp-8) * -1) var(--sp-8)}

/* Checklists */
.ck-row{display:flex;gap:var(--sp-6);padding:var(--sp-5) var(--sp-6);border-bottom:1px solid var(--line-2);
  align-items:flex-start;font-size:var(--fs-ui)}
.ck-row:hover{background:var(--surface-hover)}
.ck-no{width:34px;flex:0 0 auto;color:var(--ink-4);font-size:var(--fs-cap);font-weight:700;padding-top:2px}
.ck-txt{flex:1 1 auto;min-width:0}
.ck-st{flex:0 0 auto;display:flex;gap:2px}
.ck-st button{border:1px solid var(--line-strong);background:var(--panel);width:26px;height:22px;
  border-radius:4px;cursor:pointer;font-size:var(--fs-cap);line-height:1;padding:0}
.ck-st button.on[data-v="y"]{background:var(--green-bg);border-color:var(--green);color:var(--green);font-weight:800}
.ck-st button.on[data-v="p"]{background:var(--amber-bg);border-color:var(--amber);color:var(--amber);font-weight:800}
.ck-st button.on[data-v="n"]{background:var(--red-bg);border-color:var(--red);color:var(--red);font-weight:800}
.ck-st button.on[data-v="na"]{background:var(--surface-sel);border-color:var(--blue);color:var(--ac-ink);font-weight:800}

/* Portal-paste block: the text that gets copied into ScholarOne / Editorial Manager */
.paste{font:12.5px/1.6 var(--mono);white-space:pre-wrap;background:var(--surface-3);
  border:1px solid var(--line);border-radius:var(--radius-sm);padding:var(--sp-8);max-height:420px;overflow:auto}

/* Audit trail */
.aud{font-size:var(--fs-sm);display:grid;grid-template-columns:auto auto 1fr auto;gap:var(--sp-3) var(--sp-6);
  align-items:baseline}
.aud .t{color:var(--ink-4);font-variant-numeric:tabular-nums;font-size:var(--fs-cap);white-space:nowrap}
.aud .w{font-weight:640;white-space:nowrap}
.aud .d{color:var(--ink-2);min-width:0}
.aud .s{color:var(--ink-4);font-size:var(--fs-cap);white-space:nowrap}

/* ---------- Print ------------------------------------------------------- */
@media print{
  body{overflow:visible;background:#fff}
  #app,#toasts,#modals,#boot{display:none !important}
  #printRoot{display:block !important}
}
#printRoot{display:none}

/* ---------- Lint marks -------------------------------------------------
   Painted with the CSS Custom Highlight API over live Ranges, so the checker
   never writes a <span> into the paragraph — nothing it does can reach the
   saved HTML, the diff, or the .docx. Where the API is missing these rules
   simply never match and the side panel still lists every issue. */
::highlight(ms-spell){
  text-decoration:underline wavy var(--red);
  text-decoration-skip-ink:none;
  text-underline-offset:3px;
}
::highlight(ms-grammar){
  text-decoration:underline wavy var(--blue);
  text-decoration-skip-ink:none;
  text-underline-offset:3px;
}

/* Placeholder for a stub changelog before sync-app.sh generates the real one. */
.card-body code{font:var(--fs-sm)/1.4 var(--mono);background:var(--surface-2);
  padding:1px 4px;border-radius:3px}

/* ============================================================================
   Citation library — three columns: collections, hits, the selected record.
   The shape every reference manager converges on, because it is the one that
   lets you search, file and read without losing your place in any of the three.
   ========================================================================= */
.cite{display:flex;height:100%;min-height:0}
.cite-side{width:230px;flex:0 0 auto;border-right:1px solid var(--line);
  background:var(--surface-2);overflow:auto;padding:var(--sp-6) 0}
.cite-list{width:380px;flex:0 0 auto;border-right:1px solid var(--line);
  display:flex;flex-direction:column;min-width:0;overflow:hidden}
.cite-detail{flex:1 1 auto;overflow:auto;min-width:0;background:var(--panel)}
@media (max-width:1200px){.cite-side{display:none}}
/* Below 860px the three columns will not fit, so the record used to be
   display:none — which quietly removed every per-record action (edit, PDF,
   copy, add-to-manuscript) with no way to reach them. Stack instead of delete:
   the list sits on top, the selected record reads underneath, and both keep
   their own scroll. Nothing becomes unreachable, it just becomes taller. */
@media (max-width:860px){
  .cite{flex-direction:column}
  .cite-list{flex:0 0 auto;width:auto;max-height:45%;border-right:0;
    border-bottom:1px solid var(--line)}
  .cite-detail{flex:1 1 auto;min-height:0}
}

.cite-sec{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.09em;
  color:var(--ink-4);font-weight:700;padding:var(--sp-8) var(--sp-6) var(--sp-3);
  display:flex;align-items:center;gap:var(--sp-3)}
.cite-sec .btn{margin-left:auto;padding:0 5px}
.cite-row{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-3) var(--sp-6);
  cursor:pointer;font-size:var(--fs-ui);color:var(--ink-2);border-radius:var(--radius-sm);
  margin:0 var(--sp-3)}
.cite-row:hover{background:var(--surface-hover)}
.cite-row.sel{background:var(--surface-sel);color:var(--ac-ink);font-weight:640}
.cite-row .lbl{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cite-row .n{font-size:var(--fs-micro);color:var(--ink-4);flex:0 0 auto}

.cite-bar{flex:0 0 auto;display:flex;gap:var(--sp-4);align-items:center;
  padding:var(--sp-5) var(--sp-6);border-bottom:1px solid var(--line);background:var(--tb-bg)}
.cite-bar input[type=search]{flex:1 1 auto;min-width:0}
.cite-bar select{width:auto;flex:0 0 auto}
.cite-scroll{flex:1 1 auto;overflow:auto;min-height:0}

.cite-item{padding:var(--sp-6) var(--sp-8);border-bottom:1px solid var(--line-2);cursor:pointer}
.cite-item:hover{background:var(--surface-hover)}
.cite-item.sel{background:var(--surface-sel);box-shadow:inset 3px 0 0 var(--ac-fill)}
.ci-top{display:flex;align-items:center;gap:var(--sp-4);margin-bottom:2px}
.ci-au{font-size:var(--fs-ui);font-weight:660;color:var(--ink)}
.ci-yr{font-size:var(--fs-cap);color:var(--ink-3);font-variant-numeric:tabular-nums}
.ci-fav{color:var(--amber)}
.ci-ti{font-size:var(--fs-ui);line-height:1.4;color:var(--ink);margin-bottom:2px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ci-jo{font-size:var(--fs-cap);color:var(--ink-3);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

.cd-head{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-5) var(--sp-8);
  border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--panel);z-index:2}
.cd-body{padding:var(--sp-8) var(--sp-10) 60px}
.cd-cite{font-family:var(--doc-font);font-size:15px;line-height:1.6;
  padding-bottom:var(--sp-8);border-bottom:1px solid var(--line-2)}
.cd-actions{display:flex;gap:var(--sp-4);flex-wrap:wrap;align-items:center;margin:var(--sp-8) 0}
.cd-actions select{width:auto;max-width:220px}
.cd-actions a.btn{text-decoration:none}
.cd-sec{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.09em;
  color:var(--ink-4);font-weight:700;margin:var(--sp-10) 0 var(--sp-4)}
.cd-chips{display:flex;flex-wrap:wrap;gap:var(--sp-3)}
table.cd-fields td{padding:var(--sp-3) var(--sp-5);font-size:var(--fs-ui)}
table.cd-fields td.k{width:110px;color:var(--ink-3);font-weight:600}

/* ============================================================================
   Formatting toolbar + whole-document view
   ========================================================================= */
.edwrap{display:flex;flex-direction:column;height:100%;min-height:0}
.edsurface{flex:1 1 auto;overflow:auto;min-height:0}
.fmtbar{flex:0 0 auto;display:flex;align-items:center;gap:2px;flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-6);background:var(--tb-bg);
  border-bottom:1px solid var(--tb-line);position:sticky;top:0;z-index:6}
.fmtbar .tbb{background:var(--tb-btn-bg);border:1px solid transparent;color:var(--ink);
  min-width:28px;height:26px;border-radius:var(--radius-sm);cursor:pointer;
  font-size:var(--fs-ui);line-height:1;padding:0 6px;display:inline-flex;
  align-items:center;justify-content:center}
.fmtbar .tbb:hover{background:var(--tb-btn-hover);border-color:var(--tb-btn-line)}
.fmtbar .tbb.on{background:var(--surface-sel);border-color:var(--blue);color:var(--ac-ink)}
.fmtbar .tbsel{width:auto;min-width:120px;font-size:var(--fs-sm);padding:3px 6px;
  background:var(--tb-btn-bg);border-color:var(--tb-btn-line)}
.fmtbar .tbsep{width:1px;height:18px;background:var(--tb-sep);margin:0 var(--sp-3)}
.fmtbar .tbstate{font-size:var(--fs-cap);color:var(--ink-3);padding-right:var(--sp-4)}
.fmtbar mark,.paste mark{background:var(--amber-bg);color:var(--amber);border-radius:2px}

/* Whole-document view: the sections run continuously, each still its own sheet
   so you can see where one ends and the next begins. */
.wholehead{width:100%;margin:0 auto var(--sp-8);text-align:center}
.wh-title{font-size:20px;font-weight:680;letter-spacing:-.015em;color:var(--ink)}
.wh-meta{font-size:var(--fs-cap);color:var(--ink-3);margin-top:var(--sp-2)}
.sheet.cont{margin-bottom:var(--sp-12)}
.sheet.cont .sh-head{position:sticky;top:0;background:var(--paper);z-index:3;
  padding-top:var(--sp-6);margin-top:calc(var(--sp-16) * -1 + var(--sp-6))}

/* ============================================================================
   Compare and merge returned versions
   ========================================================================= */
.vstrip{display:flex;gap:var(--sp-6);flex-wrap:wrap}
.vcard{flex:1 1 190px;min-width:170px;border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:var(--sp-6);background:var(--surface-2)}
.vcard.base{background:var(--blue-lt);border-color:var(--blue-line)}
.vcard.off{opacity:.5}
.vname{font-weight:660;font-size:var(--fs-ui);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vmeta{font-size:var(--fs-cap);color:var(--ink-3);margin-top:2px;line-height:1.4}
.vacts{display:flex;gap:2px;margin-top:var(--sp-4)}

.mrows{display:flex;flex-direction:column;gap:var(--sp-6)}
.mrow{border:1px solid var(--line);border-radius:var(--radius);background:var(--panel);
  box-shadow:var(--shadow);overflow:hidden}
.mrow.changed{border-left:3px solid var(--amber)}
.mrow.conflict{border-left:3px solid var(--red)}
.mhead{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-4) var(--sp-8);
  border-bottom:1px solid var(--line-2);background:var(--surface-2)}
.mno{font-size:var(--fs-cap);font-weight:700;color:var(--ink-4);font-variant-numeric:tabular-nums}
.mcols{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:1px;
  background:var(--line-2)}
.mcol{background:var(--panel);padding:var(--sp-6) var(--sp-8);display:flex;flex-direction:column;gap:var(--sp-4)}
.mcol.picked{background:var(--surface-sel);box-shadow:inset 0 0 0 2px var(--blue)}
.mwho{font-size:var(--fs-cap);font-weight:700;color:var(--ink-2);text-transform:uppercase;
  letter-spacing:.05em;display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.mtext{font-family:var(--doc-font);font-size:14px;line-height:1.6;flex:1 1 auto}
.mtext.diff ins{background:var(--green-bg);color:var(--green);text-decoration:none}
.mtext.diff del{background:var(--red-bg);color:var(--red)}
.mcmt{font-size:var(--fs-sm);background:var(--amber-bg);border-left:2px solid var(--amber);
  padding:var(--sp-4) var(--sp-5);border-radius:0 var(--radius-sm) var(--radius-sm) 0}
.mcol .btn{align-self:flex-start}

/* The whole-manuscript viewer pane: the rest of the paper always to hand, with
   the section you are editing marked so clicking through the outline never
   loses your place. */
.wp-sec{border-bottom:1px solid var(--line-2);padding-bottom:var(--sp-6)}
.wp-sec:last-child{border-bottom:0}
.wp-sec.here{background:var(--surface-sel);box-shadow:inset 3px 0 0 var(--ac-fill)}
.wp-head{position:sticky;top:0;z-index:1;background:var(--surface-2);
  display:flex;align-items:center;gap:var(--sp-4);
  padding:var(--sp-4) var(--sp-8);font-family:var(--ui-font);
  font-size:var(--fs-cap);font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  color:var(--ink-2);border-bottom:1px solid var(--line-2);margin-bottom:var(--sp-5)}
.wp-sec.here .wp-head{background:var(--surface-sel);color:var(--ac-ink)}
.wp-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wp-wc{margin-left:auto;font-weight:600;letter-spacing:0;color:var(--ink-4);
  font-variant-numeric:tabular-nums;flex:0 0 auto}
.wp .pv-p,.wp .pv-h2,.wp .pv-h3{padding-left:var(--sp-8);padding-right:var(--sp-8)}
.wp-empty{padding:0 var(--sp-8) var(--sp-4);font-size:var(--fs-cap);color:var(--ink-4);font-style:italic}

/* ============================================================================
   APPEARANCE
   Seeds are data-* attributes on <html>; each block below supplies the role
   tokens the rest of the stylesheet consumes. Three namespaces, never mixed:

     --ac-* / --ui-* / --rail-*   screen furniture
     --srf-*                      the writing surface as seen on screen
     --doc-*                      what the exporter reads — written by nothing
                                  in here, and read by nothing outside .sheet

   No block below sets a --doc-* value. That is the property that stops an
   appearance setting from changing a manuscript you have already submitted.
   ========================================================================= */

/* ---------- Accent, five roles ------------------------------------------
   fill  solid backgrounds        3:1 vs the panel behind it
   on    text ON the fill         4.5:1 vs the fill  (inverts in dark mode)
   ink   the accent AS TEXT       4.5:1 vs the panel
   edge  1px borders/underlines   3:1 vs the panel
   wash  tint behind a hot row    --ink on top of it must still clear 4.5:1  */
:root{
  --ac-fill:#012169; --ac-fill-hover:#0b2f7e; --ac-on:#ffffff;
  --ac-ink:#012169;  --ac-edge:#5c78bd;       --ac-wash:#eef2fc;
}
:root[data-accent="navy"]{--ac-fill:#012169;--ac-fill-hover:#0b2f7e;--ac-on:#fff;--ac-ink:#012169;--ac-edge:#5c78bd;--ac-wash:#eef2fc}
:root[data-accent="blue"]{--ac-fill:#1b5fbf;--ac-fill-hover:#154b99;--ac-on:#fff;--ac-ink:#154b99;--ac-edge:#5b8ad6;--ac-wash:#eaf1fc}
:root[data-accent="teal"]{--ac-fill:#0e6a6b;--ac-fill-hover:#0a5354;--ac-on:#fff;--ac-ink:#0a5354;--ac-edge:#3e9596;--ac-wash:#e8f5f5}
:root[data-accent="bronze"]{--ac-fill:#8a5a1b;--ac-fill-hover:#734a14;--ac-on:#fff;--ac-ink:#734a14;--ac-edge:#b28248;--ac-wash:#faf1e4}
:root[data-accent="plum"]{--ac-fill:#6b3fa0;--ac-fill-hover:#57318a;--ac-on:#fff;--ac-ink:#57318a;--ac-edge:#9470c4;--ac-wash:#f3eefa}
:root[data-accent="ember"]{--ac-fill:#a8431f;--ac-fill-hover:#8f3617;--ac-on:#fff;--ac-ink:#8f3617;--ac-edge:#c06a44;--ac-wash:#fcf1ec}
:root[data-accent="forest"]{--ac-fill:#1f6b3a;--ac-fill-hover:#17542d;--ac-on:#fff;--ac-ink:#17542d;--ac-edge:#4f9468;--ac-wash:#eaf5ee}
:root[data-accent="graphite"]{--ac-fill:#3d4757;--ac-fill-hover:#2f3846;--ac-on:#fff;--ac-ink:#2f3846;--ac-edge:#78849a;--ac-wash:#eef0f4}

/* Dark mode is NOT the light palette dimmed. The fill goes bright so it stays
   findable on a dark panel, which forces the label on it to go near-black. */
:root[data-theme="dark"][data-accent="navy"]{--ac-fill:#7d9df0;--ac-fill-hover:#93aef5;--ac-on:#0a1020;--ac-ink:#a8bdf7;--ac-edge:#3f5390;--ac-wash:#161d2e}
:root[data-theme="dark"][data-accent="blue"]{--ac-fill:#6fa8f5;--ac-fill-hover:#87b8f8;--ac-on:#06101f;--ac-ink:#9cc4fa;--ac-edge:#3a6099;--ac-wash:#121f30}
:root[data-theme="dark"][data-accent="teal"]{--ac-fill:#3fbfbf;--ac-fill-hover:#5bcece;--ac-on:#04201f;--ac-ink:#6fd8d6;--ac-edge:#2a7b7b;--ac-wash:#0f2222}
:root[data-theme="dark"][data-accent="bronze"]{--ac-fill:#d9a05a;--ac-fill-hover:#e3b273;--ac-on:#1e1305;--ac-ink:#e8bb80;--ac-edge:#8f6a34;--ac-wash:#241c0f}
:root[data-theme="dark"][data-accent="plum"]{--ac-fill:#a97fe0;--ac-fill-hover:#bb96e8;--ac-on:#140a22;--ac-ink:#c6a8f2;--ac-edge:#6b4a9c;--ac-wash:#1d1629}
:root[data-theme="dark"][data-accent="ember"]{--ac-fill:#d5642f;--ac-fill-hover:#e07a48;--ac-on:#1a0e07;--ac-ink:#e8875a;--ac-edge:#a85630;--ac-wash:#241612}
:root[data-theme="dark"][data-accent="forest"]{--ac-fill:#5fc384;--ac-fill-hover:#7ad09a;--ac-on:#04190c;--ac-ink:#8bd8a6;--ac-edge:#2f7a4b;--ac-wash:#0f2216}
:root[data-theme="dark"][data-accent="graphite"]{--ac-fill:#9aa7bb;--ac-fill-hover:#aeb9ca;--ac-on:#0d1119;--ac-ink:#b8c3d4;--ac-edge:#5a6577;--ac-wash:#181d26}

/* The existing vocabulary now derives from the accent roles, so every rule in
   the stylesheet above follows the palette without being touched. */
:root{
  --navy:var(--ac-ink); --navy-2:var(--ac-fill-hover);
  --blue:var(--ac-edge); --blue-lt:var(--ac-wash); --blue-line:var(--ac-edge);
  --surface-sel:var(--ac-wash); --on-accent:var(--ac-on);
}

/* ---------- Chrome tone --------------------------------------------------
   Independent of light/dark on purpose: the classic workstation look is a deep
   rail beside a white page IN A LIGHT APP, which a light/dark switch alone
   cannot express. */
:root[data-chrome="ink"]{--nav-fill:#0e1c33;--nav-edge:#0a1526;--nav-ink:#dbe3f5;--nav-ink-dim:#8fa3cf}
:root[data-chrome="slate"]{--nav-fill:#2b3444;--nav-edge:#222a38;--nav-ink:#e2e7f0;--nav-ink-dim:#9aa6ba}
:root[data-chrome="paper"]{--nav-fill:#f2f4f8;--nav-edge:#dde2ea;--nav-ink:#26303f;--nav-ink-dim:#68748a}
:root[data-theme="dark"][data-chrome="paper"]{--nav-fill:#171d28;--nav-edge:#232b38;--nav-ink:#dfe4ec;--nav-ink-dim:#8e99ab}
:root[data-theme="dark"][data-chrome="slate"]{--nav-fill:#111722;--nav-edge:#1b2230;--nav-ink:#dfe4ec;--nav-ink-dim:#8e99ab}
#sidebar{background:var(--nav-fill);border-right-color:var(--nav-edge);color:var(--nav-ink)}
.nav-title{color:var(--nav-ink)}
.nav-sub,.nav-sec-head,.nav-row .val{color:var(--nav-ink-dim)}
.nav-row{color:var(--nav-ink)}
.nav-mark{background:rgba(127,127,127,.18);color:var(--nav-ink)}
:root[data-chrome="paper"] .nav-row:hover{background:rgba(0,0,0,.05)}
:root[data-chrome="paper"] .nav-row.sel{background:var(--ac-wash);color:var(--ac-ink);border-color:var(--ac-edge)}
:root[data-chrome="paper"] .nav-foot{border-top-color:var(--nav-edge)}

/* ---------- Density — CHROME ONLY ---------------------------------------
   Density must never reach the sheet. The moment the writing surface's metrics
   move, the on-screen preview stops matching the exported file and the writer
   has no way to know. */
:root{--ui-scale:1;--ui-row:1;--ui-fs:1}
:root[data-density="compact"]{--ui-scale:.82;--ui-row:.84;--ui-fs:.94}
:root[data-density="roomy"]{--ui-scale:1.22;--ui-row:1.2;--ui-fs:1.06}
:root[data-density="compact"],:root[data-density="roomy"]{
  --sp-3:calc(6px*var(--ui-scale)); --sp-4:calc(8px*var(--ui-scale));
  --sp-5:calc(10px*var(--ui-scale)); --sp-6:calc(12px*var(--ui-scale));
  --sp-8:calc(16px*var(--ui-scale)); --sp-10:calc(20px*var(--ui-scale));
  --sp-12:calc(24px*var(--ui-scale));
  --fs-ui:calc(12.5px*var(--ui-fs)); --fs-sm:calc(12px*var(--ui-fs));
  --fs-base:calc(13px*var(--ui-fs)); --fs-cap:calc(11px*var(--ui-fs));
  --fs-title:calc(14px*var(--ui-fs));
}
:root[data-density="compact"] .nav-row,
:root[data-density="compact"] .out-row,
:root[data-density="compact"] .cite-row{padding-top:2px;padding-bottom:2px}
:root[data-density="roomy"] .nav-row,
:root[data-density="roomy"] .out-row,
:root[data-density="roomy"] .cite-row{padding-top:7px;padding-bottom:7px}

/* ---------- Corners ------------------------------------------------------ */
:root[data-corners="square"]{--radius:3px;--radius-sm:2px}
:root[data-corners="soft"]{--radius:10px;--radius-sm:6px}
:root[data-corners="round"]{--radius:16px;--radius-sm:10px}

/* ---------- Panel style --------------------------------------------------
   Flat is also the performance mode: no blurred shadows repainting behind a
   long scrolling document. Separation moves to a hairline, so nothing ever
   depends on a shadow alone to be distinguishable. */
:root[data-panels="flat"]{
  --shadow:0 0 0 1px var(--line-strong);
  --shadow-lg:0 0 0 1px var(--line-strong);
  --paper-shadow:transparent;
}
:root[data-panels="flat"] .card,
:root[data-panels="flat"] .sheet{box-shadow:0 0 0 1px var(--line)}
:root[data-panels="flat"] .dropmenu,
:root[data-panels="flat"] .modal{box-shadow:0 0 0 1px var(--line-strong),0 8px 24px rgba(0,0,0,.18)}

/* ---------- Paper (SCREEN ONLY) -----------------------------------------
   Exported and printed documents are always white. This changes what you look
   at while writing and nothing else — exports.js writes its own literal CSS. */
:root[data-paper="bright"]{--paper:#ffffff;--paper-ink:#161a22;--paper-line:#e3e6ec;--paper-rule:#eef0f4}
:root[data-paper="warm"]{--paper:#fbf7ef;--paper-ink:#1d1a14;--paper-line:#e6ded0;--paper-rule:#f0e9dc}
:root[data-paper="dim"]{--paper:#141a22;--paper-ink:#e4e7ee;--paper-line:#28303c;--paper-rule:#222a34}
:root[data-theme="dark"][data-paper="bright"]{--paper:#141b27;--paper-ink:#e3e7ee;--paper-line:#2a3242;--paper-rule:#222a38}
:root[data-theme="dark"][data-paper="warm"]{--paper:#1a1712;--paper-ink:#ece5d8;--paper-line:#332c22;--paper-rule:#2a241c}

/* ---------- Faithful vs Comfort -----------------------------------------
   Faithful: the sheet renders the DOCUMENT's own font, size and leading, so
   what is on screen is a preview of the file.
   Comfort: the on-screen reading experience is tuned independently — and the
   app says so, permanently, in the toolbar. A writer drafting at 1.2x on a
   short measure will otherwise misjudge length and paragraph rhythm. */
:root{--srf-measure:0;--srf-scale:1;--srf-leading:0;--doc-face:"Times New Roman",Times,serif;--doc-pt:12pt;--doc-lead:2}
:root[data-sheetview="faithful"] .blk .bd{
  font-family:var(--doc-face);
  font-size:calc(var(--doc-pt)*1.34);   /* 12pt reads ~16px at 100% on screen */
  line-height:var(--doc-lead);
}
:root[data-sheetview="faithful"] .sheet{width:min(820px,100%)}
:root[data-sheetview="comfort"] .blk .bd{
  font-family:var(--doc-face);
  font-size:calc(16px*var(--srf-scale));
  line-height:var(--srf-leading, 1.7);
}
:root[data-sheetview="comfort"] .sheet{width:min(var(--srf-measure,72ch),100%)}
.viewbadge{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-micro);
  font-weight:700;text-transform:uppercase;letter-spacing:.07em;
  padding:1px 6px;border-radius:999px;background:var(--amber-bg);
  color:var(--amber);border:1px solid var(--amber-line)}
:root[data-sheetview="faithful"] .viewbadge{display:none}

/* ---------- High contrast ------------------------------------------------
   Not a mood, a floor. Washes collapse to a left bar plus weight, so a selected
   row never depends on a tint that could be stacked below legibility. */
:root[data-contrast="high"]{
  --ink-3:var(--ink-2); --ink-4:var(--ink-2);
  --line:var(--line-strong); --line-2:var(--line-strong);
  --ac-wash:transparent;
}
:root[data-contrast="high"] .out-row.sel,
:root[data-contrast="high"] .cite-row.sel,
:root[data-contrast="high"] .nav-row.sel{
  background:transparent;box-shadow:inset 3px 0 0 var(--ac-fill);font-weight:700
}
:root[data-contrast="high"] :focus-visible{outline-width:3px}

/* ---------- Motion ------------------------------------------------------- */
:root[data-motion="reduce"] *,
:root[data-motion="reduce"] *::before{animation:none !important;transition:none !important}

/* ---------- Appearance settings UI --------------------------------------- */
.apr-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:var(--sp-6)}
.apr-card{border:1px solid var(--line);border-radius:var(--radius-sm);padding:var(--sp-6);
  cursor:pointer;background:var(--surface-2);text-align:left}
.apr-card:hover{border-color:var(--ac-edge)}
.apr-card.on{border-color:var(--ac-fill);box-shadow:inset 0 0 0 1px var(--ac-fill);background:var(--ac-wash)}
.apr-name{font-weight:660;font-size:var(--fs-ui)}
.apr-hint{font-size:var(--fs-cap);color:var(--ink-3);margin-top:2px;line-height:1.45}
.apr-mini{display:flex;height:34px;border-radius:4px;overflow:hidden;margin-bottom:var(--sp-5);
  border:1px solid var(--line)}
.apr-mini i{display:block;height:100%}
.apr-mini .m-rail{width:26%}
.apr-mini .m-body{flex:1 1 auto;position:relative}
.apr-mini .m-page{position:absolute;inset:5px 20% 5px 8%;border-radius:2px}
.apr-mini .m-dot{position:absolute;right:6px;top:6px;width:10px;height:5px;border-radius:2px}
.swatches{display:flex;flex-wrap:wrap;gap:var(--sp-4)}
.swatch{width:34px;height:34px;border-radius:999px;border:2px solid transparent;cursor:pointer;
  position:relative;padding:0}
.swatch.on{border-color:var(--ink);box-shadow:0 0 0 2px var(--panel) inset}
.seg{display:inline-flex;gap:4px;flex-wrap:wrap}
.contrastline{display:flex;align-items:center;gap:var(--sp-5);flex-wrap:wrap;
  font-size:var(--fs-ui);padding:var(--sp-5) 0}

/* ============================================================================
   OPUS BENCH branding
   Colours taken from the app icon: a rose-plum → slate gradient with a
   folded-paper mark in pale blue and pale rose. The pastels are used as
   SURFACES and facets only; anything carrying text derives a darker role, which
   is why the accent has five values rather than one.
   ========================================================================= */
:root{
  --opus-rose:#9a5360; --opus-plum:#705c71; --opus-slate:#4e6481; --opus-mid:#625f77;
  --mark-a:#a9bdd3;    /* the blue leaf  */
  --mark-b:#d2a3a8;    /* the rose leaf  */
}

/* Accent — derived from the icon, roles measured not sampled. */
:root[data-accent="opus"]{--ac-fill:#7d4250;--ac-fill-hover:#6d3944;--ac-on:#fff;--ac-ink:#7a3f4c;--ac-edge:#a86b73;--ac-wash:#f7edee}
:root[data-theme="dark"][data-accent="opus"]{--ac-fill:#d2a3a8;--ac-fill-hover:#dcb2b7;--ac-on:#22141a;--ac-ink:#e3bfc3;--ac-edge:#8a5c64;--ac-wash:#251a1e}
:root[data-accent="slate"]{--ac-fill:#42566f;--ac-fill-hover:#3a4c63;--ac-on:#fff;--ac-ink:#3a4c63;--ac-edge:#7b8ea8;--ac-wash:#eef1f6}
:root[data-theme="dark"][data-accent="slate"]{--ac-fill:#a9bdd3;--ac-fill-hover:#bbcbde;--ac-on:#111a24;--ac-ink:#c0cee1;--ac-edge:#5b6e88;--ac-wash:#171e29}

/* ---------- --ob-*: the suite's own hue ----------------------------------
   THE CORNER RULE, IN COLOUR. The icon's gradient runs rose to slate, and the
   two ends now mean something: SLATE is Opus Bench — the landing page, the
   platform controls in the top right, bookmarks, the console — and ROSE is the
   app you happen to be in. Walk from Stylus into Remit and the slate does not
   move; that is the point of it. It is the same reasoning as the corner rule
   itself: what belongs to the suite looks identical everywhere, and what
   belongs to an app is free to differ.

   DELIBERATELY NOT UNDER [data-accent]. --ac-* is the person's choice for the
   app they are writing in, and they may set it to Forest. --ob-* is identity
   and must not follow, for the same reason the four app marks sit outside the
   token system entirely: identity does not adapt to preference.

   DERIVED FROM THE SLATE LEAF, NOT SAMPLED FROM IT — the same rule the rose
   accent follows, and for the same reason. The mark's slate (#4e6481) is a
   mid-tone because it is a shape in a logo, not a colour anything is read
   against; used directly it gives an icon that reads grey at 18px and a fill
   that fails against white. Hue is kept and saturation lifted, so it is
   recognisably the mark's blue and legible at control sizes. Every pair below
   is measured, not judged. */
:root{
  --ob-fill:#2f5686; --ob-fill-hover:#274a75; --ob-on:#ffffff;
  --ob-ink:#2c5180;  --ob-edge:#7f9dc4;       --ob-wash:#eef3fa;
}
:root[data-theme="dark"]{
  --ob-fill:#8fb6e8; --ob-fill-hover:#a4c4ed; --ob-on:#0d1826;
  --ob-ink:#a9c8f0;  --ob-edge:#4d6b96;       --ob-wash:#141d2a;
}
/* Must stay AFTER the dark block: equal specificity, so source order decides.
   Collapses for the same reason --ac-wash does — a tint may never be the only
   thing carrying a state. */
:root[data-contrast="high"]{--ob-wash:transparent}

/* The rail carries the icon's gradient, at the icon's own angle. Nav ink is
   lifted to #f5f0f1 so it clears 4.5:1 at the ROSE corner, which is the
   darkest-to-text point of the ramp — checking only the middle would ship a
   sidebar that goes illegible at one end. */
:root[data-chrome="opus"]{
  --nav-fill:var(--opus-plum); --nav-edge:#3d3145;
  --nav-ink:#f5f0f1; --nav-ink-dim:#d3c2c8;
}
:root[data-chrome="opus"] #sidebar{
  background:linear-gradient(200deg,var(--opus-slate) 0%,var(--opus-mid) 38%,
             var(--opus-plum) 66%,var(--opus-rose) 100%);
}
:root[data-chrome="opus"] .nav-row.sel{
  background:rgba(255,255,255,.20);border-color:rgba(255,255,255,.30);color:#fff
}
:root[data-chrome="opus"] .nav-row:hover{background:rgba(255,255,255,.13);color:#fff}
:root[data-chrome="opus"] .nav-mark{background:rgba(255,255,255,.16)}
:root[data-chrome="opus"] .nav-foot{border-top-color:rgba(255,255,255,.22)}
:root[data-theme="dark"][data-chrome="opus"] #sidebar{
  background:linear-gradient(200deg,#243040 0%,#241f2c 40%,#2e2029 72%,#3a2029 100%);
}
:root[data-theme="dark"][data-chrome="opus"]{--nav-ink:#efe6e8;--nav-ink-dim:#b8a6ad}
.nav-mark svg{display:block}

/* ---------- Viewer panes, echoing the folded-paper mark -------------------
   Each pane header carries a two-tone leading edge — blue leaf, rose leaf —
   so a stack of viewers reads as a set of folded sheets rather than as
   undifferentiated boxes. Purely a top border: no tint sits under any text. */
.pane-bar{position:relative}
.pane-bar::before{
  content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:linear-gradient(90deg,var(--mark-a) 0 50%,var(--mark-b) 50% 100%);
  opacity:.85;
}
.pane-head{position:relative}
.pane-head::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;
  background:linear-gradient(90deg,var(--mark-a),var(--mark-b));
}
/* The pane the editor's section is showing gets the mark at full strength. */
.wp-sec.here .wp-head{box-shadow:inset 3px 0 0 var(--ac-fill)}

/* The writing sheet gets the same folded edge along its top, so the page and
   the viewers read as the same family of object.

   This used to be `overflow:hidden` purely so the 3px edge would follow the
   sheet's rounded corners. That cost two real things: it made the sheet its own
   scrollport, which silently rendered the sticky section header in the
   whole-document view inert, and it clipped the per-paragraph ⋯/💬 gutter (which
   sits at left:-38px) once the sheet's side padding shrinks on a narrow screen.
   Rounding the pseudo-element itself buys the same look for neither price. */
.sheet{position:relative}
.sheet::before{
  content:"";position:absolute;left:0;right:0;top:0;height:3px;
  background:linear-gradient(90deg,var(--mark-a) 0 42%,var(--mark-b) 58% 100%);
  border-radius:8px 8px 0 0;
  opacity:.9;
}
:root[data-panels="flat"] .sheet::before{opacity:.7}

/* Review workbench + citation detail get the same treatment, so every
   "window" in the app is recognisably part of one set. */
.cite-detail .cd-head{position:relative}
.cite-detail .cd-head::before{
  content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:linear-gradient(90deg,var(--mark-a),var(--mark-b));
}
.rv-form .card:first-child{position:relative}
.mrow{position:relative}
.mrow::before{
  content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:linear-gradient(90deg,var(--mark-a) 0 50%,var(--mark-b) 50% 100%);
  opacity:.55;
}
.mrow.conflict::before{background:var(--red);opacity:.9}

/* Boot screen wears the mark too, so the first thing you see is the app. */
.boot-card{border-top:3px solid transparent;
  border-image:linear-gradient(90deg,var(--mark-a),var(--mark-b)) 1}
.boot-title{color:var(--ac-ink)}

/* A seat count is two or three digits in a table cell; the browser default
   stretches a number input to fill it and the stepper crowds the value out. */
/* Qualified by type on purpose. The base rule is `input[type="number"] …
   {width:100%}` — an element plus an attribute, which outweighs a bare class —
   so `.adm-seats{width:66px}` lost silently and every seat box stretched to
   215px, taking the column with it. Same family as the dead `--r-sm` and the
   `:first-of-type` trap: a rule that reads correctly and never applies. */
input[type="number"].adm-seats{width:66px}

/* The account corner in the app's own top bar. Same controls, same place and
   the same classes as the landing page's — reusing .hub-icbtn / .hub-me is the
   point, because two surfaces of one product drifting apart on where your face
   lives is how a suite starts feeling like stapled-together apps. */
.tb-acct{display:flex;align-items:center;gap:var(--sp-3);margin-left:auto;flex:0 0 auto}
/* The topbar corner is denser than the landing page's, so the same three
   controls step down together — 30px against a 30px avatar, keeping the
   one-size rule that makes them read as peers. */
.tb-acct .hub-icbtn{width:30px;height:30px}
.tb-acct .hub-icbtn svg{width:18px;height:18px}
/* .tb-right already claims margin-left:auto on some screens; the corner has to
   sit outside it, so it gets its own auto and a left gutter when both appear. */
.tb-right + .tb-acct{margin-left:var(--sp-6)}

/* The rail's mark is the app's real icon now, and a button — it is the way back
   up to the suite. */
.nav-mark-btn{background:transparent;border:0;padding:0;cursor:pointer;display:flex;
  border-radius:7px;line-height:0}
.nav-mark-btn:hover{box-shadow:0 0 0 3px var(--ac-wash)}
.nav-mark-btn:focus-visible{outline:2px solid var(--ac-edge);outline-offset:2px}

/* A hairline "or" between two ways of doing the same thing. */
.hu-orbar{display:flex;align-items:center;gap:var(--sp-6);margin:var(--sp-8) 0 var(--sp-6);
  color:var(--ink-3);font-size:var(--fs-cap);letter-spacing:.04em;text-transform:uppercase}
.hu-orbar::before,.hu-orbar::after{content:"";flex:1 1 auto;height:1px;background:var(--line)}

/* App grants in the roster and in the person's card. */
.hu-apps{white-space:nowrap}
.hu-appchip{display:inline-flex;margin-right:3px;vertical-align:middle}
.hu-appsfld{margin-top:var(--sp-8)}
.hu-appopt{display:flex;align-items:center;gap:var(--sp-6);padding:var(--sp-3) var(--sp-4);
  border-radius:var(--radius-sm);cursor:pointer}
.hu-appopt:hover{background:var(--surface-hover)}
.hu-appopt.locked{opacity:.7;cursor:default}
.hu-appopt .hint{margin-left:auto}

/* The rail's four verb groups (Write / Edit / Cite / Review). A heading above
   the sections, not another row — it names an activity, and nothing about it is
   clickable. */
.nav-group{
  font-size:var(--fs-cap);font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  /* Brighter than the section headings beneath it, not dimmer. The first
     version inherited --ink-4 at 75% and came out fainter than the labels it
     was meant to group, which reads as decoration rather than structure. The
     rail has its own ink (#8fa3cf for a section head); a group sits above that. */
  color:#c3d0ea;padding:var(--sp-7) var(--sp-5) var(--sp-2);
  border-top:1px solid rgba(255,255,255,.09);margin-top:var(--sp-4)
}
.nav-scroll > .nav-group:first-child,
.nav-sec:first-child + .nav-group{border-top:0;margin-top:0}
.nav-sec + .nav-group{margin-top:var(--sp-4)}
/* A paper inside a folder, and the folder itself. */
.nav-row.nav-sub .lbl{padding-left:var(--sp-8)}
.nav-row.nav-folder .mk{font-size:var(--fs-sm)}
.nav-row.soon{opacity:.55}
.nav-row.soon .val{font-size:var(--fs-micro);letter-spacing:.06em;text-transform:uppercase}

/* Name and post-nominals share a row at roughly 4:1 — "Alex Hall, MD" is one
   fact with a short suffix, not two facts of equal weight. */
.prof-name .fld:first-child{flex:4 1 0}
.prof-name .fld:last-child{flex:1 1 0;min-width:90px}

/* The co-author directory and its picker. */
.orcid-mark{vertical-align:-2px}
.ca-pick{max-height:46vh;overflow:auto;border:1px solid var(--line);border-radius:var(--radius)}
.ca-pick-row{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:var(--sp-8);
  padding:var(--sp-6) var(--sp-8);border-bottom:1px solid var(--line-2);cursor:pointer}
.ca-pick-row:last-child{border-bottom:0}
.ca-pick-row:hover{background:var(--surface-hover)}
.ca-pick-row.on-paper{opacity:.55;cursor:default}
.ca-pick-name{min-width:0}

/* Live presence, above the writing columns. Patched in place every couple of
   seconds, so it must never be inside the editor — rebuilding the writing
   surface on that cadence would destroy the caret twice a second. */
.ed-presence{
  display:flex;align-items:center;gap:var(--sp-8);flex-wrap:wrap;
  padding:var(--sp-4) var(--sp-10);background:var(--ac-wash);
  border-bottom:1px solid var(--ac-edge);font-size:var(--fs-sm);color:var(--ink-2)
}
.pres-one{display:inline-flex;align-items:center;gap:var(--sp-4)}
.pres-txt b{color:var(--ink)}
.pres-more{color:var(--ink-3);font-weight:600}

/* ---------- The landing page ---------------------------------------------
   A full surface over the app, not a screen inside it: the suite is a level
   above any one app, and drawing it inside the writing app's chrome would say
   the opposite. z-index sits ABOVE the app and its sidebar (60) and BELOW the
   sign-in gate (400) — an expired session must cover the landing page, not
   appear under it — and far below the modal layer, because every dialog it
   opens is an ordinary MS.dialog.

   Type: the two display sizes are DERIVED from --fs-lead rather than written as
   pixels, so Compact and Roomy still move them. A raw px here would silently
   opt the landing page out of the density setting. */
.hub{
  position:fixed;inset:0;z-index:300;background:var(--bg);color:var(--ink);
  overflow:auto;display:flex;flex-direction:column;
  --hub-h:calc(var(--fs-lead) + 5px);
  --hub-tile:calc(var(--fs-lead) + 1px);
}
.hub-bar{
  position:sticky;top:0;z-index:2;flex:0 0 auto;display:flex;align-items:center;
  gap:var(--sp-8);padding:var(--sp-6) var(--sp-12);background:var(--panel);
  border-bottom:1px solid var(--line)
}
.hub-brand{display:flex;align-items:center;gap:var(--sp-5)}
.hub-brand-name{font-size:var(--fs-lead);font-weight:680;letter-spacing:-.01em}
.hub-bar-right{margin-left:auto;display:flex;align-items:center;gap:var(--sp-3)}
/* Three controls of the SAME size, of which exactly one is filled. The help and
   settings glyphs used to be the literal characters "?" and "⚙" set at 15px
   inside a 32px button, sitting beside a 34px solid disc — so the two platform
   controls read as annotations on the avatar rather than as its peers. Real
   icons at 20px in a 34px hit target fixes the proportion; the avatar stays the
   only filled thing in the bar, because it is the only one that is an identity. */
.hub-icbtn{
  width:34px;height:34px;border-radius:999px;border:1px solid transparent;
  background:transparent;color:var(--ob-ink);cursor:pointer;
  display:grid;place-items:center;font-family:inherit
}
.hub-icbtn svg{width:20px;height:20px;display:block}
.hub-icbtn:hover{background:var(--ob-wash);color:var(--ob-fill);border-color:var(--ob-edge)}
.hub-icbtn:focus-visible{outline:2px solid var(--ob-edge);outline-offset:2px}
.hub-me{border:0;background:transparent;padding:0;cursor:pointer;border-radius:999px;
  display:flex;line-height:0}
.hub-me:hover{box-shadow:0 0 0 3px var(--ac-wash)}
.hub-main{flex:1 1 auto}
.hub-wrap{max-width:1120px;margin:0 auto;padding:var(--sp-16) var(--sp-12) 64px}
.hub-err{margin-bottom:var(--sp-12)}

.hub-sec{margin-bottom:var(--sp-16)}
.hub-h{
  display:flex;align-items:center;gap:var(--sp-5);margin:0 0 var(--sp-10);
  font-size:var(--hub-h);font-weight:700;letter-spacing:-.015em
}
.hub-h svg{color:var(--ob-ink);flex:0 0 auto}

/* The app marks. A rounded square with its own gradient — product identity,
   deliberately outside the accent-token system, because these are four logos
   that must look the same in both themes rather than five roles that adapt. */
.app-ic{display:inline-flex;flex:0 0 auto;line-height:0}
.app-ic img{display:block;width:100%;height:100%;object-fit:contain}

/* Two up, not three. minmax(330px) gave three columns at 1280 and left the
   fourth app alone on a second row looking like an afterthought; 420px holds a
   2×2 grid at every desktop width and collapses to one on a narrow window. */
/* align-items:start, or grid stretches every card in a row to the tallest —
   so expanding one tile inflates the one beside it into a tall empty box that
   looks broken. Only visible once the tiles could differ in height. */
.hub-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(420px,1fr));
  gap:var(--sp-12);align-items:start}
.hub-tile{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:var(--sp-12);display:flex;flex-direction:column;gap:var(--sp-8);box-shadow:var(--shadow)
}
/* A tile for something that does not exist yet reads as recessed, not broken:
   the card steps back a surface and the mark loses its shadow. Dimming the
   whole card would take the description with it, and the description is the
   only reason the tile is worth drawing at all. */
.hub-tile.soon{background:var(--surface-2);box-shadow:none}
.hub-tile.soon .app-ic{opacity:.55;filter:saturate(.55)}

/* CONDENSED BY DEFAULT. The tile is a row — mark, name, and Launch hard against
   the right edge opposite the mark — and the description is one click down.
   Padding tightens because a one-line row in card padding reads as a card
   waiting for content that never arrives. */
/* Bottom padding is smaller than the top on purpose: the chevron block sits in
   it, so the two have to be read together. Trimmed until the air above the
   header row and the air below it measure the same. */
.hub-tile{padding:var(--sp-8) var(--sp-10) var(--sp-3);gap:0}
.hub-tile-head{
  display:flex;align-items:center;gap:var(--sp-8);width:100%;
  background:none;border:0;padding:0;font:inherit;color:inherit;text-align:left;
  cursor:pointer
}
.hub-tile-head:focus-visible{outline:2px solid var(--ob-edge);outline-offset:3px;border-radius:var(--radius-sm)}
.hub-tile-id{min-width:0;flex:1 1 auto}
.hub-tile-name{font-size:var(--hub-tile);font-weight:680;letter-spacing:-.01em}
.hub-tile-tag{font-size:var(--fs-cap);color:var(--ink-3);letter-spacing:.05em;
  text-transform:uppercase;margin-top:1px}

/* Launch: narrow, fixed right, and the SUITE's blue rather than the app accent —
   opening an app is an Opus Bench act and looks the same on every tile. */
.hub-btn-go{
  flex:0 0 auto;margin-left:auto;padding:7px 18px;font-weight:600;
  background:var(--ob-fill);border-color:var(--ob-fill);color:var(--ob-on)
}
.hub-btn-go:hover:not([disabled]){background:var(--ob-fill-hover);border-color:var(--ob-fill-hover)}
.hub-btn-go[disabled]{opacity:.45;cursor:default}

/* The only chevron on the card: centred, and tucked toward the bottom edge
   without reaching it. The glyph stays small and the button around it does not —
   padding is the hit target, or this is a 14px thing to hit — so the padding
   above the glyph is what holds it off the header and the negative bottom
   margin is what pulls it toward the edge, leaving a couple of px of air.

   The card's own bottom padding is cut to --sp-4 (above) so that, with this
   block sitting in it, the space above the header row and the space below it
   read as equal. aria-hidden + tabindex -1 because the header already exposes
   the toggle to the keyboard and a screen reader does not need it twice. */
.hub-tile-more{
  display:flex;align-items:center;justify-content:center;
  margin:0 auto -4px;padding:0 18px 2px;
  background:none;border:0;cursor:pointer;color:var(--ink-4);line-height:0
}
.hub-tile-more:hover{color:var(--ob-ink)}
.hub-tile-more svg{width:14px;height:14px;transition:transform .16s ease}
.hub-tile.open .hub-tile-more svg{transform:rotate(180deg)}

/* Collapsed is the DEFAULT STATE IN CSS, not a class that has to be applied —
   a tile that paints expanded and then snaps shut on the next frame is what you
   get from doing this the other way round. */
.hub-tile-body{display:none;padding-top:var(--sp-6)}
.hub-tile.open .hub-tile-body{display:block}
.hub-tile-blurb{margin:0 0 var(--sp-8);color:var(--ink-2);line-height:1.6}
.hub-btn-more{color:var(--ob-ink);font-weight:600;padding:6px 14px}
.hub-chip{
  display:inline-flex;align-items:center;font-size:var(--fs-tag);font-weight:650;
  letter-spacing:.03em;padding:1px 7px;border-radius:999px;margin-top:2px;
  background:var(--ac-wash);color:var(--ac-ink);border:1px solid var(--ac-edge)
}

.hub-cols{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-16)}
.hub-rows{display:flex;flex-direction:column;gap:var(--sp-6)}
.hub-row{
  display:flex;align-items:center;gap:var(--sp-8);width:100%;text-align:left;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:var(--sp-8) var(--sp-10);cursor:pointer;font:inherit;color:var(--ink)
}
.hub-row:hover{background:var(--surface-hover);border-color:var(--line-strong)}
.hub-row-ic{display:flex;color:var(--ob-ink);flex:0 0 auto}
.hub-row-lbl{font-weight:600}
.hub-row-meta{margin-left:auto;color:var(--ink-3);font-size:var(--fs-sm);white-space:nowrap}
.hub-note{margin-top:var(--sp-6);color:var(--ink-3);font-size:var(--fs-sm)}
.hub-teampick{margin-bottom:var(--sp-6)}

/* A value the person may read but not set. Deliberately NOT a disabled input:
   a greyed box still looks like a box, so it invites a click and then refuses
   it. This reads as what it is — a fact about the account. */
.prof-ro{
  padding:9px 0;font-weight:600;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap
}

/* The initials picker. Real discs, not a dropdown of labels: "AJH" against
   "AH" is a difference you judge by looking at it. */
.mono-row{display:flex;gap:var(--sp-6);flex-wrap:wrap}
.mono-opt{
  display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:var(--sp-5) var(--sp-6);background:none;cursor:pointer;font:inherit;
  border:1px solid var(--line);border-radius:var(--radius-sm);color:var(--ink-3)
}
.mono-opt:hover{border-color:var(--line-strong);background:var(--surface-hover)}
.mono-opt.on{border-color:var(--ob-edge);background:var(--ob-wash);color:var(--ob-ink)}
.mono-opt:focus-visible{outline:2px solid var(--ob-edge);outline-offset:2px}
.mono-lbl{font-size:var(--fs-cap);white-space:nowrap}

/* First / MI / Last. The middle initial is one character, so it gets one
   character's worth of box — a full-width third column would say it is as
   important as the other two. */
.row.ui-name{display:flex;gap:var(--sp-6);align-items:flex-end}
.row.ui-name .fld:nth-child(1),.row.ui-name .fld:nth-child(3){flex:1 1 0;min-width:0}
.row.ui-name .fld:nth-child(2){flex:0 0 64px}

/* Avatars. Solid disc in the person's own colour with the PAIRED tint as ink —
   --au-N and --au-N-bg are guaranteed 4.5:1 against each other in both themes,
   which white is not: the dark palette brightens --au-1 to #7fb0f5, and white
   on that is about 2:1. (The 20px .avatar chip in the rail still hardcodes
   #fff and has exactly this problem; it is not this surface's to fix.) */
.hub-av{
  display:inline-flex;align-items:center;justify-content:center;border-radius:999px;
  font-weight:700;letter-spacing:-.02em;flex:0 0 auto;overflow:hidden;line-height:1
}
.hub-av.has-photo{background:var(--surface-3)}
.hub-av img{width:100%;height:100%;object-fit:cover;display:block}

/* The account popover. Its own thing rather than a dropmenu: it shows a face
   and three lines of identity before it shows any action, and a list of rows
   cannot say who you are. */
.hub-pop{
  position:fixed;z-index:7450;width:250px;background:var(--tb-menu-bg);
  border:1px solid var(--line-strong);border-radius:var(--radius);
  box-shadow:var(--shadow-lg);overflow:hidden
}
.hub-pop-id{padding:var(--sp-12) var(--sp-10);text-align:center;
  border-bottom:1px solid var(--line-2)}
.hub-pop-id .hub-av{margin-bottom:var(--sp-6)}
.hub-pop-name{font-weight:680}
.hub-pop-mail,.hub-pop-inst{font-size:var(--fs-sm);color:var(--ink-3);word-break:break-word}
.hub-pop-plan{margin-top:var(--sp-5)}
.hub-pop-acts{padding:var(--sp-3)}
.hub-pop-act{
  display:flex;align-items:center;gap:var(--sp-8);width:100%;text-align:left;
  background:transparent;border:0;border-radius:var(--radius-sm);cursor:pointer;
  padding:var(--sp-5) var(--sp-6);font:inherit;color:var(--ink)
}
.hub-pop-act:hover{background:var(--surface-hover)}
.hub-pop-act svg{color:var(--ink-3);flex:0 0 auto}

.hub-learn-head{display:flex;align-items:center;gap:var(--sp-8);margin-bottom:var(--sp-8)}
.hub-learn-name{font-size:var(--fs-lead);font-weight:680}
.hub-learn-tag{font-size:var(--fs-cap);color:var(--ink-3);letter-spacing:.05em;text-transform:uppercase}
.hub-learn p{line-height:1.6;color:var(--ink-2)}

.hub-prof{display:flex;gap:var(--sp-16);align-items:flex-start}
.hub-prof-pic{flex:0 0 auto;text-align:center}
.hub-prof-picacts{display:flex;flex-direction:column;gap:var(--sp-3);margin-top:var(--sp-6)}
.hub-prof-fields{flex:1 1 auto;min-width:0}

/* ---------- The Users screen (inside the landing page) -------------------- */

.hu-head{display:flex;align-items:center;gap:var(--sp-8);margin-bottom:var(--sp-10)}
.hu-headtxt{min-width:0}
.hu-sub{font-size:var(--fs-sm);color:var(--ink-3);margin-top:1px}
.hu-invite{padding:8px 14px;font-weight:600}
.hu-scopebar{margin-bottom:var(--sp-8)}
.hu-scope{font-size:var(--fs-sm);color:var(--ink-3);display:inline-flex;align-items:center;gap:var(--sp-5)}
.hu-back{
  width:34px;height:34px;border-radius:999px;border:1px solid var(--line);
  background:var(--panel);color:var(--ink-2);cursor:pointer;font-size:var(--fs-lead);
  display:grid;place-items:center;font-family:inherit;line-height:1
}
.hu-back:hover{background:var(--surface-hover);color:var(--ink)}
.hu-title{margin:0;font-size:var(--hub-h);font-weight:700;letter-spacing:-.015em}
.hu-head-right{margin-left:auto;display:flex;align-items:center;gap:var(--sp-8)}
.hu-seats{font-size:var(--fs-sm);color:var(--ink-3)}
.hu-plusic{font-weight:700}

.hu-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  overflow:hidden;box-shadow:var(--shadow)}
.hu-bar{display:flex;gap:var(--sp-8);padding:var(--sp-8) var(--sp-10);background:var(--surface-2);
  border-bottom:1px solid var(--line)}
.hu-search{flex:1 1 auto;display:flex;align-items:center;gap:var(--sp-5);
  background:var(--input-bg);border:1px solid var(--input-line);
  border-radius:var(--radius-sm);padding:0 var(--sp-8);color:var(--ink-4)}
.hu-search input{flex:1 1 auto;border:0;background:transparent;padding:9px 0;
  font:inherit;color:var(--ink);outline:none;min-width:0}
.hu-filter{flex:0 0 auto}
.hu-filter.on{border-color:var(--ac-edge);color:var(--ac-ink)}
.hu-fcount{display:inline-grid;place-items:center;min-width:16px;height:16px;padding:0 4px;
  border-radius:999px;background:var(--ac-fill);color:var(--ac-on);font-size:var(--fs-micro);
  font-weight:700}

/* A roster is read at a glance and clicked once, so it is deliberately roomier
   than the app's dense working grids: a 40px face, a tall row, and real space
   either side. This is the one table in the product that is not trying to fit
   as much as possible on screen. */
.hu-table{width:100%;border-collapse:collapse;font-size:var(--fs-md)}
.hu-table th{
  text-align:left;font-size:var(--fs-cap);font-weight:700;color:var(--ink-3);
  letter-spacing:.04em;text-transform:uppercase;padding:var(--sp-8) var(--sp-12);
  border-bottom:1px solid var(--line)
}
.hu-table td{padding:var(--sp-8) var(--sp-12);border-bottom:1px solid var(--line-2);height:64px}
.hu-role{color:var(--ink-2)}
.hu-row{cursor:pointer}
.hu-row:hover td{background:var(--surface-hover)}
/* The row you last opened stays marked, so closing the card does not lose your
   place in a list of thirty people. */
.hu-row.sel td{background:var(--ac-wash)}
.hu-row.sel td:first-child{box-shadow:inset 3px 0 0 var(--ac-fill)}
.hu-row.off td{opacity:.62}
/* The real control in the row: a button, so it can be tabbed to and pressed.
   The <tr> is a mouse convenience on top of it, not the only way in. */
.hu-person{display:flex;align-items:center;gap:var(--sp-8);width:100%;text-align:left;
  background:transparent;border:0;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;
  border-radius:var(--radius-sm)}
.hu-person:focus-visible{outline:2px solid var(--ac-edge);outline-offset:2px}
.hu-name{font-weight:600}
.hu-mail{color:var(--ac-ink)}
.hu-empty{padding:var(--sp-16);text-align:center;color:var(--ink-3)}

.hu-pill{
  display:inline-flex;align-items:center;font-size:var(--fs-cap);font-weight:650;
  padding:2px 11px;border-radius:999px;border:1px solid
}
.hu-pill.active{color:var(--green);background:var(--green-bg);border-color:var(--green-line)}
.hu-pill.pending{color:var(--amber);background:var(--amber-bg);border-color:var(--amber-line)}
.hu-pill.deactivated,.hu-pill.suspended{color:var(--ink-3);background:var(--surface-2);border-color:var(--line-strong)}

.hu-foot{display:flex;align-items:center;justify-content:flex-end;gap:var(--sp-8);
  padding:var(--sp-8) var(--sp-12);font-size:var(--fs-sm);color:var(--ink-3)}
.hu-per{display:flex;align-items:center;gap:var(--sp-5);white-space:nowrap}
.hu-pg{
  width:26px;height:26px;border-radius:var(--radius-sm);border:1px solid var(--line);
  background:var(--panel);color:var(--ink-2);cursor:pointer;font-family:inherit;line-height:1
}
.hu-pg:hover:not([disabled]){background:var(--surface-hover);color:var(--ink)}
.hu-pg[disabled]{opacity:.4;cursor:default}

/* The filter popover is checkboxes, not actions: several can be on at once and
   picking one must not close it, which is exactly what U.menu does. */
.hu-fpop{
  position:fixed;z-index:7450;width:210px;background:var(--tb-menu-bg);
  border:1px solid var(--line-strong);border-radius:var(--radius);
  box-shadow:var(--shadow-lg);padding:var(--sp-6)
}
.hu-fgrp + .hu-fgrp{margin-top:var(--sp-6);padding-top:var(--sp-6);border-top:1px solid var(--line-2)}
.hu-fh{font-size:var(--fs-cap);font-weight:700;color:var(--ink-3);letter-spacing:.04em;
  text-transform:uppercase;padding:0 var(--sp-4) var(--sp-3)}
.hu-fopt{display:flex;align-items:center;gap:var(--sp-6);padding:var(--sp-3) var(--sp-4);
  border-radius:var(--radius-sm);cursor:pointer}
.hu-fopt:hover{background:var(--surface-hover)}
.hu-fclear{margin-top:var(--sp-4);text-align:right}

.hu-info{display:flex;gap:var(--sp-16);align-items:flex-start}
.hu-info-pic{flex:0 0 auto}
.hu-info-fields{flex:1 1 auto;min-width:0}
.hu-info-status{margin-bottom:var(--sp-10)}
.hu-pair{margin-bottom:var(--sp-10)}
.hu-pk{font-weight:700;font-size:var(--fs-sm)}
.hu-pv{color:var(--ink-2);word-break:break-word}
.hu-pv.mono{font-family:var(--mono);font-size:var(--fs-sm)}
.hu-pv.mail{color:var(--ac-ink)}
/* Destructive action to the left of the confirm pair, so "Deactivate" is never
   where a hurried click expects "Cancel". It is an outlined red button, not a
   filled one: it is not the action of the dialog, and .ghost on its own wins
   over .danger (later in the sheet, same specificity) and rendered it grey —
   a destructive control that looks like a disabled one. */
.hu-foot-left{margin-right:auto}
.btn.danger.ghost{background:transparent;color:var(--red);border-color:var(--red-line)}
.btn.danger.ghost:hover{background:var(--red-bg);color:var(--red)}

.hu-add-lead{margin:0 0 var(--sp-10);color:var(--ink-2)}
.hu-add-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--radius)}
.hu-add{width:100%;border-collapse:collapse;min-width:560px}
.hu-add th{text-align:left;font-size:var(--fs-cap);font-weight:700;color:var(--ink-3);
  letter-spacing:.04em;text-transform:uppercase;padding:var(--sp-5) var(--sp-6);
  border-bottom:1px solid var(--line);background:var(--surface-2)}
.hu-add td{padding:var(--sp-5) var(--sp-6);border-bottom:1px solid var(--line-2)}
.hu-add tr:last-child td{border-bottom:0}
.hu-add input,.hu-add select{width:100%}
.hu-add-del{width:38px}
.hu-trash{background:transparent;border:0;cursor:pointer;color:var(--ink-4);font-size:var(--fs-md);
  padding:var(--sp-3);border-radius:var(--radius-sm);line-height:1}
.hu-trash:hover:not([disabled]){background:var(--red-bg);color:var(--red)}
.hu-trash[disabled]{opacity:.3;cursor:default}
.hu-add-foot{display:flex;align-items:center;gap:var(--sp-8);margin-top:var(--sp-8)}
.hu-add-foot .hint{margin-left:auto}

/* ---------- Narrow windows and phones ------------------------------------
   Last in the sheet on purpose: these are overrides, and at equal specificity
   the later rule wins. Sitting them next to the sidebar rules meant
   `.tb-facts{display:none}` lost to the plain `.tb-facts` declared below it. */

/* The landing page is two columns of cards on a desktop and one everywhere
   else. The tile grid handles itself (auto-fit/minmax); Support and Team
   Settings do not, and side by side below 1000px they were 380px each. */
@media (max-width:980px){
  .hub-cols{grid-template-columns:1fr;gap:var(--sp-12)}
  .hub-prof,.hu-info{flex-direction:column;align-items:center}
  .hub-prof-fields,.hu-info-fields{width:100%}
}

/* The band between the phone breakpoint and a comfortable desktop had no
   treatment at all: the bar kept the full word/ref/table/figure counts AND the
   full action group, so once it was allowed to wrap it grew to three rows.
   Drop the counts first — they are ambient information, and the same numbers
   are on the section outline and in Details. */
@media (max-width:1000px){
  .tb-facts{display:none}
  .tb-sec{display:none}
}
@media (max-width:760px){
  /* The landing page on a phone: one tile per row, the two buttons stacked so
     neither is a 90px target, and the bar's seat count dropped — it is ambient,
     and the Add New User button is what has to survive. */
  .hub-wrap{padding:var(--sp-10) var(--sp-6) 48px}
  .hub-grid{grid-template-columns:1fr}
  .hub-tile-foot{flex-direction:column}
  .hub-btn-more,.hub-btn-go{flex:1 1 auto}
  .hu-seats{display:none}
  .hu-bar{flex-wrap:wrap}
  .hu-search{flex:1 1 100%}
  /* The roster keeps Name and Status on a phone. Email is the widest column and
     it is on the person's card one tap away; Role is a word the pill implies. */
  .hu-table td:nth-child(2),.hu-table th:nth-child(2),
  .hu-table td:nth-child(3),.hu-table th:nth-child(3){display:none}
  .hu-foot{flex-wrap:wrap;justify-content:space-between}
}

@media (max-width:760px){
  .tb{flex-wrap:wrap;row-gap:var(--sp-4)}
  .tb-nav{order:0;margin-right:var(--sp-4)}
  .tb-crumb{min-width:0;flex:1 1 0;order:1}
  .tb-sec{display:none}
  .tb-right{flex:1 1 100%;order:2;flex-wrap:wrap;justify-content:flex-start;gap:var(--sp-4)}
  .tb-facts{display:none}
  /* On a phone the bar has to stay one row. The view toggles are the ones to
     lose: Track and Marks are settings you set once, not controls you reach
     for mid-sentence, and both are reachable from Settings. What is left —
     Check, More, Export — is what you actually press. */
  .tb-right .tb-view{display:none}
  /* The carets cost a whole extra button row once touch targets are 40px
     tall. Tapping a button that opens a menu is self-evident anyway. */
  .tb-car{display:none}
  .tb-group + .tb-group::before,.tb-group + .btn::before{display:none}
  .tb-name{font-size:var(--fs-md);white-space:normal}
  .save-ind span:nth-child(2){display:none}
  .sheet{padding:var(--sp-10) var(--sp-8)}
  .sheetwrap{padding:4px 4px 30vh}
  .citefoot{padding:0 var(--sp-6) var(--sp-2)}
  .abs-main{padding:var(--sp-6) var(--sp-6) 50px}
  .page{padding:var(--sp-8) var(--sp-6) 40px}
  .row{flex-direction:column;gap:0}
  .fld{flex:1 1 auto !important}

  /* The peer-review workbench is a 55/45 split. Both panes carry min-width:0,
     so the percentages hold all the way down and a phone got a 215px PDF beside
     a 176px form — neither usable. On a phone you are reading the paper OR
     writing the review, never both at once, so stack them and let the form own
     the screen; the PDF is still reachable by scrolling up to it. */
  .rvwrap{flex-direction:column}
  .rv-pdf{flex:0 0 auto;max-height:45vh}
  .rv-form{flex:1 1 auto;min-height:0}

  /* The search box was sharing a row with a 130px sort select and collapsed to
     about 44px — not enough to see what you typed. Give it its own row. */
  .cite-bar{flex-wrap:wrap}
  .cite-bar input[type=search]{flex:1 1 100%;order:-1}

  /* The 30vh runway below the sheet is there so the last paragraph of a long
     manuscript can sit mid-screen while you type. An abstract is one screen
     long, so the same runway just buries the Authors card under blank space. */
  .abs-main .sheetwrap{padding-bottom:0}
}
/* Touch only — gated on BOTH conditions so a desktop pointer is never
   inflated. Anything revealed by :hover has no equivalent under a finger. */
@media (hover:none) and (pointer:coarse){
  .nav-row,.btn,.btn.sm,.tab,.tb-nav,.nav-collapse{min-height:40px}
  .nav-row{padding-top:var(--sp-5);padding-bottom:var(--sp-5)}
  .blk-gut,.cf-row .btn,.pane-bar .btn{opacity:1}
}

/* ---------- Sign-in providers + admin -----------------------------------
   The "or" divider between the emailed link and the OAuth buttons, and the
   operator panel opened from Settings. */
.or-sep{display:flex;align-items:center;gap:var(--sp-5);margin:var(--sp-6) 0;color:var(--ink-4);
  font-size:var(--fs-cap)}
.or-sep::before,.or-sep::after{content:"";flex:1 1 auto;height:1px;background:var(--line)}
/* ---------- Opus Bench surfaces ------------------------------------------
   BLUE IS THE SUITE'S BUTTON. `.btn.primary` otherwise takes --ac-fill, which
   is the accent somebody picked for the app they WRITE in — so Administration
   and the Users page wore a different colour depending on a preference that has
   nothing to do with them. `.modal.ob` is the marker a platform dialog sets on
   itself; #hub is the landing page. Danger keeps its own red: "this destroys
   something" outranks "this belongs to the suite". */
.modal.ob .btn.primary,#hub .btn.primary{
  background:var(--ob-fill);border-color:var(--ob-fill);color:var(--ob-on)
}
.modal.ob .btn.primary:hover:not([disabled]),#hub .btn.primary:hover:not([disabled]){
  background:var(--ob-fill-hover);border-color:var(--ob-fill-hover)
}
.modal.ob .btn:focus-visible,#hub .btn:focus-visible{outline:2px solid var(--ob-edge);outline-offset:2px}
.modal.ob a,#hub a{color:var(--ob-ink)}

/* THE TABS HAD NO CSS AT ALL — `.tab` and `.tab.on` were undefined, so four
   plain bordered buttons sat in a row with nothing to say which one you were
   looking at. A segmented control: one recessed track, the active tab raised
   out of it. */
.tabs{
  display:inline-flex;gap:2px;padding:3px;margin-bottom:var(--sp-10);
  background:var(--surface-2);border:1px solid var(--line);border-radius:9px
}
.tab{
  appearance:none;border:0;background:none;font:inherit;cursor:pointer;
  padding:6px 14px;border-radius:var(--radius-sm);color:var(--ink-2);
  font-weight:600;font-size:var(--fs-sm);white-space:nowrap
}
.tab:hover{background:var(--surface-hover);color:var(--ink)}
.tab.on{background:var(--panel);color:var(--ob-ink);box-shadow:var(--shadow)}
.tab:focus-visible{outline:2px solid var(--ob-edge);outline-offset:1px}

/* The operator search. It was a bare full-width box with no label and no icon,
   floating between the stat tiles and the table. */
.adm-search{
  display:flex;align-items:center;gap:var(--sp-5);margin:var(--sp-10) 0;
  border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  padding:0 var(--sp-8);background:var(--panel)
}
.adm-search svg{width:15px;height:15px;flex:0 0 auto;color:var(--ink-4)}
.adm-search input{flex:1 1 auto;border:0;background:transparent;padding:9px 0;font:inherit;color:var(--ink)}
.adm-search input:focus{outline:none}
.adm-search:focus-within{border-color:var(--ob-edge);box-shadow:0 0 0 3px var(--ob-wash)}

/* An empty state that says what to do next, not just that there is nothing. */
.adm-empty{
  padding:var(--sp-16) var(--sp-12);text-align:center;border:1px dashed var(--line-strong);
  border-radius:var(--radius-sm);background:var(--surface-2)
}
.adm-empty b{display:block;color:var(--ink);margin-bottom:2px}
.adm-empty span{color:var(--ink-3);font-size:var(--fs-sm)}

/* ---------- The operator console ----------------------------------------
   Its own host, its own whole window. Deliberately plainer than the product —
   an operator surface that looks like the app is one somebody mistakes for the
   app, and the top of this screen should never be ambiguous about which of the
   two you are typing into. */
.cons{position:fixed;inset:0;z-index:400;background:var(--bg);overflow:auto;
  display:flex;flex-direction:column}
.cons-bar{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:var(--sp-8);
  padding:var(--sp-6) var(--sp-12);background:var(--panel);border-bottom:2px solid var(--ob-fill)}
.cons-brand{display:flex;align-items:center;gap:var(--sp-5)}
.cons-name{font-weight:680;letter-spacing:-.01em;color:var(--ob-ink)}
.cons-who{margin-left:auto;display:flex;align-items:center;gap:var(--sp-6);
  font-size:var(--fs-sm);color:var(--ink-3)}
.cons-main{flex:1 1 auto;max-width:900px;width:100%;margin:0 auto;padding:var(--sp-16) var(--sp-12) 64px}
.cons-mid{text-align:center;padding:var(--sp-16)}
.cons-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:var(--sp-12);box-shadow:var(--shadow);margin-bottom:var(--sp-12)}
.cons-search{display:flex;align-items:center;gap:var(--sp-6);margin-bottom:var(--sp-6);
  background:var(--panel);border:1px solid var(--line-strong);border-radius:var(--radius);
  padding:var(--sp-4) var(--sp-6)}
.cons-search svg{width:16px;height:16px;color:var(--ink-4);flex:0 0 auto}
.cons-search input{flex:1 1 auto;border:0;background:transparent;padding:9px 0;font:inherit}
.cons-search input:focus{outline:none}
.cons-search:focus-within{border-color:var(--ob-edge);box-shadow:0 0 0 3px var(--ob-wash)}
.cons-hint{margin:0 0 var(--sp-12)}
.cons-head{display:flex;align-items:center;gap:var(--sp-8);margin-bottom:var(--sp-10)}
.cons-head-right{margin-left:auto}
.cons-h1{font-size:var(--fs-lead);font-weight:680}
.cons-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:var(--sp-6);margin-bottom:var(--sp-10)}
.cons-fact{border:1px solid var(--line);border-radius:var(--radius-sm);padding:var(--sp-5) var(--sp-6)}
.cons-k{font-size:var(--fs-cap);color:var(--ink-3);text-transform:uppercase;letter-spacing:.06em}
.cons-v{font-weight:600;overflow:hidden;text-overflow:ellipsis}
.cons-v.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--fs-sm);font-weight:500}
.cons-sec{margin-top:var(--sp-12);padding-top:var(--sp-10);border-top:1px solid var(--line-2)}
.cons-row{display:flex;align-items:center;gap:var(--sp-8);padding:var(--sp-6) 0}
.cons-row > div:first-child{flex:1 1 auto;min-width:0}
.cons .btn.primary{background:var(--ob-fill);border-color:var(--ob-fill);color:var(--ob-on)}
.cons .btn.primary:hover:not([disabled]){background:var(--ob-fill-hover);border-color:var(--ob-fill-hover)}

/* Bookmarks. The add row is the first thing on the screen because adding is
   what somebody opened this to do; editing what is already there is the rarer
   visit. */
.bm-add{display:flex;gap:var(--sp-6);align-items:flex-end;flex-wrap:wrap}
.bm-add .fld{flex:1 1 160px;min-width:0}
.bm-addgo{flex:0 0 auto;padding-bottom:12px}
.bm-folders{display:flex;flex-direction:column;gap:var(--sp-5)}
.bm-folder{display:flex;gap:var(--sp-6);align-items:center}
.bm-folder input{flex:1 1 auto}

.adm-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:var(--sp-5)}
.adm-stat{border:1px solid var(--line);border-radius:var(--radius-sm);padding:var(--sp-5) var(--sp-6);
  background:var(--surface-2)}
.adm-n{font-size:var(--fs-lead);font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink)}
.adm-l{font-size:var(--fs-cap);color:var(--ink-3);text-transform:uppercase;letter-spacing:.06em}
.adm-list{max-height:52vh;overflow:auto;border:1px solid var(--line);border-radius:var(--radius-sm)}
.adm-list table{width:100%}
.adm-list td{vertical-align:top}
tr.adm-susp{opacity:.6}

/* ---------- The sign-in screen -------------------------------------------
   A front door for the web build. It sits above everything (including the
   modal layer, which is why the z-index is higher than the scrim's) and it is
   deliberately not dismissable by Escape: leaving it should be a choice you
   made, not a key you pressed. The desktop build never constructs it. */
.gate{position:fixed;inset:0;z-index:400;display:grid;place-items:center;
  padding:var(--sp-10);overflow:auto;background:var(--bg)}
/* Generous, EXPLICIT padding (px, not a token) so the content column is inset
   like the reference — buttons sit narrow and centred, not edge-to-edge. The
   earlier `var(--sp-14)` did not exist in the scale, which invalidated the whole
   padding shorthand and collapsed it to 0. */
.gate-card{width:100%;max-width:420px;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:0 18px 60px rgba(16,24,40,.20);padding:48px 40px 36px}
/* Brand: the app icon (rounded square) centred, tagline beneath. */
.gate-brand{display:flex;flex-direction:column;align-items:center;gap:var(--sp-5);margin-bottom:var(--sp-8)}
.gate-app-icon{width:76px;height:76px;border-radius:18px;display:block;
  box-shadow:0 4px 16px rgba(16,24,40,.20)}
.gate-logo{width:56px;height:56px;display:grid;place-items:center}
.gate-logo svg{width:56px;height:56px}
.gate-tag{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.14em;
  color:var(--ink-4);font-weight:700}
.gate-h{font-size:var(--fs-title);font-weight:680;text-align:center;margin:0 0 var(--sp-4)}
.gate-sub{font-size:var(--fs-sm);color:var(--ink-3);text-align:center;line-height:1.5;margin:0 0 var(--sp-8)}
.gate-card .fld{margin-bottom:var(--sp-6)}
.gate-card .fld + .fld{margin-top:0}

/* The two buttons take their colour from the logo: a deep slate-blue Continue
   and a muted-rose CILogon, both with white text. Defined here so they match the
   mark regardless of the app's accent theme. */
.gate-primary{width:100%;justify-content:center;min-height:44px;
  background:var(--gate-blue);border-color:var(--gate-blue);color:#fff;font-weight:640}
.gate-primary:hover:not(:disabled){background:var(--gate-blue-h);border-color:var(--gate-blue-h);color:#fff}
.gate-primary:disabled{opacity:.45;cursor:default}
.gate-note{font-size:var(--fs-cap);color:var(--ink-3);line-height:1.5;margin-top:var(--sp-5)}
.gate-oauth,.gate-local{width:100%;justify-content:center;min-height:44px;margin-top:var(--sp-5);
  display:flex;align-items:center;gap:var(--sp-5)}
.gate-cilogon{background:var(--gate-rose);border-color:var(--gate-rose);color:#fff;font-weight:600}
.gate-cilogon:hover{background:var(--gate-rose-h);border-color:var(--gate-rose-h);color:#fff}
.gate-oauth-ic{flex:0 0 auto}

/* Password field + reveal eye share the row, equal-height columns. */
.gate-pw{display:flex;align-items:stretch;gap:var(--sp-4)}
.gate-pw input{flex:1 1 auto;min-width:0}
.gate-eye{flex:0 0 auto;width:40px;border:1px solid var(--line);border-radius:var(--r-input,8px);
  background:var(--surface-2);cursor:pointer;font-size:15px;line-height:1;opacity:.6}
.gate-eye:hover,.gate-eye.on{opacity:1;border-color:var(--gate-blue)}

/* The signed-in email on the password step, with its Edit link. */
.gate-idrow{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-5);
  border:1px solid var(--line);border-radius:var(--r-input,8px);
  padding:var(--sp-5) var(--sp-6);margin-bottom:var(--sp-6);background:var(--surface-2)}
.gate-id{font-size:var(--fs-sm);color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gate-edit{flex:0 0 auto;color:var(--blue);font-weight:600}

.gate-rule{display:flex;align-items:center;gap:var(--sp-6);margin:var(--sp-8) 0;
  color:var(--ink-4);font-size:var(--fs-cap)}
.gate-rule::before,.gate-rule::after{content:"";flex:1 1 auto;height:1px;background:var(--line)}
.nav-signin .mk{font-weight:700}
.gate-links{margin-top:var(--sp-6);font-size:var(--fs-cap);text-align:center;color:var(--ink-3)}
.gate-links-left{text-align:left;margin-top:0;margin-bottom:var(--sp-6)}
.gate-links a{color:var(--blue);text-decoration:none;font-weight:600}
.gate-links a:hover{text-decoration:underline}
@media (max-width:760px){
  .gate{padding:var(--sp-6);place-items:start center}
  .gate-card{padding:var(--sp-10);max-width:none}
}

/* Admin section subheading (Access tab). */
.adm-h{font-size:var(--fs-cap);font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  color:var(--ink-3);margin:0 0 var(--sp-5)}

/* The mail diagnosis. Green or red, because the answer is binary and the whole
   point is not having to read carefully to find out which. */
.cons-mail{margin-top:var(--sp-8);padding:var(--sp-8);border-radius:var(--radius-sm);
  border:1px solid var(--line)}
.cons-mail.good{background:var(--green-bg);border-color:var(--green-line)}
.cons-mail.good b{color:var(--green)}
.cons-mail.bad{background:var(--amber-bg);border-color:var(--amber-line)}
.cons-mail.bad b{color:var(--amber)}
