/* Ilova qatlamining uslublari — dizayn tizimi bermaydigan narsalar:
   modal oyna, fokusli grid, grid tekisligi.
   Barcha qiymat tokenlardan; o'ylab topilgan rang yo'q. */

/* ---------- Grid tekisligi ----------
   Katakchalar balandligi har xil bo'lsa, grid qatorlarida bo'shliq
   qoladi. Katakcha ustunini to'liq cho'zamiz. */
.ds-grid > div { display: flex; }
.ds-grid > div > .ds-tile,
.ds-grid > div > div { width: 100%; }
.ds-grid > div > .ds-tile { display: flex; flex-direction: column; }

/* ---------- Modal oyna ---------- */
.app-modal-back {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--scrim);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--space-32) var(--space-24);
  overflow: auto;
  animation: appFade var(--dur-hover) var(--ease-hover);
}
@keyframes appFade { from { opacity: 0 } to { opacity: 1 } }

.app-modal {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  animation: appRise var(--dur-tile) var(--ease-soft);
}
@keyframes appRise {
  from { opacity: 0; transform: translateY(12px) }
  to { opacity: 1; transform: none }
}

.app-modal-head {
  display: flex;
  align-items: center;
  gap: var(--space-16);
  padding: var(--space-20) var(--space-24);
  border-bottom: 1px solid var(--line-soft);
  background: var(--surface);
}
.app-modal-actions { margin-left: auto; display: flex; align-items: center; gap: var(--space-8); }
.app-modal-body { padding: var(--space-24); }
.app-modal-foot {
  padding: var(--space-16) var(--space-24);
  border-top: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  gap: var(--space-12);
}

/* ---------- Fokusli grid ---------- */
.app-pick { cursor: pointer; border-radius: var(--r-sm); min-width: 0; }
.app-pick:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.app-pick > * { pointer-events: none; }

.app-focus { display: flex; flex-direction: column; gap: var(--space-12); }
.app-focus-main { position: relative; }
.app-focus-tools {
  position: absolute;
  top: var(--space-12);
  right: var(--space-12);
  display: flex;
  gap: var(--space-8);
}
.app-strip .app-pick { flex: 0 0 210px; }

/* ---------- Tab panellari ---------- */
.app-panel[hidden] { display: none !important; }

/* Segment tanlagich bosiladigan ko'rinishda */
.ds-seg > * { cursor: pointer; }

/* ---------- Scroll'da yopiladigan sarlavha ----------
   Pastga surilganda panel yig'iladi, yuqoriga surilganda qaytadi.
   Kamera va jadval uchun joy ochiladi. */
.ds-topbar {
  transition: transform var(--dur-tile) var(--ease-soft);
  will-change: transform;
}
.ds-topbar.is-hidden { transform: translateY(-100%); }

@media (prefers-reduced-motion: reduce) {
  .ds-topbar { transition: none; }
}

/* Yuqori paneldagi mikrofon ishlatilmaydi — u dashboardda suzib turadi */
.ds-topbar .ds-mic { display: none; }

/* ---------- Suzuvchi AI tugmasi (faqat Dashboard) ---------- */
.app-ai-fab {
  position: fixed;
  right: var(--space-24);
  bottom: var(--space-24);
  z-index: 40;
  width: 60px; height: 60px;
  display: grid; place-items: center;
  border: 0;
  border-radius: var(--r-full);
  background: linear-gradient(150deg, var(--accent-soft), var(--accent));
  color: var(--on-fill);
  cursor: pointer;
  box-shadow: 0 16px 36px -12px var(--accent-tint),
              inset 0 1px 0 var(--surface-3);
  transition: transform var(--dur-tile) var(--ease-soft),
              box-shadow var(--dur-tile) var(--ease-soft),
              background var(--dur-tile) var(--ease-soft);
}
.app-ai-fab:hover {
  transform: translateY(-3px) scale(1.04);
  box-shadow: 0 24px 46px -12px var(--accent-tint),
              inset 0 1px 0 var(--surface-3);
}
.app-ai-fab:active { transform: translateY(-1px) scale(.97); }
.app-ai-fab:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: 4px; }

