/* =========================================================================
   Derslik — channel panel + members panel (slice 4)

   Owns: the `.guild-layout` row, the channel panel (`v5:287-410`) and the
   members panel (`v5:675-721`). The chat pane's internals belong to
   `dk/chat.css`, the stage and the dock to `dk/voice.css`.

   Loaded after `styles.css`, so the legacy `.channel-sidebar` / `.channel-row`
   / `.voice-channel` rules there are overridden rather than deleted — those
   selectors are still DOM hooks (`public/guild.js`, `public/notify.js`), only
   their looks change.
   ========================================================================= */

/* --- the workspace row ---------------------------------------------------
   `shell-extra.css` already makes `.guild-layout` the flex row; `styles.css`
   still pins a `height: calc(100vh - 56px)` from the retired app shell, which
   now overflows the workspace. Neutralise it here.
   ------------------------------------------------------------------------- */
.dk-workspace > .guild-layout {
  height: auto;
  min-height: 0;
  align-items: stretch;
}

/* The panel is a column: head → scrolling body → pinned voice dock. The
   pane-level `overflow-y:auto` from shell-extra would scroll the dock away.
   No `display` here on purpose: `.dk-pane` (base.css) already makes it a flex
   box, and restating it at this selector's weight beat the canonical
   `data-stage="zoom"` rule that has to take the panel away for a live lesson. */
.dk-workspace > .guild-layout > .channel-sidebar.dk-pane--sidebar {
  flex-direction: column;
  width: clamp(300px, 27vw, 420px);
  max-width: 44vw;
  overflow: hidden;
  padding: 0;
  background: var(--panel);
  border-right: 0;
}

/* --- panel header (v5:288-302) ------------------------------------------- */
.channel-sidebar > .sidebar-head {
  align-items: center;
  gap: var(--sp-5);
  padding: var(--sp-8) var(--sp-8) var(--sp-6);
}
.sidebar-id { flex: 1; min-width: 0; }
.channel-sidebar .guild-title {
  margin: 0;
  font: 800 var(--fs-md) / 1.25 var(--font);
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.channel-sidebar .guild-bio {
  margin: 0;
  font: 400 var(--fs-2xs) / 1.3 var(--font);
  color: var(--mut);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- "Sınıf kodu" pill + popover (v5:300) -------------------------------- */
.panel-code { position: relative; margin: 0 var(--sp-8) var(--sp-5); }
.panel-code__pill {
  width: 100%;
  justify-content: center;
  gap: var(--sp-4);
  letter-spacing: var(--ls-label);
}
.panel-code__pop {
  position: absolute;
  z-index: var(--z-popover);
  top: calc(100% + var(--sp-3));
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  text-align: center;
}
.panel-code__pop[hidden] { display: none; }
.panel-code__value { align-self: center; }
.panel-code__hint { margin: 0; font: 700 var(--fs-xs) / 1.35 var(--font); }

/* --- next lesson (schedule.js fills it, then unhides it) ----------------- */
.next-lesson {
  margin: 0 var(--sp-8) var(--sp-5);
  text-decoration: none;
  color: inherit;
}
.next-lesson[hidden] { display: none; }
.next-lesson-body { display: flex; flex-direction: column; min-width: 0; }
.next-lesson-body strong { font: 800 var(--fs-sm) / 1.25 var(--font); }
.next-lesson-body .muted { font: 700 var(--fs-2xs) / 1.25 var(--font); color: var(--mut); }

/* --- the scrolling body (v5:303) ----------------------------------------- */
.channel-sidebar > .panel-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--sp-3) var(--sp-5) var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.channel-group { display: flex; flex-direction: column; gap: var(--sp-1); }
.channel-sidebar .dk-subhead {
  margin: var(--sp-6) 0 var(--sp-3);
  padding: 0 var(--sp-4);
}
.channel-group:first-child .dk-subhead { margin-top: var(--sp-2); }
.channel-list { display: flex; flex-direction: column; gap: var(--sp-1); }
.channel-empty {
  margin: 0 var(--sp-2) var(--sp-3);
  padding: var(--sp-5);
  font-size: var(--fs-sm);
}

/* --- "+ Yeni kanal oluştur" (v5:306-318) --------------------------------- */
.add-channel { margin: 0 var(--sp-2) var(--sp-3); }
.add-channel__summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  padding: var(--sp-5);
  border-radius: var(--r-md);
  cursor: pointer;
  list-style: none;
  font: 800 var(--fs-sm) / 1 var(--font);
}
.add-channel__summary::-webkit-details-marker { display: none; }
.add-channel__summary:hover { background: var(--accSoft); }
.add-channel__summary:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
.add-channel__form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
  padding: var(--sp-5);
  border-radius: var(--r-md);
  background: var(--panel2);
}
.add-channel__hint {
  margin: var(--sp-3) var(--sp-2) 0;
  font: 600 var(--fs-xs) / 1.4 var(--font);
  color: var(--mut);
}
.add-channel__form .nsfw-toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font: 700 var(--fs-xs) / 1.2 var(--font);
  color: var(--mut);
}

