*{margin:0;padding:0;box-sizing:border-box}
:root{
  --bg:#fafafa;--bg2:#ffffff;--bg3:#f3f4f6;--bg4:#e9eaec;
  --border:#e5e7eb;--border2:#d1d5db;
  --text:#111827;--text2:#4b5563;--text3:#9ca3af;
  --accent:#6a8fbf;--accent-hover:#5078a8;--accent-light:#eff4fb;
  --green:#059669;--yellow:#d97706;--red:#dc2626;--orange:#ea580c;
  --mono:'JetBrains Mono','SF Mono',Menlo,ui-monospace,"Cascadia Code","Courier New",monospace;
  --sans:'IBM Plex Sans',-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
  --header-bg:rgba(255,255,255,0.96);--overlay-bg:rgba(255,255,255,0.99);--divider:#e5e7eb;
  --shadow-sm:0 1px 3px rgba(0,0,0,.06),0 1px 2px rgba(0,0,0,.04);
  --shadow-md:0 4px 12px rgba(0,0,0,.08),0 2px 4px rgba(0,0,0,.04);
  --shadow-lg:0 16px 48px rgba(0,0,0,.12),0 4px 8px rgba(0,0,0,.04);
  --r-xs:4px;--r-sm:6px;--r-md:8px;--r-lg:12px;--r-xl:16px;
  --chip-blue-bg:#dbeafe;--chip-blue-fg:#1d4ed8;
  --chip-green-bg:#dcfce7;--chip-green-fg:#166534;
  --chip-purple-bg:#f3e8ff;--chip-purple-fg:#6b21a8;
  --chip-red-bg:#fee2e2;--chip-red-fg:#991b1b;
  --warn-bg:#fff3cd;--warn-border:#ffc107;--warn-fg:#856404;
  color-scheme:light;
}
/* ── DARK THEME ─ real dark, not pure black: cool graphite surfaces, near-white text ── */
:root[data-theme="dark"]{
  --bg:#15181d;--bg2:#1c2128;--bg3:#252b34;--bg4:#2e3540;
  --border:#2c333d;--border2:#3d4653;
  --text:#e6e8eb;--text2:#aab2bd;--text3:#717b88;
  --accent:#82a7d6;--accent-hover:#9bbae3;--accent-light:#243348;
  --green:#3fb884;--yellow:#e0a63e;--red:#ef7168;--orange:#ef8e50;
  --header-bg:rgba(21,24,29,0.94);--overlay-bg:rgba(21,24,29,0.98);--divider:#2c333d;
  --shadow-sm:0 1px 3px rgba(0,0,0,.35),0 1px 2px rgba(0,0,0,.25);
  --shadow-md:0 4px 12px rgba(0,0,0,.45),0 2px 4px rgba(0,0,0,.3);
  --shadow-lg:0 16px 48px rgba(0,0,0,.55),0 4px 8px rgba(0,0,0,.3);
  --chip-blue-bg:#1f3352;--chip-blue-fg:#8fb8f6;
  --chip-green-bg:#1c3b2c;--chip-green-fg:#7dd8a8;
  --chip-purple-bg:#372a4d;--chip-purple-fg:#c8a8f0;
  --chip-red-bg:#462423;--chip-red-fg:#f0918a;
  --warn-bg:#332b18;--warn-border:#8a6d1a;--warn-fg:#e8c86a;
  color-scheme:dark;
}
/* Dark-mode fixes for third-party / hardcoded-light components */
:root[data-theme="dark"] .ql-toolbar.ql-snow,
:root[data-theme="dark"] .ql-container.ql-snow{border-color:var(--border2);background:var(--bg2);color:var(--text)}
:root[data-theme="dark"] .ql-editor{color:var(--text)}
:root[data-theme="dark"] .ql-editor.ql-blank::before{color:var(--text3)}
:root[data-theme="dark"] .ql-snow .ql-stroke{stroke:var(--text2)}
:root[data-theme="dark"] .ql-snow .ql-fill{fill:var(--text2)}
:root[data-theme="dark"] .ql-snow .ql-picker{color:var(--text2)}
:root[data-theme="dark"] .ql-snow .ql-picker-options{background:var(--bg2);border-color:var(--border2)}
:root[data-theme="dark"] .ql-snow .ql-tooltip{background:var(--bg2);border-color:var(--border2);color:var(--text);box-shadow:var(--shadow-md)}
:root[data-theme="dark"] .ql-snow .ql-tooltip input[type=text]{background:var(--bg3);border-color:var(--border2);color:var(--text)}
:root[data-theme="dark"] .ql-snow.ql-toolbar button:hover .ql-stroke,
:root[data-theme="dark"] .ql-snow.ql-toolbar button.ql-active .ql-stroke{stroke:var(--accent)}
:root[data-theme="dark"] .ql-snow.ql-toolbar button:hover .ql-fill,
:root[data-theme="dark"] .ql-snow.ql-toolbar button.ql-active .ql-fill{fill:var(--accent)}
/* Chemical structures & reaction schemes: RDKit draws near-black bonds on a
   transparent/white canvas. In dark mode, invert the drawing so bonds render
   light on the dark surface; hue-rotate(180deg) restores heteroatom colors
   (O red, N blue) after inversion. RDKit SVGs are identified by their
   xmlns:rdkit attribute (inline) or data-URI (reaction schemes / thumbs).
   Screen only — printed reports and vial labels stay black-on-white. */
@media screen {
  :root[data-theme="dark"] svg[xmlns\:rdkit],
  :root[data-theme="dark"] img[src^="data:image/svg+xml"],
  :root[data-theme="dark"] img[src^="/api/structure/svg"],
  :root[data-theme="dark"] img[src^="/api/svg"],
  :root[data-theme="dark"] #lib-struct-thumb,
  :root[data-theme="dark"] #browser-struct-thumb,
  :root[data-theme="dark"] #rs-struct-thumb,
  :root[data-theme="dark"] .browser-eln-thumb,
  :root[data-theme="dark"] .bio-exp-modal-card img,
  :root[data-theme="dark"] #bio-exp-tooltip .tt-struct{filter:invert(.88) hue-rotate(180deg)}
  /* The forced --bg3 plate would invert to a light block — keep it transparent */
  :root[data-theme="dark"] .card-struct svg rect:first-child,
  :root[data-theme="dark"] .dp-struct svg rect:first-child,
  :root[data-theme="dark"] #cm-struct-preview svg rect:first-child{fill:transparent!important}
}
/* Reaction-table role colors: brighter variants for dark surfaces */
:root[data-theme="dark"] .rxn-row-reagent,:root[data-theme="dark"] .rxn-role-reagent,:root[data-theme="dark"] .rxn-role-reactant{color:#e3a94f}
:root[data-theme="dark"] .rxn-row-catalyst,:root[data-theme="dark"] .rxn-role-catalyst{color:#b79bf2}
:root[data-theme="dark"] .rxn-row-solvent,:root[data-theme="dark"] .rxn-role-solvent{color:#4ecbbd}
:root[data-theme="dark"] .rxn-row-product,:root[data-theme="dark"] .rxn-role-product{color:#5fce8f}
body{background:var(--bg);color:var(--text);font-family:var(--sans);font-size:14px;min-height:100vh;overflow-x:hidden;-webkit-font-smoothing:antialiased}
::selection{background:var(--accent-light);color:var(--accent)}
::-webkit-scrollbar{width:6px;height:6px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border2);border-radius:var(--r-xs)}
::-webkit-scrollbar-thumb:hover{background:var(--text3)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* ── AUTH OVERLAY ─────────────────────────────────────────────── */
#auth-overlay{position:fixed;inset:0;background:var(--overlay-bg);z-index:999;display:flex;align-items:center;justify-content:center}
.auth-card{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-xl);padding:36px 40px;width:380px;max-width:95vw;box-shadow:var(--shadow-lg)}
.auth-card h1{font-size:16px;font-weight:600;letter-spacing:-.3px;margin-bottom:4px}
.auth-card .subtitle{font-size:12px;color:var(--text3);margin-bottom:28px}
.auth-form .form-row{margin-bottom:14px}
.auth-form label{display:block;font-size:11px;color:var(--text3);margin-bottom:5px;font-weight:500}
.auth-form input{width:100%;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-sm);padding:9px 12px;color:var(--text);font-size:13px;font-family:var(--sans);outline:none;transition:border .15s,box-shadow .15s}
.auth-form input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-light)}
.auth-error{font-size:12px;color:var(--red);margin-bottom:12px;display:none}
.auth-btn{width:100%;padding:10px;background:var(--accent);color:#fff;border:none;border-radius:var(--r-md);font-size:13px;font-family:var(--sans);font-weight:500;cursor:pointer;transition:background .15s,box-shadow .15s;margin-top:4px;box-shadow:var(--shadow-sm)}
.auth-btn:hover{background:var(--accent-hover);box-shadow:var(--shadow-md)}
.auth-logo{display:flex;align-items:center;gap:10px;margin-bottom:24px}
.auth-logo-suffix{font-size:15px;font-weight:600;letter-spacing:-.2px;color:var(--text)}
#auth-network-bg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0}
.auth-card{position:relative;z-index:1}
.logo-img{width:22px;height:22px;object-fit:contain;border-radius:var(--r-xs);vertical-align:middle;margin-right:2px}

/* ── HEADER ───────────────────────────────────────────────────── */
header{position:sticky;top:0;z-index:200;background:var(--header-bg);backdrop-filter:blur(12px);border-bottom:1px solid var(--border);height:56px;display:flex;align-items:stretch;padding:0 20px;gap:16px;box-shadow:var(--shadow-sm)}
.logo{font-family:var(--sans);font-size:14px;font-weight:600;letter-spacing:-.02em;display:flex;align-items:center;gap:8px;flex-shrink:0}
.logo-badge{background:var(--accent-light);color:var(--accent);font-size:9px;padding:2px 6px;border-radius:var(--r-xs);font-weight:600;letter-spacing:.02em}
.logo-mark-wrap{transition:transform .4s cubic-bezier(.34,1.56,.64,1)}
.logo:hover .logo-mark-wrap{transform:scale(1.12)}
nav{display:flex;gap:2px;flex:1;align-items:center;padding:0 4px}
.nav-item{display:flex;align-items:center;padding:5px 12px;border-radius:var(--r-md);border:none;font-size:13px;color:var(--text3);cursor:pointer;background:transparent;transition:color .12s,background .12s;height:36px;font-weight:500}
.nav-dot{display:inline-flex;align-items:center;justify-content:center;background:var(--red);color:#fff;font-size:9px;font-weight:700;min-width:14px;height:14px;padding:0 3px;border-radius:var(--r-sm);margin-left:5px;line-height:1}
.nav-item:hover{color:var(--text2);background:var(--bg3)}
.nav-item.active{color:var(--accent);font-weight:600;background:var(--accent-light)}
.module-locked{opacity:.5!important;pointer-events:none!important;filter:grayscale(.3)}
.module-lock-icon{display:inline-flex;vertical-align:middle;margin-left:5px;flex-shrink:0}
.module-lock-overlay{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;color:var(--text2);background:var(--bg2);z-index:5;text-align:center;font-size:13px;font-weight:500}
.user-menu{display:flex;align-items:center;gap:10px;flex-shrink:0;align-self:center}
.user-badge{display:flex;align-items:center;gap:7px;padding:5px 10px;border-radius:var(--r-md);background:var(--bg3);border:1px solid var(--border);font-size:12px;color:var(--text2);cursor:pointer;position:relative;transition:background .12s,border-color .12s}
.user-badge:hover{background:var(--bg4);border-color:var(--border2)}
.user-avatar{min-width:22px;height:22px;border-radius:999px;background:var(--accent);color:#fff;font-size:10px;font-weight:600;display:flex;align-items:center;justify-content:center;padding:0 3px;box-sizing:border-box;letter-spacing:-.2px;overflow:hidden}
.user-avatar img{width:100%;height:100%;object-fit:cover}
.user-avatar svg{flex-shrink:0}
.user-role{font-size:10px;color:var(--text3);font-family:var(--mono)}
.user-dropdown{position:absolute;top:calc(100% + 6px);right:0;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-lg);min-width:180px;z-index:300;display:none;overflow:hidden;box-shadow:var(--shadow-md)}
.user-dropdown.open{display:block}
.user-dropdown button{width:100%;padding:9px 14px;text-align:left;background:transparent;border:none;color:var(--text2);font-size:12px;font-family:var(--sans);cursor:pointer;transition:background .1s,color .1s}
.user-dropdown button:hover{background:var(--bg3);color:var(--text)}
.user-dropdown .dd-sep,.help-hud-body .dd-sep{height:1px;background:var(--border);margin:8px 0}

/* ── NOTIFICATION CENTER ──────────────────────────────────────── */
.notif-markall{background:none;border:none;padding:2px 4px;font-size:11px;color:var(--accent);cursor:pointer}
.notif-group-label{padding:10px 2px 4px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text3);border-top:1px solid var(--border);margin-top:4px}
.notif-group-label:first-of-type{border-top:none;margin-top:0}
.notif-item{display:flex;align-items:flex-start;gap:9px;padding:8px 6px;border-radius:var(--r-sm);cursor:pointer;transition:background .12s}
.notif-item:hover{background:var(--bg3)}
.notif-item.read{opacity:.5;cursor:default}
.notif-item.read:hover{background:none}
.notif-icon{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:12px;font-weight:700;margin-top:1px}
.notif-body{flex:1;min-width:0}
.notif-text{font-size:13px;line-height:1.4;color:var(--text)}
.notif-time{font-size:11px;color:var(--text3);margin-top:2px;font-family:var(--mono)}
.notif-dismiss{width:20px;height:20px;flex-shrink:0;display:flex;align-items:center;justify-content:center;background:none;border:none;padding:0;font-size:11px;color:var(--text3);cursor:pointer;border-radius:var(--r-xs);transition:background .12s,color .12s}
.notif-dismiss:hover{background:var(--bg4);color:var(--text)}
.notif-showmore{width:auto;background:none;border:none;padding:4px 6px 8px;font-size:11px;color:var(--accent);cursor:pointer;text-align:left}
.notif-showmore.muted{color:var(--text3)}

/* ── LAYOUT ───────────────────────────────────────────────────── */
.page{display:none}
.page.active{display:contents}
#page-home.active{display:block;padding:32px 24px;max-width:1100px;margin:0 auto;width:100%}
/* Stock-ticker-style scrolling strip for active announcements, bleeding
   edge-to-edge above #page-home's own padding so it reads as sitting right
   under the header, not as another card in the content column. Track holds
   the item list duplicated twice back-to-back so the loop has no visible
   seam. Keeps scrolling on hover by design — pausing made the strip feel
   broken/stuck, and every item is short enough to read mid-scroll anyway. */
/* #page-home is a centered max-width:1100px column, so plain negative
   margins only break out to that column's own edges — the "break out of a
   centered container" trick (100vw + 50% left offset via position:relative)
   is what actually reaches the real browser window edges either side. */
.home-ticker{position:relative;left:50%;right:50%;margin-left:-50vw;margin-right:-50vw;width:100vw;overflow:hidden;background:var(--bg2);border-bottom:1px solid var(--border);margin-top:-32px;margin-bottom:20px;white-space:nowrap}
.home-ticker-track{display:inline-flex;align-items:center;animation:home-ticker-scroll 15s linear infinite}
.home-ticker-item{display:inline-flex;align-items:center;gap:6px;padding:7px 28px;font-size:12px;color:var(--text2);flex-shrink:0}
.home-ticker-item strong{color:var(--text);font-weight:600}
.home-ticker-item .home-ticker-dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}
@media(prefers-reduced-motion:reduce){.home-ticker-track{animation:none}}
@keyframes home-ticker-scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* Docking job progress bar while a ligand is actively being docked — real
   progress_current/progress_total only advances between whole ligands, so
   it sits frozen at the same width for however long a single Vina run
   takes (minutes). This sweeping segment is a deliberately fake "it's
   alive" cue for that in-between time, not a real progress indicator. */
.comp-dock-indeterminate{position:absolute;top:0;bottom:0;left:0;width:35%;background:var(--accent);border-radius:3px;animation:comp-dock-sweep 1.4s ease-in-out infinite}
@keyframes comp-dock-sweep{0%{left:-35%}100%{left:100%}}

/* Docking sidebar (grouped preps/jobs) + detail pane — .cv-dock-row is the
   shared selectable-card look for both a prep header and a job row so
   selection highlighting (--active) reads the same regardless of which
   kind of row it's on. */
.cv-dock-row{transition:border-color .12s,background .12s}
.cv-dock-row--active{border-color:var(--accent) !important;background:color-mix(in srgb,var(--accent) 10%,var(--bg2)) !important}
.cv-dock-group{margin-bottom:14px}
.cv-dock-detail-empty{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text3);font-size:13px;text-align:center}
.home-hero{margin-bottom:28px}
.home-hero h2{font-size:20px;font-weight:600;letter-spacing:-.02em;margin-bottom:4px}
.home-hero p{font-size:13px;color:var(--text3)}
.home-hero p a{color:var(--text2);cursor:pointer;text-decoration:none}
.home-hero p a:hover{color:var(--accent)}
.home-hero p strong{font-family:var(--mono);font-weight:600}
.home-section{margin-bottom:32px}
.home-section:last-child{margin-bottom:0}
.home-section-title{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--text3);margin-bottom:12px;display:flex;align-items:center;gap:6px}
.home-relations-icon{display:inline-flex;color:var(--text3);cursor:pointer;transition:color .15s}
.home-relations-icon:hover{color:var(--accent)}
.home-empty-note{font-size:12px;color:var(--text3);padding:10px 2px}
#home-banners{margin-bottom:20px}
.home-2col{display:grid;grid-template-columns:1fr 1fr;gap:28px;align-items:start;margin-bottom:32px}
.home-2col .home-section{margin-bottom:0}
.home-2col.single{grid-template-columns:1fr}
@media(max-width:700px){.home-2col{grid-template-columns:1fr}}

.home-next-item{display:flex;align-items:center;gap:6px;padding:2px 0;font-size:12px}
.home-next-item .dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.mq-status-chip{font-family:var(--sans);font-size:11px;font-weight:500;text-transform:none;color:var(--text3);
  background:var(--bg3);border-radius:var(--r-xs);padding:1px 6px;flex-shrink:0}
.home-task-icon-btn{display:flex;align-items:center;justify-content:center;width:19px;height:19px;padding:0;border:none;background:none;border-radius:var(--r-sm);color:var(--text3);cursor:pointer;transition:background .15s,color .15s;flex-shrink:0}
.home-task-icon-btn:hover{background:var(--bg3);color:var(--text)}
.home-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.home-grid.home-grid-small{grid-template-columns:repeat(7,minmax(0,1fr));gap:10px}
.home-grid.home-grid-big{grid-template-columns:repeat(2,minmax(0,1fr))}
@media(max-width:1100px){
  .home-grid.home-grid-small{grid-template-columns:repeat(4,minmax(0,1fr))}
}
@media(max-width:900px){
  .home-grid,.home-grid.home-grid-small,.home-grid.home-grid-big{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(max-width:560px){
  .home-grid,.home-grid.home-grid-small,.home-grid.home-grid-big{grid-template-columns:minmax(0,1fr)}
}
/* Small: 7 modules in one row — same icon-left structure as Medium/Big,
   just narrower. No room for the stat number, so that's dropped; title and
   description wrap instead of ellipsis-truncating. Description is always
   exactly 2 lines — clamped so it never grows past that, and a min-height
   reserving that same 2-line space so every card lines up even when its
   text is short enough to only need one. */
.home-grid-small .home-card{padding:12px;gap:8px;min-width:0}
.home-grid-small .home-card-stat{display:none}
.home-grid-small .home-card-icon{width:32px;height:32px}
.home-grid-small .home-card-title{white-space:normal;font-size:13px}
.home-grid-small .home-card-desc{white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:11px;line-height:1.35;min-height:calc(1.35em * 2)}
.home-links-row{display:flex;flex-wrap:wrap;justify-content:center;gap:36px}
.home-link-btn{display:flex;flex-direction:column;align-items:center;gap:6px;width:72px;padding:8px 4px;border-radius:var(--r-md);text-decoration:none;color:var(--text2);transition:background .15s,transform .15s}
.home-link-btn:hover{background:var(--bg2);transform:translateY(-2px)}
.home-link-btn img{width:18px;height:18px;object-fit:contain;filter:grayscale(1);opacity:.6;transition:filter .15s,opacity .15s}
.home-link-btn:hover img{filter:grayscale(0);opacity:1}
.home-link-fallback{width:18px;height:18px;border-radius:var(--r-xs);background:var(--bg3);display:flex;align-items:center;justify-content:center;font-size:8px;font-weight:700;color:var(--text3)}
.hl-preset-btn{display:flex;flex-direction:column;align-items:center;gap:5px;width:66px;padding:8px 4px;border:1px solid var(--border2);border-radius:var(--r-md);background:var(--bg2);color:var(--text2);font-size:11px;cursor:pointer;transition:border-color .15s,background .15s}
.hl-preset-btn:hover{border-color:var(--accent);background:var(--bg2)}
.hl-preset-icon{display:flex;align-items:center;justify-content:center;width:20px;height:20px}
.home-link-btn span{font-size:11px;text-align:center;overflow-wrap:break-word;white-space:normal;line-height:1.25;max-width:100%}
.home-card{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-lg);padding:16px;cursor:pointer;transition:border-color .18s,box-shadow .18s,transform .18s;display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:12px;box-shadow:var(--shadow-sm);animation:card-in .42s cubic-bezier(.22,1,.36,1) backwards;min-width:0}
.home-card-main{display:flex;flex-direction:column;gap:6px;min-width:0;flex:1}
.home-card-stat{text-align:right;flex-shrink:0}
.home-card:nth-child(1){animation-delay:.04s}.home-card:nth-child(2){animation-delay:.09s}.home-card:nth-child(3){animation-delay:.14s}.home-card:nth-child(4){animation-delay:.19s}.home-card:nth-child(5){animation-delay:.24s}.home-card:nth-child(6){animation-delay:.29s}.home-card:nth-child(7){animation-delay:.34s}
@keyframes card-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}
.home-card:hover{border-color:color-mix(in srgb,var(--card-color,var(--border2)) 45%,var(--border));box-shadow:var(--shadow-md),0 0 0 1px color-mix(in srgb,var(--card-color,transparent) 12%,transparent);transform:translateY(-3px)}
.home-card-icon{width:38px;height:38px;border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .2s,color .2s,transform .22s cubic-bezier(.34,1.56,.64,1)}
.home-card:hover .home-card-icon{background:var(--card-bg,var(--bg3))!important;color:var(--card-color,var(--text2))!important;transform:scale(1.1)}
.home-card:hover .home-card-icon svg{animation:none}
/* Chemistry: flask rocks + liquid rises + bubbles */
.ico-bubble1,.ico-bubble2,.ico-bubble3{transform-box:fill-box;transform-origin:center}
.home-card[data-tab="eln"]:hover .home-card-icon svg{animation:flask-rock .75s cubic-bezier(.36,.07,.19,.97) forwards;transform-box:fill-box;transform-origin:center bottom}
.home-card[data-tab="eln"]:hover .ico-flask-fill{animation:flask-rise .45s ease .05s forwards}
.home-card[data-tab="eln"]:hover .ico-bubble1{animation:bubble-up 1.4s ease 0s infinite}
.home-card[data-tab="eln"]:hover .ico-bubble2{animation:bubble-up 1.4s ease .45s infinite}
.home-card[data-tab="eln"]:hover .ico-bubble3{animation:bubble-up 1.4s ease .9s infinite}
/* Biology: DNA rotation handled by _initDnaRotation() RAF loop */
/* Lab: sun/moon day-night cycle behind the building (home card only; nav icon is static) */
/* Library: loupe scans shelf in loop */
.ico-loupe{opacity:0;transition:opacity .2s ease}
.ico-openbook{opacity:0}
.home-card[data-tab="library"]:hover .ico-loupe{opacity:1;animation:loupe-circle 2s linear infinite}
@keyframes loupe-circle{0%{transform:translate(4px,0)}25%{transform:translate(0,4px)}50%{transform:translate(-4px,0)}75%{transform:translate(0,-4px)}100%{transform:translate(4px,0)}}
/* Projects: briefcase → bulleted list */
.ico-brief-body,.ico-brief-lid{transition:opacity .18s ease .28s}
.ico-bullet1,.ico-bullet2,.ico-bullet3{opacity:0;transition:opacity .2s ease}
.ico-listline1,.ico-listline2,.ico-listline3{opacity:0;transform:translateX(-4px);transition:opacity .25s ease,transform .25s ease}
.home-card[data-tab="projects"]:hover .ico-brief-body,.home-card[data-tab="projects"]:hover .ico-brief-lid{opacity:0;transition-delay:0s}
.home-card[data-tab="projects"]:hover .ico-bullet1{opacity:1;transition-delay:.18s}
.home-card[data-tab="projects"]:hover .ico-bullet2{opacity:1;transition-delay:.28s}
.home-card[data-tab="projects"]:hover .ico-bullet3{opacity:1;transition-delay:.38s}
.home-card[data-tab="projects"]:hover .ico-listline1{opacity:1;transform:translateX(0);transition-delay:.18s}
.home-card[data-tab="projects"]:hover .ico-listline2{opacity:1;transform:translateX(0);transition-delay:.28s}
.home-card[data-tab="projects"]:hover .ico-listline3{opacity:1;transform:translateX(0);transition-delay:.38s}
/* Lab building: sun and moon swing in an arc over the roof (pivot below the building), taking turns (loop) */
.ico-lab-sun,.ico-lab-moon{opacity:0;transform-box:view-box;transform-origin:9px 16.5px;transform:rotate(75deg)}
.home-card[data-tab="equipment"]:hover .ico-lab-sun{animation:lab-sun-cycle 5s linear infinite}
.home-card[data-tab="equipment"]:hover .ico-lab-moon{animation:lab-moon-cycle 5s linear infinite}
@keyframes lab-sun-cycle{0%{transform:rotate(75deg);opacity:0}12%{transform:rotate(45deg);opacity:1}38%{transform:rotate(-45deg);opacity:1}50%{transform:rotate(-75deg);opacity:0}100%{transform:rotate(-75deg);opacity:0}}
@keyframes lab-moon-cycle{0%,50%{transform:rotate(75deg);opacity:0}62%{transform:rotate(45deg);opacity:1}88%{transform:rotate(-45deg);opacity:1}100%{transform:rotate(-75deg);opacity:0}}
/* Lab easter egg: 30s hover → a UFO flies in, abducts the "Lab" title (and a cow) */
.home-card-header{position:relative}
.lab-ufo-scene{position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:12}
.ufo-craft{position:absolute;left:0;top:-8px;animation:ufo-flyover-header 4.2s cubic-bezier(.4,0,.2,1) forwards}
.ufo-light{animation:ufo-lights-blink .5s steps(1) infinite}
.ufo-light:nth-child(2){animation-delay:.12s}
.ufo-light:nth-child(3){animation-delay:.24s}
.ufo-beam{position:absolute;left:44px;top:4px;width:34px;height:28px;background:linear-gradient(to bottom,rgba(125,211,252,.6),rgba(125,211,252,0));clip-path:polygon(38% 0,62% 0,100% 100%,0% 100%);opacity:0;transition:opacity .3s ease}
.lab-ufo-scene.beaming .ufo-beam{opacity:1;animation:ufo-beam-pulse 1s ease-in-out infinite}
.ufo-cow{position:absolute;left:56px;top:24px;font-size:12px;opacity:0;line-height:1}
.lab-ufo-scene.beaming .ufo-cow{animation:ufo-cow-abduct .9s ease-in forwards}
@keyframes ufo-flyover-header{
  0%{transform:translate(-24px,6px) scale(.6);opacity:0}
  10%{opacity:1}
  30%{transform:translate(30px,0) scale(.9)}
  50%,75%{transform:translate(48px,-2px) scale(1)}
  88%{opacity:1}
  100%{transform:translate(100px,8px) scale(.6);opacity:0}
}
@keyframes ufo-beam-pulse{0%,100%{opacity:.7}50%{opacity:1}}
@keyframes ufo-lights-blink{0%,49%{opacity:1}50%,100%{opacity:.25}}
@keyframes ufo-cow-abduct{
  0%{opacity:0;transform:translateY(0) scale(.6) rotate(0deg)}
  20%{opacity:1;transform:translateY(-2px) scale(.8) rotate(-10deg)}
  100%{opacity:0;transform:translateY(-26px) scale(.15) rotate(20deg)}
}
.home-card-title.ufo-abducted{animation:title-abduct 1s ease-in forwards}
.home-card-title.ufo-restored{animation:title-restore .5s cubic-bezier(.34,1.56,.64,1) forwards}
@keyframes title-abduct{0%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:0;transform:translateY(-22px) scale(.7)}}
@keyframes title-restore{0%{opacity:0;transform:translateY(-10px) scale(.7)}60%{opacity:1;transform:translateY(2px) scale(1.08)}100%{opacity:1;transform:translateY(0) scale(1)}}
@media(prefers-reduced-motion:reduce){.lab-ufo-scene{display:none}.home-card-title.ufo-abducted,.home-card-title.ufo-restored{animation:none!important}}
@keyframes flask-rock{0%{transform:rotate(0)}25%{transform:rotate(-10deg)}60%{transform:rotate(8deg)}80%{transform:rotate(-4deg)}100%{transform:rotate(0)}}
@keyframes flask-rise{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:translateY(0)}}
@keyframes bubble-up{0%{opacity:0;transform:translateY(0)}15%{opacity:.9}75%{opacity:.7;transform:translateY(-5px)}100%{opacity:0;transform:translateY(-8px)}}
/* DNA rotation is handled by _initDnaRotation() in app.js (RAF, path computation) */
@keyframes chart-march{to{stroke-dashoffset:-6.5}}
/* Orders tab — shopping cart wheels */
.ico-wheel-l,.ico-wheel-r{transform-box:fill-box;transform-origin:center}
.home-card[data-tab="orders"]:hover .ico-wheel-l{animation:wheel-spin .45s linear infinite}
.home-card[data-tab="orders"]:hover .ico-wheel-r{animation:wheel-spin .45s linear infinite}
@keyframes wheel-spin{to{transform:rotate(360deg)}}
/* Chemistry easter egg: long hover → flask disappears, leaves a sad face */
.flask-heating svg{animation:flask-shake-mild .3s ease-in-out infinite!important;transform-box:fill-box;transform-origin:center bottom}
@keyframes flask-shake-mild{0%,100%{transform:rotate(0)}30%{transform:rotate(-9deg)}70%{transform:rotate(9deg)}}
.flask-kaboom svg{animation:flask-vanish .35s ease-in forwards!important;transform-box:fill-box;transform-origin:center}
@keyframes flask-vanish{0%{transform:scale(1);opacity:1}40%{transform:scale(1.1);opacity:.6}100%{transform:scale(0);opacity:0}}
.home-card-icon{position:relative;overflow:visible}
/* A rotated ":(" reads as an actual face (colon → two eyes side by side,
   parenthesis → a frown underneath) instead of flat sideways punctuation.
   The rotation lives on the inner span (shrink-wrapped to the glyphs, so it
   pivots around its own visual center) — the outer div just centers that
   span in the icon box, untransformed. */