/* Holat rangi gradient bilan beriladi, shuning uchun to'liq qayta yoziladi */
.app-ai-fab.is-tinglash { background: linear-gradient(150deg, var(--late), var(--absent)); }
.app-ai-fab.is-tahlil   { background: linear-gradient(150deg, var(--cat-3), var(--late)); }
.app-ai-fab.is-gapirish { background: linear-gradient(150deg, var(--ok), var(--info)); }

/* ---------- Tugma atrofidagi halqalar ----------

   Uch qatlam: `.app-ai-halo` (doimiy sekin nafas), `::before` va
   `::after` (tinglashdagi ketma-ket to'lqinlar). Tahlil holatida
   `::after` aylanuvchi yoyga aylanadi. Faqat transform va opacity
   o'zgaradi — brauzer sahifani qayta hisoblamaydi. */

.app-ai-halo {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid var(--accent-soft);
  opacity: 0;
  pointer-events: none;
  animation: aiHalqa 3.4s var(--ease-soft) infinite;
}
.app-ai-fab::before,
.app-ai-fab::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
}

.app-ai-fab.is-tinglash .app-ai-halo { border-color: var(--absent); animation-duration: 1.8s; }
.app-ai-fab.is-tinglash::before,
.app-ai-fab.is-tinglash::after {
  border: 2px solid var(--absent);
  animation: aiHalqa 1.8s var(--ease-soft) infinite;
}
.app-ai-fab.is-tinglash::before { animation-delay: .6s; }
.app-ai-fab.is-tinglash::after  { animation-delay: 1.2s; }

.app-ai-fab.is-gapirish .app-ai-halo { border-color: var(--info); animation-duration: 2.2s; }

/* Tahlil: javob kutilayotgani aylanuvchi yoy bilan ko'rsatiladi */
.app-ai-fab.is-tahlil .app-ai-halo { animation: none; opacity: 0; }
.app-ai-fab.is-tahlil::after {
  inset: -6px;
  opacity: 1;
  border: 2px solid transparent;
  border-top-color: var(--late);
  border-right-color: var(--late);
  animation: aiAylan .85s linear infinite;
}

@keyframes aiHalqa {
  0%   { opacity: .5; transform: scale(1) }
  70%  { opacity: 0;  transform: scale(1.45) }
  100% { opacity: 0;  transform: scale(1.45) }
}
@keyframes aiAylan { to { transform: rotate(360deg) } }

/* ---------- Jonli mikrofon belgisi ----------

   Bitta shakl to'rt holatda ishlaydi: tinch (sekin nafas), tinglash
   (tez ekvalayzer), tahlil (yuguruvchi to'lqin), gapirish (nutq
   ritmi). Holat sinfi OTA elementda (`.app-ai-fab` yoki
   `.app-ai-panel`) turadi — shuning uchun tugmadagi, sarlavhadagi va
   pastdagi belgilar bir vaqtda bir xil holatni ko'rsatadi.

   O'lcham `--mic-o` orqali beriladi, shakl esa 32 birlik viewBox'da —
   har qanday o'lchamda o'tkir chiqadi. */

.app-mic {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--mic-o, 22px);
  height: var(--mic-o, 22px);
  flex: none;
  color: inherit;
}
.app-mic svg { display: block; width: 100%; height: 100%; overflow: visible; }

