:root {
  --bg: #f5f6f8;
  --panel: #ffffff;
  --ink: #1f2430;
  --muted: #6b7280;
  --line: #e6e8ec;
  --brand: #ea580c;        /* orange */
  --brand-dark: #c2410c;
  --brand-2: #f59e0b;      /* amber, for gradients */
  --brand-soft: #fdba74;
  --brand-tint: #fff7ed;
  --focus: #2563eb;
  --danger: #dc2626;       /* error toasts stay red */
  --urgent: #f97316;       /* priority: orange */
  --urgent-ink: #ffffff;
  --semi: #facc15;         /* priority: yellow */
  --semi-ink: #422006;
  --normal: #16a34a;       /* priority: green */
  --normal-ink: #ffffff;
  font-synthesis: none;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 14px/1.5 -apple-system, "Segoe UI", "Microsoft YaHei", Roboto, sans-serif;
}

button {
  font: inherit;
  cursor: pointer;
  border: 1px solid var(--line);
  background: #fff;
  border-radius: 7px;
  padding: 7px 13px;
  transition: background .12s, border-color .12s, transform .12s;
}
button:hover { background: #f3f4f6; }
button.primary {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
button.primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); }
button.ghost { background: transparent; border-color: transparent; color: var(--muted); }
button:disabled { opacity: .5; cursor: not-allowed; }

input, select, textarea {
  font: inherit;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #fff;
  color: var(--ink);
  width: 100%;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--focus); outline-offset: -1px; }
textarea { min-height: 62px; resize: vertical; }
label { display: block; font-size: 12px; color: var(--muted); margin: 10px 0 4px; }
label.chk { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); cursor: pointer; }
label.chk input { width: auto; margin: 0; }

/* Show/hide toggle on every password field (wirePasswordToggles in app.js) —
   browsers' own reveal icon isn't guaranteed to show for every user, so the
   portal supplies its own. */
.pwWrap { position: relative; }
.pwWrap input { padding-right: 38px; }
.pwToggle {
  position: absolute; top: 50%; right: 4px; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; border: none; background: transparent;
  color: var(--muted); border-radius: 6px;
}
.pwToggle:hover { color: var(--brand-dark); background: var(--brand-tint); }
.pwToggle svg { display: block; }
/* Edge/IE draw their own built-in reveal icon in the same spot — without
   this it'd sit right on top of ours. */
input[type="password"]::-ms-reveal, input[type="password"]::-ms-clear { display: none; }