.flask-sadface{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none;color:var(--red)}
.flask-sadface span{display:inline-block;font-size:15px;font-weight:700;line-height:1;white-space:nowrap;animation:sadface-pop .35s ease-out forwards}
@keyframes sadface-pop{0%{transform:rotate(90deg) scale(0);opacity:0}60%{transform:rotate(90deg) scale(1.2);opacity:1}100%{transform:rotate(90deg) scale(1);opacity:1}}
/* Neutral (no fire-colored) explosion flash right as the flask vanishes */
.flask-boom{position:absolute;inset:-6px;border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,.95) 0%,var(--text3) 55%,transparent 100%);animation:boom-expand .5s ease-out forwards;pointer-events:none;z-index:10}
.flask-boom::after{content:'';position:absolute;inset:-8px;border-radius:50%;border:3px solid var(--text3);opacity:.6;animation:boom-shockwave .5s ease-out .03s forwards}
@keyframes boom-expand{0%{transform:scale(0);opacity:1}60%{opacity:.85}100%{transform:scale(3);opacity:0}}
@keyframes boom-shockwave{0%{transform:scale(.3);opacity:.7}100%{transform:scale(4);opacity:0}}
.home-card-title{font-size:14px;font-weight:600;letter-spacing:-.01em;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.home-card-desc{font-size:12px;color:var(--text3);line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.home-stat-main{font-size:20px;font-weight:600;font-family:var(--mono);letter-spacing:-.04em;line-height:1;color:var(--text)}
.home-stat-sub{font-size:11px;color:var(--text3);margin-top:3px}
.home-card[data-tab="computational"]:hover .ico-comp-bar{opacity:.85;animation:ico-comp-bar-slide 1s ease-in-out infinite}
@keyframes ico-comp-bar-slide{0%,100%{transform:translateX(0)}50%{transform:translateX(6px)}}
@media(prefers-reduced-motion:reduce){.home-card[data-tab="computational"]:hover .ico-comp-bar{animation:none;opacity:.85}}
/* Admin → Site → Home page → Icon behavior: "Animate module icons on hover"
   off. DNA rotation is skipped at the JS level (_initDnaRotation's animate
   arg); everything else here is pure CSS keyframes, so they're neutralized
   the same way prefers-reduced-motion already handles Computational above. */
#home-grid.home-icons-static .home-card[data-tab="eln"]:hover .home-card-icon svg,
#home-grid.home-icons-static .home-card[data-tab="eln"]:hover .ico-flask-fill,
#home-grid.home-icons-static .home-card[data-tab="eln"]:hover .ico-bubble1,
#home-grid.home-icons-static .home-card[data-tab="eln"]:hover .ico-bubble2,
#home-grid.home-icons-static .home-card[data-tab="eln"]:hover .ico-bubble3,
#home-grid.home-icons-static .home-card[data-tab="equipment"]:hover .ico-lab-sun,
#home-grid.home-icons-static .home-card[data-tab="equipment"]:hover .ico-lab-moon,
#home-grid.home-icons-static .home-card[data-tab="library"]:hover .ico-loupe,
#home-grid.home-icons-static .home-card[data-tab="computational"]:hover .ico-comp-bar{animation:none!important}
#page-library.active{display:flex;flex-direction:column;height:calc(100vh - 56px);overflow:hidden}
/* Flexbox, same as every other sidebar+content pane (ELN/Bio/Projects/
   Equipment/Reagents/Orders) — this used to be a CSS Grid with a second,
   separately-toggled .sidebar-collapsed class on this container to swap
   grid-template-columns, kept in sync with #library-sidebar's own
   .collapsed by hand in toggleLibrarySidebar()/initLibrarySidebar(). Two
   elements' classes staying frame-perfectly in sync (plus the aside's own
   width transition animating independently of the grid's instant column
   snap) was the actual cause behind "sidebar sometimes collapses wrong,
   especially in Library" — a flex child's width transition alone, like
   every other sidebar already uses, has nothing else to fall out of sync
   with. */
#lib-compounds-inner{display:flex;flex:1;overflow:hidden;min-height:0}
#main-compounds{flex:1;min-width:0}
#lib-boxes-inner{display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden}
/* Boxes gets its own filter sidebar (search/project/location/sort) — same
   flex sidebar+content shape as bio-results (#lib-bio-results-inner);
   Plates keeps the old simple centered/padded layout, now on itself since
   the padding moved off the shared #lib-boxes-inner wrapper. */
.storage-shell{display:flex;min-height:0;flex:1;overflow:hidden}
#lib-bio-results-inner{display:flex;flex:1;overflow:hidden;min-height:0}
#lib-charts-inner{display:flex;flex:1;overflow:hidden;min-height:0}
#page-eln.active,#page-bio.active,#page-projects.active,#page-orders.active,#page-admin.active{display:flex;flex-direction:column;min-height:calc(100vh - 56px);padding:0;max-width:none}
#page-equipment.active,#page-computational.active{display:flex;flex-direction:column;height:calc(100vh - 56px);padding:0;max-width:none;overflow:hidden}
#page-orders.active{height:calc(100vh - 56px)}
#page-eln.active,#page-bio.active,#page-projects.active,#page-admin.active{height:calc(100vh - 56px)}
#admin-content{flex:1;overflow-y:auto;padding:24px;width:100%;box-sizing:border-box}
/* Shared shell for every left filter/list sidebar that isn't .eln-list
   (Equipment, Maintenance, Team, Dissemination, Projects) -- same base
   layout and header padding repeated 5x byte-for-byte before this; each
   module still owns its own collapsed-state hide rule below since which
   children get hidden differs per module. */
.side-panel{width:260px;flex-shrink:0;border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;transition:width .2s ease}
.side-panel.collapsed{width:36px}
.side-panel-header{padding:14px 14px 10px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:8px;flex-shrink:0}
#maint-sidebar.collapsed #maint-sidebar-header>:not(.sidebar-toggle-btn),#maint-sidebar.collapsed>:not(#maint-sidebar-header){display:none!important}
#team-sidebar.collapsed #team-sidebar-header>:not(.sidebar-toggle-btn),#team-sidebar.collapsed>:not(#team-sidebar-header){display:none!important}
#diss-sidebar.collapsed #diss-sidebar-header>:not(.sidebar-toggle-btn),#diss-sidebar.collapsed>:not(#diss-sidebar-header){display:none!important}
.equip-list-row{display:flex;align-items:center;gap:10px;padding:9px 14px;cursor:pointer;border-bottom:1px solid var(--border);transition:background .1s;font-size:13px;color:var(--text2)}
.equip-list-row:hover{background:var(--bg3)}
.equip-list-row.active{background:var(--accent-light);color:var(--accent);font-weight:600}
.equip-list-row.active .equip-status{box-shadow:0 0 0 2px var(--accent-light)}
.equip-list-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}
.equip-list-meta{font-size:11px;color:var(--text3);white-space:nowrap}
.equip-list-group-header{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text3);padding:10px 14px 4px;margin-top:4px}
.equip-list-group-header:first-child{margin-top:0}
#equip-detail-panel{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0}
.bk-provider-btn:hover{border-color:var(--accent)!important;box-shadow:0 0 0 3px var(--accent-light)}
.integration-card:hover{border-color:var(--accent)!important;box-shadow:0 0 0 3px var(--accent-light)}
#equip-detail-bar{justify-content:space-between;flex-shrink:0}
#equip-cards-inner{padding:16px}
.subtab-strip{display:flex;align-items:center;gap:2px;padding:8px 14px;min-height:48px;box-sizing:border-box;border-bottom:1px solid var(--border);background:var(--bg2);flex-shrink:0}
/* Sub-navigation system: .subtab (pill, default) + variants
   .subtab--tab (underline tabs in Chem/Bio sidebars) and
   .subtab--row (full-width sidebar rows in Reagents/Orders). */
.subtab{padding:5px 14px;border-radius:var(--r-md);font-size:12px;color:var(--text3);cursor:pointer;border:none;background:transparent;transition:all .12s;font-weight:500}
.subtab:hover{color:var(--text2);background:var(--bg3)}
.subtab.active{color:var(--accent);font-weight:600;background:var(--accent-light)}
.subtab--tab{flex:1;padding:6px 4px;font-size:11px;border-radius:0;border-bottom:2px solid transparent;margin-bottom:-1px}
.subtab--tab:hover{background:transparent}
.subtab--tab.active{background:transparent;border-bottom-color:var(--accent)}
.subtab--row{display:block;width:100%;text-align:left;padding:7px 14px;font-size:13px;color:var(--text2);border-radius:0;white-space:nowrap}

/* ── SIDEBAR ──────────────────────────────────────────────────── */
/* Background lives on each sidebar's own class/id below, not here — this
   bare-tag rule used to carry it too, which meant only the sidebars that
   happen to be an <aside> element (Library, Storage, Bio charts, Projects)
   got var(--bg2); the rest (plain <div>s) fell through to the page's own
   --bg and came out visibly grayer. */
aside{border-right:1px solid var(--border);padding:14px;overflow-y:auto;position:sticky;top:56px;height:calc(100vh - 56px)}
.eln-list,.pj-sidebar,#equip-sidebar,#maint-sidebar,#team-sidebar,#diss-sidebar{background:var(--bg2)}
.sl{font-family:var(--sans);font-size:10px;color:var(--text3);font-weight:700;margin-bottom:7px;padding-top:2px;text-transform:uppercase;letter-spacing:.06em}
.ss{margin-bottom:18px}
.search-wrap{position:relative;margin-bottom:10px}
.search-wrap input{width:100%;background:var(--bg3);border:1px solid var(--border);border-radius:var(--r-md);padding:8px 10px 8px 30px;color:var(--text);font-size:12px;font-family:var(--sans);outline:none;transition:border .15s,box-shadow .15s}
.search-wrap input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-light)}
.search-wrap input::placeholder{color:var(--text3)}
.si{position:absolute;left:9px;top:50%;transform:translateY(-50%);color:var(--text3);font-size:13px}
.fc{display:flex;align-items:center;justify-content:space-between;padding:5px 8px;border-radius:var(--r-sm);cursor:pointer;font-size:12px;color:var(--text2);border:none;background:transparent;width:100%;text-align:left;transition:all .12s;gap:6px}
.fc:hover{background:var(--bg3);color:var(--text)}
.fc.active{background:var(--accent-light);color:var(--accent);font-weight:600}
.fc-left{display:flex;align-items:center;gap:6px;min-width:0;overflow:hidden}
.fc-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fc-sub{font-size:10px;color:var(--text3);font-family:var(--mono);white-space:nowrap}
.fc-count{font-family:var(--mono);font-size:10px;background:var(--bg3);padding:1px 5px;border-radius:var(--r-xs);flex-shrink:0;color:var(--text3)}
.fc-right{display:flex;gap:2px;flex-shrink:0}
.stats-grid{display:grid;grid-template-columns:1fr 1fr;gap:5px}
.stat-card{background:var(--bg3);border:1px solid var(--border);border-radius:var(--r-md);padding:9px;text-align:center}
.stat-val{font-family:var(--mono);font-size:18px;font-weight:600;color:var(--text)}
.stat-lbl{font-size:10px;color:var(--text3);margin-top:2px}


/* ── MAIN ─────────────────────────────────────────────────────── */
main{padding:18px;overflow-y:auto;min-height:0}
.toolbar{display:flex;align-items:center;gap:8px;margin-bottom:14px}
.result-count{font-family:var(--mono);font-size:12px;color:var(--text3);flex:1}
select.sort-sel{background:var(--bg2);border:1px solid var(--border2);color:var(--text2);font-size:12px;padding:5px 9px;border-radius:var(--r-sm);outline:none;cursor:pointer;transition:border .15s;font-family:var(--sans)}
select.sort-sel:focus{border-color:var(--accent)}
.view-toggle{display:flex;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-sm);overflow:hidden}
.vb{padding:5px 10px;font-size:13px;cursor:pointer;color:var(--text3);border:none;background:transparent;transition:all .12s}
.vb.active{background:var(--bg3);color:var(--text)}
.btn{display:inline-flex;align-items:center;gap:5px;padding:7px 14px;border-radius:var(--r-md);font-size:12px;font-family:var(--sans);cursor:pointer;transition:all .15s;border:none;white-space:nowrap;font-weight:500}
.btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}
.btn-primary{background:var(--accent);color:#fff;box-shadow:var(--shadow-sm)}
.btn-primary:hover{background:var(--accent-hover);box-shadow:var(--shadow-md)}
.btn-ghost{background:transparent;color:var(--text2);border:1px solid var(--border2)}
.btn-ghost:hover{color:var(--text);background:var(--bg3);border-color:var(--border2)}
.btn-danger{background:transparent;color:var(--red);border:1px solid color-mix(in srgb,var(--red) 40%,transparent)}
#reac-section-search{display:flex;flex-direction:row}
.btn-danger:hover{background:color-mix(in srgb,var(--red) 8%,transparent);border-color:color-mix(in srgb,var(--red) 60%,transparent)}
.btn-sm{padding:4px 9px;font-size:12px}
.btn-icon{padding:4px 7px;font-size:12px;border-radius:var(--r-sm);background:var(--bg3);border:1px solid var(--border);color:var(--text3);cursor:pointer;line-height:1;transition:background .12s,color .12s}
.btn-icon:hover{background:var(--bg4);color:var(--text)}

/* ── ROLE PERMISSION GRID (clickable toggle cells) ───────────── */
.perm-toggle{width:28px;height:24px;padding:0;border:none;background:none;border-radius:var(--r-sm);
  cursor:pointer;color:var(--text3);line-height:1;transition:background .12s,color .12s}
.perm-toggle:hover{background:var(--bg3)}
.perm-toggle.on{color:var(--green)}
.perm-toggle.on:hover{background:color-mix(in srgb,var(--red) 12%,transparent);color:var(--red)}

/* ── DRAFT RECOVERY BANNER ────────────────────────────────────── */
.draft-banner{display:flex;align-items:center;justify-content:space-between;gap:12px;
  background:var(--warn-bg);border:1px solid var(--warn-border);color:var(--warn-fg);
  border-radius:var(--r-sm);padding:8px 12px;margin-bottom:10px;font-size:13px}
.draft-banner-actions{display:flex;gap:6px;flex-shrink:0}

/* ── CARD GRID ────────────────────────────────────────────────── */
.cg{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:10px}
.cg.hide{display:none}
.card{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;cursor:pointer;transition:border-color .15s,box-shadow .15s,transform .15s;position:relative;box-shadow:var(--shadow-sm)}
.card:hover{border-color:var(--border2);box-shadow:var(--shadow-md);transform:translateY(-1px)}
.card-struct{background:var(--bg3);height:125px;display:flex;align-items:center;justify-content:center;border-bottom:1px solid var(--border);position:relative;overflow:hidden;padding:6px;box-sizing:border-box}
.card-struct svg{max-width:100%;max-height:100%;width:auto;height:auto}
#cm-struct-preview svg,#lib-struct-preview svg,#rs-struct-preview svg{max-width:100%;max-height:100%;width:auto;height:auto}
.card-struct svg rect:first-child,.dp-struct svg rect:first-child,#cm-struct-preview svg rect:first-child{fill:var(--bg3)!important}
.card-struct .no-struct{font-size:10px;color:var(--text3);font-family:var(--mono)}
.struct-loading{width:24px;height:24px;border:2px solid var(--border2);border-top-color:var(--accent);border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.stock-dot{position:absolute;top:7px;right:7px;width:7px;height:7px;border-radius:50%;box-shadow:0 0 0 2px var(--bg3)}
.card-body{padding:9px 11px}
.card-id{font-family:var(--sans);font-size:12px;font-weight:700;color:var(--text);margin-bottom:2px}
.card-formula{font-size:10px;color:var(--text3);font-family:var(--mono);margin-bottom:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card-footer{display:flex;justify-content:space-between;font-size:11px;align-items:center}
.vol-badge{display:flex;align-items:center;gap:3px;font-family:var(--mono);font-size:11px}
.dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;display:inline-block}
.card-tags{display:flex;flex-wrap:wrap;gap:3px;margin-top:5px}
/* Badges & chips — one system: .tag-pill (colored pill), and mono data
   badges (.hz-badge/.file-type-badge/.log-action: subtle bg, 4px radius) */
.tag-pill{font-size:9px;padding:2px 7px;border-radius:999px;color:#fff;font-weight:600;white-space:nowrap}
.hazard-mini{display:flex;gap:2px;margin-top:4px;flex-wrap:wrap}
.hz-badge{font-size:9px;padding:1px 5px;border-radius:var(--r-xs);background:color-mix(in srgb,var(--yellow) 12%,transparent);color:var(--yellow);font-family:var(--mono)}

/* ── TABLE ────────────────────────────────────────────────────── */
.ct{width:100%;border-collapse:collapse;display:none}
.ct.show{display:table}
.ct th{font-family:var(--sans);font-size:10px;color:var(--text3);font-weight:700;padding:8px 10px;text-align:left;border-bottom:1px solid var(--border);background:var(--bg3);white-space:nowrap;text-transform:uppercase;letter-spacing:.05em}
.ct td{padding:8px 10px;border-bottom:1px solid var(--border);font-size:13px;color:var(--text2);vertical-align:middle}
.ct tbody tr{transition:background .1s}
.ct tr:hover td{background:var(--accent-light);cursor:pointer;color:var(--text)}
.mono{font-family:var(--mono)}
.smiles-td{max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:var(--mono);font-size:10px}

/* ── DETAIL PANEL ─────────────────────────────────────────────── */
.dp{position:fixed;right:0;top:56px;width:600px;height:calc(100vh - 56px);background:var(--bg2);border-left:1px solid var(--border);transform:translateX(600px);transition:transform .25s cubic-bezier(.4,0,.2,1);z-index:150;display:flex;flex-direction:column;overflow:hidden;box-shadow:-4px 0 24px rgba(0,0,0,.06)}
.help-hud{position:fixed;right:0;top:56px;width:360px;height:calc(100vh - 56px);background:var(--bg2);border-left:1px solid var(--border);transform:translateX(360px);transition:transform .25s cubic-bezier(.4,0,.2,1);z-index:250;display:flex;flex-direction:column;overflow:hidden}
.help-hud.open{transform:translateX(0)}
.help-hud-backdrop{display:none;position:fixed;inset:0;z-index:249}
/* ── Guided tour ── */
/* The cut-out itself carries the chapter's color (a ring plus a soft glow),
   so the thing being pointed at is visibly part of the section being
   explained, not just "the lit rectangle". --tour-chapter is set per step. */
.tour-spotlight{position:fixed;z-index:6000;border-radius:var(--r-md);--tour-backdrop:rgba(17,24,39,.55);box-shadow:0 0 0 3px color-mix(in srgb,var(--tour-chapter,var(--accent)) 85%,transparent),0 0 0 9px color-mix(in srgb,var(--tour-chapter,var(--accent)) 22%,transparent),0 0 0 9999px var(--tour-backdrop);outline:0 solid transparent;outline-offset:2px;pointer-events:none;transition:top .25s ease,left .25s ease,width .25s ease,height .25s ease,box-shadow .25s ease}
/* A click-to-continue step pulses, so it reads as "do something here" rather
   than "read this". Steadier than the error nudge, and in the chapter color. */
.tour-spotlight.awaiting-click{animation:tour-await 1.8s ease-in-out infinite}
@keyframes tour-await{
  0%,100%{box-shadow:0 0 0 3px color-mix(in srgb,var(--tour-chapter,var(--accent)) 85%,transparent),0 0 0 9px color-mix(in srgb,var(--tour-chapter,var(--accent)) 22%,transparent),0 0 0 9999px var(--tour-backdrop)}
  50%{box-shadow:0 0 0 4px var(--tour-chapter,var(--accent)),0 0 0 16px color-mix(in srgb,var(--tour-chapter,var(--accent)) 26%,transparent),0 0 0 9999px var(--tour-backdrop)}
}
@media (prefers-reduced-motion: reduce){ .tour-spotlight.awaiting-click{animation:none} }
:root[data-theme="dark"] .tour-spotlight{--tour-backdrop:rgba(0,0,0,.72)}
.tour-spotlight.nudge{animation:tour-nudge .6s ease}
@keyframes tour-nudge{
  0%,20%,40%,100%{outline-width:0}
  10%,30%{outline-width:3px;outline-color:var(--red)}
}
.tour-card{position:fixed;z-index:6001;width:300px;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:14px 16px;transition:top .25s ease,left .25s ease}
.tour-card h4{font-size:14px;font-weight:600;margin:2px 0 6px}
.tour-card p{font-size:12px;color:var(--text2);line-height:1.5}
.tour-step-label{font-size:10px;color:var(--text3);font-family:var(--mono)}
/* Chapter identity: each section of the tour tints its own card, so it is
   obvious at a glance which module is being explained (and that the tour has
   moved on to a new one). --tour-chapter is set per step in _tourShow. */
.tour-card{border-top:3px solid var(--tour-chapter,var(--accent))}
.tour-chapter-bar{display:flex;align-items:center;gap:6px;margin-bottom:7px}
.tour-chapter-dot{width:7px;height:7px;border-radius:50%;background:var(--tour-chapter,var(--accent));flex-shrink:0}
.tour-chapter-name{font-size:11px;font-weight:700;color:var(--tour-chapter,var(--accent));letter-spacing:.02em}
.tour-chapter-count{font-size:10px;color:var(--text3)}
.tour-chapter-bar .tour-step-label{margin-left:auto}
.tour-progress{height:3px;border-radius:2px;background:var(--bg3);overflow:hidden;margin-bottom:10px}
.tour-progress>span{display:block;height:100%;background:var(--tour-chapter,var(--accent));border-radius:2px;transition:width .25s ease}
/* Opening "how much do you want to see" picker */
.tour-mode-opt{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;text-align:left;padding:11px 13px;border:1px solid var(--border);border-radius:var(--r-md);background:var(--bg2);cursor:pointer;transition:border-color .15s,background .15s}
.tour-mode-opt:hover{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 6%,var(--bg2))}
.tour-mode-opt-title{font-size:13px;font-weight:600;color:var(--text)}
.tour-mode-opt-sub{font-size:12px;color:var(--text2);line-height:1.45}
.tour-mode-opt-meta{font-size:11px;color:var(--text3);font-family:var(--mono);margin-top:2px}
.tour-actions{display:flex;gap:6px;margin-top:12px;align-items:center;flex-wrap:wrap}
.tour-hint{font-size:11px;color:var(--accent);font-weight:600;margin-top:8px;display:flex;align-items:center;flex-wrap:wrap;gap:4px}
.tour-kbd{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 5px;border-radius:var(--r-sm);border:1px solid var(--border2);background:var(--bg3);color:var(--text);font-family:var(--mono);font-size:11px;font-weight:700;box-shadow:0 2px 0 var(--border2);animation:tour-kbd-press 1.6s ease-in-out infinite}
.tour-kbd-plus{color:var(--text3);font-weight:600}
@keyframes tour-kbd-press{0%,55%,100%{transform:translateY(0);box-shadow:0 2px 0 var(--border2)}28%{transform:translateY(2px);box-shadow:0 0 0 var(--border2)}}
.help-hud-backdrop.open{display:block}
.help-hud-header{padding:14px 18px 12px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-shrink:0}
.help-hud-label{font-size:11px;font-weight:600;color:var(--text3);margin-bottom:2px}
.help-hud-title{font-size:14px;font-weight:600}
.help-hud-body{flex:1;overflow-y:auto;padding:16px 18px 24px}
.hh-section{margin-bottom:20px}
.hh-section h4{font-size:11px;font-weight:600;color:var(--text3);margin-bottom:8px}
.hh-section p,.hh-section li{font-size:13px;color:var(--text2);line-height:1.65}
.hh-section ol,.hh-section ul{padding-left:16px}
.hh-section li{margin-bottom:3px}
.hh-kbd{font-family:var(--mono);background:var(--bg3);border:1px solid var(--border2);padding:1px 5px;border-radius:var(--r-xs);font-size:11px;color:var(--accent)}
.hh-tag{display:inline-block;background:var(--bg3);border:1px solid var(--border2);padding:0px 5px;border-radius:var(--r-xs);font-size:11px;font-family:var(--mono)}
.hh-details{border:1px solid var(--border);border-radius:var(--r-sm);margin-bottom:5px;overflow:hidden}
.hh-details>summary{padding:7px 10px 7px 28px;cursor:pointer;font-size:12px;font-weight:600;color:var(--text2);background:var(--bg3);list-style:none;position:relative;user-select:none}
.hh-details>summary::before{content:'▸';position:absolute;left:10px;top:50%;transform:translateY(-50%);font-size:9px;color:var(--text3);transition:transform .15s}
.hh-details[open]>summary::before{transform:translateY(-50%) rotate(90deg)}
.hh-db{padding:9px 12px;font-size:12px;color:var(--text2);line-height:1.65}
.hh-db p{margin:0 0 5px}.hh-db p:last-child{margin-bottom:0}
.hh-db ol,.hh-db ul{padding-left:16px;margin:0}.hh-db li{margin-bottom:3px}
.nav-icon-group{display:flex;align-items:center;gap:4px;margin:0 6px;flex-shrink:0}
.btn-help,.nav-icon-btn{background:none;border:none;color:var(--text2);width:28px;height:28px;border-radius:var(--r-xs);cursor:pointer;font-size:13px;font-weight:600;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;align-self:center;position:relative;transition:background .15s,color .15s}
.btn-help:hover,.nav-icon-btn:hover{background:var(--bg3);color:var(--text)}
.nav-icon-btn.active{background:var(--accent-light);color:var(--accent)}
.dp.open{transform:translateX(0)}
.dp-header{padding:14px 18px 12px;border-bottom:1px solid var(--border);display:flex;align-items:flex-start;justify-content:space-between;flex-shrink:0}
.dp-header-info{min-width:0;flex:1}
.dp-id{font-family:var(--sans);font-size:16px;font-weight:700;color:var(--text);margin-bottom:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dp-name{font-size:15px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dp-header-actions{display:flex;gap:6px;align-items:center;flex-shrink:0}
.close-btn{background:var(--bg3);border:1px solid var(--border);color:var(--text3);width:28px;height:28px;border-radius:var(--r-sm);cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;transition:background .12s,color .12s}
.close-btn:hover{background:var(--bg4);color:var(--text)}
.dp-body{flex:1;overflow-y:auto}
.dp-section{padding:12px 18px;border-bottom:1px solid var(--border)}
.dp-stitle{font-family:var(--sans);font-size:11px;color:var(--text3);font-weight:600;margin-bottom:9px}
details.dp-section > summary.dp-stitle{cursor:pointer;list-style:none;user-select:none;margin-bottom:0}
details.dp-section > summary.dp-stitle::-webkit-details-marker{display:none}
details.dp-section > summary.dp-stitle::before{content:'▸';display:inline-block;margin-right:6px;font-size:9px;transition:transform .15s}
details.dp-section[open] > summary.dp-stitle::before{transform:rotate(90deg)}
details.dp-section[open] > summary.dp-stitle{margin-bottom:9px}
details.dp-section .prop-row:first-of-type{margin-top:2px}
.dp-struct{background:var(--bg3);border-radius:var(--r-md);height:170px;display:flex;align-items:center;justify-content:center;border:1px solid var(--border);overflow:hidden;margin-bottom:10px;padding:8px;box-sizing:border-box}
/* Cap the SVG instead of forcing it to 100% — object-fit does nothing for an inline
   SVG, so stretching it to the panel width blew large structures past the box. */
.dp-struct svg{max-width:100%;max-height:100%;width:auto;height:auto}
.prop-row{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--divider);font-size:12px;align-items:center}
.prop-row:last-child{border:none}
.pk{color:var(--text2)}
.pv{font-family:var(--mono);color:var(--text);text-align:right;max-width:240px;word-break:break-all}
.hazard-row{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
.hz-chip{display:flex;align-items:center;gap:4px;padding:3px 9px;border-radius:var(--r-sm);background:color-mix(in srgb,var(--yellow) 12%,transparent);border:1px solid color-mix(in srgb,var(--yellow) 25%,transparent);font-size:11px;color:var(--yellow);font-weight:500}
.hz-chip.ghs01,.hz-chip.ghs06{background:color-mix(in srgb,var(--red) 10%,transparent);border-color:color-mix(in srgb,var(--red) 22%,transparent);color:var(--red)}
.hz-chip.ghs02{background:color-mix(in srgb,var(--orange) 10%,transparent);border-color:color-mix(in srgb,var(--orange) 22%,transparent);color:var(--orange)}
.hz-chip.ghs09{background:color-mix(in srgb,var(--green) 10%,transparent);border-color:color-mix(in srgb,var(--green) 22%,transparent);color:var(--green)}
.purity-bar-wrap{width:100%;background:var(--bg3);border-radius:var(--r-xs);height:5px;margin-top:4px;overflow:hidden}
.purity-bar{height:100%;border-radius:var(--r-xs);background:var(--green);transition:width .3s}

/* ── FILES ────────────────────────────────────────────────────── */
.file-item{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid var(--divider);font-size:11px}
.file-item:last-child{border:none}
.file-type-badge{font-family:var(--mono);font-size:9px;padding:2px 6px;border-radius:var(--r-xs);background:var(--bg4);color:var(--text3);flex-shrink:0}
.file-name{flex:1;color:var(--text2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.file-size{font-family:var(--mono);font-size:10px;color:var(--text3);flex-shrink:0}
.upload-drop{border:1.5px dashed var(--border2);border-radius:var(--r-md);padding:18px;text-align:center;font-size:12px;color:var(--text3);cursor:pointer;transition:all .15s;margin-top:8px;background:var(--bg3)}
.upload-drop:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-light)}
.upload-drop input[type=file]{display:none}

/* ── USAGE LOG ────────────────────────────────────────────────── */
.log-entry{display:flex;gap:8px;padding:7px 0;border-bottom:1px solid var(--divider);font-size:11px}
.log-entry:last-child{border:none}
.log-action{font-family:var(--mono);padding:2px 6px;border-radius:var(--r-xs);font-size:10px;flex-shrink:0;align-self:flex-start;margin-top:1px}
.la-use{background:color-mix(in srgb,var(--red) 12%,transparent);color:var(--red)}
.la-restock{background:color-mix(in srgb,var(--green) 12%,transparent);color:var(--green)}
.la-new{background:var(--accent-light);color:var(--accent)}
.la-discard{background:color-mix(in srgb,var(--yellow) 14%,transparent);color:var(--yellow)}
.log-meta{color:var(--text3);line-height:1.6}

/* ── FORM / MODAL ─────────────────────────────────────────────── */
.form-row{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}
.form-row label{font-size:11px;color:var(--text3);font-weight:500}
.form-row input,.form-row select,.form-row textarea{background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-sm);padding:8px 12px;color:var(--text);font-size:13px;font-family:var(--sans);outline:none;transition:border .15s,box-shadow .15s;width:100%}
.form-row input[type=checkbox],.form-row input[type=radio]{width:auto;flex-shrink:0;padding:0}
.form-row input:focus,.form-row select:focus,.form-row textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-light)}
.form-row textarea{resize:vertical;min-height:60px;line-height:1.5}
.form-row input[type=date]{color-scheme:light}
/* .form-input on its own (not inside a .form-row) had no base rule at all —
   every sidebar filter select built this way (Orders' budget-line/project/
   supplier/PI/year pickers, etc.) fell back to the browser's bare native
   <select> box, focus ring included (the thick, square-cornered blue outline
   that doesn't match anything else in the app). Same recipe as .form-row's
   own fields above, just sized for a compact sidebar rather than a modal. */
.form-input{background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-sm);padding:6px 9px;color:var(--text);font-family:var(--sans);outline:none;transition:border .15s,box-shadow .15s;width:100%}
.form-input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-light)}
/* Number fields are typed, never clicked up and down. The Firefox half of
   this was already global; the WebKit half only existed on the ELN table
   (.rxn-inp.num below), so every other number field in the app — bio
   experiments, orders, plates, admin — still grew spinners in Chrome. A
   spinner on a mass, a concentration or an IC50 is worse than useless: the
   step is arbitrary and one stray scroll silently changes a measured value. */
