/* Steeped — a refined dark reading room. Tea-black ink, parchment text, and two
   accents that each mean one thing: jade for what you can act on (links, buttons,
   focus) and amber for the thing you were looking for (the search match, a page
   marker). Soft radii, quiet shadows, serif display over a sans body. */

/* Latin only, so Thai filenames fall through to the Thai fallback below. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/static/fonts/inter-latin-var.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-latin-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: dark; /* native controls and scrollbars follow the dark theme */

  --primary: #efede3;   /* parchment — the ink of the page, brighter for contrast */
  --secondary: #0a0e0c; /* tea-black, cool and crisp */
  --tertiary: #35443b;  /* strong border / divider */
  --surface: #121815;   /* cards */
  --surface-2: #18201c; /* inputs, table headers, raised chrome */
  --border: #26312b;    /* default hairline */
  --hover: #1b231e;     /* row / control hover wash */
  --muted: #93a093;
  --info: #a8b3a7;

  /* Jade — the one thing you can act on. Links, buttons, focus, active nav. */
  --accent: #4ed8a0;
  --accent-hover: #5fe6ae;
  --accent-dim: #2fa277;
  --accent-ink: #07130d;       /* text that sits on a jade fill */
  --accent-wash: rgba(78, 216, 160, 0.14);

  /* Amber — the thing you were looking for. The search match, a page marker. */
  --amber: #e8b54d;
  --amber-line: rgba(232, 181, 77, 0.55);
  --amber-glow: rgba(232, 181, 77, 0.30);

  --success: #8ed6a6;
  --warning: #e8b54d;
  --error: #f0846f;

  --font: 'Inter', 'Leelawadee UI', 'Noto Sans Thai', system-ui, sans-serif;
  /* System serifs only — bookish display without shipping another font file. */
  --display: 'Iowan Old Style', 'Palatino Linotype', 'Book Antiqua', Georgia, serif;
  --mono: 'IBM Plex Mono', Consolas, monospace;

  --radius: 10px;       /* controls */
  --radius-lg: 14px;    /* cards, tables */
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-lift: 0 8px 26px rgba(0, 0, 0, 0.38);

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 16px;
  --space-4: 32px;
  --space-5: 48px;
  --space-6: 64px;
  --space-8: 96px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--secondary);
  color: var(--primary);
  font-family: var(--font);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* Chrome recedes: no bar, just a rule under the nav (login view). */
header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
}
.brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.03em;
}
/* The wordmark's tile: a small jade chip carrying the initials. */
.brand .mark {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
}
nav {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
}
nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 400;
  letter-spacing: 0.01em;
  padding: 9px 12px;
  border-radius: 8px;
  transition: background 140ms, color 140ms;
}
nav a .ic { flex: 0 0 17px; width: 17px; height: 17px; opacity: 0.9; }
nav a:hover { background: var(--hover); color: var(--primary); }
/* The page you are on: jade wash plus a jade marker down the left. */
nav a.active { background: var(--accent-wash); color: var(--primary); position: relative; }
.who {
  color: var(--info);
  font-size: 12.5px;
  font-weight: 400;
  padding-left: var(--space-3);
  border-left: 1px solid var(--border);
}
.who b { display: block; color: var(--primary); font-weight: 500; }

main {
  max-width: 900px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-3) var(--space-8);
}
/* 900px is a measure for reading. A file table is not prose and would rather
   have the room than the margins. */
main.wide { max-width: 1400px; }

/* Signed in, the nav runs down the left instead of across the top. Login keeps
   the top bar, since a 232px column holding only the wordmark is just a gap. */
