:root {
  /* surfaces */
  --background: 240 20% 99%;
  --foreground: 240 10% 3.9%;
  --card: 0 0% 100%;
  --card-2: 240 20% 97.5%;
  --muted: 240 4.8% 95.9%;
  --muted-foreground: 240 4% 44%;
  --accent: 240 4.8% 95.5%;
  --border: 240 6% 92.5%;
  --border-strong: 240 6% 85%;
  --input: 240 6% 83%;

  /* brand */
  --primary: 238 72% 56%;
  --primary-hover: 238 72% 50%;
  --primary-foreground: 0 0% 100%;
  --primary-muted: 238 60% 96%;
  --ring: 238 72% 56%;

  /* semantic */
  --destructive: 0 72% 48%;
  --destructive-foreground: 0 0% 100%;
  --success: 145 55% 38%;
  --success-dot: 145 63% 43%;
  --warning: 32 90% 44%;

  /* radius scale */
  --radius: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-md: calc(var(--radius) - 2px);
  --radius-sm: calc(var(--radius) - 4px);
  --radius-full: 999px;

  /* elevation scale */
  --shadow-sm: 0 1px 2px hsl(240 8% 12% / 0.05);
  --shadow-md: 0 4px 12px hsl(240 8% 12% / 0.08), 0 1px 3px hsl(240 8% 12% / 0.05);
  --shadow-lg: 0 12px 32px hsl(240 8% 12% / 0.12), 0 2px 8px hsl(240 8% 12% / 0.06);
  --shadow: var(--shadow-sm); /* back-compat alias */

  /* type + spacing */
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --text-xs: 0.75rem;
  --text-sm: 0.8125rem;
  --text-base: 0.9375rem;
  --text-md: 1.0625rem;
  --text-lg: 1.25rem;
  --text-xl: 1.625rem;
  --space-1: .25rem; --space-2: .5rem; --space-3: .75rem; --space-4: 1rem;
  --space-5: 1.5rem; --space-6: 2rem; --space-8: 3rem;

  /* syntax highlighting */
  --syn-comment: 240 4% 55%;
  --syn-keyword: 265 60% 52%;
  --syn-string: 145 45% 38%;
  --syn-number: 25 72% 45%;
  --syn-func: 215 72% 48%;
}
/* dark palette — the shared (non-theme) tokens for dark. Applied for explicit
 * dark mode (`[data-mode="dark"]`), and for system mode under an OS dark
 * preference. Light is the base `:root` above; each theme re-tints its own
 * surfaces for dark in the theme section below. */
[data-mode="dark"] {
  --background: 240 10% 3.9%;
  --foreground: 0 0% 98%;
  --card: 240 10% 6.5%;
  --card-2: 240 10% 8.5%;
  --muted: 240 3.7% 15.9%;
  --muted-foreground: 240 5% 65%;
  --accent: 240 3.7% 15.9%;
  --border: 240 4% 18%;
  --border-strong: 240 4% 26%;
  --input: 240 4% 24%;
  --primary: 234 89% 74%;
  --primary-hover: 234 89% 80%;
  --primary-foreground: 240 10% 8%;
  --primary-muted: 234 40% 22%;
  --ring: 234 89% 74%;
  --destructive: 0 72% 62%;
  --destructive-foreground: 0 0% 100%;
  --success: 145 55% 58%;
  --success-dot: 145 63% 52%;
  --warning: 38 92% 62%;
  --shadow-sm: 0 1px 2px hsl(0 0% 0% / 0.5);
  --shadow-md: 0 2px 6px hsl(0 0% 0% / 0.55), 0 8px 24px hsl(0 0% 0% / 0.35);
  --shadow-lg: 0 12px 32px hsl(0 0% 0% / 0.6);
  --shadow: var(--shadow-sm);
  --syn-comment: 240 5% 55%;
  --syn-keyword: 265 84% 80%;
  --syn-string: 145 55% 68%;
  --syn-number: 30 90% 70%;
  --syn-func: 210 90% 74%;
}
@media (prefers-color-scheme: dark) {
  [data-mode="system"] {
    --background: 240 10% 3.9%; --foreground: 0 0% 98%;
    --card: 240 10% 6.5%; --card-2: 240 10% 8.5%;
    --muted: 240 3.7% 15.9%; --muted-foreground: 240 5% 65%; --accent: 240 3.7% 15.9%;
    --border: 240 4% 18%; --border-strong: 240 4% 26%; --input: 240 4% 24%;
    --primary: 234 89% 74%; --primary-hover: 234 89% 80%; --primary-foreground: 240 10% 8%;
    --primary-muted: 234 40% 22%; --ring: 234 89% 74%;
    --destructive: 0 72% 62%; --destructive-foreground: 0 0% 100%;
    --success: 145 55% 58%; --success-dot: 145 63% 52%; --warning: 38 92% 62%;
    --shadow-sm: 0 1px 2px hsl(0 0% 0% / 0.5);
    --shadow-md: 0 2px 6px hsl(0 0% 0% / 0.55), 0 8px 24px hsl(0 0% 0% / 0.35);
    --shadow-lg: 0 12px 32px hsl(0 0% 0% / 0.6); --shadow: var(--shadow-sm);
    --syn-comment: 240 5% 55%; --syn-keyword: 265 84% 80%; --syn-string: 145 55% 68%;
    --syn-number: 30 90% 70%; --syn-func: 210 90% 74%;
  }
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  font: 15px/1.6 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: hsl(var(--primary)); }