/* --- channel rows (v5:319-330) -------------------------------------------
   `.channel-row` stays the hook wrapper; the `<a>` inside is the painted row.
   ------------------------------------------------------------------------- */
.channel-sidebar .channel-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0;
  border-radius: var(--r-md);
  background: transparent;
  box-shadow: none;
}
.channel-sidebar .channel-row:hover { background: transparent; }
.channel-sidebar .channel-row.active { background: transparent; box-shadow: none; }
.channel-sidebar .channel-item {
  flex: 1;
  min-width: 0;
  padding: var(--sp-4) var(--sp-5);
  color: var(--ink);
}
.channel-sidebar .channel-item .channel-hash {
  width: 30px;
  height: 30px;
  color: var(--mut);
  background: var(--panel2);
}
.channel-sidebar .channel-item.is-active .channel-hash { background: var(--acc); color: var(--accInk); }
.channel-sidebar .channel-row.active .channel-name { color: inherit; }
.channel-sidebar .channel-name { font-weight: 600; }
/* The delete affordance only appears on hover/focus, as it does today. */
.channel-sidebar .channel-del {
  flex: none;
  opacity: 0;
  padding: 0;
  color: var(--mut);
  background: transparent;
  border: 0;
}
.channel-sidebar .channel-row:hover .channel-del,
.channel-sidebar .channel-row:focus-within .channel-del,
.channel-sidebar .voice-channel:hover .channel-del,
.channel-sidebar .voice-channel:focus-within .channel-del { opacity: 1; }
.channel-sidebar .channel-del:hover { color: var(--bad); border-color: var(--bad); }
.channel-sidebar .channel-del:focus-visible { opacity: 1; }

/* notify.js appends the unread badge straight onto `.channel-row`. */
.channel-sidebar .channel-row .unread-badge {
  flex: none;
  margin-right: var(--sp-4);
  min-width: 18px;
  padding: 0 var(--sp-3);
  border-radius: var(--r-full);
  background: var(--bad);
  color: var(--badInk);
  font: 800 var(--fs-4xs) / 18px var(--font);
  text-align: center;
}
/* S-05 "a dot, not a pill": the channel row's selector above (0,3,0) out-weighed shell-extra's `.unread-badge.seeded` (0,2,0), so an
   unread plain message drew an 18x10 oval holding a 9 px bullet while the tab strip drew the round dot (phase-5
   ux-unread-dot-oval). Same reset, same weight as the rule it must beat. Count variants keep the pill. */
.channel-sidebar .channel-row .unread-badge.seeded {
  min-width: 0.6rem;
  width: 0.6rem;
  height: 0.6rem;
  padding: 0;
  font-size: 0;
  line-height: 0;
  vertical-align: middle;
}

/* --- sesli derslik cards (v5:357-371) ------------------------------------ */
.channel-sidebar .voice-channel {
  margin: 0 var(--sp-2) var(--sp-3);
  padding: var(--sp-7);
  background: var(--panel2);
}
.channel-sidebar .voice-channel.is-active { background: var(--accSoft); }
.vroom-head { gap: var(--sp-5) !important; }
.vroom-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 42px;
  height: 42px;
  border-radius: var(--r-lg);
  background: var(--panel);
  color: var(--acc);
}
.vroom-icon.is-exam { background: var(--warnSoft); color: var(--warn); }
.vroom-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 800 var(--fs-xl) / 1.2 var(--font);
}
.channel-sidebar .voice-join-btn {
  flex: none;
  padding: var(--sp-5) var(--sp-10);
  font-size: var(--fs-sm);
  white-space: nowrap;
}
.vroom-meta:empty { display: none; }
.vroom-count::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: var(--sp-2);
  border-radius: var(--r-full);
  background: currentColor;
}
.channel-sidebar .stage-badge {
  margin-left: 0;
  border: 0;
  padding: 2px var(--sp-4);
  font-size: var(--fs-4xs);
}