body.app { display: flex; align-items: flex-start; }
body.app header {
  flex: 0 0 232px;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  gap: var(--space-5);
  height: 100vh;
  position: sticky;
  top: 0;
  padding: var(--space-5) var(--space-3);
  border-bottom: 0;
  border-right: 1px solid var(--border);
  background: linear-gradient(180deg, #0c1210, var(--secondary));
}
body.app .brand { padding: 0 var(--space-2); }
body.app nav {
  flex: 1;
  flex-direction: column;
  align-items: stretch;
  align-self: stretch;
  gap: var(--space-1);
}
body.app nav a.active::before {
  content: "";
  position: absolute;
  left: -16px;
  top: 8px;
  bottom: 8px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--accent);
}
/* margin-top:auto drops the name and Log out to the foot of the column. */
body.app .who {
  margin-top: auto;
  align-self: stretch;
  padding: var(--space-3) var(--space-2) 0;
  border-left: 0;
  border-top: 1px solid var(--border);
}
/* min-width:0 lets .table-wrap shrink; a flex item defaults to min-width:auto
   and a wide table would otherwise push the whole layout sideways again. */
body.app main { flex: 1; min-width: 0; padding: var(--space-6) var(--space-5) var(--space-8); }

/* Too narrow for a column beside the content — put it back on top. A 232px
   nav is a third of a 730px window, and the file table cannot be read out of
   what is left; lying down it costs two lines and gives the width back. */
@media (max-width: 950px) {
  body.app { display: block; }
  body.app header {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: var(--space-2);
    height: auto;
    position: static;
    padding: var(--space-3);
    border-right: 0;
    border-bottom: 1px solid var(--border);
    background: var(--secondary);
  }
  body.app .brand { flex: 1 0 100%; padding: 0; margin-bottom: var(--space-1); }
  body.app nav {
    flex: 1;
    flex-direction: row;
    align-items: center;
    align-self: auto;
    flex-wrap: wrap;
    gap: var(--space-1);
  }
  body.app nav a { padding: 7px 10px; font-size: 13px; }
  body.app nav a.active::before { display: none; }
  body.app .who {
    margin-top: 0;
    align-self: auto;
    padding: var(--space-2) 0 0;
    border-top: 1px solid var(--border);
    flex: 1 0 100%;
  }
  body.app .who b { display: inline; }
  body.app main { padding: var(--space-4) var(--space-3) var(--space-6); }
}

/* Eyebrow over a hero title: the section you are in, said quietly in jade. */
.eyebrow {
  margin: 0 0 var(--space-2);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}
/* Lede under a hero title. */
.lede { margin: 0 0 var(--space-4); color: var(--muted); font-size: 15px; }

/* Two title scales, and it matters which a page uses. The hero (.search-box on
   Search and Ask) is the whole point of its page and keeps the 42px serif. A
   working page — a file list, the team roster — is a title with things to do
   beside it, so .page-head sets it smaller and hangs the actions off the right.
   Every page other than the two heroes and the login plate uses this. */
.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.page-head-text { min-width: 0; flex: 1 1 320px; }
.page-head h1 { font-size: 30px; margin: 0; }
/* The lede's own bottom margin belongs to the hero; here the flex gap has it. */
.page-head .lede { margin: var(--space-2) 0 0; max-width: 64ch; }
.page-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

/* Headings carry the library: serif display over a sans body. */
h1 {
  font-family: var(--display);
  font-size: 42px;
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin: 0 0 var(--space-4);
}
h2 {
  font-family: var(--display);
  font-size: 28px;
  font-weight: 600;
  line-height: 1.2;
  margin: 0 0 var(--space-3);
}
h3 {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
  margin: 0 0 var(--space-3);
}

a { color: var(--accent); }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  margin-bottom: var(--space-3);
  box-shadow: var(--shadow);
  transition: border-color 140ms, box-shadow 140ms, transform 140ms;
}
.card:hover { border-color: var(--tertiary); box-shadow: var(--shadow-lift); }
.narrow { max-width: 460px; margin: var(--space-6) auto; }

/* A panel holds a form or a setting; a card holds content. They look alike on
   purpose but a panel does not lift on hover — lifting reads as "this opens",
   which is a lie about a form you are already standing in. */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  margin-bottom: var(--space-3);
  box-shadow: var(--shadow);
}
/* Separates two jobs inside one panel. */
hr.rule { border: 0; border-top: 1px solid var(--border); margin: var(--space-4) 0; }