input[type=number]{-moz-appearance:textfield;appearance:textfield}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
.input-error,.form-row .input-error,.form-input.input-error{border-color:var(--red) !important;box-shadow:0 0 0 3px rgba(220,38,38,.12) !important}
.form-row .input-error:focus,.form-input.input-error:focus{border-color:var(--red) !important;box-shadow:0 0 0 3px rgba(220,38,38,.2) !important}
.form-cols{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@keyframes modal-in{from{opacity:0;transform:scale(.96) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}
@keyframes modal-out{from{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}}
.modal-overlay{position:fixed;inset:0;background:rgba(17,24,39,.55);backdrop-filter:blur(3px);z-index:300;display:none;align-items:center;justify-content:center}
.modal-overlay.show{display:flex}
.modal-overlay.show .modal{animation:modal-in .15s cubic-bezier(.34,1.56,.64,1)}
.modal{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-xl);padding:22px 24px;width:520px;max-width:95vw;max-height:85vh;overflow-y:auto;box-shadow:var(--shadow-lg)}
.modal h3{font-size:15px;font-weight:600;margin-bottom:16px;display:flex;align-items:center;gap:8px;color:var(--text)}
.dp-footer{padding:10px 18px;border-top:1px solid var(--border);display:flex;gap:6px;flex-shrink:0;background:var(--bg3)}

/* ── HAZARD SELECTOR ──────────────────────────────────────────── */
.hazard-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:5px}
.hazard-opt{display:flex;align-items:center;gap:6px;padding:6px 8px;border:1px solid var(--border2);border-radius:var(--r-xs);cursor:pointer;font-size:11px;color:var(--text2);transition:all .15s;user-select:none}
.hazard-opt:hover{border-color:var(--text3)}
.hazard-opt.selected{border-color:var(--yellow);background:rgba(240,192,64,.08);color:var(--yellow)}
.hazard-opt input{display:none}


/* ── PROJECTS PAGE ────────────────────────────────────────────── */
.projects-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px;margin-top:16px}
.proj-list{display:flex;flex-direction:column;gap:0;margin-top:12px;border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow-sm)}
.proj-list-row{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--bg2);border-bottom:1px solid var(--border);transition:background .1s}
.proj-list-row:last-child{border-bottom:none}
.proj-list-row:hover{background:var(--bg3)}
.proj-list-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
.proj-list-name{font-size:13px;font-weight:500;min-width:140px;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.proj-list-meta{font-size:11px;color:var(--text3);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.proj-card{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;transition:border .15s,box-shadow .15s,transform .15s;box-shadow:var(--shadow-sm)}
.proj-card:hover{border-color:var(--border2);box-shadow:var(--shadow-md);transform:translateY(-1px)}
.proj-card-header{display:flex;align-items:center;gap:10px;padding:14px 16px 10px}
.proj-card-title{font-size:14px;font-weight:600;flex:1;min-width:0;color:var(--text)}
.proj-status{font-size:10px;padding:3px 8px;border-radius:var(--r-sm);font-weight:600}
.ps-active{background:color-mix(in srgb,var(--green) 12%,transparent);color:var(--green)}
.ps-completed{background:var(--accent-light);color:var(--accent)}
.ps-archived{background:var(--bg3);color:var(--text3)}
.proj-card-body{padding:4px 16px 14px 30px}
.proj-card-desc{font-size:11px;color:var(--text3);margin-bottom:8px;line-height:1.5}
.proj-card-footer{display:flex;align-items:center;justify-content:space-between}
.proj-compound-count{font-family:var(--mono);font-size:12px;color:var(--text2)}
.proj-actions{display:flex;gap:5px}

/* ── BIOLOGY PAGE ────────────────────────────────────────────── */
/* ── BIO RESULTS TABLE ────────────────────────────────────────── */
.bio-filter-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.bio-filter-bar select,.bio-filter-bar input[type=text],.bio-filter-bar input[type=number]{font-size:12px;padding:5px 8px;border:1px solid var(--border2);border-radius:var(--r-xs);background:var(--bg2);color:var(--text)}
.bio-filter-bar input[type=number]{width:68px}
.bio-filter-panel{width:260px;flex-shrink:0;border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;transition:width .2s ease}
.bio-filter-panel.collapsed{width:36px}
.bio-filter-panel-hdr{padding:14px 14px 10px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:8px;flex-shrink:0}
.bio-filter-panel-body{flex:1;overflow-y:auto;padding:14px 12px;display:flex;flex-direction:column;gap:12px}
#bio-exp-sidebar.collapsed{width:36px}
#bio-exp-sidebar.collapsed .eln-list-header>:not(.sidebar-toggle-btn),#bio-exp-sidebar.collapsed .eln-list-body{display:none!important}
#bio-exp-sidebar.collapsed .eln-list-header{width:100%;padding:12px 0 10px;justify-content:center}
#bio-exp-group-list{padding:2px 0}
.bio-filter-panel.collapsed .bio-filter-panel-body,.bio-filter-panel.collapsed .bio-filter-panel-ftr{display:none!important}
.bio-filter-panel.collapsed .bio-filter-panel-hdr>:not(#bio-res-filter-toggle){display:none!important}
.bio-filter-panel-ftr{padding:10px 12px;border-top:1px solid var(--border);display:flex;flex-direction:column;gap:5px;flex-shrink:0}
.bio-filter-panel select,.bio-filter-panel input{width:100%;font-size:12px;padding:5px 7px;border:1px solid var(--border2);border-radius:var(--r-xs);background:var(--bg2);color:var(--text);outline:none;box-sizing:border-box}
.bio-filter-panel .search-wrap input{padding-left:28px}
.bio-filter-panel .bio-range-row{display:flex;align-items:center;gap:4px}
.bio-filter-panel .bio-range-row input{width:0;flex:1}
#bio-res-filter-toggle{background:none;border:none;cursor:pointer;color:var(--text3);padding:2px 5px;border-radius:var(--r-xs);font-size:15px;line-height:1;flex-shrink:0}
#bio-res-filter-toggle:hover{background:var(--bg3);color:var(--text)}
.bio-results-main{flex:1;padding:16px 20px;overflow:auto;display:flex;flex-direction:column;min-width:0}
/* ── BIO EXPLORER (3-panel charts) ──────────────────────────── */
.bio-exp-panel{border-right:1px solid var(--border);flex-shrink:0;display:flex;flex-direction:column;overflow:hidden}
.bio-exp-panel:last-child{border-right:none}
.bio-exp-row-group{width:52px;flex-shrink:0;font-size:10px;border:2px solid var(--border2);border-radius:3px;background:var(--bg2);color:var(--text2);padding:1px 2px;cursor:pointer}
.bio-exp-row-swatch{width:16px;height:16px;flex-shrink:0;padding:0;border:1px solid var(--border2);border-radius:3px;background:none;cursor:pointer}
.bio-exp-row-swatch::-webkit-color-swatch-wrapper{padding:1px}
.bio-exp-row-swatch::-webkit-color-swatch{border:none;border-radius:2px}
.bio-exp-row-swatch-reset{flex-shrink:0;width:14px;height:16px;padding:0;font-size:10px;line-height:1;border:none;background:none;color:var(--text3);cursor:pointer}
.bio-exp-row-swatch-reset:hover{color:var(--accent)}
/* Select-compounds modal toolbar — one bordered block holding search,
   selection actions, project filter and group assignment, so the modal
   reads as one coherent control panel instead of loose stacked rows. */
.bio-exp-modal-toolbar{display:flex;flex-direction:column;gap:8px;padding:10px;margin-bottom:12px;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md)}
.bio-exp-modal-toolbar-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.bio-exp-modal-toolbar-row:not(:last-child){padding-bottom:8px;border-bottom:1px solid var(--border)}
.bio-exp-modal-search-wrap{display:flex;align-items:center;gap:6px;flex:1;min-width:180px;padding:0 8px;border:1px solid var(--border2);border-radius:var(--r-xs);background:var(--bg);color:var(--text3)}
.bio-exp-modal-search-wrap input{flex:1;border:none;background:none;padding:6px 0;font-size:12px;color:var(--text);outline:none}
.bio-exp-modal-seg{display:flex;border:1px solid var(--border2);border-radius:var(--r-xs);overflow:hidden;flex-shrink:0}
.bio-exp-modal-seg button{background:var(--bg);border:none;color:var(--text2);font-size:12px;padding:6px 10px;cursor:pointer}
.bio-exp-modal-seg button:not(:last-child){border-right:1px solid var(--border2)}
.bio-exp-modal-seg button:hover{background:var(--bg3);color:var(--text)}
.bio-exp-modal-clear:hover{color:var(--red)!important}
.bio-exp-modal-filter-details{position:relative;flex-shrink:0}
.bio-exp-modal-filter-details summary{list-style:none;cursor:pointer;user-select:none;font-size:12px;padding:6px 10px;border:1px solid var(--border2);border-radius:var(--r-xs);background:var(--bg);color:var(--text2)}
.bio-exp-modal-filter-details summary::-webkit-details-marker{display:none}
.bio-exp-modal-filter-details summary:hover{color:var(--text);border-color:var(--accent)}
.bio-exp-modal-filter-details[open] summary{color:var(--text);border-color:var(--accent)}
.bio-exp-modal-filter-panel{position:absolute;top:calc(100% + 4px);left:0;z-index:20;min-width:220px;max-height:260px;overflow-y:auto;display:flex;flex-direction:column;gap:6px;padding:10px;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-sm);box-shadow:0 10px 28px rgba(0,0,0,.2)}
.bio-exp-modal-filter-panel .bio-exp-project-filter-list{display:flex;flex-direction:column;gap:4px}
#bio-exp-modal-group-select{font-size:12px;padding:6px 8px;border:1px solid var(--border2);border-radius:var(--r-xs);background:var(--bg);color:var(--text)}
.bio-exp-modal-grid{overflow-y:auto;flex:1;display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;padding:2px 2px 4px}
.bio-exp-modal-card{display:flex;flex-direction:column;align-items:center;gap:4px;padding:10px 8px;border:1px solid var(--border2);border-radius:var(--r-md);cursor:pointer;text-align:center;position:relative;background:var(--bg2);transition:border-color .12s,box-shadow .12s,transform .12s}
.bio-exp-modal-card:hover{border-color:var(--text3);box-shadow:0 2px 8px rgba(0,0,0,.08);transform:translateY(-1px)}
.bio-exp-modal-card.checked{border-color:var(--accent);background:color-mix(in srgb, var(--accent) 8%, transparent)}
.bio-exp-modal-card input[type=checkbox]{position:absolute;top:6px;left:6px;margin:0;width:15px;height:15px;accent-color:var(--accent)}
.bio-exp-modal-card img{width:120px;height:70px;object-fit:contain;background:#fff;border-radius:var(--r-xs)}
.bio-exp-modal-card .cid{font-weight:700;font-size:12px;color:var(--text)}
.bio-exp-modal-card .cnt{font-size:10px;color:var(--text3);font-family:var(--mono)}
.bio-exp-modal-card-group{display:flex;align-items:center;gap:4px;margin-top:2px;width:100%}
.bio-exp-modal-card-group .bio-exp-row-group{width:auto;flex:1}
.bio-exp-group-row{display:flex;align-items:center;gap:5px;font-size:11px;padding:3px 0}
.bio-exp-group-row .name{flex:1;color:var(--text2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bio-exp-group-row .n{color:var(--text3);font-family:var(--mono);font-size:10px}
.bio-exp-group-swatch{width:16px;height:16px;flex-shrink:0;padding:0;border:1px solid var(--border2);border-radius:3px;background:none;cursor:pointer}
.bio-exp-group-swatch::-webkit-color-swatch-wrapper{padding:1px}
.bio-exp-group-swatch::-webkit-color-swatch{border:none;border-radius:2px}
.bio-exp-group-shape{font-size:10px;padding:1px 3px;border:1px solid var(--border2);border-radius:3px;background:var(--bg2);color:var(--text2);max-width:64px}
.bio-exp-group-row button{background:none;border:none;color:var(--text3);cursor:pointer;font-size:11px;padding:0 2px;flex-shrink:0;display:inline-flex;align-items:center}
.bio-exp-group-row button:last-child:hover{color:var(--red)}
.bio-exp-group-row button:not(:last-child):hover{color:var(--accent)}
.bio-exp-group-row.hidden{opacity:.45}
.bio-exp-group-row .bio-exp-shape-btn{width:22px;height:22px;flex-shrink:0;display:flex;align-items:center;justify-content:center;border:1px solid var(--border2)!important;border-radius:4px;background:var(--bg2)!important;color:var(--text2);padding:0}
.bio-exp-group-row .bio-exp-shape-btn:hover{background:var(--bg3)!important;color:var(--text)}
.bio-exp-group-row .bio-exp-shape-btn:disabled{opacity:.4;cursor:default}
.bio-exp-shape-pop{position:absolute;z-index:60;top:100%;right:0;margin-top:3px;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-sm);box-shadow:0 6px 18px rgba(0,0,0,.28);padding:5px;display:grid;grid-template-columns:repeat(4,26px);gap:3px}
.bio-exp-shape-opt{width:26px;height:26px;display:flex;align-items:center;justify-content:center;border:1px solid transparent!important;border-radius:4px;background:none!important;color:var(--text2);cursor:pointer;padding:0}
.bio-exp-shape-opt:hover{background:var(--bg3)!important;color:var(--text)}
.bio-exp-shape-opt.active{border-color:var(--accent)!important;color:var(--accent)}
.bio-exp-style-preset.active{background:var(--bg3);color:var(--text);border-color:var(--accent)}
.bio-exp-group-expand{width:14px;color:var(--text3);font-size:10px!important}
.bio-exp-group-members{display:flex;flex-direction:column;gap:3px;padding:2px 0 6px 20px}
.bio-exp-group-member-chip{display:flex;align-items:center;gap:5px;font-size:11px;background:var(--bg3);border-radius:var(--r-xs);padding:2px 4px}
.bio-exp-group-member-chip .cid{flex:1;color:var(--text2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
.bio-exp-group-member-chip button{background:none;border:none;color:var(--text3);cursor:pointer;flex-shrink:0;display:inline-flex;align-items:center;padding:0}
.bio-exp-group-member-chip .bio-exp-chip-btn{width:17px;height:17px;justify-content:center;border-radius:3px}
.bio-exp-group-member-chip .bio-exp-chip-btn:hover{color:var(--accent);background:var(--bg2)}
.bio-exp-group-member-chip .bio-exp-chip-btn.active{color:var(--accent);background:color-mix(in srgb, var(--accent) 16%, transparent)}
.bio-exp-move-pop{position:absolute;z-index:60;top:100%;right:0;margin-top:3px;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-sm);box-shadow:0 6px 18px rgba(0,0,0,.28);padding:4px;display:flex;flex-direction:column;gap:1px;min-width:140px;max-height:220px;overflow-y:auto}
.bio-exp-group-member-chip .bio-exp-move-opt{display:flex;align-items:center;gap:6px;padding:5px 7px;border-radius:4px;font-size:11px;color:var(--text2);text-align:left;white-space:nowrap;width:100%}
.bio-exp-group-member-chip .bio-exp-move-opt:hover{background:var(--bg3);color:var(--text)}
.bio-exp-group-member-chip .bio-exp-move-opt.active{color:var(--accent);font-weight:600}
.bio-exp-move-opt .sw{width:9px;height:9px;border-radius:50%;flex-shrink:0}
.bio-exp-oor-notice{position:absolute;bottom:10px;left:50%;transform:translateX(-50%);background:var(--warn-bg);border:1px solid var(--warn-border);color:var(--warn-fg);font-size:11px;padding:4px 10px;border-radius:var(--r-lg);z-index:4;cursor:help;white-space:nowrap}
.nmr-peaks-warn-box{background:var(--warn-bg);border:1px solid var(--warn-border);color:var(--warn-fg);font-size:11px;line-height:1.6;padding:6px 9px;border-radius:var(--r-sm);margin-top:6px}
.bio-exp-shockwave{position:fixed;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;border:3px solid var(--accent);pointer-events:none;z-index:9999;animation:bioExpShockwave .9s ease-out forwards}
@keyframes bioExpShockwave{0%{transform:scale(.3);opacity:1}100%{transform:scale(6);opacity:0}}
.bio-exp-config{width:230px;padding:14px 12px;overflow-y:auto;gap:14px}
.bio-exp-type-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.bio-exp-type-btn{display:flex;flex-direction:column;align-items:center;gap:4px;padding:8px 4px;border:1px solid var(--border2);border-radius:var(--r-sm);background:var(--bg2);color:var(--text2);cursor:pointer}
.bio-exp-type-btn span{font-size:10px;font-weight:600}
.bio-exp-type-btn:hover{border-color:var(--accent);color:var(--text)}
.bio-exp-type-btn.active{background:color-mix(in srgb, var(--accent) 12%, transparent);border-color:var(--accent);color:var(--accent)}
.bio-exp-config .sl{font-size:11px;color:var(--text3);font-weight:600;text-transform:uppercase;letter-spacing:.04em;margin-bottom:4px}
.bio-exp-config select{width:100%;font-size:12px;padding:6px 8px;border:1px solid var(--border2);border-radius:var(--r-xs);background:var(--bg2);color:var(--text);outline:none;box-sizing:border-box}
.bio-exp-config label.chk{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text2);padding:3px 0;cursor:pointer}
.bio-exp-chart-area{flex:1;padding:16px 20px;position:relative;min-width:420px}
.bio-exp-heatmap-table{border-collapse:collapse;font-size:11px;white-space:nowrap}
.bio-exp-heatmap-table th{position:sticky;top:0;background:var(--bg2);padding:6px 8px;text-align:center;border-bottom:1px solid var(--border2);z-index:2}
.bio-exp-heat-col-type{color:var(--accent);font-family:var(--mono);font-size:9px;text-transform:uppercase;letter-spacing:.03em}
.bio-exp-heat-col-name{color:var(--text);font-weight:600}
.bio-exp-heat-col-unit{color:var(--text3);font-size:9px;font-family:var(--mono)}
.bio-exp-heat-rowhead{position:sticky;left:0;background:var(--bg2);display:flex;align-items:center;gap:6px;padding:4px 10px 4px 6px;font-weight:600;border-right:1px solid var(--border2);z-index:1}
.bio-exp-heat-rowhead img{width:32px;height:20px;object-fit:contain;border-radius:var(--r-xs);flex-shrink:0}
.bio-exp-heat-cell{text-align:center;padding:6px 10px;font-family:var(--mono);color:var(--text);border-bottom:1px solid var(--border)}
.bio-exp-heat-cell.empty{color:var(--text3)}
.bio-exp-heat-toolbar{position:sticky;top:0;left:0;z-index:3;display:flex;align-items:center;justify-content:space-between;gap:12px;background:var(--bg2);border-bottom:1px solid var(--border2);padding:0 0 8px;margin-bottom:4px}
.bio-exp-heat-legend{display:flex;align-items:center;gap:6px;font-size:10px;color:var(--text3)}
.bio-exp-heat-legend-bar{width:110px;height:10px;border-radius:3px;border:1px solid var(--border2)}
#bio-exp-heat-scale-select{padding:3px 6px;border:1px solid var(--border2);border-radius:var(--r-xs);background:var(--bg2);color:var(--text2)}
.bio-exp-heat-collist{display:flex;flex-direction:column;gap:2px;max-height:280px;overflow-y:auto}
.bio-exp-heat-collist .chk{white-space:nowrap}
#bio-exp-tooltip{position:fixed;z-index:2000;pointer-events:none;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);box-shadow:0 8px 24px rgba(0,0,0,.18);padding:10px;font-size:11px;display:none;width:220px}
#bio-exp-tooltip .tt-struct{width:100%;height:90px;background:#fff;border-radius:var(--r-xs);overflow:hidden;display:flex;align-items:center;justify-content:center;margin-bottom:6px}
#bio-exp-tooltip .tt-struct svg{max-width:100%;max-height:100%}
#bio-exp-tooltip .tt-cid{font-weight:700;font-size:12px;color:var(--text);margin-bottom:4px}
#bio-exp-tooltip table{width:100%;border-collapse:collapse}
#bio-exp-tooltip td{padding:1px 0;color:var(--text2)}
#bio-exp-tooltip td:last-child{text-align:right;font-family:var(--mono);color:var(--text)}
#bio-exp-tooltip .tt-section{font-size:9px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.05em;margin:6px 0 2px;padding-top:4px;border-top:1px solid var(--border2)}
.be-file-badge{font-size:10px;font-weight:600;padding:1px 6px;border-radius:var(--r-lg);flex-shrink:0}
.be-file-badge.data{background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent)}
.be-file-badge.report{background:color-mix(in srgb,var(--orange) 12%,transparent);color:var(--orange)}
.be-file-badge.image{background:var(--bg4);color:var(--text2)}
.be-file-badge.other{background:var(--bg4);color:var(--text3)}
.bio-table{width:100%;border-collapse:collapse}
.bio-table thead th{text-align:left;font-size:10px;color:var(--text3);font-weight:700;padding:7px 10px;border-bottom:1px solid var(--border);white-space:nowrap;background:var(--bg3);text-transform:uppercase;letter-spacing:.05em}
.bio-table tbody td{padding:8px 10px;border-bottom:1px solid var(--border);font-size:12px;vertical-align:middle}
.bio-table tbody tr:last-child td{border-bottom:none}
.bio-tr{cursor:pointer}
.bio-tr:hover td{background:var(--bg3)}
.bio-assay-tag{display:inline-block;font-size:10px;font-family:var(--mono);padding:2px 7px;border-radius:var(--r-sm);background:var(--accent-light);border:1px solid color-mix(in srgb,var(--accent) 20%,transparent);color:var(--accent);white-space:nowrap;font-weight:500}
.bio-target-tag{display:inline-block;font-size:10px;font-family:var(--mono);padding:2px 7px;border-radius:var(--r-sm);background:var(--bg3);border:1px solid var(--border2);color:var(--text2);white-space:nowrap}
.cid-chip{font-family:var(--sans);font-size:12px;font-weight:700;color:var(--text)}
/* Bio results in compound detail panel */
.bio-row{position:relative;padding:7px 30px 7px 0;border-bottom:1px solid var(--border);font-size:12px}
.bio-row:last-child{border-bottom:none}
.bio-row-main{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.bio-name{color:var(--text);flex:1;min-width:0}
.bio-value{font-family:var(--mono);font-weight:700;color:var(--text);white-space:nowrap}
.bio-row-meta{font-size:11px;color:var(--text3);margin-top:2px}
.bio-row-notes{font-size:11px;color:var(--text2);margin-top:2px;font-style:italic}
.bio-row-actions{position:absolute;top:7px;right:0;display:flex;gap:2px;opacity:0;transition:opacity .15s}
.bio-row:hover .bio-row-actions{opacity:1}
.bio-del-btn,.bio-edit-btn{background:none;border:none;cursor:pointer;color:var(--text3);font-size:12px;padding:2px 4px;border-radius:var(--r-xs)}
.bio-del-btn:hover{background:rgba(220,38,38,.12);color:var(--red)}
.bio-edit-btn:hover{background:var(--bg3);color:var(--text)}
.bio-row-group .bio-row-main:hover{color:var(--accent)}
.bio-group-toggle{color:var(--text3);font-size:10px;flex-shrink:0}
.bio-group-detail{padding-left:14px;border-left:2px solid var(--border2);margin:0 0 4px 2px}
.bio-group-detail .bio-row{padding-right:30px}
.bio-tr-group{background:color-mix(in srgb, var(--accent) 5%, transparent)}
.bio-tr-group:hover td{background:color-mix(in srgb, var(--accent) 10%, transparent)!important}
.bio-tr-sub td:nth-child(4){padding-left:16px}
.bio-tr-sub{opacity:.9}
.bio-report-link{display:inline-flex;align-items:center;gap:3px;font-size:11px;color:var(--accent);text-decoration:none;margin-top:3px}
.bio-report-link:hover{text-decoration:underline}
.bio-files{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}
.bio-file-chip{display:inline-flex;align-items:center;gap:4px;font-size:11px;padding:2px 7px;border-radius:var(--r-xs);background:var(--bg3);border:1px solid var(--border2);color:var(--text2);cursor:pointer;text-decoration:none}
.bio-file-chip:hover{border-color:var(--accent);color:var(--accent)}
.bio-attach-btn{font-size:12px;color:var(--text3);background:none;border:none;cursor:pointer;padding:2px 4px;border-radius:var(--r-xs)}
.bio-attach-btn:hover{background:var(--bg3);color:var(--accent)}
.bio-table td.bio-td-notes{max-width:180px;white-space:pre-wrap;word-break:break-word;font-size:11px;color:var(--text3)}
.bio-table .bio-report-cell a{color:var(--accent);font-size:11px;text-decoration:none}
.bio-table .bio-report-cell a:hover{text-decoration:underline}

/* ── COMPOUND AUTOCOMPLETE ────────────────────────────────────── */
.cmp-ac-wrap{position:relative}
.cmp-ac-dropdown{position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);box-shadow:0 6px 20px rgba(0,0,0,.12);z-index:500;overflow:hidden;display:none;max-height:240px;overflow-y:auto}
.cmp-ac-dropdown.open{display:block}
.cmp-ac-item{display:flex;align-items:center;gap:8px;padding:7px 12px;cursor:pointer;font-size:13px;transition:background .1s}
.cmp-ac-item:hover,.cmp-ac-item.focused{background:var(--bg3)}
.cmp-ac-none{padding:10px 12px;font-size:12px;color:var(--text3)}

/* ── BIO SUB-TABS & REPORTS ───────────────────────────────────── */
.bio-subtabs{display:flex;gap:2px;background:transparent;padding:2px 0}
.bio-subtab{padding:4px 14px;border-radius:var(--r-xs);font-size:12px;color:var(--text3);cursor:pointer;border:none;background:transparent;transition:all .15s}
.bio-subtab.active{color:var(--text);font-weight:500;background:var(--bg2)}
.bio-import-preview{max-height:320px;overflow-y:auto;margin:12px 0}
.bio-import-table{width:100%;border-collapse:collapse;font-size:12px}
.bio-import-table th{text-align:left;padding:5px 8px;font-size:11px;color:var(--text3);font-weight:500;border-bottom:1px solid var(--border)}
.bio-import-table td{padding:5px 8px;border-bottom:1px solid var(--border)}
.bio-import-row-ok{background:rgba(52,199,89,.05)}
.bio-import-row-err{background:rgba(255,59,48,.05);color:var(--red)}
.bio-import-row-skip{opacity:.5;text-decoration:line-through}

/* ── Compound Picker ─────────────────────────────────────────── */
.cpd-picker-list{max-height:280px;overflow-y:auto;border:1px solid var(--border);border-radius:var(--r-sm)}
.cpd-picker-row{display:flex;align-items:center;gap:10px;padding:8px 12px;cursor:pointer;border-bottom:1px solid var(--border);font-size:12px}
.cpd-picker-row:last-child{border-bottom:none}
.cpd-picker-row:hover{background:var(--bg3)}
.cpd-picker-cid{font-family:var(--sans);font-weight:700;color:var(--text2);min-width:72px;flex-shrink:0}
.cpd-picker-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cpd-picker-formula{font-size:11px;color:var(--text3);flex-shrink:0}
.cpd-pick-btn{background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-xs);padding:3px 8px;font-size:12px;color:var(--text2);cursor:pointer;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}
.cpd-pick-btn:hover{border-color:var(--accent);color:var(--accent)}
.cpd-pick-btn.has-value{color:var(--accent);font-family:var(--mono);font-weight:600}

/* ── BIO-ELN ─────────────────────────────────────────────────── */
.be-table,.admin-table{width:100%;border-collapse:collapse}
.be-table th,.admin-table th{text-align:left;padding:5px 8px;font-size:11px;color:var(--text3);font-weight:500;border-bottom:1px solid var(--border)}
.be-table td,.admin-table td{padding:6px 8px;border-bottom:1px solid var(--border);font-size:12px;color:var(--text)}
.be-table tr:last-child td,.admin-table tr:last-child td{border-bottom:none}
.admin-table tr:hover td{background:var(--bg3)}
.be-add-row td{background:var(--bg3);border-top:1px dashed var(--border2)!important}
#pharm-diss-section input[type=number]:focus,#pharm-diss-section input[type=text]:focus{background:var(--bg2)!important;box-shadow:inset 0 0 0 2px var(--accent);border-radius:2px}
#pharm-diss-section input[type=number]:hover,#pharm-diss-section input[type=text]:hover{background:var(--bg3)!important}
#pharm-diss-section tr:hover td{background:color-mix(in srgb,var(--accent) 4%,transparent)}
.be-add-row input,.be-add-row select{background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-xs);padding:3px 5px;font-size:12px;color:var(--text);outline:none}
.be-inline-input{width:100%;background:transparent;border:none;border-bottom:1px solid transparent;padding:2px 0;font-size:12px;color:var(--text);outline:none;font-family:var(--sans)}
.be-inline-input:focus,.be-inline-input:hover{border-bottom-color:var(--border2)}

