/* ===================================================================
   SQUIDDLR — persistent app shell (top nav + left sidebar + footer)
   Loaded on every admin page alongside squiddlr.css.
   =================================================================== */

/* Hide the whole app shell until authenticated; shared.js adds .authed
   to <body> once a valid secret is present. Every shell page should
   include this file instead of repeating the rule inline. */
body:not(.authed) > header.app-header,
body:not(.authed) .site-chrome,
body:not(.authed) .shell-topnav,
body:not(.authed) .shell-crumbs,
body:not(.authed) > .subtabs,
body:not(.authed) > .tabs,
body:not(.authed) > main,
body:not(.authed) > .shell-body,
body:not(.authed) > .shell-footer,
body:not(.authed) > #squiddlr-helper { display: none !important; }
/* Role-only navigation stays hidden before auth resolves, including when
   .side-btn/.topnav-btn normally set display:flex/block. */
[data-shell-instructor][hidden],
[data-shell-collaborators][hidden],
[data-shell-staff][hidden],
[data-shell-href][hidden] { display: none !important; }

/* ---------------------------------------------------------------------
   Top navbar — the ONE canonical site nav, shared by every page.
   A single rounded-pill bar floating over the ocean background: the
   Squiddlr mascot on the left, then the top-level section buttons as
   equal-width teal pills that touch edge-to-edge (no gaps, no separate
   header row, no divider). This is the single source of truth for the
   bar's look: shell.js generates this markup on shell pages, and
   welcome.html hand-writes the same .shell-topnav / .topnav-brand /
   .topnav-btn markup for the splash (it can't call renderShell() without
   duplicating its custom hero/footer). Same classes -> identical bar.
   --------------------------------------------------------------------- */
/* Header + main navbar travel together. The bar stays on screen while
   a long page scrolls. Lecture status headers offset themselves by
   --site-chrome-offset so they do not slide underneath this bar. */
.site-chrome {
  position: sticky;
  top: 0;
  z-index: 50;
  background: linear-gradient(180deg, rgba(6, 11, 20, 0.92), rgba(6, 11, 20, 0.78));
  padding-bottom: 8px;
}
.site-header {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 12px 16px 0; padding: 8px 16px;
  background: rgba(10, 18, 32, 0.88);
  border: 1px solid var(--ink-300); border-radius: 16px;
}
.site-header-brand {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; color: inherit;
}
.site-header-brand img { height: 36px; width: auto; }
.site-header-word {
  display: block; font-family: var(--f-script); color: var(--teal-400);
  font-size: 1.45em; line-height: 1;
}
.site-header-tag {
  display: block; font-family: var(--f-display); font-size: 0.75em; color: var(--fog-300);
}
.shell-topnav {
  display: flex; align-items: stretch; gap: 12px;
  margin: 8px 16px 0; padding: 10px 14px;
  background: rgba(10, 18, 32, 0.72); backdrop-filter: blur(8px);
  border: 1px solid var(--ink-300); border-radius: 999px;
  box-shadow: var(--shadow-md);
  position: relative; z-index: 2;
}
.shell-topnav .topnav-brand {
  display: flex; align-items: center; justify-content: center;
  flex: none; padding: 0 6px;
}
.shell-topnav .topnav-brand img {
  height: 48px; width: auto;
  filter: drop-shadow(0 2px 6px rgba(79, 209, 197, 0.45));
}
.shell-topnav a.topnav-btn {
  flex: 1 1 0; /* equal width, fill the bar */
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 12px 10px; border-radius: 999px;
  background: linear-gradient(180deg, var(--teal-700), var(--teal-500));
  color: #06281c; text-decoration: none;
  font-family: var(--f-display); font-size: 0.95em; font-weight: 700;
  border: 1px solid var(--teal-400);
  transition: transform var(--transition), filter var(--transition), box-shadow var(--transition);
}
.shell-topnav a.topnav-btn:hover { transform: translateY(-1px); filter: brightness(1.08); }
/* Current section: same pill shape/size, just a brighter face + inset ring
   so it reads as "you are here" without breaking the seamless bar. */
.shell-topnav a.topnav-btn.active {
  filter: brightness(1.12);
  box-shadow: inset 0 0 0 2px var(--amber-400);
}

/* User chip — name + role + Sign out button, right-aligned inside the
   topnav pill. Populated asynchronously by _mountUserChip() in shell.js;
   stays hidden until /auth/me confirms a session. */