/* Login as a bookplate: a faint outline frames the card, the title sits centred
   over one short jade line — the ex-libris of the library. */
.login-plate {
  padding: var(--space-5);
  border-color: var(--border);
  outline: 1px solid var(--border);
  outline-offset: 6px;
  margin-top: var(--space-8);
}
.login-plate:hover { border-color: var(--border); transform: none; }
.login-plate h1 {
  font-size: 30px;
  text-align: center;
}
.login-plate h1::after {
  content: "";
  display: block;
  width: 48px;
  margin: var(--space-3) auto 0;
  border-bottom: 2px solid var(--accent);
}
.login-plate button { width: 100%; margin-top: var(--space-2); }

/* Forms */
label {
  display: block;
  margin: 0 0 var(--space-3);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
label.inline {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  text-transform: none;
  letter-spacing: 0;
  font-size: 14px;
  font-weight: 400;
  color: var(--primary);
}

input, select {
  display: block;
  width: 100%;
  height: 42px;
  margin-top: var(--space-2);
  padding: 0 14px;
  border: 1px solid var(--tertiary);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--primary);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  transition: border-color 140ms, box-shadow 140ms;
}
input::placeholder { color: var(--muted); opacity: 0.7; }
input:hover, select:hover { border-color: var(--muted); }
input:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-wash);
}
input[type="file"] { padding: var(--space-2); height: auto; }
label.inline input {
  display: inline;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--accent);
}