/* ── ELN ──────────────────────────────────────────────────────── */
#page-eln{padding:0;overflow:hidden}
#page-eln.active{display:flex;flex-direction:column;height:calc(100vh - 56px)}
.eln-layout{display:flex;flex:1;overflow:hidden}
/* height:100% overrides the legacy bare `aside{height:calc(100vh - 56px)}`
   rule below — that fixed viewport-relative height only happens to match
   when nothing else shares the page above the sidebar; Library's subtab
   strip (Compounds/Storage/Bio Results/Charts) eats into that space, so
   without this the sidebar box itself ends up taller than its actual grid
   row and the last ~40px (rendered content there, whatever it is) gets
   clipped by the grid container's overflow:hidden — not fixable by
   scrolling, since it's the sidebar's own box that's oversized. */
.eln-list{width:260px;height:100%;flex-shrink:0;border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;transition:width .2s ease}
.eln-list.collapsed{width:36px}
#eln-sidebar.collapsed .eln-list-header>:not(#eln-sidebar-toggle),#eln-sidebar.collapsed .subtab-bar,#eln-sidebar.collapsed .pj-scope,#eln-sidebar.collapsed #eln-entries-panel,#eln-sidebar.collapsed #eln-ci-panel{display:none!important}
#bio-sidebar.collapsed .eln-list-header>:not(#bio-sidebar-toggle),#bio-sidebar.collapsed .subtab-bar,#bio-sidebar.collapsed .pj-scope,#bio-sidebar.collapsed .eln-list-search,#bio-sidebar.collapsed .eln-list-body,#bio-sidebar.collapsed .ci-panel-notice{display:none!important}
#d2b-sidebar.collapsed .eln-list-header>:not(#d2b-sidebar-toggle),#d2b-sidebar.collapsed .pj-scope,#d2b-sidebar.collapsed #d2b-entries-panel,#d2b-sidebar.collapsed #d2b-browser-panel,#d2b-sidebar.collapsed #d2b-source-panel{display:none!important}
#eln-sidebar-toggle,#bio-sidebar-toggle,#d2b-sidebar-toggle{background:none;border:none;cursor:pointer;color:var(--text3);padding:2px 5px;border-radius:var(--r-xs);font-size:15px;line-height:1;flex-shrink:0;margin-left:auto}
#eln-sidebar-toggle:hover,#bio-sidebar-toggle:hover,#d2b-sidebar-toggle:hover{background:var(--bg3);color:var(--text)}

/* ── Shared collapsible-sidebar toggle (Projects/Library/Equipment/Reagents/Orders) ── */
.sidebar-toggle-btn{background:none;border:none;cursor:pointer;color:var(--text3);padding:2px 5px;border-radius:var(--r-xs);font-size:15px;line-height:1;flex-shrink:0;margin-left:auto}
.sidebar-toggle-btn:hover{background:var(--bg3);color:var(--text)}
.sidebar-plain-icon-btn{background:none;border:none;cursor:pointer;color:var(--text3);padding:2px 5px;border-radius:var(--r-xs);display:inline-flex;align-items:center;flex-shrink:0}
.sidebar-plain-icon-btn:hover{background:var(--bg3);color:var(--text)}
#library-sidebar.collapsed{width:36px}
#library-sidebar.collapsed .eln-list-header>:not(.sidebar-toggle-btn),#library-sidebar.collapsed .eln-list-body,#library-sidebar.collapsed .eln-list-footer{display:none!important}
#storage-sidebar.collapsed{width:36px}
#storage-sidebar.collapsed .eln-list-header>:not(.sidebar-toggle-btn),#storage-sidebar.collapsed .eln-list-body{display:none!important}
#equip-sidebar.collapsed #equip-sidebar-header>:not(.sidebar-toggle-btn),#equip-sidebar.collapsed>:not(#equip-sidebar-header){display:none!important}
#reac-nav-sidebar.collapsed{width:36px}
#reac-nav-sidebar.collapsed .eln-list-header>:not(.sidebar-toggle-btn),#reac-nav-sidebar.collapsed .eln-list-body{display:none!important}
#orders-nav-sidebar.collapsed{width:36px}
#orders-nav-sidebar.collapsed .eln-list-header>:not(.sidebar-toggle-btn),#orders-nav-sidebar.collapsed .eln-list-body{display:none!important}
.ci-res-thumb{flex-shrink:0;border-radius:var(--r-xs);background:var(--bg3);border:1px solid var(--border2)}
.eln-list-header{padding:14px 14px 10px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:8px}
.eln-list-header .page-title{flex:1;font-size:14px}
.eln-review-alert{display:flex;flex-direction:column;gap:6px;margin:8px 12px 0;padding:8px 10px;background:rgba(249,115,22,.08);border:1px solid rgba(249,115,22,.3);border-radius:var(--r-sm);font-size:12px;color:var(--orange)}
.eln-review-alert .btn{align-self:flex-start}
.eln-list-search{padding:8px 12px;border-bottom:1px solid var(--border)}
.eln-list-search input{width:100%;background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-xs);padding:6px 9px;font-size:12px;color:var(--text);outline:none}
.eln-list-search .search-wrap input{padding-left:30px}
.eln-list-body{flex:1;overflow-y:auto;padding:6px}
.eln-list-footer{flex-shrink:0;padding:10px 14px;border-top:1px solid var(--border)}
.subtab-bar{display:flex;border-bottom:1px solid var(--border);padding:0 10px;gap:2px;flex-shrink:0}
#eln-entries-panel{flex:1;display:flex;flex-direction:column;overflow:hidden}
#eln-ci-panel{flex:1;flex-direction:column;overflow:hidden;display:none}
#d2b-entries-panel{flex:1;display:flex;flex-direction:column;overflow:hidden}
#d2b-browser-panel{flex:1;flex-direction:column;overflow:hidden;display:none}
.ci-panel-notice{margin:8px 10px 4px;padding:6px 9px;background:rgba(99,102,241,.07);border:1px solid rgba(99,102,241,.2);border-radius:var(--r-sm);font-size:11px;color:var(--text2);line-height:1.4}
.ci-panel-search{padding:8px 10px;border-bottom:1px solid var(--border);display:flex;flex-direction:column;gap:5px}
.ci-panel-result{padding:8px 10px;border-bottom:1px solid var(--border2);font-size:12px}
.ci-panel-result-name{font-weight:600;color:var(--text);margin-bottom:2px}
.ci-panel-result-meta{color:var(--text3);font-size:11px;line-height:1.5}
.browser-panel-head{padding:10px;display:flex;flex-direction:column;gap:8px;border-bottom:1px solid var(--border)}
.browser-section-hdr{display:flex;align-items:center;gap:6px;padding:5px 10px;font-size:10px;font-weight:700;color:var(--text3);letter-spacing:.05em;text-transform:uppercase;border-bottom:1px solid var(--border);cursor:pointer;user-select:none;transition:background .1s;position:sticky;top:0;background:var(--bg2);z-index:1}
.browser-section-hdr:hover{background:var(--bg3)}
.browser-draw-card{border:1.5px dashed var(--border2);border-radius:var(--r-md);padding:10px 12px;cursor:pointer;display:flex;align-items:center;justify-content:center;min-height:52px;transition:border-color .15s,background .15s}
.browser-draw-card:hover{border-color:var(--accent);background:rgba(99,102,241,.04)}
.browser-draw-card.has-struct{border-style:solid;border-color:var(--border);cursor:default}
.browser-eln-card{display:flex;gap:10px;align-items:stretch;cursor:pointer;padding:8px 10px;border-bottom:1px solid var(--border2);transition:background .1s}
.browser-eln-card:hover{background:var(--bg3)}
.browser-eln-thumb{width:68px;height:68px;border:1px solid var(--border2);border-radius:var(--r-sm);background:white;object-fit:contain;flex-shrink:0;align-self:center}
.browser-eln-info{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:3px}
.browser-eln-role{display:inline-block;font-size:9px;font-weight:700;text-transform:uppercase;padding:1px 5px;border-radius:var(--r-xs);background:rgba(0,0,0,.06);letter-spacing:.03em}
.eln-card{position:relative;overflow:hidden;padding:10px 12px 10px 14px;border-radius:var(--r-md);cursor:pointer;margin-bottom:3px;border:1px solid transparent;transition:background .1s,border-color .1s}
/* Left accent band, same language as the Projects sidebar (.pj-card::before) —
   here it carries the entry's status color, matching the status dot */
.eln-card::before{content:'';position:absolute;left:0;top:6px;bottom:6px;width:3px;border-radius:0 3px 3px 0;background:var(--text3);opacity:.45;transition:opacity .12s}
.eln-card:hover::before{opacity:.85}
.eln-card.active::before{opacity:1}
/* draft/completed/annulled/pending_review/sent are shared across Chem/ELN,
   Bio (experiments + requests) and D2B, so a color here is app-wide, not
   per-module — draft ("open") reads blue everywhere per lab feedback
   (2026-09-10, #help-chemlib). "sent" (Bio's external pharma requests
   only) took purple instead of blue so it stays visually distinct from
   draft in the one list where both statuses can appear together. */
.eln-card:has(.eln-status-dot.draft)::before{background:var(--accent)}
.eln-card:has(.eln-status-dot.completed)::before{background:var(--green)}
.eln-card:has(.eln-status-dot.annulled)::before{background:var(--red)}
.eln-card:has(.eln-status-dot.pending_review)::before{background:var(--orange)}
.eln-card:has(.eln-status-dot.sent)::before{background:var(--chip-purple-fg)}
.eln-card:hover{background:var(--bg3)}
.eln-card.active{background:var(--accent-light);border-color:color-mix(in srgb,var(--accent) 20%,transparent)}
.eln-card-head{display:flex;align-items:center;gap:6px;margin-bottom:3px}
.eln-id-badge{font-family:var(--sans);font-size:11px;font-weight:700;color:var(--text3)}
.eln-status{font-size:10px;padding:1px 6px;border-radius:var(--r-xs);margin-left:auto}
.eln-status.draft{background:var(--accent-light);color:var(--accent);font-weight:600}
.eln-status.completed{background:color-mix(in srgb,var(--green) 12%,transparent);color:var(--green);font-weight:600}
.eln-status.annulled{background:color-mix(in srgb,var(--red) 10%,transparent);color:var(--red);font-weight:600}
.eln-status.pending_review{background:color-mix(in srgb,var(--orange) 14%,transparent);color:var(--orange);font-weight:600}
.eln-status.sent{background:var(--chip-purple-bg);color:var(--chip-purple-fg);font-weight:600}
.eln-status-dot{width:8px;height:8px;border-radius:50%;margin-left:auto;flex-shrink:0}
.eln-status-dot.draft{background:var(--accent)}
.eln-status-dot.completed{background:var(--green)}
.eln-status-dot.annulled{background:var(--red)}
.eln-status-dot.pending_review{background:var(--orange)}
.eln-status-dot.sent{background:var(--chip-purple-fg)}
/* Completed, but a mandatory characterization requirement was overridden with a
   reason instead of actually attached — same "done" color, hollow instead of
   filled, so it never looks identical to a normal, clean completion. */
.eln-status-dot.completed.char-override{width:9px;height:9px;box-sizing:border-box;background:transparent;border:2px solid var(--green)}
/* Same idea while still pending review — the submitter already overrode the
   gap with a reason, before the reviewer ever sees it. */
.eln-status-dot.pending_review.char-override{width:9px;height:9px;box-sizing:border-box;background:transparent;border:2px solid var(--orange)}

/* Status filter — one circle per status, same colors as .eln-status-dot
   above, all on one row instead of a native <select>. */
.eln-status-filter-row{display:flex;gap:5px;align-items:center}
.eln-status-filter-btn{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:var(--r-sm);border:1px solid var(--border2);background:var(--bg3);cursor:pointer;padding:0;flex-shrink:0;transition:border-color .12s,box-shadow .12s}
.eln-status-filter-btn:hover{border-color:var(--text3)}
.eln-status-filter-btn.active{border-color:var(--text);box-shadow:0 0 0 1px var(--text)}
.eln-status-filter-dot{width:9px;height:9px;border-radius:3px;flex-shrink:0}
.eln-status-filter-dot.all{background:transparent;border:1.5px solid var(--text3)}
.eln-status-filter-dot.draft{background:var(--accent)}
.eln-status-filter-dot.pending_review{background:var(--orange)}
.eln-status-filter-dot.completed{background:var(--green)}
.eln-status-filter-dot.annulled{background:var(--red)}
.eln-card.annulled{opacity:.55}
.eln-card.annulled .eln-card-title{text-decoration:line-through}
.proj-team-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 6px 2px 3px;border-radius:20px;background:var(--bg3);border:1px solid var(--border);font-size:10px;color:var(--text2);white-space:nowrap}
.proj-team-chip-av{min-width:14px;height:14px;border-radius:999px;color:#fff;font-size:8px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:0 2px;box-sizing:border-box;letter-spacing:-.2px}
.proj-team-chip-role{font-size:9px;font-weight:600;padding:0 4px;border-radius:var(--r-md);flex-shrink:0}
.proj-task-progress{flex:1;height:6px;border-radius:99px;background:var(--bg3);overflow:hidden}
.proj-task-progress-bar{height:100%;background:var(--accent);border-radius:99px;transition:width .2s}
.proj-task-board{display:grid;grid-template-columns:repeat(3,1fr);gap:0;transition:grid-template-rows .15s;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--border)}
.proj-task-board.collapsed{display:none}
.proj-task-col{background:var(--bg3);padding:9px 8px}
.proj-task-col+.proj-task-col{border-left:1px solid var(--border)}
.proj-task-col-head{display:flex;align-items:center;gap:5px;font-size:10px;font-weight:600;color:var(--text3);text-transform:uppercase;letter-spacing:.04em;margin-bottom:7px}
.proj-task-col-head-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
.proj-task-col[data-status="todo"] .proj-task-col-head-dot{background:var(--text3)}
.proj-task-col[data-status="doing"] .proj-task-col-head-dot{background:var(--accent)}
.proj-task-col[data-status="done"] .proj-task-col-head-dot{background:var(--green)}
.proj-task-col-body{display:flex;flex-direction:column;gap:6px;min-height:30px;max-height:260px;overflow-y:auto;border-radius:var(--r-sm);padding:1px}
.proj-task-col-body.drag-over{background:color-mix(in srgb,var(--accent) 8%,transparent);outline:1.5px dashed color-mix(in srgb,var(--accent) 50%,transparent);outline-offset:-1px}
.proj-task-card{border:none;border-radius:var(--r-sm);padding:6px 8px;background:var(--bg2);cursor:pointer;box-shadow:var(--shadow-sm);transition:transform .1s,box-shadow .1s}
.proj-task-card:hover{transform:translateY(-1px);box-shadow:var(--shadow-md)}
.proj-task-title{font-size:12px;font-weight:500;color:var(--text);line-height:1.35}
.proj-task-structure{width:26px;height:20px;display:flex;align-items:center;justify-content:center;background:var(--bg3);border-radius:3px;flex-shrink:0;overflow:hidden}
.proj-task-structure svg{max-width:100%;max-height:100%}
.proj-task-synth{margin-top:4px;font-size:9px;font-weight:600;color:var(--green);cursor:pointer;display:inline-block}
.proj-task-synth:hover{text-decoration:underline}
.proj-task-lock{cursor:help;font-size:11px;line-height:1;opacity:.6}
.proj-task-lock:hover{opacity:1}
.proj-task-card.highlight{box-shadow:0 0 0 2px var(--accent),var(--shadow-md)}
.proj-task-collapse-btn{background:none;border:none;color:var(--text3);cursor:pointer;padding:2px;display:inline-flex;align-items:center;transition:transform .15s}
.proj-task-collapse-btn.collapsed{transform:rotate(-90deg)}
.proj-pending-row{cursor:pointer;border-bottom:1px dashed var(--border2);background:color-mix(in srgb,var(--text3) 4%,transparent)}
.proj-pending-row:hover{background:color-mix(in srgb,var(--accent) 8%,transparent)}
.proj-subtask-list{display:flex;flex-direction:column;gap:2px;margin-top:5px;padding-top:5px;border-top:1px solid var(--border)}
.proj-subtask-row{display:flex;align-items:center;gap:5px;padding:3px 4px;border-radius:var(--r-xs);cursor:pointer;transition:background .1s}
.proj-subtask-row:hover{background:var(--bg3)}
.proj-subtask-row.highlight{box-shadow:0 0 0 2px var(--accent)}
.proj-subtask-thumb{width:28px;height:20px;display:flex;align-items:center;justify-content:center;background:var(--bg3);border-radius:3px;flex-shrink:0;overflow:hidden}
.proj-subtask-thumb svg{max-width:100%;max-height:100%}
.proj-subtask-title{font-size:11px;color:var(--text2);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.eln-card-title{font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.eln-card-meta{font-size:11px;color:var(--text3);margin-top:2px}
.eln-table-grid{width:100%;border-collapse:collapse;font-size:13px;table-layout:fixed}
.eln-table-grid thead th{position:sticky;top:0;background:var(--bg2);border-bottom:1px solid var(--border2);text-align:left;font-size:10px;font-weight:600;color:var(--text3);text-transform:uppercase;letter-spacing:.03em;padding:9px 12px;z-index:1;white-space:nowrap}
.eln-table-grid thead th.eln-tg-sortable,.ct thead th.eln-tg-sortable{cursor:pointer;user-select:none}
.eln-table-grid thead th.eln-tg-sortable:hover,.ct thead th.eln-tg-sortable:hover{color:var(--text)}
.eln-tg-sort-arrow{display:inline-block;margin-left:3px;font-size:9px;opacity:.8}
.eln-table-grid td{padding:8px 12px;border-bottom:1px solid var(--border);vertical-align:middle;color:var(--text2);height:48px;box-sizing:border-box}
.eln-tg-row{cursor:pointer;transition:background .1s}
.eln-tg-row:nth-child(even){background:color-mix(in srgb,var(--bg2) 45%,transparent)}
.eln-tg-row:hover{background:var(--bg3)}
.eln-tg-scheme{width:70px;padding:4px 8px !important}
.eln-tg-scheme-box{width:54px;height:38px;display:flex;align-items:center;justify-content:center;background:var(--bg3);border-radius:var(--r-xs);overflow:hidden;margin:0 auto}
.eln-tg-title{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;color:var(--text);display:block}
.eln-tg-ellip{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.eln-table-grid th:nth-child(1),.eln-table-grid td:nth-child(1){width:70px}
.eln-table-grid th:nth-child(2),.eln-table-grid td:nth-child(2){width:80px}
.eln-table-grid th:nth-child(3),.eln-table-grid td:nth-child(3){width:auto}
.eln-table-grid th:nth-child(4),.eln-table-grid td:nth-child(4){width:15%}
.eln-table-grid th:nth-child(5),.eln-table-grid td:nth-child(5){width:16%}
.eln-table-grid th:nth-child(6),.eln-table-grid td:nth-child(6){width:90px}
.eln-table-grid th:nth-child(7),.eln-table-grid td:nth-child(7){width:110px}
.eln-table-grid th:nth-child(8),.eln-table-grid td:nth-child(8){width:80px}
.eln-detail{flex:1;overflow-y:auto;display:flex;flex-direction:column}
.eln-empty{flex:1;display:flex;align-items:center;justify-content:center;color:var(--text3);font-size:13px;flex-direction:column;gap:8px}
.eln-editor{padding:20px 24px;flex:1}
.eln-editor-head{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap}
.eln-title-input{flex:1;font-size:16px;font-weight:500;background:none;border:none;border-bottom:1px solid var(--border2);padding:4px 0;color:var(--text);font-family:var(--sans);outline:none;min-width:160px}
.eln-title-input:focus{border-bottom-color:var(--accent)}
.eln-meta-row{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap}
.eln-meta-row label{font-size:11px;color:var(--text3)}
.eln-meta-row input,.eln-meta-row select{background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-xs);padding:4px 8px;font-size:12px;color:var(--text);outline:none}
.eln-section{margin-bottom:20px}
.eln-section-title{font-size:11px;font-weight:600;color:var(--text3);margin-bottom:8px}
.rxn-area{display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap}
.rxn-draw-panel{flex-shrink:0}
.rxn-draw-btns{display:flex;gap:6px;margin-top:6px}
.rxn-table-panel{flex:1;min-width:300px;overflow-x:auto;border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden}
.rxn-table{width:100%;border-collapse:collapse;font-size:12px}
.rxn-table thead tr{background:var(--bg2)}
.rxn-table th{text-align:left;font-size:11px;color:var(--text2);font-weight:600;padding:5px 6px;border-bottom:1px solid var(--border);border-right:1px solid var(--border2);white-space:nowrap}
.rxn-table th:last-child{border-right:none}
.rxn-table td{padding:3px 4px;border-bottom:1px solid var(--border2);border-right:1px solid var(--border2);vertical-align:middle}
.rxn-table td:last-child{border-right:none}
.rxn-table tr:last-child td{border-bottom:none}
.rxn-row-reagent td:first-child,.rxn-row-catalyst td:first-child,.rxn-row-solvent td:first-child,.rxn-row-product td:first-child{box-shadow:inset 3px 0 0 currentColor}
.rxn-row-reagent{color:#b45309}.rxn-row-catalyst{color:#7c3aed}.rxn-row-solvent{color:#0d9488}.rxn-row-product{color:#16a34a}
.rxn-inp{width:100%;background:var(--bg3);border:1px solid transparent;border-radius:var(--r-xs);padding:3px 6px;font-size:12px;color:var(--text);font-family:var(--sans);outline:none;min-width:0}
.rxn-inp:focus{border-color:var(--accent);background:var(--bg2)}
.rxn-inp.calc{background:transparent;color:var(--text2);font-family:var(--mono);font-size:11px;cursor:default}
.rxn-inp.num{width:72px;font-family:var(--mono);text-align:right}
.rxn-inp.num::-webkit-inner-spin-button,.rxn-inp.num::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
.rxn-inp.num{-moz-appearance:textfield}
.rxn-inp.wide{width:120px}
/* Theoretical-mass ghost text (product row) lives in a real sibling <span>,
   not the input's native placeholder — see _updateCalcCells() in eln.js for
   why. The wrapper carries the field's usual background/border so the input
   itself can go transparent and let the ghost text show through underneath. */
.rxn-mass-wrap{position:relative;border:1px solid transparent;border-radius:var(--r-xs);background:var(--bg3)}
.rxn-mass-wrap:focus-within{border-color:var(--accent);background:var(--bg2)}
.rxn-mass-wrap .rxn-inp{background:transparent;border-color:transparent}
.rxn-mass-wrap .rxn-inp:focus{background:transparent}
.rxn-mass-ghost{position:absolute;inset:0;display:flex;align-items:center;justify-content:flex-end;padding:3px 6px;font-family:var(--mono);font-size:12px;color:var(--text3);pointer-events:none;white-space:nowrap;overflow:hidden}
.rxn-role-sel{background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-xs);padding:3px 4px;font-size:11px;color:var(--text);outline:none;width:74px}
.info-tip{position:relative;cursor:help;font-weight:400;color:var(--text3)}
.info-tip::after{content:attr(data-tip);position:absolute;left:0;top:100%;margin-top:6px;background:var(--bg2);color:var(--text);border:1px solid var(--border);border-radius:var(--r-sm);padding:6px 8px;font-size:11px;font-weight:400;white-space:normal;width:220px;z-index:50;display:none;box-shadow:0 4px 12px rgba(0,0,0,.2);text-transform:none}
.info-tip:hover::after,.info-tip:focus::after{display:block}
/* This info-tip sits at the end of a long label near the modal's right edge —
   the default left:0 tooltip would spill outside the (narrower) role modal. */
#rm-requires-countersign ~ .info-tip::after{left:auto;right:0}
.rxn-lim-radio{text-align:center;vertical-align:middle;cursor:pointer}
.rxn-lim-radio input{cursor:pointer;accent-color:var(--accent);display:block;margin:0 auto}
.rxn-del-btn{background:none;border:none;color:var(--text3);cursor:pointer;padding:2px 5px;border-radius:var(--r-xs);font-size:12px}
.rxn-del-btn:hover{background:var(--bg3);color:var(--red)}
.rxn-draw-row-btn{background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-xs);cursor:pointer;padding:1px 5px;font-size:10px;font-family:var(--sans);color:var(--text2);white-space:nowrap}
.rxn-draw-row-btn:hover{border-color:var(--accent);color:var(--accent)}
.rxn-draw-row-btn svg{display:block;width:40px!important;height:32px!important}
.rxn-register-btn{background:none;border:1px solid var(--green);color:var(--green);border-radius:var(--r-xs);font-size:10px;padding:2px 6px;cursor:pointer;white-space:nowrap}
.rxn-register-btn:hover{background:rgba(22,163,74,.1)}
.rxn-registered-badge{font-size:10px;color:var(--green);white-space:nowrap}
.rxn-unlink-btn{background:none;border:1px solid var(--border2);color:var(--text3);cursor:pointer;padding:1px 5px;font-size:9px;border-radius:var(--r-xs);line-height:1.4}
.rxn-unlink-btn:hover{border-color:var(--red);color:var(--red)}
.rxn-role-reactant{color:#b45309}.rxn-role-product{color:#16a34a}.rxn-role-reagent{color:#b45309}.rxn-role-catalyst{color:#7c3aed}.rxn-role-solvent{color:#0d9488}
.eln-textarea{width:100%;background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-sm);padding:10px 12px;font-size:12px;color:var(--text);font-family:var(--sans);resize:vertical;outline:none;min-height:80px;line-height:1.6}
.eln-textarea:focus{border-color:var(--accent);background:var(--bg2)}
.eln-procedure-ce{min-height:140px;white-space:pre-wrap;cursor:text}
.eln-format-bar{display:flex;gap:3px;margin-bottom:4px}
.eln-fmt-btn{background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-xs);padding:2px 0;font-size:12px;color:var(--text);cursor:pointer;line-height:1.6;transition:background .1s;width:28px;text-align:center;flex-shrink:0}
.eln-fmt-btn:hover{background:var(--bg4)}
.eln-fmt-sep{width:1px;height:18px;background:var(--border2);margin:0 8px;flex-shrink:0;align-self:center}
.eln-fmt-color{width:28px;height:28px;border-radius:var(--r-xs);border:2px solid transparent;cursor:pointer;padding:0;flex-shrink:0;transition:border-color .1s,transform .1s}
.eln-fmt-color:hover{border-color:var(--text3);transform:scale(1.1)}
.eln-procedure-ce:empty::before{content:attr(data-placeholder);color:var(--text3);pointer-events:none}
.eln-procedure-ce ol,.eln-procedure-ce ul{padding-left:1.5em;margin:4px 0}
.eln-procedure-ce li{margin:2px 0}
.eln-insert-chips{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:6px;min-height:0}
.eln-ref-chip{background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-lg);padding:2px 9px;font-size:11px;color:var(--text2);cursor:pointer;white-space:nowrap}
.eln-ref-chip:hover{border-color:var(--accent);color:var(--accent)}
.eln-ref{display:inline-block;background:var(--accent-light);border:1px solid color-mix(in srgb,var(--accent) 25%,transparent);border-radius:var(--r-xs);padding:0 5px;font-size:11px;color:var(--accent);cursor:default;user-select:none;white-space:nowrap;font-family:var(--mono)}
.bio-step-ref{display:inline-block;background:var(--accent-light);border:1px solid color-mix(in srgb,var(--accent) 25%,transparent);border-radius:var(--r-xs);padding:0 5px;font-size:11px;color:var(--accent);cursor:pointer;user-select:none;white-space:nowrap;font-family:var(--mono)}
.bio-step-ref:hover{border-color:var(--accent)}
.step-time-chip{display:inline-flex;align-items:center;gap:3px;font-size:11px;padding:1px 7px;border-radius:var(--r-lg);background:var(--bg3);border:1px solid var(--border2);color:var(--text3);white-space:nowrap;font-family:var(--mono)}
.step-time-chip.running{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 35%,transparent)}
.step-time-chip.overrun{color:var(--red);border-color:color-mix(in srgb,var(--red) 40%,transparent);background:color-mix(in srgb,var(--red) 8%,transparent)}
.be-step-card.highlight{outline:2px solid var(--accent);outline-offset:2px}