.app-mic-body { fill: currentColor; }
.app-mic-arc,
.app-mic-stem {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

/* `transform-box: fill-box` bo'lmasa SVG ichidagi transform butun
   viewBox'ga nisbatan hisoblanadi va tayoqcha joyidan siljib ketadi. */
.app-mic-bar {
  fill: currentColor;
  transform-box: fill-box;
  transform-origin: center;
  animation: micNafas 2.8s ease-in-out infinite;
}
.app-mic-bar:nth-child(1) { animation-delay: 0s; }
.app-mic-bar:nth-child(2) { animation-delay: .35s; }
.app-mic-bar:nth-child(3) { animation-delay: .18s; }
.app-mic-bar:nth-child(4) { animation-delay: .52s; }

/* Kichik o'lchamda to'rt tayoqcha g'ijimlanadi — tashqi juftini olamiz */
.app-mic.is-kichik .app-mic-bar:nth-child(1),
.app-mic.is-kichik .app-mic-bar:nth-child(4) { display: none; }

@keyframes micNafas {
  0%, 100% { transform: scaleY(.42); opacity: .45 }
  50%      { transform: scaleY(.84); opacity: .85 }
}

/* Tinglash — tirik ekvalayzer */
.is-tinglash .app-mic-bar { animation: micEshit .62s ease-in-out infinite; }
.is-tinglash .app-mic-bar:nth-child(1) { animation-delay: .07s; }
.is-tinglash .app-mic-bar:nth-child(2) { animation-delay: .21s; }
.is-tinglash .app-mic-bar:nth-child(3) { animation-delay: 0s; }
.is-tinglash .app-mic-bar:nth-child(4) { animation-delay: .14s; }
@keyframes micEshit {
  0%, 100% { transform: scaleY(.26); opacity: .6 }
  32%      { transform: scaleY(1.12); opacity: 1 }
  64%      { transform: scaleY(.52); opacity: .85 }
}
.is-tinglash .app-mic-body {
  transform-box: fill-box;
  transform-origin: center;
  animation: micTana 1.24s ease-in-out infinite;
}
@keyframes micTana {
  0%, 100% { transform: scale(1) }
  50%      { transform: scale(1.08) }
}

/* Tahlil — chapdan o'ngga yuguruvchi to'lqin */
.is-tahlil .app-mic-bar { animation: micOylash 1.15s ease-in-out infinite; }
.is-tahlil .app-mic-bar:nth-child(1) { animation-delay: 0s; }
.is-tahlil .app-mic-bar:nth-child(2) { animation-delay: .12s; }
.is-tahlil .app-mic-bar:nth-child(3) { animation-delay: .24s; }
.is-tahlil .app-mic-bar:nth-child(4) { animation-delay: .36s; }
@keyframes micOylash {
  0%, 100% { transform: scaleY(.24); opacity: .34 }
  40%      { transform: scaleY(.96); opacity: .95 }
}

/* Gapirish — nutqqa o'xshash notekis ritm */
.is-gapirish .app-mic-bar { animation: micGapir .84s ease-in-out infinite; }
.is-gapirish .app-mic-bar:nth-child(1) { animation-delay: 0s; }
.is-gapirish .app-mic-bar:nth-child(2) { animation-delay: .19s; }
.is-gapirish .app-mic-bar:nth-child(3) { animation-delay: .09s; }
.is-gapirish .app-mic-bar:nth-child(4) { animation-delay: .28s; }
@keyframes micGapir {
  0%, 100% { transform: scaleY(.34); opacity: .7 }
  25%      { transform: scaleY(.94); opacity: 1 }
  55%      { transform: scaleY(.46); opacity: .8 }
  78%      { transform: scaleY(.80); opacity: .95 }
}

/* Jonli rejim: tayoqchalar haqiqiy ovoz kuchiga qarab qimirlaydi
   (`ai.js` -> darajaQoy). CSS animatsiyasi o'chiriladi, aks holda
   ikkita harakat ustma-ust tushardi. `transition` sakrashni yumshatadi. */
.app-mic.is-jonli .app-mic-bar {
  animation: none !important;
  transition: transform 70ms linear, opacity 70ms linear;
}

/* Paneldagi belgilar ham holat rangini oladi */
.app-ai-head .app-mic,
.app-ai-mic .app-mic { transition: color var(--dur-hover) var(--ease-hover); }
.app-ai-panel.is-tinglash .app-ai-head .app-mic,
.app-ai-panel.is-tinglash .app-ai-mic { color: var(--absent); }
.app-ai-panel.is-tahlil .app-ai-head .app-mic,
.app-ai-panel.is-tahlil .app-ai-mic { color: var(--late); }
.app-ai-panel.is-gapirish .app-ai-head .app-mic,
.app-ai-panel.is-gapirish .app-ai-mic { color: var(--info); }

/* Harakat kamaytirilgan bo'lsa belgi qimirlamaydi, lekin o'qiladi */
@media (prefers-reduced-motion: reduce) {
  .app-mic-bar,
  .app-mic-body,
  .app-ai-halo,
  .app-ai-fab::before,
  .app-ai-fab::after { animation: none !important; }
  .app-mic-bar { opacity: .7; }
  .app-ai-fab:hover { transform: none; }
}

/* ---------- AI paneli ---------- */
.app-ai-panel {
  position: fixed;
  right: var(--space-24);
  bottom: calc(var(--space-24) + 72px);
  z-index: 40;
  width: 420px;
  max-height: min(70vh, 640px);
  display: flex; flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  animation: appRise var(--dur-tile) var(--ease-soft);
}
.app-ai-head {
  display: flex; align-items: center; gap: var(--space-12);
  padding: var(--space-16) var(--space-20);
  border-bottom: 1px solid var(--line-soft);
  background: var(--surface);
}
.app-ai-log { flex: 1; overflow: auto; padding: var(--space-16) var(--space-20); }
.app-ai-turn { margin-bottom: var(--space-16); }
.app-ai-q {
  color: var(--accent-soft);
  font-weight: 600;
  margin-bottom: var(--space-8);
}
.app-ai-a { white-space: pre-wrap; }
.app-ai-src { margin-top: var(--space-8); color: var(--faint); }
.app-ai-foot {
  display: flex; gap: var(--space-8); align-items: center;
  padding: var(--space-12) var(--space-20);
  border-top: 1px solid var(--line-soft);
}
.app-ai-input {
  flex: 1;
  height: 38px;
  padding: 0 var(--space-12);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--text);
  font: inherit;
  font-size: 14px;
}
.app-ai-input::placeholder { color: var(--faint); }
.app-ai-chips { display: flex; flex-wrap: wrap; gap: var(--space-8); }
.app-ai-chips button {
  all: unset;
  cursor: pointer;
  padding: var(--space-4) var(--space-12);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  color: var(--muted);
  font-size: 13px;
}
.app-ai-chips button:hover { color: var(--text); background: var(--surface-3); }