/* Primary actions are jade — the one thing you can act on. */
button {
  height: 42px;
  min-width: 96px;
  padding: 0 24px;
  border: 0;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: pointer;
  transition: background 140ms, box-shadow 140ms, color 140ms;
}
button:hover { background: var(--accent-hover); box-shadow: 0 6px 22px rgba(78, 216, 160, 0.22); }
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button:disabled { opacity: 0.35; cursor: not-allowed; box-shadow: none; }
button.danger { background: transparent; color: var(--error); border: 1px solid rgba(240, 132, 111, 0.45); }
button.danger:hover { background: var(--error); color: #1a0d0a; box-shadow: none; }
/* The second of two submit buttons — same weight of action, less of the eye.
   Jade is "the thing to press"; two jade buttons side by side would say the
   choice matters more than it does. */
button.ghost { background: transparent; color: var(--primary); border: 1px solid var(--tertiary); }
button.ghost:hover { background: var(--hover); color: var(--accent); border-color: var(--accent); box-shadow: none; }
/* Secondary: outlined, fills toward jade on hover rather than shouting in it. */
button.small-btn {
  height: 34px;
  min-width: 64px;
  padding: 0 var(--space-3);
  font-size: 12.5px;
  font-weight: 500;
  background: transparent;
  color: var(--primary);
  border: 1px solid var(--tertiary);
}
button.small-btn:hover { background: var(--hover); color: var(--accent); border-color: var(--accent); box-shadow: none; }
button.danger.small-btn { color: var(--error); border-color: rgba(240, 132, 111, 0.45); background: transparent; }
button.danger.small-btn:hover { background: var(--error); color: #1a0d0a; border-color: var(--error); }
/* Asked and waiting for the second press. It has to look unlike the button you
   pressed, or the question does not read as a question. */
button.armed, button.danger.armed, button.danger.small-btn.armed {
  background: var(--error);
  color: #1a0d0a;
  border-color: var(--error);
  box-shadow: none;
}

/* Upload is a link (it goes to a page) that has to sit in a row of buttons and
   read as the primary action there, so it borrows the button's shape. */
a.btn {
  display: inline-flex;
  align-items: center;
  height: 42px;
  padding: 0 24px;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
  transition: background 140ms, box-shadow 140ms, color 140ms, border-color 140ms;
}
a.btn:hover { background: var(--accent-hover); box-shadow: 0 6px 22px rgba(78, 216, 160, 0.22); }
a.btn.ghost { background: transparent; color: var(--primary); border: 1px solid var(--tertiary); }
a.btn.ghost:hover { background: var(--hover); color: var(--accent); border-color: var(--accent); box-shadow: none; }

/* Jobs you do a few times a year — make a folder, rename one — used to be
   panels sitting open on the page forever. <details> costs a click and no
   layout, and works with the markup alone if the browser has no JS. */
details.disclose { position: relative; }
details.disclose > summary {
  display: inline-flex;
  align-items: center;
  height: 42px;
  padding: 0 var(--space-3);
  border: 1px solid var(--tertiary);
  border-radius: var(--radius);
  color: var(--primary);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  list-style: none;             /* the default triangle, hidden two ways */
  transition: background 140ms, color 140ms, border-color 140ms;
}
details.disclose > summary::-webkit-details-marker { display: none; }
details.disclose > summary:hover { background: var(--hover); color: var(--accent); border-color: var(--accent); }
details.disclose[open] > summary { background: var(--hover); border-color: var(--accent); color: var(--accent); }
/* Floated over the page: opening it must not push the file table down. */
.disclose-body {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 5;
  width: 340px;
  padding: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--tertiary);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
  text-align: left;
}
.disclose-body button { width: 100%; }
/* Too narrow to float 340px against the right edge — let it push instead. */
@media (max-width: 700px) {
  details.disclose { width: 100%; }
  details.disclose > summary { width: 100%; justify-content: center; }
  .disclose-body { position: static; width: auto; margin-top: var(--space-2); box-shadow: none; }
}

/* Search */
.search-box { margin-bottom: var(--space-6); }
/* Wraps, because two buttons plus the field do not fit a phone on one line. */
.search-box form { display: flex; gap: var(--space-2); flex-wrap: wrap; }
/* Wraps the input so a search glyph can sit inside it on the left. The basis
   keeps the field on its own line before it is squeezed to nothing. */
.search-field { position: relative; flex: 1 1 280px; }
.search-field .search-icon {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  width: 19px;
  height: 19px;
  color: var(--muted);
  pointer-events: none;
}
.search-box input {
  margin: 0;
  width: 100%;
  height: 54px;
  padding-left: 46px;
  border-radius: 12px;
  font-size: 16px;
}
/* No icon in front (fallback) — reclaim the left padding. */
.search-box form > input { padding-left: 16px; }
.search-box button { height: 54px; min-width: 128px; padding: 0 var(--space-4); font-size: 16px; border-radius: 12px; }

.result-head {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
}
.result-head a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 16px;
  font-weight: 600;
  color: var(--primary);
  text-decoration: none;
}
.result-head a .file-icon { width: 17px; height: 17px; color: var(--accent); flex: 0 0 17px; }
.result-head a:hover { color: var(--accent); }
.snippet {
  margin: var(--space-3) 0 0;
  color: #d7d9ce;
  font-weight: 400;
  font-size: 14.5px;
  line-height: 1.68;
}
/* RAG answer — keep the model's line breaks, sit the citations apart from the prose. */
.card.answer { border-left: 3px solid var(--accent); }
.answer-text {
  margin: 0;
  color: var(--primary);
  line-height: 1.7;
  white-space: pre-wrap;
}
.cite {
  font-weight: 700;
  color: var(--amber);
}

/* The hit is lit in amber — lamplight falls on the match. */
mark {
  background: transparent;
  color: var(--amber);
  font-weight: 600;
  border-bottom: 2px solid var(--amber-line);
  text-shadow: 0 0 14px var(--amber-glow);
  padding-bottom: 1px;
}