/* Quill: Quill adds .ql-container to #eln-ed-procedure and inserts .ql-toolbar before it as a sibling */
#eln-ed-procedure.ql-container.ql-snow{border:1px solid var(--border2);border-top:0;border-radius:0 0 6px 6px;font-size:13px;font-family:var(--sans);height:auto!important}
#eln-ed-procedure.ql-container .ql-editor{min-height:200px;height:auto!important;line-height:1.6;color:var(--text);font-family:var(--sans)}
#eln-ed-procedure.ql-container .ql-editor.ql-blank::before{color:var(--text3);font-style:normal}
.ql-toolbar.ql-snow:has(+#eln-ed-procedure){border:1px solid var(--border2);border-radius:var(--r-sm) 6px 0 0;background:var(--bg2);padding:4px 8px;font-family:var(--sans)}
.ql-editor img{max-width:100%;border-radius:var(--r-xs);cursor:pointer}
.ql-img-size-menu{position:absolute;z-index:500;display:flex;gap:2px;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-sm);box-shadow:var(--shadow-sm);padding:2px}
.ql-img-size-menu button{font-size:11px;font-weight:500;padding:3px 8px;border:none;border-radius:var(--r-xs);background:none;color:var(--text2);cursor:pointer;white-space:nowrap}
.ql-img-size-menu button:hover{background:var(--bg3);color:var(--text)}
.ql-img-size-sep{width:1px;background:var(--border2);margin:2px 2px}
.ql-editor .ql-align-center img{display:block;margin-left:auto;margin-right:auto}
.ql-editor .ql-align-right img{display:block;margin-left:auto}
.ql-toolbar.ql-snow:has(+#eln-ed-procedure) .ql-stroke{stroke:var(--text2)}
.ql-toolbar.ql-snow:has(+#eln-ed-procedure) button:hover .ql-stroke,.ql-toolbar.ql-snow:has(+#eln-ed-procedure) button.ql-active .ql-stroke{stroke:var(--accent)}
.ql-toolbar.ql-snow:has(+#eln-ed-procedure) .ql-fill{fill:var(--text2)}
.ql-toolbar.ql-snow:has(+#eln-ed-procedure) button:hover .ql-fill,.ql-toolbar.ql-snow:has(+#eln-ed-procedure) button.ql-active .ql-fill{fill:var(--accent)}
.ql-snow .ql-tooltip{z-index:9999}
.eln-del-btn{color:var(--text3);background:none;border:none;cursor:pointer;padding:4px 8px;border-radius:var(--r-xs);font-size:12px}
.eln-del-btn:hover{background:var(--bg3);color:var(--red)}

/* ── ACTIVITY PAGE ────────────────────────────────────────────── */
.activity-list{margin-top:16px}

/* ── ACTIVITY LOG (collapsed under Statistics) ───────────────────── */
.act-day-header{font-size:11px;font-weight:600;color:var(--text3);text-transform:uppercase;letter-spacing:.03em;padding:14px 0 5px}
.act-day-header:first-child{padding-top:0}

/* ── MODULE ACCESS (Admin > Settings) ────────────────────────────── */
.modlock-table{display:flex;flex-direction:column;gap:10px}
.modlock-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.modlock-name{width:180px;flex-shrink:0;font-size:13px;color:var(--text2)}
.modlock-seg{display:inline-flex;border:1px solid var(--border);border-radius:var(--r-sm);overflow:hidden;flex-shrink:0}
.modlock-seg-btn{padding:5px 12px;font-size:12px;background:var(--bg2);color:var(--text3);border:none;border-right:1px solid var(--border);cursor:pointer}
.modlock-seg-btn:last-child{border-right:none}
.modlock-seg-btn:hover:not(:disabled):not(.active){background:var(--bg3);color:var(--text2)}
.modlock-seg-btn:disabled{cursor:not-allowed;opacity:.55}
.modlock-seg-btn.active{background:var(--accent-light);color:var(--accent);font-weight:500}
.modlock-row .module-lock-reason{flex:1;min-width:180px;max-width:360px;font-size:12px;padding:4px 8px}

/* ── STATS PAGE ───────────────────────────────────────────────── */
.stats-section{margin-bottom:24px}
.stats-section h3{font-size:13px;font-weight:500;margin-bottom:12px;color:var(--text2)}
.stat-grid-wide{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:20px}
.bar-row{display:flex;align-items:center;gap:10px;margin-bottom:7px;font-size:12px}
.bar-label{width:100px;color:var(--text2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex-shrink:0}
.bar-track{flex:1;background:var(--bg3);border-radius:var(--r-xs);height:8px;overflow:hidden}
.bar-fill{height:100%;border-radius:var(--r-xs)}
.bar-count{font-family:var(--mono);font-size:11px;color:var(--text3);width:40px;text-align:right;flex-shrink:0}

/* ── ADMIN PAGE ───────────────────────────────────────────────── */
.admin-section{margin-bottom:32px}
.admin-section h3{font-size:13px;font-weight:600;margin-bottom:14px;padding-bottom:10px;border-bottom:2px solid var(--border);color:var(--text)}
.user-table{width:100%;border-collapse:collapse;font-size:12px}
.user-table th{font-family:var(--sans);font-size:10px;color:var(--text3);font-weight:700;padding:8px 10px;text-align:left;border-bottom:1px solid var(--border);background:var(--bg3);text-transform:uppercase;letter-spacing:.05em}
.user-table td{padding:10px 10px;border-bottom:1px solid var(--border);color:var(--text2);vertical-align:middle}
.user-table tbody tr{transition:background .1s}
.user-table tr:hover td{background:var(--bg3)}
.role-badge{font-family:var(--mono);font-size:10px;padding:3px 8px;border-radius:var(--r-sm);font-weight:600}
.rb-admin{background:var(--accent-light);color:var(--accent)}
.rb-member{background:var(--bg3);color:var(--text3)}
.status-dot{width:8px;height:8px;border-radius:50%;display:inline-block}

/* ── PROJECT MULTI-SELECT ─────────────────────────────────────── */
.proj-select-list{display:flex;flex-direction:column;gap:2px;max-height:120px;overflow-y:auto;border:1px solid var(--border2);border-radius:var(--r-xs);padding:6px}
.proj-sel-item{display:flex;align-items:center;gap:5px;padding:3px 5px;border-radius:var(--r-xs);cursor:pointer;font-size:12px;color:var(--text2)}
.proj-sel-item:hover{background:var(--bg3)}
.proj-sel-item input[type=checkbox]{accent-color:var(--accent);width:13px;height:13px;flex-shrink:0;margin:0}

/* ── EQUIPMENT TAB ────────────────────────────────────────────── */
.equip-grid{display:flex;flex-direction:column;gap:2px}
.equip-table{border-collapse:collapse;width:100%;font-size:13px}
.equip-table thead th{text-align:left;padding:8px 12px;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--text3);border-bottom:2px solid var(--border2);background:var(--bg2);position:sticky;top:0;z-index:1}
.equip-table thead th.eqt-actions-col{width:1%}
.equip-table td{padding:9px 12px;border-bottom:1px solid var(--border);vertical-align:top}
.equip-table-cat td{padding:14px 12px 6px;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text3);border-bottom:none}
.equip-table-row{cursor:pointer;transition:background .12s}
.equip-table-row:hover{background:var(--bg2)}
.equip-table-row.inactive{opacity:.55}
.eqt-name-cell{font-size:13px;font-weight:600;min-width:160px}
.eqt-badge{display:inline-block;font-size:10px;font-weight:600;color:var(--text3);background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-xs);padding:1px 6px}
.eqt-badge-icon{display:inline-flex;align-items:center;justify-content:center;padding:2px;line-height:0}
.eqt-badge-icon svg{vertical-align:middle}
.eqt-empty{color:var(--text3)}
.eqt-location-link{cursor:pointer;border-radius:4px;padding:1px 3px;margin:-1px -3px}
.eqt-location-link:hover{background:var(--accent-light);color:var(--accent)}
.equip-row-desc{font-size:12px;color:var(--text2);line-height:1.4;margin-top:3px;font-weight:400}
.eqt-actions{display:flex;align-items:center;gap:6px;flex-wrap:nowrap;white-space:nowrap}
.equip-until-line{font-size:11px;color:var(--text3);margin-top:2px}
.equip-status{width:7px;height:7px;border-radius:50%;flex-shrink:0;display:inline-block}
.equip-status.on{background:var(--green)}
.equip-status.off{background:var(--text3)}
.equip-status.busy{background:var(--red);animation:equip-status-pulse 1.6s ease-in-out infinite}
@keyframes equip-status-pulse{0%,100%{opacity:1}50%{opacity:.35}}
@media(prefers-reduced-motion:reduce){.equip-status.busy{animation:none}}

/* ── Cleaning tasks table (Lab > Tasks) ──────────────────────────── */
.cln-table{border-collapse:collapse;width:100%;font-size:13px}
.cln-table thead th{text-align:left;padding:8px 12px;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--text3);border-bottom:2px solid var(--border2);background:var(--bg2);position:sticky;top:0;z-index:1}
.cln-table td{padding:9px 12px;border-bottom:1px solid var(--border);vertical-align:top}
.cln-table-row{cursor:pointer;transition:background .12s}
.cln-table-row:hover{background:var(--bg2)}
.cln-table-row.mine-today{background:color-mix(in srgb,var(--accent) 7%,transparent)}
.cln-table-row.mine-today:hover{background:color-mix(in srgb,var(--accent) 12%,transparent)}
.cln-table-row.mine-today td:first-child{box-shadow:inset 2px 0 0 var(--accent)}
.cln-mine-chip{font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--accent);background:color-mix(in srgb,var(--accent) 16%,transparent);padding:2px 6px;border-radius:var(--r-xs);white-space:nowrap}
.cln-name-cell{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;min-width:160px}
.cln-row-summary{font-size:12px;color:var(--text3)}
.cln-overdue-summary{color:var(--chip-red-fg);font-weight:600}
.cln-row-chevron{flex-shrink:0;color:var(--text3);transition:transform .15s}
.cln-table-row.expanded .cln-row-chevron{transform:rotate(90deg)}
.cln-table-body-row td{cursor:default;background:var(--bg2)}
.cln-table-body-row .btn{cursor:pointer}
.equip-busy-badge{color:var(--red);font-weight:600}
.equip-free-badge{color:var(--green);font-weight:600}

/* ══ Equipment > Map ═══════════════════════════════════════════ */
#map-room-bar{display:flex;align-items:center;gap:8px;padding:10px 16px;border-bottom:1px solid var(--border);flex-wrap:wrap}
#map-room-pills{display:flex;gap:6px;flex-wrap:wrap;flex:1}
#map-mode-toggle{display:flex;background:var(--bg3);border-radius:var(--r-md);padding:2px;gap:1px}
#map-mode-toggle button{border:none;background:transparent;color:var(--text2);font-size:12px;font-weight:600;padding:5px 12px;border-radius:calc(var(--r-md) - 2px);cursor:pointer;transition:background .12s,color .12s}
#map-mode-toggle button.active{background:var(--bg2);color:var(--text);box-shadow:var(--shadow-sm)}
.map-draw-tools{display:flex;align-items:center;gap:4px;padding:2px 6px;background:var(--bg3);border-radius:var(--r-md)}
.map-draw-tools .icon-btn.armed{background:var(--accent);color:#fff}
.map-shape-picker{position:absolute;top:calc(100% + 6px);left:0;z-index:30;display:flex;gap:2px;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);padding:4px;box-shadow:var(--shadow-md)}
.map-shape-picker button{border:none;background:transparent;color:var(--text2);padding:6px;border-radius:6px;cursor:pointer;display:flex;transition:background .12s,color .12s}
.map-shape-picker button:hover{background:var(--bg3);color:var(--text)}
#map-body{display:flex;flex:1;overflow:hidden}
#map-canvas-wrap{flex:1;overflow:auto;padding:20px;display:flex;align-items:flex-start;justify-content:center;background:var(--bg)}
#map-canvas{position:relative;display:inline-block;max-width:100%;transition:filter .15s}
#map-canvas img{max-width:100%;display:block;border-radius:var(--r-lg);border:1px solid var(--border);box-shadow:var(--shadow-md);-webkit-user-drag:none;user-select:none}
#map-canvas.empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;width:100%;min-height:300px;color:var(--text3);font-size:13px;text-align:center}
#map-canvas.drag-over img{outline:2px dashed var(--accent);outline-offset:2px}
#map-sidebar{width:220px;flex-shrink:0;border-left:1px solid var(--border);padding:14px;overflow-y:auto}
.map-sidebar-title{font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--text3);margin-bottom:10px}
#map-status-filters{margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid var(--border)}
.map-group-title{font-size:10px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--text3);margin:12px 0 6px;padding-top:8px;border-top:1px solid var(--border);cursor:pointer;border-radius:4px;transition:color .12s}
.map-group-title:first-child{margin-top:0;padding-top:0;border-top:none}
.map-group-title:hover{color:var(--accent)}
.map-group-title.selected{color:var(--accent)}
.map-unplaced-chip{padding:7px 10px;border:1px solid var(--border);border-radius:var(--r-md);font-size:13px;margin-bottom:6px;cursor:pointer;background:var(--bg2);transition:border-color .15s,background .15s}
.map-unplaced-chip:hover{border-color:var(--accent)}
.map-unplaced-chip:active{cursor:grabbing}
.map-unplaced-chip.selected{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,var(--bg2))}
.map-unplaced-chip .mc-dot{display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:6px;vertical-align:middle}

.map-area{position:absolute;border-radius:6px;border:1.5px solid transparent;cursor:grab;box-sizing:border-box;min-width:12px;min-height:12px;box-shadow:0 1px 3px rgba(0,0,0,.12);transition:opacity .18s,filter .18s}
.map-area:hover{z-index:4}
.map-area:active{cursor:grabbing}
#map-canvas.edit-mode .map-area{cursor:grab}
#map-canvas:not(.edit-mode) .map-area{cursor:pointer}
.map-area-busy{background:color-mix(in srgb,var(--red) 26%,transparent);border-color:color-mix(in srgb,var(--red) 70%,transparent)}
.map-area-free{background:color-mix(in srgb,var(--green) 26%,transparent);border-color:color-mix(in srgb,var(--green) 70%,transparent)}
.map-area-maintenance{background:color-mix(in srgb,var(--orange) 26%,transparent);border-color:color-mix(in srgb,var(--orange) 70%,transparent)}
.map-area-assigned{background:color-mix(in srgb,var(--accent) 26%,transparent);border-color:color-mix(in srgb,var(--accent) 70%,transparent)}
.map-area-inactive{background:color-mix(in srgb,var(--text3) 20%,transparent);border-color:color-mix(in srgb,var(--text3) 60%,transparent)}
.map-area-drawing{background:color-mix(in srgb,var(--accent) 14%,transparent);border:2px dashed var(--accent);pointer-events:none;box-shadow:none}
.map-area.highlighted{filter:brightness(1.15) saturate(1.3);box-shadow:0 0 0 2px var(--bg2),0 0 0 4px var(--accent),0 4px 14px rgba(0,0,0,.25);z-index:5}
.map-area.dimmed{opacity:.25}
/* Free-standing work areas (RoomMarker) — a dashed neutral zone, distinct
   from equipment's solid status colors since a marker has no status. Custom
   color (--marker-color) is optional; falls back to --text3. */
.map-marker-area{background:color-mix(in srgb,var(--marker-color,var(--text3)) 16%,transparent);border:1.5px dashed color-mix(in srgb,var(--marker-color,var(--text3)) 65%,transparent);z-index:1}
.map-marker-area .map-area-label{color:var(--text2);font-weight:600}
/* Safety-icon markers (extinguisher, exit, shower...) — a small solid badge
   rather than a dashed zone, since these mark one physical fixture, not an
   area. Green reads as "safety equipment" without hijacking the semantic
   status colors equipment areas use. */
.map-marker-safety{background:color-mix(in srgb,var(--red) 18%,var(--bg2));border:1.5px solid color-mix(in srgb,var(--red) 55%,transparent);z-index:2}
.map-marker-safety .map-area-icon{color:var(--red)}

/* Free-floating text — no box at all, just the label */
.map-marker-text{background:none;border:none;box-shadow:none;z-index:2}
.map-marker-text .map-area-label{color:var(--text);font-weight:700;font-size:13px;white-space:nowrap}