/* ---------- Chap menyu scroll'da joyida qoladi ----------
   Sidebar grid ustuni bo'lib butun sahifa balandligiga cho'ziladi va
   scroll'da yuqoriga ketib qoladi. Ekran balandligiga qisqartirib,
   sticky qilamiz: kontent suriladi, menyu turadi. */
.ds-shell > .ds-sidebar {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Menyu ichi ekranga sig'masa, o'zi suriladi va pastki karta joyida qoladi */
.ds-shell > .ds-sidebar::-webkit-scrollbar { width: 6px; }
.ds-shell > .ds-sidebar::-webkit-scrollbar-thumb {
  background: var(--surface-3);
  border-radius: var(--r-xs);
}

/* ---------- Sozlamalar: kiritish maydoni va belgilash ro'yxati ---------- */
.app-input {
  height: 38px;
  padding: 0 var(--space-12);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  width: 100%;
}
.app-input::placeholder { color: var(--faint); }
.app-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.app-list { display: flex; flex-direction: column; gap: 2px; }
.app-list.is-scroll { max-height: 280px; overflow-y: auto; padding-right: var(--space-4); }

.app-check {
  display: flex; align-items: center; gap: var(--space-8);
  padding: var(--space-8) var(--space-12);
  border-radius: var(--r-sm);
  cursor: pointer;
}
.app-check:hover { background: var(--surface-2); }
.app-check input { accent-color: var(--accent); width: 15px; height: 15px; flex-shrink: 0; }

/* Masofaviy dars oynasi — fokus rejimida kamera o'rnida */
.app-lesson-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  background: var(--bg);
}

/* ---------- Davomat qamrovi ---------- */
.app-scope {
  display: flex; align-items: center; gap: var(--space-12);
  padding: var(--space-12) var(--space-16);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: border-color var(--dur-hover) var(--ease-hover),
              background var(--dur-hover) var(--ease-hover);
}
.app-scope:hover { background: var(--surface-2); }
.app-scope:has(input:checked) { border-color: var(--accent); background: var(--accent-tint); }
.app-scope input { accent-color: var(--accent); width: 16px; height: 16px; flex-shrink: 0; }

/* Masofaviy — davomat boshqa manbadan, shuning uchun alohida belgilanadi */
.app-scope.is-eduon:has(input:checked) {
  border-color: var(--info);
  background: var(--info-tint);
}

.app-note {
  display: flex; align-items: flex-start; gap: var(--space-8);
  padding: var(--space-12) var(--space-16);
  border: 1px solid var(--line);
  border-left: 3px solid var(--info);
  border-radius: var(--r-sm);
  color: var(--muted);
}
.app-note svg { flex-shrink: 0; color: var(--info); margin-top: 1px; }

