/* ═══════════════════════════════════════════════════════════════
   Session management - /admin/session-management (AdminSessionManagement.vue)

   The teaching-plan screen: a course content pane beside the list of
   four-hour session cards.

   Two things about this file are load-bearing:

   1. The FILENAME must keep its `admin` prefix. scripts/bundle-css.mjs
      partitions the public and admin bundles on
      `href.startsWith('/css/admin')` alone, so a rename would ship this
      sheet to every marketing visitor.
   2. `.csm-page` re-establishes `direction: rtl` AND `text-align: start`.
      The shell pins `.admin-main` to `direction: ltr` + `text-align: left`,
      and this is a Hebrew screen, so the page root is where the island
      starts. Both are needed: `text-align` is inherited as its own computed
      value, so flipping only the direction leaves every stretched flex
      child (session titles, item titles, wrapped paragraphs) hugging the
      left edge inside a right-to-left row. `start` rather than `right` so
      the Latin islands below that carry their own `dir="ltr"` still read
      left-aligned.

   Everything here is prefixed `csm-`. The shared kit from admin.css
   (`.admin-page-header`, `.admin-toolbar`, `.admin-stat*`, `.empty-state`,
   `.form-*`, `.btn*`, `.badge`, `.modal*`, `.toast`) is reused rather than
   restated; only what is genuinely new to this screen lives below.
   ═══════════════════════════════════════════════════════════════ */