/* Chips — a rounded pill with a colour dot. Departments read at a glance. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 10px;
  border: 1px solid var(--tertiary);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 6px; }
.badge.page { color: var(--amber); border-color: rgba(232, 181, 77, 0.35); }
.badge.dept { color: #7fb6e6; border-color: rgba(127, 182, 230, 0.32); background: rgba(127, 182, 230, 0.08); }
.badge.shared { color: var(--success); border-color: rgba(142, 214, 166, 0.30); background: rgba(142, 214, 166, 0.07); }
.badge.error-badge { color: var(--error); border-color: rgba(240, 132, 111, 0.45); background: rgba(240, 132, 111, 0.08); }

.banner {
  padding: var(--space-3) var(--space-3);
  margin-bottom: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: var(--radius);
  font-size: 14px;
  font-weight: 400;
}
.banner.error { border-left-color: var(--error); color: var(--error); }
.banner.warn { border-left-color: var(--warning); color: var(--warning); }
.banner.ok { border-left-color: var(--success); color: var(--success); }

.muted { color: var(--muted); }
.small { font-size: 12.5px; line-height: 1.5; }

/* Lists */
/* A wide table scrolls inside this, so the page itself never scrolls sideways. */
.table-wrap { overflow-x: auto; margin-bottom: var(--space-3); border-radius: var(--radius-lg); border: 1px solid var(--border); }
/* Apple_Developer_Enrollment_Guide.pdf is one word to a browser: nowhere to
   break it, so unbroken it sets the width of the table and everything else
   gets pushed off the page. A filename may break anywhere it has to. The
   badges and dates say nowrap for themselves and are not affected. */
.table-wrap td { overflow-wrap: anywhere; }
table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--surface);
}
th {
  text-align: left;
  padding: var(--space-3);
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--muted);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
td {
  text-align: left;
  padding: var(--space-3);
  border-bottom: 1px solid var(--border);
  font-size: 14px;
  font-weight: 400;
  vertical-align: top;
}
tr:last-child td { border-bottom: 0; }
tbody tr:hover td, table tr:hover td { background: var(--hover); }
th:first-child, td:first-child { padding-left: var(--space-3); }
td a { color: var(--primary); text-decoration: none; font-weight: 500; }
td a:hover { color: var(--accent); }
/* Tabular figures line up down the column; a date is not worth three lines. */
.num { font-family: var(--mono); font-size: 13px; color: var(--muted); white-space: nowrap; }

ul { padding-left: var(--space-3); font-size: 14px; }

.admin-grid { display: grid; grid-template-columns: 1fr 1.6fr; gap: var(--space-4); }
@media (max-width: 700px) { .admin-grid { grid-template-columns: 1fr; } }
.upload-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
@media (max-width: 700px) { .upload-grid { grid-template-columns: 1fr; } }

/* The library: the folders beside the files, not stacked on top of them. As a
   grid of cards the folders pushed the table off the fold and made moving from
   one folder to another a trip back through "All files"; as a rail they cost a
   fixed 200px and every folder is one click from every other. */
