/* js-signage — the visual system.
 *
 * The subject: a control room for a network of screens. What is airing, where,
 * at what hour, and whether it really did air. The page is scanned and
 * operated, not read from top to bottom: the summary before the detail, state
 * encoded in a shape (pill, dot, stripe), not in a number alone.
 *
 * Colour — graphite and signal. Cool neutrals (screens give off light of their
 * own), a single petrol-green accent for everything interactive, and the state
 * colours (good, careful, bad, “on air”) stay apart from the accent so they do
 * not compete with it. The administrative blue is gone: five buttons no longer
 * shout at once.
 *
 * Typography — two roles: an interface sans (the system’s own) for text and a
 * mono for numbers, hours, ids and money, with tabular figures so that they
 * line up in columns. The scale: 11 (small label, uppercase, tracked), 12.5
 * (meta), 14 (text), 16 (card title), 20 (page title), 26 (the big number).
 *
 * Layout — a narrow, quiet navigation column, a title bar that says where you
 * are and what you can do, a toolbar that lets the search breathe, then the
 * content: cards with a single thin border, dense tables with a label header
 * and numbers to the right. No shadows everywhere: a shadow lifts only what
 * really floats (the dialog, the card under the cursor).
 */
:root {
  color-scheme: light;
  /* cool neutrals */
  --bg: #eef1f4; --card: #ffffff; --card-2: #f7f9fa;
  --ink: #151a21; --ink-2: #3c4654; --muted: #6b7684;
  --line: #dde3e9; --line-2: #c7d0d9;
  /* accent: petrol green, the only “interactive” tone */
  --accent: #0f6d67; --accent-ink: #ffffff; --accent-soft: #e2f0ef; --accent-line: #9fcbc7;
  /* states (kept apart from the accent) */
  --ok: #1c7a46; --ok-soft: #e6f4ec; --warn: #8a5a00; --warn-soft: #fbf1dd;
  --bad: #b42318; --bad-soft: #fdecea; --live: #e0344b;
  /* the navigation column */
  --side: #161b22; --side-ink: #9aa4b2; --side-active: #222b36; --side-line: #262f3a;
  /* auxiliary surfaces */
  --chip: #eef1f4; --chip-ink: #39434f; --chip-active: var(--accent-soft); --media: #0f172a;
  --hover: #f5f7f9; --focus: rgba(15, 109, 103, .35);
  --shadow: 0 10px 30px rgba(21, 26, 33, .10), 0 1px 2px rgba(21, 26, 33, .06);
  --page-x: 26px; --page-y: 22px;
  --radius: 10px; --radius-sm: 7px;
  --ui: -apple-system, "Segoe UI Variable Text", "Segoe UI", system-ui, Roboto, "Helvetica Neue", sans-serif;
  --data: ui-monospace, "Cascadia Mono", "SF Mono", "Segoe UI Mono", Consolas, monospace;
}
/* At night, in a control room, a white screen blinds. The same symbols on a
   different ground: only the tokens change. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0e1116; --card: #161b22; --card-2: #1b212a;
    --ink: #e6eaef; --ink-2: #c2cad4; --muted: #8b95a3;
    --line: #262e38; --line-2: #333d49;
    --accent: #2fa79c; --accent-ink: #06231f; --accent-soft: #10312e; --accent-line: #2b5f59;
    --ok: #4cc38a; --ok-soft: #11291e; --warn: #d6a336; --warn-soft: #2b2313; --bad: #f2807a; --bad-soft: #2c1614;
    --chip: #1f262f; --chip-ink: #c2cad4; --hover: #1b212a; --media: #05070b;
    --shadow: 0 12px 32px rgba(0, 0, 0, .5);
  }
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  font: 14px/1.55 var(--ui);
  background: var(--bg); color: var(--ink);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
h1, h2, h3 { text-wrap: balance; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
[hidden] { display: none !important; }
.muted { color: var(--muted); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* ---- the shell ---------------------------------------------------------- */
.shell { display: grid; grid-template-columns: 212px 1fr; min-height: 100vh; }
.sidebar { background: var(--side); color: var(--side-ink); display: flex; flex-direction: column; padding: 18px 0 14px; position: sticky; top: 0; height: 100vh; }
/* The logo carries a red tell-tale — the light that says “on air”. */
.brand { display: flex; align-items: center; gap: 8px; color: #fff; font-weight: 650; font-size: 16px; letter-spacing: -.01em; padding: 0 16px 18px; }
.brand::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--live); box-shadow: 0 0 0 3px rgba(224, 52, 75, .18); flex: none; }
.brand:hover { text-decoration: none; }
.sidebar nav { display: flex; flex-direction: column; gap: 1px; padding: 0 8px; }
.sidebar nav a { display: block; color: var(--side-ink); font-size: 13.5px; padding: 7px 10px; border-radius: var(--radius-sm); position: relative; }
.sidebar nav a:hover { background: var(--side-active); color: #e8edf3; text-decoration: none; }
.sidebar nav a.active { background: var(--side-active); color: #fff; font-weight: 600; }
.sidebar nav a.active::before { content: ""; position: absolute; left: -8px; top: 7px; bottom: 7px; width: 3px; border-radius: 0 3px 3px 0; background: var(--accent); }
.sidebar nav a.external { margin-top: 12px; font-size: 12.5px; color: #7f8a98; }
.sidebar-foot { margin-top: auto; padding: 12px 16px 0; margin-top: auto; border-top: 1px solid var(--side-line); display: flex; flex-direction: column; gap: 3px; font-size: 12.5px; }
.user-name { color: #e8edf3; font-weight: 600; }
.link-button { background: none; border: 0; color: var(--side-ink); padding: 0; font: inherit; font-size: 12.5px; cursor: pointer; text-align: left; }
.link-button:hover { color: #fff; text-decoration: underline; }

.content { display: flex; flex-direction: column; min-width: 0; }
.topbar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; padding: 13px var(--page-x); background: var(--card); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 3; }
.topbar h1 { margin: 0; font-size: 20px; font-weight: 650; letter-spacing: -.015em; }
.page-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-left: auto; min-width: 0; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.page { padding: var(--page-y) var(--page-x) 32px; flex: 1; min-width: 0; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; margin-bottom: 14px; }
.card h2 { margin: 0 0 8px; font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.stage { display: inline-block; font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em; padding: 2px 7px; border-radius: 999px; background: var(--chip); color: var(--muted); margin-left: 8px; vertical-align: middle; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.grid .card { margin: 0; }
ul.plain { margin: 6px 0 0; padding-left: 18px; }
code { font: 12px/1.5 var(--data); background: var(--chip); padding: 1px 5px; border-radius: 4px; }

/* ---- sign-in ------------------------------------------------------------ */
.auth-body { display: grid; place-items: center; min-height: 100vh; padding: 16px; background: var(--bg); }
.auth-card { width: 100%; max-width: 380px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 26px 28px; box-shadow: var(--shadow); }
.auth-card h1 { margin: 0 0 4px; font-size: 19px; font-weight: 650; letter-spacing: -.015em; }
.auth-card p.lead { margin: 0 0 18px; color: var(--muted); font-size: 13px; }
.field { display: block; margin-top: 12px; }
.field span { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin-bottom: 5px; }
.field input { width: 100%; font: inherit; padding: 8px 11px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--card); color: var(--ink); }
.field input:focus { outline: 3px solid var(--focus); outline-offset: 0; border-color: var(--accent); }
.auth-card button.primary { width: 100%; margin-top: 20px; padding: 9px 14px; }
.error { color: var(--bad); font-size: 13px; margin-top: 10px; min-height: 18px; }

@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar { position: static; height: auto; padding-bottom: 8px; }
  .sidebar nav { flex-direction: row; flex-wrap: wrap; gap: 2px; }
  .sidebar nav a.active::before { display: none; }
  .sidebar-foot { flex-direction: row; flex-wrap: wrap; gap: 12px; align-items: center; }
}

/* ---- interface controls (buttons, segments, pills, tags) ---------------- */
button.primary, .btn {
  font: inherit; font-size: 13px; line-height: 1.35; cursor: pointer; white-space: nowrap;
  border-radius: var(--radius-sm); transition: background-color .12s, border-color .12s, color .12s;
}
button.primary { background: var(--accent); color: var(--accent-ink); border: 1px solid var(--accent); padding: 7px 14px; font-weight: 550; }
button.primary:hover { background: #0c5b56; border-color: #0c5b56; }
.btn { background: var(--card); color: var(--ink-2); border: 1px solid var(--line-2); padding: 5px 11px; }
.btn:hover { background: var(--hover); color: var(--ink); border-color: var(--muted); }
.btn.small { padding: 3px 8px; font-size: 12px; }
.btn.danger { color: var(--bad); }
.btn.danger:hover { border-color: var(--bad); background: var(--bad-soft); color: var(--bad); }
/* The “chosen” state is ink, not accent: on a bar with three filter groups,
   three patches of accent would say that three things matter at once. */
.btn.active, .btn[aria-pressed="true"] { background: var(--ink); color: #fff; border-color: var(--ink); position: relative; z-index: 1; }
.btn:disabled, button.primary:disabled { opacity: .5; cursor: default; }
.seg { display: inline-flex; flex: none; border-radius: var(--radius-sm); }
.seg .btn { border-radius: 0; margin-left: -1px; }
.seg .btn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); margin-left: 0; }
.seg .btn:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.badge { display: inline-block; font-size: 11.5px; line-height: 1.5; padding: 1px 7px; border-radius: 5px; background: var(--chip); color: var(--chip-ink); white-space: nowrap; font-variant-numeric: tabular-nums; }
.badge.kind-video { background: #ece4fb; color: #4a2b8a; }
.badge.kind-image { background: var(--ok-soft); color: var(--ok); }
.badge.override { box-shadow: inset 0 0 0 1px var(--warn); }
.badge.deleted { background: var(--bad-soft); color: var(--bad); }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
/* A tag reads as a sentence: the key small and dimmed, the value in ink. */
.chip-group { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 2px; padding: 2px 4px 2px 2px; border-radius: 999px; background: var(--card); border: 1px solid var(--line); }
.chip-key { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; padding: 2px 8px; border-radius: 999px; background: var(--chip); color: var(--muted); }
.chip-group.auto .chip-key { background: var(--ink); color: #fff; }
.chip { font: inherit; font-size: 12.5px; line-height: 1.35; padding: 2px 9px; border-radius: 999px; border: 1px solid transparent; background: transparent; color: var(--ink-2); cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
.chip em { font-style: normal; font-family: var(--data); font-size: 10.5px; color: var(--muted); background: var(--chip); border-radius: 999px; padding: 0 5px; font-variant-numeric: tabular-nums; }
.chip:hover { background: var(--chip); color: var(--ink); }
.chip.active, .chip[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); font-weight: 550; }
.chip.active em { background: rgba(15, 109, 103, .12); color: var(--accent); }
.tag { font: inherit; font-size: 12px; line-height: 1.45; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); color: var(--ink-2); cursor: pointer; white-space: nowrap; }
.tag.auto { color: var(--chip-ink); background: var(--chip); border-color: transparent; }
.tag.override { box-shadow: inset 0 0 0 1px var(--warn); }
.tag:hover { border-color: var(--accent-line); color: var(--accent); }
.tag.active { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.tag-none { font-size: 11.5px; }
.mono { font: 12px var(--data); }
/* The state pill: the colour says what is going on, the border keeps it quiet. */
.pill { display: inline-block; font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; padding: 2px 8px; border-radius: 999px; background: var(--chip); color: var(--muted); border: 1px solid transparent; margin-left: 6px; vertical-align: middle; white-space: nowrap; }
.pill.ok { background: var(--ok-soft); color: var(--ok); border-color: rgba(28, 122, 70, .22); }
.pill.warn { background: var(--warn-soft); color: var(--warn); border-color: rgba(138, 90, 0, .22); }
.pill.off { background: var(--chip); color: var(--muted); }


/* ---- Assets page (the library) ---- */
.ct-toolbar { position: sticky; top: var(--sticky-top, 56px); z-index: 1; background: var(--bg); margin: calc(-1 * var(--page-y)) calc(-1 * var(--page-x)) 12px; padding: 10px var(--page-x) 8px; border-bottom: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
.ct-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.ct-row-b { align-items: flex-start; gap: 8px 16px; }
.ct-search { flex: 1 1 200px; min-width: 160px; max-width: 320px; }
.ct-search-input, .ct-sort, .ct-upload-tags { font: inherit; font-size: 13px; padding: 5px 9px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--ink); width: 100%; }
.ct-search-input:focus, .ct-sort:focus, .ct-upload-tags:focus { outline: 2px solid var(--focus); border-color: var(--accent); }
.ct-sort { width: auto; flex: none; }
.ct-counter { font-size: 13px; color: var(--muted); white-space: nowrap; margin-right: 6px; }
.ct-counter b { color: var(--ink); font-size: 15px; }
.ct-chips { flex: 1 1 320px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; min-width: 0; min-height: 30px; }
.ct-chips-empty { font-size: 12.5px; }
.ct-upload { display: flex; align-items: center; gap: 6px; flex: 0 1 auto; flex-wrap: wrap; }
.ct-upload-tags { width: 280px; }
.ct-upload .primary { padding: 6px 14px; font-size: 13px; white-space: nowrap; }
.ct-notice { background: #fde8e8; color: var(--bad); border: 1px solid #f5c2c2; border-radius: 6px; padding: 6px 10px; display: flex; gap: 8px; align-items: center; font-size: 13px; }
.ct-notice .btn { margin-left: auto; color: var(--ink); }
.asset-name-wrap { min-width: 0; }
.asset-inline-error { color: var(--bad); font-size: 12px; margin-top: 4px; line-height: 1.35; }
.page.has-uploads { padding-bottom: 300px; }
.page.has-uploads-collapsed { padding-bottom: 72px; }
.ct-list[aria-busy="true"] { opacity: .6; pointer-events: none; }
.ct-more { text-align: center; padding: 14px 0 4px; }

.asset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.asset-card { background: var(--card); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; display: flex; flex-direction: column; min-width: 0; transition: box-shadow .15s, outline-color .2s; }
.asset-card:hover { box-shadow: var(--shadow); }
.asset-card.highlight { outline: 3px solid var(--accent); outline-offset: -1px; }
.asset-row.highlight td { background: var(--chip-active); }
.asset-card.deleted { opacity: .8; }
.asset-media { position: relative; aspect-ratio: 16 / 9; max-width: 100%; background: var(--media) radial-gradient(ellipse at 30% 20%, #243042, #0f172a 70%); display: grid; place-items: center; overflow: hidden; }
.asset-media.clickable { cursor: zoom-in; }
.asset-media img { width: 100%; height: 100%; display: block; }
.asset-media img.contain { object-fit: contain; }
.asset-media img.cover { object-fit: cover; }
.asset-play { font-size: 26px; color: #fff; width: 52px; height: 52px; border-radius: 50%; background: rgba(255, 255, 255, .14); display: grid; place-items: center; padding-left: 3px; }
.asset-duration { position: absolute; right: 6px; bottom: 6px; background: rgba(0, 0, 0, .7); color: #fff; font-size: 11.5px; line-height: 1.4; padding: 1px 6px; border-radius: 4px; font-variant-numeric: tabular-nums; }
.asset-media.small { width: 64px; height: 36px; aspect-ratio: auto; border-radius: 4px; }
.asset-media.small .asset-play { width: 22px; height: 22px; font-size: 11px; padding-left: 2px; }
.asset-media.small .asset-duration { display: none; }
.asset-body { padding: 8px 10px 10px; display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
.asset-name { display: inline-block; max-width: 100%; font-weight: 600; font-size: 13.5px; line-height: 1.3; overflow-wrap: anywhere; cursor: text; border-radius: 4px; padding: 2px 4px; margin: -2px -4px; border: 1px dashed transparent; }
.asset-name[role="button"]:hover { background: var(--chip); border-color: var(--line); }
.asset-name-input { font: inherit; font-weight: 600; font-size: 13.5px; width: 100%; padding: 1px 4px; margin: -2px -4px; border: 1px solid var(--accent); border-radius: 4px; outline: 2px solid var(--focus); color: var(--ink); }
.asset-badges, .asset-tags { display: flex; flex-wrap: wrap; gap: 3px 4px; }
.asset-actions { display: flex; gap: 4px; margin-top: auto; padding-top: 6px; border-top: 1px dashed var(--line); }
.asset-actions .btn { flex: 1 1 0; padding: 4px 4px; font-size: 12px; }

.table-wrap { background: var(--card); border: 1px solid var(--line); border-radius: 8px; overflow-x: auto; max-width: 100%; }
.asset-table { width: 100%; min-width: 900px; border-collapse: collapse; font-size: 13px; }
.asset-table th { text-align: left; font-size: 11.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); padding: 8px 8px; border-bottom: 1px solid var(--line); background: var(--hover); white-space: nowrap; }
.asset-table th.num, .asset-table td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.asset-table td { padding: 5px 8px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.asset-table tr:last-child td { border-bottom: 0; }
.asset-table tbody tr:hover td { background: var(--hover); }
.asset-table .cell-thumb { width: 64px; padding-right: 0; }
.asset-table .cell-name { min-width: 170px; max-width: 300px; }
.asset-table .cell-name .asset-name-input { margin: 0; }
.asset-table .cell-tags { min-width: 170px; max-width: 320px; }
.asset-table .cell-tags .asset-tags { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; padding-bottom: 2px; }
.asset-table .override-cell { text-decoration: underline dotted var(--warn); }
.asset-table .cell-date { white-space: nowrap; color: var(--muted); }
.asset-table .cell-actions { white-space: nowrap; }
.asset-table .asset-actions { margin: 0; padding: 0; border: 0; }
.asset-table .asset-actions .btn { flex: none; padding: 3px 7px; }
.asset-table .small-note { font-size: 11.5px; }
.asset-table tr.deleted td { opacity: .8; }

.ct-empty { border: 2px dashed #b8c2cf; border-radius: 12px; background: var(--card); padding: 40px 24px; text-align: center; color: var(--muted); display: flex; flex-direction: column; align-items: center; gap: 8px; min-height: 42vh; justify-content: center; }
.ct-empty h2 { margin: 0; color: var(--ink); font-size: 18px; }
.ct-empty p { margin: 0; max-width: 560px; }
.ct-empty .glyph { font-size: 40px; line-height: 1; color: var(--accent); }
.ct-empty-filter { min-height: 28vh; border-style: solid; border-color: var(--line); }

.ct-drop-overlay { position: fixed; inset: 0; z-index: 50; background: rgba(31, 111, 235, .12); display: grid; place-items: center; pointer-events: none; }
.ct-drop-overlay > div { border: 3px dashed var(--accent); border-radius: 16px; background: rgba(255, 255, 255, .94); padding: 32px 40px; font-size: 18px; font-weight: 600; color: var(--accent); text-align: center; line-height: 1.5; }
.ct-drop-overlay small { font-size: 13px; font-weight: 400; color: var(--muted); }

.ct-uploads { position: fixed; right: 16px; bottom: 16px; z-index: 40; width: min(400px, calc(100vw - 32px)); background: var(--card); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); font-size: 13px; }
.ct-uploads header { display: flex; align-items: center; gap: 6px; padding: 8px 12px; border-bottom: 1px solid var(--line); font-weight: 600; }
.ct-uploads header > span { color: var(--muted); font-weight: 400; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ct-uploads ul { list-style: none; margin: 0; padding: 4px 0; max-height: 40vh; overflow: auto; }
.ct-uploads.collapsed ul { display: none; }
.ct-uploads.collapsed header { border-bottom: 0; }
.upload-item { padding: 6px 12px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 8px; align-items: center; }
.upload-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.upload-status { color: var(--muted); display: inline-flex; gap: 6px; align-items: center; max-width: 60vw; min-width: 0; }
.upload-status .upload-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.upload-status .btn { flex: none; }
.upload-duration { width: 74px; font: inherit; font-size: 12px; padding: 2px 6px; border: 1px solid var(--line); border-radius: 4px; }
.upload-item[data-state="ok"] .upload-status { color: var(--ok); }
.upload-item[data-state="existing"] .upload-status, .upload-item[data-state="duplicate"] .upload-status { color: var(--warn); }
.upload-item[data-state="error"] .upload-status { color: var(--bad); flex-wrap: wrap; }
.upload-item[data-state="error"] .upload-status .upload-text { white-space: normal; }
.upload-bar { grid-column: 1 / -1; height: 4px; background: var(--chip); border-radius: 2px; overflow: hidden; }
.upload-bar i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .2s; }
.upload-item[data-state="ok"] .upload-bar i { background: var(--ok); }
.upload-item[data-state="existing"] .upload-bar i, .upload-item[data-state="duplicate"] .upload-bar i { background: var(--warn); }
.upload-item[data-state="error"] .upload-bar i { background: var(--bad); }

dialog.ct-dialog { border: 0; border-radius: 10px; padding: 0; width: min(680px, calc(100vw - 32px)); max-height: calc(100vh - 32px); box-shadow: 0 24px 60px rgba(17, 24, 39, .3); color: var(--ink); background: var(--card); }
dialog.ct-dialog::backdrop { background: rgba(17, 24, 39, .45); }
.ct-dialog-body { display: flex; flex-direction: column; max-height: calc(100vh - 32px); }
.ct-dialog header { padding: 12px 18px 10px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 10px; }
.ct-dialog h2 { margin: 0; font-size: 16px; flex: 1; min-width: 0; overflow-wrap: anywhere; }
.ct-dialog h3 { margin: 14px 0 4px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.ct-dialog-main { padding: 12px 18px 14px; overflow: auto; }
.ct-dialog footer { padding: 10px 18px 12px; border-top: 1px solid var(--line); display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.ct-dialog .spacer { flex: 1; }
.ct-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.ct-form-grid .span2 { grid-column: 1 / -1; }
.ct-form-grid .field { margin-top: 10px; }
.field textarea, .field select, .field input[type="file"] { width: 100%; font: inherit; padding: 7px 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--ink); }
.field textarea { resize: vertical; font: 13px/1.5 ui-monospace, Consolas, monospace; }
.field textarea:focus, .field select:focus { outline: 2px solid var(--focus); border-color: var(--accent); }
.field small { display: block; color: var(--muted); font-size: 12px; margin-top: 4px; line-height: 1.4; }
.field .upload-bar { margin-top: 6px; }
.ct-replace { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13px; }
.ct-edit-media { display: flex; gap: 12px; align-items: center; background: var(--chip); border-radius: 8px; padding: 8px 10px; font-size: 13px; }
.ct-edit-media .asset-media { width: 144px; flex: none; border-radius: 6px; }
.ct-edit-facts { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ct-error { color: var(--bad); font-size: 13px; margin-top: 10px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.ct-error:empty { display: none; }
.ct-error .ok { color: var(--ok); }
.ct-preview-media { background: var(--media); border-radius: 8px; display: grid; place-items: center; min-height: 160px; max-height: 44vh; overflow: hidden; }
.ct-preview-media video, .ct-preview-media img { max-width: 100%; max-height: 44vh; display: block; }
.ct-preview-media .asset-play { width: 72px; height: 72px; font-size: 32px; }
.ct-meta { display: grid; grid-template-columns: max-content 1fr; gap: 3px 14px; margin: 12px 0 0; font-size: 13px; }
.ct-meta dt { color: var(--muted); white-space: nowrap; }
.ct-meta dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.ct-versions li { margin: 2px 0; }

@media (max-width: 600px) {
  :root { --page-x: 12px; --page-y: 12px; }
  .topbar { padding: 10px 12px; }
  .ct-toolbar { position: static; }
  .ct-search { max-width: none; flex-basis: 100%; }
  .ct-toolbar, .ct-row { gap: 6px; }
  .ct-uploads ul { max-height: 24vh; }
  .page-actions { width: 100%; margin-left: 0; }
  .ct-upload { width: 100%; }
  .ct-upload-tags { width: auto; flex: 1 1 140px; }
  .badge, .tag { font-size: 12.5px; }
  .page.has-uploads { padding-bottom: 40vh; }
  .ct-form-grid { grid-template-columns: 1fr; }
  .ct-edit-media { flex-wrap: wrap; }
  .ct-uploads { right: 8px; left: 8px; bottom: 8px; width: auto; }
  .ct-meta { grid-template-columns: 1fr; gap: 0; }
  .ct-meta dt { margin-top: 6px; }
}

/* ---- Locations page (the screen network) ---- */
.lc-actions-bar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lc-badge-count { font-style: normal; font-size: 11px; font-weight: 700; line-height: 1.4; margin-left: 6px; padding: 0 6px; border-radius: 9px; background: var(--chip); color: var(--muted); font-variant-numeric: tabular-nums; }
.lc-badge-count.warn { background: var(--warn); color: #fff; }
.lc-devices-button { display: inline-flex; align-items: center; }
.lc-toolbar .seg { flex: none; }

.lc-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex: none; background: #94a3b8; vertical-align: middle; margin-right: 5px; }
.lc-dot-online { background: #16a34a; }
.lc-dot-offline { background: #f59e0b; }
.lc-dot-none { background: #94a3b8; }
.lc-state { font-weight: 600; }
.lc-state-online { color: var(--ok); }
.lc-state-offline { color: var(--warn); }
.lc-state-none { color: var(--muted); }

.lc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
.lc-grid.small { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; }
.lc-card { background: var(--card); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; display: flex; flex-direction: column; min-width: 0; cursor: pointer; transition: box-shadow .15s, outline-color .2s; }
.lc-card:hover { box-shadow: var(--shadow); }
.lc-card:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.lc-card.highlight { outline: 3px solid var(--accent); outline-offset: -1px; }
.lc-row.highlight td { background: var(--chip-active); }
.lc-card.deleted { opacity: .85; }
.lc-shot { position: relative; height: 150px; background: linear-gradient(180deg, #eef2f7, #dde5ee); display: grid; place-items: center; overflow: hidden; }
.lc-grid.small .lc-shot { height: 100px; }
.lc-screen { height: calc(100% - 16px); max-width: calc(100% - 24px); background: var(--media) radial-gradient(ellipse at 30% 20%, #243042, #0f172a 70%); overflow: hidden; display: grid; place-items: center; box-shadow: 0 0 0 3px #2a3546, 0 5px 12px rgba(15, 23, 42, .35); border-radius: 3px; }
.lc-screen.portrait { aspect-ratio: 9 / 16; }
.lc-screen.landscape { aspect-ratio: 16 / 9; }
.lc-screen img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lc-initials { color: #93a8c2; font-weight: 700; font-size: 18px; letter-spacing: .08em; }
.lc-grid.small .lc-initials { font-size: 14px; }
.lc-shot > .lc-dot { position: absolute; top: 6px; left: 6px; width: 11px; height: 11px; margin: 0; box-shadow: 0 0 0 2px #fff, 0 0 0 3px rgba(15, 23, 42, .18); }
.lc-orient-badge { position: absolute; right: 5px; bottom: 5px; background: rgba(255, 255, 255, .88); color: var(--muted); font-size: 10.5px; line-height: 1.6; padding: 0 6px; border-radius: 4px; letter-spacing: .03em; }
.lc-body { padding: 7px 10px 9px; display: flex; flex-direction: column; gap: 5px; flex: 1; min-width: 0; }
.lc-name-wrap { min-width: 0; }
.lc-name { display: inline-block; max-width: 100%; font-weight: 600; font-size: 13.5px; line-height: 1.3; overflow-wrap: anywhere; cursor: text; border-radius: 4px; padding: 2px 4px; margin: -2px -4px; border: 1px dashed transparent; }
.lc-name[role="button"]:hover { background: var(--chip); border-color: var(--line); }
.lc-name-input { font: inherit; font-weight: 600; font-size: 13.5px; width: 100%; padding: 1px 4px; margin: -2px -4px; border: 1px solid var(--accent); border-radius: 4px; outline: 2px solid var(--focus); color: var(--ink); }
.lc-inline-error { color: var(--bad); font-size: 12px; margin-top: 4px; line-height: 1.35; }
.lc-opening-hours { font-size: 12.5px; line-height: 1.35; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.lc-clock { color: var(--muted); margin-right: 4px; }
.lc-tags { display: flex; flex-wrap: wrap; gap: 3px 4px; }
.lc-player { font-size: 12.5px; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; min-width: 0; }
.lc-player-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.lc-stale { background: #fdf1d4; color: var(--warn); }
.lc-behind { background: #fde2d4; color: var(--warn); }
.lc-behind-line { margin-top: 4px; }
.pl-run-source { margin: 0 0 6px; }
.lc-actions { display: flex; gap: 4px; margin-top: auto; padding-top: 6px; border-top: 1px dashed var(--line); }
.lc-actions .btn { flex: 1 1 0; padding: 4px 4px; font-size: 12px; }

.lc-table { min-width: 980px; }
.lc-table .cell-dot { width: 22px; padding-right: 0; }
.lc-table .cell-dot .lc-dot { margin: 0; }
.lc-table .cell-name { min-width: 160px; max-width: 260px; }
.lc-table .cell-name .lc-name-input { margin: 0; }
.lc-table .cell-opening-hours { white-space: nowrap; font-variant-numeric: tabular-nums; }
.lc-table .cell-zone { white-space: nowrap; font-size: 12.5px; }
.lc-table .cell-player { min-width: 150px; }
.lc-table .cell-tags { min-width: 150px; max-width: 260px; }
.lc-table .cell-tags .lc-tags { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; padding-bottom: 2px; }
.lc-table .cell-date { white-space: nowrap; color: var(--muted); }
.lc-table .cell-actions { white-space: nowrap; }
.lc-table .lc-actions { margin: 0; padding: 0; border: 0; }
.lc-table .lc-actions .btn { flex: none; padding: 3px 7px; }
.lc-table .lc-player { flex-wrap: nowrap; }
.lc-empty-first .glyph { font-size: 34px; }

/* dialogs */
dialog.lc-dialog { width: min(760px, calc(100vw - 32px)); }
.lc-fact-strip { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; font-size: 12.5px; padding: 0 0 10px; margin-bottom: 2px; }
.lc-fact-strip .lc-dot { margin-right: 0; }
.lc-fact-player { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.lc-fact-config { margin-left: auto; }
.lc-fact-sep { opacity: .5; }
.lc-tabs { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: 1px solid var(--line); padding-bottom: 8px; margin-bottom: 4px; }
.lc-panel-body { padding-top: 6px; }
.lc-hint { font-size: 12.5px; margin: 2px 0 10px; }
.lc-facts { background: var(--chip); border-radius: 8px; padding: 8px 10px; font-size: 13px; display: flex; flex-direction: column; gap: 2px; }
.lc-panel-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.lc-panel-actions .primary { font-size: 13px; padding: 5px 12px; }

/* The command channel, in the Player tab: what the screen declared it can do,
   the buttons that ask for it, and the log of what was asked. The declared
   list is set apart from the buttons on purpose — it is a fact about the
   screen, and the buttons are a thing to do, and an operator reading one is
   not yet doing the other. */
.lc-powers-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 3px; font-size: 13px; }
.lc-powers-list li { padding: 3px 8px; border-radius: 6px; background: var(--chip); }
.lc-powers-none, .lc-powers-loading, .lc-tasks-loading, .lc-tasks-none { margin: 4px 0 0; font-size: 12.5px; }
.lc-command-notice { margin-top: 10px; display: flex; gap: 8px; align-items: center; font-size: 13px; }
.lc-command-notice .btn { margin-left: auto; }
.lc-task-list li { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; }
.lc-task-list .lc-task-cancel { margin-left: auto; }
.lc-task-detail { font-style: italic; }
/* The two ends that are not an answer from the screen read quieter than the
   two that are: a cancelled task is a decision, a failed one is news. */
.lc-task-status.lc-task-failed { background: var(--bad-soft); color: var(--bad); }
.lc-task-status.lc-task-done { background: var(--ok-soft); color: var(--ok); }
.lc-task-status.lc-task-pending, .lc-task-status.lc-task-sent { background: var(--warn-soft); color: var(--warn); }
.lc-rotation-waiting, .lc-rotation-grace { padding-top: 3px; }

.lc-opening-hours-editor { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; background: var(--card); }
.lc-opening-hours-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.lc-opening-hours-grid { display: flex; flex-direction: column; gap: 3px; }
.lc-opening-hours-grid.disabled { opacity: .45; }
.lc-opening-hours-row { display: grid; grid-template-columns: 106px max-content 10px max-content 1fr; align-items: center; gap: 0 6px; }
.lc-opening-hours-editor.compact .lc-opening-hours-row { grid-template-columns: 62px max-content 10px max-content 1fr; }
.lc-day { display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; margin: 0; }
.lc-day input { margin: 0; }
.lc-day span { display: inline; font-size: 13px; color: var(--ink); margin: 0; }
.lc-hour { font: inherit; font-size: 12.5px; padding: 2px 4px; border: 1px solid var(--line); border-radius: 5px; background: var(--card); color: var(--ink); font-variant-numeric: tabular-nums; }
.lc-hour:disabled { color: var(--muted); background: var(--hover); }
.lc-dash { font-size: 12px; text-align: center; }
.lc-closed { font-size: 12px; visibility: hidden; padding-left: 6px; }
.lc-opening-hours-row.closed .lc-closed { visibility: visible; }
.lc-opening-hours-summary { margin-top: 8px; padding-top: 7px; border-top: 1px dashed var(--line); font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.lc-opening-hours-summary b { color: var(--ink); }

.lc-identity-current { display: flex; gap: 12px; align-items: center; background: var(--chip); border-radius: 8px; padding: 8px 10px; }
.lc-identity-shot { height: 90px; width: 156px; flex: none; border-radius: 6px; border: 1px solid var(--line); }
.lc-identity-facts { min-width: 0; display: flex; flex-direction: column; gap: 3px; font-size: 13px; }
.lc-identity-facts .btn { align-self: flex-start; margin-top: 3px; }
.lc-picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 6px; max-height: 230px; overflow: auto; padding: 2px; }
.lc-picker-item { font: inherit; background: var(--card); border: 1px solid var(--line); border-radius: 6px; padding: 4px; cursor: pointer; display: flex; flex-direction: column; gap: 4px; min-width: 0; text-align: left; }
.lc-picker-item:hover { border-color: var(--accent); }
.lc-picker-item.active { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: var(--chip-active); }
.lc-picker-shot { height: 62px; background: var(--media); border-radius: 4px; display: grid; place-items: center; overflow: hidden; }
.lc-picker-shot img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.lc-picker-shot .lc-initials { font-size: 13px; }
.lc-picker-name { font-size: 11.5px; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lc-picker-note { font-size: 12px; margin-top: 6px; }
.lc-new-picker .lc-picker { max-height: 170px; }

.lc-token { border: 1px solid #f0d48a; background: #fdf6e3; border-radius: 8px; padding: 8px 10px; margin-top: 10px; }
.lc-token-warn { color: var(--warn); font-size: 12.5px; margin-bottom: 6px; font-weight: 600; }
.lc-token-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.lc-token-input { flex: 1 1 260px; min-width: 0; font-size: 12px; padding: 5px 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--ink); }
.lc-copied { font-size: 12px; }

.lc-device-list { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.lc-device-list li { border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13px; background: var(--card); }
.lc-device-main { flex: 1 1 200px; min-width: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lc-device-main .muted { flex-basis: 100%; font-size: 12px; }
.lc-code-big { font: 700 20px/1.2 ui-monospace, Consolas, monospace; letter-spacing: .12em; background: var(--side); color: #fff; padding: 6px 10px; border-radius: 6px; flex: none; }
.lc-code { font: 12px ui-monospace, Consolas, monospace; background: var(--chip); padding: 1px 6px; border-radius: 4px; }
.lc-inline-form { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lc-location-select, .lc-newplayer-name { font: inherit; font-size: 12.5px; padding: 4px 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--ink); max-width: 240px; }
.lc-devices-section { margin-top: 12px; }
.lc-devices-section:first-of-type { margin-top: 0; }
.lc-status-pending { background: #fdf1d4; color: var(--warn); }
.lc-status-revoked { background: #fde8e8; color: var(--bad); }
.lc-history { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.lc-history li { padding: 5px 8px; border-left: 3px solid var(--line); background: var(--hover); border-radius: 0 6px 6px 0; }
.lc-config-versions { font-size: 12.5px; font-variant-numeric: tabular-nums; }
.lc-config-doc { margin-top: 6px; }

@media (max-width: 600px) {
  .lc-actions-bar { width: 100%; }
  .lc-actions-bar .lc-counter { flex: 1 1 100%; }
  .lc-grid, .lc-grid.small { grid-template-columns: 1fr; }
  .lc-shot, .lc-grid.small .lc-shot { height: 132px; }
  .lc-tabs .btn { flex: 1 1 auto; }
  .lc-opening-hours-row { grid-template-columns: 96px max-content 10px max-content 1fr; }
  .lc-identity-current { flex-wrap: wrap; }
  .lc-picker { grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); }
  .lc-device-list li { flex-direction: column; align-items: stretch; }
  .lc-location-select, .lc-newplayer-name { max-width: none; flex: 1 1 auto; }
}

.lc-one-line { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

/* The strip of players under the list: two columns, one row per box. Dense on
   purpose — it is counted and scanned, not read — and the identifier is a
   selectable block because it is copied into a ticket far more often than it
   is looked at. */
.lc-fleet { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--line); }
.lc-fleet-title { margin: 0; font-size: 16px; }
.lc-fleet-lede { margin: 3px 0 10px; font-size: 12.5px; }
.lc-fleet-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 18px; align-items: start; }
.lc-fleet-head { margin: 0 0 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.lc-fleet-count { font-style: normal; font-variant-numeric: tabular-nums; }
.lc-fleet-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.lc-fleet-row { display: flex; align-items: center; gap: 4px 8px; flex-wrap: wrap; padding: 5px 9px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); font-size: 13px; }
.lc-fleet-row .lc-dot { margin-right: 0; }
.lc-fleet-name { min-width: 0; font-weight: 600; overflow-wrap: anywhere; }
button.lc-fleet-name { font: inherit; font-weight: 600; background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; text-align: left; }
button.lc-fleet-name:hover { text-decoration: underline; }
.lc-fleet-where, .lc-fleet-platform { font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lc-fleet-id { margin-left: auto; font: 12px var(--data); background: var(--chip); color: var(--chip-ink); border-radius: 4px; padding: 1px 6px; overflow-wrap: anywhere; user-select: all; -webkit-user-select: all; }
.lc-fleet-id-none { color: var(--muted); }
.lc-fleet-when { font: 12px var(--data); color: var(--muted); font-variant-numeric: tabular-nums; min-width: 32px; text-align: right; }
.lc-fleet-none, .lc-fleet-limit { font-size: 12.5px; margin: 0; }
.lc-fleet-limit { margin-top: 8px; }
@media (max-width: 600px) {
  .lc-fleet-cols { grid-template-columns: 1fr; }
  .lc-fleet-id { margin-left: 0; }
}

/* ---- sub-page tabs under the title -------------------------------------- */

/* ---- content groups: the tree table ------------------------------------- */
.gr-banner { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; background: #fff7e0; border: 1px solid #f0dda6; color: var(--warn); border-radius: 6px; padding: 7px 12px; font-size: 13px; margin-bottom: 12px; }
.gr-list { background: var(--card); border: 1px solid var(--line); border-radius: 8px; overflow: auto; }
.gr-empty { padding: 40px 24px; text-align: center; color: var(--muted); }
.gr-empty h3 { margin: 0 0 6px; font-size: 16px; color: var(--ink); }
.gr-empty p { margin: 0 auto 14px; max-width: 60ch; }

.tree-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
.tree-table th { position: sticky; top: 0; z-index: 1; background: var(--hover); color: var(--muted); font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.tree-table td { padding: 5px 8px; border-bottom: 1px solid #eef1f5; vertical-align: middle; }
.tree-table .col-name { width: auto; min-width: 260px; }
.tree-table .col-num { width: 92px; }
.tree-table .col-type { width: 120px; }
.tree-table .col-window { width: 138px; }
.tree-table .col-where { width: 190px; }
.tree-table .col-toggle { width: 58px; text-align: center; }
.tree-table .col-actions { width: 96px; text-align: right; white-space: nowrap; }
.tree-row.is-parent > td { background: var(--card); }
.tree-row.is-parent.is-open > td { background: var(--hover); border-bottom-color: var(--line); }
.tree-row.is-child > td { background: #fbfcfe; }
.tree-row.is-add > td { background: #fbfcfe; padding: 2px 8px 8px 44px; }
.tree-row.is-disabled .tree-input, .tree-row.is-disabled .tree-meta, .tree-row.is-disabled .tree-range, .tree-row.is-disabled .tree-glyph, .tree-row.is-disabled .tree-thumb { opacity: .55; }

.tree-name { display: flex; align-items: center; gap: 7px; min-width: 0; }
.tree-name.is-child { padding-left: 12px; }
.tree-name-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.tree-branch { flex: none; width: 12px; height: 16px; border-left: 1px solid #ccd5e0; border-bottom: 1px solid #ccd5e0; border-bottom-left-radius: 5px; margin: -10px 0 5px 2px; }
.tree-glyph { flex: none; width: 24px; height: 24px; border-radius: 7px; display: grid; place-items: center; font-size: 13px; }
.tree-glyph.daily { color: #9a6700; background: #fff4d6; }
.tree-glyph.evergreen { color: #6b4fbb; background: #efeafb; }
.tree-thumb { flex: none; width: 44px; height: 26px; border-radius: 4px; object-fit: cover; background: var(--media); }
.tree-thumb.is-blank { display: grid; place-items: center; color: #94a3b8; font-size: 12px; }
.tree-meta { display: block; color: var(--muted); font-size: 11.5px; line-height: 1.5; overflow-wrap: anywhere; }
.tree-name + .tree-meta { padding-left: 55px; margin-top: -3px; }
.tree-meta.warn { color: var(--warn); }
.tree-range { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tree-seconds { display: flex; align-items: center; gap: 3px; color: var(--muted); font-size: 12px; }

.tree-input { font: inherit; font-size: 13px; border: 1px solid transparent; background: transparent; border-radius: 6px; padding: 5px 7px; color: var(--ink); min-height: 30px; }
.tree-input:hover:not(:disabled) { border-color: var(--line); background: var(--card); }
.tree-input:focus { outline: 2px solid var(--focus); border-color: var(--accent); background: var(--card); }
.tree-input:disabled { color: var(--muted); }
.tree-input.text { flex: 1; min-width: 0; font-weight: 600; text-overflow: ellipsis; }
.tree-row.is-child .tree-input.text { font-weight: 500; }
.tree-input.num { width: 62px; text-align: right; font-variant-numeric: tabular-nums; -moz-appearance: textfield; }
.tree-input.num::-webkit-outer-spin-button, .tree-input.num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.tree-input.select, .tree-input.date { width: 100%; font-size: 12.5px; }

.tree-icon { font: inherit; font-size: 13px; line-height: 1; width: 26px; height: 26px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer; }
.tree-icon:hover:not(:disabled) { background: var(--chip); color: var(--ink); }
.tree-icon:disabled { opacity: .3; cursor: default; }
.tree-icon.danger:hover { background: #fde8e8; color: var(--bad); }
.tree-icon:focus-visible, .tree-where:focus-visible, .tree-add:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.tree-chevron { color: var(--ink); }
.tree-where { font: inherit; text-align: left; width: 100%; border: 1px solid transparent; border-radius: 6px; background: transparent; padding: 4px 7px; cursor: pointer; color: var(--ink); }
.tree-where:hover:not(:disabled) { border-color: var(--line); background: var(--card); }
.tree-where-main { display: block; font-size: 12.5px; overflow-wrap: anywhere; }
.tree-add { font: inherit; font-size: 12.5px; border: 1px dashed var(--line); background: var(--card); color: var(--muted); border-radius: 6px; padding: 4px 10px; cursor: pointer; }
.tree-add:hover { border-color: var(--accent); color: var(--accent); }

.tree-switch { display: inline-flex; align-items: center; cursor: pointer; }
.tree-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.tree-track { width: 34px; height: 19px; border-radius: 10px; background: #cbd5e1; position: relative; transition: background .15s; }
.tree-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%; background: #fff; transition: transform .15s; }
.tree-switch input:checked + .tree-track { background: var(--ok); }
.tree-switch input:checked + .tree-track::after { transform: translateX(15px); }
.tree-switch input:focus-visible + .tree-track { outline: 2px solid var(--focus); outline-offset: 2px; }
.tree-switch input:disabled + .tree-track { opacity: .45; }


/* ---- group dialogs ------------------------------------------------------- */
.ct-field { display: flex; flex-direction: column; gap: 3px; margin-bottom: 10px; font-size: 13px; }
.ct-field > span { color: var(--muted); }
.ct-input { font: inherit; padding: 7px 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--ink); width: 100%; }
.ct-input:focus { outline: 2px solid var(--focus); border-color: var(--accent); }
.ct-input.small { width: auto; min-width: 160px; padding: 4px 8px; font-size: 12.5px; }
.ct-check { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 3px 0; }
.ct-check .tree-meta { margin-left: auto; text-align: right; }
.ct-hint { color: var(--muted); font-size: 12.5px; margin: 4px 0 10px; }
.chip-x { font: inherit; font-size: 11px; line-height: 1; border: 0; background: transparent; color: var(--muted); cursor: pointer; padding: 0 0 0 2px; }
.gr-block { border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px 12px; margin: 0 0 12px; }
.gr-block legend { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); padding: 0 4px; }
.gr-block:disabled { opacity: .5; }
.gr-tags { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.gr-tags .chip { background: var(--chip); }
.gr-locations { max-height: 210px; overflow: auto; }
.gr-preview { font-size: 13px; color: var(--muted); background: var(--hover); border-radius: 6px; padding: 8px 10px; margin: 0 0 10px; }
.gr-preview.warn { background: #fff7e0; color: var(--warn); }
.gr-picker-head { display: flex; gap: 10px; align-items: center; margin-bottom: 6px; }
.gr-picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 10px; }
.gr-pick { font: inherit; text-align: left; border: 1px solid var(--line); border-radius: 8px; background: var(--card); padding: 6px; cursor: pointer; display: flex; flex-direction: column; gap: 3px; }
.gr-pick img, .gr-pick-blank { width: 100%; height: 72px; border-radius: 5px; object-fit: cover; background: var(--media); display: grid; place-items: center; color: #94a3b8; }
.gr-pick-name { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gr-pick:hover:not(:disabled) { border-color: var(--accent); }
.gr-pick.is-chosen { border-color: var(--accent); box-shadow: 0 0 0 2px var(--chip-active); }
.gr-pick.is-in { opacity: .5; cursor: default; }

@media (max-width: 800px) {
  .tree-table .col-where, .tree-table .col-window, .tree-table .col-type { display: none; }
}

/* ---- airing orders (stage 5): the tree table and its dialog -------------- */
.cp-table .col-window { width: 132px; }
.cp-table .col-hours { width: 96px; }
.cp-table .col-num { width: 88px; }
.cp-table .col-where { width: 132px; }
.cp-table .col-state { width: 128px; text-align: left; }
.cp-table .col-actions { width: 44px; }
.cp-table .col-window .tree-meta { padding-left: 7px; }
.cp-table .tree-input.date { font-size: 12px; }
.cp-glyph { color: var(--accent); background: var(--accent-soft); }
.cp-open { color: var(--muted); flex: none; }
.cp-state { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.cp-acts { display: flex; flex-wrap: wrap; gap: 4px; }
.cp-acts .btn { padding: 2px 8px; }
.cp-act-go { border-color: var(--accent); color: var(--accent); }
.cp-act-go:hover { background: var(--chip-active); }
.cp-variant-window { white-space: nowrap; }

/* dialog: order details, variants, screens, planned time */
dialog.cp-dialog { width: min(820px, calc(100vw - 32px)); }
.cp-facts { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 12.5px; color: var(--muted); padding-bottom: 10px; }
.cp-facts .pill { margin-left: 0; }
.cp-fact { white-space: nowrap; }
.cp-fact + .cp-fact::before { content: "·"; margin-right: 8px; opacity: .6; }
.cp-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.cp-form-grid .cp-span2 { grid-column: 1 / -1; }
.cp-form-grid .ct-field.is-locked > span { opacity: .6; }
.cp-dialog .ct-input:disabled { background: var(--hover); color: var(--muted); cursor: not-allowed; }
.cp-form-grid .ct-hint { margin: 3px 0 0; }
.cp-lock { font-size: 12.5px; background: #fff7e0; border: 1px solid #f0dda6; color: var(--warn); border-radius: 6px; padding: 6px 10px; margin: 0 0 10px; }

.cp-variants { display: flex; flex-direction: column; gap: 8px; }
.cp-variant { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; background: var(--card); }
.cp-variant.is-off { background: var(--hover); }
.cp-variant.is-off .cp-variant-name, .cp-variant.is-off .cp-variant-title { color: var(--muted); }
.cp-variant-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.cp-variant-head .tree-thumb { width: 52px; height: 30px; }
.cp-variant-name { flex: 1; min-width: 0; }
.cp-variant-title { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cp-variant-order { display: flex; align-items: center; gap: 4px; flex: none; }
.cp-variant-order .ct-input.small { width: 74px; min-width: 0; }
.cp-variant-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(124px, 1fr)); gap: 0 12px; align-items: end; margin-top: 6px; }
.cp-variant-grid .ct-field { margin-bottom: 4px; }
.cp-variant > .tree-meta { padding-left: 60px; }
.cp-variant-switch { align-self: center; }
.cp-new-variants { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.cp-new-variant .cp-variant-order .tree-meta { display: inline; }

.cp-screen-picker { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; }
.cp-screen-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.cp-screen-head .ct-input.small { flex: 1 1 180px; }
.cp-screen-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
.cp-screens { max-height: 240px; overflow: auto; }
.cp-screen { border-radius: 6px; padding: 3px 6px; }
.cp-screen:hover { background: var(--hover); }
.cp-screen.is-unfit { background: #fff7e0; }
.cp-screen > span:nth-child(2) { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.cp-screen-summary { margin: 8px 0 0; }
.cp-unfit { white-space: nowrap; }

.cp-fit { border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px; font-size: 13px; background: var(--hover); margin-top: 10px; }
.cp-fit.is-ok { background: #eefaf1; border-color: #bfe6cb; }
.cp-fit.is-warn { background: #fff7e0; border-color: #f0dda6; }
.cp-fit-list { margin: 6px 0; padding-left: 18px; }
.cp-fit-list li { margin: 2px 0; }
.cp-fit-list li.warn { color: var(--warn); }

.cp-total { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; margin-bottom: 12px; }
.cp-total > div { background: var(--chip); border-radius: 8px; padding: 8px 10px; display: flex; flex-direction: column; gap: 1px; }
.cp-total > div.is-warn { background: #fff4d6; }
.cp-total b { font-size: 19px; font-variant-numeric: tabular-nums; }
.cp-plan-block { margin-top: 12px; }
.cp-plan-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.cp-plan-table th { text-align: left; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); padding: 5px 8px; border-bottom: 1px solid var(--line); }
.cp-plan-table td { padding: 4px 8px; border-bottom: 1px solid #eef1f5; }
.cp-plan-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cp-plan-table td.is-warn { color: var(--warn); font-weight: 600; }
.cp-plan-empty { margin-top: 0; }

@media (max-width: 900px) {
  .cp-table .col-hours { display: none; }
}
@media (max-width: 600px) {
  .cp-form-grid { grid-template-columns: 1fr; }
  .cp-facts { gap: 3px 6px; }
  .cp-screens { max-height: 200px; }
  .cp-total { grid-template-columns: 1fr 1fr; }
  .cp-variant-order .ct-input.small { width: 64px; }
}

/* ---- planning (step 1.4): the occupancy map, the rundown, “does it fit?” -- */
.pl-field { display: flex; flex-direction: column; gap: 2px; font-size: 12px; color: var(--muted); }
.pl-field .ct-input.small { min-width: 132px; }
.pl-field-wide .ct-input.small { min-width: 190px; max-width: 260px; }
.pl-chips { min-height: 24px; }
.pl-ask { background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 10px 14px 12px; margin-bottom: 14px; }
.pl-ask-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.pl-ask-head h2 { margin: 0; font-size: 15px; }
.pl-ask-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: 0 12px; align-items: end; }
.pl-ask-grid .ct-field { margin-bottom: 6px; }
.pl-ask-go > span { visibility: hidden; }
.pl-ask-go .primary { width: 100%; padding: 7px 10px; }
.pl-fit-answer { margin-top: 6px; }

.pl-days { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-bottom: 10px; }
.pl-days-label { margin-right: 2px; }
.pl-day { font-variant-numeric: tabular-nums; }
.pl-day b { font-weight: 600; }
.pl-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; margin: 0 0 8px; font-size: 12.5px; color: var(--muted); }
.pl-legend-item { display: inline-flex; align-items: center; gap: 5px; }
.pl-swatch { width: 14px; height: 14px; border-radius: 3px; display: inline-block; border: 1px solid rgba(17, 24, 39, .1); }

.pl-grid-wrap { margin-bottom: 16px; }
.pl-grid { width: 100%; border-collapse: separate; border-spacing: 2px; font-size: 12px; }
.pl-grid thead th { font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; padding: 4px 2px; }
.pl-grid tbody th { font-weight: 400; color: var(--ink); padding: 4px 2px; }
.pl-grid td { padding: 0; }
.pl-col-name { text-align: left; min-width: 168px; position: sticky; left: 0; background: var(--card); z-index: 1; padding-right: 8px; }
.pl-col-hour { width: 34px; text-align: center; font-variant-numeric: tabular-nums; }
.pl-col-total { width: 94px; padding-left: 6px; }
.pl-name { display: flex; flex-direction: column; min-width: 0; }
.pl-name-text { font-weight: 600; font-size: 13px; overflow-wrap: anywhere; }
.pl-cell-wrap { padding: 0; }
.pl-cell { display: block; width: 100%; min-width: 30px; height: 26px; border: 1px solid transparent; border-radius: 4px; font: inherit; font-size: 10.5px; font-variant-numeric: tabular-nums; cursor: pointer; padding: 0; }
.pl-cell:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.pl-lvl-0 { background: #f2f5f9; border-color: #e3e8ef; color: #97a2b0; }
.pl-lvl-1 { background: #dbe7fb; color: #1c2430; }
.pl-lvl-2 { background: #a9c8f6; color: #10243f; }
.pl-lvl-3 { background: #6ea3f0; color: #0b1c33; }
.pl-lvl-4 { background: #1f6feb; color: #fff; }
.pl-closed { background: repeating-linear-gradient(45deg, #e7e9ee, #e7e9ee 4px, #dfe3e9 4px, #dfe3e9 8px); color: #98a1ad; }
.pl-outside { background: transparent; color: #cdd5e0; cursor: default; line-height: 26px; text-align: center; }
.pl-has-shed { box-shadow: inset 0 0 0 2px var(--warn); }
.pl-total-bar { position: relative; display: block; height: 20px; border-radius: 4px; background: var(--chip); overflow: hidden; }
.pl-total-bar i { position: absolute; top: 0; bottom: 0; left: 0; background: #a9c8f6; }
.pl-total-bar b { position: relative; display: block; text-align: center; font-size: 11px; line-height: 20px; font-variant-numeric: tabular-nums; }
.pl-hour-facts { padding-bottom: 6px; }
.pl-hour-bar { height: 10px; border-radius: 5px; background: var(--chip); overflow: hidden; margin: 0 0 6px; }
.pl-hour-bar i { display: block; height: 100%; background: var(--accent); }
.pl-hour-list { list-style: none; margin: 4px 0 10px; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.pl-hour-list li { background: var(--hover); border-radius: 6px; padding: 4px 8px; overflow-wrap: anywhere; }
.pl-hour-list li.warn { background: #fff7e0; color: var(--warn); }
.pl-empty-wrap { background: var(--card); border: 1px solid var(--line); border-radius: 8px; }

/* ---- reports (step 1.4): planned against realized ------------------------ */
.rp-filters { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 0 12px; margin-bottom: 10px; }
.rp-filters .ct-field { margin-bottom: 8px; }
.rp-totals { margin-bottom: 12px; }
.rp-span { grid-column: 1 / -1; margin: 0; }
.rp-gran { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.rp-table-wrap { margin-bottom: 12px; max-width: 940px; }
.rp-table { min-width: 640px; }
.rp-table .rp-cell-label { font-variant-numeric: tabular-nums; white-space: nowrap; }
.rp-cell-bar { width: 150px; }
.rp-bar { position: relative; display: block; height: 18px; border-radius: 4px; background: var(--chip); overflow: hidden; }
.rp-bar i { position: absolute; top: 0; bottom: 0; left: 0; background: #bfe6cb; }
.rp-bar.is-short i { background: #f6dfae; }
.rp-bar b { position: relative; display: block; text-align: center; font-size: 11px; line-height: 18px; font-variant-numeric: tabular-nums; }
.rp-row.is-shed td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
.rp-exports { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 16px; }
.rp-reports h3 { margin: 0 0 4px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.rp-report-list { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.rp-report { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px; background: var(--card); }
.rp-report.is-failed { background: #fff7e0; border-color: #f0dda6; }
.rp-report.is-failed .pill.warn { background: var(--card); box-shadow: inset 0 0 0 1px #e6ce92; }
.rp-report-main { display: flex; flex-direction: column; flex: 1 1 220px; min-width: 0; }
.rp-report-main .warn { color: var(--warn); }
.rp-report .pill { margin-left: 0; }
.rp-two { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.rp-col h3 { margin: 0 0 6px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.rp-log-head, .rp-program-head { margin: 0 0 8px; }
.rp-hour { border: 1px solid var(--line); border-radius: 8px; background: var(--card); margin-bottom: 8px; overflow: hidden; }
.rp-hour-head { display: flex; align-items: center; gap: 8px; padding: 5px 10px; background: var(--hover); border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; }
.rp-log-items { list-style: none; margin: 0; padding: 0; }
.rp-log-item { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 4px 10px; font-size: 12.5px; }
.rp-log-item + .rp-log-item { border-top: 1px solid #f1f4f8; }
.rp-log-item.is-off { background: #fffaf0; }
.rp-log-clock { font-variant-numeric: tabular-nums; color: var(--muted); flex: none; }
.rp-log-name { font-weight: 600; flex: 1 1 130px; min-width: 0; overflow-wrap: anywhere; }
.rp-log-duration { flex: none; font-variant-numeric: tabular-nums; }
.rp-log-item .pill { margin-left: 0; }
.rp-hour-closed td { color: var(--muted); background: var(--hover); }
.rp-empty { min-height: 0; padding: 26px 18px; }

/* ---- administration (stage 8): people, rights, the trash, the machine --- */
.adm-denied { max-width: 760px; margin: 0 auto; }
.adm-list { background: transparent; border: 0; border-radius: 0; overflow: visible; }
.adm-list .table-wrap { max-width: 1000px; }
.adm-notice { margin-bottom: 12px; }
.adm-inline-field { margin-bottom: 0; }
.adm-last-super-note { max-width: 1000px; margin: 8px 0 0; }
.adm-table { min-width: 640px; }
.adm-table th, .adm-table td { padding: 6px 10px; vertical-align: middle; }
.adm-cell-name { min-width: 150px; overflow-wrap: anywhere; }
.adm-cell-date { white-space: nowrap; }
.adm-cell-actions { white-space: nowrap; }
.adm-cell-actions .btn { margin-right: 4px; }
.adm-user.is-off .adm-username { color: var(--muted); }
.adm-chips { display: flex; flex-wrap: wrap; gap: 3px; }
.adm-table .pill { margin-left: 0; margin-right: 4px; white-space: nowrap; }
.adm-group-picker, .adm-member-picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 0 14px; max-height: 208px; overflow: auto; }
.adm-super-check { margin: 6px 0 2px; }
.adm-last-super { margin-top: 0; }

.adm-group { border: 1px solid var(--line); border-radius: 8px; background: var(--card); padding: 8px 12px 10px; margin-bottom: 10px; }
.adm-group.is-open { box-shadow: var(--shadow); }
.adm-group-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.adm-group-head .tree-name-text { flex: 1; }
.adm-group h3 { margin: 12px 0 4px; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.adm-rights { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.adm-right { display: flex; align-items: center; gap: 8px; font-size: 13px; background: var(--hover); border-radius: 6px; padding: 4px 4px 4px 9px; }
.adm-right-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.adm-rights-compact { margin-top: 4px; }
.adm-rights-compact .adm-right { background: transparent; color: var(--muted); padding: 0 0 0 34px; font-size: 12.5px; }
.adm-right-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0 12px; align-items: end; margin-top: 10px; }
.adm-right-form .ct-field { margin-bottom: 6px; }
.adm-field-wide { grid-column: span 2; }
.adm-owner-check { align-self: center; }
.adm-right-go > span { visibility: hidden; }

/* THE RIGHTS TREE. One territory per block, a row per entity, a tick per
   action — and the parents carry a third state, because "some of it" is the
   answer most of the time (BIBLE 3.7, "an interface shaped like the table"). */
.adm-tree { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.adm-place { border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px 10px; }
.adm-place-head { display: flex; align-items: center; gap: 10px; }
.adm-place-all { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; cursor: pointer; }
.adm-place-all strong { overflow-wrap: anywhere; }
.adm-place-count { white-space: nowrap; font-variant-numeric: tabular-nums; }
.adm-grid { margin-top: 8px; display: flex; flex-direction: column; gap: 2px; overflow-x: auto; }
.adm-grid-head, .adm-grid-row { display: grid; grid-template-columns: minmax(132px, 1.4fr) repeat(7, minmax(58px, 1fr)); align-items: center; gap: 0 4px; }
.adm-grid-head { font-size: 11.5px; color: var(--muted); text-transform: lowercase; letter-spacing: .02em; padding-bottom: 2px; }
.adm-grid-row { border-radius: 6px; padding: 3px 0; }
.adm-grid-row:nth-child(odd) { background: var(--hover); }
.adm-grid-what { display: flex; align-items: center; gap: 8px; font-size: 12.5px; padding-left: 4px; cursor: pointer; }
.adm-grid-col { text-align: center; }
.adm-tick { cursor: pointer; }
.adm-tick-all { width: 17px; height: 17px; }
.adm-rights-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 10px; flex-wrap: wrap; }
.adm-rights-count { margin: 0; }
.adm-rights-head { margin: 14px 0 0; font-size: 13px; color: var(--muted); font-weight: 600; }
.adm-place-form { margin-top: 12px; }
.adm-right-go .btn { width: 100%; padding: 7px 10px; }
.adm-right-preview { margin: 4px 0 0; }

.adm-live { border: 1px solid var(--line); border-radius: 8px; background: var(--card); padding: 8px 12px 10px; margin-bottom: 14px; }
.adm-live-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.adm-live-head .lc-dot { margin-right: 0; }
.adm-live-hint { margin-left: auto; }
.adm-live-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; max-height: 168px; overflow: auto; font-size: 12.5px; }
.adm-live-item { display: flex; align-items: center; gap: 8px; padding: 2px 0; }
.adm-live-clock { font-variant-numeric: tabular-nums; color: var(--muted); flex: none; }
.adm-live-kind { flex: none; }
.adm-live-text { min-width: 0; overflow-wrap: anywhere; }

.adm-buttons { margin: 0 0 12px; }
.adm-result { border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px; margin-bottom: 12px; background: var(--hover); font-size: 13px; }
.adm-result.is-ok { background: #eefaf1; border-color: #bfe6cb; }
.adm-result.is-warn { background: #fff7e0; border-color: #f0dda6; color: var(--warn); }
.adm-json { margin: 6px 0 0; max-height: 180px; overflow: auto; font: 12px ui-monospace, Consolas, monospace; white-space: pre-wrap; overflow-wrap: anywhere; }
.adm-grid { align-items: start; }
.adm-card .ct-meta { margin-top: 0; }
.adm-card .pill { margin-left: 0; }
.adm-jobs-failed { margin: 8px 0 0; padding-left: 18px; font-size: 12.5px; }
.adm-jobs-failed li.warn { color: var(--warn); }
.ct-notice.adm-ok, .ct-notice.od-ok, .ct-notice.lc-ok { background: #eefaf1; border-color: #bfe6cb; color: var(--ok); }

@media (max-width: 900px) {
  .rp-two { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .pl-ask-grid { grid-template-columns: 1fr 1fr; }
  .pl-col-name { min-width: 122px; }
  .pl-field .ct-input.small, .pl-field-wide .ct-input.small { min-width: 118px; }
  .rp-filters { grid-template-columns: 1fr; }
  .rp-cell-bar { width: 104px; }
  .adm-right-form { grid-template-columns: 1fr; }
  /* On a phone the seven columns cannot fit; the grid scrolls sideways inside
     its own box rather than pushing the page over (BIBLE: the body never
     scrolls sideways). The first column stays wide enough to read. */
  .adm-grid-head, .adm-grid-row { grid-template-columns: minmax(112px, 1fr) repeat(7, 52px); }
  .adm-field-wide { grid-column: auto; }
  .adm-group-picker, .adm-member-picker { grid-template-columns: 1fr; }
  .adm-live-hint { display: none; }
}

/* Campaigns (stage 12): a campaign card, the budget bar, the table of lines. */
.od-list { background: transparent; border: 0; }
.od-card { padding: 12px 14px; }
.od-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.od-toggle { display: inline-flex; align-items: center; gap: 8px; background: none; border: 0; padding: 0; cursor: pointer; font: inherit; color: inherit; }
.od-caret { color: var(--muted); font-size: 12px; }
.od-name { font-size: 15px; }
.od-budget { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 600; }
.od-bar { position: relative; height: 6px; border-radius: 3px; background: var(--chip); margin-top: 10px; overflow: hidden; }
.od-bar span { position: absolute; inset: 0 auto 0 0; border-radius: 3px; }
.od-bar-committed { background: #d7e3f6; }
.od-bar-consumed { background: var(--accent); }
.od-bar.is-over .od-bar-committed { background: #ffe0b8; }
.od-detail { margin-top: 14px; display: grid; gap: 12px; }
.od-facts { display: flex; flex-wrap: wrap; gap: 18px; }
.od-fact { display: grid; gap: 2px; }
.od-fact b { font-size: 16px; font-variant-numeric: tabular-nums; }
.od-table td, .od-table th { vertical-align: top; }
.od-screens { display: flex; flex-wrap: wrap; gap: 4px; }
.od-cell-dates, .od-cell-rate { white-space: nowrap; }
.od-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.od-pick { display: grid; gap: 6px; max-height: 50vh; overflow: auto; }
.od-pick-row { display: grid; grid-template-columns: auto 1fr auto auto; gap: 8px; align-items: center; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; }
.od-pick-row.is-off { opacity: .55; }
.od-pick-name { display: grid; gap: 2px; }
.od-pick-rate { width: 90px; }
.od-pick-hint { grid-column: 2 / -1; }
@media (max-width: 720px) {
  .od-budget { margin-left: 0; }
  .od-pick-row { grid-template-columns: auto 1fr; }
  .od-pick-kind, .od-pick-rate { grid-column: 2; width: 100%; }
}

/* ---- system adjustments over the pages’ older rules --------------------- */
/* A table header is a label, not a title: small, uppercase, dimmed. */
.cp-plan-table th, .adm-table th, .rp-table th, .gr-table th, .ct-table th, .lc-table th, .od-table th {
  font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .07em; color: var(--muted);
  background: var(--card-2); border-bottom: 1px solid var(--line); padding: 8px 10px; text-align: left; white-space: nowrap;
}
.cp-plan-table td, .adm-table td, .rp-table td, .lc-table td, .od-table td { border-bottom: 1px solid var(--line); }
.cp-plan-table tbody tr:last-child td, .adm-table tbody tr:last-child td, .od-table tbody tr:last-child td { border-bottom: 0; }
.cp-plan-table tbody tr:hover td, .adm-table tbody tr:hover td, .od-table tbody tr:hover td { background: var(--hover); }
/* The numbers stand in a column: the same width for every digit. */
.num, .cp-plan-table .num, .od-table .num, td.num, th.num { font-variant-numeric: tabular-nums; }
.tree-meta, .ct-hint, .lc-opening-hours { font-variant-numeric: tabular-nums; }

/* The toolbar: the search takes the room, the filters sit quietly beside it. */
.ct-toolbar { background: var(--bg); border-bottom: 1px solid var(--line); padding-top: 10px; padding-bottom: 10px; }
.ct-input { border-color: var(--line-2); border-radius: var(--radius-sm); padding: 7px 11px; }
.ct-input:focus { outline: 3px solid var(--focus); outline-offset: 0; border-color: var(--accent); }
.ct-input.small { padding: 5px 9px; }
.ct-search, input[type="search"].ct-input { min-width: 260px; flex: 1 1 260px; }
.ct-counter { font-size: 12.5px; color: var(--muted); }
.ct-counter b { font-family: var(--data); font-size: 14px; color: var(--ink); font-variant-numeric: tabular-nums; }

/* Notices: a thin band, not a red block. */
.ct-notice { background: var(--bad-soft); border: 1px solid rgba(180, 35, 24, .25); border-left: 3px solid var(--bad); color: var(--bad); border-radius: var(--radius-sm); padding: 8px 12px; }
.ct-notice.adm-ok, .ct-notice.od-ok, .ct-notice.lc-ok { background: var(--ok-soft); border-color: rgba(28, 122, 70, .25); border-left-color: var(--ok); color: var(--ok); }
/* A third tone, between the two: the server explaining itself. A command
   refused because the screen never declared it, or a cancellation that lost
   the race, is not a failure of anything — dressing it in the red band would
   teach an operator to read a working guard as a defect. */
.ct-notice.lc-note { background: var(--warn-soft); border-color: rgba(138, 90, 0, .25); border-left-color: var(--warn); color: var(--warn); }

/* The dialog is the only thing that really floats. */
dialog.ct-dialog { border-radius: 12px; box-shadow: var(--shadow); background: var(--card); color: var(--ink); }
dialog.ct-dialog::backdrop { background: rgba(10, 14, 20, .55); }
.ct-dialog header { padding: 14px 20px 12px; }
.ct-dialog h2 { font-size: 16px; font-weight: 650; letter-spacing: -.01em; }
.ct-dialog h3 { font-size: 10.5px; letter-spacing: .07em; }
.ct-dialog-main { padding: 14px 20px 16px; }
.ct-dialog footer { padding: 12px 20px 14px; background: var(--card-2); }
.ct-field > span { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }

/* The empty state says what comes next, left-aligned like the rest of the page. */
.gr-empty { padding: 34px 24px 38px; text-align: left; }
.gr-empty h3 { font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.gr-empty p { margin: 0 0 14px; max-width: 62ch; }
.gr-list, .table-wrap { border-radius: var(--radius); }

/* The tabs under the title: a line, not pills. */
.page-tabs { display: flex; gap: 18px; padding: 0 var(--page-x); background: var(--card); border-bottom: 1px solid var(--line); position: sticky; top: var(--topbar-h, 56px); z-index: 2; overflow-x: auto; scrollbar-width: none; }
.page-tabs a { background: none; display: block; padding: 9px 0 8px; font-size: 13px; color: var(--muted); border-bottom: 2px solid transparent; margin-bottom: -1px; }
.page-tabs a:hover { color: var(--ink); text-decoration: none; }
.page-tabs a.active { background: none; color: var(--ink); font-weight: 600; border-bottom-color: var(--accent); }

/* A screen’s card: the thin frame, the shadow only under the cursor. */
.lc-card { border-radius: var(--radius); }
.lc-card:hover { box-shadow: var(--shadow); border-color: var(--line-2); }
.lc-shot { background: linear-gradient(180deg, var(--card-2), var(--chip)); }
.lc-body { padding: 10px 12px 12px; gap: 6px; }
.lc-name { font-size: 14px; }
.lc-actions { border-top: 1px solid var(--line); padding-top: 8px; gap: 6px; }
.lc-actions .btn { flex: 0 0 auto; }
.lc-actions .btn:first-child { flex: 1 1 auto; }
.lc-orient-badge { background: rgba(255, 255, 255, .9); font-size: 10px; text-transform: uppercase; letter-spacing: .06em; }
.lc-initials { font-family: var(--data); letter-spacing: .12em; }

/* A campaign’s budget bar: committed behind, consumed in front. */
.od-bar { background: var(--chip); }
.od-bar-committed { background: var(--accent-line); }
.od-bar-consumed { background: var(--accent); }
.od-fact b { font-family: var(--data); font-size: 17px; letter-spacing: -.01em; }
.od-name { font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.od-budget { font-family: var(--data); }

/* A tag reads as “network: metro”, not as a variable: the key small and
   dimmed, the value in ink, with no equals sign. */
.tag-key { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin-right: 5px; }
.tag.active .tag-key { color: var(--accent); opacity: .8; }
.tag-value { font-size: 12px; }

/* The occupancy map: a single ramp, from empty to full, in the accent’s tone —
   the eye reads the density, not the colours. The number in the cell stays
   mono, so that the hours line up vertically. */
.pl-cell { font-family: var(--data); letter-spacing: -.02em; }
.pl-lvl-0 { background: var(--card-2); border-color: var(--line); color: var(--muted); }
.pl-lvl-1 { background: #d8ebe9; border-color: #c6e0dd; color: #10403c; }
.pl-lvl-2 { background: #a9d4d0; border-color: #93c8c3; color: #0d3936; }
.pl-lvl-3 { background: #5fada7; border-color: #4c9d97; color: #05231f; }
.pl-lvl-4 { background: var(--accent); border-color: var(--accent); color: #fff; }
.pl-closed { background: repeating-linear-gradient(45deg, var(--chip), var(--chip) 4px, var(--line) 4px, var(--line) 8px); color: var(--muted); }
.pl-total-bar { background: var(--chip); }
.pl-total-bar i { background: var(--accent-line); }
.pl-total-bar b { font-family: var(--data); }
.pl-legend { font-size: 12px; }
.pl-legend-item { gap: 6px; }
.pl-name-text { font-size: 13px; font-weight: 600; letter-spacing: -.005em; }

/* The big numbers on the pages (planned, realized, budget) read in a column. */
.rp-fact b, .rp-facts b, .pl-fact b, .adm-card dd, .cp-total b, .lc-facts b { font-family: var(--data); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.tag-rest { color: var(--muted); border-style: dashed; cursor: default; }

/* ---- the network map (stage 13) ----------------------------------------- */
.mp-body { display: block; }
.mp-layout { display: grid; grid-template-columns: 1fr 320px; gap: 14px; align-items: stretch; }
.mp-canvas { min-height: 62vh; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); overflow: hidden; }
.mp-canvas.is-keyless { display: grid; place-items: center; padding: 26px; background: var(--card-2); }
.mp-keyless { max-width: 60ch; }
.mp-keyless h3 { margin: 0 0 6px; font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.mp-keyless p { margin: 0 0 12px; color: var(--muted); }
.mp-key-row { margin-bottom: 14px; }
.mp-key-input { min-width: 260px; flex: 1 1 260px; font-family: var(--data); }
.mp-keyless-list { display: grid; gap: 4px; padding: 0; list-style: none; }
.mp-keyless-list li { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.mp-side { border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); overflow: auto; max-height: 62vh; }
.mp-list-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--card); }
.mp-item { display: grid; gap: 2px; width: 100%; text-align: left; font: inherit; background: none; border: 0; border-bottom: 1px solid var(--line); padding: 9px 12px; cursor: pointer; }
.mp-item:hover { background: var(--hover); }
.mp-item.is-selected { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.mp-item-head { display: flex; align-items: center; gap: 7px; min-width: 0; }
.mp-item-head b { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mp-item-meta { font-size: 12px; }
.mp-info { font: 13px/1.5 var(--ui); max-width: 260px; }
.mp-info b { display: block; margin-bottom: 2px; }
.mp-info a { color: #0f6d67; }
@media (max-width: 900px) {
  .mp-layout { grid-template-columns: 1fr; }
  .mp-canvas { min-height: 46vh; }
  .mp-side { max-height: 40vh; }
}
.lc-coord { font-family: var(--data); }
.lc-maps-link { font-size: 12px; }

/* ---- Administration · Downloads ------------------------------------------
   The address baked into the packages comes first and large: it is what will
   be written into the file, and if it is not the right one, the button is not
   the one to blame. */
.adm-dl-head .adm-dl-url { margin: 2px 0 8px; font: 15px var(--data); word-break: break-all; }
.adm-card.is-off { opacity: .7; }
.adm-card .lc-panel-actions { margin-top: 12px; align-items: center; gap: 10px; }
.btn.get { background: var(--ink); color: #fff; border-color: var(--ink); text-decoration: none; }
.btn.get:hover { background: var(--ink-2); border-color: var(--ink-2); color: #fff; }
.adm-dl-steps { margin: 4px 0 0; padding-left: 18px; display: grid; gap: 6px; color: var(--ink-2); }
.adm-dl-steps li { line-height: 1.45; }

/* The button that empties the device panel sits on the left, far away from
   “Close”: a press made there by mistake would delete everything. */
.lc-devices-wipe { margin-right: auto; }
.lc-devices-wipe:disabled { opacity: .45; }

/* The stress key: it is seen once only, so it has to be plainly visible and
   copyable in one move. It stays on a line of its own, not inside a table. */
.adm-token { margin: 8px 0 2px; padding: 10px 12px; border: 1px solid var(--warn, #c9973d); border-radius: 8px; background: rgba(201, 151, 61, .08); }
.adm-token p { margin: 0 0 6px; }
.adm-token-value { display: block; margin-bottom: 8px; padding: 7px 9px; border-radius: 6px; background: rgba(0, 0, 0, .25); font-family: Consolas, "Cascadia Mono", monospace; font-size: 12.5px; word-break: break-all; user-select: all; }
.adm-token-input { flex: 1 1 200px; min-width: 160px; }

/* Administration → Stress test. Every button on this tab deletes something
   that does not come back, so what each one takes is written out beside it
   rather than left to the label: a list, not a row of red buttons. */
.adm-stress-list { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.adm-stress-item { font-size: 13px; line-height: 1.45; color: var(--ink-2); background: var(--hover); border-radius: 6px; padding: 7px 10px; overflow-wrap: anywhere; }
.adm-stress-item b { color: var(--ink); }
.adm-stress-key { flex: 1 1 240px; min-width: 160px; font-family: Consolas, "Cascadia Mono", monospace; }
.adm-stress-open-actions { margin-top: 12px; }

/* Locations → Now. Cards rather than a table: what an operator wants here is
   one screen at a glance, not a column to compare across fifty rows. The
   progress bar is the only thing that moves between two refreshes, and it has
   to — a page about "now" that looks frozen reads as broken. */
.sn-summary { margin: 0 0 10px; color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.sn-error { margin: 0 0 10px; padding: 8px 10px; border-radius: 8px; border: 1px solid var(--line-2); color: var(--ink-2); font-size: 13px; }
.sn-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.sn-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; }
.sn-card[data-state="closed"] { opacity: .72; }
.sn-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.sn-head strong { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sn-state { font-size: 12px; font-weight: 600; }
.sn-time { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.sn-item { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin: 4px 0; font-size: 13px; }
.sn-item strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sn-label { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; min-width: 34px; }
.sn-kind, .sn-secs { color: var(--muted); font-size: 12px; }
.sn-secs { font-variant-numeric: tabular-nums; }
.sn-bar { display: block; height: 4px; margin: 6px 0; border-radius: 2px; background: var(--line); overflow: hidden; }
.sn-bar span { display: block; height: 100%; background: #1c7a46; transition: width .4s linear; }
.sn-none, .sn-foot { margin: 4px 0 0; color: var(--muted); font-size: 12px; }
.sn-foot { padding-top: 6px; border-top: 1px solid var(--line); font-variant-numeric: tabular-nums; }
/* The two nights a year the clock does something an operator has to be told
   about, and the case where the clock table cannot say. It sits above
   everything else on the card because it changes how the rest of the card
   should be read; `unknown` is quieter, because it is an admission and not an
   event. */
.sn-dst { margin: 0 0 8px; padding: 6px 8px; border-radius: 6px; background: var(--warn-soft); color: var(--warn); font-size: 12px; line-height: 1.45; }
.sn-dst[data-dst="unknown"] { background: var(--chip); color: var(--ink-2); }

/* The rundown of one hour: what airs, and at which second — the seller’s own
   question, answered on the planning page from the hour the screen is served.
   The clock column is tabular so the eye reads the rhythm down the list
   instead of having to measure it. */
.pl-run { list-style: none; margin: 4px 0 10px; padding: 0; display: flex; flex-direction: column; gap: 2px; font-size: 12.5px; max-height: 280px; overflow-y: auto; }
.pl-run li { display: flex; align-items: baseline; gap: 8px; padding: 3px 8px; border-radius: 6px; background: var(--hover); }
.pl-run li.is-ad { background: #dbe7fb; }
.pl-run-at { font-variant-numeric: tabular-nums; color: var(--muted); flex: none; min-width: 52px; }
.pl-run-name { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.pl-run-len { flex: none; font-variant-numeric: tabular-nums; color: var(--muted); }

/* One screen in the report: what it was promised, what it played. */
.rp-screen-list { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.rp-screen-list li { background: var(--hover); border-radius: 6px; padding: 4px 8px; display: flex; gap: 8px; flex-wrap: wrap; align-items: baseline; }
.rp-screen-list b { flex: 1 1 140px; }

/* Giving a box a location, and replacing one (docs/player-three-parts.md 13.1,
   13.2). The picker is a list of FREE locations the server answered for what
   was typed, so it is drawn as a short list of buttons rather than a select:
   the options change as somebody types, and the one chosen has to be visible
   before the Confirm that names it. */
.lc-actions { flex-wrap: wrap; }
.lc-assign-form, .lc-find { display: flex; flex-direction: column; gap: 6px; width: 100%; min-width: 0; margin-top: 4px; }
.lc-fleet-give-form:has(.lc-assign-form), .lc-give-slot:has(.lc-assign-form), .lc-unassigned-slot:has(.lc-assign-form) { flex: 1 1 100%; }
.lc-place-input, .lc-pair-input, .lc-replace-input, .lc-unassigned-search { font: inherit; width: 100%; max-width: 420px; padding: 6px 10px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: var(--card); color: var(--ink); }
.lc-place-options, .lc-find-options { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; max-height: 220px; overflow-y: auto; }
.lc-place-option, .lc-find-option { font: inherit; font-size: 13px; width: 100%; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; text-align: left; padding: 5px 9px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--card); color: var(--ink); cursor: pointer; }
.lc-place-option:hover, .lc-find-option:hover { background: var(--hover); }
.lc-place-option.active, .lc-find-option.active { border-color: var(--accent); background: var(--accent-soft); }
.lc-place-name, .lc-find-name { font-weight: 600; overflow-wrap: anywhere; }
.lc-place-facts, .lc-find-facts { font-size: 12px; overflow-wrap: anywhere; }
.lc-place-more, .lc-place-none, .lc-find-none, .lc-find-more { font-size: 12.5px; margin: 0; }
.lc-place-said { margin: 0; font-size: 13px; color: var(--warn); }
.lc-find-title { margin: 6px 0 0; font-size: 14px; }
.lc-player-note { margin-top: 10px; }
.lc-unassigned-button { display: inline-flex; align-items: center; }
.lc-unassigned-find { display: block; margin: 0 0 6px; }
.lc-unassigned-total { margin: 4px 0; font-size: 12.5px; }
.lc-unassigned-ip { font-family: var(--data); }
.lc-replace-pair { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.lc-replace-box { flex: 1 1 200px; min-width: 0; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px 10px; background: var(--card-2); display: flex; flex-direction: column; gap: 3px; font-size: 13px; }
.lc-replace-box[data-role="old"] { border-left: 3px solid var(--warn); }
.lc-replace-box[data-role="new"] { border-left: 3px solid var(--ok); }
.lc-replace-role { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
.lc-replace-arrow { font-size: 20px; color: var(--muted); }
.lc-replace-question { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px 12px; margin: 0 0 8px; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.lc-replace-question legend { font-weight: 600; padding: 0 4px; }
.lc-replace-explain { font-size: 12.5px; margin: 0 0 6px; }

/* The alarm badge in the header and its list (alarms.js). The count is of
   lines, not screens: a site or fleet line is one. Red when the watch itself
   has stopped (A9), because then nothing else on the page can be believed. */
.alarm-badge { font: inherit; font-size: 13px; font-weight: 600; padding: 5px 11px; border-radius: 999px; border: 1px solid var(--line); background: var(--chip); color: var(--chip-ink); cursor: pointer; white-space: nowrap; }
.alarm-badge.alarm-ok { color: var(--ok); background: var(--ok-soft); border-color: transparent; }
.alarm-badge.alarm-warn { color: var(--warn); background: var(--warn-soft); border-color: transparent; }
.alarm-badge.alarm-fault { color: var(--bad); background: var(--bad-soft); border-color: var(--bad); }
.alarm-badge.alarm-dead { color: #fff; background: var(--bad); border-color: var(--bad); }
body.alarms-dead .topbar { box-shadow: inset 0 -3px 0 var(--bad); }
.alarm-list, .alarm-devices { list-style: none; margin: 0; padding: 0; }
.alarm-line { padding: 9px 0 9px 12px; border-bottom: 1px solid var(--line); border-left: 3px solid var(--warn); }
.alarm-line.alarm-fault { border-left-color: var(--bad); }
.alarm-line.alarm-nested { margin-left: 8px; }
.alarm-sentence { font-weight: 600; overflow-wrap: anywhere; }
.alarm-meta { font-size: 12px; margin-top: 2px; }
.alarm-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.alarm-devices { margin-top: 6px; }
.alarm-note { margin: 0 0 8px; font-size: 13px; }
/* The Locations header counts (locations.js): each one a filter. */
.lc-counts { display: flex; flex-wrap: wrap; gap: 6px; }
.lc-count { font: inherit; font-size: 12.5px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); color: var(--ink-2); cursor: pointer; }
.lc-count b { font-variant-numeric: tabular-nums; }
.lc-count.active { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.lc-count.warn b { color: var(--warn); }
/* What this screen said (Player tab). */
.lc-said-list { list-style: none; margin: 0; padding: 0; font-size: 12.5px; max-height: 320px; overflow: auto; }
.lc-said-list li { padding: 4px 0; border-bottom: 1px solid var(--line); display: flex; gap: 8px; flex-wrap: wrap; }
.lc-said-kind { font-weight: 600; }
.lc-said-payload { color: var(--muted); font-family: var(--data); overflow-wrap: anywhere; }

/* ---- a device's own states, the proof owed, the paste-list (slice F) -------
   docs/player-three-parts.md 5.9-5.11 and 13.1-13.3: each state a device row
   carries is one sentence under it, in the warning colour when it asks for a
   decision; the fleet lines sit beside the header counts. */
.lc-counts-row { display: flex; flex-wrap: wrap; gap: 6px; }
.lc-fleet-lines:empty { display: none; }
.lc-states { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; flex: 1 1 100%; }
.lc-state-line { font-size: 12.5px; color: var(--warn); }
/* Inside a device row, which is itself a list item with a border: a state is a
   sentence under the row, not a row of its own. */
.lc-device-list .lc-states li, .lc-device-list li .lc-states li { border: 0; padding: 0; background: none; display: block; border-radius: 0; }
.lc-state-line.lc-state-let-back-in, .lc-state-line.lc-state-allow-pickup, .lc-state-line.lc-state-scheduled { color: var(--ink-2); }
.lc-state-line.lc-state-owed { color: var(--ink-2); }
.lc-devices-bulk:empty { display: none; }
.lc-devices-bulk { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 8px; }
.lc-owed-here { margin-top: 10px; }
.lc-owed-here-title { font-size: 13px; margin: 0 0 4px; }
.lc-owed-here-list { list-style: none; margin: 0; padding: 0; font-size: 12.5px; }
.lc-owed-here-list li { padding: 3px 0; border-bottom: 1px solid var(--line); }
.lc-paste-text { width: 100%; font: 13px/1.5 var(--data); box-sizing: border-box; }
.lc-paste-lines { margin: 8px 0 0; padding-left: 22px; font-size: 12.5px; max-height: 320px; overflow: auto; }
.lc-paste-line { padding: 2px 0; }
.lc-paste-line.lc-paste-refused .lc-paste-says { color: var(--warn); }
.lc-paste-line.lc-paste-paired .lc-paste-says, .lc-paste-line.lc-paste-replaced .lc-paste-says { color: var(--ok); }
.lc-paste-source { font-size: 12px; }
.lc-staged-batch { margin: 0 0 12px; }
.lc-staged-batch h3 { font-size: 13px; margin: 0 0 4px; }
.lc-staged-batch .lc-staged-install { margin-top: 6px; }
.lc-unassigned-tools { align-items: center; }
.lc-unassigned-tools .lc-unassigned-find { flex: 1 1 240px; }

/* Administration → Storage: the R2 form, at a reading width. */
.adm-storage-form { display: grid; gap: 12px; max-width: 44rem; }
.adm-storage-switch { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.adm-storage-actions { gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.adm-storage-cors { max-width: 44rem; }


/* Cloudflare: the connection, what was made for R2, the usage. */
.cf-grid { gap: 16px; }
.cf-form { display: grid; gap: 12px; max-width: 44rem; }
.cf-actions { gap: 8px; flex-wrap: wrap; margin-top: 8px; align-items: center; }
.cf-accounts { display: grid; gap: 6px; margin: 8px 0; }
.cf-account code { font-size: 12px; color: var(--muted, #666); }
.cf-summary { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 8px 0; }
.cf-summary dt { font-weight: 600; }
.cf-summary dd { margin: 0; overflow-wrap: anywhere; }
.cf-steps { margin: 8px 0 0; padding-left: 20px; font-size: 13px; }
.cf-steps li { margin: 2px 0; }
.cf-steps li.is-ok strong { color: var(--ok, #1a7f37); }
.cf-steps li.is-warn strong { color: var(--warn); }
.cf-card .ct-hint.is-warn { color: var(--warn); }
.cf-usage { border-collapse: collapse; width: 100%; font-size: 13px; margin: 8px 0; }
.cf-usage th, .cf-usage td { text-align: right; padding: 4px 8px; border-bottom: 1px solid var(--line, #e5e5e5); }
.cf-usage th:first-child, .cf-usage td:first-child { text-align: left; }
.cf-usage .cf-total td { font-weight: 600; }
.cf-estimate strong { font-size: 18px; }
.cf-again { margin-top: 12px; }
.cf-switch { display: flex; align-items: center; gap: 8px; margin: 8px 0; flex-wrap: wrap; }

/* Cloudflare tab, second pass after looking at it (29 September 2026): two
   cards side by side, the usage across the whole width; ids in monospace on a
   line of their own; numbers never broken. */
.grid.cf-grid { grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr)); align-items: start; }
.cf-table-wrap { overflow-x: auto; }
@media (max-width: 480px) { .cf-summary { grid-template-columns: 1fr; } .cf-summary dt { margin-top: 6px; } }
.cf-wide { grid-column: 1 / -1; }
.cf-summary { grid-template-columns: 7rem 1fr; }
.cf-summary dd { display: flex; flex-direction: column; gap: 2px; }
.cf-id { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; overflow-wrap: anywhere; color: var(--muted, #555); }
.cf-made { margin: 8px 0; font-size: 13px; }
.cf-made summary { cursor: pointer; color: var(--ok, #1a7f37); }
.cf-made.is-warn summary { color: var(--warn); }
.cf-usage td, .cf-usage th { white-space: nowrap; }
.cf-usage td:first-child .cf-id { color: inherit; }

/* ===== HORIZONTAL CARD (.hcard) — the panel's card layout from 29 September 2026 =====
   The owner: cards are horizontal bands, and on a narrow (phone) screen they
   rearrange into a column. Every menu takes this layout when it is next
   revised. A card is:  header (title + its state) | body (fields across) | actions.
     <section class="card hcard">
       <header class="hcard-head"><h2>Title</h2> …state…</header>
       <div class="hcard-body"><div class="hcard-fields"><div class="hcard-field">…</div>…</div> …</div>
       <div class="hcard-actions"> …buttons… </div>
     </section>                                                                   */
.hcard { display: grid; grid-template-columns: minmax(11rem, 14rem) minmax(0, 1fr) auto; gap: 12px 28px; align-items: start; margin: 0 0 14px; }
.hcard-head { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.hcard-head h2 { margin: 0; }
.hcard-body { min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.hcard-fields { display: flex; flex-wrap: wrap; gap: 14px 36px; }
.hcard-field { display: flex; flex-direction: column; gap: 2px; min-width: 12rem; max-width: 100%; }
.hcard-label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted, #666); }
.hcard-actions { display: flex; flex-direction: column; gap: 8px; align-items: stretch; min-width: 9rem; }
.hcard-actions > * { white-space: nowrap; }
@media (max-width: 760px) {
  .hcard { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .hcard-head { flex-direction: row; align-items: center; justify-content: space-between; flex-wrap: wrap; }
  .hcard-actions { flex-direction: row; flex-wrap: wrap; min-width: 0; }
  .hcard-field { min-width: 0; }
}
/* The Cloudflare tab in that layout: one band per card, one under the other. */
.grid.cf-grid { grid-template-columns: minmax(0, 1fr); gap: 0; }
.cf-served { display: flex; flex-direction: column; gap: 4px; }
.cf-total-usd { font-size: 22px; }
.hcard .cf-form { display: flex; flex-wrap: wrap; gap: 10px 16px; max-width: none; align-items: flex-start; }
.hcard .cf-form > .cf-field { flex: 1 1 16rem; min-width: 0; }
.hcard .cf-form > .ct-error, .hcard .cf-form > .cf-ok, .hcard .cf-form > .cf-form-actions { flex: 1 0 100%; }
.cf-form-actions > button { flex: none; }
.hcard-head .pill { align-self: flex-start; }
.grid.cf-grid .hcard { margin-bottom: 14px; }

/* ===== THE i AND ITS BALLOON (BIBLE §3.9) — details on demand, any page =====
   <span class="info-wrap"><button class="info-i" popovertarget="x">i</button>
   <div id="x" popover class="info-balloon">…</div></span>                        */
.info-wrap { display: inline-flex; align-items: center; }
.info-i { width: 20px; height: 20px; padding: 0; border-radius: 50%; border: 1px solid var(--line, #cfd6dd); background: var(--card, #fff);
  color: var(--muted, #555); font: italic 600 12px/18px Georgia, 'Times New Roman', serif; cursor: pointer; flex: none; }
.info-i:hover, .info-i:focus-visible { border-color: var(--accent, #0f6e67); color: var(--accent, #0f6e67); }
.info-balloon { position: fixed; margin: 0; inset: auto; max-height: 70vh; overflow: auto; padding: 12px 14px; border: 1px solid var(--line, #d8dee4);
  border-radius: 10px; background: var(--card, #fff); box-shadow: 0 10px 30px rgba(15, 30, 45, .18); font-size: 13px; line-height: 1.45; }
.info-balloon:not([popover]) { z-index: 50; }
.info-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 4px 12px; margin: 0; }
.info-facts dt { color: var(--muted, #666); }
.info-facts dd { margin: 0; overflow-wrap: anywhere; }
.info-section { margin-top: 10px; }
.info-title { font-weight: 600; margin-bottom: 2px; }
/* Cloudflare, condensed */
.cf-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cf-form { display: grid; gap: 10px; max-width: 34rem; }
.cf-form-actions { display: flex; gap: 8px; }
.cf-ok { color: var(--ok, #1a7f37); margin: 0; }
.pill.warn { background: #fff4d6; color: #7a5a00; }
.pill.bad { background: #fde8e8; color: #9b1c1c; }
.cf-notice.is-error { border-color: #f3c1c1; background: #fdf0f0; }
.info-balloon .cf-usage { width: 100%; table-layout: auto; }
.info-balloon .cf-usage td, .info-balloon .cf-usage th { white-space: normal; padding: 4px 6px; }
.info-balloon .cf-usage td:first-child .cf-id { overflow-wrap: anywhere; }
/* COMPACT (BIBLE §3.9, the owner, 29 September 2026): a card that is well is ONE
   line — title and its state side by side, the content on the same line, the
   action at the right — at the height its content needs and no more. */
.hcard { padding: 10px 18px; align-items: center; row-gap: 8px; }
.hcard-head { flex-direction: row; align-items: center; gap: 10px; flex-wrap: wrap; }
.hcard-head h2 { font-size: 15px; }
.hcard-head .pill { align-self: center; }
.hcard-actions { flex-direction: row; min-width: 0; align-items: center; }
.grid.cf-grid .hcard { margin-bottom: 10px; }
@media (max-width: 760px) { .hcard-head { justify-content: flex-start; } }
.cf-usage .cf-cost td { font-weight: 600; border-top: 2px solid var(--line, #d8dee4); cursor: help; }
.cf-total-usd[title] { cursor: help; }
.info-balloon .cf-usage-refresh { margin-top: 8px; }
.has-tip { cursor: help; text-decoration: underline dotted rgba(0,0,0,.35); text-underline-offset: 3px; }
.tip-balloon { font-size: 12px; padding: 8px 10px; }
.cf-how { display: inline-block; margin: 6px 12px 0 0; font-size: 12px; color: var(--muted, #666); }
.info-balloon .cf-usage td, .info-balloon .cf-usage th { white-space: nowrap; }
.info-balloon .cf-usage td:first-child, .info-balloon .cf-usage th:first-child { white-space: normal; }
@media (max-width: 480px) { .info-balloon .cf-usage { font-size: 12px; } .info-balloon .cf-usage td, .info-balloon .cf-usage th { padding: 3px 4px; } .info-balloon .cf-usage .cf-id { font-size: 11px; } }
/* The balloon's own tools, top right: an action of its own (↻) and its × */
.info-tools { display: flex; justify-content: flex-end; gap: 4px; margin: -4px -6px 4px 0; }
.info-tool { width: 24px; height: 24px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--muted, #666); font-size: 16px; line-height: 24px; cursor: pointer; }
.info-tool:hover, .info-tool:focus-visible { background: var(--line, #eef1f4); color: var(--ink, #111); }
.info-tool:disabled { opacity: .5; cursor: default; }

/* ===== Clients (Campaigns → Clients) ===== */
.cl-form { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: 10px 14px; }
.cl-card .hcard-body { justify-content: center; }

.ct-narrow { max-width: 7rem; }

/* ===== The order wizard (Campaigns → New order) ===== */
.ow-card { margin: 0 0 14px; }
.ow-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 20px; margin-bottom: 12px; }
.ow-head h2 { margin: 0; }
.ow-steps { display: flex; flex-wrap: wrap; gap: 6px 14px; list-style: none; margin: 0; padding: 0; font-size: 12.5px; color: var(--muted); }
.ow-steps li b { display: inline-grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: var(--chip); font-size: 11px; }
.ow-steps li.is-now { color: var(--ink); font-weight: 600; }
.ow-steps li.is-now b { background: var(--ink); color: #fff; }
.ow-steps li.is-done b { background: var(--ok-soft); color: var(--ok); }
.ow-body { display: flex; flex-direction: column; gap: 10px; }
.ow-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.ow-films, .ow-screens { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr)); gap: 6px 14px; }
.ow-film { display: flex; align-items: center; gap: 10px; padding: 5px 8px; border: 1px solid var(--line); border-radius: 6px; }
.ow-film.is-chosen { border-color: var(--ink-2); background: var(--chip); }
/* The whole name, wrapped if it must: a film is chosen by its name. */
.ow-film-name { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.ow-film .pill { flex: 0 0 auto; margin-left: 0; }
.ow-film-seconds { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.ow-seconds { width: 4.2rem; }
.ow-upload { display: none; }
.ow-upload-label { cursor: pointer; }
.ow-group { display: flex; flex-direction: column; gap: 6px; }
.ow-rows td { padding: 4px 6px; }
.ow-cell { width: 100%; min-width: 4.5rem; }
.ow-cell.is-bad { border-color: var(--bad); background: var(--bad-soft); }
.ow-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
@media (max-width: 640px) { .ow-rows thead { display: none; } .ow-rows tr { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin-bottom: 10px; } .ow-rows td:first-child { grid-column: 1 / -1; } }
.ow-rows tr.is-clash td { background: var(--warn-soft); }
/* The pickers (Assets and Locations in the order wizard) */
.ow-embed { border-top: 1px solid var(--line); padding-top: 8px; }
.ow-chosen { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; min-height: 30px; }
.ow-chip { display: inline-flex; align-items: center; gap: 6px; padding: 2px 4px 2px 10px; border: 1px solid var(--line-2); border-radius: 999px; background: var(--chip); }
.ow-chip .pill { margin-left: 0; }
.asset-card.is-picked { outline: 2px solid var(--ink); outline-offset: -2px; }
.asset-row.is-picked td { background: var(--chip); }
.lc-pick-table { width: 100%; border-collapse: collapse; }
.lc-pick-table th, .lc-pick-table td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.lc-pick-row { cursor: pointer; }
.lc-pick-row.is-picked td { background: var(--chip); }
.lc-pick-name { font-weight: 600; }

.adm-horizons-row { display: flex; flex-wrap: wrap; gap: 10px 16px; }
.adm-horizons-row .adm-horizon { width: 6.5rem; }

/* A function the person does not hold (app/public/app.js `guard`): shown, greyed,
   and saying why on a tap instead of acting. */
.is-forbidden, .is-forbidden:hover { opacity: .45; cursor: not-allowed; filter: grayscale(1); }
.page-forbidden { color: var(--muted, #57606a); }

/* THE RIGHTS OF ONE USER (pages/rights-editor.js): one line per node, folders
   that open, the objects beside it; on a phone the two columns stack. */
.rt-dialog { width: min(1100px, 96vw); }
.rt-dialog header { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.rt-clone { display: inline-flex; gap: 6px; align-items: center; margin-left: auto; }
.rt-main { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 16px; max-height: 68vh; }
.rt-tree { overflow: auto; border: 1px solid var(--line, #d8dee4); border-radius: 8px; padding: 6px; }
.rt-tree ul { list-style: none; margin: 0; padding-left: 18px; }
.rt-tree > ul { padding-left: 0; }
.rt-line { display: flex; align-items: center; gap: 8px; min-height: 30px; padding: 2px 4px; border-radius: 6px; }
.rt-line:hover { background: var(--hover, #f3f5f7); }
.rt-folder > summary { cursor: pointer; list-style: none; }
.rt-folder > summary::-webkit-details-marker { display: none; }
.rt-folder > summary::before { content: '▸'; width: 12px; color: var(--muted, #57606a); transition: transform .12s; }
.rt-folder[open] > summary::before { transform: rotate(90deg); }
.rt-leaf > .rt-line { padding-left: 24px; }
.rt-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rt-danger { margin-left: 6px; color: var(--danger, #cf222e); font-weight: 700; }
.rt-tick.is-covered { opacity: .6; }
.rt-objects, .rt-who { border: 1px solid var(--line, #d8dee4); background: transparent; border-radius: 999px; font-size: 12px; padding: 1px 8px; cursor: pointer; }
.rt-objects.is-set { border-color: var(--accent, #0969da); color: var(--accent, #0969da); }
.rt-scopes { overflow: auto; }
.rt-scopes h3 { margin: 4px 0 8px; font-size: 14px; }
.rt-scope-line { display: flex; align-items: center; gap: 8px; min-height: 32px; border-bottom: 1px solid var(--line, #eef1f4); }
.rt-scope-value.warn { color: var(--danger, #cf222e); }
.rt-scope-narrow { font-size: 12px; color: var(--muted, #57606a); }
.rt-scope-head { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
.rt-scope-dialog { width: min(1000px, 94vw); }
.rt-pick-list { list-style: none; padding: 0; max-height: 50vh; overflow: auto; }
.rt-hint { font-size: 12px; }
@media (max-width: 720px) { .rt-main { grid-template-columns: 1fr; max-height: none; } .rt-clone { margin-left: 0; } }
.adm-cell-actions { white-space: nowrap; }
.rt-who { color: var(--muted, #57606a); }
/* Nothing repeated (BIBLE §3.9): the objects and who of a node show on the row
   under the pointer or the focus; a touch screen, which has no hover, keeps them.
   Objects already chosen on a node always show. */
@media (hover: hover) {
  .rt-line .rt-who, .rt-line .rt-objects:not(.is-set) { opacity: 0; }
  .rt-line:hover .rt-who, .rt-line:hover .rt-objects, .rt-line:focus-within .rt-who, .rt-line:focus-within .rt-objects { opacity: 1; }
}

/* THE PEOPLE OF A CAMPAIGN (pages/campaigns.js openPeople). */
.cp-people-dialog { width: min(620px, 94vw); }
.cp-people, .cp-people-found { list-style: none; padding: 0; margin: 8px 0; }
.cp-people-row { display: flex; align-items: center; gap: 8px; min-height: 36px; border-bottom: 1px solid var(--line, #eef1f4); }
.cp-people-found li { display: inline-block; margin: 0 6px 6px 0; }

/* DELEGATION (app.js openDelegations). */
.dg-dialog { width: min(760px, 94vw); }
.dg-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0; }
.dg-row { display: flex; align-items: center; gap: 8px; margin: 6px 0; }
.dg-list h3 { font-size: 13px; margin: 12px 0 4px; }

/* What the server said without anything on the page to say it in (app.js toast). */
.app-toast { position: fixed; right: 16px; bottom: 16px; max-width: min(420px, calc(100vw - 32px)); padding: 10px 14px; border-radius: 8px;
  background: var(--ink, #1f2328); color: #fff; font-size: 13px; box-shadow: 0 6px 24px rgba(0,0,0,.25); z-index: 50; }

/* APPROVALS (admin.js renderApprovals). */
.adm-approval { display: flex; align-items: center; gap: 8px; margin: 6px 0; }
.adm-level-line { display: flex; align-items: center; gap: 8px; min-height: 34px; border-bottom: 1px solid var(--line, #eef1f4); }
/* The trash: how long it keeps, beside the list it governs (admin.js renderTrash). */
.adm-keep-row { display: inline-flex; align-items: center; gap: 6px; }
.ct-input.adm-keep-days { width: 5.5em; }
/* The live stream's quiet bar (app.js showLiveBar): somebody else changed what this page shows. */
.live-bar { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; padding: 8px 12px; border-radius: var(--radius-sm); background: var(--warn-soft); color: var(--warn); font-size: 13px; }
.live-bar[hidden] { display: none; }
.live-bar .live-text { flex: 1; min-width: 0; }
.live-bar .live-close { background: none; border: 0; color: inherit; font-size: 16px; cursor: pointer; padding: 0 4px; }