/* The roster under a room: one avatar chip per participant (voice.js paints). */
.channel-sidebar .voice-participants {
  list-style: none;
  margin: 0;
  padding: 0 0 0 53px;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--mut);
}
.channel-sidebar .voice-participants:empty { display: none; }
.channel-sidebar .voice-participants li {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 2px var(--sp-4) 2px 2px;
  border-radius: var(--r-full);
  background: var(--panel);
  font: 700 var(--fs-xs) / 1.2 var(--font);
  color: var(--ink);
}
.channel-sidebar .voice-participants li.hand-raised {
  background: var(--warnSoft);
  color: var(--warn);
}
.vp-flags { color: var(--mut); font-size: var(--fs-3xs); }
.channel-sidebar .voice-participants .btn-tiny {
  border: 0;
  border-radius: var(--r-2xs);
  padding: 1px var(--sp-3);
  background: var(--accSoft);
  color: var(--accInkSoft);
  font: 800 var(--fs-4xs) / 1.4 var(--font);
  cursor: pointer;
}
.channel-sidebar .voice-participants .btn-tiny:hover { background: var(--acc); color: var(--accInk); }

/* The companion "<oda> sohbeti" row, indented under its room (v5:1456-1464). */
.vroom-companion { margin: var(--sp-3) 0 0 42px; }
.vroom-companion .channel-item { padding: var(--sp-3) var(--sp-4); }
.vroom-companion .channel-hash { width: 26px; height: 26px; }

/* --- DERS ARAÇLARI (v5:373-385) ------------------------------------------ */
.panel-tools { display: flex; flex-direction: column; gap: var(--sp-3); padding: 0 var(--sp-2); }
.panel-tools .dk-row--tool { width: 100%; gap: var(--sp-5); }
.panel-tools .dk-row__icon {
  width: 34px;
  height: 34px;
  border-radius: var(--r-sm);
  background: var(--panel);
  color: var(--acc);
}
.tool-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.tool-name { font: 800 var(--fs-sm) / 1.2 var(--font); }
.tool-sub { font: 700 var(--fs-2xs) / 1.25 var(--font); color: var(--mut); }
.tool-chevron { flex: none; color: var(--mut); font-size: var(--fs-md); }
.dk-row--tool.is-disabled { opacity: 0.5; cursor: not-allowed; }
.dk-row--tool.is-disabled:hover { border-color: var(--line); background: var(--panel2); }

/* --- members panel (v5:675-721) ------------------------------------------
   The pane itself (`.dk-pane--members`: width, padding, scroll, `[hidden]`) is
   a base primitive now — `dk/base.css`, visual-system §7. What follows is the
   derslik-specific content of that pane.
   ------------------------------------------------------------------------- */
.members-sec + .members-sec { margin-top: var(--sp-6); }
/* spec §4.7 (v5:1662-1663): the two sections are exclusive — while you are in a
   room the panel shows who is *in the room*, not the whole class list. */