/* header / nav */
header.nav {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: .35rem; flex-wrap: wrap;
  padding: .55rem .85rem;
  background: hsl(var(--background) / 0.72);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid hsl(var(--border));
}
header.nav .brand { display: inline-flex; align-items: center; gap: .4rem; font-weight: 650; color: hsl(var(--foreground)); text-decoration: none; padding: .35rem .5rem; }
header.nav .brand .icon { width: 1.05rem; height: 1.05rem; color: hsl(var(--primary)); }
header.nav a.navlink {
  color: hsl(var(--muted-foreground)); text-decoration: none;
  font-size: .875rem; font-weight: 500;
  padding: .4rem .6rem; border-radius: var(--radius-md);
  transition: background .12s ease, color .12s ease;
}
header.nav a.navlink:hover { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
/* active page (set client-side from location.pathname) — subtle by default */
header.nav a.navlink.on, header.nav summary.navlink.on { color: hsl(var(--primary)); font-weight: 560; }
form.search { position: relative; margin-left: auto; flex: 0 1 15rem; min-width: 7rem; }
form.search .icon { position: absolute; left: .55rem; top: 50%; transform: translateY(-50%); width: 1rem; height: 1rem; color: hsl(var(--muted-foreground)); pointer-events: none; }
form.search input {
  width: 100%; appearance: none;
  background: hsl(var(--card)); color: hsl(var(--foreground));
  border: 1px solid hsl(var(--border-strong)); border-radius: var(--radius-md);
  padding: .45rem .6rem .45rem 2rem; font-size: .875rem;
  transition: border-color .12s ease, box-shadow .12s ease;
}
form.search input::placeholder { color: hsl(var(--muted-foreground)); }
form.search input:focus-visible, .login-input:focus-visible {
  outline: none; border-color: hsl(var(--ring));
  box-shadow: 0 0 0 3px hsl(var(--ring) / 0.25);
}

/* nav dropdowns (Tracking / Ops) + the user menu — zero-JS via <details> */
header.nav .dropdown { position: relative; }
header.nav .dropdown > summary { list-style: none; cursor: pointer; }
header.nav .dropdown > summary::-webkit-details-marker { display: none; }
header.nav summary.drop::after { content: "▾"; font-size: .7em; margin-left: .3rem; opacity: .65; }
header.nav .dropdown[open] > summary.navlink { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
header.nav .dropdown-panel {
  position: absolute; top: calc(100% + .35rem); left: 0; z-index: 40;
  min-width: 12rem; display: flex; flex-direction: column; gap: .05rem;
  background: hsl(var(--card)); border: 1px solid hsl(var(--border));
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg); padding: .35rem;
}
header.nav .dropdown-panel.right { left: auto; right: 0; }
header.nav .dropdown-panel a.navlink { display: block; }
header.nav .dropdown-panel .menu-theme { padding: .1rem .3rem .5rem; margin: 0 0 .3rem; }
header.nav .dropdown-panel .logout { margin-top: .1rem; }
header.nav .user-btn {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: var(--radius-full); flex: none;
  color: hsl(var(--muted-foreground)); background: hsl(var(--card)); border: 1px solid hsl(var(--border-strong));
}
header.nav .user-btn::-webkit-details-marker { display: none; }
header.nav .user-btn svg { width: 1.1rem; height: 1.1rem; }
header.nav .dropdown.user { margin-left: .4rem; }
header.nav .dropdown.user[open] .user-btn { color: hsl(var(--foreground)); background: hsl(var(--accent)); }

/* layout */
main { max-width: 46rem; margin: 0 auto; padding: 1.3rem 1rem 4rem; }
h1 { font-size: 1.85rem; font-weight: 630; letter-spacing: -0.022em; line-height: 1.15; margin: .1rem 0 .4rem; }
h2 { font-size: var(--text-lg); font-weight: 620; letter-spacing: -0.015em; line-height: 1.25; margin: 2rem 0 .4rem; }
h3 { font-size: var(--text-md); font-weight: 620; letter-spacing: -0.01em; line-height: 1.3; margin: 1.2rem 0 .25rem; }
.subtitle { color: hsl(var(--muted-foreground)); font-size: 1rem; margin: .2rem 0 1.6rem; }
.journals-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
.journals-head .subtitle { margin-bottom: 1rem; }
.empty { color: hsl(var(--muted-foreground)); padding: 1.1rem .9rem; margin: 0; text-align: center; font-size: .9rem; }

/* dashboard summary strip: a wrapping row of at-a-glance figure cards. Purely a
   snapshot at page load (refreshes on reload), so no client state. */
.stats-strip { display: flex; flex-wrap: wrap; gap: .7rem; margin: 0 0 1.6rem; }
.stats-strip .stat { flex: 1 1 8.5rem; min-width: 8.5rem; background: hsl(var(--card)); border: 1px solid hsl(var(--border)); border-radius: var(--radius-lg); padding: .65rem .85rem; }
/* A stat that links to its page: no underline, subtle hover affordance. */
.stats-strip a.stat-link { display: block; text-decoration: none; color: inherit; transition: border-color .12s ease, background .12s ease; }
.stats-strip a.stat-link:hover { border-color: hsl(var(--primary)); background: hsl(var(--accent)); }
.stats-strip .stat-num { font-size: 1.55rem; font-weight: 640; line-height: 1.05; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.stats-strip .stat-label { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .04em; color: hsl(var(--muted-foreground)); margin-top: .15rem; }
.stats-strip .stat-sub { font-size: var(--text-xs); color: hsl(var(--muted-foreground)); margin-top: .2rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stats-strip .stat.prim .stat-num { color: hsl(var(--primary)); }
.stats-strip .stat.warn .stat-num { color: hsl(var(--warning)); }
.stats-strip .stat.over { border-color: hsl(var(--destructive) / .4); }
.stats-strip .stat.over .stat-num { color: hsl(var(--destructive)); }
.stats-strip .stat.ok .stat-num { color: hsl(var(--success)); }
.stats-strip .stat-fail { color: hsl(var(--destructive)); }

/* KB landing: the "Trust" header row carrying the Verify-all action */
.kb-trust-head { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin: 0 0 .6rem; }
.kb-trust-head h2 { margin: 0; font-size: 1rem; }
.kb-trust-head form.inline { margin: 0; }

/* KB landing: a card per top-level collection — its recursive document count
   and, for provenance-bearing kinds, the derived trust mix (●/◐/○). */
.kb-collections { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: .6rem; margin: 0 0 1.6rem; }
.kb-col { display: flex; flex-direction: column; gap: .45rem; text-decoration: none; color: inherit; background: hsl(var(--card)); border: 1px solid hsl(var(--border)); border-radius: var(--radius-lg); padding: .6rem .8rem; transition: border-color .12s ease, background .12s ease; }
.kb-col:hover { border-color: hsl(var(--primary)); background: hsl(var(--accent)); }
.kb-col-head { display: flex; align-items: baseline; gap: .5rem; }
.kb-col-n { font-size: 1.35rem; font-weight: 640; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.kb-col-name { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .04em; color: hsl(var(--muted-foreground)); }
/* the trust mix: three tinted counts, monospace glyph + number */
.trust-mix { display: flex; flex-wrap: wrap; gap: .5rem; font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.trust-mix .trust { display: inline-flex; align-items: center; gap: .18rem; }
.trust.ok { color: hsl(var(--success)); }
.trust.warn { color: hsl(var(--warning)); }
.trust.muted { color: hsl(var(--muted-foreground)); }

/* the per-item trust pill on a KB document's detail page */
.trust-badge { display: inline-flex; align-items: center; gap: .3rem; font-size: var(--text-xs); font-weight: 500; padding: .12rem .55rem; border-radius: var(--radius-full); background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); border: 1px solid transparent; white-space: nowrap; }
.trust-badge .trust-dot { line-height: 1; }
.trust-badge.ok { color: hsl(var(--success)); background: hsl(var(--success) / .12); border-color: hsl(var(--success) / .3); }
.trust-badge.warn { color: hsl(var(--warning)); background: hsl(var(--warning) / .12); border-color: hsl(var(--warning) / .3); }
/* KB entry upstream-sources pane: a collapsible list of the `sources.citekeys`
   the entry is built on, shown below the toolbar. Collapsed by default. */
.kb-upstream { margin: .5rem 0 1rem; border: 1px solid hsl(var(--border)); border-radius: var(--radius-md); background: hsl(var(--card)); }
.kb-upstream > summary { display: flex; align-items: center; justify-content: space-between; gap: .6rem; padding: .5rem .8rem; cursor: pointer; list-style: none; user-select: none; }
.kb-upstream > summary::-webkit-details-marker { display: none; }
.kb-upstream-title::before { content: "\25B8"; display: inline-block; color: hsl(var(--muted-foreground)); transition: transform .12s ease; }
.kb-upstream[open] .kb-upstream-title::before { transform: rotate(90deg); }
.kb-upstream-title { display: inline-flex; align-items: center; gap: .4rem; font-weight: 560; }
.kb-upstream-counts { display: inline-flex; gap: .3rem; }
.kb-upstream > .card { border: none; border-top: 1px solid hsl(var(--border)); border-radius: 0; margin: 0; box-shadow: none; }

/* pane grid: on wide (desktop) viewports a page that carries `.pane-grid` tiles
   its `.pane` sections into columns instead of one long scroll. Opt-in, so only
   pages that use it widen — reading pages keep the narrow single column. Below
   the breakpoint (or without `:has()` support) it stays a plain block → the
   sections stack exactly as before, so mobile is unchanged. */
@media (min-width: 60rem) {
  /* Page width is one explicit knob: a `w-*` class the shared `shell` layout puts
     on `main` (no more sniffing the first child). `[data-theme]` scoping lifts
     specificity above the per-theme `main` rules (e.g. journal caps main at
     42rem) so a page's declared width wins on every theme.
       `w-wide` — the default (app/list/detail pages), ≤74rem on desktop.
       `w-full` — near-full-bleed (the terminal). Narrow on mobile regardless. */
  [data-theme] main.w-wide { max-width: 74rem; }
  [data-theme] main.w-full { max-width: 112rem; padding-left: 1rem; padding-right: 1rem; }
  .pane-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(26rem, 1fr)); gap: 1rem 1.5rem; align-items: start; }
  .pane-grid > .pane > h2 { margin-top: .4rem; }
  /* a pane that spans the full grid width (every column) instead of one cell */
  .pane-grid > .pane-full { grid-column: 1 / -1; }
  /* a section that should stay a single, normal-width column on a widened page */
  .single-col { max-width: 46rem; }
}
/* a grid item that spans every column of its `.pane-grid` (inert below the grid
   breakpoint, where the grid is a plain block). */
.span-full { grid-column: 1 / -1; }
/* pane header: title on the left, a "see all" action on the right */
.pane-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
/* `min-width: 0` lets the heading shrink below its flex-item default (which
   would otherwise hold the row at the title's full intrinsic width); a long
   unbroken title (an underscore-slug project name with no spaces to wrap at)
   still needs `overflow-wrap: anywhere` to break onto the next line instead of
   forcing the whole row into horizontal scroll on narrow viewports. */
.pane-head h2 { margin: .4rem 0; min-width: 0; overflow-wrap: anywhere; }
/* a bit of breathing room below a pane's header, before its body */
.card.tool > .pane-head { margin-bottom: .55rem; }

/* breadcrumb */
nav.crumb { display: flex; align-items: center; flex-wrap: wrap; gap: .1rem; color: hsl(var(--muted-foreground)); font-size: .82rem; margin-bottom: 1rem; }
nav.crumb a { color: hsl(var(--muted-foreground)); text-decoration: none; padding: .12rem .35rem; border-radius: var(--radius-sm); transition: background .1s ease, color .1s ease; }
nav.crumb a:hover { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
nav.crumb .sep .icon { width: .85rem; height: .85rem; opacity: .55; }
nav.crumb .here { color: hsl(var(--foreground)); padding: .12rem .35rem; }

/* card + rows */
.card { background: hsl(var(--card)); border: 1px solid hsl(var(--border)); border-radius: var(--radius-lg); overflow: hidden; box-shadow: none; margin: .4rem 0 1.3rem; }
.card.interactive { transition: box-shadow .16s ease, border-color .16s ease; }
.card.interactive:hover { box-shadow: var(--shadow-sm); border-color: hsl(var(--border-strong)); }
a.row { position: relative; display: flex; align-items: center; gap: .7rem; padding: .68rem .85rem; color: hsl(var(--foreground)); text-decoration: none; transition: background .12s ease; }
/* subtle, inset row divider (gap left & right) instead of an edge-to-edge line */
a.row::before { content: ""; position: absolute; top: 0; left: .85rem; right: .85rem; height: 1px; background: hsl(var(--border) / .55); }
.card > a.row:first-child::before, a.row:first-child::before { content: none; }
a.row:hover { background: hsl(var(--accent)); }
a.row:hover .row-icon { color: hsl(var(--primary)); }
a.row:active { background: hsl(var(--primary-muted)); }
.row-icon { flex: none; display: inline-flex; color: hsl(var(--muted-foreground)); transition: color .12s ease; }
.row-icon .icon { width: 1.05rem; height: 1.05rem; }
.row-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .92rem; }
.badge { margin-left: auto; flex: none; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); color: hsl(var(--muted-foreground)); background: hsl(var(--muted)); border: none; padding: .08rem .5rem; border-radius: var(--radius-full); }
a.row.stacked { flex-direction: column; align-items: stretch; gap: .25rem; }
.row-top { display: flex; align-items: center; gap: .6rem; }
.snippet { color: hsl(var(--muted-foreground)); font-size: .82rem; padding-left: 1.75rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* grouped search results: a category heading + count above each result card */
.search-group + .search-group { margin-top: 1.25rem; }
h2.search-cat { display: flex; align-items: baseline; gap: .5rem; }
h2.search-cat .search-count { font-size: .8rem; font-weight: 500; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }
/* category filter bar: a row of toggle chips above the grouped results */
.search-filter { display: flex; flex-wrap: wrap; gap: .4rem; margin: .2rem 0 1.25rem; }
.search-filter .chip {
  cursor: pointer; font: inherit; font-size: .82rem; line-height: 1;
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .38rem .7rem; border-radius: 999px;
  border: 1px solid hsl(var(--border)); background: hsl(var(--card));
  color: hsl(var(--muted-foreground));
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.search-filter .chip:hover { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
.search-filter .chip.active { background: hsl(var(--primary-muted)); border-color: hsl(var(--primary)); color: hsl(var(--primary)); font-weight: 560; }
.search-filter .chip .chip-count { font-variant-numeric: tabular-nums; opacity: .8; }

/* literature: external search + ingest */
.lit-search { display: flex; gap: .5rem; margin: .3rem 0 1.25rem; max-width: 640px; }
.lit-search .login-input { flex: 1; margin: 0; }
.lit-group + .lit-group { margin-top: 1.5rem; }
.lit-list { display: flex; flex-direction: column; gap: .75rem; margin-top: .6rem; }
.lit-hit { border: 1px solid hsl(var(--border)); border-radius: var(--radius-lg); padding: .85rem 1rem; background: hsl(var(--card)); }
.lit-hit-head { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; }
.lit-title { font-size: .98rem; font-weight: 600; margin: 0; line-height: 1.35; }
.lit-byline { color: hsl(var(--muted-foreground)); font-size: .82rem; margin: .3rem 0 0; }
.lit-abstract { margin: .5rem 0 0; }
.lit-abstract summary { cursor: pointer; font-size: .8rem; color: hsl(var(--primary)); width: max-content; }
.lit-abstract p { font-size: .84rem; color: hsl(var(--foreground)); margin: .4rem 0 0; line-height: 1.5; }
.lit-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; margin-top: .7rem; }
.lit-note { font-size: .8rem; color: hsl(var(--muted-foreground)); }
.lit-abstract-body { font-size: .88rem; line-height: 1.55; margin: .2rem 0 0; }
.lit-bibtex { margin: .3rem 0 0; padding: .7rem .8rem; background: hsl(var(--muted)); border-radius: var(--radius-md); overflow-x: auto; font-size: .8rem; }
/* literature library: faceted browse */
.lib-active { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin: .2rem 0 1rem; font-size: .85rem; color: hsl(var(--muted-foreground)); }
/* library server-side sort control (above the record list) */
.lib-sort { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: 0 0 .8rem; }
.lib-sort-label { color: hsl(var(--muted-foreground)); text-transform: uppercase; letter-spacing: .04em; font-size: .7rem; font-weight: 600; margin-right: .1rem; }
.lib-sort-link { text-decoration: none; color: hsl(var(--muted-foreground)); font-size: .82rem; padding: .16rem .5rem; border-radius: var(--radius-sm); }
.lib-sort-link:hover { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
.lib-sort-link.active { background: hsl(var(--primary-muted)); color: hsl(var(--primary)); font-weight: 600; }
.lib-layout { display: flex; flex-direction: column; gap: 1.1rem; }
/* Mobile: the facets collapse into a "Filters" drawer (checkbox toggle) so the
   records show first; a sr-only checkbox keeps it keyboard-accessible. */
.lib-facets-check { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.lib-facets-toggle { cursor: pointer; user-select: none; width: max-content; display: inline-flex; align-items: center; gap: .4rem; font-weight: 600; font-size: .9rem; padding: .45rem .8rem; border: 1px solid hsl(var(--border)); border-radius: var(--radius-sm); background: hsl(var(--card)); }
.lib-facets-toggle::before { content: "▸"; color: hsl(var(--muted-foreground)); font-size: .8em; }
.lib-facets-check:checked ~ .lib-facets-toggle { margin-bottom: .8rem; }
.lib-facets-check:checked ~ .lib-facets-toggle::before { content: "▾"; }
.lib-facets-check:focus-visible ~ .lib-facets-toggle { outline: 2px solid hsl(var(--primary)); outline-offset: 2px; }
.lib-facets { display: none; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: .6rem 1.2rem; align-content: start; }
.lib-facets-check:checked ~ .lib-facets { display: grid; }
/* Per-facet "N more" overflow toggle. */
.facet-more { margin-top: .1rem; }
.facet-more > summary { cursor: pointer; list-style: none; font-size: .78rem; color: hsl(var(--primary)); padding: .1rem .4rem; }
.facet-more > summary::-webkit-details-marker { display: none; }
.facet-more[open] > summary { color: hsl(var(--muted-foreground)); }
.facet-group { min-width: 0; }
.facet-title { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: hsl(var(--muted-foreground)); margin: 0 0 .3rem; }
.facet-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .06rem; }
.facet-link { display: flex; justify-content: space-between; gap: .5rem; padding: .16rem .4rem; border-radius: var(--radius-sm); font-size: .82rem; color: hsl(var(--foreground)); text-decoration: none; }
.facet-link:hover { background: hsl(var(--accent)); }
.facet-link.active { background: hsl(var(--primary-muted)); color: hsl(var(--primary)); font-weight: 560; }
.facet-val { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.facet-count { flex: none; font-variant-numeric: tabular-nums; color: hsl(var(--muted-foreground)); }
.lib-list { list-style: none; margin: .2rem 0 0; padding: 0; }
.lib-row { display: flex; gap: .8rem; align-items: baseline; padding: .55rem .4rem; border-top: 1px solid hsl(var(--border)); text-decoration: none; color: inherit; }
.lib-row:hover { background: hsl(var(--accent)); }
.lib-list li:first-child .lib-row { border-top: none; }
.lib-year { flex: none; width: 3rem; font-variant-numeric: tabular-nums; font-size: .82rem; color: hsl(var(--muted-foreground)); }
.lib-body { min-width: 0; flex: 1; }
.lib-title { display: block; font-weight: 560; font-size: .92rem; line-height: 1.35; }
.lib-byline { display: block; font-size: .8rem; color: hsl(var(--muted-foreground)); margin-top: .1rem; }
.lib-badges { flex: none; display: flex; align-items: center; gap: .4rem; }
.lib-status { font-size: .68rem; text-transform: uppercase; letter-spacing: .03em; padding: .08rem .4rem; border-radius: var(--radius-sm); background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); white-space: nowrap; }
.lib-status.status-verified { background: hsl(145 45% 92%); color: hsl(145 55% 28%); }
.lib-status.status-needs_review { background: hsl(38 90% 92%); color: hsl(30 70% 34%); }
.lib-status.status-unverifiable { background: hsl(0 70% 94%); color: hsl(0 60% 42%); }
/* PDF / markdown in-store indicator (library table, TOC rows, summary page) */
.toc-pdf, .toc-md { font-size: .66rem; font-weight: 600; padding: .08rem .38rem; border-radius: var(--radius-sm); }
.toc-pdf.have, .toc-md.have { background: hsl(var(--success) / .15); color: hsl(var(--success)); }
.toc-pdf.missing, .toc-md.missing { background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); }
/* The one actionable badge that is a real <button> (start-conversion "no MD"),
   not an <a>/<span> like every other store badge — strip the browser's native
   button chrome so it renders pixel-identical to its siblings. */
button.toc-pdf, button.toc-md { border: none; margin: 0; font: inherit; font-size: .66rem; font-weight: 600; line-height: inherit; appearance: none; -webkit-appearance: none; cursor: pointer; }
/* literature type tag (Paper / Book / Report …) — outlined to sit apart from the filled store badges */
.lit-type { font-size: .66rem; font-weight: 600; padding: .08rem .38rem; border-radius: var(--radius-sm); color: hsl(var(--muted-foreground)); border: 1px solid hsl(var(--border-strong)); }
/* full bibliographic citation below a title (record + summary pages) */
.lit-citation { color: hsl(var(--muted-foreground)); font-size: .92rem; line-height: 1.55; margin: .6rem 0 1.5rem; max-width: 54rem; }
.lit-citation em { font-style: italic; }
.lit-citation a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
/* "already saved" label replacing the Save-issue button on a saved live view */
.issue-saved { display: inline-flex; align-items: center; font-size: .82rem; font-weight: 600; color: hsl(var(--primary)); background: hsl(var(--primary-muted)); padding: .3rem .6rem; border-radius: var(--radius-sm); }
/* Settings: browser-PDF-fetcher status + setup steps */
.pill { font-size: .72rem; font-weight: 600; padding: .12rem .5rem; border-radius: 999px; background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); }
.pill:empty { display: none; }
.pill.ok { background: hsl(var(--primary-muted)); color: hsl(var(--primary)); }
.pill.bad { background: hsl(var(--destructive) / .14); color: hsl(var(--destructive)); }
.setup-steps { margin: .5rem 0 .7rem 1.2rem; padding: 0; display: flex; flex-direction: column; gap: .6rem; }
.setup-steps li { line-height: 1.7; }
.fetch-pdf-btn.needs-setup { opacity: .7; }
.lib-pager { display: flex; align-items: center; gap: .8rem; margin-top: 1rem; }
.lib-page { font-size: .82rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }
/* record management: inline edit form + verify/delete */
.lit-edit summary { cursor: pointer; font-size: .85rem; color: hsl(var(--primary)); width: max-content; }
.lit-edit-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: .6rem .9rem; margin: .7rem 0; }
.lit-field { display: flex; flex-direction: column; gap: .2rem; font-size: .78rem; color: hsl(var(--muted-foreground)); }
.lit-field.lit-field-wide { margin: 0 0 .7rem; }
.lit-field input, .lit-field textarea { font: inherit; font-size: .85rem; color: hsl(var(--foreground)); background: hsl(var(--background)); border: 1px solid hsl(var(--border-strong)); border-radius: var(--radius-md); padding: .35rem .5rem; width: 100%; }
.lit-field textarea { resize: vertical; }
.lit-manage-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .8rem; }
/* collections: research-topic cards */
.coll-filter { display: block; max-width: 26rem; margin: .2rem 0 1rem; }
.coll-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: .8rem; margin-top: .3rem; }
.coll-card { border: 1px solid hsl(var(--border)); border-radius: var(--radius-lg); padding: .8rem .9rem; background: hsl(var(--card)); display: flex; flex-direction: column; gap: .3rem; }
.coll-name { font-weight: 600; font-size: .92rem; text-transform: capitalize; text-decoration: none; color: hsl(var(--foreground)); }
.coll-name:hover { color: hsl(var(--primary)); }
.coll-count { font-size: .78rem; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; }
/* Push actions to the card bottom so rows with 1- and 2-line titles align. */
.coll-actions { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: auto; padding-top: .35rem; }
/* journals: followed-journal chips + issue TOC */
.journal-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin: .2rem 0 1rem; }
.journal-chips .chip { font-size: .82rem; padding: .28rem .7rem; text-decoration: none; }
.jrnl-num { max-width: 9rem; }
.toc-list { list-style: none; margin: .6rem 0 0; padding: 0; }
.toc-item { display: flex; gap: .8rem; align-items: baseline; padding: .6rem .3rem; border-top: 1px solid hsl(var(--border)); }
.toc-list li:first-child { border-top: none; }
.toc-pages { flex: none; width: 4.5rem; font-variant-numeric: tabular-nums; font-size: .8rem; color: hsl(var(--muted-foreground)); }
.toc-body { flex: 1; min-width: 0; }
.toc-title { display: block; font-weight: 560; font-size: .9rem; line-height: 1.35; }
.toc-authors { display: block; font-size: .8rem; color: hsl(var(--muted-foreground)); margin-top: .1rem; }
.toc-actions { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
/* health tab: metric tiles + duplicate-DOI groups */
.health-metrics { display: flex; flex-wrap: wrap; gap: .7rem; margin: .3rem 0 .3rem; }
.health-metric { display: flex; flex-direction: column; min-width: 8rem; padding: .6rem .8rem; border: 1px solid hsl(var(--border)); border-radius: var(--radius-md); text-decoration: none; color: inherit; }
.health-metric:hover { background: hsl(var(--accent)); }
.health-num { font-size: 1.5rem; font-weight: 640; font-variant-numeric: tabular-nums; line-height: 1.1; }
.health-label { font-size: .78rem; color: hsl(var(--muted-foreground)); }
.health-metric.warn .health-num { color: hsl(30 70% 40%); }
.health-metric.bad .health-num { color: hsl(0 62% 46%); }
.health-metric.ok .health-num { color: hsl(145 50% 32%); }
.health-dups { margin-top: .6rem; }
.health-dups summary { cursor: pointer; font-size: .85rem; color: hsl(var(--primary)); width: max-content; }
.health-dup-keys { display: inline-flex; flex-wrap: wrap; gap: .5rem; margin-left: .5rem; }
@media (min-width: 60rem) {
  .lib-layout { display: grid; grid-template-columns: minmax(13rem, 16rem) 1fr; gap: 1.6rem; align-items: start; }
  /* Permanent sidebar on wide screens: drop the drawer toggle, always show it. */
  .lib-facets-toggle { display: none; }
  .lib-facets { display: flex !important; flex-direction: column; gap: 1rem; }
}
/* select-submit molecule: a menu choice committed with a button — the
   application status panel, the todo-inbox project filter, etc. One row, the
   select and button gap-spaced (not touching). */
.select-submit { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin: 0; }
.select-submit-field { font: inherit; font-size: .85rem; color: hsl(var(--foreground)); background: hsl(var(--background)); border: 1px solid hsl(var(--border-strong)); border-radius: var(--radius-md); padding: .38rem .55rem; }
/* The Claude-commands pane-head's model picker — a bare select (no submit of its
   own); every skill-run button on the page reads its value on submit. */
.model-select { font: inherit; font-size: .82rem; color: hsl(var(--foreground)); background: hsl(var(--background)); border: 1px solid hsl(var(--border-strong)); border-radius: var(--radius-md); padding: .3rem .5rem; }
/* history pane: a deliverable's *.toml lifecycle timeline (newest first) */
.history-list { list-style: none; margin: .3rem 0 0; padding: 0; }
.history-row { display: flex; gap: .75rem; padding: .55rem 0; border-top: 1px solid hsl(var(--border)); }
.history-row:first-child { border-top: none; }
.history-date { flex: none; width: 6.2rem; font-variant-numeric: tabular-nums; font-size: .8rem; color: hsl(var(--muted-foreground)); padding-top: .1rem; }
.history-body { min-width: 0; }
.history-head { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.history-kind, .history-decision { font-size: .8rem; color: hsl(var(--muted-foreground)); }
.history-decision { font-weight: 560; color: hsl(var(--foreground)); }
.history-journal { font-size: .8rem; font-weight: 560; color: hsl(var(--foreground)); }
.history-note { margin: .25rem 0 0; font-size: .84rem; color: hsl(var(--foreground)); line-height: 1.45; }
/* deliverables pane: the target journal's submission package (wf-deliverables),
   rendered as a `.dash` table; cells top-align so long `Contents` line up with badges */
.deliverables table.dash td { vertical-align: top; }
.deliverable-doc { font-weight: 560; color: hsl(var(--foreground)); }
.deliverable-format { font-size: .72rem; text-transform: uppercase; letter-spacing: .03em; color: hsl(var(--muted-foreground)); border: 1px solid hsl(var(--border)); border-radius: var(--radius-sm); padding: .05rem .3rem; }
/* PDF/MD store badges: a group cell, and the link form (a.toc-*) drops the
   underline and gains a pointer + subtle hover so it reads as an actionable pill. */
.store-cell { display: inline-flex; gap: .3rem; align-items: center; }
a.toc-pdf, a.toc-md { text-decoration: none; cursor: pointer; }
a.toc-pdf:hover, a.toc-md:hover, button.toc-pdf:hover, button.toc-md:hover { filter: brightness(1.08); text-decoration: none; }
.deliverable-file { font-size: .8rem; font-variant-numeric: tabular-nums; }
.deliverable-file.present { color: hsl(var(--foreground)); text-decoration: none; border-bottom: 1px dotted hsl(var(--border-strong)); }
.deliverable-file.present:hover { border-bottom-color: hsl(var(--foreground)); }
.deliverable-file.missing { color: hsl(var(--destructive, 0 72% 51%)); }
.deliverable-contents { font-size: .8rem; color: hsl(var(--muted-foreground)); line-height: 1.4; word-break: break-word; }
/* Submission-readiness tab: the headline verdict banner + the gate/history
   status atoms. The banner tints its whole surface by outcome so readiness is
   legible at a glance before any table is read. */
.readiness-banner { display: flex; align-items: center; gap: 1rem; padding: 1rem 1.15rem; border-radius: var(--radius); border: 1px solid; }
.readiness-banner.ready { background: hsl(var(--success) / .08); border-color: hsl(var(--success) / .5); }
.readiness-banner.not-ready { background: hsl(var(--destructive) / .07); border-color: hsl(var(--destructive) / .45); }
.readiness-mark { font-size: 2rem; line-height: 1; font-weight: 700; }
.readiness-banner.ready .readiness-mark { color: hsl(var(--success)); }
.readiness-banner.not-ready .readiness-mark { color: hsl(var(--destructive)); }
.readiness-text { display: flex; flex-direction: column; gap: .15rem; }
.readiness-title { font-size: 1.2rem; font-weight: 680; letter-spacing: -0.01em; }
.readiness-banner.ready .readiness-title { color: hsl(var(--success)); }
.readiness-banner.not-ready .readiness-title { color: hsl(var(--destructive)); }
.readiness-sub { color: hsl(var(--muted-foreground)); font-size: .88rem; }
/* Pass/fail/warn status pills reused across the gate-checks and history tables. */
.gate-pass, .gate-fail, .gate-warn { font-size: .74rem; font-weight: 640; text-transform: uppercase; letter-spacing: .03em; padding: .05rem .4rem; border-radius: var(--radius-sm); white-space: nowrap; }
.gate-pass { color: hsl(var(--success)); background: hsl(var(--success) / .12); }
.gate-fail { color: hsl(var(--destructive)); background: hsl(var(--destructive) / .1); }
.gate-warn { color: hsl(var(--warning)); background: hsl(var(--warning) / .12); }
.gate-checks td, .review-history td { vertical-align: top; }
.gate-ensures { color: hsl(var(--muted-foreground)); font-size: .85rem; line-height: 1.4; }
/* KB linter-health pane: reuses the readiness banner + gate pills; just spacing. */
.kb-health .readiness-banner { margin: .3rem 0 .8rem; }
.kb-health h3 { margin: 1rem 0 .4rem; font-size: .95rem; }
/* At-a-glance submission-gate signal on the Deliverables pane header — a tinted
   pill that links to the full breakdown on the Submission tab. */
.ready-signal { display: inline-flex; align-items: center; gap: .35rem; font-size: .82rem; font-weight: 600; padding: .2rem .55rem; border-radius: var(--radius-sm); text-decoration: none; border: 1px solid; white-space: nowrap; }
.ready-signal .ready-mark { font-weight: 700; }
.ready-signal.ready { color: hsl(var(--success)); background: hsl(var(--success) / .12); border-color: hsl(var(--success) / .35); }
.ready-signal.not-ready { color: hsl(var(--destructive)); background: hsl(var(--destructive) / .1); border-color: hsl(var(--destructive) / .35); }
.ready-signal:hover { filter: brightness(1.05); text-decoration: none; }
/* search-submit busy state: spinner tinted for the primary button, width pinned
   so swapping "Search" → "Searching…" doesn't reflow the row. */
.lit-search .btn { min-width: 7.5rem; justify-content: center; }
@media (max-width: 640px) { .lit-search .btn { min-width: auto; } }
.lit-search .btn[aria-busy] { pointer-events: none; }
.lit-search .btn .spinner { width: .8rem; height: .8rem; border-color: hsl(var(--primary-foreground) / .35); border-top-color: hsl(var(--primary-foreground)); }

/* button */
.btn {
  display: inline-flex; align-items: center; gap: .45rem;
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  border: 1px solid transparent; border-radius: var(--radius-md);
  padding: .5rem .9rem; font-size: .875rem; font-weight: 500; line-height: 1;
  text-decoration: none; cursor: pointer; box-shadow: var(--shadow-sm);
  transition: background .13s ease, box-shadow .13s ease, transform .06s ease, border-color .13s ease;
}
.btn:hover { background: hsl(var(--primary-hover)); }
.btn:active { transform: translateY(1px); box-shadow: none; }
/* An inline icon inside a button (e.g. the download glyph): sized to the label,
   never the SVG's intrinsic default — the `.icon` class carries no base size. */
.btn .icon { width: 1.05em; height: 1.05em; flex: none; }
.btn.ghost { background: hsl(var(--card)); color: hsl(var(--foreground)); border: 1px solid hsl(var(--border-strong)); }
.btn.ghost:hover { background: hsl(var(--accent)); border-color: hsl(var(--border-strong)); }
/* Web-triggered skill buttons (the /tender + handoff resume actions). */
.tool-actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin: .5rem 0; }
.tool-run {
  font: inherit; font-size: .85rem; cursor: pointer; line-height: 1;
  padding: .4rem .8rem; border-radius: var(--radius-md);
  background: hsl(var(--card)); color: hsl(var(--foreground)); border: 1px solid hsl(var(--border-strong));
  transition: background .13s ease, color .13s ease, border-color .13s ease;
}
.tool-run:hover { background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); border-color: transparent; }
.needs-input { border-left: 3px solid hsl(var(--primary)); }
.paused-run + .paused-run { margin-top: .75rem; padding-top: .75rem; border-top: 1px solid hsl(var(--border)); }
.paused-run-id { margin: 0 0 .25rem; font-size: .9rem; }
.run-list { list-style: none; margin: 0; padding: 0; }
.run-item { padding: .6rem 0; border-top: 1px solid hsl(var(--border)); }
.run-item:first-child { border-top: none; }
.run-head { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.run-label { font-weight: 600; }
.run-status { font-size: .82rem; padding: .1rem .45rem; border-radius: var(--radius-sm); background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); }
.run-status.ok { color: hsl(var(--primary)); }
.run-status.failed { color: hsl(var(--destructive, 0 70% 55%)); }
.run-out { margin-top: .4rem; }
.run-out summary { cursor: pointer; color: hsl(var(--muted-foreground)); font-size: .85rem; }
.run-toolbar { display: flex; gap: .5rem; flex-wrap: wrap; margin: .5rem 0 .25rem; }
.run-age { font-size: .78rem; color: hsl(var(--muted-foreground)); }
.btn.ghost:active { transform: translateY(1px); box-shadow: none; }
.btn.sm { padding: .34rem .62rem; font-size: .8rem; gap: .3rem; border-radius: var(--radius-sm); }
/* native file input styled as a ghost button so it matches the surface */
input[type=file] { font-size: .82rem; color: hsl(var(--muted-foreground)); max-width: 100%; }
input[type=file]::file-selector-button { font: inherit; font-weight: 500; margin-right: .6rem; padding: .34rem .62rem; border-radius: var(--radius-sm); border: 1px solid hsl(var(--border-strong)); background: hsl(var(--card)); color: hsl(var(--foreground)); cursor: pointer; transition: background .12s ease; }
input[type=file]::file-selector-button:hover { background: hsl(var(--accent)); }
.btn.ghost.danger { color: hsl(var(--destructive)); border-color: hsl(var(--destructive) / .35); }
.btn.ghost.danger:hover { background: hsl(var(--destructive) / .10); border-color: hsl(var(--destructive) / .55); color: hsl(var(--destructive)); }