/* ---------- header ---------- */
header {
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  padding: 12px 20px;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
header h1 {
  font-size: 16px;
  margin: 0;
  color: var(--brand);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 9px;
  letter-spacing: .2px;
}
header h1::before {
  content: "\25B6";
  font-size: 10px;
  color: #fff;
  background: var(--brand);
  width: 22px;
  height: 22px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-left: 2px;
}
/* Global "something's in flight" indicator (api() in app.js) — shown while
   waiting on a network response so a refresh or an action-then-confirmation
   gap never looks like the page has simply stopped responding. Fixed dead
   center of the viewport, above everything (including modals), and never
   blocks clicks underneath it. */
.busySpin {
  position: fixed; inset: 0; z-index: 999;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.busySpin[hidden] { display: none; }
.busySpin::after {
  content: ""; width: 40px; height: 40px;
  border: 4px solid var(--line); border-top-color: var(--brand);
  border-radius: 50%;
  animation: busySpin .7s linear infinite;
}
@keyframes busySpin { to { transform: rotate(360deg); } }
header .who { margin-left: auto; display: flex; gap: 8px; align-items: center; }
header .who select { width: auto; min-width: 120px; }
header .hint { font-size: 12px; color: var(--muted); width: 100%; }

nav {
  display: flex;
  gap: 4px;
  padding: 10px 20px 0;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
nav button {
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  background: none;
  color: var(--muted);
  padding: 8px 12px;
}
nav button:hover { background: none; color: var(--ink); }
nav button.active { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }
nav .badge {
  background: var(--brand);
  color: #fff;
  border-radius: 999px;
  font-size: 11px;
  padding: 1px 7px;
  margin-left: 5px;
}

main { padding: 22px 20px 48px; max-width: 1120px; margin: 0 auto; }

/* ---------- homepage ---------- */
.hero {
  position: relative;
  overflow: hidden;
  background: linear-gradient(135deg, var(--brand) 0%, var(--brand-2) 100%);
  color: #fff;
  border-radius: 16px;
  padding: 26px 28px;
  margin-bottom: 20px;
  box-shadow: 0 10px 28px -12px rgba(234, 88, 12, .45);
}
.hero-badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  background: rgba(255, 255, 255, .18);
  border: 1px solid rgba(255, 255, 255, .28);
  padding: 3px 10px;
  border-radius: 999px;
  margin-bottom: 12px;
}
.hero h2 { margin: 0 0 6px; font-size: 24px; }
.hero p { margin: 0; font-size: 14px; opacity: .95; }
.hero .hero-sub { opacity: .82; margin-top: 4px; }
.hero .cta { margin-top: 18px; display: flex; gap: 10px; flex-wrap: wrap; }
.hero .cta button {
  background: rgba(255, 255, 255, .16);
  border-color: rgba(255, 255, 255, .35);
  color: #fff;
}
.hero .cta button:hover { background: rgba(255, 255, 255, .26); }
.hero .cta button.solid {
  background: #fff;
  border-color: #fff;
  color: var(--brand-dark);
  font-weight: 600;
}
.hero .cta button.solid:hover { background: #fff5ee; }
.hero-date { margin-top: 14px; font-size: 12px; opacity: .78; }

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-bottom: 20px;
}
.stat {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 15px 16px;
}
.stat .n { font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.1; }
.stat .k { font-size: 12px; color: var(--muted); margin-top: 3px; }
.stat.ok .n { color: var(--normal); }
.stat.urgent .n { color: var(--brand-dark); }

.section {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px 20px;
  margin-bottom: 18px;
}
.section > h3 {
  margin: 0 0 14px;
  font-size: 14px;
  display: flex;
  align-items: center;
}
.section > h3 .link {
  margin-left: auto;
  font-size: 12px;
  font-weight: 500;
  color: var(--brand);
  cursor: pointer;
}
.section > h3 .link:hover { color: var(--brand-dark); }

.pipeline {
  display: flex;
  align-items: stretch;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 6px;
}
.pstage {
  flex: 0 0 auto;
  min-width: 108px;
  text-align: left;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  background: #fff;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pstage:hover { background: var(--brand-tint); border-color: var(--brand-soft); transform: translateY(-1px); }
.pstage .bar { height: 3px; border-radius: 2px; background: var(--brand-soft); margin-bottom: 8px; }
.pstage.published .bar { background: var(--normal); }
.pstage .pn { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pstage .pl { font-size: 11px; color: var(--muted); white-space: nowrap; }
.pstage.zero { opacity: .45; }
.pstage.zero:hover { opacity: .8; }
.parrow { flex: 0 0 auto; align-self: center; color: #cfd3da; font-size: 13px; }

.feed { list-style: none; margin: 0; padding: 0; }
.feed li {
  display: flex;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
  cursor: pointer;
}
.feed li:last-child { border-bottom: none; }
.feed li:hover { background: #fbfbfd; }
.feed .fid { color: var(--brand); font-weight: 600; font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.feed .fmain { flex: 1; }
.feed .ft { display: block; color: var(--muted); font-size: 11px; margin-top: 1px; }

/* ---------- schedule board (Maree only) ---------- */
.schedbar {
  display: flex;
  align-items: center;
  gap: 12px 16px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.schedbar .axisrow {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  flex: 0 0 auto;
}
.schedbar .axisbtn {
  border: none;
  border-radius: 0;
  border-left: 1px solid var(--line);
  background: #fff;
  color: var(--muted);
  padding: 6px 12px;
  font-size: 13px;
}
.schedbar .axisbtn:first-child { border-left: none; }
.schedbar .axisbtn:hover { background: #f6f7f9; }
.schedbar .axisbtn.on { background: var(--brand); color: #fff; }
.schedbar .snow {
  font-size: 16px;
  font-weight: 700;
  color: var(--brand-dark);
  font-variant-numeric: tabular-nums;
}
.schedbar .snote { font-size: 12px; color: var(--muted); flex: 1 1 240px; }

.section > h3 .onnow {
  font-size: 15px;
  font-weight: 600;
  color: var(--normal);
  background: #f0fdf4;
  border: 1px solid #bbf7d0;
  border-radius: 999px;
  padding: 2px 11px;
  margin-left: 8px;
}

/* The schedule breaks out of the normal column so each day is wide enough
   to read names; blocks wrap the name rather than truncate it. */
main:has(.calwrap) { max-width: 1720px; }
.calwrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; background: #fff; touch-action: pan-x pan-y; }
.calwrap[data-cal] { cursor: grab; }
.calwrap[data-cal].dragging { cursor: grabbing; user-select: none; }
.calwrap[data-cal].dragging .cblk { pointer-events: none; }
.cal { min-width: 1280px; }
.calhead {
  display: grid;
  grid-template-columns: 40px repeat(7, 1fr);
  border-bottom: 2px solid #d0d3d9;
  background: #fff;
}
.calhead .cdh {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 6px 0 7px;
  border-left: 2px solid #d8dbe0;
  border-top: 4px solid transparent;   /* thick colour key per day */
}
.calhead .cdh .cdn { font-size: 13px; font-weight: 700; color: var(--ink); }
.calhead .cdh .cdd { font-size: 13px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
/* per-day colour: strong on the header, light wash on the column body */
.calhead .cdh.d0 { background: #d7e6fb; border-top-color: #3b82f6; }
.calhead .cdh.d1 { background: #d5ecdc; border-top-color: #22c55e; }
.calhead .cdh.d2 { background: #f8e6c4; border-top-color: #f59e0b; }
.calhead .cdh.d3 { background: #e2d6f5; border-top-color: #8b5cf6; }
.calhead .cdh.d4 { background: #cfeaea; border-top-color: #14b8a6; }
.calhead .cdh.d5 { background: #f7d3de; border-top-color: #ec4899; }
.calhead .cdh.d6 { background: #f7ddc4; border-top-color: #f97316; }
.calhead .cdh.wknd .cdn { color: #b91c1c; }
.calhead .cdh.today { background: var(--brand); border-top-color: var(--brand-dark); }
.calhead .cdh.today .cdn, .calhead .cdh.today .cdd { color: #fff; }

.calbody { display: grid; grid-template-columns: 40px repeat(7, 1fr); }
.caxis { position: relative; }
.caxis .hrl {
  position: absolute;
  right: 4px;
  font-size: 10px;
  color: var(--muted);
  transform: translateY(-50%);
  font-variant-numeric: tabular-nums;
}
.cday {
  position: relative;
  border-left: 2px solid #d8dbe0;
  background-image: repeating-linear-gradient(
    to bottom, transparent 0, transparent 59px, rgba(0,0,0,.07) 59px, rgba(0,0,0,.07) 60px);
}
/* per-day wash on the column body (clearly visible, still lets blocks show) */
.cday.d0 { background-color: #e6eefb; }
.cday.d1 { background-color: #e4f2e9; }
.cday.d2 { background-color: #fbf0d9; }
.cday.d3 { background-color: #eee6fa; }
.cday.d4 { background-color: #ddf1f1; }
.cday.d5 { background-color: #fae2ea; }
.cday.d6 { background-color: #faead7; }
.cday.today {
  background-color: #ffe6cc;
  box-shadow: inset 3px 0 0 var(--brand), inset -3px 0 0 var(--brand);
}
.cblk {
  position: absolute;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.2;
  padding: 2px 4px;
  overflow: hidden;
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
  background: #fed7aa;
  border: 1px solid #ea580c;
  color: #7c2d12;
  cursor: default;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .16);
}
.cblk.g-F { background: #fbcfe8; border-color: #db2777; color: #9d174d; }
.cblk.g-M { background: #bfdbfe; border-color: #2563eb; color: #1e40af; }
.cblk { cursor: default; }
.cblk.editable { cursor: pointer; }
.cblk.editable:hover { filter: brightness(.95); box-shadow: 0 0 0 2px var(--brand); z-index: 2; }
.nowline {
  position: absolute; left: 0; right: 0; height: 2px;
  background: var(--brand); z-index: 3;
}
/* On the roster but with no hours filled in yet — no block on the calendar
   above to click, so this is the only entry point to their schedule editor. */
.unschedRow {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: 10px; font-size: 14px;
}
.unschedLbl { color: var(--ink); font-weight: 700; }
.unschedChip {
  display: inline-block; padding: 4px 10px; border-radius: 12px;
  background: var(--brand-tint); border: 1.5px dashed var(--brand);
  font-size: 13px; font-weight: 700; color: var(--brand-dark); cursor: default;
}
.unschedChip.editable { cursor: pointer; }
.unschedChip.editable:hover { border-style: solid; background: var(--brand-soft); color: #7c2d12; }
.nowline::before {
  content: ""; position: absolute; left: -3px; top: -3px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--brand);
}

.muted-note { color: var(--muted); font-size: 13px; padding: 6px 0; }

/* ---------- job offers (accept / claim) ---------- */
.card.offered { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand-soft); }
.tagoffer {
  background: var(--brand); color: #fff; border-radius: 999px;
  padding: 1px 8px; font-weight: 700; font-size: 11px;
}
.offerbox {
  background: var(--brand-tint);
  border: 1px solid var(--brand-soft);
  border-radius: 8px;
  padding: 12px;
}
.offerbox p { margin: 0 0 10px; font-size: 13px; color: var(--brand-dark); }

/* ---------- schedule editor (inside modal) ---------- */
.swmeta { font-size: 12px; color: var(--muted); margin: 4px 0 14px; }
.swmeta .onnow { margin-left: 8px; }
.swrow {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.swrow .swday { width: 96px; flex: 0 0 auto; }
.swrow .swstart, .swrow .swend { width: 120px; flex: 0 0 auto; }
.swrow .swdash { color: var(--muted); }
.swrow .swdel { padding: 4px 8px; color: var(--urgent); flex: 0 0 auto; margin-left: auto; }
#swAdd { margin-top: 4px; color: var(--brand); }
.swhint { font-size: 11px; color: var(--muted); margin: 10px 0 0; }

/* ---------- filters + table ---------- */
.filters { display: flex; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; align-items: flex-start; }
.filters > * { width: auto; }
.filters input { min-width: 220px; }
/* An active (non-default) filter is highlighted so it's obvious what the
   list is scoped to. */
.filters .filter-on,
.filters .msel.filter-on .mselbtn {
  border-color: var(--brand);
  background: var(--brand-tint);
  color: var(--brand-dark);
  font-weight: 600;
}
/* multi-select filter: button + checkbox panel that stays open */
.msel { position: relative; }
.msel .mselbtn {
  display: inline-flex; align-items: center; gap: 8px; min-width: 116px; max-width: 340px;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--panel); color: var(--ink); font: inherit; cursor: pointer;
  white-space: nowrap; overflow: hidden;
}
/* down-pointing chevron drawn as an outline arrow (no glyph) */
.msel .mselbtn .mselcar {
  margin-left: auto; flex: none;
  width: 7px; height: 7px; margin-top: -3px;
  border: solid var(--brand); border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.msel .mselbtn:hover .mselcar { border-color: var(--brand-dark); }
.msel .mselopt.mselall { border-bottom: 1px solid var(--line); border-radius: 0; margin-bottom: 2px; font-weight: 600; }
.msel .mselpanel {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 30;
  min-width: 200px; max-height: 320px; overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.14); padding: 4px;
}
.msel .mselopt {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 6px; font-size: 13px; cursor: pointer; white-space: nowrap;
}
.msel .mselopt:hover { background: var(--brand-tint); }
.msel .mselopt input { width: auto; margin: 0; flex: none; }

/* The All-articles view breaks out of the normal 1120px column. Columns are
   user-resizable; the table scrolls sideways and freezes the first four
   columns (through Status). */
main:has(.tablewrap) { max-width: 1840px; }
/* Scroll box: both scrollbars stay pinned to its edges, so the horizontal
   bar is always reachable no matter how far down the list you are. */
.tablewrap { overflow: auto; max-height: calc(100vh - 232px); border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.tablewrap table { table-layout: fixed; width: max-content; border-collapse: separate; border-spacing: 0; background: var(--panel); overflow: visible; border-radius: 0; }
.tablewrap th, .tablewrap td {
  padding: 2px 10px; white-space: normal; word-break: break-word; overflow-wrap: anywhere;
  border-bottom: 1px solid var(--line); text-align: left; color: #10121a;
}
.tablewrap td { font-size: 13px; }
/* Dropdown + status icon(s) on one line, never wrapping underneath — keeps
   every row's height the same regardless of whether a cell has an
   "awaiting Maree" triangle or a pending-accept hourglass next to it. */
.tablewrap td .cellRow { display: flex; align-items: center; gap: 4px; flex-wrap: nowrap; white-space: nowrap; }
.tablewrap td .cellRow select { min-width: 0; flex: 1 1 auto; }
.tablewrap td .cellRow .skipwarn { flex: 0 0 auto; }
/* header row freezes on top while scrolling down */
.tablewrap thead th { position: sticky; top: 0; z-index: 5; background: #fafafa; color: var(--ink); font-weight: 700; font-size: 14px; border-bottom: 2px solid #d0d3d9; }
.tablewrap tbody tr:hover td { background: #fbfbfd; }
/* frozen columns (through Status) — left offset set inline by applyColLayout */
.tablewrap .stk { position: sticky; background: var(--panel); z-index: 2; }
.tablewrap thead .stk { background: #fafafa; z-index: 6; }
.tablewrap tbody tr:hover .stk { background: #fbfbfd; }
.tablewrap .stk.stk-edge { box-shadow: 7px 0 7px -5px rgba(0,0,0,.16); }
/* drag handle on a header's right edge */
.tablewrap .colrz { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: col-resize; z-index: 6; touch-action: none; }
.tablewrap .colrz:hover { background: var(--brand); opacity: .35; }
/* Chinese + English title: always one line, ellipsis on overflow (hover shows the full text) */
.tablewrap td.title, .tablewrap td.titleen { overflow: hidden; }
.tablewrap td.title .titletxt, .tablewrap td.titleen .titletxt {
  display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
}
/* Click a truncated Chinese title to show it in full, wrapped across as many
   lines as it needs (app.js's wireMain()) — the cell's own clipping has to
   relax too, or the span's overflow:visible does nothing. */
.tablewrap td.title .titletxt.expanded, .tablewrap td.titleen .titletxt.expanded {
  white-space: normal; overflow: visible; text-overflow: clip; word-break: break-word;
}
.tablewrap td.title:has(.titletxt.expanded), .tablewrap td.titleen:has(.titletxt.expanded) {
  overflow: visible;
}
/* Voice column: artist names coloured by the paragraph colour they took. */
.tablewrap td.voice .vc { font-weight: 400; }
.skipwarn { color: var(--danger); font-weight: 700; cursor: help; }
.tablewrap td.voice .vc-blue { color: #1d4ed8; }
.tablewrap td.voice .vc-red { color: #b91c1c; }
.tablewrap td.voice .vc-black { color: #1f2937; }
.tablewrap td.date { font-variant-numeric: tabular-nums; white-space: nowrap; color: #4b5563; }
.tablewrap td.num { font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.tablewrap input.cellInput { width: 100%; font: inherit; font-size: 13px; padding: 3px 5px; border: 1px solid var(--line); border-radius: 5px; background: var(--panel); color: var(--ink); }
.tablewrap input.cellInput:hover, .tablewrap input.cellInput:focus { border-color: var(--brand); }
.tablewrap td.id { font-variant-numeric: tabular-nums; color: #4b5563; }
.tablewrap .ytlink { color: var(--brand-dark); white-space: nowrap; cursor: pointer; }
.tablewrap a.ytlink { text-decoration: underline; }
.tablewrap td.yt[data-yt] { cursor: pointer; }
.tablewrap td.yt .ytadd { color: #4b5563; font-weight: 700; }
table { width: 100%; border-collapse: collapse; background: var(--panel); border-radius: 10px; overflow: hidden; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); font-size: 13px; }
th { background: #fafafa; color: var(--muted); font-weight: 600; }
p.hint { font-size: 12px; color: var(--muted); margin: -4px 0 12px; }
.prioWrap { position: relative; display: inline-block; }
.prioWrap::after { content: "▾"; position: absolute; right: 10px; top: 50%; transform: translateY(-50%); font-size: 9px; pointer-events: none; color: inherit; opacity: .8; }
.prioWrap.Urgent { color: var(--urgent-ink); }
.prioWrap.Semi-Urgent { color: var(--semi-ink); }
.prioWrap.Normal { color: var(--normal-ink); }
.prioWrap select.prioSel { -webkit-appearance: none; appearance: none; border: 0; border-radius: 999px; padding: 3px 26px 3px 12px; min-width: 104px; white-space: nowrap; text-overflow: clip; font-size: 12px; font-weight: 600; line-height: 1; cursor: pointer; color: inherit; }
.prioWrap.Urgent select.prioSel { background: var(--urgent); }
.prioWrap.Semi-Urgent select.prioSel { background: var(--semi); }
.prioWrap.Normal select.prioSel { background: var(--normal); }
.prioWrap select.prioSel option { background: var(--panel); color: var(--ink); }
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--ink); }
th.sorted { color: var(--brand); }
.sortIcon { margin-left: 4px; font-size: 13px; line-height: 1; display: inline-block; vertical-align: -2px; opacity: .3; }
th.sortable:hover .sortIcon { opacity: 1; color: var(--brand); }
th.sorted .sortIcon { opacity: 1; color: var(--brand); }
tbody tr { cursor: pointer; }
tbody tr:hover { background: #fbfbfd; }
tbody tr:last-child td { border-bottom: none; }
td.id { font-variant-numeric: tabular-nums; color: var(--muted); }
td.date { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--muted); }

/* ---------- badges ---------- */
.pill {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
}
.pill.Urgent { background: var(--urgent); color: var(--urgent-ink); }
.pill.Semi-Urgent { background: var(--semi); color: var(--semi-ink); }
.pill.Normal { background: var(--normal); color: var(--normal-ink); }

.stage {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 6px;
  font-size: 12px;
  background: #eef2ff;
  color: #3730a3;
  white-space: nowrap;
}
.stage.published { background: #dcfce7; color: #166534; }
.stage.review_amy, .stage.review_maree, .stage.review_video { background: #fef3c7; color: #92400e; }

/* ---------- cards ---------- */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
.cards.mini { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; }
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px;
}
.cards.mini .card { padding: 12px; cursor: pointer; }
.cards.mini .card:hover { border-color: var(--brand-soft); background: var(--brand-tint); }
/* Separates "my queue" cards already in progress from the rest (app.js's
   queueItemInProgress) — spans every column of the cards grid. */
.queueDivider {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 10px;
  margin: 6px 0; font-size: 12px; font-weight: 700; color: var(--brand-dark);
  text-transform: uppercase; letter-spacing: .04em;
}
.queueDivider::before, .queueDivider::after { content: ""; flex: 1; height: 2px; background: var(--brand-soft); }
.card h3 { margin: 0 0 6px; font-size: 14px; }
.card .meta { font-size: 12px; color: var(--muted); display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.cards.mini .card .meta { margin-bottom: 0; }
.card .row { display: flex; gap: 8px; flex-wrap: wrap; }

.empty { color: var(--muted); text-align: center; padding: 60px 0; }

/* ---------- modal ---------- */
.overlay {
  position: fixed; inset: 0;
  z-index: 50;   /* above the All-articles sticky header / frozen columns */
  background: rgba(15, 18, 26, .45);
  display: flex; justify-content: center; align-items: flex-start;
  padding: 40px 16px;
  overflow-y: auto;
}
.overlay[hidden] { display: none; }
.modal {
  background: var(--panel);
  border-radius: 12px;
  width: 100%;
  max-width: 760px;
  padding: 22px;
}
.modal header { background: none; border: none; padding: 0; margin-bottom: 12px; align-items: flex-start; }
.modal h2 { font-size: 16px; margin: 0; }
.modal .close { margin-left: auto; flex: none; }
/* Long/multi-line titles collapse to one line by default — click to expand
   (public/app.js's openDetail()). min-width:0 on the wrap lets it actually
   shrink inside the header's flex row instead of pushing the close button. */
.modalTitleWrap { min-width: 0; flex: 1; }
.modal h2.modalTitle {
  cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.modal h2.modalTitle.expanded { white-space: normal; overflow: visible; text-overflow: clip; }

/* success popup after an action */
#okOverlay { z-index: 60; align-items: center; }
.okModal { max-width: 440px; }
.okHead { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.okHead h2 { font-size: 17px; }
.okTick {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--normal); color: #fff; font-size: 15px; font-weight: 700;
  display: grid; place-items: center;
}
.okNext { margin-top: 12px; padding: 12px 14px; background: var(--brand-tint); border: 1px solid var(--brand-soft); border-radius: 9px; }
.okNextLbl { display: block; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--brand-dark); margin-bottom: 4px; }
.okNext p { margin: 0; font-size: 13px; line-height: 1.5; }
.okStage { margin: 10px 0 0; font-size: 12px; color: var(--muted); }
.okLog { margin: 8px 0 0; padding-left: 18px; }
.okLog li { font-size: 12px; line-height: 1.45; color: var(--muted); margin: 2px 0; }
.okActions { margin-top: 16px; text-align: right; }

/* Two collapsible sections in the detail popup — "topic info" (title/plan/
   source/notes, entered at creation) vs. "other details" (everything a
   writer doesn't need day to day). Which one opens by default depends on
   role (app.js's openDetail()); either can still be expanded by anyone. */
.infoDetails { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.infoDetails summary {
  cursor: pointer; font-size: 13px; font-weight: 600; color: var(--muted);
  list-style: none; display: flex; align-items: center; gap: 6px;
}
.infoDetails summary::-webkit-details-marker { display: none; }
.infoDetails summary::before { content: "▸"; font-size: 22px; line-height: 1; color: var(--brand); }
.infoDetails[open] > summary::before { content: "▾"; }
.infoDetails[open] > summary { margin-bottom: 4px; }

.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 18px; margin: 12px 0; }
.gridCol { min-width: 0; }
.field { font-size: 13px; padding: 6px 0; border-bottom: 1px dashed var(--line); }
/* Direct child only — a nested span (e.g. segmentsBlock's colour tags,
   .ctag) must keep its own bold colour, not inherit this label styling. */
.field > span { color: var(--muted); display: block; font-size: 12px; font-weight: 700; }
.field a { color: var(--focus); word-break: break-all; }
.field .segLink { cursor: pointer; }
.field .segLinkGo { color: var(--focus); text-decoration: underline; word-break: break-all; }
.field .segLinkAdd { color: var(--muted); font-weight: 700; }
.field input.segLinkEdit { display: block; width: 100%; margin-top: 4px; font: inherit; font-size: 12px; padding: 4px 6px; border: 1px solid var(--line); border-radius: 5px; background: var(--panel); color: var(--ink); }
/* English title / planned / actual publish date — always-editable boxes,
   same treatment as the All-articles list's own inline cells (app.js's
   topicInfoInput wiring, reused here for a plain <input> too). */
.field input.topicInfoInput { display: block; width: 100%; margin-top: 2px; font: inherit; font-size: 12px; padding: 4px 6px; border: 1px solid var(--line); border-radius: 5px; background: var(--panel); color: var(--ink); }
.field input.segLinkEdit:hover, .field input.segLinkEdit:focus,
.field .topicInfoInput:hover, .field .topicInfoInput:focus { border-color: var(--brand); outline: none; }

.tcPanel { margin: 16px 0; }
button.tcOpen {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 12px 14px; background: var(--brand-tint); border: 1px solid var(--brand-soft);
  border-radius: 9px;
}
button.tcOpen:hover { background: #ffedd9; border-color: var(--brand); }
.tcOpen .tcIcon {
  flex: none; width: 30px; height: 30px; display: grid; place-items: center;
  background: var(--brand); color: #fff; border-radius: 7px; font-size: 15px; font-weight: 700;
}
.tcOpen .tcTxt { display: flex; flex-direction: column; gap: 1px; line-height: 1.35; }
.tcOpen .tcTxt b { color: var(--brand-dark); font-size: 14px; }
.tcOpen .tcTxt small { color: var(--muted); font-size: 11.5px; }
.tcOpen .tcChev { margin-left: auto; color: var(--brand); font-size: 20px; line-height: 1; }
.tcActions { display: flex; justify-content: flex-end; margin: 6px 0 8px; }
#tcText {
  margin: 0; padding: 12px 14px; max-height: 60vh; overflow: auto;
  background: var(--bg); border: 1px solid var(--line); border-radius: 6px;
  white-space: pre-wrap; word-break: break-word; line-height: 1.8; font-size: 14px;
  font-family: "PingFang TC", "Microsoft JhengHei", "Noto Sans TC", system-ui, sans-serif;
}

.histHeading { margin: 20px 0 6px; padding-top: 16px; border-top: 1px solid var(--line); font-size: 13px; color: var(--muted); }
.dangerZone { margin-top: 26px; padding-top: 14px; border-top: 1px solid var(--line); text-align: right; }
.dangerBtn { border: 1.5px solid var(--danger); color: var(--danger); background: #fff; font-weight: 600; }
.dangerBtn:hover { background: var(--danger); color: #fff; border-color: var(--danger); }
.timeline { margin: 8px 0 0; border-left: 2px solid var(--line); padding-left: 14px; }
.timeline li { list-style: none; margin-bottom: 10px; font-size: 12.5px; position: relative; }
.timeline li::before {
  content: ""; position: absolute; left: -20px; top: 5px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--brand);
}
.timeline .t { color: var(--muted); }

.actions {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  /* One size for every button, select, input, label and note in this
     section (buttons/inputs/selects already use font: inherit) — the
     per-element overrides below used to drift between 11-14px. */
  font-size: 13px;
}
.actions:empty { display: none; }
.actions h4 { margin: 0 0 8px; color: var(--muted); }
.actions label { font-size: 13px; }
/* Secondary action buttons (Allocate, Re-scan, Send back, …) — a clear
   outline so they read as buttons, distinct from the filled .primary. */
.actions button:not(.primary):not(.ghost) {
  border: 1.5px solid var(--brand);
  color: var(--brand-dark);
  background: #fff;
  font-weight: 600;
}
.actions button:not(.primary):not(.ghost):hover {
  background: var(--brand-tint);
  border-color: var(--brand-dark);
}
.actionRow { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-end; }
.actionRow > div { flex: 1; min-width: 160px; }
.actionRow.col { flex-direction: column; align-items: stretch; }
.actionRow.col > div { flex: none; min-width: 0; }

/* Maree's per-colour voice allocation — one row each for Red / Blue / Black */
.allocRow { display: flex; align-items: center; gap: 10px; margin: 4px 0; flex-wrap: wrap; }
.allocRow select, .allocRow input { flex: 1; min-width: 140px; }
.cSwatch { flex: none; display: inline-flex; align-items: center; gap: 6px; width: 80px; font-weight: 600; padding: 4px 10px; border-radius: 999px; }
.cSwatch::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: currentColor; }
.cSwatch.red { color: #b91c1c; background: #fee2e2; }
.cSwatch.blue { color: #1d4ed8; background: #dbeafe; }
.cSwatch.black { color: #1f2937; background: #e5e7eb; }
.allocCur { color: var(--muted); }
/* Colour names shown in their own colour (voice-assignment section) */
.ctag { font-weight: 700; }
.ctag-blue, .field span.ctag-blue { color: #1d4ed8; }
.ctag-red, .field span.ctag-red { color: #b91c1c; }
.ctag-black, .field span.ctag-black { color: #1f2937; }

.toast {
  position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
  z-index: 80;
  background: #1f2430; color: #fff; padding: 10px 18px; border-radius: 8px;
  font-size: 13px; opacity: 0; transition: opacity .2s; pointer-events: none;
}
.toast.show { opacity: 1; }
.toast.err { background: var(--danger); }

@media (max-width: 820px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .grid2 { grid-template-columns: 1fr; }
  table { font-size: 12px; }
  .hero h2 { font-size: 20px; }
}

/* --- sign-in gate + account admin (Cloudflare Access, docs/auth.md) ------ */
header .who .meChip {
  font-size: 12px; color: var(--muted); max-width: 260px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
header .who .meChip.dev { color: var(--brand-dark); font-weight: 600; }
header .who .signOut { font-size: 12px; color: var(--muted); text-decoration: none; }
header .who .signOut:hover { color: var(--brand); text-decoration: underline; }

.gate {
  max-width: 560px; margin: 32px auto; background: var(--panel);
  border: 1px solid var(--line); border-radius: 12px; padding: 24px 26px 26px;
}
.gate h2 { margin: 0 0 10px; font-size: 20px; }
.gate .gateIntro { margin: 0 0 4px; font-size: 13px; line-height: 1.6; color: var(--ink); }
.gateRoles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 4px 14px; margin: 4px 0 2px;
}
.gateActions { margin-top: 20px; display: flex; gap: 10px; flex-wrap: wrap; }

.acct {
  /* A visibly darker border + soft shadow than the plain --line default —
     .section (the surrounding container) is the same white as .acct, so the
     old 1px --line border barely showed where one account ended and the
     next began. */
  border: 1px solid #d2d7de; border-radius: 10px; padding: 14px 16px 16px;
  margin-bottom: 16px; background: var(--panel);
  box-shadow: 0 1px 4px rgba(15, 18, 26, .07);
  font-size: 13px;
}
.acct:last-child { margin-bottom: 0; }
/* New-account form (createAccountFormHtml) — same one-size rule as .acct so
   its labels/inputs/buttons don't drift between the 12/13/14px they used to. */
.acctForm { font-size: 13px; }
.acctForm label, .acct label { font-size: 13px; }
.acctForm p.hint { font-size: 13px; }
.acctHead { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.acctEmail { font-weight: 600; font-size: 13px; word-break: break-all; }
.acctStatus {
  font-size: 11px; padding: 1px 7px; border-radius: 999px;
  background: #eef0f4; color: var(--muted);
}
.acctStatus.invited { background: #fff3d6; color: #8a5a00; }
.acctStatus.active { background: #e4f6e8; color: #1d7a36; }
.acctStatus.disabled { background: #fbe6e6; color: #a33; }
.acctAdmin { font-size: 11px; padding: 1px 7px; border-radius: 999px; background: var(--brand-tint); color: var(--brand-dark); }
.acctFlag { font-size: 11px; color: var(--brand-dark); border-bottom: 1px dotted currentColor; cursor: help; }
.acctCount { font-size: 12px; color: var(--muted); font-weight: 400; }
.acctAdminChk { margin-top: 10px; }
.acctActions { margin-top: 14px; display: flex; gap: 8px; flex-wrap: wrap; }
.acctResetBox {
  margin-top: 10px; padding: 10px 12px; border-radius: 8px;
  background: var(--bg); border: 1px solid var(--line);
}
.acctResetBox .acctNewPw { margin-bottom: 8px; }
.acctResetBox .gateActions { margin-top: 0; }

/* Sign-in, forgot-password and set-password pages (docs/sign-in.md). */
.gate .gateLink { align-self: center; font-size: 13px; color: var(--muted); }
.gate .gateLink:hover { color: var(--brand); }
/* A plain browser-navigation link styled to read as a button — used on the
   .gate auth pages (a real navigation, not a fetch()). */
a.buttonLink {
  display: inline-block; padding: 8px 14px; border-radius: 7px; text-decoration: none;
  background: var(--brand); color: #fff; font-size: 14px;
}
a.buttonLink:hover { background: var(--brand-dark); }
.gateDivider {
  margin: 18px 0; text-align: center; font-size: 12px; color: var(--muted);
  display: flex; align-items: center; gap: 10px;
}
.gateDivider::before, .gateDivider::after { content: ""; flex: 1; height: 1px; background: var(--line); }
/* Standard "Sign in with Google" look (white pill, brand-coloured G, visible
   border) so it reads immediately as its own distinct, legitimate sign-in
   option — not a muted secondary link easy to miss below the password form. */
a.buttonLink.gateGoogleBtn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  background: #fff; color: #3c4043; border: 1px solid #dadce0;
  font-size: 15px; font-weight: 500; padding: 10px 16px;
}
a.buttonLink.gateGoogleBtn:hover { background: #f8f9fa; box-shadow: 0 1px 3px rgba(0,0,0,.15); }
a.buttonLink.gateGoogleBtn svg { flex: none; }

/* An admin viewing a function they don't hold (docs/auth.md). */
header .who .viewOnlyTag {
  font-size: 11px; padding: 2px 8px; border-radius: 999px; white-space: nowrap;
  background: var(--brand-tint); color: var(--brand-dark);
}

/* --- payments (worker/src/payments.ts) --- */
button.link {
  background: none; border: none; padding: 0; color: var(--brand);
  font-size: 12px; font-weight: 500; cursor: pointer;
}
button.link:hover { background: none; color: var(--brand-dark); text-decoration: underline; }
.payToolbar h3 { margin-bottom: 8px; }
.payMonthNav { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.payMonthNav strong { font-size: 15px; }
.payGrandTotal { font-weight: 600; margin-top: 8px; }
.payCard > h3 { justify-content: space-between; }
.payCardTotal { font-variant-numeric: tabular-nums; color: var(--brand-dark); }
table.payTable, table.payAdhocTable, table.payDrillTable { font-size: 13px; }
table.payTable th, table.payAdhocTable th, table.payDrillTable th {
  text-align: left; font-weight: 500; color: var(--muted); font-size: 12px; padding: 6px 8px;
}
table.payTable td, table.payAdhocTable td, table.payDrillTable td { padding: 6px 8px; border-top: 1px solid var(--line); }
table.payTable td.num, table.payAdhocTable td.num, table.payDrillTable td.num, table.payTable th.num, table.payAdhocTable th.num, table.payDrillTable th.num {
  text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;
}
table.payTable tfoot td { border-top: 2px solid var(--line); font-weight: 600; }
.payAmount { font-weight: 600; }
.payLabel { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.payDrillRow td { padding: 0 8px 12px; border-top: none; }
table.payDrillTable { width: 100%; background: var(--bg); border-radius: 8px; }
table.payDrillTable th, table.payDrillTable td { border-top: 1px solid var(--line); }
.payOverrideInput, .paySnapshotInput, .payAdhocQtyInput, .payFieldInput, .payAdhocFieldInput[type=number] { width: 90px; text-align: right; }
.payAdhocTable .cellInput { width: 90px; text-align: right; }
.payAdhocTable .payNoteCell .cellInput { width: 100%; min-width: 140px; text-align: left; }
.payWorking { font-size: 12px; color: var(--muted, #6b7280); font-weight: normal; margin-top: 2px; }
.payNoteInput, .payAdhocFieldInput[type=text] { width: 100%; min-width: 160px; }
.payAdhocSection .hint { margin-bottom: 12px; }
.payAdhocForm input, .payAdhocForm select { font: inherit; font-size: 13px; padding: 4px 6px; border: 1px solid var(--line); border-radius: 5px; width: 100%; }
.payAdhocFormActions { display: flex; gap: 8px; white-space: nowrap; }
.payAdhocFormActions button { font-size: 12px; padding: 5px 10px; }
.viewOnlyNote { margin: 6px 0 0; }
.payAdhocSelect { min-width: 150px; max-width: none; }
.payAdhocTable select.payAdhocSelect[data-field="role"] { min-width: 112px; }
.payAdhocCard > h3 { justify-content: space-between; }
.payAdhocFormGrid { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: flex-end; }
.payAdhocFormGrid label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--muted, #6b7280); }
.payAdhocFormGrid input, .payAdhocFormGrid select { min-width: 120px; }
/* Notes / descriptions: a roomy box that scrolls (small scrollbar) once the text outgrows it. */
.payTextarea { width: 100%; min-width: 240px; min-height: 2.8em; max-height: 6.5em; overflow-y: auto; resize: vertical;
  font: inherit; text-align: left; line-height: 1.35; box-sizing: border-box; scrollbar-width: thin; }
td.payNoteCell, td.payExtraDesc { min-width: 260px; }
.payAdhocTable .payNoteCell .payTextarea, .payNoteInput.payTextarea { min-width: 240px; }
.paySnapBanner { margin: 6px 0; padding: 8px 12px; border-radius: 6px; font-size: 13px; border: 1px solid var(--line); }
.paySnapBanner.pending { background: #fff7e0; border-color: #f0c36d; color: #6b4a00; }
.paySnapBanner.final { background: #e8f5ec; border-color: #9fd3ac; color: #1d5a2c; }
.payGroupHeading { display: flex; justify-content: space-between; align-items: center; margin: 32px 0 12px; padding: 14px 18px;
  border-radius: 8px; background: linear-gradient(90deg, #f97316 0%, #fbbf24 55%, #fde68a 100%); color: #1f1300;
  font-size: 24px; font-weight: 700; letter-spacing: .2px; }
.payGroupHeading .payCardTotal { color: #1f1300; }
/* "Other staff" banner: big, orange highlight so it stands apart from the China Observer groups above. */
.payOtherBanner { display: flex; justify-content: space-between; align-items: center; margin: 0 0 10px; padding: 14px 18px;
  border-radius: 8px; background: #f59e0b; color: #1f1300; font-size: 24px; font-weight: 700; letter-spacing: .2px; }
.payOtherBanner .payCardTotal { color: #1f1300; }
.payConfirmBtn { margin-left: 14px; padding: 8px 16px; font-weight: 600; }
.payConfirmBtn[disabled] { opacity: .5; cursor: not-allowed; }
.payConfirmedLine { margin: 6px 0; padding: 8px 12px; border-radius: 6px; background: #e8f5ec; border: 1px solid #9fd3ac; color: #1d5a2c; font-size: 13px; }
.payGroupRight { display: inline-flex; align-items: center; gap: 12px; }
.payApprovedCount { font-size: 14px; font-weight: 600; opacity: .85; }
.payApproveAllBtn { padding: 6px 14px; font-size: 14px; font-weight: 700; border-radius: 6px; border: 2px solid #1f1300; background: #fff; color: #1f1300; cursor: pointer; }
.payApproveAllBtn:hover { background: #1f1300; color: #fff; }
.payChip { display: inline-block; margin-left: 8px; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; vertical-align: middle; }
.payChip.awaiting { background: #fff1d6; color: #8a4b00; border: 1px solid #f0c36d; }
.payChip.approved, .payApproveBtn.approved { background: #dff3e4; color: #1d6a35; border: 1px solid #8fcf9f; }
.payApproveBtn { margin-left: 6px; padding: 3px 12px; font-size: 12px; font-weight: 700; border-radius: 999px; border: 1px solid #c77700; background: #f59e0b; color: #1f1300; cursor: pointer; vertical-align: middle; }
.payApproveBtn.approved { cursor: pointer; }
.payApprovalPending { margin-left: 12px; font-size: 13px; font-weight: 600; color: #8a4b00; }
/* Collapsed view: every person is one line (name, approval, total); group banners keep their subtotals. Default is expanded. */
.payCollapseBtn { margin-left: 16px; padding: 6px 16px; font-weight: 700; border-radius: 6px; border: 2px solid #c2410c; background: #fff7ed; color: #7c2d12; cursor: pointer; }
.payCollapseBtn:hover { background: #ffedd5; }
.payCollapsed .payCard table, .payCollapsed .payAdhocSection > .hint, .payCollapsed .payAdhocSection > table { display: none; }
.payCollapsed .payCard { padding: 6px 16px; margin: 3px 0; }
.payCollapsed .payCard > h3 { margin: 0; font-size: 15px; }
.payCollapsed .payGroupHeading { margin-top: 18px; }
.payOtherSubheading { display: flex; justify-content: space-between; align-items: center; margin: 22px 0 8px; padding: 8px 14px;
  border-left: 6px solid #f59e0b; background: #fff4de; border-radius: 4px; font-size: 17px; }
/* Collapsed view: a card whose line was clicked opens in full again. */
.payCollapsed .payCard.payCardOpen table { display: table; }
.payCollapsed .payCard.payCardOpen { padding: 12px 16px; }
.payCollapsed .payCard > h3 { cursor: pointer; }
.payCollapsed .payCard > h3 > span:first-child::before { content: "\25B8  "; color: #c2410c; }
.payCollapsed .payCard.payCardOpen > h3 > span:first-child::before { content: "\25BE  "; }
.acctSearch { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.acctSearch input { flex: 1 1 320px; max-width: 520px; padding: 8px 12px; font-size: 15px; }
.signalBanner { margin: 0 0 14px; padding: 12px 16px; border-radius: 8px; background: #fde8e8; border: 2px solid #d92d20; color: #7a1410; }
.signalBanner .sbHead { display: flex; justify-content: space-between; align-items: center; gap: 12px; font-size: 16px; }
.signalBanner .sbSub { font-size: 13px; margin: 4px 0; }
.signalBanner ul { margin: 8px 0 0; padding-left: 18px; }
.signalBanner li { margin: 5px 0; }
.signalBanner .sfErr { color: #55201c; font-size: 12px; margin: 0 8px; }
.sfBtn { padding: 3px 12px; font-size: 12px; font-weight: 700; border-radius: 999px; border: 1px solid #d92d20; background: #d92d20; color: #fff; cursor: pointer; }
.sfBtn.ghost { background: #fff; color: #d92d20; }
.payUnpaidChip { display: inline-block; margin-left: 8px; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; vertical-align: middle; background: #ffedd5; color: #c2410c; border: 1px solid #fb923c; }
.payUnpaidNote { margin-top: 3px; font-size: 11px; font-weight: 700; color: #ea580c; text-align: right; }
.payChannelsBox { margin: 6px 0 12px; }
.payChannelsBtn { padding: 5px 14px; font-weight: 700; border-radius: 6px; border: 2px solid #c2410c; background: #fff7ed; color: #7c2d12; cursor: pointer; }
.payChannelsPanel { margin-top: 8px; padding: 12px 14px; border: 1px solid #fb923c; border-radius: 8px; background: #fffaf3; }
.payChannelChips { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 12px; }
.payChannelChip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 4px 3px 12px; border: 1px solid var(--line); border-radius: 999px; background: #fff; font-size: 13px; }
.payChannelChip small { color: #6b7280; }
.payChannelChip.other { padding-right: 12px; background: #fff1d6; font-weight: 600; }
.payChannelDel { border: 0; background: #fee2e2; color: #b91c1c; border-radius: 999px; width: 22px; height: 22px; cursor: pointer; font-size: 12px; line-height: 1; }
.payChannelDel[disabled] { opacity: .35; cursor: not-allowed; }
.payChannelAdd { display: flex; gap: 8px; }
.payChannelAdd input { max-width: 260px; }
/* Excel download: a small button in the filter row; the date pickers open in a popover under it. */
.expWrap { position: relative; display: inline-block; }
.expToggle { padding: 6px 12px; font-weight: 700; border-radius: 6px; border: 2px solid #c2410c; background: #fff7ed; color: #7c2d12; cursor: pointer; white-space: nowrap; }
.expToggle.on, .expToggle:hover { background: #ffedd5; }
.expPanel { position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; min-width: 270px; display: flex; flex-direction: column; gap: 10px;
  padding: 12px 14px; border: 1px solid #fb923c; border-radius: 8px; background: #fff; box-shadow: 0 8px 24px rgba(0,0,0,.18); }
.expPanel label { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 13px; }
.expPanel .hint { margin: 0; font-size: 12px; }
.expPanel input, .expPanel select { min-width: 0; }
/* Card headers: name and status chips are separate cells so, when collapsed, the Approve / Approved /
   Awaiting approval chips line up in a column across all the cards. */
.payCard > h3 > span:first-child { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.payChips { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.payCollapsed .payCard > h3 > span:first-child { flex-wrap: nowrap; }
.payCollapsed .payName { flex: 0 0 230px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.payCollapsed .payChips { flex: 0 0 360px; flex-wrap: nowrap; }
.payCollapsed .payChip, .payCollapsed .payApproveBtn, .payCollapsed .payUnpaidChip { margin-left: 0; white-space: nowrap; }
.payAdhocAddLine td { padding: 6px 8px; }
/* The "add new staff" form must stay usable when everything else is collapsed. */
.payCollapsed .payAdhocSection > table.payAdhocNewForm { display: table; }
/* Unpaid people: the calculated pay is shown, but in grey — it is not part of any total. */
.payCardTotal.payUnpaidTotal, .payAmount.payUnpaidTotal { color: #9ca3af; font-weight: 600; text-decoration: none; }
.payDownloadBtn { margin-left: 14px; padding: 8px 14px; font-weight: 700; border-radius: 6px; border: 2px solid #c2410c; background: #fff7ed; color: #7c2d12; cursor: pointer; }
.payDownloadBtn:hover { background: #ffedd5; }
/* Pay rules and lines panel (Wallace / Maree) */
.payAdmin { margin: 10px 0; }
.payAdmin > summary { cursor: pointer; font-size: 1.05em; }
.payAdmin h4 { margin: 16px 0 6px; }
.payRulesTable td { padding: 6px 8px; vertical-align: top; }
.payRuleInput { width: 120px; }
.payLineGrid { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.payRemovedList { margin: 6px 0; padding-left: 18px; }
.payRemovedList li { margin: 4px 0; }
.payRulesBtn { margin-left: 8px; padding: 6px 12px; font-weight: 700; border-radius: 6px; border: 2px solid #c2410c; background: #fff7ed; color: #7c2d12; cursor: pointer; }
.payRulesBtn:hover { background: #ffedd5; }
.payAdmin { border: 2px solid #fdba74; }
.payAdmin > summary { color: #7c2d12; }
.payAddLineBar { margin: 6px 0 2px; }
.payAddLineForm { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin: 8px 0 4px; }
/* The page's global `label { display: block }` otherwise defeats the hidden attribute on the duty-only fields. */
label[hidden], .plcDuty[hidden] { display: none !important; }
.payRulesBtn.active { background: #fdba74; }
/* Currency tag on the headline totals, and a big, obvious month total. */
.payUsd { font-size: .55em; font-weight: 700; letter-spacing: .5px; margin-left: 6px; opacity: .85; }
.payGrandTotal { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 10px 0 6px; padding: 8px 14px;
  border-radius: 8px; background: #fff7ed; border: 2px solid #fdba74; font-weight: 600; }
.payGrandLabel { font-size: 15px; font-weight: 800; color: #7c2d12; }
.payGrandAmount { font-size: 22px; font-weight: 800; color: #c2410c; line-height: 1.1; }
.payGrandAmount .payUsd { font-size: .6em; }
.payGrandActions { margin-left: auto; display: inline-flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.payGrandActions .payDownloadBtn, .payGrandActions .payConfirmBtn { margin-left: 0; }
/* Collapsed view: just the one-line cards — no add-line bar, forms or status links. */
/* (a card that has been opened on its own, by clicking its name, shows them again) */
.payCollapsed .payCard:not(.payCardOpen) .payAddLineBar, .payCollapsed .payCard:not(.payCardOpen) .payAddLineForm,
.payCollapsed .payCard:not(.payCardOpen) .payUnpaidToggle { display: none; }
.payUnpaidToggle { font-size: 12px; margin-left: 8px; }
/* Remove line: a bare ✕ at the end of the row; its tooltip says "Remove line". */
.payRemoveCell { width: 36px; text-align: center; vertical-align: middle; }
.payRemoveX { border: 0; background: none; color: #b91c1c; font-size: 16px; line-height: 1; padding: 4px 8px; border-radius: 4px; cursor: pointer; }
.payRemoveX:hover { background: #fee2e2; }
/* Hiu's pay split */
.paySplitHead td { background: #f3f4f6; padding: 10px 12px; border-top: 2px solid #d1d5db; }
.paySplitPool td { padding: 6px 12px; font-weight: 600; color: #374151; }
.paySplitPerson td { background: #fff7ed; padding: 6px 12px; border-top: 1px solid #fed7aa; }
.paySplitDiff td { padding: 10px 12px; font-weight: 700; }
.paySplitDiff.ok td { background: #dcfce7; color: #166534; }
.paySplitDiff.bad td { background: #fee2e2; color: #991b1b; border: 2px solid #ef4444; }
.paySplitInput { width: 140px; }
/* The formula behind a card's total — only on a collapsed (not individually opened) card, for Wallace / Maree. */
.payFormula { display: none; }
.payCollapsed .payCard:not(.payCardOpen) .payFormula { display: block; flex: 1 1 0; min-width: 0; margin: 0 16px 0 8px; text-align: left;
  font-size: 13px; font-weight: 500; line-height: 1.4; color: #374151; white-space: normal; overflow-wrap: anywhere; }
/* Collapsed banners: keep every part of the formula visible (it wraps onto more lines instead of being cut off),
   and drop the Delete button there so the left side has room. */
.payCollapsed .payCard:not(.payCardOpen) .payAdhocDeletePerson { display: none; }
.payCollapsed .payCard:not(.payCardOpen) > h3 { align-items: center; }
.payCollapsed .payCard:not(.payCardOpen) .payFormula::after { content: "  ="; font-weight: 700; }
.payCollapsed .payCard:not(.payCardOpen) > h3 > .payCardTotal { flex: 0 0 auto; white-space: nowrap; }
.payCollapsed .payCard:not(.payCardOpen) > h3 > span:first-child { flex: 0 0 auto; }

/* Cost report by channel — one table, so amounts and percentages line up in columns; details ~30% bigger */
.payChannelsBar { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.payCostPanel { margin: 12px 0 4px; padding: 14px 16px; border: 2px solid #fdba74; border-radius: 10px; background: #fffaf3; }
.payCostHead { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.payCostHead h3 { margin: 0; }
.payCostReport { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 15px; table-layout: fixed; }
.payCostReport col.cAmt { width: 190px; }
.payCostReport col.cPct { width: 100px; }
.payCostReport col.cDet { width: 42%; }
.payCostReport th { padding: 4px 12px; font-size: 13px; font-weight: 600; color: #6b7280; text-align: left; border-bottom: 1px solid #fed7aa; }
.payCostReport td { padding: 6px 12px; vertical-align: top; overflow-wrap: anywhere; }
.payCostReport .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.payCostReport .ghost { visibility: hidden; }
.payCostBanner td { background: #f59e0b; color: #000; font-weight: 700; font-size: 16px; padding: 8px 12px; }
.payCostBannerDetail { font-size: 14px !important; font-weight: 500 !important; }
.payCostBanner td:first-child { border-radius: 6px 0 0 6px; }
.payCostBanner td:last-child { border-radius: 0 6px 6px 0; }
.payCostBanner .payCardTotal, .payCostBanner .payUsd { color: #000; }
.payCostChan { font-weight: 600; }
.payCostPct { color: #374151; }
.payCostLines { color: #374151; font-size: 15px; line-height: 1.4; }
.payCostEmpty td { color: #6b7280; font-size: 15px; font-style: italic; }
.payCostSpacer td { padding: 5px; }
.payCostGrandRow td { padding-top: 10px; border-top: 2px solid #fdba74; font-size: 17px; font-weight: 800; color: #000; }
.payCostGrandRow .payUsd { font-size: .5em; }
.payCostGrandRow td:last-child { font-size: 14px; font-weight: 600; }
.payCostOk { color: #166534; }
.payCostBad { color: #991b1b; font-weight: 700; }
.payCostMap { margin-top: 14px; font-size: 15px; }
.payCostMapTable td { padding: 4px 10px; }
.payCostHeadRight { display: inline-flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.payCostHeadRight .payDownloadBtn { margin-left: 0; }
/* Other staff role sub-headings (Writers, Voiceovers, …): the subtotal is black, not red. */
.payOtherSubheading, .payOtherSubheading .payCardTotal, .payOtherSubheading .payUsd { color: #000; }
/* All Topics page — same table look as All articles */
.topicsTable td { vertical-align: top; padding: 6px 10px; }
.topicsTable td.date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.topicsTable td.title .titletxt { font-weight: 600; }
.topicText { white-space: pre-wrap; max-width: 320px; }
.topicText a { color: var(--brand-dark, #1d4ed8); word-break: break-all; }
.topicNone { color: #9ca3af; }
.topicCount { align-self: center; }
/* All Topics: narrower, wrapping columns; long links / notes are held to a few lines (scroll inside the cell); rows open the topic */
.topicsTable { width: max-content; }
.topicRow { cursor: pointer; }
.topicsTable tbody tr.topicRow:hover td { background: #fff7ed; }
.topicText { white-space: normal; overflow-wrap: anywhere; word-break: break-word; }
.topicClip { max-height: 6.2em; overflow-y: auto; white-space: pre-wrap; line-height: 1.45; scrollbar-width: thin; }
.topicsTable td.title .titletxt { white-space: normal; overflow-wrap: anywhere; }
.payDownloadBtn.active { background: #fdba74; }
.payCostMap h4 { margin: 0 0 4px; }
/* All Topics: alternating rows in light blue */
.topicsTable tbody tr:nth-child(even) td { background: #eaf3fe; }
.topicsTable tbody tr:nth-child(odd) td { background: #fff; }
.payTermChip { color: #92400e; background: #fef3c7; border-radius: 10px; padding: 1px 8px; font-size: 12px; font-weight: 600; }
/* Delete / Terminated / Undo on a pay card: pill buttons shaped like the Approve button, in their own colours */
.payActBtn { margin-left: 6px; padding: 3px 12px; font-size: 12px; font-weight: 700; border-radius: 999px; border: 1px solid; cursor: pointer; vertical-align: middle; text-decoration: none; }
.payActDelete { background: #fee2e2; color: #b91c1c; border-color: #fca5a5; }
.payActDelete:hover { background: #fecaca; }
.payActTerm { background: #ede9fe; color: #5b21b6; border-color: #c4b5fd; }
.payActTerm:hover { background: #ddd6fe; }
.payActUndo { background: #e0f2fe; color: #0369a1; border-color: #7dd3fc; }
.payActUndo:hover { background: #bae6fd; }
/* collapsed cards: no Terminated button, "Terminated after ..." label or Undo on the banner (open the card to see them) */
.payCollapsed .payCard:not(.payCardOpen) .payTermToggle, .payCollapsed .payCard:not(.payCardOpen) .payTermChip { display: none; }
.ytRefreshBtn { padding: 6px 14px; font-size: 14px; font-weight: 600; border-radius: 6px; border: 1px solid var(--line, #d0d3d9); background: #fff; cursor: pointer; align-self: center; }
.ytRefreshBtn:hover:not(:disabled) { background: var(--brand-tint, #fff7ed); }
.ytRefreshBtn:disabled { opacity: .7; cursor: progress; }
.moreRows { margin: 10px 2px; font-size: 14px; color: #4b5563; }
.moreRows .link { margin-left: 12px; font-weight: 600; }
.msel .mselpanel { max-height: 60vh; overflow-y: auto; }
/* Long All-articles list drawn as a window of rows (see updateVirtual in app.js): every row one fixed height, one line */
.tablewrap table.vtable tbody tr[data-open] { height: 32px; }
.tablewrap table.vtable td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; word-break: normal; overflow-wrap: normal; }
.tablewrap table.vtable tr.vspacer td { padding: 0; border: 0; background: transparent; }
/* Filters on the All-articles column headings (Writer, Translator, Voice, Video editor) */
.msel.cf { display: inline-block; margin-left: 4px; vertical-align: middle; }
.msel.cf .cfBtn { padding: 0 5px; min-width: 0; height: 20px; line-height: 18px; font-size: 12px; border: 1px solid transparent; border-radius: 4px; background: transparent; color: #6b7280; cursor: pointer; }
.msel.cf .cfBtn:hover { background: #eef2f7; border-color: var(--line, #d0d3d9); }
.msel.cf .cfBtn.on { background: #fde68a; border-color: #d97706; color: #7c2d12; }
.msel.cf .mselpanel { position: fixed; z-index: 80; min-width: 200px; max-width: 320px; max-height: 60vh; overflow-y: auto; font-weight: 400; color: #10121a; text-align: left; font-size: 13px; }
.msel.cf .mselbtn .mselcar { display: none; }
/* Payments: period controls, staff search, range view, confirmed tick, per-person Excel */
.payPeriod { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin: 8px 0; }
.payModeBtns { display: inline-flex; border: 1px solid var(--line, #d0d3d9); border-radius: 8px; overflow: hidden; }
.payModeBtn { border: 0; background: #fff; padding: 6px 14px; font-size: 14px; font-weight: 600; cursor: pointer; }
.payModeBtn + .payModeBtn { border-left: 1px solid var(--line, #d0d3d9); }
.payModeBtn.active { background: #fde68a; color: #7c2d12; }
.payPeriodBody { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.payPeriodBody label { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; }
.paySearch { min-width: 230px; flex: 1 1 230px; max-width: 360px; }
.payConfirmedInline { display: inline-flex; align-items: center; gap: 6px; margin-left: 14px; font-size: 13px; font-weight: 600; color: #1d6a35; flex: 1 1 260px; min-width: 0; }
.payTick { color: #15803d; font-weight: 800; font-size: 1.15em; }
.payTickOpen { color: #9ca3af; }
.payActXls { background: #dcfce7; color: #166534; border-color: #86efac; }
.payActXls:hover { background: #bbf7d0; }
.payRangeWrap { max-height: calc(100vh - 330px); }
.payRangeTable td.num, .payRangeTable th.num { text-align: right; white-space: nowrap; }
.payRangeTable tfoot td { font-weight: 700; border-top: 2px solid #d0d3d9; }
.payRangeTable tbody tr:nth-child(even) td { background: #f8fafc; }
.payCollapsed .payCard:not(.payCardOpen) .payPersonXls { display: none; }
/* Payments: mode buttons, previous / month / year / next and the staff search all on ONE row (wraps only on a narrow screen) */
.payPeriod { flex-wrap: nowrap; gap: 10px 12px; }
.payPeriod .payModeBtns, .payPeriod .payPeriodBody { flex: 0 0 auto; flex-wrap: nowrap; white-space: nowrap; }
.payPeriod select, .payPeriod input[type="month"], .payPeriod button { width: auto; margin: 0; }
.payPeriod .paySearch { flex: 1 1 140px; min-width: 120px; max-width: 360px; }
@media (max-width: 1100px) { .payPeriod { flex-wrap: wrap; } }
/* Chinese channel 慧眼频道 */
.ccTable td { padding: 2px 6px; vertical-align: middle; }
.ccTable td.num { text-align: right; white-space: nowrap; }
.ccTable td.ccTick { text-align: center; }
.ccIn { width: 100%; min-width: 0; height: 26px; padding: 1px 6px; font-size: 13px; box-sizing: border-box; }
.ccChk { width: 18px; height: 18px; cursor: pointer; }
.ccTable tbody tr:nth-child(even) td { background: #f6f9fe; }
.ccDetails .field > span { min-width: 150px; }
.ccDetails .field .ccIn { max-width: 380px; }
/* Payments: automatic quantity from the Chinese channel page, and the pieces behind it */
.payAutoChip { display: inline-block; margin-top: 2px; padding: 0 8px; border-radius: 999px; font-size: 11px; font-weight: 700; background: #e0f2fe; color: #0369a1; border: 1px solid #7dd3fc; cursor: help; }
.payQtyAuto { font-size: 12px; }
.payAdhocPieces > td { padding: 0 8px 8px 24px; background: #f8fafc; }
.payPieces summary { cursor: pointer; font-size: 13px; font-weight: 600; color: #0369a1; padding: 4px 0; }
.payPieceTable { width: 100%; border-collapse: collapse; font-size: 13px; background: #fff; }
.payPieceTable th, .payPieceTable td { text-align: left; padding: 3px 8px; border-bottom: 1px solid #e5e7eb; }
.payPieceTable td.date { white-space: nowrap; }
/* Article page: the Traditional-text bar is short and shares its row with the snapshot buttons */
.tcPanel.tcBar { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; gap: 8px; margin: 0; }
.tcBar button.tcOpen { width: 100%; padding: 6px 12px; gap: 8px; }
.tcBar .tcOpen .tcIcon { width: 24px; height: 24px; font-size: 13px; }
.tcBar .tcOpen .tcTxt b { font-size: 13px; }
.tcBar .tcOpen .tcChev { margin-left: 4px; font-size: 18px; }
/* the Retake button: orange outline and orange text, like the Save / Re-scan buttons */
.tcBar button.tcRetake { width: 100%; border: 1.5px solid var(--brand); color: var(--brand-dark); background: #fff; font-weight: 600; }
.tcBar button.tcRetake:hover { background: var(--brand-tint); border-color: var(--brand-dark); }
/* Article page: "Offer to ..." text, Re-scan colours, and the manual blue / red counts + Save on one row */
.actionRow.voiceRow { flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.actionRow.voiceRow > div { flex: 0 0 auto; min-width: 0; }
.voiceRow .vrAdjust { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.voiceRow .vrAdjust > label:first-child { font-size: 12px; font-weight: 700; color: var(--muted); }
.voiceRow .vrNum { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; }
.voiceRow .vrNum input { width: 64px; margin: 0; }
.voiceRow button { margin: 0; }
/* 慧眼 section: a field that takes the whole row */
.grid2 .field.wide { grid-column: 1 / -1; }
/* Article page, other details: two columns, each going down */
.infoCols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; margin: 12px 0; align-items: start; }
.infoCol { min-width: 0; }
.infoCol .field { padding: 6px 0; }
.infoCol .datePair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; }
/* long links (Drive files, YouTube, the document) are shortened with an ellipsis; the whole address is still what opens */
.infoCol .field a, .infoCol .field .segLinkGo { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; word-break: normal; }
@media (max-width: 640px) { .infoCols { grid-template-columns: 1fr; } }
/* 慧眼 section: the collection tick and its ID on one row */
.collRow .collBox { display: flex; align-items: center; gap: 12px; }
.collRow .collId { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700; color: var(--muted); flex: 1; min-width: 0; }
.collRow .collId input { flex: 1; min-width: 0; }
/* 慧眼 article link: the field and the "create document" button on one row */
.docRow { display: flex; gap: 8px; align-items: center; }
.docRow input { flex: 1; min-width: 0; }
.docRow button { flex: none; border: 1.5px solid var(--brand); color: var(--brand-dark); background: #fff; font-weight: 600; }
.docRow button:hover { background: var(--brand-tint); }
/* 慧經 section top row: Traditional-text bar + Retake on the left, article link + Create document on the right */
.ccTop { align-items: end; }
.ccTop .infoCol .field { border-bottom: 0; padding: 0; }
/* 慧眼 section: the Collection link and its publish date on one row, the date on the right */
.collPair { display: grid; grid-template-columns: 1fr auto; gap: 0 12px; align-items: start; }
.collPair .field input { width: 100%; }
.collPair .field:last-child input { width: 150px; }
/* Article page, other details: English title | YouTube | planned | actual on one row, with a slightly darker line above and a line below */
.infoRow { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 1.1fr) 128px 128px; gap: 0 14px; margin: 4px 0 12px; padding-top: 8px; border-top: 2px solid #c9ccd3; border-bottom: 2px solid #c9ccd3; }
.infoRow .field { border-bottom: 0; min-width: 0; }
.infoRow .field:first-child { overflow-wrap: anywhere; }            /* the English title gets the most room and wraps rather than being cut */
.infoRow .field input[type="date"] { width: 100%; min-width: 0; padding-left: 6px; padding-right: 4px; }
.infoRow .field:nth-child(2) a, .infoRow .field:nth-child(2) .segLinkGo { max-width: 100%; }   /* the YouTube link is shortened with ... */
.infoRow .field a, .infoRow .field .segLinkGo { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; word-break: normal; }
/* Phones: the title and the YouTube link each take a full row, the two dates share the next one */
@media (max-width: 760px) {
  .infoRow { grid-template-columns: 1fr 1fr; }
  .infoRow .field:nth-child(1), .infoRow .field:nth-child(2) { grid-column: 1 / -1; }
  .collPair { grid-template-columns: 1fr; }
  .collPair .field:last-child input { width: 100%; }
  .docRow { flex-wrap: wrap; }
  .docRow input { flex: 1 1 100%; }
  .tcPanel.tcBar { grid-template-columns: 1fr; }
}
/* English title box: wraps, and grows (see the script) to show the whole title */
.field textarea.titleEnArea { display: block; width: 100%; margin-top: 2px; font: inherit; font-size: 12px; line-height: 1.4; padding: 4px 6px; border: 1px solid var(--line); border-radius: 5px; background: var(--panel); color: var(--ink); resize: none; overflow: hidden; }
/* the 慧眼 section follows the title row, which already ends in a line: no second one */
.infoDetails.ccDetails { border-top: 0; margin-top: 0; }
/* Delete / Terminate / Undo / Mark as not paid: small links, underlined */
button.link.payActLink, button.link.payUnpaidToggle { font-size: 12px; margin-left: 8px; text-decoration: underline; }
/* a card header's buttons never break onto two lines (the Download arrow used to sit above its word when a card was opened) */
.payActBtn, .payChips .link, .payChips button { white-space: nowrap; flex: none; }
.payChips { flex-wrap: wrap; }
.payArchList { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 8px 0 2px; font-size: 13px; }
.payArchItem { white-space: nowrap; }
/* 慧眼: a person drop-down with its small "completed" tick */
.ccPick { display: flex; align-items: center; gap: 6px; }
.ccPick .ccIn { flex: 1; min-width: 0; }
.ccPick .ccDone { flex: none; width: 16px; height: 16px; margin: 0; cursor: pointer; accent-color: #16a34a; }
/* 慧眼 article link: one click opens the document (Edit swaps it for the text box) */
.docRow a.ccDocGo { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--focus, #2563eb); text-decoration: underline; font-size: 13px; }
/* 慧眼 top row: more room for the article link (the buttons beside it are short now) */
.infoCols.ccTop { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.3fr); }
.ccDetails .docRow .ccIn { max-width: none; }
.docRow button { padding: 5px 10px; font-size: 12px; }
/* YouTube field inside the 慧眼 / Cantonese article sections: one click opens, a double click edits */
.ytField { cursor: pointer; min-height: 26px; display: flex; align-items: center; }
.ytField .ytlink { color: var(--focus, #2563eb); font-weight: 600; }
.ytField .ytadd { color: #4b5563; font-weight: 700; }
.ccTable td.yt[data-yt] { cursor: pointer; }
/* Reports: three panes (English / 慧眼 / Cantonese), each scrolling sideways on its own; all three scroll up and down together */
.rpCols { display: grid; gap: 8px; align-items: start; }
.rpTop { margin-top: 6px; align-items: end; }
.rpPaneTop { min-width: 0; }
.rpHBar { overflow-x: auto; overflow-y: hidden; height: 14px; margin-bottom: 2px; }
.rpHBar > div { height: 1px; }
.rpClip { overflow: hidden; min-width: 0; border: 1px solid var(--line); }
.rpPaneTop .rpClip { border-bottom: 0; border-radius: 8px 8px 0 0; }
.rpBodyClip { border-top: 0; border-radius: 0 0 8px 8px; }
.rpScroll { overflow-y: auto; overflow-x: hidden; }
.rpSlide { will-change: transform; }
.rpTbl { table-layout: fixed; border-collapse: collapse; }
.rpTbl th, .rpTbl td { height: 32px; padding: 0 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-bottom: 1px solid rgba(0,0,0,.07); text-align: left; font-size: 13px; color: #10121a; box-sizing: border-box; }
.rpTbl th { position: relative; font-weight: 700; user-select: none; }
.rpTbl th.sortable { cursor: pointer; }
.rpTbl td.num { text-align: right; font-variant-numeric: tabular-nums; }
.rpTbl td.date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.rpTbl td .titletxt { display: block; overflow: hidden; text-overflow: ellipsis; font-weight: 600; }
.rpTbl .colrz { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: col-resize; z-index: 6; touch-action: none; }
/* the three colours: light orange, very light orange, light yellow */
.rpEn th  { background: #fdd9a6; }  .rpEn td  { background: #ffeed8; }
.rpHy th  { background: #ffeedd; }  .rpHy td  { background: #fff9f2; }
.rpYue th { background: #fff2b3; }  .rpYue td { background: #fffbe0; }
.rpEn tr.rpHover td, .rpHy tr.rpHover td, .rpYue tr.rpHover td { filter: brightness(.95); cursor: pointer; }
.rpTbl tr[data-open] { cursor: pointer; }
.rpEn .rpHBar, .rpHy .rpHBar, .rpYue .rpHBar { border-radius: 4px; }
/* Reports, second round: English frozen, headings wrap, the sideways bars sit under the rows */
.rpTbl th { height: 46px; white-space: normal; line-height: 1.15; font-size: 12px; padding: 4px 10px; overflow: hidden; text-overflow: clip; vertical-align: middle; }
.rpTop { align-items: stretch; }
.rpBottom { margin-top: 2px; }
.rpHBar { height: 14px; margin: 0; }
/* Reports, third round: the three panes are at least as wide as their columns; an empty column at the right end of 慧眼 / Cantonese */
.rpPanes { overflow-x: auto; }
.rpTbl .rpSpacer { padding: 0; }
.rpTbl th.rpSpacer { cursor: default; }
/* Reports: the three panes always fit the window; no scroll bar of the page itself */
.rpPanes { overflow: visible; }


/* Reports uses the whole window (the other table pages are widened by .tablewrap; this page has no .tablewrap, so it was stuck at the narrow default page width) */
main:has(.rpPanes) { max-width: 2400px; }
/* Reports: centred in the window like the other table pages */
main:has(.rpPanes) { max-width: 1840px; margin-left: auto; margin-right: auto; }


/* Reports: no space between the 慧眼 and Cantonese panes (a small gap stays after the frozen English pane) */
.rpCols { gap: 0; }
.rpCols > :nth-child(2) { margin-left: 8px; }
.rpScroll .rpCols > :nth-child(3), .rpTop > :nth-child(3) .rpClip { border-left: 0; }
/* Reports: the three panes are exactly as wide as their columns, and centred like the other table pages */
.rpCols { justify-content: center; }
/* 小美 page: every cell is a box edited in place */
.xmTable td { padding: 2px 6px; }
.xmTable td.xmDel { text-align: center; }
.xmTable td.xmDel .link { color: var(--muted); font-size: 14px; }
.xmTable td.xmDel .link:hover { color: #b91c1c; }