/* Decorative shapes (square/circle/arrow) — pure diagramming, no label */
.map-marker-shape{background:color-mix(in srgb,var(--marker-color,var(--text2)) 30%,transparent);border:1.5px solid color-mix(in srgb,var(--marker-color,var(--text2)) 70%,transparent);z-index:1}
.map-shape-circle{border-radius:50%}
.map-shape-square{border-radius:4px}
.map-shape-arrow{background:none;border:none;box-shadow:none;color:var(--marker-color,var(--text2))}
.map-shape-arrow-svg{position:absolute;inset:12%;width:76%;height:76%}
.map-safety-chip{display:flex;align-items:center;gap:7px}
.map-safety-chip svg{flex-shrink:0;color:var(--red)}
#map-canvas.armed-draw{cursor:crosshair}
#map-canvas.armed-draw .map-area{pointer-events:none}
.map-area-icon{display:inline-flex;color:var(--text);filter:drop-shadow(0 0 2px var(--bg2)) drop-shadow(0 0 2px var(--bg2))}
.map-area-label{font-size:10px;font-weight:700;color:var(--text);background:color-mix(in srgb,var(--bg2) 82%,transparent);border-radius:3px;padding:0 4px;line-height:1.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.map-area-assignee{font-size:9px;font-weight:600;color:var(--accent);background:color-mix(in srgb,var(--bg2) 82%,transparent);border-radius:3px;padding:0 4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
/* Single always-present, always-positioned label — centered on the box by
   default, moved to wherever it was last dragged otherwise (see
   _mapPositionLabels/_mapBindLabelDrag in equipment.js). A narrow area
   rotates its label 90° instead of clipping it, and a too-small/dragged-out
   one gets a short leader line, same idea as a map-pin callout. */
.map-area-label-pos{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;gap:1px;pointer-events:none;z-index:3;max-width:160px;padding:3px}
.map-area-label-pos.outside .map-area-label,.map-area-label-pos.outside .map-area-assignee{white-space:nowrap;max-width:none}
/* Leader line — real geometry (see _mapPositionLabels), not a fixed tick:
   left/top/width/transform are all set from JS per-area so it always runs
   from whichever side of the box faces the label to whichever side of the
   label faces the box. */
.map-area-line{position:absolute;left:0;top:0;height:1px;width:0;background:var(--text3);transform-origin:0 50%;pointer-events:none;z-index:2;display:none}
.map-area-label-pos.vertical{flex-direction:row}
.map-area-label-pos.vertical .map-area-label,
.map-area-label-pos.vertical .map-area-assignee{writing-mode:vertical-rl;text-orientation:mixed;white-space:nowrap;max-height:100%}
/* Only receives pointer events (and this hover) once _mapBindLabelDrag has
   set pointer-events:auto inline — i.e. only in edit mode, and only after
   this element is actually draggable, so the affordance can't lie. */
.map-area-label-pos:hover{outline:1.5px dashed var(--accent);outline-offset:2px;border-radius:4px}
.map-area-delete{position:absolute;top:-8px;right:-8px;width:16px;height:16px;border-radius:50%;border:1px solid var(--border);background:var(--bg2);color:var(--text2);font-size:9px;line-height:1;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:0;transition:opacity .12s,background .12s,color .12s}
.map-area:hover .map-area-delete{opacity:1}
.map-area-delete:hover{background:var(--red);color:#fff;border-color:var(--red)}
/* Open-issue badge — always visible (not hover-only like delete), opposite
   corner so the two never collide. */
.map-area-issue{position:absolute;top:-8px;left:-8px;width:18px;height:18px;border-radius:50%;border:1px solid var(--bg2);background:var(--red);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:6;box-shadow:0 1px 3px rgba(0,0,0,.25);padding:0}
.map-area-issue svg{width:11px;height:11px}
.map-area-issue:hover{filter:brightness(1.15)}
.map-area-handle{position:absolute;width:9px;height:9px;background:var(--bg2);border:1.5px solid var(--text);border-radius:2px;opacity:0;transition:opacity .12s}
.map-area:hover .map-area-handle{opacity:1}
.map-area-handle-nw{top:-5px;left:-5px;cursor:nwse-resize}
.map-area-handle-se{bottom:-5px;right:-5px;cursor:nwse-resize}
.map-area-handle-ne{top:-5px;right:-5px;cursor:nesw-resize}
.map-area-handle-sw{bottom:-5px;left:-5px;cursor:nesw-resize}

/* Edit-mode click menu on an area — Remove from map / Move label out|in.
   position:fixed + viewport coords (see _mapOpenAreaMenu), same small-card
   look as .user-dropdown. */
.map-area-menu{position:fixed;z-index:2100;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-lg);min-width:170px;overflow:hidden;box-shadow:var(--shadow-md)}
.map-area-menu button{display:block;width:100%;padding:9px 14px;text-align:left;background:transparent;border:none;color:var(--text2);font-size:12px;font-family:var(--sans);cursor:pointer;transition:background .1s,color .1s}
.map-area-menu button:hover{background:var(--bg3);color:var(--text)}
.map-area-menu button.danger:hover{color:var(--red)}

/* Hover info card — cursor-following, same pattern as #well-tooltip/
   #bio-exp-tooltip (see _positionTooltip in boxes.js) */
#map-tooltip{position:fixed;z-index:2000;pointer-events:none;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);box-shadow:var(--shadow-lg);padding:11px 13px;font-size:12px;display:none;width:230px}
#map-tooltip .mtt-name{font-weight:700;color:var(--text);font-size:13px;margin-bottom:2px}
#map-tooltip .mtt-status{font-size:11px;font-weight:600;margin-bottom:6px}
#map-tooltip .mtt-desc{color:var(--text2);font-size:12px;line-height:1.4;margin-bottom:6px}
#map-tooltip .mtt-row{display:flex;justify-content:space-between;gap:8px;font-size:11px;padding:3px 0;border-top:1px solid var(--border)}
#map-tooltip .mtt-row span:first-child{color:var(--text3);flex-shrink:0}
#map-tooltip .mtt-row span:last-child{text-align:right;color:var(--text)}
/* agenda */
.equip-agenda-wrap{overflow-x:auto;overflow-y:auto;flex:1}
.equip-agenda-inner{min-width:660px}
.equip-agenda-header{display:grid;grid-template-columns:52px repeat(7,1fr);position:sticky;top:0;z-index:2;background:var(--bg2);border-bottom:2px solid var(--border2);box-shadow:var(--shadow-sm)}
.equip-agenda-header .equip-day-hdr{padding:10px 4px 8px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:2px;font-size:10px;font-weight:600;color:var(--text3);text-transform:uppercase;letter-spacing:.05em}
.equip-day-num{width:26px;height:26px;display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:14px;font-weight:600;color:var(--text2);letter-spacing:-.01em;line-height:1}
.equip-agenda-header .equip-day-hdr.today{color:var(--accent)}
.equip-agenda-header .equip-day-hdr.today .equip-day-num{background:var(--accent);color:#fff}
.equip-agenda-body{display:grid;grid-template-columns:52px repeat(7,1fr);padding-top:6px}
.equip-time-gutter{position:relative;background:var(--bg2)}
.equip-time-label{position:absolute;right:7px;font-size:10px;color:var(--text3);transform:translateY(-50%);font-family:var(--mono);white-space:nowrap}
.equip-day-col{position:relative;border-left:1px solid var(--border);cursor:pointer;transition:background .1s}
.equip-day-col:hover{background:color-mix(in srgb,var(--accent) 4%,transparent)}
.equip-offhour{position:absolute;left:0;right:0;background:var(--bg3);pointer-events:none;opacity:.6}
.equip-hour-line{position:absolute;left:0;right:0;border-top:1px solid var(--border)}
.equip-half-line{position:absolute;left:0;right:0;border-top:1px dashed var(--border);opacity:.4}
.equip-now-line{position:absolute;left:0;right:0;border-top:2px solid var(--red);z-index:3;pointer-events:none}.equip-now-line::before{content:'';position:absolute;left:-4px;top:-4px;width:8px;height:8px;border-radius:50%;background:var(--red)}
.equip-booking{position:absolute;left:3px;right:3px;border-radius:var(--r-sm);padding:4px 7px;font-size:11px;overflow:hidden;cursor:default;z-index:1;border-left-width:3px;border-left-style:solid;transition:box-shadow .12s,filter .12s}
.equip-booking.mine{cursor:pointer}
.equip-booking.mine:hover{filter:brightness(.92);box-shadow:0 2px 8px rgba(0,0,0,.12)}
.equip-booking-user{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:11px}
.equip-booking-time{font-size:10px;opacity:.75;font-family:var(--mono);margin-top:1px}
/* overview */
.equip-overview-wrap{overflow-x:auto}
.equip-overview-table{border-collapse:collapse;width:100%;min-width:640px;font-size:12px}
.equip-overview-table th{padding:8px 8px;text-align:center;font-size:11px;font-weight:600;color:var(--text2);border-bottom:2px solid var(--border2);white-space:nowrap;text-transform:uppercase;letter-spacing:.04em}
.equip-overview-table th.eq-name-col{text-align:left;width:140px;text-transform:none;font-size:12px}
.equip-overview-table th.today-col{color:var(--accent);background:var(--accent-light)}
.equip-overview-table td{border:1px solid var(--border);padding:2px;vertical-align:top;height:56px;cursor:pointer}
.equip-overview-table td:hover{background:var(--bg3)}
.equip-overview-table td.eq-name-cell{cursor:default;padding:6px 8px;font-weight:500;color:var(--accent);vertical-align:middle;border-right:2px solid var(--border2);display:flex;align-items:center;gap:4px}
.equip-overview-table td.eq-name-cell:hover{background:var(--accent-light)}
.eq-name-cell-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.eq-name-cell .icon-btn{flex-shrink:0;opacity:.55}
.eq-name-cell .icon-btn:hover{opacity:1}
.equip-overview-cell{position:relative;width:100%;height:52px}
.equip-ov-block{position:absolute;top:2px;height:calc(100% - 4px);border-radius:var(--r-xs);min-width:3px;overflow:hidden;font-size:9px;padding:1px 3px;white-space:nowrap;border-left-width:2px;border-left-style:solid}
/* reagent catalog list rows */
.rs-row{display:flex;gap:8px;align-items:center;padding:8px 12px;border-bottom:1px solid var(--border);cursor:pointer;transition:background .1s}
.rs-row:hover{background:var(--bg2)}
.rs-row.active{background:var(--accent-light);border-left:2px solid var(--accent)}
.rs-row-thumb{width:44px;height:44px;flex-shrink:0;background:var(--bg2);border-radius:var(--r-sm);overflow:hidden;display:flex;align-items:center;justify-content:center;border:1px solid var(--border)}
.rs-row-body{flex:1;min-width:0}
.rs-row-name{font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rs-row-meta{font-size:10px;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
.rs-row-stock{font-size:10px;font-weight:500;flex-shrink:0;text-align:right}
/* month calendar */
#equip-month-inner{padding:12px 16px}
.equip-month-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:0;border-top:1px solid var(--border);border-left:1px solid var(--border)}
.equip-month-head{text-align:center;font-size:11px;font-weight:600;color:var(--text3);padding:6px 4px;border-right:1px solid var(--border);border-bottom:2px solid var(--border2)}
/* min-width:0 is load-bearing: a grid item's default auto-minimum is its
   content's min-content width, and a nowrap+ellipsis event label (long
   absence name, long celebration title...) has nothing to wrap to — so
   that day's column silently grew wider than the other six until this
   overrode it, ellipsis clipping only kicking in *after* the column had
   already been sized against the unwrapped text. */
.equip-month-cell{min-height:88px;min-width:0;overflow:hidden;border-right:1px solid var(--border);border-bottom:1px solid var(--border);padding:4px;cursor:pointer;transition:background .1s}
.equip-month-cell:hover{background:var(--accent-light)}
.equip-month-cell.emc-today .equip-month-day-num{background:var(--accent);color:#fff;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-weight:700}
.equip-month-cell.emc-other{opacity:.45}
.equip-month-cell.emc-drag-sel{background:var(--accent-light);box-shadow:inset 0 0 0 1px var(--accent)}
.equip-month-cell{user-select:none}
.equip-month-day-num{font-size:12px;font-weight:500;color:var(--text2);margin-bottom:3px;width:20px;height:20px;display:flex;align-items:center;justify-content:center}
.equip-month-event{font-size:10px;border-radius:var(--r-xs);padding:1px 4px;margin-bottom:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-left-width:2px;border-left-style:solid;cursor:pointer}
.equip-month-event:hover{filter:brightness(1.1)}
.equip-month-more{font-size:10px;color:var(--text3);padding-left:4px}
/* Tasks month calendar tends to have more entries per day than Bookings/Team, so it gets a taller cell */
#maint-month-wrap .equip-month-cell{min-height:150px}

/* ── TOAST ────────────────────────────────────────────────────── */
.toast{position:fixed;bottom:24px;right:24px;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-lg);padding:11px 16px 11px 14px;font-size:13px;z-index:500;transform:translateY(80px);opacity:0;transition:transform .25s cubic-bezier(.34,1.56,.64,1),opacity .2s ease;pointer-events:none;box-shadow:var(--shadow-md);display:flex;align-items:center;gap:9px;max-width:320px;font-weight:500}
.toast::before{font-size:15px;flex-shrink:0}
.toast.show{transform:translateY(0);opacity:1}
.toast.success{border-left:3px solid var(--green);color:var(--green);border-color:color-mix(in srgb,var(--green) 30%,var(--border))}
.toast.success::before{content:'✓'}
.toast.error{border-left:3px solid var(--red);color:var(--red);border-color:color-mix(in srgb,var(--red) 30%,var(--border))}
.toast.error::before{content:'✕'}
.toast.info{border-left:3px solid var(--accent);color:var(--accent);border-color:color-mix(in srgb,var(--accent) 30%,var(--border))}
.toast.info::before{content:'ℹ'}

.empty{text-align:center;padding:40px 20px;color:var(--text3);font-size:13px;line-height:1.6}
.empty-sm{color:var(--text3);font-size:12px;padding:10px 12px}
.page-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:16px;margin-bottom:20px;border-bottom:1px solid var(--border)}
.page-title{font-size:16px;font-weight:700;letter-spacing:-.02em;color:var(--text)}

/* ── DRAW BUTTON ──────────────────────────────────────────────── */
.btn-draw{display:inline-flex;align-items:center;gap:4px;padding:4px 9px;border-radius:var(--r-xs);font-size:11px;cursor:pointer;border:1px solid var(--border2);background:var(--bg3);color:var(--text2);transition:all .15s;white-space:nowrap}
.btn-draw:hover{border-color:var(--border2);color:var(--text)}

/* ── STOCK TYPE SELECTOR ──────────────────────────────────────── */
.stock-type-seg{display:flex;background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-sm);overflow:hidden;margin-bottom:12px}
.stock-type-seg label{flex:1;text-align:center;padding:6px 4px;font-size:11px;cursor:pointer;color:var(--text2);transition:all .15s;user-select:none}
.stock-type-seg input[type=radio]{display:none}
.stock-type-seg label:has(input:checked){background:var(--accent);color:#fff}

/* ── BOXES PAGE ───────────────────────────────────────────────── */
.boxes-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px;margin-top:12px}
.box-card{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;transition:border .15s,box-shadow .15s,transform .15s;cursor:pointer;box-shadow:var(--shadow-sm)}
.box-card:hover{border-color:var(--accent);box-shadow:var(--shadow-md);transform:translateY(-1px)}
.box-card-header{padding:12px 14px 8px;display:flex;align-items:flex-start;justify-content:space-between;gap:8px}
.box-card-title{font-size:13px;font-weight:500}
.box-card-meta{font-size:11px;color:var(--text3);margin-top:2px}
.box-mini-wrap{padding:2px 14px 10px}
.box-mini-grid{display:inline-flex;flex-direction:column;gap:1px}
.box-mini-row{display:flex;gap:1px}
.box-mini-cell{width:9px;height:9px;border-radius:1px}
.plate-mini-cell{width:9px;height:9px;border-radius:50%}
.box-card-footer{padding:8px 14px;border-top:1px solid var(--border);display:flex;align-items:center;gap:10px;font-size:11px;color:var(--text3)}
.box-occ-bar{flex:1;background:var(--bg3);border-radius:var(--r-xs);height:4px;overflow:hidden}
.box-occ-fill{height:100%;border-radius:var(--r-xs);background:var(--accent)}

/* ── BOX DETAIL GRID ──────────────────────────────────────────── */
.box-detail-wrap{overflow:auto;margin-top:10px}
.box-detail-tbl{border-collapse:separate;border-spacing:3px}
.bd-corner{width:18px;height:18px}
.bd-col-lbl{font-size:9px;color:var(--text3);font-family:var(--mono);text-align:center;min-width:34px}
.bd-row-lbl{font-size:9px;color:var(--text3);font-family:var(--mono);vertical-align:middle;padding-right:4px;text-align:right;width:18px}
.bd-cell{width:34px;min-width:34px;height:34px;border-radius:50%;border:1px solid var(--border);cursor:pointer;text-align:center;vertical-align:middle;font-size:8px;font-family:var(--mono);transition:all .12s;user-select:none;line-height:1.2;padding:2px;overflow:hidden}
.bd-cell.empty{background:var(--bg3);color:var(--text3)}
.bd-cell.empty:hover{border-color:var(--accent);background:var(--accent-light);color:var(--accent)}
.bd-cell.occupied{color:#fff;font-weight:500}
.bd-cell.occupied:hover{filter:brightness(1.1);transform:scale(1.12);z-index:1;position:relative;box-shadow:var(--shadow-md)}
.bd-cell.highlighted{outline:2px solid var(--accent);outline-offset:2px}

/* ── COMPOUND MODAL (stacked over box view) ───────────────────── */
#compound-modal-overlay{z-index:400}
/* _pjZoomStructure is opened from inside other already-open modals (Molecule,
   reagent requests, ELN structure thumbnails...) — needs a higher z-index
   than the base .modal-overlay, not just DOM order, or whichever of the two
   .modal-overlay elements happened to be created first in the page's
   lifetime silently wins the tie and the zoom view opens behind it. */
#structure-zoom-modal{z-index:400}
/* Confirm/prompt must always sit above whatever modal spawned them — #info-modal
   and #prompt-modal are appended to <body> at first use, so DOM order alone would
   paint them over the (static, earlier) #confirm-modal. */
#prompt-modal{z-index:450}
#confirm-modal{z-index:500}
/* Same DOM-order problem as above: Ketcher is opened from inside another
   already-open modal (compound edit, molecule detail, ELN row…) far more
   often than from the bare page, so it must always win regardless of which
   modal happens to come later in the DOM. */
#draw-modal{z-index:520}
.cm-grid{display:grid;grid-template-columns:240px 1fr;gap:16px;margin-bottom:14px}
#cm-svg{background:var(--bg3);border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;min-height:155px;border:1px solid var(--border);overflow:hidden}
#cm-svg svg{max-width:230px;max-height:155px}
.cm-prop{display:flex;justify-content:space-between;font-size:11px;padding:3px 0;border-bottom:1px solid var(--divider)}
.cm-prop span:first-child{color:var(--text3)}
.cm-prop span:last-child{font-family:var(--mono);text-align:right}
.cm-stock-row{display:flex;justify-content:space-between;align-items:center;font-size:11px;padding:4px 0;border-bottom:1px solid var(--divider)}
#cm-loguse{background:var(--bg3);border-radius:var(--r-sm);padding:9px 12px;margin-bottom:12px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
#cm-vol{width:68px;font-size:12px}
#cm-qty{width:68px;font-size:12px}
#cm-stock-sel{font-size:12px;flex:1;min-width:100px}
/* Move mode */
#move-bar{display:none;align-items:center;gap:8px;background:var(--accent-light);border:1px solid color-mix(in srgb,var(--accent) 22%,transparent);border-radius:var(--r-md);padding:8px 12px;margin-bottom:10px;font-size:12px;flex-wrap:wrap}
#move-bar select{font-size:11px;padding:3px 6px;border-radius:var(--r-sm);border:1px solid var(--border2);background:var(--bg2);color:var(--text);cursor:pointer}
.bd-cell.move-src{outline:2px solid var(--orange) !important;outline-offset:2px}
.bd-cell.move-ok{background:color-mix(in srgb,var(--accent) 13%,transparent) !important;border-color:var(--accent) !important;cursor:crosshair !important}
/* Assign pick mode */
#assign-bar{display:none;align-items:center;gap:8px;background:color-mix(in srgb,var(--green) 10%,transparent);border:1px solid color-mix(in srgb,var(--green) 30%,transparent);border-radius:var(--r-md);padding:8px 12px;margin-bottom:10px;font-size:12px;flex-wrap:wrap}
.bd-cell.assign-ok{background:color-mix(in srgb,var(--green) 15%,transparent) !important;border-color:color-mix(in srgb,var(--green) 50%,transparent) !important;cursor:crosshair !important}
.bd-cell.move-ok:hover{background:color-mix(in srgb,var(--accent) 28%,transparent) !important;transform:scale(1.15) !important}
.bd-cell.move-blocked{opacity:0.3;cursor:not-allowed !important;pointer-events:none}
.bd-cell[draggable="true"]{cursor:grab}
.bd-cell[draggable="true"]:active{cursor:grabbing}
.bd-cell.drag-over{outline:2px solid var(--accent);background:color-mix(in srgb,var(--accent) 20%,transparent) !important;transform:scale(1.1);z-index:1;position:relative}

/* ── WELL TOOLTIP ─────────────────────────────────────────────── */
#well-tooltip{position:fixed;z-index:9999;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-lg);padding:12px 14px;pointer-events:none;display:none;box-shadow:var(--shadow-lg);min-width:190px;max-width:230px}
#well-tooltip .wtt-id{font-family:var(--mono);font-size:13px;font-weight:600;color:var(--text);margin-bottom:2px}
#well-tooltip .wtt-pos{font-size:10px;color:var(--text3);margin-bottom:8px}
#well-tooltip .wtt-svg{text-align:center;min-height:70px;display:flex;align-items:center;justify-content:center;margin-bottom:8px}
#well-tooltip .wtt-svg svg{max-width:170px;max-height:90px;border-radius:var(--r-xs)}
#well-tooltip .wtt-row{display:flex;justify-content:space-between;font-size:10px;padding:2px 0;border-top:1px solid var(--border)}
#well-tooltip .wtt-row span:first-child{color:var(--text3)}
#well-tooltip .wtt-row span:last-child{font-family:var(--mono);color:var(--text)}

/* ── POSITION PICKER ──────────────────────────────────────────── */
.pp-wrap{overflow-x:auto;margin-top:8px}
.pp-tbl{border-collapse:separate;border-spacing:3px}
.pp-col-lbl{font-size:8px;color:var(--text3);font-family:var(--mono);text-align:center;min-width:28px}
.pp-row-lbl{font-size:8px;color:var(--text3);font-family:var(--mono);padding-right:4px;text-align:right;width:16px}
.pp-cell{width:28px;min-width:28px;height:28px;border-radius:50%;border:1px solid var(--border);font-size:7px;font-family:var(--mono);text-align:center;vertical-align:middle;transition:all .1s;user-select:none;overflow:hidden;line-height:1.2;padding:2px}
.pp-cell.empty{background:var(--bg3);cursor:pointer}
.pp-cell.empty:hover{border-color:var(--accent);background:var(--accent-light);transform:scale(1.1)}
.pp-cell.taken{background:var(--border2);color:var(--text2);cursor:default;font-weight:500}
.pp-cell.chosen{background:var(--accent);border-color:var(--accent);color:#fff;cursor:pointer;transform:scale(1.1);box-shadow:0 2px 8px color-mix(in srgb,var(--accent) 40%,transparent)}



/* ── CUSTOM CONFIRM ───────────────────────────────────────────── */
#confirm-modal .modal{max-width:380px}
#confirm-msg{font-size:13px;color:var(--text2);line-height:1.6;margin-bottom:18px}
#confirm-title{font-size:15px;font-weight:600;margin-bottom:8px}

/* ── PRINT LABEL ──────────────────────────────────────────────── */
@media print {
  body > *:not(#print-frame){ display:none!important }
  #print-frame{ display:block!important; position:static; background:#fff; }
}
#print-frame{ display:none }
/* ── ELN PDF report styles (injected into #print-frame) ─────── */
.eln-report{ font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; font-size:11pt; color:#111; padding:18mm 20mm; max-width:none }
.eln-report h1{ font-size:15pt; font-weight:700; margin:0 0 2mm }
.eln-report h2{ font-size:10pt; font-weight:600; color:#444; margin:6mm 0 2mm; text-transform:uppercase; letter-spacing:.05em; border-bottom:0.5pt solid #ddd; padding-bottom:1mm }
.eln-report .rpt-header{ display:flex; justify-content:space-between; align-items:flex-start; border-bottom:1.5pt solid #111; padding-bottom:3mm; margin-bottom:5mm }
.eln-report .rpt-meta{ display:grid; grid-template-columns:auto 1fr; gap:1mm 6mm; font-size:9pt; margin-bottom:4mm }
.eln-report .rpt-meta .lbl{ color:#666; font-weight:500 }
.eln-report table{ width:100%; border-collapse:collapse; font-size:8.5pt; margin-bottom:4mm }
.eln-report table th{ background:#f0f0f0; border:0.5pt solid #ccc; padding:1.5mm 2mm; text-align:left; font-weight:600 }
.eln-report table td{ border:0.5pt solid #ccc; padding:1.5mm 2mm; vertical-align:top }
.eln-report table tr.role-catalyst td{ background:#fffbf0 }
.eln-report table tr.role-solvent  td{ background:#f0f8ff }
.eln-report table tr.role-product  td{ background:#f0fff4 }
.eln-report .rpt-conditions{ display:flex; gap:8mm; flex-wrap:wrap; font-size:9.5pt; margin-bottom:4mm; padding:2mm 3mm; background:#f8f8f8; border-radius:2mm }
.eln-report .rpt-conditions span{ white-space:nowrap }
.eln-report .rpt-conditions .lbl{ color:#666; font-size:8.5pt }
.eln-report .rpt-body{ white-space:pre-wrap; font-size:10pt; line-height:1.5; text-align:justify }
.eln-report .rpt-body ol,.eln-report .rpt-body ul{ padding-left:1.5em; margin:4px 0; white-space:normal }
.eln-report .rpt-body li{ margin:2px 0 }
.eln-report .rpt-footer{ margin-top:8mm; font-size:8pt; color:#999; border-top:0.5pt solid #ddd; padding-top:2mm }
.eln-report .rpt-scheme{ text-align:center; margin:3mm 0 5mm; page-break-inside:avoid }
.eln-report .rpt-scheme svg,.eln-report .rpt-scheme img{ max-width:100%; max-height:60mm }
.label-sheet{ display:flex; flex-wrap:wrap; gap:8mm; padding:10mm }
.vial-label{
  border:0.5pt solid #ccc; border-radius:2mm;
  padding:3mm; display:flex; flex-direction:column; justify-content:space-between;
  font-family:"SF Mono",Menlo,ui-monospace,"Courier New",monospace; box-sizing:border-box;
  page-break-inside:avoid; position:relative;
}
.vial-label .lbl-id{ font-size:var(--lbl-id,14pt); font-weight:700; letter-spacing:-.3px; line-height:1.1; white-space:nowrap; overflow:hidden; display:block; transform-origin:left center }
.vial-label .lbl-sub{ font-size:var(--lbl-body,7pt); color:#555; margin-top:0.5mm; line-height:1.15; white-space:nowrap; overflow:hidden; display:block; transform-origin:left center }
.vial-label .lbl-qty{ font-size:var(--lbl-body,7pt); font-weight:600; margin-top:0.5mm; line-height:1.15; white-space:nowrap; overflow:hidden; display:block; transform-origin:left center }
.vial-label .lbl-comment{ font-size:var(--lbl-body,7pt); font-weight:600; color:#111; line-height:1.2; white-space:nowrap; overflow:hidden; display:block; transform-origin:left center }
.vial-label .lbl-qr{ flex-shrink:0; margin-top:1mm }
.vial-label-inner{ display:flex; flex-direction:column; height:100%; overflow:hidden }
.vial-label-text{ flex:1 1 0; min-height:0; min-width:0; overflow:hidden }

/* ── MOBILE ───────────────────────────────────────────────────── */
@media(max-width:768px){
  header{padding:0 12px;gap:8px}
  nav{gap:0;padding:0 2px}
  nav .nav-item{padding:5px 8px;font-size:12px;height:32px}
  aside{display:none;position:fixed;left:0;top:56px;bottom:0;z-index:200;width:260px;box-shadow:4px 0 24px rgba(0,0,0,.12);border-right:1px solid var(--border)}
  aside.open{display:flex;flex-direction:column;animation:slide-in-left .2s cubic-bezier(.4,0,.2,1)}
  @keyframes slide-in-left{from{transform:translateX(-100%)}to{transform:translateX(0)}}
  #mobile-menu-btn{display:flex}
  .dp.open{width:100%!important;right:0!important;transform:none!important;border-left:none;border-radius:0}
  .modal{width:100vw;max-width:100vw;border-radius:var(--r-xl) var(--r-xl) 0 0;padding:20px 20px;position:fixed;bottom:0;left:0;right:0;max-height:90vh;margin:0}
  .modal-overlay{align-items:flex-end}
  .btn{min-height:40px;padding:8px 14px}
  .form-row input,.form-row select,.form-row textarea{min-height:42px;font-size:14px}
  .home-grid{gap:12px}
  .home-card{padding:16px}
}
@media(max-width:480px){
  .home-grid{grid-template-columns:1fr;gap:10px}
  nav .nav-item span{display:none}
  nav .nav-item{padding:5px 10px}
  .dp.open{width:100vw}
}
#mobile-menu-btn{display:none;align-items:center;justify-content:center;width:36px;height:36px;border-radius:var(--r-md);border:1px solid var(--border2);background:var(--bg2);cursor:pointer;font-size:18px;margin-right:4px;flex-shrink:0;transition:background .12s}
#mobile-menu-btn:hover{background:var(--bg3)}
#yt-overlay{position:fixed;inset:0;background:rgba(0,0,0,.92);backdrop-filter:blur(8px);z-index:10000;display:none;align-items:center;justify-content:center;flex-direction:column;gap:16px}
#yt-overlay.visible{display:flex}
#yt-frame{width:min(854px,90vw);aspect-ratio:16/9;border:none;border-radius:var(--r-lg);box-shadow:0 32px 100px rgba(0,0,0,.7)}
#yt-close{background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.2);color:#fff;border-radius:var(--r-md);padding:6px 18px;cursor:pointer;font-size:13px;font-family:inherit}
#yt-close:hover{background:rgba(255,255,255,.22)}

/* ── Bio-ELN plate map & dose-response ──────────────────────────────── */
.be-plate-card{border:1px solid var(--border2);border-radius:var(--r-md);padding:10px;margin-bottom:10px;background:var(--bg2)}
.be-plate-head{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.be-plate-name{flex:0 1 auto;min-width:120px}
.be-plate-dim{font-size:11px;color:var(--text3);font-family:var(--mono)}
.be-palette{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:6px}
.be-palette-lbl{font-size:11px;color:var(--text3)}
.be-role-btn{display:inline-flex;align-items:center;gap:5px;font-size:11px;padding:3px 9px;border:1px solid var(--border2);border-radius:var(--r-sm);background:var(--bg3);color:var(--text2);cursor:pointer;font-family:inherit}
.be-role-btn:hover{border-color:var(--accent)}
.be-role-btn.active{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--text);font-weight:600}
.be-role-sw{width:12px;height:12px;border-radius:3px;border:1px solid var(--border2);display:inline-block}
.be-brush-row{display:flex;align-items:center;gap:6px;margin-bottom:6px}
.be-brush-input{font-size:12px;padding:3px 7px}
.be-dilution-form,.be-paste-form{border:1px solid var(--border2);border-radius:var(--r-sm);padding:8px;margin-bottom:8px;background:var(--bg3)}
.be-dil-grid{display:flex;flex-wrap:wrap;gap:10px}
.be-dil-grid label{display:flex;flex-direction:column;gap:2px;font-size:10px;color:var(--text3)}
.be-dil-grid .form-input{font-size:12px;padding:3px 6px}
.be-plate-grid-wrap{overflow-x:auto;margin-bottom:8px}
.be-plate-grid{border-collapse:separate;border-spacing:2px}
.be-plate-grid th{font-size:9px;color:var(--text3);font-weight:600;font-family:var(--mono);text-align:center;padding:0 2px}
.be-plate-grid .be-row-h{padding-right:4px}
.be-cond-row th{border:none;padding:0 2px 4px;height:15px;font-family:var(--sans)}
/* The bracket border/ticks live on the <th> itself (.be-cond-th below),
   not on a percentage-height/width child span — an earlier version tried
   height:100% on the inner span to make a row bracket reach from its first
   row to its last, which worked in Chromium but not Safari/WebKit: a
   percentage height inside a table cell is only reliably resolvable in
   some browsers, and WebKit instead resolved it against something far
   larger than the actual cell, stretching the bracket hundreds of pixels
   past where it should've ended. A border always hugs the real edges of
   its own box no matter how that box's size was arrived at — a <th>,
   rowspan or not, always has a genuine, definite height/width for that
   purpose — so it can't misrender this way regardless of browser. */
th.be-cond-th{position:relative;border-bottom:1.5px solid var(--cond-color,var(--accent))}
th.be-cond-th::before,th.be-cond-th::after{content:'';position:absolute;bottom:-1px;width:1.5px;height:5px;background:var(--cond-color,var(--accent))}
th.be-cond-th::before{left:0}
th.be-cond-th::after{right:0}
.be-cond-seg{font-size:9px;font-weight:600;color:var(--text2);white-space:nowrap;padding:0 2px 3px}
.be-cond-x{cursor:pointer;color:var(--text3);margin-left:3px}
.be-cond-x:hover{color:var(--red)}
/* Row-axis condition bracket — same idea, rotated: a right-hand border
   instead of a bottom one, tick marks at top/bottom instead of left/right,
   vertical text since the cell is narrow. Overrides .be-cond-th's
   bottom-border rules (source order, equal specificity). */
th.be-cond-th-row{border-bottom:none;border-right:1.5px solid var(--cond-color,var(--accent));vertical-align:middle}
th.be-cond-th-row::before,th.be-cond-th-row::after{left:auto;right:-1px;bottom:auto;width:5px;height:1.5px}
th.be-cond-th-row::before{top:0}
th.be-cond-th-row::after{bottom:0}
.be-cond-seg-row{writing-mode:vertical-rl;text-orientation:mixed;padding:3px 0}
.be-cond-seg-row .be-cond-x{margin-left:0;margin-top:3px}
.be-cond-form{display:flex;flex-wrap:wrap;gap:8px;align-items:flex-end;border:1px solid var(--border2);border-radius:var(--r-sm);padding:8px;margin-bottom:8px;background:var(--bg3)}
.be-cond-form label{display:flex;flex-direction:column;gap:2px;font-size:10px;color:var(--text3)}
.be-cond-form .form-input{font-size:12px;padding:3px 6px}
.be-well-combo{outline:1.5px dashed var(--text3);outline-offset:-1px}
.be-well{width:34px;height:34px;min-width:34px;border:1px solid var(--border2);border-radius:4px;text-align:center;vertical-align:middle;cursor:pointer;padding:0;position:relative;user-select:none;line-height:1.05;transition:box-shadow .08s}
.be-well:hover{box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 45%,transparent)}
.be-well-lbl{display:block;font-size:9px;font-weight:700;color:var(--text);font-family:var(--mono)}
.be-well-conc{display:block;font-size:8px;color:var(--text2);font-family:var(--mono)}
.be-well-read{display:block;font-size:8px;color:var(--text3);font-family:var(--mono)}
.be-plate-tools{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.be-tool-lbl{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text3)}
.be-zprime{font-size:12px;font-weight:600;font-family:var(--mono);color:var(--text3);padding:2px 8px;border-radius:var(--r-sm);border:1px solid var(--border2)}
.be-zprime.be-z-good{color:var(--green);border-color:color-mix(in srgb,var(--green) 45%,transparent);background:color-mix(in srgb,var(--green) 10%,transparent)}
.be-zprime.be-z-ok{color:var(--warn-text,#a86a00);border-color:color-mix(in srgb,var(--warn-border,#e0a000) 45%,transparent);background:color-mix(in srgb,var(--warn-border,#e0a000) 10%,transparent)}
.be-zprime.be-z-bad{color:var(--red);border-color:color-mix(in srgb,var(--red) 45%,transparent);background:color-mix(in srgb,var(--red) 10%,transparent)}
.be-curves{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:8px}
.be-curve-card{border:1px solid var(--border2);border-radius:var(--r-sm);padding:6px 8px;background:var(--bg3)}
.be-curve-head{display:flex;align-items:center;gap:6px;margin-bottom:2px;flex-wrap:wrap}
.be-curve-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
.be-curve-name{font-size:12px;font-weight:600;color:var(--text);font-family:var(--mono)}
.be-curve-fit{font-size:10px;color:var(--text3);font-family:var(--mono)}
.be-curve-card.be-curve-lowconf{border-color:color-mix(in srgb,var(--red) 45%,var(--border2))}
.be-curve-flag{font-size:9px;font-weight:600;color:var(--red);background:color-mix(in srgb,var(--red) 12%,transparent);border-radius:var(--r-xs);padding:1px 6px;flex-shrink:0}
.be-curve-plot{width:100%;min-height:190px}
.be-well-sel{box-shadow:inset 0 0 0 2px var(--accent)}
.be-selbar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:8px;padding:6px 8px;border:1px solid var(--accent);border-radius:var(--r-sm);background:color-mix(in srgb,var(--accent) 8%,transparent)}
.be-sel-count{font-size:11px;font-weight:600;color:var(--text)}
.be-fmt-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:12px}
.be-fmt-card{display:flex;flex-direction:column;align-items:center;gap:3px;padding:10px 8px;border:1px solid var(--border2);border-radius:var(--r-md);background:var(--bg2);cursor:pointer;font-family:inherit;transition:border-color .1s,transform .06s}
.be-fmt-card:hover{border-color:var(--accent);transform:translateY(-1px)}
.be-fmt-thumb{width:100%;aspect-ratio:3/2;border:1px solid var(--border2);border-radius:var(--r-sm);background:var(--bg3);color:var(--accent);display:flex;align-items:center;justify-content:center;overflow:hidden}
.be-fmt-name{font-size:13px;font-weight:600;color:var(--text)}
.be-fmt-sub{font-size:11px;color:var(--text3);font-family:var(--mono)}
.be-fmt-custom{display:flex;align-items:center;gap:8px;padding-top:10px;border-top:1px solid var(--border)}
.be-fmt-custom .form-input{font-size:12px;padding:3px 6px}
.be-fmt-custom-preview{width:36px;height:24px;flex-shrink:0;border:1px solid var(--border2);border-radius:4px;background:var(--bg3);color:var(--accent);display:flex;align-items:center;justify-content:center;overflow:hidden}

/* D2B — plate-based combinatorial screening */
.d2b-reagent-cols{display:flex;flex-direction:column;gap:14px}
.d2b-reagent-col{border:1px solid var(--border2);border-radius:var(--r-md);padding:10px;background:var(--bg2)}
.d2b-reagent-col-head{font-size:11px;font-weight:600;color:var(--text2);margin-bottom:6px;display:flex;align-items:center;gap:6px}
.d2b-reagent-col-name{font-size:11px;font-weight:600;color:var(--text2);background:none;border:none;border-bottom:1px solid transparent;padding:1px 2px;min-width:40px;flex:0 1 auto}
.d2b-reagent-col-name:hover,.d2b-reagent-col-name:focus{border-bottom-color:var(--border2);outline:none}
.d2b-reagent-col-del{background:none;border:none;color:var(--text3);cursor:pointer;font-size:11px;padding:0;margin-left:auto}
.d2b-reagent-col-del:hover{color:var(--red)}
.d2b-reagent-col-reacts{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--text3);margin-bottom:6px;cursor:pointer}
.d2b-reagent-col-reacts input{width:12px;height:12px;cursor:pointer}
.d2b-reagent-list{display:flex;flex-direction:column;gap:5px;margin-bottom:6px}
.d2b-reagent-row{display:flex;align-items:center;gap:6px;padding:5px 6px;border:1px solid var(--border2);border-radius:var(--r-sm);background:var(--bg2);transition:border-color .12s,box-shadow .12s,background .12s}
.d2b-reagent-row.hl{border-color:var(--accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 35%,transparent);background:color-mix(in srgb,var(--accent) 6%,transparent)}
.d2b-reagent-row.assignable .d2b-reagent-thumb{border-color:var(--accent);box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 30%,transparent)}
.d2b-reagent-thumb{width:30px;height:26px;flex-shrink:0;border:1px solid var(--border2);border-radius:4px;background:var(--bg3);display:flex;align-items:center;justify-content:center;cursor:pointer;overflow:hidden}
.d2b-well-reagent-chip{width:36px;height:30px;flex-shrink:0;border:1.5px solid var(--border2);border-radius:var(--r-sm);background:var(--bg3);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;overflow:hidden;padding:0;font-size:9px;color:var(--text2)}
.d2b-well-reagent-chip:hover{border-color:var(--accent)}
.d2b-well-reagent-chip.active{border-color:var(--accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 35%,transparent)}
.d2b-well-reagent-chip.clear{background:var(--bg3);color:var(--text3);border-style:dashed}
.d2b-reagent-thumb svg{max-width:26px;max-height:22px}
.d2b-reagent-thumb-plus{font-size:13px;color:var(--text3);opacity:.5}
.d2b-reagent-input{background:none;border:none;border-bottom:1px solid transparent;color:var(--text);font-size:11px;padding:2px 3px;outline:none;min-width:0}
.d2b-reagent-input:hover,.d2b-reagent-input:focus{border-bottom-color:var(--border2)}
.d2b-reagent-input.d2b-ri-cas{width:64px;flex-shrink:0}
.d2b-reagent-input.d2b-ri-equiv,.d2b-reagent-input.d2b-ri-conc,.d2b-reagent-input.d2b-ri-unit{width:38px;flex-shrink:0}
.d2b-reagent-input.d2b-ri-solvent{width:52px;flex-shrink:0}
.d2b-reagent-del{background:none;border:none;color:var(--text3);cursor:pointer;font-size:12px;padding:2px 3px;flex-shrink:0}
.d2b-reagent-del:hover{color:var(--red)}
.d2b-reagent-id{flex:1 1 auto;min-width:60px;position:relative}
.d2b-reagent-name{font-size:11px;color:var(--text);display:flex;align-items:center;gap:5px;overflow:hidden}
.d2b-reagent-name-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.d2b-reagent-tag{font-size:9px;font-weight:600;padding:1px 5px;border-radius:var(--r-lg);flex-shrink:0;text-transform:uppercase;letter-spacing:.02em}
.d2b-reagent-tag.db{background:color-mix(in srgb,var(--accent) 14%,transparent);color:var(--accent)}
.d2b-reagent-tag.ci{background:color-mix(in srgb,var(--orange) 14%,transparent);color:var(--orange)}
.d2b-reagent-unlink{background:none;border:none;color:var(--text3);cursor:pointer;font-size:10px;padding:0;flex-shrink:0}
.d2b-reagent-edit{background:none;border:none;color:var(--text3);cursor:pointer;font-size:10px;padding:0;flex-shrink:0;text-decoration:underline}
.d2b-reagent-edit:hover{color:var(--accent)}
/* Reusable "N selected" toolbar for a plain checkbox list (as opposed to
   the grid-cell selection .d2b-select-bar/.be-selbar are for) — same visual
   language, promoted out of what used to be one-off inline styles on the
   Print Labels modal. */
.list-selbar{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text2);background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-sm);padding:6px 10px;margin:0 12px 8px}
.list-sel-count{font-weight:600;color:var(--text)}
.list-selbar .btn{margin-left:auto}
.list-selbar .btn+.btn{margin-left:0}
.eln-card.list-sel-mode{padding-left:34px}
.eln-card .list-sel-check{position:absolute;left:10px;top:12px;width:15px;height:15px;cursor:pointer}
.d2b-select-bar{display:none;align-items:center;gap:8px;font-size:12px;color:var(--text2);background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-sm);padding:6px 10px;margin:6px 0}
.d2b-select-bar select{background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-sm);padding:3px 6px;font-size:11px;color:var(--text)}
.d2b-well-selected{outline:2px solid var(--accent);outline-offset:-2px}
.d2b-plate-grid.selecting .d2b-well{cursor:cell}
.d2b-plate-grid.selecting .be-row-h,.d2b-plate-grid.selecting .be-col-h{cursor:cell}
.d2b-reagent-unlink:hover{color:var(--red)}
.d2b-reagent-search-btn{background:none;border:1px dashed var(--border2);border-radius:var(--r-xs);color:var(--text3);font-size:11px;padding:2px 7px;cursor:pointer;white-space:nowrap}
.d2b-reagent-search-btn:hover{border-color:var(--accent);color:var(--accent)}
.d2b-plate-card{border:1px solid var(--border2);border-radius:var(--r-md);padding:10px 12px;margin-bottom:12px;background:var(--bg2)}
.d2b-plate-card-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:6px}
.d2b-view-toggle-label{font-size:11px;color:var(--text3);flex-shrink:0}
.d2b-scheme-label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text3);margin-bottom:8px}
.d2b-view-toggle{display:flex;align-items:center;gap:4px;flex-shrink:0;overflow-x:auto;max-width:100%}
.d2b-view-btn{flex-shrink:0;white-space:nowrap;background:var(--bg2);border:1px solid var(--border2);color:var(--text2);font-size:11px;font-weight:600;padding:4px 11px;border-radius:999px;cursor:pointer;transition:background .12s,color .12s,border-color .12s}
.d2b-view-btn:hover{border-color:var(--accent);color:var(--text)}
.d2b-view-btn.active{background:var(--accent);border-color:var(--accent);color:#fff}
.d2b-plate-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin:6px 0}
.d2b-plate-row-lbl{font-size:11px;color:var(--text3);flex-shrink:0}
/* Generic bordered icon-only button (hover text via title=) — introduced for
   the D2B plate toolbar, then adopted app-wide for any row/card action bar
   that was leaning on several text buttons in a line. */
.icon-btn{width:26px;height:26px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--border2);border-radius:var(--r-sm);background:var(--bg2);color:var(--text2);cursor:pointer;transition:border-color .12s,color .12s,background .12s}
.icon-btn:hover{border-color:var(--accent);color:var(--accent)}
.icon-btn.active{background:var(--accent);border-color:var(--accent);color:#fff}
.icon-btn.danger:hover{border-color:var(--red);color:var(--red)}
.icon-btn:disabled{opacity:.35;cursor:default;border-color:var(--border2);color:var(--text3);background:var(--bg2)}
.icon-btn-sm{width:22px;height:22px}
.icon-btn-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
/* Flat modifier — no border/background at rest, for dense inline rows
   (Dissemination cards, file lists) where a bordered box per action reads
   as cluttered; only the icon shows until hovered. */
.icon-btn-flat{border-color:transparent;background:transparent}
.icon-btn-flat:hover{background:var(--bg3);border-color:transparent}
.cv-seq-res{cursor:pointer;border-radius:2px}
.cv-seq-res:hover{background:var(--accent);color:#fff}
.cv-prep-progress-bar{height:100%;width:35%;border-radius:3px;background:var(--accent);animation:cv-progress-slide 1.1s ease-in-out infinite}
@keyframes cv-progress-slide{0%{margin-left:0%}50%{margin-left:65%}100%{margin-left:0%}}
.cv-dd{position:relative;display:inline-block}
.cv-dd-btn{display:flex;align-items:center;gap:5px;white-space:nowrap}
.cv-dd-btn svg{flex-shrink:0;opacity:.6}
.cv-dd-menu{display:none;position:absolute;top:calc(100% + 4px);left:0;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);box-shadow:var(--shadow-md);z-index:50;min-width:150px;overflow:hidden;padding:3px}
.cv-dd-menu.show{display:block}
.cv-dd-menu button{display:block;width:100%;text-align:left;padding:6px 10px;font-size:12px;background:none;border:none;cursor:pointer;color:var(--text);border-radius:var(--r-sm)}
.cv-dd-menu button:hover{background:var(--bg3)}
.cv-dd-menu button.active{color:var(--accent);font-weight:600}
.cv-dd-sep:not(:empty){border-top:1px solid var(--border);margin-top:3px;padding-top:3px}
.cv-dd-row{display:flex;align-items:center;gap:2px}
.cv-dd-row button:first-child{flex:1}
/* NMR-subtype multi-select popover (core.js nmrSubtypePickerHtml) — same
   visual language as .cv-dd-menu, own class since it's not Computational-
   viewer-specific (used by the ELN attach toolbar and Library file rows). */
.nmr-subtype-dd{position:relative;display:inline-block}
.nmr-subtype-dd-menu{display:none;position:absolute;top:calc(100% + 4px);left:0;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);box-shadow:var(--shadow-md);z-index:50;min-width:110px;padding:6px 10px;flex-direction:column;gap:5px}
.nmr-subtype-dd-menu.show{display:flex}
.nmr-subtype-dd-menu label{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--text2);cursor:pointer;white-space:nowrap}
.nmr-subtype-dd-menu input[type="checkbox"]{accent-color:var(--accent)}
.cv-dd-row-x{width:22px!important;flex-shrink:0;text-align:center!important;color:var(--text3)}
.cv-dd-row-x:hover{color:var(--red)!important;background:var(--bg3)}
.cv-search-group-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.02em;color:var(--text3);padding:8px 10px 4px}
.cv-search-row{display:flex;align-items:center;gap:8px;padding:6px 10px;cursor:pointer;border-bottom:1px solid var(--border)}
.cv-search-row:hover{background:var(--bg3)}
.d2b-well-enum-badge{position:absolute;top:2px;right:2px;font-size:9px;font-weight:700;padding:1px 4px;border-radius:999px;line-height:1.4}
.d2b-well-enum-badge.generated{background:var(--chip-green-bg);color:var(--chip-green-fg)}
.d2b-well-enum-badge.ambiguous{background:var(--chip-yellow-bg,rgba(202,138,4,.15));color:var(--chip-yellow-fg,#ca8a04)}
.d2b-well-enum-badge.no_match{background:var(--chip-red-bg);color:var(--chip-red-fg)}
.d2b-well-enum-badge.incomplete{background:var(--bg3);color:var(--text3)}
.d2b-plate-name-input{font-size:13px;font-weight:600;background:none;border:none;border-bottom:1px solid transparent;color:var(--text);padding:1px 2px;min-width:80px}
.d2b-plate-name-input:hover,.d2b-plate-name-input:focus{border-bottom-color:var(--border2);outline:none}
.d2b-plate-grid-wrap{overflow-x:auto;margin-bottom:4px}
.d2b-plate-grid{border-collapse:separate;border-spacing:3px}
.d2b-plate-grid th{font-size:9px;color:var(--text3);font-weight:600;font-family:var(--mono);text-align:center;padding:2px;border-radius:4px;transition:background .1s,color .1s}
.d2b-plate-grid .be-row-h{padding-right:4px}
.d2b-well{width:64px;height:64px;min-width:64px;border:1px solid var(--border2);border-radius:6px;text-align:center;vertical-align:middle;cursor:pointer;padding:2px;position:relative;user-select:none;background:var(--bg2);transition:box-shadow .08s,border-color .08s}
.d2b-well *{pointer-events:none;-webkit-user-drag:none;user-drag:none}
.d2b-well:hover{border-color:var(--accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 35%,transparent)}
.d2b-well.has-struct{background:var(--bg3)}
.d2b-well-code{position:absolute;top:2px;left:3px;font-size:8px;font-weight:700;color:var(--text3);font-family:var(--mono)}
.d2b-well-struct{display:flex;align-items:center;justify-content:center;width:100%;height:100%}
.d2b-well-struct svg{max-width:56px;max-height:36px}
.d2b-well-plus{font-size:18px;color:var(--text3);opacity:.35;font-weight:400}
.d2b-well-label{position:absolute;bottom:14px;left:0;right:0;font-size:8px;color:var(--text2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 4px}
.d2b-well-yield{position:absolute;bottom:2px;left:0;right:0;font-size:9px;font-weight:700;color:var(--accent);font-family:var(--mono)}
/* Reagent A/B and Yield well-views: a colored chip fills the well instead of a structure thumbnail */
.d2b-well-chip{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;border-radius:4px;gap:2px;background:var(--bg3)}
.d2b-well-chip-label{font-size:9px;font-weight:600;color:var(--text);max-width:56px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.d2b-well-chip-sub{font-size:8px;color:var(--text3);font-family:var(--mono);max-width:58px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.d2b-well-chip-struct{display:flex;align-items:center;justify-content:center;max-width:100%;max-height:32px}
.d2b-well-chip-struct svg{max-width:44px;max-height:30px}
.d2b-well-yield-big{font-size:15px;font-weight:700;font-family:var(--mono);color:var(--text)}

/* ══ Projects module ═══════════════════════════════════════════════════════
   Own namespace (.pj-*) rather than borrowing .eln-list/.eln-card: the project
   sidebar carries a progress ring, an accent band and an avatar stack that the
   ELN list has no use for, and sharing the classes made both hard to change. */
.pj-layout{display:flex;flex:1;overflow:hidden;min-height:0}

/* ── Sidebar ── */
#proj-sidebar.collapsed .pj-sb-head>:not(.sidebar-toggle-btn),#proj-sidebar.collapsed .pj-sb-filters,#proj-sidebar.collapsed .pj-sb-body,#proj-sidebar.collapsed .pj-dashboard-row{display:none!important}
#proj-sidebar.collapsed .pj-sb-head{width:100%;padding:12px 0 10px;justify-content:center}
.pj-sb-head .btn-primary{flex:1}
.pj-sb-filters{padding:9px 12px;border-bottom:1px solid var(--border);display:flex;flex-direction:column;gap:7px}
.pj-scope{display:flex;background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-sm);padding:2px;gap:2px}
.pj-scope-btn{flex:1;background:none;border:none;color:var(--text3);font-size:11px;font-weight:600;padding:4px 0;border-radius:calc(var(--r-sm) - 2px);cursor:pointer;transition:background .12s,color .12s}
.pj-scope-btn:hover{color:var(--text2)}
.pj-scope-btn.active{background:var(--bg2);color:var(--text);box-shadow:var(--shadow-sm)}
/* Boxes/Plates keeps the pill highlight on .active but stays gray text/icon
   rather than the usual dark --text — a deliberate one-off, not a change
   to the shared Mine/All-style toggle look used elsewhere. */
#storage-subtab-boxes.active,#storage-subtab-plates.active{color:var(--text3)}
/* Pinned "Dashboard" row — not a project card, always present above the list */
.pj-dashboard-row{display:flex;align-items:center;gap:8px;width:calc(100% - 16px);margin:6px 8px 2px;padding:8px 10px;
  background:none;border:1px solid transparent;border-radius:var(--r-md);color:var(--text2);font-size:13px;font-weight:600;cursor:pointer;transition:background .12s,border-color .12s}
.pj-dashboard-row:hover{background:var(--bg3)}
.pj-dashboard-row.active{background:color-mix(in srgb,var(--accent) 9%,transparent);border-color:color-mix(in srgb,var(--accent) 26%,transparent);color:var(--text)}
.pj-sb-body{flex:1;overflow-y:auto;padding:8px 8px 20px}

/* Collapsible status group */
.pj-group+.pj-group{margin-top:10px}
.pj-group-head{display:flex;align-items:center;gap:6px;width:100%;background:none;border:none;padding:4px 6px;cursor:pointer;color:var(--text3);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em}
.pj-group-head:hover{color:var(--text2)}
.pj-group-chev{transition:transform .15s;flex-shrink:0}
.pj-group.collapsed .pj-group-chev{transform:rotate(-90deg)}
.pj-group-count{margin-left:auto;font-family:var(--mono);font-weight:600;font-size:10px;opacity:.75}
.pj-group.collapsed .pj-group-body{display:none}
/* Parent-project sub-grouping inside a status section. Deliberately quieter
   than the status heading above it (sentence case, no letter-spacing) so the
   sidebar reads as one list with dividers, not two competing hierarchies. */
.pj-subgroup+.pj-subgroup{margin-top:6px}
/* "Ungrouped" is everything else, not another programme — detached with a
   rule and extra air so the last real group doesn't look like it owns it. */
.pj-subgroup.loose{margin-top:12px;padding-top:8px;border-top:1px dashed var(--border)}
.pj-subgroup.loose .pj-subgroup-head{font-style:italic;opacity:.85}
.pj-subgroup-row{display:flex;align-items:center}
.pj-subgroup-row .pj-subgroup-head{flex:1;min-width:0}
.pj-subgroup-edit{flex-shrink:0;background:none;border:none;padding:2px 6px;cursor:pointer;color:var(--text3);opacity:0;transition:opacity .12s;display:flex;align-items:center}
.pj-subgroup-row:hover .pj-subgroup-edit,.pj-subgroup-edit:focus-visible{opacity:1}
.pj-subgroup-edit:hover{color:var(--text)}
.pp-swatch{width:22px;height:22px;border-radius:var(--r-sm);border:2px solid transparent;cursor:pointer;padding:0}
.pp-swatch.active{border-color:var(--text);box-shadow:0 0 0 1px var(--bg)}
.pj-subgroup-head{display:flex;align-items:center;gap:5px;width:100%;background:none;border:none;padding:3px 6px 3px 10px;cursor:pointer;color:var(--text3);font-size:11px;font-weight:600}
.pj-subgroup-head:hover{color:var(--text2)}
.pj-subgroup .pj-group-chev{transition:transform .15s;flex-shrink:0}
.pj-subgroup.collapsed .pj-group-chev{transform:rotate(-90deg)}
.pj-subgroup.collapsed .pj-subgroup-body{display:none}
.pj-subgroup-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}

/* Project card */
.pj-card{position:relative;display:flex;gap:9px;align-items:flex-start;padding:6px 10px;margin-bottom:2px;border-radius:var(--r-md);border:1px solid transparent;cursor:pointer;overflow:hidden;transition:background .12s,border-color .12s}
.pj-card:hover{background:var(--bg3)}
/* Not a member: listed but not openable — dimmed, no hover invitation */
.pj-card.locked{opacity:.5;cursor:not-allowed}
.pj-req-btn{display:inline-flex;margin-top:6px;padding:2px 9px;font-size:11px;font-weight:600;border:1px solid var(--accent);color:var(--accent);background:none;border-radius:var(--r-xs);cursor:pointer}
.pj-req-btn:hover{background:color-mix(in srgb, var(--accent) 10%, transparent)}
.pj-req-sent{display:inline-flex;align-items:center;gap:4px;margin-top:6px;font-size:11px;color:var(--text3)}
.pj-req-sent svg{width:11px;height:11px}
.pj-card.locked:hover{background:none}
.pj-card.active{background:color-mix(in srgb,var(--accent) 9%,transparent);border-color:color-mix(in srgb,var(--accent) 26%,transparent)}
.pj-card-main{flex:1;min-width:0}
.pj-card-title{font-size:13px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:5px}
.pj-card-meta{font-size:11px;color:var(--text3);margin-top:3px;font-family:var(--mono);display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.pj-card-meta b{font-weight:600;color:var(--text2)}
.pj-lock{display:inline-flex;align-items:center;color:var(--text3);flex-shrink:0}

/* Progress ring */
.pj-ring{flex-shrink:0;position:relative;width:30px;height:30px}
.pj-ring svg{transform:rotate(-90deg);display:block}
.pj-ring-track{stroke:var(--bg3)}
.pj-ring-bar{stroke:var(--accent);transition:stroke-dashoffset .3s}
.pj-ring-label{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;font-family:var(--mono);color:var(--text2)}

/* Overlapping avatar stack */
.pj-stack{display:flex;align-items:center;margin-top:6px}
.pj-stack .pj-av{margin-left:-5px;border:1.5px solid var(--bg2)}
.pj-stack .pj-av:first-child{margin-left:0}
.pj-card.active .pj-stack .pj-av{border-color:color-mix(in srgb,var(--accent) 9%,var(--bg2))}
.pj-av{width:19px;height:19px;border-radius:999px;color:#fff;font-size:8px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;letter-spacing:-.2px;box-sizing:border-box;overflow:hidden}
.pj-av img{width:100%;height:100%;object-fit:cover}
.pj-av-more{background:var(--bg3);color:var(--text3);font-family:var(--mono)}

/* ── Detail pane ── */
.pj-detail{flex:1;overflow-y:auto;display:flex;flex-direction:column;min-width:0}
.pj-empty{flex:1;display:flex;align-items:center;justify-content:center;color:var(--text3);font-size:13px;flex-direction:column;gap:8px}

/* ── Dashboard panel (pinned sidebar entry, not a real project) ── */
.pj-dashboard{padding:20px 26px 26px;max-width:1180px}
.pj-dashboard-head h2{margin:0 0 4px;font-size:19px}
.pj-dashboard-sub{margin:0 0 18px;color:var(--text3);font-size:13px}
.pj-dash-mol-head{display:flex;align-items:center;gap:7px;cursor:pointer;user-select:none;padding:8px 0;margin-bottom:10px;border-bottom:1px solid var(--border)}
.pj-dash-mol-head span:first-of-type{font-size:13px;font-weight:700}
.pj-dash-mol-chev{transition:transform .12s;flex-shrink:0;color:var(--text3)}
.pj-dash-mol-chev.open{transform:rotate(90deg)}
.pj-dash-pipe .pj-pipe-body{max-height:280px}
.pj-dashboard-body{display:grid;grid-template-columns:1fr 260px;gap:24px;align-items:start}
.pj-dashboard-main{min-width:0}
.pj-dashboard-stats{display:flex;flex-direction:column;gap:14px}
#pj-dashboard-molecules:empty{display:none}
#pj-dashboard-queue+#pj-dashboard-molecules{margin-top:22px}
.pj-dash-stat-card{background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);padding:12px}
.pj-dash-stat-title{font-size:11px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px}
/* Chart.js's maintainAspectRatio:false only respects a container that already
   has a real height — without this, a canvas with no CSS height keeps
   growing (especially a bar chart with several categories). */
.pj-dash-chart-wrap{position:relative;height:110px}
.pj-dash-chart-wrap-donut{height:150px;max-width:180px;margin:0 auto}
.pj-dash-chart-empty{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text3);font-size:12px;text-align:center}
/* Heatmap + Recent activity side by side — the heatmap hugs its own content
   width (a fixed year-long grid, no reason to stretch it) while Recent
   activity takes whatever's left, so the row actually fills out instead of
   leaving the heatmap alone with dead space beside it. Stacks on narrow
   viewports, same breakpoint as .pj-dashboard-body's own column collapse. */
.pj-dash-activity-row{display:flex;gap:14px;margin-top:14px;align-items:stretch}
@media (max-width:900px){.pj-dash-activity-row{flex-direction:column}}
.pj-dash-recent-card{flex:1;min-width:0;overflow-y:auto;max-height:340px}
/* Activity heatmap — GitHub-style contribution calendar, one .pj-heat-col
   per week (7 stacked .pj-heat-cell days), horizontally scrollable so a
   full year still fits on a narrower window without squeezing the cells. */
.pj-dash-heatmap-card{width:fit-content;max-width:100%;min-width:0;overflow-x:auto}
.pj-heat-total{font-size:12px;color:var(--text3);margin-bottom:8px}
.pj-heat-grid{display:flex;gap:3px;width:max-content}
.pj-heat-col{display:flex;flex-direction:column;gap:3px}
.pj-heat-month{font-size:9px;color:var(--text3);height:12px;white-space:nowrap}
.pj-heat-days{display:flex;flex-direction:column;gap:3px}
.pj-heat-cell{width:10px;height:10px;border-radius:2px;background:var(--bg3)}
.pj-heat-cell.pj-heat-empty{background:transparent}
.pj-heat-cell[data-level="1"]{background:color-mix(in srgb,var(--green) 25%,var(--bg3))}
.pj-heat-cell[data-level="2"]{background:color-mix(in srgb,var(--green) 50%,var(--bg3))}
.pj-heat-cell[data-level="3"]{background:color-mix(in srgb,var(--green) 75%,var(--bg3))}
.pj-heat-cell[data-level="4"]{background:var(--green)}
.pj-heat-scale{display:flex;align-items:center;gap:3px;margin-top:8px;font-size:10px;color:var(--text3)}
.pj-dash-kanban-head{margin:0 0 8px;display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.pj-dash-kanban-head>span{font-size:11px;font-weight:700;color:var(--text3);text-transform:uppercase;letter-spacing:.05em}
.pj-dash-kanban-head .pj-scope{width:auto}
.pj-dash-kanban-head .pj-scope-btn{padding:4px 12px}
.pj-dash-tag{display:inline-block;margin-top:4px;padding:1px 7px;border-radius:var(--r-sm);font-size:10px;font-weight:600}
@media (max-width:900px){.pj-dashboard-body{grid-template-columns:1fr}}

.pj-hero{padding:20px 26px 0;border-bottom:1px solid var(--border);position:relative}
.pj-hero::before{content:'';position:absolute;left:0;right:0;top:0;height:2px;background:var(--accent)}
.pj-hero-top{display:flex;align-items:flex-start;gap:14px}
.pj-hero-title{margin:0;font-size:21px;font-weight:700;letter-spacing:-.01em;display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.pj-badge{font-size:10px;font-family:var(--mono);font-weight:600;color:var(--text3);background:var(--bg3);border:1px solid var(--border);border-radius:var(--r-xs);padding:1px 5px;text-transform:uppercase;letter-spacing:.04em}
.pj-hero-desc{font-size:13px;color:var(--text2);margin-top:7px;line-height:1.55;max-width:70ch}
.pj-hero-links{display:flex;align-items:center;gap:14px;margin-top:9px;flex-wrap:wrap}
.pj-hero-link{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--accent);text-decoration:none}
.pj-hero-link:hover{text-decoration:underline}
.pj-hero-actions{display:flex;gap:6px;flex-shrink:0}

/* Metric strip under the hero title — a bordered card row, not raw floating numbers */
.pj-metrics{display:flex;margin-top:15px;width:fit-content;border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden;background:var(--bg2)}
.pj-metric{background:none;border:none;border-right:1px solid var(--border);padding:8px 18px;text-align:left;cursor:pointer;font:inherit;transition:background .1s}
.pj-metric:last-child{border-right:none}
.pj-metric:hover{background:var(--bg3)}
.pj-metric-n{font-size:17px;font-weight:600;font-family:var(--mono);color:var(--text);line-height:1.15}
.pj-metric-l{font-size:10px;color:var(--text3);text-transform:uppercase;letter-spacing:.05em;margin-top:2px}
.pj-metric:hover .pj-metric-n{color:var(--accent)}

.pj-tabbar{display:flex;gap:2px;margin-top:16px;overflow-x:auto;scrollbar-width:none}
/* Inside the workspace the underline tabs take the project's own accent */
.pj-tabbar .subtab--tab.active{border-bottom-color:var(--accent)}
.pj-tabbar::-webkit-scrollbar{display:none}
.pj-panel{padding:22px 26px 40px;max-width:1180px}

/* ── Pipeline board (Design → Make → Test → Analyse) ── */
/* Stacked Molecules + Tasks board */
.pj-board-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.pj-board-heading{margin:0;font-size:14px;font-weight:700;letter-spacing:-.01em}
.pj-board-split{height:1px;background:var(--border);margin:52px 0 34px}

/* Reaction scheme expanded inline under a row in Projects > Chemistry */
.pj-chem-scheme{display:flex;align-items:center;gap:12px;padding:10px 12px;background:var(--bg2);border-top:1px solid var(--border)}
.pj-chem-canvas{flex:1;min-width:0;min-height:78px;display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;background:var(--bg3);border-radius:var(--r-sm);padding:8px;overflow-x:auto}
.pj-chem-canvas img{max-height:70px;width:auto}

/* Inline task editing — the card expands in place instead of a form at the top */
.proj-task-card.editing{cursor:default;box-shadow:0 0 0 2px var(--accent),var(--shadow-md);background:var(--bg2)}
.proj-task-edit{display:flex;flex-direction:column;gap:6px}
.proj-task-edit .form-input{font-size:12px;padding:4px 6px;width:100%}
.proj-task-edit-row{display:flex;gap:5px;flex-wrap:wrap}
.proj-task-edit-row .form-input{flex:1;min-width:88px}
.proj-task-edit textarea.form-input{resize:vertical;font:inherit;font-size:12px}
.proj-task-edit-actions{display:flex;align-items:center;gap:6px;margin-top:2px}
.pj-pipe{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}
.pj-pipe-col{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-lg);display:flex;flex-direction:column;min-height:120px;overflow:hidden}
.pj-pipe-head{display:flex;align-items:center;gap:6px;padding:9px 11px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text2);border-bottom:1px solid var(--border);background:var(--bg3);cursor:pointer;user-select:none}
.pj-pipe-head .n{margin-left:auto;font-family:var(--mono);color:var(--text3);font-weight:600}
.pj-pipe-chev{transition:transform .12s;flex-shrink:0;color:var(--text3)}
.pj-pipe-col.collapsed .pj-pipe-chev{transform:rotate(-90deg)}
.pj-pipe-col.collapsed .pj-pipe-head{border-bottom:none}
.pj-pipe-col.collapsed .pj-pipe-body{display:none}
.pj-pipe-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.pj-pipe-col[data-stage="designed"]    .pj-pipe-dot{background:var(--text3)}
.pj-pipe-col[data-stage="synthesized"] .pj-pipe-dot{background:var(--chip-blue-fg,#5b7fa6)}
.pj-pipe-col[data-stage="tested"]      .pj-pipe-dot{background:var(--chip-purple-fg,#a06ab4)}
.pj-pipe-col[data-stage="evaluated"]   .pj-pipe-dot{background:var(--green)}
.pj-pipe-body{padding:8px;display:flex;flex-direction:column;gap:6px;overflow-y:auto;max-height:60vh}
.pj-pipe-empty{border:1px dashed var(--border2);border-radius:var(--r-md);padding:14px 6px;text-align:center;color:var(--text3);font-size:11px}
.pj-mol{display:flex;gap:8px;align-items:center;padding:7px 8px;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-md);cursor:pointer;transition:border-color .12s,transform .1s,box-shadow .1s}
.pj-mol:hover{border-color:color-mix(in srgb,var(--accent) 40%,var(--border));transform:translateY(-1px);box-shadow:var(--shadow-sm)}
/* Someone already has an open (not-yet-completed) reaction making this
   designed molecule — a slow, low-amplitude "heartbeat" glow instead of a
   loud static color, so it reads as "in progress" without competing for
   attention against the rest of the board. */
.pj-mol--open-reaction{background:color-mix(in srgb,var(--accent) 6%,var(--bg2));border-color:color-mix(in srgb,var(--accent) 35%,var(--border));animation:pj-heartbeat 2.6s ease-in-out infinite}
@keyframes pj-heartbeat{
  0%,100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 16%,transparent)}
  50%{box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 8%,transparent)}
}
@media (prefers-reduced-motion:reduce){.pj-mol--open-reaction{animation:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 12%,transparent)}}
/* Completed in ELN but not yet registered in the Library — a done signal,
   not an in-progress one, so a static tint (no pulse) in the "synthesized"
   stage color rather than the accent used for open reactions. */
.pj-mol--completed-reaction{background:color-mix(in srgb,var(--green) 6%,var(--bg2));border-color:color-mix(in srgb,var(--green) 30%,var(--border))}
/* Expanded/grouped Molecules view — same card, more room: bigger thumbnail,
   title/sub allowed to wrap instead of ellipsis-truncating since a card here
   is a fixed-width tile, not a column-constrained kanban row. Card/thumbnail
   size is user-selectable (S/M/L, see _pjMolExpandedSize) — the JS-side pixel
   sizes fed into getSVG() live in _PJ_MOL_THUMB_PX and must stay in step with
   the thumbnail box sizes below, or the rendered SVG gets stretched/squished
   by CSS instead of drawn at its native size. */
.pj-mol--big{padding:10px;gap:10px;align-items:flex-start}
.pj-mol--big .pj-mol-title{white-space:normal}
.pj-mol--big .pj-mol-sub{white-space:normal}
.pj-mol--big.pj-mol--sm{flex:0 0 190px;width:190px}
.pj-mol--big.pj-mol--sm .pj-mol-thumb{width:72px;height:52px}
.pj-mol--big.pj-mol--md{flex:0 0 260px;width:260px}
.pj-mol--big.pj-mol--md .pj-mol-thumb{width:108px;height:78px}
.pj-mol--big.pj-mol--lg{flex:0 0 340px;width:340px}
.pj-mol--big.pj-mol--lg .pj-mol-thumb{width:156px;height:112px}
.pj-mol--big.pj-mol--xl{flex:0 0 440px;width:440px}
.pj-mol--big.pj-mol--xl .pj-mol-thumb{width:220px;height:160px}
/* Groups render as horizontal, wrapping rows of cards (left-to-right, one
   section per group) rather than side-by-side kanban columns — this view is
   for scanning/comparing structures at a glance, which a shelf of rows reads
   better for than several parallel columns each fighting for width. */
.pj-mol-expanded-rows{display:flex;flex-direction:column;gap:16px}
.pj-mol-exp-row-head{display:flex;align-items:center;gap:6px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text2);margin-bottom:8px}
.pj-mol-exp-row-body{display:flex;flex-wrap:wrap;gap:10px}
.pj-mol-thumb{width:52px;height:38px;flex-shrink:0;background:var(--bg3);border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;overflow:hidden}
.pj-mol-thumb svg{max-width:100%;max-height:100%}
.pj-mol-thumb--zoomable{cursor:pointer;position:relative}
.pj-mol-thumb--zoomable::after{content:'full size';position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,.55);color:#fff;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;
  opacity:0;transition:opacity .15s;border-radius:var(--r-xs)}
.pj-mol-thumb--zoomable:hover::after{opacity:1}
.pj-mol-body{flex:1;min-width:0}
.pj-mol-title{font-size:12px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pj-mol-sub{font-size:10px;color:var(--text3);font-family:var(--mono);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gs-result-row:hover{background:var(--bg3)}
.pj-mol-del{flex-shrink:0;opacity:0;transition:opacity .12s}
.pj-mol:hover .pj-mol-del{opacity:1}
.pj-mol.mine{border-color:color-mix(in srgb,var(--accent) 45%,var(--border));background:color-mix(in srgb,var(--accent) 6%,var(--bg2))}
.pj-mol-mine-tag{flex-shrink:0;font-size:9px;font-weight:700;color:var(--accent);background:color-mix(in srgb,var(--accent) 16%,transparent);padding:1px 6px;border-radius:var(--r-xs);text-transform:uppercase;letter-spacing:.03em}
/* Series rationale line under the series filter bar */
.pj-series-note{display:flex;align-items:baseline;gap:8px;font-size:12px;color:var(--text2);line-height:1.5;margin-bottom:12px;padding:7px 10px;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-md)}
.pj-series-note-actions{margin-left:auto;display:flex;gap:10px;flex-shrink:0;align-items:baseline}

/* Task priority + overdue badges */
.pj-prio{font-size:9px;font-weight:700;padding:1px 5px;border-radius:var(--r-xs);text-transform:uppercase;letter-spacing:.03em}
.pj-prio.high{background:var(--chip-red-bg);color:var(--chip-red-fg)}
.pj-prio.low{background:var(--bg3);color:var(--text3)}
.pj-due-over{font-size:9px;font-weight:700;color:var(--chip-red-fg);background:var(--chip-red-bg);padding:1px 5px;border-radius:var(--r-xs);font-family:var(--mono)}

/* Collapsible series groups inside pipeline columns */
.pj-series{border:1px solid var(--border);border-radius:var(--r-md);padding:4px;background:var(--bg3)}
.pj-series-head{display:flex;align-items:center;gap:5px;font-size:11px;font-weight:600;color:var(--text2);cursor:pointer;padding:2px 3px;border-radius:var(--r-xs);user-select:none}
.pj-series-head .n{margin-left:auto;font-family:var(--mono);color:var(--text3);font-weight:600}
.pj-series-chev{transition:transform .12s;flex-shrink:0}
.pj-series.collapsed .pj-series-chev{transform:rotate(-90deg)}
.pj-series.collapsed .pj-series-body{display:none}
.pj-series-body{display:flex;flex-direction:column;gap:6px;margin-top:5px}

/* Molecule pipeline — view switcher + its three visualizations */
.pj-funnel-switch{display:inline-flex;gap:2px;background:var(--bg3);border-radius:var(--r-md);padding:2px;margin:8px 0}
.pj-funnel-switch-btn{padding:3px 10px;font-size:11px;font-weight:500;color:var(--text3);background:none;border:none;border-radius:calc(var(--r-md) - 2px);cursor:pointer;transition:all .12s}
.pj-funnel-switch-btn:hover{color:var(--text2)}
.pj-funnel-switch-btn.active{background:var(--bg2);color:var(--text);box-shadow:var(--shadow-sm)}

/* Bar — original flat segmented distribution (each stage's current headcount) */
.pj-funnel{display:flex;height:9px;border-radius:99px;overflow:hidden;background:var(--bg3);margin:10px 0 7px}
.pj-funnel span{display:block;height:100%}
.pj-funnel-key{display:flex;gap:14px;flex-wrap:wrap;font-size:11px;color:var(--text3)}
.pj-funnel-key i{width:8px;height:8px;border-radius:2px;display:inline-block;margin-right:4px}

/* Timeline — per-bucket count lines, one per stage */
.pj-funnel-timeline{margin:10px 0 2px}
.pj-funnel-timeline-axis{display:flex;justify-content:space-between;font-size:10px;color:var(--text3);margin-top:2px}

/* Momentum chip — sits in the section header next to "Molecule pipeline" */
.pj-momentum{font-size:11px;font-weight:600;color:var(--green);background:color-mix(in srgb,var(--green) 14%,transparent);border-radius:99px;padding:2px 9px}

/* Goal — free-text final objective, shown as a small callout above the
   pipeline section */
.pj-goal-text{font-size:13px;color:var(--text2);line-height:1.5;margin:2px 0 12px;padding:8px 10px;background:var(--bg2);border-left:2px solid var(--accent);border-radius:var(--r-xs)}
.pj-goal-tag{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text3);margin-right:7px}

/* ── SAR matrix ── */
.pj-sar-wrap{overflow:auto;max-height:72vh;border:1px solid var(--border);border-radius:var(--r-lg);background:var(--bg2)}
.pj-sar{border-collapse:separate;border-spacing:0;font-size:12px;min-width:100%}
.pj-sar th,.pj-sar td{padding:6px 10px;border-bottom:1px solid var(--border);white-space:nowrap}
.pj-sar thead th{position:sticky;top:0;z-index:3;background:var(--bg3);font-size:10px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:.04em;text-align:left;border-bottom:1px solid var(--border2)}
.pj-sar thead th small{display:block;font-family:var(--mono);font-weight:500;text-transform:none;letter-spacing:0;color:var(--text3);font-size:10px;margin-top:1px}
.pj-sar tbody tr:hover td{background:color-mix(in srgb,var(--accent) 5%,transparent)}
.pj-sar .pj-sar-cpd{position:sticky;left:0;z-index:2;background:var(--bg2);font-family:var(--mono);font-weight:600;cursor:pointer}
.pj-sar thead .pj-sar-cpd{z-index:4;background:var(--bg3)}
.pj-sar tbody tr:hover .pj-sar-cpd{background:color-mix(in srgb,var(--accent) 8%,var(--bg2))}
.pj-sar-struct{width:74px;height:46px;background:var(--bg3);border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;overflow:hidden}
.pj-sar-struct svg{max-width:100%;max-height:100%}
.pj-sar-val{font-family:var(--mono);font-weight:600;padding:1px 6px;border-radius:var(--r-xs)}
.pj-sar-n{font-size:9px;color:var(--text3);margin-left:3px;font-family:var(--mono);font-weight:400}
.pj-sar-empty{color:var(--text3)}

/* ── Timeline ── */
.pj-time{position:relative;padding-left:22px}
.pj-time::before{content:'';position:absolute;left:5px;top:4px;bottom:4px;width:1px;background:var(--border)}
.pj-time-item{position:relative;padding:0 0 15px}
.pj-time-item::before{content:'';position:absolute;left:-20px;top:4px;width:9px;height:9px;border-radius:50%;background:var(--bg2);border:2px solid var(--border2)}
.pj-time-item[data-kind="stage"]::before,.pj-time-item[data-kind="verdict"]::before{border-color:var(--accent)}
.pj-time-item[data-kind="compound"]::before{border-color:var(--green)}
.pj-time-item[data-kind="docking"]::before{border-color:var(--text2)}
.pj-time-title{font-size:12px;color:var(--text);font-weight:500}
.pj-time-meta{font-size:11px;color:var(--text3);margin-top:2px;font-family:var(--mono)}
.pj-time-detail{font-size:11px;color:var(--text2);margin-top:3px;line-height:1.45}

/* ── Journal / comments ── */
.pj-cmt{display:flex;gap:9px;padding:11px 0;border-bottom:1px solid var(--border)}
.pj-cmt:last-child{border-bottom:none}
.pj-cmt-body{flex:1;min-width:0}
.pj-cmt-head{display:flex;align-items:baseline;gap:7px;flex-wrap:wrap}
.pj-cmt-author{font-size:12px;font-weight:600;color:var(--text)}
.pj-cmt-when{font-size:10px;color:var(--text3);font-family:var(--mono)}
.pj-cmt-text{font-size:13px;color:var(--text2);line-height:1.55;margin-top:3px;white-space:pre-wrap;word-break:break-word}
.pj-mention{color:var(--accent);font-weight:600}
.pj-cmt-actions{display:flex;gap:8px;margin-top:4px;opacity:0;transition:opacity .12s}
.pj-cmt:hover .pj-cmt-actions{opacity:1}
.pj-cmt-action{background:none;border:none;padding:0;font-size:11px;color:var(--text3);cursor:pointer}
.pj-cmt-action:hover{color:var(--accent)}
.pj-composer{display:flex;gap:9px;align-items:flex-start;margin-top:14px}
.pj-composer>div{flex:1;min-width:0;position:relative}
.pj-composer textarea{display:block;width:100%;box-sizing:border-box;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);padding:9px 11px;font:inherit;font-size:13px;color:var(--text);resize:vertical;min-height:64px;outline:none}
.pj-composer textarea:focus{border-color:color-mix(in srgb,var(--accent) 55%,transparent)}
/* @mention autocomplete under the composer */
.pj-mention-dd{position:absolute;left:0;right:0;top:100%;margin-top:2px;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);box-shadow:var(--shadow-md,0 4px 14px rgba(0,0,0,.18));z-index:60;overflow:hidden}
.pj-mention-dd button{display:flex;align-items:center;gap:7px;width:100%;text-align:left;background:none;border:none;padding:6px 10px;font-size:12px;color:var(--text);cursor:pointer}
.pj-mention-dd button:hover,.pj-mention-dd button.sel{background:var(--bg3)}
/* Comment-count bubble on molecule/task cards */
.pj-cmt-badge{display:inline-flex;align-items:center;gap:3px;font-size:10px;font-family:var(--mono);font-weight:600;color:var(--text3);flex-shrink:0}

/* ── Documents ── */
.pj-doc{display:flex;align-items:center;gap:11px;padding:10px 12px;border:1px solid var(--border);border-radius:var(--r-md);background:var(--bg2);margin-bottom:6px;transition:border-color .12s}
.pj-doc:hover{border-color:var(--border2)}
.pj-doc-icon{width:30px;height:30px;border-radius:var(--r-sm);background:var(--bg3);display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--text3)}
.pj-doc-main{flex:1;min-width:0}
.pj-doc-title{font-size:13px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pj-doc-meta{font-size:11px;color:var(--text3);font-family:var(--mono);margin-top:2px}

/* ── Team ── */
.pj-team-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:10px}
.pj-member{display:flex;gap:11px;align-items:center;padding:12px;border:1px solid var(--border);border-radius:var(--r-lg);background:var(--bg2)}
.pj-member .pj-av{width:34px;height:34px;font-size:12px}
.pj-member-name{font-size:13px;font-weight:600;color:var(--text)}
.pj-member-meta{font-size:11px;color:var(--text3);margin-top:2px}
.pj-load{height:5px;border-radius:99px;background:var(--bg3);overflow:hidden;margin-top:6px}
.pj-load span{display:block;height:100%;background:var(--accent);border-radius:99px}
/* Someone on an approved absence today: dimmed, with the reason spelled out. The
   card stays fully readable on hover so it never becomes an accessibility trap. */
.pj-member.away{opacity:.5;transition:opacity .15s}
.pj-member.away:hover{opacity:1}
.pj-away{font-size:11px;font-weight:600;color:var(--warn-fg,var(--text2));margin-top:2px}

/* Shared small pieces */
.pj-section{margin-bottom:26px}
.pj-section-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:9px}
.pj-section-title{margin:0;font-size:13px;font-weight:700;color:var(--text)}
.pj-section-collapsible>summary.pj-section-title{cursor:pointer;list-style:none;user-select:none}
.pj-section-collapsible>summary.pj-section-title::-webkit-details-marker{display:none}
.pj-section-collapsible>summary.pj-section-title::before{content:'▸';display:inline-block;margin-right:6px;font-size:10px;color:var(--text3);transition:transform .15s}
.pj-section-collapsible[open]>summary.pj-section-title::before{transform:rotate(90deg)}
.pj-card-box{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--bg2);overflow:hidden}
.pj-row{display:flex;align-items:center;gap:9px;padding:8px 12px;border-bottom:1px solid var(--border);cursor:pointer;transition:background .1s}
.pj-row:last-child{border-bottom:none}
.pj-row:hover{background:var(--bg3)}
.pj-row-id{font-family:var(--mono);font-size:11px;color:var(--text3);flex-shrink:0}
.pj-row-title{font-size:12px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text)}
.pj-row-when{font-size:11px;color:var(--text3);font-family:var(--mono);flex-shrink:0}
.pj-empty-sm{padding:16px 12px;text-align:center;color:var(--text3);font-size:12px}