.csm-page {
  direction: rtl;
  text-align: start;

  /* The three states of a session against its budget. They are read in the
     bar, in the meter line, in the picker and in the proposal, so they are
     declared once here rather than five times below. */
  --csm-under: var(--primary-color, #0071e3);
  --csm-exact: #2e7d32;
  --csm-over: var(--alert-color, #be123c);
  --csm-warm: #b26a00;

  --csm-surface: #fff;
  --csm-surface-sunken: #f7f9fc;
  --csm-border: #e4eaf3;
  --csm-border-strong: #cfdcee;
  --csm-ink: #1f2430;
  --csm-muted: #6b7280;
  --csm-radius: 14px;
}

.csm-header {
  flex-wrap: wrap;
  gap: 0.75rem;
}

.csm-toolbar {
  flex-wrap: wrap;
  justify-content: flex-start;
}

.csm-note {
  direction: rtl;
}

.csm-drift-banner {
  direction: rtl;
}

/* ── Course selector ─────────────────────────────────────────
   The two course names are the brand logo components, so the tab is sized
   from its content rather than from a text length. */

.csm-course-tabs {
  display: inline-flex;
  align-items: stretch;
  background: #f3f4f6;
  border: 1px solid #e2e4e8;
  border-radius: 10px;
  padding: 3px;
  gap: 2px;
}

.csm-course-tab {
  border: none;
  background: transparent;
  padding: 0.45rem 0.9rem;
  border-radius: 7px;
  font-size: 0.9rem;
  font-weight: 400;
  color: #555;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  transition: background 0.15s, box-shadow 0.15s, color 0.15s;
}

.csm-course-tab:hover {
  background: rgba(255, 255, 255, 0.6);
  color: #1a1a1a;
}

.csm-course-tab.is-active {
  background: #fff;
  color: #1a1a1a;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

.csm-course-tab:focus-visible {
  outline: 2px solid var(--primary-color, #0071e3);
  outline-offset: 1px;
}

/* Held while a proposal is being computed. That answer belongs to the course
   that asked for it, so the strip says it is busy rather than letting a click
   land on another track while a proposal for this one is still on its way. */
.csm-course-tabs.is-pending {
  cursor: progress;
}

.csm-course-tab:disabled {
  cursor: progress;
  opacity: 0.55;
}

.csm-course-tab:disabled:hover {
  background: transparent;
  color: #555;
}

.csm-course-tab.is-active:disabled:hover {
  background: #fff;
  color: #1a1a1a;
}

/* The logo marks sit on their own baseline; nudge them onto the tab's. */
.csm-course-tab .logo-10x-inline svg,
.csm-course-tab .logo-10x-architect-inline svg {
  vertical-align: -0.18em;
}

/* ── The target figure, edited in place inside the stat strip ── */

.csm-stat-edit {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-inline-start: 0.4rem;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--csm-border-strong);
  border-radius: 999px;
  background: #fff;
  color: var(--csm-muted);
  font-size: 0.66rem;
  cursor: pointer;
}

.csm-stat-edit:hover {
  color: var(--primary-color, #0071e3);
  border-color: var(--primary-color, #0071e3);
}

.csm-target-input {
  width: 92px;
  text-align: center;
  font-size: 1.4rem;
  padding: 0.2rem 0.4rem;
}

.csm-target-actions {
  display: inline-flex;
  gap: 0.15rem;
  margin-top: 0.35rem;
}

/* A reading that has left the comfortable range stops being decorative. */
.admin-stat.csm-stat--alert .admin-stat-label {
  color: var(--csm-over);
}

/* Content another track is still holding: a warning, not yet a refusal. The
   `csm-stat--alert` variant is used instead the moment one of those meetings is
   marked ready, because then the assignment is refused rather than merely
   costly. */
.admin-stat.csm-stat--held .admin-stat-label {
  color: var(--csm-warm);
}

/* ── Page body: content pane + session list ─────────────────── */

.csm-body {
  display: grid;
  grid-template-columns: minmax(280px, 360px) minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}

.csm-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  color: var(--csm-over);
}

/* ── Content pane ───────────────────────────────────────────── */

.csm-pane {
  min-width: 0;
  background: var(--csm-surface);
  border: 1px solid var(--csm-border);
  border-radius: var(--csm-radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

/* Dropping an item back on the pane unassigns it, so the pane says so. */
.csm-pane.is-drop-target {
  border-color: var(--primary-color, #0071e3);
  box-shadow: 0 0 0 2px rgba(0, 113, 227, 0.15);
}

.csm-pane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.8rem 1rem;
  border-bottom: 1px solid var(--csm-border);
  background: var(--csm-surface-sunken);
}

.csm-pane-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--csm-ink);
}

.csm-pane-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border: none;
  background: transparent;
  padding: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--csm-ink);
  cursor: pointer;
}

/* Two readings, side by side: what is free to place, and what another track is
   still holding. They were one number, and that number was wrong whenever a
   module had moved tracks without its placements. */
.csm-pane-badges {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.3rem;
}

.csm-backlog-badge {
  background: rgba(190, 18, 60, 0.09);
  color: var(--csm-over);
  white-space: nowrap;
}

.csm-backlog-badge.is-clear {
  background: #e8f5e9;
  color: var(--csm-exact);
}

.csm-held-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: rgba(178, 106, 0, 0.12);
  color: var(--csm-warm);
  white-space: nowrap;
}

/* A holder marked ready refuses the write outright, so it does not share the
   colour of one that merely loses the content. */
.csm-held-badge.is-ready {
  background: rgba(190, 18, 60, 0.09);
  color: var(--csm-over);
  box-shadow: inset 0 0 0 1px rgba(190, 18, 60, 0.3);
}

.csm-pane-body {
  padding: 0.85rem 1rem 1rem;
}

.csm-pane-controls {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.csm-search {
  width: 100%;
}

.csm-search input {
  width: 100%;
  /* Mirrors the shared `.admin-search` geometry for this RTL island: the
     magnifier belongs at the START of the field, which here is the right. */
  padding-right: 30px;
  padding-left: 28px;
}

.csm-search .fa-search {
  left: auto;
  right: 10px;
}

.csm-search .search-clear {
  right: auto;
  left: 6px;
}

.csm-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.82rem;
  color: var(--csm-muted);
  cursor: pointer;
}

.csm-pane-buttons {
  display: flex;
  gap: 0.4rem;
}

.csm-pane-hint {
  margin: 0.75rem 0 0;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--csm-muted);
}

.csm-pane-empty {
  padding: 2rem 0.5rem;
  font-size: 0.85rem;
}

.csm-tree {
  margin-top: 0.75rem;
}

.csm-module + .csm-module {
  margin-top: 0.5rem;
}

.csm-module-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.45rem 0.5rem;
  border: none;
  border-radius: 8px;
  background: var(--csm-surface-sunken);
  color: var(--csm-ink);
  font-size: 0.85rem;
  font-weight: 600;
  text-align: start;
  cursor: pointer;
}