.shell-topnav .topnav-user {
  margin-left: 0; flex: none;
  display: flex; align-items: center; gap: 8px;
  padding: 0 6px 0 12px;
  border-left: 1px solid var(--ink-300);
}
.shell-topnav .topnav-user[hidden] { display: none; }
.shell-topnav .topnav-user-name {
  font-family: var(--f-display); font-weight: 700; font-size: 0.9em;
  color: var(--fog-100); white-space: nowrap;
  max-width: 180px; overflow: hidden; text-overflow: ellipsis;
}
.shell-topnav .topnav-user-role {
  font-family: var(--f-display); font-size: 0.68em; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--teal-400);
  padding: 3px 8px; border-radius: 999px;
  background: rgba(79, 209, 197, 0.14);
  border: 1px solid rgba(79, 209, 197, 0.35);
}
.shell-topnav .topnav-user-role[hidden] { display: none; }
.shell-topnav .topnav-user-signout {
  font-family: var(--f-display); font-size: 0.82em; font-weight: 700;
  padding: 7px 12px; border-radius: 999px; cursor: pointer;
  color: var(--fog-100); background: transparent;
  border: 1px solid var(--ink-300);
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.shell-topnav .topnav-user-signout:hover {
  color: var(--amber-400); border-color: var(--amber-400);
  background: rgba(255, 184, 77, 0.08);
}
.shell-topnav .topnav-user-signout:focus-visible {
  outline: 2px solid var(--amber-400); outline-offset: 2px;
}

/* Bug icon — directly in the top pill and the footer, not only in Help.
   Opaque fill so the glyph stays readable over the ocean photo.
   #E6EAF1 on #0A1220 is about 15:1. Hover is #06281c on #4FD1C5, about 8:1. */
.shell-topnav .topnav-tools {
  margin-left: auto; flex: none;
  display: flex; align-items: center; gap: 8px;
}
a.bug-report-btn,
a.bug-report-btn:link,
a.bug-report-btn:visited {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 44px; height: 44px; min-width: 44px; min-height: 44px;
  border-radius: 999px; text-decoration: none; cursor: pointer;
  color: #E6EAF1;
  background: #0A1220;
  border: 2px solid #4FD1C5;
}
a.bug-report-btn:hover {
  color: #06281c;
  background: #4FD1C5;
  text-decoration: none;
}
a.bug-report-btn:focus-visible {
  outline: 2px solid #F4B860; outline-offset: 2px;
}
.bug-report-glyph { display: block; }
.bug-report-label {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.bug-list-wrap { display: inline-flex; align-items: center; }
a.bug-list-link,
a.bug-list-link:link,
a.bug-list-link:visited {
  color: #E6EAF1; background: #0A1220;
  border: 1px solid #4FD1C5; border-radius: 999px;
  padding: 8px 12px; font-family: var(--f-display); font-weight: 700;
  font-size: 0.85em; line-height: 1.2; text-decoration: none; white-space: nowrap;
}
a.bug-list-link:hover { color: #06281c; background: #4FD1C5; text-decoration: none; }
a.bug-list-link:focus-visible { outline: 2px solid #F4B860; outline-offset: 2px; }

/* ---------------------------------------------------------------------
   Sub-tabs — flat peer-level nav directly under .shell-topnav for pages
   with multiple sibling sub-sections in one main body (Course Builder:
   Instructor/Textbook/Supplies/Schedule-Topics/Syllabus). One reusable
   component; do not roll page-specific tab variants. Panel switching
   reuses .shell-panel/.shell-panel.active (defined below).
   --------------------------------------------------------------------- */
.subtabs {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin: 0 16px 16px; padding: 0 16px;
}
.subtabs .subtab-btn {
  padding: 9px 18px; border: 1px solid var(--ink-300); background: var(--ink-100);
  color: var(--fog-200); border-radius: var(--radius-sm); cursor: pointer;
  font-family: var(--f-display); font-size: 0.9em; font-weight: 600;
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.subtabs .subtab-btn:hover { border-color: var(--teal-500); color: var(--teal-400); }
.subtabs .subtab-btn.active {
  background: rgba(79,209,197,0.14); border-color: var(--teal-400); color: var(--teal-400);
}
/* Inline course-picker re-homed into a .subtabs row (Textbook & Supplies,
   Schedule & Topics both still carry a #courseSelect). Pushed to the row's
   right edge via margin-left:auto; label sits beside the select instead of
   stacked above it, unlike the sidebar's .shell-course-picker slot. */
.subtabs .subtabs-picker {
  margin-left: auto; display: flex; align-items: center; gap: 8px;
}
.subtabs .subtabs-picker label.shell-picker-label {
  margin-bottom: 0; white-space: nowrap;
  font-size: 0.72em; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--fog-400); font-family: var(--f-display);
}
.subtabs .subtabs-picker select {
  width: auto; min-width: 200px; padding: 7px 10px;
  background: var(--ink-100); border: 1px solid var(--ink-300);
  border-radius: var(--radius-sm); color: var(--fog-100);
  font-family: var(--f-body); font-size: 0.85em;
}

.shell-body { display: flex; align-items: flex-start; position: relative; z-index: 1; flex: 1 0 auto; }
/* Pages without a sidebar keep <main> as body's direct content child (no
   .shell-body wrapper) — let it grow too so the footer still pins. */
body > main { flex: 1 0 auto; }

.shell-sidebar {
  width: 200px; flex: none; padding: 20px 12px; display: flex; flex-direction: column; gap: 8px;
  min-height: calc(100vh - 240px);
}

/* Canonical course-picker slot — ONE location, site-wide: the top of the
   left sidebar, above the sub-nav buttons. Never full width, never in the
   header or top navbar. If a page has no sub-nav items, this still renders
   alone in an otherwise-nav-less sidebar so the slot stays consistent. */
.shell-course-picker {
  padding-bottom: 12px; margin-bottom: 8px; border-bottom: 1px solid var(--ink-300);
}
.shell-course-picker label.shell-picker-label {
  display: block; font-family: var(--f-display); font-size: 0.72em; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--fog-400); margin-bottom: 6px;
}
.shell-course-picker select {
  width: 100%; padding: 7px 10px; background: var(--ink-100); border: 1px solid var(--ink-300);
  border-radius: var(--radius-sm); color: var(--fog-100); font-family: var(--f-body); font-size: 0.85em;
}

.shell-sidebar-nav { display: flex; flex-direction: column; gap: 8px; }

.shell-sidebar button.side-btn {
  display: block; width: 100%; text-align: left; padding: 10px 14px; border-radius: var(--radius-sm);
  background: var(--ink-100); border: 1px solid var(--ink-300); color: var(--fog-200);
  font-family: var(--f-display); font-size: 0.88em; font-weight: 600; cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.shell-sidebar button.side-btn:hover { border-color: var(--teal-500); color: var(--teal-400); }
.shell-sidebar button.side-btn.active {
  background: rgba(79,209,197,0.14); border-color: var(--teal-400); color: var(--teal-400);
}

/* Main content column. squiddlr.css's base `main` rule caps width at 1280px
   and centers it with `margin: 0 auto`; inside the shell flex row that left a
   narrow column floating between big empty gutters. Override both so the main
   area fills all space between the sidebar and the page edge (keeping only the
   comfortable inner padding). This is THE systemic width fix — every shell
   page inherits it. */
.shell-main { flex: 1 1 auto; min-width: 0; max-width: none; margin: 0; padding: 24px 32px; }

.shell-footer {
  position: sticky; bottom: 0; z-index: 40; flex-shrink: 0;
  border-top: 1px solid var(--ink-300); background: #0A1220;
  color: #E6EAF1; font-family: var(--f-display); font-size: 0.85em;
  padding: 14px 24px; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px;
}
.shell-footer a, .shell-footer button.shell-footer-back { color: #E6EAF1; text-decoration: none; }
.shell-footer a:hover, .shell-footer button.shell-footer-back:hover { color: #4FD1C5; text-decoration: underline; }
.shell-footer a.bug-report-btn:hover,
.shell-footer a.bug-list-link:hover { color: #06281c; text-decoration: none; }
.shell-footer nav { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.shell-footer button.shell-footer-back {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
}
.shell-crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 0 16px 8px; padding: 0 8px;
  font-family: var(--f-display); font-size: 0.85em; color: var(--fog-300);
}
.shell-crumbs a { color: var(--teal-400); text-decoration: none; }
.shell-crumbs a:hover { text-decoration: underline; }
.shell-crumbs [aria-current="page"] { color: var(--fog-100); }
.shell-back, .shell-footer-back { font: inherit; }
.shell-back {
  margin-left: auto; background: transparent; color: var(--fog-100);
  border: 1px solid var(--ink-300); border-radius: 999px;
  padding: 4px 12px; cursor: pointer; font-family: var(--f-display); font-weight: 700;
}
.shell-back:hover { border-color: var(--teal-400); color: var(--teal-400); }
[data-sticky-actions], .sticky-actions {
  position: sticky; bottom: var(--shell-footer-offset, 72px); z-index: 35;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: 12px; padding: 10px 12px;
  background: rgba(10, 18, 32, 0.94);
  border: 1px solid var(--ink-300); border-radius: var(--radius-sm);
  box-shadow: 0 -8px 18px rgba(0, 0, 0, 0.28);
}
.shell-footer .footer-brand { display: flex; align-items: center; gap: 8px; text-decoration: none; }
.shell-footer .footer-brand .wordmark-sm { font-family: var(--f-script); color: var(--teal-400); font-size: 1.15em; }

/* Sidebar panel switching, mirrors .panel/.panel.active from squiddlr.css
   but scoped for shell-driven sub-pages inside shell-main */
.shell-panel { display: none; }
.shell-panel.active { display: block; }

/* ---------------------------------------------------------------------
   Shared modal dialog — the ONE canonical CRUD dialog chrome, site-wide.
   Any page needing an add/edit modal builds its own <div class="modal-overlay">
   > <div class="modal"> markup and toggles .open via Shell.openModal/closeModal
   in shell.js. Styled once here so every dialog matches the ocean theme.
   --------------------------------------------------------------------- */
.modal-overlay {
  display: none; position: fixed; inset: 0; z-index: 300;
  align-items: center; align-items: safe center; justify-content: center; padding: 24px;
  background: rgba(6, 11, 20, 0.72); backdrop-filter: blur(4px);
  overflow-y: auto; overscroll-behavior: contain;
}
.modal-overlay.open { display: flex; }
/* While a dialog is open, the page behind it must not scroll. The bars
   that used to cover the dialog are position:sticky, so a scrolling page
   kept them painted over Save. */
html.modal-open, html.modal-open body { overflow: hidden; }
.modal {
  background: linear-gradient(180deg, var(--ink-100), var(--ink-050));
  border: 1px solid var(--teal-700); border-radius: var(--radius);
  box-shadow: var(--shadow-md); width: 100%; max-width: 560px;
  /* Stay inside the viewport, including the overlay's padding. 88vh is the
     fallback where 100dvh is unsupported. The body scrolls; the header and
     the footer (Save) stay on screen. */
  max-height: calc(100vh - 48px);
  max-height: calc(100dvh - 48px);
  min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.modal.modal-wide { max-width: 760px; }
.modal-header {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex: none;
  padding: 16px 20px; border-bottom: 1px solid var(--ink-300);
}
.modal-header h3 { margin: 0; color: var(--teal-400); font-family: var(--f-display); }
.modal-close {
  background: transparent; border: none; color: var(--fog-300); font-size: 1.4em;
  line-height: 1; padding: 2px 8px; cursor: pointer;
}
.modal-close:hover { color: var(--teal-400); transform: none; }
.modal-body {
  padding: 18px 20px; overflow-y: auto;
  flex: 1 1 auto; min-height: 0;
}
.modal-footer {
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px;
  flex: none;
  padding: 14px 20px; border-top: 1px solid var(--ink-300);
}
@media (max-width: 640px) {
  .modal-overlay { padding: 12px; }
  .modal {
    max-height: calc(100vh - 24px);
    max-height: calc(100dvh - 24px);
  }
}

/* ---------------------------------------------------------------------
   Squiddlr D'Ink confirm dialog (Shell.confirm() in shell.js) -- the
   themed replacement for every window.confirm() across the app. A small
   squid-ink blot animates in behind the mascot each time the dialog
   opens, then the message + Cancel/OK buttons follow. Pure CSS/SVG, no
   external assets, reuses the existing modal-overlay/modal chrome and
   teal/ink palette so it matches every other dialog in the app.
   --------------------------------------------------------------------- */
.shell-confirm-modal { max-width: 420px; overflow: hidden; }
.shell-confirm-ink {
  position: relative; height: 84px; display: flex; align-items: center;
  justify-content: center; overflow: hidden;
  background: linear-gradient(180deg, var(--ink-200), var(--ink-100));
  border-bottom: 1px solid var(--ink-300);
}
.shell-confirm-ink svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.ink-blot { fill: var(--teal-700); opacity: 0; transform-origin: center; transform: scale(0); }
.shell-confirm-mascot {
  position: relative; z-index: 1; height: 46px; opacity: 0; transform: scale(0.6);
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.4));
}
/* Animation only plays while .inking is present on the overlay (added right
   before Shell.openModal, removed on close) so re-opening always replays it
   instead of the dialog looking half-finished. */
.shell-confirm-overlay.inking .ink-blot {
  animation: shellInkBlot 0.62s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
.shell-confirm-overlay.inking .ink-blot-1 { animation-delay: 0s; }
.shell-confirm-overlay.inking .ink-blot-2 { animation-delay: 0.06s; }
.shell-confirm-overlay.inking .ink-blot-3 { animation-delay: 0.11s; }
.shell-confirm-overlay.inking .ink-blot-4 { animation-delay: 0.16s; }
.shell-confirm-overlay.inking .ink-blot-5 { animation-delay: 0.2s; }
.shell-confirm-overlay.inking .shell-confirm-mascot {
  animation: shellInkMascot 0.4s ease-out 0.28s forwards;
}
@keyframes shellInkBlot {
  0%   { opacity: 0; transform: scale(0); }
  55%  { opacity: 0.9; transform: scale(1.08); }
  100% { opacity: 0.85; transform: scale(1); }
}
@keyframes shellInkMascot {
  0%   { opacity: 0; transform: scale(0.6) translateY(6px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
.shell-confirm-body { text-align: center; padding: 20px 22px; }
.shell-confirm-message { margin: 0; color: var(--fog-100); font-size: 1em; line-height: 1.5; white-space: pre-line; }
.shell-confirm-modal .modal-footer { justify-content: center; }
@media (prefers-reduced-motion: reduce) {
  .shell-confirm-overlay.inking .ink-blot,
  .shell-confirm-overlay.inking .shell-confirm-mascot { animation: none; opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------
   Card grid — the course-picker card grid on the Build a Class home and
   any future "pick one of many" surface. Reusable, theme-consistent.
   --------------------------------------------------------------------- */
.card-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px; margin-top: 6px;
}
.grid-card {
  background: linear-gradient(180deg, var(--ink-100), var(--ink-050));
  border: 1px solid var(--ink-300); border-radius: var(--radius);
  padding: 18px; box-shadow: var(--shadow-sm); cursor: pointer; text-align: left;
  transition: border-color var(--transition), transform var(--transition), box-shadow var(--transition);
  display: flex; flex-direction: column; gap: 6px; min-height: 120px;
}
.grid-card:hover { border-color: var(--teal-500); transform: translateY(-2px); box-shadow: var(--shadow); }
.grid-card .grid-card-title { font-family: var(--f-display); font-weight: 700; color: var(--teal-400); font-size: 1.05em; }
.grid-card .grid-card-meta { font-size: 0.85em; color: var(--fog-300); }
.grid-card.add-new {
  align-items: center; justify-content: center; text-align: center;
  border-style: dashed; border-color: var(--teal-600, var(--teal-700)); color: var(--teal-400);
  background: rgba(79, 209, 197, 0.06);
}
.grid-card.add-new .grid-card-title { font-size: 1.1em; }
.grid-card.add-new .add-plus { font-size: 2em; line-height: 1; color: var(--teal-400); }

/* ---------------------------------------------------------------------
   Compact card variant — for lists of many small click-to-edit items
   (World Builder characters/arcs/episodes, References Library, Lecture
   Studio, Communications). Denser than the course-picker .grid-card:
   smaller min width, tighter padding, a leading icon-glyph chip plus a
   small color-coded type dot so a dense grid still reads at a glance.
   Reuse .card-grid for the container; add .card-grid-compact for tighter
   packing. Reuse .grid-card and add .grid-card-compact for the item.
   --------------------------------------------------------------------- */
.card-grid-compact {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px; margin-top: 6px;
}
.grid-card-compact {
  padding: 12px 14px; min-height: 0; gap: 4px; position: relative;
}
.grid-card-compact .grid-card-head {
  display: flex; align-items: center; gap: 8px;
}
.grid-card-compact .grid-card-glyph {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.1em; line-height: 1; background: var(--ink-200);
}
.grid-card-compact .grid-card-title {
  font-size: 0.95em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.grid-card-compact .grid-card-meta {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.grid-card-compact .type-dot {
  flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--fog-300);
}
.grid-card-compact .grid-card-remove {
  position: absolute; top: 8px; right: 8px; background: none; border: none;
  color: var(--fog-400); font-size: 1em; line-height: 1; cursor: pointer; padding: 2px 4px;
}
.grid-card-compact .grid-card-remove:hover { color: var(--error); transform: none; }
.grid-card-compact.card-add-mini {
  align-items: center; justify-content: center; text-align: center; min-height: 64px;
  border-style: dashed; border-color: var(--teal-600, var(--teal-700)); color: var(--teal-400);
  background: rgba(79, 209, 197, 0.06); flex-direction: row; gap: 8px;
}

/* Per-type accent colors for the glyph chip + dot. Reused across World
   Builder (character/arc/episode) and future card lists (resource/lecture). */
.grid-card-glyph.type-character { background: rgba(79, 209, 197, 0.16); color: var(--teal-400); }
.grid-card-glyph.type-arc { background: rgba(244, 184, 96, 0.16); color: var(--amber-400); }
.grid-card-glyph.type-episode { background: rgba(52, 211, 153, 0.16); color: var(--success); }
.type-dot.type-character { background: var(--teal-400); }
.type-dot.type-arc { background: var(--amber-400); }
.type-dot.type-episode { background: var(--success); }

/* Resources Library type accents (reference/image/file/link/video/dataset).
   Two new hex accents (blue, violet) added here since the existing palette
   (teal/amber/success) is already spoken for by World Builder. */
.grid-card-glyph.type-reference { background: rgba(79, 209, 197, 0.16); color: var(--teal-400); }
.grid-card-glyph.type-image { background: rgba(244, 184, 96, 0.16); color: var(--amber-400); }
.grid-card-glyph.type-file { background: rgba(133, 148, 171, 0.18); color: var(--fog-200); }
.grid-card-glyph.type-link { background: rgba(96, 165, 244, 0.16); color: #60A5F4; }
.grid-card-glyph.type-video { background: rgba(52, 211, 153, 0.16); color: var(--success); }
.grid-card-glyph.type-dataset { background: rgba(167, 139, 250, 0.16); color: #A78BFA; }
.type-dot.type-reference { background: var(--teal-400); }
.type-dot.type-image { background: var(--amber-400); }
.type-dot.type-file { background: var(--fog-200); }
.type-dot.type-link { background: #60A5F4; }
.type-dot.type-video { background: var(--success); }
.type-dot.type-dataset { background: #A78BFA; }

/* Lecture Studio type accents — reuse the exact status-pill color ramp
   (squiddlr.css --status-*-fg tokens) so a card's glyph/dot always matches
   its own status pill, whatever the status. One vocabulary, two surfaces. */
.grid-card-glyph.type-contract    { background: var(--status-contract-bg);  color: var(--status-contract-fg); }
.grid-card-glyph.type-draft       { background: var(--status-draft-bg);     color: var(--status-draft-fg); }
.grid-card-glyph.type-in_progress { background: var(--status-progress-bg);  color: var(--status-progress-fg); }
.grid-card-glyph.type-approved    { background: var(--status-approved-bg);  color: var(--status-approved-fg); }
.grid-card-glyph.type-published   { background: var(--status-published-bg); color: var(--status-published-fg); }
.type-dot.type-contract    { background: var(--status-contract-fg); }
.type-dot.type-draft       { background: var(--status-draft-fg); }
.type-dot.type-in_progress { background: var(--status-progress-fg); }
.type-dot.type-approved    { background: var(--status-approved-fg); }
.type-dot.type-published   { background: var(--status-published-fg); }
/* status-generated shares the published ramp in squiddlr.css — mirror that alias here */
.grid-card-glyph.type-generated { background: var(--status-published-bg); color: var(--status-published-fg); }
.type-dot.type-generated        { background: var(--status-published-fg); }

/* ---------------------------------------------------------------------
   Drag-deck split view — reusable lego pattern for any "drag library
   cards onto a drop target" surface (References pane; future Assignments
   builder). Two-column .day-split grid; each side is a .day-split-lib
   panel box. Library cards are .catalog-card (draggable via DragDeck);
   attached items reuse .catalog-card with .is-static (no grab cursor).
   Pairs with js/drag-deck.js (makeDraggable / registerDropTarget).
   --------------------------------------------------------------------- */
.day-split { display: grid; grid-template-columns: 1.4fr 1fr; gap: 16px; margin-top: 12px; align-items: start; }
.day-split-lib {
  background: var(--ink-050); border: 1px solid var(--ink-300); border-radius: var(--radius-sm);
  padding: 12px; display: flex; flex-direction: column; gap: 10px;
}
.day-split-lib > .toolbar { margin: 0; }

/* Course Builder tour bar — sequential Next button injected by course-tour.js.
   Pinned near the bottom of instructor / textbook / schedule / syllabus /
   course-info so a first-time setup can walk the flow without bouncing back
   to the tile page between every step. */
.course-tour-bar {
  margin: 24px 0 12px; padding: 16px 12px; display: flex;
  justify-content: flex-end; border-top: 1px solid var(--ink-300);
}
.course-tour-next {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px; font-weight: 600; font-size: 0.95em;
  border-radius: 6px; text-decoration: none;
}

/* library panel — scope selector (This course / All Base / Full library) */
.catalog-scope { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.catalog-scope-btn {
  font-size: 0.78em; padding: 5px 12px; border-radius: 6px; cursor: pointer;
  background: transparent; border: 1px solid var(--ink-300); color: var(--fog-200);
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.catalog-scope-btn:hover { border-color: var(--teal-400); color: var(--teal-400); }
.catalog-scope-btn.active { background: var(--teal-500); border-color: var(--teal-500); color: var(--ink-000); font-weight: 600; }

/* library panel — type chips + search + draggable card list */
.catalog-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.catalog-chip {
  font-size: 0.78em; padding: 4px 10px; border-radius: 999px; cursor: pointer;
  background: transparent; border: 1px solid var(--ink-300); color: var(--fog-200);
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.catalog-chip:hover { border-color: var(--teal-400); color: var(--teal-400); }
.catalog-chip.active { background: var(--teal-500); border-color: var(--teal-500); color: var(--ink-000); font-weight: 600; }
.catalog-list { display: flex; flex-direction: column; gap: 6px; max-height: 60vh; overflow-y: auto; padding-right: 4px; }
/* drop-target highlight (DragDeck adds .drag-over to the registered target) */
.catalog-list.drag-over { outline: 2px dashed var(--teal-400); outline-offset: -2px; background: rgba(79,209,197,0.10); }
.catalog-card {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 6px 8px;
  background: var(--ink-100); border: 1px solid var(--ink-300); border-radius: var(--radius-sm);
  padding: 8px 10px; cursor: grab; transition: border-color 0.15s, background 0.15s;
}
.catalog-card:hover { border-color: var(--teal-400); }
.catalog-card.dragging { opacity: 0.5; cursor: grabbing; }
.catalog-card.is-static { cursor: default; }
/* Inline "+ create" card (Topics fold: search-or-create). Distinguished from
   a normal draggable library card by a dashed teal border + cursor:pointer. */
.catalog-card.catalog-card-create {
  border-style: dashed; border-color: var(--teal-500);
  background: transparent; cursor: pointer;
}
.catalog-card.catalog-card-create:hover { border-color: var(--teal-300); background: rgba(90,170,160,0.06); }
.catalog-card.catalog-card-create .catalog-card-type {
  background: var(--teal-700); color: var(--teal-100);
}
.catalog-card-type { grid-row: span 2; font-size: 0.66em; text-transform: uppercase; letter-spacing: 0.04em;
  padding: 2px 6px; border-radius: var(--radius-sm); background: var(--ink-300); color: var(--fog-100); white-space: nowrap; }
.catalog-card-label { font-weight: 600; color: var(--fog-100); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.catalog-card-sub { grid-column: 2 / 4; font-size: 0.74em; color: var(--fog-300); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.catalog-card-open { grid-row: span 2; font-size: 0.78em; white-space: nowrap; }
.catalog-card-topic .catalog-card-action { grid-column: 2 / -1; justify-self: start; margin-top: 3px; }
.catalog-empty { text-align: center; padding: 20px 8px; font-size: 0.88em; color: var(--fog-300); }
@media (max-width: 920px) {
  .day-split { grid-template-columns: 1fr; }
}

/* Communications type accents (ta_notes/announcement/canvas_post/email_blast).
   Reuses the violet accent introduced for Resources' dataset type (not yet
   used by any method here) plus the existing teal/amber/blue family, so the
   Communications grid stays inside the established palette. */
.grid-card-glyph.type-ta_notes { background: rgba(79, 209, 197, 0.16); color: var(--teal-400); }
.grid-card-glyph.type-announcement { background: rgba(244, 184, 96, 0.16); color: var(--amber-400); }
.grid-card-glyph.type-canvas_post { background: rgba(96, 165, 244, 0.16); color: #60A5F4; }
.grid-card-glyph.type-email_blast { background: rgba(167, 139, 250, 0.16); color: #A78BFA; }
.type-dot.type-ta_notes { background: var(--teal-400); }
.type-dot.type-announcement { background: var(--amber-400); }
.type-dot.type-canvas_post { background: #60A5F4; }
.type-dot.type-email_blast { background: #A78BFA; }
/* ---------------------------------------------------------------------
   Segmented toggle — a small pill switch for view A / view B on a single
   page (e.g. Textbook chapters vs Supplies). One shared component.
   --------------------------------------------------------------------- */
.seg-toggle { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--ink-300); border-radius: 999px; padding: 3px; background: var(--ink-050); gap: 3px; }
.seg-toggle button {
  border: none; background: transparent; color: var(--fog-300);
  padding: 7px 16px; border-radius: 999px; font-family: var(--f-display);
  font-weight: 600; font-size: 0.85em; cursor: pointer;
  white-space: nowrap;
}
.seg-toggle button:hover { transform: none; color: var(--teal-400); }
.seg-toggle button.active { background: linear-gradient(180deg, var(--teal-700), var(--teal-500)); color: #06281c; }

/* On narrow viewports a 3+ button toggle (or one with a longer label like
   "Purchasing & Access Info") no longer fits one pill row without squeezing
   text into a circle. Below 480px, drop the pill wrapper's inline-flex
   constraint and let the toggle become a full-width stack of pill buttons —
   each button keeps its own pill shape and single-line label, just stacked
   vertically instead of forced onto one line. Reusable for any future
   3+ button .seg-toggle, not specific to one page. */
@media (max-width: 480px) {
  .seg-toggle {
    display: flex; flex-direction: column; width: 100%;
    border-radius: var(--radius-sm);
  }
  .seg-toggle button {
    width: 100%; text-align: center;
    border-radius: var(--radius-sm);
  }
}

/* ---------------------------------------------------------------------
   Resource / topic chips list used inside the Design-the-Class-Day dialog
   and on calendar cells. Draggable rows for reorder reuse .drag-over etc.
   --------------------------------------------------------------------- */
.chip-list { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.chip-row {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  background: var(--ink-100); border: 1px solid var(--ink-300); border-radius: var(--radius-sm);
  font-size: 0.88em; color: var(--fog-100);
}
.chip-row .chip-handle { cursor: grab; color: var(--fog-400); }
.chip-row .chip-type {
  font-size: 0.7em; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--teal-400); font-family: var(--f-display); font-weight: 700;
}
.chip-row .chip-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip-row.drag-over { outline: 2px dashed var(--teal-400); outline-offset: -2px; }
.chip-row.dragging { opacity: 0.4; }

/* Clickable calendar day + its content chips (Schedule & Topics). */
.cal-day.clickable { cursor: pointer; }
.cal-day.clickable:hover { border-color: var(--teal-400); }
.cal-day .cal-add {
  position: absolute; top: 3px; right: 4px; width: 18px; height: 18px; line-height: 16px;
  text-align: center; border-radius: 50%; background: rgba(79,209,197,0.18);
  color: var(--teal-400); font-weight: 700; font-size: 0.9em; border: none; padding: 0;
}
.cal-day .cal-add:hover { transform: none; filter: brightness(1.2); }

/* ---------------------------------------------------------------------
   Detail-editing layout — the ONE canonical pattern for every Content
   Studio / Communication Studio detail screen (World Builder, Assignments,
   Lecture/Slide/Tool detail, Communications compose, etc.).

   Two columns: a left list/nav column (.detail-list) that fills its own
   width right up against the sidebar, and a wide editor column
   (.detail-main) that holds the record's sections. Each section is a
   collapsible <details class="fold"> row spanning the full editor width, so
   opening one reveals a big, comfortable editing surface and sections never
   sit side-by-side at mismatched heights. Native <details> = no JS needed
   (pages may still toggle a fold's `display`/`open` for show-on-select).
   --------------------------------------------------------------------- */
.detail-layout { display: flex; gap: 20px; align-items: flex-start; }
.detail-list { flex: 0 0 300px; }
.detail-list > .card { width: 100%; margin-bottom: 0; }
.detail-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 16px; }

.fold {
  background: linear-gradient(180deg, var(--ink-100), var(--ink-050));
  border: 1px solid var(--ink-300); border-radius: var(--radius);
  box-shadow: var(--shadow-sm); overflow: hidden;
}
/* An open fold must not clip native date/time pickers. overflow:hidden on the
   closed summary keeps the rounded corners; the open body stays clickable. */
.fold[open] { overflow: visible; }
.fold > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; gap: 10px;
  padding: 15px 20px; font-family: var(--f-display); font-weight: 700;
  font-size: 1.1em; color: var(--teal-400);
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::before {
  content: '\25B8'; /* ▸ */ flex: none; font-size: 0.85em; color: var(--teal-400);
  transition: transform var(--transition);
}
.fold[open] > summary::before { transform: rotate(90deg); }
.fold > summary:hover { filter: brightness(1.12); }
.fold > summary .fold-hint { margin-left: auto; font-family: var(--f-body); font-weight: 400; font-size: 0.72em; color: var(--fog-300); }
.fold-body { padding: 6px 20px 20px; }
/* Folds reveal larger writing surfaces than the compact base textarea. */
.fold-body textarea { min-height: 128px; }

/* Clickable record rows in a .detail-list column (the "pick one to edit"
   list on every Content Studio detail page). Promoted here from
   world-builder.css so World Builder, Resources, Slide Studio, etc. share one
   list-item look. World Builder keeps its .sl-card-item alias for now. */
.detail-list-item {
  border: 1px solid var(--ink-200); border-radius: 8px; padding: 10px 12px;
  margin-bottom: 8px; cursor: pointer; background: var(--ink-050);
}
.detail-list-item:hover { border-color: var(--teal-500); }
.detail-list-item.selected { border-color: var(--teal-400); box-shadow: 0 0 0 1px var(--teal-400); }
.detail-list-item .dli-title { font-weight: 600; color: var(--teal-400); font-family: var(--f-display); }
.detail-list-item .dli-meta { font-size: 0.78em; color: var(--fog-400); margin-top: 2px; }

/* Repeated editable sub-rows inside a fold (characters, slides, etc.). */
.detail-row-item {
  border: 1px solid var(--ink-200); border-radius: 6px; padding: 8px 10px;
  margin-bottom: 6px; position: relative;
}
.detail-row-item .dri-remove {
  position: absolute; top: 6px; right: 8px; cursor: pointer; color: var(--error);
  font-weight: bold; font-size: 0.9em; background: none; border: none;
}
.detail-row-item input, .detail-row-item textarea, .detail-row-item select { margin-bottom: 4px; }

/* Read-only generated-spec / preview block (AI contract, world block, …). */
.detail-preview {
  border: 1px solid var(--ink-200); border-radius: 8px; padding: 12px;
  background: var(--ink-000); font-family: var(--f-mono);
  font-size: 12.5px; line-height: 1.5; white-space: pre-wrap;
  max-height: 420px; overflow-y: auto; color: var(--fog-100);
}

@media (max-width: 980px) {
  .detail-layout { flex-direction: column; }
  .detail-list { flex: 1 1 auto; width: 100%; }
  .detail-list > .card { margin-bottom: 0; }
}

/* ---------------------------------------------------------------------
   Lecture status header — sticky identity, edition pills, and actions.
   Uses the same ink / teal / status-pill tokens as the rest of the shell.
   --------------------------------------------------------------------- */
.lecture-status-header {
  position: sticky;
  top: var(--site-chrome-offset, 0px);
  z-index: 30;
  margin: 0 0 16px;
  padding: 12px 16px;
  background: var(--ink-100);
  border: 1px solid var(--ink-300);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.lecture-status-header[hidden] { display: none; }
.lecture-status-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  flex-wrap: wrap;
}
.lecture-status-crumb {
  margin: 0 0 4px;
  font-family: var(--f-display);
  font-size: 0.78em;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--fog-300);
}
.lecture-status-header h2 {
  margin: 0;
  font-family: var(--f-display);
  font-size: 1.25em;
  line-height: 1.25;
  color: var(--teal-400);
}
.lecture-status-id {
  margin: 4px 0 0;
  font-family: var(--f-mono);
  font-size: 12px;
  color: var(--fog-300);
}
.lecture-status-saved {
  margin: 0;
  font-size: 0.85em;
  color: var(--fog-200);
  text-align: right;
}
.lecture-status-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.lecture-status-pills .status-pill { font-size: 0.78em; }
button.lecture-deck-pill { cursor: pointer; }
button.lecture-deck-pill:hover { filter: brightness(1.08); }
.lecture-status-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.lecture-status-actions [data-action-wrap] { display: inline-flex; }
.lecture-status-header button:disabled,
.lecture-status-header button:disabled:hover {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
  filter: none;
}
#lecture-header-qa-badge { margin-left: 6px; text-transform: none; }
#lecture-header-qa-badge[hidden] { display: none; }

.conflict-banner {
  margin: 0;
  padding: 10px 12px;
  background: var(--warn-bg);
  border: 1px solid var(--amber-400);
  border-radius: var(--radius-sm);
  color: var(--fog-100);
}
.conflict-banner[hidden] { display: none; }
.conflict-banner-sticky {
  position: sticky;
  top: var(--site-chrome-offset, 0px);
  z-index: 30;
  margin-bottom: 12px;
}
.conflict-banner-message { margin: 0 0 6px; font-weight: 700; color: var(--amber-400); font-family: var(--f-display); }
.conflict-banner-warn { margin: 0 0 8px; color: var(--fog-100); }
.conflict-banner-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.conflict-diff { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 8px; }
.conflict-diff-label {
  font-family: var(--f-display);
  font-size: 0.75em;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fog-300);
  margin-bottom: 4px;
}
.conflict-diff-pane pre {
  margin: 0;
  max-height: 240px;
  overflow: auto;
  padding: 8px 10px;
  background: var(--ink-000);
  border: 1px solid var(--ink-300);
  border-radius: var(--radius-sm);
  font-family: var(--f-mono);
  font-size: 12px;
  line-height: 1.45;
  white-space: pre-wrap;
  color: var(--fog-100);
}
@media (max-width: 800px) {
  .lecture-status-saved { text-align: left; }
  .conflict-diff { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------
   Slideshow editor toolbars. Same sticky contract as .lecture-status-header:
   position:sticky, top offset by the site chrome, opaque ink surface,
   z-index under the top nav (50), the footer (40), dialogs (300), and
   the asset picker (200). .shell-body is its own stacking context, so
   these bars cannot paint over the chrome or a popup parked on <body>.
   The add-slide bar and each slide's move/delete bar stick while that
   part of the deck is on screen. Save slides reuses .sticky-actions.
   --------------------------------------------------------------------- */
#slide-editor-toolbar,
.slide-card-toolbar {
  position: sticky;
  z-index: 30;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  min-width: 0;
  margin: 0 0 8px;
  padding: 8px 10px;
  background: var(--ink-100);
  border: 1px solid var(--ink-300);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
#slide-editor-toolbar {
  top: var(--slide-toolbar-top, var(--site-chrome-offset, 0px));
}
.slide-card-toolbar {
  top: var(--slide-card-toolbar-top, calc(var(--site-chrome-offset, 0px) + 56px));
  z-index: 29;
  justify-content: space-between;
}
.slide-card-toolbar-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  justify-content: flex-end;
}
/* Save sits above the footer and under the add-slide bar, the deck
   conflict banner, and every popup. */
#slide-editor-actions {
  z-index: 28;
}
/* Focused fields scroll clear of the sticky bars instead of hiding under them. */
#fold-slide-editor .slide-card :is(input, textarea, select) {
  scroll-margin-top: calc(var(--slide-card-toolbar-top, var(--site-chrome-offset, 0px)) + 44px);
  scroll-margin-bottom: calc(var(--shell-footer-offset, 72px) + var(--slide-actions-offset, 52px) + 12px);
}
@media (max-width: 800px) {
  #slide-editor-toolbar .toolbar-btn {
    flex: 1 1 10rem;
    min-width: 0;
    white-space: normal;
    overflow-wrap: anywhere;
    text-align: center;
  }
  .slide-card-toolbar { align-items: flex-start; }
}
/* A short window cannot spare extra sticky rows without burying the slide.
   The add-slide bar still sticks. Card controls and Save stay in the flow. */
@media (max-height: 520px) {
  .slide-card-toolbar { position: static; top: auto; }
  #slide-editor-actions { position: static; bottom: auto; }
}

@media (max-width: 860px) {
  .shell-topnav { flex-wrap: wrap; border-radius: 20px; min-width: 0; }
  .shell-topnav a.topnav-btn { flex: 1 1 40%; }
  /* On narrow screens the user chip wraps under the nav pills rather
     than compressing them; drop the left divider and stretch full-width. */
  .shell-topnav .topnav-tools {
    flex: 1 1 100%; flex-wrap: wrap; justify-content: flex-end;
    max-width: 100%;
    margin-left: 0; padding-top: 8px; margin-top: 4px;
    border-top: 1px solid var(--ink-300);
  }
  .shell-topnav .topnav-user {
    flex: none; justify-content: flex-end;
    margin-left: 0; padding-left: 8px;
    border-left: none; border-top: none;
    padding-top: 0; margin-top: 0;
  }
  .shell-footer { padding: 12px 16px; }
  .shell-body { flex-direction: column; }
  .shell-sidebar { width: 100%; flex-direction: row; flex-wrap: wrap; min-height: 0; }
  .shell-sidebar button.side-btn { width: auto; flex: 1; min-width: 140px; }
}

/* ---------------------------------------------------------------------------
   Course quick-link chip row — used at the top of pages that scope by course
   (Communications, TA Tasks). Renders one pill per course from
   /api/admin/courses; clicking selects that course.
   --------------------------------------------------------------------------- */
.course-chip-row {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 8px 12px; margin: 0;
  background: rgba(255,255,255,0.02);
  border-bottom: 1px solid var(--ink-300);
}
.course-chip-row .course-chip-label {
  align-self: center; font-size: 0.8em;
  color: var(--ink-500); margin-right: 4px;
}
.course-chip {
  background: rgba(79, 209, 197, 0.08);
  border: 1px solid var(--teal-700);
  color: var(--teal-400);
  border-radius: 999px; padding: 4px 12px;
  font-size: 0.82em; cursor: pointer;
  transition: filter var(--transition, 0.15s), background 0.15s;
  font-family: inherit;
}
.course-chip:hover { filter: brightness(1.2); }
.course-chip.active {
  background: var(--teal-700);
  color: var(--ink-100);
  border-color: var(--teal-500);
}
.course-chip[data-mine="false"] { opacity: 0.55; }

/* Draft badge — one mark for bot proposals, on the item and in Needs review. */
.draft-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(79, 209, 197, 0.16);
  color: var(--teal-400, #4fd1c5);
  border-radius: 999px;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 650;
  line-height: 1.4;
  white-space: nowrap;
}
.draft-badge-icon { display: block; flex: none; }
.draft-review {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.needs-review { position: relative; flex: none; }
.needs-review-btn {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 12px;
  border-radius: 999px;
  border: 2px solid #4FD1C5;
  background: #0A1220;
  color: #E6EAF1;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.needs-review-btn:hover,
.needs-review-btn[aria-expanded="true"] { background: #4FD1C5; color: #06281c; }
.needs-review-btn:focus-visible { outline: 2px solid #F4B860; outline-offset: 2px; }
.needs-review-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(420px, 80vw);
  max-height: min(70vh, 520px);
  overflow: auto;
  z-index: 40;
  background: var(--ink-900, #101c2f);
  color: var(--fog-100, #e6eaf1);
  border: 1px solid var(--teal-700, #2c7a7b);
  border-radius: 12px;
  padding: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
}
.needs-review-row {
  display: grid;
  gap: 2px;
  padding: 8px;
  border-radius: 8px;
  text-decoration: none;
  color: inherit;
}
.needs-review-row:hover { background: rgba(79, 209, 197, 0.08); }
.needs-review-type { color: var(--teal-400, #4fd1c5); font-size: 12px; }
.needs-review-title { font-weight: 650; }
.needs-review-meta { color: var(--fog-200, #c5ced9); font-size: 12px; }
.needs-review-actions { display: flex; gap: 6px; margin-top: 4px; }
.needs-review-empty { margin: 8px; color: var(--fog-200, #c5ced9); }