/* Haqiqiy surat avatar ichida — bosh harflar o'rniga (App.rasmliAvatar) */
.ds-avatar.is-photo {
  background-size: cover;
  background-position: center 22%;
  color: transparent;
  text-indent: -9999px;
}

/* ---------------------------------------------------------------------
   Dashboard: qo'shni katakchalar balandligi
   ---------------------------------------------------------------------
   `.ds-grid` — oddiy CSS grid: qatordagi hamma element eng balandiga
   tenglashadi. Haqiqiy ma'lumot ulangach o'ng katakcha o'sdi, chapdagisi
   esa o'z balandligida qolib, tagida bo'shliq qoldi.

   Yechim uch qadam: ustun to'liq qatorni egallaydi → katakcha ustunni
   to'ldiradi → katakcha tanasi (`.app-fill`) qolgan joyni olib,
   ichidagini markazlaydi. Ba'zi katakchalar qo'shimcha `div` ichida
   (id bilan yangilanishi uchun), shuning uchun oraliq qatlam ham
   hisobga olingan. */
.ds-grid > div { display: flex; flex-direction: column; min-width: 0; }
.ds-grid > div > .ds-tile,
.ds-grid > div > div { flex: 1; min-height: 0; }
.ds-grid > div > div:not(.ds-tile) { display: flex; flex-direction: column; }
.ds-grid > div > div > .ds-tile { flex: 1; }
.ds-grid .ds-tile { display: flex; flex-direction: column; }
.ds-grid .ds-tile > .ds-tile-head { flex: 0 0 auto; }

/* Katakcha tanasi qolgan balandlikni oladi va ichidagini markazlaydi */
.app-fill {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 0;
}

/* Uzun ro'yxatlar: barcha kafedra/bo'lim ko'rinadi, ortig'i scroll bo'ladi */
.app-scrollist {
  max-height: 420px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: var(--space-8);
  margin-right: calc(-1 * var(--space-8));
}
.app-scrollist::-webkit-scrollbar { width: 8px; }
.app-scrollist::-webkit-scrollbar-thumb {
  background: var(--surface-3);
  border-radius: 4px;
}
.app-scrollist::-webkit-scrollbar-thumb:hover { background: var(--line); }


/* ---------- Masofaviy ta'lim: jonli qatlam ----------

   Ayni damda ketayotgan darslardagi ishtirok. Yakuniy davomat bilan
   ARALASHTIRILMAYDI, shuning uchun alohida ramka va alohida rang
   (`--info`) bilan ajratilgan: pastdagi halqa tugagan darslar hisobi. */
.app-jonli-blok {
  padding: var(--space-16);
  margin-bottom: var(--space-20);
  border: 1px solid var(--line);
  border-left: 3px solid var(--info);
  border-radius: var(--r-sm);
  background: var(--info-tint);
}

/* Efirdagi belgi — ma'lumot jonli ekanini bildiradi */
.app-jonli-nuqta {
  width: 8px; height: 8px;
  border-radius: var(--r-full);
  background: var(--info);
  flex: none;
  animation: appEfir 1.8s var(--ease-soft) infinite;
}
@keyframes appEfir {
  0%, 100% { opacity: 1;   box-shadow: 0 0 0 0 var(--info-tint) }
  50%      { opacity: .55; box-shadow: 0 0 0 6px transparent }
}

@media (prefers-reduced-motion: reduce) {
  .app-jonli-nuqta { animation: none; }
}

/* ====================================================================
   Jonlantirish qatlami — `jonli.js` bilan juft ishlaydi.

   Dizayn tizimi (`bundle.css`) tegilmaydi: harakat shu yerda, ilova
   qatlamida qo'shiladi. Hamma qiymat tokenlardan.

   Qoida: faqat `transform`, `opacity`, `width`, `height` va
   `stroke-dasharray` o'zgaradi — bular kompozitorda bajariladi yoki
   bitta elementni qayta chizadi, sahifa tartibini qo'zg'atmaydi.
   ==================================================================== */

/* ---------- Qiymat yangilanganda qisqa yorug'lik ----------
   Ma'lumot kelganda qaysi raqam o'zgarganini ko'rsatadi. */
