/* ============================================================================
   LabSpace — dark "Aqua" skeuomorphic design system
   Full-bleed, black desktop, graphite brushed-metal chrome, glossy gel buttons,
   recessed dark inputs, real depth. Self-contained (no image assets).
   ============================================================================ */

:root {
  /* ── Type scale ───────────────────────────────────────────────────────────
     Eight steps, and nothing off-scale. Every font-size in the product should
     be one of these tokens; a one-off like 12.5px or 15.5px is what turns a
     design into a pile of near-misses. */
  --fs-100:  11px;   /* micro labels inside the UI mockups */
  --fs-200:  12px;   /* captions, meta, table cells — the legibility floor */
  --fs-300:  13px;   /* secondary body, buttons, tabs */
  --fs-400:  15px;   /* body copy */
  --fs-500:  17px;   /* card + dialog headings */
  --fs-600:  22px;   /* icons, sub-display */
  --fs-700:  28px;   /* section headings, stat numbers */
  --fs-800:  40px;   /* hero display */

  /* Text
     Four steps of ink, brightest to faintest. --ink-strong is for display
     headings only; everything that was #f2f4f8 / #f0f2f6 / #eef1f6 / #e2e5eb
     collapses into these. */
  --ink-strong:     #f4f6fa;
  --ink:            #eceef2;
  --ink-soft:       #b7bcc6;
  --ink-faint:      #7e8590;
  --ok:             #7fd08a;   /* the one success green */
  --ink-on-light:   #3c4043;   /* text on light surfaces: Google button, mock paper */

  /* ── Colours that have to survive the theme flip ──────────────────────────
     Each of these was a literal once, which is why light mode had to repaint
     it by hand and kept missing pieces: pale green status text on a pale green
     pill, a hover that went to #fff on a white page, a reader pane that stayed
     black. Named here instead, so the flip carries them.

     --ink-invert is "the ink that contrasts hardest with the page". On dark
     that is white; on light it is near-black. Every `:hover { color: var(--ink-invert) }`
     meant this and said the other thing.

     Note what is NOT here: text sitting on a photo, on a scrim over a photo,
     or on a solid coloured button stays pale in both themes, because what is
     under it never flips. Those keep their literals. */
  --ink-invert:     #ffffff;
  /* Status text. Legible on the page AND on its own tinted pill, which is why
     these are not the same values as --ok / --aqua. */
  --ok-ink:         #a6e6ad;
  --warn-ink:       #ffcf9a;
  --bad-ink:        #ff9d95;
  --aqua-ink:       #9cc2ff;
  /* Wells: inset areas that hold content rather than chrome — the PDF reader's
     pages, a plot canvas, a thumbnail strip. Darker than a panel on dark and
     *lighter* than the page on light, which is the whole reason they are a
     token and not a colour. */
  --well:           #16181c;
  --well-deep:      #2b2e33;
  --avatar-bg:      #1b1f27;   /* placeholder ground behind initials */
  /* Table rows. The stripes were literals and light mode repainted the cells
     but not the rows they sit in, so the library table stayed dark with dark
     text on it — readable only under the cursor, which had its own rule. */
  --row:            #1d1e22;
  --row-alt:        #232a38;   /* the faint blue stripe */
  --row-hover:      #2c3b5a;

  /* Aqua blue */
  --aqua:           #3d81f6;
  --aqua-dark:      #1a5fd6;
  --aqua-light:     #a9ccff;
  --aqua-bright:    #6fa8ff;   /* accent text on dark: eyebrows, figures */
  --aqua-glow:      rgba(61,129,246,.55);

  /* Dark surfaces */
  --bg:             #0c0d0f;
  --surface:        #212227;
  --surface-hi:     #2b2d33;
  --surface-lo:     #191a1d;
  --panel-edge:     #3a3d44;
  --hairline:       rgba(255,255,255,.06);

  /* Graphite metal (titlebar) */
  --metal-top:      #4a4d54;
  --metal-hi:       #3c3f45;
  --metal-mid:      #303237;
  --metal-lo:       #232529;
  --metal-edge:     #14151800;

  /* ── Corner radii ─────────────────────────────────────────────────────────
     Six values, one of which is "round". Anything that was 2/3/5px is --xs,
     8/10px is --radius, 14/15/16px is --radius-lg, and a shape meant to read
     as a capsule uses --radius-pill rather than guessing a number that happens
     to exceed half its height. */
  --radius-xs:      4px;
  --radius-sm:      6px;
  --radius:         9px;
  --radius-lg:      13px;
  --radius-pill:    999px;
  --radius-round:   50%;

  --font: -apple-system, "Lucida Grande", "Segoe UI", Tahoma, Geneva, sans-serif;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }

body {
  font-family: var(--font);
  font-size: 13px;
  color: var(--ink);
  background-color: #000;
  background-image:
    repeating-linear-gradient(45deg,  rgba(255,255,255,.014) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(-45deg, rgba(0,0,0,.30)        0 1px, transparent 1px 3px),
    radial-gradient(circle at 50% -10%, #16181c, #0b0c0e 60%, #000 100%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
}

/* An element carrying the hidden attribute stays hidden, whatever display a
   component rule gives it. Without this a rule like `display: flex` silently
   beats the browser's own [hidden] rule, and `el.hidden = true` does nothing —
   which is how the cover's idle buttons stayed on screen while framing. */
[hidden] { display: none !important; }

/* ── App shell (full-bleed) ─────────────────────────────────────────────── */

.app {
  display: grid;
  grid-template-columns: 1fr;
  height: 100vh;
  padding: 0;
}

.window {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;
  grid-column: 1 / -1;
  position: relative;
  overflow: hidden;
  background: var(--bg);
  border: none;
  transition: grid-template-columns .22s cubic-bezier(.4,0,.2,1);
}

.pro-tag {
  margin-left: auto; font-size: 8.5px; font-weight: 800; letter-spacing: .5px;
  padding: 1px 5px; border-radius: var(--radius-pill); color: #10233f;
  background: linear-gradient(#ffd479, #f0a93c);
}

/* ── Title bar (dark brushed metal) ─────────────────────────────────────── */

.titlebar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 12px;
  height: 48px;
  padding: 0 16px;
  background: linear-gradient(var(--metal-top), var(--metal-mid) 52%, var(--metal-lo));
  border-bottom: 1px solid #000;
  box-shadow: 0 1px 0 rgba(255,255,255,.10) inset, 0 -1px 0 rgba(0,0,0,.6) inset;
  -webkit-user-select: none; user-select: none;
}
/* Brand lockup — the logo and wordmark that open the Virtual Lab. */
.tb-brand { display: flex; align-items: center; gap: 9px; text-decoration: none; flex-shrink: 0; }
.tb-brand img { width: 26px; height: 26px; border-radius: 7px; display: block;
  box-shadow: 0 0 12px rgba(61,129,246,.35), 0 1px 3px rgba(0,0,0,.6); }
.tb-brand span { font-size: 15px; font-weight: 700; color: #eef0f4; letter-spacing: -.2px;
  text-shadow: 0 -1px 0 rgba(0,0,0,.6); }
.tb-brand b { font-weight: 700; color: var(--aqua-bright); }
.tb-brand:hover img { box-shadow: 0 0 16px rgba(61,129,246,.55), 0 1px 3px rgba(0,0,0,.6); }

.titlebar .title {
  font-weight: 600; font-size: 13px; color: var(--ink);
  text-shadow: 0 -1px 0 rgba(0,0,0,.6); letter-spacing: .2px;
}
.titlebar .spacer { flex: 1 1 0; min-width: 0; }
/* The account menu and activity flask must never be pushed off the edge. */
.tb-me, .tb-bellwrap { flex: none; }

/* Titlebar search island */
.tb-search { position: relative; margin-left: 14px; flex: 1 1 60px; min-width: 0;
  width: auto; max-width: 430px; }
.tb-search .tb-mag { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); font-size: 12px; opacity: .55; pointer-events: none; }
.titlebar .tb-search input { width: 100%; height: 30px; border-radius: 15px; padding: 0 12px 0 40px !important; font-size: 12.5px;
  color: #eef1f6; background: linear-gradient(#141518, #1b1c20); border: 1px solid #000;
  box-shadow: 0 2px 4px rgba(0,0,0,.6) inset, 0 1px 0 rgba(255,255,255,.06); }
.titlebar .tb-search input:focus { border-color: var(--aqua); outline: none; box-shadow: 0 2px 4px rgba(0,0,0,.6) inset, 0 0 0 3px var(--aqua-glow); }
.tb-results { position: absolute; top: 36px; right: 0; left: auto; z-index: 120;
  /* At least readable even when the search box itself is shrunk on a tablet;
     anchored to the box's right edge so it never spills off-screen. */
  width: max(100%, 360px); max-width: 92vw;
  background: linear-gradient(var(--surface-hi), var(--surface)); border: 1px solid var(--panel-edge);
  border-radius: 10px; box-shadow: 0 18px 44px rgba(0,0,0,.6); overflow: hidden; }
.tb-results[hidden] { display: none; }
.tb-res { display: flex; gap: 8px; align-items: center; flex-wrap: nowrap;
  padding: 8px 12px; text-decoration: none; color: var(--ink-soft); }
.tb-res:hover { background: rgba(255,255,255,.06); }
.tb-res small { color: var(--ink-faint); }
.tb-av { width: 30px; height: 30px; border-radius: 50%; background-size: cover; background-position: center; flex-shrink: 0; }
.tb-avi { display: grid; place-items: center; font-weight: 800; color: #fff; background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.tb-empty { padding: 12px; color: var(--ink-faint); font-size: 12px; text-align: center; }

/* Titlebar stats: Labs / Citers / Cited. Sized to sit inside the 48px ribbon. */
.tb-stats {
  position: relative; display: flex; align-items: center; gap: 2px;
  margin-left: 12px; flex-shrink: 0; padding: 3px; border-radius: var(--radius-pill);
  background: rgba(0,0,0,.25); border: 1px solid rgba(255,255,255,.08);
}
.tb-stat {
  display: flex; align-items: baseline; gap: 5px; height: 26px; padding: 0 11px;
  border: none; border-radius: var(--radius-pill); background: transparent;
  font: inherit; font-size: 11.5px; color: var(--ink-soft); cursor: pointer;
  white-space: nowrap; transition: background .15s, color .15s;
}
.tb-stat b { font-size: 13px; font-weight: 800; color: var(--ink-invert); }
.tb-stat:hover { background: rgba(255,255,255,.08); color: #e6eaf1; }
.tb-stat.open { color: var(--aqua-ink);
  background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark));
  box-shadow: 0 1px 0 rgba(255,255,255,.3) inset, 0 2px 5px rgba(0,0,0,.4); }
.tb-stat.open b { color: var(--ink-invert); }
.tb-stat:focus-visible { outline: 2px solid var(--aqua-light); outline-offset: 1px; }

.tb-pop {
  position: absolute; top: 40px; left: 0; width: 300px; z-index: 130;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: 10px;
  box-shadow: 0 18px 44px rgba(0,0,0,.6); overflow: hidden;
  max-height: 380px; overflow-y: auto;
}
.tb-pop[hidden] { display: none; }
.tb-pop-head { display: flex; align-items: baseline; gap: 8px; padding: 9px 12px;
  font-weight: 700; font-size: 12.5px; color: #e6e9ee; border-bottom: 1px solid #000;
  background: linear-gradient(#34373d, #282a2f); position: sticky; top: 0; }
.tb-pop-head small { font-weight: 400; font-size: 11px; color: var(--ink-faint); }
.tb-lab { display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  text-decoration: none; color: var(--ink-soft); border-bottom: 1px solid rgba(0,0,0,.35); }
.tb-lab:hover { background: rgba(255,255,255,.06); }
.tb-lab-ico { font-size: 17px; }
.tb-lab-body { flex: 1; min-width: 0; }
.tb-lab-body b { display: block; font-size: 12.5px; }
.tb-lab-body small { color: var(--aqua-bright); font-size: 11px; }
.tb-lab-n { font-size: 11px; color: var(--ink-faint); }

@media (max-width: 1180px) { .tb-stat span { display: none; } }
@media (max-width: 900px)  { .tb-stats { display: none; } }

/* Titlebar account button + menu */
.tb-me { position: relative; display: flex; align-items: center; }
.tb-me-btn {
  display: flex; align-items: center; gap: 5px; cursor: pointer;
  padding: 3px 6px 3px 3px; border-radius: var(--radius-pill);
  background: rgba(0,0,0,.25); border: 1px solid rgba(255,255,255,.10);
  transition: background .15s, border-color .15s;
}
.tb-me-btn:hover { background: rgba(0,0,0,.42); border-color: rgba(255,255,255,.2); }
.tb-me-btn:focus-visible { outline: 2px solid var(--aqua-light); outline-offset: 2px; }
.tb-me-av {
  width: 30px; height: 30px; border-radius: 50%; display: block; flex-shrink: 0;
  background-color: var(--avatar-bg); background-size: cover; background-position: center;
  box-shadow: 0 0 0 1px rgba(255,255,255,.16), 0 1px 3px rgba(0,0,0,.5);
}
.tb-me-initial { display: grid; place-items: center; font-weight: 800; font-size: 13px;
  color: #fff; background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.tb-me-chev { width: 13px; height: 13px; color: var(--ink-soft); }
.tb-me-btn[aria-expanded="true"] .tb-me-chev { transform: rotate(180deg); }

.tb-menu {
  position: absolute; top: 40px; right: 0; width: 262px; z-index: 130;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  box-shadow: 0 18px 44px rgba(0,0,0,.6); overflow: hidden; padding-bottom: 6px;
}
.tb-menu[hidden] { display: none; }
.tb-menu-head { display: flex; gap: 11px; align-items: center; padding: 14px;
  border-bottom: 1px solid rgba(0,0,0,.5); }
.tb-menu-av { width: 48px; height: 48px; border-radius: 50%; flex-shrink: 0;
  background-color: var(--avatar-bg); background-size: cover; background-position: center;
  box-shadow: 0 0 0 1px rgba(255,255,255,.16); font-size: 20px; }
.tb-menu-who { min-width: 0; }
.tb-menu-who b { display: block; color: var(--ink-strong); font-size: 13.5px; }
.tb-menu-who small { display: block; font-size: 11.5px; color: var(--ink-faint); }
.tb-menu-who small:first-of-type { color: var(--aqua-bright); }
.tb-menu-cta { display: block; margin: 12px 14px 4px; padding: 7px 0; text-align: center;
  border-radius: var(--radius-pill); text-decoration: none; font-size: 12.5px; font-weight: 700;
  color: var(--aqua-ink); border: 1px solid var(--aqua); }
.tb-menu-cta:hover { background: rgba(61,129,246,.14); }
.tb-menu-sep { height: 1px; margin: 8px 0; background: var(--panel-edge);
  border-bottom: 1px solid var(--hairline); }
.tb-menu a:not(.tb-menu-cta) {
  display: flex; align-items: center; gap: 10px; padding: 8px 14px;
  text-decoration: none; color: var(--ink); font-size: 12.5px;
}
.tb-menu a:not(.tb-menu-cta):hover { background: rgba(255,255,255,.06); color: var(--ink-invert); }
.tb-menu a span { width: 16px; text-align: center; opacity: .85; }
.tb-menu-out { color: var(--bad-ink) !important; }
.tb-menu-out:hover { background: rgba(236,91,82,.14) !important; color: var(--bad-ink) !important; }

/* Titlebar activity heart + notifications */
.tb-bellwrap { position: relative; display: flex; align-items: center; }
.tb-bell { position: relative; background: none; border: none; cursor: pointer; padding: 3px 6px; display: inline-flex; align-items: center; line-height: 0; }
.tb-bell .tb-flask { width: 21px; height: 21px; display: block; filter: drop-shadow(0 0 5px rgba(45,124,255,.65)); }
.tb-bell:hover .tb-flask { filter: drop-shadow(0 0 7px rgba(45,124,255,.9)); }
.tb-badge { position: absolute; top: -1px; right: -2px; min-width: 15px; height: 15px; border-radius: 8px;
  background: #ec5b52; color: #fff; font-size: 9px; font-weight: 800; display: grid; place-items: center; padding: 0 3px; border: 1px solid var(--metal-mid); }
.tb-notif { position: absolute; top: 34px; right: 0; width: 330px; z-index: 120;
  background: linear-gradient(var(--surface-hi), var(--surface)); border: 1px solid var(--panel-edge);
  border-radius: 10px; box-shadow: 0 18px 44px rgba(0,0,0,.6); overflow: hidden; }
.tb-notif[hidden] { display: none; }
.tb-notif-head { padding: 9px 12px; font-weight: 700; color: #e6e9ee; border-bottom: 1px solid #000; background: linear-gradient(#34373d, #282a2f); }
.tb-notif-list { max-height: 360px; overflow: auto; }
.tb-nitem { display: flex; gap: 9px; padding: 9px 12px; border-bottom: 1px solid rgba(0,0,0,.4); font-size: 12px; color: var(--ink-soft); }
.tb-nic { color: #ff6b81; }
.tb-nitem small { color: var(--ink-faint); }

/* Activity feed */
/* minmax(0, …) on both tracks, not a bare 360px and 1fr. A bare track is
   min-content wide at its narrowest, so anything inside that refuses to wrap —
   a long @handle, a role pill, the Chat button — forces the column wider than
   it was declared and the card paints out over the feed beside it. It depends
   on display scaling, which is why the same page looks right on one machine
   and spills on another. */
.lab-cols { display: grid; grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
  gap: 18px; align-items: start; margin-bottom: 20px; }
@media (max-width: 1000px) { .lab-cols { grid-template-columns: 1fr; } }

/* Public page: the same three-column shape as the lab, with the feed held to a
   readable width in the middle. Inside a lab the left column carries Members
   and Equipment; here both rails are deliberately empty for now, but they are
   real grid columns rather than plain margin, so whatever goes in them later
   drops straight in without the feed moving. */
.pub-cols { display: grid; align-items: start; justify-content: center; gap: 18px;
  /* The left rail is still a placeholder, so it gives room to the right one,
     which now carries the to-do list and needs the width for a time field and
     a row of buttons. */
  grid-template-columns: minmax(0, 230px) minmax(0, 620px) minmax(0, 380px);
  margin-top: 18px; }
.pub-main { min-width: 0; }
.pub-rail { min-width: 0; position: sticky; top: 18px; }
/* Both columns start on the same line. The compose box carries its own top
   margin for the pages where it is not in a grid; inside one, the grid's own
   margin already did that job and the extra 18px simply pushed one column
   below the other. */
.pub-cols .pub-main > .post-box:first-child,
.pub-cols .pub-rail > .panel:first-child { margin-top: 0; }
/* One rail's worth of room short: drop the rails before the feed narrows.
   A rail holding nothing may simply go. One holding the to-do list may not —
   it moves above the feed instead. `order`, not a second copy of the markup:
   the grid reorders what is already there, so the rail stays on the right on a
   wide screen and climbs to the top on a narrow one. Below the feed would have
   been easier and useless — a reminder under forty posts is not a reminder,
   which is where the phone app puts it too. */
@media (max-width: 1260px) {
  .pub-cols { grid-template-columns: minmax(0, 620px); }
  .pub-rail { display: none; }
  .pub-rail#todo-rail { display: block; position: static; order: -1; }
}
/* No drag-to-resize corner on post boxes (the owner's call, 2026-10-18). */
.feed-compose textarea, .post-box textarea { min-height: 54px; resize: none; }
.post { border: 1px solid var(--panel-edge); border-radius: var(--radius); overflow: hidden;
  background: linear-gradient(var(--surface-hi), var(--surface)); margin-bottom: 14px; box-shadow: 0 4px 12px rgba(0,0,0,.3); }
.post-head { display: flex; gap: 10px; align-items: center; padding: 12px 14px; }
.post-head .spacer { flex: 1; }
.post-del { background: none; border: none; color: var(--ink-faint); cursor: pointer; font-size: 15px; padding: 4px 6px; border-radius: 6px; }
.post-del:hover { color: #ff6b81; background: rgba(255,107,129,.12); }
.attach-btn { display: inline-flex; align-items: center; gap: 6px; }
.feed-fname { font-size: 12px; color: var(--ink-faint); margin-left: 8px; }
.feed-preview[hidden] { display: none; }
.feed-preview { position: relative; display: inline-block; margin-top: 10px; }
.feed-preview img { max-height: 200px; max-width: 100%; border-radius: 10px; border: 1px solid var(--panel-edge); display: block; box-shadow: 0 6px 16px rgba(0,0,0,.4); }
.feed-prev-x { position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 50%;
  background: rgba(0,0,0,.65); color: #fff; border: 1px solid rgba(255,255,255,.25); cursor: pointer;
  font-size: 12px; line-height: 1; display: grid; place-items: center; }
.feed-prev-x:hover { background: #ec5b52; }
.post-av { width: 38px; height: 38px; border-radius: 50%; background-size: cover; background-position: center; flex-shrink: 0; }
.post-avi { display: grid; place-items: center; font-weight: 800; color: #fff; background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.post-who { font-weight: 700; color: var(--ink); }
.post-meta { font-size: 11px; color: var(--ink-faint); }
.post-text { padding: 0 14px 12px; color: var(--ink-soft); white-space: pre-wrap; word-wrap: break-word; }
.post-img { width: 100%; display: block; max-height: 440px; object-fit: cover; }
.post-actions { display: flex; gap: 4px; padding: 8px 10px; border-top: 1px solid rgba(0,0,0,.35); align-items: center; }
.post-actions .act { background: none; border: none; cursor: pointer; color: var(--ink-soft); font-size: 13px;
  display: inline-flex; gap: 5px; align-items: center; padding: 5px 9px; border-radius: 8px; font-weight: 600; }
.post-actions .act:hover { background: rgba(255,255,255,.06); }
.post-actions .act.liked { color: #ff6b81; }
.comments { padding: 4px 14px 12px; }
.comment { font-size: 12px; color: var(--ink-soft); padding: 3px 0; }
.comment b { color: var(--ink); }
.comment-form { display: flex; gap: 8px; margin-top: 8px; }
.comment-form input { height: 30px; }

.content {
  grid-row: 2; grid-column: 1; overflow-y: auto; padding: 24px 30px 48px;
  background: radial-gradient(120% 60% at 50% 0, #1a1c20, #101114 60%, #0b0c0e 100%);
}

.page-head { display: flex; align-items: flex-end; gap: 14px; margin-bottom: 20px; }
.page-head h1 {
  margin: 0; font-size: 23px; font-weight: 700; color: var(--ink-strong);
  text-shadow: 0 -1px 0 rgba(0,0,0,.7), 0 0 22px rgba(61,129,246,.15);
}
.page-head .sub { color: var(--ink-faint); font-size: 12.5px; padding-bottom: 3px; }
.page-head .spacer { flex: 1; }

/* ── Aqua gel buttons ───────────────────────────────────────────────────── */

.btn {
  position: relative; display: inline-flex; align-items: center; gap: 6px;
  font: inherit; font-weight: 600; font-size: var(--fs-300); color: var(--ink);
  padding: 6px 15px; border-radius: var(--radius-pill); border: 1px solid #0a0a0b; cursor: pointer;
  text-decoration: none;
  background: linear-gradient(#5a5e66, #3f4249 48%, #34363c 52%, #26282c);
  box-shadow: 0 1px 0 rgba(255,255,255,.18) inset, 0 -6px 8px -6px rgba(0,0,0,.5) inset,
              0 1px 2px rgba(0,0,0,.5);
  text-shadow: 0 -1px 0 rgba(0,0,0,.5);
  -webkit-user-select: none; user-select: none; overflow: hidden;
}
.btn::before {
  content: ""; position: absolute; left: 3px; right: 3px; top: 1px; height: 45%;
  border-radius: 14px 14px 40px 40px / 14px 14px 18px 18px;
  background: linear-gradient(rgba(255,255,255,.28), rgba(255,255,255,.03));
  pointer-events: none;
}
.btn:active { box-shadow: 0 2px 5px rgba(0,0,0,.6) inset; top: 1px; }
.btn.primary {
  color: #fff; border-color: #0d3a8f;
  background: linear-gradient(#bcd7ff, var(--aqua) 48%, var(--aqua-dark) 52%, #114fbf);
  box-shadow: 0 1px 0 rgba(255,255,255,.6) inset, 0 0 0 1px rgba(255,255,255,.15) inset,
              0 1px 3px rgba(0,0,0,.5), 0 0 12px var(--aqua-glow);
}
.btn.danger { color: #fff; border-color: #5c130d;
  background: linear-gradient(#ffb0a8, #ec5b52 48%, #d33c33 52%, #b02b23); }
.btn.go { color: #fff; border-color: #123f0c;
  background: linear-gradient(#b6f29a, #5fc23d 48%, #3d9a24 52%, #2c7d1f); }
.btn.small { padding: 3px 10px; font-size: var(--fs-200); border-radius: var(--radius-pill); }
.btn:disabled { opacity: .5; cursor: default; }
.btn-row { display: flex; gap: 9px; flex-wrap: wrap; align-items: center; }

/* Segmented control */
.segmented {
  display: inline-flex; border: 1px solid #000; border-radius: 15px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(0,0,0,.5), 0 1px 0 rgba(255,255,255,.12) inset;
}
.segmented label { position: relative; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented span {
  display: block; padding: 5px 16px; font-weight: 600; font-size: 12px; color: var(--ink-soft);
  cursor: pointer; text-shadow: 0 -1px 0 rgba(0,0,0,.5);
  background: linear-gradient(var(--metal-hi), var(--metal-lo));
  border-left: 1px solid var(--panel-edge);
}
.segmented label:first-child span { border-left: none; }
.segmented input:checked + span {
  color: var(--ink-invert); text-shadow: 0 -1px 0 rgba(0,0,0,.4);
  background: linear-gradient(var(--aqua-light), var(--aqua) 50%, var(--aqua-dark));
  box-shadow: 0 2px 5px rgba(0,0,0,.4) inset;
}

/* ── Panels ─────────────────────────────────────────────────────────────── */

.panel {
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius);
  box-shadow: 0 1px 0 rgba(255,255,255,.05) inset, 0 6px 16px rgba(0,0,0,.4);
  margin-bottom: 20px;
}
.panel > .panel-head {
  padding: 11px 16px; font-weight: 700; color: #e6e9ee;
  border-bottom: 1px solid #000;
  background: linear-gradient(#34373d, #282a2f);
  border-radius: var(--radius) var(--radius) 0 0;
  text-shadow: 0 -1px 0 rgba(0,0,0,.6);
  display: flex; align-items: center; gap: 8px;
}
.panel > .panel-body { padding: 16px; }

/* ── Form Agent hub cards ───────────────────────────────────────────────── */
.form-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 18px; }
.formcard {
  display: block; text-decoration: none; color: inherit; padding: 22px;
  border-radius: var(--radius-lg); border: 1px solid var(--panel-edge);
  background: linear-gradient(var(--surface-hi), var(--surface));
  box-shadow: 0 1px 0 rgba(255,255,255,.05) inset, 0 8px 22px rgba(0,0,0,.4);
  transition: transform .12s ease, box-shadow .12s ease;
}
.formcard:hover { transform: translateY(-3px);
  box-shadow: 0 14px 32px rgba(0,0,0,.5), 0 0 0 1px var(--aqua) inset; }
.formcard .fc-ic { font-size: 30px; margin-bottom: 10px; }
.formcard h3 { margin: 0 0 6px; color: var(--ink); font-size: 16px; }
.formcard p { margin: 0 0 14px; color: var(--ink-soft); font-size: 12.5px; line-height: 1.5; }
.formcard.soon { opacity: .62; }

/* ── Virtual Lab ────────────────────────────────────────────────────────── */
.lab-hero { display: flex; align-items: center; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }
.lab-hero h1 { margin: 0; font-size: 26px; font-weight: 800; color: var(--ink-strong);
  text-shadow: 0 -1px 0 rgba(0,0,0,.7), 0 0 26px rgba(61,129,246,.18); }
.lab-hero .sub { color: var(--ink-soft); font-size: 13.5px; margin-top: 4px; }
.lab-hero .spacer { flex: 1; }

/* Settings hub */
.settings-grid { display: grid; grid-template-columns: minmax(0, 210px) minmax(0, 1fr);
  gap: 18px; align-items: start; }
@media (max-width: 820px){ .settings-grid { grid-template-columns: 1fr; } }
.settings-nav { display: flex; flex-direction: column; gap: 4px;
  background: linear-gradient(var(--surface-hi), var(--surface)); border: 1px solid var(--panel-edge);
  border-radius: var(--radius); padding: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.3); }
.settings-nav a { display: block; padding: 9px 12px; border-radius: 7px; color: var(--ink-soft);
  text-decoration: none; font-weight: 600; font-size: 13px; }
.settings-nav a:hover { background: rgba(255,255,255,.05); }
.settings-nav a.active { color: var(--ink-invert); background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark));
  box-shadow: 0 1px 0 rgba(255,255,255,.3) inset, 0 1px 3px rgba(0,0,0,.4); }
.settings-body .panel:last-child { margin-bottom: 0; }

/* Per-device sound controls in Settings. */
.sound-setting { display:grid; grid-template-columns:minmax(0,1fr) auto auto; gap:14px; align-items:center;
  padding:14px 0; border-bottom:1px solid var(--panel-edge); }
.sound-setting:last-child { border-bottom:0; }
.sound-setting strong, .sound-setting small { display:block; }
.sound-setting small { margin-top:4px; color:var(--ink-faint); font-size:12px; }
.sound-switch { display:flex; align-items:center; gap:7px; cursor:pointer; color:var(--ink-soft); font-size:12px; }
.sound-switch input { position:absolute; opacity:0; }
.sound-switch span { width:36px; height:20px; border-radius:999px; background:var(--surface-lo); border:1px solid var(--panel-edge); position:relative; transition:.16s ease; }
.sound-switch span::after { content:""; position:absolute; width:14px; height:14px; top:2px; left:2px; border-radius:50%; background:var(--ink-faint); transition:.16s ease; }
.sound-switch input:checked + span { background:var(--aqua); border-color:var(--aqua); }
.sound-switch input:checked + span::after { transform:translateX(16px); background:#fff; }
.sound-switch input:focus-visible + span { outline:2px solid var(--aqua-light); outline-offset:2px; }
@media (max-width:560px) { .sound-setting { grid-template-columns:minmax(0,1fr) auto; } .sound-setting .btn { grid-column:1 / -1; } }

.lab-id { display: inline-block; margin: 0 6px; font-size: 12px; font-weight: 700;
  color: var(--aqua-ink); background: rgba(61,129,246,.14); border: 1px solid rgba(61,129,246,.3);
  padding: 1px 8px; border-radius: 8px; }

/* ResearchGate-style member cards */
.member-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.rg-card { position: relative; display: flex; gap: 12px; padding: 14px;
  min-width: 0; overflow: hidden;
  border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  background: linear-gradient(var(--surface-hi), var(--surface)); box-shadow: 0 6px 16px rgba(0,0,0,.32); }
.rg-photo { width: 58px; height: 58px; border-radius: 50%; flex-shrink: 0;
  background-size: cover; background-position: center; border: 2px solid #3f4550;
  box-shadow: 0 2px 8px rgba(0,0,0,.4); }
.rg-initial { display: grid; place-items: center; font-weight: 800; font-size: 24px; color: #fff;
  background: linear-gradient(160deg, #5fa0ff, #1a5fd6); border-color: rgba(255,255,255,.2); }
.rg-body { min-width: 0; flex: 1; }
.rg-name { font-weight: 700; color: var(--ink); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rg-handle { font-size: 12px; color: var(--aqua-ink); margin: 1px 0 4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rg-desig { font-size: 12.5px; color: var(--ink-soft); overflow-wrap: anywhere; }
.rg-exp { font-size: 12px; color: var(--ink-faint); margin-top: 3px;
  overflow-wrap: anywhere; }

/* ── Stat gel tiles ─────────────────────────────────────────────────────── */

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px,1fr)); gap: 16px; margin-bottom: 22px; }
.tile {
  position: relative; border-radius: var(--radius-lg); padding: 16px 18px; color: #fff;
  overflow: hidden; border: 1px solid rgba(0,0,0,.5);
  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset, 0 6px 16px rgba(0,0,0,.5);
  background: linear-gradient(160deg, #6f7681, #3a3f47);
}
.tile::before {
  content: ""; position: absolute; inset: 1px 1px 55% 1px;
  border-radius: 12px 12px 60px 60px / 12px 12px 26px 26px;
  background: linear-gradient(rgba(255,255,255,.45), rgba(255,255,255,.04)); pointer-events: none;
}
.tile.blue   { background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.tile.green  { background: linear-gradient(160deg, #74d158, #2f9e2f); }
.tile.orange { background: linear-gradient(160deg, #ffb765, #e8791d); }
.tile.purple { background: linear-gradient(160deg, #b58cff, #6a3fd6); }
.tile .k { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; opacity: .95; text-shadow: 0 -1px 0 rgba(0,0,0,.4); position: relative; }
.tile .v { font-size: 30px; font-weight: 800; margin-top: 4px; text-shadow: 0 1px 2px rgba(0,0,0,.4); position: relative; }
.tile .note { font-size: 11.5px; opacity: .95; margin-top: 2px; position: relative; text-shadow: 0 -1px 0 rgba(0,0,0,.35); }

/* ── Inputs (recessed, dark) ────────────────────────────────────────────── */

label.field { display: block; margin-bottom: 12px; }
label.field > .lab { display: block; font-weight: 600; color: var(--ink-soft); margin-bottom: 4px; font-size: 12px; }

input[type=text], input[type=number], input[type=date], input[type=email],
input[type=password], input[type=search], select, textarea {
  width: 100%; font: inherit; font-size: 13px; color: var(--ink);
  padding: 7px 10px; border-radius: 6px; border: 1px solid #000;
  background: linear-gradient(#141518, #1b1c20);
  box-shadow: 0 2px 4px rgba(0,0,0,.5) inset, 0 1px 0 rgba(255,255,255,.05); outline: none;
}
input::placeholder, textarea::placeholder { color: #63696f; }
textarea { resize: vertical; min-height: 60px; }
select option { background: var(--surface-lo); color: var(--ink); }
input:focus, select:focus, textarea:focus {
  border-color: var(--aqua);
  box-shadow: 0 2px 4px rgba(0,0,0,.5) inset, 0 0 0 3px var(--aqua-glow);
}

.search { position: relative; display: inline-block; }
.search input { border-radius: 14px; padding-left: 30px; width: 250px; }
.search::before { content: "🔍"; position: absolute; left: 10px; top: 50%; transform: translateY(-50%); font-size: 12px; opacity: .5; }

.charge-grid { display: grid; grid-template-columns: minmax(0, 160px) minmax(0, 1fr); gap: 0 18px; }
@media (max-width: 620px){ .charge-grid { grid-template-columns: 1fr; } }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.grid3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0 18px; }
@media (max-width: 760px){ .grid2,.grid3{ grid-template-columns: 1fr; } }

/* ── Tables (dark striped) ──────────────────────────────────────────────── */

.table-wrap { border: 1px solid var(--panel-edge); border-radius: var(--radius); overflow: hidden; box-shadow: 0 6px 16px rgba(0,0,0,.4); background: var(--surface-lo); }
table.grid { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.grid thead th {
  text-align: left; font-weight: 600; color: var(--ink-soft); padding: 8px 12px;
  background: linear-gradient(#34373d, #282a2f); border-bottom: 1px solid #000;
  border-right: 1px solid rgba(255,255,255,.04); text-shadow: 0 -1px 0 rgba(0,0,0,.6); white-space: nowrap;
}
table.grid thead th:last-child { border-right: none; }
table.grid tbody td { padding: 8px 12px; border-bottom: 1px solid var(--hairline); color: var(--ink); }
table.grid tbody tr:nth-child(odd)  { background: var(--row); }
table.grid tbody tr:nth-child(even) { background: var(--row-alt); }   /* faint blue stripe */
table.grid tbody tr:hover { background: var(--row-hover); }
table.grid .num { text-align: right; font-variant-numeric: tabular-nums; }
table.grid .actions { white-space: nowrap; text-align: right; }
table.grid td input, table.grid td select { padding: 4px 6px; font-size: 12px; }

/* status pills */
.pill { display: inline-block; padding: 2px 9px; border-radius: 10px; font-size: 11px; font-weight: 700;
        border: 1px solid rgba(0,0,0,.4); box-shadow: 0 1px 0 rgba(255,255,255,.25) inset; }
.pill.made      { background: linear-gradient(#fff2c4,#ffe08a); color: #7a5a00; }
.pill.prepared  { background: linear-gradient(#cfe0ff,#a9ccff); color: #14346e; }
.pill.processed { background: linear-gradient(#c8f0be,#8fe07d); color: #1f6b2b; }
.pill.pending   { background: linear-gradient(#ffd6d1,#ffb0a8); color: #8a2b23; }
.pill.settled   { background: linear-gradient(#c8f0be,#8fe07d); color: #1f6b2b; }

/* ── Flash / empty ──────────────────────────────────────────────────────── */
.flash { padding: 10px 14px; border-radius: var(--radius); margin-bottom: 16px; font-weight: 600;
         border: 1px solid; box-shadow: 0 1px 0 rgba(255,255,255,.08) inset; }
.flash.ok  { background: linear-gradient(#1f3a24,#17301c); border-color:#2f6b34; color:#a6e6ad; }
.flash.err { background: linear-gradient(#3a1f1c,#301715); border-color:#7a2b23; color:#ffb7ae; }
/* It worked, but not completely — a DOI saved without its Crossref metadata,
   say. Neither green nor red would be honest about that. */
.flash.warn { background: linear-gradient(#3a331c,#302a15); border-color:#7a6623; color:#f0dda6; }
.empty { text-align:center; color: var(--ink-faint); padding: 40px 20px; font-style: italic; }

.row-actions a { color: var(--aqua-ink); text-decoration: none; font-weight: 600; margin-left: 10px; }
.row-actions a:hover { text-decoration: underline; }

.toolbar { display:flex; align-items:center; gap:10px; margin-bottom:14px; flex-wrap: wrap; }
.toolbar .spacer { flex:1; }
hr.sep { border:none; border-top:1px solid var(--panel-edge); margin: 18px 0; }
.muted { color: var(--ink-faint); }
.right { text-align: right; }
.nowrap { white-space: nowrap; }

/* Reference star toggle */
.ref-star { background: none; border: none; cursor: pointer; font-size: 16px; color: #566; padding: 2px 4px; line-height: 1; }
.ref-star.on { color: #f6be3f; text-shadow: 0 0 8px rgba(246,190,63,.5); }
.ref-star:hover { color: #ffd86a; }

/* Library list: one line per paper.
   The row is the open affordance, so it gets the pointer; the title is the
   only cell allowed to grow, and the rest are clipped rather than wrapped —
   wrapping is what made every row four lines tall. */
.ref-row { cursor: pointer; }
.ref-starcell { width: 1%; }
table.grid tbody .ref-starcell,
table.grid tbody .ref-titlecell,
table.grid tbody .ref-cell-tight,
table.grid tbody .ref-row .num { padding-top: 6px; padding-bottom: 6px; }
.ref-titlecell { line-height: 1.35; }
.ref-doi { font-size: 11px; margin-left: 8px; white-space: nowrap; }
.ref-cell-tight { max-width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Right-click menu for a library row */
.ctx-menu { position: fixed; z-index: 400; min-width: 190px; padding: 5px;
  background: var(--surface); border: 1px solid var(--panel-edge);
  border-radius: var(--radius); box-shadow: 0 10px 30px rgba(0,0,0,.5); }
.ctx-item { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  width: 100%; padding: 6px 10px; background: none; border: 0; border-radius: 6px;
  color: var(--ink); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; }
.ctx-item:hover, .ctx-item:focus-visible { background: var(--row-hover); outline: none; }
.ctx-item.danger { color: #e8897f; }
.ctx-sep { height: 1px; margin: 5px 6px; background: var(--panel-edge); }
.ctx-arrow { opacity: .6; }
/* One flyout, for projects — the only list long enough to need one. */
.ctx-parent { position: relative; }
.ctx-sub { display: none; position: absolute; left: 100%; top: -5px; min-width: 170px;
  max-height: 60vh; overflow: auto; padding: 5px;
  background: var(--surface); border: 1px solid var(--panel-edge);
  border-radius: var(--radius); box-shadow: 0 10px 30px rgba(0,0,0,.5); }
.ctx-parent:hover .ctx-sub, .ctx-parent:focus-within .ctx-sub { display: block; }

/* Reference reader */
.reader-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: 16px; align-items: start; }
@media (max-width: 1000px) { .reader-grid { grid-template-columns: 1fr; } }
.pdf-reader { width: 100%; height: 80vh; border: none; display: block; background: #525659; }
.pdf-pages { max-height: 80vh; overflow: auto; background: var(--well-deep); padding: 14px;
  display: flex; flex-direction: column; gap: 14px; align-items: center; border-radius: 0 0 var(--radius) var(--radius); }
.pdf-page { width: 100%; max-width: 820px; height: auto; border-radius: 3px; box-shadow: 0 6px 18px rgba(0,0,0,.55); background: #fff; }

/* ── Research paper reader ──────────────────────────────────────────────── */
.rdr { display: flex; flex-direction: column; height: calc(100vh - 96px); margin: -6px 0; }
.rdr-top { display: flex; align-items: center; gap: 8px; padding: 6px 10px; flex-wrap: wrap;
  background: linear-gradient(var(--surface-hi), var(--surface)); border: 1px solid var(--panel-edge);
  border-radius: var(--radius) var(--radius) 0 0; }
.rdr-title { font-weight: 700; color: var(--ink); max-width: 34vw; min-width: 0; flex: 0 1 auto;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rdr-top .spacer { flex: 1; }
.rdr-tools { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rdr-sep { width: 1px; height: 20px; background: var(--panel-edge); margin: 0 2px; }
.rdr-pageind { font-size: 12px; color: var(--ink-soft); display: inline-flex; align-items: center; gap: 5px; }
.rdr-pageind input { width: 46px; padding: 3px 4px; text-align: center; }
.rdr-swatches { display: inline-flex; gap: 4px; }
.rdr-swatches .sw { width: 18px; height: 18px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0; }
.rdr-swatches .sw.active { border-color: #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.5); }

.rdr-main { flex: 1; min-height: 0; display: flex; border: 1px solid var(--panel-edge); border-top: none;
  border-radius: 0 0 var(--radius) var(--radius); overflow: hidden; }
.rdr-thumbs { width: 132px; flex-shrink: 0; overflow-y: auto; background: var(--well); border-right: 1px solid var(--panel-edge); padding: 8px; }
.rdr.no-thumbs .rdr-thumbs { display: none; }
.rdr-thumb { cursor: pointer; margin-bottom: 8px; text-align: center; border: 0; border-radius: 4px; }
.rdr-thumb img { width: 100%; display: block; border-radius: 3px; box-shadow: 0 2px 6px rgba(0,0,0,.5); background: #fff; }
.rdr-thumb span { font-size: 10px; color: var(--ink-faint); }
/* The mark goes round the page, not round the page and its number. Outline
   rather than border, so nothing shifts when it appears. */
.rdr-thumb:hover img { outline: 2px solid var(--aqua); outline-offset: 1px; }

.rdr-pages { flex: 1; overflow: auto; background: var(--well-deep); padding: 18px; display: flex; flex-direction: column; align-items: center; gap: 16px; }
.rdr-page { position: relative; width: var(--pw, 780px); max-width: 100%; background: #fff; box-shadow: 0 6px 20px rgba(0,0,0,.55); border-radius: 2px; }
.rdr-pageimg { width: 100%; display: block; border-radius: 2px; }
.rdr-annolayer { position: absolute; inset: 0; pointer-events: none; }
/* Highlighting means selecting the words, so the overlay must not swallow the
   cursor — it used to, which is what made this a crosshair and a dragged box.
   Only a page with no text behind it, a scan or a saved page image, still
   needs the box. .hl-rect sets pointer-events itself, so existing highlights
   stay clickable through a layer that ignores the mouse. */
.rdr.hl-on .rdr-annolayer { pointer-events: none; }
.rdr.hl-on .no-text .rdr-annolayer,
.rdr.hl-on #rdr-legacy-pages .rdr-annolayer { pointer-events: auto; cursor: crosshair; }
.rdr.hl-on .textLayer { cursor: text; }
/* While dragging, the selection wears the pen you picked rather than the
   browser's blue, so what you are about to get is what you see.
   Written out per pen, with no var() and no color-mix(): if either fails to
   resolve inside ::selection the whole declaration is dropped and the browser
   paints its own blue, which is exactly what it was doing. */
.rdr.hl-on[data-pen="yellow"] .textLayer ::selection,
.rdr.hl-on[data-pen="yellow"] .textLayer::selection { background-color: rgba(255,213,74,.5); }
.rdr.hl-on[data-pen="green"] .textLayer ::selection,
.rdr.hl-on[data-pen="green"] .textLayer::selection { background-color: rgba(127,208,138,.5); }
.rdr.hl-on[data-pen="blue"] .textLayer ::selection,
.rdr.hl-on[data-pen="blue"] .textLayer::selection { background-color: rgba(95,160,255,.5); }
.rdr.hl-on[data-pen="red"] .textLayer ::selection,
.rdr.hl-on[data-pen="red"] .textLayer::selection { background-color: rgba(255,143,133,.5); }
.hl-rect { position: absolute; border: 1.5px solid; border-radius: 2px; pointer-events: auto; cursor: pointer; }
/* The transparency lives here, once, so overlapping lines inside cannot lay
   the colour down twice. The lines themselves are painted solid. */
.hl-rect.hl-run { border-color: transparent; border: 0; background: none;
  opacity: .38; pointer-events: none; }
/* Rounded and inset a hair, so a run reads as a stroke of a pen over the words
   rather than a rectangle ruled around them. */
.hl-rect.hl-run > i { position: absolute; border-radius: 4px; background: var(--hl, #ffd54a);
  pointer-events: auto; cursor: pointer; }
.hl-rect.hl-run.has-note { outline: 1.5px solid var(--hl, #ffd54a); outline-offset: 1px; }
.hl-rect.has-note::after { content: "🗨"; position: absolute; top: -10px; right: -8px; font-size: 11px; }
.hl-sel { position: absolute; border: 1.5px dashed; border-radius: 2px; pointer-events: none; }

.rdr-side { width: 300px; flex-shrink: 0; border-left: 1px solid var(--panel-edge); display: flex; flex-direction: column; background: var(--surface); }
.rdr-tabs { display: flex; border-bottom: 1px solid #000; }
.rdr-tabs .rdr-tab { flex: 1; padding: 9px 4px; background: linear-gradient(#2b2d33, #232529); color: var(--ink-faint);
  border: none; border-right: 1px solid rgba(0,0,0,.4); font-weight: 600; font-size: 12px; cursor: pointer; }
.rdr-tabs .rdr-tab:last-of-type { border-right: none; }
/* Shuts the panel from inside it, rather than only from the toolbar. */
.rdr-side-close { flex: 0 0 auto; padding: 0 11px; background: linear-gradient(#2b2d33, #232529);
  border: 0; color: var(--ink-faint); font-size: 12px; cursor: pointer; }
.rdr-side-close:hover { color: var(--ink); }
.rdr-tabs .rdr-tab.active { color: #fff; background: linear-gradient(#34373d, #2a2c31); box-shadow: 0 -2px 0 var(--aqua) inset; }
.rdr-pane { display: none; padding: 14px; overflow-y: auto; }
.rdr-pane.active { display: block; }
.rdr-meta .k { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: #6fa8ff; margin-top: 12px; }
.rdr-meta .k:first-child { margin-top: 0; }
.rdr-meta .v { color: var(--ink-soft); font-size: 12.5px; margin-top: 3px; }
#rdr-notes { width: 100%; min-height: 320px; }

.hl-item { display: flex; gap: 8px; padding: 8px; border-radius: 6px; cursor: pointer; align-items: flex-start; }
.hl-item:hover { background: rgba(255,255,255,.05); }
.hl-item .dot { width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0; margin-top: 2px; }
.hl-item .t { font-size: 12px; color: var(--ink-soft); }

.hl-pop { position: fixed; z-index: 300; width: 280px; padding: 10px; border-radius: 10px;
  background: linear-gradient(var(--surface-hi), var(--surface)); border: 1px solid var(--panel-edge);
  box-shadow: 0 18px 44px rgba(0,0,0,.7); }
.hl-pop[hidden] { display: none; }
.hl-pop textarea { width: 100%; min-height: 60px; margin-bottom: 8px; }

/* Inline label link (e.g. "＋ New vendor") */
.lab-link { margin-left: 8px; font-weight: 600; font-size: 11px; color: var(--aqua-ink); text-decoration: none; }
.lab-link:hover { text-decoration: underline; }

/* Modal */
.modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.6); display: grid; place-items: center; z-index: 200; }
.modal-backdrop[hidden] { display: none; }
.modal-card { width: 100%; max-width: 460px; border-radius: var(--radius-lg); border: 1px solid var(--panel-edge);
  background: linear-gradient(var(--surface-hi), var(--surface)); box-shadow: 0 30px 80px rgba(0,0,0,.75); overflow: hidden; }
.modal-head { padding: 12px 16px; font-weight: 700; color: #e6e9ee; background: linear-gradient(#34373d, #282a2f);
  border-bottom: 1px solid #000; display: flex; align-items: center; text-shadow: 0 -1px 0 rgba(0,0,0,.6); }
.modal-x { margin-left: auto; background: none; border: none; color: var(--ink-faint); font-size: 15px; cursor: pointer; }
.modal-x:hover { color: var(--ink-invert); }
.modal-body { padding: 16px; }

/* Dashboard bar list */
.barlist { display: grid; gap: 9px; }
.barrow { display: grid; grid-template-columns: minmax(0, 130px) minmax(0, 1fr) minmax(0, 90px);
  gap: 12px; align-items: center; font-size: 12px; }
.barrow .track { height: 15px; background: var(--surface-lo); border-radius: 8px; overflow: hidden; border: 1px solid #000; }
.barrow .fill { height: 100%; background: linear-gradient(90deg, var(--aqua-light), var(--aqua-dark)); box-shadow: 0 1px 0 rgba(255,255,255,.2) inset; }
.barrow .val { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink-soft); }
.barrow .lbl { color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ============================================================================
   Landing / front page
   ============================================================================ */

.landing {
  min-height: 100vh; display: grid;
  grid-template-columns: 1.5fr minmax(340px, 400px);
  grid-template-areas: "hero login" "clips clips";
  align-content: center; gap: 30px 5vw;
  padding: 4vh 5vw 7vh; position: relative; overflow: hidden;
}
.hero       { grid-area: hero; }
.auth-wrap  { grid-area: login; }
.hero-clips { grid-area: clips; }
.landing::before {  /* aqua glow */
  content: ""; position: absolute; width: 900px; height: 900px; left: -220px; top: -300px;
  background: radial-gradient(circle, rgba(61,129,246,.28), transparent 62%);
  pointer-events: none;
}
.landing::after {
  content: ""; position: absolute; width: 700px; height: 700px; right: -160px; bottom: -260px;
  background: radial-gradient(circle, rgba(106,63,214,.22), transparent 62%);
  pointer-events: none;
}

.hero { position: relative; padding: 0; display: flex; flex-direction: column; justify-content: center; gap: 3vh; }
.hero .brand-top { display: flex; align-items: center; gap: 14px; }
.hero .logo {
  width: 58px; height: 58px; border-radius: var(--radius-lg); display: block; flex-shrink: 0;
  filter: drop-shadow(0 6px 16px rgba(26,95,214,.5));
}
.hero h1 {
  margin: 0; font-size: var(--fs-800); font-weight: 800; letter-spacing: -.5px; color: var(--ink-strong);
  text-shadow: 0 2px 0 rgba(0,0,0,.6), 0 0 40px rgba(61,129,246,.25);
}
.hero h1 span { color: var(--aqua-bright); }
.hero .tag { color: var(--ink-faint); font-size: var(--fs-300); margin-top: 6px; }

.hero .quote {
  position: relative; margin: 0; display: grid;
  grid-template-columns: minmax(0, auto) minmax(420px, 1fr);
  column-gap: 52px; align-items: center;
}
.hero .quote .big {
  font-size: var(--fs-800); line-height: 1.18; font-weight: 800; color: var(--ink); max-width: 15ch;
  text-shadow: 0 2px 0 rgba(0,0,0,.5);
}
.hero .quote .big em { color: var(--ok); font-style: normal; }
.hero .quote .desc { margin: 0; color: var(--ink-soft); font-size: var(--fs-400); line-height: 1.72; max-width: 70ch; text-align: justify; text-justify: inter-word; }
@media (max-width: 1080px) {
  .hero .quote { grid-template-columns: 1fr; row-gap: 20px; }
  .hero .quote .desc { max-width: 60ch; }
}
.hero .foot { color: var(--ink-faint); font-size: var(--fs-200); }
.landing .foot-cue {
  position: absolute; left: 0; right: 0; bottom: 22px; text-align: center;
  color: var(--ink-faint); font-size: var(--fs-200); z-index: 2; text-decoration: none;
}
.landing .foot-cue:hover { color: var(--aqua-ink); }

.auth-wrap { position: relative; align-self: start; justify-self: end; width: 100%; }
.auth-card {
  width: 100%; max-width: 400px; margin-left: auto; border-radius: var(--radius-lg); overflow: hidden;
  border: 1px solid rgba(255,255,255,.07);
  background: linear-gradient(var(--surface), var(--surface-lo));
  box-shadow: 0 1px 0 rgba(255,255,255,.04) inset, 0 16px 38px rgba(0,0,0,.42);
}
.auth-tabs { display: flex; border-bottom: 1px solid #000; }
.auth-tabs a {
  flex: 1; text-align: center; padding: 14px 0; font-weight: 700; font-size: var(--fs-300);
  color: var(--ink-soft); text-decoration: none; background: linear-gradient(#2b2d33,#232529);
  text-shadow: 0 -1px 0 rgba(0,0,0,.6);
}
.auth-tabs a.active {
  color: #fff; background: linear-gradient(#34373d,#2a2c31);
  box-shadow: 0 -2px 0 var(--aqua) inset;
}
.auth-tabs a:focus-visible {
  outline: 2px solid var(--aqua-light); outline-offset: -3px;
}
.auth-body { padding: 22px 22px 26px; }
.auth-body h2 { margin: 0 0 4px; font-size: var(--fs-500); color: var(--ink-strong); }
.auth-body p.sub { margin: 0 0 18px; color: var(--ink-faint); font-size: var(--fs-200); }
.auth-body .btn.primary { width: 100%; justify-content: center; padding: 9px; font-size: var(--fs-300); margin-top: 6px; }
.auth-body .google-btn { width: 100%; justify-content: center; margin-top: 10px; gap: 9px;
  color: var(--ink-on-light); background: linear-gradient(#ffffff, #f1f1f3); border-color: #c8c8cd; text-shadow: none; }
.auth-body .google-btn .g { font-weight: 800; font-size: var(--fs-400);
  background: conic-gradient(from -45deg, #ea4335 0 25%, #fbbc05 0 50%, #34a853 0 75%, #4285f4 0);
  -webkit-background-clip: text; background-clip: text; color: transparent; }
.auth-body .hint { margin-top: 14px; font-size: var(--fs-200); color: var(--ink-faint); text-align: center; }
.auth-body .hint a { color: var(--aqua-ink); text-decoration: none; }

/* Demo clips inside the hero fold */
.hero-clips { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: start; }
.hero-clips .clip-eyebrow { grid-column: 1 / -1; margin-bottom: -8px; }

@media (max-width: 1000px) {
  .landing { grid-template-columns: 1fr; grid-template-areas: "hero" "login" "clips"; }
  .auth-wrap { justify-self: stretch; }
  .auth-card { margin-left: 0; max-width: 460px; }
  .hero-clips { grid-template-columns: 1fr; }
}
@media (max-width: 860px) {
  .hero h1 { font-size: var(--fs-700); }
  .hero .quote .big { font-size: var(--fs-700); }
}

/* ── Marketing sections (below the fold) ────────────────────────────────── */

.marketing { position: relative; background: linear-gradient(#0b0c0e, #0f1114); border-top: 1px solid #000; }
.section { max-width: 1200px; margin: 0 auto; padding: 80px 6vw; position: relative; }
.section + .section { border-top: 1px solid rgba(255,255,255,.04); }
.eyebrow { color: var(--aqua-bright); font-weight: 700; text-transform: uppercase; letter-spacing: 1.2px; font-size: var(--fs-200); }
.section h2 { font-size: var(--fs-700); font-weight: 800; color: var(--ink-strong); margin: 8px 0 12px; letter-spacing: -.3px; text-shadow: 0 2px 0 rgba(0,0,0,.5); }
.section .lead { color: var(--ink-soft); font-size: var(--fs-400); line-height: 1.6; max-width: 62ch; }

/* Feature pillars */
.pillars { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 40px; }
.pillar {
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius-lg); padding: 24px 22px;
  box-shadow: 0 1px 0 rgba(255,255,255,.05) inset, 0 12px 30px rgba(0,0,0,.45);
}
.pillar .ic {
  width: 52px; height: 52px; border-radius: var(--radius-lg); display: grid; place-items: center;
  font-size: var(--fs-600); margin-bottom: 14px; border: 1px solid rgba(0,0,0,.6);
  box-shadow: 0 1px 0 rgba(255,255,255,.4) inset, 0 6px 16px rgba(0,0,0,.4);
}
.pillar.a .ic { background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.pillar.b .ic { background: linear-gradient(160deg, #74d158, #2f9e2f); }
.pillar.c .ic { background: linear-gradient(160deg, #b58cff, #6a3fd6); }
.pillar h3 { margin: 0 0 8px; font-size: var(--fs-500); color: var(--ink); }
.pillar p { margin: 0 0 12px; color: var(--ink-soft); font-size: var(--fs-300); line-height: 1.55; }
.pillar ul { margin: 0; padding: 0; list-style: none; }
.pillar li { color: var(--ink-soft); font-size: var(--fs-200); padding: 4px 0 4px 20px; position: relative; }
.pillar li::before { content: "✓"; position: absolute; left: 0; color: var(--ok); font-weight: 800; }

/* Use-case cards */
.section.wide { max-width: 1560px; }
.uc-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px; margin-top: 40px; }
@media (max-width: 1200px) { .uc-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 680px)  { .uc-grid { grid-template-columns: repeat(2, 1fr); } }
.uc-card {
  position: relative; display: flex; flex-direction: column; height: 100%;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius); padding: 24px 18px 20px 22px;
  box-shadow: 0 8px 22px rgba(0,0,0,.4); overflow: hidden;
}
.uc-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: linear-gradient(var(--aqua-light), var(--aqua-dark)); }
.uc-card .uc-ic { font-size: var(--fs-600); line-height: 1; }
.uc-card h3 { margin: 12px 0 6px; font-size: var(--fs-400); color: var(--ink); }
.uc-card p { margin: 0; color: var(--ink-soft); font-size: var(--fs-200); line-height: 1.5; }
.uc-card .tag {
  align-self: flex-start; margin-top: auto; display: inline-block;
  font-size: var(--fs-100); font-weight: 700; letter-spacing: .2px;
  color: var(--aqua-ink); background: rgba(61,129,246,.14); border: 1px solid rgba(61,129,246,.3);
  padding: 4px 9px; border-radius: var(--radius-sm);
}
.uc-card p { margin-bottom: 16px; }

/* Stat strip */
.section.statband { max-width: none; padding: 56px 3vw; }
.statstrip {
  display: grid; grid-template-columns: repeat(4, auto); justify-content: center;
  gap: 0; margin: 8px auto 0; width: fit-content; max-width: 100%;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  box-shadow: 0 1px 0 rgba(255,255,255,.05) inset, 0 12px 30px rgba(0,0,0,.45); overflow: hidden;
}
.statstrip .n .forms-ticker { color: var(--aqua-bright); display: inline-block; }
.statstrip .n .forms-ticker.flip { animation: tickFlip .45s ease; }
@keyframes tickFlip { 0% { opacity: 0; transform: translateY(10px); } 100% { opacity: 1; transform: none; } }
.statstrip .live-dot {
  display: inline-block; width: 9px; height: 9px; border-radius: var(--radius-round); background: #5fc23d;
  margin-right: 9px; vertical-align: middle; animation: livePulse 1.8s infinite;
}
@keyframes livePulse {
  0%   { box-shadow: 0 0 0 0 rgba(95,194,61,.55); }
  70%  { box-shadow: 0 0 0 9px rgba(95,194,61,0); }
  100% { box-shadow: 0 0 0 0 rgba(95,194,61,0); }
}
.statstrip .stat { padding: 26px 30px; text-align: center; border-left: 1px solid rgba(255,255,255,.05); }
.statstrip .stat:first-child { border-left: none; }
.statstrip .n { font-size: var(--fs-700); font-weight: 800; color: var(--ink-strong); text-shadow: 0 0 22px rgba(61,129,246,.25); }
.statstrip .n span { color: var(--aqua-bright); }
.statstrip .l { font-size: var(--fs-200); color: var(--ink-faint); margin-top: 4px; white-space: nowrap; }

/* Closing CTA */
.cta-band { text-align: center; }
.cta-band h2 { font-size: var(--fs-700); }
.cta-band p { color: var(--ink-soft); max-width: 54ch; margin: 0 auto 22px; font-size: var(--fs-400); }
.cta-band .btn.primary { padding: 11px 28px; font-size: var(--fs-400); }

.lfooter { text-align: center; color: var(--ink-faint); font-size: var(--fs-200); padding: 30px 6vw 40px; border-top: 1px solid rgba(255,255,255,.04); }

@media (max-width: 860px) {
  .pillars { grid-template-columns: 1fr; }
  .statstrip { grid-template-columns: repeat(2, 1fr); }
  .statstrip .stat:nth-child(3) { border-left: none; }
  .section { padding: 54px 8vw; }
}

/* ============================================================================
   EIS workbench
   ============================================================================ */
.eis-wb { display: flex; flex-direction: column; min-height: calc(100vh - 48px); }
.wb-toolbar { display: flex; align-items: center; gap: 10px; padding: 4px 2px 14px; flex-wrap: wrap; }
.wb-toolbar .wb-active { font-weight: 700; color: var(--ink); }
.wb-toolbar .spacer { flex: 1; }
.wb-chk { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-soft); }
.wb-chk input { width: auto; }

.wb-empty[hidden], .wb-grid[hidden] { display: none; }
.wb-empty { flex: 1; display: grid; place-items: center; }
.wb-empty-card { text-align: center; max-width: 460px; padding: 40px; border-radius: var(--radius-lg);
  border: 1px dashed var(--panel-edge); background: linear-gradient(var(--surface-hi), var(--surface)); }
.wb-empty-card h2 { margin: 8px 0 6px; color: var(--ink); }
.wb-empty-card .btn { margin-top: 16px; }

.wb-grid { display: grid; grid-template-columns: 190px minmax(0,1fr) 300px; gap: 14px; align-items: start; }
@media (max-width: 1200px){ .wb-grid { grid-template-columns: 170px minmax(0,1fr); } .wb-controls { grid-column: 1 / -1; } }

/* project tree */
.wb-tree { background: linear-gradient(var(--surface-hi), var(--surface)); border: 1px solid var(--panel-edge);
  border-radius: var(--radius); box-shadow: 0 1px 3px rgba(0,0,0,.3); overflow: hidden; }
.wb-tree-head { padding: 9px 12px; font-weight: 700; color: #cdd1d8; background: linear-gradient(#34373d,#282a2f); border-bottom: 1px solid #000; }
.wb-ds-list { list-style: none; margin: 0; padding: 6px; }
.wb-ds { display: flex; align-items: center; gap: 4px; padding: 6px 8px; border-radius: 6px; cursor: pointer; }
.wb-ds:hover { background: rgba(255,255,255,.05); }
.wb-ds.active { background: linear-gradient(var(--aqua-light), var(--aqua)); }
.wb-ds.active .wb-ds-name { color: var(--ink-invert); }
.wb-ds-name { flex: 1; font-size: 12px; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wb-ds-x { background: none; border: none; color: var(--ink-faint); cursor: pointer; font-size: 11px; }
.wb-ds-x:hover { color: var(--bad-ink); }
.wb-tree-actions { padding: 8px; border-top: 1px solid var(--panel-edge); }
.wb-tree-actions .btn { width: 100%; justify-content: center; }

/* center tabs */
.wb-center { min-width: 0; }
.wb-tabs { display: flex; gap: 4px; margin-bottom: 12px; flex-wrap: wrap; }
.wb-tab { font: inherit; font-weight: 600; font-size: 12.5px; color: #cfd3da; cursor: pointer;
  padding: 7px 14px; border-radius: 8px 8px 0 0; border: 1px solid var(--panel-edge); border-bottom: none;
  background: linear-gradient(#2b2d33, #232529); }
.wb-tab.active { color: var(--ink-invert); background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark)); }
.wb-pane { display: none; }
.wb-pane.active { display: block; }

.wb-plot-actions { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.wb-plot-actions .spacer { flex: 1; }
.wb-plots { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 1500px){ .wb-plots { grid-template-columns: 1fr; } }
.wb-plot { height: 380px; background: var(--well); border: 1px solid var(--panel-edge); border-radius: var(--radius); }

/* right controls */
.wb-controls { display: flex; flex-direction: column; gap: 14px; }
.wb-controls .panel { margin-bottom: 0; }
.wb-results { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 14px; }
.wb-results > div { display: flex; justify-content: space-between; font-size: 12px; color: var(--ink-soft);
  border-bottom: 1px solid rgba(255,255,255,.05); padding: 3px 0; }
.wb-results b { color: var(--ink); font-variant-numeric: tabular-nums; }
.wb-cell-out { margin-top: 14px; }
.wb-cell-badge { padding: 8px 12px; border-radius: 8px; background: rgba(61,129,246,.14);
  border: 1px solid rgba(61,129,246,.3); color: var(--aqua-ink); font-weight: 600; }
.wb-cell-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
@media (max-width: 1100px){ .wb-cell-grid { grid-template-columns: 1fr; } }
.cs-explode { background: var(--well); border: 1px solid var(--panel-edge); border-radius: 8px; padding: 8px; margin-bottom: 12px; }

/* ── Animated demo "clips" ──────────────────────────────────────────────── */

.demo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 40px; }
@media (max-width: 860px) { .demo-grid { grid-template-columns: 1fr; } }

.clip {
  border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--panel-edge);
  box-shadow: 0 1px 0 rgba(255,255,255,.06) inset, 0 18px 44px rgba(0,0,0,.55);
  background: var(--surface);
}
.clip-bar {
  display: flex; align-items: center; gap: 7px; padding: 0 12px; height: 34px;
  background: linear-gradient(var(--metal-top), var(--metal-mid) 52%, var(--metal-lo));
  border-bottom: 1px solid #000;
}
.clip-bar i { width: 10px; height: 10px; border-radius: var(--radius-round); display: block;
  box-shadow: 0 0 0 .5px rgba(0,0,0,.5), 0 1px 1px rgba(255,255,255,.4) inset; }
.clip-bar .r { background: radial-gradient(circle at 35% 30%, #ff9d95, #ec5b52); }
.clip-bar .y { background: radial-gradient(circle at 35% 30%, #ffe08a, #f6be3f); }
.clip-bar .g { background: radial-gradient(circle at 35% 30%, #b6f29a, #5fc23d); }
.clip-bar span { margin-left: 6px; font-size: var(--fs-200); color: var(--ink); font-weight: 600; text-shadow: 0 -1px 0 rgba(0,0,0,.6); }

.clip-screen { position: relative; height: 330px; overflow: hidden;
  background: radial-gradient(120% 80% at 50% 0, #1a1c20, #0f1013); }
.clip-screen .frame { position: absolute; inset: 0; padding: 16px 16px 34px; opacity: 0; }
/* Step 1 is the resting state, so a paused, blocked or not-yet-started
   animation still shows a populated window instead of a black rectangle. */
.clip-screen .frame.a { opacity: 1; }

.clip-caps { position: absolute; left: 0; right: 0; bottom: 0; height: 30px;
  background: linear-gradient(transparent, rgba(0,0,0,.55)); pointer-events: none; }
.clip-caps .cap { position: absolute; left: 14px; bottom: 8px; font-size: var(--fs-200); font-weight: 700;
  color: var(--aqua-light); opacity: 0; text-shadow: 0 1px 2px #000; }
.clip-caps .cap.ca { opacity: 1; }

/* mini mock widgets */
.m-title { font-size: var(--fs-200); font-weight: 800; color: var(--ink); margin: 0 0 12px; display: flex; align-items: center; gap: 6px; }
.m-row { display: flex; gap: 8px; align-items: center; margin-bottom: 9px; }
.m-lab { width: 74px; font-size: var(--fs-100); color: var(--ink-faint); text-align: right; }
.m-inp { flex: 1; height: 26px; border-radius: var(--radius-xs); border: 1px solid #000;
  background: linear-gradient(#141518, #1b1c20); box-shadow: 0 2px 4px rgba(0,0,0,.5) inset;
  font-size: var(--fs-200); color: var(--ink); display: flex; align-items: center; padding: 0 8px; }
.m-inp.hl { border-color: var(--aqua); box-shadow: 0 2px 4px rgba(0,0,0,.5) inset, 0 0 0 3px var(--aqua-glow); }
.caret { display: inline-block; width: 1.5px; height: 13px; background: #6fa8ff; margin-left: 1px; animation: mBlink 1s steps(1) infinite; }
@keyframes mBlink { 50% { opacity: 0; } }
.m-btn { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-200); font-weight: 700; color: #fff;
  padding: 5px 12px; border-radius: var(--radius-pill); border: 1px solid #0d3a8f;
  background: linear-gradient(#bcd7ff, var(--aqua) 48%, var(--aqua-dark) 52%, #114fbf);
  box-shadow: 0 1px 0 rgba(255,255,255,.5) inset, 0 0 10px var(--aqua-glow); }
.m-btn.go { border-color:#123f0c; background: linear-gradient(#b6f29a, #5fc23d 48%, #3d9a24 52%, #2c7d1f); }

/* mini table */
.m-tbl { width: 100%; border-collapse: collapse; font-size: var(--fs-200); border: 1px solid var(--panel-edge); border-radius: var(--radius-sm); overflow: hidden; }
.m-tbl th { background: linear-gradient(#34373d, #282a2f); color: var(--ink-soft); text-align: left; padding: 6px 8px; font-weight: 600; }
.m-tbl td { padding: 6px 8px; border-top: 1px solid rgba(0,0,0,.5); color: var(--ink); }
.m-tbl tr:nth-child(even) td { background: var(--row-alt); }
.m-tot { text-align: right; font-size: var(--fs-200); color: var(--ink); margin-top: 8px; font-weight: 700; }
.m-tot b { color: var(--ok); }
.m-count { font-weight: 400; color: var(--ink-faint); font-size: var(--fs-100); }

/* PDF paper */
.m-pdf { position: absolute; left: 50%; top: 46%; width: 200px; height: 250px;
  transform: translate(-50%, -50%); background: #f5f5ef; color: var(--ink-on-light); border-radius: var(--radius-xs);
  box-shadow: 0 22px 44px rgba(0,0,0,.6); padding: 14px 14px 0;
  overflow: hidden; }   /* the fake page clips its own fake content, like a real one */
.m-pdf .ph { font-size: var(--fs-100); font-weight: 800; color: var(--ink-on-light); text-align: center; letter-spacing: .2px;
  border-bottom: 1px solid #bbb; padding-bottom: 6px; }
.m-pdf .pl { height: 5px; background: #dcdcd2; border-radius: var(--radius-pill); margin: 7px 0; }
.m-pdf .pl.s { width: 60%; }
.m-pdf .pgrid { height: 60px; border: 1px solid #cfcfc4; border-radius: var(--radius-xs); margin-top: 8px;
  background: repeating-linear-gradient(#eee 0 11px, #e2e2d8 11px 12px); }

/* audit stamp */
.m-stamp { position: absolute; right: 26px; top: 54px; color: var(--ok); border: 3px solid var(--ok);
  border-radius: var(--radius-sm); padding: 5px 11px; font-weight: 900; font-size: var(--fs-400); letter-spacing: 1px;
  transform: rotate(-14deg); text-shadow: 0 0 8px rgba(127,208,138,.5); box-shadow: 0 0 14px rgba(127,208,138,.35); }
.m-pill { display: inline-block; padding: 2px 9px; border-radius: var(--radius-pill); font-size: var(--fs-100); font-weight: 800;
  background: linear-gradient(#c8f0be, #8fe07d); color: #1f6b2b; }
/* Form-type badge — same shape, amber so it reads as a category, not a status. */
.m-pill.type { background: linear-gradient(#fff2c4, #ffe08a); color: #7a5a00; }

/* ---- C-Form clip timeline (15s, three phases) ---- */
.clip-cform .frame.a { animation: cfA 15s infinite; }
.clip-cform .frame.b { animation: cfB 15s infinite; }
.clip-cform .frame.c { animation: cfC 15s infinite; }
.clip-cform .cap.ca  { animation: cfA 15s infinite; }
.clip-cform .cap.cb  { animation: cfB 15s infinite; }
.clip-cform .cap.cc  { animation: cfC 15s infinite; }
@keyframes cfA { 0%,30%{opacity:1} 34%,100%{opacity:0} }
@keyframes cfB { 0%,33%{opacity:0} 37%,63%{opacity:1} 67%,100%{opacity:0} }
@keyframes cfC { 0%,66%{opacity:0} 70%,97%{opacity:1} 100%{opacity:0} }
.clip-cform .m-pdf { animation: pdfRise 15s infinite; }
@keyframes pdfRise {
  0%,34%   { opacity:0; transform: translate(-50%, calc(-50% + 60px)); }
  41%,63%  { opacity:1; transform: translate(-50%, -50%); }
  67%,100% { opacity:0; transform: translate(-50%, calc(-50% + 60px)); }
}
.clip-cform .m-stamp { animation: stampIn 15s infinite; }
@keyframes stampIn {
  0%,67% { opacity:0; transform: rotate(-14deg) scale(2.4); }
  71%    { opacity:1; transform: rotate(-14deg) scale(.92); }
  75%,97%{ opacity:1; transform: rotate(-14deg) scale(1); }
  100%   { opacity:0; }
}
.clip-cform .row-add { animation: rowDrop 15s infinite; }
@keyframes rowDrop {
  0%,10% { opacity:0; transform: translateY(8px); }
  16%,30%{ opacity:1; transform: none; }
  34%,100%{ opacity:0; }
}

/* ---- Inventory clip timeline (10s, two phases) ---- */
.clip-inv .frame.a { animation: ivA 10s infinite; }
.clip-inv .frame.b { animation: ivB 10s infinite; }
.clip-inv .cap.ca  { animation: ivA 10s infinite; }
.clip-inv .cap.cb  { animation: ivB 10s infinite; }
@keyframes ivA { 0%,45%{opacity:1} 50%,100%{opacity:0} }
@keyframes ivB { 0%,50%{opacity:0} 54%,96%{opacity:1} 100%{opacity:0} }
.clip-inv .newrow td { animation: newRow 10s infinite; }
@keyframes newRow {
  0%,53% { background: rgba(127,208,138,0); }
  57%    { background: rgba(127,208,138,.5); }
  64%,96%{ background: rgba(127,208,138,.12); }
  100%   { background: rgba(127,208,138,0); }
}
.clip-inv .newrow { animation: newRowIn 10s infinite; }
@keyframes newRowIn {
  0%,53% { opacity:0; transform: translateX(-12px); }
  58%,96%{ opacity:1; transform: none; }
  100%   { opacity:0; }
}

@media (prefers-reduced-motion: reduce) {
  .clip-screen .frame, .clip-caps .cap, .m-pdf, .m-stamp, .row-add,
  .clip-inv .newrow, .clip-inv .newrow td { animation: none !important; }
  .clip-screen .frame.a { opacity: 1; }        /* show first step statically */
  .clip-caps .cap.ca { opacity: 1; }
  .caret { animation: none; }
}


/* ── XRD Agent ──────────────────────────────────────────────────────────── */
.xrd-wb { display:flex; flex-direction:column; gap:14px; }
.xrd-grid { display:grid; grid-template-columns:minmax(0, 290px) minmax(0, 1fr); gap:16px; align-items:start; }
.xrd-side { display:flex; flex-direction:column; gap:14px; }
.xrd-card { padding:16px 16px 18px; }
.xrd-card-t { font-size:13px; font-weight:700; color: var(--ink); margin-bottom:12px;
  text-shadow:0 -1px 0 rgba(0,0,0,.5); }
.xrd-card .fld-l { display:flex; justify-content:space-between; font-size:12px; color:var(--ink-soft);
  margin:12px 0 6px; }
.xrd-card .fld-l b { color: var(--aqua-ink); }
.xrd-inp, .xrd-num { width:100%; height:34px; border-radius:8px; padding:0 10px; font-size:12.5px;
  color: var(--ink-invert); background:linear-gradient(var(--surface-lo),#131417); border:1px solid #000;
  box-shadow:0 2px 4px rgba(0,0,0,.6) inset; }
.xrd-num { height:28px; }
.xrd-rng { width:100%; accent-color:var(--aqua); }
.xrd-chk { display:flex; align-items:center; gap:6px; font-size:12.5px; color:var(--ink-soft); }
.xrd-main { display:flex; flex-direction:column; gap:16px; min-width:0; }
.xrd-plot-card { padding:14px 16px; }
.xrd-plot { width:100%; height:440px; }
.xrd-tables { display:grid; grid-template-columns:1fr; gap:16px; }
.xrd-tbl-card { padding:14px 16px; }
.xrd-tbl { width:100%; border-collapse:collapse; font-size:12.5px; }
.xrd-tbl th { text-align:left; color:var(--ink-faint); font-size:11px; text-transform:uppercase;
  letter-spacing:.5px; padding:8px 10px; border-bottom:1px solid var(--hairline);
  position:sticky; top:0; background:var(--surface); }
.xrd-tbl td { padding:8px 10px; border-bottom:1px solid rgba(255,255,255,.04); color: var(--ink-soft); }
.xrd-tbl tr.top td { background:rgba(55,200,113,.10); color: var(--ink-invert); font-weight:600; }


/* ── Rietveld Agent ─────────────────────────────────────────────────────── */
.riet-tabs { display:flex; align-items:center; gap:6px; margin-bottom:12px; }
.riet-tab { background:none; border:1px solid transparent; color:var(--ink-soft); font-size:12.5px;
  font-weight:600; padding:7px 14px; border-radius:8px 8px 0 0; cursor:pointer; }
.riet-tab:hover { color: var(--ink-invert); background:rgba(255,255,255,.04); }
.riet-tab.active { color: var(--ink-invert); background:linear-gradient(var(--surface-hi),var(--surface));
  border-color:var(--panel-edge); box-shadow:0 -2px 0 var(--aqua) inset; }
.riet-pane { display:none; }
.riet-pane.active { display:block; }
.riet-rf { display:flex; gap:14px; }
.riet-kv { font-size:12px; color:var(--ink-soft); background:rgba(255,255,255,.04);
  border:1px solid var(--hairline); border-radius:8px; padding:4px 10px; }
.riet-kv b { color: var(--aqua-ink); }
.riet-wt { display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
.riet-chip { font-size:12px; color: var(--ink-soft); border:1px solid var(--panel-edge); border-left-width:3px;
  border-radius:8px; padding:5px 10px; background:rgba(255,255,255,.03); }
.riet-chip b { color: var(--ink-invert); }
.riet-an-top { display:flex; align-items:center; gap:12px; margin-bottom:8px; flex-wrap:wrap; }
.riet-an-res { display:flex; gap:10px; flex-wrap:wrap; margin-left:auto; }
.riet-flag { font-size:10.5px; font-weight:700; color:#3a2c00; background:linear-gradient(#ffe08a,#f6be3f);
  border-radius:6px; padding:1px 7px; }
/* phase builder rows */
.riet-phase { border:1px solid var(--panel-edge); border-radius:10px; padding:10px; margin-bottom:8px;
  background:rgba(255,255,255,.02); }
.riet-phase-hd { display:flex; gap:8px; align-items:center; margin-bottom:8px; }
.riet-phase-hd .ph-type { flex:1; }
.riet-del { width:28px; height:28px; flex:0 0 auto; border-radius:7px; cursor:pointer; color: var(--bad-ink);
  background:rgba(255,90,82,.12); border:1px solid rgba(255,90,82,.35); font-size:13px; }
.riet-del:hover { background:rgba(255,90,82,.22); }
.riet-phase-grid { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.riet-phase-grid .xrd-inp { height:32px; font-size:12px; }


/* ── Profile banner ─────────────────────────────────────────────────────────
   The block that opens the Virtual Lab home and every researcher profile: a
   cover the owner can replace, an avatar straddling its lower edge, and the
   four counts that open a list when clicked. Rendered by
   templates/partials/profile_header.html. */

.pfh {
  --pfh-cover: 210px;                 /* cover height; the avatar hangs off it */
  --pfh-av: 132px;
  position: relative; display: flex; flex-direction: column; margin-bottom: 20px;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius);
  box-shadow: 0 1px 0 rgba(255,255,255,.05) inset, 0 6px 16px rgba(0,0,0,.4);
}

/* Cover. An uploaded banner arrives as an inline background-image and simply
   paints over the default glow. */
.pfh-cover {
  position: relative; height: var(--pfh-cover); border-bottom: 1px solid #000;
  border-radius: var(--radius) var(--radius) 0 0;
  background-color: var(--well); background-size: cover; background-position: center;
  background-image:
    radial-gradient(900px 320px at 18% -30%, rgba(61,129,246,.38), transparent 70%),
    radial-gradient(700px 280px at 88% 130%, rgba(106,63,214,.34), transparent 70%),
    linear-gradient(125deg, #101620, #1a1f2a);
}
.pfh-cover-set { position: absolute; top: 12px; right: 12px; }
.pfh-chip {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  padding: 7px 12px; border-radius: var(--radius-pill); font-size: 12px; font-weight: 600;
  color: #e8edf5; background: rgba(10,12,16,.55); backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,.14); transition: background .15s;
}
.pfh-chip:hover { background: rgba(10,12,16,.78); }
.pfh-chip svg { width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* Avatar — half on the cover, half on the panel below it. */
.pfh-av { position: absolute; left: 26px; bottom: calc(var(--pfh-av) / -2); }
.pfh-av-img {
  width: var(--pfh-av); height: var(--pfh-av); border-radius: 50%;
  background-color: var(--avatar-bg); background-size: cover; background-position: center;
  border: 4px solid var(--surface-hi); box-shadow: 0 8px 24px rgba(0,0,0,.6);
}
.pfh-av-initial { display: grid; place-items: center; font-size: 52px; font-weight: 800;
  color: #fff; background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.pfh-av-btn {
  position: absolute; right: 4px; bottom: 6px; display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  color: #eaf1ff; background: linear-gradient(var(--aqua), var(--aqua-dark));
  border: 2px solid var(--surface-hi); box-shadow: 0 3px 10px rgba(0,0,0,.5);
  transition: transform .15s;
}
.pfh-av-btn:hover { transform: scale(1.08); }
.pfh-av-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* Name row. Its left padding is what keeps text clear of the avatar. */
.pfh-id {
  display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap;
  padding: 16px 20px 18px calc(26px + var(--pfh-av) + 22px);
  min-height: calc(var(--pfh-av) / 2);
}
.pfh-id .spacer { flex: 1; }
.pfh-who h2 { margin: 0; font-size: 24px; font-weight: 800; color: var(--ink-strong);
  text-shadow: 0 -1px 0 rgba(0,0,0,.7); }
.pfh-handle { font-size: 13px; color: var(--aqua-bright); margin: 2px 0 5px; }
.pfh-desig { font-size: 13px; color: var(--ink-soft); }
.pfh-exp { font-size: 12px; color: var(--ink-faint); margin-top: 3px; }
.pfh-act form { margin: 0; }

/* A researcher card that is also a link to their profile. */
.rg-link { text-decoration: none; color: inherit;
  transition: border-color .15s, transform .12s; }
.rg-link:hover { border-color: var(--aqua); transform: translateY(-2px); }

@media (max-width: 860px) {
  .pfh { --pfh-cover: 150px; --pfh-av: 96px; }
  .pfh-id { padding-left: calc(20px + var(--pfh-av) + 16px); }
  .pfh-av { left: 20px; }
  .pfh-who h2 { font-size: 20px; }
}

@media (max-width: 560px) {
  /* Narrower still: centre the avatar and let everything stack. */
  .pfh-av { left: 50%; transform: translateX(-50%); }
  .pfh-id { flex-direction: column; align-items: center; text-align: center;
    padding: calc(var(--pfh-av) / 2 + 14px) 18px 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .rg-link:hover, .pfh-av-btn:hover { transform: none; }
}


/* ── Cite buttons, search results, and the new-user home ────────────────────
   A citation is a request: the button says Cite, then Requested, then Citing.
   `relation` comes down with each search result so the label is right on the
   first paint. */

.tb-res-head { padding: 7px 12px 5px; font-size: 10.5px; font-weight: 700;
  letter-spacing: .6px; text-transform: uppercase; color: var(--ink-faint);
  background: rgba(0,0,0,.25); border-bottom: 1px solid rgba(0,0,0,.4); }
.tb-res-body { flex: 1 1 auto; min-width: 0; text-decoration: none; color: inherit; }
.tb-res-body:hover b { color: var(--ink-invert); text-decoration: underline; }
/* Name and handle each truncate, so a long name shrinks the text column instead
   of shoving the Invite/Cite buttons out of their right-hand column. */
.tb-res-body b, .tb-res-body small { display: block; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
/* Every action pinned to the right, side by side, never wrapping. Uniform
   width so a row with two actions and a row with one still line up in columns
   packed from the right edge — no zig-zag from differing button widths. */
.tb-res .tb-cite, .tb-res .tb-tag {
  flex: 0 0 auto; align-self: center; box-sizing: border-box;
  min-width: 76px; height: 26px; padding: 0 10px;
  display: inline-flex; align-items: center; justify-content: center; text-align: center;
}

.tb-cite {
  flex: none; padding: 4px 11px; border-radius: var(--radius-pill); cursor: pointer;
  font: inherit; font-size: 11px; font-weight: 700; color: #eaf2ff;
  background: linear-gradient(var(--aqua), var(--aqua-dark));
  border: 1px solid rgba(255,255,255,.14); transition: transform .12s, filter .12s;
}
.tb-cite:hover { transform: translateY(-1px); filter: brightness(1.08); }
.tb-cite[disabled] { opacity: .6; cursor: progress; transform: none; }
.tb-cite.decline { background: linear-gradient(#4a4d54, #34373d); color: #d8dde5; }
.tb-tag { flex: none; font-size: 10.5px; font-weight: 700; color: var(--ink-faint);
  padding: 4px 9px; border-radius: var(--radius-pill);
  border: 1px solid var(--panel-edge); background: rgba(0,0,0,.25); white-space: nowrap; }

/* A request in the flask carries its own answer. */
.tb-nask { background: rgba(61,129,246,.07); }
.tb-nask-act { display: flex; gap: 6px; margin-top: 7px; }

/* The home page of someone who is not in a lab yet. */
.nl-hero { max-width: 680px; margin: 0 auto; text-align: center; }
.nl-hero h1 { margin: 6px 0 10px; font-size: var(--fs-700); font-weight: 800;
  color: var(--ink-strong); text-shadow: 0 -1px 0 rgba(0,0,0,.7); }
.nl-hero > p { margin: 0 auto 22px; max-width: 560px; color: var(--ink-soft);
  font-size: var(--fs-400); line-height: 1.75; }
.nl-search-btn { font-size: var(--fs-300); padding: 10px 20px; }

.nl-steps { display: grid; gap: 12px; margin: 26px 0 20px; text-align: left; }
.nl-step { display: flex; gap: 13px; align-items: flex-start; padding: 14px 16px;
  border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  background: linear-gradient(var(--surface-hi), var(--surface)); }
.nl-step .nl-n { flex: none; display: grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; font-size: 12px; font-weight: 800; color: #fff;
  background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.nl-step b { display: block; color: var(--ink); font-size: 13.5px; margin-bottom: 3px; }
.nl-step small { color: var(--ink-soft); font-size: 12.5px; line-height: 1.6; }
.nl-foot { color: var(--ink-faint); font-size: var(--fs-200); line-height: 1.7; }
.nl-foot b { color: var(--aqua-bright); }

/* A cite-back offer: no answer required, so it reads quieter than a request. */
.tb-ntip { background: rgba(127,208,138,.06); }
.tb-ntip .tb-nic { color: var(--ok); }


/* ── Post grid ──────────────────────────────────────────────────────────────
   A profile's posts as squares. The corner glyph says which kind it is —
   lines for text, a framed picture, a play button for video. No labels. */
.pg { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.pg-cell { position: relative; aspect-ratio: 1; overflow: hidden; display: block;
  border-radius: var(--radius); text-decoration: none; background: var(--surface-lo);
  border: 1px solid var(--panel-edge); transition: transform .12s, border-color .12s; }
.pg-cell:hover { transform: translateY(-2px); border-color: var(--aqua); }
.pg-cell img, .pg-cell video { width: 100%; height: 100%; object-fit: cover; display: block; }
.pg-text { display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical;
  overflow: hidden; padding: 16px; font-size: 13px; line-height: 1.55; color: var(--ink-soft); }
.pg-cell.pg-text { background: linear-gradient(150deg, var(--surface-hi), var(--surface-lo)); }

.pg-mark { position: absolute; top: 8px; right: 8px; display: grid; place-items: center;
  width: 24px; height: 24px; border-radius: 50%; color: #fff;
  background: rgba(8,10,14,.6); backdrop-filter: blur(6px); }
.pg-mark svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.pg-meta { position: absolute; left: 0; right: 0; bottom: 0; padding: 16px 10px 7px;
  font-size: 11px; color: #eef1f6; opacity: 0; transition: opacity .15s;
  background: linear-gradient(transparent, rgba(0,0,0,.75)); }
.pg-cell:hover .pg-meta { opacity: 1; }

.post-box { margin-top: 18px; }

@media (prefers-reduced-motion: reduce) { .pg-cell:hover { transform: none; } }

/* ── Mode toggle + lab picker ───────────────────────────────────────────────
   Lab or Public, and — when someone belongs to more than one — which lab they
   are working in. Both sized to sit inside the 48px ribbon. */
.tb-mode { display: flex; gap: 2px; flex-shrink: 0; margin-left: 14px; padding: 3px;
  border-radius: var(--radius-pill); background: rgba(0,0,0,.28);
  border: 1px solid rgba(255,255,255,.08); }
.tb-mode a { padding: 4px 13px; border-radius: var(--radius-pill); font-size: 11.5px;
  font-weight: 700; color: var(--ink-soft); text-decoration: none; white-space: nowrap; }
.tb-mode a:hover { background: rgba(255,255,255,.08); color: #e6eaf1; }
.tb-mode a.on { color: var(--ink-invert);
  background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark));
  box-shadow: 0 1px 0 rgba(255,255,255,.3) inset, 0 1px 3px rgba(0,0,0,.4); }

.tb-lab-name { flex-shrink: 0; margin-left: 8px; padding: 5px 12px; font-size: 12px;
  font-weight: 700; color: var(--ink-soft); white-space: nowrap; border-radius: var(--radius-pill);
  background: rgba(0,0,0,.25); border: 1px solid rgba(255,255,255,.08); }

.tb-pick { position: relative; flex-shrink: 0; margin-left: 8px; }
.tb-pick-btn { display: flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 5px 10px 5px 12px; border-radius: var(--radius-pill); font: inherit;
  font-size: 12px; font-weight: 700; color: var(--ink-soft); white-space: nowrap;
  background: rgba(0,0,0,.25); border: 1px solid rgba(255,255,255,.10);
  max-width: 210px; }
.tb-pick-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tb-pick-btn:hover { background: rgba(0,0,0,.42); border-color: rgba(255,255,255,.2); }
.tb-pick-btn svg { width: 12px; height: 12px; flex: none; color: #9aa3b0; }
.tb-pick-btn[aria-expanded="true"] svg { transform: rotate(180deg); }

.tb-pick-menu { position: absolute; top: 38px; left: 0; width: 290px; z-index: 130;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: 10px;
  box-shadow: 0 18px 44px rgba(0,0,0,.6); overflow: hidden; }
.tb-pick-menu[hidden] { display: none; }
.tb-pick-menu a { display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  text-decoration: none; color: var(--ink-soft); border-bottom: 1px solid rgba(0,0,0,.35); }
.tb-pick-menu a:last-child { border-bottom: none; }
.tb-pick-menu a:hover { background: rgba(255,255,255,.06); }
.tb-pick-menu a.on { background: rgba(61,129,246,.14); }
.tb-pick-menu a.on b { color: var(--aqua-ink); }
.tb-pick-ico { font-size: 16px; }
.tb-pick-body { flex: 1; min-width: 0; }
.tb-pick-body b { display: block; font-size: 12.5px; }
.tb-pick-body small { color: var(--aqua-bright); font-size: 11px; }
.tb-pick-n { font-size: 11px; color: var(--ink-faint); }

@media (max-width: 1180px) { .tb-mode a { padding: 4px 9px; } }
@media (max-width: 1000px) { .tb-lab-name, .tb-pick { display: none; } }

/* ── Tags, and owning your own posts ────────────────────────────────────────
   A post can name the people and labs it is about. Tags are stored as
   kind + id, so a rename never strands the link. */
.tagbar { display: flex; flex-wrap: wrap; gap: 6px; margin: 9px 0 0; }
.tag { display: inline-flex; align-items: center; gap: 5px; padding: 3px 6px 3px 9px;
  border-radius: var(--radius-pill); font-size: 11.5px; font-weight: 600;
  color: var(--aqua-ink); background: rgba(61,129,246,.14);
  border: 1px solid rgba(61,129,246,.3); }
.tag-lab { color: var(--ok-ink); background: rgba(127,208,138,.13);
  border-color: rgba(127,208,138,.3); }
.tag-x { border: none; background: none; cursor: pointer; color: inherit;
  font-size: 14px; line-height: 1; opacity: .7; padding: 0 2px; }
.tag-x:hover { opacity: 1; }

.tagpick { position: relative; margin-top: 9px; padding: 9px; border-radius: var(--radius);
  border: 1px solid var(--panel-edge); background: rgba(0,0,0,.28); }
.tagpick[hidden] { display: none; }
.tagpick input { width: 100%; height: 30px; padding: 0 11px; font-size: 12.5px;
  color: #eef1f6; border-radius: var(--radius-pill); border: 1px solid #000;
  background: linear-gradient(#141518, #1b1c20); box-sizing: border-box; }
.tagpick input:focus { border-color: var(--aqua); outline: none;
  box-shadow: 0 0 0 3px var(--aqua-glow); }
.tagpick-list { max-height: 180px; overflow-y: auto; margin-top: 7px; }
.tagpick-row { display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 7px 10px; border: none; border-radius: 7px; font: inherit; font-size: 12.5px;
  color: var(--ink-soft); background: transparent; }
.tagpick-row:hover { background: rgba(255,255,255,.07); }
.tagpick-row small { color: var(--ink-faint); }

/* Post tags as rendered on a post. */

/* The ⋯ on your own square. */
.pg-wrap { position: relative; }
.pg-own { position: absolute; top: 6px; left: 6px; z-index: 2; }
.pg-dots { display: grid; place-items: center; width: 24px; height: 24px; padding: 0;
  border-radius: 50%; cursor: pointer; font-size: 15px; line-height: 1; color: #fff;
  background: rgba(8,10,14,.6); border: 1px solid rgba(255,255,255,.14);
  backdrop-filter: blur(6px); }
.pg-dots:hover { background: rgba(8,10,14,.85); }

.pg-edit { position: absolute; inset: 0; z-index: 3; display: flex; flex-direction: column;
  gap: 8px; padding: 10px; border-radius: var(--radius); overflow-y: auto;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--aqua); box-shadow: 0 14px 34px rgba(0,0,0,.6); }
.pg-edit[hidden] { display: none; }
.pg-edit textarea { width: 100%; box-sizing: border-box; resize: none; font: inherit;
  font-size: 12.5px; padding: 8px 10px; border-radius: 8px; color: var(--ink);
  background: rgba(0,0,0,.35); border: 1px solid var(--panel-edge); }
.pg-edit-row { display: flex; align-items: center; gap: 6px; font-size: 11px; }
.pg-del { margin-top: auto; }
.btn.danger { color: #ffd9d6; background: linear-gradient(#8d3a34, #6d2b26);
  border-color: #4c1f1b; }
.btn.danger:hover { background: linear-gradient(#a34840, #7d322c); }

/* The delete-account panel. Set apart deliberately: it is the one control on
   the page that cannot be undone, and it should not look like the ones above
   it that can. */
.danger-panel { border-color: #5c130d; }
.danger-panel .panel-head { color: #ffd9d6;
  background: linear-gradient(rgba(141,58,52,.35), rgba(109,43,38,.25)); }

/* ── Agent menu + the tabs inside each agent ────────────────────────────────
   One entry per agent in the title bar. A dashboard, a vendor list or an
   import screen belongs to an agent, so it lives inside that agent's own tab
   strip rather than in a permanent tree down the side. */
.tb-agent { position: relative; flex-shrink: 0; }
.tb-agent-btn { display: flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 5px 10px 5px 13px; border-radius: var(--radius-pill); font: inherit;
  font-size: 12px; font-weight: 700; color: var(--ink-soft); white-space: nowrap;
  background: rgba(0,0,0,.25); border: 1px solid rgba(255,255,255,.10); }
.tb-agent-btn:hover { background: rgba(0,0,0,.42); border-color: rgba(255,255,255,.2); }
.tb-agent-btn svg { width: 12px; height: 12px; flex: none; color: #9aa3b0; }
.tb-agent-btn[aria-expanded="true"] svg { transform: rotate(180deg); }
.tb-agent-btn:focus-visible { outline: 2px solid var(--aqua-light); outline-offset: 2px; }

.tb-agent-menu { position: absolute; top: 38px; right: 0; width: 250px; z-index: 130;
  padding: 6px; background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  box-shadow: 0 18px 44px rgba(0,0,0,.6); }
.tb-agent-menu[hidden] { display: none; }
.tb-agent-menu a { display: flex; align-items: center; gap: 10px; padding: 9px 11px;
  border-radius: 8px; text-decoration: none; color: var(--ink); font-size: 12.5px;
  font-weight: 600; }
.tb-agent-menu a:hover { background: rgba(255,255,255,.06); color: var(--ink-invert); }
.tb-agent-menu a.on { color: var(--ink-invert);
  background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark));
  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset; }
.tb-agent-menu a.on .pro-tag { background: rgba(255,255,255,.85); }
.ag-ico { width: 20px; text-align: center; font-size: 15px; }
.tb-agent-sep { height: 1px; margin: 6px 4px; background: var(--panel-edge);
  border-bottom: 1px solid var(--hairline); }

/* An agent's own screens. */
/* One row: where you are, and what you are looking for. */
.agent-bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 14px; }
.agent-bar > .agent-tabs { margin-bottom: 0; }
.agent-tabs { display: flex; gap: 3px; flex-wrap: wrap; margin-bottom: 14px;
  padding: 4px; width: fit-content; max-width: 100%;
  border-radius: var(--radius-pill); border: 1px solid var(--panel-edge);
  background: linear-gradient(var(--surface-hi), var(--surface)); }
.agent-tabs a { padding: 6px 15px; border-radius: var(--radius-pill); font-size: 12.5px;
  font-weight: 600; color: var(--ink-soft); text-decoration: none; white-space: nowrap; }
.agent-tabs a:hover { background: rgba(255,255,255,.06); color: var(--ink); }
.agent-tabs a.on { color: var(--ink-invert); font-weight: 700;
  background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark));
  box-shadow: 0 1px 0 rgba(255,255,255,.3) inset, 0 1px 3px rgba(0,0,0,.4); }
/* The page's name, in the strip rather than on a row of its own. */
.agent-tabs-title { align-self: center; margin: 0 8px 0 12px; padding-right: 12px;
  font-size: 15px; font-weight: 700; letter-spacing: -.02em; white-space: nowrap;
  color: var(--ink-strong); border-right: 1px solid var(--panel-edge); }

/* ── Add a paper ────────────────────────────────────────────────────────────
   Two ways in that earn their space, and the rare ones folded underneath. */
.add-ways { max-width: 680px; }
.add-way { padding: 18px 20px; border: 1px solid var(--panel-edge);
  border-radius: var(--radius); background: var(--surface-lo); }
.add-way h2 { margin: 0 0 12px; font-size: 15px; letter-spacing: -.02em; color: var(--ink-strong); }
.add-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.add-row input { flex: 1; min-width: 220px; }
.add-doi { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.add-note { margin: 10px 0 0; font-size: 12px; line-height: 1.5; }
.add-or { display: flex; align-items: center; gap: 12px; margin: 14px 0;
  font-size: 12px; color: var(--ink-faint); }
.add-or::before, .add-or::after { content: ''; flex: 1; height: 1px; background: var(--panel-edge); }
.add-more { margin-top: 18px; }
.add-more summary { padding: 8px 2px; font-size: 12.5px; color: var(--ink-soft); cursor: pointer; }
.add-more summary:hover { color: var(--ink); }
.add-more > form { margin-top: 10px; padding: 16px 18px; border: 1px solid var(--panel-edge);
  border-radius: var(--radius); background: var(--surface-lo); }

/* ── Framing a cover ────────────────────────────────────────────────────────
   A chosen picture is previewed from the browser's own copy and dragged into
   place before anything is uploaded, so the framing is decided first. */
.pfh-cover-idle { display: flex; gap: 8px; }
.pfh-cover-edit { display: flex; align-items: center; gap: 8px; }
/* Both rows set display:flex, which beats the browser's own [hidden] rule — so
   each needs its own. Without this the idle row stayed on screen during
   framing and Save/Cancel appeared underneath it, where a click meant for
   Save landed on Cancel and quietly restored the old position. */
.pfh-cover-idle[hidden], .pfh-cover-edit[hidden] { display: none; }
.pfh-hint { font-size: 11.5px; font-weight: 600; color: #eaf1ff; padding: 6px 11px;
  border-radius: var(--radius-pill); background: rgba(8,10,14,.6);
  backdrop-filter: blur(8px); border: 1px solid rgba(255,255,255,.12); }
.pfh-chip-go { color: #fff !important;
  background: linear-gradient(var(--aqua), var(--aqua-dark)) !important;
  border-color: rgba(255,255,255,.2) !important; }
button.pfh-chip { font: inherit; }

/* While framing: grab-to-move, and the frame edges made obvious. */
.pfh-cover.framing { cursor: grab; touch-action: none;
  outline: 2px dashed rgba(169,204,255,.65); outline-offset: -6px; }
.pfh-cover.framing:active { cursor: grabbing; }
.pfh-cover.framing::after { content: ""; position: absolute; inset: 0;
  pointer-events: none; border-radius: inherit;
  box-shadow: 0 0 0 100vmax rgba(0,0,0,.28) inset; }

/* A picture that only overflows one way can only be dragged that way. */
.pfh-cover.framing.lock-x.lock-y { cursor: not-allowed; }
.pfh-cover.framing.lock-x:not(.lock-y) { cursor: ns-resize; }
.pfh-cover.framing.lock-y:not(.lock-x) { cursor: ew-resize; }

/* An Invite button reads a touch different from Cite — it grants lab access. */
.tb-cite.invite { background: linear-gradient(#3fa45f, #2b7d45); }

/* ── Invite-to-lab, on a profile ────────────────────────────────────────────
   Only labs the viewer runs are offered; picking one sends the invitation. */
.pfh-invite { position: relative; display: inline-block; }
.btn.invite { color: #eafff0; background: linear-gradient(#3fa45f, #2b7d45);
  border-color: #256b3b; }
.btn.invite:hover { filter: brightness(1.08); }
.pfh-invite-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 40;
  min-width: 220px; padding: 6px; border-radius: var(--radius-lg);
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); box-shadow: 0 18px 44px rgba(0,0,0,.6); }
.pfh-invite-menu[hidden] { display: none; }
.pfh-invite-head { padding: 7px 10px 8px; font-size: 11px; font-weight: 700;
  letter-spacing: .4px; text-transform: uppercase; color: var(--ink-faint); }
.pfh-invite-menu form { margin: 0; }
.pfh-invite-menu button { display: flex; align-items: center; gap: 9px; width: 100%;
  text-align: left; padding: 9px 11px; border: none; border-radius: 8px; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--ink-soft); background: transparent; }
.pfh-invite-menu button:hover { background: rgba(255,255,255,.06); color: var(--ink-invert); }
.pfh-invite-done { padding: 8px 11px; font-size: 12px; color: var(--ink-faint); }

/* ── Add-member modal: invite existing vs create new ────────────────────────*/
.mm-tabs { display: flex; gap: 3px; margin-bottom: 14px; padding: 4px;
  border-radius: var(--radius-pill); border: 1px solid var(--panel-edge);
  background: rgba(0,0,0,.25); width: fit-content; }
.mm-tabs button { padding: 6px 16px; border: none; border-radius: var(--radius-pill);
  cursor: pointer; font: inherit; font-size: 12.5px; font-weight: 700;
  color: var(--ink-soft); background: transparent; }
.mm-tabs button.on { color: var(--ink-invert);
  background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark)); }
.mm-search input { width: 100%; height: 36px; padding: 0 12px; box-sizing: border-box;
  border-radius: 9px; border: 1px solid #000; color: #eef1f6;
  background: linear-gradient(#141518, #1b1c20); font-size: 13px; }
.mm-search input:focus { border-color: var(--aqua); outline: none;
  box-shadow: 0 0 0 3px var(--aqua-glow); }
.mm-results { margin-top: 8px; max-height: 260px; overflow-y: auto; }
.mm-row { display: flex; align-items: center; gap: 11px; padding: 8px 6px;
  border-bottom: 1px solid rgba(0,0,0,.35); }
.mm-av { width: 34px; height: 34px; border-radius: 50%; flex: none;
  background-size: cover; background-position: center; }
.mm-avi { display: grid; place-items: center; font-weight: 800; color: #fff;
  background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.mm-who { flex: 1; min-width: 0; }
.mm-who b { display: block; font-size: 13px; color: var(--ink); }
.mm-who small { color: var(--ink-faint); font-size: 11.5px; }
.mm-tag { font-size: 11px; font-weight: 700; color: var(--ink-faint);
  padding: 4px 10px; border-radius: var(--radius-pill);
  border: 1px solid var(--panel-edge); background: rgba(0,0,0,.25); white-space: nowrap; }
.mm-empty { padding: 16px; text-align: center; color: var(--ink-faint); font-size: 12.5px; }

/* Per-lab access rows inside the profile invite menu. */
.pfh-lab-row { display: flex; align-items: center; gap: 12px; padding: 8px 10px;
  border-bottom: 1px solid rgba(0,0,0,.3); }
.pfh-lab-row:last-child { border-bottom: none; }
.pfh-lab-nm { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; color: var(--ink-soft); }
.pfh-lab-row form { margin: 0; }
.pfh-mini { padding: 4px 12px; border-radius: var(--radius-pill); cursor: pointer;
  font: inherit; font-size: 11.5px; font-weight: 700; white-space: nowrap;
  color: var(--ink-soft); background: rgba(255,255,255,.06);
  border: 1px solid var(--panel-edge); }
.pfh-mini:hover { color: var(--ink-invert); background: rgba(255,255,255,.12); }
.pfh-mini.go { color: #eafff0; background: linear-gradient(#3fa45f, #2b7d45);
  border-color: #256b3b; }
.pfh-mini.danger { color: #ffd9d6; background: linear-gradient(#8d3a34, #6d2b26);
  border-color: #4c1f1b; }


/* ═══════════════════════════════════════════════════════════════════════════
   LIGHT THEME
   The app is dark by design; this repaints it for [data-theme="light"]. Tokens
   flip first (everything token-based follows), then the hardcoded skeuomorphic
   surfaces — the metal chrome, the dark gradient bars, the sunken inputs — are
   overridden by hand, since those never referenced a token.
   ═════════════════════════════════════════════════════════════════════════ */

:root[data-theme="light"] {
  --ink-strong: #0f1626;
  --ink:        #1c2434;
  --ink-soft:   #46536b;
  --ink-faint:  #71809a;
  --ok:         #0c9a89;
  --aqua-bright:#1a5fd6;

  /* The flip. Each is dark enough to read as ink on white and on its own
     tinted pill — which is what pale-on-pale was failing at. */
  --ink-invert: #0f1626;
  --ok-ink:     #0a7250;
  --warn-ink:   #8a5206;
  --bad-ink:    #b42318;
  --aqua-ink:   #1a5fd6;

  /* A well on light is lighter than the page, not darker: an inset area reads
     as recessed by being paler here and darker on dark. */
  --well:       #e9edf4;
  --well-deep:  #dfe4ec;
  --avatar-bg:  #dde3ec;
  --row:        #ffffff;
  --row-alt:    #f4f7fc;
  --row-hover:  #e6eefb;

  --bg:         #eef1f6;
  --surface:    #ffffff;
  --surface-hi: #ffffff;
  --surface-lo: #f3f6fb;
  --panel-edge: #d7dde7;
  --hairline:   rgba(16,24,40,.08);

  --metal-top:  #fbfcfe;
  --metal-hi:   #eef2f7;
  --metal-mid:  #e7ecf3;
  --metal-lo:   #dbe2ec;
}

/* Page + content ground */
:root[data-theme="light"] body {
  background-color: #e7ebf2;
  background-image: radial-gradient(circle at 50% -10%, #f4f7fb, #e7ebf2 60%, #dfe4ec 100%);
}
[data-theme="light"] .content {
  background: radial-gradient(120% 60% at 50% 0, #f6f8fc, #eef1f6 60%, #e7ebf2 100%);
}

/* Title bar: light metal, dark text */
[data-theme="light"] .titlebar { border-bottom: 1px solid #cfd6e1;
  box-shadow: 0 1px 0 rgba(255,255,255,.7) inset, 0 1px 2px rgba(16,24,40,.06); }
[data-theme="light"] .tb-brand span { color: #16203a; text-shadow: none; }
[data-theme="light"] .titlebar .tb-search input,
[data-theme="light"] .tagpick input,
[data-theme="light"] .mm-search input {
  color: #16203a; background: #fff; border: 1px solid #cfd6e1;
  box-shadow: 0 1px 2px rgba(16,24,40,.06) inset; }
[data-theme="light"] .tb-mode, [data-theme="light"] .tb-stats,
[data-theme="light"] .tb-pick-btn, [data-theme="light"] .tb-agent-btn,
[data-theme="light"] .tb-me-btn {
  background: #eef2f7; border-color: #d7dde7; }
[data-theme="light"] .tb-mode a, [data-theme="light"] .tb-stat,
[data-theme="light"] .tb-pick-btn, [data-theme="light"] .tb-agent-btn,
[data-theme="light"] .tb-lab-name { color: #46536b; }
[data-theme="light"] .tb-stat b { color: #16203a; }
[data-theme="light"] .tb-mode a:hover, [data-theme="light"] .tb-stat:hover,
[data-theme="light"] .tb-agent-menu a:hover, [data-theme="light"] .tb-menu a:not(.tb-menu-cta):hover,
[data-theme="light"] .tb-res:hover, [data-theme="light"] .tagpick-row:hover,
[data-theme="light"] .tb-pick-menu a:hover, [data-theme="light"] .mm-tabs button:hover {
  background: rgba(16,24,40,.06); color: #16203a; }

/* The dark gradient bars: panel/modal/menu/table heads → light */
[data-theme="light"] .panel > .panel-head,
[data-theme="light"] .modal-head,
[data-theme="light"] .tb-notif-head,
[data-theme="light"] .tb-pop-head,
[data-theme="light"] .m-tbl th,
[data-theme="light"] .wb-tree-head {
  background: linear-gradient(#f7f9fc, #eef2f7); color: #16203a;
  border-bottom: 1px solid #d7dde7; text-shadow: none; }

/* Panels, cards, dropdown surfaces */
[data-theme="light"] .panel,
[data-theme="light"] .rg-card,
[data-theme="light"] .tb-results, [data-theme="light"] .tb-menu,
[data-theme="light"] .tb-notif, [data-theme="light"] .tb-pop,
[data-theme="light"] .tb-pick-menu, [data-theme="light"] .tb-agent-menu,
[data-theme="light"] .pfh-invite-menu, [data-theme="light"] .modal-card,
[data-theme="light"] .pfh, [data-theme="light"] .pg-cell,
[data-theme="light"] .settings-nav, [data-theme="light"] .agent-tabs,
[data-theme="light"] .ws-switch, [data-theme="light"] .nl-step {
  background: #fff; border-color: #d7dde7;
  box-shadow: 0 1px 3px rgba(16,24,40,.08), 0 8px 22px rgba(16,24,40,.06); }

/* Inputs, selects, textareas */
[data-theme="light"] input, [data-theme="light"] select, [data-theme="light"] textarea,
[data-theme="light"] .l-field input, [data-theme="light"] .field input,
[data-theme="light"] .pg-edit textarea, [data-theme="light"] .post-box textarea {
  color: #16203a; background: #fff; border: 1px solid #cfd6e1;
  box-shadow: 0 1px 2px rgba(16,24,40,.05) inset; }
[data-theme="light"] input::placeholder, [data-theme="light"] textarea::placeholder { color: #98a4b8; }

/* Tables */
[data-theme="light"] table.grid th { background: linear-gradient(#f7f9fc, #eef2f7);
  color: #46536b; border-bottom: 1px solid #d7dde7; }
[data-theme="light"] .table-wrap { border-color: #d7dde7; }

/* Tabs (reader, references) */
[data-theme="light"] .rdr-tabs .rdr-tab,
[data-theme="light"] .l-auth-tabs a { background: linear-gradient(#f1f4f8, #e7ecf3); color: #46536b; }
[data-theme="light"] .rdr-tabs .rdr-tab.active,
[data-theme="light"] .l-auth-tabs a.active { color: #16203a; background: #fff; }

/* Small text pills / tags that used dark grounds */
[data-theme="light"] .tb-tag, [data-theme="light"] .mm-tag,
[data-theme="light"] .pfh-mini { background: #eef2f7; border-color: #d7dde7; color: #46536b; }
[data-theme="light"] .muted, [data-theme="light"] .tb-res small,
[data-theme="light"] .rg-handle { color: #71809a; }
[data-theme="light"] .rg-handle { color: #1a5fd6; }

/* Buttons that were dark-on-dark */
[data-theme="light"] .btn:not(.primary):not(.invite):not(.danger) {
  background: #fff; border: 1px solid #cfd6e1; color: #2b3550; }
[data-theme="light"] .btn:not(.primary):not(.invite):not(.danger):hover { background: #f3f6fb; }

/* Headings drop the dark emboss shadow */
[data-theme="light"] h1, [data-theme="light"] h2, [data-theme="light"] .lab-hero h1,
[data-theme="light"] .pfh-who h2, [data-theme="light"] .page-head h1 { text-shadow: none; }

/* The metal traffic-free chrome edges that used pure black borders */
[data-theme="light"] .titlebar .tb-search input { border-color: #cfd6e1; }

/* Toggle row in the account menu */
.tb-theme { display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 14px; border: none; background: transparent; cursor: pointer;
  font: inherit; font-size: 12.5px; color: var(--ink-soft); }
.tb-theme:hover { background: rgba(255,255,255,.06); color: var(--ink-invert); }
.tb-theme-ico { width: 16px; text-align: center; }
.tb-theme-state { margin-left: auto; font-size: 11px; font-weight: 700;
  color: var(--ink-faint); }
[data-theme="light"] .tb-theme { color: #46536b; }
[data-theme="light"] .tb-theme:hover { background: rgba(16,24,40,.06); color: #16203a; }

/* Light theme — text that was near-white now reads dark on light surfaces.
   These selectors set a bright colour directly, so each needs its own override
   (a child's own colour beats one set on the container). */
[data-theme="light"] .tb-menu-who b,
[data-theme="light"] .post-who,
[data-theme="light"] .post-text,
[data-theme="light"] .formcard h3,
[data-theme="light"] .lab-hero h1,
[data-theme="light"] .settings-nav a,
[data-theme="light"] .rg-name,
[data-theme="light"] .rdr-title,
[data-theme="light"] .wb-empty-card h2,
[data-theme="light"] .wb-ds-name,
[data-theme="light"] .wb-tab,
[data-theme="light"] .wb-results b,
[data-theme="light"] .pfh-who h2,
[data-theme="light"] .nl-step b,
[data-theme="light"] .mm-who b,
[data-theme="light"] .rg-body .rg-name,
[data-theme="light"] .pfh-lab-body b,
[data-theme="light"] .tb-lab-body b,
[data-theme="light"] .pfh-lab-nm,
[data-theme="light"] .pfh-desig,
[data-theme="light"] .pfh-handle,
[data-theme="light"] .rg-desig,
[data-theme="light"] .pfp-post-text,
[data-theme="light"] .feed-compose textarea,
[data-theme="light"] .tile .k, [data-theme="light"] .tile .v,
[data-theme="light"] .l-lab, [data-theme="light"] .field .lab,
[data-theme="light"] .pg-text { color: #1c2434; }

[data-theme="light"] .settings-nav a.active { color: #fff; }
[data-theme="light"] .pfh-handle, [data-theme="light"] .rdr-title { color: #1a5fd6; }

/* Members panel role pills and status pills keep contrast on light */
[data-theme="light"] .pill { filter: none; }

/* The post grid text tile ground */
[data-theme="light"] .pg-cell.pg-text {
  background: linear-gradient(150deg, #f5f8fc, #eef2f7); }
[data-theme="light"] .pg-cell { background: #f3f6fb; }

/* Sidebar-less content: page-head + generic body copy */
[data-theme="light"] .page-head h1 { color: #0f1626; }
[data-theme="light"] .sub, [data-theme="light"] .lab-hero .sub { color: #46536b; }

/* ── Compose box: @-mentions and emoji ──────────────────────────────────────*/
.pb-editor { position: relative; }
.pb-mention { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 60;
  max-height: 260px; overflow-y: auto; padding: 5px;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  box-shadow: 0 18px 44px rgba(0,0,0,.55); }
.pb-mention[hidden] { display: none; }
.pb-m-row { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 7px 10px; border: none; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12.5px; color: var(--ink-soft); background: transparent; }
.pb-m-row:hover { background: rgba(255,255,255,.07); }
.pb-m-row small { color: var(--ink-faint); }
.pb-m-av { width: 30px; height: 30px; border-radius: 50%; flex: none; display: grid;
  place-items: center; font-size: 14px; background-size: cover; background-position: center;
  background-color: var(--avatar-bg); }
.pb-m-avi { font-weight: 800; color: #fff; background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }

.pb-emoji { margin-top: 8px; border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  background: linear-gradient(var(--surface-hi), var(--surface)); overflow: hidden; }
.pb-emoji[hidden] { display: none; }
.pb-emoji-tabs { display: flex; gap: 2px; padding: 6px; border-bottom: 1px solid var(--panel-edge); }
.pb-etab { flex: 1; padding: 5px 0; font-size: 17px; line-height: 1; cursor: pointer;
  border: none; border-radius: 8px; background: transparent; }
.pb-etab:hover { background: rgba(255,255,255,.06); }
.pb-etab.on { background: var(--aqua-soft, rgba(61,129,246,.16)); }
.pb-emoji-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 2px; padding: 8px; max-height: 200px; overflow-y: auto; }
.pb-emo { font-size: 20px; line-height: 1; padding: 4px 0; cursor: pointer; border: none;
  border-radius: 7px; background: transparent; }
.pb-emo:hover { background: rgba(255,255,255,.1); }

[data-theme="light"] .pb-mention, [data-theme="light"] .pb-emoji {
  background: #fff; border-color: #d7dde7; box-shadow: 0 12px 30px rgba(16,24,40,.12); }
[data-theme="light"] .pb-m-row { color: #1c2434; }
[data-theme="light"] .pb-m-row:hover, [data-theme="light"] .pb-etab:hover,
[data-theme="light"] .pb-emo:hover { background: rgba(16,24,40,.06); }

.feed-heading { margin: 0 0 12px; font-size: 15px; font-weight: 700; color: var(--ink-strong); }
[data-theme="light"] .feed-heading { color: #0f1626; }

/* ── Post & comment ownership controls (author-only, shown as icons) ────────*/
.post-own { display: flex; gap: 4px; align-items: center; }
.post-ico { display: grid; place-items: center; width: 28px; height: 28px; padding: 0;
  border: none; border-radius: 8px; cursor: pointer; color: var(--ink-faint);
  background: transparent; }
.post-ico svg { width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.post-ico:hover { background: rgba(255,255,255,.08); color: var(--ink); }
.post-ico.danger:hover { background: rgba(214,69,69,.15); color: #ff9d95; }
.post-own form { margin: 0; }

.post-edit { margin: 8px 0 4px; display: flex; flex-direction: column; gap: 8px; }
.post-edit textarea { width: 100%; box-sizing: border-box; resize: none; font: inherit;
  font-size: 13px; padding: 8px 10px; border-radius: 8px; color: var(--ink);
  background: rgba(0,0,0,.3); border: 1px solid var(--panel-edge); }
.post-edit-row { display: flex; gap: 6px; justify-content: flex-end; }

.comment { display: flex; align-items: flex-start; gap: 8px; }
.comment > span:first-child { flex: 1; min-width: 0; }
.comment form { margin: 0; }
.comment-del { border: none; background: transparent; cursor: pointer; color: var(--ink-faint);
  font-size: 13px; line-height: 1; padding: 2px 4px; border-radius: 5px; opacity: 0;
  transition: opacity .12s; }
.comment:hover .comment-del { opacity: .7; }
.comment-del:hover { opacity: 1; color: var(--bad-ink); background: rgba(214,69,69,.14); }

.pg-del-ico { display: flex; align-items: center; gap: 7px; width: 100%;
  padding: 8px 11px; border: none; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12.5px; font-weight: 700; color: var(--bad-ink); background: rgba(214,69,69,.14); }
.pg-del-ico svg { width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.pg-del-ico:hover { background: rgba(214,69,69,.24); color: var(--bad-ink); }

[data-theme="light"] .post-ico:hover { background: rgba(16,24,40,.06); color: #1c2434; }
[data-theme="light"] .post-edit textarea { background: #fff; border-color: #cfd6e1; color: #1c2434; }


/* Messages panel (msg-panel.js): a column down the right-hand side. The page
   gives up the same width rather than sitting under it, so a paper being read
   stays fully on screen beside the conversation. Too narrow for both, it lies
   over the page instead. */
:root { --msg-panel-w: 380px; }
#tb-msg-btn.on { color: var(--ink); border-color: var(--aqua); }
.msg-panel { display: none; }
html.msg-open .msg-panel { position: fixed; top: 0; right: 0; bottom: 0; z-index: 900;
  width: var(--msg-panel-w); display: flex; flex-direction: column;
  background: var(--surface, var(--bg)); border-left: 1px solid var(--panel-edge);
  box-shadow: -10px 0 30px rgba(0,0,0,.18); }
.msg-panel-head { display: flex; align-items: center; gap: 8px; height: 48px; padding: 0 10px 0 14px;
  border-bottom: 1px solid var(--panel-edge); font-size: 14px; color: var(--ink); flex: none; }
.msg-panel-full { font-size: 12px; color: var(--ink-soft); text-decoration: none; }
.msg-panel-full:hover { color: var(--aqua-ink, var(--aqua)); text-decoration: underline; }
.msg-panel-x { width: 30px; height: 30px; border: 0; border-radius: 50%; background: none;
  color: var(--ink-soft); font-size: 20px; line-height: 1; cursor: pointer; }
.msg-panel-x:hover { background: rgba(127,127,127,.15); color: var(--ink); }
.msg-panel-frame { flex: 1; width: 100%; border: 0; background: var(--surface, var(--bg)); }
html.msg-open .app { padding-right: var(--msg-panel-w); box-sizing: border-box; }
@media (max-width: 900px) {
  html.msg-open .msg-panel { width: min(100vw, 420px); }
  html.msg-open .app { padding-right: 0; }
}

/* Ribbon calendar */
.tb-cal { position: relative; flex-shrink: 0; margin-left: 8px; }
.tb-cal-btn { display: flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 5px 11px; border-radius: var(--radius-pill); font: inherit; font-size: 12px;
  font-weight: 700; color: var(--ink-soft); white-space: nowrap; background: rgba(0,0,0,.25);
  border: 1px solid rgba(255,255,255,.10); }
.tb-cal-btn:hover { background: rgba(0,0,0,.42); border-color: rgba(255,255,255,.2); }
.tb-cal-btn svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.tb-cal-menu { position: absolute; top: 40px; right: 0; width: 300px; z-index: 130;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  box-shadow: 0 18px 44px rgba(0,0,0,.6); overflow: hidden auto;
  /* On a short window the lower half (the day and the add form) ran off the
     screen with no way to reach it; now it scrolls inside the menu. */
  max-height: calc(100vh - 90px); max-height: calc(100dvh - 90px); overscroll-behavior: contain; }
.tb-cal-menu[hidden] { display: none; }
.tb-cal-list { max-height: 300px; overflow-y: auto; }
.tb-cal-item { display: flex; gap: 10px; padding: 9px 12px; border-bottom: 1px solid rgba(0,0,0,.35); }
.tb-cal-ic { font-size: 16px; }
.tb-cal-body { min-width: 0; font-size: 12.5px; color: var(--ink-soft); }
.tb-cal-body small { color: var(--ink-faint); }
.tb-cal-add { padding: 10px 12px; border-top: 1px solid var(--panel-edge); display: flex;
  flex-direction: column; gap: 6px; }
.tb-cal-add input { width: 100%; box-sizing: border-box; height: 30px; padding: 0 10px;
  border-radius: 8px; border: 1px solid #000; color: #eef1f6;
  background: linear-gradient(#141518, #1b1c20); font-size: 12.5px; }
.tb-cal-add-row { display: flex; gap: 6px; }
.tb-cal-add-row input { flex: 1; }
@media (max-width: 1080px) { .tb-cal-btn span { display: none; } }

/* Collapsible panels */
.collapse-head { cursor: pointer; user-select: none; }
.collapse-chev { margin-left: 10px; font-size: 20px; line-height: 1; opacity: .6; transition: transform .15s; }
.collapse.collapsed .collapse-chev { transform: rotate(-90deg); }
.collapse.collapsed .collapse-body { display: none; }

/* Equipment */
.eq-add { display: flex; gap: 6px; margin-bottom: 12px; flex-wrap: wrap; }
.eq-add input[type=text] { flex: 1; min-width: 120px; }
.eq-add input[type=number] { width: 60px; }
.eq-add input { height: 32px; padding: 0 10px; border-radius: 8px; border: 1px solid #000;
  color: #eef1f6; background: linear-gradient(#141518, #1b1c20); font-size: 12.5px; }
.eq-row { display: flex; align-items: center; gap: 11px; padding: 9px 6px;
  border-bottom: 1px solid rgba(0,0,0,.3); }
.eq-ic { font-size: 18px; }
.eq-body { flex: 1; min-width: 0; font-size: 13px; color: var(--ink); }
.eq-body small { color: var(--ink-faint); }
.eq-status { flex: none; font-size: 11px; font-weight: 700; padding: 4px 10px;
  border-radius: var(--radius-pill); white-space: nowrap; }
.eq-status.ok { color: var(--ok-ink); background: rgba(127,208,138,.14); border: 1px solid rgba(127,208,138,.3); }
.eq-status.busy { color: var(--warn-ink); background: rgba(201,121,10,.16); border: 1px solid rgba(201,121,10,.35); }
.eq-status[data-eq] { cursor: pointer; }

[data-theme="light"] .tb-cal-menu { background: #fff; border-color: #d7dde7; }
[data-theme="light"] .tb-cal-add input, [data-theme="light"] .eq-add input {
  background: #fff; border-color: #cfd6e1; color: #16203a; }
[data-theme="light"] .tb-cal-body, [data-theme="light"] .eq-body { color: #1c2434; }


/* ── Month-grid calendar ────────────────────────────────────────────────────*/
.tb-cal-top { display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px 6px; }
.tb-cal-month { font-weight: 700; font-size: 13px; color: var(--ink-strong); }
.tb-cal-nav { border: none; background: transparent; cursor: pointer; font-size: 18px;
  line-height: 1; color: var(--ink-soft); padding: 2px 8px; border-radius: 6px; }
.tb-cal-nav:hover { background: rgba(255,255,255,.08); color: var(--ink); }
.tb-cal-dow { display: grid; grid-template-columns: repeat(7,1fr); padding: 0 8px;
  font-size: 10px; color: var(--ink-faint); text-transform: uppercase; text-align: center; }
.tb-cal-grid { display: grid; grid-template-columns: repeat(7,1fr); gap: 2px; padding: 4px 8px 8px; }
.cal-cell { position: relative; aspect-ratio: 1; min-width: 0; padding: 0; border: none;
  border-radius: 7px; cursor: pointer; font: inherit; font-size: 12px; color: var(--ink);
  background: transparent; display: grid; place-items: center; box-sizing: border-box; }
.cal-cell.empty { visibility: hidden; cursor: default; }
.cal-cell:hover { background: rgba(255,255,255,.08); }
.cal-cell.today { outline: 1px solid var(--aqua); }
.cal-cell.sel { color: var(--ink-invert); background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark)); }
.cal-dot { position: absolute; bottom: 4px; width: 4px; height: 4px; border-radius: 50%;
  background: var(--aqua-bright); }
.cal-cell.sel .cal-dot { background: #fff; }
.tb-cal-day { border-top: 1px solid var(--panel-edge); padding: 8px 12px 12px; }
.tb-cal-day-h { font-weight: 700; font-size: 12px; color: var(--ink-strong); margin-bottom: 6px; }
.tb-cal-day-list { max-height: 150px; overflow-y: auto; margin-bottom: 8px; }
.cal-ev { display: flex; gap: 8px; padding: 6px 0; font-size: 12px; color: var(--ink-soft);
  border-bottom: 1px solid rgba(0,0,0,.25); }
.cal-ev small { color: var(--ink-faint); }
.tb-cal-add { display: flex; flex-direction: column; gap: 6px; }
.tb-cal-add input { width: 100%; box-sizing: border-box; height: 30px; padding: 0 10px;
  border-radius: 8px; border: 1px solid #000; color: #eef1f6;
  background: linear-gradient(#141518, #1b1c20); font-size: 12.5px; }
.tb-cal-add-row { display: flex; gap: 6px; }
.tb-cal-add-row input { flex: 1; }

/* ── Equipment rows + catalogue ─────────────────────────────────────────────*/
.head-add { border: none; background: rgba(255,255,255,.1); color: var(--ink-invert); cursor: pointer;
  width: 22px; height: 22px; border-radius: 6px; font-size: 15px; line-height: 1;
  margin-left: 8px; display: grid; place-items: center; }
.head-add:hover { background: var(--aqua); }
.eq-row { display: flex; align-items: flex-start; gap: 11px; padding: 10px 6px;
  border-bottom: 1px solid rgba(0,0,0,.3); }
.eq-ic { font-size: 18px; margin-top: 1px; }
.eq-body { flex: 1; min-width: 0; }
.eq-title { font-size: 13px; color: var(--ink-strong); }
.eq-title small { color: var(--ink-faint); font-weight: 400; }
.eq-spec { font-size: 12px; color: var(--ink-soft); margin-top: 3px; }
.eq-svc { font-size: 12px; color: var(--aqua-bright); margin-top: 3px; }
.eq-booking { font-size: 11.5px; color: var(--ink-faint); margin-top: 3px; }
.eq-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex: none; }
.eq-cat-g { margin-bottom: 14px; }
.eq-cat-h { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  color: var(--ink-faint); margin-bottom: 7px; }
.eq-chip { display: inline-block; margin: 0 6px 6px 0; padding: 7px 12px; cursor: pointer;
  border-radius: var(--radius-pill); font: inherit; font-size: 12.5px; color: var(--ink-soft);
  background: linear-gradient(var(--surface-hi), var(--surface)); border: 1px solid var(--panel-edge); }
.eq-chip:hover { border-color: var(--aqua); color: var(--ink-invert); }
.eq-chosen { padding: 10px 12px; margin-bottom: 12px; border-radius: var(--radius);
  background: rgba(61,129,246,.1); border: 1px solid rgba(61,129,246,.3); color: var(--ink); }
.bk-existing { margin: 8px 0; }
.bk-ex-h { font-size: 11px; font-weight: 700; color: var(--ink-faint); text-transform: uppercase; }
.bk-ex { font-size: 12px; color: var(--ink-soft); padding: 3px 0; }

[data-theme="light"] .cal-cell:hover, [data-theme="light"] .tb-cal-nav:hover { background: rgba(16,24,40,.06); }
[data-theme="light"] .tb-cal-add input { background: #fff; border-color: #cfd6e1; color: #16203a; }
[data-theme="light"] .eq-chip { background: #fff; border-color: #d7dde7; color: #46536b; }
[data-theme="light"] .head-add { background: rgba(16,24,40,.1); color: #16203a; }


/* ── Profile About: Experience + Education (LinkedIn-style, collapsible) ─────*/
.about { margin: 18px 0; border: 1px solid var(--panel-edge); border-radius: var(--radius);
  background: linear-gradient(var(--surface-hi), var(--surface)); overflow: hidden; }
.about-head { display: flex; align-items: center; gap: 8px; padding: 13px 16px;
  font-weight: 700; font-size: 15px; color: var(--ink-strong); cursor: pointer; user-select: none;
  background: linear-gradient(#34373d, #282a2f); border-bottom: 1px solid #000; }
.about-body { padding: 6px 16px 14px; }
.about-sub { border-bottom: 1px solid var(--panel-edge); }
.about-sub:last-child { border-bottom: none; }
.about-sub-head { display: flex; align-items: center; gap: 8px; padding: 12px 2px;
  font-weight: 700; font-size: 13.5px; color: var(--ink); cursor: pointer; user-select: none; }
.about-sub-head .muted { font-weight: 400; }
.collapse.collapsed > .collapse-body, .about.collapsed > .collapse-body,
.about-sub.collapsed > .collapse-body { display: none; }
.about-sub.collapsed .collapse-chev, .about.collapsed .collapse-chev { transform: rotate(-90deg); }

/* Timeline */
.tl { list-style: none; margin: 4px 0 12px; padding: 0 0 0 6px; }
.tl-item { position: relative; display: flex; gap: 12px; padding: 8px 0 8px 18px;
  border-left: 2px solid var(--panel-edge); }
.tl-item:last-child { border-left-color: transparent; }
.tl-dot { position: absolute; left: -7px; top: 12px; width: 11px; height: 11px; border-radius: 50%;
  background: var(--aqua); border: 2px solid var(--surface); }
.tl-body { flex: 1; min-width: 0; }
.tl-title { font-weight: 700; font-size: 13.5px; color: var(--ink-strong); }
.tl-at { font-weight: 400; color: var(--ink-soft); }
.tl-org { font-size: 12.5px; color: var(--ink-soft); }
.tl-when { font-size: 12px; color: var(--ink-faint); margin: 2px 0; }
.tl-desc { font-size: 12.5px; color: var(--ink-soft); line-height: 1.55; margin-top: 3px; }
.tl-del { border: none; background: transparent; cursor: pointer; color: var(--ink-faint);
  font-size: 15px; line-height: 1; padding: 2px 6px; border-radius: 6px; align-self: flex-start; }
.tl-del:hover { color: var(--bad-ink); background: rgba(214,69,69,.14); }

.about-add { margin: 6px 0 4px; padding: 12px; border-radius: var(--radius-lg);
  border: 1px dashed var(--panel-edge); background: rgba(0,0,0,.15); }
.about-add .field { margin-bottom: 8px; }
.field.checkline { display: flex; align-items: center; gap: 8px; font-size: 12.5px;
  color: var(--ink-soft); }
.field.checkline input { width: auto; }

[data-theme="light"] .about-head { background: linear-gradient(#f7f9fc, #eef2f7);
  color: #16203a; border-bottom-color: #d7dde7; }
[data-theme="light"] .about-add { background: rgba(16,24,40,.03); }
[data-theme="light"] .tl-dot { border-color: #fff; }


/* Institution typeahead */
.inst-wrap { position: relative; display: block; }
.inst-menu { position: absolute; left: 0; right: 0; top: calc(100% + 3px); z-index: 70;
  max-height: 230px; overflow-y: auto; padding: 4px;
  background: linear-gradient(var(--surface-hi), var(--surface));
  border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  box-shadow: 0 16px 40px rgba(0,0,0,.5); }
.inst-menu[hidden] { display: none; }
.inst-opt { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; text-align: left; padding: 8px 10px; border: none; border-radius: 7px;
  cursor: pointer; font: inherit; font-size: 12.5px; color: var(--ink); background: transparent; }
.inst-opt:hover { background: rgba(255,255,255,.07); }
.inst-flag { flex: none; font-size: 10px; font-weight: 700; color: var(--ok-ink);
  background: rgba(127,208,138,.14); border: 1px solid rgba(127,208,138,.3);
  border-radius: var(--radius-pill); padding: 2px 7px; }
[data-theme="light"] .inst-menu { background: #fff; border-color: #d7dde7; }
[data-theme="light"] .inst-opt { color: #1c2434; }
[data-theme="light"] .inst-opt:hover { background: rgba(16,24,40,.06); }


/* About: add line + per-item edit/delete tools */
.add-line { display: inline-flex; align-items: center; gap: 6px; margin: 4px 0 6px;
  padding: 8px 14px; border-radius: var(--radius-pill); cursor: pointer; font: inherit;
  font-size: 12.5px; font-weight: 700; color: var(--aqua-ink);
  background: transparent; border: 1px dashed var(--aqua); }
.add-line:hover { background: rgba(61,129,246,.1); }
.add-line[hidden] { display: none; }
.tl-tools { display: flex; gap: 2px; align-self: flex-start; }
.tl-tools form { margin: 0; }
.tl-ico { display: grid; place-items: center; width: 26px; height: 26px; padding: 0;
  border: none; border-radius: 6px; cursor: pointer; font-size: 14px; line-height: 1;
  color: var(--ink-faint); background: transparent; }
.tl-ico:hover { color: var(--ink); background: rgba(255,255,255,.08); }
.tl-item form.tl-edit { margin-top: 6px; }
.tl-view[hidden] { display: none; }
[data-theme="light"] .tl-ico:hover { color: #1c2434; background: rgba(16,24,40,.06); }


/* Facebook-style post feed (profile + lab) */
.feed { display: flex; flex-direction: column; gap: 14px; }
.post.fb { border: 1px solid var(--panel-edge); border-radius: var(--radius-lg);
  background: linear-gradient(var(--surface-hi), var(--surface)); overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,.3); }
.post.fb .post-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px 8px; }
.post.fb .post-av { width: 42px; height: 42px; border-radius: 50%; flex: none; display: block;
  background-size: cover; background-position: center; text-decoration: none; }
.post.fb .post-av.post-avi { display: grid; place-items: center; font-weight: 800; color: #fff;
  background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.post.fb .post-who { font-weight: 700; font-size: 14px; color: var(--ink-strong); text-decoration: none; }
.post.fb .post-who:hover { text-decoration: underline; }
.post.fb .post-meta { font-size: 11.5px; color: var(--ink-faint); }
.post.fb .post-text { padding: 2px 14px 10px; font-size: 14px; line-height: 1.6;
  color: var(--ink); white-space: pre-wrap; word-wrap: break-word; }
.post.fb .post-tags { padding: 0 14px 10px; display: flex; flex-wrap: wrap; gap: 6px; }
/* Show the photo at its own shape. The file on disk is already the final
   crop, so there is nothing left to fit it into: no `cover` to cut it, and no
   fixed frame to letterbox it. A forced 1:1 frame is what put black bars
   around every photo that was not square, including ones posted before the
   cropper existed — those now simply show at the shape they were taken. */
.post-media { display: block; width: 100%; height: auto; background: #000; }
/* Video is never cropped on the way in, so it keeps its own shape. */
video.post-media { aspect-ratio: auto; max-height: 70vh; object-fit: contain; }
.post-stat { display: flex; align-items: center; gap: 6px; padding: 8px 14px;
  font-size: 12px; color: var(--ink-faint); }
.post-actions.fb { display: flex; border-top: 1px solid var(--panel-edge); padding: 4px; }
.fbact { flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px;
  padding: 8px; border: none; background: transparent; cursor: pointer; font: inherit;
  font-size: 13px; font-weight: 600; color: var(--ink-soft); border-radius: 8px; }
.fbact:hover { background: rgba(255,255,255,.06); }
.fbact.liked { color: #ff4d6d; }

/* Comments */
.post-comments { padding: 8px 14px 12px; border-top: 1px solid var(--panel-edge);
  display: flex; flex-direction: column; gap: 8px; }
.post-comments[hidden] { display: none; }
.comments-open { border: 0; padding: 0; background: transparent; color: var(--ink-faint); font: inherit; cursor: pointer; }
.comments-open:hover { color: var(--aqua-bright); text-decoration: underline; }
.cmt { display: flex; align-items: flex-start; gap: 8px; }
.cmt-reply { margin-left: 38px; }
.cmt-body { min-width: 0; flex: 1; }
.cmt-av { width: 30px; height: 30px; border-radius: 50%; flex: none; background-size: cover;
  background-position: center; text-decoration: none; }
.cmt-av.cmt-avi { display: grid; place-items: center; font-weight: 800; font-size: 12px; color: #fff;
  background: linear-gradient(160deg, #7bb0ff, #2f6be0); }
.cmt-bubble { background: rgba(255,255,255,.05); border-radius: 14px; padding: 7px 12px; min-width: 0; }
.cmt-who { display: block; font-size: 12.5px; font-weight: 700; color: var(--ink-strong); text-decoration: none; }
.cmt-who:hover { text-decoration: underline; }
.cmt-text { font-size: 13px; color: var(--ink); white-space: pre-wrap; word-wrap: break-word; }
.cmt-ago { font-size: 11px; color: var(--ink-faint); white-space: nowrap; }
.cmt-actions { display: flex; align-items: center; gap: 11px; margin: 3px 0 0 5px; }
.cmt-actions form { margin: 0; }
.cmt-action { padding: 0; border: 0; background: transparent; color: var(--ink-faint); cursor: pointer; font: inherit; font-size: 11px; font-weight: 650; }
.cmt-action:hover { color: var(--ink); }
.cmt-action.liked { color: #ff4d6d; }
.cmt-del { border: none; background: transparent; cursor: pointer; color: var(--ink-faint);
  font-size: 13px; padding: 2px 4px; border-radius: 5px; align-self: center; opacity: 0; }
.cmt:hover .cmt-del { opacity: .7; }
.cmt-del:hover { opacity: 1; color: var(--bad-ink); }

/* Comment composer (Instagram-style: @ mention + emoji) */
.cbox { position: relative; display: flex; align-items: flex-end; gap: 8px; margin-top: 4px; }
.cbox-replying { position: absolute; left: 0; bottom: calc(100% + 6px); display: flex; gap: 8px; align-items: center; font-size: 11px; color: var(--ink-faint); }
.cbox-replying button { border: 0; padding: 0; background: transparent; color: var(--aqua-bright); cursor: pointer; font: inherit; font-size: inherit; }
.cbox-text { flex: 1; resize: none; min-height: 34px; max-height: 120px; padding: 8px 12px;
  border-radius: 16px; border: 1px solid var(--panel-edge); background: rgba(0,0,0,.28);
  color: var(--ink); font: inherit; font-size: 13px; line-height: 1.4; box-sizing: border-box; }
.cbox-text:focus { border-color: var(--aqua); outline: none; }
.cbox-side { display: flex; align-items: center; gap: 4px; }
.cbox-emoji, .cbox-send { border: none; background: transparent; cursor: pointer; font-size: 17px;
  line-height: 1; padding: 6px; border-radius: 8px; color: var(--ink-soft); }
.cbox-send { color: var(--aqua-bright); font-size: 15px; }
.cbox-emoji:hover, .cbox-send:hover { background: rgba(255,255,255,.08); }
.cbox-mention { position: absolute; left: 0; bottom: calc(100% + 4px); z-index: 60; min-width: 220px;
  background: linear-gradient(var(--surface-hi), var(--surface)); border: 1px solid var(--panel-edge);
  border-radius: var(--radius-lg); box-shadow: 0 14px 34px rgba(0,0,0,.55); overflow: hidden; }
.cbox-mention[hidden] { display: none; }
.cm-row { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 8px 11px;
  border: none; background: transparent; cursor: pointer; font: inherit; font-size: 12.5px; color: var(--ink); }
.cm-row:hover { background: rgba(255,255,255,.07); }
.cm-row small { color: var(--ink-faint); }
.cm-av { width: 26px; height: 26px; border-radius: 50%; flex: none; background-size: cover; background-position: center; }
.cm-av.cm-avi { display: grid; place-items: center; font-weight: 800; font-size: 11px; color: #fff;
  background: linear-gradient(160deg, #7bb0ff, #2f6be0); }
.cbox-emoji-tray { position: absolute; right: 0; bottom: calc(100% + 4px); z-index: 60; width: 260px;
  display: flex; flex-wrap: wrap; gap: 2px; padding: 8px; max-height: 170px; overflow-y: auto;
  background: linear-gradient(var(--surface-hi), var(--surface)); border: 1px solid var(--panel-edge);
  border-radius: var(--radius-lg); box-shadow: 0 14px 34px rgba(0,0,0,.55); }
.cbox-emoji-tray[hidden] { display: none; }
.cbox-emo { font-size: 19px; line-height: 1; padding: 4px; border: none; background: transparent;
  cursor: pointer; border-radius: 6px; }
.cbox-emo:hover { background: rgba(255,255,255,.1); }

[data-theme="light"] .fbact:hover, [data-theme="light"] .cbox-emo:hover,
[data-theme="light"] .cm-row:hover { background: rgba(16,24,40,.05); }
[data-theme="light"] .cmt-bubble { background: rgba(16,24,40,.05); }
[data-theme="light"] .cbox-text { background: #fff; }
[data-theme="light"] .cbox-mention, [data-theme="light"] .cbox-emoji-tray { background: #fff; }


/* Equipment row: edit/delete icons */
.eq-btns { display: flex; align-items: center; gap: 4px; }
.eq-ico { display: grid; place-items: center; width: 26px; height: 26px; padding: 0; border: none;
  border-radius: 6px; cursor: pointer; font-size: 14px; line-height: 1; color: var(--ink-faint);
  background: transparent; }
.eq-ico:hover { color: var(--ink); background: rgba(255,255,255,.08); }
.eq-ico.danger:hover { color: #ff9d95; background: rgba(214,69,69,.14); }
[data-theme="light"] .eq-ico:hover { color: #1c2434; background: rgba(16,24,40,.06); }


/* Calendar day items: done state + inline tools */
.cal-ev { align-items: flex-start; }
.cal-ev-body { flex: 1; min-width: 0; }
.cal-ev.done .cal-ev-body b { text-decoration: line-through; opacity: .6; }
.cal-tools { display: flex; gap: 2px; flex: none; }
.cal-tool { border: none; background: transparent; cursor: pointer; width: 22px; height: 22px;
  border-radius: 5px; font-size: 13px; line-height: 1; color: var(--ink-faint); }
.cal-tool:hover { color: var(--ok); background: rgba(127,208,138,.16); }
.cal-tool.danger:hover { color: #ff9d95; background: rgba(214,69,69,.16); }
[data-theme="light"] .cal-tool:hover { background: rgba(12,154,137,.12); }


/* Calendar 12-hour time pickers */
.tb-cal-times { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.t12-row { display: flex; align-items: center; gap: 8px; }
.t12-label { width: 38px; font-size: 11.5px; color: var(--ink-faint); }
.t12 { display: inline-flex; gap: 3px; }
.t12 select { flex: 1; }
.t12 select { height: 28px; padding: 0 4px; border-radius: 6px; border: 1px solid #000;
  color: #eef1f6; background: linear-gradient(#141518, #1b1c20); font-size: 12px; }
[data-theme="light"] .t12 select { background: #fff; border-color: #cfd6e1; color: #16203a; }


/* ══ Tablet & small-screen chrome (iPad and below) ═════════════════════════
   The ribbon holds a lot; on narrow screens the search shrinks first, then the
   decorative pieces drop, so the brand, Agent menu, activity flask and the
   account menu stay visible and reachable. */

/* iPad landscape and down: drop the stats strip and the lab picker/name. */
@media (max-width: 1100px) {
  .tb-stats { display: none; }
  .tb-lab-name, .tb-pick { display: none; }
  .content { padding: 20px 20px 40px; }
}

/* iPad portrait and down: labels off the mode toggle, Agent and Calendar —
   icons carry them — and give the search a smaller floor. */
@media (max-width: 900px) {
  .tb-mode a { padding: 4px 10px; font-size: 11px; }
  .tb-agent-btn span, .tb-cal-btn span { display: none; }
  .tb-agent-btn, .tb-cal-btn { padding: 6px 9px; }
  .titlebar { gap: 8px; padding: 0 10px; }
  .tb-search { margin-left: 8px; }
  .content { padding: 16px 14px 36px; }
  .lab-hero h1 { font-size: 22px; }
}

/* Phones: everything stays reachable, reduced to its icon.

   This block used to hide .tb-agent, .tb-cal and .tb-mode outright. That left a
   phone with brand, search, flask and account only — and since .tb-agent is the
   menu holding C-Form, Inventory, Reference, Messages, EIS, XRD and Rietveld,
   there was no route to any of them on a phone at all. Shrinking beats hiding:
   a cramped control can still be tapped, a missing one cannot. */
@media (max-width: 640px) {
  .tb-brand span { display: none; }        /* logo alone */
  /* Tighter than the tablet rules: every pixel reclaimed here is a pixel the
     search box gets back below. */
  .tb-mode { margin-left: 6px; padding: 2px; }
  .tb-mode a { padding: 4px 6px; }
  .tb-mode a span { display: none; }       /* ⚗️ / 🌐 carry the meaning */
  .tb-agent-btn, .tb-cal-btn { padding: 6px 7px; }
  .titlebar { gap: 5px; padding: 0 7px; }
  /* The search still yields room before the buttons do, but it needs a floor —
     flexed to nothing it was too short to read what you had typed. 88px is what
     the bar can actually spare: seven controls plus the search have to fit
     inside 360px, and a floor above that made the titlebar wider than the
     screen, which is what pushed the whole page sideways. */
  .tb-search { margin-left: 5px; flex: 1 1 88px; min-width: 88px; }
  /* Nothing in the bar may refuse to shrink; a flex item's default min-width is
     its content, which is how a single long control drags the page wider than
     the viewport. */
  .titlebar > * { min-width: 0; }

  /* Dropdowns anchor to the viewport, not to their button.

     These menus are `position: absolute; right: 0` with a fixed width, which
     lines them up under a button that has plenty of room to its left. On a
     phone there is no such room: a 300px menu hanging off a button near the
     middle of a 360px bar runs past the left edge and gets clipped. Pinned to
     both screen edges instead, each one is fully on-screen at any width. */
  .tb-agent-menu, .tb-notif, .tb-results, .tb-pop {
    position: fixed; top: 52px; left: 8px; right: 8px;
    width: auto; max-width: none;
    max-height: calc(100vh - 68px); overflow-y: auto;
    /* A swipe that reaches the end of the list stops there. Without this the
       remaining movement is handed to the page underneath, so scrolling the
       results scrolls the feed behind them — and a short list, which never
       scrolls at all, hands over the whole gesture. */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  /* While the search results are up they are the only thing on screen that
     should move. Set by setResults() in base.html; the class goes away when
     the panel does, and the page keeps its scroll position either way. */
  body.tb-search-open { overflow: hidden; }
  /* .tb-results and .tb-pop were the two this list forgot, and both failed the
     same way the comment above describes — off the side of the screen.

     The search panel was the worse of the pair. It is `right: 0` on a box that
     the rule below shrinks to a 88px floor, and it asks for
     `width: max(100%, 360px)` — so 360px of panel hangs from the right edge of
     an 88px box sitting mid-bar, putting roughly 270px of it, including every
     name, off the left of the screen. What was left on-screen was the tail of
     each row, which is why it read as "only the buttons are visible".

     .tb-pop (Labs / Citers / Cited) is the mirror image: `left: 0` with a
     300px width, so it runs off the right instead. Pinned to both edges, each
     is fully on-screen at any width.

     .tb-menu is deliberately not in this list: it hangs `right: 0` off the
     account button, which is already at the far right, so its 262px sits on
     screen down to 278px of viewport — narrower than any phone. */

  /* The calendar is the one that earns a sheet: it is the tallest of the three
     and the one people keep open while reading. It rises from the bottom edge,
     where a thumb already is, and can be swiped back down. */
  .tb-cal-menu {
    position: fixed; top: auto; bottom: 0; left: 0; right: 0;
    width: auto; max-width: none;
    max-height: 82vh; overflow-y: auto;
    border-radius: 16px 16px 0 0;
    padding-top: 18px;                       /* room for the grab handle */
    transform: translateY(100%);
    transition: transform .28s cubic-bezier(.22, .61, .36, 1);
    box-shadow: 0 -14px 40px rgba(0,0,0,.55);
  }
  .tb-cal-menu.sheet-open { transform: translateY(0); }
  /* The handle says "this can be dragged" before anyone tries it. */
  .tb-cal-menu::before {
    content: ""; position: absolute; top: 7px; left: 50%;
    width: 38px; height: 4px; margin-left: -19px;
    border-radius: 2px; background: rgba(255,255,255,.3);
  }
  .page-head h1 { font-size: 22px; }
}

[data-theme="light"] .tb-cal-menu::before { background: rgba(0,0,0,.22); }

/* Someone who has asked for less motion gets the sheet without the slide. */
@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
  .tb-cal-menu { transition: none; }
}

/* Touch: reveal the row controls that only appeared on hover on desktop. */
@media (hover: none) {
  .cmt-del, .comment-del, .eq-ico, .tl-del, .tl-ico, .cbox-emoji { opacity: 1; }
  /* The photo frame is square everywhere now, so it needs no touch-specific
     height; only video, which keeps its own shape, still wants a ceiling. */
  video.post-media { max-height: 70vh; }
}


/* ── "N new posts" ─────────────────────────────────────────────────────────
   Raised by static/js/feed-live.js when someone else has posted since this
   page was rendered. Sticky rather than fixed: it belongs to the feed column,
   so it tracks that column's width instead of floating over the whole app, and
   it stays in reach however far down you have scrolled. */
.feed-new {
  position: sticky; top: 10px; z-index: 40;
  display: block; width: 100%; margin: 0 0 12px;
  padding: 9px 14px; border: 0; border-radius: var(--radius-pill);
  font: inherit; font-size: 12.5px; font-weight: 700; color: #eaf2ff;
  background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark));
  box-shadow: 0 1px 0 rgba(255,255,255,.3) inset, 0 6px 18px rgba(0,0,0,.45);
  cursor: pointer;
}
.feed-new:hover { filter: brightness(1.08); }
.feed-new:active { transform: translateY(1px); }

@media (prefers-reduced-motion: reduce) {
  .feed-new:active { transform: none; }
}


/* ── Publications ──────────────────────────────────────────────────────────
   Reuses the Experience/Education timeline, with two additions: the title is
   a link to the paper, and the DOI sits underneath in small type. A citation
   is scanned, so the title carries the weight and everything else recedes. */
.pub-title { color: var(--ink); text-decoration: none; }
.pub-title:hover { color: var(--aqua); text-decoration: underline; }
.pub-journal { font-style: italic; }
.pub-doi { margin-top: 3px; font-size: 11.5px; color: var(--ink-faint); }
.pub-doi a { color: var(--ink-faint); text-decoration: none; }
.pub-doi a:hover { color: var(--aqua); text-decoration: underline; }
/* A long DOI or title must wrap rather than widen the panel on a phone. */
.pub-list .tl-title, .pub-doi { overflow-wrap: anywhere; }
/* Ask the author, under each paper on someone else's profile. */
.pub-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-top: 7px; }
.pub-ask-btn { display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px;
  border: 1px solid var(--panel-edge); border-radius: 999px; background: var(--surface);
  color: var(--aqua-ink, var(--aqua)); font: inherit; font-size: 12px; font-weight: 600;
  line-height: 1.3; text-decoration: none; cursor: pointer; }
.pub-ask-btn:hover { border-color: var(--aqua); }
.pub-ask-btn:disabled { opacity: .6; cursor: default; }
.pub-ask-btn.sent { color: #eaf2ff; border-color: transparent;
  background: linear-gradient(var(--aqua), var(--aqua-dark)); }
.pub-ask-state { font-size: 12px; font-weight: 600; color: var(--ok, #2e9e6b); }
.pub-ask-note { font-size: 11.5px; color: var(--ink-faint); }
/* The author's Send PDF dialog (ask-author.js). */
.ask-send-dialog { width: min(500px, calc(100vw - 32px)); max-height: calc(100dvh - 48px); overflow: auto;
  padding: 24px; border: 1px solid var(--panel-edge); border-radius: 16px;
  background: var(--surface); color: var(--ink); }
.ask-send-dialog::backdrop { background: #0008; }
.ask-send-dialog h2 { margin: 0 0 10px; font-size: 18px; }
.ask-send-who { margin: 0; font-size: 13px; color: var(--ink-soft); }
.ask-send-title { margin: 2px 0 14px; font-weight: 650; overflow-wrap: anywhere; }
.ask-send-file { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; font-size: 13px; }
.ask-send-file span { font-weight: 650; }
.ask-send-ok { display: flex; align-items: flex-start; gap: 9px; font-size: 13px; line-height: 1.45; cursor: pointer; }
.ask-send-ok input { margin-top: 3px; flex: none; }
.ask-send-note { font-size: 12px; line-height: 1.5; margin: 12px 0; }
.ask-send-err { color: var(--bad-ink, #c0392b); font-size: 12.5px; margin: 0 0 10px; }
/* ORCID iD and "Find my publications" (partials/about.html). */
.pub-orcid { margin: 8px 0 4px; font-size: 12.5px; color: var(--ink-soft); }
.pub-orcid a { color: var(--aqua); }
.pub-find { margin: 10px 0; padding: 10px 12px; border: 1px dashed var(--panel-edge); border-radius: 10px; display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; }
.pub-find .pub-orcid-form { display: flex; gap: 8px; align-items: flex-end; flex: 1 1 320px; }
.pub-find .pub-orcid-form .field { flex: 1; margin: 0; }
.pub-find p { flex-basis: 100%; }
/* Papers found for you, waiting for Add / Not mine (about.html). */
.pub-wait { margin: 10px 0; padding: 10px 12px; border: 1px solid var(--panel-edge); border-radius: 10px; }
.pub-wait-head { font-weight: 600; margin-bottom: 6px; }
.pub-wait-item { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; justify-content: space-between; padding: 6px 0; border-top: 1px solid var(--panel-edge); }
.pub-wait-item > div { flex: 1 1 260px; min-width: 0; overflow-wrap: anywhere; }
.pub-wait-item .tb-nask-act { display: flex; gap: 6px; }


/* ── A lab's own identity ──────────────────────────────────────────────────
   The lab header reuses the .pfh block wholesale, so only what is particular
   to a lab lives here: the line under the name, and the facts list in About. */
.pfh-sub { font-size: 13px; color: var(--ink-soft); display: flex;
  align-items: center; gap: 7px; flex-wrap: wrap; }
.lab-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; padding: 2px 7px; border-radius: var(--radius-pill);
  background: rgba(0,0,0,.28); border: 1px solid rgba(255,255,255,.08);
  color: var(--ink-faint); }
.pfh-dot { color: var(--ink-faint); }
/* Under a lab's name: "LAB ID [code]   RESEARCH FOCUS text", labelled like the
   facts beside it, one pair per item so nothing runs together. */
.lab-sub { gap: 6px 22px; margin-top: 6px; }
.lab-pair { display: inline-flex; align-items: baseline; gap: 7px; min-width: 0; }
.lab-k { font-size: 10.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase;
  color: var(--ink-faint); white-space: nowrap; }
.lab-k::after { content: ":"; }
.lab-v { color: var(--ink-soft); overflow-wrap: anywhere; }
.lab-about-k { margin: 0 0 2px; }
@media (max-width: 560px) {
  /* The header centres on a phone: the facts follow the name. */
  .lab-sub { justify-content: center; }
  .lab-pair { flex-wrap: wrap; justify-content: center; text-align: center; }
  .pfh-id .pfh-about { text-align: center; }
  .pfh-id .pfh-about .lab-facts { justify-content: center; }
}

.lab-about-text { margin: 0 0 14px; line-height: 1.6; color: var(--ink-soft);
  white-space: pre-wrap; }          /* keep the paragraphs an admin typed */

/* Label above value on a phone, two columns once there is room for them. */
.lab-facts { margin: 0; display: grid; grid-template-columns: 1fr; gap: 2px 18px; }
.lab-facts dt { font-size: 11px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: var(--ink-faint); }
.lab-facts dd { margin: 0 0 10px; color: var(--ink-soft); white-space: pre-wrap; }
@media (min-width: 640px) {
  .lab-facts { grid-template-columns: 150px minmax(0, 1fr); }
  .lab-facts dt { padding-top: 1px; }
  .lab-facts dd { margin-bottom: 6px; }
}

[data-theme="light"] .lab-code { background: #eef1f6; border-color: #d7dde7; }


/* ── Discover: searching the literature, not the shelf ─────────────────────
   A results list is scanned, so the title carries the weight, the metadata
   line stays quiet, and the two facts that decide what you can do next —
   open access or not, already on the shelf or not — are the only colour. */
.discover-search .panel-body { padding: 14px 16px; }
.discover-hint { margin-top: 8px; font-size: 11.5px; line-height: 1.5; }
.discover-count { margin: 4px 2px 12px; font-size: 12px; }

.disc-row { margin-bottom: 10px; }
.disc-row .panel-body { padding: 14px 16px; }
.disc-title { margin: 0 0 5px; font-size: 15.5px; line-height: 1.35; font-weight: 700; }
.disc-title a { color: var(--ink); text-decoration: none; }
.disc-title a:hover { color: var(--aqua); text-decoration: underline; }
.disc-authors { font-size: 12.5px; color: var(--ink-soft); margin-bottom: 4px;
  overflow-wrap: anywhere; }
.disc-meta { display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--ink-faint); }
.disc-journal { font-style: italic; }
.disc-dot { opacity: .6; }

.disc-tag { padding: 1px 8px; border-radius: var(--radius-pill); font-size: 10.5px;
  font-weight: 700; letter-spacing: .3px; border: 1px solid; }
.disc-tag.oa     { color: var(--ok-ink); border-color: var(--ok);
  background: rgba(127,208,138,.16); }
.disc-tag.closed { color: var(--ink-faint); border-color: rgba(255,255,255,.14);
  background: rgba(0,0,0,.25); }
.disc-tag.have   { color: var(--aqua-ink); border-color: var(--aqua);
  background: rgba(61,129,246,.16); }

.disc-abstract { margin: 9px 0 0; font-size: 12.5px; line-height: 1.6;
  color: var(--ink-soft); }
.disc-actions { margin-top: 11px; align-items: center; gap: 8px; flex-wrap: wrap; }
.disc-doi { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px; color: var(--ink-faint); overflow-wrap: anywhere; }
.disc-pager { margin: 16px 0 40px; justify-content: center; gap: 10px; }

[data-theme="light"] .disc-tag.closed { background: #eef1f6; border-color: #d7dde7; }
[data-theme="light"] .disc-tag.oa { background: #e8f7ea; }
[data-theme="light"] .disc-tag.have { background: #e9f0fd; }


/* ── One search box, two scopes ────────────────────────────────────────────
   The scope selector sits inside the box at its left edge, so "where am I
   looking?" is answered by the control you are already typing into rather
   than by remembering which page you are on. */
/* In the tab strip's row. The search grows into whatever the tabs leave, the
   filters sit beside it while there is room, and each wraps to its own line
   rather than squashing when there is not. */
.ref-find { margin: 0; flex: 1 1 360px; min-width: 0;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ref-find .find-box { flex: 1 1 280px; min-width: 0; }
.ref-find .disc-filters { flex: 1 1 100%; }
.find-box { display: flex; align-items: stretch; gap: 0;
  border: 1px solid #000; border-radius: var(--radius-pill);
  background: linear-gradient(#141518, #1b1c20);
  box-shadow: 0 2px 5px rgba(0,0,0,.55) inset, 0 1px 0 rgba(255,255,255,.06);
  overflow: hidden; }
.find-box:focus-within { border-color: var(--aqua);
  box-shadow: 0 2px 5px rgba(0,0,0,.55) inset, 0 0 0 3px var(--aqua-glow); }

.find-scope { flex: 0 0 auto; width: auto; height: 42px; padding: 0 10px 0 14px;
  border: 0; border-right: 1px solid rgba(255,255,255,.09); border-radius: 0;
  background: rgba(0,0,0,.3); color: var(--ink-soft);
  font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer; }
.find-scope:focus { outline: none; }

.find-input { flex: 1 1 auto; min-width: 0; height: 42px; padding: 0 14px !important;
  border: 0 !important; background: transparent !important; box-shadow: none !important;
  color: var(--ink); font-size: 14px; }
.find-input:focus { outline: none; box-shadow: none !important; }

.find-go { flex: 0 0 auto; height: 42px; padding: 0 20px; border: 0; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 700; color: #eaf2ff;
  background: linear-gradient(var(--aqua-light), var(--aqua) 60%, var(--aqua-dark)); }
.find-go:hover { filter: brightness(1.08); }

.find-note { margin: 8px 4px 0; font-size: 11.5px; line-height: 1.5; }
.find-filters { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 0; flex: 0 1 auto; }
.find-filters .spacer { flex: 1; }

/* The dead end that is not one: nothing on the shelf, so offer the wider net. */
.find-widen { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px 16px; margin-bottom: 14px; border-radius: var(--radius);
  border: 1px dashed var(--panel-edge); background: rgba(0,0,0,.18);
  color: var(--ink-soft); font-size: 13px; }

@media (max-width: 640px) {
  /* Stacked: a 360px row cannot hold a scope, a query and a verb. */
  .find-box { flex-wrap: wrap; border-radius: var(--radius); }
  .find-scope { flex: 1 1 auto; border-right: 0;
    border-bottom: 1px solid rgba(255,255,255,.09); }
  .find-go { flex: 1 1 100%; border-top: 1px solid rgba(255,255,255,.09); }
  .find-input { flex: 1 1 100%; order: -1; height: 44px; }
}

[data-theme="light"] .find-box { background: #fff; border-color: #cfd6e1; }
[data-theme="light"] .find-scope { background: #f2f5fa; color: #33415c;
  border-right-color: #dfe5ee; }
[data-theme="light"] .find-input { color: #16203a; }


/* ── Projects: a private tree beside the shelf ─────────────────────────────
   The library is the lab's; the arrangement is each person's own, so two
   researchers can organise the same papers differently without either one
   rearranging the other's view. */
.ref-layout { display: grid; grid-template-columns: minmax(0, 232px) minmax(0, 1fr); gap: 18px;
  align-items: start; }
.ref-main { min-width: 0; }        /* or a wide table drags the grid open */

.proj-pane { position: sticky; top: 10px; padding: 12px 10px 14px;
  border: 1px solid var(--panel-edge); border-radius: var(--radius);
  background: linear-gradient(var(--surface-hi), var(--surface)); }
.proj-head { display: flex; align-items: center; gap: 6px; padding: 0 4px 8px;
  font-size: 12px; font-weight: 800; letter-spacing: .4px; color: var(--ink-soft); }
.proj-tree, .proj-kids { list-style: none; margin: 0; padding: 0; }

.proj-row { display: flex; align-items: center; gap: 2px; border-radius: 7px; }
/* The twist-down, on the left where a tree keeps it. A project with nothing
   inside gets the same width of nothing, so every name starts in line. */
.proj-caret { flex: none; width: 20px; height: 22px; padding: 0; border: 0;
  background: none; color: var(--ink-soft); font-size: 15px; line-height: 22px;
  text-align: center; cursor: pointer; }
.proj-caret:hover { color: var(--aqua); }
.proj-caret-none { cursor: default; }
/* Renaming happens on the row, so the box stands where the name was. */
.proj-edit { flex: 1 1 auto; min-width: 0; height: 24px; margin: 1px 4px 1px 0;
  padding: 0 7px; font-size: 12px; }
.proj-row-new { padding-top: 1px; padding-bottom: 1px; }
.proj-row:hover { background: rgba(255,255,255,.05); }
.proj-row.on { background: rgba(61,129,246,.16); }
.proj-link { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 7px;
  padding: 6px 4px; text-decoration: none; color: var(--ink-soft); font-size: 12.5px; }
.proj-row.on .proj-link { color: var(--ink-invert); font-weight: 700; }
.proj-ico { flex: none; font-size: 12px; }
.proj-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.proj-n { flex: none; font-size: 10.5px; color: var(--ink-faint);
  background: rgba(0,0,0,.3); border-radius: var(--radius-pill); padding: 1px 7px; }

.proj-menu-btn { flex: none; border: 0; background: none; cursor: pointer;
  color: var(--ink-faint); font-size: 14px; line-height: 1; padding: 4px 6px;
  border-radius: 6px; }
.proj-menu-btn:hover { color: var(--ink-invert); background: rgba(255,255,255,.08); }

.proj-menu { margin: 4px 4px 8px; padding: 9px; border-radius: 8px;
  background: rgba(0,0,0,.32); border: 1px solid var(--panel-edge);
  display: flex; flex-direction: column; gap: 7px; }
.proj-menu form { display: flex; gap: 5px; align-items: center; }
.proj-menu input[type="text"] { flex: 1 1 auto; min-width: 0; height: 26px;
  padding: 0 8px; font-size: 11.5px; }
.proj-new { display: flex; gap: 5px; padding: 0 4px 8px; }
.proj-new input { flex: 1 1 auto; min-width: 0; height: 28px; padding: 0 8px;
  font-size: 12px; }
.proj-empty { padding: 8px 6px 2px; font-size: 11.5px; line-height: 1.55; }

.file-pick { width: auto !important; padding: 2px 6px !important;
  font-size: 11px !important; }

@media (max-width: 900px) {
  /* The tree goes above the list rather than squeezing it. */
  .ref-layout { grid-template-columns: 1fr; }
  .proj-pane { position: static; }
}

[data-theme="light"] .proj-pane { background: #fff; }
[data-theme="light"] .proj-n { background: #eef1f6; }
[data-theme="light"] .proj-menu { background: #f4f6fa; }


/* ══ One height for every control, and content centred in all of them ══════
   The ribbon's pieces were each sized by their own padding, so the search
   island, the Agent and Calendar pills, the mode toggle and the account button
   all landed on different heights — 27px to 36px — and sat on a row that only
   looked aligned because nothing was tall enough to make the mismatch obvious.

   Height is set once here, from a token. Width still follows content, which is
   the point: a pill should be as wide as its label and exactly as tall as its
   neighbours.

   `padding-block` rather than `padding`, so the tighter horizontal padding the
   phone rules apply further up is left intact. */
:root { --tb-ctl: 32px; }

.titlebar .tb-search input,
.tb-agent-btn,
.tb-cal-btn,
.tb-me-btn,
.tb-bell {
  height: var(--tb-ctl);
  padding-block: 0;
  box-sizing: border-box;
}

/* The mode toggle keeps its own 3px inset — its segments are sized from it —
   so it gets the height without losing the padding that makes it read as a
   track with pills in it. */
.tb-mode { height: var(--tb-ctl); align-items: center; box-sizing: border-box; }

/* Everything that is a button also centres what is inside it, both ways. An
   emoji, an SVG and a word have different natural baselines; without this the
   glyph decides where the row sits. */
.tb-agent-btn, .tb-cal-btn, .tb-me-btn, .tb-bell, .tb-mode a {
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1;
}

/* The mode toggle is a container with its own 3px padding and a border, so its
   segments are the outer height minus both. */
.tb-mode a { height: calc(var(--tb-ctl) - 8px); }

/* 30px of avatar could not fit inside a 32px button; it was what made the
   account control the tallest thing on the ribbon. */
.tb-me-av { width: 26px; height: 26px; }
.tb-bell { line-height: 1; }

/* ── Buttons everywhere else ───────────────────────────────────────────────
   .btn already flexed, but never centred along the inline axis, so any button
   given a width — or sitting in a grid cell — pushed its label to the left.
   The min-height stops a label with no descenders from riding high in a row of
   buttons that do have them. */
.btn { justify-content: center; line-height: 1.15; min-height: 30px; }
.btn.small { min-height: 24px; }

/* Inputs and selects that share a row with a button should match it, or the
   row reads as two different heights pretending to be one. This is the case
   the new-project form in the Reference Agent got wrong. */
.proj-new input, .proj-menu input[type="text"] { height: 24px; }
.proj-new .btn.small, .proj-menu .btn.small { min-height: 24px; height: 24px; }
.proj-new, .proj-menu form { align-items: center; }

/* Same rule for the compact selects that sit inside table action cells. */
.file-pick, .actions select { height: 24px; }


/* ── Member cards: the role pill in a column, and a way to say hello ───────
   The pill used to follow the name inline, so it started wherever that name
   happened to end — down a list of names of different lengths, a ragged edge.
   Pinned right, the pills line up and the eye can run down them. */
.rg-name { flex-wrap: nowrap; }
.rg-nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rg-name .pill { margin-left: auto; flex: none; }

/* The card is a div now, so the whole of it is still a link to the profile:
   this covers the card, and anything that must stay clickable sits above it. */
.rg-stretch { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.rg-card > :not(.rg-stretch) { position: relative; }
.rg-chat { z-index: 2; align-self: flex-start; flex: none; }

/* ── The corner chat window ────────────────────────────────────────────────
   Bottom right, above everything, and out of the way when minimised. Its own
   stacking context so a dropdown elsewhere cannot appear through it. */
.chatdock {
  position: fixed; right: 18px; bottom: 0; z-index: 200;
  width: 320px; max-width: calc(100vw - 24px);
  display: flex; flex-direction: column;
  border: 1px solid var(--panel-edge); border-bottom: 0;
  border-radius: 12px 12px 0 0; overflow: hidden;
  background: linear-gradient(var(--surface-hi), var(--surface));
  box-shadow: 0 -6px 32px rgba(0,0,0,.55);
}
.chatdock[hidden] { display: none; }

.chatdock-head { display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 0 8px 0 12px; height: 40px; flex: none;
  background: linear-gradient(#34373d, #282a2f); border-bottom: 1px solid #000; }
.chatdock-dot { width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: #4ad07a; box-shadow: 0 0 6px rgba(74,208,122,.7); }
.chatdock-who { flex: 1 1 auto; min-width: 0; font-weight: 700; font-size: 13px;
  color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chatdock-lock { flex: none; font-size: 11px; opacity: .7; }
.chatdock-btn { flex: none; width: 26px; height: 26px; border: 0; cursor: pointer;
  border-radius: 6px; background: none; color: var(--ink-soft); font-size: 15px;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
.chatdock-btn:hover { background: rgba(255,255,255,.1); color: var(--ink); }
/* In light mode the bar turns light too; its name is --ink, which is dark
   there, and was unreadable on the dark bar. */
[data-theme="light"] .chatdock-head { background: linear-gradient(#ffffff, #eef1f6);
  border-bottom-color: var(--panel-edge); }
[data-theme="light"] .chatdock-btn:hover { background: rgba(0,0,0,.06); }

.chatdock-body { display: flex; flex-direction: column; min-height: 0; }
/* Minimised: the bar alone stays, so it sits at the bottom edge like a tab. */
.chatdock.min .chatdock-body { display: none; }
.chatdock.min { border-radius: 10px 10px 0 0; }

.chatdock-state { display: flex; flex-direction: column; min-height: 0;
  padding: 12px; gap: 10px; }
.chatdock-state[hidden] { display: none; }
.chatdock-state p { margin: 0; font-size: 12.5px; color: var(--ink-soft); line-height: 1.5; }
.chatdock-unlock { display: flex; gap: 6px; }
.chatdock-unlock input { flex: 1 1 auto; min-width: 0; height: 28px; padding: 0 9px;
  font-size: 12.5px; }

.chatdock-msgs { flex: 1 1 auto; min-height: 220px; max-height: 46vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 6px; padding-right: 2px; }
.chatdock-msg { max-width: 82%; padding: 7px 11px; border-radius: 13px;
  font-size: 12.5px; line-height: 1.45; overflow-wrap: anywhere; }
.chatdock-msg.mine { align-self: flex-end;
  background: linear-gradient(var(--aqua-light), var(--aqua) 70%); color: var(--ink-invert); }
.chatdock-msg.theirs { align-self: flex-start;
  background: rgba(255,255,255,.08); color: var(--ink); }
.chatdock-text { display: block; }
.chatdock-when { display: block; margin-top: 3px; font-size: 9.5px; opacity: .65; }
/* Who said it, in a group. */
.chatdock-from { display: block; margin-bottom: 2px; font-size: 10.5px; font-weight: 700;
  color: var(--aqua-light); }

/* ＋ (add a lab member) and 👥 (members, private chat): a sheet over the top
   of the thread, so the conversation stays where it was underneath. */
.chatdock-panel { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px;
  border-bottom: 1px solid var(--panel-edge); max-height: 46vh; overflow-y: auto; }
.chatdock-panel[hidden] { display: none; }
.chatdock-panel-head { display: flex; align-items: center; gap: 8px; }
.chatdock-panel-title { flex: 1 1 auto; font-size: 13px; color: var(--ink); }
.chatdock-panel-note { margin: 0; font-size: 11.5px; color: var(--ink-soft); line-height: 1.45; }
.chatdock-panel-note:empty { display: none; }
.chatdock-panel-list { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; }
.chatdock-person { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
.chatdock-person-name { flex: 1 1 auto; min-width: 0; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chatdock-person-note { font-size: 11px; color: var(--ink-soft); }
.chatdock-leave { align-self: flex-start; margin-top: 6px; }

.chatdock-compose { display: flex; gap: 6px; align-items: flex-end; }
.chatdock-compose textarea { flex: 1 1 auto; min-width: 0; min-height: 34px;
  max-height: 96px; padding: 8px 10px; font-size: 12.5px; resize: none; }
.chatdock-err { color: var(--bad-ink); font-size: 11.5px; min-height: 0; }
.chatdock-err:empty { display: none; }

/* The one plain-text first message to someone with no chat key yet
   (apps/api/app/stores/chat_first.py). It must always say it is not
   encrypted: a dashed edge on the bubble and a label under the text. */
.chatdock-firstform { display: flex; flex-direction: column; gap: 6px; }
.chatdock-firstform textarea { min-height: 64px; max-height: 140px; padding: 8px 10px;
  font-size: 12.5px; resize: vertical; }
.chatdock-firstform button { align-self: flex-end; }
.chatdock-waiting { display: flex; flex-direction: column; gap: 6px; }
.chatdock-waiting .chatdock-msg { align-self: flex-end; }
.chatdock-waiting button { align-self: flex-end; }
.ls-plain { border: 1px dashed var(--warn-ink); }
.ls-plain-note { display: block; margin-top: 3px; font-size: 10px; font-weight: 600;
  letter-spacing: .01em; opacity: .85; }
.chatdock-state p.ls-plain-explain { font-size: 11.5px; }

@media (max-width: 640px) {
  /* Full width on a phone; a 320px panel beside a 360px screen is neither. */
  .chatdock { right: 0; left: 0; width: auto; max-width: none; border-radius: 0;
    border-left: 0; border-right: 0; }
  .chatdock-msgs { max-height: 40vh; }
}

[data-theme="light"] .chatdock-msg.theirs { background: #eef1f6; }


/* ── The activity flask ────────────────────────────────────────────────────
   It was a 21px outline in a fixed pale blue with a blue glow behind it. On a
   dark ribbon that reads; on a light one the outline all but disappears and
   only the liquid is left, so the control looked like a smudge rather than a
   button. The glass now takes its colour from the theme, the flask is larger,
   and it sits in a pill like every other control up there — a thing you can
   see is clickable before you hover it. */
.tb-bell { padding-inline: 7px; border-radius: var(--radius-pill);
  border: 1px solid transparent; transition: background .12s, border-color .12s; }
.tb-bell:hover { background: rgba(0,0,0,.42); border-color: rgba(255,255,255,.2); }
.tb-bell:focus-visible { outline: 2px solid var(--aqua-light); outline-offset: 2px; }
.tb-bell[aria-expanded="true"] { background: rgba(0,0,0,.42); }

.tb-bell .tb-flask {
  width: 25px; height: 25px;
  color: #dbeaff;                       /* the glass, via currentColor */
  filter: drop-shadow(0 0 5px rgba(45,124,255,.55));
}
.tb-flask-glass { fill: rgba(255,255,255,.10); }
.tb-flask-bubble { fill: #dff0ff; }
.tb-bell:hover .tb-flask { filter: drop-shadow(0 0 8px rgba(45,124,255,.9)); }

/* Light: a dark outline on a pale ribbon, and no glow to wash it out. */
[data-theme="light"] .tb-bell:hover,
[data-theme="light"] .tb-bell[aria-expanded="true"] { background: #e9edf4;
  border-color: #d2d9e4; }
/* No glow in light mode: the drop-shadow that lifts the flask off a dark
   ribbon only fogs it on a pale one. */
[data-theme="light"] .tb-bell .tb-flask { color: #24365c; filter: none; }
[data-theme="light"] .tb-flask-glass { fill: rgba(36,54,92,.07); }
[data-theme="light"] .tb-flask-bubble { fill: #24365c; }

/* The unread badge has to clear a bigger flask without covering the neck. */
.tb-badge { top: -2px; right: -3px; }


/* ── A year of days, in the identity line ──────────────────────────────────
   It occupies the gap that was already between the name and the action
   buttons — `.pfh-id` had a flexing spacer there.

   Column-major over seven fixed rows: a column is a week, a row a weekday.
   Months label the top; three weekdays label the side, chosen server-side so
   the row for today is always the first one named.

   `--heat-cell` and `--heat-gap` are shared by the grid, the weekday column
   and the month row — they have to agree on a track size or the labels drift
   away from what they label. */
.heat { --heat-cell: 9px; --heat-gap: 2px;
  flex: 1 1 auto; min-width: 0; align-self: center;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 0 14px; }

.heat-body { display: flex; align-items: flex-end; gap: 5px; max-width: 100%; }

/* Fixed while the year scrolls beside it. The empty top cell keeps these
   aligned with the grid rather than with the month row above it. */
.heat-days { display: grid; grid-template-rows: repeat(7, var(--heat-cell));
  gap: var(--heat-gap); flex: none; padding-bottom: 2px;
  font-size: 8px; line-height: var(--heat-cell); color: var(--ink-faint);
  text-align: right; letter-spacing: -.1px; }

/* It fits at most widths, so there is normally nothing to scroll. The
   overflow stays for the narrow cases, but without a visible bar: a scrollbar
   sitting under a graph that fits is just a line of chrome. */
.heat-scroll { min-width: 0; overflow-x: auto;
  scrollbar-width: none; -ms-overflow-style: none; }
.heat-scroll::-webkit-scrollbar { display: none; }

.heat-months { display: grid; grid-auto-flow: column;
  grid-auto-columns: var(--heat-cell); gap: var(--heat-gap);
  height: 12px; font-size: 8.5px; color: var(--ink-faint); }
.heat-months span { white-space: nowrap; overflow: hidden; }

.heat-grid { display: grid; grid-auto-flow: column;
  grid-template-rows: repeat(7, var(--heat-cell));
  grid-auto-columns: var(--heat-cell); gap: var(--heat-gap); }

.heat-cell { width: var(--heat-cell); height: var(--heat-cell); border-radius: 2px;
  background: rgba(255,255,255,.06); }
.heat-cell.l1 { background: #14395f; }
.heat-cell.l2 { background: #1f5fa8; }
.heat-cell.l3 { background: #2f86e0; }
.heat-cell.l4 { background: #6fb6ff; }

.heat-top { font-size: 10.5px; color: var(--ink-faint); text-align: center;
  white-space: nowrap; }
.heat-top strong { color: var(--ink-soft); }
.heat-dot { opacity: .5; margin: 0 4px; }

[data-theme="light"] .heat-cell { background: #e6eaf1; }
[data-theme="light"] .heat-cell.l1 { background: #cfe0f7; }
[data-theme="light"] .heat-cell.l2 { background: #8fbdf0; }
[data-theme="light"] .heat-cell.l3 { background: #4a90e2; }
[data-theme="light"] .heat-cell.l4 { background: #1c5fb0; }
/* ── An avatar showing initials rather than a photo ──────────────────────────
   The placeholder ground (--avatar-bg) is pale in light mode, which is right
   when a photo is about to cover it and wrong when white initials are sitting
   on it — the disc and the ground are two rules of equal weight, and the one
   written later wins. Name the pair so the blue disc always does. */
.tb-me-av.tb-me-initial,
.tb-menu-av.tb-me-initial,
.pfh-av-img.pfh-av-initial,
.pb-m-av.pb-m-avi {
  background: linear-gradient(160deg, #5fa0ff, #1a5fd6);
}

/* Amber on white washes out; the same star needs a deeper gold. */
[data-theme="light"] .ref-star.on { color: #b07400; text-shadow: none; }
[data-theme="light"] .ref-star:hover { color: #8a5b00; }
[data-theme="light"] .ctx-menu,
[data-theme="light"] .ctx-sub { box-shadow: 0 10px 28px rgba(28,36,52,.18); }
[data-theme="light"] .ctx-item.danger { color: #b3261e; }

/* Narrow: the identity line already stacks, so the graph becomes a full-width
   row of its own rather than being squeezed between two columns. */
@media (max-width: 860px) {
  .heat { padding: 8px 0 0; width: 100%; }
  .heat-top { white-space: normal; }
}

/* Right of the heatmap: the person's labs on top, then the buttons in one row.
   A column with its own row of buttons, because the Cite form is a block and
   the invite menu an inline-block, and left to themselves they stacked with
   ragged edges. */
.pfh-act { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.pfh-act-btns { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
.pfh-labs { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; max-width: 340px; }
.pfh-lab { display: inline-flex; align-items: center; gap: 4px; max-width: 100%;
  padding: 3px 10px; border-radius: 999px; border: 1px solid var(--panel-edge);
  font-size: 12px; font-weight: 600; color: var(--ink); text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pfh-lab:hover { border-color: var(--aqua); color: var(--aqua-ink, var(--aqua)); }
@media (max-width: 560px) {
  .pfh-act { margin-left: 0; align-items: center; }
  .pfh-labs, .pfh-act-btns { justify-content: center; }
}


/* ── Discover's filters ────────────────────────────────────────────────────
   A grid of labelled fields rather than a flex row of bare inputs. The row
   ran past the edge and left the last controls half-visible; a grid wraps by
   whole fields, and every control fills its own cell, so nothing is ever
   partly there. */
.disc-filters { display: grid; gap: 8px 10px; margin-top: 10px;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); align-items: end; }
.disc-f { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.disc-f > span { font-size: 10px; font-weight: 700; letter-spacing: .4px;
  text-transform: uppercase; color: var(--ink-faint); }
.disc-f input, .disc-f select {
  width: 100% !important; min-width: 0; height: 30px;
  padding: 0 9px !important; font-size: 12.5px; }
.disc-f-go { display: flex; align-items: center; gap: 8px; }
.disc-f-go .btn { height: 30px; }

/* ── Share sheet ────────────────────────────────────────────────────────────
   Rises from the bottom edge, where a thumb already is. Two scrolls, because
   they answer different questions: the people are a grid read downwards like
   any contact list, the actions are one row read sideways so a new
   destination can be added later without pushing the people off screen. */
.sh-back { position: fixed; inset: 0; z-index: 300; display: flex;
  align-items: flex-end; justify-content: center;
  background: rgba(6,9,16,0); transition: background .2s; }
.sh-back.sh-open { background: rgba(6,9,16,.72); }
.sh-card { width: min(520px, 100%); max-height: 82vh; display: flex; flex-direction: column;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--panel-edge); border-bottom: none;
  border-radius: 18px 18px 0 0; box-shadow: 0 -18px 50px rgba(0,0,0,.55);
  transform: translateY(100%); transition: transform .24s cubic-bezier(.22,.61,.36,1); }
.sh-back.sh-open .sh-card { transform: translateY(0); }
.sh-grab { width: 38px; height: 4px; border-radius: 2px; margin: 8px auto 0;
  background: rgba(255,255,255,.28); flex: 0 0 auto; }
.sh-head { display: flex; align-items: center; padding: 12px 16px 8px;
  font-weight: 700; font-size: var(--fs-400); flex: 0 0 auto; }
.sh-head .sh-sp { flex: 1; }
.sh-x { border: none; background: none; color: var(--ink-faint); font-size: 20px;
  line-height: 1; cursor: pointer; padding: 2px 6px; border-radius: 8px; }
.sh-x:hover { background: var(--surface-hi); color: var(--ink); }

/* People: down the page. */
.sh-people { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px 6px;
  padding: 6px 14px 14px; }
@media (max-width: 380px) { .sh-people { grid-template-columns: repeat(3, 1fr); } }
.sh-person { display: flex; flex-direction: column; align-items: center; gap: 6px;
  text-decoration: none; color: var(--ink); font-size: var(--fs-200); }
.sh-av { width: 58px; height: 58px; border-radius: 50%; display: grid; place-items: center;
  background-size: cover; background-position: center; flex: 0 0 auto;
  background-color: var(--aqua-dark); color: #fff; font-weight: 700; font-size: 20px;
  box-shadow: 0 0 0 2px transparent; transition: box-shadow .15s; }
.sh-person:hover .sh-av { box-shadow: 0 0 0 2px var(--aqua); }
.sh-name { text-align: center; line-height: 1.2; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sh-note { font-size: var(--fs-100); color: var(--ink-faint); text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.sh-wait { grid-column: 1 / -1; color: var(--ink-faint); font-size: var(--fs-200);
  text-align: center; padding: 22px 0; }

/* Actions: across, and only across. */
.sh-actions { flex: 0 0 auto; display: flex; gap: 8px; overflow-x: auto;
  overscroll-behavior-x: contain; scrollbar-width: none;
  padding: 12px 14px calc(14px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--panel-edge); }
.sh-actions::-webkit-scrollbar { height: 0; }
.sh-act { flex: 0 0 auto; display: flex; align-items: center; gap: 7px;
  border: 1px solid var(--panel-edge); background: var(--surface-hi); color: var(--ink);
  border-radius: 999px; padding: 9px 15px; font: inherit; font-size: var(--fs-300);
  font-weight: 600; cursor: pointer; white-space: nowrap; }
.sh-act:hover { border-color: var(--aqua); }
.sh-ico { font-size: 14px; }

body.sh-locked { overflow: hidden; }

/* ── Group chat ────────────────────────────────────────────────────────── */
.chat-newgroup { width: 100%; margin-bottom: 8px; }
.chat-groupnew { border: 1px solid var(--panel-edge); border-radius: var(--radius);
  padding: 10px; margin-bottom: 10px; background: var(--surface-lo); }
.chat-groupnew input[type="text"] { width: 100%; margin-bottom: 8px; }
/* The picker scrolls on its own: a lab of thirty must not push the
   conversation list off the screen to choose three of them. */
.group-people { max-height: 190px; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px;
  font-size: var(--fs-200); color: var(--ink-soft); }
.group-pick { display: flex; align-items: center; gap: 7px; padding: 3px 2px;
  cursor: pointer; border-radius: var(--radius-sm); }
.group-pick:hover { background: var(--surface-hi); color: var(--ink); }

/* ── Post carousel ─────────────────────────────────────────────────────────
   The scrolling is the browser's: a snap-scroller means a swipe works on a
   phone and a trackpad flick works on a laptop before any script has loaded.
   Arrows and dots are the mouse's version of the same thing. */
.post-carousel { position: relative; background: #000; }
.pc-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain; scrollbar-width: none;
  -webkit-overflow-scrolling: touch; }
.pc-track::-webkit-scrollbar { height: 0; }
.pc-shot { flex: 0 0 100%; width: 100%; height: auto; display: block;
  scroll-snap-align: center; }
.pc-arrow { position: absolute; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(0,0,0,.55); color: #fff; font-size: 20px; line-height: 1;
  display: grid; place-items: center; opacity: 0; transition: opacity .15s; }
.post-carousel:hover .pc-arrow, .pc-arrow:focus-visible { opacity: 1; }
.pc-arrow[disabled] { opacity: 0 !important; pointer-events: none; }
.pc-prev { left: 8px; }
.pc-next { right: 8px; }
/* On touch there is no hover to reveal them, and no need — the swipe is the
   control. Showing arrows that only ever sit there is clutter over a photo. */
@media (hover: none) { .pc-arrow { display: none; } }
.pc-count { position: absolute; top: 10px; right: 10px; pointer-events: none;
  background: rgba(0,0,0,.6); color: #fff; border-radius: 999px;
  padding: 3px 9px; font-size: var(--fs-100); font-weight: 700; }
.pc-dots { position: absolute; left: 0; right: 0; bottom: 9px; display: flex;
  justify-content: center; gap: 6px; }
.pc-dot { width: 6px; height: 6px; border-radius: 50%; cursor: pointer;
  background: rgba(255,255,255,.45); transition: background .15s, transform .15s; }
.pc-dot.on { background: #fff; transform: scale(1.25); }

/* ── Sample registry ──────────────────────────────────────────────────────── */
.s-code { font-family: var(--font-mono, ui-monospace, monospace);
  font-weight: 700; color: var(--aqua-bright); text-decoration: none; }
.s-code:hover { text-decoration: underline; }
/* Lineage is indented by depth, so "made from something that was itself made
   from…" reads as the chain it is rather than a flat list. */
.lineage { list-style: none; margin: 0; padding: 0; }
.lineage li { padding: 5px 0; font-size: var(--fs-300); color: var(--ink-soft);
  border-bottom: 1px solid var(--hairline); }
.lineage li:last-child { border-bottom: none; }
.tbl.rows td, .tbl.rows th { padding: 9px 12px; border-bottom: 1px solid var(--hairline); }
.tbl.rows th { text-align: left; font-size: var(--fs-200); color: var(--ink-faint);
  font-weight: 600; }

/* ── Offline papers ───────────────────────────────────────────────────────── */
.rdr-offline-note { font-size: var(--fs-100); color: var(--ink-faint);
  margin-left: 10px; white-space: nowrap; }
#rdr-offline.on { color: var(--ok); border-color: var(--ok); }

/* Focus read uses the whole viewport. Controls appear when the pointer reaches
   the top edge, leaving the paper unobstructed while reading. */
.rdr.rdr-focus { position: fixed; z-index: 1100; inset: 0; height: 100dvh; margin: 0;
  background: var(--well-deep); }
.rdr.rdr-focus .rdr-main { border: 0; border-radius: 0; }
/* Focus read opens with nothing but the paper, but the two toggles still work
   here. They used to be dead: this hid both outright, whatever the buttons
   said. Asked for, they come back over the paper rather than squeezing it. */
.rdr.rdr-focus:not(.show-thumbs) .rdr-thumbs,
.rdr.rdr-focus:not(.show-side) .rdr-side { display: none; }
/* Below the toolbar, not over it. These sat at 11 against the toolbar's 10 and
   covered the controls on its left — the back arrow, the title, and the very
   button that had just opened the thumbnails. */
/* They take their own room rather than lying over the paper: the page gives
   up the width and stays wholly readable. Padded clear of the toolbar, which
   does float above everything. */
.rdr.rdr-focus.show-thumbs .rdr-thumbs,
.rdr.rdr-focus.show-side .rdr-side { padding-top: var(--rdr-top-h, 62px); }
.rdr.rdr-focus .rdr-pages { padding: 28px; }
/* Opaque, not a fade: the old gradient went transparent at its lower edge, so
   the page scrolling beneath printed straight through the controls. */
.rdr.rdr-focus .rdr-top { position: absolute; z-index: 10; inset: 0 0 auto; min-height: 56px;
  padding: 10px max(16px, env(safe-area-inset-left)) 10px max(16px, env(safe-area-inset-right));
  background: var(--surface); border: 0; border-bottom: 1px solid var(--panel-edge);
  border-radius: 0; box-shadow: 0 6px 18px rgba(0,0,0,.35);
  opacity: 0; transform: translateY(-100%); pointer-events: none;
  transition: opacity .18s ease, transform .18s ease; }
.rdr.rdr-focus.show-controls .rdr-top,
.rdr.rdr-focus .rdr-top:focus-within { opacity: 1; transform: translateY(0); pointer-events: auto; }
.rdr.rdr-focus .rdr-title { max-width: min(34vw, 430px); }
@media (max-width: 700px) {
  .rdr.rdr-focus .rdr-pages { padding: 14px 6px; }
  .rdr.rdr-focus .rdr-top { gap: 5px; }
  .rdr.rdr-focus .rdr-title,
  .rdr.rdr-focus .rdr-offline-note { display: none; }
  .rdr.rdr-focus .rdr-tools { gap: 4px; }
  .rdr.rdr-focus .rdr-tools .btn { padding-left: 7px; padding-right: 7px; }
}
.off-row { display: flex; align-items: center; gap: 12px; padding: 10px 14px;
  border-bottom: 1px solid var(--hairline); font-size: var(--fs-300); }
.off-row:last-child { border-bottom: none; }
.off-row .off-t { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; color: var(--ink); }
.off-row .off-s { color: var(--ink-faint); font-size: var(--fs-200);
  flex: 0 0 auto; }

/* ── Radar ────────────────────────────────────────────────────────────────── */
.rad-row { padding: 11px 14px; border-bottom: 1px solid var(--hairline); }
.rad-row:last-child { border-bottom: none; }
.rad-t { color: var(--ink); font-size: var(--fs-300); font-weight: 600;
  line-height: 1.35; }
.rad-m { color: var(--ink-faint); font-size: var(--fs-200); margin-top: 3px; }
.rad-a { display: flex; align-items: center; gap: 8px; margin-top: 8px; }

/* ── Protocols ────────────────────────────────────────────────────────────── */
.proto-steps { margin: 0; padding-left: 22px; color: var(--ink-soft);
  font-size: var(--fs-300); line-height: 1.55; }
.proto-steps li { padding: 5px 0; border-bottom: 1px solid var(--hairline); }
.proto-steps li:last-child { border-bottom: none; }

/* ── To-do rail ───────────────────────────────────────────────────────────── */
#todo-rail .stack > * { width: 100%; }
.todo-list { list-style: none; margin: 12px 0 0; padding: 0; }
.todo { display: flex; align-items: flex-start; gap: 8px; padding: 7px 0;
  border-bottom: 1px solid var(--hairline); font-size: var(--fs-200); }
.todo:last-child { border-bottom: none; }
.todo-tick { background: none; border: none; cursor: pointer; padding: 0;
  color: var(--ink-soft); font-size: 15px; line-height: 1.2; flex: 0 0 auto; }
.todo-text { flex: 1; min-width: 0; color: var(--ink-soft); line-height: 1.4;
  overflow-wrap: anywhere; }
/* Struck through and kept. A list that empties itself says nothing about the
   day you had. */
.todo.done .todo-text { text-decoration: line-through; color: var(--ink-faint); }
.todo.late .todo-when { color: var(--like); font-weight: 700; }
.todo-when { flex: 0 0 auto; color: var(--ink-faint); font-size: var(--fs-100);
  white-space: nowrap; padding-top: 1px; }
.todo-put { color: var(--warn); font-size: var(--fs-100); }
.todo-x { background: none; border: none; color: var(--ink-faint); cursor: pointer;
  padding: 0 2px; font-size: 14px; opacity: 0; transition: opacity .12s; }
.todo:hover .todo-x { opacity: 1; }
.todo-empty { color: var(--ink-faint); font-size: var(--fs-200); padding: 10px 0; }

/* The card that appears when something comes due. */
.todo-due { border: 1px solid var(--aqua); border-radius: var(--radius);
  background: var(--aqua-soft); padding: 10px; margin-top: 10px; }
.todo-due-t { color: var(--ink); font-size: var(--fs-300); font-weight: 600;
  line-height: 1.35; margin-bottom: 8px; }
.todo-due-acts, .todo-pick { display: flex; flex-wrap: wrap; gap: 6px; }
.todo-pick { margin-top: 8px; align-items: center; }
.todo-pick-l { width: 100%; color: var(--ink-faint); font-size: var(--fs-100); }
.todo-when-in { flex: 1; min-width: 150px; }

/* ── The to-do add row ──────────────────────────────────────────────────── */
.todo-add-row { display: flex; align-items: center; gap: 8px; }
.todo-notime { color: var(--ink-faint); font-size: var(--fs-200);
  display: flex; align-items: center; gap: 5px; cursor: pointer; }

/* ── Radar: which list am I looking at ───────────────────────────────────────
   Nothing new is not the same as nothing found, and the page used to render
   both as an empty panel. This line sits above the papers and says which. */
.rad-none { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
  padding: 10px 14px; border-bottom: 1px solid var(--panel-edge);
  background: var(--surface-lo); font-size: var(--fs-200); }
.rad-none span { color: var(--ink-faint); }
.rad-none.rad-fresh { background: rgba(61, 129, 246, .10); }

/* ── Compose tools: a symbol, not a button ───────────────────────────────────
   Three filled pills under an empty text box read as three things you have to
   press before writing anything. The symbol alone is the affordance; it takes
   a ground only under the cursor, where it needs to show it is live. */
.pb-tool { border: none; background: none; cursor: pointer; padding: 5px 7px;
  border-radius: var(--radius-sm); font-size: 16px; line-height: 1;
  color: var(--ink-soft); transition: background .12s, transform .12s; }
.pb-tool:hover { background: var(--hairline); color: var(--ink); }
.pb-tool:active { transform: scale(.92); }
.pb-tool:focus-visible { outline: 2px solid var(--aqua); outline-offset: 1px; }

/* Emoji the sentence suggests, offered while you write. */
.pb-suggest { display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  margin-top: 8px; }
.pb-suggest[hidden] { display: none; }
.pb-suggest-l { color: var(--ink-faint); font-size: var(--fs-100);
  text-transform: uppercase; letter-spacing: .4px; margin-right: 2px; }
.pb-sugg { border: 1px solid var(--panel-edge); background: var(--surface-lo);
  border-radius: var(--radius-sm); cursor: pointer; font-size: 15px;
  line-height: 1; padding: 4px 7px; transition: transform .1s, border-color .1s; }
.pb-sugg:hover { border-color: var(--aqua); transform: translateY(-1px); }

/* ── A mention inside the text ───────────────────────────────────────────────
   The word you typed is the link. It used to be listed twice — inline as plain
   words, and again as a pill row underneath — so the same fact was in two
   places and the half you wrote was not clickable. Colour is the only marker:
   no pill, no background, so a sentence still reads as a sentence. */
.mention { color: var(--aqua-ink); font-weight: 600; text-decoration: none; }
.mention:hover { text-decoration: underline; }
.mention-lab { color: var(--ok-ink); }

/* ── Who liked it ────────────────────────────────────────────────────────────
   The count is the way in. Before this, the only place a like had a name on it
   was your own notifications, which cover your own posts and nobody else's. */
.likes-open { border: none; background: none; cursor: pointer; font: inherit;
  color: var(--ink-faint); padding: 0; border-radius: var(--radius-xs); }
.likes-open:hover { color: var(--ink); text-decoration: underline; }
.likers { display: grid; gap: 2px; max-height: 60vh; overflow-y: auto; }
.liker { display: flex; align-items: center; gap: 10px; padding: 8px 6px;
  border-radius: var(--radius-sm); text-decoration: none; color: inherit; }
.liker:hover { background: var(--surface-lo); }
.liker-av { width: 34px; height: 34px; border-radius: 50%; flex: none;
  background-color: var(--avatar-bg); background-size: cover;
  background-position: center; display: grid; place-items: center;
  font-weight: 800; font-size: 14px; }
.liker-av.liker-initial { color: #fff;
  background: linear-gradient(160deg, #5fa0ff, #1a5fd6); }
.liker-n { font-weight: 600; }
.liker-d { font-size: var(--fs-200); color: var(--ink-faint); }

/* ── Sketcher ────────────────────────────────────────────────────────────────
   Tools across the top, frame left, slides and the generator in the right
   rail. A drawing tool is reached constantly and a generator setting once, so
   the tools take the edge nearest the frame. The frame is the only part that
   should ever be scrolled to, so the rail is fixed-width and it takes the
   rest. */
/* The ribbon. Tabs across the top, then one panel of grouped controls — the
   group name under its row, which is what makes a dense strip readable: you
   find a control by the heading it lives under, not by scanning icons. */
/* Pinned, and pinned above everything it scrolls over. */
.sk-ribbon { position: sticky; top: 0; z-index: 30;
  border-top-left-radius: 0; border-top-right-radius: 0; }
/* `top: 0` pins to the top of the scrollport, and the scrollport includes the
   page's own 24px of top padding — so the ribbon stopped 24px short of the
   top and the canvas scrolled up through the transparent strip left above it,
   which is the drawing appearing over the toolbar. Measured at 1600x900: the
   ribbon settled at y=72 against a content top of y=48. The padding moves onto
   the page so the ribbon can sit flush against the top of the screen, which is
   where a pinned toolbar belongs anyway. */
.content:has(> .sk-ribbon) { padding: 0 0 24px; }
.content:has(> .sk-ribbon) > .sk-ribbon { margin-top: 0; }
/* One row: what this is, the file, the tabs, then the always-on actions hard
   right. `flex-end` keeps the tabs sitting on the bottom border while the
   taller buttons grow upwards off it. */
.sk-tabs { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 2px;
  padding: 6px 8px 0; border-bottom: 1px solid var(--panel-edge); }
.sk-brand { font-size: 14px; font-weight: 700; color: var(--ink-strong);
  white-space: nowrap; padding: 0 8px 6px 3px; }
.sk-file { font-size: var(--fs-100); color: var(--ink-faint); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 170px;
  padding: 0 12px 7px 0; }
.sk-tabs-gap { flex: 1 1 auto; min-width: 10px; }
.sk-tabs .btn { margin-bottom: 4px; }
.sk-tab { border: 1px solid transparent; border-bottom: none; cursor: pointer;
  background: none; color: var(--ink-soft); font-size: var(--fs-200);
  font-weight: 600; padding: 6px 13px; border-radius: 6px 6px 0 0;
  transition: background .12s, color .12s; }
.sk-tab:hover { color: var(--ink); background: var(--surface-lo); }
.sk-tab.on { color: var(--ink); background: var(--surface-lo);
  border-color: var(--panel-edge); margin-bottom: -1px;
  border-bottom: 1px solid var(--surface-lo); }
/* Every tab is exactly the same height — a set height, not a minimum.
   Measured, the tabs ran from 65px (View) to 267px (Structure), so going to
   size a field shoved the canvas 200px down the screen and leaving it pulled
   the canvas back up: the drawing moved under you every time you reached for
   a tool. A minimum could not fix that, because the spread came from the
   panel wrapping onto three rows, and a wrapped row is taller than any floor.
   So the groups do not wrap — `nowrap` plus a sideways scroll for the tab
   that has more controls than fit. A ribbon that scrolls sideways is the
   ordinary answer here, and it keeps the one promise that matters: the canvas
   is always in the same place.

   `stretch` is what it wanted all along once the height is fixed: the groups
   share it, and `margin-top: auto` on the names lands them on one baseline. */
.sk-panel { display: flex; flex-wrap: nowrap; align-items: stretch;
  gap: 2px; padding: 7px 10px 5px; height: 104px; box-sizing: border-box;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: auto; scrollbar-gutter: stable;
  overscroll-behavior-x: contain; }
.sk-group { display: flex; flex-direction: column; gap: 5px; padding: 0 9px;
  flex: 0 0 auto; border-right: 1px solid var(--panel-edge); }
.sk-group:last-child { border-right: none; }
.sk-group-wide { flex: 0 0 auto; min-width: 0; }
/* No `flex: 1` here. In a column-flex group that makes the row grow to fill,
   which stretched every control block to the panel's full height. */
.sk-group-row { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
/* A group is one line. Letting them wrap inside themselves gave six groups six
   different heights, which is what made the ribbon look thrown together — the
   panel wraps between groups instead, on a tidy shared baseline. */
.sk-ribbon .sk-group-row { flex-wrap: nowrap; }
.sk-group-name { font-size: var(--fs-100); color: var(--ink-faint);
  text-align: center; letter-spacing: .3px; margin-top: auto; padding-top: 2px; }
.sk-ribbon select { max-width: 112px; }
/* A slider small enough to live in a ribbon and still be draggable. */
.sk-mini { display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-100); color: var(--ink-soft); white-space: nowrap; }
.sk-mini input[type="range"] { width: 74px; }

.sk-tool-row { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.sk-tool-sep { width: 1px; align-self: stretch; margin: 2px 4px;
  background: var(--panel-edge); }
.sk-tool-spacer { flex: 1 1 auto; min-width: 0; }
.sk-inline { display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-100); color: var(--ink-soft); white-space: nowrap; }
.sk-inline input[type="color"] { width: 34px; height: 26px; padding: 0;
  border: 1px solid var(--panel-edge); border-radius: var(--radius-xs);
  background: none; cursor: pointer; }
.sk-inline .sk-size { width: 58px; }
/* Twelve 22px swatches plus gaps, on one line — wrapped, they made Home the
   second-tallest tab for no reason. */
.sk-ribbon .sk-swatches { max-width: 330px; margin: 0; }
/* A count is typed, not dragged. Wide enough for three digits so 200 grains
   does not sit behind the spinner arrows. */
.sk-num { width: 62px; }
.sk-num-sm { width: 50px; }

/* Slides left, frame centre, library right — a slide editor's shape, because
   that is what this is being used as. The frame is the only part that should
   ever be scrolled to, so both rails are fixed and it takes what is left. */
.sk-layout { display: grid; align-items: start; gap: 14px;
  grid-template-columns: minmax(0, 178px) minmax(0, 1fr) minmax(0, 250px);
  margin-top: 10px; }
@media (max-width: 900px) {
  .sk-layout { grid-template-columns: minmax(0, 1fr); }
  .sk-slides-rail { order: 2; }
  .sk-side { order: 3; }
  .sk-middle { order: 1; }
  /* Stays pinned here too. Dropping to `static` under 1180px was why the
     toolbar scrolled away and the drawing ended up occupying the strip where
     the tabs had been — on the narrow window where the tools are hardest to
     scroll back to. */
}
.sk-side .panel-body, .sk-slides-rail .panel-body { padding: 12px; }
/* No scrollbar of its own. A rail that scrolls internally means two scrollbars
   on one page and a slide you cannot reach without finding the right one —
   the rail just gets as long as it needs and the page scrolls. */
.sk-slides-rail .sk-stages { max-height: none; overflow: visible; }
.sk-side-h { font-size: var(--fs-100); font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: var(--ink-faint); margin: 14px 0 7px; }
.sk-side-h:first-child { margin-top: 0; }

.sk-tool-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; }
.sk-tool { aspect-ratio: 1; display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--panel-edge); border-radius: var(--radius-sm);
  background: var(--surface-lo); color: var(--ink-soft); font-size: 17px;
  line-height: 1; transition: border-color .12s, color .12s; }
.sk-tool:hover { border-color: var(--aqua); color: var(--ink); }
.sk-tool.on { border-color: var(--aqua); color: var(--ink-invert);
  background: linear-gradient(var(--aqua), var(--aqua-dark)); }

.sk-row { display: flex; align-items: center; gap: 8px; margin: 6px 0;
  font-size: var(--fs-200); color: var(--ink-soft); }
.sk-row > span:first-child { width: 52px; flex: none; }
.sk-row input[type="range"] { flex: 1; min-width: 0; }
.sk-row input[type="color"] { width: 40px; height: 26px; padding: 0;
  border: 1px solid var(--panel-edge); border-radius: var(--radius-xs);
  background: none; cursor: pointer; }
.sk-row select { flex: 1; min-width: 0; }
.sk-hint { font-size: var(--fs-100); line-height: 1.5; margin: 8px 0 0; }

/* The frame itself. White whatever the theme is: a figure that came out of
   here goes into a paper, and the paper is white. */
.sk-middle { min-width: 0; display: grid; gap: 10px; align-content: start; }
.sk-stage-wrap { min-width: 0; border: 1px solid var(--panel-edge);
  border-radius: var(--radius); overflow: hidden; background: #ffffff;
  box-shadow: 0 6px 18px rgba(0,0,0,.25); }
.sk-canvas { display: block; width: 100%; height: auto; touch-action: none;
  cursor: crosshair; }

/* Three structures to choose between, stacked in the rail beside the frame —
   big enough to actually tell apart, which is the whole job of a suggestion. */
.sk-suggest { display: grid; gap: 7px; margin-top: 8px; }
.sk-suggest-bar { display: flex; gap: 6px; flex-wrap: wrap; }
.sk-stats { font-size: var(--fs-100); color: var(--ink-faint); margin: 8px 0 0; }
.sk-option { display: block; width: 100%; padding: 0; cursor: pointer;
  border: 1px solid var(--panel-edge); border-radius: var(--radius-sm);
  background: var(--surface-lo); overflow: hidden; text-align: left; }
.sk-option:hover { border-color: var(--aqua); }
.sk-option svg { display: block; width: 100%; height: 72px; }
.sk-option-n { display: block; padding: 5px 8px; font-size: var(--fs-100);
  color: var(--ink-faint); }

.sk-ver, .sk-open { display: block; width: 100%; text-align: left; cursor: pointer;
  border: none; background: none; color: var(--ink-soft); font: inherit;
  font-size: var(--fs-200); padding: 6px 8px; border-radius: var(--radius-sm); }
.sk-ver:hover, .sk-open:hover { background: var(--surface-lo); color: var(--ink); }
.sk-ver-n, .sk-item-n { display: block; font-size: var(--fs-100);
  color: var(--ink-faint); }
.sk-item { display: flex; align-items: center; gap: 4px; }
.sk-item.on { background: var(--aqua-soft, rgba(61,129,246,.14));
  border-radius: var(--radius-sm); }
.sk-item .sk-open { flex: 1; min-width: 0; }
.sk-del { border: none; background: none; cursor: pointer; color: var(--ink-faint);
  font-size: 16px; padding: 2px 7px; border-radius: var(--radius-xs); }
.sk-del:hover { color: var(--bad-ink); }

/* The palette as clickable swatches — what you reach for when recolouring the
   next grain along, which a colour picker is bad at. */
.sk-swatches { display: flex; flex-wrap: wrap; gap: 4px; margin: 8px 0 0; }
.sk-swatch { width: 22px; height: 22px; padding: 0; cursor: pointer;
  border: 1px solid var(--panel-edge); border-radius: var(--radius-xs); }
.sk-swatch:hover { border-color: var(--aqua); transform: scale(1.12); }
.sk-row > b { width: 30px; flex: none; text-align: right;
  font-variant-numeric: tabular-nums; color: var(--ink); font-size: var(--fs-200); }
.sk-size { width: 52px; min-width: 0; padding: 3px 5px; font-size: var(--fs-200); }
.sk-row[hidden] { display: none; }

/* ── The stages of a figure ──────────────────────────────────────────────────
   A process figure is a row of panels, not one drawing. The strip is that row,
   in order, and clicking one puts it on the canvas. */
.sk-stage-fields { display: grid; gap: 6px;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.4fr) auto;
  align-items: center; }
.sk-stage-fields input[type="text"] { width: 100%; min-width: 0; }
.sk-f-title { font-weight: 700; }
.sk-f-cap { grid-column: 1 / -1; }
.sk-stage-fields input[type="color"] { width: 34px; height: 28px; padding: 0;
  border: 1px solid var(--panel-edge); border-radius: var(--radius-xs);
  background: none; cursor: pointer; }

/* Down the rail, not across the bottom — a slide sorter reads as a column,
   and a column is what a five-stage figure needs room for. */
.sk-stages { display: flex; flex-direction: column; gap: 8px;
  padding: 2px 2px 8px; }
.sk-stage { position: relative; flex: 0 0 auto; cursor: pointer;
  border: 1px solid var(--panel-edge); border-radius: var(--radius-sm);
  background: var(--tint, var(--surface-lo)); padding: 6px; }
.sk-stage.on { border-color: var(--aqua); box-shadow: 0 0 0 2px var(--aqua-glow); }
/* The tint is the paper colour of the panel, so the label on it is always
   dark — this strip shows the figure's own colours, not the app's theme. */
.sk-stage-t { font-size: var(--fs-100); font-weight: 700; color: #1f2430;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sk-stage-img { margin: 5px 0 4px; border-radius: var(--radius-xs);
  overflow: hidden; background: #fff; }
.sk-stage-img svg { display: block; width: 100%; height: 62px; }
/* A thumbnail still being drawn (sketcher.js fillThumbs). */
.sk-stage-wait { height: 62px; background: linear-gradient(90deg, #ffffff10, #ffffff22, #ffffff10); }
.sk-stage-n { font-size: var(--fs-100); color: #5a6678; }
.sk-stage-x { position: absolute; top: 2px; right: 2px; border: none;
  background: rgba(255,255,255,.75); color: #1f2430; cursor: pointer;
  border-radius: var(--radius-xs); font-size: 13px; line-height: 1;
  padding: 1px 5px; opacity: 0; transition: opacity .12s; }
.sk-stage:hover .sk-stage-x { opacity: 1; }
.sk-stage-add { flex: 0 0 34px; align-self: stretch; cursor: pointer;
  border: 1px dashed var(--panel-edge); border-radius: var(--radius-sm);
  background: none; color: var(--ink-faint); font-size: 20px; }
.sk-stage-add:hover { border-color: var(--aqua); color: var(--ink); }

/* ── Equipment booking form: From / To, Start / End, all the same size ────── */
.bk-form .bk-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.bk-form .field { display: flex; flex-direction: column; gap: 6px; margin: 0 0 12px; min-width: 0; }
.bk-form .field .lab small { font-weight: 400; color: var(--ink-faint); }
.bk-form input[type="date"], .bk-form input[type="time"], .bk-form input[type="text"] {
  width: 100%; box-sizing: border-box; height: 40px; padding: 0 12px; font: inherit; font-size: 14px;
  border: 1px solid var(--panel-edge); border-radius: 10px; background: var(--bg); color: var(--ink); }
.bk-form input:focus { outline: none; border-color: var(--aqua); box-shadow: 0 0 0 3px var(--aqua-glow); }
.bk-form .bk-span { margin: -4px 0 12px; font-size: 12.5px; color: var(--aqua-ink); min-height: 0; }
.bk-form .bk-span:empty { display: none; }
.bk-form .bk-error { margin: 0 0 10px; padding: 8px 10px; border-radius: 8px; font-size: 13px;
  background: color-mix(in srgb, var(--bad-ink, #c0392b) 12%, transparent); color: var(--bad-ink, #c0392b); }
.bk-form .bk-error[hidden] { display: none; }
@media (max-width: 420px) { .bk-form .bk-row { grid-template-columns: 1fr; gap: 0; } }

/* Calendar: booking equipment over a run of days. */
.tb-cal-add .tb-cal-eq { width: 100%; height: 30px; margin-bottom: 6px; padding: 0 8px; font: inherit; font-size: 12.5px;
  border: 1px solid var(--panel-edge); border-radius: 8px; background: var(--bg); color: var(--ink); }
.tb-cal-until { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: 12px; color: var(--ink-soft); }
.tb-cal-until[hidden] { display: none; }
.tb-cal-until span { width: 58px; flex: none; }
.tb-cal-add .tb-cal-until input { flex: 1; height: 30px; }
.tb-cal-span { font-size: 12px; color: var(--aqua-ink); margin-top: 4px; }
.tb-cal-span:empty { display: none; }
.cal-cell.in-range { background: color-mix(in srgb, var(--aqua) 18%, transparent); border-radius: 6px; }

/* Calendar: From / To each show their day; a hint says what a click will do. */
.tb-cal-times .t12-label { display: flex; flex-direction: column; line-height: 1.15; min-width: 64px; }
.tb-cal-times .t12-day { font-size: 10.5px; font-weight: 600; color: var(--aqua-ink); white-space: nowrap; }
.tb-cal-hint { font-size: 11.5px; color: var(--ink-faint); margin: 6px 0 2px; line-height: 1.4; }
.tb-cal-hint:empty { display: none; }

/* Calendar: a reminder, and who gets it. */
.tb-cal-remind { margin-top: 6px; }
.tb-cal-remind[hidden], .tb-cal-add .tb-cal-eq[hidden], .tb-cal-people[hidden] { display: none; }
.tb-cal-people { display: flex; flex-direction: column; gap: 2px; max-height: 132px; overflow-y: auto;
  margin-bottom: 6px; padding: 6px 8px; border: 1px solid var(--panel-edge); border-radius: 8px; }
.tb-cal-person { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink); }

/* Booking window: history, and a picked time that is already taken. */
.bk-form .bk-hist { margin: 4px 0 8px; }
.bk-form details.bk-hist summary { cursor: pointer; list-style: revert; }
.bk-form .bk-ex { padding: 4px 0; border-bottom: 1px solid var(--hairline, rgba(0,0,0,.06)); }
.bk-form .bk-ex:last-child { border-bottom: 0; }
.bk-form.bk-clash .bk-row input[type="time"],
.bk-form.bk-clash .bk-row input[type="date"] { filter: blur(1.2px) grayscale(1); opacity: .55;
  border-color: var(--bad-ink, #c0392b); transition: filter .15s, opacity .15s; }
.bk-form.bk-clash .bk-row input:focus { filter: none; opacity: 1; }
.bk-form #bk-submit:disabled { opacity: .45; cursor: not-allowed; }

/* The chat window slides up from the bottom edge when it opens, whether by a
   click or because a message arrived. */
@keyframes chatdock-up { from { transform: translateY(100%); opacity: .4; } to { transform: none; opacity: 1; } }
.chatdock:not([hidden]) { animation: chatdock-up .28s cubic-bezier(.2,.8,.3,1); }
@media (prefers-reduced-motion: reduce) { .chatdock:not([hidden]) { animation: none; } }

/* Chat window: files about to be sent, and the attach button. */
.chatdock-tray { padding: 4px 8px 0; }
.chatdock-compose .lsf-add { width: 34px; height: 34px; min-width: 34px; }
.chatdock-msg .lsf-list { margin-top: 4px; }

/* Institute picker (static/js/affiliation.js): search results and "add it". */
.aff-results { display: flex; flex-direction: column; margin: -6px 0 12px;
  border: 1px solid var(--panel-edge); border-radius: var(--radius); background: var(--surface-hi);
  max-height: 260px; overflow-y: auto; }
.aff-item { text-align: left; padding: 9px 12px; background: none; border: 0;
  border-bottom: 1px solid var(--panel-edge); color: var(--ink); cursor: pointer; font: inherit; }
.aff-item:last-child { border-bottom: 0; }
.aff-item:hover, .aff-item:focus-visible { background: var(--surface); }
.aff-add-link { color: var(--aqua); }
.aff-new { border: 1px dashed var(--panel-edge); border-radius: var(--radius); padding: 12px; margin-bottom: 12px; }
.aff-status:empty { display: none; }
.aff-status { margin: -6px 0 10px; font-size: 12.5px; }

/* Procurement editor heading and clickable list rows. */
.page-head.cform-editor-head { justify-content: space-between; flex-wrap: wrap; }
.cform-editor-title { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: flex-end; gap: 8px 14px; text-align: right; margin-left: auto; }
.cform-editor-actions { display: flex; align-items: center; gap: 10px; }
.cform-sno[readonly] { opacity: .75; cursor: default; }
.cform-list-row { cursor: pointer; }
.cform-edit-link { color: inherit; text-decoration: none; }
.cform-edit-link:hover { text-decoration: underline; }
.cform-edit-link:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