.library {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}
/* min-width:0 again — without it the table's own width sets the column. */
.lib-main { min-width: 0; }
.lib-rail {
  position: sticky;
  top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.rail-label {
  margin: var(--space-3) 0 var(--space-1);
  padding: 0 10px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.rail-label:first-child { margin-top: 0; }
.rail-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  color: var(--muted);
  text-decoration: none;
  font-size: 13.5px;
  transition: background 140ms, color 140ms;
}
.rail-item .ic { flex: 0 0 16px; width: 16px; height: 16px; opacity: 0.9; }
.rail-item .rail-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail-item:hover { background: var(--hover); color: var(--primary); }
.rail-item.active { background: var(--accent-wash); color: var(--primary); }
.rail-item.active .ic { color: var(--accent); }
/* The department badge will not fit in 200px — the same colour as a dot will. */
.rail-dot { flex: 0 0 6px; width: 6px; height: 6px; margin-left: auto; border-radius: 50%; }
.rail-dot.dept { background: #7fb6e6; }
.rail-dot.shared { background: var(--success); }

/* A file's page index uses the same rail, and a long file has hundreds of
   entries — it scrolls in place rather than running off the bottom. */
.lib-rail.scroll { max-height: calc(100vh - var(--space-6)); overflow-y: auto; }
.lib-rail .find input { height: 36px; margin: 0 0 var(--space-2); font-size: 13px; }

/* The rail costs a fixed 232px (200 + gap) out of a page that has already given
   232px to the nav. Below 1340px what is left cannot hold the file table, and
   the table was the thing you came for — so the rail lies down and scrolls. */
@media (max-width: 1340px) {
  .library { grid-template-columns: minmax(0, 1fr); }
  /* Same bargain, smaller: the margins of a reading page are worth less than
     the last column of the table. Only the library pages are this hungry. */
  body.app main.wide { padding-left: var(--space-4); padding-right: var(--space-4); }
  /* 16px of air on each side of six columns is 192px — most of a column. The
     table reads a little denser and stays whole, which is the better trade. */
  main.wide th:not(.pick), main.wide td:not(.pick) { padding-left: 12px; padding-right: 12px; }
  main.wide th.pick, main.wide td.pick { padding-left: 12px; }
  .lib-rail {
    position: static;
    flex-direction: row;
    gap: var(--space-1);
    overflow-x: auto;
    padding-bottom: var(--space-2);
    margin-bottom: var(--space-2);
    border-bottom: 1px solid var(--border);
  }
  .lib-rail .rail-label { display: none; }
  .rail-item { flex: 0 0 auto; }
  .rail-dot { margin-left: 2px; }
  /* Lying down, it scrolls sideways — a height cap would clip it instead. */
  .lib-rail.scroll { max-height: none; overflow-y: visible; }
  .lib-rail .find { flex: 0 0 180px; }
  .lib-rail .find input { margin: 0; }
}

/* One page of a document, read in place. pre-wrap keeps the line breaks the
   extractor found; without it a page of a PDF collapses into one paragraph. */
.crumb { margin: 0 0 var(--space-3); }
.page-text {
  margin: var(--space-3) 0 0;
  color: #d7d9ce;
  font-size: 14.5px;
  line-height: 1.75;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Covers the page while an upload is in flight: says what is happening, and
   blocks a second submit by sitting on top of the form. No spinner — the clock
   in .busy-clock is the thing that proves it has not hung. */
.busy {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: rgba(10, 14, 12, 0.92);
}
.busy[hidden] { display: none; }
.busy-inner {
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-lift);
}
.busy-heading { margin: 0 0 var(--space-3); font-size: 20px; font-weight: 600; line-height: 1.3; }
.busy-note { margin: 0 0 var(--space-4); color: var(--muted); font-size: 14px; font-weight: 400; line-height: 1.6; }
.busy-clock { margin: 0; }

form.row { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
form.row input, form.row select { margin: 0; width: auto; flex: 1; min-width: 140px; }
/* Pinned, because a table column is sized from the select's longest option and
   "Business Development department" would otherwise set it. */
td form.row select { flex: 0 0 160px; width: 160px; min-width: 0; }
/* `input, select` sets display:block, which outranks the hidden attribute — so
   without this the Move dropdown refuses to hide. */
select[hidden] { display: none; }
/* Where the file lives, hung under its name instead of costing a column. */
.file-where { margin-top: var(--space-2); }
/* Move and Delete side by side: a row is one control tall, not three stacked.
   The flex box is a wrapper inside the cell, never the cell itself — a td set
   to display:flex stops being a table cell, and its border then draws where
   its own content ends rather than at the foot of the row, which put a kink in
   every line down the right of the table. */
td.actions .row-actions { display: flex; gap: var(--space-2); align-items: center; }
td form.row { flex-wrap: nowrap; }
/* The last 150px, and the last thing to give: past here the two buttons stack
   so the table still ends where the page ends. Kept to this width so that a
   normal window never pays for it. */
@media (max-width: 1000px) { td.actions .row-actions { flex-wrap: wrap; } }

/* Ticking files: the column is a box wide, not a text field wide — the global
   `input` rule would otherwise make each one 42px tall and fill the cell. */
th.pick, td.pick { width: 1%; padding-right: 0; }
th.pick input, td.pick input {
  width: 18px;
  height: 18px;
  margin: 0;
  padding: 0;
  accent-color: var(--accent);
}
/* The cells are top-aligned, so nudge the box onto the first line of the name. */
td.pick input { margin-top: 3px; }

/* What you do with the ticked files, above the table rather than below it —
   you decide to delete while looking at the list, not after scrolling past it. */
.bulk-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  font-size: 14px;
}
.bulk-bar[hidden] { display: none; }