.app-yangi {
  animation: appYangi 1.2s var(--ease-soft);
}
@keyframes appYangi {
  0%   { color: var(--accent-soft); text-shadow: 0 0 12px var(--accent-tint) }
  100% { color: inherit; text-shadow: none }
}

/* ---------- Chiziqli diagrammalar ----------
   O'sish tugagach ustidan sekin yorug'lik o'tadi: ko'rsatkich
   "tirik" ekani sezilib turadi, lekin raqamni o'qishga xalaqit
   qilmaydi (yorug'lik past, harakat sekin). */
.app-jonli-chiziq {
  position: relative;
  overflow: hidden;
}
.app-jonli-chiziq.is-oqim::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(
    100deg,
    transparent 0%,
    var(--surface-3) 42%,
    var(--surface-3) 58%,
    transparent 100%);
  transform: translateX(-140%);
  animation: appOqim 4.2s var(--ease-soft) infinite;
  animation-delay: var(--jonli-kech, 0s);
  pointer-events: none;
}
@keyframes appOqim {
  0%   { transform: translateX(-140%) }
  55%  { transform: translateX(140%) }
  100% { transform: translateX(140%) }
}

/* ---------- Issiqlik xaritasi katakchalari ---------- */
.app-jonli-katak {
  animation: appKatak 420ms var(--ease-soft) both;
  animation-delay: var(--jonli-kech, 0ms);
}
@keyframes appKatak {
  from { opacity: 0; transform: scale(.72) }
  to   { opacity: 1; transform: none }
}

/* ---------- Halqa uchidagi nuqta ----------
   Diagramma o'sib bo'lgach ham urib turadi — joriy ko'rsatkich shu
   yerda ekanini bildiradi. */
.app-halqa-nuqta {
  transform-box: fill-box;
  transform-origin: center;
  animation: appNuqta 2.1s var(--ease-soft) infinite;
}
@keyframes appNuqta {
  0%, 100% { transform: scale(1);    opacity: .95 }
  50%      { transform: scale(1.45); opacity: .55 }
}

/* ---------- Donut atrofidagi aylanuvchi yorug'lik ----------
   `--jonli-aylana` — aylana uzunligi, `jonli.js` hisoblab beradi.
   Bir aylanish 9 soniya: ko'z ilg'aydi, lekin chalg'itmaydi. */
.app-donut-yoruglik {
  opacity: .16;
  animation: appAylanma 9s linear infinite;
}
@keyframes appAylanma {
  from { stroke-dashoffset: 0 }
  to   { stroke-dashoffset: calc(var(--jonli-aylana) * -1px) }
}

/* ---------- KPI katakchasi: kirish ----------
   Katakchalar pastdan ko'tarilib chiqadi. Kechikish grid tartibida
   berilgani uchun ko'z chapdan o'ngga ergashadi. */
.ds-grid > div {
  animation: appKirish 520ms var(--ease-soft) both;
}
.ds-grid > div:nth-child(1) { animation-delay: 0ms }
.ds-grid > div:nth-child(2) { animation-delay: 60ms }
.ds-grid > div:nth-child(3) { animation-delay: 120ms }
.ds-grid > div:nth-child(4) { animation-delay: 180ms }
.ds-grid > div:nth-child(5) { animation-delay: 240ms }
.ds-grid > div:nth-child(6) { animation-delay: 300ms }
.ds-grid > div:nth-child(n+7) { animation-delay: 340ms }
@keyframes appKirish {
  from { opacity: 0; transform: translateY(14px) }
  to   { opacity: 1; transform: none }
}

/* Raqamlar sanalayotganda ustun tebranmasin */
.ds-kpi-value, .ds-num, .ds-barval { font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  .app-yangi,
  .app-jonli-chiziq.is-oqim::after,
  .app-jonli-katak,
  .app-halqa-nuqta,
  .app-donut-yoruglik,
  .ds-grid > div { animation: none !important; }
  .app-jonli-chiziq.is-oqim::after { display: none; }
}