/* focus rings (keyboard) */
a:focus-visible, input:focus-visible, .btn:focus-visible, a.row:focus-visible {
  outline: 2px solid transparent; outline-offset: 2px;
  box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));
  border-radius: calc(var(--radius) - 2px);
}

/* rendered markdown */
.content { line-height: 1.7; }
.doc-photo { float: right; width: 160px; margin: 0 0 1rem 1.4rem; }
.doc-photo img { width: 100%; height: auto; border-radius: var(--radius); border: 1px solid hsl(var(--border)); display: block; }
.content h1, .content h2, .content h3, .content h4 { line-height: 1.3; font-weight: 600; margin: 1.6em 0 .5em; }
.content h2 { font-size: 1.25rem; padding-bottom: .3rem; border-bottom: 1px solid hsl(var(--border)); }
.content h3 { font-size: 1.08rem; }
.content p { margin: .8em 0; }
.content a { color: hsl(var(--primary)); text-decoration: none; }
.content a:hover { text-decoration: underline; }
.content code { font-family: var(--mono); background: hsl(var(--muted)); padding: .12em .35em; border-radius: var(--radius-sm); font-size: .875em; }
.content pre { background: hsl(var(--muted)); padding: .9rem 1rem; border-radius: var(--radius); overflow-x: auto; border: 1px solid hsl(var(--border)); }
.content pre code { background: none; padding: 0; }
.content blockquote { border-left: 2px solid hsl(var(--border)); margin: 1em 0; padding: .1rem 0 .1rem 1rem; color: hsl(var(--muted-foreground)); }
.content ul, .content ol { padding-left: 1.35rem; }
.content img { max-width: 100%; height: auto; border-radius: var(--radius); }
.content hr { border: none; border-top: 1px solid hsl(var(--border)); margin: 1.5em 0; }
.content table { border-collapse: collapse; width: 100%; font-size: .9rem; margin: 1em 0; display: block; overflow-x: auto; }
.content th { background: hsl(var(--muted)); font-weight: 600; text-align: left; }
.content th, .content td { border: 1px solid hsl(var(--border)); padding: .45rem .7rem; }