.csm-module-head:hover {
  background: #eef3fa;
}

.csm-module-num {
  flex: 0 0 auto;
  min-width: 1.4rem;
  height: 1.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  background: #fff;
  border: 1px solid var(--csm-border-strong);
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--csm-muted);
}

.csm-module-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Collapsed carets point LEFT on an RTL screen: that is the direction the
   panel opens towards. */
.csm-caret {
  flex: 0 0 auto;
  width: 1rem;
  color: var(--csm-muted);
  font-size: 0.7rem;
  transition: transform 0.15s;
}

.csm-caret.is-open {
  transform: rotate(-90deg);
}

.csm-caret-btn {
  border: none;
  background: transparent;
  padding: 0.15rem;
  cursor: pointer;
  line-height: 1;
}

.csm-chapters {
  padding-right: 0.75rem;
  margin-top: 0.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.csm-chapter {
  min-width: 0;
}

.csm-chapter-head {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  padding: 0.38rem 0.45rem;
  border: 1px solid var(--csm-border);
  border-radius: 8px;
  background: #fff;
  font-size: 0.82rem;
  color: var(--csm-ink);
}

.csm-chapter-head[draggable='true'] {
  cursor: grab;
}

.csm-chapter-head:hover {
  border-color: var(--csm-border-strong);
}

.csm-chapter-head.is-dragging,
.csm-subject.is-dragging,
.csm-item.is-dragging {
  opacity: 0.45;
}

.csm-chapter-title {
  flex: 1 1 8rem;
  min-width: 0;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.csm-grip {
  flex: 0 0 auto;
  color: #c3cbd8;
  font-size: 0.75rem;
  cursor: grab;
}

.csm-subjects {
  list-style: none;
  margin: 0.3rem 0 0.2rem;
  padding: 0 1rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.csm-subject {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin: 0;
  padding: 0.3rem 0.45rem;
  border: 1px solid transparent;
  border-radius: 7px;
  font-size: 0.79rem;
  background: #fff;
}

.csm-subject[draggable='true'] {
  cursor: grab;
}

/* Placed content recedes; unplaced content is the work still to do, so it
   is the thing that catches the eye. */
.csm-subject.is-placed {
  color: #98a2b3;
  background: #fbfcfe;
}

.csm-subject.is-open {
  border-color: rgba(190, 18, 60, 0.22);
  background: rgba(190, 18, 60, 0.035);
}

.csm-subject-title {
  flex: 1 1 7rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.csm-tree-foot {
  margin: 0.85rem 0 0;
  text-align: center;
  font-size: 0.72rem;
  color: var(--csm-muted);
}

/* ── Hour chips, and the inline editor behind them ──────────── */

.csm-hours-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  background: #eef3fa;
  border: 1px solid transparent;
  color: #46536b;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.csm-hours-chip.is-over {
  background: rgba(190, 18, 60, 0.08);
  color: var(--csm-over);
}

.csm-hours-chip.is-empty {
  background: rgba(178, 106, 0, 0.1);
  color: var(--csm-warm);
}

.csm-fit-icon {
  font-size: 0.62rem;
  opacity: 0.75;
}

.csm-hours-btn {
  cursor: pointer;
  font-family: inherit;
}

.csm-hours-btn:hover:not(:disabled) {
  border-color: var(--primary-color, #0071e3);
  color: var(--primary-color, #0071e3);
}

.csm-hours-btn:disabled {
  cursor: default;
}

.csm-hours-edit {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
}

.csm-hours-input {
  width: 74px;
  padding: 0.15rem 0.35rem;
  font-size: 0.75rem;
}

/* ── Small status pills, shared by the pane and the cards ───── */

.csm-pill {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.08rem 0.45rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 500;
  white-space: nowrap;
}

.csm-pill--open {
  background: rgba(190, 18, 60, 0.08);
  color: var(--csm-over);
}

.csm-pill--done {
  background: #e8f5e9;
  color: var(--csm-exact);
}

.csm-pill--part {
  background: rgba(178, 106, 0, 0.1);
  color: var(--csm-warm);
}

.csm-pill--placed {
  background: #eef3fa;
  color: #5b6b85;
}

.csm-pill--warn {
  background: rgba(178, 106, 0, 0.1);
  color: var(--csm-warm);
}

/* ── Held by another track ───────────────────────────────────
   The marker that replaces a false "לא משובץ". Two states, and they must not
   read alike: a DRAFT holder will simply lose the subject when it is placed
   here, while a READY holder makes the placement fail. One is a cost, the other
   is a wall, so the wall carries the alert colour, a ring and a lock. */

.csm-pill--held {
  background: rgba(178, 106, 0, 0.12);
  color: var(--csm-warm);
  box-shadow: inset 0 0 0 1px rgba(178, 106, 0, 0.24);
}

.csm-pill--held-ready {
  background: rgba(190, 18, 60, 0.1);
  color: var(--csm-over);
  font-weight: 600;
  box-shadow: inset 0 0 0 1px rgba(190, 18, 60, 0.32);
}

/* The mirror image, read from the HOLDING side: a placement sitting in one of
   THIS course's meetings whose subject now belongs to another track. Same
   vocabulary as the held pills above, because it is the same fact seen from the
   other end - but neutral rather than alarmed: from here it is a leftover to
   release, not a wall. */
.csm-pill--stale {
  background: rgba(107, 114, 128, 0.1);
  color: #4b5563;
  box-shadow: inset 0 0 0 1px rgba(107, 114, 128, 0.24);
}

.csm-assign-btn {
  flex: 0 0 auto;
  margin-inline-start: auto;
}

/* ── Session list ───────────────────────────────────────────── */

.csm-sessions {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.csm-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 3rem 1.5rem;
  background: var(--csm-surface);
  border: 1px dashed var(--csm-border-strong);
  border-radius: var(--csm-radius);
  color: var(--csm-muted);
}

.csm-empty-icon {
  font-size: 1.8rem;
  color: #c3cbd8;
}

.csm-empty-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 500;
  color: var(--csm-ink);
}

.csm-empty-body {
  margin: 0;
  max-width: 34rem;
  font-size: 0.85rem;
  line-height: 1.6;
}

.csm-empty-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 0.6rem;
}

.csm-session {
  position: relative;
  min-width: 0;
  padding: 0.85rem 1rem 0.95rem;
  background: var(--csm-surface);
  border: 1px solid var(--csm-border);
  border-inline-start: 3px solid var(--csm-under);
  border-radius: var(--csm-radius);
  box-shadow: var(--shadow-sm);
}

.csm-session.is-exact {
  border-inline-start-color: var(--csm-exact);
}

.csm-session.is-over {
  border-inline-start-color: var(--csm-over);
}

.csm-session.is-overflow {
  background: linear-gradient(180deg, rgba(190, 18, 60, 0.035) 0%, #fff 40%);
}

.csm-session.is-drop-target {
  border-color: var(--primary-color, #0071e3);
  box-shadow: 0 0 0 2px rgba(0, 113, 227, 0.14);
}

.csm-session-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.csm-session-num {
  flex: 0 0 auto;
  width: 1.9rem;
  height: 1.9rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: var(--csm-surface-sunken);
  border: 1px solid var(--csm-border-strong);
  /* Solid ink, never the brand gradient: this numeral is a weight-500
     figure and the gradient only reads cleanly through light letterforms. */
  color: var(--primary-color, #0071e3);
  font-size: 0.85rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.csm-session-title {
  flex: 1 1 10rem;
  min-width: 0;
  margin: 0;
  font-size: 0.98rem;
  font-weight: 600;
  color: var(--csm-ink);
  overflow-wrap: anywhere;
}

.csm-badge-overflow {
  background: rgba(190, 18, 60, 0.1);
  color: var(--csm-over);
}

.csm-status--draft {
  background: #eef1f6;
  color: #5b6b85;
}

.csm-status--in_progress {
  background: rgba(178, 106, 0, 0.12);
  color: var(--csm-warm);
}

.csm-status--ready {
  background: #e8f5e9;
  color: var(--csm-exact);
}

.csm-session-actions {
  display: flex;
  align-items: center;
  gap: 0.2rem;
  margin-inline-start: auto;
}

.csm-status-select {
  width: auto;
  min-width: 6.5rem;
  padding: 0.25rem 0.5rem;
  font-size: 0.75rem;
}

/* ── The four-hour meter ────────────────────────────────────── */

.csm-meter {
  margin-top: 0.7rem;
}

.csm-bar {
  height: 8px;
  border-radius: 999px;
  background: #eef1f6;
  overflow: hidden;
}

.csm-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--csm-under);
  transition: width 0.2s ease;
}

.csm-bar.is-exact .csm-bar-fill {
  background: var(--csm-exact);
}

.csm-bar.is-over .csm-bar-fill {
  /* A full bar cannot show how far past the budget the session is, so the
     stripes say "this ran out" and the meter line says by how much. */
  background: repeating-linear-gradient(
    135deg,
    var(--csm-over) 0 6px,
    rgba(190, 18, 60, 0.65) 6px 12px
  );
}

.csm-meter-read {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  margin-top: 0.35rem;
  font-size: 0.76rem;
  color: var(--csm-muted);
}

.csm-meter-num {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--csm-ink);
  font-variant-numeric: tabular-nums;
}

.csm-meter-of {
  white-space: nowrap;
}

.csm-meter-flag {
  margin-inline-start: auto;
  font-weight: 500;
}

.csm-meter-flag.is-over {
  color: var(--csm-over);
}

.csm-meter-flag.is-exact {
  color: var(--csm-exact);
}

.csm-flags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.55rem;
}

.csm-session-empty {
  margin-top: 0.7rem;
  padding: 1.1rem;
  border: 1px dashed var(--csm-border-strong);
  border-radius: 10px;
  text-align: center;
  font-size: 0.8rem;
  color: var(--csm-muted);
}

/* A meeting with no content OF THIS COURSE that is still holding another
   track's placements. It is not the empty state and must not read as one: the
   rows it holds are listed immediately below, so the box points down rather
   than inviting a drop. */
.csm-session-empty.is-stale-only {
  border-style: solid;
  border-color: rgba(178, 106, 0, 0.28);
  background: rgba(178, 106, 0, 0.05);
  color: #6b5220;
  text-align: start;
}

/* ── A session's content, in stored order ─────────────────────
   The boxes are RUNS: consecutive rows that teach the same chapter. Reading a
   card top to bottom gives the order the server holds, which is the order the
   drop indicator promised. A chapter taught in two stretches gets two boxes,
   and the second one says so - the card never re-sorts the plan to look tidy. */

.csm-groups {
  margin-top: 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.csm-group {
  border: 1px solid var(--csm-border);
  border-radius: 10px;
  overflow: hidden;
}

/* A chapter resuming after another one was taught in between. */
.csm-group.is-continued {
  border-style: dashed;
}

.csm-group.is-continued .csm-group-title {
  font-weight: 400;
  color: var(--csm-muted);
}

.csm-group-head {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
  padding: 0.35rem 0.6rem;
  background: var(--csm-surface-sunken);
  font-size: 0.76rem;
}

.csm-group-title {
  flex: 1 1 8rem;
  min-width: 0;
  font-weight: 600;
  color: var(--csm-ink);
  overflow-wrap: anywhere;
}

.csm-group-hours {
  color: var(--csm-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.csm-items {
  list-style: none;
  margin: 0;
  padding: 0;
}

.csm-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin: 0;
  padding: 0.35rem 0.6rem;
  font-size: 0.8rem;
  border-top: 1px solid var(--csm-border);
}

.csm-item:first-child {
  border-top: none;
}

.csm-item[draggable='true'] {
  cursor: grab;
}

.csm-item:hover {
  background: #fbfcfe;
}

/* The drop indicator. Drawn on dragover, acted on only in the drop event. */
.csm-item.is-drop-before::before,
.csm-item.is-drop-after::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  height: 2px;
  background: var(--primary-color, #0071e3);
}

.csm-item.is-drop-before::before {
  top: -1px;
}

.csm-item.is-drop-after::after {
  bottom: -1px;
}

.csm-item-title {
  flex: 1 1 8rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.csm-item-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.1rem;
  margin-inline-start: auto;
}

/* ── Placements whose subject moved to another track ──────────
   NOT this course's content, and the card has to say so without a sentence.
   So the block sits apart from the chapter groups, wears a warm dashed frame
   rather than the groups' solid one, and its rows carry no hours chip, no grip
   and no reorder arrows - nothing that would suggest they take part in the
   plan or in the hours bar above. The only control on them is release. */

.csm-stale {
  margin-top: 0.7rem;
  border: 1px dashed rgba(178, 106, 0, 0.42);
  border-radius: 10px;
  background: rgba(178, 106, 0, 0.04);
  overflow: hidden;
}

.csm-stale-head {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
  padding: 0.4rem 0.6rem;
  background: rgba(178, 106, 0, 0.08);
  font-size: 0.76rem;
}

.csm-stale-icon {
  color: var(--csm-warm);
}

.csm-stale-title {
  flex: 1 1 8rem;
  min-width: 0;
  font-weight: 600;
  color: #6b5220;
  overflow-wrap: anywhere;
}

.csm-stale-release-all {
  flex: 0 0 auto;
  padding: 0.2rem 0.55rem;
  font-size: 0.72rem;
}

.csm-stale-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.csm-stale-item {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin: 0;
  padding: 0.35rem 0.6rem;
  font-size: 0.8rem;
  border-top: 1px dashed rgba(178, 106, 0, 0.28);
}

.csm-stale-item-title {
  flex: 1 1 8rem;
  min-width: 0;
  color: var(--csm-muted);
  overflow-wrap: anywhere;
}

.csm-stale-release {
  margin-inline-start: auto;
}

.csm-stale-note {
  margin: 0;
  padding: 0.4rem 0.6rem 0.5rem;
  border-top: 1px dashed rgba(178, 106, 0, 0.28);
  font-size: 0.74rem;
  line-height: 1.6;
  color: #6b5220;
}

.csm-notes {
  display: flex;
  align-items: flex-start;
  gap: 0.45rem;
  margin: 0.7rem 0 0;
  padding: 0.5rem 0.65rem;
  background: rgba(178, 106, 0, 0.06);
  border-radius: 9px;
  font-size: 0.78rem;
  line-height: 1.6;
  color: #5c4a25;
  white-space: pre-wrap;
}

.csm-materials {
  list-style: none;
  margin: 0.55rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.csm-materials li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  font-size: 0.76rem;
  color: var(--csm-muted);
}

.csm-materials a {
  color: var(--primary-color, #0071e3);
  text-decoration: none;
  word-break: break-all;
}

.csm-materials a:hover {
  text-decoration: underline;
}

.csm-add-tail {
  align-self: flex-start;
  border-style: dashed;
}

/* ── Modals: editor, picker, proposal ───────────────────────── */

.csm-modal {
  direction: rtl;
  text-align: start;
}

/* The panel takes focus itself only as a fallback, when it holds no control of
   its own to hand the keyboard to. It is a landing place, not a control, so it
   is not outlined for a mouse - but a keyboard reader still gets the ring. */
.csm-modal:focus {
  outline: none;
}

.csm-modal:focus-visible {
  outline: 2px solid var(--primary-color, #0071e3);
  outline-offset: 2px;
}

.csm-material-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.4rem;
}

.csm-material-label {
  flex: 1 1 40%;
  min-width: 0;
}

.csm-material-url {
  flex: 1 1 60%;
  min-width: 0;
}

.csm-picker-lede {
  margin: 0 0 0.9rem;
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--csm-muted);
}

.csm-picker-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.csm-picker-list li {
  margin: 0;
}

.csm-picker-option {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--csm-border);
  border-radius: 10px;
  background: #fff;
  text-align: start;
  font-size: 0.85rem;
  cursor: pointer;
}

.csm-picker-option:hover {
  border-color: var(--primary-color, #0071e3);
  background: rgba(0, 113, 227, 0.04);
}

.csm-picker-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}

.csm-picker-hours {
  flex: 0 0 auto;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--csm-under);
  white-space: nowrap;
}

.csm-picker-hours.is-exact {
  color: var(--csm-exact);
}

.csm-picker-hours.is-over {
  color: var(--csm-over);
}

.csm-picker-footer {
  flex-wrap: wrap;
  gap: 0.4rem;
}

.csm-proposal-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  padding: 0.6rem 0.8rem;
  margin-bottom: 0.8rem;
  background: var(--csm-surface-sunken);
  border-radius: 10px;
  font-size: 0.8rem;
  color: var(--csm-muted);
}

.csm-proposal-stats strong {
  font-weight: 600;
  color: var(--csm-ink);
  font-variant-numeric: tabular-nums;
}

.csm-proposal-stats .is-alert strong {
  color: var(--csm-over);
}

.csm-proposal-note {
  margin: 0 0 0.5rem;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--csm-muted);
}

.csm-proposal-note.is-warn {
  color: var(--csm-warm);
}

/* The un-confirmable refusal: another track's prepared meeting holds this
   content. Read louder than a warning because no button on this screen can
   answer it - the fix is in the curriculum editor. */
.csm-proposal-block {
  margin: 0 0 0.7rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid rgba(190, 18, 60, 0.28);
  border-radius: 10px;
  background: rgba(190, 18, 60, 0.04);
}

.csm-proposal-block-lede {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--csm-over);
}