/* ====================================================================
   Yorug' tema — nozik to'g'rilashlar

   Ranglar tokenlarda (tokens.json → tokens.css) va ular o'zi
   almashadi. Bu yerda faqat temaga bog'liq STRUKTURA farqlari:
   qorong'ida qatlamlilik chegara bilan berilgan edi, yorug'da esa oq
   karta oq-kulrang fonda faqat chegara bilan ajralmaydi — soya kerak.

   Qoida: selektorlar `:root:not([data-theme="dark"])` bilan boshlanadi,
   ya'ni standart (yorug') holatda ishlaydi va qorong'iga tegmaydi.
   ==================================================================== */

/* `bundle.css` `:root { color-scheme: dark }` deb belgilaydi va u
   tokens.css dan KEYIN ulanadi. Ilova qatlami eng oxirgi — to'g'ri
   qiymat shu yerda beriladi. Bu scrollbar, forma elementlari va
   brauzerning o'z ranglariga ta'sir qiladi. */
:root { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* ---------- Qatlam soyasi ---------- */
:root:not([data-theme="dark"]) .ds-tile,
:root:not([data-theme="dark"]) .app-modal {
  box-shadow: 0 1px 2px var(--shadow), 0 10px 28px -16px var(--shadow-strong);
}
:root:not([data-theme="dark"]) .ds-sidebar {
  box-shadow: 1px 0 3px -1px var(--shadow);
}
:root:not([data-theme="dark"]) .ds-topbar {
  box-shadow: 0 1px 0 var(--line);
}

/* Suzuvchi AI tugmasi yorug' fonda kuchliroq soya bilan turadi */
:root:not([data-theme="dark"]) .app-ai-fab {
  box-shadow: 0 10px 24px -8px var(--shadow-strong),
              0 2px 6px var(--shadow);
}
:root:not([data-theme="dark"]) .app-ai-fab:hover {
  box-shadow: 0 18px 34px -10px var(--shadow-strong),
              0 2px 6px var(--shadow);
}
:root:not([data-theme="dark"]) .app-ai-panel {
  box-shadow: 0 18px 48px -18px var(--shadow-strong), 0 2px 8px var(--shadow);
}

/* Brend belgisi oq fonda o'z holicha turadi — to'ldirish shart emas */
:root:not([data-theme="dark"]) .ds-brand-mark { background: transparent; }

/* ---------- Tema tanlagich ---------- */
.app-tema {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface-2);
  flex: none;
}
.app-tema button {
  display: grid;
  place-items: center;
  width: 28px; height: 28px;
  padding: 0;
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background var(--dur-hover) var(--ease-hover),
              color var(--dur-hover) var(--ease-hover);
}
.app-tema button:hover { color: var(--text); }
.app-tema button.is-faol {
  background: var(--surface);
  color: var(--accent);
  box-shadow: 0 1px 2px var(--shadow);
}
.app-tema button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Tema almashganda ranglar keskin sakramasin. Faqat fon va matn —
   hamma narsaga qo'yilsa sahifa og'irlashadi. */
:root.app-tema-otish,
:root.app-tema-otish body,
:root.app-tema-otish .ds-tile,
:root.app-tema-otish .ds-sidebar,
:root.app-tema-otish .ds-topbar {
  transition: background-color 220ms var(--ease-hover),
              color 220ms var(--ease-hover),
              border-color 220ms var(--ease-hover);
}

@media (prefers-reduced-motion: reduce) {
  :root.app-tema-otish,
  :root.app-tema-otish body,
  :root.app-tema-otish .ds-tile,
  :root.app-tema-otish .ds-sidebar,
  :root.app-tema-otish .ds-topbar { transition: none; }
}


/* ---------- Ixcham to'r ----------
   Kurslar kesimidagi ta'lim shakllari ro'yxati uchun.
   Bo'linmalar bo'limida avval shu ishlatilgandi, lekin chiziqli
   ro'yxat aniqroq taqqoslash berdi va o'sha qaytarildi. */
.app-tor {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--tor-eni, 190px), 1fr));
  gap: var(--space-12);
}

/* Foiz rangi — `ds-num` da to'g'ridan-to'g'ri ton sinfi */
.ds-num.is-ok { color: var(--ok); }
.ds-num.is-late { color: var(--late); }
.ds-num.is-absent { color: var(--absent); }