.members-pane:has([data-members-inroom-sec]:not([hidden])) > .members-sec:not([data-members-inroom-sec]) {
  display: none;
}
.members-pane .dk-subhead { margin: 0 0 var(--sp-4); padding: 0 var(--sp-3); }
.members-list { display: flex; flex-direction: column; gap: var(--sp-3); }
.members-pane .member-row {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  margin: 0;
  padding: var(--sp-5);
  border-radius: var(--r-md);
  background: var(--panel2);
}
.members-pane .member-row .dk-avatar { position: relative; }
/* `chat.js:922` repaints presence with the bare state words, not `is-*`. */
.members-pane .presence-dot.online { background: var(--ok); }
.members-pane .presence-dot.idle { background: var(--warn); }
.members-pane .presence-dot.dnd { background: var(--bad); }
.members-pane .presence-dot.offline { background: var(--mut); }
.member-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.member-name {
  font: 700 var(--fs-sm) / 1.25 var(--font);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.member-tag { font: 800 var(--fs-4xs) / 1.3 var(--font); color: var(--accText); letter-spacing: var(--ls-label); } /* H-87: 9px text keeps the 4.5:1 floor */
.member-flag { flex: none; }

/* H-106: a member whose school membership ended is listed "askıda" (accessState suspended_idp): a muted chip, a dimmed
   avatar and name, no actions (the views and the client twins decide which rows get it; this only paints it). The chip is a
   .dk-badge (muted on --panel2); the text is the words as typed, not upper-cased. */
.member-askida, .fd-askida { text-transform: none; font-weight: 700; }
.fd-askida {
  display: inline-block;
  margin-left: var(--sp-3);
  padding: 1px var(--sp-3);
  border-radius: var(--r-2xs);
  background: var(--panel2);
  color: var(--mut);
  font-size: var(--fs-4xs);
  line-height: 1.4;
}
.members-pane .member-row.is-askida .dk-avatar,
.fd-row.is-askida .fd-avatar { opacity: 0.55; }
.members-pane .member-row.is-askida .member-name,
.fd-row.is-askida .fd-name { color: var(--mut); }
.member-meta .member-askida { align-self: flex-start; margin-top: 1px; }
.gs-member.is-askida .gs-member__name > strong { color: var(--mut); }


/* The in-room rows voice.js paints: name line + the moderator menu (v5:686-694,
   minus the two actions with no endpoint — G7 kick and G9 assistant). */
.members-pane .member-row.has-menu { flex-direction: column; align-items: stretch; gap: 0; }
/* The flags (✋ söz, KAMERA / EKRAN grants) used to share the name's line and squeezed it to "Mer…" in the
   236px pane. The name now keeps a floor (7rem: "Zeynep Ak" fits whole); when the flags do not fit beside
   it they wrap onto a line of their own under the avatar and name, they never take the name's room. */
.member-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-5); min-width: 0; }
.member-line .dk-avatar { position: relative; flex: none; }
.member-line .member-meta { flex: 1 1 7rem; min-width: 7rem; }
/* v5:684 keeps the menu behind a chevron. Collapsed with max-height rather than
   `display:none` so the buttons stay in the tab order and focus opens the row. */
.member-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  max-height: 0;
  padding-top: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height var(--dur-2) var(--ease), opacity var(--dur-2) var(--ease),
    padding-top var(--dur-2) var(--ease);
}
.members-pane .member-row:hover .member-actions,
.members-pane .member-row:focus-within .member-actions {
  max-height: 6rem;
  padding-top: var(--sp-3);
  opacity: 1;
}
.member-actions .dk-btn { flex: 1 1 auto; justify-content: center; padding: var(--sp-3) var(--sp-4); }

/* The zoom stage (spec §2.2) is declared in one canonical block in
   `dk/base.css` — tab strip *and* channel panel — so the whole state reads in
   one place. Nothing about it belongs here. */

/* --- narrow screens ------------------------------------------------------ */
/* The workspace is height-locked and clips, so wrapping the row would push the
   panel off-screen. Below 1100 px the members pane leaves the row and becomes a DRAWER over the chat's right edge:
   closed by default, opened by the same header toggle (public/guild.js membersPane), closed again by the toggle,
   Esc or a click outside. It used to be `display:none` there while the toggle stayed active and could never show
   it - in a call that took the ODADAKİLER roster and the member menu (Sustur / Söz ver / Kamera / Ekran) off the
   screen (phase-5 ux-members-toggle-dead-1100). `[hidden]` (base.css) still wins when it is closed. */
@media (max-width: 1100px) {
  .dk-workspace > .guild-layout { position: relative; }
  .dk-pane--members:not([hidden]) {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-popover);
    width: min(320px, 92%);
    background: var(--panel);
    border-left: var(--bw, 1px) solid var(--line);
    box-shadow: var(--shadow-modal);
  }
}
@media (max-width: 900px) {
  .dk-workspace > .guild-layout > .channel-sidebar.dk-pane--sidebar {
    width: clamp(220px, 34vw, 300px);
  }
  .channel-sidebar .vroom-name { font-size: var(--fs-lg); }
  .channel-sidebar .voice-participants,
  .vroom-companion { padding-left: 0; margin-left: 0; }
}

/* OD-22 (phase 9): a CATEGORY groups the text channels filed under it (parent_id): a muted heading, its channels indented. */
.channel-category { margin-top: var(--sp-5); }
.channel-category-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-4);
  color: var(--mut);
}
.channel-category-name {
  flex: 1;
  min-width: 0;
  margin: 0;
  font: 800 var(--fs-3xs) / 1.3 var(--font);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--mut);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.channel-category__children { padding-left: var(--sp-4); }