.csm-proposal-block-lede i {
  margin-left: 0.35rem;
}

.csm-proposal-block-list {
  margin: 0.4rem 0 0;
  padding-right: 1.1rem;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--csm-ink);
}

/* The way out, set apart from the refusal above it: the refusal is what
   happened, this is what to do about it. */
.csm-proposal-block-remedy {
  margin: 0.5rem 0 0;
  padding-top: 0.45rem;
  border-top: 1px solid rgba(190, 18, 60, 0.18);
  font-size: 0.78rem;
  line-height: 1.6;
  font-weight: 600;
  color: var(--csm-ink);
}

.csm-proposal-list {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.csm-proposal-session {
  margin: 0;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--csm-border);
  border-radius: 10px;
}

.csm-proposal-session.is-overflow {
  border-color: rgba(190, 18, 60, 0.28);
  background: rgba(190, 18, 60, 0.03);
}

.csm-proposal-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 0.35rem;
}

.csm-proposal-items {
  list-style: none;
  margin: 0;
  padding: 0 0.3rem 0 0;
  font-size: 0.78rem;
  color: var(--csm-ink);
}

.csm-proposal-items li {
  margin: 0 0 0.15rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.csm-proposal-chapter {
  color: var(--csm-muted);
  font-size: 0.72rem;
}

.csm-toast {
  text-align: right;
}

/* ── Tablet: the two panes stack, content first ─────────────── */

@media (min-width: 1025px) {
  /* Only worth pinning when there is a column to pin it beside. The admin
     shell scrolls `.admin-main`, not the document, which is what makes a
     sticky offset inside it behave. */
  .csm-pane {
    position: sticky;
    top: 0.5rem;
    max-height: calc(100vh - 7rem);
    overflow-y: auto;
  }
}

@media (max-width: 1024px) {
  .csm-body {
    grid-template-columns: minmax(0, 1fr);
  }

  .csm-header {
    align-items: flex-start;
  }
}

/* ── Phone: the content pane becomes a collapsible sheet ────── */

@media (max-width: 767px) {
  .csm-pane.is-collapsed .csm-pane-body {
    display: none;
  }

  .csm-pane-head {
    padding: 0.7rem 0.8rem;
  }

  .csm-toolbar {
    width: 100%;
  }

  .csm-course-tabs {
    width: 100%;
  }

  .csm-course-tab {
    flex: 1 1 0;
    justify-content: center;
    padding-inline: 0.4rem;
  }

  .csm-session {
    padding: 0.75rem 0.7rem 0.85rem;
  }

  .csm-session-actions {
    width: 100%;
    margin-inline-start: 0;
    justify-content: flex-end;
    flex-wrap: wrap;
  }

  .csm-status-select {
    flex: 1 1 100%;
    min-width: 0;
  }

  .csm-item-actions {
    width: 100%;
    margin-inline-start: 0;
    justify-content: flex-end;
  }

  .csm-target-input {
    width: 78px;
  }

  /* Nothing on this screen is a table, but a long untranslated identifier
     could still push the body sideways. Anything that overflows scrolls
     inside its own card, never the page. */
  .csm-groups,
  .csm-stale-list,
  .csm-proposal-list {
    overflow-x: auto;
  }
}