embed.pdf { width: 100%; height: 80vh; border: 1px solid hsl(var(--border)); border-radius: var(--radius); margin-top: .4rem; background: hsl(var(--muted)); }

/* hamburger menu — hidden on wide screens (the top bar is used there) */
.menu { display: none; }

/* Narrow phones, and any short viewport (landscape phones), swap the tall top
   bar for the floating hamburger so it doesn't eat the screen. */
@media (max-width: 640px), (max-height: 520px) {
  /* Swap the top bar for a floating bottom-left hamburger. */
  header.nav { display: none; }
  main { padding: 1.1rem .8rem 5.5rem; }
  .pdf-title { display: none; }

  .menu { display: block; position: fixed; bottom: 1rem; left: 1rem; z-index: 60; }
  summary.menu-btn {
    list-style: none; cursor: pointer;
    width: 3rem; height: 3rem; border-radius: 999px;
    display: flex; align-items: center; justify-content: center;
    background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
    box-shadow: 0 4px 14px hsl(0 0% 0% / 0.28);
    /* Above the open sheet so tapping it toggles the menu closed. */
    position: relative; z-index: 61;
  }
  summary.menu-btn::-webkit-details-marker { display: none; }
  summary.menu-btn .icon { width: 1.4rem; height: 1.4rem; }
  /* Open menu: a near-full-screen sheet inset by a margin, scrollable, with the
     nav links laid out in two columns so the whole map fits without overflow. */
  .menu-panel {
    position: fixed; inset: .75rem; z-index: 60;
    display: flex; flex-direction: column; gap: .55rem;
    overflow-y: auto; overscroll-behavior: contain;
    background: hsl(var(--card)); border: 1px solid hsl(var(--border));
    border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
    /* extra bottom room so the last rows clear the floating menu button */
    padding: .9rem 1rem 4.5rem;
  }
  .menu-links { columns: 2; column-gap: 1.1rem; }
  .menu-links a.navlink, .menu-links .menu-section { break-inside: avoid; }
  .menu-section { font-size: .68rem; font-weight: 650; text-transform: uppercase; letter-spacing: .06em; color: hsl(var(--muted-foreground)); padding: .55rem .6rem .15rem; }
  .menu-panel a.navlink {
    display: block;
    color: hsl(var(--foreground)); text-decoration: none; font-size: .9rem;
    padding: .5rem .6rem; border-radius: calc(var(--radius) - 2px);
  }
  .menu-panel a.navlink:hover { background: hsl(var(--accent)); }
  .menu-panel a.navlink.on { color: hsl(var(--primary)); font-weight: 560; background: hsl(var(--primary-muted)); }
  .menu-panel form.search { position: relative; margin: 0; flex: none; }
  .menu-panel form.search input { width: 100%; }
}