@media (max-width:1100px){
  .pj-pipe{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:760px){
  .pj-pipe{grid-template-columns:1fr}
  .pj-panel{padding:16px 14px 32px}
  .pj-hero{padding:16px 14px 0}
}

/* ── Avatar picker (profile modal) ── */
.av-picker{display:flex;gap:16px;align-items:flex-start;padding:14px;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-lg);margin-bottom:14px}
.av-preview .pj-av{box-shadow:var(--shadow-sm)}
.av-picker-main{flex:1;min-width:0}
.av-tabs{display:flex;gap:2px;background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-sm);padding:2px;width:fit-content;margin-bottom:10px}
.av-tab{background:none;border:none;color:var(--text3);font-size:11px;font-weight:600;padding:4px 12px;border-radius:calc(var(--r-sm) - 2px);cursor:pointer}
.av-tab.active{background:var(--bg2);color:var(--text);box-shadow:var(--shadow-sm)}
.av-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(38px,1fr));gap:6px;margin-bottom:10px}
.av-opt{width:38px;height:38px;border-radius:var(--r-md);border:1.5px solid var(--border);background:var(--bg3);color:var(--text2);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:border-color .12s,transform .1s}
.av-opt:hover{transform:translateY(-1px);border-color:var(--border2)}
.av-opt.active{border-color:var(--accent);color:var(--accent);background:var(--accent-light)}
.av-colors{display:flex;gap:6px;flex-wrap:wrap}
.av-color{width:22px;height:22px;border-radius:999px;border:2px solid transparent;cursor:pointer;padding:0;transition:transform .1s}
.av-color:hover{transform:scale(1.12)}
.av-color.active{border-color:var(--text);box-shadow:0 0 0 2px var(--bg2) inset}