/* ---------- Radar diagrammasi uchun past quti ----------

   `radar()` SVG ni `width:100%` bilan beradi va balandlik viewBox
   nisbatidan kelib chiqadi — keng ustunda u juda baland bo'lib
   ketadi. Balandlikni cheklaymiz: `preserveAspectRatio` standart
   qiymati (`xMidYMid meet`) tufayli shakl nisbatini saqlagan holda
   kichrayadi va markazda turadi. */
/* Radar va ko'rsatkichlar bir qatorda. Tor ekranda ustma-ust tushadi. */
.app-radar-qator {
  display: flex;
  align-items: center;
  gap: var(--space-16);
  flex-wrap: wrap;
}
.app-radar-past {
  flex: 1 1 260px;
  min-width: 0;
}
.app-radar-past svg { display: block; width: 100%; }

/* Ko'rsatkichlar ustuni — radar yonida */
.app-radar-yon {
  flex: 0 1 150px;
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}

/* ==================== Sahifa sarlavhasi (topbar) =====================

   Balandlik 40% ga kamaytirildi: o'lchangan 120px → 72px.

   Qaerdan 48 piksel tejaldi (brauzerda o'lchangan qiymatlar):
     h1 ning tabiiy chekkalari  17.15 × 2 = 34.3px  → 0
     yuqori/quyi ichki bo'shliq 16 × 2    = 32px    → 20px  (10+10)
     sarlavha va izoh orasi     4px                → 2px
   Matnning o'zi tegilmagan: h1 30.7px, izoh 18px — o'qilishi
   o'zgarmaydi, faqat atrofidagi havo qisqardi.

   `.ds-topbar-end` (tema tugmasi, soat, mikrofon) 36px — u yangi
   72px ga bemalol sig'adi, shuning uchun unga tegilmadi.

   Dizayn tizimi fayllari (bundle.css) O'ZGARTIRILMAYDI — shuning uchun
   ustidan shu qatlamda yoziladi. */
.ds-topbar {
  padding-top: 10px;
  padding-bottom: 10px;
}

.ds-topbar-title { gap: 2px; }

.ds-topbar-title h1 { margin: 0; }

/* ==================== Jonli dars oynasi (LiveKit) ====================

   Dars oqimi EduON iframe'i o'rniga to'g'ridan-to'g'ri LiveKit dan
   keladi (kuzat.js). Bir nechta trek bo'lishi mumkin: o'qituvchi
   kamerasi, talabalar kamerasi, ekran ulashuv.

   Ekran ulashuv bo'lsa (`has-ekran`) u asosiy oyna bo'ladi va kameralar
   yon ustunga o'tadi — darsda muhimi taqdimot, kamera emas. */
.app-kuzat {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 240px;
  background: #000;
  overflow: hidden;
}

.app-kuzat-video {
  display: grid;
  gap: 4px;
  width: 100%;
  height: 100%;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  align-content: center;
  background: #000;
}

.app-kuzat-video.has-ekran {
  grid-template-columns: 1fr 200px;
  align-content: stretch;
}

.app-kuzat-video.has-ekran [data-manba="screen_share"] {
  grid-row: 1 / -1;
  grid-column: 1;
}

.app-kuzat-oyna {
  width: 100%;
  height: 100%;
  max-height: 100%;
  object-fit: contain;
  background: #000;
}

/* Ovoz elementi ko'rinmaydi, lekin DOM da bo'lishi SHART — aks holda
   brauzer oqimni ijro etmaydi. */
.app-kuzat-ovoz { display: none; }

.app-kuzat-past {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  gap: var(--space-8);
  align-items: baseline;
  padding: var(--space-8) var(--space-12);
  background: linear-gradient(to top, rgba(0, 0, 0, 0.72), transparent);
  color: #fff;
  pointer-events: none;
}

.app-kuzat-nom { font-size: 13px; font-weight: 600; }
.app-kuzat-izoh { font-size: 12px; opacity: 0.82; }

.app-kuzat-holat {
  display: flex;
  gap: var(--space-8);
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 240px;
  color: rgba(255, 255, 255, 0.78);
  font-size: 13px;
  text-align: center;
  padding: var(--space-16);
}

.app-kuzat-holat span {
  width: 13px;
  height: 13px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: appAylanma 0.8s linear infinite;
}

.app-kuzat-holat.is-xato { color: #ff9ba6; }
.app-kuzat-holat.is-xato span { display: none; }