/* full-page PDF viewer */
body.pdfview { height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
/* the reusable pdf.js viewer: fills the standalone page, or a bounded card frame
   when `.inline`, or the whole screen when fullscreened from an inline embed. */
.pdf-viewer { display: flex; flex-direction: column; min-height: 0; }
body.pdfview .pdf-viewer { flex: 1; }
.pdf-viewer.inline { height: 74vh; border: 1px solid hsl(var(--border)); border-radius: var(--radius); overflow: hidden; background: hsl(var(--card-2)); }
.pdf-viewer:fullscreen { height: 100vh; width: 100vw; border: none; border-radius: 0; }
/* The embedded terminal: fills its (wide) pane, or the whole screen when the
   Fullscreen toggle requests fullscreen on it. */
.term-embed:fullscreen { width: 100vw; height: 100vh; border-radius: 0; padding: 4px; background: #0b0b0e; }
.term-head { display: flex; align-items: center; gap: .6rem; }
.pdf-toolbar {
  display: flex; align-items: center; gap: .35rem; padding: .4rem .55rem;
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--background) / 0.82);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
}
.pdf-title { flex: 1; min-width: 0; font-size: .85rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tb-group { display: inline-flex; align-items: center; gap: .05rem; }
.tb-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border: none; background: none;
  color: hsl(var(--foreground)); border-radius: var(--radius-md);
  cursor: pointer; text-decoration: none; flex: none;
  transition: background .12s ease, color .12s ease, transform .06s ease;
}
.tb-btn:hover { background: hsl(var(--accent)); }
.tb-btn:active { transform: translateY(1px); }
.tb-btn .icon { width: 1.15rem; height: 1.15rem; }
.pdf-pageind { font-size: .8rem; color: hsl(var(--muted-foreground)); min-width: 2.8rem; text-align: center; white-space: nowrap; font-variant-numeric: tabular-nums; }
#pdf-container { flex: 1; overflow: auto; background: hsl(var(--muted)); display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 12px; }
.pdf-page { background: #fff; box-shadow: var(--shadow-md); border-radius: var(--radius-sm); position: relative; }
.pdf-page canvas { display: block; }
.pdf-error { color: hsl(var(--muted-foreground)); padding: 2rem; }
/* pdf.js text layer (4.10.38) — transparent, selectable text over the canvas. */
.textLayer { position: absolute; text-align: initial; inset: 0; overflow: clip; opacity: 1; line-height: 1; text-size-adjust: none; forced-color-adjust: none; transform-origin: 0 0; caret-color: CanvasText; z-index: 0; }
.textLayer :is(span, br) { color: transparent; position: absolute; white-space: pre; cursor: text; transform-origin: 0% 0%; }
.textLayer span.markedContent { top: 0; height: 0; }
.textLayer ::selection { background: rgba(0 0 255 / 0.25); }
.textLayer br::selection { background: transparent; }
.textLayer .endOfContent { display: block; position: absolute; inset: 100% 0 0; z-index: 0; cursor: default; user-select: none; }
.textLayer.selecting .endOfContent { top: 0; }
/* PDF dark (invert) toggle — inverts only the page canvas, not the text layer. */
#pdf-container.inverted .pdf-page { background: #1a1a1a; }
#pdf-container.inverted .pdf-page canvas { filter: invert(1) hue-rotate(180deg); }
.tb-btn[aria-pressed="true"] { background: hsl(var(--primary-muted)); color: hsl(var(--primary)); }

/* sign-in */
.login {
  min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding: 1rem;
  background: radial-gradient(120% 120% at 50% 0%, hsl(var(--primary-muted)) 0%, hsl(var(--background)) 55%);
}
.login-card { width: 100%; max-width: 22rem; padding: 1.6rem; display: flex; flex-direction: column; box-shadow: var(--shadow-lg); border-radius: var(--radius-lg); }
.login-brand { display: inline-flex; align-items: center; gap: .5rem; font-weight: 680; font-size: 1.1rem; }
.login-brand .icon { width: 1.3rem; height: 1.3rem; color: hsl(var(--primary)); }
.login-card .subtitle { margin: .5rem 0 1rem; }
.login-input {
  width: 100%; margin-bottom: .8rem; appearance: none;
  background: hsl(var(--card)); color: hsl(var(--foreground));
  border: 1px solid hsl(var(--border-strong)); border-radius: var(--radius-md);
  padding: .55rem .7rem; font-size: .95rem;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.login .btn { width: 100%; justify-content: center; }
.login-error { color: hsl(var(--destructive)); font-size: .85rem; margin: 0 0 .7rem; }

/* tools */
.card.tool { padding: 1.35rem 1.45rem; display: block; }
.card.tool h2 { margin: 0 0 .15rem; font-size: 1.15rem; border: none; padding: 0; }
.tool-note { color: hsl(var(--muted-foreground)); font-size: .88rem; margin: .1rem 0 .7rem; }
.card.tool .login-input { margin-bottom: .55rem; }
/* saved-issue archive: collapsed by default, a Volume / Year / Issues table */
.issue-archive-wrap { margin-top: .6rem; }
.archive-summary { cursor: pointer; user-select: none; font-weight: 600; font-size: .95rem; padding: .2rem 0; }
.archive-summary:hover { color: hsl(var(--primary)); }
.archive-count { font-weight: 400; font-size: .8rem; color: hsl(var(--muted-foreground)); margin-left: .5rem; }
.issue-archive { width: 100%; border-collapse: collapse; margin-top: .5rem; font-size: .9rem; }
.issue-archive th, .issue-archive td { padding: .4rem .55rem; text-align: left; vertical-align: baseline; border-top: 1px solid hsl(var(--border) / .5); }
.issue-archive tr:first-child th, .issue-archive tr:first-child td { border-top: none; }
.ia-vol { font-weight: 600; white-space: nowrap; width: 6rem; }
.ia-year { color: hsl(var(--muted-foreground)); white-space: nowrap; width: 4rem; font-variant-numeric: tabular-nums; }
.ia-issues { display: flex; flex-wrap: wrap; gap: .3rem; }
.ia-issue { display: inline-flex; align-items: baseline; gap: .3rem; text-decoration: none; padding: .12rem .45rem; border: 1px solid hsl(var(--border)); border-radius: .35rem; color: hsl(var(--foreground)); font-variant-numeric: tabular-nums; }
.ia-issue:hover { background: hsl(var(--muted)); }
.ia-issue.active { background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); border-color: hsl(var(--primary)); }
.ia-n { font-size: .72rem; color: hsl(var(--muted-foreground)); }
.ia-issue.active .ia-n { color: hsl(var(--primary-foreground)); opacity: .85; }
/* prev/next issue navigation in the TOC pane title */
.issue-nav { display: flex; gap: .35rem; }
.issue-nav-btn { min-width: 2rem; text-align: center; font-size: 1.05rem; line-height: 1; }
.issue-nav-btn.disabled { opacity: .4; pointer-events: none; }
/* paper.toml metadata + recent commits in the project Status pane */
.paper-title { font-size: .95rem; font-weight: 600; line-height: 1.35; margin: .1rem 0 .6rem; }
.paper-meta { display: grid; grid-template-columns: max-content 1fr; gap: .2rem .8rem; margin: 0 0 .7rem; font-size: .86rem; }
.paper-meta dt { color: hsl(var(--muted-foreground)); }
.paper-meta dd { margin: 0; min-width: 0; }
.status-pill { display: inline-block; font-size: .72rem; font-weight: 600; padding: .1rem .5rem; border-radius: var(--radius-full); background: hsl(var(--primary-muted)); color: hsl(var(--primary)); text-transform: capitalize; }
.commit-head { font-size: .7rem; font-weight: 620; text-transform: uppercase; letter-spacing: .06em; color: hsl(var(--muted-foreground)); margin: 1rem 0 .45rem; }
.commit-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .35rem; }
.commit-list li { display: flex; gap: .55rem; align-items: baseline; font-size: .82rem; min-width: 0; }
.commit-hash { font-family: var(--mono); color: hsl(var(--primary)); flex: none; }
.commit-subj { color: hsl(var(--foreground)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Actions-page skill + nix-app grids: wrap-flow buttons under a small group
   label, with each group's long tail behind a "more" expander. */
.group-label { display: block; font-size: .7rem; font-weight: 620; text-transform: uppercase; letter-spacing: .06em; color: hsl(var(--muted-foreground)); margin-bottom: .1rem; }
.count { font-size: .68rem; font-weight: 600; color: hsl(var(--muted-foreground)); background: hsl(var(--muted)); border: 1px solid hsl(var(--border)); border-radius: var(--radius-full); padding: .02rem .45rem; margin-left: .35rem; }
.skill-group { margin: .3rem 0 1.05rem; }
/* A simple wrap-row of buttons (non-action-table button groups, e.g. component links). */
.btn-row { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .4rem; }
.btn-row form { margin: 0; }
/* Actions as a two-column table: the run button (left, shrink-to-fit) and its
   one-line explanation (right, muted). Shared by the skill groups and Nix apps. */
.action-table { width: 100%; border-collapse: collapse; margin-top: .4rem; }
.action-table td { padding: .28rem .6rem .28rem 0; vertical-align: top; border-bottom: 1px solid hsl(var(--border) / .5); }
.action-table tr:last-child td { border-bottom: 0; }
.action-table .action-cell { white-space: nowrap; width: 1%; }
.action-table .action-cell form { margin: 0; }
.action-table .action-desc { color: hsl(var(--muted-foreground)); font-size: .85rem; line-height: 1.45; }
.action-table .action-desc code { font-family: var(--mono); font-size: .82em; }
details.skill-more { margin-top: .5rem; }
details.skill-more > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: .3rem; font-size: .72rem; color: hsl(var(--muted-foreground)); }
details.skill-more > summary::-webkit-details-marker { display: none; }
details.skill-more > summary::before { content: "\25B8"; font-size: .8em; transition: transform .15s ease; }
details.skill-more[open] > summary::before { transform: rotate(90deg); }
table.stats { border-collapse: collapse; font-size: .85rem; margin-top: .4rem; }
table.stats td { padding: .18rem .8rem .18rem 0; vertical-align: top; }
table.stats td:first-child { color: hsl(var(--muted-foreground)); white-space: nowrap; }
/* Word-count "By section" table: full width, wrapping section names, and the
   count/budget columns pinned right so long titles never push them off-screen. */
table.stats.wc-sections { width: 100%; table-layout: auto; }
table.stats.wc-sections td:first-child { white-space: normal; word-break: break-word; color: hsl(var(--foreground)); padding-right: .6rem; }
table.stats.wc-sections td.num { text-align: right; white-space: nowrap; padding-right: .35rem; font-variant-numeric: tabular-nums; width: 1%; }
table.stats.wc-sections td.sub { text-align: right; white-space: nowrap; padding: .18rem 0 .18rem 0; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; width: 1%; }
.wc-budget.over { color: hsl(var(--destructive)); }
.wc-budget.warn { color: hsl(var(--warning)); }

/* session management (Sessions page + project cards) */
form.inline { display: inline; margin: 0; }
.chip { display: inline-flex; align-items: center; gap: .4rem; font-size: var(--text-xs); color: hsl(var(--muted-foreground)); background: hsl(var(--muted)); border: none; padding: .16rem .6rem; border-radius: var(--radius-full); }
.chip code { background: none; padding: 0; color: hsl(var(--foreground)); font-family: var(--mono); font-size: .95em; }
.dot { width: .5rem; height: .5rem; border-radius: var(--radius-full); background: hsl(var(--success-dot)); flex: none; box-shadow: 0 0 0 3px hsl(var(--success-dot) / .16); }
@media (prefers-reduced-motion: no-preference) {
  .dot { animation: dot-pulse 2.4s ease-in-out infinite; }
  @keyframes dot-pulse {
    0%, 100% { box-shadow: 0 0 0 3px hsl(var(--success-dot) / .16); }
    50%      { box-shadow: 0 0 0 4px hsl(var(--success-dot) / .30); }
  }
}
/* Claude sessions grouped by zellij session — the three-level hierarchy made
   explicit: (1) the card heading is the project/scope, (2) "Zellij session"
   is the ONE labelled line naming the underlying zellij session + its live
   status (never duplicated elsewhere on the card), (3) "Claude tabs" labels
   the list of individual `claude` processes running inside it. */
.session-group + .session-group { margin-top: 1.1rem; padding-top: 1.1rem; border-top: 1px solid hsl(var(--border)); }
.session-group-head { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.session-group-head .group-label { display: inline; margin-bottom: 0; margin-right: .1rem; }
.session-name { font-family: var(--mono); font-size: .82rem; background: none; padding: 0; color: hsl(var(--foreground)); }
.session-badge { font-size: .6rem; font-weight: 650; text-transform: uppercase; letter-spacing: .05em; padding: .06rem .42rem; border-radius: var(--radius-full); }
.session-badge.live { color: hsl(var(--success)); background: hsl(var(--success) / .12); }
/* Start-session/Start-Claude forms reuse the select-submit molecule (defined
   above) for its gap-spaced select+button row — no bespoke spacing here. */
.session-group form.select-submit { margin: .5rem 0; }
.session-group > .group-label { display: block; margin: .7rem 0 .3rem; }
.sessions-empty { color: hsl(var(--muted-foreground)); font-size: .88rem; margin: 0; padding: .7rem; text-align: center; background: hsl(var(--card-2)); border: 1px dashed hsl(var(--border-strong)); border-radius: var(--radius-md); }
.session-list { list-style: none; margin: 0; padding: 0; background: transparent; border: none; }
.session-row { position: relative; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; row-gap: .35rem; gap: .6rem; padding: .62rem .55rem; margin: 0 -.55rem; border-radius: var(--radius-sm); transition: background .12s ease; }
.session-row::before { content: ""; position: absolute; top: 0; left: 1rem; right: 1rem; height: 1px; background: hsl(var(--border) / .55); }
.session-list > .session-row:first-child::before { content: none; }
.session-row:hover { background: hsl(var(--accent)); }
.session-id { font-family: var(--mono); font-size: .86rem; background: none; padding: 0; }
/* The two groups a session-row lays out between: the tab id (+ model badge)
   on the left, Peek/Stop actions on the right — exactly one gap, sized by
   `justify-content: space-between` on the row, instead of several competing
   `margin-left: auto` elements stretching unpredictably on narrow viewports. */
.session-row-main { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.session-row .session-act { display: inline-flex; align-items: center; gap: .25rem; flex: none; }
/* A muted inline note — "untracked" model, "No Claude tabs." — dimmer than
   surrounding text without the heavier `.sessions-empty` block treatment. */
.muted { color: hsl(var(--muted-foreground)); font-size: .84rem; }
/* An unrecognized ("Other") zellij session: id + Stop on one line, its Claude
   tab badges wrapping onto their own full-width line below — never spilling
   past the card edge, however many tabs are running. */
.session-row.other-session { flex-wrap: wrap; }
.session-tabs { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: .3rem; }
.sessions-foot { margin-top: .6rem; }
/* version control page: stats strip + changes/commits/bookmarks panes */
.vcs-st { font-family: var(--mono); font-size: .72rem; font-weight: 700; width: 1.5rem; flex: none; text-align: center; color: hsl(var(--muted-foreground)); }
.stats-strip .stat-num code.stat-branch { font-family: var(--mono); font-size: 1.05rem; font-weight: 600; letter-spacing: 0; }
.push-count { font-variant-numeric: tabular-nums; background: hsl(var(--primary-muted)); color: hsl(var(--primary)); border-radius: var(--radius-full); padding: 0 .4rem; margin-left: .1rem; }
.session-row .commit-subj { flex: 1; min-width: 0; font-size: .88rem; }
.commit-link { display: flex; align-items: baseline; gap: .55rem; flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.commit-link:hover .commit-subj { color: hsl(var(--primary)); }
.session-bookmark { font-family: var(--mono); font-size: .78rem; background: none; padding: 0; white-space: pre-wrap; word-break: break-word; line-height: 1.45; }
details.commits-more { margin-top: .5rem; }
details.commits-more > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: .3rem; font-size: .78rem; color: hsl(var(--muted-foreground)); }
details.commits-more > summary::-webkit-details-marker { display: none; }
details.commits-more > summary::before { content: "\25B8"; font-size: .8em; transition: transform .15s ease; }
details.commits-more[open] > summary::before { transform: rotate(90deg); }
/* job spinner (reduced-motion neutralised by the global block) */
.spinner { display: inline-block; width: .85rem; height: .85rem; vertical-align: -1px; border: 2px solid hsl(var(--border-strong)); border-top-color: hsl(var(--primary)); border-radius: 50%; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
/* inbox todos */
/* Leading control gutter: fixed-size, glyph centred on the title's first line, so
   the checkbox / run icons align with each other and the title. The run column is
   reserved (`.todo-run-slot`) on done rows in runnable projects → titles line up. */
.todo-check, .todo-run, .todo-run-slot, .todo-wontfix, .todo-wontfix-slot { flex: none; width: 1.5rem; height: 1.5rem; }
.todo-check, .todo-run, .todo-wontfix { display: inline-flex; align-items: center; justify-content: center; background: none; border: none; cursor: pointer; line-height: 1; color: hsl(var(--muted-foreground)); padding: 0; }
.todo-check { font-size: 1.05rem; }
.todo-run { font-size: .85rem; }
.todo-wontfix { font-size: .95rem; }
.todo-check:hover, .todo-run:hover, .todo-wontfix:hover { color: hsl(var(--primary)); }
.todo-wontfix.active { color: hsl(var(--primary)); }
.todo-run-slot, .todo-wontfix-slot { display: inline-block; }
/* The reject + run buttons in a right-aligned column at the end of the row. */
.todo-actions { display: inline-flex; align-items: center; gap: .25rem; flex: none; margin-left: auto; }
.todo-text { font-size: .95rem; line-height: 1.5rem; min-width: 0; }
.todo-row { align-items: flex-start; gap: .1rem; }
.filter-row .filter-action { margin-left: auto; }
.todo-main { min-width: 0; display: flex; flex-direction: column; gap: .25rem; }
.todo-meta { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; font-size: .75rem; margin-top: .1rem; }
.todo-due { color: hsl(var(--muted-foreground)); white-space: nowrap; font-variant-numeric: tabular-nums; }
.todo-due.todo-overdue, .todo-overdue { color: hsl(var(--destructive)); font-weight: 640; }
.todo-prio { padding: .05rem .35rem; border-radius: var(--radius-sm); font-weight: 640; border: none; background: hsl(var(--muted)); }
.todo-prio.p1 { color: hsl(var(--destructive)); border-color: hsl(var(--destructive) / .5); }
.todo-prio.p2 { color: hsl(var(--foreground)); }
.todo-prio.p3 { color: hsl(var(--muted-foreground)); }
.todo-tag { color: hsl(var(--primary)); }
.todo-llm { padding: .05rem .3rem; border-radius: var(--radius-sm); background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); text-transform: uppercase; letter-spacing: .04em; font-size: .64rem; }
.todo-text.done { text-decoration: line-through; color: hsl(var(--muted-foreground)); }
/* inbox filter bar */
/* the inbox filter toolbar sits on the page, not in a boxed card */
.card.tool.inbox-filters { background: transparent; border: none; box-shadow: none; padding: .2rem 0 1.4rem; }
.inbox-filters { display: flex; flex-direction: column; gap: .6rem; }
.filter-row { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; }
.filter-label { font-size: .7rem; text-transform: uppercase; letter-spacing: .07em; color: hsl(var(--muted-foreground)); min-width: 3.4rem; margin-right: .3rem; flex: none; }
.chip { font-size: .8rem; padding: .32rem .74rem; border-radius: 999px; border: none; background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); text-decoration: none; white-space: nowrap; transition: background .12s ease, color .12s ease; }
.chip:hover { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
.chip.active { background: hsl(var(--primary-muted)); color: hsl(var(--primary)); font-weight: 600; }
/* kind badge */
.kind-badge { font-size: .62rem; text-transform: uppercase; letter-spacing: .04em; padding: .08rem .4rem; border-radius: var(--radius-sm); border: none; background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); font-weight: 600; }
.kind-paper { color: hsl(var(--primary)); border-color: hsl(var(--primary) / .5); }
.kind-application { color: hsl(28 80% 45%); border-color: hsl(28 80% 45% / .5); }
.kind-referee { color: hsl(160 60% 38%); border-color: hsl(160 60% 38% / .5); }
.kind-personal { color: hsl(280 45% 55%); border-color: hsl(280 45% 55% / .5); }
.kind-grant { color: hsl(210 70% 50%); border-color: hsl(210 70% 50% / .5); }
/* expandable todo detail + edit form */
.todo-details { min-width: 0; flex: 1; }
.todo-summary { list-style: none; cursor: pointer; display: flex; flex-direction: column; gap: .25rem; padding: 0; }
.todo-summary::-webkit-details-marker { display: none; }
.todo-summary:hover .todo-text { color: hsl(var(--primary)); }
details.todo-details[open] > .todo-summary { margin-bottom: .5rem; }
.todo-edit { display: flex; flex-direction: column; gap: .5rem; padding: .6rem; background: hsl(var(--muted)); border: 1px solid hsl(var(--border)); border-radius: var(--radius-md); }
.todo-edit label { display: flex; flex-direction: column; gap: .2rem; font-size: .72rem; color: hsl(var(--muted-foreground)); }
.todo-edit input, .todo-edit select, .todo-edit textarea { appearance: none; background: hsl(var(--card)); color: hsl(var(--foreground)); border: 1px solid hsl(var(--border-strong)); border-radius: var(--radius-sm); padding: .35rem .45rem; font: inherit; font-size: .85rem; }
.todo-edit textarea { resize: vertical; font-family: var(--mono); }
.todo-edit-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; }
.todo-edit-actions { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.todo-id { font-size: .7rem; color: hsl(var(--muted-foreground)); }
@media (max-width: 640px) { .todo-edit-grid { grid-template-columns: 1fr; } }
/* project-page todos */
.project-todos { margin-top: 1rem; }
.todo-add { margin: .3rem 0 .7rem; gap: .4rem; }
.todo-add-input { flex: 1; appearance: none; background: hsl(var(--card)); color: hsl(var(--foreground)); border: 1px solid hsl(var(--border-strong)); border-radius: var(--radius-md); padding: .35rem .55rem; font: inherit; font-size: .85rem; }
/* server status footer */
.app-status { display: flex; align-items: center; justify-content: center; gap: .4rem; padding: 1rem .8rem 2.4rem; color: hsl(var(--muted-foreground)); font-size: .72rem; }
.status-dot { width: .5rem; height: .5rem; border-radius: 50%; background: hsl(145 60% 42%); box-shadow: 0 0 0 0 hsl(145 60% 42% / .5); animation: statuspulse 2.4s ease-out infinite; flex: none; }
@keyframes statuspulse { 0% { box-shadow: 0 0 0 0 hsl(145 60% 42% / .5); } 70% { box-shadow: 0 0 0 .35rem hsl(145 60% 42% / 0); } 100% { box-shadow: 0 0 0 0 hsl(145 60% 42% / 0); } }
.status-text { font-variant-numeric: tabular-nums; }
/* CV render (applications page) */
.cv-card { margin-top: 1.4rem; }
.cv-source { color: hsl(var(--muted-foreground)); font-size: .78rem; }
.cv-section { margin: .8rem 0; }
.cv-section h3 { margin: 0 0 .35rem; font-size: .82rem; text-transform: uppercase; letter-spacing: .04em; color: hsl(var(--muted-foreground)); }
.cv-map { display: grid; grid-template-columns: max-content 1fr; gap: .15rem .8rem; margin: 0; }
.cv-map dt { color: hsl(var(--muted-foreground)); font-size: .85rem; }
.cv-map dd { margin: 0; font-size: .88rem; }
.cv-entries { display: flex; flex-direction: column; gap: .4rem; }
.cv-entry { padding: .4rem .55rem; border: 1px solid hsl(var(--border)); border-radius: var(--radius-md); display: flex; flex-wrap: wrap; gap: .1rem .9rem; font-size: .86rem; }
.cv-field { white-space: normal; }
.cv-k { color: hsl(var(--muted-foreground)); }
.cv-scalar { font-size: .88rem; margin: 0; }
.cv-count { color: hsl(var(--muted-foreground)); font-weight: 400; }
.cv-pub { flex-direction: column; gap: .1rem; }
.cv-pub-main { font-size: .88rem; }
.cv-pub-venue { color: hsl(var(--muted-foreground)); font-size: .82rem; font-style: italic; }
.cv-pubgroup { margin: .5rem 0 .1rem; font-size: .8rem; font-weight: 620; }
.cv-pubgroup:first-child { margin-top: 0; }
/* drafted dossiers (applications page) */
.dossiers-card { margin-top: 1.4rem; }
.draft-card { margin-top: 1.4rem; }
.draft-note { margin: 0 0 .5rem; }
.draft-row { align-items: center; gap: .6rem; justify-content: space-between; }
.draft-title { min-width: 0; font-size: .9rem; }
.dossier-row { align-items: center; gap: .6rem; }
.dossier-main { min-width: 0; display: flex; flex-direction: column; gap: .3rem; flex: 1; }
.dossier-slug { font-weight: 620; font-size: .9rem; overflow-wrap: anywhere; }
.dossier-card { font-size: .78rem; color: hsl(var(--muted-foreground)); text-decoration: none; }
.dossier-card:hover { color: hsl(var(--primary)); }
.dossier-status { padding: .02rem .3rem; border-radius: var(--radius-sm); background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); font-size: .68rem; text-transform: uppercase; letter-spacing: .03em; }
.dossier-links { display: flex; flex-wrap: wrap; gap: .3rem; }
.dossier-actions { display: flex; gap: .3rem; flex: none; align-items: center; }
/* cv.yaml editor */
.cv-edit { display: flex; flex-direction: column; gap: .6rem; }
.cv-edit-area { width: 100%; min-height: 60vh; box-sizing: border-box; appearance: none; background: hsl(var(--card)); color: hsl(var(--foreground)); border: 1px solid hsl(var(--border-strong)); border-radius: var(--radius-md); padding: .7rem .8rem; font-family: var(--mono); font-size: .82rem; line-height: 1.5; tab-size: 2; resize: vertical; }
.cv-edit-area:focus-visible { outline: none; border-color: hsl(var(--ring)); box-shadow: 0 0 0 3px hsl(var(--ring) / .25); }
.cv-edit-bar { display: flex; gap: .5rem; }
.cv-err { color: hsl(var(--destructive)); }
@media (max-width: 640px) { .cv-map { grid-template-columns: 1fr; gap: 0; } .cv-map dt { margin-top: .35rem; } }
.vcs-msg { width: 100%; margin: .2rem 0 .6rem; appearance: none; background: hsl(var(--card)); color: hsl(var(--foreground)); border: 1px solid hsl(var(--border-strong)); border-radius: var(--radius-md); padding: .5rem .6rem; font-family: var(--mono); font-size: .85rem; resize: vertical; min-height: 3rem; }
.vcs-msg:focus-visible { outline: none; border-color: hsl(var(--ring)); box-shadow: 0 0 0 3px hsl(var(--ring) / .25); }

/* dashboard tables */
table.dash { border-collapse: collapse; width: 100%; font-size: .88rem; }
table.dash td { padding: .55rem .7rem; border-top: 1px solid hsl(var(--border) / .5); vertical-align: top; font-variant-numeric: tabular-nums; }
table.dash tr:first-child td { border-top: none; }
/* inset the table so its row dividers have a gap at the card's left & right */
.card:not(.tool):has(> table.dash) { padding: 0 .9rem; }
table.dash tr { transition: background .1s ease; }
table.dash tr:hover td { background: hsl(var(--accent)); }
/* title and detail (e.g. institution/location) share the flexible width; fit,
   status and deadline stay compact (shrink to their content). */
.dash-title a { text-decoration: none; }
.dash-title { overflow-wrap: anywhere; }
/* Health tab's Source column: a file:line path — long and unbroken (no
   spaces), so it needs to wrap mid-string rather than force the row (and the
   whole table) into horizontal overflow. */
.dash-source { overflow-wrap: anywhere; font-size: .82rem; }
.dash-status { color: hsl(var(--muted-foreground)); white-space: nowrap; width: 1%; }
.dash-detail { color: hsl(var(--muted-foreground)); }
.dash-fit { text-align: center; white-space: nowrap; width: 1%; }
/* Record metadata: keep the label column on one line (was wrapping "Citek/ey"). */
table.lit-meta td.dash-detail { white-space: nowrap; }
/* Wide data tables scroll rather than clip columns / wrap titles one word per
   line on a phone; the record-metadata table stacks instead (below). */
@media (max-width: 640px) {
  .card:has(> table.dash) { overflow-x: auto; }
  table.dash:not(.lit-meta) { min-width: 30rem; }
}
/* data-table component: horizontal-scroll wrapper, sortable headers, pager */
.dt-scroll { overflow-x: auto; }
.dt-filter-bar { margin: 0 0 .7rem; font-size: .85rem; color: hsl(var(--muted-foreground)); }
.dt-filter-bar select { margin-left: .3rem; font: inherit; padding: .15rem .4rem; border: 1px solid hsl(var(--border)); border-radius: var(--radius-sm); background: hsl(var(--background)); color: hsl(var(--foreground)); }
table.dash thead th .dt-sort { background: none; border: 0; margin: 0; padding: 0; font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; cursor: pointer; display: inline-flex; align-items: baseline; gap: .25rem; }
table.dash thead th .dt-sort:hover { color: hsl(var(--foreground)); }
.dt-ind { font-size: .7em; min-width: .6em; color: hsl(var(--muted-foreground)); }
th[data-dir="asc"] .dt-ind::after { content: "▲"; }
th[data-dir="desc"] .dt-ind::after { content: "▼"; }
.dt-pager { display: flex; align-items: center; justify-content: center; gap: .9rem; margin-top: .9rem; }
.dt-page { font-variant-numeric: tabular-nums; color: hsl(var(--muted-foreground)); font-size: .85rem; }
.dt-pager button[disabled] { opacity: .4; pointer-events: none; }
/* Mobile: stack a data table into per-row cards — the sort headers become a
   compact wrapping "sort" chip bar, and each row shows label:value pairs with
   the title spanning full width. No horizontal scroll / cramped columns. */
@media (max-width: 640px) {
  .data-table .dt-scroll { overflow-x: visible; }
  .data-table table.dash { min-width: 0; display: block; }
  .data-table table.dash thead { display: block; }
  .data-table table.dash thead tr { display: flex; flex-wrap: wrap; gap: .3rem; border: none; margin-bottom: .7rem; }
  .data-table table.dash thead th { display: inline-flex; padding: 0; border: none; width: auto; }
  .data-table table.dash thead th .dt-sort { border: 1px solid hsl(var(--border)); border-radius: 999px; padding: .22rem .6rem; font-size: .68rem; }
  .data-table table.dash thead th[data-dir] .dt-sort { background: hsl(var(--primary-muted)); color: hsl(var(--primary)); border-color: transparent; }
  /* A non-sortable header (Store, Actions) gets the same chip padding/size as
     the sort pills — otherwise it sits as bare cramped text against its rounded
     siblings in the wrapping chip bar, with visibly uneven spacing. */
  .data-table table.dash thead th .dt-label { display: inline-flex; padding: .22rem .6rem; font-size: .68rem; color: hsl(var(--muted-foreground)); }
  .data-table table.dash tbody { display: block; }
  .data-table table.dash tbody tr { display: block; border: 1px solid hsl(var(--border)); border-radius: var(--radius); padding: .55rem .8rem; margin-bottom: .55rem; }
  .data-table table.dash tbody tr:hover td { background: none; }
  .data-table table.dash tbody td { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; padding: .12rem 0; border: none; text-align: right; }
  .data-table table.dash tbody td::before { content: attr(data-label); color: hsl(var(--muted-foreground)); font-size: .7rem; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; text-align: left; flex: none; }
  .data-table table.dash tbody td:empty { display: none; }
  /* Title spans the row, prominent, no label prefix. */
  .data-table table.dash tbody td.dash-title { display: block; text-align: left; margin-bottom: .35rem; }
  .data-table table.dash tbody td.dash-title::before { display: none; }
  .dt-pager { justify-content: space-between; }
}
/* Record metadata: long unbroken values (citekey, DOI, topic slugs) must wrap,
   and on a phone the label/value pairs stack so nothing is clipped. */
table.lit-meta td { overflow-wrap: anywhere; }
@media (max-width: 640px) {
  table.lit-meta, table.lit-meta tbody, table.lit-meta tr, table.lit-meta td { display: block; }
  table.lit-meta tr { border-top: 1px solid hsl(var(--border) / .5); padding: .35rem 0; }
  table.lit-meta tr:first-child { border-top: none; }
  table.lit-meta td { border: none; padding: .05rem .2rem; }
  table.lit-meta td.dash-detail { color: hsl(var(--muted-foreground)); font-size: .8rem; }
}
.dl-date { white-space: nowrap; color: hsl(var(--muted-foreground)); font-variant-numeric: tabular-nums; width: 1%; }
table.dash thead th { text-align: left; padding: .3rem .7rem .5rem; font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: hsl(var(--muted-foreground)); white-space: nowrap; border-bottom: 1px solid hsl(var(--border)); }
.tag { display: inline-block; font-size: var(--text-xs); color: hsl(var(--muted-foreground)); background: hsl(var(--muted)); padding: .1rem .55rem; border-radius: var(--radius-full); white-space: nowrap; text-transform: capitalize; }
.dash-sub { color: hsl(var(--muted-foreground)); opacity: .85; }
/* tender eligibility sub-line under the title */
.dash-note { font-size: var(--text-xs); color: hsl(var(--muted-foreground)); margin-top: .15rem; max-width: 60ch; }
/* tender detail — labelled field list */
dl.kv { display: grid; grid-template-columns: max-content 1fr; gap: .55rem 1.4rem; margin: 0; align-items: baseline; }
dl.kv dt { font-weight: 600; color: hsl(var(--muted-foreground)); }
dl.kv dd { margin: 0; }
dl.kv dd ul { margin: 0; padding-left: 1.1rem; }
/* discovery fit score (jobs) — a plain colour-coded number, no badge */
.fit-score { font-weight: 650; font-variant-numeric: tabular-nums; color: hsl(var(--muted-foreground)); }
.fit-score.fit-5, .fit-score.fit-4 { color: hsl(142 60% 34%); }
.fit-score.fit-3 { color: hsl(38 75% 40%); }
/* job-search feed list */
.feed-list { list-style: none; margin: .3rem 0 0; padding: 0; }
.feed-list li { font-size: var(--text-xs); line-height: 1.55; }
.feed-list a { color: hsl(var(--muted-foreground)); }
.feed-list a:hover { color: hsl(var(--foreground)); }
.dl-date .overdue { color: hsl(var(--destructive)); font-weight: 620; }

/* preformatted blocks — shared base, then per-use differences */
.tool-output, pre.codeblock, .screen {
  font-family: var(--mono); overflow: auto;
  border: 1px solid hsl(var(--border)); border-radius: var(--radius);
}
.tool-output { background: hsl(var(--muted)); padding: .85rem; white-space: pre-wrap; word-break: break-word; font-size: .82rem; line-height: 1.5; }
.screen { background: hsl(var(--muted)); padding: .85rem; white-space: pre; max-height: 70vh; font-size: .78rem; line-height: 1.35; }

/* page header row (title + inline action, e.g. Edit) */
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
/* See `.pane-head h2` above — same fix, same reason (long unbroken project/job/
   grant/review titles forcing horizontal scroll on mobile otherwise). */
.page-head h1 { margin: .1rem 0 .35rem; min-width: 0; overflow-wrap: anywhere; }
.head-actions { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }

/* project-detail secondary nav: a right-aligned bar of section links at title
   height. Each opens that section's own page; `.active` is the current one. */
.section-nav { display: flex; align-items: center; gap: .1rem; flex-wrap: wrap; justify-content: flex-end; }
.section-link { font-size: .85rem; color: hsl(var(--muted-foreground)); text-decoration: none; padding: .32rem .62rem; border-radius: var(--radius-sm); transition: background .12s ease, color .12s ease; }
.section-link:hover { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
.section-link.active { background: hsl(var(--primary-muted)); color: hsl(var(--primary)); font-weight: 600; }
@media (max-width: 640px) {
  /* On phones the section bar runs flush-left. Without JS it wraps; the overflow
     script (`.js-overflow`) forces a single line and moves the extras into a
     "…" menu. */
  .section-nav { justify-content: flex-start; width: 100%; }
  /* min-width:0 lets the flex item shrink below its content width, so the
     overflow script can measure `scrollWidth > clientWidth` and collapse. */
  /* If the tabs still overflow (measurement race / very narrow), scroll them
     rather than clipping the last tab off-screen. */
  .section-nav.js-overflow { flex-wrap: nowrap; min-width: 0; overflow-x: auto; scrollbar-width: none; }
  .section-nav.js-overflow::-webkit-scrollbar { display: none; }
  .section-link { flex: none; white-space: nowrap; padding: .5rem .7rem; }
}
/* the "…" overflow button + its dropdown of the links that didn't fit */
.section-more { position: relative; }
.section-more > summary { list-style: none; }
.section-more > summary::-webkit-details-marker { display: none; }
.section-more[open] > summary.section-link { background: hsl(var(--accent)); color: hsl(var(--foreground)); }
.section-more-panel {
  position: absolute; top: calc(100% + .35rem); right: 0; z-index: 30;
  display: flex; flex-direction: column; gap: .05rem; min-width: 9rem;
  background: hsl(var(--card)); border: 1px solid hsl(var(--border));
  border-radius: var(--radius); box-shadow: var(--shadow); padding: .3rem;
}
.section-more-panel .section-link { display: block; }
/* When the ⋯ menu is open, stop the nav from clipping: `.js-overflow` sets
   overflow-x:auto on the bar (for the scroll fallback), which per spec also clips
   overflow-y and would hide the dropdown panel that drops below the bar. */
.section-nav.js-overflow:has(.section-more[open]) { overflow: visible; }
/* swipe between sections: the content wrapper that slides (header/submenu stay
   put), plus the prefetched neighbour panels that slide in with the finger. */
.section-body { will-change: transform; }
.swipe-ghost { position: fixed; left: 0; width: 100%; z-index: 5; overflow: hidden; background: hsl(var(--background)); will-change: transform; }

/* project Dashboard + Files preview panes. Stacked by default; a two-column grid
   on desktop. The desktop rule must follow this base rule in source order (equal
   specificity) so `grid` wins over `flex` on a wide viewport. */
.proj-dash, .proj-files { display: flex; flex-direction: column; gap: 1rem; }
.proj-dash-side { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
@media (min-width: 60rem) {
  /* Dashboard: essentials beside the manuscript preview. Files: the file list
     beside a preview pane. */
  .proj-dash { display: grid; grid-template-columns: minmax(19rem, 23rem) 1fr; gap: 1.3rem; align-items: start; }
  .proj-files { display: grid; grid-template-columns: minmax(15rem, 20rem) 1fr; gap: 1.3rem; align-items: start; }
}
.file-pane, .preview-pane { min-width: 0; } /* let the grid columns shrink */
.preview-img { display: block; max-width: 100%; height: auto; border-radius: var(--radius); }
.preview-code { max-height: 74vh; overflow: auto; }
/* the previewed file's row, and the manuscript-preview panel heading */
a.row.active { background: hsl(var(--primary-muted)); }
a.row.active .row-label { color: hsl(var(--primary)); font-weight: 600; }
/* the parent (`..`) row is a navigation affordance, not a file → muted */
a.row.up .row-label, a.row.up .row-icon { color: hsl(var(--muted-foreground)); }
/* the preview pane is a flush file viewer: the embedded file fills the pane card
   with no inner border or padding. Only the header keeps its inset (divided by a
   rule); the body — iframe / source / image — runs edge to edge. */
.preview-pane > .card.tool { padding: 0; }
.preview-pane > .card.tool > .pane-head { margin: 0; padding: .5rem .85rem; border-bottom: 1px solid hsl(var(--border) / .6); }
.preview-pane .content { padding: .9rem 1.15rem; }
.preview-pane pre.codeblock { margin: 0; box-shadow: none; border-radius: 0; }
.preview-pane .preview-img { border-radius: 0; }
.upload-form { display: inline-flex; align-items: center; gap: .4rem; }

/* editor (CodeMirror, themed via tokens so it adapts to dark) */
.editor-path { display: flex; align-items: center; gap: .6rem; margin: .3rem 0 .7rem; }
.editor-path span { font-size: .8rem; color: hsl(var(--muted-foreground)); }
.editor-path input { margin: 0; max-width: 34rem; font-family: var(--mono); font-size: .85rem; }
.editor-box { margin: .5rem 0 .85rem; }
.editor-actions { display: flex; gap: .6rem; }
.CodeMirror { height: 62vh; border: 1px solid hsl(var(--border)); border-radius: var(--radius); background: hsl(var(--card)); color: hsl(var(--foreground)); font-family: var(--mono); font-size: .85rem; line-height: 1.55; }
.CodeMirror-gutters { background: hsl(var(--card-2)); border-right: 1px solid hsl(var(--border)); }
.CodeMirror-linenumber { color: hsl(var(--muted-foreground)); }
.CodeMirror-cursor { border-left: 1.5px solid hsl(var(--foreground)); }
.CodeMirror-selected { background: hsl(var(--primary-muted)); }
.CodeMirror-focused .CodeMirror-selected { background: hsl(var(--primary-muted)); }
.cm-header { color: hsl(var(--primary)); font-weight: 600; }
.cm-keyword { color: hsl(var(--syn-keyword)); }
.cm-string, .cm-string-2 { color: hsl(var(--syn-string)); }
.cm-comment { color: hsl(var(--syn-comment)); font-style: italic; }
.cm-variable-2, .cm-def { color: hsl(var(--syn-func)); }
.cm-number { color: hsl(var(--syn-number)); }
.cm-link, .cm-url { color: hsl(var(--primary)); }
.cm-quote { color: hsl(var(--muted-foreground)); }

/* code viewer + highlight.js theme (shadcn tokens, adapts light/dark) */
pre.codeblock {
  background: hsl(var(--card)); padding: .9rem 1rem; margin: .4rem 0 1.3rem;
  box-shadow: var(--shadow-sm); font-size: .8rem; line-height: 1.55; tab-size: 2;
}
pre.codeblock code { background: none; padding: 0; white-space: pre; }
.hljs { color: hsl(var(--foreground)); background: transparent; }
.hljs-comment, .hljs-quote { color: hsl(var(--syn-comment)); font-style: italic; }
.hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-section, .hljs-doctag, .hljs-type, .hljs-name, .hljs-strong { color: hsl(var(--syn-keyword)); }
.hljs-string, .hljs-attr, .hljs-regexp, .hljs-addition, .hljs-meta-string { color: hsl(var(--syn-string)); }
.hljs-number, .hljs-built_in, .hljs-builtin-name, .hljs-literal, .hljs-symbol, .hljs-bullet { color: hsl(var(--syn-number)); }
.hljs-title, .hljs-title.function_, .hljs-function .hljs-title, .hljs-selector-id, .hljs-selector-class { color: hsl(var(--syn-func)); }
.hljs-variable, .hljs-template-variable, .hljs-attribute, .hljs-params { color: hsl(var(--foreground)); }
.hljs-meta, .hljs-comment { color: hsl(var(--syn-comment)); }
.hljs-deletion { color: hsl(var(--destructive)); }

/* utility layer — a deliberately small, composable set (no-Tailwind ethos) */
.u-flex    { display: flex; align-items: center; gap: var(--space-2); }
.u-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.u-stack   { display: flex; flex-direction: column; gap: var(--space-2); }
.u-wrap    { flex-wrap: wrap; }
.u-muted   { color: hsl(var(--muted-foreground)); }
.u-mono    { font-family: var(--mono); }
.u-nums    { font-variant-numeric: tabular-nums; }
.u-truncate { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.u-mt      { margin-top: var(--space-4); }
.u-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* honour reduced-motion: neutralise transitions/animations globally */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}

/* ================= themes × light/dark ================= *
 * `data-theme` (journal|studio|console) picks the identity — fonts, layout,
 * button style, accent; `data-mode` (system|light|dark) picks the palette. Each
 * theme defines LIGHT surface tokens on its base selector and DARK ones in the
 * dark blocks at the end (applied for data-mode=dark, or data-mode=system under
 * an OS dark preference). Server sets both attributes on <html> (defaults
 * theme=journal, mode=system). */

/* self-hosted variable faces (served from /static) */
@font-face { font-family: 'Inter'; src: url('/static/inter.woff2') format('woff2'); font-weight: 100 900; font-style: normal; font-display: swap; }
@font-face { font-family: 'Newsreader'; src: url('/static/serif.woff2') format('woff2'); font-weight: 200 800; font-style: normal; font-display: swap; }

/* type hooks — each theme points these at the faces it wants */
:root { --font-ui: 'Inter', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; --font-head: var(--font-ui); --font-prose: var(--font-ui); }
body { font-family: var(--font-ui); }
h1, h2, h3, .brand, .login-brand { font-family: var(--font-head); }
.content, .prose { font-family: var(--font-prose); }

/* keep native controls (scrollbars, form widgets, the pdf.js UI) in step */
[data-mode="light"] { color-scheme: light; }
[data-mode="dark"] { color-scheme: dark; }
[data-mode="system"] { color-scheme: light dark; }

/* the in-nav switchers (theme J/S/C and mode share this styling) */
.theme-switch { display: inline-flex; gap: 2px; padding: 2px; margin-left: .3rem; background: hsl(var(--muted)); border: 1px solid hsl(var(--border)); border-radius: var(--radius-full); }
.theme-switch .tsw { display: inline-flex; align-items: center; justify-content: center; width: 1.5rem; height: 1.5rem; border-radius: var(--radius-full); font-size: .72rem; font-weight: 650; color: hsl(var(--muted-foreground)); text-decoration: none; }
.theme-switch .tsw:hover { color: hsl(var(--foreground)); }
.theme-switch .tsw.on { background: hsl(var(--card)); color: hsl(var(--foreground)); box-shadow: var(--shadow-sm); }
/* mobile menu: labeled 'Theme'/'Mode' rows with word labels (the compact copies
 * inherited from the nav links are hidden here to avoid a buried duplicate) */
.menu-theme { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .1rem .25rem .55rem; margin-bottom: .35rem; border-bottom: 1px solid hsl(var(--border)); }
.menu-theme-label { font-size: .82rem; font-weight: 600; color: hsl(var(--muted-foreground)); }
.menu-panel .theme-switch:not(.wide) { display: none; }
.theme-switch.wide { margin-left: 0; }
.theme-switch.wide .tsw { width: auto; height: auto; padding: .34rem .62rem; font-size: .78rem; }

/* ---- JOURNAL — editorial serif, ink/cream pill buttons, warm paper ---- */
[data-theme="journal"] {
  --background: 38 30% 98.5%; --card: 38 30% 99.3%; --card-2: 38 22% 96.5%;
  --foreground: 30 12% 14%; --muted-foreground: 34 8% 40%;
  --muted: 38 18% 95.5%; --accent: 38 22% 94%;
  --border: 34 16% 88%; --border-strong: 34 16% 80%;
  --primary: 8 56% 44%; --primary-hover: 8 56% 38%; --primary-foreground: 38 30% 98%;
  --primary-muted: 8 50% 95%; --ring: 8 56% 44%;
  --jbtn: 28 22% 16%; --jbtn-fg: 38 30% 97%;
  --radius: .5rem; --radius-lg: .7rem;
  --font-head: 'Newsreader', Georgia, serif; --font-prose: 'Newsreader', Georgia, serif;
}
[data-theme="journal"] h1 { font-weight: 560; letter-spacing: -.008em; font-size: 2.05rem; line-height: 1.1; }
[data-theme="journal"] h2 { font-weight: 560; letter-spacing: 0; }
[data-theme="journal"] .subtitle { font-family: var(--font-head); font-style: italic; font-size: 1.08rem; }
[data-theme="journal"] .content { font-size: 1.08rem; line-height: 1.8; }
[data-theme="journal"] main { max-width: 42rem; }
[data-theme="journal"] .card { box-shadow: none; }
[data-theme="journal"] .session-list { background: transparent; }
[data-theme="journal"] .btn { background: hsl(var(--jbtn)); color: hsl(var(--jbtn-fg)); border: 1px solid hsl(var(--jbtn)); border-radius: var(--radius-full); box-shadow: var(--shadow-sm); font-weight: 600; }
[data-theme="journal"] .btn:hover { filter: brightness(1.3); }
[data-theme="journal"] .btn.ghost { background: transparent; color: hsl(var(--foreground)); border: 1px solid hsl(var(--border-strong)); box-shadow: none; filter: none; }
[data-theme="journal"] .btn.ghost:hover { background: hsl(var(--card-2)); border-color: hsl(var(--foreground)); }
[data-theme="journal"] .btn.ghost.danger { color: hsl(var(--destructive)); border-color: hsl(var(--destructive) / .4); }

/* ---- STUDIO — cool-neutral (obsidian) surfaces, magenta accent, flat cards ---- */
[data-theme="studio"] {
  --background: 240 12% 96.5%; --card: 0 0% 100%; --card-2: 250 14% 94%;
  --foreground: 250 17% 13%; --muted-foreground: 247 9% 42%;
  --muted: 250 13% 94%; --accent: 250 13% 92%;
  --border: 246 14% 89%; --border-strong: 247 11% 80%;
  --primary: 327 74% 48%; --primary-hover: 327 77% 42%; --primary-muted: 327 62% 95%; --primary-foreground: 0 0% 100%; --ring: 327 74% 48%;
  --success: 150 45% 37%; --success-dot: 150 50% 42%; --warning: 32 82% 47%;
  --nav-bg: 240 12% 96%;
  --radius: .5rem; --radius-lg: .8rem;
}
/* flat cards, separated by a hairline in both modes (global .card border, no shadow) */
[data-theme="studio"] .btn { background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); border: 1px solid transparent; box-shadow: none; }
[data-theme="studio"] .btn:hover { background: hsl(var(--primary-hover)); }
[data-theme="studio"] .btn.ghost { background: transparent; color: hsl(var(--foreground)); border: 1px solid hsl(var(--border-strong)); box-shadow: none; }
[data-theme="studio"] .btn.ghost:hover { background: hsl(var(--accent)); }

/* turn the top nav into a left rail on wide screens */
@media (min-width: 641px) {
  [data-theme="studio"] body { display: flex; align-items: stretch; position: relative; }
  /* keep the status line at the bottom of the content, not as a 3rd flex column */
  [data-theme="studio"] .app-status { position: absolute; left: 220px; right: 0; bottom: 0; }
  [data-theme="studio"] header.nav {
    position: sticky; top: 0; align-self: flex-start; height: 100dvh;
    width: 220px; flex: none; flex-direction: column; align-items: stretch; gap: .12rem;
    background: hsl(var(--nav-bg)); border-bottom: none; border-right: 1px solid hsl(var(--border));
    -webkit-backdrop-filter: none; backdrop-filter: none; padding: .9rem .55rem;
  }
  [data-theme="studio"] header.nav .brand { margin-bottom: .5rem; }
  [data-theme="studio"] header.nav a.navlink,
  [data-theme="studio"] header.nav summary.navlink { font-size: .9rem; padding: .5rem .6rem; }
  /* current page reads as a soft filled pill in the rail */
  [data-theme="studio"] header.nav a.navlink.on,
  [data-theme="studio"] header.nav summary.navlink.on { background: hsl(var(--primary-muted)); color: hsl(var(--primary)); }
  /* group the Tracking/Ops clusters below the top links with a hairline */
  [data-theme="studio"] header.nav > details.dropdown:first-of-type { margin-top: .5rem; padding-top: .6rem; border-top: 1px solid hsl(var(--border)); }
  [data-theme="studio"] header.nav form.search { margin: .5rem 0 0; order: 8; flex: 0 0 auto; }
  /* user/settings menu pinned to the bottom of the rail, opening upward */
  [data-theme="studio"] header.nav .dropdown.user { margin: .5rem 0 0; order: 9; align-self: flex-start; }
  /* In the left rail the user button sits at the far left, so the panel must
     open rightward (into the content). Override the `.right` alignment (which is
     correct only for the top-right nav) so it does not spill off the left edge. */
  [data-theme="studio"] header.nav .dropdown.user .dropdown-panel { top: auto; bottom: calc(100% + .35rem); left: 0; right: auto; }
  [data-theme="studio"] main { flex: 1; min-width: 0; }
}

/* ---- CONSOLE — vibrant violet gradient buttons, glow (light base) ---- */
[data-theme="console"] {
  --background: 240 20% 98.5%; --card: 0 0% 100%; --card-2: 240 22% 97%;
  --foreground: 240 14% 12%; --muted-foreground: 240 6% 45%;
  --muted: 240 8% 95%; --accent: 240 8% 95%; --input: 240 8% 84%;
  --border: 240 8% 90%; --border-strong: 240 8% 84%;
  --primary: 255 82% 60%; --primary-hover: 255 82% 54%; --primary-foreground: 0 0% 100%;
  --primary-muted: 255 70% 96%; --ring: 255 82% 60%;
  --radius-lg: .9rem;
}
[data-theme="console"] .btn { background: linear-gradient(135deg, hsl(258 90% 66%), hsl(240 90% 60%)); color: #fff; border: none; box-shadow: 0 4px 14px hsl(255 90% 55% / .35), inset 0 1px 0 hsl(0 0% 100% / .2); }
[data-theme="console"] .btn:hover { filter: brightness(1.07); background: linear-gradient(135deg, hsl(258 90% 66%), hsl(240 90% 60%)); }
[data-theme="console"] .btn.ghost { background: hsl(var(--card-2)); color: hsl(var(--foreground)); border: 1px solid hsl(var(--border)); box-shadow: none; }
[data-theme="console"] .btn.ghost:hover { background: hsl(var(--accent)); }
[data-theme="console"] .btn.ghost.danger { color: hsl(var(--destructive)); border-color: hsl(var(--destructive) / .4); }
[data-theme="console"] .dot { box-shadow: 0 0 10px hsl(var(--success-dot) / .85); }
[data-theme="console"] .session-list { background: hsl(var(--card-2)); }
[data-theme="console"] header.nav a.navlink.on, [data-theme="console"] .theme-switch .tsw.on { color: hsl(var(--primary)); }

/* ============ per-theme DARK surface tints ============ *
 * Applied for explicit dark mode and for system mode under OS dark. Duplicated
 * across the two conditions (pure CSS cannot share a rule across the media
 * boundary); the shared non-surface dark tokens come from `[data-mode="dark"]`
 * / `[data-mode="system"]` above. */
[data-mode="dark"][data-theme="journal"] {
  --background: 28 14% 10%; --card: 28 13% 13%; --card-2: 28 12% 16.5%;
  --foreground: 38 22% 89%; --muted-foreground: 34 10% 63%;
  --muted: 28 10% 17%; --accent: 28 10% 18%;
  --border: 30 9% 23%; --border-strong: 30 9% 32%;
  --primary: 8 72% 65%; --primary-hover: 8 72% 71%; --primary-muted: 8 45% 22%; --ring: 8 72% 65%;
  --jbtn: 38 32% 90%; --jbtn-fg: 28 24% 12%;
}
[data-mode="dark"][data-theme="studio"] {
  --background: 240 16% 6%; --card: 246 17% 11%; --card-2: 250 16% 14%;
  --foreground: 250 14% 91%; --muted-foreground: 247 8% 60%;
  --muted: 250 15% 15%; --accent: 248 14% 19%; --input: 248 12% 22%;
  --border: 250 14% 17%; --border-strong: 248 12% 27%;
  --primary: 330 82% 66%; --primary-hover: 330 88% 73%; --primary-muted: 328 38% 20%; --primary-foreground: 335 30% 11%; --ring: 330 82% 66%;
  --nav-bg: 242 16% 8%;
}
[data-mode="dark"][data-theme="console"] {
  --background: 240 14% 8%; --card: 240 12% 11%; --card-2: 240 12% 13.5%;
  --foreground: 240 20% 96%; --muted-foreground: 240 8% 62%;
  --muted: 240 10% 16%; --accent: 240 10% 16%; --input: 240 10% 24%;
  --border: 240 10% 20%; --border-strong: 240 10% 28%;
  --primary: 255 90% 74%; --primary-hover: 255 90% 80%; --primary-muted: 255 55% 22%; --ring: 255 90% 74%;
  --destructive: 0 78% 66%; --success: 145 60% 58%; --success-dot: 145 70% 55%;
}
@media (prefers-color-scheme: dark) {
  [data-mode="system"][data-theme="journal"] {
    --background: 28 14% 10%; --card: 28 13% 13%; --card-2: 28 12% 16.5%;
    --foreground: 38 22% 89%; --muted-foreground: 34 10% 63%;
    --muted: 28 10% 17%; --accent: 28 10% 18%;
    --border: 30 9% 23%; --border-strong: 30 9% 32%;
    --primary: 8 72% 65%; --primary-hover: 8 72% 71%; --primary-muted: 8 45% 22%; --ring: 8 72% 65%;
    --jbtn: 38 32% 90%; --jbtn-fg: 28 24% 12%;
  }
  [data-mode="system"][data-theme="studio"] {
    --background: 240 16% 6%; --card: 246 17% 11%; --card-2: 250 16% 14%;
    --foreground: 250 14% 91%; --muted-foreground: 247 8% 60%;
    --muted: 250 15% 15%; --accent: 248 14% 19%; --input: 248 12% 22%;
    --border: 250 14% 17%; --border-strong: 248 12% 27%;
    --primary: 330 82% 66%; --primary-hover: 330 88% 73%; --primary-muted: 328 38% 20%; --primary-foreground: 335 30% 11%; --ring: 330 82% 66%;
    --nav-bg: 242 16% 8%;
  }
  [data-mode="system"][data-theme="console"] {
    --background: 240 14% 8%; --card: 240 12% 11%; --card-2: 240 12% 13.5%;
    --foreground: 240 20% 96%; --muted-foreground: 240 8% 62%;
    --muted: 240 10% 16%; --accent: 240 10% 16%; --input: 240 10% 24%;
    --border: 240 10% 20%; --border-strong: 240 10% 28%;
    --primary: 255 90% 74%; --primary-hover: 255 90% 80%; --primary-muted: 255 55% 22%; --ring: 255 90% 74%;
    --destructive: 0 78% 66%; --success: 145 60% 58%; --success-dot: 145 70% 55%;
  }
}

/* ── detail-page components (application / review / tender pages) ──────────── */
/* status pipeline: a row of step pills with arrows, current step highlighted */
.pipeline { display: flex; gap: .3rem; align-items: center; flex-wrap: wrap; margin: .2rem 0 .7rem; }
.pipe-arrow { color: hsl(var(--muted-foreground)); }
.pipe-step { padding: .1rem .5rem; border-radius: var(--radius-sm); font-size: .75rem; background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); }
.pipe-step.reached { color: hsl(var(--foreground)); }
.pipe-step.current { background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); font-weight: 640; }
.pipe-outcome { margin-left: .3rem; font-weight: 640; }

/* completeness progress bar + its checkpoint list (dossier documents) */
.progress-label { margin: .2rem 0; }
.progress { background: hsl(var(--muted)); border-radius: var(--radius-sm); height: 8px; overflow: hidden; }
.progress-fill { height: 100%; background: hsl(var(--primary)); } /* width set inline (data-driven) */
.checklist { list-style: none; padding: 0; margin: .4rem 0 0; display: flex; flex-wrap: wrap; gap: .2rem 1rem; font-size: .8rem; }
.checklist-item.pending { color: hsl(var(--muted-foreground)); }
.deadline-line { margin: 0; }

/* embedded PDF preview (dossier / manuscript) */

/* a plain vertical list of file links (detail-page file panes) */
.file-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: .25rem; }

/* "New review" disclosure form on the reviews page */
.review-new { margin-top: 1.2rem; }
.review-new > summary { cursor: pointer; font-weight: 620; }
.review-new .subtitle { margin: .5rem 0 .2rem; }
.review-form { display: flex; flex-direction: column; gap: .6rem; max-width: 34rem; }
.review-form label { display: flex; flex-direction: column; gap: .2rem; }

/* dedicated "New <item>" pages (Projects/Talks/Reviews) */
.new-form { display: flex; flex-direction: column; gap: .7rem; max-width: 34rem; }
.new-field { display: flex; flex-direction: column; gap: .25rem; }
.new-field > span { font-weight: 560; font-size: .9rem; }
.new-actions { display: flex; gap: .6rem; margin-top: .4rem; }

/* institute members (professors) on a job/application page */
.prof-label { margin: .3rem 0 .2rem; }
.prof-list { display: flex; flex-wrap: wrap; gap: .3rem .7rem; align-items: center; }
.prof-fetch { display: inline-flex; align-items: center; gap: .25rem; }

/* nested todo rows indent by depth (`--todo-depth` set inline) */
.todo-row { margin-left: calc(var(--todo-depth, 0) * 1.1rem); }