/* ── In-app back chip ── */
/* In-app history arrows, grouped so they read as one control next to the icons */
.nav-history{display:inline-flex;align-items:center;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-sm);padding:1px;margin-right:2px}
.nav-history .nav-icon-btn{width:24px;height:24px;border-radius:calc(var(--r-xs) - 1px)}
.nav-icon-btn:disabled{opacity:.32;cursor:default}
.nav-icon-btn:disabled:hover{background:none;color:var(--text2)}
@media (max-width:820px){.nav-history{display:none}}

/* ══ Similar structures (Library) ═════════════════════════════════ */
.similar-struct-card{border:1px solid var(--border);border-radius:var(--r-md);padding:8px;cursor:pointer;text-align:center;transition:border-color .15s,box-shadow .15s;background:var(--bg2)}
.similar-struct-card:hover{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-light)}
.similar-struct-svg{width:100%;height:80px;display:flex;align-items:center;justify-content:center;color:var(--text)}
.similar-struct-svg svg{max-width:100%;max-height:100%}
.similar-struct-id{font-family:var(--mono);font-size:11px;font-weight:600;margin-top:4px;color:var(--text)}
.similar-struct-formula{font-size:10px;color:var(--text3)}
.similar-struct-pct{font-size:11px;font-weight:600;color:var(--accent);margin-top:2px}

/* ══ Open relations graph ═══════════════════════════════════════ */
.rel-modal{display:none;position:fixed;inset:0;background:var(--overlay-bg);z-index:998;align-items:center;justify-content:center}
.rel-modal.show{display:flex}
.rel-modal-inner{width:min(1100px,96vw);height:min(760px,92vh);background:var(--bg2);border-radius:var(--r-xl);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;overflow:hidden}
.rel-header{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid var(--border);gap:16px;flex-wrap:wrap}
.rel-htitle{display:flex;flex-direction:column;gap:2px;min-width:0}
.rel-htitle h3{font-size:14px;font-weight:600;margin:0}
.rel-search{position:relative;display:flex;align-items:center;gap:6px;background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-sm);padding:5px 9px;width:180px;flex-shrink:0;color:var(--text3)}
.rel-search:focus-within{border-color:var(--accent)}
.rel-search input{flex:1;min-width:0;background:none;border:none;outline:none;color:var(--text);font-size:12px;font-family:var(--sans)}
.rel-search-results{display:none;position:absolute;top:calc(100% + 4px);left:0;right:0;max-height:280px;overflow-y:auto;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--shadow-md,0 4px 16px rgba(0,0,0,.18));z-index:20}
.rel-search-results.show{display:block}
.rel-search-result{display:flex;align-items:center;gap:7px;padding:6px 9px;font-size:12px;color:var(--text2);cursor:pointer}
.rel-search-result .dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.rel-search-result:hover,.rel-search-result.active{background:var(--bg3);color:var(--text)}
.rel-search-result-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rel-search-result-type{font-size:10px;color:var(--text3);flex-shrink:0}
.rel-sub{font-size:11px;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rel-crumbs{display:flex;align-items:center;gap:6px;font-size:12px;flex-wrap:wrap;flex:1;justify-content:center}
.rel-crumbs .crumb{display:flex;align-items:center;gap:6px;padding:4px 10px 4px 8px;border-radius:999px;background:var(--bg3);border:1px solid var(--border);cursor:pointer;color:var(--text2);transition:border-color .15s,color .15s}
.rel-crumbs .crumb:hover{border-color:var(--text3);color:var(--text)}
.rel-crumbs .crumb:last-child{color:var(--text);font-weight:600;cursor:default;border-color:var(--border)}
.rel-crumbs .crumb:last-child:hover{border-color:var(--border)}
.rel-crumbs .crumb .dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.rel-crumbs .crumb-sep{color:var(--text3);font-size:11px}

.rel-stage{position:relative;overflow:hidden;flex:1;background:var(--bg)}
.rel-stage svg{width:100%;height:100%;display:block;cursor:grab}
.rel-stage svg:active{cursor:grabbing}
.rel-loading-hint{position:absolute;inset:0;display:none;align-items:center;justify-content:center;font-size:12px;color:var(--text3);background:var(--bg);pointer-events:none}
.rel-stage.rel-loading .rel-loading-hint{display:flex}

.rel-legend{position:absolute;left:16px;bottom:16px;display:flex;flex-direction:column;gap:6px;background:color-mix(in srgb,var(--bg2) 88%,transparent);border:1px solid var(--border);border-radius:var(--r-md);padding:10px 12px;font-size:11px;color:var(--text2);backdrop-filter:blur(6px)}
.rel-legend-row{display:flex;align-items:center;gap:7px;cursor:pointer;user-select:none;border-radius:var(--r-sm);padding:2px 4px;margin:-2px -4px;transition:background .12s,opacity .12s}
.rel-legend-row:hover{background:var(--bg3)}
.rel-legend-row.off{opacity:.4;text-decoration:line-through}
.rel-legend .dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.rel-legend .dot--square{border-radius:1px}
.rel-legend .dot--diamond{border-radius:1px;clip-path:polygon(50% 0%,100% 50%,50% 100%,0% 50%)}
.rel-legend .dot--triangle{border-radius:0;clip-path:polygon(50% 0%,100% 100%,0% 100%)}
.rel-legend .dot--hexagon{border-radius:0;clip-path:polygon(50% 0%,100% 25%,100% 75%,50% 100%,0% 75%,0% 25%)}
.rel-legend .dot--pentagon{border-radius:0;clip-path:polygon(50% 0%,100% 38%,82% 100%,18% 100%,0% 38%)}
.rel-legend .dot--dashed{width:12px;height:0;border-top:2px dashed var(--text3);border-radius:0;background:none}
.rel-legend-row--edge{border-top:1px solid var(--border);padding-top:6px;margin-top:2px}
.rel-depth-lbl{display:block;font-size:10px;color:var(--text3);margin-bottom:3px}
.rel-depth-select{width:100%;background:var(--bg3);border:1px solid var(--border2);border-radius:var(--r-xs);padding:3px 6px;font-size:11px;color:var(--text);outline:none}
.rel-depth-select:focus{border-color:var(--accent)}
.rel-legend-reset{cursor:pointer;font-size:10px;font-weight:600;color:var(--accent);margin-top:2px;padding-top:6px;border-top:1px solid var(--border)}
.rel-legend-reset:hover{text-decoration:underline}

.rel-hint{position:absolute;left:16px;top:16px;font-size:11px;color:var(--text3);background:color-mix(in srgb,var(--bg2) 88%,transparent);border:1px solid var(--border);border-radius:var(--r-md);padding:8px 12px;max-width:220px;line-height:1.5}

.rel-zoom-ctl{position:absolute;right:16px;top:16px;display:flex;flex-direction:column;gap:1px;background:color-mix(in srgb,var(--bg2) 88%,transparent);border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden;backdrop-filter:blur(6px)}
.rel-zoom-ctl button{width:30px;height:30px;border:none;background:transparent;color:var(--text2);font-size:15px;cursor:pointer;transition:background .15s,color .15s}
.rel-zoom-ctl button:hover{background:var(--bg3);color:var(--text)}
.rel-zoom-ctl button:first-child{border-bottom:1px solid var(--border)}
#rel2DToggle{font-size:11px;font-weight:700;letter-spacing:.02em}

/* A soft halo behind each project's directly-connected nodes — the visual
   "these belong together" grouping the spring physics alone only gets
   partway to (adjacent nodes end up near each other, but nothing actually
   shows the boundary). Purely cosmetic, drawn behind edges/nodes. */
.rel-cluster-halo{transition:opacity .2s}

.rel-edge{fill:none;stroke-width:2.2;opacity:.5;transition:opacity .15s,stroke-width .15s}
.rel-edge.dim{opacity:.1}
.rel-edge.hi{opacity:.95;stroke-width:3.2}
.rel-edge-similar{stroke-dasharray:1 6;stroke-linecap:round;stroke-width:2.2;opacity:.55}
.rel-edge-similar.hi{opacity:.9;stroke-width:2.8}

.rel-node{cursor:pointer}
.rel-node circle.halo{fill:none;stroke-width:2;opacity:0;transition:opacity .15s}
.rel-node:hover circle.halo,.rel-node.hovered circle.halo{opacity:.55}
.rel-node.dim{opacity:.28}
.rel-node .core{transition:filter .15s;animation:rel-breathe 3.6s ease-in-out infinite;transform-box:fill-box;transform-origin:center;stroke:none}
.rel-node:hover .core,.rel-node.hovered .core{filter:brightness(1.3) saturate(1.15);animation-play-state:paused}
.rel-node.center .core{animation-duration:2.4s}
@keyframes rel-breathe{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.78;transform:scale(1.05)}}
@media (prefers-reduced-motion:reduce){.rel-node .core{animation:none}}
.rel-node text.label{font-size:11px;fill:var(--text2);font-family:var(--sans);pointer-events:none;text-anchor:middle}
.rel-node.center text.label{fill:var(--text);font-weight:600;font-size:12px}
.rel-node .rel-avatar-icon{pointer-events:none;filter:drop-shadow(0 0 1.5px rgba(0,0,0,.45))}
/* A pending-review ELN entry or a failed docking job — something that
   genuinely needs a person to act, not just "still in progress" — gets a
   pulsing ring on top of its normal type color, distinct from the plain
   hover halo (which needs a mouseover to appear at all). */
.rel-node .attention-ring{fill:none;stroke:var(--orange);stroke-width:1.6;opacity:.85;animation:rel-attention-pulse 1.8s ease-in-out infinite;pointer-events:none}
@keyframes rel-attention-pulse{0%,100%{opacity:.85;transform:scale(1)}50%{opacity:.25;transform:scale(1.35)}}
@media (prefers-reduced-motion:reduce){.rel-node .attention-ring{animation:none}}

/* Fixed bottom-right, always — never chases a node's constantly-drifting
   3D screen position (that per-frame tracking was the "un poco caótico"
   feeling). Hover = light preview; .locked (a click set it) = persistent,
   with a visible accent edge to distinguish it from a passing preview. */
.pin-card{position:absolute;z-index:20;right:16px;bottom:16px;width:260px;max-height:calc(100% - 32px);overflow-y:auto;background:var(--bg2);border:1px solid var(--border);border-radius:var(--r-lg);padding:16px;display:flex;flex-direction:column;gap:14px;box-shadow:var(--shadow-lg);opacity:0;transform:translateY(6px);pointer-events:none;transition:opacity .15s,transform .15s}
.pin-card.show{opacity:1;transform:translateY(0);pointer-events:auto}
.pin-card.locked{border-color:color-mix(in srgb,var(--accent) 45%,var(--border))}
.pin-close{position:absolute;top:10px;right:10px;width:22px;height:22px;border-radius:50%;border:none;background:var(--bg3);color:var(--text2);font-size:12px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s,color .15s}
.pin-close:hover{background:var(--bg4);color:var(--text)}

.pin-card .p-type{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--text2)}
.pin-card .p-type .dot{width:7px;height:7px;border-radius:50%}
.pin-card .p-name{font-size:17px;font-weight:600;letter-spacing:-.01em;margin:6px 0 2px;line-height:1.3}
.pin-card .p-id{font-family:var(--mono);font-size:12px;color:var(--text3)}
.pin-card .structure-box{background:var(--bg3);border:1px solid var(--border);border-radius:var(--r-lg);min-height:130px;display:flex;align-items:center;justify-content:center;margin-top:4px;padding:6px}
.pin-card .structure-box svg{max-width:100%;max-height:100%}
.pin-card .p-meta{display:flex;flex-direction:column;gap:9px;font-size:13px}
.pin-card .p-meta-row{display:flex;justify-content:space-between;gap:10px;color:var(--text2)}
.pin-card .p-meta-row b{color:var(--text);font-weight:500;text-align:right}
.pin-card .p-open{display:flex;align-items:center;justify-content:center;gap:7px;background:var(--text);color:var(--bg2);border:none;border-radius:9px;padding:10px 14px;font-size:13px;font-weight:600;cursor:pointer;margin-top:2px;transition:opacity .15s}
.pin-card .p-open:hover{opacity:.85}

.pin-card .p-isolate{background:var(--bg3);color:var(--text2);border:1px solid var(--border)}
.pin-card .p-isolate:hover{background:var(--bg4);color:var(--text);opacity:1}

.pin-card .p-hide{background:transparent;color:var(--text3);border:1px dashed var(--border);margin-top:-6px}
.pin-card .p-hide:hover{background:color-mix(in srgb,var(--red) 10%,transparent);color:var(--red);border-color:color-mix(in srgb,var(--red) 40%,transparent);opacity:1}

/* Reaction scheme — hover preview + pin card, for chemistry (ELN) nodes */
.rel-scheme{display:flex;align-items:center;gap:4px;flex-wrap:wrap;justify-content:center}
.rel-scheme-mol svg{max-width:64px;max-height:52px}
.rel-scheme-plus{color:var(--text3);font-size:12px}
.rel-scheme-arrow{color:var(--text2);font-size:13px;margin:0 2px}
.rel-scheme-fallback{font-family:var(--mono);font-size:9px;color:var(--text3);max-width:60px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.structure-box.rel-scheme-box{min-height:auto;padding:10px}

/* Zoom is the reveal mechanism, like a real map: zoomed all the way out,
   labels would just be noise, so only color/shape identify a node; at a
   middle zoom the focused node and its direct neighbors label themselves;
   zoomed in close, everything labels itself. */
.rel-lod-far .rel-node text.label{display:none}
.rel-lod-mid .rel-node text.label{display:none}
.rel-lod-mid .rel-node.center text.label,
.rel-lod-mid .rel-node.near-focus text.label,
.rel-lod-mid .rel-node.hovered text.label{display:block}

/* Manual override for the label-toggle button — wins over the zoom-based
   LOD rules above either way, since "always" and "hover only" are both a
   deliberate choice that shouldn't flip back just because you zoomed. */
.rel-labels-all .rel-node text.label{display:block !important}
.rel-labels-off .rel-node text.label{display:none !important}

#relFitAll,#relResetView{font-size:14px;border-bottom:1px solid var(--border)}
#relLabelToggle{font-size:10px;font-weight:700;font-family:var(--sans);border-bottom:1px solid var(--border)}

@media (max-width:820px){
  .rel-modal-inner{width:100vw;height:100dvh;border-radius:0}
  .rel-sub{display:none}
}

/* DVD screensaver easter egg — little radial pop on a perfect corner hit */
@keyframes dvd-corner-pop{
  0%{opacity:1;transform:scale(1)}
  100%{opacity:0;transform:scale(4)}
}

/* Footer flags (Galicia + Scotland), side by side — grayscale until hovered */
.footer-flag{
  display:inline-block;
  vertical-align:middle;
  filter:grayscale(1);
  opacity:.55;
  transition:filter .2s, opacity .2s;
  cursor:default;
}

/* ChemInventory location tree picker — collapsible-tree replacement for the
   flat, dot-indented <select> (see the same tree pattern in the Locations
   browser). */
.ci-loc-picker{position:relative}
.ci-loc-picker>button{background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-sm);padding:9px 12px;color:var(--text);font-size:13px;font-family:var(--sans);outline:none;transition:border .15s,box-shadow .15s;min-height:38px}
.ci-loc-picker>button:hover{border-color:var(--text3)}
.ci-loc-picker>button:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-light)}
.ci-loc-picker-panel{display:none;position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(--bg2);border:1px solid var(--border2);border-radius:var(--r-md);box-shadow:var(--shadow-md);z-index:60}
.ci-loc-picker-panel.show{display:block}
.footer-flags:hover .footer-flag{filter:none;opacity:1}
